Commit b04c7e75 authored by hybrid's avatar hybrid

Added driver support for Point sprites.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@852 dfc29bdd-3216-0410-991c-e03cc46cb475
parent d2702c7f
Changes in version 1.4 (... 2007) Changes in version 1.4 (... 2007)
- Point sprite support in the driver. Point sprites use just one 3d vertex and a size to create a textured billboard on the GPU. This can provide fast particle systems, especially in combination with shaders. The proper particle extension will follow later on as it needs some more refactoring.
- OpenGL 2D drawing accuracy fix by tuXXX - OpenGL 2D drawing accuracy fix by tuXXX
- Added OnResize and getCurrentRenderTargetSize to the software video drivers. - Added OnResize and getCurrentRenderTargetSize to the software video drivers.
......
...@@ -47,7 +47,10 @@ enum E_PRIMITIVE_TYPE ...@@ -47,7 +47,10 @@ enum E_PRIMITIVE_TYPE
EPT_QUADS, EPT_QUADS,
//! Just as LINE_LOOP, but filled. //! Just as LINE_LOOP, but filled.
EPT_POLYGON EPT_POLYGON,
//! The single vertices are expanded to quad billboards on the GPU.
EPT_POINT_SPRITES
}; };
//! Struct for holding a mesh with a single material //! Struct for holding a mesh with a single material
......
...@@ -636,7 +636,7 @@ void CD3D8Driver::setMaterial(const SMaterial& material) ...@@ -636,7 +636,7 @@ void CD3D8Driver::setMaterial(const SMaterial& material)
for (u32 i=0; i<MaxTextureUnits; ++i) for (u32 i=0; i<MaxTextureUnits; ++i)
{ {
setTexture(i, Material.Textures[i]); setTexture(i, Material.Textures[i]);
setTransform((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ), setTransform((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ),
material.getTextureMatrix(i)); material.getTextureMatrix(i));
} }
...@@ -834,39 +834,55 @@ void CD3D8Driver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, ...@@ -834,39 +834,55 @@ void CD3D8Driver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
{ {
switch (pType) switch (pType)
{ {
case scene::EPT_POINTS: case scene::EPT_POINT_SPRITES:
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_POINTLIST, 0, vertexCount, case scene::EPT_POINTS:
primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); {
break; if (pType==scene::EPT_POINT_SPRITES)
case scene::EPT_LINE_STRIP: pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);
primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *(DWORD*)(&Material.Thickness));
break; f32 tmp=1.0f;
case scene::EPT_LINE_LOOP: pID3DDevice->SetRenderState(D3DRS_POINTSCALE_C, *(DWORD*)(&tmp));
{ tmp=0.0f;
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, pID3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, *(DWORD*)(&tmp));
primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); pID3DDevice->SetRenderState(D3DRS_POINTSCALE_A, *(DWORD*)(&tmp));
u16 tmpIndices[] = {0, primitiveCount}; pID3DDevice->SetRenderState(D3DRS_POINTSCALE_B, *(DWORD*)(&tmp));
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_POINTLIST, 0, vertexCount,
1, tmpIndices, D3DFMT_INDEX16, vertices, stride); primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride);
} pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
break; if (pType==scene::EPT_POINT_SPRITES)
case scene::EPT_LINES: pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, }
primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); break;
break; case scene::EPT_LINE_STRIP:
case scene::EPT_TRIANGLE_STRIP: pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount,
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, 0, vertexCount, primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride);
primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); break;
break; case scene::EPT_LINE_LOOP:
case scene::EPT_TRIANGLE_FAN: {
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, 0, vertexCount, pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount,
primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride);
break; u16 tmpIndices[] = {0, primitiveCount};
case scene::EPT_TRIANGLES: pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount,
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount, 1, tmpIndices, D3DFMT_INDEX16, vertices, stride);
primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); }
break; break;
case scene::EPT_LINES:
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount,
primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride);
break;
case scene::EPT_TRIANGLE_STRIP:
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, 0, vertexCount,
primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride);
break;
case scene::EPT_TRIANGLE_FAN:
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, 0, vertexCount,
primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride);
break;
case scene::EPT_TRIANGLES:
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount,
primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride);
break;
} }
} }
} }
......
...@@ -832,9 +832,25 @@ void CD3D9Driver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, ...@@ -832,9 +832,25 @@ void CD3D9Driver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
{ {
switch (pType) switch (pType)
{ {
case scene::EPT_POINT_SPRITES:
case scene::EPT_POINTS: case scene::EPT_POINTS:
{
if (pType==scene::EPT_POINT_SPRITES)
pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *(DWORD*)(&Material.Thickness));
f32 tmp=1.0f;
pID3DDevice->SetRenderState(D3DRS_POINTSCALE_C, *(DWORD*)(&tmp));
tmp=0.0f;
pID3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, *(DWORD*)(&tmp));
pID3DDevice->SetRenderState(D3DRS_POINTSCALE_A, *(DWORD*)(&tmp));
pID3DDevice->SetRenderState(D3DRS_POINTSCALE_B, *(DWORD*)(&tmp));
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_POINTLIST, 0, vertexCount, pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_POINTLIST, 0, vertexCount,
primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride); primitiveCount, indexList, D3DFMT_INDEX16, vertices, stride);
pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
if (pType==scene::EPT_POINT_SPRITES)
pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
}
break; break;
case scene::EPT_LINE_STRIP: case scene::EPT_LINE_STRIP:
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount,
......
...@@ -464,4 +464,4 @@ void CGUIButton::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWr ...@@ -464,4 +464,4 @@ void CGUIButton::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWr
} // end namespace gui } // end namespace gui
} // end namespace irr } // end namespace irr
#endif _IRR_COMPILE_WITH_GUI_ #endif // _IRR_COMPILE_WITH_GUI_
...@@ -551,9 +551,9 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun ...@@ -551,9 +551,9 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_VERTEX_ARRAY);
if (pType!=scene::EPT_POINTS) if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES))
glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY);
if (pType!=scene::EPT_POINTS) if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES))
glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_NORMAL_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]); glColorPointer(4, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]);
...@@ -597,7 +597,28 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun ...@@ -597,7 +597,28 @@ void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCoun
switch (pType) switch (pType)
{ {
case scene::EPT_POINTS: case scene::EPT_POINTS:
case scene::EPT_POINT_SPRITES:
{
if (pType==scene::EPT_POINT_SPRITES)
glEnable(GL_POINT_SPRITE_ARB);
float quadratic[] = {0.0f, 0.0f, 10.01f};
extGlPointParameterfv(GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic);
float maxParticleSize=1.0f;
glGetFloatv(GL_POINT_SIZE_MAX_ARB, &maxParticleSize);
maxParticleSize=maxParticleSize<Material.Thickness?maxParticleSize:Material.Thickness;
// extGlPointParameterf(GL_POINT_SIZE_MAX_ARB,maxParticleSize);
// extGlPointParameterf(GL_POINT_SIZE_MIN_ARB,Material.Thickness/2);
extGlPointParameterf(GL_POINT_FADE_THRESHOLD_SIZE_ARB, 60.0f);
glPointSize(Material.Thickness*600.0f);
if (pType==scene::EPT_POINT_SPRITES)
glTexEnvf(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE, GL_TRUE);
glDrawArrays(GL_POINTS, 0, primitiveCount); glDrawArrays(GL_POINTS, 0, primitiveCount);
if (pType==scene::EPT_POINT_SPRITES)
{
glDisable(GL_POINT_SPRITE_ARB);
glTexEnvf(GL_POINT_SPRITE_ARB,GL_COORD_REPLACE, GL_FALSE);
}
}
break; break;
case scene::EPT_LINE_STRIP: case scene::EPT_LINE_STRIP:
glDrawElements(GL_LINE_STRIP, primitiveCount+1, GL_UNSIGNED_SHORT, indexList); glDrawElements(GL_LINE_STRIP, primitiveCount+1, GL_UNSIGNED_SHORT, indexList);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment