Subject: [PATCH 1/2] Initial instancing support --- source/Irrlicht/CNullDriver.cpp | 13 +++++++ source/Irrlicht/CNullDriver.h | 6 +++ source/Irrlicht/COpenGLDriver.cpp | 46 +++++++++++++++++++++++++++ source/Irrlicht/COpenGLDriver.h | 3 ++ source/Irrlicht/COpenGLExtensionHandler.cpp | 5 ++- source/Irrlicht/COpenGLExtensionHandler.h | 13 +++++++ 6 files changed, 85 insertions(+), 1 deletions(-) diff --git a/source/Irrlicht/CNullDriver.cpp b/source/Irrlicht/CNullDriver.cpp index c69bacf..cc3a385 100644 --- a/source/Irrlicht/CNullDriver.cpp +++ b/source/Irrlicht/CNullDriver.cpp @@ -1469,6 +1469,19 @@ void CNullDriver::drawMeshBuffer(const scene::IMeshBuffer* mb) drawVertexPrimitiveList(mb->getVertices(), mb->getVertexCount(), mb->getIndices(), mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); } +//! Draws an instanced mesh buffer +void CNullDriver::drawInstancedMeshBuffer(const scene::IMeshBuffer* mb, const u32 num) +{ + if (!mb) + return; + + //IVertexBuffer and IIndexBuffer later + SHWBufferLink *HWBuffer=getBufferLink(mb); + + if (HWBuffer) + drawInstancedHardwareBuffer(HWBuffer, num); +} + CNullDriver::SHWBufferLink *CNullDriver::getBufferLink(const scene::IMeshBuffer* mb) { diff --git a/source/Irrlicht/CNullDriver.h b/source/Irrlicht/CNullDriver.h index 8896784..ebdbbf4 100644 --- a/source/Irrlicht/CNullDriver.h +++ b/source/Irrlicht/CNullDriver.h @@ -363,6 +363,9 @@ namespace video //! Draws a mesh buffer virtual void drawMeshBuffer(const scene::IMeshBuffer* mb); + //! Draws an instanced mesh buffer + virtual void drawInstancedMeshBuffer(const scene::IMeshBuffer* mb, const u32 num); + protected: struct SHWBufferLink { @@ -401,6 +404,9 @@ namespace video //! Draw hardware buffer (only some drivers can) virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer) {} + //! Draw instancd hardware buffer (only some drivers can) + virtual void drawInstancedHardwareBuffer(SHWBufferLink *HWBuffer, const u32 num) {} + //! Update all hardware buffers, remove unused ones virtual void updateAllHardwareBuffers(); diff --git a/source/Irrlicht/COpenGLDriver.cpp b/source/Irrlicht/COpenGLDriver.cpp index 0d2a5ba..bf2e0e5 100644 --- a/source/Irrlicht/COpenGLDriver.cpp +++ b/source/Irrlicht/COpenGLDriver.cpp @@ -1215,6 +1215,52 @@ void COpenGLDriver::drawHardwareBuffer(SHWBufferLink *_HWBuffer) #endif } +//! Draw instanced hardware buffer +void COpenGLDriver::drawInstancedHardwareBuffer(SHWBufferLink *_HWBuffer, const u32 num) +{ + if (!_HWBuffer) + return; + + updateHardwareBuffer(_HWBuffer); //check if update is needed + _HWBuffer->LastUsed=0; //reset count + +#if defined(GL_ARB_vertex_buffer_object) && defined(GL_ARB_draw_instanced) + SHWBufferLink_opengl *HWBuffer=(SHWBufferLink_opengl*)_HWBuffer; + + const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer; + const void *vertices=mb->getVertices(); + const void *indexList=mb->getIndices(); + + if (HWBuffer->Mapped_Vertex==scene::EHM_NEVER) + return; + + extGlBindBuffer(GL_ARRAY_BUFFER, HWBuffer->vbo_verticesID); + vertices=0; + + extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, HWBuffer->vbo_indicesID); + indexList=0; + + GLenum indexSize = 0; + switch (mb->getIndexType()) { + case EIT_16BIT: + indexSize = GL_UNSIGNED_SHORT; + break; + case EIT_32BIT: + indexSize = GL_UNSIGNED_INT; + break; + } + +// drawVertexPrimitiveList(vertices, mb->getVertexCount(), indexList, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); + extGlDrawElementsInstanced(GL_TRIANGLES, mb->getIndexCount(), indexSize, indexList, num); + + printf("Drawing instanced hwbuf with idxcount %u, size %u, list %p, num %u\n",mb->getIndexCount(), + indexSize, indexList, num); + + extGlBindBuffer(GL_ARRAY_BUFFER, 0); + extGlBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +#endif +} + // small helper function to create vertex buffer object adress offsets static inline u8* buffer_offset(const long offset) diff --git a/source/Irrlicht/COpenGLDriver.h b/source/Irrlicht/COpenGLDriver.h index 9aa4326..35e6da3 100644 --- a/source/Irrlicht/COpenGLDriver.h +++ b/source/Irrlicht/COpenGLDriver.h @@ -99,6 +99,9 @@ namespace video //! Draw hardware buffer virtual void drawHardwareBuffer(SHWBufferLink *HWBuffer); + //! Draw instanced hardware buffer + virtual void drawInstancedHardwareBuffer(SHWBufferLink *HWBuffer, const u32 num); + //! draws a vertex primitive list virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount, const void* indexList, u32 primitiveCount, diff --git a/source/Irrlicht/COpenGLExtensionHandler.cpp b/source/Irrlicht/COpenGLExtensionHandler.cpp index ccd1417..0c2f153 100644 --- a/source/Irrlicht/COpenGLExtensionHandler.cpp +++ b/source/Irrlicht/COpenGLExtensionHandler.cpp @@ -25,7 +25,7 @@ COpenGLExtensionHandler::COpenGLExtensionHandler() : MaxTextureSize(1), MaxGeometryVerticesOut(0), MaxTextureLODBias(0.f), Version(0), ShaderLanguageVersion(0) #ifdef _IRR_OPENGL_USE_EXTPOINTER_ - ,pGlActiveTextureARB(0), pGlClientActiveTextureARB(0), + ,pGlDrawElementsInstancedARB(0), pGlActiveTextureARB(0), pGlClientActiveTextureARB(0), pGlGenProgramsARB(0), pGlGenProgramsNV(0), pGlBindProgramARB(0), pGlBindProgramNV(0), pGlDeleteProgramsARB(0), pGlDeleteProgramsNV(0), @@ -244,6 +244,9 @@ void COpenGLExtensionHandler::initExtensions(bool stencilBuffer) #endif #endif + pGlDrawElementsInstancedARB = (PFNGLDRAWELEMENTSINSTANCEDARBPROC) + IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glDrawElementsInstancedARB")); + pGlActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC) IRR_OGL_LOAD_EXTENSION(reinterpret_cast("glActiveTextureARB")); diff --git a/source/Irrlicht/COpenGLExtensionHandler.h b/source/Irrlicht/COpenGLExtensionHandler.h index 67e63cf..2e4b05d 100644 --- a/source/Irrlicht/COpenGLExtensionHandler.h +++ b/source/Irrlicht/COpenGLExtensionHandler.h @@ -847,6 +847,7 @@ class COpenGLExtensionHandler void extGlCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data); + void extGlDrawElementsInstanced(GLenum, GLsizei, GLenum, const GLvoid *, GLsizei); // shader programming void extGlGenPrograms(GLsizei n, GLuint *programs); @@ -919,6 +920,7 @@ class COpenGLExtensionHandler bool FeatureAvailable[IRR_OpenGL_Feature_Count]; #if defined(_IRR_OPENGL_USE_EXTPOINTER_) + PFNGLDRAWELEMENTSINSTANCEDARBPROC pGlDrawElementsInstancedARB; PFNGLACTIVETEXTUREARBPROC pGlActiveTextureARB; PFNGLCLIENTACTIVETEXTUREARBPROC pGlClientActiveTextureARB; PFNGLGENPROGRAMSARBPROC pGlGenProgramsARB; @@ -1012,6 +1014,17 @@ inline void COpenGLExtensionHandler::extGlActiveTexture(GLenum texture) #endif } +inline void COpenGLExtensionHandler::extGlDrawElementsInstanced(GLenum mode, GLsizei count, + GLenum type, const GLvoid *ind, GLsizei num) +{ +#ifdef _IRR_OPENGL_USE_EXTPOINTER_ + if (pGlDrawElementsInstancedARB) + pGlDrawElementsInstancedARB(mode, count, type, ind, num); +#else + glDrawElementsInstancedARB(mode, count, type, ind, num); +#endif +} + inline void COpenGLExtensionHandler::extGlClientActiveTexture(GLenum texture) { #ifdef _IRR_OPENGL_USE_EXTPOINTER_ -- 1.7.2.1