diff --git a/.gitignore b/.gitignore index 44729e355..fd6451f19 100644 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,7 @@ *.out # Windows image file caches -Thumbs.db +Thumbs.db # Folder config file Desktop.ini diff --git a/NazaraModuleTemplate/src/Nazara/ModuleName/Debug/Leaks.cpp b/NazaraModuleTemplate/src/Nazara/ModuleName/Debug/Leaks.cpp index 13e396e67..6c4fc1d7d 100644 --- a/NazaraModuleTemplate/src/Nazara/ModuleName/Debug/Leaks.cpp +++ b/NazaraModuleTemplate/src/Nazara/ModuleName/Debug/Leaks.cpp @@ -7,22 +7,22 @@ #include #include -void* operator new(std::size_t size) throw(std::bad_alloc) +void* operator new(std::size_t size) { return NzMemoryManager::Allocate(size, false); } -void* operator new[](std::size_t size) throw(std::bad_alloc) +void* operator new[](std::size_t size) { return NzMemoryManager::Allocate(size, true); } -void operator delete(void* pointer) throw() +void operator delete(void* pointer) noexcept { NzMemoryManager::Free(pointer, false); } -void operator delete[](void* pointer) throw() +void operator delete[](void* pointer) noexcept { NzMemoryManager::Free(pointer, true); } diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 220bd104c..d2df3aa9a 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -32,5 +32,8 @@ configuration "*Static" configuration "*DLL" kind "SharedLib" +configuration "gmake" + buildoptions "-std=c++11" + configuration { "linux or bsd or macosx", "gmake" } buildoptions "-fvisibility=hidden" \ No newline at end of file diff --git a/include/Nazara/Core/Color.hpp b/include/Nazara/Core/Color.hpp index 7a3b59f42..609fae5ae 100644 --- a/include/Nazara/Core/Color.hpp +++ b/include/Nazara/Core/Color.hpp @@ -47,15 +47,15 @@ class NzColor nzUInt8 r, g, b, a; - static const NzColor Black; - static const NzColor Blue; - static const NzColor Cyan; - static const NzColor Green; - static const NzColor Magenta; - static const NzColor Orange; - static const NzColor Red; - static const NzColor Yellow; - static const NzColor White; + static NAZARA_API const NzColor Black; + static NAZARA_API const NzColor Blue; + static NAZARA_API const NzColor Cyan; + static NAZARA_API const NzColor Green; + static NAZARA_API const NzColor Magenta; + static NAZARA_API const NzColor Orange; + static NAZARA_API const NzColor Red; + static NAZARA_API const NzColor Yellow; + static NAZARA_API const NzColor White; private: static float Hue2RGB(float v1, float v2, float vH); diff --git a/include/Nazara/Math/Cube.hpp b/include/Nazara/Math/Cube.hpp index bbc98dae4..57aacdf77 100644 --- a/include/Nazara/Math/Cube.hpp +++ b/include/Nazara/Math/Cube.hpp @@ -8,6 +8,7 @@ #define NAZARA_CUBE_HPP #include +#include #include template @@ -17,6 +18,7 @@ class NzCube NzCube(); NzCube(T X, T Y, T Z, T Width, T Height, T Depth); NzCube(T cube[6]); + NzCube(const NzRect& rect); template explicit NzCube(const NzCube& rect); NzCube(const NzCube& rect) = default; ~NzCube() = default; diff --git a/include/Nazara/Math/Cube.inl b/include/Nazara/Math/Cube.inl index f281dc824..5fc3b0c2d 100644 --- a/include/Nazara/Math/Cube.inl +++ b/include/Nazara/Math/Cube.inl @@ -33,6 +33,17 @@ depth(vec[5]) { } +template +NzCube::NzCube(const NzRect& rect) : +x(rect.x), +y(rect.y), +z(0), +width(rect.width), +height(rect.height), +depth(1) +{ +} + template template NzCube::NzCube(const NzCube& rect) : diff --git a/include/Nazara/Math/Matrix4.hpp b/include/Nazara/Math/Matrix4.hpp index f53ad1499..5b6e5878c 100644 --- a/include/Nazara/Math/Matrix4.hpp +++ b/include/Nazara/Math/Matrix4.hpp @@ -96,17 +96,12 @@ template class NzMatrix4 struct SharedMatrix { - SharedMatrix() : // Vivement GCC 4.7 sur Windows - refCount(1) - { - } - T m11, m12, m13, m14; T m21, m22, m23, m24; T m31, m32, m33, m34; T m41, m42, m43, m44; - unsigned short refCount; + unsigned short refCount = 1; NazaraMutex(mutex) }; diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index fca54c880..708190ad8 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -107,7 +107,7 @@ NzMatrix4 NzMatrix4::GetInverse() const NzMatrix4 matrix; T det = GetDeterminant(); - if (det != 0.0) + if (!NzNumberEquals(det, static_cast(0.0))) { matrix(0, 0) = (m_sharedMatrix->m22 * (m_sharedMatrix->m33 * m_sharedMatrix->m44 - m_sharedMatrix->m34 * m_sharedMatrix->m43) - m_sharedMatrix->m32 * (m_sharedMatrix->m23 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m24) + m_sharedMatrix->m42 * (m_sharedMatrix->m23 * m_sharedMatrix->m34 - m_sharedMatrix->m33 * m_sharedMatrix->m24)) / det; matrix(0, 1) = -(m_sharedMatrix->m12 * (m_sharedMatrix->m33 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m34) - m_sharedMatrix->m32 * (m_sharedMatrix->m13 * m_sharedMatrix->m44 - m_sharedMatrix->m43 * m_sharedMatrix->m14) + m_sharedMatrix->m42 * (m_sharedMatrix->m13 * m_sharedMatrix->m34 - m_sharedMatrix->m33 * m_sharedMatrix->m14)) / det; diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index a49fbde81..afba1dd72 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -217,15 +217,15 @@ NzQuaternion NzQuaternion::Slerp(const NzQuaternion& quatA, const NzQuater k1 = std::sin(interp * omega) * sinOmega; } - /* interpolate and return new quaternion */ NzQuaternion result(k0 * quatA.w, k0 * quatA.x, k0 * quatA.y, k0 * quatA.z); - return result += q; } template NzEulerAngles NzQuaternion::ToEulerAngles() const { + Normalize(); + T test = x*y + z*w; if (test > 0.499) // singularity at north pole diff --git a/include/Nazara/Math/Vector2.hpp b/include/Nazara/Math/Vector2.hpp index ec12330c0..6473d7206 100644 --- a/include/Nazara/Math/Vector2.hpp +++ b/include/Nazara/Math/Vector2.hpp @@ -22,12 +22,14 @@ template class NzVector2 T AbsDotProduct(const NzVector2& vec) const; T Distance(const NzVector2& vec) const; + float Distancef(const NzVector2& vec) const; T DotProduct(const NzVector2& vec) const; NzVector2 GetNormal() const; void MakeCeil(const NzVector2& vec); void MakeFloor(const NzVector2& vec); T Length() const; - T Normalize(); + float Lengthf() const; + void Normalize(); T SquaredDistance(const NzVector2& vec) const; T SquaredLength() const; diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index d8214981c..3889aaa78 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -49,7 +49,14 @@ T NzVector2::AbsDotProduct(const NzVector2& vec) const return std::fabs(x * vec.x) + std::fabs(y * vec.y); } -template<> inline int NzVector2::AbsDotProduct(const NzVector2& vec) const +template<> +inline int NzVector2::AbsDotProduct(const NzVector2& vec) const +{ + return std::labs(x * vec.x) + std::labs(y * vec.y); +} + +template<> +inline unsigned int NzVector2::AbsDotProduct(const NzVector2& vec) const { return std::labs(x * vec.x) + std::labs(y * vec.y); } @@ -60,6 +67,12 @@ T NzVector2::Distance(const NzVector2& vec) const return std::sqrt(SquaredDistance(vec)); } +template +float NzVector2::Distancef(const NzVector2& vec) const +{ + return std::sqrt(static_cast(SquaredDistance(vec))); +} + template T NzVector2::DotProduct(const NzVector2& vec) const { @@ -102,17 +115,21 @@ T NzVector2::Length() const } template -T NzVector2::Normalize() +float NzVector2::Lengthf() const { - T length = Length(); + return std::sqrt(static_cast(SquaredLength())); +} - if (length != 0.f) +template +void NzVector2::Normalize() +{ + auto length = Length(); + + if (!NzNumberEquals(length, static_cast(0.0))) { x /= length; y /= length; } - - return length; } template @@ -214,7 +231,7 @@ NzVector2 NzVector2::operator*(T scale) const template NzVector2 NzVector2::operator/(const NzVector2& vec) const { - if (vec.x == 0.f || vec.y == 0.f) + if (NzNumberEquals(vec.x, static_cast(0.0)) || NzNumberEquals(vec.y, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; @@ -228,7 +245,7 @@ NzVector2 NzVector2::operator/(const NzVector2& vec) const template NzVector2 NzVector2::operator/(T scale) const { - if (scale == 0.f) + if (NzNumberEquals(scale, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; @@ -278,7 +295,7 @@ NzVector2& NzVector2::operator*=(T scale) template NzVector2& NzVector2::operator/=(const NzVector2& vec) { - if (vec.x == 0.f || vec.y == 0.f) + if (NzNumberEquals(vec.x, static_cast(0.0)) || NzNumberEquals(vec.y, static_cast(0.0)) || NzNumberEquals(vec.z, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; @@ -295,7 +312,7 @@ NzVector2& NzVector2::operator/=(const NzVector2& vec) template NzVector2& NzVector2::operator/=(T scale) { - if (scale == 0.f) + if (NzNumberEquals(scale, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; @@ -361,7 +378,7 @@ NzVector2 operator*(T scale, const NzVector2& vec) template NzVector2 operator/(T scale, const NzVector2& vec) { - if (vec.x == 0.f || vec.y == 0.f) + if (NzNumberEquals(vec.x, static_cast(0.0)) || NzNumberEquals(vec.y, static_cast(0.0)) || NzNumberEquals(vec.z, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index 563ec83c8..04e3834c2 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -8,6 +8,7 @@ #define NAZARA_VECTOR3_HPP #include +#include template class NzVector3 { @@ -16,6 +17,7 @@ template class NzVector3 NzVector3(T X, T Y, T Z); explicit NzVector3(T scale); NzVector3(T vec[3]); + NzVector3(const NzVector2& vec); template explicit NzVector3(const NzVector3& vec); NzVector3(const NzVector3& vec) = default; ~NzVector3() = default; @@ -23,12 +25,14 @@ template class NzVector3 T AbsDotProduct(const NzVector3& vec) const; NzVector3 CrossProduct(const NzVector3& vec) const; T Distance(const NzVector3& vec) const; + float Distancef(const NzVector3& vec) const; T DotProduct(const NzVector3& vec) const; NzVector3 GetNormal() const; void MakeCeil(const NzVector3& vec); void MakeFloor(const NzVector3& vec); T Length() const; - T Normalize(); + float Lengthf() const; + void Normalize(); T SquaredDistance(const NzVector3& vec) const; T SquaredLength() const; @@ -77,6 +81,7 @@ template NzVector3 operator/(T scale, const NzVector3& vec); typedef NzVector3 NzVector3d; typedef NzVector3 NzVector3f; typedef NzVector3 NzVector3i; +typedef NzVector3 NzVector3ui; #include diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index 30c1e15e4..73eff32fe 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -38,6 +38,14 @@ z(vec[2]) { } +template +NzVector3::NzVector3(const NzVector2& vec) : +x(vec.x), +y(vec.y), +z(0) +{ +} + template template NzVector3::NzVector3(const NzVector3& vec) : @@ -53,7 +61,14 @@ T NzVector3::AbsDotProduct(const NzVector3& vec) const return std::fabs(x * vec.x) + std::fabs(y * vec.y) + std::fabs(z * vec.z); } -template<> inline int NzVector3::AbsDotProduct(const NzVector3& vec) const +template<> +inline int NzVector3::AbsDotProduct(const NzVector3& vec) const +{ + return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z); +} + +template<> +inline unsigned int NzVector3::AbsDotProduct(const NzVector3& vec) const { return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z); } @@ -70,6 +85,12 @@ T NzVector3::Distance(const NzVector3& vec) const return std::sqrt(SquaredDistance(vec)); } +template +float NzVector3::Distancef(const NzVector3& vec) const +{ + return std::sqrt(static_cast(SquaredDistance())); +} + template T NzVector3::DotProduct(const NzVector3& vec) const { @@ -118,18 +139,22 @@ T NzVector3::Length() const } template -T NzVector3::Normalize() +float NzVector3::Lengthf() const +{ + return std::sqrt(static_cast(SquaredLength())); +} + +template +void NzVector3::Normalize() { T length = Length(); - if (length != 0.f) + if (!NzNumberEquals(length, static_cast(0.0))) { x /= length; y /= length; z /= length; } - - return length; } template @@ -231,7 +256,7 @@ NzVector3 NzVector3::operator*(T scale) const template NzVector3 NzVector3::operator/(const NzVector3& vec) const { - if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f) + if (NzNumberEquals(vec.x, static_cast(0.0)) || NzNumberEquals(vec.y, static_cast(0.0)) || NzNumberEquals(vec.z, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; @@ -245,7 +270,7 @@ NzVector3 NzVector3::operator/(const NzVector3& vec) const template NzVector3 NzVector3::operator/(T scale) const { - if (scale == 0.f) + if (NzNumberEquals(scale, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; @@ -299,7 +324,7 @@ NzVector3& NzVector3::operator*=(T scale) template NzVector3& NzVector3::operator/=(const NzVector3& vec) { - if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f) + if (NzNumberEquals(vec.x, static_cast(0.0)) || NzNumberEquals(vec.y, static_cast(0.0)) || NzNumberEquals(vec.z, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; @@ -317,7 +342,7 @@ NzVector3& NzVector3::operator/=(const NzVector3& vec) template NzVector3& NzVector3::operator/=(T scale) { - if (scale == 0.f) + if (NzNumberEquals(scale, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; @@ -385,7 +410,7 @@ NzVector3 operator*(T scale, const NzVector3& vec) template NzVector3 operator/(T scale, const NzVector3& vec) { - if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f) + if (NzNumberEquals(vec.x, static_cast(0.0)) || NzNumberEquals(vec.y, static_cast(0.0)) || NzNumberEquals(vec.z, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; diff --git a/include/Nazara/Math/Vector4.hpp b/include/Nazara/Math/Vector4.hpp index afd108acb..872ac16c0 100644 --- a/include/Nazara/Math/Vector4.hpp +++ b/include/Nazara/Math/Vector4.hpp @@ -8,6 +8,7 @@ #define NAZARA_VECTOR4_HPP #include +#include template class NzVector4 { @@ -17,6 +18,7 @@ template class NzVector4 explicit NzVector4(T scale); NzVector4(T vec[4]); template explicit NzVector4(const NzVector4& vec); + NzVector4(const NzVector3& vec, T W = 1.0); NzVector4(const NzVector4& vec) = default; ~NzVector4() = default; diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index 3ee1f4165..6620c7f35 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -51,13 +51,29 @@ w(static_cast(vec.w)) { } +template +NzVector4::NzVector4(const NzVector3& vec, T W) : +x(vec.x), +y(vec.y), +z(vec.z), +w(W) +{ +} + template T NzVector4::AbsDotProduct(const NzVector4& vec) const { return std::fabs(x * vec.x) + std::fabs(y * vec.y) + std::fabs(z * vec.z) + std::fabs(w * vec.w); } -template<> inline int NzVector4::AbsDotProduct(const NzVector4& vec) const +template<> +inline int NzVector4::AbsDotProduct(const NzVector4& vec) const +{ + return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z) + std::labs(w * vec.w); +} + +template<> +inline unsigned int NzVector4::AbsDotProduct(const NzVector4& vec) const { return std::labs(x * vec.x) + std::labs(y * vec.y) + std::labs(z * vec.z) + std::labs(w * vec.w); } @@ -103,7 +119,7 @@ void NzVector4::MakeFloor(const NzVector4& vec) template void NzVector4::Normalize() { - if (w != 0.f) + if (!NzNumberEquals(w, static_cast(0.0))) { x /= w; y /= w; @@ -116,7 +132,7 @@ NzString NzVector4::ToString() const { NzStringStream ss; - return ss << "Vector4(" << x << ", " << y << ", " << z <<')'; + return ss << "Vector4(" << x << ", " << y << ", " << z << ", " << w << ')'; } template @@ -180,7 +196,7 @@ NzVector4 NzVector4::operator+(const NzVector4& vec) const template NzVector4 NzVector4::operator-(const NzVector4& vec) const { - return NzVector4(x - vec.x, y - vec.y, z - vec.z); + return NzVector4(x - vec.x, y - vec.y, z - vec.z, w - vec.w); } template @@ -198,7 +214,7 @@ NzVector4 NzVector4::operator*(T scale) const template NzVector4 NzVector4::operator/(const NzVector4& vec) const { - if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f || vec.w == 0.f) + if (NzNumberEquals(vec.x, static_cast(0.0)) || NzNumberEquals(vec.y, static_cast(0.0)) || NzNumberEquals(vec.z, static_cast(0.0)) || NzNumberEquals(vec.w, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; @@ -212,7 +228,7 @@ NzVector4 NzVector4::operator/(const NzVector4& vec) const template NzVector4 NzVector4::operator/(T scale) const { - if (scale == 0.f) + if (NzNumberEquals(scale, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; @@ -270,7 +286,7 @@ NzVector4& NzVector4::operator*=(T scale) template NzVector4& NzVector4::operator/=(const NzVector4& vec) { - if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f || vec.w == 0.f) + if (NzNumberEquals(vec.x, static_cast(0.0)) || NzNumberEquals(vec.y, static_cast(0.0)) || NzNumberEquals(vec.z, static_cast(0.0)) || NzNumberEquals(vec.w, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; @@ -289,7 +305,7 @@ NzVector4& NzVector4::operator/=(const NzVector4& vec) template NzVector4& NzVector4::operator/=(T scale) { - if (scale == 0.f) + if (NzNumberEquals(scale, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; @@ -359,7 +375,7 @@ NzVector4 operator*(T scale, const NzVector4& vec) template NzVector4 operator/(T scale, const NzVector4& vec) { - if (vec.x == 0.f || vec.y == 0.f || vec.z == 0.f || vec.w == 0.f) + if (NzNumberEquals(vec.x, static_cast(0.0)) || NzNumberEquals(vec.y, static_cast(0.0)) || NzNumberEquals(vec.z, static_cast(0.0)) || NzNumberEquals(vec.w, static_cast(0.0))) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << ": Division by zero"; diff --git a/include/Nazara/Prerequesites.hpp b/include/Nazara/Prerequesites.hpp index 8acfc19f5..0691fc975 100644 --- a/include/Nazara/Prerequesites.hpp +++ b/include/Nazara/Prerequesites.hpp @@ -5,10 +5,9 @@ #ifndef NAZARA_PREREQUESITES_HPP #define NAZARA_PREREQUESITES_HPP -// (Commenté en attendant GCC 4.7) -/*#if __cplusplus < 201103L +#if __cplusplus < 201103L #error Nazara requires a C++11 compliant compiler -#endif*/ +#endif // Version du moteur #define NAZARA_VERSION_MAJOR 0 diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index 0deb0b068..8f5e92d85 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -46,6 +46,7 @@ class NAZARA_API NzOpenGL Count }; + static NzOpenGLFunc GetEntry(const NzString& entryPoint); static unsigned int GetVersion(); static bool Initialize(); static bool IsSupported(Extension extension); @@ -131,6 +132,7 @@ NAZARA_API extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; NAZARA_API extern PFNGLLINKPROGRAMPROC glLinkProgram; NAZARA_API extern PFNGLMAPBUFFERPROC glMapBuffer; NAZARA_API extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange; +NAZARA_API extern PFNGLPIXELSTOREIPROC glPixelStorei; NAZARA_API extern PFNGLPOLYGONMODEPROC glPolygonMode; NAZARA_API extern PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d; NAZARA_API extern PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f; diff --git a/include/Nazara/Utility/Config.hpp b/include/Nazara/Utility/Config.hpp index be9b3a8bf..a7d025626 100644 --- a/include/Nazara/Utility/Config.hpp +++ b/include/Nazara/Utility/Config.hpp @@ -36,6 +36,6 @@ #define NAZARA_UTILITY_SAFE 1 // Fait tourner chaque fenêtre dans un thread séparé si le système le supporte -#define NAZARA_UTILITY_THREADED_WINDOW 1 +#define NAZARA_UTILITY_THREADED_WINDOW 0 ///FIXME: Buggé depuis GCC 4.7 #endif // NAZARA_CONFIG_UTILITY_HPP diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index 296179ae5..71cddbaa3 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -19,12 +20,12 @@ enum nzCubemapFace { - nzCubemapFace_PositiveX, - nzCubemapFace_NegativeX, - nzCubemapFace_PositiveY, - nzCubemapFace_NegativeY, - nzCubemapFace_PositiveZ, - nzCubemapFace_NegativeZ + nzCubemapFace_PositiveX = 0, + nzCubemapFace_NegativeX = 1, + nzCubemapFace_PositiveY = 2, + nzCubemapFace_NegativeY = 3, + nzCubemapFace_PositiveZ = 4, + nzCubemapFace_NegativeZ = 5 }; enum nzImageType @@ -39,15 +40,8 @@ enum nzImageType struct NzImageParams { - // GCC 4.7 je te veux - NzImageParams() : - loadFormat(nzPixelFormat_Undefined), - levelCount(0) - { - } - - nzPixelFormat loadFormat; - nzUInt8 levelCount; + nzPixelFormat loadFormat = nzPixelFormat_Undefined; + nzUInt8 levelCount = 0; bool IsValid() const { @@ -70,22 +64,27 @@ class NAZARA_API NzImage : public NzResource, public NzResourceLoader #include -void* operator new(std::size_t size) throw(std::bad_alloc) +void* operator new(std::size_t size) { return NzMemoryManager::Allocate(size, false); } -void* operator new[](std::size_t size) throw(std::bad_alloc) +void* operator new[](std::size_t size) { return NzMemoryManager::Allocate(size, true); } -void operator delete(void* pointer) throw() +void operator delete(void* pointer) noexcept { NzMemoryManager::Free(pointer, false); } -void operator delete[](void* pointer) throw() +void operator delete[](void* pointer) noexcept { NzMemoryManager::Free(pointer, true); } diff --git a/src/Nazara/Core/Debug/Leaks.cpp b/src/Nazara/Core/Debug/Leaks.cpp index 97811836a..732b99a20 100644 --- a/src/Nazara/Core/Debug/Leaks.cpp +++ b/src/Nazara/Core/Debug/Leaks.cpp @@ -7,22 +7,22 @@ #include #include -void* operator new(std::size_t size) throw(std::bad_alloc) +void* operator new(std::size_t size) { return NzMemoryManager::Allocate(size, false); } -void* operator new[](std::size_t size) throw(std::bad_alloc) +void* operator new[](std::size_t size) { return NzMemoryManager::Allocate(size, true); } -void operator delete(void* pointer) throw() +void operator delete(void* pointer) noexcept { NzMemoryManager::Free(pointer, false); } -void operator delete[](void* pointer) throw() +void operator delete[](void* pointer) noexcept { NzMemoryManager::Free(pointer, true); } diff --git a/src/Nazara/Core/Debug/MemoryLeakTracker.cpp b/src/Nazara/Core/Debug/MemoryLeakTracker.cpp index bdf0daba2..08fce3532 100644 --- a/src/Nazara/Core/Debug/MemoryLeakTracker.cpp +++ b/src/Nazara/Core/Debug/MemoryLeakTracker.cpp @@ -73,7 +73,7 @@ void* NzMemoryManager::Allocate(std::size_t size, bool multi, const char* file, Block* ptr = reinterpret_cast(std::malloc(size+sizeof(Block))); if (!ptr) - return nullptr; + return nullptr; // Impossible d'envoyer une exception car cela allouerait de la mémoire avec new (boucle infinie) ptr->array = multi; ptr->file = file; diff --git a/src/Nazara/Core/Win32/ThreadImpl.cpp b/src/Nazara/Core/Win32/ThreadImpl.cpp index 6e8db44c6..b38b6304f 100644 --- a/src/Nazara/Core/Win32/ThreadImpl.cpp +++ b/src/Nazara/Core/Win32/ThreadImpl.cpp @@ -65,7 +65,7 @@ void NzThreadImpl::Terminate() TerminateThread(m_thread, 0); } -unsigned int _stdcall NzThreadImpl::ThreadProc(void* userdata) +unsigned int __stdcall NzThreadImpl::ThreadProc(void* userdata) { NzThread* owner = reinterpret_cast(userdata); NzFunctor* func = owner->m_func; diff --git a/src/Nazara/Core/Win32/ThreadImpl.hpp b/src/Nazara/Core/Win32/ThreadImpl.hpp index eed45a31b..2e7cbd8ce 100644 --- a/src/Nazara/Core/Win32/ThreadImpl.hpp +++ b/src/Nazara/Core/Win32/ThreadImpl.hpp @@ -29,7 +29,7 @@ class NzThreadImpl void Terminate(); private: - static unsigned int _stdcall ThreadProc(void* userdata); + static unsigned int __stdcall ThreadProc(void* userdata); HANDLE m_thread; unsigned int m_threadId; diff --git a/src/Nazara/Network/Debug/Leaks.cpp b/src/Nazara/Network/Debug/Leaks.cpp index a6b378ab2..403a969d7 100644 --- a/src/Nazara/Network/Debug/Leaks.cpp +++ b/src/Nazara/Network/Debug/Leaks.cpp @@ -7,22 +7,22 @@ #include #include -void* operator new(std::size_t size) throw(std::bad_alloc) +void* operator new(std::size_t size) { return NzMemoryManager::Allocate(size, false); } -void* operator new[](std::size_t size) throw(std::bad_alloc) +void* operator new[](std::size_t size) { return NzMemoryManager::Allocate(size, true); } -void operator delete(void* pointer) throw() +void operator delete(void* pointer) noexcept { NzMemoryManager::Free(pointer, false); } -void operator delete[](void* pointer) throw() +void operator delete[](void* pointer) noexcept { NzMemoryManager::Free(pointer, true); } diff --git a/src/Nazara/Noise/Debug/Leaks.cpp b/src/Nazara/Noise/Debug/Leaks.cpp index 3e65ef142..aaba6c452 100644 --- a/src/Nazara/Noise/Debug/Leaks.cpp +++ b/src/Nazara/Noise/Debug/Leaks.cpp @@ -7,22 +7,22 @@ #include #include -void* operator new(std::size_t size) throw(std::bad_alloc) +void* operator new(std::size_t size) { return NzMemoryManager::Allocate(size, false); } -void* operator new[](std::size_t size) throw(std::bad_alloc) +void* operator new[](std::size_t size) { return NzMemoryManager::Allocate(size, true); } -void operator delete(void* pointer) throw() +void operator delete(void* pointer) noexcept { NzMemoryManager::Free(pointer, false); } -void operator delete[](void* pointer) throw() +void operator delete[](void* pointer) noexcept { NzMemoryManager::Free(pointer, true); } diff --git a/src/Nazara/Renderer/Buffer.cpp b/src/Nazara/Renderer/Buffer.cpp index 335d13e7e..d5fa5b961 100644 --- a/src/Nazara/Renderer/Buffer.cpp +++ b/src/Nazara/Renderer/Buffer.cpp @@ -145,7 +145,7 @@ void* NzBuffer::GetBufferPtr() if (!m_impl) { NazaraError("Buffer not created"); - return false; + return nullptr; } #endif @@ -158,7 +158,7 @@ const void* NzBuffer::GetBufferPtr() const if (!m_impl) { NazaraError("Buffer not created"); - return false; + return nullptr; } #endif diff --git a/src/Nazara/Renderer/Debug/Leaks.cpp b/src/Nazara/Renderer/Debug/Leaks.cpp index 9fb75777f..ee8f4be88 100644 --- a/src/Nazara/Renderer/Debug/Leaks.cpp +++ b/src/Nazara/Renderer/Debug/Leaks.cpp @@ -7,22 +7,22 @@ #include #include -void* operator new(std::size_t size) throw(std::bad_alloc) +void* operator new(std::size_t size) { return NzMemoryManager::Allocate(size, false); } -void* operator new[](std::size_t size) throw(std::bad_alloc) +void* operator new[](std::size_t size) { return NzMemoryManager::Allocate(size, true); } -void operator delete(void* pointer) throw() +void operator delete(void* pointer) noexcept { NzMemoryManager::Free(pointer, false); } -void operator delete[](void* pointer) throw() +void operator delete[](void* pointer) noexcept { NzMemoryManager::Free(pointer, true); } diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 401499ef6..d6144728d 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -102,6 +102,11 @@ namespace } } +NzOpenGLFunc NzOpenGL::GetEntry(const NzString& entryPoint) +{ + return LoadEntry(entryPoint.GetConstBuffer(), false); +} + unsigned int NzOpenGL::GetVersion() { return openGLversion; @@ -262,6 +267,7 @@ bool NzOpenGL::Initialize() glGetUniformLocation = reinterpret_cast(LoadEntry("glGetUniformLocation")); glLinkProgram = reinterpret_cast(LoadEntry("glLinkProgram")); glMapBuffer = reinterpret_cast(LoadEntry("glMapBuffer")); + glPixelStorei = reinterpret_cast(LoadEntry("glPixelStorei")); glPolygonMode = reinterpret_cast(LoadEntry("glPolygonMode")); glReadPixels = reinterpret_cast(LoadEntry("glReadPixels")); glScissor = reinterpret_cast(LoadEntry("glScissor")); @@ -600,6 +606,7 @@ PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = nullptr; PFNGLLINKPROGRAMPROC glLinkProgram = nullptr; PFNGLMAPBUFFERPROC glMapBuffer = nullptr; PFNGLMAPBUFFERRANGEPROC glMapBufferRange = nullptr; +PFNGLPIXELSTOREIPROC glPixelStorei = nullptr; PFNGLPOLYGONMODEPROC glPolygonMode = nullptr; PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d = nullptr; PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f = nullptr; diff --git a/src/Nazara/Renderer/RenderWindow.cpp b/src/Nazara/Renderer/RenderWindow.cpp index 6891e3aba..1af1c2174 100644 --- a/src/Nazara/Renderer/RenderWindow.cpp +++ b/src/Nazara/Renderer/RenderWindow.cpp @@ -80,8 +80,7 @@ bool NzRenderWindow::CopyToImage(NzImage* image) nzUInt8* pixels = image->GetPixels(); glReadPixels(0, 0, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - for (unsigned int j = 0; j < size.y/2; ++j) - std::swap_ranges(&pixels[j*size.x*4], &pixels[(j+1)*size.x*4-1], &pixels[(size.y-j-1)*size.x*4]); + image->FlipVertically(); return true; } diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index c5eb3e639..8283fc32c 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -13,21 +13,13 @@ struct NzTextureImpl { - // GCC 4.7 !!!!!! - NzTextureImpl() : - isTarget(false), - mipmapping(false), - mipmapsUpdated(true) - { - } - GLuint id; nzImageType type; nzPixelFormat format; nzUInt8 levelCount; - bool isTarget; - bool mipmapping; - bool mipmapsUpdated; + bool isTarget = false; + bool mipmapping = false; + bool mipmapsUpdated = true; unsigned int depth; unsigned int height; unsigned int width; @@ -279,6 +271,18 @@ namespace } } + inline void SetUnpackAlignement(nzUInt8 bpp) + { + if (bpp % 8 == 0) + glPixelStorei(GL_UNPACK_ALIGNMENT, 8); + else if (bpp % 4 == 0) + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); + else if (bpp % 2 == 0) + glPixelStorei(GL_UNPACK_ALIGNMENT, 2); + else + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + } + void UnlockTexture(NzTextureImpl* impl) { #ifdef NAZARA_DEBUG @@ -539,27 +543,11 @@ bool NzTexture::Download(NzImage* image) const unsigned int width = m_impl->width; unsigned int height = m_impl->height; unsigned int depth = m_impl->depth; - nzUInt8 bpp = NzPixelFormat::GetBPP(m_impl->format); - - nzUInt8* mirrored = new nzUInt8[width*height*depth*bpp]; // Téléchargement... for (nzUInt8 level = 0; level < m_impl->levelCount; ++level) { - glGetTexImage(openglTarget[m_impl->type], level, format.dataFormat, format.dataType, mirrored); - - // Inversion de la texture pour le repère d'OpenGL - ///FIXME: Gérer l'inversion dans NzImage, et gérer également les images compressées - unsigned int faceSize = width*height*bpp; - - nzUInt8* ptr = mirrored; - for (unsigned int d = 0; d < depth; ++d) - { - for (unsigned int j = 0; j < height/2; ++j) - std::swap_ranges(&ptr[j*width*bpp], &ptr[(j+1)*width*bpp-1], &ptr[(height-j-1)*width*bpp]); - - ptr += faceSize; - } + glGetTexImage(openglTarget[m_impl->type], level, format.dataFormat, format.dataType, image->GetPixels(level)); if (width > 1) width >>= 1; @@ -573,7 +561,9 @@ bool NzTexture::Download(NzImage* image) const UnlockTexture(m_impl); - delete[] mirrored; + // Inversion de la texture pour le repère d'OpenGL + if (!image->FlipVertically()) + NazaraWarning("Failed to flip image"); return true; } @@ -1138,7 +1128,20 @@ bool NzTexture::Update(const NzImage& image, const NzRectui& rect, unsigned int } #endif - return Update(image.GetConstPixels(level), rect, z, level); + const nzUInt8* pixels = image.GetConstPixels(level, rect.x, rect.y, z); + if (!pixels) + { + NazaraError("Failed to access image's pixels"); + return false; + } + + glPixelStorei(GL_UNPACK_ROW_LENGTH, image.GetWidth(level)); + + bool success = Update(pixels, rect, z, level); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + + return success; } bool NzTexture::Update(const NzImage& image, const NzCubeui& cube, nzUInt8 level) @@ -1157,7 +1160,22 @@ bool NzTexture::Update(const NzImage& image, const NzCubeui& cube, nzUInt8 level } #endif - return Update(image.GetConstPixels(level), cube, level); + const nzUInt8* pixels = image.GetConstPixels(level, cube.x, cube.y, cube.z); + if (!pixels) + { + NazaraError("Failed to access image's pixels"); + return false; + } + + glPixelStorei(GL_UNPACK_ROW_LENGTH, image.GetWidth(level)); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, image.GetHeight(level)); + + bool success = Update(pixels, cube, level); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0); + + return success; } bool NzTexture::Update(const nzUInt8* pixels, nzUInt8 level) @@ -1208,8 +1226,12 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int NazaraError("Invalid rectangle"); return false; } + #endif - if (rect.x+rect.width > std::max(m_impl->width >> level, 1U) || rect.y+rect.height > std::max(m_impl->height >> level, 1U)) + unsigned int height = std::max(m_impl->height >> level, 1U); + + #if NAZARA_RENDERER_SAFE + if (rect.x+rect.width > std::max(m_impl->width >> level, 1U) || rect.y+rect.height > height) { NazaraError("Rectangle dimensions are out of bounds"); return false; @@ -1238,39 +1260,35 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int nzUInt8 bpp = NzPixelFormat::GetBPP(m_impl->format); // Inversion de la texture pour le repère d'OpenGL - ///FIXME: Gérer l'inversion dans NzImage, et gérer également les images compressées - unsigned int size = rect.width*rect.height*bpp; - nzUInt8* mirrored = new nzUInt8[size]; - std::memcpy(mirrored, pixels, size); + NzImage mirrored; + mirrored.Create(m_impl->type, m_impl->format, rect.width, rect.height); + mirrored.Update(pixels); - nzUInt8* ptr = &mirrored[size*z]; - for (unsigned int j = 0; j < rect.height/2; ++j) - std::swap_ranges(&ptr[j*rect.width*bpp], &ptr[(j+1)*rect.width*bpp-1], &ptr[(rect.height-j-1)*rect.width*bpp]); + if (!mirrored.FlipVertically()) + NazaraWarning("Failed to flip image"); + + SetUnpackAlignement(bpp); LockTexture(m_impl); - switch (m_impl->type) { case nzImageType_1D: - glTexSubImage1D(GL_TEXTURE_1D, level, rect.x, rect.width, format.dataFormat, format.dataType, mirrored); + glTexSubImage1D(GL_TEXTURE_1D, level, rect.x, rect.width, format.dataFormat, format.dataType, mirrored.GetConstPixels()); break; case nzImageType_2D: - glTexSubImage2D(GL_TEXTURE_2D, level, rect.x, rect.y, rect.width, rect.height, format.dataFormat, format.dataType, mirrored); + glTexSubImage2D(GL_TEXTURE_2D, level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, mirrored.GetConstPixels()); break; case nzImageType_3D: - glTexSubImage3D(GL_TEXTURE_3D, level, rect.x, rect.y, z, rect.width, rect.height, 1, format.dataFormat, format.dataType, mirrored); + glTexSubImage3D(GL_TEXTURE_3D, level, rect.x, height-rect.height-rect.y, z, rect.width, rect.height, 1, format.dataFormat, format.dataType, mirrored.GetConstPixels()); break; default: NazaraInternalError("Image type not handled (0x" + NzString::Number(m_impl->type, 16) + ')'); } - UnlockTexture(m_impl); - delete[] mirrored; - return true; } @@ -1306,9 +1324,13 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve NazaraError("Invalid rectangle"); return false; } + #endif + unsigned int height = std::max(m_impl->height >> level, 1U); + + #if NAZARA_RENDERER_SAFE if (cube.x+cube.width > std::max(m_impl->width >> level, 1U) || - cube.y+cube.height > std::max(m_impl->height >> level, 1U) || + cube.y+cube.height > height || cube.z+cube.depth > std::max(m_impl->depth >> level, 1U)) { NazaraError("Cube dimensions are out of bounds"); @@ -1332,45 +1354,35 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve nzUInt8 bpp = NzPixelFormat::GetBPP(m_impl->format); // Inversion de la texture pour le repère d'OpenGL - ///FIXME: Gérer l'inversion dans NzImage, et gérer également les images compressées - unsigned int faceSize = cube.width*cube.height*bpp; - unsigned int size = faceSize*cube.depth; - nzUInt8* mirrored = new nzUInt8[size]; - std::memcpy(mirrored, pixels, size); + NzImage mirrored; + mirrored.Create(m_impl->type, m_impl->format, cube.width, cube.height, cube.depth); + mirrored.Update(pixels); - nzUInt8* ptr = mirrored; - for (unsigned int d = 0; d < cube.depth; ++d) - { - for (unsigned int j = 0; j < cube.height/2; ++j) - std::swap_ranges(&ptr[j*cube.width*bpp], &ptr[(j+1)*cube.width*bpp-1], &ptr[(cube.height-j-1)*cube.width*bpp]); + if (!mirrored.FlipVertically()) + NazaraWarning("Failed to flip image"); - ptr += faceSize; - } + SetUnpackAlignement(bpp); LockTexture(m_impl); - switch (m_impl->type) { case nzImageType_1D: - glTexSubImage1D(GL_TEXTURE_1D, level, cube.x, cube.width, format.dataFormat, format.dataType, mirrored); + glTexSubImage1D(GL_TEXTURE_1D, level, cube.x, cube.width, format.dataFormat, format.dataType, mirrored.GetConstPixels()); break; case nzImageType_2D: - glTexSubImage2D(GL_TEXTURE_2D, level, cube.x, cube.y, cube.width, cube.height, format.dataFormat, format.dataType, mirrored); + glTexSubImage2D(GL_TEXTURE_2D, level, cube.x, height-cube.height-cube.y, cube.width, cube.height, format.dataFormat, format.dataType, mirrored.GetConstPixels()); break; case nzImageType_3D: - glTexSubImage3D(GL_TEXTURE_3D, level, cube.x, cube.y, cube.z, cube.width, cube.height, cube.depth, format.dataFormat, format.dataType, mirrored); + glTexSubImage3D(GL_TEXTURE_3D, level, cube.x, height-cube.height-cube.y, cube.z, cube.width, cube.height, cube.depth, format.dataFormat, format.dataType, mirrored.GetConstPixels()); break; default: NazaraInternalError("Image type not handled (0x" + NzString::Number(m_impl->type, 16) + ')'); } - UnlockTexture(m_impl); - delete[] mirrored; - return true; } @@ -1409,7 +1421,13 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const NzImage& image, const NzRec } #endif - return UpdateFace(face, image.GetConstPixels(level), rect, level); + glPixelStorei(GL_UNPACK_ROW_LENGTH, image.GetWidth(level)); + + bool success = UpdateFace(face, image.GetConstPixels(level), rect, level); + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + + return success; } bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, nzUInt8 level) @@ -1457,8 +1475,12 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe NazaraError("Invalid rectangle"); return false; } + #endif - if (rect.x+rect.width > std::max(m_impl->width >> level, 1U) || rect.y+rect.height > std::max(m_impl->height >> level, 1U)) + unsigned int height = std::max(m_impl->height >> level, 1U); + + #if NAZARA_RENDERER_SAFE + if (rect.x+rect.width > std::max(m_impl->width >> level, 1U) || rect.y+rect.height > height) { NazaraError("Rectangle dimensions are out of bounds"); return false; @@ -1481,21 +1503,19 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe nzUInt8 bpp = NzPixelFormat::GetBPP(m_impl->format); // Inversion de la texture pour le repère d'OpenGL - ///FIXME: Gérer l'inversion dans NzImage, et gérer également les images compressées - unsigned int size = rect.width*rect.height*bpp; - nzUInt8* mirrored = new nzUInt8[size]; - std::memcpy(mirrored, pixels, size); - for (unsigned int j = 0; j < rect.height/2; ++j) - std::swap_ranges(&mirrored[j*rect.width*bpp], &mirrored[(j+1)*rect.width*bpp-1], &mirrored[(rect.height-j-1)*rect.width*bpp]); + NzImage mirrored; + mirrored.Create(m_impl->type, m_impl->format, rect.width, rect.height); + mirrored.Update(pixels); + + if (!mirrored.FlipVertically()) + NazaraWarning("Failed to flip image"); + + SetUnpackAlignement(bpp); LockTexture(m_impl); - - glTexSubImage2D(cubemapFace[face], level, rect.x, rect.y, rect.width, rect.height, format.dataFormat, format.dataType, mirrored); - + glTexSubImage2D(cubemapFace[face], level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, mirrored.GetConstPixels()); UnlockTexture(m_impl); - delete[] mirrored; - return true; } diff --git a/src/Nazara/Utility/Debug/Leaks.cpp b/src/Nazara/Utility/Debug/Leaks.cpp index dfb2f33a7..46b4e1abf 100644 --- a/src/Nazara/Utility/Debug/Leaks.cpp +++ b/src/Nazara/Utility/Debug/Leaks.cpp @@ -7,22 +7,22 @@ #include #include -void* operator new(std::size_t size) throw(std::bad_alloc) +void* operator new(std::size_t size) { return NzMemoryManager::Allocate(size, false); } -void* operator new[](std::size_t size) throw(std::bad_alloc) +void* operator new[](std::size_t size) { return NzMemoryManager::Allocate(size, true); } -void operator delete(void* pointer) throw() +void operator delete(void* pointer) noexcept { NzMemoryManager::Free(pointer, false); } -void operator delete[](void* pointer) throw() +void operator delete[](void* pointer) noexcept { NzMemoryManager::Free(pointer, true); } diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index d5a1f08b6..11284bd52 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -9,6 +9,19 @@ #include #include +namespace +{ + inline unsigned int GetLevelSize(unsigned int size, nzUInt8 level) + { + return std::max(size >> level, 1U); + } + + inline nzUInt8* GetPixelPtr(nzUInt8* base, nzUInt8 bpp, unsigned int x, unsigned int y, unsigned int z, unsigned int width, unsigned int height) + { + return &base[(width*(height*z+y) + x) * bpp]; + } +} + NzImage::NzImage() : m_sharedImage(&emptyImage) { @@ -98,13 +111,13 @@ bool NzImage::Convert(nzPixelFormat format) } if (width > 1) - width /= 2; + width >>= 1; if (height > 1) - height /= 2; + height >>= 1; if (depth > 1 && m_sharedImage->type != nzImageType_Cubemap) - depth /= 2; + depth >>= 1; } SharedImage* newImage = new SharedImage(1, m_sharedImage->type, format, m_sharedImage->levelCount, levels, m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); @@ -115,7 +128,7 @@ bool NzImage::Convert(nzPixelFormat format) return true; } -bool NzImage::Copy(const NzImage& source, const NzRectui& srcRect, const NzVector2ui& dstPos) +bool NzImage::Copy(const NzImage& source, const NzCubeui& srcCube, const NzVector3ui& dstPos) { #if NAZARA_UTILITY_SAFE if (!source.IsValid()) @@ -131,29 +144,49 @@ bool NzImage::Copy(const NzImage& source, const NzRectui& srcRect, const NzVecto } #endif - return Update(&source.GetConstPixels()[(srcRect.x + srcRect.y * source.GetHeight()) * source.GetBPP()], - NzRectui(dstPos.x, dstPos.y, srcRect.width, srcRect.height)); -} - -bool NzImage::CopyToFace(nzCubemapFace face, const NzImage& source, const NzRectui& srcRect, const NzVector2ui& dstPos) -{ - #if NAZARA_UTILITY_SAFE - if (!source.IsValid()) + const nzUInt8* pixels = source.GetConstPixels(0, srcCube.x, srcCube.y, srcCube.z); + if (!pixels) { - NazaraError("Source image must be valid"); + NazaraError("Failed to access pixels"); return false; } - if (source.GetFormat() != m_sharedImage->format) - { - NazaraError("Source image format does not match destination image format"); - return false; - } - #endif + /* + Correctif temporaire : Update veut de la mémoire contigüe + Il est donc nécessaire de prendre la partie de la texture que nous voulons mettre à jour - return UpdateFace(face, - &source.GetConstPixels()[(srcRect.x + srcRect.y * source.GetHeight()) * source.GetBPP()], - NzRectui(dstPos.x, dstPos.y, srcRect.width, srcRect.height)); + FIXME: Trouver une interface pour gérer ce genre de problème (Façon OpenGL?) + (Appliquer l'interface à NzTexture également) + */ + nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format); + unsigned int dstLineStride = srcCube.width*bpp; + unsigned int dstFaceStride = dstLineStride*srcCube.height; + unsigned int srcLineStride = m_sharedImage->width*bpp; + unsigned int srcFaceStride = srcLineStride*m_sharedImage->height; + + nzUInt8* cube = new nzUInt8[dstFaceStride*srcCube.depth]; + nzUInt8* ptr = cube; + + for (unsigned int z = 0; z < srcCube.depth; ++z) + { + nzUInt8* facePixels = ptr; + for (unsigned int y = 0; y < srcCube.height; ++y) + { + std::memcpy(facePixels, pixels, dstLineStride); + + facePixels += dstLineStride; + pixels += srcLineStride; + } + + ptr += dstFaceStride; + pixels += srcFaceStride; + } + + bool success = Update(cube, NzCubeui(dstPos.x, dstPos.y, dstPos.z, srcCube.width, srcCube.height, srcCube.depth)); + + delete[] cube; + + return success; } bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount) @@ -233,13 +266,13 @@ bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width, levels[i] = new nzUInt8[w * h * d * NzPixelFormat::GetBPP(format)]; if (w > 1) - w /= 2; + w >>= 1; if (h > 1) - h /= 2; + h >>= 1; if (d > 1 && type != nzImageType_Cubemap) - d /= 2; + d >>= 1; } catch (const std::exception& e) { @@ -263,14 +296,323 @@ void NzImage::Destroy() ReleaseImage(); } +bool NzImage::Fill(const NzColor& color) +{ + #if NAZARA_RENDERER_SAFE + if (!IsValid()) + { + NazaraError("Image must be valid"); + return false; + } + + if (NzPixelFormat::IsCompressed(m_sharedImage->format)) + { + NazaraError("Cannot access pixels from compressed image"); + return false; + } + #endif + + EnsureOwnership(); + + nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format); + nzUInt8* pixels = new nzUInt8[bpp]; + if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, pixels)) + { + NazaraError("Failed to convert RGBA8 to " + NzPixelFormat::ToString(m_sharedImage->format)); + delete[] pixels; + + return false; + } + + unsigned int width = m_sharedImage->width; + unsigned int height = m_sharedImage->height; + unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth; + + for (unsigned int level = 0; level < m_sharedImage->levelCount; ++level) + { + nzUInt8* ptr = &m_sharedImage->pixels[level][0]; + nzUInt8* end = &m_sharedImage->pixels[level][width*height*depth*bpp]; + + while (ptr < end) + { + std::memcpy(ptr, pixels, bpp); + ptr += bpp; + } + + if (width > 1U) + width >>= 1; + + if (height > 1U) + height >>= 1; + + if (depth > 1U && m_sharedImage->type != nzImageType_Cubemap) + depth >>= 1; + } + + delete[] pixels; + + return true; +} + +bool NzImage::Fill(const NzColor& color, const NzRectui& rect, unsigned int z) +{ + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Image must be valid"); + return false; + } + + if (!rect.IsValid()) + { + NazaraError("Invalid rectangle"); + return false; + } + + if (rect.x+rect.width > m_sharedImage->width || rect.y+rect.height > m_sharedImage->height) + { + NazaraError("Rectangle dimensions are out of bounds"); + return false; + } + + unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth; + if (z >= depth) + { + NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')'); + return false; + } + #endif + + EnsureOwnership(); + + nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format); + nzUInt8* pixels = new nzUInt8[bpp]; + if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, pixels)) + { + NazaraError("Failed to convert RGBA8 to " + NzPixelFormat::ToString(m_sharedImage->format)); + delete[] pixels; + + return false; + } + + nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->pixels[0], bpp, rect.x, rect.y, z, m_sharedImage->width, m_sharedImage->height); + unsigned int srcStride = rect.width * bpp; + unsigned int dstStride = m_sharedImage->width * bpp; + for (unsigned int y = 0; y < rect.height; ++y) + { + nzUInt8* start = dstPixels; + nzUInt8* end = dstPixels + srcStride; + while (start < end) + { + std::memcpy(start, pixels, bpp); + start += bpp; + } + + dstPixels += dstStride; + } + + return true; +} + +bool NzImage::Fill(const NzColor& color, const NzCubeui& cube) +{ + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Image must be valid"); + return false; + } + + if (!cube.IsValid()) + { + NazaraError("Invalid rectangle"); + return false; + } + + if (cube.x+cube.width > m_sharedImage->width || cube.y+cube.height > m_sharedImage->height || cube.z+cube.depth > m_sharedImage->depth) + { + NazaraError("Cube dimensions are out of bounds"); + return false; + } + #endif + + EnsureOwnership(); + + nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format); + nzUInt8* pixels = new nzUInt8[bpp]; + if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, pixels)) + { + NazaraError("Failed to convert RGBA8 to " + NzPixelFormat::ToString(m_sharedImage->format)); + delete[] pixels; + + return false; + } + + nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->pixels[0], bpp, cube.x, cube.y, cube.z, m_sharedImage->width, m_sharedImage->height); + unsigned int srcStride = cube.width * bpp; + unsigned int dstStride = m_sharedImage->width * bpp; + unsigned int faceSize = dstStride * m_sharedImage->height; + for (unsigned int z = 0; z < cube.depth; ++z) + { + nzUInt8* facePixels = dstPixels; + for (unsigned int y = 0; y < cube.height; ++y) + { + nzUInt8* start = facePixels; + nzUInt8* end = facePixels + srcStride; + while (start < end) + { + std::memcpy(start, pixels, bpp); + start += bpp; + } + + facePixels += dstStride; + } + + dstPixels += faceSize; + } + + delete[] pixels; + + return true; +} + +bool NzImage::FlipHorizontally() +{ + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Image must be valid"); + return false; + } + + if (NzPixelFormat::IsCompressed(m_sharedImage->format)) + { + NazaraError("Cannot flip compressed image"); + return false; + } + #endif + + EnsureOwnership(); + + nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format); + unsigned int width = m_sharedImage->width; + unsigned int height = m_sharedImage->height; + unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth; + for (unsigned int level = 0; level < m_sharedImage->levelCount; ++level) + { + for (unsigned int z = 0; z < depth; ++z) + { + nzUInt8* ptr = &m_sharedImage->pixels[level][width*height*z]; + unsigned int lineStride = width*bpp; + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width/2; ++x) + std::swap_ranges(&ptr[x*bpp], &ptr[(x+1)*bpp], &ptr[(width-x)*bpp]); + + ptr += lineStride; + } + } + + if (width > 1U) + width >>= 1; + + if (height > 1U) + height >>= 1; + + if (depth > 1U && m_sharedImage->type != nzImageType_Cubemap) + depth >>= 1; + } + + return true; +} + + +bool NzImage::FlipVertically() +{ + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Image must be valid"); + return false; + } + + if (NzPixelFormat::IsCompressed(m_sharedImage->format)) + { + NazaraError("Cannot flip compressed image"); + return false; + } + #endif + + EnsureOwnership(); + + nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format); + unsigned int width = m_sharedImage->width; + unsigned int height = m_sharedImage->height; + unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth; + for (unsigned int level = 0; level < m_sharedImage->levelCount; ++level) + { + for (unsigned int z = 0; z < depth; ++z) + { + nzUInt8* ptr = &m_sharedImage->pixels[level][width*height*z]; + unsigned int lineStride = width*bpp; + for (unsigned int y = 0; y < height/2; ++y) + std::swap_ranges(&ptr[y*lineStride], &ptr[(y+1)*lineStride-1], &ptr[(height-y-1)*lineStride]); + } + + if (width > 1U) + width >>= 1; + + if (height > 1U) + height >>= 1; + + if (depth > 1U && m_sharedImage->type != nzImageType_Cubemap) + depth >>= 1; + } + + return true; +} + nzUInt8 NzImage::GetBPP() const { return NzPixelFormat::GetBPP(m_sharedImage->format); } -const nzUInt8* NzImage::GetConstPixels(nzUInt8 level) const +const nzUInt8* NzImage::GetConstPixels(nzUInt8 level, unsigned int x, unsigned int y, unsigned int z) const { - return m_sharedImage->pixels[level]; + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Image must be valid"); + return nullptr; + } + + if (level >= m_sharedImage->levelCount) + { + NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')'); + return nullptr; + } + + if (x >= m_sharedImage->width) + { + NazaraError("X value exceeds width (" + NzString::Number(x) + " >= (" + NzString::Number(m_sharedImage->width) + ')'); + return nullptr; + } + + if (y >= m_sharedImage->height) + { + NazaraError("Y value exceeds width (" + NzString::Number(y) + " >= (" + NzString::Number(m_sharedImage->height) + ')'); + return nullptr; + } + + unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth; + if (z >= depth) + { + NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')'); + return nullptr; + } + #endif + + return GetPixelPtr(m_sharedImage->pixels[level], NzPixelFormat::GetBPP(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height); } unsigned int NzImage::GetDepth(nzUInt8 level) const @@ -283,7 +625,7 @@ unsigned int NzImage::GetDepth(nzUInt8 level) const } #endif - return std::max(m_sharedImage->depth >> level, 1U); + return GetLevelSize(m_sharedImage->depth, level); } nzPixelFormat NzImage::GetFormat() const @@ -301,7 +643,7 @@ unsigned int NzImage::GetHeight(nzUInt8 level) const } #endif - return std::max(m_sharedImage->height >> level, 1U); + return GetLevelSize(m_sharedImage->height, level); } nzUInt8 NzImage::GetLevelCount() const @@ -314,7 +656,7 @@ nzUInt8 NzImage::GetMaxLevel() const return GetMaxLevel(m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); } -NzColor NzImage::GetPixel(unsigned int x, unsigned int y, unsigned int z) const +NzColor NzImage::GetPixelColor(unsigned int x, unsigned int y, unsigned int z) const { #if NAZARA_UTILITY_SAFE if (!IsValid()) @@ -323,12 +665,6 @@ NzColor NzImage::GetPixel(unsigned int x, unsigned int y, unsigned int z) const return NzColor(); } - if (m_sharedImage->type == nzImageType_Cubemap) - { - NazaraError("GetPixel is not designed for cubemaps, use GetPixelFace instead"); - return NzColor(); - } - if (NzPixelFormat::IsCompressed(m_sharedImage->format)) { NazaraError("Cannot access pixels from compressed image"); @@ -347,14 +683,15 @@ NzColor NzImage::GetPixel(unsigned int x, unsigned int y, unsigned int z) const return NzColor(); } - if (z >= m_sharedImage->depth) + unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth; + if (z >= depth) { - NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(m_sharedImage->depth) + ')'); + NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')'); return NzColor(); } #endif - const nzUInt8* pixel = &m_sharedImage->pixels[0][(m_sharedImage->height*(m_sharedImage->width*z+y) + x) * NzPixelFormat::GetBPP(m_sharedImage->format)]; + const nzUInt8* pixel = GetPixelPtr(m_sharedImage->pixels[0], NzPixelFormat::GetBPP(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height); NzColor color; if (!NzPixelFormat::Convert(m_sharedImage->format, nzPixelFormat_RGBA8, pixel, &color.r)) @@ -363,54 +700,44 @@ NzColor NzImage::GetPixel(unsigned int x, unsigned int y, unsigned int z) const return color; } -NzColor NzImage::GetPixelFace(nzCubemapFace face, unsigned int x, unsigned int y) const +nzUInt8* NzImage::GetPixels(nzUInt8 level, unsigned int x, unsigned int y, unsigned int z) { #if NAZARA_UTILITY_SAFE if (!IsValid()) { NazaraError("Image must be valid"); - return NzColor(); + return nullptr; } - if (m_sharedImage->type != nzImageType_Cubemap) + if (level >= m_sharedImage->levelCount) { - NazaraError("GetPixelFace is designed for cubemaps, use GetPixel instead"); - return NzColor(); - } - - if (NzPixelFormat::IsCompressed(m_sharedImage->format)) - { - NazaraError("Cannot access pixels from compressed image"); - return NzColor(); + NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')'); + return nullptr; } if (x >= m_sharedImage->width) { NazaraError("X value exceeds width (" + NzString::Number(x) + " >= (" + NzString::Number(m_sharedImage->width) + ')'); - return NzColor(); + return nullptr; } if (y >= m_sharedImage->height) { NazaraError("Y value exceeds width (" + NzString::Number(y) + " >= (" + NzString::Number(m_sharedImage->height) + ')'); - return NzColor(); + return nullptr; + } + + unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth; + if (z >= depth) + { + NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')'); + return nullptr; } #endif - const nzUInt8* pixel = &m_sharedImage->pixels[0][(m_sharedImage->height*(m_sharedImage->width*(face-nzCubemapFace_PositiveX)+y) + x) * NzPixelFormat::GetBPP(m_sharedImage->format)]; - - NzColor color; - if (!NzPixelFormat::Convert(m_sharedImage->format, nzPixelFormat_RGBA8, pixel, &color.r)) - NazaraError("Failed to convert image's format to RGBA8"); - - return color; -} - -nzUInt8* NzImage::GetPixels(nzUInt8 level) -{ EnsureOwnership(); - return m_sharedImage->pixels[level]; + return GetPixelPtr(m_sharedImage->pixels[level], NzPixelFormat::GetBPP(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height); } unsigned int NzImage::GetSize() const @@ -425,13 +752,13 @@ unsigned int NzImage::GetSize() const size += width * height * depth; if (width > 1) - width /= 2; + width >>= 1; if (height > 1) - height /= 2; + height >>= 1; if (depth > 1) - depth /= 2; + depth >>= 1; } if (m_sharedImage->type == nzImageType_Cubemap) @@ -450,9 +777,9 @@ unsigned int NzImage::GetSize(nzUInt8 level) const } #endif - return (std::max(m_sharedImage->width >> level, 1U)) * - (std::max(m_sharedImage->height >> level, 1U)) * - ((m_sharedImage->type == nzImageType_Cubemap) ? 6 : std::max(m_sharedImage->depth >> level, 1U)) * + return (GetLevelSize(m_sharedImage->width, level)) * + (GetLevelSize(m_sharedImage->height, level)) * + ((m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level)) * NzPixelFormat::GetBPP(m_sharedImage->format); } @@ -471,7 +798,7 @@ unsigned int NzImage::GetWidth(nzUInt8 level) const } #endif - return std::max(m_sharedImage->width >> level, 1U); + return GetLevelSize(m_sharedImage->width, level); } bool NzImage::IsCompressed() const @@ -549,7 +876,7 @@ bool NzImage::SetLevelCount(nzUInt8 levelCount) return true; } -bool NzImage::SetPixel(const NzColor& color, unsigned int x, unsigned int y, unsigned int z) +bool NzImage::SetPixelColor(const NzColor& color, unsigned int x, unsigned int y, unsigned int z) { #if NAZARA_UTILITY_SAFE if (!IsValid()) @@ -558,12 +885,6 @@ bool NzImage::SetPixel(const NzColor& color, unsigned int x, unsigned int y, uns return false; } - if (m_sharedImage->type == nzImageType_Cubemap) - { - NazaraError("SetPixel is not designed for cubemaps, use SetPixelFace instead"); - return false; - } - if (NzPixelFormat::IsCompressed(m_sharedImage->format)) { NazaraError("Cannot access pixels from compressed image"); @@ -582,59 +903,15 @@ bool NzImage::SetPixel(const NzColor& color, unsigned int x, unsigned int y, uns return false; } - if (z >= m_sharedImage->depth) + unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth; + if (z >= depth) { - NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(m_sharedImage->depth) + ')'); + NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')'); return false; } #endif - nzUInt8* pixel = &m_sharedImage->pixels[0][(m_sharedImage->height*(m_sharedImage->width*z+y) + x) * NzPixelFormat::GetBPP(m_sharedImage->format)]; - - if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, pixel)) - { - NazaraError("Failed to convert RGBA8 to image's format"); - return false; - } - - return true; -} - -bool NzImage::SetPixelFace(nzCubemapFace face, const NzColor& color, unsigned int x, unsigned int y) -{ - #if NAZARA_UTILITY_SAFE - if (!IsValid()) - { - NazaraError("Image must be valid"); - return false; - } - - if (m_sharedImage->type != nzImageType_Cubemap) - { - NazaraError("SetPixelFace is designed for cubemaps, use SetPixel instead"); - return false; - } - - if (NzPixelFormat::IsCompressed(m_sharedImage->format)) - { - NazaraError("Cannot access pixels from compressed image"); - return false; - } - - if (x >= m_sharedImage->width) - { - NazaraError("X value exceeds width (" + NzString::Number(x) + " >= (" + NzString::Number(m_sharedImage->width) + ')'); - return false; - } - - if (y >= m_sharedImage->height) - { - NazaraError("Y value exceeds width (" + NzString::Number(y) + " >= (" + NzString::Number(m_sharedImage->height) + ')'); - return false; - } - #endif - - nzUInt8* pixel = &m_sharedImage->pixels[0][(m_sharedImage->height*(m_sharedImage->width*(face-nzCubemapFace_PositiveX)+y) + x) * NzPixelFormat::GetBPP(m_sharedImage->format)]; + nzUInt8* pixel = GetPixelPtr(m_sharedImage->pixels[0], NzPixelFormat::GetBPP(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height); if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, pixel)) { @@ -654,12 +931,6 @@ bool NzImage::Update(const nzUInt8* pixels, nzUInt8 level) return false; } - if (m_sharedImage->type == nzImageType_Cubemap) - { - NazaraError("Update is not designed for cubemaps, use UpdateFace instead"); - return false; - } - if (!pixels) { NazaraError("Invalid pixel source"); @@ -689,12 +960,6 @@ bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z return false; } - if (m_sharedImage->type == nzImageType_Cubemap) - { - NazaraError("Update is not designed for cubemaps, use UpdateFace instead"); - return false; - } - if (!pixels) { NazaraError("Invalid pixel source"); @@ -706,25 +971,25 @@ bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')'); return false; } - #endif - unsigned int width = std::max(m_sharedImage->width >> level, 1U); - unsigned int height = std::max(m_sharedImage->height >> level, 1U); - - #if NAZARA_UTILITY_SAFE if (!rect.IsValid()) { NazaraError("Invalid rectangle"); return false; } + #endif + unsigned int width = GetLevelSize(m_sharedImage->width, level); + unsigned int height = GetLevelSize(m_sharedImage->height, level); + + #if NAZARA_UTILITY_SAFE if (rect.x+rect.width > width || rect.y+rect.height > height) { NazaraError("Rectangle dimensions are out of bounds"); return false; } - unsigned int depth = std::max(m_sharedImage->depth >> level, 1U); + unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level); if (z >= depth) { NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')'); @@ -735,14 +1000,14 @@ bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z EnsureOwnership(); nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format); - nzUInt8* dstPixels = &m_sharedImage->pixels[level][(height*(width*z + rect.y) + rect.x) * bpp]; + nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->pixels[level], bpp, rect.x, rect.y, z, width, height); unsigned int srcStride = rect.width * bpp; - unsigned int blockSize = width * bpp; - for (unsigned int i = 0; i < rect.height; ++i) + unsigned int dstStride = m_sharedImage->width * bpp; + for (unsigned int y = 0; y < rect.height; ++y) { - std::memcpy(dstPixels, pixels, blockSize); + std::memcpy(dstPixels, pixels, srcStride); pixels += srcStride; - dstPixels += blockSize; + dstPixels += dstStride; } return true; @@ -758,12 +1023,6 @@ bool NzImage::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level) return false; } - if (m_sharedImage->type == nzImageType_Cubemap) - { - NazaraError("Update is not designed for cubemaps, use UpdateFace instead"); - return false; - } - if (!pixels) { NazaraError("Invalid pixel source"); @@ -777,9 +1036,9 @@ bool NzImage::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level) } #endif - unsigned int width = std::max(m_sharedImage->width >> level, 1U); - unsigned int height = std::max(m_sharedImage->height >> level, 1U); - unsigned int depth = std::max(m_sharedImage->height >> level, 1U); + unsigned int width = GetLevelSize(m_sharedImage->width, level); + unsigned int height = GetLevelSize(m_sharedImage->height, level); + unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->height, level); #if NAZARA_UTILITY_SAFE if (!cube.IsValid()) @@ -798,18 +1057,18 @@ bool NzImage::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level) EnsureOwnership(); nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format); - nzUInt8* dstPixels = &m_sharedImage->pixels[level][(height*(width*cube.z + cube.y) + cube.x) * bpp]; + nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->pixels[level], bpp, cube.x, cube.y, cube.z, width, height); unsigned int srcStride = cube.width * bpp; - unsigned int blockSize = width * bpp; - unsigned int faceSize = width * height * bpp; + unsigned int dstStride = width * bpp; + unsigned int faceSize = dstStride * height; for (unsigned int z = 0; z < cube.depth; ++z) { nzUInt8* facePixels = dstPixels; - for (unsigned int i = 0; i < cube.height; ++i) + for (unsigned int y = 0; y < cube.height; ++y) { - std::memcpy(dstPixels, pixels, blockSize); + std::memcpy(facePixels, pixels, srcStride); pixels += srcStride; - facePixels += blockSize; + facePixels += dstStride; } dstPixels += faceSize; @@ -818,98 +1077,6 @@ bool NzImage::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level) return true; } -bool NzImage::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, nzUInt8 level) -{ - #if NAZARA_UTILITY_SAFE - if (!IsValid()) - { - NazaraError("Image must be valid"); - return false; - } - - if (m_sharedImage->type != nzImageType_Cubemap) - { - NazaraError("UpdateFace is designed for cubemaps, use Update instead"); - return false; - } - - if (!pixels) - { - NazaraError("Invalid pixel source"); - return false; - } - - if (level >= m_sharedImage->levelCount) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')'); - return false; - } - #endif - - EnsureOwnership(); - - unsigned int size = GetSize(level); - std::memcpy(&m_sharedImage->pixels[level][size*(face-nzCubemapFace_PositiveX)], pixels, size); - - return true; -} - -bool NzImage::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRectui& rect, nzUInt8 level) -{ - #if NAZARA_UTILITY_SAFE - if (!IsValid()) - { - NazaraError("Image must be valid"); - return false; - } - - if (m_sharedImage->type != nzImageType_Cubemap) - { - NazaraError("UpdateFace is designed for cubemaps, use Update instead"); - return false; - } - - if (!pixels) - { - NazaraError("Invalid pixel source"); - return false; - } - - if (!rect.IsValid()) - { - NazaraError("Invalid rectangle"); - return false; - } - - if (rect.x+rect.width > std::max(m_sharedImage->width >> level, 1U) || rect.y+rect.height > std::max(m_sharedImage->height >> level, 1U)) - { - NazaraError("Rectangle dimensions are out of bounds"); - return false; - } - - if (level >= m_sharedImage->levelCount) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')'); - return false; - } - #endif - - EnsureOwnership(); - - nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format); - nzUInt8* dstPixels = &m_sharedImage->pixels[level][(m_sharedImage->height*(m_sharedImage->width*(face-nzCubemapFace_PositiveX) + rect.y) + rect.x) * bpp]; - unsigned int srcStride = rect.width * bpp; - unsigned int blockSize = m_sharedImage->width * bpp; - for (unsigned int i = 0; i < rect.height; ++i) - { - std::memcpy(dstPixels, pixels, blockSize); - pixels += srcStride; - dstPixels += blockSize; - } - - return true; -} - NzImage& NzImage::operator=(const NzImage& image) { ReleaseImage(); @@ -988,7 +1155,7 @@ void NzImage::EnsureOwnership() { unsigned int size = GetSize(i); pixels[i] = new nzUInt8[size]; - std::memcpy(pixels[i], &m_sharedImage->pixels[i], size); + std::memcpy(pixels[i], m_sharedImage->pixels[i], size); } m_sharedImage = new SharedImage(1, m_sharedImage->type, m_sharedImage->format, m_sharedImage->levelCount, pixels, m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); diff --git a/src/Nazara/Utility/Loaders/STB.cpp b/src/Nazara/Utility/Loaders/STB.cpp index 1b6ed1c6b..e031fa4b1 100644 --- a/src/Nazara/Utility/Loaders/STB.cpp +++ b/src/Nazara/Utility/Loaders/STB.cpp @@ -11,7 +11,7 @@ #include #define STBI_HEADER_FILE_ONLY -#include +#include #include diff --git a/src/Nazara/Utility/Loaders/STB/stb_image.c b/src/Nazara/Utility/Loaders/STB/stb_image.cpp similarity index 100% rename from src/Nazara/Utility/Loaders/STB/stb_image.c rename to src/Nazara/Utility/Loaders/STB/stb_image.cpp diff --git a/src/Nazara/Utility/Win32/WindowImpl.cpp b/src/Nazara/Utility/Win32/WindowImpl.cpp index 8ce9a18b7..d241ef1ab 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.cpp +++ b/src/Nazara/Utility/Win32/WindowImpl.cpp @@ -4,6 +4,8 @@ // Un grand merci à Laurent Gomila pour la SFML qui m'aura bien aidé à réaliser cette implémentation +#define OEMRESOURCE + #include #include #include @@ -14,6 +16,11 @@ #include #include +#ifdef _WIN64 + #define GWL_USERDATA GWLP_USERDATA + #define GCL_HCURSOR GCLP_HCURSOR +#endif + // N'est pas définit avec MinGW apparemment #ifndef MAPVK_VK_TO_VSC #define MAPVK_VK_TO_VSC 0 @@ -116,7 +123,7 @@ bool NzWindowImpl::Create(NzVideoMode mode, const NzString& title, nzUInt32 styl win32StyleEx = 0; - RECT rect = {0, 0, width, height}; + RECT rect = {0, 0, static_cast(width), static_cast(height)}; AdjustWindowRect(&rect, win32Style, false); width = rect.right-rect.left; height = rect.bottom-rect.top; @@ -330,7 +337,7 @@ void NzWindowImpl::SetPosition(int x, int y) void NzWindowImpl::SetSize(unsigned int width, unsigned int height) { // SetWindowPos demande la taille totale de la fenêtre - RECT rect = {0, 0, width, height}; + RECT rect = {0, 0, static_cast(width), static_cast(height)}; AdjustWindowRect(&rect, GetWindowLongPtr(m_handle, GWL_STYLE), false); SetWindowPos(m_handle, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER); diff --git a/src/Nazara/Utility/Window.cpp b/src/Nazara/Utility/Window.cpp index 1ef9c3de8..5f83ff6f2 100644 --- a/src/Nazara/Utility/Window.cpp +++ b/src/Nazara/Utility/Window.cpp @@ -308,6 +308,7 @@ void NzWindow::SetEventListener(bool listener) m_impl->SetEventListener(listener); if (!listener) { + // On vide la pile des évènements NzLockGuard lock(m_eventMutex); while (!m_events.empty()) m_events.pop();