From 347b267d4380881ce0c6fb3d521da9b675acbfca Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 1 Mar 2013 21:54:41 +0100 Subject: [PATCH] Added shader flags Renamed ShaderBuilder enum to ShaderFlags Former-commit-id: b3440bac5491f0a0a90cbd7f9ed8e396c16c0864 --- include/Nazara/Renderer/Config.hpp | 3 + include/Nazara/Renderer/Enums.hpp | 20 +++--- include/Nazara/Renderer/Material.hpp | 15 ++--- include/Nazara/Renderer/Renderer.hpp | 3 +- include/Nazara/Renderer/Shader.hpp | 4 ++ src/Nazara/Renderer/Shader.cpp | 10 +++ src/Nazara/Renderer/ShaderBuilder.cpp | 87 +++++++++++++++------------ 7 files changed, 84 insertions(+), 58 deletions(-) diff --git a/include/Nazara/Renderer/Config.hpp b/include/Nazara/Renderer/Config.hpp index dab42a297..a1d897b9c 100644 --- a/include/Nazara/Renderer/Config.hpp +++ b/include/Nazara/Renderer/Config.hpp @@ -29,6 +29,9 @@ /// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci +// Le nombre maximum d'instances pouvant être géré par le Renderer +#define NAZARA_RENDERER_INSTANCING_MAX 8192 + // Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution) #define NAZARA_RENDERER_MEMORYLEAKTRACKER 0 diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index af6cedfcc..2468da0f2 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -73,6 +73,7 @@ enum nzRendererCap nzRendererCap_AnisotropicFilter, nzRendererCap_FP64, nzRendererCap_HardwareBuffer, + nzRendererCap_Instancing, nzRendererCap_MultipleRenderTargets, nzRendererCap_OcclusionQuery, nzRendererCap_PixelBufferObject, @@ -143,17 +144,18 @@ enum nzSamplerWrap nzSamplerWrap_Max = nzSamplerWrap_Repeat }; -enum nzShaderBuilderFlags +enum nzShaderFlags { - nzShaderBuilder_None = 0, + nzShaderFlags_None = 0, - nzShaderBuilder_Deferred = 0x01, - nzShaderBuilder_DiffuseMapping = 0x02, - nzShaderBuilder_Instancing = 0x04, - nzShaderBuilder_Lighting = 0x08, - nzShaderBuilder_NormalMapping = 0x10, - nzShaderBuilder_ParallaxMapping = 0x20, - nzShaderBuilder_SpecularMapping = 0x40 + nzShaderFlags_Deferred = 0x01, + nzShaderFlags_DiffuseMapping = 0x02, + nzShaderFlags_FlipUVs = 0x04, + nzShaderFlags_Instancing = 0x08, + nzShaderFlags_Lighting = 0x10, + nzShaderFlags_NormalMapping = 0x20, + nzShaderFlags_ParallaxMapping = 0x40, + nzShaderFlags_SpecularMapping = 0x80 }; enum nzShaderLanguage diff --git a/include/Nazara/Renderer/Material.hpp b/include/Nazara/Renderer/Material.hpp index 10a544e38..04186c8da 100644 --- a/include/Nazara/Renderer/Material.hpp +++ b/include/Nazara/Renderer/Material.hpp @@ -37,7 +37,7 @@ class NAZARA_API NzMaterial : public NzResource NzMaterial(NzMaterial&& material); ~NzMaterial(); - void Apply() const; + void Apply(const NzShader* shader) const; void EnableAlphaBlending(bool alphaBlending); void EnableFaceCulling(bool faceCulling); @@ -46,6 +46,7 @@ class NAZARA_API NzMaterial : public NzResource void EnableZWrite(bool zWrite); NzColor GetAmbientColor() const; + const NzShader* GetCustomShader() const; NzColor GetDiffuseColor() const; NzTexture* GetDiffuseMap() const; NzTextureSampler& GetDiffuseSampler(); @@ -55,7 +56,7 @@ class NAZARA_API NzMaterial : public NzResource nzFaceFilling GetFaceFilling() const; NzTexture* GetHeightMap() const; NzTexture* GetNormalMap() const; - const NzShader* GetShader() const; + nzUInt32 GetShaderFlags() const; float GetShininess() const; NzColor GetSpecularColor() const; NzTexture* GetSpecularMap() const; @@ -64,6 +65,8 @@ class NAZARA_API NzMaterial : public NzResource nzBlendFunc GetSrcBlend() const; nzRendererComparison GetZTestCompare() const; + bool HasCustomShader() const; + bool IsAlphaBlendingEnabled() const; bool IsFaceCullingEnabled() const; bool IsLightingEnabled() const; @@ -85,7 +88,7 @@ class NAZARA_API NzMaterial : public NzResource void SetFaceFilling(nzFaceFilling filling); void SetHeightMap(NzTexture* map); void SetNormalMap(NzTexture* map); - void SetShader(const NzShader* shader); + void SetCustomShader(const NzShader* shader); void SetShininess(float shininess); void SetSpecularColor(const NzColor& specular); void SetSpecularMap(NzTexture* map); @@ -99,25 +102,23 @@ class NAZARA_API NzMaterial : public NzResource static NzMaterial* GetDefault(); private: - void UpdateShader() const; - nzBlendFunc m_dstBlend; nzBlendFunc m_srcBlend; nzFaceCulling m_faceCulling; nzFaceFilling m_faceFilling; nzRendererComparison m_zTestCompareFunc; + nzUInt32 m_shaderFlags; NzColor m_ambientColor; NzColor m_diffuseColor; NzColor m_specularColor; NzTextureSampler m_diffuseSampler; NzTextureSampler m_specularSampler; - mutable const NzShader* m_shader; + mutable const NzShader* m_customShader; NzTexture* m_diffuseMap; NzTexture* m_heightMap; NzTexture* m_normalMap; NzTexture* m_specularMap; bool m_alphaBlendingEnabled; - bool m_autoShader; bool m_faceCullingEnabled; bool m_lightingEnabled; bool m_zTestEnabled; diff --git a/include/Nazara/Renderer/Renderer.hpp b/include/Nazara/Renderer/Renderer.hpp index 9be165780..34e1135ab 100644 --- a/include/Nazara/Renderer/Renderer.hpp +++ b/include/Nazara/Renderer/Renderer.hpp @@ -22,7 +22,6 @@ class NzMaterial; class NzRenderTarget; class NzShader; class NzVertexBuffer; -class NzVertexDeclaration; class NAZARA_API NzRenderer { @@ -94,7 +93,7 @@ class NAZARA_API NzRenderer static void Uninitialize(); private: - static bool EnsureStateUpdate(); + static bool EnsureStateUpdate(bool instancing); static unsigned int s_moduleReferenceCounter; }; diff --git a/include/Nazara/Renderer/Shader.hpp b/include/Nazara/Renderer/Shader.hpp index 040d5bbf7..e7339ca9a 100644 --- a/include/Nazara/Renderer/Shader.hpp +++ b/include/Nazara/Renderer/Shader.hpp @@ -36,6 +36,7 @@ class NAZARA_API NzShader : public NzResource, NzNonCopyable void Destroy(); + nzUInt32 GetFlags() const; NzString GetLog() const; nzShaderLanguage GetLanguage() const; NzString GetSourceCode(nzShaderType type) const; @@ -67,6 +68,8 @@ class NAZARA_API NzShader : public NzResource, NzNonCopyable bool SendVector(int location, const NzVector4d& vector) const; bool SendVector(int location, const NzVector4f& vector) const; + void SetFlags(nzUInt32 flags); + void Unlock(); NzShader& operator=(NzShader&& shader); @@ -75,6 +78,7 @@ class NAZARA_API NzShader : public NzResource, NzNonCopyable static bool IsTypeSupported(nzShaderType type); private: + nzUInt32 m_flags = nzShaderFlags_None; NzShaderImpl* m_impl = nullptr; bool m_compiled = false; }; diff --git a/src/Nazara/Renderer/Shader.cpp b/src/Nazara/Renderer/Shader.cpp index c4779daea..dbd911093 100644 --- a/src/Nazara/Renderer/Shader.cpp +++ b/src/Nazara/Renderer/Shader.cpp @@ -93,6 +93,11 @@ void NzShader::Destroy() } } +nzUInt32 NzShader::GetFlags() const +{ + return m_flags; +} + NzString NzShader::GetLog() const { #if NAZARA_RENDERER_SAFE @@ -602,6 +607,11 @@ bool NzShader::SendVector(int location, const NzVector4f& vector) const return m_impl->SendVector(location, vector); } +void NzShader::SetFlags(nzUInt32 flags) +{ + m_flags = flags; +} + void NzShader::Unlock() { #if NAZARA_RENDERER_SAFE diff --git a/src/Nazara/Renderer/ShaderBuilder.cpp b/src/Nazara/Renderer/ShaderBuilder.cpp index 1b6c1587f..4c396da0f 100644 --- a/src/Nazara/Renderer/ShaderBuilder.cpp +++ b/src/Nazara/Renderer/ShaderBuilder.cpp @@ -35,7 +35,7 @@ namespace sourceCode += '\n'; - if (flags & nzShaderBuilder_Lighting) + if (flags & nzShaderFlags_Lighting) { sourceCode += "#define LIGHT_DIRECTIONAL 0\n" "#define LIGHT_POINT 1\n" @@ -47,7 +47,7 @@ namespace sourceCode += '\n'; /********************Uniformes********************/ - if (flags & nzShaderBuilder_Lighting) + if (flags & nzShaderFlags_Lighting) { sourceCode += "struct Light\n" "{\n" @@ -63,7 +63,7 @@ namespace "\n"; } - if (flags & nzShaderBuilder_Lighting) + if (flags & nzShaderFlags_Lighting) { sourceCode += "uniform vec3 CameraPosition;\n" "uniform int LightCount;\n" @@ -71,21 +71,21 @@ namespace "uniform vec4 MaterialAmbient;\n"; } - if ((flags & nzShaderBuilder_DiffuseMapping) == 0 || flags & nzShaderBuilder_Lighting) + if ((flags & nzShaderFlags_DiffuseMapping) == 0 || flags & nzShaderFlags_Lighting) sourceCode += "uniform vec4 MaterialDiffuse;\n"; - if (flags & nzShaderBuilder_DiffuseMapping) + if (flags & nzShaderFlags_DiffuseMapping) sourceCode += "uniform sampler2D MaterialDiffuseMap;\n"; - if (flags & nzShaderBuilder_Lighting) + if (flags & nzShaderFlags_Lighting) { - if (flags & nzShaderBuilder_NormalMapping) + if (flags & nzShaderFlags_NormalMapping) sourceCode += "uniform sampler2D MaterialNormalMap;\n"; sourceCode += "uniform float MaterialShininess;\n" "uniform vec4 MaterialSpecular;\n"; - if (flags & nzShaderBuilder_SpecularMapping) + if (flags & nzShaderFlags_SpecularMapping) sourceCode += "uniform sampler2D MaterialSpecularMap;\n"; sourceCode += "uniform vec4 SceneAmbient;\n"; @@ -94,18 +94,18 @@ namespace sourceCode += '\n'; /********************Entrant********************/ - if (flags & nzShaderBuilder_Lighting) + if (flags & nzShaderFlags_Lighting) { - if (flags & nzShaderBuilder_NormalMapping) + if (flags & nzShaderFlags_NormalMapping) sourceCode += inKW + " mat3 vLightToWorld;\n"; else sourceCode += inKW + " vec3 vNormal;\n"; } - if (flags & nzShaderBuilder_DiffuseMapping || flags & nzShaderBuilder_NormalMapping) + if (flags & nzShaderFlags_DiffuseMapping || flags & nzShaderFlags_NormalMapping) sourceCode += inKW + " vec2 vTexCoord;\n"; - if (flags & nzShaderBuilder_Lighting) + if (flags & nzShaderFlags_Lighting) sourceCode += inKW + " vec3 vWorldPos;\n"; sourceCode += '\n'; @@ -120,14 +120,14 @@ namespace sourceCode += "void main()\n" "{\n"; - if (flags & nzShaderBuilder_Lighting) + if (flags & nzShaderFlags_Lighting) { sourceCode += "vec3 light = vec3(0.0, 0.0, 0.0);\n"; - if (flags & nzShaderBuilder_SpecularMapping) + if (flags & nzShaderFlags_SpecularMapping) sourceCode += "vec3 si = vec3(0.0, 0.0, 0.0);\n"; - if (flags & nzShaderBuilder_NormalMapping) + if (flags & nzShaderFlags_NormalMapping) sourceCode += "vec3 normal = normalize(vLightToWorld * (2.0 * vec3(texture2D(MaterialNormalMap, vTexCoord)) - 1.0));\n"; else sourceCode += "vec3 normal = normalize(vNormal);\n"; @@ -160,7 +160,7 @@ namespace "\n" "float specular = pow(max(dot(reflection, eyeVec), 0.0), MaterialShininess);\n"; - if (flags & nzShaderBuilder_SpecularMapping) + if (flags & nzShaderFlags_SpecularMapping) sourceCode += "si"; else sourceCode += "light"; @@ -197,7 +197,7 @@ namespace "\n" "float specular = pow(max(dot(reflection, eyeVec), 0.0), MaterialShininess);\n"; - if (flags & nzShaderBuilder_SpecularMapping) + if (flags & nzShaderFlags_SpecularMapping) sourceCode += "si"; else sourceCode += "light"; @@ -241,7 +241,7 @@ namespace "\n" "float specular = pow(max(dot(reflection, eyeVec), 0.0), MaterialShininess);\n"; - if (flags & nzShaderBuilder_SpecularMapping) + if (flags & nzShaderFlags_SpecularMapping) sourceCode += "si"; else sourceCode += "light"; @@ -265,15 +265,15 @@ namespace sourceCode += fragmentColorKW + " = vec4(light, MaterialDiffuse.a)"; - if (flags & nzShaderBuilder_DiffuseMapping) + if (flags & nzShaderFlags_DiffuseMapping) sourceCode += "*texture2D(MaterialDiffuseMap, vTexCoord)"; - if (flags & nzShaderBuilder_SpecularMapping) + if (flags & nzShaderFlags_SpecularMapping) sourceCode += " + vec4(si, MaterialDiffuse.a)*texture2D(MaterialSpecularMap, vTexCoord)"; // Utiliser l'alpha de MaterialSpecular n'aurait aucun sens sourceCode += ";\n"; } - else if (flags & nzShaderBuilder_DiffuseMapping) + else if (flags & nzShaderFlags_DiffuseMapping) sourceCode += fragmentColorKW + " = texture2D(MaterialDiffuseMap, vTexCoord);\n"; else sourceCode += fragmentColorKW + " = MaterialDiffuse;\n"; @@ -303,11 +303,11 @@ namespace sourceCode += '\n'; /********************Uniformes********************/ - if (flags & nzShaderBuilder_Instancing) + if (flags & nzShaderFlags_Instancing) sourceCode += "uniform mat4 ViewProjMatrix;\n"; else { - if (flags & nzShaderBuilder_Lighting) + if (flags & nzShaderFlags_Lighting) sourceCode += "uniform mat4 WorldMatrix;\n"; sourceCode += "uniform mat4 WorldViewProjMatrix;\n"; @@ -316,35 +316,35 @@ namespace sourceCode += '\n'; /********************Entrant********************/ - if (flags & nzShaderBuilder_Instancing) + if (flags & nzShaderFlags_Instancing) sourceCode += inKW + " mat4 InstanceMatrix;\n"; sourceCode += inKW + " vec3 VertexPosition;\n"; - if (flags & nzShaderBuilder_Lighting) + if (flags & nzShaderFlags_Lighting) { sourceCode += inKW + " vec3 VertexNormal;\n"; sourceCode += inKW + " vec3 VertexTangent;\n"; } - if (flags & nzShaderBuilder_DiffuseMapping) + if (flags & nzShaderFlags_DiffuseMapping) sourceCode += inKW + " vec2 VertexTexCoord0;\n"; sourceCode += '\n'; /********************Sortant********************/ - if (flags & nzShaderBuilder_Lighting) + if (flags & nzShaderFlags_Lighting) { - if (flags & nzShaderBuilder_NormalMapping) + if (flags & nzShaderFlags_NormalMapping) sourceCode += outKW + " mat3 vLightToWorld;\n"; else sourceCode += outKW + " vec3 vNormal;\n"; } - if (flags & nzShaderBuilder_DiffuseMapping || flags & nzShaderBuilder_NormalMapping) + if (flags & nzShaderFlags_DiffuseMapping || flags & nzShaderFlags_NormalMapping) sourceCode += outKW + " vec2 vTexCoord;\n"; - if (flags & nzShaderBuilder_Lighting) + if (flags & nzShaderFlags_Lighting) sourceCode += outKW + " vec3 vWorldPos;\n"; sourceCode += '\n'; @@ -353,19 +353,19 @@ namespace sourceCode += "void main()\n" "{\n"; - if (flags & nzShaderBuilder_Instancing) - sourceCode += "gl_Position = InstanceMatrix * ViewProjMatrix * vec4(VertexPosition, 1.0);\n"; + if (flags & nzShaderFlags_Instancing) + sourceCode += "gl_Position = ViewProjMatrix * InstanceMatrix * vec4(VertexPosition, 1.0);\n"; else sourceCode += "gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0);\n"; - if (flags & nzShaderBuilder_Lighting) + if (flags & nzShaderFlags_Lighting) { - if (flags & nzShaderBuilder_Instancing) + if (flags & nzShaderFlags_Instancing) sourceCode += "mat3 rotationMatrix = mat3(InstanceMatrix);\n"; else sourceCode += "mat3 rotationMatrix = mat3(WorldMatrix);\n"; - if (flags & nzShaderBuilder_NormalMapping) + if (flags & nzShaderFlags_NormalMapping) { sourceCode += "\n" "vec3 binormal = cross(VertexNormal, VertexTangent);\n" @@ -378,12 +378,17 @@ namespace sourceCode += "vNormal = normalize(rotationMatrix * VertexNormal);\n"; } - if (flags & nzShaderBuilder_DiffuseMapping || flags & nzShaderBuilder_NormalMapping) - sourceCode += "vTexCoord = VertexTexCoord0;\n"; - - if (flags & nzShaderBuilder_Lighting) + if (flags & nzShaderFlags_DiffuseMapping || flags & nzShaderFlags_NormalMapping || flags & nzShaderFlags_SpecularMapping) { - if (flags & nzShaderBuilder_Instancing) + if (flags & nzShaderFlags_FlipUVs) + sourceCode += "vTexCoord = vec2(VertexTexCoord0.x, 1.0 - VertexTexCoord0.y);\n"; + else + sourceCode += "vTexCoord = VertexTexCoord0;\n"; + } + + if (flags & nzShaderFlags_Lighting) + { + if (flags & nzShaderFlags_Instancing) sourceCode += "vWorldPos = vec3(InstanceMatrix * vec4(VertexPosition, 1.0));\n"; else sourceCode += "vWorldPos = vec3(WorldMatrix * vec4(VertexPosition, 1.0));\n"; @@ -434,6 +439,8 @@ namespace return nullptr; } + shader->SetFlags(flags); + return shader.release(); } }