diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index c0c15269b..2003a1db6 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -29,8 +29,17 @@ class NAZARA_API NzAbstractRenderQueue : NzNonCopyable NzAbstractRenderQueue() = default; virtual ~NzAbstractRenderQueue(); + // Je ne suis vraiment pas fan du nombre de surcharges pour AddBillboards, + // mais je n'ai pas d'autre solution tout aussi performante pour le moment... virtual void AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos = NzVector2f(0.f, 1.f), const NzColor& color = NzColor::White) = 0; virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) = 0; virtual void AddDrawable(const NzDrawable* drawable) = 0; virtual void AddLight(const NzLight* light) = 0; virtual void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) = 0; diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index 589d10efd..dff95292c 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -30,6 +30,13 @@ class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzResourc void AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos = NzVector2f(0.f, 1.f), const NzColor& color = NzColor::White) override; void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) override; void AddDrawable(const NzDrawable* drawable) override; void AddLight(const NzLight* light) override; void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index 36b2636ce..c1cbbdaf5 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -32,6 +32,13 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource void AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos = NzVector2f(0.f, 1.f), const NzColor& color = NzColor::White) override; void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr = nullptr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr = nullptr) override; + void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) override; void AddDrawable(const NzDrawable* drawable) override; void AddLight(const NzLight* light) override; void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index e98232bbf..1e5692c70 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -55,6 +55,7 @@ class NAZARA_API NzMaterial : public NzResource void Enable(nzRendererParameter renderParameter, bool enable); void EnableAlphaTest(bool alphaTest); + void EnableDepthSorting(bool depthSorting); void EnableLighting(bool lighting); void EnableTransform(bool transform); @@ -90,6 +91,7 @@ class NAZARA_API NzMaterial : public NzResource bool HasSpecularMap() const; bool IsAlphaTestEnabled() const; + bool IsDepthSortingEnabled() const; bool IsEnabled(nzRendererParameter renderParameter) const; bool IsLightingEnabled() const; bool IsTransformEnabled() const; @@ -163,6 +165,7 @@ class NAZARA_API NzMaterial : public NzResource NzUberShaderConstRef m_uberShader; mutable ShaderInstance m_shaders[nzShaderFlags_Max+1]; bool m_alphaTestEnabled; + bool m_depthSortingEnabled; bool m_lightingEnabled; bool m_transformEnabled; float m_alphaThreshold; diff --git a/include/Nazara/Math/Algorithm.hpp b/include/Nazara/Math/Algorithm.hpp index 46d11645f..c4420f621 100644 --- a/include/Nazara/Math/Algorithm.hpp +++ b/include/Nazara/Math/Algorithm.hpp @@ -22,7 +22,8 @@ template T NzApproach(T value, T objective, T increment); template constexpr T NzClamp(T value, T min, T max); -template constexpr T NzDegrees(T degrees); +template constexpr T NzFromDegrees(T degrees); +template constexpr T NzFromRadians(T radians); template constexpr T NzDegreeToRadian(T degrees); unsigned int NzGetNearestPowerOfTwo(unsigned int number); unsigned int NzGetNumberLength(signed char number); @@ -40,9 +41,10 @@ template T NzMultiplyAdd(T x, T y, T z); template T NzNormalizeAngle(T angle); template bool NzNumberEquals(T a, T b, T maxDifference = std::numeric_limits::epsilon()); NzString NzNumberToString(long long number, nzUInt8 radix = 10); -template T NzRadians(T radians); template T NzRadianToDegree(T radians); long long NzStringToNumber(NzString str, nzUInt8 radix = 10, bool* ok = nullptr); +template constexpr T NzToDegrees(T angle); +template constexpr T NzToRadians(T angle); #include diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index 7f6884da8..49b54be32 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -31,7 +31,13 @@ constexpr T NzClamp(T value, T min, T max) } template -constexpr T NzDegrees(T degrees) +constexpr T NzDegreeToRadian(T degrees) +{ + return degrees * F(M_PI/180.0); +} + +template +constexpr T NzFromDegrees(T degrees) { #if NAZARA_MATH_ANGLE_RADIAN return NzDegreeToRadian(degrees); @@ -41,9 +47,13 @@ constexpr T NzDegrees(T degrees) } template -constexpr T NzDegreeToRadian(T degrees) +constexpr T NzFromRadians(T radians) { - return degrees * F(M_PI/180.0); + #if NAZARA_MATH_ANGLE_RADIAN + return radians; + #else + return NzRadianToDegree(radians); + #endif } inline unsigned int NzGetNearestPowerOfTwo(unsigned int number) @@ -51,7 +61,7 @@ inline unsigned int NzGetNearestPowerOfTwo(unsigned int number) ///TODO: Marquer comme constexpr en C++14 unsigned int x = 1; // Tant que x est plus petit que n, on décale ses bits vers la gauche, ce qui revient à multiplier par deux - while(x <= number) + while (x <= number) x <<= 1; return x; @@ -268,16 +278,6 @@ inline NzString NzNumberToString(long long number, nzUInt8 radix) return str.Reversed(); } -template -T NzRadians(T radians) -{ - #if NAZARA_MATH_ANGLE_RADIAN - return radians; - #else - return NzRadianToDegree(radians); - #endif -} - template T NzRadianToDegree(T radians) { @@ -333,6 +333,26 @@ inline long long NzStringToNumber(NzString str, nzUInt8 radix, bool* ok) return (negative) ? -static_cast(total) : total; } +template +constexpr T NzToDegrees(T angle) +{ + #if NAZARA_MATH_ANGLE_RADIAN + return NzRadianToDegree(angle); + #else + return angle; + #endif +} + +template +constexpr T NzToRadians(T angle) +{ + #if NAZARA_MATH_ANGLE_RADIAN + return angle; + #else + return NzDegreeToRadian(angle); + #endif +} + #undef F2 #undef F diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index 8348a5e2f..e62ed166f 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -265,14 +265,14 @@ NzEulerAngles NzQuaternion::ToEulerAngles() const T test = x*y + z*w; if (test > F(0.499)) // singularity at north pole - return NzEulerAngles(NzDegrees(F(90.0)), NzRadians(F(2.0) * std::atan2(x, w)), F(0.0)); + return NzEulerAngles(NzFromDegrees(F(90.0)), NzFromRadians(F(2.0) * std::atan2(x, w)), F(0.0)); if (test < F(-0.499)) - return NzEulerAngles(NzDegrees(F(-90.0)), NzRadians(F(-2.0) * std::atan2(x, w)), F(0.0)); + return NzEulerAngles(NzFromDegrees(F(-90.0)), NzFromRadians(F(-2.0) * std::atan2(x, w)), F(0.0)); - return NzEulerAngles(NzRadians(std::atan2(F(2.0)*x*w - F(2.0)*y*z, F(1.0) - F(2.0)*x* - F(2.0)*z*z)), - NzRadians(std::atan2(F(2.0)*y*w - F(2.0)*x*z, F(1.0) - F(2.0)*y*y - F(2.0)*z*z)), - NzRadians(std::asin(F(2.0)*test))); + return NzEulerAngles(NzFromRadians(std::atan2(F(2.0)*x*w - F(2.0)*y*z, F(1.0) - F(2.0)*x* - F(2.0)*z*z)), + NzFromRadians(std::atan2(F(2.0)*y*w - F(2.0)*x*z, F(1.0) - F(2.0)*y*y - F(2.0)*z*z)), + NzFromRadians(std::asin(F(2.0)*test))); } template diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index f97786610..81e25ac51 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -69,7 +69,7 @@ inline unsigned int NzVector2::AbsDotProduct(const NzVector2 T NzVector2::AngleBetween(const NzVector2& vec) const { - return NzRadians(std::atan2(vec.y, vec.x) - std::atan2(y, x)); + return NzFromRadians(std::atan2(vec.y, vec.x) - std::atan2(y, x)); } template diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index fb395a748..1e09a2af3 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -89,7 +89,7 @@ T NzVector3::AngleBetween(const NzVector3& vec) const #endif T alpha = DotProduct(vec)/divisor; - return NzRadians(std::acos(NzClamp(alpha, F(-1.0), F(1.0)))); + return NzFromRadians(std::acos(NzClamp(alpha, F(-1.0), F(1.0)))); } template diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index dc90f9e77..2736e7e32 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -8,6 +8,8 @@ #include #include +///TODO: Rendre les billboards via Deferred Shading si possible + namespace { enum ResourceType @@ -25,16 +27,49 @@ m_forwardQueue(forwardQueue) void NzDeferredRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color) { - ///TODO: Rendre les billboards via Deferred Shading si possible m_forwardQueue->AddBillboard(material, position, size, sinCos, color); } void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) { - ///TODO: Rendre les billboards via Deferred Shading si possible m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); } +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) +{ + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); +} + +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) +{ + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); +} + +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) +{ + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); +} + +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) +{ + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); +} + +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) +{ + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); +} + +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) +{ + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); +} + +void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) +{ + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); +} + void NzDeferredRenderQueue::AddDrawable(const NzDrawable* drawable) { m_forwardQueue->AddDrawable(drawable); diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index 3b0a7e4a3..37d41cb5c 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -72,6 +72,212 @@ void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned in } } +void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + + if (!sinCosPtr) + sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + float defaultAlpha = 1.f; + + if (!alphaPtr) + alphaPtr.Reset(&defaultAlpha, 0); // Pareil + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos = *sinCosPtr++; + billboardData->size = *sizePtr++; + billboardData++; + } +} + +void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) +{ + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + float defaultRotation = 0.f; + + if (!anglePtr) + anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + if (!colorPtr) + colorPtr.Reset(&NzColor::White, 0); // Pareil + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(NzToRadians(*anglePtr)); + float cos = std::cos(NzToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos.Set(sin, cos); + billboardData->size = *sizePtr++; + billboardData++; + } +} + +void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + float defaultRotation = 0.f; + + if (!anglePtr) + anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + float defaultAlpha = 1.f; + + if (!alphaPtr) + alphaPtr.Reset(&defaultAlpha, 0); // Pareil + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(NzToRadians(*anglePtr)); + float cos = std::cos(NzToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos.Set(sin, cos); + billboardData->size = *sizePtr++; + billboardData++; + } +} + +void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) +{ + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + + if (!sinCosPtr) + sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + if (!colorPtr) + colorPtr.Reset(&NzColor::White, 0); // Pareil + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos = *sinCosPtr++; + billboardData->size.Set(*sizePtr++); + billboardData++; + } +} + +void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1 + + if (!sinCosPtr) + sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + float defaultAlpha = 1.f; + + if (!alphaPtr) + alphaPtr.Reset(&defaultAlpha, 0); // Pareil + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos = *sinCosPtr++; + billboardData->size.Set(*sizePtr++); + billboardData++; + } +} + +void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr colorPtr) +{ + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + float defaultRotation = 0.f; + + if (!anglePtr) + anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + if (!colorPtr) + colorPtr.Reset(&NzColor::White, 0); // Pareil + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(NzToRadians(*anglePtr)); + float cos = std::cos(NzToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos.Set(sin, cos); + billboardData->size.Set(*sizePtr++); + billboardData++; + } +} + +void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr anglePtr, NzSparsePtr alphaPtr) +{ + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + float defaultRotation = 0.f; + + if (!anglePtr) + anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile + + float defaultAlpha = 1.f; + + if (!alphaPtr) + alphaPtr.Reset(&defaultAlpha, 0); // Pareil + + std::vector& billboardVec = billboards[material]; + unsigned int prevSize = billboardVec.size(); + billboardVec.resize(prevSize + count); + + BillboardData* billboardData = &billboardVec[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(NzToRadians(*anglePtr)); + float cos = std::cos(NzToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = NzColor(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos.Set(sin, cos); + billboardData->size.Set(*sizePtr++); + billboardData++; + } +} + void NzForwardRenderQueue::AddDrawable(const NzDrawable* drawable) { #if NAZARA_GRAPHICS_SAFE @@ -231,7 +437,7 @@ void NzForwardRenderQueue::Sort(const NzAbstractViewer* viewer) { const NzMaterial* mat = pair.first; - if (mat->IsEnabled(nzRendererParameter_Blend)) + if (mat->IsDepthSortingEnabled()) { BatchedBillboardEntry& entry = pair.second; auto& billboardVector = entry.billboards; diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 1cea892fd..1933d0414 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -138,6 +138,11 @@ void NzMaterial::EnableAlphaTest(bool alphaTest) InvalidateShaders(); } +void NzMaterial::EnableDepthSorting(bool depthSorting) +{ + m_depthSortingEnabled = depthSorting; +} + void NzMaterial::EnableLighting(bool lighting) { m_lightingEnabled = lighting; @@ -306,6 +311,11 @@ bool NzMaterial::IsAlphaTestEnabled() const return m_alphaTestEnabled; } +bool NzMaterial::IsDepthSortingEnabled() const +{ + return m_depthSortingEnabled; +} + bool NzMaterial::IsEnabled(nzRendererParameter parameter) const { #ifdef NAZARA_DEBUG @@ -362,6 +372,7 @@ void NzMaterial::Reset() m_alphaThreshold = 0.2f; m_alphaTestEnabled = false; m_ambientColor = NzColor(128, 128, 128); + m_depthSortingEnabled = false; m_diffuseColor = NzColor::White; m_diffuseSampler = NzTextureSampler(); m_lightingEnabled = true;