From cf2035ca0ad4cb4d9e3b668c7b1035b77747dd58 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Sun, 9 Mar 2014 22:52:51 +0100 Subject: [PATCH 1/5] Batch draw calls --- .../source/Irrlicht/CIrrDeviceLinux.cpp | 2 +- src/graphics/stkanimatedmesh.cpp | 280 +++++++++----- src/graphics/stkanimatedmesh.hpp | 10 +- src/graphics/stkmesh.cpp | 362 ++++++++++------- src/graphics/stkmesh.hpp | 45 ++- src/graphics/stkmeshscenenode.cpp | 366 +++++++++++------- src/graphics/stkmeshscenenode.hpp | 13 +- 7 files changed, 679 insertions(+), 399 deletions(-) diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp index 4829cf72c..4769a079c 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp @@ -745,7 +745,7 @@ bool CIrrDeviceLinux::createWindow() { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 3, - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, //GLX_CONTEXT_CORE_PROFILE_BIT_ARB +// GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, //GLX_CONTEXT_CORE_PROFILE_BIT_ARB GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, None }; diff --git a/src/graphics/stkanimatedmesh.cpp b/src/graphics/stkanimatedmesh.cpp index 1beb8ef28..8bb937dd1 100644 --- a/src/graphics/stkanimatedmesh.cpp +++ b/src/graphics/stkanimatedmesh.cpp @@ -23,72 +23,52 @@ void STKAnimatedMesh::setMesh(scene::IAnimatedMesh* mesh) { firstTime = true; GLmeshes.clear(); + for (unsigned i = 0; i < FPSM_COUNT; i++) + GeometricMesh[i].clear(); + for (unsigned i = 0; i < SM_COUNT; i++) + ShadedMesh[i].clear(); CAnimatedMeshSceneNode::setMesh(mesh); } -void STKAnimatedMesh::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type) +void STKAnimatedMesh::drawSolidPass1(const GLMesh &mesh, GeometricMaterial type) { - assert(irr_driver->getPhase() == TRANSPARENT_PASS); - - computeMVP(ModelViewProjectionMatrix); - - if (World::getWorld()->getTrack()->isFogEnabled()) - drawTransparentFogObject(mesh, ModelViewProjectionMatrix, TextureMatrix); - else - drawTransparentObject(mesh, ModelViewProjectionMatrix, TextureMatrix); - - return; + switch (type) + { + case FPSM_ALPHA_REF_TEXTURE: + drawObjectRefPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, mesh.TextureMatrix); + break; + case FPSM_DEFAULT: + drawObjectPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView); + break; + default: + assert(0 && "Wrong geometric material"); + break; + } } -void STKAnimatedMesh::drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type) +void STKAnimatedMesh::drawSolidPass2(const GLMesh &mesh, ShadedMaterial type) { - switch (irr_driver->getPhase()) - { - case SOLID_NORMAL_AND_DEPTH_PASS: - { - computeMVP(ModelViewProjectionMatrix); - computeTIMV(TransposeInverseModelView); - - if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) - drawObjectRefPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix); - else - drawObjectPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView); - break; - } - case SOLID_LIT_PASS: - { - if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) - drawObjectRefPass2(mesh, ModelViewProjectionMatrix, TextureMatrix); - else if (type == irr_driver->getShader(ES_OBJECTPASS_RIMLIT)) - drawObjectRimLimit(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix); - else if (type == irr_driver->getShader(ES_OBJECT_UNLIT)) - drawObjectUnlit(mesh, ModelViewProjectionMatrix); - else if (mesh.textures[1]) - drawDetailledObjectPass2(mesh, ModelViewProjectionMatrix); - else - drawObjectPass2(mesh, ModelViewProjectionMatrix, TextureMatrix); - break; - } - default: - { - assert(0 && "wrong pass"); - } - } -} - -void STKAnimatedMesh::drawShadow(const GLMesh &mesh) -{ - GLenum ptype = mesh.PrimitiveType; - GLenum itype = mesh.IndexType; - size_t count = mesh.IndexCount; - assert(irr_driver->getPhase() == SHADOW_PASS); - std::vector ShadowMVP(irr_driver->getShadowViewProj()); - for (unsigned i = 0; i < ShadowMVP.size(); i++) - ShadowMVP[i] *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - glUseProgram(MeshShader::ShadowShader::Program); - MeshShader::ShadowShader::setUniforms(ShadowMVP); - glBindVertexArray(mesh.vao_shadow_pass); - glDrawElements(ptype, count, itype, 0); + switch (type) + { + case SM_ALPHA_REF_TEXTURE: + drawObjectRefPass2(mesh, ModelViewProjectionMatrix, mesh.TextureMatrix); + break; + case SM_RIMLIT: + drawObjectRimLimit(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, mesh.TextureMatrix); + break; + case SM_UNLIT: + drawObjectUnlit(mesh, ModelViewProjectionMatrix); + break; + case SM_DETAILS: + drawDetailledObjectPass2(mesh, ModelViewProjectionMatrix); + break; + case SM_DEFAULT: + drawObjectPass2(mesh, ModelViewProjectionMatrix, mesh.TextureMatrix); + break; + default: + assert(0 && "Wrong shaded material"); + break; + } } void STKAnimatedMesh::render() @@ -114,54 +94,142 @@ void STKAnimatedMesh::render() driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); - if (firstTime) - for (u32 i = 0; igetMeshBufferCount(); ++i) - { - scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); - GLmeshes.push_back(allocateMeshBuffer(mb)); - } + if (firstTime) + { + for (u32 i = 0; i < m->getMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); + GLmeshes.push_back(allocateMeshBuffer(mb)); + } + + for (u32 i = 0; i < m->getMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); + if (!mb) + continue; + video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType; + video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type); + if (!isObject(type)) + { +#ifdef DEBUG + Log::warn("material", "Unhandled (animated) material type : %d", type); +#endif + continue; + } + GLMesh &mesh = GLmeshes[i]; + if (rnd->isTransparent()) + { + TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type); + initvaostate(mesh, TranspMat); + TransparentMesh[TranspMat].push_back(&mesh); + } + else + { + GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type); + ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures); + initvaostate(mesh, GeometricType, ShadedType); + GeometricMesh[GeometricType].push_back(&mesh); + ShadedMesh[ShadedType].push_back(&mesh); + } + } + } firstTime = false; - // render original meshes - for (u32 i = 0; igetMeshBufferCount(); ++i) - { - video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType); - bool transparent = (rnd && rnd->isTransparent()); - - // only render transparent buffer if this is the transparent render pass - // and solid only in solid pass - if (transparent != isTransparentPass) - continue; - scene::IMeshBuffer* mb = m->getMeshBuffer(i); - TextureMatrix = getMaterial(i).getTextureMatrix(0); - const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; - if (RenderFromIdentity) - driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); - else if (Mesh->getMeshType() == scene::EAMT_SKINNED) - driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((scene::SSkinMeshBuffer*)mb)->Transformation); + for (u32 i = 0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = m->getMeshBuffer(i); + const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; if (isObject(material.MaterialType)) - { - irr_driver->IncreaseObjectCount(); - initvaostate(GLmeshes[i], material.MaterialType); - if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS) - { - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, GLmeshes[i].vertex_buffer); - glBufferSubData(GL_ARRAY_BUFFER, 0, mb->getVertexCount() * GLmeshes[i].Stride, mb->getVertices()); - } - if (irr_driver->getPhase() == SHADOW_PASS) - drawShadow(GLmeshes[i]); - else if (isTransparentPass) - drawTransparent(GLmeshes[i], material.MaterialType); - else - drawSolid(GLmeshes[i], material.MaterialType); - } - else - { -#ifdef DEBUG - Log::warn("material", "Unhandled (animated) material type : %d", material.MaterialType); -#endif - continue; - } - } + { + if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS) + { + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, GLmeshes[i].vertex_buffer); + glBufferSubData(GL_ARRAY_BUFFER, 0, mb->getVertexCount() * GLmeshes[i].Stride, mb->getVertices()); + } + } + if (mb) + GLmeshes[i].TextureMatrix = getMaterial(i).getTextureMatrix(0); + + video::IMaterialRenderer* rnd = driver->getMaterialRenderer(Materials[i].MaterialType); + bool transparent = (rnd && rnd->isTransparent()); + + // only render transparent buffer if this is the transparent render pass + // and solid only in solid pass + if (transparent != isTransparentPass) + continue; + + if (RenderFromIdentity) + driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); + else if (Mesh->getMeshType() == scene::EAMT_SKINNED) + driver->setTransform(video::ETS_WORLD, AbsoluteTransformation * ((scene::SSkinMeshBuffer*)mb)->Transformation); + + } + + if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS) + { + computeMVP(ModelViewProjectionMatrix); + computeTIMV(TransposeInverseModelView); + + glUseProgram(MeshShader::ObjectPass1Shader::Program); + for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++) + drawSolidPass1(*GeometricMesh[FPSM_DEFAULT][i], FPSM_DEFAULT); + + glUseProgram(MeshShader::ObjectRefPass1Shader::Program); + for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++) + drawSolidPass1(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i], FPSM_ALPHA_REF_TEXTURE); + + return; + } + + if (irr_driver->getPhase() == SOLID_LIT_PASS) + { + glUseProgram(MeshShader::ObjectPass2Shader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_DEFAULT].size(); i++) + drawSolidPass2(*ShadedMesh[SM_DEFAULT][i], SM_DEFAULT); + + glUseProgram(MeshShader::ObjectRefPass2Shader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_ALPHA_REF_TEXTURE].size(); i++) + drawSolidPass2(*ShadedMesh[SM_ALPHA_REF_TEXTURE][i], SM_ALPHA_REF_TEXTURE); + + glUseProgram(MeshShader::ObjectRimLimitShader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_RIMLIT].size(); i++) + drawSolidPass2(*ShadedMesh[SM_RIMLIT][i], SM_RIMLIT); + + glUseProgram(MeshShader::ObjectUnlitShader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_UNLIT].size(); i++) + drawSolidPass2(*ShadedMesh[SM_UNLIT][i], SM_UNLIT); + + glUseProgram(MeshShader::DetailledObjectPass2Shader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_DETAILS].size(); i++) + drawSolidPass2(*ShadedMesh[SM_DETAILS][i], SM_DETAILS); + + return; + } + + if (irr_driver->getPhase() == SHADOW_PASS) + { + glUseProgram(MeshShader::ShadowShader::Program); + for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++) + drawShadow(*GeometricMesh[FPSM_DEFAULT][i]); + + glUseProgram(MeshShader::RefShadowShader::Program); + for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++) + drawShadowRef(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i]); + return; + } + + if (irr_driver->getPhase() == TRANSPARENT_PASS) + { + computeMVP(ModelViewProjectionMatrix); + + glUseProgram(MeshShader::BubbleShader::Program); + for (unsigned i = 0; i < TransparentMesh[TM_BUBBLE].size(); i++) + drawBubble(*TransparentMesh[TM_BUBBLE][i], ModelViewProjectionMatrix); + + glUseProgram(MeshShader::TransparentShader::Program); + for (unsigned i = 0; i < TransparentMesh[TM_DEFAULT].size(); i++) + drawTransparentObject(*TransparentMesh[TM_DEFAULT][i], ModelViewProjectionMatrix, (*TransparentMesh[TM_DEFAULT][i]).TextureMatrix); + return; + } } diff --git a/src/graphics/stkanimatedmesh.hpp b/src/graphics/stkanimatedmesh.hpp index 7ff5b6109..20521b2d3 100644 --- a/src/graphics/stkanimatedmesh.hpp +++ b/src/graphics/stkanimatedmesh.hpp @@ -11,11 +11,13 @@ class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode { protected: bool firstTime; + std::vector GeometricMesh[FPSM_COUNT]; + std::vector ShadedMesh[SM_COUNT]; + std::vector TransparentMesh[TM_COUNT]; std::vector GLmeshes; - core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix; - void drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type); - void drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type); - void drawShadow(const GLMesh &mesh); + core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView; + void drawSolidPass1(const GLMesh &mesh, GeometricMaterial type); + void drawSolidPass2(const GLMesh &mesh, ShadedMaterial type); public: STKAnimatedMesh(irr::scene::IAnimatedMesh* mesh, irr::scene::ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index 6078bdb4d..db34974b0 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -9,6 +9,49 @@ #include "graphics/camera.hpp" #include "modes/world.hpp" +GeometricMaterial MaterialTypeToGeometricMaterial(video::E_MATERIAL_TYPE MaterialType) +{ + if (MaterialType == irr_driver->getShader(ES_NORMAL_MAP)) + return FPSM_NORMAL_MAP; + else if (MaterialType == irr_driver->getShader(ES_OBJECTPASS_REF) || MaterialType == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF) + return FPSM_ALPHA_REF_TEXTURE; + else if (MaterialType == irr_driver->getShader(ES_GRASS) || MaterialType == irr_driver->getShader(ES_GRASS_REF)) + return FPSM_GRASS; + else + return FPSM_DEFAULT; +} + +ShadedMaterial MaterialTypeToShadedMaterial(video::E_MATERIAL_TYPE type, GLuint *textures) +{ + if (type == irr_driver->getShader(ES_SPHERE_MAP)) + return SM_SPHEREMAP; + else if (type == irr_driver->getShader(ES_SPLATTING)) + return SM_SPLATTING; + else if (type == irr_driver->getShader(ES_OBJECTPASS_REF) || type == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF) + return SM_ALPHA_REF_TEXTURE; + else if (type == irr_driver->getShader(ES_OBJECTPASS_RIMLIT)) + return SM_RIMLIT; + else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) + return SM_GRASS; + else if (type == irr_driver->getShader(ES_OBJECT_UNLIT)) + return SM_UNLIT; + else if (type == irr_driver->getShader(ES_CAUSTICS)) + return SM_CAUSTICS; + else if (textures[1] && type != irr_driver->getShader(ES_NORMAL_MAP)) + return SM_DETAILS; + else if (!textures[0]) + return SM_UNTEXTURED; + else + return SM_DEFAULT; +} + +TransparentMaterial MaterialTypeToTransparentMaterial(video::E_MATERIAL_TYPE type) +{ + if (type == irr_driver->getShader(ES_BUBBLES)) + return TM_BUBBLE; + else + return TM_DEFAULT; +} GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_second_texcoord, GLuint attrib_normal, GLuint attrib_tangent, GLuint attrib_bitangent, GLuint attrib_color, size_t stride) { @@ -141,6 +184,7 @@ GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb) else result.textures[i] = 0; } + result.TextureMatrix = 0; return result; } @@ -162,11 +206,11 @@ void computeTIMV(core::matrix4 &TransposeInverseModelView) void drawObjectPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView) { + irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - glUseProgram(MeshShader::ObjectPass1Shader::Program); MeshShader::ObjectPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView); glBindVertexArray(mesh.vao_first_pass); @@ -175,6 +219,7 @@ void drawObjectPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjecti void drawObjectRefPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &TextureMatrix) { + irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -182,7 +227,6 @@ void drawObjectRefPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProje setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - glUseProgram(MeshShader::ObjectRefPass1Shader::Program); MeshShader::ObjectRefPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix, 0); glBindVertexArray(mesh.vao_first_pass); @@ -191,13 +235,13 @@ void drawObjectRefPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProje void drawGrassPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, core::vector3df windDir) { + irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - glUseProgram(MeshShader::GrassPass1Shader::Program); MeshShader::GrassPass1Shader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, windDir, 0); glBindVertexArray(mesh.vao_first_pass); @@ -206,6 +250,7 @@ void drawGrassPass1(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio void drawNormalPass(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView) { + irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -213,7 +258,6 @@ void drawNormalPass(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio assert(mesh.textures[1]); setTexture(0, mesh.textures[1], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - glUseProgram(MeshShader::NormalMapShader::Program); MeshShader::NormalMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, 0); glBindVertexArray(mesh.vao_first_pass); @@ -222,6 +266,7 @@ void drawNormalPass(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView) { + irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -234,12 +279,11 @@ void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM } else { - glBindBuffer(GL_TEXTURE_CUBE_MAP, irr_driver->SkyboxCubeMap); + glBindTexture(GL_TEXTURE_CUBE_MAP, irr_driver->SkyboxCubeMap); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } - glUseProgram(MeshShader::SphereMapShader::Program); MeshShader::SphereMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, irr_driver->getInvProjMatrix(), core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0); glBindVertexArray(mesh.vao_second_pass); @@ -253,6 +297,7 @@ void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix) { + irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -331,7 +376,6 @@ void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - glUseProgram(MeshShader::SplattingShader::Program); MeshShader::SplattingShader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3, 4, 5, 6, 7); glBindVertexArray(mesh.vao_second_pass); @@ -340,6 +384,7 @@ void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM void drawObjectRefPass2(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; @@ -364,7 +409,6 @@ void drawObjectRefPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjec glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - glUseProgram(MeshShader::ObjectRefPass2Shader::Program); MeshShader::ObjectRefPass2Shader::setUniforms(ModelViewProjectionMatrix, TextureMatrix, 0, 1, 2, 3); glBindVertexArray(mesh.vao_second_pass); @@ -373,6 +417,7 @@ void drawObjectRefPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjec void drawCaustics(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, core::vector2df dir, core::vector2df dir2) { + irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -398,8 +443,6 @@ void drawCaustics(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionM glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - - glUseProgram(MeshShader::CausticsShader::Program); MeshShader::CausticsShader::setUniforms(ModelViewProjectionMatrix, dir, dir2, core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0, 2, 3, 4, 1); glBindVertexArray(mesh.vao_second_pass); @@ -408,6 +451,7 @@ void drawCaustics(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionM void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionMatrix, core::vector3df windDir) { + irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -432,7 +476,6 @@ void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - glUseProgram(MeshShader::GrassPass2Shader::Program); MeshShader::GrassPass2Shader::setUniforms(ModelViewProjectionMatrix, windDir, 0, 1, 2, 3); glBindVertexArray(mesh.vao_second_pass); @@ -441,6 +484,7 @@ void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio void drawUntexturedObject(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix) { + irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -453,9 +497,7 @@ void drawUntexturedObject(const GLMesh &mesh, const core::matrix4 &ModelViewProj GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ONE}; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - - glUseProgram(MeshShader::UntexturedObjectShader::Program); MeshShader::UntexturedObjectShader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2); glBindVertexArray(mesh.vao_second_pass); @@ -464,6 +506,7 @@ void drawUntexturedObject(const GLMesh &mesh, const core::matrix4 &ModelViewProj void drawObjectRimLimit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &TextureMatrix) { + irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -489,7 +532,6 @@ void drawObjectRimLimit(const GLMesh &mesh, const core::matrix4 &ModelViewProjec glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - glUseProgram(MeshShader::ObjectRimLimitShader::Program); MeshShader::ObjectRimLimitShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix, 0, 1, 2, 3); glBindVertexArray(mesh.vao_second_pass); @@ -498,6 +540,7 @@ void drawObjectRimLimit(const GLMesh &mesh, const core::matrix4 &ModelViewProjec void drawObjectUnlit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix) { + irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -514,8 +557,6 @@ void drawObjectUnlit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectio glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - - glUseProgram(MeshShader::ObjectUnlitShader::Program); MeshShader::ObjectUnlitShader::setUniforms(ModelViewProjectionMatrix, 0); glBindVertexArray(mesh.vao_second_pass); @@ -524,6 +565,7 @@ void drawObjectUnlit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectio void drawDetailledObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix) { + irr_driver->IncreaseObjectCount(); GLenum ptype = mesh.PrimitiveType; GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; @@ -551,7 +593,6 @@ void drawDetailledObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelView glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - glUseProgram(MeshShader::DetailledObjectPass2Shader::Program); MeshShader::DetailledObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3, 4); glBindVertexArray(mesh.vao_second_pass); @@ -560,6 +601,7 @@ void drawDetailledObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelView void drawObjectPass2(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; @@ -585,7 +627,6 @@ void drawObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjectio glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - glUseProgram(MeshShader::ObjectPass2Shader::Program); MeshShader::ObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, TextureMatrix, 0, 1, 2, 3); glBindVertexArray(mesh.vao_second_pass); @@ -594,13 +635,13 @@ void drawObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjectio 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; setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - glUseProgram(MeshShader::TransparentShader::Program); MeshShader::TransparentShader::setUniforms(ModelViewProjectionMatrix, TextureMatrix, 0); glBindVertexArray(mesh.vao_first_pass); @@ -609,6 +650,7 @@ void drawTransparentObject(const GLMesh &mesh, const core::matrix4 &ModelViewPro 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; @@ -638,6 +680,7 @@ void drawTransparentFogObject(const GLMesh &mesh, const core::matrix4 &ModelView void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix) { + irr_driver->IncreaseObjectCount(); const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f; float transparency = 1.; @@ -647,13 +690,54 @@ void drawBubble(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatr setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - glUseProgram(MeshShader::BubbleShader::Program); MeshShader::BubbleShader::setUniforms(ModelViewProjectionMatrix, 0, time, transparency); glBindVertexArray(mesh.vao_first_pass); glDrawElements(ptype, count, itype, 0); } +void drawShadowRef(const GLMesh &mesh) +{ + irr_driver->IncreaseObjectCount(); + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + std::vector ShadowMVP(irr_driver->getShadowViewProj()); + for (unsigned i = 0; i < ShadowMVP.size(); i++) + ShadowMVP[i] *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + + setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + MeshShader::RefShadowShader::setUniforms(ShadowMVP, 0); + + glBindVertexArray(mesh.vao_shadow_pass); + glDrawElements(ptype, count, itype, 0); +} + +void drawShadow(const GLMesh &mesh) +{ + irr_driver->IncreaseObjectCount(); + GLenum ptype = mesh.PrimitiveType; + GLenum itype = mesh.IndexType; + size_t count = mesh.IndexCount; + + std::vector ShadowMVP(irr_driver->getShadowViewProj()); + for (unsigned i = 0; i < ShadowMVP.size(); i++) + ShadowMVP[i] *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); + + /* 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(ShadowMVP); + + glBindVertexArray(mesh.vao_shadow_pass); + glDrawElements(ptype, count, itype, 0); +} + bool isObject(video::E_MATERIAL_TYPE type) { if (type == irr_driver->getShader(ES_OBJECTPASS)) @@ -684,137 +768,119 @@ bool isObject(video::E_MATERIAL_TYPE type) return true; if (type == video::EMT_TRANSPARENT_ADD_COLOR) return true; + if (type == video::EMT_SOLID) + return true; + if (type == video::EMT_LIGHTMAP_LIGHTING) + return true; + if (type == video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF) + return true; return false; } -void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type) +void initvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat) { - switch (irr_driver->getPhase()) - { - case SOLID_NORMAL_AND_DEPTH_PASS: - if (mesh.vao_first_pass) - return; - if (type == irr_driver->getShader(ES_NORMAL_MAP)) - { - mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::NormalMapShader::attrib_position, MeshShader::NormalMapShader::attrib_texcoord, -1, -1, MeshShader::NormalMapShader::attrib_tangent, MeshShader::NormalMapShader::attrib_bitangent, -1, mesh.Stride); - } - else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) - { - mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::ObjectPass1Shader::attrib_position, MeshShader::ObjectRefPass1Shader::attrib_texcoord, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride); - } - else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) - { - mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::GrassPass1Shader::attrib_position, MeshShader::GrassPass1Shader::attrib_texcoord, -1, MeshShader::GrassPass1Shader::attrib_normal, -1, -1, MeshShader::GrassPass1Shader::attrib_color, mesh.Stride); - } - else - { - mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::ObjectPass1Shader::attrib_position, -1, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride); - } - return; - case SOLID_LIT_PASS: - if (mesh.vao_second_pass) - return; - if (type == irr_driver->getShader(ES_SPHERE_MAP)) - { - mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::SphereMapShader::attrib_position, -1, -1, MeshShader::SphereMapShader::attrib_normal, -1, -1, -1, mesh.Stride); - } - else if (type == irr_driver->getShader(ES_SPLATTING)) - { - mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::SplattingShader::attrib_position, MeshShader::SplattingShader::attrib_texcoord, MeshShader::SplattingShader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride); - } - else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) - { - mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::ObjectRefPass2Shader::attrib_position, MeshShader::ObjectRefPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); - } - else if (type == irr_driver->getShader(ES_OBJECTPASS_RIMLIT)) - { - mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::ObjectRimLimitShader::attrib_position, MeshShader::ObjectRimLimitShader::attrib_texcoord, -1, MeshShader::ObjectRimLimitShader::attrib_normal, -1, -1, -1, mesh.Stride); - } - else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) - { - mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::GrassPass2Shader::attrib_position, MeshShader::GrassPass2Shader::attrib_texcoord, -1, -1, -1, -1, MeshShader::GrassPass2Shader::attrib_color, mesh.Stride); - } - else if (type == irr_driver->getShader(ES_OBJECT_UNLIT)) - { - mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::ObjectUnlitShader::attrib_position, MeshShader::ObjectUnlitShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); - } - else if (type == irr_driver->getShader(ES_CAUSTICS)) - { - mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::CausticsShader::attrib_position, MeshShader::CausticsShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); - } - else if (mesh.textures[1]) - { - mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::DetailledObjectPass2Shader::attrib_position, MeshShader::DetailledObjectPass2Shader::attrib_texcoord, MeshShader::DetailledObjectPass2Shader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride); - } - else if (!mesh.textures[0]) - { - mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::UntexturedObjectShader::attrib_position, -1, -1, -1, -1, -1, MeshShader::UntexturedObjectShader::attrib_color, mesh.Stride); - } - else - { - mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::ObjectPass2Shader::attrib_position, MeshShader::ObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); - } - return; - case GLOW_PASS: - if (mesh.vao_glow_pass) - return; - mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ColorizeShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride); - return; - case TRANSPARENT_PASS: - if (mesh.vao_first_pass) - return; - if (type == irr_driver->getShader(ES_BUBBLES)) - { - mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::BubbleShader::attrib_position, MeshShader::BubbleShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); - } - else if (World::getWorld()->getTrack()->isFogEnabled()) - { - mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::TransparentFogShader::attrib_position, MeshShader::TransparentFogShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); - } - else - { - mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, - MeshShader::TransparentShader::attrib_position, MeshShader::TransparentShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); - } - return; - case DISPLACEMENT_PASS: - if (mesh.vao_displace_pass) - return; - mesh.vao_displace_mask_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position,-1, -1, -1, -1, -1, -1, mesh.Stride); - mesh.vao_displace_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position, MeshShader::DisplaceShader::attrib_texcoord, MeshShader::DisplaceShader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride); - return; - case SHADOW_PASS: - if (mesh.vao_shadow_pass) - return; - if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) - { - mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::RefShadowShader::attrib_position, MeshShader::RefShadowShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); - } - /*else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) - { - mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::GrassShadowShader::attrib_position, MeshShader::GrassShadowShader::attrib_texcoord, -1, -1, -1, -1, MeshShader::GrassShadowShader::attrib_color, mesh.Stride); - }*/ - else - { - mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride); - } - return; - } + switch (GeoMat) + { + case FPSM_DEFAULT: + mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::ObjectPass1Shader::attrib_position, -1, -1, MeshShader::ObjectPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride); + mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride); + break; + case FPSM_ALPHA_REF_TEXTURE: + mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::ObjectRefPass1Shader::attrib_position, MeshShader::ObjectRefPass1Shader::attrib_texcoord, -1, MeshShader::ObjectRefPass1Shader::attrib_normal, -1, -1, -1, mesh.Stride); + mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::RefShadowShader::attrib_position, MeshShader::RefShadowShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); + break; + case FPSM_NORMAL_MAP: + mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::NormalMapShader::attrib_position, MeshShader::NormalMapShader::attrib_texcoord, -1, -1, MeshShader::NormalMapShader::attrib_tangent, MeshShader::NormalMapShader::attrib_bitangent, -1, mesh.Stride); + mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ShadowShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride); + break; + case FPSM_GRASS: + mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::GrassPass1Shader::attrib_position, MeshShader::GrassPass1Shader::attrib_texcoord, -1, MeshShader::GrassPass1Shader::attrib_normal, -1, -1, MeshShader::GrassPass1Shader::attrib_color, mesh.Stride); + mesh.vao_shadow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::GrassShadowShader::attrib_position, MeshShader::GrassShadowShader::attrib_texcoord, -1, -1, -1, -1, MeshShader::GrassShadowShader::attrib_color, mesh.Stride); + break; + default: + assert(0 && "Unknow material"); + break; + } + + switch (ShadedMat) + { + case SM_SPHEREMAP: + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::SphereMapShader::attrib_position, -1, -1, MeshShader::SphereMapShader::attrib_normal, -1, -1, -1, mesh.Stride); + break; + case SM_SPLATTING: + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::SplattingShader::attrib_position, MeshShader::SplattingShader::attrib_texcoord, MeshShader::SplattingShader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride); + break; + case SM_ALPHA_REF_TEXTURE: + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::ObjectRefPass2Shader::attrib_position, MeshShader::ObjectRefPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); + break; + case SM_RIMLIT: + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::ObjectRimLimitShader::attrib_position, MeshShader::ObjectRimLimitShader::attrib_texcoord, -1, MeshShader::ObjectRimLimitShader::attrib_normal, -1, -1, -1, mesh.Stride); + break; + case SM_GRASS: + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::GrassPass2Shader::attrib_position, MeshShader::GrassPass2Shader::attrib_texcoord, -1, -1, -1, -1, MeshShader::GrassPass2Shader::attrib_color, mesh.Stride); + break; + case SM_UNLIT: + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::ObjectUnlitShader::attrib_position, MeshShader::ObjectUnlitShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); + break; + case SM_CAUSTICS: + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::CausticsShader::attrib_position, MeshShader::CausticsShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); + break; + case SM_DETAILS: + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::DetailledObjectPass2Shader::attrib_position, MeshShader::DetailledObjectPass2Shader::attrib_texcoord, MeshShader::DetailledObjectPass2Shader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride); + break; + case SM_UNTEXTURED: + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::UntexturedObjectShader::attrib_position, -1, -1, -1, -1, -1, MeshShader::UntexturedObjectShader::attrib_color, mesh.Stride); + break; + case SM_DEFAULT: + mesh.vao_second_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::ObjectPass2Shader::attrib_position, MeshShader::ObjectPass2Shader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); + break; + default: + assert(0 && "unknow shaded material"); + break; + } + + mesh.vao_glow_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::ColorizeShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride); + mesh.vao_displace_mask_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride); + if (mesh.Stride >= 44) + mesh.vao_displace_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position, MeshShader::DisplaceShader::attrib_texcoord, MeshShader::DisplaceShader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride); +} + +void initvaostate(GLMesh &mesh, TransparentMaterial TranspMat) +{ + switch (TranspMat) + { + case TM_BUBBLE: + mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::BubbleShader::attrib_position, MeshShader::BubbleShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); + break; + case TM_DEFAULT: + mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, + MeshShader::TransparentShader::attrib_position, MeshShader::TransparentShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); + break; + } + mesh.vao_displace_mask_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position, -1, -1, -1, -1, -1, -1, mesh.Stride); + if (mesh.Stride >= 44) + mesh.vao_displace_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, MeshShader::DisplaceShader::attrib_position, MeshShader::DisplaceShader::attrib_texcoord, MeshShader::DisplaceShader::attrib_second_texcoord, -1, -1, -1, -1, mesh.Stride); + +/* +else if (World::getWorld()->getTrack()->isFogEnabled()) +{ +mesh.vao_first_pass = createVAO(mesh.vertex_buffer, mesh.index_buffer, +MeshShader::TransparentFogShader::attrib_position, MeshShader::TransparentFogShader::attrib_texcoord, -1, -1, -1, -1, -1, mesh.Stride); +}*/ } diff --git a/src/graphics/stkmesh.hpp b/src/graphics/stkmesh.hpp index f9758e86f..d24834ed7 100644 --- a/src/graphics/stkmesh.hpp +++ b/src/graphics/stkmesh.hpp @@ -8,6 +8,37 @@ #include "glwrap.hpp" #include +enum GeometricMaterial +{ + FPSM_DEFAULT, + FPSM_ALPHA_REF_TEXTURE, + FPSM_NORMAL_MAP, + FPSM_GRASS, + FPSM_COUNT +}; + +enum ShadedMaterial +{ + SM_DEFAULT, + SM_ALPHA_REF_TEXTURE, + SM_RIMLIT, + SM_SPHEREMAP, + SM_SPLATTING, + SM_GRASS, + SM_UNLIT, + SM_CAUSTICS, + SM_DETAILS, + SM_UNTEXTURED, + SM_COUNT +}; + +enum TransparentMaterial +{ + TM_DEFAULT, + TM_BUBBLE, + TM_COUNT +}; + struct GLMesh { GLuint vao_first_pass; GLuint vao_second_pass; @@ -22,11 +53,13 @@ struct GLMesh { GLenum IndexType; size_t IndexCount; size_t Stride; + core::matrix4 TextureMatrix; }; GLuint createVAO(GLuint vbo, GLuint idx, GLuint attrib_position, GLuint attrib_texcoord, GLuint attrib_second_texcoord, GLuint attrib_normal, GLuint attrib_tangent, GLuint attrib_bitangent, GLuint attrib_color, size_t stride); GLMesh allocateMeshBuffer(scene::IMeshBuffer* mb); -void initvaostate(GLMesh &mesh, video::E_MATERIAL_TYPE type); +void initvaostate(GLMesh &mesh, GeometricMaterial GeoMat, ShadedMaterial ShadedMat); +void initvaostate(GLMesh &mesh, TransparentMaterial TranspMat); void computeMVP(core::matrix4 &ModelViewProjectionMatrix); void computeTIMV(core::matrix4 &TransposeInverseModelView); bool isObject(video::E_MATERIAL_TYPE type); @@ -49,9 +82,17 @@ void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio void drawObjectRimLimit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &TextureMatrix); void drawObjectUnlit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionMatrix); +// Shadow pass +void drawShadowRef(const GLMesh &mesh); +void drawShadow(const GLMesh &mesh); + // 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); -#endif // STKMESH_H \ No newline at end of file +GeometricMaterial MaterialTypeToGeometricMaterial(video::E_MATERIAL_TYPE); +ShadedMaterial MaterialTypeToShadedMaterial(video::E_MATERIAL_TYPE, GLuint *textures); +TransparentMaterial MaterialTypeToTransparentMaterial(video::E_MATERIAL_TYPE); + +#endif // STKMESH_H diff --git a/src/graphics/stkmeshscenenode.cpp b/src/graphics/stkmeshscenenode.cpp index 78a31083a..045fef6c6 100644 --- a/src/graphics/stkmeshscenenode.cpp +++ b/src/graphics/stkmeshscenenode.cpp @@ -42,6 +42,46 @@ void STKMeshSceneNode::createGLMeshes() scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); GLmeshes.push_back(allocateMeshBuffer(mb)); } + isMaterialInitialized = false; +} + +void STKMeshSceneNode::setFirstTimeMaterial() +{ + if (isMaterialInitialized) + return; + irr::video::IVideoDriver* driver = irr_driver->getVideoDriver(); + for (u32 i = 0; igetMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); + if (!mb) + continue; + video::E_MATERIAL_TYPE type = mb->getMaterial().MaterialType; + video::IMaterialRenderer* rnd = driver->getMaterialRenderer(type); + if (!isObject(type)) + { +#ifdef DEBUG + Log::warn("material", "Unhandled (static) material type : %d", type); +#endif + continue; + } + + GLMesh &mesh = GLmeshes[i]; + if (rnd->isTransparent()) + { + TransparentMaterial TranspMat = MaterialTypeToTransparentMaterial(type); + initvaostate(mesh, TranspMat); + TransparentMesh[TranspMat].push_back(&mesh); + } + else + { + GeometricMaterial GeometricType = MaterialTypeToGeometricMaterial(type); + ShadedMaterial ShadedType = MaterialTypeToShadedMaterial(type, mesh.textures); + initvaostate(mesh, GeometricType, ShadedType); + GeometricMesh[GeometricType].push_back(&mesh); + ShadedMesh[ShadedType].push_back(&mesh); + } + } + isMaterialInitialized = true; } void STKMeshSceneNode::cleanGLMeshes() @@ -63,6 +103,10 @@ void STKMeshSceneNode::cleanGLMeshes() glDeleteBuffers(1, &(mesh.index_buffer)); } GLmeshes.clear(); + for (unsigned i = 0; i < FPSM_COUNT; i++) + GeometricMesh[i].clear(); + for (unsigned i = 0; i < SM_COUNT; i++) + ShadedMesh[i].clear(); } void STKMeshSceneNode::setMesh(irr::scene::IMesh* mesh) @@ -86,7 +130,6 @@ void STKMeshSceneNode::drawGlow(const GLMesh &mesh) size_t count = mesh.IndexCount; computeMVP(ModelViewProjectionMatrix); - glUseProgram(MeshShader::ColorizeShader::Program); MeshShader::ColorizeShader::setUniforms(ModelViewProjectionMatrix, cb->getRed(), cb->getGreen(), cb->getBlue()); glBindVertexArray(mesh.vao_glow_pass); @@ -135,114 +178,92 @@ void STKMeshSceneNode::drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYP if (type == irr_driver->getShader(ES_BUBBLES)) drawBubble(mesh, ModelViewProjectionMatrix); - else if (World::getWorld()->getTrack()->isFogEnabled()) - drawTransparentFogObject(mesh, ModelViewProjectionMatrix, TextureMatrix); +// else if (World::getWorld()->getTrack()->isFogEnabled()) +// drawTransparentFogObject(mesh, ModelViewProjectionMatrix, TextureMatrix); else - drawTransparentObject(mesh, ModelViewProjectionMatrix, TextureMatrix); + drawTransparentObject(mesh, ModelViewProjectionMatrix, mesh.TextureMatrix); return; } -void STKMeshSceneNode::drawShadow(const GLMesh &mesh, video::E_MATERIAL_TYPE type) +void STKMeshSceneNode::drawSolidPass1(const GLMesh &mesh, GeometricMaterial type) { - - GLenum ptype = mesh.PrimitiveType; - GLenum itype = mesh.IndexType; - size_t count = mesh.IndexCount; - - - std::vector ShadowMVP(irr_driver->getShadowViewProj()); - for (unsigned i = 0; i < ShadowMVP.size(); i++) - ShadowMVP[i] *= irr_driver->getVideoDriver()->getTransform(video::ETS_WORLD); - - if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) + irr_driver->IncreaseObjectCount(); + windDir = getWind(); + switch (type) { - setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - glUseProgram(MeshShader::RefShadowShader::Program); - MeshShader::RefShadowShader::setUniforms(ShadowMVP, 0); + case FPSM_NORMAL_MAP: + drawNormalPass(mesh, ModelViewProjectionMatrix, TransposeInverseModelView); + break; + case FPSM_ALPHA_REF_TEXTURE: + drawObjectRefPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, mesh.TextureMatrix); + break; + case FPSM_GRASS: + drawGrassPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, windDir); + break; + case FPSM_DEFAULT: + drawObjectPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView); + break; + default: + assert(0 && "wrong geometric material"); } - /* else 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); - }*/ - else - { - glUseProgram(MeshShader::ShadowShader::Program); - MeshShader::ShadowShader::setUniforms(ShadowMVP); - } - glBindVertexArray(mesh.vao_shadow_pass); - glDrawElements(ptype, count, itype, 0); } -void STKMeshSceneNode::drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type) +void STKMeshSceneNode::drawSolidPass2(const GLMesh &mesh, ShadedMaterial type) { - switch (irr_driver->getPhase()) + switch (type) { - case SOLID_NORMAL_AND_DEPTH_PASS: + case SM_SPHEREMAP: + drawSphereMap(mesh, ModelViewProjectionMatrix, TransposeInverseModelView); + break; + case SM_SPLATTING: + drawSplatting(mesh, ModelViewProjectionMatrix); + break; + case SM_ALPHA_REF_TEXTURE: + drawObjectRefPass2(mesh, ModelViewProjectionMatrix, mesh.TextureMatrix); + break; + case SM_GRASS: + drawGrassPass2(mesh, ModelViewProjectionMatrix, windDir); + break; + case SM_RIMLIT: + drawObjectRimLimit(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, core::matrix4::EM4CONST_IDENTITY); + break; + case SM_UNLIT: + drawObjectUnlit(mesh, ModelViewProjectionMatrix); + break; + case SM_CAUSTICS: { - windDir = getWind(); + const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f; + const float speed = World::getWorld()->getTrack()->getCausticsSpeed(); - computeMVP(ModelViewProjectionMatrix); - computeTIMV(TransposeInverseModelView); + float strength = time; + strength = fabsf(noise2d(strength / 10.0f)) * 0.006f + 0.001f; - if (type == irr_driver->getShader(ES_NORMAL_MAP)) - drawNormalPass(mesh, ModelViewProjectionMatrix, TransposeInverseModelView); - else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) - drawObjectRefPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix); - else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) - drawGrassPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, windDir); - else - drawObjectPass1(mesh, ModelViewProjectionMatrix, TransposeInverseModelView); + vector3df wind = irr_driver->getWind() * strength * speed; + caustic_dir.X += wind.X; + caustic_dir.Y += wind.Z; + + strength = time * 0.56f + sinf(time); + strength = fabsf(noise2d(0.0, strength / 6.0f)) * 0.0095f + 0.001f; + + wind = irr_driver->getWind() * strength * speed; + wind.rotateXZBy(cosf(time)); + caustic_dir2.X += wind.X; + caustic_dir2.Y += wind.Z; + drawCaustics(mesh, ModelViewProjectionMatrix, caustic_dir, caustic_dir2); break; } - case SOLID_LIT_PASS: - { - if (type == irr_driver->getShader(ES_SPHERE_MAP)) - drawSphereMap(mesh, ModelViewProjectionMatrix, TransposeInverseModelView); - else if (type == irr_driver->getShader(ES_SPLATTING)) - drawSplatting(mesh, ModelViewProjectionMatrix); - else if (type == irr_driver->getShader(ES_OBJECTPASS_REF)) - drawObjectRefPass2(mesh, ModelViewProjectionMatrix, TextureMatrix); - else if (type == irr_driver->getShader(ES_GRASS) || type == irr_driver->getShader(ES_GRASS_REF)) - drawGrassPass2(mesh, ModelViewProjectionMatrix, windDir); - else if (type == irr_driver->getShader(ES_OBJECTPASS_RIMLIT)) - drawObjectRimLimit(mesh, ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix); - else if (type == irr_driver->getShader(ES_OBJECT_UNLIT)) - drawObjectUnlit(mesh, ModelViewProjectionMatrix); - else if (type == irr_driver->getShader(ES_CAUSTICS)) - { - const float time = irr_driver->getDevice()->getTimer()->getTime() / 1000.0f; - const float speed = World::getWorld()->getTrack()->getCausticsSpeed(); - - float strength = time; - strength = fabsf(noise2d(strength / 10.0f)) * 0.006f + 0.001f; - - vector3df wind = irr_driver->getWind() * strength * speed; - caustic_dir.X += wind.X; - caustic_dir.Y += wind.Z; - - strength = time * 0.56f + sinf(time); - strength = fabsf(noise2d(0.0, strength / 6.0f)) * 0.0095f + 0.001f; - - wind = irr_driver->getWind() * strength * speed; - wind.rotateXZBy(cosf(time)); - caustic_dir2.X += wind.X; - caustic_dir2.Y += wind.Z; - drawCaustics(mesh, ModelViewProjectionMatrix, caustic_dir, caustic_dir2); - } - else if (mesh.textures[1] && type != irr_driver->getShader(ES_NORMAL_MAP)) - drawDetailledObjectPass2(mesh, ModelViewProjectionMatrix); - else if (!mesh.textures[0]) - drawUntexturedObject(mesh, ModelViewProjectionMatrix); - else - drawObjectPass2(mesh, ModelViewProjectionMatrix, TextureMatrix); + case SM_DETAILS: + drawDetailledObjectPass2(mesh, ModelViewProjectionMatrix); + break; + case SM_UNTEXTURED: + drawUntexturedObject(mesh, ModelViewProjectionMatrix); + break; + case SM_DEFAULT: + drawObjectPass2(mesh, ModelViewProjectionMatrix, mesh.TextureMatrix); break; - } default: - { - assert(0 && "wrong pass"); - } + assert(0 && "Wrong shaded material"); + break; } } @@ -261,54 +282,131 @@ void STKMeshSceneNode::render() driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); Box = Mesh->getBoundingBox(); - for (u32 i = 0; igetMeshBufferCount(); ++i) + setFirstTimeMaterial(); + + for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) { scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); - if (mb) + if (!mb) + continue; + GLmeshes[i].TextureMatrix = getMaterial(i).getTextureMatrix(0); + } + + if (irr_driver->getPhase() == SOLID_NORMAL_AND_DEPTH_PASS) + { + computeMVP(ModelViewProjectionMatrix); + computeTIMV(TransposeInverseModelView); + + glUseProgram(MeshShader::ObjectPass1Shader::Program); + for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++) + drawSolidPass1(*GeometricMesh[FPSM_DEFAULT][i], FPSM_DEFAULT); + + glUseProgram(MeshShader::ObjectRefPass1Shader::Program); + for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++) + drawSolidPass1(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i], FPSM_ALPHA_REF_TEXTURE); + + glUseProgram(MeshShader::NormalMapShader::Program); + for (unsigned i = 0; i < GeometricMesh[FPSM_NORMAL_MAP].size(); i++) + drawSolidPass1(*GeometricMesh[FPSM_NORMAL_MAP][i], FPSM_NORMAL_MAP); + + glUseProgram(MeshShader::GrassPass1Shader::Program); + for (unsigned i = 0; i < GeometricMesh[FPSM_GRASS].size(); i++) + drawSolidPass1(*GeometricMesh[FPSM_GRASS][i], FPSM_GRASS); + + return; + } + + if (irr_driver->getPhase() == SOLID_LIT_PASS) + { + glUseProgram(MeshShader::ObjectPass2Shader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_DEFAULT].size(); i++) + drawSolidPass2(*ShadedMesh[SM_DEFAULT][i], SM_DEFAULT); + + glUseProgram(MeshShader::ObjectRefPass2Shader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_ALPHA_REF_TEXTURE].size(); i++) + drawSolidPass2(*ShadedMesh[SM_ALPHA_REF_TEXTURE][i], SM_ALPHA_REF_TEXTURE); + + glUseProgram(MeshShader::ObjectRimLimitShader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_RIMLIT].size(); i++) + drawSolidPass2(*ShadedMesh[SM_RIMLIT][i], SM_RIMLIT); + + glUseProgram(MeshShader::SphereMapShader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_SPHEREMAP].size(); i++) + drawSolidPass2(*ShadedMesh[SM_SPHEREMAP][i], SM_SPHEREMAP); + + glUseProgram(MeshShader::SplattingShader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_SPLATTING].size(); i++) + drawSolidPass2(*ShadedMesh[SM_SPLATTING][i], SM_SPLATTING); + + glUseProgram(MeshShader::GrassPass2Shader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_GRASS].size(); i++) + drawSolidPass2(*ShadedMesh[SM_GRASS][i], SM_GRASS); + + glUseProgram(MeshShader::ObjectUnlitShader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_UNLIT].size(); i++) + drawSolidPass2(*ShadedMesh[SM_UNLIT][i], SM_UNLIT); + + glUseProgram(MeshShader::CausticsShader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_CAUSTICS].size(); i++) + drawSolidPass2(*ShadedMesh[SM_CAUSTICS][i], SM_CAUSTICS); + + glUseProgram(MeshShader::DetailledObjectPass2Shader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_DETAILS].size(); i++) + drawSolidPass2(*ShadedMesh[SM_DETAILS][i], SM_DETAILS); + + glUseProgram(MeshShader::UntexturedObjectShader::Program); + for (unsigned i = 0; i < ShadedMesh[SM_UNTEXTURED].size(); i++) + drawSolidPass2(*ShadedMesh[SM_UNTEXTURED][i], SM_UNTEXTURED); + + return; + } + + if (irr_driver->getPhase() == SHADOW_PASS) + { + glUseProgram(MeshShader::ShadowShader::Program); + for (unsigned i = 0; i < GeometricMesh[FPSM_DEFAULT].size(); i++) + drawShadow(*GeometricMesh[FPSM_DEFAULT][i]); + + glUseProgram(MeshShader::RefShadowShader::Program); + for (unsigned i = 0; i < GeometricMesh[FPSM_ALPHA_REF_TEXTURE].size(); i++) + drawShadowRef(*GeometricMesh[FPSM_ALPHA_REF_TEXTURE][i]); + return; + } + + if (irr_driver->getPhase() == GLOW_PASS) + { + glUseProgram(MeshShader::ColorizeShader::Program); + for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) { - TextureMatrix = getMaterial(i).getTextureMatrix(0); - const video::SMaterial& material = ReadOnlyMaterials ? mb->getMaterial() : Materials[i]; - - video::IMaterialRenderer* rnd = driver->getMaterialRenderer(material.MaterialType); - bool transparent = (rnd && rnd->isTransparent()); - - if (isTransparentPass != transparent) + scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); + if (!mb) continue; - if (irr_driver->getPhase() == DISPLACEMENT_PASS) - { - initvaostate(GLmeshes[i], material.MaterialType); - drawDisplace(GLmeshes[i]); - continue; - } - if (!isObject(material.MaterialType)) - { -#ifdef DEBUG - Log::warn("material", "Unhandled (static) material type : %d", material.MaterialType); -#endif - continue; - } + drawGlow(GLmeshes[i]); + } + } - // only render transparent buffer if this is the transparent render pass - // and solid only in solid pass - if (irr_driver->getPhase() == GLOW_PASS) - { - initvaostate(GLmeshes[i], material.MaterialType); - drawGlow(GLmeshes[i]); - } - else if (irr_driver->getPhase() == SHADOW_PASS) - { - initvaostate(GLmeshes[i], material.MaterialType); - drawShadow(GLmeshes[i], material.MaterialType); - } - else - { - irr_driver->IncreaseObjectCount(); - initvaostate(GLmeshes[i], material.MaterialType); - if (transparent) - drawTransparent(GLmeshes[i], material.MaterialType); - else - drawSolid(GLmeshes[i], material.MaterialType); - } + if (irr_driver->getPhase() == TRANSPARENT_PASS) + { + computeMVP(ModelViewProjectionMatrix); + + glUseProgram(MeshShader::BubbleShader::Program); + for (unsigned i = 0; i < TransparentMesh[TM_BUBBLE].size(); i++) + drawBubble(*TransparentMesh[TM_BUBBLE][i], ModelViewProjectionMatrix); + + glUseProgram(MeshShader::TransparentShader::Program); + for (unsigned i = 0; i < TransparentMesh[TM_DEFAULT].size(); i++) + drawTransparentObject(*TransparentMesh[TM_DEFAULT][i], ModelViewProjectionMatrix, (*TransparentMesh[TM_DEFAULT][i]).TextureMatrix); + return; + } + + if (irr_driver->getPhase() == DISPLACEMENT_PASS) + { + for (u32 i = 0; i < Mesh->getMeshBufferCount(); ++i) + { + scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); + if (!mb) + continue; + drawDisplace(GLmeshes[i]); } } } diff --git a/src/graphics/stkmeshscenenode.hpp b/src/graphics/stkmeshscenenode.hpp index c10a8b0bb..afc628335 100644 --- a/src/graphics/stkmeshscenenode.hpp +++ b/src/graphics/stkmeshscenenode.hpp @@ -6,19 +6,24 @@ class STKMeshSceneNode : public irr::scene::CMeshSceneNode { protected: + std::vector GeometricMesh[FPSM_COUNT]; + std::vector ShadedMesh[SM_COUNT]; + std::vector TransparentMesh[TM_COUNT]; std::vector GLmeshes; - core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix; + core::matrix4 ModelViewProjectionMatrix, TransposeInverseModelView; core::vector3df windDir; core::vector2df caustic_dir, caustic_dir2; - void drawSolid(const GLMesh &mesh, video::E_MATERIAL_TYPE type); + void drawSolidPass1(const GLMesh &mesh, GeometricMaterial type); + void drawSolidPass2(const GLMesh &mesh, ShadedMaterial type); void drawTransparent(const GLMesh &mesh, video::E_MATERIAL_TYPE type); // Misc passes shaders (glow, displace...) void drawGlow(const GLMesh &mesh); void drawDisplace(const GLMesh &mesh); - void drawShadow(const GLMesh &mesh, video::E_MATERIAL_TYPE type); void createGLMeshes(); void cleanGLMeshes(); + void setFirstTimeMaterial(); + bool isMaterialInitialized; public: STKMeshSceneNode(irr::scene::IMesh* mesh, ISceneNode* parent, irr::scene::ISceneManager* mgr, irr::s32 id, const irr::core::vector3df& position = irr::core::vector3df(0, 0, 0), @@ -30,4 +35,4 @@ public: ~STKMeshSceneNode(); }; -#endif \ No newline at end of file +#endif From 6cad7339e38256a1e6d625230842ce25aadd8819 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 10 Mar 2014 15:46:05 +0100 Subject: [PATCH 2/5] Factorize texture binding. --- src/graphics/render.cpp | 8 + src/graphics/shaders.cpp | 399 +++++++++++++++++++++------------------ src/graphics/shaders.hpp | 93 ++++----- src/graphics/stkmesh.cpp | 123 +++--------- 4 files changed, 296 insertions(+), 327 deletions(-) diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index b0a2a00c0..d64ef292a 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -236,6 +236,14 @@ void IrrDriver::renderGLSL(float dt) glDepthMask(GL_FALSE); glDisable(GL_BLEND); m_renderpass = scene::ESNRP_CAMERA | scene::ESNRP_SOLID; + setTexture(0, getTextureGLuint(irr_driver->getRTT(RTT_TMP1)), GL_NEAREST, GL_NEAREST); + setTexture(1, getTextureGLuint(irr_driver->getRTT(RTT_TMP2)), GL_NEAREST, GL_NEAREST); + setTexture(2, getTextureGLuint(irr_driver->getRTT(RTT_SSAO)), GL_NEAREST, GL_NEAREST); + if (!UserConfigParams::m_ssao) + { + GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ONE }; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); + } m_scene_manager->drawAll(m_renderpass); PROFILER_POP_CPU_MARKER(); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index 5c59c4ab5..fcaadc662 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -297,6 +297,8 @@ void Shaders::check(const int num) const namespace MeshShader { + + // Solid Normal and depth pass shaders GLuint ObjectPass1Shader::Program; GLuint ObjectPass1Shader::attrib_position; GLuint ObjectPass1Shader::attrib_normal; @@ -347,17 +349,75 @@ namespace MeshShader glUniform1i(uniform_tex, TU_tex); } + GLuint GrassPass1Shader::Program; + GLuint GrassPass1Shader::attrib_position; + GLuint GrassPass1Shader::attrib_texcoord; + GLuint GrassPass1Shader::attrib_normal; + GLuint GrassPass1Shader::attrib_color; + GLuint GrassPass1Shader::uniform_MVP; + GLuint GrassPass1Shader::uniform_TIMV; + GLuint GrassPass1Shader::uniform_tex; + GLuint GrassPass1Shader::uniform_windDir; + + void GrassPass1Shader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/grass_pass1.vert").c_str(), file_manager->getAsset("shaders/objectref_pass1.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + attrib_normal = glGetAttribLocation(Program, "Normal"); + attrib_color = glGetAttribLocation(Program, "Color"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); + uniform_tex = glGetUniformLocation(Program, "tex"); + uniform_windDir = glGetUniformLocation(Program, "windDir"); + } + + void GrassPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::vector3df &windDirection, unsigned TU_tex) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + glUniform3f(uniform_windDir, windDirection.X, windDirection.Y, windDirection.Z); + glUniform1i(uniform_tex, TU_tex); + } + + GLuint NormalMapShader::Program; + GLuint NormalMapShader::attrib_position; + GLuint NormalMapShader::attrib_texcoord; + GLuint NormalMapShader::attrib_tangent; + GLuint NormalMapShader::attrib_bitangent; + GLuint NormalMapShader::uniform_MVP; + GLuint NormalMapShader::uniform_TIMV; + GLuint NormalMapShader::uniform_normalMap; + + void NormalMapShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/normalmap.vert").c_str(), file_manager->getAsset("shaders/normalmap.frag").c_str()); + attrib_position = glGetAttribLocation(Program, "Position"); + attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); + attrib_tangent = glGetAttribLocation(Program, "Tangent"); + attrib_bitangent = glGetAttribLocation(Program, "Bitangent"); + uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); + uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); + uniform_normalMap = glGetUniformLocation(Program, "normalMap"); + } + + void NormalMapShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_normalMap) + { + glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); + glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + glUniform1i(uniform_normalMap, TU_normalMap); + } + + // Solid Lit pass shaders + GLuint ObjectPass2Shader::Program; GLuint ObjectPass2Shader::attrib_position; GLuint ObjectPass2Shader::attrib_texcoord; GLuint ObjectPass2Shader::uniform_MVP; GLuint ObjectPass2Shader::uniform_TM; - GLuint ObjectPass2Shader::uniform_Albedo; - GLuint ObjectPass2Shader::uniform_DiffuseMap; - GLuint ObjectPass2Shader::uniform_SpecularMap; - GLuint ObjectPass2Shader::uniform_SSAO; GLuint ObjectPass2Shader::uniform_screen; GLuint ObjectPass2Shader::uniform_ambient; + GLuint ObjectPass2Shader::TU_Albedo; void ObjectPass2Shader::init() { @@ -366,22 +426,26 @@ namespace MeshShader attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); uniform_TM = glGetUniformLocation(Program, "TextureMatrix"); - uniform_Albedo = glGetUniformLocation(Program, "Albedo"); - uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); - uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); - uniform_SSAO = glGetUniformLocation(Program, "SSAO"); + GLuint uniform_Albedo = glGetUniformLocation(Program, "Albedo"); + GLuint uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + GLuint uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + GLuint uniform_SSAO = glGetUniformLocation(Program, "SSAO"); uniform_screen = glGetUniformLocation(Program, "screen"); uniform_ambient = glGetUniformLocation(Program, "ambient"); + TU_Albedo = 3; + + glUseProgram(Program); + glUniform1i(uniform_DiffuseMap, 0); + glUniform1i(uniform_SpecularMap, 1); + glUniform1i(uniform_SSAO, 2); + glUniform1i(uniform_Albedo, TU_Albedo); + glUseProgram(0); } - void ObjectPass2Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) + void ObjectPass2Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); glUniformMatrix4fv(uniform_TM, 1, GL_FALSE, TextureMatrix.pointer()); - glUniform1i(uniform_Albedo, TU_Albedo); - glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); - glUniform1i(uniform_SpecularMap, TU_SpecularMap); - glUniform1i(uniform_SSAO, TU_SSAO); glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); glUniform3f(uniform_ambient, s.r, s.g, s.b); @@ -392,13 +456,10 @@ namespace MeshShader GLuint DetailledObjectPass2Shader::attrib_texcoord; GLuint DetailledObjectPass2Shader::attrib_second_texcoord; GLuint DetailledObjectPass2Shader::uniform_MVP; - GLuint DetailledObjectPass2Shader::uniform_Albedo; - GLuint DetailledObjectPass2Shader::uniform_Detail; - GLuint DetailledObjectPass2Shader::uniform_DiffuseMap; - GLuint DetailledObjectPass2Shader::uniform_SpecularMap; - GLuint DetailledObjectPass2Shader::uniform_SSAO; GLuint DetailledObjectPass2Shader::uniform_screen; GLuint DetailledObjectPass2Shader::uniform_ambient; + GLuint DetailledObjectPass2Shader::TU_Albedo; + GLuint DetailledObjectPass2Shader::TU_detail; void DetailledObjectPass2Shader::init() { @@ -407,23 +468,28 @@ namespace MeshShader attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); attrib_second_texcoord = glGetAttribLocation(Program, "SecondTexcoord"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_Albedo = glGetUniformLocation(Program, "Albedo"); - uniform_Detail = glGetUniformLocation(Program, "Detail"); - uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); - uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); - uniform_SSAO = glGetUniformLocation(Program, "SSAO"); - uniform_screen = glGetUniformLocation(Program, "screen"); + GLuint uniform_Albedo = glGetUniformLocation(Program, "Albedo"); + GLuint uniform_Detail = glGetUniformLocation(Program, "Detail"); + GLuint uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + GLuint uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + GLuint uniform_SSAO = glGetUniformLocation(Program, "SSAO"); + uniform_screen = glGetUniformLocation(Program, "screen"); uniform_ambient = glGetUniformLocation(Program, "ambient"); + TU_Albedo = 3; + TU_detail = 4; + + glUseProgram(Program); + glUniform1i(uniform_DiffuseMap, 0); + glUniform1i(uniform_SpecularMap, 1); + glUniform1i(uniform_SSAO, 2); + glUniform1i(uniform_Albedo, TU_Albedo); + glUniform1i(uniform_Detail, TU_detail); + glUseProgram(0); } - void DetailledObjectPass2Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_detail, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) + void DetailledObjectPass2Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniform1i(uniform_Albedo, TU_Albedo); - glUniform1i(uniform_Detail, TU_detail); - glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); - glUniform1i(uniform_SpecularMap, TU_SpecularMap); - glUniform1i(uniform_SSAO, TU_SSAO); glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); glUniform3f(uniform_ambient, s.r, s.g, s.b); @@ -433,7 +499,7 @@ namespace MeshShader GLuint ObjectUnlitShader::attrib_position; GLuint ObjectUnlitShader::attrib_texcoord; GLuint ObjectUnlitShader::uniform_MVP; - GLuint ObjectUnlitShader::uniform_tex; + GLuint ObjectUnlitShader::TU_tex; void ObjectUnlitShader::init() { @@ -441,13 +507,17 @@ namespace MeshShader attrib_position = glGetAttribLocation(Program, "Position"); attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_tex = glGetUniformLocation(Program, "tex"); + GLuint uniform_tex = glGetUniformLocation(Program, "tex"); + TU_tex = 3; + + glUseProgram(Program); + glUniform1i(uniform_tex, TU_tex); + glUseProgram(0); } - void ObjectUnlitShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex) + void ObjectUnlitShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniform1i(uniform_tex, TU_tex); } GLuint ObjectRimLimitShader::Program; @@ -457,12 +527,9 @@ namespace MeshShader GLuint ObjectRimLimitShader::uniform_MVP; GLuint ObjectRimLimitShader::uniform_TIMV; GLuint ObjectRimLimitShader::uniform_TM; - GLuint ObjectRimLimitShader::uniform_Albedo; - GLuint ObjectRimLimitShader::uniform_DiffuseMap; - GLuint ObjectRimLimitShader::uniform_SpecularMap; - GLuint ObjectRimLimitShader::uniform_SSAO; GLuint ObjectRimLimitShader::uniform_screen; GLuint ObjectRimLimitShader::uniform_ambient; + GLuint ObjectRimLimitShader::TU_Albedo; void ObjectRimLimitShader::init() { @@ -473,23 +540,27 @@ namespace MeshShader uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); uniform_TM = glGetUniformLocation(Program, "TextureMatrix"); - uniform_Albedo = glGetUniformLocation(Program, "Albedo"); - uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); - uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); - uniform_SSAO = glGetUniformLocation(Program, "SSAO"); + GLuint uniform_Albedo = glGetUniformLocation(Program, "Albedo"); + GLuint uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + GLuint uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + GLuint uniform_SSAO = glGetUniformLocation(Program, "SSAO"); uniform_screen = glGetUniformLocation(Program, "screen"); uniform_ambient = glGetUniformLocation(Program, "ambient"); + TU_Albedo = 3; + + glUseProgram(Program); + glUniform1i(uniform_DiffuseMap, 0); + glUniform1i(uniform_SpecularMap, 1); + glUniform1i(uniform_SSAO, 2); + glUniform1i(uniform_Albedo, TU_Albedo); + glUseProgram(0); } - void ObjectRimLimitShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &TextureMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) + void ObjectRimLimitShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &TextureMatrix) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); glUniformMatrix4fv(uniform_TM, 1, GL_FALSE, TextureMatrix.pointer()); - glUniform1i(uniform_Albedo, TU_Albedo); - glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); - glUniform1i(uniform_SpecularMap, TU_SpecularMap); - glUniform1i(uniform_SSAO, TU_SSAO); glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); glUniform3f(uniform_ambient, s.r, s.g, s.b); @@ -499,9 +570,6 @@ namespace MeshShader GLuint UntexturedObjectShader::attrib_position; GLuint UntexturedObjectShader::attrib_color; GLuint UntexturedObjectShader::uniform_MVP; - GLuint UntexturedObjectShader::uniform_DiffuseMap; - GLuint UntexturedObjectShader::uniform_SpecularMap; - GLuint UntexturedObjectShader::uniform_SSAO; GLuint UntexturedObjectShader::uniform_screen; GLuint UntexturedObjectShader::uniform_ambient; @@ -511,19 +579,22 @@ namespace MeshShader attrib_position = glGetAttribLocation(Program, "Position"); attrib_color = glGetAttribLocation(Program, "Color"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); - uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); - uniform_SSAO = glGetUniformLocation(Program, "SSAO"); + GLuint uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + GLuint uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + GLuint uniform_SSAO = glGetUniformLocation(Program, "SSAO"); uniform_screen = glGetUniformLocation(Program, "screen"); uniform_ambient = glGetUniformLocation(Program, "ambient"); + + glUseProgram(Program); + glUniform1i(uniform_DiffuseMap, 0); + glUniform1i(uniform_SpecularMap, 1); + glUniform1i(uniform_SSAO, 2); + glUseProgram(0); } - void UntexturedObjectShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) + void UntexturedObjectShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); - glUniform1i(uniform_SpecularMap, TU_SpecularMap); - glUniform1i(uniform_SSAO, TU_SSAO); glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); glUniform3f(uniform_ambient, s.r, s.g, s.b); @@ -535,12 +606,9 @@ namespace MeshShader GLuint ObjectRefPass2Shader::attrib_texcoord; GLuint ObjectRefPass2Shader::uniform_MVP; GLuint ObjectRefPass2Shader::uniform_TM; - GLuint ObjectRefPass2Shader::uniform_Albedo; - GLuint ObjectRefPass2Shader::uniform_DiffuseMap; - GLuint ObjectRefPass2Shader::uniform_SpecularMap; - GLuint ObjectRefPass2Shader::uniform_SSAO; GLuint ObjectRefPass2Shader::uniform_screen; GLuint ObjectRefPass2Shader::uniform_ambient; + GLuint ObjectRefPass2Shader::TU_Albedo; void ObjectRefPass2Shader::init() { @@ -550,70 +618,40 @@ namespace MeshShader attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); uniform_TM = glGetUniformLocation(Program, "TextureMatrix"); - uniform_Albedo = glGetUniformLocation(Program, "Albedo"); - uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); - uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); - uniform_SSAO = glGetUniformLocation(Program, "SSAO"); + GLuint uniform_Albedo = glGetUniformLocation(Program, "Albedo"); + GLuint uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + GLuint uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + GLuint uniform_SSAO = glGetUniformLocation(Program, "SSAO"); uniform_screen = glGetUniformLocation(Program, "screen"); uniform_ambient = glGetUniformLocation(Program, "ambient"); + TU_Albedo = 3; + + glUseProgram(Program); + glUniform1i(uniform_DiffuseMap, 0); + glUniform1i(uniform_SpecularMap, 1); + glUniform1i(uniform_SSAO, 2); + glUniform1i(uniform_Albedo, TU_Albedo); + glUseProgram(0); } - void ObjectRefPass2Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) + void ObjectRefPass2Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); glUniformMatrix4fv(uniform_TM, 1, GL_FALSE, TextureMatrix.pointer()); - glUniform1i(uniform_Albedo, TU_Albedo); - glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); - glUniform1i(uniform_SpecularMap, TU_SpecularMap); - glUniform1i(uniform_SSAO, TU_SSAO); glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); glUniform3f(uniform_ambient, s.r, s.g, s.b); } - GLuint GrassPass1Shader::Program; - GLuint GrassPass1Shader::attrib_position; - GLuint GrassPass1Shader::attrib_texcoord; - GLuint GrassPass1Shader::attrib_normal; - GLuint GrassPass1Shader::attrib_color; - GLuint GrassPass1Shader::uniform_MVP; - GLuint GrassPass1Shader::uniform_TIMV; - GLuint GrassPass1Shader::uniform_tex; - GLuint GrassPass1Shader::uniform_windDir; - - void GrassPass1Shader::init() - { - Program = LoadProgram(file_manager->getAsset("shaders/grass_pass1.vert").c_str(), file_manager->getAsset("shaders/objectref_pass1.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); - attrib_normal = glGetAttribLocation(Program, "Normal"); - attrib_color = glGetAttribLocation(Program, "Color"); - uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); - uniform_tex = glGetUniformLocation(Program, "tex"); - uniform_windDir = glGetUniformLocation(Program, "windDir"); - } - - void GrassPass1Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::vector3df &windDirection, unsigned TU_tex) - { - glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); - glUniform3f(uniform_windDir, windDirection.X, windDirection.Y, windDirection.Z); - glUniform1i(uniform_tex, TU_tex); - } - GLuint GrassPass2Shader::Program; GLuint GrassPass2Shader::attrib_position; GLuint GrassPass2Shader::attrib_texcoord; GLuint GrassPass2Shader::attrib_color; GLuint GrassPass2Shader::uniform_MVP; - GLuint GrassPass2Shader::uniform_Albedo; - GLuint GrassPass2Shader::uniform_DiffuseMap; - GLuint GrassPass2Shader::uniform_SpecularMap; - GLuint GrassPass2Shader::uniform_SSAO; GLuint GrassPass2Shader::uniform_screen; GLuint GrassPass2Shader::uniform_ambient; GLuint GrassPass2Shader::uniform_windDir; + GLuint GrassPass2Shader::TU_Albedo; void GrassPass2Shader::init() { @@ -622,64 +660,40 @@ namespace MeshShader attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); attrib_color = glGetAttribLocation(Program, "Color"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_Albedo = glGetUniformLocation(Program, "Albedo"); - uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); - uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); - uniform_SSAO = glGetUniformLocation(Program, "SSAO"); + GLuint uniform_Albedo = glGetUniformLocation(Program, "Albedo"); + GLuint uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + GLuint uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + GLuint uniform_SSAO = glGetUniformLocation(Program, "SSAO"); uniform_screen = glGetUniformLocation(Program, "screen"); uniform_ambient = glGetUniformLocation(Program, "ambient"); uniform_windDir = glGetUniformLocation(Program, "windDir"); + TU_Albedo = 3; + + glUseProgram(Program); + glUniform1i(uniform_DiffuseMap, 0); + glUniform1i(uniform_SpecularMap, 1); + glUniform1i(uniform_SSAO, 2); + glUniform1i(uniform_Albedo, TU_Albedo); + glUseProgram(0); } - void GrassPass2Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDirection, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) + void GrassPass2Shader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDirection) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniform1i(uniform_Albedo, TU_Albedo); - glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); - glUniform1i(uniform_SpecularMap, TU_SpecularMap); - glUniform1i(uniform_SSAO, TU_SSAO); glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); glUniform3f(uniform_ambient, s.r, s.g, s.b); glUniform3f(uniform_windDir, windDirection.X, windDirection.Y, windDirection.Z); } - GLuint NormalMapShader::Program; - GLuint NormalMapShader::attrib_position; - GLuint NormalMapShader::attrib_texcoord; - GLuint NormalMapShader::attrib_tangent; - GLuint NormalMapShader::attrib_bitangent; - GLuint NormalMapShader::uniform_MVP; - GLuint NormalMapShader::uniform_TIMV; - GLuint NormalMapShader::uniform_normalMap; - - void NormalMapShader::init() - { - Program = LoadProgram(file_manager->getAsset("shaders/normalmap.vert").c_str(), file_manager->getAsset("shaders/normalmap.frag").c_str()); - attrib_position = glGetAttribLocation(Program, "Position"); - attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); - attrib_tangent = glGetAttribLocation(Program, "Tangent"); - attrib_bitangent = glGetAttribLocation(Program, "Bitangent"); - uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); - uniform_normalMap = glGetUniformLocation(Program, "normalMap"); - } - - void NormalMapShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_normalMap) - { - glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); - glUniform1i(uniform_normalMap, TU_normalMap); - } - GLuint SphereMapShader::Program; GLuint SphereMapShader::attrib_position; GLuint SphereMapShader::attrib_normal; GLuint SphereMapShader::uniform_MVP; GLuint SphereMapShader::uniform_TIMV; - GLuint SphereMapShader::uniform_tex; GLuint SphereMapShader::uniform_invproj; GLuint SphereMapShader::uniform_screen; + GLuint SphereMapShader::TU_tex; void SphereMapShader::init() { @@ -688,18 +702,22 @@ namespace MeshShader attrib_normal = glGetAttribLocation(Program, "Normal"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); - uniform_tex = glGetUniformLocation(Program, "tex"); + GLuint uniform_tex = glGetUniformLocation(Program, "tex"); uniform_invproj = glGetUniformLocation(Program, "invproj"); uniform_screen = glGetUniformLocation(Program, "screen"); + TU_tex = 3; + + glUseProgram(Program); + glUniform1i(uniform_tex, TU_tex); + glUseProgram(0); } - void SphereMapShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &InvProj, const core::vector2df& screen, unsigned TU_tex) + void SphereMapShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &InvProj, const core::vector2df& screen) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); glUniformMatrix4fv(uniform_invproj, 1, GL_FALSE, InvProj.pointer()); glUniform2f(uniform_screen, screen.X, screen.Y); - glUniform1i(uniform_tex, TU_tex); } GLuint SplattingShader::Program; @@ -707,16 +725,13 @@ namespace MeshShader GLuint SplattingShader::attrib_texcoord; GLuint SplattingShader::attrib_second_texcoord; GLuint SplattingShader::uniform_MVP; - GLuint SplattingShader::uniform_tex_layout; - GLuint SplattingShader::uniform_tex_detail0; - GLuint SplattingShader::uniform_tex_detail1; - GLuint SplattingShader::uniform_tex_detail2; - GLuint SplattingShader::uniform_tex_detail3; - GLuint SplattingShader::uniform_DiffuseMap; - GLuint SplattingShader::uniform_SpecularMap; - GLuint SplattingShader::uniform_SSAO; GLuint SplattingShader::uniform_screen; GLuint SplattingShader::uniform_ambient; + GLuint SplattingShader::TU_tex_layout; + GLuint SplattingShader::TU_tex_detail0; + GLuint SplattingShader::TU_tex_detail1; + GLuint SplattingShader::TU_tex_detail2; + GLuint SplattingShader::TU_tex_detail3; void SplattingShader::init() { @@ -725,29 +740,37 @@ namespace MeshShader attrib_texcoord = glGetAttribLocation(Program, "Texcoord"); attrib_second_texcoord = glGetAttribLocation(Program, "SecondTexcoord"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); - uniform_tex_layout = glGetUniformLocation(Program, "tex_layout"); - uniform_tex_detail0 = glGetUniformLocation(Program, "tex_detail0"); - uniform_tex_detail1 = glGetUniformLocation(Program, "tex_detail1"); - uniform_tex_detail2 = glGetUniformLocation(Program, "tex_detail2"); - uniform_tex_detail3 = glGetUniformLocation(Program, "tex_detail3"); - uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); - uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); - uniform_SSAO = glGetUniformLocation(Program, "SSAO"); + GLuint uniform_tex_layout = glGetUniformLocation(Program, "tex_layout"); + GLuint uniform_tex_detail0 = glGetUniformLocation(Program, "tex_detail0"); + GLuint uniform_tex_detail1 = glGetUniformLocation(Program, "tex_detail1"); + GLuint uniform_tex_detail2 = glGetUniformLocation(Program, "tex_detail2"); + GLuint uniform_tex_detail3 = glGetUniformLocation(Program, "tex_detail3"); + GLuint uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + GLuint uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + GLuint uniform_SSAO = glGetUniformLocation(Program, "SSAO"); uniform_screen = glGetUniformLocation(Program, "screen"); uniform_ambient = glGetUniformLocation(Program, "ambient"); + TU_tex_layout = 3; + TU_tex_detail0 = 4; + TU_tex_detail1 = 5; + TU_tex_detail2 = 6; + TU_tex_detail3 = 7; + + glUseProgram(Program); + glUniform1i(uniform_DiffuseMap, 0); + glUniform1i(uniform_SpecularMap, 1); + glUniform1i(uniform_SSAO, 2); + glUniform1i(uniform_tex_layout, TU_tex_layout); + glUniform1i(uniform_tex_detail0, TU_tex_detail0); + glUniform1i(uniform_tex_detail1, TU_tex_detail1); + glUniform1i(uniform_tex_detail2, TU_tex_detail2); + glUniform1i(uniform_tex_detail3, TU_tex_detail3); + glUseProgram(0); } - void SplattingShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex_layout, unsigned TU_tex_detail0, unsigned TU_tex_detail1, unsigned TU_tex_detail2, unsigned TU_tex_detail3, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO) + void SplattingShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); - glUniform1i(uniform_tex_layout, TU_tex_layout); - glUniform1i(uniform_tex_detail0, TU_tex_detail0); - glUniform1i(uniform_tex_detail1, TU_tex_detail1); - glUniform1i(uniform_tex_detail2, TU_tex_detail2); - glUniform1i(uniform_tex_detail3, TU_tex_detail3); - glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); - glUniform1i(uniform_SpecularMap, TU_SpecularMap); - glUniform1i(uniform_SSAO, TU_SSAO); glUniform2f(uniform_screen, UserConfigParams::m_width, UserConfigParams::m_height); const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); glUniform3f(uniform_ambient, s.r, s.g, s.b); @@ -759,13 +782,10 @@ namespace MeshShader GLuint CausticsShader::uniform_MVP; GLuint CausticsShader::uniform_dir; GLuint CausticsShader::uniform_dir2; - GLuint CausticsShader::uniform_Albedo; - GLuint CausticsShader::uniform_caustictex; - GLuint CausticsShader::uniform_DiffuseMap; - GLuint CausticsShader::uniform_SpecularMap; - GLuint CausticsShader::uniform_SSAO; GLuint CausticsShader::uniform_screen; GLuint CausticsShader::uniform_ambient; + GLuint CausticsShader::TU_Albedo; + GLuint CausticsShader::TU_caustictex; void CausticsShader::init() { @@ -775,26 +795,31 @@ namespace MeshShader uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); uniform_dir = glGetUniformLocation(Program, "dir"); uniform_dir2 = glGetUniformLocation(Program, "dir2"); - uniform_Albedo = glGetUniformLocation(Program, "Albedo"); - uniform_caustictex = glGetUniformLocation(Program, "caustictex"); - uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); - uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); - uniform_SSAO = glGetUniformLocation(Program, "SSAO"); + GLuint uniform_Albedo = glGetUniformLocation(Program, "Albedo"); + GLuint uniform_caustictex = glGetUniformLocation(Program, "caustictex"); + GLuint uniform_DiffuseMap = glGetUniformLocation(Program, "DiffuseMap"); + GLuint uniform_SpecularMap = glGetUniformLocation(Program, "SpecularMap"); + GLuint uniform_SSAO = glGetUniformLocation(Program, "SSAO"); uniform_screen = glGetUniformLocation(Program, "screen"); uniform_ambient = glGetUniformLocation(Program, "ambient"); + TU_Albedo = 3; + TU_caustictex = 4; + + glUseProgram(Program); + glUniform1i(uniform_DiffuseMap, 0); + glUniform1i(uniform_SpecularMap, 1); + glUniform1i(uniform_SSAO, 2); + glUniform1i(uniform_Albedo, TU_Albedo); + glUniform1i(uniform_caustictex, TU_caustictex); + glUseProgram(0); } - void CausticsShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector2df &dir, const core::vector2df &dir2, const core::vector2df &screen, unsigned TU_albedo, unsigned TU_DiffuseMap, unsigned TU_Specmap, unsigned TU_SSAO, unsigned TU_caustictex) + void CausticsShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector2df &dir, const core::vector2df &dir2, const core::vector2df &screen) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); glUniform2f(uniform_dir, dir.X, dir.Y); glUniform2f(uniform_dir2, dir2.X, dir2.Y); - glUniform1i(uniform_Albedo, TU_albedo); - glUniform1i(uniform_caustictex, TU_caustictex); glUniform2f(uniform_screen, screen.X, screen.Y); - glUniform1i(uniform_DiffuseMap, TU_DiffuseMap); - glUniform1i(uniform_SpecularMap, TU_Specmap); - glUniform1i(uniform_SSAO, TU_SSAO); const video::SColorf s = irr_driver->getSceneManager()->getAmbientLight(); glUniform3f(uniform_ambient, s.r, s.g, s.b); } diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 84d28ab68..8a039fe35 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -48,15 +48,38 @@ public: static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &TextureMatrix, unsigned TU_texture); }; +class GrassPass1Shader +{ +public: + static GLuint Program; + static GLuint attrib_position, attrib_texcoord, attrib_normal, attrib_color; + static GLuint uniform_MVP, uniform_TIMV, uniform_tex, uniform_windDir; + + static void init(); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::vector3df &windDirection, unsigned TU_tex); +}; + +class NormalMapShader +{ +public: + static GLuint Program; + static GLuint attrib_position, attrib_texcoord, attrib_tangent, attrib_bitangent; + static GLuint uniform_MVP, uniform_TIMV, uniform_normalMap; + + static void init(); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_normalMap); +}; + class ObjectPass2Shader { public: static GLuint Program; static GLuint attrib_position, attrib_texcoord; - static GLuint uniform_MVP, uniform_TM, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; + static GLuint uniform_MVP, uniform_TM, uniform_screen, uniform_ambient; + static GLuint TU_Albedo; static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix); }; class DetailledObjectPass2Shader @@ -64,10 +87,11 @@ class DetailledObjectPass2Shader public: static GLuint Program; static GLuint attrib_position, attrib_texcoord, attrib_second_texcoord; - static GLuint uniform_MVP, uniform_Albedo, uniform_Detail, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; + static GLuint uniform_MVP, uniform_screen, uniform_ambient; + static GLuint TU_Albedo, TU_detail; static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_Albedo, unsigned TU_detail, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix); }; class ObjectRimLimitShader @@ -75,10 +99,11 @@ class ObjectRimLimitShader public: static GLuint Program; static GLuint attrib_position, attrib_normal, attrib_texcoord; - static GLuint uniform_MVP, uniform_TIMV, uniform_TM, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; + static GLuint uniform_MVP, uniform_TIMV, uniform_TM, uniform_screen, uniform_ambient; + static GLuint TU_Albedo; static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &TextureMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &TextureMatrix); }; class UntexturedObjectShader @@ -86,10 +111,10 @@ class UntexturedObjectShader public: static GLuint Program; static GLuint attrib_position, attrib_color; - static GLuint uniform_MVP, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; + static GLuint uniform_MVP, uniform_screen, uniform_ambient; static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix); }; class ObjectUnlitShader @@ -97,10 +122,11 @@ class ObjectUnlitShader public: static GLuint Program; static GLuint attrib_position, attrib_texcoord; - static GLuint uniform_MVP, uniform_tex; + static GLuint uniform_MVP; + static GLuint TU_tex; static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix); }; class ObjectRefPass2Shader @@ -108,21 +134,11 @@ class ObjectRefPass2Shader public: static GLuint Program; static GLuint attrib_position, attrib_texcoord; - static GLuint uniform_MVP, uniform_TM, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; + static GLuint uniform_MVP, uniform_TM, uniform_screen, uniform_ambient; + static GLuint TU_Albedo; static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); -}; - -class GrassPass1Shader -{ -public: - static GLuint Program; - static GLuint attrib_position, attrib_texcoord, attrib_normal, attrib_color; - static GLuint uniform_MVP, uniform_TIMV, uniform_tex, uniform_windDir; - - static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::vector3df &windDirection, unsigned TU_tex); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix); }; class GrassPass2Shader @@ -130,21 +146,11 @@ class GrassPass2Shader public: static GLuint Program; static GLuint attrib_position, attrib_texcoord, attrib_color; - static GLuint uniform_MVP, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient, uniform_windDir; + static GLuint uniform_MVP, uniform_screen, uniform_ambient, uniform_windDir; + static GLuint TU_Albedo; static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDirection, unsigned TU_Albedo, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); -}; - -class NormalMapShader -{ -public: - static GLuint Program; - static GLuint attrib_position, attrib_texcoord, attrib_tangent, attrib_bitangent; - static GLuint uniform_MVP, uniform_TIMV, uniform_normalMap; - - static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, unsigned TU_normalMap); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector3df &windDirection); }; class SphereMapShader @@ -152,10 +158,11 @@ class SphereMapShader public: static GLuint Program; static GLuint attrib_position, attrib_normal; - static GLuint uniform_MVP, uniform_TIMV, uniform_tex, uniform_invproj, uniform_screen; + static GLuint uniform_MVP, uniform_TIMV, uniform_invproj, uniform_screen; + static GLuint TU_tex; static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &InvProj, const core::vector2df& screen, unsigned TU_tex); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &InvProj, const core::vector2df& screen); }; class SplattingShader @@ -163,10 +170,11 @@ class SplattingShader public: static GLuint Program; static GLuint attrib_position, attrib_texcoord, attrib_second_texcoord; - static GLuint uniform_MVP, uniform_tex_layout, uniform_tex_detail0, uniform_tex_detail1, uniform_tex_detail2, uniform_tex_detail3, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient; + static GLuint uniform_MVP, uniform_screen, uniform_ambient; + static GLuint TU_tex_layout, TU_tex_detail0, TU_tex_detail1, TU_tex_detail2, TU_tex_detail3; static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, unsigned TU_tex_layout, unsigned TU_tex_detail0, unsigned TU_tex_detail1, unsigned TU_tex_detail2, unsigned TU_tex_detail3, unsigned TU_DiffuseMap, unsigned TU_SpecularMap, unsigned TU_SSAO); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix); }; class CausticsShader @@ -174,10 +182,11 @@ class CausticsShader public: static GLuint Program; static GLuint attrib_position, attrib_texcoord; - static GLuint uniform_MVP, uniform_dir, uniform_dir2, uniform_Albedo, uniform_DiffuseMap, uniform_SpecularMap, uniform_SSAO, uniform_screen, uniform_ambient, uniform_caustictex; + static GLuint uniform_MVP, uniform_dir, uniform_dir2, uniform_screen, uniform_ambient; + static GLuint TU_Albedo, TU_caustictex; static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector2df &dir, const core::vector2df &dir2, const core::vector2df &screen, unsigned TU_albedo, unsigned TU_DiffuseMap, unsigned TU_Specmap, unsigned TU_SSAO, unsigned TU_caustictex); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::vector2df &dir, const core::vector2df &dir2, const core::vector2df &screen); }; class BubbleShader diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index db34974b0..edcbfdc0c 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -271,7 +271,7 @@ void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - glActiveTexture(GL_TEXTURE0); + glActiveTexture(GL_TEXTURE0 + MeshShader::SphereMapShader::TU_tex); if (!irr_driver->SkyboxCubeMap) { GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ONE }; @@ -284,7 +284,7 @@ void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } - MeshShader::SphereMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, irr_driver->getInvProjMatrix(), core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0); + MeshShader::SphereMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, irr_driver->getInvProjMatrix(), core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height)); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); @@ -303,7 +303,7 @@ void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM size_t count = mesh.IndexCount; // Texlayout - setTexture(0, mesh.textures[1], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::SplattingShader::TU_tex_layout, mesh.textures[1], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); if (irr_driver->getLightViz()) { GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ALPHA}; @@ -315,7 +315,7 @@ void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } //Tex detail0 - setTexture(1, mesh.textures[2], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::SplattingShader::TU_tex_detail0, mesh.textures[2], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); if (irr_driver->getLightViz()) { GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ALPHA}; @@ -327,7 +327,7 @@ void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } //Tex detail1 - setTexture(2, mesh.textures[3], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::SplattingShader::TU_tex_detail1, mesh.textures[3], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); if (irr_driver->getLightViz()) { GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ALPHA}; @@ -339,7 +339,7 @@ void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } //Tex detail2 - setTexture(3, mesh.textures[4], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::SplattingShader::TU_tex_detail2, mesh.textures[4], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); if (irr_driver->getLightViz()) { GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ALPHA}; @@ -351,7 +351,7 @@ void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } //Tex detail3 - setTexture(4, mesh.textures[5], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::SplattingShader::TU_tex_detail3, mesh.textures[5], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); if (irr_driver->getLightViz()) { GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ALPHA}; @@ -362,21 +362,8 @@ void drawSplatting(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM GLint swizzleMask[] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA}; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - // Diffuse - setTexture(5, getTextureGLuint(irr_driver->getRTT(RTT_TMP1)), GL_NEAREST, GL_NEAREST); - // Specular - setTexture(6, getTextureGLuint(irr_driver->getRTT(RTT_TMP2)), GL_NEAREST, GL_NEAREST); - - // SSAO - setTexture(7, getTextureGLuint(irr_driver->getRTT(RTT_SSAO)), GL_NEAREST, GL_NEAREST); - if (!UserConfigParams::m_ssao) - { - GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ONE}; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } - - MeshShader::SplattingShader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3, 4, 5, 6, 7); + MeshShader::SplattingShader::setUniforms(ModelViewProjectionMatrix); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); @@ -389,7 +376,7 @@ void drawObjectRefPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjec GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::ObjectRefPass2Shader::TU_Albedo, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); if (irr_driver->getLightViz()) { GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ALPHA}; @@ -400,16 +387,8 @@ void drawObjectRefPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjec GLint swizzleMask[] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA}; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - setTexture(1, getTextureGLuint(irr_driver->getRTT(RTT_TMP1)), GL_NEAREST, GL_NEAREST); - setTexture(2, getTextureGLuint(irr_driver->getRTT(RTT_TMP2)), GL_NEAREST, GL_NEAREST); - setTexture(3, getTextureGLuint(irr_driver->getRTT(RTT_SSAO)), GL_NEAREST, GL_NEAREST); - if (!UserConfigParams::m_ssao) - { - GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ONE}; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } - MeshShader::ObjectRefPass2Shader::setUniforms(ModelViewProjectionMatrix, TextureMatrix, 0, 1, 2, 3); + MeshShader::ObjectRefPass2Shader::setUniforms(ModelViewProjectionMatrix, TextureMatrix); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); @@ -422,7 +401,7 @@ void drawCaustics(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionM GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::CausticsShader::TU_Albedo, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); if (irr_driver->getLightViz()) { GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ALPHA }; @@ -433,17 +412,9 @@ void drawCaustics(const GLMesh &mesh, const core::matrix4 & ModelViewProjectionM GLint swizzleMask[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - setTexture(1, getTextureGLuint(irr_driver->getTexture(file_manager->getAsset("textures/caustics.png").c_str())), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - setTexture(2, getTextureGLuint(irr_driver->getRTT(RTT_TMP1)), GL_NEAREST, GL_NEAREST); - setTexture(3, getTextureGLuint(irr_driver->getRTT(RTT_TMP2)), GL_NEAREST, GL_NEAREST); - setTexture(4, getTextureGLuint(irr_driver->getRTT(RTT_SSAO)), GL_NEAREST, GL_NEAREST); - if (!UserConfigParams::m_ssao) - { - GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ONE }; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } + setTexture(MeshShader::CausticsShader::TU_caustictex, getTextureGLuint(irr_driver->getTexture(file_manager->getAsset("textures/caustics.png").c_str())), GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - MeshShader::CausticsShader::setUniforms(ModelViewProjectionMatrix, dir, dir2, core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 0, 2, 3, 4, 1); + MeshShader::CausticsShader::setUniforms(ModelViewProjectionMatrix, dir, dir2, core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height)); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); @@ -456,7 +427,7 @@ void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::GrassPass2Shader::TU_Albedo, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); if (irr_driver->getLightViz()) { GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ALPHA}; @@ -467,16 +438,8 @@ void drawGrassPass2(const GLMesh &mesh, const core::matrix4 & ModelViewProjectio GLint swizzleMask[] = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA}; glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - setTexture(1, getTextureGLuint(irr_driver->getRTT(RTT_TMP1)), GL_NEAREST, GL_NEAREST); - setTexture(2, getTextureGLuint(irr_driver->getRTT(RTT_TMP2)), GL_NEAREST, GL_NEAREST); - setTexture(3, getTextureGLuint(irr_driver->getRTT(RTT_SSAO)), GL_NEAREST, GL_NEAREST); - if (!UserConfigParams::m_ssao) - { - GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ONE}; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } - MeshShader::GrassPass2Shader::setUniforms(ModelViewProjectionMatrix, windDir, 0, 1, 2, 3); + MeshShader::GrassPass2Shader::setUniforms(ModelViewProjectionMatrix, windDir); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); @@ -489,16 +452,7 @@ void drawUntexturedObject(const GLMesh &mesh, const core::matrix4 &ModelViewProj GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - setTexture(0, getTextureGLuint(irr_driver->getRTT(RTT_TMP1)), GL_NEAREST, GL_NEAREST); - setTexture(1, getTextureGLuint(irr_driver->getRTT(RTT_TMP2)), GL_NEAREST, GL_NEAREST); - setTexture(2, getTextureGLuint(irr_driver->getRTT(RTT_SSAO)), GL_NEAREST, GL_NEAREST); - if (!UserConfigParams::m_ssao) - { - GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ONE}; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } - - MeshShader::UntexturedObjectShader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2); + MeshShader::UntexturedObjectShader::setUniforms(ModelViewProjectionMatrix); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); @@ -511,7 +465,7 @@ void drawObjectRimLimit(const GLMesh &mesh, const core::matrix4 &ModelViewProjec GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::ObjectRimLimitShader::TU_Albedo, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); if (irr_driver->getLightViz()) { GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ALPHA }; @@ -523,16 +477,7 @@ void drawObjectRimLimit(const GLMesh &mesh, const core::matrix4 &ModelViewProjec glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - setTexture(1, getTextureGLuint(irr_driver->getRTT(RTT_TMP1)), GL_NEAREST, GL_NEAREST); - setTexture(2, getTextureGLuint(irr_driver->getRTT(RTT_TMP2)), GL_NEAREST, GL_NEAREST); - setTexture(3, getTextureGLuint(irr_driver->getRTT(RTT_SSAO)), GL_NEAREST, GL_NEAREST); - if (!UserConfigParams::m_ssao) - { - GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ONE }; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } - - MeshShader::ObjectRimLimitShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix, 0, 1, 2, 3); + MeshShader::ObjectRimLimitShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, TextureMatrix); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); @@ -545,7 +490,7 @@ void drawObjectUnlit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectio GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::ObjectUnlitShader::TU_tex, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); if (irr_driver->getLightViz()) { GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ALPHA }; @@ -557,7 +502,7 @@ void drawObjectUnlit(const GLMesh &mesh, const core::matrix4 &ModelViewProjectio glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - MeshShader::ObjectUnlitShader::setUniforms(ModelViewProjectionMatrix, 0); + MeshShader::ObjectUnlitShader::setUniforms(ModelViewProjectionMatrix); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); @@ -570,7 +515,7 @@ void drawDetailledObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelView GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::DetailledObjectPass2Shader::TU_Albedo, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); if (irr_driver->getLightViz()) { GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ALPHA}; @@ -582,18 +527,9 @@ void drawDetailledObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelView glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - setTexture(1, mesh.textures[1], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::DetailledObjectPass2Shader::TU_detail, mesh.textures[1], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); - setTexture(2, getTextureGLuint(irr_driver->getRTT(RTT_TMP1)), GL_NEAREST, GL_NEAREST); - setTexture(3, getTextureGLuint(irr_driver->getRTT(RTT_TMP2)), GL_NEAREST, GL_NEAREST); - setTexture(4, getTextureGLuint(irr_driver->getRTT(RTT_SSAO)), GL_NEAREST, GL_NEAREST); - if (!UserConfigParams::m_ssao) - { - GLint swizzleMask[] = {GL_ONE, GL_ONE, GL_ONE, GL_ONE}; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } - - MeshShader::DetailledObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, 0, 1, 2, 3, 4); + MeshShader::DetailledObjectPass2Shader::setUniforms(ModelViewProjectionMatrix); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); @@ -606,7 +542,7 @@ void drawObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjectio GLenum itype = mesh.IndexType; size_t count = mesh.IndexCount; - setTexture(0, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); + setTexture(MeshShader::ObjectPass2Shader::TU_Albedo, mesh.textures[0], GL_LINEAR, GL_LINEAR_MIPMAP_LINEAR, true); if (irr_driver->getLightViz()) { GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ALPHA }; @@ -618,16 +554,7 @@ void drawObjectPass2(const GLMesh &mesh, const core::matrix4 &ModelViewProjectio glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); } - setTexture(1, getTextureGLuint(irr_driver->getRTT(RTT_TMP1)), GL_NEAREST, GL_NEAREST); - setTexture(2, getTextureGLuint(irr_driver->getRTT(RTT_TMP2)), GL_NEAREST, GL_NEAREST); - setTexture(3, getTextureGLuint(irr_driver->getRTT(RTT_SSAO)), GL_NEAREST, GL_NEAREST); - if (!UserConfigParams::m_ssao) - { - GLint swizzleMask[] = { GL_ONE, GL_ONE, GL_ONE, GL_ONE }; - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, swizzleMask); - } - - MeshShader::ObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, TextureMatrix, 0, 1, 2, 3); + MeshShader::ObjectPass2Shader::setUniforms(ModelViewProjectionMatrix, TextureMatrix); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); From 740c25180850f064bcd58bbcafa7bc176a5261d3 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Mon, 10 Mar 2014 23:29:37 +0100 Subject: [PATCH 3/5] Use Instancing for lights. --- data/shaders/pointlight.frag | 53 ++++++--------- data/shaders/pointlight.vert | 38 +++++++++++ src/graphics/post_processing.cpp | 22 ------ src/graphics/post_processing.hpp | 1 - src/graphics/render.cpp | 113 ++++++++++++++++++++++++------- src/graphics/shaders.cpp | 97 +++++++++++++++----------- src/graphics/shaders.hpp | 28 +++++--- src/graphics/stkbillboard.cpp | 12 +--- 8 files changed, 225 insertions(+), 139 deletions(-) create mode 100644 data/shaders/pointlight.vert diff --git a/data/shaders/pointlight.frag b/data/shaders/pointlight.frag index 174732010..0c2c9a1cf 100644 --- a/data/shaders/pointlight.frag +++ b/data/shaders/pointlight.frag @@ -1,23 +1,16 @@ uniform sampler2D ntex; uniform sampler2D dtex; - -uniform vec4 center[16]; -uniform vec4 col[16]; -uniform float energy[16]; uniform float spec; uniform mat4 invproj; -uniform mat4 viewm; +uniform mat4 ViewMatrix; +uniform vec2 screen; + +flat in vec3 center; +flat in float energy; +flat in vec3 col; -#if __VERSION__ >= 130 -in vec2 uv; out vec4 Diffuse; out vec4 Specular; -#else -varying vec2 uv; -#define Diffuse gl_FragData[0] -#define Specular gl_FragData[1] -#endif - vec3 DecodeNormal(vec2 n) { @@ -27,7 +20,7 @@ vec3 DecodeNormal(vec2 n) } void main() { - vec2 texc = uv; + vec2 texc = gl_FragCoord.xy / screen; float z = texture(dtex, texc).x; vec3 norm = normalize(DecodeNormal(2. * texture(ntex, texc).xy - 1.)); @@ -38,25 +31,23 @@ void main() { vec3 diffuse = vec3(0.), specular = vec3(0.); - for (int i = 0; i < 16; ++i) { - vec4 pseudocenter = viewm * vec4(center[i].xyz, 1.0); - pseudocenter /= pseudocenter.w; - vec3 light_pos = pseudocenter.xyz; - vec3 light_col = col[i].xyz; - float d = distance(light_pos, xpos.xyz); - float att = energy[i] * 200. / (4. * 3.14 * d * d); - float spec_att = (energy[i] + 10.) * 200. / (4. * 3.14 * d * d); + vec4 pseudocenter = ViewMatrix * vec4(center.xyz, 1.0); + pseudocenter /= pseudocenter.w; + vec3 light_pos = pseudocenter.xyz; + vec3 light_col = col.xyz; + float d = distance(light_pos, xpos.xyz); + float att = energy * 200. / (4. * 3.14 * d * d); + float spec_att = (energy + 10.) * 200. / (4. * 3.14 * d * d); - // Light Direction - vec3 L = normalize(xpos.xyz - light_pos); + // Light Direction + vec3 L = normalize(xpos.xyz - light_pos); - float NdotL = max(0.0, dot(norm, -L)); - diffuse += NdotL * light_col * att; - // Reflected light dir - vec3 R = reflect(-L, norm); - float RdotE = max(0.0, dot(R, eyedir)); - specular += pow(RdotE, spec) * light_col * spec_att; - } + float NdotL = max(0.0, dot(norm, -L)); + diffuse += NdotL * light_col * att; + // Reflected light dir + vec3 R = reflect(-L, norm); + float RdotE = max(0.0, dot(R, eyedir)); + specular += pow(RdotE, spec) * light_col * spec_att; Diffuse = vec4(diffuse, 1.); Specular = vec4(specular , 1.); diff --git a/data/shaders/pointlight.vert b/data/shaders/pointlight.vert new file mode 100644 index 000000000..540584c4c --- /dev/null +++ b/data/shaders/pointlight.vert @@ -0,0 +1,38 @@ +uniform mat4 ViewMatrix; +uniform mat4 ProjectionMatrix; + +in vec3 Position; +in float Energy; +in vec3 Color; + +in vec2 Corner; + +flat out vec3 center; +flat out float energy; +flat out vec3 col; + +const float zNear = 1.; + +void main(void) +{ + // Beyond that value, light is too attenuated + float r = 40 * Energy; + center = Position; + energy = Energy; + vec4 Center = ViewMatrix * vec4(Position, 1.); + if (Center.z > zNear) // Light is in front of the cam + { + vec3 UnitCenter = normalize(-Center.xyz); + float clampedR = min(r, Center.z - 1.); + float cosTheta = dot(UnitCenter, vec3(0., 0., -1)); + float d = clampedR / cosTheta; + Center.xyz += d * UnitCenter; + } + else if (Center.z + r > zNear) // Light is behind the cam but in range + { + Center.z = zNear; + // TODO: Change r so that we make the screen aligned quad fits light range. + } + col = Color; + gl_Position = ProjectionMatrix * (Center + r * vec4(Corner, 0., 0.)); +} diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index b03fc3ff9..e4fa28b4a 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -280,28 +280,6 @@ void renderColorLevel(ITexture *in) glEnable(GL_DEPTH_TEST); } -void PostProcessing::renderPointlight(const std::vector &positions, const std::vector &colors, const std::vector &energy) -{ - glEnable(GL_BLEND); - glBlendEquation(GL_FUNC_ADD); - glBlendFunc(GL_ONE, GL_ONE); - glDisable(GL_DEPTH_TEST); - - glUseProgram(FullScreenShader::PointLightShader::Program); - glBindVertexArray(FullScreenShader::PointLightShader::vao); - - setTexture(0, getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST); - setTexture(1, getDepthTexture(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST); - FullScreenShader::PointLightShader::setUniforms(irr_driver->getInvProjMatrix(), irr_driver->getViewMatrix(), positions, colors, energy, 200, 0, 1); - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glBindVertexArray(0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glEnable(GL_DEPTH_TEST); - glDisable(GL_BLEND); -} - void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSHCoeff, const float *rSHCoeff) { glDisable(GL_DEPTH_TEST); diff --git a/src/graphics/post_processing.hpp b/src/graphics/post_processing.hpp index 260a2ee26..bac7bdb5c 100644 --- a/src/graphics/post_processing.hpp +++ b/src/graphics/post_processing.hpp @@ -73,7 +73,6 @@ public: void update(float dt); /** Generate diffuse and specular map */ - void renderPointlight(const std::vector &positions, const std::vector &colors, const std::vector &energy); void renderSunlight(); void renderShadowedSunlight(const std::vector &sun_ortho_matrix, unsigned depthtex); diff --git a/src/graphics/render.cpp b/src/graphics/render.cpp index d64ef292a..aba3241fa 100644 --- a/src/graphics/render.cpp +++ b/src/graphics/render.cpp @@ -744,6 +744,73 @@ void IrrDriver::renderGlow(video::SOverrideMaterial &overridemat, // ---------------------------------------------------------------------------- #define MAXLIGHT 16 // to be adjusted in pointlight.frag too + + +static GLuint pointlightvbo = 0; +static GLuint pointlightsvao = 0; + +struct PointLightInfo +{ + float posX; + float posY; + float posZ; + float energy; + float red; + float green; + float blue; + float padding; +}; + +void createPointLightVAO() +{ + glGenVertexArrays(1, &pointlightsvao); + glBindVertexArray(pointlightsvao); + + glBindBuffer(GL_ARRAY_BUFFER, SharedObject::billboardvbo); + glEnableVertexAttribArray(MeshShader::PointLightShader::attrib_Corner); + glVertexAttribPointer(MeshShader::PointLightShader::attrib_Corner, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + + glGenBuffers(1, &pointlightvbo); + glBindBuffer(GL_ARRAY_BUFFER, pointlightvbo); + glBufferData(GL_ARRAY_BUFFER, MAXLIGHT * sizeof(PointLightInfo), 0, GL_DYNAMIC_DRAW); + + glEnableVertexAttribArray(MeshShader::PointLightShader::attrib_Position); + glVertexAttribPointer(MeshShader::PointLightShader::attrib_Position, 3, GL_FLOAT, GL_FALSE, sizeof(PointLightInfo), 0); + glEnableVertexAttribArray(MeshShader::PointLightShader::attrib_Energy); + glVertexAttribPointer(MeshShader::PointLightShader::attrib_Energy, 1, GL_FLOAT, GL_FALSE, sizeof(PointLightInfo), (GLvoid*)(3 * sizeof(float))); + glEnableVertexAttribArray(MeshShader::PointLightShader::attrib_Color); + glVertexAttribPointer(MeshShader::PointLightShader::attrib_Color, 3, GL_FLOAT, GL_FALSE, sizeof(PointLightInfo), (GLvoid*)(4 * sizeof(float))); + + glVertexAttribDivisor(MeshShader::PointLightShader::attrib_Position, 1); + glVertexAttribDivisor(MeshShader::PointLightShader::attrib_Energy, 1); + glVertexAttribDivisor(MeshShader::PointLightShader::attrib_Color, 1); +} + +static void renderPointLights() +{ + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFunc(GL_ONE, GL_ONE); + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + + glUseProgram(MeshShader::PointLightShader::Program); + glBindVertexArray(pointlightsvao); + + setTexture(0, getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST); + setTexture(1, getDepthTexture(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST); + MeshShader::PointLightShader::setUniforms(irr_driver->getViewMatrix(), irr_driver->getProjMatrix(), irr_driver->getInvProjMatrix(), core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height), 200, 0, 1); + + glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, MAXLIGHT); + glBindVertexArray(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glEnable(GL_DEPTH_TEST); + glDisable(GL_BLEND); +} + +PointLightInfo PointLightsInfo[MAXLIGHT]; + void IrrDriver::renderLights(const core::aabbox3df& cambox, scene::ICameraSceneNode * const camnode, video::SOverrideMaterial &overridemat, @@ -765,9 +832,7 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, const u32 lightcount = m_lights.size(); const core::vector3df &campos = irr_driver->getSceneManager()->getActiveCamera()->getAbsolutePosition(); - std::vector accumulatedLightPos; - std::vector accumulatedLightColor; - std::vector accumulatedLightEnergy; + std::vector BucketedLN[15]; for (unsigned int i = 0; i < lightcount; i++) { @@ -793,7 +858,7 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, { for (unsigned j = 0; j < BucketedLN[i].size(); j++) { - if (++lightnum > MAXLIGHT) + if (++lightnum >= MAXLIGHT) { LightNode* light_node = BucketedLN[i].at(j); light_node->setEnergyMultiplier(0.0f); @@ -809,17 +874,16 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, } const core::vector3df &pos = light_node->getAbsolutePosition(); - accumulatedLightPos.push_back(pos.X); - accumulatedLightPos.push_back(pos.Y); - accumulatedLightPos.push_back(pos.Z); - accumulatedLightPos.push_back(0.); - const core::vector3df &col = light_node->getColor(); + PointLightsInfo[lightnum].posX = pos.X; + PointLightsInfo[lightnum].posY = pos.Y; + PointLightsInfo[lightnum].posZ = pos.Z; - accumulatedLightColor.push_back(col.X); - accumulatedLightColor.push_back(col.Y); - accumulatedLightColor.push_back(col.Z); - accumulatedLightColor.push_back(0.); - accumulatedLightEnergy.push_back(light_node->getEffectiveEnergy()); + PointLightsInfo[lightnum].energy = light_node->getEffectiveEnergy(); + + const core::vector3df &col = light_node->getColor(); + PointLightsInfo[lightnum].red = col.X; + PointLightsInfo[lightnum].green = col.Y; + PointLightsInfo[lightnum].blue = col.Z; } } if (lightnum > MAXLIGHT) @@ -828,19 +892,20 @@ void IrrDriver::renderLights(const core::aabbox3df& cambox, break; } } + + lightnum++; + // Fill lights for (; lightnum < MAXLIGHT; lightnum++) { - accumulatedLightPos.push_back(0.); - accumulatedLightPos.push_back(0.); - accumulatedLightPos.push_back(0.); - accumulatedLightPos.push_back(0.); - accumulatedLightColor.push_back(0.); - accumulatedLightColor.push_back(0.); - accumulatedLightColor.push_back(0.); - accumulatedLightColor.push_back(0.); - accumulatedLightEnergy.push_back(0.); + PointLightsInfo[lightnum].energy = 0; } - m_post_processing->renderPointlight(accumulatedLightPos, accumulatedLightColor, accumulatedLightEnergy); + + if (!pointlightsvao) + createPointLightVAO(); + glBindVertexArray(pointlightsvao); + glBindBuffer(GL_ARRAY_BUFFER, pointlightvbo); + glBufferSubData(GL_ARRAY_BUFFER, 0, MAXLIGHT * sizeof(PointLightInfo), PointLightsInfo); + renderPointLights(); if (SkyboxCubeMap) m_post_processing->renderDiffuseEnvMap(blueSHCoeff, greenSHCoeff, redSHCoeff); // Handle SSAO diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index fcaadc662..f6e3c280e 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -89,6 +89,21 @@ static void initQuadBuffer() glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad_vertex, GL_STATIC_DRAW); } +GLuint SharedObject::billboardvbo = 0; + +static void initBillboardVBO() +{ + float quad[] = { + -.5, -.5, 0., 1., + -.5, .5, 0., 0., + .5, -.5, 1., 1., + .5, .5, 1., 0., + }; + glGenBuffers(1, &(SharedObject::billboardvbo)); + glBindBuffer(GL_ARRAY_BUFFER, SharedObject::billboardvbo); + glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad, GL_STATIC_DRAW); +} + void Shaders::loadShaders() { const std::string &dir = file_manager->getAsset(FileManager::SHADER, ""); @@ -215,6 +230,7 @@ void Shaders::loadShaders() initGL(); initQuadVBO(); initQuadBuffer(); + initBillboardVBO(); FullScreenShader::BloomBlendShader::init(); FullScreenShader::BloomShader::init(); FullScreenShader::ColorLevelShader::init(); @@ -227,7 +243,6 @@ void Shaders::loadShaders() FullScreenShader::PenumbraVShader::init(); FullScreenShader::GlowShader::init(); FullScreenShader::PassThroughShader::init(); - FullScreenShader::PointLightShader::init(); FullScreenShader::SSAOShader::init(); FullScreenShader::SunLightShader::init(); FullScreenShader::DiffuseEnvMapShader::init(); @@ -254,6 +269,7 @@ void Shaders::loadShaders() MeshShader::TransparentShader::init(); MeshShader::TransparentFogShader::init(); MeshShader::BillboardShader::init(); + MeshShader::PointLightShader::init(); MeshShader::DisplaceShader::init(); MeshShader::DisplaceMaskShader::init(); MeshShader::ShadowShader::init(); @@ -921,6 +937,47 @@ namespace MeshShader glUniformMatrix4fv(uniform_ipvmat, 1, GL_FALSE, ipvmat.pointer()); glUniform1i(uniform_tex, TU_tex); } + + GLuint PointLightShader::Program; + GLuint PointLightShader::attrib_Position; + GLuint PointLightShader::attrib_Color; + GLuint PointLightShader::attrib_Energy; + GLuint PointLightShader::attrib_Corner; + GLuint PointLightShader::uniform_ntex; + GLuint PointLightShader::uniform_dtex; + GLuint PointLightShader::uniform_spec; + GLuint PointLightShader::uniform_screen; + GLuint PointLightShader::uniform_invproj; + GLuint PointLightShader::uniform_VM; + GLuint PointLightShader::uniform_PM; + + void PointLightShader::init() + { + Program = LoadProgram(file_manager->getAsset("shaders/pointlight.vert").c_str(), file_manager->getAsset("shaders/pointlight.frag").c_str()); + attrib_Position = glGetAttribLocation(Program, "Position"); + attrib_Color = glGetAttribLocation(Program, "Color"); + attrib_Energy = glGetAttribLocation(Program, "Energy"); + attrib_Corner = glGetAttribLocation(Program, "Corner"); + uniform_ntex = glGetUniformLocation(Program, "ntex"); + uniform_dtex = glGetUniformLocation(Program, "dtex"); + uniform_spec = glGetUniformLocation(Program, "spec"); + uniform_invproj = glGetUniformLocation(Program, "invproj"); + uniform_screen = glGetUniformLocation(Program, "screen"); + uniform_VM = glGetUniformLocation(Program, "ViewMatrix"); + uniform_PM = glGetUniformLocation(Program, "ProjectionMatrix"); + } + + void PointLightShader::setUniforms(const core::matrix4 &ViewMatrix, const core::matrix4 &ProjMatrix, const core::matrix4 &InvProjMatrix, const core::vector2df &screen, unsigned spec, unsigned TU_ntex, unsigned TU_dtex) + { + glUniform1f(uniform_spec, 200); + glUniform2f(uniform_screen, screen.X, screen.Y); + glUniformMatrix4fv(uniform_invproj, 1, GL_FALSE, InvProjMatrix.pointer()); + glUniformMatrix4fv(uniform_VM, 1, GL_FALSE, ViewMatrix.pointer()); + glUniformMatrix4fv(uniform_PM, 1, GL_FALSE, ProjMatrix.pointer()); + + glUniform1i(uniform_ntex, TU_ntex); + glUniform1i(uniform_dtex, TU_dtex); + } GLuint BillboardShader::Program; GLuint BillboardShader::attrib_corner; @@ -1366,44 +1423,6 @@ namespace FullScreenShader vao = createVAO(Program); } - GLuint PointLightShader::Program; - GLuint PointLightShader::uniform_ntex; - GLuint PointLightShader::uniform_dtex; - GLuint PointLightShader::uniform_center; - GLuint PointLightShader::uniform_col; - GLuint PointLightShader::uniform_energy; - GLuint PointLightShader::uniform_spec; - GLuint PointLightShader::uniform_invproj; - GLuint PointLightShader::uniform_viewm; - GLuint PointLightShader::vao; - - void PointLightShader::init() - { - Program = LoadProgram(file_manager->getAsset("shaders/screenquad.vert").c_str(), file_manager->getAsset("shaders/pointlight.frag").c_str()); - uniform_ntex = glGetUniformLocation(Program, "ntex"); - uniform_dtex = glGetUniformLocation(Program, "dtex"); - uniform_center = glGetUniformLocation(Program, "center[0]"); - uniform_col = glGetUniformLocation(Program, "col[0]"); - uniform_energy = glGetUniformLocation(Program, "energy[0]"); - uniform_spec = glGetUniformLocation(Program, "spec"); - uniform_invproj = glGetUniformLocation(Program, "invproj"); - uniform_viewm = glGetUniformLocation(Program, "viewm"); - vao = createVAO(Program); - } - - void PointLightShader::setUniforms(const core::matrix4 &InvProjMatrix, const core::matrix4 &ViewMatrix, const std::vector &positions, const std::vector &colors, const std::vector &energy, unsigned spec, unsigned TU_ntex, unsigned TU_dtex) - { - glUniform4fv(FullScreenShader::PointLightShader::uniform_center, 16, positions.data()); - glUniform4fv(FullScreenShader::PointLightShader::uniform_col, 16, colors.data()); - glUniform1fv(FullScreenShader::PointLightShader::uniform_energy, 16, energy.data()); - glUniform1f(FullScreenShader::PointLightShader::uniform_spec, 200); - glUniformMatrix4fv(FullScreenShader::PointLightShader::uniform_invproj, 1, GL_FALSE, InvProjMatrix.pointer()); - glUniformMatrix4fv(FullScreenShader::PointLightShader::uniform_viewm, 1, GL_FALSE, ViewMatrix.pointer()); - - glUniform1i(FullScreenShader::PointLightShader::uniform_ntex, TU_ntex); - glUniform1i(FullScreenShader::PointLightShader::uniform_dtex, TU_dtex); - } - GLuint SunLightShader::Program; GLuint SunLightShader::uniform_ntex; GLuint SunLightShader::uniform_dtex; diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 8a039fe35..4015fdb3e 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -24,6 +24,11 @@ typedef unsigned int GLuint; using namespace irr; +class SharedObject +{ +public: + static GLuint billboardvbo; +}; namespace MeshShader { class ObjectPass1Shader @@ -222,6 +227,18 @@ public: static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TextureMatrix, const core::matrix4 &ipvmat, float fogmax, float startH, float endH, float start, float end, const core::vector3df &col, const core::vector3df &campos, unsigned TU_tex); }; +class PointLightShader +{ +public: + static GLuint Program; + static GLuint attrib_Position, attrib_Energy, attrib_Color; + static GLuint attrib_Corner; + static GLuint uniform_ntex, uniform_dtex, uniform_spec, uniform_screen, uniform_invproj, uniform_VM, uniform_PM; + + static void init(); + static void setUniforms(const core::matrix4 &ViewMatrix, const core::matrix4 &ProjMatrix, const core::matrix4 &InvProjMatrix, const core::vector2df &screen, unsigned spec, unsigned TU_ntex, unsigned TU_dtex); +}; + class BillboardShader { public: @@ -395,17 +412,6 @@ public: static void init(); }; -class PointLightShader -{ -public: - static GLuint Program; - static GLuint uniform_ntex, uniform_dtex, uniform_center, uniform_col, uniform_energy, uniform_spec, uniform_invproj, uniform_viewm; - static GLuint vao; - - static void init(); - static void setUniforms(const core::matrix4 &InvProjMatrix, const core::matrix4 &ViewMatrix, const std::vector &positions, const std::vector &colors, const std::vector &energy, unsigned spec, unsigned TU_ntex, unsigned TU_dtex); -}; - class SunLightShader { public: diff --git a/src/graphics/stkbillboard.cpp b/src/graphics/stkbillboard.cpp index ee24b1270..2f4d5f578 100644 --- a/src/graphics/stkbillboard.cpp +++ b/src/graphics/stkbillboard.cpp @@ -5,23 +5,13 @@ using namespace irr; -static GLuint billboardvbo; static GLuint billboardvao = 0; static void createbillboardvao() { - float quad[] = { - -.5, -.5, 0., 1., - -.5, .5, 0., 0., - .5, -.5, 1., 1., - .5, .5, 1., 0., - }; - - glGenBuffers(1, &billboardvbo); glGenVertexArrays(1, &billboardvao); glBindVertexArray(billboardvao); - glBindBuffer(GL_ARRAY_BUFFER, billboardvbo); - glBufferData(GL_ARRAY_BUFFER, 16 * sizeof(float), quad, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, SharedObject::billboardvbo); glEnableVertexAttribArray(MeshShader::BillboardShader::attrib_corner); glEnableVertexAttribArray(MeshShader::BillboardShader::attrib_texcoord); glVertexAttribPointer(MeshShader::BillboardShader::attrib_corner, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); From 0c5d5ce96ebf12633c8c05385c617711736479ca Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Wed, 12 Mar 2014 19:28:04 +0100 Subject: [PATCH 4/5] IBL: Fix sampling ignoring cubemap rotation --- data/shaders/diffuseenvmap.frag | 5 ++++- data/shaders/objectpass_spheremap.frag | 6 +++++- src/graphics/post_processing.cpp | 3 ++- src/graphics/shaders.cpp | 10 ++++++++-- src/graphics/shaders.hpp | 8 ++++---- src/graphics/stkmesh.cpp | 2 +- 6 files changed, 24 insertions(+), 10 deletions(-) diff --git a/data/shaders/diffuseenvmap.frag b/data/shaders/diffuseenvmap.frag index 1e0777fcd..eb2822598 100644 --- a/data/shaders/diffuseenvmap.frag +++ b/data/shaders/diffuseenvmap.frag @@ -2,6 +2,7 @@ uniform float blueLmn[9]; uniform float greenLmn[9]; uniform float redLmn[9]; uniform sampler2D ntex; +uniform mat4 TransposeViewMatrix; #if __VERSION__ >= 130 in vec2 uv; @@ -35,7 +36,9 @@ mat4 getMatrix(float L[9]) void main(void) { vec3 normal = normalize(DecodeNormal(2. * texture(ntex, uv).xy - 1.)); - vec4 extendednormal = vec4(normal, 1.); + // Convert normal in world space (where SH coordinates were computed) + vec4 extendednormal = TransposeViewMatrix * vec4(normal, 1.); + extendednormal.w = 1.; mat4 rmat = getMatrix(redLmn); mat4 gmat = getMatrix(greenLmn); mat4 bmat = getMatrix(blueLmn); diff --git a/data/shaders/objectpass_spheremap.frag b/data/shaders/objectpass_spheremap.frag index 8a02ae7ab..13467bbad 100644 --- a/data/shaders/objectpass_spheremap.frag +++ b/data/shaders/objectpass_spheremap.frag @@ -1,6 +1,7 @@ uniform samplerCube tex; uniform mat4 invproj; uniform vec2 screen; +uniform mat4 TransposeViewMatrix; #if __VERSION__ >= 130 in vec3 nor; @@ -17,7 +18,10 @@ void main() { xpos = invproj * xpos; xpos.xyz /= xpos.w; - vec4 detail0 = texture(tex, reflect(xpos.xyz, nor)); + vec3 viewSampleDir = reflect(xpos.xyz, nor); + // Convert sampleDir in world space (where tex was generated) + vec4 sampleDir = TransposeViewMatrix * vec4(viewSampleDir, 0.); + vec4 detail0 = texture(tex, sampleDir.xyz); FragColor = vec4(detail0.xyz, 1.); } diff --git a/src/graphics/post_processing.cpp b/src/graphics/post_processing.cpp index e4fa28b4a..b10dad033 100644 --- a/src/graphics/post_processing.cpp +++ b/src/graphics/post_processing.cpp @@ -291,7 +291,8 @@ void PostProcessing::renderDiffuseEnvMap(const float *bSHCoeff, const float *gSH glBindVertexArray(FullScreenShader::DiffuseEnvMapShader::vao); setTexture(0, getTextureGLuint(irr_driver->getRTT(RTT_NORMAL_AND_DEPTH)), GL_NEAREST, GL_NEAREST); - FullScreenShader::DiffuseEnvMapShader::setUniforms(bSHCoeff, gSHCoeff, rSHCoeff, 0); + core::matrix4 TVM = irr_driver->getViewMatrix().getTransposed(); + FullScreenShader::DiffuseEnvMapShader::setUniforms(TVM, bSHCoeff, gSHCoeff, rSHCoeff, 0); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glBindVertexArray(0); diff --git a/src/graphics/shaders.cpp b/src/graphics/shaders.cpp index f6e3c280e..405003ac4 100644 --- a/src/graphics/shaders.cpp +++ b/src/graphics/shaders.cpp @@ -707,6 +707,7 @@ namespace MeshShader GLuint SphereMapShader::attrib_normal; GLuint SphereMapShader::uniform_MVP; GLuint SphereMapShader::uniform_TIMV; + GLuint SphereMapShader::uniform_TVM; GLuint SphereMapShader::uniform_invproj; GLuint SphereMapShader::uniform_screen; GLuint SphereMapShader::TU_tex; @@ -718,6 +719,7 @@ namespace MeshShader attrib_normal = glGetAttribLocation(Program, "Normal"); uniform_MVP = glGetUniformLocation(Program, "ModelViewProjectionMatrix"); uniform_TIMV = glGetUniformLocation(Program, "TransposeInverseModelView"); + uniform_TVM = glGetUniformLocation(Program, "TransposeViewMatrix"); GLuint uniform_tex = glGetUniformLocation(Program, "tex"); uniform_invproj = glGetUniformLocation(Program, "invproj"); uniform_screen = glGetUniformLocation(Program, "screen"); @@ -728,10 +730,11 @@ namespace MeshShader glUseProgram(0); } - void SphereMapShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &InvProj, const core::vector2df& screen) + void SphereMapShader::setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeViewMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &InvProj, const core::vector2df& screen) { glUniformMatrix4fv(uniform_MVP, 1, GL_FALSE, ModelViewProjectionMatrix.pointer()); glUniformMatrix4fv(uniform_TIMV, 1, GL_FALSE, TransposeInverseModelView.pointer()); + glUniformMatrix4fv(uniform_TVM, 1, GL_FALSE, TransposeViewMatrix.pointer()); glUniformMatrix4fv(uniform_invproj, 1, GL_FALSE, InvProj.pointer()); glUniform2f(uniform_screen, screen.X, screen.Y); } @@ -1456,6 +1459,7 @@ namespace FullScreenShader GLuint DiffuseEnvMapShader::uniform_blueLmn; GLuint DiffuseEnvMapShader::uniform_greenLmn; GLuint DiffuseEnvMapShader::uniform_redLmn; + GLuint DiffuseEnvMapShader::uniform_TVM; GLuint DiffuseEnvMapShader::vao; void DiffuseEnvMapShader::init() @@ -1465,11 +1469,13 @@ namespace FullScreenShader uniform_blueLmn = glGetUniformLocation(Program, "blueLmn[0]"); uniform_greenLmn = glGetUniformLocation(Program, "greenLmn[0]"); uniform_redLmn = glGetUniformLocation(Program, "redLmn[0]"); + uniform_TVM = glGetUniformLocation(Program, "TransposeViewMatrix"); vao = createVAO(Program); } - void DiffuseEnvMapShader::setUniforms(const float *blueSHCoeff, const float *greenSHCoeff, const float *redSHCoeff, unsigned TU_ntex) + void DiffuseEnvMapShader::setUniforms(const core::matrix4 &TransposeViewMatrix, const float *blueSHCoeff, const float *greenSHCoeff, const float *redSHCoeff, unsigned TU_ntex) { + glUniformMatrix4fv(uniform_TVM, 1, GL_FALSE, TransposeViewMatrix.pointer()); glUniform1i(uniform_ntex, TU_ntex); glUniform1fv(uniform_blueLmn, 9, blueSHCoeff); glUniform1fv(uniform_greenLmn, 9, greenSHCoeff); diff --git a/src/graphics/shaders.hpp b/src/graphics/shaders.hpp index 4015fdb3e..e68fd7e40 100644 --- a/src/graphics/shaders.hpp +++ b/src/graphics/shaders.hpp @@ -163,11 +163,11 @@ class SphereMapShader public: static GLuint Program; static GLuint attrib_position, attrib_normal; - static GLuint uniform_MVP, uniform_TIMV, uniform_invproj, uniform_screen; + static GLuint uniform_MVP, uniform_TIMV, uniform_TVM, uniform_invproj, uniform_screen; static GLuint TU_tex; static void init(); - static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &InvProj, const core::vector2df& screen); + static void setUniforms(const core::matrix4 &ModelViewProjectionMatrix, const core::matrix4 &TransposeViewMatrix, const core::matrix4 &TransposeInverseModelView, const core::matrix4 &InvProj, const core::vector2df& screen); }; class SplattingShader @@ -427,11 +427,11 @@ class DiffuseEnvMapShader { public: static GLuint Program; - static GLuint uniform_ntex, uniform_blueLmn, uniform_greenLmn, uniform_redLmn; + static GLuint uniform_ntex, uniform_TVM, uniform_blueLmn, uniform_greenLmn, uniform_redLmn; static GLuint vao; static void init(); - static void setUniforms(const float *blueSHCoeff, const float *greenSHCoeff, const float *redSHCoeff, unsigned TU_ntex); + static void setUniforms(const core::matrix4 &TransposeViewMatrix, const float *blueSHCoeff, const float *greenSHCoeff, const float *redSHCoeff, unsigned TU_ntex); }; class ShadowedSunLightShader diff --git a/src/graphics/stkmesh.cpp b/src/graphics/stkmesh.cpp index edcbfdc0c..98ac9d682 100644 --- a/src/graphics/stkmesh.cpp +++ b/src/graphics/stkmesh.cpp @@ -284,7 +284,7 @@ void drawSphereMap(const GLMesh &mesh, const core::matrix4 &ModelViewProjectionM glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } - MeshShader::SphereMapShader::setUniforms(ModelViewProjectionMatrix, TransposeInverseModelView, irr_driver->getInvProjMatrix(), core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height)); + MeshShader::SphereMapShader::setUniforms(ModelViewProjectionMatrix, irr_driver->getViewMatrix().getTransposed(), TransposeInverseModelView, irr_driver->getInvProjMatrix(), core::vector2df(UserConfigParams::m_width, UserConfigParams::m_height)); glBindVertexArray(mesh.vao_second_pass); glDrawElements(ptype, count, itype, 0); From 5e03e461bc4a899636f55f00d59550d54db09937 Mon Sep 17 00:00:00 2001 From: Vincent Lejeune Date: Fri, 14 Mar 2014 17:04:44 +0100 Subject: [PATCH 5/5] Revert to compatibility context for linux build. --- lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp index 4769a079c..4829cf72c 100644 --- a/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp +++ b/lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.cpp @@ -745,7 +745,7 @@ bool CIrrDeviceLinux::createWindow() { GLX_CONTEXT_MAJOR_VERSION_ARB, 3, GLX_CONTEXT_MINOR_VERSION_ARB, 3, -// GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, //GLX_CONTEXT_CORE_PROFILE_BIT_ARB + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, //GLX_CONTEXT_CORE_PROFILE_BIT_ARB GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB, None };