diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index 0a7ec31dd..eacf20ac6 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -709,116 +709,27 @@ void IrrDriver::renderTransparent() glEnable(GL_BLEND); glBlendEquation(GL_FUNC_ADD); glDisable(GL_CULL_FACE); - TransparentMeshes::reset(); - TransparentMeshes::reset(); + ListBlendTransparent::Arguments.clear(); + ListAdditiveTransparent::Arguments.clear(); + ListBlendTransparentFog::Arguments.clear(); + ListAdditiveTransparentFog::Arguments.clear(); m_scene_manager->drawAll(scene::ESNRP_TRANSPARENT); glBindVertexArray(getVAO(EVT_STANDARD)); if (World::getWorld() && World::getWorld()->isFogEnabled()) { - const Track * const track = World::getWorld()->getTrack(); - - // This function is only called once per frame - thus no need for setters. - const float fogmax = track->getFogMax(); - const float startH = track->getFogStartHeight(); - const float endH = track->getFogEndHeight(); - const float start = track->getFogStart(); - const float end = track->getFogEnd(); - const video::SColor tmpcol = track->getFogColor(); - - core::vector3df col(tmpcol.getRed() / 255.0f, - tmpcol.getGreen() / 255.0f, - tmpcol.getBlue() / 255.0f); - - glUseProgram(MeshShader::TransparentFogShader::Program); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - for (unsigned i = 0; i < TransparentMeshes::MeshSet.size(); i++) - { - GLMesh &mesh = *TransparentMeshes::MeshSet[i]; - if (mesh.VAOType != EVT_STANDARD) - { -#ifdef DEBUG - Log::error("Materials", "Wrong vertex Type associed to fog + transparent blend (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str()); -#endif - glBindVertexArray(getVAO(mesh.VAOType)); - } - - - if (!mesh.textures[0]) - mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); - compressTexture(mesh.textures[0], true); - setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - - draw(&mesh, TransparentMeshes::MVPSet[i], TransparentMeshes::MeshSet[i]->TextureMatrix, fogmax, startH, endH, start, end, col, Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition(), 0); - if (mesh.VAOType != EVT_STANDARD) - glBindVertexArray(getVAO(EVT_STANDARD)); - } + renderMeshes2ndPass({ MeshShader::TransparentFogShader::TU_tex }, ListBlendTransparentFog::Arguments); glBlendFunc(GL_ONE, GL_ONE); - for (unsigned i = 0; i < TransparentMeshes::MeshSet.size(); i++) - { - GLMesh &mesh = *TransparentMeshes::MeshSet[i]; - if (mesh.VAOType != EVT_STANDARD) - { -#ifdef DEBUG - Log::error("Materials", "Wrong vertex Type associed to fog + transparent additive (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str()); -#endif - glBindVertexArray(getVAO(mesh.VAOType)); - } - glBindVertexArray(getVAO(mesh.VAOType)); - - if (!mesh.textures[0]) - mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); - compressTexture(mesh.textures[0], true); - setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - - draw(&mesh, TransparentMeshes::MVPSet[i], TransparentMeshes::MeshSet[i]->TextureMatrix, fogmax, startH, endH, start, end, col, Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition(), 0); - if (mesh.VAOType != EVT_STANDARD) - glBindVertexArray(getVAO(EVT_STANDARD)); - } + renderMeshes2ndPass({ MeshShader::TransparentFogShader::TU_tex }, ListAdditiveTransparentFog::Arguments); } else { - glUseProgram(MeshShader::TransparentShader::Program); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - for (unsigned i = 0; i < TransparentMeshes::MeshSet.size(); i++) - { - GLMesh &mesh = *TransparentMeshes::MeshSet[i]; - if (mesh.VAOType != EVT_STANDARD) - { -#ifdef DEBUG - Log::error("Materials", "Wrong vertex Type associed to fog + transparent additive (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str()); -#endif - glBindVertexArray(getVAO(mesh.VAOType)); - } - glBindVertexArray(getVAO(mesh.VAOType)); - if (!mesh.textures[0]) - mesh.textures[0] = getUnicolorTexture(video::SColor(255, 255, 255, 255)); - compressTexture(mesh.textures[0], true); - setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - draw(&mesh, TransparentMeshes::MVPSet[i], TransparentMeshes::MeshSet[i]->TextureMatrix, 0); - if (mesh.VAOType != EVT_STANDARD) - glBindVertexArray(getVAO(EVT_STANDARD)); - } - + renderMeshes2ndPass({ MeshShader::TransparentShader::TU_tex }, ListBlendTransparent::Arguments); glBlendFunc(GL_ONE, GL_ONE); - for (unsigned i = 0; i < TransparentMeshes::MeshSet.size(); i++) - { - GLMesh &mesh = *TransparentMeshes::MeshSet[i]; - if (mesh.VAOType != EVT_STANDARD) - { -#ifdef DEBUG - Log::error("Materials", "Wrong vertex Type associed to fog + transparent additive (hint texture : %s)", mesh.textures[0]->getName().getPath().c_str()); -#endif - glBindVertexArray(getVAO(mesh.VAOType)); - } - glBindVertexArray(getVAO(mesh.VAOType)); - compressTexture(mesh.textures[0], true); - setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - draw(&mesh, TransparentMeshes::MVPSet[i], TransparentMeshes::MeshSet[i]->TextureMatrix, 0); - if (mesh.VAOType != EVT_STANDARD) - glBindVertexArray(getVAO(EVT_STANDARD)); - } + renderMeshes2ndPass({ MeshShader::TransparentShader::TU_tex }, ListAdditiveTransparent::Arguments); } } diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 1be223a12..40249d8dd 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -1153,7 +1153,7 @@ namespace MeshShader GLuint TransparentShader::Program; GLuint TransparentShader::uniform_MVP; GLuint TransparentShader::uniform_TM; - GLuint TransparentShader::uniform_tex; + GLuint TransparentShader::TU_tex; void TransparentShader::init() { @@ -1162,25 +1162,29 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/transparent.frag").c_str()); uniform_MVP = glGetUniformLocation(Program, "ModelMatrix"); uniform_TM = glGetUniformLocation(Program, "TextureMatrix"); - uniform_tex = glGetUniformLocation(Program, "tex"); + GLuint uniform_tex = glGetUniformLocation(Program, "tex"); if (!UserConfigParams::m_ubo_disabled) { GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); } + TU_tex = 0; + + glUseProgram(Program); + glUniform1i(uniform_tex, TU_tex); + glUseProgram(0); } - void TransparentShader::setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &TextureMatrix, unsigned TU_tex) + void TransparentShader::setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &TextureMatrix) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelMatrix.pointer()); glUniformMatrix4fv(uniform_TM, 1, GL_FALSE, TextureMatrix.pointer()); - glUniform1i(uniform_tex, TU_tex); } GLuint TransparentFogShader::Program; GLuint TransparentFogShader::uniform_MVP; GLuint TransparentFogShader::uniform_TM; - GLuint TransparentFogShader::uniform_tex; + GLuint TransparentFogShader::TU_tex; GLuint TransparentFogShader::uniform_fogmax; GLuint TransparentFogShader::uniform_startH; GLuint TransparentFogShader::uniform_endH; @@ -1195,7 +1199,7 @@ namespace MeshShader GL_FRAGMENT_SHADER, file_manager->getAsset("shaders/transparentfog.frag").c_str()); uniform_MVP = glGetUniformLocation(Program, "ModelMatrix"); uniform_TM = glGetUniformLocation(Program, "TextureMatrix"); - uniform_tex = glGetUniformLocation(Program, "tex"); + GLuint uniform_tex = glGetUniformLocation(Program, "tex"); uniform_fogmax = glGetUniformLocation(Program, "fogmax"); uniform_startH = glGetUniformLocation(Program, "startH"); uniform_endH = glGetUniformLocation(Program, "endH"); @@ -1207,9 +1211,14 @@ namespace MeshShader GLuint uniform_ViewProjectionMatrixesUBO = glGetUniformBlockIndex(Program, "MatrixesData"); glUniformBlockBinding(Program, uniform_ViewProjectionMatrixesUBO, 0); } + TU_tex = 0; + + glUseProgram(Program); + glUniform1i(uniform_tex, TU_tex); + glUseProgram(0); } - void TransparentFogShader::setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &TextureMatrix, float fogmax, float startH, float endH, float start, float end, const core::vector3df &col, const core::vector3df &campos, unsigned TU_tex) + void TransparentFogShader::setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &TextureMatrix, float fogmax, float startH, float endH, float start, float end, const core::vector3df &col, const core::vector3df &campos) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelMatrix.pointer()); glUniformMatrix4fv(uniform_TM, 1, GL_FALSE, TextureMatrix.pointer()); @@ -1219,7 +1228,6 @@ namespace MeshShader glUniform1f(uniform_start, start); glUniform1f(uniform_end, end); glUniform3f(uniform_col, col.X, col.Y, col.Z); - glUniform1i(uniform_tex, TU_tex); } GLuint BillboardShader::Program; diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 885d8807a..87e7f41d0 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -253,20 +253,22 @@ class TransparentShader { public: static GLuint Program; - static GLuint uniform_MVP, uniform_TM, uniform_tex; + static GLuint uniform_MVP, uniform_TM; + static GLuint TU_tex; static void init(); - static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &TextureMatrix, unsigned TU_tex); + static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &TextureMatrix); }; class TransparentFogShader { public: static GLuint Program; - static GLuint uniform_MVP, uniform_TM, uniform_tex, uniform_fogmax, uniform_startH, uniform_endH, uniform_start, uniform_end, uniform_col; + static GLuint uniform_MVP, uniform_TM, uniform_fogmax, uniform_startH, uniform_endH, uniform_start, uniform_end, uniform_col; + static GLuint TU_tex; static void init(); - static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &TextureMatrix, float fogmax, float startH, float endH, float start, float end, const core::vector3df &col, const core::vector3df &campos, unsigned TU_tex); + static void setUniforms(const core::matrix4 &ModelMatrix, const core::matrix4 &TextureMatrix, float fogmax, float startH, float endH, float start, float end, const core::vector3df &col, const core::vector3df &campos); }; class BillboardShader diff --git a/src/graphics/stkanimatedmesh.cpp b/src/graphics/stkanimatedmesh.cpp index 7561e353b..d96b72d21 100644 --- a/src/graphics/stkanimatedmesh.cpp +++ b/src/graphics/stkanimatedmesh.cpp @@ -6,6 +6,7 @@ #include "config/user_config.hpp" #include "modes/world.hpp" #include "tracks/track.hpp" +#include "graphics/camera.hpp" #include "utils/profiler.hpp" using namespace irr; @@ -200,16 +201,40 @@ void STKAnimatedMesh::render() glUseProgram(MeshShader::BubbleShader::Program); GLMesh* mesh; - for_in(mesh, TransparentMesh[TM_DEFAULT]) + if (World::getWorld() && World::getWorld()->isFogEnabled()) { - TransparentMeshes::MeshSet.push_back(mesh); - TransparentMeshes::MVPSet.push_back(AbsoluteTransformation); - } + const Track * const track = World::getWorld()->getTrack(); - for_in(mesh, TransparentMesh[TM_ADDITIVE]) + // Todo : put everything in a ubo + const float fogmax = track->getFogMax(); + const float startH = track->getFogStartHeight(); + const float endH = track->getFogEndHeight(); + const float start = track->getFogStart(); + const float end = track->getFogEnd(); + const video::SColor tmpcol = track->getFogColor(); + + core::vector3df col(tmpcol.getRed() / 255.0f, + tmpcol.getGreen() / 255.0f, + tmpcol.getBlue() / 255.0f); + + for_in(mesh, TransparentMesh[TM_DEFAULT]) + ListBlendTransparentFog::Arguments.push_back( + std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix, + fogmax, startH, endH, start, end, col, + Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition())); + for_in(mesh, TransparentMesh[TM_ADDITIVE]) + ListAdditiveTransparentFog::Arguments.push_back( + std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix, + fogmax, startH, endH, start, end, col, + Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition())); + } + else { - TransparentMeshes::MeshSet.push_back(mesh); - TransparentMeshes::MVPSet.push_back(AbsoluteTransformation); + for_in(mesh, TransparentMesh[TM_DEFAULT]) + ListBlendTransparent::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix)); + + for_in(mesh, TransparentMesh[TM_ADDITIVE]) + ListAdditiveTransparent::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix)); } return; } diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index f8c614ba9..71112650f 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -379,58 +379,6 @@ void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio glDrawElementsBaseVertex(ptype, count, itype, (GLvoid *)mesh.vaoOffset, mesh.vaoBaseVertex); } -void drawTransparentObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix) -{ - irr_driver->IncreaseObjectCount(); - GLenum ptype = mesh.PrimitiveType; - GLenum itype = mesh.IndexType; - size_t count = mesh.IndexCount; - - compressTexture(mesh.textures[0], true); - setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - - MeshShader::TransparentShader::setUniforms(ModelViewProjectionMatrix, TextureMatrix, 0); - - assert(mesh.vao); - glBindVertexArray(mesh.vao); - glDrawElements(ptype, count, itype, 0); -} - -void drawTransparentFogObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix) -{ - irr_driver->IncreaseObjectCount(); - GLenum ptype = mesh.PrimitiveType; - GLenum itype = mesh.IndexType; - size_t count = mesh.IndexCount; - - const Track * const track = World::getWorld()->getTrack(); - - // This function is only called once per frame - thus no need for setters. - const float fogmax = track->getFogMax(); - const float startH = track->getFogStartHeight(); - const float endH = track->getFogEndHeight(); - const float start = track->getFogStart(); - const float end = track->getFogEnd(); - const video::SColor tmpcol = track->getFogColor(); - - core::vector3df col(tmpcol.getRed() / 255.0f, - tmpcol.getGreen() / 255.0f, - tmpcol.getBlue() / 255.0f); - - if (mesh.textures[0] != NULL) - { - compressTexture(mesh.textures[0], true); - setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - } - - glUseProgram(MeshShader::TransparentFogShader::Program); - MeshShader::TransparentFogShader::setUniforms(ModelViewProjectionMatrix, TextureMatrix, fogmax, startH, endH, start, end, col, Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition(), 0); - - assert(mesh.vao); - glBindVertexArray(mesh.vao); - glDrawElements(ptype, count, itype, 0); -} - void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix) { irr_driver->IncreaseObjectCount(); @@ -524,4 +472,8 @@ std::vector > ListDefaultTang std::vector > ListAlphaRefSM::Arguments; std::vector > ListSphereMapSM::Arguments; std::vector > ListUnlitSM::Arguments; -std::vector > ListDetailSM::Arguments; \ No newline at end of file +std::vector > ListDetailSM::Arguments; +std::vector > ListBlendTransparent::Arguments; +std::vector > ListAdditiveTransparent::Arguments; +std::vector > ListBlendTransparentFog::Arguments; +std::vector > ListAdditiveTransparentFog::Arguments; diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index 95685d426..8b7276c57 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -145,6 +145,30 @@ public: static std::vector > Arguments; }; +class ListBlendTransparent +{ +public: + static std::vector > Arguments; +}; + +class ListAdditiveTransparent +{ +public: + static std::vector > Arguments; +}; + +class ListBlendTransparentFog +{ +public: + static std::vector > Arguments; +}; + +class ListAdditiveTransparentFog +{ +public: + static std::vector > Arguments; +}; + template class GroupedSM { @@ -194,8 +218,6 @@ template std::vector TransparentMeshes::MVPSet; // Forward pass (for transparents meshes) -void drawTransparentObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix); -void drawTransparentFogObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix); void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix); GeometricMaterial MaterialTypeToGeometricMaterial(video::E_MATERIAL_TYPE, video::E_VERTEX_TYPE); diff --git a/src/graphics/stkmeshscenenode.cpp b/src/graphics/stkmeshscenenode.cpp index 54d0f0e62..59d399522 100644 --- a/src/graphics/stkmeshscenenode.cpp +++ b/src/graphics/stkmeshscenenode.cpp @@ -431,7 +431,7 @@ void STKMeshSceneNode::render() compressTexture(mesh.textures[0], true); setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - MeshShader::TransparentFogShader::setUniforms(AbsoluteTransformation, mesh.TextureMatrix, fogmax, startH, endH, start, end, col, Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition(), 0); + MeshShader::TransparentFogShader::setUniforms(AbsoluteTransformation, mesh.TextureMatrix, fogmax, startH, endH, start, end, col, Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition()); assert(mesh.vao); glBindVertexArray(mesh.vao); @@ -451,9 +451,9 @@ void STKMeshSceneNode::render() size_t count = mesh.IndexCount; compressTexture(mesh.textures[0], true); - setTexture(0, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::TransparentShader::TU_tex, getTextureGLuint(mesh.textures[0]), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - MeshShader::TransparentShader::setUniforms(AbsoluteTransformation, mesh.TextureMatrix, 0); + MeshShader::TransparentShader::setUniforms(AbsoluteTransformation, mesh.TextureMatrix); assert(mesh.vao); glBindVertexArray(mesh.vao); glDrawElements(ptype, count, itype, 0); @@ -465,16 +465,40 @@ void STKMeshSceneNode::render() GLMesh* mesh; - for_in(mesh, TransparentMesh[TM_DEFAULT]) + if (World::getWorld() && World::getWorld()->isFogEnabled()) { - TransparentMeshes::MeshSet.push_back(mesh); - TransparentMeshes::MVPSet.push_back(AbsoluteTransformation); - } + const Track * const track = World::getWorld()->getTrack(); - for_in(mesh, TransparentMesh[TM_ADDITIVE]) + // Todo : put everything in a ubo + const float fogmax = track->getFogMax(); + const float startH = track->getFogStartHeight(); + const float endH = track->getFogEndHeight(); + const float start = track->getFogStart(); + const float end = track->getFogEnd(); + const video::SColor tmpcol = track->getFogColor(); + + core::vector3df col(tmpcol.getRed() / 255.0f, + tmpcol.getGreen() / 255.0f, + tmpcol.getBlue() / 255.0f); + + for_in(mesh, TransparentMesh[TM_DEFAULT]) + ListBlendTransparentFog::Arguments.push_back( + std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix, + fogmax, startH, endH, start, end, col, + Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition())); + for_in(mesh, TransparentMesh[TM_ADDITIVE]) + ListAdditiveTransparentFog::Arguments.push_back( + std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix, + fogmax, startH, endH, start, end, col, + Camera::getCamera(0)->getCameraSceneNode()->getAbsolutePosition())); + } + else { - TransparentMeshes::MeshSet.push_back(mesh); - TransparentMeshes::MVPSet.push_back(AbsoluteTransformation); + for_in(mesh, TransparentMesh[TM_DEFAULT]) + ListBlendTransparent::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix)); + + for_in(mesh, TransparentMesh[TM_ADDITIVE]) + ListAdditiveTransparent::Arguments.push_back(std::make_tuple(mesh, AbsoluteTransformation, mesh->TextureMatrix)); } if (!TransparentMesh[TM_BUBBLE].empty())