From cf6e2be0b04a1ef22c97a74fbcdddad9b4442a76 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 24 May 2013 20:12:40 +0200 Subject: [PATCH 1/4] Renamed PrimitiveType to PrimitiveMode Also renamed RENDERER_INSTANCING_MAX to RENDERER_MAX_INSTANCES Added RENDERER_SHADER_MAX_LIGHTCOUNT Former-commit-id: bc26e087dd1b55c424836e6e2fa6e1dc0f17effa --- include/Nazara/Renderer/Config.hpp | 5 +- include/Nazara/Renderer/OpenGL.hpp | 2 +- include/Nazara/Renderer/Renderer.hpp | 8 ++-- include/Nazara/Utility/Enums.hpp | 16 +++---- include/Nazara/Utility/SubMesh.hpp | 6 +-- include/Nazara/Utility/TriangleIterator.hpp | 2 +- src/Nazara/Graphics/Loaders/OBJ/Loader.cpp | 2 +- src/Nazara/Graphics/SkyboxBackground.cpp | 2 +- src/Nazara/Renderer/DebugDrawer.cpp | 10 ++-- src/Nazara/Renderer/OpenGL.cpp | 14 +++--- src/Nazara/Renderer/Renderer.cpp | 52 ++++++++++----------- src/Nazara/Renderer/ShaderBuilder.cpp | 3 +- src/Nazara/Utility/SubMesh.cpp | 26 +++++------ src/Nazara/Utility/TriangleIterator.cpp | 10 ++-- 14 files changed, 80 insertions(+), 78 deletions(-) diff --git a/include/Nazara/Renderer/Config.hpp b/include/Nazara/Renderer/Config.hpp index a83c0bbe6..a300a3691 100644 --- a/include/Nazara/Renderer/Config.hpp +++ b/include/Nazara/Renderer/Config.hpp @@ -30,7 +30,7 @@ /// 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 +#define NAZARA_RENDERER_MAX_INSTANCES 8192 // Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution) #define NAZARA_RENDERER_MEMORYLEAKTRACKER 0 @@ -41,4 +41,7 @@ // Active les tests de sécurité basés sur le code (Conseillé pour le développement) #define NAZARA_RENDERER_SAFE 1 +// Le nombre maximum de lumières qu'un forward shader supportera +#define NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT 8 + #endif // NAZARA_CONFIG_MODULENAME_HPP diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index 16fab954c..b84617fbe 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -107,7 +107,7 @@ class NAZARA_API NzOpenGL static GLenum ElementType[nzElementType_Max+1]; static GLenum FaceCulling[nzFaceCulling_Max+1]; static GLenum FaceFilling[nzFaceFilling_Max+1]; - static GLenum PrimitiveType[nzPrimitiveType_Max+1]; + static GLenum PrimitiveMode[nzPrimitiveMode_Max+1]; static GLenum RendererComparison[nzRendererComparison_Max+1]; static GLenum RendererParameter[nzRendererParameter_Max+1]; static GLenum SamplerWrapMode[nzSamplerWrap_Max+1]; diff --git a/include/Nazara/Renderer/Renderer.hpp b/include/Nazara/Renderer/Renderer.hpp index 2fc4b0314..fee2806a7 100644 --- a/include/Nazara/Renderer/Renderer.hpp +++ b/include/Nazara/Renderer/Renderer.hpp @@ -36,10 +36,10 @@ class NAZARA_API NzRenderer static void Clear(unsigned long flags = nzRendererClear_Color | nzRendererClear_Depth); - static void DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int firstIndex, unsigned int indexCount); - static void DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveType primitive, unsigned int firstIndex, unsigned int indexCount); - static void DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount); - static void DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount); + static void DrawIndexedPrimitives(nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount); + static void DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount); + static void DrawPrimitives(nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount); + static void DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount); NAZARA_DEPRECATED("Don't use this or you will have cancer") static void DrawTexture(unsigned int unit, const NzRectf& rect, const NzVector2f& uv0, const NzVector2f& uv1, float z = 0.f); static void Enable(nzRendererParameter parameter, bool enable); diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index 2933407cc..1fb7a8ba9 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -205,16 +205,16 @@ enum nzPixelFlipping nzPixelFlipping_Max = nzPixelFlipping_Vertically }; -enum nzPrimitiveType +enum nzPrimitiveMode { - nzPrimitiveType_LineList, - nzPrimitiveType_LineStrip, - nzPrimitiveType_PointList, - nzPrimitiveType_TriangleList, - nzPrimitiveType_TriangleStrip, - nzPrimitiveType_TriangleFan, + nzPrimitiveMode_LineList, + nzPrimitiveMode_LineStrip, + nzPrimitiveMode_PointList, + nzPrimitiveMode_TriangleList, + nzPrimitiveMode_TriangleStrip, + nzPrimitiveMode_TriangleFan, - nzPrimitiveType_Max = nzPrimitiveType_TriangleFan + nzPrimitiveMode_Max = nzPrimitiveMode_TriangleFan }; enum nzWindowCursor diff --git a/include/Nazara/Utility/SubMesh.hpp b/include/Nazara/Utility/SubMesh.hpp index b43290a3e..3f2b709f0 100644 --- a/include/Nazara/Utility/SubMesh.hpp +++ b/include/Nazara/Utility/SubMesh.hpp @@ -39,17 +39,17 @@ class NAZARA_API NzSubMesh : public NzResource virtual const NzIndexBuffer* GetIndexBuffer() const = 0; unsigned int GetMaterialIndex() const; const NzMesh* GetParent() const; - nzPrimitiveType GetPrimitiveType() const; + nzPrimitiveMode GetPrimitiveMode() const; unsigned int GetTriangleCount() const; virtual unsigned int GetVertexCount() const = 0; virtual bool IsAnimated() const = 0; void SetMaterialIndex(unsigned int matIndex); - void SetPrimitiveType(nzPrimitiveType primitiveType); + void SetPrimitiveMode(nzPrimitiveMode mode); protected: - nzPrimitiveType m_primitiveType; + nzPrimitiveMode m_primitiveMode; const NzMesh* m_parent; unsigned int m_matIndex; }; diff --git a/include/Nazara/Utility/TriangleIterator.hpp b/include/Nazara/Utility/TriangleIterator.hpp index e6739102e..c65f88a1a 100644 --- a/include/Nazara/Utility/TriangleIterator.hpp +++ b/include/Nazara/Utility/TriangleIterator.hpp @@ -37,7 +37,7 @@ class NAZARA_API NzTriangleIterator void Unmap(); private: - nzPrimitiveType m_primitiveType; + nzPrimitiveMode m_primitiveMode; nzUInt32 m_triangleIndices[3]; NzIndexMapper m_indexMapper; NzVertexMapper m_vertexMapper; diff --git a/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp b/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp index ab81c0b8d..ae39ebb1d 100644 --- a/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp +++ b/src/Nazara/Graphics/Loaders/OBJ/Loader.cpp @@ -160,7 +160,7 @@ namespace subMesh->GenerateAABB(); subMesh->SetMaterialIndex(meshes[i].material); - subMesh->SetPrimitiveType(nzPrimitiveType_TriangleList); + subMesh->SetPrimitiveMode(nzPrimitiveMode_TriangleList); if (hasNormals && hasTexCoords) subMesh->GenerateTangents(); diff --git a/src/Nazara/Graphics/SkyboxBackground.cpp b/src/Nazara/Graphics/SkyboxBackground.cpp index 6a5fc81af..a92802efd 100644 --- a/src/Nazara/Graphics/SkyboxBackground.cpp +++ b/src/Nazara/Graphics/SkyboxBackground.cpp @@ -224,7 +224,7 @@ void NzSkyboxBackground::Draw(const NzScene* scene) const NzRenderer::SetTextureSampler(textureUnit, m_sampler); NzRenderer::SetVertexBuffer(m_vertexBuffer); - NzRenderer::DrawIndexedPrimitives(nzPrimitiveType_TriangleList, 0, 36); + NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, 36); NzRenderer::SetMatrix(nzMatrixType_View, viewMatrix); } diff --git a/src/Nazara/Renderer/DebugDrawer.cpp b/src/Nazara/Renderer/DebugDrawer.cpp index c63316ea3..8aace853a 100644 --- a/src/Nazara/Renderer/DebugDrawer.cpp +++ b/src/Nazara/Renderer/DebugDrawer.cpp @@ -135,7 +135,7 @@ void NzDebugDrawer::Draw(const NzCubef& cube) shader->SendColor(colorLocation, primaryColor); - NzRenderer::DrawPrimitives(nzPrimitiveType_LineList, 0, 24); + NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, 24); } void NzDebugDrawer::Draw(const NzCubeui& cube) @@ -223,7 +223,7 @@ void NzDebugDrawer::Draw(const NzFrustumf& frustum) shader->SendColor(colorLocation, primaryColor); - NzRenderer::DrawPrimitives(nzPrimitiveType_LineList, 0, 24); + NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, 24); } void NzDebugDrawer::Draw(const NzOrientedCubef& orientedCube) @@ -306,7 +306,7 @@ void NzDebugDrawer::Draw(const NzOrientedCubef& orientedCube) shader->SendColor(colorLocation, primaryColor); - NzRenderer::DrawPrimitives(nzPrimitiveType_LineList, 0, 24); + NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, 24); } void NzDebugDrawer::Draw(const NzSkeleton* skeleton) @@ -355,10 +355,10 @@ void NzDebugDrawer::Draw(const NzSkeleton* skeleton) NzRenderer::SetVertexBuffer(vertexBuffer); shader->SendColor(colorLocation, primaryColor); - NzRenderer::DrawPrimitives(nzPrimitiveType_LineList, 0, vertexCount); + NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, vertexCount); shader->SendColor(colorLocation, secondaryColor); - NzRenderer::DrawPrimitives(nzPrimitiveType_PointList, 0, vertexCount); + NzRenderer::DrawPrimitives(nzPrimitiveMode_PointList, 0, vertexCount); } } /* diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index b7a7c886d..f4007de9f 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -1010,14 +1010,14 @@ GLenum NzOpenGL::FaceFilling[nzFaceFilling_Max+1] = GL_FILL // nzFaceFilling_Fill }; -GLenum NzOpenGL::PrimitiveType[nzPrimitiveType_Max+1] = +GLenum NzOpenGL::PrimitiveMode[nzPrimitiveMode_Max+1] = { - GL_LINES, // nzPrimitiveType_LineList, - GL_LINE_STRIP, // nzPrimitiveType_LineStrip, - GL_POINTS, // nzPrimitiveType_PointList, - GL_TRIANGLES, // nzPrimitiveType_TriangleList, - GL_TRIANGLE_STRIP, // nzPrimitiveType_TriangleStrip, - GL_TRIANGLE_FAN // nzPrimitiveType_TriangleFan + GL_LINES, // nzPrimitiveMode_LineList + GL_LINE_STRIP, // nzPrimitiveMode_LineStrip + GL_POINTS, // nzPrimitiveMode_PointList + GL_TRIANGLES, // nzPrimitiveMode_TriangleList + GL_TRIANGLE_STRIP, // nzPrimitiveMode_TriangleStrip + GL_TRIANGLE_FAN // nzPrimitiveMode_TriangleFan }; GLenum NzOpenGL::RendererComparison[nzRendererComparison_Max+1] = diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 508e03526..28dbc6e98 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -133,7 +133,7 @@ void NzRenderer::Clear(unsigned long flags) } } -void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int firstIndex, unsigned int indexCount) +void NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount) { #ifdef NAZARA_DEBUG if (NzContext::GetCurrent() == nullptr) @@ -142,9 +142,9 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f return; } - if (primitive > nzPrimitiveType_Max) + if (mode > nzPrimitiveMode_Max) { - NazaraError("Primitive type out of enum"); + NazaraError("Primitive mode out of enum"); return; } #endif @@ -166,7 +166,7 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f } if (s_indexBuffer->IsSequential()) - glDrawArrays(NzOpenGL::PrimitiveType[primitive], s_indexBuffer->GetStartIndex(), s_indexBuffer->GetIndexCount()); + glDrawArrays(NzOpenGL::PrimitiveMode[mode], s_indexBuffer->GetStartIndex(), s_indexBuffer->GetIndexCount()); else { GLenum type; @@ -182,11 +182,11 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f type = GL_UNSIGNED_SHORT; } - glDrawElements(NzOpenGL::PrimitiveType[primitive], indexCount, type, ptr); + glDrawElements(NzOpenGL::PrimitiveMode[mode], indexCount, type, ptr); } } -void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveType primitive, unsigned int firstIndex, unsigned int indexCount) +void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount) { #ifdef NAZARA_DEBUG if (NzContext::GetCurrent() == nullptr) @@ -195,9 +195,9 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr return; } - if (primitive > nzPrimitiveType_Max) + if (mode > nzPrimitiveMode_Max) { - NazaraError("Primitive type out of enum"); + NazaraError("Primitive mode out of enum"); return; } #endif @@ -221,9 +221,9 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr return; } - if (instanceCount > NAZARA_RENDERER_INSTANCING_MAX) + if (instanceCount > NAZARA_RENDERER_MAX_INSTANCES) { - NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " + NzString::Number(NAZARA_RENDERER_INSTANCING_MAX) + ')'); + NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")" ); return; } #endif @@ -237,7 +237,7 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr } if (s_indexBuffer->IsSequential()) - glDrawArraysInstanced(NzOpenGL::PrimitiveType[primitive], s_indexBuffer->GetStartIndex(), s_indexBuffer->GetIndexCount(), instanceCount); + glDrawArraysInstanced(NzOpenGL::PrimitiveMode[mode], s_indexBuffer->GetStartIndex(), s_indexBuffer->GetIndexCount(), instanceCount); else { GLenum type; @@ -253,11 +253,11 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr type = GL_UNSIGNED_SHORT; } - glDrawElementsInstanced(NzOpenGL::PrimitiveType[primitive], indexCount, type, ptr, instanceCount); + glDrawElementsInstanced(NzOpenGL::PrimitiveMode[mode], indexCount, type, ptr, instanceCount); } } -void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount) +void NzRenderer::DrawPrimitives(nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount) { #ifdef NAZARA_DEBUG if (NzContext::GetCurrent() == nullptr) @@ -266,9 +266,9 @@ void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVer return; } - if (primitive > nzPrimitiveType_Max) + if (mode > nzPrimitiveMode_Max) { - NazaraError("Primitive type out of enum"); + NazaraError("Primitive mode out of enum"); return; } #endif @@ -281,10 +281,10 @@ void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVer return; } - glDrawArrays(NzOpenGL::PrimitiveType[primitive], firstVertex, vertexCount); + glDrawArrays(NzOpenGL::PrimitiveMode[mode], firstVertex, vertexCount); } -void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount) +void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount) { #ifdef NAZARA_DEBUG if (NzContext::GetCurrent() == nullptr) @@ -293,9 +293,9 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive return; } - if (primitive > nzPrimitiveType_Max) + if (mode > nzPrimitiveMode_Max) { - NazaraError("Primitive type out of enum"); + NazaraError("Primitive mode out of enum"); return; } #endif @@ -313,9 +313,9 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive return; } - if (instanceCount > NAZARA_RENDERER_INSTANCING_MAX) + if (instanceCount > NAZARA_RENDERER_MAX_INSTANCES) { - NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " + NzString::Number(NAZARA_RENDERER_INSTANCING_MAX) + ')'); + NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")" ); return; } #endif @@ -328,7 +328,7 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive return; } - glDrawArraysInstanced(NzOpenGL::PrimitiveType[primitive], firstVertex, vertexCount, instanceCount); + glDrawArraysInstanced(NzOpenGL::PrimitiveMode[mode], firstVertex, vertexCount, instanceCount); } void NzRenderer::DrawTexture(unsigned int unit, const NzRectf& rect, const NzVector2f& uv0, const NzVector2f& uv1, float z) @@ -443,7 +443,7 @@ void NzRenderer::DrawTexture(unsigned int unit, const NzRectf& rect, const NzVec shader->SendMatrix(s_matrixLocation[nzMatrixCombination_WorldViewProj], NzMatrix4f::Ortho(0.f, s_targetSize.x, 0.f, s_targetSize.y, 0.f)); - glDrawArrays(NzOpenGL::PrimitiveType[nzPrimitiveType_TriangleStrip], 0, 4); + glDrawArrays(NzOpenGL::PrimitiveMode[nzPrimitiveMode_TriangleStrip], 0, 4); // Restauration Enable(nzRendererParameter_FaceCulling, faceCulling); @@ -706,7 +706,7 @@ bool NzRenderer::Initialize() if (s_capabilities[nzRendererCap_Instancing]) { s_instancingBuffer = new NzBuffer(nzBufferType_Vertex); - if (!s_instancingBuffer->Create(NAZARA_RENDERER_INSTANCING_MAX, sizeof(InstancingData), nzBufferStorage_Hardware, nzBufferUsage_Dynamic)) + if (!s_instancingBuffer->Create(NAZARA_RENDERER_MAX_INSTANCES, sizeof(InstancingData), nzBufferStorage_Hardware, nzBufferUsage_Dynamic)) { s_capabilities[nzRendererCap_Instancing] = false; @@ -1014,9 +1014,9 @@ void NzRenderer::SetInstancingData(const NzRenderer::InstancingData* instancingD return; } - if (instanceCount > NAZARA_RENDERER_INSTANCING_MAX) + if (instanceCount > NAZARA_RENDERER_MAX_INSTANCES) { - NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " + NzString::Number(NAZARA_RENDERER_INSTANCING_MAX) + ')'); + NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")"); return; } #endif diff --git a/src/Nazara/Renderer/ShaderBuilder.cpp b/src/Nazara/Renderer/ShaderBuilder.cpp index a6e55d83c..706408638 100644 --- a/src/Nazara/Renderer/ShaderBuilder.cpp +++ b/src/Nazara/Renderer/ShaderBuilder.cpp @@ -44,7 +44,6 @@ namespace sourceCode += "#define LIGHT_DIRECTIONAL 0\n" "#define LIGHT_POINT 1\n" "#define LIGHT_SPOT 2\n" - "#define MAX_LIGHTS 8\n" "\n"; } @@ -71,7 +70,7 @@ namespace { sourceCode += "uniform vec3 CameraPosition;\n" "uniform int LightCount;\n" - "uniform Light Lights[MAX_LIGHTS];\n" + "uniform Light Lights[" NazaraStringifyMacro(NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT) "];\n" "uniform vec4 MaterialAmbient;\n"; } diff --git a/src/Nazara/Utility/SubMesh.cpp b/src/Nazara/Utility/SubMesh.cpp index 6ed613e2c..e2f61f855 100644 --- a/src/Nazara/Utility/SubMesh.cpp +++ b/src/Nazara/Utility/SubMesh.cpp @@ -14,7 +14,7 @@ NzSubMesh::NzSubMesh(const NzMesh* parent) : NzResource(false), // Un SubMesh n'est pas persistant par défaut -m_primitiveType(nzPrimitiveType_TriangleList), +m_primitiveMode(nzPrimitiveMode_TriangleList), m_parent(parent), m_matIndex(0) { @@ -147,9 +147,9 @@ const NzMesh* NzSubMesh::GetParent() const return m_parent; } -nzPrimitiveType NzSubMesh::GetPrimitiveType() const +nzPrimitiveMode NzSubMesh::GetPrimitiveMode() const { - return m_primitiveType; + return m_primitiveMode; } unsigned int NzSubMesh::GetTriangleCount() const @@ -161,24 +161,24 @@ unsigned int NzSubMesh::GetTriangleCount() const else indexCount = GetVertexCount(); - switch (m_primitiveType) + switch (m_primitiveMode) { - case nzPrimitiveType_LineList: - case nzPrimitiveType_LineStrip: - case nzPrimitiveType_PointList: + case nzPrimitiveMode_LineList: + case nzPrimitiveMode_LineStrip: + case nzPrimitiveMode_PointList: return 0; - case nzPrimitiveType_TriangleFan: + case nzPrimitiveMode_TriangleFan: return (indexCount - 1) / 2; - case nzPrimitiveType_TriangleList: + case nzPrimitiveMode_TriangleList: return indexCount / 3; - case nzPrimitiveType_TriangleStrip: + case nzPrimitiveMode_TriangleStrip: return indexCount - 2; } - NazaraError("Primitive type not handled (0x" + NzString::Number(m_primitiveType, 16) + ')'); + NazaraError("Primitive mode not handled (0x" + NzString::Number(m_primitiveMode, 16) + ')'); return 0; } @@ -187,9 +187,9 @@ unsigned int NzSubMesh::GetMaterialIndex() const return m_matIndex; } -void NzSubMesh::SetPrimitiveType(nzPrimitiveType primitiveType) +void NzSubMesh::SetPrimitiveMode(nzPrimitiveMode mode) { - m_primitiveType = primitiveType; + m_primitiveMode = mode; } void NzSubMesh::SetMaterialIndex(unsigned int matIndex) diff --git a/src/Nazara/Utility/TriangleIterator.cpp b/src/Nazara/Utility/TriangleIterator.cpp index 3a113e711..2571d2862 100644 --- a/src/Nazara/Utility/TriangleIterator.cpp +++ b/src/Nazara/Utility/TriangleIterator.cpp @@ -7,7 +7,7 @@ #include NzTriangleIterator::NzTriangleIterator(NzSubMesh* subMesh, nzBufferAccess access) : -m_primitiveType(subMesh->GetPrimitiveType()), +m_primitiveMode(subMesh->GetPrimitiveMode()), m_indexMapper(subMesh->GetIndexBuffer(), nzBufferAccess_ReadOnly), m_vertexMapper(subMesh) { @@ -33,20 +33,20 @@ bool NzTriangleIterator::Advance() return false; } - switch (m_primitiveType) + switch (m_primitiveMode) { - case nzPrimitiveType_TriangleFan: + case nzPrimitiveMode_TriangleFan: m_triangleIndices[1] = m_indexMapper.Get(m_currentIndex++); m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++); break; - case nzPrimitiveType_TriangleList: + case nzPrimitiveMode_TriangleList: m_triangleIndices[0] = m_indexMapper.Get(m_currentIndex++); m_triangleIndices[1] = m_indexMapper.Get(m_currentIndex++); m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++); break; - case nzPrimitiveType_TriangleStrip: + case nzPrimitiveMode_TriangleStrip: m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++); m_triangleIndices[1] = m_triangleIndices[2]; m_triangleIndices[0] = m_triangleIndices[1]; From 5f36817209380de3ad0860c5d94dd1efe7b4c242 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 25 May 2013 10:07:36 +0200 Subject: [PATCH 2/4] Rewritted rendersystem Former-commit-id: 9cbc601413e057047b94b8b872ee2316a86638c4 --- include/Nazara/Graphics.hpp | 1 - .../Nazara/Graphics/AbstractRenderQueue.hpp | 30 ++ .../Graphics/AbstractRenderTechnique.hpp | 29 ++ include/Nazara/Graphics/Camera.hpp | 4 +- ...RenderQueue.hpp => ForwardRenderQueue.hpp} | 83 ++--- .../Graphics/ForwardRenderTechnique.hpp | 33 ++ include/Nazara/Graphics/Light.hpp | 4 +- include/Nazara/Graphics/Model.hpp | 3 +- include/Nazara/Graphics/Scene.hpp | 11 +- include/Nazara/Graphics/SceneNode.hpp | 3 +- include/Nazara/Graphics/SceneRoot.hpp | 2 +- src/Nazara/Graphics/AbstractRenderQueue.cpp | 8 + .../Graphics/AbstractRenderTechnique.cpp | 8 + src/Nazara/Graphics/Camera.cpp | 4 +- src/Nazara/Graphics/ForwardRenderQueue.cpp | 224 ++++++++++++++ .../Graphics/ForwardRenderTechnique.cpp | 277 +++++++++++++++++ src/Nazara/Graphics/Light.cpp | 19 +- src/Nazara/Graphics/Model.cpp | 50 +-- src/Nazara/Graphics/RenderQueue.cpp | 96 ------ src/Nazara/Graphics/Scene.cpp | 285 ++---------------- src/Nazara/Graphics/SceneRoot.cpp | 2 +- 21 files changed, 714 insertions(+), 462 deletions(-) create mode 100644 include/Nazara/Graphics/AbstractRenderQueue.hpp create mode 100644 include/Nazara/Graphics/AbstractRenderTechnique.hpp rename include/Nazara/Graphics/{RenderQueue.hpp => ForwardRenderQueue.hpp} (60%) create mode 100644 include/Nazara/Graphics/ForwardRenderTechnique.hpp create mode 100644 src/Nazara/Graphics/AbstractRenderQueue.cpp create mode 100644 src/Nazara/Graphics/AbstractRenderTechnique.cpp create mode 100644 src/Nazara/Graphics/ForwardRenderQueue.cpp create mode 100644 src/Nazara/Graphics/ForwardRenderTechnique.cpp delete mode 100644 src/Nazara/Graphics/RenderQueue.cpp diff --git a/include/Nazara/Graphics.hpp b/include/Nazara/Graphics.hpp index 87e179731..411200e53 100644 --- a/include/Nazara/Graphics.hpp +++ b/include/Nazara/Graphics.hpp @@ -38,7 +38,6 @@ #include #include #include -#include #include #include #include diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp new file mode 100644 index 000000000..2246e94b2 --- /dev/null +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -0,0 +1,30 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_ABSTRACTRENDERQUEUE_HPP +#define NAZARA_ABSTRACTRENDERQUEUE_HPP + +#include +#include + +class NzDrawable; +class NzLight; +class NzModel; + +class NAZARA_API NzAbstractRenderQueue : NzNonCopyable +{ + public: + NzAbstractRenderQueue() = default; + virtual ~NzAbstractRenderQueue(); + + virtual void AddDrawable(const NzDrawable* drawable) = 0; + virtual void AddLight(const NzLight* light) = 0; + virtual void AddModel(const NzModel* model) = 0; + + virtual void Clear() = 0; +}; + +#endif // NAZARA_ABSTRACTRENDERQUEUE_HPP diff --git a/include/Nazara/Graphics/AbstractRenderTechnique.hpp b/include/Nazara/Graphics/AbstractRenderTechnique.hpp new file mode 100644 index 000000000..b390597e3 --- /dev/null +++ b/include/Nazara/Graphics/AbstractRenderTechnique.hpp @@ -0,0 +1,29 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_ABSTRACTRENDERTECHNIQUE_HPP +#define NAZARA_ABSTRACTRENDERTECHNIQUE_HPP + +#include +#include +#include + +class NzBackground; +class NzScene; + +class NAZARA_API NzAbstractRenderTechnique : NzNonCopyable +{ + public: + NzAbstractRenderTechnique() = default; + virtual ~NzAbstractRenderTechnique(); + + virtual void Clear(const NzScene* scene) = 0; + virtual void Draw(const NzScene* scene) = 0; + + virtual NzAbstractRenderQueue* GetRenderQueue() = 0; +}; + +#endif // NAZARA_ABSTRACTRENDERTECHNIQUE_HPP diff --git a/include/Nazara/Graphics/Camera.hpp b/include/Nazara/Graphics/Camera.hpp index 2e536ef3f..724cd4c75 100644 --- a/include/Nazara/Graphics/Camera.hpp +++ b/include/Nazara/Graphics/Camera.hpp @@ -22,7 +22,7 @@ class NAZARA_API NzCamera : public NzSceneNode NzCamera(); ~NzCamera(); - void Activate() const; + void Activate(); void EnsureFrustumUpdate() const; void EnsureProjectionMatrixUpdate() const; @@ -50,7 +50,7 @@ class NAZARA_API NzCamera : public NzSceneNode void SetZNear(float zNear); private: - void AddToRenderQueue(NzRenderQueue& renderQueue) const; + void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; void Invalidate(); void Register(); void Unregister(); diff --git a/include/Nazara/Graphics/RenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp similarity index 60% rename from include/Nazara/Graphics/RenderQueue.hpp rename to include/Nazara/Graphics/ForwardRenderQueue.hpp index a5d2f3a7e..4c83d4245 100644 --- a/include/Nazara/Graphics/RenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -2,60 +2,49 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -#ifndef NAZARA_RENDERQUEUE_HPP -#define NAZARA_RENDERQUEUE_HPP +#pragma once + +#ifndef NAZARA_FORWARDRENDERQUEUE_HPP +#define NAZARA_FORWARDRENDERQUEUE_HPP #include +#include #include -#include #include -#include -class NzDrawable; -class NzLight; +class NzCamera; class NzMaterial; -class NzModel; class NzSkeletalMesh; class NzStaticMesh; -class NAZARA_API NzRenderQueue +class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue { + friend class NzForwardRenderTechnique; + public: - NzRenderQueue() = default; - ~NzRenderQueue() = default; + NzForwardRenderQueue() = default; + ~NzForwardRenderQueue() = default; + + void AddDrawable(const NzDrawable* drawable); + void AddLight(const NzLight* light); + void AddModel(const NzModel* model); void Clear(); - struct SkeletalData - { - NzMatrix4f transformMatrix; - - ///TODO: Déplacer vers un container séparé qui ne serait pas sujet à Clear(); - std::vector skinnedVertices; - }; - - struct TransparentModel - { - NzMatrix4f transformMatrix; - NzMaterial* material; - }; - - struct TransparentSkeletalModel : public TransparentModel - { - ///TODO: Déplacer vers un container séparé qui ne serait pas sujet à Clear(); - std::vector skinnedVertices; - }; - - struct TransparentStaticModel : public TransparentModel - { - NzStaticMesh* mesh; - }; + void Sort(const NzCamera& camera); + private: struct MaterialComparator { bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); }; + struct SkeletalData + { + ///TODO + NzMatrix4f transformMatrix; + }; + struct SkeletalMeshComparator { bool operator()(const NzSkeletalMesh* subMesh1, const NzSkeletalMesh* subMesh2); @@ -66,16 +55,32 @@ class NAZARA_API NzRenderQueue bool operator()(const NzStaticMesh* subMesh1, const NzStaticMesh* subMesh2); }; + struct TransparentModel + { + NzMatrix4f transformMatrix; + NzMaterial* material; + }; + + struct TransparentSkeletalModel : public TransparentModel + { + ///TODO + }; + + struct TransparentStaticModel : public TransparentModel + { + NzStaticMesh* mesh; + }; + typedef std::map, SkeletalMeshComparator> SkeletalMeshContainer; typedef std::map, StaticMeshComparator> StaticMeshContainer; - std::map visibleSkeletalModels; - std::map visibleStaticModels; - std::vector visibleTransparentSkeletalModels; - std::vector visibleTransparentStaticModels; + std::map, MaterialComparator> visibleModels; + std::vector> visibleTransparentsModels; + std::vector transparentSkeletalModels; + std::vector transparentStaticModels; std::vector otherDrawables; std::vector directionnalLights; std::vector visibleLights; }; -#endif // NAZARA_RENDERQUEUE_HPP +#endif // NAZARA_FORWARDRENDERQUEUE_HPP diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp new file mode 100644 index 000000000..385b5f7e2 --- /dev/null +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_FORWARDRENDERTECHNIQUE_HPP +#define NAZARA_FORWARDRENDERTECHNIQUE_HPP + +#include +#include +#include + +class NAZARA_API NzForwardRenderTechnique : public NzAbstractRenderTechnique +{ + public: + NzForwardRenderTechnique(); + ~NzForwardRenderTechnique() = default; + + void Clear(const NzScene* scene); + void Draw(const NzScene* scene); + + unsigned int GetMaxLightsPerObject() const; + NzAbstractRenderQueue* GetRenderQueue() override; + + void SetMaxLightsPerObject(unsigned int lightCount); + + private: + NzForwardRenderQueue m_renderQueue; + unsigned int m_maxLightsPerObject; +}; + +#endif // NAZARA_FORWARDRENDERTECHNIQUE_HPP diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index 048a5d210..6492a1081 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -19,9 +19,9 @@ class NAZARA_API NzLight : public NzSceneNode public: NzLight(nzLightType type); NzLight(const NzLight& light); - ~NzLight(); + ~NzLight() = default; - void AddToRenderQueue(NzRenderQueue& renderQueue) const; + void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; void Apply(const NzShader* shader, unsigned int lightUnit) const; diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index bff162ee0..603d7dbda 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -41,7 +41,7 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable NzModel(NzModel&& model); ~NzModel(); - void AddToRenderQueue(NzRenderQueue& renderQueue) const; + void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; void AdvanceAnimation(float elapsedTime); void EnableAnimation(bool animation); @@ -64,6 +64,7 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable bool HasAnimation() const; bool IsAnimationEnabled() const; + bool IsDrawable() const; bool IsDrawEnabled() const; bool LoadFromFile(const NzString& filePath, const NzModelParameters& params = NzModelParameters()); diff --git a/include/Nazara/Graphics/Scene.hpp b/include/Nazara/Graphics/Scene.hpp index beaa10cd7..ab394d92e 100644 --- a/include/Nazara/Graphics/Scene.hpp +++ b/include/Nazara/Graphics/Scene.hpp @@ -10,9 +10,11 @@ #include #include #include +#include #include #include +class NzAbstractRenderQueue; class NzCamera; class NzLight; class NzModel; @@ -34,8 +36,10 @@ class NAZARA_API NzScene void Cull(); void Draw(); - const NzCamera* GetActiveCamera() const; + NzCamera* GetActiveCamera() const; + NzColor GetAmbientColor() const; NzBackground* GetBackground() const; + NzAbstractRenderTechnique* GetRenderTechnique() const; NzSceneNode& GetRoot() const; float GetUpdateTime() const; unsigned int GetUpdatePerSecond() const; @@ -44,6 +48,7 @@ class NAZARA_API NzScene void SetAmbientColor(const NzColor& color); void SetBackground(NzBackground* background); + void SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique); void SetUpdatePerSecond(unsigned int updatePerSecond); void UnregisterForUpdate(NzUpdatable* object); @@ -54,8 +59,8 @@ class NAZARA_API NzScene operator const NzSceneNode&() const; private: - void RecursiveFrustumCull(NzRenderQueue& renderQueue, const NzFrustumf& frustum, NzNode* node); - void SetActiveCamera(const NzCamera* camera); + void RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node); + void SetActiveCamera(NzCamera* camera); NzSceneImpl* m_impl; }; diff --git a/include/Nazara/Graphics/SceneNode.hpp b/include/Nazara/Graphics/SceneNode.hpp index ba2b010a3..871939eb8 100644 --- a/include/Nazara/Graphics/SceneNode.hpp +++ b/include/Nazara/Graphics/SceneNode.hpp @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -24,7 +23,7 @@ class NAZARA_API NzSceneNode : public NzNode NzSceneNode(const NzSceneNode& node); virtual ~NzSceneNode(); - virtual void AddToRenderQueue(NzRenderQueue& renderQueue) const = 0; + virtual void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const = 0; virtual const NzBoundingBoxf& GetBoundingBox() const = 0; nzNodeType GetNodeType() const final; diff --git a/include/Nazara/Graphics/SceneRoot.hpp b/include/Nazara/Graphics/SceneRoot.hpp index c28651b70..a84b0f970 100644 --- a/include/Nazara/Graphics/SceneRoot.hpp +++ b/include/Nazara/Graphics/SceneRoot.hpp @@ -17,7 +17,7 @@ class NAZARA_API NzSceneRoot : public NzSceneNode friend struct NzSceneImpl; public: - void AddToRenderQueue(NzRenderQueue& renderQueue) const override; + void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override; const NzBoundingBoxf& GetBoundingBox() const override; nzSceneNodeType GetSceneNodeType() const override; diff --git a/src/Nazara/Graphics/AbstractRenderQueue.cpp b/src/Nazara/Graphics/AbstractRenderQueue.cpp new file mode 100644 index 000000000..d4cf28f7a --- /dev/null +++ b/src/Nazara/Graphics/AbstractRenderQueue.cpp @@ -0,0 +1,8 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +NzAbstractRenderQueue::~NzAbstractRenderQueue() = default; diff --git a/src/Nazara/Graphics/AbstractRenderTechnique.cpp b/src/Nazara/Graphics/AbstractRenderTechnique.cpp new file mode 100644 index 000000000..c41001b7b --- /dev/null +++ b/src/Nazara/Graphics/AbstractRenderTechnique.cpp @@ -0,0 +1,8 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +NzAbstractRenderTechnique::~NzAbstractRenderTechnique() = default; diff --git a/src/Nazara/Graphics/Camera.cpp b/src/Nazara/Graphics/Camera.cpp index 96234b7f6..3a9b8ffa3 100644 --- a/src/Nazara/Graphics/Camera.cpp +++ b/src/Nazara/Graphics/Camera.cpp @@ -23,7 +23,7 @@ m_zNear(1.f) NzCamera::~NzCamera() = default; -void NzCamera::Activate() const +void NzCamera::Activate() { #ifdef NAZARA_GRAPHICS_SAFE if (!m_target) @@ -206,7 +206,7 @@ void NzCamera::SetZNear(float zNear) m_projectionMatrixUpdated = false; } -void NzCamera::AddToRenderQueue(NzRenderQueue& renderQueue) const +void NzCamera::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const { NazaraUnused(renderQueue); diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp new file mode 100644 index 000000000..f892bfc98 --- /dev/null +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -0,0 +1,224 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include +#include +#include + +void NzForwardRenderQueue::AddDrawable(const NzDrawable* drawable) +{ + #if NAZARA_GRAPHICS_SAFE + if (!drawable) + { + NazaraError("Invalid drawable"); + return; + } + #endif + + otherDrawables.push_back(drawable); +} + +void NzForwardRenderQueue::AddLight(const NzLight* light) +{ + #if NAZARA_GRAPHICS_SAFE + if (!light) + { + NazaraError("Invalid light"); + return; + } + #endif + + switch (light->GetLightType()) + { + case nzLightType_Directional: + directionnalLights.push_back(light); + break; + + case nzLightType_Point: + case nzLightType_Spot: + visibleLights.push_back(light); + break; + + #ifdef NAZARA_DEBUG + default: + NazaraError("Light type not handled (0x" + NzString::Number(light->GetLightType(), 16) + ')'); + #endif + } +} + +void NzForwardRenderQueue::AddModel(const NzModel* model) +{ + #if NAZARA_GRAPHICS_SAFE + if (!model) + { + NazaraError("Invalid model"); + return; + } + + if (!model->IsDrawable()) + { + NazaraError("Model is not drawable"); + return; + } + #endif + + const NzMatrix4f& transformMatrix = model->GetTransformMatrix(); + + NzMesh* mesh = model->GetMesh(); + unsigned int submeshCount = mesh->GetSubMeshCount(); + + for (unsigned int i = 0; i < submeshCount; ++i) + { + NzSubMesh* subMesh = mesh->GetSubMesh(i); + NzMaterial* material = model->GetMaterial(subMesh->GetMaterialIndex()); + + switch (subMesh->GetAnimationType()) + { + case nzAnimationType_Skeletal: + { + ///TODO + /* + ** Il y a ici deux choses importantes à gérer: + ** -Pour commencer, la mise en cache de std::vector suffisamment grands pour contenir le résultat du skinning + ** l'objectif ici est d'éviter une allocation à chaque frame, donc de réutiliser un tableau existant + ** Note: Il faudrait évaluer aussi la possibilité de conserver le buffer d'une frame à l'autre. + ** Ceci permettant de ne pas skinner inutilement ce qui ne bouge pas, ou de skinner partiellement un mesh. + ** Il faut cependant voir où stocker ce set de buffers, qui doit être communs à toutes les RQ d'une même scène. + ** + ** -Ensuite, la possibilité de regrouper les modèles skinnés identiques, une centaine de soldats marchant au pas + ** ne devrait requérir qu'un skinning. + */ + NazaraError("Skeletal mesh not supported yet, sorry"); + break; + } + + case nzAnimationType_Static: + { + NzStaticMesh* staticMesh = static_cast(subMesh); + if (material->IsAlphaBlendingEnabled()) + { + unsigned int index = transparentStaticModels.size(); + transparentStaticModels.resize(index+1); + + TransparentStaticModel& data = transparentStaticModels.back(); + data.material = material; + data.mesh = staticMesh; + data.transformMatrix = transformMatrix; + + visibleTransparentsModels.push_back(std::make_pair(index, true)); + } + else + visibleModels[material].second[staticMesh].push_back(transformMatrix); + + break; + } + } + } +} + +void NzForwardRenderQueue::Clear() +{ + directionnalLights.clear(); + otherDrawables.clear(); + visibleLights.clear(); + visibleModels.clear(); + visibleTransparentsModels.clear(); + transparentSkeletalModels.clear(); + transparentStaticModels.clear(); +} + +void NzForwardRenderQueue::Sort(const NzCamera& camera) +{ + struct TransparentModelComparator + { + bool operator()(const std::pair& index1, const std::pair& index2) + { + const NzMatrix4f& matrix1 = (index1.second) ? + queue->transparentStaticModels[index1.first].transformMatrix : + queue->transparentSkeletalModels[index1.first].transformMatrix; + + const NzMatrix4f& matrix2 = (index1.second) ? + queue->transparentStaticModels[index2.first].transformMatrix : + queue->transparentSkeletalModels[index2.first].transformMatrix; + + return nearPlane.Distance(matrix1.GetTranslation()) < nearPlane.Distance(matrix2.GetTranslation()); + } + + NzForwardRenderQueue* queue; + NzPlanef nearPlane; + }; + + TransparentModelComparator comparator {this, camera.GetFrustum().GetPlane(nzFrustumPlane_Near)}; + std::sort(visibleTransparentsModels.begin(), visibleTransparentsModels.end(), comparator); +} + +bool NzForwardRenderQueue::SkeletalMeshComparator::operator()(const NzSkeletalMesh* subMesh1, const NzSkeletalMesh* subMesh2) +{ + const NzIndexBuffer* iBuffer1 = subMesh1->GetIndexBuffer(); + const NzBuffer* buffer1 = (iBuffer1) ? iBuffer1->GetBuffer() : nullptr; + + const NzIndexBuffer* iBuffer2 = subMesh1->GetIndexBuffer(); + const NzBuffer* buffer2 = (iBuffer2) ? iBuffer2->GetBuffer() : nullptr; + + if (buffer1 == buffer2) + return subMesh1 < subMesh2; + else + return buffer2 < buffer2; +} + +bool NzForwardRenderQueue::StaticMeshComparator::operator()(const NzStaticMesh* subMesh1, const NzStaticMesh* subMesh2) +{ + const NzIndexBuffer* iBuffer1 = subMesh1->GetIndexBuffer(); + const NzBuffer* buffer1 = (iBuffer1) ? iBuffer1->GetBuffer() : nullptr; + + const NzIndexBuffer* iBuffer2 = subMesh1->GetIndexBuffer(); + const NzBuffer* buffer2 = (iBuffer2) ? iBuffer2->GetBuffer() : nullptr; + + if (buffer1 == buffer2) + { + buffer1 = subMesh1->GetVertexBuffer()->GetBuffer(); + buffer2 = subMesh2->GetVertexBuffer()->GetBuffer(); + + if (buffer1 == buffer2) + return subMesh1 < subMesh2; + else + return buffer1 < buffer2; + } + else + return buffer1 < buffer2; +} + +bool NzForwardRenderQueue::MaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2) +{ + const NzShader* shader1 = mat1->GetCustomShader(); + const NzShader* shader2 = mat2->GetCustomShader(); + + if (shader1) + { + if (shader2) + { + if (shader1 != shader2) + return shader1 < shader2; + } + else + return true; + } + else if (shader2) + return false; + else + { + nzUInt32 shaderFlags1 = mat1->GetShaderFlags(); + nzUInt32 shaderFlags2 = mat2->GetShaderFlags(); + + if (shaderFlags1 != shaderFlags2) + return shaderFlags1 < shaderFlags2; + } + + return mat1 < mat2; +} diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp new file mode 100644 index 000000000..21fc0350b --- /dev/null +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -0,0 +1,277 @@ +// Copyright (C) 2013 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + struct LightComparator + { + bool operator()(const NzLight* light1, const NzLight* light2) + { + return light1->GetPosition().SquaredDistance(pos) < light2->GetPosition().SquaredDistance(pos); + } + + NzVector3f pos; + }; +} + +NzForwardRenderTechnique::NzForwardRenderTechnique() : +m_maxLightsPerObject(3) // Valeur totalement arbitraire +{ +} + +void NzForwardRenderTechnique::Clear(const NzScene* scene) +{ + NzRenderer::Enable(nzRendererParameter_DepthBuffer, true); + NzRenderer::Enable(nzRendererParameter_DepthWrite, true); + NzRenderer::Clear(nzRendererClear_Depth); + + NzBackground* background = scene->GetBackground(); + if (background) + background->Draw(scene); +} + +void NzForwardRenderTechnique::Draw(const NzScene* scene) +{ + ///TODO: Regrouper les activations par méthode + LightComparator lightComparator; + + const NzCamera* camera = scene->GetActiveCamera(); + const NzShader* lastShader = nullptr; + + // Externes à la boucle pour conserver leur valeurs si le shader ne change pas + unsigned int lightCount = 0; + int lightCountLocation = -1; + + // Rendu des modèles opaques + for (auto matIt : m_renderQueue.visibleModels) + { + NzMaterial* material = matIt.first; + + // On commence par récupérer le shader du matériau + const NzShader* shader; + if (material->HasCustomShader()) + shader = material->GetCustomShader(); + else + shader = NzShaderBuilder::Get(material->GetShaderFlags()); + + // Les uniformes sont conservées au sein du shader, inutile de les renvoyer tant que le shader reste le même + if (shader != lastShader) + { + // On récupère l'information sur l'éclairage en même temps que la position de l'uniforme "LightCount" + lightCountLocation = shader->GetUniformLocation(nzShaderUniform_LightCount); + + NzRenderer::SetShader(shader); + + // Couleur ambiante de la scène + shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + // Position de la caméra + shader->SendVector(shader->GetUniformLocation(nzShaderUniform_CameraPosition), camera->GetPosition()); + + lightCount = 0; + + // On envoie les lumières directionnelles s'il y a (Les mêmes pour tous) + if (lightCountLocation != -1) + { + for (const NzLight* light : m_renderQueue.directionnalLights) + { + light->Apply(shader, lightCount++); + if (lightCount > NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT) + break; // Prévenons les bêtises des utilisateurs + } + } + lastShader = shader; + } + + material->Apply(shader); + + // Meshs squelettiques + /*NzForwardRenderQueue::SkeletalMeshContainer& container = matIt.second.first; + if (!container.empty()) + { + NzRenderer::SetVertexBuffer(m_skinningBuffer); // Vertex buffer commun + for (auto subMeshIt : container) + { + ///TODO + } + }*/ + + // Meshs statiques + for (auto subMeshIt : matIt.second.second) + { + NzStaticMesh* mesh = subMeshIt.first; + + const NzIndexBuffer* indexBuffer = mesh->GetIndexBuffer(); + const NzVertexBuffer* vertexBuffer = mesh->GetVertexBuffer(); + + // Gestion du draw call avant la boucle de rendu + std::function drawFunc; + unsigned int indexCount; + + if (indexBuffer) + { + drawFunc = NzRenderer::DrawIndexedPrimitives; + indexCount = indexBuffer->GetIndexCount(); + } + else + { + drawFunc = NzRenderer::DrawPrimitives; + indexCount = vertexBuffer->GetVertexCount(); + } + + NzRenderer::SetIndexBuffer(indexBuffer); + NzRenderer::SetVertexBuffer(vertexBuffer); + + for (const NzMatrix4f& matrix : subMeshIt.second) + { + // Calcul des lumières les plus proches + ///TODO: LightManager ? + if (lightCountLocation != -1) + { + std::vector& visibleLights = m_renderQueue.visibleLights; + + lightComparator.pos = matrix.GetTranslation(); + std::sort(visibleLights.begin(), visibleLights.end(), lightComparator); + + unsigned int max = std::min(std::min(NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT - lightCount, m_maxLightsPerObject), static_cast(visibleLights.size())); + for (unsigned int i = 0; i < max; ++i) + visibleLights[i]->Apply(shader, lightCount++); + + shader->SendInteger(lightCountLocation, lightCount); + } + + NzRenderer::SetMatrix(nzMatrixType_World, matrix); + drawFunc(mesh->GetPrimitiveMode(), 0, indexCount); + } + } + } + + for (const std::pair& pair : m_renderQueue.visibleTransparentsModels) + { + // Matériau + NzMaterial* material = (pair.second) ? + m_renderQueue.transparentStaticModels[pair.first].material : + m_renderQueue.transparentSkeletalModels[pair.first].material; + + // On commence par récupérer le shader du matériau + const NzShader* shader; + if (material->HasCustomShader()) + shader = material->GetCustomShader(); + else + shader = NzShaderBuilder::Get(material->GetShaderFlags()); + + // Les uniformes sont conservées au sein du shader, inutile de les renvoyer tant que le shader reste le même + if (shader != lastShader) + { + // On récupère l'information sur l'éclairage en même temps que la position de l'uniforme "LightCount" + lightCountLocation = shader->GetUniformLocation(nzShaderUniform_LightCount); + + NzRenderer::SetShader(shader); + + // Couleur ambiante de la scène + shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor()); + // Position de la caméra + shader->SendVector(shader->GetUniformLocation(nzShaderUniform_CameraPosition), camera->GetPosition()); + + lightCount = 0; + + // On envoie les lumières directionnelles s'il y a (Les mêmes pour tous) + if (lightCountLocation != -1) + { + for (const NzLight* light : m_renderQueue.directionnalLights) + { + light->Apply(shader, lightCount++); + if (lightCount > NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT) + break; // Prévenons les bêtises des utilisateurs + } + } + lastShader = shader; + } + + material->Apply(shader); + + // Mesh + if (pair.second) + { + NzForwardRenderQueue::TransparentStaticModel& staticModel = m_renderQueue.transparentStaticModels[pair.first]; + + const NzMatrix4f& matrix = staticModel.transformMatrix; + NzStaticMesh* mesh = staticModel.mesh; + + const NzIndexBuffer* indexBuffer = mesh->GetIndexBuffer(); + const NzVertexBuffer* vertexBuffer = mesh->GetVertexBuffer(); + + // Gestion du draw call avant la boucle de rendu + std::function drawFunc; + unsigned int indexCount; + + if (indexBuffer) + { + drawFunc = NzRenderer::DrawIndexedPrimitives; + indexCount = indexBuffer->GetIndexCount(); + } + else + { + drawFunc = NzRenderer::DrawPrimitives; + indexCount = vertexBuffer->GetVertexCount(); + } + + NzRenderer::SetIndexBuffer(indexBuffer); + NzRenderer::SetVertexBuffer(vertexBuffer); + + // Calcul des lumières les plus proches + ///TODO: LightManager ? + if (lightCountLocation != -1) + { + std::vector& visibleLights = m_renderQueue.visibleLights; + + lightComparator.pos = matrix.GetTranslation(); + std::sort(visibleLights.begin(), visibleLights.end(), lightComparator); + + unsigned int max = std::min(std::min(NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT - lightCount, m_maxLightsPerObject), static_cast(visibleLights.size())); + for (unsigned int i = 0; i < max; ++i) + visibleLights[i]->Apply(shader, lightCount++); + + shader->SendInteger(lightCountLocation, lightCount); + } + + NzRenderer::SetMatrix(nzMatrixType_World, matrix); + drawFunc(mesh->GetPrimitiveMode(), 0, indexCount); + } + else + { + ///TODO + } + } + + // Les autres drawables (Exemple: Terrain) + for (const NzDrawable* drawable : m_renderQueue.otherDrawables) + drawable->Draw(); +} + +unsigned int NzForwardRenderTechnique::GetMaxLightsPerObject() const +{ + return m_maxLightsPerObject; +} + +NzAbstractRenderQueue* NzForwardRenderTechnique::GetRenderQueue() +{ + return &m_renderQueue; +} + +void NzForwardRenderTechnique::SetMaxLightsPerObject(unsigned int lightCount) +{ + m_maxLightsPerObject = lightCount; +} diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index 3fdb7ed87..cadcdc325 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include #include @@ -32,23 +33,9 @@ NzSceneNode(light) std::memcpy(this, &light, sizeof(NzLight)); // Aussi simple que ça } -NzLight::~NzLight() +void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const { -} - -void NzLight::AddToRenderQueue(NzRenderQueue& renderQueue) const -{ - switch (m_type) - { - case nzLightType_Directional: - renderQueue.directionnalLights.push_back(this); - break; - - case nzLightType_Point: - case nzLightType_Spot: - renderQueue.visibleLights.push_back(this); - break; - } + renderQueue->AddLight(this); } void NzLight::Apply(const NzShader* shader, unsigned int lightUnit) const diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index 10ba81fec..c89209bff 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -64,45 +65,9 @@ NzModel::~NzModel() Reset(); } -void NzModel::AddToRenderQueue(NzRenderQueue& renderQueue) const +void NzModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const { - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); - - unsigned int subMeshCount = m_mesh->GetSubMeshCount(); - for (unsigned int i = 0; i < subMeshCount; ++i) - { - NzSubMesh* subMesh = m_mesh->GetSubMesh(i); - NzMaterial* material = m_materials[m_skin*m_matCount + subMesh->GetMaterialIndex()]; - - switch (subMesh->GetAnimationType()) - { - case nzAnimationType_Skeletal: - { - NzSkeletalMesh* skeletalMesh = static_cast(subMesh); - std::vector& data = renderQueue.visibleSkeletalModels[material][skeletalMesh]; - - ///TODO: Corriger cette abomination - data.resize(data.size()+1); - NzRenderQueue::SkeletalData& skeletalData = data.back(); - - skeletalData.skinnedVertices.resize(skeletalMesh->GetVertexCount()); - skeletalData.transformMatrix = m_transformMatrix; - - skeletalMesh->Skin(&skeletalData.skinnedVertices[0], &m_skeleton); - break; - } - - case nzAnimationType_Static: - { - NzStaticMesh* staticMesh = static_cast(subMesh); - std::vector& matrices = renderQueue.visibleStaticModels[material][staticMesh]; - - matrices.push_back(m_transformMatrix); - break; - } - } - } + renderQueue->AddModel(this); } void NzModel::AdvanceAnimation(float elapsedTime) @@ -310,6 +275,11 @@ bool NzModel::IsAnimationEnabled() const return m_animationEnabled; } +bool NzModel::IsDrawable() const +{ + return m_mesh != nullptr && m_mesh->GetSubMeshCount() >= 1; +} + bool NzModel::IsDrawEnabled() const { return m_drawEnabled; @@ -702,9 +672,9 @@ void NzModel::UpdateBoundingBox() const bool NzModel::VisibilityTest(const NzFrustumf& frustum) { #if NAZARA_GRAPHICS_SAFE - if (!m_mesh) + if (!IsDrawable()) { - NazaraError("Model has no mesh"); + NazaraError("Model is not drawable"); return false; } #endif diff --git a/src/Nazara/Graphics/RenderQueue.cpp b/src/Nazara/Graphics/RenderQueue.cpp deleted file mode 100644 index 59a6c5921..000000000 --- a/src/Nazara/Graphics/RenderQueue.cpp +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (C) 2013 Jérôme Leclercq -// This file is part of the "Nazara Engine - Graphics module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include - -bool NzRenderQueue::MaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2) -{ - const NzShader* shader1 = mat1->GetCustomShader(); - const NzShader* shader2 = mat2->GetCustomShader(); - - if (shader1) - { - if (shader2) - return shader1 < shader2; - else - return true; - } - else if (shader2) - return false; - else - { - nzUInt32 shaderFlags1 = mat1->GetShaderFlags(); - nzUInt32 shaderFlags2 = mat2->GetShaderFlags(); - - if (shaderFlags1 == shaderFlags2) - return mat1 < mat2; - else - return shaderFlags1 < shaderFlags2; - } -} - -bool NzRenderQueue::SkeletalMeshComparator::operator()(const NzSkeletalMesh* subMesh1, const NzSkeletalMesh* subMesh2) -{ - const NzBuffer* buffer1; - const NzIndexBuffer* iBuffer1 = subMesh1->GetIndexBuffer(); - if (iBuffer1) - buffer1 = iBuffer1->GetBuffer(); - else - buffer1 = nullptr; - - const NzBuffer* buffer2; - const NzIndexBuffer* iBuffer2 = subMesh1->GetIndexBuffer(); - if (iBuffer2) - buffer2 = iBuffer1->GetBuffer(); - else - buffer2 = nullptr; - - if (buffer1 == buffer2) - return subMesh1 < subMesh2; - else - return buffer2 < buffer2; -} - -bool NzRenderQueue::StaticMeshComparator::operator()(const NzStaticMesh* subMesh1, const NzStaticMesh* subMesh2) -{ - const NzBuffer* buffer1; - const NzIndexBuffer* iBuffer1 = subMesh1->GetIndexBuffer(); - if (iBuffer1) - buffer1 = iBuffer1->GetBuffer(); - else - buffer1 = nullptr; - - const NzBuffer* buffer2; - const NzIndexBuffer* iBuffer2 = subMesh1->GetIndexBuffer(); - if (iBuffer2) - buffer2 = iBuffer1->GetBuffer(); - else - buffer2 = nullptr; - - if (iBuffer1 == iBuffer2) - { - buffer1 = subMesh1->GetVertexBuffer()->GetBuffer(); - buffer2 = subMesh2->GetVertexBuffer()->GetBuffer(); - - if (buffer1 == buffer2) - return subMesh1 < subMesh2; - else - return buffer1 < buffer2; - } - else - return iBuffer1 < iBuffer2; -} - -void NzRenderQueue::Clear() -{ - directionnalLights.clear(); - otherDrawables.clear(); - visibleLights.clear(); - visibleSkeletalModels.clear(); - visibleStaticModels.clear(); -} diff --git a/src/Nazara/Graphics/Scene.cpp b/src/Nazara/Graphics/Scene.cpp index 8645e487f..c18326d0e 100644 --- a/src/Nazara/Graphics/Scene.cpp +++ b/src/Nazara/Graphics/Scene.cpp @@ -5,41 +5,17 @@ #include #include #include -#include -#include #include -#include -#include -#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include #include #include #include #include #include -namespace -{ - const unsigned int maxLights = 8; ///TODO: Config - - struct LightComparator - { - bool operator()(const NzLight* light1, const NzLight* light2) - { - return light1->GetPosition().SquaredDistance(pos) < light2->GetPosition().SquaredDistance(pos); - } - - NzVector3f pos; - }; -} - struct NzSceneImpl { NzSceneImpl(NzScene* scene) : @@ -47,16 +23,14 @@ struct NzSceneImpl { } + std::unique_ptr renderTechnique; std::unique_ptr background; std::vector updateList; std::vector visibleUpdateList; - std::vector instancingData; NzClock updateClock; NzColor ambientColor = NzColor(25,25,25); - NzRenderQueue renderQueue; NzSceneRoot root; - const NzCamera* activeCamera; - NzVertexBuffer* skinningBuffer; + NzCamera* activeCamera; bool update; float frameTime; float updateTime; @@ -67,10 +41,7 @@ NzScene::NzScene() { m_impl = new NzSceneImpl(this); m_impl->background.reset(new NzColorBackground); - m_impl->skinningBuffer = new NzVertexBuffer(NzMesh::GetDeclaration(), 20000, nzBufferStorage_Hardware, nzBufferUsage_Dynamic); - - if (NzRenderer::HasCapability(nzRendererCap_Instancing)) - m_impl->instancingData.resize(NAZARA_RENDERER_INSTANCING_MAX); + m_impl->renderTechnique.reset(new NzForwardRenderTechnique); } NzScene::~NzScene() @@ -81,7 +52,6 @@ NzScene::~NzScene() static_cast(child)->SetScene(nullptr); } - delete m_impl->skinningBuffer; delete m_impl; } @@ -92,11 +62,13 @@ void NzScene::AddToVisibilityList(NzUpdatable* object) void NzScene::Cull() { - m_impl->renderQueue.Clear(); + NzAbstractRenderQueue* renderQueue = m_impl->renderTechnique->GetRenderQueue(); + renderQueue->Clear(); + m_impl->visibleUpdateList.clear(); // Frustum culling - RecursiveFrustumCull(m_impl->renderQueue, m_impl->activeCamera->GetFrustum(), &m_impl->root); + RecursiveFrustumCull(renderQueue, m_impl->activeCamera->GetFrustum(), &m_impl->root); ///TODO: Occlusion culling @@ -105,234 +77,30 @@ void NzScene::Cull() void NzScene::Draw() { - NzRenderer::Clear(nzRendererClear_Depth); - - if (m_impl->background) - m_impl->background->Draw(this); - - LightComparator lightComparator; - - // Pour les meshs squelettiques, on utilise un buffer commun - NzRenderer::SetVertexBuffer(m_impl->skinningBuffer); - for (auto matIt : m_impl->renderQueue.visibleSkeletalModels) - { - // On applique le shader du matériau - nzUInt32 shaderFlags = matIt.first->GetShaderFlags(); - - const NzShader* shader = NzShaderBuilder::Get(shaderFlags); - - NzRenderer::SetShader(shader); - matIt.first->Apply(shader); - - // Position de la caméra - int camPosLocation = shader->GetUniformLocation(nzShaderUniform_CameraPosition); - if (camPosLocation != -1) - shader->SendVector(camPosLocation, m_impl->activeCamera->GetPosition()); - - // Couleur ambiante de la scène - int sceneAmbientLocation = shader->GetUniformLocation(nzShaderUniform_SceneAmbient); - if (sceneAmbientLocation != -1) - shader->SendColor(sceneAmbientLocation, m_impl->ambientColor); - - // Gestion des lumières (D'abord directionnelles) - int lightCountLocation = shader->GetUniformLocation(nzShaderUniform_LightCount); - - unsigned int lightIndex = 0; - if (lightCountLocation != -1) - { - for (const NzLight* light : m_impl->renderQueue.directionnalLights) - { - light->Apply(shader, lightIndex++); - if (lightIndex > maxLights) - break; // N'arrivera jamais mais pourrait résulter en un bug - } - } - - for (auto subMeshIt : matIt.second) - { - const NzSkeletalMesh* skeletalMesh = subMeshIt.first; - const NzIndexBuffer* indexBuffer = skeletalMesh->GetIndexBuffer(); - - unsigned int vertexCount = skeletalMesh->GetVertexCount(); - - // Gestion du draw call avant la boucle de rendu - std::function drawFunc; - nzPrimitiveType primitiveType = skeletalMesh->GetPrimitiveType(); - unsigned int indexCount; - if (indexBuffer) - { - drawFunc = NzRenderer::DrawIndexedPrimitives; - indexCount = indexBuffer->GetIndexCount(); - NzRenderer::SetIndexBuffer(indexBuffer); - } - else - { - drawFunc = NzRenderer::DrawPrimitives; - indexCount = skeletalMesh->GetVertexCount(); - } - - for (const NzRenderQueue::SkeletalData& data : subMeshIt.second) - { - // Transfert du résultat du skinning vers notre buffer hardware - NzBufferMapper outputMapper(m_impl->skinningBuffer, nzBufferAccess_DiscardAndWrite, 0, vertexCount); - std::memcpy(outputMapper.GetPointer(), &data.skinnedVertices[0], vertexCount*sizeof(NzMeshVertex)); - outputMapper.Unmap(); - - // Calcul des lumières les plus proches (TODO: LightManager ?) - if (lightCountLocation != -1) - { - auto visibleLights = m_impl->renderQueue.visibleLights; - lightComparator.pos = data.transformMatrix.GetTranslation(); - std::sort(visibleLights.begin(), visibleLights.end(), lightComparator); - - const unsigned int maxLightPerObject = 3; ///TODO: Config - unsigned int max = std::min(std::min(maxLights - lightIndex, maxLightPerObject), static_cast(visibleLights.size())); - for (unsigned int i = 0; i < max; ++i) - visibleLights[i]->Apply(shader, lightIndex + i); - - shader->SendInteger(lightCountLocation, lightIndex + max); - } - - NzRenderer::SetMatrix(nzMatrixType_World, data.transformMatrix); - - drawFunc(primitiveType, 0, indexCount); - } - } - } - - // Pour les meshs statiques, on utilise le buffer du mesh - for (auto matIt : m_impl->renderQueue.visibleStaticModels) - { - // On applique le shader du matériau - nzUInt32 shaderFlags = matIt.first->GetShaderFlags(); - if (NzRenderer::HasCapability(nzRendererCap_Instancing) && m_impl->renderQueue.visibleLights.empty()) - shaderFlags |= nzShaderFlags_Instancing; - - const NzShader* shader = NzShaderBuilder::Get(shaderFlags); - - NzRenderer::SetShader(shader); - matIt.first->Apply(shader); - - bool instancing = shader->GetFlags() & nzShaderFlags_Instancing; - - // Position de la caméra - int camPosLocation = shader->GetUniformLocation(nzShaderUniform_CameraPosition); - if (camPosLocation != -1) - shader->SendVector(camPosLocation, m_impl->activeCamera->GetPosition()); - - // Couleur ambiante de la scène - int sceneAmbientLocation = shader->GetUniformLocation(nzShaderUniform_SceneAmbient); - if (sceneAmbientLocation != -1) - shader->SendColor(sceneAmbientLocation, m_impl->ambientColor); - - // Gestion des lumières (D'abord directionnelles) - int lightCountLocation = shader->GetUniformLocation(nzShaderUniform_LightCount); - - unsigned int lightIndex = 0; - if (lightCountLocation != -1) - { - for (const NzLight* light : m_impl->renderQueue.directionnalLights) - { - light->Apply(shader, lightIndex++); - if (lightIndex > maxLights) - break; // N'arrivera probablement jamais mais pourrait résulter en un bug - } - } - - for (auto subMeshIt : matIt.second) - { - NzStaticMesh* staticMesh = subMeshIt.first; - - const NzIndexBuffer* indexBuffer = staticMesh->GetIndexBuffer(); - const NzVertexBuffer* vertexBuffer = staticMesh->GetVertexBuffer(); - - NzRenderer::SetVertexBuffer(vertexBuffer); - - // Gestion du draw call avant la boucle de rendu - std::function draw; - std::function instancedDraw; - nzPrimitiveType primitiveType = staticMesh->GetPrimitiveType(); - unsigned int indexCount; - if (indexBuffer) - { - draw = NzRenderer::DrawIndexedPrimitives; - indexCount = indexBuffer->GetIndexCount(); - instancedDraw = NzRenderer::DrawIndexedPrimitivesInstanced; - NzRenderer::SetIndexBuffer(indexBuffer); - } - else - { - draw = NzRenderer::DrawPrimitives; - indexCount = vertexBuffer->GetVertexCount(); - instancedDraw = NzRenderer::DrawPrimitivesInstanced; - } - - if (instancing) - { - if (lightCountLocation != -1) - shader->SendInteger(lightCountLocation, lightIndex); - - unsigned int count = 0; - for (const NzMatrix4f& matrix : subMeshIt.second) - { - m_impl->instancingData[count++].worldMatrix = matrix; - if (count == m_impl->instancingData.size()) - { - NzRenderer::SetInstancingData(&m_impl->instancingData[0], count); - instancedDraw(count, primitiveType, 0, indexCount); - - count = 0; - } - } - - if (count > 0) - { - NzRenderer::SetInstancingData(&m_impl->instancingData[0], count); - instancedDraw(count, primitiveType, 0, indexCount); - } - } - else - { - for (const NzMatrix4f& matrix : subMeshIt.second) - { - // Calcul des lumières les plus proches (TODO: LightManager ?) - if (lightCountLocation != -1) - { - std::vector& visibleLights = m_impl->renderQueue.visibleLights; - lightComparator.pos = matrix.GetTranslation(); - std::sort(visibleLights.begin(), visibleLights.end(), lightComparator); - - const unsigned int maxLightPerObject = 3; ///TODO: Config - unsigned int max = std::min(std::min(maxLights - lightIndex, maxLightPerObject), static_cast(visibleLights.size())); - for (unsigned int i = 0; i < max; ++i) - visibleLights[i]->Apply(shader, lightIndex + i); - - shader->SendInteger(lightCountLocation, lightIndex + max); - } - - NzRenderer::SetMatrix(nzMatrixType_World, matrix); - - draw(primitiveType, 0, indexCount); - } - } - } - } - - // Les autres drawables (Exemple: Terrain) - for (const NzDrawable* drawable : m_impl->renderQueue.otherDrawables) - drawable->Draw(); + m_impl->renderTechnique->Clear(this); + m_impl->renderTechnique->Draw(this); } -const NzCamera* NzScene::GetActiveCamera() const +NzCamera* NzScene::GetActiveCamera() const { return m_impl->activeCamera; } +NzColor NzScene::GetAmbientColor() const +{ + return m_impl->ambientColor; +} + NzBackground* NzScene::GetBackground() const { return m_impl->background.get(); } +NzAbstractRenderTechnique* NzScene::GetRenderTechnique() const +{ + return m_impl->renderTechnique.get(); +} + NzSceneNode& NzScene::GetRoot() const { return m_impl->root; @@ -371,6 +139,11 @@ void NzScene::SetBackground(NzBackground* background) m_impl->background.reset(background); } +void NzScene::SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique) +{ + m_impl->renderTechnique.reset(renderTechnique); +} + void NzScene::SetUpdatePerSecond(unsigned int updatePerSecond) { m_impl->updatePerSecond = updatePerSecond; @@ -419,7 +192,7 @@ NzScene::operator const NzSceneNode&() const return m_impl->root; } -void NzScene::RecursiveFrustumCull(NzRenderQueue& renderQueue, const NzFrustumf& frustum, NzNode* node) +void NzScene::RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node) { for (NzNode* child : node->GetChilds()) { @@ -437,7 +210,7 @@ void NzScene::RecursiveFrustumCull(NzRenderQueue& renderQueue, const NzFrustumf& } } -void NzScene::SetActiveCamera(const NzCamera* camera) +void NzScene::SetActiveCamera(NzCamera* camera) { m_impl->activeCamera = camera; } diff --git a/src/Nazara/Graphics/SceneRoot.cpp b/src/Nazara/Graphics/SceneRoot.cpp index 44cbb15c6..ed0670216 100644 --- a/src/Nazara/Graphics/SceneRoot.cpp +++ b/src/Nazara/Graphics/SceneRoot.cpp @@ -13,7 +13,7 @@ NzSceneRoot::NzSceneRoot(NzScene* scene) NzSceneRoot::~NzSceneRoot() = default; -void NzSceneRoot::AddToRenderQueue(NzRenderQueue& renderQueue) const +void NzSceneRoot::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const { NazaraUnused(renderQueue); From 810b45fbb7fbd3b273a53c6892932c3056ef4216 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 25 May 2013 10:07:55 +0200 Subject: [PATCH 3/4] New emission-map algorithm Former-commit-id: a45adb79b885d41a2d461a1d672fc8f63dedff65 --- src/Nazara/Renderer/ShaderBuilder.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Renderer/ShaderBuilder.cpp b/src/Nazara/Renderer/ShaderBuilder.cpp index 706408638..b82f37319 100644 --- a/src/Nazara/Renderer/ShaderBuilder.cpp +++ b/src/Nazara/Renderer/ShaderBuilder.cpp @@ -289,8 +289,9 @@ namespace if (flags & nzShaderFlags_EmissiveMapping) { - sourceCode += "vec3 emission = vec3(" + textureLookupKW + "(MaterialEmissiveMap, vTexCoord));\n" - + fragmentColorKW + " = vec4(mix(lighting, emission, max(0.0, 1.0-length(light))), alpha);\n"; + sourceCode += "float intensity = light.r*0.3 + light.g*0.59 + light.b*0.11;\n" + "vec3 emission = vec3(" + textureLookupKW + "(MaterialEmissiveMap, vTexCoord));\n" + + fragmentColorKW + " = vec4(mix(lighting, emission, clamp(1.0 - 3.0*intensity, 0.0, 1.0)), alpha);\n"; ///NOTE: Pour un shader avec un coût réduit avec une qualité moyenne, il est possible de remplacer "length(light)" par "dot(light, light)" } else From 90bc3c342cbbb69cacc489bee76809759d52753f Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 25 May 2013 10:08:13 +0200 Subject: [PATCH 4/4] Fixed STB loader artefacts Former-commit-id: df4b7cef68efc9e67b968daaa71f578cea68e061 --- src/Nazara/Utility/Loaders/STB/Loader.cpp | 49 +++-------------------- 1 file changed, 5 insertions(+), 44 deletions(-) diff --git a/src/Nazara/Utility/Loaders/STB/Loader.cpp b/src/Nazara/Utility/Loaders/STB/Loader.cpp index 0257edf4f..185509090 100644 --- a/src/Nazara/Utility/Loaders/STB/Loader.cpp +++ b/src/Nazara/Utility/Loaders/STB/Loader.cpp @@ -53,56 +53,18 @@ namespace bool Load(NzImage* image, NzInputStream& stream, const NzImageParams& parameters) { - static const nzPixelFormat formats[4] = - { - nzPixelFormat_L8, - nzPixelFormat_LA8, - nzPixelFormat_RGB8, - nzPixelFormat_RGBA8 - }; - - nzPixelFormat format; - int stbiFormat; - switch (parameters.loadFormat) - { - case nzPixelFormat_L8: - format = nzPixelFormat_L8; - stbiFormat = STBI_grey; - break; - - case nzPixelFormat_LA8: - format = nzPixelFormat_LA8; - stbiFormat = STBI_grey_alpha; - break; - - case nzPixelFormat_RGB8: - format = nzPixelFormat_RGB8; - stbiFormat = STBI_rgb; - break; - - case nzPixelFormat_RGBA8: - format = nzPixelFormat_RGBA8; - stbiFormat = STBI_rgb_alpha; - break; - - default: - format = nzPixelFormat_Undefined; - stbiFormat = STBI_default; - } + // Je charge tout en RGBA8 et je converti ensuite via la méthode Convert + // Ceci à cause d'un bug de STB lorsqu'il s'agit de charger certaines images (ex: JPG) en "default" int width, height, bpp; - nzUInt8* ptr = stbi_load_from_callbacks(&callbacks, &stream, &width, &height, &bpp, stbiFormat); - + nzUInt8* ptr = stbi_load_from_callbacks(&callbacks, &stream, &width, &height, &bpp, STBI_rgb_alpha); if (!ptr) { NazaraError("Failed to load image: " + NzString(stbi_failure_reason())); return false; } - if (format == nzPixelFormat_Undefined) - format = formats[bpp-1]; - - if (!image->Create(nzImageType_2D, format, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1)) + if (!image->Create(nzImageType_2D, nzPixelFormat_RGBA8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1)) { NazaraError("Failed to create image"); stbi_image_free(ptr); @@ -111,10 +73,9 @@ namespace } image->Update(ptr); - stbi_image_free(ptr); - if (stbiFormat == STBI_default && parameters.loadFormat != nzPixelFormat_Undefined) + if (parameters.loadFormat != nzPixelFormat_Undefined) image->Convert(parameters.loadFormat); return true;