diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index fd87cac6c..fcd241006 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -148,6 +148,26 @@ namespace Nz ShaderFlags_Max = ShaderFlags_VertexColor * 2 - 1 }; + + enum TextureMap + { + TextureMap_Alpha, + TextureMap_Diffuse, + TextureMap_Emissive, + TextureMap_Height, + TextureMap_ReflectionCube, + TextureMap_Normal, + TextureMap_Overlay, + TextureMap_Shadow2D_1, + TextureMap_Shadow2D_2, + TextureMap_Shadow2D_3, + TextureMap_ShadowCube_1, + TextureMap_ShadowCube_2, + TextureMap_ShadowCube_3, + TextureMap_Specular, + + TextureMap_Max = TextureMap_Specular + }; } #endif // NAZARA_ENUMS_GRAPHICS_HPP diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 5d82c4bf9..0a35518fc 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -46,7 +46,7 @@ namespace Nz void DrawTransparentModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; const ShaderUniforms* GetShaderUniforms(const Shader* shader) const; void OnShaderInvalidated(const Shader* shader) const; - void SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset, UInt8 availableTextureUnit) const; + void SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int lightIndex, unsigned int uniformOffset) const; static float ComputeDirectionalLightScore(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light); static float ComputePointLightScore(const Spheref& object, const AbstractRenderQueue::PointLight& light); diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.inl b/include/Nazara/Graphics/ForwardRenderTechnique.inl index 07b735dac..c0d5b5f1b 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.inl +++ b/include/Nazara/Graphics/ForwardRenderTechnique.inl @@ -6,135 +6,6 @@ namespace Nz { - /*! - * \brief Sens the uniforms for light - * - * \param shader Shader to send uniforms to - * \param uniforms Uniforms to send - * \param index Index of the light - * \param uniformOffset Offset for the uniform - * \param availableTextureUnit Unit texture available - */ - - inline void ForwardRenderTechnique::SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset, UInt8 availableTextureUnit) const - { - // If anyone got a better idea.. - int dummyCubemap = Renderer::GetMaxTextureUnits() - 1; - int dummyTexture = Renderer::GetMaxTextureUnits() - 2; - - if (index < m_lights.size()) - { - const LightIndex& lightIndex = m_lights[index]; - - shader->SendInteger(uniforms.locations.type + uniformOffset, lightIndex.type); //< Sends the light type - - switch (lightIndex.type) - { - case LightType_Directional: - { - const auto& light = m_renderQueue.directionalLights[lightIndex.index]; - - shader->SendColor(uniforms.locations.color + uniformOffset, light.color); - shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); - shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.direction)); - - if (uniforms.locations.shadowMapping != -1) - shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); - - if (light.shadowMap) - { - Renderer::SetTexture(availableTextureUnit, light.shadowMap); - Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); - - if (uniforms.locations.lightViewProjMatrix != -1) - shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); - - if (uniforms.locations.directionalSpotLightShadowMap != -1) - shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit); - } - else if (uniforms.locations.directionalSpotLightShadowMap != -1) - shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); - - if (uniforms.locations.directionalSpotLightShadowMap != -1) - shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); - break; - } - - case LightType_Point: - { - const auto& light = m_renderQueue.pointLights[lightIndex.index]; - - shader->SendColor(uniforms.locations.color + uniformOffset, light.color); - shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); - shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.position, light.attenuation)); - shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(0.f, 0.f, 0.f, light.invRadius)); - - if (uniforms.locations.shadowMapping != -1) - shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); - - if (light.shadowMap) - { - Renderer::SetTexture(availableTextureUnit, light.shadowMap); - Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); - - if (uniforms.locations.pointLightShadowMap != -1) - shader->SendInteger(uniforms.locations.pointLightShadowMap + index, availableTextureUnit); - } - else if (uniforms.locations.pointLightShadowMap != -1) - shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); - - if (uniforms.locations.directionalSpotLightShadowMap != -1) - shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); - break; - } - - case LightType_Spot: - { - const auto& light = m_renderQueue.spotLights[lightIndex.index]; - - shader->SendColor(uniforms.locations.color + uniformOffset, light.color); - shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); - shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.position, light.attenuation)); - shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(light.direction, light.invRadius)); - shader->SendVector(uniforms.locations.parameters3 + uniformOffset, Vector2f(light.innerAngleCosine, light.outerAngleCosine)); - - if (uniforms.locations.shadowMapping != -1) - shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); - - if (light.shadowMap) - { - Renderer::SetTexture(availableTextureUnit, light.shadowMap); - Renderer::SetTextureSampler(availableTextureUnit, s_shadowSampler); - - if (uniforms.locations.lightViewProjMatrix != -1) - shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); - - if (uniforms.locations.directionalSpotLightShadowMap != -1) - shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, availableTextureUnit); - } - else if (uniforms.locations.directionalSpotLightShadowMap != -1) - shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); - - if (uniforms.locations.pointLightShadowMap != -1) - shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); - - break; - } - } - } - else - { - if (uniforms.locations.type != -1) - shader->SendInteger(uniforms.locations.type + uniformOffset, -1); //< Disable the light in the shader - - if (uniforms.locations.directionalSpotLightShadowMap != -1) - shader->SendInteger(uniforms.locations.directionalSpotLightShadowMap + index, dummyTexture); - - if (uniforms.locations.pointLightShadowMap != -1) - shader->SendInteger(uniforms.locations.pointLightShadowMap + index, dummyCubemap); - } - } - /*! * \brief Computes the score for directional light * \return 0.f diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index 071b748c3..3951be6ad 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -102,13 +102,11 @@ namespace Nz { int type; int color; - int directionalSpotLightShadowMap; int factors; int lightViewProjMatrix; int parameters1; int parameters2; int parameters3; - int pointLightShadowMap; int shadowMapping; }; diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index f7d15d6fe..be6e2c58b 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -64,7 +64,7 @@ namespace Nz inline Material(const Material& material); inline ~Material(); - void Apply(const MaterialPipeline::Instance& instance, UInt8 textureUnit = 0, UInt8* lastUsedUnit = nullptr) const; + void Apply(const MaterialPipeline::Instance& instance) const; void BuildFromParameters(const ParameterList& matData, const MaterialParams& matParams = MaterialParams()); @@ -174,6 +174,7 @@ namespace Nz inline Material& operator=(const Material& material); inline static MaterialRef GetDefault(); + inline static int GetTextureUnit(TextureMap textureMap); template static MaterialRef New(Args&&... args); // Signals: @@ -207,6 +208,7 @@ namespace Nz float m_alphaThreshold; float m_shininess; + static std::array s_textureUnits; static MaterialLibrary::LibraryMap s_library; static MaterialLoader::LoaderList s_loaders; static MaterialManager::ManagerMap s_managerMap; diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index cec965e6e..b0ce4ff1c 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -1356,6 +1356,11 @@ namespace Nz return s_defaultMaterial; } + inline int Material::GetTextureUnit(TextureMap textureMap) + { + return s_textureUnits[textureMap]; + } + inline void Material::InvalidatePipeline() { m_pipelineUpdated = false; diff --git a/src/Nazara/Graphics/DepthRenderTechnique.cpp b/src/Nazara/Graphics/DepthRenderTechnique.cpp index c153fd514..3f0d76379 100644 --- a/src/Nazara/Graphics/DepthRenderTechnique.cpp +++ b/src/Nazara/Graphics/DepthRenderTechnique.cpp @@ -249,13 +249,12 @@ namespace Nz if (matEntry.enabled) { - UInt8 overlayUnit; - material->Apply(pipelineInstance, 0, &overlayUnit); - overlayUnit++; + unsigned int overlayTextureUnit = Material::GetTextureUnit(TextureMap_Overlay); + material->Apply(pipelineInstance); - shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + shader->SendInteger(shaderUniforms->textureOverlay, overlayTextureUnit); - Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); + Renderer::SetTextureSampler(overlayTextureUnit, material->GetDiffuseSampler()); auto& overlayMap = matEntry.overlayMap; for (auto& overlayIt : overlayMap) @@ -266,7 +265,7 @@ namespace Nz std::size_t spriteChainCount = spriteChainVector.size(); if (spriteChainCount > 0) { - Renderer::SetTexture(overlayUnit, (overlay) ? overlay : &m_whiteTexture); + Renderer::SetTexture(overlayTextureUnit, (overlay) ? overlay : &m_whiteTexture); std::size_t spriteChain = 0; // Which chain of sprites are we treating std::size_t spriteChainOffset = 0; // Where was the last offset where we stopped in the last chain @@ -525,8 +524,7 @@ namespace Nz if (matEntry.enabled) { - UInt8 freeTextureUnit; - material->Apply(pipelineInstance, 0, &freeTextureUnit); + material->Apply(pipelineInstance); ForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 22961b157..2e8f3e12f 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -318,7 +318,7 @@ namespace Nz // Index of uniforms in the shader shaderUniforms = GetShaderUniforms(shader); - // Ambiant color of the scene + // Ambient color of the scene shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); // Position of the camera shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); @@ -333,13 +333,13 @@ namespace Nz if (matEntry.enabled) { - UInt8 overlayUnit; - material->Apply(pipelineInstance, 0, &overlayUnit); - overlayUnit++; + material->Apply(pipelineInstance); - shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + unsigned int overlayTextureUnit = Material::GetTextureUnit(TextureMap_Overlay); - Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); + shader->SendInteger(shaderUniforms->textureOverlay, overlayTextureUnit); + + Renderer::SetTextureSampler(overlayTextureUnit, material->GetDiffuseSampler()); auto& overlayMap = matEntry.overlayMap; for (auto& overlayIt : overlayMap) @@ -350,7 +350,7 @@ namespace Nz std::size_t spriteChainCount = spriteChainVector.size(); if (spriteChainCount > 0) { - Renderer::SetTexture(overlayUnit, (overlay) ? overlay : &m_whiteTexture); + Renderer::SetTexture(overlayTextureUnit, (overlay) ? overlay : &m_whiteTexture); std::size_t spriteChain = 0; // Which chain of sprites are we treating std::size_t spriteChainOffset = 0; // Where was the last offset where we stopped in the last chain @@ -616,8 +616,7 @@ namespace Nz if (matEntry.enabled) { - UInt8 freeTextureUnit; - material->Apply(pipelineInstance, 0, &freeTextureUnit); + material->Apply(pipelineInstance); ForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; @@ -688,8 +687,8 @@ namespace Nz } // Sends the uniforms - for (std::size_t i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset * i, freeTextureUnit + i); + for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) + SendLightUniforms(shader, shaderUniforms->lightUniforms, i, lightIndex++, shaderUniforms->lightOffset * i); } const Matrix4f* instanceMatrices = &instances[0]; @@ -747,8 +746,8 @@ namespace Nz } // Sends the light uniforms to the shader - for (std::size_t i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset*i, freeTextureUnit + i); + for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) + SendLightUniforms(shader, shaderUniforms->lightUniforms, i, lightIndex++, shaderUniforms->lightOffset*i); // And we draw drawFunc(meshData.primitiveMode, 0, indexCount); @@ -812,8 +811,7 @@ namespace Nz } // We begin to apply the material - UInt8 freeTextureUnit; - material->Apply(*pipelineInstance, 0, &freeTextureUnit); + material->Apply(*pipelineInstance); // Uniforms are conserved in our program, there's no point to send them back until they change const Shader* shader = pipelineInstance->uberInstance->GetShader(); @@ -833,7 +831,7 @@ namespace Nz lightCount = std::min(m_renderQueue.directionalLights.size(), static_cast(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS)); for (std::size_t i = 0; i < lightCount; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset * i, freeTextureUnit++); + SendLightUniforms(shader, shaderUniforms->lightUniforms, i, i, shaderUniforms->lightOffset * i); } lastShader = shader; @@ -872,7 +870,7 @@ namespace Nz ChooseLights(Spheref(position, radius), false); for (std::size_t i = lightCount; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset*i, freeTextureUnit++); + SendLightUniforms(shader, shaderUniforms->lightUniforms, i, i, shaderUniforms->lightOffset*i); } Renderer::SetMatrix(MatrixType_World, matrix); @@ -915,9 +913,7 @@ namespace Nz uniforms.lightUniforms.locations.parameters1 = shader->GetUniformLocation("Lights[0].parameters1"); uniforms.lightUniforms.locations.parameters2 = shader->GetUniformLocation("Lights[0].parameters2"); uniforms.lightUniforms.locations.parameters3 = shader->GetUniformLocation("Lights[0].parameters3"); - uniforms.lightUniforms.locations.pointLightShadowMap = shader->GetUniformLocation("PointLightShadowMap[0]"); uniforms.lightUniforms.locations.shadowMapping = shader->GetUniformLocation("Lights[0].shadowMapping"); - uniforms.lightUniforms.locations.directionalSpotLightShadowMap = shader->GetUniformLocation("DirectionalSpotLightShadowMap[0]"); } else uniforms.hasLightUniforms = false; @@ -939,6 +935,107 @@ namespace Nz m_shaderUniforms.erase(shader); } + /*! + * \brief Sends the uniforms for light + * + * \param shader Shader to send uniforms to + * \param uniforms Uniforms to send + * \param index Index of the light + * \param uniformOffset Offset for the uniform + * \param availableTextureUnit Unit texture available + */ + void ForwardRenderTechnique::SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int lightIndex, unsigned int uniformOffset) const + { + if (lightIndex < m_lights.size()) + { + const LightIndex& lightInfo = m_lights[lightIndex]; + + shader->SendInteger(uniforms.locations.type + uniformOffset, lightInfo.type); //< Sends the light type + + switch (lightInfo.type) + { + case LightType_Directional: + { + const auto& light = m_renderQueue.directionalLights[lightInfo.index]; + + shader->SendColor(uniforms.locations.color + uniformOffset, light.color); + shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); + shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.direction)); + + if (uniforms.locations.shadowMapping != -1) + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + + if (light.shadowMap) + { + unsigned int textureUnit2D = Material::GetTextureUnit(static_cast(TextureMap_Shadow2D_1 + index)); + + Renderer::SetTexture(textureUnit2D, light.shadowMap); + Renderer::SetTextureSampler(textureUnit2D, s_shadowSampler); + + if (uniforms.locations.lightViewProjMatrix != -1) + shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); + } + break; + } + + case LightType_Point: + { + const auto& light = m_renderQueue.pointLights[lightInfo.index]; + + shader->SendColor(uniforms.locations.color + uniformOffset, light.color); + shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); + shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.position, light.attenuation)); + shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(0.f, 0.f, 0.f, light.invRadius)); + + if (uniforms.locations.shadowMapping != -1) + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + + unsigned int textureUnit = Material::GetTextureUnit(static_cast(TextureMap_ShadowCube_1 + index)); + if (light.shadowMap) + { + unsigned int textureUnitCube = Material::GetTextureUnit(static_cast(TextureMap_ShadowCube_1 + index)); + + Renderer::SetTexture(textureUnitCube, light.shadowMap); + Renderer::SetTextureSampler(textureUnitCube, s_shadowSampler); + } + break; + } + + case LightType_Spot: + { + const auto& light = m_renderQueue.spotLights[lightInfo.index]; + + shader->SendColor(uniforms.locations.color + uniformOffset, light.color); + shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); + shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.position, light.attenuation)); + shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(light.direction, light.invRadius)); + shader->SendVector(uniforms.locations.parameters3 + uniformOffset, Vector2f(light.innerAngleCosine, light.outerAngleCosine)); + + if (uniforms.locations.shadowMapping != -1) + shader->SendBoolean(uniforms.locations.shadowMapping + uniformOffset, light.shadowMap != nullptr); + + unsigned int textureUnit = Material::GetTextureUnit(static_cast(TextureMap_Shadow2D_1 + index)); + if (light.shadowMap) + { + unsigned int textureUnit2D = Material::GetTextureUnit(static_cast(TextureMap_Shadow2D_1 + index)); + + Renderer::SetTexture(textureUnit2D, light.shadowMap); + Renderer::SetTextureSampler(textureUnit2D, s_shadowSampler); + + if (uniforms.locations.lightViewProjMatrix != -1) + shader->SendMatrix(uniforms.locations.lightViewProjMatrix + index, light.transformMatrix); + } + break; + } + } + } + else + { + if (uniforms.locations.type != -1) + shader->SendInteger(uniforms.locations.type + uniformOffset, -1); //< Disable the light in the shader + } + } + IndexBuffer ForwardRenderTechnique::s_quadIndexBuffer; TextureSampler ForwardRenderTechnique::s_shadowSampler; VertexBuffer ForwardRenderTechnique::s_quadVertexBuffer; diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index b81bd82b4..d833a601d 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -36,7 +36,7 @@ namespace Nz * \param textureUnit Unit for the texture GL_TEXTURE"i" * \param lastUsedUnit Optional argument to get the last texture unit */ - void Material::Apply(const MaterialPipeline::Instance& instance, UInt8 textureUnit, UInt8* lastUsedUnit) const + void Material::Apply(const MaterialPipeline::Instance& instance) const { const Shader* shader = instance.renderPipeline.GetInfo().shader; @@ -57,54 +57,51 @@ namespace Nz if (m_alphaMap && instance.uniforms[MaterialUniform_AlphaMap] != -1) { + unsigned int textureUnit = s_textureUnits[TextureMap_Alpha]; + Renderer::SetTexture(textureUnit, m_alphaMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - shader->SendInteger(instance.uniforms[MaterialUniform_AlphaMap], textureUnit); - textureUnit++; } if (m_diffuseMap && instance.uniforms[MaterialUniform_DiffuseMap] != -1) { + unsigned int textureUnit = s_textureUnits[TextureMap_Diffuse]; + Renderer::SetTexture(textureUnit, m_diffuseMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - shader->SendInteger(instance.uniforms[MaterialUniform_DiffuseMap], textureUnit); - textureUnit++; } if (m_emissiveMap && instance.uniforms[MaterialUniform_EmissiveMap] != -1) { + unsigned int textureUnit = s_textureUnits[TextureMap_Emissive]; + Renderer::SetTexture(textureUnit, m_emissiveMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - shader->SendInteger(instance.uniforms[MaterialUniform_EmissiveMap], textureUnit); - textureUnit++; } if (m_heightMap && instance.uniforms[MaterialUniform_HeightMap] != -1) { + unsigned int textureUnit = s_textureUnits[TextureMap_Height]; + Renderer::SetTexture(textureUnit, m_heightMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - shader->SendInteger(instance.uniforms[MaterialUniform_HeightMap], textureUnit); - textureUnit++; } if (m_normalMap && instance.uniforms[MaterialUniform_NormalMap] != -1) { + unsigned int textureUnit = s_textureUnits[TextureMap_Normal]; + Renderer::SetTexture(textureUnit, m_normalMap); Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); - shader->SendInteger(instance.uniforms[MaterialUniform_NormalMap], textureUnit); - textureUnit++; } if (m_specularMap && instance.uniforms[MaterialUniform_SpecularMap] != -1) { + unsigned int textureUnit = s_textureUnits[TextureMap_Specular]; + Renderer::SetTexture(textureUnit, m_specularMap); Renderer::SetTextureSampler(textureUnit, m_specularSampler); - shader->SendInteger(instance.uniforms[MaterialUniform_SpecularMap], textureUnit); - textureUnit++; } - - if (lastUsedUnit) - *lastUsedUnit = textureUnit; } /*! @@ -459,6 +456,23 @@ namespace Nz s_defaultMaterial->SetFaceFilling(FaceFilling_Line); MaterialLibrary::Register("Default", s_defaultMaterial); + unsigned int textureUnit = 0; + + s_textureUnits[TextureMap_Diffuse] = textureUnit++; + s_textureUnits[TextureMap_Alpha] = textureUnit++; + s_textureUnits[TextureMap_Specular] = textureUnit++; + s_textureUnits[TextureMap_Normal] = textureUnit++; + s_textureUnits[TextureMap_Emissive] = textureUnit++; + s_textureUnits[TextureMap_Overlay] = textureUnit++; + s_textureUnits[TextureMap_ReflectionCube] = textureUnit++; + s_textureUnits[TextureMap_Height] = textureUnit++; + s_textureUnits[TextureMap_Shadow2D_1] = textureUnit++; + s_textureUnits[TextureMap_ShadowCube_1] = textureUnit++; + s_textureUnits[TextureMap_Shadow2D_2] = textureUnit++; + s_textureUnits[TextureMap_ShadowCube_2] = textureUnit++; + s_textureUnits[TextureMap_Shadow2D_3] = textureUnit++; + s_textureUnits[TextureMap_ShadowCube_3] = textureUnit++; + return true; } @@ -473,6 +487,7 @@ namespace Nz MaterialLibrary::Uninitialize(); } + std::array Material::s_textureUnits; MaterialLibrary::LibraryMap Material::s_library; MaterialLoader::LoaderList Material::s_loaders; MaterialManager::ManagerMap Material::s_managerMap; diff --git a/src/Nazara/Graphics/MaterialPipeline.cpp b/src/Nazara/Graphics/MaterialPipeline.cpp index 07865c4cd..e8799fdd1 100644 --- a/src/Nazara/Graphics/MaterialPipeline.cpp +++ b/src/Nazara/Graphics/MaterialPipeline.cpp @@ -3,12 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include - -#ifndef NAZARA_RENDERER_OPENGL -#define NAZARA_RENDERER_OPENGL // Mandatory to include the OpenGL headers -#endif - -#include +#include #include #include @@ -106,6 +101,25 @@ namespace Nz CacheUniform(SpecularMap); #undef CacheUniform + + // Send texture units (those never changes) + renderPipelineInfo.shader->SendInteger(instance.uniforms[MaterialUniform_AlphaMap], Material::GetTextureUnit(TextureMap_Alpha)); + renderPipelineInfo.shader->SendInteger(instance.uniforms[MaterialUniform_DiffuseMap], Material::GetTextureUnit(TextureMap_Diffuse)); + renderPipelineInfo.shader->SendInteger(instance.uniforms[MaterialUniform_EmissiveMap], Material::GetTextureUnit(TextureMap_Emissive)); + renderPipelineInfo.shader->SendInteger(instance.uniforms[MaterialUniform_HeightMap], Material::GetTextureUnit(TextureMap_Height)); + renderPipelineInfo.shader->SendInteger(instance.uniforms[MaterialUniform_NormalMap], Material::GetTextureUnit(TextureMap_Normal)); + renderPipelineInfo.shader->SendInteger(instance.uniforms[MaterialUniform_SpecularMap], Material::GetTextureUnit(TextureMap_Specular)); + + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("ReflectionMap"), Material::GetTextureUnit(TextureMap_ReflectionCube)); + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("TextureOverlay"), Material::GetTextureUnit(TextureMap_Overlay)); + + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("DirectionalSpotLightShadowMap[0]"), Material::GetTextureUnit(TextureMap_Shadow2D_1)); + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("DirectionalSpotLightShadowMap[1]"), Material::GetTextureUnit(TextureMap_Shadow2D_2)); + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("DirectionalSpotLightShadowMap[2]"), Material::GetTextureUnit(TextureMap_Shadow2D_3)); + + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("PointLightShadowMap[0]"), Material::GetTextureUnit(TextureMap_ShadowCube_1)); + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("PointLightShadowMap[1]"), Material::GetTextureUnit(TextureMap_ShadowCube_2)); + renderPipelineInfo.shader->SendInteger(renderPipelineInfo.shader->GetUniformLocation("PointLightShadowMap[2]"), Material::GetTextureUnit(TextureMap_ShadowCube_3)); } bool MaterialPipeline::Initialize() @@ -178,4 +192,4 @@ namespace Nz MaterialPipelineLibrary::LibraryMap MaterialPipeline::s_library; MaterialPipeline::PipelineCache MaterialPipeline::s_pipelineCache; -} \ No newline at end of file +}