Graphics/Shader: Make texture units statics
Provides better performances and prevents the sampler type bug to happen
This commit is contained in:
parent
1a8805aad1
commit
682dab32b3
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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<typename... Args> static MaterialRef New(Args&&... args);
|
||||
|
||||
// Signals:
|
||||
|
|
@ -207,6 +208,7 @@ namespace Nz
|
|||
float m_alphaThreshold;
|
||||
float m_shininess;
|
||||
|
||||
static std::array<int, TextureMap_Max + 1> s_textureUnits;
|
||||
static MaterialLibrary::LibraryMap s_library;
|
||||
static MaterialLoader::LoaderList s_loaders;
|
||||
static MaterialManager::ManagerMap s_managerMap;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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<decltype(m_renderQueue.directionalLights.size())>(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>(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>(TextureMap_ShadowCube_1 + index));
|
||||
if (light.shadowMap)
|
||||
{
|
||||
unsigned int textureUnitCube = Material::GetTextureUnit(static_cast<TextureMap>(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>(TextureMap_Shadow2D_1 + index));
|
||||
if (light.shadowMap)
|
||||
{
|
||||
unsigned int textureUnit2D = Material::GetTextureUnit(static_cast<TextureMap>(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;
|
||||
|
|
|
|||
|
|
@ -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<int, TextureMap_Max + 1> Material::s_textureUnits;
|
||||
MaterialLibrary::LibraryMap Material::s_library;
|
||||
MaterialLoader::LoaderList Material::s_loaders;
|
||||
MaterialManager::ManagerMap Material::s_managerMap;
|
||||
|
|
|
|||
|
|
@ -3,12 +3,7 @@
|
|||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/MaterialPipeline.hpp>
|
||||
|
||||
#ifndef NAZARA_RENDERER_OPENGL
|
||||
#define NAZARA_RENDERER_OPENGL // Mandatory to include the OpenGL headers
|
||||
#endif
|
||||
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Graphics/Material.hpp>
|
||||
#include <Nazara/Renderer/UberShaderPreprocessor.hpp>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue