Subject: [PATCH 2/2] More hacking --- include/IVideoDriver.h | 5 + source/Irrlicht/CNullDriver.cpp | 2 + source/Irrlicht/COpenGLDriver.cpp | 171 ++++++++++++++++++++++++++++++++++++- source/Irrlicht/COpenGLDriver.h | 7 ++ 4 files changed, 183 insertions(+), 2 deletions(-) diff --git a/include/IVideoDriver.h b/include/IVideoDriver.h index 9c63205..7c6fdb4 100644 --- a/include/IVideoDriver.h +++ b/include/IVideoDriver.h @@ -940,6 +940,11 @@ namespace video /** \param mb Buffer to draw; */ virtual void drawMeshBuffer(const scene::IMeshBuffer* mb) =0; + //! Draws an instanced mesh buffer + /** \param mb Buffer to draw; */ + /** \param num How many to draw; */ + virtual void drawInstancedMeshBuffer(const scene::IMeshBuffer* mb, const u32 num) =0; + //! Sets the fog mode. /** These are global values attached to each 3d object rendered, which has the fog flag enabled in its material. diff --git a/source/Irrlicht/CNullDriver.cpp b/source/Irrlicht/CNullDriver.cpp index cc3a385..1557049 100644 --- a/source/Irrlicht/CNullDriver.cpp +++ b/source/Irrlicht/CNullDriver.cpp @@ -1472,6 +1472,7 @@ void CNullDriver::drawMeshBuffer(const scene::IMeshBuffer* mb) //! Draws an instanced mesh buffer void CNullDriver::drawInstancedMeshBuffer(const scene::IMeshBuffer* mb, const u32 num) { +//puts("drawinstanced first"); if (!mb) return; @@ -1480,6 +1481,7 @@ void CNullDriver::drawInstancedMeshBuffer(const scene::IMeshBuffer* mb, const u3 if (HWBuffer) drawInstancedHardwareBuffer(HWBuffer, num); + else puts("no hwbuf"); } diff --git a/source/Irrlicht/COpenGLDriver.cpp b/source/Irrlicht/COpenGLDriver.cpp index bf2e0e5..53a319b 100644 --- a/source/Irrlicht/COpenGLDriver.cpp +++ b/source/Irrlicht/COpenGLDriver.cpp @@ -1124,8 +1124,10 @@ bool COpenGLDriver::updateHardwareBuffer(SHWBufferLink *HWBuffer) COpenGLDriver::SHWBufferLink *COpenGLDriver::createHardwareBuffer(const scene::IMeshBuffer* mb) { #if defined(GL_ARB_vertex_buffer_object) +puts("creating hwbuf"); if (!mb || (mb->getHardwareMappingHint_Index()==scene::EHM_NEVER && mb->getHardwareMappingHint_Vertex()==scene::EHM_NEVER)) return 0; +puts("mapping ok"); SHWBufferLink_opengl *HWBuffer=new SHWBufferLink_opengl(mb); @@ -1218,6 +1220,7 @@ void COpenGLDriver::drawHardwareBuffer(SHWBufferLink *_HWBuffer) //! Draw instanced hardware buffer void COpenGLDriver::drawInstancedHardwareBuffer(SHWBufferLink *_HWBuffer, const u32 num) { +//puts("drawinstancedhwbuffer"); if (!_HWBuffer) return; @@ -1250,8 +1253,9 @@ void COpenGLDriver::drawInstancedHardwareBuffer(SHWBufferLink *_HWBuffer, const break; } -// drawVertexPrimitiveList(vertices, mb->getVertexCount(), indexList, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); - extGlDrawElementsInstanced(GL_TRIANGLES, mb->getIndexCount(), indexSize, indexList, num); + drawInstancedVertexPrimitiveList(vertices, mb->getVertexCount(), indexList, + mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, + mb->getIndexType(), num); printf("Drawing instanced hwbuf with idxcount %u, size %u, list %p, num %u\n",mb->getIndexCount(), indexSize, indexList, num); @@ -1269,6 +1273,169 @@ static inline u8* buffer_offset(const long offset) } +//! draws an instanced vertex primitive list +void COpenGLDriver::drawInstancedVertexPrimitiveList(const void* vertices, u32 vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType, const u32 num) +{ +//puts("drawinstvert start"); + if (!primitiveCount || !vertexCount) + return; + + if (!checkPrimitiveCount(primitiveCount)) + return; + + CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType); + + if (vertices) + createColorBuffer(vertices, vertexCount, vType); + + // draw everything + setRenderStates3DMode(); + + if (MultiTextureExtension) + extGlClientActiveTexture(GL_TEXTURE0_ARB); + + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES)) + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if ((pType!=scene::EPT_POINTS) && (pType!=scene::EPT_POINT_SPRITES)) + glEnableClientState(GL_NORMAL_ARRAY); + + if (vertices) + glColorPointer(4, GL_UNSIGNED_BYTE, 0, &ColorBuffer[0]); + + switch (vType) + { + case EVT_STANDARD: + if (vertices) + { + glNormalPointer(GL_FLOAT, sizeof(S3DVertex), &(static_cast(vertices))[0].Normal); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast(vertices))[0].TCoords); + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex), &(static_cast(vertices))[0].Pos); + } + else + { + glNormalPointer(GL_FLOAT, sizeof(S3DVertex), buffer_offset(12)); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(S3DVertex), buffer_offset(24)); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), buffer_offset(28)); + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex), 0); + } + + if (MultiTextureExtension && CurrentTexture[1]) + { + extGlClientActiveTexture(GL_TEXTURE1_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if (vertices) + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), &(static_cast(vertices))[0].TCoords); + else + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex), buffer_offset(28)); + } + break; + case EVT_2TCOORDS: + if (vertices) + { + glNormalPointer(GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast(vertices))[0].Normal); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast(vertices))[0].TCoords); + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast(vertices))[0].Pos); + } + else + { + glNormalPointer(GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(12)); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(S3DVertex2TCoords), buffer_offset(24)); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(28)); + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(0)); + } + + + if (MultiTextureExtension) + { + extGlClientActiveTexture(GL_TEXTURE1_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if (vertices) + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), &(static_cast(vertices))[0].TCoords2); + else + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertex2TCoords), buffer_offset(36)); + } + break; + case EVT_TANGENTS: + if (vertices) + { + glNormalPointer(GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Normal); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].TCoords); + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Pos); + } + else + { + glNormalPointer(GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(12)); + glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(S3DVertexTangents), buffer_offset(24)); + glTexCoordPointer(2, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(28)); + glVertexPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(0)); + } + + if (MultiTextureExtension) + { + extGlClientActiveTexture(GL_TEXTURE1_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if (vertices) + glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Tangent); + else + glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(36)); + + extGlClientActiveTexture(GL_TEXTURE2_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + if (vertices) + glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), &(static_cast(vertices))[0].Binormal); + else + glTexCoordPointer(3, GL_FLOAT, sizeof(S3DVertexTangents), buffer_offset(48)); + } + break; + } + + GLenum indexSize=0; + + switch (iType) + { + case EIT_16BIT: + { + indexSize=GL_UNSIGNED_SHORT; + break; + } + case EIT_32BIT: + { + indexSize=GL_UNSIGNED_INT; + break; + } + } + int before = glGetError(); + if (before) printf("%d\n",before); + extGlDrawElementsInstanced(GL_TRIANGLES, primitiveCount, indexSize, 0, num); +// renderArray(indexList, primitiveCount, pType, iType); +// puts("RenderArray action"); + before = glGetError(); + if (before) printf("%d\n",before); + + if (MultiTextureExtension) + { + if (vType==EVT_TANGENTS) + { + extGlClientActiveTexture(GL_TEXTURE2_ARB); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + if ((vType!=EVT_STANDARD) || CurrentTexture[1]) + { + extGlClientActiveTexture(GL_TEXTURE1_ARB); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + extGlClientActiveTexture(GL_TEXTURE0_ARB); + } + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +} + //! draws a vertex primitive list void COpenGLDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const void* indexList, u32 primitiveCount, diff --git a/source/Irrlicht/COpenGLDriver.h b/source/Irrlicht/COpenGLDriver.h index 35e6da3..44a052a 100644 --- a/source/Irrlicht/COpenGLDriver.h +++ b/source/Irrlicht/COpenGLDriver.h @@ -107,6 +107,13 @@ namespace video const void* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType); + //! draws an instanced vertex primitive list + virtual void drawInstancedVertexPrimitiveList(const void* vertices, u32 + vertexCount, + const void* indexList, u32 primitiveCount, + E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE + iType, const u32 num); + //! draws a vertex primitive list in 2d virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount, const void* indexList, u32 primitiveCount, -- 1.7.2.1