From 55489bc188d6b6c9d40a5fff082a7a21be58dceb Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Tue, 8 Apr 2014 21:44:43 +0200 Subject: [PATCH] Use UBO instead of copying Shadow VP matrixes. --- data/shaders/shadow.geom | 5 +- src/graphics/glwrap.cpp | 4 ++ src/graphics/glwrap.hpp | 2 + src/graphics/render.cpp | 12 +++++ src/graphics/shaders.cpp | 64 ++++++++++---------------- src/graphics/shaders.hpp | 16 +++---- src/graphics/stkinstancedscenenode.cpp | 7 +-- src/graphics/stkmesh.cpp | 15 +----- 8 files changed, 58 insertions(+), 67 deletions(-) diff --git a/data/shaders/shadow.geom b/data/shaders/shadow.geom index 02681265b..3333dc893 100644 --- a/data/shaders/shadow.geom +++ b/data/shaders/shadow.geom @@ -1,4 +1,7 @@ -uniform mat4 ViewProjectionMatrix[4]; +layout (std140) uniform MatrixesData +{ + mat4 ViewProjectionMatrix[4]; +}; #if __VERSION__ >= 400 layout(triangles, invocations=4) in; diff --git a/src/graphics/glwrap.cpp b/src/graphics/glwrap.cpp index 51581bed8..4edd237b2 100644 --- a/src/graphics/glwrap.cpp +++ b/src/graphics/glwrap.cpp @@ -64,6 +64,8 @@ PFNGLGENERATEMIPMAPPROC glGenerateMipmap; PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; +PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex; +PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding; #endif static bool is_gl_init = false; @@ -207,6 +209,8 @@ void initGL() glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)IRR_OGL_LOAD_EXTENSION("glCheckFramebufferStatus"); glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)IRR_OGL_LOAD_EXTENSION("glTexImage2DMultisample"); glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)IRR_OGL_LOAD_EXTENSION("glBlitFramebuffer"); + glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)IRR_OGL_LOAD_EXTENSION("glGetUniformBlockIndex"); + glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)IRR_OGL_LOAD_EXTENSION("glUniformBlockBinding"); #ifdef DEBUG glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC)IRR_OGL_LOAD_EXTENSION("glDebugMessageCallbackARB"); #endif diff --git a/src/graphics/glwrap.hpp b/src/graphics/glwrap.hpp index da1552b04..18b4556c5 100644 --- a/src/graphics/glwrap.hpp +++ b/src/graphics/glwrap.hpp @@ -81,6 +81,8 @@ extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap; extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; +extern PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex; +extern PFNGLUNIFORMBLOCKBINDINGPROC glUniformBlockBinding; #ifdef DEBUG extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB; #endif diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 561e43e67..61b80e428 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -565,7 +565,19 @@ void IrrDriver::renderShadows(//ShadowImportanceProvider * const sicb, glViewport(0, 0, 1024, 1024); glClear(GL_DEPTH_BUFFER_BIT); glDrawBuffer(GL_NONE); + + size_t size = irr_driver->getShadowViewProj().size(); + float *tmp = new float[16 * size]; + for (unsigned i = 0; i < size; i++) { + memcpy(&tmp[16 * i], irr_driver->getShadowViewProj()[i].pointer(), 16 * sizeof(float)); + } + glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::ViewProjectionMatrixesUBO); + glBufferSubData(GL_UNIFORM_BUFFER, 0, 16 * 4 * sizeof(float), tmp); + glBindBufferBase(GL_UNIFORM_BUFFER, 0, SharedObject::ViewProjectionMatrixesUBO); + delete tmp; + m_scene_manager->drawAll(scene::ESNRP_SOLID); + glBindBuffer(GL_UNIFORM_BUFFER, 0); glCullFace(GL_BACK); camnode->setNearValue(oldnear); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 0b7819c63..2e28d668c 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -164,6 +164,16 @@ static void initCubeVBO() glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * 6 * sizeof(int), indices, GL_STATIC_DRAW); } +GLuint SharedObject::ViewProjectionMatrixesUBO; + +static void initShadowVPMUBO() +{ + glGenBuffers(1, &SharedObject::ViewProjectionMatrixesUBO); + glBindBuffer(GL_UNIFORM_BUFFER, SharedObject::ViewProjectionMatrixesUBO); + glBufferData(GL_UNIFORM_BUFFER, 16 * 4 * sizeof(float), 0, GL_STATIC_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); +} + void Shaders::loadShaders() { const std::string &dir = file_manager->getAsset(FileManager::SHADER, ""); @@ -285,6 +295,7 @@ void Shaders::loadShaders() initQuadBuffer(); initBillboardVBO(); initCubeVBO(); + initShadowVPMUBO(); FullScreenShader::BloomBlendShader::init(); FullScreenShader::BloomShader::init(); FullScreenShader::ColorLevelShader::init(); @@ -1397,7 +1408,6 @@ namespace MeshShader GLuint ShadowShader::Program; GLuint ShadowShader::attrib_position; - GLuint ShadowShader::uniform_VP; GLuint ShadowShader::uniform_MM; void ShadowShader::init() @@ -1413,20 +1423,15 @@ namespace MeshShader GL_GEOMETRY_SHADER, file_manager->getAsset("shaders/shadow.geom").c_str(), GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/white.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); - uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix[0]"); uniform_MM = glGetUniformLocation(Program, "ModelMatrix"); + GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); + glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); } - void ShadowShader::setUniforms(const core::matrix4 &ModelMatrix, const std::vector &ViewProjectionMatrix) + void ShadowShader::setUniforms(const core::matrix4 &ModelMatrix) { - size_t size = ViewProjectionMatrix.size(); - float *tmp = new float[16 * size]; - for (unsigned i = 0; i < size; i++) { - memcpy(&tmp[16 * i], ViewProjectionMatrix[i].pointer(), 16 * sizeof(float)); - } - glUniformMatrix4fv(uniform_VP, size, GL_FALSE, tmp); + glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer()); - delete[] tmp; } GLuint InstancedShadowShader::Program; @@ -1434,7 +1439,6 @@ namespace MeshShader GLuint InstancedShadowShader::attrib_origin; GLuint InstancedShadowShader::attrib_orientation; GLuint InstancedShadowShader::attrib_scale; - GLuint InstancedShadowShader::uniform_VP; void InstancedShadowShader::init() { @@ -1453,24 +1457,17 @@ namespace MeshShader attrib_origin = glGetAttribLocation(Program, "Origin"); attrib_orientation = glGetAttribLocation(Program, "Orientation"); attrib_scale = glGetAttribLocation(Program, "Scale"); - uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix[0]"); + GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); + glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); } - void InstancedShadowShader::setUniforms(const std::vector &ViewProjectionMatrix) + void InstancedShadowShader::setUniforms() { - size_t size = ViewProjectionMatrix.size(); - float *tmp = new float[16 * size]; - for (unsigned i = 0; i < size; i++) { - memcpy(&tmp[16 * i], ViewProjectionMatrix[i].pointer(), 16 * sizeof(float)); - } - glUniformMatrix4fv(uniform_VP, size, GL_FALSE, tmp); - delete[] tmp; } GLuint RefShadowShader::Program; GLuint RefShadowShader::attrib_position; GLuint RefShadowShader::attrib_texcoord; - GLuint RefShadowShader::uniform_VP; GLuint RefShadowShader::uniform_MM; GLuint RefShadowShader::uniform_tex; @@ -1489,22 +1486,16 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/object_unlit.frag").c_str()); attrib_position = glGetAttribLocation(Program, "Position"); attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); - uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix[0]"); uniform_tex = glGetUniformLocation(Program, "tex"); uniform_MM = glGetUniformLocation(Program, "ModelMatrix"); + GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); + glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); } - void RefShadowShader::setUniforms(const core::matrix4 &ModelMatrix, const std::vector &ViewProjectionMatrix, unsigned TU_tex) + void RefShadowShader::setUniforms(const core::matrix4 &ModelMatrix, unsigned TU_tex) { - size_t size = ViewProjectionMatrix.size(); - float *tmp = new float[16 * size]; - for (unsigned i = 0; i < size; i++) { - memcpy(&tmp[16 * i], ViewProjectionMatrix[i].pointer(), 16 * sizeof(float)); - } - glUniformMatrix4fv(uniform_VP, size, GL_FALSE, tmp); glUniformMatrix4fv(uniform_MM, 1, GL_FALSE, ModelMatrix.pointer()); glUniform1i(uniform_tex, TU_tex); - delete[] tmp; } GLuint InstancedRefShadowShader::Program; @@ -1513,7 +1504,6 @@ namespace MeshShader GLuint InstancedRefShadowShader::attrib_origin; GLuint InstancedRefShadowShader::attrib_orientation; GLuint InstancedRefShadowShader::attrib_scale; - GLuint InstancedRefShadowShader::uniform_VP; GLuint InstancedRefShadowShader::uniform_tex; void InstancedRefShadowShader::init() @@ -1535,20 +1525,14 @@ namespace MeshShader attrib_origin = glGetAttribLocation(Program, "Origin"); attrib_orientation = glGetAttribLocation(Program, "Orientation"); attrib_scale = glGetAttribLocation(Program, "Scale"); - uniform_VP = glGetUniformLocation(Program, "ViewProjectionMatrix[0]"); uniform_tex = glGetUniformLocation(Program, "tex"); + GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); + glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); } - void InstancedRefShadowShader::setUniforms(const std::vector &ViewProjectionMatrix, unsigned TU_tex) + void InstancedRefShadowShader::setUniforms(unsigned TU_tex) { - size_t size = ViewProjectionMatrix.size(); - float *tmp = new float[16 * size]; - for (unsigned i = 0; i < size; i++) { - memcpy(&tmp[16 * i], ViewProjectionMatrix[i].pointer(), 16 * sizeof(float)); - } - glUniformMatrix4fv(uniform_VP, size, GL_FALSE, tmp); glUniform1i(uniform_tex, TU_tex); - delete[] tmp; } GLuint GrassShadowShader::Program; diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 5170e28cb..e795d7cef 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -30,6 +30,7 @@ class SharedObject public: static GLuint billboardvbo; static GLuint cubevbo, cubeindexes; + static GLuint ViewProjectionMatrixesUBO; }; namespace MeshShader { @@ -326,10 +327,10 @@ class ShadowShader public: static GLuint Program; static GLuint attrib_position; - static GLuint uniform_VP, uniform_MM; + static GLuint uniform_MM, uniform_ViewProjectionMatrixesUBO; static void init(); - static void setUniforms(const core::matrix4 &ModelMatrix, const std::vector &ViewProjectionMatrix); + static void setUniforms(const core::matrix4 &ModelMatrix); }; class InstancedShadowShader @@ -337,10 +338,9 @@ class InstancedShadowShader public: static GLuint Program; static GLuint attrib_position, attrib_origin, attrib_orientation, attrib_scale; - static GLuint uniform_VP; static void init(); - static void setUniforms(const std::vector &ViewProjectionMatrix); + static void setUniforms(); }; class RefShadowShader @@ -348,10 +348,10 @@ class RefShadowShader public: static GLuint Program; static GLuint attrib_position, attrib_texcoord; - static GLuint uniform_VP, uniform_MM, uniform_tex; + static GLuint uniform_MM, uniform_tex; static void init(); - static void setUniforms(const core::matrix4 &ModelMatrix, const std::vector &ModelViewProjectionMatrix, unsigned TU_tex); + static void setUniforms(const core::matrix4 &ModelMatrix, unsigned TU_tex); }; class InstancedRefShadowShader @@ -359,10 +359,10 @@ class InstancedRefShadowShader public: static GLuint Program; static GLuint attrib_position, attrib_texcoord, attrib_origin, attrib_orientation, attrib_scale; - static GLuint uniform_VP, uniform_tex; + static GLuint uniform_tex; static void init(); - static void setUniforms(const std::vector &ModelViewProjectionMatrix, unsigned TU_tex); + static void setUniforms(unsigned TU_tex); }; class GrassShadowShader diff --git a/src/graphics/stkinstancedscenenode.cpp b/src/graphics/stkinstancedscenenode.cpp index d4b1ddfd6..8350c38f3 100644 --- a/src/graphics/stkinstancedscenenode.cpp +++ b/src/graphics/stkinstancedscenenode.cpp @@ -200,8 +200,7 @@ static void drawShadowDefault(GLMesh &mesh, size_t instance_count) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - std::vector ShadowMVP(irr_driver->getShadowViewProj()); - MeshShader::InstancedShadowShader::setUniforms(ShadowMVP); + MeshShader::InstancedShadowShader::setUniforms(); assert(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass); @@ -229,10 +228,8 @@ static void drawShadowAlphaRefTexture(GLMesh &mesh, size_t instance_count) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - std::vector ShadowMVP(irr_driver->getShadowViewProj()); - setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - MeshShader::InstancedRefShadowShader::setUniforms(ShadowMVP, 0); + MeshShader::InstancedRefShadowShader::setUniforms(0); assert(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass); diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index cdb8227b5..c9f0aeeb0 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -667,10 +667,8 @@ void drawShadowRef(const GLMesh &mesh, const core::matrix4 &ModelMatrix) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - std::vector ShadowMVP(irr_driver->getShadowViewProj()); - setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - MeshShader::RefShadowShader::setUniforms(ModelMatrix, ShadowMVP, 0); + MeshShader::RefShadowShader::setUniforms(ModelMatrix, 0); assert(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass); @@ -684,16 +682,7 @@ void drawShadow(const GLMesh &mesh, const core::matrix4 &ModelMatrix) GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - std::vector ShadowMVP(irr_driver->getShadowViewProj()); - - /* if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) - { - setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - glUseProgram(MeshShader::GrassShadowShader::Program); - MeshShader::GrassShadowShader::setUniforms(ShadowMVP, windDir, 0); - }*/ - - MeshShader::ShadowShader::setUniforms(ModelMatrix, ShadowMVP); + MeshShader::ShadowShader::setUniforms(ModelMatrix); assert(mesh.vao_shadow_pass); glBindVertexArray(mesh.vao_shadow_pass);