From db4a499151f7713002da119c3051c6d07eec80b1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 30 Jan 2015 15:39:25 +0100 Subject: [PATCH 01/97] Removed support for OpenGL 2 Former-commit-id: e796c333d6c2ef0550ff4427d36dcfbaf00ef924 --- include/Nazara/Renderer/Enums.hpp | 11 +- include/Nazara/Renderer/GpuQuery.hpp | 1 - include/Nazara/Renderer/OpenGL.hpp | 9 +- include/Nazara/Renderer/RenderBuffer.hpp | 1 - include/Nazara/Renderer/RenderTexture.hpp | 1 - include/Nazara/Renderer/Texture.hpp | 1 - .../Graphics/AbstractRenderTechnique.cpp | 17 +- .../Graphics/DeferredRenderTechnique.cpp | 8 +- src/Nazara/Graphics/Material.cpp | 59 +--- .../Shaders/Basic/compatibility.frag | 37 --- .../Shaders/Basic/compatibility.frag.h | 1 - .../Shaders/Basic/compatibility.vert | 99 ------ .../Shaders/Basic/compatibility.vert.h | 1 - .../Shaders/PhongLighting/compatibility.frag | 237 ------------- .../PhongLighting/compatibility.frag.h | 1 - .../Shaders/PhongLighting/compatibility.vert | 135 -------- .../PhongLighting/compatibility.vert.h | 1 - src/Nazara/Graphics/SkyboxBackground.cpp | 35 +- src/Nazara/Renderer/GpuQuery.cpp | 27 +- src/Nazara/Renderer/OpenGL.cpp | 222 +++---------- src/Nazara/Renderer/RenderBuffer.cpp | 5 - src/Nazara/Renderer/RenderTexture.cpp | 11 - src/Nazara/Renderer/Renderer.cpp | 313 +++++------------- .../Shaders/Debug/compatibility.frag | 10 - .../Shaders/Debug/compatibility.frag.h | 1 - .../Shaders/Debug/compatibility.vert | 13 - .../Shaders/Debug/compatibility.vert.h | 1 - src/Nazara/Renderer/Shader.cpp | 17 +- src/Nazara/Renderer/ShaderStage.cpp | 4 +- src/Nazara/Renderer/Texture.cpp | 32 +- 30 files changed, 160 insertions(+), 1151 deletions(-) delete mode 100644 src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag delete mode 100644 src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag.h delete mode 100644 src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert delete mode 100644 src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert.h delete mode 100644 src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag delete mode 100644 src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag.h delete mode 100644 src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert delete mode 100644 src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert.h delete mode 100644 src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.frag delete mode 100644 src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.frag.h delete mode 100644 src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.vert delete mode 100644 src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.vert.h diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index d20b6dd87..274ed4beb 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -107,20 +107,11 @@ enum nzPixelBufferType enum nzRendererCap { nzRendererCap_AnisotropicFilter, - nzRendererCap_ConditionalRendering, nzRendererCap_FP64, - nzRendererCap_HardwareBuffer, nzRendererCap_Instancing, - nzRendererCap_MultipleRenderTargets, - nzRendererCap_OcclusionQuery, nzRendererCap_PixelBufferObject, - nzRendererCap_RenderTexture, - nzRendererCap_Texture3D, - nzRendererCap_TextureCubemap, - nzRendererCap_TextureMulti, - nzRendererCap_TextureNPOT, - nzRendererCap_Max = nzRendererCap_TextureNPOT + nzRendererCap_Max = nzRendererCap_PixelBufferObject }; enum nzRendererBufferFlags diff --git a/include/Nazara/Renderer/GpuQuery.hpp b/include/Nazara/Renderer/GpuQuery.hpp index bd792b979..17aec76be 100644 --- a/include/Nazara/Renderer/GpuQuery.hpp +++ b/include/Nazara/Renderer/GpuQuery.hpp @@ -28,7 +28,6 @@ class NAZARA_API NzGpuQuery : NzNonCopyable unsigned int GetOpenGLID() const; static bool IsModeSupported(nzGpuQueryMode mode); - static bool IsSupported(); private: nzGpuQueryMode m_mode; diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index 08079582a..4e90aceb9 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -28,23 +28,16 @@ enum nzOpenGLExtension { nzOpenGLExtension_AnisotropicFilter, - nzOpenGLExtension_ConditionalRender, nzOpenGLExtension_DebugOutput, - nzOpenGLExtension_DrawInstanced, nzOpenGLExtension_FP64, - nzOpenGLExtension_FrameBufferObject, nzOpenGLExtension_GetProgramBinary, - nzOpenGLExtension_InstancedArray, nzOpenGLExtension_PixelBufferObject, - nzOpenGLExtension_SamplerObjects, nzOpenGLExtension_SeparateShaderObjects, nzOpenGLExtension_Shader_ImageLoadStore, - nzOpenGLExtension_TextureArray, nzOpenGLExtension_TextureCompression_s3tc, nzOpenGLExtension_TextureStorage, - nzOpenGLExtension_VertexArrayObjects, - nzOpenGLExtension_Max = nzOpenGLExtension_VertexArrayObjects + nzOpenGLExtension_Max = nzOpenGLExtension_TextureStorage }; class NzContext; diff --git a/include/Nazara/Renderer/RenderBuffer.hpp b/include/Nazara/Renderer/RenderBuffer.hpp index 69a76aa6a..d1a9efc3d 100644 --- a/include/Nazara/Renderer/RenderBuffer.hpp +++ b/include/Nazara/Renderer/RenderBuffer.hpp @@ -44,7 +44,6 @@ class NAZARA_API NzRenderBuffer : public NzRefCounted, NzNonCopyable bool IsValid() const; - static bool IsSupported(); template static NzRenderBufferRef New(Args&&... args); private: diff --git a/include/Nazara/Renderer/RenderTexture.hpp b/include/Nazara/Renderer/RenderTexture.hpp index 68460eeed..8b5361f18 100644 --- a/include/Nazara/Renderer/RenderTexture.hpp +++ b/include/Nazara/Renderer/RenderTexture.hpp @@ -58,7 +58,6 @@ class NAZARA_API NzRenderTexture : public NzRenderTarget, NzObjectListener, NzNo static void Blit(NzRenderTexture* src, NzRenderTexture* dst, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); static void Blit(NzRenderTexture* src, NzRectui srcRect, NzRenderTexture* dst, NzRectui dstRect, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); - static bool IsSupported(); protected: bool Activate() const override; diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index cc0e2d8f9..ae2f663c6 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -103,7 +103,6 @@ class NAZARA_API NzTexture : public NzAbstractImage, public NzRefCounted, public // Fonctions OpenGL unsigned int GetOpenGLID() const; - static unsigned int GetValidSize(unsigned int size); static bool IsFormatSupported(nzPixelFormat format); static bool IsMipmappingSupported(); static bool IsTypeSupported(nzImageType type); diff --git a/src/Nazara/Graphics/AbstractRenderTechnique.cpp b/src/Nazara/Graphics/AbstractRenderTechnique.cpp index c338091b8..a73a71418 100644 --- a/src/Nazara/Graphics/AbstractRenderTechnique.cpp +++ b/src/Nazara/Graphics/AbstractRenderTechnique.cpp @@ -8,27 +8,16 @@ #include #include -NzAbstractRenderTechnique::NzAbstractRenderTechnique() +NzAbstractRenderTechnique::NzAbstractRenderTechnique() : +m_instancingEnabled(true) { - #ifdef NAZARA_DEBUG - if (!NzRenderer::IsInitialized()) - { - NazaraError("NazaraRenderer is not initialized"); - return; - } - #endif - - m_instancingEnabled = NzRenderer::HasCapability(nzRendererCap_Instancing); } NzAbstractRenderTechnique::~NzAbstractRenderTechnique() = default; void NzAbstractRenderTechnique::EnableInstancing(bool instancing) { - if (NzRenderer::HasCapability(nzRendererCap_Instancing)) - m_instancingEnabled = instancing; - else if (instancing) - NazaraError("NazaraRenderer does not support instancing"); + m_instancingEnabled = instancing; } NzString NzAbstractRenderTechnique::GetName() const diff --git a/src/Nazara/Graphics/DeferredRenderTechnique.cpp b/src/Nazara/Graphics/DeferredRenderTechnique.cpp index 51d609325..d6a888e8d 100644 --- a/src/Nazara/Graphics/DeferredRenderTechnique.cpp +++ b/src/Nazara/Graphics/DeferredRenderTechnique.cpp @@ -400,12 +400,8 @@ void NzDeferredRenderTechnique::SetPass(nzRenderPassType relativeTo, int positio bool NzDeferredRenderTechnique::IsSupported() { - // On ne va pas s'embêter à écrire un Deferred Renderer qui ne passe pas par le MRT, ce serait trop lent pour servir... - return NzOpenGL::GetGLSLVersion() >= 140 && // On ne va pas s'embêter non plus avec le mode de compatibilité - NzRenderer::HasCapability(nzRendererCap_RenderTexture) && - NzRenderer::HasCapability(nzRendererCap_MultipleRenderTargets) && - NzRenderer::GetMaxColorAttachments() >= 4 && - NzRenderer::GetMaxRenderTargets() >= 4; + // Depuis qu'OpenGL 3.3 est la version minimale, le Renderer supporte ce qu'il faut, mais par acquis de conscience... + return NzRenderer::GetMaxColorAttachments() >= 4 && NzRenderer::GetMaxRenderTargets() >= 4; } bool NzDeferredRenderTechnique::Resize(const NzVector2ui& dimensions) const diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 0544067f5..2d1a4a646 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -16,21 +16,22 @@ namespace { - const nzUInt8 r_coreFragmentShader[] = { + const nzUInt8 r_basicFragmentShader[] = { #include }; - const nzUInt8 r_coreVertexShader[] = { + const nzUInt8 r_basicVertexShader[] = { #include }; - const nzUInt8 r_compatibilityFragmentShader[] = { - #include + const nzUInt8 r_phongLightingFragmentShader[] = { + #include }; - const nzUInt8 r_compatibilityVertexShader[] = { - #include + const nzUInt8 r_phongLightingVertexShader[] = { + #include }; + } bool NzMaterialParams::IsValid() const @@ -722,24 +723,12 @@ bool NzMaterial::Initialize() return false; } - bool glsl140 = (NzOpenGL::GetGLSLVersion() >= 140); - // Basic shader { NzUberShaderPreprocessorRef uberShader = NzUberShaderPreprocessor::New(); - NzString fragmentShader; - NzString vertexShader; - if (glsl140) - { - fragmentShader.Set(reinterpret_cast(r_coreFragmentShader), sizeof(r_coreFragmentShader)); - vertexShader.Set(reinterpret_cast(r_coreVertexShader), sizeof(r_coreVertexShader)); - } - else - { - fragmentShader.Set(reinterpret_cast(r_compatibilityFragmentShader), sizeof(r_compatibilityFragmentShader)); - vertexShader.Set(reinterpret_cast(r_compatibilityVertexShader), sizeof(r_compatibilityVertexShader)); - } + NzString fragmentShader(reinterpret_cast(r_basicFragmentShader), sizeof(r_basicFragmentShader)); + NzString vertexShader(reinterpret_cast(r_basicVertexShader), sizeof(r_basicVertexShader)); uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING"); uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_INSTANCING FLAG_VERTEXCOLOR TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); @@ -751,34 +740,8 @@ bool NzMaterial::Initialize() { NzUberShaderPreprocessorRef uberShader = NzUberShaderPreprocessor::New(); - NzString fragmentShader; - NzString vertexShader; - if (glsl140) - { - const nzUInt8 coreFragmentShader[] = { - #include - }; - - const nzUInt8 coreVertexShader[] = { - #include - }; - - fragmentShader.Set(reinterpret_cast(coreFragmentShader), sizeof(coreFragmentShader)); - vertexShader.Set(reinterpret_cast(coreVertexShader), sizeof(coreVertexShader)); - } - else - { - const nzUInt8 compatibilityFragmentShader[] = { - #include - }; - - const nzUInt8 compatibilityVertexShader[] = { - #include - }; - - fragmentShader.Set(reinterpret_cast(compatibilityFragmentShader), sizeof(compatibilityFragmentShader)); - vertexShader.Set(reinterpret_cast(compatibilityVertexShader), sizeof(compatibilityVertexShader)); - } + NzString fragmentShader(reinterpret_cast(r_phongLightingFragmentShader), sizeof(r_phongLightingFragmentShader)); + NzString vertexShader(reinterpret_cast(r_phongLightingVertexShader), sizeof(r_phongLightingVertexShader)); uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "FLAG_DEFERRED FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING EMISSIVE_MAPPING LIGHTING NORMAL_MAPPING PARALLAX_MAPPING SPECULAR_MAPPING"); uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX LIGHTING PARALLAX_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag b/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag deleted file mode 100644 index bc3955b48..000000000 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag +++ /dev/null @@ -1,37 +0,0 @@ -/********************Entrant********************/ -varying vec2 vTexCoord; -varying vec4 vColor; - -/********************Uniformes********************/ -uniform sampler2D MaterialAlphaMap; -uniform float MaterialAlphaThreshold; -uniform vec4 MaterialDiffuse; -uniform sampler2D MaterialDiffuseMap; -uniform vec2 InvTargetSize; - -/********************Fonctions********************/ -void main() -{ - vec4 fragmentColor = MaterialDiffuse; * vColor; - -#if AUTO_TEXCOORDS - vec2 texCoord = gl_FragCoord.xy * InvTargetSize; -#else - vec2 texCoord = vTexCoord; -#endif - -#if DIFFUSE_MAPPING - fragmentColor *= texture2D(MaterialDiffuseMap, texCoord); -#endif - -#if ALPHA_MAPPING - fragmentColor.a *= texture2D(MaterialAlphaMap, texCoord).r; -#endif - -#if ALPHA_TEST - if (fragmentColor.a < MaterialAlphaThreshold) - discard; -#endif - - gl_FragColor = fragmentColor; -} \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag.h b/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag.h deleted file mode 100644 index b1ae605a4..000000000 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.frag.h +++ /dev/null @@ -1 +0,0 @@ -47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,97,114,121,105,110,103,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,118,101,99,50,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,32,42,32,118,67,111,108,111,114,59,13,10,13,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,35,101,108,115,101,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,50,68,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,50,68,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,9,103,108,95,70,114,97,103,67,111,108,111,114,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,125, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert b/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert deleted file mode 100644 index 47c2260d7..000000000 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert +++ /dev/null @@ -1,99 +0,0 @@ -/********************Entrant********************/ -#if FLAG_BILLBOARD -varying vec3 InstanceData0; // center -varying vec4 InstanceData1; // size | sin cos -varying vec4 InstanceData2; // color -#else -varying mat4 InstanceData0; -#endif - -varying vec4 VertexColor; -varying vec3 VertexPosition; -varying vec2 VertexTexCoord; - -/********************Sortant********************/ -varying vec2 vTexCoord; -varying vec4 vColor; - -/********************Uniformes********************/ -uniform float VertexDepth; -uniform mat4 ViewProjMatrix; -uniform mat4 WorldViewProjMatrix; - -/********************Fonctions********************/ -void main() -{ -#if FLAG_VERTEXCOLOR - vec4 color = VertexColor; -#else - vec4 color = vec4(1.0); -#endif - vec2 texCoords; - -#if FLAG_BILLBOARD - #if FLAG_INSTANCING - vec3 billboardCenter = InstanceData0; - vec2 billboardSize = InstanceData1.xy; - vec2 billboardSinCos = InstanceData1.zw; - vec4 billboardColor = InstanceData2; - - vec2 rotatedPosition; - rotatedPosition.x = VertexPosition.x*billboardSinCos.y - VertexPosition.y*billboardSinCos.x; - rotatedPosition.y = VertexPosition.y*billboardSinCos.y + VertexPosition.x*billboardSinCos.x; - rotatedPosition *= billboardSize; - - vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); - vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); - vec3 vertexPos = billboardCenter + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; - - gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); - color = billboardColor; - texCoords = VertexPosition.xy + vec2(0.5, 0.5); - #else - vec2 billboardCorner = VertexTexCoord - vec2(0.5, 0.5); - vec2 billboardSize = VertexUserdata0.xy; - vec2 billboardSinCos = VertexUserdata0.zw; - - vec2 rotatedPosition; - rotatedPosition.x = billboardCorner.x*billboardSinCos.y - billboardCorner.y*billboardSinCos.x; - rotatedPosition.y = billboardCorner.y*billboardSinCos.y + billboardCorner.x*billboardSinCos.x; - rotatedPosition *= billboardSize; - - vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); - vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); - vec3 vertexPos = VertexPosition + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; - - gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); - texCoords = VertexTexCoord; - #endif -#else - #if FLAG_INSTANCING - #if TRANSFORM - gl_Position = ViewProjMatrix * InstanceData0 * vec4(VertexPosition, 1.0); - #else - #if UNIFORM_VERTEX_DEPTH - gl_Position = InstanceData0 * vec4(VertexPosition.xy, VertexDepth, 1.0); - #else - gl_Position = InstanceData0 * vec4(VertexPosition, 1.0); - #endif - #endif - #else - #if TRANSFORM - gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0); - #else - #if UNIFORM_VERTEX_DEPTH - gl_Position = vec4(VertexPosition.xy, VertexDepth, 1.0); - #else - gl_Position = vec4(VertexPosition, 1.0); - #endif - #endif - #endif - - texCoords = VertexTexCoord; -#endif - - vColor = color; -#if TEXTURE_MAPPING - vTexCoord = vec2(texCoords); -#endif -} diff --git a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert.h b/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert.h deleted file mode 100644 index 556f0c733..000000000 --- a/src/Nazara/Graphics/Resources/Shaders/Basic/compatibility.vert.h +++ /dev/null @@ -1 +0,0 @@ -47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,32,47,47,32,99,101,110,116,101,114,13,10,118,97,114,121,105,110,103,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,49,59,32,47,47,32,115,105,122,101,32,124,32,115,105,110,32,99,111,115,13,10,118,97,114,121,105,110,103,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,32,47,47,32,99,111,108,111,114,13,10,35,101,108,115,101,13,10,118,97,114,121,105,110,103,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,35,101,110,100,105,102,13,10,13,10,118,97,114,121,105,110,103,32,118,101,99,52,32,86,101,114,116,101,120,67,111,108,111,114,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,13,10,118,97,114,121,105,110,103,32,118,101,99,50,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,97,114,121,105,110,103,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,86,101,114,116,101,120,68,101,112,116,104,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,35,105,102,32,70,76,65,71,95,86,69,82,84,69,88,67,79,76,79,82,13,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,86,101,114,116,101,120,67,111,108,111,114,59,13,10,35,101,108,115,101,13,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,118,101,99,52,40,49,46,48,41,59,13,10,35,101,110,100,105,102,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,115,59,13,10,13,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,118,101,99,51,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,120,121,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,122,119,59,13,10,9,118,101,99,52,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,13,10,13,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,13,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,13,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,13,10,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,13,10,9,99,111,108,111,114,32,61,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,59,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,32,43,32,118,101,99,50,40,48,46,53,44,32,48,46,53,41,59,13,10,9,35,101,108,115,101,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,32,45,32,118,101,99,50,40,48,46,53,44,32,48,46,53,41,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,120,121,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,122,119,59,13,10,9,13,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,13,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,13,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,13,10,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,35,101,108,115,101,13,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,13,10,9,9,9,35,101,108,115,101,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,9,35,101,110,100,105,102,13,10,9,9,35,101,110,100,105,102,13,10,9,35,101,108,115,101,13,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,35,101,108,115,101,13,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,13,10,9,9,9,35,101,108,115,101,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,9,35,101,110,100,105,102,13,10,9,9,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,9,118,67,111,108,111,114,32,61,32,99,111,108,111,114,59,13,10,35,105,102,32,84,69,88,84,85,82,69,95,77,65,80,80,73,78,71,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,118,101,99,50,40,116,101,120,67,111,111,114,100,115,41,59,13,10,35,101,110,100,105,102,13,10,125,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag deleted file mode 100644 index f78f73ed6..000000000 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag +++ /dev/null @@ -1,237 +0,0 @@ -#if FLAG_DEFERRED - #error Deferred Shading is not supported by compatibility shaders -#endif - -#define LIGHT_DIRECTIONAL 0 -#define LIGHT_POINT 1 -#define LIGHT_SPOT 2 - -/********************Entrant********************/ -varying mat3 vLightToWorld; -varying vec3 vNormal; -varying vec2 vTexCoord; -varying vec3 vWorldPos; -varying vec4 vColor; - -/********************Uniformes********************/ -struct Light -{ - int type; - vec4 color; - vec2 factors; - - vec4 parameters1; - vec4 parameters2; - vec2 parameters3; -}; - -// Lumières -uniform Light Lights[3]; - -// Matériau -uniform sampler2D MaterialAlphaMap; -uniform float MaterialAlphaThreshold; -uniform vec4 MaterialAmbient; -uniform vec4 MaterialDiffuse; -uniform sampler2D MaterialDiffuseMap; -uniform sampler2D MaterialEmissiveMap; -uniform sampler2D MaterialNormalMap; -uniform float MaterialShininess; -uniform vec4 MaterialSpecular; -uniform sampler2D MaterialSpecularMap; - -// Autres -uniform vec3 EyePosition; -uniform vec4 SceneAmbient; - -/********************Fonctions********************/ -void main() -{ - vec4 diffuseColor = MaterialDiffuse * vColor; - -#if AUTO_TEXCOORDS - vec2 texCoord = gl_FragCoord.xy * InvTargetSize; -#else - vec2 texCoord = vTexCoord; -#endif - -#if DIFFUSE_MAPPING - diffuseColor *= texture(MaterialDiffuseMap, texCoord); -#endif - -#if ALPHA_MAPPING - diffuseColor.a *= texture(MaterialAlphaMap, texCoord).r; -#endif - -#if ALPHA_TEST - if (diffuseColor.a < MaterialAlphaThreshold) - discard; -#endif - -#if LIGHTING - vec3 lightAmbient = vec3(0.0); - vec3 lightDiffuse = vec3(0.0); - vec3 lightSpecular = vec3(0.0); - - #if NORMAL_MAPPING - vec3 normal = normalize(vLightToWorld * (2.0 * vec3(texture(MaterialNormalMap, texCoord)) - 1.0)); - #else - vec3 normal = normalize(vNormal); - #endif - - if (MaterialShininess > 0.0) - { - vec3 eyeVec = normalize(EyePosition - vWorldPos); - - for (int i = 0; i < 3; ++i) - { - if (Lights[i].type == LIGHT_DIRECTIONAL) - { - vec3 lightDir = -Lights[i].parameters1.xyz; - - // Ambient - lightAmbient += Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); - - // Diffuse - float lambert = max(dot(normal, lightDir), 0.0); - - lightDiffuse += lambert * Lights[i].color.rgb * Lights[i].factors.y; - - // Specular - vec3 reflection = reflect(-lightDir, normal); - float specularFactor = max(dot(reflection, eyeVec), 0.0); - specularFactor = pow(specularFactor, MaterialShininess); - - lightSpecular += specularFactor * Lights[i].color.rgb; - } - else if (Lights[i].type == LIGHT_POINT) - { - vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos; - float lightDirLength = length(lightDir); - lightDir /= lightDirLength; // Normalisation - - float att = max(Lights[i].parameters1.w - Lights[i].parameters2.w*lightDirLength, 0.0); - - // Ambient - lightAmbient += att * Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); - - // Diffuse - float lambert = max(dot(normal, lightDir), 0.0); - - lightDiffuse += att * lambert * Lights[i].color.rgb * Lights[i].factors.y; - - // Specular - vec3 reflection = reflect(-lightDir, normal); - float specularFactor = max(dot(reflection, eyeVec), 0.0); - specularFactor = pow(specularFactor, MaterialShininess); - - lightSpecular += att * specularFactor * Lights[i].color.rgb; - } - else if (Lights[i].type == LIGHT_SPOT) - { - vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos; - float lightDirLength = length(lightDir); - lightDir /= lightDirLength; // Normalisation - - float att = max(Lights[i].parameters1.w - Lights[i].parameters2.w*lightDirLength, 0.0); - - // Ambient - lightAmbient += att * Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); - - // Diffuse - float lambert = max(dot(normal, lightDir), 0.0); - - // Modification de l'atténuation pour gérer le spot - float curAngle = dot(Lights[i].parameters2.xyz, -lightDir); - float outerAngle = Lights[i].parameters3.y; - float innerMinusOuterAngle = Lights[i].parameters3.x - outerAngle; - att *= max((curAngle - outerAngle) / innerMinusOuterAngle, 0.0); - - lightDiffuse += att * lambert * Lights[i].color.rgb * Lights[i].factors.y; - - // Specular - vec3 reflection = reflect(-lightDir, normal); - float specularFactor = max(dot(reflection, eyeVec), 0.0); - specularFactor = pow(specularFactor, MaterialShininess); - - lightSpecular += att * specularFactor * Lights[i].color.rgb; - } - } - } - else - { - for (int i = 0; i < 3; ++i) - { - if (Lights[i].type == LIGHT_DIRECTIONAL) - { - vec3 lightDir = -Lights[i].parameters1.xyz; - - // Ambient - lightAmbient += Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); - - // Diffuse - float lambert = max(dot(normal, lightDir), 0.0); - - lightDiffuse += lambert * Lights[i].color.rgb * Lights[i].factors.y; - } - else if (Lights[i].type == LIGHT_POINT) - { - vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos; - float lightDirLength = length(lightDir); - lightDir /= lightDirLength; // Normalisation - - float att = max(Lights[i].parameters1.w - Lights[i].parameters2.w*lightDirLength, 0.0); - - // Ambient - lightAmbient += att * Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); - - // Diffuse - float lambert = max(dot(normal, lightDir), 0.0); - - lightDiffuse += att * lambert * Lights[i].color.rgb * Lights[i].factors.y; - } - else if (Lights[i].type == LIGHT_SPOT) - { - vec3 lightDir = Lights[i].parameters1.xyz - vWorldPos; - float lightDirLength = length(lightDir); - lightDir /= lightDirLength; // Normalisation - - float att = max(Lights[i].parameters1.w - Lights[i].parameters2.w*lightDirLength, 0.0); - - // Ambient - lightAmbient += att * Lights[i].color.rgb * Lights[i].factors.x * (MaterialAmbient.rgb + SceneAmbient.rgb); - - // Diffuse - float lambert = max(dot(normal, lightDir), 0.0); - - // Modification de l'atténuation pour gérer le spot - float curAngle = dot(Lights[i].parameters2.xyz, -lightDir); - float outerAngle = Lights[i].parameters3.y; - float innerMinusOuterAngle = Lights[i].parameters3.x - outerAngle; - att *= max((curAngle - outerAngle) / innerMinusOuterAngle, 0.0); - - lightDiffuse += att * lambert * Lights[i].color.rgb * Lights[i].factors.y; - } - } - } - - lightSpecular *= MaterialSpecular.rgb; - #if SPECULAR_MAPPING - lightSpecular *= texture(MaterialSpecularMap, texCoord).rgb; // Utiliser l'alpha de MaterialSpecular n'aurait aucun sens - #endif - - vec3 lightColor = (lightAmbient + lightDiffuse + lightSpecular); - vec4 fragmentColor = vec4(lightColor, 1.0) * diffuseColor; - - #if EMISSIVE_MAPPING - float lightIntensity = dot(lightColor, vec3(0.3, 0.59, 0.11)); - - vec3 emissionColor = MaterialDiffuse.rgb * texture(MaterialEmissiveMap, texCoord).rgb; - RenderTarget0 = vec4(mix(fragmentColor.rgb, emissionColor, clamp(1.0 - 3.0*lightIntensity, 0.0, 1.0)), fragmentColor.a); - #else - RenderTarget0 = fragmentColor; - #endif // EMISSIVE_MAPPING -#else - RenderTarget0 = diffuseColor; -#endif // LIGHTING -} diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag.h deleted file mode 100644 index 3358d4e82..000000000 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.frag.h +++ /dev/null @@ -1 +0,0 @@ -35,105,102,32,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,101,114,114,111,114,32,68,101,102,101,114,114,101,100,32,83,104,97,100,105,110,103,32,105,115,32,110,111,116,32,115,117,112,112,111,114,116,101,100,32,98,121,32,99,111,109,112,97,116,105,98,105,108,105,116,121,32,115,104,97,100,101,114,115,13,10,35,101,110,100,105,102,13,10,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,32,48,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,80,79,73,78,84,32,49,13,10,35,100,101,102,105,110,101,32,76,73,71,72,84,95,83,80,79,84,32,50,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,97,114,121,105,110,103,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,118,97,114,121,105,110,103,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,118,97,114,121,105,110,103,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,115,116,114,117,99,116,32,76,105,103,104,116,13,10,123,13,10,9,105,110,116,32,116,121,112,101,59,13,10,9,118,101,99,52,32,99,111,108,111,114,59,13,10,9,118,101,99,50,32,102,97,99,116,111,114,115,59,13,10,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,49,59,13,10,9,118,101,99,52,32,112,97,114,97,109,101,116,101,114,115,50,59,13,10,9,118,101,99,50,32,112,97,114,97,109,101,116,101,114,115,51,59,13,10,125,59,13,10,13,10,47,47,32,76,117,109,105,195,168,114,101,115,13,10,117,110,105,102,111,114,109,32,76,105,103,104,116,32,76,105,103,104,116,115,91,51,93,59,13,10,13,10,47,47,32,77,97,116,195,169,114,105,97,117,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,59,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,59,13,10,117,110,105,102,111,114,109,32,115,97,109,112,108,101,114,50,68,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,59,13,10,13,10,47,47,32,65,117,116,114,101,115,13,10,117,110,105,102,111,114,109,32,118,101,99,51,32,69,121,101,80,111,115,105,116,105,111,110,59,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,83,99,101,110,101,65,109,98,105,101,110,116,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,118,101,99,52,32,100,105,102,102,117,115,101,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,32,42,32,118,67,111,108,111,114,59,13,10,13,10,35,105,102,32,65,85,84,79,95,84,69,88,67,79,79,82,68,83,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,103,108,95,70,114,97,103,67,111,111,114,100,46,120,121,32,42,32,73,110,118,84,97,114,103,101,116,83,105,122,101,59,13,10,35,101,108,115,101,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,32,61,32,118,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,68,73,70,70,85,83,69,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,65,76,80,72,65,95,77,65,80,80,73,78,71,13,10,9,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,65,76,80,72,65,95,84,69,83,84,13,10,9,105,102,32,40,100,105,102,102,117,115,101,67,111,108,111,114,46,97,32,60,32,77,97,116,101,114,105,97,108,65,108,112,104,97,84,104,114,101,115,104,111,108,100,41,13,10,9,9,100,105,115,99,97,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,118,101,99,51,32,108,105,103,104,116,65,109,98,105,101,110,116,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,68,105,102,102,117,115,101,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,9,118,101,99,51,32,108,105,103,104,116,83,112,101,99,117,108,97,114,32,61,32,118,101,99,51,40,48,46,48,41,59,13,10,13,10,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,76,105,103,104,116,84,111,87,111,114,108,100,32,42,32,40,50,46,48,32,42,32,118,101,99,51,40,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,78,111,114,109,97,108,77,97,112,44,32,116,101,120,67,111,111,114,100,41,41,32,45,32,49,46,48,41,41,59,13,10,9,35,101,108,115,101,13,10,9,118,101,99,51,32,110,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,118,78,111,114,109,97,108,41,59,13,10,9,35,101,110,100,105,102,13,10,13,10,9,105,102,32,40,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,32,62,32,48,46,48,41,13,10,9,123,13,10,9,9,118,101,99,51,32,101,121,101,86,101,99,32,61,32,110,111,114,109,97,108,105,122,101,40,69,121,101,80,111,115,105,116,105,111,110,32,45,32,118,87,111,114,108,100,80,111,115,41,59,13,10,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,41,13,10,9,9,9,123,13,10,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,59,13,10,9,9,9,125,13,10,9,9,9,101,108,115,101,32,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,80,79,73,78,84,41,13,10,9,9,9,123,13,10,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,108,105,103,104,116,68,105,114,32,47,61,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,13,10,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,32,45,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,42,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,13,10,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,59,13,10,9,9,9,125,13,10,9,9,9,101,108,115,101,32,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,83,80,79,84,41,13,10,9,9,9,123,13,10,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,108,105,103,104,116,68,105,114,32,47,61,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,13,10,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,32,45,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,42,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,44,32,45,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,102,108,111,97,116,32,111,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,32,45,32,111,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,111,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,13,10,9,9,9,9,47,47,32,83,112,101,99,117,108,97,114,13,10,9,9,9,9,118,101,99,51,32,114,101,102,108,101,99,116,105,111,110,32,61,32,114,101,102,108,101,99,116,40,45,108,105,103,104,116,68,105,114,44,32,110,111,114,109,97,108,41,59,13,10,9,9,9,9,102,108,111,97,116,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,109,97,120,40,100,111,116,40,114,101,102,108,101,99,116,105,111,110,44,32,101,121,101,86,101,99,41,44,32,48,46,48,41,59,13,10,9,9,9,9,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,61,32,112,111,119,40,115,112,101,99,117,108,97,114,70,97,99,116,111,114,44,32,77,97,116,101,114,105,97,108,83,104,105,110,105,110,101,115,115,41,59,13,10,13,10,9,9,9,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,43,61,32,97,116,116,32,42,32,115,112,101,99,117,108,97,114,70,97,99,116,111,114,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,9,101,108,115,101,13,10,9,123,13,10,9,9,102,111,114,32,40,105,110,116,32,105,32,61,32,48,59,32,105,32,60,32,51,59,32,43,43,105,41,13,10,9,9,123,13,10,9,9,9,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,68,73,82,69,67,84,73,79,78,65,76,41,13,10,9,9,9,123,13,10,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,45,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,59,13,10,13,10,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,9,9,9,125,13,10,9,9,9,101,108,115,101,32,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,80,79,73,78,84,41,13,10,9,9,9,123,13,10,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,108,105,103,104,116,68,105,114,32,47,61,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,13,10,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,32,45,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,42,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,9,9,9,9,13,10,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,9,9,9,125,13,10,9,9,9,101,108,115,101,32,105,102,32,40,76,105,103,104,116,115,91,105,93,46,116,121,112,101,32,61,61,32,76,73,71,72,84,95,83,80,79,84,41,13,10,9,9,9,123,13,10,9,9,9,9,118,101,99,51,32,108,105,103,104,116,68,105,114,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,120,121,122,32,45,32,118,87,111,114,108,100,80,111,115,59,13,10,9,9,9,9,102,108,111,97,116,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,32,61,32,108,101,110,103,116,104,40,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,108,105,103,104,116,68,105,114,32,47,61,32,108,105,103,104,116,68,105,114,76,101,110,103,116,104,59,32,47,47,32,78,111,114,109,97,108,105,115,97,116,105,111,110,13,10,9,9,9,9,13,10,9,9,9,9,102,108,111,97,116,32,97,116,116,32,61,32,109,97,120,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,49,46,119,32,45,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,119,42,108,105,103,104,116,68,105,114,76,101,110,103,116,104,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,47,47,32,65,109,98,105,101,110,116,13,10,9,9,9,9,108,105,103,104,116,65,109,98,105,101,110,116,32,43,61,32,97,116,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,120,32,42,32,40,77,97,116,101,114,105,97,108,65,109,98,105,101,110,116,46,114,103,98,32,43,32,83,99,101,110,101,65,109,98,105,101,110,116,46,114,103,98,41,59,13,10,13,10,9,9,9,9,47,47,32,68,105,102,102,117,115,101,13,10,9,9,9,9,102,108,111,97,116,32,108,97,109,98,101,114,116,32,61,32,109,97,120,40,100,111,116,40,110,111,114,109,97,108,44,32,108,105,103,104,116,68,105,114,41,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,47,47,32,77,111,100,105,102,105,99,97,116,105,111,110,32,100,101,32,108,39,97,116,116,195,169,110,117,97,116,105,111,110,32,112,111,117,114,32,103,195,169,114,101,114,32,108,101,32,115,112,111,116,13,10,9,9,9,9,102,108,111,97,116,32,99,117,114,65,110,103,108,101,32,61,32,100,111,116,40,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,50,46,120,121,122,44,32,45,108,105,103,104,116,68,105,114,41,59,13,10,9,9,9,9,102,108,111,97,116,32,111,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,121,59,13,10,9,9,9,9,102,108,111,97,116,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,32,61,32,76,105,103,104,116,115,91,105,93,46,112,97,114,97,109,101,116,101,114,115,51,46,120,32,45,32,111,117,116,101,114,65,110,103,108,101,59,13,10,9,9,9,9,97,116,116,32,42,61,32,109,97,120,40,40,99,117,114,65,110,103,108,101,32,45,32,111,117,116,101,114,65,110,103,108,101,41,32,47,32,105,110,110,101,114,77,105,110,117,115,79,117,116,101,114,65,110,103,108,101,44,32,48,46,48,41,59,13,10,13,10,9,9,9,9,108,105,103,104,116,68,105,102,102,117,115,101,32,43,61,32,97,116,116,32,42,32,108,97,109,98,101,114,116,32,42,32,76,105,103,104,116,115,91,105,93,46,99,111,108,111,114,46,114,103,98,32,42,32,76,105,103,104,116,115,91,105,93,46,102,97,99,116,111,114,115,46,121,59,13,10,9,9,9,125,13,10,9,9,125,13,10,9,125,13,10,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,46,114,103,98,59,13,10,9,35,105,102,32,83,80,69,67,85,76,65,82,95,77,65,80,80,73,78,71,13,10,9,108,105,103,104,116,83,112,101,99,117,108,97,114,32,42,61,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,32,47,47,32,85,116,105,108,105,115,101,114,32,108,39,97,108,112,104,97,32,100,101,32,77,97,116,101,114,105,97,108,83,112,101,99,117,108,97,114,32,110,39,97,117,114,97,105,116,32,97,117,99,117,110,32,115,101,110,115,13,10,9,35,101,110,100,105,102,13,10,9,9,13,10,9,118,101,99,51,32,108,105,103,104,116,67,111,108,111,114,32,61,32,40,108,105,103,104,116,65,109,98,105,101,110,116,32,43,32,108,105,103,104,116,68,105,102,102,117,115,101,32,43,32,108,105,103,104,116,83,112,101,99,117,108,97,114,41,59,13,10,9,118,101,99,52,32,102,114,97,103,109,101,110,116,67,111,108,111,114,32,61,32,118,101,99,52,40,108,105,103,104,116,67,111,108,111,114,44,32,49,46,48,41,32,42,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,13,10,9,35,105,102,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,9,102,108,111,97,116,32,108,105,103,104,116,73,110,116,101,110,115,105,116,121,32,61,32,100,111,116,40,108,105,103,104,116,67,111,108,111,114,44,32,118,101,99,51,40,48,46,51,44,32,48,46,53,57,44,32,48,46,49,49,41,41,59,13,10,13,10,9,118,101,99,51,32,101,109,105,115,115,105,111,110,67,111,108,111,114,32,61,32,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,46,114,103,98,32,42,32,116,101,120,116,117,114,101,40,77,97,116,101,114,105,97,108,69,109,105,115,115,105,118,101,77,97,112,44,32,116,101,120,67,111,111,114,100,41,46,114,103,98,59,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,118,101,99,52,40,109,105,120,40,102,114,97,103,109,101,110,116,67,111,108,111,114,46,114,103,98,44,32,101,109,105,115,115,105,111,110,67,111,108,111,114,44,32,99,108,97,109,112,40,49,46,48,32,45,32,51,46,48,42,108,105,103,104,116,73,110,116,101,110,115,105,116,121,44,32,48,46,48,44,32,49,46,48,41,41,44,32,102,114,97,103,109,101,110,116,67,111,108,111,114,46,97,41,59,13,10,9,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,102,114,97,103,109,101,110,116,67,111,108,111,114,59,13,10,9,35,101,110,100,105,102,32,47,47,32,69,77,73,83,83,73,86,69,95,77,65,80,80,73,78,71,13,10,35,101,108,115,101,13,10,9,82,101,110,100,101,114,84,97,114,103,101,116,48,32,61,32,100,105,102,102,117,115,101,67,111,108,111,114,59,13,10,35,101,110,100,105,102,32,47,47,32,76,73,71,72,84,73,78,71,13,10,125,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert deleted file mode 100644 index e42e972f7..000000000 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert +++ /dev/null @@ -1,135 +0,0 @@ -/********************Entrant********************/ -#if FLAG_BILLBOARD -varying vec3 InstanceData0; // center -varying vec4 InstanceData1; // size | sin cos -varying vec4 InstanceData2; // color -#else -varying mat4 InstanceData0; -#endif - -varying vec3 VertexPosition; -varying vec3 VertexNormal; -varying vec3 VertexTangent; -varying vec2 VertexTexCoord; - -/********************Sortant********************/ -varying mat3 vLightToWorld; -varying vec3 vNormal; -varying vec2 vTexCoord; -varying vec3 vWorldPos; -varying vec4 vColor; - -/********************Uniformes********************/ -uniform float VertexDepth; -uniform mat4 ViewProjMatrix; -uniform mat4 WorldMatrix; -uniform mat4 WorldViewProjMatrix; - -/********************Fonctions********************/ -void main() -{ -#if FLAG_VERTEXCOLOR - vec4 color = VertexColor; -#else - vec4 color = vec4(1.0); -#endif - vec2 texCoords; - -#if FLAG_BILLBOARD - #if FLAG_INSTANCING - vec3 billboardCenter = InstanceData0; - vec2 billboardSize = InstanceData1.xy; - vec2 billboardSinCos = InstanceData1.zw; - vec4 billboardColor = InstanceData2; - - vec2 rotatedPosition; - rotatedPosition.x = VertexPosition.x*billboardSinCos.y - VertexPosition.y*billboardSinCos.x; - rotatedPosition.y = VertexPosition.y*billboardSinCos.y + VertexPosition.x*billboardSinCos.x; - rotatedPosition *= billboardSize; - - vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); - vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); - vec3 vertexPos = billboardCenter + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; - - gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); - color = billboardColor; - texCoords = VertexPosition.xy + vec2(0.5, 0.5); - #else - vec2 billboardCorner = VertexTexCoord - vec2(0.5, 0.5); - vec2 billboardSize = VertexUserdata0.xy; - vec2 billboardSinCos = VertexUserdata0.zw; - - vec2 rotatedPosition; - rotatedPosition.x = billboardCorner.x*billboardSinCos.y - billboardCorner.y*billboardSinCos.x; - rotatedPosition.y = billboardCorner.y*billboardSinCos.y + billboardCorner.x*billboardSinCos.x; - rotatedPosition *= billboardSize; - - vec3 cameraRight = vec3(ViewMatrix[0][0], ViewMatrix[1][0], ViewMatrix[2][0]); - vec3 cameraUp = vec3(ViewMatrix[0][1], ViewMatrix[1][1], ViewMatrix[2][1]); - vec3 vertexPos = VertexPosition + cameraRight*rotatedPosition.x + cameraUp*rotatedPosition.y; - - gl_Position = ViewProjMatrix * vec4(vertexPos, 1.0); - texCoords = VertexTexCoord; - #endif -#else - #if FLAG_INSTANCING - #if TRANSFORM - gl_Position = ViewProjMatrix * InstanceData0 * vec4(VertexPosition, 1.0); - #else - #if UNIFORM_VERTEX_DEPTH - gl_Position = InstanceData0 * vec4(VertexPosition.xy, VertexDepth, 1.0); - #else - gl_Position = InstanceData0 * vec4(VertexPosition, 1.0); - #endif - #endif - #else - #if TRANSFORM - gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0); - #else - #if UNIFORM_VERTEX_DEPTH - gl_Position = vec4(VertexPosition.xy, VertexDepth, 1.0); - #else - gl_Position = vec4(VertexPosition, 1.0); - #endif - #endif - #endif - - texCoords = VertexTexCoord; -#endif - - vColor = color; - -#if LIGHTING - #if FLAG_INSTANCING - mat3 rotationMatrix = mat3(InstanceData0[0].xyz, InstanceData0[1].xyz, InstanceData0[2].xyz); - #else - mat3 rotationMatrix = mat3(WorldMatrix[0].xyz, WorldMatrix[1].xyz, WorldMatrix[2].xyz); - #endif - - #if NORMAL_MAPPING - vec3 binormal = cross(VertexNormal, VertexTangent); - vLightToWorld[0] = normalize(rotationMatrix * VertexTangent); - vLightToWorld[1] = normalize(rotationMatrix * binormal); - vLightToWorld[2] = normalize(rotationMatrix * VertexNormal); - #else - vNormal = normalize(rotationMatrix * VertexNormal); - #endif -#endif - -#if TEXTURE_MAPPING - vTexCoord = vec2(texCoords); -#endif - -#if LIGHTING && PARALLAX_MAPPING - vViewDir = EyePosition - VertexPosition; - vViewDir *= vLightToWorld; -#endif - -#if LIGHTING && !FLAG_DEFERRED - #if FLAG_INSTANCING - vWorldPos = vec3(InstanceData0 * vec4(VertexPosition, 1.0)); - #else - vWorldPos = vec3(WorldMatrix * vec4(VertexPosition, 1.0)); - #endif -#endif -} diff --git a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert.h b/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert.h deleted file mode 100644 index 29df285c8..000000000 --- a/src/Nazara/Graphics/Resources/Shaders/PhongLighting/compatibility.vert.h +++ /dev/null @@ -1 +0,0 @@ -47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,32,47,47,32,99,101,110,116,101,114,13,10,118,97,114,121,105,110,103,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,49,59,32,47,47,32,115,105,122,101,32,124,32,115,105,110,32,99,111,115,13,10,118,97,114,121,105,110,103,32,118,101,99,52,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,32,47,47,32,99,111,108,111,114,13,10,35,101,108,115,101,13,10,118,97,114,121,105,110,103,32,109,97,116,52,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,35,101,110,100,105,102,13,10,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,78,111,114,109,97,108,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,84,97,110,103,101,110,116,59,13,10,118,97,114,121,105,110,103,32,118,101,99,50,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,83,111,114,116,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,97,114,121,105,110,103,32,109,97,116,51,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,118,78,111,114,109,97,108,59,13,10,118,97,114,121,105,110,103,32,118,101,99,50,32,118,84,101,120,67,111,111,114,100,59,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,118,87,111,114,108,100,80,111,115,59,13,10,118,97,114,121,105,110,103,32,118,101,99,52,32,118,67,111,108,111,114,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,117,110,105,102,111,114,109,32,102,108,111,97,116,32,86,101,114,116,101,120,68,101,112,116,104,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,77,97,116,114,105,120,59,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,35,105,102,32,70,76,65,71,95,86,69,82,84,69,88,67,79,76,79,82,13,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,86,101,114,116,101,120,67,111,108,111,114,59,13,10,35,101,108,115,101,13,10,9,118,101,99,52,32,99,111,108,111,114,32,61,32,118,101,99,52,40,49,46,48,41,59,13,10,35,101,110,100,105,102,13,10,9,118,101,99,50,32,116,101,120,67,111,111,114,100,115,59,13,10,13,10,35,105,102,32,70,76,65,71,95,66,73,76,76,66,79,65,82,68,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,118,101,99,51,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,120,121,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,49,46,122,119,59,13,10,9,118,101,99,52,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,50,59,13,10,13,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,13,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,13,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,98,105,108,108,98,111,97,114,100,67,101,110,116,101,114,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,13,10,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,13,10,9,99,111,108,111,114,32,61,32,98,105,108,108,98,111,97,114,100,67,111,108,111,114,59,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,32,43,32,118,101,99,50,40,48,46,53,44,32,48,46,53,41,59,13,10,9,35,101,108,115,101,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,32,45,32,118,101,99,50,40,48,46,53,44,32,48,46,53,41,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,122,101,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,120,121,59,13,10,9,118,101,99,50,32,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,32,61,32,86,101,114,116,101,120,85,115,101,114,100,97,116,97,48,46,122,119,59,13,10,9,13,10,9,118,101,99,50,32,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,45,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,32,61,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,121,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,121,32,43,32,98,105,108,108,98,111,97,114,100,67,111,114,110,101,114,46,120,42,98,105,108,108,98,111,97,114,100,83,105,110,67,111,115,46,120,59,13,10,9,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,32,42,61,32,98,105,108,108,98,111,97,114,100,83,105,122,101,59,13,10,13,10,9,118,101,99,51,32,99,97,109,101,114,97,82,105,103,104,116,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,48,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,48,93,41,59,13,10,9,118,101,99,51,32,99,97,109,101,114,97,85,112,32,61,32,118,101,99,51,40,86,105,101,119,77,97,116,114,105,120,91,48,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,49,93,91,49,93,44,32,86,105,101,119,77,97,116,114,105,120,91,50,93,91,49,93,41,59,13,10,9,118,101,99,51,32,118,101,114,116,101,120,80,111,115,32,61,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,32,43,32,99,97,109,101,114,97,82,105,103,104,116,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,120,32,43,32,99,97,109,101,114,97,85,112,42,114,111,116,97,116,101,100,80,111,115,105,116,105,111,110,46,121,59,13,10,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,118,101,114,116,101,120,80,111,115,44,32,49,46,48,41,59,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,9,35,101,110,100,105,102,13,10,35,101,108,115,101,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,35,101,108,115,101,13,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,13,10,9,9,9,35,101,108,115,101,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,9,35,101,110,100,105,102,13,10,9,9,35,101,110,100,105,102,13,10,9,35,101,108,115,101,13,10,9,9,35,105,102,32,84,82,65,78,83,70,79,82,77,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,35,101,108,115,101,13,10,9,9,9,35,105,102,32,85,78,73,70,79,82,77,95,86,69,82,84,69,88,95,68,69,80,84,72,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,46,120,121,44,32,86,101,114,116,101,120,68,101,112,116,104,44,32,49,46,48,41,59,13,10,9,9,9,35,101,108,115,101,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,9,9,9,35,101,110,100,105,102,13,10,9,9,35,101,110,100,105,102,13,10,9,35,101,110,100,105,102,13,10,9,13,10,9,116,101,120,67,111,111,114,100,115,32,61,32,86,101,114,116,101,120,84,101,120,67,111,111,114,100,59,13,10,35,101,110,100,105,102,13,10,13,10,9,118,67,111,108,111,114,32,61,32,99,111,108,111,114,59,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,109,97,116,51,32,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,61,32,109,97,116,51,40,73,110,115,116,97,110,99,101,68,97,116,97,48,91,48,93,46,120,121,122,44,32,73,110,115,116,97,110,99,101,68,97,116,97,48,91,49,93,46,120,121,122,44,32,73,110,115,116,97,110,99,101,68,97,116,97,48,91,50,93,46,120,121,122,41,59,13,10,9,35,101,108,115,101,13,10,9,109,97,116,51,32,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,61,32,109,97,116,51,40,87,111,114,108,100,77,97,116,114,105,120,91,48,93,46,120,121,122,44,32,87,111,114,108,100,77,97,116,114,105,120,91,49,93,46,120,121,122,44,32,87,111,114,108,100,77,97,116,114,105,120,91,50,93,46,120,121,122,41,59,13,10,9,35,101,110,100,105,102,13,10,9,13,10,9,35,105,102,32,78,79,82,77,65,76,95,77,65,80,80,73,78,71,13,10,9,118,101,99,51,32,98,105,110,111,114,109,97,108,32,61,32,99,114,111,115,115,40,86,101,114,116,101,120,78,111,114,109,97,108,44,32,86,101,114,116,101,120,84,97,110,103,101,110,116,41,59,13,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,48,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,84,97,110,103,101,110,116,41,59,13,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,49,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,98,105,110,111,114,109,97,108,41,59,13,10,9,118,76,105,103,104,116,84,111,87,111,114,108,100,91,50,93,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,78,111,114,109,97,108,41,59,13,10,9,35,101,108,115,101,13,10,9,118,78,111,114,109,97,108,32,61,32,110,111,114,109,97,108,105,122,101,40,114,111,116,97,116,105,111,110,77,97,116,114,105,120,32,42,32,86,101,114,116,101,120,78,111,114,109,97,108,41,59,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,84,69,88,84,85,82,69,95,77,65,80,80,73,78,71,13,10,9,118,84,101,120,67,111,111,114,100,32,61,32,118,101,99,50,40,116,101,120,67,111,111,114,100,115,41,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,80,65,82,65,76,76,65,88,95,77,65,80,80,73,78,71,13,10,9,118,86,105,101,119,68,105,114,32,61,32,69,121,101,80,111,115,105,116,105,111,110,32,45,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,32,13,10,9,118,86,105,101,119,68,105,114,32,42,61,32,118,76,105,103,104,116,84,111,87,111,114,108,100,59,13,10,35,101,110,100,105,102,13,10,13,10,35,105,102,32,76,73,71,72,84,73,78,71,32,38,38,32,33,70,76,65,71,95,68,69,70,69,82,82,69,68,13,10,9,35,105,102,32,70,76,65,71,95,73,78,83,84,65,78,67,73,78,71,13,10,9,118,87,111,114,108,100,80,111,115,32,61,32,118,101,99,51,40,73,110,115,116,97,110,99,101,68,97,116,97,48,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,41,59,13,10,9,35,101,108,115,101,13,10,9,118,87,111,114,108,100,80,111,115,32,61,32,118,101,99,51,40,87,111,114,108,100,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,41,59,13,10,9,35,101,110,100,105,102,13,10,35,101,110,100,105,102,13,10,125,13,10, \ No newline at end of file diff --git a/src/Nazara/Graphics/SkyboxBackground.cpp b/src/Nazara/Graphics/SkyboxBackground.cpp index ba806d76b..319dad2af 100644 --- a/src/Nazara/Graphics/SkyboxBackground.cpp +++ b/src/Nazara/Graphics/SkyboxBackground.cpp @@ -45,20 +45,6 @@ namespace NzShader* BuildShader() { - const char* fragmentSource110 = - "#version 110\n" - - "varying vec3 vTexCoord;\n" - - "uniform samplerCube Skybox;\n" - "uniform float VertexDepth;\n" - - "void main()\n" - "{\n" - " gl_FragColor = textureCube(Skybox, vTexCoord);\n" - " gl_FragDepth = VertexDepth;\n" - "}\n"; - const char* fragmentSource140 = "#version 140\n" @@ -75,21 +61,6 @@ namespace " gl_FragDepth = VertexDepth;\n" "}\n"; - const char* vertexSource110 = - "#version 110\n" - - "attribute vec3 VertexPosition;\n" - - "varying vec3 vTexCoord;\n" - - "uniform mat4 WorldViewProjMatrix;\n" - - "void main()\n" - "{\n" - " gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0);\n" - " vTexCoord = vec3(VertexPosition.x, VertexPosition.y, -VertexPosition.z);\n" - "}\n"; - const char* vertexSource140 = "#version 140\n" @@ -115,15 +86,13 @@ namespace return nullptr; } - bool useGLSL140 = (NzOpenGL::GetVersion() >= 310); - - if (!shader->AttachStageFromSource(nzShaderStage_Fragment, (useGLSL140) ? fragmentSource140 : fragmentSource110)) + if (!shader->AttachStageFromSource(nzShaderStage_Fragment, fragmentSource140)) { NazaraError("Failed to load fragment shader"); return nullptr; } - if (!shader->AttachStageFromSource(nzShaderStage_Vertex, (useGLSL140) ? vertexSource140 : vertexSource110)) + if (!shader->AttachStageFromSource(nzShaderStage_Vertex, vertexSource140)) { NazaraError("Failed to load vertex shader"); return nullptr; diff --git a/src/Nazara/Renderer/GpuQuery.cpp b/src/Nazara/Renderer/GpuQuery.cpp index 37b03ebe7..32dfdb586 100644 --- a/src/Nazara/Renderer/GpuQuery.cpp +++ b/src/Nazara/Renderer/GpuQuery.cpp @@ -11,20 +11,12 @@ #include #include -NzGpuQuery::NzGpuQuery() : -m_id(0) +NzGpuQuery::NzGpuQuery() { - if (IsSupported()) - { - NzContext::EnsureContext(); + NzContext::EnsureContext(); - glGenQueries(1, reinterpret_cast(&m_id)); - } - else - { - NazaraError("Occlusion queries not supported"); - return; - } + m_id = 0; + glGenQueries(1, reinterpret_cast(&m_id)); #ifdef NAZARA_DEBUG if (!m_id) @@ -110,15 +102,13 @@ bool NzGpuQuery::IsModeSupported(nzGpuQueryMode mode) { switch (mode) { - case nzGpuQueryMode_AnySamplesPassed: - case nzGpuQueryMode_TimeElapsed: - return NzOpenGL::GetVersion() >= 330; - case nzGpuQueryMode_AnySamplesPassedConservative: return NzOpenGL::GetVersion() >= 430; + case nzGpuQueryMode_AnySamplesPassed: case nzGpuQueryMode_PrimitiveGenerated: case nzGpuQueryMode_SamplesPassed: + case nzGpuQueryMode_TimeElapsed: case nzGpuQueryMode_TransformFeedbackPrimitivesWritten: return true; } @@ -126,8 +116,3 @@ bool NzGpuQuery::IsModeSupported(nzGpuQueryMode mode) NazaraError("Gpu Query mode not handled (0x" + NzString::Number(mode, 16) + ')'); return false; } - -bool NzGpuQuery::IsSupported() -{ - return NzRenderer::HasCapability(nzRendererCap_OcclusionQuery); -} diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index 01f60a39f..c1bec3aa4 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -797,10 +797,10 @@ bool NzOpenGL::Initialize() NazaraDebug("OpenGL version: " + NzString::Number(major) + '.' + NzString::Number(minor)); - // Le moteur ne fonctionnera pas avec OpenGL 1.x, autant s'arrêter là si c'est le cas - if (s_openglVersion < 200) + // Le moteur nécessite OpenGL 3.3, autant s'arrêter là si c'est le cas + if (s_openglVersion < 330) { - NazaraError("OpenGL " + NzString::Number(major) + '.' + NzString::Number(minor) + " detected (2.0 required). Please upgrade your drivers or your video card"); + NazaraError("OpenGL " + NzString::Number(major) + '.' + NzString::Number(minor) + " detected (3.3 required). Please upgrade your drivers or your video card"); return false; } @@ -829,10 +829,8 @@ bool NzOpenGL::Initialize() s_glslVersion = major*100 + minor*10; // GLSL 3.3 => 330 - // Possible uniquement dans le cas où le GLSL vient d'une extension d'OpenGL 1 - // Ce qui est rejeté il y a un moment déjà, mais on doit s'attendre à tout de la part d'un driver... - // (Exemple: Un driver OpenGL 2 mais ne supportant que le GLSL 100) - if (s_glslVersion < 110) + // Normalement rejeté il y a un moment déjà, mais on doit s'attendre à tout de la part d'un driver... + if (s_glslVersion < 330) { NazaraError("GLSL version is too low, please upgrade your drivers or your video card"); return false; @@ -854,18 +852,26 @@ bool NzOpenGL::Initialize() { glActiveTexture = reinterpret_cast(LoadEntry("glActiveTexture")); glAttachShader = reinterpret_cast(LoadEntry("glAttachShader")); + glBeginConditionalRender = reinterpret_cast(LoadEntry("glBeginConditionalRender")); glBeginQuery = reinterpret_cast(LoadEntry("glBeginQuery")); glBindAttribLocation = reinterpret_cast(LoadEntry("glBindAttribLocation")); glBindBuffer = reinterpret_cast(LoadEntry("glBindBuffer")); + glBindFragDataLocation = reinterpret_cast(LoadEntry("glBindFragDataLocation")); + glBindFramebuffer = reinterpret_cast(LoadEntry("glBindFramebuffer")); + glBindRenderbuffer = reinterpret_cast(LoadEntry("glBindRenderbuffer")); + glBindSampler = reinterpret_cast(LoadEntry("glBindSampler")); glBindTexture = reinterpret_cast(LoadEntry("glBindTexture")); + glBindVertexArray = reinterpret_cast(LoadEntry("glBindVertexArray")); glBlendFunc = reinterpret_cast(LoadEntry("glBlendFunc")); glBlendFuncSeparate = reinterpret_cast(LoadEntry("glBlendFuncSeparate")); + glBlitFramebuffer = reinterpret_cast(LoadEntry("glBlitFramebuffer")); glBufferData = reinterpret_cast(LoadEntry("glBufferData")); glBufferSubData = reinterpret_cast(LoadEntry("glBufferSubData")); glClear = reinterpret_cast(LoadEntry("glClear")); glClearColor = reinterpret_cast(LoadEntry("glClearColor")); glClearDepth = reinterpret_cast(LoadEntry("glClearDepth")); glClearStencil = reinterpret_cast(LoadEntry("glClearStencil")); + glCheckFramebufferStatus = reinterpret_cast(LoadEntry("glCheckFramebufferStatus")); glCreateProgram = reinterpret_cast(LoadEntry("glCreateProgram")); glCreateShader = reinterpret_cast(LoadEntry("glCreateShader")); glColorMask = reinterpret_cast(LoadEntry("glColorMask")); @@ -873,25 +879,43 @@ bool NzOpenGL::Initialize() glCompileShader = reinterpret_cast(LoadEntry("glCompileShader")); glCopyTexSubImage2D = reinterpret_cast(LoadEntry("glCopyTexSubImage2D")); glDeleteBuffers = reinterpret_cast(LoadEntry("glDeleteBuffers")); + glDeleteFramebuffers = reinterpret_cast(LoadEntry("glDeleteFramebuffers")); glDeleteQueries = reinterpret_cast(LoadEntry("glDeleteQueries")); glDeleteProgram = reinterpret_cast(LoadEntry("glDeleteProgram")); + glDeleteRenderbuffers = reinterpret_cast(LoadEntry("glDeleteRenderbuffers")); + glDeleteSamplers = reinterpret_cast(LoadEntry("glDeleteSamplers")); glDeleteShader = reinterpret_cast(LoadEntry("glDeleteShader")); glDeleteTextures = reinterpret_cast(LoadEntry("glDeleteTextures")); + glDeleteVertexArrays = reinterpret_cast(LoadEntry("glDeleteVertexArrays")); glDepthFunc = reinterpret_cast(LoadEntry("glDepthFunc")); glDepthMask = reinterpret_cast(LoadEntry("glDepthMask")); glDisable = reinterpret_cast(LoadEntry("glDisable")); glDisableVertexAttribArray = reinterpret_cast(LoadEntry("glDisableVertexAttribArray")); glDrawArrays = reinterpret_cast(LoadEntry("glDrawArrays")); + glDrawArraysInstanced = reinterpret_cast(LoadEntry("glDrawArraysInstanced")); glDrawBuffer = reinterpret_cast(LoadEntry("glDrawBuffer")); glDrawBuffers = reinterpret_cast(LoadEntry("glDrawBuffers")); glDrawElements = reinterpret_cast(LoadEntry("glDrawElements")); + glDrawElementsInstanced = reinterpret_cast(LoadEntry("glDrawElementsInstanced")); glEnable = reinterpret_cast(LoadEntry("glEnable")); glEnableVertexAttribArray = reinterpret_cast(LoadEntry("glEnableVertexAttribArray")); + glEndConditionalRender = reinterpret_cast(LoadEntry("glEndConditionalRender")); glEndQuery = reinterpret_cast(LoadEntry("glEndQuery")); glFlush = reinterpret_cast(LoadEntry("glFlush")); + glFramebufferRenderbuffer = reinterpret_cast(LoadEntry("glFramebufferRenderbuffer")); + glFramebufferTexture = reinterpret_cast(LoadEntry("glFramebufferTexture")); + glFramebufferTexture1D = reinterpret_cast(LoadEntry("glFramebufferTexture1D")); + glFramebufferTexture2D = reinterpret_cast(LoadEntry("glFramebufferTexture2D")); + glFramebufferTexture3D = reinterpret_cast(LoadEntry("glFramebufferTexture3D")); + glFramebufferTextureLayer = reinterpret_cast(LoadEntry("glFramebufferTextureLayer")); + glGenerateMipmap = reinterpret_cast(LoadEntry("glGenerateMipmap")); glGenBuffers = reinterpret_cast(LoadEntry("glGenBuffers")); + glGenFramebuffers = reinterpret_cast(LoadEntry("glGenFramebuffers")); glGenQueries = reinterpret_cast(LoadEntry("glGenQueries")); + glGenRenderbuffers = reinterpret_cast(LoadEntry("glGenRenderbuffers")); + glGenSamplers = reinterpret_cast(LoadEntry("glGenSamplers")); glGenTextures = reinterpret_cast(LoadEntry("glGenTextures")); + glGenVertexArrays = reinterpret_cast(LoadEntry("glGenVertexArrays")); glGetActiveUniform = reinterpret_cast(LoadEntry("glGetActiveUniform")); glGetBooleanv = reinterpret_cast(LoadEntry("glGetBooleanv")); glGetBufferParameteriv = reinterpret_cast(LoadEntry("glGetBufferParameteriv")); @@ -906,6 +930,7 @@ bool NzOpenGL::Initialize() glGetShaderInfoLog = reinterpret_cast(LoadEntry("glGetShaderInfoLog")); glGetShaderiv = reinterpret_cast(LoadEntry("glGetShaderiv")); glGetShaderSource = reinterpret_cast(LoadEntry("glGetShaderSource")); + glGetStringi = reinterpret_cast(LoadEntry("glGetStringi")); glGetTexImage = reinterpret_cast(LoadEntry("glGetTexImage")); glGetTexLevelParameterfv = reinterpret_cast(LoadEntry("glGetTexLevelParameterfv")); glGetTexLevelParameteriv = reinterpret_cast(LoadEntry("glGetTexLevelParameteriv")); @@ -916,10 +941,14 @@ bool NzOpenGL::Initialize() glLineWidth = reinterpret_cast(LoadEntry("glLineWidth")); glLinkProgram = reinterpret_cast(LoadEntry("glLinkProgram")); glMapBuffer = reinterpret_cast(LoadEntry("glMapBuffer")); + glMapBufferRange = reinterpret_cast(LoadEntry("glMapBufferRange")); glPixelStorei = reinterpret_cast(LoadEntry("glPixelStorei")); glPointSize = reinterpret_cast(LoadEntry("glPointSize")); glPolygonMode = reinterpret_cast(LoadEntry("glPolygonMode")); glReadPixels = reinterpret_cast(LoadEntry("glReadPixels")); + glRenderbufferStorage = reinterpret_cast(LoadEntry("glRenderbufferStorage")); + glSamplerParameterf = reinterpret_cast(LoadEntry("glSamplerParameterf")); + glSamplerParameteri = reinterpret_cast(LoadEntry("glSamplerParameteri")); glScissor = reinterpret_cast(LoadEntry("glScissor")); glShaderSource = reinterpret_cast(LoadEntry("glShaderSource")); glStencilFunc = reinterpret_cast(LoadEntry("glStencilFunc")); @@ -946,7 +975,9 @@ bool NzOpenGL::Initialize() glUnmapBuffer = reinterpret_cast(LoadEntry("glUnmapBuffer")); glUseProgram = reinterpret_cast(LoadEntry("glUseProgram")); glVertexAttrib4f = reinterpret_cast(LoadEntry("glVertexAttrib4f")); + glVertexAttribDivisor = reinterpret_cast(LoadEntry("glVertexAttribDivisor")); glVertexAttribPointer = reinterpret_cast(LoadEntry("glVertexAttribPointer")); + glVertexAttribIPointer = reinterpret_cast(LoadEntry("glVertexAttribIPointer")); glViewport = reinterpret_cast(LoadEntry("glViewport")); } catch (const std::exception& e) @@ -958,16 +989,10 @@ bool NzOpenGL::Initialize() /****************************************Extensions****************************************/ // Fonctions optionnelles - glBindFragDataLocation = reinterpret_cast(LoadEntry("glBindFragDataLocation", false)); - if (!glBindFragDataLocation) - glBindFragDataLocation = reinterpret_cast(LoadEntry("glBindFragDataLocationEXT", false)); + glBindFragDataLocation = reinterpret_cast(LoadEntry("glBindFragDataLocation")); glDrawTexture = reinterpret_cast(LoadEntry("glDrawTextureNV", false)); - glFramebufferTexture = reinterpret_cast(LoadEntry("glFramebufferTexture", false)); - glGetStringi = reinterpret_cast(LoadEntry("glGetStringi", false)); glInvalidateBufferData = reinterpret_cast(LoadEntry("glInvalidateBufferData", false)); - glMapBufferRange = reinterpret_cast(LoadEntry("glMapBufferRange", false)); - glVertexAttribIPointer = reinterpret_cast(LoadEntry("glVertexAttribIPointer", false)); glVertexAttribLPointer = reinterpret_cast(LoadEntry("glVertexAttribLPointer", false)); #if defined(NAZARA_PLATFORM_WINDOWS) @@ -980,8 +1005,7 @@ bool NzOpenGL::Initialize() if (!glGetStringi || !LoadExtensions3()) { - if (s_openglVersion >= 300) // Dans le cas contraire c'est normal - NazaraWarning("Failed to load OpenGL 3 extension system, switching to OpenGL 2 extension system..."); + NazaraWarning("Failed to load OpenGL 3 extension system, falling back to OpenGL 2 extension system..."); if (!LoadExtensionsString(reinterpret_cast(glGetString(GL_EXTENSIONS)))) NazaraWarning("Failed to load extension system"); @@ -1005,37 +1029,6 @@ bool NzOpenGL::Initialize() // AnisotropicFilter s_openGLextensions[nzOpenGLExtension_AnisotropicFilter] = IsSupported("GL_EXT_texture_filter_anisotropic"); - // ConditionalRender - if (s_openglVersion >= 300) - { - try - { - glBeginConditionalRender = reinterpret_cast(LoadEntry("glBeginConditionalRender")); - glEndConditionalRender = reinterpret_cast(LoadEntry("glEndConditionalRender")); - - s_openGLextensions[nzOpenGLExtension_ConditionalRender] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load Conditional Render: " + NzString(e.what())); - } - } - - if (!s_openGLextensions[nzOpenGLExtension_ConditionalRender] && IsSupported("GL_NV_conditional_render")) - { - try - { - glBeginConditionalRender = reinterpret_cast(LoadEntry("glBeginConditionalRenderNV")); - glEndConditionalRender = reinterpret_cast(LoadEntry("glEndConditionalRenderNV")); - - s_openGLextensions[nzOpenGLExtension_ConditionalRender] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load GL_NV_conditional_render: " + NzString(e.what())); - } - } - // DebugOutput if (s_openglVersion >= 430 || IsSupported("GL_KHR_debug")) { @@ -1071,37 +1064,6 @@ bool NzOpenGL::Initialize() } } - // DrawInstanced - if (s_openglVersion >= 310) - { - try - { - glDrawArraysInstanced = reinterpret_cast(LoadEntry("glDrawArraysInstanced")); - glDrawElementsInstanced = reinterpret_cast(LoadEntry("glDrawElementsInstanced")); - - s_openGLextensions[nzOpenGLExtension_DrawInstanced] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load Draw Instanced: " + NzString(e.what())); - } - } - - if (!s_openGLextensions[nzOpenGLExtension_DrawInstanced] && IsSupported("GL_ARB_draw_instanced")) - { - try - { - glDrawArraysInstanced = reinterpret_cast(LoadEntry("glDrawArraysInstancedARB")); - glDrawElementsInstanced = reinterpret_cast(LoadEntry("glDrawElementsInstancedARB")); - - s_openGLextensions[nzOpenGLExtension_DrawInstanced] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load GL_ARB_draw_instanced: " + NzString(e.what())); - } - } - // FP64 if (s_openglVersion >= 400 || IsSupported("GL_ARB_gpu_shader_fp64")) { @@ -1121,35 +1083,6 @@ bool NzOpenGL::Initialize() } } - // FrameBufferObject - if (s_openglVersion >= 300 || IsSupported("GL_ARB_framebuffer_object")) - { - try - { - glBindFramebuffer = reinterpret_cast(LoadEntry("glBindFramebuffer")); - glBindRenderbuffer = reinterpret_cast(LoadEntry("glBindRenderbuffer")); - glBlitFramebuffer = reinterpret_cast(LoadEntry("glBlitFramebuffer")); - glCheckFramebufferStatus = reinterpret_cast(LoadEntry("glCheckFramebufferStatus")); - glDeleteFramebuffers = reinterpret_cast(LoadEntry("glDeleteFramebuffers")); - glDeleteRenderbuffers = reinterpret_cast(LoadEntry("glDeleteRenderbuffers")); - glFramebufferRenderbuffer = reinterpret_cast(LoadEntry("glFramebufferRenderbuffer")); - glFramebufferTexture1D = reinterpret_cast(LoadEntry("glFramebufferTexture1D")); - glFramebufferTexture2D = reinterpret_cast(LoadEntry("glFramebufferTexture2D")); - glFramebufferTexture3D = reinterpret_cast(LoadEntry("glFramebufferTexture3D")); - glFramebufferTextureLayer = reinterpret_cast(LoadEntry("glFramebufferTextureLayer")); - glGenerateMipmap = reinterpret_cast(LoadEntry("glGenerateMipmap")); - glGenFramebuffers = reinterpret_cast(LoadEntry("glGenFramebuffers")); - glGenRenderbuffers = reinterpret_cast(LoadEntry("glGenRenderbuffers")); - glRenderbufferStorage = reinterpret_cast(LoadEntry("glRenderbufferStorage")); - - s_openGLextensions[nzOpenGLExtension_FrameBufferObject] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load ARB_framebuffer_object: (" + NzString(e.what()) + ")"); - } - } - // GetProgramBinary if (s_openglVersion >= 410 || IsSupported("GL_ARB_get_program_binary")) { @@ -1167,57 +1100,6 @@ bool NzOpenGL::Initialize() } } - // InstancedArray - if (s_openglVersion >= 330) - { - try - { - glVertexAttribDivisor = reinterpret_cast(LoadEntry("glVertexAttribDivisor")); - - s_openGLextensions[nzOpenGLExtension_InstancedArray] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load Instanced Array: " + NzString(e.what())); - } - } - - if (!s_openGLextensions[nzOpenGLExtension_InstancedArray] && IsSupported("GL_ARB_instanced_arrays")) - { - try - { - glVertexAttribDivisor = reinterpret_cast(LoadEntry("glVertexAttribDivisorARB")); - - s_openGLextensions[nzOpenGLExtension_InstancedArray] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load GL_ARB_instanced_arrays: " + NzString(e.what())); - } - } - - // PixelBufferObject - s_openGLextensions[nzOpenGLExtension_PixelBufferObject] = (s_openglVersion >= 210 || IsSupported("GL_ARB_pixel_buffer_object")); - - // SamplerObjects - if (s_openglVersion >= 330 || IsSupported("GL_ARB_sampler_objects")) - { - try - { - glBindSampler = reinterpret_cast(LoadEntry("glBindSampler")); - glDeleteSamplers = reinterpret_cast(LoadEntry("glDeleteSamplers")); - glGenSamplers = reinterpret_cast(LoadEntry("glGenSamplers")); - glSamplerParameterf = reinterpret_cast(LoadEntry("glSamplerParameterf")); - glSamplerParameteri = reinterpret_cast(LoadEntry("glSamplerParameteri")); - - s_openGLextensions[nzOpenGLExtension_SamplerObjects] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load ARB_sampler_objects: (" + NzString(e.what()) + ")"); - } - } - // SeparateShaderObjects if (s_openglVersion >= 400 || IsSupported("GL_ARB_separate_shader_objects")) { @@ -1257,9 +1139,6 @@ bool NzOpenGL::Initialize() // Shader_ImageLoadStore s_openGLextensions[nzOpenGLExtension_Shader_ImageLoadStore] = (s_openglVersion >= 420 || IsSupported("GL_ARB_shader_image_load_store")); - // TextureArray - s_openGLextensions[nzOpenGLExtension_TextureArray] = (s_openglVersion >= 300 || IsSupported("GL_EXT_texture_array")); - // TextureCompression_s3tc s_openGLextensions[nzOpenGLExtension_TextureCompression_s3tc] = IsSupported("GL_EXT_texture_compression_s3tc"); @@ -1280,27 +1159,6 @@ bool NzOpenGL::Initialize() } } - // VertexArrayObject - if (s_openglVersion >= 300 || IsSupported("GL_ARB_vertex_array_object")) - { - try - { - glBindVertexArray = reinterpret_cast(LoadEntry("glBindVertexArray")); - glDeleteVertexArrays = reinterpret_cast(LoadEntry("glDeleteVertexArrays")); - glGenVertexArrays = reinterpret_cast(LoadEntry("glGenVertexArrays")); - - s_openGLextensions[nzOpenGLExtension_VertexArrayObjects] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load ARB_vertex_array_object: " + NzString(e.what())); - } - } - - // Fonctions de substitut - if (!glGenerateMipmap) - glGenerateMipmap = reinterpret_cast(LoadEntry("glGenerateMipmapEXT", false)); - /******************************Initialisation*****************************/ s_contextStates = nullptr; diff --git a/src/Nazara/Renderer/RenderBuffer.cpp b/src/Nazara/Renderer/RenderBuffer.cpp index 9e6cdb79f..45cae54b7 100644 --- a/src/Nazara/Renderer/RenderBuffer.cpp +++ b/src/Nazara/Renderer/RenderBuffer.cpp @@ -110,11 +110,6 @@ bool NzRenderBuffer::IsValid() const return m_id != 0; } -bool NzRenderBuffer::IsSupported() -{ - return NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject); -} - bool NzRenderBuffer::Initialize() { if (!NzRenderBufferLibrary::Initialize()) diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index 4f1b53962..f12d060ec 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -329,12 +329,6 @@ bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 i bool NzRenderTexture::Create(bool lock) { - if (!IsSupported()) - { - NazaraError("Render textures not supported"); - return false; - } - Destroy(); #if NAZARA_RENDERER_SAFE @@ -742,11 +736,6 @@ bool NzRenderTexture::HasContext() const return false; } -bool NzRenderTexture::IsSupported() -{ - return NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject); -} - void NzRenderTexture::Blit(NzRenderTexture* src, NzRenderTexture* dst, nzUInt32 buffers, bool bilinearFilter) { #if NAZARA_RENDERER_SAFE diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index d536c85ba..b9c00db97 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -33,6 +33,8 @@ #include #include +///TODO: Manager les VAO (permettre plusieurs draw calls sans rebinder le VAO) + namespace { const nzUInt8 r_coreFragmentShader[] = { @@ -43,14 +45,6 @@ namespace #include }; - const nzUInt8 r_compatibilityFragmentShader[] = { - #include - }; - - const nzUInt8 r_compatibilityVertexShader[] = { - #include - }; - enum ObjectType { ObjectType_Context, @@ -133,8 +127,6 @@ namespace const NzVertexBuffer* s_vertexBuffer; bool s_capabilities[nzRendererCap_Max+1]; bool s_instancing; - bool s_useSamplerObjects; - bool s_useVertexArrayObjects; unsigned int s_maxColorAttachments; unsigned int s_maxRenderTarget; unsigned int s_maxTextureSize; @@ -269,14 +261,6 @@ void NzRenderer::BeginCondition(const NzGpuQuery& query, nzGpuQueryCondition con } #endif - #if NAZARA_RENDERER_SAFE - if (!s_capabilities[nzRendererCap_ConditionalRendering]) - { - NazaraError("Conditional rendering is not supported"); - return; - } - #endif - glBeginConditionalRender(query.GetOpenGLID(), NzOpenGL::QueryCondition[condition]); } @@ -333,9 +317,7 @@ void NzRenderer::DrawFullscreenQuad() } glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - if (s_useVertexArrayObjects) - glBindVertexArray(0); + glBindVertexArray(0); } void NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount) @@ -385,9 +367,7 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode mode, unsigned int firstI } glDrawElements(NzOpenGL::PrimitiveMode[mode], indexCount, type, offset); - - if (s_useVertexArrayObjects) - glBindVertexArray(0); + glBindVertexArray(0); } void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount) @@ -407,12 +387,6 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr #endif #if NAZARA_RENDERER_SAFE - if (!s_capabilities[nzRendererCap_Instancing]) - { - NazaraError("Instancing not supported"); - return; - } - if (!s_indexBuffer) { NazaraError("No index buffer"); @@ -456,9 +430,7 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr } glDrawElementsInstanced(NzOpenGL::PrimitiveMode[mode], indexCount, type, offset, instanceCount); - - if (s_useVertexArrayObjects) - glBindVertexArray(0); + glBindVertexArray(0); } void NzRenderer::DrawPrimitives(nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount) @@ -486,9 +458,7 @@ void NzRenderer::DrawPrimitives(nzPrimitiveMode mode, unsigned int firstVertex, } glDrawArrays(NzOpenGL::PrimitiveMode[mode], firstVertex, vertexCount); - - if (s_useVertexArrayObjects) - glBindVertexArray(0); + glBindVertexArray(0); } void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount) @@ -508,12 +478,6 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive #endif #if NAZARA_RENDERER_SAFE - if (!s_capabilities[nzRendererCap_Instancing]) - { - NazaraError("Instancing not supported"); - return; - } - if (instanceCount == 0) { NazaraError("Instance count must be over zero"); @@ -537,9 +501,7 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive } glDrawArraysInstanced(NzOpenGL::PrimitiveMode[mode], firstVertex, vertexCount, instanceCount); - - if (s_useVertexArrayObjects) - glBindVertexArray(0); + glBindVertexArray(0); } void NzRenderer::Enable(nzRendererParameter parameter, bool enable) @@ -571,14 +533,6 @@ void NzRenderer::EndCondition() } #endif - #if NAZARA_RENDERER_SAFE - if (!s_capabilities[nzRendererCap_ConditionalRendering]) - { - NazaraError("Conditional rendering is not supported"); - return; - } - #endif - glEndConditionalRender(); } @@ -602,14 +556,6 @@ nzRendererComparison NzRenderer::GetDepthFunc() NzVertexBuffer* NzRenderer::GetInstanceBuffer() { - #if NAZARA_RENDERER_SAFE - if (!s_capabilities[nzRendererCap_Instancing]) - { - NazaraError("Instancing not supported"); - return nullptr; - } - #endif - s_updateFlags |= Update_VAO; return &s_instanceBuffer; } @@ -757,19 +703,10 @@ bool NzRenderer::Initialize() } // Récupération des capacités d'OpenGL - s_capabilities[nzRendererCap_AnisotropicFilter] = NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter); - s_capabilities[nzRendererCap_ConditionalRendering] = NzOpenGL::IsSupported(nzOpenGLExtension_ConditionalRender); - s_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(nzOpenGLExtension_FP64); - s_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5 - s_capabilities[nzRendererCap_Instancing] = NzOpenGL::IsSupported(nzOpenGLExtension_DrawInstanced) && NzOpenGL::IsSupported(nzOpenGLExtension_InstancedArray); - s_capabilities[nzRendererCap_MultipleRenderTargets] = (glBindFragDataLocation != nullptr); // Natif depuis OpenGL 2.0 mais inutile sans glBindFragDataLocation - s_capabilities[nzRendererCap_OcclusionQuery] = true; // Natif depuis OpenGL 1.5 - s_capabilities[nzRendererCap_PixelBufferObject] = NzOpenGL::IsSupported(nzOpenGLExtension_PixelBufferObject); - s_capabilities[nzRendererCap_RenderTexture] = NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject); - s_capabilities[nzRendererCap_Texture3D] = true; // Natif depuis OpenGL 1.2 - s_capabilities[nzRendererCap_TextureCubemap] = true; // Natif depuis OpenGL 1.3 - s_capabilities[nzRendererCap_TextureMulti] = true; // Natif depuis OpenGL 1.3 - s_capabilities[nzRendererCap_TextureNPOT] = true; // Natif depuis OpenGL 2.0 + s_capabilities[nzRendererCap_AnisotropicFilter] = NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter); + s_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(nzOpenGLExtension_FP64); + s_capabilities[nzRendererCap_PixelBufferObject] = NzOpenGL::IsSupported(nzOpenGLExtension_PixelBufferObject); + s_capabilities[nzRendererCap_Instancing] = true; // Supporté par OpenGL 3.3 NzContext::EnsureContext(); @@ -783,39 +720,21 @@ bool NzRenderer::Initialize() else s_maxAnisotropyLevel = 1; - if (s_capabilities[nzRendererCap_RenderTexture]) - { - GLint maxColorAttachments; - glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments); + GLint maxColorAttachments; + glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments); + s_maxColorAttachments = static_cast(maxColorAttachments); - s_maxColorAttachments = static_cast(maxColorAttachments); - } - else - s_maxColorAttachments = 1; + GLint maxDrawBuffers; + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); + s_maxRenderTarget = static_cast(maxDrawBuffers); - if (s_capabilities[nzRendererCap_MultipleRenderTargets]) - { - GLint maxDrawBuffers; - glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); - - s_maxRenderTarget = static_cast(maxDrawBuffers); - } - else - s_maxRenderTarget = 1; - - if (s_capabilities[nzRendererCap_TextureMulti]) - { - GLint maxTextureUnits; - glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits); - - s_maxTextureUnit = static_cast(maxTextureUnits); - } - else - s_maxTextureUnit = 1; + GLint maxTextureUnits; + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits); + s_maxTextureUnit = static_cast(maxTextureUnits); GLint maxTextureSize; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); - s_maxTextureSize = maxTextureSize; + s_maxTextureSize = static_cast(maxTextureSize); GLint maxVertexAttribs; glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); @@ -828,8 +747,6 @@ bool NzRenderer::Initialize() s_target = nullptr; s_targetSize.Set(0U); s_textureUnits.resize(s_maxTextureUnit); - s_useSamplerObjects = NzOpenGL::IsSupported(nzOpenGLExtension_SamplerObjects); - s_useVertexArrayObjects = NzOpenGL::IsSupported(nzOpenGLExtension_VertexArrayObjects); s_updateFlags = Update_Matrices | Update_Shader | Update_VAO; s_vertexBuffer = nullptr; @@ -903,32 +820,13 @@ bool NzRenderer::Initialize() return false; } - const char* fragmentShader; - const char* vertexShader; - unsigned int fragmentShaderLength; - unsigned int vertexShaderLength; - if (NzOpenGL::GetGLSLVersion() >= 140) - { - fragmentShader = reinterpret_cast(r_coreFragmentShader); - fragmentShaderLength = sizeof(r_coreFragmentShader); - vertexShader = reinterpret_cast(r_coreVertexShader); - vertexShaderLength = sizeof(r_coreVertexShader); - } - else - { - fragmentShader = reinterpret_cast(r_compatibilityFragmentShader); - fragmentShaderLength = sizeof(r_compatibilityFragmentShader); - vertexShader = reinterpret_cast(r_compatibilityVertexShader); - vertexShaderLength = sizeof(r_compatibilityVertexShader); - } - - if (!debugShader->AttachStageFromSource(nzShaderStage_Fragment, fragmentShader, fragmentShaderLength)) + if (!debugShader->AttachStageFromSource(nzShaderStage_Fragment, reinterpret_cast(r_coreFragmentShader), sizeof(r_coreFragmentShader))) { NazaraError("Failed to attach fragment stage"); return false; } - if (!debugShader->AttachStageFromSource(nzShaderStage_Vertex, vertexShader, vertexShaderLength)) + if (!debugShader->AttachStageFromSource(nzShaderStage_Vertex, reinterpret_cast(r_coreVertexShader), sizeof(r_coreVertexShader))) { NazaraError("Failed to attach vertex stage"); return false; @@ -1677,36 +1575,16 @@ bool NzRenderer::EnsureStateUpdate() { if (s_updateFlags & Update_Textures) { - if (s_useSamplerObjects) + for (unsigned int i : s_dirtyTextureUnits) { - for (unsigned int i : s_dirtyTextureUnits) - { - TextureUnit& unit = s_textureUnits[i]; + TextureUnit& unit = s_textureUnits[i]; - if (unit.texture && !unit.samplerUpdated) - { - unit.sampler.Bind(i); - unit.samplerUpdated = true; - } + if (unit.texture && !unit.samplerUpdated) + { + unit.sampler.Bind(i); + unit.samplerUpdated = true; } } - else - { - for (unsigned int i : s_dirtyTextureUnits) - { - TextureUnit& unit = s_textureUnits[i]; - - if (unit.texture && !unit.samplerUpdated) - { - NzOpenGL::BindTextureUnit(i); - unit.sampler.Apply(unit.texture); - unit.samplerUpdated = true; - } - } - } - - s_dirtyTextureUnits.clear(); // Ne change pas la capacité - s_updateFlags &= ~Update_Textures; } if (s_updateFlags & Update_Matrices) @@ -1736,68 +1614,45 @@ bool NzRenderer::EnsureStateUpdate() } #endif - bool update; - VAO_Map::iterator vaoIt; + // Note: Les VAOs ne sont pas partagés entre les contextes, nous avons donc un tableau de VAOs par contexte + const NzContext* context = NzContext::GetCurrent(); - // Si les VAOs sont supportés, on entoure nos appels par ceux-ci - if (s_useVertexArrayObjects) + auto it = s_vaos.find(context); + if (it == s_vaos.end()) { - // Note: Les VAOs ne sont pas partagés entre les contextes, nous avons donc un tableau de VAOs par contexte - const NzContext* context = NzContext::GetCurrent(); + Context_Entry entry(&s_listener, ObjectType_Context); + entry.contextListener = context; - auto it = s_vaos.find(context); - if (it == s_vaos.end()) - { - Context_Entry entry(&s_listener, ObjectType_Context); - entry.contextListener = context; - - it = s_vaos.insert(std::make_pair(context, std::move(entry))).first; - } - - VAO_Map& vaoMap = it->second.vaoMap; - - // Notre clé est composée de ce qui définit un VAO - const NzVertexDeclaration* vertexDeclaration = s_vertexBuffer->GetVertexDeclaration(); - const NzVertexDeclaration* instancingDeclaration = (s_instancing) ? s_instanceBuffer.GetVertexDeclaration() : nullptr; - VAO_Key key(s_indexBuffer, s_vertexBuffer, vertexDeclaration, instancingDeclaration); - - // On recherche un VAO existant avec notre configuration - vaoIt = vaoMap.find(key); - if (vaoIt == vaoMap.end()) - { - // On créé notre VAO - glGenVertexArrays(1, &s_currentVAO); - glBindVertexArray(s_currentVAO); - - // On l'ajoute à notre liste - VAO_Entry entry(&s_listener, ObjectType_IndexBuffer, ObjectType_VertexBuffer, ObjectType_VertexDeclaration, ObjectType_VertexDeclaration); - entry.indexBufferListener = std::get<0>(key); - entry.instancingDeclarationListener = std::get<3>(key); - entry.vertexBufferListener = std::get<1>(key); - entry.vertexDeclarationListener = std::get<2>(key); - entry.vao = s_currentVAO; - - vaoIt = vaoMap.insert(std::make_pair(key, std::move(entry))).first; - - // Et on indique qu'on veut le programmer - update = true; - } - else - { - // Notre VAO existe déjà, il est donc inutile de le reprogrammer - s_currentVAO = vaoIt->second.vao; - - update = false; - } + it = s_vaos.insert(std::make_pair(context, std::move(entry))).first; } - else - update = true; // Fallback si les VAOs ne sont pas supportés - bool updateFailed = false; + VAO_Map& vaoMap = it->second.vaoMap; - if (update) + // Notre clé est composée de ce qui définit un VAO + const NzVertexDeclaration* vertexDeclaration = s_vertexBuffer->GetVertexDeclaration(); + const NzVertexDeclaration* instancingDeclaration = (s_instancing) ? s_instanceBuffer.GetVertexDeclaration() : nullptr; + VAO_Key key(s_indexBuffer, s_vertexBuffer, vertexDeclaration, instancingDeclaration); + + // On recherche un VAO existant avec notre configuration + auto vaoIt = vaoMap.find(key); + if (vaoIt == vaoMap.end()) { - const NzVertexDeclaration* vertexDeclaration; + // On créé notre VAO + glGenVertexArrays(1, &s_currentVAO); + glBindVertexArray(s_currentVAO); + + // On l'ajoute à notre liste + VAO_Entry entry(&s_listener, ObjectType_IndexBuffer, ObjectType_VertexBuffer, ObjectType_VertexDeclaration, ObjectType_VertexDeclaration); + entry.indexBufferListener = std::get<0>(key); + entry.instancingDeclarationListener = std::get<3>(key); + entry.vertexBufferListener = std::get<1>(key); + entry.vertexDeclarationListener = std::get<2>(key); + entry.vao = s_currentVAO; + + vaoIt = vaoMap.insert(std::make_pair(key, std::move(entry))).first; + + // Et on le programme + bool updateFailed = false; unsigned int bufferOffset; unsigned int stride; @@ -1927,46 +1782,34 @@ bool NzRenderer::EnsureStateUpdate() // On invalide les bindings des buffers (car nous les avons défini manuellement) NzOpenGL::SetBuffer(nzBufferType_Index, 0); NzOpenGL::SetBuffer(nzBufferType_Vertex, 0); - } - if (s_useVertexArrayObjects) - { - if (update) + if (updateFailed) { - if (updateFailed) - { - // La création de notre VAO a échoué, libérons-le et marquons-le comme problématique - glDeleteVertexArrays(1, &vaoIt->second.vao); - vaoIt->second.vao = 0; - s_currentVAO = 0; - } - else - glBindVertexArray(0); // On marque la fin de la construction du VAO en le débindant + // La création de notre VAO a échoué, libérons-le et marquons-le comme problématique + glDeleteVertexArrays(1, &vaoIt->second.vao); + vaoIt->second.vao = 0; + s_currentVAO = 0; } - - // En cas de non-support des VAOs, les attributs doivent être respécifiés à chaque frame - s_updateFlags &= ~Update_VAO; + else + glBindVertexArray(0); // On marque la fin de la construction du VAO en le débindant } - } + else + // Notre VAO existe déjà, il est donc inutile de le reprogrammer + s_currentVAO = vaoIt->second.vao; - #ifdef NAZARA_DEBUG - if (s_updateFlags != Update_None && !s_useVertexArrayObjects && s_updateFlags != Update_VAO) - NazaraWarning("Update flags not fully cleared"); - #endif + s_updateFlags &= ~Update_VAO; + } } // On bind notre VAO - if (s_useVertexArrayObjects) + if (!s_currentVAO) { - if (!s_currentVAO) - { - NazaraError("Failed to create VAO"); - return false; - } - - glBindVertexArray(s_currentVAO); + NazaraError("Failed to create VAO"); + return false; } + glBindVertexArray(s_currentVAO); + // On vérifie que les textures actuellement bindées sont bien nos textures // Ceci à cause du fait qu'il est possible que des opérations sur les textures aient eu lieu // entre le dernier rendu et maintenant diff --git a/src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.frag b/src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.frag deleted file mode 100644 index 040d69895..000000000 --- a/src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.frag +++ /dev/null @@ -1,10 +0,0 @@ -#version 110 - -/********************Uniformes********************/ -uniform vec4 Color; - -/********************Fonctions********************/ -void main() -{ - gl_FragColor = Color; -} \ No newline at end of file diff --git a/src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.frag.h b/src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.frag.h deleted file mode 100644 index 7a6061298..000000000 --- a/src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.frag.h +++ /dev/null @@ -1 +0,0 @@ -35,118,101,114,115,105,111,110,32,49,49,48,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,117,110,105,102,111,114,109,32,118,101,99,52,32,67,111,108,111,114,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,103,108,95,70,114,97,103,67,111,108,111,114,32,61,32,67,111,108,111,114,59,13,10,125, \ No newline at end of file diff --git a/src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.vert b/src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.vert deleted file mode 100644 index 16fc72149..000000000 --- a/src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.vert +++ /dev/null @@ -1,13 +0,0 @@ -#version 110 - -/********************Entrant********************/ -varying vec3 VertexPosition; - -/********************Uniformes********************/ -uniform mat4 WorldViewProjMatrix; - -/********************Fonctions********************/ -void main() -{ - gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0); -} diff --git a/src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.vert.h b/src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.vert.h deleted file mode 100644 index ec0fba61f..000000000 --- a/src/Nazara/Renderer/Resources/Shaders/Debug/compatibility.vert.h +++ /dev/null @@ -1 +0,0 @@ -35,118,101,114,115,105,111,110,32,49,49,48,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,69,110,116,114,97,110,116,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,97,114,121,105,110,103,32,118,101,99,51,32,86,101,114,116,101,120,80,111,115,105,116,105,111,110,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,85,110,105,102,111,114,109,101,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,117,110,105,102,111,114,109,32,109,97,116,52,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,59,13,10,13,10,47,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,70,111,110,99,116,105,111,110,115,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,47,13,10,118,111,105,100,32,109,97,105,110,40,41,13,10,123,13,10,9,103,108,95,80,111,115,105,116,105,111,110,32,61,32,87,111,114,108,100,86,105,101,119,80,114,111,106,77,97,116,114,105,120,32,42,32,118,101,99,52,40,86,101,114,116,101,120,80,111,115,105,116,105,111,110,44,32,49,46,48,41,59,13,10,125,13,10, \ No newline at end of file diff --git a/src/Nazara/Renderer/Shader.cpp b/src/Nazara/Renderer/Shader.cpp index d01f1eda2..eee928a1a 100644 --- a/src/Nazara/Renderer/Shader.cpp +++ b/src/Nazara/Renderer/Shader.cpp @@ -155,17 +155,14 @@ bool NzShader::Create() glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata3], "VertexUserdata3"); glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata4], "VertexUserdata4"); - if (NzRenderer::HasCapability(nzRendererCap_MultipleRenderTargets)) - { - NzString uniform; - uniform = "RenderTarget"; + NzString uniform; + uniform = "RenderTarget"; - unsigned int maxRenderTargets = NzRenderer::GetMaxRenderTargets(); - for (unsigned int i = 0; i < maxRenderTargets; ++i) - { - NzString uniformName = uniform + NzString::Number(i); - glBindFragDataLocation(m_program, i, uniformName.GetConstBuffer()); - } + unsigned int maxRenderTargets = NzRenderer::GetMaxRenderTargets(); + for (unsigned int i = 0; i < maxRenderTargets; ++i) + { + NzString uniformName = uniform + NzString::Number(i); + glBindFragDataLocation(m_program, i, uniformName.GetConstBuffer()); } if (NzOpenGL::IsSupported(nzOpenGLExtension_GetProgramBinary)) diff --git a/src/Nazara/Renderer/ShaderStage.cpp b/src/Nazara/Renderer/ShaderStage.cpp index c45757192..30949bbf6 100644 --- a/src/Nazara/Renderer/ShaderStage.cpp +++ b/src/Nazara/Renderer/ShaderStage.cpp @@ -220,12 +220,10 @@ bool NzShaderStage::IsSupported(nzShaderStage stage) switch (stage) { case nzShaderStage_Fragment: + case nzShaderStage_Geometry: case nzShaderStage_Vertex: return true; - case nzShaderStage_Geometry: - return NzOpenGL::GetVersion() >= 320; - default: NazaraError("Shader stage not handled (0x" + NzString::Number(stage, 16) + ')'); return false; diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index e1b57caa9..7b3aebe90 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -163,12 +163,12 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt } m_impl = new NzTextureImpl; - m_impl->depth = GetValidSize(depth); + m_impl->depth = depth; m_impl->format = format; - m_impl->height = GetValidSize(height); + m_impl->height = height; m_impl->levelCount = levelCount; m_impl->type = type; - m_impl->width = GetValidSize(width); + m_impl->width = width; glGenTextures(1, &m_impl->id); NzOpenGL::BindTexture(m_impl->type, m_impl->id); @@ -1038,20 +1038,6 @@ unsigned int NzTexture::GetOpenGLID() const return m_impl->id; } -unsigned int NzTexture::GetValidSize(unsigned int size) -{ - if (NzRenderer::HasCapability(nzRendererCap_TextureNPOT)) - return size; - else - { - unsigned int pot = 1; - while (pot < size) - pot <<= 1; - - return pot; - } -} - bool NzTexture::IsFormatSupported(nzPixelFormat format) { switch (format) @@ -1104,14 +1090,14 @@ bool NzTexture::IsFormatSupported(nzPixelFormat format) case nzPixelFormat_RGBA32F: case nzPixelFormat_RGBA32I: case nzPixelFormat_RGBA32UI: - return NzOpenGL::GetVersion() >= 300; + return true; // Formats de profondeur (Supportés avec les FBOs) case nzPixelFormat_Depth16: case nzPixelFormat_Depth24: case nzPixelFormat_Depth32: case nzPixelFormat_Depth24Stencil8: - return NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject); + return true; // Formats de stencil (Non supportés pour les textures) case nzPixelFormat_Stencil1: @@ -1144,14 +1130,12 @@ bool NzTexture::IsTypeSupported(nzImageType type) switch (type) { case nzImageType_1D: + case nzImageType_1D_Array: case nzImageType_2D: + case nzImageType_2D_Array: case nzImageType_3D: case nzImageType_Cubemap: - return true; // Tous supportés nativement dans OpenGL 2 - - case nzImageType_1D_Array: - case nzImageType_2D_Array: - return NzOpenGL::IsSupported(nzOpenGLExtension_TextureArray); + return true; // Tous supportés nativement dans OpenGL 3 } NazaraError("Image type not handled (0x" + NzString::Number(type, 16) + ')'); From 2462a6f4bf70bdd8a72a5287e49e1accaeaaebac Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 30 Jan 2015 15:44:34 +0100 Subject: [PATCH 02/97] Removed conditional support of PBOs Altough the Renderer doesn't support them yet Former-commit-id: 8417f465c913bea1226fa7d742fe1dc614ecf72b --- include/Nazara/Renderer/Enums.hpp | 3 +-- include/Nazara/Renderer/OpenGL.hpp | 1 - src/Nazara/Renderer/OpenGL.cpp | 2 +- src/Nazara/Renderer/Renderer.cpp | 1 - 4 files changed, 2 insertions(+), 5 deletions(-) diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index 274ed4beb..241fbe549 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -109,9 +109,8 @@ enum nzRendererCap nzRendererCap_AnisotropicFilter, nzRendererCap_FP64, nzRendererCap_Instancing, - nzRendererCap_PixelBufferObject, - nzRendererCap_Max = nzRendererCap_PixelBufferObject + nzRendererCap_Max = nzRendererCap_Instancing }; enum nzRendererBufferFlags diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index 4e90aceb9..12a392b7e 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -31,7 +31,6 @@ enum nzOpenGLExtension nzOpenGLExtension_DebugOutput, nzOpenGLExtension_FP64, nzOpenGLExtension_GetProgramBinary, - nzOpenGLExtension_PixelBufferObject, nzOpenGLExtension_SeparateShaderObjects, nzOpenGLExtension_Shader_ImageLoadStore, nzOpenGLExtension_TextureCompression_s3tc, diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index c1bec3aa4..172255f23 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -797,7 +797,7 @@ bool NzOpenGL::Initialize() NazaraDebug("OpenGL version: " + NzString::Number(major) + '.' + NzString::Number(minor)); - // Le moteur nécessite OpenGL 3.3, autant s'arrêter là si c'est le cas + // Le moteur nécessite OpenGL 3.3, autant s'arrêter là si ce n'est pas le cas if (s_openglVersion < 330) { NazaraError("OpenGL " + NzString::Number(major) + '.' + NzString::Number(minor) + " detected (3.3 required). Please upgrade your drivers or your video card"); diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index b9c00db97..1884a4c3a 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -705,7 +705,6 @@ bool NzRenderer::Initialize() // Récupération des capacités d'OpenGL s_capabilities[nzRendererCap_AnisotropicFilter] = NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter); s_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(nzOpenGLExtension_FP64); - s_capabilities[nzRendererCap_PixelBufferObject] = NzOpenGL::IsSupported(nzOpenGLExtension_PixelBufferObject); s_capabilities[nzRendererCap_Instancing] = true; // Supporté par OpenGL 3.3 NzContext::EnsureContext(); From 2fd3872099dfc3409f46fafbebbf9a3a40ea2925 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 24 Sep 2015 00:37:21 +0200 Subject: [PATCH 03/97] Core: Remove NonCopyable Former-commit-id: f8c6d10ad0b1abb4a32e3c867b7f24fd4bde68a4 --- SDK/include/NDK/World.hpp | 8 ++++++-- include/Nazara/Audio/Music.hpp | 11 +++++++--- include/Nazara/Audio/SoundBuffer.hpp | 8 ++++++-- include/Nazara/Audio/SoundEmitter.hpp | 7 +++++-- include/Nazara/Core.hpp | 1 - include/Nazara/Core/AbstractHash.hpp | 8 ++++++-- include/Nazara/Core/CallOnExit.hpp | 8 ++++++-- include/Nazara/Core/ConditionVariable.hpp | 8 ++++++-- include/Nazara/Core/Directory.hpp | 10 +++++++--- include/Nazara/Core/DynLib.hpp | 9 +++++---- include/Nazara/Core/ErrorFlags.hpp | 8 ++++++-- include/Nazara/Core/File.hpp | 9 +++++---- include/Nazara/Core/Hash.hpp | 8 ++++++-- include/Nazara/Core/Log.hpp | 8 ++++++-- include/Nazara/Core/Mutex.hpp | 10 ++++++---- include/Nazara/Core/NonCopyable.hpp | 20 ------------------- include/Nazara/Core/Semaphore.hpp | 8 ++++++-- include/Nazara/Core/Thread.hpp | 9 +++++---- .../Nazara/Graphics/AbstractRenderQueue.hpp | 7 ++++--- .../Graphics/AbstractRenderTechnique.hpp | 7 ++++--- .../Nazara/Graphics/InstancedRenderable.hpp | 5 +++-- include/Nazara/Graphics/Renderable.hpp | 10 ++++------ include/Nazara/Lua/LuaInstance.hpp | 8 ++++++-- include/Nazara/Physics/Geom.hpp | 8 ++++++-- include/Nazara/Physics/PhysObject.hpp | 1 - include/Nazara/Physics/PhysWorld.hpp | 8 ++++++-- include/Nazara/Renderer/GpuQuery.hpp | 8 ++++++-- include/Nazara/Renderer/RenderBuffer.hpp | 8 ++++++-- include/Nazara/Renderer/RenderTexture.hpp | 8 ++++++-- include/Nazara/Renderer/Shader.hpp | 8 ++++++-- include/Nazara/Renderer/ShaderStage.hpp | 9 +++++---- include/Nazara/Renderer/Texture.hpp | 8 ++++++-- include/Nazara/Utility/Buffer.hpp | 8 ++++++-- include/Nazara/Utility/Font.hpp | 8 ++++++-- include/Nazara/Utility/Window.hpp | 8 ++++++-- src/Nazara/Core/Win32/DirectoryImpl.hpp | 8 ++++++-- src/Nazara/Core/Win32/DynLibImpl.hpp | 8 ++++++-- src/Nazara/Core/Win32/FileImpl.hpp | 8 ++++++-- src/Nazara/Utility/Win32/WindowImpl.hpp | 8 ++++++-- 39 files changed, 205 insertions(+), 112 deletions(-) delete mode 100644 include/Nazara/Core/NonCopyable.hpp diff --git a/SDK/include/NDK/World.hpp b/SDK/include/NDK/World.hpp index 794f5fb2a..2af17de1e 100644 --- a/SDK/include/NDK/World.hpp +++ b/SDK/include/NDK/World.hpp @@ -8,7 +8,6 @@ #define NDK_WORLD_HPP #include -#include #include #include #include @@ -19,7 +18,7 @@ namespace Ndk { - class NDK_API World : NzNonCopyable + class NDK_API World { friend Entity; @@ -27,6 +26,8 @@ namespace Ndk using EntityList = std::vector; inline World(bool addDefaultSystems = true); + World(const World&) = delete; + World(World&&) = delete; ///TODO ~World(); void AddDefaultSystems(); @@ -60,6 +61,9 @@ namespace Ndk void Update(); inline void Update(float elapsedTime); + World& operator=(const World&) = delete; + World& operator=(World&&) = delete; ///TODO + private: inline void Invalidate(); inline void Invalidate(EntityId id); diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index a4d990a29..0777052d3 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -27,12 +27,14 @@ using NzMusicLoader = NzResourceLoader; struct NzMusicImpl; -class NAZARA_AUDIO_API NzMusic : public NzResource, public NzSoundEmitter, NzNonCopyable +class NAZARA_AUDIO_API NzMusic : public NzResource, public NzSoundEmitter { friend NzMusicLoader; public: NzMusic() = default; + NzMusic(const NzMusic&) = delete; + NzMusic(NzMusic&&) = delete; ///TODO ~NzMusic(); bool Create(NzSoundStream* soundStream); @@ -43,8 +45,8 @@ class NAZARA_AUDIO_API NzMusic : public NzResource, public NzSoundEmitter, NzNon nzUInt32 GetDuration() const; nzAudioFormat GetFormat() const; nzUInt32 GetPlayingOffset() const; - unsigned int GetSampleCount() const; - unsigned int GetSampleRate() const; + unsigned int GetSampleCount() const; + unsigned int GetSampleRate() const; nzSoundStatus GetStatus() const; bool IsLooping() const; @@ -60,6 +62,9 @@ class NAZARA_AUDIO_API NzMusic : public NzResource, public NzSoundEmitter, NzNon void Stop(); + NzMusic& operator=(const NzMusic&) = delete; + NzMusic& operator=(NzMusic&&) = delete; ///TODO + private: NzMusicImpl* m_impl = nullptr; diff --git a/include/Nazara/Audio/SoundBuffer.hpp b/include/Nazara/Audio/SoundBuffer.hpp index 4016cf60d..8b773c5c6 100644 --- a/include/Nazara/Audio/SoundBuffer.hpp +++ b/include/Nazara/Audio/SoundBuffer.hpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -38,7 +37,7 @@ using NzSoundBufferRef = NzObjectRef; struct NzSoundBufferImpl; -class NAZARA_AUDIO_API NzSoundBuffer : public NzRefCounted, public NzResource, NzNonCopyable +class NAZARA_AUDIO_API NzSoundBuffer : public NzRefCounted, public NzResource { friend NzSound; friend NzSoundBufferLibrary; @@ -49,6 +48,8 @@ class NAZARA_AUDIO_API NzSoundBuffer : public NzRefCounted, public NzResource, N public: NzSoundBuffer() = default; NzSoundBuffer(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples); + NzSoundBuffer(const NzSoundBuffer&) = delete; + NzSoundBuffer(NzSoundBuffer&&) = delete; ~NzSoundBuffer(); bool Create(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples); @@ -69,6 +70,9 @@ class NAZARA_AUDIO_API NzSoundBuffer : public NzRefCounted, public NzResource, N static bool IsFormatSupported(nzAudioFormat format); template static NzSoundBufferRef New(Args&&... args); + NzSoundBuffer& operator=(const NzSoundBuffer&) = delete; + NzSoundBuffer& operator=(NzSoundBuffer&&) = delete; ///TODO + // Signals: NazaraSignal(OnSoundBufferDestroy, const NzSoundBuffer* /*soundBuffer*/); NazaraSignal(OnSoundBufferRelease, const NzSoundBuffer* /*soundBuffer*/); diff --git a/include/Nazara/Audio/SoundEmitter.hpp b/include/Nazara/Audio/SoundEmitter.hpp index e4e6cf837..043dc8439 100644 --- a/include/Nazara/Audio/SoundEmitter.hpp +++ b/include/Nazara/Audio/SoundEmitter.hpp @@ -11,7 +11,6 @@ #include #include #include -#include #include ///TODO: Faire hériter SoundEmitter de Node @@ -51,9 +50,13 @@ class NAZARA_AUDIO_API NzSoundEmitter virtual void Stop() = 0; + NzSoundEmitter& operator=(const NzSoundEmitter&) = delete; ///TODO + NzSoundEmitter& operator=(NzSoundEmitter&&) = delete; ///TODO + protected: NzSoundEmitter(); - NzSoundEmitter(const NzSoundEmitter& emitter); + NzSoundEmitter(const NzSoundEmitter& emitter); + NzSoundEmitter(NzSoundEmitter&&) = delete; ///TODO nzSoundStatus GetInternalStatus() const; diff --git a/include/Nazara/Core.hpp b/include/Nazara/Core.hpp index 14e593ab5..6ee347b88 100644 --- a/include/Nazara/Core.hpp +++ b/include/Nazara/Core.hpp @@ -61,7 +61,6 @@ #include #include #include -#include #include #include #include diff --git a/include/Nazara/Core/AbstractHash.hpp b/include/Nazara/Core/AbstractHash.hpp index 798d3879a..eb9db66e2 100644 --- a/include/Nazara/Core/AbstractHash.hpp +++ b/include/Nazara/Core/AbstractHash.hpp @@ -8,19 +8,23 @@ #define NAZARA_ABSTRACTHASH_HPP #include -#include class NzHashDigest; -class NAZARA_CORE_API NzAbstractHash : NzNonCopyable +class NAZARA_CORE_API NzAbstractHash { public: NzAbstractHash() = default; + NzAbstractHash(const NzAbstractHash&) = delete; + NzAbstractHash(NzAbstractHash&&) = default; virtual ~NzAbstractHash(); virtual void Append(const nzUInt8* data, unsigned int len) = 0; virtual void Begin() = 0; virtual NzHashDigest End() = 0; + + NzAbstractHash& operator=(const NzAbstractHash&) = delete; + NzAbstractHash& operator=(NzAbstractHash&&) = default; }; #endif // NAZARA_ABSTRACTHASH_HPP diff --git a/include/Nazara/Core/CallOnExit.hpp b/include/Nazara/Core/CallOnExit.hpp index 9c6da1ae6..f1f633940 100644 --- a/include/Nazara/Core/CallOnExit.hpp +++ b/include/Nazara/Core/CallOnExit.hpp @@ -8,20 +8,24 @@ #define NAZARA_CALLONEXIT_HPP #include -#include #include -class NzCallOnExit : NzNonCopyable +class NzCallOnExit { using Func = std::function; public: NzCallOnExit(Func func = nullptr); + NzCallOnExit(const NzCallOnExit&) = delete; + NzCallOnExit(NzCallOnExit&&) = delete; ~NzCallOnExit(); void CallAndReset(Func func = nullptr); void Reset(Func func = nullptr); + NzCallOnExit& operator=(const NzCallOnExit&) = delete; + NzCallOnExit& operator=(NzCallOnExit&&) = default; + private: Func m_func; }; diff --git a/include/Nazara/Core/ConditionVariable.hpp b/include/Nazara/Core/ConditionVariable.hpp index f3e9bb912..3abd2d817 100644 --- a/include/Nazara/Core/ConditionVariable.hpp +++ b/include/Nazara/Core/ConditionVariable.hpp @@ -8,15 +8,16 @@ #define NAZARA_CONDITIONVARIABLE_HPP #include -#include class NzConditionVariableImpl; class NzMutex; -class NAZARA_CORE_API NzConditionVariable : NzNonCopyable +class NAZARA_CORE_API NzConditionVariable { public: NzConditionVariable(); + NzConditionVariable(const NzConditionVariable&) = delete; + NzConditionVariable(NzConditionVariable&&) = delete; ///TODO ~NzConditionVariable(); void Signal(); @@ -25,6 +26,9 @@ class NAZARA_CORE_API NzConditionVariable : NzNonCopyable void Wait(NzMutex* mutex); bool Wait(NzMutex* mutex, nzUInt32 timeout); + NzConditionVariable& operator=(const NzConditionVariable&) = delete; + NzConditionVariable& operator=(NzConditionVariable&&) = delete; ///TODO + private: NzConditionVariableImpl* m_impl; }; diff --git a/include/Nazara/Core/Directory.hpp b/include/Nazara/Core/Directory.hpp index e145a7aae..1d990f23b 100644 --- a/include/Nazara/Core/Directory.hpp +++ b/include/Nazara/Core/Directory.hpp @@ -8,7 +8,6 @@ #define NAZARA_DIRECTORY_HPP #include -#include #include #if defined(NAZARA_PLATFORM_WINDOWS) @@ -28,11 +27,13 @@ class NzDirectoryImpl; -class NAZARA_CORE_API NzDirectory : NzNonCopyable +class NAZARA_CORE_API NzDirectory { public: NzDirectory(); - NzDirectory(const NzString& dirPath); + NzDirectory(const NzString& dirPath); + NzDirectory(const NzDirectory&) = delete; + NzDirectory(NzDirectory&&) = delete; ///TODO ~NzDirectory(); void Close(); @@ -63,6 +64,9 @@ class NAZARA_CORE_API NzDirectory : NzNonCopyable static bool Remove(const NzString& dirPath, bool emptyDirectory = false); static bool SetCurrent(const NzString& dirPath); + NzDirectory& operator=(const NzDirectory&) = delete; + NzDirectory& operator=(NzDirectory&&) = delete; ///TODO + private: NazaraMutexAttrib(m_mutex, mutable) diff --git a/include/Nazara/Core/DynLib.hpp b/include/Nazara/Core/DynLib.hpp index bd9aab3a2..f98585d27 100644 --- a/include/Nazara/Core/DynLib.hpp +++ b/include/Nazara/Core/DynLib.hpp @@ -8,7 +8,6 @@ #define NAZARA_DYNLIB_HPP #include -#include #include #if defined(NAZARA_PLATFORM_WINDOWS) @@ -31,11 +30,12 @@ using NzDynLibFunc = int (*)(); // Type "générique" de pointeur sur fonction class NzDynLibImpl; -class NAZARA_CORE_API NzDynLib : NzNonCopyable +class NAZARA_CORE_API NzDynLib { public: NzDynLib(); - NzDynLib(NzDynLib&& lib); + NzDynLib(const NzDynLib&) = delete; + NzDynLib(NzDynLib&& lib); ~NzDynLib(); NzString GetLastError() const; @@ -46,7 +46,8 @@ class NAZARA_CORE_API NzDynLib : NzNonCopyable bool Load(const NzString& libraryPath); void Unload(); - NzDynLib& operator=(NzDynLib&& lib); + NzDynLib& operator=(const NzDynLib&) = delete; + NzDynLib& operator=(NzDynLib&& lib); private: NazaraMutexAttrib(m_mutex, mutable) diff --git a/include/Nazara/Core/ErrorFlags.hpp b/include/Nazara/Core/ErrorFlags.hpp index 6795db107..6e85aaa0a 100644 --- a/include/Nazara/Core/ErrorFlags.hpp +++ b/include/Nazara/Core/ErrorFlags.hpp @@ -9,18 +9,22 @@ #include #include -#include -class NAZARA_CORE_API NzErrorFlags : NzNonCopyable +class NAZARA_CORE_API NzErrorFlags { public: NzErrorFlags(nzUInt32 flags, bool replace = false); + NzErrorFlags(const NzErrorFlags&) = delete; + NzErrorFlags(NzErrorFlags&&) = delete; ~NzErrorFlags(); nzUInt32 GetPreviousFlags() const; void SetFlags(nzUInt32 flags, bool replace = false); + NzErrorFlags& operator=(const NzErrorFlags&) = delete; + NzErrorFlags& operator=(NzErrorFlags&&) = delete; + private: nzUInt32 m_previousFlags; }; diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index c41eedd0c..043b0b333 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_FILE @@ -27,13 +26,14 @@ class NzFileImpl; -class NAZARA_CORE_API NzFile : public NzHashable, public NzInputStream, NzNonCopyable +class NAZARA_CORE_API NzFile : public NzHashable, public NzInputStream { public: NzFile(); NzFile(const NzString& filePath); NzFile(const NzString& filePath, unsigned int openMode); - NzFile(NzFile&& file) noexcept; + NzFile(const NzFile&) = delete; + NzFile(NzFile&& file) noexcept; ~NzFile(); bool Copy(const NzString& newFilePath); @@ -76,7 +76,8 @@ class NAZARA_CORE_API NzFile : public NzHashable, public NzInputStream, NzNonCop bool Write(const NzString& string); std::size_t Write(const void* buffer, std::size_t typeSize, unsigned int count); - NzFile& operator=(const NzString& filePath); + NzFile& operator=(const NzString& filePath); + NzFile& operator=(const NzFile&) = delete; NzFile& operator=(NzFile&& file) noexcept; static NzString AbsolutePath(const NzString& filePath); diff --git a/include/Nazara/Core/Hash.hpp b/include/Nazara/Core/Hash.hpp index 7ad150231..c9abb4502 100644 --- a/include/Nazara/Core/Hash.hpp +++ b/include/Nazara/Core/Hash.hpp @@ -11,17 +11,21 @@ #include #include #include -#include -class NAZARA_CORE_API NzHash : NzNonCopyable +class NAZARA_CORE_API NzHash { public: NzHash(nzHash hash); NzHash(NzAbstractHash* hashImpl); + NzHash(const NzHash&) = delete; + NzHash(NzHash&&) = delete; ///TODO ~NzHash(); NzHashDigest Hash(const NzHashable& hashable); + NzHash& operator=(const NzHash&) = delete; + NzHash& operator=(NzHash&&) = delete; ///TODO + private: NzAbstractHash* m_impl; }; diff --git a/include/Nazara/Core/Log.hpp b/include/Nazara/Core/Log.hpp index d2d3f9ad9..3e4e73b7d 100644 --- a/include/Nazara/Core/Log.hpp +++ b/include/Nazara/Core/Log.hpp @@ -9,7 +9,6 @@ #include #include -#include #include #if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_LOG @@ -29,7 +28,7 @@ class NzFile; -class NAZARA_CORE_API NzLog : NzNonCopyable +class NAZARA_CORE_API NzLog { public: void Enable(bool enable); @@ -50,8 +49,13 @@ class NAZARA_CORE_API NzLog : NzNonCopyable private: NzLog(); + NzLog(const NzLog&) = delete; + NzLog(NzLog&&) = delete; ~NzLog(); + NzLog& operator=(const NzLog&) = delete; + NzLog& operator=(NzLog&&) = delete; + NazaraMutexAttrib(m_mutex, mutable) NzString m_filePath; diff --git a/include/Nazara/Core/Mutex.hpp b/include/Nazara/Core/Mutex.hpp index d682f2356..ca108513d 100644 --- a/include/Nazara/Core/Mutex.hpp +++ b/include/Nazara/Core/Mutex.hpp @@ -8,24 +8,26 @@ #define NAZARA_MUTEX_HPP #include -#include class NzMutexImpl; -class NAZARA_CORE_API NzMutex : NzNonCopyable +class NAZARA_CORE_API NzMutex { friend class NzConditionVariable; public: NzMutex(); + NzMutex(const NzMutex&) = delete; + NzMutex(NzMutex&&) = delete; ///TODO ~NzMutex(); void Lock(); - bool TryLock(); - void Unlock(); + NzMutex& operator=(const NzMutex&) = delete; + NzMutex& operator=(NzMutex&&) = delete; ///TODO + private: NzMutexImpl* m_impl; }; diff --git a/include/Nazara/Core/NonCopyable.hpp b/include/Nazara/Core/NonCopyable.hpp deleted file mode 100644 index e8dec1851..000000000 --- a/include/Nazara/Core/NonCopyable.hpp +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_NONCOPYABLE_HPP -#define NAZARA_NONCOPYABLE_HPP - -#include - -class NAZARA_CORE_API NzNonCopyable -{ - protected: - NzNonCopyable() = default; - NzNonCopyable(const NzNonCopyable&) = delete; - NzNonCopyable& operator=(const NzNonCopyable&) = delete; -}; - -#endif // NAZARA_NONCOPYABLE_HPP diff --git a/include/Nazara/Core/Semaphore.hpp b/include/Nazara/Core/Semaphore.hpp index 9fd57a218..860405188 100644 --- a/include/Nazara/Core/Semaphore.hpp +++ b/include/Nazara/Core/Semaphore.hpp @@ -8,14 +8,15 @@ #define NAZARA_SEMAPHORE_HPP #include -#include class NzSemaphoreImpl; -class NAZARA_CORE_API NzSemaphore : NzNonCopyable +class NAZARA_CORE_API NzSemaphore { public: NzSemaphore(unsigned int count); + NzSemaphore(const NzSemaphore&) = delete; + NzSemaphore(NzSemaphore&&) = delete; ///TODO ~NzSemaphore(); unsigned int GetCount() const; @@ -25,6 +26,9 @@ class NAZARA_CORE_API NzSemaphore : NzNonCopyable void Wait(); bool Wait(nzUInt32 timeout); + NzSemaphore& operator=(const NzSemaphore&) = delete; + NzSemaphore& operator=(NzSemaphore&&) = delete; ///TODO + private: NzSemaphoreImpl* m_impl; }; diff --git a/include/Nazara/Core/Thread.hpp b/include/Nazara/Core/Thread.hpp index fedf6a14b..1a96a323e 100644 --- a/include/Nazara/Core/Thread.hpp +++ b/include/Nazara/Core/Thread.hpp @@ -9,12 +9,11 @@ #include #include -#include #include class NzThreadImpl; -class NAZARA_CORE_API NzThread : NzNonCopyable +class NAZARA_CORE_API NzThread { public: class Id; @@ -23,7 +22,8 @@ class NAZARA_CORE_API NzThread : NzNonCopyable template NzThread(F function); template NzThread(F function, Args&&... args); template NzThread(void (C::*function)(), C* object); - NzThread(NzThread&& other); + NzThread(const NzThread&) = delete; + NzThread(NzThread&& other); ~NzThread(); void Detach(); @@ -31,7 +31,8 @@ class NAZARA_CORE_API NzThread : NzNonCopyable bool IsJoinable() const; void Join(); - NzThread& operator=(NzThread&& thread); + NzThread& operator=(const NzThread&) = delete; + NzThread& operator=(NzThread&& thread); static unsigned int HardwareConcurrency(); static void Sleep(nzUInt32 milliseconds); diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index e641dcca0..1e5d282e6 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -31,7 +30,8 @@ class NAZARA_GRAPHICS_API NzAbstractRenderQueue struct SpotLight; NzAbstractRenderQueue() = default; - NzAbstractRenderQueue(const NzAbstractRenderQueue&) = delete; + NzAbstractRenderQueue(const NzAbstractRenderQueue&) = delete; + NzAbstractRenderQueue(NzAbstractRenderQueue&&) = default; virtual ~NzAbstractRenderQueue(); // Je ne suis vraiment pas fan du nombre de surcharges pour AddBillboards, @@ -54,7 +54,8 @@ class NAZARA_GRAPHICS_API NzAbstractRenderQueue virtual void Clear(bool fully = false); - NzAbstractRenderQueue& operator=(const NzAbstractRenderQueue&) = delete; + NzAbstractRenderQueue& operator=(const NzAbstractRenderQueue&) = delete; + NzAbstractRenderQueue& operator=(NzAbstractRenderQueue&&) = default; struct DirectionalLight { diff --git a/include/Nazara/Graphics/AbstractRenderTechnique.hpp b/include/Nazara/Graphics/AbstractRenderTechnique.hpp index e6e370307..a2fa3c69c 100644 --- a/include/Nazara/Graphics/AbstractRenderTechnique.hpp +++ b/include/Nazara/Graphics/AbstractRenderTechnique.hpp @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -23,7 +22,8 @@ class NAZARA_GRAPHICS_API NzAbstractRenderTechnique { public: NzAbstractRenderTechnique(); - NzAbstractRenderTechnique(const NzAbstractRenderTechnique&) = delete; + NzAbstractRenderTechnique(const NzAbstractRenderTechnique&) = delete; + NzAbstractRenderTechnique(NzAbstractRenderTechnique&&) = default; virtual ~NzAbstractRenderTechnique(); virtual bool Draw(const NzSceneData& sceneData) const = 0; @@ -36,7 +36,8 @@ class NAZARA_GRAPHICS_API NzAbstractRenderTechnique virtual bool IsInstancingEnabled() const; - NzAbstractRenderTechnique& operator=(const NzAbstractRenderTechnique&) = delete; + NzAbstractRenderTechnique& operator=(const NzAbstractRenderTechnique&) = delete; + NzAbstractRenderTechnique& operator=(NzAbstractRenderTechnique&&) = default; protected: bool m_instancingEnabled; diff --git a/include/Nazara/Graphics/InstancedRenderable.hpp b/include/Nazara/Graphics/InstancedRenderable.hpp index 79dd50a5c..0931d36eb 100644 --- a/include/Nazara/Graphics/InstancedRenderable.hpp +++ b/include/Nazara/Graphics/InstancedRenderable.hpp @@ -7,7 +7,6 @@ #ifndef NAZARA_INSTANCEDRENDERABLE_HPP #define NAZARA_INSTANCEDRENDERABLE_HPP -#include #include #include #include @@ -31,7 +30,8 @@ class NAZARA_GRAPHICS_API NzInstancedRenderable : public NzRefCounted struct InstanceData; NzInstancedRenderable() = default; - inline NzInstancedRenderable(const NzInstancedRenderable& renderable); + inline NzInstancedRenderable(const NzInstancedRenderable& renderable); + NzInstancedRenderable(NzInstancedRenderable&& renderable) = delete; virtual ~NzInstancedRenderable(); inline void EnsureBoundingVolumeUpdated() const; @@ -44,6 +44,7 @@ class NAZARA_GRAPHICS_API NzInstancedRenderable : public NzRefCounted virtual void UpdateData(InstanceData* instanceData) const; inline NzInstancedRenderable& operator=(const NzInstancedRenderable& renderable); + NzInstancedRenderable& operator=(NzInstancedRenderable&& renderable) = delete; // Signals: NazaraSignal(OnInstancedRenderableInvalidateData, const NzInstancedRenderable* /*instancedRenderable*/, nzUInt32 /*flags*/); diff --git a/include/Nazara/Graphics/Renderable.hpp b/include/Nazara/Graphics/Renderable.hpp index 5e2794bc3..7851df0fc 100644 --- a/include/Nazara/Graphics/Renderable.hpp +++ b/include/Nazara/Graphics/Renderable.hpp @@ -7,9 +7,6 @@ #ifndef NAZARA_RENDERABLE_HPP #define NAZARA_RENDERABLE_HPP -#include -#include -#include #include #include #include @@ -22,16 +19,17 @@ class NAZARA_GRAPHICS_API NzRenderable public: NzRenderable() = default; NzRenderable(const NzRenderable& renderable) = default; + NzRenderable(NzRenderable&&) = default; virtual ~NzRenderable(); - inline void EnsureBoundingVolumeUpdated() const; - virtual void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const = 0; virtual bool Cull(const NzFrustumf& frustum, const NzMatrix4f& transformMatrix) const; + inline void EnsureBoundingVolumeUpdated() const; virtual const NzBoundingVolumef& GetBoundingVolume() const; virtual void UpdateBoundingVolume(const NzMatrix4f& transformMatrix); - NzRenderable& operator=(const NzRenderable& renderable) = default; + NzRenderable& operator=(const NzRenderable& renderable) = default; + NzRenderable& operator=(NzRenderable&& renderable) = default; protected: virtual void MakeBoundingVolume() const = 0; diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index cdb3b05cb..9b72e421c 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -25,10 +24,12 @@ class NzLuaInstance; using NzLuaCFunction = int (*)(lua_State* state); using NzLuaFunction = std::function; -class NAZARA_LUA_API NzLuaInstance : NzNonCopyable +class NAZARA_LUA_API NzLuaInstance { public: NzLuaInstance(); + NzLuaInstance(const NzLuaInstance&) = delete; + NzLuaInstance(NzLuaInstance&&) = delete; ///TODO ~NzLuaInstance(); void ArgCheck(bool condition, unsigned int argNum, const char* error); @@ -148,6 +149,9 @@ class NAZARA_LUA_API NzLuaInstance : NzNonCopyable void* ToUserdata(int index, const char* tname) const; void* ToUserdata(int index, const NzString& tname) const; + NzLuaInstance& operator=(const NzLuaInstance&) = delete; + NzLuaInstance& operator=(NzLuaInstance&&) = delete; ///TODO + static int GetIndexOfUpValue(int upValue); static NzLuaInstance* GetInstance(lua_State* state); diff --git a/include/Nazara/Physics/Geom.hpp b/include/Nazara/Physics/Geom.hpp index 511b7019d..c14f10ff8 100644 --- a/include/Nazara/Physics/Geom.hpp +++ b/include/Nazara/Physics/Geom.hpp @@ -8,7 +8,6 @@ #define NAZARA_GEOM_HPP #include -#include #include #include #include @@ -35,10 +34,12 @@ using NzPhysGeomConstRef = NzObjectRef; using NzPhysGeomLibrary = NzObjectLibrary; using NzPhysGeomRef = NzObjectRef; -class NAZARA_PHYSICS_API NzPhysGeom : public NzRefCounted, NzNonCopyable +class NAZARA_PHYSICS_API NzPhysGeom : public NzRefCounted { public: NzPhysGeom() = default; + NzPhysGeom(const NzPhysGeom&) = delete; + NzPhysGeom(NzPhysGeom&&) = delete; virtual ~NzPhysGeom(); NzBoxf ComputeAABB(const NzVector3f& translation, const NzQuaternionf& rotation, const NzVector3f& scale) const; @@ -49,6 +50,9 @@ class NAZARA_PHYSICS_API NzPhysGeom : public NzRefCounted, NzNonCopyable NewtonCollision* GetHandle(NzPhysWorld* world) const; virtual nzGeomType GetType() const = 0; + NzPhysGeom& operator=(const NzPhysGeom&) = delete; + NzPhysGeom& operator=(NzPhysGeom&&) = delete; + static NzPhysGeomRef Build(const NzPrimitiveList& list); // Signals: diff --git a/include/Nazara/Physics/PhysObject.hpp b/include/Nazara/Physics/PhysObject.hpp index 3ee1f2a4c..154a7cbde 100644 --- a/include/Nazara/Physics/PhysObject.hpp +++ b/include/Nazara/Physics/PhysObject.hpp @@ -9,7 +9,6 @@ #include #include -#include #include #include #include diff --git a/include/Nazara/Physics/PhysWorld.hpp b/include/Nazara/Physics/PhysWorld.hpp index ed54d5106..a48d85a86 100644 --- a/include/Nazara/Physics/PhysWorld.hpp +++ b/include/Nazara/Physics/PhysWorld.hpp @@ -8,17 +8,18 @@ #define NAZARA_PHYSWORLD_HPP #include -#include #include #include #include struct NewtonWorld; -class NAZARA_PHYSICS_API NzPhysWorld : NzNonCopyable +class NAZARA_PHYSICS_API NzPhysWorld { public: NzPhysWorld(); + NzPhysWorld(const NzPhysWorld&) = delete; + NzPhysWorld(NzPhysWorld&&) = delete; ///TODO ~NzPhysWorld(); NzVector3f GetGravity() const; @@ -31,6 +32,9 @@ class NAZARA_PHYSICS_API NzPhysWorld : NzNonCopyable void Step(float timestep); + NzPhysWorld& operator=(const NzPhysWorld&) = delete; + NzPhysWorld& operator=(NzPhysWorld&&) = delete; ///TODO + private: NzVector3f m_gravity; NewtonWorld* m_world; diff --git a/include/Nazara/Renderer/GpuQuery.hpp b/include/Nazara/Renderer/GpuQuery.hpp index 25b21eed3..334de87b9 100644 --- a/include/Nazara/Renderer/GpuQuery.hpp +++ b/include/Nazara/Renderer/GpuQuery.hpp @@ -8,14 +8,15 @@ #define NAZARA_GPUQUERY_HPP #include -#include #include #include -class NAZARA_RENDERER_API NzGpuQuery : NzNonCopyable +class NAZARA_RENDERER_API NzGpuQuery { public: NzGpuQuery(); + NzGpuQuery(const NzGpuQuery&) = delete; + NzGpuQuery(NzGpuQuery&&) = delete; ///TODO ~NzGpuQuery(); void Begin(nzGpuQueryMode mode); @@ -28,6 +29,9 @@ class NAZARA_RENDERER_API NzGpuQuery : NzNonCopyable // Fonctions OpenGL unsigned int GetOpenGLID() const; + NzGpuQuery& operator=(const NzGpuQuery&) = delete; + NzGpuQuery& operator=(NzGpuQuery&&) = delete; ///TODO + static bool IsModeSupported(nzGpuQueryMode mode); static bool IsSupported(); diff --git a/include/Nazara/Renderer/RenderBuffer.hpp b/include/Nazara/Renderer/RenderBuffer.hpp index ea99c74c1..e0ccbbb1c 100644 --- a/include/Nazara/Renderer/RenderBuffer.hpp +++ b/include/Nazara/Renderer/RenderBuffer.hpp @@ -8,7 +8,6 @@ #define NAZARA_RENDERBUFFER_HPP #include -#include #include #include #include @@ -22,13 +21,15 @@ using NzRenderBufferConstRef = NzObjectRef; using NzRenderBufferLibrary = NzObjectLibrary; using NzRenderBufferRef = NzObjectRef; -class NAZARA_RENDERER_API NzRenderBuffer : public NzRefCounted, NzNonCopyable +class NAZARA_RENDERER_API NzRenderBuffer : public NzRefCounted { friend NzRenderBufferLibrary; friend class NzRenderer; public: NzRenderBuffer(); + NzRenderBuffer(const NzRenderBuffer&) = delete; + NzRenderBuffer(NzRenderBuffer&&) = delete; ~NzRenderBuffer(); bool Create(nzPixelFormat format, unsigned int width, unsigned int height); @@ -43,6 +44,9 @@ class NAZARA_RENDERER_API NzRenderBuffer : public NzRefCounted, NzNonCopyable bool IsValid() const; + NzRenderBuffer& operator=(const NzRenderBuffer&) = delete; + NzRenderBuffer& operator=(NzRenderBuffer&&) = delete; + static bool IsSupported(); template static NzRenderBufferRef New(Args&&... args); diff --git a/include/Nazara/Renderer/RenderTexture.hpp b/include/Nazara/Renderer/RenderTexture.hpp index 6130e4184..b7796bac2 100644 --- a/include/Nazara/Renderer/RenderTexture.hpp +++ b/include/Nazara/Renderer/RenderTexture.hpp @@ -8,7 +8,6 @@ #define NAZARA_RENDERTEXTURE_HPP #include -#include #include #include #include @@ -23,10 +22,12 @@ class NzTexture; struct NzRenderTextureImpl; -class NAZARA_RENDERER_API NzRenderTexture : public NzRenderTarget, NzNonCopyable +class NAZARA_RENDERER_API NzRenderTexture : public NzRenderTarget { public: inline NzRenderTexture(); + NzRenderTexture(const NzRenderTexture&) = delete; + NzRenderTexture(NzRenderTexture&&) = delete; ///TODO inline ~NzRenderTexture(); bool AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzRenderBuffer* buffer); @@ -59,6 +60,9 @@ class NAZARA_RENDERER_API NzRenderTexture : public NzRenderTarget, NzNonCopyable unsigned int GetOpenGLID() const; bool HasContext() const override; + NzRenderTexture& operator=(const NzRenderTexture&) = delete; + NzRenderTexture& operator=(NzRenderTexture&&) = delete; ///TODO + static inline void Blit(NzRenderTexture* src, NzRenderTexture* dst, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); static void Blit(NzRenderTexture* src, NzRectui srcRect, NzRenderTexture* dst, NzRectui dstRect, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); static bool IsSupported(); diff --git a/include/Nazara/Renderer/Shader.hpp b/include/Nazara/Renderer/Shader.hpp index 14e747af5..7d142acac 100644 --- a/include/Nazara/Renderer/Shader.hpp +++ b/include/Nazara/Renderer/Shader.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -30,13 +29,15 @@ using NzShaderConstRef = NzObjectRef; using NzShaderLibrary = NzObjectLibrary; using NzShaderRef = NzObjectRef; -class NAZARA_RENDERER_API NzShader : public NzRefCounted, NzNonCopyable +class NAZARA_RENDERER_API NzShader : public NzRefCounted { friend NzShaderLibrary; friend class NzRenderer; public: NzShader(); + NzShader(const NzShader&) = delete; + NzShader(NzShader&&) = delete; ~NzShader(); void AttachStage(nzShaderStage stage, const NzShaderStage& shaderStage); @@ -98,6 +99,9 @@ class NAZARA_RENDERER_API NzShader : public NzRefCounted, NzNonCopyable // Fonctions OpenGL unsigned int GetOpenGLID() const; + NzShader& operator=(const NzShader&) = delete; + NzShader& operator=(NzShader&&) = delete; + static bool IsStageSupported(nzShaderStage stage); template static NzShaderRef New(Args&&... args); diff --git a/include/Nazara/Renderer/ShaderStage.hpp b/include/Nazara/Renderer/ShaderStage.hpp index ef3ba4053..479c1da3c 100644 --- a/include/Nazara/Renderer/ShaderStage.hpp +++ b/include/Nazara/Renderer/ShaderStage.hpp @@ -8,17 +8,17 @@ #define NAZARA_SHADERSTAGE_HPP #include -#include #include #include #include -class NAZARA_RENDERER_API NzShaderStage : NzNonCopyable +class NAZARA_RENDERER_API NzShaderStage { public: NzShaderStage(); NzShaderStage(nzShaderStage stage); - NzShaderStage(NzShaderStage&& stage); + NzShaderStage(const NzShaderStage&) = delete; + NzShaderStage(NzShaderStage&& stage); ~NzShaderStage(); bool Compile(); @@ -36,7 +36,8 @@ class NAZARA_RENDERER_API NzShaderStage : NzNonCopyable void SetSource(const NzString& source); bool SetSourceFromFile(const NzString& filePath); - NzShaderStage& operator=(NzShaderStage&& shader); + NzShaderStage& operator=(const NzShaderStage&) = delete; + NzShaderStage& operator=(NzShaderStage&& shader); // Fonctions OpenGL unsigned int GetOpenGLID() const; diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 8ff2205c0..e3b85100b 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -8,7 +8,6 @@ #define NAZARA_TEXTURE_HPP #include -#include #include #include #include @@ -30,7 +29,7 @@ using NzTextureRef = NzObjectRef; struct NzTextureImpl; -class NAZARA_RENDERER_API NzTexture : public NzAbstractImage, public NzRefCounted, public NzResource, NzNonCopyable +class NAZARA_RENDERER_API NzTexture : public NzAbstractImage, public NzRefCounted, public NzResource { friend NzTextureLibrary; friend NzTextureManager; @@ -40,6 +39,8 @@ class NAZARA_RENDERER_API NzTexture : public NzAbstractImage, public NzRefCounte NzTexture() = default; NzTexture(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1); explicit NzTexture(const NzImage& image); + NzTexture(const NzTexture&) = delete; + NzTexture(NzTexture&&) = delete; ~NzTexture(); bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1); @@ -102,6 +103,9 @@ class NAZARA_RENDERER_API NzTexture : public NzAbstractImage, public NzRefCounte // Fonctions OpenGL unsigned int GetOpenGLID() const; + NzTexture& operator=(const NzTexture&) = delete; + NzTexture& operator=(NzTexture&&) = delete; + static unsigned int GetValidSize(unsigned int size); static bool IsFormatSupported(nzPixelFormat format); static bool IsMipmappingSupported(); diff --git a/include/Nazara/Utility/Buffer.hpp b/include/Nazara/Utility/Buffer.hpp index 3dd352307..1081905da 100644 --- a/include/Nazara/Utility/Buffer.hpp +++ b/include/Nazara/Utility/Buffer.hpp @@ -8,7 +8,6 @@ #define NAZARA_BUFFER_HPP #include -#include #include #include #include @@ -22,7 +21,7 @@ using NzBufferRef = NzObjectRef; class NzAbstractBuffer; -class NAZARA_UTILITY_API NzBuffer : public NzRefCounted, NzNonCopyable +class NAZARA_UTILITY_API NzBuffer : public NzRefCounted { friend class NzUtility; @@ -31,6 +30,8 @@ class NAZARA_UTILITY_API NzBuffer : public NzRefCounted, NzNonCopyable NzBuffer(nzBufferType type); NzBuffer(nzBufferType type, unsigned int size, nzUInt32 storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); + NzBuffer(const NzBuffer&) = delete; + NzBuffer(NzBuffer&&) = delete; ~NzBuffer(); bool CopyContent(const NzBuffer& buffer); @@ -56,6 +57,9 @@ class NAZARA_UTILITY_API NzBuffer : public NzRefCounted, NzNonCopyable void Unmap() const; + NzBuffer& operator=(const NzBuffer&) = delete; + NzBuffer& operator=(NzBuffer&&) = delete; + static bool IsStorageSupported(nzUInt32 storage); template static NzBufferRef New(Args&&... args); static void SetBufferFactory(nzUInt32 storage, BufferFactory func); diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index dc5544dff..e11ecf551 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -10,7 +10,6 @@ #define NAZARA_FONT_HPP #include -#include #include #include #include @@ -34,7 +33,7 @@ using NzFontLibrary = NzObjectLibrary; using NzFontLoader = NzResourceLoader; using NzFontRef = NzObjectRef; -class NAZARA_UTILITY_API NzFont : public NzRefCounted, public NzResource, NzNonCopyable +class NAZARA_UTILITY_API NzFont : public NzRefCounted, public NzResource { friend NzFontLibrary; friend NzFontLoader; @@ -45,6 +44,8 @@ class NAZARA_UTILITY_API NzFont : public NzRefCounted, public NzResource, NzNonC struct SizeInfo; NzFont(); + NzFont(const NzFont&) = delete; + NzFont(NzFont&&) = delete; ~NzFont(); void ClearGlyphCache(); @@ -81,6 +82,9 @@ class NAZARA_UTILITY_API NzFont : public NzRefCounted, public NzResource, NzNonC void SetGlyphBorder(unsigned int borderSize); void SetMinimumStepSize(unsigned int minimumStepSize); + NzFont& operator=(const NzFont&) = delete; + NzFont& operator=(NzFont&&) = delete; + static std::shared_ptr GetDefaultAtlas(); static NzFont* GetDefault(); static unsigned int GetDefaultGlyphBorder(); diff --git a/include/Nazara/Utility/Window.hpp b/include/Nazara/Utility/Window.hpp index aee4f693a..ce38e72b5 100644 --- a/include/Nazara/Utility/Window.hpp +++ b/include/Nazara/Utility/Window.hpp @@ -10,7 +10,6 @@ #define NAZARA_WINDOW_HPP #include -#include #include #include #include @@ -30,7 +29,7 @@ class NzImage; class NzIcon; class NzWindowImpl; -class NAZARA_UTILITY_API NzWindow : NzNonCopyable +class NAZARA_UTILITY_API NzWindow { friend NzWindowImpl; friend class NzMouse; @@ -40,6 +39,8 @@ class NAZARA_UTILITY_API NzWindow : NzNonCopyable NzWindow(); NzWindow(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default); NzWindow(NzWindowHandle handle); + NzWindow(const NzWindow&) = delete; + NzWindow(NzWindow&&) = delete; ///TODO virtual ~NzWindow(); void Close(); @@ -89,6 +90,9 @@ class NAZARA_UTILITY_API NzWindow : NzNonCopyable bool WaitEvent(NzEvent* event); + NzWindow& operator=(const NzWindow&) = delete; + NzWindow& operator=(NzWindow&&) = delete; ///TODO + protected: virtual bool OnWindowCreated(); virtual void OnWindowDestroy(); diff --git a/src/Nazara/Core/Win32/DirectoryImpl.hpp b/src/Nazara/Core/Win32/DirectoryImpl.hpp index cb2df657d..117d04d7f 100644 --- a/src/Nazara/Core/Win32/DirectoryImpl.hpp +++ b/src/Nazara/Core/Win32/DirectoryImpl.hpp @@ -8,16 +8,17 @@ #define NAZARA_DIRECTORYIMPL_HPP #include -#include #include class NzDirectory; class NzString; -class NzDirectoryImpl : NzNonCopyable +class NzDirectoryImpl { public: NzDirectoryImpl(const NzDirectory* parent); + NzDirectoryImpl(const NzDirectoryImpl&) = delete; + NzDirectoryImpl(NzDirectoryImpl&&) = delete; ///TODO ~NzDirectoryImpl() = default; void Close(); @@ -31,6 +32,9 @@ class NzDirectoryImpl : NzNonCopyable bool Open(const NzString& dirPath); + NzDirectoryImpl& operator=(const NzDirectoryImpl&) = delete; + NzDirectoryImpl& operator=(NzDirectoryImpl&&) = delete; ///TODO + static bool Create(const NzString& dirPath); static bool Exists(const NzString& dirPath); static NzString GetCurrent(); diff --git a/src/Nazara/Core/Win32/DynLibImpl.hpp b/src/Nazara/Core/Win32/DynLibImpl.hpp index cb3f504c5..4c6a2e72f 100644 --- a/src/Nazara/Core/Win32/DynLibImpl.hpp +++ b/src/Nazara/Core/Win32/DynLibImpl.hpp @@ -9,21 +9,25 @@ #include #include -#include #include class NzString; -class NzDynLibImpl : NzNonCopyable +class NzDynLibImpl { public: NzDynLibImpl(NzDynLib* m_parent); + NzDynLibImpl(const NzDynLibImpl&) = delete; + NzDynLibImpl(NzDynLibImpl&&) = delete; ///TODO? ~NzDynLibImpl() = default; NzDynLibFunc GetSymbol(const NzString& symbol, NzString* errorMessage) const; bool Load(const NzString& libraryPath, NzString* errorMessage); void Unload(); + NzDynLibImpl& operator=(const NzDynLibImpl&) = delete; + NzDynLibImpl& operator=(NzDynLibImpl&&) = delete; ///TODO? + private: HMODULE m_handle; }; diff --git a/src/Nazara/Core/Win32/FileImpl.hpp b/src/Nazara/Core/Win32/FileImpl.hpp index b9c667595..1e1f2c854 100644 --- a/src/Nazara/Core/Win32/FileImpl.hpp +++ b/src/Nazara/Core/Win32/FileImpl.hpp @@ -9,17 +9,18 @@ #include #include -#include #include #include class NzFile; class NzString; -class NzFileImpl : NzNonCopyable +class NzFileImpl { public: NzFileImpl(const NzFile* parent); + NzFileImpl(const NzFileImpl&) = delete; + NzFileImpl(NzFileImpl&&) = delete; ///TODO ~NzFileImpl() = default; void Close(); @@ -31,6 +32,9 @@ class NzFileImpl : NzNonCopyable bool SetCursorPos(nzCursorPosition pos, nzInt64 offset); std::size_t Write(const void* buffer, std::size_t size); + NzFileImpl& operator=(const NzFileImpl&) = delete; + NzFileImpl& operator=(NzFileImpl&&) = delete; ///TODO + static bool Copy(const NzString& sourcePath, const NzString& targetPath); static bool Delete(const NzString& filePath); static bool Exists(const NzString& filePath); diff --git a/src/Nazara/Utility/Win32/WindowImpl.hpp b/src/Nazara/Utility/Win32/WindowImpl.hpp index c393fcd59..288150ad9 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.hpp +++ b/src/Nazara/Utility/Win32/WindowImpl.hpp @@ -10,7 +10,6 @@ #define NAZARA_WINDOWIMPL_HPP #include -#include #include #include #include @@ -29,10 +28,12 @@ class NzWindow; #undef IsMinimized // Conflit avec la méthode du même nom -class NzWindowImpl : NzNonCopyable +class NzWindowImpl { public: NzWindowImpl(NzWindow* parent); + NzWindowImpl(const NzWindowImpl&) = delete; + NzWindowImpl(NzWindowImpl&&) = delete; ///TODO? ~NzWindowImpl() = default; bool Create(const NzVideoMode& mode, const NzString& title, nzUInt32 style); @@ -73,6 +74,9 @@ class NzWindowImpl : NzNonCopyable void SetTitle(const NzString& title); void SetVisible(bool visible); + NzWindowImpl& operator=(const NzWindowImpl&) = delete; + NzWindowImpl& operator=(NzWindowImpl&&) = delete; ///TODO? + static bool Initialize(); static void Uninitialize(); From ce3bbf6c78dd16d18151f27c491243d5706a5add Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 24 Sep 2015 00:39:48 +0200 Subject: [PATCH 04/97] Audio: Uniformize SampleCount/SampleRate type Former-commit-id: a67b0f10a4aeb1399834221d32859ab0e376813e --- include/Nazara/Audio/Music.hpp | 4 ++-- include/Nazara/Audio/SoundBuffer.hpp | 4 ++-- include/Nazara/Audio/SoundStream.hpp | 2 +- src/Nazara/Audio/Formats/sndfileLoader.cpp | 12 +++++----- src/Nazara/Audio/Music.cpp | 26 ++++++++++++++++++++++ src/Nazara/Audio/SoundBuffer.cpp | 4 ++-- 6 files changed, 39 insertions(+), 13 deletions(-) diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index 0777052d3..98aafa0d2 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -45,8 +45,8 @@ class NAZARA_AUDIO_API NzMusic : public NzResource, public NzSoundEmitter nzUInt32 GetDuration() const; nzAudioFormat GetFormat() const; nzUInt32 GetPlayingOffset() const; - unsigned int GetSampleCount() const; - unsigned int GetSampleRate() const; + nzUInt32 GetSampleCount() const; + nzUInt32 GetSampleRate() const; nzSoundStatus GetStatus() const; bool IsLooping() const; diff --git a/include/Nazara/Audio/SoundBuffer.hpp b/include/Nazara/Audio/SoundBuffer.hpp index 8b773c5c6..ba66911db 100644 --- a/include/Nazara/Audio/SoundBuffer.hpp +++ b/include/Nazara/Audio/SoundBuffer.hpp @@ -58,8 +58,8 @@ class NAZARA_AUDIO_API NzSoundBuffer : public NzRefCounted, public NzResource nzUInt32 GetDuration() const; nzAudioFormat GetFormat() const; const nzInt16* GetSamples() const; - unsigned int GetSampleCount() const; - unsigned int GetSampleRate() const; + nzUInt32 GetSampleCount() const; + nzUInt32 GetSampleRate() const; bool IsValid() const; diff --git a/include/Nazara/Audio/SoundStream.hpp b/include/Nazara/Audio/SoundStream.hpp index 13def198d..f59a7dd8f 100644 --- a/include/Nazara/Audio/SoundStream.hpp +++ b/include/Nazara/Audio/SoundStream.hpp @@ -19,7 +19,7 @@ class NAZARA_AUDIO_API NzSoundStream virtual nzUInt32 GetDuration() const = 0; virtual nzAudioFormat GetFormat() const = 0; - virtual nzUInt64 GetSampleCount() const = 0; + virtual nzUInt32 GetSampleCount() const = 0; virtual nzUInt32 GetSampleRate() const = 0; virtual unsigned int Read(void* buffer, unsigned int sampleCount) = 0; diff --git a/src/Nazara/Audio/Formats/sndfileLoader.cpp b/src/Nazara/Audio/Formats/sndfileLoader.cpp index 3bc449d61..1b3100d40 100644 --- a/src/Nazara/Audio/Formats/sndfileLoader.cpp +++ b/src/Nazara/Audio/Formats/sndfileLoader.cpp @@ -95,7 +95,7 @@ namespace return m_format; } - nzUInt64 GetSampleCount() const override + nzUInt32 GetSampleCount() const override { return m_sampleCount; } @@ -152,11 +152,11 @@ namespace return false; } - m_sampleCount = infos.channels*infos.frames; + m_sampleCount = static_cast(infos.channels*infos.frames); m_sampleRate = infos.samplerate; // Durée de la musique (s) = samples / channels*rate - m_duration = static_cast(1000*m_sampleCount / (m_format*m_sampleRate)); + m_duration = static_cast(1000ULL*m_sampleCount / (m_format*m_sampleRate)); // https://github.com/LaurentGomila/SFML/issues/271 // http://www.mega-nerd.com/libsndfile/command.html#SFC_SET_SCALE_FLOAT_INT_READ @@ -168,7 +168,7 @@ namespace if (forceMono && m_format != nzAudioFormat_Mono) { m_mixToMono = true; - m_sampleCount = infos.frames; + m_sampleCount = static_cast(infos.frames); } else m_mixToMono = false; @@ -206,8 +206,8 @@ namespace SNDFILE* m_handle; bool m_mixToMono; nzUInt32 m_duration; - nzUInt64 m_sampleCount; - nzUInt32 m_sampleRate; + unsigned int m_sampleCount; + unsigned int m_sampleRate; }; bool IsSupported(const NzString& extension) diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index 59e551e2a..0d3bd757e 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -119,6 +119,32 @@ nzUInt32 NzMusic::GetPlayingOffset() const return 0; } +nzUInt32 NzMusic::GetSampleCount() const +{ + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return 0; + } + #endif + + return m_impl->stream->GetSampleCount(); +} + +nzUInt32 NzMusic::GetSampleRate() const +{ + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return 0; + } + #endif + + return m_impl->stream->GetSampleRate(); +} + nzSoundStatus NzMusic::GetStatus() const { #if NAZARA_AUDIO_SAFE diff --git a/src/Nazara/Audio/SoundBuffer.cpp b/src/Nazara/Audio/SoundBuffer.cpp index d1d02cd65..d55a973cd 100644 --- a/src/Nazara/Audio/SoundBuffer.cpp +++ b/src/Nazara/Audio/SoundBuffer.cpp @@ -25,8 +25,8 @@ struct NzSoundBufferImpl nzAudioFormat format; nzUInt32 duration; std::unique_ptr samples; - unsigned int sampleCount; - unsigned int sampleRate; + nzUInt32 sampleCount; + nzUInt32 sampleRate; }; NzSoundBuffer::NzSoundBuffer(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples) From dea3fb4e3967360bb785520c0f29d0313785c01f Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 24 Sep 2015 00:55:57 +0200 Subject: [PATCH 05/97] Convert spaces to tabs Former-commit-id: b459cfe0c83f651cc660d42f7d3014c3b146f345 --- SDK/include/NDK/EntityHandle.inl | 10 +- SDK/include/NDK/World.hpp | 8 +- SDK/src/NDK/BaseSystem.cpp | 16 +- include/Nazara/Audio/Algorithm.inl | 2 +- include/Nazara/Audio/Music.hpp | 8 +- include/Nazara/Audio/SoundBuffer.hpp | 8 +- include/Nazara/Audio/SoundEmitter.hpp | 8 +- include/Nazara/Core/AbstractHash.hpp | 8 +- include/Nazara/Core/Algorithm.inl | 18 +- include/Nazara/Core/CallOnExit.hpp | 8 +- include/Nazara/Core/ConditionVariable.hpp | 8 +- include/Nazara/Core/Directory.hpp | 10 +- include/Nazara/Core/DynLib.hpp | 8 +- include/Nazara/Core/ErrorFlags.hpp | 8 +- include/Nazara/Core/File.hpp | 8 +- include/Nazara/Core/Hash.hpp | 8 +- include/Nazara/Core/Log.hpp | 8 +- include/Nazara/Core/Mutex.hpp | 8 +- include/Nazara/Core/Semaphore.hpp | 8 +- include/Nazara/Core/Signal.inl | 32 +-- include/Nazara/Core/Thread.hpp | 8 +- .../Nazara/Graphics/AbstractRenderQueue.hpp | 8 +- .../Graphics/AbstractRenderTechnique.hpp | 8 +- .../Nazara/Graphics/InstancedRenderable.hpp | 6 +- include/Nazara/Graphics/Renderable.hpp | 8 +- include/Nazara/Lua/LuaInstance.hpp | 8 +- include/Nazara/Lua/LuaInstance.inl | 2 +- include/Nazara/Noise/Abstract2DNoise.hpp | 10 +- include/Nazara/Noise/Abstract3DNoise.hpp | 10 +- include/Nazara/Noise/Abstract4DNoise.hpp | 10 +- include/Nazara/Noise/ComplexNoiseBase.hpp | 37 +-- include/Nazara/Noise/FBM2D.hpp | 20 +- include/Nazara/Noise/FBM3D.hpp | 20 +- include/Nazara/Noise/FBM4D.hpp | 20 +- include/Nazara/Noise/HybridMultiFractal3D.hpp | 26 +- include/Nazara/Noise/HybridMultiFractal4D.hpp | 26 +- include/Nazara/Noise/HybridMultifractal2D.hpp | 26 +- include/Nazara/Noise/MappedNoiseBase.hpp | 26 +- include/Nazara/Noise/NoiseBase.hpp | 34 +-- include/Nazara/Noise/Perlin2D.hpp | 30 +-- include/Nazara/Noise/Perlin3D.hpp | 34 +-- include/Nazara/Noise/Perlin4D.hpp | 32 +-- include/Nazara/Noise/Simplex2D.hpp | 36 +-- include/Nazara/Noise/Simplex3D.hpp | 36 +-- include/Nazara/Noise/Simplex4D.hpp | 40 +-- include/Nazara/Physics/Geom.hpp | 8 +- include/Nazara/Physics/PhysWorld.hpp | 8 +- include/Nazara/Renderer/GpuQuery.hpp | 8 +- include/Nazara/Renderer/RenderBuffer.hpp | 8 +- include/Nazara/Renderer/RenderTexture.hpp | 8 +- include/Nazara/Renderer/Shader.hpp | 8 +- include/Nazara/Renderer/ShaderStage.hpp | 8 +- include/Nazara/Renderer/Texture.hpp | 8 +- include/Nazara/Utility/Buffer.hpp | 8 +- include/Nazara/Utility/Font.hpp | 8 +- .../Nazara/Utility/GuillotineImageAtlas.hpp | 2 +- include/Nazara/Utility/Window.hpp | 8 +- src/Nazara/Audio/Formats/sndfileLoader.cpp | 38 +-- src/Nazara/Audio/Music.cpp | 32 +-- .../Graphics/DeferredPhongLightingPass.cpp | 2 +- .../Graphics/DeferredRenderTechnique.cpp | 4 +- src/Nazara/Graphics/SkinningManager.cpp | 14 +- src/Nazara/Noise/Abstract2DNoise.cpp | 4 +- src/Nazara/Noise/Abstract3DNoise.cpp | 4 +- src/Nazara/Noise/Abstract4DNoise.cpp | 4 +- src/Nazara/Noise/ComplexNoiseBase.cpp | 64 ++--- src/Nazara/Noise/FBM2D.cpp | 48 ++-- src/Nazara/Noise/FBM3D.cpp | 48 ++-- src/Nazara/Noise/FBM4D.cpp | 48 ++-- src/Nazara/Noise/HybridMultiFractal3D.cpp | 64 ++--- src/Nazara/Noise/HybridMultiFractal4D.cpp | 64 ++--- src/Nazara/Noise/HybridMultifractal2D.cpp | 64 ++--- src/Nazara/Noise/MappedNoiseBase.cpp | 14 +- src/Nazara/Noise/NoiseBase.cpp | 76 +++--- src/Nazara/Noise/Perlin2D.cpp | 60 ++--- src/Nazara/Noise/Perlin3D.cpp | 114 ++++----- src/Nazara/Noise/Perlin4D.cpp | 204 +++++++-------- src/Nazara/Noise/Simplex2D.cpp | 110 ++++---- src/Nazara/Noise/Simplex3D.cpp | 240 ++++++++--------- src/Nazara/Noise/Simplex4D.cpp | 242 +++++++++--------- src/Nazara/Renderer/RenderTexture.cpp | 2 +- src/Nazara/Renderer/Shader.cpp | 2 +- src/Nazara/Renderer/Texture.cpp | 8 +- .../Renderer/UberShaderPreprocessor.cpp | 16 +- src/Nazara/Utility/Formats/FreeTypeLoader.cpp | 2 +- src/Nazara/Utility/Formats/STBLoader.cpp | 6 +- src/Nazara/Utility/Win32/WindowImpl.cpp | 2 +- 87 files changed, 1206 insertions(+), 1205 deletions(-) diff --git a/SDK/include/NDK/EntityHandle.inl b/SDK/include/NDK/EntityHandle.inl index e34bc8492..a3919d383 100644 --- a/SDK/include/NDK/EntityHandle.inl +++ b/SDK/include/NDK/EntityHandle.inl @@ -260,9 +260,9 @@ namespace Ndk namespace std { - template<> - struct hash - { + template<> + struct hash + { size_t operator()(const Ndk::EntityHandle& handle) const { // Hasher le pointeur fonctionnerait jusqu'à ce que l'entité soit mise à jour et déplacée @@ -271,9 +271,9 @@ namespace std return hash()(id); } - }; + }; - inline void swap(Ndk::EntityHandle& lhs, Ndk::EntityHandle& rhs) + inline void swap(Ndk::EntityHandle& lhs, Ndk::EntityHandle& rhs) { lhs.Swap(rhs); } diff --git a/SDK/include/NDK/World.hpp b/SDK/include/NDK/World.hpp index 2af17de1e..a5fa6594a 100644 --- a/SDK/include/NDK/World.hpp +++ b/SDK/include/NDK/World.hpp @@ -26,8 +26,8 @@ namespace Ndk using EntityList = std::vector; inline World(bool addDefaultSystems = true); - World(const World&) = delete; - World(World&&) = delete; ///TODO + World(const World&) = delete; + World(World&&) = delete; ///TODO ~World(); void AddDefaultSystems(); @@ -61,8 +61,8 @@ namespace Ndk void Update(); inline void Update(float elapsedTime); - World& operator=(const World&) = delete; - World& operator=(World&&) = delete; ///TODO + World& operator=(const World&) = delete; + World& operator=(World&&) = delete; ///TODO private: inline void Invalidate(); diff --git a/SDK/src/NDK/BaseSystem.cpp b/SDK/src/NDK/BaseSystem.cpp index 5aa9aac30..d37ba1791 100644 --- a/SDK/src/NDK/BaseSystem.cpp +++ b/SDK/src/NDK/BaseSystem.cpp @@ -17,15 +17,15 @@ namespace Ndk if (!entity) return false; - const NzBitset<>& components = entity->GetComponentBits(); + const NzBitset<>& components = entity->GetComponentBits(); - m_filterResult.PerformsAND(m_requiredComponents, components); - if (m_filterResult != m_requiredComponents) - return false; // Au moins un component requis n'est pas présent + m_filterResult.PerformsAND(m_requiredComponents, components); + if (m_filterResult != m_requiredComponents) + return false; // Au moins un component requis n'est pas présent - m_filterResult.PerformsAND(m_excludedComponents, components); - if (m_filterResult.TestAny()) - return false; // Au moins un component exclu est présent + m_filterResult.PerformsAND(m_excludedComponents, components); + if (m_filterResult.TestAny()) + return false; // Au moins un component exclu est présent // Si nous avons une liste de composants nécessaires if (m_requiredAnyComponents.TestAny()) @@ -34,7 +34,7 @@ namespace Ndk return false; } - return true; + return true; } void BaseSystem::OnEntityAdded(Entity* entity) diff --git a/include/Nazara/Audio/Algorithm.inl b/include/Nazara/Audio/Algorithm.inl index ca4b28575..c96aa655e 100644 --- a/include/Nazara/Audio/Algorithm.inl +++ b/include/Nazara/Audio/Algorithm.inl @@ -11,7 +11,7 @@ void NzMixToMono(T* input, T* output, unsigned int channelCount, unsigned int fr ///DOC: Le buffer d'entrée peut être le même que le buffer de sortie // Pour éviter l'overflow, on utilise comme accumulateur un type assez grand, (u)int 64 bits pour les entiers, double pour les flottants typedef typename std::conditional::value, nzUInt64, nzInt64>::type BiggestInt; - typedef typename std::conditional::value, BiggestInt, double>::type Biggest; + typedef typename std::conditional::value, BiggestInt, double>::type Biggest; for (unsigned int i = 0; i < frameCount; ++i) { diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index 98aafa0d2..3c472fbb6 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -33,8 +33,8 @@ class NAZARA_AUDIO_API NzMusic : public NzResource, public NzSoundEmitter public: NzMusic() = default; - NzMusic(const NzMusic&) = delete; - NzMusic(NzMusic&&) = delete; ///TODO + NzMusic(const NzMusic&) = delete; + NzMusic(NzMusic&&) = delete; ///TODO ~NzMusic(); bool Create(NzSoundStream* soundStream); @@ -62,8 +62,8 @@ class NAZARA_AUDIO_API NzMusic : public NzResource, public NzSoundEmitter void Stop(); - NzMusic& operator=(const NzMusic&) = delete; - NzMusic& operator=(NzMusic&&) = delete; ///TODO + NzMusic& operator=(const NzMusic&) = delete; + NzMusic& operator=(NzMusic&&) = delete; ///TODO private: NzMusicImpl* m_impl = nullptr; diff --git a/include/Nazara/Audio/SoundBuffer.hpp b/include/Nazara/Audio/SoundBuffer.hpp index ba66911db..259fa7145 100644 --- a/include/Nazara/Audio/SoundBuffer.hpp +++ b/include/Nazara/Audio/SoundBuffer.hpp @@ -48,8 +48,8 @@ class NAZARA_AUDIO_API NzSoundBuffer : public NzRefCounted, public NzResource public: NzSoundBuffer() = default; NzSoundBuffer(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples); - NzSoundBuffer(const NzSoundBuffer&) = delete; - NzSoundBuffer(NzSoundBuffer&&) = delete; + NzSoundBuffer(const NzSoundBuffer&) = delete; + NzSoundBuffer(NzSoundBuffer&&) = delete; ~NzSoundBuffer(); bool Create(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples); @@ -70,8 +70,8 @@ class NAZARA_AUDIO_API NzSoundBuffer : public NzRefCounted, public NzResource static bool IsFormatSupported(nzAudioFormat format); template static NzSoundBufferRef New(Args&&... args); - NzSoundBuffer& operator=(const NzSoundBuffer&) = delete; - NzSoundBuffer& operator=(NzSoundBuffer&&) = delete; ///TODO + NzSoundBuffer& operator=(const NzSoundBuffer&) = delete; + NzSoundBuffer& operator=(NzSoundBuffer&&) = delete; ///TODO // Signals: NazaraSignal(OnSoundBufferDestroy, const NzSoundBuffer* /*soundBuffer*/); diff --git a/include/Nazara/Audio/SoundEmitter.hpp b/include/Nazara/Audio/SoundEmitter.hpp index 043dc8439..4935b39d7 100644 --- a/include/Nazara/Audio/SoundEmitter.hpp +++ b/include/Nazara/Audio/SoundEmitter.hpp @@ -50,13 +50,13 @@ class NAZARA_AUDIO_API NzSoundEmitter virtual void Stop() = 0; - NzSoundEmitter& operator=(const NzSoundEmitter&) = delete; ///TODO - NzSoundEmitter& operator=(NzSoundEmitter&&) = delete; ///TODO + NzSoundEmitter& operator=(const NzSoundEmitter&) = delete; ///TODO + NzSoundEmitter& operator=(NzSoundEmitter&&) = delete; ///TODO protected: NzSoundEmitter(); - NzSoundEmitter(const NzSoundEmitter& emitter); - NzSoundEmitter(NzSoundEmitter&&) = delete; ///TODO + NzSoundEmitter(const NzSoundEmitter& emitter); + NzSoundEmitter(NzSoundEmitter&&) = delete; ///TODO nzSoundStatus GetInternalStatus() const; diff --git a/include/Nazara/Core/AbstractHash.hpp b/include/Nazara/Core/AbstractHash.hpp index eb9db66e2..e63a025aa 100644 --- a/include/Nazara/Core/AbstractHash.hpp +++ b/include/Nazara/Core/AbstractHash.hpp @@ -15,16 +15,16 @@ class NAZARA_CORE_API NzAbstractHash { public: NzAbstractHash() = default; - NzAbstractHash(const NzAbstractHash&) = delete; - NzAbstractHash(NzAbstractHash&&) = default; + NzAbstractHash(const NzAbstractHash&) = delete; + NzAbstractHash(NzAbstractHash&&) = default; virtual ~NzAbstractHash(); virtual void Append(const nzUInt8* data, unsigned int len) = 0; virtual void Begin() = 0; virtual NzHashDigest End() = 0; - NzAbstractHash& operator=(const NzAbstractHash&) = delete; - NzAbstractHash& operator=(NzAbstractHash&&) = default; + NzAbstractHash& operator=(const NzAbstractHash&) = delete; + NzAbstractHash& operator=(NzAbstractHash&&) = default; }; #endif // NAZARA_ABSTRACTHASH_HPP diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 859dbb8d9..028085917 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -12,7 +12,7 @@ template auto NzApplyImplFunc(F&& fn, Tuple&& t, std::index_sequence) { - return std::forward(fn)(std::get(std::forward(t))...); + return std::forward(fn)(std::get(std::forward(t))...); } template @@ -26,7 +26,7 @@ auto NzApply(F&& fn, Tuple&& t) template auto NzApplyImplMethod(O& object, F&& fn, Tuple&& t, std::index_sequence) { - return (object .* std::forward(fn))(std::get(std::forward(t))...); + return (object .* std::forward(fn))(std::get(std::forward(t))...); } template @@ -41,16 +41,16 @@ auto NzApply(O& object, F&& fn, Tuple&& t) template void NzHashCombine(std::size_t& seed, const T& v) { - const nzUInt64 kMul = 0x9ddfea08eb382d69ULL; + const nzUInt64 kMul = 0x9ddfea08eb382d69ULL; - std::hash hasher; - nzUInt64 a = (hasher(v) ^ seed) * kMul; - a ^= (a >> 47); + std::hash hasher; + nzUInt64 a = (hasher(v) ^ seed) * kMul; + a ^= (a >> 47); - nzUInt64 b = (seed ^ a) * kMul; - b ^= (b >> 47); + nzUInt64 b = (seed ^ a) * kMul; + b ^= (b >> 47); - seed = static_cast(b * kMul); + seed = static_cast(b * kMul); } #include diff --git a/include/Nazara/Core/CallOnExit.hpp b/include/Nazara/Core/CallOnExit.hpp index f1f633940..aef4dce2c 100644 --- a/include/Nazara/Core/CallOnExit.hpp +++ b/include/Nazara/Core/CallOnExit.hpp @@ -16,15 +16,15 @@ class NzCallOnExit public: NzCallOnExit(Func func = nullptr); - NzCallOnExit(const NzCallOnExit&) = delete; - NzCallOnExit(NzCallOnExit&&) = delete; + NzCallOnExit(const NzCallOnExit&) = delete; + NzCallOnExit(NzCallOnExit&&) = delete; ~NzCallOnExit(); void CallAndReset(Func func = nullptr); void Reset(Func func = nullptr); - NzCallOnExit& operator=(const NzCallOnExit&) = delete; - NzCallOnExit& operator=(NzCallOnExit&&) = default; + NzCallOnExit& operator=(const NzCallOnExit&) = delete; + NzCallOnExit& operator=(NzCallOnExit&&) = default; private: Func m_func; diff --git a/include/Nazara/Core/ConditionVariable.hpp b/include/Nazara/Core/ConditionVariable.hpp index 3abd2d817..001aa3d5c 100644 --- a/include/Nazara/Core/ConditionVariable.hpp +++ b/include/Nazara/Core/ConditionVariable.hpp @@ -16,8 +16,8 @@ class NAZARA_CORE_API NzConditionVariable { public: NzConditionVariable(); - NzConditionVariable(const NzConditionVariable&) = delete; - NzConditionVariable(NzConditionVariable&&) = delete; ///TODO + NzConditionVariable(const NzConditionVariable&) = delete; + NzConditionVariable(NzConditionVariable&&) = delete; ///TODO ~NzConditionVariable(); void Signal(); @@ -26,8 +26,8 @@ class NAZARA_CORE_API NzConditionVariable void Wait(NzMutex* mutex); bool Wait(NzMutex* mutex, nzUInt32 timeout); - NzConditionVariable& operator=(const NzConditionVariable&) = delete; - NzConditionVariable& operator=(NzConditionVariable&&) = delete; ///TODO + NzConditionVariable& operator=(const NzConditionVariable&) = delete; + NzConditionVariable& operator=(NzConditionVariable&&) = delete; ///TODO private: NzConditionVariableImpl* m_impl; diff --git a/include/Nazara/Core/Directory.hpp b/include/Nazara/Core/Directory.hpp index 1d990f23b..b24962849 100644 --- a/include/Nazara/Core/Directory.hpp +++ b/include/Nazara/Core/Directory.hpp @@ -31,9 +31,9 @@ class NAZARA_CORE_API NzDirectory { public: NzDirectory(); - NzDirectory(const NzString& dirPath); - NzDirectory(const NzDirectory&) = delete; - NzDirectory(NzDirectory&&) = delete; ///TODO + NzDirectory(const NzString& dirPath); + NzDirectory(const NzDirectory&) = delete; + NzDirectory(NzDirectory&&) = delete; ///TODO ~NzDirectory(); void Close(); @@ -64,8 +64,8 @@ class NAZARA_CORE_API NzDirectory static bool Remove(const NzString& dirPath, bool emptyDirectory = false); static bool SetCurrent(const NzString& dirPath); - NzDirectory& operator=(const NzDirectory&) = delete; - NzDirectory& operator=(NzDirectory&&) = delete; ///TODO + NzDirectory& operator=(const NzDirectory&) = delete; + NzDirectory& operator=(NzDirectory&&) = delete; ///TODO private: NazaraMutexAttrib(m_mutex, mutable) diff --git a/include/Nazara/Core/DynLib.hpp b/include/Nazara/Core/DynLib.hpp index f98585d27..0e92aaee7 100644 --- a/include/Nazara/Core/DynLib.hpp +++ b/include/Nazara/Core/DynLib.hpp @@ -34,8 +34,8 @@ class NAZARA_CORE_API NzDynLib { public: NzDynLib(); - NzDynLib(const NzDynLib&) = delete; - NzDynLib(NzDynLib&& lib); + NzDynLib(const NzDynLib&) = delete; + NzDynLib(NzDynLib&& lib); ~NzDynLib(); NzString GetLastError() const; @@ -46,8 +46,8 @@ class NAZARA_CORE_API NzDynLib bool Load(const NzString& libraryPath); void Unload(); - NzDynLib& operator=(const NzDynLib&) = delete; - NzDynLib& operator=(NzDynLib&& lib); + NzDynLib& operator=(const NzDynLib&) = delete; + NzDynLib& operator=(NzDynLib&& lib); private: NazaraMutexAttrib(m_mutex, mutable) diff --git a/include/Nazara/Core/ErrorFlags.hpp b/include/Nazara/Core/ErrorFlags.hpp index 6e85aaa0a..b36b351bb 100644 --- a/include/Nazara/Core/ErrorFlags.hpp +++ b/include/Nazara/Core/ErrorFlags.hpp @@ -14,16 +14,16 @@ class NAZARA_CORE_API NzErrorFlags { public: NzErrorFlags(nzUInt32 flags, bool replace = false); - NzErrorFlags(const NzErrorFlags&) = delete; - NzErrorFlags(NzErrorFlags&&) = delete; + NzErrorFlags(const NzErrorFlags&) = delete; + NzErrorFlags(NzErrorFlags&&) = delete; ~NzErrorFlags(); nzUInt32 GetPreviousFlags() const; void SetFlags(nzUInt32 flags, bool replace = false); - NzErrorFlags& operator=(const NzErrorFlags&) = delete; - NzErrorFlags& operator=(NzErrorFlags&&) = delete; + NzErrorFlags& operator=(const NzErrorFlags&) = delete; + NzErrorFlags& operator=(NzErrorFlags&&) = delete; private: nzUInt32 m_previousFlags; diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index 043b0b333..8507fb1da 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -32,8 +32,8 @@ class NAZARA_CORE_API NzFile : public NzHashable, public NzInputStream NzFile(); NzFile(const NzString& filePath); NzFile(const NzString& filePath, unsigned int openMode); - NzFile(const NzFile&) = delete; - NzFile(NzFile&& file) noexcept; + NzFile(const NzFile&) = delete; + NzFile(NzFile&& file) noexcept; ~NzFile(); bool Copy(const NzString& newFilePath); @@ -76,8 +76,8 @@ class NAZARA_CORE_API NzFile : public NzHashable, public NzInputStream bool Write(const NzString& string); std::size_t Write(const void* buffer, std::size_t typeSize, unsigned int count); - NzFile& operator=(const NzString& filePath); - NzFile& operator=(const NzFile&) = delete; + NzFile& operator=(const NzString& filePath); + NzFile& operator=(const NzFile&) = delete; NzFile& operator=(NzFile&& file) noexcept; static NzString AbsolutePath(const NzString& filePath); diff --git a/include/Nazara/Core/Hash.hpp b/include/Nazara/Core/Hash.hpp index c9abb4502..45d03f935 100644 --- a/include/Nazara/Core/Hash.hpp +++ b/include/Nazara/Core/Hash.hpp @@ -17,14 +17,14 @@ class NAZARA_CORE_API NzHash public: NzHash(nzHash hash); NzHash(NzAbstractHash* hashImpl); - NzHash(const NzHash&) = delete; - NzHash(NzHash&&) = delete; ///TODO + NzHash(const NzHash&) = delete; + NzHash(NzHash&&) = delete; ///TODO ~NzHash(); NzHashDigest Hash(const NzHashable& hashable); - NzHash& operator=(const NzHash&) = delete; - NzHash& operator=(NzHash&&) = delete; ///TODO + NzHash& operator=(const NzHash&) = delete; + NzHash& operator=(NzHash&&) = delete; ///TODO private: NzAbstractHash* m_impl; diff --git a/include/Nazara/Core/Log.hpp b/include/Nazara/Core/Log.hpp index 3e4e73b7d..c41bf0c48 100644 --- a/include/Nazara/Core/Log.hpp +++ b/include/Nazara/Core/Log.hpp @@ -49,12 +49,12 @@ class NAZARA_CORE_API NzLog private: NzLog(); - NzLog(const NzLog&) = delete; - NzLog(NzLog&&) = delete; + NzLog(const NzLog&) = delete; + NzLog(NzLog&&) = delete; ~NzLog(); - NzLog& operator=(const NzLog&) = delete; - NzLog& operator=(NzLog&&) = delete; + NzLog& operator=(const NzLog&) = delete; + NzLog& operator=(NzLog&&) = delete; NazaraMutexAttrib(m_mutex, mutable) diff --git a/include/Nazara/Core/Mutex.hpp b/include/Nazara/Core/Mutex.hpp index ca108513d..0b73bb268 100644 --- a/include/Nazara/Core/Mutex.hpp +++ b/include/Nazara/Core/Mutex.hpp @@ -17,16 +17,16 @@ class NAZARA_CORE_API NzMutex public: NzMutex(); - NzMutex(const NzMutex&) = delete; - NzMutex(NzMutex&&) = delete; ///TODO + NzMutex(const NzMutex&) = delete; + NzMutex(NzMutex&&) = delete; ///TODO ~NzMutex(); void Lock(); bool TryLock(); void Unlock(); - NzMutex& operator=(const NzMutex&) = delete; - NzMutex& operator=(NzMutex&&) = delete; ///TODO + NzMutex& operator=(const NzMutex&) = delete; + NzMutex& operator=(NzMutex&&) = delete; ///TODO private: NzMutexImpl* m_impl; diff --git a/include/Nazara/Core/Semaphore.hpp b/include/Nazara/Core/Semaphore.hpp index 860405188..b7a6683a9 100644 --- a/include/Nazara/Core/Semaphore.hpp +++ b/include/Nazara/Core/Semaphore.hpp @@ -15,8 +15,8 @@ class NAZARA_CORE_API NzSemaphore { public: NzSemaphore(unsigned int count); - NzSemaphore(const NzSemaphore&) = delete; - NzSemaphore(NzSemaphore&&) = delete; ///TODO + NzSemaphore(const NzSemaphore&) = delete; + NzSemaphore(NzSemaphore&&) = delete; ///TODO ~NzSemaphore(); unsigned int GetCount() const; @@ -26,8 +26,8 @@ class NAZARA_CORE_API NzSemaphore void Wait(); bool Wait(nzUInt32 timeout); - NzSemaphore& operator=(const NzSemaphore&) = delete; - NzSemaphore& operator=(NzSemaphore&&) = delete; ///TODO + NzSemaphore& operator=(const NzSemaphore&) = delete; + NzSemaphore& operator=(NzSemaphore&&) = delete; ///TODO private: NzSemaphoreImpl* m_impl; diff --git a/include/Nazara/Core/Signal.inl b/include/Nazara/Core/Signal.inl index 872501861..cae03220a 100644 --- a/include/Nazara/Core/Signal.inl +++ b/include/Nazara/Core/Signal.inl @@ -56,40 +56,40 @@ template template typename NzSignal::Connection NzSignal::Connect(O& object, void (O::*method) (Args...)) { - return Connect([&object, method] (Args&&... args) - { - return (object .* method) (std::forward(args)...); - }); + return Connect([&object, method] (Args&&... args) + { + return (object .* method) (std::forward(args)...); + }); } template template typename NzSignal::Connection NzSignal::Connect(O* object, void (O::*method)(Args...)) { - return Connect([object, method] (Args&&... args) - { - return (object ->* method) (std::forward(args)...); - }); + return Connect([object, method] (Args&&... args) + { + return (object ->* method) (std::forward(args)...); + }); } template template typename NzSignal::Connection NzSignal::Connect(const O& object, void (O::*method) (Args...) const) { - return Connect([&object, method] (Args&&... args) - { - return (object .* method) (std::forward(args)...); - }); + return Connect([&object, method] (Args&&... args) + { + return (object .* method) (std::forward(args)...); + }); } template template typename NzSignal::Connection NzSignal::Connect(const O* object, void (O::*method)(Args...) const) { - return Connect([object, method] (Args&&... args) - { - return (object ->* method) (std::forward(args)...); - }); + return Connect([object, method] (Args&&... args) + { + return (object ->* method) (std::forward(args)...); + }); } template diff --git a/include/Nazara/Core/Thread.hpp b/include/Nazara/Core/Thread.hpp index 1a96a323e..cb77862ea 100644 --- a/include/Nazara/Core/Thread.hpp +++ b/include/Nazara/Core/Thread.hpp @@ -22,8 +22,8 @@ class NAZARA_CORE_API NzThread template NzThread(F function); template NzThread(F function, Args&&... args); template NzThread(void (C::*function)(), C* object); - NzThread(const NzThread&) = delete; - NzThread(NzThread&& other); + NzThread(const NzThread&) = delete; + NzThread(NzThread&& other); ~NzThread(); void Detach(); @@ -31,8 +31,8 @@ class NAZARA_CORE_API NzThread bool IsJoinable() const; void Join(); - NzThread& operator=(const NzThread&) = delete; - NzThread& operator=(NzThread&& thread); + NzThread& operator=(const NzThread&) = delete; + NzThread& operator=(NzThread&& thread); static unsigned int HardwareConcurrency(); static void Sleep(nzUInt32 milliseconds); diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index 1e5d282e6..a02c09c88 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -30,8 +30,8 @@ class NAZARA_GRAPHICS_API NzAbstractRenderQueue struct SpotLight; NzAbstractRenderQueue() = default; - NzAbstractRenderQueue(const NzAbstractRenderQueue&) = delete; - NzAbstractRenderQueue(NzAbstractRenderQueue&&) = default; + NzAbstractRenderQueue(const NzAbstractRenderQueue&) = delete; + NzAbstractRenderQueue(NzAbstractRenderQueue&&) = default; virtual ~NzAbstractRenderQueue(); // Je ne suis vraiment pas fan du nombre de surcharges pour AddBillboards, @@ -54,8 +54,8 @@ class NAZARA_GRAPHICS_API NzAbstractRenderQueue virtual void Clear(bool fully = false); - NzAbstractRenderQueue& operator=(const NzAbstractRenderQueue&) = delete; - NzAbstractRenderQueue& operator=(NzAbstractRenderQueue&&) = default; + NzAbstractRenderQueue& operator=(const NzAbstractRenderQueue&) = delete; + NzAbstractRenderQueue& operator=(NzAbstractRenderQueue&&) = default; struct DirectionalLight { diff --git a/include/Nazara/Graphics/AbstractRenderTechnique.hpp b/include/Nazara/Graphics/AbstractRenderTechnique.hpp index a2fa3c69c..a6d62b78f 100644 --- a/include/Nazara/Graphics/AbstractRenderTechnique.hpp +++ b/include/Nazara/Graphics/AbstractRenderTechnique.hpp @@ -22,8 +22,8 @@ class NAZARA_GRAPHICS_API NzAbstractRenderTechnique { public: NzAbstractRenderTechnique(); - NzAbstractRenderTechnique(const NzAbstractRenderTechnique&) = delete; - NzAbstractRenderTechnique(NzAbstractRenderTechnique&&) = default; + NzAbstractRenderTechnique(const NzAbstractRenderTechnique&) = delete; + NzAbstractRenderTechnique(NzAbstractRenderTechnique&&) = default; virtual ~NzAbstractRenderTechnique(); virtual bool Draw(const NzSceneData& sceneData) const = 0; @@ -36,8 +36,8 @@ class NAZARA_GRAPHICS_API NzAbstractRenderTechnique virtual bool IsInstancingEnabled() const; - NzAbstractRenderTechnique& operator=(const NzAbstractRenderTechnique&) = delete; - NzAbstractRenderTechnique& operator=(NzAbstractRenderTechnique&&) = default; + NzAbstractRenderTechnique& operator=(const NzAbstractRenderTechnique&) = delete; + NzAbstractRenderTechnique& operator=(NzAbstractRenderTechnique&&) = default; protected: bool m_instancingEnabled; diff --git a/include/Nazara/Graphics/InstancedRenderable.hpp b/include/Nazara/Graphics/InstancedRenderable.hpp index 0931d36eb..2428b4e7b 100644 --- a/include/Nazara/Graphics/InstancedRenderable.hpp +++ b/include/Nazara/Graphics/InstancedRenderable.hpp @@ -30,8 +30,8 @@ class NAZARA_GRAPHICS_API NzInstancedRenderable : public NzRefCounted struct InstanceData; NzInstancedRenderable() = default; - inline NzInstancedRenderable(const NzInstancedRenderable& renderable); - NzInstancedRenderable(NzInstancedRenderable&& renderable) = delete; + inline NzInstancedRenderable(const NzInstancedRenderable& renderable); + NzInstancedRenderable(NzInstancedRenderable&& renderable) = delete; virtual ~NzInstancedRenderable(); inline void EnsureBoundingVolumeUpdated() const; @@ -44,7 +44,7 @@ class NAZARA_GRAPHICS_API NzInstancedRenderable : public NzRefCounted virtual void UpdateData(InstanceData* instanceData) const; inline NzInstancedRenderable& operator=(const NzInstancedRenderable& renderable); - NzInstancedRenderable& operator=(NzInstancedRenderable&& renderable) = delete; + NzInstancedRenderable& operator=(NzInstancedRenderable&& renderable) = delete; // Signals: NazaraSignal(OnInstancedRenderableInvalidateData, const NzInstancedRenderable* /*instancedRenderable*/, nzUInt32 /*flags*/); diff --git a/include/Nazara/Graphics/Renderable.hpp b/include/Nazara/Graphics/Renderable.hpp index 7851df0fc..1a357a18a 100644 --- a/include/Nazara/Graphics/Renderable.hpp +++ b/include/Nazara/Graphics/Renderable.hpp @@ -19,17 +19,17 @@ class NAZARA_GRAPHICS_API NzRenderable public: NzRenderable() = default; NzRenderable(const NzRenderable& renderable) = default; - NzRenderable(NzRenderable&&) = default; + NzRenderable(NzRenderable&&) = default; virtual ~NzRenderable(); virtual void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const = 0; virtual bool Cull(const NzFrustumf& frustum, const NzMatrix4f& transformMatrix) const; - inline void EnsureBoundingVolumeUpdated() const; + inline void EnsureBoundingVolumeUpdated() const; virtual const NzBoundingVolumef& GetBoundingVolume() const; virtual void UpdateBoundingVolume(const NzMatrix4f& transformMatrix); - NzRenderable& operator=(const NzRenderable& renderable) = default; - NzRenderable& operator=(NzRenderable&& renderable) = default; + NzRenderable& operator=(const NzRenderable& renderable) = default; + NzRenderable& operator=(NzRenderable&& renderable) = default; protected: virtual void MakeBoundingVolume() const = 0; diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index 9b72e421c..35fd1cd73 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -28,8 +28,8 @@ class NAZARA_LUA_API NzLuaInstance { public: NzLuaInstance(); - NzLuaInstance(const NzLuaInstance&) = delete; - NzLuaInstance(NzLuaInstance&&) = delete; ///TODO + NzLuaInstance(const NzLuaInstance&) = delete; + NzLuaInstance(NzLuaInstance&&) = delete; ///TODO ~NzLuaInstance(); void ArgCheck(bool condition, unsigned int argNum, const char* error); @@ -149,8 +149,8 @@ class NAZARA_LUA_API NzLuaInstance void* ToUserdata(int index, const char* tname) const; void* ToUserdata(int index, const NzString& tname) const; - NzLuaInstance& operator=(const NzLuaInstance&) = delete; - NzLuaInstance& operator=(NzLuaInstance&&) = delete; ///TODO + NzLuaInstance& operator=(const NzLuaInstance&) = delete; + NzLuaInstance& operator=(NzLuaInstance&&) = delete; ///TODO static int GetIndexOfUpValue(int upValue); static NzLuaInstance* GetInstance(lua_State* state); diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index 6a1a35e24..f116af219 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -160,7 +160,7 @@ void NzLuaInstance::PushFunction(R(*func)(Args...)) PushFunction([func](NzLuaInstance& instance) -> int { NzLuaImplFunctionProxy handler(instance); - handler.ProcessArgs(); + handler.ProcessArgs(); return handler.Invoke(func); }); diff --git a/include/Nazara/Noise/Abstract2DNoise.hpp b/include/Nazara/Noise/Abstract2DNoise.hpp index 42b5e5fad..e96dedb74 100644 --- a/include/Nazara/Noise/Abstract2DNoise.hpp +++ b/include/Nazara/Noise/Abstract2DNoise.hpp @@ -12,12 +12,12 @@ class NAZARA_NOISE_API NzAbstract2DNoise : public NzMappedNoiseBase { - public: - virtual ~NzAbstract2DNoise(); + public: + virtual ~NzAbstract2DNoise(); - float GetBasicValue(float x, float y); - float GetMappedValue(float x, float y); - virtual float GetValue(float x, float y, float resolution) = 0; + float GetBasicValue(float x, float y); + float GetMappedValue(float x, float y); + virtual float GetValue(float x, float y, float resolution) = 0; }; #endif // NAZARA_ABSTRACT2DNOISE_HPP diff --git a/include/Nazara/Noise/Abstract3DNoise.hpp b/include/Nazara/Noise/Abstract3DNoise.hpp index 06ee2b9bc..92021d6e5 100644 --- a/include/Nazara/Noise/Abstract3DNoise.hpp +++ b/include/Nazara/Noise/Abstract3DNoise.hpp @@ -12,12 +12,12 @@ class NAZARA_NOISE_API NzAbstract3DNoise : public NzMappedNoiseBase { - public: - virtual ~NzAbstract3DNoise(); + public: + virtual ~NzAbstract3DNoise(); - float GetBasicValue(float x, float y, float z); - float GetMappedValue(float x, float y, float z); - virtual float GetValue(float x, float y, float z, float resolution) = 0; + float GetBasicValue(float x, float y, float z); + float GetMappedValue(float x, float y, float z); + virtual float GetValue(float x, float y, float z, float resolution) = 0; }; #endif // NAZARA_ABSTRACT3DNOISE_HPP diff --git a/include/Nazara/Noise/Abstract4DNoise.hpp b/include/Nazara/Noise/Abstract4DNoise.hpp index 1d137df0d..12630aec5 100644 --- a/include/Nazara/Noise/Abstract4DNoise.hpp +++ b/include/Nazara/Noise/Abstract4DNoise.hpp @@ -12,12 +12,12 @@ class NAZARA_NOISE_API NzAbstract4DNoise : public NzMappedNoiseBase { - public: - virtual ~NzAbstract4DNoise(); + public: + virtual ~NzAbstract4DNoise(); - float GetBasicValue(float x, float y, float z, float w); - float GetMappedValue(float x, float y, float z, float w); - virtual float GetValue(float x, float y, float z, float w, float resolution) = 0; + float GetBasicValue(float x, float y, float z, float w); + float GetMappedValue(float x, float y, float z, float w); + virtual float GetValue(float x, float y, float z, float w, float resolution) = 0; }; #endif // NAZARA_ABSTRACT4DNOISE_HPP diff --git a/include/Nazara/Noise/ComplexNoiseBase.hpp b/include/Nazara/Noise/ComplexNoiseBase.hpp index ae4c6daa3..ef77eaa2b 100644 --- a/include/Nazara/Noise/ComplexNoiseBase.hpp +++ b/include/Nazara/Noise/ComplexNoiseBase.hpp @@ -12,26 +12,27 @@ class NAZARA_NOISE_API NzComplexNoiseBase { - public: - NzComplexNoiseBase(); - ~NzComplexNoiseBase() = default; + public: + NzComplexNoiseBase(); + ~NzComplexNoiseBase() = default; - float GetHurstParameter() const; - float GetLacunarity() const; - float GetOctaveNumber() const; - void SetHurstParameter(float h); - void SetLacunarity(float lacunarity); - void SetOctavesNumber(float octaves); - void RecomputeExponentArray(); + float GetHurstParameter() const; + float GetLacunarity() const; + float GetOctaveNumber() const; + void SetHurstParameter(float h); + void SetLacunarity(float lacunarity); + void SetOctavesNumber(float octaves); + void RecomputeExponentArray(); - protected: - float m_lacunarity; - float m_hurst; - float m_octaves; - std::array m_exponent_array; - float m_sum; - private: - bool m_parametersModified; + protected: + float m_lacunarity; + float m_hurst; + float m_octaves; + std::array m_exponent_array; + float m_sum; + + private: + bool m_parametersModified; }; #endif // COMPLEXNOISEBASE_HPP diff --git a/include/Nazara/Noise/FBM2D.hpp b/include/Nazara/Noise/FBM2D.hpp index d2fc883fa..ecd65ca39 100644 --- a/include/Nazara/Noise/FBM2D.hpp +++ b/include/Nazara/Noise/FBM2D.hpp @@ -13,16 +13,16 @@ class NAZARA_NOISE_API NzFBM2D : public NzAbstract2DNoise, public NzComplexNoiseBase { - public: - NzFBM2D(nzNoises source, unsigned int seed); - float GetValue(float x, float y, float resolution); - ~NzFBM2D(); - protected: - private: - NzAbstract2DNoise* m_source; - float m_value; - float m_remainder; - nzNoises m_noiseType; + public: + NzFBM2D(nzNoises source, unsigned int seed); + float GetValue(float x, float y, float resolution); + ~NzFBM2D(); + + private: + NzAbstract2DNoise* m_source; + float m_value; + float m_remainder; + nzNoises m_noiseType; }; #endif // FBM2D_HPP diff --git a/include/Nazara/Noise/FBM3D.hpp b/include/Nazara/Noise/FBM3D.hpp index e331581e9..f85f68e26 100644 --- a/include/Nazara/Noise/FBM3D.hpp +++ b/include/Nazara/Noise/FBM3D.hpp @@ -13,16 +13,16 @@ class NAZARA_NOISE_API NzFBM3D : public NzAbstract3DNoise, public NzComplexNoiseBase { - public: - NzFBM3D(nzNoises source, unsigned int seed); - float GetValue(float x, float y, float z, float resolution); - ~NzFBM3D(); - protected: - private: - NzAbstract3DNoise* m_source; - float m_value; - float m_remainder; - nzNoises m_noiseType; + public: + NzFBM3D(nzNoises source, unsigned int seed); + float GetValue(float x, float y, float z, float resolution); + ~NzFBM3D(); + + private: + NzAbstract3DNoise* m_source; + float m_value; + float m_remainder; + nzNoises m_noiseType; }; #endif // FBM3D_HPP diff --git a/include/Nazara/Noise/FBM4D.hpp b/include/Nazara/Noise/FBM4D.hpp index 2aafe2c40..5b781bbc0 100644 --- a/include/Nazara/Noise/FBM4D.hpp +++ b/include/Nazara/Noise/FBM4D.hpp @@ -13,16 +13,16 @@ class NAZARA_NOISE_API NzFBM4D : public NzAbstract4DNoise, public NzComplexNoiseBase { - public: - NzFBM4D(nzNoises source, unsigned int seed); - float GetValue(float x, float y, float z, float w, float resolution); - ~NzFBM4D(); - protected: - private: - NzAbstract4DNoise* m_source; - float m_value; - float m_remainder; - nzNoises m_noiseType; + public: + NzFBM4D(nzNoises source, unsigned int seed); + float GetValue(float x, float y, float z, float w, float resolution); + ~NzFBM4D(); + + private: + NzAbstract4DNoise* m_source; + float m_value; + float m_remainder; + nzNoises m_noiseType; }; #endif // FBM4D_HPP diff --git a/include/Nazara/Noise/HybridMultiFractal3D.hpp b/include/Nazara/Noise/HybridMultiFractal3D.hpp index 6fc84c04a..0f01dd3a1 100644 --- a/include/Nazara/Noise/HybridMultiFractal3D.hpp +++ b/include/Nazara/Noise/HybridMultiFractal3D.hpp @@ -13,19 +13,19 @@ class NAZARA_NOISE_API NzHybridMultiFractal3D : public NzAbstract3DNoise, public NzComplexNoiseBase { - public: - NzHybridMultiFractal3D(nzNoises source, unsigned int seed); - float GetValue(float x, float y, float z, float resolution); - ~NzHybridMultiFractal3D(); - protected: - private: - NzAbstract3DNoise* m_source; - float m_value; - float m_remainder; - float m_offset; - float m_weight; - float m_signal; - nzNoises m_noiseType; + public: + NzHybridMultiFractal3D(nzNoises source, unsigned int seed); + float GetValue(float x, float y, float z, float resolution); + ~NzHybridMultiFractal3D(); + protected: + private: + NzAbstract3DNoise* m_source; + float m_value; + float m_remainder; + float m_offset; + float m_weight; + float m_signal; + nzNoises m_noiseType; }; #endif // HYBRIDMULTIFRACTAL3D_HPP diff --git a/include/Nazara/Noise/HybridMultiFractal4D.hpp b/include/Nazara/Noise/HybridMultiFractal4D.hpp index 04ee10f4f..e264b279b 100644 --- a/include/Nazara/Noise/HybridMultiFractal4D.hpp +++ b/include/Nazara/Noise/HybridMultiFractal4D.hpp @@ -13,19 +13,19 @@ class NAZARA_NOISE_API NzHybridMultiFractal4D : public NzAbstract4DNoise, public NzComplexNoiseBase { - public: - NzHybridMultiFractal4D(nzNoises source, unsigned int seed); - float GetValue(float x, float y, float z, float w, float resolution); - ~NzHybridMultiFractal4D(); - protected: - private: - NzAbstract4DNoise* m_source; - float m_value; - float m_remainder; - float m_offset; - float m_weight; - float m_signal; - nzNoises m_noiseType; + public: + NzHybridMultiFractal4D(nzNoises source, unsigned int seed); + float GetValue(float x, float y, float z, float w, float resolution); + ~NzHybridMultiFractal4D(); + protected: + private: + NzAbstract4DNoise* m_source; + float m_value; + float m_remainder; + float m_offset; + float m_weight; + float m_signal; + nzNoises m_noiseType; }; #endif // HYBRIDMULTIFRACTAL4D_HPP diff --git a/include/Nazara/Noise/HybridMultifractal2D.hpp b/include/Nazara/Noise/HybridMultifractal2D.hpp index 12fac538b..0619c3bb9 100644 --- a/include/Nazara/Noise/HybridMultifractal2D.hpp +++ b/include/Nazara/Noise/HybridMultifractal2D.hpp @@ -13,19 +13,19 @@ class NAZARA_NOISE_API NzHybridMultiFractal2D : public NzAbstract2DNoise, public NzComplexNoiseBase { - public: - NzHybridMultiFractal2D(nzNoises source, unsigned int seed); - float GetValue(float x, float y, float resolution); - ~NzHybridMultiFractal2D(); - protected: - private: - NzAbstract2DNoise* m_source; - float m_value; - float m_remainder; - float m_offset; - float m_weight; - float m_signal; - nzNoises m_noiseType; + public: + NzHybridMultiFractal2D(nzNoises source, unsigned int seed); + float GetValue(float x, float y, float resolution); + ~NzHybridMultiFractal2D(); + + private: + NzAbstract2DNoise* m_source; + float m_value; + float m_remainder; + float m_offset; + float m_weight; + float m_signal; + nzNoises m_noiseType; }; #endif // HYBRIDMULTIFRACTAL2D_HPP diff --git a/include/Nazara/Noise/MappedNoiseBase.hpp b/include/Nazara/Noise/MappedNoiseBase.hpp index c4b4169f5..be68873f7 100644 --- a/include/Nazara/Noise/MappedNoiseBase.hpp +++ b/include/Nazara/Noise/MappedNoiseBase.hpp @@ -12,20 +12,20 @@ class NAZARA_NOISE_API NzMappedNoiseBase : public NzNoiseBase { - public: - NzMappedNoiseBase(); - ~NzMappedNoiseBase() = default; + public: + NzMappedNoiseBase(); + ~NzMappedNoiseBase() = default; - float GetGain() const; - float GetOffset() const; - float GetResolution() const; - void SetGain(float gain); - void SetOffset(float offset); - void SetResolution(float resolution); - protected: - float m_gain; - float m_offset; - float m_resolution; + float GetGain() const; + float GetOffset() const; + float GetResolution() const; + void SetGain(float gain); + void SetOffset(float offset); + void SetResolution(float resolution); + protected: + float m_gain; + float m_offset; + float m_resolution; }; #endif // NAZARA_MAPPEDNOISEBASE_HPP diff --git a/include/Nazara/Noise/NoiseBase.hpp b/include/Nazara/Noise/NoiseBase.hpp index baa240f9f..d2cf9f93d 100644 --- a/include/Nazara/Noise/NoiseBase.hpp +++ b/include/Nazara/Noise/NoiseBase.hpp @@ -12,31 +12,31 @@ enum nzNoises { - PERLIN, - SIMPLEX, - CELL + PERLIN, + SIMPLEX, + CELL }; class NAZARA_NOISE_API NzNoiseBase { - public: - NzNoiseBase(unsigned int seed = 0); - ~NzNoiseBase() = default; + public: + NzNoiseBase(unsigned int seed = 0); + ~NzNoiseBase() = default; - void SetNewSeed(unsigned int seed); + void SetNewSeed(unsigned int seed); - void ShufflePermutationTable(); + void ShufflePermutationTable(); - unsigned int GetUniformRandomValue(); + unsigned int GetUniformRandomValue(); - int fastfloor(float n); - int JenkinsHash(int a, int b, int c); - protected: - unsigned int perm[512]; - private: - unsigned int Ua, Uc, Um; - unsigned int UcurrentSeed; - unsigned int Uprevious, Ulast; + int fastfloor(float n); + int JenkinsHash(int a, int b, int c); + protected: + unsigned int perm[512]; + private: + unsigned int Ua, Uc, Um; + unsigned int UcurrentSeed; + unsigned int Uprevious, Ulast; }; diff --git a/include/Nazara/Noise/Perlin2D.hpp b/include/Nazara/Noise/Perlin2D.hpp index a5eaff5e5..599968ac4 100644 --- a/include/Nazara/Noise/Perlin2D.hpp +++ b/include/Nazara/Noise/Perlin2D.hpp @@ -14,21 +14,21 @@ class NAZARA_NOISE_API NzPerlin2D : public NzAbstract2DNoise { - public: - NzPerlin2D(); - NzPerlin2D(unsigned int seed); - float GetValue(float x, float y, float resolution); - ~NzPerlin2D() = default; - protected: - private: - int x0, y0; - int gi0,gi1,gi2,gi3; - int ii, jj; - float gradient2[8][2]; - float s,t,u,v; - float Cx,Cy; - float Li1, Li2; - NzVector2 temp; + public: + NzPerlin2D(); + NzPerlin2D(unsigned int seed); + float GetValue(float x, float y, float resolution); + ~NzPerlin2D() = default; + protected: + private: + int x0, y0; + int gi0,gi1,gi2,gi3; + int ii, jj; + float gradient2[8][2]; + float s,t,u,v; + float Cx,Cy; + float Li1, Li2; + NzVector2 temp; }; #endif // PERLIN2D_HPP diff --git a/include/Nazara/Noise/Perlin3D.hpp b/include/Nazara/Noise/Perlin3D.hpp index e04713fdd..f32274568 100644 --- a/include/Nazara/Noise/Perlin3D.hpp +++ b/include/Nazara/Noise/Perlin3D.hpp @@ -14,23 +14,23 @@ class NAZARA_NOISE_API NzPerlin3D : public NzAbstract3DNoise { - public: - NzPerlin3D(); - NzPerlin3D(unsigned int seed); - float GetValue(float x, float y, float z, float resolution); - ~NzPerlin3D() = default; - protected: - private: - int x0,y0,z0; - int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7; - int ii,jj,kk; - float gradient3[16][3]; - float Li1,Li2,Li3,Li4,Li5,Li6; - float s[2],t[2],u[2],v[2]; - float Cx,Cy,Cz; - float nx,ny,nz; - float tmp; - NzVector3 temp; + public: + NzPerlin3D(); + NzPerlin3D(unsigned int seed); + float GetValue(float x, float y, float z, float resolution); + ~NzPerlin3D() = default; + protected: + private: + int x0,y0,z0; + int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7; + int ii,jj,kk; + float gradient3[16][3]; + float Li1,Li2,Li3,Li4,Li5,Li6; + float s[2],t[2],u[2],v[2]; + float Cx,Cy,Cz; + float nx,ny,nz; + float tmp; + NzVector3 temp; }; #endif // PERLIN3D_HPP diff --git a/include/Nazara/Noise/Perlin4D.hpp b/include/Nazara/Noise/Perlin4D.hpp index 6abef3ba3..c317ed75d 100644 --- a/include/Nazara/Noise/Perlin4D.hpp +++ b/include/Nazara/Noise/Perlin4D.hpp @@ -14,22 +14,22 @@ class NAZARA_NOISE_API NzPerlin4D : public NzAbstract4DNoise { - public: - NzPerlin4D(); - NzPerlin4D(unsigned int seed); - float GetValue(float x, float y, float z, float w, float resolution); - ~NzPerlin4D() = default; - protected: - private: - int x0,y0,z0,w0; - int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7,gi8,gi9,gi10,gi11,gi12,gi13,gi14,gi15; - int ii,jj,kk,ll; - float gradient4[32][4]; - float Li1,Li2,Li3,Li4,Li5,Li6,Li7,Li8,Li9,Li10,Li11,Li12,Li13,Li14; - float s[4],t[4],u[4],v[4]; - float Cx,Cy,Cz,Cw; - float tmp; - NzVector4 temp; + public: + NzPerlin4D(); + NzPerlin4D(unsigned int seed); + float GetValue(float x, float y, float z, float w, float resolution); + ~NzPerlin4D() = default; + protected: + private: + int x0,y0,z0,w0; + int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7,gi8,gi9,gi10,gi11,gi12,gi13,gi14,gi15; + int ii,jj,kk,ll; + float gradient4[32][4]; + float Li1,Li2,Li3,Li4,Li5,Li6,Li7,Li8,Li9,Li10,Li11,Li12,Li13,Li14; + float s[4],t[4],u[4],v[4]; + float Cx,Cy,Cz,Cw; + float tmp; + NzVector4 temp; }; #endif // PERLIN4D_HPP diff --git a/include/Nazara/Noise/Simplex2D.hpp b/include/Nazara/Noise/Simplex2D.hpp index 232a730ea..a951086a0 100644 --- a/include/Nazara/Noise/Simplex2D.hpp +++ b/include/Nazara/Noise/Simplex2D.hpp @@ -14,24 +14,24 @@ class NAZARA_NOISE_API NzSimplex2D : public NzAbstract2DNoise { - public: - NzSimplex2D(); - NzSimplex2D(unsigned int seed); - float GetValue(float x, float y, float resolution); - virtual ~NzSimplex2D() = default; - protected: - private: - int ii,jj; - int gi0,gi1,gi2; - NzVector2i skewedCubeOrigin,off1; - float n1,n2,n3; - float c1,c2,c3; - float gradient2[8][2]; - float UnskewCoeff2D; - float SkewCoeff2D; - float sum; - NzVector2 unskewedCubeOrigin, unskewedDistToOrigin; - NzVector2 d1,d2,d3; + public: + NzSimplex2D(); + NzSimplex2D(unsigned int seed); + float GetValue(float x, float y, float resolution); + virtual ~NzSimplex2D() = default; + protected: + private: + int ii,jj; + int gi0,gi1,gi2; + NzVector2i skewedCubeOrigin,off1; + float n1,n2,n3; + float c1,c2,c3; + float gradient2[8][2]; + float UnskewCoeff2D; + float SkewCoeff2D; + float sum; + NzVector2 unskewedCubeOrigin, unskewedDistToOrigin; + NzVector2 d1,d2,d3; }; #endif // SIMPLEX2D_HPP diff --git a/include/Nazara/Noise/Simplex3D.hpp b/include/Nazara/Noise/Simplex3D.hpp index 5ca1bd425..ecfb1f13d 100644 --- a/include/Nazara/Noise/Simplex3D.hpp +++ b/include/Nazara/Noise/Simplex3D.hpp @@ -14,24 +14,24 @@ class NAZARA_NOISE_API NzSimplex3D : public NzAbstract3DNoise { - public: - NzSimplex3D(); - NzSimplex3D(unsigned int seed); - float GetValue(float x, float y, float z, float resolution); - ~NzSimplex3D() = default; - protected: - private: - int ii,jj,kk; - int gi0,gi1,gi2,gi3; - NzVector3i skewedCubeOrigin,off1,off2; - float n1,n2,n3,n4; - float c1,c2,c3,c4; - float gradient3[12][3]; - float UnskewCoeff3D; - float SkewCoeff3D; - float sum; - NzVector3 unskewedCubeOrigin, unskewedDistToOrigin; - NzVector3 d1,d2,d3,d4; + public: + NzSimplex3D(); + NzSimplex3D(unsigned int seed); + float GetValue(float x, float y, float z, float resolution); + ~NzSimplex3D() = default; + protected: + private: + int ii,jj,kk; + int gi0,gi1,gi2,gi3; + NzVector3i skewedCubeOrigin,off1,off2; + float n1,n2,n3,n4; + float c1,c2,c3,c4; + float gradient3[12][3]; + float UnskewCoeff3D; + float SkewCoeff3D; + float sum; + NzVector3 unskewedCubeOrigin, unskewedDistToOrigin; + NzVector3 d1,d2,d3,d4; }; #endif // SIMPLEX3D_HPP diff --git a/include/Nazara/Noise/Simplex4D.hpp b/include/Nazara/Noise/Simplex4D.hpp index 81d134e6f..af4d2f043 100644 --- a/include/Nazara/Noise/Simplex4D.hpp +++ b/include/Nazara/Noise/Simplex4D.hpp @@ -14,26 +14,26 @@ class NAZARA_NOISE_API NzSimplex4D : public NzAbstract4DNoise { - public: - NzSimplex4D(); - NzSimplex4D(unsigned int seed); - float GetValue(float x, float y, float z, float w, float resolution); - ~NzSimplex4D() = default; - protected: - private: - int ii,jj,kk,ll; - int gi0,gi1,gi2,gi3,gi4; - NzVector4i skewedCubeOrigin,off1,off2,off3; - int lookupTable4D[64][4]; - int c; - float n1,n2,n3,n4,n5; - float c1,c2,c3,c4,c5,c6; - float gradient4[32][4]; - float UnskewCoeff4D; - float SkewCoeff4D; - float sum; - NzVector4 unskewedCubeOrigin, unskewedDistToOrigin; - NzVector4 d1,d2,d3,d4,d5; + public: + NzSimplex4D(); + NzSimplex4D(unsigned int seed); + float GetValue(float x, float y, float z, float w, float resolution); + ~NzSimplex4D() = default; + protected: + private: + int ii,jj,kk,ll; + int gi0,gi1,gi2,gi3,gi4; + NzVector4i skewedCubeOrigin,off1,off2,off3; + int lookupTable4D[64][4]; + int c; + float n1,n2,n3,n4,n5; + float c1,c2,c3,c4,c5,c6; + float gradient4[32][4]; + float UnskewCoeff4D; + float SkewCoeff4D; + float sum; + NzVector4 unskewedCubeOrigin, unskewedDistToOrigin; + NzVector4 d1,d2,d3,d4,d5; }; #endif // SIMPLEX4D_H diff --git a/include/Nazara/Physics/Geom.hpp b/include/Nazara/Physics/Geom.hpp index c14f10ff8..d9321b037 100644 --- a/include/Nazara/Physics/Geom.hpp +++ b/include/Nazara/Physics/Geom.hpp @@ -38,8 +38,8 @@ class NAZARA_PHYSICS_API NzPhysGeom : public NzRefCounted { public: NzPhysGeom() = default; - NzPhysGeom(const NzPhysGeom&) = delete; - NzPhysGeom(NzPhysGeom&&) = delete; + NzPhysGeom(const NzPhysGeom&) = delete; + NzPhysGeom(NzPhysGeom&&) = delete; virtual ~NzPhysGeom(); NzBoxf ComputeAABB(const NzVector3f& translation, const NzQuaternionf& rotation, const NzVector3f& scale) const; @@ -50,8 +50,8 @@ class NAZARA_PHYSICS_API NzPhysGeom : public NzRefCounted NewtonCollision* GetHandle(NzPhysWorld* world) const; virtual nzGeomType GetType() const = 0; - NzPhysGeom& operator=(const NzPhysGeom&) = delete; - NzPhysGeom& operator=(NzPhysGeom&&) = delete; + NzPhysGeom& operator=(const NzPhysGeom&) = delete; + NzPhysGeom& operator=(NzPhysGeom&&) = delete; static NzPhysGeomRef Build(const NzPrimitiveList& list); diff --git a/include/Nazara/Physics/PhysWorld.hpp b/include/Nazara/Physics/PhysWorld.hpp index a48d85a86..a86d95544 100644 --- a/include/Nazara/Physics/PhysWorld.hpp +++ b/include/Nazara/Physics/PhysWorld.hpp @@ -18,8 +18,8 @@ class NAZARA_PHYSICS_API NzPhysWorld { public: NzPhysWorld(); - NzPhysWorld(const NzPhysWorld&) = delete; - NzPhysWorld(NzPhysWorld&&) = delete; ///TODO + NzPhysWorld(const NzPhysWorld&) = delete; + NzPhysWorld(NzPhysWorld&&) = delete; ///TODO ~NzPhysWorld(); NzVector3f GetGravity() const; @@ -32,8 +32,8 @@ class NAZARA_PHYSICS_API NzPhysWorld void Step(float timestep); - NzPhysWorld& operator=(const NzPhysWorld&) = delete; - NzPhysWorld& operator=(NzPhysWorld&&) = delete; ///TODO + NzPhysWorld& operator=(const NzPhysWorld&) = delete; + NzPhysWorld& operator=(NzPhysWorld&&) = delete; ///TODO private: NzVector3f m_gravity; diff --git a/include/Nazara/Renderer/GpuQuery.hpp b/include/Nazara/Renderer/GpuQuery.hpp index 334de87b9..29509b241 100644 --- a/include/Nazara/Renderer/GpuQuery.hpp +++ b/include/Nazara/Renderer/GpuQuery.hpp @@ -15,8 +15,8 @@ class NAZARA_RENDERER_API NzGpuQuery { public: NzGpuQuery(); - NzGpuQuery(const NzGpuQuery&) = delete; - NzGpuQuery(NzGpuQuery&&) = delete; ///TODO + NzGpuQuery(const NzGpuQuery&) = delete; + NzGpuQuery(NzGpuQuery&&) = delete; ///TODO ~NzGpuQuery(); void Begin(nzGpuQueryMode mode); @@ -29,8 +29,8 @@ class NAZARA_RENDERER_API NzGpuQuery // Fonctions OpenGL unsigned int GetOpenGLID() const; - NzGpuQuery& operator=(const NzGpuQuery&) = delete; - NzGpuQuery& operator=(NzGpuQuery&&) = delete; ///TODO + NzGpuQuery& operator=(const NzGpuQuery&) = delete; + NzGpuQuery& operator=(NzGpuQuery&&) = delete; ///TODO static bool IsModeSupported(nzGpuQueryMode mode); static bool IsSupported(); diff --git a/include/Nazara/Renderer/RenderBuffer.hpp b/include/Nazara/Renderer/RenderBuffer.hpp index e0ccbbb1c..8176db842 100644 --- a/include/Nazara/Renderer/RenderBuffer.hpp +++ b/include/Nazara/Renderer/RenderBuffer.hpp @@ -28,8 +28,8 @@ class NAZARA_RENDERER_API NzRenderBuffer : public NzRefCounted public: NzRenderBuffer(); - NzRenderBuffer(const NzRenderBuffer&) = delete; - NzRenderBuffer(NzRenderBuffer&&) = delete; + NzRenderBuffer(const NzRenderBuffer&) = delete; + NzRenderBuffer(NzRenderBuffer&&) = delete; ~NzRenderBuffer(); bool Create(nzPixelFormat format, unsigned int width, unsigned int height); @@ -44,8 +44,8 @@ class NAZARA_RENDERER_API NzRenderBuffer : public NzRefCounted bool IsValid() const; - NzRenderBuffer& operator=(const NzRenderBuffer&) = delete; - NzRenderBuffer& operator=(NzRenderBuffer&&) = delete; + NzRenderBuffer& operator=(const NzRenderBuffer&) = delete; + NzRenderBuffer& operator=(NzRenderBuffer&&) = delete; static bool IsSupported(); template static NzRenderBufferRef New(Args&&... args); diff --git a/include/Nazara/Renderer/RenderTexture.hpp b/include/Nazara/Renderer/RenderTexture.hpp index b7796bac2..2aa872122 100644 --- a/include/Nazara/Renderer/RenderTexture.hpp +++ b/include/Nazara/Renderer/RenderTexture.hpp @@ -26,8 +26,8 @@ class NAZARA_RENDERER_API NzRenderTexture : public NzRenderTarget { public: inline NzRenderTexture(); - NzRenderTexture(const NzRenderTexture&) = delete; - NzRenderTexture(NzRenderTexture&&) = delete; ///TODO + NzRenderTexture(const NzRenderTexture&) = delete; + NzRenderTexture(NzRenderTexture&&) = delete; ///TODO inline ~NzRenderTexture(); bool AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzRenderBuffer* buffer); @@ -60,8 +60,8 @@ class NAZARA_RENDERER_API NzRenderTexture : public NzRenderTarget unsigned int GetOpenGLID() const; bool HasContext() const override; - NzRenderTexture& operator=(const NzRenderTexture&) = delete; - NzRenderTexture& operator=(NzRenderTexture&&) = delete; ///TODO + NzRenderTexture& operator=(const NzRenderTexture&) = delete; + NzRenderTexture& operator=(NzRenderTexture&&) = delete; ///TODO static inline void Blit(NzRenderTexture* src, NzRenderTexture* dst, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); static void Blit(NzRenderTexture* src, NzRectui srcRect, NzRenderTexture* dst, NzRectui dstRect, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); diff --git a/include/Nazara/Renderer/Shader.hpp b/include/Nazara/Renderer/Shader.hpp index 7d142acac..9217b9482 100644 --- a/include/Nazara/Renderer/Shader.hpp +++ b/include/Nazara/Renderer/Shader.hpp @@ -36,8 +36,8 @@ class NAZARA_RENDERER_API NzShader : public NzRefCounted public: NzShader(); - NzShader(const NzShader&) = delete; - NzShader(NzShader&&) = delete; + NzShader(const NzShader&) = delete; + NzShader(NzShader&&) = delete; ~NzShader(); void AttachStage(nzShaderStage stage, const NzShaderStage& shaderStage); @@ -99,8 +99,8 @@ class NAZARA_RENDERER_API NzShader : public NzRefCounted // Fonctions OpenGL unsigned int GetOpenGLID() const; - NzShader& operator=(const NzShader&) = delete; - NzShader& operator=(NzShader&&) = delete; + NzShader& operator=(const NzShader&) = delete; + NzShader& operator=(NzShader&&) = delete; static bool IsStageSupported(nzShaderStage stage); template static NzShaderRef New(Args&&... args); diff --git a/include/Nazara/Renderer/ShaderStage.hpp b/include/Nazara/Renderer/ShaderStage.hpp index 479c1da3c..4e4917f63 100644 --- a/include/Nazara/Renderer/ShaderStage.hpp +++ b/include/Nazara/Renderer/ShaderStage.hpp @@ -17,8 +17,8 @@ class NAZARA_RENDERER_API NzShaderStage public: NzShaderStage(); NzShaderStage(nzShaderStage stage); - NzShaderStage(const NzShaderStage&) = delete; - NzShaderStage(NzShaderStage&& stage); + NzShaderStage(const NzShaderStage&) = delete; + NzShaderStage(NzShaderStage&& stage); ~NzShaderStage(); bool Compile(); @@ -36,8 +36,8 @@ class NAZARA_RENDERER_API NzShaderStage void SetSource(const NzString& source); bool SetSourceFromFile(const NzString& filePath); - NzShaderStage& operator=(const NzShaderStage&) = delete; - NzShaderStage& operator=(NzShaderStage&& shader); + NzShaderStage& operator=(const NzShaderStage&) = delete; + NzShaderStage& operator=(NzShaderStage&& shader); // Fonctions OpenGL unsigned int GetOpenGLID() const; diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index e3b85100b..32e440924 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -39,8 +39,8 @@ class NAZARA_RENDERER_API NzTexture : public NzAbstractImage, public NzRefCounte NzTexture() = default; NzTexture(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1); explicit NzTexture(const NzImage& image); - NzTexture(const NzTexture&) = delete; - NzTexture(NzTexture&&) = delete; + NzTexture(const NzTexture&) = delete; + NzTexture(NzTexture&&) = delete; ~NzTexture(); bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1); @@ -103,8 +103,8 @@ class NAZARA_RENDERER_API NzTexture : public NzAbstractImage, public NzRefCounte // Fonctions OpenGL unsigned int GetOpenGLID() const; - NzTexture& operator=(const NzTexture&) = delete; - NzTexture& operator=(NzTexture&&) = delete; + NzTexture& operator=(const NzTexture&) = delete; + NzTexture& operator=(NzTexture&&) = delete; static unsigned int GetValidSize(unsigned int size); static bool IsFormatSupported(nzPixelFormat format); diff --git a/include/Nazara/Utility/Buffer.hpp b/include/Nazara/Utility/Buffer.hpp index 1081905da..89f48f241 100644 --- a/include/Nazara/Utility/Buffer.hpp +++ b/include/Nazara/Utility/Buffer.hpp @@ -30,8 +30,8 @@ class NAZARA_UTILITY_API NzBuffer : public NzRefCounted NzBuffer(nzBufferType type); NzBuffer(nzBufferType type, unsigned int size, nzUInt32 storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); - NzBuffer(const NzBuffer&) = delete; - NzBuffer(NzBuffer&&) = delete; + NzBuffer(const NzBuffer&) = delete; + NzBuffer(NzBuffer&&) = delete; ~NzBuffer(); bool CopyContent(const NzBuffer& buffer); @@ -57,8 +57,8 @@ class NAZARA_UTILITY_API NzBuffer : public NzRefCounted void Unmap() const; - NzBuffer& operator=(const NzBuffer&) = delete; - NzBuffer& operator=(NzBuffer&&) = delete; + NzBuffer& operator=(const NzBuffer&) = delete; + NzBuffer& operator=(NzBuffer&&) = delete; static bool IsStorageSupported(nzUInt32 storage); template static NzBufferRef New(Args&&... args); diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index e11ecf551..f0c52cb11 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -44,8 +44,8 @@ class NAZARA_UTILITY_API NzFont : public NzRefCounted, public NzResource struct SizeInfo; NzFont(); - NzFont(const NzFont&) = delete; - NzFont(NzFont&&) = delete; + NzFont(const NzFont&) = delete; + NzFont(NzFont&&) = delete; ~NzFont(); void ClearGlyphCache(); @@ -82,8 +82,8 @@ class NAZARA_UTILITY_API NzFont : public NzRefCounted, public NzResource void SetGlyphBorder(unsigned int borderSize); void SetMinimumStepSize(unsigned int minimumStepSize); - NzFont& operator=(const NzFont&) = delete; - NzFont& operator=(NzFont&&) = delete; + NzFont& operator=(const NzFont&) = delete; + NzFont& operator=(NzFont&&) = delete; static std::shared_ptr GetDefaultAtlas(); static NzFont* GetDefault(); diff --git a/include/Nazara/Utility/GuillotineImageAtlas.hpp b/include/Nazara/Utility/GuillotineImageAtlas.hpp index 60973d74d..cb349361e 100644 --- a/include/Nazara/Utility/GuillotineImageAtlas.hpp +++ b/include/Nazara/Utility/GuillotineImageAtlas.hpp @@ -43,7 +43,7 @@ class NAZARA_UTILITY_API NzGuillotineImageAtlas : public NzAbstractAtlas struct QueuedGlyph { - NzImage image; + NzImage image; NzRectui rect; bool flipped; }; diff --git a/include/Nazara/Utility/Window.hpp b/include/Nazara/Utility/Window.hpp index ce38e72b5..4effff377 100644 --- a/include/Nazara/Utility/Window.hpp +++ b/include/Nazara/Utility/Window.hpp @@ -39,8 +39,8 @@ class NAZARA_UTILITY_API NzWindow NzWindow(); NzWindow(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default); NzWindow(NzWindowHandle handle); - NzWindow(const NzWindow&) = delete; - NzWindow(NzWindow&&) = delete; ///TODO + NzWindow(const NzWindow&) = delete; + NzWindow(NzWindow&&) = delete; ///TODO virtual ~NzWindow(); void Close(); @@ -90,8 +90,8 @@ class NAZARA_UTILITY_API NzWindow bool WaitEvent(NzEvent* event); - NzWindow& operator=(const NzWindow&) = delete; - NzWindow& operator=(NzWindow&&) = delete; ///TODO + NzWindow& operator=(const NzWindow&) = delete; + NzWindow& operator=(NzWindow&&) = delete; ///TODO protected: virtual bool OnWindowCreated(); diff --git a/src/Nazara/Audio/Formats/sndfileLoader.cpp b/src/Nazara/Audio/Formats/sndfileLoader.cpp index 1b3100d40..3020c8de6 100644 --- a/src/Nazara/Audio/Formats/sndfileLoader.cpp +++ b/src/Nazara/Audio/Formats/sndfileLoader.cpp @@ -25,21 +25,21 @@ namespace { sf_count_t GetSize(void* user_data) { - NzInputStream* stream = static_cast(user_data); + NzInputStream* stream = static_cast(user_data); return stream->GetSize(); } - sf_count_t Read(void* ptr, sf_count_t count, void* user_data) - { - NzInputStream* stream = static_cast(user_data); - return static_cast(stream->Read(ptr, static_cast(count))); - } + sf_count_t Read(void* ptr, sf_count_t count, void* user_data) + { + NzInputStream* stream = static_cast(user_data); + return static_cast(stream->Read(ptr, static_cast(count))); + } - sf_count_t Seek(sf_count_t offset, int whence, void* user_data) - { - NzInputStream* stream = static_cast(user_data); - switch (whence) - { + sf_count_t Seek(sf_count_t offset, int whence, void* user_data) + { + NzInputStream* stream = static_cast(user_data); + switch (whence) + { case SEEK_CUR: stream->Read(nullptr, static_cast(offset)); break; @@ -54,16 +54,16 @@ namespace default: NazaraInternalError("Seek mode not handled"); - } + } - return stream->GetCursorPos(); - } + return stream->GetCursorPos(); + } - sf_count_t Tell(void* user_data) - { - NzInputStream* stream = static_cast(user_data); - return stream->GetCursorPos(); - } + sf_count_t Tell(void* user_data) + { + NzInputStream* stream = static_cast(user_data); + return stream->GetCursorPos(); + } static SF_VIRTUAL_IO callbacks = {GetSize, Seek, Read, nullptr, Tell}; diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index 0d3bd757e..eaddfa74c 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -121,28 +121,28 @@ nzUInt32 NzMusic::GetPlayingOffset() const nzUInt32 NzMusic::GetSampleCount() const { - #if NAZARA_AUDIO_SAFE - if (!m_impl) - { - NazaraError("Music not created"); - return 0; - } - #endif + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return 0; + } + #endif - return m_impl->stream->GetSampleCount(); + return m_impl->stream->GetSampleCount(); } nzUInt32 NzMusic::GetSampleRate() const { - #if NAZARA_AUDIO_SAFE - if (!m_impl) - { - NazaraError("Music not created"); - return 0; - } - #endif + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return 0; + } + #endif - return m_impl->stream->GetSampleRate(); + return m_impl->stream->GetSampleRate(); } nzSoundStatus NzMusic::GetStatus() const diff --git a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp index 4b7e179cb..34321d345 100644 --- a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp +++ b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp @@ -104,7 +104,7 @@ bool NzDeferredPhongLightingPass::Process(const NzSceneData& sceneData, unsigned { m_directionalLightShader->SendColor(m_directionalLightUniforms.locations.color, light.color); m_directionalLightShader->SendVector(m_directionalLightUniforms.locations.factors, NzVector2f(light.ambientFactor, light.diffuseFactor)); - m_directionalLightShader->SendVector(m_directionalLightUniforms.locations.parameters1, NzVector4f(light.direction)); + m_directionalLightShader->SendVector(m_directionalLightUniforms.locations.parameters1, NzVector4f(light.direction)); NzRenderer::DrawFullscreenQuad(); } diff --git a/src/Nazara/Graphics/DeferredRenderTechnique.cpp b/src/Nazara/Graphics/DeferredRenderTechnique.cpp index d5af6e2c8..f660a1e22 100644 --- a/src/Nazara/Graphics/DeferredRenderTechnique.cpp +++ b/src/Nazara/Graphics/DeferredRenderTechnique.cpp @@ -375,8 +375,8 @@ NzDeferredRenderPass* NzDeferredRenderTechnique::ResetPass(nzRenderPassType rend if (oldPass && !oldPass->IsEnabled()) smartPtr->Enable(false); - SetPass(renderPass, position, smartPtr.get()); - return smartPtr.release(); + SetPass(renderPass, position, smartPtr.get()); + return smartPtr.release(); } void NzDeferredRenderTechnique::SetPass(nzRenderPassType relativeTo, int position, NzDeferredRenderPass* pass) diff --git a/src/Nazara/Graphics/SkinningManager.cpp b/src/Nazara/Graphics/SkinningManager.cpp index b9189f7cd..a64a3863e 100644 --- a/src/Nazara/Graphics/SkinningManager.cpp +++ b/src/Nazara/Graphics/SkinningManager.cpp @@ -15,13 +15,13 @@ namespace { - struct BufferData - { - NazaraSlot(NzSkeletalMesh, OnSkeletalMeshDestroy, skeletalMeshDestroySlot); + struct BufferData + { + NazaraSlot(NzSkeletalMesh, OnSkeletalMeshDestroy, skeletalMeshDestroySlot); NzVertexBufferRef buffer; bool updated; - }; + }; using MeshMap = std::unordered_map; @@ -115,9 +115,9 @@ NzVertexBuffer* NzSkinningManager::GetBuffer(const NzSkeletalMesh* mesh, const N NzVertexBuffer* buffer; - MeshMap& meshMap = it->second.meshMap; - MeshMap::iterator it2 = meshMap.find(mesh); - if (it2 == meshMap.end()) + MeshMap& meshMap = it->second.meshMap; + MeshMap::iterator it2 = meshMap.find(mesh); + if (it2 == meshMap.end()) { NzVertexBufferRef vertexBuffer = NzVertexBuffer::New(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), mesh->GetVertexCount(), nzDataStorage_Hardware, nzBufferUsage_Dynamic); diff --git a/src/Nazara/Noise/Abstract2DNoise.cpp b/src/Nazara/Noise/Abstract2DNoise.cpp index 2f2ae4f76..562661f9e 100644 --- a/src/Nazara/Noise/Abstract2DNoise.cpp +++ b/src/Nazara/Noise/Abstract2DNoise.cpp @@ -12,10 +12,10 @@ NzAbstract2DNoise::~NzAbstract2DNoise() = default; float NzAbstract2DNoise::GetBasicValue(float x, float y) { - return this->GetValue(x,y,m_resolution); + return this->GetValue(x,y,m_resolution); } float NzAbstract2DNoise::GetMappedValue(float x, float y) { - return (this->GetValue(x,y,m_resolution) + m_offset) * m_gain; + return (this->GetValue(x,y,m_resolution) + m_offset) * m_gain; } diff --git a/src/Nazara/Noise/Abstract3DNoise.cpp b/src/Nazara/Noise/Abstract3DNoise.cpp index 654df62d6..26abb35ad 100644 --- a/src/Nazara/Noise/Abstract3DNoise.cpp +++ b/src/Nazara/Noise/Abstract3DNoise.cpp @@ -12,10 +12,10 @@ NzAbstract3DNoise::~NzAbstract3DNoise() = default; float NzAbstract3DNoise::GetBasicValue(float x, float y, float z) { - return this->GetValue(x,y,z,m_resolution); + return this->GetValue(x,y,z,m_resolution); } float NzAbstract3DNoise::GetMappedValue(float x, float y, float z) { - return (this->GetValue(x,y,z,m_resolution) + m_offset) * m_gain ; + return (this->GetValue(x,y,z,m_resolution) + m_offset) * m_gain ; } diff --git a/src/Nazara/Noise/Abstract4DNoise.cpp b/src/Nazara/Noise/Abstract4DNoise.cpp index 781e3b57e..e6688447a 100644 --- a/src/Nazara/Noise/Abstract4DNoise.cpp +++ b/src/Nazara/Noise/Abstract4DNoise.cpp @@ -12,10 +12,10 @@ NzAbstract4DNoise::~NzAbstract4DNoise() = default; float NzAbstract4DNoise::GetBasicValue(float x, float y, float z, float w) { - return this->GetValue(x,y,z,w,m_resolution); + return this->GetValue(x,y,z,w,m_resolution); } float NzAbstract4DNoise::GetMappedValue(float x, float y, float z, float w) { - return (this->GetValue(x,y,z,w,m_resolution) + m_offset) * m_gain ; + return (this->GetValue(x,y,z,w,m_resolution) + m_offset) * m_gain ; } diff --git a/src/Nazara/Noise/ComplexNoiseBase.cpp b/src/Nazara/Noise/ComplexNoiseBase.cpp index 7529efdb5..d3cadd270 100644 --- a/src/Nazara/Noise/ComplexNoiseBase.cpp +++ b/src/Nazara/Noise/ComplexNoiseBase.cpp @@ -10,71 +10,71 @@ NzComplexNoiseBase::NzComplexNoiseBase() { - m_parametersModified = true; - m_lacunarity = 5.0f; - m_hurst = 1.2f; - m_octaves = 3.0f; + m_parametersModified = true; + m_lacunarity = 5.0f; + m_hurst = 1.2f; + m_octaves = 3.0f; - for (int i(0) ; i < m_octaves; ++i) - { - m_exponent_array[i] = 0; - } + for (int i(0) ; i < m_octaves; ++i) + { + m_exponent_array[i] = 0; + } } float NzComplexNoiseBase::GetLacunarity() const { - return m_lacunarity; + return m_lacunarity; } float NzComplexNoiseBase::GetHurstParameter() const { - return m_hurst; + return m_hurst; } float NzComplexNoiseBase::GetOctaveNumber() const { - return m_octaves; + return m_octaves; } void NzComplexNoiseBase::SetLacunarity(float lacunarity) { - m_lacunarity = lacunarity; - m_parametersModified = true; + m_lacunarity = lacunarity; + m_parametersModified = true; } void NzComplexNoiseBase::SetHurstParameter(float h) { - m_hurst = h; - m_parametersModified = true; + m_hurst = h; + m_parametersModified = true; } void NzComplexNoiseBase::SetOctavesNumber(float octaves) { - if(octaves <= 30.0f) - m_octaves = octaves; - else - m_octaves = 30.0f; + if(octaves <= 30.0f) + m_octaves = octaves; + else + m_octaves = 30.0f; - m_parametersModified = true; + m_parametersModified = true; } void NzComplexNoiseBase::RecomputeExponentArray() { - if(m_parametersModified) - { - float frequency = 1.0; - m_sum = 0.f; - for (int i(0) ; i < static_cast(m_octaves) ; ++i) - { + if(m_parametersModified) + { + float frequency = 1.0; + m_sum = 0.f; + for (int i(0) ; i < static_cast(m_octaves) ; ++i) + { - m_exponent_array[i] = std::pow( frequency, -m_hurst ); - frequency *= m_lacunarity; + m_exponent_array[i] = std::pow( frequency, -m_hurst ); + frequency *= m_lacunarity; - m_sum += m_exponent_array[i]; + m_sum += m_exponent_array[i]; - } - m_parametersModified = false; - } + } + m_parametersModified = false; + } } diff --git a/src/Nazara/Noise/FBM2D.cpp b/src/Nazara/Noise/FBM2D.cpp index 8d43e3a07..9e35b3c57 100644 --- a/src/Nazara/Noise/FBM2D.cpp +++ b/src/Nazara/Noise/FBM2D.cpp @@ -11,41 +11,41 @@ NzFBM2D::NzFBM2D(nzNoises source, unsigned int seed) { - switch(source) - { - case PERLIN: - m_source = new NzPerlin2D(); - break; + switch(source) + { + case PERLIN: + m_source = new NzPerlin2D(); + break; - default: - m_source = new NzSimplex2D(); - break; - } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; + default: + m_source = new NzSimplex2D(); + break; + } + m_source->SetNewSeed(seed); + m_source->ShufflePermutationTable(); + m_noiseType = source; } float NzFBM2D::GetValue(float x, float y, float resolution) { - this->RecomputeExponentArray(); + this->RecomputeExponentArray(); - m_value = 0.0; + m_value = 0.0; - for (int i(0); i < m_octaves; ++i) - { - m_value += m_source->GetValue(x,y,resolution) * m_exponent_array[i]; - resolution *= m_lacunarity; - } - m_remainder = m_octaves - static_cast(m_octaves); + for (int i(0); i < m_octaves; ++i) + { + m_value += m_source->GetValue(x,y,resolution) * m_exponent_array[i]; + resolution *= m_lacunarity; + } + m_remainder = m_octaves - static_cast(m_octaves); - if(!NzNumberEquals(m_remainder, static_cast(0.0))) - m_value += m_remainder * m_source->GetValue(x,y,resolution) * m_exponent_array[static_cast(m_octaves-1)]; + if(!NzNumberEquals(m_remainder, static_cast(0.0))) + m_value += m_remainder * m_source->GetValue(x,y,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - return m_value/this->m_sum; + return m_value/this->m_sum; } NzFBM2D::~NzFBM2D() { - delete m_source; + delete m_source; } diff --git a/src/Nazara/Noise/FBM3D.cpp b/src/Nazara/Noise/FBM3D.cpp index 6ac7afc07..a56a8a90c 100644 --- a/src/Nazara/Noise/FBM3D.cpp +++ b/src/Nazara/Noise/FBM3D.cpp @@ -11,41 +11,41 @@ NzFBM3D::NzFBM3D(nzNoises source, unsigned int seed) { - switch(source) - { - case PERLIN: - m_source = new NzPerlin3D(); - break; + switch(source) + { + case PERLIN: + m_source = new NzPerlin3D(); + break; - default: - m_source = new NzSimplex3D(); - break; - } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; + default: + m_source = new NzSimplex3D(); + break; + } + m_source->SetNewSeed(seed); + m_source->ShufflePermutationTable(); + m_noiseType = source; } float NzFBM3D::GetValue(float x, float y, float z, float resolution) { - this->RecomputeExponentArray(); + this->RecomputeExponentArray(); - m_value = 0.0; + m_value = 0.0; - for (int i(0); i < m_octaves; ++i) - { - m_value += m_source->GetValue(x,y,z,resolution) * m_exponent_array[i]; - resolution *= m_lacunarity; - } - m_remainder = m_octaves - static_cast(m_octaves); + for (int i(0); i < m_octaves; ++i) + { + m_value += m_source->GetValue(x,y,z,resolution) * m_exponent_array[i]; + resolution *= m_lacunarity; + } + m_remainder = m_octaves - static_cast(m_octaves); - if(!NzNumberEquals(m_remainder, static_cast(0.0))) - m_value += m_remainder * m_source->GetValue(x,y,z,resolution) * m_exponent_array[static_cast(m_octaves-1)]; + if(!NzNumberEquals(m_remainder, static_cast(0.0))) + m_value += m_remainder * m_source->GetValue(x,y,z,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - return m_value/this->m_sum; + return m_value/this->m_sum; } NzFBM3D::~NzFBM3D() { - delete m_source; + delete m_source; } diff --git a/src/Nazara/Noise/FBM4D.cpp b/src/Nazara/Noise/FBM4D.cpp index c5a256a40..483ef7a77 100644 --- a/src/Nazara/Noise/FBM4D.cpp +++ b/src/Nazara/Noise/FBM4D.cpp @@ -11,41 +11,41 @@ NzFBM4D::NzFBM4D(nzNoises source, unsigned int seed) { - switch(source) - { - case PERLIN: - m_source = new NzPerlin4D(); - break; + switch(source) + { + case PERLIN: + m_source = new NzPerlin4D(); + break; - default: - m_source = new NzSimplex4D(); - break; - } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; + default: + m_source = new NzSimplex4D(); + break; + } + m_source->SetNewSeed(seed); + m_source->ShufflePermutationTable(); + m_noiseType = source; } float NzFBM4D::GetValue(float x, float y, float z, float w, float resolution) { - this->RecomputeExponentArray(); + this->RecomputeExponentArray(); - m_value = 0.0; + m_value = 0.0; - for (int i(0); i < m_octaves; ++i) - { - m_value += m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[i]; - resolution *= m_lacunarity; - } - m_remainder = m_octaves - static_cast(m_octaves); + for (int i(0); i < m_octaves; ++i) + { + m_value += m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[i]; + resolution *= m_lacunarity; + } + m_remainder = m_octaves - static_cast(m_octaves); - if(!NzNumberEquals(m_remainder, static_cast(0.0))) - m_value += m_remainder * m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[static_cast(m_octaves-1)]; + if(!NzNumberEquals(m_remainder, static_cast(0.0))) + m_value += m_remainder * m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - return m_value/this->m_sum; + return m_value/this->m_sum; } NzFBM4D::~NzFBM4D() { - delete m_source; + delete m_source; } diff --git a/src/Nazara/Noise/HybridMultiFractal3D.cpp b/src/Nazara/Noise/HybridMultiFractal3D.cpp index 77df9e3d4..5c584da1f 100644 --- a/src/Nazara/Noise/HybridMultiFractal3D.cpp +++ b/src/Nazara/Noise/HybridMultiFractal3D.cpp @@ -11,54 +11,54 @@ NzHybridMultiFractal3D::NzHybridMultiFractal3D(nzNoises source, unsigned int seed) { - switch(source) - { - case PERLIN: - m_source = new NzPerlin3D(); - break; + switch(source) + { + case PERLIN: + m_source = new NzPerlin3D(); + break; - default: - m_source = new NzSimplex3D(); - break; - } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; + default: + m_source = new NzSimplex3D(); + break; + } + m_source->SetNewSeed(seed); + m_source->ShufflePermutationTable(); + m_noiseType = source; } float NzHybridMultiFractal3D::GetValue(float x, float y, float z, float resolution) { - this->RecomputeExponentArray(); + this->RecomputeExponentArray(); - m_offset = 1.0f; + m_offset = 1.0f; - m_value = (m_source->GetValue(x,y,z,resolution) + m_offset) * m_exponent_array[0]; - m_weight = m_value; - m_signal = 0.f; + m_value = (m_source->GetValue(x,y,z,resolution) + m_offset) * m_exponent_array[0]; + m_weight = m_value; + m_signal = 0.f; - resolution *= m_lacunarity; + resolution *= m_lacunarity; - for(int i(1) ; i < m_octaves; ++i) - { - if (m_weight > 1.f) - m_weight = 1.f; + for(int i(1) ; i < m_octaves; ++i) + { + if (m_weight > 1.f) + m_weight = 1.f; - m_signal = (m_source->GetValue(x,y,z,resolution) + m_offset) * m_exponent_array[i]; - m_value += m_weight * m_signal; + m_signal = (m_source->GetValue(x,y,z,resolution) + m_offset) * m_exponent_array[i]; + m_value += m_weight * m_signal; - m_weight *= m_signal; + m_weight *= m_signal; - resolution *= m_lacunarity; - } + resolution *= m_lacunarity; + } - m_remainder = m_octaves - static_cast(m_octaves); - if (m_remainder > 0.f) - m_value += m_remainder * m_source->GetValue(x,y,z,resolution) * m_exponent_array[static_cast(m_octaves-1)]; + m_remainder = m_octaves - static_cast(m_octaves); + if (m_remainder > 0.f) + m_value += m_remainder * m_source->GetValue(x,y,z,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - return m_value/this->m_sum - m_offset; + return m_value/this->m_sum - m_offset; } NzHybridMultiFractal3D::~NzHybridMultiFractal3D() { - delete m_source; + delete m_source; } diff --git a/src/Nazara/Noise/HybridMultiFractal4D.cpp b/src/Nazara/Noise/HybridMultiFractal4D.cpp index 7909d3c1e..d4f60066d 100644 --- a/src/Nazara/Noise/HybridMultiFractal4D.cpp +++ b/src/Nazara/Noise/HybridMultiFractal4D.cpp @@ -11,54 +11,54 @@ NzHybridMultiFractal4D::NzHybridMultiFractal4D(nzNoises source, unsigned int seed) { - switch(source) - { - case PERLIN: - m_source = new NzPerlin4D(); - break; + switch(source) + { + case PERLIN: + m_source = new NzPerlin4D(); + break; - default: - m_source = new NzSimplex4D(); - break; - } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; + default: + m_source = new NzSimplex4D(); + break; + } + m_source->SetNewSeed(seed); + m_source->ShufflePermutationTable(); + m_noiseType = source; } float NzHybridMultiFractal4D::GetValue(float x, float y, float z, float w, float resolution) { - this->RecomputeExponentArray(); + this->RecomputeExponentArray(); - m_offset = 1.0f; + m_offset = 1.0f; - m_value = (m_source->GetValue(x,y,z,w,resolution) + m_offset) * m_exponent_array[0]; - m_weight = m_value; - m_signal = 0.f; + m_value = (m_source->GetValue(x,y,z,w,resolution) + m_offset) * m_exponent_array[0]; + m_weight = m_value; + m_signal = 0.f; - resolution *= m_lacunarity; + resolution *= m_lacunarity; - for(int i(1) ; i < m_octaves; ++i) - { - if (m_weight > 1.f) - m_weight = 1.f; + for(int i(1) ; i < m_octaves; ++i) + { + if (m_weight > 1.f) + m_weight = 1.f; - m_signal = (m_source->GetValue(x,y,z,w,resolution) + m_offset) * m_exponent_array[i]; - m_value += m_weight * m_signal; + m_signal = (m_source->GetValue(x,y,z,w,resolution) + m_offset) * m_exponent_array[i]; + m_value += m_weight * m_signal; - m_weight *= m_signal; + m_weight *= m_signal; - resolution *= m_lacunarity; - } + resolution *= m_lacunarity; + } - m_remainder = m_octaves - static_cast(m_octaves); - if (m_remainder > 0.f) - m_value += m_remainder * m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[static_cast(m_octaves-1)]; + m_remainder = m_octaves - static_cast(m_octaves); + if (m_remainder > 0.f) + m_value += m_remainder * m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - return m_value/this->m_sum - m_offset; + return m_value/this->m_sum - m_offset; } NzHybridMultiFractal4D::~NzHybridMultiFractal4D() { - delete m_source; + delete m_source; } diff --git a/src/Nazara/Noise/HybridMultifractal2D.cpp b/src/Nazara/Noise/HybridMultifractal2D.cpp index 6721fd981..bfd016a5d 100644 --- a/src/Nazara/Noise/HybridMultifractal2D.cpp +++ b/src/Nazara/Noise/HybridMultifractal2D.cpp @@ -11,54 +11,54 @@ NzHybridMultiFractal2D::NzHybridMultiFractal2D(nzNoises source, unsigned int seed) { - switch(source) - { - case PERLIN: - m_source = new NzPerlin2D(); - break; + switch(source) + { + case PERLIN: + m_source = new NzPerlin2D(); + break; - default: - m_source = new NzSimplex2D(); - break; - } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; + default: + m_source = new NzSimplex2D(); + break; + } + m_source->SetNewSeed(seed); + m_source->ShufflePermutationTable(); + m_noiseType = source; } float NzHybridMultiFractal2D::GetValue(float x, float y, float resolution) { - this->RecomputeExponentArray(); + this->RecomputeExponentArray(); - m_offset = 1.0f; + m_offset = 1.0f; - m_value = (m_source->GetValue(x,y,resolution) + m_offset) * m_exponent_array[0]; - m_weight = m_value; - m_signal = 0.f; + m_value = (m_source->GetValue(x,y,resolution) + m_offset) * m_exponent_array[0]; + m_weight = m_value; + m_signal = 0.f; - resolution *= m_lacunarity; + resolution *= m_lacunarity; - for(int i(1) ; i < m_octaves; ++i) - { - if (m_weight > 1.f) - m_weight = 1.f; + for(int i(1) ; i < m_octaves; ++i) + { + if (m_weight > 1.f) + m_weight = 1.f; - m_signal = (m_source->GetValue(x,y,resolution) + m_offset) * m_exponent_array[i]; - m_value += m_weight * m_signal; + m_signal = (m_source->GetValue(x,y,resolution) + m_offset) * m_exponent_array[i]; + m_value += m_weight * m_signal; - m_weight *= m_signal; + m_weight *= m_signal; - resolution *= m_lacunarity; - } + resolution *= m_lacunarity; + } - m_remainder = m_octaves - static_cast(m_octaves); - if (m_remainder > 0.f) - m_value += m_remainder * m_source->GetValue(x,y,resolution) * m_exponent_array[static_cast(m_octaves-1)]; + m_remainder = m_octaves - static_cast(m_octaves); + if (m_remainder > 0.f) + m_value += m_remainder * m_source->GetValue(x,y,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - return m_value/this->m_sum - m_offset; + return m_value/this->m_sum - m_offset; } NzHybridMultiFractal2D::~NzHybridMultiFractal2D() { - delete m_source; + delete m_source; } diff --git a/src/Nazara/Noise/MappedNoiseBase.cpp b/src/Nazara/Noise/MappedNoiseBase.cpp index 27b8ece40..7b520ae87 100644 --- a/src/Nazara/Noise/MappedNoiseBase.cpp +++ b/src/Nazara/Noise/MappedNoiseBase.cpp @@ -17,37 +17,37 @@ NzMappedNoiseBase::NzMappedNoiseBase() : m_gain(1.f), m_offset(0.f), m_resolutio float NzMappedNoiseBase::GetGain() const { - return m_gain; + return m_gain; } float NzMappedNoiseBase::GetOffset() const { - return m_offset; + return m_offset; } float NzMappedNoiseBase::GetResolution() const { - return m_resolution; + return m_resolution; } void NzMappedNoiseBase::SetGain(float gain) { - m_gain = gain; + m_gain = gain; } void NzMappedNoiseBase::SetOffset(float offset) { - m_offset = offset; + m_offset = offset; } void NzMappedNoiseBase::SetResolution(float resolution) { - if (NzNumberEquals(resolution, 0.f)) + if (NzNumberEquals(resolution, 0.f)) { NzStringStream ss; ss << __FILE__ << ':' << __LINE__ << " : resolution cannot be 0.0f"; throw std::domain_error(ss.ToString()); } - m_resolution = resolution; + m_resolution = resolution; } diff --git a/src/Nazara/Noise/NoiseBase.cpp b/src/Nazara/Noise/NoiseBase.cpp index d394b7f9c..007ffa376 100644 --- a/src/Nazara/Noise/NoiseBase.cpp +++ b/src/Nazara/Noise/NoiseBase.cpp @@ -9,68 +9,68 @@ NzNoiseBase::NzNoiseBase(unsigned int seed) { - Ua = 16807; - Uc = 0; - Um = 2147483647; - UcurrentSeed = 0; - Uprevious = 0; + Ua = 16807; + Uc = 0; + Um = 2147483647; + UcurrentSeed = 0; + Uprevious = 0; - SetNewSeed(seed); + SetNewSeed(seed); - for(int i(0) ; i < 512 ; i++) - perm[i] = i & 255; + for(int i(0) ; i < 512 ; i++) + perm[i] = i & 255; } void NzNoiseBase::SetNewSeed(unsigned int seed) { - Uprevious = seed; - UcurrentSeed = seed; + Uprevious = seed; + UcurrentSeed = seed; } unsigned int NzNoiseBase::GetUniformRandomValue() { - Ulast = Ua*Uprevious + Uc%Um; - Uprevious = Ulast; - return Ulast; + Ulast = Ua*Uprevious + Uc%Um; + Uprevious = Ulast; + return Ulast; } void NzNoiseBase::ShufflePermutationTable() { - int xchanger; - unsigned int ncase; + int xchanger; + unsigned int ncase; - for(unsigned int i(0) ; i < 256 ; i++) - perm[i] = i; + for(unsigned int i(0) ; i < 256 ; i++) + perm[i] = i; - for(unsigned int j(0) ; j < 20 ; ++j) - for (unsigned int i(0); i < 256 ; ++i) - { - ncase = this->GetUniformRandomValue() & 255; - xchanger = perm[i]; - perm[i] = perm[ncase]; - perm[ncase] = xchanger; - } + for(unsigned int j(0) ; j < 20 ; ++j) + for (unsigned int i(0); i < 256 ; ++i) + { + ncase = this->GetUniformRandomValue() & 255; + xchanger = perm[i]; + perm[i] = perm[ncase]; + perm[ncase] = xchanger; + } - for(unsigned int i(256) ; i < 512; ++i) - perm[i] = perm[i & 255]; + for(unsigned int i(256) ; i < 512; ++i) + perm[i] = perm[i & 255]; } int NzNoiseBase::fastfloor(float n) { - return (n >= 0) ? static_cast(n) : static_cast(n-1); + return (n >= 0) ? static_cast(n) : static_cast(n-1); } int NzNoiseBase::JenkinsHash(int a, int b, int c) { - a = a-b; a = a - c; a = a^(static_cast(c) >> 13); - b = b-c; b = b - a; b = b^(a << 8); - c = c-a; c = c - b; c = c^(static_cast(b) >> 13); - a = a-b; a = a - c; a = a^(static_cast(c) >> 12); - b = b-c; b = b - a; b = b^(a << 16); - c = c-a; c = c - b; c = c^(static_cast(b) >> 5); - a = a-b; a = a - c; a = a^(static_cast(c) >> 3); - b = b-c; b = b - a; b = b^(a << 10); - c = c-a; c = c - b; c = c^(static_cast(b) >> 15); - return c; + a = a-b; a = a - c; a = a^(static_cast(c) >> 13); + b = b-c; b = b - a; b = b^(a << 8); + c = c-a; c = c - b; c = c^(static_cast(b) >> 13); + a = a-b; a = a - c; a = a^(static_cast(c) >> 12); + b = b-c; b = b - a; b = b^(a << 16); + c = c-a; c = c - b; c = c^(static_cast(b) >> 5); + a = a-b; a = a - c; a = a^(static_cast(c) >> 3); + b = b-c; b = b - a; b = b^(a << 10); + c = c-a; c = c - b; c = c^(static_cast(b) >> 15); + return c; } diff --git a/src/Nazara/Noise/Perlin2D.cpp b/src/Nazara/Noise/Perlin2D.cpp index 4622016d0..02a6e58cb 100644 --- a/src/Nazara/Noise/Perlin2D.cpp +++ b/src/Nazara/Noise/Perlin2D.cpp @@ -9,7 +9,7 @@ NzPerlin2D::NzPerlin2D() { - float grad2Temp[][2] = { + float grad2Temp[][2] = { {1.f,1.f}, {-1.f,1.f}, {1.f,-1.f}, @@ -21,52 +21,52 @@ NzPerlin2D::NzPerlin2D() {0.f,-1.f} }; - for(int i(0) ; i < 8 ; ++i) - for(int j(0) ; j < 2 ; ++j) - gradient2[i][j] = grad2Temp[i][j]; + for(int i(0) ; i < 8 ; ++i) + for(int j(0) ; j < 2 ; ++j) + gradient2[i][j] = grad2Temp[i][j]; } NzPerlin2D::NzPerlin2D(unsigned int seed) : NzPerlin2D() { - this->SetNewSeed(seed); - this->ShufflePermutationTable(); + this->SetNewSeed(seed); + this->ShufflePermutationTable(); } float NzPerlin2D::GetValue(float x, float y, float resolution) { - x *= resolution; - y *= resolution; + x *= resolution; + y *= resolution; - x0 = fastfloor(x); - y0 = fastfloor(y); + x0 = fastfloor(x); + y0 = fastfloor(y); - ii = x0 & 255; - jj = y0 & 255; + ii = x0 & 255; + jj = y0 & 255; - gi0 = perm[ii + perm[jj]] & 7; - gi1 = perm[ii + 1 + perm[jj]] & 7; - gi2 = perm[ii + perm[jj + 1]] & 7; - gi3 = perm[ii + 1 + perm[jj + 1]] & 7; + gi0 = perm[ii + perm[jj]] & 7; + gi1 = perm[ii + 1 + perm[jj]] & 7; + gi2 = perm[ii + perm[jj + 1]] & 7; + gi3 = perm[ii + 1 + perm[jj + 1]] & 7; - temp.x = x-x0; - temp.y = y-y0; + temp.x = x-x0; + temp.y = y-y0; - Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); - Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); + Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); + Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); - s = gradient2[gi0][0]*temp.x + gradient2[gi0][1]*temp.y; + s = gradient2[gi0][0]*temp.x + gradient2[gi0][1]*temp.y; - temp.x = x-(x0+1); - t = gradient2[gi1][0]*temp.x + gradient2[gi1][1]*temp.y; + temp.x = x-(x0+1); + t = gradient2[gi1][0]*temp.x + gradient2[gi1][1]*temp.y; - temp.y = y-(y0+1); - v = gradient2[gi3][0]*temp.x + gradient2[gi3][1]*temp.y; + temp.y = y-(y0+1); + v = gradient2[gi3][0]*temp.x + gradient2[gi3][1]*temp.y; - temp.x = x-x0; - u = gradient2[gi2][0]*temp.x + gradient2[gi2][1]*temp.y; + temp.x = x-x0; + u = gradient2[gi2][0]*temp.x + gradient2[gi2][1]*temp.y; - Li1 = s + Cx*(t-s); - Li2 = u + Cx*(v-u); + Li1 = s + Cx*(t-s); + Li2 = u + Cx*(v-u); - return Li1 + Cy*(Li2-Li1); + return Li1 + Cy*(Li2-Li1); } diff --git a/src/Nazara/Noise/Perlin3D.cpp b/src/Nazara/Noise/Perlin3D.cpp index 87d79622b..472707814 100644 --- a/src/Nazara/Noise/Perlin3D.cpp +++ b/src/Nazara/Noise/Perlin3D.cpp @@ -9,87 +9,87 @@ NzPerlin3D::NzPerlin3D() { - float grad3Temp[][3] = { - {1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0}, - {1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1}, - {0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}, - {1,1,0},{-1,1,0},{0,-1,1},{0,-1,-1} - }; + float grad3Temp[][3] = { + {1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0}, + {1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1}, + {0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}, + {1,1,0},{-1,1,0},{0,-1,1},{0,-1,-1} + }; - for(int i(0) ; i < 16 ; ++i) - for(int j(0) ; j < 3 ; ++j) - gradient3[i][j] = grad3Temp[i][j]; + for(int i(0) ; i < 16 ; ++i) + for(int j(0) ; j < 3 ; ++j) + gradient3[i][j] = grad3Temp[i][j]; } NzPerlin3D::NzPerlin3D(unsigned int seed) : NzPerlin3D() { - this->SetNewSeed(seed); - this->ShufflePermutationTable(); + this->SetNewSeed(seed); + this->ShufflePermutationTable(); } float NzPerlin3D::GetValue(float x, float y, float z, float resolution) { - x /= resolution; - y /= resolution; - z /= resolution; + x /= resolution; + y /= resolution; + z /= resolution; - x0 = fastfloor(x); - y0 = fastfloor(y); - z0 = fastfloor(z); + x0 = fastfloor(x); + y0 = fastfloor(y); + z0 = fastfloor(z); - ii = x0 & 255; - jj = y0 & 255; - kk = z0 & 255; + ii = x0 & 255; + jj = y0 & 255; + kk = z0 & 255; - gi0 = perm[ii + perm[jj + perm[kk]]] & 15; - gi1 = perm[ii + 1 + perm[jj + perm[kk]]] & 15; - gi2 = perm[ii + perm[jj + 1 + perm[kk]]] & 15; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk]]] & 15; + gi0 = perm[ii + perm[jj + perm[kk]]] & 15; + gi1 = perm[ii + 1 + perm[jj + perm[kk]]] & 15; + gi2 = perm[ii + perm[jj + 1 + perm[kk]]] & 15; + gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk]]] & 15; - gi4 = perm[ii + perm[jj + perm[kk + 1]]] & 15; - gi5 = perm[ii + 1 + perm[jj + perm[kk + 1]]] & 15; - gi6 = perm[ii + perm[jj + 1 + perm[kk + 1]]] & 15; - gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] & 15; + gi4 = perm[ii + perm[jj + perm[kk + 1]]] & 15; + gi5 = perm[ii + 1 + perm[jj + perm[kk + 1]]] & 15; + gi6 = perm[ii + perm[jj + 1 + perm[kk + 1]]] & 15; + gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] & 15; - temp.x = x-x0; - temp.y = y-y0; - temp.z = z-z0; + temp.x = x-x0; + temp.y = y-y0; + temp.z = z-z0; - Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); - Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); - Cz = temp.z * temp.z * temp.z * (temp.z * (temp.z * 6 - 15) + 10); + Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); + Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); + Cz = temp.z * temp.z * temp.z * (temp.z * (temp.z * 6 - 15) + 10); - s[0] = gradient3[gi0][0]*temp.x + gradient3[gi0][1]*temp.y + gradient3[gi0][2]*temp.z; + s[0] = gradient3[gi0][0]*temp.x + gradient3[gi0][1]*temp.y + gradient3[gi0][2]*temp.z; - temp.x = x-(x0+1); - t[0] = gradient3[gi1][0]*temp.x + gradient3[gi1][1]*temp.y + gradient3[gi1][2]*temp.z; + temp.x = x-(x0+1); + t[0] = gradient3[gi1][0]*temp.x + gradient3[gi1][1]*temp.y + gradient3[gi1][2]*temp.z; - temp.y = y-(y0+1); - v[0] = gradient3[gi3][0]*temp.x + gradient3[gi3][1]*temp.y + gradient3[gi3][2]*temp.z; + temp.y = y-(y0+1); + v[0] = gradient3[gi3][0]*temp.x + gradient3[gi3][1]*temp.y + gradient3[gi3][2]*temp.z; - temp.x = x-x0; - u[0] = gradient3[gi2][0]*temp.x + gradient3[gi2][1]*temp.y + gradient3[gi2][2]*temp.z; + temp.x = x-x0; + u[0] = gradient3[gi2][0]*temp.x + gradient3[gi2][1]*temp.y + gradient3[gi2][2]*temp.z; - temp.y = y-y0; - temp.z = z-(z0+1); - s[1] = gradient3[gi4][0]*temp.x + gradient3[gi4][1]*temp.y + gradient3[gi4][2]*temp.z; + temp.y = y-y0; + temp.z = z-(z0+1); + s[1] = gradient3[gi4][0]*temp.x + gradient3[gi4][1]*temp.y + gradient3[gi4][2]*temp.z; - temp.x = x-(x0+1); - t[1] = gradient3[gi5][0]*temp.x + gradient3[gi5][1]*temp.y + gradient3[gi5][2]*temp.z; + temp.x = x-(x0+1); + t[1] = gradient3[gi5][0]*temp.x + gradient3[gi5][1]*temp.y + gradient3[gi5][2]*temp.z; - temp.y = y-(y0+1); - v[1] = gradient3[gi7][0]*temp.x + gradient3[gi7][1]*temp.y + gradient3[gi7][2]*temp.z; + temp.y = y-(y0+1); + v[1] = gradient3[gi7][0]*temp.x + gradient3[gi7][1]*temp.y + gradient3[gi7][2]*temp.z; - temp.x = x-x0; - u[1] = gradient3[gi6][0]*temp.x + gradient3[gi6][1]*temp.y + gradient3[gi6][2]*temp.z; + temp.x = x-x0; + u[1] = gradient3[gi6][0]*temp.x + gradient3[gi6][1]*temp.y + gradient3[gi6][2]*temp.z; - Li1 = s[0] + Cx*(t[0]-s[0]); - Li2 = u[0] + Cx*(v[0]-u[0]); - Li3 = s[1] + Cx*(t[1]-s[1]); - Li4 = u[1] + Cx*(v[1]-u[1]); + Li1 = s[0] + Cx*(t[0]-s[0]); + Li2 = u[0] + Cx*(v[0]-u[0]); + Li3 = s[1] + Cx*(t[1]-s[1]); + Li4 = u[1] + Cx*(v[1]-u[1]); - Li5 = Li1 + Cy*(Li2-Li1); - Li6 = Li3 + Cy*(Li4-Li3); + Li5 = Li1 + Cy*(Li2-Li1); + Li6 = Li3 + Cy*(Li4-Li3); - return Li5 + Cz*(Li6-Li5); + return Li5 + Cz*(Li6-Li5); } diff --git a/src/Nazara/Noise/Perlin4D.cpp b/src/Nazara/Noise/Perlin4D.cpp index 1c49c40f8..4c2cb9051 100644 --- a/src/Nazara/Noise/Perlin4D.cpp +++ b/src/Nazara/Noise/Perlin4D.cpp @@ -9,145 +9,145 @@ NzPerlin4D::NzPerlin4D() { - float grad4Temp[][4] = - { - {0,1,1,1}, {0,1,1,-1}, {0,1,-1,1}, {0,1,-1,-1}, - {0,-1,1,1},{0,-1,1,-1},{0,-1,-1,1},{0,-1,-1,-1}, - {1,0,1,1}, {1,0,1,-1}, {1,0,-1,1}, {1,0,-1,-1}, - {-1,0,1,1},{-1,0,1,-1},{-1,0,-1,1},{-1,0,-1,-1}, - {1,1,0,1}, {1,1,0,-1}, {1,-1,0,1}, {1,-1,0,-1}, - {-1,1,0,1},{-1,1,0,-1},{-1,-1,0,1},{-1,-1,0,-1}, - {1,1,1,0}, {1,1,-1,0}, {1,-1,1,0}, {1,-1,-1,0}, - {-1,1,1,0},{-1,1,-1,0},{-1,-1,1,0},{-1,-1,-1,0} - }; + float grad4Temp[][4] = + { + {0,1,1,1}, {0,1,1,-1}, {0,1,-1,1}, {0,1,-1,-1}, + {0,-1,1,1},{0,-1,1,-1},{0,-1,-1,1},{0,-1,-1,-1}, + {1,0,1,1}, {1,0,1,-1}, {1,0,-1,1}, {1,0,-1,-1}, + {-1,0,1,1},{-1,0,1,-1},{-1,0,-1,1},{-1,0,-1,-1}, + {1,1,0,1}, {1,1,0,-1}, {1,-1,0,1}, {1,-1,0,-1}, + {-1,1,0,1},{-1,1,0,-1},{-1,-1,0,1},{-1,-1,0,-1}, + {1,1,1,0}, {1,1,-1,0}, {1,-1,1,0}, {1,-1,-1,0}, + {-1,1,1,0},{-1,1,-1,0},{-1,-1,1,0},{-1,-1,-1,0} + }; - for(int i(0) ; i < 32 ; ++i) - for(int j(0) ; j < 4 ; ++j) - gradient4[i][j] = grad4Temp[i][j]; + for(int i(0) ; i < 32 ; ++i) + for(int j(0) ; j < 4 ; ++j) + gradient4[i][j] = grad4Temp[i][j]; } NzPerlin4D::NzPerlin4D(unsigned int seed) : NzPerlin4D() { - this->SetNewSeed(seed); - this->ShufflePermutationTable(); + this->SetNewSeed(seed); + this->ShufflePermutationTable(); } float NzPerlin4D::GetValue(float x, float y, float z, float w, float resolution) { - x *= resolution; - y *= resolution; - z *= resolution; - w *= resolution; + x *= resolution; + y *= resolution; + z *= resolution; + w *= resolution; - x0 = fastfloor(x); - y0 = fastfloor(y); - z0 = fastfloor(z); - w0 = fastfloor(w); + x0 = fastfloor(x); + y0 = fastfloor(y); + z0 = fastfloor(z); + w0 = fastfloor(w); - ii = x0 & 255; - jj = y0 & 255; - kk = z0 & 255; - ll = w0 & 255; + ii = x0 & 255; + jj = y0 & 255; + kk = z0 & 255; + ll = w0 & 255; - gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] & 31; - gi1 = perm[ii + 1 + perm[jj + perm[kk + perm[ll]]]] & 31; - gi2 = perm[ii + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; + gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] & 31; + gi1 = perm[ii + 1 + perm[jj + perm[kk + perm[ll]]]] & 31; + gi2 = perm[ii + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; + gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; - gi4 = perm[ii + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; - gi5 = perm[ii + 1 + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; - gi6 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; - gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; + gi4 = perm[ii + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; + gi5 = perm[ii + 1 + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; + gi6 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; + gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; - gi8 = perm[ii + perm[jj + perm[kk + perm[ll + 1]]]] & 31; - gi9 = perm[ii + 1 + perm[jj + perm[kk + perm[ll + 1]]]] & 31; - gi10 = perm[ii + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; - gi11 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; + gi8 = perm[ii + perm[jj + perm[kk + perm[ll + 1]]]] & 31; + gi9 = perm[ii + 1 + perm[jj + perm[kk + perm[ll + 1]]]] & 31; + gi10 = perm[ii + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; + gi11 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; - gi12 = perm[ii + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi13 = perm[ii + 1 + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi14 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi15 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; + gi12 = perm[ii + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; + gi13 = perm[ii + 1 + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; + gi14 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; + gi15 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; - temp.x = x-x0; - temp.y = y-y0; - temp.z = z-z0; - temp.w = w-w0; + temp.x = x-x0; + temp.y = y-y0; + temp.z = z-z0; + temp.w = w-w0; - Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); - Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); - Cz = temp.z * temp.z * temp.z * (temp.z * (temp.z * 6 - 15) + 10); - Cw = temp.w * temp.w * temp.w * (temp.w * (temp.w * 6 - 15) + 10); + Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); + Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); + Cz = temp.z * temp.z * temp.z * (temp.z * (temp.z * 6 - 15) + 10); + Cw = temp.w * temp.w * temp.w * (temp.w * (temp.w * 6 - 15) + 10); - s[0] = gradient4[gi0][0]*temp.x + gradient4[gi0][1]*temp.y + gradient4[gi0][2]*temp.z + gradient4[gi0][3]*temp.w; + s[0] = gradient4[gi0][0]*temp.x + gradient4[gi0][1]*temp.y + gradient4[gi0][2]*temp.z + gradient4[gi0][3]*temp.w; - temp.x = x-(x0+1); - t[0] = gradient4[gi1][0]*temp.x + gradient4[gi1][1]*temp.y + gradient4[gi1][2]*temp.z + gradient4[gi1][3]*temp.w; + temp.x = x-(x0+1); + t[0] = gradient4[gi1][0]*temp.x + gradient4[gi1][1]*temp.y + gradient4[gi1][2]*temp.z + gradient4[gi1][3]*temp.w; - temp.y = y-(y0+1); - v[0] = gradient4[gi3][0]*temp.x + gradient4[gi3][1]*temp.y + gradient4[gi3][2]*temp.z + gradient4[gi3][3]*temp.w; + temp.y = y-(y0+1); + v[0] = gradient4[gi3][0]*temp.x + gradient4[gi3][1]*temp.y + gradient4[gi3][2]*temp.z + gradient4[gi3][3]*temp.w; - temp.x = x-x0; - u[0] = gradient4[gi2][0]*temp.x + gradient4[gi2][1]*temp.y + gradient4[gi2][2]*temp.z + gradient4[gi2][3]*temp.w; + temp.x = x-x0; + u[0] = gradient4[gi2][0]*temp.x + gradient4[gi2][1]*temp.y + gradient4[gi2][2]*temp.z + gradient4[gi2][3]*temp.w; - temp.y = y-y0; - temp.z = z-(z0+1); - s[1] = gradient4[gi4][0]*temp.x + gradient4[gi4][1]*temp.y + gradient4[gi4][2]*temp.z + gradient4[gi4][3]*temp.w; + temp.y = y-y0; + temp.z = z-(z0+1); + s[1] = gradient4[gi4][0]*temp.x + gradient4[gi4][1]*temp.y + gradient4[gi4][2]*temp.z + gradient4[gi4][3]*temp.w; - temp.x = x-(x0+1); - t[1] = gradient4[gi5][0]*temp.x + gradient4[gi5][1]*temp.y + gradient4[gi5][2]*temp.z + gradient4[gi5][3]*temp.w; + temp.x = x-(x0+1); + t[1] = gradient4[gi5][0]*temp.x + gradient4[gi5][1]*temp.y + gradient4[gi5][2]*temp.z + gradient4[gi5][3]*temp.w; - temp.y = y-(y0+1); - v[1] = gradient4[gi7][0]*temp.x + gradient4[gi7][1]*temp.y + gradient4[gi7][2]*temp.z + gradient4[gi7][3]*temp.w; + temp.y = y-(y0+1); + v[1] = gradient4[gi7][0]*temp.x + gradient4[gi7][1]*temp.y + gradient4[gi7][2]*temp.z + gradient4[gi7][3]*temp.w; - temp.x = x-x0; - u[1] = gradient4[gi6][0]*temp.x + gradient4[gi6][1]*temp.y + gradient4[gi6][2]*temp.z + gradient4[gi6][3]*temp.w; + temp.x = x-x0; + u[1] = gradient4[gi6][0]*temp.x + gradient4[gi6][1]*temp.y + gradient4[gi6][2]*temp.z + gradient4[gi6][3]*temp.w; - temp.y = y-y0; - temp.z = z-z0; - temp.w = w-(w0+1); - s[2] = gradient4[gi8][0]*temp.x + gradient4[gi8][1]*temp.y + gradient4[gi8][2]*temp.z + gradient4[gi8][3]*temp.w; + temp.y = y-y0; + temp.z = z-z0; + temp.w = w-(w0+1); + s[2] = gradient4[gi8][0]*temp.x + gradient4[gi8][1]*temp.y + gradient4[gi8][2]*temp.z + gradient4[gi8][3]*temp.w; - temp.x = x-(x0+1); - t[2] = gradient4[gi9][0]*temp.x + gradient4[gi9][1]*temp.y + gradient4[gi9][2]*temp.z + gradient4[gi9][3]*temp.w; + temp.x = x-(x0+1); + t[2] = gradient4[gi9][0]*temp.x + gradient4[gi9][1]*temp.y + gradient4[gi9][2]*temp.z + gradient4[gi9][3]*temp.w; - temp.y = y-(y0+1); - v[2] = gradient4[gi11][0]*temp.x + gradient4[gi11][1]*temp.y + gradient4[gi11][2]*temp.z + gradient4[gi11][3]*temp.w; + temp.y = y-(y0+1); + v[2] = gradient4[gi11][0]*temp.x + gradient4[gi11][1]*temp.y + gradient4[gi11][2]*temp.z + gradient4[gi11][3]*temp.w; - temp.x = x-x0; - u[2] = gradient4[gi10][0]*temp.x + gradient4[gi10][1]*temp.y + gradient4[gi10][2]*temp.z + gradient4[gi10][3]*temp.w; + temp.x = x-x0; + u[2] = gradient4[gi10][0]*temp.x + gradient4[gi10][1]*temp.y + gradient4[gi10][2]*temp.z + gradient4[gi10][3]*temp.w; - temp.y = y-y0; - temp.z = z-(z0+1); - s[3] = gradient4[gi12][0]*temp.x + gradient4[gi12][1]*temp.y + gradient4[gi12][2]*temp.z + gradient4[gi12][3]*temp.w; + temp.y = y-y0; + temp.z = z-(z0+1); + s[3] = gradient4[gi12][0]*temp.x + gradient4[gi12][1]*temp.y + gradient4[gi12][2]*temp.z + gradient4[gi12][3]*temp.w; - temp.x = x-(x0+1); - t[3] = gradient4[gi13][0]*temp.x + gradient4[gi13][1]*temp.y + gradient4[gi13][2]*temp.z + gradient4[gi13][3]*temp.w; + temp.x = x-(x0+1); + t[3] = gradient4[gi13][0]*temp.x + gradient4[gi13][1]*temp.y + gradient4[gi13][2]*temp.z + gradient4[gi13][3]*temp.w; - temp.y = y-(y0+1); - v[3] = gradient4[gi15][0]*temp.x + gradient4[gi15][1]*temp.y + gradient4[gi15][2]*temp.z + gradient4[gi15][3]*temp.w; + temp.y = y-(y0+1); + v[3] = gradient4[gi15][0]*temp.x + gradient4[gi15][1]*temp.y + gradient4[gi15][2]*temp.z + gradient4[gi15][3]*temp.w; - temp.x = x-x0; - u[3] = gradient4[gi14][0]*temp.x + gradient4[gi14][1]*temp.y + gradient4[gi14][2]*temp.z + gradient4[gi14][3]*temp.w; + temp.x = x-x0; + u[3] = gradient4[gi14][0]*temp.x + gradient4[gi14][1]*temp.y + gradient4[gi14][2]*temp.z + gradient4[gi14][3]*temp.w; - Li1 = s[0] + Cx*(t[0]-s[0]); - Li2 = u[0] + Cx*(v[0]-u[0]); - Li3 = s[1] + Cx*(t[1]-s[1]); - Li4 = u[1] + Cx*(v[1]-u[1]); - Li5 = s[2] + Cx*(t[2]-s[2]); - Li6 = u[2] + Cx*(v[2]-u[2]); - Li7 = s[3] + Cx*(t[3]-s[3]); - Li8 = u[3] + Cx*(v[3]-u[3]); + Li1 = s[0] + Cx*(t[0]-s[0]); + Li2 = u[0] + Cx*(v[0]-u[0]); + Li3 = s[1] + Cx*(t[1]-s[1]); + Li4 = u[1] + Cx*(v[1]-u[1]); + Li5 = s[2] + Cx*(t[2]-s[2]); + Li6 = u[2] + Cx*(v[2]-u[2]); + Li7 = s[3] + Cx*(t[3]-s[3]); + Li8 = u[3] + Cx*(v[3]-u[3]); - Li9 = Li1 + Cy*(Li2-Li1); - Li10 = Li3 + Cy*(Li4-Li3); - Li11 = Li5 + Cy*(Li6-Li5); - Li12 = Li7 + Cy*(Li8-Li7); + Li9 = Li1 + Cy*(Li2-Li1); + Li10 = Li3 + Cy*(Li4-Li3); + Li11 = Li5 + Cy*(Li6-Li5); + Li12 = Li7 + Cy*(Li8-Li7); - Li13 = Li9 + Cz*(Li10-Li9); - Li14 = Li11 + Cz*(Li12-Li11); + Li13 = Li9 + Cz*(Li10-Li9); + Li14 = Li11 + Cz*(Li12-Li11); - return Li13 + Cw*(Li14-Li13); + return Li13 + Cw*(Li14-Li13); } diff --git a/src/Nazara/Noise/Simplex2D.cpp b/src/Nazara/Noise/Simplex2D.cpp index 78f9ceb43..c94e82977 100644 --- a/src/Nazara/Noise/Simplex2D.cpp +++ b/src/Nazara/Noise/Simplex2D.cpp @@ -9,83 +9,83 @@ NzSimplex2D::NzSimplex2D() { - float grad2Temp[][2] = {{1,1},{-1,1},{1,-1},{-1,-1}, - {1,0},{-1,0},{0,1},{0,-1}}; + float grad2Temp[][2] = {{1,1},{-1,1},{1,-1},{-1,-1}, + {1,0},{-1,0},{0,1},{0,-1}}; - for(int i(0) ; i < 8 ; ++i) - for(int j(0) ; j < 2 ; ++j) - gradient2[i][j] = grad2Temp[i][j]; + for(int i(0) ; i < 8 ; ++i) + for(int j(0) ; j < 2 ; ++j) + gradient2[i][j] = grad2Temp[i][j]; - SkewCoeff2D = 0.5f*(std::sqrt(3.f) - 1.f); - UnskewCoeff2D = (3.f-std::sqrt(3.f))/6.f; + SkewCoeff2D = 0.5f*(std::sqrt(3.f) - 1.f); + UnskewCoeff2D = (3.f-std::sqrt(3.f))/6.f; } NzSimplex2D::NzSimplex2D(unsigned int seed) : NzSimplex2D() { - this->SetNewSeed(seed); - this->ShufflePermutationTable(); + this->SetNewSeed(seed); + this->ShufflePermutationTable(); } float NzSimplex2D::GetValue(float x, float y, float resolution) { - x *= resolution; - y *= resolution; + x *= resolution; + y *= resolution; - sum = (x + y) * SkewCoeff2D; - skewedCubeOrigin.x = fastfloor(x + sum); - skewedCubeOrigin.y = fastfloor(y + sum); + sum = (x + y) * SkewCoeff2D; + skewedCubeOrigin.x = fastfloor(x + sum); + skewedCubeOrigin.y = fastfloor(y + sum); - sum = (skewedCubeOrigin.x + skewedCubeOrigin.y) * UnskewCoeff2D; - unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; - unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; + sum = (skewedCubeOrigin.x + skewedCubeOrigin.y) * UnskewCoeff2D; + unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; + unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; - unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; - unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; + unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; + unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; - if(unskewedDistToOrigin.x > unskewedDistToOrigin.y) - { - off1.x = 1; - off1.y = 0; - } - else - { - off1.x = 0; - off1.y = 1; - } + if(unskewedDistToOrigin.x > unskewedDistToOrigin.y) + { + off1.x = 1; + off1.y = 0; + } + else + { + off1.x = 0; + off1.y = 1; + } - d1 = - unskewedDistToOrigin; + d1 = - unskewedDistToOrigin; - d2.x = d1.x + off1.x - UnskewCoeff2D; - d2.y = d1.y + off1.y - UnskewCoeff2D; + d2.x = d1.x + off1.x - UnskewCoeff2D; + d2.y = d1.y + off1.y - UnskewCoeff2D; - d3.x = d1.x + 1.f - 2.f * UnskewCoeff2D; - d3.y = d1.y + 1.f - 2.f * UnskewCoeff2D; + d3.x = d1.x + 1.f - 2.f * UnskewCoeff2D; + d3.y = d1.y + 1.f - 2.f * UnskewCoeff2D; - ii = skewedCubeOrigin.x & 255; - jj = skewedCubeOrigin.y & 255; + ii = skewedCubeOrigin.x & 255; + jj = skewedCubeOrigin.y & 255; - gi0 = perm[ii + perm[jj ]] & 7; - gi1 = perm[ii + off1.x + perm[jj + off1.y]] & 7; - gi2 = perm[ii + 1 + perm[jj + 1 ]] & 7; + gi0 = perm[ii + perm[jj ]] & 7; + gi1 = perm[ii + off1.x + perm[jj + off1.y]] & 7; + gi2 = perm[ii + 1 + perm[jj + 1 ]] & 7; - c1 = 0.5f - d1.x * d1.x - d1.y * d1.y; - c2 = 0.5f - d2.x * d2.x - d2.y * d2.y; - c3 = 0.5f - d3.x * d3.x - d3.y * d3.y; + c1 = 0.5f - d1.x * d1.x - d1.y * d1.y; + c2 = 0.5f - d2.x * d2.x - d2.y * d2.y; + c3 = 0.5f - d3.x * d3.x - d3.y * d3.y; - if(c1 < 0) - n1 = 0; - else - n1 = c1*c1*c1*c1*(gradient2[gi0][0] * d1.x + gradient2[gi0][1] * d1.y); + if(c1 < 0) + n1 = 0; + else + n1 = c1*c1*c1*c1*(gradient2[gi0][0] * d1.x + gradient2[gi0][1] * d1.y); - if(c2 < 0) - n2 = 0; - else - n2 = c2*c2*c2*c2*(gradient2[gi1][0] * d2.x + gradient2[gi1][1] * d2.y); + if(c2 < 0) + n2 = 0; + else + n2 = c2*c2*c2*c2*(gradient2[gi1][0] * d2.x + gradient2[gi1][1] * d2.y); - if(c3 < 0) - n3 = 0; - else - n3 = c3*c3*c3*c3*(gradient2[gi2][0] * d3.x + gradient2[gi2][1] * d3.y); + if(c3 < 0) + n3 = 0; + else + n3 = c3*c3*c3*c3*(gradient2[gi2][0] * d3.x + gradient2[gi2][1] * d3.y); - return (n1+n2+n3)*70.f; + return (n1+n2+n3)*70.f; } diff --git a/src/Nazara/Noise/Simplex3D.cpp b/src/Nazara/Noise/Simplex3D.cpp index 9a6138cff..1907af576 100644 --- a/src/Nazara/Noise/Simplex3D.cpp +++ b/src/Nazara/Noise/Simplex3D.cpp @@ -9,10 +9,10 @@ NzSimplex3D::NzSimplex3D() { - SkewCoeff3D = 1/3.f; - UnskewCoeff3D = 1/6.f; + SkewCoeff3D = 1/3.f; + UnskewCoeff3D = 1/6.f; - float grad3Temp[][3] = { + float grad3Temp[][3] = { {1.f,1.f,0.f}, {-1.f,1.f,0.f}, {1.f,-1.f,0.f}, @@ -29,145 +29,145 @@ NzSimplex3D::NzSimplex3D() {0.f,-1.f,-1.f} }; - for(int i(0) ; i < 12 ; ++i) - for(int j(0) ; j < 3 ; ++j) - gradient3[i][j] = grad3Temp[i][j]; + for(int i(0) ; i < 12 ; ++i) + for(int j(0) ; j < 3 ; ++j) + gradient3[i][j] = grad3Temp[i][j]; } NzSimplex3D::NzSimplex3D(unsigned int seed) : NzSimplex3D() { - this->SetNewSeed(seed); - this->ShufflePermutationTable(); + this->SetNewSeed(seed); + this->ShufflePermutationTable(); } float NzSimplex3D::GetValue(float x, float y, float z, float resolution) { - x *= resolution; - y *= resolution; - z *= resolution; + x *= resolution; + y *= resolution; + z *= resolution; - sum = (x + y + z) * SkewCoeff3D; - skewedCubeOrigin.x = fastfloor(x + sum); - skewedCubeOrigin.y = fastfloor(y + sum); - skewedCubeOrigin.z = fastfloor(z + sum); + sum = (x + y + z) * SkewCoeff3D; + skewedCubeOrigin.x = fastfloor(x + sum); + skewedCubeOrigin.y = fastfloor(y + sum); + skewedCubeOrigin.z = fastfloor(z + sum); - sum = (skewedCubeOrigin.x + skewedCubeOrigin.y + skewedCubeOrigin.z) * UnskewCoeff3D; - unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; - unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; - unskewedCubeOrigin.z = skewedCubeOrigin.z - sum; + sum = (skewedCubeOrigin.x + skewedCubeOrigin.y + skewedCubeOrigin.z) * UnskewCoeff3D; + unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; + unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; + unskewedCubeOrigin.z = skewedCubeOrigin.z - sum; - unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; - unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; - unskewedDistToOrigin.z = z - unskewedCubeOrigin.z; + unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; + unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; + unskewedDistToOrigin.z = z - unskewedCubeOrigin.z; - if(unskewedDistToOrigin.x >= unskewedDistToOrigin.y) - { - if(unskewedDistToOrigin.y >= unskewedDistToOrigin.z) - { - off1.x = 1; - off1.y = 0; - off1.z = 0; - off2.x = 1; - off2.y = 1; - off2.z = 0; - } - else if(unskewedDistToOrigin.x >= unskewedDistToOrigin.z) - { - off1.x = 1; - off1.y = 0; - off1.z = 0; - off2.x = 1; - off2.y = 0; - off2.z = 1; - } - else - { - off1.x = 0; - off1.y = 0; - off1.z = 1; - off2.x = 1; - off2.y = 0; - off2.z = 1; - } - } - else - { - if(unskewedDistToOrigin.y < unskewedDistToOrigin.z) - { - off1.x = 0; - off1.y = 0; - off1.z = 1; - off2.x = 0; - off2.y = 1; - off2.z = 1; - } - else if(unskewedDistToOrigin.x < unskewedDistToOrigin.z) - { - off1.x = 0; - off1.y = 1; - off1.z = 0; - off2.x = 0; - off2.y = 1; - off2.z = 1; - } - else - { - off1.x = 0; - off1.y = 1; - off1.z = 0; - off2.x = 1; - off2.y = 1; - off2.z = 0; - } - } + if(unskewedDistToOrigin.x >= unskewedDistToOrigin.y) + { + if(unskewedDistToOrigin.y >= unskewedDistToOrigin.z) + { + off1.x = 1; + off1.y = 0; + off1.z = 0; + off2.x = 1; + off2.y = 1; + off2.z = 0; + } + else if(unskewedDistToOrigin.x >= unskewedDistToOrigin.z) + { + off1.x = 1; + off1.y = 0; + off1.z = 0; + off2.x = 1; + off2.y = 0; + off2.z = 1; + } + else + { + off1.x = 0; + off1.y = 0; + off1.z = 1; + off2.x = 1; + off2.y = 0; + off2.z = 1; + } + } + else + { + if(unskewedDistToOrigin.y < unskewedDistToOrigin.z) + { + off1.x = 0; + off1.y = 0; + off1.z = 1; + off2.x = 0; + off2.y = 1; + off2.z = 1; + } + else if(unskewedDistToOrigin.x < unskewedDistToOrigin.z) + { + off1.x = 0; + off1.y = 1; + off1.z = 0; + off2.x = 0; + off2.y = 1; + off2.z = 1; + } + else + { + off1.x = 0; + off1.y = 1; + off1.z = 0; + off2.x = 1; + off2.y = 1; + off2.z = 0; + } + } - d1 = unskewedDistToOrigin; + d1 = unskewedDistToOrigin; - d2.x = d1.x - off1.x + UnskewCoeff3D; - d2.y = d1.y - off1.y + UnskewCoeff3D; - d2.z = d1.z - off1.z + UnskewCoeff3D; + d2.x = d1.x - off1.x + UnskewCoeff3D; + d2.y = d1.y - off1.y + UnskewCoeff3D; + d2.z = d1.z - off1.z + UnskewCoeff3D; - d3.x = d1.x - off2.x + 2.f*UnskewCoeff3D; - d3.y = d1.y - off2.y + 2.f*UnskewCoeff3D; - d3.z = d1.z - off2.z + 2.f*UnskewCoeff3D; + d3.x = d1.x - off2.x + 2.f*UnskewCoeff3D; + d3.y = d1.y - off2.y + 2.f*UnskewCoeff3D; + d3.z = d1.z - off2.z + 2.f*UnskewCoeff3D; - d4.x = d1.x - 1.f + 3.f*UnskewCoeff3D; - d4.y = d1.y - 1.f + 3.f*UnskewCoeff3D; - d4.z = d1.z - 1.f + 3.f*UnskewCoeff3D; + d4.x = d1.x - 1.f + 3.f*UnskewCoeff3D; + d4.y = d1.y - 1.f + 3.f*UnskewCoeff3D; + d4.z = d1.z - 1.f + 3.f*UnskewCoeff3D; - ii = skewedCubeOrigin.x & 255; - jj = skewedCubeOrigin.y & 255; - kk = skewedCubeOrigin.z & 255; + ii = skewedCubeOrigin.x & 255; + jj = skewedCubeOrigin.y & 255; + kk = skewedCubeOrigin.z & 255; - gi0 = perm[ii + perm[jj + perm[kk ]]] % 12; - gi1 = perm[ii + off1.x + perm[jj + off1.y + perm[kk + off1.z]]] % 12; - gi2 = perm[ii + off2.x + perm[jj + off2.y + perm[kk + off2.z]]] % 12; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 ]]] % 12; + gi0 = perm[ii + perm[jj + perm[kk ]]] % 12; + gi1 = perm[ii + off1.x + perm[jj + off1.y + perm[kk + off1.z]]] % 12; + gi2 = perm[ii + off2.x + perm[jj + off2.y + perm[kk + off2.z]]] % 12; + gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 ]]] % 12; - c1 = 0.6f - d1.x * d1.x - d1.y * d1.y - d1.z * d1.z; - c2 = 0.6f - d2.x * d2.x - d2.y * d2.y - d2.z * d2.z; - c3 = 0.6f - d3.x * d3.x - d3.y * d3.y - d3.z * d3.z; - c4 = 0.6f - d4.x * d4.x - d4.y * d4.y - d4.z * d4.z; + c1 = 0.6f - d1.x * d1.x - d1.y * d1.y - d1.z * d1.z; + c2 = 0.6f - d2.x * d2.x - d2.y * d2.y - d2.z * d2.z; + c3 = 0.6f - d3.x * d3.x - d3.y * d3.y - d3.z * d3.z; + c4 = 0.6f - d4.x * d4.x - d4.y * d4.y - d4.z * d4.z; - if(c1 < 0) - n1 = 0; - else - n1 = c1*c1*c1*c1*(gradient3[gi0][0] * d1.x + gradient3[gi0][1] * d1.y + gradient3[gi0][2] * d1.z); + if(c1 < 0) + n1 = 0; + else + n1 = c1*c1*c1*c1*(gradient3[gi0][0] * d1.x + gradient3[gi0][1] * d1.y + gradient3[gi0][2] * d1.z); - if(c2 < 0) - n2 = 0; - else - n2 = c2*c2*c2*c2*(gradient3[gi1][0] * d2.x + gradient3[gi1][1] * d2.y + gradient3[gi1][2] * d2.z); + if(c2 < 0) + n2 = 0; + else + n2 = c2*c2*c2*c2*(gradient3[gi1][0] * d2.x + gradient3[gi1][1] * d2.y + gradient3[gi1][2] * d2.z); - if(c3 < 0) - n3 = 0; - else - n3 = c3*c3*c3*c3*(gradient3[gi2][0] * d3.x + gradient3[gi2][1] * d3.y + gradient3[gi2][2] * d3.z); + if(c3 < 0) + n3 = 0; + else + n3 = c3*c3*c3*c3*(gradient3[gi2][0] * d3.x + gradient3[gi2][1] * d3.y + gradient3[gi2][2] * d3.z); - if(c4 < 0) - n4 = 0; - else - n4 = c4*c4*c4*c4*(gradient3[gi3][0] * d4.x + gradient3[gi3][1] * d4.y + gradient3[gi3][2] * d4.z); + if(c4 < 0) + n4 = 0; + else + n4 = c4*c4*c4*c4*(gradient3[gi3][0] * d4.x + gradient3[gi3][1] * d4.y + gradient3[gi3][2] * d4.z); - return (n1+n2+n3+n4)*32; + return (n1+n2+n3+n4)*32; } diff --git a/src/Nazara/Noise/Simplex4D.cpp b/src/Nazara/Noise/Simplex4D.cpp index 9cc2b28a1..8647a0386 100644 --- a/src/Nazara/Noise/Simplex4D.cpp +++ b/src/Nazara/Noise/Simplex4D.cpp @@ -9,158 +9,158 @@ NzSimplex4D::NzSimplex4D() { - SkewCoeff4D = (std::sqrt(5.f) - 1.f)/4.f; - UnskewCoeff4D = (5.f - std::sqrt(5.f))/20.f; + SkewCoeff4D = (std::sqrt(5.f) - 1.f)/4.f; + UnskewCoeff4D = (5.f - std::sqrt(5.f))/20.f; - int lookupTemp4D[][4] = - { - {0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0}, - {0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0}, - {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, - {1,2,0,3},{0,0,0,0},{1,3,0,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,3,0,1},{2,3,1,0}, - {1,0,2,3},{1,0,3,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,0,3,1},{0,0,0,0},{2,1,3,0}, - {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, - {2,0,1,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,0,1,2},{3,0,2,1},{0,0,0,0},{3,1,2,0}, - {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0} - }; + int lookupTemp4D[][4] = + { + {0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0}, + {0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0}, + {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, + {1,2,0,3},{0,0,0,0},{1,3,0,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,3,0,1},{2,3,1,0}, + {1,0,2,3},{1,0,3,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,0,3,1},{0,0,0,0},{2,1,3,0}, + {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, + {2,0,1,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,0,1,2},{3,0,2,1},{0,0,0,0},{3,1,2,0}, + {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0} + }; - for(int i(0) ; i < 64 ; ++i) - for(int j(0) ; j < 4 ; ++j) - lookupTable4D[i][j] = lookupTemp4D[i][j]; + for(int i(0) ; i < 64 ; ++i) + for(int j(0) ; j < 4 ; ++j) + lookupTable4D[i][j] = lookupTemp4D[i][j]; - float grad4Temp[][4] = - { - {0.f,1.f,1.f,1.f}, {0.f,1.f,1.f,-1.f}, {0.f,1.f,-1.f,1.f}, {0.f,1.f,-1.f,-1.f}, - {0.f,-1.f,1.f,1.f},{0.f,-1.f,1.f,-1.f},{0.f,-1.f,-1.f,1.f},{0.f,-1.f,-1.f,-1.f}, - {1.f,0.f,1.f,1.f}, {1.f,0.f,1.f,-1.f}, {1.f,0.f,-1.f,1.f}, {1.f,0.f,-1.f,-1.f}, - {-1.f,0.f,1.f,1.f},{-1.f,0.f,1.f,-1.f},{-1.f,0.f,-1.f,1.f},{-1.f,0.f,-1.f,-1.f}, - {1.f,1.f,0.f,1.f}, {1.f,1.f,0.f,-1.f}, {1.f,-1.f,0.f,1.f}, {1.f,-1.f,0.f,-1.f}, - {-1.f,1.f,0.f,1.f},{-1.f,1.f,0.f,-1.f},{-1.f,-1.f,0.f,1.f},{-1.f,-1.f,0.f,-1.f}, - {1.f,1.f,1.f,0.f}, {1.f,1.f,-1.f,0.f}, {1.f,-1.f,1.f,0.f}, {1.f,-1.f,-1.f,0.f}, - {-1.f,1.f,1.f,0.f},{-1.f,1.f,-1.f,0.f},{-1.f,-1.f,1.f,0.f},{-1.f,-1.f,-1.f,0.f} - }; + float grad4Temp[][4] = + { + {0.f,1.f,1.f,1.f}, {0.f,1.f,1.f,-1.f}, {0.f,1.f,-1.f,1.f}, {0.f,1.f,-1.f,-1.f}, + {0.f,-1.f,1.f,1.f},{0.f,-1.f,1.f,-1.f},{0.f,-1.f,-1.f,1.f},{0.f,-1.f,-1.f,-1.f}, + {1.f,0.f,1.f,1.f}, {1.f,0.f,1.f,-1.f}, {1.f,0.f,-1.f,1.f}, {1.f,0.f,-1.f,-1.f}, + {-1.f,0.f,1.f,1.f},{-1.f,0.f,1.f,-1.f},{-1.f,0.f,-1.f,1.f},{-1.f,0.f,-1.f,-1.f}, + {1.f,1.f,0.f,1.f}, {1.f,1.f,0.f,-1.f}, {1.f,-1.f,0.f,1.f}, {1.f,-1.f,0.f,-1.f}, + {-1.f,1.f,0.f,1.f},{-1.f,1.f,0.f,-1.f},{-1.f,-1.f,0.f,1.f},{-1.f,-1.f,0.f,-1.f}, + {1.f,1.f,1.f,0.f}, {1.f,1.f,-1.f,0.f}, {1.f,-1.f,1.f,0.f}, {1.f,-1.f,-1.f,0.f}, + {-1.f,1.f,1.f,0.f},{-1.f,1.f,-1.f,0.f},{-1.f,-1.f,1.f,0.f},{-1.f,-1.f,-1.f,0.f} + }; - for(int i(0) ; i < 32 ; ++i) - for(int j(0) ; j < 4 ; ++j) - gradient4[i][j] = grad4Temp[i][j]; + for(int i(0) ; i < 32 ; ++i) + for(int j(0) ; j < 4 ; ++j) + gradient4[i][j] = grad4Temp[i][j]; } NzSimplex4D::NzSimplex4D(unsigned int seed) : NzSimplex4D() { - this->SetNewSeed(seed); - this->ShufflePermutationTable(); + this->SetNewSeed(seed); + this->ShufflePermutationTable(); } float NzSimplex4D::GetValue(float x, float y, float z, float w, float resolution) { - x *= resolution; - y *= resolution; - z *= resolution; - w *= resolution; + x *= resolution; + y *= resolution; + z *= resolution; + w *= resolution; - sum = (x + y + z + w) * SkewCoeff4D; - skewedCubeOrigin.x = fastfloor(x + sum); - skewedCubeOrigin.y = fastfloor(y + sum); - skewedCubeOrigin.z = fastfloor(z + sum); - skewedCubeOrigin.w = fastfloor(w + sum); + sum = (x + y + z + w) * SkewCoeff4D; + skewedCubeOrigin.x = fastfloor(x + sum); + skewedCubeOrigin.y = fastfloor(y + sum); + skewedCubeOrigin.z = fastfloor(z + sum); + skewedCubeOrigin.w = fastfloor(w + sum); - sum = (skewedCubeOrigin.x + skewedCubeOrigin.y + skewedCubeOrigin.z + skewedCubeOrigin.w) * UnskewCoeff4D; - unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; - unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; - unskewedCubeOrigin.z = skewedCubeOrigin.z - sum; - unskewedCubeOrigin.w = skewedCubeOrigin.w - sum; + sum = (skewedCubeOrigin.x + skewedCubeOrigin.y + skewedCubeOrigin.z + skewedCubeOrigin.w) * UnskewCoeff4D; + unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; + unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; + unskewedCubeOrigin.z = skewedCubeOrigin.z - sum; + unskewedCubeOrigin.w = skewedCubeOrigin.w - sum; - unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; - unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; - unskewedDistToOrigin.z = z - unskewedCubeOrigin.z; - unskewedDistToOrigin.w = w - unskewedCubeOrigin.w; + unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; + unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; + unskewedDistToOrigin.z = z - unskewedCubeOrigin.z; + unskewedDistToOrigin.w = w - unskewedCubeOrigin.w; - c1 = (unskewedDistToOrigin.x > unskewedDistToOrigin.y) ? 32 : 0; - c2 = (unskewedDistToOrigin.x > unskewedDistToOrigin.z) ? 16 : 0; - c3 = (unskewedDistToOrigin.y > unskewedDistToOrigin.z) ? 8 : 0; - c4 = (unskewedDistToOrigin.x > unskewedDistToOrigin.w) ? 4 : 0; - c5 = (unskewedDistToOrigin.y > unskewedDistToOrigin.w) ? 2 : 0; - c6 = (unskewedDistToOrigin.z > unskewedDistToOrigin.w) ? 1 : 0; - c = c1 + c2 + c3 + c4 + c5 + c6; + c1 = (unskewedDistToOrigin.x > unskewedDistToOrigin.y) ? 32 : 0; + c2 = (unskewedDistToOrigin.x > unskewedDistToOrigin.z) ? 16 : 0; + c3 = (unskewedDistToOrigin.y > unskewedDistToOrigin.z) ? 8 : 0; + c4 = (unskewedDistToOrigin.x > unskewedDistToOrigin.w) ? 4 : 0; + c5 = (unskewedDistToOrigin.y > unskewedDistToOrigin.w) ? 2 : 0; + c6 = (unskewedDistToOrigin.z > unskewedDistToOrigin.w) ? 1 : 0; + c = c1 + c2 + c3 + c4 + c5 + c6; - off1.x = lookupTable4D[c][0] >= 3 ? 1 : 0; - off1.y = lookupTable4D[c][1] >= 3 ? 1 : 0; - off1.z = lookupTable4D[c][2] >= 3 ? 1 : 0; - off1.w = lookupTable4D[c][3] >= 3 ? 1 : 0; + off1.x = lookupTable4D[c][0] >= 3 ? 1 : 0; + off1.y = lookupTable4D[c][1] >= 3 ? 1 : 0; + off1.z = lookupTable4D[c][2] >= 3 ? 1 : 0; + off1.w = lookupTable4D[c][3] >= 3 ? 1 : 0; - off2.x = lookupTable4D[c][0] >= 2 ? 1 : 0; - off2.y = lookupTable4D[c][1] >= 2 ? 1 : 0; - off2.z = lookupTable4D[c][2] >= 2 ? 1 : 0; - off2.w = lookupTable4D[c][3] >= 2 ? 1 : 0; + off2.x = lookupTable4D[c][0] >= 2 ? 1 : 0; + off2.y = lookupTable4D[c][1] >= 2 ? 1 : 0; + off2.z = lookupTable4D[c][2] >= 2 ? 1 : 0; + off2.w = lookupTable4D[c][3] >= 2 ? 1 : 0; - off3.x = lookupTable4D[c][0] >= 1 ? 1 : 0; - off3.y = lookupTable4D[c][1] >= 1 ? 1 : 0; - off3.z = lookupTable4D[c][2] >= 1 ? 1 : 0; - off3.w = lookupTable4D[c][3] >= 1 ? 1 : 0; + off3.x = lookupTable4D[c][0] >= 1 ? 1 : 0; + off3.y = lookupTable4D[c][1] >= 1 ? 1 : 0; + off3.z = lookupTable4D[c][2] >= 1 ? 1 : 0; + off3.w = lookupTable4D[c][3] >= 1 ? 1 : 0; - d1 = unskewedDistToOrigin; + d1 = unskewedDistToOrigin; - d2.x = d1.x - off1.x + UnskewCoeff4D; - d2.y = d1.y - off1.y + UnskewCoeff4D; - d2.z = d1.z - off1.z + UnskewCoeff4D; - d2.w = d1.w - off1.w + UnskewCoeff4D; + d2.x = d1.x - off1.x + UnskewCoeff4D; + d2.y = d1.y - off1.y + UnskewCoeff4D; + d2.z = d1.z - off1.z + UnskewCoeff4D; + d2.w = d1.w - off1.w + UnskewCoeff4D; - d3.x = d1.x - off2.x + 2.f*UnskewCoeff4D; - d3.y = d1.y - off2.y + 2.f*UnskewCoeff4D; - d3.z = d1.z - off2.z + 2.f*UnskewCoeff4D; - d3.w = d1.w - off2.w + 2.f*UnskewCoeff4D; + d3.x = d1.x - off2.x + 2.f*UnskewCoeff4D; + d3.y = d1.y - off2.y + 2.f*UnskewCoeff4D; + d3.z = d1.z - off2.z + 2.f*UnskewCoeff4D; + d3.w = d1.w - off2.w + 2.f*UnskewCoeff4D; - d4.x = d1.x - off3.x + 3.f*UnskewCoeff4D; - d4.y = d1.y - off3.y + 3.f*UnskewCoeff4D; - d4.z = d1.z - off3.z + 3.f*UnskewCoeff4D; - d4.w = d1.w - off3.w + 3.f*UnskewCoeff4D; + d4.x = d1.x - off3.x + 3.f*UnskewCoeff4D; + d4.y = d1.y - off3.y + 3.f*UnskewCoeff4D; + d4.z = d1.z - off3.z + 3.f*UnskewCoeff4D; + d4.w = d1.w - off3.w + 3.f*UnskewCoeff4D; - d5.x = d1.x - 1.f + 4*UnskewCoeff4D; - d5.y = d1.y - 1.f + 4*UnskewCoeff4D; - d5.z = d1.z - 1.f + 4*UnskewCoeff4D; - d5.w = d1.w - 1.f + 4*UnskewCoeff4D; + d5.x = d1.x - 1.f + 4*UnskewCoeff4D; + d5.y = d1.y - 1.f + 4*UnskewCoeff4D; + d5.z = d1.z - 1.f + 4*UnskewCoeff4D; + d5.w = d1.w - 1.f + 4*UnskewCoeff4D; - ii = skewedCubeOrigin.x & 255; - jj = skewedCubeOrigin.y & 255; - kk = skewedCubeOrigin.z & 255; - ll = skewedCubeOrigin.w & 255; + ii = skewedCubeOrigin.x & 255; + jj = skewedCubeOrigin.y & 255; + kk = skewedCubeOrigin.z & 255; + ll = skewedCubeOrigin.w & 255; - gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] & 31; - gi1 = perm[ii + off1.x + perm[jj + off1.y + perm[kk + off1.z + perm[ll + off1.w]]]] & 31; - gi2 = perm[ii + off2.x + perm[jj + off2.y + perm[kk + off2.z + perm[ll + off2.w]]]] & 31; - gi3 = perm[ii + off3.x + perm[jj + off3.y + perm[kk + off3.z + perm[ll + off3.w]]]] & 31; - gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32; + gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] & 31; + gi1 = perm[ii + off1.x + perm[jj + off1.y + perm[kk + off1.z + perm[ll + off1.w]]]] & 31; + gi2 = perm[ii + off2.x + perm[jj + off2.y + perm[kk + off2.z + perm[ll + off2.w]]]] & 31; + gi3 = perm[ii + off3.x + perm[jj + off3.y + perm[kk + off3.z + perm[ll + off3.w]]]] & 31; + gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32; - c1 = 0.6f - d1.x*d1.x - d1.y*d1.y - d1.z*d1.z - d1.w*d1.w; - c2 = 0.6f - d2.x*d2.x - d2.y*d2.y - d2.z*d2.z - d2.w*d2.w; - c3 = 0.6f - d3.x*d3.x - d3.y*d3.y - d3.z*d3.z - d3.w*d3.w; - c4 = 0.6f - d4.x*d4.x - d4.y*d4.y - d4.z*d4.z - d4.w*d4.w; - c5 = 0.6f - d5.x*d5.x - d5.y*d5.y - d5.z*d5.z - d5.w*d5.w; + c1 = 0.6f - d1.x*d1.x - d1.y*d1.y - d1.z*d1.z - d1.w*d1.w; + c2 = 0.6f - d2.x*d2.x - d2.y*d2.y - d2.z*d2.z - d2.w*d2.w; + c3 = 0.6f - d3.x*d3.x - d3.y*d3.y - d3.z*d3.z - d3.w*d3.w; + c4 = 0.6f - d4.x*d4.x - d4.y*d4.y - d4.z*d4.z - d4.w*d4.w; + c5 = 0.6f - d5.x*d5.x - d5.y*d5.y - d5.z*d5.z - d5.w*d5.w; - if(c1 < 0) - n1 = 0; - else - n1 = c1*c1*c1*c1*(gradient4[gi0][0]*d1.x + gradient4[gi0][1]*d1.y + gradient4[gi0][2]*d1.z + gradient4[gi0][3]*d1.w); + if(c1 < 0) + n1 = 0; + else + n1 = c1*c1*c1*c1*(gradient4[gi0][0]*d1.x + gradient4[gi0][1]*d1.y + gradient4[gi0][2]*d1.z + gradient4[gi0][3]*d1.w); - if(c2 < 0) - n2 = 0; - else - n2 = c2*c2*c2*c2*(gradient4[gi1][0]*d2.x + gradient4[gi1][1]*d2.y + gradient4[gi1][2]*d2.z + gradient4[gi1][3]*d2.w); + if(c2 < 0) + n2 = 0; + else + n2 = c2*c2*c2*c2*(gradient4[gi1][0]*d2.x + gradient4[gi1][1]*d2.y + gradient4[gi1][2]*d2.z + gradient4[gi1][3]*d2.w); - if(c3 < 0) - n3 = 0; - else - n3 = c3*c3*c3*c3*(gradient4[gi2][0]*d3.x + gradient4[gi2][1]*d3.y + gradient4[gi2][2]*d3.z + gradient4[gi2][3]*d3.w); + if(c3 < 0) + n3 = 0; + else + n3 = c3*c3*c3*c3*(gradient4[gi2][0]*d3.x + gradient4[gi2][1]*d3.y + gradient4[gi2][2]*d3.z + gradient4[gi2][3]*d3.w); - if(c4 < 0) - n4 = 0; - else - n4 = c4*c4*c4*c4*(gradient4[gi3][0]*d4.x + gradient4[gi3][1]*d4.y + gradient4[gi3][2]*d4.z + gradient4[gi3][3]*d4.w); + if(c4 < 0) + n4 = 0; + else + n4 = c4*c4*c4*c4*(gradient4[gi3][0]*d4.x + gradient4[gi3][1]*d4.y + gradient4[gi3][2]*d4.z + gradient4[gi3][3]*d4.w); - if(c5 < 0) - n5 = 0; - else - n5 = c5*c5*c5*c5*(gradient4[gi4][0]*d5.x + gradient4[gi4][1]*d5.y + gradient4[gi4][2]*d5.z + gradient4[gi4][3]*d5.w); + if(c5 < 0) + n5 = 0; + else + n5 = c5*c5*c5*c5*(gradient4[gi4][0]*d5.x + gradient4[gi4][1]*d5.y + gradient4[gi4][2]*d5.z + gradient4[gi4][3]*d5.w); - return (n1+n2+n3+n4+n5)*27.f; + return (n1+n2+n3+n4+n5)*27.f; } diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index b574de8d9..08ac50822 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -647,7 +647,7 @@ unsigned int NzRenderTexture::GetOpenGLID() const } #endif - return m_impl->fbo; + return m_impl->fbo; } bool NzRenderTexture::HasContext() const diff --git a/src/Nazara/Renderer/Shader.cpp b/src/Nazara/Renderer/Shader.cpp index 21d3a9a24..f09bbea8b 100644 --- a/src/Nazara/Renderer/Shader.cpp +++ b/src/Nazara/Renderer/Shader.cpp @@ -351,7 +351,7 @@ bool NzShader::LoadFromBinary(const void* buffer, unsigned int size) bool NzShader::LoadFromBinary(const NzByteArray& byteArray) { - return LoadFromBinary(byteArray.GetConstBuffer(), byteArray.GetSize()); + return LoadFromBinary(byteArray.GetConstBuffer(), byteArray.GetSize()); } void NzShader::SendBoolean(int location, bool value) const diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 303b983fa..9b9789839 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -1041,11 +1041,11 @@ unsigned int NzTexture::GetValidSize(unsigned int size) return size; else { - unsigned int pot = 1; - while (pot < size) - pot <<= 1; + unsigned int pot = 1; + while (pot < size) + pot <<= 1; - return pot; + return pot; } } diff --git a/src/Nazara/Renderer/UberShaderPreprocessor.cpp b/src/Nazara/Renderer/UberShaderPreprocessor.cpp index 7df799419..6d41cfb7d 100644 --- a/src/Nazara/Renderer/UberShaderPreprocessor.cpp +++ b/src/Nazara/Renderer/UberShaderPreprocessor.cpp @@ -111,15 +111,15 @@ NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& param void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& source, const NzString& shaderFlags, const NzString& requiredFlags) { - Shader& shader = m_shaders[stage]; - shader.present = true; - shader.source = source; + Shader& shader = m_shaders[stage]; + shader.present = true; + shader.source = source; - // On extrait les flags de la chaîne - std::vector flags; - shaderFlags.Split(flags, ' '); + // On extrait les flags de la chaîne + std::vector flags; + shaderFlags.Split(flags, ' '); - for (NzString& flag : flags) + for (NzString& flag : flags) { auto it = m_flags.find(flag); if (it == m_flags.end()) @@ -136,7 +136,7 @@ void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& so flags.clear(); requiredFlags.Split(flags, ' '); - for (NzString& flag : flags) + for (NzString& flag : flags) { nzUInt32 flagVal; diff --git a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp index e327f4971..af1e619ae 100644 --- a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp +++ b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp @@ -106,7 +106,7 @@ namespace SetCharacterSize(characterSize); - if (FT_Load_Char(m_face, character, FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_NORMAL) != 0) + if (FT_Load_Char(m_face, character, FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_NORMAL) != 0) { NazaraError("Failed to load character"); return false; diff --git a/src/Nazara/Utility/Formats/STBLoader.cpp b/src/Nazara/Utility/Formats/STBLoader.cpp index 21f7f985c..1ef8fd2fa 100644 --- a/src/Nazara/Utility/Formats/STBLoader.cpp +++ b/src/Nazara/Utility/Formats/STBLoader.cpp @@ -21,11 +21,11 @@ namespace return static_cast(stream->Read(data, size)); } - void Skip(void* userdata, int size) - { + void Skip(void* userdata, int size) + { NzInputStream* stream = static_cast(userdata); stream->SetCursorPos(static_cast(stream->GetCursorPos()) + static_cast(size)); - } + } int Eof(void* userdata) { diff --git a/src/Nazara/Utility/Win32/WindowImpl.cpp b/src/Nazara/Utility/Win32/WindowImpl.cpp index 0119ccb2a..53d891e22 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.cpp +++ b/src/Nazara/Utility/Win32/WindowImpl.cpp @@ -29,7 +29,7 @@ // N'est pas défini avec MinGW #ifndef MAPVK_VK_TO_VSC - #define MAPVK_VK_TO_VSC 0 + #define MAPVK_VK_TO_VSC 0 #endif #undef IsMinimized // Conflit avec la méthode du même nom From c214251ecff94f167c6e5a2afbfa7572d64b9752 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 24 Sep 2015 12:51:52 +0200 Subject: [PATCH 06/97] Update copy/move constructors/operators Former-commit-id: b1faeeae9211a6c0ca29261d46929dc8c66ea0c4 --- include/Nazara/Audio/Sound.hpp | 4 ++++ include/Nazara/Core/Clock.hpp | 3 +++ include/Nazara/Core/HardwareInfo.hpp | 3 +++ include/Nazara/Core/Hashable.hpp | 5 +++++ include/Nazara/Core/Initializer.hpp | 5 +++++ include/Nazara/Core/MemoryStream.hpp | 5 +++++ include/Nazara/Core/ParameterList.hpp | 4 ++-- include/Nazara/Core/PrimitiveList.hpp | 5 +++++ include/Nazara/Core/SparsePtr.hpp | 4 ++-- include/Nazara/Core/Stream.hpp | 5 +++++ include/Nazara/Core/StringStream.hpp | 5 +++++ include/Nazara/Core/Thread.hpp | 2 +- include/Nazara/Graphics/AbstractBackground.hpp | 5 +++++ include/Nazara/Graphics/AbstractViewer.hpp | 5 +++++ include/Nazara/Graphics/Billboard.hpp | 2 ++ include/Nazara/Graphics/ColorBackground.hpp | 4 ++++ include/Nazara/Renderer/Context.hpp | 5 +++++ include/Nazara/Renderer/RenderTarget.hpp | 5 +++++ include/Nazara/Renderer/RenderTexture.hpp | 4 ++-- include/Nazara/Renderer/RenderWindow.hpp | 5 +++++ include/Nazara/Renderer/UberShader.hpp | 5 +++++ include/Nazara/Renderer/UberShaderInstance.hpp | 5 +++++ src/Nazara/Core/ParameterList.cpp | 11 ----------- src/Nazara/Core/Thread.cpp | 2 +- 24 files changed, 89 insertions(+), 19 deletions(-) diff --git a/include/Nazara/Audio/Sound.hpp b/include/Nazara/Audio/Sound.hpp index d875d5460..3381a1ad6 100644 --- a/include/Nazara/Audio/Sound.hpp +++ b/include/Nazara/Audio/Sound.hpp @@ -18,6 +18,7 @@ class NAZARA_AUDIO_API NzSound : public NzSoundEmitter NzSound() = default; NzSound(const NzSoundBuffer* soundBuffer); NzSound(const NzSound& sound); + NzSound(NzSound&&) = default; ~NzSound(); void EnableLooping(bool loop); @@ -43,6 +44,9 @@ class NAZARA_AUDIO_API NzSound : public NzSoundEmitter void Stop(); + NzSound& operator=(const NzSound&) = delete; ///TODO? + NzSound& operator=(NzSound&&) = default; + private: NzSoundBufferConstRef m_buffer; }; diff --git a/include/Nazara/Core/Clock.hpp b/include/Nazara/Core/Clock.hpp index 8eac3c2db..82e30e009 100644 --- a/include/Nazara/Core/Clock.hpp +++ b/include/Nazara/Core/Clock.hpp @@ -20,6 +20,8 @@ class NAZARA_CORE_API NzClock public: NzClock(nzUInt64 startingValue = 0, bool paused = false); NzClock(const NzClock& clock) = default; + NzClock(NzClock&& clock) = default; + ~NzClock() = default; float GetSeconds() const; nzUInt64 GetMicroseconds() const; @@ -32,6 +34,7 @@ class NAZARA_CORE_API NzClock void Unpause(); NzClock& operator=(const NzClock& clock) = default; + NzClock& operator=(NzClock&& clock) = default; private: NazaraMutexAttrib(m_mutex, mutable) diff --git a/include/Nazara/Core/HardwareInfo.hpp b/include/Nazara/Core/HardwareInfo.hpp index bbdf704f7..ec844e6b2 100644 --- a/include/Nazara/Core/HardwareInfo.hpp +++ b/include/Nazara/Core/HardwareInfo.hpp @@ -14,6 +14,9 @@ class NAZARA_CORE_API NzHardwareInfo { public: + NzHardwareInfo() = delete; + ~NzHardwareInfo() = delete; + static void Cpuid(nzUInt32 functionId, nzUInt32 subFunctionId, nzUInt32 result[4]); static NzString GetProcessorBrandString(); diff --git a/include/Nazara/Core/Hashable.hpp b/include/Nazara/Core/Hashable.hpp index 45f29dab1..d46773674 100644 --- a/include/Nazara/Core/Hashable.hpp +++ b/include/Nazara/Core/Hashable.hpp @@ -19,11 +19,16 @@ class NAZARA_CORE_API NzHashable public: NzHashable() = default; + NzHashable(const NzHashable&) = default; + NzHashable(NzHashable&&) = default; virtual ~NzHashable(); NzHashDigest GetHash(nzHash hash) const; NzHashDigest GetHash(NzAbstractHash* impl) const; + NzHashable& operator=(const NzHashable&) = default; + NzHashable& operator=(NzHashable&&) = default; + private: virtual bool FillHash(NzAbstractHash* impl) const = 0; }; diff --git a/include/Nazara/Core/Initializer.hpp b/include/Nazara/Core/Initializer.hpp index 64081f891..c7a8109f6 100644 --- a/include/Nazara/Core/Initializer.hpp +++ b/include/Nazara/Core/Initializer.hpp @@ -14,6 +14,8 @@ class NzInitializer { public: NzInitializer(bool initialize = true); + NzInitializer(const NzInitializer&) = delete; + NzInitializer(NzInitializer&&) = delete; ///TODO ~NzInitializer(); bool Initialize(); @@ -22,6 +24,9 @@ class NzInitializer operator bool() const; + NzInitializer& operator=(const NzInitializer&) = delete; + NzInitializer& operator=(NzInitializer&&) = delete; ///TODO + private: bool m_initialized; }; diff --git a/include/Nazara/Core/MemoryStream.hpp b/include/Nazara/Core/MemoryStream.hpp index 11d9a7827..20ca52997 100644 --- a/include/Nazara/Core/MemoryStream.hpp +++ b/include/Nazara/Core/MemoryStream.hpp @@ -14,6 +14,8 @@ class NAZARA_CORE_API NzMemoryStream : public NzInputStream { public: NzMemoryStream(const void* ptr, nzUInt64 size); + NzMemoryStream(const NzMemoryStream&) = delete; + NzMemoryStream(NzMemoryStream&&) = delete; ///TODO ~NzMemoryStream(); bool EndOfStream() const; @@ -25,6 +27,9 @@ class NAZARA_CORE_API NzMemoryStream : public NzInputStream bool SetCursorPos(nzUInt64 offset); + NzMemoryStream& operator=(const NzMemoryStream&) = delete; + NzMemoryStream& operator=(NzMemoryStream&&) = delete; ///TODO + private: const nzUInt8* m_ptr; nzUInt64 m_pos; diff --git a/include/Nazara/Core/ParameterList.hpp b/include/Nazara/Core/ParameterList.hpp index a3dbcb197..9f3326fbe 100644 --- a/include/Nazara/Core/ParameterList.hpp +++ b/include/Nazara/Core/ParameterList.hpp @@ -19,7 +19,7 @@ class NAZARA_CORE_API NzParameterList NzParameterList() = default; NzParameterList(const NzParameterList& list); - NzParameterList(NzParameterList&& list); + NzParameterList(NzParameterList&&) = default; ~NzParameterList(); void Clear(); @@ -46,7 +46,7 @@ class NAZARA_CORE_API NzParameterList void SetParameter(const NzString& name, int value); NzParameterList& operator=(const NzParameterList& list); - NzParameterList& operator=(NzParameterList&& list); + NzParameterList& operator=(NzParameterList&&) = default; private: struct Parameter diff --git a/include/Nazara/Core/PrimitiveList.hpp b/include/Nazara/Core/PrimitiveList.hpp index 8d48e8953..5ddb6b21b 100644 --- a/include/Nazara/Core/PrimitiveList.hpp +++ b/include/Nazara/Core/PrimitiveList.hpp @@ -15,6 +15,8 @@ class NAZARA_CORE_API NzPrimitiveList { public: NzPrimitiveList() = default; + NzPrimitiveList(const NzPrimitiveList&) = default; + NzPrimitiveList(NzPrimitiveList&&) = default; ~NzPrimitiveList() = default; void AddBox(const NzVector3f& lengths, const NzVector3ui& subdivision = NzVector3ui(0U), const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); @@ -35,6 +37,9 @@ class NAZARA_CORE_API NzPrimitiveList const NzPrimitive& GetPrimitive(unsigned int i) const; unsigned int GetSize() const; + NzPrimitiveList& operator=(const NzPrimitiveList&) = default; + NzPrimitiveList& operator=(NzPrimitiveList&&) = default; + NzPrimitive& operator()(unsigned int i); const NzPrimitive& operator()(unsigned int i) const; diff --git a/include/Nazara/Core/SparsePtr.hpp b/include/Nazara/Core/SparsePtr.hpp index 65016432f..5652502da 100644 --- a/include/Nazara/Core/SparsePtr.hpp +++ b/include/Nazara/Core/SparsePtr.hpp @@ -45,6 +45,8 @@ class NzSparsePtr T* operator->() const; T& operator[](int index) const; + NzSparsePtr& operator=(const NzSparsePtr& ptr) = default; + NzSparsePtr operator+(int count) const; NzSparsePtr operator+(unsigned int count) const; NzSparsePtr operator-(int count) const; @@ -67,8 +69,6 @@ class NzSparsePtr bool operator<=(const NzSparsePtr& ptr) const; bool operator>=(const NzSparsePtr& ptr) const; - NzSparsePtr& operator=(const NzSparsePtr& ptr) = default; - private: BytePtr m_ptr; int m_stride; diff --git a/include/Nazara/Core/Stream.hpp b/include/Nazara/Core/Stream.hpp index 54c1d5b94..8a744b7ac 100644 --- a/include/Nazara/Core/Stream.hpp +++ b/include/Nazara/Core/Stream.hpp @@ -15,6 +15,8 @@ class NAZARA_CORE_API NzStream { public: NzStream() = default; + NzStream(const NzStream&) = default; + NzStream(NzStream&&) = default; virtual ~NzStream(); virtual nzUInt64 GetCursorPos() const = 0; @@ -25,6 +27,9 @@ class NAZARA_CORE_API NzStream virtual bool SetCursorPos(nzUInt64 offset) = 0; void SetStreamOptions(unsigned int options); + NzStream& operator=(const NzStream&) = default; + NzStream& operator=(NzStream&&) = default; + protected: unsigned int m_streamOptions = 0; }; diff --git a/include/Nazara/Core/StringStream.hpp b/include/Nazara/Core/StringStream.hpp index 906cdafce..da9521b35 100644 --- a/include/Nazara/Core/StringStream.hpp +++ b/include/Nazara/Core/StringStream.hpp @@ -17,9 +17,14 @@ class NAZARA_CORE_API NzStringStream public: NzStringStream(); NzStringStream(const NzString& str); + NzStringStream(const NzStringStream&) = default; + NzStringStream(NzStringStream&&) noexcept = default; NzString ToString() const; + NzStringStream& operator=(const NzStringStream&) = default; + NzStringStream& operator=(NzStringStream&&) noexcept = default; + NzStringStream& operator<<(bool boolean); NzStringStream& operator<<(short number); NzStringStream& operator<<(unsigned short number); diff --git a/include/Nazara/Core/Thread.hpp b/include/Nazara/Core/Thread.hpp index cb77862ea..5be32e7ad 100644 --- a/include/Nazara/Core/Thread.hpp +++ b/include/Nazara/Core/Thread.hpp @@ -23,7 +23,7 @@ class NAZARA_CORE_API NzThread template NzThread(F function, Args&&... args); template NzThread(void (C::*function)(), C* object); NzThread(const NzThread&) = delete; - NzThread(NzThread&& other); + NzThread(NzThread&& other) noexcept; ~NzThread(); void Detach(); diff --git a/include/Nazara/Graphics/AbstractBackground.hpp b/include/Nazara/Graphics/AbstractBackground.hpp index b557ee871..3d57462e0 100644 --- a/include/Nazara/Graphics/AbstractBackground.hpp +++ b/include/Nazara/Graphics/AbstractBackground.hpp @@ -24,12 +24,17 @@ class NAZARA_GRAPHICS_API NzAbstractBackground : public NzRefCounted { public: NzAbstractBackground() = default; + NzAbstractBackground(const NzAbstractBackground&) = default; + NzAbstractBackground(NzAbstractBackground&&) = delete; virtual ~NzAbstractBackground(); virtual void Draw(const NzAbstractViewer* viewer) const = 0; virtual nzBackgroundType GetBackgroundType() const = 0; + NzAbstractBackground& operator=(const NzAbstractBackground&) = default; + NzAbstractBackground& operator=(NzAbstractBackground&&) = delete; + private: static NzBackgroundLibrary::LibraryMap s_library; }; diff --git a/include/Nazara/Graphics/AbstractViewer.hpp b/include/Nazara/Graphics/AbstractViewer.hpp index 9ca7c7f77..c6baa1675 100644 --- a/include/Nazara/Graphics/AbstractViewer.hpp +++ b/include/Nazara/Graphics/AbstractViewer.hpp @@ -21,6 +21,8 @@ class NAZARA_GRAPHICS_API NzAbstractViewer { public: NzAbstractViewer() = default; + NzAbstractViewer(const NzAbstractViewer&) = default; + NzAbstractViewer(NzAbstractViewer&&) noexcept = default; virtual ~NzAbstractViewer(); virtual void ApplyView() const = 0; @@ -35,6 +37,9 @@ class NAZARA_GRAPHICS_API NzAbstractViewer virtual const NzRecti& GetViewport() const = 0; virtual float GetZFar() const = 0; virtual float GetZNear() const = 0; + + NzAbstractViewer& operator=(const NzAbstractViewer&) = default; + NzAbstractViewer& operator=(NzAbstractViewer&&) noexcept = default; }; #endif // NAZARA_ABSTRACTVIEWER_HPP diff --git a/include/Nazara/Graphics/Billboard.hpp b/include/Nazara/Graphics/Billboard.hpp index 037044c21..495ad403a 100644 --- a/include/Nazara/Graphics/Billboard.hpp +++ b/include/Nazara/Graphics/Billboard.hpp @@ -24,6 +24,7 @@ class NAZARA_GRAPHICS_API NzBillboard : public NzInstancedRenderable inline NzBillboard(NzMaterialRef material); inline NzBillboard(NzTexture* texture); inline NzBillboard(const NzBillboard& billboard); + NzBillboard(NzBillboard&&) = delete; ~NzBillboard() = default; void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; @@ -42,6 +43,7 @@ class NAZARA_GRAPHICS_API NzBillboard : public NzInstancedRenderable inline void SetTexture(NzTextureRef texture, bool resizeBillboard = true); inline NzBillboard& operator=(const NzBillboard& billboard); + NzBillboard& operator=(NzBillboard&&) = delete; template static NzBillboardRef New(Args&&... args); diff --git a/include/Nazara/Graphics/ColorBackground.hpp b/include/Nazara/Graphics/ColorBackground.hpp index c769ba15d..c1f541552 100644 --- a/include/Nazara/Graphics/ColorBackground.hpp +++ b/include/Nazara/Graphics/ColorBackground.hpp @@ -21,6 +21,8 @@ class NAZARA_GRAPHICS_API NzColorBackground : public NzAbstractBackground { public: NzColorBackground(const NzColor& color = NzColor::Black); + NzColorBackground(const NzColorBackground&) = default; + NzColorBackground(NzColorBackground&&) = delete; void Draw(const NzAbstractViewer* viewer) const; @@ -29,6 +31,8 @@ class NAZARA_GRAPHICS_API NzColorBackground : public NzAbstractBackground void SetColor(const NzColor& color); + NzColorBackground& operator=(NzColorBackground&&) = delete; + template static NzColorBackgroundRef New(Args&&... args); private: diff --git a/include/Nazara/Renderer/Context.hpp b/include/Nazara/Renderer/Context.hpp index a258746b1..1813a62aa 100644 --- a/include/Nazara/Renderer/Context.hpp +++ b/include/Nazara/Renderer/Context.hpp @@ -32,6 +32,8 @@ class NAZARA_RENDERER_API NzContext : public NzRefCounted public: NzContext() = default; + NzContext(const NzContext&) = delete; + NzContext(NzContext&&) = delete; ~NzContext(); bool Create(const NzContextParameters& parameters = NzContextParameters()); @@ -47,6 +49,9 @@ class NAZARA_RENDERER_API NzContext : public NzRefCounted bool SetActive(bool active) const; void SwapBuffers(); + NzContext& operator=(const NzContext&) = delete; + NzContext& operator=(NzContext&&) = delete; + static bool EnsureContext(); static const NzContext* GetCurrent(); diff --git a/include/Nazara/Renderer/RenderTarget.hpp b/include/Nazara/Renderer/RenderTarget.hpp index 2e9be52a7..25392bd9a 100644 --- a/include/Nazara/Renderer/RenderTarget.hpp +++ b/include/Nazara/Renderer/RenderTarget.hpp @@ -21,6 +21,8 @@ class NAZARA_RENDERER_API NzRenderTarget public: NzRenderTarget() = default; + NzRenderTarget(const NzRenderTarget&) = delete; + NzRenderTarget(NzRenderTarget&&) = delete; ///TOOD? virtual ~NzRenderTarget(); virtual unsigned int GetHeight() const = 0; @@ -35,6 +37,9 @@ class NAZARA_RENDERER_API NzRenderTarget // Fonctions OpenGL virtual bool HasContext() const = 0; + NzRenderTarget& operator=(const NzRenderTarget&) = delete; + NzRenderTarget& operator=(NzRenderTarget&&) = delete; ///TOOD? + // Signals: NazaraSignal(OnRenderTargetParametersChange, const NzRenderTarget* /*renderTarget*/); NazaraSignal(OnRenderTargetRelease, const NzRenderTarget* /*renderTarget*/); diff --git a/include/Nazara/Renderer/RenderTexture.hpp b/include/Nazara/Renderer/RenderTexture.hpp index 2aa872122..087061b75 100644 --- a/include/Nazara/Renderer/RenderTexture.hpp +++ b/include/Nazara/Renderer/RenderTexture.hpp @@ -27,7 +27,7 @@ class NAZARA_RENDERER_API NzRenderTexture : public NzRenderTarget public: inline NzRenderTexture(); NzRenderTexture(const NzRenderTexture&) = delete; - NzRenderTexture(NzRenderTexture&&) = delete; ///TODO + NzRenderTexture(NzRenderTexture&&) = delete; ///TODO? inline ~NzRenderTexture(); bool AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzRenderBuffer* buffer); @@ -61,7 +61,7 @@ class NAZARA_RENDERER_API NzRenderTexture : public NzRenderTarget bool HasContext() const override; NzRenderTexture& operator=(const NzRenderTexture&) = delete; - NzRenderTexture& operator=(NzRenderTexture&&) = delete; ///TODO + NzRenderTexture& operator=(NzRenderTexture&&) = delete; ///TODO? static inline void Blit(NzRenderTexture* src, NzRenderTexture* dst, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); static void Blit(NzRenderTexture* src, NzRectui srcRect, NzRenderTexture* dst, NzRectui dstRect, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); diff --git a/include/Nazara/Renderer/RenderWindow.hpp b/include/Nazara/Renderer/RenderWindow.hpp index 05d1c0163..e6db97e34 100644 --- a/include/Nazara/Renderer/RenderWindow.hpp +++ b/include/Nazara/Renderer/RenderWindow.hpp @@ -30,6 +30,8 @@ class NAZARA_RENDERER_API NzRenderWindow : public NzRenderTarget, public NzWindo NzRenderWindow() = default; NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default, const NzContextParameters& parameters = NzContextParameters()); NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters = NzContextParameters()); + NzRenderWindow(const NzRenderWindow&) = delete; + NzRenderWindow(NzRenderWindow&&) = delete; ///TODO virtual ~NzRenderWindow(); bool CopyToImage(NzAbstractImage* image, const NzVector3ui& dstPos = NzVector3ui(0U)) const; @@ -55,6 +57,9 @@ class NAZARA_RENDERER_API NzRenderWindow : public NzRenderTarget, public NzWindo NzContextParameters GetContextParameters() const; bool HasContext() const override; + NzRenderWindow& operator=(const NzRenderWindow&) = delete; + NzRenderWindow& operator=(NzRenderWindow&&) = delete; ///TODO + protected: bool Activate() const override; void EnsureTargetUpdated() const override; diff --git a/include/Nazara/Renderer/UberShader.hpp b/include/Nazara/Renderer/UberShader.hpp index 99258223e..c6df6f915 100644 --- a/include/Nazara/Renderer/UberShader.hpp +++ b/include/Nazara/Renderer/UberShader.hpp @@ -28,10 +28,15 @@ class NAZARA_RENDERER_API NzUberShader : public NzRefCounted public: NzUberShader() = default; + NzUberShader(const NzUberShader&) = delete; + NzUberShader(NzUberShader&&) = delete; virtual ~NzUberShader(); virtual NzUberShaderInstance* Get(const NzParameterList& parameters) const = 0; + NzUberShader& operator=(const NzUberShader&) = delete; + NzUberShader& operator=(NzUberShader&&) = delete; + // Signals: NazaraSignal(OnUberShaderRelease, const NzUberShader* /*uberShader*/); diff --git a/include/Nazara/Renderer/UberShaderInstance.hpp b/include/Nazara/Renderer/UberShaderInstance.hpp index d531d1926..e56f13d2f 100644 --- a/include/Nazara/Renderer/UberShaderInstance.hpp +++ b/include/Nazara/Renderer/UberShaderInstance.hpp @@ -14,12 +14,17 @@ class NAZARA_RENDERER_API NzUberShaderInstance { public: NzUberShaderInstance(const NzShader* shader); + NzUberShaderInstance(const NzUberShaderInstance&) = delete; + NzUberShaderInstance(NzUberShaderInstance&&) = delete; virtual ~NzUberShaderInstance(); virtual bool Activate() const = 0; const NzShader* GetShader() const; + NzUberShaderInstance& operator=(const NzUberShaderInstance&) = delete; + NzUberShaderInstance& operator=(NzUberShaderInstance&&) = delete; + protected: NzShaderConstRef m_shader; }; diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index 3add83482..663deafe2 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -15,11 +15,6 @@ NzParameterList::NzParameterList(const NzParameterList& list) operator=(list); } -NzParameterList::NzParameterList(NzParameterList&& list) : -m_parameters(std::move(list.m_parameters)) -{ -} - NzParameterList::~NzParameterList() { Clear(); @@ -421,12 +416,6 @@ NzParameterList& NzParameterList::operator=(const NzParameterList& list) return *this; } -NzParameterList& NzParameterList::operator=(NzParameterList&& list) -{ - m_parameters = std::move(list.m_parameters); - return *this; -} - void NzParameterList::DestroyValue(Parameter& parameter) { switch (parameter.type) diff --git a/src/Nazara/Core/Thread.cpp b/src/Nazara/Core/Thread.cpp index a25a6546e..a31025d68 100644 --- a/src/Nazara/Core/Thread.cpp +++ b/src/Nazara/Core/Thread.cpp @@ -24,7 +24,7 @@ m_impl(nullptr) { } -NzThread::NzThread(NzThread&& other) : +NzThread::NzThread(NzThread&& other) noexcept : m_impl(other.m_impl) { other.m_impl = nullptr; From c1831027844b50b9b1cffbe3afdf261f766b1941 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 24 Sep 2015 21:36:59 +0200 Subject: [PATCH 07/97] Examples: Fix HardwareInfo Former-commit-id: f11e0b1f012fedd2be903cc3da91af72ca036e10 --- examples/HardwareInfo/main.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/examples/HardwareInfo/main.cpp b/examples/HardwareInfo/main.cpp index bcc76c4c3..b93134031 100644 --- a/examples/HardwareInfo/main.cpp +++ b/examples/HardwareInfo/main.cpp @@ -82,14 +82,9 @@ int main() printCap(oss, "-Calculs 64bits", NzOpenGL::IsSupported(nzOpenGLExtension_FP64)); printCap(oss, "-Compression de textures (s3tc)", NzOpenGL::IsSupported(nzOpenGLExtension_TextureCompression_s3tc)); printCap(oss, "-Filtrage anisotrope", NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter)); - printCap(oss, "-Framebuffer Object", NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject)); printCap(oss, "-Mode debug", NzOpenGL::IsSupported(nzOpenGLExtension_DebugOutput)); - printCap(oss, "-Pixelbuffer Object", NzOpenGL::IsSupported(nzOpenGLExtension_PixelBufferObject)); - printCap(oss, "-Samplers Object", NzOpenGL::IsSupported(nzOpenGLExtension_SamplerObjects)); printCap(oss, "-Separate shader objects", NzOpenGL::IsSupported(nzOpenGLExtension_SeparateShaderObjects)); - printCap(oss, "-Texture array", NzOpenGL::IsSupported(nzOpenGLExtension_TextureArray)); printCap(oss, "-Texture storage", NzOpenGL::IsSupported(nzOpenGLExtension_TextureStorage)); - printCap(oss, "-Vertex array objects", NzOpenGL::IsSupported(nzOpenGLExtension_VertexArrayObjects)); } else oss << "Impossible de retrouver les informations de la carte graphique" << std::endl; From df8da275c416c27fa1e3c1ab8cf3dfe0eee819da Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 25 Sep 2015 19:20:05 +0200 Subject: [PATCH 08/97] Switch from Nz prefix to namespace Nz What a huge commit Former-commit-id: 38ac5eebf70adc1180f571f6006192d28fb99897 --- SDK/include/NDK/Application.inl | 2 +- SDK/include/NDK/BaseComponent.hpp | 4 +- SDK/include/NDK/BaseSystem.hpp | 10 +- .../NDK/Components/CameraComponent.hpp | 54 +- .../NDK/Components/CameraComponent.inl | 32 +- .../NDK/Components/CollisionComponent.hpp | 19 +- .../NDK/Components/CollisionComponent.inl | 8 +- .../NDK/Components/GraphicsComponent.hpp | 20 +- .../NDK/Components/GraphicsComponent.inl | 4 +- SDK/include/NDK/Components/LightComponent.hpp | 4 +- SDK/include/NDK/Components/LightComponent.inl | 6 +- SDK/include/NDK/Components/NodeComponent.hpp | 4 +- SDK/include/NDK/Components/NodeComponent.inl | 4 +- .../NDK/Components/PhysicsComponent.hpp | 34 +- .../NDK/Components/PhysicsComponent.inl | 32 +- .../NDK/Components/VelocityComponent.hpp | 6 +- .../NDK/Components/VelocityComponent.inl | 4 +- SDK/include/NDK/Entity.hpp | 8 +- SDK/include/NDK/Entity.inl | 4 +- SDK/include/NDK/EntityHandle.hpp | 2 +- SDK/include/NDK/EntityHandle.inl | 4 +- SDK/include/NDK/EntityList.hpp | 2 +- SDK/include/NDK/EntityList.inl | 2 +- SDK/include/NDK/Prerequesites.hpp | 8 +- SDK/include/NDK/Systems/PhysicsSystem.hpp | 6 +- SDK/include/NDK/Systems/PhysicsSystem.inl | 4 +- SDK/include/NDK/Systems/RenderSystem.hpp | 24 +- SDK/include/NDK/Systems/RenderSystem.inl | 24 +- SDK/include/NDK/World.hpp | 4 +- SDK/src/NDK/BaseSystem.cpp | 4 +- SDK/src/NDK/Components/CameraComponent.cpp | 34 +- SDK/src/NDK/Components/CollisionComponent.cpp | 6 +- SDK/src/NDK/Components/GraphicsComponent.cpp | 6 +- SDK/src/NDK/Components/PhysicsComponent.cpp | 10 +- SDK/src/NDK/Sdk.cpp | 28 +- SDK/src/NDK/Systems/ListenerSystem.cpp | 8 +- SDK/src/NDK/Systems/PhysicsSystem.cpp | 30 +- SDK/src/NDK/Systems/RenderSystem.cpp | 12 +- examples/HardwareInfo/main.cpp | 76 +- examples/MeshInfos/main.cpp | 34 +- include/Nazara/Audio/Algorithm.hpp | 5 +- include/Nazara/Audio/Algorithm.inl | 27 +- include/Nazara/Audio/Audio.hpp | 61 +- include/Nazara/Audio/Enums.hpp | 38 +- include/Nazara/Audio/Music.hpp | 85 +- include/Nazara/Audio/OpenAL.hpp | 287 +- include/Nazara/Audio/Sound.hpp | 59 +- include/Nazara/Audio/SoundBuffer.hpp | 123 +- include/Nazara/Audio/SoundBuffer.inl | 13 +- include/Nazara/Audio/SoundEmitter.hpp | 76 +- include/Nazara/Audio/SoundStream.hpp | 25 +- include/Nazara/Core/AbstractHash.hpp | 31 +- include/Nazara/Core/Algorithm.hpp | 13 +- include/Nazara/Core/Algorithm.inl | 74 +- include/Nazara/Core/Bitset.hpp | 233 +- include/Nazara/Core/Bitset.inl | 1381 +-- include/Nazara/Core/ByteArray.hpp | 195 +- include/Nazara/Core/ByteArray.inl | 507 +- include/Nazara/Core/CallOnExit.hpp | 31 +- include/Nazara/Core/CallOnExit.inl | 37 +- include/Nazara/Core/Clock.hpp | 51 +- include/Nazara/Core/Color.hpp | 85 +- include/Nazara/Core/Color.inl | 735 +- include/Nazara/Core/ConditionVariable.hpp | 39 +- include/Nazara/Core/Config.hpp | 14 +- include/Nazara/Core/Core.hpp | 23 +- include/Nazara/Core/Debug/NewRedefinition.hpp | 2 +- include/Nazara/Core/Directory.hpp | 77 +- include/Nazara/Core/DynLib.hpp | 45 +- include/Nazara/Core/Endianness.hpp | 7 +- include/Nazara/Core/Endianness.inl | 31 +- include/Nazara/Core/Enums.hpp | 289 +- include/Nazara/Core/Error.hpp | 47 +- include/Nazara/Core/ErrorFlags.hpp | 29 +- include/Nazara/Core/File.hpp | 133 +- include/Nazara/Core/Functor.hpp | 63 +- include/Nazara/Core/Functor.inl | 63 +- include/Nazara/Core/GuillotineBinPack.hpp | 111 +- include/Nazara/Core/HardwareInfo.hpp | 35 +- include/Nazara/Core/Hash.hpp | 29 +- include/Nazara/Core/Hash/CRC32.hpp | 31 +- include/Nazara/Core/Hash/Fletcher16.hpp | 31 +- include/Nazara/Core/Hash/MD5.hpp | 31 +- include/Nazara/Core/Hash/SHA1.hpp | 31 +- include/Nazara/Core/Hash/SHA224.hpp | 31 +- include/Nazara/Core/Hash/SHA256.hpp | 31 +- include/Nazara/Core/Hash/SHA384.hpp | 31 +- include/Nazara/Core/Hash/SHA512.hpp | 31 +- include/Nazara/Core/Hash/Whirlpool.hpp | 31 +- include/Nazara/Core/HashDigest.hpp | 57 +- include/Nazara/Core/Hashable.hpp | 37 +- include/Nazara/Core/Initializer.hpp | 35 +- include/Nazara/Core/Initializer.inl | 127 +- include/Nazara/Core/InputStream.hpp | 19 +- include/Nazara/Core/LockGuard.hpp | 21 +- include/Nazara/Core/Log.hpp | 61 +- include/Nazara/Core/MemoryHelper.hpp | 11 +- include/Nazara/Core/MemoryHelper.inl | 41 +- include/Nazara/Core/MemoryManager.hpp | 41 +- include/Nazara/Core/MemoryPool.hpp | 55 +- include/Nazara/Core/MemoryPool.inl | 231 +- include/Nazara/Core/MemoryStream.hpp | 39 +- include/Nazara/Core/Mutex.hpp | 37 +- include/Nazara/Core/ObjectLibrary.hpp | 35 +- include/Nazara/Core/ObjectLibrary.inl | 83 +- include/Nazara/Core/ObjectRef.hpp | 53 +- include/Nazara/Core/ObjectRef.inl | 243 +- include/Nazara/Core/OffsetOf.hpp | 20 +- include/Nazara/Core/ParameterList.hpp | 127 +- include/Nazara/Core/PluginManager.hpp | 41 +- include/Nazara/Core/Primitive.hpp | 157 +- include/Nazara/Core/Primitive.inl | 317 +- include/Nazara/Core/PrimitiveList.hpp | 61 +- include/Nazara/Core/RefCounted.hpp | 37 +- include/Nazara/Core/Resource.hpp | 29 +- include/Nazara/Core/ResourceLoader.hpp | 49 +- include/Nazara/Core/ResourceLoader.inl | 447 +- include/Nazara/Core/ResourceManager.hpp | 41 +- include/Nazara/Core/ResourceManager.inl | 151 +- include/Nazara/Core/Semaphore.hpp | 37 +- include/Nazara/Core/Signal.hpp | 170 +- include/Nazara/Core/Signal.inl | 435 +- include/Nazara/Core/SparsePtr.hpp | 97 +- include/Nazara/Core/SparsePtr.inl | 395 +- include/Nazara/Core/Stream.hpp | 37 +- include/Nazara/Core/String.hpp | 509 +- include/Nazara/Core/String.inl | 44 +- include/Nazara/Core/StringStream.hpp | 67 +- include/Nazara/Core/TaskScheduler.hpp | 35 +- include/Nazara/Core/TaskScheduler.inl | 29 +- include/Nazara/Core/Thread.hpp | 81 +- include/Nazara/Core/Thread.inl | 29 +- include/Nazara/Core/ThreadSafety.hpp | 8 +- include/Nazara/Core/Unicode.hpp | 173 +- include/Nazara/Core/Updatable.hpp | 15 +- .../Nazara/Graphics/AbstractBackground.hpp | 43 +- .../Nazara/Graphics/AbstractRenderQueue.hpp | 141 +- .../Graphics/AbstractRenderTechnique.hpp | 45 +- include/Nazara/Graphics/AbstractViewer.hpp | 48 +- include/Nazara/Graphics/Billboard.hpp | 79 +- include/Nazara/Graphics/Billboard.inl | 259 +- include/Nazara/Graphics/ColorBackground.hpp | 49 +- include/Nazara/Graphics/ColorBackground.inl | 13 +- include/Nazara/Graphics/DeferredBloomPass.hpp | 63 +- include/Nazara/Graphics/DeferredDOFPass.hpp | 35 +- include/Nazara/Graphics/DeferredFXAAPass.hpp | 23 +- include/Nazara/Graphics/DeferredFinalPass.hpp | 29 +- include/Nazara/Graphics/DeferredFogPass.hpp | 25 +- .../Nazara/Graphics/DeferredForwardPass.hpp | 25 +- .../Nazara/Graphics/DeferredGeometryPass.hpp | 47 +- .../Graphics/DeferredPhongLightingPass.hpp | 55 +- .../Nazara/Graphics/DeferredRenderPass.hpp | 67 +- .../Nazara/Graphics/DeferredRenderQueue.hpp | 99 +- .../Graphics/DeferredRenderTechnique.hpp | 79 +- include/Nazara/Graphics/Drawable.hpp | 15 +- include/Nazara/Graphics/Enums.hpp | 221 +- .../Nazara/Graphics/ForwardRenderQueue.hpp | 217 +- .../Graphics/ForwardRenderTechnique.hpp | 121 +- .../Graphics/ForwardRenderTechnique.inl | 155 +- include/Nazara/Graphics/Graphics.hpp | 23 +- .../Graphics/GuillotineTextureAtlas.hpp | 19 +- .../Nazara/Graphics/InstancedRenderable.hpp | 97 +- .../Nazara/Graphics/InstancedRenderable.inl | 59 +- include/Nazara/Graphics/Light.hpp | 149 +- include/Nazara/Graphics/Light.inl | 155 +- include/Nazara/Graphics/Material.hpp | 285 +- include/Nazara/Graphics/Material.inl | 13 +- include/Nazara/Graphics/Model.hpp | 111 +- include/Nazara/Graphics/Model.inl | 13 +- .../Nazara/Graphics/ParticleController.hpp | 49 +- .../Nazara/Graphics/ParticleDeclaration.hpp | 89 +- include/Nazara/Graphics/ParticleEmitter.hpp | 53 +- include/Nazara/Graphics/ParticleGenerator.hpp | 49 +- include/Nazara/Graphics/ParticleMapper.hpp | 23 +- include/Nazara/Graphics/ParticleMapper.inl | 71 +- include/Nazara/Graphics/ParticleRenderer.hpp | 51 +- include/Nazara/Graphics/ParticleStruct.hpp | 49 +- include/Nazara/Graphics/ParticleSystem.hpp | 103 +- include/Nazara/Graphics/RenderTechniques.hpp | 35 +- include/Nazara/Graphics/Renderable.hpp | 49 +- include/Nazara/Graphics/Renderable.inl | 27 +- include/Nazara/Graphics/SceneData.hpp | 19 +- include/Nazara/Graphics/SkeletalModel.hpp | 103 +- include/Nazara/Graphics/SkinningManager.hpp | 43 +- include/Nazara/Graphics/SkyboxBackground.hpp | 51 +- include/Nazara/Graphics/SkyboxBackground.inl | 57 +- include/Nazara/Graphics/Sprite.hpp | 81 +- include/Nazara/Graphics/Sprite.inl | 305 +- include/Nazara/Graphics/TextSprite.hpp | 103 +- include/Nazara/Graphics/TextSprite.inl | 237 +- include/Nazara/Graphics/TextureBackground.hpp | 45 +- include/Nazara/Graphics/TextureBackground.inl | 31 +- include/Nazara/Lua/Lua.hpp | 23 +- include/Nazara/Lua/LuaClass.hpp | 101 +- include/Nazara/Lua/LuaClass.inl | 657 +- include/Nazara/Lua/LuaInstance.hpp | 253 +- include/Nazara/Lua/LuaInstance.inl | 315 +- include/Nazara/Math/Algorithm.hpp | 61 +- include/Nazara/Math/Algorithm.inl | 843 +- include/Nazara/Math/BoundingVolume.hpp | 87 +- include/Nazara/Math/BoundingVolume.inl | 575 +- include/Nazara/Math/Box.hpp | 132 +- include/Nazara/Math/Box.inl | 999 +-- include/Nazara/Math/Enums.hpp | 89 +- include/Nazara/Math/EulerAngles.hpp | 79 +- include/Nazara/Math/EulerAngles.inl | 319 +- include/Nazara/Math/Frustum.hpp | 71 +- include/Nazara/Math/Frustum.inl | 889 +- include/Nazara/Math/Matrix4.hpp | 214 +- include/Nazara/Math/Matrix4.inl | 2093 ++--- include/Nazara/Math/OrientedBox.hpp | 81 +- include/Nazara/Math/OrientedBox.inl | 423 +- include/Nazara/Math/Plane.hpp | 73 +- include/Nazara/Math/Plane.inl | 337 +- include/Nazara/Math/Quaternion.hpp | 123 +- include/Nazara/Math/Quaternion.inl | 895 +- include/Nazara/Math/Ray.hpp | 89 +- include/Nazara/Math/Ray.inl | 787 +- include/Nazara/Math/Rect.hpp | 127 +- include/Nazara/Math/Rect.inl | 843 +- include/Nazara/Math/Sphere.hpp | 104 +- include/Nazara/Math/Sphere.inl | 643 +- include/Nazara/Math/Vector2.hpp | 159 +- include/Nazara/Math/Vector2.inl | 873 +- include/Nazara/Math/Vector3.hpp | 199 +- include/Nazara/Math/Vector3.inl | 1237 +-- include/Nazara/Math/Vector4.hpp | 155 +- include/Nazara/Math/Vector4.inl | 971 +-- include/Nazara/Noise/Abstract2DNoise.hpp | 17 +- include/Nazara/Noise/Abstract3DNoise.hpp | 17 +- include/Nazara/Noise/Abstract4DNoise.hpp | 17 +- include/Nazara/Noise/ComplexNoiseBase.hpp | 43 +- include/Nazara/Noise/FBM2D.hpp | 25 +- include/Nazara/Noise/FBM3D.hpp | 25 +- include/Nazara/Noise/FBM4D.hpp | 25 +- include/Nazara/Noise/HybridMultiFractal3D.hpp | 34 +- include/Nazara/Noise/HybridMultiFractal4D.hpp | 34 +- include/Nazara/Noise/HybridMultifractal2D.hpp | 32 +- include/Nazara/Noise/MappedNoiseBase.hpp | 34 +- include/Nazara/Noise/Noise.hpp | 23 +- include/Nazara/Noise/NoiseBase.hpp | 49 +- include/Nazara/Noise/Perlin2D.hpp | 38 +- include/Nazara/Noise/Perlin3D.hpp | 42 +- include/Nazara/Noise/Perlin4D.hpp | 40 +- include/Nazara/Noise/Simplex2D.hpp | 44 +- include/Nazara/Noise/Simplex3D.hpp | 44 +- include/Nazara/Noise/Simplex4D.hpp | 48 +- include/Nazara/Physics/Enums.hpp | 26 +- include/Nazara/Physics/Geom.hpp | 340 +- include/Nazara/Physics/Geom.inl | 111 +- include/Nazara/Physics/PhysObject.hpp | 102 +- include/Nazara/Physics/PhysWorld.hpp | 45 +- include/Nazara/Physics/Physics.hpp | 25 +- include/Nazara/Prerequesites.hpp | 19 +- include/Nazara/Renderer/Context.hpp | 87 +- include/Nazara/Renderer/ContextParameters.hpp | 77 +- include/Nazara/Renderer/DebugDrawer.hpp | 67 +- include/Nazara/Renderer/Enums.hpp | 437 +- include/Nazara/Renderer/GpuQuery.hpp | 43 +- include/Nazara/Renderer/OpenGL.hpp | 223 +- include/Nazara/Renderer/RenderBuffer.hpp | 79 +- include/Nazara/Renderer/RenderBuffer.inl | 13 +- include/Nazara/Renderer/RenderStates.hpp | 55 +- include/Nazara/Renderer/RenderStates.inl | 75 +- include/Nazara/Renderer/RenderTarget.hpp | 59 +- .../Renderer/RenderTargetParameters.hpp | 23 +- include/Nazara/Renderer/RenderTexture.hpp | 119 +- include/Nazara/Renderer/RenderTexture.inl | 69 +- include/Nazara/Renderer/RenderWindow.hpp | 89 +- include/Nazara/Renderer/Renderer.hpp | 173 +- include/Nazara/Renderer/Shader.hpp | 167 +- include/Nazara/Renderer/Shader.inl | 13 +- include/Nazara/Renderer/ShaderStage.hpp | 57 +- include/Nazara/Renderer/Texture.hpp | 173 +- include/Nazara/Renderer/Texture.inl | 15 +- include/Nazara/Renderer/TextureSampler.hpp | 77 +- include/Nazara/Renderer/UberShader.hpp | 51 +- .../Nazara/Renderer/UberShaderInstance.hpp | 26 +- .../UberShaderInstancePreprocessor.hpp | 15 +- .../Renderer/UberShaderPreprocessor.hpp | 61 +- .../Renderer/UberShaderPreprocessor.inl | 13 +- include/Nazara/Utility/AbstractAtlas.hpp | 39 +- include/Nazara/Utility/AbstractBuffer.hpp | 25 +- include/Nazara/Utility/AbstractImage.hpp | 45 +- include/Nazara/Utility/AbstractTextDrawer.hpp | 47 +- include/Nazara/Utility/Algorithm.hpp | 65 +- include/Nazara/Utility/Animation.hpp | 147 +- include/Nazara/Utility/Animation.inl | 13 +- include/Nazara/Utility/Buffer.hpp | 101 +- include/Nazara/Utility/Buffer.inl | 13 +- include/Nazara/Utility/BufferMapper.hpp | 43 +- include/Nazara/Utility/BufferMapper.inl | 225 +- include/Nazara/Utility/CubemapParams.hpp | 41 +- include/Nazara/Utility/Cursor.hpp | 33 +- include/Nazara/Utility/Enums.hpp | 547 +- include/Nazara/Utility/Event.hpp | 173 +- include/Nazara/Utility/Font.hpp | 243 +- include/Nazara/Utility/Font.inl | 13 +- include/Nazara/Utility/FontData.hpp | 37 +- include/Nazara/Utility/FontGlyph.hpp | 13 +- .../Nazara/Utility/Formats/MD5AnimParser.hpp | 105 +- .../Nazara/Utility/Formats/MD5MeshParser.hpp | 109 +- include/Nazara/Utility/Formats/MTLParser.hpp | 79 +- include/Nazara/Utility/Formats/OBJParser.hpp | 101 +- .../Nazara/Utility/GuillotineImageAtlas.hpp | 77 +- include/Nazara/Utility/Icon.hpp | 31 +- include/Nazara/Utility/Image.hpp | 251 +- include/Nazara/Utility/Image.inl | 13 +- include/Nazara/Utility/Image.inl.save-failed | 20 + include/Nazara/Utility/IndexBuffer.hpp | 97 +- include/Nazara/Utility/IndexBuffer.inl | 13 +- include/Nazara/Utility/IndexIterator.hpp | 93 +- include/Nazara/Utility/IndexIterator.inl | 239 +- include/Nazara/Utility/IndexMapper.hpp | 61 +- include/Nazara/Utility/Joint.hpp | 51 +- include/Nazara/Utility/Joystick.hpp | 17 +- include/Nazara/Utility/Keyboard.hpp | 287 +- include/Nazara/Utility/Mesh.hpp | 207 +- include/Nazara/Utility/Mesh.inl | 13 +- include/Nazara/Utility/MeshData.hpp | 19 +- include/Nazara/Utility/Mouse.hpp | 49 +- include/Nazara/Utility/Node.hpp | 183 +- include/Nazara/Utility/PixelFormat.hpp | 51 +- include/Nazara/Utility/PixelFormat.inl | 1309 +-- include/Nazara/Utility/Sequence.hpp | 27 +- include/Nazara/Utility/SimpleTextDrawer.hpp | 93 +- include/Nazara/Utility/SkeletalMesh.hpp | 63 +- include/Nazara/Utility/SkeletalMesh.inl | 13 +- include/Nazara/Utility/Skeleton.hpp | 93 +- include/Nazara/Utility/Skeleton.inl | 13 +- include/Nazara/Utility/StaticMesh.hpp | 67 +- include/Nazara/Utility/StaticMesh.inl | 13 +- include/Nazara/Utility/SubMesh.hpp | 67 +- include/Nazara/Utility/TriangleIterator.hpp | 37 +- include/Nazara/Utility/Utility.hpp | 27 +- include/Nazara/Utility/VertexBuffer.hpp | 95 +- include/Nazara/Utility/VertexBuffer.inl | 13 +- include/Nazara/Utility/VertexDeclaration.hpp | 93 +- include/Nazara/Utility/VertexDeclaration.inl | 13 +- include/Nazara/Utility/VertexMapper.hpp | 27 +- include/Nazara/Utility/VertexMapper.inl | 41 +- include/Nazara/Utility/VertexStruct.hpp | 109 +- include/Nazara/Utility/VideoMode.hpp | 37 +- include/Nazara/Utility/Window.hpp | 155 +- include/Nazara/Utility/WindowHandle.hpp | 23 +- src/Nazara/Audio/Audio.cpp | 411 +- src/Nazara/Audio/Formats/sndfileLoader.cpp | 664 +- src/Nazara/Audio/Formats/sndfileLoader.hpp | 10 +- src/Nazara/Audio/Music.cpp | 541 +- src/Nazara/Audio/OpenAL.cpp | 835 +- src/Nazara/Audio/Sound.cpp | 281 +- src/Nazara/Audio/SoundBuffer.cpp | 425 +- src/Nazara/Audio/SoundEmitter.cpp | 283 +- src/Nazara/Audio/SoundStream.cpp | 5 +- src/Nazara/Core/AbstractHash.cpp | 5 +- src/Nazara/Core/ByteArray.cpp | 19 +- src/Nazara/Core/Clock.cpp | 157 +- src/Nazara/Core/Color.cpp | 21 +- src/Nazara/Core/ConditionVariable.cpp | 51 +- src/Nazara/Core/Core.cpp | 63 +- src/Nazara/Core/Debug/NewOverload.cpp | 8 +- src/Nazara/Core/Debug/NewRedefinition.cpp | 12 +- src/Nazara/Core/Directory.cpp | 613 +- src/Nazara/Core/DynLib.cpp | 159 +- src/Nazara/Core/Error.cpp | 211 +- src/Nazara/Core/ErrorFlags.cpp | 37 +- src/Nazara/Core/File.cpp | 1301 +-- src/Nazara/Core/GuillotineBinPack.cpp | 789 +- src/Nazara/Core/HardwareInfo.cpp | 411 +- src/Nazara/Core/Hash.cpp | 107 +- src/Nazara/Core/Hash/CRC32.cpp | 225 +- src/Nazara/Core/Hash/Fletcher16.cpp | 117 +- src/Nazara/Core/Hash/MD5.cpp | 516 +- src/Nazara/Core/Hash/SHA/Internal.cpp | 1808 ++-- src/Nazara/Core/Hash/SHA/Internal.hpp | 79 +- src/Nazara/Core/Hash/SHA1.cpp | 77 +- src/Nazara/Core/Hash/SHA224.cpp | 77 +- src/Nazara/Core/Hash/SHA256.cpp | 77 +- src/Nazara/Core/Hash/SHA384.cpp | 77 +- src/Nazara/Core/Hash/SHA512.cpp | 77 +- src/Nazara/Core/Hash/Whirlpool.cpp | 1859 ++-- src/Nazara/Core/HashDigest.cpp | 309 +- src/Nazara/Core/Hashable.cpp | 23 +- src/Nazara/Core/InputStream.cpp | 87 +- src/Nazara/Core/LockGuard.cpp | 17 +- src/Nazara/Core/Log.cpp | 245 +- src/Nazara/Core/MemoryManager.cpp | 613 +- src/Nazara/Core/MemoryStream.cpp | 87 +- src/Nazara/Core/Mutex.cpp | 39 +- src/Nazara/Core/ParameterList.cpp | 827 +- src/Nazara/Core/PluginManager.cpp | 295 +- src/Nazara/Core/PrimitiveList.cpp | 199 +- src/Nazara/Core/RefCounted.cpp | 108 +- src/Nazara/Core/Resource.cpp | 19 +- src/Nazara/Core/Semaphore.cpp | 47 +- src/Nazara/Core/Stream.cpp | 35 +- src/Nazara/Core/String.cpp | 7550 +++++++++-------- src/Nazara/Core/StringStream.cpp | 339 +- src/Nazara/Core/TaskScheduler.cpp | 123 +- src/Nazara/Core/Thread.cpp | 237 +- src/Nazara/Core/Unicode.cpp | 643 +- src/Nazara/Core/Updatable.cpp | 5 +- src/Nazara/Core/Win32/ClockImpl.cpp | 63 +- src/Nazara/Core/Win32/ClockImpl.hpp | 9 +- .../Core/Win32/ConditionVariableImpl.cpp | 138 +- .../Core/Win32/ConditionVariableImpl.hpp | 58 +- src/Nazara/Core/Win32/DirectoryImpl.cpp | 199 +- src/Nazara/Core/Win32/DirectoryImpl.hpp | 55 +- src/Nazara/Core/Win32/DynLibImpl.cpp | 62 +- src/Nazara/Core/Win32/DynLibImpl.hpp | 35 +- src/Nazara/Core/Win32/FileImpl.cpp | 507 +- src/Nazara/Core/Win32/FileImpl.hpp | 67 +- src/Nazara/Core/Win32/HardwareInfoImpl.cpp | 155 +- src/Nazara/Core/Win32/HardwareInfoImpl.hpp | 17 +- src/Nazara/Core/Win32/MutexImpl.cpp | 47 +- src/Nazara/Core/Win32/MutexImpl.hpp | 25 +- src/Nazara/Core/Win32/SemaphoreImpl.cpp | 103 +- src/Nazara/Core/Win32/SemaphoreImpl.hpp | 25 +- src/Nazara/Core/Win32/TaskSchedulerImpl.cpp | 401 +- src/Nazara/Core/Win32/TaskSchedulerImpl.hpp | 51 +- src/Nazara/Core/Win32/ThreadImpl.cpp | 73 +- src/Nazara/Core/Win32/ThreadImpl.hpp | 27 +- src/Nazara/Core/Win32/Time.cpp | 29 +- src/Nazara/Core/Win32/Time.hpp | 5 +- src/Nazara/Graphics/AbstractBackground.cpp | 7 +- src/Nazara/Graphics/AbstractRenderQueue.cpp | 41 +- .../Graphics/AbstractRenderTechnique.cpp | 57 +- src/Nazara/Graphics/AbstractViewer.cpp | 5 +- src/Nazara/Graphics/Billboard.cpp | 29 +- src/Nazara/Graphics/ColorBackground.cpp | 114 +- src/Nazara/Graphics/DeferredBloomPass.cpp | 283 +- src/Nazara/Graphics/DeferredDOFPass.cpp | 323 +- src/Nazara/Graphics/DeferredFXAAPass.cpp | 53 +- src/Nazara/Graphics/DeferredFinalPass.cpp | 81 +- src/Nazara/Graphics/DeferredFogPass.cpp | 269 +- src/Nazara/Graphics/DeferredForwardPass.cpp | 55 +- src/Nazara/Graphics/DeferredGeometryPass.cpp | 411 +- .../Graphics/DeferredPhongLightingPass.cpp | 459 +- src/Nazara/Graphics/DeferredRenderPass.cpp | 77 +- src/Nazara/Graphics/DeferredRenderQueue.cpp | 349 +- .../Graphics/DeferredRenderTechnique.cpp | 981 +-- src/Nazara/Graphics/Drawable.cpp | 5 +- src/Nazara/Graphics/Formats/MeshLoader.cpp | 177 +- src/Nazara/Graphics/Formats/MeshLoader.hpp | 10 +- src/Nazara/Graphics/Formats/OBJLoader.cpp | 524 +- src/Nazara/Graphics/Formats/OBJLoader.hpp | 10 +- src/Nazara/Graphics/Formats/TextureLoader.cpp | 66 +- src/Nazara/Graphics/Formats/TextureLoader.hpp | 10 +- src/Nazara/Graphics/ForwardRenderQueue.cpp | 1183 +-- .../Graphics/ForwardRenderTechnique.cpp | 1277 +-- src/Nazara/Graphics/Graphics.cpp | 293 +- .../Graphics/GuillotineTextureAtlas.cpp | 63 +- src/Nazara/Graphics/InstancedRenderable.cpp | 71 +- src/Nazara/Graphics/Light.cpp | 293 +- src/Nazara/Graphics/Material.cpp | 1515 ++-- src/Nazara/Graphics/Model.cpp | 603 +- src/Nazara/Graphics/ParticleController.cpp | 47 +- src/Nazara/Graphics/ParticleDeclaration.cpp | 403 +- src/Nazara/Graphics/ParticleEmitter.cpp | 121 +- src/Nazara/Graphics/ParticleGenerator.cpp | 47 +- src/Nazara/Graphics/ParticleMapper.cpp | 14 +- src/Nazara/Graphics/ParticleRenderer.cpp | 47 +- src/Nazara/Graphics/ParticleSystem.cpp | 556 +- src/Nazara/Graphics/RenderTechniques.cpp | 265 +- src/Nazara/Graphics/Renderable.cpp | 37 +- src/Nazara/Graphics/SkeletalModel.cpp | 455 +- src/Nazara/Graphics/SkinningManager.cpp | 337 +- src/Nazara/Graphics/SkyboxBackground.cpp | 281 +- src/Nazara/Graphics/Sprite.cpp | 79 +- src/Nazara/Graphics/TextSprite.cpp | 437 +- src/Nazara/Graphics/TextureBackground.cpp | 107 +- src/Nazara/Lua/Lua.cpp | 75 +- src/Nazara/Lua/LuaInstance.cpp | 1665 ++-- src/Nazara/Noise/Abstract2DNoise.cpp | 19 +- src/Nazara/Noise/Abstract3DNoise.cpp | 19 +- src/Nazara/Noise/Abstract4DNoise.cpp | 19 +- src/Nazara/Noise/ComplexNoiseBase.cpp | 129 +- src/Nazara/Noise/FBM2D.cpp | 65 +- src/Nazara/Noise/FBM3D.cpp | 65 +- src/Nazara/Noise/FBM4D.cpp | 65 +- src/Nazara/Noise/HybridMultiFractal3D.cpp | 83 +- src/Nazara/Noise/HybridMultiFractal4D.cpp | 83 +- src/Nazara/Noise/HybridMultifractal2D.cpp | 83 +- src/Nazara/Noise/MappedNoiseBase.cpp | 75 +- src/Nazara/Noise/Noise.cpp | 79 +- src/Nazara/Noise/NoiseBase.cpp | 127 +- src/Nazara/Noise/Perlin2D.cpp | 121 +- src/Nazara/Noise/Perlin3D.cpp | 169 +- src/Nazara/Noise/Perlin4D.cpp | 283 +- src/Nazara/Noise/Simplex2D.cpp | 139 +- src/Nazara/Noise/Simplex3D.cpp | 311 +- src/Nazara/Noise/Simplex4D.cpp | 303 +- src/Nazara/Physics/Geom.cpp | 771 +- src/Nazara/Physics/PhysObject.cpp | 663 +- src/Nazara/Physics/PhysWorld.cpp | 103 +- src/Nazara/Physics/Physics.cpp | 85 +- src/Nazara/Renderer/Context.cpp | 659 +- src/Nazara/Renderer/ContextParameters.cpp | 39 +- src/Nazara/Renderer/DebugDrawer.cpp | 1375 +-- src/Nazara/Renderer/GpuQuery.cpp | 221 +- src/Nazara/Renderer/HardwareBuffer.cpp | 213 +- src/Nazara/Renderer/HardwareBuffer.hpp | 39 +- src/Nazara/Renderer/OpenGL.cpp | 4203 ++++----- src/Nazara/Renderer/RenderBuffer.cpp | 215 +- src/Nazara/Renderer/RenderTarget.cpp | 39 +- src/Nazara/Renderer/RenderTexture.cpp | 1465 ++-- src/Nazara/Renderer/RenderWindow.cpp | 486 +- src/Nazara/Renderer/Renderer.cpp | 3831 ++++----- src/Nazara/Renderer/Shader.cpp | 1527 ++-- src/Nazara/Renderer/ShaderStage.cpp | 421 +- src/Nazara/Renderer/Texture.cpp | 2427 +++--- src/Nazara/Renderer/TextureSampler.cpp | 681 +- src/Nazara/Renderer/UberShader.cpp | 35 +- src/Nazara/Renderer/UberShaderInstance.cpp | 17 +- .../UberShaderInstancePreprocessor.cpp | 25 +- .../Renderer/UberShaderPreprocessor.cpp | 291 +- src/Nazara/Renderer/Win32/ContextImpl.cpp | 391 +- src/Nazara/Renderer/Win32/ContextImpl.hpp | 33 +- src/Nazara/Utility/AbstractAtlas.cpp | 7 +- src/Nazara/Utility/AbstractBuffer.cpp | 5 +- src/Nazara/Utility/AbstractImage.cpp | 27 +- src/Nazara/Utility/AbstractTextDrawer.cpp | 5 +- src/Nazara/Utility/Algorithm.cpp | 1995 ++--- src/Nazara/Utility/Animation.cpp | 1019 +-- src/Nazara/Utility/Buffer.cpp | 507 +- src/Nazara/Utility/Cursor.cpp | 81 +- src/Nazara/Utility/Font.cpp | 1063 +-- src/Nazara/Utility/FontData.cpp | 5 +- src/Nazara/Utility/Formats/DDSConstants.hpp | 64 +- src/Nazara/Utility/Formats/DDSLoader.cpp | 194 +- src/Nazara/Utility/Formats/DDSLoader.hpp | 10 +- src/Nazara/Utility/Formats/FreeTypeLoader.cpp | 820 +- src/Nazara/Utility/Formats/FreeTypeLoader.hpp | 10 +- src/Nazara/Utility/Formats/MD2Constants.cpp | 335 +- src/Nazara/Utility/Formats/MD2Constants.hpp | 81 +- src/Nazara/Utility/Formats/MD2Loader.cpp | 406 +- src/Nazara/Utility/Formats/MD2Loader.hpp | 10 +- src/Nazara/Utility/Formats/MD5AnimLoader.cpp | 150 +- src/Nazara/Utility/Formats/MD5AnimLoader.hpp | 10 +- src/Nazara/Utility/Formats/MD5AnimParser.cpp | 865 +- src/Nazara/Utility/Formats/MD5MeshLoader.cpp | 516 +- src/Nazara/Utility/Formats/MD5MeshLoader.hpp | 10 +- src/Nazara/Utility/Formats/MD5MeshParser.cpp | 689 +- src/Nazara/Utility/Formats/MTLParser.cpp | 621 +- src/Nazara/Utility/Formats/OBJParser.cpp | 775 +- src/Nazara/Utility/Formats/PCXLoader.cpp | 496 +- src/Nazara/Utility/Formats/PCXLoader.hpp | 10 +- src/Nazara/Utility/Formats/STBLoader.cpp | 140 +- src/Nazara/Utility/Formats/STBLoader.hpp | 10 +- src/Nazara/Utility/GuillotineImageAtlas.cpp | 443 +- src/Nazara/Utility/Icon.cpp | 71 +- src/Nazara/Utility/Image.cpp | 2563 +++--- src/Nazara/Utility/IndexBuffer.cpp | 437 +- src/Nazara/Utility/IndexMapper.cpp | 231 +- src/Nazara/Utility/Joint.cpp | 155 +- src/Nazara/Utility/Keyboard.cpp | 15 +- src/Nazara/Utility/Mesh.cpp | 1898 ++--- src/Nazara/Utility/Mouse.cpp | 79 +- src/Nazara/Utility/Node.cpp | 1303 +-- src/Nazara/Utility/PixelFormat.cpp | 2331 ++--- src/Nazara/Utility/SimpleTextDrawer.cpp | 679 +- src/Nazara/Utility/SkeletalMesh.cpp | 163 +- src/Nazara/Utility/Skeleton.cpp | 751 +- src/Nazara/Utility/SoftwareBuffer.cpp | 149 +- src/Nazara/Utility/SoftwareBuffer.hpp | 33 +- src/Nazara/Utility/StaticMesh.cpp | 207 +- src/Nazara/Utility/SubMesh.cpp | 339 +- src/Nazara/Utility/TriangleIterator.cpp | 119 +- src/Nazara/Utility/Utility.cpp | 337 +- src/Nazara/Utility/VertexBuffer.cpp | 475 +- src/Nazara/Utility/VertexDeclaration.cpp | 509 +- src/Nazara/Utility/VertexMapper.cpp | 59 +- src/Nazara/Utility/VideoMode.cpp | 141 +- src/Nazara/Utility/VideoModeImpl.hpp | 8 +- src/Nazara/Utility/Win32/CursorImpl.cpp | 73 +- src/Nazara/Utility/Win32/CursorImpl.hpp | 23 +- src/Nazara/Utility/Win32/IconImpl.cpp | 69 +- src/Nazara/Utility/Win32/IconImpl.hpp | 23 +- src/Nazara/Utility/Win32/InputImpl.cpp | 523 +- src/Nazara/Utility/Win32/InputImpl.hpp | 23 +- src/Nazara/Utility/Win32/VideoModeImpl.cpp | 37 +- src/Nazara/Utility/Win32/VideoModeImpl.hpp | 13 +- src/Nazara/Utility/Win32/WindowImpl.cpp | 2115 ++--- src/Nazara/Utility/Win32/WindowImpl.hpp | 166 +- src/Nazara/Utility/Window.cpp | 1339 +-- src/Nazara/Utility/X11/ScopedXCB.inl | 59 +- tests/Engine/Core/ByteArray.cpp | 60 +- tests/Engine/Core/Clock.cpp | 6 +- tests/Engine/Core/Color.cpp | 12 +- tests/Engine/Core/Directory.cpp | 10 +- tests/Engine/Core/Error.cpp | 22 +- tests/Engine/Core/File.cpp | 14 +- tests/Engine/Core/String.cpp | 20 +- tests/Engine/Core/StringStream.cpp | 48 +- tests/Engine/Math/Algorithm.cpp | 60 +- tests/Engine/Math/BoundingVolume.cpp | 22 +- tests/Engine/Math/Box.cpp | 52 +- tests/Engine/Math/EulerAngles.cpp | 34 +- tests/Engine/Math/Frustum.cpp | 76 +- tests/Engine/Math/Matrix4.cpp | 58 +- tests/Engine/Math/OrientedBox.cpp | 14 +- tests/Engine/Math/Plane.cpp | 28 +- tests/Engine/Math/Quaternion.cpp | 68 +- tests/Engine/Math/Ray.cpp | 72 +- tests/Engine/Math/Rect.cpp | 26 +- tests/Engine/Math/Sphere.cpp | 34 +- tests/Engine/Math/Vector2.cpp | 10 +- tests/Engine/Math/Vector3.cpp | 12 +- tests/Engine/Math/Vector4.cpp | 12 +- 609 files changed, 68265 insertions(+), 66534 deletions(-) create mode 100644 include/Nazara/Utility/Image.inl.save-failed diff --git a/SDK/include/NDK/Application.inl b/SDK/include/NDK/Application.inl index a09d1d610..dafbd54d8 100644 --- a/SDK/include/NDK/Application.inl +++ b/SDK/include/NDK/Application.inl @@ -9,7 +9,7 @@ namespace Ndk { inline Application::Application() { - NzErrorFlags errFlags(nzErrorFlag_ThrowException, true); + Nz::ErrorFlags errFlags(Nz::ErrorFlag_ThrowException, true); // Initialisation du SDK Sdk::Initialize(); diff --git a/SDK/include/NDK/BaseComponent.hpp b/SDK/include/NDK/BaseComponent.hpp index e8fc59c14..be738b737 100644 --- a/SDK/include/NDK/BaseComponent.hpp +++ b/SDK/include/NDK/BaseComponent.hpp @@ -24,7 +24,7 @@ namespace Ndk BaseComponent(ComponentIndex componentIndex); BaseComponent(const BaseComponent&) = default; - BaseComponent(BaseComponent&&) noexcept = default; + BaseComponent(BaseComponent&&) = default; virtual ~BaseComponent(); virtual BaseComponent* Clone() const = 0; @@ -32,7 +32,7 @@ namespace Ndk ComponentIndex GetIndex() const; BaseComponent& operator=(const BaseComponent&) = default; - BaseComponent& operator=(BaseComponent&&) noexcept = default; + BaseComponent& operator=(BaseComponent&&) = default; protected: ComponentIndex m_componentIndex; diff --git a/SDK/include/NDK/BaseSystem.hpp b/SDK/include/NDK/BaseSystem.hpp index 202095be4..0cb66b3b4 100644 --- a/SDK/include/NDK/BaseSystem.hpp +++ b/SDK/include/NDK/BaseSystem.hpp @@ -79,11 +79,11 @@ namespace Ndk static inline void Uninitialize(); std::vector m_entities; - NzBitset m_entityBits; - NzBitset<> m_excludedComponents; - mutable NzBitset<> m_filterResult; - NzBitset<> m_requiredAnyComponents; - NzBitset<> m_requiredComponents; + Nz::Bitset m_entityBits; + Nz::Bitset<> m_excludedComponents; + mutable Nz::Bitset<> m_filterResult; + Nz::Bitset<> m_requiredAnyComponents; + Nz::Bitset<> m_requiredComponents; SystemIndex m_systemIndex; World* m_world; float m_updateCounter; diff --git a/SDK/include/NDK/Components/CameraComponent.hpp b/SDK/include/NDK/Components/CameraComponent.hpp index 4b610d5a0..4eea340e8 100644 --- a/SDK/include/NDK/Components/CameraComponent.hpp +++ b/SDK/include/NDK/Components/CameraComponent.hpp @@ -19,7 +19,7 @@ namespace Ndk { class Entity; - class NDK_API CameraComponent : public Component, public NzAbstractViewer + class NDK_API CameraComponent : public Component, public Nz::AbstractViewer { public: inline CameraComponent(); @@ -34,26 +34,26 @@ namespace Ndk inline void EnsureViewportUpdate() const; inline float GetAspectRatio() const; - inline NzVector3f GetEyePosition() const; - inline NzVector3f GetForward() const; + inline Nz::Vector3f GetEyePosition() const; + inline Nz::Vector3f GetForward() const; inline float GetFOV() const; - inline const NzFrustumf& GetFrustum() const; + inline const Nz::Frustumf& GetFrustum() const; inline unsigned int GetLayer() const; - inline const NzMatrix4f& GetProjectionMatrix() const; - inline nzProjectionType GetProjectionType() const; - inline const NzRenderTarget* GetTarget() const; - inline const NzRectf& GetTargetRegion() const; - inline const NzMatrix4f& GetViewMatrix() const; - inline const NzRecti& GetViewport() const; + inline const Nz::Matrix4f& GetProjectionMatrix() const; + inline Nz::ProjectionType GetProjectionType() const; + inline const Nz::RenderTarget* GetTarget() const; + inline const Nz::Rectf& GetTargetRegion() const; + inline const Nz::Matrix4f& GetViewMatrix() const; + inline const Nz::Recti& GetViewport() const; inline float GetZFar() const; inline float GetZNear() const; inline void SetFOV(float fov); inline void SetLayer(unsigned int layer); - inline void SetProjectionType(nzProjectionType projection); - inline void SetTarget(const NzRenderTarget* renderTarget); - inline void SetTargetRegion(const NzRectf& region); - inline void SetViewport(const NzRecti& viewport); + inline void SetProjectionType(Nz::ProjectionType projection); + inline void SetTarget(const Nz::RenderTarget* renderTarget); + inline void SetTargetRegion(const Nz::Rectf& region); + inline void SetViewport(const Nz::Recti& viewport); inline void SetZFar(float zFar); inline void SetZNear(float zNear); @@ -69,26 +69,26 @@ namespace Ndk void OnComponentAttached(BaseComponent& component) override; void OnComponentDetached(BaseComponent& component) override; void OnDetached() override; - void OnNodeInvalidated(const NzNode* node); - void OnRenderTargetRelease(const NzRenderTarget* renderTarget); - void OnRenderTargetSizeChange(const NzRenderTarget* renderTarget); + void OnNodeInvalidated(const Nz::Node* node); + void OnRenderTargetRelease(const Nz::RenderTarget* renderTarget); + void OnRenderTargetSizeChange(const Nz::RenderTarget* renderTarget); void UpdateFrustum() const; void UpdateProjectionMatrix() const; void UpdateViewMatrix() const; void UpdateViewport() const; - NazaraSlot(NzNode, OnNodeInvalidation, m_nodeInvalidationSlot); - NazaraSlot(NzRenderTarget, OnRenderTargetRelease, m_targetReleaseSlot); - NazaraSlot(NzRenderTarget, OnRenderTargetSizeChange, m_targetResizeSlot); + NazaraSlot(Nz::Node, OnNodeInvalidation, m_nodeInvalidationSlot); + NazaraSlot(Nz::RenderTarget, OnRenderTargetRelease, m_targetReleaseSlot); + NazaraSlot(Nz::RenderTarget, OnRenderTargetSizeChange, m_targetResizeSlot); - nzProjectionType m_projectionType; - mutable NzFrustumf m_frustum; - mutable NzMatrix4f m_projectionMatrix; - mutable NzMatrix4f m_viewMatrix; - NzRectf m_targetRegion; - mutable NzRecti m_viewport; - const NzRenderTarget* m_target; + Nz::ProjectionType m_projectionType; + mutable Nz::Frustumf m_frustum; + mutable Nz::Matrix4f m_projectionMatrix; + mutable Nz::Matrix4f m_viewMatrix; + Nz::Rectf m_targetRegion; + mutable Nz::Recti m_viewport; + const Nz::RenderTarget* m_target; mutable bool m_frustumUpdated; mutable bool m_projectionMatrixUpdated; mutable bool m_viewMatrixUpdated; diff --git a/SDK/include/NDK/Components/CameraComponent.inl b/SDK/include/NDK/Components/CameraComponent.inl index 083ef4219..efaf6ba36 100644 --- a/SDK/include/NDK/Components/CameraComponent.inl +++ b/SDK/include/NDK/Components/CameraComponent.inl @@ -8,7 +8,7 @@ namespace Ndk { inline CameraComponent::CameraComponent() : - m_projectionType(nzProjectionType_Perspective), + m_projectionType(Nz::ProjectionType_Perspective), m_targetRegion(0.f, 0.f, 1.f, 1.f), m_target(nullptr), m_frustumUpdated(false), @@ -25,7 +25,7 @@ namespace Ndk inline CameraComponent::CameraComponent(const CameraComponent& camera) : Component(camera), - NzAbstractViewer(camera), + AbstractViewer(camera), m_projectionType(camera.m_projectionType), m_targetRegion(camera.m_targetRegion), m_target(nullptr), @@ -78,7 +78,7 @@ namespace Ndk return m_fov; } - inline const NzFrustumf& CameraComponent::GetFrustum() const + inline const Nz::Frustumf& CameraComponent::GetFrustum() const { EnsureFrustumUpdate(); @@ -90,36 +90,36 @@ namespace Ndk return m_layer; } - inline const NzMatrix4f& CameraComponent::GetProjectionMatrix() const + inline const Nz::Matrix4f& CameraComponent::GetProjectionMatrix() const { EnsureProjectionMatrixUpdate(); return m_projectionMatrix; } - inline nzProjectionType CameraComponent::GetProjectionType() const + inline Nz::ProjectionType CameraComponent::GetProjectionType() const { return m_projectionType; } - inline const NzRenderTarget* CameraComponent::GetTarget() const + inline const Nz::RenderTarget* CameraComponent::GetTarget() const { return m_target; } - inline const NzRectf& CameraComponent::GetTargetRegion() const + inline const Nz::Rectf& CameraComponent::GetTargetRegion() const { return m_targetRegion; } - inline const NzMatrix4f& CameraComponent::GetViewMatrix() const + inline const Nz::Matrix4f& CameraComponent::GetViewMatrix() const { EnsureViewMatrixUpdate(); return m_viewMatrix; } - inline const NzRecti& CameraComponent::GetViewport() const + inline const Nz::Recti& CameraComponent::GetViewport() const { EnsureViewportUpdate(); @@ -138,20 +138,20 @@ namespace Ndk inline void CameraComponent::SetFOV(float fov) { - NazaraAssert(!NzNumberEquals(fov, 0.f), "FOV must be different from zero"); + NazaraAssert(!Nz::NumberEquals(fov, 0.f), "FOV must be different from zero"); m_fov = fov; InvalidateProjectionMatrix(); } - inline void CameraComponent::SetProjectionType(nzProjectionType projectionType) + inline void CameraComponent::SetProjectionType(Nz::ProjectionType projectionType) { m_projectionType = projectionType; InvalidateProjectionMatrix(); } - inline void CameraComponent::SetTarget(const NzRenderTarget* renderTarget) + inline void CameraComponent::SetTarget(const Nz::RenderTarget* renderTarget) { m_target = renderTarget; if (m_target) @@ -160,14 +160,14 @@ namespace Ndk m_targetReleaseSlot.Disconnect(); } - inline void CameraComponent::SetTargetRegion(const NzRectf& region) + inline void CameraComponent::SetTargetRegion(const Nz::Rectf& region) { m_targetRegion = region; InvalidateViewport(); } - inline void CameraComponent::SetViewport(const NzRecti& viewport) + inline void CameraComponent::SetViewport(const Nz::Recti& viewport) { NazaraAssert(m_target, "Component has no render target"); @@ -175,7 +175,7 @@ namespace Ndk float invWidth = 1.f/m_target->GetWidth(); float invHeight = 1.f/m_target->GetHeight(); - SetTargetRegion(NzRectf(invWidth * viewport.x, invHeight * viewport.y, invWidth * viewport.width, invHeight * viewport.height)); + SetTargetRegion(Nz::Rectf(invWidth * viewport.x, invHeight * viewport.y, invWidth * viewport.width, invHeight * viewport.height)); } inline void CameraComponent::SetZFar(float zFar) @@ -187,7 +187,7 @@ namespace Ndk inline void CameraComponent::SetZNear(float zNear) { - NazaraAssert(!NzNumberEquals(zNear, 0.f), "zNear cannot be zero"); + NazaraAssert(!Nz::NumberEquals(zNear, 0.f), "zNear cannot be zero"); m_zNear = zNear; InvalidateProjectionMatrix(); diff --git a/SDK/include/NDK/Components/CollisionComponent.hpp b/SDK/include/NDK/Components/CollisionComponent.hpp index c421f127a..e0af0d09b 100644 --- a/SDK/include/NDK/Components/CollisionComponent.hpp +++ b/SDK/include/NDK/Components/CollisionComponent.hpp @@ -11,7 +11,10 @@ #include #include -class NzPhysObject; +namespace Nz +{ + class PhysObject; +} namespace Ndk { @@ -23,30 +26,30 @@ namespace Ndk friend class StaticCollisionSystem; public: - CollisionComponent(NzPhysGeomRef geom = NzPhysGeomRef()); + CollisionComponent(Nz::PhysGeomRef geom = Nz::PhysGeomRef()); CollisionComponent(const CollisionComponent& collision); ~CollisionComponent() = default; - const NzPhysGeomRef& GetGeom() const; + const Nz::PhysGeomRef& GetGeom() const; - void SetGeom(NzPhysGeomRef geom); + void SetGeom(Nz::PhysGeomRef geom); - CollisionComponent& operator=(NzPhysGeomRef geom); + CollisionComponent& operator=(Nz::PhysGeomRef geom); CollisionComponent& operator=(CollisionComponent&& collision) = default; static ComponentIndex componentIndex; private: void InitializeStaticBody(); - NzPhysObject* GetStaticBody(); + Nz::PhysObject* GetStaticBody(); void OnAttached() override; void OnComponentAttached(BaseComponent& component) override; void OnComponentDetached(BaseComponent& component) override; void OnDetached() override; - std::unique_ptr m_staticBody; - NzPhysGeomRef m_geom; + std::unique_ptr m_staticBody; + Nz::PhysGeomRef m_geom; bool m_bodyUpdated; }; } diff --git a/SDK/include/NDK/Components/CollisionComponent.inl b/SDK/include/NDK/Components/CollisionComponent.inl index 2f748c1d6..58356ac9e 100644 --- a/SDK/include/NDK/Components/CollisionComponent.inl +++ b/SDK/include/NDK/Components/CollisionComponent.inl @@ -9,7 +9,7 @@ namespace Ndk { - inline CollisionComponent::CollisionComponent(NzPhysGeomRef geom) : + inline CollisionComponent::CollisionComponent(Nz::PhysGeomRef geom) : m_geom(std::move(geom)), m_bodyUpdated(false) { @@ -21,19 +21,19 @@ namespace Ndk { } - inline const NzPhysGeomRef& CollisionComponent::GetGeom() const + inline const Nz::PhysGeomRef& CollisionComponent::GetGeom() const { return m_geom; } - inline CollisionComponent& CollisionComponent::operator=(NzPhysGeomRef geom) + inline CollisionComponent& CollisionComponent::operator=(Nz::PhysGeomRef geom) { SetGeom(geom); return *this; } - inline NzPhysObject* CollisionComponent::GetStaticBody() + inline Nz::PhysObject* CollisionComponent::GetStaticBody() { return m_staticBody.get(); } diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index 70223bbab..8d1e3e2f7 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -22,16 +22,16 @@ namespace Ndk inline GraphicsComponent(const GraphicsComponent& graphicsComponent); ~GraphicsComponent() = default; - inline void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const; + inline void AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const; - inline void Attach(NzInstancedRenderableRef renderable); + inline void Attach(Nz::InstancedRenderableRef renderable); inline void EnsureTransformMatrixUpdate() const; static ComponentIndex componentIndex; private: - void InvalidateRenderableData(const NzInstancedRenderable* renderable, nzUInt32 flags, unsigned int index); + void InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, unsigned int index); inline void InvalidateRenderables(); inline void InvalidateTransformMatrix(); @@ -39,29 +39,29 @@ namespace Ndk void OnComponentAttached(BaseComponent& component) override; void OnComponentDetached(BaseComponent& component) override; void OnDetached() override; - void OnNodeInvalidated(const NzNode* node); + void OnNodeInvalidated(const Nz::Node* node); void UpdateTransformMatrix() const; - NazaraSlot(NzNode, OnNodeInvalidation, m_nodeInvalidationSlot); + NazaraSlot(Nz::Node, OnNodeInvalidation, m_nodeInvalidationSlot); struct Renderable { - Renderable(NzMatrix4f& transformMatrix) : + Renderable(Nz::Matrix4f& transformMatrix) : data(transformMatrix), dataUpdated(false) { } - NazaraSlot(NzInstancedRenderable, OnInstancedRenderableInvalidateData, renderableInvalidationSlot); + NazaraSlot(Nz::InstancedRenderable, OnInstancedRenderableInvalidateData, renderableInvalidationSlot); - mutable NzInstancedRenderable::InstanceData data; - NzInstancedRenderableRef renderable; + mutable Nz::InstancedRenderable::InstanceData data; + Nz::InstancedRenderableRef renderable; mutable bool dataUpdated; }; std::vector m_renderables; - mutable NzMatrix4f m_transformMatrix; + mutable Nz::Matrix4f m_transformMatrix; mutable bool m_transformMatrixUpdated; }; } diff --git a/SDK/include/NDK/Components/GraphicsComponent.inl b/SDK/include/NDK/Components/GraphicsComponent.inl index 0691414d1..56b003b00 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.inl +++ b/SDK/include/NDK/Components/GraphicsComponent.inl @@ -16,7 +16,7 @@ namespace Ndk Attach(r.renderable); } - inline void GraphicsComponent::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const + inline void GraphicsComponent::AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const { EnsureTransformMatrixUpdate(); @@ -32,7 +32,7 @@ namespace Ndk } } - inline void GraphicsComponent::Attach(NzInstancedRenderableRef renderable) + inline void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable) { m_renderables.emplace_back(m_transformMatrix); Renderable& r = m_renderables.back(); diff --git a/SDK/include/NDK/Components/LightComponent.hpp b/SDK/include/NDK/Components/LightComponent.hpp index 0839ac98e..c55ae57bb 100644 --- a/SDK/include/NDK/Components/LightComponent.hpp +++ b/SDK/include/NDK/Components/LightComponent.hpp @@ -12,10 +12,10 @@ namespace Ndk { - class NDK_API LightComponent : public Component, public NzLight + class NDK_API LightComponent : public Component, public Nz::Light { public: - inline LightComponent(nzLightType lightType = nzLightType_Point); + inline LightComponent(Nz::LightType lightType = Nz::LightType_Point); LightComponent(const LightComponent& light) = default; ~LightComponent() = default; diff --git a/SDK/include/NDK/Components/LightComponent.inl b/SDK/include/NDK/Components/LightComponent.inl index 3a3d0a794..f06fcb24c 100644 --- a/SDK/include/NDK/Components/LightComponent.inl +++ b/SDK/include/NDK/Components/LightComponent.inl @@ -4,8 +4,8 @@ namespace Ndk { - inline LightComponent::LightComponent(nzLightType lightType) : - NzLight(lightType) + inline LightComponent::LightComponent(Nz::LightType lightType) : + Nz::Light(lightType) { } -} \ No newline at end of file +} diff --git a/SDK/include/NDK/Components/NodeComponent.hpp b/SDK/include/NDK/Components/NodeComponent.hpp index c52f0ed88..1e6eee879 100644 --- a/SDK/include/NDK/Components/NodeComponent.hpp +++ b/SDK/include/NDK/Components/NodeComponent.hpp @@ -14,14 +14,14 @@ namespace Ndk { class Entity; - class NDK_API NodeComponent : public Component, public NzNode + class NDK_API NodeComponent : public Component, public Nz::Node { public: NodeComponent() = default; ~NodeComponent() = default; void SetParent(Entity* entity, bool keepDerived = false); - using NzNode::SetParent; + using Nz::Node::SetParent; static ComponentIndex componentIndex; }; diff --git a/SDK/include/NDK/Components/NodeComponent.inl b/SDK/include/NDK/Components/NodeComponent.inl index ac41cf982..e6d49c9a9 100644 --- a/SDK/include/NDK/Components/NodeComponent.inl +++ b/SDK/include/NDK/Components/NodeComponent.inl @@ -13,9 +13,9 @@ namespace Ndk { NazaraAssert(entity->HasComponent(), "Entity must have a NodeComponent"); - NzNode::SetParent(entity->GetComponent(), keepDerived); + Nz::Node::SetParent(entity->GetComponent(), keepDerived); } else - NzNode::SetParent(nullptr, keepDerived); + Nz::Node::SetParent(nullptr, keepDerived); } } diff --git a/SDK/include/NDK/Components/PhysicsComponent.hpp b/SDK/include/NDK/Components/PhysicsComponent.hpp index 4385735f9..9c5618785 100644 --- a/SDK/include/NDK/Components/PhysicsComponent.hpp +++ b/SDK/include/NDK/Components/PhysicsComponent.hpp @@ -25,45 +25,45 @@ namespace Ndk PhysicsComponent(const PhysicsComponent& physics); ~PhysicsComponent() = default; - void AddForce(const NzVector3f& force, nzCoordSys coordSys = nzCoordSys_Global); - void AddForce(const NzVector3f& force, const NzVector3f& point, nzCoordSys coordSys = nzCoordSys_Global); - void AddTorque(const NzVector3f& torque, nzCoordSys coordSys = nzCoordSys_Global); + void AddForce(const Nz::Vector3f& force, Nz::CoordSys coordSys = Nz::CoordSys_Global); + void AddForce(const Nz::Vector3f& force, const Nz::Vector3f& point, Nz::CoordSys coordSys = Nz::CoordSys_Global); + void AddTorque(const Nz::Vector3f& torque, Nz::CoordSys coordSys = Nz::CoordSys_Global); void EnableAutoSleep(bool autoSleep); - NzBoxf GetAABB() const; - NzVector3f GetAngularVelocity() const; + Nz::Boxf GetAABB() const; + Nz::Vector3f GetAngularVelocity() const; float GetGravityFactor() const; float GetMass() const; - NzVector3f GetMassCenter(nzCoordSys coordSys = nzCoordSys_Local) const; - const NzMatrix4f& GetMatrix() const; - NzVector3f GetPosition() const; - NzQuaternionf GetRotation() const; - NzVector3f GetVelocity() const; + Nz::Vector3f GetMassCenter(Nz::CoordSys coordSys = Nz::CoordSys_Local) const; + const Nz::Matrix4f& GetMatrix() const; + Nz::Vector3f GetPosition() const; + Nz::Quaternionf GetRotation() const; + Nz::Vector3f GetVelocity() const; bool IsAutoSleepEnabled() const; bool IsMoveable() const; bool IsSleeping() const; - void SetAngularVelocity(const NzVector3f& angularVelocity); + void SetAngularVelocity(const Nz::Vector3f& angularVelocity); void SetGravityFactor(float gravityFactor); void SetMass(float mass); - void SetMassCenter(const NzVector3f& center); - void SetPosition(const NzVector3f& position); - void SetRotation(const NzQuaternionf& rotation); - void SetVelocity(const NzVector3f& velocity); + void SetMassCenter(const Nz::Vector3f& center); + void SetPosition(const Nz::Vector3f& position); + void SetRotation(const Nz::Quaternionf& rotation); + void SetVelocity(const Nz::Vector3f& velocity); static ComponentIndex componentIndex; private: - NzPhysObject& GetPhysObject(); + Nz::PhysObject& GetPhysObject(); void OnAttached() override; void OnComponentAttached(BaseComponent& component) override; void OnComponentDetached(BaseComponent& component) override; void OnDetached() override; - std::unique_ptr m_object; + std::unique_ptr m_object; }; } diff --git a/SDK/include/NDK/Components/PhysicsComponent.inl b/SDK/include/NDK/Components/PhysicsComponent.inl index fec47f8f5..f0847842d 100644 --- a/SDK/include/NDK/Components/PhysicsComponent.inl +++ b/SDK/include/NDK/Components/PhysicsComponent.inl @@ -12,21 +12,21 @@ namespace Ndk NazaraUnused(physics); } - inline void PhysicsComponent::AddForce(const NzVector3f& force, nzCoordSys coordSys) + inline void PhysicsComponent::AddForce(const Nz::Vector3f& force, Nz::CoordSys coordSys) { NazaraAssert(m_object, "Invalid physics object"); m_object->AddForce(force, coordSys); } - inline void PhysicsComponent::AddForce(const NzVector3f& force, const NzVector3f& point, nzCoordSys coordSys) + inline void PhysicsComponent::AddForce(const Nz::Vector3f& force, const Nz::Vector3f& point, Nz::CoordSys coordSys) { NazaraAssert(m_object, "Invalid physics object"); m_object->AddForce(force, point, coordSys); } - inline void PhysicsComponent::AddTorque(const NzVector3f& torque, nzCoordSys coordSys) + inline void PhysicsComponent::AddTorque(const Nz::Vector3f& torque, Nz::CoordSys coordSys) { NazaraAssert(m_object, "Invalid physics object"); @@ -40,14 +40,14 @@ namespace Ndk m_object->EnableAutoSleep(autoSleep); } - inline NzBoxf PhysicsComponent::GetAABB() const + inline Nz::Boxf PhysicsComponent::GetAABB() const { NazaraAssert(m_object, "Invalid physics object"); return m_object->GetAABB(); } - inline NzVector3f PhysicsComponent::GetAngularVelocity() const + inline Nz::Vector3f PhysicsComponent::GetAngularVelocity() const { NazaraAssert(m_object, "Invalid physics object"); @@ -68,35 +68,35 @@ namespace Ndk return m_object->GetMass(); } - inline NzVector3f PhysicsComponent::GetMassCenter(nzCoordSys coordSys) const + inline Nz::Vector3f PhysicsComponent::GetMassCenter(Nz::CoordSys coordSys) const { NazaraAssert(m_object, "Invalid physics object"); return m_object->GetMassCenter(coordSys); } - inline const NzMatrix4f& PhysicsComponent::GetMatrix() const + inline const Nz::Matrix4f& PhysicsComponent::GetMatrix() const { NazaraAssert(m_object, "Invalid physics object"); return m_object->GetMatrix(); } - inline NzVector3f PhysicsComponent::GetPosition() const + inline Nz::Vector3f PhysicsComponent::GetPosition() const { NazaraAssert(m_object, "Invalid physics object"); return m_object->GetPosition(); } - inline NzQuaternionf PhysicsComponent::GetRotation() const + inline Nz::Quaternionf PhysicsComponent::GetRotation() const { NazaraAssert(m_object, "Invalid physics object"); return m_object->GetRotation(); } - inline NzVector3f PhysicsComponent::GetVelocity() const + inline Nz::Vector3f PhysicsComponent::GetVelocity() const { NazaraAssert(m_object, "Invalid physics object"); @@ -117,7 +117,7 @@ namespace Ndk return m_object->IsSleeping(); } - inline void PhysicsComponent::SetAngularVelocity(const NzVector3f& angularVelocity) + inline void PhysicsComponent::SetAngularVelocity(const Nz::Vector3f& angularVelocity) { NazaraAssert(m_object, "Invalid physics object"); @@ -139,35 +139,35 @@ namespace Ndk m_object->SetMass(mass); } - inline void PhysicsComponent::SetMassCenter(const NzVector3f& center) + inline void PhysicsComponent::SetMassCenter(const Nz::Vector3f& center) { NazaraAssert(m_object, "Invalid physics object"); m_object->SetMassCenter(center); } - inline void PhysicsComponent::SetPosition(const NzVector3f& position) + inline void PhysicsComponent::SetPosition(const Nz::Vector3f& position) { NazaraAssert(m_object, "Invalid physics object"); m_object->SetPosition(position); } - inline void PhysicsComponent::SetRotation(const NzQuaternionf& rotation) + inline void PhysicsComponent::SetRotation(const Nz::Quaternionf& rotation) { NazaraAssert(m_object, "Invalid physics object"); m_object->SetRotation(rotation); } - inline void PhysicsComponent::SetVelocity(const NzVector3f& velocity) + inline void PhysicsComponent::SetVelocity(const Nz::Vector3f& velocity) { NazaraAssert(m_object, "Invalid physics object"); m_object->SetVelocity(velocity); } - inline NzPhysObject& PhysicsComponent::GetPhysObject() + inline Nz::PhysObject& PhysicsComponent::GetPhysObject() { return *m_object.get(); } diff --git a/SDK/include/NDK/Components/VelocityComponent.hpp b/SDK/include/NDK/Components/VelocityComponent.hpp index 99a0cad6d..28d317a2c 100644 --- a/SDK/include/NDK/Components/VelocityComponent.hpp +++ b/SDK/include/NDK/Components/VelocityComponent.hpp @@ -17,12 +17,12 @@ namespace Ndk class NDK_API VelocityComponent : public Component { public: - VelocityComponent(const NzVector3f& velocity = NzVector3f::Zero()); + VelocityComponent(const Nz::Vector3f& velocity = Nz::Vector3f::Zero()); ~VelocityComponent() = default; - NzVector3f linearVelocity; + Nz::Vector3f linearVelocity; - VelocityComponent& operator=(const NzVector3f& vel); + VelocityComponent& operator=(const Nz::Vector3f& vel); static ComponentIndex componentIndex; }; diff --git a/SDK/include/NDK/Components/VelocityComponent.inl b/SDK/include/NDK/Components/VelocityComponent.inl index 55e319351..1c2f0ed87 100644 --- a/SDK/include/NDK/Components/VelocityComponent.inl +++ b/SDK/include/NDK/Components/VelocityComponent.inl @@ -7,12 +7,12 @@ namespace Ndk { - inline VelocityComponent::VelocityComponent(const NzVector3f& velocity) : + inline VelocityComponent::VelocityComponent(const Nz::Vector3f& velocity) : linearVelocity(velocity) { } - inline VelocityComponent& VelocityComponent::operator=(const NzVector3f& vel) + inline VelocityComponent& VelocityComponent::operator=(const Nz::Vector3f& vel) { linearVelocity = vel; return *this; diff --git a/SDK/include/NDK/Entity.hpp b/SDK/include/NDK/Entity.hpp index 508930e94..f2febee51 100644 --- a/SDK/include/NDK/Entity.hpp +++ b/SDK/include/NDK/Entity.hpp @@ -36,9 +36,9 @@ namespace Ndk inline BaseComponent& GetComponent(ComponentIndex index); template ComponentType& GetComponent(); - inline const NzBitset<>& GetComponentBits() const; + inline const Nz::Bitset<>& GetComponentBits() const; inline EntityId GetId() const; - inline const NzBitset<>& GetSystemBits() const; + inline const Nz::Bitset<>& GetSystemBits() const; inline World* GetWorld() const; inline bool HasComponent(ComponentIndex index) const; @@ -69,9 +69,9 @@ namespace Ndk std::vector> m_components; std::vector m_handles; + Nz::Bitset<> m_componentBits; + Nz::Bitset<> m_systemBits; EntityId m_id; - NzBitset<> m_componentBits; - NzBitset<> m_systemBits; World* m_world; bool m_valid; }; diff --git a/SDK/include/NDK/Entity.inl b/SDK/include/NDK/Entity.inl index 22353dac9..d30f58530 100644 --- a/SDK/include/NDK/Entity.inl +++ b/SDK/include/NDK/Entity.inl @@ -40,7 +40,7 @@ namespace Ndk return static_cast(GetComponent(index)); } - inline const NzBitset<>& Entity::GetComponentBits() const + inline const Nz::Bitset<>& Entity::GetComponentBits() const { return m_componentBits; } @@ -50,7 +50,7 @@ namespace Ndk return m_id; } - inline const NzBitset<>& Entity::GetSystemBits() const + inline const Nz::Bitset<>& Entity::GetSystemBits() const { return m_systemBits; } diff --git a/SDK/include/NDK/EntityHandle.hpp b/SDK/include/NDK/EntityHandle.hpp index 554bd4a35..c6a325b7e 100644 --- a/SDK/include/NDK/EntityHandle.hpp +++ b/SDK/include/NDK/EntityHandle.hpp @@ -33,7 +33,7 @@ namespace Ndk EntityHandle& Swap(EntityHandle& handle); - NzString ToString() const; + Nz::String ToString() const; operator bool() const; operator Entity*() const; diff --git a/SDK/include/NDK/EntityHandle.inl b/SDK/include/NDK/EntityHandle.inl index a3919d383..636287878 100644 --- a/SDK/include/NDK/EntityHandle.inl +++ b/SDK/include/NDK/EntityHandle.inl @@ -90,9 +90,9 @@ namespace Ndk return *this; } - inline NzString EntityHandle::ToString() const + inline Nz::String EntityHandle::ToString() const { - NzStringStream ss; + Nz::StringStream ss; ss << "EntityHandle("; if (IsValid()) ss << "Entity(" << m_entity->GetId() << ')'; diff --git a/SDK/include/NDK/EntityList.hpp b/SDK/include/NDK/EntityList.hpp index 4737cdba7..0edefde11 100644 --- a/SDK/include/NDK/EntityList.hpp +++ b/SDK/include/NDK/EntityList.hpp @@ -54,7 +54,7 @@ namespace Ndk private: std::vector m_entities; - NzBitset m_entityBits; + Nz::Bitset m_entityBits; }; } diff --git a/SDK/include/NDK/EntityList.inl b/SDK/include/NDK/EntityList.inl index e7cd2bb3b..57bd4a8af 100644 --- a/SDK/include/NDK/EntityList.inl +++ b/SDK/include/NDK/EntityList.inl @@ -44,7 +44,7 @@ namespace Ndk } } - // Interface STD + // Nz::Interface STD inline EntityList::Container::iterator EntityList::begin() { return m_entities.begin(); diff --git a/SDK/include/NDK/Prerequesites.hpp b/SDK/include/NDK/Prerequesites.hpp index f49e1a76c..d75ed0eb0 100644 --- a/SDK/include/NDK/Prerequesites.hpp +++ b/SDK/include/NDK/Prerequesites.hpp @@ -57,10 +57,10 @@ namespace Ndk { - using ComponentId = nzUInt64; - using ComponentIndex = nzUInt32; - using EntityId = nzUInt32; - using SystemIndex = nzUInt32; + using ComponentId = Nz::UInt64; + using ComponentIndex = Nz::UInt32; + using EntityId = Nz::UInt32; + using SystemIndex = Nz::UInt32; } #endif // NDK_PREREQUESITES_HPP diff --git a/SDK/include/NDK/Systems/PhysicsSystem.hpp b/SDK/include/NDK/Systems/PhysicsSystem.hpp index 95d4bfe13..a5b0b9fcc 100644 --- a/SDK/include/NDK/Systems/PhysicsSystem.hpp +++ b/SDK/include/NDK/Systems/PhysicsSystem.hpp @@ -20,8 +20,8 @@ namespace Ndk PhysicsSystem(const PhysicsSystem& system); ~PhysicsSystem() = default; - NzPhysWorld& GetWorld(); - const NzPhysWorld& GetWorld() const; + Nz::PhysWorld& GetWorld(); + const Nz::PhysWorld& GetWorld() const; static SystemIndex systemIndex; @@ -31,7 +31,7 @@ namespace Ndk EntityList m_dynamicObjects; EntityList m_staticObjects; - NzPhysWorld m_world; + Nz::PhysWorld m_world; }; } diff --git a/SDK/include/NDK/Systems/PhysicsSystem.inl b/SDK/include/NDK/Systems/PhysicsSystem.inl index 78d396282..e9fb52c49 100644 --- a/SDK/include/NDK/Systems/PhysicsSystem.inl +++ b/SDK/include/NDK/Systems/PhysicsSystem.inl @@ -4,12 +4,12 @@ namespace Ndk { - inline NzPhysWorld& PhysicsSystem::GetWorld() + inline Nz::PhysWorld& PhysicsSystem::GetWorld() { return m_world; } - inline const NzPhysWorld& PhysicsSystem::GetWorld() const + inline const Nz::PhysWorld& PhysicsSystem::GetWorld() const { return m_world; } diff --git a/SDK/include/NDK/Systems/RenderSystem.hpp b/SDK/include/NDK/Systems/RenderSystem.hpp index 66167c92c..ff077278d 100644 --- a/SDK/include/NDK/Systems/RenderSystem.hpp +++ b/SDK/include/NDK/Systems/RenderSystem.hpp @@ -25,16 +25,16 @@ namespace Ndk inline RenderSystem(const RenderSystem& renderSystem); ~RenderSystem() = default; - inline const NzBackgroundRef& GetDefaultBackground() const; - inline const NzMatrix4f& GetCoordinateSystemMatrix() const; - inline NzVector3f GetGlobalForward() const; - inline NzVector3f GetGlobalRight() const; - inline NzVector3f GetGlobalUp() const; + inline const Nz::BackgroundRef& GetDefaultBackground() const; + inline const Nz::Matrix4f& GetCoordinateSystemMatrix() const; + inline Nz::Vector3f GetGlobalForward() const; + inline Nz::Vector3f GetGlobalRight() const; + inline Nz::Vector3f GetGlobalUp() const; - inline void SetDefaultBackground(NzBackgroundRef background); - inline void SetGlobalForward(const NzVector3f& direction); - inline void SetGlobalRight(const NzVector3f& direction); - inline void SetGlobalUp(const NzVector3f& direction); + inline void SetDefaultBackground(Nz::BackgroundRef background); + inline void SetGlobalForward(const Nz::Vector3f& direction); + inline void SetGlobalRight(const Nz::Vector3f& direction); + inline void SetGlobalUp(const Nz::Vector3f& direction); static SystemIndex systemIndex; @@ -48,9 +48,9 @@ namespace Ndk EntityList m_cameras; EntityList m_drawables; EntityList m_lights; - NzBackgroundRef m_background; - NzForwardRenderTechnique m_renderTechnique; - NzMatrix4f m_coordinateSystemMatrix; + Nz::BackgroundRef m_background; + Nz::ForwardRenderTechnique m_renderTechnique; + Nz::Matrix4f m_coordinateSystemMatrix; bool m_coordinateSystemInvalidated; }; } diff --git a/SDK/include/NDK/Systems/RenderSystem.inl b/SDK/include/NDK/Systems/RenderSystem.inl index a2eed384e..d0cb0af47 100644 --- a/SDK/include/NDK/Systems/RenderSystem.inl +++ b/SDK/include/NDK/Systems/RenderSystem.inl @@ -9,37 +9,37 @@ namespace Ndk { } - inline const NzBackgroundRef& RenderSystem::GetDefaultBackground() const + inline const Nz::BackgroundRef& RenderSystem::GetDefaultBackground() const { return m_background; } - inline const NzMatrix4f& RenderSystem::GetCoordinateSystemMatrix() const + inline const Nz::Matrix4f& RenderSystem::GetCoordinateSystemMatrix() const { return m_coordinateSystemMatrix; } - inline NzVector3f RenderSystem::GetGlobalForward() const + inline Nz::Vector3f RenderSystem::GetGlobalForward() const { - return NzVector3f(-m_coordinateSystemMatrix.m13, -m_coordinateSystemMatrix.m23, -m_coordinateSystemMatrix.m33); + return Nz::Vector3f(-m_coordinateSystemMatrix.m13, -m_coordinateSystemMatrix.m23, -m_coordinateSystemMatrix.m33); } - inline NzVector3f RenderSystem::GetGlobalRight() const + inline Nz::Vector3f RenderSystem::GetGlobalRight() const { - return NzVector3f(m_coordinateSystemMatrix.m11, m_coordinateSystemMatrix.m21, m_coordinateSystemMatrix.m31); + return Nz::Vector3f(m_coordinateSystemMatrix.m11, m_coordinateSystemMatrix.m21, m_coordinateSystemMatrix.m31); } - inline NzVector3f RenderSystem::GetGlobalUp() const + inline Nz::Vector3f RenderSystem::GetGlobalUp() const { - return NzVector3f(m_coordinateSystemMatrix.m12, m_coordinateSystemMatrix.m22, m_coordinateSystemMatrix.m32); + return Nz::Vector3f(m_coordinateSystemMatrix.m12, m_coordinateSystemMatrix.m22, m_coordinateSystemMatrix.m32); } - inline void RenderSystem::SetDefaultBackground(NzBackgroundRef background) + inline void RenderSystem::SetDefaultBackground(Nz::BackgroundRef background) { m_background = std::move(background); } - inline void RenderSystem::SetGlobalForward(const NzVector3f& direction) + inline void RenderSystem::SetGlobalForward(const Nz::Vector3f& direction) { m_coordinateSystemMatrix.m13 = -direction.x; m_coordinateSystemMatrix.m23 = -direction.y; @@ -48,7 +48,7 @@ namespace Ndk InvalidateCoordinateSystem(); } - inline void RenderSystem::SetGlobalRight(const NzVector3f& direction) + inline void RenderSystem::SetGlobalRight(const Nz::Vector3f& direction) { m_coordinateSystemMatrix.m11 = direction.x; m_coordinateSystemMatrix.m21 = direction.y; @@ -57,7 +57,7 @@ namespace Ndk InvalidateCoordinateSystem(); } - inline void RenderSystem::SetGlobalUp(const NzVector3f& direction) + inline void RenderSystem::SetGlobalUp(const Nz::Vector3f& direction) { m_coordinateSystemMatrix.m12 = direction.x; m_coordinateSystemMatrix.m22 = direction.y; diff --git a/SDK/include/NDK/World.hpp b/SDK/include/NDK/World.hpp index a5fa6594a..3b7e16684 100644 --- a/SDK/include/NDK/World.hpp +++ b/SDK/include/NDK/World.hpp @@ -85,8 +85,8 @@ namespace Ndk std::vector m_entities; std::vector m_freeIdList; EntityList m_aliveEntities; - NzBitset m_dirtyEntities; - NzBitset m_killedEntities; + Nz::Bitset m_dirtyEntities; + Nz::Bitset m_killedEntities; }; } diff --git a/SDK/src/NDK/BaseSystem.cpp b/SDK/src/NDK/BaseSystem.cpp index d37ba1791..a69f13550 100644 --- a/SDK/src/NDK/BaseSystem.cpp +++ b/SDK/src/NDK/BaseSystem.cpp @@ -17,10 +17,10 @@ namespace Ndk if (!entity) return false; - const NzBitset<>& components = entity->GetComponentBits(); + const Nz::Bitset<>& components = entity->GetComponentBits(); m_filterResult.PerformsAND(m_requiredComponents, components); - if (m_filterResult != m_requiredComponents) + if (m_filterResult != m_requiredComponents) return false; // Au moins un component requis n'est pas présent m_filterResult.PerformsAND(m_excludedComponents, components); diff --git a/SDK/src/NDK/Components/CameraComponent.cpp b/SDK/src/NDK/Components/CameraComponent.cpp index d408552c5..ac369e566 100644 --- a/SDK/src/NDK/Components/CameraComponent.cpp +++ b/SDK/src/NDK/Components/CameraComponent.cpp @@ -17,20 +17,20 @@ namespace Ndk EnsureViewMatrixUpdate(); EnsureViewportUpdate(); - NzRenderer::SetMatrix(nzMatrixType_Projection, m_projectionMatrix); - NzRenderer::SetMatrix(nzMatrixType_View, m_viewMatrix); - NzRenderer::SetTarget(m_target); - NzRenderer::SetViewport(m_viewport); + Nz::Renderer::SetMatrix(Nz::MatrixType_Projection, m_projectionMatrix); + Nz::Renderer::SetMatrix(Nz::MatrixType_View, m_viewMatrix); + Nz::Renderer::SetTarget(m_target); + Nz::Renderer::SetViewport(m_viewport); } - NzVector3f CameraComponent::GetEyePosition() const + Nz::Vector3f CameraComponent::GetEyePosition() const { NazaraAssert(m_entity && m_entity->HasComponent(), "CameraComponent requires NodeComponent"); return m_entity->GetComponent().GetPosition(); } - NzVector3f CameraComponent::GetForward() const + Nz::Vector3f CameraComponent::GetForward() const { NazaraAssert(m_entity && m_entity->HasComponent(), "CameraComponent requires NodeComponent"); @@ -80,7 +80,7 @@ namespace Ndk InvalidateViewMatrix(); } - void CameraComponent::OnNodeInvalidated(const NzNode* node) + void CameraComponent::OnNodeInvalidated(const Nz::Node* node) { NazaraUnused(node); @@ -88,20 +88,20 @@ namespace Ndk InvalidateViewMatrix(); } - void CameraComponent::OnRenderTargetRelease(const NzRenderTarget* renderTarget) + void CameraComponent::OnRenderTargetRelease(const Nz::RenderTarget* renderTarget) { if (renderTarget == m_target) m_target = nullptr; else - NazaraInternalError("Not listening to " + NzString::Pointer(renderTarget)); + NazaraInternalError("Not listening to " + Nz::String::Pointer(renderTarget)); } - void CameraComponent::OnRenderTargetSizeChange(const NzRenderTarget* renderTarget) + void CameraComponent::OnRenderTargetSizeChange(const Nz::RenderTarget* renderTarget) { if (renderTarget == m_target) InvalidateViewport(); else - NazaraInternalError("Not listening to " + NzString::Pointer(renderTarget)); + NazaraInternalError("Not listening to " + Nz::String::Pointer(renderTarget)); } void CameraComponent::UpdateFrustum() const @@ -118,13 +118,13 @@ namespace Ndk { switch (m_projectionType) { - case nzProjectionType_Orthogonal: + case Nz::ProjectionType_Orthogonal: EnsureViewportUpdate(); m_projectionMatrix.MakeOrtho(0.f, static_cast(m_viewport.width), 0.f, static_cast(m_viewport.height), m_zNear, m_zFar); break; - case nzProjectionType_Perspective: + case Nz::ProjectionType_Perspective: EnsureViewportUpdate(); // Can affect aspect ratio m_projectionMatrix.MakePerspective(m_fov, m_aspectRatio, m_zNear, m_zFar); @@ -141,7 +141,7 @@ namespace Ndk NodeComponent& nodeComponent = m_entity->GetComponent(); // Build the view matrix using the NodeComponent position/rotation - m_viewMatrix.MakeViewMatrix(nodeComponent.GetPosition(nzCoordSys_Global), nodeComponent.GetRotation(nzCoordSys_Global)); + m_viewMatrix.MakeViewMatrix(nodeComponent.GetPosition(Nz::CoordSys_Global), nodeComponent.GetRotation(Nz::CoordSys_Global)); m_viewMatrixUpdated = true; } @@ -153,7 +153,7 @@ namespace Ndk unsigned int targetHeight = std::max(m_target->GetHeight(), 1U); // Let's make sure we won't divide by zero // Our target region is expressed as % of the viewport dimensions, let's compute it in pixels - NzRectf fViewport(m_targetRegion); + Nz::Rectf fViewport(m_targetRegion); fViewport.x *= targetWidth; fViewport.y *= targetHeight; fViewport.width *= targetWidth; @@ -161,11 +161,11 @@ namespace Ndk // Compute the new aspect ratio, if it's different we need to invalidate the projection matrix float aspectRatio = fViewport.width/fViewport.height; - if (!NzNumberEquals(m_aspectRatio, aspectRatio, 0.001f)) + if (!Nz::NumberEquals(m_aspectRatio, aspectRatio, 0.001f)) { m_aspectRatio = aspectRatio; - if (m_projectionType == nzProjectionType_Perspective) + if (m_projectionType == Nz::ProjectionType_Perspective) InvalidateProjectionMatrix(); } diff --git a/SDK/src/NDK/Components/CollisionComponent.cpp b/SDK/src/NDK/Components/CollisionComponent.cpp index 929b087eb..49e8d8328 100644 --- a/SDK/src/NDK/Components/CollisionComponent.cpp +++ b/SDK/src/NDK/Components/CollisionComponent.cpp @@ -11,7 +11,7 @@ namespace Ndk { - void CollisionComponent::SetGeom(NzPhysGeomRef geom) + void CollisionComponent::SetGeom(Nz::PhysGeomRef geom) { m_geom = std::move(geom); @@ -35,9 +35,9 @@ namespace Ndk NazaraAssert(entityWorld, "Entity must have world"); NazaraAssert(entityWorld->HasSystem(), "World must have a physics system"); - NzPhysWorld& physWorld = entityWorld->GetSystem().GetWorld(); + Nz::PhysWorld& physWorld = entityWorld->GetSystem().GetWorld(); - m_staticBody.reset(new NzPhysObject(&physWorld, m_geom)); + m_staticBody.reset(new Nz::PhysObject(&physWorld, m_geom)); m_staticBody->EnableAutoSleep(false); } diff --git a/SDK/src/NDK/Components/GraphicsComponent.cpp b/SDK/src/NDK/Components/GraphicsComponent.cpp index 606a93d21..566724350 100644 --- a/SDK/src/NDK/Components/GraphicsComponent.cpp +++ b/SDK/src/NDK/Components/GraphicsComponent.cpp @@ -9,7 +9,7 @@ namespace Ndk { - void GraphicsComponent::InvalidateRenderableData(const NzInstancedRenderable* renderable, nzUInt32 flags, unsigned int index) + void GraphicsComponent::InvalidateRenderableData(const Nz::InstancedRenderable* renderable, Nz::UInt32 flags, unsigned int index) { NazaraAssert(index < m_renderables.size(), "Invalid renderable index"); NazaraUnused(renderable); @@ -55,7 +55,7 @@ namespace Ndk InvalidateTransformMatrix(); } - void GraphicsComponent::OnNodeInvalidated(const NzNode* node) + void GraphicsComponent::OnNodeInvalidated(const Nz::Node* node) { NazaraUnused(node); @@ -69,7 +69,7 @@ namespace Ndk Ndk::RenderSystem& renderSystem = m_entity->GetWorld()->GetSystem(); - m_transformMatrix = NzMatrix4f::ConcatenateAffine(renderSystem.GetCoordinateSystemMatrix(), m_entity->GetComponent().GetTransformMatrix()); + m_transformMatrix = Nz::Matrix4f::ConcatenateAffine(renderSystem.GetCoordinateSystemMatrix(), m_entity->GetComponent().GetTransformMatrix()); m_transformMatrixUpdated = true; } diff --git a/SDK/src/NDK/Components/PhysicsComponent.cpp b/SDK/src/NDK/Components/PhysicsComponent.cpp index 6c70dbff7..cc23c0954 100644 --- a/SDK/src/NDK/Components/PhysicsComponent.cpp +++ b/SDK/src/NDK/Components/PhysicsComponent.cpp @@ -17,19 +17,19 @@ namespace Ndk World* entityWorld = m_entity->GetWorld(); NazaraAssert(entityWorld->HasSystem(), "World must have a physics system"); - NzPhysWorld& world = entityWorld->GetSystem().GetWorld(); + Nz::PhysWorld& world = entityWorld->GetSystem().GetWorld(); - NzPhysGeomRef geom; + Nz::PhysGeomRef geom; if (m_entity->HasComponent()) geom = m_entity->GetComponent().GetGeom(); - NzMatrix4f matrix; + Nz::Matrix4f matrix; if (m_entity->HasComponent()) matrix = m_entity->GetComponent().GetTransformMatrix(); else matrix.MakeIdentity(); - m_object.reset(new NzPhysObject(&world, geom, matrix)); + m_object.reset(new Nz::PhysObject(&world, geom, matrix)); m_object->SetMass(1.f); } @@ -47,7 +47,7 @@ namespace Ndk if (IsComponent(component)) { NazaraAssert(m_object, "Invalid object"); - m_object->SetGeom(NzNullGeom::New()); + m_object->SetGeom(Nz::NullGeom::New()); } } diff --git a/SDK/src/NDK/Sdk.cpp b/SDK/src/NDK/Sdk.cpp index b2ed7bad9..3a45b65b3 100644 --- a/SDK/src/NDK/Sdk.cpp +++ b/SDK/src/NDK/Sdk.cpp @@ -35,19 +35,19 @@ namespace Ndk try { - NzErrorFlags errFlags(nzErrorFlag_ThrowException, true); + Nz::ErrorFlags errFlags(Nz::ErrorFlag_ThrowException, true); // Initialisation du moteur // Modules clients - NzAudio::Initialize(); - NzGraphics::Initialize(); + Nz::Audio::Initialize(); + Nz::Graphics::Initialize(); // Modules serveurs - NzLua::Initialize(); - NzNoise::Initialize(); - NzPhysics::Initialize(); - NzUtility::Initialize(); + Nz::Lua::Initialize(); + Nz::Noise::Initialize(); + Nz::Physics::Initialize(); + Nz::Utility::Initialize(); // Initialisation du SDK @@ -76,7 +76,7 @@ namespace Ndk } catch (const std::exception& e) { - NazaraError("Failed to initialize NDK: " + NzString(e.what())); + NazaraError("Failed to initialize NDK: " + Nz::String(e.what())); return false; } @@ -99,14 +99,14 @@ namespace Ndk // Libération du moteur // Modules clients - NzAudio::Uninitialize(); - NzGraphics::Uninitialize(); + Nz::Audio::Uninitialize(); + Nz::Graphics::Uninitialize(); // Modules serveurs - NzLua::Uninitialize(); - NzNoise::Uninitialize(); - NzPhysics::Uninitialize(); - NzUtility::Uninitialize(); + Nz::Lua::Uninitialize(); + Nz::Noise::Uninitialize(); + Nz::Physics::Uninitialize(); + Nz::Utility::Uninitialize(); NazaraNotice("Uninitialized: SDK"); } diff --git a/SDK/src/NDK/Systems/ListenerSystem.cpp b/SDK/src/NDK/Systems/ListenerSystem.cpp index a943b55e5..28fce2e0a 100644 --- a/SDK/src/NDK/Systems/ListenerSystem.cpp +++ b/SDK/src/NDK/Systems/ListenerSystem.cpp @@ -30,22 +30,22 @@ namespace Ndk // On récupère la position et la rotation pour les affecter au listener const NodeComponent& node = entity->GetComponent(); - NzAudio::SetListenerPosition(node.GetPosition(nzCoordSys_Global)); - NzAudio::SetListenerRotation(node.GetRotation(nzCoordSys_Global)); + Nz::Audio::SetListenerPosition(node.GetPosition(Nz::CoordSys_Global)); + Nz::Audio::SetListenerRotation(node.GetRotation(Nz::CoordSys_Global)); // On vérifie la présence d'une donnée de vitesse, et on l'affecte // (La vitesse du listener Audio ne le fait pas se déplacer, mais affecte par exemple l'effet Doppler) if (entity->HasComponent()) { const VelocityComponent& velocity = entity->GetComponent(); - NzAudio::SetListenerVelocity(velocity.linearVelocity); + Nz::Audio::SetListenerVelocity(velocity.linearVelocity); } activeListenerCount++; } if (activeListenerCount > 1) - NazaraWarning(NzString::Number(activeListenerCount) + " listeners were active in the same update loop"); + NazaraWarning(Nz::String::Number(activeListenerCount) + " listeners were active in the same update loop"); } SystemIndex ListenerSystem::systemIndex; diff --git a/SDK/src/NDK/Systems/PhysicsSystem.cpp b/SDK/src/NDK/Systems/PhysicsSystem.cpp index 150aaaac7..3d429a686 100644 --- a/SDK/src/NDK/Systems/PhysicsSystem.cpp +++ b/SDK/src/NDK/Systems/PhysicsSystem.cpp @@ -45,9 +45,9 @@ namespace Ndk NodeComponent& node = entity->GetComponent(); PhysicsComponent& phys = entity->GetComponent(); - NzPhysObject& physObj = phys.GetPhysObject(); - node.SetRotation(physObj.GetRotation(), nzCoordSys_Global); - node.SetPosition(physObj.GetPosition(), nzCoordSys_Global); + Nz::PhysObject& physObj = phys.GetPhysObject(); + node.SetRotation(physObj.GetRotation(), Nz::CoordSys_Global); + node.SetPosition(physObj.GetPosition(), Nz::CoordSys_Global); } float invElapsedTime = 1.f / elapsedTime; @@ -56,12 +56,12 @@ namespace Ndk CollisionComponent& collision = entity->GetComponent(); NodeComponent& node = entity->GetComponent(); - NzPhysObject* physObj = collision.GetStaticBody(); + Nz::PhysObject* physObj = collision.GetStaticBody(); - NzQuaternionf oldRotation = physObj->GetRotation(); - NzVector3f oldPosition = physObj->GetPosition(); - NzQuaternionf newRotation = node.GetRotation(nzCoordSys_Global); - NzVector3f newPosition = node.GetPosition(nzCoordSys_Global); + Nz::Quaternionf oldRotation = physObj->GetRotation(); + Nz::Vector3f oldPosition = physObj->GetPosition(); + Nz::Quaternionf newRotation = node.GetRotation(Nz::CoordSys_Global); + Nz::Vector3f newPosition = node.GetPosition(Nz::CoordSys_Global); // Pour déplacer des objets statiques et assurer les collisions, il faut leur définir une vitesse // (note importante: le moteur physique n'applique pas la vitesse sur les objets statiques) @@ -71,21 +71,21 @@ namespace Ndk physObj->SetVelocity((newPosition - oldPosition) * invElapsedTime); } else - physObj->SetVelocity(NzVector3f::Zero()); + physObj->SetVelocity(Nz::Vector3f::Zero()); if (newRotation != oldRotation) { - NzQuaternionf transition = newRotation * oldRotation.GetConjugate(); - NzEulerAnglesf angles = transition.ToEulerAngles(); - NzVector3f angularVelocity(NzToRadians(angles.pitch * invElapsedTime), - NzToRadians(angles.yaw * invElapsedTime), - NzToRadians(angles.roll * invElapsedTime)); + Nz::Quaternionf transition = newRotation * oldRotation.GetConjugate(); + Nz::EulerAnglesf angles = transition.ToEulerAngles(); + Nz::Vector3f angularVelocity(Nz::ToRadians(angles.pitch * invElapsedTime), + Nz::ToRadians(angles.yaw * invElapsedTime), + Nz::ToRadians(angles.roll * invElapsedTime)); physObj->SetRotation(oldRotation); physObj->SetAngularVelocity(angularVelocity); } else - physObj->SetAngularVelocity(NzVector3f::Zero()); + physObj->SetAngularVelocity(Nz::Vector3f::Zero()); } } diff --git a/SDK/src/NDK/Systems/RenderSystem.cpp b/SDK/src/NDK/Systems/RenderSystem.cpp index 6e7c714fe..7d7956a12 100644 --- a/SDK/src/NDK/Systems/RenderSystem.cpp +++ b/SDK/src/NDK/Systems/RenderSystem.cpp @@ -12,10 +12,10 @@ namespace Ndk { RenderSystem::RenderSystem() : - m_coordinateSystemMatrix(NzMatrix4f::Identity()), + m_coordinateSystemMatrix(Nz::Matrix4f::Identity()), m_coordinateSystemInvalidated(true) { - SetDefaultBackground(NzColorBackground::New()); + SetDefaultBackground(Nz::ColorBackground::New()); SetUpdateRate(0.f); } @@ -73,7 +73,7 @@ namespace Ndk CameraComponent& camComponent = camera->GetComponent(); camComponent.ApplyView(); - NzAbstractRenderQueue* renderQueue = m_renderTechnique.GetRenderQueue(); + Nz::AbstractRenderQueue* renderQueue = m_renderTechnique.GetRenderQueue(); renderQueue->Clear(); //TODO: Culling @@ -91,11 +91,11 @@ namespace Ndk NodeComponent& drawableNode = light->GetComponent(); ///TODO: Cache somehow? - lightComponent.AddToRenderQueue(renderQueue, NzMatrix4f::ConcatenateAffine(m_coordinateSystemMatrix, drawableNode.GetTransformMatrix())); + lightComponent.AddToRenderQueue(renderQueue, Nz::Matrix4f::ConcatenateAffine(m_coordinateSystemMatrix, drawableNode.GetTransformMatrix())); } - NzSceneData sceneData; - sceneData.ambientColor = NzColor(25, 25, 25); + Nz::SceneData sceneData; + sceneData.ambientColor = Nz::Color(25, 25, 25); sceneData.background = m_background; sceneData.viewer = &camComponent; diff --git a/examples/HardwareInfo/main.cpp b/examples/HardwareInfo/main.cpp index bcc76c4c3..e2b9b0b78 100644 --- a/examples/HardwareInfo/main.cpp +++ b/examples/HardwareInfo/main.cpp @@ -15,7 +15,7 @@ #include #include -void printCap(std::ostream& o, const NzString& cap, bool b); +void printCap(std::ostream& o, const String& cap, bool b); int main() { @@ -28,68 +28,68 @@ int main() // Plutôt que d'initialiser le Renderer de Nazara, nous initialisons les deux classes utilisées ici // Elles sont compatibles avec NzInitialiser et seront donc libérées automatiquement // Cela permet d'avoir une initialisation plus rapide et un coût en mémoire moindre - NzInitializer hardwareInfo; + Initializer hardwareInfo; if (hardwareInfo) { // On commence par les informations sur le processeur, Nazara en récupère trois caractéristiques: // 1) La "brand string", qui est une chaîne de 48 caractères identifiant le processeur // 2) Le concepteur du processeur, accessible via une énumération (GetProcessorVendor) ou une chaîne de caractère (GetProcessorVendorName) // 3) Le nombre de processeurs logique, alias bien souvent le nombre de coeurs (logiques), cette valeur est renvoyée par l'OS (Le SMT multiplie donc la valeur réelle) - oss << "Identification: " << NzHardwareInfo::GetProcessorBrandString() << std::endl; - oss << "Concepteur: " << NzHardwareInfo::GetProcessorVendorName() << std::endl; - oss << "Nombre de coeurs logiques: " << NzHardwareInfo::GetProcessorCount() << std::endl; + oss << "Identification: " << HardwareInfo::GetProcessorBrandString() << std::endl; + oss << "Concepteur: " << HardwareInfo::GetProcessorVendorName() << std::endl; + oss << "Nombre de coeurs logiques: " << HardwareInfo::GetProcessorCount() << std::endl; oss << std::endl; // Ensuite, Nazara récupère les capacités du processeur, dont des jeux d'extensions supplémentaires oss << "Rapport des capacites: " << std::endl;// Pas d'accent car écriture dans un fichier (et on ne va pas s'embêter avec ça) - printCap(oss, "-64bits", NzHardwareInfo::HasCapability(nzProcessorCap_x64)); - printCap(oss, "-AVX", NzHardwareInfo::HasCapability(nzProcessorCap_AVX)); - printCap(oss, "-FMA3", NzHardwareInfo::HasCapability(nzProcessorCap_FMA3)); - printCap(oss, "-FMA4", NzHardwareInfo::HasCapability(nzProcessorCap_FMA4)); - printCap(oss, "-MMX", NzHardwareInfo::HasCapability(nzProcessorCap_MMX)); - printCap(oss, "-SSE", NzHardwareInfo::HasCapability(nzProcessorCap_SSE)); - printCap(oss, "-SSE2", NzHardwareInfo::HasCapability(nzProcessorCap_SSE2)); - printCap(oss, "-SSE3", NzHardwareInfo::HasCapability(nzProcessorCap_SSE3)); - printCap(oss, "-SSSE3", NzHardwareInfo::HasCapability(nzProcessorCap_SSSE3)); - printCap(oss, "-SSE4.1", NzHardwareInfo::HasCapability(nzProcessorCap_SSE41)); - printCap(oss, "-SSE4.2", NzHardwareInfo::HasCapability(nzProcessorCap_SSE42)); - printCap(oss, "-SSE4.a", NzHardwareInfo::HasCapability(nzProcessorCap_SSE4a)); + printCap(oss, "-64bits", HardwareInfo::HasCapability(ProcessorCap_x64)); + printCap(oss, "-AVX", HardwareInfo::HasCapability(ProcessorCap_AVX)); + printCap(oss, "-FMA3", HardwareInfo::HasCapability(ProcessorCap_FMA3)); + printCap(oss, "-FMA4", HardwareInfo::HasCapability(ProcessorCap_FMA4)); + printCap(oss, "-MMX", HardwareInfo::HasCapability(ProcessorCap_MMX)); + printCap(oss, "-SSE", HardwareInfo::HasCapability(ProcessorCap_SSE)); + printCap(oss, "-SSE2", HardwareInfo::HasCapability(ProcessorCap_SSE2)); + printCap(oss, "-SSE3", HardwareInfo::HasCapability(ProcessorCap_SSE3)); + printCap(oss, "-SSSE3", HardwareInfo::HasCapability(ProcessorCap_SSSE3)); + printCap(oss, "-SSE4.1", HardwareInfo::HasCapability(ProcessorCap_SSE41)); + printCap(oss, "-SSE4.2", HardwareInfo::HasCapability(ProcessorCap_SSE42)); + printCap(oss, "-SSE4.a", HardwareInfo::HasCapability(ProcessorCap_SSE4a)); } else oss << "Impossible de retrouver les informations du processeur" << std::endl; oss << std::endl << "--Carte graphique--" << std::endl; - // La classe NzOpenGL nous donne accès à des informations sur la carte graphique + // La classe OpenGL nous donne accès à des informations sur la carte graphique // Cependant celle-ci n'est accessible que si le projet est compilé avec NAZARA_RENDERER_OPENGL // et que les répertoires d'inclusions donnent accès aux includes d'OpenGL (Cette démo utilisent ceux de Nazara) - NzInitializer openGL; + Initializer openGL; if (openGL) { // Nous récupérons ensuite la version d'OpenGL sous forme d'entier (ex: OpenGL 3.3 donnera 330) - unsigned int openglVersion = NzOpenGL::GetVersion(); + unsigned int openglVersion = OpenGL::GetVersion(); - // NzOpenGL nous donne accès à trois informations principales: + // OpenGL nous donne accès à trois informations principales: // 1) La chaîne d'identification du driver ("Renderer name") // 2) La chaîne d'identification du concepteur ("Vendor name") // 3) La version d'OpenGL - oss << "Identification: " << NzOpenGL::GetRendererName() << std::endl; - oss << "Concepteur: " << NzOpenGL::GetVendorName() << std::endl; + oss << "Identification: " << OpenGL::GetRendererName() << std::endl; + oss << "Concepteur: " << OpenGL::GetVendorName() << std::endl; oss << "Version d'OpenGL: " << openglVersion/100 << '.' << openglVersion%100 << std::endl; oss << std::endl; // Ainsi qu'un report des capacités de la carte graphique (avec le driver actuel) oss << "Rapport des capacites: " << std::endl; // Pas d'accent car écriture dans un fichier (et on ne va pas s'embêter avec ça) - printCap(oss, "-Calculs 64bits", NzOpenGL::IsSupported(nzOpenGLExtension_FP64)); - printCap(oss, "-Compression de textures (s3tc)", NzOpenGL::IsSupported(nzOpenGLExtension_TextureCompression_s3tc)); - printCap(oss, "-Filtrage anisotrope", NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter)); - printCap(oss, "-Framebuffer Object", NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject)); - printCap(oss, "-Mode debug", NzOpenGL::IsSupported(nzOpenGLExtension_DebugOutput)); - printCap(oss, "-Pixelbuffer Object", NzOpenGL::IsSupported(nzOpenGLExtension_PixelBufferObject)); - printCap(oss, "-Samplers Object", NzOpenGL::IsSupported(nzOpenGLExtension_SamplerObjects)); - printCap(oss, "-Separate shader objects", NzOpenGL::IsSupported(nzOpenGLExtension_SeparateShaderObjects)); - printCap(oss, "-Texture array", NzOpenGL::IsSupported(nzOpenGLExtension_TextureArray)); - printCap(oss, "-Texture storage", NzOpenGL::IsSupported(nzOpenGLExtension_TextureStorage)); - printCap(oss, "-Vertex array objects", NzOpenGL::IsSupported(nzOpenGLExtension_VertexArrayObjects)); + printCap(oss, "-Calculs 64bits", OpenGL::IsSupported(OpenGLExtension_FP64)); + printCap(oss, "-Compression de textures (s3tc)", OpenGL::IsSupported(OpenGLExtension_TextureCompression_s3tc)); + printCap(oss, "-Filtrage anisotrope", OpenGL::IsSupported(OpenGLExtension_AnisotropicFilter)); + printCap(oss, "-Framebuffer Object", OpenGL::IsSupported(OpenGLExtension_FrameBufferObject)); + printCap(oss, "-Mode debug", OpenGL::IsSupported(OpenGLExtension_DebugOutput)); + printCap(oss, "-Pixelbuffer Object", OpenGL::IsSupported(OpenGLExtension_PixelBufferObject)); + printCap(oss, "-Samplers Object", OpenGL::IsSupported(OpenGLExtension_SamplerObjects)); + printCap(oss, "-Separate shader objects", OpenGL::IsSupported(OpenGLExtension_SeparateShaderObjects)); + printCap(oss, "-Texture array", OpenGL::IsSupported(OpenGLExtension_TextureArray)); + printCap(oss, "-Texture storage", OpenGL::IsSupported(OpenGLExtension_TextureStorage)); + printCap(oss, "-Vertex array objects", OpenGL::IsSupported(OpenGLExtension_VertexArrayObjects)); } else oss << "Impossible de retrouver les informations de la carte graphique" << std::endl; @@ -99,10 +99,10 @@ int main() std::cout << oss.str() << std::endl; - NzFile reportFile("RapportHardwareInfo.txt"); - if (reportFile.Open(nzOpenMode_Text | nzOpenMode_Truncate | nzOpenMode_WriteOnly)) + File reportFile("RapportHardwareInfo.txt"); + if (reportFile.Open(OpenMode_Text | OpenMode_Truncate | OpenMode_WriteOnly)) { - reportFile.Write(oss.str()); // Conversion implicite en NzString + reportFile.Write(oss.str()); // Conversion implicite en String reportFile.Close(); char accentAigu = static_cast(130); // C'est crade, mais ça marche chez 95% des Windowsiens @@ -116,7 +116,7 @@ int main() return 0; } -void printCap(std::ostream& o, const NzString& cap, bool b) +void printCap(std::ostream& o, const String& cap, bool b) { if (b) o << cap << ": Oui" << std::endl; diff --git a/examples/MeshInfos/main.cpp b/examples/MeshInfos/main.cpp index 35d816b44..839c20f31 100644 --- a/examples/MeshInfos/main.cpp +++ b/examples/MeshInfos/main.cpp @@ -11,7 +11,7 @@ int main() { // Pour charger des ressources, il est impératif d'initialiser le module utilitaire - NzInitializer utility; + Initializer utility; if (!utility) { // Ça n'a pas fonctionné, le pourquoi se trouve dans le fichier NazaraLog.log @@ -22,7 +22,7 @@ int main() for (;;) { - NzDirectory resourceDirectory("resources/"); + Directory resourceDirectory("resources/"); if (!resourceDirectory.Open()) { std::cerr << "Failed to open resource directory" << std::endl; @@ -30,12 +30,12 @@ int main() return EXIT_FAILURE; } - std::vector models; + std::vector models; while (resourceDirectory.NextResult()) { - NzString path = resourceDirectory.GetResultName(); - NzString ext = path.SubStringFrom('.', -1, true); // Tout ce qui vient après le dernier '.' de la chaîne - if (NzMeshLoader::IsExtensionSupported(ext)) // L'extension est-elle supportée par le MeshLoader ? + String path = resourceDirectory.GetResultName(); + String ext = path.SubStringFrom('.', -1, true); // Tout ce qui vient après le dernier '.' de la chaîne + if (MeshLoader::IsExtensionSupported(ext)) // L'extension est-elle supportée par le MeshLoader ? models.push_back(path); } @@ -67,7 +67,7 @@ int main() if (iChoice == 0) break; - NzMesh mesh; + Mesh mesh; if (!mesh.LoadFromFile("resources/" + models[iChoice-1])) { std::cout << "Failed to load mesh" << std::endl; @@ -77,11 +77,11 @@ int main() switch (mesh.GetAnimationType()) { - case nzAnimationType_Skeletal: + case AnimationType_Skeletal: std::cout << "This is a skeletal-animated mesh" << std::endl; break; - case nzAnimationType_Static: + case AnimationType_Static: std::cout << "This is a static mesh" << std::endl; break; @@ -92,9 +92,9 @@ int main() if (mesh.IsAnimable()) { - if (mesh.GetAnimationType() == nzAnimationType_Skeletal) + if (mesh.GetAnimationType() == AnimationType_Skeletal) { - const NzSkeleton* skeleton = mesh.GetSkeleton(); + const Skeleton* skeleton = mesh.GetSkeleton(); unsigned int jointCount = skeleton->GetJointCount(); std::cout << "It has a skeleton made of " << skeleton->GetJointCount() << " joint(s)." << std::endl; std::cout << "Print joints ? (Y/N) "; @@ -107,10 +107,10 @@ int main() { for (unsigned int i = 0; i < jointCount; ++i) { - const NzJoint* joint = skeleton->GetJoint(i); + const Joint* joint = skeleton->GetJoint(i); std::cout << "\t" << (i+1) << ": " << joint->GetName(); - const NzJoint* parent = static_cast(joint->GetParent()); + const Joint* parent = static_cast(joint->GetParent()); if (parent) std::cout << " (Parent: " << parent->GetName() << ')'; @@ -119,10 +119,10 @@ int main() } } - NzString animationPath = mesh.GetAnimation(); + String animationPath = mesh.GetAnimation(); if (!animationPath.IsEmpty()) { - NzAnimation animation; + Animation animation; if (animation.LoadFromFile(animationPath)) { unsigned int sequenceCount = animation.GetSequenceCount(); @@ -137,7 +137,7 @@ int main() { for (unsigned int i = 0; i < sequenceCount; ++i) { - const NzSequence* sequence = animation.GetSequence(i); + const Sequence* sequence = animation.GetSequence(i); std::cout << "\t" << (i+1) << ": " << sequence->name << std::endl; std::cout << "\t\tStart frame: " << sequence->firstFrame << std::endl; std::cout << "\t\tFrame count: " << sequence->frameCount << std::endl; @@ -153,7 +153,7 @@ int main() std::cout << "It's animable but has no animation information" << std::endl; } - NzBoxf cube = mesh.GetAABB(); + Boxf cube = mesh.GetAABB(); std::cout << "Mesh is " << cube.width << " units wide, " << cube.height << " units height and " << cube.depth << " units depth" << std::endl; unsigned int materialCount = mesh.GetMaterialCount(); diff --git a/include/Nazara/Audio/Algorithm.hpp b/include/Nazara/Audio/Algorithm.hpp index 696d64682..ddb72a6b0 100644 --- a/include/Nazara/Audio/Algorithm.hpp +++ b/include/Nazara/Audio/Algorithm.hpp @@ -9,7 +9,10 @@ #include -template void NzMixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount); +namespace Nz +{ + template void MixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount); +} #include diff --git a/include/Nazara/Audio/Algorithm.inl b/include/Nazara/Audio/Algorithm.inl index c96aa655e..ec89cdca9 100644 --- a/include/Nazara/Audio/Algorithm.inl +++ b/include/Nazara/Audio/Algorithm.inl @@ -5,21 +5,24 @@ #include #include -template -void NzMixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount) +namespace Nz { - ///DOC: Le buffer d'entrée peut être le même que le buffer de sortie - // Pour éviter l'overflow, on utilise comme accumulateur un type assez grand, (u)int 64 bits pour les entiers, double pour les flottants - typedef typename std::conditional::value, nzUInt64, nzInt64>::type BiggestInt; - typedef typename std::conditional::value, BiggestInt, double>::type Biggest; - - for (unsigned int i = 0; i < frameCount; ++i) + template + void MixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount) { - Biggest acc = Biggest(0); - for (unsigned int j = 0; j < channelCount; ++j) - acc += input[i*channelCount + j]; + ///DOC: Le buffer d'entrée peut être le même que le buffer de sortie + // Pour éviter l'overflow, on utilise comme accumulateur un type assez grand, (u)int 64 bits pour les entiers, double pour les flottants + typedef typename std::conditional::value, UInt64, Int64>::type BiggestInt; + typedef typename std::conditional::value, BiggestInt, double>::type Biggest; - output[i] = static_cast(acc/channelCount); + for (unsigned int i = 0; i < frameCount; ++i) + { + Biggest acc = Biggest(0); + for (unsigned int j = 0; j < channelCount; ++j) + acc += input[i*channelCount + j]; + + output[i] = static_cast(acc / channelCount); + } } } diff --git a/include/Nazara/Audio/Audio.hpp b/include/Nazara/Audio/Audio.hpp index c1dd2f508..c80d478d0 100644 --- a/include/Nazara/Audio/Audio.hpp +++ b/include/Nazara/Audio/Audio.hpp @@ -14,41 +14,44 @@ #include #include -class NAZARA_AUDIO_API NzAudio +namespace Nz { - public: - NzAudio() = delete; - ~NzAudio() = delete; + class NAZARA_AUDIO_API Audio + { + public: + Audio() = delete; + ~Audio() = delete; - static nzAudioFormat GetAudioFormat(unsigned int channelCount); - static float GetDopplerFactor(); - static float GetGlobalVolume(); - static NzVector3f GetListenerDirection(); - static NzVector3f GetListenerPosition(); - static NzQuaternionf GetListenerRotation(); - static NzVector3f GetListenerVelocity(); - static float GetSpeedOfSound(); + static AudioFormat GetAudioFormat(unsigned int channelCount); + static float GetDopplerFactor(); + static float GetGlobalVolume(); + static Vector3f GetListenerDirection(); + static Vector3f GetListenerPosition(); + static Quaternionf GetListenerRotation(); + static Vector3f GetListenerVelocity(); + static float GetSpeedOfSound(); - static bool Initialize(); + static bool Initialize(); - static bool IsFormatSupported(nzAudioFormat format); - static bool IsInitialized(); + static bool IsFormatSupported(AudioFormat format); + static bool IsInitialized(); - static void SetDopplerFactor(float dopplerFactor); - static void SetGlobalVolume(float volume); - static void SetListenerDirection(const NzVector3f& direction); - static void SetListenerDirection(float dirX, float dirY, float dirZ); - static void SetListenerPosition(const NzVector3f& position); - static void SetListenerPosition(float x, float y, float z); - static void SetListenerRotation(const NzQuaternionf& rotation); - static void SetListenerVelocity(const NzVector3f& velocity); - static void SetListenerVelocity(float velX, float velY, float velZ); - static void SetSpeedOfSound(float speed); + static void SetDopplerFactor(float dopplerFactor); + static void SetGlobalVolume(float volume); + static void SetListenerDirection(const Vector3f& direction); + static void SetListenerDirection(float dirX, float dirY, float dirZ); + static void SetListenerPosition(const Vector3f& position); + static void SetListenerPosition(float x, float y, float z); + static void SetListenerRotation(const Quaternionf& rotation); + static void SetListenerVelocity(const Vector3f& velocity); + static void SetListenerVelocity(float velX, float velY, float velZ); + static void SetSpeedOfSound(float speed); - static void Uninitialize(); + static void Uninitialize(); - private: - static unsigned int s_moduleReferenceCounter; -}; + private: + static unsigned int s_moduleReferenceCounter; + }; +} #endif // NAZARA_AUDIO_HPP diff --git a/include/Nazara/Audio/Enums.hpp b/include/Nazara/Audio/Enums.hpp index a9d8dd41d..e88a2fa92 100644 --- a/include/Nazara/Audio/Enums.hpp +++ b/include/Nazara/Audio/Enums.hpp @@ -7,26 +7,30 @@ #ifndef NAZARA_ENUMS_HPP #define NAZARA_ENUMS_HPP -enum nzAudioFormat +namespace Nz { - nzAudioFormat_Unknown = -1, - // La valeur entière est le nombre de canaux possédés par ce format - nzAudioFormat_Mono = 1, - nzAudioFormat_Stereo = 2, - nzAudioFormat_Quad = 4, - nzAudioFormat_5_1 = 6, - nzAudioFormat_6_1 = 7, - nzAudioFormat_7_1 = 8, + enum AudioFormat + { + AudioFormat_Unknown = -1, - nzAudioFormat_Max = nzAudioFormat_7_1 -}; + // La valeur entière est le nombre de canaux possédés par ce format + AudioFormat_Mono = 1, + AudioFormat_Stereo = 2, + AudioFormat_Quad = 4, + AudioFormat_5_1 = 6, + AudioFormat_6_1 = 7, + AudioFormat_7_1 = 8, -enum nzSoundStatus -{ - nzSoundStatus_Playing, - nzSoundStatus_Paused, - nzSoundStatus_Stopped -}; + AudioFormat_Max = AudioFormat_7_1 + }; + + enum SoundStatus + { + SoundStatus_Playing, + SoundStatus_Paused, + SoundStatus_Stopped + }; +} #endif // NAZARA_ENUMS_HPP diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index 3c472fbb6..b8b17956e 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -13,65 +13,68 @@ #include #include -struct NzMusicParams +namespace Nz { - bool forceMono = false; + struct MusicParams + { + bool forceMono = false; - bool IsValid() const; -}; + bool IsValid() const; + }; -class NzMusic; -class NzSoundStream; + class Music; + class SoundStream; -using NzMusicLoader = NzResourceLoader; + using MusicLoader = ResourceLoader; -struct NzMusicImpl; + struct MusicImpl; -class NAZARA_AUDIO_API NzMusic : public NzResource, public NzSoundEmitter -{ - friend NzMusicLoader; + class NAZARA_AUDIO_API Music : public Resource, public SoundEmitter + { + friend MusicLoader; - public: - NzMusic() = default; - NzMusic(const NzMusic&) = delete; - NzMusic(NzMusic&&) = delete; ///TODO - ~NzMusic(); + public: + Music() = default; + Music(const Music&) = delete; + Music(Music&&) = delete; ///TODO + ~Music(); - bool Create(NzSoundStream* soundStream); - void Destroy(); + bool Create(SoundStream* soundStream); + void Destroy(); - void EnableLooping(bool loop); + void EnableLooping(bool loop); - nzUInt32 GetDuration() const; - nzAudioFormat GetFormat() const; - nzUInt32 GetPlayingOffset() const; - nzUInt32 GetSampleCount() const; - nzUInt32 GetSampleRate() const; - nzSoundStatus GetStatus() const; + UInt32 GetDuration() const; + AudioFormat GetFormat() const; + UInt32 GetPlayingOffset() const; + UInt32 GetSampleCount() const; + UInt32 GetSampleRate() const; + SoundStatus GetStatus() const; - bool IsLooping() const; + bool IsLooping() const; - bool OpenFromFile(const NzString& filePath, const NzMusicParams& params = NzMusicParams()); - bool OpenFromMemory(const void* data, std::size_t size, const NzMusicParams& params = NzMusicParams()); - bool OpenFromStream(NzInputStream& stream, const NzMusicParams& params = NzMusicParams()); + bool OpenFromFile(const String& filePath, const MusicParams& params = MusicParams()); + bool OpenFromMemory(const void* data, std::size_t size, const MusicParams& params = MusicParams()); + bool OpenFromStream(InputStream& stream, const MusicParams& params = MusicParams()); - void Pause(); - void Play(); + void Pause(); + void Play(); - void SetPlayingOffset(nzUInt32 offset); + void SetPlayingOffset(UInt32 offset); - void Stop(); + void Stop(); - NzMusic& operator=(const NzMusic&) = delete; - NzMusic& operator=(NzMusic&&) = delete; ///TODO + Music& operator=(const Music&) = delete; + Music& operator=(Music&&) = delete; ///TODO - private: - NzMusicImpl* m_impl = nullptr; + private: + MusicImpl* m_impl = nullptr; - bool FillAndQueueBuffer(unsigned int buffer); - void MusicThread(); + bool FillAndQueueBuffer(unsigned int buffer); + void MusicThread(); - static NzMusicLoader::LoaderList s_loaders; -}; + static MusicLoader::LoaderList s_loaders; + }; +} #endif // NAZARA_MUSIC_HPP diff --git a/include/Nazara/Audio/OpenAL.hpp b/include/Nazara/Audio/OpenAL.hpp index 12416c9d4..812b002b6 100644 --- a/include/Nazara/Audio/OpenAL.hpp +++ b/include/Nazara/Audio/OpenAL.hpp @@ -20,168 +20,171 @@ // Étant donné que les headers OpenAL ne nous permettent pas de n'avoir que les signatures sans les pointeurs de fonctions // Et que je ne souhaite pas les modifier, je suis contraint de les placer dans un espace de nom différent pour ensuite // remettre dans l'espace global les choses intéressantes (les typedef notamment) -namespace NzOpenALDetail +namespace OpenALDetail { #include #include } // Si quelqu'un a une meilleure idée ... -using NzOpenALDetail::ALboolean; -using NzOpenALDetail::ALbyte; -using NzOpenALDetail::ALchar; -using NzOpenALDetail::ALdouble; -using NzOpenALDetail::ALenum; -using NzOpenALDetail::ALfloat; -using NzOpenALDetail::ALint; -using NzOpenALDetail::ALshort; -using NzOpenALDetail::ALsizei; -using NzOpenALDetail::ALubyte; -using NzOpenALDetail::ALuint; -using NzOpenALDetail::ALushort; -using NzOpenALDetail::ALvoid; +using OpenALDetail::ALboolean; +using OpenALDetail::ALbyte; +using OpenALDetail::ALchar; +using OpenALDetail::ALdouble; +using OpenALDetail::ALenum; +using OpenALDetail::ALfloat; +using OpenALDetail::ALint; +using OpenALDetail::ALshort; +using OpenALDetail::ALsizei; +using OpenALDetail::ALubyte; +using OpenALDetail::ALuint; +using OpenALDetail::ALushort; +using OpenALDetail::ALvoid; -using NzOpenALDetail::ALCboolean; -using NzOpenALDetail::ALCbyte; -using NzOpenALDetail::ALCchar; -using NzOpenALDetail::ALCcontext; -using NzOpenALDetail::ALCdevice; -using NzOpenALDetail::ALCdouble; -using NzOpenALDetail::ALCenum; -using NzOpenALDetail::ALCfloat; -using NzOpenALDetail::ALCint; -using NzOpenALDetail::ALCshort; -using NzOpenALDetail::ALCsizei; -using NzOpenALDetail::ALCubyte; -using NzOpenALDetail::ALCuint; -using NzOpenALDetail::ALCushort; -using NzOpenALDetail::ALCvoid; +using OpenALDetail::ALCboolean; +using OpenALDetail::ALCbyte; +using OpenALDetail::ALCchar; +using OpenALDetail::ALCcontext; +using OpenALDetail::ALCdevice; +using OpenALDetail::ALCdouble; +using OpenALDetail::ALCenum; +using OpenALDetail::ALCfloat; +using OpenALDetail::ALCint; +using OpenALDetail::ALCshort; +using OpenALDetail::ALCsizei; +using OpenALDetail::ALCubyte; +using OpenALDetail::ALCuint; +using OpenALDetail::ALCushort; +using OpenALDetail::ALCvoid; -using NzOpenALFunc = void (*)(); - -class NAZARA_AUDIO_API NzOpenAL +namespace Nz { - public: - static NzOpenALFunc GetEntry(const NzString& entryPoint); - static NzString GetRendererName(); - static NzString GetVendorName(); - static unsigned int GetVersion(); + using OpenALFunc = void(*)(); - static bool Initialize(bool openDevice = true); + class NAZARA_AUDIO_API OpenAL + { + public: + static OpenALFunc GetEntry(const String& entryPoint); + static String GetRendererName(); + static String GetVendorName(); + static unsigned int GetVersion(); - static bool IsInitialized(); + static bool Initialize(bool openDevice = true); - static unsigned int QueryInputDevices(std::vector& devices); - static unsigned int QueryOutputDevices(std::vector& devices); + static bool IsInitialized(); - static bool SetDevice(const NzString& deviceName); + static unsigned int QueryInputDevices(std::vector& devices); + static unsigned int QueryOutputDevices(std::vector& devices); - static void Uninitialize(); + static bool SetDevice(const String& deviceName); - static ALenum AudioFormat[nzAudioFormat_Max+1]; + static void Uninitialize(); - private: - static void CloseDevice(); - static bool OpenDevice(); - static NzOpenALFunc LoadEntry(const char* name, bool throwException = false); -}; + static ALenum AudioFormat[AudioFormat_Max + 1]; + + private: + static void CloseDevice(); + static bool OpenDevice(); + static OpenALFunc LoadEntry(const char* name, bool throwException = false); + }; +} // al -NAZARA_AUDIO_API extern NzOpenALDetail::LPALBUFFER3F alBuffer3f; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALBUFFER3I alBuffer3i; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALBUFFERDATA alBufferData; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALBUFFERF alBufferf; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALBUFFERFV alBufferfv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALBUFFERI alBufferi; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALBUFFERIV alBufferiv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALDELETEBUFFERS alDeleteBuffers; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALDELETESOURCES alDeleteSources; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALDISABLE alDisable; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALDISTANCEMODEL alDistanceModel; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALDOPPLERFACTOR alDopplerFactor; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALDOPPLERVELOCITY alDopplerVelocity; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALENABLE alEnable; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGENBUFFERS alGenBuffers; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGENSOURCES alGenSources; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETBOOLEAN alGetBoolean; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETBOOLEANV alGetBooleanv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETBUFFER3F alGetBuffer3f; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETBUFFER3I alGetBuffer3i; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETBUFFERF alGetBufferf; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETBUFFERFV alGetBufferfv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETBUFFERI alGetBufferi; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETBUFFERIV alGetBufferiv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETDOUBLE alGetDouble; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETDOUBLEV alGetDoublev; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETENUMVALUE alGetEnumValue; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETERROR alGetError; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETFLOAT alGetFloat; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETFLOATV alGetFloatv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETINTEGER alGetInteger; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETINTEGERV alGetIntegerv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETLISTENER3F alGetListener3f; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETLISTENER3I alGetListener3i; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETLISTENERF alGetListenerf; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETLISTENERFV alGetListenerfv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETLISTENERI alGetListeneri; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETLISTENERIV alGetListeneriv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETPROCADDRESS alGetProcAddress; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETSOURCE3F alGetSource3f; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETSOURCE3I alGetSource3i; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETSOURCEF alGetSourcef; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETSOURCEFV alGetSourcefv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETSOURCEI alGetSourcei; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETSOURCEIV alGetSourceiv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALGETSTRING alGetString; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALISBUFFER alIsBuffer; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALISENABLED alIsEnabled; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALISEXTENSIONPRESENT alIsExtensionPresent; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALISSOURCE alIsSource; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALLISTENER3F alListener3f; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALLISTENER3I alListener3i; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALLISTENERF alListenerf; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALLISTENERFV alListenerfv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALLISTENERI alListeneri; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALLISTENERIV alListeneriv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCE3F alSource3f; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCE3I alSource3i; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCEF alSourcef; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCEFV alSourcefv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCEI alSourcei; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCEIV alSourceiv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCEPAUSE alSourcePause; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCEPAUSEV alSourcePausev; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCEPLAY alSourcePlay; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCEPLAYV alSourcePlayv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCEQUEUEBUFFERS alSourceQueueBuffers; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCEREWIND alSourceRewind; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCEREWINDV alSourceRewindv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCESTOP alSourceStop; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCESTOPV alSourceStopv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSOURCEUNQUEUEBUFFERS alSourceUnqueueBuffers; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALSPEEDOFSOUND alSpeedOfSound; +NAZARA_AUDIO_API extern OpenALDetail::LPALBUFFER3F alBuffer3f; +NAZARA_AUDIO_API extern OpenALDetail::LPALBUFFER3I alBuffer3i; +NAZARA_AUDIO_API extern OpenALDetail::LPALBUFFERDATA alBufferData; +NAZARA_AUDIO_API extern OpenALDetail::LPALBUFFERF alBufferf; +NAZARA_AUDIO_API extern OpenALDetail::LPALBUFFERFV alBufferfv; +NAZARA_AUDIO_API extern OpenALDetail::LPALBUFFERI alBufferi; +NAZARA_AUDIO_API extern OpenALDetail::LPALBUFFERIV alBufferiv; +NAZARA_AUDIO_API extern OpenALDetail::LPALDELETEBUFFERS alDeleteBuffers; +NAZARA_AUDIO_API extern OpenALDetail::LPALDELETESOURCES alDeleteSources; +NAZARA_AUDIO_API extern OpenALDetail::LPALDISABLE alDisable; +NAZARA_AUDIO_API extern OpenALDetail::LPALDISTANCEMODEL alDistanceModel; +NAZARA_AUDIO_API extern OpenALDetail::LPALDOPPLERFACTOR alDopplerFactor; +NAZARA_AUDIO_API extern OpenALDetail::LPALDOPPLERVELOCITY alDopplerVelocity; +NAZARA_AUDIO_API extern OpenALDetail::LPALENABLE alEnable; +NAZARA_AUDIO_API extern OpenALDetail::LPALGENBUFFERS alGenBuffers; +NAZARA_AUDIO_API extern OpenALDetail::LPALGENSOURCES alGenSources; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETBOOLEAN alGetBoolean; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETBOOLEANV alGetBooleanv; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETBUFFER3F alGetBuffer3f; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETBUFFER3I alGetBuffer3i; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETBUFFERF alGetBufferf; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETBUFFERFV alGetBufferfv; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETBUFFERI alGetBufferi; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETBUFFERIV alGetBufferiv; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETDOUBLE alGetDouble; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETDOUBLEV alGetDoublev; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETENUMVALUE alGetEnumValue; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETERROR alGetError; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETFLOAT alGetFloat; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETFLOATV alGetFloatv; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETINTEGER alGetInteger; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETINTEGERV alGetIntegerv; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETLISTENER3F alGetListener3f; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETLISTENER3I alGetListener3i; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETLISTENERF alGetListenerf; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETLISTENERFV alGetListenerfv; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETLISTENERI alGetListeneri; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETLISTENERIV alGetListeneriv; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETPROCADDRESS alGetProcAddress; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETSOURCE3F alGetSource3f; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETSOURCE3I alGetSource3i; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETSOURCEF alGetSourcef; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETSOURCEFV alGetSourcefv; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETSOURCEI alGetSourcei; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETSOURCEIV alGetSourceiv; +NAZARA_AUDIO_API extern OpenALDetail::LPALGETSTRING alGetString; +NAZARA_AUDIO_API extern OpenALDetail::LPALISBUFFER alIsBuffer; +NAZARA_AUDIO_API extern OpenALDetail::LPALISENABLED alIsEnabled; +NAZARA_AUDIO_API extern OpenALDetail::LPALISEXTENSIONPRESENT alIsExtensionPresent; +NAZARA_AUDIO_API extern OpenALDetail::LPALISSOURCE alIsSource; +NAZARA_AUDIO_API extern OpenALDetail::LPALLISTENER3F alListener3f; +NAZARA_AUDIO_API extern OpenALDetail::LPALLISTENER3I alListener3i; +NAZARA_AUDIO_API extern OpenALDetail::LPALLISTENERF alListenerf; +NAZARA_AUDIO_API extern OpenALDetail::LPALLISTENERFV alListenerfv; +NAZARA_AUDIO_API extern OpenALDetail::LPALLISTENERI alListeneri; +NAZARA_AUDIO_API extern OpenALDetail::LPALLISTENERIV alListeneriv; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCE3F alSource3f; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCE3I alSource3i; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCEF alSourcef; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCEFV alSourcefv; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCEI alSourcei; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCEIV alSourceiv; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCEPAUSE alSourcePause; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCEPAUSEV alSourcePausev; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCEPLAY alSourcePlay; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCEPLAYV alSourcePlayv; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCEQUEUEBUFFERS alSourceQueueBuffers; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCEREWIND alSourceRewind; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCEREWINDV alSourceRewindv; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCESTOP alSourceStop; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCESTOPV alSourceStopv; +NAZARA_AUDIO_API extern OpenALDetail::LPALSOURCEUNQUEUEBUFFERS alSourceUnqueueBuffers; +NAZARA_AUDIO_API extern OpenALDetail::LPALSPEEDOFSOUND alSpeedOfSound; // alc -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCCAPTURECLOSEDEVICE alcCaptureCloseDevice; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCCAPTUREOPENDEVICE alcCaptureOpenDevice; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCCAPTURESAMPLES alcCaptureSamples; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCCAPTURESTART alcCaptureStart; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCCAPTURESTOP alcCaptureStop; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCCLOSEDEVICE alcCloseDevice; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCCREATECONTEXT alcCreateContext; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCDESTROYCONTEXT alcDestroyContext; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCGETCONTEXTSDEVICE alcGetContextsDevice; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCGETCURRENTCONTEXT alcGetCurrentContext; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCGETENUMVALUE alcGetEnumValue; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCGETERROR alcGetError; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCGETINTEGERV alcGetIntegerv; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCGETPROCADDRESS alcGetProcAddress; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCGETSTRING alcGetString; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCISEXTENSIONPRESENT alcIsExtensionPresent; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCMAKECONTEXTCURRENT alcMakeContextCurrent; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCOPENDEVICE alcOpenDevice; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCPROCESSCONTEXT alcProcessContext; -NAZARA_AUDIO_API extern NzOpenALDetail::LPALCSUSPENDCONTEXT alcSuspendContext; +NAZARA_AUDIO_API extern OpenALDetail::LPALCCAPTURECLOSEDEVICE alcCaptureCloseDevice; +NAZARA_AUDIO_API extern OpenALDetail::LPALCCAPTUREOPENDEVICE alcCaptureOpenDevice; +NAZARA_AUDIO_API extern OpenALDetail::LPALCCAPTURESAMPLES alcCaptureSamples; +NAZARA_AUDIO_API extern OpenALDetail::LPALCCAPTURESTART alcCaptureStart; +NAZARA_AUDIO_API extern OpenALDetail::LPALCCAPTURESTOP alcCaptureStop; +NAZARA_AUDIO_API extern OpenALDetail::LPALCCLOSEDEVICE alcCloseDevice; +NAZARA_AUDIO_API extern OpenALDetail::LPALCCREATECONTEXT alcCreateContext; +NAZARA_AUDIO_API extern OpenALDetail::LPALCDESTROYCONTEXT alcDestroyContext; +NAZARA_AUDIO_API extern OpenALDetail::LPALCGETCONTEXTSDEVICE alcGetContextsDevice; +NAZARA_AUDIO_API extern OpenALDetail::LPALCGETCURRENTCONTEXT alcGetCurrentContext; +NAZARA_AUDIO_API extern OpenALDetail::LPALCGETENUMVALUE alcGetEnumValue; +NAZARA_AUDIO_API extern OpenALDetail::LPALCGETERROR alcGetError; +NAZARA_AUDIO_API extern OpenALDetail::LPALCGETINTEGERV alcGetIntegerv; +NAZARA_AUDIO_API extern OpenALDetail::LPALCGETPROCADDRESS alcGetProcAddress; +NAZARA_AUDIO_API extern OpenALDetail::LPALCGETSTRING alcGetString; +NAZARA_AUDIO_API extern OpenALDetail::LPALCISEXTENSIONPRESENT alcIsExtensionPresent; +NAZARA_AUDIO_API extern OpenALDetail::LPALCMAKECONTEXTCURRENT alcMakeContextCurrent; +NAZARA_AUDIO_API extern OpenALDetail::LPALCOPENDEVICE alcOpenDevice; +NAZARA_AUDIO_API extern OpenALDetail::LPALCPROCESSCONTEXT alcProcessContext; +NAZARA_AUDIO_API extern OpenALDetail::LPALCSUSPENDCONTEXT alcSuspendContext; #endif // NAZARA_AUDIO_OPENAL diff --git a/include/Nazara/Audio/Sound.hpp b/include/Nazara/Audio/Sound.hpp index 3381a1ad6..a8de761de 100644 --- a/include/Nazara/Audio/Sound.hpp +++ b/include/Nazara/Audio/Sound.hpp @@ -12,43 +12,46 @@ #include #include -class NAZARA_AUDIO_API NzSound : public NzSoundEmitter +namespace Nz { - public: - NzSound() = default; - NzSound(const NzSoundBuffer* soundBuffer); - NzSound(const NzSound& sound); - NzSound(NzSound&&) = default; - ~NzSound(); + class NAZARA_AUDIO_API Sound : public SoundEmitter + { + public: + Sound() = default; + Sound(const SoundBuffer* soundBuffer); + Sound(const Sound& sound); + Sound(Sound&&) = default; + ~Sound(); - void EnableLooping(bool loop); + void EnableLooping(bool loop); - const NzSoundBuffer* GetBuffer() const; - nzUInt32 GetDuration() const; - nzUInt32 GetPlayingOffset() const; - nzSoundStatus GetStatus() const; + const SoundBuffer* GetBuffer() const; + UInt32 GetDuration() const; + UInt32 GetPlayingOffset() const; + SoundStatus GetStatus() const; - bool IsLooping() const; - bool IsPlayable() const; - bool IsPlaying() const; + bool IsLooping() const; + bool IsPlayable() const; + bool IsPlaying() const; - bool LoadFromFile(const NzString& filePath, const NzSoundBufferParams& params = NzSoundBufferParams()); - bool LoadFromMemory(const void* data, std::size_t size, const NzSoundBufferParams& params = NzSoundBufferParams()); - bool LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params = NzSoundBufferParams()); + bool LoadFromFile(const String& filePath, const SoundBufferParams& params = SoundBufferParams()); + bool LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params = SoundBufferParams()); + bool LoadFromStream(InputStream& stream, const SoundBufferParams& params = SoundBufferParams()); - void Pause(); - void Play(); + void Pause(); + void Play(); - void SetBuffer(const NzSoundBuffer* buffer); - void SetPlayingOffset(nzUInt32 offset); + void SetBuffer(const SoundBuffer* buffer); + void SetPlayingOffset(UInt32 offset); - void Stop(); + void Stop(); - NzSound& operator=(const NzSound&) = delete; ///TODO? - NzSound& operator=(NzSound&&) = default; + Sound& operator=(const Sound&) = delete; ///TODO? + Sound& operator=(Sound&&) = default; - private: - NzSoundBufferConstRef m_buffer; -}; + private: + SoundBufferConstRef m_buffer; + }; +} #endif // NAZARA_SOUND_HPP diff --git a/include/Nazara/Audio/SoundBuffer.hpp b/include/Nazara/Audio/SoundBuffer.hpp index 259fa7145..883825524 100644 --- a/include/Nazara/Audio/SoundBuffer.hpp +++ b/include/Nazara/Audio/SoundBuffer.hpp @@ -19,77 +19,80 @@ #include #include -struct NzSoundBufferParams +namespace Nz { - bool forceMono = false; - - bool IsValid() const; -}; - -class NzSound; -class NzSoundBuffer; - -using NzSoundBufferConstRef = NzObjectRef; -using NzSoundBufferLibrary = NzObjectLibrary; -using NzSoundBufferLoader = NzResourceLoader; -using NzSoundBufferManager = NzResourceManager; -using NzSoundBufferRef = NzObjectRef; - -struct NzSoundBufferImpl; - -class NAZARA_AUDIO_API NzSoundBuffer : public NzRefCounted, public NzResource -{ - friend NzSound; - friend NzSoundBufferLibrary; - friend NzSoundBufferLoader; - friend NzSoundBufferManager; - friend class NzAudio; - - public: - NzSoundBuffer() = default; - NzSoundBuffer(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples); - NzSoundBuffer(const NzSoundBuffer&) = delete; - NzSoundBuffer(NzSoundBuffer&&) = delete; - ~NzSoundBuffer(); - - bool Create(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples); - void Destroy(); - - nzUInt32 GetDuration() const; - nzAudioFormat GetFormat() const; - const nzInt16* GetSamples() const; - nzUInt32 GetSampleCount() const; - nzUInt32 GetSampleRate() const; + struct SoundBufferParams + { + bool forceMono = false; bool IsValid() const; + }; - bool LoadFromFile(const NzString& filePath, const NzSoundBufferParams& params = NzSoundBufferParams()); - bool LoadFromMemory(const void* data, std::size_t size, const NzSoundBufferParams& params = NzSoundBufferParams()); - bool LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params = NzSoundBufferParams()); + class Sound; + class SoundBuffer; - static bool IsFormatSupported(nzAudioFormat format); - template static NzSoundBufferRef New(Args&&... args); + using SoundBufferConstRef = ObjectRef; + using SoundBufferLibrary = ObjectLibrary; + using SoundBufferLoader = ResourceLoader; + using SoundBufferManager = ResourceManager; + using SoundBufferRef = ObjectRef; - NzSoundBuffer& operator=(const NzSoundBuffer&) = delete; - NzSoundBuffer& operator=(NzSoundBuffer&&) = delete; ///TODO + struct SoundBufferImpl; - // Signals: - NazaraSignal(OnSoundBufferDestroy, const NzSoundBuffer* /*soundBuffer*/); - NazaraSignal(OnSoundBufferRelease, const NzSoundBuffer* /*soundBuffer*/); + class NAZARA_AUDIO_API SoundBuffer : public RefCounted, public Resource + { + friend Sound; + friend SoundBufferLibrary; + friend SoundBufferLoader; + friend SoundBufferManager; + friend class Audio; - private: - unsigned int GetOpenALBuffer() const; + public: + SoundBuffer() = default; + SoundBuffer(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples); + SoundBuffer(const SoundBuffer&) = delete; + SoundBuffer(SoundBuffer&&) = delete; + ~SoundBuffer(); - static bool Initialize(); - static void Uninitialize(); + bool Create(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples); + void Destroy(); - NzSoundBufferImpl* m_impl = nullptr; + UInt32 GetDuration() const; + AudioFormat GetFormat() const; + const Int16* GetSamples() const; + UInt32 GetSampleCount() const; + UInt32 GetSampleRate() const; - static NzSoundBufferLibrary::LibraryMap s_library; - static NzSoundBufferLoader::LoaderList s_loaders; - static NzSoundBufferManager::ManagerMap s_managerMap; - static NzSoundBufferManager::ManagerParams s_managerParameters; -}; + bool IsValid() const; + + bool LoadFromFile(const String& filePath, const SoundBufferParams& params = SoundBufferParams()); + bool LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params = SoundBufferParams()); + bool LoadFromStream(InputStream& stream, const SoundBufferParams& params = SoundBufferParams()); + + static bool IsFormatSupported(AudioFormat format); + template static SoundBufferRef New(Args&&... args); + + SoundBuffer& operator=(const SoundBuffer&) = delete; + SoundBuffer& operator=(SoundBuffer&&) = delete; ///TODO + + // Signals: + NazaraSignal(OnSoundBufferDestroy, const SoundBuffer* /*soundBuffer*/); + NazaraSignal(OnSoundBufferRelease, const SoundBuffer* /*soundBuffer*/); + + private: + unsigned int GetOpenALBuffer() const; + + static bool Initialize(); + static void Uninitialize(); + + SoundBufferImpl* m_impl = nullptr; + + static SoundBufferLibrary::LibraryMap s_library; + static SoundBufferLoader::LoaderList s_loaders; + static SoundBufferManager::ManagerMap s_managerMap; + static SoundBufferManager::ManagerParams s_managerParameters; + }; +} #include diff --git a/include/Nazara/Audio/SoundBuffer.inl b/include/Nazara/Audio/SoundBuffer.inl index ca95239ea..9c5d1198b 100644 --- a/include/Nazara/Audio/SoundBuffer.inl +++ b/include/Nazara/Audio/SoundBuffer.inl @@ -5,13 +5,16 @@ #include #include -template -NzSoundBufferRef NzSoundBuffer::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzSoundBuffer(std::forward(args)...)); - object->SetPersistent(false); + template + SoundBufferRef SoundBuffer::New(Args&&... args) + { + std::unique_ptr object(new SoundBuffer(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Audio/SoundEmitter.hpp b/include/Nazara/Audio/SoundEmitter.hpp index 4935b39d7..d05045114 100644 --- a/include/Nazara/Audio/SoundEmitter.hpp +++ b/include/Nazara/Audio/SoundEmitter.hpp @@ -15,52 +15,54 @@ ///TODO: Faire hériter SoundEmitter de Node -class NAZARA_AUDIO_API NzSoundEmitter +namespace Nz { - public: - virtual ~NzSoundEmitter(); + class NAZARA_AUDIO_API SoundEmitter + { + public: + virtual ~SoundEmitter(); - virtual void EnableLooping(bool loop) = 0; - void EnableSpatialization(bool spatialization); + virtual void EnableLooping(bool loop) = 0; + void EnableSpatialization(bool spatialization); - float GetAttenuation() const; - virtual nzUInt32 GetDuration() const = 0; - float GetMinDistance() const; - float GetPitch() const; - virtual nzUInt32 GetPlayingOffset() const = 0; - NzVector3f GetPosition() const; - NzVector3f GetVelocity() const; - virtual nzSoundStatus GetStatus() const = 0; - float GetVolume() const; + float GetAttenuation() const; + virtual UInt32 GetDuration() const = 0; + float GetMinDistance() const; + float GetPitch() const; + virtual UInt32 GetPlayingOffset() const = 0; + Vector3f GetPosition() const; + Vector3f GetVelocity() const; + virtual SoundStatus GetStatus() const = 0; + float GetVolume() const; - virtual bool IsLooping() const = 0; - bool IsSpatialized() const; + virtual bool IsLooping() const = 0; + bool IsSpatialized() const; - virtual void Pause() = 0; - virtual void Play() = 0; + virtual void Pause() = 0; + virtual void Play() = 0; - void SetAttenuation(float attenuation); - void SetMinDistance(float minDistance); - void SetPitch(float pitch); - void SetPosition(const NzVector3f& position); - void SetPosition(float x, float y, float z); - void SetVelocity(const NzVector3f& velocity); - void SetVelocity(float velX, float velY, float velZ); - void SetVolume(float volume); + void SetAttenuation(float attenuation); + void SetMinDistance(float minDistance); + void SetPitch(float pitch); + void SetPosition(const Vector3f& position); + void SetPosition(float x, float y, float z); + void SetVelocity(const Vector3f& velocity); + void SetVelocity(float velX, float velY, float velZ); + void SetVolume(float volume); - virtual void Stop() = 0; + virtual void Stop() = 0; - NzSoundEmitter& operator=(const NzSoundEmitter&) = delete; ///TODO - NzSoundEmitter& operator=(NzSoundEmitter&&) = delete; ///TODO + SoundEmitter& operator=(const SoundEmitter&) = delete; ///TODO + SoundEmitter& operator=(SoundEmitter&&) = delete; ///TODO - protected: - NzSoundEmitter(); - NzSoundEmitter(const NzSoundEmitter& emitter); - NzSoundEmitter(NzSoundEmitter&&) = delete; ///TODO + protected: + SoundEmitter(); + SoundEmitter(const SoundEmitter& emitter); + SoundEmitter(SoundEmitter&&) = delete; ///TODO - nzSoundStatus GetInternalStatus() const; - - unsigned int m_source; -}; + SoundStatus GetInternalStatus() const; + unsigned int m_source; + }; +} #endif // NAZARA_SOUNDEMITTER_HPP diff --git a/include/Nazara/Audio/SoundStream.hpp b/include/Nazara/Audio/SoundStream.hpp index f59a7dd8f..4edc7b412 100644 --- a/include/Nazara/Audio/SoundStream.hpp +++ b/include/Nazara/Audio/SoundStream.hpp @@ -11,19 +11,22 @@ #include #include -class NAZARA_AUDIO_API NzSoundStream +namespace Nz { - public: - NzSoundStream() = default; - virtual ~NzSoundStream(); + class NAZARA_AUDIO_API SoundStream + { + public: + SoundStream() = default; + virtual ~SoundStream(); - virtual nzUInt32 GetDuration() const = 0; - virtual nzAudioFormat GetFormat() const = 0; - virtual nzUInt32 GetSampleCount() const = 0; - virtual nzUInt32 GetSampleRate() const = 0; + virtual UInt32 GetDuration() const = 0; + virtual AudioFormat GetFormat() const = 0; + virtual UInt32 GetSampleCount() const = 0; + virtual UInt32 GetSampleRate() const = 0; - virtual unsigned int Read(void* buffer, unsigned int sampleCount) = 0; - virtual void Seek(nzUInt32 offset) = 0; -}; + virtual unsigned int Read(void* buffer, unsigned int sampleCount) = 0; + virtual void Seek(UInt32 offset) = 0; + }; +} #endif // NAZARA_SOUNDSTREAM_HPP diff --git a/include/Nazara/Core/AbstractHash.hpp b/include/Nazara/Core/AbstractHash.hpp index e63a025aa..7314b1b59 100644 --- a/include/Nazara/Core/AbstractHash.hpp +++ b/include/Nazara/Core/AbstractHash.hpp @@ -9,22 +9,25 @@ #include -class NzHashDigest; - -class NAZARA_CORE_API NzAbstractHash +namespace Nz { - public: - NzAbstractHash() = default; - NzAbstractHash(const NzAbstractHash&) = delete; - NzAbstractHash(NzAbstractHash&&) = default; - virtual ~NzAbstractHash(); + class HashDigest; - virtual void Append(const nzUInt8* data, unsigned int len) = 0; - virtual void Begin() = 0; - virtual NzHashDigest End() = 0; + class NAZARA_CORE_API AbstractHash + { + public: + AbstractHash() = default; + AbstractHash(const AbstractHash&) = delete; + AbstractHash(AbstractHash&&) = default; + virtual ~AbstractHash(); - NzAbstractHash& operator=(const NzAbstractHash&) = delete; - NzAbstractHash& operator=(NzAbstractHash&&) = default; -}; + virtual void Append(const UInt8* data, unsigned int len) = 0; + virtual void Begin() = 0; + virtual HashDigest End() = 0; + + AbstractHash& operator=(const AbstractHash&) = delete; + AbstractHash& operator=(AbstractHash&&) = default; + }; +} #endif // NAZARA_ABSTRACTHASH_HPP diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index 462175307..b91250049 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -11,12 +11,15 @@ #include #include -template auto NzApply(F&& fn, Tuple&& t); -template auto NzApply(O& object, F&& fn, Tuple&& t); -template void NzHashCombine(std::size_t& seed, const T& v); +namespace Nz +{ + template auto Apply(F&& fn, Tuple&& t); + template auto Apply(O& object, F&& fn, Tuple&& t); + template void HashCombine(std::size_t& seed, const T& v); -template -struct NzTypeTag {}; + template + struct TypeTag {}; +} #include diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 028085917..b01c1e176 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -8,49 +8,55 @@ #include -// http://www.cppsamples.com/common-tasks/apply-tuple-to-function.html -template -auto NzApplyImplFunc(F&& fn, Tuple&& t, std::index_sequence) +namespace Nz { - return std::forward(fn)(std::get(std::forward(t))...); -} + namespace Detail + { + // http://www.cppsamples.com/common-tasks/apply-tuple-to-function.html + template + auto ApplyImplFunc(F&& fn, Tuple&& t, std::index_sequence) + { + return std::forward(fn)(std::get(std::forward(t))...); + } -template -auto NzApply(F&& fn, Tuple&& t) -{ - constexpr std::size_t tSize = std::tuple_size::type>::value; + template + auto ApplyImplMethod(O& object, F&& fn, Tuple&& t, std::index_sequence) + { + return (object .* std::forward(fn))(std::get(std::forward(t))...); + } + } - return NzApplyImplFunc(std::forward(fn), std::forward(t), std::make_index_sequence()); -} + template + auto Apply(F&& fn, Tuple&& t) + { + constexpr std::size_t tSize = std::tuple_size::type>::value; -template -auto NzApplyImplMethod(O& object, F&& fn, Tuple&& t, std::index_sequence) -{ - return (object .* std::forward(fn))(std::get(std::forward(t))...); -} + return Detail::ApplyImplFunc(std::forward(fn), std::forward(t), std::make_index_sequence()); + } -template -auto NzApply(O& object, F&& fn, Tuple&& t) -{ - constexpr std::size_t tSize = std::tuple_size::type>::value; + template + auto Apply(O& object, F&& fn, Tuple&& t) + { + constexpr std::size_t tSize = std::tuple_size::type>::value; - return NzApplyImplMethod(object, std::forward(fn), std::forward(t), std::make_index_sequence()); -} -// Algorithme venant de CityHash par Google -// http://stackoverflow.com/questions/8513911/how-to-create-a-good-hash-combine-with-64-bit-output-inspired-by-boosthash-co -template -void NzHashCombine(std::size_t& seed, const T& v) -{ - const nzUInt64 kMul = 0x9ddfea08eb382d69ULL; + return Detail::ApplyImplMethod(object, std::forward(fn), std::forward(t), std::make_index_sequence()); + } + // Algorithme venant de CityHash par Google + // http://stackoverflow.com/questions/8513911/how-to-create-a-good-hash-combine-with-64-bit-output-inspired-by-boosthash-co + template + void HashCombine(std::size_t& seed, const T& v) + { + const UInt64 kMul = 0x9ddfea08eb382d69ULL; - std::hash hasher; - nzUInt64 a = (hasher(v) ^ seed) * kMul; - a ^= (a >> 47); + std::hash hasher; + UInt64 a = (hasher(v) ^ seed) * kMul; + a ^= (a >> 47); - nzUInt64 b = (seed ^ a) * kMul; - b ^= (b >> 47); + UInt64 b = (seed ^ a) * kMul; + b ^= (b >> 47); - seed = static_cast(b * kMul); + seed = static_cast(b * kMul); + } } #include diff --git a/include/Nazara/Core/Bitset.hpp b/include/Nazara/Core/Bitset.hpp index 4fbf582d5..ba60ae062 100644 --- a/include/Nazara/Core/Bitset.hpp +++ b/include/Nazara/Core/Bitset.hpp @@ -12,165 +12,168 @@ #include #include -class NzAbstractHash; - -template> -class NzBitset +namespace Nz { - static_assert(std::is_integral::value && std::is_unsigned::value, "Block must be a unsigned integral type"); + class AbstractHash; - public: - class Bit; + template> + class Bitset + { + static_assert(std::is_integral::value && std::is_unsigned::value, "Block must be a unsigned integral type"); - NzBitset(); - explicit NzBitset(unsigned int bitCount, bool val = false); - explicit NzBitset(const char* bits); - NzBitset(const char* bits, unsigned int bitCount); - NzBitset(const NzBitset& bitset) = default; - explicit NzBitset(const NzString& bits); - NzBitset(NzBitset&& bitset) noexcept = default; - ~NzBitset() = default; + public: + class Bit; - void Clear(); - unsigned int Count() const; - void Flip(); + Bitset(); + explicit Bitset(unsigned int bitCount, bool val = false); + explicit Bitset(const char* bits); + Bitset(const char* bits, unsigned int bitCount); + Bitset(const Bitset& bitset) = default; + explicit Bitset(const String& bits); + Bitset(Bitset&& bitset) noexcept = default; + ~Bitset() = default; - unsigned int FindFirst() const; - unsigned int FindNext(unsigned int bit) const; + void Clear(); + unsigned int Count() const; + void Flip(); - Block GetBlock(unsigned int i) const; - unsigned int GetBlockCount() const; - unsigned int GetCapacity() const; - unsigned int GetSize() const; + unsigned int FindFirst() const; + unsigned int FindNext(unsigned int bit) const; - void PerformsAND(const NzBitset& a, const NzBitset& b); - void PerformsNOT(const NzBitset& a); - void PerformsOR(const NzBitset& a, const NzBitset& b); - void PerformsXOR(const NzBitset& a, const NzBitset& b); + Block GetBlock(unsigned int i) const; + unsigned int GetBlockCount() const; + unsigned int GetCapacity() const; + unsigned int GetSize() const; - bool Intersects(const NzBitset& bitset) const; + void PerformsAND(const Bitset& a, const Bitset& b); + void PerformsNOT(const Bitset& a); + void PerformsOR(const Bitset& a, const Bitset& b); + void PerformsXOR(const Bitset& a, const Bitset& b); - void Reserve(unsigned int bitCount); - void Resize(unsigned int bitCount, bool defaultVal = false); + bool Intersects(const Bitset& bitset) const; - void Reset(); - void Reset(unsigned int bit); + void Reserve(unsigned int bitCount); + void Resize(unsigned int bitCount, bool defaultVal = false); - void Set(bool val = true); - void Set(unsigned int bit, bool val = true); - void SetBlock(unsigned int i, Block block); + void Reset(); + void Reset(unsigned int bit); - void Swap(NzBitset& bitset); + void Set(bool val = true); + void Set(unsigned int bit, bool val = true); + void SetBlock(unsigned int i, Block block); - bool Test(unsigned int bit) const; - bool TestAll() const; - bool TestAny() const; - bool TestNone() const; + void Swap(Bitset& bitset); - template T To() const; - NzString ToString() const; + bool Test(unsigned int bit) const; + bool TestAll() const; + bool TestAny() const; + bool TestNone() const; - void UnboundedReset(unsigned int bit); - void UnboundedSet(unsigned int bit, bool val = true); - bool UnboundedTest(unsigned int bit) const; + template T To() const; + String ToString() const; - Bit operator[](int index); - bool operator[](int index) const; + void UnboundedReset(unsigned int bit); + void UnboundedSet(unsigned int bit, bool val = true); + bool UnboundedTest(unsigned int bit) const; - NzBitset operator~() const; + Bit operator[](int index); + bool operator[](int index) const; - NzBitset& operator=(const NzBitset& bitset) = default; - NzBitset& operator=(const NzString& bits); - NzBitset& operator=(NzBitset&& bitset) noexcept = default; + Bitset operator~() const; - NzBitset& operator&=(const NzBitset& bitset); - NzBitset& operator|=(const NzBitset& bitset); - NzBitset& operator^=(const NzBitset& bitset); + Bitset& operator=(const Bitset& bitset) = default; + Bitset& operator=(const String& bits); + Bitset& operator=(Bitset&& bitset) noexcept = default; - static Block fullBitMask; - static unsigned int bitsPerBlock; - static unsigned int npos; + Bitset& operator&=(const Bitset& bitset); + Bitset& operator|=(const Bitset& bitset); + Bitset& operator^=(const Bitset& bitset); - private: - unsigned int FindFirstFrom(unsigned int blockIndex) const; - Block GetLastBlockMask() const; - void ResetExtraBits(); + static Block fullBitMask; + static unsigned int bitsPerBlock; + static unsigned int npos; - static unsigned int ComputeBlockCount(unsigned int bitCount); - static unsigned int GetBitIndex(unsigned int bit); - static unsigned int GetBlockIndex(unsigned int bit); + private: + unsigned int FindFirstFrom(unsigned int blockIndex) const; + Block GetLastBlockMask() const; + void ResetExtraBits(); - std::vector m_blocks; - unsigned int m_bitCount; -}; + static unsigned int ComputeBlockCount(unsigned int bitCount); + static unsigned int GetBitIndex(unsigned int bit); + static unsigned int GetBlockIndex(unsigned int bit); -template -bool operator==(const NzBitset& lhs, const NzBitset& rhs); + std::vector m_blocks; + unsigned int m_bitCount; + }; -template -bool operator!=(const NzBitset& lhs, const NzBitset& rhs); + template + class Bitset::Bit + { + friend Bitset; -template -bool operator<(const NzBitset& lhs, const NzBitset& rhs); + public: + Bit(const Bit& bit) = default; -template -bool operator<=(const NzBitset& lhs, const NzBitset& rhs); + Bit& Flip(); + Bit& Reset(); + Bit& Set(bool val = true); + bool Test() const; -template -bool operator>(const NzBitset& lhs, const NzBitset& rhs); + template + void* operator&() const; -template -bool operator>=(const NzBitset& lhs, const NzBitset& rhs); + operator bool() const; + Bit& operator=(bool val); + Bit& operator=(const Bit& bit); -template -NzBitset operator&(const NzBitset& lhs, const NzBitset& rhs); + Bit& operator|=(bool val); + Bit& operator&=(bool val); + Bit& operator^=(bool val); + Bit& operator-=(bool val); -template -NzBitset operator|(const NzBitset& lhs, const NzBitset& rhs); + private: + Bit(Block& block, Block mask) : + m_block(block), + m_mask(mask) + { + } -template -NzBitset operator^(const NzBitset& lhs, const NzBitset& rhs); + Block& m_block; + Block m_mask; + }; -template -class NzBitset::Bit -{ - friend NzBitset; + template + bool operator==(const Bitset& lhs, const Nz::Bitset& rhs); - public: - Bit(const Bit& bit) = default; + template + bool operator!=(const Bitset& lhs, const Nz::Bitset& rhs); - Bit& Flip(); - Bit& Reset(); - Bit& Set(bool val = true); - bool Test() const; + template + bool operator<(const Bitset& lhs, const Nz::Bitset& rhs); - template - void* operator&() const; + template + bool operator<=(const Bitset& lhs, const Nz::Bitset& rhs); - operator bool() const; - Bit& operator=(bool val); - Bit& operator=(const Bit& bit); + template + bool operator>(const Bitset& lhs, const Nz::Bitset& rhs); - Bit& operator|=(bool val); - Bit& operator&=(bool val); - Bit& operator^=(bool val); - Bit& operator-=(bool val); + template + bool operator>=(const Bitset& lhs, const Nz::Bitset& rhs); - private: - Bit(Block& block, Block mask) : - m_block(block), - m_mask(mask) - { - } + template + Bitset operator&(const Bitset& lhs, const Bitset& rhs); - Block& m_block; - Block m_mask; -}; + template + Bitset operator|(const Bitset& lhs, const Bitset& rhs); + + template + Bitset operator^(const Bitset& lhs, const Bitset& rhs); +} namespace std { template - void swap(NzBitset& lhs, NzBitset& rhs); + void swap(Nz::Bitset& lhs, Nz::Bitset& rhs); } #include diff --git a/include/Nazara/Core/Bitset.inl b/include/Nazara/Core/Bitset.inl index eb7720015..54edf9f67 100644 --- a/include/Nazara/Core/Bitset.inl +++ b/include/Nazara/Core/Bitset.inl @@ -14,748 +14,751 @@ #pragma warning(disable: 4804) #endif -template -NzBitset::NzBitset() : -m_bitCount(0) +namespace Nz { -} - -template -NzBitset::NzBitset(unsigned int bitCount, bool val) : -NzBitset() -{ - Resize(bitCount, val); -} - -template -NzBitset::NzBitset(const char* bits) : -NzBitset(bits, std::strlen(bits)) -{ -} - -template -NzBitset::NzBitset(const char* bits, unsigned int bitCount) : -m_blocks(ComputeBlockCount(bitCount), 0U), -m_bitCount(bitCount) -{ - for (unsigned int i = 0; i < bitCount; ++i) + template + Bitset::Bitset() : + m_bitCount(0) { - switch (*bits++) + } + + template + Bitset::Bitset(unsigned int bitCount, bool val) : + Bitset() + { + Resize(bitCount, val); + } + + template + Bitset::Bitset(const char* bits) : + Bitset(bits, std::strlen(bits)) + { + } + + template + Bitset::Bitset(const char* bits, unsigned int bitCount) : + m_blocks(ComputeBlockCount(bitCount), 0U), + m_bitCount(bitCount) + { + for (unsigned int i = 0; i < bitCount; ++i) { - case '1': - // On adapte l'indice (inversion par rapport à la chaîne) - Set(m_bitCount - i - 1, true); - break; + switch (*bits++) + { + case '1': + // On adapte l'indice (inversion par rapport à la chaîne) + Set(m_bitCount - i - 1, true); + break; - case '0': - // Tous les blocs ont été initialisés à zéro, rien à faire ici - break; + case '0': + // Tous les blocs ont été initialisés à zéro, rien à faire ici + break; - default: - NazaraAssert(false, "Unexpected char (neither 1 nor 0)"); - break; + default: + NazaraAssert(false, "Unexpected char (neither 1 nor 0)"); + break; + } } } -} -template -NzBitset::NzBitset(const NzString& bits) : -NzBitset(bits.GetConstBuffer(), bits.GetSize()) -{ -} - -template -void NzBitset::Clear() -{ - m_bitCount = 0; - m_blocks.clear(); -} - -template -unsigned int NzBitset::Count() const -{ - if (m_blocks.empty()) - return 0; - - unsigned int count = 0; - for (unsigned int i = 0; i < m_blocks.size(); ++i) - count += NzCountBits(m_blocks[i]); - - return count; -} - -template -void NzBitset::Flip() -{ - for (Block& block : m_blocks) - block ^= fullBitMask; - - ResetExtraBits(); -} - -template -unsigned int NzBitset::FindFirst() const -{ - return FindFirstFrom(0); -} - -template -unsigned int NzBitset::FindNext(unsigned int bit) const -{ - NazaraAssert(bit < m_bitCount, "Bit index out of range"); - - if (++bit >= m_bitCount) - return npos; - - // Le bloc du bit, l'indice du bit - unsigned int blockIndex = GetBlockIndex(bit); - unsigned int bitIndex = GetBitIndex(bit); - - // Récupération du bloc - Block block = m_blocks[blockIndex]; - - // On ignore les X premiers bits - block >>= bitIndex; - - // Si le bloc n'est pas nul, c'est bon, sinon on doit chercher à partir du prochain bloc - if (block) - return NzIntegralLog2Pot(block & -block) + bit; - else - return FindFirstFrom(blockIndex + 1); -} - -template -Block NzBitset::GetBlock(unsigned int i) const -{ - NazaraAssert(i < m_blocks.size(), "Block index out of range"); - - return m_blocks[i]; -} - -template -unsigned int NzBitset::GetBlockCount() const -{ - return m_blocks.size(); -} - -template -unsigned int NzBitset::GetCapacity() const -{ - return m_blocks.capacity()*bitsPerBlock; -} - -template -unsigned int NzBitset::GetSize() const -{ - return m_bitCount; -} - -template -void NzBitset::PerformsAND(const NzBitset& a, const NzBitset& b) -{ - std::pair minmax = std::minmax(a.GetBlockCount(), b.GetBlockCount()); - - // On réinitialise nos blocs à zéro - m_blocks.clear(); - m_blocks.resize(minmax.second, 0U); - m_bitCount = std::max(a.GetSize(), b.GetSize()); - - // Dans le cas du AND, nous pouvons nous arrêter à la plus petite taille (car x & 0 = 0) - for (unsigned int i = 0; i < minmax.first; ++i) - m_blocks[i] = a.GetBlock(i) & b.GetBlock(i); - - ResetExtraBits(); -} - -template -void NzBitset::PerformsNOT(const NzBitset& a) -{ - m_blocks.resize(a.GetBlockCount()); - m_bitCount = a.GetSize(); - - for (unsigned int i = 0; i < m_blocks.size(); ++i) - m_blocks[i] = ~a.GetBlock(i); - - ResetExtraBits(); -} - -template -void NzBitset::PerformsOR(const NzBitset& a, const NzBitset& b) -{ - const NzBitset& greater = (a.GetBlockCount() > b.GetBlockCount()) ? a : b; - const NzBitset& lesser = (a.GetBlockCount() > b.GetBlockCount()) ? b : a; - - unsigned int maxBlockCount = greater.GetBlockCount(); - unsigned int minBlockCount = lesser.GetBlockCount(); - m_blocks.resize(maxBlockCount); - m_bitCount = greater.GetSize(); - - for (unsigned int i = 0; i < minBlockCount; ++i) - m_blocks[i] = a.GetBlock(i) | b.GetBlock(i); - - for (unsigned int i = minBlockCount; i < maxBlockCount; ++i) - m_blocks[i] = greater.GetBlock(i); // (x | 0 = x) - - ResetExtraBits(); -} - -template -void NzBitset::PerformsXOR(const NzBitset& a, const NzBitset& b) -{ - const NzBitset& greater = (a.GetBlockCount() > b.GetBlockCount()) ? a : b; - const NzBitset& lesser = (a.GetBlockCount() > b.GetBlockCount()) ? b : a; - - unsigned int maxBlockCount = greater.GetBlockCount(); - unsigned int minBlockCount = lesser.GetBlockCount(); - m_blocks.resize(maxBlockCount); - m_bitCount = greater.GetSize(); - - for (unsigned int i = 0; i < minBlockCount; ++i) - m_blocks[i] = a.GetBlock(i) ^ b.GetBlock(i); - - for (unsigned int i = minBlockCount; i < maxBlockCount; ++i) - m_blocks[i] = greater.GetBlock(i); // (x ^ 0 = x) - - ResetExtraBits(); -} - -template -bool NzBitset::Intersects(const NzBitset& bitset) const -{ - // On ne testera que les blocs en commun - unsigned int sharedBlocks = std::min(GetBlockCount(), bitset.GetBlockCount()); - for (unsigned int i = 0; i < sharedBlocks; ++i) + template + Bitset::Bitset(const String& bits) : + Bitset(bits.GetConstBuffer(), bits.GetSize()) { - Block a = GetBlock(i); - Block b = bitset.GetBlock(i); - if (a & b) - return true; } - return false; -} + template + void Bitset::Clear() + { + m_bitCount = 0; + m_blocks.clear(); + } -template -void NzBitset::Reserve(unsigned int bitCount) -{ - m_blocks.reserve(ComputeBlockCount(bitCount)); -} + template + unsigned int Bitset::Count() const + { + if (m_blocks.empty()) + return 0; -template -void NzBitset::Resize(unsigned int bitCount, bool defaultVal) -{ - // On commence par changer la taille du conteneur, avec la valeur correcte d'initialisation - unsigned int lastBlockIndex = m_blocks.size() - 1; - m_blocks.resize(ComputeBlockCount(bitCount), (defaultVal) ? fullBitMask : 0U); + unsigned int count = 0; + for (unsigned int i = 0; i < m_blocks.size(); ++i) + count += CountBits(m_blocks[i]); - unsigned int remainingBits = GetBitIndex(m_bitCount); - if (bitCount > m_bitCount && remainingBits > 0 && defaultVal) - // Initialisation des bits non-utilisés du dernier bloc avant le changement de taille - m_blocks[lastBlockIndex] |= fullBitMask << remainingBits; + return count; + } - m_bitCount = bitCount; - ResetExtraBits(); -} + template + void Bitset::Flip() + { + for (Block& block : m_blocks) + block ^= fullBitMask; -template -void NzBitset::Reset() -{ - Set(false); -} - -template -void NzBitset::Reset(unsigned int bit) -{ - Set(bit, false); -} - -template -void NzBitset::Set(bool val) -{ - std::fill(m_blocks.begin(), m_blocks.end(), (val) ? fullBitMask : Block(0U)); - if (val) ResetExtraBits(); -} + } -template -void NzBitset::Set(unsigned int bit, bool val) -{ - NazaraAssert(bit < m_bitCount, "Bit index out of range"); + template + unsigned int Bitset::FindFirst() const + { + return FindFirstFrom(0); + } - Block& block = m_blocks[GetBlockIndex(bit)]; - Block mask = Block(1U) << GetBitIndex(bit); + template + unsigned int Bitset::FindNext(unsigned int bit) const + { + NazaraAssert(bit < m_bitCount, "Bit index out of range"); - // Activation du bit sans branching - // https://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching - block = (block & ~mask) | (-val & mask); -} + if (++bit >= m_bitCount) + return npos; -template -void NzBitset::SetBlock(unsigned int i, Block block) -{ - NazaraAssert(i < m_blocks.size(), "Block index out of range"); + // Le bloc du bit, l'indice du bit + unsigned int blockIndex = GetBlockIndex(bit); + unsigned int bitIndex = GetBitIndex(bit); + + // Récupération du bloc + Block block = m_blocks[blockIndex]; + + // On ignore les X premiers bits + block >>= bitIndex; + + // Si le bloc n'est pas nul, c'est bon, sinon on doit chercher à partir du prochain bloc + if (block) + return IntegralLog2Pot(block & -block) + bit; + else + return FindFirstFrom(blockIndex + 1); + } + + template + Block Bitset::GetBlock(unsigned int i) const + { + NazaraAssert(i < m_blocks.size(), "Block index out of range"); + + return m_blocks[i]; + } + + template + unsigned int Bitset::GetBlockCount() const + { + return m_blocks.size(); + } + + template + unsigned int Bitset::GetCapacity() const + { + return m_blocks.capacity()*bitsPerBlock; + } + + template + unsigned int Bitset::GetSize() const + { + return m_bitCount; + } + + template + void Bitset::PerformsAND(const Bitset& a, const Bitset& b) + { + std::pair minmax = std::minmax(a.GetBlockCount(), b.GetBlockCount()); + + // On réinitialise nos blocs à zéro + m_blocks.clear(); + m_blocks.resize(minmax.second, 0U); + m_bitCount = std::max(a.GetSize(), b.GetSize()); + + // Dans le cas du AND, nous pouvons nous arrêter à la plus petite taille (car x & 0 = 0) + for (unsigned int i = 0; i < minmax.first; ++i) + m_blocks[i] = a.GetBlock(i) & b.GetBlock(i); - m_blocks[i] = block; - if (i == m_blocks.size()-1) ResetExtraBits(); -} - -template -void NzBitset::Swap(NzBitset& bitset) -{ - std::swap(m_bitCount, bitset.m_bitCount); - std::swap(m_blocks, bitset.m_blocks); -} - -template -bool NzBitset::Test(unsigned int bit) const -{ - NazaraAssert(bit < m_bitCount, "Bit index out of range"); - - return (m_blocks[GetBlockIndex(bit)] & (Block(1U) << GetBitIndex(bit))) != 0; -} - -template -bool NzBitset::TestAll() const -{ - // Cas particulier du dernier bloc - Block lastBlockMask = GetLastBlockMask(); - - for (unsigned int i = 0; i < m_blocks.size(); ++i) - { - Block mask = (i == m_blocks.size() - 1) ? lastBlockMask : fullBitMask; - if (m_blocks[i] == mask) // Les extra bits sont à zéro, on peut donc tester sans procéder à un masquage - return false; } - return true; -} + template + void Bitset::PerformsNOT(const Bitset& a) + { + m_blocks.resize(a.GetBlockCount()); + m_bitCount = a.GetSize(); + + for (unsigned int i = 0; i < m_blocks.size(); ++i) + m_blocks[i] = ~a.GetBlock(i); + + ResetExtraBits(); + } + + template + void Bitset::PerformsOR(const Bitset& a, const Bitset& b) + { + const Bitset& greater = (a.GetBlockCount() > b.GetBlockCount()) ? a : b; + const Bitset& lesser = (a.GetBlockCount() > b.GetBlockCount()) ? b : a; + + unsigned int maxBlockCount = greater.GetBlockCount(); + unsigned int minBlockCount = lesser.GetBlockCount(); + m_blocks.resize(maxBlockCount); + m_bitCount = greater.GetSize(); + + for (unsigned int i = 0; i < minBlockCount; ++i) + m_blocks[i] = a.GetBlock(i) | b.GetBlock(i); + + for (unsigned int i = minBlockCount; i < maxBlockCount; ++i) + m_blocks[i] = greater.GetBlock(i); // (x | 0 = x) + + ResetExtraBits(); + } + + template + void Bitset::PerformsXOR(const Bitset& a, const Bitset& b) + { + const Bitset& greater = (a.GetBlockCount() > b.GetBlockCount()) ? a : b; + const Bitset& lesser = (a.GetBlockCount() > b.GetBlockCount()) ? b : a; + + unsigned int maxBlockCount = greater.GetBlockCount(); + unsigned int minBlockCount = lesser.GetBlockCount(); + m_blocks.resize(maxBlockCount); + m_bitCount = greater.GetSize(); + + for (unsigned int i = 0; i < minBlockCount; ++i) + m_blocks[i] = a.GetBlock(i) ^ b.GetBlock(i); + + for (unsigned int i = minBlockCount; i < maxBlockCount; ++i) + m_blocks[i] = greater.GetBlock(i); // (x ^ 0 = x) + + ResetExtraBits(); + } + + template + bool Bitset::Intersects(const Bitset& bitset) const + { + // On ne testera que les blocs en commun + unsigned int sharedBlocks = std::min(GetBlockCount(), bitset.GetBlockCount()); + for (unsigned int i = 0; i < sharedBlocks; ++i) + { + Block a = GetBlock(i); + Block b = bitset.GetBlock(i); + if (a & b) + return true; + } -template -bool NzBitset::TestAny() const -{ - if (m_blocks.empty()) return false; - - for (unsigned int i = 0; i < m_blocks.size(); ++i) - { - if (m_blocks[i]) - return true; } - return false; -} - -template -bool NzBitset::TestNone() const -{ - return !TestAny(); -} - -template -template -T NzBitset::To() const -{ - static_assert(std::is_integral() && std::is_unsigned(), "T must be a unsigned integral type"); - - NazaraAssert(m_bitCount <= std::numeric_limits::digits, "Bit count cannot be greater than T bit count"); - - T value = 0; - for (unsigned int i = 0; i < m_blocks.size(); ++i) - value |= static_cast(m_blocks[i]) << i*bitsPerBlock; - - return value; -} - -template -NzString NzBitset::ToString() const -{ - NzString str(m_bitCount, '0'); - - for (unsigned int i = 0; i < m_bitCount; ++i) + template + void Bitset::Reserve(unsigned int bitCount) { - if (Test(i)) - str[m_bitCount - i - 1] = '1'; // Inversion de l'indice + m_blocks.reserve(ComputeBlockCount(bitCount)); } - return str; -} - -template -void NzBitset::UnboundedReset(unsigned int bit) -{ - UnboundedSet(bit, false); -} - -template -void NzBitset::UnboundedSet(unsigned int bit, bool val) -{ - if (bit < m_bitCount) - Set(bit, val); - else if (val) + template + void Bitset::Resize(unsigned int bitCount, bool defaultVal) { - // On élargit le bitset seulement s'il y a un bit à marquer - Resize(bit + 1, false); - Set(bit, true); - } -} + // On commence par changer la taille du conteneur, avec la valeur correcte d'initialisation + unsigned int lastBlockIndex = m_blocks.size() - 1; + m_blocks.resize(ComputeBlockCount(bitCount), (defaultVal) ? fullBitMask : 0U); + + unsigned int remainingBits = GetBitIndex(m_bitCount); + if (bitCount > m_bitCount && remainingBits > 0 && defaultVal) + // Initialisation des bits non-utilisés du dernier bloc avant le changement de taille + m_blocks[lastBlockIndex] |= fullBitMask << remainingBits; + + m_bitCount = bitCount; + ResetExtraBits(); + } + + template + void Bitset::Reset() + { + Set(false); + } + + template + void Bitset::Reset(unsigned int bit) + { + Set(bit, false); + } + + template + void Bitset::Set(bool val) + { + std::fill(m_blocks.begin(), m_blocks.end(), (val) ? fullBitMask : Block(0U)); + if (val) + ResetExtraBits(); + } + + template + void Bitset::Set(unsigned int bit, bool val) + { + NazaraAssert(bit < m_bitCount, "Bit index out of range"); + + Block& block = m_blocks[GetBlockIndex(bit)]; + Block mask = Block(1U) << GetBitIndex(bit); + + // Activation du bit sans branching + // https://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching + block = (block & ~mask) | (-val & mask); + } + + template + void Bitset::SetBlock(unsigned int i, Block block) + { + NazaraAssert(i < m_blocks.size(), "Block index out of range"); + + m_blocks[i] = block; + if (i == m_blocks.size()-1) + ResetExtraBits(); + } + + template + void Bitset::Swap(Bitset& bitset) + { + std::swap(m_bitCount, bitset.m_bitCount); + std::swap(m_blocks, bitset.m_blocks); + } + + template + bool Bitset::Test(unsigned int bit) const + { + NazaraAssert(bit < m_bitCount, "Bit index out of range"); + + return (m_blocks[GetBlockIndex(bit)] & (Block(1U) << GetBitIndex(bit))) != 0; + } + + template + bool Bitset::TestAll() const + { + // Cas particulier du dernier bloc + Block lastBlockMask = GetLastBlockMask(); + + for (unsigned int i = 0; i < m_blocks.size(); ++i) + { + Block mask = (i == m_blocks.size() - 1) ? lastBlockMask : fullBitMask; + if (m_blocks[i] == mask) // Les extra bits sont à zéro, on peut donc tester sans procéder à un masquage + return false; + } + + return true; + } + + template + bool Bitset::TestAny() const + { + if (m_blocks.empty()) + return false; + + for (unsigned int i = 0; i < m_blocks.size(); ++i) + { + if (m_blocks[i]) + return true; + } -template -bool NzBitset::UnboundedTest(unsigned int bit) const -{ - if (bit < m_bitCount) - return Test(bit); - else return false; -} - -template -typename NzBitset::Bit NzBitset::operator[](int index) -{ - return Bit(m_blocks[GetBlockIndex(index)], Block(1U) << GetBitIndex(index)); -} - -template -bool NzBitset::operator[](int index) const -{ - return Test(index); -} - -template -NzBitset NzBitset::operator~() const -{ - NzBitset bitset; - bitset.PerformsNOT(*this); - - return bitset; -} - -template -NzBitset& NzBitset::operator=(const NzString& bits) -{ - NzBitset bitset(bits); - std::swap(*this, bitset); - - return *this; -} - -template -NzBitset& NzBitset::operator&=(const NzBitset& bitset) -{ - PerformsAND(*this, bitset); - - return *this; -} - -template -NzBitset& NzBitset::operator|=(const NzBitset& bitset) -{ - PerformsOR(*this, bitset); - - return *this; -} - -template -NzBitset& NzBitset::operator^=(const NzBitset& bitset) -{ - PerformsXOR(*this, bitset); - - return *this; -} - -template -unsigned int NzBitset::FindFirstFrom(unsigned int blockIndex) const -{ - if (blockIndex >= m_blocks.size()) - return npos; - - // On cherche le premier bloc non-nul - unsigned int i = blockIndex; - for (; i < m_blocks.size(); ++i) - { - if (m_blocks[i]) - break; } - // Est-ce qu'on a un bloc non-nul ? - if (i == m_blocks.size()) - return npos; - - Block block = m_blocks[i]; - - // Calcul de la position du LSB dans le bloc (et ajustement de la position) - return NzIntegralLog2Pot(block & -block) + i*bitsPerBlock; -} - -template -Block NzBitset::GetLastBlockMask() const -{ - return (Block(1U) << GetBitIndex(m_bitCount)) - 1U; -} - -template -void NzBitset::ResetExtraBits() -{ - Block mask = GetLastBlockMask(); - if (mask) - m_blocks.back() &= mask; -} - -template -unsigned int NzBitset::ComputeBlockCount(unsigned int bitCount) -{ - return GetBlockIndex(bitCount) + ((GetBitIndex(bitCount) != 0U) ? 1U : 0U); -} - -template -unsigned int NzBitset::GetBitIndex(unsigned int bit) -{ - return bit & (bitsPerBlock - 1U); // bit % bitsPerBlock -} - -template -unsigned int NzBitset::GetBlockIndex(unsigned int bit) -{ - return bit / bitsPerBlock; -} - -template -Block NzBitset::fullBitMask = std::numeric_limits::max(); - -template -unsigned int NzBitset::bitsPerBlock = std::numeric_limits::digits; - -template -unsigned int NzBitset::npos = std::numeric_limits::max(); - - -template -bool operator==(const NzBitset& lhs, const NzBitset& rhs) -{ - // La comparaison part du principe que (uint8) 00001100 == (uint16) 00000000 00001100 - // et conserve donc cette propriété - const NzBitset& greater = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? lhs : rhs; - const NzBitset& lesser = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? rhs : lhs; - - unsigned int maxBlockCount = greater.GetBlockCount(); - unsigned int minBlockCount = lesser.GetBlockCount(); - - // Nous testons les blocs en commun pour vérifier l'égalité des bits - for (unsigned int i = 0; i < minBlockCount; ++i) + template + bool Bitset::TestNone() const { - if (lhs.GetBlock(i) != rhs.GetBlock(i)) + return !TestAny(); + } + + template + template + T Bitset::To() const + { + static_assert(std::is_integral() && std::is_unsigned(), "T must be a unsigned integral type"); + + NazaraAssert(m_bitCount <= std::numeric_limits::digits, "Bit count cannot be greater than T bit count"); + + T value = 0; + for (unsigned int i = 0; i < m_blocks.size(); ++i) + value |= static_cast(m_blocks[i]) << i*bitsPerBlock; + + return value; + } + + template + String Bitset::ToString() const + { + String str(m_bitCount, '0'); + + for (unsigned int i = 0; i < m_bitCount; ++i) + { + if (Test(i)) + str[m_bitCount - i - 1] = '1'; // Inversion de l'indice + } + + return str; + } + + template + void Bitset::UnboundedReset(unsigned int bit) + { + UnboundedSet(bit, false); + } + + template + void Bitset::UnboundedSet(unsigned int bit, bool val) + { + if (bit < m_bitCount) + Set(bit, val); + else if (val) + { + // On élargit le bitset seulement s'il y a un bit à marquer + Resize(bit + 1, false); + Set(bit, true); + } + } + + template + bool Bitset::UnboundedTest(unsigned int bit) const + { + if (bit < m_bitCount) + return Test(bit); + else return false; } - // Nous vérifions maintenant les blocs que seul le plus grand bitset possède, pour prétendre à l'égalité - // ils doivent tous être nuls - for (unsigned int i = minBlockCount; i < maxBlockCount; ++i) - if (greater.GetBlock(i)) - return false; - - return true; -} - -template -bool operator!=(const NzBitset& lhs, const NzBitset& rhs) -{ - return !(lhs == rhs); -} - -template -bool operator<(const NzBitset& lhs, const NzBitset& rhs) -{ - const NzBitset& greater = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? lhs : rhs; - const NzBitset& lesser = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? rhs : lhs; - - unsigned int maxBlockCount = greater.GetBlockCount(); - unsigned int minBlockCount = lesser.GetBlockCount(); - - // If the greatest bitset has a single bit active in a block outside the lesser bitset range, then it is greater - for (unsigned int i = maxBlockCount; i > minBlockCount; ++i) + template + typename Bitset::Bit Bitset::operator[](int index) { - if (greater.GetBlock(i)) - return lhs.GetBlockCount() < rhs.GetBlockCount(); + return Bit(m_blocks[GetBlockIndex(index)], Block(1U) << GetBitIndex(index)); } - // Compare the common blocks - for (unsigned int i = 0; i < minBlockCount; ++i) + template + bool Bitset::operator[](int index) const { - unsigned int index = (minBlockCount - i - 1); // Compare from the most significant block to the less significant block - if (lhs.GetBlock(index) < rhs.GetBlock(index)) - return true; + return Test(index); } - return false; // They are equal + template + Bitset Bitset::operator~() const + { + Bitset bitset; + bitset.PerformsNOT(*this); + + return bitset; + } + + template + Bitset& Bitset::operator=(const String& bits) + { + Bitset bitset(bits); + std::swap(*this, bitset); + + return *this; + } + + template + Bitset& Bitset::operator&=(const Bitset& bitset) + { + PerformsAND(*this, bitset); + + return *this; + } + + template + Bitset& Bitset::operator|=(const Bitset& bitset) + { + PerformsOR(*this, bitset); + + return *this; + } + + template + Bitset& Bitset::operator^=(const Bitset& bitset) + { + PerformsXOR(*this, bitset); + + return *this; + } + + template + unsigned int Bitset::FindFirstFrom(unsigned int blockIndex) const + { + if (blockIndex >= m_blocks.size()) + return npos; + + // On cherche le premier bloc non-nul + unsigned int i = blockIndex; + for (; i < m_blocks.size(); ++i) + { + if (m_blocks[i]) + break; + } + + // Est-ce qu'on a un bloc non-nul ? + if (i == m_blocks.size()) + return npos; + + Block block = m_blocks[i]; + + // Calcul de la position du LSB dans le bloc (et ajustement de la position) + return IntegralLog2Pot(block & -block) + i*bitsPerBlock; + } + + template + Block Bitset::GetLastBlockMask() const + { + return (Block(1U) << GetBitIndex(m_bitCount)) - 1U; + } + + template + void Bitset::ResetExtraBits() + { + Block mask = GetLastBlockMask(); + if (mask) + m_blocks.back() &= mask; + } + + template + unsigned int Bitset::ComputeBlockCount(unsigned int bitCount) + { + return GetBlockIndex(bitCount) + ((GetBitIndex(bitCount) != 0U) ? 1U : 0U); + } + + template + unsigned int Bitset::GetBitIndex(unsigned int bit) + { + return bit & (bitsPerBlock - 1U); // bit % bitsPerBlock + } + + template + unsigned int Bitset::GetBlockIndex(unsigned int bit) + { + return bit / bitsPerBlock; + } + + template + Block Bitset::fullBitMask = std::numeric_limits::max(); + + template + unsigned int Bitset::bitsPerBlock = std::numeric_limits::digits; + + template + unsigned int Bitset::npos = std::numeric_limits::max(); + + + template + typename Bitset::Bit& Bitset::Bit::Flip() + { + m_block ^= m_mask; + + return *this; + } + + template + typename Bitset::Bit& Bitset::Bit::Reset() + { + return Set(false); + } + + template + typename Bitset::Bit& Bitset::Bit::Set(bool val) + { + // https://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching + m_block = (m_block & ~m_mask) | (-val & m_mask); + + return *this; + } + + template + bool Bitset::Bit::Test() const + { + return m_block & m_mask; + } + + template + template + void* Bitset::Bit::operator&() const + { + // Le template est nécessaire pour ne planter la compilation qu'à l'utilisation + static_assert(!BadCall, "It is impossible to take the address of a bit in a bitset"); + + return nullptr; + } + + template + Bitset::Bit::operator bool() const + { + return Test(); + } + + template + typename Bitset::Bit& Bitset::Bit::operator=(bool val) + { + return Set(val); + } + + template + typename Bitset::Bit& Bitset::Bit::operator=(const Bit& bit) + { + return Set(bit); + } + + template + typename Bitset::Bit& Bitset::Bit::operator|=(bool val) + { + // Version sans branching: + Set((val) ? true : Test()); + + // Avec branching: + /* + if (val) + Set(); + */ + + return *this; + } + + template + typename Bitset::Bit& Bitset::Bit::operator&=(bool val) + { + // Version sans branching: + Set((val) ? Test() : false); + + // Avec branching: + /* + if (!val) + Reset(); + */ + + return *this; + } + + template + typename Bitset::Bit& Bitset::Bit::operator^=(bool val) + { + // Version sans branching: + Set((val) ? !Test() : Test()); + + // Avec branching: + /* + if (val) + Flip(); + */ + + return *this; + } + + template + typename Bitset::Bit& Bitset::Bit::operator-=(bool val) + { + // Version sans branching: + Set((val) ? false : Test()); + + // Avec branching: + /* + if (val) + Reset(); + */ + + return *this; + } + + template + bool operator==(const Bitset& lhs, const Bitset& rhs) + { + // La comparaison part du principe que (uint8) 00001100 == (uint16) 00000000 00001100 + // et conserve donc cette propriété + const Bitset& greater = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? lhs : rhs; + const Bitset& lesser = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? rhs : lhs; + + unsigned int maxBlockCount = greater.GetBlockCount(); + unsigned int minBlockCount = lesser.GetBlockCount(); + + // Nous testons les blocs en commun pour vérifier l'égalité des bits + for (unsigned int i = 0; i < minBlockCount; ++i) + { + if (lhs.GetBlock(i) != rhs.GetBlock(i)) + return false; + } + + // Nous vérifions maintenant les blocs que seul le plus grand bitset possède, pour prétendre à l'égalité + // ils doivent tous être nuls + for (unsigned int i = minBlockCount; i < maxBlockCount; ++i) + if (greater.GetBlock(i)) + return false; + + return true; + } + + template + bool operator!=(const Bitset& lhs, const Bitset& rhs) + { + return !(lhs == rhs); + } + + template + bool operator<(const Bitset& lhs, const Bitset& rhs) + { + const Bitset& greater = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? lhs : rhs; + const Bitset& lesser = (lhs.GetBlockCount() > rhs.GetBlockCount()) ? rhs : lhs; + + unsigned int maxBlockCount = greater.GetBlockCount(); + unsigned int minBlockCount = lesser.GetBlockCount(); + + // If the greatest bitset has a single bit active in a block outside the lesser bitset range, then it is greater + for (unsigned int i = maxBlockCount; i > minBlockCount; ++i) + { + if (greater.GetBlock(i)) + return lhs.GetBlockCount() < rhs.GetBlockCount(); + } + + // Compare the common blocks + for (unsigned int i = 0; i < minBlockCount; ++i) + { + unsigned int index = (minBlockCount - i - 1); // Compare from the most significant block to the less significant block + if (lhs.GetBlock(index) < rhs.GetBlock(index)) + return true; + } + + return false; // They are equal + } + + template + bool operator<=(const Bitset& lhs, const Bitset& rhs) + { + return lhs < rhs || lhs == rhs; + } + + template + bool operator>(const Bitset& lhs, const Bitset& rhs) + { + return rhs < lhs; + } + + template + bool operator>=(const Bitset& lhs, const Bitset& rhs) + { + return rhs <= lhs; + } + + template + Bitset operator&(const Bitset& lhs, const Bitset& rhs) + { + Bitset bitset; + bitset.PerformsAND(lhs, rhs); + + return bitset; + } + + template + Bitset operator|(const Bitset& lhs, const Bitset& rhs) + { + Bitset bitset; + bitset.PerformsOR(lhs, rhs); + + return bitset; + } + + template + Bitset operator^(const Bitset& lhs, const Bitset& rhs) + { + Bitset bitset; + bitset.PerformsXOR(lhs, rhs); + + return bitset; + } } -template -bool operator<=(const NzBitset& lhs, const NzBitset& rhs) -{ - return lhs < rhs || lhs == rhs; -} - -template -bool operator>(const NzBitset& lhs, const NzBitset& rhs) -{ - return rhs < lhs; -} - -template -bool operator>=(const NzBitset& lhs, const NzBitset& rhs) -{ - return rhs <= lhs; -} - -template -NzBitset operator&(const NzBitset& lhs, const NzBitset& rhs) -{ - NzBitset bitset; - bitset.PerformsAND(lhs, rhs); - - return bitset; -} - -template -NzBitset operator|(const NzBitset& lhs, const NzBitset& rhs) -{ - NzBitset bitset; - bitset.PerformsOR(lhs, rhs); - - return bitset; -} - -template -NzBitset operator^(const NzBitset& lhs, const NzBitset& rhs) -{ - NzBitset bitset; - bitset.PerformsXOR(lhs, rhs); - - return bitset; -} - - -template -typename NzBitset::Bit& NzBitset::Bit::Flip() -{ - m_block ^= m_mask; - - return *this; -} - -template -typename NzBitset::Bit& NzBitset::Bit::Reset() -{ - return Set(false); -} - -template -typename NzBitset::Bit& NzBitset::Bit::Set(bool val) -{ - // https://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching - m_block = (m_block & ~m_mask) | (-val & m_mask); - - return *this; -} - -template -bool NzBitset::Bit::Test() const -{ - return m_block & m_mask; -} - -template -template -void* NzBitset::Bit::operator&() const -{ - // Le template est nécessaire pour ne planter la compilation qu'à l'utilisation - static_assert(!BadCall, "It is impossible to take the address of a bit in a bitset"); - - return nullptr; -} - -template -NzBitset::Bit::operator bool() const -{ - return Test(); -} - -template -typename NzBitset::Bit& NzBitset::Bit::operator=(bool val) -{ - return Set(val); -} - -template -typename NzBitset::Bit& NzBitset::Bit::operator=(const Bit& bit) -{ - return Set(bit); -} - -template -typename NzBitset::Bit& NzBitset::Bit::operator|=(bool val) -{ - // Version sans branching: - Set((val) ? true : Test()); - - // Avec branching: - /* - if (val) - Set(); - */ - - return *this; -} - -template -typename NzBitset::Bit& NzBitset::Bit::operator&=(bool val) -{ - // Version sans branching: - Set((val) ? Test() : false); - - // Avec branching: - /* - if (!val) - Reset(); - */ - - return *this; -} - -template -typename NzBitset::Bit& NzBitset::Bit::operator^=(bool val) -{ - // Version sans branching: - Set((val) ? !Test() : Test()); - - // Avec branching: - /* - if (val) - Flip(); - */ - - return *this; -} - -template -typename NzBitset::Bit& NzBitset::Bit::operator-=(bool val) -{ - // Version sans branching: - Set((val) ? false : Test()); - - // Avec branching: - /* - if (val) - Reset(); - */ - - return *this; -} namespace std { template - void swap(NzBitset& lhs, NzBitset& rhs) + void swap(Nz::Bitset& lhs, Nz::Bitset& rhs) { lhs.Swap(rhs); } diff --git a/include/Nazara/Core/ByteArray.hpp b/include/Nazara/Core/ByteArray.hpp index 5cddbf17a..926c53fd1 100644 --- a/include/Nazara/Core/ByteArray.hpp +++ b/include/Nazara/Core/ByteArray.hpp @@ -13,125 +13,128 @@ #include #include -class NzAbstractHash; - -class NAZARA_CORE_API NzByteArray : public NzHashable +namespace Nz { - using Container = std::vector; + class AbstractHash; - public: - // types: - using allocator_type = Container::allocator_type; - using const_iterator = Container::const_iterator; - using const_reference = Container::const_reference; - using const_pointer = Container::const_pointer; - using const_reverse_iterator = Container::const_reverse_iterator; - using difference_type = Container::difference_type; - using pointer = Container::pointer; - using iterator = Container::iterator; - using reference = Container::reference; - using reverse_iterator = Container::reverse_iterator; - using size_type = Container::size_type; - using value_type = Container::value_type; + class NAZARA_CORE_API ByteArray : public Hashable + { + using Container = std::vector; - // construct/destroy: - inline NzByteArray() = default; - inline explicit NzByteArray(size_type n); - inline NzByteArray(const void* buffer, size_type n); - inline NzByteArray(size_type n, value_type value); - template NzByteArray(InputIterator first, InputIterator last); - NzByteArray(const NzByteArray& other) = default; - NzByteArray(NzByteArray&& other) = default; - ~NzByteArray() = default; + public: + // types: + using allocator_type = Container::allocator_type; + using const_iterator = Container::const_iterator; + using const_reference = Container::const_reference; + using const_pointer = Container::const_pointer; + using const_reverse_iterator = Container::const_reverse_iterator; + using difference_type = Container::difference_type; + using pointer = Container::pointer; + using iterator = Container::iterator; + using reference = Container::reference; + using reverse_iterator = Container::reverse_iterator; + using size_type = Container::size_type; + using value_type = Container::value_type; - inline iterator Append(const void* buffer, size_type size); - inline iterator Append(const NzByteArray& other); - template void Assign(InputIterator first, InputIterator last); - inline void Assign(size_type n, value_type value); + // construct/destroy: + inline ByteArray() = default; + inline explicit ByteArray(size_type n); + inline ByteArray(const void* buffer, size_type n); + inline ByteArray(size_type n, value_type value); + template ByteArray(InputIterator first, InputIterator last); + ByteArray(const ByteArray& other) = default; + ByteArray(ByteArray&& other) = default; + ~ByteArray() = default; - inline reference Back(); - inline const_reference Back() const; + inline iterator Append(const void* buffer, size_type size); + inline iterator Append(const ByteArray& other); + template void Assign(InputIterator first, InputIterator last); + inline void Assign(size_type n, value_type value); - inline void Clear(bool keepBuffer = false); + inline reference Back(); + inline const_reference Back() const; - inline iterator Erase(const_iterator pos); - inline iterator Erase(const_iterator first, const_iterator last); + inline void Clear(bool keepBuffer = false); - inline reference Front(); - inline const_reference Front() const; + inline iterator Erase(const_iterator pos); + inline iterator Erase(const_iterator first, const_iterator last); - inline allocator_type GetAllocator() const; - inline pointer GetBuffer(); - inline size_type GetCapacity() const noexcept; - inline const_pointer GetConstBuffer() const; - inline size_type GetMaxSize() const noexcept; - inline size_type GetSize() const noexcept; - inline NzByteArray GetSubArray(const_iterator startPos, const_iterator endPos) const; + inline reference Front(); + inline const_reference Front() const; - inline iterator Insert(const_iterator pos, const void* buffer, size_type n); - inline iterator Insert(const_iterator pos, const NzByteArray& other); - inline iterator Insert(const_iterator pos, size_type n, value_type byte); - template iterator Insert(const_iterator pos, InputIterator first, InputIterator last); - inline bool IsEmpty() const noexcept; + inline allocator_type GetAllocator() const; + inline pointer GetBuffer(); + inline size_type GetCapacity() const noexcept; + inline const_pointer GetConstBuffer() const; + inline size_type GetMaxSize() const noexcept; + inline size_type GetSize() const noexcept; + inline ByteArray GetSubArray(const_iterator startPos, const_iterator endPos) const; - inline void PopBack(); - inline void PopFront(); - inline iterator Prepend(const void* buffer, size_type size); - inline iterator Prepend(const NzByteArray& other); - inline void PushBack(value_type byte); - inline void PushFront(value_type byte); + inline iterator Insert(const_iterator pos, const void* buffer, size_type n); + inline iterator Insert(const_iterator pos, const ByteArray& other); + inline iterator Insert(const_iterator pos, size_type n, value_type byte); + template iterator Insert(const_iterator pos, InputIterator first, InputIterator last); + inline bool IsEmpty() const noexcept; - inline void Reserve(size_type bufferSize); - inline void Resize(size_type newSize); - inline void Resize(size_type newSize, value_type byte); + inline void PopBack(); + inline void PopFront(); + inline iterator Prepend(const void* buffer, size_type size); + inline iterator Prepend(const ByteArray& other); + inline void PushBack(value_type byte); + inline void PushFront(value_type byte); - inline void ShrinkToFit(); - inline void Swap(NzByteArray& other); + inline void Reserve(size_type bufferSize); + inline void Resize(size_type newSize); + inline void Resize(size_type newSize, value_type byte); - inline NzString ToString() const; + inline void ShrinkToFit(); + inline void Swap(ByteArray& other); - // STL interface - inline iterator begin() noexcept; - inline const_iterator begin() const noexcept; - inline bool empty() const noexcept; - inline iterator end() noexcept; - inline const_iterator end() const noexcept; - inline reverse_iterator rbegin() noexcept; - inline const_reverse_iterator rbegin() const noexcept; - inline reverse_iterator rend() noexcept; - inline const_reverse_iterator rend() const noexcept; - inline const_iterator cbegin() const noexcept; - inline const_iterator cend() const noexcept; - inline const_reverse_iterator crbegin() const noexcept; - inline const_reverse_iterator crend() const noexcept; - inline size_type size() const noexcept; + inline String ToString() const; - // Operators - inline reference operator[](size_type pos); - inline const_reference operator[](size_type pos) const; - inline NzByteArray& operator=(const NzByteArray& array) = default; - inline NzByteArray& operator=(NzByteArray&& array) = default; - inline NzByteArray operator+(const NzByteArray& array) const; - inline NzByteArray& operator+=(const NzByteArray& array); + // STL interface + inline iterator begin() noexcept; + inline const_iterator begin() const noexcept; + inline bool empty() const noexcept; + inline iterator end() noexcept; + inline const_iterator end() const noexcept; + inline reverse_iterator rbegin() noexcept; + inline const_reverse_iterator rbegin() const noexcept; + inline reverse_iterator rend() noexcept; + inline const_reverse_iterator rend() const noexcept; + inline const_iterator cbegin() const noexcept; + inline const_iterator cend() const noexcept; + inline const_reverse_iterator crbegin() const noexcept; + inline const_reverse_iterator crend() const noexcept; + inline size_type size() const noexcept; - inline bool operator==(const NzByteArray& rhs) const; - inline bool operator!=(const NzByteArray& rhs) const; - inline bool operator<(const NzByteArray& rhs) const; - inline bool operator<=(const NzByteArray& rhs) const; - inline bool operator>(const NzByteArray& rhs) const; - inline bool operator>=(const NzByteArray& rhs) const; + // Operators + inline reference operator[](size_type pos); + inline const_reference operator[](size_type pos) const; + inline ByteArray& operator=(const ByteArray& array) = default; + inline ByteArray& operator=(ByteArray&& array) = default; + inline ByteArray operator+(const ByteArray& array) const; + inline ByteArray& operator+=(const ByteArray& array); - private: - bool FillHash(NzAbstractHash* hash) const; + inline bool operator==(const ByteArray& rhs) const; + inline bool operator!=(const ByteArray& rhs) const; + inline bool operator<(const ByteArray& rhs) const; + inline bool operator<=(const ByteArray& rhs) const; + inline bool operator>(const ByteArray& rhs) const; + inline bool operator>=(const ByteArray& rhs) const; - Container m_array; -}; + private: + bool FillHash(AbstractHash* hash) const; -NAZARA_CORE_API std::ostream& operator<<(std::ostream& out, const NzByteArray& byteArray); + Container m_array; + }; +} + +NAZARA_CORE_API std::ostream& operator<<(std::ostream& out, const Nz::ByteArray& byteArray); namespace std { - void swap(NzByteArray& lhs, NzByteArray& rhs); + void swap(Nz::ByteArray& lhs, Nz::ByteArray& rhs); } #include diff --git a/include/Nazara/Core/ByteArray.inl b/include/Nazara/Core/ByteArray.inl index 6c8d97f35..25d90c7eb 100644 --- a/include/Nazara/Core/ByteArray.inl +++ b/include/Nazara/Core/ByteArray.inl @@ -2,327 +2,330 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp -inline NzByteArray::NzByteArray(size_type n) : -m_array() +namespace Nz { - m_array.reserve(n); -} + inline ByteArray::ByteArray(size_type n) : + m_array() + { + m_array.reserve(n); + } -inline NzByteArray::NzByteArray(const void* buffer, size_type n) : -m_array(static_cast(buffer), static_cast(buffer) + n) -{ -} + inline ByteArray::ByteArray(const void* buffer, size_type n) : + m_array(static_cast(buffer), static_cast(buffer) + n) + { + } -inline NzByteArray::NzByteArray(size_type n, const value_type value) : -m_array(n, value) -{ -} + inline ByteArray::ByteArray(size_type n, const value_type value) : + m_array(n, value) + { + } -template -NzByteArray::NzByteArray(InputIterator first, InputIterator last) : -m_array(first, last) -{ -} + template + ByteArray::ByteArray(InputIterator first, InputIterator last) : + m_array(first, last) + { + } -inline NzByteArray::iterator NzByteArray::Append(const void* buffer, size_type n) -{ - return Insert(end(), static_cast(buffer), static_cast(buffer) + n); -} + inline ByteArray::iterator ByteArray::Append(const void* buffer, size_type n) + { + return Insert(end(), static_cast(buffer), static_cast(buffer) + n); + } -inline NzByteArray::iterator NzByteArray::Append(const NzByteArray& other) -{ - return Insert(end(), other.begin(), other.end()); -} + inline ByteArray::iterator ByteArray::Append(const ByteArray& other) + { + return Insert(end(), other.begin(), other.end()); + } -inline void NzByteArray::Assign(size_type n, value_type value) -{ - m_array.assign(n, value); -} + inline void ByteArray::Assign(size_type n, value_type value) + { + m_array.assign(n, value); + } -template -void NzByteArray::Assign(InputIterator first, InputIterator last) -{ - m_array.assign(first, last); -} + template + void ByteArray::Assign(InputIterator first, InputIterator last) + { + m_array.assign(first, last); + } -inline NzByteArray::reference NzByteArray::Back() -{ - return m_array.back(); -} + inline ByteArray::reference ByteArray::Back() + { + return m_array.back(); + } -inline NzByteArray::const_reference NzByteArray::Back() const -{ - return m_array.back(); -} + inline ByteArray::const_reference ByteArray::Back() const + { + return m_array.back(); + } -inline NzByteArray::iterator NzByteArray::Erase(const_iterator pos) -{ - return m_array.erase(pos); -} + inline ByteArray::iterator ByteArray::Erase(const_iterator pos) + { + return m_array.erase(pos); + } -inline NzByteArray::iterator NzByteArray::Erase(const_iterator first, const_iterator last) -{ - return m_array.erase(first, last); -} + inline ByteArray::iterator ByteArray::Erase(const_iterator first, const_iterator last) + { + return m_array.erase(first, last); + } -inline NzByteArray::reference NzByteArray::Front() -{ - return m_array.front(); -} + inline ByteArray::reference ByteArray::Front() + { + return m_array.front(); + } -inline NzByteArray::const_reference NzByteArray::Front() const -{ - return m_array.front(); -} + inline ByteArray::const_reference ByteArray::Front() const + { + return m_array.front(); + } -inline NzByteArray::allocator_type NzByteArray::GetAllocator() const -{ - return m_array.get_allocator(); -} + inline ByteArray::allocator_type ByteArray::GetAllocator() const + { + return m_array.get_allocator(); + } -inline NzByteArray::pointer NzByteArray::GetBuffer() -{ - return m_array.data(); -} + inline ByteArray::pointer ByteArray::GetBuffer() + { + return m_array.data(); + } -inline NzByteArray::size_type NzByteArray::GetCapacity() const noexcept -{ - return m_array.capacity(); -} + inline ByteArray::size_type ByteArray::GetCapacity() const noexcept + { + return m_array.capacity(); + } -inline NzByteArray::const_pointer NzByteArray::GetConstBuffer() const -{ - return m_array.data(); -} + inline ByteArray::const_pointer ByteArray::GetConstBuffer() const + { + return m_array.data(); + } -inline NzByteArray::size_type NzByteArray::GetMaxSize() const noexcept -{ - return m_array.max_size(); -} + inline ByteArray::size_type ByteArray::GetMaxSize() const noexcept + { + return m_array.max_size(); + } -inline NzByteArray::size_type NzByteArray::GetSize() const noexcept -{ - return m_array.size(); -} + inline ByteArray::size_type ByteArray::GetSize() const noexcept + { + return m_array.size(); + } -inline NzByteArray NzByteArray::GetSubArray(const_iterator startPos, const_iterator endPos) const -{ - return NzByteArray(startPos, endPos); -} + inline ByteArray ByteArray::GetSubArray(const_iterator startPos, const_iterator endPos) const + { + return ByteArray(startPos, endPos); + } -inline NzByteArray::iterator NzByteArray::Insert(const_iterator pos, const void* buffer, size_type n) -{ - return m_array.insert(pos, static_cast(buffer), static_cast(buffer) + n); -} + inline ByteArray::iterator ByteArray::Insert(const_iterator pos, const void* buffer, size_type n) + { + return m_array.insert(pos, static_cast(buffer), static_cast(buffer) + n); + } -inline NzByteArray::iterator NzByteArray::Insert(const_iterator pos, const NzByteArray& other) -{ - return m_array.insert(pos, other.begin(), other.end()); -} + inline ByteArray::iterator ByteArray::Insert(const_iterator pos, const ByteArray& other) + { + return m_array.insert(pos, other.begin(), other.end()); + } -inline NzByteArray::iterator NzByteArray::Insert(const_iterator pos, size_type n, value_type byte) -{ - return m_array.insert(pos, n, byte); -} + inline ByteArray::iterator ByteArray::Insert(const_iterator pos, size_type n, value_type byte) + { + return m_array.insert(pos, n, byte); + } -template -NzByteArray::iterator NzByteArray::Insert(const_iterator pos, InputIterator first, InputIterator last) -{ - return m_array.insert(pos, first, last); -} + template + ByteArray::iterator ByteArray::Insert(const_iterator pos, InputIterator first, InputIterator last) + { + return m_array.insert(pos, first, last); + } -inline bool NzByteArray::IsEmpty() const noexcept -{ - return m_array.empty(); -} + inline bool ByteArray::IsEmpty() const noexcept + { + return m_array.empty(); + } -inline void NzByteArray::PopBack() -{ - Erase(end() - 1); -} + inline void ByteArray::PopBack() + { + Erase(end() - 1); + } -inline void NzByteArray::PopFront() -{ - Erase(begin()); -} + inline void ByteArray::PopFront() + { + Erase(begin()); + } -inline NzByteArray::iterator NzByteArray::Prepend(const void* buffer, size_type n) -{ - return Insert(begin(), buffer, n); -} + inline ByteArray::iterator ByteArray::Prepend(const void* buffer, size_type n) + { + return Insert(begin(), buffer, n); + } -inline NzByteArray::iterator NzByteArray::Prepend(const NzByteArray& other) -{ - return Insert(begin(), other); -} + inline ByteArray::iterator ByteArray::Prepend(const ByteArray& other) + { + return Insert(begin(), other); + } -inline void NzByteArray::PushBack(const value_type byte) -{ - m_array.push_back(byte); -} + inline void ByteArray::PushBack(const value_type byte) + { + m_array.push_back(byte); + } -inline void NzByteArray::PushFront(const value_type byte) -{ - m_array.insert(begin(), 1, byte); -} + inline void ByteArray::PushFront(const value_type byte) + { + m_array.insert(begin(), 1, byte); + } -inline void NzByteArray::Reserve(size_type bufferSize) -{ - m_array.reserve(bufferSize); -} + inline void ByteArray::Reserve(size_type bufferSize) + { + m_array.reserve(bufferSize); + } -inline void NzByteArray::Resize(size_type newSize) -{ - m_array.resize(newSize); -} + inline void ByteArray::Resize(size_type newSize) + { + m_array.resize(newSize); + } -inline void NzByteArray::Resize(size_type newSize, const value_type byte) -{ - m_array.resize(newSize, byte); -} + inline void ByteArray::Resize(size_type newSize, const value_type byte) + { + m_array.resize(newSize, byte); + } -inline void NzByteArray::ShrinkToFit() -{ - m_array.shrink_to_fit(); -} + inline void ByteArray::ShrinkToFit() + { + m_array.shrink_to_fit(); + } -inline void NzByteArray::Swap(NzByteArray& other) -{ - m_array.swap(other.m_array); -} + inline void ByteArray::Swap(ByteArray& other) + { + m_array.swap(other.m_array); + } -inline NzString NzByteArray::ToString() const -{ - return NzString(reinterpret_cast(GetConstBuffer()), GetSize()); -} + inline String ByteArray::ToString() const + { + return String(reinterpret_cast(GetConstBuffer()), GetSize()); + } -inline NzByteArray::iterator NzByteArray::begin() noexcept -{ - return m_array.begin(); -} + inline ByteArray::iterator ByteArray::begin() noexcept + { + return m_array.begin(); + } -inline NzByteArray::const_iterator NzByteArray::begin() const noexcept -{ - return m_array.begin(); -} + inline ByteArray::const_iterator ByteArray::begin() const noexcept + { + return m_array.begin(); + } -inline NzByteArray::const_iterator NzByteArray::cbegin() const noexcept -{ - return m_array.cbegin(); -} + inline ByteArray::const_iterator ByteArray::cbegin() const noexcept + { + return m_array.cbegin(); + } -inline NzByteArray::const_iterator NzByteArray::cend() const noexcept -{ - return m_array.cend(); -} + inline ByteArray::const_iterator ByteArray::cend() const noexcept + { + return m_array.cend(); + } -inline NzByteArray::const_reverse_iterator NzByteArray::crbegin() const noexcept -{ - return m_array.crbegin(); -} + inline ByteArray::const_reverse_iterator ByteArray::crbegin() const noexcept + { + return m_array.crbegin(); + } -inline NzByteArray::const_reverse_iterator NzByteArray::crend() const noexcept -{ - return m_array.crend(); -} + inline ByteArray::const_reverse_iterator ByteArray::crend() const noexcept + { + return m_array.crend(); + } -inline bool NzByteArray::empty() const noexcept -{ - return m_array.empty(); -} + inline bool ByteArray::empty() const noexcept + { + return m_array.empty(); + } -inline NzByteArray::iterator NzByteArray::end() noexcept -{ - return m_array.end(); -} + inline ByteArray::iterator ByteArray::end() noexcept + { + return m_array.end(); + } -inline NzByteArray::const_iterator NzByteArray::end() const noexcept -{ - return m_array.end(); -} + inline ByteArray::const_iterator ByteArray::end() const noexcept + { + return m_array.end(); + } -inline NzByteArray::reverse_iterator NzByteArray::rbegin() noexcept -{ - return m_array.rbegin(); -} + inline ByteArray::reverse_iterator ByteArray::rbegin() noexcept + { + return m_array.rbegin(); + } -inline NzByteArray::const_reverse_iterator NzByteArray::rbegin() const noexcept -{ - return m_array.rbegin(); -} + inline ByteArray::const_reverse_iterator ByteArray::rbegin() const noexcept + { + return m_array.rbegin(); + } -inline NzByteArray::reverse_iterator NzByteArray::rend() noexcept -{ - return m_array.rend(); -} + inline ByteArray::reverse_iterator ByteArray::rend() noexcept + { + return m_array.rend(); + } -inline NzByteArray::size_type NzByteArray::size() const noexcept -{ - return GetSize(); -} + inline ByteArray::size_type ByteArray::size() const noexcept + { + return GetSize(); + } -inline NzByteArray::reference NzByteArray::operator[](size_type pos) -{ - NazaraAssert(pos < GetSize(), "Index out of range"); + inline ByteArray::reference ByteArray::operator[](size_type pos) + { + NazaraAssert(pos < GetSize(), "Index out of range"); - return m_array[pos]; -} + return m_array[pos]; + } -inline NzByteArray::const_reference NzByteArray::operator[](size_type pos) const -{ - NazaraAssert(pos < GetSize(), "Index out of range"); + inline ByteArray::const_reference ByteArray::operator[](size_type pos) const + { + NazaraAssert(pos < GetSize(), "Index out of range"); - return m_array[pos]; -} + return m_array[pos]; + } -inline NzByteArray NzByteArray::operator+(const NzByteArray& other) const -{ - NzByteArray tmp(*this); - tmp += other; + inline ByteArray ByteArray::operator+(const ByteArray& other) const + { + ByteArray tmp(*this); + tmp += other; - return tmp; -} + return tmp; + } -inline NzByteArray& NzByteArray::operator+=(const NzByteArray& other) -{ - Append(other); + inline ByteArray& ByteArray::operator+=(const ByteArray& other) + { + Append(other); - return *this; -} + return *this; + } -inline bool NzByteArray::operator==(const NzByteArray& rhs) const -{ - return m_array == rhs.m_array; -} + inline bool ByteArray::operator==(const ByteArray& rhs) const + { + return m_array == rhs.m_array; + } -inline bool NzByteArray::operator!=(const NzByteArray& rhs) const -{ - return !operator==(rhs); -} + inline bool ByteArray::operator!=(const ByteArray& rhs) const + { + return !operator==(rhs); + } -inline bool NzByteArray::operator<(const NzByteArray& rhs) const -{ - return m_array < rhs.m_array; -} + inline bool ByteArray::operator<(const ByteArray& rhs) const + { + return m_array < rhs.m_array; + } -inline bool NzByteArray::operator<=(const NzByteArray& rhs) const -{ - return m_array <= rhs.m_array; -} + inline bool ByteArray::operator<=(const ByteArray& rhs) const + { + return m_array <= rhs.m_array; + } -inline bool NzByteArray::operator>(const NzByteArray& rhs) const -{ - return m_array > rhs.m_array; -} + inline bool ByteArray::operator>(const ByteArray& rhs) const + { + return m_array > rhs.m_array; + } -inline bool NzByteArray::operator>=(const NzByteArray& rhs) const -{ - return m_array >= rhs.m_array; + inline bool ByteArray::operator>=(const ByteArray& rhs) const + { + return m_array >= rhs.m_array; + } } namespace std { - inline void swap(NzByteArray& lhs, NzByteArray& rhs) + inline void swap(Nz::ByteArray& lhs, Nz::ByteArray& rhs) { lhs.Swap(rhs); } diff --git a/include/Nazara/Core/CallOnExit.hpp b/include/Nazara/Core/CallOnExit.hpp index aef4dce2c..3c11ea205 100644 --- a/include/Nazara/Core/CallOnExit.hpp +++ b/include/Nazara/Core/CallOnExit.hpp @@ -10,25 +10,28 @@ #include #include -class NzCallOnExit +namespace Nz { - using Func = std::function; + class CallOnExit + { + using Func = std::function; - public: - NzCallOnExit(Func func = nullptr); - NzCallOnExit(const NzCallOnExit&) = delete; - NzCallOnExit(NzCallOnExit&&) = delete; - ~NzCallOnExit(); + public: + CallOnExit(Func func = nullptr); + CallOnExit(const CallOnExit&) = delete; + CallOnExit(CallOnExit&&) = delete; + ~CallOnExit(); - void CallAndReset(Func func = nullptr); - void Reset(Func func = nullptr); + void CallAndReset(Func func = nullptr); + void Reset(Func func = nullptr); - NzCallOnExit& operator=(const NzCallOnExit&) = delete; - NzCallOnExit& operator=(NzCallOnExit&&) = default; + CallOnExit& operator=(const CallOnExit&) = delete; + CallOnExit& operator=(CallOnExit&&) = default; - private: - Func m_func; -}; + private: + Func m_func; + }; +} #include diff --git a/include/Nazara/Core/CallOnExit.inl b/include/Nazara/Core/CallOnExit.inl index c24b737a5..f89810a77 100644 --- a/include/Nazara/Core/CallOnExit.inl +++ b/include/Nazara/Core/CallOnExit.inl @@ -5,28 +5,31 @@ #include #include -inline NzCallOnExit::NzCallOnExit(Func func) : -m_func(func) +namespace Nz { -} + inline CallOnExit::CallOnExit(Func func) : + m_func(func) + { + } -inline NzCallOnExit::~NzCallOnExit() -{ - if (m_func) - m_func(); -} + inline CallOnExit::~CallOnExit() + { + if (m_func) + m_func(); + } -inline void NzCallOnExit::CallAndReset(Func func) -{ - if (m_func) - m_func(); + inline void CallOnExit::CallAndReset(Func func) + { + if (m_func) + m_func(); - Reset(func); -} + Reset(func); + } -inline void NzCallOnExit::Reset(Func func) -{ - m_func = func; + inline void CallOnExit::Reset(Func func) + { + m_func = func; + } } #include diff --git a/include/Nazara/Core/Clock.hpp b/include/Nazara/Core/Clock.hpp index 82e30e009..e624c59d8 100644 --- a/include/Nazara/Core/Clock.hpp +++ b/include/Nazara/Core/Clock.hpp @@ -15,38 +15,41 @@ #include #endif -class NAZARA_CORE_API NzClock +namespace Nz { - public: - NzClock(nzUInt64 startingValue = 0, bool paused = false); - NzClock(const NzClock& clock) = default; - NzClock(NzClock&& clock) = default; - ~NzClock() = default; + class NAZARA_CORE_API Clock + { + public: + Clock(UInt64 startingValue = 0, bool paused = false); + Clock(const Clock& clock) = default; + Clock(Clock&& clock) = default; + ~Clock() = default; - float GetSeconds() const; - nzUInt64 GetMicroseconds() const; - nzUInt64 GetMilliseconds() const; + float GetSeconds() const; + UInt64 GetMicroseconds() const; + UInt64 GetMilliseconds() const; - bool IsPaused() const; + bool IsPaused() const; - void Pause(); - void Restart(); - void Unpause(); + void Pause(); + void Restart(); + void Unpause(); - NzClock& operator=(const NzClock& clock) = default; - NzClock& operator=(NzClock&& clock) = default; + Clock& operator=(const Clock& clock) = default; + Clock& operator=(Clock&& clock) = default; - private: - NazaraMutexAttrib(m_mutex, mutable) + private: + NazaraMutexAttrib(m_mutex, mutable) - nzUInt64 m_elapsedTime; - nzUInt64 m_refTime; - bool m_paused; -}; + UInt64 m_elapsedTime; + UInt64 m_refTime; + bool m_paused; + }; -typedef nzUInt64 (*NzClockFunction)(); + typedef UInt64 (*ClockFunction)(); -extern NAZARA_CORE_API NzClockFunction NzGetMicroseconds; -extern NAZARA_CORE_API NzClockFunction NzGetMilliseconds; + extern NAZARA_CORE_API ClockFunction GetElapsedMicroseconds; + extern NAZARA_CORE_API ClockFunction GetElapsedMilliseconds; +} #endif // NAZARA_CLOCK_HPP diff --git a/include/Nazara/Core/Color.hpp b/include/Nazara/Core/Color.hpp index 852ddad37..a7df6b9a2 100644 --- a/include/Nazara/Core/Color.hpp +++ b/include/Nazara/Core/Color.hpp @@ -11,57 +11,60 @@ #include #include -class NzColor +namespace Nz { - public: - inline NzColor(); - inline NzColor(nzUInt8 red, nzUInt8 green, nzUInt8 blue, nzUInt8 alpha = 255); - inline explicit NzColor(nzUInt8 lightness); - inline NzColor(nzUInt8 color[3], nzUInt8 alpha = 255); - inline NzColor(const NzColor& color) = default; - inline ~NzColor() = default; + class Color + { + public: + inline Color(); + inline Color(UInt8 red, UInt8 green, UInt8 blue, UInt8 alpha = 255); + inline explicit Color(UInt8 lightness); + inline Color(UInt8 color[3], UInt8 alpha = 255); + inline Color(const Color& color) = default; + inline ~Color() = default; - inline NzString ToString() const; + inline String ToString() const; - inline NzColor operator+(const NzColor& angles) const; - inline NzColor operator*(const NzColor& angles) const; + inline Color operator+(const Color& angles) const; + inline Color operator*(const Color& angles) const; - inline NzColor operator+=(const NzColor& angles); - inline NzColor operator*=(const NzColor& angles); + inline Color operator+=(const Color& angles); + inline Color operator*=(const Color& angles); - inline bool operator==(const NzColor& angles) const; - inline bool operator!=(const NzColor& angles) const; + inline bool operator==(const Color& angles) const; + inline bool operator!=(const Color& angles) const; - static inline NzColor FromCMY(float cyan, float magenta, float yellow); - static inline NzColor FromCMYK(float cyan, float magenta, float yellow, float black); - static inline NzColor FromHSL(nzUInt8 hue, nzUInt8 saturation, nzUInt8 lightness); - static inline NzColor FromHSV(float hue, float saturation, float value); - static inline NzColor FromXYZ(const NzVector3f& vec); - static inline NzColor FromXYZ(float x, float y, float z); - static inline void ToCMY(const NzColor& color, float* cyan, float* magenta, float* yellow); - static inline void ToCMYK(const NzColor& color, float* cyan, float* magenta, float* yellow, float* black); - static inline void ToHSL(const NzColor& color, nzUInt8* hue, nzUInt8* saturation, nzUInt8* lightness); - static inline void ToHSV(const NzColor& color, float* hue, float* saturation, float* value); - static inline void ToXYZ(const NzColor& color, NzVector3f* vec); - static inline void ToXYZ(const NzColor& color, float* x, float* y, float* z); + static inline Color FromCMY(float cyan, float magenta, float yellow); + static inline Color FromCMYK(float cyan, float magenta, float yellow, float black); + static inline Color FromHSL(UInt8 hue, UInt8 saturation, UInt8 lightness); + static inline Color FromHSV(float hue, float saturation, float value); + static inline Color FromXYZ(const Vector3f& vec); + static inline Color FromXYZ(float x, float y, float z); + static inline void ToCMY(const Color& color, float* cyan, float* magenta, float* yellow); + static inline void ToCMYK(const Color& color, float* cyan, float* magenta, float* yellow, float* black); + static inline void ToHSL(const Color& color, UInt8* hue, UInt8* saturation, UInt8* lightness); + static inline void ToHSV(const Color& color, float* hue, float* saturation, float* value); + static inline void ToXYZ(const Color& color, Vector3f* vec); + static inline void ToXYZ(const Color& color, float* x, float* y, float* z); - nzUInt8 r, g, b, a; + UInt8 r, g, b, a; - static NAZARA_CORE_API const NzColor Black; - static NAZARA_CORE_API const NzColor Blue; - static NAZARA_CORE_API const NzColor Cyan; - static NAZARA_CORE_API const NzColor Green; - static NAZARA_CORE_API const NzColor Magenta; - static NAZARA_CORE_API const NzColor Orange; - static NAZARA_CORE_API const NzColor Red; - static NAZARA_CORE_API const NzColor Yellow; - static NAZARA_CORE_API const NzColor White; + static NAZARA_CORE_API const Color Black; + static NAZARA_CORE_API const Color Blue; + static NAZARA_CORE_API const Color Cyan; + static NAZARA_CORE_API const Color Green; + static NAZARA_CORE_API const Color Magenta; + static NAZARA_CORE_API const Color Orange; + static NAZARA_CORE_API const Color Red; + static NAZARA_CORE_API const Color Yellow; + static NAZARA_CORE_API const Color White; - private: - static float Hue2RGB(float v1, float v2, float vH); -}; + private: + static float Hue2RGB(float v1, float v2, float vH); + }; +} -std::ostream& operator<<(std::ostream& out, const NzColor& color); +std::ostream& operator<<(std::ostream& out, const Nz::Color& color); #include diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl index 9b042d315..8bf6dd414 100644 --- a/include/Nazara/Core/Color.inl +++ b/include/Nazara/Core/Color.inl @@ -9,411 +9,414 @@ #include #include -inline NzColor::NzColor() +namespace Nz { -} - -inline NzColor::NzColor(nzUInt8 red, nzUInt8 green, nzUInt8 blue, nzUInt8 alpha) : -r(red), -g(green), -b(blue), -a(alpha) -{ -} - -inline NzColor::NzColor(nzUInt8 lightness) : -r(lightness), -g(lightness), -b(lightness), -a(255) -{ -} - -inline NzColor::NzColor(nzUInt8 vec[3], nzUInt8 alpha) : -r(vec[0]), -g(vec[1]), -b(vec[2]), -a(alpha) -{ -} - -inline NzString NzColor::ToString() const -{ - NzStringStream ss; - ss << "Color(" << static_cast(r) << ", " << static_cast(g) << ", " << static_cast(b); - - if (a != 255) - ss << ", " << static_cast(a); - - ss << ')'; - - return ss; -} - -inline NzColor NzColor::operator+(const NzColor& color) const -{ - NzColor c; - c.r = std::min(static_cast(r) + static_cast(color.r), 255U); - c.g = std::min(static_cast(g) + static_cast(color.g), 255U); - c.b = std::min(static_cast(b) + static_cast(color.b), 255U); - c.a = std::min(static_cast(a) + static_cast(color.a), 255U); - - return c; -} - -inline NzColor NzColor::operator*(const NzColor& color) const -{ - NzColor c; - c.r = (static_cast(r) * static_cast(color.r)) / 255U; - c.g = (static_cast(g) * static_cast(color.g)) / 255U; - c.b = (static_cast(b) * static_cast(color.b)) / 255U; - c.a = (static_cast(a) * static_cast(color.a)) / 255U; - - return c; -} - -inline NzColor NzColor::operator+=(const NzColor& color) -{ - return operator=(operator+(color)); -} - -inline NzColor NzColor::operator*=(const NzColor& color) -{ - return operator=(operator*(color)); -} - -inline bool NzColor::operator==(const NzColor& color) const -{ - return r == color.r && g == color.g && b == color.b && a == color.a; -} - -inline bool NzColor::operator!=(const NzColor& color) const -{ - return !operator==(color); -} - -// Algorithmes venant de http://www.easyrgb.com/index.php?X=MATH - -inline NzColor NzColor::FromCMY(float cyan, float magenta, float yellow) -{ - return NzColor(static_cast((1.f-cyan)*255.f), static_cast((1.f-magenta)*255.f), static_cast((1.f-yellow)*255.f)); -} - -inline NzColor NzColor::FromCMYK(float cyan, float magenta, float yellow, float black) -{ - return FromCMY(cyan * (1.f - black) + black, - magenta * (1.f - black) + black, - yellow * (1.f - black) + black); -} - -inline NzColor NzColor::FromHSL(nzUInt8 hue, nzUInt8 saturation, nzUInt8 lightness) -{ - if (saturation == 0) + inline Color::Color() { - // RGB results from 0 to 255 - return NzColor(lightness * 255, - lightness * 255, - lightness * 255); } - else + + inline Color::Color(UInt8 red, UInt8 green, UInt8 blue, UInt8 alpha) : + r(red), + g(green), + b(blue), + a(alpha) { - // Norme Windows - float l = lightness/240.f; - float h = hue/240.f; - float s = saturation/240.f; - - float v2; - if (l < 0.5f) - v2 = l * (1.f + s); - else - v2 = (l + s) - (s*l); - - float v1 = 2.f * l - v2; - - return NzColor(static_cast(255.f * Hue2RGB(v1, v2, h + (1.f/3.f))), - static_cast(255.f * Hue2RGB(v1, v2, h)), - static_cast(255.f * Hue2RGB(v1, v2, h - (1.f/3.f)))); } -} -inline NzColor NzColor::FromHSV(float hue, float saturation, float value) -{ - if (NzNumberEquals(saturation, 0.f)) - return NzColor(static_cast(value * 255.f)); - else + inline Color::Color(UInt8 lightness) : + r(lightness), + g(lightness), + b(lightness), + a(255) { - float h = hue/360.f * 6.f; - float s = saturation/360.f; + } - if (NzNumberEquals(h, 6.f)) - h = 0; // hue must be < 1 + inline Color::Color(UInt8 vec[3], UInt8 alpha) : + r(vec[0]), + g(vec[1]), + b(vec[2]), + a(alpha) + { + } - int i = static_cast(h); - float v1 = value * (1.f - s); - float v2 = value * (1.f - s * (h - i)); - float v3 = value * (1.f - s * (1.f - (h - i))); + inline String Color::ToString() const + { + StringStream ss; + ss << "Color(" << static_cast(r) << ", " << static_cast(g) << ", " << static_cast(b); - float r, g, b; - switch (i) + if (a != 255) + ss << ", " << static_cast(a); + + ss << ')'; + + return ss; + } + + inline Color Color::operator+(const Color& color) const + { + Color c; + c.r = std::min(static_cast(r) + static_cast(color.r), 255U); + c.g = std::min(static_cast(g) + static_cast(color.g), 255U); + c.b = std::min(static_cast(b) + static_cast(color.b), 255U); + c.a = std::min(static_cast(a) + static_cast(color.a), 255U); + + return c; + } + + inline Color Color::operator*(const Color& color) const + { + Color c; + c.r = (static_cast(r) * static_cast(color.r)) / 255U; + c.g = (static_cast(g) * static_cast(color.g)) / 255U; + c.b = (static_cast(b) * static_cast(color.b)) / 255U; + c.a = (static_cast(a) * static_cast(color.a)) / 255U; + + return c; + } + + inline Color Color::operator+=(const Color& color) + { + return operator=(operator+(color)); + } + + inline Color Color::operator*=(const Color& color) + { + return operator=(operator*(color)); + } + + inline bool Color::operator==(const Color& color) const + { + return r == color.r && g == color.g && b == color.b && a == color.a; + } + + inline bool Color::operator!=(const Color& color) const + { + return !operator==(color); + } + + // Algorithmes venant de http://www.easyrgb.com/index.php?X=MATH + + inline Color Color::FromCMY(float cyan, float magenta, float yellow) + { + return Color(static_cast((1.f-cyan)*255.f), static_cast((1.f-magenta)*255.f), static_cast((1.f-yellow)*255.f)); + } + + inline Color Color::FromCMYK(float cyan, float magenta, float yellow, float black) + { + return FromCMY(cyan * (1.f - black) + black, + magenta * (1.f - black) + black, + yellow * (1.f - black) + black); + } + + inline Color Color::FromHSL(UInt8 hue, UInt8 saturation, UInt8 lightness) + { + if (saturation == 0) { - case 0: - r = value; - g = v3; - b = v1; - break; + // RGB results from 0 to 255 + return Color(lightness * 255, + lightness * 255, + lightness * 255); + } + else + { + // Norme Windows + float l = lightness/240.f; + float h = hue/240.f; + float s = saturation/240.f; - case 1: - r = v2; - g = value; - b = v1; - break; + float v2; + if (l < 0.5f) + v2 = l * (1.f + s); + else + v2 = (l + s) - (s*l); - case 2: - r = v1; - g = value; - b = v3; - break; + float v1 = 2.f * l - v2; - case 3: - r = v1; - g = v2; - b = value; - break; + return Color(static_cast(255.f * Hue2RGB(v1, v2, h + (1.f/3.f))), + static_cast(255.f * Hue2RGB(v1, v2, h)), + static_cast(255.f * Hue2RGB(v1, v2, h - (1.f/3.f)))); + } + } - case 4: - r = v3; - g = v1; - b = value; - break; + inline Color Color::FromHSV(float hue, float saturation, float value) + { + if (NumberEquals(saturation, 0.f)) + return Color(static_cast(value * 255.f)); + else + { + float h = hue/360.f * 6.f; + float s = saturation/360.f; - default: - r = value; - g = v1; - b = v2; - break; + if (NumberEquals(h, 6.f)) + h = 0; // hue must be < 1 + + int i = static_cast(h); + float v1 = value * (1.f - s); + float v2 = value * (1.f - s * (h - i)); + float v3 = value * (1.f - s * (1.f - (h - i))); + + float r, g, b; + switch (i) + { + case 0: + r = value; + g = v3; + b = v1; + break; + + case 1: + r = v2; + g = value; + b = v1; + break; + + case 2: + r = v1; + g = value; + b = v3; + break; + + case 3: + r = v1; + g = v2; + b = value; + break; + + case 4: + r = v3; + g = v1; + b = value; + break; + + default: + r = value; + g = v1; + b = v2; + break; + } + + // RGB results from 0 to 255 + return Color(static_cast(r*255.f), static_cast(g*255.f), static_cast(b*255.f)); + } + } + inline Color Color::FromXYZ(const Vector3f& vec) + { + return FromXYZ(vec.x, vec.y, vec.z); + } + + inline Color Color::FromXYZ(float x, float y, float z) + { + x /= 100.f; // X from 0 to 95.047 + y /= 100.f; // Y from 0 to 100.000 + z /= 100.f; // Z from 0 to 108.883 + + float r = x * 3.2406f + y * -1.5372f + z * -0.4986f; + float g = x * -0.9689f + y * 1.8758f + z * 0.0415f; + float b = x * 0.0557f + y * -0.2040f + z * 1.0570f; + + if (r > 0.0031308f) + r = 1.055f * (std::pow(r, 1.f/2.4f)) - 0.055f; + else + r *= 12.92f; + + if (g > 0.0031308f) + g = 1.055f * (std::pow(r, 1.f/2.4f)) - 0.055f; + else + g *= 12.92f; + + if (b > 0.0031308f) + b = 1.055f * (std::pow(r, 1.f/2.4f)) - 0.055f; + else + b *= 12.92f; + + return Color(static_cast(r * 255.f), static_cast(g * 255.f), static_cast(b * 255.f)); + } + + inline void Color::ToCMY(const Color& color, float* cyan, float* magenta, float* yellow) + { + *cyan = 1.f - color.r/255.f; + *magenta = 1.f - color.g/255.f; + *yellow = 1.f - color.b/255.f; + } + + inline void Color::ToCMYK(const Color& color, float* cyan, float* magenta, float* yellow, float* black) + { + float c, m, y; + ToCMY(color, &c, &m, &y); + + float k = std::min({1.f, c, m, y}); + + if (NumberEquals(k, 1.f)) + { + //Black + *cyan = 0.f; + *magenta = 0.f; + *yellow = 0.f; + } + else + { + *cyan = (c-k)/(1.f-k); + *magenta = (m-k)/(1.f-k); + *yellow = (y-k)/(1.f-k); } - // RGB results from 0 to 255 - return NzColor(static_cast(r*255.f), static_cast(g*255.f), static_cast(b*255.f)); - } -} -inline NzColor NzColor::FromXYZ(const NzVector3f& vec) -{ - return FromXYZ(vec.x, vec.y, vec.z); -} - -inline NzColor NzColor::FromXYZ(float x, float y, float z) -{ - x /= 100.f; // X from 0 to 95.047 - y /= 100.f; // Y from 0 to 100.000 - z /= 100.f; // Z from 0 to 108.883 - - float r = x * 3.2406f + y * -1.5372f + z * -0.4986f; - float g = x * -0.9689f + y * 1.8758f + z * 0.0415f; - float b = x * 0.0557f + y * -0.2040f + z * 1.0570f; - - if (r > 0.0031308f) - r = 1.055f * (std::pow(r, 1.f/2.4f)) - 0.055f; - else - r *= 12.92f; - - if (g > 0.0031308f) - g = 1.055f * (std::pow(r, 1.f/2.4f)) - 0.055f; - else - g *= 12.92f; - - if (b > 0.0031308f) - b = 1.055f * (std::pow(r, 1.f/2.4f)) - 0.055f; - else - b *= 12.92f; - - return NzColor(static_cast(r * 255.f), static_cast(g * 255.f), static_cast(b * 255.f)); -} - -inline void NzColor::ToCMY(const NzColor& color, float* cyan, float* magenta, float* yellow) -{ - *cyan = 1.f - color.r/255.f; - *magenta = 1.f - color.g/255.f; - *yellow = 1.f - color.b/255.f; -} - -inline void NzColor::ToCMYK(const NzColor& color, float* cyan, float* magenta, float* yellow, float* black) -{ - float c, m, y; - ToCMY(color, &c, &m, &y); - - float k = std::min({1.f, c, m, y}); - - if (NzNumberEquals(k, 1.f)) - { - //Black - *cyan = 0.f; - *magenta = 0.f; - *yellow = 0.f; - } - else - { - *cyan = (c-k)/(1.f-k); - *magenta = (m-k)/(1.f-k); - *yellow = (y-k)/(1.f-k); + *black = k; } - *black = k; -} - -inline void NzColor::ToHSL(const NzColor& color, nzUInt8* hue, nzUInt8* saturation, nzUInt8* lightness) -{ - float r = color.r / 255.f; - float g = color.g / 255.f; - float b = color.b / 255.f; - - float min = std::min({r, g, b}); // Min. value of RGB - float max = std::max({r, g, b}); // Max. value of RGB - - float deltaMax = max - min; //Delta RGB value - - float l = (max + min)/2.f; - - if (NzNumberEquals(deltaMax, 0.f)) + inline void Color::ToHSL(const Color& color, UInt8* hue, UInt8* saturation, UInt8* lightness) { - //This is a gray, no chroma... - *hue = 0; //HSL results from 0 to 1 - *saturation = 0; - } - else - { - //Chromatic data... - if (l < 0.5f) - *saturation = static_cast(deltaMax/(max+min)*240.f); + float r = color.r / 255.f; + float g = color.g / 255.f; + float b = color.b / 255.f; + + float min = std::min({r, g, b}); // Min. value of RGB + float max = std::max({r, g, b}); // Max. value of RGB + + float deltaMax = max - min; //Delta RGB value + + float l = (max + min)/2.f; + + if (NumberEquals(deltaMax, 0.f)) + { + //This is a gray, no chroma... + *hue = 0; //HSL results from 0 to 1 + *saturation = 0; + } else - *saturation = static_cast(deltaMax/(2.f-max-min)*240.f); + { + //Chromatic data... + if (l < 0.5f) + *saturation = static_cast(deltaMax/(max+min)*240.f); + else + *saturation = static_cast(deltaMax/(2.f-max-min)*240.f); - *lightness = static_cast(l*240.f); + *lightness = static_cast(l*240.f); - float deltaR = ((max - r)/6.f + deltaMax/2.f)/deltaMax; - float deltaG = ((max - g)/6.f + deltaMax/2.f)/deltaMax; - float deltaB = ((max - b)/6.f + deltaMax/2.f)/deltaMax; + float deltaR = ((max - r)/6.f + deltaMax/2.f)/deltaMax; + float deltaG = ((max - g)/6.f + deltaMax/2.f)/deltaMax; + float deltaB = ((max - b)/6.f + deltaMax/2.f)/deltaMax; - float h; - if (NzNumberEquals(r, max)) - h = deltaB - deltaG; - else if (NzNumberEquals(g, max)) - h = (1.f/3.f) + deltaR - deltaB; - else - h = (2.f/3.f) + deltaG - deltaR; + float h; + if (NumberEquals(r, max)) + h = deltaB - deltaG; + else if (NumberEquals(g, max)) + h = (1.f/3.f) + deltaR - deltaB; + else + h = (2.f/3.f) + deltaG - deltaR; - if (h < 0.f) - h += 1.f; - else if (h > 1.f) - h -= 1.f; + if (h < 0.f) + h += 1.f; + else if (h > 1.f) + h -= 1.f; - *hue = static_cast(h*240.f); + *hue = static_cast(h*240.f); + } } -} -inline void NzColor::ToHSV(const NzColor& color, float* hue, float* saturation, float* value) -{ - float r = color.r / 255.f; - float g = color.g / 255.f; - float b = color.b / 255.f; - - float min = std::min({r, g, b}); //Min. value of RGB - float max = std::max({r, g, b}); //Max. value of RGB - - float deltaMax = max - min; //Delta RGB value - - *value = max; - - if (NzNumberEquals(deltaMax, 0.f)) + inline void Color::ToHSV(const Color& color, float* hue, float* saturation, float* value) { - //This is a gray, no chroma... - *hue = 0; //HSV results from 0 to 1 - *saturation = 0; - } - else - { - //Chromatic data... - *saturation = deltaMax/max*360.f; + float r = color.r / 255.f; + float g = color.g / 255.f; + float b = color.b / 255.f; - float deltaR = ((max - r)/6.f + deltaMax/2.f)/deltaMax; - float deltaG = ((max - g)/6.f + deltaMax/2.f)/deltaMax; - float deltaB = ((max - b)/6.f + deltaMax/2.f)/deltaMax; + float min = std::min({r, g, b}); //Min. value of RGB + float max = std::max({r, g, b}); //Max. value of RGB - float h; + float deltaMax = max - min; //Delta RGB value - if (NzNumberEquals(r, max)) - h = deltaB - deltaG; - else if (NzNumberEquals(g, max)) - h = (1.f/3.f) + deltaR - deltaB; + *value = max; + + if (NumberEquals(deltaMax, 0.f)) + { + //This is a gray, no chroma... + *hue = 0; //HSV results from 0 to 1 + *saturation = 0; + } else - h = (2.f/3.f) + deltaG - deltaR; + { + //Chromatic data... + *saturation = deltaMax/max*360.f; - if (h < 0.f) - h += 1.f; - else if (h > 1.f) - h -= 1.f; + float deltaR = ((max - r)/6.f + deltaMax/2.f)/deltaMax; + float deltaG = ((max - g)/6.f + deltaMax/2.f)/deltaMax; + float deltaB = ((max - b)/6.f + deltaMax/2.f)/deltaMax; - *hue = h*360.f; + float h; + + if (NumberEquals(r, max)) + h = deltaB - deltaG; + else if (NumberEquals(g, max)) + h = (1.f/3.f) + deltaR - deltaB; + else + h = (2.f/3.f) + deltaG - deltaR; + + if (h < 0.f) + h += 1.f; + else if (h > 1.f) + h -= 1.f; + + *hue = h*360.f; + } } + + inline void Color::ToXYZ(const Color& color, Vector3f* vec) + { + return ToXYZ(color, &vec->x, &vec->y, &vec->z); + } + + inline void Color::ToXYZ(const Color& color, float* x, float* y, float* z) + { + float r = color.r/255.f; //R from 0 to 255 + float g = color.g/255.f; //G from 0 to 255 + float b = color.b/255.f; //B from 0 to 255 + + if (r > 0.04045f) + r = std::pow((r + 0.055f)/1.055f, 2.4f); + else + r /= 12.92f; + + if (g > 0.04045f) + g = std::pow((g + 0.055f)/1.055f, 2.4f); + else + g /= 12.92f; + + if (b > 0.04045f) + b = std::pow((b + 0.055f)/1.055f, 2.4f); + else + b /= 12.92f; + + r *= 100.f; + g *= 100.f; + b *= 100.f; + + //Observer. = 2°, Illuminant = D65 + *x = r*0.4124f + g*0.3576f + b*0.1805f; + *y = r*0.2126f + g*0.7152f + b*0.0722f; + *z = r*0.0193f + g*0.1192f + b*0.9505f; + } + + inline float Color::Hue2RGB(float v1, float v2, float vH) + { + if (vH < 0.f) + vH += 1; + + if (vH > 1.f) + vH -= 1; + + if ((6.f * vH) < 1.f) + return v1 + (v2-v1)*6*vH; + + if ((2.f * vH) < 1.f) + return v2; + + if ((3.f * vH) < 2.f) + return v1 + (v2 - v1)*(2.f/3.f - vH)*6; + + return v1; +} } -inline void NzColor::ToXYZ(const NzColor& color, NzVector3f* vec) -{ - return ToXYZ(color, &vec->x, &vec->y, &vec->z); -} - -inline void NzColor::ToXYZ(const NzColor& color, float* x, float* y, float* z) -{ - float r = color.r/255.f; //R from 0 to 255 - float g = color.g/255.f; //G from 0 to 255 - float b = color.b/255.f; //B from 0 to 255 - - if (r > 0.04045f) - r = std::pow((r + 0.055f)/1.055f, 2.4f); - else - r /= 12.92f; - - if (g > 0.04045f) - g = std::pow((g + 0.055f)/1.055f, 2.4f); - else - g /= 12.92f; - - if (b > 0.04045f) - b = std::pow((b + 0.055f)/1.055f, 2.4f); - else - b /= 12.92f; - - r *= 100.f; - g *= 100.f; - b *= 100.f; - - //Observer. = 2°, Illuminant = D65 - *x = r*0.4124f + g*0.3576f + b*0.1805f; - *y = r*0.2126f + g*0.7152f + b*0.0722f; - *z = r*0.0193f + g*0.1192f + b*0.9505f; -} - -inline float NzColor::Hue2RGB(float v1, float v2, float vH) -{ - if (vH < 0.f) - vH += 1; - - if (vH > 1.f) - vH -= 1; - - if ((6.f * vH) < 1.f) - return v1 + (v2-v1)*6*vH; - - if ((2.f * vH) < 1.f) - return v2; - - if ((3.f * vH) < 2.f) - return v1 + (v2 - v1)*(2.f/3.f - vH)*6; - - return v1; -} - -inline std::ostream& operator<<(std::ostream& out, const NzColor& color) +inline std::ostream& operator<<(std::ostream& out, const Nz::Color& color) { return out << color.ToString(); } diff --git a/include/Nazara/Core/ConditionVariable.hpp b/include/Nazara/Core/ConditionVariable.hpp index 001aa3d5c..4096e00b4 100644 --- a/include/Nazara/Core/ConditionVariable.hpp +++ b/include/Nazara/Core/ConditionVariable.hpp @@ -9,28 +9,31 @@ #include -class NzConditionVariableImpl; -class NzMutex; - -class NAZARA_CORE_API NzConditionVariable +namespace Nz { - public: - NzConditionVariable(); - NzConditionVariable(const NzConditionVariable&) = delete; - NzConditionVariable(NzConditionVariable&&) = delete; ///TODO - ~NzConditionVariable(); + class ConditionVariableImpl; + class Mutex; - void Signal(); - void SignalAll(); + class NAZARA_CORE_API ConditionVariable + { + public: + ConditionVariable(); + ConditionVariable(const ConditionVariable&) = delete; + ConditionVariable(ConditionVariable&&) = delete; ///TODO + ~ConditionVariable(); - void Wait(NzMutex* mutex); - bool Wait(NzMutex* mutex, nzUInt32 timeout); + void Signal(); + void SignalAll(); - NzConditionVariable& operator=(const NzConditionVariable&) = delete; - NzConditionVariable& operator=(NzConditionVariable&&) = delete; ///TODO + void Wait(Mutex* mutex); + bool Wait(Mutex* mutex, UInt32 timeout); - private: - NzConditionVariableImpl* m_impl; -}; + ConditionVariable& operator=(const ConditionVariable&) = delete; + ConditionVariable& operator=(ConditionVariable&&) = delete; ///TODO + + private: + ConditionVariableImpl* m_impl; + }; +} #endif // NAZARA_CONDITIONVARIABLE_HPP diff --git a/include/Nazara/Core/Config.hpp b/include/Nazara/Core/Config.hpp index 71fe1b974..eee521307 100644 --- a/include/Nazara/Core/Config.hpp +++ b/include/Nazara/Core/Config.hpp @@ -44,7 +44,7 @@ // Taille du buffer lors d'une lecture complète d'un fichier (ex: Hash) #define NAZARA_CORE_FILE_BUFFERSIZE 4096 -// Incorpore la table Unicode Character Data (Nécessaires pour faire fonctionner le flag NzString::HandleUTF8) +// Incorpore la table Unicode Character Data (Nécessaires pour faire fonctionner le flag String::HandleUTF8) #define NAZARA_CORE_INCLUDE_UNICODEDATA 0 // Utilise le MemoryManager pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes) @@ -57,12 +57,12 @@ #define NAZARA_CORE_THREADSAFE 1 // Les classes à protéger des accès concurrentiels -#define NAZARA_THREADSAFETY_CLOCK 0 // NzClock -#define NAZARA_THREADSAFETY_DIRECTORY 1 // NzDirectory -#define NAZARA_THREADSAFETY_DYNLIB 1 // NzDynLib -#define NAZARA_THREADSAFETY_FILE 1 // NzFile -#define NAZARA_THREADSAFETY_LOG 1 // NzLog -#define NAZARA_THREADSAFETY_REFCOUNTED 1 // NzRefCounted +#define NAZARA_THREADSAFETY_CLOCK 0 // Clock +#define NAZARA_THREADSAFETY_DIRECTORY 1 // Directory +#define NAZARA_THREADSAFETY_DYNLIB 1 // DynLib +#define NAZARA_THREADSAFETY_FILE 1 // File +#define NAZARA_THREADSAFETY_LOG 1 // Log +#define NAZARA_THREADSAFETY_REFCOUNTED 1 // RefCounted // Le nombre de spinlocks à utiliser avec les sections critiques de Windows (0 pour désactiver) #define NAZARA_CORE_WINDOWS_CS_SPINLOCKS 4096 diff --git a/include/Nazara/Core/Core.hpp b/include/Nazara/Core/Core.hpp index 7c315fb3f..00840dc1a 100644 --- a/include/Nazara/Core/Core.hpp +++ b/include/Nazara/Core/Core.hpp @@ -10,20 +10,23 @@ #include #include -class NAZARA_CORE_API NzCore +namespace Nz { - public: - NzCore() = delete; - ~NzCore() = delete; + class NAZARA_CORE_API Core + { + public: + Core() = delete; + ~Core() = delete; - static bool Initialize(); + static bool Initialize(); - static bool IsInitialized(); + static bool IsInitialized(); - static void Uninitialize(); + static void Uninitialize(); - private: - static unsigned int s_moduleReferenceCounter; -}; + private: + static unsigned int s_moduleReferenceCounter; + }; +} #endif // NAZARA_CORE_HPP diff --git a/include/Nazara/Core/Debug/NewRedefinition.hpp b/include/Nazara/Core/Debug/NewRedefinition.hpp index 4faf79aa1..5b9b2088f 100644 --- a/include/Nazara/Core/Debug/NewRedefinition.hpp +++ b/include/Nazara/Core/Debug/NewRedefinition.hpp @@ -21,7 +21,7 @@ NAZARA_CORE_API void operator delete[](void* ptr, const char* file, unsigned int #endif // NAZARA_DEBUG_NEWREDEFINITION_HPP #ifndef NAZARA_DEBUG_NEWREDEFINITION_DISABLE_REDEFINITION - #define delete NzMemoryManager::NextFree(__FILE__, __LINE__), delete + #define delete MemoryManager::NextFree(__FILE__, __LINE__), delete #define new new(__FILE__, __LINE__) #endif diff --git a/include/Nazara/Core/Directory.hpp b/include/Nazara/Core/Directory.hpp index b24962849..9dd24ee7d 100644 --- a/include/Nazara/Core/Directory.hpp +++ b/include/Nazara/Core/Directory.hpp @@ -25,54 +25,57 @@ #include #endif -class NzDirectoryImpl; - -class NAZARA_CORE_API NzDirectory +namespace Nz { - public: - NzDirectory(); - NzDirectory(const NzString& dirPath); - NzDirectory(const NzDirectory&) = delete; - NzDirectory(NzDirectory&&) = delete; ///TODO - ~NzDirectory(); + class DirectoryImpl; - void Close(); + class NAZARA_CORE_API Directory + { + public: + Directory(); + Directory(const String& dirPath); + Directory(const Directory&) = delete; + Directory(Directory&&) = delete; ///TODO + ~Directory(); - bool Exists() const; + void Close(); - NzString GetPath() const; - NzString GetPattern() const; - NzString GetResultName() const; - NzString GetResultPath() const; - nzUInt64 GetResultSize() const; + bool Exists() const; - bool IsOpen() const; - bool IsResultDirectory() const; + String GetPath() const; + String GetPattern() const; + String GetResultName() const; + String GetResultPath() const; + UInt64 GetResultSize() const; - bool NextResult(bool skipDots = true); + bool IsOpen() const; + bool IsResultDirectory() const; - bool Open(); + bool NextResult(bool skipDots = true); - void SetPath(const NzString& dirPath); - void SetPattern(const NzString& pattern); + bool Open(); - static bool Copy(const NzString& sourcePath, const NzString& destPath); - static bool Create(const NzString& dirPath, bool recursive = false); - static bool Exists(const NzString& dirPath); - static NzString GetCurrent(); - static const char* GetCurrentFileRelativeToEngine(const char* currentFile); - static bool Remove(const NzString& dirPath, bool emptyDirectory = false); - static bool SetCurrent(const NzString& dirPath); + void SetPath(const String& dirPath); + void SetPattern(const String& pattern); - NzDirectory& operator=(const NzDirectory&) = delete; - NzDirectory& operator=(NzDirectory&&) = delete; ///TODO + static bool Copy(const String& sourcePath, const String& destPath); + static bool Create(const String& dirPath, bool recursive = false); + static bool Exists(const String& dirPath); + static String GetCurrent(); + static const char* GetCurrentFileRelativeToEngine(const char* currentFile); + static bool Remove(const String& dirPath, bool emptyDirectory = false); + static bool SetCurrent(const String& dirPath); - private: - NazaraMutexAttrib(m_mutex, mutable) + Directory& operator=(const Directory&) = delete; + Directory& operator=(Directory&&) = delete; ///TODO - NzString m_dirPath; - NzString m_pattern; - NzDirectoryImpl* m_impl; -}; + private: + NazaraMutexAttrib(m_mutex, mutable) + + String m_dirPath; + String m_pattern; + DirectoryImpl* m_impl; + }; +} #endif // NAZARA_DIRECTORY_HPP diff --git a/include/Nazara/Core/DynLib.hpp b/include/Nazara/Core/DynLib.hpp index 0e92aaee7..767165fe4 100644 --- a/include/Nazara/Core/DynLib.hpp +++ b/include/Nazara/Core/DynLib.hpp @@ -26,34 +26,37 @@ #include #endif -using NzDynLibFunc = int (*)(); // Type "générique" de pointeur sur fonction - -class NzDynLibImpl; - -class NAZARA_CORE_API NzDynLib +namespace Nz { - public: - NzDynLib(); - NzDynLib(const NzDynLib&) = delete; - NzDynLib(NzDynLib&& lib); - ~NzDynLib(); + using DynLibFunc = int (*)(); // Type "générique" de pointeur sur fonction - NzString GetLastError() const; - NzDynLibFunc GetSymbol(const NzString& symbol) const; + class DynLibImpl; - bool IsLoaded() const; + class NAZARA_CORE_API DynLib + { + public: + DynLib(); + DynLib(const DynLib&) = delete; + DynLib(DynLib&& lib); + ~DynLib(); - bool Load(const NzString& libraryPath); - void Unload(); + String GetLastError() const; + DynLibFunc GetSymbol(const String& symbol) const; - NzDynLib& operator=(const NzDynLib&) = delete; - NzDynLib& operator=(NzDynLib&& lib); + bool IsLoaded() const; - private: - NazaraMutexAttrib(m_mutex, mutable) + bool Load(const String& libraryPath); + void Unload(); - mutable NzString m_lastError; - NzDynLibImpl* m_impl; + DynLib& operator=(const DynLib&) = delete; + DynLib& operator=(DynLib&& lib); + + private: + NazaraMutexAttrib(m_mutex, mutable) + + mutable String m_lastError; + DynLibImpl* m_impl; }; +} #endif // NAZARA_DYNLIB_HPP diff --git a/include/Nazara/Core/Endianness.hpp b/include/Nazara/Core/Endianness.hpp index 3f929f912..a97687dac 100644 --- a/include/Nazara/Core/Endianness.hpp +++ b/include/Nazara/Core/Endianness.hpp @@ -25,8 +25,11 @@ #error You cannot define both NAZARA_BIG_ENDIAN and NAZARA_LITTLE_ENDIAN #endif -inline void NzByteSwap(void* buffer, unsigned int size); -inline nzEndianness NzGetPlatformEndianness(); +namespace Nz +{ + inline Endianness GetPlatformEndianness(); + inline void SwapBytes(void* buffer, unsigned int size); +} #include diff --git a/include/Nazara/Core/Endianness.inl b/include/Nazara/Core/Endianness.inl index ab696dba3..3d489c567 100644 --- a/include/Nazara/Core/Endianness.inl +++ b/include/Nazara/Core/Endianness.inl @@ -5,23 +5,26 @@ #include #include -inline void NzByteSwap(void* buffer, unsigned int size) +namespace Nz { - nzUInt8* bytes = reinterpret_cast(buffer); - unsigned int i = 0; - unsigned int j = size-1; + inline Endianness GetPlatformEndianness() + { + #if defined(NAZARA_BIG_ENDIAN) + return Endianness_BigEndian; + #elif defined(NAZARA_LITTLE_ENDIAN) + return Endianness_LittleEndian; + #endif + } - while (i < j) - std::swap(bytes[i++], bytes[j--]); -} + inline void SwapBytes(void* buffer, unsigned int size) + { + UInt8* bytes = reinterpret_cast(buffer); + unsigned int i = 0; + unsigned int j = size-1; -inline nzEndianness NzGetPlatformEndianness() -{ - #if defined(NAZARA_BIG_ENDIAN) - return nzEndianness_BigEndian; - #elif defined(NAZARA_LITTLE_ENDIAN) - return nzEndianness_LittleEndian; - #endif + while (i < j) + std::swap(bytes[i++], bytes[j--]); + } } #include diff --git a/include/Nazara/Core/Enums.hpp b/include/Nazara/Core/Enums.hpp index 94d8584ad..02c92af35 100644 --- a/include/Nazara/Core/Enums.hpp +++ b/include/Nazara/Core/Enums.hpp @@ -7,182 +7,185 @@ #ifndef NAZARA_ENUMS_CORE_HPP #define NAZARA_ENUMS_CORE_HPP -enum nzCoordSys +namespace Nz { - nzCoordSys_Global, - nzCoordSys_Local, + enum CoordSys + { + CoordSys_Global, + CoordSys_Local, - nzCoordSys_Max = nzCoordSys_Local -}; + CoordSys_Max = CoordSys_Local + }; -enum nzCursorPosition -{ - nzCursorPosition_AtBegin, // Début du fichier - nzCursorPosition_AtCurrent, // Position du pointeur - nzCursorPosition_AtEnd, // Fin du fichier + enum CursorPosition + { + CursorPosition_AtBegin, // Début du fichier + CursorPosition_AtCurrent, // Position du pointeur + CursorPosition_AtEnd, // Fin du fichier - nzCursorPosition_Max = nzCursorPosition_AtEnd -}; + CursorPosition_Max = CursorPosition_AtEnd + }; -enum nzEndianness -{ - nzEndianness_Unknown = -1, + enum Endianness + { + Endianness_Unknown = -1, - nzEndianness_BigEndian, - nzEndianness_LittleEndian, + Endianness_BigEndian, + Endianness_LittleEndian, - nzEndianness_Max = nzEndianness_LittleEndian -}; + Endianness_Max = Endianness_LittleEndian + }; -enum nzErrorFlag -{ - nzErrorFlag_None = 0, + enum ErrorFlag + { + ErrorFlag_None = 0, - nzErrorFlag_Silent = 0x1, - nzErrorFlag_SilentDisabled = 0x2, - nzErrorFlag_ThrowException = 0x4, - nzErrorFlag_ThrowExceptionDisabled = 0x8, + ErrorFlag_Silent = 0x1, + ErrorFlag_SilentDisabled = 0x2, + ErrorFlag_ThrowException = 0x4, + ErrorFlag_ThrowExceptionDisabled = 0x8, - nzErrorFlag_Max = nzErrorFlag_ThrowExceptionDisabled*2-1 -}; + ErrorFlag_Max = ErrorFlag_ThrowExceptionDisabled*2-1 + }; -enum nzErrorType -{ - nzErrorType_AssertFailed, - nzErrorType_Internal, - nzErrorType_Normal, - nzErrorType_Warning, + enum ErrorType + { + ErrorType_AssertFailed, + ErrorType_Internal, + ErrorType_Normal, + ErrorType_Warning, - nzErrorType_Max = nzErrorType_Warning -}; + ErrorType_Max = ErrorType_Warning + }; -enum nzHash -{ - nzHash_CRC32, - nzHash_Fletcher16, - nzHash_MD5, - nzHash_SHA1, - nzHash_SHA224, - nzHash_SHA256, - nzHash_SHA384, - nzHash_SHA512, - nzHash_Whirlpool, + enum HashType + { + HashType_CRC32, + HashType_Fletcher16, + HashType_MD5, + HashType_SHA1, + HashType_SHA224, + HashType_SHA256, + HashType_SHA384, + HashType_SHA512, + HashType_Whirlpool, - nzHash_Max = nzHash_Whirlpool -}; + HashType_Max = HashType_Whirlpool + }; -enum nzOpenModeFlags -{ - nzOpenMode_Current = 0x00, // Utilise le mode d'ouverture actuel + enum OpenModeFlags + { + OpenMode_Current = 0x00, // Utilise le mode d'ouverture actuel - nzOpenMode_Append = 0x01, // Empêche l'écriture sur la partie déjà existante et met le curseur à la fin - nzOpenMode_Lock = 0x02, // Empêche le fichier d'être modifié tant qu'il est ouvert - nzOpenMode_ReadOnly = 0x04, // Ouvre uniquement en lecture - nzOpenMode_ReadWrite = 0x08, // Ouvre en lecture/écriture - nzOpenMode_Text = 0x10, // Ouvre en mode texte - nzOpenMode_Truncate = 0x20, // Créé le fichier s'il n'existe pas et le vide s'il existe - nzOpenMode_WriteOnly = 0x40, // Ouvre uniquement en écriture, créé le fichier s'il n'existe pas + OpenMode_Append = 0x01, // Empêche l'écriture sur la partie déjà existante et met le curseur à la fin + OpenMode_Lock = 0x02, // Empêche le fichier d'être modifié tant qu'il est ouvert + OpenMode_ReadOnly = 0x04, // Ouvre uniquement en lecture + OpenMode_ReadWrite = 0x08, // Ouvre en lecture/écriture + OpenMode_Text = 0x10, // Ouvre en mode texte + OpenMode_Truncate = 0x20, // Créé le fichier s'il n'existe pas et le vide s'il existe + OpenMode_WriteOnly = 0x40, // Ouvre uniquement en écriture, créé le fichier s'il n'existe pas - nzOpenMode_Max = nzOpenMode_WriteOnly -}; + OpenMode_Max = OpenMode_WriteOnly + }; -enum nzParameterType -{ - nzParameterType_Boolean, - nzParameterType_Float, - nzParameterType_Integer, - nzParameterType_None, - nzParameterType_Pointer, - nzParameterType_String, - nzParameterType_Userdata, + enum ParameterType + { + ParameterType_Boolean, + ParameterType_Float, + ParameterType_Integer, + ParameterType_None, + ParameterType_Pointer, + ParameterType_String, + ParameterType_Userdata, - nzParameterType_Max = nzParameterType_Userdata -}; + ParameterType_Max = ParameterType_Userdata + }; -enum nzPlugin -{ - nzPlugin_Assimp, - nzPlugin_FreeType -}; + enum Plugin + { + Plugin_Assimp, + Plugin_FreeType + }; -enum nzPrimitiveType -{ - nzPrimitiveType_Box, - nzPrimitiveType_Cone, - nzPrimitiveType_Plane, - nzPrimitiveType_Sphere, + enum PrimitiveType + { + PrimitiveType_Box, + PrimitiveType_Cone, + PrimitiveType_Plane, + PrimitiveType_Sphere, - nzPrimitiveType_Max = nzPrimitiveType_Sphere -}; + PrimitiveType_Max = PrimitiveType_Sphere + }; -enum nzProcessorCap -{ - nzProcessorCap_x64, - nzProcessorCap_AVX, - nzProcessorCap_FMA3, - nzProcessorCap_FMA4, - nzProcessorCap_MMX, - nzProcessorCap_XOP, - nzProcessorCap_SSE, - nzProcessorCap_SSE2, - nzProcessorCap_SSE3, - nzProcessorCap_SSSE3, - nzProcessorCap_SSE41, - nzProcessorCap_SSE42, - nzProcessorCap_SSE4a, + enum ProcessorCap + { + ProcessorCap_x64, + ProcessorCap_AVX, + ProcessorCap_FMA3, + ProcessorCap_FMA4, + ProcessorCap_MMX, + ProcessorCap_XOP, + ProcessorCap_SSE, + ProcessorCap_SSE2, + ProcessorCap_SSE3, + ProcessorCap_SSSE3, + ProcessorCap_SSE41, + ProcessorCap_SSE42, + ProcessorCap_SSE4a, - nzProcessorCap_Max = nzProcessorCap_SSE4a -}; + ProcessorCap_Max = ProcessorCap_SSE4a + }; -enum nzProcessorVendor -{ - nzProcessorVendor_Unknown = -1, + enum ProcessorVendor + { + ProcessorVendor_Unknown = -1, - nzProcessorVendor_AMD, - nzProcessorVendor_Centaur, - nzProcessorVendor_Cyrix, - nzProcessorVendor_Intel, - nzProcessorVendor_KVM, - nzProcessorVendor_HyperV, - nzProcessorVendor_NSC, - nzProcessorVendor_NexGen, - nzProcessorVendor_Rise, - nzProcessorVendor_SIS, - nzProcessorVendor_Transmeta, - nzProcessorVendor_UMC, - nzProcessorVendor_VIA, - nzProcessorVendor_VMware, - nzProcessorVendor_Vortex, - nzProcessorVendor_XenHVM, + ProcessorVendor_AMD, + ProcessorVendor_Centaur, + ProcessorVendor_Cyrix, + ProcessorVendor_Intel, + ProcessorVendor_KVM, + ProcessorVendor_HyperV, + ProcessorVendor_NSC, + ProcessorVendor_NexGen, + ProcessorVendor_Rise, + ProcessorVendor_SIS, + ProcessorVendor_Transmeta, + ProcessorVendor_UMC, + ProcessorVendor_VIA, + ProcessorVendor_VMware, + ProcessorVendor_Vortex, + ProcessorVendor_XenHVM, - nzProcessorVendor_Max = nzProcessorVendor_XenHVM -}; + ProcessorVendor_Max = ProcessorVendor_XenHVM + }; -enum nzSphereType -{ - nzSphereType_Cubic, - nzSphereType_Ico, - nzSphereType_UV, + enum SphereType + { + SphereType_Cubic, + SphereType_Ico, + SphereType_UV, - nzSphereType_Max = nzSphereType_UV -}; + SphereType_Max = SphereType_UV + }; -enum nzStreamOptionFlags -{ - nzStreamOption_None = 0, + enum StreamOptionFlags + { + StreamOption_None = 0, - nzStreamOption_Text = 0x1, + StreamOption_Text = 0x1, - nzStreamOption_Max = nzStreamOption_Text*2-1 -}; + StreamOption_Max = StreamOption_Text*2-1 + }; -enum nzTernary -{ - nzTernary_False, - nzTernary_True, - nzTernary_Unknown, + enum Ternary + { + Ternary_False, + Ternary_True, + Ternary_Unknown, - nzTernary_Max = nzTernary_Unknown -}; + Ternary_Max = Ternary_Unknown + }; +} #endif // NAZARA_ENUMS_CORE_HPP diff --git a/include/Nazara/Core/Error.hpp b/include/Nazara/Core/Error.hpp index 4253f5881..f970b5ba8 100644 --- a/include/Nazara/Core/Error.hpp +++ b/include/Nazara/Core/Error.hpp @@ -14,37 +14,40 @@ #include #if NAZARA_CORE_ENABLE_ASSERTS || defined(NAZARA_DEBUG) - #define NazaraAssert(a, err) if (!(a)) NzError::Error(nzErrorType_AssertFailed, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) + #define NazaraAssert(a, err) if (!(a)) Nz::Error::Trigger(Nz::ErrorType_AssertFailed, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) #else #define NazaraAssert(a, err) #endif -#define NazaraError(err) NzError::Error(nzErrorType_Normal, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) -#define NazaraInternalError(err) NzError::Error(nzErrorType_Internal, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) -#define NazaraWarning(err) NzError::Error(nzErrorType_Warning, err, __LINE__, NzDirectory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) +#define NazaraError(err) Nz::Error::Trigger(Nz::ErrorType_Normal, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) +#define NazaraInternalError(err) Nz::Error::Trigger(Nz::ErrorType_Internal, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) +#define NazaraWarning(err) Nz::Error::Trigger(Nz::ErrorType_Warning, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) -class NAZARA_CORE_API NzError +namespace Nz { - public: - NzError() = delete; - ~NzError() = delete; + class NAZARA_CORE_API Error + { + public: + Error() = delete; + ~Error() = delete; - static void Error(nzErrorType type, const NzString& error); - static void Error(nzErrorType type, const NzString& error, unsigned int line, const char* file, const char* function); + static UInt32 GetFlags(); + static String GetLastError(const char** file = nullptr, unsigned int* line = nullptr, const char** function = nullptr); + static unsigned int GetLastSystemErrorCode(); + static String GetLastSystemError(unsigned int code = GetLastSystemErrorCode()); - static nzUInt32 GetFlags(); - static NzString GetLastError(const char** file = nullptr, unsigned int* line = nullptr, const char** function = nullptr); - static unsigned int GetLastSystemErrorCode(); - static NzString GetLastSystemError(unsigned int code = GetLastSystemErrorCode()); + static void SetFlags(UInt32 flags); - static void SetFlags(nzUInt32 flags); + static void Trigger(ErrorType type, const String& error); + static void Trigger(ErrorType type, const String& error, unsigned int line, const char* file, const char* function); - private: - static nzUInt32 s_flags; - static NzString s_lastError; - static const char* s_lastErrorFunction; - static const char* s_lastErrorFile; - static unsigned int s_lastErrorLine; -}; + private: + static UInt32 s_flags; + static String s_lastError; + static const char* s_lastErrorFunction; + static const char* s_lastErrorFile; + static unsigned int s_lastErrorLine; + }; +} #endif // NAZARA_ERROR_HPP diff --git a/include/Nazara/Core/ErrorFlags.hpp b/include/Nazara/Core/ErrorFlags.hpp index b36b351bb..43f2ae589 100644 --- a/include/Nazara/Core/ErrorFlags.hpp +++ b/include/Nazara/Core/ErrorFlags.hpp @@ -10,23 +10,26 @@ #include #include -class NAZARA_CORE_API NzErrorFlags +namespace Nz { - public: - NzErrorFlags(nzUInt32 flags, bool replace = false); - NzErrorFlags(const NzErrorFlags&) = delete; - NzErrorFlags(NzErrorFlags&&) = delete; - ~NzErrorFlags(); + class NAZARA_CORE_API ErrorFlags + { + public: + ErrorFlags(UInt32 flags, bool replace = false); + ErrorFlags(const ErrorFlags&) = delete; + ErrorFlags(ErrorFlags&&) = delete; + ~ErrorFlags(); - nzUInt32 GetPreviousFlags() const; + UInt32 GetPreviousFlags() const; - void SetFlags(nzUInt32 flags, bool replace = false); + void SetFlags(UInt32 flags, bool replace = false); - NzErrorFlags& operator=(const NzErrorFlags&) = delete; - NzErrorFlags& operator=(NzErrorFlags&&) = delete; + ErrorFlags& operator=(const ErrorFlags&) = delete; + ErrorFlags& operator=(ErrorFlags&&) = delete; - private: - nzUInt32 m_previousFlags; -}; + private: + UInt32 m_previousFlags; + }; +} #endif // NAZARA_ERRORFLAGS_HPP diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index 8507fb1da..d73c27823 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -24,87 +24,90 @@ #include -class NzFileImpl; - -class NAZARA_CORE_API NzFile : public NzHashable, public NzInputStream +namespace Nz { - public: - NzFile(); - NzFile(const NzString& filePath); - NzFile(const NzString& filePath, unsigned int openMode); - NzFile(const NzFile&) = delete; - NzFile(NzFile&& file) noexcept; - ~NzFile(); + class FileImpl; - bool Copy(const NzString& newFilePath); - void Close(); + class NAZARA_CORE_API File : public Hashable, public InputStream + { + public: + File(); + File(const String& filePath); + File(const String& filePath, unsigned int openMode); + File(const File&) = delete; + File(File&& file) noexcept; + ~File(); - bool Delete(); + bool Copy(const String& newFilePath); + void Close(); - bool EndOfFile() const; - bool EndOfStream() const; + bool Delete(); - bool Exists() const; + bool EndOfFile() const; + bool EndOfStream() const; - void Flush(); + bool Exists() const; - time_t GetCreationTime() const; - nzUInt64 GetCursorPos() const; - NzString GetDirectory() const; - NzString GetFileName() const; - time_t GetLastAccessTime() const; - time_t GetLastWriteTime() const; - NzString GetPath() const; - nzUInt64 GetSize() const; + void Flush(); - bool IsOpen() const; + time_t GetCreationTime() const; + UInt64 GetCursorPos() const; + String GetDirectory() const; + String GetFileName() const; + time_t GetLastAccessTime() const; + time_t GetLastWriteTime() const; + String GetPath() const; + UInt64 GetSize() const; - bool Open(unsigned int openMode = nzOpenMode_Current); - bool Open(const NzString& filePath, unsigned int openMode = nzOpenMode_Current); + bool IsOpen() const; - std::size_t Read(void* buffer, std::size_t size); - std::size_t Read(void* buffer, std::size_t typeSize, unsigned int count); - bool Rename(const NzString& newFilePath); + bool Open(unsigned int openMode = OpenMode_Current); + bool Open(const String& filePath, unsigned int openMode = OpenMode_Current); - bool SetCursorPos(nzCursorPosition pos, nzInt64 offset = 0); - bool SetCursorPos(nzUInt64 offset); - void SetEndianness(nzEndianness endianness); - bool SetFile(const NzString& filePath); - bool SetOpenMode(unsigned int openMode); + std::size_t Read(void* buffer, std::size_t size); + std::size_t Read(void* buffer, std::size_t typeSize, unsigned int count); + bool Rename(const String& newFilePath); - bool Write(const NzByteArray& byteArray); - bool Write(const NzString& string); - std::size_t Write(const void* buffer, std::size_t typeSize, unsigned int count); + bool SetCursorPos(CursorPosition pos, Int64 offset = 0); + bool SetCursorPos(UInt64 offset); + void SetEndianness(Endianness endianness); + bool SetFile(const String& filePath); + bool SetOpenMode(unsigned int openMode); - NzFile& operator=(const NzString& filePath); - NzFile& operator=(const NzFile&) = delete; - NzFile& operator=(NzFile&& file) noexcept; + bool Write(const Nz::ByteArray& byteArray); + bool Write(const String& string); + std::size_t Write(const void* buffer, std::size_t typeSize, unsigned int count); - static NzString AbsolutePath(const NzString& filePath); - static bool Copy(const NzString& sourcePath, const NzString& targetPath); - static bool Delete(const NzString& filePath); - static bool Exists(const NzString& filePath); - static time_t GetCreationTime(const NzString& filePath); - static NzString GetDirectory(const NzString& filePath); - static time_t GetLastAccessTime(const NzString& filePath); - static time_t GetLastWriteTime(const NzString& filePath); - static NzHashDigest GetHash(const NzString& filePath, nzHash hash); - static NzHashDigest GetHash(const NzString& filePath, NzAbstractHash* hash); - static nzUInt64 GetSize(const NzString& filePath); - static bool IsAbsolute(const NzString& filePath); - static NzString NormalizePath(const NzString& filePath); - static NzString NormalizeSeparators(const NzString& filePath); - static bool Rename(const NzString& sourcePath, const NzString& targetPath); + File& operator=(const String& filePath); + File& operator=(const File&) = delete; + File& operator=(File&& file) noexcept; - private: - bool FillHash(NzAbstractHash* hash) const; + static String AbsolutePath(const String& filePath); + static bool Copy(const String& sourcePath, const String& targetPath); + static bool Delete(const String& filePath); + static bool Exists(const String& filePath); + static time_t GetCreationTime(const String& filePath); + static String GetDirectory(const String& filePath); + static time_t GetLastAccessTime(const String& filePath); + static time_t GetLastWriteTime(const String& filePath); + static HashDigest GetHash(const String& filePath, HashType hash); + static HashDigest GetHash(const String& filePath, AbstractHash* hash); + static UInt64 GetSize(const String& filePath); + static bool IsAbsolute(const String& filePath); + static String NormalizePath(const String& filePath); + static String NormalizeSeparators(const String& filePath); + static bool Rename(const String& sourcePath, const String& targetPath); - NazaraMutexAttrib(m_mutex, mutable) + private: + bool FillHash(AbstractHash* hash) const; - nzEndianness m_endianness; - NzString m_filePath; - NzFileImpl* m_impl; - unsigned int m_openMode; -}; + NazaraMutexAttrib(m_mutex, mutable) + + Endianness m_endianness; + String m_filePath; + FileImpl* m_impl; + unsigned int m_openMode; + }; +} #endif // NAZARA_FILE_HPP diff --git a/include/Nazara/Core/Functor.hpp b/include/Nazara/Core/Functor.hpp index 46ffc634f..994ecc5ae 100644 --- a/include/Nazara/Core/Functor.hpp +++ b/include/Nazara/Core/Functor.hpp @@ -11,47 +11,50 @@ // Inspiré du code de la SFML par Laurent Gomila -struct NzFunctor +namespace Nz { - virtual ~NzFunctor() {} + struct Functor + { + virtual ~Functor() {} - virtual void Run() = 0; -}; + virtual void Run() = 0; + }; -template -struct NzFunctorWithoutArgs : NzFunctor -{ - NzFunctorWithoutArgs(F func); + template + struct FunctorWithoutArgs : Functor + { + FunctorWithoutArgs(F func); - void Run(); + void Run(); - private: - F m_func; -}; + private: + F m_func; + }; -template -struct NzFunctorWithArgs : NzFunctor -{ - NzFunctorWithArgs(F func, Args&&... args); + template + struct FunctorWithArgs : Functor + { + FunctorWithArgs(F func, Args&&... args); - void Run(); + void Run(); - private: - F m_func; - std::tuple m_args; -}; + private: + F m_func; + std::tuple m_args; + }; -template -struct NzMemberWithoutArgs : NzFunctor -{ - NzMemberWithoutArgs(void (C::*func)(), C* object); + template + struct MemberWithoutArgs : Functor + { + MemberWithoutArgs(void (C::*func)(), C* object); - void Run(); + void Run(); - private: - void (C::*m_func)(); - C* m_object; -}; + private: + void (C::*m_func)(); + C* m_object; + }; +} #include diff --git a/include/Nazara/Core/Functor.inl b/include/Nazara/Core/Functor.inl index df9f4b8e4..84ea8e76f 100644 --- a/include/Nazara/Core/Functor.inl +++ b/include/Nazara/Core/Functor.inl @@ -4,41 +4,44 @@ #include -template -NzFunctorWithoutArgs::NzFunctorWithoutArgs(F func) : -m_func(func) +namespace Nz { -} + template + FunctorWithoutArgs::FunctorWithoutArgs(F func) : + m_func(func) + { + } -template -void NzFunctorWithoutArgs::Run() -{ - m_func(); -} + template + void FunctorWithoutArgs::Run() + { + m_func(); + } -template -NzFunctorWithArgs::NzFunctorWithArgs(F func, Args&&... args) : -m_func(func), -m_args(std::forward(args)...) -{ -} + template + FunctorWithArgs::FunctorWithArgs(F func, Args&&... args) : + m_func(func), + m_args(std::forward(args)...) + { + } -template -void NzFunctorWithArgs::Run() -{ - NzApply(m_func, m_args); -} + template + void FunctorWithArgs::Run() + { + Apply(m_func, m_args); + } -template -NzMemberWithoutArgs::NzMemberWithoutArgs(void (C::*func)(), C* object) : -m_func(func), -m_object(object) -{ -} + template + MemberWithoutArgs::MemberWithoutArgs(void (C::*func)(), C* object) : + m_func(func), + m_object(object) + { + } -template -void NzMemberWithoutArgs::Run() -{ - (m_object->*m_func)(); + template + void MemberWithoutArgs::Run() + { + (m_object->*m_func)(); + } } diff --git a/include/Nazara/Core/GuillotineBinPack.hpp b/include/Nazara/Core/GuillotineBinPack.hpp index 9cbd5ed6b..878df27ea 100644 --- a/include/Nazara/Core/GuillotineBinPack.hpp +++ b/include/Nazara/Core/GuillotineBinPack.hpp @@ -15,74 +15,77 @@ #include #include -class NAZARA_CORE_API NzGuillotineBinPack +namespace Nz { - public: - enum FreeRectChoiceHeuristic : int; - enum GuillotineSplitHeuristic : int; + class NAZARA_CORE_API GuillotineBinPack + { + public: + enum FreeRectChoiceHeuristic : int; + enum GuillotineSplitHeuristic : int; - NzGuillotineBinPack(); - NzGuillotineBinPack(unsigned int width, unsigned int height); - NzGuillotineBinPack(const NzVector2ui& size); - NzGuillotineBinPack(const NzGuillotineBinPack&) = default; - NzGuillotineBinPack(NzGuillotineBinPack&&) = default; - ~NzGuillotineBinPack() = default; + GuillotineBinPack(); + GuillotineBinPack(unsigned int width, unsigned int height); + GuillotineBinPack(const Vector2ui& size); + GuillotineBinPack(const GuillotineBinPack&) = default; + GuillotineBinPack(GuillotineBinPack&&) = default; + ~GuillotineBinPack() = default; - void Clear(); + void Clear(); - void Expand(unsigned int newWidth, unsigned newHeight); - void Expand(const NzVector2ui& newSize); + void Expand(unsigned int newWidth, unsigned newHeight); + void Expand(const Vector2ui& newSize); - void FreeRectangle(const NzRectui& rect); + void FreeRectangle(const Rectui& rect); - unsigned int GetHeight() const; - float GetOccupancy() const; - NzVector2ui GetSize() const; - unsigned int GetWidth() const; + unsigned int GetHeight() const; + float GetOccupancy() const; + Vector2ui GetSize() const; + unsigned int GetWidth() const; - bool Insert(NzRectui* rects, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod); - bool Insert(NzRectui* rects, bool* flipped, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod); - bool Insert(NzRectui* rects, bool* flipped, bool* inserted, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod); + bool Insert(Rectui* rects, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod); + bool Insert(Rectui* rects, bool* flipped, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod); + bool Insert(Rectui* rects, bool* flipped, bool* inserted, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod); - bool MergeFreeRectangles(); + bool MergeFreeRectangles(); - void Reset(); - void Reset(unsigned int width, unsigned int height); - void Reset(const NzVector2ui& size); + void Reset(); + void Reset(unsigned int width, unsigned int height); + void Reset(const Vector2ui& size); - NzGuillotineBinPack& operator=(const NzGuillotineBinPack&) = default; - NzGuillotineBinPack& operator=(NzGuillotineBinPack&&) = default; + GuillotineBinPack& operator=(const GuillotineBinPack&) = default; + GuillotineBinPack& operator=(GuillotineBinPack&&) = default; - enum FreeRectChoiceHeuristic : int - { - RectBestAreaFit, - RectBestLongSideFit, - RectBestShortSideFit, - RectWorstAreaFit, - RectWorstLongSideFit, - RectWorstShortSideFit - }; + enum FreeRectChoiceHeuristic : int + { + RectBestAreaFit, + RectBestLongSideFit, + RectBestShortSideFit, + RectWorstAreaFit, + RectWorstLongSideFit, + RectWorstShortSideFit + }; - enum GuillotineSplitHeuristic : int - { - SplitLongerAxis, - SplitLongerLeftoverAxis, - SplitMaximizeArea, - SplitMinimizeArea, - SplitShorterAxis, - SplitShorterLeftoverAxis - }; + enum GuillotineSplitHeuristic : int + { + SplitLongerAxis, + SplitLongerLeftoverAxis, + SplitMaximizeArea, + SplitMinimizeArea, + SplitShorterAxis, + SplitShorterLeftoverAxis + }; - private: - void SplitFreeRectAlongAxis(const NzRectui& freeRect, const NzRectui& placedRect, bool splitHorizontal); - void SplitFreeRectByHeuristic(const NzRectui& freeRect, const NzRectui& placedRect, GuillotineSplitHeuristic method); + private: + void SplitFreeRectAlongAxis(const Rectui& freeRect, const Rectui& placedRect, bool splitHorizontal); + void SplitFreeRectByHeuristic(const Rectui& freeRect, const Rectui& placedRect, GuillotineSplitHeuristic method); - static int ScoreByHeuristic(int width, int height, const NzRectui& freeRect, FreeRectChoiceHeuristic rectChoice); + static int ScoreByHeuristic(int width, int height, const Rectui& freeRect, FreeRectChoiceHeuristic rectChoice); - std::vector m_freeRectangles; - unsigned int m_height; - unsigned int m_usedArea; - unsigned int m_width; -}; + std::vector m_freeRectangles; + unsigned int m_height; + unsigned int m_usedArea; + unsigned int m_width; + }; +} #endif // NAZARA_GUILLOTINEBINPACK_HPP diff --git a/include/Nazara/Core/HardwareInfo.hpp b/include/Nazara/Core/HardwareInfo.hpp index ec844e6b2..2a79165cf 100644 --- a/include/Nazara/Core/HardwareInfo.hpp +++ b/include/Nazara/Core/HardwareInfo.hpp @@ -11,28 +11,31 @@ #include #include -class NAZARA_CORE_API NzHardwareInfo +namespace Nz { - public: - NzHardwareInfo() = delete; - ~NzHardwareInfo() = delete; + class NAZARA_CORE_API HardwareInfo + { + public: + HardwareInfo() = delete; + ~HardwareInfo() = delete; - static void Cpuid(nzUInt32 functionId, nzUInt32 subFunctionId, nzUInt32 result[4]); + static void Cpuid(UInt32 functionId, UInt32 subFunctionId, UInt32 result[4]); - static NzString GetProcessorBrandString(); - static unsigned int GetProcessorCount(); - static nzProcessorVendor GetProcessorVendor(); - static NzString GetProcessorVendorName(); - static nzUInt64 GetTotalMemory(); + static String GetProcessorBrandString(); + static unsigned int GetProcessorCount(); + static ProcessorVendor GetProcessorVendor(); + static String GetProcessorVendorName(); + static UInt64 GetTotalMemory(); - static bool HasCapability(nzProcessorCap capability); + static bool HasCapability(ProcessorCap capability); - static bool Initialize(); + static bool Initialize(); - static bool IsCpuidSupported(); - static bool IsInitialized(); + static bool IsCpuidSupported(); + static bool IsInitialized(); - static void Uninitialize(); -}; + static void Uninitialize(); + }; +} #endif // NAZARA_HARDWAREINFO_HPP diff --git a/include/Nazara/Core/Hash.hpp b/include/Nazara/Core/Hash.hpp index 45d03f935..a9a152a2b 100644 --- a/include/Nazara/Core/Hash.hpp +++ b/include/Nazara/Core/Hash.hpp @@ -12,22 +12,25 @@ #include #include -class NAZARA_CORE_API NzHash +namespace Nz { - public: - NzHash(nzHash hash); - NzHash(NzAbstractHash* hashImpl); - NzHash(const NzHash&) = delete; - NzHash(NzHash&&) = delete; ///TODO - ~NzHash(); + class NAZARA_CORE_API Hash + { + public: + Hash(HashType hash); + Hash(AbstractHash* hashImpl); + Hash(const Hash&) = delete; + Hash(Hash&&) = delete; ///TODO + ~Hash(); - NzHashDigest Hash(const NzHashable& hashable); + HashDigest Process(const Hashable& hashable); - NzHash& operator=(const NzHash&) = delete; - NzHash& operator=(NzHash&&) = delete; ///TODO + Hash& operator=(const Hash&) = delete; + Hash& operator=(Hash&&) = delete; ///TODO - private: - NzAbstractHash* m_impl; -}; + private: + AbstractHash* m_impl; + }; +} #endif // NAZARA_HASH_HPP diff --git a/include/Nazara/Core/Hash/CRC32.hpp b/include/Nazara/Core/Hash/CRC32.hpp index 04789932e..602432897 100644 --- a/include/Nazara/Core/Hash/CRC32.hpp +++ b/include/Nazara/Core/Hash/CRC32.hpp @@ -11,23 +11,26 @@ #include #include -struct NzHashCRC32_state; - -class NAZARA_CORE_API NzHashCRC32 : public NzAbstractHash +namespace Nz { - public: - NzHashCRC32(nzUInt32 polynomial = 0x04c11db7); - virtual ~NzHashCRC32(); + struct HashCRC32_state; - void Append(const nzUInt8* data, unsigned int len); - void Begin(); - NzHashDigest End(); + class NAZARA_CORE_API HashCRC32 : public AbstractHash + { + public: + HashCRC32(UInt32 polynomial = 0x04c11db7); + virtual ~HashCRC32(); - static unsigned int GetDigestLength(); - static NzString GetHashName(); + void Append(const UInt8* data, unsigned int len); + void Begin(); + HashDigest End(); - private: - NzHashCRC32_state* m_state; -}; + static unsigned int GetDigestLength(); + static String GetHashName(); + + private: + HashCRC32_state* m_state; + }; +} #endif // NAZARA_HASH_CRC32_HPP diff --git a/include/Nazara/Core/Hash/Fletcher16.hpp b/include/Nazara/Core/Hash/Fletcher16.hpp index bfa594fa9..de84ecfeb 100644 --- a/include/Nazara/Core/Hash/Fletcher16.hpp +++ b/include/Nazara/Core/Hash/Fletcher16.hpp @@ -12,23 +12,26 @@ #include #include -struct NzHashFletcher16_state; - -class NAZARA_CORE_API NzHashFletcher16 : public NzAbstractHash +namespace Nz { - public: - NzHashFletcher16(); - virtual ~NzHashFletcher16(); + struct HashFletcher16_state; - void Append(const nzUInt8* data, unsigned int len); - void Begin(); - NzHashDigest End(); + class NAZARA_CORE_API HashFletcher16 : public AbstractHash + { + public: + HashFletcher16(); + virtual ~HashFletcher16(); - static unsigned int GetDigestLength(); - static NzString GetHashName(); + void Append(const UInt8* data, unsigned int len); + void Begin(); + HashDigest End(); - private: - NzHashFletcher16_state* m_state; -}; + static unsigned int GetDigestLength(); + static String GetHashName(); + + private: + HashFletcher16_state* m_state; + }; +} #endif // NAZARA_HASH_FLETCHER16_HPP diff --git a/include/Nazara/Core/Hash/MD5.hpp b/include/Nazara/Core/Hash/MD5.hpp index e398d403d..b3723c7ed 100644 --- a/include/Nazara/Core/Hash/MD5.hpp +++ b/include/Nazara/Core/Hash/MD5.hpp @@ -11,23 +11,26 @@ #include #include -struct NzHashMD5_state; - -class NAZARA_CORE_API NzHashMD5 : public NzAbstractHash +namespace Nz { - public: - NzHashMD5(); - virtual ~NzHashMD5(); + struct HashMD5_state; - void Append(const nzUInt8* data, unsigned int len); - void Begin(); - NzHashDigest End(); + class NAZARA_CORE_API HashMD5 : public AbstractHash + { + public: + HashMD5(); + virtual ~HashMD5(); - static unsigned int GetDigestLength(); - static NzString GetHashName(); + void Append(const UInt8* data, unsigned int len); + void Begin(); + HashDigest End(); - private: - NzHashMD5_state* m_state; -}; + static unsigned int GetDigestLength(); + static String GetHashName(); + + private: + HashMD5_state* m_state; + }; +} #endif // NAZARA_HASH_MD5_HPP diff --git a/include/Nazara/Core/Hash/SHA1.hpp b/include/Nazara/Core/Hash/SHA1.hpp index f02b364de..abce7daee 100644 --- a/include/Nazara/Core/Hash/SHA1.hpp +++ b/include/Nazara/Core/Hash/SHA1.hpp @@ -11,23 +11,26 @@ #include #include -union SHA_CTX; - -class NAZARA_CORE_API NzHashSHA1 : public NzAbstractHash +namespace Nz { - public: - NzHashSHA1(); - virtual ~NzHashSHA1(); + union SHA_CTX; - void Append(const nzUInt8* data, unsigned int len); - void Begin(); - NzHashDigest End(); + class NAZARA_CORE_API HashSHA1 : public AbstractHash + { + public: + HashSHA1(); + virtual ~HashSHA1(); - static unsigned int GetDigestLength(); - static NzString GetHashName(); + void Append(const UInt8* data, unsigned int len); + void Begin(); + HashDigest End(); - private: - SHA_CTX* m_state; -}; + static unsigned int GetDigestLength(); + static String GetHashName(); + + private: + SHA_CTX* m_state; + }; +} #endif // NAZARA_HASH_SHA1_HPP diff --git a/include/Nazara/Core/Hash/SHA224.hpp b/include/Nazara/Core/Hash/SHA224.hpp index f98f0ef5c..f6f30da1c 100644 --- a/include/Nazara/Core/Hash/SHA224.hpp +++ b/include/Nazara/Core/Hash/SHA224.hpp @@ -11,23 +11,26 @@ #include #include -union SHA_CTX; - -class NAZARA_CORE_API NzHashSHA224 : public NzAbstractHash +namespace Nz { - public: - NzHashSHA224(); - virtual ~NzHashSHA224(); + union SHA_CTX; - void Append(const nzUInt8* data, unsigned int len); - void Begin(); - NzHashDigest End(); + class NAZARA_CORE_API HashSHA224 : public AbstractHash + { + public: + HashSHA224(); + virtual ~HashSHA224(); - static unsigned int GetDigestLength(); - static NzString GetHashName(); + void Append(const UInt8* data, unsigned int len); + void Begin(); + HashDigest End(); - private: - SHA_CTX* m_state; -}; + static unsigned int GetDigestLength(); + static String GetHashName(); + + private: + SHA_CTX* m_state; + }; +} #endif // NAZARA_HASH_SHA224_HPP diff --git a/include/Nazara/Core/Hash/SHA256.hpp b/include/Nazara/Core/Hash/SHA256.hpp index 0f407a2b2..7d7b672af 100644 --- a/include/Nazara/Core/Hash/SHA256.hpp +++ b/include/Nazara/Core/Hash/SHA256.hpp @@ -11,23 +11,26 @@ #include #include -union SHA_CTX; - -class NAZARA_CORE_API NzHashSHA256 : public NzAbstractHash +namespace Nz { - public: - NzHashSHA256(); - virtual ~NzHashSHA256(); + union SHA_CTX; - void Append(const nzUInt8* data, unsigned int len); - void Begin(); - NzHashDigest End(); + class NAZARA_CORE_API HashSHA256 : public AbstractHash + { + public: + HashSHA256(); + virtual ~HashSHA256(); - static unsigned int GetDigestLength(); - static NzString GetHashName(); + void Append(const UInt8* data, unsigned int len); + void Begin(); + HashDigest End(); - private: - SHA_CTX* m_state; -}; + static unsigned int GetDigestLength(); + static String GetHashName(); + + private: + SHA_CTX* m_state; + }; +} #endif // NAZARA_HASH_SHA256_HPP diff --git a/include/Nazara/Core/Hash/SHA384.hpp b/include/Nazara/Core/Hash/SHA384.hpp index bfd7995b5..8c03cac90 100644 --- a/include/Nazara/Core/Hash/SHA384.hpp +++ b/include/Nazara/Core/Hash/SHA384.hpp @@ -11,23 +11,26 @@ #include #include -union SHA_CTX; - -class NAZARA_CORE_API NzHashSHA384 : public NzAbstractHash +namespace Nz { - public: - NzHashSHA384(); - virtual ~NzHashSHA384(); + union SHA_CTX; - void Append(const nzUInt8* data, unsigned int len); - void Begin(); - NzHashDigest End(); + class NAZARA_CORE_API HashSHA384 : public AbstractHash + { + public: + HashSHA384(); + virtual ~HashSHA384(); - static unsigned int GetDigestLength(); - static NzString GetHashName(); + void Append(const UInt8* data, unsigned int len); + void Begin(); + HashDigest End(); - private: - SHA_CTX* m_state; -}; + static unsigned int GetDigestLength(); + static String GetHashName(); + + private: + SHA_CTX* m_state; + }; +} #endif // NAZARA_HASH_SHA384_HPP diff --git a/include/Nazara/Core/Hash/SHA512.hpp b/include/Nazara/Core/Hash/SHA512.hpp index 3e28a7597..799022266 100644 --- a/include/Nazara/Core/Hash/SHA512.hpp +++ b/include/Nazara/Core/Hash/SHA512.hpp @@ -11,23 +11,26 @@ #include #include -union SHA_CTX; - -class NAZARA_CORE_API NzHashSHA512 : public NzAbstractHash +namespace Nz { - public: - NzHashSHA512(); - virtual ~NzHashSHA512(); + union SHA_CTX; - void Append(const nzUInt8* data, unsigned int len); - void Begin(); - NzHashDigest End(); + class NAZARA_CORE_API HashSHA512 : public AbstractHash + { + public: + HashSHA512(); + virtual ~HashSHA512(); - static unsigned int GetDigestLength(); - static NzString GetHashName(); + void Append(const UInt8* data, unsigned int len); + void Begin(); + HashDigest End(); - private: - SHA_CTX* m_state; -}; + static unsigned int GetDigestLength(); + static String GetHashName(); + + private: + SHA_CTX* m_state; + }; +} #endif // NAZARA_HASH_SHA512_HPP diff --git a/include/Nazara/Core/Hash/Whirlpool.hpp b/include/Nazara/Core/Hash/Whirlpool.hpp index 1eacee93f..9d49a5ecf 100644 --- a/include/Nazara/Core/Hash/Whirlpool.hpp +++ b/include/Nazara/Core/Hash/Whirlpool.hpp @@ -9,23 +9,26 @@ #include #include -struct NzHashWhirlpool_state; - -class NAZARA_CORE_API NzHashWhirlpool : public NzAbstractHash +namespace Nz { - public: - NzHashWhirlpool(); - virtual ~NzHashWhirlpool(); + struct HashWhirlpool_state; - void Append(const nzUInt8* data, unsigned int len); - void Begin(); - NzHashDigest End(); + class NAZARA_CORE_API HashWhirlpool : public AbstractHash + { + public: + HashWhirlpool(); + virtual ~HashWhirlpool(); - static unsigned int GetDigestLength(); - static NzString GetHashName(); + void Append(const UInt8* data, unsigned int len); + void Begin(); + HashDigest End(); - private: - NzHashWhirlpool_state* m_state; -}; + static unsigned int GetDigestLength(); + static String GetHashName(); + + private: + HashWhirlpool_state* m_state; + }; +} #endif // NAZARA_HASH_WHIRLPOOL_HPP diff --git a/include/Nazara/Core/HashDigest.hpp b/include/Nazara/Core/HashDigest.hpp index 42d04acf3..902104de1 100644 --- a/include/Nazara/Core/HashDigest.hpp +++ b/include/Nazara/Core/HashDigest.hpp @@ -13,41 +13,44 @@ #include #include -class NAZARA_CORE_API NzHashDigest +namespace Nz { - public: - NzHashDigest(); - NzHashDigest(const NzString& hashName, const nzUInt8* digest, unsigned int length); - NzHashDigest(const NzHashDigest& rhs); - NzHashDigest(NzHashDigest&& rhs) noexcept; - ~NzHashDigest(); + class NAZARA_CORE_API HashDigest + { + public: + HashDigest(); + HashDigest(const String& hashName, const UInt8* digest, unsigned int length); + HashDigest(const HashDigest& rhs); + HashDigest(HashDigest&& rhs) noexcept; + ~HashDigest(); - bool IsValid() const; + bool IsValid() const; - const nzUInt8* GetDigest() const; - unsigned int GetDigestLength() const; - NzString GetHashName() const; + const UInt8* GetDigest() const; + unsigned int GetDigestLength() const; + String GetHashName() const; - NzString ToHex() const; + String ToHex() const; - nzUInt8 operator[](unsigned int pos) const; + UInt8 operator[](unsigned int pos) const; - NzHashDigest& operator=(const NzHashDigest& rhs); - NzHashDigest& operator=(NzHashDigest&& rhs) noexcept; + HashDigest& operator=(const HashDigest& rhs); + HashDigest& operator=(HashDigest&& rhs) noexcept; - bool operator==(const NzHashDigest& rhs) const; - bool operator!=(const NzHashDigest& rhs) const; - bool operator<(const NzHashDigest& rhs) const; - bool operator<=(const NzHashDigest& rhs) const; - bool operator>(const NzHashDigest& rhs) const; - bool operator>=(const NzHashDigest& rhs) const; + bool operator==(const HashDigest& rhs) const; + bool operator!=(const HashDigest& rhs) const; + bool operator<(const HashDigest& rhs) const; + bool operator<=(const HashDigest& rhs) const; + bool operator>(const HashDigest& rhs) const; + bool operator>=(const HashDigest& rhs) const; - NAZARA_CORE_API friend std::ostream& operator<<(std::ostream& out, const NzHashDigest& string); + NAZARA_CORE_API friend std::ostream& operator<<(std::ostream& out, const HashDigest& string); - private: - NzString m_hashName; - nzUInt8* m_digest; - unsigned int m_digestLength; -}; + private: + String m_hashName; + UInt8* m_digest; + unsigned int m_digestLength; + }; +} #endif // NAZARA_HASHDIGEST_HPP diff --git a/include/Nazara/Core/Hashable.hpp b/include/Nazara/Core/Hashable.hpp index d46773674..3c79b319f 100644 --- a/include/Nazara/Core/Hashable.hpp +++ b/include/Nazara/Core/Hashable.hpp @@ -10,27 +10,30 @@ #include #include -class NzAbstractHash; -class NzHashDigest; - -class NAZARA_CORE_API NzHashable +namespace Nz { - friend class NzHash; + class AbstractHash; + class HashDigest; - public: - NzHashable() = default; - NzHashable(const NzHashable&) = default; - NzHashable(NzHashable&&) = default; - virtual ~NzHashable(); + class NAZARA_CORE_API Hashable + { + friend class Hash; - NzHashDigest GetHash(nzHash hash) const; - NzHashDigest GetHash(NzAbstractHash* impl) const; + public: + Hashable() = default; + Hashable(const Hashable&) = default; + Hashable(Hashable&&) = default; + virtual ~Hashable(); - NzHashable& operator=(const NzHashable&) = default; - NzHashable& operator=(NzHashable&&) = default; + HashDigest GetHash(HashType hash) const; + HashDigest GetHash(AbstractHash* impl) const; - private: - virtual bool FillHash(NzAbstractHash* impl) const = 0; -}; + Hashable& operator=(const Hashable&) = default; + Hashable& operator=(Hashable&&) = default; + + private: + virtual bool FillHash(AbstractHash* impl) const = 0; + }; +} #endif // HASHABLE_HPP_INCLUDED diff --git a/include/Nazara/Core/Initializer.hpp b/include/Nazara/Core/Initializer.hpp index c7a8109f6..d884dfcc8 100644 --- a/include/Nazara/Core/Initializer.hpp +++ b/include/Nazara/Core/Initializer.hpp @@ -9,27 +9,30 @@ #include -template -class NzInitializer +namespace Nz { - public: - NzInitializer(bool initialize = true); - NzInitializer(const NzInitializer&) = delete; - NzInitializer(NzInitializer&&) = delete; ///TODO - ~NzInitializer(); + template + class Initializer + { + public: + Initializer(bool initialize = true); + Initializer(const Initializer&) = delete; + Initializer(Initializer&&) = delete; ///TODO + ~Initializer(); - bool Initialize(); - bool IsInitialized() const; - void Uninitialize(); + bool Initialize(); + bool IsInitialized() const; + void Uninitialize(); - operator bool() const; + operator bool() const; - NzInitializer& operator=(const NzInitializer&) = delete; - NzInitializer& operator=(NzInitializer&&) = delete; ///TODO + Initializer& operator=(const Initializer&) = delete; + Initializer& operator=(Initializer&&) = delete; ///TODO - private: - bool m_initialized; -}; + private: + bool m_initialized; + }; +} #include diff --git a/include/Nazara/Core/Initializer.inl b/include/Nazara/Core/Initializer.inl index 0bc5f1fda..cb2529643 100644 --- a/include/Nazara/Core/Initializer.inl +++ b/include/Nazara/Core/Initializer.inl @@ -4,84 +4,91 @@ #include -template struct NzImplInitializer; - -template -struct NzImplInitializer +namespace Nz { - static bool Init() + namespace Detail { - if (T::Initialize()) + template struct Initializer; + + template + struct Initializer { - if (NzImplInitializer::Init()) - return true; - else + static bool Init() + { + if (T::Initialize()) + { + if (Initializer::Init()) + return true; + else + T::Uninitialize(); + } + + return false; + } + + static void Uninit() + { + Initializer::Uninit(); T::Uninitialize(); - } + } + }; - return false; + template<> + struct Initializer<> + { + static bool Init() + { + return true; + } + + static void Uninit() + { + } + }; } - static void Uninit() + + template + Initializer::Initializer(bool initialize) : + m_initialized(false) { - NzImplInitializer::Uninit(); - T::Uninitialize(); + if (initialize) + Initialize(); } -}; -template<> -struct NzImplInitializer<> -{ - static bool Init() + template + Initializer::~Initializer() { - return true; + Uninitialize(); } - static void Uninit() + template + bool Initializer::Initialize() { + if (!m_initialized) + m_initialized = Detail::Initializer::Init(); + + return m_initialized; } -}; -template -NzInitializer::NzInitializer(bool initialize) : -m_initialized(false) -{ - if (initialize) - Initialize(); -} + template + bool Initializer::IsInitialized() const + { + return m_initialized; + } -template -NzInitializer::~NzInitializer() -{ - Uninitialize(); -} + template + void Initializer::Uninitialize() + { + if (m_initialized) + Detail::Initializer::Uninit(); + } -template -bool NzInitializer::Initialize() -{ - if (!m_initialized) - m_initialized = NzImplInitializer::Init(); - - return m_initialized; -} - -template -bool NzInitializer::IsInitialized() const -{ - return m_initialized; -} - -template -void NzInitializer::Uninitialize() -{ - if (m_initialized) - NzImplInitializer::Uninit(); -} - -template -NzInitializer::operator bool() const -{ - return IsInitialized(); + template + Initializer::operator bool() const + { + return IsInitialized(); + } } #include diff --git a/include/Nazara/Core/InputStream.hpp b/include/Nazara/Core/InputStream.hpp index 8b9d31766..1aea60cd8 100644 --- a/include/Nazara/Core/InputStream.hpp +++ b/include/Nazara/Core/InputStream.hpp @@ -10,17 +10,20 @@ #include #include -class NAZARA_CORE_API NzInputStream : public NzStream +namespace Nz { - public: - virtual ~NzInputStream(); + class NAZARA_CORE_API InputStream : public Stream + { + public: + virtual ~InputStream(); - virtual bool EndOfStream() const = 0; + virtual bool EndOfStream() const = 0; - virtual nzUInt64 GetSize() const = 0; + virtual UInt64 GetSize() const = 0; - virtual std::size_t Read(void* buffer, std::size_t size) = 0; - virtual NzString ReadLine(unsigned int lineSize = 0); -}; + virtual std::size_t Read(void* buffer, std::size_t size) = 0; + virtual String ReadLine(unsigned int lineSize = 0); + }; +} #endif // NAZARA_INPUTSTREAM_HPP diff --git a/include/Nazara/Core/LockGuard.hpp b/include/Nazara/Core/LockGuard.hpp index 409c0ad8c..2dac4b578 100644 --- a/include/Nazara/Core/LockGuard.hpp +++ b/include/Nazara/Core/LockGuard.hpp @@ -9,16 +9,19 @@ #include -class NzMutex; - -class NAZARA_CORE_API NzLockGuard +namespace Nz { - public: - NzLockGuard(NzMutex& mutex); - ~NzLockGuard(); + class Mutex; - private: - NzMutex& m_mutex; -}; + class NAZARA_CORE_API LockGuard + { + public: + LockGuard(Mutex& mutex); + ~LockGuard(); + + private: + Mutex& m_mutex; + }; +} #endif // NAZARA_LOCKGUARD_HPP diff --git a/include/Nazara/Core/Log.hpp b/include/Nazara/Core/Log.hpp index c41bf0c48..27ae6577d 100644 --- a/include/Nazara/Core/Log.hpp +++ b/include/Nazara/Core/Log.hpp @@ -23,46 +23,49 @@ #define NazaraDebug(txt) #endif -#define NazaraLog NzLog::Instance() +#define NazaraLog Nz::Log::Instance() #define NazaraNotice(txt) NazaraLog->Write(txt) -class NzFile; - -class NAZARA_CORE_API NzLog +namespace Nz { - public: - void Enable(bool enable); - void EnableAppend(bool enable); - void EnableDateTime(bool enable); + class File; - NzString GetFile() const; + class NAZARA_CORE_API Log + { + public: + void Enable(bool enable); + void EnableAppend(bool enable); + void EnableDateTime(bool enable); - bool IsEnabled() const; + String GetFile() const; - void SetFile(const NzString& filePath); + bool IsEnabled() const; - void Write(const NzString& string); - void WriteError(nzErrorType type, const NzString& error); - void WriteError(nzErrorType type, const NzString& error, unsigned int line, const NzString& file, const NzString& func); + void SetFile(const String& filePath); - static NzLog* Instance(); + void Write(const String& string); + void WriteError(ErrorType type, const String& error); + void WriteError(ErrorType type, const String& error, unsigned int line, const String& file, const String& func); - private: - NzLog(); - NzLog(const NzLog&) = delete; - NzLog(NzLog&&) = delete; - ~NzLog(); + static Log* Instance(); - NzLog& operator=(const NzLog&) = delete; - NzLog& operator=(NzLog&&) = delete; + private: + Log(); + Log(const Log&) = delete; + Log(Log&&) = delete; + ~Log(); - NazaraMutexAttrib(m_mutex, mutable) + Log& operator=(const Log&) = delete; + Log& operator=(Log&&) = delete; - NzString m_filePath; - NzFile* m_file; - bool m_append; - bool m_enabled; - bool m_writeTime; -}; + NazaraMutexAttrib(m_mutex, mutable) + + String m_filePath; + File* m_file; + bool m_append; + bool m_enabled; + bool m_writeTime; + }; +} #endif // NAZARA_LOGGER_HPP diff --git a/include/Nazara/Core/MemoryHelper.hpp b/include/Nazara/Core/MemoryHelper.hpp index 959f170f6..880418bec 100644 --- a/include/Nazara/Core/MemoryHelper.hpp +++ b/include/Nazara/Core/MemoryHelper.hpp @@ -9,11 +9,14 @@ #include -void NzOperatorDelete(void* ptr); -void* NzOperatorNew(std::size_t size); +namespace Nz +{ + void OperatorDelete(void* ptr); + void* OperatorNew(std::size_t size); -template -T* NzPlacementNew(void* ptr, Args&&... args); + template + T* PlacementNew(void* ptr, Args&&... args); +} #include diff --git a/include/Nazara/Core/MemoryHelper.inl b/include/Nazara/Core/MemoryHelper.inl index e28363a7d..579e02ae2 100644 --- a/include/Nazara/Core/MemoryHelper.inl +++ b/include/Nazara/Core/MemoryHelper.inl @@ -14,28 +14,31 @@ #include #include -inline void NzOperatorDelete(void* ptr) +namespace Nz { - #if NAZARA_CORE_MANAGE_MEMORY - NzMemoryManager::Free(ptr); - #else - operator delete(ptr); - #endif -} + inline void OperatorDelete(void* ptr) + { + #if NAZARA_CORE_MANAGE_MEMORY + MemoryManager::Free(ptr); + #else + operator delete(ptr); + #endif + } -inline void* NzOperatorNew(std::size_t size) -{ - #if NAZARA_CORE_MANAGE_MEMORY - return NzMemoryManager::Allocate(size); - #else - return operator new(size); - #endif -} + inline void* OperatorNew(std::size_t size) + { + #if NAZARA_CORE_MANAGE_MEMORY + return MemoryManager::Allocate(size); + #else + return operator new(size); + #endif + } -template -T* NzPlacementNew(void* ptr, Args&&... args) -{ - return new (ptr) T(std::forward(args)...); + template + T* PlacementNew(void* ptr, Args&&... args) + { + return new (ptr) T(std::forward(args)...); + } } #include diff --git a/include/Nazara/Core/MemoryManager.hpp b/include/Nazara/Core/MemoryManager.hpp index fb17539e9..39d5be712 100644 --- a/include/Nazara/Core/MemoryManager.hpp +++ b/include/Nazara/Core/MemoryManager.hpp @@ -11,32 +11,35 @@ #include #include -class NAZARA_CORE_API NzMemoryManager +namespace Nz { - public: - static void* Allocate(std::size_t size, bool multi = false, const char* file = nullptr, unsigned int line = 0); + class NAZARA_CORE_API MemoryManager + { + public: + static void* Allocate(std::size_t size, bool multi = false, const char* file = nullptr, unsigned int line = 0); - static void EnableAllocationFilling(bool allocationFilling); - static void EnableAllocationLogging(bool logAllocations); + static void EnableAllocationFilling(bool allocationFilling); + static void EnableAllocationLogging(bool logAllocations); - static void Free(void* pointer, bool multi = false); + static void Free(void* pointer, bool multi = false); - static unsigned int GetAllocatedBlockCount(); - static std::size_t GetAllocatedSize(); - static unsigned int GetAllocationCount(); + static unsigned int GetAllocatedBlockCount(); + static std::size_t GetAllocatedSize(); + static unsigned int GetAllocationCount(); - static bool IsAllocationFillingEnabled(); - static bool IsAllocationLoggingEnabled(); + static bool IsAllocationFillingEnabled(); + static bool IsAllocationLoggingEnabled(); - static void NextFree(const char* file, unsigned int line); + static void NextFree(const char* file, unsigned int line); - private: - NzMemoryManager(); - ~NzMemoryManager(); + private: + MemoryManager(); + ~MemoryManager(); - static void Initialize(); - static void TimeInfo(char buffer[23]); - static void Uninitialize(); -}; + static void Initialize(); + static void TimeInfo(char buffer[23]); + static void Uninitialize(); + }; +} #endif // NAZARA_MEMORYMANAGER_HPP diff --git a/include/Nazara/Core/MemoryPool.hpp b/include/Nazara/Core/MemoryPool.hpp index 2f22a484b..71761b612 100644 --- a/include/Nazara/Core/MemoryPool.hpp +++ b/include/Nazara/Core/MemoryPool.hpp @@ -11,39 +11,42 @@ #include #include -class NzMemoryPool +namespace Nz { - public: - NzMemoryPool(unsigned int blockSize, unsigned int size = 1024, bool canGrow = true); - NzMemoryPool(const NzMemoryPool&) = delete; - NzMemoryPool(NzMemoryPool&& pool) noexcept; - ~NzMemoryPool() = default; + class MemoryPool + { + public: + MemoryPool(unsigned int blockSize, unsigned int size = 1024, bool canGrow = true); + MemoryPool(const MemoryPool&) = delete; + MemoryPool(MemoryPool&& pool) noexcept; + ~MemoryPool() = default; - void* Allocate(unsigned int size); - template void Delete(T* ptr); - void Free(void* ptr); + void* Allocate(unsigned int size); + template void Delete(T* ptr); + void Free(void* ptr); - unsigned int GetBlockSize() const; - unsigned int GetFreeBlocks() const; - unsigned int GetSize() const; + unsigned int GetBlockSize() const; + unsigned int GetFreeBlocks() const; + unsigned int GetSize() const; - template T* New(Args&&... args); + template T* New(Args&&... args); - NzMemoryPool& operator=(const NzMemoryPool&) = delete; - NzMemoryPool& operator=(NzMemoryPool&& pool) noexcept; + MemoryPool& operator=(const MemoryPool&) = delete; + MemoryPool& operator=(MemoryPool&& pool) noexcept; - private: - NzMemoryPool(NzMemoryPool* pool); + private: + MemoryPool(MemoryPool* pool); - std::unique_ptr m_freeList; - std::unique_ptr m_pool; - std::unique_ptr m_next; - std::atomic_uint m_freeCount; - NzMemoryPool* m_previous; - bool m_canGrow; - unsigned int m_blockSize; - unsigned int m_size; -}; + std::unique_ptr m_freeList; + std::unique_ptr m_pool; + std::unique_ptr m_next; + std::atomic_uint m_freeCount; + MemoryPool* m_previous; + bool m_canGrow; + unsigned int m_blockSize; + unsigned int m_size; + }; +} #include diff --git a/include/Nazara/Core/MemoryPool.inl b/include/Nazara/Core/MemoryPool.inl index 49241905a..9ba21fa0c 100644 --- a/include/Nazara/Core/MemoryPool.inl +++ b/include/Nazara/Core/MemoryPool.inl @@ -6,140 +6,143 @@ #include #include -inline NzMemoryPool::NzMemoryPool(unsigned int blockSize, unsigned int size, bool canGrow) : -m_freeCount(size), -m_previous(nullptr), -m_canGrow(canGrow), -m_blockSize(blockSize), -m_size(size) +namespace Nz { - m_pool.reset(new nzUInt8[blockSize * size]); - m_freeList.reset(new void*[size]); - - // Remplissage de la free list - for (unsigned int i = 0; i < size; ++i) - m_freeList[i] = &m_pool[m_blockSize * (size-i-1)]; -} - -inline NzMemoryPool::NzMemoryPool(NzMemoryPool&& pool) noexcept -{ - operator=(std::move(pool)); -} - -inline NzMemoryPool::NzMemoryPool(NzMemoryPool* pool) : -NzMemoryPool(pool->m_blockSize, pool->m_size, pool->m_canGrow) -{ - m_previous = pool; -} - -inline void* NzMemoryPool::Allocate(unsigned int size) -{ - ///DOC: Si la taille est supérieure à celle d'un bloc du pool, l'opérateur new est utilisé - if (size <= m_blockSize) + inline MemoryPool::MemoryPool(unsigned int blockSize, unsigned int size, bool canGrow) : + m_freeCount(size), + m_previous(nullptr), + m_canGrow(canGrow), + m_blockSize(blockSize), + m_size(size) { - if (m_freeCount > 0) - return m_freeList[--m_freeCount]; - else if (m_canGrow) - { - if (!m_next) - m_next.reset(new NzMemoryPool(this)); + m_pool.reset(new UInt8[blockSize * size]); + m_freeList.reset(new void*[size]); - return m_next->Allocate(size); - } + // Remplissage de la free list + for (unsigned int i = 0; i < size; ++i) + m_freeList[i] = &m_pool[m_blockSize * (size-i-1)]; } - return NzOperatorNew(size); -} - -template -inline void NzMemoryPool::Delete(T* ptr) -{ - ///DOC: Va appeler le destructeur de l'objet avant de le libérer - if (ptr) + inline MemoryPool::MemoryPool(MemoryPool&& pool) noexcept { - ptr->~T(); - Free(ptr); + operator=(std::move(pool)); } -} -inline void NzMemoryPool::Free(void* ptr) -{ - ///DOC: Si appelé avec un pointeur ne faisant pas partie du pool, l'opérateur delete est utilisé - if (ptr) + inline MemoryPool::MemoryPool(MemoryPool* pool) : + MemoryPool(pool->m_blockSize, pool->m_size, pool->m_canGrow) { - // Le pointeur nous appartient-il ? - nzUInt8* freePtr = static_cast(ptr); - nzUInt8* poolPtr = m_pool.get(); - if (freePtr >= poolPtr && freePtr < poolPtr + m_blockSize*m_size) + m_previous = pool; + } + + inline void* MemoryPool::Allocate(unsigned int size) + { + ///DOC: Si la taille est supérieure à celle d'un bloc du pool, l'opérateur new est utilisé + if (size <= m_blockSize) { - #if NAZARA_CORE_SAFE - if ((freePtr - poolPtr) % m_blockSize != 0) - throw std::runtime_error("Invalid pointer (does not point to an element of the pool)"); - #endif - - m_freeList[m_freeCount++] = ptr; - - // Si nous sommes vide et l'extension d'un autre pool, nous nous suicidons - if (m_freeCount == m_size && m_previous && !m_next) + if (m_freeCount > 0) + return m_freeList[--m_freeCount]; + else if (m_canGrow) { - m_previous->m_next.release(); - delete this; // Suicide + if (!m_next) + m_next.reset(new MemoryPool(this)); + + return m_next->Allocate(size); } } - else + + return OperatorNew(size); + } + + template + inline void MemoryPool::Delete(T* ptr) + { + ///DOC: Va appeler le destructeur de l'objet avant de le libérer + if (ptr) { - if (m_next) - m_next->Free(ptr); - else - NzOperatorDelete(ptr); + ptr->~T(); + Free(ptr); } } -} -inline unsigned int NzMemoryPool::GetBlockSize() const -{ - return m_blockSize; -} - -inline unsigned int NzMemoryPool::GetFreeBlocks() const -{ - return m_freeCount; -} - -inline unsigned int NzMemoryPool::GetSize() const -{ - return m_size; -} - -template -inline T* NzMemoryPool::New(Args&&... args) -{ - ///DOC: Permet de construire un objet directement dans le pook - T* object = static_cast(Allocate(sizeof(T))); - NzPlacementNew(object, std::forward(args)...); - - return object; -} - -inline NzMemoryPool& NzMemoryPool::operator=(NzMemoryPool&& pool) noexcept -{ - m_blockSize = pool.m_blockSize; - m_canGrow = pool.m_canGrow; - m_freeCount = pool.m_freeCount.load(std::memory_order_relaxed); - m_freeList = std::move(pool.m_freeList); - m_pool = std::move(pool.m_pool); - m_previous = pool.m_previous; - m_next = std::move(pool.m_next); - m_size = pool.m_size; - - // Si nous avons été créés par un autre pool, nous devons le faire pointer vers nous de nouveau - if (m_previous) + inline void MemoryPool::Free(void* ptr) { - m_previous->m_next.release(); - m_previous->m_next.reset(this); + ///DOC: Si appelé avec un pointeur ne faisant pas partie du pool, l'opérateur delete est utilisé + if (ptr) + { + // Le pointeur nous appartient-il ? + UInt8* freePtr = static_cast(ptr); + UInt8* poolPtr = m_pool.get(); + if (freePtr >= poolPtr && freePtr < poolPtr + m_blockSize*m_size) + { + #if NAZARA_CORE_SAFE + if ((freePtr - poolPtr) % m_blockSize != 0) + throw std::runtime_error("Invalid pointer (does not point to an element of the pool)"); + #endif + + m_freeList[m_freeCount++] = ptr; + + // Si nous sommes vide et l'extension d'un autre pool, nous nous suicidons + if (m_freeCount == m_size && m_previous && !m_next) + { + m_previous->m_next.release(); + delete this; // Suicide + } + } + else + { + if (m_next) + m_next->Free(ptr); + else + OperatorDelete(ptr); + } + } } - return *this; + inline unsigned int MemoryPool::GetBlockSize() const + { + return m_blockSize; + } + + inline unsigned int MemoryPool::GetFreeBlocks() const + { + return m_freeCount; + } + + inline unsigned int MemoryPool::GetSize() const + { + return m_size; + } + + template + inline T* MemoryPool::New(Args&&... args) + { + ///DOC: Permet de construire un objet directement dans le pook + T* object = static_cast(Allocate(sizeof(T))); + PlacementNew(object, std::forward(args)...); + + return object; + } + + inline MemoryPool& MemoryPool::operator=(MemoryPool&& pool) noexcept + { + m_blockSize = pool.m_blockSize; + m_canGrow = pool.m_canGrow; + m_freeCount = pool.m_freeCount.load(std::memory_order_relaxed); + m_freeList = std::move(pool.m_freeList); + m_pool = std::move(pool.m_pool); + m_previous = pool.m_previous; + m_next = std::move(pool.m_next); + m_size = pool.m_size; + + // Si nous avons été créés par un autre pool, nous devons le faire pointer vers nous de nouveau + if (m_previous) + { + m_previous->m_next.release(); + m_previous->m_next.reset(this); + } + + return *this; + } } #include diff --git a/include/Nazara/Core/MemoryStream.hpp b/include/Nazara/Core/MemoryStream.hpp index 20ca52997..a6cf6ea70 100644 --- a/include/Nazara/Core/MemoryStream.hpp +++ b/include/Nazara/Core/MemoryStream.hpp @@ -10,30 +10,33 @@ #include #include -class NAZARA_CORE_API NzMemoryStream : public NzInputStream +namespace Nz { - public: - NzMemoryStream(const void* ptr, nzUInt64 size); - NzMemoryStream(const NzMemoryStream&) = delete; - NzMemoryStream(NzMemoryStream&&) = delete; ///TODO - ~NzMemoryStream(); + class NAZARA_CORE_API MemoryStream : public InputStream + { + public: + MemoryStream(const void* ptr, UInt64 size); + MemoryStream(const MemoryStream&) = delete; + MemoryStream(MemoryStream&&) = delete; ///TODO + ~MemoryStream(); - bool EndOfStream() const; + bool EndOfStream() const; - nzUInt64 GetCursorPos() const; - nzUInt64 GetSize() const; + UInt64 GetCursorPos() const; + UInt64 GetSize() const; - std::size_t Read(void* buffer, std::size_t size); + std::size_t Read(void* buffer, std::size_t size); - bool SetCursorPos(nzUInt64 offset); + bool SetCursorPos(UInt64 offset); - NzMemoryStream& operator=(const NzMemoryStream&) = delete; - NzMemoryStream& operator=(NzMemoryStream&&) = delete; ///TODO + MemoryStream& operator=(const MemoryStream&) = delete; + MemoryStream& operator=(MemoryStream&&) = delete; ///TODO - private: - const nzUInt8* m_ptr; - nzUInt64 m_pos; - nzUInt64 m_size; -}; + private: + const UInt8* m_ptr; + UInt64 m_pos; + UInt64 m_size; + }; +} #endif // NAZARA_MEMORYSTREAM_HPP diff --git a/include/Nazara/Core/Mutex.hpp b/include/Nazara/Core/Mutex.hpp index 0b73bb268..e49de7512 100644 --- a/include/Nazara/Core/Mutex.hpp +++ b/include/Nazara/Core/Mutex.hpp @@ -9,27 +9,30 @@ #include -class NzMutexImpl; - -class NAZARA_CORE_API NzMutex +namespace Nz { - friend class NzConditionVariable; + class MutexImpl; - public: - NzMutex(); - NzMutex(const NzMutex&) = delete; - NzMutex(NzMutex&&) = delete; ///TODO - ~NzMutex(); + class NAZARA_CORE_API Mutex + { + friend class ConditionVariable; - void Lock(); - bool TryLock(); - void Unlock(); + public: + Mutex(); + Mutex(const Mutex&) = delete; + Mutex(Mutex&&) = delete; ///TODO + ~Mutex(); - NzMutex& operator=(const NzMutex&) = delete; - NzMutex& operator=(NzMutex&&) = delete; ///TODO + void Lock(); + bool TryLock(); + void Unlock(); - private: - NzMutexImpl* m_impl; -}; + Mutex& operator=(const Mutex&) = delete; + Mutex& operator=(Mutex&&) = delete; ///TODO + + private: + MutexImpl* m_impl; + }; +} #endif // NAZARA_MUTEX_HPP diff --git a/include/Nazara/Core/ObjectLibrary.hpp b/include/Nazara/Core/ObjectLibrary.hpp index fca255b01..ee0a40e29 100644 --- a/include/Nazara/Core/ObjectLibrary.hpp +++ b/include/Nazara/Core/ObjectLibrary.hpp @@ -12,28 +12,31 @@ #include #include -template -class NzObjectLibrary +namespace Nz { - friend Type; + template + class ObjectLibrary + { + friend Type; - public: - NzObjectLibrary() = delete; - ~NzObjectLibrary() = delete; + public: + ObjectLibrary() = delete; + ~ObjectLibrary() = delete; - static NzObjectRef Get(const NzString& name); - static bool Has(const NzString& name); + static ObjectRef Get(const String& name); + static bool Has(const String& name); - static void Register(const NzString& name, NzObjectRef object); - static NzObjectRef Query(const NzString& name); - static void Unregister(const NzString& name); + static void Register(const String& name, ObjectRef object); + static ObjectRef Query(const String& name); + static void Unregister(const String& name); - private: - static bool Initialize(); - static void Uninitialize(); + private: + static bool Initialize(); + static void Uninitialize(); - using LibraryMap = std::unordered_map>; -}; + using LibraryMap = std::unordered_map>; + }; +} #include diff --git a/include/Nazara/Core/ObjectLibrary.inl b/include/Nazara/Core/ObjectLibrary.inl index 15ed62ffc..998adece4 100644 --- a/include/Nazara/Core/ObjectLibrary.inl +++ b/include/Nazara/Core/ObjectLibrary.inl @@ -5,54 +5,57 @@ #include #include -template -NzObjectRef NzObjectLibrary::Get(const NzString& name) +namespace Nz { - NzObjectRef ref = Query(name); - if (!ref) - NazaraError("Object \"" + name + "\" is not present"); + template + ObjectRef ObjectLibrary::Get(const String& name) + { + ObjectRef ref = Query(name); + if (!ref) + NazaraError("Object \"" + name + "\" is not present"); - return ref; -} + return ref; + } -template -bool NzObjectLibrary::Has(const NzString& name) -{ - return Type::s_library.find(name) != Type::s_library.end(); -} + template + bool ObjectLibrary::Has(const String& name) + { + return Type::s_library.find(name) != Type::s_library.end(); + } -template -void NzObjectLibrary::Register(const NzString& name, NzObjectRef object) -{ - Type::s_library.emplace(name, object); -} + template + void ObjectLibrary::Register(const String& name, ObjectRef object) + { + Type::s_library.emplace(name, object); + } -template -NzObjectRef NzObjectLibrary::Query(const NzString& name) -{ - auto it = Type::s_library.find(name); - if (it != Type::s_library.end()) - return it->second; - else - return nullptr; -} + template + ObjectRef ObjectLibrary::Query(const String& name) + { + auto it = Type::s_library.find(name); + if (it != Type::s_library.end()) + return it->second; + else + return nullptr; + } -template -void NzObjectLibrary::Unregister(const NzString& name) -{ - Type::s_library.erase(name); -} + template + void ObjectLibrary::Unregister(const String& name) + { + Type::s_library.erase(name); + } -template -bool NzObjectLibrary::Initialize() -{ - return true; // Que faire -} + template + bool ObjectLibrary::Initialize() + { + return true; // Que faire + } -template -void NzObjectLibrary::Uninitialize() -{ - Type::s_library.clear(); + template + void ObjectLibrary::Uninitialize() + { + Type::s_library.clear(); + } } #include diff --git a/include/Nazara/Core/ObjectRef.hpp b/include/Nazara/Core/ObjectRef.hpp index 35d016f90..0c82b3abc 100644 --- a/include/Nazara/Core/ObjectRef.hpp +++ b/include/Nazara/Core/ObjectRef.hpp @@ -11,37 +11,40 @@ #include #include -template -class NzObjectRef +namespace Nz { - static_assert(std::is_base_of::value, "ObjectRef shall only be used with RefCounted-derived type"); + template + class ObjectRef + { + static_assert(std::is_base_of::value, "ObjectRef shall only be used with RefCounted-derived type"); - public: - NzObjectRef(); - NzObjectRef(T* object); - NzObjectRef(const NzObjectRef& ref); - template NzObjectRef(const NzObjectRef& ref); - NzObjectRef(NzObjectRef&& ref) noexcept; - ~NzObjectRef(); + public: + ObjectRef(); + ObjectRef(T* object); + ObjectRef(const ObjectRef& ref); + template ObjectRef(const ObjectRef& ref); + ObjectRef(ObjectRef&& ref) noexcept; + ~ObjectRef(); - T* Get() const; - bool IsValid() const; - T* Release(); - bool Reset(T* object = nullptr); - NzObjectRef& Swap(NzObjectRef& ref); + T* Get() const; + bool IsValid() const; + T* Release(); + bool Reset(T* object = nullptr); + ObjectRef& Swap(ObjectRef& ref); - operator bool() const; - operator T*() const; - T* operator->() const; + operator bool() const; + operator T*() const; + T* operator->() const; - NzObjectRef& operator=(T* object); - NzObjectRef& operator=(const NzObjectRef& ref); - template NzObjectRef& operator=(const NzObjectRef& ref); - NzObjectRef& operator=(NzObjectRef&& ref) noexcept; + ObjectRef& operator=(T* object); + ObjectRef& operator=(const ObjectRef& ref); + template ObjectRef& operator=(const ObjectRef& ref); + ObjectRef& operator=(ObjectRef&& ref) noexcept; - private: - T* m_object; -}; + private: + T* m_object; + }; +} #include diff --git a/include/Nazara/Core/ObjectRef.inl b/include/Nazara/Core/ObjectRef.inl index ec01ffc38..2e933bdf0 100644 --- a/include/Nazara/Core/ObjectRef.inl +++ b/include/Nazara/Core/ObjectRef.inl @@ -5,148 +5,151 @@ #include #include -template -NzObjectRef::NzObjectRef() : -m_object(nullptr) +namespace Nz { -} - -template -NzObjectRef::NzObjectRef(T* object) : -m_object(object) -{ - if (m_object) - m_object->AddReference(); -} - -template -NzObjectRef::NzObjectRef(const NzObjectRef& ref) : -m_object(ref.m_object) -{ - if (m_object) - m_object->AddReference(); -} - -template -template -NzObjectRef::NzObjectRef(const NzObjectRef& ref) : -NzObjectRef(ref.Get()) -{ -} - -template -NzObjectRef::NzObjectRef(NzObjectRef&& ref) noexcept : -m_object(ref.m_object) -{ - ref.m_object = nullptr; // On vole la référence -} - -template -NzObjectRef::~NzObjectRef() -{ - if (m_object) - m_object->RemoveReference(); -} - -template -T* NzObjectRef::Get() const -{ - return m_object; -} - -template -bool NzObjectRef::IsValid() const -{ - return m_object != nullptr; -} - -template -T* NzObjectRef::Release() -{ - T* object = m_object; - m_object = nullptr; - - return object; -} - -template -bool NzObjectRef::Reset(T* object) -{ - bool destroyed = false; - if (m_object != object) + template + ObjectRef::ObjectRef() : + m_object(nullptr) { - if (m_object) - destroyed = m_object->RemoveReference(); + } - m_object = object; + template + ObjectRef::ObjectRef(T* object) : + m_object(object) + { if (m_object) m_object->AddReference(); } - return destroyed; -} + template + ObjectRef::ObjectRef(const ObjectRef& ref) : + m_object(ref.m_object) + { + if (m_object) + m_object->AddReference(); + } -template -NzObjectRef& NzObjectRef::Swap(NzObjectRef& ref) -{ - std::swap(m_object, ref.m_object); + template + template + ObjectRef::ObjectRef(const ObjectRef& ref) : + ObjectRef(ref.Get()) + { + } - return *this; -} + template + ObjectRef::ObjectRef(ObjectRef&& ref) noexcept : + m_object(ref.m_object) + { + ref.m_object = nullptr; // On vole la référence + } -template -NzObjectRef::operator bool() const -{ - return IsValid(); -} + template + ObjectRef::~ObjectRef() + { + if (m_object) + m_object->RemoveReference(); + } -template -NzObjectRef::operator T*() const -{ - return m_object; -} + template + T* ObjectRef::Get() const + { + return m_object; + } -template -T* NzObjectRef::operator->() const -{ - return m_object; -} + template + bool ObjectRef::IsValid() const + { + return m_object != nullptr; + } -template -NzObjectRef& NzObjectRef::operator=(T* object) -{ - Reset(object); + template + T* ObjectRef::Release() + { + T* object = m_object; + m_object = nullptr; - return *this; -} + return object; + } -template -NzObjectRef& NzObjectRef::operator=(const NzObjectRef& ref) -{ - Reset(ref.m_object); + template + bool ObjectRef::Reset(T* object) + { + bool destroyed = false; + if (m_object != object) + { + if (m_object) + destroyed = m_object->RemoveReference(); - return *this; -} + m_object = object; + if (m_object) + m_object->AddReference(); + } -template -template -NzObjectRef& NzObjectRef::operator=(const NzObjectRef& ref) -{ - static_assert(std::is_convertible::value, "U is not implicitly convertible to T"); + return destroyed; + } - Reset(ref.Get()); + template + ObjectRef& ObjectRef::Swap(ObjectRef& ref) + { + std::swap(m_object, ref.m_object); - return *this; -} + return *this; + } -template -NzObjectRef& NzObjectRef::operator=(NzObjectRef&& ref) noexcept -{ - Reset(); + template + ObjectRef::operator bool() const + { + return IsValid(); + } - std::swap(m_object, ref.m_object); + template + ObjectRef::operator T*() const + { + return m_object; + } - return *this; + template + T* ObjectRef::operator->() const + { + return m_object; + } + + template + ObjectRef& ObjectRef::operator=(T* object) + { + Reset(object); + + return *this; + } + + template + ObjectRef& ObjectRef::operator=(const ObjectRef& ref) + { + Reset(ref.m_object); + + return *this; + } + + template + template + ObjectRef& ObjectRef::operator=(const ObjectRef& ref) + { + static_assert(std::is_convertible::value, "U is not implicitly convertible to T"); + + Reset(ref.Get()); + + return *this; + } + + template + ObjectRef& ObjectRef::operator=(ObjectRef&& ref) noexcept + { + Reset(); + + std::swap(m_object, ref.m_object); + + return *this; + } } #include diff --git a/include/Nazara/Core/OffsetOf.hpp b/include/Nazara/Core/OffsetOf.hpp index 4f13abacf..7b97a44e2 100644 --- a/include/Nazara/Core/OffsetOf.hpp +++ b/include/Nazara/Core/OffsetOf.hpp @@ -10,15 +10,21 @@ // Par "Jesse Good" de SO: // http://stackoverflow.com/questions/12811330/c-compile-time-offsetof-inside-a-template?answertab=votes#tab-top -template T NzImplGetClassType(M T::*); -template M NzImplGetMemberType(M T::*); - -template -constexpr std::size_t NzImplOffsetOf() +namespace Nz { - return reinterpret_cast(&((static_cast(0))->*M)); + namespace Detail + { + template T GetClassType(M T::*); + template M GetMemberType(M T::*); + + template + constexpr std::size_t OffsetOf() + { + return reinterpret_cast(&((static_cast(0))->*M)); + } + } } -#define NzOffsetOf(type, member) NzImplOffsetOf() +#define NazaraOffsetOf(type, member) Nz::Detail::OffsetOf() #endif // NAZARA_OFFSETOF_HPP diff --git a/include/Nazara/Core/ParameterList.hpp b/include/Nazara/Core/ParameterList.hpp index 9f3326fbe..bd4b01b58 100644 --- a/include/Nazara/Core/ParameterList.hpp +++ b/include/Nazara/Core/ParameterList.hpp @@ -12,83 +12,86 @@ #include #include -class NAZARA_CORE_API NzParameterList +namespace Nz { - public: - using Destructor = void (*)(void* value); + class NAZARA_CORE_API ParameterList + { + public: + using Destructor = void (*)(void* value); - NzParameterList() = default; - NzParameterList(const NzParameterList& list); - NzParameterList(NzParameterList&&) = default; - ~NzParameterList(); + ParameterList() = default; + ParameterList(const ParameterList& list); + ParameterList(ParameterList&&) = default; + ~ParameterList(); - void Clear(); + void Clear(); - bool GetBooleanParameter(const NzString& name, bool* value) const; - bool GetFloatParameter(const NzString& name, float* value) const; - bool GetIntegerParameter(const NzString& name, int* value) const; - bool GetParameterType(const NzString& name, nzParameterType* type) const; - bool GetPointerParameter(const NzString& name, void** value) const; - bool GetStringParameter(const NzString& name, NzString* value) const; - bool GetUserdataParameter(const NzString& name, void** value) const; + bool GetBooleanParameter(const String& name, bool* value) const; + bool GetFloatParameter(const String& name, float* value) const; + bool GetIntegerParameter(const String& name, int* value) const; + bool GetParameterType(const String& name, ParameterType* type) const; + bool GetPointerParameter(const String& name, void** value) const; + bool GetStringParameter(const String& name, String* value) const; + bool GetUserdataParameter(const String& name, void** value) const; - bool HasParameter(const NzString& name) const; + bool HasParameter(const String& name) const; - void RemoveParameter(const NzString& name); + void RemoveParameter(const String& name); - void SetParameter(const NzString& name); - void SetParameter(const NzString& name, const NzString& value); - void SetParameter(const NzString& name, const char* value); - void SetParameter(const NzString& name, void* value); - void SetParameter(const NzString& name, void* value, Destructor destructor); - void SetParameter(const NzString& name, bool value); - void SetParameter(const NzString& name, float value); - void SetParameter(const NzString& name, int value); + void SetParameter(const String& name); + void SetParameter(const String& name, const String& value); + void SetParameter(const String& name, const char* value); + void SetParameter(const String& name, void* value); + void SetParameter(const String& name, void* value, Destructor destructor); + void SetParameter(const String& name, bool value); + void SetParameter(const String& name, float value); + void SetParameter(const String& name, int value); - NzParameterList& operator=(const NzParameterList& list); - NzParameterList& operator=(NzParameterList&&) = default; + ParameterList& operator=(const ParameterList& list); + ParameterList& operator=(ParameterList&&) = default; - private: - struct Parameter - { - struct UserdataValue + private: + struct Parameter { - UserdataValue(Destructor Destructor, void* value) : - counter(1), - destructor(Destructor), - ptr(value) + struct UserdataValue { - } + UserdataValue(Destructor Destructor, void* value) : + counter(1), + destructor(Destructor), + ptr(value) + { + } - std::atomic_uint counter; - Destructor destructor; - void* ptr; + std::atomic_uint counter; + Destructor destructor; + void* ptr; + }; + + ParameterType type; + union Value + { + // On définit un constructeur/destructeur vide, permettant de mettre des classes dans l'union + Value() {} + Value(const Value&) {} // Placeholder + ~Value() {} + + bool boolVal; + float floatVal; + int intVal; + void* ptrVal; + String stringVal; + UserdataValue* userdataVal; + }; + + Value value; }; - nzParameterType type; - union Value - { - // On définit un constructeur/destructeur vide, permettant de mettre des classes dans l'union - Value() {} - Value(const Value&) {} // Placeholder - ~Value() {} + using ParameterMap = std::unordered_map; - bool boolVal; - float floatVal; - int intVal; - void* ptrVal; - NzString stringVal; - UserdataValue* userdataVal; - }; + void DestroyValue(Parameter& parameter); - Value value; - }; - - using ParameterMap = std::unordered_map; - - void DestroyValue(Parameter& parameter); - - ParameterMap m_parameters; -}; + ParameterMap m_parameters; + }; +} #endif // NAZARA_PARAMETERLIST_HPP diff --git a/include/Nazara/Core/PluginManager.hpp b/include/Nazara/Core/PluginManager.hpp index abd1b31e8..b2b20ffde 100644 --- a/include/Nazara/Core/PluginManager.hpp +++ b/include/Nazara/Core/PluginManager.hpp @@ -14,34 +14,35 @@ #include ///TODO: Révision - -class NzDynLib; - -class NAZARA_CORE_API NzPluginManager +namespace Nz { - public: - NzPluginManager() = delete; - ~NzPluginManager() = delete; + class DynLib; - static void AddDirectory(const NzString& directoryPath); + class NAZARA_CORE_API PluginManager + { + public: + PluginManager() = delete; + ~PluginManager() = delete; - static bool Initialize(); + static void AddDirectory(const String& directoryPath); - static bool Mount(nzPlugin plugin); - static bool Mount(const NzString& pluginPath, bool appendExtension = true); + static bool Initialize(); - static void RemoveDirectory(const NzString& directoryPath); + static bool Mount(Plugin plugin); + static bool Mount(const String& pluginPath, bool appendExtension = true); - static void Unmount(nzPlugin plugin); - static void Unmount(const NzString& pluginPath); + static void RemoveDirectory(const String& directoryPath); - static void Uninitialize(); + static void Unmount(Plugin plugin); + static void Unmount(const String& pluginPath); - private: - static std::set s_directories; - static std::unordered_map s_plugins; - static bool s_initialized; + static void Uninitialize(); -}; + private: + static std::set s_directories; + static std::unordered_map s_plugins; + static bool s_initialized; + }; +} #endif // NAZARA_PLUGINMANAGER_HPP diff --git a/include/Nazara/Core/Primitive.hpp b/include/Nazara/Core/Primitive.hpp index 655a8fdab..16c27100d 100644 --- a/include/Nazara/Core/Primitive.hpp +++ b/include/Nazara/Core/Primitive.hpp @@ -14,94 +14,97 @@ #include #include -struct NzPrimitive +namespace Nz { - void MakeBox(const NzVector3f& lengths, const NzVector3ui& subdivision = NzVector3ui(0U), const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - void MakeBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - void MakeCone(float length, float radius, unsigned int subdivision = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - void MakeCone(float length, float radius, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - void MakeCubicSphere(float size, unsigned int subdivision = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - void MakeCubicSphere(float size, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - void MakeIcoSphere(float size, unsigned int recursionLevel = 3, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - void MakeIcoSphere(float size, unsigned int recursionLevel, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - void MakePlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - void MakePlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzPlanef& plane, const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - void MakePlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - void MakeUVSphere(float size, unsigned int sliceCount = 4, unsigned int stackCount = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - void MakeUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - - static NzPrimitive Box(const NzVector3f& lengths, const NzVector3ui& subdivision = NzVector3ui(0U), const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - static NzPrimitive Box(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - static NzPrimitive Cone(float length, float radius, unsigned int subdivision = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - static NzPrimitive Cone(float length, float radius, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - static NzPrimitive CubicSphere(float size, unsigned int subdivision = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - static NzPrimitive CubicSphere(float size, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - static NzPrimitive IcoSphere(float size, unsigned int recursionLevel = 3, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - static NzPrimitive IcoSphere(float size, unsigned int recursionLevel, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - static NzPrimitive Plane(const NzVector2f& size, const NzVector2ui& subdivision = NzVector2ui(0U), const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - static NzPrimitive Plane(const NzVector2f& size, const NzVector2ui& subdivision, const NzPlanef& plane, const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - static NzPrimitive Plane(const NzVector2f& size, const NzVector2ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - static NzPrimitive UVSphere(float size, unsigned int sliceCount = 4, unsigned int stackCount = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - static NzPrimitive UVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity(), const NzRectf& uvCoords = NzRectf(0.f, 0.f, 1.f, 1.f)); - - NzMatrix4f matrix; - nzPrimitiveType type; - NzRectf textureCoords; - - union + struct Primitive { - struct - { - NzVector3f lengths; - NzVector3ui subdivision; - } - box; + void MakeBox(const Vector3f& lengths, const Vector3ui& subdivision = Vector3ui(0U), const Matrix4f& transformMatrix = Matrix4f::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + void MakeBox(const Vector3f& lengths, const Vector3ui& subdivision, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + void MakeCone(float length, float radius, unsigned int subdivision = 4, const Matrix4f& transformMatrix = Matrix4f::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + void MakeCone(float length, float radius, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + void MakeCubicSphere(float size, unsigned int subdivision = 4, const Matrix4f& transformMatrix = Matrix4f::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + void MakeCubicSphere(float size, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + void MakeIcoSphere(float size, unsigned int recursionLevel = 3, const Matrix4f& transformMatrix = Matrix4f::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + void MakeIcoSphere(float size, unsigned int recursionLevel, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + void MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Matrix4f& transformMatrix = Matrix4f::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + void MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Planef& plane, const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + void MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + void MakeUVSphere(float size, unsigned int sliceCount = 4, unsigned int stackCount = 4, const Matrix4f& transformMatrix = Matrix4f::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + void MakeUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); - struct - { - float length; - float radius; - unsigned int subdivision; - } - cone; + static Primitive Box(const Vector3f& lengths, const Vector3ui& subdivision = Vector3ui(0U), const Matrix4f& transformMatrix = Matrix4f::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + static Primitive Box(const Vector3f& lengths, const Vector3ui& subdivision, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + static Primitive Cone(float length, float radius, unsigned int subdivision = 4, const Matrix4f& transformMatrix = Matrix4f::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + static Primitive Cone(float length, float radius, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + static Primitive CubicSphere(float size, unsigned int subdivision = 4, const Matrix4f& transformMatrix = Matrix4f::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + static Primitive CubicSphere(float size, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + static Primitive IcoSphere(float size, unsigned int recursionLevel = 3, const Matrix4f& transformMatrix = Matrix4f::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + static Primitive IcoSphere(float size, unsigned int recursionLevel, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + static Primitive Plane(const Vector2f& size, const Vector2ui& subdivision = Vector2ui(0U), const Matrix4f& transformMatrix = Matrix4f::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + static Primitive Plane(const Vector2f& size, const Vector2ui& subdivision, const Planef& plane, const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + static Primitive Plane(const Vector2f& size, const Vector2ui& subdivision, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + static Primitive UVSphere(float size, unsigned int sliceCount = 4, unsigned int stackCount = 4, const Matrix4f& transformMatrix = Matrix4f::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); + static Primitive UVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity(), const Rectf& uvCoords = Rectf(0.f, 0.f, 1.f, 1.f)); - struct - { - NzVector2f size; - NzVector2ui subdivision; - } - plane; + Matrix4f matrix; + PrimitiveType type; + Rectf textureCoords; - struct + union { - nzSphereType type; - float size; - - union + struct { - struct - { - unsigned int subdivision; - } - cubic; + Vector3f lengths; + Vector3ui subdivision; + } + box; - struct - { - unsigned int recursionLevel; - } - ico; + struct + { + float length; + float radius; + unsigned int subdivision; + } + cone; - struct + struct + { + Vector2f size; + Vector2ui subdivision; + } + plane; + + struct + { + SphereType type; + float size; + + union { - unsigned int sliceCount; - unsigned int stackCount; - } - uv; - }; - } - sphere; + struct + { + unsigned int subdivision; + } + cubic; + + struct + { + unsigned int recursionLevel; + } + ico; + + struct + { + unsigned int sliceCount; + unsigned int stackCount; + } + uv; + }; + } + sphere; + }; }; -}; +} #include diff --git a/include/Nazara/Core/Primitive.inl b/include/Nazara/Core/Primitive.inl index b27031f56..ce458739d 100644 --- a/include/Nazara/Core/Primitive.inl +++ b/include/Nazara/Core/Primitive.inl @@ -4,202 +4,205 @@ #include -inline void NzPrimitive::MakeBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) +namespace Nz { - matrix = transformMatrix; - textureCoords = uvCoords; - type = nzPrimitiveType_Box; - box.lengths = lengths; - box.subdivision = subdivision; -} + inline void Primitive::MakeBox(const Vector3f& lengths, const Vector3ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) + { + matrix = transformMatrix; + textureCoords = uvCoords; + type = PrimitiveType_Box; + box.lengths = lengths; + box.subdivision = subdivision; + } -inline void NzPrimitive::MakeBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation, const NzRectf& uvCoords) -{ - MakeBox(lengths, subdivision, NzMatrix4f::Transform(position, rotation), uvCoords); -} + inline void Primitive::MakeBox(const Vector3f& lengths, const Vector3ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) + { + MakeBox(lengths, subdivision, Matrix4f::Transform(position, rotation), uvCoords); + } -inline void NzPrimitive::MakeCone(float length, float radius, unsigned int subdivision, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) -{ - matrix = transformMatrix; - textureCoords = uvCoords; - type = nzPrimitiveType_Cone; - cone.length = length; - cone.radius = radius; - cone.subdivision = subdivision; -} + inline void Primitive::MakeCone(float length, float radius, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) + { + matrix = transformMatrix; + textureCoords = uvCoords; + type = PrimitiveType_Cone; + cone.length = length; + cone.radius = radius; + cone.subdivision = subdivision; + } -inline void NzPrimitive::MakeCone(float length, float radius, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation, const NzRectf& uvCoords) -{ - MakeCone(length, radius, subdivision, NzMatrix4f::Transform(position, rotation), uvCoords); -} + inline void Primitive::MakeCone(float length, float radius, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) + { + MakeCone(length, radius, subdivision, Matrix4f::Transform(position, rotation), uvCoords); + } -inline void NzPrimitive::MakeCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) -{ - matrix = transformMatrix; - textureCoords = uvCoords; - type = nzPrimitiveType_Sphere; - sphere.size = size; - sphere.type = nzSphereType_Cubic; - sphere.cubic.subdivision = subdivision; -} + inline void Primitive::MakeCubicSphere(float size, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) + { + matrix = transformMatrix; + textureCoords = uvCoords; + type = PrimitiveType_Sphere; + sphere.size = size; + sphere.type = SphereType_Cubic; + sphere.cubic.subdivision = subdivision; + } -inline void NzPrimitive::MakeCubicSphere(float size, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation, const NzRectf& uvCoords) -{ - MakeCubicSphere(size, subdivision, NzMatrix4f::Transform(position, rotation), uvCoords); -} + inline void Primitive::MakeCubicSphere(float size, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) + { + MakeCubicSphere(size, subdivision, Matrix4f::Transform(position, rotation), uvCoords); + } -inline void NzPrimitive::MakeIcoSphere(float size, unsigned int recursionLevel, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) -{ - matrix = transformMatrix; - textureCoords = uvCoords; - type = nzPrimitiveType_Sphere; - sphere.size = size; - sphere.type = nzSphereType_Ico; - sphere.ico.recursionLevel = recursionLevel; -} + inline void Primitive::MakeIcoSphere(float size, unsigned int recursionLevel, const Matrix4f& transformMatrix, const Rectf& uvCoords) + { + matrix = transformMatrix; + textureCoords = uvCoords; + type = PrimitiveType_Sphere; + sphere.size = size; + sphere.type = SphereType_Ico; + sphere.ico.recursionLevel = recursionLevel; + } -inline void NzPrimitive::MakeIcoSphere(float size, unsigned int recursionLevel, const NzVector3f& position, const NzQuaternionf& rotation, const NzRectf& uvCoords) -{ - MakeIcoSphere(size, recursionLevel, NzMatrix4f::Transform(position, rotation), uvCoords); -} + inline void Primitive::MakeIcoSphere(float size, unsigned int recursionLevel, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) + { + MakeIcoSphere(size, recursionLevel, Matrix4f::Transform(position, rotation), uvCoords); + } -inline void NzPrimitive::MakePlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) -{ - matrix = transformMatrix; - textureCoords = uvCoords; - type = nzPrimitiveType_Plane; - plane.size = size; - plane.subdivision = subdivision; -} + inline void Primitive::MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) + { + matrix = transformMatrix; + textureCoords = uvCoords; + type = PrimitiveType_Plane; + plane.size = size; + plane.subdivision = subdivision; + } -inline void NzPrimitive::MakePlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzPlanef& planeInfo, const NzRectf& uvCoords) -{ - MakePlane(size, subdivision, NzMatrix4f::Transform(planeInfo.distance * planeInfo.normal, NzQuaternionf::RotationBetween(NzVector3f::Up(), planeInfo.normal)), uvCoords); -} + inline void Primitive::MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Planef& planeInfo, const Rectf& uvCoords) + { + MakePlane(size, subdivision, Matrix4f::Transform(planeInfo.distance * planeInfo.normal, Quaternionf::RotationBetween(Vector3f::Up(), planeInfo.normal)), uvCoords); + } -inline void NzPrimitive::MakePlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation, const NzRectf& uvCoords) -{ - MakePlane(size, subdivision, NzMatrix4f::Transform(position, rotation), uvCoords); -} + inline void Primitive::MakePlane(const Vector2f& size, const Vector2ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) + { + MakePlane(size, subdivision, Matrix4f::Transform(position, rotation), uvCoords); + } -inline void NzPrimitive::MakeUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) -{ - matrix = transformMatrix; - textureCoords = uvCoords; - type = nzPrimitiveType_Sphere; - sphere.size = size; - sphere.type = nzSphereType_UV; - sphere.uv.sliceCount = sliceCount; - sphere.uv.stackCount = stackCount; -} + inline void Primitive::MakeUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Matrix4f& transformMatrix, const Rectf& uvCoords) + { + matrix = transformMatrix; + textureCoords = uvCoords; + type = PrimitiveType_Sphere; + sphere.size = size; + sphere.type = SphereType_UV; + sphere.uv.sliceCount = sliceCount; + sphere.uv.stackCount = stackCount; + } -inline void NzPrimitive::MakeUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzVector3f& position, const NzQuaternionf& rotation, const NzRectf& uvCoords) -{ - MakeUVSphere(size, sliceCount, stackCount, NzMatrix4f::Transform(position, rotation), uvCoords); -} + inline void Primitive::MakeUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) + { + MakeUVSphere(size, sliceCount, stackCount, Matrix4f::Transform(position, rotation), uvCoords); + } -inline NzPrimitive NzPrimitive::Box(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) -{ - NzPrimitive primitive; - primitive.MakeBox(lengths, subdivision, transformMatrix, uvCoords); + inline Primitive Primitive::Box(const Vector3f& lengths, const Vector3ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) + { + Primitive primitive; + primitive.MakeBox(lengths, subdivision, transformMatrix, uvCoords); - return primitive; -} + return primitive; + } -inline NzPrimitive NzPrimitive::Box(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation, const NzRectf& uvCoords) -{ - NzPrimitive primitive; - primitive.MakeBox(lengths, subdivision, position, rotation, uvCoords); + inline Primitive Primitive::Box(const Vector3f& lengths, const Vector3ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) + { + Primitive primitive; + primitive.MakeBox(lengths, subdivision, position, rotation, uvCoords); - return primitive; -} + return primitive; + } -inline NzPrimitive NzPrimitive::Cone(float length, float radius, unsigned int subdivision, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) -{ - NzPrimitive primitive; - primitive.MakeCone(length, radius, subdivision, transformMatrix, uvCoords); + inline Primitive Primitive::Cone(float length, float radius, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) + { + Primitive primitive; + primitive.MakeCone(length, radius, subdivision, transformMatrix, uvCoords); - return primitive; -} + return primitive; + } -inline NzPrimitive NzPrimitive::Cone(float length, float radius, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation, const NzRectf& uvCoords) -{ - NzPrimitive primitive; - primitive.MakeCone(length, radius, subdivision, position, rotation, uvCoords); + inline Primitive Primitive::Cone(float length, float radius, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) + { + Primitive primitive; + primitive.MakeCone(length, radius, subdivision, position, rotation, uvCoords); - return primitive; -} + return primitive; + } -inline NzPrimitive NzPrimitive::CubicSphere(float size, unsigned int subdivision, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) -{ - NzPrimitive primitive; - primitive.MakeCubicSphere(size, subdivision, transformMatrix, uvCoords); + inline Primitive Primitive::CubicSphere(float size, unsigned int subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) + { + Primitive primitive; + primitive.MakeCubicSphere(size, subdivision, transformMatrix, uvCoords); - return primitive; -} + return primitive; + } -inline NzPrimitive NzPrimitive::CubicSphere(float size, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation, const NzRectf& uvCoords) -{ - NzPrimitive primitive; - primitive.MakeCubicSphere(size, subdivision, position, rotation, uvCoords); + inline Primitive Primitive::CubicSphere(float size, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) + { + Primitive primitive; + primitive.MakeCubicSphere(size, subdivision, position, rotation, uvCoords); - return primitive; -} + return primitive; + } -inline NzPrimitive NzPrimitive::IcoSphere(float size, unsigned int recursionLevel, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) -{ - NzPrimitive primitive; - primitive.MakeIcoSphere(size, recursionLevel, transformMatrix, uvCoords); + inline Primitive Primitive::IcoSphere(float size, unsigned int recursionLevel, const Matrix4f& transformMatrix, const Rectf& uvCoords) + { + Primitive primitive; + primitive.MakeIcoSphere(size, recursionLevel, transformMatrix, uvCoords); - return primitive; -} + return primitive; + } -inline NzPrimitive NzPrimitive::IcoSphere(float size, unsigned int recursionLevel, const NzVector3f& position, const NzQuaternionf& rotation, const NzRectf& uvCoords) -{ - NzPrimitive primitive; - primitive.MakeIcoSphere(size, recursionLevel, position, rotation, uvCoords); + inline Primitive Primitive::IcoSphere(float size, unsigned int recursionLevel, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) + { + Primitive primitive; + primitive.MakeIcoSphere(size, recursionLevel, position, rotation, uvCoords); - return primitive; -} + return primitive; + } -inline NzPrimitive NzPrimitive::Plane(const NzVector2f& size, const NzVector2ui& subdivision, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) -{ - NzPrimitive primitive; - primitive.MakePlane(size, subdivision, transformMatrix, uvCoords); + inline Primitive Primitive::Plane(const Vector2f& size, const Vector2ui& subdivision, const Matrix4f& transformMatrix, const Rectf& uvCoords) + { + Primitive primitive; + primitive.MakePlane(size, subdivision, transformMatrix, uvCoords); - return primitive; -} + return primitive; + } -inline NzPrimitive NzPrimitive::Plane(const NzVector2f& size, const NzVector2ui& subdivision, const NzPlanef& plane, const NzRectf& uvCoords) -{ - NzPrimitive primitive; - primitive.MakePlane(size, subdivision, plane, uvCoords); + inline Primitive Primitive::Plane(const Vector2f& size, const Vector2ui& subdivision, const Planef& plane, const Rectf& uvCoords) + { + Primitive primitive; + primitive.MakePlane(size, subdivision, plane, uvCoords); - return primitive; -} + return primitive; + } -inline NzPrimitive NzPrimitive::Plane(const NzVector2f& size, const NzVector2ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation, const NzRectf& uvCoords) -{ - NzPrimitive primitive; - primitive.MakePlane(size, subdivision, position, rotation, uvCoords); + inline Primitive Primitive::Plane(const Vector2f& size, const Vector2ui& subdivision, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) + { + Primitive primitive; + primitive.MakePlane(size, subdivision, position, rotation, uvCoords); - return primitive; -} + return primitive; + } -inline NzPrimitive NzPrimitive::UVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzMatrix4f& transformMatrix, const NzRectf& uvCoords) -{ - NzPrimitive primitive; - primitive.MakeUVSphere(size, sliceCount, stackCount, transformMatrix, uvCoords); + inline Primitive Primitive::UVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Matrix4f& transformMatrix, const Rectf& uvCoords) + { + Primitive primitive; + primitive.MakeUVSphere(size, sliceCount, stackCount, transformMatrix, uvCoords); - return primitive; -} + return primitive; + } -inline NzPrimitive NzPrimitive::UVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzVector3f& position, const NzQuaternionf& rotation, const NzRectf& uvCoords) -{ - NzPrimitive primitive; - primitive.MakeUVSphere(size, sliceCount, stackCount, position, rotation, uvCoords); + inline Primitive Primitive::UVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation, const Rectf& uvCoords) + { + Primitive primitive; + primitive.MakeUVSphere(size, sliceCount, stackCount, position, rotation, uvCoords); - return primitive; + return primitive; + } } #include diff --git a/include/Nazara/Core/PrimitiveList.hpp b/include/Nazara/Core/PrimitiveList.hpp index 5ddb6b21b..d7fe83a0c 100644 --- a/include/Nazara/Core/PrimitiveList.hpp +++ b/include/Nazara/Core/PrimitiveList.hpp @@ -11,40 +11,43 @@ #include #include -class NAZARA_CORE_API NzPrimitiveList +namespace Nz { - public: - NzPrimitiveList() = default; - NzPrimitiveList(const NzPrimitiveList&) = default; - NzPrimitiveList(NzPrimitiveList&&) = default; - ~NzPrimitiveList() = default; + class NAZARA_CORE_API PrimitiveList + { + public: + PrimitiveList() = default; + PrimitiveList(const PrimitiveList&) = default; + PrimitiveList(PrimitiveList&&) = default; + ~PrimitiveList() = default; - void AddBox(const NzVector3f& lengths, const NzVector3ui& subdivision = NzVector3ui(0U), const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - void AddBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity()); - void AddCone(float length, float radius, unsigned int subdivision = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - void AddCone(float length, float radius, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity()); - void AddCubicSphere(float size, unsigned int subdivision = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - void AddCubicSphere(float size, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity()); - void AddIcoSphere(float size, unsigned int recursionLevel = 3, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - void AddIcoSphere(float size, unsigned int recursionLevel, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity()); - void AddPlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - void AddPlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzPlanef& planeInfo); - void AddPlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity()); - void AddUVSphere(float size, unsigned int sliceCount = 4, unsigned int stackCount = 4, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - void AddUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzVector3f& position, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + void AddBox(const Vector3f& lengths, const Vector3ui& subdivision = Vector3ui(0U), const Matrix4f& transformMatrix = Matrix4f::Identity()); + void AddBox(const Vector3f& lengths, const Vector3ui& subdivision, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity()); + void AddCone(float length, float radius, unsigned int subdivision = 4, const Matrix4f& transformMatrix = Matrix4f::Identity()); + void AddCone(float length, float radius, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity()); + void AddCubicSphere(float size, unsigned int subdivision = 4, const Matrix4f& transformMatrix = Matrix4f::Identity()); + void AddCubicSphere(float size, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity()); + void AddIcoSphere(float size, unsigned int recursionLevel = 3, const Matrix4f& transformMatrix = Matrix4f::Identity()); + void AddIcoSphere(float size, unsigned int recursionLevel, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity()); + void AddPlane(const Vector2f& size, const Vector2ui& subdivision, const Matrix4f& transformMatrix = Matrix4f::Identity()); + void AddPlane(const Vector2f& size, const Vector2ui& subdivision, const Planef& planeInfo); + void AddPlane(const Vector2f& size, const Vector2ui& subdivision, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity()); + void AddUVSphere(float size, unsigned int sliceCount = 4, unsigned int stackCount = 4, const Matrix4f& transformMatrix = Matrix4f::Identity()); + void AddUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity()); - NzPrimitive& GetPrimitive(unsigned int i); - const NzPrimitive& GetPrimitive(unsigned int i) const; - unsigned int GetSize() const; + Primitive& GetPrimitive(unsigned int i); + const Primitive& GetPrimitive(unsigned int i) const; + unsigned int GetSize() const; - NzPrimitiveList& operator=(const NzPrimitiveList&) = default; - NzPrimitiveList& operator=(NzPrimitiveList&&) = default; + PrimitiveList& operator=(const PrimitiveList&) = default; + PrimitiveList& operator=(PrimitiveList&&) = default; - NzPrimitive& operator()(unsigned int i); - const NzPrimitive& operator()(unsigned int i) const; + Primitive& operator()(unsigned int i); + const Primitive& operator()(unsigned int i) const; - private: - std::vector m_primitives; -}; + private: + std::vector m_primitives; + }; +} #endif // NAZARA_PRIMITIVELIST_HPP diff --git a/include/Nazara/Core/RefCounted.hpp b/include/Nazara/Core/RefCounted.hpp index 4915a9361..542784787 100644 --- a/include/Nazara/Core/RefCounted.hpp +++ b/include/Nazara/Core/RefCounted.hpp @@ -17,30 +17,33 @@ #include #endif -class NAZARA_CORE_API NzRefCounted +namespace Nz { - public: - NzRefCounted(bool persistent = true); - NzRefCounted(const NzRefCounted&) = delete; - NzRefCounted(NzRefCounted&&) = default; - virtual ~NzRefCounted(); + class NAZARA_CORE_API RefCounted + { + public: + RefCounted(bool persistent = true); + RefCounted(const RefCounted&) = delete; + RefCounted(RefCounted&&) = default; + virtual ~RefCounted(); - void AddReference() const; + void AddReference() const; - unsigned int GetReferenceCount() const; + unsigned int GetReferenceCount() const; - bool IsPersistent() const; + bool IsPersistent() const; - bool RemoveReference() const; + bool RemoveReference() const; - bool SetPersistent(bool persistent = true, bool checkReferenceCount = false); + bool SetPersistent(bool persistent = true, bool checkReferenceCount = false); - NzRefCounted& operator=(const NzRefCounted&) = delete; - NzRefCounted& operator=(NzRefCounted&&) = default; + RefCounted& operator=(const RefCounted&) = delete; + RefCounted& operator=(RefCounted&&) = default; - private: - std::atomic_bool m_persistent; - mutable std::atomic_uint m_referenceCount; -}; + private: + std::atomic_bool m_persistent; + mutable std::atomic_uint m_referenceCount; + }; +} #endif // NAZARA_RESOURCE_HPP diff --git a/include/Nazara/Core/Resource.hpp b/include/Nazara/Core/Resource.hpp index eb852fe86..7d1a12530 100644 --- a/include/Nazara/Core/Resource.hpp +++ b/include/Nazara/Core/Resource.hpp @@ -10,23 +10,26 @@ #include #include -class NAZARA_CORE_API NzResource +namespace Nz { - public: - NzResource() = default; - NzResource(const NzResource&) = default; - NzResource(NzResource&&) = default; - virtual ~NzResource(); + class NAZARA_CORE_API Resource + { + public: + Resource() = default; + Resource(const Resource&) = default; + Resource(Resource&&) = default; + virtual ~Resource(); - const NzString& GetFilePath() const; + const String& GetFilePath() const; - void SetFilePath(const NzString& filePath); + void SetFilePath(const String& filePath); - NzResource& operator=(const NzResource&) = default; - NzResource& operator=(NzResource&&) = default; + Resource& operator=(const Resource&) = default; + Resource& operator=(Resource&&) = default; - private: - NzString m_filePath; -}; + private: + String m_filePath; + }; +} #endif // NAZARA_RESOURCE_HPP diff --git a/include/Nazara/Core/ResourceLoader.hpp b/include/Nazara/Core/ResourceLoader.hpp index b2de65c6a..64d9d81d7 100644 --- a/include/Nazara/Core/ResourceLoader.hpp +++ b/include/Nazara/Core/ResourceLoader.hpp @@ -14,36 +14,39 @@ #include #include -class NzInputStream; - -template -class NzResourceLoader +namespace Nz { - friend Type; + class InputStream; - public: - using ExtensionGetter = bool (*)(const NzString& extension); - using FileLoader = bool (*)(Type* resource, const NzString& filePath, const Parameters& parameters); - using MemoryLoader = bool (*)(Type* resource, const void* data, std::size_t size, const Parameters& parameters); - using StreamChecker = nzTernary (*)(NzInputStream& stream, const Parameters& parameters); - using StreamLoader = bool (*)(Type* resource, NzInputStream& stream, const Parameters& parameters); + template + class ResourceLoader + { + friend Type; - NzResourceLoader() = delete; - ~NzResourceLoader() = delete; + public: + using ExtensionGetter = bool (*)(const String& extension); + using FileLoader = bool (*)(Type* resource, const String& filePath, const Parameters& parameters); + using MemoryLoader = bool (*)(Type* resource, const void* data, std::size_t size, const Parameters& parameters); + using StreamChecker = Ternary (*)(InputStream& stream, const Parameters& parameters); + using StreamLoader = bool (*)(Type* resource, InputStream& stream, const Parameters& parameters); - static bool IsExtensionSupported(const NzString& extension); + ResourceLoader() = delete; + ~ResourceLoader() = delete; - static bool LoadFromFile(Type* resource, const NzString& filePath, const Parameters& parameters = Parameters()); - static bool LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters = Parameters()); - static bool LoadFromStream(Type* resource, NzInputStream& stream, const Parameters& parameters = Parameters()); + static bool IsExtensionSupported(const String& extension); - static void RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr); - static void UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr); + static bool LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters = Parameters()); + static bool LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters = Parameters()); + static bool LoadFromStream(Type* resource, InputStream& stream, const Parameters& parameters = Parameters()); - private: - using Loader = std::tuple; - using LoaderList = std::list; -}; + static void RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr); + static void UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr); + + private: + using Loader = std::tuple; + using LoaderList = std::list; + }; +} #include diff --git a/include/Nazara/Core/ResourceLoader.inl b/include/Nazara/Core/ResourceLoader.inl index 11d9a0a63..fd4b9d4e3 100644 --- a/include/Nazara/Core/ResourceLoader.inl +++ b/include/Nazara/Core/ResourceLoader.inl @@ -9,271 +9,274 @@ #include #include -template -bool NzResourceLoader::IsExtensionSupported(const NzString& extension) +namespace Nz { - for (Loader& loader : Type::s_loaders) + template + bool ResourceLoader::IsExtensionSupported(const String& extension) { - ExtensionGetter isExtensionSupported = std::get<0>(loader); - - if (isExtensionSupported && isExtensionSupported(extension)) - return true; - } - - return false; -} - -template -bool NzResourceLoader::LoadFromFile(Type* resource, const NzString& filePath, const Parameters& parameters) -{ - #if NAZARA_CORE_SAFE - if (!parameters.IsValid()) - { - NazaraError("Invalid parameters"); - return false; - } - #endif - - NzString path = NzFile::NormalizePath(filePath); - NzString ext = path.SubStringFrom('.', -1, true).ToLower(); - if (ext.IsEmpty()) - { - NazaraError("Failed to get file extension from \"" + filePath + '"'); - return false; - } - - NzFile file(path); // Ouvert seulement en cas de besoin - - bool found = false; - for (Loader& loader : Type::s_loaders) - { - ExtensionGetter isExtensionSupported = std::get<0>(loader); - if (!isExtensionSupported || !isExtensionSupported(ext)) - continue; - - StreamChecker checkFunc = std::get<1>(loader); - StreamLoader streamLoader = std::get<2>(loader); - FileLoader fileLoader = std::get<3>(loader); - - if (checkFunc && !file.IsOpen()) + for (Loader& loader : Type::s_loaders) { - if (!file.Open(nzOpenMode_ReadOnly)) - { - NazaraError("Failed to load file: unable to open \"" + filePath + '"'); - return false; - } + ExtensionGetter isExtensionSupported = std::get<0>(loader); + + if (isExtensionSupported && isExtensionSupported(extension)) + return true; } - nzTernary recognized = nzTernary_Unknown; - if (fileLoader) + return false; + } + + template + bool ResourceLoader::LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters) + { + #if NAZARA_CORE_SAFE + if (!parameters.IsValid()) { - if (checkFunc) + NazaraError("Invalid parameters"); + return false; + } + #endif + + String path = File::NormalizePath(filePath); + String ext = path.SubStringFrom('.', -1, true).ToLower(); + if (ext.IsEmpty()) + { + NazaraError("Failed to get file extension from \"" + filePath + '"'); + return false; + } + + File file(path); // Ouvert seulement en cas de besoin + + bool found = false; + for (Loader& loader : Type::s_loaders) + { + ExtensionGetter isExtensionSupported = std::get<0>(loader); + if (!isExtensionSupported || !isExtensionSupported(ext)) + continue; + + StreamChecker checkFunc = std::get<1>(loader); + StreamLoader streamLoader = std::get<2>(loader); + FileLoader fileLoader = std::get<3>(loader); + + if (checkFunc && !file.IsOpen()) + { + if (!file.Open(OpenMode_ReadOnly)) + { + NazaraError("Failed to load file: unable to open \"" + filePath + '"'); + return false; + } + } + + Ternary recognized = Ternary_Unknown; + if (fileLoader) + { + if (checkFunc) + { + file.SetCursorPos(0); + + recognized = checkFunc(file, parameters); + if (recognized == Ternary_False) + continue; + else + found = true; + } + else + { + recognized = Ternary_Unknown; + found = true; + } + + if (fileLoader(resource, filePath, parameters)) + { + resource->SetFilePath(filePath); + return true; + } + } + else { file.SetCursorPos(0); recognized = checkFunc(file, parameters); - if (recognized == nzTernary_False) + if (recognized == Ternary_False) continue; - else + else if (recognized == Ternary_True) found = true; + + file.SetCursorPos(0); + + if (streamLoader(resource, file, parameters)) + { + resource->SetFilePath(filePath); + return true; + } + } + + if (recognized == Ternary_True) + NazaraWarning("Loader failed"); + } + + if (found) + NazaraError("Failed to load file: all loaders failed"); + else + NazaraError("Failed to load file: no loader found for extension \"" + ext + '"'); + + return false; + } + + template + bool ResourceLoader::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters) + { + #if NAZARA_CORE_SAFE + if (!parameters.IsValid()) + { + NazaraError("Invalid parameters"); + return false; + } + + if (size == 0) + { + NazaraError("No data to load"); + return false; + } + #endif + + MemoryStream stream(data, size); + + bool found = false; + for (Loader& loader : Type::s_loaders) + { + StreamChecker checkFunc = std::get<1>(loader); + StreamLoader streamLoader = std::get<2>(loader); + MemoryLoader memoryLoader = std::get<4>(loader); + + Ternary recognized = Ternary_Unknown; + if (memoryLoader) + { + if (checkFunc) + { + stream.SetCursorPos(0); + + recognized = checkFunc(stream, parameters); + if (recognized == Ternary_False) + continue; + else + found = true; + } + else + { + recognized = Ternary_Unknown; + found = true; + } + + if (memoryLoader(resource, data, size, parameters)) + return true; } else - { - recognized = nzTernary_Unknown; - found = true; - } - - if (fileLoader(resource, filePath, parameters)) - { - resource->SetFilePath(filePath); - return true; - } - } - else - { - file.SetCursorPos(0); - - recognized = checkFunc(file, parameters); - if (recognized == nzTernary_False) - continue; - else if (recognized == nzTernary_True) - found = true; - - file.SetCursorPos(0); - - if (streamLoader(resource, file, parameters)) - { - resource->SetFilePath(filePath); - return true; - } - } - - if (recognized == nzTernary_True) - NazaraWarning("Loader failed"); - } - - if (found) - NazaraError("Failed to load file: all loaders failed"); - else - NazaraError("Failed to load file: no loader found for extension \"" + ext + '"'); - - return false; -} - -template -bool NzResourceLoader::LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters) -{ - #if NAZARA_CORE_SAFE - if (!parameters.IsValid()) - { - NazaraError("Invalid parameters"); - return false; - } - - if (size == 0) - { - NazaraError("No data to load"); - return false; - } - #endif - - NzMemoryStream stream(data, size); - - bool found = false; - for (Loader& loader : Type::s_loaders) - { - StreamChecker checkFunc = std::get<1>(loader); - StreamLoader streamLoader = std::get<2>(loader); - MemoryLoader memoryLoader = std::get<4>(loader); - - nzTernary recognized = nzTernary_Unknown; - if (memoryLoader) - { - if (checkFunc) { stream.SetCursorPos(0); recognized = checkFunc(stream, parameters); - if (recognized == nzTernary_False) + if (recognized == Ternary_False) continue; - else + else if (recognized == Ternary_True) found = true; - } - else - { - recognized = nzTernary_Unknown; - found = true; + + stream.SetCursorPos(0); + + if (streamLoader(resource, stream, parameters)) + return true; } - if (memoryLoader(resource, data, size, parameters)) - return true; + if (recognized == Ternary_True) + NazaraWarning("Loader failed"); } - else - { - stream.SetCursorPos(0); - recognized = checkFunc(stream, parameters); - if (recognized == nzTernary_False) + if (found) + NazaraError("Failed to load file: all loaders failed"); + else + NazaraError("Failed to load file: no loader found"); + + return false; + } + + template + bool ResourceLoader::LoadFromStream(Type* resource, InputStream& stream, const Parameters& parameters) + { + #if NAZARA_CORE_SAFE + if (!parameters.IsValid()) + { + NazaraError("Invalid parameters"); + return false; + } + + if (stream.GetSize() == 0 || stream.GetCursorPos() >= stream.GetSize()) + { + NazaraError("No data to load"); + return false; + } + #endif + + UInt64 streamPos = stream.GetCursorPos(); + bool found = false; + for (Loader& loader : Type::s_loaders) + { + StreamChecker checkFunc = std::get<1>(loader); + StreamLoader streamLoader = std::get<2>(loader); + + stream.SetCursorPos(streamPos); + + // Le loader supporte-t-il les données ? + Ternary recognized = checkFunc(stream, parameters); + if (recognized == Ternary_False) continue; - else if (recognized == nzTernary_True) + else if (recognized == Ternary_True) found = true; - stream.SetCursorPos(0); + // On repositionne le stream à son ancienne position + stream.SetCursorPos(streamPos); + // Chargement de la ressource if (streamLoader(resource, stream, parameters)) return true; + + if (recognized == Ternary_True) + NazaraWarning("Loader failed"); } - if (recognized == nzTernary_True) - NazaraWarning("Loader failed"); - } + if (found) + NazaraError("Failed to load file: all loaders failed"); + else + NazaraError("Failed to load file: no loader found"); - if (found) - NazaraError("Failed to load file: all loaders failed"); - else - NazaraError("Failed to load file: no loader found"); - - return false; -} - -template -bool NzResourceLoader::LoadFromStream(Type* resource, NzInputStream& stream, const Parameters& parameters) -{ - #if NAZARA_CORE_SAFE - if (!parameters.IsValid()) - { - NazaraError("Invalid parameters"); return false; } - if (stream.GetSize() == 0 || stream.GetCursorPos() >= stream.GetSize()) + template + void ResourceLoader::RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader) { - NazaraError("No data to load"); - return false; - } - #endif - - nzUInt64 streamPos = stream.GetCursorPos(); - bool found = false; - for (Loader& loader : Type::s_loaders) - { - StreamChecker checkFunc = std::get<1>(loader); - StreamLoader streamLoader = std::get<2>(loader); - - stream.SetCursorPos(streamPos); - - // Le loader supporte-t-il les données ? - nzTernary recognized = checkFunc(stream, parameters); - if (recognized == nzTernary_False) - continue; - else if (recognized == nzTernary_True) - found = true; - - // On repositionne le stream à son ancienne position - stream.SetCursorPos(streamPos); - - // Chargement de la ressource - if (streamLoader(resource, stream, parameters)) - return true; - - if (recognized == nzTernary_True) - NazaraWarning("Loader failed"); - } - - if (found) - NazaraError("Failed to load file: all loaders failed"); - else - NazaraError("Failed to load file: no loader found"); - - return false; -} - -template -void NzResourceLoader::RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader) -{ - #if NAZARA_CORE_SAFE - if (streamLoader) - { - if (!checkFunc) + #if NAZARA_CORE_SAFE + if (streamLoader) { - NazaraError("StreamLoader present without StreamChecker"); + if (!checkFunc) + { + NazaraError("StreamLoader present without StreamChecker"); + return; + } + } + else if (!fileLoader && !memoryLoader) + { + NazaraError("Neither FileLoader nor MemoryLoader nor StreamLoader were present"); return; } + #endif + + Type::s_loaders.push_front(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader, memoryLoader)); } - else if (!fileLoader && !memoryLoader) + + template + void ResourceLoader::UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader) { - NazaraError("Neither FileLoader nor MemoryLoader nor StreamLoader were present"); - return; + Type::s_loaders.remove(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader, memoryLoader)); } - #endif - - Type::s_loaders.push_front(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader, memoryLoader)); -} - -template -void NzResourceLoader::UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader, MemoryLoader memoryLoader) -{ - Type::s_loaders.remove(std::make_tuple(extensionGetter, checkFunc, streamLoader, fileLoader, memoryLoader)); } #include diff --git a/include/Nazara/Core/ResourceManager.hpp b/include/Nazara/Core/ResourceManager.hpp index ce15e5050..fa3dd63ec 100644 --- a/include/Nazara/Core/ResourceManager.hpp +++ b/include/Nazara/Core/ResourceManager.hpp @@ -11,32 +11,35 @@ #include #include -template -class NzResourceManager +namespace Nz { - friend Type; + template + class ResourceManager + { + friend Type; - public: - NzResourceManager() = delete; - ~NzResourceManager() = delete; + public: + ResourceManager() = delete; + ~ResourceManager() = delete; - static void Clear(); + static void Clear(); - static NzObjectRef Get(const NzString& filePath); - static const Parameters& GetDefaultParameters(); + static ObjectRef Get(const String& filePath); + static const Parameters& GetDefaultParameters(); - static void Purge(); - static void Register(const NzString& filePath, NzObjectRef resource); - static void SetDefaultParameters(const Parameters& params); - static void Unregister(const NzString& filePath); + static void Purge(); + static void Register(const String& filePath, ObjectRef resource); + static void SetDefaultParameters(const Parameters& params); + static void Unregister(const String& filePath); - private: - static bool Initialize(); - static void Uninitialize(); + private: + static bool Initialize(); + static void Uninitialize(); - using ManagerMap = std::unordered_map>; - using ManagerParams = Parameters; -}; + using ManagerMap = std::unordered_map>; + using ManagerParams = Parameters; + }; +} #include diff --git a/include/Nazara/Core/ResourceManager.inl b/include/Nazara/Core/ResourceManager.inl index 33a4620d4..c5f37237e 100644 --- a/include/Nazara/Core/ResourceManager.inl +++ b/include/Nazara/Core/ResourceManager.inl @@ -7,95 +7,98 @@ #include #include -template -void NzResourceManager::Clear() +namespace Nz { - Type::s_managerMap.clear(); -} - -template -NzObjectRef NzResourceManager::Get(const NzString& filePath) -{ - NzString absolutePath = NzFile::AbsolutePath(filePath); - auto it = Type::s_managerMap.find(absolutePath); - if (it == Type::s_managerMap.end()) + template + void ResourceManager::Clear() { - NzObjectRef resource = Type::New(); - if (!resource) - { - NazaraError("Failed to create resource"); - return NzObjectRef(); - } - - if (!resource->LoadFromFile(absolutePath, GetDefaultParameters())) - { - NazaraError("Failed to load resource from file: " + absolutePath); - return NzObjectRef(); - } - - NazaraDebug("Loaded resource from file " + absolutePath); - - it = Type::s_managerMap.insert(std::make_pair(absolutePath, resource)).first; + Type::s_managerMap.clear(); } - return it->second; -} - -template -const Parameters& NzResourceManager::GetDefaultParameters() -{ - return Type::s_managerParameters; -} - -template -void NzResourceManager::Purge() -{ - auto it = Type::s_managerMap.begin(); - while (it != Type::s_managerMap.end()) + template + ObjectRef ResourceManager::Get(const String& filePath) { - const NzObjectRef& ref = it->second; - if (ref.GetReferenceCount() == 1) // Sommes-nous les seuls à détenir la ressource ? + String absolutePath = File::AbsolutePath(filePath); + auto it = Type::s_managerMap.find(absolutePath); + if (it == Type::s_managerMap.end()) { - NazaraDebug("Purging resource from file " + ref->GetFilePath()); - Type::s_managerMap.erase(it++); // Alors on la supprime + ObjectRef resource = Type::New(); + if (!resource) + { + NazaraError("Failed to create resource"); + return ObjectRef(); + } + + if (!resource->LoadFromFile(absolutePath, GetDefaultParameters())) + { + NazaraError("Failed to load resource from file: " + absolutePath); + return ObjectRef(); + } + + NazaraDebug("Loaded resource from file " + absolutePath); + + it = Type::s_managerMap.insert(std::make_pair(absolutePath, resource)).first; } - else - ++it; + + return it->second; } -} -template -void NzResourceManager::Register(const NzString& filePath, NzObjectRef resource) -{ - NzString absolutePath = NzFile::AbsolutePath(filePath); + template + const Parameters& ResourceManager::GetDefaultParameters() + { + return Type::s_managerParameters; + } - Type::s_managerMap[absolutePath] = resource; -} + template + void ResourceManager::Purge() + { + auto it = Type::s_managerMap.begin(); + while (it != Type::s_managerMap.end()) + { + const ObjectRef& ref = it->second; + if (ref.GetReferenceCount() == 1) // Sommes-nous les seuls à détenir la ressource ? + { + NazaraDebug("Purging resource from file " + ref->GetFilePath()); + Type::s_managerMap.erase(it++); // Alors on la supprime + } + else + ++it; + } + } -template -void NzResourceManager::SetDefaultParameters(const Parameters& params) -{ - Type::s_managerParameters = params; -} + template + void ResourceManager::Register(const String& filePath, ObjectRef resource) + { + String absolutePath = File::AbsolutePath(filePath); -template -void NzResourceManager::Unregister(const NzString& filePath) -{ - NzString absolutePath = NzFile::AbsolutePath(filePath); + Type::s_managerMap[absolutePath] = resource; + } - Type::s_managerMap.erase(absolutePath); -} + template + void ResourceManager::SetDefaultParameters(const Parameters& params) + { + Type::s_managerParameters = params; + } -template -bool NzResourceManager::Initialize() -{ - return true; -} + template + void ResourceManager::Unregister(const String& filePath) + { + String absolutePath = File::AbsolutePath(filePath); -template -void NzResourceManager::Uninitialize() -{ - Clear(); + Type::s_managerMap.erase(absolutePath); + } + + template + bool ResourceManager::Initialize() + { + return true; + } + + template + void ResourceManager::Uninitialize() + { + Clear(); + } } #include diff --git a/include/Nazara/Core/Semaphore.hpp b/include/Nazara/Core/Semaphore.hpp index b7a6683a9..c64ebc4e0 100644 --- a/include/Nazara/Core/Semaphore.hpp +++ b/include/Nazara/Core/Semaphore.hpp @@ -9,28 +9,31 @@ #include -class NzSemaphoreImpl; - -class NAZARA_CORE_API NzSemaphore +namespace Nz { - public: - NzSemaphore(unsigned int count); - NzSemaphore(const NzSemaphore&) = delete; - NzSemaphore(NzSemaphore&&) = delete; ///TODO - ~NzSemaphore(); + class SemaphoreImpl; - unsigned int GetCount() const; + class NAZARA_CORE_API Semaphore + { + public: + Semaphore(unsigned int count); + Semaphore(const Semaphore&) = delete; + Semaphore(Semaphore&&) = delete; ///TODO + ~Semaphore(); - void Post(); + unsigned int GetCount() const; - void Wait(); - bool Wait(nzUInt32 timeout); + void Post(); - NzSemaphore& operator=(const NzSemaphore&) = delete; - NzSemaphore& operator=(NzSemaphore&&) = delete; ///TODO + void Wait(); + bool Wait(UInt32 timeout); - private: - NzSemaphoreImpl* m_impl; -}; + Semaphore& operator=(const Semaphore&) = delete; + Semaphore& operator=(Semaphore&&) = delete; ///TODO + + private: + SemaphoreImpl* m_impl; + }; +} #endif // NAZARA_SEMAPHORE_HPP diff --git a/include/Nazara/Core/Signal.hpp b/include/Nazara/Core/Signal.hpp index b26fdb29b..bd6d3ab9e 100644 --- a/include/Nazara/Core/Signal.hpp +++ b/include/Nazara/Core/Signal.hpp @@ -11,122 +11,124 @@ #include #include -#define NazaraSignal(SignalName, ...) using SignalName ## Type = NzSignal<__VA_ARGS__>; \ +#define NazaraSignal(SignalName, ...) using SignalName ## Type = Nz::Signal<__VA_ARGS__>; \ mutable SignalName ## Type SignalName #define NazaraSlotType(Class, SignalName) Class::SignalName ## Type::ConnectionGuard #define NazaraSlot(Class, SignalName, SlotName) NazaraSlotType(Class, SignalName) SlotName - -template -class NzSignal +namespace Nz { - public: - using Callback = std::function; - class Connection; - class ConnectionGuard; + template + class Signal + { + public: + using Callback = std::function; + class Connection; + class ConnectionGuard; - NzSignal(); - NzSignal(const NzSignal&) = delete; - NzSignal(NzSignal&& signal); - ~NzSignal() = default; + Signal(); + Signal(const Signal&) = delete; + Signal(Signal&& signal); + ~Signal() = default; - void Clear(); + void Clear(); - Connection Connect(const Callback& func); - Connection Connect(Callback&& func); - template Connection Connect(O& object, void (O::*method)(Args...)); - template Connection Connect(O* object, void (O::*method)(Args...)); - template Connection Connect(const O& object, void (O::*method)(Args...) const); - template Connection Connect(const O* object, void (O::*method)(Args...) const); + Connection Connect(const Callback& func); + Connection Connect(Callback&& func); + template Connection Connect(O& object, void (O::*method)(Args...)); + template Connection Connect(O* object, void (O::*method)(Args...)); + template Connection Connect(const O& object, void (O::*method)(Args...) const); + template Connection Connect(const O* object, void (O::*method)(Args...) const); - void operator()(Args... args) const; + void operator()(Args... args) const; - NzSignal& operator=(const NzSignal&) = delete; - NzSignal& operator=(NzSignal&& signal); + Signal& operator=(const Signal&) = delete; + Signal& operator=(Signal&& signal); - private: - struct Slot; + private: + struct Slot; - using SlotPtr = std::shared_ptr; - using SlotList = std::vector; - using SlotListIndex = typename SlotList::size_type; + using SlotPtr = std::shared_ptr; + using SlotList = std::vector; + using SlotListIndex = typename SlotList::size_type; - struct Slot - { - Slot(NzSignal* me) : - signal(me) + struct Slot { - } + Slot(Signal* me) : + signal(me) + { + } - Callback callback; - NzSignal* signal; - SlotListIndex index; - }; + Callback callback; + Signal* signal; + SlotListIndex index; + }; - void Disconnect(const SlotPtr& slot); + void Disconnect(const SlotPtr& slot); - SlotList m_slots; - mutable SlotListIndex m_slotIterator; -}; + SlotList m_slots; + mutable SlotListIndex m_slotIterator; + }; -template -class NzSignal::Connection -{ - using BaseClass = NzSignal; - friend BaseClass; + template + class Signal::Connection + { + using BaseClass = Signal; + friend BaseClass; - public: - Connection() = default; - Connection(const Connection& connection) = default; - Connection(Connection&& connection) = default; - ~Connection() = default; + public: + Connection() = default; + Connection(const Connection& connection) = default; + Connection(Connection&& connection) = default; + ~Connection() = default; - template - void Connect(BaseClass& signal, ConnectArgs&&... args); - void Disconnect(); + template + void Connect(BaseClass& signal, ConnectArgs&&... args); + void Disconnect(); - bool IsConnected() const; + bool IsConnected() const; - Connection& operator=(const Connection& connection) = default; - Connection& operator=(Connection&& connection) = default; + Connection& operator=(const Connection& connection) = default; + Connection& operator=(Connection&& connection) = default; - private: - Connection(const SlotPtr& slot); + private: + Connection(const SlotPtr& slot); - std::weak_ptr m_ptr; -}; + std::weak_ptr m_ptr; + }; -template -class NzSignal::ConnectionGuard -{ - using BaseClass = NzSignal; - using Connection = typename BaseClass::Connection; + template + class Signal::ConnectionGuard + { + using BaseClass = Signal; + using Connection = typename BaseClass::Connection; - public: - ConnectionGuard() = default; - ConnectionGuard(const Connection& connection); - ConnectionGuard(const ConnectionGuard& connection) = delete; - ConnectionGuard(Connection&& connection); - ConnectionGuard(ConnectionGuard&& connection) = default; - ~ConnectionGuard(); + public: + ConnectionGuard() = default; + ConnectionGuard(const Connection& connection); + ConnectionGuard(const ConnectionGuard& connection) = delete; + ConnectionGuard(Connection&& connection); + ConnectionGuard(ConnectionGuard&& connection) = default; + ~ConnectionGuard(); - template - void Connect(BaseClass& signal, ConnectArgs&&... args); - void Disconnect(); + template + void Connect(BaseClass& signal, ConnectArgs&&... args); + void Disconnect(); - Connection& GetConnection(); + Connection& GetConnection(); - bool IsConnected() const; + bool IsConnected() const; - ConnectionGuard& operator=(const Connection& connection); - ConnectionGuard& operator=(const ConnectionGuard& connection) = delete; - ConnectionGuard& operator=(Connection&& connection); - ConnectionGuard& operator=(ConnectionGuard&& connection); + ConnectionGuard& operator=(const Connection& connection); + ConnectionGuard& operator=(const ConnectionGuard& connection) = delete; + ConnectionGuard& operator=(Connection&& connection); + ConnectionGuard& operator=(ConnectionGuard&& connection); - private: - Connection m_connection; -}; + private: + Connection m_connection; + }; +} #include diff --git a/include/Nazara/Core/Signal.inl b/include/Nazara/Core/Signal.inl index cae03220a..a635302ec 100644 --- a/include/Nazara/Core/Signal.inl +++ b/include/Nazara/Core/Signal.inl @@ -6,245 +6,248 @@ #include #include -template -NzSignal::NzSignal() : -m_slotIterator(0) +namespace Nz { -} - -template -NzSignal::NzSignal(NzSignal&& signal) -{ - operator=(std::move(signal)); -} - -template -void NzSignal::Clear() -{ - m_slots.clear(); - m_slotIterator = 0; -} - -template -typename NzSignal::Connection NzSignal::Connect(const Callback& func) -{ - return Connect(Callback(func)); -} - -template -typename NzSignal::Connection NzSignal::Connect(Callback&& func) -{ - NazaraAssert(func, "Invalid function"); - - // Since we're incrementing the slot vector size, we need to replace our iterator at the end - // (Except when we are iterating on the signal) - bool resetIt = (m_slotIterator >= m_slots.size()); - - auto tempPtr = std::make_shared(this); - tempPtr->callback = std::move(func); - tempPtr->index = m_slots.size(); - - m_slots.emplace_back(std::move(tempPtr)); - - if (resetIt) - m_slotIterator = m_slots.size(); //< Replace the iterator to the end - - return Connection(m_slots.back()); -} - -template -template -typename NzSignal::Connection NzSignal::Connect(O& object, void (O::*method) (Args...)) -{ - return Connect([&object, method] (Args&&... args) + template + Signal::Signal() : + m_slotIterator(0) { - return (object .* method) (std::forward(args)...); - }); -} - -template -template -typename NzSignal::Connection NzSignal::Connect(O* object, void (O::*method)(Args...)) -{ - return Connect([object, method] (Args&&... args) - { - return (object ->* method) (std::forward(args)...); - }); -} - -template -template -typename NzSignal::Connection NzSignal::Connect(const O& object, void (O::*method) (Args...) const) -{ - return Connect([&object, method] (Args&&... args) - { - return (object .* method) (std::forward(args)...); - }); -} - -template -template -typename NzSignal::Connection NzSignal::Connect(const O* object, void (O::*method)(Args...) const) -{ - return Connect([object, method] (Args&&... args) - { - return (object ->* method) (std::forward(args)...); - }); -} - -template -void NzSignal::operator()(Args... args) const -{ - for (m_slotIterator = 0; m_slotIterator < m_slots.size(); ++m_slotIterator) - m_slots[m_slotIterator]->callback(args...); -} - -template -NzSignal& NzSignal::operator=(NzSignal&& signal) -{ - m_slots = std::move(signal.m_slots); - m_slotIterator = signal.m_slotIterator; - - // We need to update the signal pointer inside of each slot - for (SlotPtr& slot : m_slots) - slot->signal = this; - - return *this; -} - -template -void NzSignal::Disconnect(const SlotPtr& slot) -{ - NazaraAssert(slot, "Invalid slot pointer"); - NazaraAssert(slot->index < m_slots.size(), "Invalid slot index"); - - // "Swap this slot with the last one and pop" idiom - // This will preserve slot indexes - - // Can we safely "remove" this slot? - if (m_slotIterator >= m_slots.size()-1 || slot->index > m_slotIterator) - { - // Yes we can - SlotPtr& newSlot = m_slots[slot->index]; - newSlot = std::move(m_slots.back()); - newSlot->index = slot->index; //< Update the moved slot index before resizing (in case it's the last one) - } - else - { - // Nope, let's be tricky - SlotPtr& current = m_slots[m_slotIterator]; - SlotPtr& newSlot = m_slots[slot->index]; - - newSlot = std::move(current); - newSlot->index = slot->index; //< Update the moved slot index - - current = std::move(m_slots.back()); - current->index = m_slotIterator; //< Update the moved slot index - - --m_slotIterator; } - // Pop the last entry (from where we moved our slot) - m_slots.pop_back(); -} + template + Signal::Signal(Signal&& signal) + { + operator=(std::move(signal)); + } + + template + void Signal::Clear() + { + m_slots.clear(); + m_slotIterator = 0; + } + + template + typename Signal::Connection Signal::Connect(const Callback& func) + { + return Connect(Callback(func)); + } + + template + typename Signal::Connection Signal::Connect(Callback&& func) + { + NazaraAssert(func, "Invalid function"); + + // Since we're incrementing the slot vector size, we need to replace our iterator at the end + // (Except when we are iterating on the signal) + bool resetIt = (m_slotIterator >= m_slots.size()); + + auto tempPtr = std::make_shared(this); + tempPtr->callback = std::move(func); + tempPtr->index = m_slots.size(); + + m_slots.emplace_back(std::move(tempPtr)); + + if (resetIt) + m_slotIterator = m_slots.size(); //< Replace the iterator to the end + + return Connection(m_slots.back()); + } + + template + template + typename Signal::Connection Signal::Connect(O& object, void (O::*method) (Args...)) + { + return Connect([&object, method] (Args&&... args) + { + return (object .* method) (std::forward(args)...); + }); + } + + template + template + typename Signal::Connection Signal::Connect(O* object, void (O::*method)(Args...)) + { + return Connect([object, method] (Args&&... args) + { + return (object ->* method) (std::forward(args)...); + }); + } + + template + template + typename Signal::Connection Signal::Connect(const O& object, void (O::*method) (Args...) const) + { + return Connect([&object, method] (Args&&... args) + { + return (object .* method) (std::forward(args)...); + }); + } + + template + template + typename Signal::Connection Signal::Connect(const O* object, void (O::*method)(Args...) const) + { + return Connect([object, method] (Args&&... args) + { + return (object ->* method) (std::forward(args)...); + }); + } + + template + void Signal::operator()(Args... args) const + { + for (m_slotIterator = 0; m_slotIterator < m_slots.size(); ++m_slotIterator) + m_slots[m_slotIterator]->callback(args...); + } + + template + Signal& Signal::operator=(Signal&& signal) + { + m_slots = std::move(signal.m_slots); + m_slotIterator = signal.m_slotIterator; + + // We need to update the signal pointer inside of each slot + for (SlotPtr& slot : m_slots) + slot->signal = this; + + return *this; + } + + template + void Signal::Disconnect(const SlotPtr& slot) + { + NazaraAssert(slot, "Invalid slot pointer"); + NazaraAssert(slot->index < m_slots.size(), "Invalid slot index"); + + // "Swap this slot with the last one and pop" idiom + // This will preserve slot indexes + + // Can we safely "remove" this slot? + if (m_slotIterator >= m_slots.size()-1 || slot->index > m_slotIterator) + { + // Yes we can + SlotPtr& newSlot = m_slots[slot->index]; + newSlot = std::move(m_slots.back()); + newSlot->index = slot->index; //< Update the moved slot index before resizing (in case it's the last one) + } + else + { + // Nope, let's be tricky + SlotPtr& current = m_slots[m_slotIterator]; + SlotPtr& newSlot = m_slots[slot->index]; + + newSlot = std::move(current); + newSlot->index = slot->index; //< Update the moved slot index + + current = std::move(m_slots.back()); + current->index = m_slotIterator; //< Update the moved slot index + + --m_slotIterator; + } + + // Pop the last entry (from where we moved our slot) + m_slots.pop_back(); + } -template -NzSignal::Connection::Connection(const SlotPtr& slot) : -m_ptr(slot) -{ -} + template + Signal::Connection::Connection(const SlotPtr& slot) : + m_ptr(slot) + { + } -template -template -void NzSignal::Connection::Connect(BaseClass& signal, ConnectArgs&&... args) -{ - operator=(signal.Connect(std::forward(args)...)); -} + template + template + void Signal::Connection::Connect(BaseClass& signal, ConnectArgs&&... args) + { + operator=(signal.Connect(std::forward(args)...)); + } -template -void NzSignal::Connection::Disconnect() -{ - if (SlotPtr ptr = m_ptr.lock()) - ptr->signal->Disconnect(ptr); -} + template + void Signal::Connection::Disconnect() + { + if (SlotPtr ptr = m_ptr.lock()) + ptr->signal->Disconnect(ptr); + } -template -bool NzSignal::Connection::IsConnected() const -{ - return !m_ptr.expired(); -} + template + bool Signal::Connection::IsConnected() const + { + return !m_ptr.expired(); + } -template -NzSignal::ConnectionGuard::ConnectionGuard(const Connection& connection) : -m_connection(connection) -{ -} + template + Signal::ConnectionGuard::ConnectionGuard(const Connection& connection) : + m_connection(connection) + { + } -template -NzSignal::ConnectionGuard::ConnectionGuard(Connection&& connection) : -m_connection(std::move(connection)) -{ -} + template + Signal::ConnectionGuard::ConnectionGuard(Connection&& connection) : + m_connection(std::move(connection)) + { + } -template -NzSignal::ConnectionGuard::~ConnectionGuard() -{ - m_connection.Disconnect(); -} + template + Signal::ConnectionGuard::~ConnectionGuard() + { + m_connection.Disconnect(); + } -template -template -void NzSignal::ConnectionGuard::Connect(BaseClass& signal, ConnectArgs&&... args) -{ - m_connection.Disconnect(); - m_connection.Connect(signal, std::forward(args)...); -} + template + template + void Signal::ConnectionGuard::Connect(BaseClass& signal, ConnectArgs&&... args) + { + m_connection.Disconnect(); + m_connection.Connect(signal, std::forward(args)...); + } -template -void NzSignal::ConnectionGuard::Disconnect() -{ - m_connection.Disconnect(); -} + template + void Signal::ConnectionGuard::Disconnect() + { + m_connection.Disconnect(); + } -template -typename NzSignal::Connection& NzSignal::ConnectionGuard::GetConnection() -{ - return m_connection; -} + template + typename Signal::Connection& Signal::ConnectionGuard::GetConnection() + { + return m_connection; + } -template -bool NzSignal::ConnectionGuard::IsConnected() const -{ - return m_connection.IsConnected(); -} + template + bool Signal::ConnectionGuard::IsConnected() const + { + return m_connection.IsConnected(); + } -template -typename NzSignal::ConnectionGuard& NzSignal::ConnectionGuard::operator=(const Connection& connection) -{ - m_connection.Disconnect(); - m_connection = connection; + template + typename Signal::ConnectionGuard& Signal::ConnectionGuard::operator=(const Connection& connection) + { + m_connection.Disconnect(); + m_connection = connection; - return *this; -} + return *this; + } -template -typename NzSignal::ConnectionGuard& NzSignal::ConnectionGuard::operator=(Connection&& connection) -{ - m_connection.Disconnect(); - m_connection = std::move(connection); + template + typename Signal::ConnectionGuard& Signal::ConnectionGuard::operator=(Connection&& connection) + { + m_connection.Disconnect(); + m_connection = std::move(connection); - return *this; -} + return *this; + } -template -typename NzSignal::ConnectionGuard& NzSignal::ConnectionGuard::operator=(ConnectionGuard&& connection) -{ - m_connection.Disconnect(); - m_connection = std::move(connection.m_connection); + template + typename Signal::ConnectionGuard& Signal::ConnectionGuard::operator=(ConnectionGuard&& connection) + { + m_connection.Disconnect(); + m_connection = std::move(connection.m_connection); - return *this; + return *this; + } } #include diff --git a/include/Nazara/Core/SparsePtr.hpp b/include/Nazara/Core/SparsePtr.hpp index 5652502da..79c87ca95 100644 --- a/include/Nazara/Core/SparsePtr.hpp +++ b/include/Nazara/Core/SparsePtr.hpp @@ -13,66 +13,69 @@ #include #include -template -class NzSparsePtr +namespace Nz { - public: - using BytePtr = typename std::conditional::value, const nzUInt8*, nzUInt8*>::type; - using VoidPtr = typename std::conditional::value, const void*, void*>::type; + template + class SparsePtr + { + public: + using BytePtr = typename std::conditional::value, const UInt8*, UInt8*>::type; + using VoidPtr = typename std::conditional::value, const void*, void*>::type; - NzSparsePtr(); - NzSparsePtr(T* ptr); - NzSparsePtr(VoidPtr ptr, int stride); - template NzSparsePtr(const NzSparsePtr& ptr); - NzSparsePtr(const NzSparsePtr& ptr) = default; - ~NzSparsePtr() = default; + SparsePtr(); + SparsePtr(T* ptr); + SparsePtr(VoidPtr ptr, int stride); + template SparsePtr(const SparsePtr& ptr); + SparsePtr(const SparsePtr& ptr) = default; + ~SparsePtr() = default; - VoidPtr GetPtr() const; - int GetStride() const; + VoidPtr GetPtr() const; + int GetStride() const; - void Reset(); - void Reset(T* ptr); - void Reset(VoidPtr ptr, int stride); - void Reset(const NzSparsePtr& ptr); - template void Reset(const NzSparsePtr& ptr); + void Reset(); + void Reset(T* ptr); + void Reset(VoidPtr ptr, int stride); + void Reset(const SparsePtr& ptr); + template void Reset(const SparsePtr& ptr); - void SetPtr(VoidPtr ptr); - void SetStride(int stride); + void SetPtr(VoidPtr ptr); + void SetStride(int stride); - operator bool() const; - operator T*() const; - T& operator*() const; - T* operator->() const; - T& operator[](int index) const; + operator bool() const; + operator T*() const; + T& operator*() const; + T* operator->() const; + T& operator[](int index) const; - NzSparsePtr& operator=(const NzSparsePtr& ptr) = default; + SparsePtr& operator=(const SparsePtr& ptr) = default; - NzSparsePtr operator+(int count) const; - NzSparsePtr operator+(unsigned int count) const; - NzSparsePtr operator-(int count) const; - NzSparsePtr operator-(unsigned int count) const; - std::ptrdiff_t operator-(const NzSparsePtr& ptr) const; + SparsePtr operator+(int count) const; + SparsePtr operator+(unsigned int count) const; + SparsePtr operator-(int count) const; + SparsePtr operator-(unsigned int count) const; + std::ptrdiff_t operator-(const SparsePtr& ptr) const; - NzSparsePtr& operator+=(int count); - NzSparsePtr& operator-=(int count); + SparsePtr& operator+=(int count); + SparsePtr& operator-=(int count); - NzSparsePtr& operator++(); - NzSparsePtr operator++(int); + SparsePtr& operator++(); + SparsePtr operator++(int); - NzSparsePtr& operator--(); - NzSparsePtr operator--(int); + SparsePtr& operator--(); + SparsePtr operator--(int); - bool operator==(const NzSparsePtr& ptr) const; - bool operator!=(const NzSparsePtr& ptr) const; - bool operator<(const NzSparsePtr& ptr) const; - bool operator>(const NzSparsePtr& ptr) const; - bool operator<=(const NzSparsePtr& ptr) const; - bool operator>=(const NzSparsePtr& ptr) const; + bool operator==(const SparsePtr& ptr) const; + bool operator!=(const SparsePtr& ptr) const; + bool operator<(const SparsePtr& ptr) const; + bool operator>(const SparsePtr& ptr) const; + bool operator<=(const SparsePtr& ptr) const; + bool operator>=(const SparsePtr& ptr) const; - private: - BytePtr m_ptr; - int m_stride; -}; + private: + BytePtr m_ptr; + int m_stride; + }; +} #include diff --git a/include/Nazara/Core/SparsePtr.inl b/include/Nazara/Core/SparsePtr.inl index 2ad111798..d6b227226 100644 --- a/include/Nazara/Core/SparsePtr.inl +++ b/include/Nazara/Core/SparsePtr.inl @@ -5,250 +5,253 @@ #include #include -template -NzSparsePtr::NzSparsePtr() +namespace Nz { - Reset(); -} + template + SparsePtr::SparsePtr() + { + Reset(); + } -template -NzSparsePtr::NzSparsePtr(T* ptr) -{ - Reset(ptr); -} + template + SparsePtr::SparsePtr(T* ptr) + { + Reset(ptr); + } -template -NzSparsePtr::NzSparsePtr(VoidPtr ptr, int stride) -{ - Reset(ptr, stride); -} + template + SparsePtr::SparsePtr(VoidPtr ptr, int stride) + { + Reset(ptr, stride); + } -template -template -NzSparsePtr::NzSparsePtr(const NzSparsePtr& ptr) -{ - Reset(ptr); -} + template + template + SparsePtr::SparsePtr(const SparsePtr& ptr) + { + Reset(ptr); + } -template -typename NzSparsePtr::VoidPtr NzSparsePtr::GetPtr() const -{ - return m_ptr; -} + template + typename SparsePtr::VoidPtr SparsePtr::GetPtr() const + { + return m_ptr; + } -template -int NzSparsePtr::GetStride() const -{ - return m_stride; -} + template + int SparsePtr::GetStride() const + { + return m_stride; + } -template -void NzSparsePtr::Reset() -{ - SetPtr(nullptr); - SetStride(0); -} + template + void SparsePtr::Reset() + { + SetPtr(nullptr); + SetStride(0); + } -template -void NzSparsePtr::Reset(T* ptr) -{ - SetPtr(ptr); - SetStride(sizeof(T)); -} + template + void SparsePtr::Reset(T* ptr) + { + SetPtr(ptr); + SetStride(sizeof(T)); + } -template -void NzSparsePtr::Reset(VoidPtr ptr, int stride) -{ - SetPtr(ptr); - SetStride(stride); -} + template + void SparsePtr::Reset(VoidPtr ptr, int stride) + { + SetPtr(ptr); + SetStride(stride); + } -template -void NzSparsePtr::Reset(const NzSparsePtr& ptr) -{ - SetPtr(ptr.GetPtr()); - SetStride(ptr.GetStride()); -} + template + void SparsePtr::Reset(const SparsePtr& ptr) + { + SetPtr(ptr.GetPtr()); + SetStride(ptr.GetStride()); + } -template -template -void NzSparsePtr::Reset(const NzSparsePtr& ptr) -{ - static_assert(std::is_convertible::value, "Source type pointer cannot be implicitely converted to target type pointer"); + template + template + void SparsePtr::Reset(const SparsePtr& ptr) + { + static_assert(std::is_convertible::value, "Source type pointer cannot be implicitely converted to target type pointer"); - SetPtr(static_cast(ptr.GetPtr())); - SetStride(ptr.GetStride()); -} + SetPtr(static_cast(ptr.GetPtr())); + SetStride(ptr.GetStride()); + } -template -void NzSparsePtr::SetPtr(VoidPtr ptr) -{ - m_ptr = reinterpret_cast(ptr); -} + template + void SparsePtr::SetPtr(VoidPtr ptr) + { + m_ptr = reinterpret_cast(ptr); + } -template -void NzSparsePtr::SetStride(int stride) -{ - m_stride = stride; -} + template + void SparsePtr::SetStride(int stride) + { + m_stride = stride; + } -template -NzSparsePtr::operator bool() const -{ - return m_ptr != nullptr; -} + template + SparsePtr::operator bool() const + { + return m_ptr != nullptr; + } -template -NzSparsePtr::operator T*() const -{ - return reinterpret_cast(m_ptr); -} + template + SparsePtr::operator T*() const + { + return reinterpret_cast(m_ptr); + } -template -T& NzSparsePtr::operator*() const -{ - return *reinterpret_cast(m_ptr); -} + template + T& SparsePtr::operator*() const + { + return *reinterpret_cast(m_ptr); + } -template -T* NzSparsePtr::operator->() const -{ - return reinterpret_cast(m_ptr); -} + template + T* SparsePtr::operator->() const + { + return reinterpret_cast(m_ptr); + } -template -T& NzSparsePtr::operator[](int index) const -{ - return *reinterpret_cast(m_ptr + index*m_stride); -} + template + T& SparsePtr::operator[](int index) const + { + return *reinterpret_cast(m_ptr + index*m_stride); + } -template -NzSparsePtr NzSparsePtr::operator+(int count) const -{ - return NzSparsePtr(m_ptr + count*m_stride, m_stride); -} + template + SparsePtr SparsePtr::operator+(int count) const + { + return SparsePtr(m_ptr + count*m_stride, m_stride); + } -template -NzSparsePtr NzSparsePtr::operator+(unsigned int count) const -{ - return NzSparsePtr(m_ptr + count*m_stride, m_stride); -} + template + SparsePtr SparsePtr::operator+(unsigned int count) const + { + return SparsePtr(m_ptr + count*m_stride, m_stride); + } -template -NzSparsePtr NzSparsePtr::operator-(int count) const -{ - return NzSparsePtr(m_ptr - count*m_stride, m_stride); -} + template + SparsePtr SparsePtr::operator-(int count) const + { + return SparsePtr(m_ptr - count*m_stride, m_stride); + } -template -NzSparsePtr NzSparsePtr::operator-(unsigned int count) const -{ - return NzSparsePtr(m_ptr - count*m_stride, m_stride); -} + template + SparsePtr SparsePtr::operator-(unsigned int count) const + { + return SparsePtr(m_ptr - count*m_stride, m_stride); + } -template -std::ptrdiff_t NzSparsePtr::operator-(const NzSparsePtr& ptr) const -{ - return (m_ptr - ptr.m_ptr)/m_stride; -} + template + std::ptrdiff_t SparsePtr::operator-(const SparsePtr& ptr) const + { + return (m_ptr - ptr.m_ptr)/m_stride; + } -template -NzSparsePtr& NzSparsePtr::operator+=(int count) -{ - m_ptr += count*m_stride; + template + SparsePtr& SparsePtr::operator+=(int count) + { + m_ptr += count*m_stride; - return *this; -} + return *this; + } -template -NzSparsePtr& NzSparsePtr::operator-=(int count) -{ - m_ptr -= count*m_stride; + template + SparsePtr& SparsePtr::operator-=(int count) + { + m_ptr -= count*m_stride; - return *this; -} + return *this; + } -template -NzSparsePtr& NzSparsePtr::operator++() -{ - m_ptr += m_stride; + template + SparsePtr& SparsePtr::operator++() + { + m_ptr += m_stride; - return *this; -} + return *this; + } -template -NzSparsePtr NzSparsePtr::operator++(int) -{ - // On fait une copie de l'objet - NzSparsePtr tmp(*this); + template + SparsePtr SparsePtr::operator++(int) + { + // On fait une copie de l'objet + SparsePtr tmp(*this); - // On modifie l'objet - operator++(); + // On modifie l'objet + operator++(); - // On retourne la copie - return tmp; -} + // On retourne la copie + return tmp; + } -template -NzSparsePtr& NzSparsePtr::operator--() -{ - m_ptr -= m_stride; - return *this; -} + template + SparsePtr& SparsePtr::operator--() + { + m_ptr -= m_stride; + return *this; + } -template -NzSparsePtr NzSparsePtr::operator--(int) -{ - // On fait une copie de l'objet - NzSparsePtr tmp(*this); + template + SparsePtr SparsePtr::operator--(int) + { + // On fait une copie de l'objet + SparsePtr tmp(*this); - // On modifie l'objet - operator--(); + // On modifie l'objet + operator--(); - // On retourne la copie - return tmp; -} + // On retourne la copie + return tmp; + } -template -bool NzSparsePtr::operator==(const NzSparsePtr& ptr) const -{ - return m_ptr == ptr.m_ptr; -} + template + bool SparsePtr::operator==(const SparsePtr& ptr) const + { + return m_ptr == ptr.m_ptr; + } -template -bool NzSparsePtr::operator!=(const NzSparsePtr& ptr) const -{ - return m_ptr != ptr.m_ptr; -} + template + bool SparsePtr::operator!=(const SparsePtr& ptr) const + { + return m_ptr != ptr.m_ptr; + } -template -bool NzSparsePtr::operator<(const NzSparsePtr& ptr) const -{ - return m_ptr < ptr.m_ptr; -} + template + bool SparsePtr::operator<(const SparsePtr& ptr) const + { + return m_ptr < ptr.m_ptr; + } -template -bool NzSparsePtr::operator>(const NzSparsePtr& ptr) const -{ - return m_ptr > ptr.m_ptr; -} + template + bool SparsePtr::operator>(const SparsePtr& ptr) const + { + return m_ptr > ptr.m_ptr; + } -template -bool NzSparsePtr::operator<=(const NzSparsePtr& ptr) const -{ - return m_ptr <= ptr.m_ptr; -} + template + bool SparsePtr::operator<=(const SparsePtr& ptr) const + { + return m_ptr <= ptr.m_ptr; + } -template -bool NzSparsePtr::operator>=(const NzSparsePtr& ptr) const -{ - return m_ptr >= ptr.m_ptr; + template + bool SparsePtr::operator>=(const SparsePtr& ptr) const + { + return m_ptr >= ptr.m_ptr; + } } namespace std { template - struct iterator_traits> + struct iterator_traits> { using difference_type = ptrdiff_t; using iterator_category = random_access_iterator_tag; diff --git a/include/Nazara/Core/Stream.hpp b/include/Nazara/Core/Stream.hpp index 8a744b7ac..11154cb4d 100644 --- a/include/Nazara/Core/Stream.hpp +++ b/include/Nazara/Core/Stream.hpp @@ -11,27 +11,30 @@ #include #include -class NAZARA_CORE_API NzStream +namespace Nz { - public: - NzStream() = default; - NzStream(const NzStream&) = default; - NzStream(NzStream&&) = default; - virtual ~NzStream(); + class NAZARA_CORE_API Stream + { + public: + Stream() = default; + Stream(const Stream&) = default; + Stream(Stream&&) = default; + virtual ~Stream(); - virtual nzUInt64 GetCursorPos() const = 0; - virtual NzString GetDirectory() const; - virtual NzString GetPath() const; - unsigned int GetStreamOptions() const; + virtual UInt64 GetCursorPos() const = 0; + virtual String GetDirectory() const; + virtual String GetPath() const; + unsigned int GetStreamOptions() const; - virtual bool SetCursorPos(nzUInt64 offset) = 0; - void SetStreamOptions(unsigned int options); + virtual bool SetCursorPos(UInt64 offset) = 0; + void SetStreamOptions(unsigned int options); - NzStream& operator=(const NzStream&) = default; - NzStream& operator=(NzStream&&) = default; + Stream& operator=(const Stream&) = default; + Stream& operator=(Stream&&) = default; - protected: - unsigned int m_streamOptions = 0; -}; + protected: + unsigned int m_streamOptions = 0; + }; +} #endif // NAZARA_STREAM_HPP diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 88b6e6673..06b9d2c09 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -15,318 +15,321 @@ #include #include -class NzAbstractHash; -class NzHashDigest; - -class NAZARA_CORE_API NzString : public NzHashable +namespace Nz { - public: - enum Flags - { - None = 0x00, // Mode par défaut - CaseInsensitive = 0x01, // Insensible à la casse - HandleUtf8 = 0x02, // Traite les octets comme une suite de caractères UTF-8 - TrimOnlyLeft = 0x04, // Trim(med), ne coupe que la partie gauche de la chaîne - TrimOnlyRight = 0x08 // Trim(med), ne coupe que la partie droite de la chaîne - }; + class AbstractHash; + class HashDigest; - NzString(); - explicit NzString(char character); - NzString(unsigned int rep, char character); - NzString(unsigned int rep, const char* string); - NzString(unsigned int rep, const char* string, unsigned int length); - NzString(unsigned int rep, const NzString& string); - NzString(const char* string); - NzString(const char* string, unsigned int length); - NzString(const std::string& string); - NzString(const NzString& string) = default; - NzString(NzString&& string) noexcept = default; - ~NzString() = default; + class NAZARA_CORE_API String : public Hashable + { + public: + enum Flags + { + None = 0x00, // Mode par défaut + CaseInsensitive = 0x01, // Insensible à la casse + HandleUtf8 = 0x02, // Traite les octets comme une suite de caractères UTF-8 + TrimOnlyLeft = 0x04, // Trim(med), ne coupe que la partie gauche de la chaîne + TrimOnlyRight = 0x08 // Trim(med), ne coupe que la partie droite de la chaîne + }; - NzString& Append(char character); - NzString& Append(const char* string); - NzString& Append(const char* string, unsigned int length); - NzString& Append(const NzString& string); + String(); + explicit String(char character); + String(unsigned int rep, char character); + String(unsigned int rep, const char* string); + String(unsigned int rep, const char* string, unsigned int length); + String(unsigned int rep, const String& string); + String(const char* string); + String(const char* string, unsigned int length); + String(const std::string& string); + String(const String& string) = default; + String(String&& string) noexcept = default; + ~String() = default; - void Clear(bool keepBuffer = false); + String& Append(char character); + String& Append(const char* string); + String& Append(const char* string, unsigned int length); + String& Append(const String& string); - bool Contains(char character, int start = 0, nzUInt32 flags = None) const; - bool Contains(const char* string, int start = 0, nzUInt32 flags = None) const; - bool Contains(const NzString& string, int start = 0, nzUInt32 flags = None) const; + void Clear(bool keepBuffer = false); - unsigned int Count(char character, int start = 0, nzUInt32 flags = None) const; - unsigned int Count(const char* string, int start = 0, nzUInt32 flags = None) const; - unsigned int Count(const NzString& string, int start = 0, nzUInt32 flags = None) const; - unsigned int CountAny(const char* string, int start = 0, nzUInt32 flags = None) const; - unsigned int CountAny(const NzString& string, int start = 0, nzUInt32 flags = None) const; + bool Contains(char character, int start = 0, UInt32 flags = None) const; + bool Contains(const char* string, int start = 0, UInt32 flags = None) const; + bool Contains(const String& string, int start = 0, UInt32 flags = None) const; - bool EndsWith(char character, nzUInt32 flags = None) const; - bool EndsWith(const char* string, nzUInt32 flags = None) const; - bool EndsWith(const char* string, unsigned int length, nzUInt32 flags = None) const; - bool EndsWith(const NzString& string, nzUInt32 flags = None) const; + unsigned int Count(char character, int start = 0, UInt32 flags = None) const; + unsigned int Count(const char* string, int start = 0, UInt32 flags = None) const; + unsigned int Count(const String& string, int start = 0, UInt32 flags = None) const; + unsigned int CountAny(const char* string, int start = 0, UInt32 flags = None) const; + unsigned int CountAny(const String& string, int start = 0, UInt32 flags = None) const; - unsigned int Find(char character, int start = 0, nzUInt32 flags = None) const; - unsigned int Find(const char* string, int start = 0, nzUInt32 flags = None) const; - unsigned int Find(const NzString& string, int start = 0, nzUInt32 flags = None) const; - unsigned int FindAny(const char* string, int start = 0, nzUInt32 flags = None) const; - unsigned int FindAny(const NzString& string, int start = 0, nzUInt32 flags = None) const; - unsigned int FindLast(char character, int start = -1, nzUInt32 flags = None) const; - unsigned int FindLast(const char *string, int start = -1, nzUInt32 flags = None) const; - unsigned int FindLast(const NzString& string, int start = -1, nzUInt32 flags = None) const; - unsigned int FindLastAny(const char* string, int start = -1, nzUInt32 flags = None) const; - unsigned int FindLastAny(const NzString& string, int start = -1, nzUInt32 flags = None) const; - unsigned int FindLastWord(const char* string, int start = -1, nzUInt32 flags = None) const; - unsigned int FindLastWord(const NzString& string, int start = -1, nzUInt32 flags = None) const; - unsigned int FindWord(const char* string, int start = 0, nzUInt32 flags = None) const; - unsigned int FindWord(const NzString& string, int start = 0, nzUInt32 flags = None) const; + bool EndsWith(char character, UInt32 flags = None) const; + bool EndsWith(const char* string, UInt32 flags = None) const; + bool EndsWith(const char* string, unsigned int length, UInt32 flags = None) const; + bool EndsWith(const String& string, UInt32 flags = None) const; - char* GetBuffer(); - unsigned int GetCapacity() const; - const char* GetConstBuffer() const; - unsigned int GetLength() const; - unsigned int GetSize() const; - std::string GetUtf8String() const; - std::u16string GetUtf16String() const; - std::u32string GetUtf32String() const; - std::wstring GetWideString() const; - NzString GetWord(unsigned int index, nzUInt32 flags = None) const; - unsigned int GetWordPosition(unsigned int index, nzUInt32 flags = None) const; + unsigned int Find(char character, int start = 0, UInt32 flags = None) const; + unsigned int Find(const char* string, int start = 0, UInt32 flags = None) const; + unsigned int Find(const String& string, int start = 0, UInt32 flags = None) const; + unsigned int FindAny(const char* string, int start = 0, UInt32 flags = None) const; + unsigned int FindAny(const String& string, int start = 0, UInt32 flags = None) const; + unsigned int FindLast(char character, int start = -1, UInt32 flags = None) const; + unsigned int FindLast(const char *string, int start = -1, UInt32 flags = None) const; + unsigned int FindLast(const String& string, int start = -1, UInt32 flags = None) const; + unsigned int FindLastAny(const char* string, int start = -1, UInt32 flags = None) const; + unsigned int FindLastAny(const String& string, int start = -1, UInt32 flags = None) const; + unsigned int FindLastWord(const char* string, int start = -1, UInt32 flags = None) const; + unsigned int FindLastWord(const String& string, int start = -1, UInt32 flags = None) const; + unsigned int FindWord(const char* string, int start = 0, UInt32 flags = None) const; + unsigned int FindWord(const String& string, int start = 0, UInt32 flags = None) const; - NzString& Insert(int pos, char character); - NzString& Insert(int pos, const char* string); - NzString& Insert(int pos, const char* string, unsigned int length); - NzString& Insert(int pos, const NzString& string); + char* GetBuffer(); + unsigned int GetCapacity() const; + const char* GetConstBuffer() const; + unsigned int GetLength() const; + unsigned int GetSize() const; + std::string GetUtf8String() const; + std::u16string GetUtf16String() const; + std::u32string GetUtf32String() const; + std::wstring GetWideString() const; + String GetWord(unsigned int index, UInt32 flags = None) const; + unsigned int GetWordPosition(unsigned int index, UInt32 flags = None) const; - bool IsEmpty() const; - bool IsNull() const; - bool IsNumber(nzUInt8 radix = 10, nzUInt32 flags = CaseInsensitive) const; + String& Insert(int pos, char character); + String& Insert(int pos, const char* string); + String& Insert(int pos, const char* string, unsigned int length); + String& Insert(int pos, const String& string); - bool Match(const char* pattern) const; - bool Match(const NzString& pattern) const; + bool IsEmpty() const; + bool IsNull() const; + bool IsNumber(UInt8 radix = 10, UInt32 flags = CaseInsensitive) const; - NzString& Prepend(char character); - NzString& Prepend(const char* string); - NzString& Prepend(const char* string, unsigned int length); - NzString& Prepend(const NzString& string); + bool Match(const char* pattern) const; + bool Match(const String& pattern) const; - unsigned int Replace(char oldCharacter, char newCharacter, int start = 0, nzUInt32 flags = None); - unsigned int Replace(const char* oldString, const char* replaceString, int start = 0, nzUInt32 flags = None); - unsigned int Replace(const char* oldString, unsigned int oldLength, const char* replaceString, unsigned int replaceLength, int start = 0, nzUInt32 flags = None); - unsigned int Replace(const NzString& oldString, const NzString& replaceString, int start = 0, nzUInt32 flags = None); - unsigned int ReplaceAny(const char* oldCharacters, char replaceCharacter, int start = 0, nzUInt32 flags = None); - //unsigned int ReplaceAny(const char* oldCharacters, const char* replaceString, int start = 0, nzUInt32 flags = None); - //unsigned int ReplaceAny(const NzString& oldCharacters, const NzString& replaceString, int start = 0, nzUInt32 flags = None); + String& Prepend(char character); + String& Prepend(const char* string); + String& Prepend(const char* string, unsigned int length); + String& Prepend(const String& string); - void Reserve(unsigned int bufferSize); + unsigned int Replace(char oldCharacter, char newCharacter, int start = 0, UInt32 flags = None); + unsigned int Replace(const char* oldString, const char* replaceString, int start = 0, UInt32 flags = None); + unsigned int Replace(const char* oldString, unsigned int oldLength, const char* replaceString, unsigned int replaceLength, int start = 0, UInt32 flags = None); + unsigned int Replace(const String& oldString, const String& replaceString, int start = 0, UInt32 flags = None); + unsigned int ReplaceAny(const char* oldCharacters, char replaceCharacter, int start = 0, UInt32 flags = None); + //unsigned int ReplaceAny(const char* oldCharacters, const char* replaceString, int start = 0, UInt32 flags = None); + //unsigned int ReplaceAny(const String& oldCharacters, const String& replaceString, int start = 0, UInt32 flags = None); - NzString& Resize(int size, char character = ' '); - NzString Resized(int size, char character = ' ') const; + void Reserve(unsigned int bufferSize); - NzString& Reverse(); - NzString Reversed() const; + String& Resize(int size, char character = ' '); + String Resized(int size, char character = ' ') const; - NzString& Set(char character); - NzString& Set(unsigned int rep, char character); - NzString& Set(unsigned int rep, const char* string); - NzString& Set(unsigned int rep, const char* string, unsigned int length); - NzString& Set(unsigned int rep, const NzString& string); - NzString& Set(const char* string); - NzString& Set(const char* string, unsigned int length); - NzString& Set(const std::string& string); - NzString& Set(const NzString& string); - NzString& Set(NzString&& string) noexcept; + String& Reverse(); + String Reversed() const; - NzString Simplified(nzUInt32 flags = None) const; - NzString& Simplify(nzUInt32 flags = None); + String& Set(char character); + String& Set(unsigned int rep, char character); + String& Set(unsigned int rep, const char* string); + String& Set(unsigned int rep, const char* string, unsigned int length); + String& Set(unsigned int rep, const String& string); + String& Set(const char* string); + String& Set(const char* string, unsigned int length); + String& Set(const std::string& string); + String& Set(const String& string); + String& Set(String&& string) noexcept; - unsigned int Split(std::vector& result, char separation = ' ', int start = 0, nzUInt32 flags = None) const; - unsigned int Split(std::vector& result, const char* separation, int start = 0, nzUInt32 flags = None) const; - unsigned int Split(std::vector& result, const char* separation, unsigned int length, int start = 0, nzUInt32 flags = None) const; - unsigned int Split(std::vector& result, const NzString& separation, int start = 0, nzUInt32 flags = None) const; - unsigned int SplitAny(std::vector& result, const char* separations, int start = 0, nzUInt32 flags = None) const; - unsigned int SplitAny(std::vector& result, const NzString& separations, int start = 0, nzUInt32 flags = None) const; + String Simplified(UInt32 flags = None) const; + String& Simplify(UInt32 flags = None); - bool StartsWith(char character, nzUInt32 flags = None) const; - bool StartsWith(const char* string, nzUInt32 flags = None) const; - bool StartsWith(const NzString& string, nzUInt32 flags = None) const; + unsigned int Split(std::vector& result, char separation = ' ', int start = 0, UInt32 flags = None) const; + unsigned int Split(std::vector& result, const char* separation, int start = 0, UInt32 flags = None) const; + unsigned int Split(std::vector& result, const char* separation, unsigned int length, int start = 0, UInt32 flags = None) const; + unsigned int Split(std::vector& result, const String& separation, int start = 0, UInt32 flags = None) const; + unsigned int SplitAny(std::vector& result, const char* separations, int start = 0, UInt32 flags = None) const; + unsigned int SplitAny(std::vector& result, const String& separations, int start = 0, UInt32 flags = None) const; - NzString SubString(int startPos, int endPos = -1) const; - NzString SubStringFrom(char character, int startPos = 0, bool fromLast = false, bool include = false, nzUInt32 flags = None) const; - NzString SubStringFrom(const char *string, int startPos = 0, bool fromLast = false, bool include = false, nzUInt32 flags = None) const; - NzString SubStringFrom(const char *string, unsigned int length, int startPos = 0, bool fromLast = false, bool include = false, nzUInt32 flags = None) const; - NzString SubStringFrom(const NzString& string, int startPos = 0, bool fromLast = false, bool include = false, nzUInt32 flags = None) const; - NzString SubStringTo(char character, int startPos = 0, bool toLast = false, bool include = false, nzUInt32 flags = None) const; - NzString SubStringTo(const char *string, int startPos = 0, bool toLast = false, bool include = false, nzUInt32 flags = None) const; - NzString SubStringTo(const char *string, unsigned int length, int startPos = 0, bool toLast = false, bool include = false, nzUInt32 flags = None) const; - NzString SubStringTo(const NzString& string, int startPos = 0, bool toLast = false, bool include = false, nzUInt32 flags = None) const; + bool StartsWith(char character, UInt32 flags = None) const; + bool StartsWith(const char* string, UInt32 flags = None) const; + bool StartsWith(const String& string, UInt32 flags = None) const; - void Swap(NzString& str); + String SubString(int startPos, int endPos = -1) const; + String SubStringFrom(char character, int startPos = 0, bool fromLast = false, bool include = false, UInt32 flags = None) const; + String SubStringFrom(const char *string, int startPos = 0, bool fromLast = false, bool include = false, UInt32 flags = None) const; + String SubStringFrom(const char *string, unsigned int length, int startPos = 0, bool fromLast = false, bool include = false, UInt32 flags = None) const; + String SubStringFrom(const String& string, int startPos = 0, bool fromLast = false, bool include = false, UInt32 flags = None) const; + String SubStringTo(char character, int startPos = 0, bool toLast = false, bool include = false, UInt32 flags = None) const; + String SubStringTo(const char *string, int startPos = 0, bool toLast = false, bool include = false, UInt32 flags = None) const; + String SubStringTo(const char *string, unsigned int length, int startPos = 0, bool toLast = false, bool include = false, UInt32 flags = None) const; + String SubStringTo(const String& string, int startPos = 0, bool toLast = false, bool include = false, UInt32 flags = None) const; - bool ToBool(bool* value, nzUInt32 flags = None) const; - bool ToDouble(double* value) const; - bool ToInteger(long long* value, nzUInt8 radix = 10) const; - NzString ToLower(nzUInt32 flags = None) const; - NzString ToUpper(nzUInt32 flags = None) const; + void Swap(String& str); - NzString& Trim(nzUInt32 flags = None); - NzString& Trim(char character, nzUInt32 flags = None); - NzString Trimmed(nzUInt32 flags = None) const; - NzString Trimmed(char character, nzUInt32 flags = None) const; + bool ToBool(bool* value, UInt32 flags = None) const; + bool ToDouble(double* value) const; + bool ToInteger(long long* value, UInt8 radix = 10) const; + String ToLower(UInt32 flags = None) const; + String ToUpper(UInt32 flags = None) const; - // Méthodes STD - char* begin(); - const char* begin() const; - char* end(); - const char* end() const; - void push_front(char c); - void push_back(char c); - //char* rbegin(); - //const char* rbegin() const; - //char* rend(); - //const char* rend() const; + String& Trim(UInt32 flags = None); + String& Trim(char character, UInt32 flags = None); + String Trimmed(UInt32 flags = None) const; + String Trimmed(char character, UInt32 flags = None) const; - typedef const char& const_reference; - typedef char* iterator; - //typedef char* reverse_iterator; - typedef char value_type; - // Méthodes STD + // Méthodes STD + char* begin(); + const char* begin() const; + char* end(); + const char* end() const; + void push_front(char c); + void push_back(char c); + //char* rbegin(); + //const char* rbegin() const; + //char* rend(); + //const char* rend() const; - operator std::string() const; + typedef const char& const_reference; + typedef char* iterator; + //typedef char* reverse_iterator; + typedef char value_type; + // Méthodes STD - char& operator[](unsigned int pos); - char operator[](unsigned int pos) const; + operator std::string() const; - NzString& operator=(char character); - NzString& operator=(const char* string); - NzString& operator=(const std::string& string); - NzString& operator=(const NzString& string); - NzString& operator=(NzString&& string) noexcept; + char& operator[](unsigned int pos); + char operator[](unsigned int pos) const; - NzString operator+(char character) const; - NzString operator+(const char* string) const; - NzString operator+(const std::string& string) const; - NzString operator+(const NzString& string) const; + String& operator=(char character); + String& operator=(const char* string); + String& operator=(const std::string& string); + String& operator=(const String& string); + String& operator=(String&& string) noexcept; - NzString& operator+=(char character); - NzString& operator+=(const char* string); - NzString& operator+=(const std::string& string); - NzString& operator+=(const NzString& string); + String operator+(char character) const; + String operator+(const char* string) const; + String operator+(const std::string& string) const; + String operator+(const String& string) const; - bool operator==(char character) const; - bool operator==(const char* string) const; - bool operator==(const std::string& string) const; + String& operator+=(char character); + String& operator+=(const char* string); + String& operator+=(const std::string& string); + String& operator+=(const String& string); - bool operator!=(char character) const; - bool operator!=(const char* string) const; - bool operator!=(const std::string& string) const; + bool operator==(char character) const; + bool operator==(const char* string) const; + bool operator==(const std::string& string) const; - bool operator<(char character) const; - bool operator<(const char* string) const; - bool operator<(const std::string& string) const; + bool operator!=(char character) const; + bool operator!=(const char* string) const; + bool operator!=(const std::string& string) const; - bool operator<=(char character) const; - bool operator<=(const char* string) const; - bool operator<=(const std::string& string) const; + bool operator<(char character) const; + bool operator<(const char* string) const; + bool operator<(const std::string& string) const; - bool operator>(char character) const; - bool operator>(const char* string) const; - bool operator>(const std::string& string) const; + bool operator<=(char character) const; + bool operator<=(const char* string) const; + bool operator<=(const std::string& string) const; - bool operator>=(char character) const; - bool operator>=(const char* string) const; - bool operator>=(const std::string& string) const; + bool operator>(char character) const; + bool operator>(const char* string) const; + bool operator>(const std::string& string) const; - static NzString Boolean(bool boolean); - static int Compare(const NzString& first, const NzString& second); - static NzString Number(float number); - static NzString Number(double number); - static NzString Number(long double number); - static NzString Number(signed char number, nzUInt8 radix = 10); - static NzString Number(unsigned char number, nzUInt8 radix = 10); - static NzString Number(short number, nzUInt8 radix = 10); - static NzString Number(unsigned short number, nzUInt8 radix = 10); - static NzString Number(int number, nzUInt8 radix = 10); - static NzString Number(unsigned int number, nzUInt8 radix = 10); - static NzString Number(long number, nzUInt8 radix = 10); - static NzString Number(unsigned long number, nzUInt8 radix = 10); - static NzString Number(long long number, nzUInt8 radix = 10); - static NzString Number(unsigned long long number, nzUInt8 radix = 10); - static NzString Pointer(const void* ptr); - static NzString Unicode(char32_t character); - static NzString Unicode(const char* u8String); - static NzString Unicode(const char16_t* u16String); - static NzString Unicode(const char32_t* u32String); - static NzString Unicode(const wchar_t* wString); + bool operator>=(char character) const; + bool operator>=(const char* string) const; + bool operator>=(const std::string& string) const; - NAZARA_CORE_API friend std::istream& operator>>(std::istream& in, NzString& string); - NAZARA_CORE_API friend std::ostream& operator<<(std::ostream& out, const NzString& string); + static String Boolean(bool boolean); + static int Compare(const String& first, const String& second); + static String Number(float number); + static String Number(double number); + static String Number(long double number); + static String Number(signed char number, UInt8 radix = 10); + static String Number(unsigned char number, UInt8 radix = 10); + static String Number(short number, UInt8 radix = 10); + static String Number(unsigned short number, UInt8 radix = 10); + static String Number(int number, UInt8 radix = 10); + static String Number(unsigned int number, UInt8 radix = 10); + static String Number(long number, UInt8 radix = 10); + static String Number(unsigned long number, UInt8 radix = 10); + static String Number(long long number, UInt8 radix = 10); + static String Number(unsigned long long number, UInt8 radix = 10); + static String Pointer(const void* ptr); + static String Unicode(char32_t character); + static String Unicode(const char* u8String); + static String Unicode(const char16_t* u16String); + static String Unicode(const char32_t* u32String); + static String Unicode(const wchar_t* wString); - NAZARA_CORE_API friend NzString operator+(char character, const NzString& string); - NAZARA_CORE_API friend NzString operator+(const char* string, const NzString& nstring); - NAZARA_CORE_API friend NzString operator+(const std::string& string, const NzString& nstring); + NAZARA_CORE_API friend std::istream& operator>>(std::istream& in, String& string); + NAZARA_CORE_API friend std::ostream& operator<<(std::ostream& out, const String& string); - NAZARA_CORE_API friend bool operator==(const NzString& first, const NzString& second); - NAZARA_CORE_API friend bool operator!=(const NzString& first, const NzString& second); - NAZARA_CORE_API friend bool operator<(const NzString& first, const NzString& second); - NAZARA_CORE_API friend bool operator<=(const NzString& first, const NzString& second); - NAZARA_CORE_API friend bool operator>(const NzString& first, const NzString& second); - NAZARA_CORE_API friend bool operator>=(const NzString& first, const NzString& second); + NAZARA_CORE_API friend String operator+(char character, const String& string); + NAZARA_CORE_API friend String operator+(const char* string, const String& nstring); + NAZARA_CORE_API friend String operator+(const std::string& string, const String& nstring); - NAZARA_CORE_API friend bool operator==(char character, const NzString& nstring); - NAZARA_CORE_API friend bool operator==(const char* string, const NzString& nstring); - NAZARA_CORE_API friend bool operator==(const std::string& string, const NzString& nstring); + NAZARA_CORE_API friend bool operator==(const String& first, const String& second); + NAZARA_CORE_API friend bool operator!=(const String& first, const String& second); + NAZARA_CORE_API friend bool operator<(const String& first, const String& second); + NAZARA_CORE_API friend bool operator<=(const String& first, const String& second); + NAZARA_CORE_API friend bool operator>(const String& first, const String& second); + NAZARA_CORE_API friend bool operator>=(const String& first, const String& second); - NAZARA_CORE_API friend bool operator!=(char character, const NzString& nstring); - NAZARA_CORE_API friend bool operator!=(const char* string, const NzString& nstring); - NAZARA_CORE_API friend bool operator!=(const std::string& string, const NzString& nstring); + NAZARA_CORE_API friend bool operator==(char character, const String& nstring); + NAZARA_CORE_API friend bool operator==(const char* string, const String& nstring); + NAZARA_CORE_API friend bool operator==(const std::string& string, const String& nstring); - NAZARA_CORE_API friend bool operator<(char character, const NzString& nstring); - NAZARA_CORE_API friend bool operator<(const char* string, const NzString& nstring); - NAZARA_CORE_API friend bool operator<(const std::string& string, const NzString& nstring); + NAZARA_CORE_API friend bool operator!=(char character, const String& nstring); + NAZARA_CORE_API friend bool operator!=(const char* string, const String& nstring); + NAZARA_CORE_API friend bool operator!=(const std::string& string, const String& nstring); - NAZARA_CORE_API friend bool operator<=(char character, const NzString& nstring); - NAZARA_CORE_API friend bool operator<=(const char* string, const NzString& nstring); - NAZARA_CORE_API friend bool operator<=(const std::string& string, const NzString& nstring); + NAZARA_CORE_API friend bool operator<(char character, const String& nstring); + NAZARA_CORE_API friend bool operator<(const char* string, const String& nstring); + NAZARA_CORE_API friend bool operator<(const std::string& string, const String& nstring); - NAZARA_CORE_API friend bool operator>(char character, const NzString& nstring); - NAZARA_CORE_API friend bool operator>(const char* string, const NzString& nstring); - NAZARA_CORE_API friend bool operator>(const std::string& string, const NzString& nstring); + NAZARA_CORE_API friend bool operator<=(char character, const String& nstring); + NAZARA_CORE_API friend bool operator<=(const char* string, const String& nstring); + NAZARA_CORE_API friend bool operator<=(const std::string& string, const String& nstring); - NAZARA_CORE_API friend bool operator>=(char character, const NzString& nstring); - NAZARA_CORE_API friend bool operator>=(const char* string, const NzString& nstring); - NAZARA_CORE_API friend bool operator>=(const std::string& string, const NzString& nstring); + NAZARA_CORE_API friend bool operator>(char character, const String& nstring); + NAZARA_CORE_API friend bool operator>(const char* string, const String& nstring); + NAZARA_CORE_API friend bool operator>(const std::string& string, const String& nstring); - static const unsigned int npos; + NAZARA_CORE_API friend bool operator>=(char character, const String& nstring); + NAZARA_CORE_API friend bool operator>=(const char* string, const String& nstring); + NAZARA_CORE_API friend bool operator>=(const std::string& string, const String& nstring); - private: - struct SharedString; + static const unsigned int npos; - NzString(std::shared_ptr&& sharedString); + private: + struct SharedString; - void EnsureOwnership(bool discardContent = false); - bool FillHash(NzAbstractHash* hash) const; - inline void ReleaseString(); + String(std::shared_ptr&& sharedString); - static const std::shared_ptr& GetEmptyString(); + void EnsureOwnership(bool discardContent = false); + bool FillHash(AbstractHash* hash) const; + inline void ReleaseString(); - std::shared_ptr m_sharedString; + static const std::shared_ptr& GetEmptyString(); - struct SharedString - { - inline SharedString(); - inline SharedString(unsigned int strSize); + std::shared_ptr m_sharedString; - unsigned int capacity; - unsigned int size; - std::unique_ptr string; - }; -}; + struct SharedString + { + inline SharedString(); + inline SharedString(unsigned int strSize); + + unsigned int capacity; + unsigned int size; + std::unique_ptr string; + }; + }; +} namespace std { - NAZARA_CORE_API istream& getline(istream& is, NzString& str); - NAZARA_CORE_API istream& getline(istream& is, NzString& str, char delim); - NAZARA_CORE_API void swap(NzString& lhs, NzString& rhs); + NAZARA_CORE_API istream& getline(istream& is, Nz::String& str); + NAZARA_CORE_API istream& getline(istream& is, Nz::String& str, char delim); + NAZARA_CORE_API void swap(Nz::String& lhs, Nz::String& rhs); } #include diff --git a/include/Nazara/Core/String.inl b/include/Nazara/Core/String.inl index cb07298a8..656a56121 100644 --- a/include/Nazara/Core/String.inl +++ b/include/Nazara/Core/String.inl @@ -4,37 +4,39 @@ #include -inline NzString::NzString(std::shared_ptr&& sharedString) : -m_sharedString(std::move(sharedString)) +namespace Nz { -} + inline String::String(std::shared_ptr&& sharedString) : + m_sharedString(std::move(sharedString)) + { + } -inline void NzString::ReleaseString() -{ - m_sharedString = std::move(GetEmptyString()); -} + inline void String::ReleaseString() + { + m_sharedString = std::move(GetEmptyString()); + } -inline NzString::SharedString::SharedString() : // Special case: empty string -capacity(0), -size(0) -{ -} + inline String::SharedString::SharedString() : // Special case: empty string + capacity(0), + size(0) + { + } -inline NzString::SharedString::SharedString(unsigned int strSize) : -capacity(strSize), -size(strSize), -string(new char[strSize + 1]) -{ - string[strSize] = '\0'; + inline String::SharedString::SharedString(unsigned int strSize) : + capacity(strSize), + size(strSize), + string(new char[strSize + 1]) + { + string[strSize] = '\0'; + } } - namespace std { template<> - struct hash + struct hash { - size_t operator()(const NzString& str) const + size_t operator()(const Nz::String& str) const { // Algorithme DJB2 // http://www.cse.yorku.ca/~oz/hash.html diff --git a/include/Nazara/Core/StringStream.hpp b/include/Nazara/Core/StringStream.hpp index da9521b35..c34209433 100644 --- a/include/Nazara/Core/StringStream.hpp +++ b/include/Nazara/Core/StringStream.hpp @@ -12,43 +12,46 @@ #include #include -class NAZARA_CORE_API NzStringStream +namespace Nz { - public: - NzStringStream(); - NzStringStream(const NzString& str); - NzStringStream(const NzStringStream&) = default; - NzStringStream(NzStringStream&&) noexcept = default; + class NAZARA_CORE_API StringStream + { + public: + StringStream(); + StringStream(const String& str); + StringStream(const StringStream&) = default; + StringStream(StringStream&&) noexcept = default; - NzString ToString() const; + String ToString() const; - NzStringStream& operator=(const NzStringStream&) = default; - NzStringStream& operator=(NzStringStream&&) noexcept = default; + StringStream& operator=(const StringStream&) = default; + StringStream& operator=(StringStream&&) noexcept = default; - NzStringStream& operator<<(bool boolean); - NzStringStream& operator<<(short number); - NzStringStream& operator<<(unsigned short number); - NzStringStream& operator<<(int number); - NzStringStream& operator<<(unsigned int number); - NzStringStream& operator<<(long number); - NzStringStream& operator<<(unsigned long number); - NzStringStream& operator<<(long long number); - NzStringStream& operator<<(unsigned long long number); - NzStringStream& operator<<(float number); - NzStringStream& operator<<(double number); - NzStringStream& operator<<(long double number); - NzStringStream& operator<<(char character); - NzStringStream& operator<<(unsigned char character); - NzStringStream& operator<<(const char* string); - NzStringStream& operator<<(const std::string& string); - NzStringStream& operator<<(const NzString& string); - NzStringStream& operator<<(const void* ptr); + StringStream& operator<<(bool boolean); + StringStream& operator<<(short number); + StringStream& operator<<(unsigned short number); + StringStream& operator<<(int number); + StringStream& operator<<(unsigned int number); + StringStream& operator<<(long number); + StringStream& operator<<(unsigned long number); + StringStream& operator<<(long long number); + StringStream& operator<<(unsigned long long number); + StringStream& operator<<(float number); + StringStream& operator<<(double number); + StringStream& operator<<(long double number); + StringStream& operator<<(char character); + StringStream& operator<<(unsigned char character); + StringStream& operator<<(const char* string); + StringStream& operator<<(const std::string& string); + StringStream& operator<<(const String& string); + StringStream& operator<<(const void* ptr); - operator NzString() const; + operator String() const; - private: - std::vector m_strings; - unsigned int m_bufferSize; -}; + private: + std::vector m_strings; + unsigned int m_bufferSize; + }; +} #endif // NAZARA_STRINGSTREAM_HPP diff --git a/include/Nazara/Core/TaskScheduler.hpp b/include/Nazara/Core/TaskScheduler.hpp index 4ce423db7..3a061168d 100644 --- a/include/Nazara/Core/TaskScheduler.hpp +++ b/include/Nazara/Core/TaskScheduler.hpp @@ -10,25 +10,28 @@ #include #include -class NAZARA_CORE_API NzTaskScheduler +namespace Nz { - public: - NzTaskScheduler() = delete; - ~NzTaskScheduler() = delete; + class NAZARA_CORE_API TaskScheduler + { + public: + TaskScheduler() = delete; + ~TaskScheduler() = delete; - template static void AddTask(F function); - template static void AddTask(F function, Args&&... args); - template static void AddTask(void (C::*function)(), C* object); - static unsigned int GetWorkerCount(); - static bool Initialize(); - static void Run(); - static void SetWorkerCount(unsigned int workerCount); - static void Uninitialize(); - static void WaitForTasks(); + template static void AddTask(F function); + template static void AddTask(F function, Args&&... args); + template static void AddTask(void (C::*function)(), C* object); + static unsigned int GetWorkerCount(); + static bool Initialize(); + static void Run(); + static void SetWorkerCount(unsigned int workerCount); + static void Uninitialize(); + static void WaitForTasks(); - private: - static void AddTaskFunctor(NzFunctor* taskFunctor); -}; + private: + static void AddTaskFunctor(Functor* taskFunctor); + }; +} #include diff --git a/include/Nazara/Core/TaskScheduler.inl b/include/Nazara/Core/TaskScheduler.inl index 5230f260b..b8b99ed47 100644 --- a/include/Nazara/Core/TaskScheduler.inl +++ b/include/Nazara/Core/TaskScheduler.inl @@ -4,22 +4,25 @@ #include -template -void NzTaskScheduler::AddTask(F function) +namespace Nz { - AddTaskFunctor(new NzFunctorWithoutArgs(function)); -} + template + void TaskScheduler::AddTask(F function) + { + AddTaskFunctor(new FunctorWithoutArgs(function)); + } -template -void NzTaskScheduler::AddTask(F function, Args&&... args) -{ - AddTaskFunctor(new NzFunctorWithArgs(function, std::forward(args)...)); -} + template + void TaskScheduler::AddTask(F function, Args&&... args) + { + AddTaskFunctor(new FunctorWithArgs(function, std::forward(args)...)); + } -template -void NzTaskScheduler::AddTask(void (C::*function)(), C* object) -{ - AddTaskFunctor(new NzMemberWithoutArgs(function, object)); + template + void TaskScheduler::AddTask(void (C::*function)(), C* object) + { + AddTaskFunctor(new MemberWithoutArgs(function, object)); + } } #include diff --git a/include/Nazara/Core/Thread.hpp b/include/Nazara/Core/Thread.hpp index 5be32e7ad..4e4dd4efb 100644 --- a/include/Nazara/Core/Thread.hpp +++ b/include/Nazara/Core/Thread.hpp @@ -11,57 +11,60 @@ #include #include -class NzThreadImpl; - -class NAZARA_CORE_API NzThread +namespace Nz { - public: - class Id; + class ThreadImpl; - NzThread(); - template NzThread(F function); - template NzThread(F function, Args&&... args); - template NzThread(void (C::*function)(), C* object); - NzThread(const NzThread&) = delete; - NzThread(NzThread&& other) noexcept; - ~NzThread(); + class NAZARA_CORE_API Thread + { + public: + class Id; - void Detach(); - Id GetId() const; - bool IsJoinable() const; - void Join(); + Thread(); + template Thread(F function); + template Thread(F function, Args&&... args); + template Thread(void (C::*function)(), C* object); + Thread(const Thread&) = delete; + Thread(Thread&& other) noexcept; + ~Thread(); - NzThread& operator=(const NzThread&) = delete; - NzThread& operator=(NzThread&& thread); + void Detach(); + Id GetId() const; + bool IsJoinable() const; + void Join(); - static unsigned int HardwareConcurrency(); - static void Sleep(nzUInt32 milliseconds); + Thread& operator=(const Thread&) = delete; + Thread& operator=(Thread&& thread); - private: - void CreateImpl(NzFunctor* functor); + static unsigned int HardwareConcurrency(); + static void Sleep(UInt32 milliseconds); - NzThreadImpl* m_impl; -}; + private: + void CreateImpl(Functor* functor); -class NAZARA_CORE_API NzThread::Id -{ - friend NzThread; + ThreadImpl* m_impl; + }; - public: - NAZARA_CORE_API friend bool operator==(const Id& lhs, const Id& rhs); - NAZARA_CORE_API friend bool operator!=(const Id& lhs, const Id& rhs); - NAZARA_CORE_API friend bool operator<(const Id& lhs, const Id& rhs); - NAZARA_CORE_API friend bool operator<=(const Id& lhs, const Id& rhs); - NAZARA_CORE_API friend bool operator>(const Id& lhs, const Id& rhs); - NAZARA_CORE_API friend bool operator>=(const Id& lhs, const Id& rhs); + class NAZARA_CORE_API Thread::Id + { + friend Thread; - NAZARA_CORE_API friend std::ostream& operator<<(std::ostream& o, const Id& id); + public: + NAZARA_CORE_API friend bool operator==(const Id& lhs, const Id& rhs); + NAZARA_CORE_API friend bool operator!=(const Id& lhs, const Id& rhs); + NAZARA_CORE_API friend bool operator<(const Id& lhs, const Id& rhs); + NAZARA_CORE_API friend bool operator<=(const Id& lhs, const Id& rhs); + NAZARA_CORE_API friend bool operator>(const Id& lhs, const Id& rhs); + NAZARA_CORE_API friend bool operator>=(const Id& lhs, const Id& rhs); - private: - Id(NzThreadImpl* thread); + NAZARA_CORE_API friend std::ostream& operator<<(std::ostream& o, const Id& id); - NzThreadImpl* m_id = nullptr; -}; + private: + Id(ThreadImpl* thread); + + ThreadImpl* m_id = nullptr; + }; +} #include diff --git a/include/Nazara/Core/Thread.inl b/include/Nazara/Core/Thread.inl index 8e4c60181..d6c76522a 100644 --- a/include/Nazara/Core/Thread.inl +++ b/include/Nazara/Core/Thread.inl @@ -5,22 +5,25 @@ #include #include -template -NzThread::NzThread(F function) +namespace Nz { - CreateImpl(new NzFunctorWithoutArgs(function)); -} + template + Thread::Thread(F function) + { + CreateImpl(new FunctorWithoutArgs(function)); + } -template -NzThread::NzThread(F function, Args&&... args) -{ - CreateImpl(new NzFunctorWithArgs(function, std::forward(args)...)); -} + template + Thread::Thread(F function, Args&&... args) + { + CreateImpl(new FunctorWithArgs(function, std::forward(args)...)); + } -template -NzThread::NzThread(void (C::*function)(), C* object) -{ - CreateImpl(new NzMemberWithoutArgs(function, object)); + template + Thread::Thread(void (C::*function)(), C* object) + { + CreateImpl(new MemberWithoutArgs(function, object)); + } } #include diff --git a/include/Nazara/Core/ThreadSafety.hpp b/include/Nazara/Core/ThreadSafety.hpp index 7eb5bbf0b..26b446ae6 100644 --- a/include/Nazara/Core/ThreadSafety.hpp +++ b/include/Nazara/Core/ThreadSafety.hpp @@ -15,9 +15,9 @@ #undef NazaraMutexUnlock #undef NazaraNamedLock -#define NazaraLock(mutex) NzLockGuard lock_mutex(mutex); -#define NazaraMutex(name) NzMutex name; -#define NazaraMutexAttrib(name, attribute) attribute NzMutex name; +#define NazaraLock(mutex) Nz::LockGuard lock_mutex(mutex); +#define NazaraMutex(name) Nz::Mutex name; +#define NazaraMutexAttrib(name, attribute) attribute Mutex name; #define NazaraMutexLock(mutex) mutex.Lock(); #define NazaraMutexUnlock(mutex) mutex.Unlock(); -#define NazaraNamedLock(mutex, name) NzLockGuard lock_##name(mutex); +#define NazaraNamedLock(mutex, name) Nz::LockGuard lock_##name(mutex); diff --git a/include/Nazara/Core/Unicode.hpp b/include/Nazara/Core/Unicode.hpp index bc086ee46..6aa8794ce 100644 --- a/include/Nazara/Core/Unicode.hpp +++ b/include/Nazara/Core/Unicode.hpp @@ -9,99 +9,104 @@ #include -class NzUnicode +namespace Nz { - public: - /* - Catégorie Unicode: - -Les valeurs de 0x01 à 0x80 indiquent la catégorie. - -Les valeurs de 0x100 à 0x10000 indiquent la sous-catégorie. - */ - enum Category : nzUInt16 - { - // Catégorie non-reconnue par Nazara - Category_NoCategory = 0, + class Unicode + { + public: + Unicode() = delete; + ~Unicode() = delete; + /* + Catégorie Unicode: + -Les valeurs de 0x01 à 0x80 indiquent la catégorie. + -Les valeurs de 0x100 à 0x10000 indiquent la sous-catégorie. + */ + enum Category : UInt16 + { + // Catégorie non-reconnue par Nazara + Category_NoCategory = 0, - // Lettres - Category_Letter = 0x01, // L - Category_Letter_Lowercase = Category_Letter | 0x0100, // Ll - Category_Letter_Modifier = Category_Letter | 0x0200, // Lm - Category_Letter_Other = Category_Letter | 0x0400, // Lo - Category_Letter_Titlecase = Category_Letter | 0x0800, // Lt - Category_Letter_Uppercase = Category_Letter | 0x1000, // Lu + // Lettres + Category_Letter = 0x01, // L + Category_Letter_Lowercase = Category_Letter | 0x0100, // Ll + Category_Letter_Modifier = Category_Letter | 0x0200, // Lm + Category_Letter_Other = Category_Letter | 0x0400, // Lo + Category_Letter_Titlecase = Category_Letter | 0x0800, // Lt + Category_Letter_Uppercase = Category_Letter | 0x1000, // Lu - // Marques - Category_Mark = 0x02, // M - Category_Mark_Enclosing = Category_Mark | 0x100, // Me - Category_Mark_NonSpacing = Category_Mark | 0x200, // Mn - Category_Mark_SpacingCombining = Category_Mark | 0x400, // Mc + // Marques + Category_Mark = 0x02, // M + Category_Mark_Enclosing = Category_Mark | 0x100, // Me + Category_Mark_NonSpacing = Category_Mark | 0x200, // Mn + Category_Mark_SpacingCombining = Category_Mark | 0x400, // Mc - // Nombres - Category_Number = 0x04, // N - Category_Number_DecimalDigit = Category_Number | 0x100, // Nd - Category_Number_Letter = Category_Number | 0x200, // Nl - Category_Number_Other = Category_Number | 0x400, // No + // Nombres + Category_Number = 0x04, // N + Category_Number_DecimalDigit = Category_Number | 0x100, // Nd + Category_Number_Letter = Category_Number | 0x200, // Nl + Category_Number_Other = Category_Number | 0x400, // No - // Autres - Category_Other = 0x08, // C - Category_Other_Control = Category_Other | 0x0100, // Cc - Category_Other_Format = Category_Other | 0x0200, // Cf - Category_Other_NotAssigned = Category_Other | 0x0400, // Cn - Category_Other_PrivateUse = Category_Other | 0x0800, // Co - Category_Other_Surrogate = Category_Other | 0x1000, // Cs + // Autres + Category_Other = 0x08, // C + Category_Other_Control = Category_Other | 0x0100, // Cc + Category_Other_Format = Category_Other | 0x0200, // Cf + Category_Other_NotAssigned = Category_Other | 0x0400, // Cn + Category_Other_PrivateUse = Category_Other | 0x0800, // Co + Category_Other_Surrogate = Category_Other | 0x1000, // Cs - // Ponctuations - Category_Punctuation = 0x10, // P - Category_Punctuation_Close = Category_Punctuation | 0x0100, // Pe - Category_Punctuation_Connector = Category_Punctuation | 0x0200, // Pc - Category_Punctuation_Dash = Category_Punctuation | 0x0400, // Pd - Category_Punctuation_FinalQuote = Category_Punctuation | 0x0800, // Pf - Category_Punctuation_InitialQuote = Category_Punctuation | 0x1000, // Pi - Category_Punctuation_Open = Category_Punctuation | 0x2000, // Ps - Category_Punctuation_Other = Category_Punctuation | 0x4000, // Po + // Ponctuations + Category_Punctuation = 0x10, // P + Category_Punctuation_Close = Category_Punctuation | 0x0100, // Pe + Category_Punctuation_Connector = Category_Punctuation | 0x0200, // Pc + Category_Punctuation_Dash = Category_Punctuation | 0x0400, // Pd + Category_Punctuation_FinalQuote = Category_Punctuation | 0x0800, // Pf + Category_Punctuation_InitialQuote = Category_Punctuation | 0x1000, // Pi + Category_Punctuation_Open = Category_Punctuation | 0x2000, // Ps + Category_Punctuation_Other = Category_Punctuation | 0x4000, // Po - // Espacements - Category_Separator = 0x20, // Z - Category_Separator_Line = Category_Separator | 0x0100, // Zl - Category_Separator_Paragraph = Category_Separator | 0x0200, // Zp - Category_Separator_Space = Category_Separator | 0x0400, // Zs + // Espacements + Category_Separator = 0x20, // Z + Category_Separator_Line = Category_Separator | 0x0100, // Zl + Category_Separator_Paragraph = Category_Separator | 0x0200, // Zp + Category_Separator_Space = Category_Separator | 0x0400, // Zs - // Symboles - Category_Symbol = 0x40, // S - Category_Symbol_Currency = Category_Symbol | 0x0100, // Sc - Category_Symbol_Math = Category_Symbol | 0x0200, // Sm - Category_Symbol_Modifier = Category_Symbol | 0x0400, // Sk - Category_Symbol_Other = Category_Symbol | 0x0800 // So - }; + // Symboles + Category_Symbol = 0x40, // S + Category_Symbol_Currency = Category_Symbol | 0x0100, // Sc + Category_Symbol_Math = Category_Symbol | 0x0200, // Sm + Category_Symbol_Modifier = Category_Symbol | 0x0400, // Sk + Category_Symbol_Other = Category_Symbol | 0x0800 // So + }; - enum Direction : nzUInt8 - { - Direction_Arabic_Letter, // AL - Direction_Arabic_Number, // AN - Direction_Boundary_Neutral, // BN - Direction_Common_Separator, // CS - Direction_European_Number, // EN - Direction_European_Separator, // ES - Direction_European_Terminator, // ET - Direction_Left_To_Right, // L - Direction_Left_To_Right_Embedding, // LRE - Direction_Left_To_Right_Override, // LRO - Direction_Nonspacing_Mark, // NSM - Direction_Other_Neutral, // ON - Direction_Paragraph_Separator, // B - Direction_Pop_Directional_Format, // PDF - Direction_Right_To_Left, // R - Direction_Right_To_Left_Embedding, // RLE - Direction_Right_To_Left_Override, // RLO - Direction_Segment_Separator, // S - Direction_White_Space // WS - }; + enum Direction : UInt8 + { + Direction_Arabic_Letter, // AL + Direction_Arabic_Number, // AN + Direction_Boundary_Neutral, // BN + Direction_Common_Separator, // CS + Direction_European_Number, // EN + Direction_European_Separator, // ES + Direction_European_Terminator, // ET + Direction_Left_To_Right, // L + Direction_Left_To_Right_Embedding, // LRE + Direction_Left_To_Right_Override, // LRO + Direction_Nonspacing_Mark, // NSM + Direction_Other_Neutral, // ON + Direction_Paragraph_Separator, // B + Direction_Pop_Directional_Format, // PDF + Direction_Right_To_Left, // R + Direction_Right_To_Left_Embedding, // RLE + Direction_Right_To_Left_Override, // RLO + Direction_Segment_Separator, // S + Direction_White_Space // WS + }; - static Category GetCategory(char32_t character); - static Direction GetDirection(char32_t character); - static char32_t GetLowercase(char32_t character); - static char32_t GetTitlecase(char32_t character); - static char32_t GetUppercase(char32_t character); -}; + static Category GetCategory(char32_t character); + static Direction GetDirection(char32_t character); + static char32_t GetLowercase(char32_t character); + static char32_t GetTitlecase(char32_t character); + static char32_t GetUppercase(char32_t character); + }; +} #endif // NAZARA_UNICODE_HPP diff --git a/include/Nazara/Core/Updatable.hpp b/include/Nazara/Core/Updatable.hpp index e738cf9a4..fd93dafe8 100644 --- a/include/Nazara/Core/Updatable.hpp +++ b/include/Nazara/Core/Updatable.hpp @@ -9,13 +9,16 @@ #include -class NAZARA_CORE_API NzUpdatable +namespace Nz { - public: - NzUpdatable() = default; - virtual ~NzUpdatable(); + class NAZARA_CORE_API Updatable + { + public: + Updatable() = default; + virtual ~Updatable(); - virtual void Update() = 0; -}; + virtual void Update() = 0; + }; +} #endif // NAZARA_UPDATABLE_HPP diff --git a/include/Nazara/Graphics/AbstractBackground.hpp b/include/Nazara/Graphics/AbstractBackground.hpp index 3d57462e0..8e21326e5 100644 --- a/include/Nazara/Graphics/AbstractBackground.hpp +++ b/include/Nazara/Graphics/AbstractBackground.hpp @@ -13,30 +13,33 @@ #include #include -class NzAbstractBackground; -class NzAbstractViewer; - -using NzBackgroundConstRef = NzObjectRef; -using NzBackgroundLibrary = NzObjectLibrary; -using NzBackgroundRef = NzObjectRef; - -class NAZARA_GRAPHICS_API NzAbstractBackground : public NzRefCounted +namespace Nz { - public: - NzAbstractBackground() = default; - NzAbstractBackground(const NzAbstractBackground&) = default; - NzAbstractBackground(NzAbstractBackground&&) = delete; - virtual ~NzAbstractBackground(); + class AbstractBackground; + class AbstractViewer; - virtual void Draw(const NzAbstractViewer* viewer) const = 0; + using BackgroundConstRef = ObjectRef; + using BackgroundLibrary = ObjectLibrary; + using BackgroundRef = ObjectRef; - virtual nzBackgroundType GetBackgroundType() const = 0; + class NAZARA_GRAPHICS_API AbstractBackground : public RefCounted + { + public: + AbstractBackground() = default; + AbstractBackground(const AbstractBackground&) = default; + AbstractBackground(AbstractBackground&&) = delete; + virtual ~AbstractBackground(); - NzAbstractBackground& operator=(const NzAbstractBackground&) = default; - NzAbstractBackground& operator=(NzAbstractBackground&&) = delete; + virtual void Draw(const AbstractViewer* viewer) const = 0; - private: - static NzBackgroundLibrary::LibraryMap s_library; -}; + virtual BackgroundType GetBackgroundType() const = 0; + + AbstractBackground& operator=(const AbstractBackground&) = default; + AbstractBackground& operator=(AbstractBackground&&) = delete; + + private: + static BackgroundLibrary::LibraryMap s_library; + }; +} #endif // NAZARA_ABSTRACTBACKGROUND_HPP diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index a02c09c88..d5e4554b9 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -17,83 +17,86 @@ #include #include -class NzDrawable; -class NzMaterial; -class NzTexture; -struct NzMeshData; - -class NAZARA_GRAPHICS_API NzAbstractRenderQueue +namespace Nz { - public: - struct DirectionalLight; - struct PointLight; - struct SpotLight; + class Drawable; + class Material; + class Texture; + struct MeshData; - NzAbstractRenderQueue() = default; - NzAbstractRenderQueue(const NzAbstractRenderQueue&) = delete; - NzAbstractRenderQueue(NzAbstractRenderQueue&&) = default; - virtual ~NzAbstractRenderQueue(); + class NAZARA_GRAPHICS_API AbstractRenderQueue + { + public: + struct DirectionalLight; + struct PointLight; + struct SpotLight; - // 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 AddDirectionalLight(const DirectionalLight& light); - virtual void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) = 0; - virtual void AddPointLight(const PointLight& light); - virtual void AddSpotLight(const SpotLight& light); - virtual void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay = nullptr) = 0; + AbstractRenderQueue() = default; + AbstractRenderQueue(const AbstractRenderQueue&) = delete; + AbstractRenderQueue(AbstractRenderQueue&&) = default; + virtual ~AbstractRenderQueue(); - virtual void Clear(bool fully = false); + // 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 Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) = 0; + virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) = 0; + virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) = 0; + virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) = 0; + virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) = 0; + virtual void AddDrawable(const Drawable* drawable) = 0; + virtual void AddDirectionalLight(const DirectionalLight& light); + virtual void AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) = 0; + virtual void AddPointLight(const PointLight& light); + virtual void AddSpotLight(const SpotLight& light); + virtual void AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) = 0; - NzAbstractRenderQueue& operator=(const NzAbstractRenderQueue&) = delete; - NzAbstractRenderQueue& operator=(NzAbstractRenderQueue&&) = default; + virtual void Clear(bool fully = false); - struct DirectionalLight - { - NzColor color; - NzVector3f direction; - float ambientFactor; - float diffuseFactor; - }; + AbstractRenderQueue& operator=(const AbstractRenderQueue&) = delete; + AbstractRenderQueue& operator=(AbstractRenderQueue&&) = default; - struct PointLight - { - NzColor color; - NzVector3f position; - float ambientFactor; - float attenuation; - float diffuseFactor; - float invRadius; - float radius; - }; + struct DirectionalLight + { + Color color; + Vector3f direction; + float ambientFactor; + float diffuseFactor; + }; - struct SpotLight - { - NzColor color; - NzVector3f direction; - NzVector3f position; - float ambientFactor; - float attenuation; - float diffuseFactor; - float innerAngleCosine; - float invRadius; - float outerAngleCosine; - float outerAngleTangent; - float radius; - }; + struct PointLight + { + Color color; + Vector3f position; + float ambientFactor; + float attenuation; + float diffuseFactor; + float invRadius; + float radius; + }; - std::vector directionalLights; - std::vector pointLights; - std::vector spotLights; -}; + struct SpotLight + { + Color color; + Vector3f direction; + Vector3f position; + float ambientFactor; + float attenuation; + float diffuseFactor; + float innerAngleCosine; + float invRadius; + float outerAngleCosine; + float outerAngleTangent; + float radius; + }; + + std::vector directionalLights; + std::vector pointLights; + std::vector spotLights; + }; +} #endif // NAZARA_ABSTRACTRENDERQUEUE_HPP diff --git a/include/Nazara/Graphics/AbstractRenderTechnique.hpp b/include/Nazara/Graphics/AbstractRenderTechnique.hpp index a6d62b78f..5f268275e 100644 --- a/include/Nazara/Graphics/AbstractRenderTechnique.hpp +++ b/include/Nazara/Graphics/AbstractRenderTechnique.hpp @@ -14,33 +14,36 @@ #include #include -class NzAbstractViewer; -class NzBackground; -struct SceneData; - -class NAZARA_GRAPHICS_API NzAbstractRenderTechnique +namespace Nz { - public: - NzAbstractRenderTechnique(); - NzAbstractRenderTechnique(const NzAbstractRenderTechnique&) = delete; - NzAbstractRenderTechnique(NzAbstractRenderTechnique&&) = default; - virtual ~NzAbstractRenderTechnique(); + class AbstractViewer; + class Background; + struct SceneData; - virtual bool Draw(const NzSceneData& sceneData) const = 0; + class NAZARA_GRAPHICS_API AbstractRenderTechnique + { + public: + AbstractRenderTechnique(); + AbstractRenderTechnique(const AbstractRenderTechnique&) = delete; + AbstractRenderTechnique(AbstractRenderTechnique&&) = default; + virtual ~AbstractRenderTechnique(); - virtual void EnableInstancing(bool instancing); + virtual bool Draw(const SceneData& sceneData) const = 0; - virtual NzString GetName() const; - virtual NzAbstractRenderQueue* GetRenderQueue() = 0; - virtual nzRenderTechniqueType GetType() const = 0; + virtual void EnableInstancing(bool instancing); - virtual bool IsInstancingEnabled() const; + virtual String GetName() const; + virtual AbstractRenderQueue* GetRenderQueue() = 0; + virtual RenderTechniqueType GetType() const = 0; - NzAbstractRenderTechnique& operator=(const NzAbstractRenderTechnique&) = delete; - NzAbstractRenderTechnique& operator=(NzAbstractRenderTechnique&&) = default; + virtual bool IsInstancingEnabled() const; - protected: - bool m_instancingEnabled; -}; + AbstractRenderTechnique& operator=(const AbstractRenderTechnique&) = delete; + AbstractRenderTechnique& operator=(AbstractRenderTechnique&&) = default; + + protected: + bool m_instancingEnabled; + }; +} #endif // NAZARA_ABSTRACTRENDERTECHNIQUE_HPP diff --git a/include/Nazara/Graphics/AbstractViewer.hpp b/include/Nazara/Graphics/AbstractViewer.hpp index c6baa1675..a38bb6bd7 100644 --- a/include/Nazara/Graphics/AbstractViewer.hpp +++ b/include/Nazara/Graphics/AbstractViewer.hpp @@ -14,32 +14,34 @@ #include #include -class NzRenderTarget; -class NzScene; - -class NAZARA_GRAPHICS_API NzAbstractViewer +namespace Nz { - public: - NzAbstractViewer() = default; - NzAbstractViewer(const NzAbstractViewer&) = default; - NzAbstractViewer(NzAbstractViewer&&) noexcept = default; - virtual ~NzAbstractViewer(); + class RenderTarget; - virtual void ApplyView() const = 0; + class NAZARA_GRAPHICS_API AbstractViewer + { + public: + AbstractViewer() = default; + AbstractViewer(const AbstractViewer&) = default; + AbstractViewer(AbstractViewer&&) noexcept = default; + virtual ~AbstractViewer(); - virtual float GetAspectRatio() const = 0; - virtual NzVector3f GetEyePosition() const = 0; - virtual NzVector3f GetForward() const = 0; - virtual const NzFrustumf& GetFrustum() const = 0; - virtual const NzMatrix4f& GetProjectionMatrix() const = 0; - virtual const NzRenderTarget* GetTarget() const = 0; - virtual const NzMatrix4f& GetViewMatrix() const = 0; - virtual const NzRecti& GetViewport() const = 0; - virtual float GetZFar() const = 0; - virtual float GetZNear() const = 0; + virtual void ApplyView() const = 0; - NzAbstractViewer& operator=(const NzAbstractViewer&) = default; - NzAbstractViewer& operator=(NzAbstractViewer&&) noexcept = default; -}; + virtual float GetAspectRatio() const = 0; + virtual Vector3f GetEyePosition() const = 0; + virtual Vector3f GetForward() const = 0; + virtual const Frustumf& GetFrustum() const = 0; + virtual const Matrix4f& GetProjectionMatrix() const = 0; + virtual const RenderTarget* GetTarget() const = 0; + virtual const Matrix4f& GetViewMatrix() const = 0; + virtual const Recti& GetViewport() const = 0; + virtual float GetZFar() const = 0; + virtual float GetZNear() const = 0; + + AbstractViewer& operator=(const AbstractViewer&) = default; + AbstractViewer& operator=(AbstractViewer&&) noexcept = default; + }; +} #endif // NAZARA_ABSTRACTVIEWER_HPP diff --git a/include/Nazara/Graphics/Billboard.hpp b/include/Nazara/Graphics/Billboard.hpp index 495ad403a..68a64a4b5 100644 --- a/include/Nazara/Graphics/Billboard.hpp +++ b/include/Nazara/Graphics/Billboard.hpp @@ -11,53 +11,56 @@ #include #include -class NzBillboard; - -using NzBillboardConstRef = NzObjectRef; -using NzBillboardLibrary = NzObjectLibrary; -using NzBillboardRef = NzObjectRef; - -class NAZARA_GRAPHICS_API NzBillboard : public NzInstancedRenderable +namespace Nz { - public: - inline NzBillboard(); - inline NzBillboard(NzMaterialRef material); - inline NzBillboard(NzTexture* texture); - inline NzBillboard(const NzBillboard& billboard); - NzBillboard(NzBillboard&&) = delete; - ~NzBillboard() = default; + class Billboard; - void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; + using BillboardConstRef = ObjectRef; + using BillboardLibrary = ObjectLibrary; + using BillboardRef = ObjectRef; - inline const NzColor& GetColor() const; - inline const NzMaterialRef& GetMaterial() const; - inline float GetRotation() const; - inline const NzVector2f& GetSize() const; + class NAZARA_GRAPHICS_API Billboard : public InstancedRenderable + { + public: + inline Billboard(); + inline Billboard(MaterialRef material); + inline Billboard(Texture* texture); + inline Billboard(const Billboard& billboard); + Billboard(Billboard&&) = delete; + ~Billboard() = default; - inline void SetColor(const NzColor& color); - inline void SetDefaultMaterial(); - inline void SetMaterial(NzMaterialRef material, bool resizeBillboard = true); - inline void SetRotation(float rotation); - inline void SetSize(const NzVector2f& size); - inline void SetSize(float sizeX, float sizeY); - inline void SetTexture(NzTextureRef texture, bool resizeBillboard = true); + void AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; - inline NzBillboard& operator=(const NzBillboard& billboard); - NzBillboard& operator=(NzBillboard&&) = delete; + inline const Color& GetColor() const; + inline const MaterialRef& GetMaterial() const; + inline float GetRotation() const; + inline const Vector2f& GetSize() const; - template static NzBillboardRef New(Args&&... args); + inline void SetColor(const Color& color); + inline void SetDefaultMaterial(); + inline void SetMaterial(MaterialRef material, bool resizeBillboard = true); + inline void SetRotation(float rotation); + inline void SetSize(const Vector2f& size); + inline void SetSize(float sizeX, float sizeY); + inline void SetTexture(TextureRef texture, bool resizeBillboard = true); - private: - void MakeBoundingVolume() const override; + inline Billboard& operator=(const Billboard& billboard); + Billboard& operator=(Billboard&&) = delete; - NzColor m_color; - NzMaterialRef m_material; - NzVector2f m_sinCos; - NzVector2f m_size; - float m_rotation; + template static BillboardRef New(Args&&... args); - static NzBillboardLibrary::LibraryMap s_library; -}; + private: + void MakeBoundingVolume() const override; + + Color m_color; + MaterialRef m_material; + Vector2f m_sinCos; + Vector2f m_size; + float m_rotation; + + static BillboardLibrary::LibraryMap s_library; + }; +} #include diff --git a/include/Nazara/Graphics/Billboard.inl b/include/Nazara/Graphics/Billboard.inl index 3698dd63d..4a8cde469 100644 --- a/include/Nazara/Graphics/Billboard.inl +++ b/include/Nazara/Graphics/Billboard.inl @@ -5,137 +5,140 @@ #include #include -inline NzBillboard::NzBillboard() +namespace Nz { - SetColor(NzColor::White); - SetDefaultMaterial(); - SetRotation(0.f); - SetSize(64.f, 64.f); -} - -inline NzBillboard::NzBillboard(NzMaterialRef material) -{ - SetColor(NzColor::White); - SetMaterial(std::move(material), true); - SetRotation(0.f); - SetSize(64.f, 64.f); -} - -inline NzBillboard::NzBillboard(NzTexture* texture) -{ - SetColor(NzColor::White); - SetRotation(0.f); - SetSize(64.f, 64.f); - SetTexture(texture, true); -} - -inline NzBillboard::NzBillboard(const NzBillboard& billboard) : -NzInstancedRenderable(billboard), -m_color(billboard.m_color), -m_material(billboard.m_material), -m_rotation(billboard.m_rotation), -m_sinCos(billboard.m_sinCos), -m_size(billboard.m_size) -{ -} - -inline const NzColor& NzBillboard::GetColor() const -{ - return m_color; -} - -inline const NzMaterialRef& NzBillboard::GetMaterial() const -{ - return m_material; -} - -inline float NzBillboard::GetRotation() const -{ - return m_rotation; -} - -inline const NzVector2f& NzBillboard::GetSize() const -{ - return m_size; -} - -inline void NzBillboard::SetColor(const NzColor& color) -{ - m_color = color; -} - -inline void NzBillboard::SetDefaultMaterial() -{ - NzMaterialRef material = NzMaterial::New(); - material->Enable(nzRendererParameter_FaceCulling, true); - material->EnableLighting(false); - - SetMaterial(std::move(material)); -} - -inline void NzBillboard::SetMaterial(NzMaterialRef material, bool resizeBillboard) -{ - m_material = std::move(material); - if (m_material && resizeBillboard) + inline Billboard::Billboard() { - NzTexture* diffuseMap = m_material->GetDiffuseMap(); - if (diffuseMap && diffuseMap->IsValid()) - SetSize(NzVector2f(NzVector2ui(diffuseMap->GetSize()))); + SetColor(Color::White); + SetDefaultMaterial(); + SetRotation(0.f); + SetSize(64.f, 64.f); + } + + inline Billboard::Billboard(MaterialRef material) + { + SetColor(Color::White); + SetMaterial(std::move(material), true); + SetRotation(0.f); + SetSize(64.f, 64.f); + } + + inline Billboard::Billboard(Texture* texture) + { + SetColor(Color::White); + SetRotation(0.f); + SetSize(64.f, 64.f); + SetTexture(texture, true); + } + + inline Billboard::Billboard(const Billboard& billboard) : + InstancedRenderable(billboard), + m_color(billboard.m_color), + m_material(billboard.m_material), + m_rotation(billboard.m_rotation), + m_sinCos(billboard.m_sinCos), + m_size(billboard.m_size) + { + } + + inline const Color& Billboard::GetColor() const + { + return m_color; + } + + inline const MaterialRef& Billboard::GetMaterial() const + { + return m_material; + } + + inline float Billboard::GetRotation() const + { + return m_rotation; + } + + inline const Vector2f& Billboard::GetSize() const + { + return m_size; + } + + inline void Billboard::SetColor(const Color& color) + { + m_color = color; + } + + inline void Billboard::SetDefaultMaterial() + { + MaterialRef material = Material::New(); + material->Enable(RendererParameter_FaceCulling, true); + material->EnableLighting(false); + + SetMaterial(std::move(material)); + } + + inline void Billboard::SetMaterial(MaterialRef material, bool resizeBillboard) + { + m_material = std::move(material); + if (m_material && resizeBillboard) + { + Texture* diffuseMap = m_material->GetDiffuseMap(); + if (diffuseMap && diffuseMap->IsValid()) + SetSize(Vector2f(Vector2ui(diffuseMap->GetSize()))); + } + } + + inline void Billboard::SetRotation(float rotation) + { + m_rotation = rotation; + m_sinCos.Set(std::sin(m_rotation), std::cos(m_rotation)); + } + + inline void Billboard::SetSize(const Vector2f& size) + { + m_size = size; + + // On invalide la bounding box + InvalidateBoundingVolume(); + } + + inline void Billboard::SetSize(float sizeX, float sizeY) + { + SetSize(Vector2f(sizeX, sizeY)); + } + + inline void Billboard::SetTexture(TextureRef texture, bool resizeBillboard) + { + if (!m_material) + SetDefaultMaterial(); + else if (m_material->GetReferenceCount() > 1) + m_material = Material::New(*m_material); // Copie + + if (resizeBillboard && texture && texture->IsValid()) + SetSize(Vector2f(Vector2ui(texture->GetSize()))); + + m_material->SetDiffuseMap(std::move(texture)); + } + + inline Billboard& Billboard::operator=(const Billboard& billboard) + { + InstancedRenderable::operator=(billboard); + + m_color = billboard.m_color; + m_material = billboard.m_material; + m_size = billboard.m_size; + + InvalidateBoundingVolume(); + + return *this; + } + + template + BillboardRef Billboard::New(Args&&... args) + { + std::unique_ptr object(new Billboard(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); } } -inline void NzBillboard::SetRotation(float rotation) -{ - m_rotation = rotation; - m_sinCos.Set(std::sin(m_rotation), std::cos(m_rotation)); -} - -inline void NzBillboard::SetSize(const NzVector2f& size) -{ - m_size = size; - - // On invalide la bounding box - InvalidateBoundingVolume(); -} - -inline void NzBillboard::SetSize(float sizeX, float sizeY) -{ - SetSize(NzVector2f(sizeX, sizeY)); -} - -inline void NzBillboard::SetTexture(NzTextureRef texture, bool resizeBillboard) -{ - if (!m_material) - SetDefaultMaterial(); - else if (m_material->GetReferenceCount() > 1) - m_material = NzMaterial::New(*m_material); // Copie - - if (resizeBillboard && texture && texture->IsValid()) - SetSize(NzVector2f(NzVector2ui(texture->GetSize()))); - - m_material->SetDiffuseMap(std::move(texture)); -} - -inline NzBillboard& NzBillboard::operator=(const NzBillboard& billboard) -{ - NzInstancedRenderable::operator=(billboard); - - m_color = billboard.m_color; - m_material = billboard.m_material; - m_size = billboard.m_size; - - InvalidateBoundingVolume(); - - return *this; -} - -template -NzBillboardRef NzBillboard::New(Args&&... args) -{ - std::unique_ptr object(new NzBillboard(std::forward(args)...)); - object->SetPersistent(false); - - return object.release(); -} - #include diff --git a/include/Nazara/Graphics/ColorBackground.hpp b/include/Nazara/Graphics/ColorBackground.hpp index c1f541552..95113f71b 100644 --- a/include/Nazara/Graphics/ColorBackground.hpp +++ b/include/Nazara/Graphics/ColorBackground.hpp @@ -12,36 +12,39 @@ #include #include -class NzColorBackground; - -using NzColorBackgroundConstRef = NzObjectRef; -using NzColorBackgroundRef = NzObjectRef; - -class NAZARA_GRAPHICS_API NzColorBackground : public NzAbstractBackground +namespace Nz { - public: - NzColorBackground(const NzColor& color = NzColor::Black); - NzColorBackground(const NzColorBackground&) = default; - NzColorBackground(NzColorBackground&&) = delete; + class ColorBackground; - void Draw(const NzAbstractViewer* viewer) const; + using ColorBackgroundConstRef = ObjectRef; + using ColorBackgroundRef = ObjectRef; - nzBackgroundType GetBackgroundType() const; - NzColor GetColor() const; + class NAZARA_GRAPHICS_API ColorBackground : public AbstractBackground + { + public: + ColorBackground(const Color& color = Color::Black); + ColorBackground(const ColorBackground&) = default; + ColorBackground(ColorBackground&&) = delete; - void SetColor(const NzColor& color); + void Draw(const AbstractViewer* viewer) const; - NzColorBackground& operator=(NzColorBackground&&) = delete; + BackgroundType GetBackgroundType() const; + Color GetColor() const; - template static NzColorBackgroundRef New(Args&&... args); + void SetColor(const Color& color); - private: - NzColor m_color; - NzUberShaderConstRef m_uberShader; - const NzUberShaderInstance* m_uberShaderInstance; - int m_materialDiffuseUniform; - int m_vertexDepthUniform; -}; + ColorBackground& operator=(ColorBackground&&) = delete; + + template static ColorBackgroundRef New(Args&&... args); + + private: + Color m_color; + UberShaderConstRef m_uberShader; + const UberShaderInstance* m_uberShaderInstance; + int m_materialDiffuseUniform; + int m_vertexDepthUniform; + }; +} #include diff --git a/include/Nazara/Graphics/ColorBackground.inl b/include/Nazara/Graphics/ColorBackground.inl index c082703f0..21b67d92c 100644 --- a/include/Nazara/Graphics/ColorBackground.inl +++ b/include/Nazara/Graphics/ColorBackground.inl @@ -5,13 +5,16 @@ #include #include -template -NzColorBackgroundRef NzColorBackground::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzColorBackground(std::forward(args)...)); - object->SetPersistent(false); + template + ColorBackgroundRef ColorBackground::New(Args&&... args) + { + std::unique_ptr object(new ColorBackground(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Graphics/DeferredBloomPass.hpp b/include/Nazara/Graphics/DeferredBloomPass.hpp index 3a6aace09..603998d84 100644 --- a/include/Nazara/Graphics/DeferredBloomPass.hpp +++ b/include/Nazara/Graphics/DeferredBloomPass.hpp @@ -15,40 +15,43 @@ #include #include -class NAZARA_GRAPHICS_API NzDeferredBloomPass : public NzDeferredRenderPass +namespace Nz { - public: - NzDeferredBloomPass(); - virtual ~NzDeferredBloomPass(); + class NAZARA_GRAPHICS_API DeferredBloomPass : public DeferredRenderPass + { + public: + DeferredBloomPass(); + virtual ~DeferredBloomPass(); - unsigned int GetBlurPassCount() const; - float GetBrightLuminance() const; - float GetBrightMiddleGrey() const; - float GetBrightThreshold() const; - NzTexture* GetTexture(unsigned int i) const; + unsigned int GetBlurPassCount() const; + float GetBrightLuminance() const; + float GetBrightMiddleGrey() const; + float GetBrightThreshold() const; + Texture* GetTexture(unsigned int i) const; - bool Process(const NzSceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; - bool Resize(const NzVector2ui& dimensions); + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + bool Resize(const Vector2ui& dimensions); - void SetBlurPassCount(unsigned int passCount); - void SetBrightLuminance(float luminance); - void SetBrightMiddleGrey(float middleGrey); - void SetBrightThreshold(float threshold); + void SetBlurPassCount(unsigned int passCount); + void SetBrightLuminance(float luminance); + void SetBrightMiddleGrey(float middleGrey); + void SetBrightThreshold(float threshold); - protected: - NzRenderStates m_bloomStates; - NzRenderTexture m_bloomRTT; - NzShaderRef m_bloomBrightShader; - NzShaderRef m_bloomFinalShader; - NzShaderRef m_gaussianBlurShader; - NzTextureRef m_bloomTextures[2]; - NzTextureSampler m_bilinearSampler; - mutable bool m_uniformUpdated; - float m_brightLuminance; - float m_brightMiddleGrey; - float m_brightThreshold; - int m_gaussianBlurShaderFilterLocation; - unsigned int m_blurPassCount; -}; + protected: + RenderStates m_bloomStates; + RenderTexture m_bloomRTT; + ShaderRef m_bloomBrightShader; + ShaderRef m_bloomFinalShader; + ShaderRef m_gaussianBlurShader; + TextureRef m_bloomTextures[2]; + TextureSampler m_bilinearSampler; + mutable bool m_uniformUpdated; + float m_brightLuminance; + float m_brightMiddleGrey; + float m_brightThreshold; + int m_gaussianBlurShaderFilterLocation; + unsigned int m_blurPassCount; + }; +} #endif // NAZARA_DEFERREDBLOOMPASS_HPP diff --git a/include/Nazara/Graphics/DeferredDOFPass.hpp b/include/Nazara/Graphics/DeferredDOFPass.hpp index 9043037cc..4da8824c7 100644 --- a/include/Nazara/Graphics/DeferredDOFPass.hpp +++ b/include/Nazara/Graphics/DeferredDOFPass.hpp @@ -15,24 +15,27 @@ #include #include -class NAZARA_GRAPHICS_API NzDeferredDOFPass : public NzDeferredRenderPass +namespace Nz { - public: - NzDeferredDOFPass(); - virtual ~NzDeferredDOFPass(); + class NAZARA_GRAPHICS_API DeferredDOFPass : public DeferredRenderPass + { + public: + DeferredDOFPass(); + virtual ~DeferredDOFPass(); - bool Process(const NzSceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; - bool Resize(const NzVector2ui& dimensions); + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + bool Resize(const Vector2ui& dimensions); - protected: - NzRenderTexture m_dofRTT; - NzRenderStates m_states; - NzShaderConstRef m_dofShader; - NzShaderConstRef m_gaussianBlurShader; - NzTextureRef m_dofTextures[2]; - NzTextureSampler m_bilinearSampler; - NzTextureSampler m_pointSampler; - int m_gaussianBlurShaderFilterLocation; -}; + protected: + RenderTexture m_dofRTT; + RenderStates m_states; + ShaderConstRef m_dofShader; + ShaderConstRef m_gaussianBlurShader; + TextureRef m_dofTextures[2]; + TextureSampler m_bilinearSampler; + TextureSampler m_pointSampler; + int m_gaussianBlurShaderFilterLocation; + }; +} #endif // NAZARA_DEFERREDDOFPASS_HPP diff --git a/include/Nazara/Graphics/DeferredFXAAPass.hpp b/include/Nazara/Graphics/DeferredFXAAPass.hpp index d4da4d5a0..34fc46867 100644 --- a/include/Nazara/Graphics/DeferredFXAAPass.hpp +++ b/include/Nazara/Graphics/DeferredFXAAPass.hpp @@ -13,18 +13,21 @@ #include #include -class NAZARA_GRAPHICS_API NzDeferredFXAAPass : public NzDeferredRenderPass +namespace Nz { - public: - NzDeferredFXAAPass(); - virtual ~NzDeferredFXAAPass(); + class NAZARA_GRAPHICS_API DeferredFXAAPass : public DeferredRenderPass + { + public: + DeferredFXAAPass(); + virtual ~DeferredFXAAPass(); - bool Process(const NzSceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; - protected: - NzRenderStates m_states; - NzShaderRef m_fxaaShader; - NzTextureSampler m_pointSampler; -}; + protected: + RenderStates m_states; + ShaderRef m_fxaaShader; + TextureSampler m_pointSampler; + }; +} #endif // NAZARA_DEFERREDFXAAPASS_HPP diff --git a/include/Nazara/Graphics/DeferredFinalPass.hpp b/include/Nazara/Graphics/DeferredFinalPass.hpp index d847b59f3..c800d44d1 100644 --- a/include/Nazara/Graphics/DeferredFinalPass.hpp +++ b/include/Nazara/Graphics/DeferredFinalPass.hpp @@ -13,21 +13,24 @@ #include #include -class NAZARA_GRAPHICS_API NzDeferredFinalPass : public NzDeferredRenderPass +namespace Nz { - public: - NzDeferredFinalPass(); - virtual ~NzDeferredFinalPass(); + class NAZARA_GRAPHICS_API DeferredFinalPass : public DeferredRenderPass + { + public: + DeferredFinalPass(); + virtual ~DeferredFinalPass(); - bool Process(const NzSceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; - protected: - NzRenderStates m_states; - NzTextureSampler m_pointSampler; - NzUberShaderConstRef m_uberShader; - const NzUberShaderInstance* m_uberShaderInstance; - int m_materialDiffuseUniform; - int m_materialDiffuseMapUniform; -}; + protected: + RenderStates m_states; + TextureSampler m_pointSampler; + UberShaderConstRef m_uberShader; + const UberShaderInstance* m_uberShaderInstance; + int m_materialDiffuseUniform; + int m_materialDiffuseMapUniform; + }; +} #endif // NAZARA_DEFERREDFINALPASS_HPP diff --git a/include/Nazara/Graphics/DeferredFogPass.hpp b/include/Nazara/Graphics/DeferredFogPass.hpp index b531f8daa..37466305b 100644 --- a/include/Nazara/Graphics/DeferredFogPass.hpp +++ b/include/Nazara/Graphics/DeferredFogPass.hpp @@ -13,19 +13,22 @@ #include #include -class NAZARA_GRAPHICS_API NzDeferredFogPass : public NzDeferredRenderPass +namespace Nz { - public: - NzDeferredFogPass(); - virtual ~NzDeferredFogPass(); + class NAZARA_GRAPHICS_API DeferredFogPass : public DeferredRenderPass + { + public: + DeferredFogPass(); + virtual ~DeferredFogPass(); - bool Process(const NzSceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; - protected: - NzRenderStates m_states; - NzShaderRef m_shader; - NzTextureSampler m_pointSampler; - int m_shaderEyePositionLocation; -}; + protected: + RenderStates m_states; + ShaderRef m_shader; + TextureSampler m_pointSampler; + int m_shaderEyePositionLocation; + }; +} #endif // NAZARA_DEFERREDFOGPASS_HPP diff --git a/include/Nazara/Graphics/DeferredForwardPass.hpp b/include/Nazara/Graphics/DeferredForwardPass.hpp index 7f18180ab..0b1d8aa0a 100644 --- a/include/Nazara/Graphics/DeferredForwardPass.hpp +++ b/include/Nazara/Graphics/DeferredForwardPass.hpp @@ -10,19 +10,22 @@ #include #include -class NzForwardRenderTechnique; - -class NAZARA_GRAPHICS_API NzDeferredForwardPass : public NzDeferredRenderPass +namespace Nz { - public: - NzDeferredForwardPass(); - virtual ~NzDeferredForwardPass(); + class ForwardRenderTechnique; - void Initialize(NzDeferredRenderTechnique* technique); - bool Process(const NzSceneData& sceneData, unsigned int workTexture, unsigned sceneTexture) const; + class NAZARA_GRAPHICS_API DeferredForwardPass : public DeferredRenderPass + { + public: + DeferredForwardPass(); + virtual ~DeferredForwardPass(); - protected: - const NzForwardRenderTechnique* m_forwardTechnique; -}; + void Initialize(DeferredRenderTechnique* technique); + bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned sceneTexture) const; + + protected: + const ForwardRenderTechnique* m_forwardTechnique; + }; +} #endif // NAZARA_DEFERREDFORWARDPASS_HPP diff --git a/include/Nazara/Graphics/DeferredGeometryPass.hpp b/include/Nazara/Graphics/DeferredGeometryPass.hpp index 403e68e07..652060b3d 100644 --- a/include/Nazara/Graphics/DeferredGeometryPass.hpp +++ b/include/Nazara/Graphics/DeferredGeometryPass.hpp @@ -13,34 +13,37 @@ #include #include -class NAZARA_GRAPHICS_API NzDeferredGeometryPass : public NzDeferredRenderPass +namespace Nz { - public: - NzDeferredGeometryPass(); - virtual ~NzDeferredGeometryPass(); + class NAZARA_GRAPHICS_API DeferredGeometryPass : public DeferredRenderPass + { + public: + DeferredGeometryPass(); + virtual ~DeferredGeometryPass(); - bool Process(const NzSceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; - bool Resize(const NzVector2ui& dimensions); + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + bool Resize(const Vector2ui& dimensions); - protected: - struct ShaderUniforms; + protected: + struct ShaderUniforms; - const ShaderUniforms* GetShaderUniforms(const NzShader* shader) const; - void OnShaderInvalidated(const NzShader* shader) const; + const ShaderUniforms* GetShaderUniforms(const Shader* shader) const; + void OnShaderInvalidated(const Shader* shader) const; - struct ShaderUniforms - { - NazaraSlot(NzShader, OnShaderUniformInvalidated, shaderUniformInvalidatedSlot); - NazaraSlot(NzShader, OnShaderRelease, shaderReleaseSlot); + struct ShaderUniforms + { + NazaraSlot(Shader, OnShaderUniformInvalidated, shaderUniformInvalidatedSlot); + NazaraSlot(Shader, OnShaderRelease, shaderReleaseSlot); - int eyePosition; - int sceneAmbient; - int textureOverlay; - }; + int eyePosition; + int sceneAmbient; + int textureOverlay; + }; - mutable std::unordered_map m_shaderUniforms; - NzRenderStates m_clearStates; - NzShaderRef m_clearShader; -}; + mutable std::unordered_map m_shaderUniforms; + RenderStates m_clearStates; + ShaderRef m_clearShader; + }; +} #endif // NAZARA_DEFERREDGEOMETRYPASS_HPP diff --git a/include/Nazara/Graphics/DeferredPhongLightingPass.hpp b/include/Nazara/Graphics/DeferredPhongLightingPass.hpp index 6da596c5e..40b480217 100644 --- a/include/Nazara/Graphics/DeferredPhongLightingPass.hpp +++ b/include/Nazara/Graphics/DeferredPhongLightingPass.hpp @@ -14,36 +14,39 @@ #include #include -class NzStaticMesh; - -class NAZARA_GRAPHICS_API NzDeferredPhongLightingPass : public NzDeferredRenderPass +namespace Nz { - public: - NzDeferredPhongLightingPass(); - virtual ~NzDeferredPhongLightingPass(); + class StaticMesh; - void EnableLightMeshesDrawing(bool enable); + class NAZARA_GRAPHICS_API DeferredPhongLightingPass : public DeferredRenderPass + { + public: + DeferredPhongLightingPass(); + virtual ~DeferredPhongLightingPass(); - bool IsLightMeshesDrawingEnabled() const; + void EnableLightMeshesDrawing(bool enable); - bool Process(const NzSceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + bool IsLightMeshesDrawingEnabled() const; - protected: - NzLightUniforms m_directionalLightUniforms; - NzLightUniforms m_pointSpotLightUniforms; - NzMeshRef m_cone; - NzMeshRef m_sphere; - NzShaderRef m_directionalLightShader; - NzShaderRef m_pointSpotLightShader; - NzTextureSampler m_pointSampler; - NzStaticMesh* m_coneMesh; - NzStaticMesh* m_sphereMesh; - bool m_lightMeshesDrawing; - int m_directionalLightShaderEyePositionLocation; - int m_directionalLightShaderSceneAmbientLocation; - int m_pointSpotLightShaderDiscardLocation; - int m_pointSpotLightShaderEyePositionLocation; - int m_pointSpotLightShaderSceneAmbientLocation; -}; + bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; + + protected: + LightUniforms m_directionalLightUniforms; + LightUniforms m_pointSpotLightUniforms; + MeshRef m_cone; + MeshRef m_sphere; + ShaderRef m_directionalLightShader; + ShaderRef m_pointSpotLightShader; + TextureSampler m_pointSampler; + StaticMesh* m_coneMesh; + StaticMesh* m_sphereMesh; + bool m_lightMeshesDrawing; + int m_directionalLightShaderEyePositionLocation; + int m_directionalLightShaderSceneAmbientLocation; + int m_pointSpotLightShaderDiscardLocation; + int m_pointSpotLightShaderEyePositionLocation; + int m_pointSpotLightShaderSceneAmbientLocation; + }; +} #endif // NAZARA_DEFERREDPHONGLIGHTINGPASS_HPP diff --git a/include/Nazara/Graphics/DeferredRenderPass.hpp b/include/Nazara/Graphics/DeferredRenderPass.hpp index 0a23a2ab2..d9ad69919 100644 --- a/include/Nazara/Graphics/DeferredRenderPass.hpp +++ b/include/Nazara/Graphics/DeferredRenderPass.hpp @@ -13,46 +13,49 @@ #include #include -class NzAbstractViewer; -class NzDeferredRenderTechnique; -class NzDeferredRenderQueue; -class NzRenderBuffer; -class NzRenderTexture; -class NzScene; -class NzTexture; - -class NAZARA_GRAPHICS_API NzDeferredRenderPass +namespace Nz { - friend NzDeferredRenderTechnique; + class AbstractViewer; + class DeferredRenderTechnique; + class DeferredRenderQueue; + class RenderBuffer; + class RenderTexture; + class Scene; + class Texture; - public: - NzDeferredRenderPass(); - NzDeferredRenderPass(const NzDeferredRenderPass&) = delete; - virtual ~NzDeferredRenderPass(); + class NAZARA_GRAPHICS_API DeferredRenderPass + { + friend DeferredRenderTechnique; - void Enable(bool enable); + public: + DeferredRenderPass(); + DeferredRenderPass(const DeferredRenderPass&) = delete; + virtual ~DeferredRenderPass(); - virtual void Initialize(NzDeferredRenderTechnique* technique); + void Enable(bool enable); - bool IsEnabled() const; + virtual void Initialize(DeferredRenderTechnique* technique); - virtual bool Process(const NzSceneData& sceneData, unsigned int workTexture, unsigned sceneTexture) const = 0; - virtual bool Resize(const NzVector2ui& GBufferSize); + bool IsEnabled() const; - NzDeferredRenderPass& operator=(const NzDeferredRenderPass&) = delete; + virtual bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned sceneTexture) const = 0; + virtual bool Resize(const Vector2ui& GBufferSize); - protected: - NzVector2ui m_dimensions; - NzDeferredRenderTechnique* m_deferredTechnique; - NzDeferredRenderQueue* m_renderQueue; - NzRenderBuffer* m_depthStencilBuffer; - NzRenderTexture* m_GBufferRTT; - NzRenderTexture* m_workRTT; - NzTexture* m_GBuffer[4]; - NzTexture* m_workTextures[2]; + DeferredRenderPass& operator=(const DeferredRenderPass&) = delete; - private: - bool m_enabled; -}; + protected: + Vector2ui m_dimensions; + DeferredRenderTechnique* m_deferredTechnique; + DeferredRenderQueue* m_renderQueue; + RenderBuffer* m_depthStencilBuffer; + RenderTexture* m_GBufferRTT; + RenderTexture* m_workRTT; + Texture* m_GBuffer[4]; + Texture* m_workTextures[2]; + + private: + bool m_enabled; + }; +} #endif // NAZARA_DEFERREDRENDERPASS_HPP diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index 51343251d..b69204174 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -19,66 +19,69 @@ #include #include -class NzForwardRenderQueue; - -class NAZARA_GRAPHICS_API NzDeferredRenderQueue : public NzAbstractRenderQueue +namespace Nz { - public: - NzDeferredRenderQueue(NzForwardRenderQueue* forwardQueue); - ~NzDeferredRenderQueue() = default; + class ForwardRenderQueue; - 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 AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; - void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay = nullptr) override; + class NAZARA_GRAPHICS_API DeferredRenderQueue : public AbstractRenderQueue + { + public: + DeferredRenderQueue(ForwardRenderQueue* forwardQueue); + ~DeferredRenderQueue() = default; - void Clear(bool fully = false); + void AddBillboard(const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddDrawable(const Drawable* drawable) override; + void AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; + void AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; - struct MeshDataComparator - { - bool operator()(const NzMeshData& data1, const NzMeshData& data2) const; - }; + void Clear(bool fully = false); - struct MeshInstanceEntry - { - NazaraSlot(NzIndexBuffer, OnIndexBufferRelease, indexBufferReleaseSlot); - NazaraSlot(NzVertexBuffer, OnVertexBufferRelease, vertexBufferReleaseSlot); + struct MeshDataComparator + { + bool operator()(const MeshData& data1, const MeshData& data2) const; + }; - std::vector instances; - }; + struct MeshInstanceEntry + { + NazaraSlot(IndexBuffer, OnIndexBufferRelease, indexBufferReleaseSlot); + NazaraSlot(VertexBuffer, OnVertexBufferRelease, vertexBufferReleaseSlot); - typedef std::map MeshInstanceContainer; + std::vector instances; + }; - struct BatchedModelMaterialComparator - { - bool operator()(const NzMaterial* mat1, const NzMaterial* mat2) const; - }; + typedef std::map MeshInstanceContainer; - struct BatchedModelEntry - { - NazaraSlot(NzMaterial, OnMaterialRelease, materialReleaseSlot); + struct BatchedModelMaterialComparator + { + bool operator()(const Material* mat1, const Material* mat2) const; + }; - MeshInstanceContainer meshMap; - bool enabled = false; - bool instancingEnabled = false; - }; + struct BatchedModelEntry + { + NazaraSlot(Material, OnMaterialRelease, materialReleaseSlot); - typedef std::map ModelBatches; + MeshInstanceContainer meshMap; + bool enabled = false; + bool instancingEnabled = false; + }; - ModelBatches opaqueModels; - NzForwardRenderQueue* m_forwardQueue; + typedef std::map ModelBatches; - void OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer); - void OnMaterialInvalidation(const NzMaterial* material); - void OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer); -}; + ModelBatches opaqueModels; + ForwardRenderQueue* m_forwardQueue; + + void OnIndexBufferInvalidation(const IndexBuffer* indexBuffer); + void OnMaterialInvalidation(const Material* material); + void OnVertexBufferInvalidation(const VertexBuffer* vertexBuffer); + }; +} #endif // NAZARA_DEFERREDRENDERQUEUE_HPP diff --git a/include/Nazara/Graphics/DeferredRenderTechnique.hpp b/include/Nazara/Graphics/DeferredRenderTechnique.hpp index 8d73110ba..5d371b94f 100644 --- a/include/Nazara/Graphics/DeferredRenderTechnique.hpp +++ b/include/Nazara/Graphics/DeferredRenderTechnique.hpp @@ -22,57 +22,60 @@ #include #include -class NAZARA_GRAPHICS_API NzDeferredRenderTechnique : public NzAbstractRenderTechnique +namespace Nz { - friend class NzGraphics; + class NAZARA_GRAPHICS_API DeferredRenderTechnique : public AbstractRenderTechnique + { + friend class Graphics; - public: - NzDeferredRenderTechnique(); - ~NzDeferredRenderTechnique(); + public: + DeferredRenderTechnique(); + ~DeferredRenderTechnique(); - bool Draw(const NzSceneData& sceneData) const override; + bool Draw(const SceneData& sceneData) const override; - void EnablePass(nzRenderPassType renderPass, int position, bool enable); + void EnablePass(RenderPassType renderPass, int position, bool enable); - NzRenderBuffer* GetDepthStencilBuffer() const; - NzTexture* GetGBuffer(unsigned int i) const; - NzRenderTexture* GetGBufferRTT() const; - const NzForwardRenderTechnique* GetForwardTechnique() const; - NzDeferredRenderPass* GetPass(nzRenderPassType renderPass, int position = 0); - NzAbstractRenderQueue* GetRenderQueue() override; - nzRenderTechniqueType GetType() const override; - NzRenderTexture* GetWorkRTT() const; - NzTexture* GetWorkTexture(unsigned int i) const; + RenderBuffer* GetDepthStencilBuffer() const; + Texture* GetGBuffer(unsigned int i) const; + RenderTexture* GetGBufferRTT() const; + const ForwardRenderTechnique* GetForwardTechnique() const; + DeferredRenderPass* GetPass(RenderPassType renderPass, int position = 0); + AbstractRenderQueue* GetRenderQueue() override; + RenderTechniqueType GetType() const override; + RenderTexture* GetWorkRTT() const; + Texture* GetWorkTexture(unsigned int i) const; - bool IsPassEnabled(nzRenderPassType renderPass, int position); + bool IsPassEnabled(RenderPassType renderPass, int position); - NzDeferredRenderPass* ResetPass(nzRenderPassType renderPass, int position); + DeferredRenderPass* ResetPass(RenderPassType renderPass, int position); - void SetPass(nzRenderPassType relativeTo, int position, NzDeferredRenderPass* pass); + void SetPass(RenderPassType relativeTo, int position, DeferredRenderPass* pass); - static bool IsSupported(); + static bool IsSupported(); - private: - bool Resize(const NzVector2ui& dimensions) const; + private: + bool Resize(const Vector2ui& dimensions) const; - static bool Initialize(); - static void Uninitialize(); + static bool Initialize(); + static void Uninitialize(); - struct RenderPassComparator - { - bool operator()(nzRenderPassType pass1, nzRenderPassType pass2) const; - }; + struct RenderPassComparator + { + bool operator()(RenderPassType pass1, RenderPassType pass2) const; + }; - std::map>, RenderPassComparator> m_passes; - NzForwardRenderTechnique m_forwardTechnique; // Doit être initialisé avant la RenderQueue - NzDeferredRenderQueue m_renderQueue; - mutable NzRenderBufferRef m_depthStencilBuffer; - mutable NzRenderTexture m_GBufferRTT; - mutable NzRenderTexture m_workRTT; - mutable NzTextureRef m_GBuffer[4]; - mutable NzTextureRef m_workTextures[2]; - mutable NzVector2ui m_GBufferSize; - const NzRenderTarget* m_viewerTarget; + std::map>, RenderPassComparator> m_passes; + ForwardRenderTechnique m_forwardTechnique; // Doit être initialisé avant la RenderQueue + DeferredRenderQueue m_renderQueue; + mutable RenderBufferRef m_depthStencilBuffer; + mutable RenderTexture m_GBufferRTT; + mutable RenderTexture m_workRTT; + mutable TextureRef m_GBuffer[4]; + mutable TextureRef m_workTextures[2]; + mutable Vector2ui m_GBufferSize; + const RenderTarget* m_viewerTarget; }; +} #endif // NAZARA_FORWARDRENDERTECHNIQUE_HPP diff --git a/include/Nazara/Graphics/Drawable.hpp b/include/Nazara/Graphics/Drawable.hpp index 2c89b152f..5d5eca95b 100644 --- a/include/Nazara/Graphics/Drawable.hpp +++ b/include/Nazara/Graphics/Drawable.hpp @@ -10,13 +10,16 @@ #include #include -class NAZARA_GRAPHICS_API NzDrawable +namespace Nz { - public: - NzDrawable() = default; - virtual ~NzDrawable(); + class NAZARA_GRAPHICS_API Drawable + { + public: + Drawable() = default; + virtual ~Drawable(); - virtual void Draw() const = 0; -}; + virtual void Draw() const = 0; + }; +} #endif // NAZARA_DRAWABLE_HPP diff --git a/include/Nazara/Graphics/Enums.hpp b/include/Nazara/Graphics/Enums.hpp index a0f9749a4..35510ac5b 100644 --- a/include/Nazara/Graphics/Enums.hpp +++ b/include/Nazara/Graphics/Enums.hpp @@ -7,136 +7,139 @@ #ifndef NAZARA_ENUMS_GRAPHICS_HPP #define NAZARA_ENUMS_GRAPHICS_HPP -enum nzBackgroundType +namespace Nz { - nzBackgroundType_Color, // NzColorBackground - nzBackgroundType_Skybox, // NzSkyboxBackground - nzBackgroundType_Texture, // NzTextureBackground - nzBackgroundType_User, + enum BackgroundType + { + BackgroundType_Color, // ColorBackground + BackgroundType_Skybox, // SkyboxBackground + BackgroundType_Texture, // TextureBackground + BackgroundType_User, - nzBackgroundType_Max = nzBackgroundType_User -}; + BackgroundType_Max = BackgroundType_User + }; -enum nzProjectionType -{ - nzProjectionType_Orthogonal, - nzProjectionType_Perspective, + enum ProjectionType + { + ProjectionType_Orthogonal, + ProjectionType_Perspective, - nzProjectionType_Max = nzProjectionType_Perspective -}; + ProjectionType_Max = ProjectionType_Perspective + }; -enum nzLightType -{ - nzLightType_Directional, - nzLightType_Point, - nzLightType_Spot, + enum LightType + { + LightType_Directional, + LightType_Point, + LightType_Spot, - nzLightType_Max = nzLightType_Spot -}; + LightType_Max = LightType_Spot + }; -enum nzMaterialUniform -{ - nzMaterialUniform_AlphaMap, - nzMaterialUniform_AlphaThreshold, - nzMaterialUniform_Ambient, - nzMaterialUniform_Diffuse, - nzMaterialUniform_DiffuseMap, - nzMaterialUniform_EmissiveMap, - nzMaterialUniform_HeightMap, - nzMaterialUniform_NormalMap, - nzMaterialUniform_Shininess, - nzMaterialUniform_Specular, - nzMaterialUniform_SpecularMap, + enum MaterialUniform + { + MaterialUniform_AlphaMap, + MaterialUniform_AlphaThreshold, + MaterialUniform_Ambient, + MaterialUniform_Diffuse, + MaterialUniform_DiffuseMap, + MaterialUniform_EmissiveMap, + MaterialUniform_HeightMap, + MaterialUniform_NormalMap, + MaterialUniform_Shininess, + MaterialUniform_Specular, + MaterialUniform_SpecularMap, - nzMaterialUniform_Max = nzMaterialUniform_SpecularMap -}; + MaterialUniform_Max = MaterialUniform_SpecularMap + }; -enum nzParticleComponent -{ - nzParticleComponent_Unused = -1, + enum ParticleComponent + { + ParticleComponent_Unused = -1, - nzParticleComponent_Color, - nzParticleComponent_Life, - nzParticleComponent_Mass, - nzParticleComponent_Normal, - nzParticleComponent_Position, - nzParticleComponent_Radius, - nzParticleComponent_Rotation, - nzParticleComponent_Size, - nzParticleComponent_Velocity, - nzParticleComponent_Userdata0, - nzParticleComponent_Userdata1, - nzParticleComponent_Userdata2, - nzParticleComponent_Userdata3, - nzParticleComponent_Userdata4, - nzParticleComponent_Userdata5, - nzParticleComponent_Userdata6, - nzParticleComponent_Userdata7, - nzParticleComponent_Userdata8, + ParticleComponent_Color, + ParticleComponent_Life, + ParticleComponent_Mass, + ParticleComponent_Normal, + ParticleComponent_Position, + ParticleComponent_Radius, + ParticleComponent_Rotation, + ParticleComponent_Size, + ParticleComponent_Velocity, + ParticleComponent_Userdata0, + ParticleComponent_Userdata1, + ParticleComponent_Userdata2, + ParticleComponent_Userdata3, + ParticleComponent_Userdata4, + ParticleComponent_Userdata5, + ParticleComponent_Userdata6, + ParticleComponent_Userdata7, + ParticleComponent_Userdata8, - nzParticleComponent_Max = nzParticleComponent_Userdata8 -}; + ParticleComponent_Max = ParticleComponent_Userdata8 + }; -enum nzParticleLayout -{ - nzParticleLayout_Billboard, - nzParticleLayout_Model, - nzParticleLayout_Sprite, + enum ParticleLayout + { + ParticleLayout_Billboard, + ParticleLayout_Model, + ParticleLayout_Sprite, - nzParticleLayout_Max = nzParticleLayout_Sprite -}; + ParticleLayout_Max = ParticleLayout_Sprite + }; -enum nzRenderPassType -{ - nzRenderPassType_AA, - nzRenderPassType_Bloom, - nzRenderPassType_DOF, - nzRenderPassType_Final, - nzRenderPassType_Fog, - nzRenderPassType_Forward, - nzRenderPassType_Lighting, - nzRenderPassType_Geometry, - nzRenderPassType_SSAO, + enum RenderPassType + { + RenderPassType_AA, + RenderPassType_Bloom, + RenderPassType_DOF, + RenderPassType_Final, + RenderPassType_Fog, + RenderPassType_Forward, + RenderPassType_Lighting, + RenderPassType_Geometry, + RenderPassType_SSAO, - nzRenderPassType_Max = nzRenderPassType_SSAO -}; + RenderPassType_Max = RenderPassType_SSAO + }; -enum nzRenderTechniqueType -{ - nzRenderTechniqueType_AdvancedForward, // NzAdvancedForwardRenderTechnique - nzRenderTechniqueType_BasicForward, // NzBasicForwardRenderTechnique - nzRenderTechniqueType_DeferredShading, // NzDeferredRenderTechnique - nzRenderTechniqueType_LightPrePass, // NzLightPrePassRenderTechnique - nzRenderTechniqueType_User, + enum RenderTechniqueType + { + RenderTechniqueType_AdvancedForward, // NzAdvancedForwardRenderTechnique + RenderTechniqueType_BasicForward, // NzBasicForwardRenderTechnique + RenderTechniqueType_DeferredShading, // DeferredRenderTechnique + RenderTechniqueType_LightPrePass, // LightPrePassRenderTechnique + RenderTechniqueType_User, - nzRenderTechniqueType_Max = nzRenderTechniqueType_User -}; + RenderTechniqueType_Max = RenderTechniqueType_User + }; -enum nzSceneNodeType -{ - nzSceneNodeType_Light, // NzLight - nzSceneNodeType_Model, // NzModel - nzSceneNodeType_ParticleEmitter, // NzParticleEmitter - nzSceneNodeType_Root, // NzSceneRoot - nzSceneNodeType_Sprite, // NzSprite - nzSceneNodeType_TextSprite, // NzTextSprite - nzSceneNodeType_User, + enum SceneNodeType + { + SceneNodeType_Light, // Light + SceneNodeType_Model, // Model + SceneNodeType_ParticleEmitter, // ParticleEmitter + SceneNodeType_Root, // SceneRoot + SceneNodeType_Sprite, // Sprite + SceneNodeType_TextSprite, // TextSprite + SceneNodeType_User, - nzSceneNodeType_Max = nzSceneNodeType_User -}; + SceneNodeType_Max = SceneNodeType_User + }; -// Ces paramètres sont indépendants du matériau: ils peuvent être demandés à tout moment -enum nzShaderFlags -{ - nzShaderFlags_None = 0, + // Ces paramètres sont indépendants du matériau: ils peuvent être demandés à tout moment + enum ShaderFlags + { + ShaderFlags_None = 0, - nzShaderFlags_Billboard = 0x01, - nzShaderFlags_Deferred = 0x02, - nzShaderFlags_Instancing = 0x04, - nzShaderFlags_TextureOverlay = 0x08, - nzShaderFlags_VertexColor = 0x10, + ShaderFlags_Billboard = 0x01, + ShaderFlags_Deferred = 0x02, + ShaderFlags_Instancing = 0x04, + ShaderFlags_TextureOverlay = 0x08, + ShaderFlags_VertexColor = 0x10, - nzShaderFlags_Max = nzShaderFlags_VertexColor*2-1 -}; + ShaderFlags_Max = ShaderFlags_VertexColor*2-1 + }; +} #endif // NAZARA_ENUMS_GRAPHICS_HPP diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index ed799f11d..df3d82a81 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -19,142 +19,145 @@ #include #include -class NzAbstractViewer; - -class NAZARA_GRAPHICS_API NzForwardRenderQueue : public NzAbstractRenderQueue +namespace Nz { - friend class NzForwardRenderTechnique; + class AbstractViewer; - public: - NzForwardRenderQueue() = default; - ~NzForwardRenderQueue() = default; + class NAZARA_GRAPHICS_API ForwardRenderQueue : public AbstractRenderQueue + { + friend class ForwardRenderTechnique; - 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 AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override; - void AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay = nullptr) override; + public: + ForwardRenderQueue() = default; + ~ForwardRenderQueue() = default; - void Clear(bool fully = false); + void AddBillboard(const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddDrawable(const Drawable* drawable) override; + void AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; + void AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; - void Sort(const NzAbstractViewer* viewer); + void Clear(bool fully = false); - /// Billboards - struct BillboardData - { - NzColor color; - NzVector3f center; - NzVector2f size; - NzVector2f sinCos; - }; + void Sort(const AbstractViewer* viewer); - struct BatchedBillboardComparator - { - bool operator()(const NzMaterial* mat1, const NzMaterial* mat2) const; - }; + /// Billboards + struct BillboardData + { + Color color; + Vector3f center; + Vector2f size; + Vector2f sinCos; + }; - struct BatchedBillboardEntry - { - NazaraSlot(NzMaterial, OnMaterialRelease, materialReleaseSlot); + struct BatchedBillboardComparator + { + bool operator()(const Material* mat1, const Material* mat2) const; + }; - std::vector billboards; - }; + struct BatchedBillboardEntry + { + NazaraSlot(Material, OnMaterialRelease, materialReleaseSlot); - typedef std::map BatchedBillboardContainer; + std::vector billboards; + }; - /// Sprites - struct SpriteChain_XYZ_Color_UV - { - const NzVertexStruct_XYZ_Color_UV* vertices; - unsigned int spriteCount; - }; + typedef std::map BatchedBillboardContainer; - struct BatchedSpriteEntry - { - NazaraSlot(NzTexture, OnTextureRelease, textureReleaseSlot); + /// Sprites + struct SpriteChain_XYZ_Color_UV + { + const VertexStruct_XYZ_Color_UV* vertices; + unsigned int spriteCount; + }; - std::vector spriteChains; - }; + struct BatchedSpriteEntry + { + NazaraSlot(Texture, OnTextureRelease, textureReleaseSlot); - struct BatchedSpriteMaterialComparator - { - bool operator()(const NzMaterial* mat1, const NzMaterial* mat2); - }; + std::vector spriteChains; + }; - typedef std::map BasicSpriteOverlayContainer; + struct BatchedSpriteMaterialComparator + { + bool operator()(const Material* mat1, const Material* mat2); + }; - struct BatchedBasicSpriteEntry - { - NazaraSlot(NzMaterial, OnMaterialRelease, materialReleaseSlot); + typedef std::map BasicSpriteOverlayContainer; - BasicSpriteOverlayContainer overlayMap; - bool enabled = false; - }; + struct BatchedBasicSpriteEntry + { + NazaraSlot(Material, OnMaterialRelease, materialReleaseSlot); - typedef std::map BasicSpriteBatches; + BasicSpriteOverlayContainer overlayMap; + bool enabled = false; + }; - /// Meshes - struct MeshDataComparator - { - bool operator()(const NzMeshData& data1, const NzMeshData& data2) const; - }; + typedef std::map BasicSpriteBatches; - struct MeshInstanceEntry - { - NazaraSlot(NzIndexBuffer, OnIndexBufferRelease, indexBufferReleaseSlot); - NazaraSlot(NzVertexBuffer, OnVertexBufferRelease, vertexBufferReleaseSlot); + /// Meshes + struct MeshDataComparator + { + bool operator()(const MeshData& data1, const MeshData& data2) const; + }; - std::vector instances; - NzSpheref squaredBoundingSphere; - }; + struct MeshInstanceEntry + { + NazaraSlot(IndexBuffer, OnIndexBufferRelease, indexBufferReleaseSlot); + NazaraSlot(VertexBuffer, OnVertexBufferRelease, vertexBufferReleaseSlot); - typedef std::map MeshInstanceContainer; + std::vector instances; + Spheref squaredBoundingSphere; + }; - struct BatchedModelMaterialComparator - { - bool operator()(const NzMaterial* mat1, const NzMaterial* mat2) const; - }; + typedef std::map MeshInstanceContainer; - struct BatchedModelEntry - { - NazaraSlot(NzMaterial, OnMaterialRelease, materialReleaseSlot); + struct BatchedModelMaterialComparator + { + bool operator()(const Material* mat1, const Material* mat2) const; + }; - MeshInstanceContainer meshMap; - bool enabled = false; - bool instancingEnabled = false; - }; + struct BatchedModelEntry + { + NazaraSlot(Material, OnMaterialRelease, materialReleaseSlot); - typedef std::map ModelBatches; + MeshInstanceContainer meshMap; + bool enabled = false; + bool instancingEnabled = false; + }; - struct TransparentModelData - { - NzMatrix4f transformMatrix; - NzMeshData meshData; - NzSpheref squaredBoundingSphere; - const NzMaterial* material; - }; + typedef std::map ModelBatches; - typedef std::vector TransparentModelContainer; + struct TransparentModelData + { + Matrix4f transformMatrix; + MeshData meshData; + Spheref squaredBoundingSphere; + const Material* material; + }; - BatchedBillboardContainer billboards; - BasicSpriteBatches basicSprites; - ModelBatches opaqueModels; - TransparentModelContainer transparentModels; - std::vector transparentModelData; - std::vector otherDrawables; + typedef std::vector TransparentModelContainer; - private: - void OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer); - void OnMaterialInvalidation(const NzMaterial* material); - void OnTextureInvalidation(const NzTexture* texture); - void OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer); -}; + BatchedBillboardContainer billboards; + BasicSpriteBatches basicSprites; + ModelBatches opaqueModels; + TransparentModelContainer transparentModels; + std::vector transparentModelData; + std::vector otherDrawables; + + private: + void OnIndexBufferInvalidation(const IndexBuffer* indexBuffer); + void OnMaterialInvalidation(const Material* material); + void OnTextureInvalidation(const Texture* texture); + void OnVertexBufferInvalidation(const VertexBuffer* vertexBuffer); + }; +} #endif // NAZARA_FORWARDRENDERQUEUE_HPP diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 766fd6fc9..855eb9461 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -16,80 +16,83 @@ #include #include -class NAZARA_GRAPHICS_API NzForwardRenderTechnique : public NzAbstractRenderTechnique +namespace Nz { - public: - NzForwardRenderTechnique(); - ~NzForwardRenderTechnique() = default; + class NAZARA_GRAPHICS_API ForwardRenderTechnique : public AbstractRenderTechnique + { + public: + ForwardRenderTechnique(); + ~ForwardRenderTechnique() = default; - bool Draw(const NzSceneData& sceneData) const override; + bool Draw(const SceneData& sceneData) const override; - unsigned int GetMaxLightPassPerObject() const; - NzAbstractRenderQueue* GetRenderQueue() override; - nzRenderTechniqueType GetType() const override; + unsigned int GetMaxLightPassPerObject() const; + AbstractRenderQueue* GetRenderQueue() override; + RenderTechniqueType GetType() const override; - void SetMaxLightPassPerObject(unsigned int passCount); + void SetMaxLightPassPerObject(unsigned int passCount); - static bool Initialize(); - static void Uninitialize(); + static bool Initialize(); + static void Uninitialize(); - private: - struct ShaderUniforms; + private: + struct ShaderUniforms; - void ChooseLights(const NzSpheref& object, bool includeDirectionalLights = true) const; - void DrawBasicSprites(const NzSceneData& sceneData) const; - void DrawBillboards(const NzSceneData& sceneData) const; - void DrawOpaqueModels(const NzSceneData& sceneData) const; - void DrawTransparentModels(const NzSceneData& sceneData) const; - const ShaderUniforms* GetShaderUniforms(const NzShader* shader) const; - void OnShaderInvalidated(const NzShader* shader) const; - void SendLightUniforms(const NzShader* shader, const NzLightUniforms& uniforms, unsigned int index, unsigned int uniformOffset) const; + void ChooseLights(const Spheref& object, bool includeDirectionalLights = true) const; + void DrawBasicSprites(const SceneData& sceneData) const; + void DrawBillboards(const SceneData& sceneData) const; + void DrawOpaqueModels(const SceneData& sceneData) const; + void DrawTransparentModels(const SceneData& sceneData) const; + const ShaderUniforms* GetShaderUniforms(const Shader* shader) const; + void OnShaderInvalidated(const Shader* shader) const; + void SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset) const; - static float ComputeDirectionalLightScore(const NzSpheref& object, const NzAbstractRenderQueue::DirectionalLight& light); - static float ComputePointLightScore(const NzSpheref& object, const NzAbstractRenderQueue::PointLight& light); - static float ComputeSpotLightScore(const NzSpheref& object, const NzAbstractRenderQueue::SpotLight& light); - static bool IsDirectionalLightSuitable(const NzSpheref& object, const NzAbstractRenderQueue::DirectionalLight& light); - static bool IsPointLightSuitable(const NzSpheref& object, const NzAbstractRenderQueue::PointLight& light); - static bool IsSpotLightSuitable(const NzSpheref& object, const NzAbstractRenderQueue::SpotLight& light); + static float ComputeDirectionalLightScore(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light); + static float ComputePointLightScore(const Spheref& object, const AbstractRenderQueue::PointLight& light); + static float ComputeSpotLightScore(const Spheref& object, const AbstractRenderQueue::SpotLight& light); + static bool IsDirectionalLightSuitable(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light); + static bool IsPointLightSuitable(const Spheref& object, const AbstractRenderQueue::PointLight& light); + static bool IsSpotLightSuitable(const Spheref& object, const AbstractRenderQueue::SpotLight& light); - struct LightIndex - { - nzLightType type; - float score; - unsigned int index; - }; + struct LightIndex + { + LightType type; + float score; + unsigned int index; + }; - struct ShaderUniforms - { - NazaraSlot(NzShader, OnShaderUniformInvalidated, shaderUniformInvalidatedSlot); - NazaraSlot(NzShader, OnShaderRelease, shaderReleaseSlot); + struct ShaderUniforms + { + NazaraSlot(Shader, OnShaderUniformInvalidated, shaderUniformInvalidatedSlot); + NazaraSlot(Shader, OnShaderRelease, shaderReleaseSlot); - NzLightUniforms lightUniforms; - bool hasLightUniforms; + LightUniforms lightUniforms; + bool hasLightUniforms; - /// Moins coûteux en mémoire que de stocker un NzLightUniforms par index de lumière, - /// à voir si ça fonctionne chez tout le monde - int lightOffset; // "Distance" entre Lights[0].type et Lights[1].type + /// Moins coûteux en mémoire que de stocker un LightUniforms par index de lumière, + /// à voir si ça fonctionne chez tout le monde + int lightOffset; // "Distance" entre Lights[0].type et Lights[1].type - // Autre uniformes - int eyePosition; - int sceneAmbient; - int textureOverlay; - }; + // Autre uniformes + int eyePosition; + int sceneAmbient; + int textureOverlay; + }; - mutable std::unordered_map m_shaderUniforms; - mutable std::vector m_lights; - NzBuffer m_vertexBuffer; - mutable NzForwardRenderQueue m_renderQueue; - NzVertexBuffer m_billboardPointBuffer; - NzVertexBuffer m_spriteBuffer; - unsigned int m_maxLightPassPerObject; + mutable std::unordered_map m_shaderUniforms; + mutable std::vector m_lights; + Buffer m_vertexBuffer; + mutable ForwardRenderQueue m_renderQueue; + VertexBuffer m_billboardPointBuffer; + VertexBuffer m_spriteBuffer; + unsigned int m_maxLightPassPerObject; - static NzIndexBuffer s_quadIndexBuffer; - static NzVertexBuffer s_quadVertexBuffer; - static NzVertexDeclaration s_billboardInstanceDeclaration; - static NzVertexDeclaration s_billboardVertexDeclaration; -}; + static IndexBuffer s_quadIndexBuffer; + static VertexBuffer s_quadVertexBuffer; + static VertexDeclaration s_billboardInstanceDeclaration; + static VertexDeclaration s_billboardVertexDeclaration; + }; +} #include diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.inl b/include/Nazara/Graphics/ForwardRenderTechnique.inl index 8d4d8736b..69ae7614f 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.inl +++ b/include/Nazara/Graphics/ForwardRenderTechnique.inl @@ -2,92 +2,95 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -inline void NzForwardRenderTechnique::SendLightUniforms(const NzShader* shader, const NzLightUniforms& uniforms, unsigned int index, unsigned int uniformOffset) const +namespace Nz { - if (index < m_lights.size()) + inline void ForwardRenderTechnique::SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset) const { - const LightIndex& lightIndex = m_lights[index]; - - shader->SendInteger(uniforms.locations.type + uniformOffset, lightIndex.type); //< Sends the light type - - switch (lightIndex.type) + if (index < m_lights.size()) { - case nzLightType_Directional: + const LightIndex& lightIndex = m_lights[index]; + + shader->SendInteger(uniforms.locations.type + uniformOffset, lightIndex.type); //< Sends the light type + + switch (lightIndex.type) { - const auto& light = m_renderQueue.directionalLights[lightIndex.index]; + case LightType_Directional: + { + const auto& light = m_renderQueue.directionalLights[lightIndex.index]; - shader->SendColor(uniforms.locations.color + uniformOffset, light.color); - shader->SendVector(uniforms.locations.factors + uniformOffset, NzVector2f(light.ambientFactor, light.diffuseFactor)); - shader->SendVector(uniforms.locations.parameters1 + uniformOffset, NzVector4f(light.direction)); - break; - } + shader->SendColor(uniforms.locations.color + uniformOffset, light.color); + shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); + shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.direction)); + break; + } - case nzLightType_Point: - { - const auto& light = m_renderQueue.pointLights[lightIndex.index]; + case LightType_Point: + { + const auto& light = m_renderQueue.pointLights[lightIndex.index]; - shader->SendColor(uniforms.locations.color + uniformOffset, light.color); - shader->SendVector(uniforms.locations.factors + uniformOffset, NzVector2f(light.ambientFactor, light.diffuseFactor)); - shader->SendVector(uniforms.locations.parameters1 + uniformOffset, NzVector4f(light.position, light.attenuation)); - shader->SendVector(uniforms.locations.parameters2 + uniformOffset, NzVector4f(0.f, 0.f, 0.f, light.invRadius)); - break; - } + shader->SendColor(uniforms.locations.color + uniformOffset, light.color); + shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); + shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.position, light.attenuation)); + shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(0.f, 0.f, 0.f, light.invRadius)); + break; + } - case nzLightType_Spot: - { - const auto& light = m_renderQueue.spotLights[lightIndex.index]; + case LightType_Spot: + { + const auto& light = m_renderQueue.spotLights[lightIndex.index]; - shader->SendColor(uniforms.locations.color + uniformOffset, light.color); - shader->SendVector(uniforms.locations.factors + uniformOffset, NzVector2f(light.ambientFactor, light.diffuseFactor)); - shader->SendVector(uniforms.locations.parameters1 + uniformOffset, NzVector4f(light.position, light.attenuation)); - shader->SendVector(uniforms.locations.parameters2 + uniformOffset, NzVector4f(light.direction, light.invRadius)); - shader->SendVector(uniforms.locations.parameters3 + uniformOffset, NzVector2f(light.innerAngleCosine, light.outerAngleCosine)); - break; + shader->SendColor(uniforms.locations.color + uniformOffset, light.color); + shader->SendVector(uniforms.locations.factors + uniformOffset, Vector2f(light.ambientFactor, light.diffuseFactor)); + shader->SendVector(uniforms.locations.parameters1 + uniformOffset, Vector4f(light.position, light.attenuation)); + shader->SendVector(uniforms.locations.parameters2 + uniformOffset, Vector4f(light.direction, light.invRadius)); + shader->SendVector(uniforms.locations.parameters3 + uniformOffset, Vector2f(light.innerAngleCosine, light.outerAngleCosine)); + break; + } } } + else + shader->SendInteger(uniforms.locations.type + uniformOffset, -1); //< Disable the light in the shader + } + + inline float ForwardRenderTechnique::ComputeDirectionalLightScore(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light) + { + NazaraUnused(object); + NazaraUnused(light); + + ///TODO: Compute a score depending on the light luminosity + return 0.f; + } + + inline float ForwardRenderTechnique::ComputePointLightScore(const Spheref& object, const AbstractRenderQueue::PointLight& light) + { + ///TODO: Compute a score depending on the light luminosity + return object.SquaredDistance(light.position); + } + + inline float ForwardRenderTechnique::ComputeSpotLightScore(const Spheref& object, const AbstractRenderQueue::SpotLight& light) + { + ///TODO: Compute a score depending on the light luminosity and spot direction + return object.SquaredDistance(light.position); + } + + inline bool ForwardRenderTechnique::IsDirectionalLightSuitable(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light) + { + NazaraUnused(object); + NazaraUnused(light); + + // Directional light are always suitables + return true; + } + + inline bool ForwardRenderTechnique::IsPointLightSuitable(const Spheref& object, const AbstractRenderQueue::PointLight& light) + { + // If the object is too far away from this point light, there is not way it could light it + return object.SquaredDistance(light.position) <= light.radius * light.radius; + } + + inline bool ForwardRenderTechnique::IsSpotLightSuitable(const Spheref& object, const AbstractRenderQueue::SpotLight& light) + { + ///TODO: Exclude spot lights based on their direction and outer angle? + return object.SquaredDistance(light.position) <= light.radius * light.radius; } - else - shader->SendInteger(uniforms.locations.type + uniformOffset, -1); //< Disable the light in the shader -} - -inline float NzForwardRenderTechnique::ComputeDirectionalLightScore(const NzSpheref& object, const NzAbstractRenderQueue::DirectionalLight& light) -{ - NazaraUnused(object); - NazaraUnused(light); - - ///TODO: Compute a score depending on the light luminosity - return 0.f; -} - -inline float NzForwardRenderTechnique::ComputePointLightScore(const NzSpheref& object, const NzAbstractRenderQueue::PointLight& light) -{ - ///TODO: Compute a score depending on the light luminosity - return object.SquaredDistance(light.position); -} - -inline float NzForwardRenderTechnique::ComputeSpotLightScore(const NzSpheref& object, const NzAbstractRenderQueue::SpotLight& light) -{ - ///TODO: Compute a score depending on the light luminosity and spot direction - return object.SquaredDistance(light.position); -} - -inline bool NzForwardRenderTechnique::IsDirectionalLightSuitable(const NzSpheref& object, const NzAbstractRenderQueue::DirectionalLight& light) -{ - NazaraUnused(object); - NazaraUnused(light); - - // Directional light are always suitables - return true; -} - -inline bool NzForwardRenderTechnique::IsPointLightSuitable(const NzSpheref& object, const NzAbstractRenderQueue::PointLight& light) -{ - // If the object is too far away from this point light, there is not way it could light it - return object.SquaredDistance(light.position) <= light.radius * light.radius; -} - -inline bool NzForwardRenderTechnique::IsSpotLightSuitable(const NzSpheref& object, const NzAbstractRenderQueue::SpotLight& light) -{ - ///TODO: Exclude spot lights based on their direction and outer angle? - return object.SquaredDistance(light.position) <= light.radius * light.radius; } diff --git a/include/Nazara/Graphics/Graphics.hpp b/include/Nazara/Graphics/Graphics.hpp index 287e36121..e2aef76ba 100644 --- a/include/Nazara/Graphics/Graphics.hpp +++ b/include/Nazara/Graphics/Graphics.hpp @@ -11,20 +11,23 @@ #include #include -class NAZARA_GRAPHICS_API NzGraphics +namespace Nz { - public: - NzGraphics() = delete; - ~NzGraphics() = delete; + class NAZARA_GRAPHICS_API Graphics + { + public: + Graphics() = delete; + ~Graphics() = delete; - static bool Initialize(); + static bool Initialize(); - static bool IsInitialized(); + static bool IsInitialized(); - static void Uninitialize(); + static void Uninitialize(); - private: - static unsigned int s_moduleReferenceCounter; -}; + private: + static unsigned int s_moduleReferenceCounter; + }; +} #endif // NAZARA_GRAPHICS_HPP diff --git a/include/Nazara/Graphics/GuillotineTextureAtlas.hpp b/include/Nazara/Graphics/GuillotineTextureAtlas.hpp index 1076dc453..b40e4f610 100644 --- a/include/Nazara/Graphics/GuillotineTextureAtlas.hpp +++ b/include/Nazara/Graphics/GuillotineTextureAtlas.hpp @@ -11,16 +11,19 @@ #include #include -class NAZARA_GRAPHICS_API NzGuillotineTextureAtlas : public NzGuillotineImageAtlas +namespace Nz { - public: - NzGuillotineTextureAtlas() = default; - ~NzGuillotineTextureAtlas() = default; + class NAZARA_GRAPHICS_API GuillotineTextureAtlas : public GuillotineImageAtlas + { + public: + GuillotineTextureAtlas() = default; + ~GuillotineTextureAtlas() = default; - nzUInt32 GetStorage() const; + UInt32 GetStorage() const; - private: - NzAbstractImage* ResizeImage(NzAbstractImage* oldImage, const NzVector2ui& size) const override; -}; + private: + AbstractImage* ResizeImage(AbstractImage* oldImage, const Vector2ui& size) const override; + }; +} #endif // NAZARA_GUILLOTINETEXTUREATLAS_HPP diff --git a/include/Nazara/Graphics/InstancedRenderable.hpp b/include/Nazara/Graphics/InstancedRenderable.hpp index 2428b4e7b..f3f17d866 100644 --- a/include/Nazara/Graphics/InstancedRenderable.hpp +++ b/include/Nazara/Graphics/InstancedRenderable.hpp @@ -17,66 +17,69 @@ #include #include -class NzAbstractRenderQueue; -class NzInstancedRenderable; - -using NzInstancedRenderableConstRef = NzObjectRef; -using NzInstancedRenderableLibrary = NzObjectLibrary; -using NzInstancedRenderableRef = NzObjectRef; - -class NAZARA_GRAPHICS_API NzInstancedRenderable : public NzRefCounted +namespace Nz { - public: - struct InstanceData; + class AbstractRenderQueue; + class InstancedRenderable; - NzInstancedRenderable() = default; - inline NzInstancedRenderable(const NzInstancedRenderable& renderable); - NzInstancedRenderable(NzInstancedRenderable&& renderable) = delete; - virtual ~NzInstancedRenderable(); + using InstancedRenderableConstRef = ObjectRef; + using InstancedRenderableLibrary = ObjectLibrary; + using InstancedRenderableRef = ObjectRef; - inline void EnsureBoundingVolumeUpdated() const; + class NAZARA_GRAPHICS_API InstancedRenderable : public RefCounted + { + public: + struct InstanceData; - virtual void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const = 0; - virtual bool Cull(const NzFrustumf& frustum, const InstanceData& instanceData) const; - virtual const NzBoundingVolumef& GetBoundingVolume() const; - virtual void InvalidateData(InstanceData* instanceData, nzUInt32 flags) const; - virtual void UpdateBoundingVolume(InstanceData* instanceData) const; - virtual void UpdateData(InstanceData* instanceData) const; + InstancedRenderable() = default; + inline InstancedRenderable(const InstancedRenderable& renderable); + InstancedRenderable(InstancedRenderable&& renderable) = delete; + virtual ~InstancedRenderable(); - inline NzInstancedRenderable& operator=(const NzInstancedRenderable& renderable); - NzInstancedRenderable& operator=(NzInstancedRenderable&& renderable) = delete; + inline void EnsureBoundingVolumeUpdated() const; - // Signals: - NazaraSignal(OnInstancedRenderableInvalidateData, const NzInstancedRenderable* /*instancedRenderable*/, nzUInt32 /*flags*/); - NazaraSignal(OnInstancedRenderableRelease, const NzInstancedRenderable* /*instancedRenderable*/); + virtual void AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const = 0; + virtual bool Cull(const Frustumf& frustum, const InstanceData& instanceData) const; + virtual const BoundingVolumef& GetBoundingVolume() const; + virtual void InvalidateData(InstanceData* instanceData, UInt32 flags) const; + virtual void UpdateBoundingVolume(InstanceData* instanceData) const; + virtual void UpdateData(InstanceData* instanceData) const; - struct InstanceData - { - InstanceData(NzMatrix4f& referenceMatrix) : - transformMatrix(referenceMatrix), - flags(0) + inline InstancedRenderable& operator=(const InstancedRenderable& renderable); + InstancedRenderable& operator=(InstancedRenderable&& renderable) = delete; + + // Signals: + NazaraSignal(OnInstancedRenderableInvalidateData, const InstancedRenderable* /*instancedRenderable*/, UInt32 /*flags*/); + NazaraSignal(OnInstancedRenderableRelease, const InstancedRenderable* /*instancedRenderable*/); + + struct InstanceData { - } + InstanceData(Matrix4f& referenceMatrix) : + transformMatrix(referenceMatrix), + flags(0) + { + } - std::vector data; - NzBoundingVolumef volume; - NzMatrix4f& transformMatrix; - nzUInt32 flags; - }; + std::vector data; + BoundingVolumef volume; + Matrix4f& transformMatrix; + UInt32 flags; + }; - protected: - virtual void MakeBoundingVolume() const = 0; - void InvalidateBoundingVolume(); - inline void InvalidateInstanceData(nzUInt32 flags); - inline void UpdateBoundingVolume() const; + protected: + virtual void MakeBoundingVolume() const = 0; + void InvalidateBoundingVolume(); + inline void InvalidateInstanceData(UInt32 flags); + inline void UpdateBoundingVolume() const; - mutable NzBoundingVolumef m_boundingVolume; + mutable BoundingVolumef m_boundingVolume; - private: - mutable bool m_boundingVolumeUpdated; + private: + mutable bool m_boundingVolumeUpdated; - static NzInstancedRenderableLibrary::LibraryMap s_library; -}; + static InstancedRenderableLibrary::LibraryMap s_library; + }; +} #include diff --git a/include/Nazara/Graphics/InstancedRenderable.inl b/include/Nazara/Graphics/InstancedRenderable.inl index 6023e684c..0cc97f101 100644 --- a/include/Nazara/Graphics/InstancedRenderable.inl +++ b/include/Nazara/Graphics/InstancedRenderable.inl @@ -2,39 +2,42 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -inline NzInstancedRenderable::NzInstancedRenderable(const NzInstancedRenderable& renderable) : -NzRefCounted(), -m_boundingVolume(renderable.m_boundingVolume), -m_boundingVolumeUpdated(renderable.m_boundingVolumeUpdated) +namespace Nz { -} + inline InstancedRenderable::InstancedRenderable(const InstancedRenderable& renderable) : + RefCounted(), + m_boundingVolume(renderable.m_boundingVolume), + m_boundingVolumeUpdated(renderable.m_boundingVolumeUpdated) + { + } -inline void NzInstancedRenderable::EnsureBoundingVolumeUpdated() const -{ - if (!m_boundingVolumeUpdated) - UpdateBoundingVolume(); -} + inline void InstancedRenderable::EnsureBoundingVolumeUpdated() const + { + if (!m_boundingVolumeUpdated) + UpdateBoundingVolume(); + } -inline void NzInstancedRenderable::InvalidateBoundingVolume() -{ - m_boundingVolumeUpdated = false; -} + inline void InstancedRenderable::InvalidateBoundingVolume() + { + m_boundingVolumeUpdated = false; + } -inline void NzInstancedRenderable::InvalidateInstanceData(nzUInt32 flags) -{ - OnInstancedRenderableInvalidateData(this, flags); -} + inline void InstancedRenderable::InvalidateInstanceData(UInt32 flags) + { + OnInstancedRenderableInvalidateData(this, flags); + } -inline NzInstancedRenderable& NzInstancedRenderable::operator=(const NzInstancedRenderable& renderable) -{ - m_boundingVolume = renderable.m_boundingVolume; - m_boundingVolumeUpdated = renderable.m_boundingVolumeUpdated; + inline InstancedRenderable& InstancedRenderable::operator=(const InstancedRenderable& renderable) + { + m_boundingVolume = renderable.m_boundingVolume; + m_boundingVolumeUpdated = renderable.m_boundingVolumeUpdated; - return *this; -} + return *this; + } -inline void NzInstancedRenderable::UpdateBoundingVolume() const -{ - MakeBoundingVolume(); - m_boundingVolumeUpdated = true; + inline void InstancedRenderable::UpdateBoundingVolume() const + { + MakeBoundingVolume(); + m_boundingVolumeUpdated = true; + } } diff --git a/include/Nazara/Graphics/Light.hpp b/include/Nazara/Graphics/Light.hpp index 9a6a4235b..efa468ba6 100644 --- a/include/Nazara/Graphics/Light.hpp +++ b/include/Nazara/Graphics/Light.hpp @@ -12,86 +12,89 @@ #include #include -class NzLight; -struct NzLightUniforms; - -class NAZARA_GRAPHICS_API NzLight : public NzRenderable +namespace Nz { - public: - NzLight(nzLightType type = nzLightType_Point); - NzLight(const NzLight& light) = default; - ~NzLight() = default; + class Light; + struct LightUniforms; - void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const override; - - NzLight* Clone() const; - NzLight* Create() const; - - bool Cull(const NzFrustumf& frustum, const NzMatrix4f& transformMatrix) const override; - - float GetAmbientFactor() const; - float GetAttenuation() const; - NzColor GetColor() const; - float GetDiffuseFactor() const; - float GetInnerAngle() const; - float GetInnerAngleCosine() const; - float GetInvRadius() const; - nzLightType GetLightType() const; - float GetOuterAngle() const; - float GetOuterAngleCosine() const; - float GetOuterAngleTangent() const; - float GetRadius() const; - - void SetAmbientFactor(float factor); - void SetAttenuation(float attenuation); - void SetColor(const NzColor& color); - void SetDiffuseFactor(float factor); - void SetInnerAngle(float innerAngle); - void SetLightType(nzLightType type); - void SetOuterAngle(float outerAngle); - void SetRadius(float radius); - - void UpdateBoundingVolume(const NzMatrix4f& transformMatrix) override; - - NzLight& operator=(const NzLight& light) = default; - - private: - void MakeBoundingVolume() const override; - - nzLightType m_type; - NzColor m_color; - float m_ambientFactor; - float m_attenuation; - float m_diffuseFactor; - float m_innerAngle; - float m_innerAngleCosine; - float m_invRadius; - float m_outerAngle; - float m_outerAngleCosine; - float m_outerAngleTangent; - float m_radius; -}; - -struct NzLightUniforms -{ - struct UniformLocations + class NAZARA_GRAPHICS_API Light : public Renderable { - int type; - int color; - int factors; - int parameters1; - int parameters2; - int parameters3; + public: + Light(LightType type = LightType_Point); + Light(const Light& light) = default; + ~Light() = default; + + void AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const override; + + Light* Clone() const; + Light* Create() const; + + bool Cull(const Frustumf& frustum, const Matrix4f& transformMatrix) const override; + + float GetAmbientFactor() const; + float GetAttenuation() const; + Color GetColor() const; + float GetDiffuseFactor() const; + float GetInnerAngle() const; + float GetInnerAngleCosine() const; + float GetInvRadius() const; + LightType GetLightType() const; + float GetOuterAngle() const; + float GetOuterAngleCosine() const; + float GetOuterAngleTangent() const; + float GetRadius() const; + + void SetAmbientFactor(float factor); + void SetAttenuation(float attenuation); + void SetColor(const Color& color); + void SetDiffuseFactor(float factor); + void SetInnerAngle(float innerAngle); + void SetLightType(LightType type); + void SetOuterAngle(float outerAngle); + void SetRadius(float radius); + + void UpdateBoundingVolume(const Matrix4f& transformMatrix) override; + + Light& operator=(const Light& light) = default; + + private: + void MakeBoundingVolume() const override; + + LightType m_type; + Color m_color; + float m_ambientFactor; + float m_attenuation; + float m_diffuseFactor; + float m_innerAngle; + float m_innerAngleCosine; + float m_invRadius; + float m_outerAngle; + float m_outerAngleCosine; + float m_outerAngleTangent; + float m_radius; }; - bool ubo; - - union + struct LightUniforms { - UniformLocations locations; - int blockLocation; + struct UniformLocations + { + int type; + int color; + int factors; + int parameters1; + int parameters2; + int parameters3; + }; + + bool ubo; + + union + { + UniformLocations locations; + int blockLocation; + }; }; -}; +} #include diff --git a/include/Nazara/Graphics/Light.inl b/include/Nazara/Graphics/Light.inl index 2d594a178..ff3f7bb6b 100644 --- a/include/Nazara/Graphics/Light.inl +++ b/include/Nazara/Graphics/Light.inl @@ -5,103 +5,106 @@ #include #include -inline float NzLight::GetAmbientFactor() const +namespace Nz { - return m_ambientFactor; -} + inline float Light::GetAmbientFactor() const + { + return m_ambientFactor; + } -inline float NzLight::GetAttenuation() const -{ - return m_attenuation; -} + inline float Light::GetAttenuation() const + { + return m_attenuation; + } -inline NzColor NzLight::GetColor() const -{ - return m_color; -} + inline Color Light::GetColor() const + { + return m_color; + } -inline float NzLight::GetDiffuseFactor() const -{ - return m_diffuseFactor; -} + inline float Light::GetDiffuseFactor() const + { + return m_diffuseFactor; + } -inline float NzLight::GetInnerAngle() const -{ - return m_innerAngle; -} + inline float Light::GetInnerAngle() const + { + return m_innerAngle; + } -inline nzLightType NzLight::GetLightType() const -{ - return m_type; -} + inline LightType Light::GetLightType() const + { + return m_type; + } -inline float NzLight::GetOuterAngle() const -{ - return m_outerAngle; -} + inline float Light::GetOuterAngle() const + { + return m_outerAngle; + } -inline float NzLight::GetOuterAngleCosine() const -{ - return m_outerAngleCosine; -} + inline float Light::GetOuterAngleCosine() const + { + return m_outerAngleCosine; + } -inline float NzLight::GetOuterAngleTangent() const -{ - return m_outerAngleTangent; -} + inline float Light::GetOuterAngleTangent() const + { + return m_outerAngleTangent; + } -inline float NzLight::GetRadius() const -{ - return m_radius; -} + inline float Light::GetRadius() const + { + return m_radius; + } -inline void NzLight::SetAmbientFactor(float factor) -{ - m_ambientFactor = factor; -} + inline void Light::SetAmbientFactor(float factor) + { + m_ambientFactor = factor; + } -inline void NzLight::SetAttenuation(float attenuation) -{ - m_attenuation = attenuation; -} + inline void Light::SetAttenuation(float attenuation) + { + m_attenuation = attenuation; + } -inline void NzLight::SetColor(const NzColor& color) -{ - m_color = color; -} + inline void Light::SetColor(const Color& color) + { + m_color = color; + } -inline void NzLight::SetDiffuseFactor(float factor) -{ - m_diffuseFactor = factor; -} + inline void Light::SetDiffuseFactor(float factor) + { + m_diffuseFactor = factor; + } -inline void NzLight::SetInnerAngle(float innerAngle) -{ - m_innerAngle = innerAngle; - m_innerAngleCosine = std::cos(NzDegreeToRadian(m_innerAngle)); -} + inline void Light::SetInnerAngle(float innerAngle) + { + m_innerAngle = innerAngle; + m_innerAngleCosine = std::cos(NzDegreeToRadian(m_innerAngle)); + } -inline void NzLight::SetLightType(nzLightType type) -{ - m_type = type; -} + inline void Light::SetLightType(LightType type) + { + m_type = type; + } -inline void NzLight::SetOuterAngle(float outerAngle) -{ - m_outerAngle = outerAngle; - m_outerAngleCosine = std::cos(NzDegreeToRadian(m_outerAngle)); - m_outerAngleTangent = std::tan(NzDegreeToRadian(m_outerAngle)); + inline void Light::SetOuterAngle(float outerAngle) + { + m_outerAngle = outerAngle; + m_outerAngleCosine = std::cos(NzDegreeToRadian(m_outerAngle)); + m_outerAngleTangent = std::tan(NzDegreeToRadian(m_outerAngle)); - InvalidateBoundingVolume(); -} + InvalidateBoundingVolume(); + } -inline void NzLight::SetRadius(float radius) -{ - m_radius = radius; + inline void Light::SetRadius(float radius) + { + m_radius = radius; - m_invRadius = 1.f / m_radius; + m_invRadius = 1.f / m_radius; - InvalidateBoundingVolume(); + InvalidateBoundingVolume(); + } } #include diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 94d2c47c5..7e55f285a 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -24,169 +24,172 @@ #include #include -struct NAZARA_GRAPHICS_API NzMaterialParams +namespace Nz { - bool loadAlphaMap = true; - bool loadDiffuseMap = true; - bool loadEmissiveMap = true; - bool loadHeightMap = true; - bool loadNormalMap = true; - bool loadSpecularMap = true; - NzString shaderName = "Basic"; + struct NAZARA_GRAPHICS_API MaterialParams + { + bool loadAlphaMap = true; + bool loadDiffuseMap = true; + bool loadEmissiveMap = true; + bool loadHeightMap = true; + bool loadNormalMap = true; + bool loadSpecularMap = true; + String shaderName = "Basic"; - bool IsValid() const; -}; + bool IsValid() const; + }; -class NzMaterial; + class Material; -using NzMaterialConstRef = NzObjectRef; -using NzMaterialLibrary = NzObjectLibrary; -using NzMaterialLoader = NzResourceLoader; -using NzMaterialManager = NzResourceManager; -using NzMaterialRef = NzObjectRef; + using MaterialConstRef = ObjectRef; + using MaterialLibrary = ObjectLibrary; + using MaterialLoader = ResourceLoader; + using MaterialManager = ResourceManager; + using MaterialRef = ObjectRef; -class NAZARA_GRAPHICS_API NzMaterial : public NzRefCounted, public NzResource -{ - friend NzMaterialLibrary; - friend NzMaterialLoader; - friend NzMaterialManager; - friend class NzGraphics; + class NAZARA_GRAPHICS_API Material : public RefCounted, public Resource + { + friend MaterialLibrary; + friend MaterialLoader; + friend MaterialManager; + friend class Graphics; - public: - NzMaterial(); - NzMaterial(const NzMaterial& material); - ~NzMaterial(); + public: + Material(); + Material(const Material& material); + ~Material(); - const NzShader* Apply(nzUInt32 shaderFlags = 0, nzUInt8 textureUnit = 0, nzUInt8* lastUsedUnit = nullptr) const; + const Shader* Apply(UInt32 shaderFlags = 0, UInt8 textureUnit = 0, UInt8* lastUsedUnit = nullptr) const; - void Enable(nzRendererParameter renderParameter, bool enable); - void EnableAlphaTest(bool alphaTest); - void EnableDepthSorting(bool depthSorting); - void EnableLighting(bool lighting); - void EnableTransform(bool transform); + void Enable(RendererParameter renderParameter, bool enable); + void EnableAlphaTest(bool alphaTest); + void EnableDepthSorting(bool depthSorting); + void EnableLighting(bool lighting); + void EnableTransform(bool transform); - NzTexture* GetAlphaMap() const; - float GetAlphaThreshold() const; - NzColor GetAmbientColor() const; - nzRendererComparison GetDepthFunc() const; - NzColor GetDiffuseColor() const; - NzTexture* GetDiffuseMap() const; - NzTextureSampler& GetDiffuseSampler(); - const NzTextureSampler& GetDiffuseSampler() const; - nzBlendFunc GetDstBlend() const; - NzTexture* GetEmissiveMap() const; - nzFaceSide GetFaceCulling() const; - nzFaceFilling GetFaceFilling() const; - NzTexture* GetHeightMap() const; - NzTexture* GetNormalMap() const; - const NzRenderStates& GetRenderStates() const; - const NzUberShader* GetShader() const; - const NzUberShaderInstance* GetShaderInstance(nzUInt32 flags = nzShaderFlags_None) const; - float GetShininess() const; - NzColor GetSpecularColor() const; - NzTexture* GetSpecularMap() const; - NzTextureSampler& GetSpecularSampler(); - const NzTextureSampler& GetSpecularSampler() const; - nzBlendFunc GetSrcBlend() const; + Texture* GetAlphaMap() const; + float GetAlphaThreshold() const; + Color GetAmbientColor() const; + RendererComparison GetDepthFunc() const; + Color GetDiffuseColor() const; + Texture* GetDiffuseMap() const; + TextureSampler& GetDiffuseSampler(); + const TextureSampler& GetDiffuseSampler() const; + BlendFunc GetDstBlend() const; + Texture* GetEmissiveMap() const; + FaceSide GetFaceCulling() const; + FaceFilling GetFaceFilling() const; + Texture* GetHeightMap() const; + Texture* GetNormalMap() const; + const RenderStates& GetRenderStates() const; + const UberShader* GetShader() const; + const UberShaderInstance* GetShaderInstance(UInt32 flags = ShaderFlags_None) const; + float GetShininess() const; + Color GetSpecularColor() const; + Texture* GetSpecularMap() const; + TextureSampler& GetSpecularSampler(); + const TextureSampler& GetSpecularSampler() const; + BlendFunc GetSrcBlend() const; - bool HasAlphaMap() const; - bool HasDiffuseMap() const; - bool HasEmissiveMap() const; - bool HasHeightMap() const; - bool HasNormalMap() const; - bool HasSpecularMap() const; + bool HasAlphaMap() const; + bool HasDiffuseMap() const; + bool HasEmissiveMap() const; + bool HasHeightMap() const; + bool HasNormalMap() const; + bool HasSpecularMap() const; - bool IsAlphaTestEnabled() const; - bool IsDepthSortingEnabled() const; - bool IsEnabled(nzRendererParameter renderParameter) const; - bool IsLightingEnabled() const; - bool IsTransformEnabled() const; + bool IsAlphaTestEnabled() const; + bool IsDepthSortingEnabled() const; + bool IsEnabled(RendererParameter renderParameter) const; + bool IsLightingEnabled() const; + bool IsTransformEnabled() const; - bool LoadFromFile(const NzString& filePath, const NzMaterialParams& params = NzMaterialParams()); - bool LoadFromMemory(const void* data, std::size_t size, const NzMaterialParams& params = NzMaterialParams()); - bool LoadFromStream(NzInputStream& stream, const NzMaterialParams& params = NzMaterialParams()); + bool LoadFromFile(const String& filePath, const MaterialParams& params = MaterialParams()); + bool LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params = MaterialParams()); + bool LoadFromStream(InputStream& stream, const MaterialParams& params = MaterialParams()); - void Reset(); + void Reset(); - bool SetAlphaMap(const NzString& textureName); - void SetAlphaMap(NzTextureRef alphaMap); - void SetAlphaThreshold(float alphaThreshold); - void SetAmbientColor(const NzColor& ambient); - void SetDepthFunc(nzRendererComparison depthFunc); - void SetDiffuseColor(const NzColor& diffuse); - bool SetDiffuseMap(const NzString& textureName); - void SetDiffuseMap(NzTextureRef diffuseMap); - void SetDiffuseSampler(const NzTextureSampler& sampler); - void SetDstBlend(nzBlendFunc func); - bool SetEmissiveMap(const NzString& textureName); - void SetEmissiveMap(NzTextureRef textureName); - void SetFaceCulling(nzFaceSide faceSide); - void SetFaceFilling(nzFaceFilling filling); - bool SetHeightMap(const NzString& textureName); - void SetHeightMap(NzTextureRef textureName); - bool SetNormalMap(const NzString& textureName); - void SetNormalMap(NzTextureRef textureName); - void SetRenderStates(const NzRenderStates& states); - void SetShader(NzUberShaderConstRef uberShader); - bool SetShader(const NzString& uberShaderName); - void SetShininess(float shininess); - void SetSpecularColor(const NzColor& specular); - bool SetSpecularMap(const NzString& textureName); - void SetSpecularMap(NzTextureRef specularMap); - void SetSpecularSampler(const NzTextureSampler& sampler); - void SetSrcBlend(nzBlendFunc func); + bool SetAlphaMap(const String& textureName); + void SetAlphaMap(TextureRef alphaMap); + void SetAlphaThreshold(float alphaThreshold); + void SetAmbientColor(const Color& ambient); + void SetDepthFunc(RendererComparison depthFunc); + void SetDiffuseColor(const Color& diffuse); + bool SetDiffuseMap(const String& textureName); + void SetDiffuseMap(TextureRef diffuseMap); + void SetDiffuseSampler(const TextureSampler& sampler); + void SetDstBlend(BlendFunc func); + bool SetEmissiveMap(const String& textureName); + void SetEmissiveMap(TextureRef textureName); + void SetFaceCulling(FaceSide faceSide); + void SetFaceFilling(FaceFilling filling); + bool SetHeightMap(const String& textureName); + void SetHeightMap(TextureRef textureName); + bool SetNormalMap(const String& textureName); + void SetNormalMap(TextureRef textureName); + void SetRenderStates(const RenderStates& states); + void SetShader(UberShaderConstRef uberShader); + bool SetShader(const String& uberShaderName); + void SetShininess(float shininess); + void SetSpecularColor(const Color& specular); + bool SetSpecularMap(const String& textureName); + void SetSpecularMap(TextureRef specularMap); + void SetSpecularSampler(const TextureSampler& sampler); + void SetSrcBlend(BlendFunc func); - NzMaterial& operator=(const NzMaterial& material); + Material& operator=(const Material& material); - static NzMaterialRef GetDefault(); - template static NzMaterialRef New(Args&&... args); + static MaterialRef GetDefault(); + template static MaterialRef New(Args&&... args); - // Signals: - NazaraSignal(OnMaterialRelease, const NzMaterial* /*material*/); - NazaraSignal(OnMaterialReset, const NzMaterial* /*material*/); + // Signals: + NazaraSignal(OnMaterialRelease, const Material* /*material*/); + NazaraSignal(OnMaterialReset, const Material* /*material*/); - private: - struct ShaderInstance - { - const NzShader* shader; - NzUberShaderInstance* uberInstance = nullptr; - int uniforms[nzMaterialUniform_Max+1]; - }; + private: + struct ShaderInstance + { + const Shader* shader; + UberShaderInstance* uberInstance = nullptr; + int uniforms[MaterialUniform_Max+1]; + }; - void Copy(const NzMaterial& material); - void GenerateShader(nzUInt32 flags) const; - void InvalidateShaders(); + void Copy(const Material& material); + void GenerateShader(UInt32 flags) const; + void InvalidateShaders(); - static bool Initialize(); - static void Uninitialize(); + static bool Initialize(); + static void Uninitialize(); - NzColor m_ambientColor; - NzColor m_diffuseColor; - NzColor m_specularColor; - NzRenderStates m_states; - NzTextureSampler m_diffuseSampler; - NzTextureSampler m_specularSampler; - NzTextureRef m_alphaMap; - NzTextureRef m_diffuseMap; - NzTextureRef m_emissiveMap; - NzTextureRef m_heightMap; - NzTextureRef m_normalMap; - NzTextureRef m_specularMap; - 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; - float m_shininess; + Color m_ambientColor; + Color m_diffuseColor; + Color m_specularColor; + RenderStates m_states; + TextureSampler m_diffuseSampler; + TextureSampler m_specularSampler; + TextureRef m_alphaMap; + TextureRef m_diffuseMap; + TextureRef m_emissiveMap; + TextureRef m_heightMap; + TextureRef m_normalMap; + TextureRef m_specularMap; + UberShaderConstRef m_uberShader; + mutable ShaderInstance m_shaders[ShaderFlags_Max+1]; + bool m_alphaTestEnabled; + bool m_depthSortingEnabled; + bool m_lightingEnabled; + bool m_transformEnabled; + float m_alphaThreshold; + float m_shininess; - static NzMaterialLibrary::LibraryMap s_library; - static NzMaterialLoader::LoaderList s_loaders; - static NzMaterialManager::ManagerMap s_managerMap; - static NzMaterialManager::ManagerParams s_managerParameters; - static NzMaterialRef s_defaultMaterial; -}; + static MaterialLibrary::LibraryMap s_library; + static MaterialLoader::LoaderList s_loaders; + static MaterialManager::ManagerMap s_managerMap; + static MaterialManager::ManagerParams s_managerParameters; + static MaterialRef s_defaultMaterial; + }; +} #include diff --git a/include/Nazara/Graphics/Material.inl b/include/Nazara/Graphics/Material.inl index 08c3d9b2d..177c8130b 100644 --- a/include/Nazara/Graphics/Material.inl +++ b/include/Nazara/Graphics/Material.inl @@ -5,13 +5,16 @@ #include #include -template -NzMaterialRef NzMaterial::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzMaterial(std::forward(args)...)); - object->SetPersistent(false); + template + MaterialRef Material::New(Args&&... args) + { + std::unique_ptr object(new Material(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index 80fc8c3db..2655fdedd 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -14,78 +14,81 @@ #include #include -struct NAZARA_GRAPHICS_API NzModelParameters +namespace Nz { - NzModelParameters(); + struct NAZARA_GRAPHICS_API ModelParameters + { + ModelParameters(); - bool loadMaterials = true; - NzMaterialParams material; - NzMeshParams mesh; + bool loadMaterials = true; + MaterialParams material; + MeshParams mesh; - bool IsValid() const; -}; + bool IsValid() const; + }; -class NzModel; + class Model; -using NzModelConstRef = NzObjectRef; -using NzModelLoader = NzResourceLoader; -using NzModelRef = NzObjectRef; + using ModelConstRef = ObjectRef; + using ModelLoader = ResourceLoader; + using ModelRef = ObjectRef; -class NAZARA_GRAPHICS_API NzModel : public NzInstancedRenderable, public NzResource -{ - friend NzModelLoader; + class NAZARA_GRAPHICS_API Model : public InstancedRenderable, public Resource + { + friend ModelLoader; - public: - NzModel(); - NzModel(const NzModel& model) = default; - NzModel(NzModel&& model) = default; - virtual ~NzModel(); + public: + Model(); + Model(const Model& model) = default; + Model(Model&& model) = default; + virtual ~Model(); - void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; + void AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; - NzMaterial* GetMaterial(const NzString& subMeshName) const; - NzMaterial* GetMaterial(unsigned int matIndex) const; - NzMaterial* GetMaterial(unsigned int skinIndex, const NzString& subMeshName) const; - NzMaterial* GetMaterial(unsigned int skinIndex, unsigned int matIndex) const; - unsigned int GetMaterialCount() const; - unsigned int GetSkin() const; - unsigned int GetSkinCount() const; - NzMesh* GetMesh() const; + Material* GetMaterial(const String& subMeshName) const; + Material* GetMaterial(unsigned int matIndex) const; + Material* GetMaterial(unsigned int skinIndex, const String& subMeshName) const; + Material* GetMaterial(unsigned int skinIndex, unsigned int matIndex) const; + unsigned int GetMaterialCount() const; + unsigned int GetSkin() const; + unsigned int GetSkinCount() const; + Mesh* GetMesh() const; - virtual bool IsAnimated() const; + virtual bool IsAnimated() const; - bool LoadFromFile(const NzString& filePath, const NzModelParameters& params = NzModelParameters()); - bool LoadFromMemory(const void* data, std::size_t size, const NzModelParameters& params = NzModelParameters()); - bool LoadFromStream(NzInputStream& stream, const NzModelParameters& params = NzModelParameters()); + bool LoadFromFile(const String& filePath, const ModelParameters& params = ModelParameters()); + bool LoadFromMemory(const void* data, std::size_t size, const ModelParameters& params = ModelParameters()); + bool LoadFromStream(InputStream& stream, const ModelParameters& params = ModelParameters()); - void Reset(); + void Reset(); - bool SetMaterial(const NzString& subMeshName, NzMaterial* material); - void SetMaterial(unsigned int matIndex, NzMaterial* material); - bool SetMaterial(unsigned int skinIndex, const NzString& subMeshName, NzMaterial* material); - void SetMaterial(unsigned int skinIndex, unsigned int matIndex, NzMaterial* material); - virtual void SetMesh(NzMesh* mesh); - bool SetSequence(const NzString& sequenceName); - void SetSequence(unsigned int sequenceIndex); - void SetSkin(unsigned int skin); - void SetSkinCount(unsigned int skinCount); + bool SetMaterial(const String& subMeshName, Material* material); + void SetMaterial(unsigned int matIndex, Material* material); + bool SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material); + void SetMaterial(unsigned int skinIndex, unsigned int matIndex, Material* material); + virtual void SetMesh(Mesh* mesh); + bool SetSequence(const String& sequenceName); + void SetSequence(unsigned int sequenceIndex); + void SetSkin(unsigned int skin); + void SetSkinCount(unsigned int skinCount); - NzModel& operator=(const NzModel& node) = default; - NzModel& operator=(NzModel&& node) = default; + Model& operator=(const Model& node) = default; + Model& operator=(Model&& node) = default; - template static NzModelRef New(Args&&... args); + template static ModelRef New(Args&&... args); - protected: - void MakeBoundingVolume() const override; + protected: + void MakeBoundingVolume() const override; - std::vector m_materials; - NzMeshRef m_mesh; - unsigned int m_matCount; - unsigned int m_skin; - unsigned int m_skinCount; + std::vector m_materials; + MeshRef m_mesh; + unsigned int m_matCount; + unsigned int m_skin; + unsigned int m_skinCount; - static NzModelLoader::LoaderList s_loaders; -}; + static ModelLoader::LoaderList s_loaders; + }; +} #include diff --git a/include/Nazara/Graphics/Model.inl b/include/Nazara/Graphics/Model.inl index b45c6296f..ea30ebd72 100644 --- a/include/Nazara/Graphics/Model.inl +++ b/include/Nazara/Graphics/Model.inl @@ -5,13 +5,16 @@ #include #include -template -NzModelRef NzModel::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzModel(std::forward(args)...)); - object->SetPersistent(false); + template + ModelRef Model::New(Args&&... args) + { + std::unique_ptr object(new Model(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Graphics/ParticleController.hpp b/include/Nazara/Graphics/ParticleController.hpp index eb35416fa..17e4ac9e1 100644 --- a/include/Nazara/Graphics/ParticleController.hpp +++ b/include/Nazara/Graphics/ParticleController.hpp @@ -14,34 +14,37 @@ #include #include -class NzParticleController; -class NzParticleMapper; -class NzParticleSystem; - -using NzParticleControllerConstRef = NzObjectRef; -using NzParticleControllerLibrary = NzObjectLibrary; -using NzParticleControllerRef = NzObjectRef; - -class NAZARA_GRAPHICS_API NzParticleController : public NzRefCounted +namespace Nz { - friend NzParticleControllerLibrary; - friend class NzGraphics; + class ParticleController; + class ParticleMapper; + class ParticleSystem; - public: - NzParticleController() = default; - NzParticleController(const NzParticleController& controller); - virtual ~NzParticleController(); + using ParticleControllerConstRef = ObjectRef; + using ParticleControllerLibrary = ObjectLibrary; + using ParticleControllerRef = ObjectRef; - virtual void Apply(NzParticleSystem& system, NzParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) = 0; + class NAZARA_GRAPHICS_API ParticleController : public RefCounted + { + friend ParticleControllerLibrary; + friend class Graphics; - // Signals: - NazaraSignal(OnParticleControllerRelease, const NzParticleController* /*particleController*/); + public: + ParticleController() = default; + ParticleController(const ParticleController& controller); + virtual ~ParticleController(); - private: - static bool Initialize(); - static void Uninitialize(); + virtual void Apply(ParticleSystem& system, ParticleMapper& mapper, unsigned int startId, unsigned int endId, float elapsedTime) = 0; - static NzParticleControllerLibrary::LibraryMap s_library; -}; + // Signals: + NazaraSignal(OnParticleControllerRelease, const ParticleController* /*particleController*/); + + private: + static bool Initialize(); + static void Uninitialize(); + + static ParticleControllerLibrary::LibraryMap s_library; + }; +} #endif // NAZARA_PARTICLECONTROLLER_HPP diff --git a/include/Nazara/Graphics/ParticleDeclaration.hpp b/include/Nazara/Graphics/ParticleDeclaration.hpp index 4b63dc568..4fd8b6c33 100644 --- a/include/Nazara/Graphics/ParticleDeclaration.hpp +++ b/include/Nazara/Graphics/ParticleDeclaration.hpp @@ -16,61 +16,64 @@ #include #include -class NzParticleDeclaration; - -using NzParticleDeclarationConstRef = NzObjectRef; -using NzParticleDeclarationLibrary = NzObjectLibrary; -using NzParticleDeclarationRef = NzObjectRef; - -class NAZARA_GRAPHICS_API NzParticleDeclaration : public NzRefCounted +namespace Nz { - friend NzParticleDeclarationLibrary; - friend class NzGraphics; + class ParticleDeclaration; - public: - NzParticleDeclaration(); - NzParticleDeclaration(const NzParticleDeclaration& declaration); - ~NzParticleDeclaration(); + using ParticleDeclarationConstRef = ObjectRef; + using ParticleDeclarationLibrary = ObjectLibrary; + using ParticleDeclarationRef = ObjectRef; - void DisableComponent(nzParticleComponent component); - void EnableComponent(nzParticleComponent component, nzComponentType type, unsigned int offset); + class NAZARA_GRAPHICS_API ParticleDeclaration : public RefCounted + { + friend ParticleDeclarationLibrary; + friend class Graphics; - void GetComponent(nzParticleComponent component, bool* enabled, nzComponentType* type, unsigned int* offset) const; - unsigned int GetStride() const; + public: + ParticleDeclaration(); + ParticleDeclaration(const ParticleDeclaration& declaration); + ~ParticleDeclaration(); - void SetStride(unsigned int stride); + void DisableComponent(ParticleComponent component); + void EnableComponent(ParticleComponent component, ComponentType type, unsigned int offset); - NzParticleDeclaration& operator=(const NzParticleDeclaration& declaration); + void GetComponent(ParticleComponent component, bool* enabled, ComponentType* type, unsigned int* offset) const; + unsigned int GetStride() const; - static NzParticleDeclaration* Get(nzParticleLayout layout); - static bool IsTypeSupported(nzComponentType type); + void SetStride(unsigned int stride); - // Signals: - NazaraSignal(OnParticleDeclarationRelease, const NzParticleDeclaration* /*particleDeclaration*/); + ParticleDeclaration& operator=(const ParticleDeclaration& declaration); - private: - static bool Initialize(); - static void Uninitialize(); + static ParticleDeclaration* Get(ParticleLayout layout); + static bool IsTypeSupported(ComponentType type); - struct Component - { - nzComponentType type; - bool enabled = false; - unsigned int offset; + // Signals: + NazaraSignal(OnParticleDeclarationRelease, const ParticleDeclaration* /*particleDeclaration*/); - /* - ** -Lynix: - ** Il serait aussi possible de préciser le stride de façon indépendante, ce que je ne permets pas - ** pour décomplexifier l'interface en enlevant quelque chose que je juge inutile. - ** Si vous pensez que ça peut être utile, n'hésitez pas à me le faire savoir ! - */ - }; + private: + static bool Initialize(); + static void Uninitialize(); - Component m_components[nzParticleComponent_Max+1]; - unsigned int m_stride; + struct Component + { + ComponentType type; + bool enabled = false; + unsigned int offset; - static NzParticleDeclaration s_declarations[nzParticleLayout_Max+1]; - static NzParticleDeclarationLibrary::LibraryMap s_library; -}; + /* + ** -Lynix: + ** Il serait aussi possible de préciser le stride de façon indépendante, ce que je ne permets pas + ** pour décomplexifier l'interface en enlevant quelque chose que je juge inutile. + ** Si vous pensez que ça peut être utile, n'hésitez pas à me le faire savoir ! + */ + }; + + Component m_components[ParticleComponent_Max+1]; + unsigned int m_stride; + + static ParticleDeclaration s_declarations[ParticleLayout_Max+1]; + static ParticleDeclarationLibrary::LibraryMap s_library; + }; +} #endif // NAZARA_PARTICLEDECLARATION_HPP diff --git a/include/Nazara/Graphics/ParticleEmitter.hpp b/include/Nazara/Graphics/ParticleEmitter.hpp index 47c688ebc..d5e3c8ea8 100644 --- a/include/Nazara/Graphics/ParticleEmitter.hpp +++ b/include/Nazara/Graphics/ParticleEmitter.hpp @@ -11,39 +11,42 @@ #include #include -class NzParticleMapper; -class NzParticleSystem; - -class NAZARA_GRAPHICS_API NzParticleEmitter : public NzNode +namespace Nz { - public: - NzParticleEmitter(); - NzParticleEmitter(const NzParticleEmitter& emitter) = default; - NzParticleEmitter(NzParticleEmitter&& emitter) = default; - virtual ~NzParticleEmitter(); + class ParticleMapper; + class ParticleSystem; - virtual void Emit(NzParticleSystem& system, float elapsedTime) const; + class NAZARA_GRAPHICS_API ParticleEmitter : public Node + { + public: + ParticleEmitter(); + ParticleEmitter(const ParticleEmitter& emitter) = default; + ParticleEmitter(ParticleEmitter&& emitter) = default; + virtual ~ParticleEmitter(); - void EnableLagCompensation(bool enable); + virtual void Emit(ParticleSystem& system, float elapsedTime) const; - unsigned int GetEmissionCount() const; - float GetEmissionRate() const; + void EnableLagCompensation(bool enable); - bool IsLagCompensationEnabled() const; + unsigned int GetEmissionCount() const; + float GetEmissionRate() const; - void SetEmissionCount(unsigned int count); - void SetEmissionRate(float rate); + bool IsLagCompensationEnabled() const; - NzParticleEmitter& operator=(const NzParticleEmitter& emitter) = default; - NzParticleEmitter& operator=(NzParticleEmitter&& emitter) = default; + void SetEmissionCount(unsigned int count); + void SetEmissionRate(float rate); - private: - virtual void SetupParticles(NzParticleMapper& mapper, unsigned int count) const = 0; + ParticleEmitter& operator=(const ParticleEmitter& emitter) = default; + ParticleEmitter& operator=(ParticleEmitter&& emitter) = default; - bool m_lagCompensationEnabled; - mutable float m_emissionAccumulator; - float m_emissionRate; - unsigned int m_emissionCount; -}; + private: + virtual void SetupParticles(ParticleMapper& mapper, unsigned int count) const = 0; + + bool m_lagCompensationEnabled; + mutable float m_emissionAccumulator; + float m_emissionRate; + unsigned int m_emissionCount; + }; +} #endif // NAZARA_PARTICLEEMITTER_HPP diff --git a/include/Nazara/Graphics/ParticleGenerator.hpp b/include/Nazara/Graphics/ParticleGenerator.hpp index 30f379a66..d9d2a789a 100644 --- a/include/Nazara/Graphics/ParticleGenerator.hpp +++ b/include/Nazara/Graphics/ParticleGenerator.hpp @@ -14,34 +14,37 @@ #include #include -class NzParticleGenerator; -class NzParticleMapper; -class NzParticleSystem; - -using NzParticleGeneratorConstRef = NzObjectRef; -using NzParticleGeneratorLibrary = NzObjectLibrary; -using NzParticleGeneratorRef = NzObjectRef; - -class NAZARA_GRAPHICS_API NzParticleGenerator : public NzRefCounted +namespace Nz { - friend NzParticleGeneratorLibrary; - friend class NzGraphics; + class ParticleGenerator; + class ParticleMapper; + class ParticleSystem; - public: - NzParticleGenerator() = default; - NzParticleGenerator(const NzParticleGenerator& generator); - virtual ~NzParticleGenerator(); + using ParticleGeneratorConstRef = ObjectRef; + using ParticleGeneratorLibrary = ObjectLibrary; + using ParticleGeneratorRef = ObjectRef; - virtual void Generate(NzParticleSystem& system, NzParticleMapper& mapper, unsigned int startId, unsigned int endId) = 0; + class NAZARA_GRAPHICS_API ParticleGenerator : public RefCounted + { + friend ParticleGeneratorLibrary; + friend class Graphics; - // Signals: - NazaraSignal(OnParticleGeneratorRelease, const NzParticleGenerator* /*particleGenerator*/); + public: + ParticleGenerator() = default; + ParticleGenerator(const ParticleGenerator& generator); + virtual ~ParticleGenerator(); - private: - static bool Initialize(); - static void Uninitialize(); + virtual void Generate(ParticleSystem& system, ParticleMapper& mapper, unsigned int startId, unsigned int endId) = 0; - static NzParticleGeneratorLibrary::LibraryMap s_library; -}; + // Signals: + NazaraSignal(OnParticleGeneratorRelease, const ParticleGenerator* /*particleGenerator*/); + + private: + static bool Initialize(); + static void Uninitialize(); + + static ParticleGeneratorLibrary::LibraryMap s_library; + }; +} #endif // NAZARA_PARTICLEGENERATOR_HPP diff --git a/include/Nazara/Graphics/ParticleMapper.hpp b/include/Nazara/Graphics/ParticleMapper.hpp index 7ac3e6e38..e66b519a7 100644 --- a/include/Nazara/Graphics/ParticleMapper.hpp +++ b/include/Nazara/Graphics/ParticleMapper.hpp @@ -12,19 +12,22 @@ #include #include -class NAZARA_GRAPHICS_API NzParticleMapper +namespace Nz { - public: - NzParticleMapper(void* buffer, const NzParticleDeclaration* declaration); - ~NzParticleMapper(); + class NAZARA_GRAPHICS_API ParticleMapper + { + public: + ParticleMapper(void* buffer, const ParticleDeclaration* declaration); + ~ParticleMapper(); - template NzSparsePtr GetComponentPtr(nzParticleComponent component); - template NzSparsePtr GetComponentPtr(nzParticleComponent component) const; + template SparsePtr GetComponentPtr(ParticleComponent component); + template SparsePtr GetComponentPtr(ParticleComponent component) const; - private: - const NzParticleDeclaration* m_declaration; - nzUInt8* m_ptr; -}; + private: + const ParticleDeclaration* m_declaration; + UInt8* m_ptr; + }; +} #include diff --git a/include/Nazara/Graphics/ParticleMapper.inl b/include/Nazara/Graphics/ParticleMapper.inl index 07f974ad8..a28315312 100644 --- a/include/Nazara/Graphics/ParticleMapper.inl +++ b/include/Nazara/Graphics/ParticleMapper.inl @@ -5,45 +5,48 @@ #include #include -template -NzSparsePtr NzParticleMapper::GetComponentPtr(nzParticleComponent component) +namespace Nz { - // Ensuite le composant qui nous intéresse - bool enabled; - nzComponentType type; - unsigned int offset; - m_declaration->GetComponent(component, &enabled, &type, &offset); + template + SparsePtr ParticleMapper::GetComponentPtr(ParticleComponent component) + { + // Ensuite le composant qui nous intéresse + bool enabled; + ComponentType type; + unsigned int offset; + m_declaration->GetComponent(component, &enabled, &type, &offset); - if (enabled) - { - ///TODO: Vérifier le rapport entre le type de l'attribut et le type template ? - return NzSparsePtr(m_ptr + offset, m_declaration->GetStride()); + if (enabled) + { + ///TODO: Vérifier le rapport entre le type de l'attribut et le type template ? + return SparsePtr(m_ptr + offset, m_declaration->GetStride()); + } + else + { + NazaraError("Attribute 0x" + String::Number(component, 16) + " is not enabled"); + return SparsePtr(); + } } - else - { - NazaraError("Attribute 0x" + NzString::Number(component, 16) + " is not enabled"); - return NzSparsePtr(); - } -} -template -NzSparsePtr NzParticleMapper::GetComponentPtr(nzParticleComponent component) const -{ - // Ensuite le composant qui nous intéresse - bool enabled; - nzComponentType type; - unsigned int offset; - m_declaration->GetComponent(component, &enabled, &type, &offset); + template + SparsePtr ParticleMapper::GetComponentPtr(ParticleComponent component) const + { + // Ensuite le composant qui nous intéresse + bool enabled; + ComponentType type; + unsigned int offset; + m_declaration->GetComponent(component, &enabled, &type, &offset); - if (enabled) - { - ///TODO: Vérifier le rapport entre le type de l'attribut et le type template ? - return NzSparsePtr(m_ptr + offset, m_declaration->GetStride()); - } - else - { - NazaraError("Attribute 0x" + NzString::Number(component, 16) + " is not enabled"); - return NzSparsePtr(); + if (enabled) + { + ///TODO: Vérifier le rapport entre le type de l'attribut et le type template ? + return SparsePtr(m_ptr + offset, m_declaration->GetStride()); + } + else + { + NazaraError("Attribute 0x" + String::Number(component, 16) + " is not enabled"); + return SparsePtr(); + } } } diff --git a/include/Nazara/Graphics/ParticleRenderer.hpp b/include/Nazara/Graphics/ParticleRenderer.hpp index e3e2082e7..d79d448f2 100644 --- a/include/Nazara/Graphics/ParticleRenderer.hpp +++ b/include/Nazara/Graphics/ParticleRenderer.hpp @@ -14,35 +14,38 @@ #include #include -class NzAbstractRenderQueue; -class NzParticleMapper; -class NzParticleRenderer; -class NzParticleSystem; - -using NzParticleRendererConstRef = NzObjectRef; -using NzParticleRendererLibrary = NzObjectLibrary; -using NzParticleRendererRef = NzObjectRef; - -class NAZARA_GRAPHICS_API NzParticleRenderer : public NzRefCounted +namespace Nz { - friend NzParticleRendererLibrary; - friend class NzGraphics; + class AbstractRenderQueue; + class ParticleMapper; + class ParticleRenderer; + class ParticleSystem; - public: - NzParticleRenderer() = default; - NzParticleRenderer(const NzParticleRenderer& renderer); - virtual ~NzParticleRenderer(); + using ParticleRendererConstRef = ObjectRef; + using ParticleRendererLibrary = ObjectLibrary; + using ParticleRendererRef = ObjectRef; - virtual void Render(const NzParticleSystem& system, const NzParticleMapper& mapper, unsigned int startId, unsigned int endId, NzAbstractRenderQueue* renderQueue) = 0; + class NAZARA_GRAPHICS_API ParticleRenderer : public RefCounted + { + friend ParticleRendererLibrary; + friend class Graphics; - // Signals: - NazaraSignal(OnParticleRendererRelease, const NzParticleRenderer* /*particleRenderer*/); + public: + ParticleRenderer() = default; + ParticleRenderer(const ParticleRenderer& renderer); + virtual ~ParticleRenderer(); - private: - static bool Initialize(); - static void Uninitialize(); + virtual void Render(const ParticleSystem& system, const ParticleMapper& mapper, unsigned int startId, unsigned int endId, AbstractRenderQueue* renderQueue) = 0; - static NzParticleRendererLibrary::LibraryMap s_library; -}; + // Signals: + NazaraSignal(OnParticleRendererRelease, const ParticleRenderer* /*particleRenderer*/); + + private: + static bool Initialize(); + static void Uninitialize(); + + static ParticleRendererLibrary::LibraryMap s_library; + }; +} #endif // NAZARA_PARTICLERENDERER_HPP diff --git a/include/Nazara/Graphics/ParticleStruct.hpp b/include/Nazara/Graphics/ParticleStruct.hpp index 7c478b812..b68836935 100644 --- a/include/Nazara/Graphics/ParticleStruct.hpp +++ b/include/Nazara/Graphics/ParticleStruct.hpp @@ -12,31 +12,34 @@ #include #include -struct NzParticleStruct_Billboard +namespace Nz { - NzColor color; - NzVector3f normal; - NzVector3f position; - NzVector3f velocity; - nzUInt32 life; - float rotation; -}; + struct ParticleStruct_Billboard + { + Color color; + Vector3f normal; + Vector3f position; + Vector3f velocity; + UInt32 life; + float rotation; + }; -struct NzParticleStruct_Model -{ - NzVector3f position; - NzVector3f velocity; - nzUInt32 life; - NzQuaternionf rotation; -}; + struct ParticleStruct_Model + { + Vector3f position; + Vector3f velocity; + UInt32 life; + Quaternionf rotation; + }; -struct NzParticleStruct_Sprite -{ - NzColor color; - NzVector2f position; - NzVector2f velocity; - nzUInt32 life; - float rotation; -}; + struct ParticleStruct_Sprite + { + Color color; + Vector2f position; + Vector2f velocity; + UInt32 life; + float rotation; + }; +} #endif // NAZARA_PARTICLESTRUCT_HPP diff --git a/include/Nazara/Graphics/ParticleSystem.hpp b/include/Nazara/Graphics/ParticleSystem.hpp index 73a53addf..34dcbb137 100644 --- a/include/Nazara/Graphics/ParticleSystem.hpp +++ b/include/Nazara/Graphics/ParticleSystem.hpp @@ -20,70 +20,73 @@ #include #include -class NAZARA_GRAPHICS_API NzParticleSystem : public NzRenderable +namespace Nz { - public: - NzParticleSystem(unsigned int maxParticleCount, nzParticleLayout layout); - NzParticleSystem(unsigned int maxParticleCount, NzParticleDeclarationConstRef declaration); - NzParticleSystem(const NzParticleSystem& emitter); - ~NzParticleSystem(); + class NAZARA_GRAPHICS_API ParticleSystem : public Renderable + { + public: + ParticleSystem(unsigned int maxParticleCount, ParticleLayout layout); + ParticleSystem(unsigned int maxParticleCount, ParticleDeclarationConstRef declaration); + ParticleSystem(const ParticleSystem& emitter); + ~ParticleSystem(); - void AddController(NzParticleControllerRef controller); - void AddEmitter(NzParticleEmitter* emitter); - void AddGenerator(NzParticleGeneratorRef generator); - void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const; + void AddController(ParticleControllerRef controller); + void AddEmitter(ParticleEmitter* emitter); + void AddGenerator(ParticleGeneratorRef generator); + void AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const; - void ApplyControllers(NzParticleMapper& mapper, unsigned int particleCount, float elapsedTime); + void ApplyControllers(ParticleMapper& mapper, unsigned int particleCount, float elapsedTime); - void* CreateParticle(); - void* CreateParticles(unsigned int count); + void* CreateParticle(); + void* CreateParticles(unsigned int count); - void EnableFixedStep(bool fixedStep); + void EnableFixedStep(bool fixedStep); - void* GenerateParticle(); - void* GenerateParticles(unsigned int count); + void* GenerateParticle(); + void* GenerateParticles(unsigned int count); - const NzParticleDeclarationConstRef& GetDeclaration() const; - float GetFixedStepSize() const; - unsigned int GetMaxParticleCount() const; - unsigned int GetParticleCount() const; - unsigned int GetParticleSize() const; + const ParticleDeclarationConstRef& GetDeclaration() const; + float GetFixedStepSize() const; + unsigned int GetMaxParticleCount() const; + unsigned int GetParticleCount() const; + unsigned int GetParticleSize() const; - bool IsFixedStepEnabled() const; + bool IsFixedStepEnabled() const; - void KillParticle(unsigned int index); - void KillParticles(); + void KillParticle(unsigned int index); + void KillParticles(); - void RemoveController(NzParticleController* controller); - void RemoveEmitter(NzParticleEmitter* emitter); - void RemoveGenerator(NzParticleGenerator* generator); + void RemoveController(ParticleController* controller); + void RemoveEmitter(ParticleEmitter* emitter); + void RemoveGenerator(ParticleGenerator* generator); - void SetFixedStepSize(float stepSize); - void SetRenderer(NzParticleRenderer* renderer); + void SetFixedStepSize(float stepSize); + void SetRenderer(ParticleRenderer* renderer); - void Update(float elapsedTime); - void UpdateBoundingVolume(const NzMatrix4f& transformMatrix) override; + void Update(float elapsedTime); + void UpdateBoundingVolume(const Matrix4f& transformMatrix) override; - NzParticleSystem& operator=(const NzParticleSystem& emitter); + ParticleSystem& operator=(const ParticleSystem& emitter); - private: - void MakeBoundingVolume() const override; - void ResizeBuffer(); + private: + void MakeBoundingVolume() const override; + void ResizeBuffer(); - std::set> m_dyingParticles; - mutable std::vector m_buffer; - std::vector m_controllers; - std::vector m_emitters; - std::vector m_generators; - NzParticleDeclarationConstRef m_declaration; - NzParticleRendererRef m_renderer; - bool m_fixedStepEnabled; - bool m_processing; - float m_stepAccumulator; - float m_stepSize; - unsigned int m_maxParticleCount; - unsigned int m_particleCount; - unsigned int m_particleSize; -}; + std::set> m_dyingParticles; + mutable std::vector m_buffer; + std::vector m_controllers; + std::vector m_emitters; + std::vector m_generators; + ParticleDeclarationConstRef m_declaration; + ParticleRendererRef m_renderer; + bool m_fixedStepEnabled; + bool m_processing; + float m_stepAccumulator; + float m_stepSize; + unsigned int m_maxParticleCount; + unsigned int m_particleCount; + unsigned int m_particleSize; + }; +} #endif // NAZARA_PARTICLESYSTEM_HPP diff --git a/include/Nazara/Graphics/RenderTechniques.hpp b/include/Nazara/Graphics/RenderTechniques.hpp index 983b69590..1e006858a 100644 --- a/include/Nazara/Graphics/RenderTechniques.hpp +++ b/include/Nazara/Graphics/RenderTechniques.hpp @@ -12,28 +12,31 @@ #include #include -class NzAbstractRenderTechnique; - -class NAZARA_GRAPHICS_API NzRenderTechniques +namespace Nz { - public: - using RenderTechniqueFactory = NzAbstractRenderTechnique* (*)(); + class AbstractRenderTechnique; - NzRenderTechniques() = delete; - ~NzRenderTechniques() = delete; + class NAZARA_GRAPHICS_API RenderTechniques + { + public: + using RenderTechniqueFactory = AbstractRenderTechnique* (*)(); - static NzAbstractRenderTechnique* GetByEnum(nzRenderTechniqueType renderTechnique, int* techniqueRanking = nullptr); - static NzAbstractRenderTechnique* GetByIndex(unsigned int index, int* techniqueRanking = nullptr); - static NzAbstractRenderTechnique* GetByName(const NzString& name, int* techniqueRanking = nullptr); - static NzAbstractRenderTechnique* GetByRanking(int maxRanking, int* techniqueRanking = nullptr); + RenderTechniques() = delete; + ~RenderTechniques() = delete; - static unsigned int GetCount(); + static AbstractRenderTechnique* GetByEnum(RenderTechniqueType renderTechnique, int* techniqueRanking = nullptr); + static AbstractRenderTechnique* GetByIndex(unsigned int index, int* techniqueRanking = nullptr); + static AbstractRenderTechnique* GetByName(const String& name, int* techniqueRanking = nullptr); + static AbstractRenderTechnique* GetByRanking(int maxRanking, int* techniqueRanking = nullptr); - static void Register(const NzString& name, int ranking, RenderTechniqueFactory factory); + static unsigned int GetCount(); - static NzString ToString(nzRenderTechniqueType renderTechnique); + static void Register(const String& name, int ranking, RenderTechniqueFactory factory); - static void Unregister(const NzString& name); -}; + static String ToString(RenderTechniqueType renderTechnique); + + static void Unregister(const String& name); + }; +} #endif // NAZARA_RENDERTECHNIQUES_HPP diff --git a/include/Nazara/Graphics/Renderable.hpp b/include/Nazara/Graphics/Renderable.hpp index 1a357a18a..f8d441955 100644 --- a/include/Nazara/Graphics/Renderable.hpp +++ b/include/Nazara/Graphics/Renderable.hpp @@ -12,35 +12,38 @@ #include #include -class NzAbstractRenderQueue; - -class NAZARA_GRAPHICS_API NzRenderable +namespace Nz { - public: - NzRenderable() = default; - NzRenderable(const NzRenderable& renderable) = default; - NzRenderable(NzRenderable&&) = default; - virtual ~NzRenderable(); + class AbstractRenderQueue; - virtual void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const = 0; - virtual bool Cull(const NzFrustumf& frustum, const NzMatrix4f& transformMatrix) const; - inline void EnsureBoundingVolumeUpdated() const; - virtual const NzBoundingVolumef& GetBoundingVolume() const; - virtual void UpdateBoundingVolume(const NzMatrix4f& transformMatrix); + class NAZARA_GRAPHICS_API Renderable + { + public: + Renderable() = default; + Renderable(const Renderable& renderable) = default; + Renderable(Renderable&&) = default; + virtual ~Renderable(); - NzRenderable& operator=(const NzRenderable& renderable) = default; - NzRenderable& operator=(NzRenderable&& renderable) = default; + virtual void AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const = 0; + virtual bool Cull(const Frustumf& frustum, const Matrix4f& transformMatrix) const; + inline void EnsureBoundingVolumeUpdated() const; + virtual const BoundingVolumef& GetBoundingVolume() const; + virtual void UpdateBoundingVolume(const Matrix4f& transformMatrix); - protected: - virtual void MakeBoundingVolume() const = 0; - inline void InvalidateBoundingVolume(); - inline void UpdateBoundingVolume() const; + Renderable& operator=(const Renderable& renderable) = default; + Renderable& operator=(Renderable&& renderable) = default; - mutable NzBoundingVolumef m_boundingVolume; + protected: + virtual void MakeBoundingVolume() const = 0; + inline void InvalidateBoundingVolume(); + inline void UpdateBoundingVolume() const; - private: - mutable bool m_boundingVolumeUpdated; -}; + mutable BoundingVolumef m_boundingVolume; + + private: + mutable bool m_boundingVolumeUpdated; + }; +} #include diff --git a/include/Nazara/Graphics/Renderable.inl b/include/Nazara/Graphics/Renderable.inl index 2fd3748a9..ed445ec96 100644 --- a/include/Nazara/Graphics/Renderable.inl +++ b/include/Nazara/Graphics/Renderable.inl @@ -2,19 +2,22 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -inline void NzRenderable::EnsureBoundingVolumeUpdated() const +namespace Nz { - if (!m_boundingVolumeUpdated) - UpdateBoundingVolume(); -} + inline void Renderable::EnsureBoundingVolumeUpdated() const + { + if (!m_boundingVolumeUpdated) + UpdateBoundingVolume(); + } -inline void NzRenderable::InvalidateBoundingVolume() -{ - m_boundingVolumeUpdated = false; -} + inline void Renderable::InvalidateBoundingVolume() + { + m_boundingVolumeUpdated = false; + } -inline void NzRenderable::UpdateBoundingVolume() const -{ - MakeBoundingVolume(); - m_boundingVolumeUpdated = true; + inline void Renderable::UpdateBoundingVolume() const + { + MakeBoundingVolume(); + m_boundingVolumeUpdated = true; + } } diff --git a/include/Nazara/Graphics/SceneData.hpp b/include/Nazara/Graphics/SceneData.hpp index a1dbe8103..94aafbda4 100644 --- a/include/Nazara/Graphics/SceneData.hpp +++ b/include/Nazara/Graphics/SceneData.hpp @@ -9,14 +9,17 @@ #include -class NzAbstractBackground; -class NzAbstractViewer; - -struct NzSceneData +namespace Nz { - NzColor ambientColor; - const NzAbstractBackground* background; - const NzAbstractViewer* viewer; -}; + class AbstractBackground; + class AbstractViewer; + + struct SceneData + { + Color ambientColor; + const AbstractBackground* background; + const AbstractViewer* viewer; + }; +} #endif // NAZARA_SCENEDATA_HPP diff --git a/include/Nazara/Graphics/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp index a8b5da497..976411133 100644 --- a/include/Nazara/Graphics/SkeletalModel.hpp +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -16,74 +16,77 @@ #include #include -struct NAZARA_GRAPHICS_API NzSkeletalModelParameters : public NzModelParameters +namespace Nz { - bool loadAnimation = true; - NzAnimationParams animation; + struct NAZARA_GRAPHICS_API SkeletalModelParameters : public ModelParameters + { + bool loadAnimation = true; + AnimationParams animation; - bool IsValid() const; -}; + bool IsValid() const; + }; -class NzSkeletalModel; + class SkeletalModel; -using NzSkeletalModelLoader = NzResourceLoader; + using SkeletalModelLoader = ResourceLoader; -class NAZARA_GRAPHICS_API NzSkeletalModel : public NzModel, NzUpdatable -{ - friend NzSkeletalModelLoader; + class NAZARA_GRAPHICS_API SkeletalModel : public Model, Updatable + { + friend SkeletalModelLoader; - public: - NzSkeletalModel(); - NzSkeletalModel(const NzSkeletalModel& model) = default; - NzSkeletalModel(NzSkeletalModel&& model) = default; - ~NzSkeletalModel() = default; + public: + SkeletalModel(); + SkeletalModel(const SkeletalModel& model) = default; + SkeletalModel(SkeletalModel&& model) = default; + ~SkeletalModel() = default; - void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; - void AdvanceAnimation(float elapsedTime); + void AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; + void AdvanceAnimation(float elapsedTime); - NzSkeletalModel* Clone() const; - NzSkeletalModel* Create() const; + SkeletalModel* Clone() const; + SkeletalModel* Create() const; - void EnableAnimation(bool animation); + void EnableAnimation(bool animation); - NzAnimation* GetAnimation() const; - NzSkeleton* GetSkeleton(); - const NzSkeleton* GetSkeleton() const; + Animation* GetAnimation() const; + Skeleton* GetSkeleton(); + const Skeleton* GetSkeleton() const; - bool HasAnimation() const; + bool HasAnimation() const; - bool IsAnimated() const; - bool IsAnimationEnabled() const; + bool IsAnimated() const; + bool IsAnimationEnabled() const; - bool LoadFromFile(const NzString& filePath, const NzSkeletalModelParameters& params = NzSkeletalModelParameters()); - bool LoadFromMemory(const void* data, std::size_t size, const NzSkeletalModelParameters& params = NzSkeletalModelParameters()); - bool LoadFromStream(NzInputStream& stream, const NzSkeletalModelParameters& params = NzSkeletalModelParameters()); + bool LoadFromFile(const String& filePath, const SkeletalModelParameters& params = SkeletalModelParameters()); + bool LoadFromMemory(const void* data, std::size_t size, const SkeletalModelParameters& params = SkeletalModelParameters()); + bool LoadFromStream(InputStream& stream, const SkeletalModelParameters& params = SkeletalModelParameters()); - void Reset(); + void Reset(); - bool SetAnimation(NzAnimation* animation); - void SetMesh(NzMesh* mesh) override; - bool SetSequence(const NzString& sequenceName); - void SetSequence(unsigned int sequenceIndex); + bool SetAnimation(Animation* animation); + void SetMesh(Mesh* mesh) override; + bool SetSequence(const String& sequenceName); + void SetSequence(unsigned int sequenceIndex); - NzSkeletalModel& operator=(const NzSkeletalModel& node) = default; - NzSkeletalModel& operator=(NzSkeletalModel&& node) = default; + SkeletalModel& operator=(const SkeletalModel& node) = default; + SkeletalModel& operator=(SkeletalModel&& node) = default; - private: - void MakeBoundingVolume() const override; - /*void Register() override; - void Unregister() override;*/ - void Update() override; + private: + void MakeBoundingVolume() const override; + /*void Register() override; + void Unregister() override;*/ + void Update() override; - NzAnimationRef m_animation; - NzSkeleton m_skeleton; - const NzSequence* m_currentSequence; - bool m_animationEnabled; - float m_interpolation; - unsigned int m_currentFrame; - unsigned int m_nextFrame; + AnimationRef m_animation; + Skeleton m_skeleton; + const Sequence* m_currentSequence; + bool m_animationEnabled; + float m_interpolation; + unsigned int m_currentFrame; + unsigned int m_nextFrame; - static NzSkeletalModelLoader::LoaderList s_loaders; -}; + static SkeletalModelLoader::LoaderList s_loaders; + }; +} #endif // NAZARA_SKELETALMODEL_HPP diff --git a/include/Nazara/Graphics/SkinningManager.hpp b/include/Nazara/Graphics/SkinningManager.hpp index c32c011ea..a8f76768e 100644 --- a/include/Nazara/Graphics/SkinningManager.hpp +++ b/include/Nazara/Graphics/SkinningManager.hpp @@ -10,31 +10,34 @@ #include #include -class NzSkeleton; -class NzSkeletalMesh; -class NzVertexBuffer; - -class NAZARA_GRAPHICS_API NzSkinningManager +namespace Nz { - friend class NzGraphics; + class Skeleton; + class SkeletalMesh; + class VertexBuffer; - public: - using SkinFunction = void (*)(const NzSkeletalMesh* mesh, const NzSkeleton* skeleton, NzVertexBuffer* buffer); + class NAZARA_GRAPHICS_API SkinningManager + { + friend class Graphics; - NzSkinningManager() = delete; - ~NzSkinningManager() = delete; + public: + using SkinFunction = void (*)(const SkeletalMesh* mesh, const Skeleton* skeleton, VertexBuffer* buffer); - static NzVertexBuffer* GetBuffer(const NzSkeletalMesh* mesh, const NzSkeleton* skeleton); - static void Skin(); + SkinningManager() = delete; + ~SkinningManager() = delete; - private: - static bool Initialize(); - static void OnSkeletalMeshDestroy(const NzSkeletalMesh* mesh); - static void OnSkeletonInvalidated(const NzSkeleton* skeleton); - static void OnSkeletonRelease(const NzSkeleton* skeleton); - static void Uninitialize(); + static VertexBuffer* GetBuffer(const SkeletalMesh* mesh, const Skeleton* skeleton); + static void Skin(); - static SkinFunction s_skinFunc; -}; + private: + static bool Initialize(); + static void OnSkeletalMeshDestroy(const SkeletalMesh* mesh); + static void OnSkeletonInvalidated(const Skeleton* skeleton); + static void OnSkeletonRelease(const Skeleton* skeleton); + static void Uninitialize(); + + static SkinFunction s_skinFunc; + }; +} #endif // NAZARA_SKINNINGMANAGER_HPP diff --git a/include/Nazara/Graphics/SkyboxBackground.hpp b/include/Nazara/Graphics/SkyboxBackground.hpp index 08a9984ee..b861dbbb8 100644 --- a/include/Nazara/Graphics/SkyboxBackground.hpp +++ b/include/Nazara/Graphics/SkyboxBackground.hpp @@ -15,38 +15,41 @@ #include #include -class NzSkyboxBackground; - -using NzSkyboxBackgroundConstRef = NzObjectRef; -using NzSkyboxBackgroundRef = NzObjectRef; - -class NAZARA_GRAPHICS_API NzSkyboxBackground : public NzAbstractBackground +namespace Nz { - friend class NzGraphics; + class SkyboxBackground; - public: - NzSkyboxBackground(NzTextureRef cubemapTexture = NzTextureRef()); - ~NzSkyboxBackground() = default; + using SkyboxBackgroundConstRef = ObjectRef; + using SkyboxBackgroundRef = ObjectRef; - void Draw(const NzAbstractViewer* viewer) const; + class NAZARA_GRAPHICS_API SkyboxBackground : public AbstractBackground + { + friend class Graphics; - nzBackgroundType GetBackgroundType() const; - inline const NzTextureRef& GetTexture() const; - inline NzTextureSampler& GetTextureSampler(); - inline const NzTextureSampler& GetTextureSampler() const; + public: + SkyboxBackground(TextureRef cubemapTexture = TextureRef()); + ~SkyboxBackground() = default; - inline void SetTexture(NzTextureRef cubemapTexture); - inline void SetTextureSampler(const NzTextureSampler& sampler); + void Draw(const AbstractViewer* viewer) const; - template static NzSkyboxBackgroundRef New(Args&&... args); + BackgroundType GetBackgroundType() const; + inline const TextureRef& GetTexture() const; + inline TextureSampler& GetTextureSampler(); + inline const TextureSampler& GetTextureSampler() const; - private: - static bool Initialize(); - static void Uninitialize(); + inline void SetTexture(TextureRef cubemapTexture); + inline void SetTextureSampler(const TextureSampler& sampler); - NzTextureRef m_texture; - NzTextureSampler m_sampler; -}; + template static SkyboxBackgroundRef New(Args&&... args); + + private: + static bool Initialize(); + static void Uninitialize(); + + TextureRef m_texture; + TextureSampler m_sampler; + }; +} #include diff --git a/include/Nazara/Graphics/SkyboxBackground.inl b/include/Nazara/Graphics/SkyboxBackground.inl index f8105bd30..51b3bf123 100644 --- a/include/Nazara/Graphics/SkyboxBackground.inl +++ b/include/Nazara/Graphics/SkyboxBackground.inl @@ -5,41 +5,44 @@ #include #include -inline const NzTextureRef& NzSkyboxBackground::GetTexture() const +namespace Nz { - return m_texture; -} + inline const TextureRef& SkyboxBackground::GetTexture() const + { + return m_texture; + } -inline NzTextureSampler& NzSkyboxBackground::GetTextureSampler() -{ - return m_sampler; -} + inline TextureSampler& SkyboxBackground::GetTextureSampler() + { + return m_sampler; + } -inline const NzTextureSampler& NzSkyboxBackground::GetTextureSampler() const -{ - return m_sampler; -} + inline const TextureSampler& SkyboxBackground::GetTextureSampler() const + { + return m_sampler; + } -inline void NzSkyboxBackground::SetTexture(NzTextureRef cubemapTexture) -{ - NazaraAssert(!cubemapTexture || cubemapTexture->IsValid(), "Invalid texture"); - NazaraAssert(!cubemapTexture || cubemapTexture->IsCubemap(), "Texture must be a cubemap"); + inline void SkyboxBackground::SetTexture(TextureRef cubemapTexture) + { + NazaraAssert(!cubemapTexture || cubemapTexture->IsValid(), "Invalid texture"); + NazaraAssert(!cubemapTexture || cubemapTexture->IsCubemap(), "Texture must be a cubemap"); - m_texture = std::move(cubemapTexture); -} + m_texture = std::move(cubemapTexture); + } -void NzSkyboxBackground::SetTextureSampler(const NzTextureSampler& sampler) -{ - m_sampler = sampler; -} + void SkyboxBackground::SetTextureSampler(const TextureSampler& sampler) + { + m_sampler = sampler; + } -template -NzSkyboxBackgroundRef NzSkyboxBackground::New(Args&&... args) -{ - std::unique_ptr object(new NzSkyboxBackground(std::forward(args)...)); - object->SetPersistent(false); + template + SkyboxBackgroundRef SkyboxBackground::New(Args&&... args) + { + std::unique_ptr object(new SkyboxBackground(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Graphics/Sprite.hpp b/include/Nazara/Graphics/Sprite.hpp index 756cb4ba8..e61f19840 100644 --- a/include/Nazara/Graphics/Sprite.hpp +++ b/include/Nazara/Graphics/Sprite.hpp @@ -13,53 +13,58 @@ #include #include -class NzSprite; - -using NzSpriteConstRef = NzObjectRef; -using NzSpriteLibrary = NzObjectLibrary; -using NzSpriteRef = NzObjectRef; - -class NAZARA_GRAPHICS_API NzSprite : public NzInstancedRenderable +namespace Nz { - public: - inline NzSprite(); - inline NzSprite(NzMaterialRef material); - inline NzSprite(NzTexture* texture); - inline NzSprite(const NzSprite& sprite); - ~NzSprite() = default; + class Sprite; - void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; + using SpriteConstRef = ObjectRef; + using SpriteLibrary = ObjectLibrary; + using SpriteRef = ObjectRef; - inline const NzColor& GetColor() const; - inline const NzMaterialRef& GetMaterial() const; - inline const NzVector2f& GetSize() const; - inline const NzRectf& GetTextureCoords() const; + class NAZARA_GRAPHICS_API Sprite : public InstancedRenderable + { + public: + inline Sprite(); + inline Sprite(MaterialRef material); + inline Sprite(Texture* texture); + inline Sprite(const Sprite& sprite); + Sprite(Sprite&&) = delete; + ~Sprite() = default; - inline void SetColor(const NzColor& color); - inline void SetDefaultMaterial(); - inline void SetMaterial(NzMaterialRef material, bool resizeSprite = true); - inline void SetSize(const NzVector2f& size); - inline void SetSize(float sizeX, float sizeY); - inline void SetTexture(NzTextureRef texture, bool resizeSprite = true); - inline void SetTextureCoords(const NzRectf& coords); - inline void SetTextureRect(const NzRectui& rect); + void AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; - inline NzSprite& operator=(const NzSprite& sprite); + inline const Color& GetColor() const; + inline const MaterialRef& GetMaterial() const; + inline const Vector2f& GetSize() const; + inline const Rectf& GetTextureCoords() const; - template static NzSpriteRef New(Args&&... args); + inline void SetColor(const Color& color); + inline void SetDefaultMaterial(); + inline void SetMaterial(MaterialRef material, bool resizeSprite = true); + inline void SetSize(const Vector2f& size); + inline void SetSize(float sizeX, float sizeY); + inline void SetTexture(TextureRef texture, bool resizeSprite = true); + inline void SetTextureCoords(const Rectf& coords); + inline void SetTextureRect(const Rectui& rect); - private: - inline void InvalidateVertices(); - void MakeBoundingVolume() const override; - void UpdateData(InstanceData* instanceData) const override; + inline Sprite& operator=(const Sprite& sprite); + Sprite& operator=(Sprite&& sprite) = delete; - NzColor m_color; - NzMaterialRef m_material; - NzRectf m_textureCoords; - NzVector2f m_size; + template static SpriteRef New(Args&&... args); - static NzSpriteLibrary::LibraryMap s_library; -}; + private: + inline void InvalidateVertices(); + void MakeBoundingVolume() const override; + void UpdateData(InstanceData* instanceData) const override; + + Color m_color; + MaterialRef m_material; + Rectf m_textureCoords; + Vector2f m_size; + + static SpriteLibrary::LibraryMap s_library; + }; +} #include diff --git a/include/Nazara/Graphics/Sprite.inl b/include/Nazara/Graphics/Sprite.inl index 1051fee6f..8969cddf0 100644 --- a/include/Nazara/Graphics/Sprite.inl +++ b/include/Nazara/Graphics/Sprite.inl @@ -6,160 +6,163 @@ #include #include -inline NzSprite::NzSprite() : -m_color(NzColor::White), -m_textureCoords(0.f, 0.f, 1.f, 1.f), -m_size(64.f, 64.f) +namespace Nz { - SetDefaultMaterial(); -} - -inline NzSprite::NzSprite(NzMaterialRef material) : -m_color(NzColor::White), -m_textureCoords(0.f, 0.f, 1.f, 1.f), -m_size(64.f, 64.f) -{ - SetMaterial(std::move(material), true); -} - -inline NzSprite::NzSprite(NzTexture* texture) : -m_color(NzColor::White), -m_textureCoords(0.f, 0.f, 1.f, 1.f), -m_size(64.f, 64.f) -{ - SetTexture(texture, true); -} - -inline NzSprite::NzSprite(const NzSprite& sprite) : -NzInstancedRenderable(sprite), -m_color(sprite.m_color), -m_material(sprite.m_material), -m_textureCoords(sprite.m_textureCoords), -m_size(sprite.m_size) -{ -} - -inline const NzColor& NzSprite::GetColor() const -{ - return m_color; -} - -inline const NzMaterialRef& NzSprite::GetMaterial() const -{ - return m_material; -} - -inline const NzVector2f& NzSprite::GetSize() const -{ - return m_size; -} - -inline const NzRectf& NzSprite::GetTextureCoords() const -{ - return m_textureCoords; -} - -inline void NzSprite::SetColor(const NzColor& color) -{ - m_color = color; - - InvalidateVertices(); -} - -inline void NzSprite::SetDefaultMaterial() -{ - NzMaterialRef material = NzMaterial::New(); - material->Enable(nzRendererParameter_FaceCulling, false); - material->EnableLighting(false); - - SetMaterial(std::move(material)); -} - -inline void NzSprite::SetMaterial(NzMaterialRef material, bool resizeSprite) -{ - m_material = std::move(material); - if (m_material && resizeSprite) + inline Sprite::Sprite() : + m_color(Color::White), + m_textureCoords(0.f, 0.f, 1.f, 1.f), + m_size(64.f, 64.f) { - NzTexture* diffuseMap = m_material->GetDiffuseMap(); - if (diffuseMap && diffuseMap->IsValid()) - SetSize(NzVector2f(NzVector2ui(diffuseMap->GetSize()))); + SetDefaultMaterial(); + } + + inline Sprite::Sprite(MaterialRef material) : + m_color(Color::White), + m_textureCoords(0.f, 0.f, 1.f, 1.f), + m_size(64.f, 64.f) + { + SetMaterial(std::move(material), true); + } + + inline Sprite::Sprite(Texture* texture) : + m_color(Color::White), + m_textureCoords(0.f, 0.f, 1.f, 1.f), + m_size(64.f, 64.f) + { + SetTexture(texture, true); + } + + inline Sprite::Sprite(const Sprite& sprite) : + InstancedRenderable(sprite), + m_color(sprite.m_color), + m_material(sprite.m_material), + m_textureCoords(sprite.m_textureCoords), + m_size(sprite.m_size) + { + } + + inline const Color& Sprite::GetColor() const + { + return m_color; + } + + inline const MaterialRef& Sprite::GetMaterial() const + { + return m_material; + } + + inline const Vector2f& Sprite::GetSize() const + { + return m_size; + } + + inline const Rectf& Sprite::GetTextureCoords() const + { + return m_textureCoords; + } + + inline void Sprite::SetColor(const Color& color) + { + m_color = color; + + InvalidateVertices(); + } + + inline void Sprite::SetDefaultMaterial() + { + MaterialRef material = Material::New(); + material->Enable(RendererParameter_FaceCulling, false); + material->EnableLighting(false); + + SetMaterial(std::move(material)); + } + + inline void Sprite::SetMaterial(MaterialRef material, bool resizeSprite) + { + m_material = std::move(material); + if (m_material && resizeSprite) + { + Texture* diffuseMap = m_material->GetDiffuseMap(); + if (diffuseMap && diffuseMap->IsValid()) + SetSize(Vector2f(Vector2ui(diffuseMap->GetSize()))); + } + } + + inline void Sprite::SetSize(const Vector2f& size) + { + m_size = size; + + // On invalide la bounding box + InvalidateBoundingVolume(); + InvalidateVertices(); + } + + inline void Sprite::SetSize(float sizeX, float sizeY) + { + SetSize(Vector2f(sizeX, sizeY)); + } + + inline void Sprite::SetTexture(TextureRef texture, bool resizeSprite) + { + if (!m_material) + SetDefaultMaterial(); + else if (m_material->GetReferenceCount() > 1) + m_material = Material::New(*m_material); // Copie + + if (resizeSprite && texture && texture->IsValid()) + SetSize(Vector2f(Vector2ui(texture->GetSize()))); + + m_material->SetDiffuseMap(std::move(texture)); + } + + inline void Sprite::SetTextureCoords(const Rectf& coords) + { + m_textureCoords = coords; + InvalidateVertices(); + } + + inline void Sprite::SetTextureRect(const Rectui& rect) + { + NazaraAssert(m_material, "Sprite has no material"); + NazaraAssert(m_material->HasDiffuseMap(), "Sprite material has no diffuse map"); + + Texture* diffuseMap = m_material->GetDiffuseMap(); + + float invWidth = 1.f/diffuseMap->GetWidth(); + float invHeight = 1.f/diffuseMap->GetHeight(); + + SetTextureCoords(Rectf(invWidth*rect.x, invHeight*rect.y, invWidth*rect.width, invHeight*rect.height)); + } + + inline Sprite& Sprite::operator=(const Sprite& sprite) + { + InstancedRenderable::operator=(sprite); + + m_color = sprite.m_color; + m_material = sprite.m_material; + m_textureCoords = sprite.m_textureCoords; + m_size = sprite.m_size; + + // On ne copie pas les sommets finaux car il est très probable que nos paramètres soient modifiés et qu'ils doivent être régénérés de toute façon + InvalidateBoundingVolume(); + InvalidateVertices(); + + return *this; + } + + inline void Sprite::InvalidateVertices() + { + InvalidateInstanceData(0); + } + + template + SpriteRef Sprite::New(Args&&... args) + { + std::unique_ptr object(new Sprite(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); } } -inline void NzSprite::SetSize(const NzVector2f& size) -{ - m_size = size; - - // On invalide la bounding box - InvalidateBoundingVolume(); - InvalidateVertices(); -} - -inline void NzSprite::SetSize(float sizeX, float sizeY) -{ - SetSize(NzVector2f(sizeX, sizeY)); -} - -inline void NzSprite::SetTexture(NzTextureRef texture, bool resizeSprite) -{ - if (!m_material) - SetDefaultMaterial(); - else if (m_material->GetReferenceCount() > 1) - m_material = NzMaterial::New(*m_material); // Copie - - if (resizeSprite && texture && texture->IsValid()) - SetSize(NzVector2f(NzVector2ui(texture->GetSize()))); - - m_material->SetDiffuseMap(std::move(texture)); -} - -inline void NzSprite::SetTextureCoords(const NzRectf& coords) -{ - m_textureCoords = coords; - InvalidateVertices(); -} - -inline void NzSprite::SetTextureRect(const NzRectui& rect) -{ - NazaraAssert(m_material, "Sprite has no material"); - NazaraAssert(m_material->HasDiffuseMap(), "Sprite material has no diffuse map"); - - NzTexture* diffuseMap = m_material->GetDiffuseMap(); - - float invWidth = 1.f/diffuseMap->GetWidth(); - float invHeight = 1.f/diffuseMap->GetHeight(); - - SetTextureCoords(NzRectf(invWidth*rect.x, invHeight*rect.y, invWidth*rect.width, invHeight*rect.height)); -} - -inline NzSprite& NzSprite::operator=(const NzSprite& sprite) -{ - NzInstancedRenderable::operator=(sprite); - - m_color = sprite.m_color; - m_material = sprite.m_material; - m_textureCoords = sprite.m_textureCoords; - m_size = sprite.m_size; - - // On ne copie pas les sommets finaux car il est très probable que nos paramètres soient modifiés et qu'ils doivent être régénérés de toute façon - InvalidateBoundingVolume(); - InvalidateVertices(); - - return *this; -} - -inline void NzSprite::InvalidateVertices() -{ - InvalidateInstanceData(0); -} - -template -NzSpriteRef NzSprite::New(Args&&... args) -{ - std::unique_ptr object(new NzSprite(std::forward(args)...)); - object->SetPersistent(false); - - return object.release(); -} - #include diff --git a/include/Nazara/Graphics/TextSprite.hpp b/include/Nazara/Graphics/TextSprite.hpp index 3eebe9d10..2a664a5c3 100644 --- a/include/Nazara/Graphics/TextSprite.hpp +++ b/include/Nazara/Graphics/TextSprite.hpp @@ -16,69 +16,72 @@ #include #include -class NzTextSprite; - -using NzTextSpriteConstRef = NzObjectRef; -using NzTextSpriteLibrary = NzObjectLibrary; -using NzTextSpriteRef = NzObjectRef; - -class NAZARA_GRAPHICS_API NzTextSprite : public NzInstancedRenderable +namespace Nz { - public: - inline NzTextSprite(); - inline NzTextSprite(const NzTextSprite& sprite); - ~NzTextSprite() = default; + class TextSprite; - void AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; + using TextSpriteConstRef = ObjectRef; + using TextSpriteLibrary = ObjectLibrary; + using TextSpriteRef = ObjectRef; - inline void Clear(); + class NAZARA_GRAPHICS_API TextSprite : public InstancedRenderable + { + public: + inline TextSprite(); + inline TextSprite(const TextSprite& sprite); + ~TextSprite() = default; - inline const NzColor& GetColor() const; - inline const NzMaterialRef& GetMaterial() const; - inline float GetScale() const; + void AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const override; - inline void SetColor(const NzColor& color); - inline void SetDefaultMaterial(); - inline void SetMaterial(NzMaterialRef material); - inline void SetScale(float scale); + inline void Clear(); - void Update(const NzAbstractTextDrawer& drawer); + inline const Color& GetColor() const; + inline const MaterialRef& GetMaterial() const; + inline float GetScale() const; - inline NzTextSprite& operator=(const NzTextSprite& text); + inline void SetColor(const Color& color); + inline void SetDefaultMaterial(); + inline void SetMaterial(MaterialRef material); + inline void SetScale(float scale); - template static NzTextSpriteRef New(Args&&... args); + void Update(const AbstractTextDrawer& drawer); - private: - inline void InvalidateVertices(); - void MakeBoundingVolume() const override; - void OnAtlasInvalidated(const NzAbstractAtlas* atlas); - void OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer); - void UpdateData(InstanceData* instanceData) const override; + inline TextSprite& operator=(const TextSprite& text); - struct RenderIndices - { - unsigned int first; - unsigned int count; - }; + template static TextSpriteRef New(Args&&... args); - struct AtlasSlots - { - NazaraSlot(NzAbstractAtlas, OnAtlasCleared, clearSlot); - NazaraSlot(NzAbstractAtlas, OnAtlasLayerChange, layerChangeSlot); - NazaraSlot(NzAbstractAtlas, OnAtlasRelease, releaseSlot); - }; + private: + inline void InvalidateVertices(); + void MakeBoundingVolume() const override; + void OnAtlasInvalidated(const AbstractAtlas* atlas); + void OnAtlasLayerChange(const AbstractAtlas* atlas, AbstractImage* oldLayer, AbstractImage* newLayer); + void UpdateData(InstanceData* instanceData) const override; - std::unordered_map m_atlases; - mutable std::unordered_map m_renderInfos; - mutable std::vector m_localVertices; - NzColor m_color; - NzMaterialRef m_material; - NzRectui m_localBounds; - mutable bool m_verticesUpdated; - float m_scale; + struct RenderIndices + { + unsigned int first; + unsigned int count; + }; - static NzTextSpriteLibrary::LibraryMap s_library; -}; + struct AtlasSlots + { + NazaraSlot(AbstractAtlas, OnAtlasCleared, clearSlot); + NazaraSlot(AbstractAtlas, OnAtlasLayerChange, layerChangeSlot); + NazaraSlot(AbstractAtlas, OnAtlasRelease, releaseSlot); + }; + + std::unordered_map m_atlases; + mutable std::unordered_map m_renderInfos; + mutable std::vector m_localVertices; + Color m_color; + MaterialRef m_material; + Rectui m_localBounds; + mutable bool m_verticesUpdated; + float m_scale; + + static TextSpriteLibrary::LibraryMap s_library; + }; +} #include diff --git a/include/Nazara/Graphics/TextSprite.inl b/include/Nazara/Graphics/TextSprite.inl index a940ff212..a22641100 100644 --- a/include/Nazara/Graphics/TextSprite.inl +++ b/include/Nazara/Graphics/TextSprite.inl @@ -5,130 +5,133 @@ #include #include -inline NzTextSprite::NzTextSprite() : -m_color(NzColor::White), -m_scale(1.f) +namespace Nz { - SetDefaultMaterial(); -} - -inline NzTextSprite::NzTextSprite(const NzTextSprite& sprite) : -NzInstancedRenderable(sprite), -m_renderInfos(sprite.m_renderInfos), -m_localVertices(sprite.m_localVertices), -m_color(sprite.m_color), -m_material(sprite.m_material), -m_localBounds(sprite.m_localBounds), -m_scale(sprite.m_scale) -{ - for (auto it = sprite.m_atlases.begin(); it != sprite.m_atlases.end(); ++it) + inline TextSprite::TextSprite() : + m_color(Color::White), + m_scale(1.f) { - const NzAbstractAtlas* atlas = it->first; - AtlasSlots& slots = m_atlases[atlas]; - - slots.clearSlot.Connect(atlas->OnAtlasCleared, this, &NzTextSprite::OnAtlasInvalidated); - slots.layerChangeSlot.Connect(atlas->OnAtlasLayerChange, this, &NzTextSprite::OnAtlasLayerChange); - slots.releaseSlot.Connect(atlas->OnAtlasRelease, this, &NzTextSprite::OnAtlasInvalidated); - } -} - -inline void NzTextSprite::Clear() -{ - m_atlases.clear(); - m_boundingVolume.MakeNull(); - m_localVertices.clear(); - m_renderInfos.clear(); -} - -inline const NzColor& NzTextSprite::GetColor() const -{ - return m_color; -} - -inline const NzMaterialRef& NzTextSprite::GetMaterial() const -{ - return m_material; -} - -inline float NzTextSprite::GetScale() const -{ - return m_scale; -} - -inline void NzTextSprite::SetColor(const NzColor& color) -{ - m_color = color; - - InvalidateVertices(); -} - -inline void NzTextSprite::SetDefaultMaterial() -{ - NzMaterialRef material = NzMaterial::New(); - material->Enable(nzRendererParameter_Blend, true); - material->Enable(nzRendererParameter_DepthWrite, false); - material->Enable(nzRendererParameter_FaceCulling, false); - material->EnableLighting(false); - material->SetDstBlend(nzBlendFunc_InvSrcAlpha); - material->SetSrcBlend(nzBlendFunc_SrcAlpha); - - SetMaterial(material); -} - -inline void NzTextSprite::SetMaterial(NzMaterialRef material) -{ - m_material = std::move(material); -} - -inline void NzTextSprite::SetScale(float scale) -{ - m_scale = scale; - - InvalidateVertices(); -} - -inline void NzTextSprite::InvalidateVertices() -{ - InvalidateInstanceData(0); -} - -inline NzTextSprite& NzTextSprite::operator=(const NzTextSprite& text) -{ - NzInstancedRenderable::operator=(text); - - m_atlases.clear(); - - m_color = text.m_color; - m_material = text.m_material; - m_renderInfos = text.m_renderInfos; - m_localBounds = text.m_localBounds; - m_localVertices = text.m_localVertices; - m_scale = text.m_scale; - - // Connect to the slots of the new atlases - for (auto it = text.m_atlases.begin(); it != text.m_atlases.end(); ++it) - { - const NzAbstractAtlas* atlas = it->first; - AtlasSlots& slots = m_atlases[atlas]; - - slots.clearSlot.Connect(atlas->OnAtlasCleared, this, &NzTextSprite::OnAtlasInvalidated); - slots.layerChangeSlot.Connect(atlas->OnAtlasLayerChange, this, &NzTextSprite::OnAtlasLayerChange); - slots.releaseSlot.Connect(atlas->OnAtlasRelease, this, &NzTextSprite::OnAtlasInvalidated); + SetDefaultMaterial(); } - InvalidateBoundingVolume(); - InvalidateVertices(); + inline TextSprite::TextSprite(const TextSprite& sprite) : + InstancedRenderable(sprite), + m_renderInfos(sprite.m_renderInfos), + m_localVertices(sprite.m_localVertices), + m_color(sprite.m_color), + m_material(sprite.m_material), + m_localBounds(sprite.m_localBounds), + m_scale(sprite.m_scale) + { + for (auto it = sprite.m_atlases.begin(); it != sprite.m_atlases.end(); ++it) + { + const AbstractAtlas* atlas = it->first; + AtlasSlots& slots = m_atlases[atlas]; - return *this; -} + slots.clearSlot.Connect(atlas->OnAtlasCleared, this, &TextSprite::OnAtlasInvalidated); + slots.layerChangeSlot.Connect(atlas->OnAtlasLayerChange, this, &TextSprite::OnAtlasLayerChange); + slots.releaseSlot.Connect(atlas->OnAtlasRelease, this, &TextSprite::OnAtlasInvalidated); + } + } -template -NzTextSpriteRef NzTextSprite::New(Args&&... args) -{ - std::unique_ptr object(new NzTextSprite(std::forward(args)...)); - object->SetPersistent(false); + inline void TextSprite::Clear() + { + m_atlases.clear(); + m_boundingVolume.MakeNull(); + m_localVertices.clear(); + m_renderInfos.clear(); + } - return object.release(); + inline const Color& TextSprite::GetColor() const + { + return m_color; + } + + inline const MaterialRef& TextSprite::GetMaterial() const + { + return m_material; + } + + inline float TextSprite::GetScale() const + { + return m_scale; + } + + inline void TextSprite::SetColor(const Color& color) + { + m_color = color; + + InvalidateVertices(); + } + + inline void TextSprite::SetDefaultMaterial() + { + MaterialRef material = Material::New(); + material->Enable(RendererParameter_Blend, true); + material->Enable(RendererParameter_DepthWrite, false); + material->Enable(RendererParameter_FaceCulling, false); + material->EnableLighting(false); + material->SetDstBlend(BlendFunc_InvSrcAlpha); + material->SetSrcBlend(BlendFunc_SrcAlpha); + + SetMaterial(material); + } + + inline void TextSprite::SetMaterial(MaterialRef material) + { + m_material = std::move(material); + } + + inline void TextSprite::SetScale(float scale) + { + m_scale = scale; + + InvalidateVertices(); + } + + inline void TextSprite::InvalidateVertices() + { + InvalidateInstanceData(0); + } + + inline TextSprite& TextSprite::operator=(const TextSprite& text) + { + InstancedRenderable::operator=(text); + + m_atlases.clear(); + + m_color = text.m_color; + m_material = text.m_material; + m_renderInfos = text.m_renderInfos; + m_localBounds = text.m_localBounds; + m_localVertices = text.m_localVertices; + m_scale = text.m_scale; + + // Connect to the slots of the new atlases + for (auto it = text.m_atlases.begin(); it != text.m_atlases.end(); ++it) + { + const AbstractAtlas* atlas = it->first; + AtlasSlots& slots = m_atlases[atlas]; + + slots.clearSlot.Connect(atlas->OnAtlasCleared, this, &TextSprite::OnAtlasInvalidated); + slots.layerChangeSlot.Connect(atlas->OnAtlasLayerChange, this, &TextSprite::OnAtlasLayerChange); + slots.releaseSlot.Connect(atlas->OnAtlasRelease, this, &TextSprite::OnAtlasInvalidated); + } + + InvalidateBoundingVolume(); + InvalidateVertices(); + + return *this; + } + + template + TextSpriteRef TextSprite::New(Args&&... args) + { + std::unique_ptr object(new TextSprite(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); + } } #include diff --git a/include/Nazara/Graphics/TextureBackground.hpp b/include/Nazara/Graphics/TextureBackground.hpp index 0bd8804bb..741c974b7 100644 --- a/include/Nazara/Graphics/TextureBackground.hpp +++ b/include/Nazara/Graphics/TextureBackground.hpp @@ -12,33 +12,36 @@ #include #include -class NzTextureBackground; - -using NzTextureBackgroundConstRef = NzObjectRef; -using NzTextureBackgroundRef = NzObjectRef; - -class NAZARA_GRAPHICS_API NzTextureBackground : public NzAbstractBackground +namespace Nz { - public: - NzTextureBackground(NzTextureRef texture = NzTextureRef()); + class TextureBackground; - void Draw(const NzAbstractViewer* viewer) const; + using TextureBackgroundConstRef = ObjectRef; + using TextureBackgroundRef = ObjectRef; - nzBackgroundType GetBackgroundType() const; - inline const NzTextureRef& GetTexture() const; + class NAZARA_GRAPHICS_API TextureBackground : public AbstractBackground + { + public: + TextureBackground(TextureRef texture = TextureRef()); - inline void SetTexture(NzTextureRef texture); + void Draw(const AbstractViewer* viewer) const; - template static NzTextureBackgroundRef New(Args&&... args); + BackgroundType GetBackgroundType() const; + inline const TextureRef& GetTexture() const; - private: - NzTextureRef m_texture; - NzUberShaderConstRef m_uberShader; - const NzUberShaderInstance* m_uberShaderInstance; - int m_materialDiffuseUniform; - int m_materialDiffuseMapUniform; - int m_vertexDepthUniform; -}; + inline void SetTexture(TextureRef texture); + + template static TextureBackgroundRef New(Args&&... args); + + private: + TextureRef m_texture; + UberShaderConstRef m_uberShader; + const UberShaderInstance* m_uberShaderInstance; + int m_materialDiffuseUniform; + int m_materialDiffuseMapUniform; + int m_vertexDepthUniform; + }; +} #include diff --git a/include/Nazara/Graphics/TextureBackground.inl b/include/Nazara/Graphics/TextureBackground.inl index 7016b4c9a..c40ad3d2d 100644 --- a/include/Nazara/Graphics/TextureBackground.inl +++ b/include/Nazara/Graphics/TextureBackground.inl @@ -5,25 +5,28 @@ #include #include -inline const NzTextureRef& NzTextureBackground::GetTexture() const +namespace Nz { - return m_texture; -} + inline const TextureRef& TextureBackground::GetTexture() const + { + return m_texture; + } -inline void NzTextureBackground::SetTexture(NzTextureRef texture) -{ - NazaraAssert(!texture || texture->IsValid(), "Invalid texture"); + inline void TextureBackground::SetTexture(TextureRef texture) + { + NazaraAssert(!texture || texture->IsValid(), "Invalid texture"); - m_texture = std::move(texture); -} + m_texture = std::move(texture); + } -template -NzTextureBackgroundRef NzTextureBackground::New(Args&&... args) -{ - std::unique_ptr object(new NzTextureBackground(std::forward(args)...)); - object->SetPersistent(false); + template + TextureBackgroundRef TextureBackground::New(Args&&... args) + { + std::unique_ptr object(new TextureBackground(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Lua/Lua.hpp b/include/Nazara/Lua/Lua.hpp index 632cdc610..e41de7e1e 100644 --- a/include/Nazara/Lua/Lua.hpp +++ b/include/Nazara/Lua/Lua.hpp @@ -11,20 +11,23 @@ #include #include -class NAZARA_LUA_API NzLua +namespace Nz { - public: - NzLua() = delete; - ~NzLua() = delete; + class NAZARA_LUA_API Lua + { + public: + Lua() = delete; + ~Lua() = delete; - static bool Initialize(); + static bool Initialize(); - static bool IsInitialized(); + static bool IsInitialized(); - static void Uninitialize(); + static void Uninitialize(); - private: - static unsigned int s_moduleReferenceCounter; -}; + private: + static unsigned int s_moduleReferenceCounter; + }; +} #endif // NAZARA_LUA_HPP diff --git a/include/Nazara/Lua/LuaClass.hpp b/include/Nazara/Lua/LuaClass.hpp index 85cad0162..4f47f36f1 100644 --- a/include/Nazara/Lua/LuaClass.hpp +++ b/include/Nazara/Lua/LuaClass.hpp @@ -14,65 +14,68 @@ #include //#include -template -class NzLuaClass +namespace Nz { - //static_assert(std::is_same::value || std::is_base_of::value, "P must be a base of T"); + template + class LuaClass + { + //static_assert(std::is_same::value || std::is_base_of::value, "P must be a base of T"); - public: - using ClassFunc = int (*)(NzLuaInstance& lua, T& instance); - using ClassIndexFunc = bool (*)(NzLuaInstance& lua, T& instance); - using ConstructorFunc = T* (*)(NzLuaInstance& lua); - using FinalizerFunc = bool (*)(NzLuaInstance& lua, T& instance); - using StaticIndexFunc = bool (*)(NzLuaInstance& lua); - using StaticFunc = int (*)(NzLuaInstance& lua); + public: + using ClassFunc = int (*)(LuaInstance& lua, T& instance); + using ClassIndexFunc = bool (*)(LuaInstance& lua, T& instance); + using ConstructorFunc = T* (*)(LuaInstance& lua); + using FinalizerFunc = bool (*)(LuaInstance& lua, T& instance); + using StaticIndexFunc = bool (*)(LuaInstance& lua); + using StaticFunc = int (*)(LuaInstance& lua); - NzLuaClass(const NzString& name); + LuaClass(const String& name); - //void Inherit(NzLuaClass

& parent); + //void Inherit(LuaClass

& parent); - void Register(NzLuaInstance& lua); + void Register(LuaInstance& lua); - void PushGlobalTable(NzLuaInstance& lua); + void PushGlobalTable(LuaInstance& lua); - void SetConstructor(ConstructorFunc constructor); - void SetFinalizer(FinalizerFunc finalizer); - void SetGetter(ClassIndexFunc getter); - void SetMethod(const NzString& name, ClassFunc method); - void SetSetter(ClassIndexFunc setter); - void SetStaticGetter(StaticIndexFunc getter); - void SetStaticMethod(const NzString& name, StaticFunc func); - void SetStaticSetter(StaticIndexFunc getter); + void SetConstructor(ConstructorFunc constructor); + void SetFinalizer(FinalizerFunc finalizer); + void SetGetter(ClassIndexFunc getter); + void SetMethod(const String& name, ClassFunc method); + void SetSetter(ClassIndexFunc setter); + void SetStaticGetter(StaticIndexFunc getter); + void SetStaticMethod(const String& name, StaticFunc func); + void SetStaticSetter(StaticIndexFunc getter); - private: - static int ConstructorProxy(lua_State* state); - static int FinalizerProxy(lua_State* state); - static int InfoDestructor(lua_State* state); - static int GetterProxy(lua_State* state); - static int MethodProxy(lua_State* state); - static int SetterProxy(lua_State* state); - static int StaticGetterProxy(lua_State* state); - static int StaticMethodProxy(lua_State* state); - static int StaticSetterProxy(lua_State* state); + private: + static int ConstructorProxy(lua_State* state); + static int FinalizerProxy(lua_State* state); + static int InfoDestructor(lua_State* state); + static int GetterProxy(lua_State* state); + static int MethodProxy(lua_State* state); + static int SetterProxy(lua_State* state); + static int StaticGetterProxy(lua_State* state); + static int StaticMethodProxy(lua_State* state); + static int StaticSetterProxy(lua_State* state); - struct ClassInfo - { - std::vector methods; - std::vector staticMethods; - ClassIndexFunc getter = nullptr; - ClassIndexFunc setter = nullptr; - ConstructorFunc constructor = nullptr; - FinalizerFunc finalizer = nullptr; - StaticIndexFunc staticGetter = nullptr; - StaticIndexFunc staticSetter = nullptr; - NzString name; - int globalTableRef = -1; - }; + struct ClassInfo + { + std::vector methods; + std::vector staticMethods; + ClassIndexFunc getter = nullptr; + ClassIndexFunc setter = nullptr; + ConstructorFunc constructor = nullptr; + FinalizerFunc finalizer = nullptr; + StaticIndexFunc staticGetter = nullptr; + StaticIndexFunc staticSetter = nullptr; + String name; + int globalTableRef = -1; + }; - std::map m_methods; - std::map m_staticMethods; - std::shared_ptr m_info; -}; + std::map m_methods; + std::map m_staticMethods; + std::shared_ptr m_info; + }; +} #include diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index 04c645018..9fa445ffa 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -6,357 +6,360 @@ #include #include -template -NzLuaClass::NzLuaClass(const NzString& name) : -m_info(new ClassInfo) +namespace Nz { - m_info->name = name; -} -/* -template -void NzLuaClass::Inherit(NzLuaClass

& parent) -{ - static_assert(std::is_base_of::value, "P must be a base of T"); - - m_info->parentInfo = parent.m_info; -} -*/ -template -void NzLuaClass::Register(NzLuaInstance& lua) -{ - // Le ClassInfo doit rester en vie jusqu'à la fin du script - // Obliger l'instance de LuaClass à rester en vie dans cette fin serait contraignant pour l'utilisateur - // J'utilise donc une astuce, la stocker dans une UserData associée avec chaque fonction de la metatable du type, - // cette UserData disposera d'un finalizer qui libérera le ClassInfo - // Ainsi c'est Lua qui va s'occuper de la destruction pour nous :-) - // De même, l'utilisation d'un shared_ptr permet de garder la structure en vie même si l'instance est libérée avant le LuaClass - void* info = lua.PushUserdata(sizeof(std::shared_ptr)); - NzPlacementNew>(info, m_info); - - // On créé la table qui contiendra une méthode (Le finalizer) pour libérer le ClassInfo - lua.PushTable(0, 1); - lua.PushLightUserdata(info); - lua.PushCFunction(InfoDestructor, 1); - lua.SetField("__gc"); - lua.SetMetatable(-2); // La table devient la metatable de l'UserData - - // Maintenant, nous allons associer l'UserData avec chaque fonction, de sorte qu'il reste en vie - // aussi longtemps que nécessaire, et que le pointeur soit transmis à chaque méthode - - if (!lua.NewMetatable(m_info->name)) - NazaraWarning("Class \"" + m_info->name + "\" already registred in this instance"); + template + LuaClass::LuaClass(const String& name) : + m_info(new ClassInfo) { - lua.PushValue(1); // On associe l'UserData avec la fonction - lua.PushCFunction(FinalizerProxy, 1); - lua.SetField("__gc"); // Finalizer + m_info->name = name; + } + /* + template + void LuaClass::Inherit(LuaClass

& parent) + { + static_assert(std::is_base_of::value, "P must be a base of T"); - if (m_info->getter) + m_info->parentInfo = parent.m_info; + } + */ + template + void LuaClass::Register(LuaInstance& lua) + { + // Le ClassInfo doit rester en vie jusqu'à la fin du script + // Obliger l'instance de LuaClass à rester en vie dans cette fin serait contraignant pour l'utilisateur + // J'utilise donc une astuce, la stocker dans une UserData associée avec chaque fonction de la metatable du type, + // cette UserData disposera d'un finalizer qui libérera le ClassInfo + // Ainsi c'est Lua qui va s'occuper de la destruction pour nous :-) + // De même, l'utilisation d'un shared_ptr permet de garder la structure en vie même si l'instance est libérée avant le LuaClass + void* info = lua.PushUserdata(sizeof(std::shared_ptr)); + PlacementNew>(info, m_info); + + // On créé la table qui contiendra une méthode (Le finalizer) pour libérer le ClassInfo + lua.PushTable(0, 1); + lua.PushLightUserdata(info); + lua.PushCFunction(InfoDestructor, 1); + lua.SetField("__gc"); + lua.SetMetatable(-2); // La table devient la metatable de l'UserData + + // Maintenant, nous allons associer l'UserData avec chaque fonction, de sorte qu'il reste en vie + // aussi longtemps que nécessaire, et que le pointeur soit transmis à chaque méthode + + if (!lua.NewMetatable(m_info->name)) + NazaraWarning("Class \"" + m_info->name + "\" already registred in this instance"); { - lua.PushValue(1); + lua.PushValue(1); // On associe l'UserData avec la fonction + lua.PushCFunction(FinalizerProxy, 1); + lua.SetField("__gc"); // Finalizer + + if (m_info->getter) + { + lua.PushValue(1); + lua.PushValue(-2); + lua.PushCFunction(GetterProxy, 2); + } + else + // Optimisation, plutôt que de rediriger vers une fonction C qui ne fera rien d'autre que rechercher + // dans la table, nous envoyons directement la table, de sorte que Lua fasse directement la recherche + // Ceci n'est possible que si nous n'avons ni getter, ni parent + lua.PushValue(-1); + + lua.SetField("__index"); // Getter + + if (m_info->setter) + { + lua.PushValue(1); + lua.PushCFunction(SetterProxy, 1); + lua.SetField("__newindex"); // Setter + } + + m_info->methods.reserve(m_methods.size()); + for (auto& pair : m_methods) + { + m_info->methods.push_back(pair.second); + + lua.PushValue(1); + lua.PushInteger(m_info->methods.size() - 1); + + lua.PushCFunction(MethodProxy, 2); + lua.SetField(pair.first); // Méthode + } + } + lua.Pop(); // On pop la metatable + + if (m_info->constructor || m_info->staticGetter || m_info->staticSetter || !m_info->staticMethods.empty()) + { + // Création de l'instance globale + lua.PushTable(); // Class = {} + + // Création de la metatable associée à la table globale + lua.PushTable(); // ClassMeta = {} + + if (m_info->constructor) + { + lua.PushValue(1); // ClassInfo + lua.PushCFunction(ConstructorProxy, 1); + lua.SetField("__call"); // ClassMeta.__call = ConstructorProxy + } + + if (m_info->staticGetter) + { + lua.PushValue(1); + lua.PushValue(-2); + lua.PushCFunction(StaticGetterProxy, 2); + } + else + // Optimisation, plutôt que de rediriger vers une fonction C qui ne fera rien d'autre que rechercher + // dans la table, nous envoyons directement la table, de sorte que Lua fasse directement la recherche + // Ceci n'est possible que si nous n'avons ni getter, ni parent + lua.PushValue(-1); + + lua.SetField("__index"); // ClassMeta.__index = StaticGetterProxy/ClassMeta + + if (m_info->staticSetter) + { + lua.PushValue(1); + lua.PushCFunction(StaticSetterProxy, 1); + lua.SetField("__newindex"); // ClassMeta.__newindex = StaticSetterProxy + } + + m_info->staticMethods.reserve(m_staticMethods.size()); + for (auto& pair : m_staticMethods) + { + m_info->staticMethods.push_back(pair.second); + + lua.PushValue(1); + lua.PushInteger(m_info->staticMethods.size() - 1); + + lua.PushCFunction(StaticMethodProxy, 2); + lua.SetField(pair.first); // ClassMeta.method = StaticMethodProxy + } + + lua.SetMetatable(-2); // setmetatable(Class, ClassMeta) + + lua.PushValue(-1); // Copie + lua.SetGlobal(m_info->name); // Class + + m_info->globalTableRef = lua.CreateReference(); + } + lua.Pop(); // On pop l'Userdata (contenant nos informations) + } + + template + void LuaClass::PushGlobalTable(LuaInstance& lua) + { + lua.PushReference(m_info->globalTableRef); + } + + template + void LuaClass::SetConstructor(ConstructorFunc constructor) + { + m_info->constructor = constructor; + } + + template + void LuaClass::SetFinalizer(FinalizerFunc finalizer) + { + m_info->finalizer = finalizer; + } + + template + void LuaClass::SetGetter(ClassIndexFunc getter) + { + m_info->getter = getter; + } + + template + void LuaClass::SetMethod(const String& name, ClassFunc method) + { + m_methods[name] = method; + } + + template + void LuaClass::SetSetter(ClassIndexFunc setter) + { + m_info->setter = setter; + } + + template + void LuaClass::SetStaticGetter(StaticIndexFunc getter) + { + m_info->staticGetter = getter; + } + + template + void LuaClass::SetStaticMethod(const String& name, StaticFunc method) + { + m_staticMethods[name] = method; + } + + template + void LuaClass::SetStaticSetter(StaticIndexFunc setter) + { + m_info->staticSetter = setter; + } + + template + int LuaClass::ConstructorProxy(lua_State* state) + { + LuaInstance& lua = *LuaInstance::GetInstance(state); + + ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + ConstructorFunc constructor = info->constructor; + + lua.Remove(1); // On enlève l'argument "table" du stack + + T* instance = constructor(lua); + if (!instance) + { + lua.Error("Constructor failed"); + return 0; // Normalement jamais exécuté (l'erreur provoquant une exception) + } + + T** ud = static_cast(lua.PushUserdata(sizeof(T*))); + *ud = instance; + lua.SetMetatable(info->name); + + return 1; + } + + template + int LuaClass::FinalizerProxy(lua_State* state) + { + LuaInstance& lua = *LuaInstance::GetInstance(state); + + ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + FinalizerFunc finalizer = info->finalizer; + + T* instance = *static_cast(lua.CheckUserdata(1, info->name)); + + if (!finalizer || finalizer(lua, *instance)) + delete instance; + + return 0; + } + + template + int LuaClass::InfoDestructor(lua_State* state) + { + LuaInstance& lua = *LuaInstance::GetInstance(state); + + std::shared_ptr& infoPtr = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + lua.DestroyReference(infoPtr->globalTableRef); + + using namespace std; // Obligatoire pour le destructeur + infoPtr.~shared_ptr(); // Si vous voyez une autre façon de faire, je suis preneur + + return 0; + } + + template + int LuaClass::GetterProxy(lua_State* state) + { + LuaInstance& lua = *LuaInstance::GetInstance(state); + + ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + ClassIndexFunc getter = info->getter; + + T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); + + if (!getter(lua, instance)) + { + // On accède alors à la table + lua.PushValue(lua.GetIndexOfUpValue(2)); lua.PushValue(-2); - lua.PushCFunction(GetterProxy, 2); - } - else - // Optimisation, plutôt que de rediriger vers une fonction C qui ne fera rien d'autre que rechercher - // dans la table, nous envoyons directement la table, de sorte que Lua fasse directement la recherche - // Ceci n'est possible que si nous n'avons ni getter, ni parent - lua.PushValue(-1); - - lua.SetField("__index"); // Getter - - if (m_info->setter) - { - lua.PushValue(1); - lua.PushCFunction(SetterProxy, 1); - lua.SetField("__newindex"); // Setter + lua.GetTable(); } - m_info->methods.reserve(m_methods.size()); - for (auto& pair : m_methods) - { - m_info->methods.push_back(pair.second); - - lua.PushValue(1); - lua.PushInteger(m_info->methods.size() - 1); - - lua.PushCFunction(MethodProxy, 2); - lua.SetField(pair.first); // Méthode - } + return 1; } - lua.Pop(); // On pop la metatable - if (m_info->constructor || m_info->staticGetter || m_info->staticSetter || !m_info->staticMethods.empty()) + template + int LuaClass::MethodProxy(lua_State* state) { - // Création de l'instance globale - lua.PushTable(); // Class = {} + LuaInstance& lua = *LuaInstance::GetInstance(state); - // Création de la metatable associée à la table globale - lua.PushTable(); // ClassMeta = {} + ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + unsigned int index = static_cast(lua.ToInteger(lua.GetIndexOfUpValue(2))); + ClassFunc method = info->methods[index]; - if (m_info->constructor) + T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); + + lua.Remove(1); // On enlève l'argument "userdata" du stack + + return method(lua, instance); + } + + template + int LuaClass::SetterProxy(lua_State* state) + { + LuaInstance& lua = *LuaInstance::GetInstance(state); + + ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + ClassIndexFunc setter = info->setter; + + T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); + + if (!setter(lua, instance)) { - lua.PushValue(1); // ClassInfo - lua.PushCFunction(ConstructorProxy, 1); - lua.SetField("__call"); // ClassMeta.__call = ConstructorProxy + std::size_t length; + const char* str = lua.ToString(2, &length); + + lua.Error("Class \"" + info->name + "\" has no field \"" + String(str, length) + ')'); } - if (m_info->staticGetter) + return 1; + } + + template + int LuaClass::StaticGetterProxy(lua_State* state) + { + LuaInstance& lua = *LuaInstance::GetInstance(state); + + ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + StaticIndexFunc getter = info->staticGetter; + + if (!getter(lua)) { - lua.PushValue(1); + // On accède alors à la table + lua.PushValue(lua.GetIndexOfUpValue(2)); lua.PushValue(-2); - lua.PushCFunction(StaticGetterProxy, 2); + lua.GetTable(); } - else - // Optimisation, plutôt que de rediriger vers une fonction C qui ne fera rien d'autre que rechercher - // dans la table, nous envoyons directement la table, de sorte que Lua fasse directement la recherche - // Ceci n'est possible que si nous n'avons ni getter, ni parent - lua.PushValue(-1); - lua.SetField("__index"); // ClassMeta.__index = StaticGetterProxy/ClassMeta + return 1; + } - if (m_info->staticSetter) + template + int LuaClass::StaticMethodProxy(lua_State* state) + { + LuaInstance& lua = *LuaInstance::GetInstance(state); + + ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + unsigned int index = static_cast(lua.ToInteger(lua.GetIndexOfUpValue(2))); + StaticFunc method = info->staticMethods[index]; + + return method(lua); + } + + template + int LuaClass::StaticSetterProxy(lua_State* state) + { + LuaInstance& lua = *LuaInstance::GetInstance(state); + + ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); + StaticIndexFunc setter = info->staticSetter; + + if (!setter(lua)) { - lua.PushValue(1); - lua.PushCFunction(StaticSetterProxy, 1); - lua.SetField("__newindex"); // ClassMeta.__newindex = StaticSetterProxy + std::size_t length; + const char* str = lua.ToString(2, &length); + + lua.Error("Class \"" + info->name + "\" has no static field \"" + String(str, length) + ')'); } - m_info->staticMethods.reserve(m_staticMethods.size()); - for (auto& pair : m_staticMethods) - { - m_info->staticMethods.push_back(pair.second); - - lua.PushValue(1); - lua.PushInteger(m_info->staticMethods.size() - 1); - - lua.PushCFunction(StaticMethodProxy, 2); - lua.SetField(pair.first); // ClassMeta.method = StaticMethodProxy - } - - lua.SetMetatable(-2); // setmetatable(Class, ClassMeta) - - lua.PushValue(-1); // Copie - lua.SetGlobal(m_info->name); // Class - - m_info->globalTableRef = lua.CreateReference(); + return 1; } - lua.Pop(); // On pop l'Userdata (contenant nos informations) -} - -template -void NzLuaClass::PushGlobalTable(NzLuaInstance& lua) -{ - lua.PushReference(m_info->globalTableRef); -} - -template -void NzLuaClass::SetConstructor(ConstructorFunc constructor) -{ - m_info->constructor = constructor; -} - -template -void NzLuaClass::SetFinalizer(FinalizerFunc finalizer) -{ - m_info->finalizer = finalizer; -} - -template -void NzLuaClass::SetGetter(ClassIndexFunc getter) -{ - m_info->getter = getter; -} - -template -void NzLuaClass::SetMethod(const NzString& name, ClassFunc method) -{ - m_methods[name] = method; -} - -template -void NzLuaClass::SetSetter(ClassIndexFunc setter) -{ - m_info->setter = setter; -} - -template -void NzLuaClass::SetStaticGetter(StaticIndexFunc getter) -{ - m_info->staticGetter = getter; -} - -template -void NzLuaClass::SetStaticMethod(const NzString& name, StaticFunc method) -{ - m_staticMethods[name] = method; -} - -template -void NzLuaClass::SetStaticSetter(StaticIndexFunc setter) -{ - m_info->staticSetter = setter; -} - -template -int NzLuaClass::ConstructorProxy(lua_State* state) -{ - NzLuaInstance& lua = *NzLuaInstance::GetInstance(state); - - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - ConstructorFunc constructor = info->constructor; - - lua.Remove(1); // On enlève l'argument "table" du stack - - T* instance = constructor(lua); - if (!instance) - { - lua.Error("Constructor failed"); - return 0; // Normalement jamais exécuté (l'erreur provoquant une exception) - } - - T** ud = static_cast(lua.PushUserdata(sizeof(T*))); - *ud = instance; - lua.SetMetatable(info->name); - - return 1; -} - -template -int NzLuaClass::FinalizerProxy(lua_State* state) -{ - NzLuaInstance& lua = *NzLuaInstance::GetInstance(state); - - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - FinalizerFunc finalizer = info->finalizer; - - T* instance = *static_cast(lua.CheckUserdata(1, info->name)); - - if (!finalizer || finalizer(lua, *instance)) - delete instance; - - return 0; -} - -template -int NzLuaClass::InfoDestructor(lua_State* state) -{ - NzLuaInstance& lua = *NzLuaInstance::GetInstance(state); - - std::shared_ptr& infoPtr = *static_cast*>(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - lua.DestroyReference(infoPtr->globalTableRef); - - using namespace std; // Obligatoire pour le destructeur - infoPtr.~shared_ptr(); // Si vous voyez une autre façon de faire, je suis preneur - - return 0; -} - -template -int NzLuaClass::GetterProxy(lua_State* state) -{ - NzLuaInstance& lua = *NzLuaInstance::GetInstance(state); - - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - ClassIndexFunc getter = info->getter; - - T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); - - if (!getter(lua, instance)) - { - // On accède alors à la table - lua.PushValue(lua.GetIndexOfUpValue(2)); - lua.PushValue(-2); - lua.GetTable(); - } - - return 1; -} - -template -int NzLuaClass::MethodProxy(lua_State* state) -{ - NzLuaInstance& lua = *NzLuaInstance::GetInstance(state); - - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - unsigned int index = static_cast(lua.ToInteger(lua.GetIndexOfUpValue(2))); - ClassFunc method = info->methods[index]; - - T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); - - lua.Remove(1); // On enlève l'argument "userdata" du stack - - return method(lua, instance); -} - -template -int NzLuaClass::SetterProxy(lua_State* state) -{ - NzLuaInstance& lua = *NzLuaInstance::GetInstance(state); - - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - ClassIndexFunc setter = info->setter; - - T& instance = *(*static_cast(lua.CheckUserdata(1, info->name))); - - if (!setter(lua, instance)) - { - std::size_t length; - const char* str = lua.ToString(2, &length); - - lua.Error("Class \"" + info->name + "\" has no field \"" + NzString(str, length) + ')'); - } - - return 1; -} - -template -int NzLuaClass::StaticGetterProxy(lua_State* state) -{ - NzLuaInstance& lua = *NzLuaInstance::GetInstance(state); - - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - StaticIndexFunc getter = info->staticGetter; - - if (!getter(lua)) - { - // On accède alors à la table - lua.PushValue(lua.GetIndexOfUpValue(2)); - lua.PushValue(-2); - lua.GetTable(); - } - - return 1; -} - -template -int NzLuaClass::StaticMethodProxy(lua_State* state) -{ - NzLuaInstance& lua = *NzLuaInstance::GetInstance(state); - - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - unsigned int index = static_cast(lua.ToInteger(lua.GetIndexOfUpValue(2))); - StaticFunc method = info->staticMethods[index]; - - return method(lua); -} - -template -int NzLuaClass::StaticSetterProxy(lua_State* state) -{ - NzLuaInstance& lua = *NzLuaInstance::GetInstance(state); - - ClassInfo* info = *static_cast(lua.ToUserdata(lua.GetIndexOfUpValue(1))); - StaticIndexFunc setter = info->staticSetter; - - if (!setter(lua)) - { - std::size_t length; - const char* str = lua.ToString(2, &length); - - lua.Error("Class \"" + info->name + "\" has no static field \"" + NzString(str, length) + ')'); - } - - return 1; } #include diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index 35fd1cd73..e3ff30adc 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -19,157 +19,160 @@ struct lua_Debug; struct lua_State; -class NzLuaInstance; - -using NzLuaCFunction = int (*)(lua_State* state); -using NzLuaFunction = std::function; - -class NAZARA_LUA_API NzLuaInstance +namespace Nz { - public: - NzLuaInstance(); - NzLuaInstance(const NzLuaInstance&) = delete; - NzLuaInstance(NzLuaInstance&&) = delete; ///TODO - ~NzLuaInstance(); + class LuaInstance; - void ArgCheck(bool condition, unsigned int argNum, const char* error); - void ArgCheck(bool condition, unsigned int argNum, const NzString& error); - int ArgError(unsigned int argNum, const char* error); - int ArgError(unsigned int argNum, const NzString& error); + using LuaCFunction = int (*)(lua_State* state); + using LuaFunction = std::function; - bool Call(unsigned int argCount); - bool Call(unsigned int argCount, unsigned int resultCount); + class NAZARA_LUA_API LuaInstance + { + public: + LuaInstance(); + LuaInstance(const LuaInstance&) = delete; + LuaInstance(LuaInstance&&) = delete; ///TODO + ~LuaInstance(); - void CheckAny(int index) const; - bool CheckBoolean(int index) const; - bool CheckBoolean(int index, bool defValue) const; - long long CheckInteger(int index) const; - long long CheckInteger(int index, long long defValue) const; - double CheckNumber(int index) const; - double CheckNumber(int index, double defValue) const; - void CheckStack(int space, const char* error = nullptr) const; - void CheckStack(int space, const NzString& error) const; - const char* CheckString(int index, std::size_t* length = nullptr) const; - const char* CheckString(int index, const char* defValue, std::size_t* length = nullptr) const; - void CheckType(int index, nzLuaType type) const; - void* CheckUserdata(int index, const char* tname) const; - void* CheckUserdata(int index, const NzString& tname) const; + void ArgCheck(bool condition, unsigned int argNum, const char* error); + void ArgCheck(bool condition, unsigned int argNum, const String& error); + int ArgError(unsigned int argNum, const char* error); + int ArgError(unsigned int argNum, const String& error); - bool Compare(int index1, int index2, nzLuaComparison comparison) const; - void Compute(nzLuaOperation operation); + bool Call(unsigned int argCount); + bool Call(unsigned int argCount, unsigned int resultCount); - void Concatenate(int count); + void CheckAny(int index) const; + bool CheckBoolean(int index) const; + bool CheckBoolean(int index, bool defValue) const; + long long CheckInteger(int index) const; + long long CheckInteger(int index, long long defValue) const; + double CheckNumber(int index) const; + double CheckNumber(int index, double defValue) const; + void CheckStack(int space, const char* error = nullptr) const; + void CheckStack(int space, const String& error) const; + const char* CheckString(int index, std::size_t* length = nullptr) const; + const char* CheckString(int index, const char* defValue, std::size_t* length = nullptr) const; + void CheckType(int index, nzLuaType type) const; + void* CheckUserdata(int index, const char* tname) const; + void* CheckUserdata(int index, const String& tname) const; - int CreateReference(); - void DestroyReference(int ref); + bool Compare(int index1, int index2, nzLuaComparison comparison) const; + void Compute(nzLuaOperation operation); - NzString DumpStack() const; + void Concatenate(int count); - void Error(const char* message); - void Error(const NzString& message); + int CreateReference(); + void DestroyReference(int ref); - bool Execute(const NzString& code); - bool ExecuteFromFile(const NzString& filePath); - bool ExecuteFromMemory(const void* data, unsigned int size); - bool ExecuteFromStream(NzInputStream& stream); + String DumpStack() const; - int GetAbsIndex(int index) const; - nzLuaType GetField(const char* fieldName, int index = -1) const; - nzLuaType GetField(const NzString& fieldName, int index = -1) const; - nzLuaType GetGlobal(const char* name) const; - nzLuaType GetGlobal(const NzString& name) const; - lua_State* GetInternalState() const; - NzString GetLastError() const; - nzUInt32 GetMemoryLimit() const; - nzUInt32 GetMemoryUsage() const; - nzLuaType GetMetatable(const char* tname) const; - nzLuaType GetMetatable(const NzString& tname) const; - bool GetMetatable(int index) const; - unsigned int GetStackTop() const; - nzLuaType GetTable(int index = -2) const; - nzUInt32 GetTimeLimit() const; - nzLuaType GetType(int index) const; - const char* GetTypeName(nzLuaType type) const; + void Error(const char* message); + void Error(const String& message); - void Insert(int index); + bool Execute(const String& code); + bool ExecuteFromFile(const String& filePath); + bool ExecuteFromMemory(const void* data, unsigned int size); + bool ExecuteFromStream(InputStream& stream); - bool IsOfType(int index, nzLuaType type) const; - bool IsOfType(int index, const char* tname) const; - bool IsOfType(int index, const NzString& tname) const; - bool IsValid(int index) const; + int GetAbsIndex(int index) const; + nzLuaType GetField(const char* fieldName, int index = -1) const; + nzLuaType GetField(const String& fieldName, int index = -1) const; + nzLuaType GetGlobal(const char* name) const; + nzLuaType GetGlobal(const String& name) const; + lua_State* GetInternalState() const; + String GetLastError() const; + UInt32 GetMemoryLimit() const; + UInt32 GetMemoryUsage() const; + nzLuaType GetMetatable(const char* tname) const; + nzLuaType GetMetatable(const String& tname) const; + bool GetMetatable(int index) const; + unsigned int GetStackTop() const; + nzLuaType GetTable(int index = -2) const; + UInt32 GetTimeLimit() const; + nzLuaType GetType(int index) const; + const char* GetTypeName(nzLuaType type) const; - long long Length(int index) const; + void Insert(int index); - void MoveTo(NzLuaInstance* instance, int n); + bool IsOfType(int index, nzLuaType type) const; + bool IsOfType(int index, const char* tname) const; + bool IsOfType(int index, const String& tname) const; + bool IsValid(int index) const; - bool NewMetatable(const char* str); - bool NewMetatable(const NzString& str); - bool Next(int index = -2); + long long Length(int index) const; - void Pop(unsigned int n = 1U); + void MoveTo(LuaInstance* instance, int n); - void PushBoolean(bool value); - void PushCFunction(NzLuaCFunction func, unsigned int upvalueCount = 0); - void PushFunction(NzLuaFunction func); - template void PushFunction(R(*func)(Args...)); - void PushInteger(long long value); - void PushLightUserdata(void* value); - void PushMetatable(const char* str); - void PushMetatable(const NzString& str); - void PushNil(); - void PushNumber(double value); - void PushReference(int ref); - void PushString(const char* str); - void PushString(const char* str, unsigned int size); - void PushString(const NzString& str); - void PushTable(unsigned int sequenceElementCount = 0, unsigned int arrayElementCount = 0); - void* PushUserdata(unsigned int size); - void PushValue(int index); + bool NewMetatable(const char* str); + bool NewMetatable(const String& str); + bool Next(int index = -2); - void Remove(int index); - void Replace(int index); + void Pop(unsigned int n = 1U); - void SetField(const char* name, int index = -2); - void SetField(const NzString& name, int index = -2); - void SetGlobal(const char* name); - void SetGlobal(const NzString& name); - void SetMetatable(const char* tname); - void SetMetatable(const NzString& tname); - void SetMetatable(int index); - void SetMemoryLimit(nzUInt32 memoryLimit); - void SetTable(int index = -3); - void SetTimeLimit(nzUInt32 timeLimit); + void PushBoolean(bool value); + void PushCFunction(LuaCFunction func, unsigned int upvalueCount = 0); + void PushFunction(LuaFunction func); + template void PushFunction(R(*func)(Args...)); + void PushInteger(long long value); + void PushLightUserdata(void* value); + void PushMetatable(const char* str); + void PushMetatable(const String& str); + void PushNil(); + void PushNumber(double value); + void PushReference(int ref); + void PushString(const char* str); + void PushString(const char* str, unsigned int size); + void PushString(const String& str); + void PushTable(unsigned int sequenceElementCount = 0, unsigned int arrayElementCount = 0); + void* PushUserdata(unsigned int size); + void PushValue(int index); - bool ToBoolean(int index) const; - long long ToInteger(int index, bool* succeeded = nullptr) const; - double ToNumber(int index, bool* succeeded = nullptr) const; - const void* ToPointer(int index) const; - const char* ToString(int index, std::size_t* length = nullptr) const; - void* ToUserdata(int index) const; - void* ToUserdata(int index, const char* tname) const; - void* ToUserdata(int index, const NzString& tname) const; + void Remove(int index); + void Replace(int index); - NzLuaInstance& operator=(const NzLuaInstance&) = delete; - NzLuaInstance& operator=(NzLuaInstance&&) = delete; ///TODO + void SetField(const char* name, int index = -2); + void SetField(const String& name, int index = -2); + void SetGlobal(const char* name); + void SetGlobal(const String& name); + void SetMetatable(const char* tname); + void SetMetatable(const String& tname); + void SetMetatable(int index); + void SetMemoryLimit(UInt32 memoryLimit); + void SetTable(int index = -3); + void SetTimeLimit(UInt32 timeLimit); - static int GetIndexOfUpValue(int upValue); - static NzLuaInstance* GetInstance(lua_State* state); + bool ToBoolean(int index) const; + long long ToInteger(int index, bool* succeeded = nullptr) const; + double ToNumber(int index, bool* succeeded = nullptr) const; + const void* ToPointer(int index) const; + const char* ToString(int index, std::size_t* length = nullptr) const; + void* ToUserdata(int index) const; + void* ToUserdata(int index, const char* tname) const; + void* ToUserdata(int index, const String& tname) const; - private: - bool Run(int argCount, int resultCount); + LuaInstance& operator=(const LuaInstance&) = delete; + LuaInstance& operator=(LuaInstance&&) = delete; ///TODO - static void* MemoryAllocator(void *ud, void *ptr, std::size_t osize, std::size_t nsize); - static int ProxyFunc(lua_State* state); - static void TimeLimiter(lua_State* state, lua_Debug* debug); + static int GetIndexOfUpValue(int upValue); + static LuaInstance* GetInstance(lua_State* state); - nzUInt32 m_memoryLimit; - nzUInt32 m_memoryUsage; - nzUInt32 m_timeLimit; - NzClock m_clock; - NzString m_lastError; - lua_State* m_state; - unsigned int m_level; -}; + private: + bool Run(int argCount, int resultCount); + + static void* MemoryAllocator(void *ud, void *ptr, std::size_t osize, std::size_t nsize); + static int ProxyFunc(lua_State* state); + static void TimeLimiter(lua_State* state, lua_Debug* debug); + + UInt32 m_memoryLimit; + UInt32 m_memoryUsage; + UInt32 m_timeLimit; + Clock m_clock; + String m_lastError; + lua_State* m_state; + unsigned int m_level; + }; +} #include diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index f116af219..beef1fe6d 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -5,163 +5,166 @@ #include #include -// Functions args -bool NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) +namespace Nz { - return instance.CheckBoolean(index); -} - -double NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) -{ - return instance.CheckNumber(index); -} - -float NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) -{ - return static_cast(instance.CheckNumber(index)); -} - -int NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) -{ - return static_cast(instance.CheckInteger(index)); -} - -std::string NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) -{ - std::size_t strLength = 0; - const char* str = instance.CheckString(index, &strLength); - - return std::string(str, strLength); -} - -NzString NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) -{ - std::size_t strLength = 0; - const char* str = instance.CheckString(index, &strLength); - - return NzString(str, strLength); -} - -template -T NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) -{ - return NzLuaImplQueryArg(instance, index, NzTypeTag()); -} - -template -std::enable_if_t::value, T> NzLuaImplQueryArg(NzLuaInstance& instance, unsigned int index, NzTypeTag) -{ - return static_cast(NzLuaImplQueryArg(instance, index, NzTypeTag::type>())); -} - -// Function returns -int NzLuaImplReplyVal(NzLuaInstance& instance, bool&& val, NzTypeTag) -{ - instance.PushBoolean(val); - return 1; -} - -int NzLuaImplReplyVal(NzLuaInstance& instance, double&& val, NzTypeTag) -{ - instance.PushNumber(val); - return 1; -} - -int NzLuaImplReplyVal(NzLuaInstance& instance, float&& val, NzTypeTag) -{ - instance.PushNumber(val); - return 1; -} - -int NzLuaImplReplyVal(NzLuaInstance& instance, int&& val, NzTypeTag) -{ - instance.PushInteger(val); - return 1; -} - -int NzLuaImplReplyVal(NzLuaInstance& instance, std::string&& val, NzTypeTag) -{ - instance.PushString(val.c_str(), val.size()); - return 1; -} - -int NzLuaImplReplyVal(NzLuaInstance& instance, NzString&& val, NzTypeTag) -{ - instance.PushString(std::move(val)); - return 1; -} - -template -int NzLuaImplReplyVal(NzLuaInstance& instance, std::pair&& val, NzTypeTag>) -{ - int retVal = 0; - - retVal += NzLuaImplReplyVal(instance, std::move(val.first), NzTypeTag()); - retVal += NzLuaImplReplyVal(instance, std::move(val.second), NzTypeTag()); - - return retVal; -} - -template -std::enable_if_t::value, int> NzLuaImplReplyVal(NzLuaInstance& instance, T&& val, NzTypeTag) -{ - using SignedT = typename std::make_signed::type; - - return NzLuaImplReplyVal(instance, val, NzTypeTag()); -} - -template -class NzLuaImplFunctionProxy -{ - public: - NzLuaImplFunctionProxy(NzLuaInstance& instance) : - m_instance(instance) - { - } - - template - void ProcessArgs() - { - std::get(m_args) = std::move(NzLuaImplQueryArg(m_instance, N+1, NzTypeTag())); - } - - template - void ProcessArgs() - { - ProcessArgs(); - ProcessArgs(); - } - - void ProcessArgs() - { - ProcessArgs<0, Args...>(); - } - - int Invoke(void (*func)(Args...)) - { - NzApply(func, m_args); - return 0; - } - - template - int Invoke(Ret (*func)(Args...)) - { - return NzLuaImplReplyVal(m_instance, std::move(NzApply(func, m_args)), NzTypeTag()); - } - - private: - NzLuaInstance& m_instance; - std::tuple m_args; -}; - -template -void NzLuaInstance::PushFunction(R(*func)(Args...)) -{ - PushFunction([func](NzLuaInstance& instance) -> int + // Functions args + bool LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) { - NzLuaImplFunctionProxy handler(instance); - handler.ProcessArgs(); + return instance.CheckBoolean(index); + } - return handler.Invoke(func); - }); + double LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + { + return instance.CheckNumber(index); + } + + float LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + { + return static_cast(instance.CheckNumber(index)); + } + + int LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + { + return static_cast(instance.CheckInteger(index)); + } + + std::string LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + { + std::size_t strLength = 0; + const char* str = instance.CheckString(index, &strLength); + + return std::string(str, strLength); + } + + String LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + { + std::size_t strLength = 0; + const char* str = instance.CheckString(index, &strLength); + + return String(str, strLength); + } + + template + T LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + { + return LuaImplQueryArg(instance, index, TypeTag()); + } + + template + std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + { + return static_cast(LuaImplQueryArg(instance, index, TypeTag::type>())); + } + + // Function returns + int LuaImplReplyVal(LuaInstance& instance, bool&& val, TypeTag) + { + instance.PushBoolean(val); + return 1; + } + + int LuaImplReplyVal(LuaInstance& instance, double&& val, TypeTag) + { + instance.PushNumber(val); + return 1; + } + + int LuaImplReplyVal(LuaInstance& instance, float&& val, TypeTag) + { + instance.PushNumber(val); + return 1; + } + + int LuaImplReplyVal(LuaInstance& instance, int&& val, TypeTag) + { + instance.PushInteger(val); + return 1; + } + + int LuaImplReplyVal(LuaInstance& instance, std::string&& val, TypeTag) + { + instance.PushString(val.c_str(), val.size()); + return 1; + } + + int LuaImplReplyVal(LuaInstance& instance, String&& val, TypeTag) + { + instance.PushString(std::move(val)); + return 1; + } + + template + int LuaImplReplyVal(LuaInstance& instance, std::pair&& val, TypeTag>) + { + int retVal = 0; + + retVal += LuaImplReplyVal(instance, std::move(val.first), TypeTag()); + retVal += LuaImplReplyVal(instance, std::move(val.second), TypeTag()); + + return retVal; + } + + template + std::enable_if_t::value, int> LuaImplReplyVal(LuaInstance& instance, T&& val, TypeTag) + { + using SignedT = typename std::make_signed::type; + + return LuaImplReplyVal(instance, val, TypeTag()); + } + + template + class LuaImplFunctionProxy + { + public: + LuaImplFunctionProxy(LuaInstance& instance) : + m_instance(instance) + { + } + + template + void ProcessArgs() + { + std::get(m_args) = std::move(LuaImplQueryArg(m_instance, N+1, TypeTag())); + } + + template + void ProcessArgs() + { + ProcessArgs(); + ProcessArgs(); + } + + void ProcessArgs() + { + ProcessArgs<0, Args...>(); + } + + int Invoke(void (*func)(Args...)) + { + Apply(func, m_args); + return 0; + } + + template + int Invoke(Ret (*func)(Args...)) + { + return LuaImplReplyVal(m_instance, std::move(Apply(func, m_args)), TypeTag()); + } + + private: + LuaInstance& m_instance; + std::tuple m_args; + }; + + template + void LuaInstance::PushFunction(R(*func)(Args...)) + { + PushFunction([func](LuaInstance& instance) -> int + { + LuaImplFunctionProxy handler(instance); + handler.ProcessArgs(); + + return handler.Invoke(func); + }); + } } diff --git a/include/Nazara/Math/Algorithm.hpp b/include/Nazara/Math/Algorithm.hpp index 0d0776746..de97c120a 100644 --- a/include/Nazara/Math/Algorithm.hpp +++ b/include/Nazara/Math/Algorithm.hpp @@ -28,35 +28,38 @@ #define M_SQRT3 1.7320508075688772935274463 #endif -template T NzApproach(T value, T objective, T increment); -template constexpr T NzClamp(T value, T min, T max); -template T NzCountBits(T value); -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); -unsigned int NzGetNumberLength(unsigned char number); -unsigned int NzGetNumberLength(int number); -unsigned int NzGetNumberLength(unsigned int number); -unsigned int NzGetNumberLength(long long number); -unsigned int NzGetNumberLength(unsigned long long number); -unsigned int NzGetNumberLength(float number, nzUInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); -unsigned int NzGetNumberLength(double number, nzUInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); -unsigned int NzGetNumberLength(long double number, nzUInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); -template unsigned int NzIntegralLog2(T number); -template unsigned int NzIntegralLog2Pot(T pot); -unsigned int NzIntegralPow(unsigned int base, unsigned int exponent); -template T NzLerp(T from, T to, T2 interpolation); -template T NzMultiplyAdd(T x, T y, T z); -template T NzNormalizeAngle(T angle); -template bool NzNumberEquals(T a, T b); -template bool NzNumberEquals(T a, T b, T maxDifference); -NzString NzNumberToString(long long number, nzUInt8 radix = 10); -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); +namespace Nz +{ + template T Approach(T value, T objective, T increment); + template constexpr T Clamp(T value, T min, T max); + template T CountBits(T value); + template constexpr T FromDegrees(T degrees); + template constexpr T FromRadians(T radians); + template constexpr T NzDegreeToRadian(T degrees); + unsigned int GetNearestPowerOfTwo(unsigned int number); + unsigned int GetNumberLength(signed char number); + unsigned int GetNumberLength(unsigned char number); + unsigned int GetNumberLength(int number); + unsigned int GetNumberLength(unsigned int number); + unsigned int GetNumberLength(long long number); + unsigned int GetNumberLength(unsigned long long number); + unsigned int GetNumberLength(float number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); + unsigned int GetNumberLength(double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); + unsigned int GetNumberLength(long double number, UInt8 precision = NAZARA_CORE_DECIMAL_DIGITS); + template unsigned int IntegralLog2(T number); + template unsigned int IntegralLog2Pot(T pot); + unsigned int IntegralPow(unsigned int base, unsigned int exponent); + template T Lerp(T from, T to, T2 interpolation); + template T MultiplyAdd(T x, T y, T z); + template T NormalizeAngle(T angle); + template bool NumberEquals(T a, T b); + template bool NumberEquals(T a, T b, T maxDifference); + String NumberToString(long long number, UInt8 radix = 10); + template T RadianToDegree(T radians); + long long StringToNumber(String str, UInt8 radix = 10, bool* ok = nullptr); + template constexpr T ToDegrees(T angle); + template constexpr T ToRadians(T angle); +} #include diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index 73c3fd3b2..3d8708695 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -11,451 +11,456 @@ #include #include -namespace +namespace Nz { - // https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn - static const unsigned int MultiplyDeBruijnBitPosition[32] = + namespace Detail { - 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, - 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 - }; - - static const unsigned int MultiplyDeBruijnBitPosition2[32] = - { - 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, - 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 - }; - - - template - typename std::enable_if::type NzImplIntegralLog2(T number) - { - // https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn - number |= number >> 1; // first round down to one less than a power of 2 - number |= number >> 2; - number |= number >> 4; - number |= number >> 8; - number |= number >> 16; - - return MultiplyDeBruijnBitPosition[static_cast(number * 0x07C4ACDDU) >> 27]; - } - - template - // Les parenthèses autour de la condition sont nécesaires pour que GCC compile ça - typename std::enable_if<(sizeof(T) > sizeof(nzUInt32)), unsigned int>::type NzImplIntegralLog2(T number) - { - static_assert(sizeof(T) % sizeof(nzUInt32) == 0, "Assertion failed"); - - // L'algorithme pour le logarithme base 2 (au dessus) ne fonctionne qu'avec des nombres au plus 32bits - // ce code décompose les nombres plus grands en nombres 32 bits par masquage et bit shifting - for (int i = sizeof(T)-sizeof(nzUInt32); i >= 0; i -= sizeof(nzUInt32)) + namespace { - // Le masque 32 bits sur la partie du nombre qu'on traite actuellement - T mask = T(std::numeric_limits::max()) << i*8; - T val = (number & mask) >> i*8; // Masquage et shifting des bits vers la droite (pour le ramener sur 32bits) + // https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn + static const unsigned int MultiplyDeBruijnBitPosition[32] = + { + 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 + }; - // Appel de la fonction avec le nombre 32bits, si le résultat est non-nul nous avons la réponse - unsigned int log2 = NzImplIntegralLog2(val); - if (log2) - return log2 + i*8; + static const unsigned int MultiplyDeBruijnBitPosition2[32] = + { + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 + }; } - return 0; - } - - template - typename std::enable_if::type NzImplIntegralLog2Pot(T number) - { - // https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn - return MultiplyDeBruijnBitPosition2[static_cast(number * 0x077CB531U) >> 27]; - } - - template - // Les parenthèses autour de la condition sont nécesaires pour que GCC compile ça - typename std::enable_if<(sizeof(T) > sizeof(nzUInt32)), unsigned int>::type NzImplIntegralLog2Pot(T number) - { - static_assert(sizeof(T) % sizeof(nzUInt32) == 0, "Assertion failed"); - - // L'algorithme pour le logarithme base 2 (au dessus) ne fonctionne qu'avec des nombres au plus 32bits - // ce code décompose les nombres plus grands en nombres 32 bits par masquage et bit shifting - for (int i = sizeof(T)-sizeof(nzUInt32); i >= 0; i -= sizeof(nzUInt32)) + template + typename std::enable_if::type IntegralLog2(T number) { - // Le masque 32 bits sur la partie du nombre qu'on traite actuellement - T mask = T(std::numeric_limits::max()) << i*8; - nzUInt32 val = nzUInt32((number & mask) >> i*8); // Masquage et shifting des bits vers la droite (pour le ramener sur 32bits) + // https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn + number |= number >> 1; // first round down to one less than a power of 2 + number |= number >> 2; + number |= number >> 4; + number |= number >> 8; + number |= number >> 16; - // Appel de la fonction avec le nombre 32bits, si le résultat est non-nul nous avons la réponse - unsigned int log2 = NzImplIntegralLog2Pot(val); - if (log2) - return log2 + i*8; + return MultiplyDeBruijnBitPosition[static_cast(number * 0x07C4ACDDU) >> 27]; } - return 0; - } -} + template + // Les parenthèses autour de la condition sont nécesaires pour que GCC compile ça + typename std::enable_if<(sizeof(T) > sizeof(UInt32)), unsigned int>::type IntegralLog2(T number) + { + static_assert(sizeof(T) % sizeof(UInt32) == 0, "Assertion failed"); -template -T NzApproach(T value, T objective, T increment) -{ - ///TODO: Marquer comme constexpr en C++14 - if (value < objective) - return std::min(value + increment, objective); - else if (value > objective) - return std::max(value - increment, objective); - else - return value; -} + // L'algorithme pour le logarithme base 2 (au dessus) ne fonctionne qu'avec des nombres au plus 32bits + // ce code décompose les nombres plus grands en nombres 32 bits par masquage et bit shifting + for (int i = sizeof(T)-sizeof(UInt32); i >= 0; i -= sizeof(UInt32)) + { + // Le masque 32 bits sur la partie du nombre qu'on traite actuellement + T mask = T(std::numeric_limits::max()) << i*8; + T val = (number & mask) >> i*8; // Masquage et shifting des bits vers la droite (pour le ramener sur 32bits) -template -constexpr T NzClamp(T value, T min, T max) -{ - return std::max(std::min(value, max), min); -} + // Appel de la fonction avec le nombre 32bits, si le résultat est non-nul nous avons la réponse + unsigned int log2 = IntegralLog2(val); + if (log2) + return log2 + i*8; + } -template -T NzCountBits(T value) -{ - // https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan - unsigned int count = 0; - while (value) - { - value &= value - 1; - count++; + return 0; + } + + template + typename std::enable_if::type IntegralLog2Pot(T number) + { + // https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn + return MultiplyDeBruijnBitPosition2[static_cast(number * 0x077CB531U) >> 27]; + } + + template + // Les parenthèses autour de la condition sont nécesaires pour que GCC compile ça + typename std::enable_if<(sizeof(T) > sizeof(UInt32)), unsigned int>::type IntegralLog2Pot(T number) + { + static_assert(sizeof(T) % sizeof(UInt32) == 0, "Assertion failed"); + + // L'algorithme pour le logarithme base 2 (au dessus) ne fonctionne qu'avec des nombres au plus 32bits + // ce code décompose les nombres plus grands en nombres 32 bits par masquage et bit shifting + for (int i = sizeof(T)-sizeof(UInt32); i >= 0; i -= sizeof(UInt32)) + { + // Le masque 32 bits sur la partie du nombre qu'on traite actuellement + T mask = T(std::numeric_limits::max()) << i*8; + UInt32 val = UInt32((number & mask) >> i*8); // Masquage et shifting des bits vers la droite (pour le ramener sur 32bits) + + // Appel de la fonction avec le nombre 32bits, si le résultat est non-nul nous avons la réponse + unsigned int log2 = IntegralLog2Pot(val); + if (log2) + return log2 + i*8; + } + + return 0; + } } - return count; -} - -template -constexpr T NzDegreeToRadian(T degrees) -{ - return degrees * T(M_PI/180.0); -} - -template -constexpr T NzFromDegrees(T degrees) -{ - #if NAZARA_MATH_ANGLE_RADIAN - return NzDegreeToRadian(degrees); - #else - return degrees; - #endif -} - -template -constexpr T NzFromRadians(T radians) -{ - #if NAZARA_MATH_ANGLE_RADIAN - return radians; - #else - return NzRadianToDegree(radians); - #endif -} - -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) - x <<= 1; - - return x; -} - -inline unsigned int NzGetNumberLength(signed char number) -{ - ///TODO: Marquer comme constexpr en C++14 - // Le standard définit le char comme étant codé sur un octet - static_assert(sizeof(number) == 1, "Signed char must be one byte-sized"); - - if (number >= 100) - return 3; - else if (number >= 10) - return 2; - else if (number >= 0) - return 1; - else if (number > -10) - return 2; - else if (number > -100) - return 3; - else - return 4; -} - -inline unsigned int NzGetNumberLength(unsigned char number) -{ - ///TODO: Marquer comme constexpr en C++14 - // Le standard définit le char comme étant codé sur un octet - static_assert(sizeof(number) == 1, "Unsigned char must be one byte-sized"); - - if (number >= 100) - return 3; - else if (number >= 10) - return 2; - else - return 1; -} - -inline unsigned int NzGetNumberLength(int number) -{ - if (number == 0) - return 1; - - return static_cast(std::log10(std::abs(number))) + (number < 0 ? 2 : 1); -} - -inline unsigned int NzGetNumberLength(unsigned int number) -{ - if (number == 0) - return 1; - - return static_cast(std::log10(number))+1; -} - -inline unsigned int NzGetNumberLength(long long number) -{ - if (number == 0) - return 1; - - return static_cast(std::log10(std::abs(number))) + (number < 0 ? 2 : 1); -} - -inline unsigned int NzGetNumberLength(unsigned long long number) -{ - if (number == 0) - return 1; - - return static_cast(std::log10(number)) + 1; -} - -inline unsigned int NzGetNumberLength(float number, nzUInt8 precision) -{ - // L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999) - return NzGetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point -} - -inline unsigned int NzGetNumberLength(double number, nzUInt8 precision) -{ - // L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999) - return NzGetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point -} - -inline unsigned int NzGetNumberLength(long double number, nzUInt8 precision) -{ - // L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999) - return NzGetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point -} - -template -unsigned int NzIntegralLog2(T number) -{ - // Proxy nécessaire pour éviter un problème de surcharge - return NzImplIntegralLog2(number); -} - -template -unsigned int NzIntegralLog2Pot(T pot) -{ - return NzImplIntegralLog2Pot(pot); -} - -inline unsigned int NzIntegralPow(unsigned int base, unsigned int exponent) -{ - ///TODO: Marquer comme constexpr en C++14 - unsigned int r = 1; - for (unsigned int i = 0; i < exponent; ++i) - r *= base; - - return r; -} - -template -T NzLerp(T from, T to, T2 interpolation) -{ - #ifdef NAZARA_DEBUG - if (interpolation < T2(0.0) || interpolation > T2(1.0)) - NazaraWarning("Interpolation should be in range [0..1] (Got " + NzString::Number(interpolation) + ')'); - #endif - - return from + interpolation * (to - from); -} - -template -T NzMultiplyAdd(T x, T y, T z) -{ - return x*y + z; -} - -#ifdef FP_FAST_FMAF -template<> -inline float NzMultiplyAdd(float x, float y, float z) -{ - return std::fmaf(x, y, z); -} -#endif - -#ifdef FP_FAST_FMA -template<> -inline double NzMultiplyAdd(double x, double y, double z) -{ - return std::fma(x, y, z); -} -#endif - -#ifdef FP_FAST_FMAL -template<> -inline long double NzMultiplyAdd(long double x, long double y, long double z) -{ - return std::fmal(x, y, z); -} -#endif - -template -T NzNormalizeAngle(T angle) -{ - #if NAZARA_MATH_ANGLE_RADIAN - const T limit = T(M_PI); - #else - const T limit = T(180.0); - #endif - const T twoLimit = limit * T(2); - - angle = std::fmod(angle + limit, twoLimit); - if (angle < T(0)) - angle += twoLimit; - - return angle - limit; -} - -template -bool NzNumberEquals(T a, T b) -{ - return NzNumberEquals(a, b, std::numeric_limits::epsilon()); -} - -template -bool NzNumberEquals(T a, T b, T maxDifference) -{ - if (b > a) - std::swap(a, b); - - T diff = a - b; - return diff <= maxDifference; -} - -inline NzString NzNumberToString(long long number, nzUInt8 radix) -{ - #if NAZARA_MATH_SAFE - if (radix < 2 || radix > 36) + template + T Approach(T value, T objective, T increment) { - NazaraError("Base must be between 2 and 36"); - return NzString(); - } - #endif - - if (number == 0) - return NzString('0'); - - static const char* symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - bool negative; - if (number < 0) - { - negative = true; - number = -number; - } - else - negative = false; - - NzString str; - str.Reserve(NzGetNumberLength(number)); // Prends en compte le signe négatif - - do - { - str.Append(symbols[number % radix]); - number /= radix; - } - while (number > 0); - - if (negative) - str.Append('-'); - - return str.Reverse(); -} - -template -T NzRadianToDegree(T radians) -{ - return radians * T(180.0/M_PI); -} - -inline long long NzStringToNumber(NzString str, nzUInt8 radix, bool* ok) -{ - #if NAZARA_MATH_SAFE - if (radix < 2 || radix > 36) - { - NazaraError("Radix must be between 2 and 36"); - - if (ok) - *ok = false; - - return 0; - } - #endif - - static const char* symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - - str.Simplify(); - if (radix > 10) - str = str.ToUpper(); - - bool negative = str.StartsWith('-'); - - char* digit = &str[(negative) ? 1 : 0]; - unsigned long long total = 0; - do - { - if (*digit == ' ') - continue; - - total *= radix; - const char* c = std::strchr(symbols, *digit); - if (c && c-symbols < radix) - total += c-symbols; + ///TODO: Marquer comme constexpr en C++14 + if (value < objective) + return std::min(value + increment, objective); + else if (value > objective) + return std::max(value - increment, objective); else + return value; + } + + template + constexpr T Clamp(T value, T min, T max) + { + return std::max(std::min(value, max), min); + } + + template + T CountBits(T value) + { + // https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetKernighan + unsigned int count = 0; + while (value) { + value &= value - 1; + count++; + } + + return count; + } + + template + constexpr T NzDegreeToRadian(T degrees) + { + return degrees * T(M_PI/180.0); + } + + template + constexpr T FromDegrees(T degrees) + { + #if NAZARA_MATH_ANGLE_RADIAN + return NzDegreeToRadian(degrees); + #else + return degrees; + #endif + } + + template + constexpr T FromRadians(T radians) + { + #if NAZARA_MATH_ANGLE_RADIAN + return radians; + #else + return RadianToDegree(radians); + #endif + } + + inline unsigned int GetNearestPowerOfTwo(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) + x <<= 1; + + return x; + } + + inline unsigned int GetNumberLength(signed char number) + { + ///TODO: Marquer comme constexpr en C++14 + // Le standard définit le char comme étant codé sur un octet + static_assert(sizeof(number) == 1, "Signed char must be one byte-sized"); + + if (number >= 100) + return 3; + else if (number >= 10) + return 2; + else if (number >= 0) + return 1; + else if (number > -10) + return 2; + else if (number > -100) + return 3; + else + return 4; + } + + inline unsigned int GetNumberLength(unsigned char number) + { + ///TODO: Marquer comme constexpr en C++14 + // Le standard définit le char comme étant codé sur un octet + static_assert(sizeof(number) == 1, "Unsigned char must be one byte-sized"); + + if (number >= 100) + return 3; + else if (number >= 10) + return 2; + else + return 1; + } + + inline unsigned int GetNumberLength(int number) + { + if (number == 0) + return 1; + + return static_cast(std::log10(std::abs(number))) + (number < 0 ? 2 : 1); + } + + inline unsigned int GetNumberLength(unsigned int number) + { + if (number == 0) + return 1; + + return static_cast(std::log10(number))+1; + } + + inline unsigned int GetNumberLength(long long number) + { + if (number == 0) + return 1; + + return static_cast(std::log10(std::abs(number))) + (number < 0 ? 2 : 1); + } + + inline unsigned int GetNumberLength(unsigned long long number) + { + if (number == 0) + return 1; + + return static_cast(std::log10(number)) + 1; + } + + inline unsigned int GetNumberLength(float number, UInt8 precision) + { + // L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999) + return GetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point + } + + inline unsigned int GetNumberLength(double number, UInt8 precision) + { + // L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999) + return GetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point + } + + inline unsigned int GetNumberLength(long double number, UInt8 precision) + { + // L'imprécision des flottants nécessite un cast (log10(9.99999) = 0.99999) + return GetNumberLength(static_cast(number)) + precision + 1; // Plus un pour le point + } + + template + unsigned int IntegralLog2(T number) + { + // Proxy nécessaire pour éviter un problème de surcharge + return Detail::IntegralLog2(number); + } + + template + unsigned int IntegralLog2Pot(T pot) + { + return Detail::IntegralLog2Pot(pot); + } + + inline unsigned int IntegralPow(unsigned int base, unsigned int exponent) + { + ///TODO: Marquer comme constexpr en C++14 + unsigned int r = 1; + for (unsigned int i = 0; i < exponent; ++i) + r *= base; + + return r; + } + + template + T Lerp(T from, T to, T2 interpolation) + { + #ifdef NAZARA_DEBUG + if (interpolation < T2(0.0) || interpolation > T2(1.0)) + NazaraWarning("Interpolation should be in range [0..1] (Got " + String::Number(interpolation) + ')'); + #endif + + return from + interpolation * (to - from); + } + + template + T MultiplyAdd(T x, T y, T z) + { + return x*y + z; + } + + #ifdef FP_FAST_FMAF + template<> + inline float MultiplyAdd(float x, float y, float z) + { + return std::fmaf(x, y, z); + } + #endif + + #ifdef FP_FAST_FMA + template<> + inline double MultiplyAdd(double x, double y, double z) + { + return std::fma(x, y, z); + } + #endif + + #ifdef FP_FAST_FMAL + template<> + inline long double MultiplyAdd(long double x, long double y, long double z) + { + return std::fmal(x, y, z); + } + #endif + + template + T NormalizeAngle(T angle) + { + #if NAZARA_MATH_ANGLE_RADIAN + const T limit = T(M_PI); + #else + const T limit = T(180.0); + #endif + const T twoLimit = limit * T(2); + + angle = std::fmod(angle + limit, twoLimit); + if (angle < T(0)) + angle += twoLimit; + + return angle - limit; + } + + template + bool NumberEquals(T a, T b) + { + return NumberEquals(a, b, std::numeric_limits::epsilon()); + } + + template + bool NumberEquals(T a, T b, T maxDifference) + { + if (b > a) + std::swap(a, b); + + T diff = a - b; + return diff <= maxDifference; + } + + inline String NumberToString(long long number, UInt8 radix) + { + #if NAZARA_MATH_SAFE + if (radix < 2 || radix > 36) + { + NazaraError("Base must be between 2 and 36"); + return String(); + } + #endif + + if (number == 0) + return String('0'); + + static const char* symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + bool negative; + if (number < 0) + { + negative = true; + number = -number; + } + else + negative = false; + + String str; + str.Reserve(GetNumberLength(number)); // Prends en compte le signe négatif + + do + { + str.Append(symbols[number % radix]); + number /= radix; + } + while (number > 0); + + if (negative) + str.Append('-'); + + return str.Reverse(); + } + + template + T RadianToDegree(T radians) + { + return radians * T(180.0/M_PI); + } + + inline long long StringToNumber(String str, UInt8 radix, bool* ok) + { + #if NAZARA_MATH_SAFE + if (radix < 2 || radix > 36) + { + NazaraError("Radix must be between 2 and 36"); + if (ok) *ok = false; return 0; } + #endif + + static const char* symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + str.Simplify(); + if (radix > 10) + str = str.ToUpper(); + + bool negative = str.StartsWith('-'); + + char* digit = &str[(negative) ? 1 : 0]; + unsigned long long total = 0; + do + { + if (*digit == ' ') + continue; + + total *= radix; + const char* c = std::strchr(symbols, *digit); + if (c && c-symbols < radix) + total += c-symbols; + else + { + if (ok) + *ok = false; + + return 0; + } + } + while (*++digit); + + if (ok) + *ok = true; + + return (negative) ? -static_cast(total) : total; } - while (*++digit); - if (ok) - *ok = true; + template + constexpr T ToDegrees(T angle) + { + #if NAZARA_MATH_ANGLE_RADIAN + return RadianToDegree(angle); + #else + return angle; + #endif + } - 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); + template + constexpr T ToRadians(T angle) + { + #if NAZARA_MATH_ANGLE_RADIAN + return angle; + #else + return NzDegreeToRadian(angle); + } #endif } diff --git a/include/Nazara/Math/BoundingVolume.hpp b/include/Nazara/Math/BoundingVolume.hpp index 3f1a7837c..e0ca2f556 100644 --- a/include/Nazara/Math/BoundingVolume.hpp +++ b/include/Nazara/Math/BoundingVolume.hpp @@ -12,61 +12,64 @@ #include #include -template -class NzBoundingVolume +namespace Nz { - public: - NzBoundingVolume(); - NzBoundingVolume(nzExtend Extend); - NzBoundingVolume(T X, T Y, T Z, T Width, T Height, T Depth); - NzBoundingVolume(const NzBox& box); - NzBoundingVolume(const NzOrientedBox& orientedBox); - NzBoundingVolume(const NzVector3& vec1, const NzVector3& vec2); - template explicit NzBoundingVolume(const NzBoundingVolume& volume); - NzBoundingVolume(const NzBoundingVolume& volume) = default; - ~NzBoundingVolume() = default; + template + class BoundingVolume + { + public: + BoundingVolume(); + BoundingVolume(Extend Extend); + BoundingVolume(T X, T Y, T Z, T Width, T Height, T Depth); + BoundingVolume(const Box& box); + BoundingVolume(const OrientedBox& orientedBox); + BoundingVolume(const Vector3& vec1, const Vector3& vec2); + template explicit BoundingVolume(const BoundingVolume& volume); + BoundingVolume(const BoundingVolume& volume) = default; + ~BoundingVolume() = default; - bool IsFinite() const; - bool IsInfinite() const; - bool IsNull() const; + bool IsFinite() const; + bool IsInfinite() const; + bool IsNull() const; - NzBoundingVolume& MakeInfinite(); - NzBoundingVolume& MakeNull(); + BoundingVolume& MakeInfinite(); + BoundingVolume& MakeNull(); - NzBoundingVolume& Set(nzExtend Extend); - NzBoundingVolume& Set(T X, T Y, T Z, T Width, T Height, T Depth); - NzBoundingVolume& Set(const NzBoundingVolume& volume); - NzBoundingVolume& Set(const NzBox& box); - NzBoundingVolume& Set(const NzOrientedBox& orientedBox); - NzBoundingVolume& Set(const NzVector3& vec1, const NzVector3& vec2); - template NzBoundingVolume& Set(const NzBoundingVolume& volume); + BoundingVolume& Set(Extend Extend); + BoundingVolume& Set(T X, T Y, T Z, T Width, T Height, T Depth); + BoundingVolume& Set(const BoundingVolume& volume); + BoundingVolume& Set(const Box& box); + BoundingVolume& Set(const OrientedBox& orientedBox); + BoundingVolume& Set(const Vector3& vec1, const Vector3& vec2); + template BoundingVolume& Set(const BoundingVolume& volume); - NzString ToString() const; + String ToString() const; - void Update(const NzMatrix4& transformMatrix); - void Update(const NzVector3& translation); + void Update(const Matrix4& transformMatrix); + void Update(const Vector3& translation); - NzBoundingVolume operator*(T scalar) const; + BoundingVolume operator*(T scalar) const; - NzBoundingVolume& operator*=(T scalar); + BoundingVolume& operator*=(T scalar); - bool operator==(const NzBoundingVolume& volume) const; - bool operator!=(const NzBoundingVolume& volume) const; + bool operator==(const BoundingVolume& volume) const; + bool operator!=(const BoundingVolume& volume) const; - static NzBoundingVolume Infinite(); - static NzBoundingVolume Lerp(const NzBoundingVolume& from, const NzBoundingVolume& to, T interpolation); - static NzBoundingVolume Null(); + static BoundingVolume Infinite(); + static BoundingVolume Lerp(const BoundingVolume& from, const BoundingVolume& to, T interpolation); + static BoundingVolume Null(); - nzExtend extend; - NzBox aabb; - NzOrientedBox obb; -}; + Extend extend; + Box aabb; + OrientedBox obb; + }; + + typedef BoundingVolume BoundingVolumed; + typedef BoundingVolume BoundingVolumef; +} template -std::ostream& operator<<(std::ostream& out, const NzBoundingVolume& volume); - -typedef NzBoundingVolume NzBoundingVolumed; -typedef NzBoundingVolume NzBoundingVolumef; +std::ostream& operator<<(std::ostream& out, const Nz::BoundingVolume& volume); #include diff --git a/include/Nazara/Math/BoundingVolume.inl b/include/Nazara/Math/BoundingVolume.inl index 8117ee1b2..13b41a63e 100644 --- a/include/Nazara/Math/BoundingVolume.inl +++ b/include/Nazara/Math/BoundingVolume.inl @@ -11,315 +11,318 @@ #define F(a) static_cast(a) -template -NzBoundingVolume::NzBoundingVolume() : -extend(nzExtend_Null) +namespace Nz { -} - -template -NzBoundingVolume::NzBoundingVolume(nzExtend Extend) -{ - Set(Extend); -} - -template -NzBoundingVolume::NzBoundingVolume(T X, T Y, T Z, T Width, T Height, T Depth) -{ - Set(X, Y, Z, Width, Height, Depth); -} - -template -NzBoundingVolume::NzBoundingVolume(const NzBox& box) -{ - Set(box); -} - -template -NzBoundingVolume::NzBoundingVolume(const NzOrientedBox& orientedBox) -{ - Set(orientedBox); -} - -template -NzBoundingVolume::NzBoundingVolume(const NzVector3& vec1, const NzVector3& vec2) -{ - Set(vec1, vec2); -} - -template -template -NzBoundingVolume::NzBoundingVolume(const NzBoundingVolume& volume) -{ - Set(volume); -} - -template -bool NzBoundingVolume::IsFinite() const -{ - return extend == nzExtend_Finite; -} - -template -bool NzBoundingVolume::IsInfinite() const -{ - return extend == nzExtend_Infinite; -} - -template -bool NzBoundingVolume::IsNull() const -{ - return extend == nzExtend_Null; -} - -template -NzBoundingVolume& NzBoundingVolume::MakeInfinite() -{ - extend = nzExtend_Infinite; - - return *this; -} - -template -NzBoundingVolume& NzBoundingVolume::MakeNull() -{ - extend = nzExtend_Null; - - return *this; -} - -template -NzBoundingVolume& NzBoundingVolume::Set(nzExtend Extend) -{ - extend = Extend; - - return *this; -} - -template -NzBoundingVolume& NzBoundingVolume::Set(T X, T Y, T Z, T Width, T Height, T Depth) -{ - obb.Set(X, Y, Z, Width, Height, Depth); - extend = nzExtend_Finite; - - return *this; -} - -template -NzBoundingVolume& NzBoundingVolume::Set(const NzBoundingVolume& volume) -{ - obb.Set(volume.obb); // Seul l'OBB est importante pour la suite - extend = volume.extend; - - return *this; -} - -template -NzBoundingVolume& NzBoundingVolume::Set(const NzBox& box) -{ - obb.Set(box); - extend = nzExtend_Finite; - - return *this; -} - -template -NzBoundingVolume& NzBoundingVolume::Set(const NzOrientedBox& orientedBox) -{ - obb.Set(orientedBox); - extend = nzExtend_Finite; - - return *this; -} - -template -NzBoundingVolume& NzBoundingVolume::Set(const NzVector3& vec1, const NzVector3& vec2) -{ - obb.Set(vec1, vec2); - extend = nzExtend_Finite; - - return *this; -} - -template -template -NzBoundingVolume& NzBoundingVolume::Set(const NzBoundingVolume& volume) -{ - obb.Set(volume.obb); - extend = volume.extend; - - return *this; -} - -template -NzString NzBoundingVolume::ToString() const -{ - switch (extend) + template + BoundingVolume::BoundingVolume() : + extend(Extend_Null) { - case nzExtend_Finite: - return "BoundingVolume(localBox=" + obb.localBox.ToString() + ')'; - - case nzExtend_Infinite: - return "BoundingVolume(Infinite)"; - - case nzExtend_Null: - return "BoundingVolume(Null)"; } - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (0x" + NzString::Number(extend, 16) + ')'); - return "BoundingVolume(ERROR)"; -} - -template -void NzBoundingVolume::Update(const NzMatrix4& transformMatrix) -{ - obb.Update(transformMatrix); - - aabb.Set(obb(0), obb(1)); - for (unsigned int i = 2; i < 8; ++i) - aabb.ExtendTo(obb(i)); -} - -template -void NzBoundingVolume::Update(const NzVector3& translation) -{ - obb.Update(translation); - - aabb.Set(obb(0), obb(1)); - for (unsigned int i = 2; i < 8; ++i) - aabb.ExtendTo(obb(i)); -} - -template -NzBoundingVolume NzBoundingVolume::operator*(T scalar) const -{ - NzBoundingVolume volume(*this); - volume *= scalar; - - return volume; -} - -template -NzBoundingVolume& NzBoundingVolume::operator*=(T scalar) -{ - obb *= scalar; - - return *this; -} - -template -bool NzBoundingVolume::operator==(const NzBoundingVolume& volume) const -{ - if (extend == volume.extend) - if (extend == nzExtend_Finite) - return obb == volume.obb; - else - return true; - else - return false; -} - -template -bool NzBoundingVolume::operator!=(const NzBoundingVolume& volume) const -{ - return !operator==(volume); -} - -template -NzBoundingVolume NzBoundingVolume::Infinite() -{ - NzBoundingVolume volume; - volume.MakeInfinite(); - - return volume; -} - -template -NzBoundingVolume NzBoundingVolume::Lerp(const NzBoundingVolume& from, const NzBoundingVolume& to, T interpolation) -{ - #ifdef NAZARA_DEBUG - if (interpolation < F(0.0) || interpolation > F(1.0)) + template + BoundingVolume::BoundingVolume(Extend Extend) { - NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')'); - return Null(); + Set(Extend); } - #endif - if (NzNumberEquals(interpolation, F(0.0))) - return from; - - if (NzNumberEquals(interpolation, F(1.0))) - return to; - - switch (to.extend) + template + BoundingVolume::BoundingVolume(T X, T Y, T Z, T Width, T Height, T Depth) { - case nzExtend_Finite: + Set(X, Y, Z, Width, Height, Depth); + } + + template + BoundingVolume::BoundingVolume(const Box& box) + { + Set(box); + } + + template + BoundingVolume::BoundingVolume(const OrientedBox& orientedBox) + { + Set(orientedBox); + } + + template + BoundingVolume::BoundingVolume(const Vector3& vec1, const Vector3& vec2) + { + Set(vec1, vec2); + } + + template + template + BoundingVolume::BoundingVolume(const BoundingVolume& volume) + { + Set(volume); + } + + template + bool BoundingVolume::IsFinite() const + { + return extend == Extend_Finite; + } + + template + bool BoundingVolume::IsInfinite() const + { + return extend == Extend_Infinite; + } + + template + bool BoundingVolume::IsNull() const + { + return extend == Extend_Null; + } + + template + BoundingVolume& BoundingVolume::MakeInfinite() + { + extend = Extend_Infinite; + + return *this; + } + + template + BoundingVolume& BoundingVolume::MakeNull() + { + extend = Extend_Null; + + return *this; + } + + template + BoundingVolume& BoundingVolume::Set(Extend Extend) + { + extend = Extend; + + return *this; + } + + template + BoundingVolume& BoundingVolume::Set(T X, T Y, T Z, T Width, T Height, T Depth) + { + obb.Set(X, Y, Z, Width, Height, Depth); + extend = Extend_Finite; + + return *this; + } + + template + BoundingVolume& BoundingVolume::Set(const BoundingVolume& volume) + { + obb.Set(volume.obb); // Seul l'OBB est importante pour la suite + extend = volume.extend; + + return *this; + } + + template + BoundingVolume& BoundingVolume::Set(const Box& box) + { + obb.Set(box); + extend = Extend_Finite; + + return *this; + } + + template + BoundingVolume& BoundingVolume::Set(const OrientedBox& orientedBox) + { + obb.Set(orientedBox); + extend = Extend_Finite; + + return *this; + } + + template + BoundingVolume& BoundingVolume::Set(const Vector3& vec1, const Vector3& vec2) + { + obb.Set(vec1, vec2); + extend = Extend_Finite; + + return *this; + } + + template + template + BoundingVolume& BoundingVolume::Set(const BoundingVolume& volume) + { + obb.Set(volume.obb); + extend = volume.extend; + + return *this; + } + + template + String BoundingVolume::ToString() const + { + switch (extend) { - switch (from.extend) - { - case nzExtend_Finite: - { - NzBoundingVolume volume; - volume.Set(NzOrientedBox::Lerp(from.obb, to.obb, interpolation)); + case Extend_Finite: + return "BoundingVolume(localBox=" + obb.localBox.ToString() + ')'; - return volume; + case Extend_Infinite: + return "BoundingVolume(Infinite)"; + + case Extend_Null: + return "BoundingVolume(Null)"; + } + + // Si nous arrivons ici c'est que l'extend est invalide + NazaraError("Invalid extend type (0x" + String::Number(extend, 16) + ')'); + return "BoundingVolume(ERROR)"; + } + + template + void BoundingVolume::Update(const Matrix4& transformMatrix) + { + obb.Update(transformMatrix); + + aabb.Set(obb(0), obb(1)); + for (unsigned int i = 2; i < 8; ++i) + aabb.ExtendTo(obb(i)); + } + + template + void BoundingVolume::Update(const Vector3& translation) + { + obb.Update(translation); + + aabb.Set(obb(0), obb(1)); + for (unsigned int i = 2; i < 8; ++i) + aabb.ExtendTo(obb(i)); + } + + template + BoundingVolume BoundingVolume::operator*(T scalar) const + { + BoundingVolume volume(*this); + volume *= scalar; + + return volume; + } + + template + BoundingVolume& BoundingVolume::operator*=(T scalar) + { + obb *= scalar; + + return *this; + } + + template + bool BoundingVolume::operator==(const BoundingVolume& volume) const + { + if (extend == volume.extend) + if (extend == Extend_Finite) + return obb == volume.obb; + else + return true; + else + return false; + } + + template + bool BoundingVolume::operator!=(const BoundingVolume& volume) const + { + return !operator==(volume); + } + + template + BoundingVolume BoundingVolume::Infinite() + { + BoundingVolume volume; + volume.MakeInfinite(); + + return volume; + } + + template + BoundingVolume BoundingVolume::Lerp(const BoundingVolume& from, const BoundingVolume& to, T interpolation) + { + #ifdef NAZARA_DEBUG + if (interpolation < F(0.0) || interpolation > F(1.0)) + { + NazaraError("Interpolation must be in range [0..1] (Got " + String::Number(interpolation) + ')'); + return Null(); + } + #endif + + if (NumberEquals(interpolation, F(0.0))) + return from; + + if (NumberEquals(interpolation, F(1.0))) + return to; + + switch (to.extend) + { + case Extend_Finite: + { + switch (from.extend) + { + case Extend_Finite: + { + BoundingVolume volume; + volume.Set(OrientedBox::Lerp(from.obb, to.obb, interpolation)); + + return volume; + } + + case Extend_Infinite: + return Infinite(); + + case Extend_Null: + return from.obb * interpolation; } - case nzExtend_Infinite: - return Infinite(); - - case nzExtend_Null: - return from.obb * interpolation; + // Si nous arrivons ici c'est que l'extend est invalide + NazaraError("Invalid extend type (From) (0x" + String::Number(from.extend, 16) + ')'); + return Null(); } - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (From) (0x" + NzString::Number(from.extend, 16) + ')'); - return Null(); - } + case Extend_Infinite: + return Infinite(); // Un petit peu d'infini est infini quand même ;) - case nzExtend_Infinite: - return Infinite(); // Un petit peu d'infini est infini quand même ;) - - case nzExtend_Null: - { - switch (from.extend) + case Extend_Null: { - case nzExtend_Finite: - return from.obb * (F(1.0) - interpolation); + switch (from.extend) + { + case Extend_Finite: + return from.obb * (F(1.0) - interpolation); - case nzExtend_Infinite: - return Infinite(); + case Extend_Infinite: + return Infinite(); - case nzExtend_Null: - return Null(); + case Extend_Null: + return Null(); + } + + // Si nous arrivons ici c'est que l'extend est invalide + NazaraError("Invalid extend type (From) (0x" + String::Number(from.extend, 16) + ')'); + return Null(); } - - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (From) (0x" + NzString::Number(from.extend, 16) + ')'); - return Null(); } + + // Si nous arrivons ici c'est que l'extend est invalide + NazaraError("Invalid extend type (To) (0x" + String::Number(to.extend, 16) + ')'); + return Null(); } - // Si nous arrivons ici c'est que l'extend est invalide - NazaraError("Invalid extend type (To) (0x" + NzString::Number(to.extend, 16) + ')'); - return Null(); + template + BoundingVolume BoundingVolume::Null() + { + BoundingVolume volume; + volume.MakeNull(); + + return volume; + } + + template + std::ostream& operator<<(std::ostream& out, const BoundingVolume& volume) + { + out << volume.ToString(); + return out; } - -template -NzBoundingVolume NzBoundingVolume::Null() -{ - NzBoundingVolume volume; - volume.MakeNull(); - - return volume; -} - -template -std::ostream& operator<<(std::ostream& out, const NzBoundingVolume& volume) -{ - out << volume.ToString(); - return out; } #undef F diff --git a/include/Nazara/Math/Box.hpp b/include/Nazara/Math/Box.hpp index 6b5e5d565..158d7753c 100644 --- a/include/Nazara/Math/Box.hpp +++ b/include/Nazara/Math/Box.hpp @@ -14,89 +14,93 @@ #include #include -template -class NzBox +namespace Nz { - public: - NzBox() = default; - NzBox(T Width, T Height, T Depth); - NzBox(T X, T Y, T Z, T Width, T Height, T Depth); - NzBox(const T box[6]); - NzBox(const NzRect& rect); - NzBox(const NzVector3& lengths); - NzBox(const NzVector3& vec1, const NzVector3& vec2); - template explicit NzBox(const NzBox& box); - NzBox(const NzBox& box) = default; - ~NzBox() = default; + template + class Box + { + public: + Box() = default; + Box(T Width, T Height, T Depth); + Box(T X, T Y, T Z, T Width, T Height, T Depth); + Box(const T box[6]); + Box(const Rect& rect); + Box(const Vector3& lengths); + Box(const Vector3& vec1, const Vector3& vec2); + template explicit Box(const Box& box); + Box(const Box& box) = default; + ~Box() = default; - bool Contains(T X, T Y, T Z) const; - bool Contains(const NzBox& box) const; - bool Contains(const NzVector3& point) const; + bool Contains(T X, T Y, T Z) const; + bool Contains(const Box& box) const; + bool Contains(const Vector3& point) const; - NzBox& ExtendTo(T X, T Y, T Z); - NzBox& ExtendTo(const NzBox& box); - NzBox& ExtendTo(const NzVector3& point); + Box& ExtendTo(T X, T Y, T Z); + Box& ExtendTo(const Box& box); + Box& ExtendTo(const Vector3& point); - NzSphere GetBoundingSphere() const; - NzVector3 GetCorner(nzBoxCorner corner) const; - NzVector3 GetCenter() const; - NzVector3 GetLengths() const; - NzVector3 GetMaximum() const; - NzVector3 GetMinimum() const; - NzVector3 GetNegativeVertex(const NzVector3& normal) const; - NzVector3 GetPosition() const; - NzVector3 GetPositiveVertex(const NzVector3& normal) const; - T GetRadius() const; - NzSphere GetSquaredBoundingSphere() const; - T GetSquaredRadius() const; + Sphere GetBoundingSphere() const; + Vector3 GetCorner(BoxCorner corner) const; + Vector3 GetCenter() const; + Vector3 GetLengths() const; + Vector3 GetMaximum() const; + Vector3 GetMinimum() const; + Vector3 GetNegativeVertex(const Vector3& normal) const; + Vector3 GetPosition() const; + Vector3 GetPositiveVertex(const Vector3& normal) const; + T GetRadius() const; + Sphere GetSquaredBoundingSphere() const; + T GetSquaredRadius() const; - bool Intersect(const NzBox& box, NzBox* intersection = nullptr) const; + bool Intersect(const Box& box, Box* intersection = nullptr) const; - bool IsValid() const; + bool IsValid() const; - NzBox& MakeZero(); + Box& MakeZero(); - NzBox& Set(T Width, T Height, T Depth); - NzBox& Set(T X, T Y, T Z, T Width, T Height, T Depth); - NzBox& Set(const T box[6]); - NzBox& Set(const NzBox& box); - NzBox& Set(const NzRect& rect); - NzBox& Set(const NzVector3& lengths); - NzBox& Set(const NzVector3& vec1, const NzVector3& vec2); - template NzBox& Set(const NzBox& box); + Box& Set(T Width, T Height, T Depth); + Box& Set(T X, T Y, T Z, T Width, T Height, T Depth); + Box& Set(const T box[6]); + Box& Set(const Box& box); + Box& Set(const Rect& rect); + Box& Set(const Vector3& lengths); + Box& Set(const Vector3& vec1, const Vector3& vec2); + template Box& Set(const Box& box); - NzString ToString() const; + String ToString() const; - NzBox& Transform(const NzMatrix4& matrix, bool applyTranslation = true); - NzBox& Translate(const NzVector3& translation); + Box& Transform(const Matrix4& matrix, bool applyTranslation = true); + Box& Translate(const Vector3& translation); - T& operator[](unsigned int i); - T operator[](unsigned int i) const; + T& operator[](unsigned int i); + T operator[](unsigned int i) const; - NzBox operator*(T scalar) const; - NzBox operator*(const NzVector3& vec) const; + Box operator*(T scalar) const; + Box operator*(const Vector3& vec) const; - NzBox& operator*=(T scalar); - NzBox& operator*=(const NzVector3& vec); + Box& operator*=(T scalar); + Box& operator*=(const Vector3& vec); - bool operator==(const NzBox& box) const; - bool operator!=(const NzBox& box) const; + bool operator==(const Box& box) const; + bool operator!=(const Box& box) const; - static NzBox Lerp(const NzBox& from, const NzBox& to, T interpolation); - static NzBox Zero(); + static Box Lerp(const Box& from, const Box& to, T interpolation); + static Box Zero(); - T x, y, z, width, height, depth; -}; + T x, y, z, width, height, depth; + }; + + typedef Box Boxd; + typedef Box Boxf; + typedef Box Boxi; + typedef Box Boxui; + typedef Box Boxi32; + typedef Box Boxui32; +} template -std::ostream& operator<<(std::ostream& out, const NzBox& box); +std::ostream& operator<<(std::ostream& out, const Nz::Box& box); -typedef NzBox NzBoxd; -typedef NzBox NzBoxf; -typedef NzBox NzBoxi; -typedef NzBox NzBoxui; -typedef NzBox NzBoxi32; -typedef NzBox NzBoxui32; #include diff --git a/include/Nazara/Math/Box.inl b/include/Nazara/Math/Box.inl index 19da1ef63..a39f867da 100644 --- a/include/Nazara/Math/Box.inl +++ b/include/Nazara/Math/Box.inl @@ -10,524 +10,527 @@ #define F(a) static_cast(a) -template -NzBox::NzBox(T Width, T Height, T Depth) +namespace Nz { - Set(Width, Height, Depth); -} - -template -NzBox::NzBox(T X, T Y, T Z, T Width, T Height, T Depth) -{ - Set(X, Y, Z, Width, Height, Depth); -} - -template -NzBox::NzBox(const NzRect& rect) -{ - Set(rect); -} - -template -NzBox::NzBox(const NzVector3& lengths) -{ - Set(lengths); -} - -template -NzBox::NzBox(const NzVector3& vec1, const NzVector3& vec2) -{ - Set(vec1, vec2); -} - -template -NzBox::NzBox(const T vec[6]) -{ - Set(vec); -} - -template -template -NzBox::NzBox(const NzBox& box) -{ - Set(box); -} - -template -bool NzBox::Contains(T X, T Y, T Z) const -{ - return X >= x && X <= x+width && - Y >= y && Y <= y+height && - Z >= z && Z <= z+depth; -} - -template -bool NzBox::Contains(const NzBox& box) const -{ - return Contains(box.x, box.y, box.z) && - Contains(box.x + box.width, box.y + box.height, box.z + box.depth); -} - -template -bool NzBox::Contains(const NzVector3& point) const -{ - return Contains(point.x, point.y, point.z); -} - -template -NzBox& NzBox::ExtendTo(T X, T Y, T Z) -{ - width = std::max(x + width, X); - height = std::max(y + height, Y); - depth = std::max(z + depth, Z); - - x = std::min(x, X); - y = std::min(y, Y); - z = std::min(z, Z); - - width -= x; - height -= y; - depth -= z; - - return *this; -} - -template -NzBox& NzBox::ExtendTo(const NzBox& box) -{ - width = std::max(x + width, box.x + box.width); - height = std::max(y + height, box.y + box.height); - depth = std::max(z + depth, box.z + box.depth); - - x = std::min(x, box.x); - y = std::min(y, box.y); - z = std::min(z, box.z); - - width -= x; - height -= y; - depth -= z; - - return *this; -} - -template -NzBox& NzBox::ExtendTo(const NzVector3& point) -{ - return ExtendTo(point.x, point.y, point.z); -} - -template -NzVector3 NzBox::GetCorner(nzBoxCorner corner) const -{ - switch (corner) + template + Box::Box(T Width, T Height, T Depth) { - case nzBoxCorner_FarLeftBottom: - return NzVector3(x, y, z); - - case nzBoxCorner_FarLeftTop: - return NzVector3(x, y + height, z); - - case nzBoxCorner_FarRightBottom: - return NzVector3(x + width, y, z); - - case nzBoxCorner_FarRightTop: - return NzVector3(x + width, y + height, z); - - case nzBoxCorner_NearLeftBottom: - return NzVector3(x, y, z + depth); - - case nzBoxCorner_NearLeftTop: - return NzVector3(x, y + height, z + depth); - - case nzBoxCorner_NearRightBottom: - return NzVector3(x + width, y, z + depth); - - case nzBoxCorner_NearRightTop: - return NzVector3(x + width, y + height, z + depth); + Set(Width, Height, Depth); } - NazaraError("Corner not handled (0x" + NzString::Number(corner, 16) + ')'); - return NzVector3(); -} - -template -NzSphere NzBox::GetBoundingSphere() const -{ - return NzSphere(GetCenter(), GetRadius()); -} - -template -NzVector3 NzBox::GetCenter() const -{ - return GetPosition() + GetLengths()/F(2.0); -} - -template -NzVector3 NzBox::GetLengths() const -{ - return NzVector3(width, height, depth); -} - -template -NzVector3 NzBox::GetMaximum() const -{ - return GetPosition() + GetLengths(); -} - -template -NzVector3 NzBox::GetMinimum() const -{ - ///DOC: Alias de GetPosition() - return GetPosition(); -} - -template -NzVector3 NzBox::GetNegativeVertex(const NzVector3& normal) const -{ - NzVector3 neg(GetPosition()); - - if (normal.x < F(0.0)) - neg.x += width; - - if (normal.y < F(0.0)) - neg.y += height; - - if (normal.z < F(0.0)) - neg.z += depth; - - return neg; -} - -template -NzVector3 NzBox::GetPosition() const -{ - return NzVector3(x, y, z); -} - -template -NzVector3 NzBox::GetPositiveVertex(const NzVector3& normal) const -{ - NzVector3 pos(GetPosition()); - - if (normal.x > F(0.0)) - pos.x += width; - - if (normal.y > F(0.0)) - pos.y += height; - - if (normal.z > F(0.0)) - pos.z += depth; - - return pos; -} - -template -T NzBox::GetRadius() const -{ - return std::sqrt(GetSquaredRadius()); -} - -template -NzSphere NzBox::GetSquaredBoundingSphere() const -{ - return NzSphere(GetCenter(), GetSquaredRadius()); -} - -template -T NzBox::GetSquaredRadius() const -{ - NzVector3 size(GetLengths()); - size /= F(2.0); // La taille étant relative à la position (minimum) de la boite et non pas à son centre - - return size.GetSquaredLength(); -} - -template -bool NzBox::Intersect(const NzBox& box, NzBox* intersection) const -{ - T left = std::max(x, box.x); - T right = std::min(x + width, box.x + box.width); - if (left >= right) - return false; - - T top = std::max(y, box.y); - T bottom = std::min(y + height, box.y + box.height); - if (top >= bottom) - return false; - - T up = std::max(z, box.z); - T down = std::min(z + depth, box.z + box.depth); - if (up >= down) - return false; - - if (intersection) + template + Box::Box(T X, T Y, T Z, T Width, T Height, T Depth) { - intersection->x = left; - intersection->y = top; - intersection->z = up; - intersection->width = right - left; - intersection->height = bottom - top; - intersection->depth = down - up; + Set(X, Y, Z, Width, Height, Depth); } - return true; -} - -template -bool NzBox::IsValid() const -{ - return width > F(0.0) && height > F(0.0) && depth > F(0.0); -} - -template -NzBox& NzBox::MakeZero() -{ - x = F(0.0); - y = F(0.0); - z = F(0.0); - width = F(0.0); - height = F(0.0); - depth = F(0.0); - - return *this; -} - -template -NzBox& NzBox::Set(T Width, T Height, T Depth) -{ - x = F(0.0); - y = F(0.0); - z = F(0.0); - width = Width; - height = Height; - depth = Depth; - - return *this; -} - -template -NzBox& NzBox::Set(T X, T Y, T Z, T Width, T Height, T Depth) -{ - x = X; - y = Y; - z = Z; - width = Width; - height = Height; - depth = Depth; - - return *this; -} - -template -NzBox& NzBox::Set(const T box[6]) -{ - x = box[0]; - y = box[1]; - z = box[2]; - width = box[3]; - height = box[4]; - depth = box[5]; - - return *this; -} - -template -NzBox& NzBox::Set(const NzBox& box) -{ - std::memcpy(this, &box, sizeof(NzBox)); - - return *this; -} - -template -NzBox& NzBox::Set(const NzRect& rect) -{ - x = rect.x; - y = rect.y; - z = F(0.0); - width = rect.width; - height = rect.height; - depth = F(1.0); - - return *this; -} - -template -NzBox& NzBox::Set(const NzVector3& lengths) -{ - return Set(lengths.x, lengths.y, lengths.z); -} - -template -NzBox& NzBox::Set(const NzVector3& vec1, const NzVector3& vec2) -{ - x = std::min(vec1.x, vec2.x); - y = std::min(vec1.y, vec2.y); - z = std::min(vec1.z, vec2.z); - width = (vec2.x > vec1.x) ? vec2.x-vec1.x : vec1.x-vec2.x; - height = (vec2.y > vec1.y) ? vec2.y-vec1.y : vec1.y-vec2.y; - depth = (vec2.z > vec1.z) ? vec2.z-vec1.z : vec1.z-vec2.z; - - return *this; -} - -template -template -NzBox& NzBox::Set(const NzBox& box) -{ - x = F(box.x); - y = F(box.y); - z = F(box.z); - width = F(box.width); - height = F(box.height); - depth = F(box.depth); - - return *this; -} - -template -NzString NzBox::ToString() const -{ - NzStringStream ss; - - return ss << "Box(" << x << ", " << y << ", " << z << ", " << width << ", " << height << ", " << depth << ')'; -} - -template -NzBox& NzBox::Transform(const NzMatrix4& matrix, bool applyTranslation) -{ - NzVector3 center = matrix.Transform(GetCenter(), (applyTranslation) ? F(1.0) : F(0.0)); // Valeur multipliant la translation - NzVector3 halfSize = GetLengths()/F(2.0); - - halfSize.Set(std::abs(matrix(0,0))*halfSize.x + std::abs(matrix(1,0))*halfSize.y + std::abs(matrix(2,0))*halfSize.z, - std::abs(matrix(0,1))*halfSize.x + std::abs(matrix(1,1))*halfSize.y + std::abs(matrix(2,1))*halfSize.z, - std::abs(matrix(0,2))*halfSize.x + std::abs(matrix(1,2))*halfSize.y + std::abs(matrix(2,2))*halfSize.z); - - return Set(center - halfSize, center + halfSize); -} - -template -NzBox& NzBox::Translate(const NzVector3& translation) -{ - x += translation.x; - y += translation.y; - z += translation.z; - - return *this; -} - -template -T& NzBox::operator[](unsigned int i) -{ - #if NAZARA_MATH_SAFE - if (i >= 6) + template + Box::Box(const Rect& rect) { - NzStringStream ss; - ss << "Index out of range: (" << i << " >= 6)"; - - NazaraError(ss); - throw std::domain_error(ss.ToString()); + Set(rect); } - #endif - return *(&x+i); -} - -template -T NzBox::operator[](unsigned int i) const -{ - #if NAZARA_MATH_SAFE - if (i >= 6) + template + Box::Box(const Vector3& lengths) { - NzStringStream ss; - ss << "Index out of range: (" << i << " >= 6)"; - - NazaraError(ss); - throw std::domain_error(ss.ToString()); + Set(lengths); } - #endif - return *(&x+i); -} - -template -NzBox NzBox::operator*(T scalar) const -{ - return NzBox(x, y, z, width*scalar, height*scalar, depth*scalar); -} - -template -NzBox NzBox::operator*(const NzVector3& vec) const -{ - return NzBox(x, y, z, width*vec.x, height*vec.y, depth*vec.z); -} - -template -NzBox& NzBox::operator*=(T scalar) -{ - width *= scalar; - height *= scalar; - depth *= scalar; - - return *this; -} - -template -NzBox& NzBox::operator*=(const NzVector3& vec) -{ - width *= vec.x; - height *= vec.y; - depth *= vec.z; - - return *this; -} - -template -bool NzBox::operator==(const NzBox& box) const -{ - return NzNumberEquals(x, box.x) && NzNumberEquals(y, box.y) && NzNumberEquals(z, box.z) && - NzNumberEquals(width, box.width) && NzNumberEquals(height, box.height) && NzNumberEquals(depth, box.depth); -} - -template -bool NzBox::operator!=(const NzBox& box) const -{ - return !operator==(box); -} - -template -NzBox NzBox::Lerp(const NzBox& from, const NzBox& to, T interpolation) -{ - #ifdef NAZARA_DEBUG - if (interpolation < F(0.0) || interpolation > F(1.0)) + template + Box::Box(const Vector3& vec1, const Vector3& vec2) { - NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')'); - return Zero(); + Set(vec1, vec2); } - #endif - NzBox box; - box.x = NzLerp(from.x, to.x, interpolation); - box.y = NzLerp(from.y, to.y, interpolation); - box.z = NzLerp(from.z, to.z, interpolation); - box.width = NzLerp(from.width, to.width, interpolation); - box.height = NzLerp(from.height, to.height, interpolation); - box.depth = NzLerp(from.depth, to.depth, interpolation); + template + Box::Box(const T vec[6]) + { + Set(vec); + } - return box; + template + template + Box::Box(const Box& box) + { + Set(box); + } + + template + bool Box::Contains(T X, T Y, T Z) const + { + return X >= x && X <= x+width && + Y >= y && Y <= y+height && + Z >= z && Z <= z+depth; + } + + template + bool Box::Contains(const Box& box) const + { + return Contains(box.x, box.y, box.z) && + Contains(box.x + box.width, box.y + box.height, box.z + box.depth); + } + + template + bool Box::Contains(const Vector3& point) const + { + return Contains(point.x, point.y, point.z); + } + + template + Box& Box::ExtendTo(T X, T Y, T Z) + { + width = std::max(x + width, X); + height = std::max(y + height, Y); + depth = std::max(z + depth, Z); + + x = std::min(x, X); + y = std::min(y, Y); + z = std::min(z, Z); + + width -= x; + height -= y; + depth -= z; + + return *this; + } + + template + Box& Box::ExtendTo(const Box& box) + { + width = std::max(x + width, box.x + box.width); + height = std::max(y + height, box.y + box.height); + depth = std::max(z + depth, box.z + box.depth); + + x = std::min(x, box.x); + y = std::min(y, box.y); + z = std::min(z, box.z); + + width -= x; + height -= y; + depth -= z; + + return *this; + } + + template + Box& Box::ExtendTo(const Vector3& point) + { + return ExtendTo(point.x, point.y, point.z); + } + + template + Vector3 Box::GetCorner(BoxCorner corner) const + { + switch (corner) + { + case BoxCorner_FarLeftBottom: + return Vector3(x, y, z); + + case BoxCorner_FarLeftTop: + return Vector3(x, y + height, z); + + case BoxCorner_FarRightBottom: + return Vector3(x + width, y, z); + + case BoxCorner_FarRightTop: + return Vector3(x + width, y + height, z); + + case BoxCorner_NearLeftBottom: + return Vector3(x, y, z + depth); + + case BoxCorner_NearLeftTop: + return Vector3(x, y + height, z + depth); + + case BoxCorner_NearRightBottom: + return Vector3(x + width, y, z + depth); + + case BoxCorner_NearRightTop: + return Vector3(x + width, y + height, z + depth); + } + + NazaraError("Corner not handled (0x" + String::Number(corner, 16) + ')'); + return Vector3(); + } + + template + Sphere Box::GetBoundingSphere() const + { + return Sphere(GetCenter(), GetRadius()); + } + + template + Vector3 Box::GetCenter() const + { + return GetPosition() + GetLengths()/F(2.0); + } + + template + Vector3 Box::GetLengths() const + { + return Vector3(width, height, depth); + } + + template + Vector3 Box::GetMaximum() const + { + return GetPosition() + GetLengths(); + } + + template + Vector3 Box::GetMinimum() const + { + ///DOC: Alias de GetPosition() + return GetPosition(); + } + + template + Vector3 Box::GetNegativeVertex(const Vector3& normal) const + { + Vector3 neg(GetPosition()); + + if (normal.x < F(0.0)) + neg.x += width; + + if (normal.y < F(0.0)) + neg.y += height; + + if (normal.z < F(0.0)) + neg.z += depth; + + return neg; + } + + template + Vector3 Box::GetPosition() const + { + return Vector3(x, y, z); + } + + template + Vector3 Box::GetPositiveVertex(const Vector3& normal) const + { + Vector3 pos(GetPosition()); + + if (normal.x > F(0.0)) + pos.x += width; + + if (normal.y > F(0.0)) + pos.y += height; + + if (normal.z > F(0.0)) + pos.z += depth; + + return pos; + } + + template + T Box::GetRadius() const + { + return std::sqrt(GetSquaredRadius()); + } + + template + Sphere Box::GetSquaredBoundingSphere() const + { + return Sphere(GetCenter(), GetSquaredRadius()); + } + + template + T Box::GetSquaredRadius() const + { + Vector3 size(GetLengths()); + size /= F(2.0); // La taille étant relative à la position (minimum) de la boite et non pas à son centre + + return size.GetSquaredLength(); + } + + template + bool Box::Intersect(const Box& box, Box* intersection) const + { + T left = std::max(x, box.x); + T right = std::min(x + width, box.x + box.width); + if (left >= right) + return false; + + T top = std::max(y, box.y); + T bottom = std::min(y + height, box.y + box.height); + if (top >= bottom) + return false; + + T up = std::max(z, box.z); + T down = std::min(z + depth, box.z + box.depth); + if (up >= down) + return false; + + if (intersection) + { + intersection->x = left; + intersection->y = top; + intersection->z = up; + intersection->width = right - left; + intersection->height = bottom - top; + intersection->depth = down - up; + } + + return true; + } + + template + bool Box::IsValid() const + { + return width > F(0.0) && height > F(0.0) && depth > F(0.0); + } + + template + Box& Box::MakeZero() + { + x = F(0.0); + y = F(0.0); + z = F(0.0); + width = F(0.0); + height = F(0.0); + depth = F(0.0); + + return *this; + } + + template + Box& Box::Set(T Width, T Height, T Depth) + { + x = F(0.0); + y = F(0.0); + z = F(0.0); + width = Width; + height = Height; + depth = Depth; + + return *this; + } + + template + Box& Box::Set(T X, T Y, T Z, T Width, T Height, T Depth) + { + x = X; + y = Y; + z = Z; + width = Width; + height = Height; + depth = Depth; + + return *this; + } + + template + Box& Box::Set(const T box[6]) + { + x = box[0]; + y = box[1]; + z = box[2]; + width = box[3]; + height = box[4]; + depth = box[5]; + + return *this; + } + + template + Box& Box::Set(const Box& box) + { + std::memcpy(this, &box, sizeof(Box)); + + return *this; + } + + template + Box& Box::Set(const Rect& rect) + { + x = rect.x; + y = rect.y; + z = F(0.0); + width = rect.width; + height = rect.height; + depth = F(1.0); + + return *this; + } + + template + Box& Box::Set(const Vector3& lengths) + { + return Set(lengths.x, lengths.y, lengths.z); + } + + template + Box& Box::Set(const Vector3& vec1, const Vector3& vec2) + { + x = std::min(vec1.x, vec2.x); + y = std::min(vec1.y, vec2.y); + z = std::min(vec1.z, vec2.z); + width = (vec2.x > vec1.x) ? vec2.x-vec1.x : vec1.x-vec2.x; + height = (vec2.y > vec1.y) ? vec2.y-vec1.y : vec1.y-vec2.y; + depth = (vec2.z > vec1.z) ? vec2.z-vec1.z : vec1.z-vec2.z; + + return *this; + } + + template + template + Box& Box::Set(const Box& box) + { + x = F(box.x); + y = F(box.y); + z = F(box.z); + width = F(box.width); + height = F(box.height); + depth = F(box.depth); + + return *this; + } + + template + String Box::ToString() const + { + StringStream ss; + + return ss << "Box(" << x << ", " << y << ", " << z << ", " << width << ", " << height << ", " << depth << ')'; + } + + template + Box& Box::Transform(const Matrix4& matrix, bool applyTranslation) + { + Vector3 center = matrix.Transform(GetCenter(), (applyTranslation) ? F(1.0) : F(0.0)); // Valeur multipliant la translation + Vector3 halfSize = GetLengths()/F(2.0); + + halfSize.Set(std::abs(matrix(0,0))*halfSize.x + std::abs(matrix(1,0))*halfSize.y + std::abs(matrix(2,0))*halfSize.z, + std::abs(matrix(0,1))*halfSize.x + std::abs(matrix(1,1))*halfSize.y + std::abs(matrix(2,1))*halfSize.z, + std::abs(matrix(0,2))*halfSize.x + std::abs(matrix(1,2))*halfSize.y + std::abs(matrix(2,2))*halfSize.z); + + return Set(center - halfSize, center + halfSize); + } + + template + Box& Box::Translate(const Vector3& translation) + { + x += translation.x; + y += translation.y; + z += translation.z; + + return *this; + } + + template + T& Box::operator[](unsigned int i) + { + #if NAZARA_MATH_SAFE + if (i >= 6) + { + StringStream ss; + ss << "Index out of range: (" << i << " >= 6)"; + + NazaraError(ss); + throw std::domain_error(ss.ToString()); + } + #endif + + return *(&x+i); + } + + template + T Box::operator[](unsigned int i) const + { + #if NAZARA_MATH_SAFE + if (i >= 6) + { + StringStream ss; + ss << "Index out of range: (" << i << " >= 6)"; + + NazaraError(ss); + throw std::domain_error(ss.ToString()); + } + #endif + + return *(&x+i); + } + + template + Box Box::operator*(T scalar) const + { + return Box(x, y, z, width*scalar, height*scalar, depth*scalar); + } + + template + Box Box::operator*(const Vector3& vec) const + { + return Box(x, y, z, width*vec.x, height*vec.y, depth*vec.z); + } + + template + Box& Box::operator*=(T scalar) + { + width *= scalar; + height *= scalar; + depth *= scalar; + + return *this; + } + + template + Box& Box::operator*=(const Vector3& vec) + { + width *= vec.x; + height *= vec.y; + depth *= vec.z; + + return *this; + } + + template + bool Box::operator==(const Box& box) const + { + return NumberEquals(x, box.x) && NumberEquals(y, box.y) && NumberEquals(z, box.z) && + NumberEquals(width, box.width) && NumberEquals(height, box.height) && NumberEquals(depth, box.depth); + } + + template + bool Box::operator!=(const Box& box) const + { + return !operator==(box); + } + + template + Box Box::Lerp(const Box& from, const Box& to, T interpolation) + { + #ifdef NAZARA_DEBUG + if (interpolation < F(0.0) || interpolation > F(1.0)) + { + NazaraError("Interpolation must be in range [0..1] (Got " + String::Number(interpolation) + ')'); + return Zero(); + } + #endif + + Box box; + box.x = Nz::Lerp(from.x, to.x, interpolation); + box.y = Nz::Lerp(from.y, to.y, interpolation); + box.z = Nz::Lerp(from.z, to.z, interpolation); + box.width = Nz::Lerp(from.width, to.width, interpolation); + box.height = Nz::Lerp(from.height, to.height, interpolation); + box.depth = Nz::Lerp(from.depth, to.depth, interpolation); + + return box; + } + + template + Box Box::Zero() + { + Box box; + box.MakeZero(); + + return box; + } } template -NzBox NzBox::Zero() -{ - NzBox box; - box.MakeZero(); - - return box; -} - -template -std::ostream& operator<<(std::ostream& out, const NzBox& box) +std::ostream& operator<<(std::ostream& out, const Nz::Box& box) { return out << box.ToString(); } diff --git a/include/Nazara/Math/Enums.hpp b/include/Nazara/Math/Enums.hpp index 496615b9e..76649906f 100644 --- a/include/Nazara/Math/Enums.hpp +++ b/include/Nazara/Math/Enums.hpp @@ -7,58 +7,61 @@ #ifndef NAZARA_ENUMS_MATH_HPP #define NAZARA_ENUMS_MATH_HPP -enum nzBoxCorner +namespace Nz { - nzBoxCorner_FarLeftBottom, - nzBoxCorner_FarLeftTop, - nzBoxCorner_FarRightBottom, - nzBoxCorner_FarRightTop, - nzBoxCorner_NearLeftBottom, - nzBoxCorner_NearLeftTop, - nzBoxCorner_NearRightBottom, - nzBoxCorner_NearRightTop, + enum BoxCorner + { + BoxCorner_FarLeftBottom, + BoxCorner_FarLeftTop, + BoxCorner_FarRightBottom, + BoxCorner_FarRightTop, + BoxCorner_NearLeftBottom, + BoxCorner_NearLeftTop, + BoxCorner_NearRightBottom, + BoxCorner_NearRightTop, - nzBoxCorner_Max = nzBoxCorner_NearRightTop -}; + BoxCorner_Max = BoxCorner_NearRightTop + }; -enum nzExtend -{ - nzExtend_Finite, - nzExtend_Infinite, - nzExtend_Null, + enum Extend + { + Extend_Finite, + Extend_Infinite, + Extend_Null, - nzExtend_Max = nzExtend_Null -}; + Extend_Max = Extend_Null + }; -enum nzFrustumPlane -{ - nzFrustumPlane_Bottom, - nzFrustumPlane_Far, - nzFrustumPlane_Left, - nzFrustumPlane_Near, - nzFrustumPlane_Right, - nzFrustumPlane_Top, + enum FrustumPlane + { + FrustumPlane_Bottom, + FrustumPlane_Far, + FrustumPlane_Left, + FrustumPlane_Near, + FrustumPlane_Right, + FrustumPlane_Top, - nzFrustumPlane_Max = nzFrustumPlane_Top -}; + FrustumPlane_Max = FrustumPlane_Top + }; -enum nzIntersectionSide -{ - nzIntersectionSide_Inside, - nzIntersectionSide_Intersecting, - nzIntersectionSide_Outside, + enum IntersectionSide + { + IntersectionSide_Inside, + IntersectionSide_Intersecting, + IntersectionSide_Outside, - nzIntersectionSide_Max = nzIntersectionSide_Outside -}; + IntersectionSide_Max = IntersectionSide_Outside + }; -enum nzRectCorner -{ - nzRectCorner_LeftBottom, - nzRectCorner_LeftTop, - nzRectCorner_RightBottom, - nzRectCorner_RightTop, + enum RectCorner + { + RectCorner_LeftBottom, + RectCorner_LeftTop, + RectCorner_RightBottom, + RectCorner_RightTop, - nzRectCorner_Max = nzRectCorner_RightTop -}; + RectCorner_Max = RectCorner_RightTop + }; +} #endif // NAZARA_ENUMS_MATH_HPP diff --git a/include/Nazara/Math/EulerAngles.hpp b/include/Nazara/Math/EulerAngles.hpp index 41030d7be..d323fe641 100644 --- a/include/Nazara/Math/EulerAngles.hpp +++ b/include/Nazara/Math/EulerAngles.hpp @@ -11,55 +11,60 @@ #include #include -template class NzEulerAngles +namespace Nz { - public: - NzEulerAngles() = default; - NzEulerAngles(T P, T Y, T R); - NzEulerAngles(const T angles[3]); - //NzEulerAngles(const NzMatrix3& mat); - NzEulerAngles(const NzQuaternion& quat); - template explicit NzEulerAngles(const NzEulerAngles& angles); - NzEulerAngles(const NzEulerAngles& angles) = default; - ~NzEulerAngles() = default; + template + class EulerAngles + { + public: + EulerAngles() = default; + EulerAngles(T P, T Y, T R); + EulerAngles(const T angles[3]); + //EulerAngles(const Matrix3& mat); + EulerAngles(const Quaternion& quat); + template explicit EulerAngles(const EulerAngles& angles); + EulerAngles(const EulerAngles& angles) = default; + ~EulerAngles() = default; - void MakeZero(); + void MakeZero(); - void Normalize(); + void Normalize(); - void Set(T P, T Y, T R); - void Set(const T angles[3]); - void Set(const NzEulerAngles& angles); - //void Set(const NzMatrix3& mat); - void Set(const NzQuaternion& quat); - template void Set(const NzEulerAngles& angles); + void Set(T P, T Y, T R); + void Set(const T angles[3]); + void Set(const EulerAngles& angles); + //void Set(const Matrix3& mat); + void Set(const Quaternion& quat); + template void Set(const EulerAngles& angles); - //NzMatrix3 ToRotationMatrix() const; - NzQuaternion ToQuaternion() const; - NzString ToString() const; + //Matrix3 ToRotationMatrix() const; + Quaternion ToQuaternion() const; + String ToString() const; - NzEulerAngles operator+(const NzEulerAngles& angles) const; - NzEulerAngles operator-(const NzEulerAngles& angles) const; - /*NzEulerAngles operator*(const NzEulerAngles& angles) const; - NzEulerAngles operator/(const NzEulerAngles& angles) const;*/ + EulerAngles operator+(const EulerAngles& angles) const; + EulerAngles operator-(const EulerAngles& angles) const; + /*EulerAngles operator*(const EulerAngles& angles) const; + EulerAngles operator/(const EulerAngles& angles) const;*/ - NzEulerAngles& operator+=(const NzEulerAngles& angles); - NzEulerAngles& operator-=(const NzEulerAngles& angles); - /*NzEulerAngles operator*=(const NzEulerAngles& angles); - NzEulerAngles operator/=(const NzEulerAngles& angles);*/ + EulerAngles& operator+=(const EulerAngles& angles); + EulerAngles& operator-=(const EulerAngles& angles); + /*EulerAngles operator*=(const EulerAngles& angles); + EulerAngles operator/=(const EulerAngles& angles);*/ - bool operator==(const NzEulerAngles& angles) const; - bool operator!=(const NzEulerAngles& angles) const; + bool operator==(const EulerAngles& angles) const; + bool operator!=(const EulerAngles& angles) const; - static NzEulerAngles Zero(); + static EulerAngles Zero(); - T pitch, yaw, roll; -}; + T pitch, yaw, roll; + }; -template std::ostream& operator<<(std::ostream& out, const NzEulerAngles& angles); + typedef EulerAngles EulerAnglesd; + typedef EulerAngles EulerAnglesf; +} + +template std::ostream& operator<<(std::ostream& out, const Nz::EulerAngles& angles); -typedef NzEulerAngles NzEulerAnglesd; -typedef NzEulerAngles NzEulerAnglesf; #include diff --git a/include/Nazara/Math/EulerAngles.inl b/include/Nazara/Math/EulerAngles.inl index b02e5f6ed..79e3c1ded 100644 --- a/include/Nazara/Math/EulerAngles.inl +++ b/include/Nazara/Math/EulerAngles.inl @@ -12,168 +12,171 @@ #define F(a) static_cast(a) -template -NzEulerAngles::NzEulerAngles(T P, T Y, T R) +namespace Nz { - Set(P, Y, R); + template + EulerAngles::EulerAngles(T P, T Y, T R) + { + Set(P, Y, R); + } + + template + EulerAngles::EulerAngles(const T angles[3]) + { + Set(angles); + } + + template + EulerAngles::EulerAngles(const Quaternion& quat) + { + Set(quat); + } + + template + template + EulerAngles::EulerAngles(const EulerAngles& angles) + { + Set(angles); + } + + template + void EulerAngles::MakeZero() + { + Set(F(0.0), F(0.0), F(0.0)); + } + + template + void EulerAngles::Normalize() + { + pitch = NormalizeAngle(pitch); + yaw = NormalizeAngle(yaw); + roll = NormalizeAngle(roll); + } + + template + void EulerAngles::Set(T P, T Y, T R) + { + pitch = P; + yaw = Y; + roll = R; + } + + template + void EulerAngles::Set(const T angles[3]) + { + pitch = angles[0]; + yaw = angles[1]; + roll = angles[2]; + } + + template + void EulerAngles::Set(const EulerAngles& angles) + { + std::memcpy(this, &angles, sizeof(EulerAngles)); + } + + template + void EulerAngles::Set(const Quaternion& quat) + { + Set(quat.ToEulerAngles()); + } + + template + template + void EulerAngles::Set(const EulerAngles& angles) + { + pitch = F(angles.pitch); + yaw = F(angles.yaw); + roll = F(angles.roll); + } + + template + Quaternion EulerAngles::ToQuaternion() const + { + T c1 = std::cos(ToRadians(yaw) / F(2.0)); + T c2 = std::cos(ToRadians(roll) / F(2.0)); + T c3 = std::cos(ToRadians(pitch) / F(2.0)); + + T s1 = std::sin(ToRadians(yaw) / F(2.0)); + T s2 = std::sin(ToRadians(roll) / F(2.0)); + T s3 = std::sin(ToRadians(pitch) / F(2.0)); + + return Quaternion(c1 * c2 * c3 - s1 * s2 * s3, + s1 * s2 * c3 + c1 * c2 * s3, + s1 * c2 * c3 + c1 * s2 * s3, + c1 * s2 * c3 - s1 * c2 * s3); + } + + template + String EulerAngles::ToString() const + { + StringStream ss; + + return ss << "EulerAngles(" << pitch << ", " << yaw << ", " << roll << ')'; + } + + template + EulerAngles EulerAngles::operator+(const EulerAngles& angles) const + { + return EulerAngles(pitch + angles.pitch, + yaw + angles.yaw, + roll + angles.roll); + } + + template + EulerAngles EulerAngles::operator-(const EulerAngles& angles) const + { + return EulerAngles(pitch - angles.pitch, + yaw - angles.yaw, + roll - angles.roll); + } + + template + EulerAngles& EulerAngles::operator+=(const EulerAngles& angles) + { + pitch += angles.pitch; + yaw += angles.yaw; + roll += angles.roll; + + return *this; + } + + template + EulerAngles& EulerAngles::operator-=(const EulerAngles& angles) + { + pitch -= angles.pitch; + yaw -= angles.yaw; + roll -= angles.roll; + + return *this; + } + + template + bool EulerAngles::operator==(const EulerAngles& angles) const + { + return NumberEquals(pitch, angles.pitch) && + NumberEquals(yaw, angles.yaw) && + NumberEquals(roll, angles.roll); + } + + template + bool EulerAngles::operator!=(const EulerAngles& angles) const + { + return !operator==(angles); + } + + template + EulerAngles EulerAngles::Zero() + { + EulerAngles angles; + angles.MakeZero(); + + return angles; + } } template -NzEulerAngles::NzEulerAngles(const T angles[3]) -{ - Set(angles); -} - -template -NzEulerAngles::NzEulerAngles(const NzQuaternion& quat) -{ - Set(quat); -} - -template -template -NzEulerAngles::NzEulerAngles(const NzEulerAngles& angles) -{ - Set(angles); -} - -template -void NzEulerAngles::MakeZero() -{ - Set(F(0.0), F(0.0), F(0.0)); -} - -template -void NzEulerAngles::Normalize() -{ - pitch = NzNormalizeAngle(pitch); - yaw = NzNormalizeAngle(yaw); - roll = NzNormalizeAngle(roll); -} - -template -void NzEulerAngles::Set(T P, T Y, T R) -{ - pitch = P; - yaw = Y; - roll = R; -} - -template -void NzEulerAngles::Set(const T angles[3]) -{ - pitch = angles[0]; - yaw = angles[1]; - roll = angles[2]; -} - -template -void NzEulerAngles::Set(const NzEulerAngles& angles) -{ - std::memcpy(this, &angles, sizeof(NzEulerAngles)); -} - -template -void NzEulerAngles::Set(const NzQuaternion& quat) -{ - Set(quat.ToEulerAngles()); -} - -template -template -void NzEulerAngles::Set(const NzEulerAngles& angles) -{ - pitch = F(angles.pitch); - yaw = F(angles.yaw); - roll = F(angles.roll); -} - -template -NzQuaternion NzEulerAngles::ToQuaternion() const -{ - T c1 = std::cos(NzToRadians(yaw) / F(2.0)); - T c2 = std::cos(NzToRadians(roll) / F(2.0)); - T c3 = std::cos(NzToRadians(pitch) / F(2.0)); - - T s1 = std::sin(NzToRadians(yaw) / F(2.0)); - T s2 = std::sin(NzToRadians(roll) / F(2.0)); - T s3 = std::sin(NzToRadians(pitch) / F(2.0)); - - return NzQuaternion(c1 * c2 * c3 - s1 * s2 * s3, - s1 * s2 * c3 + c1 * c2 * s3, - s1 * c2 * c3 + c1 * s2 * s3, - c1 * s2 * c3 - s1 * c2 * s3); -} - -template -NzString NzEulerAngles::ToString() const -{ - NzStringStream ss; - - return ss << "EulerAngles(" << pitch << ", " << yaw << ", " << roll << ')'; -} - -template -NzEulerAngles NzEulerAngles::operator+(const NzEulerAngles& angles) const -{ - return NzEulerAngles(pitch + angles.pitch, - yaw + angles.yaw, - roll + angles.roll); -} - -template -NzEulerAngles NzEulerAngles::operator-(const NzEulerAngles& angles) const -{ - return NzEulerAngles(pitch - angles.pitch, - yaw - angles.yaw, - roll - angles.roll); -} - -template -NzEulerAngles& NzEulerAngles::operator+=(const NzEulerAngles& angles) -{ - pitch += angles.pitch; - yaw += angles.yaw; - roll += angles.roll; - - return *this; -} - -template -NzEulerAngles& NzEulerAngles::operator-=(const NzEulerAngles& angles) -{ - pitch -= angles.pitch; - yaw -= angles.yaw; - roll -= angles.roll; - - return *this; -} - -template -bool NzEulerAngles::operator==(const NzEulerAngles& angles) const -{ - return NzNumberEquals(pitch, angles.pitch) && - NzNumberEquals(yaw, angles.yaw) && - NzNumberEquals(roll, angles.roll); -} - -template -bool NzEulerAngles::operator!=(const NzEulerAngles& angles) const -{ - return !operator==(angles); -} - -template -NzEulerAngles NzEulerAngles::Zero() -{ - NzEulerAngles angles; - angles.MakeZero(); - - return angles; -} - -template -std::ostream& operator<<(std::ostream& out, const NzEulerAngles& angles) +std::ostream& operator<<(std::ostream& out, const Nz::EulerAngles& angles) { return out << angles.ToString(); } diff --git a/include/Nazara/Math/Frustum.hpp b/include/Nazara/Math/Frustum.hpp index e28949f46..44c3bc0e7 100644 --- a/include/Nazara/Math/Frustum.hpp +++ b/include/Nazara/Math/Frustum.hpp @@ -16,51 +16,54 @@ #include #include -template -class NzFrustum +namespace Nz { - public: - NzFrustum() = default; - template explicit NzFrustum(const NzFrustum& frustum); - NzFrustum(const NzFrustum& frustum) = default; - ~NzFrustum() = default; + template + class Frustum + { + public: + Frustum() = default; + template explicit Frustum(const Frustum& frustum); + Frustum(const Frustum& frustum) = default; + ~Frustum() = default; - NzFrustum& Build(T angle, T ratio, T zNear, T zFar, const NzVector3& eye, const NzVector3& target, const NzVector3& up = NzVector3::Up()); + Frustum& Build(T angle, T ratio, T zNear, T zFar, const Vector3& eye, const Vector3& target, const Vector3& up = Vector3::Up()); - bool Contains(const NzBoundingVolume& volume) const; - bool Contains(const NzBox& box) const; - bool Contains(const NzOrientedBox& orientedBox) const; - bool Contains(const NzSphere& sphere) const; - bool Contains(const NzVector3& point) const; - bool Contains(const NzVector3* points, unsigned int pointCount) const; + bool Contains(const BoundingVolume& volume) const; + bool Contains(const Box& box) const; + bool Contains(const OrientedBox& orientedBox) const; + bool Contains(const Sphere& sphere) const; + bool Contains(const Vector3& point) const; + bool Contains(const Vector3* points, unsigned int pointCount) const; - NzFrustum& Extract(const NzMatrix4& clipMatrix); - NzFrustum& Extract(const NzMatrix4& view, const NzMatrix4& projection); + Frustum& Extract(const Matrix4& clipMatrix); + Frustum& Extract(const Matrix4& view, const Matrix4& projection); - const NzVector3& GetCorner(nzBoxCorner corner) const; - const NzPlane& GetPlane(nzFrustumPlane plane) const; + const Vector3& GetCorner(BoxCorner corner) const; + const Plane& GetPlane(FrustumPlane plane) const; - nzIntersectionSide Intersect(const NzBoundingVolume& volume) const; - nzIntersectionSide Intersect(const NzBox& box) const; - nzIntersectionSide Intersect(const NzOrientedBox& orientedBox) const; - nzIntersectionSide Intersect(const NzSphere& sphere) const; - nzIntersectionSide Intersect(const NzVector3* points, unsigned int pointCount) const; + IntersectionSide Intersect(const BoundingVolume& volume) const; + IntersectionSide Intersect(const Box& box) const; + IntersectionSide Intersect(const OrientedBox& orientedBox) const; + IntersectionSide Intersect(const Sphere& sphere) const; + IntersectionSide Intersect(const Vector3* points, unsigned int pointCount) const; - NzFrustum& Set(const NzFrustum& frustum); - template NzFrustum& Set(const NzFrustum& frustum); + Frustum& Set(const Frustum& frustum); + template Frustum& Set(const Frustum& frustum); - NzString ToString() const; + String ToString() const; - private: - NzVector3 m_corners[nzBoxCorner_Max+1]; - NzPlane m_planes[nzFrustumPlane_Max+1]; -}; + private: + Vector3 m_corners[BoxCorner_Max+1]; + Plane m_planes[FrustumPlane_Max+1]; + }; + + typedef Frustum Frustumd; + typedef Frustum Frustumf; +} template -std::ostream& operator<<(std::ostream& out, const NzFrustum& frustum); - -typedef NzFrustum NzFrustumd; -typedef NzFrustum NzFrustumf; +std::ostream& operator<<(std::ostream& out, const Nz::Frustum& frustum); #include diff --git a/include/Nazara/Math/Frustum.inl b/include/Nazara/Math/Frustum.inl index 45f8cc98d..46b879716 100644 --- a/include/Nazara/Math/Frustum.inl +++ b/include/Nazara/Math/Frustum.inl @@ -13,495 +13,498 @@ #define F(a) static_cast(a) -template -template -NzFrustum::NzFrustum(const NzFrustum& frustum) +namespace Nz { - Set(frustum); -} - -template -NzFrustum& NzFrustum::Build(T angle, T ratio, T zNear, T zFar, const NzVector3& eye, const NzVector3& target, const NzVector3& up) -{ - #if NAZARA_MATH_ANGLE_RADIAN - angle /= F(2.0); - #else - angle = NzDegreeToRadian(angle/F(2.0)); - #endif - - T tangent = std::tan(angle); - T nearH = zNear * tangent; - T nearW = nearH * ratio; - T farH = zFar * tangent; - T farW = farH * ratio; - - NzVector3 f = NzVector3::Normalize(target - eye); - NzVector3 u(up.GetNormal()); - NzVector3 s = NzVector3::Normalize(f.CrossProduct(u)); - u = s.CrossProduct(f); - - NzVector3 nc = eye + f * zNear; - NzVector3 fc = eye + f * zFar; - - // Calcul du frustum - m_corners[nzBoxCorner_FarLeftBottom] = fc - u*farH - s*farW; - m_corners[nzBoxCorner_FarLeftTop] = fc + u*farH - s*farW; - m_corners[nzBoxCorner_FarRightTop] = fc + u*farH + s*farW; - m_corners[nzBoxCorner_FarRightBottom] = fc - u*farH + s*farW; - - m_corners[nzBoxCorner_NearLeftBottom] = nc - u*nearH - s*nearW; - m_corners[nzBoxCorner_NearLeftTop] = nc + u*nearH - s*nearW; - m_corners[nzBoxCorner_NearRightTop] = nc + u*nearH + s*nearW; - m_corners[nzBoxCorner_NearRightBottom] = nc - u*nearH + s*nearW; - - // Construction des plans du frustum - m_planes[nzFrustumPlane_Bottom].Set(m_corners[nzBoxCorner_NearLeftBottom], m_corners[nzBoxCorner_NearRightBottom], m_corners[nzBoxCorner_FarRightBottom]); - m_planes[nzFrustumPlane_Far].Set(m_corners[nzBoxCorner_FarRightTop], m_corners[nzBoxCorner_FarLeftTop], m_corners[nzBoxCorner_FarLeftBottom]); - m_planes[nzFrustumPlane_Left].Set(m_corners[nzBoxCorner_NearLeftTop], m_corners[nzBoxCorner_NearLeftBottom], m_corners[nzBoxCorner_FarLeftBottom]); - m_planes[nzFrustumPlane_Near].Set(m_corners[nzBoxCorner_NearLeftTop], m_corners[nzBoxCorner_NearRightTop], m_corners[nzBoxCorner_NearRightBottom]); - m_planes[nzFrustumPlane_Right].Set(m_corners[nzBoxCorner_NearRightBottom], m_corners[nzBoxCorner_NearRightTop], m_corners[nzBoxCorner_FarRightBottom]); - m_planes[nzFrustumPlane_Top].Set(m_corners[nzBoxCorner_NearRightTop], m_corners[nzBoxCorner_NearLeftTop], m_corners[nzBoxCorner_FarLeftTop]); - - return *this; -} - -template -bool NzFrustum::Contains(const NzBoundingVolume& volume) const -{ - switch (volume.extend) + template + template + Frustum::Frustum(const Frustum& frustum) { - case nzExtend_Finite: + Set(frustum); + } + + template + Frustum& Frustum::Build(T angle, T ratio, T zNear, T zFar, const Vector3& eye, const Vector3& target, const Vector3& up) + { + #if NAZARA_MATH_ANGLE_RADIAN + angle /= F(2.0); + #else + angle = NzDegreeToRadian(angle/F(2.0)); + #endif + + T tangent = std::tan(angle); + T nearH = zNear * tangent; + T nearW = nearH * ratio; + T farH = zFar * tangent; + T farW = farH * ratio; + + Vector3 f = Vector3::Normalize(target - eye); + Vector3 u(up.GetNormal()); + Vector3 s = Vector3::Normalize(f.CrossProduct(u)); + u = s.CrossProduct(f); + + Vector3 nc = eye + f * zNear; + Vector3 fc = eye + f * zFar; + + // Calcul du frustum + m_corners[BoxCorner_FarLeftBottom] = fc - u*farH - s*farW; + m_corners[BoxCorner_FarLeftTop] = fc + u*farH - s*farW; + m_corners[BoxCorner_FarRightTop] = fc + u*farH + s*farW; + m_corners[BoxCorner_FarRightBottom] = fc - u*farH + s*farW; + + m_corners[BoxCorner_NearLeftBottom] = nc - u*nearH - s*nearW; + m_corners[BoxCorner_NearLeftTop] = nc + u*nearH - s*nearW; + m_corners[BoxCorner_NearRightTop] = nc + u*nearH + s*nearW; + m_corners[BoxCorner_NearRightBottom] = nc - u*nearH + s*nearW; + + // Construction des plans du frustum + m_planes[FrustumPlane_Bottom].Set(m_corners[BoxCorner_NearLeftBottom], m_corners[BoxCorner_NearRightBottom], m_corners[BoxCorner_FarRightBottom]); + m_planes[FrustumPlane_Far].Set(m_corners[BoxCorner_FarRightTop], m_corners[BoxCorner_FarLeftTop], m_corners[BoxCorner_FarLeftBottom]); + m_planes[FrustumPlane_Left].Set(m_corners[BoxCorner_NearLeftTop], m_corners[BoxCorner_NearLeftBottom], m_corners[BoxCorner_FarLeftBottom]); + m_planes[FrustumPlane_Near].Set(m_corners[BoxCorner_NearLeftTop], m_corners[BoxCorner_NearRightTop], m_corners[BoxCorner_NearRightBottom]); + m_planes[FrustumPlane_Right].Set(m_corners[BoxCorner_NearRightBottom], m_corners[BoxCorner_NearRightTop], m_corners[BoxCorner_FarRightBottom]); + m_planes[FrustumPlane_Top].Set(m_corners[BoxCorner_NearRightTop], m_corners[BoxCorner_NearLeftTop], m_corners[BoxCorner_FarLeftTop]); + + return *this; + } + + template + bool Frustum::Contains(const BoundingVolume& volume) const + { + switch (volume.extend) { - nzIntersectionSide side = Intersect(volume.aabb); - switch (side) + case Extend_Finite: { - case nzIntersectionSide_Inside: - return true; + IntersectionSide side = Intersect(volume.aabb); + switch (side) + { + case IntersectionSide_Inside: + return true; - case nzIntersectionSide_Intersecting: - return Contains(volume.obb); + case IntersectionSide_Intersecting: + return Contains(volume.obb); - case nzIntersectionSide_Outside: - return false; + case IntersectionSide_Outside: + return false; + } + + NazaraError("Invalid intersection side (0x" + String::Number(side, 16) + ')'); + return false; } - NazaraError("Invalid intersection side (0x" + NzString::Number(side, 16) + ')'); - return false; + case Extend_Infinite: + return true; + + case Extend_Null: + return false; } - case nzExtend_Infinite: - return true; - - case nzExtend_Null: - return false; + NazaraError("Invalid extend type (0x" + String::Number(volume.extend, 16) + ')'); + return false; } - NazaraError("Invalid extend type (0x" + NzString::Number(volume.extend, 16) + ')'); - return false; -} - -template -bool NzFrustum::Contains(const NzBox& box) const -{ - // http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-testing-boxes-ii/ - for(unsigned int i = 0; i <= nzFrustumPlane_Max; i++) + template + bool Frustum::Contains(const Box& box) const { - if (m_planes[i].Distance(box.GetPositiveVertex(m_planes[i].normal)) < F(0.0)) - return false; - } - - return true; -} - -template -bool NzFrustum::Contains(const NzOrientedBox& orientedbox) const -{ - return Contains(&orientedbox[0], 8); -} - -template -bool NzFrustum::Contains(const NzSphere& sphere) const -{ - for(unsigned int i = 0; i <= nzFrustumPlane_Max; i++) - { - if (m_planes[i].Distance(sphere.GetPosition()) < -sphere.radius) - return false; - } - - return true; -} - -template -bool NzFrustum::Contains(const NzVector3& point) const -{ - for(unsigned int i = 0; i <= nzFrustumPlane_Max; ++i) - { - if (m_planes[i].Distance(point) < F(0.0)) - return false; - } - - return true; -} - -template -bool NzFrustum::Contains(const NzVector3* points, unsigned int pointCount) const -{ - for (unsigned int i = 0; i <= nzFrustumPlane_Max; ++i) - { - unsigned int j; - for (j = 0; j < pointCount; j++ ) + // http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-testing-boxes-ii/ + for(unsigned int i = 0; i <= FrustumPlane_Max; i++) { - if (m_planes[i].Distance(points[j]) > F(0.0)) - break; + if (m_planes[i].Distance(box.GetPositiveVertex(m_planes[i].normal)) < F(0.0)) + return false; } - if (j == pointCount) - return false; + return true; } - return true; -} - -template -NzFrustum& NzFrustum::Extract(const NzMatrix4& clipMatrix) -{ - // http://www.crownandcutlass.com/features/technicaldetails/frustum.html - T plane[4]; - T invLength; - - // Extract the numbers for the RIGHT plane - plane[0] = clipMatrix[ 3] - clipMatrix[ 0]; - plane[1] = clipMatrix[ 7] - clipMatrix[ 4]; - plane[2] = clipMatrix[11] - clipMatrix[ 8]; - plane[3] = clipMatrix[15] - clipMatrix[12]; - - // Normalize the result - invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); - plane[0] *= invLength; - plane[1] *= invLength; - plane[2] *= invLength; - plane[3] *= -invLength; - - m_planes[nzFrustumPlane_Right].Set(plane); - - // Extract the numbers for the LEFT plane - plane[0] = clipMatrix[ 3] + clipMatrix[ 0]; - plane[1] = clipMatrix[ 7] + clipMatrix[ 4]; - plane[2] = clipMatrix[11] + clipMatrix[ 8]; - plane[3] = clipMatrix[15] + clipMatrix[12]; - - // Normalize the result - invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); - plane[0] *= invLength; - plane[1] *= invLength; - plane[2] *= invLength; - plane[3] *= -invLength; - - m_planes[nzFrustumPlane_Left].Set(plane); - - // Extract the BOTTOM plane - plane[0] = clipMatrix[ 3] + clipMatrix[ 1]; - plane[1] = clipMatrix[ 7] + clipMatrix[ 5]; - plane[2] = clipMatrix[11] + clipMatrix[ 9]; - plane[3] = clipMatrix[15] + clipMatrix[13]; - - // Normalize the result - invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); - plane[0] *= invLength; - plane[1] *= invLength; - plane[2] *= invLength; - plane[3] *= -invLength; - - m_planes[nzFrustumPlane_Bottom].Set(plane); - - // Extract the TOP plane - plane[0] = clipMatrix[ 3] - clipMatrix[ 1]; - plane[1] = clipMatrix[ 7] - clipMatrix[ 5]; - plane[2] = clipMatrix[11] - clipMatrix[ 9]; - plane[3] = clipMatrix[15] - clipMatrix[13]; - - // Normalize the result - invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); - plane[0] *= invLength; - plane[1] *= invLength; - plane[2] *= invLength; - plane[3] *= -invLength; - - m_planes[nzFrustumPlane_Top].Set(plane); - - // Extract the FAR plane - plane[0] = clipMatrix[ 3] - clipMatrix[ 2]; - plane[1] = clipMatrix[ 7] - clipMatrix[ 6]; - plane[2] = clipMatrix[11] - clipMatrix[10]; - plane[3] = clipMatrix[15] - clipMatrix[14]; - - // Normalize the result - invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); - plane[0] *= invLength; - plane[1] *= invLength; - plane[2] *= invLength; - plane[3] *= -invLength; - - m_planes[nzFrustumPlane_Far].Set(plane); - - // Extract the NEAR plane - plane[0] = clipMatrix[ 3] + clipMatrix[ 2]; - plane[1] = clipMatrix[ 7] + clipMatrix[ 6]; - plane[2] = clipMatrix[11] + clipMatrix[10]; - plane[3] = clipMatrix[15] + clipMatrix[14]; - - // Normalize the result - invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); - plane[0] *= invLength; - plane[1] *= invLength; - plane[2] *= invLength; - plane[3] *= -invLength; - - m_planes[nzFrustumPlane_Near].Set(plane); - - // Une fois les plans extraits, il faut extraire les points du frustum - // Je me base sur cette page: http://www.gamedev.net/topic/393309-calculating-the-view-frustums-vertices/ - - NzMatrix4 invClipMatrix; - if (clipMatrix.GetInverse(&invClipMatrix)) + template + bool Frustum::Contains(const OrientedBox& orientedbox) const { - NzVector4 corner; - - // FarLeftBottom - corner.Set(F(-1.0), F(-1.0), F(1.0)); - corner = invClipMatrix.Transform(corner); - corner.Normalize(); - - m_corners[nzBoxCorner_FarLeftBottom] = NzVector3(corner.x, corner.y, corner.z); - - // FarLeftTop - corner.Set(F(-1.0), F(1.0), F(1.0)); - corner = invClipMatrix.Transform(corner); - corner.Normalize(); - - m_corners[nzBoxCorner_FarLeftTop] = NzVector3(corner.x, corner.y, corner.z); - - // FarRightBottom - corner.Set(F(1.0), F(-1.0), F(1.0)); - corner = invClipMatrix.Transform(corner); - corner.Normalize(); - - m_corners[nzBoxCorner_FarRightBottom] = NzVector3(corner.x, corner.y, corner.z); - - // FarRightTop - corner.Set(F(1.0), F(1.0), F(1.0)); - corner = invClipMatrix.Transform(corner); - corner.Normalize(); - - m_corners[nzBoxCorner_FarRightTop] = NzVector3(corner.x, corner.y, corner.z); - - // NearLeftBottom - corner.Set(F(-1.0), F(-1.0), F(0.0)); - corner = invClipMatrix.Transform(corner); - corner.Normalize(); - - m_corners[nzBoxCorner_NearLeftBottom] = NzVector3(corner.x, corner.y, corner.z); - - // NearLeftTop - corner.Set(F(-1.0), F(1.0), F(0.0)); - corner = invClipMatrix.Transform(corner); - corner.Normalize(); - - m_corners[nzBoxCorner_NearLeftTop] = NzVector3(corner.x, corner.y, corner.z); - - // NearRightBottom - corner.Set(F(1.0), F(-1.0), F(0.0)); - corner = invClipMatrix.Transform(corner); - corner.Normalize(); - - m_corners[nzBoxCorner_NearRightBottom] = NzVector3(corner.x, corner.y, corner.z); - - // NearRightTop - corner.Set(F(1.0), F(1.0), F(0.0)); - corner = invClipMatrix.Transform(corner); - corner.Normalize(); - - m_corners[nzBoxCorner_NearRightTop] = NzVector3(corner.x, corner.y, corner.z); + return Contains(&orientedbox[0], 8); } - else - NazaraWarning("Clip matrix is not invertible, failed to compute frustum corners"); - return *this; -} - -template -NzFrustum& NzFrustum::Extract(const NzMatrix4& view, const NzMatrix4& projection) -{ - return Extract(NzMatrix4::Concatenate(view, projection)); -} - -template -const NzVector3& NzFrustum::GetCorner(nzBoxCorner corner) const -{ - #ifdef NAZARA_DEBUG - if (corner > nzBoxCorner_Max) + template + bool Frustum::Contains(const Sphere& sphere) const { - NazaraError("Corner not handled (0x" + NzString::Number(corner, 16) + ')'); - - static NzVector3 dummy; - return dummy; - } - #endif - - return m_corners[corner]; -} - -template -const NzPlane& NzFrustum::GetPlane(nzFrustumPlane plane) const -{ - #ifdef NAZARA_DEBUG - if (plane > nzFrustumPlane_Max) - { - NazaraError("Frustum plane not handled (0x" + NzString::Number(plane, 16) + ')'); - - static NzPlane dummy; - return dummy; - } - #endif - - return m_planes[plane]; -} - -template -nzIntersectionSide NzFrustum::Intersect(const NzBoundingVolume& volume) const -{ - switch (volume.extend) - { - case nzExtend_Finite: + for(unsigned int i = 0; i <= FrustumPlane_Max; i++) { - nzIntersectionSide side = Intersect(volume.aabb); - switch (side) + if (m_planes[i].Distance(sphere.GetPosition()) < -sphere.radius) + return false; + } + + return true; + } + + template + bool Frustum::Contains(const Vector3& point) const + { + for(unsigned int i = 0; i <= FrustumPlane_Max; ++i) + { + if (m_planes[i].Distance(point) < F(0.0)) + return false; + } + + return true; + } + + template + bool Frustum::Contains(const Vector3* points, unsigned int pointCount) const + { + for (unsigned int i = 0; i <= FrustumPlane_Max; ++i) + { + unsigned int j; + for (j = 0; j < pointCount; j++ ) { - case nzIntersectionSide_Inside: - return nzIntersectionSide_Inside; - - case nzIntersectionSide_Intersecting: - return Intersect(volume.obb); - - case nzIntersectionSide_Outside: - return nzIntersectionSide_Outside; + if (m_planes[i].Distance(points[j]) > F(0.0)) + break; } - NazaraError("Invalid intersection side (0x" + NzString::Number(side, 16) + ')'); - return nzIntersectionSide_Outside; + if (j == pointCount) + return false; } - case nzExtend_Infinite: - return nzIntersectionSide_Intersecting; // On ne peut pas contenir l'infini - - case nzExtend_Null: - return nzIntersectionSide_Outside; + return true; } - NazaraError("Invalid extend type (0x" + NzString::Number(volume.extend, 16) + ')'); - return nzIntersectionSide_Outside; -} - -template -nzIntersectionSide NzFrustum::Intersect(const NzBox& box) const -{ - // http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-testing-boxes-ii/ - nzIntersectionSide side = nzIntersectionSide_Inside; - - for(unsigned int i = 0; i <= nzFrustumPlane_Max; i++) + template + Frustum& Frustum::Extract(const Matrix4& clipMatrix) { - if (m_planes[i].Distance(box.GetPositiveVertex(m_planes[i].normal)) < F(0.0)) - return nzIntersectionSide_Outside; - else if (m_planes[i].Distance(box.GetNegativeVertex(m_planes[i].normal)) < F(0.0)) - side = nzIntersectionSide_Intersecting; - } + // http://www.crownandcutlass.com/features/technicaldetails/frustum.html + T plane[4]; + T invLength; - return side; -} + // Extract the numbers for the RIGHT plane + plane[0] = clipMatrix[ 3] - clipMatrix[ 0]; + plane[1] = clipMatrix[ 7] - clipMatrix[ 4]; + plane[2] = clipMatrix[11] - clipMatrix[ 8]; + plane[3] = clipMatrix[15] - clipMatrix[12]; -template -nzIntersectionSide NzFrustum::Intersect(const NzOrientedBox& orientedbox) const -{ - return Intersect(&orientedbox[0], 8); -} + // Normalize the result + invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); + plane[0] *= invLength; + plane[1] *= invLength; + plane[2] *= invLength; + plane[3] *= -invLength; -template -nzIntersectionSide NzFrustum::Intersect(const NzSphere& sphere) const -{ - // http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-testing-points-and-spheres/ - nzIntersectionSide side = nzIntersectionSide_Inside; + m_planes[FrustumPlane_Right].Set(plane); - for(unsigned int i = 0; i <= nzFrustumPlane_Max; i++) - { - T distance = m_planes[i].Distance(sphere.GetPosition()); - if (distance < -sphere.radius) - return nzIntersectionSide_Outside; - else if (distance < sphere.radius) - side = nzIntersectionSide_Intersecting; - } + // Extract the numbers for the LEFT plane + plane[0] = clipMatrix[ 3] + clipMatrix[ 0]; + plane[1] = clipMatrix[ 7] + clipMatrix[ 4]; + plane[2] = clipMatrix[11] + clipMatrix[ 8]; + plane[3] = clipMatrix[15] + clipMatrix[12]; - return side; -} + // Normalize the result + invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); + plane[0] *= invLength; + plane[1] *= invLength; + plane[2] *= invLength; + plane[3] *= -invLength; -template -nzIntersectionSide NzFrustum::Intersect(const NzVector3* points, unsigned int pointCount) const -{ - unsigned int c = 0; + m_planes[FrustumPlane_Left].Set(plane); - for (unsigned int i = 0; i <= nzFrustumPlane_Max; ++i) - { - unsigned int j; - for (j = 0; j < pointCount; j++ ) + // Extract the BOTTOM plane + plane[0] = clipMatrix[ 3] + clipMatrix[ 1]; + plane[1] = clipMatrix[ 7] + clipMatrix[ 5]; + plane[2] = clipMatrix[11] + clipMatrix[ 9]; + plane[3] = clipMatrix[15] + clipMatrix[13]; + + // Normalize the result + invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); + plane[0] *= invLength; + plane[1] *= invLength; + plane[2] *= invLength; + plane[3] *= -invLength; + + m_planes[FrustumPlane_Bottom].Set(plane); + + // Extract the TOP plane + plane[0] = clipMatrix[ 3] - clipMatrix[ 1]; + plane[1] = clipMatrix[ 7] - clipMatrix[ 5]; + plane[2] = clipMatrix[11] - clipMatrix[ 9]; + plane[3] = clipMatrix[15] - clipMatrix[13]; + + // Normalize the result + invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); + plane[0] *= invLength; + plane[1] *= invLength; + plane[2] *= invLength; + plane[3] *= -invLength; + + m_planes[FrustumPlane_Top].Set(plane); + + // Extract the FAR plane + plane[0] = clipMatrix[ 3] - clipMatrix[ 2]; + plane[1] = clipMatrix[ 7] - clipMatrix[ 6]; + plane[2] = clipMatrix[11] - clipMatrix[10]; + plane[3] = clipMatrix[15] - clipMatrix[14]; + + // Normalize the result + invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); + plane[0] *= invLength; + plane[1] *= invLength; + plane[2] *= invLength; + plane[3] *= -invLength; + + m_planes[FrustumPlane_Far].Set(plane); + + // Extract the NEAR plane + plane[0] = clipMatrix[ 3] + clipMatrix[ 2]; + plane[1] = clipMatrix[ 7] + clipMatrix[ 6]; + plane[2] = clipMatrix[11] + clipMatrix[10]; + plane[3] = clipMatrix[15] + clipMatrix[14]; + + // Normalize the result + invLength = F(1.0) / std::sqrt(plane[0]*plane[0] + plane[1]*plane[1] + plane[2]*plane[2]); + plane[0] *= invLength; + plane[1] *= invLength; + plane[2] *= invLength; + plane[3] *= -invLength; + + m_planes[FrustumPlane_Near].Set(plane); + + // Une fois les plans extraits, il faut extraire les points du frustum + // Je me base sur cette page: http://www.gamedev.net/topic/393309-calculating-the-view-frustums-vertices/ + + Matrix4 invClipMatrix; + if (clipMatrix.GetInverse(&invClipMatrix)) { - if (m_planes[i].Distance(points[j]) > F(0.0)) - break; - } + Vector4 corner; - if (j == pointCount) - return nzIntersectionSide_Outside; + // FarLeftBottom + corner.Set(F(-1.0), F(-1.0), F(1.0)); + corner = invClipMatrix.Transform(corner); + corner.Normalize(); + + m_corners[BoxCorner_FarLeftBottom] = Vector3(corner.x, corner.y, corner.z); + + // FarLeftTop + corner.Set(F(-1.0), F(1.0), F(1.0)); + corner = invClipMatrix.Transform(corner); + corner.Normalize(); + + m_corners[BoxCorner_FarLeftTop] = Vector3(corner.x, corner.y, corner.z); + + // FarRightBottom + corner.Set(F(1.0), F(-1.0), F(1.0)); + corner = invClipMatrix.Transform(corner); + corner.Normalize(); + + m_corners[BoxCorner_FarRightBottom] = Vector3(corner.x, corner.y, corner.z); + + // FarRightTop + corner.Set(F(1.0), F(1.0), F(1.0)); + corner = invClipMatrix.Transform(corner); + corner.Normalize(); + + m_corners[BoxCorner_FarRightTop] = Vector3(corner.x, corner.y, corner.z); + + // NearLeftBottom + corner.Set(F(-1.0), F(-1.0), F(0.0)); + corner = invClipMatrix.Transform(corner); + corner.Normalize(); + + m_corners[BoxCorner_NearLeftBottom] = Vector3(corner.x, corner.y, corner.z); + + // NearLeftTop + corner.Set(F(-1.0), F(1.0), F(0.0)); + corner = invClipMatrix.Transform(corner); + corner.Normalize(); + + m_corners[BoxCorner_NearLeftTop] = Vector3(corner.x, corner.y, corner.z); + + // NearRightBottom + corner.Set(F(1.0), F(-1.0), F(0.0)); + corner = invClipMatrix.Transform(corner); + corner.Normalize(); + + m_corners[BoxCorner_NearRightBottom] = Vector3(corner.x, corner.y, corner.z); + + // NearRightTop + corner.Set(F(1.0), F(1.0), F(0.0)); + corner = invClipMatrix.Transform(corner); + corner.Normalize(); + + m_corners[BoxCorner_NearRightTop] = Vector3(corner.x, corner.y, corner.z); + } else - c++; + NazaraWarning("Clip matrix is not invertible, failed to compute frustum corners"); + + return *this; } - return (c == 6) ? nzIntersectionSide_Inside : nzIntersectionSide_Intersecting; + template + Frustum& Frustum::Extract(const Matrix4& view, const Matrix4& projection) + { + return Extract(Matrix4::Concatenate(view, projection)); + } + + template + const Vector3& Frustum::GetCorner(BoxCorner corner) const + { + #ifdef NAZARA_DEBUG + if (corner > BoxCorner_Max) + { + NazaraError("Corner not handled (0x" + String::Number(corner, 16) + ')'); + + static Vector3 dummy; + return dummy; + } + #endif + + return m_corners[corner]; + } + + template + const Plane& Frustum::GetPlane(FrustumPlane plane) const + { + #ifdef NAZARA_DEBUG + if (plane > FrustumPlane_Max) + { + NazaraError("Frustum plane not handled (0x" + String::Number(plane, 16) + ')'); + + static Plane dummy; + return dummy; + } + #endif + + return m_planes[plane]; + } + + template + IntersectionSide Frustum::Intersect(const BoundingVolume& volume) const + { + switch (volume.extend) + { + case Extend_Finite: + { + IntersectionSide side = Intersect(volume.aabb); + switch (side) + { + case IntersectionSide_Inside: + return IntersectionSide_Inside; + + case IntersectionSide_Intersecting: + return Intersect(volume.obb); + + case IntersectionSide_Outside: + return IntersectionSide_Outside; + } + + NazaraError("Invalid intersection side (0x" + String::Number(side, 16) + ')'); + return IntersectionSide_Outside; + } + + case Extend_Infinite: + return IntersectionSide_Intersecting; // On ne peut pas contenir l'infini + + case Extend_Null: + return IntersectionSide_Outside; + } + + NazaraError("Invalid extend type (0x" + String::Number(volume.extend, 16) + ')'); + return IntersectionSide_Outside; + } + + template + IntersectionSide Frustum::Intersect(const Box& box) const + { + // http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-testing-boxes-ii/ + IntersectionSide side = IntersectionSide_Inside; + + for(unsigned int i = 0; i <= FrustumPlane_Max; i++) + { + if (m_planes[i].Distance(box.GetPositiveVertex(m_planes[i].normal)) < F(0.0)) + return IntersectionSide_Outside; + else if (m_planes[i].Distance(box.GetNegativeVertex(m_planes[i].normal)) < F(0.0)) + side = IntersectionSide_Intersecting; + } + + return side; + } + + template + IntersectionSide Frustum::Intersect(const OrientedBox& orientedbox) const + { + return Intersect(&orientedbox[0], 8); + } + + template + IntersectionSide Frustum::Intersect(const Sphere& sphere) const + { + // http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-testing-points-and-spheres/ + IntersectionSide side = IntersectionSide_Inside; + + for(unsigned int i = 0; i <= FrustumPlane_Max; i++) + { + T distance = m_planes[i].Distance(sphere.GetPosition()); + if (distance < -sphere.radius) + return IntersectionSide_Outside; + else if (distance < sphere.radius) + side = IntersectionSide_Intersecting; + } + + return side; + } + + template + IntersectionSide Frustum::Intersect(const Vector3* points, unsigned int pointCount) const + { + unsigned int c = 0; + + for (unsigned int i = 0; i <= FrustumPlane_Max; ++i) + { + unsigned int j; + for (j = 0; j < pointCount; j++ ) + { + if (m_planes[i].Distance(points[j]) > F(0.0)) + break; + } + + if (j == pointCount) + return IntersectionSide_Outside; + else + c++; + } + + return (c == 6) ? IntersectionSide_Inside : IntersectionSide_Intersecting; + } + + template + Frustum& Frustum::Set(const Frustum& frustum) + { + std::memcpy(this, &frustum, sizeof(Frustum)); + + return *this; + } + + template + template + Frustum& Frustum::Set(const Frustum& frustum) + { + for (unsigned int i = 0; i <= BoxCorner_Max; ++i) + m_corners[i].Set(frustum.m_corners[i]); + + for (unsigned int i = 0; i <= FrustumPlane_Max; ++i) + m_planes[i].Set(frustum.m_planes[i]); + + return *this; + } + + template + String Frustum::ToString() const + { + StringStream ss; + + return ss << "Frustum(Bottom: " << m_planes[FrustumPlane_Bottom].ToString() << "\n" + << " Far: " << m_planes[FrustumPlane_Far].ToString() << "\n" + << " Left: " << m_planes[FrustumPlane_Left].ToString() << "\n" + << " Near: " << m_planes[FrustumPlane_Near].ToString() << "\n" + << " Right: " << m_planes[FrustumPlane_Right].ToString() << "\n" + << " Top: " << m_planes[FrustumPlane_Top].ToString() << ")\n"; + } } template -NzFrustum& NzFrustum::Set(const NzFrustum& frustum) -{ - std::memcpy(this, &frustum, sizeof(NzFrustum)); - - return *this; -} - -template -template -NzFrustum& NzFrustum::Set(const NzFrustum& frustum) -{ - for (unsigned int i = 0; i <= nzBoxCorner_Max; ++i) - m_corners[i].Set(frustum.m_corners[i]); - - for (unsigned int i = 0; i <= nzFrustumPlane_Max; ++i) - m_planes[i].Set(frustum.m_planes[i]); - - return *this; -} - -template -NzString NzFrustum::ToString() const -{ - NzStringStream ss; - - return ss << "Frustum(Bottom: " << m_planes[nzFrustumPlane_Bottom].ToString() << "\n" - << " Far: " << m_planes[nzFrustumPlane_Far].ToString() << "\n" - << " Left: " << m_planes[nzFrustumPlane_Left].ToString() << "\n" - << " Near: " << m_planes[nzFrustumPlane_Near].ToString() << "\n" - << " Right: " << m_planes[nzFrustumPlane_Right].ToString() << "\n" - << " Top: " << m_planes[nzFrustumPlane_Top].ToString() << ")\n"; -} - -template -std::ostream& operator<<(std::ostream& out, const NzFrustum& frustum) +std::ostream& operator<<(std::ostream& out, const Nz::Frustum& frustum) { return out << frustum.ToString(); } diff --git a/include/Nazara/Math/Matrix4.hpp b/include/Nazara/Math/Matrix4.hpp index 075d3bcac..d72529d92 100644 --- a/include/Nazara/Math/Matrix4.hpp +++ b/include/Nazara/Math/Matrix4.hpp @@ -12,134 +12,138 @@ #include #include -template class NzEulerAngles; -template class NzQuaternion; -template class NzVector2; -template class NzVector3; -template class NzVector4; - -template -class NzMatrix4 +namespace Nz { - public: - NzMatrix4() = default; - NzMatrix4(T r11, T r12, T r13, T r14, - T r21, T r22, T r23, T r24, - T r31, T r32, T r33, T r34, - T r41, T r42, T r43, T r44); - //NzMatrix4(const NzMatrix3& matrix); - NzMatrix4(const T matrix[16]); - template explicit NzMatrix4(const NzMatrix4& matrix); - NzMatrix4(const NzMatrix4& matrix) = default; - ~NzMatrix4() = default; + template class EulerAngles; + template class Quaternion; + template class Vector2; + template class Vector3; + template class Vector4; - NzMatrix4& ApplyRotation(const NzQuaternion& rotation); - NzMatrix4& ApplyScale(const NzVector3& scale); - NzMatrix4& ApplyTranslation(const NzVector3& translation); + template + class Matrix4 + { + public: + Matrix4() = default; + Matrix4(T r11, T r12, T r13, T r14, + T r21, T r22, T r23, T r24, + T r31, T r32, T r33, T r34, + T r41, T r42, T r43, T r44); + //Matrix4(const Matrix3& matrix); + Matrix4(const T matrix[16]); + template explicit Matrix4(const Matrix4& matrix); + Matrix4(const Matrix4& matrix) = default; + ~Matrix4() = default; - NzMatrix4& Concatenate(const NzMatrix4& matrix); - NzMatrix4& ConcatenateAffine(const NzMatrix4& matrix); + Matrix4& ApplyRotation(const Quaternion& rotation); + Matrix4& ApplyScale(const Vector3& scale); + Matrix4& ApplyTranslation(const Vector3& translation); - NzVector4 GetColumn(unsigned int column) const; - T GetDeterminant() const; - T GetDeterminantAffine() const; - bool GetInverse(NzMatrix4* dest) const; - bool GetInverseAffine(NzMatrix4* dest) const; - NzQuaternion GetRotation() const; - //NzMatrix3 GetRotationMatrix() const; - NzVector4 GetRow(unsigned int row) const; - NzVector3 GetScale() const; - NzVector3 GetSquaredScale() const; - NzVector3 GetTranslation() const; - void GetTransposed(NzMatrix4* dest) const; + Matrix4& Concatenate(const Matrix4& matrix); + Matrix4& ConcatenateAffine(const Matrix4& matrix); - bool HasNegativeScale() const; - bool HasScale() const; + Vector4 GetColumn(unsigned int column) const; + T GetDeterminant() const; + T GetDeterminantAffine() const; + bool GetInverse(Matrix4* dest) const; + bool GetInverseAffine(Matrix4* dest) const; + Quaternion GetRotation() const; + //Matrix3 GetRotationMatrix() const; + Vector4 GetRow(unsigned int row) const; + Vector3 GetScale() const; + Vector3 GetSquaredScale() const; + Vector3 GetTranslation() const; + void GetTransposed(Matrix4* dest) const; - NzMatrix4& Inverse(bool* succeeded = nullptr); - NzMatrix4& InverseAffine(bool* succeeded = nullptr); + bool HasNegativeScale() const; + bool HasScale() const; - bool IsAffine() const; - bool IsIdentity() const; + Matrix4& Inverse(bool* succeeded = nullptr); + Matrix4& InverseAffine(bool* succeeded = nullptr); - NzMatrix4& MakeIdentity(); - NzMatrix4& MakeLookAt(const NzVector3& eye, const NzVector3& target, const NzVector3& up = NzVector3::Up()); - NzMatrix4& MakeOrtho(T left, T right, T top, T bottom, T zNear = -1.0, T zFar = 1.0); - NzMatrix4& MakePerspective(T angle, T ratio, T zNear, T zFar); - NzMatrix4& MakeRotation(const NzQuaternion& rotation); - NzMatrix4& MakeScale(const NzVector3& scale); - NzMatrix4& MakeTranslation(const NzVector3& translation); - NzMatrix4& MakeTransform(const NzVector3& translation, const NzQuaternion& rotation); - NzMatrix4& MakeTransform(const NzVector3& translation, const NzQuaternion& rotation, const NzVector3& scale); - NzMatrix4& MakeViewMatrix(const NzVector3& translation, const NzQuaternion& rotation); - NzMatrix4& MakeZero(); + bool IsAffine() const; + bool IsIdentity() const; - NzMatrix4& Set(T r11, T r12, T r13, T r14, - T r21, T r22, T r23, T r24, - T r31, T r32, T r33, T r34, - T r41, T r42, T r43, T r44); - NzMatrix4& Set(const T matrix[16]); - //NzMatrix4(const NzMatrix3& matrix); - NzMatrix4& Set(const NzMatrix4& matrix); - template NzMatrix4& Set(const NzMatrix4& matrix); - NzMatrix4& SetRotation(const NzQuaternion& rotation); - NzMatrix4& SetScale(const NzVector3& scale); - NzMatrix4& SetTranslation(const NzVector3& translation); + Matrix4& MakeIdentity(); + Matrix4& MakeLookAt(const Vector3& eye, const Vector3& target, const Vector3& up = Vector3::Up()); + Matrix4& MakeOrtho(T left, T right, T top, T bottom, T zNear = -1.0, T zFar = 1.0); + Matrix4& MakePerspective(T angle, T ratio, T zNear, T zFar); + Matrix4& MakeRotation(const Quaternion& rotation); + Matrix4& MakeScale(const Vector3& scale); + Matrix4& MakeTranslation(const Vector3& translation); + Matrix4& MakeTransform(const Vector3& translation, const Quaternion& rotation); + Matrix4& MakeTransform(const Vector3& translation, const Quaternion& rotation, const Vector3& scale); + Matrix4& MakeViewMatrix(const Vector3& translation, const Quaternion& rotation); + Matrix4& MakeZero(); - NzString ToString() const; + Matrix4& Set(T r11, T r12, T r13, T r14, + T r21, T r22, T r23, T r24, + T r31, T r32, T r33, T r34, + T r41, T r42, T r43, T r44); + Matrix4& Set(const T matrix[16]); + //Matrix4(const Matrix3& matrix); + Matrix4& Set(const Matrix4& matrix); + template Matrix4& Set(const Matrix4& matrix); + Matrix4& SetRotation(const Quaternion& rotation); + Matrix4& SetScale(const Vector3& scale); + Matrix4& SetTranslation(const Vector3& translation); - NzVector2 Transform(const NzVector2& vector, T z = 0.0, T w = 1.0) const; - NzVector3 Transform(const NzVector3& vector, T w = 1.0) const; - NzVector4 Transform(const NzVector4& vector) const; + String ToString() const; - NzMatrix4& Transpose(); + Vector2 Transform(const Vector2& vector, T z = 0.0, T w = 1.0) const; + Vector3 Transform(const Vector3& vector, T w = 1.0) const; + Vector4 Transform(const Vector4& vector) const; - operator T*(); - operator const T*() const; + Matrix4& Transpose(); - T& operator()(unsigned int x, unsigned int y); - T operator()(unsigned int x, unsigned int y) const; + operator T*(); + operator const T*() const; - NzMatrix4& operator=(const NzMatrix4& matrix) = default; + T& operator()(unsigned int x, unsigned int y); + T operator()(unsigned int x, unsigned int y) const; - NzMatrix4 operator*(const NzMatrix4& matrix) const; - NzVector2 operator*(const NzVector2& vector) const; - NzVector3 operator*(const NzVector3& vector) const; - NzVector4 operator*(const NzVector4& vector) const; - NzMatrix4 operator*(T scalar) const; + Matrix4& operator=(const Matrix4& matrix) = default; - NzMatrix4& operator*=(const NzMatrix4& matrix); - NzMatrix4& operator*=(T scalar); + Matrix4 operator*(const Matrix4& matrix) const; + Vector2 operator*(const Vector2& vector) const; + Vector3 operator*(const Vector3& vector) const; + Vector4 operator*(const Vector4& vector) const; + Matrix4 operator*(T scalar) const; - bool operator==(const NzMatrix4& mat) const; - bool operator!=(const NzMatrix4& mat) const; + Matrix4& operator*=(const Matrix4& matrix); + Matrix4& operator*=(T scalar); - static NzMatrix4 Concatenate(const NzMatrix4& left, const NzMatrix4& right); - static NzMatrix4 ConcatenateAffine(const NzMatrix4& left, const NzMatrix4& right); - static NzMatrix4 Identity(); - static NzMatrix4 LookAt(const NzVector3& eye, const NzVector3& target, const NzVector3& up = NzVector3::Up()); - static NzMatrix4 Ortho(T left, T right, T top, T bottom, T zNear = -1.0, T zFar = 1.0); - static NzMatrix4 Perspective(T angle, T ratio, T zNear, T zFar); - static NzMatrix4 Rotate(const NzQuaternion& rotation); - static NzMatrix4 Scale(const NzVector3& scale); - static NzMatrix4 Translate(const NzVector3& translation); - static NzMatrix4 Transform(const NzVector3& translation, const NzQuaternion& rotation); - static NzMatrix4 Transform(const NzVector3& translation, const NzQuaternion& rotation, const NzVector3& scale); - static NzMatrix4 ViewMatrix(const NzVector3& translation, const NzQuaternion& rotation); - static NzMatrix4 Zero(); + bool operator==(const Matrix4& mat) const; + bool operator!=(const Matrix4& mat) const; - T m11, m12, m13, m14, - m21, m22, m23, m24, - m31, m32, m33, m34, - m41, m42, m43, m44; -}; + static Matrix4 Concatenate(const Matrix4& left, const Matrix4& right); + static Matrix4 ConcatenateAffine(const Matrix4& left, const Matrix4& right); + static Matrix4 Identity(); + static Matrix4 LookAt(const Vector3& eye, const Vector3& target, const Vector3& up = Vector3::Up()); + static Matrix4 Ortho(T left, T right, T top, T bottom, T zNear = -1.0, T zFar = 1.0); + static Matrix4 Perspective(T angle, T ratio, T zNear, T zFar); + static Matrix4 Rotate(const Quaternion& rotation); + static Matrix4 Scale(const Vector3& scale); + static Matrix4 Translate(const Vector3& translation); + static Matrix4 Transform(const Vector3& translation, const Quaternion& rotation); + static Matrix4 Transform(const Vector3& translation, const Quaternion& rotation, const Vector3& scale); + static Matrix4 ViewMatrix(const Vector3& translation, const Quaternion& rotation); + static Matrix4 Zero(); -template std::ostream& operator<<(std::ostream& out, const NzMatrix4& matrix); + T m11, m12, m13, m14, + m21, m22, m23, m24, + m31, m32, m33, m34, + m41, m42, m43, m44; + }; -template NzMatrix4 operator*(T scale, const NzMatrix4& matrix); + typedef Matrix4 Matrix4d; + typedef Matrix4 Matrix4f; +} + +template std::ostream& operator<<(std::ostream& out, const Nz::Matrix4& matrix); + +template Nz::Matrix4 operator*(T scale, const Nz::Matrix4& matrix); -typedef NzMatrix4 NzMatrix4d; -typedef NzMatrix4 NzMatrix4f; #include diff --git a/include/Nazara/Math/Matrix4.inl b/include/Nazara/Math/Matrix4.inl index 208a316a3..325f52498 100644 --- a/include/Nazara/Math/Matrix4.inl +++ b/include/Nazara/Math/Matrix4.inl @@ -18,1095 +18,1098 @@ #define F(a) static_cast(a) -template -NzMatrix4::NzMatrix4(T r11, T r12, T r13, T r14, - T r21, T r22, T r23, T r24, - T r31, T r32, T r33, T r34, - T r41, T r42, T r43, T r44) +namespace Nz { - Set(r11, r12, r13, r14, - r21, r22, r23, r24, - r31, r32, r33, r34, - r41, r42, r43, r44); -} - -template -NzMatrix4::NzMatrix4(const T matrix[16]) -{ - Set(matrix); -} - -template -template -NzMatrix4::NzMatrix4(const NzMatrix4& matrix) -{ - Set(matrix); -} - -template -NzMatrix4& NzMatrix4::ApplyRotation(const NzQuaternion& rotation) -{ - return Concatenate(NzMatrix4::Rotate(rotation)); -} - -template -NzMatrix4& NzMatrix4::ApplyScale(const NzVector3& scale) -{ - m11 *= scale.x; - m12 *= scale.x; - m13 *= scale.x; - - m21 *= scale.y; - m22 *= scale.y; - m23 *= scale.y; - - m31 *= scale.z; - m32 *= scale.z; - m33 *= scale.z; - - return *this; -} - -template -NzMatrix4& NzMatrix4::ApplyTranslation(const NzVector3& translation) -{ - m41 += translation.x; - m42 += translation.y; - m43 += translation.z; - - return *this; -} - -template -NzMatrix4& NzMatrix4::Concatenate(const NzMatrix4& matrix) -{ - #if NAZARA_MATH_MATRIX4_CHECK_AFFINE - if (IsAffine() && matrix.IsAffine()) - return ConcatenateAffine(matrix); - #endif - - return Set(m11*matrix.m11 + m12*matrix.m21 + m13*matrix.m31 + m14*matrix.m41, - m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32 + m14*matrix.m42, - m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33 + m14*matrix.m43, - m11*matrix.m14 + m12*matrix.m24 + m13*matrix.m34 + m14*matrix.m44, - - m21*matrix.m11 + m22*matrix.m21 + m23*matrix.m31 + m24*matrix.m41, - m21*matrix.m12 + m22*matrix.m22 + m23*matrix.m32 + m24*matrix.m42, - m21*matrix.m13 + m22*matrix.m23 + m23*matrix.m33 + m24*matrix.m43, - m21*matrix.m14 + m22*matrix.m24 + m23*matrix.m34 + m24*matrix.m44, - - m31*matrix.m11 + m32*matrix.m21 + m33*matrix.m31 + m34*matrix.m41, - m31*matrix.m12 + m32*matrix.m22 + m33*matrix.m32 + m34*matrix.m42, - m31*matrix.m13 + m32*matrix.m23 + m33*matrix.m33 + m34*matrix.m43, - m31*matrix.m14 + m32*matrix.m24 + m33*matrix.m34 + m34*matrix.m44, - - m41*matrix.m11 + m42*matrix.m21 + m43*matrix.m31 + m44*matrix.m41, - m41*matrix.m12 + m42*matrix.m22 + m43*matrix.m32 + m44*matrix.m42, - m41*matrix.m13 + m42*matrix.m23 + m43*matrix.m33 + m44*matrix.m43, - m41*matrix.m14 + m42*matrix.m24 + m43*matrix.m34 + m44*matrix.m44); -} - -template -NzMatrix4& NzMatrix4::ConcatenateAffine(const NzMatrix4& matrix) -{ - #ifdef NAZARA_DEBUG - if (!IsAffine()) + template + Matrix4::Matrix4(T r11, T r12, T r13, T r14, + T r21, T r22, T r23, T r24, + T r31, T r32, T r33, T r34, + T r41, T r42, T r43, T r44) { - NazaraWarning("First matrix not affine"); - return Concatenate(matrix); + Set(r11, r12, r13, r14, + r21, r22, r23, r24, + r31, r32, r33, r34, + r41, r42, r43, r44); } - if (!matrix.IsAffine()) + template + Matrix4::Matrix4(const T matrix[16]) { - NazaraWarning("Second matrix not affine"); - return Concatenate(matrix); - } - #endif - - return Set(m11*matrix.m11 + m12*matrix.m21 + m13*matrix.m31, - m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32, - m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33, - F(0.0), - - m21*matrix.m11 + m22*matrix.m21 + m23*matrix.m31, - m21*matrix.m12 + m22*matrix.m22 + m23*matrix.m32, - m21*matrix.m13 + m22*matrix.m23 + m23*matrix.m33, - F(0.0), - - m31*matrix.m11 + m32*matrix.m21 + m33*matrix.m31, - m31*matrix.m12 + m32*matrix.m22 + m33*matrix.m32, - m31*matrix.m13 + m32*matrix.m23 + m33*matrix.m33, - F(0.0), - - m41*matrix.m11 + m42*matrix.m21 + m43*matrix.m31 + matrix.m41, - m41*matrix.m12 + m42*matrix.m22 + m43*matrix.m32 + matrix.m42, - m41*matrix.m13 + m42*matrix.m23 + m43*matrix.m33 + matrix.m43, - F(1.0)); -} - -template -NzVector4 NzMatrix4::GetColumn(unsigned int column) const -{ - ///FIXME: Est-ce une bonne idée de gérer la matrice de cette façon ? - - #if NAZARA_MATH_SAFE - if (column > 3) - { - NzStringStream ss; - ss << "Row out of range: (" << column << ") > 3"; - - throw std::out_of_range(ss.ToString()); - } - #endif - - T* ptr = (&m11) + column*4; - return NzVector4(ptr); -} - -template -T NzMatrix4::GetDeterminant() const -{ - T A = m22*(m33*m44 - m43*m34) - m32*(m23*m44 - m43*m24) + m42*(m23*m34 - m33*m24); - T B = m12*(m33*m44 - m43*m34) - m32*(m13*m44 - m43*m14) + m42*(m13*m34 - m33*m14); - T C = m12*(m23*m44 - m43*m24) - m22*(m13*m44 - m43*m14) + m42*(m13*m24 - m23*m14); - T D = m12*(m23*m34 - m33*m24) - m22*(m13*m34 - m33*m14) + m32*(m13*m24 - m23*m14); - - return m11*A - m21*B + m31*C - m41*D; -} - -template -T NzMatrix4::GetDeterminantAffine() const -{ - T A = m22*m33 - m32*m23; - T B = m12*m33 - m32*m13; - T C = m12*m23 - m22*m13; - - return m11*A - m21*B + m31*C; -} - -template -bool NzMatrix4::GetInverse(NzMatrix4* dest) const -{ - ///DOC: Il est possible d'appeler cette méthode avec la même matrice en argument qu'en appelant - #ifdef NAZARA_DEBUG - if (!dest) - { - NazaraError("Destination matrix must be valid"); - return false; - } - #endif - - T det = GetDeterminant(); - if (!NzNumberEquals(det, F(0.0))) - { - // http://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix - T inv[16]; - inv[0] = m22 * m33 * m44 - - m22 * m34 * m43 - - m32 * m23 * m44 + - m32 * m24 * m43 + - m42 * m23 * m34 - - m42 * m24 * m33; - - inv[1] = -m12 * m33 * m44 + - m12 * m34 * m43 + - m32 * m13 * m44 - - m32 * m14 * m43 - - m42 * m13 * m34 + - m42 * m14 * m33; - - inv[2] = m12 * m23 * m44 - - m12 * m24 * m43 - - m22 * m13 * m44 + - m22 * m14 * m43 + - m42 * m13 * m24 - - m42 * m14 * m23; - - inv[3] = -m12 * m23 * m34 + - m12 * m24 * m33 + - m22 * m13 * m34 - - m22 * m14 * m33 - - m32 * m13 * m24 + - m32 * m14 * m23; - - inv[4] = -m21 * m33 * m44 + - m21 * m34 * m43 + - m31 * m23 * m44 - - m31 * m24 * m43 - - m41 * m23 * m34 + - m41 * m24 * m33; - - inv[5] = m11 * m33 * m44 - - m11 * m34 * m43 - - m31 * m13 * m44 + - m31 * m14 * m43 + - m41 * m13 * m34 - - m41 * m14 * m33; - - inv[6] = -m11 * m23 * m44 + - m11 * m24 * m43 + - m21 * m13 * m44 - - m21 * m14 * m43 - - m41 * m13 * m24 + - m41 * m14 * m23; - - inv[7] = m11 * m23 * m34 - - m11 * m24 * m33 - - m21 * m13 * m34 + - m21 * m14 * m33 + - m31 * m13 * m24 - - m31 * m14 * m23; - - inv[8] = m21 * m32 * m44 - - m21 * m34 * m42 - - m31 * m22 * m44 + - m31 * m24 * m42 + - m41 * m22 * m34 - - m41 * m24 * m32; - - inv[9] = -m11 * m32 * m44 + - m11 * m34 * m42 + - m31 * m12 * m44 - - m31 * m14 * m42 - - m41 * m12 * m34 + - m41 * m14 * m32; - - inv[10] = m11 * m22 * m44 - - m11 * m24 * m42 - - m21 * m12 * m44 + - m21 * m14 * m42 + - m41 * m12 * m24 - - m41 * m14 * m22; - - inv[11] = -m11 * m22 * m34 + - m11 * m24 * m32 + - m21 * m12 * m34 - - m21 * m14 * m32 - - m31 * m12 * m24 + - m31 * m14 * m22; - - inv[12] = -m21 * m32 * m43 + - m21 * m33 * m42 + - m31 * m22 * m43 - - m31 * m23 * m42 - - m41 * m22 * m33 + - m41 * m23 * m32; - - inv[13] = m11 * m32 * m43 - - m11 * m33 * m42 - - m31 * m12 * m43 + - m31 * m13 * m42 + - m41 * m12 * m33 - - m41 * m13 * m32; - - inv[14] = -m11 * m22 * m43 + - m11 * m23 * m42 + - m21 * m12 * m43 - - m21 * m13 * m42 - - m41 * m12 * m23 + - m41 * m13 * m22; - - inv[15] = m11 * m22 * m33 - - m11 * m23 * m32 - - m21 * m12 * m33 + - m21 * m13 * m32 + - m31 * m12 * m23 - - m31 * m13 * m22; - - T invDet = F(1.0) / det; - for (unsigned int i = 0; i < 16; ++i) - inv[i] *= invDet; - - dest->Set(inv); - return true; - } - else - return false; -} - -template -bool NzMatrix4::GetInverseAffine(NzMatrix4* dest) const -{ - ///DOC: Il est possible d'appeler cette méthode avec la même matrice en argument qu'en appelant - #if NAZARA_MATH_SAFE - if (!IsAffine()) - { - NazaraError("Matrix is not affine"); - return false; + Set(matrix); } - if (!dest) + template + template + Matrix4::Matrix4(const Matrix4& matrix) { - NazaraError("Destination matrix must be valid"); - return false; + Set(matrix); } - #endif - T det = GetDeterminantAffine(); - if (!NzNumberEquals(det, F(0.0))) + template + Matrix4& Matrix4::ApplyRotation(const Quaternion& rotation) { - // http://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix - T inv[16]; - inv[0] = m22 * m33 - - m32 * m23; - - inv[1] = -m12 * m33 + - m32 * m13; - - inv[2] = m12 * m23 - - m22 * m13; - - inv[3] = F(0.0); - - inv[4] = -m21 * m33 + - m31 * m23; - - inv[5] = m11 * m33 - - m31 * m13; - - inv[6] = -m11 * m23 + - m21 * m13; - - inv[7] = F(0.0); - - inv[8] = m21 * m32 - - m31 * m22; - - inv[9] = -m11 * m32 + - m31 * m12; - - inv[10] = m11 * m22 - - m21 * m12; - - inv[11] = F(0.0); - - inv[12] = -m21 * m32 * m43 + - m21 * m33 * m42 + - m31 * m22 * m43 - - m31 * m23 * m42 - - m41 * m22 * m33 + - m41 * m23 * m32; - - inv[13] = m11 * m32 * m43 - - m11 * m33 * m42 - - m31 * m12 * m43 + - m31 * m13 * m42 + - m41 * m12 * m33 - - m41 * m13 * m32; - - inv[14] = -m11 * m22 * m43 + - m11 * m23 * m42 + - m21 * m12 * m43 - - m21 * m13 * m42 - - m41 * m12 * m23 + - m41 * m13 * m22; - - T invDet = F(1.0) / det; - for (unsigned int i = 0; i < 16; ++i) - inv[i] *= invDet; - - inv[15] = F(1.0); - - dest->Set(inv); - return true; + return Concatenate(Matrix4::Rotate(rotation)); } - else - return false; -} -template -NzQuaternion NzMatrix4::GetRotation() const -{ - // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ - NzQuaternion quat; - - T trace = m11 + m22 + m33; - if (trace > F(0.0)) + template + Matrix4& Matrix4::ApplyScale(const Vector3& scale) { - T s = F(0.5)/std::sqrt(trace + F(1.0)); - quat.w = F(0.25) / s; - quat.x = (m23 - m32) * s; - quat.y = (m31 - m13) * s; - quat.z = (m12 - m21) * s; + m11 *= scale.x; + m12 *= scale.x; + m13 *= scale.x; + + m21 *= scale.y; + m22 *= scale.y; + m23 *= scale.y; + + m31 *= scale.z; + m32 *= scale.z; + m33 *= scale.z; + + return *this; } - else + + template + Matrix4& Matrix4::ApplyTranslation(const Vector3& translation) { - if (m11 > m22 && m11 > m33) + m41 += translation.x; + m42 += translation.y; + m43 += translation.z; + + return *this; + } + + template + Matrix4& Matrix4::Concatenate(const Matrix4& matrix) + { + #if NAZARA_MATH_MATRIX4_CHECK_AFFINE + if (IsAffine() && matrix.IsAffine()) + return ConcatenateAffine(matrix); + #endif + + return Set(m11*matrix.m11 + m12*matrix.m21 + m13*matrix.m31 + m14*matrix.m41, + m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32 + m14*matrix.m42, + m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33 + m14*matrix.m43, + m11*matrix.m14 + m12*matrix.m24 + m13*matrix.m34 + m14*matrix.m44, + + m21*matrix.m11 + m22*matrix.m21 + m23*matrix.m31 + m24*matrix.m41, + m21*matrix.m12 + m22*matrix.m22 + m23*matrix.m32 + m24*matrix.m42, + m21*matrix.m13 + m22*matrix.m23 + m23*matrix.m33 + m24*matrix.m43, + m21*matrix.m14 + m22*matrix.m24 + m23*matrix.m34 + m24*matrix.m44, + + m31*matrix.m11 + m32*matrix.m21 + m33*matrix.m31 + m34*matrix.m41, + m31*matrix.m12 + m32*matrix.m22 + m33*matrix.m32 + m34*matrix.m42, + m31*matrix.m13 + m32*matrix.m23 + m33*matrix.m33 + m34*matrix.m43, + m31*matrix.m14 + m32*matrix.m24 + m33*matrix.m34 + m34*matrix.m44, + + m41*matrix.m11 + m42*matrix.m21 + m43*matrix.m31 + m44*matrix.m41, + m41*matrix.m12 + m42*matrix.m22 + m43*matrix.m32 + m44*matrix.m42, + m41*matrix.m13 + m42*matrix.m23 + m43*matrix.m33 + m44*matrix.m43, + m41*matrix.m14 + m42*matrix.m24 + m43*matrix.m34 + m44*matrix.m44); + } + + template + Matrix4& Matrix4::ConcatenateAffine(const Matrix4& matrix) + { + #ifdef NAZARA_DEBUG + if (!IsAffine()) { - T s = F(2.0) * std::sqrt(F(1.0) + m11 - m22 - m33); - - quat.w = (m23 - m32) / s; - quat.x = F(0.25) * s; - quat.y = (m21 + m12) / s; - quat.z = (m31 + m13) / s; + NazaraWarning("First matrix not affine"); + return Concatenate(matrix); } - else if (m22 > m33) - { - T s = F(2.0) * std::sqrt(F(1.0) + m22 - m11 - m33); - quat.w = (m31 - m13) / s; - quat.x = (m21 + m12) / s; - quat.y = F(0.25) * s; - quat.z = (m32 + m23) / s; + if (!matrix.IsAffine()) + { + NazaraWarning("Second matrix not affine"); + return Concatenate(matrix); + } + #endif + + return Set(m11*matrix.m11 + m12*matrix.m21 + m13*matrix.m31, + m11*matrix.m12 + m12*matrix.m22 + m13*matrix.m32, + m11*matrix.m13 + m12*matrix.m23 + m13*matrix.m33, + F(0.0), + + m21*matrix.m11 + m22*matrix.m21 + m23*matrix.m31, + m21*matrix.m12 + m22*matrix.m22 + m23*matrix.m32, + m21*matrix.m13 + m22*matrix.m23 + m23*matrix.m33, + F(0.0), + + m31*matrix.m11 + m32*matrix.m21 + m33*matrix.m31, + m31*matrix.m12 + m32*matrix.m22 + m33*matrix.m32, + m31*matrix.m13 + m32*matrix.m23 + m33*matrix.m33, + F(0.0), + + m41*matrix.m11 + m42*matrix.m21 + m43*matrix.m31 + matrix.m41, + m41*matrix.m12 + m42*matrix.m22 + m43*matrix.m32 + matrix.m42, + m41*matrix.m13 + m42*matrix.m23 + m43*matrix.m33 + matrix.m43, + F(1.0)); + } + + template + Vector4 Matrix4::GetColumn(unsigned int column) const + { + ///FIXME: Est-ce une bonne idée de gérer la matrice de cette façon ? + + #if NAZARA_MATH_SAFE + if (column > 3) + { + StringStream ss; + ss << "Row out of range: (" << column << ") > 3"; + + throw std::out_of_range(ss.ToString()); + } + #endif + + T* ptr = (&m11) + column*4; + return Vector4(ptr); + } + + template + T Matrix4::GetDeterminant() const + { + T A = m22*(m33*m44 - m43*m34) - m32*(m23*m44 - m43*m24) + m42*(m23*m34 - m33*m24); + T B = m12*(m33*m44 - m43*m34) - m32*(m13*m44 - m43*m14) + m42*(m13*m34 - m33*m14); + T C = m12*(m23*m44 - m43*m24) - m22*(m13*m44 - m43*m14) + m42*(m13*m24 - m23*m14); + T D = m12*(m23*m34 - m33*m24) - m22*(m13*m34 - m33*m14) + m32*(m13*m24 - m23*m14); + + return m11*A - m21*B + m31*C - m41*D; + } + + template + T Matrix4::GetDeterminantAffine() const + { + T A = m22*m33 - m32*m23; + T B = m12*m33 - m32*m13; + T C = m12*m23 - m22*m13; + + return m11*A - m21*B + m31*C; + } + + template + bool Matrix4::GetInverse(Matrix4* dest) const + { + ///DOC: Il est possible d'appeler cette méthode avec la même matrice en argument qu'en appelant + #ifdef NAZARA_DEBUG + if (!dest) + { + NazaraError("Destination matrix must be valid"); + return false; + } + #endif + + T det = GetDeterminant(); + if (!NumberEquals(det, F(0.0))) + { + // http://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix + T inv[16]; + inv[0] = m22 * m33 * m44 - + m22 * m34 * m43 - + m32 * m23 * m44 + + m32 * m24 * m43 + + m42 * m23 * m34 - + m42 * m24 * m33; + + inv[1] = -m12 * m33 * m44 + + m12 * m34 * m43 + + m32 * m13 * m44 - + m32 * m14 * m43 - + m42 * m13 * m34 + + m42 * m14 * m33; + + inv[2] = m12 * m23 * m44 - + m12 * m24 * m43 - + m22 * m13 * m44 + + m22 * m14 * m43 + + m42 * m13 * m24 - + m42 * m14 * m23; + + inv[3] = -m12 * m23 * m34 + + m12 * m24 * m33 + + m22 * m13 * m34 - + m22 * m14 * m33 - + m32 * m13 * m24 + + m32 * m14 * m23; + + inv[4] = -m21 * m33 * m44 + + m21 * m34 * m43 + + m31 * m23 * m44 - + m31 * m24 * m43 - + m41 * m23 * m34 + + m41 * m24 * m33; + + inv[5] = m11 * m33 * m44 - + m11 * m34 * m43 - + m31 * m13 * m44 + + m31 * m14 * m43 + + m41 * m13 * m34 - + m41 * m14 * m33; + + inv[6] = -m11 * m23 * m44 + + m11 * m24 * m43 + + m21 * m13 * m44 - + m21 * m14 * m43 - + m41 * m13 * m24 + + m41 * m14 * m23; + + inv[7] = m11 * m23 * m34 - + m11 * m24 * m33 - + m21 * m13 * m34 + + m21 * m14 * m33 + + m31 * m13 * m24 - + m31 * m14 * m23; + + inv[8] = m21 * m32 * m44 - + m21 * m34 * m42 - + m31 * m22 * m44 + + m31 * m24 * m42 + + m41 * m22 * m34 - + m41 * m24 * m32; + + inv[9] = -m11 * m32 * m44 + + m11 * m34 * m42 + + m31 * m12 * m44 - + m31 * m14 * m42 - + m41 * m12 * m34 + + m41 * m14 * m32; + + inv[10] = m11 * m22 * m44 - + m11 * m24 * m42 - + m21 * m12 * m44 + + m21 * m14 * m42 + + m41 * m12 * m24 - + m41 * m14 * m22; + + inv[11] = -m11 * m22 * m34 + + m11 * m24 * m32 + + m21 * m12 * m34 - + m21 * m14 * m32 - + m31 * m12 * m24 + + m31 * m14 * m22; + + inv[12] = -m21 * m32 * m43 + + m21 * m33 * m42 + + m31 * m22 * m43 - + m31 * m23 * m42 - + m41 * m22 * m33 + + m41 * m23 * m32; + + inv[13] = m11 * m32 * m43 - + m11 * m33 * m42 - + m31 * m12 * m43 + + m31 * m13 * m42 + + m41 * m12 * m33 - + m41 * m13 * m32; + + inv[14] = -m11 * m22 * m43 + + m11 * m23 * m42 + + m21 * m12 * m43 - + m21 * m13 * m42 - + m41 * m12 * m23 + + m41 * m13 * m22; + + inv[15] = m11 * m22 * m33 - + m11 * m23 * m32 - + m21 * m12 * m33 + + m21 * m13 * m32 + + m31 * m12 * m23 - + m31 * m13 * m22; + + T invDet = F(1.0) / det; + for (unsigned int i = 0; i < 16; ++i) + inv[i] *= invDet; + + dest->Set(inv); + return true; + } + else + return false; + } + + template + bool Matrix4::GetInverseAffine(Matrix4* dest) const + { + ///DOC: Il est possible d'appeler cette méthode avec la même matrice en argument qu'en appelant + #if NAZARA_MATH_SAFE + if (!IsAffine()) + { + NazaraError("Matrix is not affine"); + return false; + } + + if (!dest) + { + NazaraError("Destination matrix must be valid"); + return false; + } + #endif + + T det = GetDeterminantAffine(); + if (!NumberEquals(det, F(0.0))) + { + // http://stackoverflow.com/questions/1148309/inverting-a-4x4-matrix + T inv[16]; + inv[0] = m22 * m33 - + m32 * m23; + + inv[1] = -m12 * m33 + + m32 * m13; + + inv[2] = m12 * m23 - + m22 * m13; + + inv[3] = F(0.0); + + inv[4] = -m21 * m33 + + m31 * m23; + + inv[5] = m11 * m33 - + m31 * m13; + + inv[6] = -m11 * m23 + + m21 * m13; + + inv[7] = F(0.0); + + inv[8] = m21 * m32 - + m31 * m22; + + inv[9] = -m11 * m32 + + m31 * m12; + + inv[10] = m11 * m22 - + m21 * m12; + + inv[11] = F(0.0); + + inv[12] = -m21 * m32 * m43 + + m21 * m33 * m42 + + m31 * m22 * m43 - + m31 * m23 * m42 - + m41 * m22 * m33 + + m41 * m23 * m32; + + inv[13] = m11 * m32 * m43 - + m11 * m33 * m42 - + m31 * m12 * m43 + + m31 * m13 * m42 + + m41 * m12 * m33 - + m41 * m13 * m32; + + inv[14] = -m11 * m22 * m43 + + m11 * m23 * m42 + + m21 * m12 * m43 - + m21 * m13 * m42 - + m41 * m12 * m23 + + m41 * m13 * m22; + + T invDet = F(1.0) / det; + for (unsigned int i = 0; i < 16; ++i) + inv[i] *= invDet; + + inv[15] = F(1.0); + + dest->Set(inv); + return true; + } + else + return false; + } + + template + Quaternion Matrix4::GetRotation() const + { + // http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ + Quaternion quat; + + T trace = m11 + m22 + m33; + if (trace > F(0.0)) + { + T s = F(0.5)/std::sqrt(trace + F(1.0)); + quat.w = F(0.25) / s; + quat.x = (m23 - m32) * s; + quat.y = (m31 - m13) * s; + quat.z = (m12 - m21) * s; } else { - T s = F(2.0) * std::sqrt(F(1.0) + m33 - m11 - m22); + if (m11 > m22 && m11 > m33) + { + T s = F(2.0) * std::sqrt(F(1.0) + m11 - m22 - m33); - quat.w = (m12 - m21) / s; - quat.x = (m31 + m13) / s; - quat.y = (m32 + m23) / s; - quat.z = F(0.25) * s; + quat.w = (m23 - m32) / s; + quat.x = F(0.25) * s; + quat.y = (m21 + m12) / s; + quat.z = (m31 + m13) / s; + } + else if (m22 > m33) + { + T s = F(2.0) * std::sqrt(F(1.0) + m22 - m11 - m33); + + quat.w = (m31 - m13) / s; + quat.x = (m21 + m12) / s; + quat.y = F(0.25) * s; + quat.z = (m32 + m23) / s; + } + else + { + T s = F(2.0) * std::sqrt(F(1.0) + m33 - m11 - m22); + + quat.w = (m12 - m21) / s; + quat.x = (m31 + m13) / s; + quat.y = (m32 + m23) / s; + quat.z = F(0.25) * s; + } } + + return quat; } - return quat; -} - -template -NzVector4 NzMatrix4::GetRow(unsigned int row) const -{ - ///FIXME: Est-ce une bonne idée de gérer la matrice de cette façon ? - - #if NAZARA_MATH_SAFE - if (row > 3) + template + Vector4 Matrix4::GetRow(unsigned int row) const { - NzStringStream ss; - ss << "Column out of range: (" << row << ") > 3"; + ///FIXME: Est-ce une bonne idée de gérer la matrice de cette façon ? - throw std::out_of_range(ss.ToString()); + #if NAZARA_MATH_SAFE + if (row > 3) + { + StringStream ss; + ss << "Column out of range: (" << row << ") > 3"; + + throw std::out_of_range(ss.ToString()); + } + #endif + + T* ptr = &m11; + return Vector4(ptr[row], ptr[row+4], ptr[row+8], ptr[row+12]); } - #endif - T* ptr = &m11; - return NzVector4(ptr[row], ptr[row+4], ptr[row+8], ptr[row+12]); -} - -template -NzVector3 NzMatrix4::GetScale() const -{ - NzVector3 squaredScale = GetSquaredScale(); - return NzVector3(std::sqrt(squaredScale.x), std::sqrt(squaredScale.y), std::sqrt(squaredScale.z)); -} - -template -NzVector3 NzMatrix4::GetSquaredScale() const -{ - return NzVector3(m11*m11 + m21*m21 + m31*m31, - m12*m12 + m22*m22 + m32*m32, - m13*m13 + m23*m23 + m33*m33); -} - -template -NzVector3 NzMatrix4::GetTranslation() const -{ - return NzVector3(m41, m42, m43); -} - -template -void NzMatrix4::GetTransposed(NzMatrix4* dest) const -{ - dest->Set(m11, m21, m31, m41, - m12, m22, m32, m42, - m13, m23, m33, m43, - m14, m24, m34, m44); -} - -template -bool NzMatrix4::HasNegativeScale() const -{ - return GetDeterminant() < F(0.0); -} - -template -bool NzMatrix4::HasScale() const -{ - T t = m11*m11 + m21*m21 + m31*m31; - if (!NzNumberEquals(t, F(1.0))) - return true; - - t = m12*m12 + m22*m22 + m32*m32; - if (!NzNumberEquals(t, F(1.0))) - return true; - - t = m13*m13 + m23*m23 + m33*m33; - if (!NzNumberEquals(t, F(1.0))) - return true; - - return false; -} - -template -NzMatrix4& NzMatrix4::Inverse(bool* succeeded) -{ - bool result = GetInverse(this); - if (succeeded) - *succeeded = result; - - return *this; -} - -template -NzMatrix4& NzMatrix4::InverseAffine(bool* succeeded) -{ - bool result = GetInverseAffine(this); - if (succeeded) - *succeeded = result; - - return *this; -} - -template -bool NzMatrix4::IsAffine() const -{ - return NzNumberEquals(m14, F(0.0)) && - NzNumberEquals(m24, F(0.0)) && - NzNumberEquals(m34, F(0.0)) && - NzNumberEquals(m44, F(1.0)); -} - -template -bool NzMatrix4::IsIdentity() const -{ - return (NzNumberEquals(m11, F(1.0)) && NzNumberEquals(m12, F(0.0)) && NzNumberEquals(m13, F(0.0)) && NzNumberEquals(m14, F(0.0)) && - NzNumberEquals(m21, F(0.0)) && NzNumberEquals(m22, F(1.0)) && NzNumberEquals(m23, F(0.0)) && NzNumberEquals(m24, F(0.0)) && - NzNumberEquals(m31, F(0.0)) && NzNumberEquals(m32, F(0.0)) && NzNumberEquals(m33, F(1.0)) && NzNumberEquals(m34, F(0.0)) && - NzNumberEquals(m41, F(0.0)) && NzNumberEquals(m42, F(0.0)) && NzNumberEquals(m43, F(0.0)) && NzNumberEquals(m44, F(1.0))); -} - -template -NzMatrix4& NzMatrix4::MakeIdentity() -{ - Set(F(1.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(1.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(1.0), F(0.0), - F(0.0), F(0.0), F(0.0), F(1.0)); - - return *this; -} - -template -NzMatrix4& NzMatrix4::MakeLookAt(const NzVector3& eye, const NzVector3& target, const NzVector3& up) -{ - NzVector3 f = NzVector3::Normalize(target - eye); - NzVector3 s = NzVector3::Normalize(f.CrossProduct(up)); - NzVector3 u = s.CrossProduct(f); - - Set(s.x, u.x, -f.x, T(0.0), - s.y, u.y, -f.y, T(0.0), - s.z, u.z, -f.z, T(0.0), - -s.DotProduct(eye), -u.DotProduct(eye), f.DotProduct(eye), T(1.0)); - - return *this; -} - -template -NzMatrix4& NzMatrix4::MakeOrtho(T left, T right, T top, T bottom, T zNear, T zFar) -{ - // http://msdn.microsoft.com/en-us/library/windows/desktop/bb204942(v=vs.85).aspx - Set(F(2.0) / (right - left), F(0.0), F(0.0), F(0.0), - F(0.0), F(2.0) / (top - bottom), F(0.0), F(0.0), - F(0.0), F(0.0), F(1.0) / (zNear - zFar), F(0.0), - (left + right) / (left - right), (top + bottom) / (bottom - top), zNear/(zNear - zFar), F(1.0)); - - return *this; -} - -template -NzMatrix4& NzMatrix4::MakePerspective(T angle, T ratio, T zNear, T zFar) -{ - // http://msdn.microsoft.com/en-us/library/windows/desktop/bb204945(v=vs.85).aspx - #if NAZARA_MATH_ANGLE_RADIAN - angle /= F(2.0); - #else - angle = NzDegreeToRadian(angle/F(2.0)); - #endif - - T yScale = std::tan(M_PI_2 - angle); - - Set(yScale / ratio, F(0.0), F(0.0), F(0.0), - F(0.0), yScale, F(0.0), F(0.0), - F(0.0), F(0.0), - (zFar + zNear) / (zFar - zNear), F(-1.0), - F(0.0), F(0.0), F(-2.0) * (zNear * zFar) / (zFar - zNear), F(0.0)); - - return *this; -} - -template -NzMatrix4& NzMatrix4::MakeRotation(const NzQuaternion& rotation) -{ - SetRotation(rotation); - - // On complète la matrice - m14 = F(0.0); - m24 = F(0.0); - m34 = F(0.0); - m41 = F(0.0); - m42 = F(0.0); - m43 = F(0.0); - m44 = F(1.0); - - return *this; -} - -template -NzMatrix4& NzMatrix4::MakeScale(const NzVector3& scale) -{ - Set(scale.x, F(0.0), F(0.0), F(0.0), - F(0.0), scale.y, F(0.0), F(0.0), - F(0.0), F(0.0), scale.z, F(0.0), - F(0.0), F(0.0), F(0.0), F(1.0)); - - return *this; -} - -template -NzMatrix4& NzMatrix4::MakeTranslation(const NzVector3& translation) -{ - Set(F(1.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(1.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(1.0), F(0.0), - translation.x, translation.y, translation.z, F(1.0)); - - return *this; -} - -template -NzMatrix4& NzMatrix4::MakeTransform(const NzVector3& translation, const NzQuaternion& rotation) -{ - // La rotation et la translation peuvent être appliquées directement - SetRotation(rotation); - SetTranslation(translation); - - // On complète la matrice (les transformations sont affines) - m14 = F(0.0); - m24 = F(0.0); - m34 = F(0.0); - m44 = F(1.0); - - return *this; -} - -template -NzMatrix4& NzMatrix4::MakeTransform(const NzVector3& translation, const NzQuaternion& rotation, const NzVector3& scale) -{ - MakeTransform(translation, rotation); - - // Ensuite on fait une mise à l'échelle des valeurs déjà présentes - return ApplyScale(scale); -} - -template -NzMatrix4& NzMatrix4::MakeViewMatrix(const NzVector3& translation, const NzQuaternion& rotation) -{ - // Une matrice de vue doit appliquer une transformation opposée à la matrice "monde" - NzQuaternion invRot = rotation.GetConjugate(); // Inverse de la rotation - - return MakeTransform(-(invRot * translation), invRot); -} - -template -NzMatrix4& NzMatrix4::MakeZero() -{ - Set(F(0.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(0.0), F(0.0), - F(0.0), F(0.0), F(0.0), F(0.0)); - - return *this; -} - -template -NzMatrix4& NzMatrix4::Set(T r11, T r12, T r13, T r14, - T r21, T r22, T r23, T r24, - T r31, T r32, T r33, T r34, - T r41, T r42, T r43, T r44) -{ - m11 = r11; - m12 = r12; - m13 = r13; - m14 = r14; - m21 = r21; - m22 = r22; - m23 = r23; - m24 = r24; - m31 = r31; - m32 = r32; - m33 = r33; - m34 = r34; - m41 = r41; - m42 = r42; - m43 = r43; - m44 = r44; - - return *this; -} - -template -NzMatrix4& NzMatrix4::Set(const T matrix[16]) -{ - // Ici nous sommes certains de la continuité des éléments en mémoire - std::memcpy(&m11, matrix, 16*sizeof(T)); - - return *this; -} - -template -NzMatrix4& NzMatrix4::Set(const NzMatrix4& matrix) -{ - std::memcpy(this, &matrix, sizeof(NzMatrix4)); - - return *this; -} - -template -template -NzMatrix4& NzMatrix4::Set(const NzMatrix4& matrix) -{ - Set(F(matrix[ 0]), F(matrix[ 1]), F(matrix[ 2]), F(matrix[ 3]), - F(matrix[ 4]), F(matrix[ 5]), F(matrix[ 6]), F(matrix[ 7]), - F(matrix[ 8]), F(matrix[ 9]), F(matrix[10]), F(matrix[11]), - F(matrix[12]), F(matrix[13]), F(matrix[14]), F(matrix[15])); - - return *this; -} - -template -NzMatrix4& NzMatrix4::SetRotation(const NzQuaternion& rotation) -{ - T tx = rotation.x + rotation.x; - T ty = rotation.y + rotation.y; - T tz = rotation.z + rotation.z; - T twx = tx * rotation.w; - T twy = ty * rotation.w; - T twz = tz * rotation.w; - T txx = tx * rotation.x; - T txy = ty * rotation.x; - T txz = tz * rotation.x; - T tyy = ty * rotation.y; - T tyz = tz * rotation.y; - T tzz = tz * rotation.z; - - m11 = F(1.0) - (tyy + tzz); - m12 = txy + twz; - m13 = txz - twy; - - m21 = txy - twz; - m22 = F(1.0) - (txx + tzz); - m23 = tyz + twx; - - m31 = txz + twy; - m32 = tyz - twx; - m33 = F(1.0) - (txx + tyy); - - return *this; -} - -template -NzMatrix4& NzMatrix4::SetScale(const NzVector3& scale) -{ - m11 = scale.x; - m22 = scale.y; - m33 = scale.z; - - return *this; -} - -template -NzMatrix4& NzMatrix4::SetTranslation(const NzVector3& translation) -{ - m41 = translation.x; - m42 = translation.y; - m43 = translation.z; - - return *this; -} - -template -NzString NzMatrix4::ToString() const -{ - NzStringStream ss; - return ss << "Matrix4(" << m11 << ", " << m12 << ", " << m13 << ", " << m14 << ",\n" - << " " << m21 << ", " << m22 << ", " << m23 << ", " << m24 << ",\n" - << " " << m31 << ", " << m32 << ", " << m33 << ", " << m34 << ",\n" - << " " << m41 << ", " << m42 << ", " << m43 << ", " << m44 << ')'; -} - -template -NzVector2 NzMatrix4::Transform(const NzVector2& vector, T z, T w) const -{ - return NzVector2(m11*vector.x + m21*vector.y + m31*z + m41*w, - m12*vector.x + m22*vector.y + m32*z + m42*w); -} - -template -NzVector3 NzMatrix4::Transform(const NzVector3& vector, T w) const -{ - return NzVector3(m11*vector.x + m21*vector.y + m31*vector.z + m41*w, - m12*vector.x + m22*vector.y + m32*vector.z + m42*w, - m13*vector.x + m23*vector.y + m33*vector.z + m43*w); -} - -template -NzVector4 NzMatrix4::Transform(const NzVector4& vector) const -{ - return NzVector4(m11*vector.x + m21*vector.y + m31*vector.z + m41*vector.w, - m12*vector.x + m22*vector.y + m32*vector.z + m42*vector.w, - m13*vector.x + m23*vector.y + m33*vector.z + m43*vector.w, - m14*vector.x + m24*vector.y + m34*vector.z + m44*vector.w); -} - -template -NzMatrix4& NzMatrix4::Transpose() -{ - std::swap(m12, m21); - std::swap(m13, m31); - std::swap(m14, m41); - std::swap(m23, m32); - std::swap(m24, m42); - std::swap(m34, m43); - - return *this; -} - -template -NzMatrix4::operator T*() -{ - return &m11; -} - -template -NzMatrix4::operator const T*() const -{ - return &m11; -} - -template -T& NzMatrix4::operator()(unsigned int x, unsigned int y) -{ - #if NAZARA_MATH_SAFE - if (x > 3 || y > 3) + template + Vector3 Matrix4::GetScale() const { - NzStringStream ss; - ss << "Index out of range: (" << x << ", " << y << ") > (3,3)"; - - throw std::out_of_range(ss.ToString()); + Vector3 squaredScale = GetSquaredScale(); + return Vector3(std::sqrt(squaredScale.x), std::sqrt(squaredScale.y), std::sqrt(squaredScale.z)); } - #endif - return (&m11)[y*4+x]; -} - -template -T NzMatrix4::operator()(unsigned int x, unsigned int y) const -{ - #if NAZARA_MATH_SAFE - if (x > 3 || y > 3) + template + Vector3 Matrix4::GetSquaredScale() const { - NzStringStream ss; - ss << "Index out of range: (" << x << ", " << y << ") > (3,3)"; - - NazaraError(ss); - throw std::out_of_range(ss.ToString()); + return Vector3(m11*m11 + m21*m21 + m31*m31, + m12*m12 + m22*m22 + m32*m32, + m13*m13 + m23*m23 + m33*m33); } - #endif - return (&m11)[y*4+x]; + template + Vector3 Matrix4::GetTranslation() const + { + return Vector3(m41, m42, m43); + } + + template + void Matrix4::GetTransposed(Matrix4* dest) const + { + dest->Set(m11, m21, m31, m41, + m12, m22, m32, m42, + m13, m23, m33, m43, + m14, m24, m34, m44); + } + + template + bool Matrix4::HasNegativeScale() const + { + return GetDeterminant() < F(0.0); + } + + template + bool Matrix4::HasScale() const + { + T t = m11*m11 + m21*m21 + m31*m31; + if (!NumberEquals(t, F(1.0))) + return true; + + t = m12*m12 + m22*m22 + m32*m32; + if (!NumberEquals(t, F(1.0))) + return true; + + t = m13*m13 + m23*m23 + m33*m33; + if (!NumberEquals(t, F(1.0))) + return true; + + return false; + } + + template + Matrix4& Matrix4::Inverse(bool* succeeded) + { + bool result = GetInverse(this); + if (succeeded) + *succeeded = result; + + return *this; + } + + template + Matrix4& Matrix4::InverseAffine(bool* succeeded) + { + bool result = GetInverseAffine(this); + if (succeeded) + *succeeded = result; + + return *this; + } + + template + bool Matrix4::IsAffine() const + { + return NumberEquals(m14, F(0.0)) && + NumberEquals(m24, F(0.0)) && + NumberEquals(m34, F(0.0)) && + NumberEquals(m44, F(1.0)); + } + + template + bool Matrix4::IsIdentity() const + { + return (NumberEquals(m11, F(1.0)) && NumberEquals(m12, F(0.0)) && NumberEquals(m13, F(0.0)) && NumberEquals(m14, F(0.0)) && + NumberEquals(m21, F(0.0)) && NumberEquals(m22, F(1.0)) && NumberEquals(m23, F(0.0)) && NumberEquals(m24, F(0.0)) && + NumberEquals(m31, F(0.0)) && NumberEquals(m32, F(0.0)) && NumberEquals(m33, F(1.0)) && NumberEquals(m34, F(0.0)) && + NumberEquals(m41, F(0.0)) && NumberEquals(m42, F(0.0)) && NumberEquals(m43, F(0.0)) && NumberEquals(m44, F(1.0))); + } + + template + Matrix4& Matrix4::MakeIdentity() + { + Set(F(1.0), F(0.0), F(0.0), F(0.0), + F(0.0), F(1.0), F(0.0), F(0.0), + F(0.0), F(0.0), F(1.0), F(0.0), + F(0.0), F(0.0), F(0.0), F(1.0)); + + return *this; + } + + template + Matrix4& Matrix4::MakeLookAt(const Vector3& eye, const Vector3& target, const Vector3& up) + { + Vector3 f = Vector3::Normalize(target - eye); + Vector3 s = Vector3::Normalize(f.CrossProduct(up)); + Vector3 u = s.CrossProduct(f); + + Set(s.x, u.x, -f.x, T(0.0), + s.y, u.y, -f.y, T(0.0), + s.z, u.z, -f.z, T(0.0), + -s.DotProduct(eye), -u.DotProduct(eye), f.DotProduct(eye), T(1.0)); + + return *this; + } + + template + Matrix4& Matrix4::MakeOrtho(T left, T right, T top, T bottom, T zNear, T zFar) + { + // http://msdn.microsoft.com/en-us/library/windows/desktop/bb204942(v=vs.85).aspx + Set(F(2.0) / (right - left), F(0.0), F(0.0), F(0.0), + F(0.0), F(2.0) / (top - bottom), F(0.0), F(0.0), + F(0.0), F(0.0), F(1.0) / (zNear - zFar), F(0.0), + (left + right) / (left - right), (top + bottom) / (bottom - top), zNear/(zNear - zFar), F(1.0)); + + return *this; + } + + template + Matrix4& Matrix4::MakePerspective(T angle, T ratio, T zNear, T zFar) + { + // http://msdn.microsoft.com/en-us/library/windows/desktop/bb204945(v=vs.85).aspx + #if NAZARA_MATH_ANGLE_RADIAN + angle /= F(2.0); + #else + angle = NzDegreeToRadian(angle/F(2.0)); + #endif + + T yScale = std::tan(static_cast(M_PI_2) - angle); + + Set(yScale / ratio, F(0.0), F(0.0), F(0.0), + F(0.0), yScale, F(0.0), F(0.0), + F(0.0), F(0.0), - (zFar + zNear) / (zFar - zNear), F(-1.0), + F(0.0), F(0.0), F(-2.0) * (zNear * zFar) / (zFar - zNear), F(0.0)); + + return *this; + } + + template + Matrix4& Matrix4::MakeRotation(const Quaternion& rotation) + { + SetRotation(rotation); + + // On complète la matrice + m14 = F(0.0); + m24 = F(0.0); + m34 = F(0.0); + m41 = F(0.0); + m42 = F(0.0); + m43 = F(0.0); + m44 = F(1.0); + + return *this; + } + + template + Matrix4& Matrix4::MakeScale(const Vector3& scale) + { + Set(scale.x, F(0.0), F(0.0), F(0.0), + F(0.0), scale.y, F(0.0), F(0.0), + F(0.0), F(0.0), scale.z, F(0.0), + F(0.0), F(0.0), F(0.0), F(1.0)); + + return *this; + } + + template + Matrix4& Matrix4::MakeTranslation(const Vector3& translation) + { + Set(F(1.0), F(0.0), F(0.0), F(0.0), + F(0.0), F(1.0), F(0.0), F(0.0), + F(0.0), F(0.0), F(1.0), F(0.0), + translation.x, translation.y, translation.z, F(1.0)); + + return *this; + } + + template + Matrix4& Matrix4::MakeTransform(const Vector3& translation, const Quaternion& rotation) + { + // La rotation et la translation peuvent être appliquées directement + SetRotation(rotation); + SetTranslation(translation); + + // On complète la matrice (les transformations sont affines) + m14 = F(0.0); + m24 = F(0.0); + m34 = F(0.0); + m44 = F(1.0); + + return *this; + } + + template + Matrix4& Matrix4::MakeTransform(const Vector3& translation, const Quaternion& rotation, const Vector3& scale) + { + MakeTransform(translation, rotation); + + // Ensuite on fait une mise à l'échelle des valeurs déjà présentes + return ApplyScale(scale); + } + + template + Matrix4& Matrix4::MakeViewMatrix(const Vector3& translation, const Quaternion& rotation) + { + // Une matrice de vue doit appliquer une transformation opposée à la matrice "monde" + Quaternion invRot = rotation.GetConjugate(); // Inverse de la rotation + + return MakeTransform(-(invRot * translation), invRot); + } + + template + Matrix4& Matrix4::MakeZero() + { + Set(F(0.0), F(0.0), F(0.0), F(0.0), + F(0.0), F(0.0), F(0.0), F(0.0), + F(0.0), F(0.0), F(0.0), F(0.0), + F(0.0), F(0.0), F(0.0), F(0.0)); + + return *this; + } + + template + Matrix4& Matrix4::Set(T r11, T r12, T r13, T r14, + T r21, T r22, T r23, T r24, + T r31, T r32, T r33, T r34, + T r41, T r42, T r43, T r44) + { + m11 = r11; + m12 = r12; + m13 = r13; + m14 = r14; + m21 = r21; + m22 = r22; + m23 = r23; + m24 = r24; + m31 = r31; + m32 = r32; + m33 = r33; + m34 = r34; + m41 = r41; + m42 = r42; + m43 = r43; + m44 = r44; + + return *this; + } + + template + Matrix4& Matrix4::Set(const T matrix[16]) + { + // Ici nous sommes certains de la continuité des éléments en mémoire + std::memcpy(&m11, matrix, 16*sizeof(T)); + + return *this; + } + + template + Matrix4& Matrix4::Set(const Matrix4& matrix) + { + std::memcpy(this, &matrix, sizeof(Matrix4)); + + return *this; + } + + template + template + Matrix4& Matrix4::Set(const Matrix4& matrix) + { + Set(F(matrix[ 0]), F(matrix[ 1]), F(matrix[ 2]), F(matrix[ 3]), + F(matrix[ 4]), F(matrix[ 5]), F(matrix[ 6]), F(matrix[ 7]), + F(matrix[ 8]), F(matrix[ 9]), F(matrix[10]), F(matrix[11]), + F(matrix[12]), F(matrix[13]), F(matrix[14]), F(matrix[15])); + + return *this; + } + + template + Matrix4& Matrix4::SetRotation(const Quaternion& rotation) + { + T tx = rotation.x + rotation.x; + T ty = rotation.y + rotation.y; + T tz = rotation.z + rotation.z; + T twx = tx * rotation.w; + T twy = ty * rotation.w; + T twz = tz * rotation.w; + T txx = tx * rotation.x; + T txy = ty * rotation.x; + T txz = tz * rotation.x; + T tyy = ty * rotation.y; + T tyz = tz * rotation.y; + T tzz = tz * rotation.z; + + m11 = F(1.0) - (tyy + tzz); + m12 = txy + twz; + m13 = txz - twy; + + m21 = txy - twz; + m22 = F(1.0) - (txx + tzz); + m23 = tyz + twx; + + m31 = txz + twy; + m32 = tyz - twx; + m33 = F(1.0) - (txx + tyy); + + return *this; + } + + template + Matrix4& Matrix4::SetScale(const Vector3& scale) + { + m11 = scale.x; + m22 = scale.y; + m33 = scale.z; + + return *this; + } + + template + Matrix4& Matrix4::SetTranslation(const Vector3& translation) + { + m41 = translation.x; + m42 = translation.y; + m43 = translation.z; + + return *this; + } + + template + String Matrix4::ToString() const + { + StringStream ss; + return ss << "Matrix4(" << m11 << ", " << m12 << ", " << m13 << ", " << m14 << ",\n" + << " " << m21 << ", " << m22 << ", " << m23 << ", " << m24 << ",\n" + << " " << m31 << ", " << m32 << ", " << m33 << ", " << m34 << ",\n" + << " " << m41 << ", " << m42 << ", " << m43 << ", " << m44 << ')'; + } + + template + Vector2 Matrix4::Transform(const Vector2& vector, T z, T w) const + { + return Vector2(m11*vector.x + m21*vector.y + m31*z + m41*w, + m12*vector.x + m22*vector.y + m32*z + m42*w); + } + + template + Vector3 Matrix4::Transform(const Vector3& vector, T w) const + { + return Vector3(m11*vector.x + m21*vector.y + m31*vector.z + m41*w, + m12*vector.x + m22*vector.y + m32*vector.z + m42*w, + m13*vector.x + m23*vector.y + m33*vector.z + m43*w); + } + + template + Vector4 Matrix4::Transform(const Vector4& vector) const + { + return Vector4(m11*vector.x + m21*vector.y + m31*vector.z + m41*vector.w, + m12*vector.x + m22*vector.y + m32*vector.z + m42*vector.w, + m13*vector.x + m23*vector.y + m33*vector.z + m43*vector.w, + m14*vector.x + m24*vector.y + m34*vector.z + m44*vector.w); + } + + template + Matrix4& Matrix4::Transpose() + { + std::swap(m12, m21); + std::swap(m13, m31); + std::swap(m14, m41); + std::swap(m23, m32); + std::swap(m24, m42); + std::swap(m34, m43); + + return *this; + } + + template + Matrix4::operator T*() + { + return &m11; + } + + template + Matrix4::operator const T*() const + { + return &m11; + } + + template + T& Matrix4::operator()(unsigned int x, unsigned int y) + { + #if NAZARA_MATH_SAFE + if (x > 3 || y > 3) + { + StringStream ss; + ss << "Index out of range: (" << x << ", " << y << ") > (3,3)"; + + throw std::out_of_range(ss.ToString()); + } + #endif + + return (&m11)[y*4+x]; + } + + template + T Matrix4::operator()(unsigned int x, unsigned int y) const + { + #if NAZARA_MATH_SAFE + if (x > 3 || y > 3) + { + StringStream ss; + ss << "Index out of range: (" << x << ", " << y << ") > (3,3)"; + + NazaraError(ss); + throw std::out_of_range(ss.ToString()); + } + #endif + + return (&m11)[y*4+x]; + } + + template + Matrix4 Matrix4::operator*(const Matrix4& matrix) const + { + Matrix4 result(*this); + return result.Concatenate(matrix); + } + + template + Vector2 Matrix4::operator*(const Vector2& vector) const + { + return Transform(vector); + } + + template + Vector3 Matrix4::operator*(const Vector3& vector) const + { + return Transform(vector); + } + + template + Vector4 Matrix4::operator*(const Vector4& vector) const + { + return Transform(vector); + } + + template + Matrix4 Matrix4::operator*(T scalar) const + { + Matrix4 mat; + for (unsigned int i = 0; i < 16; ++i) + mat[i] = (&m11)[i] * scalar; + + return mat; + } + + template + Matrix4& Matrix4::operator*=(const Matrix4& matrix) + { + Concatenate(matrix); + + return *this; + } + + template + Matrix4& Matrix4::operator*=(T scalar) + { + for (unsigned int i = 0; i < 16; ++i) + (&m11)[i] *= scalar; + + return *this; + } + + template + bool Matrix4::operator==(const Matrix4& mat) const + { + for (unsigned int i = 0; i < 16; ++i) + if (!NumberEquals((&m11)[i], (&mat.m11)[i])) + return false; + + return true; + } + + template + bool Matrix4::operator!=(const Matrix4& mat) const + { + return !operator==(mat); + } + + template + Matrix4 Matrix4::Concatenate(const Matrix4& left, const Matrix4& right) + { + Matrix4 matrix(left); // Copie de la matrice de gauche + matrix.Concatenate(right); // Concaténation avec la matrice de droite + + return matrix; // Et on renvoie la matrice + } + + template + Matrix4 Matrix4::ConcatenateAffine(const Matrix4& left, const Matrix4& right) + { + Matrix4 matrix(left); // Copie de la matrice de gauche + matrix.ConcatenateAffine(right); // Concaténation (affine) avec la matrice de droite + + return matrix; // Et on renvoie la matrice + } + + template + Matrix4 Matrix4::Identity() + { + Matrix4 matrix; + matrix.MakeIdentity(); + + return matrix; + } + + template + Matrix4 Matrix4::LookAt(const Vector3& eye, const Vector3& target, const Vector3& up) + { + Matrix4 matrix; + matrix.MakeLookAt(eye, target, up); + + return matrix; + } + + template + Matrix4 Matrix4::Ortho(T left, T right, T top, T bottom, T zNear, T zFar) + { + Matrix4 matrix; + matrix.MakeOrtho(left, right, top, bottom, zNear, zFar); + + return matrix; + } + + template + Matrix4 Matrix4::Perspective(T angle, T ratio, T zNear, T zFar) + { + Matrix4 matrix; + matrix.MakePerspective(angle, ratio, zNear, zFar); + + return matrix; + } + + template + Matrix4 Matrix4::Rotate(const Quaternion& rotation) + { + Matrix4 matrix; + matrix.MakeRotation(rotation); + + return matrix; + } + + template + Matrix4 Matrix4::Scale(const Vector3& scale) + { + Matrix4 matrix; + matrix.MakeScale(scale); + + return matrix; + } + + template + Matrix4 Matrix4::Translate(const Vector3& translation) + { + Matrix4 mat; + mat.MakeTranslation(translation); + + return mat; + } + + template + Matrix4 Matrix4::Transform(const Vector3& translation, const Quaternion& rotation) + { + Matrix4 mat; + mat.MakeTransform(translation, rotation); + + return mat; + } + + template + Matrix4 Matrix4::Transform(const Vector3& translation, const Quaternion& rotation, const Vector3& scale) + { + Matrix4 mat; + mat.MakeTransform(translation, rotation, scale); + + return mat; + } + + template + Matrix4 Matrix4::ViewMatrix(const Vector3& translation, const Quaternion& rotation) + { + Matrix4 mat; + mat.MakeViewMatrix(translation, rotation); + + return mat; + } + + template + Matrix4 Matrix4::Zero() + { + Matrix4 matrix; + matrix.MakeZero(); + + return matrix; + } } template -NzMatrix4 NzMatrix4::operator*(const NzMatrix4& matrix) const -{ - NzMatrix4 result(*this); - return result.Concatenate(matrix); -} - -template -NzVector2 NzMatrix4::operator*(const NzVector2& vector) const -{ - return Transform(vector); -} - -template -NzVector3 NzMatrix4::operator*(const NzVector3& vector) const -{ - return Transform(vector); -} - -template -NzVector4 NzMatrix4::operator*(const NzVector4& vector) const -{ - return Transform(vector); -} - -template -NzMatrix4 NzMatrix4::operator*(T scalar) const -{ - NzMatrix4 mat; - for (unsigned int i = 0; i < 16; ++i) - mat[i] = (&m11)[i] * scalar; - - return mat; -} - -template -NzMatrix4& NzMatrix4::operator*=(const NzMatrix4& matrix) -{ - Concatenate(matrix); - - return *this; -} - -template -NzMatrix4& NzMatrix4::operator*=(T scalar) -{ - for (unsigned int i = 0; i < 16; ++i) - (&m11)[i] *= scalar; - - return *this; -} - -template -bool NzMatrix4::operator==(const NzMatrix4& mat) const -{ - for (unsigned int i = 0; i < 16; ++i) - if (!NzNumberEquals((&m11)[i], (&mat.m11)[i])) - return false; - - return true; -} - -template -bool NzMatrix4::operator!=(const NzMatrix4& mat) const -{ - return !operator==(mat); -} - -template -NzMatrix4 NzMatrix4::Concatenate(const NzMatrix4& left, const NzMatrix4& right) -{ - NzMatrix4 matrix(left); // Copie de la matrice de gauche - matrix.Concatenate(right); // Concaténation avec la matrice de droite - - return matrix; // Et on renvoie la matrice -} - -template -NzMatrix4 NzMatrix4::ConcatenateAffine(const NzMatrix4& left, const NzMatrix4& right) -{ - NzMatrix4 matrix(left); // Copie de la matrice de gauche - matrix.ConcatenateAffine(right); // Concaténation (affine) avec la matrice de droite - - return matrix; // Et on renvoie la matrice -} - -template -NzMatrix4 NzMatrix4::Identity() -{ - NzMatrix4 matrix; - matrix.MakeIdentity(); - - return matrix; -} - -template -NzMatrix4 NzMatrix4::LookAt(const NzVector3& eye, const NzVector3& target, const NzVector3& up) -{ - NzMatrix4 matrix; - matrix.MakeLookAt(eye, target, up); - - return matrix; -} - -template -NzMatrix4 NzMatrix4::Ortho(T left, T right, T top, T bottom, T zNear, T zFar) -{ - NzMatrix4 matrix; - matrix.MakeOrtho(left, right, top, bottom, zNear, zFar); - - return matrix; -} - -template -NzMatrix4 NzMatrix4::Perspective(T angle, T ratio, T zNear, T zFar) -{ - NzMatrix4 matrix; - matrix.MakePerspective(angle, ratio, zNear, zFar); - - return matrix; -} - -template -NzMatrix4 NzMatrix4::Rotate(const NzQuaternion& rotation) -{ - NzMatrix4 matrix; - matrix.MakeRotation(rotation); - - return matrix; -} - -template -NzMatrix4 NzMatrix4::Scale(const NzVector3& scale) -{ - NzMatrix4 matrix; - matrix.MakeScale(scale); - - return matrix; -} - -template -NzMatrix4 NzMatrix4::Translate(const NzVector3& translation) -{ - NzMatrix4 mat; - mat.MakeTranslation(translation); - - return mat; -} - -template -NzMatrix4 NzMatrix4::Transform(const NzVector3& translation, const NzQuaternion& rotation) -{ - NzMatrix4 mat; - mat.MakeTransform(translation, rotation); - - return mat; -} - -template -NzMatrix4 NzMatrix4::Transform(const NzVector3& translation, const NzQuaternion& rotation, const NzVector3& scale) -{ - NzMatrix4 mat; - mat.MakeTransform(translation, rotation, scale); - - return mat; -} - -template -NzMatrix4 NzMatrix4::ViewMatrix(const NzVector3& translation, const NzQuaternion& rotation) -{ - NzMatrix4 mat; - mat.MakeViewMatrix(translation, rotation); - - return mat; -} - -template -NzMatrix4 NzMatrix4::Zero() -{ - NzMatrix4 matrix; - matrix.MakeZero(); - - return matrix; -} - -template -std::ostream& operator<<(std::ostream& out, const NzMatrix4& matrix) +std::ostream& operator<<(std::ostream& out, const Nz::Matrix4& matrix) { return out << matrix.ToString(); } template -NzMatrix4 operator*(T scale, const NzMatrix4& matrix) +Nz::Matrix4 operator*(T scale, const Nz::Matrix4& matrix) { return matrix * scale; } diff --git a/include/Nazara/Math/OrientedBox.hpp b/include/Nazara/Math/OrientedBox.hpp index 017d627f4..0b579fcba 100644 --- a/include/Nazara/Math/OrientedBox.hpp +++ b/include/Nazara/Math/OrientedBox.hpp @@ -12,62 +12,65 @@ #include #include -template -class NzOrientedBox +namespace Nz { - public: - NzOrientedBox() = default; - NzOrientedBox(T X, T Y, T Z, T Width, T Height, T Depth); - NzOrientedBox(const NzBox& box); - NzOrientedBox(const NzVector3& vec1, const NzVector3& vec2); - template explicit NzOrientedBox(const NzOrientedBox& orientedBox); - NzOrientedBox(const NzOrientedBox& orientedBox) = default; - ~NzOrientedBox() = default; + template + class OrientedBox + { + public: + OrientedBox() = default; + OrientedBox(T X, T Y, T Z, T Width, T Height, T Depth); + OrientedBox(const Box& box); + OrientedBox(const Vector3& vec1, const Vector3& vec2); + template explicit OrientedBox(const OrientedBox& orientedBox); + OrientedBox(const OrientedBox& orientedBox) = default; + ~OrientedBox() = default; - const NzVector3& GetCorner(nzBoxCorner corner) const; + const Vector3& GetCorner(BoxCorner corner) const; - bool IsValid() const; + bool IsValid() const; - NzOrientedBox& MakeZero(); + OrientedBox& MakeZero(); - NzOrientedBox& Set(T X, T Y, T Z, T Width, T Height, T Depth); - NzOrientedBox& Set(const NzBox& box); - NzOrientedBox& Set(const NzOrientedBox& orientedBox); - NzOrientedBox& Set(const NzVector3& vec1, const NzVector3& vec2); - template NzOrientedBox& Set(const NzOrientedBox& orientedBox); + OrientedBox& Set(T X, T Y, T Z, T Width, T Height, T Depth); + OrientedBox& Set(const Box& box); + OrientedBox& Set(const OrientedBox& orientedBox); + OrientedBox& Set(const Vector3& vec1, const Vector3& vec2); + template OrientedBox& Set(const OrientedBox& orientedBox); - NzString ToString() const; + String ToString() const; - void Update(const NzMatrix4& transformMatrix); - void Update(const NzVector3& transformMatrix); + void Update(const Matrix4& transformMatrix); + void Update(const Vector3& transformMatrix); - operator NzVector3*(); - operator const NzVector3*() const; + operator Vector3*(); + operator const Vector3*() const; - NzVector3& operator()(unsigned int i); - NzVector3 operator()(unsigned int i) const; + Vector3& operator()(unsigned int i); + Vector3 operator()(unsigned int i) const; - NzOrientedBox operator*(T scalar) const; + OrientedBox operator*(T scalar) const; - NzOrientedBox& operator*=(T scalar); + OrientedBox& operator*=(T scalar); - bool operator==(const NzOrientedBox& box) const; - bool operator!=(const NzOrientedBox& box) const; + bool operator==(const OrientedBox& box) const; + bool operator!=(const OrientedBox& box) const; - static NzOrientedBox Lerp(const NzOrientedBox& from, const NzOrientedBox& to, T interpolation); - static NzOrientedBox Zero(); + static OrientedBox Lerp(const OrientedBox& from, const OrientedBox& to, T interpolation); + static OrientedBox Zero(); - NzBox localBox; + Box localBox; - private: - NzVector3 m_corners[nzBoxCorner_Max+1]; // Ne peuvent pas être modifiés directement -}; + private: + Vector3 m_corners[BoxCorner_Max+1]; // Ne peuvent pas être modifiés directement + }; + + typedef OrientedBox OrientedBoxd; + typedef OrientedBox OrientedBoxf; +} template -std::ostream& operator<<(std::ostream& out, const NzOrientedBox& orientedBox); - -typedef NzOrientedBox NzOrientedBoxd; -typedef NzOrientedBox NzOrientedBoxf; +std::ostream& operator<<(std::ostream& out, const Nz::OrientedBox& orientedBox); #include diff --git a/include/Nazara/Math/OrientedBox.inl b/include/Nazara/Math/OrientedBox.inl index bd8f55371..a54cdae79 100644 --- a/include/Nazara/Math/OrientedBox.inl +++ b/include/Nazara/Math/OrientedBox.inl @@ -11,229 +11,232 @@ #define F(a) static_cast(a) -template -NzOrientedBox::NzOrientedBox(T X, T Y, T Z, T Width, T Height, T Depth) +namespace Nz { - Set(X, Y, Z, Width, Height, Depth); -} - -template -NzOrientedBox::NzOrientedBox(const NzBox& box) -{ - Set(box); -} - -template -NzOrientedBox::NzOrientedBox(const NzVector3& vec1, const NzVector3& vec2) -{ - Set(vec1, vec2); -} - -template -template -NzOrientedBox::NzOrientedBox(const NzOrientedBox& orientedBox) -{ - Set(orientedBox); -} - -template -const NzVector3& NzOrientedBox::GetCorner(nzBoxCorner corner) const -{ - #ifdef NAZARA_DEBUG - if (corner > nzBoxCorner_Max) + template + OrientedBox::OrientedBox(T X, T Y, T Z, T Width, T Height, T Depth) { - NazaraError("Corner not handled (0x" + NzString::Number(corner, 16) + ')'); - - static NzVector3 dummy; - return dummy; + Set(X, Y, Z, Width, Height, Depth); } - #endif - return m_corners[corner]; -} - -template -bool NzOrientedBox::IsValid() const -{ - return localBox.IsValid(); -} - -template -NzOrientedBox& NzOrientedBox::MakeZero() -{ - localBox.MakeZero(); - - return *this; -} - -template -NzOrientedBox& NzOrientedBox::Set(T X, T Y, T Z, T Width, T Height, T Depth) -{ - localBox.Set(X, Y, Z, Width, Height, Depth); - - return *this; -} - -template -NzOrientedBox& NzOrientedBox::Set(const NzBox& box) -{ - localBox.Set(box); - - return *this; -} - -template -NzOrientedBox& NzOrientedBox::Set(const NzOrientedBox& orientedBox) -{ - std::memcpy(this, &orientedBox, sizeof(NzOrientedBox)); - - return *this; -} - -template -NzOrientedBox& NzOrientedBox::Set(const NzVector3& vec1, const NzVector3& vec2) -{ - localBox.Set(vec1, vec2); - - return *this; -} - -template -template -NzOrientedBox& NzOrientedBox::Set(const NzOrientedBox& orientedBox) -{ - for (unsigned int i = 0; i <= nzBoxCorner_Max; ++i) - m_corners[i].Set(orientedBox(i)); - - localBox.Set(orientedBox.localBox); - - return *this; -} - -template -NzString NzOrientedBox::ToString() const -{ - NzStringStream ss; - - return ss << "OrientedBox(FLB: " << m_corners[nzBoxCorner_FarLeftBottom].ToString() << "\n" - << " FLT: " << m_corners[nzBoxCorner_FarLeftTop].ToString() << "\n" - << " FRB: " << m_corners[nzBoxCorner_FarRightBottom].ToString() << "\n" - << " FRT: " << m_corners[nzBoxCorner_FarRightTop].ToString() << "\n" - << " NLB: " << m_corners[nzBoxCorner_NearLeftBottom].ToString() << "\n" - << " NLT: " << m_corners[nzBoxCorner_NearLeftTop].ToString() << "\n" - << " NRB: " << m_corners[nzBoxCorner_NearRightBottom].ToString() << "\n" - << " NRT: " << m_corners[nzBoxCorner_NearRightTop].ToString() << ")\n"; -} - -template -void NzOrientedBox::Update(const NzMatrix4& transformMatrix) -{ - for (unsigned int i = 0; i <= nzBoxCorner_Max; ++i) - m_corners[i] = transformMatrix.Transform(localBox.GetCorner(static_cast(i))); -} - -template -void NzOrientedBox::Update(const NzVector3& translation) -{ - for (unsigned int i = 0; i <= nzBoxCorner_Max; ++i) - m_corners[i] = localBox.GetCorner(static_cast(i)) + translation; -} - -template -NzOrientedBox::operator NzVector3*() -{ - return &m_corners[0]; -} - -template -NzOrientedBox::operator const NzVector3*() const -{ - return &m_corners[0]; -} - -template -NzVector3& NzOrientedBox::operator()(unsigned int i) -{ - #if NAZARA_MATH_SAFE - if (i > nzBoxCorner_Max) + template + OrientedBox::OrientedBox(const Box& box) { - NzStringStream ss; - ss << "Index out of range: (" << i << " >= " << nzBoxCorner_Max << ")"; - - NazaraError(ss); - throw std::out_of_range(ss.ToString()); + Set(box); } - #endif - return m_corners[i]; -} - -template -NzVector3 NzOrientedBox::operator()(unsigned int i) const -{ - #if NAZARA_MATH_SAFE - if (i > nzBoxCorner_Max) + template + OrientedBox::OrientedBox(const Vector3& vec1, const Vector3& vec2) { - NzStringStream ss; - ss << "Index out of range: (" << i << " >= " << nzBoxCorner_Max << ")"; - - NazaraError(ss); - throw std::out_of_range(ss.ToString()); + Set(vec1, vec2); } - #endif - return m_corners[i]; + template + template + OrientedBox::OrientedBox(const OrientedBox& orientedBox) + { + Set(orientedBox); + } + + template + const Vector3& OrientedBox::GetCorner(BoxCorner corner) const + { + #ifdef NAZARA_DEBUG + if (corner > BoxCorner_Max) + { + NazaraError("Corner not handled (0x" + String::Number(corner, 16) + ')'); + + static Vector3 dummy; + return dummy; + } + #endif + + return m_corners[corner]; + } + + template + bool OrientedBox::IsValid() const + { + return localBox.IsValid(); + } + + template + OrientedBox& OrientedBox::MakeZero() + { + localBox.MakeZero(); + + return *this; + } + + template + OrientedBox& OrientedBox::Set(T X, T Y, T Z, T Width, T Height, T Depth) + { + localBox.Set(X, Y, Z, Width, Height, Depth); + + return *this; + } + + template + OrientedBox& OrientedBox::Set(const Box& box) + { + localBox.Set(box); + + return *this; + } + + template + OrientedBox& OrientedBox::Set(const OrientedBox& orientedBox) + { + std::memcpy(this, &orientedBox, sizeof(OrientedBox)); + + return *this; + } + + template + OrientedBox& OrientedBox::Set(const Vector3& vec1, const Vector3& vec2) + { + localBox.Set(vec1, vec2); + + return *this; + } + + template + template + OrientedBox& OrientedBox::Set(const OrientedBox& orientedBox) + { + for (unsigned int i = 0; i <= BoxCorner_Max; ++i) + m_corners[i].Set(orientedBox(i)); + + localBox.Set(orientedBox.localBox); + + return *this; + } + + template + String OrientedBox::ToString() const + { + StringStream ss; + + return ss << "OrientedBox(FLB: " << m_corners[BoxCorner_FarLeftBottom].ToString() << "\n" + << " FLT: " << m_corners[BoxCorner_FarLeftTop].ToString() << "\n" + << " FRB: " << m_corners[BoxCorner_FarRightBottom].ToString() << "\n" + << " FRT: " << m_corners[BoxCorner_FarRightTop].ToString() << "\n" + << " NLB: " << m_corners[BoxCorner_NearLeftBottom].ToString() << "\n" + << " NLT: " << m_corners[BoxCorner_NearLeftTop].ToString() << "\n" + << " NRB: " << m_corners[BoxCorner_NearRightBottom].ToString() << "\n" + << " NRT: " << m_corners[BoxCorner_NearRightTop].ToString() << ")\n"; + } + + template + void OrientedBox::Update(const Matrix4& transformMatrix) + { + for (unsigned int i = 0; i <= BoxCorner_Max; ++i) + m_corners[i] = transformMatrix.Transform(localBox.GetCorner(static_cast(i))); + } + + template + void OrientedBox::Update(const Vector3& translation) + { + for (unsigned int i = 0; i <= BoxCorner_Max; ++i) + m_corners[i] = localBox.GetCorner(static_cast(i)) + translation; + } + + template + OrientedBox::operator Vector3*() + { + return &m_corners[0]; + } + + template + OrientedBox::operator const Vector3*() const + { + return &m_corners[0]; + } + + template + Vector3& OrientedBox::operator()(unsigned int i) + { + #if NAZARA_MATH_SAFE + if (i > BoxCorner_Max) + { + StringStream ss; + ss << "Index out of range: (" << i << " >= " << BoxCorner_Max << ")"; + + NazaraError(ss); + throw std::out_of_range(ss.ToString()); + } + #endif + + return m_corners[i]; + } + + template + Vector3 OrientedBox::operator()(unsigned int i) const + { + #if NAZARA_MATH_SAFE + if (i > BoxCorner_Max) + { + StringStream ss; + ss << "Index out of range: (" << i << " >= " << BoxCorner_Max << ")"; + + NazaraError(ss); + throw std::out_of_range(ss.ToString()); + } + #endif + + return m_corners[i]; + } + + template + OrientedBox OrientedBox::operator*(T scalar) const + { + OrientedBox box(*this); + box *= scalar; + + return box; + } + + template + OrientedBox& OrientedBox::operator*=(T scalar) + { + localBox *= scalar; + + return *this; + } + + template + bool OrientedBox::operator==(const OrientedBox& box) const + { + return localBox == box.localBox; + } + + template + bool OrientedBox::operator!=(const OrientedBox& box) const + { + return !operator==(box); + } + + template + OrientedBox OrientedBox::Lerp(const OrientedBox& from, const OrientedBox& to, T interpolation) + { + OrientedBox orientedBox; + orientedBox.Set(Box::Lerp(from.localBox, to.localBox, interpolation)); + + return orientedBox; + } + + template + OrientedBox OrientedBox::Zero() + { + OrientedBox orientedBox; + orientedBox.MakeZero(); + + return orientedBox; + } } template -NzOrientedBox NzOrientedBox::operator*(T scalar) const -{ - NzOrientedBox box(*this); - box *= scalar; - - return box; -} - -template -NzOrientedBox& NzOrientedBox::operator*=(T scalar) -{ - localBox *= scalar; - - return *this; -} - -template -bool NzOrientedBox::operator==(const NzOrientedBox& box) const -{ - return localBox == box.localBox; -} - -template -bool NzOrientedBox::operator!=(const NzOrientedBox& box) const -{ - return !operator==(box); -} - -template -NzOrientedBox NzOrientedBox::Lerp(const NzOrientedBox& from, const NzOrientedBox& to, T interpolation) -{ - NzOrientedBox orientedBox; - orientedBox.Set(NzBox::Lerp(from.localBox, to.localBox, interpolation)); - - return orientedBox; -} - -template -NzOrientedBox NzOrientedBox::Zero() -{ - NzOrientedBox orientedBox; - orientedBox.MakeZero(); - - return orientedBox; -} - -template -std::ostream& operator<<(std::ostream& out, const NzOrientedBox& orientedBox) +std::ostream& operator<<(std::ostream& out, const Nz::OrientedBox& orientedBox) { return out << orientedBox.ToString(); } diff --git a/include/Nazara/Math/Plane.hpp b/include/Nazara/Math/Plane.hpp index f3971acb1..cd0856aa5 100644 --- a/include/Nazara/Math/Plane.hpp +++ b/include/Nazara/Math/Plane.hpp @@ -10,50 +10,53 @@ #include #include -template -class NzPlane +namespace Nz { - public: - NzPlane() = default; - NzPlane(T normalX, T normalY, T normalZ, T Distance); - NzPlane(const T plane[4]); - NzPlane(const NzVector3& Normal, T Distance); - NzPlane(const NzVector3& Normal, const NzVector3& point); - NzPlane(const NzVector3& point1, const NzVector3& point2, const NzVector3& point3); - template explicit NzPlane(const NzPlane& plane); - NzPlane(const NzPlane& plane) = default; - ~NzPlane() = default; + template + class Plane + { + public: + Plane() = default; + Plane(T normalX, T normalY, T normalZ, T Distance); + Plane(const T plane[4]); + Plane(const Vector3& Normal, T Distance); + Plane(const Vector3& Normal, const Vector3& point); + Plane(const Vector3& point1, const Vector3& point2, const Vector3& point3); + template explicit Plane(const Plane& plane); + Plane(const Plane& plane) = default; + ~Plane() = default; - T Distance(const NzVector3& point) const; - T Distance(T x, T y, T z) const; + T Distance(const Vector3& point) const; + T Distance(T x, T y, T z) const; - NzPlane& Set(T normalX, T normalY, T normalZ, T Distance); - NzPlane& Set(const T plane[4]); - NzPlane& Set(const NzPlane& plane); - NzPlane& Set(const NzVector3& Normal, T Distance); - NzPlane& Set(const NzVector3& Normal, const NzVector3& point); - NzPlane& Set(const NzVector3& point1, const NzVector3& point2, const NzVector3& point3); - template NzPlane& Set(const NzPlane& plane); + Plane& Set(T normalX, T normalY, T normalZ, T Distance); + Plane& Set(const T plane[4]); + Plane& Set(const Plane& plane); + Plane& Set(const Vector3& Normal, T Distance); + Plane& Set(const Vector3& Normal, const Vector3& point); + Plane& Set(const Vector3& point1, const Vector3& point2, const Vector3& point3); + template Plane& Set(const Plane& plane); - NzString ToString() const; + String ToString() const; - bool operator==(const NzPlane& plane) const; - bool operator!=(const NzPlane& plane) const; + bool operator==(const Plane& plane) const; + bool operator!=(const Plane& plane) const; - static NzPlane Lerp(const NzPlane& from, const NzPlane& to, T interpolation); - static NzPlane XY(); - static NzPlane XZ(); - static NzPlane YZ(); + static Plane Lerp(const Plane& from, const Plane& to, T interpolation); + static Plane XY(); + static Plane XZ(); + static Plane YZ(); - NzVector3 normal; - T distance; -}; + Vector3 normal; + T distance; + }; + + typedef Plane Planed; + typedef Plane Planef; +} template -std::ostream& operator<<(std::ostream& out, const NzPlane& plane); - -typedef NzPlane NzPlaned; -typedef NzPlane NzPlanef; +std::ostream& operator<<(std::ostream& out, const Nz::Plane& plane); #include diff --git a/include/Nazara/Math/Plane.inl b/include/Nazara/Math/Plane.inl index 834435085..fceeb9cc3 100644 --- a/include/Nazara/Math/Plane.inl +++ b/include/Nazara/Math/Plane.inl @@ -9,181 +9,184 @@ #define F(a) static_cast(a) -template -NzPlane::NzPlane(T normalX, T normalY, T normalZ, T D) +namespace Nz { - Set(normalX, normalY, normalZ, D); -} - -template -NzPlane::NzPlane(const T plane[4]) -{ - Set(plane); -} - -template -NzPlane::NzPlane(const NzVector3& Normal, T D) -{ - Set(Normal, D); -} - -template -NzPlane::NzPlane(const NzVector3& Normal, const NzVector3& point) -{ - Set(Normal, point); -} - -template -NzPlane::NzPlane(const NzVector3& point1, const NzVector3& point2, const NzVector3& point3) -{ - Set(point1, point2, point3); -} - -template -template -NzPlane::NzPlane(const NzPlane& plane) -{ - Set(plane); -} - -template -T NzPlane::Distance(const NzVector3& point) const -{ - return normal.DotProduct(point) - distance; // ax + by + cd - d = 0. -} - -template -T NzPlane::Distance(T x, T y, T z) const -{ - return Distance(NzVector3(x, y, z)); -} - -template -NzPlane& NzPlane::Set(T normalX, T normalY, T normalZ, T D) -{ - distance = D; - normal.Set(normalX, normalY, normalZ); - - return *this; -} - -template -NzPlane& NzPlane::Set(const T plane[4]) -{ - normal.Set(plane[0], plane[1], plane[2]); - distance = plane[3]; - - return *this; -} - -template -NzPlane& NzPlane::Set(const NzPlane& plane) -{ - std::memcpy(this, &plane, sizeof(NzPlane)); - - return *this; -} - -template -NzPlane& NzPlane::Set(const NzVector3& Normal, T D) -{ - distance = D; - normal = Normal; - - return *this; -} - -template -NzPlane& NzPlane::Set(const NzVector3& Normal, const NzVector3& point) -{ - normal = Normal; - distance = -normal.DotProduct(point); - - return *this; -} - -template -NzPlane& NzPlane::Set(const NzVector3& point1, const NzVector3& point2, const NzVector3& point3) -{ - NzVector3 edge1 = point2 - point1; - NzVector3 edge2 = point3 - point1; - normal = edge1.CrossProduct(edge2); - normal.Normalize(); - - distance = normal.DotProduct(point3); - - return *this; -} - -template -template -NzPlane& NzPlane::Set(const NzPlane& plane) -{ - normal.Set(plane.normal); - distance = F(plane.distance); - - return *this; -} - -template -NzString NzPlane::ToString() const -{ - NzStringStream ss; - - return ss << "Plane(Normal: " << normal.ToString() << "; Distance: " << distance << ')'; -} - -template -bool NzPlane::operator==(const NzPlane& plane) const -{ - return (normal == plane.normal && NzNumberEquals(distance, plane.distance)) || (normal == -plane.normal && NzNumberEquals(distance, -plane.distance)); -} - -template -bool NzPlane::operator!=(const NzPlane& plane) const -{ - return !operator==(plane); -} - -template -NzPlane NzPlane::Lerp(const NzPlane& from, const NzPlane& to, T interpolation) -{ - #ifdef NAZARA_DEBUG - if (interpolation < F(0.0) || interpolation > F(1.0)) + template + Plane::Plane(T normalX, T normalY, T normalZ, T D) { - NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')'); - return NzPlane(); + Set(normalX, normalY, normalZ, D); } - #endif - NzPlane plane; - plane.distance = NzLerp(from.distance, to.distance, interpolation); - plane.normal = NzVector3::Lerp(from.normal, to.normal, interpolation); - plane.normal.Normalize(); + template + Plane::Plane(const T plane[4]) + { + Set(plane); + } - return plane; + template + Plane::Plane(const Vector3& Normal, T D) + { + Set(Normal, D); + } + + template + Plane::Plane(const Vector3& Normal, const Vector3& point) + { + Set(Normal, point); + } + + template + Plane::Plane(const Vector3& point1, const Vector3& point2, const Vector3& point3) + { + Set(point1, point2, point3); + } + + template + template + Plane::Plane(const Plane& plane) + { + Set(plane); + } + + template + T Plane::Distance(const Vector3& point) const + { + return normal.DotProduct(point) - distance; // ax + by + cd - d = 0. + } + + template + T Plane::Distance(T x, T y, T z) const + { + return Distance(Vector3(x, y, z)); + } + + template + Plane& Plane::Set(T normalX, T normalY, T normalZ, T D) + { + distance = D; + normal.Set(normalX, normalY, normalZ); + + return *this; + } + + template + Plane& Plane::Set(const T plane[4]) + { + normal.Set(plane[0], plane[1], plane[2]); + distance = plane[3]; + + return *this; + } + + template + Plane& Plane::Set(const Plane& plane) + { + std::memcpy(this, &plane, sizeof(Plane)); + + return *this; + } + + template + Plane& Plane::Set(const Vector3& Normal, T D) + { + distance = D; + normal = Normal; + + return *this; + } + + template + Plane& Plane::Set(const Vector3& Normal, const Vector3& point) + { + normal = Normal; + distance = -normal.DotProduct(point); + + return *this; + } + + template + Plane& Plane::Set(const Vector3& point1, const Vector3& point2, const Vector3& point3) + { + Vector3 edge1 = point2 - point1; + Vector3 edge2 = point3 - point1; + normal = edge1.CrossProduct(edge2); + normal.Normalize(); + + distance = normal.DotProduct(point3); + + return *this; + } + + template + template + Plane& Plane::Set(const Plane& plane) + { + normal.Set(plane.normal); + distance = F(plane.distance); + + return *this; + } + + template + String Plane::ToString() const + { + StringStream ss; + + return ss << "Plane(Normal: " << normal.ToString() << "; Distance: " << distance << ')'; + } + + template + bool Plane::operator==(const Plane& plane) const + { + return (normal == plane.normal && NumberEquals(distance, plane.distance)) || (normal == -plane.normal && NumberEquals(distance, -plane.distance)); + } + + template + bool Plane::operator!=(const Plane& plane) const + { + return !operator==(plane); + } + + template + Plane Plane::Lerp(const Plane& from, const Plane& to, T interpolation) + { + #ifdef NAZARA_DEBUG + if (interpolation < F(0.0) || interpolation > F(1.0)) + { + NazaraError("Interpolation must be in range [0..1] (Got " + String::Number(interpolation) + ')'); + return Plane(); + } + #endif + + Plane plane; + plane.distance = Lerp(from.distance, to.distance, interpolation); + plane.normal = Vector3::Lerp(from.normal, to.normal, interpolation); + plane.normal.Normalize(); + + return plane; + } + + template + Plane Plane::XY() + { + return Plane(F(0.0), F(0.0), F(1.0), F(0.0)); + } + + template + Plane Plane::XZ() + { + return Plane(F(0.0), F(1.0), F(0.0), F(0.0)); + } + + template + Plane Plane::YZ() + { + return Plane(F(1.0), F(0.0), F(0.0), F(0.0)); + } } template -NzPlane NzPlane::XY() -{ - return NzPlane(F(0.0), F(0.0), F(1.0), F(0.0)); -} - -template -NzPlane NzPlane::XZ() -{ - return NzPlane(F(0.0), F(1.0), F(0.0), F(0.0)); -} - -template -NzPlane NzPlane::YZ() -{ - return NzPlane(F(1.0), F(0.0), F(0.0), F(0.0)); -} - -template -std::ostream& operator<<(std::ostream& out, const NzPlane& plane) +std::ostream& operator<<(std::ostream& out, const Nz::Plane& plane) { return out << plane.ToString(); } diff --git a/include/Nazara/Math/Quaternion.hpp b/include/Nazara/Math/Quaternion.hpp index 03b27c02a..b8ca310c1 100644 --- a/include/Nazara/Math/Quaternion.hpp +++ b/include/Nazara/Math/Quaternion.hpp @@ -9,85 +9,88 @@ #include -template class NzEulerAngles; -template class NzVector3; - -template class NzQuaternion +namespace Nz { - public: - NzQuaternion() = default; - NzQuaternion(T W, T X, T Y, T Z); - NzQuaternion(const T quat[4]); - NzQuaternion(T angle, const NzVector3& axis); - NzQuaternion(const NzEulerAngles& angles); - //NzQuaternion(const NzMatrix3& mat); - template explicit NzQuaternion(const NzQuaternion& quat); - NzQuaternion(const NzQuaternion& quat) = default; - ~NzQuaternion() = default; + template class EulerAngles; + template class Vector3; - NzQuaternion& ComputeW(); - NzQuaternion& Conjugate(); + template class Quaternion + { + public: + Quaternion() = default; + Quaternion(T W, T X, T Y, T Z); + Quaternion(const T quat[4]); + Quaternion(T angle, const Vector3& axis); + Quaternion(const EulerAngles& angles); + //Quaternion(const Matrix3& mat); + template explicit Quaternion(const Quaternion& quat); + Quaternion(const Quaternion& quat) = default; + ~Quaternion() = default; - T DotProduct(const NzQuaternion& vec) const; + Quaternion& ComputeW(); + Quaternion& Conjugate(); - NzQuaternion GetConjugate() const; - NzQuaternion GetInverse() const; - NzQuaternion GetNormal(T* length = nullptr) const; + T DotProduct(const Quaternion& vec) const; - NzQuaternion& Inverse(); + Quaternion GetConjugate() const; + Quaternion GetInverse() const; + Quaternion GetNormal(T* length = nullptr) const; - NzQuaternion& MakeIdentity(); - NzQuaternion& MakeRotationBetween(const NzVector3& from, const NzVector3& to); - NzQuaternion& MakeZero(); + Quaternion& Inverse(); - T Magnitude() const; + Quaternion& MakeIdentity(); + Quaternion& MakeRotationBetween(const Vector3& from, const Vector3& to); + Quaternion& MakeZero(); - NzQuaternion& Normalize(T* length = nullptr); + T Magnitude() const; - NzQuaternion& Set(T W, T X, T Y, T Z); - NzQuaternion& Set(const T quat[4]); - NzQuaternion& Set(T angle, const NzVector3& normalizedAxis); - NzQuaternion& Set(const NzEulerAngles& angles); - //NzQuaternion& Set(const NzMatrix3& mat); - NzQuaternion& Set(const NzQuaternion& quat); - template NzQuaternion& Set(const NzQuaternion& quat); + Quaternion& Normalize(T* length = nullptr); - T SquaredMagnitude() const; + Quaternion& Set(T W, T X, T Y, T Z); + Quaternion& Set(const T quat[4]); + Quaternion& Set(T angle, const Vector3& normalizedAxis); + Quaternion& Set(const EulerAngles& angles); + //Quaternion& Set(const Matrix3& mat); + Quaternion& Set(const Quaternion& quat); + template Quaternion& Set(const Quaternion& quat); - NzEulerAngles ToEulerAngles() const; - //NzMatrix3 ToRotationMatrix() const; - NzString ToString() const; + T SquaredMagnitude() const; - NzQuaternion& operator=(const NzQuaternion& quat); + EulerAngles ToEulerAngles() const; + //Matrix3 ToRotationMatrix() const; + String ToString() const; - NzQuaternion operator+(const NzQuaternion& quat) const; - NzQuaternion operator*(const NzQuaternion& quat) const; - NzVector3 operator*(const NzVector3& vec) const; - NzQuaternion operator*(T scale) const; - NzQuaternion operator/(const NzQuaternion& quat) const; + Quaternion& operator=(const Quaternion& quat); - NzQuaternion& operator+=(const NzQuaternion& quat); - NzQuaternion& operator*=(const NzQuaternion& quat); - NzQuaternion& operator*=(T scale); - NzQuaternion& operator/=(const NzQuaternion& quat); + Quaternion operator+(const Quaternion& quat) const; + Quaternion operator*(const Quaternion& quat) const; + Vector3 operator*(const Vector3& vec) const; + Quaternion operator*(T scale) const; + Quaternion operator/(const Quaternion& quat) const; - bool operator==(const NzQuaternion& quat) const; - bool operator!=(const NzQuaternion& quat) const; + Quaternion& operator+=(const Quaternion& quat); + Quaternion& operator*=(const Quaternion& quat); + Quaternion& operator*=(T scale); + Quaternion& operator/=(const Quaternion& quat); - static NzQuaternion Identity(); - static NzQuaternion Lerp(const NzQuaternion& from, const NzQuaternion& to, T interpolation); - static NzQuaternion Normalize(const NzQuaternion& quat, T* length = nullptr); - static NzQuaternion RotationBetween(const NzVector3& from, const NzVector3& to); - static NzQuaternion Slerp(const NzQuaternion& from, const NzQuaternion& to, T interpolation); - static NzQuaternion Zero(); + bool operator==(const Quaternion& quat) const; + bool operator!=(const Quaternion& quat) const; - T w, x, y, z; -}; + static Quaternion Identity(); + static Quaternion Lerp(const Quaternion& from, const Quaternion& to, T interpolation); + static Quaternion Normalize(const Quaternion& quat, T* length = nullptr); + static Quaternion RotationBetween(const Vector3& from, const Vector3& to); + static Quaternion Slerp(const Quaternion& from, const Quaternion& to, T interpolation); + static Quaternion Zero(); -template std::ostream& operator<<(std::ostream& out, const NzQuaternion& quat); + T w, x, y, z; + }; -typedef NzQuaternion NzQuaterniond; -typedef NzQuaternion NzQuaternionf; + typedef Quaternion Quaterniond; + typedef Quaternion Quaternionf; +} + +template std::ostream& operator<<(std::ostream& out, const Nz::Quaternion& quat); #include diff --git a/include/Nazara/Math/Quaternion.inl b/include/Nazara/Math/Quaternion.inl index a83fb9296..25c2569a1 100644 --- a/include/Nazara/Math/Quaternion.inl +++ b/include/Nazara/Math/Quaternion.inl @@ -13,473 +13,476 @@ #define F(a) static_cast(a) -template -NzQuaternion::NzQuaternion(T W, T X, T Y, T Z) +namespace Nz { - Set(W, X, Y, Z); -} - -template -NzQuaternion::NzQuaternion(const T quat[4]) -{ - Set(quat); -} - -template -NzQuaternion::NzQuaternion(T angle, const NzVector3& axis) -{ - Set(angle, axis); -} - -template -NzQuaternion::NzQuaternion(const NzEulerAngles& angles) -{ - Set(angles); -} -/* -template -NzQuaternion::NzQuaternion(const NzMatrix3& mat) -{ - Set(mat); -} -*/ -template -template -NzQuaternion::NzQuaternion(const NzQuaternion& quat) -{ - Set(quat); -} - -template -NzQuaternion& NzQuaternion::ComputeW() -{ - T t = F(1.0) - SquaredMagnitude(); - - if (t < F(0.0)) - w = F(0.0); - else - w = -std::sqrt(t); - - return *this; -} - -template -NzQuaternion& NzQuaternion::Conjugate() -{ - x = -x; - y = -y; - z = -z; - - return *this; -} - -template -T NzQuaternion::DotProduct(const NzQuaternion& quat) const -{ - return w*quat.w + x*quat.x + y*quat.y + z*quat.z; -} - -template -NzQuaternion NzQuaternion::GetConjugate() const -{ - NzQuaternion quat(*this); - quat.Conjugate(); - - return quat; -} - -template -NzQuaternion NzQuaternion::GetInverse() const -{ - NzQuaternion quat(*this); - quat.Inverse(); - - return quat; -} - -template -NzQuaternion NzQuaternion::GetNormal(T* length) const -{ - NzQuaternion quat(*this); - quat.Normalize(length); - - return quat; -} - -template -NzQuaternion& NzQuaternion::Inverse() -{ - T norm = SquaredMagnitude(); - if (norm > F(0.0)) + template + Quaternion::Quaternion(T W, T X, T Y, T Z) { + Set(W, X, Y, Z); + } + + template + Quaternion::Quaternion(const T quat[4]) + { + Set(quat); + } + + template + Quaternion::Quaternion(T angle, const Vector3& axis) + { + Set(angle, axis); + } + + template + Quaternion::Quaternion(const EulerAngles& angles) + { + Set(angles); + } + /* + template + Quaternion::Quaternion(const Matrix3& mat) + { + Set(mat); + } + */ + template + template + Quaternion::Quaternion(const Quaternion& quat) + { + Set(quat); + } + + template + Quaternion& Quaternion::ComputeW() + { + T t = F(1.0) - SquaredMagnitude(); + + if (t < F(0.0)) + w = F(0.0); + else + w = -std::sqrt(t); + + return *this; + } + + template + Quaternion& Quaternion::Conjugate() + { + x = -x; + y = -y; + z = -z; + + return *this; + } + + template + T Quaternion::DotProduct(const Quaternion& quat) const + { + return w*quat.w + x*quat.x + y*quat.y + z*quat.z; + } + + template + Quaternion Quaternion::GetConjugate() const + { + Quaternion quat(*this); + quat.Conjugate(); + + return quat; + } + + template + Quaternion Quaternion::GetInverse() const + { + Quaternion quat(*this); + quat.Inverse(); + + return quat; + } + + template + Quaternion Quaternion::GetNormal(T* length) const + { + Quaternion quat(*this); + quat.Normalize(length); + + return quat; + } + + template + Quaternion& Quaternion::Inverse() + { + T norm = SquaredMagnitude(); + if (norm > F(0.0)) + { + T invNorm = F(1.0) / norm; + + w *= invNorm; + x *= -invNorm; + y *= -invNorm; + z *= -invNorm; + } + + return *this; + } + + template + Quaternion& Quaternion::MakeIdentity() + { + return Set(F(1.0), F(0.0), F(0.0), F(0.0)); + } + + template + Quaternion& Quaternion::MakeRotationBetween(const Vector3& from, const Vector3& to) + { + T dot = from.DotProduct(to); + if (NumberEquals(dot, F(-1.0))) + { + Vector3 cross = Vector3::CrossProduct(Vector3::UnitX(), from); + if (NumberEquals(cross.GetLength(), F(0.0))) + cross = Vector3::CrossProduct(Vector3::UnitY(), from); + + return Set(F(180.0), cross); + } + else if (NumberEquals(dot, F(1.0))) + return MakeIdentity(); + else + { + Vector3 a = from.CrossProduct(to); + x = a.x; + y = a.y; + z = a.z; + w = T(1.0) + dot; + + return Normalize(); + } + } + + template + Quaternion& Quaternion::MakeZero() + { + return Set(F(0.0), F(0.0), F(0.0), F(0.0)); + } + + template + T Quaternion::Magnitude() const + { + return std::sqrt(SquaredMagnitude()); + } + + template + Quaternion& Quaternion::Normalize(T* length) + { + T norm = std::sqrt(SquaredMagnitude()); T invNorm = F(1.0) / norm; w *= invNorm; - x *= -invNorm; - y *= -invNorm; - z *= -invNorm; + x *= invNorm; + y *= invNorm; + z *= invNorm; + + if (length) + *length = norm; + + return *this; } - return *this; -} - -template -NzQuaternion& NzQuaternion::MakeIdentity() -{ - return Set(F(1.0), F(0.0), F(0.0), F(0.0)); -} - -template -NzQuaternion& NzQuaternion::MakeRotationBetween(const NzVector3& from, const NzVector3& to) -{ - T dot = from.DotProduct(to); - if (NzNumberEquals(dot, F(-1.0))) + template + Quaternion& Quaternion::Set(T W, T X, T Y, T Z) { - NzVector3 cross = NzVector3::CrossProduct(NzVector3::UnitX(), from); - if (NzNumberEquals(cross.GetLength(), F(0.0))) - cross = NzVector3::CrossProduct(NzVector3::UnitY(), from); + w = W; + x = X; + y = Y; + z = Z; - return Set(F(180.0), cross); + return *this; } - else if (NzNumberEquals(dot, F(1.0))) - return MakeIdentity(); - else + + template + Quaternion& Quaternion::Set(const T quat[4]) { - NzVector3 a = from.CrossProduct(to); - x = a.x; - y = a.y; - z = a.z; - w = T(1.0) + dot; + w = quat[0]; + x = quat[1]; + y = quat[2]; + z = quat[3]; + + return *this; + } + + template + Quaternion& Quaternion::Set(T angle, const Vector3& axis) + { + #if !NAZARA_MATH_ANGLE_RADIAN + angle = NzDegreeToRadian(angle); + #endif + + angle /= F(2.0); + + Vector3 normalizedAxis = axis.GetNormal(); + + T sinAngle = std::sin(angle); + + w = std::cos(angle); + x = normalizedAxis.x * sinAngle; + y = normalizedAxis.y * sinAngle; + z = normalizedAxis.z * sinAngle; return Normalize(); } -} -template -NzQuaternion& NzQuaternion::MakeZero() -{ - return Set(F(0.0), F(0.0), F(0.0), F(0.0)); -} - -template -T NzQuaternion::Magnitude() const -{ - return std::sqrt(SquaredMagnitude()); -} - -template -NzQuaternion& NzQuaternion::Normalize(T* length) -{ - T norm = std::sqrt(SquaredMagnitude()); - T invNorm = F(1.0) / norm; - - w *= invNorm; - x *= invNorm; - y *= invNorm; - z *= invNorm; - - if (length) - *length = norm; - - return *this; -} - -template -NzQuaternion& NzQuaternion::Set(T W, T X, T Y, T Z) -{ - w = W; - x = X; - y = Y; - z = Z; - - return *this; -} - -template -NzQuaternion& NzQuaternion::Set(const T quat[4]) -{ - w = quat[0]; - x = quat[1]; - y = quat[2]; - z = quat[3]; - - return *this; -} - -template -NzQuaternion& NzQuaternion::Set(T angle, const NzVector3& axis) -{ - #if !NAZARA_MATH_ANGLE_RADIAN - angle = NzDegreeToRadian(angle); - #endif - - angle /= F(2.0); - - NzVector3 normalizedAxis = axis.GetNormal(); - - T sinAngle = std::sin(angle); - - w = std::cos(angle); - x = normalizedAxis.x * sinAngle; - y = normalizedAxis.y * sinAngle; - z = normalizedAxis.z * sinAngle; - - return Normalize(); -} - -template -NzQuaternion& NzQuaternion::Set(const NzEulerAngles& angles) -{ - return Set(angles.ToQuaternion()); -} - -template -template -NzQuaternion& NzQuaternion::Set(const NzQuaternion& quat) -{ - w = F(quat.w); - x = F(quat.x); - y = F(quat.y); - z = F(quat.z); - - return *this; -} - -template -NzQuaternion& NzQuaternion::Set(const NzQuaternion& quat) -{ - std::memcpy(this, &quat, sizeof(NzQuaternion)); - - return *this; -} - -template -T NzQuaternion::SquaredMagnitude() const -{ - return w*w + x*x + y*y + z*z; -} - -template -NzEulerAngles NzQuaternion::ToEulerAngles() const -{ - T test = x*y + z*w; - if (test > F(0.499)) - // singularity at north pole - return NzEulerAngles(NzFromDegrees(F(90.0)), NzFromRadians(F(2.0) * std::atan2(x, w)), F(0.0)); - - if (test < F(-0.499)) - return NzEulerAngles(NzFromDegrees(F(-90.0)), NzFromRadians(F(-2.0) * std::atan2(x, w)), F(0.0)); - - return NzEulerAngles(NzFromRadians(std::atan2(F(2.0)*x*w - F(2.0)*y*z, F(1.0) - F(2.0)*x*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 -NzString NzQuaternion::ToString() const -{ - NzStringStream ss; - - return ss << "Quaternion(" << w << " | " << x << ", " << y << ", " << z << ')'; -} - -template -NzQuaternion& NzQuaternion::operator=(const NzQuaternion& quat) -{ - return Set(quat); -} - -template -NzQuaternion NzQuaternion::operator+(const NzQuaternion& quat) const -{ - NzQuaternion result; - result.w = w + quat.w; - result.x = x + quat.x; - result.y = y + quat.y; - result.z = z + quat.z; - - return result; -} - -template -NzQuaternion NzQuaternion::operator*(const NzQuaternion& quat) const -{ - NzQuaternion result; - result.w = w*quat.w - x*quat.x - y*quat.y - z*quat.z; - result.x = w*quat.x + x*quat.w + y*quat.z - z*quat.y; - result.y = w*quat.y + y*quat.w + z*quat.x - x*quat.z; - result.z = w*quat.z + z*quat.w + x*quat.y - y*quat.x; - - return result; -} - -template -NzVector3 NzQuaternion::operator*(const NzVector3& vec) const -{ - NzVector3f quatVec(x, y, z); - NzVector3f uv = quatVec.CrossProduct(vec); - NzVector3f uuv = quatVec.CrossProduct(uv); - uv *= F(2.0) * w; - uuv *= F(2.0); - - return vec + uv + uuv; -} - -template -NzQuaternion NzQuaternion::operator*(T scale) const -{ - return NzQuaternion(w * scale, - x * scale, - y * scale, - z * scale); -} - -template -NzQuaternion NzQuaternion::operator/(const NzQuaternion& quat) const -{ - return quat.GetConjugate() * (*this); -} - -template -NzQuaternion& NzQuaternion::operator+=(const NzQuaternion& quat) -{ - return operator=(operator+(quat)); -} - -template -NzQuaternion& NzQuaternion::operator*=(const NzQuaternion& quat) -{ - return operator=(operator*(quat)); -} - -template -NzQuaternion& NzQuaternion::operator*=(T scale) -{ - return operator=(operator*(scale)); -} - -template -NzQuaternion& NzQuaternion::operator/=(const NzQuaternion& quat) -{ - return operator=(operator/(quat)); -} - -template -bool NzQuaternion::operator==(const NzQuaternion& quat) const -{ - return NzNumberEquals(w, quat.w) && - NzNumberEquals(x, quat.x) && - NzNumberEquals(y, quat.y) && - NzNumberEquals(z, quat.z); -} - -template -bool NzQuaternion::operator!=(const NzQuaternion& quat) const -{ - return !operator==(quat); -} - -template -NzQuaternion NzQuaternion::Identity() -{ - NzQuaternion quaternion; - quaternion.MakeIdentity(); - - return quaternion; -} - -template -NzQuaternion NzQuaternion::Lerp(const NzQuaternion& from, const NzQuaternion& to, T interpolation) -{ - #ifdef NAZARA_DEBUG - if (interpolation < F(0.0) || interpolation > F(1.0)) + template + Quaternion& Quaternion::Set(const EulerAngles& angles) { - NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')'); - return Zero(); - } - #endif - - NzQuaternion interpolated; - interpolated.w = NzLerp(from.w, to.w, interpolation); - interpolated.x = NzLerp(from.x, to.x, interpolation); - interpolated.y = NzLerp(from.y, to.y, interpolation); - interpolated.z = NzLerp(from.z, to.z, interpolation); - - return interpolated; -} - -template -NzQuaternion NzQuaternion::Normalize(const NzQuaternion& quat, T* length) -{ - return quat.GetNormal(length); -} - -template -NzQuaternion NzQuaternion::RotationBetween(const NzVector3& from, const NzVector3& to) -{ - NzQuaternion quaternion; - quaternion.MakeRotationBetween(from, to); - - return quaternion; -} - -template -NzQuaternion NzQuaternion::Slerp(const NzQuaternion& from, const NzQuaternion& to, T interpolation) -{ - #ifdef NAZARA_DEBUG - if (interpolation < F(0.0) || interpolation > F(1.0)) - { - NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')'); - return Zero(); - } - #endif - - NzQuaternion q; - - T cosOmega = from.DotProduct(to); - if (cosOmega < F(0.0)) - { - // On inverse tout - q.Set(-to.w, -to.x, -to.y, -to.z); - cosOmega = -cosOmega; - } - else - q.Set(to); - - T k0, k1; - if (cosOmega > F(0.9999)) - { - // Interpolation linéaire pour éviter une division par zéro - k0 = F(1.0) - interpolation; - k1 = interpolation; - } - else - { - T sinOmega = std::sqrt(F(1.0) - cosOmega*cosOmega); - T omega = std::atan2(sinOmega, cosOmega); - - // Pour éviter deux divisions - sinOmega = F(1.0)/sinOmega; - - k0 = std::sin((F(1.0) - interpolation) * omega) * sinOmega; - k1 = std::sin(interpolation*omega) * sinOmega; + return Set(angles.ToQuaternion()); } - NzQuaternion result(k0 * from.w, k0 * from.x, k0 * from.y, k0 * from.z); - return result += q*k1; + template + template + Quaternion& Quaternion::Set(const Quaternion& quat) + { + w = F(quat.w); + x = F(quat.x); + y = F(quat.y); + z = F(quat.z); + + return *this; + } + + template + Quaternion& Quaternion::Set(const Quaternion& quat) + { + std::memcpy(this, &quat, sizeof(Quaternion)); + + return *this; + } + + template + T Quaternion::SquaredMagnitude() const + { + return w*w + x*x + y*y + z*z; + } + + template + EulerAngles Quaternion::ToEulerAngles() const + { + T test = x*y + z*w; + if (test > F(0.499)) + // singularity at north pole + return EulerAngles(FromDegrees(F(90.0)), FromRadians(F(2.0) * std::atan2(x, w)), F(0.0)); + + if (test < F(-0.499)) + return EulerAngles(FromDegrees(F(-90.0)), FromRadians(F(-2.0) * std::atan2(x, w)), F(0.0)); + + return EulerAngles(FromRadians(std::atan2(F(2.0)*x*w - F(2.0)*y*z, F(1.0) - F(2.0)*x*x - F(2.0)*z*z)), + FromRadians(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)), + FromRadians(std::asin(F(2.0)*test))); + } + + template + String Quaternion::ToString() const + { + StringStream ss; + + return ss << "Quaternion(" << w << " | " << x << ", " << y << ", " << z << ')'; + } + + template + Quaternion& Quaternion::operator=(const Quaternion& quat) + { + return Set(quat); + } + + template + Quaternion Quaternion::operator+(const Quaternion& quat) const + { + Quaternion result; + result.w = w + quat.w; + result.x = x + quat.x; + result.y = y + quat.y; + result.z = z + quat.z; + + return result; + } + + template + Quaternion Quaternion::operator*(const Quaternion& quat) const + { + Quaternion result; + result.w = w*quat.w - x*quat.x - y*quat.y - z*quat.z; + result.x = w*quat.x + x*quat.w + y*quat.z - z*quat.y; + result.y = w*quat.y + y*quat.w + z*quat.x - x*quat.z; + result.z = w*quat.z + z*quat.w + x*quat.y - y*quat.x; + + return result; + } + + template + Vector3 Quaternion::operator*(const Vector3& vec) const + { + Vector3f quatVec(x, y, z); + Vector3f uv = quatVec.CrossProduct(vec); + Vector3f uuv = quatVec.CrossProduct(uv); + uv *= F(2.0) * w; + uuv *= F(2.0); + + return vec + uv + uuv; + } + + template + Quaternion Quaternion::operator*(T scale) const + { + return Quaternion(w * scale, + x * scale, + y * scale, + z * scale); + } + + template + Quaternion Quaternion::operator/(const Quaternion& quat) const + { + return quat.GetConjugate() * (*this); + } + + template + Quaternion& Quaternion::operator+=(const Quaternion& quat) + { + return operator=(operator+(quat)); + } + + template + Quaternion& Quaternion::operator*=(const Quaternion& quat) + { + return operator=(operator*(quat)); + } + + template + Quaternion& Quaternion::operator*=(T scale) + { + return operator=(operator*(scale)); + } + + template + Quaternion& Quaternion::operator/=(const Quaternion& quat) + { + return operator=(operator/(quat)); + } + + template + bool Quaternion::operator==(const Quaternion& quat) const + { + return NumberEquals(w, quat.w) && + NumberEquals(x, quat.x) && + NumberEquals(y, quat.y) && + NumberEquals(z, quat.z); + } + + template + bool Quaternion::operator!=(const Quaternion& quat) const + { + return !operator==(quat); + } + + template + Quaternion Quaternion::Identity() + { + Quaternion quaternion; + quaternion.MakeIdentity(); + + return quaternion; + } + + template + Quaternion Quaternion::Lerp(const Quaternion& from, const Quaternion& to, T interpolation) + { + #ifdef NAZARA_DEBUG + if (interpolation < F(0.0) || interpolation > F(1.0)) + { + NazaraError("Interpolation must be in range [0..1] (Got " + String::Number(interpolation) + ')'); + return Zero(); + } + #endif + + Quaternion interpolated; + interpolated.w = Lerp(from.w, to.w, interpolation); + interpolated.x = Lerp(from.x, to.x, interpolation); + interpolated.y = Lerp(from.y, to.y, interpolation); + interpolated.z = Lerp(from.z, to.z, interpolation); + + return interpolated; + } + + template + Quaternion Quaternion::Normalize(const Quaternion& quat, T* length) + { + return quat.GetNormal(length); + } + + template + Quaternion Quaternion::RotationBetween(const Vector3& from, const Vector3& to) + { + Quaternion quaternion; + quaternion.MakeRotationBetween(from, to); + + return quaternion; + } + + template + Quaternion Quaternion::Slerp(const Quaternion& from, const Quaternion& to, T interpolation) + { + #ifdef NAZARA_DEBUG + if (interpolation < F(0.0) || interpolation > F(1.0)) + { + NazaraError("Interpolation must be in range [0..1] (Got " + String::Number(interpolation) + ')'); + return Zero(); + } + #endif + + Quaternion q; + + T cosOmega = from.DotProduct(to); + if (cosOmega < F(0.0)) + { + // On inverse tout + q.Set(-to.w, -to.x, -to.y, -to.z); + cosOmega = -cosOmega; + } + else + q.Set(to); + + T k0, k1; + if (cosOmega > F(0.9999)) + { + // Interpolation linéaire pour éviter une division par zéro + k0 = F(1.0) - interpolation; + k1 = interpolation; + } + else + { + T sinOmega = std::sqrt(F(1.0) - cosOmega*cosOmega); + T omega = std::atan2(sinOmega, cosOmega); + + // Pour éviter deux divisions + sinOmega = F(1.0)/sinOmega; + + k0 = std::sin((F(1.0) - interpolation) * omega) * sinOmega; + k1 = std::sin(interpolation*omega) * sinOmega; + } + + Quaternion result(k0 * from.w, k0 * from.x, k0 * from.y, k0 * from.z); + return result += q*k1; + } + + template + Quaternion Quaternion::Zero() + { + Quaternion quaternion; + quaternion.MakeZero(); + + return quaternion; + } } template -NzQuaternion NzQuaternion::Zero() -{ - NzQuaternion quaternion; - quaternion.MakeZero(); - - return quaternion; -} - -template -std::ostream& operator<<(std::ostream& out, const NzQuaternion& quat) +std::ostream& operator<<(std::ostream& out, const Nz::Quaternion& quat) { return out << quat.ToString(); } diff --git a/include/Nazara/Math/Ray.hpp b/include/Nazara/Math/Ray.hpp index 24b25e110..e0ae68363 100644 --- a/include/Nazara/Math/Ray.hpp +++ b/include/Nazara/Math/Ray.hpp @@ -16,62 +16,65 @@ #include #include -template -class NzRay +namespace Nz { - public: - NzRay() = default; - NzRay(T X, T Y, T Z, T directionX, T directionY, T directionZ); - NzRay(const T origin[3], const T direction[3]); - NzRay(const NzPlane& planeOne, const NzPlane& planeTwo); - NzRay(const NzVector3& origin, const NzVector3& direction); - template explicit NzRay(const NzRay& ray); - template explicit NzRay(const NzVector3& origin, const NzVector3& direction); - NzRay(const NzRay& ray) = default; - ~NzRay() = default; + template + class Ray + { + public: + Ray() = default; + Ray(T X, T Y, T Z, T directionX, T directionY, T directionZ); + Ray(const T origin[3], const T direction[3]); + Ray(const Plane& planeOne, const Plane& planeTwo); + Ray(const Vector3& origin, const Vector3& direction); + template explicit Ray(const Ray& ray); + template explicit Ray(const Vector3& origin, const Vector3& direction); + Ray(const Ray& ray) = default; + ~Ray() = default; - T ClosestPoint(const NzVector3& point) const; + T ClosestPoint(const Vector3& point) const; - NzVector3 GetPoint(T lambda) const; + Vector3 GetPoint(T lambda) const; - bool Intersect(const NzBoundingVolume& volume, T* closestHit = nullptr, T* furthestHit = nullptr) const; - bool Intersect(const NzBox& box, T* closestHit = nullptr, T* furthestHit = nullptr) const; - bool Intersect(const NzBox& box, const NzMatrix4& transform, T* closestHit = nullptr, T* furthestHit = nullptr) const; - bool Intersect(const NzOrientedBox& orientedBox, T* closestHit = nullptr, T* furthestHit = nullptr) const; - bool Intersect(const NzPlane& plane, T* hit = nullptr) const; - bool Intersect(const NzSphere& sphere, T* closestHit = nullptr, T* furthestHit = nullptr) const; + bool Intersect(const BoundingVolume& volume, T* closestHit = nullptr, T* furthestHit = nullptr) const; + bool Intersect(const Box& box, T* closestHit = nullptr, T* furthestHit = nullptr) const; + bool Intersect(const Box& box, const Matrix4& transform, T* closestHit = nullptr, T* furthestHit = nullptr) const; + bool Intersect(const OrientedBox& orientedBox, T* closestHit = nullptr, T* furthestHit = nullptr) const; + bool Intersect(const Plane& plane, T* hit = nullptr) const; + bool Intersect(const Sphere& sphere, T* closestHit = nullptr, T* furthestHit = nullptr) const; - NzRay& MakeAxisX(); - NzRay& MakeAxisY(); - NzRay& MakeAxisZ(); + Ray& MakeAxisX(); + Ray& MakeAxisY(); + Ray& MakeAxisZ(); - NzRay& Set(T X, T Y, T Z, T directionX, T directionY, T directionZ); - NzRay& Set(const T origin[3], const T direction[3]); - NzRay& Set(const NzPlane& planeOne, const NzPlane& planeTwo); - NzRay& Set(const NzRay& ray); - NzRay& Set(const NzVector3& origin, const NzVector3& direction); - template NzRay& Set(const NzRay& ray); - template NzRay& Set(const NzVector3& origin, const NzVector3& direction); + Ray& Set(T X, T Y, T Z, T directionX, T directionY, T directionZ); + Ray& Set(const T origin[3], const T direction[3]); + Ray& Set(const Plane& planeOne, const Plane& planeTwo); + Ray& Set(const Ray& ray); + Ray& Set(const Vector3& origin, const Vector3& direction); + template Ray& Set(const Ray& ray); + template Ray& Set(const Vector3& origin, const Vector3& direction); - NzString ToString() const; + String ToString() const; - NzVector3 operator*(T lambda) const; + Vector3 operator*(T lambda) const; - bool operator==(const NzRay& ray) const; - bool operator!=(const NzRay& ray) const; + bool operator==(const Ray& ray) const; + bool operator!=(const Ray& ray) const; - static NzRay AxisX(); - static NzRay AxisY(); - static NzRay AxisZ(); - static NzRay Lerp(const NzRay& from, const NzRay& to, T interpolation); + static Ray AxisX(); + static Ray AxisY(); + static Ray AxisZ(); + static Ray Lerp(const Ray& from, const Ray& to, T interpolation); - NzVector3 direction, origin; -}; + Vector3 direction, origin; + }; -template std::ostream& operator<<(std::ostream& out, const NzRay& vec); + typedef Ray Rayd; + typedef Ray Rayf; +} -typedef NzRay NzRayd; -typedef NzRay NzRayf; +template std::ostream& operator<<(std::ostream& out, const Nz::Ray& vec); #include diff --git a/include/Nazara/Math/Ray.inl b/include/Nazara/Math/Ray.inl index d0ee2d76c..9f65b5382 100644 --- a/include/Nazara/Math/Ray.inl +++ b/include/Nazara/Math/Ray.inl @@ -8,432 +8,435 @@ #define F(a) static_cast(a) -template -NzRay::NzRay(T X, T Y, T Z, T DirectionX, T DirectionY, T DirectionZ) +namespace Nz { - Set(X, Y, Z, DirectionX, DirectionY, DirectionZ); -} - -template -NzRay::NzRay(const T Origin[3], const T Direction[3]) -{ - Set(Origin, Direction); -} - -template -NzRay::NzRay(const NzPlane& planeOne, const NzPlane& planeTwo) -{ - Set(planeOne, planeTwo); -} - -template -NzRay::NzRay(const NzVector3& Origin, const NzVector3& Direction) -{ - Set(Origin, Direction); -} - -template -template -NzRay::NzRay(const NzRay& ray) -{ - Set(ray); -} - -template -template -NzRay::NzRay(const NzVector3& Origin, const NzVector3& Direction) -{ - Set(Origin, Direction); -} - -template -T NzRay::ClosestPoint(const NzVector3& point) const -{ - NzVector3 delta = point - origin; - T vsq = direction.GetSquaredLength(); - T proj = delta.DotProduct(direction); - - return proj/vsq; -} - -template -NzVector3 NzRay::GetPoint(T lambda) const -{ - return origin + lambda * direction; -} - -template -bool NzRay::Intersect(const NzBoundingVolume& volume, T* closestHit, T* furthestHit) const -{ - switch (volume.extend) + template + Ray::Ray(T X, T Y, T Z, T DirectionX, T DirectionY, T DirectionZ) { - case nzExtend_Finite: - { - if (Intersect(volume.aabb)) - return Intersect(volume.obb, closestHit, furthestHit); - - return false; - } - - case nzExtend_Infinite: - { - if (closestHit) - *closestHit = F(0.0); - - if (furthestHit) - *furthestHit = std::numeric_limits::infinity(); - - return true; - } - - case nzExtend_Null: - return false; + Set(X, Y, Z, DirectionX, DirectionY, DirectionZ); } - NazaraError("Invalid extend type (0x" + NzString::Number(volume.extend, 16) + ')'); - return false; -} - -template -bool NzRay::Intersect(const NzBox& box, T* closestHit, T* furthestHit) const -{ - // http://www.gamedev.net/topic/429443-obb-ray-and-obb-plane-intersection/ - T tfirst = F(0.0); - T tlast = std::numeric_limits::infinity(); - - NzVector3 boxMin = box.GetMinimum(); - NzVector3 boxMax = box.GetMaximum(); - - for (unsigned int i = 0; i < 3; ++i) + template + Ray::Ray(const T Origin[3], const T Direction[3]) { - T dir = direction[i]; - T ori = origin[i]; - T max = boxMax[i]; - T min = boxMin[i]; - - if (NzNumberEquals(dir, F(0.0))) - { - if (ori < max && ori > min) - continue; - - return false; - } - - T tmin = (min - ori) / dir; - T tmax = (max - ori) / dir; - if (tmin > tmax) - std::swap(tmin, tmax); - - if (tmax < tfirst || tmin > tlast) - return false; - - tfirst = std::max(tfirst, tmin); - tlast = std::min(tlast, tmax); + Set(Origin, Direction); } - if (closestHit) - *closestHit = tfirst; - - if (furthestHit) - *furthestHit = tlast; - - return true; -} - -template -bool NzRay::Intersect(const NzBox& box, const NzMatrix4& transform, T* closestHit, T* furthestHit) const -{ - // http://www.opengl-tutorial.org/miscellaneous/clicking-on-objects/picking-with-custom-ray-obb-function/ - // Intersection method from Real-Time Rendering and Essential Mathematics for Games - T tMin = F(0.0); - T tMax = std::numeric_limits::infinity(); - - NzVector3 boxMin = box.GetMinimum(); - NzVector3 boxMax = box.GetMaximum(); - NzVector3 delta = transform.GetTranslation() - origin; - - // Test intersection with the 2 planes perpendicular to the OBB's X axis - for (unsigned int i = 0; i < 3; ++i) + template + Ray::Ray(const Plane& planeOne, const Plane& planeTwo) { - NzVector3 axis(transform(0, i), transform(1, i), transform(2, i)); - T e = axis.DotProduct(delta); - T f = direction.DotProduct(axis); + Set(planeOne, planeTwo); + } - if (!NzNumberEquals(f, F(0.0))) + template + Ray::Ray(const Vector3& Origin, const Vector3& Direction) + { + Set(Origin, Direction); + } + + template + template + Ray::Ray(const Ray& ray) + { + Set(ray); + } + + template + template + Ray::Ray(const Vector3& Origin, const Vector3& Direction) + { + Set(Origin, Direction); + } + + template + T Ray::ClosestPoint(const Vector3& point) const + { + Vector3 delta = point - origin; + T vsq = direction.GetSquaredLength(); + T proj = delta.DotProduct(direction); + + return proj/vsq; + } + + template + Vector3 Ray::GetPoint(T lambda) const + { + return origin + lambda * direction; + } + + template + bool Ray::Intersect(const BoundingVolume& volume, T* closestHit, T* furthestHit) const + { + switch (volume.extend) { - T t1 = (e + boxMin[i]) / f; // Intersection with the "left" plane - T t2 = (e + boxMax[i]) / f; // Intersection with the "right" plane - // t1 and t2 now contain distances betwen ray origin and ray-plane intersections + case Extend_Finite: + { + if (Intersect(volume.aabb)) + return Intersect(volume.obb, closestHit, furthestHit); - // We want t1 to represent the nearest intersection, - // so if it's not the case, invert t1 and t2 - if (t1 > t2) - std::swap(t1, t2); + return false; + } - // tMax is the nearest "far" intersection (amongst the X,Y and Z planes pairs) - if (t2 < tMax) - tMax = t2; + case Extend_Infinite: + { + if (closestHit) + *closestHit = F(0.0); - // tMin is the farthest "near" intersection (amongst the X,Y and Z planes pairs) - if (t1 > tMin) - tMin = t1; + if (furthestHit) + *furthestHit = std::numeric_limits::infinity(); - // And here's the trick : - // If "far" is closer than "near", then there is NO intersection. - if (tMax < tMin) + return true; + } + + case Extend_Null: return false; } - else - // Rare case : the ray is almost parallel to the planes, so they don't have any "intersection" - if (-e + boxMin[i] > F(0.0) || -e + boxMax[i] < F(0.0)) - return false; + + NazaraError("Invalid extend type (0x" + String::Number(volume.extend, 16) + ')'); + return false; } - if (closestHit) - *closestHit = tMin; - - if (furthestHit) - *furthestHit = tMax; - - return true; -} - -template -bool NzRay::Intersect(const NzOrientedBox& orientedBox, T* closestHit, T* furthestHit) const -{ - NzVector3 corner = orientedBox.GetCorner(nzBoxCorner_FarLeftBottom); - NzVector3 oppositeCorner = orientedBox.GetCorner(nzBoxCorner_NearRightTop); - - NzVector3 width = (orientedBox.GetCorner(nzBoxCorner_NearLeftBottom) - corner); - NzVector3 height = (orientedBox.GetCorner(nzBoxCorner_FarLeftTop) - corner); - NzVector3 depth = (orientedBox.GetCorner(nzBoxCorner_FarRightBottom) - corner); - - // Construction de la matrice de transformation de l'OBB - NzMatrix4 matrix(width.x, height.x, depth.x, corner.x, - width.y, height.y, depth.y, corner.y, - width.z, height.z, depth.z, corner.z, - F(0.0), F(0.0), F(0.0), F(1.0)); - - matrix.InverseAffine(); - - corner = matrix.Transform(corner); - oppositeCorner = matrix.Transform(oppositeCorner); - - NzBox tmpBox(corner, oppositeCorner); - NzRay tmpRay(matrix.Transform(origin), matrix.Transform(direction)); - - return tmpRay.Intersect(tmpBox, closestHit, furthestHit); -} - -template -bool NzRay::Intersect(const NzPlane& plane, T* hit) const -{ - T divisor = plane.normal.DotProduct(direction); - if (NzNumberEquals(divisor, F(0.0))) - return false; // perpendicular - - T lambda = -(plane.normal.DotProduct(origin) - plane.distance) / divisor; // The plane is ax + by + cz = d - if (lambda < F(0.0)) - return false; // The plane is 'behind' the ray. - - if (hit) - *hit = lambda; - - return true; -} - -template -bool NzRay::Intersect(const NzSphere& sphere, T* closestHit, T* furthestHit) const -{ - NzVector3 sphereRay = sphere.GetPosition() - origin; - T length = sphereRay.DotProduct(direction); - - if (length < F(0.0)) - return false; // ray is perpendicular to the vector origin - center - - T squaredDistance = sphereRay.GetSquaredLength() - length*length; - T squaredRadius = sphere.radius*sphere.radius; - - if (squaredDistance > squaredRadius) - return false; // if the ray is further than the radius - - // Calcul des points d'intersection si besoin - if (closestHit || furthestHit) + template + bool Ray::Intersect(const Box& box, T* closestHit, T* furthestHit) const { - T deltaLambda = std::sqrt(squaredRadius - squaredDistance); + // http://www.gamedev.net/topic/429443-obb-ray-and-obb-plane-intersection/ + T tfirst = F(0.0); + T tlast = std::numeric_limits::infinity(); + + Vector3 boxMin = box.GetMinimum(); + Vector3 boxMax = box.GetMaximum(); + + for (unsigned int i = 0; i < 3; ++i) + { + T dir = direction[i]; + T ori = origin[i]; + T max = boxMax[i]; + T min = boxMin[i]; + + if (NumberEquals(dir, F(0.0))) + { + if (ori < max && ori > min) + continue; + + return false; + } + + T tmin = (min - ori) / dir; + T tmax = (max - ori) / dir; + if (tmin > tmax) + std::swap(tmin, tmax); + + if (tmax < tfirst || tmin > tlast) + return false; + + tfirst = std::max(tfirst, tmin); + tlast = std::min(tlast, tmax); + } if (closestHit) - *closestHit = length - deltaLambda; + *closestHit = tfirst; if (furthestHit) - *furthestHit = length + deltaLambda; + *furthestHit = tlast; + + return true; } - return true; -} - -template -NzRay& NzRay::MakeAxisX() -{ - return Set(NzVector3::Zero(), NzVector3::UnitX()); -} - -template -NzRay& NzRay::MakeAxisY() -{ - return Set(NzVector3::Zero(), NzVector3::UnitY()); -} - -template -NzRay& NzRay::MakeAxisZ() -{ - return Set(NzVector3::Zero(), NzVector3::UnitZ()); -} - -template -NzRay& NzRay::Set(T X, T Y, T Z, T directionX, T directionY, T directionZ) -{ - direction.Set(directionX, directionY, directionZ); - origin.Set(X, Y, Z); - - return *this; -} - -template -NzRay& NzRay::Set(const T Origin[3], const T Direction[3]) -{ - direction.Set(Direction); - origin.Set(Origin); - - return *this; -} - -template -NzRay& NzRay::Set(const NzPlane& planeOne, const NzPlane& planeTwo) -{ - T termOne = planeOne.normal.GetLength(); - T termTwo = planeOne.normal.DotProduct(planeTwo.normal); - T termFour = planeTwo.normal.GetLength(); - T det = termOne * termFour - termTwo * termTwo; - - #if NAZARA_MATH_SAFE - if (NzNumberEquals(det, F(0.0))) + template + bool Ray::Intersect(const Box& box, const Matrix4& transform, T* closestHit, T* furthestHit) const { - NzString error("Planes are parallel."); + // http://www.opengl-tutorial.org/miscellaneous/clicking-on-objects/picking-with-custom-ray-obb-function/ + // Intersection method from Real-Time Rendering and Essential Mathematics for Games + T tMin = F(0.0); + T tMax = std::numeric_limits::infinity(); - NazaraError(error); - throw std::domain_error(error); + Vector3 boxMin = box.GetMinimum(); + Vector3 boxMax = box.GetMaximum(); + Vector3 delta = transform.GetTranslation() - origin; + + // Test intersection with the 2 planes perpendicular to the OBB's X axis + for (unsigned int i = 0; i < 3; ++i) + { + Vector3 axis(transform(0, i), transform(1, i), transform(2, i)); + T e = axis.DotProduct(delta); + T f = direction.DotProduct(axis); + + if (!NumberEquals(f, F(0.0))) + { + T t1 = (e + boxMin[i]) / f; // Intersection with the "left" plane + T t2 = (e + boxMax[i]) / f; // Intersection with the "right" plane + // t1 and t2 now contain distances betwen ray origin and ray-plane intersections + + // We want t1 to represent the nearest intersection, + // so if it's not the case, invert t1 and t2 + if (t1 > t2) + std::swap(t1, t2); + + // tMax is the nearest "far" intersection (amongst the X,Y and Z planes pairs) + if (t2 < tMax) + tMax = t2; + + // tMin is the farthest "near" intersection (amongst the X,Y and Z planes pairs) + if (t1 > tMin) + tMin = t1; + + // And here's the trick : + // If "far" is closer than "near", then there is NO intersection. + if (tMax < tMin) + return false; + } + else + // Rare case : the ray is almost parallel to the planes, so they don't have any "intersection" + if (-e + boxMin[i] > F(0.0) || -e + boxMax[i] < F(0.0)) + return false; + } + + if (closestHit) + *closestHit = tMin; + + if (furthestHit) + *furthestHit = tMax; + + return true; } - #endif - T invdet = F(1.0) / det; - T fc0 = (termFour * -planeOne.distance + termTwo * planeTwo.distance) * invdet; - T fc1 = (termOne * -planeTwo.distance + termTwo * planeOne.distance) * invdet; + template + bool Ray::Intersect(const OrientedBox& orientedBox, T* closestHit, T* furthestHit) const + { + Vector3 corner = orientedBox.GetCorner(BoxCorner_FarLeftBottom); + Vector3 oppositeCorner = orientedBox.GetCorner(BoxCorner_NearRightTop); - direction = planeOne.normal.CrossProduct(planeTwo.normal); - origin = planeOne.normal * fc0 + planeTwo.normal * fc1; + Vector3 width = (orientedBox.GetCorner(BoxCorner_NearLeftBottom) - corner); + Vector3 height = (orientedBox.GetCorner(BoxCorner_FarLeftTop) - corner); + Vector3 depth = (orientedBox.GetCorner(BoxCorner_FarRightBottom) - corner); - return *this; + // Construction de la matrice de transformation de l'OBB + Matrix4 matrix(width.x, height.x, depth.x, corner.x, + width.y, height.y, depth.y, corner.y, + width.z, height.z, depth.z, corner.z, + F(0.0), F(0.0), F(0.0), F(1.0)); + + matrix.InverseAffine(); + + corner = matrix.Transform(corner); + oppositeCorner = matrix.Transform(oppositeCorner); + + Box tmpBox(corner, oppositeCorner); + Ray tmpRay(matrix.Transform(origin), matrix.Transform(direction)); + + return tmpRay.Intersect(tmpBox, closestHit, furthestHit); + } + + template + bool Ray::Intersect(const Plane& plane, T* hit) const + { + T divisor = plane.normal.DotProduct(direction); + if (NumberEquals(divisor, F(0.0))) + return false; // perpendicular + + T lambda = -(plane.normal.DotProduct(origin) - plane.distance) / divisor; // The plane is ax + by + cz = d + if (lambda < F(0.0)) + return false; // The plane is 'behind' the ray. + + if (hit) + *hit = lambda; + + return true; + } + + template + bool Ray::Intersect(const Sphere& sphere, T* closestHit, T* furthestHit) const + { + Vector3 sphereRay = sphere.GetPosition() - origin; + T length = sphereRay.DotProduct(direction); + + if (length < F(0.0)) + return false; // ray is perpendicular to the vector origin - center + + T squaredDistance = sphereRay.GetSquaredLength() - length*length; + T squaredRadius = sphere.radius*sphere.radius; + + if (squaredDistance > squaredRadius) + return false; // if the ray is further than the radius + + // Calcul des points d'intersection si besoin + if (closestHit || furthestHit) + { + T deltaLambda = std::sqrt(squaredRadius - squaredDistance); + + if (closestHit) + *closestHit = length - deltaLambda; + + if (furthestHit) + *furthestHit = length + deltaLambda; + } + + return true; + } + + template + Ray& Ray::MakeAxisX() + { + return Set(Vector3::Zero(), Vector3::UnitX()); + } + + template + Ray& Ray::MakeAxisY() + { + return Set(Vector3::Zero(), Vector3::UnitY()); + } + + template + Ray& Ray::MakeAxisZ() + { + return Set(Vector3::Zero(), Vector3::UnitZ()); + } + + template + Ray& Ray::Set(T X, T Y, T Z, T directionX, T directionY, T directionZ) + { + direction.Set(directionX, directionY, directionZ); + origin.Set(X, Y, Z); + + return *this; + } + + template + Ray& Ray::Set(const T Origin[3], const T Direction[3]) + { + direction.Set(Direction); + origin.Set(Origin); + + return *this; + } + + template + Ray& Ray::Set(const Plane& planeOne, const Plane& planeTwo) + { + T termOne = planeOne.normal.GetLength(); + T termTwo = planeOne.normal.DotProduct(planeTwo.normal); + T termFour = planeTwo.normal.GetLength(); + T det = termOne * termFour - termTwo * termTwo; + + #if NAZARA_MATH_SAFE + if (NumberEquals(det, F(0.0))) + { + String error("Planes are parallel."); + + NazaraError(error); + throw std::domain_error(error); + } + #endif + + T invdet = F(1.0) / det; + T fc0 = (termFour * -planeOne.distance + termTwo * planeTwo.distance) * invdet; + T fc1 = (termOne * -planeTwo.distance + termTwo * planeOne.distance) * invdet; + + direction = planeOne.normal.CrossProduct(planeTwo.normal); + origin = planeOne.normal * fc0 + planeTwo.normal * fc1; + + return *this; + } + + template + Ray& Ray::Set(const Ray& ray) + { + std::memcpy(this, &ray, sizeof(Ray)); + + return *this; + } + + template + Ray& Ray::Set(const Vector3& Origin, const Vector3& Direction) + { + direction = Direction; + origin = Origin; + + return *this; + } + + template + template + Ray& Ray::Set(const Ray& ray) + { + direction.Set(ray.direction); + origin.Set(ray.origin); + + return *this; + } + + template + template + Ray& Ray::Set(const Vector3& Origin, const Vector3& Direction) + { + direction.Set(Direction); + origin.Set(Origin); + + return *this; + } + + template + String Ray::ToString() const + { + StringStream ss; + + return ss << "Ray(origin: " << origin.ToString() << ", direction: " << direction.ToString() << ")"; + } + + template + Vector3 Ray::operator*(T lambda) const + { + return GetPoint(lambda); + } + + template + bool Ray::operator==(const Ray& ray) const + { + return direction == ray.direction && origin == ray.origin; + } + + template + bool Ray::operator!=(const Ray& ray) const + { + return !operator==(ray); + } + + template + Ray Ray::AxisX() + { + Ray axis; + axis.MakeAxisX(); + + return axis; + } + + template + Ray Ray::AxisY() + { + Ray axis; + axis.MakeAxisY(); + + return axis; + } + + template + Ray Ray::AxisZ() + { + Ray axis; + axis.MakeAxisZ(); + + return axis; + } + + template + Ray Ray::Lerp(const Ray& from, const Ray& to, T interpolation) + { + return Ray(from.origin.Lerp(to.origin, interpolation), from.direction.Lerp(to.direction, interpolation)); + } } template -NzRay& NzRay::Set(const NzRay& ray) -{ - std::memcpy(this, &ray, sizeof(NzRay)); - - return *this; -} - -template -NzRay& NzRay::Set(const NzVector3& Origin, const NzVector3& Direction) -{ - direction = Direction; - origin = Origin; - - return *this; -} - -template -template -NzRay& NzRay::Set(const NzRay& ray) -{ - direction.Set(ray.direction); - origin.Set(ray.origin); - - return *this; -} - -template -template -NzRay& NzRay::Set(const NzVector3& Origin, const NzVector3& Direction) -{ - direction.Set(Direction); - origin.Set(Origin); - - return *this; -} - -template -NzString NzRay::ToString() const -{ - NzStringStream ss; - - return ss << "Ray(origin: " << origin.ToString() << ", direction: " << direction.ToString() << ")"; -} - -template -NzVector3 NzRay::operator*(T lambda) const -{ - return GetPoint(lambda); -} - -template -bool NzRay::operator==(const NzRay& ray) const -{ - return direction == ray.direction && origin == ray.origin; -} - -template -bool NzRay::operator!=(const NzRay& ray) const -{ - return !operator==(ray); -} - -template -NzRay NzRay::AxisX() -{ - NzRay axis; - axis.MakeAxisX(); - - return axis; -} - -template -NzRay NzRay::AxisY() -{ - NzRay axis; - axis.MakeAxisY(); - - return axis; -} - -template -NzRay NzRay::AxisZ() -{ - NzRay axis; - axis.MakeAxisZ(); - - return axis; -} - -template -NzRay NzRay::Lerp(const NzRay& from, const NzRay& to, T interpolation) -{ - return NzRay(from.origin.Lerp(to.origin, interpolation), from.direction.Lerp(to.direction, interpolation)); -} - -template -std::ostream& operator<<(std::ostream& out, const NzRay& ray) +std::ostream& operator<<(std::ostream& out, const Nz::Ray& ray) { return out << ray.ToString(); } diff --git a/include/Nazara/Math/Rect.hpp b/include/Nazara/Math/Rect.hpp index cb93b2167..ea468966c 100644 --- a/include/Nazara/Math/Rect.hpp +++ b/include/Nazara/Math/Rect.hpp @@ -11,86 +11,89 @@ #include #include -template -class NzRect +namespace Nz { - public: - NzRect() = default; - NzRect(T Width, T Height); - NzRect(T X, T Y, T Width, T Height); - NzRect(const T rect[4]); - NzRect(const NzVector2& lengths); - NzRect(const NzVector2& vec1, const NzVector2& vec2); - template explicit NzRect(const NzRect& rect); - NzRect(const NzRect& rect) = default; - ~NzRect() = default; + template + class Rect + { + public: + Rect() = default; + Rect(T Width, T Height); + Rect(T X, T Y, T Width, T Height); + Rect(const T rect[4]); + Rect(const Vector2& lengths); + Rect(const Vector2& vec1, const Vector2& vec2); + template explicit Rect(const Rect& rect); + Rect(const Rect& rect) = default; + ~Rect() = default; - bool Contains(T X, T Y) const; - bool Contains(const NzVector2& point) const; - bool Contains(const NzRect& rect) const; + bool Contains(T X, T Y) const; + bool Contains(const Vector2& point) const; + bool Contains(const Rect& rect) const; - NzRect& ExtendTo(T X, T Y); - NzRect& ExtendTo(const NzVector2& point); - NzRect& ExtendTo(const NzRect& rect); + Rect& ExtendTo(T X, T Y); + Rect& ExtendTo(const Vector2& point); + Rect& ExtendTo(const Rect& rect); - NzVector2 GetCenter() const; - NzVector2 GetCorner(nzRectCorner corner) const; - NzVector2 GetLengths() const; - NzVector2 GetMaximum() const; - NzVector2 GetMinimum() const; - NzVector2 GetNegativeVertex(const NzVector2& normal) const; - NzVector2 GetPosition() const; - NzVector2 GetPositiveVertex(const NzVector2& normal) const; + Vector2 GetCenter() const; + Vector2 GetCorner(RectCorner corner) const; + Vector2 GetLengths() const; + Vector2 GetMaximum() const; + Vector2 GetMinimum() const; + Vector2 GetNegativeVertex(const Vector2& normal) const; + Vector2 GetPosition() const; + Vector2 GetPositiveVertex(const Vector2& normal) const; - bool Intersect(const NzRect& rect, NzRect* intersection = nullptr) const; + bool Intersect(const Rect& rect, Rect* intersection = nullptr) const; - bool IsValid() const; + bool IsValid() const; - NzRect& MakeZero(); + Rect& MakeZero(); - NzRect& Set(T Width, T Height); - NzRect& Set(T X, T Y, T Width, T Height); - NzRect& Set(const T rect[4]); - NzRect& Set(const NzRect& rect); - NzRect& Set(const NzVector2& lengths); - NzRect& Set(const NzVector2& vec1, const NzVector2& vec2); - template NzRect& Set(const NzRect& rect); + Rect& Set(T Width, T Height); + Rect& Set(T X, T Y, T Width, T Height); + Rect& Set(const T rect[4]); + Rect& Set(const Rect& rect); + Rect& Set(const Vector2& lengths); + Rect& Set(const Vector2& vec1, const Vector2& vec2); + template Rect& Set(const Rect& rect); - NzString ToString() const; + String ToString() const; - NzRect& Translate(const NzVector2& translation); + Rect& Translate(const Vector2& translation); - T& operator[](unsigned int i); - T operator[](unsigned int i) const; + T& operator[](unsigned int i); + T operator[](unsigned int i) const; - NzRect operator*(T scalar) const; - NzRect operator*(const NzVector2& vec) const; - NzRect operator/(T scalar) const; - NzRect operator/(const NzVector2& vec) const; + Rect operator*(T scalar) const; + Rect operator*(const Vector2& vec) const; + Rect operator/(T scalar) const; + Rect operator/(const Vector2& vec) const; - NzRect& operator*=(T scalar); - NzRect& operator*=(const NzVector2& vec); - NzRect& operator/=(T scalar); - NzRect& operator/=(const NzVector2& vec); + Rect& operator*=(T scalar); + Rect& operator*=(const Vector2& vec); + Rect& operator/=(T scalar); + Rect& operator/=(const Vector2& vec); - bool operator==(const NzRect& rect) const; - bool operator!=(const NzRect& rect) const; + bool operator==(const Rect& rect) const; + bool operator!=(const Rect& rect) const; - static NzRect Lerp(const NzRect& from, const NzRect& to, T interpolation); - static NzRect Zero(); + static Rect Lerp(const Rect& from, const Rect& to, T interpolation); + static Rect Zero(); - T x, y, width, height; -}; + T x, y, width, height; + }; + + typedef Rect Rectd; + typedef Rect Rectf; + typedef Rect Recti; + typedef Rect Rectui; + typedef Rect Recti32; + typedef Rect Rectui32; +} template -std::ostream& operator<<(std::ostream& out, const NzRect& rect); - -typedef NzRect NzRectd; -typedef NzRect NzRectf; -typedef NzRect NzRecti; -typedef NzRect NzRectui; -typedef NzRect NzRecti32; -typedef NzRect NzRectui32; +std::ostream& operator<<(std::ostream& out, const Nz::Rect& rect); #include diff --git a/include/Nazara/Math/Rect.inl b/include/Nazara/Math/Rect.inl index 9dc595708..80c47ae29 100644 --- a/include/Nazara/Math/Rect.inl +++ b/include/Nazara/Math/Rect.inl @@ -10,446 +10,449 @@ #define F(a) static_cast(a) -template -NzRect::NzRect(T Width, T Height) +namespace Nz { - Set(Width, Height); -} - -template -NzRect::NzRect(T X, T Y, T Width, T Height) -{ - Set(X, Y, Width, Height); -} - -template -NzRect::NzRect(const T vec[4]) -{ - Set(vec); -} - -template -NzRect::NzRect(const NzVector2& lengths) -{ - Set(lengths); -} - -template -NzRect::NzRect(const NzVector2& vec1, const NzVector2& vec2) -{ - Set(vec1, vec2); -} - -template -template -NzRect::NzRect(const NzRect& rect) -{ - Set(rect); -} - -template -bool NzRect::Contains(T X, T Y) const -{ - return X >= x && X <= x+width && - Y >= y && Y <= y+height; -} - -template -bool NzRect::Contains(const NzVector2& point) const -{ - return Contains(point.x, point.y); -} - -template -bool NzRect::Contains(const NzRect& rect) const -{ - return Contains(rect.x, rect.y) && - Contains(rect.x + rect.width, rect.y + rect.height); -} - -template -NzRect& NzRect::ExtendTo(T X, T Y) -{ - width = std::max(x + width, X); - height = std::max(y + height, Y); - - x = std::min(x, X); - y = std::min(y, Y); - - width -= x; - height -= y; - - return *this; -} - -template -NzRect& NzRect::ExtendTo(const NzVector2& point) -{ - return ExtendTo(point.x, point.y); -} - -template -NzRect& NzRect::ExtendTo(const NzRect& rect) -{ - width = std::max(x + width, rect.x + rect.width); - height = std::max(y + height, rect.y + rect.height); - - x = std::min(x, rect.x); - y = std::min(y, rect.y); - - width -= x; - height -= y; - - return *this; -} - -template -NzVector2 NzRect::GetCenter() const -{ - return GetPosition() + GetLengths() / F(2.0); -} - -template -NzVector2 NzRect::GetCorner(nzRectCorner corner) const -{ - switch (corner) + template + Rect::Rect(T Width, T Height) { - case nzRectCorner_LeftBottom: - return NzVector2(x, y + height); - - case nzRectCorner_LeftTop: - return NzVector2(x, y); - - case nzRectCorner_RightBottom: - return NzVector2(x + width, y + height); - - case nzRectCorner_RightTop: - return NzVector2(x + width, y); + Set(Width, Height); } - NazaraError("Corner not handled (0x" + NzString::Number(corner, 16) + ')'); - return NzVector2(); -} - -template -NzVector2 NzRect::GetLengths() const -{ - return NzVector2(width, height); -} - -template -NzVector2 NzRect::GetMaximum() const -{ - return GetPosition() + GetLengths(); -} - -template -NzVector2 NzRect::GetMinimum() const -{ - ///DOC: Alias de GetPosition() - return GetPosition(); -} - -template -NzVector2 NzRect::GetNegativeVertex(const NzVector2& normal) const -{ - NzVector2 neg(GetPosition()); - - if (normal.x < F(0.0)) - neg.x += width; - - if (normal.y < F(0.0)) - neg.y += height; - - return neg; -} - -template -NzVector2 NzRect::GetPosition() const -{ - return NzVector2(x, y); -} - -template -NzVector2 NzRect::GetPositiveVertex(const NzVector2& normal) const -{ - NzVector2 pos(GetPosition()); - - if (normal.x > F(0.0)) - pos.x += width; - - if (normal.y > F(0.0)) - pos.y += height; - - return pos; -} - -template -bool NzRect::Intersect(const NzRect& rect, NzRect* intersection) const -{ - T left = std::max(x, rect.x); - T right = std::min(x + width, rect.x + rect.width); - if (left >= right) - return false; - - T top = std::max(y, rect.y); - T bottom = std::min(y + height, rect.y + rect.height); - if (top >= bottom) - return false; - - if (intersection) + template + Rect::Rect(T X, T Y, T Width, T Height) { - intersection->x = left; - intersection->y = top; - intersection->width = right - left; - intersection->height = bottom - top; + Set(X, Y, Width, Height); } - return true; -} - -template -bool NzRect::IsValid() const -{ - return width > F(0.0) && height > F(0.0); -} - -template -NzRect& NzRect::MakeZero() -{ - x = F(0.0); - y = F(0.0); - width = F(0.0); - height = F(0.0); - - return *this; -} - -template -NzRect& NzRect::Set(T Width, T Height) -{ - x = F(0.0); - y = F(0.0); - width = Width; - height = Height; - - return *this; -} - -template -NzRect& NzRect::Set(T X, T Y, T Width, T Height) -{ - x = X; - y = Y; - width = Width; - height = Height; - - return *this; -} - -template -NzRect& NzRect::Set(const T rect[4]) -{ - x = rect[0]; - y = rect[1]; - width = rect[2]; - height = rect[3]; - - return *this; -} - -template -NzRect& NzRect::Set(const NzRect& rect) -{ - std::memcpy(this, &rect, sizeof(NzRect)); - - return *this; -} - -template -NzRect& NzRect::Set(const NzVector2& lengths) -{ - return Set(lengths.x, lengths.y); -} - -template -NzRect& NzRect::Set(const NzVector2& vec1, const NzVector2& vec2) -{ - x = std::min(vec1.x, vec2.x); - y = std::min(vec1.y, vec2.y); - width = (vec2.x > vec1.x) ? vec2.x-vec1.x : vec1.x-vec2.x; - height = (vec2.y > vec1.y) ? vec2.y-vec1.y : vec1.y-vec2.y; - - return *this; -} - -template -template -NzRect& NzRect::Set(const NzRect& rect) -{ - x = F(rect.x); - y = F(rect.y); - width = F(rect.width); - height = F(rect.height); - - return *this; -} - -template -NzString NzRect::ToString() const -{ - NzStringStream ss; - - return ss << "Rect(" << x << ", " << y << ", " << width << ", " << height << ')'; -} - -template -NzRect& NzRect::Translate(const NzVector2& translation) -{ - x += translation.x; - y += translation.y; - - return *this; -} - -template -T& NzRect::operator[](unsigned int i) -{ - #if NAZARA_MATH_SAFE - if (i >= 4) + template + Rect::Rect(const T vec[4]) { - NzStringStream ss; - ss << "Index out of range: (" << i << " >= 4)"; - - NazaraError(ss); - throw std::domain_error(ss.ToString()); + Set(vec); } - #endif - return *(&x+i); -} - -template -T NzRect::operator[](unsigned int i) const -{ - #if NAZARA_MATH_SAFE - if (i >= 4) + template + Rect::Rect(const Vector2& lengths) { - NzStringStream ss; - ss << "Index out of range: (" << i << " >= 4)"; - - NazaraError(ss); - throw std::domain_error(ss.ToString()); + Set(lengths); } - #endif - return *(&x+i); -} - -template -NzRect NzRect::operator*(T scalar) const -{ - return NzRect(x, y, width*scalar, height*scalar); -} - -template -NzRect NzRect::operator*(const NzVector2& vec) const -{ - return NzRect(x, y, width*vec.x, height*vec.y); -} - -template -NzRect NzRect::operator/(T scalar) const -{ - return NzRect(x, y, width/scalar, height/scalar); -} - -template -NzRect NzRect::operator/(const NzVector2& vec) const -{ - return NzRect(x, y, width/vec.x, height/vec.y); -} - -template -NzRect& NzRect::operator*=(T scalar) -{ - width *= scalar; - height *= scalar; - - return *this; -} - -template -NzRect& NzRect::operator*=(const NzVector2& vec) -{ - width *= vec.x; - height *= vec.y; - - return *this; -} - -template -NzRect& NzRect::operator/=(T scalar) -{ - width /= scalar; - height /= scalar; - - return *this; -} - -template -NzRect& NzRect::operator/=(const NzVector2& vec) -{ - width /= vec.x; - height /= vec.y; - - return *this; -} - -template -bool NzRect::operator==(const NzRect& rect) const -{ - return NzNumberEquals(x, rect.x) && NzNumberEquals(y, rect.y) && - NzNumberEquals(width, rect.width) && NzNumberEquals(height, rect.height); -} - -template -bool NzRect::operator!=(const NzRect& rect) const -{ - return !operator==(rect); -} - -template -NzRect NzRect::Lerp(const NzRect& from, const NzRect& to, T interpolation) -{ - #ifdef NAZARA_DEBUG - if (interpolation < F(0.0) || interpolation > F(1.0)) + template + Rect::Rect(const Vector2& vec1, const Vector2& vec2) { - NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')'); - return Zero(); + Set(vec1, vec2); } - #endif - NzRect rect; - rect.x = NzLerp(from.x, to.x, interpolation); - rect.y = NzLerp(from.y, to.y, interpolation); - rect.width = NzLerp(from.width, to.width, interpolation); - rect.height = NzLerp(from.height, to.height, interpolation); + template + template + Rect::Rect(const Rect& rect) + { + Set(rect); + } - return rect; + template + bool Rect::Contains(T X, T Y) const + { + return X >= x && X <= x+width && + Y >= y && Y <= y+height; + } + + template + bool Rect::Contains(const Vector2& point) const + { + return Contains(point.x, point.y); + } + + template + bool Rect::Contains(const Rect& rect) const + { + return Contains(rect.x, rect.y) && + Contains(rect.x + rect.width, rect.y + rect.height); + } + + template + Rect& Rect::ExtendTo(T X, T Y) + { + width = std::max(x + width, X); + height = std::max(y + height, Y); + + x = std::min(x, X); + y = std::min(y, Y); + + width -= x; + height -= y; + + return *this; + } + + template + Rect& Rect::ExtendTo(const Vector2& point) + { + return ExtendTo(point.x, point.y); + } + + template + Rect& Rect::ExtendTo(const Rect& rect) + { + width = std::max(x + width, rect.x + rect.width); + height = std::max(y + height, rect.y + rect.height); + + x = std::min(x, rect.x); + y = std::min(y, rect.y); + + width -= x; + height -= y; + + return *this; + } + + template + Vector2 Rect::GetCenter() const + { + return GetPosition() + GetLengths() / F(2.0); + } + + template + Vector2 Rect::GetCorner(RectCorner corner) const + { + switch (corner) + { + case RectCorner_LeftBottom: + return Vector2(x, y + height); + + case RectCorner_LeftTop: + return Vector2(x, y); + + case RectCorner_RightBottom: + return Vector2(x + width, y + height); + + case RectCorner_RightTop: + return Vector2(x + width, y); + } + + NazaraError("Corner not handled (0x" + String::Number(corner, 16) + ')'); + return Vector2(); + } + + template + Vector2 Rect::GetLengths() const + { + return Vector2(width, height); + } + + template + Vector2 Rect::GetMaximum() const + { + return GetPosition() + GetLengths(); + } + + template + Vector2 Rect::GetMinimum() const + { + ///DOC: Alias de GetPosition() + return GetPosition(); + } + + template + Vector2 Rect::GetNegativeVertex(const Vector2& normal) const + { + Vector2 neg(GetPosition()); + + if (normal.x < F(0.0)) + neg.x += width; + + if (normal.y < F(0.0)) + neg.y += height; + + return neg; + } + + template + Vector2 Rect::GetPosition() const + { + return Vector2(x, y); + } + + template + Vector2 Rect::GetPositiveVertex(const Vector2& normal) const + { + Vector2 pos(GetPosition()); + + if (normal.x > F(0.0)) + pos.x += width; + + if (normal.y > F(0.0)) + pos.y += height; + + return pos; + } + + template + bool Rect::Intersect(const Rect& rect, Rect* intersection) const + { + T left = std::max(x, rect.x); + T right = std::min(x + width, rect.x + rect.width); + if (left >= right) + return false; + + T top = std::max(y, rect.y); + T bottom = std::min(y + height, rect.y + rect.height); + if (top >= bottom) + return false; + + if (intersection) + { + intersection->x = left; + intersection->y = top; + intersection->width = right - left; + intersection->height = bottom - top; + } + + return true; + } + + template + bool Rect::IsValid() const + { + return width > F(0.0) && height > F(0.0); + } + + template + Rect& Rect::MakeZero() + { + x = F(0.0); + y = F(0.0); + width = F(0.0); + height = F(0.0); + + return *this; + } + + template + Rect& Rect::Set(T Width, T Height) + { + x = F(0.0); + y = F(0.0); + width = Width; + height = Height; + + return *this; + } + + template + Rect& Rect::Set(T X, T Y, T Width, T Height) + { + x = X; + y = Y; + width = Width; + height = Height; + + return *this; + } + + template + Rect& Rect::Set(const T rect[4]) + { + x = rect[0]; + y = rect[1]; + width = rect[2]; + height = rect[3]; + + return *this; + } + + template + Rect& Rect::Set(const Rect& rect) + { + std::memcpy(this, &rect, sizeof(Rect)); + + return *this; + } + + template + Rect& Rect::Set(const Vector2& lengths) + { + return Set(lengths.x, lengths.y); + } + + template + Rect& Rect::Set(const Vector2& vec1, const Vector2& vec2) + { + x = std::min(vec1.x, vec2.x); + y = std::min(vec1.y, vec2.y); + width = (vec2.x > vec1.x) ? vec2.x-vec1.x : vec1.x-vec2.x; + height = (vec2.y > vec1.y) ? vec2.y-vec1.y : vec1.y-vec2.y; + + return *this; + } + + template + template + Rect& Rect::Set(const Rect& rect) + { + x = F(rect.x); + y = F(rect.y); + width = F(rect.width); + height = F(rect.height); + + return *this; + } + + template + String Rect::ToString() const + { + StringStream ss; + + return ss << "Rect(" << x << ", " << y << ", " << width << ", " << height << ')'; + } + + template + Rect& Rect::Translate(const Vector2& translation) + { + x += translation.x; + y += translation.y; + + return *this; + } + + template + T& Rect::operator[](unsigned int i) + { + #if NAZARA_MATH_SAFE + if (i >= 4) + { + StringStream ss; + ss << "Index out of range: (" << i << " >= 4)"; + + NazaraError(ss); + throw std::domain_error(ss.ToString()); + } + #endif + + return *(&x+i); + } + + template + T Rect::operator[](unsigned int i) const + { + #if NAZARA_MATH_SAFE + if (i >= 4) + { + StringStream ss; + ss << "Index out of range: (" << i << " >= 4)"; + + NazaraError(ss); + throw std::domain_error(ss.ToString()); + } + #endif + + return *(&x+i); + } + + template + Rect Rect::operator*(T scalar) const + { + return Rect(x, y, width*scalar, height*scalar); + } + + template + Rect Rect::operator*(const Vector2& vec) const + { + return Rect(x, y, width*vec.x, height*vec.y); + } + + template + Rect Rect::operator/(T scalar) const + { + return Rect(x, y, width/scalar, height/scalar); + } + + template + Rect Rect::operator/(const Vector2& vec) const + { + return Rect(x, y, width/vec.x, height/vec.y); + } + + template + Rect& Rect::operator*=(T scalar) + { + width *= scalar; + height *= scalar; + + return *this; + } + + template + Rect& Rect::operator*=(const Vector2& vec) + { + width *= vec.x; + height *= vec.y; + + return *this; + } + + template + Rect& Rect::operator/=(T scalar) + { + width /= scalar; + height /= scalar; + + return *this; + } + + template + Rect& Rect::operator/=(const Vector2& vec) + { + width /= vec.x; + height /= vec.y; + + return *this; + } + + template + bool Rect::operator==(const Rect& rect) const + { + return NumberEquals(x, rect.x) && NumberEquals(y, rect.y) && + NumberEquals(width, rect.width) && NumberEquals(height, rect.height); + } + + template + bool Rect::operator!=(const Rect& rect) const + { + return !operator==(rect); + } + + template + Rect Rect::Lerp(const Rect& from, const Rect& to, T interpolation) + { + #ifdef NAZARA_DEBUG + if (interpolation < F(0.0) || interpolation > F(1.0)) + { + NazaraError("Interpolation must be in range [0..1] (Got " + String::Number(interpolation) + ')'); + return Zero(); + } + #endif + + Rect rect; + rect.x = Lerp(from.x, to.x, interpolation); + rect.y = Lerp(from.y, to.y, interpolation); + rect.width = Lerp(from.width, to.width, interpolation); + rect.height = Lerp(from.height, to.height, interpolation); + + return rect; + } + + template + Rect Rect::Zero() + { + Rect rect; + rect.MakeZero(); + + return rect; + } } template -NzRect NzRect::Zero() -{ - NzRect rect; - rect.MakeZero(); - - return rect; -} - -template -std::ostream& operator<<(std::ostream& out, const NzRect& rect) +std::ostream& operator<<(std::ostream& out, const Nz::Rect& rect) { return out << rect.ToString(); } diff --git a/include/Nazara/Math/Sphere.hpp b/include/Nazara/Math/Sphere.hpp index f452ddf4e..e5f976d02 100644 --- a/include/Nazara/Math/Sphere.hpp +++ b/include/Nazara/Math/Sphere.hpp @@ -10,76 +10,78 @@ #include #include -template -class NzBox; - -template -class NzSphere +namespace Nz { - public: - NzSphere() = default; - NzSphere(T X, T Y, T Z, T Radius); - //NzSphere(const NzCircle& circle); - NzSphere(const NzVector3& center, T Radius); - NzSphere(const T sphere[4]); - template explicit NzSphere(const NzSphere& sphere); - NzSphere(const NzSphere& sphere) = default; - ~NzSphere() = default; + template class Box; - bool Contains(T X, T Y, T Z) const; - bool Contains(const NzBox& box) const; - bool Contains(const NzVector3& point) const; + template + class Sphere + { + public: + Sphere() = default; + Sphere(T X, T Y, T Z, T Radius); + //Sphere(const NzCircle& circle); + Sphere(const Vector3& center, T Radius); + Sphere(const T sphere[4]); + template explicit Sphere(const Sphere& sphere); + Sphere(const Sphere& sphere) = default; + ~Sphere() = default; - T Distance(T X, T Y, T Z) const; - T Distance(const NzVector3& point) const; + bool Contains(T X, T Y, T Z) const; + bool Contains(const Box& box) const; + bool Contains(const Vector3& point) const; - NzSphere& ExtendTo(T X, T Y, T Z); - NzSphere& ExtendTo(const NzVector3& point); + T Distance(T X, T Y, T Z) const; + T Distance(const Vector3& point) const; - NzVector3 GetNegativeVertex(const NzVector3& normal) const; - NzVector3 GetPosition() const; - NzVector3 GetPositiveVertex(const NzVector3& normal) const; + Sphere& ExtendTo(T X, T Y, T Z); + Sphere& ExtendTo(const Vector3& point); - bool Intersect(const NzBox& box) const; - bool Intersect(const NzSphere& sphere) const; + Vector3 GetNegativeVertex(const Vector3& normal) const; + Vector3 GetPosition() const; + Vector3 GetPositiveVertex(const Vector3& normal) const; - bool IsValid() const; + bool Intersect(const Box& box) const; + bool Intersect(const Sphere& sphere) const; - NzSphere& MakeZero(); + bool IsValid() const; - NzSphere& Set(T X, T Y, T Z, T Radius); - //NzSphere& Set(const NzCircle& rect); - NzSphere& Set(const NzSphere& sphere); - NzSphere& Set(const NzVector3& center, T Radius); - NzSphere& Set(const T sphere[4]); - template NzSphere& Set(const NzSphere& sphere); + Sphere& MakeZero(); - T SquaredDistance(T X, T Y, T Z) const; - T SquaredDistance(const NzVector3& point) const; + Sphere& Set(T X, T Y, T Z, T Radius); + //Sphere& Set(const NzCircle& rect); + Sphere& Set(const Sphere& sphere); + Sphere& Set(const Vector3& center, T Radius); + Sphere& Set(const T sphere[4]); + template Sphere& Set(const Sphere& sphere); - NzString ToString() const; + T SquaredDistance(T X, T Y, T Z) const; + T SquaredDistance(const Vector3& point) const; - T& operator[](unsigned int i); - T operator[](unsigned int i) const; + String ToString() const; - NzSphere operator*(T scalar) const; + T& operator[](unsigned int i); + T operator[](unsigned int i) const; - NzSphere& operator*=(T scalar); + Sphere operator*(T scalar) const; - bool operator==(const NzSphere& sphere) const; - bool operator!=(const NzSphere& sphere) const; + Sphere& operator*=(T scalar); - static NzSphere Lerp(const NzSphere& from, const NzSphere& to, T interpolation); - static NzSphere Zero(); + bool operator==(const Sphere& sphere) const; + bool operator!=(const Sphere& sphere) const; - T x, y, z, radius; -}; + static Sphere Lerp(const Sphere& from, const Sphere& to, T interpolation); + static Sphere Zero(); + + T x, y, z, radius; + }; + + typedef Sphere Sphered; + typedef Sphere Spheref; +} template -std::ostream& operator<<(std::ostream& out, const NzSphere& sphere); - -typedef NzSphere NzSphered; -typedef NzSphere NzSpheref; +std::ostream& operator<<(std::ostream& out, const Nz::Sphere& sphere); #include diff --git a/include/Nazara/Math/Sphere.inl b/include/Nazara/Math/Sphere.inl index 340e1319d..ae78d75f2 100644 --- a/include/Nazara/Math/Sphere.inl +++ b/include/Nazara/Math/Sphere.inl @@ -11,352 +11,355 @@ #define F(a) static_cast(a) -template -NzSphere::NzSphere(T X, T Y, T Z, T Radius) +namespace Nz { - Set(X, Y, Z, Radius); -} -/* -template -NzSphere::NzSphere(const NzCircle& circle) -{ - Set(rect); -} -*/ -template -NzSphere::NzSphere(const NzVector3& center, T Radius) -{ - Set(center, Radius); -} - -template -NzSphere::NzSphere(const T sphere[4]) -{ - Set(sphere); -} - -template -template -NzSphere::NzSphere(const NzSphere& sphere) -{ - Set(sphere); -} - -template -bool NzSphere::Contains(T X, T Y, T Z) const -{ - return SquaredDistance(X, Y, Z) <= radius*radius; -} - -template -bool NzSphere::Contains(const NzBox& box) const -{ - if (box.GetMinimum().SquaredDistance(GetPosition()) <= radius * radius) + template + Sphere::Sphere(T X, T Y, T Z, T Radius) { - if (box.GetMaximum().SquaredDistance(GetPosition()) <= radius * radius) - return true; + Set(X, Y, Z, Radius); + } + /* + template + Sphere::Sphere(const NzCircle& circle) + { + Set(rect); + } + */ + template + Sphere::Sphere(const Vector3& center, T Radius) + { + Set(center, Radius); } - return false; -} -template -bool NzSphere::Contains(const NzVector3& point) const -{ - return Contains(point.x, point.y, point.z); -} - -template -T NzSphere::Distance(T X, T Y, T Z) const -{ - NzVector3 distance(X-x, Y-y, Z-z); - return distance.GetLength(); -} - -template -T NzSphere::Distance(const NzVector3& point) const -{ - return Distance(point.x, point.y, point.z); -} - -template -NzSphere& NzSphere::ExtendTo(T X, T Y, T Z) -{ - T distance = SquaredDistance(X, Y, Z); - if (distance > radius*radius) - radius = std::sqrt(distance); - - return *this; -} - -template -NzSphere& NzSphere::ExtendTo(const NzVector3& point) -{ - return ExtendTo(point.x, point.y, point.z); -} - -template -NzVector3 NzSphere::GetNegativeVertex(const NzVector3& normal) const -{ - NzVector3 neg(GetPosition()); - neg -= normal * radius; - - return neg; -} - -template -NzVector3 NzSphere::GetPosition() const -{ - return NzVector3(x, y, z); -} - -template -NzVector3 NzSphere::GetPositiveVertex(const NzVector3& normal) const -{ - NzVector3 pos(GetPosition()); - pos += normal * radius; - - return pos; -} - -template -bool NzSphere::Intersect(const NzBox& box) const -{ - // Arvo's algorithm. - T squaredDistance = T(0.0); - if (x < box.x) + template + Sphere::Sphere(const T sphere[4]) { - T diff = x - box.x; - squaredDistance += diff*diff; - } - else if (x > box.x + box.width) - { - T diff = x - (box.x + box.width); - squaredDistance += diff*diff; + Set(sphere); } - if (y < box.y) + template + template + Sphere::Sphere(const Sphere& sphere) { - T diff = y - box.y; - squaredDistance += diff*diff; - } - else if (y > box.y + box.height) - { - T diff = y - (box.y + box.height); - squaredDistance += diff*diff; + Set(sphere); } - if (z < box.z) + template + bool Sphere::Contains(T X, T Y, T Z) const { - T diff = z - box.z; - squaredDistance += diff*diff; - } - else if (z > box.z + box.depth) - { - T diff = z - (box.z + box.depth); - squaredDistance += diff*diff; + return SquaredDistance(X, Y, Z) <= radius*radius; } - return squaredDistance <= radius * radius; -} - -template -bool NzSphere::Intersect(const NzSphere& sphere) const -{ - return SquaredDistance(sphere.x, sphere.y, sphere.z) - radius*radius <= sphere.radius*sphere.radius; -} - -template -bool NzSphere::IsValid() const -{ - return radius > F(0.0); -} - -template -NzSphere& NzSphere::MakeZero() -{ - x = F(0.0); - y = F(0.0); - z = F(0.0); - radius = F(0.0); - - return *this; -} - -template -NzSphere& NzSphere::Set(T X, T Y, T Z, T Radius) -{ - x = X; - y = Y; - z = Z; - radius = Radius; - - return *this; -} - -template -NzSphere& NzSphere::Set(const NzVector3& center, T Radius) -{ - x = center.x; - y = center.y; - z = center.z; - radius = Radius; - - return *this; -} -/* -template -NzSphere& NzSphere::Set(const NzCircle& circle) -{ - x = circle.x; - y = circle.y; - z = F(0.0); - radius = circle.radius; - - return *this; -} -*/ -template -NzSphere& NzSphere::Set(const NzSphere& sphere) -{ - std::memcpy(this, &sphere, sizeof(NzSphere)); - - return *this; -} - -template -NzSphere& NzSphere::Set(const T sphere[4]) -{ - x = sphere[0]; - y = sphere[1]; - z = sphere[2]; - radius = sphere[3]; - - return *this; -} - -template -template -NzSphere& NzSphere::Set(const NzSphere& sphere) -{ - x = F(sphere.x); - y = F(sphere.y); - z = F(sphere.z); - radius = F(sphere.radius); - - return *this; -} - -template -T NzSphere::SquaredDistance(T X, T Y, T Z) const -{ - NzVector3 distance(X-x, Y-y, Z-z); - return distance.GetSquaredLength(); -} - -template -T NzSphere::SquaredDistance(const NzVector3& point) const -{ - return SquaredDistance(point.x, point.y, point.z); -} - -template -NzString NzSphere::ToString() const -{ - NzStringStream ss; - - return ss << "Sphere(" << x << ", " << y << ", " << z << "; " << radius << ')'; -} - -template -T& NzSphere::operator[](unsigned int i) -{ - #if NAZARA_MATH_SAFE - if (i >= 4) + template + bool Sphere::Contains(const Box& box) const { - NzStringStream ss; - ss << "Index out of range: (" << i << " >= 4)"; + if (box.GetMinimum().SquaredDistance(GetPosition()) <= radius * radius) + { + if (box.GetMaximum().SquaredDistance(GetPosition()) <= radius * radius) + return true; + } - NazaraError(ss); - throw std::domain_error(ss.ToString()); + return false; } - #endif - - return *(&x+i); -} - -template -T NzSphere::operator[](unsigned int i) const -{ - #if NAZARA_MATH_SAFE - if (i >= 4) + template + bool Sphere::Contains(const Vector3& point) const { - NzStringStream ss; - ss << "Index out of range: (" << i << " >= 4)"; - - NazaraError(ss); - throw std::domain_error(ss.ToString()); + return Contains(point.x, point.y, point.z); } - #endif - return *(&x+i); -} - -template -NzSphere NzSphere::operator*(T scalar) const -{ - return NzSphere(x, y, z, radius*scalar); -} - -template -NzSphere& NzSphere::operator*=(T scalar) -{ - radius *= scalar; -} - -template -bool NzSphere::operator==(const NzSphere& sphere) const -{ - return NzNumberEquals(x, sphere.x) && NzNumberEquals(y, sphere.y) && NzNumberEquals(z, sphere.z) && - NzNumberEquals(radius, sphere.radius); -} - -template -bool NzSphere::operator!=(const NzSphere& sphere) const -{ - return !operator==(sphere); -} - -template -NzSphere NzSphere::Lerp(const NzSphere& from, const NzSphere& to, T interpolation) -{ - #ifdef NAZARA_DEBUG - if (interpolation < F(0.0) || interpolation > F(1.0)) + template + T Sphere::Distance(T X, T Y, T Z) const { - NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')'); - return Zero(); + Vector3 distance(X-x, Y-y, Z-z); + return distance.GetLength(); } - #endif - NzSphere sphere; - sphere.x = NzLerp(from.x, to.x, interpolation); - sphere.y = NzLerp(from.y, to.y, interpolation); - sphere.z = NzLerp(from.z, to.z, interpolation); - sphere.radius = NzLerp(from.radius, to.radius, interpolation); + template + T Sphere::Distance(const Vector3& point) const + { + return Distance(point.x, point.y, point.z); + } - return sphere; + template + Sphere& Sphere::ExtendTo(T X, T Y, T Z) + { + T distance = SquaredDistance(X, Y, Z); + if (distance > radius*radius) + radius = std::sqrt(distance); + + return *this; + } + + template + Sphere& Sphere::ExtendTo(const Vector3& point) + { + return ExtendTo(point.x, point.y, point.z); + } + + template + Vector3 Sphere::GetNegativeVertex(const Vector3& normal) const + { + Vector3 neg(GetPosition()); + neg -= normal * radius; + + return neg; + } + + template + Vector3 Sphere::GetPosition() const + { + return Vector3(x, y, z); + } + + template + Vector3 Sphere::GetPositiveVertex(const Vector3& normal) const + { + Vector3 pos(GetPosition()); + pos += normal * radius; + + return pos; + } + + template + bool Sphere::Intersect(const Box& box) const + { + // Arvo's algorithm. + T squaredDistance = T(0.0); + if (x < box.x) + { + T diff = x - box.x; + squaredDistance += diff*diff; + } + else if (x > box.x + box.width) + { + T diff = x - (box.x + box.width); + squaredDistance += diff*diff; + } + + if (y < box.y) + { + T diff = y - box.y; + squaredDistance += diff*diff; + } + else if (y > box.y + box.height) + { + T diff = y - (box.y + box.height); + squaredDistance += diff*diff; + } + + if (z < box.z) + { + T diff = z - box.z; + squaredDistance += diff*diff; + } + else if (z > box.z + box.depth) + { + T diff = z - (box.z + box.depth); + squaredDistance += diff*diff; + } + + return squaredDistance <= radius * radius; + } + + template + bool Sphere::Intersect(const Sphere& sphere) const + { + return SquaredDistance(sphere.x, sphere.y, sphere.z) - radius*radius <= sphere.radius*sphere.radius; + } + + template + bool Sphere::IsValid() const + { + return radius > F(0.0); + } + + template + Sphere& Sphere::MakeZero() + { + x = F(0.0); + y = F(0.0); + z = F(0.0); + radius = F(0.0); + + return *this; + } + + template + Sphere& Sphere::Set(T X, T Y, T Z, T Radius) + { + x = X; + y = Y; + z = Z; + radius = Radius; + + return *this; + } + + template + Sphere& Sphere::Set(const Vector3& center, T Radius) + { + x = center.x; + y = center.y; + z = center.z; + radius = Radius; + + return *this; + } + /* + template + Sphere& Sphere::Set(const NzCircle& circle) + { + x = circle.x; + y = circle.y; + z = F(0.0); + radius = circle.radius; + + return *this; + } + */ + template + Sphere& Sphere::Set(const Sphere& sphere) + { + std::memcpy(this, &sphere, sizeof(Sphere)); + + return *this; + } + + template + Sphere& Sphere::Set(const T sphere[4]) + { + x = sphere[0]; + y = sphere[1]; + z = sphere[2]; + radius = sphere[3]; + + return *this; + } + + template + template + Sphere& Sphere::Set(const Sphere& sphere) + { + x = F(sphere.x); + y = F(sphere.y); + z = F(sphere.z); + radius = F(sphere.radius); + + return *this; + } + + template + T Sphere::SquaredDistance(T X, T Y, T Z) const + { + Vector3 distance(X-x, Y-y, Z-z); + return distance.GetSquaredLength(); + } + + template + T Sphere::SquaredDistance(const Vector3& point) const + { + return SquaredDistance(point.x, point.y, point.z); + } + + template + String Sphere::ToString() const + { + StringStream ss; + + return ss << "Sphere(" << x << ", " << y << ", " << z << "; " << radius << ')'; + } + + template + T& Sphere::operator[](unsigned int i) + { + #if NAZARA_MATH_SAFE + if (i >= 4) + { + StringStream ss; + ss << "Index out of range: (" << i << " >= 4)"; + + NazaraError(ss); + throw std::domain_error(ss.ToString()); + } + #endif + + return *(&x+i); + } + + template + T Sphere::operator[](unsigned int i) const + { + #if NAZARA_MATH_SAFE + if (i >= 4) + { + StringStream ss; + ss << "Index out of range: (" << i << " >= 4)"; + + NazaraError(ss); + throw std::domain_error(ss.ToString()); + } + #endif + + return *(&x+i); + } + + template + Sphere Sphere::operator*(T scalar) const + { + return Sphere(x, y, z, radius*scalar); + } + + template + Sphere& Sphere::operator*=(T scalar) + { + radius *= scalar; + } + + template + bool Sphere::operator==(const Sphere& sphere) const + { + return NumberEquals(x, sphere.x) && NumberEquals(y, sphere.y) && NumberEquals(z, sphere.z) && + NumberEquals(radius, sphere.radius); + } + + template + bool Sphere::operator!=(const Sphere& sphere) const + { + return !operator==(sphere); + } + + template + Sphere Sphere::Lerp(const Sphere& from, const Sphere& to, T interpolation) + { + #ifdef NAZARA_DEBUG + if (interpolation < F(0.0) || interpolation > F(1.0)) + { + NazaraError("Interpolation must be in range [0..1] (Got " + String::Number(interpolation) + ')'); + return Zero(); + } + #endif + + Sphere sphere; + sphere.x = Lerp(from.x, to.x, interpolation); + sphere.y = Lerp(from.y, to.y, interpolation); + sphere.z = Lerp(from.z, to.z, interpolation); + sphere.radius = Lerp(from.radius, to.radius, interpolation); + + return sphere; + } + + template + Sphere Sphere::Zero() + { + Sphere sphere; + sphere.MakeZero(); + + return sphere; + } } template -NzSphere NzSphere::Zero() -{ - NzSphere sphere; - sphere.MakeZero(); - - return sphere; -} - -template -std::ostream& operator<<(std::ostream& out, const NzSphere& sphere) +std::ostream& operator<<(std::ostream& out, const Nz::Sphere& sphere) { return out << sphere.ToString(); } diff --git a/include/Nazara/Math/Vector2.hpp b/include/Nazara/Math/Vector2.hpp index 24eea3806..28ea44468 100644 --- a/include/Nazara/Math/Vector2.hpp +++ b/include/Nazara/Math/Vector2.hpp @@ -9,104 +9,107 @@ #include -template class NzVector3; -template class NzVector4; - -template -class NzVector2 +namespace Nz { - public: - NzVector2() = default; - NzVector2(T X, T Y); - explicit NzVector2(T scale); - NzVector2(const T vec[2]); - template explicit NzVector2(const NzVector2& vec); - NzVector2(const NzVector2& vec) = default; - explicit NzVector2(const NzVector3& vec); - explicit NzVector2(const NzVector4& vec); - ~NzVector2() = default; + template class Vector3; + template class Vector4; - T AbsDotProduct(const NzVector2& vec) const; - T AngleBetween(const NzVector2& vec) const; + template + class Vector2 + { + public: + Vector2() = default; + Vector2(T X, T Y); + explicit Vector2(T scale); + Vector2(const T vec[2]); + template explicit Vector2(const Vector2& vec); + Vector2(const Vector2& vec) = default; + explicit Vector2(const Vector3& vec); + explicit Vector2(const Vector4& vec); + ~Vector2() = default; - T Distance(const NzVector2& vec) const; - float Distancef(const NzVector2& vec) const; - T DotProduct(const NzVector2& vec) const; + T AbsDotProduct(const Vector2& vec) const; + T AngleBetween(const Vector2& vec) const; - T GetLength() const; - float GetLengthf() const; - NzVector2 GetNormal(T* length = nullptr) const; - T GetSquaredLength() const; + T Distance(const Vector2& vec) const; + float Distancef(const Vector2& vec) const; + T DotProduct(const Vector2& vec) const; - NzVector2& MakeUnit(); - NzVector2& MakeUnitX(); - NzVector2& MakeUnitY(); - NzVector2& MakeZero(); + T GetLength() const; + float GetLengthf() const; + Vector2 GetNormal(T* length = nullptr) const; + T GetSquaredLength() const; - NzVector2& Maximize(const NzVector2& vec); - NzVector2& Minimize(const NzVector2& vec); + Vector2& MakeUnit(); + Vector2& MakeUnitX(); + Vector2& MakeUnitY(); + Vector2& MakeZero(); - NzVector2& Normalize(T* length = nullptr); + Vector2& Maximize(const Vector2& vec); + Vector2& Minimize(const Vector2& vec); - NzVector2& Set(T X, T Y); - NzVector2& Set(T scale); - NzVector2& Set(const T vec[2]); - NzVector2& Set(const NzVector2& vec); - NzVector2& Set(const NzVector3& vec); - NzVector2& Set(const NzVector4& vec); - template NzVector2& Set(const NzVector2& vec); + Vector2& Normalize(T* length = nullptr); - T SquaredDistance(const NzVector2& vec) const; + Vector2& Set(T X, T Y); + Vector2& Set(T scale); + Vector2& Set(const T vec[2]); + Vector2& Set(const Vector2& vec); + Vector2& Set(const Vector3& vec); + Vector2& Set(const Vector4& vec); + template Vector2& Set(const Vector2& vec); - NzString ToString() const; + T SquaredDistance(const Vector2& vec) const; - operator T*(); - operator const T*() const; + String ToString() const; - const NzVector2& operator+() const; - NzVector2 operator-() const; + operator T*(); + operator const T*() const; - NzVector2 operator+(const NzVector2& vec) const; - NzVector2 operator-(const NzVector2& vec) const; - NzVector2 operator*(const NzVector2& vec) const; - NzVector2 operator*(T scale) const; - NzVector2 operator/(const NzVector2& vec) const; - NzVector2 operator/(T scale) const; + const Vector2& operator+() const; + Vector2 operator-() const; - NzVector2& operator+=(const NzVector2& vec); - NzVector2& operator-=(const NzVector2& vec); - NzVector2& operator*=(const NzVector2& vec); - NzVector2& operator*=(T scale); - NzVector2& operator/=(const NzVector2& vec); - NzVector2& operator/=(T scale); + Vector2 operator+(const Vector2& vec) const; + Vector2 operator-(const Vector2& vec) const; + Vector2 operator*(const Vector2& vec) const; + Vector2 operator*(T scale) const; + Vector2 operator/(const Vector2& vec) const; + Vector2 operator/(T scale) const; - bool operator==(const NzVector2& vec) const; - bool operator!=(const NzVector2& vec) const; - bool operator<(const NzVector2& vec) const; - bool operator<=(const NzVector2& vec) const; - bool operator>(const NzVector2& vec) const; - bool operator>=(const NzVector2& vec) const; + Vector2& operator+=(const Vector2& vec); + Vector2& operator-=(const Vector2& vec); + Vector2& operator*=(const Vector2& vec); + Vector2& operator*=(T scale); + Vector2& operator/=(const Vector2& vec); + Vector2& operator/=(T scale); - static NzVector2 Lerp(const NzVector2& from, const NzVector2& to, T interpolation); - static NzVector2 Unit(); - static NzVector2 UnitX(); - static NzVector2 UnitY(); - static NzVector2 Zero(); + bool operator==(const Vector2& vec) const; + bool operator!=(const Vector2& vec) const; + bool operator<(const Vector2& vec) const; + bool operator<=(const Vector2& vec) const; + bool operator>(const Vector2& vec) const; + bool operator>=(const Vector2& vec) const; - T x, y; -}; + static Vector2 Lerp(const Vector2& from, const Vector2& to, T interpolation); + static Vector2 Unit(); + static Vector2 UnitX(); + static Vector2 UnitY(); + static Vector2 Zero(); -template std::ostream& operator<<(std::ostream& out, const NzVector2& vec); + T x, y; + }; -template NzVector2 operator*(T scale, const NzVector2& vec); -template NzVector2 operator/(T scale, const NzVector2& vec); + typedef Vector2 Vector2d; + typedef Vector2 Vector2f; + typedef Vector2 Vector2i; + typedef Vector2 Vector2ui; + typedef Vector2 Vector2i32; + typedef Vector2 Vector2ui32; +} -typedef NzVector2 NzVector2d; -typedef NzVector2 NzVector2f; -typedef NzVector2 NzVector2i; -typedef NzVector2 NzVector2ui; -typedef NzVector2 NzVector2i32; -typedef NzVector2 NzVector2ui32; +template std::ostream& operator<<(std::ostream& out, const Nz::Vector2& vec); + +template Nz::Vector2 operator*(T scale, const Nz::Vector2& vec); +template Nz::Vector2 operator/(T scale, const Nz::Vector2& vec); #include diff --git a/include/Nazara/Math/Vector2.inl b/include/Nazara/Math/Vector2.inl index c8ec7730f..514aa3344 100644 --- a/include/Nazara/Math/Vector2.inl +++ b/include/Nazara/Math/Vector2.inl @@ -11,506 +11,509 @@ #define F(a) static_cast(a) -template -NzVector2::NzVector2(T X, T Y) +namespace Nz { - Set(X, Y); -} + template + Vector2::Vector2(T X, T Y) + { + Set(X, Y); + } -template -NzVector2::NzVector2(T scale) -{ - Set(scale); -} + template + Vector2::Vector2(T scale) + { + Set(scale); + } -template -NzVector2::NzVector2(const T vec[2]) -{ - Set(vec); -} + template + Vector2::Vector2(const T vec[2]) + { + Set(vec); + } -template -template -NzVector2::NzVector2(const NzVector2& vec) -{ - Set(vec); -} + template + template + Vector2::Vector2(const Vector2& vec) + { + Set(vec); + } -template -NzVector2::NzVector2(const NzVector3& vec) -{ - Set(vec); -} + template + Vector2::Vector2(const Vector3& vec) + { + Set(vec); + } -template -NzVector2::NzVector2(const NzVector4& vec) -{ - Set(vec); -} + template + Vector2::Vector2(const Vector4& vec) + { + Set(vec); + } -template -T NzVector2::AbsDotProduct(const NzVector2& vec) const -{ - return std::abs(x * vec.x) + std::abs(y * vec.y); -} + template + T Vector2::AbsDotProduct(const Vector2& vec) const + { + return std::abs(x * vec.x) + std::abs(y * vec.y); + } -template -T NzVector2::AngleBetween(const NzVector2& vec) const -{ - return NzFromRadians(std::atan2(vec.y, vec.x) - std::atan2(y, x)); -} + template + T Vector2::AngleBetween(const Vector2& vec) const + { + return FromRadians(std::atan2(vec.y, vec.x) - std::atan2(y, x)); + } -template -T NzVector2::Distance(const NzVector2& vec) const -{ - return std::sqrt(SquaredDistance(vec)); -} + template + T Vector2::Distance(const Vector2& vec) const + { + return std::sqrt(SquaredDistance(vec)); + } -template -float NzVector2::Distancef(const NzVector2& vec) const -{ - return std::sqrt(static_cast(SquaredDistance(vec))); -} + template + float Vector2::Distancef(const Vector2& vec) const + { + return std::sqrt(static_cast(SquaredDistance(vec))); + } -template -T NzVector2::DotProduct(const NzVector2& vec) const -{ - return x*vec.x + y*vec.y; -} + template + T Vector2::DotProduct(const Vector2& vec) const + { + return x*vec.x + y*vec.y; + } -template -T NzVector2::GetLength() const -{ - return std::sqrt(GetSquaredLength()); -} + template + T Vector2::GetLength() const + { + return std::sqrt(GetSquaredLength()); + } -template -float NzVector2::GetLengthf() const -{ - return std::sqrt(static_cast(GetSquaredLength())); -} + template + float Vector2::GetLengthf() const + { + return std::sqrt(static_cast(GetSquaredLength())); + } -template -NzVector2 NzVector2::GetNormal(T* length) const -{ - NzVector2 vec(*this); - vec.Normalize(length); + template + Vector2 Vector2::GetNormal(T* length) const + { + Vector2 vec(*this); + vec.Normalize(length); - return vec; -} + return vec; + } -template -T NzVector2::GetSquaredLength() const -{ - return x*x + y*y; -} + template + T Vector2::GetSquaredLength() const + { + return x*x + y*y; + } -template -NzVector2& NzVector2::MakeUnit() -{ - return Set(F(1.0), F(1.0)); -} + template + Vector2& Vector2::MakeUnit() + { + return Set(F(1.0), F(1.0)); + } -template -NzVector2& NzVector2::MakeUnitX() -{ - return Set(F(1.0), F(0.0)); -} + template + Vector2& Vector2::MakeUnitX() + { + return Set(F(1.0), F(0.0)); + } -template -NzVector2& NzVector2::MakeUnitY() -{ - return Set(F(0.0), F(1.0)); -} + template + Vector2& Vector2::MakeUnitY() + { + return Set(F(0.0), F(1.0)); + } -template -NzVector2& NzVector2::MakeZero() -{ - return Set(F(0.0), F(0.0)); -} + template + Vector2& Vector2::MakeZero() + { + return Set(F(0.0), F(0.0)); + } -template -NzVector2& NzVector2::Maximize(const NzVector2& vec) -{ - if (vec.x > x) + template + Vector2& Vector2::Maximize(const Vector2& vec) + { + if (vec.x > x) + x = vec.x; + + if (vec.y > y) + y = vec.y; + + return *this; + } + + template + Vector2& Vector2::Minimize(const Vector2& vec) + { + if (vec.x < x) + x = vec.x; + + if (vec.y < y) + y = vec.y; + + return *this; + } + + template + Vector2& Vector2::Normalize(T* length) + { + T norm = GetLength(); + if (norm > F(0.0)) + { + T invNorm = F(1.0) / norm; + x *= invNorm; + y *= invNorm; + } + + if (length) + *length = norm; + + return *this; + } + + template + Vector2& Vector2::Set(T X, T Y) + { + x = X; + y = Y; + + return *this; + } + + template + Vector2& Vector2::Set(T scale) + { + x = scale; + y = scale; + + return *this; + } + + template + Vector2& Vector2::Set(const T vec[2]) + { + std::memcpy(&x, vec, 2*sizeof(T)); + + return *this; + } + + template + Vector2& Vector2::Set(const Vector2& vec) + { + std::memcpy(this, &vec, sizeof(Vector2)); + + return *this; + } + + template + template + Vector2& Vector2::Set(const Vector2& vec) + { + x = F(vec.x); + y = F(vec.y); + + return *this; + } + + template + Vector2& Vector2::Set(const Vector3& vec) + { x = vec.x; - - if (vec.y > y) y = vec.y; - return *this; -} + return *this; + } -template -NzVector2& NzVector2::Minimize(const NzVector2& vec) -{ - if (vec.x < x) + template + Vector2& Vector2::Set(const Vector4& vec) + { x = vec.x; - - if (vec.y < y) y = vec.y; - return *this; -} - -template -NzVector2& NzVector2::Normalize(T* length) -{ - T norm = GetLength(); - if (norm > F(0.0)) - { - T invNorm = F(1.0) / norm; - x *= invNorm; - y *= invNorm; + return *this; } - if (length) - *length = norm; - - return *this; -} - -template -NzVector2& NzVector2::Set(T X, T Y) -{ - x = X; - y = Y; - - return *this; -} - -template -NzVector2& NzVector2::Set(T scale) -{ - x = scale; - y = scale; - - return *this; -} - -template -NzVector2& NzVector2::Set(const T vec[2]) -{ - std::memcpy(&x, vec, 2*sizeof(T)); - - return *this; -} - -template -NzVector2& NzVector2::Set(const NzVector2& vec) -{ - std::memcpy(this, &vec, sizeof(NzVector2)); - - return *this; -} - -template -template -NzVector2& NzVector2::Set(const NzVector2& vec) -{ - x = F(vec.x); - y = F(vec.y); - - return *this; -} - -template -NzVector2& NzVector2::Set(const NzVector3& vec) -{ - x = vec.x; - y = vec.y; - - return *this; -} - -template -NzVector2& NzVector2::Set(const NzVector4& vec) -{ - x = vec.x; - y = vec.y; - - return *this; -} - -template -T NzVector2::SquaredDistance(const NzVector2& vec) const -{ - return (*this - vec).GetSquaredLength(); -} - -template -NzString NzVector2::ToString() const -{ - NzStringStream ss; - - return ss << "Vector2(" << x << ", " << y << ')'; -} - -template -NzVector2::operator T*() -{ - return &x; -} - -template -NzVector2::operator const T*() const -{ - return &x; -} - -template -const NzVector2& NzVector2::operator+() const -{ - return *this; -} - -template -NzVector2 NzVector2::operator-() const -{ - return NzVector2(-x, -y); -} - -template -NzVector2 NzVector2::operator+(const NzVector2& vec) const -{ - return NzVector2(x + vec.x, y + vec.y); -} - -template -NzVector2 NzVector2::operator-(const NzVector2& vec) const -{ - return NzVector2(x - vec.x, y - vec.y); -} - -template -NzVector2 NzVector2::operator*(const NzVector2& vec) const -{ - return NzVector2(x * vec.x, y * vec.y); -} - -template -NzVector2 NzVector2::operator*(T scale) const -{ - return NzVector2(x * scale, y * scale); -} - -template -NzVector2 NzVector2::operator/(const NzVector2& vec) const -{ - #if NAZARA_MATH_SAFE - if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0))) + template + T Vector2::SquaredDistance(const Vector2& vec) const { - NzString error("Division by zero"); - - NazaraError(error); - throw std::domain_error(error); + return (*this - vec).GetSquaredLength(); } - #endif - return NzVector2(x / vec.x, y / vec.y); -} - -template -NzVector2 NzVector2::operator/(T scale) const -{ - #if NAZARA_MATH_SAFE - if (NzNumberEquals(scale, F(0.0))) + template + String Vector2::ToString() const { - NzString error("Division by zero"); + StringStream ss; - NazaraError(error); - throw std::domain_error(error); + return ss << "Vector2(" << x << ", " << y << ')'; } - #endif - return NzVector2(x / scale, y / scale); -} - -template -NzVector2& NzVector2::operator+=(const NzVector2& vec) -{ - x += vec.x; - y += vec.y; - - return *this; -} - -template -NzVector2& NzVector2::operator-=(const NzVector2& vec) -{ - x -= vec.x; - y -= vec.y; - - return *this; -} - -template -NzVector2& NzVector2::operator*=(const NzVector2& vec) -{ - x *= vec.x; - y *= vec.y; - - return *this; -} - -template -NzVector2& NzVector2::operator*=(T scale) -{ - x *= scale; - y *= scale; - - return *this; -} - -template -NzVector2& NzVector2::operator/=(const NzVector2& vec) -{ - #if NAZARA_MATH_SAFE - if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0))) + template + Vector2::operator T*() { - NzString error("Division by zero"); - - NazaraError(error); - throw std::domain_error(error); + return &x; } - #endif - x /= vec.x; - y /= vec.y; - - return *this; -} - -template -NzVector2& NzVector2::operator/=(T scale) -{ - #if NAZARA_MATH_SAFE - if (NzNumberEquals(scale, F(0.0))) + template + Vector2::operator const T*() const { - NzString error("Division by zero"); - - NazaraError(error); - throw std::domain_error(error); + return &x; } - #endif - x /= scale; - y /= scale; + template + const Vector2& Vector2::operator+() const + { + return *this; + } - return *this; + template + Vector2 Vector2::operator-() const + { + return Vector2(-x, -y); + } + + template + Vector2 Vector2::operator+(const Vector2& vec) const + { + return Vector2(x + vec.x, y + vec.y); + } + + template + Vector2 Vector2::operator-(const Vector2& vec) const + { + return Vector2(x - vec.x, y - vec.y); + } + + template + Vector2 Vector2::operator*(const Vector2& vec) const + { + return Vector2(x * vec.x, y * vec.y); + } + + template + Vector2 Vector2::operator*(T scale) const + { + return Vector2(x * scale, y * scale); + } + + template + Vector2 Vector2::operator/(const Vector2& vec) const + { + #if NAZARA_MATH_SAFE + if (NumberEquals(vec.x, F(0.0)) || NumberEquals(vec.y, F(0.0))) + { + String error("Division by zero"); + + NazaraError(error); + throw std::domain_error(error); + } + #endif + + return Vector2(x / vec.x, y / vec.y); + } + + template + Vector2 Vector2::operator/(T scale) const + { + #if NAZARA_MATH_SAFE + if (NumberEquals(scale, F(0.0))) + { + String error("Division by zero"); + + NazaraError(error); + throw std::domain_error(error); + } + #endif + + return Vector2(x / scale, y / scale); + } + + template + Vector2& Vector2::operator+=(const Vector2& vec) + { + x += vec.x; + y += vec.y; + + return *this; + } + + template + Vector2& Vector2::operator-=(const Vector2& vec) + { + x -= vec.x; + y -= vec.y; + + return *this; + } + + template + Vector2& Vector2::operator*=(const Vector2& vec) + { + x *= vec.x; + y *= vec.y; + + return *this; + } + + template + Vector2& Vector2::operator*=(T scale) + { + x *= scale; + y *= scale; + + return *this; + } + + template + Vector2& Vector2::operator/=(const Vector2& vec) + { + #if NAZARA_MATH_SAFE + if (NumberEquals(vec.x, F(0.0)) || NumberEquals(vec.y, F(0.0))) + { + String error("Division by zero"); + + NazaraError(error); + throw std::domain_error(error); + } + #endif + + x /= vec.x; + y /= vec.y; + + return *this; + } + + template + Vector2& Vector2::operator/=(T scale) + { + #if NAZARA_MATH_SAFE + if (NumberEquals(scale, F(0.0))) + { + String error("Division by zero"); + + NazaraError(error); + throw std::domain_error(error); + } + #endif + + x /= scale; + y /= scale; + + return *this; + } + + template + bool Vector2::operator==(const Vector2& vec) const + { + return NumberEquals(x, vec.x) && + NumberEquals(y, vec.y); + } + + template + bool Vector2::operator!=(const Vector2& vec) const + { + return !operator==(vec); + } + + template + bool Vector2::operator<(const Vector2& vec) const + { + if (x == vec.x) + return y < vec.y; + else + return x < vec.x; + } + + template + bool Vector2::operator<=(const Vector2& vec) const + { + if (x == vec.x) + return y <= vec.y; + else + return x < vec.x; + } + + template + bool Vector2::operator>(const Vector2& vec) const + { + return !operator<=(vec); + } + + template + bool Vector2::operator>=(const Vector2& vec) const + { + return !operator<(vec); + } + + template + Vector2 Vector2::Lerp(const Vector2& from, const Vector2& to, T interpolation) + { + return Lerp(from, to, interpolation); + } + + template + Vector2 Vector2::Unit() + { + Vector2 vector; + vector.MakeUnit(); + + return vector; + } + + template + Vector2 Vector2::UnitX() + { + Vector2 vector; + vector.MakeUnitX(); + + return vector; + } + + template + Vector2 Vector2::UnitY() + { + Vector2 vector; + vector.MakeUnitY(); + + return vector; + } + + template + Vector2 Vector2::Zero() + { + Vector2 vector; + vector.MakeZero(); + + return vector; + } } template -bool NzVector2::operator==(const NzVector2& vec) const -{ - return NzNumberEquals(x, vec.x) && - NzNumberEquals(y, vec.y); -} - -template -bool NzVector2::operator!=(const NzVector2& vec) const -{ - return !operator==(vec); -} - -template -bool NzVector2::operator<(const NzVector2& vec) const -{ - if (x == vec.x) - return y < vec.y; - else - return x < vec.x; -} - -template -bool NzVector2::operator<=(const NzVector2& vec) const -{ - if (x == vec.x) - return y <= vec.y; - else - return x < vec.x; -} - -template -bool NzVector2::operator>(const NzVector2& vec) const -{ - return !operator<=(vec); -} - -template -bool NzVector2::operator>=(const NzVector2& vec) const -{ - return !operator<(vec); -} - -template -NzVector2 NzVector2::Lerp(const NzVector2& from, const NzVector2& to, T interpolation) -{ - return NzLerp(from, to, interpolation); -} - -template -NzVector2 NzVector2::Unit() -{ - NzVector2 vector; - vector.MakeUnit(); - - return vector; -} - -template -NzVector2 NzVector2::UnitX() -{ - NzVector2 vector; - vector.MakeUnitX(); - - return vector; -} - -template -NzVector2 NzVector2::UnitY() -{ - NzVector2 vector; - vector.MakeUnitY(); - - return vector; -} - -template -NzVector2 NzVector2::Zero() -{ - NzVector2 vector; - vector.MakeZero(); - - return vector; -} - -template -std::ostream& operator<<(std::ostream& out, const NzVector2& vec) +std::ostream& operator<<(std::ostream& out, const Nz::Vector2& vec) { return out << vec.ToString(); } template -NzVector2 operator*(T scale, const NzVector2& vec) +Nz::Vector2 operator*(T scale, const Nz::Vector2& vec) { - return NzVector2(scale * vec.x, scale * vec.y); + return Nz::Vector2(scale * vec.x, scale * vec.y); } template -NzVector2 operator/(T scale, const NzVector2& vec) +Nz::Vector2 operator/(T scale, const Nz::Vector2& vec) { #if NAZARA_MATH_SAFE - if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0))) + if (Nz::NumberEquals(vec.x, F(0.0)) || Nz::NumberEquals(vec.y, F(0.0))) { - NzString error("Division by zero"); + Nz::String error("Division by zero"); NazaraError(error); throw std::domain_error(error); } #endif - return NzVector2(scale/vec.x, scale/vec.y); + return Nz::Vector2(scale/vec.x, scale/vec.y); } #undef F diff --git a/include/Nazara/Math/Vector3.hpp b/include/Nazara/Math/Vector3.hpp index 21f3c30be..5f14f8be7 100644 --- a/include/Nazara/Math/Vector3.hpp +++ b/include/Nazara/Math/Vector3.hpp @@ -9,125 +9,128 @@ #include -template class NzVector2; -template class NzVector4; - -template -class NzVector3 +namespace Nz { - public: - NzVector3() = default; - NzVector3(T X, T Y, T Z); - NzVector3(T X, const NzVector2& vec); - explicit NzVector3(T scale); - NzVector3(const T vec[3]); - NzVector3(const NzVector2& vec, T Z = 0.0); - template explicit NzVector3(const NzVector3& vec); - NzVector3(const NzVector3& vec) = default; - explicit NzVector3(const NzVector4& vec); - ~NzVector3() = default; + template class Vector2; + template class Vector4; - T AbsDotProduct(const NzVector3& vec) const; - T AngleBetween(const NzVector3& vec) const; + template + class Vector3 + { + public: + Vector3() = default; + Vector3(T X, T Y, T Z); + Vector3(T X, const Vector2& vec); + explicit Vector3(T scale); + Vector3(const T vec[3]); + Vector3(const Vector2& vec, T Z = 0.0); + template explicit Vector3(const Vector3& vec); + Vector3(const Vector3& vec) = default; + explicit Vector3(const Vector4& vec); + ~Vector3() = default; - NzVector3 CrossProduct(const NzVector3& vec) const; + T AbsDotProduct(const Vector3& vec) const; + T AngleBetween(const Vector3& vec) const; - T Distance(const NzVector3& vec) const; - float Distancef(const NzVector3& vec) const; - T DotProduct(const NzVector3& vec) const; + Vector3 CrossProduct(const Vector3& vec) const; - T GetLength() const; - float GetLengthf() const; - NzVector3 GetNormal(T* length = nullptr) const; - T GetSquaredLength() const; + T Distance(const Vector3& vec) const; + float Distancef(const Vector3& vec) const; + T DotProduct(const Vector3& vec) const; - NzVector3& MakeBackward(); - NzVector3& MakeDown(); - NzVector3& MakeForward(); - NzVector3& MakeLeft(); - NzVector3& MakeRight(); - NzVector3& MakeUnit(); - NzVector3& MakeUnitX(); - NzVector3& MakeUnitY(); - NzVector3& MakeUnitZ(); - NzVector3& MakeUp(); - NzVector3& MakeZero(); + T GetLength() const; + float GetLengthf() const; + Vector3 GetNormal(T* length = nullptr) const; + T GetSquaredLength() const; - NzVector3& Maximize(const NzVector3& vec); - NzVector3& Minimize(const NzVector3& vec); + Vector3& MakeBackward(); + Vector3& MakeDown(); + Vector3& MakeForward(); + Vector3& MakeLeft(); + Vector3& MakeRight(); + Vector3& MakeUnit(); + Vector3& MakeUnitX(); + Vector3& MakeUnitY(); + Vector3& MakeUnitZ(); + Vector3& MakeUp(); + Vector3& MakeZero(); - NzVector3& Normalize(T* length = nullptr); + Vector3& Maximize(const Vector3& vec); + Vector3& Minimize(const Vector3& vec); - NzVector3& Set(T X, T Y, T Z); - NzVector3& Set(T X, const NzVector2& vec); - NzVector3& Set(T scale); - NzVector3& Set(const T vec[3]); - NzVector3& Set(const NzVector2& vec, T Z = 0.0); - NzVector3& Set(const NzVector3& vec); - template NzVector3& Set(const NzVector3& vec); - NzVector3& Set(const NzVector4& vec); + Vector3& Normalize(T* length = nullptr); - T SquaredDistance(const NzVector3& vec) const; + Vector3& Set(T X, T Y, T Z); + Vector3& Set(T X, const Vector2& vec); + Vector3& Set(T scale); + Vector3& Set(const T vec[3]); + Vector3& Set(const Vector2& vec, T Z = 0.0); + Vector3& Set(const Vector3& vec); + template Vector3& Set(const Vector3& vec); + Vector3& Set(const Vector4& vec); - NzString ToString() const; + T SquaredDistance(const Vector3& vec) const; - operator T*(); - operator const T*() const; + String ToString() const; - const NzVector3& operator+() const; - NzVector3 operator-() const; + operator T*(); + operator const T*() const; - NzVector3 operator+(const NzVector3& vec) const; - NzVector3 operator-(const NzVector3& vec) const; - NzVector3 operator*(const NzVector3& vec) const; - NzVector3 operator*(T scale) const; - NzVector3 operator/(const NzVector3& vec) const; - NzVector3 operator/(T scale) const; + const Vector3& operator+() const; + Vector3 operator-() const; - NzVector3& operator+=(const NzVector3& vec); - NzVector3& operator-=(const NzVector3& vec); - NzVector3& operator*=(const NzVector3& vec); - NzVector3& operator*=(T scale); - NzVector3& operator/=(const NzVector3& vec); - NzVector3& operator/=(T scale); + Vector3 operator+(const Vector3& vec) const; + Vector3 operator-(const Vector3& vec) const; + Vector3 operator*(const Vector3& vec) const; + Vector3 operator*(T scale) const; + Vector3 operator/(const Vector3& vec) const; + Vector3 operator/(T scale) const; - bool operator==(const NzVector3& vec) const; - bool operator!=(const NzVector3& vec) const; - bool operator<(const NzVector3& vec) const; - bool operator<=(const NzVector3& vec) const; - bool operator>(const NzVector3& vec) const; - bool operator>=(const NzVector3& vec) const; + Vector3& operator+=(const Vector3& vec); + Vector3& operator-=(const Vector3& vec); + Vector3& operator*=(const Vector3& vec); + Vector3& operator*=(T scale); + Vector3& operator/=(const Vector3& vec); + Vector3& operator/=(T scale); - static NzVector3 Backward(); - static NzVector3 CrossProduct(const NzVector3& vec1, const NzVector3& vec2); - static T DotProduct(const NzVector3& vec1, const NzVector3& vec2); - static NzVector3 Down(); - static NzVector3 Forward(); - static NzVector3 Left(); - static NzVector3 Lerp(const NzVector3& from, const NzVector3& to, T interpolation); - static NzVector3 Normalize(const NzVector3& vec); - static NzVector3 Right(); - static NzVector3 Unit(); - static NzVector3 UnitX(); - static NzVector3 UnitY(); - static NzVector3 UnitZ(); - static NzVector3 Up(); - static NzVector3 Zero(); + bool operator==(const Vector3& vec) const; + bool operator!=(const Vector3& vec) const; + bool operator<(const Vector3& vec) const; + bool operator<=(const Vector3& vec) const; + bool operator>(const Vector3& vec) const; + bool operator>=(const Vector3& vec) const; - T x, y, z; -}; + static Vector3 Backward(); + static Vector3 CrossProduct(const Vector3& vec1, const Vector3& vec2); + static T DotProduct(const Vector3& vec1, const Vector3& vec2); + static Vector3 Down(); + static Vector3 Forward(); + static Vector3 Left(); + static Vector3 Lerp(const Vector3& from, const Vector3& to, T interpolation); + static Vector3 Normalize(const Vector3& vec); + static Vector3 Right(); + static Vector3 Unit(); + static Vector3 UnitX(); + static Vector3 UnitY(); + static Vector3 UnitZ(); + static Vector3 Up(); + static Vector3 Zero(); -template std::ostream& operator<<(std::ostream& out, const NzVector3& vec); + T x, y, z; + }; -template NzVector3 operator*(T scale, const NzVector3& vec); -template NzVector3 operator/(T scale, const NzVector3& vec); + typedef Vector3 Vector3d; + typedef Vector3 Vector3f; + typedef Vector3 Vector3i; + typedef Vector3 Vector3ui; + typedef Vector3 Vector3i32; + typedef Vector3 Vector3ui32; +} -typedef NzVector3 NzVector3d; -typedef NzVector3 NzVector3f; -typedef NzVector3 NzVector3i; -typedef NzVector3 NzVector3ui; -typedef NzVector3 NzVector3i32; -typedef NzVector3 NzVector3ui32; +template std::ostream& operator<<(std::ostream& out, const Nz::Vector3& vec); + +template Nz::Vector3 operator*(T scale, const Nz::Vector3& vec); +template Nz::Vector3 operator/(T scale, const Nz::Vector3& vec); #include diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index 598c8f686..bfb026c81 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -11,690 +11,693 @@ #define F(a) static_cast(a) -template -NzVector3::NzVector3(T X, T Y, T Z) +namespace Nz { - Set(X, Y, Z); -} - -template -NzVector3::NzVector3(T X, const NzVector2& vec) -{ - Set(X, vec); -} - -template -NzVector3::NzVector3(T scale) -{ - Set(scale); -} - -template -NzVector3::NzVector3(const T vec[3]) -{ - Set(vec); -} - -template -NzVector3::NzVector3(const NzVector2& vec, T Z) -{ - Set(vec, Z); -} - -template -template -NzVector3::NzVector3(const NzVector3& vec) -{ - Set(vec); -} - -template -NzVector3::NzVector3(const NzVector4& vec) -{ - Set(vec); -} - -template -T NzVector3::AbsDotProduct(const NzVector3& vec) const -{ - return std::abs(x * vec.x) + std::abs(y * vec.y) + std::abs(z * vec.z); -} - -template -T NzVector3::AngleBetween(const NzVector3& vec) const -{ - // sqrt(a) * sqrt(b) = sqrt(a*b) - T divisor = std::sqrt(GetSquaredLength() * vec.GetSquaredLength()); - - #if NAZARA_MATH_SAFE - if (NzNumberEquals(divisor, F(0.0))) + template + Vector3::Vector3(T X, T Y, T Z) { - NzString error("Division by zero"); - - NazaraError(error); - throw std::domain_error(error); + Set(X, Y, Z); } - #endif - T alpha = DotProduct(vec)/divisor; - return NzFromRadians(std::acos(NzClamp(alpha, F(-1.0), F(1.0)))); -} + template + Vector3::Vector3(T X, const Vector2& vec) + { + Set(X, vec); + } -template -NzVector3 NzVector3::CrossProduct(const NzVector3& vec) const -{ - return NzVector3(y * vec.z - z * vec.y, z * vec.x - x * vec.z, x * vec.y - y * vec.x); -} + template + Vector3::Vector3(T scale) + { + Set(scale); + } -template -T NzVector3::Distance(const NzVector3& vec) const -{ - return std::sqrt(SquaredDistance(vec)); -} + template + Vector3::Vector3(const T vec[3]) + { + Set(vec); + } -template -float NzVector3::Distancef(const NzVector3& vec) const -{ - return std::sqrt(static_cast(SquaredDistance(vec))); -} + template + Vector3::Vector3(const Vector2& vec, T Z) + { + Set(vec, Z); + } -template -T NzVector3::DotProduct(const NzVector3& vec) const -{ - return x*vec.x + y*vec.y + z*vec.z; -} + template + template + Vector3::Vector3(const Vector3& vec) + { + Set(vec); + } -template -T NzVector3::GetLength() const -{ - return std::sqrt(GetSquaredLength()); -} + template + Vector3::Vector3(const Vector4& vec) + { + Set(vec); + } -template -float NzVector3::GetLengthf() const -{ - return std::sqrt(static_cast(GetSquaredLength())); -} + template + T Vector3::AbsDotProduct(const Vector3& vec) const + { + return std::abs(x * vec.x) + std::abs(y * vec.y) + std::abs(z * vec.z); + } -template -NzVector3 NzVector3::GetNormal(T* length) const -{ - NzVector3 vec(*this); - vec.Normalize(length); + template + T Vector3::AngleBetween(const Vector3& vec) const + { + // sqrt(a) * sqrt(b) = sqrt(a*b) + T divisor = std::sqrt(GetSquaredLength() * vec.GetSquaredLength()); - return vec; -} + #if NAZARA_MATH_SAFE + if (NumberEquals(divisor, F(0.0))) + { + String error("Division by zero"); -template -T NzVector3::GetSquaredLength() const -{ - return x*x + y*y + z*z; -} + NazaraError(error); + throw std::domain_error(error); + } + #endif -template -NzVector3& NzVector3::MakeBackward() -{ - return Set(F(0.0), F(0.0), F(1.0)); -} + T alpha = DotProduct(vec)/divisor; + return FromRadians(std::acos(Clamp(alpha, F(-1.0), F(1.0)))); + } -template -NzVector3& NzVector3::MakeDown() -{ - return Set(F(0.0), F(-1.0), F(0.0)); -} + template + Vector3 Vector3::CrossProduct(const Vector3& vec) const + { + return Vector3(y * vec.z - z * vec.y, z * vec.x - x * vec.z, x * vec.y - y * vec.x); + } -template -NzVector3& NzVector3::MakeForward() -{ - return Set(F(0.0), F(0.0), F(-1.0)); -} + template + T Vector3::Distance(const Vector3& vec) const + { + return std::sqrt(SquaredDistance(vec)); + } -template -NzVector3& NzVector3::MakeLeft() -{ - return Set(F(-1.0), F(0.0), F(0.0)); -} + template + float Vector3::Distancef(const Vector3& vec) const + { + return std::sqrt(static_cast(SquaredDistance(vec))); + } -template -NzVector3& NzVector3::MakeRight() -{ - return Set(F(1.0), F(0.0), F(0.0)); -} + template + T Vector3::DotProduct(const Vector3& vec) const + { + return x*vec.x + y*vec.y + z*vec.z; + } -template -NzVector3& NzVector3::MakeUnit() -{ - return Set(F(1.0), F(1.0), F(1.0)); -} + template + T Vector3::GetLength() const + { + return std::sqrt(GetSquaredLength()); + } -template -NzVector3& NzVector3::MakeUnitX() -{ - return Set(F(1.0), F(0.0), F(0.0)); -} + template + float Vector3::GetLengthf() const + { + return std::sqrt(static_cast(GetSquaredLength())); + } -template -NzVector3& NzVector3::MakeUnitY() -{ - return Set(F(0.0), F(1.0), F(0.0)); -} + template + Vector3 Vector3::GetNormal(T* length) const + { + Vector3 vec(*this); + vec.Normalize(length); -template -NzVector3& NzVector3::MakeUnitZ() -{ - return Set(F(0.0), F(0.0), F(1.0)); -} + return vec; + } -template -NzVector3& NzVector3::MakeUp() -{ - return Set(F(0.0), F(1.0), F(0.0)); -} + template + T Vector3::GetSquaredLength() const + { + return x*x + y*y + z*z; + } -template -NzVector3& NzVector3::MakeZero() -{ - return Set(F(0.0), F(0.0), F(0.0)); -} + template + Vector3& Vector3::MakeBackward() + { + return Set(F(0.0), F(0.0), F(1.0)); + } -template -NzVector3& NzVector3::Maximize(const NzVector3& vec) -{ - if (vec.x > x) + template + Vector3& Vector3::MakeDown() + { + return Set(F(0.0), F(-1.0), F(0.0)); + } + + template + Vector3& Vector3::MakeForward() + { + return Set(F(0.0), F(0.0), F(-1.0)); + } + + template + Vector3& Vector3::MakeLeft() + { + return Set(F(-1.0), F(0.0), F(0.0)); + } + + template + Vector3& Vector3::MakeRight() + { + return Set(F(1.0), F(0.0), F(0.0)); + } + + template + Vector3& Vector3::MakeUnit() + { + return Set(F(1.0), F(1.0), F(1.0)); + } + + template + Vector3& Vector3::MakeUnitX() + { + return Set(F(1.0), F(0.0), F(0.0)); + } + + template + Vector3& Vector3::MakeUnitY() + { + return Set(F(0.0), F(1.0), F(0.0)); + } + + template + Vector3& Vector3::MakeUnitZ() + { + return Set(F(0.0), F(0.0), F(1.0)); + } + + template + Vector3& Vector3::MakeUp() + { + return Set(F(0.0), F(1.0), F(0.0)); + } + + template + Vector3& Vector3::MakeZero() + { + return Set(F(0.0), F(0.0), F(0.0)); + } + + template + Vector3& Vector3::Maximize(const Vector3& vec) + { + if (vec.x > x) + x = vec.x; + + if (vec.y > y) + y = vec.y; + + if (vec.z > z) + z = vec.z; + + return *this; + } + + template + Vector3& Vector3::Minimize(const Vector3& vec) + { + if (vec.x < x) + x = vec.x; + + if (vec.y < y) + y = vec.y; + + if (vec.z < z) + z = vec.z; + + return *this; + } + + template + Vector3& Vector3::Normalize(T* length) + { + T norm = GetLength(); + if (norm > F(0.0)) + { + T invNorm = F(1.0) / norm; + x *= invNorm; + y *= invNorm; + z *= invNorm; + } + + if (length) + *length = norm; + + return *this; + } + + template + Vector3& Vector3::Set(T X, T Y, T Z) + { + x = X; + y = Y; + z = Z; + + return *this; + } + + template + Vector3& Vector3::Set(T X, const Vector2& vec) + { + x = X; + y = vec.x; + z = vec.y; + + return *this; + } + + template + Vector3& Vector3::Set(T scale) + { + x = scale; + y = scale; + z = scale; + + return *this; + } + + template + Vector3& Vector3::Set(const T vec[3]) + { + std::memcpy(&x, vec, 3*sizeof(T)); + + return *this; + } + + template + Vector3& Vector3::Set(const Vector2& vec, T Z) + { x = vec.x; - - if (vec.y > y) y = vec.y; + z = Z; - if (vec.z > z) + return *this; + } + + template + Vector3& Vector3::Set(const Vector3& vec) + { + std::memcpy(this, &vec, sizeof(Vector3)); + + return *this; + } + + template + template + Vector3& Vector3::Set(const Vector3& vec) + { + x = F(vec.x); + y = F(vec.y); + z = F(vec.z); + + return *this; + } + + template + Vector3& Vector3::Set(const Vector4& vec) + { + x = vec.x; + y = vec.y; z = vec.z; - return *this; -} - -template -NzVector3& NzVector3::Minimize(const NzVector3& vec) -{ - if (vec.x < x) - x = vec.x; - - if (vec.y < y) - y = vec.y; - - if (vec.z < z) - z = vec.z; - - return *this; -} - -template -NzVector3& NzVector3::Normalize(T* length) -{ - T norm = GetLength(); - if (norm > F(0.0)) - { - T invNorm = F(1.0) / norm; - x *= invNorm; - y *= invNorm; - z *= invNorm; + return *this; } - if (length) - *length = norm; - - return *this; -} - -template -NzVector3& NzVector3::Set(T X, T Y, T Z) -{ - x = X; - y = Y; - z = Z; - - return *this; -} - -template -NzVector3& NzVector3::Set(T X, const NzVector2& vec) -{ - x = X; - y = vec.x; - z = vec.y; - - return *this; -} - -template -NzVector3& NzVector3::Set(T scale) -{ - x = scale; - y = scale; - z = scale; - - return *this; -} - -template -NzVector3& NzVector3::Set(const T vec[3]) -{ - std::memcpy(&x, vec, 3*sizeof(T)); - - return *this; -} - -template -NzVector3& NzVector3::Set(const NzVector2& vec, T Z) -{ - x = vec.x; - y = vec.y; - z = Z; - - return *this; -} - -template -NzVector3& NzVector3::Set(const NzVector3& vec) -{ - std::memcpy(this, &vec, sizeof(NzVector3)); - - return *this; -} - -template -template -NzVector3& NzVector3::Set(const NzVector3& vec) -{ - x = F(vec.x); - y = F(vec.y); - z = F(vec.z); - - return *this; -} - -template -NzVector3& NzVector3::Set(const NzVector4& vec) -{ - x = vec.x; - y = vec.y; - z = vec.z; - - return *this; -} - -template -T NzVector3::SquaredDistance(const NzVector3& vec) const -{ - return (*this - vec).GetSquaredLength(); -} - -template -NzString NzVector3::ToString() const -{ - NzStringStream ss; - - return ss << "Vector3(" << x << ", " << y << ", " << z <<')'; -} - -template -NzVector3::operator T*() -{ - return &x; -} - -template -NzVector3::operator const T*() const -{ - return &x; -} - -template -const NzVector3& NzVector3::operator+() const -{ - return *this; -} - -template -NzVector3 NzVector3::operator-() const -{ - return NzVector3(-x, -y, -z); -} - -template -NzVector3 NzVector3::operator+(const NzVector3& vec) const -{ - return NzVector3(x + vec.x, y + vec.y, z + vec.z); -} - -template -NzVector3 NzVector3::operator-(const NzVector3& vec) const -{ - return NzVector3(x - vec.x, y - vec.y, z - vec.z); -} - -template -NzVector3 NzVector3::operator*(const NzVector3& vec) const -{ - return NzVector3(x * vec.x, y * vec.y, z * vec.z); -} - -template -NzVector3 NzVector3::operator*(T scale) const -{ - return NzVector3(x * scale, y * scale, z * scale); -} - -template -NzVector3 NzVector3::operator/(const NzVector3& vec) const -{ - #if NAZARA_MATH_SAFE - if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0))) + template + T Vector3::SquaredDistance(const Vector3& vec) const { - NzString error("Division by zero"); - - NazaraError(error); - throw std::domain_error(error); - } - #endif - - return NzVector3(x / vec.x, y / vec.y, z / vec.z); -} - -template -NzVector3 NzVector3::operator/(T scale) const -{ - #if NAZARA_MATH_SAFE - if (NzNumberEquals(scale, F(0.0))) - { - NzString error("Division by zero"); - - NazaraError(error); - throw std::domain_error(error); - } - #endif - - return NzVector3(x / scale, y / scale, z / scale); -} - -template -NzVector3& NzVector3::operator+=(const NzVector3& vec) -{ - x += vec.x; - y += vec.y; - z += vec.z; - - return *this; -} - -template -NzVector3& NzVector3::operator-=(const NzVector3& vec) -{ - x -= vec.x; - y -= vec.y; - z -= vec.z; - - return *this; -} - -template -NzVector3& NzVector3::operator*=(const NzVector3& vec) -{ - x *= vec.x; - y *= vec.y; - z *= vec.z; - - return *this; -} - -template -NzVector3& NzVector3::operator*=(T scale) -{ - x *= scale; - y *= scale; - z *= scale; - - return *this; -} - -template -NzVector3& NzVector3::operator/=(const NzVector3& vec) -{ - if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0))) - { - NzString error("Division by zero"); - - NazaraError(error); - throw std::domain_error(error); + return (*this - vec).GetSquaredLength(); } - x /= vec.x; - y /= vec.y; - z /= vec.z; - - return *this; -} - -template -NzVector3& NzVector3::operator/=(T scale) -{ - if (NzNumberEquals(scale, F(0.0))) + template + String Vector3::ToString() const { - NzString error("Division by zero"); + StringStream ss; - NazaraError(error); - throw std::domain_error(error); + return ss << "Vector3(" << x << ", " << y << ", " << z <<')'; } - x /= scale; - y /= scale; - z /= scale; - - return *this; -} - -template -bool NzVector3::operator==(const NzVector3& vec) const -{ - return NzNumberEquals(x, vec.x) && - NzNumberEquals(y, vec.y) && - NzNumberEquals(z, vec.z); -} - -template -bool NzVector3::operator!=(const NzVector3& vec) const -{ - return !operator==(vec); -} - -template -bool NzVector3::operator<(const NzVector3& vec) const -{ - if (x == vec.x) + template + Vector3::operator T*() { - if (y == vec.y) - return z < vec.z; + return &x; + } + + template + Vector3::operator const T*() const + { + return &x; + } + + template + const Vector3& Vector3::operator+() const + { + return *this; + } + + template + Vector3 Vector3::operator-() const + { + return Vector3(-x, -y, -z); + } + + template + Vector3 Vector3::operator+(const Vector3& vec) const + { + return Vector3(x + vec.x, y + vec.y, z + vec.z); + } + + template + Vector3 Vector3::operator-(const Vector3& vec) const + { + return Vector3(x - vec.x, y - vec.y, z - vec.z); + } + + template + Vector3 Vector3::operator*(const Vector3& vec) const + { + return Vector3(x * vec.x, y * vec.y, z * vec.z); + } + + template + Vector3 Vector3::operator*(T scale) const + { + return Vector3(x * scale, y * scale, z * scale); + } + + template + Vector3 Vector3::operator/(const Vector3& vec) const + { + #if NAZARA_MATH_SAFE + if (NumberEquals(vec.x, F(0.0)) || NumberEquals(vec.y, F(0.0)) || NumberEquals(vec.z, F(0.0))) + { + String error("Division by zero"); + + NazaraError(error); + throw std::domain_error(error); + } + #endif + + return Vector3(x / vec.x, y / vec.y, z / vec.z); + } + + template + Vector3 Vector3::operator/(T scale) const + { + #if NAZARA_MATH_SAFE + if (NumberEquals(scale, F(0.0))) + { + String error("Division by zero"); + + NazaraError(error); + throw std::domain_error(error); + } + #endif + + return Vector3(x / scale, y / scale, z / scale); + } + + template + Vector3& Vector3::operator+=(const Vector3& vec) + { + x += vec.x; + y += vec.y; + z += vec.z; + + return *this; + } + + template + Vector3& Vector3::operator-=(const Vector3& vec) + { + x -= vec.x; + y -= vec.y; + z -= vec.z; + + return *this; + } + + template + Vector3& Vector3::operator*=(const Vector3& vec) + { + x *= vec.x; + y *= vec.y; + z *= vec.z; + + return *this; + } + + template + Vector3& Vector3::operator*=(T scale) + { + x *= scale; + y *= scale; + z *= scale; + + return *this; + } + + template + Vector3& Vector3::operator/=(const Vector3& vec) + { + if (NumberEquals(vec.x, F(0.0)) || NumberEquals(vec.y, F(0.0)) || NumberEquals(vec.z, F(0.0))) + { + String error("Division by zero"); + + NazaraError(error); + throw std::domain_error(error); + } + + x /= vec.x; + y /= vec.y; + z /= vec.z; + + return *this; + } + + template + Vector3& Vector3::operator/=(T scale) + { + if (NumberEquals(scale, F(0.0))) + { + String error("Division by zero"); + + NazaraError(error); + throw std::domain_error(error); + } + + x /= scale; + y /= scale; + z /= scale; + + return *this; + } + + template + bool Vector3::operator==(const Vector3& vec) const + { + return NumberEquals(x, vec.x) && + NumberEquals(y, vec.y) && + NumberEquals(z, vec.z); + } + + template + bool Vector3::operator!=(const Vector3& vec) const + { + return !operator==(vec); + } + + template + bool Vector3::operator<(const Vector3& vec) const + { + if (x == vec.x) + { + if (y == vec.y) + return z < vec.z; + else + return y < vec.y; + } else - return y < vec.y; + return x < vec.x; } - else - return x < vec.x; -} -template -bool NzVector3::operator<=(const NzVector3& vec) const -{ - if (x == vec.x) + template + bool Vector3::operator<=(const Vector3& vec) const { - if (y == vec.y) - return z <= vec.z; + if (x == vec.x) + { + if (y == vec.y) + return z <= vec.z; + else + return y < vec.y; + } else - return y < vec.y; + return x < vec.x; + } + + template + bool Vector3::operator>(const Vector3& vec) const + { + return !operator<=(vec); + } + + template + bool Vector3::operator>=(const Vector3& vec) const + { + return !operator<(vec); + } + + template + Vector3 Vector3::CrossProduct(const Vector3& vec1, const Vector3& vec2) + { + return vec1.CrossProduct(vec2); + } + + template + T Vector3::DotProduct(const Vector3& vec1, const Vector3& vec2) + { + return vec1.DotProduct(vec2); + } + + template + Vector3 Vector3::Backward() + { + Vector3 vector; + vector.MakeBackward(); + + return vector; + } + + template + Vector3 Vector3::Down() + { + Vector3 vector; + vector.MakeDown(); + + return vector; + } + + template + Vector3 Vector3::Forward() + { + Vector3 vector; + vector.MakeForward(); + + return vector; + } + + template + Vector3 Vector3::Left() + { + Vector3 vector; + vector.MakeLeft(); + + return vector; + } + + template + Vector3 Vector3::Lerp(const Vector3& from, const Vector3& to, T interpolation) + { + return Nz::Lerp(from, to, interpolation); + } + + template + Vector3 Vector3::Normalize(const Vector3& vec) + { + return vec.GetNormal(); + } + + template + Vector3 Vector3::Right() + { + Vector3 vector; + vector.MakeRight(); + + return vector; + } + + template + Vector3 Vector3::Unit() + { + Vector3 vector; + vector.MakeUnit(); + + return vector; + } + + template + Vector3 Vector3::UnitX() + { + Vector3 vector; + vector.MakeUnitX(); + + return vector; + } + + template + Vector3 Vector3::UnitY() + { + Vector3 vector; + vector.MakeUnitY(); + + return vector; + } + + template + Vector3 Vector3::UnitZ() + { + Vector3 vector; + vector.MakeUnitZ(); + + return vector; + } + + template + Vector3 Vector3::Up() + { + Vector3 vector; + vector.MakeUp(); + + return vector; + } + + template + Vector3 Vector3::Zero() + { + Vector3 vector; + vector.MakeZero(); + + return vector; } - else - return x < vec.x; } template -bool NzVector3::operator>(const NzVector3& vec) const -{ - return !operator<=(vec); -} - -template -bool NzVector3::operator>=(const NzVector3& vec) const -{ - return !operator<(vec); -} - -template -NzVector3 NzVector3::CrossProduct(const NzVector3& vec1, const NzVector3& vec2) -{ - return vec1.CrossProduct(vec2); -} - -template -T NzVector3::DotProduct(const NzVector3& vec1, const NzVector3& vec2) -{ - return vec1.DotProduct(vec2); -} - -template -NzVector3 NzVector3::Backward() -{ - NzVector3 vector; - vector.MakeBackward(); - - return vector; -} - -template -NzVector3 NzVector3::Down() -{ - NzVector3 vector; - vector.MakeDown(); - - return vector; -} - -template -NzVector3 NzVector3::Forward() -{ - NzVector3 vector; - vector.MakeForward(); - - return vector; -} - -template -NzVector3 NzVector3::Left() -{ - NzVector3 vector; - vector.MakeLeft(); - - return vector; -} - -template -NzVector3 NzVector3::Lerp(const NzVector3& from, const NzVector3& to, T interpolation) -{ - return NzLerp(from, to, interpolation); -} - -template -NzVector3 NzVector3::Normalize(const NzVector3& vec) -{ - return vec.GetNormal(); -} - -template -NzVector3 NzVector3::Right() -{ - NzVector3 vector; - vector.MakeRight(); - - return vector; -} - -template -NzVector3 NzVector3::Unit() -{ - NzVector3 vector; - vector.MakeUnit(); - - return vector; -} - -template -NzVector3 NzVector3::UnitX() -{ - NzVector3 vector; - vector.MakeUnitX(); - - return vector; -} - -template -NzVector3 NzVector3::UnitY() -{ - NzVector3 vector; - vector.MakeUnitY(); - - return vector; -} - -template -NzVector3 NzVector3::UnitZ() -{ - NzVector3 vector; - vector.MakeUnitZ(); - - return vector; -} - -template -NzVector3 NzVector3::Up() -{ - NzVector3 vector; - vector.MakeUp(); - - return vector; -} - -template -NzVector3 NzVector3::Zero() -{ - NzVector3 vector; - vector.MakeZero(); - - return vector; -} - -template -std::ostream& operator<<(std::ostream& out, const NzVector3& vec) +std::ostream& operator<<(std::ostream& out, const Nz::Vector3& vec) { return out << vec.ToString(); } template -NzVector3 operator*(T scale, const NzVector3& vec) +Nz::Vector3 operator*(T scale, const Nz::Vector3& vec) { - return NzVector3(scale * vec.x, scale * vec.y, scale * vec.z); + return Nz::Vector3(scale * vec.x, scale * vec.y, scale * vec.z); } template -NzVector3 operator/(T scale, const NzVector3& vec) +Nz::Vector3 operator/(T scale, const Nz::Vector3& vec) { #if NAZARA_MATH_SAFE - if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0))) + if (Nz::NumberEquals(vec.x, F(0.0)) || Nz::NumberEquals(vec.y, F(0.0)) || Nz::NumberEquals(vec.z, F(0.0))) { - NzString error("Division by zero"); + Nz::String error("Division by zero"); NazaraError(error); throw std::domain_error(error); } #endif - return NzVector3(scale / vec.x, scale / vec.y, scale / vec.z); + return Nz::Vector3(scale / vec.x, scale / vec.y, scale / vec.z); } #undef F diff --git a/include/Nazara/Math/Vector4.hpp b/include/Nazara/Math/Vector4.hpp index d4620a64a..ac953f6ab 100644 --- a/include/Nazara/Math/Vector4.hpp +++ b/include/Nazara/Math/Vector4.hpp @@ -9,101 +9,104 @@ #include -template class NzVector2; -template class NzVector3; - -template -class NzVector4 +namespace Nz { - public: - NzVector4() = default; - NzVector4(T X, T Y, T Z, T W = 1.0); - NzVector4(T X, T Y, const NzVector2& vec); - NzVector4(T X, const NzVector2& vec, T W); - NzVector4(T X, const NzVector3& vec); - explicit NzVector4(T scale); - NzVector4(const T vec[4]); - NzVector4(const NzVector2& vec, T Z = 0.0, T W = 1.0); - NzVector4(const NzVector3& vec, T W = 0.0); - template explicit NzVector4(const NzVector4& vec); - NzVector4(const NzVector4& vec) = default; - ~NzVector4() = default; + template class Vector2; + template class Vector3; - T AbsDotProduct(const NzVector4& vec) const; + template + class Vector4 + { + public: + Vector4() = default; + Vector4(T X, T Y, T Z, T W = 1.0); + Vector4(T X, T Y, const Vector2& vec); + Vector4(T X, const Vector2& vec, T W); + Vector4(T X, const Vector3& vec); + explicit Vector4(T scale); + Vector4(const T vec[4]); + Vector4(const Vector2& vec, T Z = 0.0, T W = 1.0); + Vector4(const Vector3& vec, T W = 0.0); + template explicit Vector4(const Vector4& vec); + Vector4(const Vector4& vec) = default; + ~Vector4() = default; - T DotProduct(const NzVector4& vec) const; + T AbsDotProduct(const Vector4& vec) const; - NzVector4 GetNormal(T* length = nullptr) const; + T DotProduct(const Vector4& vec) const; - NzVector4& MakeUnitX(); - NzVector4& MakeUnitY(); - NzVector4& MakeUnitZ(); - NzVector4& MakeZero(); + Vector4 GetNormal(T* length = nullptr) const; - NzVector4& Maximize(const NzVector4& vec); - NzVector4& Minimize(const NzVector4& vec); + Vector4& MakeUnitX(); + Vector4& MakeUnitY(); + Vector4& MakeUnitZ(); + Vector4& MakeZero(); - NzVector4& Normalize(T* length = nullptr); + Vector4& Maximize(const Vector4& vec); + Vector4& Minimize(const Vector4& vec); - NzVector4& Set(T X, T Y, T Z, T W = 1.0); - NzVector4& Set(T X, T Y, const NzVector2& vec); - NzVector4& Set(T X, const NzVector2& vec, T W); - NzVector4& Set(T X, const NzVector3& vec); - NzVector4& Set(T scale); - NzVector4& Set(const T vec[4]); - NzVector4& Set(const NzVector2& vec, T Z = 0.0, T W = 1.0); - NzVector4& Set(const NzVector3& vec, T W = 1.0); - NzVector4& Set(const NzVector4& vec); - template NzVector4& Set(const NzVector4& vec); + Vector4& Normalize(T* length = nullptr); - NzString ToString() const; + Vector4& Set(T X, T Y, T Z, T W = 1.0); + Vector4& Set(T X, T Y, const Vector2& vec); + Vector4& Set(T X, const Vector2& vec, T W); + Vector4& Set(T X, const Vector3& vec); + Vector4& Set(T scale); + Vector4& Set(const T vec[4]); + Vector4& Set(const Vector2& vec, T Z = 0.0, T W = 1.0); + Vector4& Set(const Vector3& vec, T W = 1.0); + Vector4& Set(const Vector4& vec); + template Vector4& Set(const Vector4& vec); - operator T*(); - operator const T*() const; + String ToString() const; - const NzVector4& operator+() const; - NzVector4 operator-() const; + operator T*(); + operator const T*() const; - NzVector4 operator+(const NzVector4& vec) const; - NzVector4 operator-(const NzVector4& vec) const; - NzVector4 operator*(const NzVector4& vec) const; - NzVector4 operator*(T scale) const; - NzVector4 operator/(const NzVector4& vec) const; - NzVector4 operator/(T scale) const; + const Vector4& operator+() const; + Vector4 operator-() const; - NzVector4& operator+=(const NzVector4& vec); - NzVector4& operator-=(const NzVector4& vec); - NzVector4& operator*=(const NzVector4& vec); - NzVector4& operator*=(T scale); - NzVector4& operator/=(const NzVector4& vec); - NzVector4& operator/=(T scale); + Vector4 operator+(const Vector4& vec) const; + Vector4 operator-(const Vector4& vec) const; + Vector4 operator*(const Vector4& vec) const; + Vector4 operator*(T scale) const; + Vector4 operator/(const Vector4& vec) const; + Vector4 operator/(T scale) const; - bool operator==(const NzVector4& vec) const; - bool operator!=(const NzVector4& vec) const; - bool operator<(const NzVector4& vec) const; - bool operator<=(const NzVector4& vec) const; - bool operator>(const NzVector4& vec) const; - bool operator>=(const NzVector4& vec) const; + Vector4& operator+=(const Vector4& vec); + Vector4& operator-=(const Vector4& vec); + Vector4& operator*=(const Vector4& vec); + Vector4& operator*=(T scale); + Vector4& operator/=(const Vector4& vec); + Vector4& operator/=(T scale); - static NzVector4 UnitX(); - static NzVector4 UnitY(); - static NzVector4 UnitZ(); - static NzVector4 Zero(); + bool operator==(const Vector4& vec) const; + bool operator!=(const Vector4& vec) const; + bool operator<(const Vector4& vec) const; + bool operator<=(const Vector4& vec) const; + bool operator>(const Vector4& vec) const; + bool operator>=(const Vector4& vec) const; - T x, y, z, w; -}; + static Vector4 UnitX(); + static Vector4 UnitY(); + static Vector4 UnitZ(); + static Vector4 Zero(); -template std::ostream& operator<<(std::ostream& out, const NzVector4& vec); + T x, y, z, w; + }; -template NzVector4 operator*(T scale, const NzVector4& vec); -template NzVector4 operator/(T scale, const NzVector4& vec); + typedef Vector4 Vector4d; + typedef Vector4 Vector4f; + typedef Vector4 Vector4i; + typedef Vector4 Vector4ui; + typedef Vector4 Vector4i32; + typedef Vector4 Vector4ui32; +} -typedef NzVector4 NzVector4d; -typedef NzVector4 NzVector4f; -typedef NzVector4 NzVector4i; -typedef NzVector4 NzVector4ui; -typedef NzVector4 NzVector4i32; -typedef NzVector4 NzVector4ui32; +template std::ostream& operator<<(std::ostream& out, const Nz::Vector4& vec); + +template Nz::Vector4 operator*(T scale, const Nz::Vector4& vec); +template Nz::Vector4 operator/(T scale, const Nz::Vector4& vec); #include diff --git a/include/Nazara/Math/Vector4.inl b/include/Nazara/Math/Vector4.inl index 6b17b2ced..9193d6f06 100644 --- a/include/Nazara/Math/Vector4.inl +++ b/include/Nazara/Math/Vector4.inl @@ -12,564 +12,567 @@ #define F(a) static_cast(a) -template -NzVector4::NzVector4(T X, T Y, T Z, T W) +namespace Nz { - Set(X, Y, Z, W); -} + template + Vector4::Vector4(T X, T Y, T Z, T W) + { + Set(X, Y, Z, W); + } -template -NzVector4::NzVector4(T X, T Y, const NzVector2& vec) -{ - Set(X, Y, vec); -} + template + Vector4::Vector4(T X, T Y, const Vector2& vec) + { + Set(X, Y, vec); + } -template -NzVector4::NzVector4(T X, const NzVector2& vec, T W) -{ - Set(X, vec, W); -} + template + Vector4::Vector4(T X, const Vector2& vec, T W) + { + Set(X, vec, W); + } -template -NzVector4::NzVector4(T X, const NzVector3& vec) -{ - Set(X, vec); -} + template + Vector4::Vector4(T X, const Vector3& vec) + { + Set(X, vec); + } -template -NzVector4::NzVector4(T scale) -{ - Set(scale); -} + template + Vector4::Vector4(T scale) + { + Set(scale); + } -template -NzVector4::NzVector4(const T vec[4]) -{ - Set(vec); -} + template + Vector4::Vector4(const T vec[4]) + { + Set(vec); + } -template -NzVector4::NzVector4(const NzVector2& vec, T Z, T W) -{ - Set(vec, Z, W); -} + template + Vector4::Vector4(const Vector2& vec, T Z, T W) + { + Set(vec, Z, W); + } -template -NzVector4::NzVector4(const NzVector3& vec, T W) -{ - Set(vec, W); -} + template + Vector4::Vector4(const Vector3& vec, T W) + { + Set(vec, W); + } -template -template -NzVector4::NzVector4(const NzVector4& vec) -{ - Set(vec); -} + template + template + Vector4::Vector4(const Vector4& vec) + { + Set(vec); + } -template -T NzVector4::AbsDotProduct(const NzVector4& vec) const -{ - return std::abs(x * vec.x) + std::abs(y * vec.y) + std::abs(z * vec.z) + std::abs(w * vec.w); -} + template + T Vector4::AbsDotProduct(const Vector4& vec) const + { + return std::abs(x * vec.x) + std::abs(y * vec.y) + std::abs(z * vec.z) + std::abs(w * vec.w); + } -template -T NzVector4::DotProduct(const NzVector4& vec) const -{ - return x*vec.x + y*vec.y + z*vec.z + w*vec.w; -} + template + T Vector4::DotProduct(const Vector4& vec) const + { + return x*vec.x + y*vec.y + z*vec.z + w*vec.w; + } -template -NzVector4 NzVector4::GetNormal(T* length) const -{ - NzVector4 vec(*this); - vec.Normalize(length); + template + Vector4 Vector4::GetNormal(T* length) const + { + Vector4 vec(*this); + vec.Normalize(length); - return vec; -} + return vec; + } -template -NzVector4& NzVector4::MakeUnitX() -{ - return Set(F(1.0), F(0.0), F(0.0), F(1.0)); -} + template + Vector4& Vector4::MakeUnitX() + { + return Set(F(1.0), F(0.0), F(0.0), F(1.0)); + } -template -NzVector4& NzVector4::MakeUnitY() -{ - return Set(F(0.0), F(1.0), F(0.0), F(1.0)); -} + template + Vector4& Vector4::MakeUnitY() + { + return Set(F(0.0), F(1.0), F(0.0), F(1.0)); + } -template -NzVector4& NzVector4::MakeUnitZ() -{ - return Set(F(0.0), F(0.0), F(1.0), F(1.0)); -} + template + Vector4& Vector4::MakeUnitZ() + { + return Set(F(0.0), F(0.0), F(1.0), F(1.0)); + } -template -NzVector4& NzVector4::MakeZero() -{ - return Set(F(0.0), F(0.0), F(0.0), F(0.0)); -} + template + Vector4& Vector4::MakeZero() + { + return Set(F(0.0), F(0.0), F(0.0), F(0.0)); + } -template -NzVector4& NzVector4::Maximize(const NzVector4& vec) -{ - if (vec.x > x) + template + Vector4& Vector4::Maximize(const Vector4& vec) + { + if (vec.x > x) + x = vec.x; + + if (vec.y > y) + y = vec.y; + + if (vec.z > z) + z = vec.z; + + if (vec.w > w) + w = vec.w; + + return *this; + } + + template + Vector4& Vector4::Minimize(const Vector4& vec) + { + if (vec.x < x) + x = vec.x; + + if (vec.y < y) + y = vec.y; + + if (vec.z < z) + z = vec.z; + + if (vec.w < w) + w = vec.w; + + return *this; + } + + template + Vector4& Vector4::Normalize(T* length) + { + T invLength = F(1.0)/w; + x *= invLength; // Attention, briser cette logique casserait Frustum::Extract + y *= invLength; + z *= invLength; + + if (length) + *length = w; + + w = F(1.0); + + return *this; + } + + template + Vector4& Vector4::Set(T X, T Y, T Z, T W) + { + x = X; + y = Y; + z = Z; + w = W; + + return *this; + } + + template + Vector4& Vector4::Set(T X, T Y, const Vector2& vec) + { + x = X; + y = Y; + z = vec.x; + w = vec.y; + + return *this; + } + + template + Vector4& Vector4::Set(T X, const Vector2& vec, T W) + { + x = X; + y = vec.x; + z = vec.y; + w = W; + + return *this; + } + + template + Vector4& Vector4::Set(T X, const Vector3& vec) + { + x = X; + y = vec.x; + z = vec.y; + w = vec.z; + + return *this; + } + + template + Vector4& Vector4::Set(T scale) + { + x = scale; + y = scale; + z = scale; + w = scale; + + return *this; + } + + template + Vector4& Vector4::Set(const T vec[4]) + { + std::memcpy(&x, vec, 4*sizeof(T)); + + return *this; + } + + template + Vector4& Vector4::Set(const Vector2& vec, T Z, T W) + { x = vec.x; - - if (vec.y > y) y = vec.y; + z = Z; + w = W; - if (vec.z > z) - z = vec.z; + return *this; + } - if (vec.w > w) - w = vec.w; - - return *this; -} - -template -NzVector4& NzVector4::Minimize(const NzVector4& vec) -{ - if (vec.x < x) + template + Vector4& Vector4::Set(const Vector3& vec, T W) + { x = vec.x; - - if (vec.y < y) y = vec.y; - - if (vec.z < z) z = vec.z; + w = W; - if (vec.w < w) - w = vec.w; - - return *this; -} - -template -NzVector4& NzVector4::Normalize(T* length) -{ - T invLength = F(1.0)/w; - x *= invLength; // Attention, briser cette logique casserait Frustum::Extract - y *= invLength; - z *= invLength; - - if (length) - *length = w; - - w = F(1.0); - - return *this; -} - -template -NzVector4& NzVector4::Set(T X, T Y, T Z, T W) -{ - x = X; - y = Y; - z = Z; - w = W; - - return *this; -} - -template -NzVector4& NzVector4::Set(T X, T Y, const NzVector2& vec) -{ - x = X; - y = Y; - z = vec.x; - w = vec.y; - - return *this; -} - -template -NzVector4& NzVector4::Set(T X, const NzVector2& vec, T W) -{ - x = X; - y = vec.x; - z = vec.y; - w = W; - - return *this; -} - -template -NzVector4& NzVector4::Set(T X, const NzVector3& vec) -{ - x = X; - y = vec.x; - z = vec.y; - w = vec.z; - - return *this; -} - -template -NzVector4& NzVector4::Set(T scale) -{ - x = scale; - y = scale; - z = scale; - w = scale; - - return *this; -} - -template -NzVector4& NzVector4::Set(const T vec[4]) -{ - std::memcpy(&x, vec, 4*sizeof(T)); - - return *this; -} - -template -NzVector4& NzVector4::Set(const NzVector2& vec, T Z, T W) -{ - x = vec.x; - y = vec.y; - z = Z; - w = W; - - return *this; -} - -template -NzVector4& NzVector4::Set(const NzVector3& vec, T W) -{ - x = vec.x; - y = vec.y; - z = vec.z; - w = W; - - return *this; -} - -template -NzVector4& NzVector4::Set(const NzVector4& vec) -{ - std::memcpy(this, &vec, sizeof(NzVector4)); - - return *this; -} - -template -template -NzVector4& NzVector4::Set(const NzVector4& vec) -{ - x = F(vec.x); - y = F(vec.y); - z = F(vec.z); - w = F(vec.w); - - return *this; -} - -template -NzString NzVector4::ToString() const -{ - NzStringStream ss; - - return ss << "Vector4(" << x << ", " << y << ", " << z << ", " << w << ')'; -} - -template -NzVector4::operator T*() -{ - return &x; -} - -template -NzVector4::operator const T*() const -{ - return &x; -} - -template -const NzVector4& NzVector4::operator+() const -{ - return *this; -} - -template -NzVector4 NzVector4::operator-() const -{ - return NzVector4(-x, -y, -z, -w); -} - -template -NzVector4 NzVector4::operator+(const NzVector4& vec) const -{ - return NzVector4(x + vec.x, y + vec.y, z + vec.z, w + vec.w); -} - -template -NzVector4 NzVector4::operator-(const NzVector4& vec) const -{ - return NzVector4(x - vec.x, y - vec.y, z - vec.z, w - vec.w); -} - -template -NzVector4 NzVector4::operator*(const NzVector4& vec) const -{ - return NzVector4(x * vec.x, y * vec.y, z * vec.z, w * vec.w); -} - -template -NzVector4 NzVector4::operator*(T scale) const -{ - return NzVector4(x * scale, y * scale, z * scale, w * scale); -} - -template -NzVector4 NzVector4::operator/(const NzVector4& vec) const -{ - #if NAZARA_MATH_SAFE - if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)) || NzNumberEquals(vec.w, F(0.0))) - { - NzString error("Division by zero"); - - NazaraError(error); - throw std::domain_error(error); + return *this; } - #endif - return NzVector4(x / vec.x, y / vec.y, z / vec.z, w / vec.w); -} - -template -NzVector4 NzVector4::operator/(T scale) const -{ - #if NAZARA_MATH_SAFE - if (NzNumberEquals(scale, F(0.0))) + template + Vector4& Vector4::Set(const Vector4& vec) { - NzString error("Division by zero"); + std::memcpy(this, &vec, sizeof(Vector4)); - NazaraError(error); - throw std::domain_error(error); + return *this; } - #endif - return NzVector4(x / scale, y / scale, z / scale, w / scale); -} - -template -NzVector4& NzVector4::operator+=(const NzVector4& vec) -{ - x += vec.x; - y += vec.y; - z += vec.z; - w += vec.w; - - return *this; -} - -template -NzVector4& NzVector4::operator-=(const NzVector4& vec) -{ - x -= vec.x; - y -= vec.y; - z -= vec.z; - w -= vec.w; - - return *this; -} - -template -NzVector4& NzVector4::operator*=(const NzVector4& vec) -{ - x *= vec.x; - y *= vec.y; - z *= vec.z; - w *= vec.w; - - return *this; -} - -template -NzVector4& NzVector4::operator*=(T scale) -{ - x *= scale; - y *= scale; - z *= scale; - w *= scale; - - return *this; -} - -template -NzVector4& NzVector4::operator/=(const NzVector4& vec) -{ - #if NAZARA_MATH_SAFE - if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)) || NzNumberEquals(vec.w, F(0.0))) + template + template + Vector4& Vector4::Set(const Vector4& vec) { - NzString error("Division by zero"); + x = F(vec.x); + y = F(vec.y); + z = F(vec.z); + w = F(vec.w); - NazaraError(error); - throw std::domain_error(error); + return *this; } - #endif - x /= vec.x; - y /= vec.y; - z /= vec.z; - w /= vec.w; - - return *this; -} - -template -NzVector4& NzVector4::operator/=(T scale) -{ - #if NAZARA_MATH_SAFE - if (NzNumberEquals(scale, F(0.0))) + template + String Vector4::ToString() const { - NzString error("Division by zero"); + StringStream ss; - NazaraError(error); - throw std::domain_error(error); + return ss << "Vector4(" << x << ", " << y << ", " << z << ", " << w << ')'; } - #endif - x /= scale; - y /= scale; - z /= scale; - w /= scale; - - return *this; -} - -template -bool NzVector4::operator==(const NzVector4& vec) const -{ - return NzNumberEquals(x, vec.x) && - NzNumberEquals(y, vec.y) && - NzNumberEquals(z, vec.z) && - NzNumberEquals(w, vec.w); -} - -template -bool NzVector4::operator!=(const NzVector4& vec) const -{ - return !operator==(vec); -} - -template -bool NzVector4::operator<(const NzVector4& vec) const -{ - if (x == vec.x) + template + Vector4::operator T*() { - if (y == vec.y) + return &x; + } + + template + Vector4::operator const T*() const + { + return &x; + } + + template + const Vector4& Vector4::operator+() const + { + return *this; + } + + template + Vector4 Vector4::operator-() const + { + return Vector4(-x, -y, -z, -w); + } + + template + Vector4 Vector4::operator+(const Vector4& vec) const + { + return Vector4(x + vec.x, y + vec.y, z + vec.z, w + vec.w); + } + + template + Vector4 Vector4::operator-(const Vector4& vec) const + { + return Vector4(x - vec.x, y - vec.y, z - vec.z, w - vec.w); + } + + template + Vector4 Vector4::operator*(const Vector4& vec) const + { + return Vector4(x * vec.x, y * vec.y, z * vec.z, w * vec.w); + } + + template + Vector4 Vector4::operator*(T scale) const + { + return Vector4(x * scale, y * scale, z * scale, w * scale); + } + + template + Vector4 Vector4::operator/(const Vector4& vec) const + { + #if NAZARA_MATH_SAFE + if (NumberEquals(vec.x, F(0.0)) || NumberEquals(vec.y, F(0.0)) || NumberEquals(vec.z, F(0.0)) || NumberEquals(vec.w, F(0.0))) { - if (z == vec.z) - return w < vec.w; + String error("Division by zero"); + + NazaraError(error); + throw std::domain_error(error); + } + #endif + + return Vector4(x / vec.x, y / vec.y, z / vec.z, w / vec.w); + } + + template + Vector4 Vector4::operator/(T scale) const + { + #if NAZARA_MATH_SAFE + if (NumberEquals(scale, F(0.0))) + { + String error("Division by zero"); + + NazaraError(error); + throw std::domain_error(error); + } + #endif + + return Vector4(x / scale, y / scale, z / scale, w / scale); + } + + template + Vector4& Vector4::operator+=(const Vector4& vec) + { + x += vec.x; + y += vec.y; + z += vec.z; + w += vec.w; + + return *this; + } + + template + Vector4& Vector4::operator-=(const Vector4& vec) + { + x -= vec.x; + y -= vec.y; + z -= vec.z; + w -= vec.w; + + return *this; + } + + template + Vector4& Vector4::operator*=(const Vector4& vec) + { + x *= vec.x; + y *= vec.y; + z *= vec.z; + w *= vec.w; + + return *this; + } + + template + Vector4& Vector4::operator*=(T scale) + { + x *= scale; + y *= scale; + z *= scale; + w *= scale; + + return *this; + } + + template + Vector4& Vector4::operator/=(const Vector4& vec) + { + #if NAZARA_MATH_SAFE + if (NumberEquals(vec.x, F(0.0)) || NumberEquals(vec.y, F(0.0)) || NumberEquals(vec.z, F(0.0)) || NumberEquals(vec.w, F(0.0))) + { + String error("Division by zero"); + + NazaraError(error); + throw std::domain_error(error); + } + #endif + + x /= vec.x; + y /= vec.y; + z /= vec.z; + w /= vec.w; + + return *this; + } + + template + Vector4& Vector4::operator/=(T scale) + { + #if NAZARA_MATH_SAFE + if (NumberEquals(scale, F(0.0))) + { + String error("Division by zero"); + + NazaraError(error); + throw std::domain_error(error); + } + #endif + + x /= scale; + y /= scale; + z /= scale; + w /= scale; + + return *this; + } + + template + bool Vector4::operator==(const Vector4& vec) const + { + return NumberEquals(x, vec.x) && + NumberEquals(y, vec.y) && + NumberEquals(z, vec.z) && + NumberEquals(w, vec.w); + } + + template + bool Vector4::operator!=(const Vector4& vec) const + { + return !operator==(vec); + } + + template + bool Vector4::operator<(const Vector4& vec) const + { + if (x == vec.x) + { + if (y == vec.y) + { + if (z == vec.z) + return w < vec.w; + else + return z < vec.z; + } else - return z < vec.z; + return y < vec.y; } else - return y < vec.y; + return x < vec.x; } - else - return x < vec.x; -} -template -bool NzVector4::operator<=(const NzVector4& vec) const -{ - if (x == vec.x) + template + bool Vector4::operator<=(const Vector4& vec) const { - if (y == vec.y) + if (x == vec.x) { - if (z == vec.z) - return w <= vec.w; + if (y == vec.y) + { + if (z == vec.z) + return w <= vec.w; + else + return z < vec.z; + } else - return z < vec.z; + return y < vec.y; } else - return y < vec.y; + return x < vec.x; + } + + template + bool Vector4::operator>(const Vector4& vec) const + { + return !operator<=(vec); + } + + template + bool Vector4::operator>=(const Vector4& vec) const + { + return !operator<(vec); + } + + template + Vector4 Vector4::UnitX() + { + Vector4 vector; + vector.MakeUnitX(); + + return vector; + } + + template + Vector4 Vector4::UnitY() + { + Vector4 vector; + vector.MakeUnitY(); + + return vector; + } + + template + Vector4 Vector4::UnitZ() + { + Vector4 vector; + vector.MakeUnitZ(); + + return vector; + } + + template + Vector4 Vector4::Zero() + { + Vector4 vector; + vector.MakeZero(); + + return vector; } - else - return x < vec.x; } template -bool NzVector4::operator>(const NzVector4& vec) const -{ - return !operator<=(vec); -} - -template -bool NzVector4::operator>=(const NzVector4& vec) const -{ - return !operator<(vec); -} - -template -NzVector4 NzVector4::UnitX() -{ - NzVector4 vector; - vector.MakeUnitX(); - - return vector; -} - -template -NzVector4 NzVector4::UnitY() -{ - NzVector4 vector; - vector.MakeUnitY(); - - return vector; -} - -template -NzVector4 NzVector4::UnitZ() -{ - NzVector4 vector; - vector.MakeUnitZ(); - - return vector; -} - -template -NzVector4 NzVector4::Zero() -{ - NzVector4 vector; - vector.MakeZero(); - - return vector; -} - -template -std::ostream& operator<<(std::ostream& out, const NzVector4& vec) +std::ostream& operator<<(std::ostream& out, const Nz::Vector4& vec) { return out << vec.ToString(); } template -NzVector4 operator*(T scale, const NzVector4& vec) +Nz::Vector4 operator*(T scale, const Nz::Vector4& vec) { - return NzVector4(scale * vec.x, scale * vec.y, scale * vec.z, scale * vec.w); + return Nz::Vector4(scale * vec.x, scale * vec.y, scale * vec.z, scale * vec.w); } template -NzVector4 operator/(T scale, const NzVector4& vec) +Nz::Vector4 operator/(T scale, const Nz::Vector4& vec) { #if NAZARA_MATH_SAFE - if (NzNumberEquals(vec.x, F(0.0)) || NzNumberEquals(vec.y, F(0.0)) || NzNumberEquals(vec.z, F(0.0)) || NzNumberEquals(vec.w, F(0.0))) + if (NumberEquals(vec.x, F(0.0)) || NumberEquals(vec.y, F(0.0)) || NumberEquals(vec.z, F(0.0)) || NumberEquals(vec.w, F(0.0))) { - NzString error("Division by zero"); + Nz::String error("Division by zero"); NazaraError(error); throw std::domain_error(error); } #endif - return NzVector4(scale / vec.x, scale / vec.y, scale / vec.z, scale / vec.w); + return Nz::Vector4(scale / vec.x, scale / vec.y, scale / vec.z, scale / vec.w); } #undef F diff --git a/include/Nazara/Noise/Abstract2DNoise.hpp b/include/Nazara/Noise/Abstract2DNoise.hpp index e96dedb74..0eb5c23e5 100644 --- a/include/Nazara/Noise/Abstract2DNoise.hpp +++ b/include/Nazara/Noise/Abstract2DNoise.hpp @@ -10,14 +10,17 @@ #include #include -class NAZARA_NOISE_API NzAbstract2DNoise : public NzMappedNoiseBase +namespace Nz { - public: - virtual ~NzAbstract2DNoise(); + class NAZARA_NOISE_API Abstract2DNoise : public MappedNoiseBase + { + public: + virtual ~Abstract2DNoise(); - float GetBasicValue(float x, float y); - float GetMappedValue(float x, float y); - virtual float GetValue(float x, float y, float resolution) = 0; -}; + float GetBasicValue(float x, float y); + float GetMappedValue(float x, float y); + virtual float GetValue(float x, float y, float resolution) = 0; + }; +} #endif // NAZARA_ABSTRACT2DNOISE_HPP diff --git a/include/Nazara/Noise/Abstract3DNoise.hpp b/include/Nazara/Noise/Abstract3DNoise.hpp index 92021d6e5..19a0c765c 100644 --- a/include/Nazara/Noise/Abstract3DNoise.hpp +++ b/include/Nazara/Noise/Abstract3DNoise.hpp @@ -10,14 +10,17 @@ #include #include -class NAZARA_NOISE_API NzAbstract3DNoise : public NzMappedNoiseBase +namespace Nz { - public: - virtual ~NzAbstract3DNoise(); + class NAZARA_NOISE_API Abstract3DNoise : public MappedNoiseBase + { + public: + virtual ~Abstract3DNoise(); - float GetBasicValue(float x, float y, float z); - float GetMappedValue(float x, float y, float z); - virtual float GetValue(float x, float y, float z, float resolution) = 0; -}; + float GetBasicValue(float x, float y, float z); + float GetMappedValue(float x, float y, float z); + virtual float GetValue(float x, float y, float z, float resolution) = 0; + }; +} #endif // NAZARA_ABSTRACT3DNOISE_HPP diff --git a/include/Nazara/Noise/Abstract4DNoise.hpp b/include/Nazara/Noise/Abstract4DNoise.hpp index 12630aec5..631228020 100644 --- a/include/Nazara/Noise/Abstract4DNoise.hpp +++ b/include/Nazara/Noise/Abstract4DNoise.hpp @@ -10,14 +10,17 @@ #include #include -class NAZARA_NOISE_API NzAbstract4DNoise : public NzMappedNoiseBase +namespace Nz { - public: - virtual ~NzAbstract4DNoise(); + class NAZARA_NOISE_API Abstract4DNoise : public MappedNoiseBase + { + public: + virtual ~Abstract4DNoise(); - float GetBasicValue(float x, float y, float z, float w); - float GetMappedValue(float x, float y, float z, float w); - virtual float GetValue(float x, float y, float z, float w, float resolution) = 0; -}; + float GetBasicValue(float x, float y, float z, float w); + float GetMappedValue(float x, float y, float z, float w); + virtual float GetValue(float x, float y, float z, float w, float resolution) = 0; + }; +} #endif // NAZARA_ABSTRACT4DNOISE_HPP diff --git a/include/Nazara/Noise/ComplexNoiseBase.hpp b/include/Nazara/Noise/ComplexNoiseBase.hpp index ef77eaa2b..6be8667a5 100644 --- a/include/Nazara/Noise/ComplexNoiseBase.hpp +++ b/include/Nazara/Noise/ComplexNoiseBase.hpp @@ -10,29 +10,32 @@ #include #include -class NAZARA_NOISE_API NzComplexNoiseBase +namespace Nz { - public: - NzComplexNoiseBase(); - ~NzComplexNoiseBase() = default; + class NAZARA_NOISE_API ComplexNoiseBase + { + public: + ComplexNoiseBase(); + ~ComplexNoiseBase() = default; - float GetHurstParameter() const; - float GetLacunarity() const; - float GetOctaveNumber() const; - void SetHurstParameter(float h); - void SetLacunarity(float lacunarity); - void SetOctavesNumber(float octaves); - void RecomputeExponentArray(); + float GetHurstParameter() const; + float GetLacunarity() const; + float GetOctaveNumber() const; + void SetHurstParameter(float h); + void SetLacunarity(float lacunarity); + void SetOctavesNumber(float octaves); + void RecomputeExponentArray(); - protected: - float m_lacunarity; - float m_hurst; - float m_octaves; - std::array m_exponent_array; - float m_sum; + protected: + float m_lacunarity; + float m_hurst; + float m_octaves; + std::array m_exponent_array; + float m_sum; - private: - bool m_parametersModified; -}; + private: + bool m_parametersModified; + }; +} #endif // COMPLEXNOISEBASE_HPP diff --git a/include/Nazara/Noise/FBM2D.hpp b/include/Nazara/Noise/FBM2D.hpp index ecd65ca39..9b456de0a 100644 --- a/include/Nazara/Noise/FBM2D.hpp +++ b/include/Nazara/Noise/FBM2D.hpp @@ -11,18 +11,21 @@ #include #include -class NAZARA_NOISE_API NzFBM2D : public NzAbstract2DNoise, public NzComplexNoiseBase +namespace Nz { - public: - NzFBM2D(nzNoises source, unsigned int seed); - float GetValue(float x, float y, float resolution); - ~NzFBM2D(); + class NAZARA_NOISE_API FBM2D : public Abstract2DNoise, public ComplexNoiseBase + { + public: + FBM2D(NoiseType source, unsigned int seed); + float GetValue(float x, float y, float resolution); + ~FBM2D(); - private: - NzAbstract2DNoise* m_source; - float m_value; - float m_remainder; - nzNoises m_noiseType; -}; + private: + Abstract2DNoise* m_source; + float m_value; + float m_remainder; + NoiseType m_noiseType; + }; +} #endif // FBM2D_HPP diff --git a/include/Nazara/Noise/FBM3D.hpp b/include/Nazara/Noise/FBM3D.hpp index f85f68e26..722ad843d 100644 --- a/include/Nazara/Noise/FBM3D.hpp +++ b/include/Nazara/Noise/FBM3D.hpp @@ -11,19 +11,22 @@ #include #include -class NAZARA_NOISE_API NzFBM3D : public NzAbstract3DNoise, public NzComplexNoiseBase +namespace Nz { - public: - NzFBM3D(nzNoises source, unsigned int seed); - float GetValue(float x, float y, float z, float resolution); - ~NzFBM3D(); + class NAZARA_NOISE_API FBM3D : public Abstract3DNoise, public ComplexNoiseBase + { + public: + FBM3D(NoiseType source, unsigned int seed); + float GetValue(float x, float y, float z, float resolution); + ~FBM3D(); - private: - NzAbstract3DNoise* m_source; - float m_value; - float m_remainder; - nzNoises m_noiseType; -}; + private: + Abstract3DNoise* m_source; + float m_value; + float m_remainder; + NoiseType m_noiseType; + }; +} #endif // FBM3D_HPP diff --git a/include/Nazara/Noise/FBM4D.hpp b/include/Nazara/Noise/FBM4D.hpp index 5b781bbc0..e18c93111 100644 --- a/include/Nazara/Noise/FBM4D.hpp +++ b/include/Nazara/Noise/FBM4D.hpp @@ -11,19 +11,22 @@ #include #include -class NAZARA_NOISE_API NzFBM4D : public NzAbstract4DNoise, public NzComplexNoiseBase +namespace Nz { - public: - NzFBM4D(nzNoises source, unsigned int seed); - float GetValue(float x, float y, float z, float w, float resolution); - ~NzFBM4D(); + class NAZARA_NOISE_API FBM4D : public Abstract4DNoise, public ComplexNoiseBase + { + public: + FBM4D(NoiseType source, unsigned int seed); + float GetValue(float x, float y, float z, float w, float resolution); + ~FBM4D(); - private: - NzAbstract4DNoise* m_source; - float m_value; - float m_remainder; - nzNoises m_noiseType; -}; + private: + Abstract4DNoise* m_source; + float m_value; + float m_remainder; + NoiseType m_noiseType; + }; +} #endif // FBM4D_HPP diff --git a/include/Nazara/Noise/HybridMultiFractal3D.hpp b/include/Nazara/Noise/HybridMultiFractal3D.hpp index 0f01dd3a1..34d554292 100644 --- a/include/Nazara/Noise/HybridMultiFractal3D.hpp +++ b/include/Nazara/Noise/HybridMultiFractal3D.hpp @@ -11,22 +11,26 @@ #include #include -class NAZARA_NOISE_API NzHybridMultiFractal3D : public NzAbstract3DNoise, public NzComplexNoiseBase +namespace Nz { - public: - NzHybridMultiFractal3D(nzNoises source, unsigned int seed); - float GetValue(float x, float y, float z, float resolution); - ~NzHybridMultiFractal3D(); - protected: - private: - NzAbstract3DNoise* m_source; - float m_value; - float m_remainder; - float m_offset; - float m_weight; - float m_signal; - nzNoises m_noiseType; -}; + class NAZARA_NOISE_API HybridMultiFractal3D : public Abstract3DNoise, public ComplexNoiseBase + { + public: + HybridMultiFractal3D(NoiseType source, unsigned int seed); + ~HybridMultiFractal3D(); + + float GetValue(float x, float y, float z, float resolution); + + private: + Abstract3DNoise* m_source; + float m_value; + float m_remainder; + float m_offset; + float m_weight; + float m_signal; + NoiseType m_noiseType; + }; +} #endif // HYBRIDMULTIFRACTAL3D_HPP diff --git a/include/Nazara/Noise/HybridMultiFractal4D.hpp b/include/Nazara/Noise/HybridMultiFractal4D.hpp index e264b279b..859ed8087 100644 --- a/include/Nazara/Noise/HybridMultiFractal4D.hpp +++ b/include/Nazara/Noise/HybridMultiFractal4D.hpp @@ -11,22 +11,26 @@ #include #include -class NAZARA_NOISE_API NzHybridMultiFractal4D : public NzAbstract4DNoise, public NzComplexNoiseBase +namespace Nz { - public: - NzHybridMultiFractal4D(nzNoises source, unsigned int seed); - float GetValue(float x, float y, float z, float w, float resolution); - ~NzHybridMultiFractal4D(); - protected: - private: - NzAbstract4DNoise* m_source; - float m_value; - float m_remainder; - float m_offset; - float m_weight; - float m_signal; - nzNoises m_noiseType; -}; + class NAZARA_NOISE_API HybridMultiFractal4D : public Abstract4DNoise, public ComplexNoiseBase + { + public: + HybridMultiFractal4D(NoiseType source, unsigned int seed); + ~HybridMultiFractal4D(); + + float GetValue(float x, float y, float z, float w, float resolution); + + private: + Abstract4DNoise* m_source; + float m_value; + float m_remainder; + float m_offset; + float m_weight; + float m_signal; + NoiseType m_noiseType; + }; +} #endif // HYBRIDMULTIFRACTAL4D_HPP diff --git a/include/Nazara/Noise/HybridMultifractal2D.hpp b/include/Nazara/Noise/HybridMultifractal2D.hpp index 0619c3bb9..4b0ad9bc6 100644 --- a/include/Nazara/Noise/HybridMultifractal2D.hpp +++ b/include/Nazara/Noise/HybridMultifractal2D.hpp @@ -11,22 +11,26 @@ #include #include -class NAZARA_NOISE_API NzHybridMultiFractal2D : public NzAbstract2DNoise, public NzComplexNoiseBase +namespace Nz { - public: - NzHybridMultiFractal2D(nzNoises source, unsigned int seed); - float GetValue(float x, float y, float resolution); - ~NzHybridMultiFractal2D(); + class NAZARA_NOISE_API HybridMultiFractal2D : public Abstract2DNoise, public ComplexNoiseBase + { + public: + HybridMultiFractal2D(NoiseType source, unsigned int seed); + ~HybridMultiFractal2D(); - private: - NzAbstract2DNoise* m_source; - float m_value; - float m_remainder; - float m_offset; - float m_weight; - float m_signal; - nzNoises m_noiseType; -}; + float GetValue(float x, float y, float resolution); + + private: + Abstract2DNoise* m_source; + float m_value; + float m_remainder; + float m_offset; + float m_weight; + float m_signal; + NoiseType m_noiseType; + }; +} #endif // HYBRIDMULTIFRACTAL2D_HPP diff --git a/include/Nazara/Noise/MappedNoiseBase.hpp b/include/Nazara/Noise/MappedNoiseBase.hpp index be68873f7..7e5106a31 100644 --- a/include/Nazara/Noise/MappedNoiseBase.hpp +++ b/include/Nazara/Noise/MappedNoiseBase.hpp @@ -10,22 +10,26 @@ #include #include -class NAZARA_NOISE_API NzMappedNoiseBase : public NzNoiseBase +namespace Nz { - public: - NzMappedNoiseBase(); - ~NzMappedNoiseBase() = default; + class NAZARA_NOISE_API MappedNoiseBase : public NoiseBase + { + public: + MappedNoiseBase(); + ~MappedNoiseBase() = default; - float GetGain() const; - float GetOffset() const; - float GetResolution() const; - void SetGain(float gain); - void SetOffset(float offset); - void SetResolution(float resolution); - protected: - float m_gain; - float m_offset; - float m_resolution; -}; + float GetGain() const; + float GetOffset() const; + float GetResolution() const; + void SetGain(float gain); + void SetOffset(float offset); + void SetResolution(float resolution); + + protected: + float m_gain; + float m_offset; + float m_resolution; + }; +} #endif // NAZARA_MAPPEDNOISEBASE_HPP diff --git a/include/Nazara/Noise/Noise.hpp b/include/Nazara/Noise/Noise.hpp index c8b954464..a1e5b7d11 100644 --- a/include/Nazara/Noise/Noise.hpp +++ b/include/Nazara/Noise/Noise.hpp @@ -11,20 +11,23 @@ #include #include -class NAZARA_NOISE_API NzNoise +namespace Nz { - public: - NzNoise() = delete; - ~NzNoise() = delete; + class NAZARA_NOISE_API Noise + { + public: + Noise() = delete; + ~Noise() = delete; - static bool Initialize(); + static bool Initialize(); - static bool IsInitialized(); + static bool IsInitialized(); - static void Uninitialize(); + static void Uninitialize(); - private: - static unsigned int s_moduleReferenceCounter; -}; + private: + static unsigned int s_moduleReferenceCounter; + }; +} #endif // NAZARA_NOISE_HPP diff --git a/include/Nazara/Noise/NoiseBase.hpp b/include/Nazara/Noise/NoiseBase.hpp index d2cf9f93d..bd268ee8c 100644 --- a/include/Nazara/Noise/NoiseBase.hpp +++ b/include/Nazara/Noise/NoiseBase.hpp @@ -10,34 +10,39 @@ #include #include -enum nzNoises +namespace Nz { - PERLIN, - SIMPLEX, - CELL -}; + enum NoiseType + { + PERLIN, + SIMPLEX, + CELL + }; -class NAZARA_NOISE_API NzNoiseBase -{ - public: - NzNoiseBase(unsigned int seed = 0); - ~NzNoiseBase() = default; + class NAZARA_NOISE_API NoiseBase + { + public: + NoiseBase(unsigned int seed = 0); + ~NoiseBase() = default; - void SetNewSeed(unsigned int seed); + void SetNewSeed(unsigned int seed); - void ShufflePermutationTable(); + void ShufflePermutationTable(); - unsigned int GetUniformRandomValue(); + unsigned int GetUniformRandomValue(); - int fastfloor(float n); - int JenkinsHash(int a, int b, int c); - protected: - unsigned int perm[512]; - private: - unsigned int Ua, Uc, Um; - unsigned int UcurrentSeed; - unsigned int Uprevious, Ulast; + int fastfloor(float n); + int JenkinsHash(int a, int b, int c); -}; + protected: + unsigned int perm[512]; + + private: + unsigned int Ua, Uc, Um; + unsigned int UcurrentSeed; + unsigned int Uprevious, Ulast; + + }; +} #endif // NOISEBASE_HPP diff --git a/include/Nazara/Noise/Perlin2D.hpp b/include/Nazara/Noise/Perlin2D.hpp index 599968ac4..88a98155b 100644 --- a/include/Nazara/Noise/Perlin2D.hpp +++ b/include/Nazara/Noise/Perlin2D.hpp @@ -12,24 +12,28 @@ #include #include -class NAZARA_NOISE_API NzPerlin2D : public NzAbstract2DNoise +namespace Nz { - public: - NzPerlin2D(); - NzPerlin2D(unsigned int seed); - float GetValue(float x, float y, float resolution); - ~NzPerlin2D() = default; - protected: - private: - int x0, y0; - int gi0,gi1,gi2,gi3; - int ii, jj; - float gradient2[8][2]; - float s,t,u,v; - float Cx,Cy; - float Li1, Li2; - NzVector2 temp; -}; + class NAZARA_NOISE_API Perlin2D : public Abstract2DNoise + { + public: + Perlin2D(); + Perlin2D(unsigned int seed); + ~Perlin2D() = default; + + float GetValue(float x, float y, float resolution); + + private: + int x0, y0; + int gi0,gi1,gi2,gi3; + int ii, jj; + float gradient2[8][2]; + float s,t,u,v; + float Cx,Cy; + float Li1, Li2; + Vector2 temp; + }; +} #endif // PERLIN2D_HPP diff --git a/include/Nazara/Noise/Perlin3D.hpp b/include/Nazara/Noise/Perlin3D.hpp index f32274568..47be7f29b 100644 --- a/include/Nazara/Noise/Perlin3D.hpp +++ b/include/Nazara/Noise/Perlin3D.hpp @@ -12,25 +12,29 @@ #include #include -class NAZARA_NOISE_API NzPerlin3D : public NzAbstract3DNoise +namespace Nz { - public: - NzPerlin3D(); - NzPerlin3D(unsigned int seed); - float GetValue(float x, float y, float z, float resolution); - ~NzPerlin3D() = default; - protected: - private: - int x0,y0,z0; - int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7; - int ii,jj,kk; - float gradient3[16][3]; - float Li1,Li2,Li3,Li4,Li5,Li6; - float s[2],t[2],u[2],v[2]; - float Cx,Cy,Cz; - float nx,ny,nz; - float tmp; - NzVector3 temp; -}; + class NAZARA_NOISE_API Perlin3D : public Abstract3DNoise + { + public: + Perlin3D(); + Perlin3D(unsigned int seed); + ~Perlin3D() = default; + + float GetValue(float x, float y, float z, float resolution); + + private: + int x0,y0,z0; + int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7; + int ii,jj,kk; + float gradient3[16][3]; + float Li1,Li2,Li3,Li4,Li5,Li6; + float s[2],t[2],u[2],v[2]; + float Cx,Cy,Cz; + float nx,ny,nz; + float tmp; + Vector3 temp; + }; +} #endif // PERLIN3D_HPP diff --git a/include/Nazara/Noise/Perlin4D.hpp b/include/Nazara/Noise/Perlin4D.hpp index c317ed75d..66d7a1b7b 100644 --- a/include/Nazara/Noise/Perlin4D.hpp +++ b/include/Nazara/Noise/Perlin4D.hpp @@ -12,24 +12,28 @@ #include #include -class NAZARA_NOISE_API NzPerlin4D : public NzAbstract4DNoise +namespace Nz { - public: - NzPerlin4D(); - NzPerlin4D(unsigned int seed); - float GetValue(float x, float y, float z, float w, float resolution); - ~NzPerlin4D() = default; - protected: - private: - int x0,y0,z0,w0; - int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7,gi8,gi9,gi10,gi11,gi12,gi13,gi14,gi15; - int ii,jj,kk,ll; - float gradient4[32][4]; - float Li1,Li2,Li3,Li4,Li5,Li6,Li7,Li8,Li9,Li10,Li11,Li12,Li13,Li14; - float s[4],t[4],u[4],v[4]; - float Cx,Cy,Cz,Cw; - float tmp; - NzVector4 temp; -}; + class NAZARA_NOISE_API Perlin4D : public Abstract4DNoise + { + public: + Perlin4D(); + Perlin4D(unsigned int seed); + ~Perlin4D() = default; + + float GetValue(float x, float y, float z, float w, float resolution); + + private: + int x0,y0,z0,w0; + int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7,gi8,gi9,gi10,gi11,gi12,gi13,gi14,gi15; + int ii,jj,kk,ll; + float gradient4[32][4]; + float Li1,Li2,Li3,Li4,Li5,Li6,Li7,Li8,Li9,Li10,Li11,Li12,Li13,Li14; + float s[4],t[4],u[4],v[4]; + float Cx,Cy,Cz,Cw; + float tmp; + Vector4 temp; + }; +} #endif // PERLIN4D_HPP diff --git a/include/Nazara/Noise/Simplex2D.hpp b/include/Nazara/Noise/Simplex2D.hpp index a951086a0..69a73478d 100644 --- a/include/Nazara/Noise/Simplex2D.hpp +++ b/include/Nazara/Noise/Simplex2D.hpp @@ -12,27 +12,31 @@ #include #include -class NAZARA_NOISE_API NzSimplex2D : public NzAbstract2DNoise +namespace Nz { - public: - NzSimplex2D(); - NzSimplex2D(unsigned int seed); - float GetValue(float x, float y, float resolution); - virtual ~NzSimplex2D() = default; - protected: - private: - int ii,jj; - int gi0,gi1,gi2; - NzVector2i skewedCubeOrigin,off1; - float n1,n2,n3; - float c1,c2,c3; - float gradient2[8][2]; - float UnskewCoeff2D; - float SkewCoeff2D; - float sum; - NzVector2 unskewedCubeOrigin, unskewedDistToOrigin; - NzVector2 d1,d2,d3; -}; + class NAZARA_NOISE_API Simplex2D : public Abstract2DNoise + { + public: + Simplex2D(); + Simplex2D(unsigned int seed); + virtual ~Simplex2D() = default; + + float GetValue(float x, float y, float resolution); + + private: + int ii,jj; + int gi0,gi1,gi2; + Vector2i skewedCubeOrigin,off1; + float n1,n2,n3; + float c1,c2,c3; + float gradient2[8][2]; + float UnskewCoeff2D; + float SkewCoeff2D; + float sum; + Vector2 unskewedCubeOrigin, unskewedDistToOrigin; + Vector2 d1,d2,d3; + }; +} #endif // SIMPLEX2D_HPP diff --git a/include/Nazara/Noise/Simplex3D.hpp b/include/Nazara/Noise/Simplex3D.hpp index ecfb1f13d..ecfc4c2a4 100644 --- a/include/Nazara/Noise/Simplex3D.hpp +++ b/include/Nazara/Noise/Simplex3D.hpp @@ -12,27 +12,31 @@ #include #include -class NAZARA_NOISE_API NzSimplex3D : public NzAbstract3DNoise +namespace Nz { - public: - NzSimplex3D(); - NzSimplex3D(unsigned int seed); - float GetValue(float x, float y, float z, float resolution); - ~NzSimplex3D() = default; - protected: - private: - int ii,jj,kk; - int gi0,gi1,gi2,gi3; - NzVector3i skewedCubeOrigin,off1,off2; - float n1,n2,n3,n4; - float c1,c2,c3,c4; - float gradient3[12][3]; - float UnskewCoeff3D; - float SkewCoeff3D; - float sum; - NzVector3 unskewedCubeOrigin, unskewedDistToOrigin; - NzVector3 d1,d2,d3,d4; -}; + class NAZARA_NOISE_API Simplex3D : public Abstract3DNoise + { + public: + Simplex3D(); + Simplex3D(unsigned int seed); + ~Simplex3D() = default; + + float GetValue(float x, float y, float z, float resolution); + + private: + int ii,jj,kk; + int gi0,gi1,gi2,gi3; + Vector3i skewedCubeOrigin,off1,off2; + float n1,n2,n3,n4; + float c1,c2,c3,c4; + float gradient3[12][3]; + float UnskewCoeff3D; + float SkewCoeff3D; + float sum; + Vector3 unskewedCubeOrigin, unskewedDistToOrigin; + Vector3 d1,d2,d3,d4; + }; +} #endif // SIMPLEX3D_HPP diff --git a/include/Nazara/Noise/Simplex4D.hpp b/include/Nazara/Noise/Simplex4D.hpp index af4d2f043..545c5f290 100644 --- a/include/Nazara/Noise/Simplex4D.hpp +++ b/include/Nazara/Noise/Simplex4D.hpp @@ -12,29 +12,33 @@ #include #include -class NAZARA_NOISE_API NzSimplex4D : public NzAbstract4DNoise +namespace Nz { - public: - NzSimplex4D(); - NzSimplex4D(unsigned int seed); - float GetValue(float x, float y, float z, float w, float resolution); - ~NzSimplex4D() = default; - protected: - private: - int ii,jj,kk,ll; - int gi0,gi1,gi2,gi3,gi4; - NzVector4i skewedCubeOrigin,off1,off2,off3; - int lookupTable4D[64][4]; - int c; - float n1,n2,n3,n4,n5; - float c1,c2,c3,c4,c5,c6; - float gradient4[32][4]; - float UnskewCoeff4D; - float SkewCoeff4D; - float sum; - NzVector4 unskewedCubeOrigin, unskewedDistToOrigin; - NzVector4 d1,d2,d3,d4,d5; -}; + class NAZARA_NOISE_API Simplex4D : public Abstract4DNoise + { + public: + Simplex4D(); + Simplex4D(unsigned int seed); + ~Simplex4D() = default; + + float GetValue(float x, float y, float z, float w, float resolution); + + private: + int ii,jj,kk,ll; + int gi0,gi1,gi2,gi3,gi4; + Vector4i skewedCubeOrigin,off1,off2,off3; + int lookupTable4D[64][4]; + int c; + float n1,n2,n3,n4,n5; + float c1,c2,c3,c4,c5,c6; + float gradient4[32][4]; + float UnskewCoeff4D; + float SkewCoeff4D; + float sum; + Vector4 unskewedCubeOrigin, unskewedDistToOrigin; + Vector4 d1,d2,d3,d4,d5; + }; +} #endif // SIMPLEX4D_H diff --git a/include/Nazara/Physics/Enums.hpp b/include/Nazara/Physics/Enums.hpp index defbdae19..1951d3eda 100644 --- a/include/Nazara/Physics/Enums.hpp +++ b/include/Nazara/Physics/Enums.hpp @@ -7,21 +7,21 @@ #ifndef NAZARA_ENUMS_PHYSICS_HPP #define NAZARA_ENUMS_PHYSICS_HPP -enum nzGeomType +enum GeomType { - nzGeomType_Box, - nzGeomType_Capsule, - nzGeomType_Cone, - nzGeomType_Compound, - nzGeomType_ConvexHull, - nzGeomType_Cylinder, - nzGeomType_Heightfield, - nzGeomType_Null, - nzGeomType_Scene, - nzGeomType_Sphere, - nzGeomType_Tree, + GeomType_Box, + GeomType_Capsule, + GeomType_Cone, + GeomType_Compound, + GeomType_ConvexHull, + GeomType_Cylinder, + GeomType_Heightfield, + GeomType_Null, + GeomType_Scene, + GeomType_Sphere, + GeomType_Tree, - nzGeomType_Max = nzGeomType_Tree + GeomType_Max = GeomType_Tree }; #endif // NAZARA_ENUMS_PHYSICS_HPP diff --git a/include/Nazara/Physics/Geom.hpp b/include/Nazara/Physics/Geom.hpp index d9321b037..1a82f8445 100644 --- a/include/Nazara/Physics/Geom.hpp +++ b/include/Nazara/Physics/Geom.hpp @@ -20,243 +20,247 @@ #include #include -///TODO: CollisionModifier -///TODO: HeightfieldGeom -///TODO: PlaneGeom ? -///TODO: SceneGeom -///TODO: TreeGeom - -class NzPhysGeom; -class NzPhysWorld; struct NewtonCollision; -using NzPhysGeomConstRef = NzObjectRef; -using NzPhysGeomLibrary = NzObjectLibrary; -using NzPhysGeomRef = NzObjectRef; - -class NAZARA_PHYSICS_API NzPhysGeom : public NzRefCounted +namespace Nz { - public: - NzPhysGeom() = default; - NzPhysGeom(const NzPhysGeom&) = delete; - NzPhysGeom(NzPhysGeom&&) = delete; - virtual ~NzPhysGeom(); + ///TODO: CollisionModifier + ///TODO: HeightfieldGeom + ///TODO: PlaneGeom ? + ///TODO: SceneGeom + ///TODO: TreeGeom - NzBoxf ComputeAABB(const NzVector3f& translation, const NzQuaternionf& rotation, const NzVector3f& scale) const; - virtual NzBoxf ComputeAABB(const NzMatrix4f& offsetMatrix = NzMatrix4f::Identity(), const NzVector3f& scale = NzVector3f::Unit()) const; - virtual void ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) const; - virtual float ComputeVolume() const; + class PhysGeom; + class PhysWorld; - NewtonCollision* GetHandle(NzPhysWorld* world) const; - virtual nzGeomType GetType() const = 0; + using PhysGeomConstRef = ObjectRef; + using PhysGeomLibrary = ObjectLibrary; + using PhysGeomRef = ObjectRef; - NzPhysGeom& operator=(const NzPhysGeom&) = delete; - NzPhysGeom& operator=(NzPhysGeom&&) = delete; + class NAZARA_PHYSICS_API PhysGeom : public RefCounted + { + public: + PhysGeom() = default; + PhysGeom(const PhysGeom&) = delete; + PhysGeom(PhysGeom&&) = delete; + virtual ~PhysGeom(); - static NzPhysGeomRef Build(const NzPrimitiveList& list); + Boxf ComputeAABB(const Vector3f& translation, const Quaternionf& rotation, const Vector3f& scale) const; + virtual Boxf ComputeAABB(const Matrix4f& offsetMatrix = Matrix4f::Identity(), const Vector3f& scale = Vector3f::Unit()) const; + virtual void ComputeInertialMatrix(Vector3f* inertia, Vector3f* center) const; + virtual float ComputeVolume() const; - // Signals: - NazaraSignal(OnPhysGeomRelease, const NzPhysGeom* /*physGeom*/); + NewtonCollision* GetHandle(PhysWorld* world) const; + virtual GeomType GetType() const = 0; - protected: - virtual NewtonCollision* CreateHandle(NzPhysWorld* world) const = 0; + PhysGeom& operator=(const PhysGeom&) = delete; + PhysGeom& operator=(PhysGeom&&) = delete; - mutable std::unordered_map m_handles; + static PhysGeomRef Build(const PrimitiveList& list); - static NzPhysGeomLibrary::LibraryMap s_library; -}; + // Signals: + NazaraSignal(OnPhysGeomRelease, const PhysGeom* /*physGeom*/); -class NzBoxGeom; + protected: + virtual NewtonCollision* CreateHandle(PhysWorld* world) const = 0; -using NzBoxGeomConstRef = NzObjectRef; -using NzBoxGeomRef = NzObjectRef; + mutable std::unordered_map m_handles; -class NAZARA_PHYSICS_API NzBoxGeom : public NzPhysGeom -{ - public: - NzBoxGeom(const NzVector3f& lengths, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - NzBoxGeom(const NzVector3f& lengths, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + static PhysGeomLibrary::LibraryMap s_library; + }; - NzBoxf ComputeAABB(const NzMatrix4f& offsetMatrix = NzMatrix4f::Identity(), const NzVector3f& scale = NzVector3f::Unit()) const override; - float ComputeVolume() const override; + class BoxGeom; - NzVector3f GetLengths() const; - nzGeomType GetType() const override; + using BoxGeomConstRef = ObjectRef; + using BoxGeomRef = ObjectRef; - template static NzBoxGeomRef New(Args&&... args); + class NAZARA_PHYSICS_API BoxGeom : public PhysGeom + { + public: + BoxGeom(const Vector3f& lengths, const Matrix4f& transformMatrix = Matrix4f::Identity()); + BoxGeom(const Vector3f& lengths, const Vector3f& translation, const Quaternionf& rotation = Quaternionf::Identity()); - private: - NewtonCollision* CreateHandle(NzPhysWorld* world) const override; + Boxf ComputeAABB(const Matrix4f& offsetMatrix = Matrix4f::Identity(), const Vector3f& scale = Vector3f::Unit()) const override; + float ComputeVolume() const override; - NzMatrix4f m_matrix; - NzVector3f m_lengths; -}; + Vector3f GetLengths() const; + GeomType GetType() const override; -class NzCapsuleGeom; + template static BoxGeomRef New(Args&&... args); -using NzCapsuleGeomConstRef = NzObjectRef; -using NzCapsuleGeomRef = NzObjectRef; + private: + NewtonCollision* CreateHandle(PhysWorld* world) const override; -class NAZARA_PHYSICS_API NzCapsuleGeom : public NzPhysGeom -{ - public: - NzCapsuleGeom(float length, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - NzCapsuleGeom(float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + Matrix4f m_matrix; + Vector3f m_lengths; + }; - float GetLength() const; - float GetRadius() const; - nzGeomType GetType() const override; + class CapsuleGeom; - template static NzCapsuleGeomRef New(Args&&... args); + using CapsuleGeomConstRef = ObjectRef; + using CapsuleGeomRef = ObjectRef; - private: - NewtonCollision* CreateHandle(NzPhysWorld* world) const override; + class NAZARA_PHYSICS_API CapsuleGeom : public PhysGeom + { + public: + CapsuleGeom(float length, float radius, const Matrix4f& transformMatrix = Matrix4f::Identity()); + CapsuleGeom(float length, float radius, const Vector3f& translation, const Quaternionf& rotation = Quaternionf::Identity()); - NzMatrix4f m_matrix; - float m_length; - float m_radius; -}; + float GetLength() const; + float GetRadius() const; + GeomType GetType() const override; -class NzCompoundGeom; + template static CapsuleGeomRef New(Args&&... args); -using NzCompoundGeomConstRef = NzObjectRef; -using NzCompoundGeomRef = NzObjectRef; + private: + NewtonCollision* CreateHandle(PhysWorld* world) const override; -class NAZARA_PHYSICS_API NzCompoundGeom : public NzPhysGeom -{ - public: - NzCompoundGeom(NzPhysGeom** geoms, unsigned int geomCount); + Matrix4f m_matrix; + float m_length; + float m_radius; + }; - const std::vector& GetGeoms() const; - nzGeomType GetType() const override; + class CompoundGeom; - template static NzCompoundGeomRef New(Args&&... args); + using CompoundGeomConstRef = ObjectRef; + using CompoundGeomRef = ObjectRef; - private: - NewtonCollision* CreateHandle(NzPhysWorld* world) const override; + class NAZARA_PHYSICS_API CompoundGeom : public PhysGeom + { + public: + CompoundGeom(PhysGeom** geoms, unsigned int geomCount); - std::vector m_geoms; -}; + const std::vector& GetGeoms() const; + GeomType GetType() const override; -class NzConeGeom; + template static CompoundGeomRef New(Args&&... args); -using NzConeGeomConstRef = NzObjectRef; -using NzConeGeomRef = NzObjectRef; + private: + NewtonCollision* CreateHandle(PhysWorld* world) const override; -class NAZARA_PHYSICS_API NzConeGeom : public NzPhysGeom -{ - public: - NzConeGeom(float length, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - NzConeGeom(float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + std::vector m_geoms; + }; - float GetLength() const; - float GetRadius() const; - nzGeomType GetType() const override; + class ConeGeom; - template static NzConeGeomRef New(Args&&... args); + using ConeGeomConstRef = ObjectRef; + using ConeGeomRef = ObjectRef; - private: - NewtonCollision* CreateHandle(NzPhysWorld* world) const override; + class NAZARA_PHYSICS_API ConeGeom : public PhysGeom + { + public: + ConeGeom(float length, float radius, const Matrix4f& transformMatrix = Matrix4f::Identity()); + ConeGeom(float length, float radius, const Vector3f& translation, const Quaternionf& rotation = Quaternionf::Identity()); - NzMatrix4f m_matrix; - float m_length; - float m_radius; -}; + float GetLength() const; + float GetRadius() const; + GeomType GetType() const override; -class NzConvexHullGeom; + template static ConeGeomRef New(Args&&... args); -using NzConvexHullGeomConstRef = NzObjectRef; -using NzConvexHullGeomRef = NzObjectRef; + private: + NewtonCollision* CreateHandle(PhysWorld* world) const override; -class NAZARA_PHYSICS_API NzConvexHullGeom : public NzPhysGeom -{ - public: - NzConvexHullGeom(const void* vertices, unsigned int vertexCount, unsigned int stride = sizeof(NzVector3f), float tolerance = 0.002f, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - NzConvexHullGeom(const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + Matrix4f m_matrix; + float m_length; + float m_radius; + }; - nzGeomType GetType() const override; + class ConvexHullGeom; - template static NzConvexHullGeomRef New(Args&&... args); + using ConvexHullGeomConstRef = ObjectRef; + using ConvexHullGeomRef = ObjectRef; - private: - NewtonCollision* CreateHandle(NzPhysWorld* world) const override; + class NAZARA_PHYSICS_API ConvexHullGeom : public PhysGeom + { + public: + ConvexHullGeom(const void* vertices, unsigned int vertexCount, unsigned int stride = sizeof(Vector3f), float tolerance = 0.002f, const Matrix4f& transformMatrix = Matrix4f::Identity()); + ConvexHullGeom(const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const Vector3f& translation, const Quaternionf& rotation = Quaternionf::Identity()); - std::vector m_vertices; - NzMatrix4f m_matrix; - float m_tolerance; - unsigned int m_vertexStride; -}; + GeomType GetType() const override; -class NzCylinderGeom; + template static ConvexHullGeomRef New(Args&&... args); -using NzCylinderGeomConstRef = NzObjectRef; -using NzCylinderGeomRef = NzObjectRef; + private: + NewtonCollision* CreateHandle(PhysWorld* world) const override; -class NAZARA_PHYSICS_API NzCylinderGeom : public NzPhysGeom -{ - public: - NzCylinderGeom(float length, float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - NzCylinderGeom(float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + std::vector m_vertices; + Matrix4f m_matrix; + float m_tolerance; + unsigned int m_vertexStride; + }; - float GetLength() const; - float GetRadius() const; - nzGeomType GetType() const override; + class NzCylinderGeom; - template static NzCylinderGeomRef New(Args&&... args); + using NzCylinderGeomConstRef = ObjectRef; + using NzCylinderGeomRef = ObjectRef; - private: - NewtonCollision* CreateHandle(NzPhysWorld* world) const override; + class NAZARA_PHYSICS_API NzCylinderGeom : public PhysGeom + { + public: + NzCylinderGeom(float length, float radius, const Matrix4f& transformMatrix = Matrix4f::Identity()); + NzCylinderGeom(float length, float radius, const Vector3f& translation, const Quaternionf& rotation = Quaternionf::Identity()); - NzMatrix4f m_matrix; - float m_length; - float m_radius; -}; + float GetLength() const; + float GetRadius() const; + GeomType GetType() const override; -class NzNullGeom; + template static NzCylinderGeomRef New(Args&&... args); -using NzNullGeomConstRef = NzObjectRef; -using NzNullGeomRef = NzObjectRef; + private: + NewtonCollision* CreateHandle(PhysWorld* world) const override; -class NAZARA_PHYSICS_API NzNullGeom : public NzPhysGeom -{ - public: - NzNullGeom(); + Matrix4f m_matrix; + float m_length; + float m_radius; + }; - void ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) const; + class NullGeom; - nzGeomType GetType() const override; + using NullGeomConstRef = ObjectRef; + using NullGeomRef = ObjectRef; - template static NzNullGeomRef New(Args&&... args); + class NAZARA_PHYSICS_API NullGeom : public PhysGeom + { + public: + NullGeom(); - private: - NewtonCollision* CreateHandle(NzPhysWorld* world) const override; -}; + void ComputeInertialMatrix(Vector3f* inertia, Vector3f* center) const; -class NzSphereGeom; + GeomType GetType() const override; -using NzSphereGeomConstRef = NzObjectRef; -using NzSphereGeomRef = NzObjectRef; + template static NullGeomRef New(Args&&... args); -class NAZARA_PHYSICS_API NzSphereGeom : public NzPhysGeom -{ - public: - NzSphereGeom(float radius, const NzMatrix4f& transformMatrix = NzMatrix4f::Identity()); - NzSphereGeom(float radius, const NzVector3f& translation, const NzQuaternionf& rotation = NzQuaternionf::Identity()); + private: + NewtonCollision* CreateHandle(PhysWorld* world) const override; + }; - NzBoxf ComputeAABB(const NzMatrix4f& offsetMatrix = NzMatrix4f::Identity(), const NzVector3f& scale = NzVector3f::Unit()) const override; - float ComputeVolume() const override; + class SphereGeom; - float GetRadius() const; - nzGeomType GetType() const override; + using SphereGeomConstRef = ObjectRef; + using SphereGeomRef = ObjectRef; - template static NzSphereGeomRef New(Args&&... args); + class NAZARA_PHYSICS_API SphereGeom : public PhysGeom + { + public: + SphereGeom(float radius, const Matrix4f& transformMatrix = Matrix4f::Identity()); + SphereGeom(float radius, const Vector3f& translation, const Quaternionf& rotation = Quaternionf::Identity()); - private: - NewtonCollision* CreateHandle(NzPhysWorld* world) const override; + Boxf ComputeAABB(const Matrix4f& offsetMatrix = Matrix4f::Identity(), const Vector3f& scale = Vector3f::Unit()) const override; + float ComputeVolume() const override; - NzVector3f m_position; - float m_radius; -}; + float GetRadius() const; + GeomType GetType() const override; + + template static SphereGeomRef New(Args&&... args); + + private: + NewtonCollision* CreateHandle(PhysWorld* world) const override; + + Vector3f m_position; + float m_radius; + }; +} #include diff --git a/include/Nazara/Physics/Geom.inl b/include/Nazara/Physics/Geom.inl index 6254feea8..1489348ac 100644 --- a/include/Nazara/Physics/Geom.inl +++ b/include/Nazara/Physics/Geom.inl @@ -5,76 +5,79 @@ #include #include -template -NzBoxGeomRef NzBoxGeom::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzBoxGeom(std::forward(args)...)); - object->SetPersistent(false); + template + BoxGeomRef BoxGeom::New(Args&&... args) + { + std::unique_ptr object(new BoxGeom(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); -} + return object.release(); + } -template -NzCapsuleGeomRef NzCapsuleGeom::New(Args&&... args) -{ - std::unique_ptr object(new NzCapsuleGeom(std::forward(args)...)); - object->SetPersistent(false); + template + CapsuleGeomRef CapsuleGeom::New(Args&&... args) + { + std::unique_ptr object(new CapsuleGeom(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); -} + return object.release(); + } -template -NzCompoundGeomRef NzCompoundGeom::New(Args&&... args) -{ - std::unique_ptr object(new NzCompoundGeom(std::forward(args)...)); - object->SetPersistent(false); + template + CompoundGeomRef CompoundGeom::New(Args&&... args) + { + std::unique_ptr object(new CompoundGeom(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); -} + return object.release(); + } -template -NzConeGeomRef NzConeGeom::New(Args&&... args) -{ - std::unique_ptr object(new NzConeGeom(std::forward(args)...)); - object->SetPersistent(false); + template + ConeGeomRef ConeGeom::New(Args&&... args) + { + std::unique_ptr object(new ConeGeom(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); -} + return object.release(); + } -template -NzConvexHullGeomRef NzConvexHullGeom::New(Args&&... args) -{ - std::unique_ptr object(new NzConvexHullGeom(std::forward(args)...)); - object->SetPersistent(false); + template + ConvexHullGeomRef ConvexHullGeom::New(Args&&... args) + { + std::unique_ptr object(new ConvexHullGeom(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); -} + return object.release(); + } -template -NzCylinderGeomRef NzCylinderGeom::New(Args&&... args) -{ - std::unique_ptr object(new NzCylinderGeom(std::forward(args)...)); - object->SetPersistent(false); + template + NzCylinderGeomRef NzCylinderGeom::New(Args&&... args) + { + std::unique_ptr object(new NzCylinderGeom(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); -} + return object.release(); + } -template -NzNullGeomRef NzNullGeom::New(Args&&... args) -{ - std::unique_ptr object(new NzNullGeom(std::forward(args)...)); - object->SetPersistent(false); + template + NullGeomRef NullGeom::New(Args&&... args) + { + std::unique_ptr object(new NullGeom(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); -} + return object.release(); + } -template -NzSphereGeomRef NzSphereGeom::New(Args&&... args) -{ - std::unique_ptr object(new NzSphereGeom(std::forward(args)...)); - object->SetPersistent(false); + template + SphereGeomRef SphereGeom::New(Args&&... args) + { + std::unique_ptr object(new SphereGeom(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Physics/PhysObject.hpp b/include/Nazara/Physics/PhysObject.hpp index 154a7cbde..7df72b1d1 100644 --- a/include/Nazara/Physics/PhysObject.hpp +++ b/include/Nazara/Physics/PhysObject.hpp @@ -15,65 +15,69 @@ #include #include -class NzPhysWorld; struct NewtonBody; -class NAZARA_PHYSICS_API NzPhysObject +namespace Nz { - public: - NzPhysObject(NzPhysWorld* world, const NzMatrix4f& mat = NzMatrix4f::Identity()); - NzPhysObject(NzPhysWorld* world, NzPhysGeomRef geom, const NzMatrix4f& mat = NzMatrix4f::Identity()); - NzPhysObject(const NzPhysObject& object); - NzPhysObject(NzPhysObject&& object); - ~NzPhysObject(); + class PhysWorld; - void AddForce(const NzVector3f& force, nzCoordSys coordSys = nzCoordSys_Global); - void AddForce(const NzVector3f& force, const NzVector3f& point, nzCoordSys coordSys = nzCoordSys_Global); - void AddTorque(const NzVector3f& torque, nzCoordSys coordSys = nzCoordSys_Global); + class NAZARA_PHYSICS_API PhysObject + { + public: + PhysObject(PhysWorld* world, const Matrix4f& mat = Matrix4f::Identity()); + PhysObject(PhysWorld* world, PhysGeomRef geom, const Matrix4f& mat = Matrix4f::Identity()); + PhysObject(const PhysObject& object); + PhysObject(PhysObject&& object); + ~PhysObject(); - void EnableAutoSleep(bool autoSleep); + void AddForce(const Vector3f& force, CoordSys coordSys = CoordSys_Global); + void AddForce(const Vector3f& force, const Vector3f& point, CoordSys coordSys = CoordSys_Global); + void AddTorque(const Vector3f& torque, CoordSys coordSys = CoordSys_Global); - NzBoxf GetAABB() const; - NzVector3f GetAngularVelocity() const; - const NzPhysGeomRef& GetGeom() const; - float GetGravityFactor() const; - NewtonBody* GetHandle() const; - float GetMass() const; - NzVector3f GetMassCenter(nzCoordSys coordSys = nzCoordSys_Local) const; - const NzMatrix4f& GetMatrix() const; - NzVector3f GetPosition() const; - NzQuaternionf GetRotation() const; - NzVector3f GetVelocity() const; + void EnableAutoSleep(bool autoSleep); - bool IsAutoSleepEnabled() const; - bool IsMoveable() const; - bool IsSleeping() const; + Boxf GetAABB() const; + Vector3f GetAngularVelocity() const; + const PhysGeomRef& GetGeom() const; + float GetGravityFactor() const; + NewtonBody* GetHandle() const; + float GetMass() const; + Vector3f GetMassCenter(CoordSys coordSys = CoordSys_Local) const; + const Matrix4f& GetMatrix() const; + Vector3f GetPosition() const; + Quaternionf GetRotation() const; + Vector3f GetVelocity() const; - void SetAngularVelocity(const NzVector3f& angularVelocity); - void SetGeom(NzPhysGeomRef geom); - void SetGravityFactor(float gravityFactor); - void SetMass(float mass); - void SetMassCenter(const NzVector3f& center); - void SetPosition(const NzVector3f& position); - void SetRotation(const NzQuaternionf& rotation); - void SetVelocity(const NzVector3f& velocity); + bool IsAutoSleepEnabled() const; + bool IsMoveable() const; + bool IsSleeping() const; - NzPhysObject& operator=(const NzPhysObject& object); - NzPhysObject& operator=(NzPhysObject&& object); + void SetAngularVelocity(const Vector3f& angularVelocity); + void SetGeom(PhysGeomRef geom); + void SetGravityFactor(float gravityFactor); + void SetMass(float mass); + void SetMassCenter(const Vector3f& center); + void SetPosition(const Vector3f& position); + void SetRotation(const Quaternionf& rotation); + void SetVelocity(const Vector3f& velocity); - private: - void UpdateBody(); - static void ForceAndTorqueCallback(const NewtonBody* body, float timeStep, int threadIndex); - static void TransformCallback(const NewtonBody* body, const float* matrix, int threadIndex); + PhysObject& operator=(const PhysObject& object); + PhysObject& operator=(PhysObject&& object); - NzMatrix4f m_matrix; - NzPhysGeomRef m_geom; - NzVector3f m_forceAccumulator; - NzVector3f m_torqueAccumulator; - NewtonBody* m_body; - NzPhysWorld* m_world; - float m_gravityFactor; - float m_mass; -}; + private: + void UpdateBody(); + static void ForceAndTorqueCallback(const NewtonBody* body, float timeStep, int threadIndex); + static void TransformCallback(const NewtonBody* body, const float* matrix, int threadIndex); + + Matrix4f m_matrix; + PhysGeomRef m_geom; + Vector3f m_forceAccumulator; + Vector3f m_torqueAccumulator; + NewtonBody* m_body; + PhysWorld* m_world; + float m_gravityFactor; + float m_mass; + }; +} #endif // NAZARA_PHYSOBJECT_HPP diff --git a/include/Nazara/Physics/PhysWorld.hpp b/include/Nazara/Physics/PhysWorld.hpp index a86d95544..b6fd7eae3 100644 --- a/include/Nazara/Physics/PhysWorld.hpp +++ b/include/Nazara/Physics/PhysWorld.hpp @@ -14,32 +14,35 @@ struct NewtonWorld; -class NAZARA_PHYSICS_API NzPhysWorld +namespace Nz { - public: - NzPhysWorld(); - NzPhysWorld(const NzPhysWorld&) = delete; - NzPhysWorld(NzPhysWorld&&) = delete; ///TODO - ~NzPhysWorld(); + class NAZARA_PHYSICS_API PhysWorld + { + public: + PhysWorld(); + PhysWorld(const PhysWorld&) = delete; + PhysWorld(PhysWorld&&) = delete; ///TODO + ~PhysWorld(); - NzVector3f GetGravity() const; - NewtonWorld* GetHandle() const; - float GetStepSize() const; + Vector3f GetGravity() const; + NewtonWorld* GetHandle() const; + float GetStepSize() const; - void SetGravity(const NzVector3f& gravity); - void SetSolverModel(unsigned int model); - void SetStepSize(float stepSize); + void SetGravity(const Vector3f& gravity); + void SetSolverModel(unsigned int model); + void SetStepSize(float stepSize); - void Step(float timestep); + void Step(float timestep); - NzPhysWorld& operator=(const NzPhysWorld&) = delete; - NzPhysWorld& operator=(NzPhysWorld&&) = delete; ///TODO + PhysWorld& operator=(const PhysWorld&) = delete; + PhysWorld& operator=(PhysWorld&&) = delete; ///TODO - private: - NzVector3f m_gravity; - NewtonWorld* m_world; - float m_stepSize; - float m_timestepAccumulator; -}; + private: + Vector3f m_gravity; + NewtonWorld* m_world; + float m_stepSize; + float m_timestepAccumulator; + }; +} #endif // NAZARA_PHYSWORLD_HPP diff --git a/include/Nazara/Physics/Physics.hpp b/include/Nazara/Physics/Physics.hpp index f418a9d55..3bb6ebde3 100644 --- a/include/Nazara/Physics/Physics.hpp +++ b/include/Nazara/Physics/Physics.hpp @@ -11,22 +11,25 @@ #include #include -class NAZARA_PHYSICS_API NzPhysics +namespace Nz { - public: - NzPhysics() = delete; - ~NzPhysics() = delete; + class NAZARA_PHYSICS_API Physics + { + public: + Physics() = delete; + ~Physics() = delete; - static unsigned int GetMemoryUsed(); + static unsigned int GetMemoryUsed(); - static bool Initialize(); + static bool Initialize(); - static bool IsInitialized(); + static bool IsInitialized(); - static void Uninitialize(); + static void Uninitialize(); - private: - static unsigned int s_moduleReferenceCounter; -}; + private: + static unsigned int s_moduleReferenceCounter; + }; +} #endif // NAZARA_PHYSICS_HPP diff --git a/include/Nazara/Prerequesites.hpp b/include/Nazara/Prerequesites.hpp index 6aae89440..edc608dff 100644 --- a/include/Nazara/Prerequesites.hpp +++ b/include/Nazara/Prerequesites.hpp @@ -165,16 +165,19 @@ static_assert(sizeof(uint16_t) == 2, "uint16_t is not of the correct size"); static_assert(sizeof(uint32_t) == 4, "uint32_t is not of the correct size"); static_assert(sizeof(uint64_t) == 8, "uint64_t is not of the correct size"); -typedef int8_t nzInt8; -typedef uint8_t nzUInt8; +namespace Nz +{ + typedef int8_t Int8; + typedef uint8_t UInt8; -typedef int16_t nzInt16; -typedef uint16_t nzUInt16; + typedef int16_t Int16; + typedef uint16_t UInt16; -typedef int32_t nzInt32; -typedef uint32_t nzUInt32; + typedef int32_t Int32; + typedef uint32_t UInt32; -typedef int64_t nzInt64; -typedef uint64_t nzUInt64; + typedef int64_t Int64; + typedef uint64_t UInt64; +} #endif // NAZARA_PREREQUESITES_HPP diff --git a/include/Nazara/Renderer/Context.hpp b/include/Nazara/Renderer/Context.hpp index 1813a62aa..4bfb7b1b0 100644 --- a/include/Nazara/Renderer/Context.hpp +++ b/include/Nazara/Renderer/Context.hpp @@ -16,62 +16,65 @@ #include #include -class NzContext; - -using NzContextConstRef = NzObjectRef; -using NzContextLibrary = NzObjectLibrary; -using NzContextRef = NzObjectRef; - -class NzContextImpl; - -class NAZARA_RENDERER_API NzContext : public NzRefCounted +namespace Nz { - friend NzContextImpl; - friend NzContextLibrary; - friend class NzOpenGL; + class Context; - public: - NzContext() = default; - NzContext(const NzContext&) = delete; - NzContext(NzContext&&) = delete; - ~NzContext(); + using ContextConstRef = ObjectRef; + using ContextLibrary = ObjectLibrary; + using ContextRef = ObjectRef; - bool Create(const NzContextParameters& parameters = NzContextParameters()); + class ContextImpl; - void Destroy(); + class NAZARA_RENDERER_API Context : public RefCounted + { + friend ContextImpl; + friend ContextLibrary; + friend class OpenGL; - void EnableVerticalSync(bool enabled); + public: + Context() = default; + Context(const Context&) = delete; + Context(Context&&) = delete; + ~Context(); - const NzContextParameters& GetParameters() const; + bool Create(const ContextParameters& parameters = ContextParameters()); - bool IsActive() const; + void Destroy(); - bool SetActive(bool active) const; - void SwapBuffers(); + void EnableVerticalSync(bool enabled); - NzContext& operator=(const NzContext&) = delete; - NzContext& operator=(NzContext&&) = delete; + const ContextParameters& GetParameters() const; - static bool EnsureContext(); + bool IsActive() const; - static const NzContext* GetCurrent(); - static const NzContext* GetReference(); - static const NzContext* GetThreadContext(); + bool SetActive(bool active) const; + void SwapBuffers(); - // Signals: - NazaraSignal(OnContextDestroy, const NzContext* /*context*/); - NazaraSignal(OnContextRelease, const NzContext* /*context*/); + Context& operator=(const Context&) = delete; + Context& operator=(Context&&) = delete; - private: - static bool Initialize(); - static void Uninitialize(); + static bool EnsureContext(); - NzContextParameters m_parameters; - NzContextImpl* m_impl = nullptr; + static const Context* GetCurrent(); + static const Context* GetReference(); + static const Context* GetThreadContext(); - static std::unique_ptr s_reference; - static std::vector> s_contexts; - static NzContextLibrary::LibraryMap s_library; -}; + // Signals: + NazaraSignal(OnContextDestroy, const Context* /*context*/); + NazaraSignal(OnContextRelease, const Context* /*context*/); + + private: + static bool Initialize(); + static void Uninitialize(); + + ContextParameters m_parameters; + ContextImpl* m_impl = nullptr; + + static std::unique_ptr s_reference; + static std::vector> s_contexts; + static ContextLibrary::LibraryMap s_library; + }; +} #endif // NAZARA_CONTEXT_HPP diff --git a/include/Nazara/Renderer/ContextParameters.hpp b/include/Nazara/Renderer/ContextParameters.hpp index f4c5eea80..ddfc76ea3 100644 --- a/include/Nazara/Renderer/ContextParameters.hpp +++ b/include/Nazara/Renderer/ContextParameters.hpp @@ -12,46 +12,49 @@ #include #include -class NzContext; - -struct NAZARA_RENDERER_API NzContextParameters +namespace Nz { - NzContextParameters(const NzRenderTargetParameters& parameters = NzRenderTargetParameters()) : - antialiasingLevel(parameters.antialiasingLevel), - bitsPerPixel(NzVideoMode::GetDesktopMode().bitsPerPixel), - depthBits(parameters.depthBits), - majorVersion(defaultMajorVersion), - minorVersion(defaultMinorVersion), - stencilBits(parameters.stencilBits), - shareContext(defaultShareContext), - window(0), - compatibilityProfile(defaultCompatibilityProfile), - debugMode(defaultDebugMode), - doubleBuffered(defaultDoubleBuffered), - shared(defaultShared) + class Context; + + struct NAZARA_RENDERER_API ContextParameters { - } + ContextParameters(const RenderTargetParameters& parameters = RenderTargetParameters()) : + antialiasingLevel(parameters.antialiasingLevel), + bitsPerPixel(VideoMode::GetDesktopMode().bitsPerPixel), + depthBits(parameters.depthBits), + majorVersion(defaultMajorVersion), + minorVersion(defaultMinorVersion), + stencilBits(parameters.stencilBits), + shareContext(defaultShareContext), + window(0), + compatibilityProfile(defaultCompatibilityProfile), + debugMode(defaultDebugMode), + doubleBuffered(defaultDoubleBuffered), + shared(defaultShared) + { + } - nzUInt8 antialiasingLevel; - nzUInt8 bitsPerPixel; - nzUInt8 depthBits; - nzUInt8 majorVersion; - nzUInt8 minorVersion; - nzUInt8 stencilBits; - const NzContext* shareContext; - NzWindowHandle window; - bool compatibilityProfile; - bool debugMode; - bool doubleBuffered; - bool shared; + UInt8 antialiasingLevel; + UInt8 bitsPerPixel; + UInt8 depthBits; + UInt8 majorVersion; + UInt8 minorVersion; + UInt8 stencilBits; + const Context* shareContext; + WindowHandle window; + bool compatibilityProfile; + bool debugMode; + bool doubleBuffered; + bool shared; - static nzUInt8 defaultMajorVersion; - static nzUInt8 defaultMinorVersion; - static const NzContext* defaultShareContext; - static bool defaultCompatibilityProfile; - static bool defaultDebugMode; - static bool defaultDoubleBuffered; - static bool defaultShared; -}; + static UInt8 defaultMajorVersion; + static UInt8 defaultMinorVersion; + static const Context* defaultShareContext; + static bool defaultCompatibilityProfile; + static bool defaultDebugMode; + static bool defaultDoubleBuffered; + static bool defaultShared; + }; +} #endif // NAZARA_CONTEXTPARAMETERS_HPP diff --git a/include/Nazara/Renderer/DebugDrawer.hpp b/include/Nazara/Renderer/DebugDrawer.hpp index 788356ad1..7880a1ae4 100644 --- a/include/Nazara/Renderer/DebugDrawer.hpp +++ b/include/Nazara/Renderer/DebugDrawer.hpp @@ -16,43 +16,46 @@ #include #include -class NzSkeleton; - -class NAZARA_RENDERER_API NzDebugDrawer +namespace Nz { - public: - static void Draw(const NzBoundingVolumef& volume); - static void Draw(const NzBoxf& box); - static void Draw(const NzBoxi& box); - static void Draw(const NzBoxui& box); - static void Draw(const NzFrustumf& frustum); - static void Draw(const NzOrientedBoxf& orientedBox); - static void Draw(const NzSkeleton* skeleton); - static void Draw(const NzVector3f& position, float size = 0.1f); - static void DrawAxes(const NzVector3f& position = NzVector3f::Zero(), float size = 1.f); - static void DrawBinormals(const NzStaticMesh* subMesh); - static void DrawCone(const NzVector3f& origin, const NzQuaternionf& rotation, float angle, float length); - static void DrawLine(const NzVector3f& p1, const NzVector3f& p2); - static void DrawPoints(const NzVector3f* ptr, unsigned int pointCount); - static void DrawNormals(const NzStaticMesh* subMesh); - static void DrawTangents(const NzStaticMesh* subMesh); + class Skeleton; - static void EnableDepthBuffer(bool depthBuffer); + class NAZARA_RENDERER_API DebugDrawer + { + public: + static void Draw(const BoundingVolumef& volume); + static void Draw(const Boxf& box); + static void Draw(const Boxi& box); + static void Draw(const Boxui& box); + static void Draw(const Frustumf& frustum); + static void Draw(const OrientedBoxf& orientedBox); + static void Draw(const Skeleton* skeleton); + static void Draw(const Vector3f& position, float size = 0.1f); + static void DrawAxes(const Vector3f& position = Vector3f::Zero(), float size = 1.f); + static void DrawBinormals(const StaticMesh* subMesh); + static void DrawCone(const Vector3f& origin, const Quaternionf& rotation, float angle, float length); + static void DrawLine(const Vector3f& p1, const Vector3f& p2); + static void DrawPoints(const Vector3f* ptr, unsigned int pointCount); + static void DrawNormals(const StaticMesh* subMesh); + static void DrawTangents(const StaticMesh* subMesh); - static float GetLineWidth(); - static float GetPointSize(); - static NzColor GetPrimaryColor(); - static NzColor GetSecondaryColor(); + static void EnableDepthBuffer(bool depthBuffer); - static bool Initialize(); - static bool IsDepthBufferEnabled(); + static float GetLineWidth(); + static float GetPointSize(); + static Color GetPrimaryColor(); + static Color GetSecondaryColor(); - static void SetLineWidth(float width); - static void SetPointSize(float size); - static void SetPrimaryColor(const NzColor& color); - static void SetSecondaryColor(const NzColor& color); + static bool Initialize(); + static bool IsDepthBufferEnabled(); - static void Uninitialize(); -}; + static void SetLineWidth(float width); + static void SetPointSize(float size); + static void SetPrimaryColor(const Color& color); + static void SetSecondaryColor(const Color& color); + + static void Uninitialize(); + }; +} #endif // NAZARA_DEBUG_DRAWER_HPP diff --git a/include/Nazara/Renderer/Enums.hpp b/include/Nazara/Renderer/Enums.hpp index d20b6dd87..87995d2b0 100644 --- a/include/Nazara/Renderer/Enums.hpp +++ b/include/Nazara/Renderer/Enums.hpp @@ -7,225 +7,228 @@ #ifndef NAZARA_ENUMS_RENDERER_HPP #define NAZARA_ENUMS_RENDERER_HPP -enum nzAttachmentPoint +namespace Nz { - nzAttachmentPoint_Color, - nzAttachmentPoint_Depth, - nzAttachmentPoint_DepthStencil, - nzAttachmentPoint_Stencil, + enum AttachmentPoint + { + AttachmentPoint_Color, + AttachmentPoint_Depth, + AttachmentPoint_DepthStencil, + AttachmentPoint_Stencil, - nzAttachmentPoint_Max = nzAttachmentPoint_Stencil -}; - -enum nzBlendFunc -{ - nzBlendFunc_DestAlpha, - nzBlendFunc_DestColor, - nzBlendFunc_SrcAlpha, - nzBlendFunc_SrcColor, - nzBlendFunc_InvDestAlpha, - nzBlendFunc_InvDestColor, - nzBlendFunc_InvSrcAlpha, - nzBlendFunc_InvSrcColor, - nzBlendFunc_One, - nzBlendFunc_Zero, - - nzBlendFunc_Max = nzBlendFunc_Zero -}; - -enum nzFaceFilling -{ - nzFaceFilling_Fill, - nzFaceFilling_Line, - nzFaceFilling_Point, - - nzFaceFilling_Max = nzFaceFilling_Point -}; - -enum nzFaceSide -{ - nzFaceSide_Back, - nzFaceSide_Front, - nzFaceSide_FrontAndBack, - - nzFaceSide_Max = nzFaceSide_FrontAndBack -}; - -enum nzGpuQueryCondition -{ - nzGpuQueryCondition_Region_NoWait, - nzGpuQueryCondition_Region_Wait, - nzGpuQueryCondition_NoWait, - nzGpuQueryCondition_Wait, - - nzGpuQueryCondition_Max = nzGpuQueryCondition_Wait -}; - -enum nzGpuQueryMode -{ - nzGpuQueryMode_AnySamplesPassed, - nzGpuQueryMode_AnySamplesPassedConservative, - nzGpuQueryMode_PrimitiveGenerated, - nzGpuQueryMode_SamplesPassed, - nzGpuQueryMode_TimeElapsed, - nzGpuQueryMode_TransformFeedbackPrimitivesWritten, - - nzGpuQueryMode_Max = nzGpuQueryMode_TransformFeedbackPrimitivesWritten -}; - -enum nzMatrixType -{ - // Matrices de base - nzMatrixType_Projection, - nzMatrixType_View, - nzMatrixType_World, - - // Matrices combinées - nzMatrixType_ViewProj, - nzMatrixType_WorldView, - nzMatrixType_WorldViewProj, - - // Matrice inversées - nzMatrixType_InvProjection, - nzMatrixType_InvView, - nzMatrixType_InvViewProj, - nzMatrixType_InvWorld, - nzMatrixType_InvWorldView, - nzMatrixType_InvWorldViewProj, - - nzMatrixType_Max = nzMatrixType_InvWorldViewProj -}; - -enum nzPixelBufferType -{ - nzPixelBufferType_Pack, - nzPixelBufferType_Unpack, - - nzPixelBufferType_Max = nzPixelBufferType_Unpack -}; - -enum nzRendererCap -{ - nzRendererCap_AnisotropicFilter, - nzRendererCap_ConditionalRendering, - nzRendererCap_FP64, - nzRendererCap_HardwareBuffer, - nzRendererCap_Instancing, - nzRendererCap_MultipleRenderTargets, - nzRendererCap_OcclusionQuery, - nzRendererCap_PixelBufferObject, - nzRendererCap_RenderTexture, - nzRendererCap_Texture3D, - nzRendererCap_TextureCubemap, - nzRendererCap_TextureMulti, - nzRendererCap_TextureNPOT, - - nzRendererCap_Max = nzRendererCap_TextureNPOT -}; - -enum nzRendererBufferFlags -{ - nzRendererBuffer_Color = 0x1, - nzRendererBuffer_Depth = 0x2, - nzRendererBuffer_Stencil = 0x4, - - nzRendererBuffer_Max = nzRendererBuffer_Stencil*2-1 -}; - -enum nzRendererComparison -{ - nzRendererComparison_Always, - nzRendererComparison_Equal, - nzRendererComparison_Greater, - nzRendererComparison_GreaterOrEqual, - nzRendererComparison_Less, - nzRendererComparison_LessOrEqual, - nzRendererComparison_Never, - nzRendererComparison_NotEqual, - - nzRendererComparison_Max = nzRendererComparison_NotEqual -}; - -enum nzRendererParameter -{ - nzRendererParameter_Blend, - nzRendererParameter_ColorWrite, - nzRendererParameter_DepthBuffer, - nzRendererParameter_DepthWrite, - nzRendererParameter_FaceCulling, - nzRendererParameter_ScissorTest, - nzRendererParameter_StencilTest, - - nzRendererParameter_Max = nzRendererParameter_StencilTest -}; - -enum nzSamplerFilter -{ - nzSamplerFilter_Unknown = -1, - - nzSamplerFilter_Bilinear, - nzSamplerFilter_Nearest, - nzSamplerFilter_Trilinear, - - nzSamplerFilter_Default, - - nzSamplerFilter_Max = nzSamplerFilter_Default -}; - -enum nzSamplerWrap -{ - nzSamplerWrap_Unknown = -1, - - nzSamplerWrap_Clamp, - nzSamplerWrap_MirroredRepeat, - nzSamplerWrap_Repeat, - - nzSamplerWrap_Default, - - nzSamplerWrap_Max = nzSamplerWrap_Repeat -}; - -enum nzShaderUniform -{ - nzShaderUniform_InvProjMatrix, - nzShaderUniform_InvTargetSize, - nzShaderUniform_InvViewMatrix, - nzShaderUniform_InvViewProjMatrix, - nzShaderUniform_InvWorldMatrix, - nzShaderUniform_InvWorldViewMatrix, - nzShaderUniform_InvWorldViewProjMatrix, - nzShaderUniform_ProjMatrix, - nzShaderUniform_TargetSize, - nzShaderUniform_ViewMatrix, - nzShaderUniform_ViewProjMatrix, - nzShaderUniform_WorldMatrix, - nzShaderUniform_WorldViewMatrix, - nzShaderUniform_WorldViewProjMatrix, - - nzShaderUniform_Max = nzShaderUniform_WorldViewProjMatrix -}; - -enum nzShaderStage -{ - nzShaderStage_Fragment, - nzShaderStage_Geometry, - nzShaderStage_Vertex, - - nzShaderStage_Max = nzShaderStage_Vertex -}; - -enum nzStencilOperation -{ - nzStencilOperation_Decrement, - nzStencilOperation_DecrementNoClamp, - nzStencilOperation_Increment, - nzStencilOperation_IncrementNoClamp, - nzStencilOperation_Invert, - nzStencilOperation_Keep, - nzStencilOperation_Replace, - nzStencilOperation_Zero, - - nzStencilOperation_Max = nzStencilOperation_Zero + AttachmentPoint_Max = AttachmentPoint_Stencil + }; + + enum BlendFunc + { + BlendFunc_DestAlpha, + BlendFunc_DestColor, + BlendFunc_SrcAlpha, + BlendFunc_SrcColor, + BlendFunc_InvDestAlpha, + BlendFunc_InvDestColor, + BlendFunc_InvSrcAlpha, + BlendFunc_InvSrcColor, + BlendFunc_One, + BlendFunc_Zero, + + BlendFunc_Max = BlendFunc_Zero + }; + + enum FaceFilling + { + FaceFilling_Fill, + FaceFilling_Line, + FaceFilling_Point, + + FaceFilling_Max = FaceFilling_Point + }; + + enum FaceSide + { + FaceSide_Back, + FaceSide_Front, + FaceSide_FrontAndBack, + + FaceSide_Max = FaceSide_FrontAndBack + }; + + enum GpuQueryCondition + { + GpuQueryCondition_Region_NoWait, + GpuQueryCondition_Region_Wait, + GpuQueryCondition_NoWait, + GpuQueryCondition_Wait, + + GpuQueryCondition_Max = GpuQueryCondition_Wait + }; + + enum GpuQueryMode + { + GpuQueryMode_AnySamplesPassed, + GpuQueryMode_AnySamplesPassedConservative, + GpuQueryMode_PrimitiveGenerated, + GpuQueryMode_SamplesPassed, + GpuQueryMode_TimeElapsed, + GpuQueryMode_TransformFeedbackPrimitivesWritten, + + GpuQueryMode_Max = GpuQueryMode_TransformFeedbackPrimitivesWritten + }; + + enum MatrixType + { + // Matrices de base + MatrixType_Projection, + MatrixType_View, + MatrixType_World, + + // Matrices combinées + MatrixType_ViewProj, + MatrixType_WorldView, + MatrixType_WorldViewProj, + + // Matrice inversées + MatrixType_InvProjection, + MatrixType_InvView, + MatrixType_InvViewProj, + MatrixType_InvWorld, + MatrixType_InvWorldView, + MatrixType_InvWorldViewProj, + + MatrixType_Max = MatrixType_InvWorldViewProj + }; + + enum PixelBufferType + { + PixelBufferType_Pack, + PixelBufferType_Unpack, + + PixelBufferType_Max = PixelBufferType_Unpack + }; + + enum RendererCap + { + RendererCap_AnisotropicFilter, + RendererCap_ConditionalRendering, + RendererCap_FP64, + RendererCap_HardwareBuffer, + RendererCap_Instancing, + RendererCap_MultipleRenderTargets, + RendererCap_OcclusionQuery, + RendererCap_PixelBufferObject, + RendererCap_RenderTexture, + RendererCap_Texture3D, + RendererCap_TextureCubemap, + RendererCap_TextureMulti, + RendererCap_TextureNPOT, + + RendererCap_Max = RendererCap_TextureNPOT + }; + + enum RendererBufferFlags + { + RendererBuffer_Color = 0x1, + RendererBuffer_Depth = 0x2, + RendererBuffer_Stencil = 0x4, + + RendererBuffer_Max = RendererBuffer_Stencil*2-1 + }; + + enum RendererComparison + { + RendererComparison_Always, + RendererComparison_Equal, + RendererComparison_Greater, + RendererComparison_GreaterOrEqual, + RendererComparison_Less, + RendererComparison_LessOrEqual, + RendererComparison_Never, + RendererComparison_NotEqual, + + RendererComparison_Max = RendererComparison_NotEqual + }; + + enum RendererParameter + { + RendererParameter_Blend, + RendererParameter_ColorWrite, + RendererParameter_DepthBuffer, + RendererParameter_DepthWrite, + RendererParameter_FaceCulling, + RendererParameter_ScissorTest, + RendererParameter_StencilTest, + + RendererParameter_Max = RendererParameter_StencilTest + }; + + enum SamplerFilter + { + SamplerFilter_Unknown = -1, + + SamplerFilter_Bilinear, + SamplerFilter_Nearest, + SamplerFilter_Trilinear, + + SamplerFilter_Default, + + SamplerFilter_Max = SamplerFilter_Default + }; + + enum SamplerWrap + { + SamplerWrap_Unknown = -1, + + SamplerWrap_Clamp, + SamplerWrap_MirroredRepeat, + SamplerWrap_Repeat, + + SamplerWrap_Default, + + SamplerWrap_Max = SamplerWrap_Repeat + }; + + enum ShaderUniform + { + ShaderUniform_InvProjMatrix, + ShaderUniform_InvTargetSize, + ShaderUniform_InvViewMatrix, + ShaderUniform_InvViewProjMatrix, + ShaderUniform_InvWorldMatrix, + ShaderUniform_InvWorldViewMatrix, + ShaderUniform_InvWorldViewProjMatrix, + ShaderUniform_ProjMatrix, + ShaderUniform_TargetSize, + ShaderUniform_ViewMatrix, + ShaderUniform_ViewProjMatrix, + ShaderUniform_WorldMatrix, + ShaderUniform_WorldViewMatrix, + ShaderUniform_WorldViewProjMatrix, + + ShaderUniform_Max = ShaderUniform_WorldViewProjMatrix + }; + + enum ShaderStageType + { + ShaderStageType_Fragment, + ShaderStageType_Geometry, + ShaderStageType_Vertex, + + ShaderStageType_Max = ShaderStageType_Vertex + }; + + enum nzStencilOperation + { + nzStencilOperation_Decrement, + nzStencilOperation_DecrementNoClamp, + nzStencilOperation_Increment, + nzStencilOperation_IncrementNoClamp, + nzStencilOperation_Invert, + nzStencilOperation_Keep, + nzStencilOperation_Replace, + nzStencilOperation_Zero, + + nzStencilOperation_Max = nzStencilOperation_Zero }; +} #endif // NAZARA_ENUMS_RENDERER_HPP diff --git a/include/Nazara/Renderer/GpuQuery.hpp b/include/Nazara/Renderer/GpuQuery.hpp index 29509b241..87b758966 100644 --- a/include/Nazara/Renderer/GpuQuery.hpp +++ b/include/Nazara/Renderer/GpuQuery.hpp @@ -11,33 +11,36 @@ #include #include -class NAZARA_RENDERER_API NzGpuQuery +namespace Nz { - public: - NzGpuQuery(); - NzGpuQuery(const NzGpuQuery&) = delete; - NzGpuQuery(NzGpuQuery&&) = delete; ///TODO - ~NzGpuQuery(); + class NAZARA_RENDERER_API GpuQuery + { + public: + GpuQuery(); + GpuQuery(const GpuQuery&) = delete; + GpuQuery(GpuQuery&&) = delete; ///TODO + ~GpuQuery(); - void Begin(nzGpuQueryMode mode); - void End(); + void Begin(GpuQueryMode mode); + void End(); - unsigned int GetResult() const; + unsigned int GetResult() const; - bool IsResultAvailable() const; + bool IsResultAvailable() const; - // Fonctions OpenGL - unsigned int GetOpenGLID() const; + // Fonctions OpenGL + unsigned int GetOpenGLID() const; - NzGpuQuery& operator=(const NzGpuQuery&) = delete; - NzGpuQuery& operator=(NzGpuQuery&&) = delete; ///TODO + GpuQuery& operator=(const GpuQuery&) = delete; + GpuQuery& operator=(GpuQuery&&) = delete; ///TODO - static bool IsModeSupported(nzGpuQueryMode mode); - static bool IsSupported(); + static bool IsModeSupported(GpuQueryMode mode); + static bool IsSupported(); - private: - nzGpuQueryMode m_mode; - unsigned int m_id; -}; + private: + GpuQueryMode m_mode; + unsigned int m_id; + }; +} #endif // NAZARA_GPUQUERY_HPP diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index 199938264..00df7a08e 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -29,136 +29,139 @@ namespace GLX #include #endif -enum nzOpenGLExtension +namespace Nz { - nzOpenGLExtension_AnisotropicFilter, - nzOpenGLExtension_ConditionalRender, - nzOpenGLExtension_DebugOutput, - nzOpenGLExtension_DrawInstanced, - nzOpenGLExtension_FP64, - nzOpenGLExtension_FrameBufferObject, - nzOpenGLExtension_GetProgramBinary, - nzOpenGLExtension_InstancedArray, - nzOpenGLExtension_PixelBufferObject, - nzOpenGLExtension_SamplerObjects, - nzOpenGLExtension_SeparateShaderObjects, - nzOpenGLExtension_Shader_ImageLoadStore, - nzOpenGLExtension_TextureArray, - nzOpenGLExtension_TextureCompression_s3tc, - nzOpenGLExtension_TextureStorage, - nzOpenGLExtension_VertexArrayObjects, + enum OpenGLExtension + { + OpenGLExtension_AnisotropicFilter, + OpenGLExtension_ConditionalRender, + OpenGLExtension_DebugOutput, + OpenGLExtension_DrawInstanced, + OpenGLExtension_FP64, + OpenGLExtension_FrameBufferObject, + OpenGLExtension_GetProgramBinary, + OpenGLExtension_InstancedArray, + OpenGLExtension_PixelBufferObject, + OpenGLExtension_SamplerObjects, + OpenGLExtension_SeparateShaderObjects, + OpenGLExtension_Shader_ImageLoadStore, + OpenGLExtension_TextureArray, + OpenGLExtension_TextureCompression_s3tc, + OpenGLExtension_TextureStorage, + OpenGLExtension_VertexArrayObjects, - nzOpenGLExtension_Max = nzOpenGLExtension_VertexArrayObjects -}; + OpenGLExtension_Max = OpenGLExtension_VertexArrayObjects + }; -class NzContext; -class NzRenderTarget; + class Context; + class RenderTarget; -using NzOpenGLFunc = void (*)(); + using OpenGLFunc = void (*)(); -class NAZARA_RENDERER_API NzOpenGL -{ - friend NzContext; + class NAZARA_RENDERER_API OpenGL + { + friend Context; - public: - enum FormatType - { - FormatType_RenderBuffer, -// FormatType_MultisampleTexture, - FormatType_Texture - }; + public: + enum FormatType + { + FormatType_RenderBuffer, + // FormatType_MultisampleTexture, + FormatType_Texture + }; - struct Format - { - GLenum dataFormat; - GLenum dataType; - GLint internalFormat; - GLint swizzle[4]; - }; + struct Format + { + GLenum dataFormat; + GLenum dataType; + GLint internalFormat; + GLint swizzle[4]; + }; - NzOpenGL() = delete; - ~NzOpenGL() = delete; + OpenGL() = delete; + ~OpenGL() = delete; - static void ApplyStates(const NzRenderStates& states); + static void ApplyStates(const RenderStates& states); - static void BindBuffer(nzBufferType type, GLuint id); - static void BindProgram(GLuint id); - static void BindSampler(GLuint unit, GLuint id); - static void BindScissorBox(const NzRecti& scissorBox); - static void BindTexture(nzImageType type, GLuint id); - static void BindTexture(unsigned int textureUnit, nzImageType type, GLuint id); - static void BindTextureUnit(unsigned int textureUnit); - static void BindViewport(const NzRecti& viewport); + static void BindBuffer(BufferType type, GLuint id); + static void BindProgram(GLuint id); + static void BindSampler(GLuint unit, GLuint id); + static void BindScissorBox(const Recti& scissorBox); + static void BindTexture(ImageType type, GLuint id); + static void BindTexture(unsigned int textureUnit, ImageType type, GLuint id); + static void BindTextureUnit(unsigned int textureUnit); + static void BindViewport(const Recti& viewport); - static void DeleteBuffer(nzBufferType type, GLuint id); - static void DeleteFrameBuffer(const NzContext* context, GLuint id); - static void DeleteProgram(GLuint id); - static void DeleteSampler(GLuint id); - static void DeleteTexture(GLuint id); - static void DeleteVertexArray(const NzContext* context, GLuint id); + static void DeleteBuffer(BufferType type, GLuint id); + static void DeleteFrameBuffer(const Context* context, GLuint id); + static void DeleteProgram(GLuint id); + static void DeleteSampler(GLuint id); + static void DeleteTexture(GLuint id); + static void DeleteVertexArray(const Context* context, GLuint id); - static GLuint GetCurrentBuffer(nzBufferType type); - static GLuint GetCurrentProgram(); - static NzRecti GetCurrentScissorBox(); - static const NzRenderTarget* GetCurrentTarget(); - static GLuint GetCurrentTexture(); - static GLuint GetCurrentTexture(unsigned int textureUnit); - static unsigned int GetCurrentTextureUnit(); - static NzRecti GetCurrentViewport(); + static GLuint GetCurrentBuffer(BufferType type); + static GLuint GetCurrentProgram(); + static Recti GetCurrentScissorBox(); + static const RenderTarget* GetCurrentTarget(); + static GLuint GetCurrentTexture(); + static GLuint GetCurrentTexture(unsigned int textureUnit); + static unsigned int GetCurrentTextureUnit(); + static Recti GetCurrentViewport(); - static NzOpenGLFunc GetEntry(const NzString& entryPoint); - static unsigned int GetGLSLVersion(); - static NzString GetRendererName(); - static NzString GetVendorName(); - static unsigned int GetVersion(); + static OpenGLFunc GetEntry(const String& entryPoint); + static unsigned int GetGLSLVersion(); + static String GetRendererName(); + static String GetVendorName(); + static unsigned int GetVersion(); - static bool Initialize(); + static bool Initialize(); - static bool IsInitialized(); - static bool IsSupported(nzOpenGLExtension extension); - static bool IsSupported(const NzString& string); + static bool IsInitialized(); + static bool IsSupported(OpenGLExtension extension); + static bool IsSupported(const String& string); - static void SetBuffer(nzBufferType type, GLuint id); - static void SetProgram(GLuint id); - static void SetScissorBox(const NzRecti& scissorBox); - static void SetTarget(const NzRenderTarget* renderTarget); - static void SetTexture(GLuint id); - static void SetTexture(unsigned int textureUnit, GLuint id); - static void SetTextureUnit(unsigned int textureUnit); - static void SetViewport(const NzRecti& viewport); + static void SetBuffer(BufferType type, GLuint id); + static void SetProgram(GLuint id); + static void SetScissorBox(const Recti& scissorBox); + static void SetTarget(const RenderTarget* renderTarget); + static void SetTexture(GLuint id); + static void SetTexture(unsigned int textureUnit, GLuint id); + static void SetTextureUnit(unsigned int textureUnit); + static void SetViewport(const Recti& viewport); - static bool TranslateFormat(nzPixelFormat pixelFormat, Format* format, FormatType target); + static bool TranslateFormat(PixelFormatType pixelFormat, Format* format, FormatType target); - static void Uninitialize(); + static void Uninitialize(); - static GLenum Attachment[nzAttachmentPoint_Max+1]; - static GLenum BlendFunc[nzBlendFunc_Max+1]; - static GLenum BufferLock[nzBufferAccess_Max+1]; - static GLenum BufferLockRange[nzBufferAccess_Max+1]; - static GLenum BufferTarget[nzBufferType_Max+1]; - static GLenum BufferTargetBinding[nzBufferType_Max+1]; - static GLenum BufferUsage[nzBufferUsage_Max+1]; - static GLenum ComponentType[nzComponentType_Max+1]; - static GLenum CubemapFace[6]; // Un cube possède six faces et ça n'est pas près de changer - static GLenum FaceFilling[nzFaceFilling_Max+1]; - static GLenum FaceSide[nzFaceSide_Max+1]; - static GLenum PrimitiveMode[nzPrimitiveMode_Max+1]; - static GLenum QueryCondition[nzGpuQueryCondition_Max+1]; - static GLenum QueryMode[nzGpuQueryMode_Max+1]; - static GLenum RendererComparison[nzRendererComparison_Max+1]; - static GLenum RendererParameter[nzRendererParameter_Max+1]; - static GLenum SamplerWrapMode[nzSamplerWrap_Max+1]; - static GLenum ShaderStage[nzShaderStage_Max+1]; - static GLenum StencilOperation[nzStencilOperation_Max+1]; - static GLenum TextureTarget[nzImageType_Max+1]; - static GLenum TextureTargetBinding[nzImageType_Max+1]; - static GLenum TextureTargetProxy[nzImageType_Max+1]; - static nzUInt8 VertexComponentIndex[nzVertexComponent_Max+1]; + static GLenum Attachment[AttachmentPoint_Max+1]; + static GLenum BlendFunc[BlendFunc_Max+1]; + static GLenum BufferLock[BufferAccess_Max+1]; + static GLenum BufferLockRange[BufferAccess_Max+1]; + static GLenum BufferTarget[BufferType_Max+1]; + static GLenum BufferTargetBinding[BufferType_Max+1]; + static GLenum BufferUsage[BufferUsage_Max+1]; + static GLenum ComponentType[ComponentType_Max+1]; + static GLenum CubemapFace[6]; // Un cube possède six faces et ça n'est pas près de changer + static GLenum FaceFilling[FaceFilling_Max+1]; + static GLenum FaceSide[FaceSide_Max+1]; + static GLenum PrimitiveMode[PrimitiveMode_Max+1]; + static GLenum QueryCondition[GpuQueryCondition_Max+1]; + static GLenum QueryMode[GpuQueryMode_Max+1]; + static GLenum RendererComparison[RendererComparison_Max+1]; + static GLenum RendererParameter[RendererParameter_Max+1]; + static GLenum SamplerWrapMode[SamplerWrap_Max+1]; + static GLenum ShaderStage[ShaderStageType_Max+1]; + static GLenum StencilOperation[nzStencilOperation_Max+1]; + static GLenum TextureTarget[ImageType_Max+1]; + static GLenum TextureTargetBinding[ImageType_Max+1]; + static GLenum TextureTargetProxy[ImageType_Max+1]; + static UInt8 VertexComponentIndex[VertexComponent_Max+1]; - private: - static void OnContextChanged(const NzContext* newContext); - static void OnContextDestruction(const NzContext* context); -}; + private: + static void OnContextChanged(const Context* newContext); + static void OnContextDestruction(const Context* context); + }; +} NAZARA_RENDERER_API extern PFNGLACTIVETEXTUREPROC glActiveTexture; NAZARA_RENDERER_API extern PFNGLATTACHSHADERPROC glAttachShader; diff --git a/include/Nazara/Renderer/RenderBuffer.hpp b/include/Nazara/Renderer/RenderBuffer.hpp index 8176db842..d6f33a52c 100644 --- a/include/Nazara/Renderer/RenderBuffer.hpp +++ b/include/Nazara/Renderer/RenderBuffer.hpp @@ -15,56 +15,59 @@ #include #include -class NzRenderBuffer; - -using NzRenderBufferConstRef = NzObjectRef; -using NzRenderBufferLibrary = NzObjectLibrary; -using NzRenderBufferRef = NzObjectRef; - -class NAZARA_RENDERER_API NzRenderBuffer : public NzRefCounted +namespace Nz { - friend NzRenderBufferLibrary; - friend class NzRenderer; + class RenderBuffer; - public: - NzRenderBuffer(); - NzRenderBuffer(const NzRenderBuffer&) = delete; - NzRenderBuffer(NzRenderBuffer&&) = delete; - ~NzRenderBuffer(); + using RenderBufferConstRef = ObjectRef; + using RenderBufferLibrary = ObjectLibrary; + using RenderBufferRef = ObjectRef; - bool Create(nzPixelFormat format, unsigned int width, unsigned int height); - void Destroy(); + class NAZARA_RENDERER_API RenderBuffer : public RefCounted + { + friend RenderBufferLibrary; + friend class Renderer; - unsigned int GetHeight() const; - nzPixelFormat GetFormat() const; - unsigned int GetWidth() const; + public: + RenderBuffer(); + RenderBuffer(const RenderBuffer&) = delete; + RenderBuffer(RenderBuffer&&) = delete; + ~RenderBuffer(); - // Fonctions OpenGL - unsigned int GetOpenGLID() const; + bool Create(PixelFormatType format, unsigned int width, unsigned int height); + void Destroy(); - bool IsValid() const; + unsigned int GetHeight() const; + PixelFormatType GetFormat() const; + unsigned int GetWidth() const; - NzRenderBuffer& operator=(const NzRenderBuffer&) = delete; - NzRenderBuffer& operator=(NzRenderBuffer&&) = delete; + // Fonctions OpenGL + unsigned int GetOpenGLID() const; - static bool IsSupported(); - template static NzRenderBufferRef New(Args&&... args); + bool IsValid() const; - // Signals: - NazaraSignal(OnRenderBufferDestroy, const NzRenderBuffer* /*renderBuffer*/); - NazaraSignal(OnRenderBufferRelease, const NzRenderBuffer* /*renderBuffer*/); + RenderBuffer& operator=(const RenderBuffer&) = delete; + RenderBuffer& operator=(RenderBuffer&&) = delete; - private: - static bool Initialize(); - static void Uninitialize(); + static bool IsSupported(); + template static RenderBufferRef New(Args&&... args); - nzPixelFormat m_pixelFormat; - unsigned int m_height; - unsigned int m_id; - unsigned int m_width; + // Signals: + NazaraSignal(OnRenderBufferDestroy, const RenderBuffer* /*renderBuffer*/); + NazaraSignal(OnRenderBufferRelease, const RenderBuffer* /*renderBuffer*/); - static NzRenderBufferLibrary::LibraryMap s_library; -}; + private: + static bool Initialize(); + static void Uninitialize(); + + PixelFormatType m_pixelFormat; + unsigned int m_height; + unsigned int m_id; + unsigned int m_width; + + static RenderBufferLibrary::LibraryMap s_library; + }; +} #include diff --git a/include/Nazara/Renderer/RenderBuffer.inl b/include/Nazara/Renderer/RenderBuffer.inl index bf79eb6e9..bd81e7a17 100644 --- a/include/Nazara/Renderer/RenderBuffer.inl +++ b/include/Nazara/Renderer/RenderBuffer.inl @@ -5,13 +5,16 @@ #include #include -template -NzRenderBufferRef NzRenderBuffer::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzRenderBuffer(std::forward(args)...)); - object->SetPersistent(false); + template + RenderBufferRef RenderBuffer::New(Args&&... args) + { + std::unique_ptr object(new RenderBuffer(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Renderer/RenderStates.hpp b/include/Nazara/Renderer/RenderStates.hpp index 15d796afb..17c6af1c6 100644 --- a/include/Nazara/Renderer/RenderStates.hpp +++ b/include/Nazara/Renderer/RenderStates.hpp @@ -9,35 +9,38 @@ #include -struct NzRenderStates +namespace Nz { - NzRenderStates(); - NzRenderStates(const NzRenderStates& states); - ~NzRenderStates() = default; - - NzRenderStates& operator=(const NzRenderStates& states); - - struct Face + struct RenderStates { - nzRendererComparison stencilCompare; - nzStencilOperation stencilFail; - nzStencilOperation stencilPass; - nzStencilOperation stencilZFail; - nzUInt32 stencilMask; - unsigned int stencilReference; - }; + RenderStates(); + RenderStates(const RenderStates& states); + ~RenderStates() = default; - Face backFace; - Face frontFace; - nzBlendFunc dstBlend; - nzBlendFunc srcBlend; - nzFaceFilling faceFilling; - nzFaceSide faceCulling; - nzRendererComparison depthFunc; - bool parameters[nzRendererParameter_Max+1]; - float lineWidth; - float pointSize; -}; + RenderStates& operator=(const RenderStates& states); + + struct Face + { + RendererComparison stencilCompare; + nzStencilOperation stencilFail; + nzStencilOperation stencilPass; + nzStencilOperation stencilZFail; + UInt32 stencilMask; + unsigned int stencilReference; + }; + + Face backFace; + Face frontFace; + BlendFunc dstBlend; + BlendFunc srcBlend; + FaceFilling faceFilling; + FaceSide faceCulling; + RendererComparison depthFunc; + bool parameters[RendererParameter_Max+1]; + float lineWidth; + float pointSize; + }; +} #include diff --git a/include/Nazara/Renderer/RenderStates.inl b/include/Nazara/Renderer/RenderStates.inl index 8a7f188da..498cdee56 100644 --- a/include/Nazara/Renderer/RenderStates.inl +++ b/include/Nazara/Renderer/RenderStates.inl @@ -5,46 +5,49 @@ #include #include -inline NzRenderStates::NzRenderStates() : -dstBlend(nzBlendFunc_Zero), -srcBlend(nzBlendFunc_One), -faceFilling(nzFaceFilling_Fill), -faceCulling(nzFaceSide_Back), -depthFunc(nzRendererComparison_Less), -lineWidth(1.f), -pointSize(1.f) +namespace Nz { - parameters[nzRendererParameter_Blend] = false; - parameters[nzRendererParameter_ColorWrite] = true; - parameters[nzRendererParameter_DepthBuffer] = false; - parameters[nzRendererParameter_DepthWrite] = true; - parameters[nzRendererParameter_FaceCulling] = false; - parameters[nzRendererParameter_ScissorTest] = false; - parameters[nzRendererParameter_StencilTest] = false; - - for (unsigned int i = 0; i < 2; ++i) + inline RenderStates::RenderStates() : + dstBlend(BlendFunc_Zero), + srcBlend(BlendFunc_One), + faceFilling(FaceFilling_Fill), + faceCulling(FaceSide_Back), + depthFunc(RendererComparison_Less), + lineWidth(1.f), + pointSize(1.f) { - Face& face = (i == 0) ? backFace : frontFace; + parameters[RendererParameter_Blend] = false; + parameters[RendererParameter_ColorWrite] = true; + parameters[RendererParameter_DepthBuffer] = false; + parameters[RendererParameter_DepthWrite] = true; + parameters[RendererParameter_FaceCulling] = false; + parameters[RendererParameter_ScissorTest] = false; + parameters[RendererParameter_StencilTest] = false; - face.stencilCompare = nzRendererComparison_Always; - face.stencilFail = nzStencilOperation_Keep; - face.stencilMask = 0xFFFFFFFF; - face.stencilPass = nzStencilOperation_Keep; - face.stencilReference = 0; - face.stencilZFail = nzStencilOperation_Keep; + for (unsigned int i = 0; i < 2; ++i) + { + Face& face = (i == 0) ? backFace : frontFace; + + face.stencilCompare = RendererComparison_Always; + face.stencilFail = nzStencilOperation_Keep; + face.stencilMask = 0xFFFFFFFF; + face.stencilPass = nzStencilOperation_Keep; + face.stencilReference = 0; + face.stencilZFail = nzStencilOperation_Keep; + } + } + + inline RenderStates::RenderStates(const RenderStates& states) + { + std::memcpy(this, &states, sizeof(RenderStates)); + } + + inline RenderStates& RenderStates::operator=(const RenderStates& states) + { + std::memcpy(this, &states, sizeof(RenderStates)); + + return *this; } } -inline NzRenderStates::NzRenderStates(const NzRenderStates& states) -{ - std::memcpy(this, &states, sizeof(NzRenderStates)); -} - -inline NzRenderStates& NzRenderStates::operator=(const NzRenderStates& states) -{ - std::memcpy(this, &states, sizeof(NzRenderStates)); - - return *this; -} - #include diff --git a/include/Nazara/Renderer/RenderTarget.hpp b/include/Nazara/Renderer/RenderTarget.hpp index 25392bd9a..d018cb952 100644 --- a/include/Nazara/Renderer/RenderTarget.hpp +++ b/include/Nazara/Renderer/RenderTarget.hpp @@ -13,42 +13,45 @@ #include #include -class NzRenderer; - -class NAZARA_RENDERER_API NzRenderTarget +namespace Nz { - friend class NzRenderer; + class Renderer; - public: - NzRenderTarget() = default; - NzRenderTarget(const NzRenderTarget&) = delete; - NzRenderTarget(NzRenderTarget&&) = delete; ///TOOD? - virtual ~NzRenderTarget(); + class NAZARA_RENDERER_API RenderTarget + { + friend class Renderer; - virtual unsigned int GetHeight() const = 0; - virtual NzRenderTargetParameters GetParameters() const = 0; - virtual unsigned int GetWidth() const = 0; + public: + RenderTarget() = default; + RenderTarget(const RenderTarget&) = delete; + RenderTarget(RenderTarget&&) = delete; ///TOOD? + virtual ~RenderTarget(); - bool IsActive() const; - virtual bool IsRenderable() const = 0; + virtual unsigned int GetHeight() const = 0; + virtual RenderTargetParameters GetParameters() const = 0; + virtual unsigned int GetWidth() const = 0; - bool SetActive(bool active); + bool IsActive() const; + virtual bool IsRenderable() const = 0; - // Fonctions OpenGL - virtual bool HasContext() const = 0; + bool SetActive(bool active); - NzRenderTarget& operator=(const NzRenderTarget&) = delete; - NzRenderTarget& operator=(NzRenderTarget&&) = delete; ///TOOD? + // Fonctions OpenGL + virtual bool HasContext() const = 0; - // Signals: - NazaraSignal(OnRenderTargetParametersChange, const NzRenderTarget* /*renderTarget*/); - NazaraSignal(OnRenderTargetRelease, const NzRenderTarget* /*renderTarget*/); - NazaraSignal(OnRenderTargetSizeChange, const NzRenderTarget* /*renderTarget*/); + RenderTarget& operator=(const RenderTarget&) = delete; + RenderTarget& operator=(RenderTarget&&) = delete; ///TOOD? - protected: - virtual bool Activate() const = 0; - virtual void Desactivate() const; - virtual void EnsureTargetUpdated() const = 0; -}; + // Signals: + NazaraSignal(OnRenderTargetParametersChange, const RenderTarget* /*renderTarget*/); + NazaraSignal(OnRenderTargetRelease, const RenderTarget* /*renderTarget*/); + NazaraSignal(OnRenderTargetSizeChange, const RenderTarget* /*renderTarget*/); + + protected: + virtual bool Activate() const = 0; + virtual void Desactivate() const; + virtual void EnsureTargetUpdated() const = 0; + }; +} #endif // NAZARA_RENDERTARGET_HPP diff --git a/include/Nazara/Renderer/RenderTargetParameters.hpp b/include/Nazara/Renderer/RenderTargetParameters.hpp index cd8a4ab0a..990848c53 100644 --- a/include/Nazara/Renderer/RenderTargetParameters.hpp +++ b/include/Nazara/Renderer/RenderTargetParameters.hpp @@ -9,18 +9,21 @@ #include -struct NzRenderTargetParameters +namespace Nz { - NzRenderTargetParameters(nzUInt8 antialiasing = 0, nzUInt8 depth = 24, nzUInt8 stencil = 0) : - antialiasingLevel(antialiasing), - depthBits(depth), - stencilBits(stencil) + struct RenderTargetParameters { - } + RenderTargetParameters(UInt8 antialiasing = 0, UInt8 depth = 24, UInt8 stencil = 0) : + antialiasingLevel(antialiasing), + depthBits(depth), + stencilBits(stencil) + { + } - nzUInt8 antialiasingLevel; - nzUInt8 depthBits; - nzUInt8 stencilBits; -}; + UInt8 antialiasingLevel; + UInt8 depthBits; + UInt8 stencilBits; + }; +} #endif // NAZARA_RENDERTARGETPARAMETERS_HPP diff --git a/include/Nazara/Renderer/RenderTexture.hpp b/include/Nazara/Renderer/RenderTexture.hpp index 087061b75..8db854360 100644 --- a/include/Nazara/Renderer/RenderTexture.hpp +++ b/include/Nazara/Renderer/RenderTexture.hpp @@ -16,79 +16,82 @@ ///TODO: Faire fonctionner les RenderTexture indépendamment du contexte (un FBO par instance et par contexte l'utilisant) -class NzContext; -class NzRenderBuffer; -class NzTexture; - -struct NzRenderTextureImpl; - -class NAZARA_RENDERER_API NzRenderTexture : public NzRenderTarget +namespace Nz { - public: - inline NzRenderTexture(); - NzRenderTexture(const NzRenderTexture&) = delete; - NzRenderTexture(NzRenderTexture&&) = delete; ///TODO? - inline ~NzRenderTexture(); + class Context; + class RenderBuffer; + class Texture; - bool AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzRenderBuffer* buffer); - bool AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, nzPixelFormat format, unsigned int width, unsigned int height); - bool AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzTexture* texture, unsigned int z = 0); + struct RenderTextureImpl; - bool Create(bool lock = false); - void Destroy(); + class NAZARA_RENDERER_API RenderTexture : public RenderTarget + { + public: + inline RenderTexture(); + RenderTexture(const RenderTexture&) = delete; + RenderTexture(RenderTexture&&) = delete; ///TODO? + inline ~RenderTexture(); - void Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index); + bool AttachBuffer(AttachmentPoint attachmentPoint, UInt8 index, RenderBuffer* buffer); + bool AttachBuffer(AttachmentPoint attachmentPoint, UInt8 index, PixelFormatType format, unsigned int width, unsigned int height); + bool AttachTexture(AttachmentPoint attachmentPoint, UInt8 index, Texture* texture, unsigned int z = 0); - unsigned int GetHeight() const override; - NzRenderTargetParameters GetParameters() const; - NzVector2ui GetSize() const; - unsigned int GetWidth() const override; + bool Create(bool lock = false); + void Destroy(); - bool IsComplete() const; - bool IsRenderable() const; - inline bool IsValid() const; + void Detach(AttachmentPoint attachmentPoint, UInt8 index); - bool Lock() const; + unsigned int GetHeight() const override; + RenderTargetParameters GetParameters() const; + Vector2ui GetSize() const; + unsigned int GetWidth() const override; - inline void SetColorTarget(nzUInt8 target) const; - void SetColorTargets(const nzUInt8* targets, unsigned int targetCount) const; - void SetColorTargets(const std::initializer_list& targets) const; + bool IsComplete() const; + bool IsRenderable() const; + inline bool IsValid() const; - void Unlock() const; + bool Lock() const; - // Fonctions OpenGL - unsigned int GetOpenGLID() const; - bool HasContext() const override; + inline void SetColorTarget(UInt8 target) const; + void SetColorTargets(const UInt8* targets, unsigned int targetCount) const; + void SetColorTargets(const std::initializer_list& targets) const; - NzRenderTexture& operator=(const NzRenderTexture&) = delete; - NzRenderTexture& operator=(NzRenderTexture&&) = delete; ///TODO? + void Unlock() const; - static inline void Blit(NzRenderTexture* src, NzRenderTexture* dst, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); - static void Blit(NzRenderTexture* src, NzRectui srcRect, NzRenderTexture* dst, NzRectui dstRect, nzUInt32 buffers = nzRendererBuffer_Color | nzRendererBuffer_Depth | nzRendererBuffer_Stencil, bool bilinearFilter = false); - static bool IsSupported(); + // Fonctions OpenGL + unsigned int GetOpenGLID() const; + bool HasContext() const override; - protected: - bool Activate() const override; - void Desactivate() const override; - void EnsureTargetUpdated() const override; + RenderTexture& operator=(const RenderTexture&) = delete; + RenderTexture& operator=(RenderTexture&&) = delete; ///TODO? - private: - inline void InvalidateDrawBuffers() const; - inline void InvalidateSize() const; - inline void InvalidateTargets() const; - void OnContextDestroy(const NzContext* context); - void OnRenderBufferDestroy(const NzRenderBuffer* renderBuffer, unsigned int attachmentIndex); - void OnTextureDestroy(const NzTexture* texture, unsigned int attachmentIndex); - void UpdateDrawBuffers() const; - void UpdateSize() const; - void UpdateTargets() const; + static inline void Blit(RenderTexture* src, RenderTexture* dst, UInt32 buffers = RendererBuffer_Color | RendererBuffer_Depth | RendererBuffer_Stencil, bool bilinearFilter = false); + static void Blit(RenderTexture* src, Rectui srcRect, RenderTexture* dst, Rectui dstRect, UInt32 buffers = RendererBuffer_Color | RendererBuffer_Depth | RendererBuffer_Stencil, bool bilinearFilter = false); + static bool IsSupported(); - NzRenderTextureImpl* m_impl; - mutable bool m_checked ; - mutable bool m_drawBuffersUpdated; - mutable bool m_sizeUpdated; - mutable bool m_targetsUpdated; -}; + protected: + bool Activate() const override; + void Desactivate() const override; + void EnsureTargetUpdated() const override; + + private: + inline void InvalidateDrawBuffers() const; + inline void InvalidateSize() const; + inline void InvalidateTargets() const; + void OnContextDestroy(const Context* context); + void OnRenderBufferDestroy(const RenderBuffer* renderBuffer, unsigned int attachmentIndex); + void OnTextureDestroy(const Texture* texture, unsigned int attachmentIndex); + void UpdateDrawBuffers() const; + void UpdateSize() const; + void UpdateTargets() const; + + RenderTextureImpl* m_impl; + mutable bool m_checked ; + mutable bool m_drawBuffersUpdated; + mutable bool m_sizeUpdated; + mutable bool m_targetsUpdated; + }; +} #include diff --git a/include/Nazara/Renderer/RenderTexture.inl b/include/Nazara/Renderer/RenderTexture.inl index d104eab39..7b8c32c68 100644 --- a/include/Nazara/Renderer/RenderTexture.inl +++ b/include/Nazara/Renderer/RenderTexture.inl @@ -6,48 +6,51 @@ #include #include -inline NzRenderTexture::NzRenderTexture() : -m_impl(nullptr) +namespace Nz { -} + inline RenderTexture::RenderTexture() : + m_impl(nullptr) + { + } -inline NzRenderTexture::~NzRenderTexture() -{ - Destroy(); -} + inline RenderTexture::~RenderTexture() + { + Destroy(); + } -inline bool NzRenderTexture::IsValid() const -{ - return m_impl != nullptr; -} + inline bool RenderTexture::IsValid() const + { + return m_impl != nullptr; + } -inline void NzRenderTexture::SetColorTarget(nzUInt8 target) const -{ - SetColorTargets(&target, 1); -} + inline void RenderTexture::SetColorTarget(UInt8 target) const + { + SetColorTargets(&target, 1); + } -inline void NzRenderTexture::Blit(NzRenderTexture* src, NzRenderTexture* dst, nzUInt32 buffers, bool bilinearFilter) -{ - Blit(src, src->GetSize(), dst, dst->GetSize(), buffers, bilinearFilter); -} + inline void RenderTexture::Blit(RenderTexture* src, RenderTexture* dst, UInt32 buffers, bool bilinearFilter) + { + Blit(src, src->GetSize(), dst, dst->GetSize(), buffers, bilinearFilter); + } -inline void NzRenderTexture::InvalidateDrawBuffers() const -{ - m_drawBuffersUpdated = false; -} + inline void RenderTexture::InvalidateDrawBuffers() const + { + m_drawBuffersUpdated = false; + } -inline void NzRenderTexture::InvalidateSize() const -{ - m_sizeUpdated = false; + inline void RenderTexture::InvalidateSize() const + { + m_sizeUpdated = false; - OnRenderTargetSizeChange(this); -} + OnRenderTargetSizeChange(this); + } -inline void NzRenderTexture::InvalidateTargets() const -{ - m_checked = false; - m_drawBuffersUpdated = false; - m_targetsUpdated = false; + inline void RenderTexture::InvalidateTargets() const + { + m_checked = false; + m_drawBuffersUpdated = false; + m_targetsUpdated = false; + } } #include diff --git a/include/Nazara/Renderer/RenderWindow.hpp b/include/Nazara/Renderer/RenderWindow.hpp index e6db97e34..0e283151b 100644 --- a/include/Nazara/Renderer/RenderWindow.hpp +++ b/include/Nazara/Renderer/RenderWindow.hpp @@ -19,61 +19,64 @@ #include #include -class NzAbstractImage; -class NzContext; -class NzTexture; -struct NzContextParameters; - -class NAZARA_RENDERER_API NzRenderWindow : public NzRenderTarget, public NzWindow +namespace Nz { - public: - NzRenderWindow() = default; - NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default, const NzContextParameters& parameters = NzContextParameters()); - NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters = NzContextParameters()); - NzRenderWindow(const NzRenderWindow&) = delete; - NzRenderWindow(NzRenderWindow&&) = delete; ///TODO - virtual ~NzRenderWindow(); + class AbstractImage; + class Context; + class Texture; + struct ContextParameters; - bool CopyToImage(NzAbstractImage* image, const NzVector3ui& dstPos = NzVector3ui(0U)) const; - bool CopyToImage(NzAbstractImage* image, const NzRectui& rect, const NzVector3ui& dstPos = NzVector3ui(0U)) const; + class NAZARA_RENDERER_API RenderWindow : public RenderTarget, public Window + { + public: + RenderWindow() = default; + RenderWindow(VideoMode mode, const String& title, UInt32 style = WindowStyle_Default, const ContextParameters& parameters = ContextParameters()); + RenderWindow(WindowHandle handle, const ContextParameters& parameters = ContextParameters()); + RenderWindow(const RenderWindow&) = delete; + RenderWindow(RenderWindow&&) = delete; ///TODO + virtual ~RenderWindow(); - bool Create(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default, const NzContextParameters& parameters = NzContextParameters()); - bool Create(NzWindowHandle handle, const NzContextParameters& parameters = NzContextParameters()); + bool CopyToImage(AbstractImage* image, const Vector3ui& dstPos = Vector3ui(0U)) const; + bool CopyToImage(AbstractImage* image, const Rectui& rect, const Vector3ui& dstPos = Vector3ui(0U)) const; - void Display(); + bool Create(VideoMode mode, const String& title, UInt32 style = WindowStyle_Default, const ContextParameters& parameters = ContextParameters()); + bool Create(WindowHandle handle, const ContextParameters& parameters = ContextParameters()); - void EnableVerticalSync(bool enabled); + void Display(); - unsigned int GetHeight() const; - NzRenderTargetParameters GetParameters() const; - unsigned int GetWidth() const; + void EnableVerticalSync(bool enabled); - bool IsRenderable() const; - bool IsValid() const; + unsigned int GetHeight() const; + RenderTargetParameters GetParameters() const; + unsigned int GetWidth() const; - void SetFramerateLimit(unsigned int limit); + bool IsRenderable() const; + bool IsValid() const; - // Fonctions OpenGL - NzContextParameters GetContextParameters() const; - bool HasContext() const override; + void SetFramerateLimit(unsigned int limit); - NzRenderWindow& operator=(const NzRenderWindow&) = delete; - NzRenderWindow& operator=(NzRenderWindow&&) = delete; ///TODO + // Fonctions OpenGL + ContextParameters GetContextParameters() const; + bool HasContext() const override; - protected: - bool Activate() const override; - void EnsureTargetUpdated() const override; + RenderWindow& operator=(const RenderWindow&) = delete; + RenderWindow& operator=(RenderWindow&&) = delete; ///TODO - private: - bool OnWindowCreated() override; - void OnWindowDestroy() override; - void OnWindowResized() override; + protected: + bool Activate() const override; + void EnsureTargetUpdated() const override; - mutable std::vector m_buffer; - NzClock m_clock; - NzContextParameters m_parameters; - mutable NzContext* m_context = nullptr; - unsigned int m_framerateLimit = 0; -}; + private: + bool OnWindowCreated() override; + void OnWindowDestroy() override; + void OnWindowResized() override; + + mutable std::vector m_buffer; + Clock m_clock; + ContextParameters m_parameters; + mutable Context* m_context = nullptr; + unsigned int m_framerateLimit = 0; + }; +} #endif // NAZARA_RENDERWINDOW_HPP diff --git a/include/Nazara/Renderer/Renderer.hpp b/include/Nazara/Renderer/Renderer.hpp index be4aa56c6..1578c5a40 100644 --- a/include/Nazara/Renderer/Renderer.hpp +++ b/include/Nazara/Renderer/Renderer.hpp @@ -18,107 +18,110 @@ #include #include -class NzColor; -class NzContext; -class NzIndexBuffer; -class NzRenderTarget; -class NzShader; -class NzTexture; -class NzVertexBuffer; - -class NAZARA_RENDERER_API NzRenderer +namespace Nz { - friend NzTexture; + class Color; + class Context; + class IndexBuffer; + class RenderTarget; + class Shader; + class Texture; + class VertexBuffer; - public: - using DrawCall = void (*)(nzPrimitiveMode, unsigned int, unsigned int); - using DrawCallInstanced = void (*)(unsigned int, nzPrimitiveMode, unsigned int, unsigned int); + class NAZARA_RENDERER_API Renderer + { + friend Texture; - NzRenderer() = delete; - ~NzRenderer() = delete; + public: + using DrawCall = void (*)(PrimitiveMode, unsigned int, unsigned int); + using DrawCallInstanced = void (*)(unsigned int, PrimitiveMode, unsigned int, unsigned int); - static void BeginCondition(const NzGpuQuery& query, nzGpuQueryCondition condition); + Renderer() = delete; + ~Renderer() = delete; - static void Clear(nzUInt32 flags = nzRendererBuffer_Color | nzRendererBuffer_Depth); + static void BeginCondition(const GpuQuery& query, GpuQueryCondition condition); - static void DrawFullscreenQuad(); - static void DrawIndexedPrimitives(nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount); - static void DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount); - static void DrawPrimitives(nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount); - static void DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount); + static void Clear(UInt32 flags = RendererBuffer_Color | RendererBuffer_Depth); - static void Enable(nzRendererParameter parameter, bool enable); + static void DrawFullscreenQuad(); + static void DrawIndexedPrimitives(PrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount); + static void DrawIndexedPrimitivesInstanced(unsigned int instanceCount, PrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount); + static void DrawPrimitives(PrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount); + static void DrawPrimitivesInstanced(unsigned int instanceCount, PrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount); - static void EndCondition(); + static void Enable(RendererParameter parameter, bool enable); - static void Flush(); + static void EndCondition(); - static nzRendererComparison GetDepthFunc(); - static NzVertexBuffer* GetInstanceBuffer(); - static float GetLineWidth(); - static NzMatrix4f GetMatrix(nzMatrixType type); - static nzUInt8 GetMaxAnisotropyLevel(); - static unsigned int GetMaxColorAttachments(); - static unsigned int GetMaxRenderTargets(); - static unsigned int GetMaxTextureSize(); - static unsigned int GetMaxTextureUnits(); - static unsigned int GetMaxVertexAttribs(); - static float GetPointSize(); - static const NzRenderStates& GetRenderStates(); - static NzRecti GetScissorRect(); - static const NzShader* GetShader(); - static const NzRenderTarget* GetTarget(); - static NzRecti GetViewport(); + static void Flush(); - static bool HasCapability(nzRendererCap capability); + static RendererComparison GetDepthFunc(); + static VertexBuffer* GetInstanceBuffer(); + static float GetLineWidth(); + static Matrix4f GetMatrix(MatrixType type); + static UInt8 GetMaxAnisotropyLevel(); + static unsigned int GetMaxColorAttachments(); + static unsigned int GetMaxRenderTargets(); + static unsigned int GetMaxTextureSize(); + static unsigned int GetMaxTextureUnits(); + static unsigned int GetMaxVertexAttribs(); + static float GetPointSize(); + static const RenderStates& GetRenderStates(); + static Recti GetScissorRect(); + static const Shader* GetShader(); + static const RenderTarget* GetTarget(); + static Recti GetViewport(); - static bool Initialize(); + static bool HasCapability(RendererCap capability); - static bool IsComponentTypeSupported(nzComponentType type); - static bool IsEnabled(nzRendererParameter parameter); - static bool IsInitialized(); + static bool Initialize(); - static void SetBlendFunc(nzBlendFunc srcBlend, nzBlendFunc dstBlend); - static void SetClearColor(const NzColor& color); - static void SetClearColor(nzUInt8 r, nzUInt8 g, nzUInt8 b, nzUInt8 a = 255); - static void SetClearDepth(double depth); - static void SetClearStencil(unsigned int value); - static void SetDepthFunc(nzRendererComparison compareFunc); - static void SetFaceCulling(nzFaceSide faceSide); - static void SetFaceFilling(nzFaceFilling fillingMode); - static void SetIndexBuffer(const NzIndexBuffer* indexBuffer); - static void SetLineWidth(float size); - static void SetMatrix(nzMatrixType type, const NzMatrix4f& matrix); - static void SetPointSize(float size); - static void SetRenderStates(const NzRenderStates& states); - static void SetScissorRect(const NzRecti& rect); - static void SetShader(const NzShader* shader); - static void SetStencilCompareFunction(nzRendererComparison compareFunc, nzFaceSide faceSide = nzFaceSide_FrontAndBack); - static void SetStencilFailOperation(nzStencilOperation failOperation, nzFaceSide faceSide = nzFaceSide_FrontAndBack); - static void SetStencilMask(nzUInt32 mask, nzFaceSide faceSide = nzFaceSide_FrontAndBack); - static void SetStencilPassOperation(nzStencilOperation passOperation, nzFaceSide faceSide = nzFaceSide_FrontAndBack); - static void SetStencilReferenceValue(unsigned int refValue, nzFaceSide faceSide = nzFaceSide_FrontAndBack); - static void SetStencilZFailOperation(nzStencilOperation zfailOperation, nzFaceSide faceSide = nzFaceSide_FrontAndBack); - static bool SetTarget(const NzRenderTarget* target); - static void SetTexture(nzUInt8 unit, const NzTexture* texture); - static void SetTextureSampler(nzUInt8 textureUnit, const NzTextureSampler& sampler); - static void SetVertexBuffer(const NzVertexBuffer* vertexBuffer); - static void SetViewport(const NzRecti& viewport); + static bool IsComponentTypeSupported(ComponentType type); + static bool IsEnabled(RendererParameter parameter); + static bool IsInitialized(); - static void Uninitialize(); + static void SetBlendFunc(BlendFunc srcBlend, BlendFunc dstBlend); + static void SetClearColor(const Color& color); + static void SetClearColor(UInt8 r, UInt8 g, UInt8 b, UInt8 a = 255); + static void SetClearDepth(double depth); + static void SetClearStencil(unsigned int value); + static void SetDepthFunc(RendererComparison compareFunc); + static void SetFaceCulling(FaceSide faceSide); + static void SetFaceFilling(FaceFilling fillingMode); + static void SetIndexBuffer(const IndexBuffer* indexBuffer); + static void SetLineWidth(float size); + static void SetMatrix(MatrixType type, const Matrix4f& matrix); + static void SetPointSize(float size); + static void SetRenderStates(const RenderStates& states); + static void SetScissorRect(const Recti& rect); + static void SetShader(const Shader* shader); + static void SetStencilCompareFunction(RendererComparison compareFunc, FaceSide faceSide = FaceSide_FrontAndBack); + static void SetStencilFailOperation(nzStencilOperation failOperation, FaceSide faceSide = FaceSide_FrontAndBack); + static void SetStencilMask(UInt32 mask, FaceSide faceSide = FaceSide_FrontAndBack); + static void SetStencilPassOperation(nzStencilOperation passOperation, FaceSide faceSide = FaceSide_FrontAndBack); + static void SetStencilReferenceValue(unsigned int refValue, FaceSide faceSide = FaceSide_FrontAndBack); + static void SetStencilZFailOperation(nzStencilOperation zfailOperation, FaceSide faceSide = FaceSide_FrontAndBack); + static bool SetTarget(const RenderTarget* target); + static void SetTexture(UInt8 unit, const Texture* texture); + static void SetTextureSampler(UInt8 textureUnit, const TextureSampler& sampler); + static void SetVertexBuffer(const VertexBuffer* vertexBuffer); + static void SetViewport(const Recti& viewport); - private: - static void EnableInstancing(bool instancing); - static bool EnsureStateUpdate(); - static void OnContextRelease(const NzContext* context); - static void OnIndexBufferRelease(const NzIndexBuffer* indexBuffer); - static void OnShaderReleased(const NzShader* shader); - static void OnTextureReleased(const NzTexture* texture); - static void OnVertexBufferRelease(const NzVertexBuffer* vertexBuffer); - static void OnVertexDeclarationRelease(const NzVertexDeclaration* vertexDeclaration); - static void UpdateMatrix(nzMatrixType type); + static void Uninitialize(); - static unsigned int s_moduleReferenceCounter; -}; + private: + static void EnableInstancing(bool instancing); + static bool EnsureStateUpdate(); + static void OnContextRelease(const Context* context); + static void OnIndexBufferRelease(const IndexBuffer* indexBuffer); + static void OnShaderReleased(const Shader* shader); + static void OnTextureReleased(const Texture* texture); + static void OnVertexBufferRelease(const VertexBuffer* vertexBuffer); + static void OnVertexDeclarationRelease(const VertexDeclaration* vertexDeclaration); + static void UpdateMatrix(MatrixType type); + + static unsigned int s_moduleReferenceCounter; + }; +} #endif // NAZARA_RENDERER_HPP diff --git a/include/Nazara/Renderer/Shader.hpp b/include/Nazara/Renderer/Shader.hpp index 9217b9482..35789d09b 100644 --- a/include/Nazara/Renderer/Shader.hpp +++ b/include/Nazara/Renderer/Shader.hpp @@ -22,107 +22,110 @@ #include #include -class NzShader; -class NzShaderStage; - -using NzShaderConstRef = NzObjectRef; -using NzShaderLibrary = NzObjectLibrary; -using NzShaderRef = NzObjectRef; - -class NAZARA_RENDERER_API NzShader : public NzRefCounted +namespace Nz { - friend NzShaderLibrary; - friend class NzRenderer; + class Shader; + class ShaderStage; - public: - NzShader(); - NzShader(const NzShader&) = delete; - NzShader(NzShader&&) = delete; - ~NzShader(); + using ShaderConstRef = ObjectRef; + using ShaderLibrary = ObjectLibrary; + using ShaderRef = ObjectRef; - void AttachStage(nzShaderStage stage, const NzShaderStage& shaderStage); - bool AttachStageFromFile(nzShaderStage stage, const NzString& filePath); - bool AttachStageFromSource(nzShaderStage stage, const char* source, unsigned int length); - bool AttachStageFromSource(nzShaderStage stage, const NzString& source); + class NAZARA_RENDERER_API Shader : public RefCounted + { + friend ShaderLibrary; + friend class Renderer; - void Bind() const; + public: + Shader(); + Shader(const Shader&) = delete; + Shader(Shader&&) = delete; + ~Shader(); - bool Create(); - void Destroy(); + void AttachStage(ShaderStageType stage, const ShaderStage& shaderStage); + bool AttachStageFromFile(ShaderStageType stage, const String& filePath); + bool AttachStageFromSource(ShaderStageType stage, const char* source, unsigned int length); + bool AttachStageFromSource(ShaderStageType stage, const String& source); - NzByteArray GetBinary() const; - NzString GetLog() const; - NzString GetSourceCode(nzShaderStage stage) const; - int GetUniformLocation(const NzString& name) const; - int GetUniformLocation(nzShaderUniform shaderUniform) const; + void Bind() const; - bool HasStage(nzShaderStage stage) const; + bool Create(); + void Destroy(); - bool IsBinaryRetrievable() const; - bool IsLinked() const; - bool IsValid() const; + ByteArray GetBinary() const; + String GetLog() const; + String GetSourceCode(ShaderStageType stage) const; + int GetUniformLocation(const String& name) const; + int GetUniformLocation(ShaderUniform shaderUniform) const; - bool Link(); + bool HasStage(ShaderStageType stage) const; - bool LoadFromBinary(const void* buffer, unsigned int size); - bool LoadFromBinary(const NzByteArray& byteArray); + bool IsBinaryRetrievable() const; + bool IsLinked() const; + bool IsValid() const; - void SendBoolean(int location, bool value) const; - void SendColor(int location, const NzColor& color) const; - void SendDouble(int location, double value) const; - void SendDoubleArray(int location, const double* values, unsigned int count) const; - void SendFloat(int location, float value) const; - void SendFloatArray(int location, const float* values, unsigned int count) const; - void SendInteger(int location, int value) const; - void SendIntegerArray(int location, const int* values, unsigned int count) const; - void SendMatrix(int location, const NzMatrix4d& matrix) const; - void SendMatrix(int location, const NzMatrix4f& matrix) const; - void SendVector(int location, const NzVector2d& vector) const; - void SendVector(int location, const NzVector2f& vector) const; - void SendVector(int location, const NzVector2i& vector) const; - void SendVector(int location, const NzVector3d& vector) const; - void SendVector(int location, const NzVector3f& vector) const; - void SendVector(int location, const NzVector3i& vector) const; - void SendVector(int location, const NzVector4d& vector) const; - void SendVector(int location, const NzVector4f& vector) const; - void SendVector(int location, const NzVector4i& vector) const; - void SendVectorArray(int location, const NzVector2d* vectors, unsigned int count) const; - void SendVectorArray(int location, const NzVector2f* vectors, unsigned int count) const; - void SendVectorArray(int location, const NzVector2i* vectors, unsigned int count) const; - void SendVectorArray(int location, const NzVector3d* vectors, unsigned int count) const; - void SendVectorArray(int location, const NzVector3f* vectors, unsigned int count) const; - void SendVectorArray(int location, const NzVector3i* vectors, unsigned int count) const; - void SendVectorArray(int location, const NzVector4d* vectors, unsigned int count) const; - void SendVectorArray(int location, const NzVector4f* vectors, unsigned int count) const; - void SendVectorArray(int location, const NzVector4i* vectors, unsigned int count) const; + bool Link(); - // Fonctions OpenGL - unsigned int GetOpenGLID() const; + bool LoadFromBinary(const void* buffer, unsigned int size); + bool LoadFromBinary(const ByteArray& byteArray); - NzShader& operator=(const NzShader&) = delete; - NzShader& operator=(NzShader&&) = delete; + void SendBoolean(int location, bool value) const; + void SendColor(int location, const Color& color) const; + void SendDouble(int location, double value) const; + void SendDoubleArray(int location, const double* values, unsigned int count) const; + void SendFloat(int location, float value) const; + void SendFloatArray(int location, const float* values, unsigned int count) const; + void SendInteger(int location, int value) const; + void SendIntegerArray(int location, const int* values, unsigned int count) const; + void SendMatrix(int location, const Matrix4d& matrix) const; + void SendMatrix(int location, const Matrix4f& matrix) const; + void SendVector(int location, const Vector2d& vector) const; + void SendVector(int location, const Vector2f& vector) const; + void SendVector(int location, const Vector2i& vector) const; + void SendVector(int location, const Vector3d& vector) const; + void SendVector(int location, const Vector3f& vector) const; + void SendVector(int location, const Vector3i& vector) const; + void SendVector(int location, const Vector4d& vector) const; + void SendVector(int location, const Vector4f& vector) const; + void SendVector(int location, const Vector4i& vector) const; + void SendVectorArray(int location, const Vector2d* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector2f* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector2i* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector3d* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector3f* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector3i* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector4d* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector4f* vectors, unsigned int count) const; + void SendVectorArray(int location, const Vector4i* vectors, unsigned int count) const; - static bool IsStageSupported(nzShaderStage stage); - template static NzShaderRef New(Args&&... args); + // Fonctions OpenGL + unsigned int GetOpenGLID() const; - // Signals: - NazaraSignal(OnShaderDestroy, const NzShader* /*shader*/); - NazaraSignal(OnShaderRelease, const NzShader* /*shader*/); - NazaraSignal(OnShaderUniformInvalidated, const NzShader* /*shader*/); + Shader& operator=(const Shader&) = delete; + Shader& operator=(Shader&&) = delete; - private: - bool PostLinkage(); + static bool IsStageSupported(ShaderStageType stage); + template static ShaderRef New(Args&&... args); - static bool Initialize(); - static void Uninitialize(); + // Signals: + NazaraSignal(OnShaderDestroy, const Shader* /*shader*/); + NazaraSignal(OnShaderRelease, const Shader* /*shader*/); + NazaraSignal(OnShaderUniformInvalidated, const Shader* /*shader*/); - std::vector m_attachedShaders[nzShaderStage_Max+1]; - bool m_linked; - int m_uniformLocations[nzShaderUniform_Max+1]; - unsigned int m_program; + private: + bool PostLinkage(); - static NzShaderLibrary::LibraryMap s_library; -}; + static bool Initialize(); + static void Uninitialize(); + + std::vector m_attachedShaders[ShaderStageType_Max+1]; + bool m_linked; + int m_uniformLocations[ShaderUniform_Max+1]; + unsigned int m_program; + + static ShaderLibrary::LibraryMap s_library; + }; +} #include diff --git a/include/Nazara/Renderer/Shader.inl b/include/Nazara/Renderer/Shader.inl index 655c30655..b868c540e 100644 --- a/include/Nazara/Renderer/Shader.inl +++ b/include/Nazara/Renderer/Shader.inl @@ -5,13 +5,16 @@ #include #include -template -NzShaderRef NzShader::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzShader(std::forward(args)...)); - object->SetPersistent(false); + template + ShaderRef Shader::New(Args&&... args) + { + std::unique_ptr object(new Shader(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Renderer/ShaderStage.hpp b/include/Nazara/Renderer/ShaderStage.hpp index 4e4917f63..1dfce1f51 100644 --- a/include/Nazara/Renderer/ShaderStage.hpp +++ b/include/Nazara/Renderer/ShaderStage.hpp @@ -12,42 +12,45 @@ #include #include -class NAZARA_RENDERER_API NzShaderStage +namespace Nz { - public: - NzShaderStage(); - NzShaderStage(nzShaderStage stage); - NzShaderStage(const NzShaderStage&) = delete; - NzShaderStage(NzShaderStage&& stage); - ~NzShaderStage(); + class NAZARA_RENDERER_API ShaderStage + { + public: + ShaderStage(); + ShaderStage(ShaderStageType stage); + ShaderStage(const ShaderStage&) = delete; + ShaderStage(ShaderStage&& stage); + ~ShaderStage(); - bool Compile(); + bool Compile(); - bool Create(nzShaderStage stage); - void Destroy(); + bool Create(ShaderStageType stage); + void Destroy(); - NzString GetLog() const; - NzString GetSource() const; + String GetLog() const; + String GetSource() const; - bool IsCompiled() const; - bool IsValid() const; + bool IsCompiled() const; + bool IsValid() const; - void SetSource(const char* source, unsigned int length); - void SetSource(const NzString& source); - bool SetSourceFromFile(const NzString& filePath); + void SetSource(const char* source, unsigned int length); + void SetSource(const String& source); + bool SetSourceFromFile(const String& filePath); - NzShaderStage& operator=(const NzShaderStage&) = delete; - NzShaderStage& operator=(NzShaderStage&& shader); + ShaderStage& operator=(const ShaderStage&) = delete; + ShaderStage& operator=(ShaderStage&& shader); - // Fonctions OpenGL - unsigned int GetOpenGLID() const; + // Fonctions OpenGL + unsigned int GetOpenGLID() const; - static bool IsSupported(nzShaderStage stage); + static bool IsSupported(ShaderStageType stage); - private: - nzShaderStage m_stage; - bool m_compiled; - unsigned int m_id; -}; + private: + ShaderStageType m_stage; + bool m_compiled; + unsigned int m_id; + }; +} #endif // NAZARA_SHADERSTAGE_HPP diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 32e440924..130ebf069 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -20,114 +20,117 @@ #include #include -class NzTexture; - -using NzTextureConstRef = NzObjectRef; -using NzTextureLibrary = NzObjectLibrary; -using NzTextureManager = NzResourceManager; -using NzTextureRef = NzObjectRef; - -struct NzTextureImpl; - -class NAZARA_RENDERER_API NzTexture : public NzAbstractImage, public NzRefCounted, public NzResource +namespace Nz { - friend NzTextureLibrary; - friend NzTextureManager; - friend class NzRenderer; + class Texture; - public: - NzTexture() = default; - NzTexture(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1); - explicit NzTexture(const NzImage& image); - NzTexture(const NzTexture&) = delete; - NzTexture(NzTexture&&) = delete; - ~NzTexture(); + using TextureConstRef = ObjectRef; + using TextureLibrary = ObjectLibrary; + using TextureManager = ResourceManager; + using TextureRef = ObjectRef; - bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1); - void Destroy(); + struct TextureImpl; - bool Download(NzImage* image) const; + class NAZARA_RENDERER_API Texture : public AbstractImage, public RefCounted, public Resource + { + friend TextureLibrary; + friend TextureManager; + friend class Renderer; - bool EnableMipmapping(bool enable); + public: + Texture() = default; + Texture(ImageType type, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth = 1, UInt8 levelCount = 1); + explicit Texture(const Image& image); + Texture(const Texture&) = delete; + Texture(Texture&&) = delete; + ~Texture(); - void EnsureMipmapsUpdate() const; + bool Create(ImageType type, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth = 1, UInt8 levelCount = 1); + void Destroy(); - unsigned int GetDepth(nzUInt8 level = 0) const; - nzPixelFormat GetFormat() const; - unsigned int GetHeight(nzUInt8 level = 0) const; - nzUInt8 GetLevelCount() const; - nzUInt8 GetMaxLevel() const; - unsigned int GetMemoryUsage() const; - unsigned int GetMemoryUsage(nzUInt8 level) const; - NzVector3ui GetSize(nzUInt8 level = 0) const; - nzImageType GetType() const; - unsigned int GetWidth(nzUInt8 level = 0) const; + bool Download(Image* image) const; - bool HasMipmaps() const; + bool EnableMipmapping(bool enable); - void InvalidateMipmaps(); - bool IsValid() const; + void EnsureMipmapsUpdate() const; - // Load - bool LoadFromFile(const NzString& filePath, const NzImageParams& params = NzImageParams(), bool generateMipmaps = true); - bool LoadFromImage(const NzImage& image, bool generateMipmaps = true); - bool LoadFromMemory(const void* data, std::size_t size, const NzImageParams& params = NzImageParams(), bool generateMipmaps = true); - bool LoadFromStream(NzInputStream& stream, const NzImageParams& params = NzImageParams(), bool generateMipmaps = true); + unsigned int GetDepth(UInt8 level = 0) const; + PixelFormatType GetFormat() const; + unsigned int GetHeight(UInt8 level = 0) const; + UInt8 GetLevelCount() const; + UInt8 GetMaxLevel() const; + unsigned int GetMemoryUsage() const; + unsigned int GetMemoryUsage(UInt8 level) const; + Vector3ui GetSize(UInt8 level = 0) const; + ImageType GetType() const; + unsigned int GetWidth(UInt8 level = 0) const; - // LoadArray - bool LoadArrayFromFile(const NzString& filePath, const NzImageParams& imageParams = NzImageParams(), bool generateMipmaps = true, const NzVector2ui& atlasSize = NzVector2ui(2, 2)); - bool LoadArrayFromImage(const NzImage& image, bool generateMipmaps = true, const NzVector2ui& atlasSize = NzVector2ui(2, 2)); - bool LoadArrayFromMemory(const void* data, std::size_t size, const NzImageParams& imageParams = NzImageParams(), bool generateMipmaps = true, const NzVector2ui& atlasSize = NzVector2ui(2, 2)); - bool LoadArrayFromStream(NzInputStream& stream, const NzImageParams& imageParams = NzImageParams(), bool generateMipmaps = true, const NzVector2ui& atlasSize = NzVector2ui(2, 2)); + bool HasMipmaps() const; - // LoadCubemap - bool LoadCubemapFromFile(const NzString& filePath, const NzImageParams& imageParams = NzImageParams(), bool generateMipmaps = true, const NzCubemapParams& cubemapParams = NzCubemapParams()); - bool LoadCubemapFromImage(const NzImage& image, bool generateMipmaps = true, const NzCubemapParams& params = NzCubemapParams()); - bool LoadCubemapFromMemory(const void* data, std::size_t size, const NzImageParams& imageParams = NzImageParams(), bool generateMipmaps = true, const NzCubemapParams& cubemapParams = NzCubemapParams()); - bool LoadCubemapFromStream(NzInputStream& stream, const NzImageParams& imageParams = NzImageParams(), bool generateMipmaps = true, const NzCubemapParams& cubemapParams = NzCubemapParams()); + void InvalidateMipmaps(); + bool IsValid() const; - // LoadFace - bool LoadFaceFromFile(nzCubemapFace face, const NzString& filePath, const NzImageParams& params = NzImageParams()); - bool LoadFaceFromMemory(nzCubemapFace face, const void* data, std::size_t size, const NzImageParams& params = NzImageParams()); - bool LoadFaceFromStream(nzCubemapFace face, NzInputStream& stream, const NzImageParams& params = NzImageParams()); + // Load + bool LoadFromFile(const String& filePath, const ImageParams& params = ImageParams(), bool generateMipmaps = true); + bool LoadFromImage(const Image& image, bool generateMipmaps = true); + bool LoadFromMemory(const void* data, std::size_t size, const ImageParams& params = ImageParams(), bool generateMipmaps = true); + bool LoadFromStream(InputStream& stream, const ImageParams& params = ImageParams(), bool generateMipmaps = true); - bool SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel); + // LoadArray + bool LoadArrayFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); + bool LoadArrayFromImage(const Image& image, bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); + bool LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); + bool LoadArrayFromStream(InputStream& stream, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); - bool Update(const NzImage& image, nzUInt8 level = 0); - bool Update(const NzImage& image, const NzBoxui& box, nzUInt8 level = 0); - bool Update(const NzImage& image, const NzRectui& rect, unsigned int z = 0, nzUInt8 level = 0); - bool Update(const nzUInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); - bool Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); - bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); + // LoadCubemap + bool LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); + bool LoadCubemapFromImage(const Image& image, bool generateMipmaps = true, const CubemapParams& params = CubemapParams()); + bool LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); + bool LoadCubemapFromStream(InputStream& stream, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); - // Fonctions OpenGL - unsigned int GetOpenGLID() const; + // LoadFace + bool LoadFaceFromFile(CubemapFace face, const String& filePath, const ImageParams& params = ImageParams()); + bool LoadFaceFromMemory(CubemapFace face, const void* data, std::size_t size, const ImageParams& params = ImageParams()); + bool LoadFaceFromStream(CubemapFace face, InputStream& stream, const ImageParams& params = ImageParams()); - NzTexture& operator=(const NzTexture&) = delete; - NzTexture& operator=(NzTexture&&) = delete; + bool SetMipmapRange(UInt8 minLevel, UInt8 maxLevel); - static unsigned int GetValidSize(unsigned int size); - static bool IsFormatSupported(nzPixelFormat format); - static bool IsMipmappingSupported(); - static bool IsTypeSupported(nzImageType type); - template static NzTextureRef New(Args&&... args); + bool Update(const Image& image, UInt8 level = 0); + bool Update(const Image& image, const Boxui& box, UInt8 level = 0); + bool Update(const Image& image, const Rectui& rect, unsigned int z = 0, UInt8 level = 0); + bool Update(const UInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0); + bool Update(const UInt8* pixels, const Boxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0); + bool Update(const UInt8* pixels, const Rectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0); - // Signals: - NazaraSignal(OnTextureDestroy, const NzTexture* /*texture*/); - NazaraSignal(OnTextureRelease, const NzTexture* /*texture*/); + // Fonctions OpenGL + unsigned int GetOpenGLID() const; - private: - bool CreateTexture(bool proxy); + Texture& operator=(const Texture&) = delete; + Texture& operator=(Texture&&) = delete; - static bool Initialize(); - static void Uninitialize(); + static unsigned int GetValidSize(unsigned int size); + static bool IsFormatSupported(PixelFormatType format); + static bool IsMipmappingSupported(); + static bool IsTypeSupported(ImageType type); + template static TextureRef New(Args&&... args); - NzTextureImpl* m_impl = nullptr; + // Signals: + NazaraSignal(OnTextureDestroy, const Texture* /*texture*/); + NazaraSignal(OnTextureRelease, const Texture* /*texture*/); - static NzTextureLibrary::LibraryMap s_library; - static NzTextureManager::ManagerMap s_managerMap; - static NzTextureManager::ManagerParams s_managerParameters; -}; + private: + bool CreateTexture(bool proxy); + + static bool Initialize(); + static void Uninitialize(); + + TextureImpl* m_impl = nullptr; + + static TextureLibrary::LibraryMap s_library; + static TextureManager::ManagerMap s_managerMap; + static TextureManager::ManagerParams s_managerParameters; + }; +} #include diff --git a/include/Nazara/Renderer/Texture.inl b/include/Nazara/Renderer/Texture.inl index bb4ed4c23..4dc53464b 100644 --- a/include/Nazara/Renderer/Texture.inl +++ b/include/Nazara/Renderer/Texture.inl @@ -5,13 +5,16 @@ #include #include -template -NzTextureRef NzTexture::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzTexture(std::forward(args)...)); - object->SetPersistent(false); + template + TextureRef Texture::New(Args&&... args) + { + std::unique_ptr object(new Texture(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); + } - return object.release(); } - #include diff --git a/include/Nazara/Renderer/TextureSampler.hpp b/include/Nazara/Renderer/TextureSampler.hpp index e0b771282..a461f57b2 100644 --- a/include/Nazara/Renderer/TextureSampler.hpp +++ b/include/Nazara/Renderer/TextureSampler.hpp @@ -11,53 +11,56 @@ #include #include -class NzTexture; - -class NAZARA_RENDERER_API NzTextureSampler +namespace Nz { - friend class NzRenderer; + class Texture; - public: - NzTextureSampler(); - NzTextureSampler(const NzTextureSampler& sampler) = default; + class NAZARA_RENDERER_API TextureSampler + { + friend class Renderer; - nzUInt8 GetAnisotropicLevel() const; - nzSamplerFilter GetFilterMode() const; - nzSamplerWrap GetWrapMode() const; + public: + TextureSampler(); + TextureSampler(const TextureSampler& sampler) = default; - void SetAnisotropyLevel(nzUInt8 anisotropyLevel); - void SetFilterMode(nzSamplerFilter filterMode); - void SetWrapMode(nzSamplerWrap wrapMode); + UInt8 GetAnisotropicLevel() const; + SamplerFilter GetFilterMode() const; + SamplerWrap GetWrapMode() const; - NzTextureSampler& operator=(const NzTextureSampler& sampler) = default; + void SetAnisotropyLevel(UInt8 anisotropyLevel); + void SetFilterMode(SamplerFilter filterMode); + void SetWrapMode(SamplerWrap wrapMode); - static nzUInt8 GetDefaultAnisotropicLevel(); - static nzSamplerFilter GetDefaultFilterMode(); - static nzSamplerWrap GetDefaultWrapMode(); + TextureSampler& operator=(const TextureSampler& sampler) = default; - static void SetDefaultAnisotropyLevel(nzUInt8 anisotropyLevel); - static void SetDefaultFilterMode(nzSamplerFilter filterMode); - static void SetDefaultWrapMode(nzSamplerWrap wrapMode); + static UInt8 GetDefaultAnisotropicLevel(); + static SamplerFilter GetDefaultFilterMode(); + static SamplerWrap GetDefaultWrapMode(); - private: - void Apply(const NzTexture* texture) const; - void Bind(unsigned int unit) const; - unsigned int GetOpenGLID() const; - void UpdateSamplerId() const; - bool UseMipmaps(bool mipmaps); + static void SetDefaultAnisotropyLevel(UInt8 anisotropyLevel); + static void SetDefaultFilterMode(SamplerFilter filterMode); + static void SetDefaultWrapMode(SamplerWrap wrapMode); - static bool Initialize(); - static void Uninitialize(); + private: + void Apply(const Texture* texture) const; + void Bind(unsigned int unit) const; + unsigned int GetOpenGLID() const; + void UpdateSamplerId() const; + bool UseMipmaps(bool mipmaps); - nzSamplerFilter m_filterMode; - nzSamplerWrap m_wrapMode; - nzUInt8 m_anisotropicLevel; - bool m_mipmaps; - mutable unsigned int m_samplerId; + static bool Initialize(); + static void Uninitialize(); - static nzSamplerFilter s_defaultFilterMode; - static nzSamplerWrap s_defaultWrapMode; - static nzUInt8 s_defaultAnisotropyLevel; -}; + SamplerFilter m_filterMode; + SamplerWrap m_wrapMode; + UInt8 m_anisotropicLevel; + bool m_mipmaps; + mutable unsigned int m_samplerId; + + static SamplerFilter s_defaultFilterMode; + static SamplerWrap s_defaultWrapMode; + static UInt8 s_defaultAnisotropyLevel; + }; +} #endif // NAZARA_TEXTURESAMPLER_HPP diff --git a/include/Nazara/Renderer/UberShader.hpp b/include/Nazara/Renderer/UberShader.hpp index c6df6f915..541715895 100644 --- a/include/Nazara/Renderer/UberShader.hpp +++ b/include/Nazara/Renderer/UberShader.hpp @@ -15,36 +15,39 @@ #include #include -class NzUberShader; - -using NzUberShaderConstRef = NzObjectRef; -using NzUberShaderLibrary = NzObjectLibrary; -using NzUberShaderRef = NzObjectRef; - -class NAZARA_RENDERER_API NzUberShader : public NzRefCounted +namespace Nz { - friend NzUberShaderLibrary; - friend class NzRenderer; + class UberShader; - public: - NzUberShader() = default; - NzUberShader(const NzUberShader&) = delete; - NzUberShader(NzUberShader&&) = delete; - virtual ~NzUberShader(); + using UberShaderConstRef = ObjectRef; + using UberShaderLibrary = ObjectLibrary; + using UberShaderRef = ObjectRef; - virtual NzUberShaderInstance* Get(const NzParameterList& parameters) const = 0; + class NAZARA_RENDERER_API UberShader : public RefCounted + { + friend UberShaderLibrary; + friend class Renderer; - NzUberShader& operator=(const NzUberShader&) = delete; - NzUberShader& operator=(NzUberShader&&) = delete; + public: + UberShader() = default; + UberShader(const UberShader&) = delete; + UberShader(UberShader&&) = delete; + virtual ~UberShader(); - // Signals: - NazaraSignal(OnUberShaderRelease, const NzUberShader* /*uberShader*/); + virtual UberShaderInstance* Get(const ParameterList& parameters) const = 0; - private: - static bool Initialize(); - static void Uninitialize(); + UberShader& operator=(const UberShader&) = delete; + UberShader& operator=(UberShader&&) = delete; - static NzUberShaderLibrary::LibraryMap s_library; -}; + // Signals: + NazaraSignal(OnUberShaderRelease, const UberShader* /*uberShader*/); + + private: + static bool Initialize(); + static void Uninitialize(); + + static UberShaderLibrary::LibraryMap s_library; + }; +} #endif // NAZARA_UBERSHADER_HPP diff --git a/include/Nazara/Renderer/UberShaderInstance.hpp b/include/Nazara/Renderer/UberShaderInstance.hpp index e56f13d2f..080cb8294 100644 --- a/include/Nazara/Renderer/UberShaderInstance.hpp +++ b/include/Nazara/Renderer/UberShaderInstance.hpp @@ -10,23 +10,21 @@ #include #include -class NAZARA_RENDERER_API NzUberShaderInstance +namespace Nz { - public: - NzUberShaderInstance(const NzShader* shader); - NzUberShaderInstance(const NzUberShaderInstance&) = delete; - NzUberShaderInstance(NzUberShaderInstance&&) = delete; - virtual ~NzUberShaderInstance(); + class NAZARA_RENDERER_API UberShaderInstance + { + public: + UberShaderInstance(const Shader* shader); + virtual ~UberShaderInstance(); - virtual bool Activate() const = 0; + virtual bool Activate() const = 0; - const NzShader* GetShader() const; + const Shader* GetShader() const; - NzUberShaderInstance& operator=(const NzUberShaderInstance&) = delete; - NzUberShaderInstance& operator=(NzUberShaderInstance&&) = delete; - - protected: - NzShaderConstRef m_shader; -}; + protected: + ShaderConstRef m_shader; + }; +} #endif // NAZARA_UBERSHADERINSTANCE_HPP diff --git a/include/Nazara/Renderer/UberShaderInstancePreprocessor.hpp b/include/Nazara/Renderer/UberShaderInstancePreprocessor.hpp index 7ba324aaf..9a0c8a6f9 100644 --- a/include/Nazara/Renderer/UberShaderInstancePreprocessor.hpp +++ b/include/Nazara/Renderer/UberShaderInstancePreprocessor.hpp @@ -10,13 +10,16 @@ #include #include -class NAZARA_RENDERER_API NzUberShaderInstancePreprocessor : public NzUberShaderInstance +namespace Nz { - public: - NzUberShaderInstancePreprocessor(const NzShader* shader); - virtual ~NzUberShaderInstancePreprocessor(); + class NAZARA_RENDERER_API UberShaderInstancePreprocessor : public UberShaderInstance + { + public: + UberShaderInstancePreprocessor(const Shader* shader); + virtual ~UberShaderInstancePreprocessor(); - bool Activate() const; -}; + bool Activate() const; + }; +} #endif // NAZARA_UBERSHADERINSTANCEPREPROCESSOR_HPP diff --git a/include/Nazara/Renderer/UberShaderPreprocessor.hpp b/include/Nazara/Renderer/UberShaderPreprocessor.hpp index 7e2042887..1411b731c 100644 --- a/include/Nazara/Renderer/UberShaderPreprocessor.hpp +++ b/include/Nazara/Renderer/UberShaderPreprocessor.hpp @@ -16,42 +16,45 @@ #include #include -class NzUberShaderPreprocessor; - -using NzUberShaderPreprocessorConstRef = NzObjectRef; -using NzUberShaderPreprocessorRef = NzObjectRef; - -class NAZARA_RENDERER_API NzUberShaderPreprocessor : public NzUberShader +namespace Nz { - public: - NzUberShaderPreprocessor() = default; - ~NzUberShaderPreprocessor(); + class UberShaderPreprocessor; - NzUberShaderInstance* Get(const NzParameterList& parameters) const; + using UberShaderPreprocessorConstRef = ObjectRef; + using UberShaderPreprocessorRef = ObjectRef; - void SetShader(nzShaderStage stage, const NzString& source, const NzString& shaderFlags, const NzString& requiredFlags = NzString()); - bool SetShaderFromFile(nzShaderStage stage, const NzString& filePath, const NzString& shaderFlags, const NzString& requiredFlags = NzString()); + class NAZARA_RENDERER_API UberShaderPreprocessor : public UberShader + { + public: + UberShaderPreprocessor() = default; + ~UberShaderPreprocessor(); - static bool IsSupported(); - template static NzUberShaderPreprocessorRef New(Args&&... args); + UberShaderInstance* Get(const ParameterList& parameters) const; - // Signals: - NazaraSignal(OnUberShaderPreprocessorRelease, const NzUberShaderPreprocessor* /*uberShaderPreprocessor*/); + void SetShader(ShaderStageType stage, const String& source, const String& shaderFlags, const String& requiredFlags = String()); + bool SetShaderFromFile(ShaderStageType stage, const String& filePath, const String& shaderFlags, const String& requiredFlags = String()); - private: - struct Shader - { - mutable std::unordered_map cache; - std::unordered_map flags; - nzUInt32 requiredFlags; - NzString source; - bool present = false; - }; + static bool IsSupported(); + template static UberShaderPreprocessorRef New(Args&&... args); - mutable std::unordered_map m_cache; - std::unordered_map m_flags; - Shader m_shaders[nzShaderStage_Max+1]; -}; + // Signals: + NazaraSignal(OnUberShaderPreprocessorRelease, const UberShaderPreprocessor* /*uberShaderPreprocessor*/); + + private: + struct CachedShader + { + mutable std::unordered_map cache; + std::unordered_map flags; + UInt32 requiredFlags; + String source; + bool present = false; + }; + + mutable std::unordered_map m_cache; + std::unordered_map m_flags; + CachedShader m_shaders[ShaderStageType_Max+1]; + }; +} #include diff --git a/include/Nazara/Renderer/UberShaderPreprocessor.inl b/include/Nazara/Renderer/UberShaderPreprocessor.inl index f5c9cb603..1e6528775 100644 --- a/include/Nazara/Renderer/UberShaderPreprocessor.inl +++ b/include/Nazara/Renderer/UberShaderPreprocessor.inl @@ -5,13 +5,16 @@ #include #include -template -NzUberShaderPreprocessorRef NzUberShaderPreprocessor::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzUberShaderPreprocessor(std::forward(args)...)); - object->SetPersistent(false); + template + UberShaderPreprocessorRef UberShaderPreprocessor::New(Args&&... args) + { + std::unique_ptr object(new UberShaderPreprocessor(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Utility/AbstractAtlas.hpp b/include/Nazara/Utility/AbstractAtlas.hpp index 1b1b28a36..4d135d465 100644 --- a/include/Nazara/Utility/AbstractAtlas.hpp +++ b/include/Nazara/Utility/AbstractAtlas.hpp @@ -15,26 +15,29 @@ #include #include -class NzAbstractImage; -class NzImage; - -class NAZARA_UTILITY_API NzAbstractAtlas +namespace Nz { - public: - NzAbstractAtlas() = default; - virtual ~NzAbstractAtlas(); + class AbstractImage; + class Image; - virtual void Clear() = 0; - virtual void Free(NzSparsePtr rects, NzSparsePtr layers, unsigned int count) = 0; - virtual NzAbstractImage* GetLayer(unsigned int layerIndex) const = 0; - virtual unsigned int GetLayerCount() const = 0; - virtual nzUInt32 GetStorage() const = 0; - virtual bool Insert(const NzImage& image, NzRectui* rect, bool* flipped, unsigned int* layerIndex) = 0; + class NAZARA_UTILITY_API AbstractAtlas + { + public: + AbstractAtlas() = default; + virtual ~AbstractAtlas(); - // Signals: - NazaraSignal(OnAtlasCleared, const NzAbstractAtlas* /*atlas*/); - NazaraSignal(OnAtlasLayerChange, const NzAbstractAtlas* /*atlas*/, NzAbstractImage* /*oldLayer*/, NzAbstractImage* /*newLayer*/); - NazaraSignal(OnAtlasRelease, const NzAbstractAtlas* /*atlas*/); -}; + virtual void Clear() = 0; + virtual void Free(SparsePtr rects, SparsePtr layers, unsigned int count) = 0; + virtual AbstractImage* GetLayer(unsigned int layerIndex) const = 0; + virtual unsigned int GetLayerCount() const = 0; + virtual UInt32 GetStorage() const = 0; + virtual bool Insert(const Image& image, Rectui* rect, bool* flipped, unsigned int* layerIndex) = 0; + + // Signals: + NazaraSignal(OnAtlasCleared, const AbstractAtlas* /*atlas*/); + NazaraSignal(OnAtlasLayerChange, const AbstractAtlas* /*atlas*/, AbstractImage* /*oldLayer*/, AbstractImage* /*newLayer*/); + NazaraSignal(OnAtlasRelease, const AbstractAtlas* /*atlas*/); + }; +} #endif // NAZARA_ABSTRACTATLAS_HPP diff --git a/include/Nazara/Utility/AbstractBuffer.hpp b/include/Nazara/Utility/AbstractBuffer.hpp index dfa0a27bb..dd214c70f 100644 --- a/include/Nazara/Utility/AbstractBuffer.hpp +++ b/include/Nazara/Utility/AbstractBuffer.hpp @@ -9,21 +9,24 @@ #include -class NAZARA_UTILITY_API NzAbstractBuffer +namespace Nz { - public: - NzAbstractBuffer() = default; - virtual ~NzAbstractBuffer(); + class NAZARA_UTILITY_API AbstractBuffer + { + public: + AbstractBuffer() = default; + virtual ~AbstractBuffer(); - virtual bool Create(unsigned int size, nzBufferUsage usage = nzBufferUsage_Static) = 0; - virtual void Destroy() = 0; + virtual bool Create(unsigned int size, BufferUsage usage = BufferUsage_Static) = 0; + virtual void Destroy() = 0; - virtual bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false) = 0; + virtual bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false) = 0; - virtual bool IsHardware() const = 0; + virtual bool IsHardware() const = 0; - virtual void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0) = 0; - virtual bool Unmap() = 0; -}; + virtual void* Map(BufferAccess access, unsigned int offset = 0, unsigned int size = 0) = 0; + virtual bool Unmap() = 0; + }; +} #endif // NAZARA_ABSTRACTBUFFER_HPP diff --git a/include/Nazara/Utility/AbstractImage.hpp b/include/Nazara/Utility/AbstractImage.hpp index bf8a08573..3a09f3a06 100644 --- a/include/Nazara/Utility/AbstractImage.hpp +++ b/include/Nazara/Utility/AbstractImage.hpp @@ -14,30 +14,33 @@ #include #include -class NAZARA_UTILITY_API NzAbstractImage +namespace Nz { - public: - NzAbstractImage() = default; - virtual ~NzAbstractImage(); + class NAZARA_UTILITY_API AbstractImage + { + public: + AbstractImage() = default; + virtual ~AbstractImage(); - nzUInt8 GetBytesPerPixel() const; - virtual unsigned int GetDepth(nzUInt8 level = 0) const = 0; - virtual nzPixelFormat GetFormat() const = 0; - virtual unsigned int GetHeight(nzUInt8 level = 0) const = 0; - virtual nzUInt8 GetLevelCount() const = 0; - virtual nzUInt8 GetMaxLevel() const = 0; - virtual unsigned int GetMemoryUsage() const = 0; - virtual unsigned int GetMemoryUsage(nzUInt8 level) const = 0; - virtual NzVector3ui GetSize(nzUInt8 level = 0) const = 0; - virtual nzImageType GetType() const = 0; - virtual unsigned int GetWidth(nzUInt8 level = 0) const = 0; + UInt8 GetBytesPerPixel() const; + virtual unsigned int GetDepth(UInt8 level = 0) const = 0; + virtual PixelFormatType GetFormat() const = 0; + virtual unsigned int GetHeight(UInt8 level = 0) const = 0; + virtual UInt8 GetLevelCount() const = 0; + virtual UInt8 GetMaxLevel() const = 0; + virtual unsigned int GetMemoryUsage() const = 0; + virtual unsigned int GetMemoryUsage(UInt8 level) const = 0; + virtual Vector3ui GetSize(UInt8 level = 0) const = 0; + virtual ImageType GetType() const = 0; + virtual unsigned int GetWidth(UInt8 level = 0) const = 0; - bool IsCompressed() const; - bool IsCubemap() const; + bool IsCompressed() const; + bool IsCubemap() const; - virtual bool Update(const nzUInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0) = 0; - virtual bool Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0) = 0; - virtual bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0) = 0; -}; + virtual bool Update(const UInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) = 0; + virtual bool Update(const UInt8* pixels, const Boxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) = 0; + virtual bool Update(const UInt8* pixels, const Rectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0) = 0; + }; +} #endif // NAZARA_IMAGE_HPP diff --git a/include/Nazara/Utility/AbstractTextDrawer.hpp b/include/Nazara/Utility/AbstractTextDrawer.hpp index 3f888bde2..20aac4db3 100644 --- a/include/Nazara/Utility/AbstractTextDrawer.hpp +++ b/include/Nazara/Utility/AbstractTextDrawer.hpp @@ -13,31 +13,34 @@ #include #include -class NzAbstractImage; -class NzFont; - -class NAZARA_UTILITY_API NzAbstractTextDrawer +namespace Nz { - public: - struct Glyph; + class AbstractImage; + class Font; - NzAbstractTextDrawer() = default; - virtual ~NzAbstractTextDrawer(); + class NAZARA_UTILITY_API AbstractTextDrawer + { + public: + struct Glyph; - virtual const NzRectui& GetBounds() const = 0; - virtual NzFont* GetFont(unsigned int index) const = 0; - virtual unsigned int GetFontCount() const = 0; - virtual const Glyph& GetGlyph(unsigned int index) const = 0; - virtual unsigned int GetGlyphCount() const = 0; + AbstractTextDrawer() = default; + virtual ~AbstractTextDrawer(); - struct Glyph - { - NzColor color; - NzRectui atlasRect; - NzVector2f corners[4]; - NzAbstractImage* atlas; - bool flipped; - }; -}; + virtual const Rectui& GetBounds() const = 0; + virtual Font* GetFont(unsigned int index) const = 0; + virtual unsigned int GetFontCount() const = 0; + virtual const Glyph& GetGlyph(unsigned int index) const = 0; + virtual unsigned int GetGlyphCount() const = 0; + + struct Glyph + { + Color color; + Rectui atlasRect; + Vector2f corners[4]; + AbstractImage* atlas; + bool flipped; + }; + }; +} #endif // NAZARA_ABSTRACTTEXTDRAWER_HPP diff --git a/include/Nazara/Utility/Algorithm.hpp b/include/Nazara/Utility/Algorithm.hpp index 3d3f3b72e..70c4cdc60 100644 --- a/include/Nazara/Utility/Algorithm.hpp +++ b/include/Nazara/Utility/Algorithm.hpp @@ -17,43 +17,46 @@ #include #include -struct NzSkinningData +namespace Nz { - const NzJoint* joints; - const NzSkeletalMeshVertex* inputVertex; - NzMeshVertex* outputVertex; -}; + struct SkinningData + { + const Joint* joints; + const SkeletalMeshVertex* inputVertex; + MeshVertex* outputVertex; + }; -struct NzVertexPointers -{ - NzSparsePtr normalPtr; - NzSparsePtr positionPtr; - NzSparsePtr tangentPtr; - NzSparsePtr uvPtr; -}; + struct VertexPointers + { + SparsePtr normalPtr; + SparsePtr positionPtr; + SparsePtr tangentPtr; + SparsePtr uvPtr; + }; -NAZARA_UTILITY_API NzBoxf NzComputeAABB(NzSparsePtr positionPtr, unsigned int vertexCount); -NAZARA_UTILITY_API void NzComputeBoxIndexVertexCount(const NzVector3ui& subdivision, unsigned int* indexCount, unsigned int* vertexCount); -NAZARA_UTILITY_API unsigned int NzComputeCacheMissCount(NzIndexIterator indices, unsigned int indexCount); -NAZARA_UTILITY_API void NzComputeConeIndexVertexCount(unsigned int subdivision, unsigned int* indexCount, unsigned int* vertexCount); -NAZARA_UTILITY_API void NzComputeCubicSphereIndexVertexCount(unsigned int subdivision, unsigned int* indexCount, unsigned int* vertexCount); -NAZARA_UTILITY_API void NzComputeIcoSphereIndexVertexCount(unsigned int recursionLevel, unsigned int* indexCount, unsigned int* vertexCount); -NAZARA_UTILITY_API void NzComputePlaneIndexVertexCount(const NzVector2ui& subdivision, unsigned int* indexCount, unsigned int* vertexCount); -NAZARA_UTILITY_API void NzComputeUvSphereIndexVertexCount(unsigned int sliceCount, unsigned int stackCount, unsigned int* indexCount, unsigned int* vertexCount); + NAZARA_UTILITY_API Boxf ComputeAABB(SparsePtr positionPtr, unsigned int vertexCount); + NAZARA_UTILITY_API void ComputeBoxIndexVertexCount(const Vector3ui& subdivision, unsigned int* indexCount, unsigned int* vertexCount); + NAZARA_UTILITY_API unsigned int ComputeCacheMissCount(IndexIterator indices, unsigned int indexCount); + NAZARA_UTILITY_API void ComputeConeIndexVertexCount(unsigned int subdivision, unsigned int* indexCount, unsigned int* vertexCount); + NAZARA_UTILITY_API void ComputeCubicSphereIndexVertexCount(unsigned int subdivision, unsigned int* indexCount, unsigned int* vertexCount); + NAZARA_UTILITY_API void ComputeIcoSphereIndexVertexCount(unsigned int recursionLevel, unsigned int* indexCount, unsigned int* vertexCount); + NAZARA_UTILITY_API void ComputePlaneIndexVertexCount(const Vector2ui& subdivision, unsigned int* indexCount, unsigned int* vertexCount); + NAZARA_UTILITY_API void ComputeUvSphereIndexVertexCount(unsigned int sliceCount, unsigned int stackCount, unsigned int* indexCount, unsigned int* vertexCount); -NAZARA_UTILITY_API void NzGenerateBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzVertexPointers vertexPointers, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); -NAZARA_UTILITY_API void NzGenerateCone(float length, float radius, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzVertexPointers vertexPointers, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); -NAZARA_UTILITY_API void NzGenerateCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzVertexPointers vertexPointers, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); -NAZARA_UTILITY_API void NzGenerateIcoSphere(float size, unsigned int recursionLevel, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzVertexPointers vertexPointers, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); -NAZARA_UTILITY_API void NzGeneratePlane(const NzVector2ui& subdivision, const NzVector2f& size, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzVertexPointers vertexPointers, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); -NAZARA_UTILITY_API void NzGenerateUvSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzVertexPointers vertexPointers, NzIndexIterator indices, NzBoxf* aabb = nullptr, unsigned int indexOffset = 0); + NAZARA_UTILITY_API void GenerateBox(const Vector3f& lengths, const Vector3ui& subdivision, const Matrix4f& matrix, const Rectf& textureCoords, VertexPointers vertexPointers, IndexIterator indices, Boxf* aabb = nullptr, unsigned int indexOffset = 0); + NAZARA_UTILITY_API void GenerateCone(float length, float radius, unsigned int subdivision, const Matrix4f& matrix, const Rectf& textureCoords, VertexPointers vertexPointers, IndexIterator indices, Boxf* aabb = nullptr, unsigned int indexOffset = 0); + NAZARA_UTILITY_API void GenerateCubicSphere(float size, unsigned int subdivision, const Matrix4f& matrix, const Rectf& textureCoords, VertexPointers vertexPointers, IndexIterator indices, Boxf* aabb = nullptr, unsigned int indexOffset = 0); + NAZARA_UTILITY_API void GenerateIcoSphere(float size, unsigned int recursionLevel, const Matrix4f& matrix, const Rectf& textureCoords, VertexPointers vertexPointers, IndexIterator indices, Boxf* aabb = nullptr, unsigned int indexOffset = 0); + NAZARA_UTILITY_API void GeneratePlane(const Vector2ui& subdivision, const Vector2f& size, const Matrix4f& matrix, const Rectf& textureCoords, VertexPointers vertexPointers, IndexIterator indices, Boxf* aabb = nullptr, unsigned int indexOffset = 0); + NAZARA_UTILITY_API void GenerateUvSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Matrix4f& matrix, const Rectf& textureCoords, VertexPointers vertexPointers, IndexIterator indices, Boxf* aabb = nullptr, unsigned int indexOffset = 0); -NAZARA_UTILITY_API void NzOptimizeIndices(NzIndexIterator indices, unsigned int indexCount); + NAZARA_UTILITY_API void OptimizeIndices(IndexIterator indices, unsigned int indexCount); -NAZARA_UTILITY_API void NzSkinPosition(const NzSkinningData& data, unsigned int startVertex, unsigned int vertexCount); -NAZARA_UTILITY_API void NzSkinPositionNormal(const NzSkinningData& data, unsigned int startVertex, unsigned int vertexCount); -NAZARA_UTILITY_API void NzSkinPositionNormalTangent(const NzSkinningData& data, unsigned int startVertex, unsigned int vertexCount); + NAZARA_UTILITY_API void SkinPosition(const SkinningData& data, unsigned int startVertex, unsigned int vertexCount); + NAZARA_UTILITY_API void SkinPositionNormal(const SkinningData& data, unsigned int startVertex, unsigned int vertexCount); + NAZARA_UTILITY_API void SkinPositionNormalTangent(const SkinningData& data, unsigned int startVertex, unsigned int vertexCount); -NAZARA_UTILITY_API void NzTransformVertices(NzVertexPointers vertexPointers, unsigned int vertexCount, const NzMatrix4f& matrix); + NAZARA_UTILITY_API void TransformVertices(VertexPointers vertexPointers, unsigned int vertexCount, const Matrix4f& matrix); +} #endif // NAZARA_ALGORITHM_UTILITY_HPP diff --git a/include/Nazara/Utility/Animation.hpp b/include/Nazara/Utility/Animation.hpp index 6e6bd9c84..b4f5dde47 100644 --- a/include/Nazara/Utility/Animation.hpp +++ b/include/Nazara/Utility/Animation.hpp @@ -21,88 +21,91 @@ #include #include -struct NAZARA_UTILITY_API NzAnimationParams +namespace Nz { - // La frame de fin à charger - unsigned int endFrame = std::numeric_limits::max(); - // La frame de début à charger - unsigned int startFrame = 0; + struct NAZARA_UTILITY_API AnimationParams + { + // La frame de fin à charger + unsigned int endFrame = std::numeric_limits::max(); + // La frame de début à charger + unsigned int startFrame = 0; - bool IsValid() const; -}; - -class NzAnimation; -class NzSkeleton; - -using NzAnimationConstRef = NzObjectRef; -using NzAnimationLibrary = NzObjectLibrary; -using NzAnimationLoader = NzResourceLoader; -using NzAnimationManager = NzResourceManager; -using NzAnimationRef = NzObjectRef; - -struct NzAnimationImpl; - -class NAZARA_UTILITY_API NzAnimation : public NzRefCounted, public NzResource -{ - friend NzAnimationLibrary; - friend NzAnimationLoader; - friend NzAnimationManager; - friend class NzUtility; - - public: - NzAnimation() = default; - ~NzAnimation(); - - bool AddSequence(const NzSequence& sequence); - void AnimateSkeleton(NzSkeleton* targetSkeleton, unsigned int frameA, unsigned int frameB, float interpolation) const; - - bool CreateSkeletal(unsigned int frameCount, unsigned int jointCount); - void Destroy(); - - void EnableLoopPointInterpolation(bool loopPointInterpolation); - - unsigned int GetFrameCount() const; - unsigned int GetJointCount() const; - NzSequence* GetSequence(const NzString& sequenceName); - NzSequence* GetSequence(unsigned int index); - const NzSequence* GetSequence(const NzString& sequenceName) const; - const NzSequence* GetSequence(unsigned int index) const; - unsigned int GetSequenceCount() const; - int GetSequenceIndex(const NzString& sequenceName) const; - NzSequenceJoint* GetSequenceJoints(unsigned int frameIndex = 0); - const NzSequenceJoint* GetSequenceJoints(unsigned int frameIndex = 0) const; - nzAnimationType GetType() const; - - bool HasSequence(const NzString& sequenceName) const; - bool HasSequence(unsigned int index = 0) const; - - bool IsLoopPointInterpolationEnabled() const; bool IsValid() const; + }; - bool LoadFromFile(const NzString& filePath, const NzAnimationParams& params = NzAnimationParams()); - bool LoadFromMemory(const void* data, std::size_t size, const NzAnimationParams& params = NzAnimationParams()); - bool LoadFromStream(NzInputStream& stream, const NzAnimationParams& params = NzAnimationParams()); + class Animation; + class Skeleton; - void RemoveSequence(const NzString& sequenceName); - void RemoveSequence(unsigned int index); + using AnimationConstRef = ObjectRef; + using AnimationLibrary = ObjectLibrary; + using AnimationLoader = ResourceLoader; + using AnimationManager = ResourceManager; + using AnimationRef = ObjectRef; - template static NzAnimationRef New(Args&&... args); + struct AnimationImpl; - // Signals: - NazaraSignal(OnAnimationDestroy, const NzAnimation* /*animation*/); - NazaraSignal(OnAnimationRelease, const NzAnimation* /*animation*/); + class NAZARA_UTILITY_API Animation : public RefCounted, public Resource + { + friend AnimationLibrary; + friend AnimationLoader; + friend AnimationManager; + friend class Utility; - private: - static bool Initialize(); - static void Uninitialize(); + public: + Animation() = default; + ~Animation(); - NzAnimationImpl* m_impl = nullptr; + bool AddSequence(const Sequence& sequence); + void AnimateSkeleton(Skeleton* targetSkeleton, unsigned int frameA, unsigned int frameB, float interpolation) const; - static NzAnimationLibrary::LibraryMap s_library; - static NzAnimationLoader::LoaderList s_loaders; - static NzAnimationManager::ManagerMap s_managerMap; - static NzAnimationManager::ManagerParams s_managerParameters; -}; + bool CreateSkeletal(unsigned int frameCount, unsigned int jointCount); + void Destroy(); + + void EnableLoopPointInterpolation(bool loopPointInterpolation); + + unsigned int GetFrameCount() const; + unsigned int GetJointCount() const; + Sequence* GetSequence(const String& sequenceName); + Sequence* GetSequence(unsigned int index); + const Sequence* GetSequence(const String& sequenceName) const; + const Sequence* GetSequence(unsigned int index) const; + unsigned int GetSequenceCount() const; + int GetSequenceIndex(const String& sequenceName) const; + SequenceJoint* GetSequenceJoints(unsigned int frameIndex = 0); + const SequenceJoint* GetSequenceJoints(unsigned int frameIndex = 0) const; + AnimationType GetType() const; + + bool HasSequence(const String& sequenceName) const; + bool HasSequence(unsigned int index = 0) const; + + bool IsLoopPointInterpolationEnabled() const; + bool IsValid() const; + + bool LoadFromFile(const String& filePath, const AnimationParams& params = AnimationParams()); + bool LoadFromMemory(const void* data, std::size_t size, const AnimationParams& params = AnimationParams()); + bool LoadFromStream(InputStream& stream, const AnimationParams& params = AnimationParams()); + + void RemoveSequence(const String& sequenceName); + void RemoveSequence(unsigned int index); + + template static AnimationRef New(Args&&... args); + + // Signals: + NazaraSignal(OnAnimationDestroy, const Animation* /*animation*/); + NazaraSignal(OnAnimationRelease, const Animation* /*animation*/); + + private: + static bool Initialize(); + static void Uninitialize(); + + AnimationImpl* m_impl = nullptr; + + static AnimationLibrary::LibraryMap s_library; + static AnimationLoader::LoaderList s_loaders; + static AnimationManager::ManagerMap s_managerMap; + static AnimationManager::ManagerParams s_managerParameters; + }; +} #include diff --git a/include/Nazara/Utility/Animation.inl b/include/Nazara/Utility/Animation.inl index 77f60c01c..0ae58c0f4 100644 --- a/include/Nazara/Utility/Animation.inl +++ b/include/Nazara/Utility/Animation.inl @@ -5,13 +5,16 @@ #include #include -template -NzAnimationRef NzAnimation::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzAnimation(std::forward(args)...)); - object->SetPersistent(false); + template + AnimationRef Animation::New(Args&&... args) + { + std::unique_ptr object(new Animation(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Utility/Buffer.hpp b/include/Nazara/Utility/Buffer.hpp index 89f48f241..5ee866ae2 100644 --- a/include/Nazara/Utility/Buffer.hpp +++ b/include/Nazara/Utility/Buffer.hpp @@ -14,72 +14,75 @@ #include #include -class NzBuffer; - -using NzBufferConstRef = NzObjectRef; -using NzBufferRef = NzObjectRef; - -class NzAbstractBuffer; - -class NAZARA_UTILITY_API NzBuffer : public NzRefCounted +namespace Nz { - friend class NzUtility; + class Buffer; - public: - using BufferFactory = NzAbstractBuffer* (*)(NzBuffer* parent, nzBufferType type); + using BufferConstRef = ObjectRef; + using BufferRef = ObjectRef; - NzBuffer(nzBufferType type); - NzBuffer(nzBufferType type, unsigned int size, nzUInt32 storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); - NzBuffer(const NzBuffer&) = delete; - NzBuffer(NzBuffer&&) = delete; - ~NzBuffer(); + class AbstractBuffer; - bool CopyContent(const NzBuffer& buffer); + class NAZARA_UTILITY_API Buffer : public RefCounted + { + friend class Utility; - bool Create(unsigned int size, nzUInt32 storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); - void Destroy(); + public: + using BufferFactory = AbstractBuffer* (*)(Buffer* parent, BufferType type); - bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false); + Buffer(BufferType type); + Buffer(BufferType type, unsigned int size, UInt32 storage = DataStorage_Software, BufferUsage usage = BufferUsage_Static); + Buffer(const Buffer&) = delete; + Buffer(Buffer&&) = delete; + ~Buffer(); - NzAbstractBuffer* GetImpl() const; - unsigned int GetSize() const; - nzUInt32 GetStorage() const; - nzBufferType GetType() const; - nzBufferUsage GetUsage() const; + bool CopyContent(const Buffer& buffer); - bool IsHardware() const; - bool IsValid() const; + bool Create(unsigned int size, UInt32 storage = DataStorage_Software, BufferUsage usage = BufferUsage_Static); + void Destroy(); - void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0); - void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0) const; + bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false); - bool SetStorage(nzUInt32 storage); + AbstractBuffer* GetImpl() const; + unsigned int GetSize() const; + UInt32 GetStorage() const; + BufferType GetType() const; + BufferUsage GetUsage() const; - void Unmap() const; + bool IsHardware() const; + bool IsValid() const; - NzBuffer& operator=(const NzBuffer&) = delete; - NzBuffer& operator=(NzBuffer&&) = delete; + void* Map(BufferAccess access, unsigned int offset = 0, unsigned int size = 0); + void* Map(BufferAccess access, unsigned int offset = 0, unsigned int size = 0) const; - static bool IsStorageSupported(nzUInt32 storage); - template static NzBufferRef New(Args&&... args); - static void SetBufferFactory(nzUInt32 storage, BufferFactory func); + bool SetStorage(UInt32 storage); - // Signals: - NazaraSignal(OnBufferDestroy, const NzBuffer* /*buffer*/); - NazaraSignal(OnBufferRelease, const NzBuffer* /*buffer*/); + void Unmap() const; - private: - static bool Initialize(); - static void Uninitialize(); + Buffer& operator=(const Buffer&) = delete; + Buffer& operator=(Buffer&&) = delete; - nzBufferType m_type; - nzBufferUsage m_usage; - nzUInt32 m_storage; - NzAbstractBuffer* m_impl; - unsigned int m_size; + static bool IsStorageSupported(UInt32 storage); + template static BufferRef New(Args&&... args); + static void SetBufferFactory(UInt32 storage, BufferFactory func); - static BufferFactory s_bufferFactories[nzDataStorage_Max+1]; -}; + // Signals: + NazaraSignal(OnBufferDestroy, const Buffer* /*buffer*/); + NazaraSignal(OnBufferRelease, const Buffer* /*buffer*/); + + private: + static bool Initialize(); + static void Uninitialize(); + + BufferType m_type; + BufferUsage m_usage; + UInt32 m_storage; + AbstractBuffer* m_impl; + unsigned int m_size; + + static BufferFactory s_bufferFactories[DataStorage_Max+1]; + }; +} #include diff --git a/include/Nazara/Utility/Buffer.inl b/include/Nazara/Utility/Buffer.inl index 89d8f679e..8703fd82c 100644 --- a/include/Nazara/Utility/Buffer.inl +++ b/include/Nazara/Utility/Buffer.inl @@ -5,13 +5,16 @@ #include #include -template -NzBufferRef NzBuffer::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzBuffer(std::forward(args)...)); - object->SetPersistent(false); + template + BufferRef Buffer::New(Args&&... args) + { + std::unique_ptr object(new Buffer(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Utility/BufferMapper.hpp b/include/Nazara/Utility/BufferMapper.hpp index 814d78f8b..b34c41c73 100644 --- a/include/Nazara/Utility/BufferMapper.hpp +++ b/include/Nazara/Utility/BufferMapper.hpp @@ -9,31 +9,34 @@ #include -template -class NzBufferMapper +namespace Nz { - public: - NzBufferMapper(); - NzBufferMapper(T* buffer, nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0); - NzBufferMapper(T& buffer, nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0); - NzBufferMapper(const T* buffer, nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0); - NzBufferMapper(const T& buffer, nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0); - ~NzBufferMapper(); + template + class BufferMapper + { + public: + BufferMapper(); + BufferMapper(T* buffer, BufferAccess access, unsigned int offset = 0, unsigned int length = 0); + BufferMapper(T& buffer, BufferAccess access, unsigned int offset = 0, unsigned int length = 0); + BufferMapper(const T* buffer, BufferAccess access, unsigned int offset = 0, unsigned int length = 0); + BufferMapper(const T& buffer, BufferAccess access, unsigned int offset = 0, unsigned int length = 0); + ~BufferMapper(); - bool Map(T* buffer, nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0); - bool Map(T& buffer, nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0); - bool Map(const T* buffer, nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0); - bool Map(const T& buffer, nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0); + bool Map(T* buffer, BufferAccess access, unsigned int offset = 0, unsigned int length = 0); + bool Map(T& buffer, BufferAccess access, unsigned int offset = 0, unsigned int length = 0); + bool Map(const T* buffer, BufferAccess access, unsigned int offset = 0, unsigned int length = 0); + bool Map(const T& buffer, BufferAccess access, unsigned int offset = 0, unsigned int length = 0); - const T* GetBuffer() const; - void* GetPointer() const; + const T* GetBuffer() const; + void* GetPointer() const; - void Unmap(); + void Unmap(); - private: - const T* m_buffer; - void* m_ptr; -}; + private: + const T* m_buffer; + void* m_ptr; + }; +} #include diff --git a/include/Nazara/Utility/BufferMapper.inl b/include/Nazara/Utility/BufferMapper.inl index 1f6499c85..1284ba26d 100644 --- a/include/Nazara/Utility/BufferMapper.inl +++ b/include/Nazara/Utility/BufferMapper.inl @@ -7,125 +7,128 @@ #include #include -template -NzBufferMapper::NzBufferMapper() : -m_buffer(nullptr), -m_ptr(nullptr) +namespace Nz { -} - -template -NzBufferMapper::NzBufferMapper(T* buffer, nzBufferAccess access, unsigned int offset, unsigned int length) : -m_buffer(nullptr) -{ - if (!Map(buffer, access, offset, length)) - NazaraError("Failed to map buffer"); ///TODO: Unexpected -} - -template -NzBufferMapper::NzBufferMapper(T& buffer, nzBufferAccess access, unsigned int offset, unsigned int length) : -NzBufferMapper(&buffer, access, offset, length) -{ -} - -template -NzBufferMapper::NzBufferMapper(const T* buffer, nzBufferAccess access, unsigned int offset, unsigned int length) : -m_buffer(nullptr) -{ - if (!Map(buffer, access, offset, length)) - NazaraError("Failed to map buffer"); ///TODO: Unexpected -} - -template -NzBufferMapper::NzBufferMapper(const T& buffer, nzBufferAccess access, unsigned int offset, unsigned int length) : -NzBufferMapper(&buffer, access, offset, length) -{ -} - -template -NzBufferMapper::~NzBufferMapper() -{ - if (m_buffer) - m_buffer->Unmap(); -} - -template -const T* NzBufferMapper::GetBuffer() const -{ - return m_buffer; -} - -template -void* NzBufferMapper::GetPointer() const -{ - return m_ptr; -} - -template -bool NzBufferMapper::Map(T* buffer, nzBufferAccess access, unsigned int offset, unsigned int length) -{ - Unmap(); - - #if NAZARA_UTILITY_SAFE - if (!buffer) + template + BufferMapper::BufferMapper() : + m_buffer(nullptr), + m_ptr(nullptr) { - NazaraError("Buffer must be valid"); - m_ptr = nullptr; - - return false; } - #endif - m_buffer = buffer; - m_ptr = buffer->Map(access, offset, length); - if (!m_ptr) - NazaraError("Failed to map buffer"); ///TODO: Unexpected - - return true; -} - -template -bool NzBufferMapper::Map(T& buffer, nzBufferAccess access, unsigned int offset, unsigned int length) -{ - return Map(&buffer, access, offset, length); -} - -template -bool NzBufferMapper::Map(const T* buffer, nzBufferAccess access, unsigned int offset, unsigned int length) -{ - Unmap(); - - #if NAZARA_UTILITY_SAFE - if (!buffer) + template + BufferMapper::BufferMapper(T* buffer, BufferAccess access, unsigned int offset, unsigned int length) : + m_buffer(nullptr) { - NazaraError("Buffer must be valid"); - m_ptr = nullptr; - - return false; + if (!Map(buffer, access, offset, length)) + NazaraError("Failed to map buffer"); ///TODO: Unexpected } - #endif - m_buffer = buffer; - m_ptr = buffer->Map(access, offset, length); - if (!m_ptr) - NazaraError("Failed to map buffer"); ///TODO: Unexpected - - return true; -} - -template -bool NzBufferMapper::Map(const T& buffer, nzBufferAccess access, unsigned int offset, unsigned int length) -{ - return Map(&buffer, access, offset, length); -} - -template -void NzBufferMapper::Unmap() -{ - if (m_buffer) + template + BufferMapper::BufferMapper(T& buffer, BufferAccess access, unsigned int offset, unsigned int length) : + BufferMapper(&buffer, access, offset, length) { - m_buffer->Unmap(); - m_buffer = nullptr; + } + + template + BufferMapper::BufferMapper(const T* buffer, BufferAccess access, unsigned int offset, unsigned int length) : + m_buffer(nullptr) + { + if (!Map(buffer, access, offset, length)) + NazaraError("Failed to map buffer"); ///TODO: Unexpected + } + + template + BufferMapper::BufferMapper(const T& buffer, BufferAccess access, unsigned int offset, unsigned int length) : + BufferMapper(&buffer, access, offset, length) + { + } + + template + BufferMapper::~BufferMapper() + { + if (m_buffer) + m_buffer->Unmap(); + } + + template + const T* BufferMapper::GetBuffer() const + { + return m_buffer; + } + + template + void* BufferMapper::GetPointer() const + { + return m_ptr; + } + + template + bool BufferMapper::Map(T* buffer, BufferAccess access, unsigned int offset, unsigned int length) + { + Unmap(); + + #if NAZARA_UTILITY_SAFE + if (!buffer) + { + NazaraError("Buffer must be valid"); + m_ptr = nullptr; + + return false; + } + #endif + + m_buffer = buffer; + m_ptr = buffer->Map(access, offset, length); + if (!m_ptr) + NazaraError("Failed to map buffer"); ///TODO: Unexpected + + return true; + } + + template + bool BufferMapper::Map(T& buffer, BufferAccess access, unsigned int offset, unsigned int length) + { + return Map(&buffer, access, offset, length); + } + + template + bool BufferMapper::Map(const T* buffer, BufferAccess access, unsigned int offset, unsigned int length) + { + Unmap(); + + #if NAZARA_UTILITY_SAFE + if (!buffer) + { + NazaraError("Buffer must be valid"); + m_ptr = nullptr; + + return false; + } + #endif + + m_buffer = buffer; + m_ptr = buffer->Map(access, offset, length); + if (!m_ptr) + NazaraError("Failed to map buffer"); ///TODO: Unexpected + + return true; + } + + template + bool BufferMapper::Map(const T& buffer, BufferAccess access, unsigned int offset, unsigned int length) + { + return Map(&buffer, access, offset, length); + } + + template + void BufferMapper::Unmap() + { + if (m_buffer) + { + m_buffer->Unmap(); + m_buffer = nullptr; + } } } diff --git a/include/Nazara/Utility/CubemapParams.hpp b/include/Nazara/Utility/CubemapParams.hpp index a9e82e299..0f9e6eba4 100644 --- a/include/Nazara/Utility/CubemapParams.hpp +++ b/include/Nazara/Utility/CubemapParams.hpp @@ -9,27 +9,30 @@ #include -struct NzCubemapParams +namespace Nz { - /* - La position de chaque face dans la cubemap - Les indices ici seront multipliés à la taille d'une face pour obtenir le coin haut-gauche de la zone. - Si la taille d'une face est 0, elle sera calculée via max(width, height)/4. + struct CubemapParams + { + /* + La position de chaque face dans la cubemap + Les indices ici seront multipliés à la taille d'une face pour obtenir le coin haut-gauche de la zone. + Si la taille d'une face est 0, elle sera calculée via max(width, height)/4. - Par défaut, cela suit ce layout : - U - L F R B - D + Par défaut, cela suit ce layout : + U + L F R B + D - Si ce n'est pas le cas, à vous de repositionner les faces correctement. - */ - NzVector2ui backPosition = NzVector2ui(3, 1); - NzVector2ui downPosition = NzVector2ui(1, 2); - NzVector2ui forwardPosition = NzVector2ui(1, 1); - NzVector2ui leftPosition = NzVector2ui(0, 1); - NzVector2ui rightPosition = NzVector2ui(2, 1); - NzVector2ui upPosition = NzVector2ui(1, 0); - unsigned int faceSize = 0; -}; + Si ce n'est pas le cas, à vous de repositionner les faces correctement. + */ + Vector2ui backPosition = Vector2ui(3, 1); + Vector2ui downPosition = Vector2ui(1, 2); + Vector2ui forwardPosition = Vector2ui(1, 1); + Vector2ui leftPosition = Vector2ui(0, 1); + Vector2ui rightPosition = Vector2ui(2, 1); + Vector2ui upPosition = Vector2ui(1, 0); + unsigned int faceSize = 0; + }; +} #endif // NAZARA_CUBEMAPPARAMS_HPP diff --git a/include/Nazara/Utility/Cursor.hpp b/include/Nazara/Utility/Cursor.hpp index aebc481ce..b45fc6a1b 100644 --- a/include/Nazara/Utility/Cursor.hpp +++ b/include/Nazara/Utility/Cursor.hpp @@ -11,25 +11,28 @@ #include #include -class NzCursorImpl; -class NzImage; - -class NAZARA_UTILITY_API NzCursor +namespace Nz { - friend class NzWindowImpl; + class CursorImpl; + class Image; - public: - NzCursor(); - ~NzCursor(); + class NAZARA_UTILITY_API Cursor + { + friend class WindowImpl; - bool Create(const NzImage& cursor, int hotSpotX = 0, int hotSpotY = 0); - bool Create(const NzImage& cursor, const NzVector2i& hotSpot); - void Destroy(); + public: + Cursor(); + ~Cursor(); - bool IsValid() const; + bool Create(const Image& cursor, int hotSpotX = 0, int hotSpotY = 0); + bool Create(const Image& cursor, const Vector2i& hotSpot); + void Destroy(); - private: - NzCursorImpl* m_impl; -}; + bool IsValid() const; + + private: + CursorImpl* m_impl; + }; +} #endif // NAZARA_CURSOR_HPP diff --git a/include/Nazara/Utility/Enums.hpp b/include/Nazara/Utility/Enums.hpp index 49d66c2af..d2b58959c 100644 --- a/include/Nazara/Utility/Enums.hpp +++ b/include/Nazara/Utility/Enums.hpp @@ -7,326 +7,329 @@ #ifndef NAZARA_ENUMS_UTILITY_HPP #define NAZARA_ENUMS_UTILITY_HPP -enum nzAnimationType +namespace Nz { - nzAnimationType_Skeletal, - nzAnimationType_Static, + enum AnimationType + { + AnimationType_Skeletal, + AnimationType_Static, - nzAnimationType_Max = nzAnimationType_Static -}; + AnimationType_Max = AnimationType_Static + }; -enum nzBufferAccess -{ - nzBufferAccess_DiscardAndWrite, - nzBufferAccess_ReadOnly, - nzBufferAccess_ReadWrite, - nzBufferAccess_WriteOnly, + enum BufferAccess + { + BufferAccess_DiscardAndWrite, + BufferAccess_ReadOnly, + BufferAccess_ReadWrite, + BufferAccess_WriteOnly, - nzBufferAccess_Max = nzBufferAccess_WriteOnly -}; + BufferAccess_Max = BufferAccess_WriteOnly + }; -enum nzBufferType -{ - nzBufferType_Index, - nzBufferType_Vertex, + enum BufferType + { + BufferType_Index, + BufferType_Vertex, - nzBufferType_Max = nzBufferType_Vertex -}; + BufferType_Max = BufferType_Vertex + }; -enum nzBufferUsage -{ - nzBufferUsage_Dynamic, - nzBufferUsage_Static, + enum BufferUsage + { + BufferUsage_Dynamic, + BufferUsage_Static, - nzBufferUsage_Max = nzBufferUsage_Static -}; + BufferUsage_Max = BufferUsage_Static + }; -enum nzComponentType -{ - nzComponentType_Color, - nzComponentType_Double1, - nzComponentType_Double2, - nzComponentType_Double3, - nzComponentType_Double4, - nzComponentType_Float1, - nzComponentType_Float2, - nzComponentType_Float3, - nzComponentType_Float4, - nzComponentType_Int1, - nzComponentType_Int2, - nzComponentType_Int3, - nzComponentType_Int4, - nzComponentType_Quaternion, + enum ComponentType + { + ComponentType_Color, + ComponentType_Double1, + ComponentType_Double2, + ComponentType_Double3, + ComponentType_Double4, + ComponentType_Float1, + ComponentType_Float2, + ComponentType_Float3, + ComponentType_Float4, + ComponentType_Int1, + ComponentType_Int2, + ComponentType_Int3, + ComponentType_Int4, + ComponentType_Quaternion, - nzComponentType_Max = nzComponentType_Quaternion -}; + ComponentType_Max = ComponentType_Quaternion + }; -enum nzCubemapFace -{ - // Cette énumération est prévue pour remplacer l'argument "z" des méthodes de NzImage contenant un cubemap - // L'ordre est X, -X, Y, -Y, Z, -Z - nzCubemapFace_PositiveX = 0, - nzCubemapFace_PositiveY = 2, - nzCubemapFace_PositiveZ = 4, - nzCubemapFace_NegativeX = 1, - nzCubemapFace_NegativeY = 3, - nzCubemapFace_NegativeZ = 5, + enum CubemapFace + { + // Cette énumération est prévue pour remplacer l'argument "z" des méthodes de Image contenant un cubemap + // L'ordre est X, -X, Y, -Y, Z, -Z + CubemapFace_PositiveX = 0, + CubemapFace_PositiveY = 2, + CubemapFace_PositiveZ = 4, + CubemapFace_NegativeX = 1, + CubemapFace_NegativeY = 3, + CubemapFace_NegativeZ = 5, - nzCubemapFace_Max = nzCubemapFace_NegativeZ -}; + CubemapFace_Max = CubemapFace_NegativeZ + }; -enum nzDataStorageFlags -{ - nzDataStorage_Hardware = 0x1, - nzDataStorage_Software = 0x2, + enum DataStorageFlags + { + DataStorage_Hardware = 0x1, + DataStorage_Software = 0x2, - nzDataStorage_Both = nzDataStorage_Hardware | nzDataStorage_Software, + DataStorage_Both = DataStorage_Hardware | DataStorage_Software, - nzDataStorage_Max = nzDataStorage_Software*2-1 -}; + DataStorage_Max = DataStorage_Software*2-1 + }; -enum nzEventType -{ - nzEventType_GainedFocus, - nzEventType_LostFocus, - nzEventType_KeyPressed, - nzEventType_KeyReleased, - nzEventType_MouseButtonDoubleClicked, - nzEventType_MouseButtonPressed, - nzEventType_MouseButtonReleased, - nzEventType_MouseEntered, - nzEventType_MouseLeft, - nzEventType_MouseMoved, - nzEventType_MouseWheelMoved, - nzEventType_Moved, - nzEventType_Quit, - nzEventType_Resized, - nzEventType_TextEntered, + enum ImageType + { + ImageType_1D, + ImageType_1D_Array, + ImageType_2D, + ImageType_2D_Array, + ImageType_3D, + ImageType_Cubemap, - nzEventType_Max = nzEventType_TextEntered -}; + ImageType_Max = ImageType_Cubemap + }; -enum nzImageType -{ - nzImageType_1D, - nzImageType_1D_Array, - nzImageType_2D, - nzImageType_2D_Array, - nzImageType_3D, - nzImageType_Cubemap, + enum nzNodeType + { + nzNodeType_Default, // Node + nzNodeType_Scene, // SceneNode (Graphics) + nzNodeType_Skeletal, ///TODO - nzImageType_Max = nzImageType_Cubemap -}; + nzNodeType_Max = nzNodeType_Skeletal + }; -enum nzNodeType -{ - nzNodeType_Default, // NzNode - nzNodeType_Scene, // NzSceneNode (Graphics) - nzNodeType_Skeletal, ///TODO + enum PixelFormatType + { + PixelFormatType_Undefined = -1, - nzNodeType_Max = nzNodeType_Skeletal -}; + PixelFormatType_A8, // 1*uint8 + PixelFormatType_BGR8, // 3*uint8 + PixelFormatType_BGRA8, // 4*uint8 + PixelFormatType_DXT1, + PixelFormatType_DXT3, + PixelFormatType_DXT5, + PixelFormatType_L8, // 1*uint8 + PixelFormatType_LA8, // 2*uint8 + PixelFormatType_R8, // 1*uint8 + PixelFormatType_R8I, // 1*int8 + PixelFormatType_R8UI, // 1*uint8 + PixelFormatType_R16, // 1*uint16 + PixelFormatType_R16F, // 1*half + PixelFormatType_R16I, // 1*int16 + PixelFormatType_R16UI, // 1*uint16 + PixelFormatType_R32F, // 1*float + PixelFormatType_R32I, // 1*uint16 + PixelFormatType_R32UI, // 1*uint32 + PixelFormatType_RG8, // 2*int8 + PixelFormatType_RG8I, // 2*int8 + PixelFormatType_RG8UI, // 2*uint8 + PixelFormatType_RG16, // 2*uint16 + PixelFormatType_RG16F, // 2*half + PixelFormatType_RG16I, // 2*int16 + PixelFormatType_RG16UI, // 2*uint16 + PixelFormatType_RG32F, // 2*float + PixelFormatType_RG32I, // 2*uint16 + PixelFormatType_RG32UI, // 2*uint32 + PixelFormatType_RGB5A1, // 3*uint5 + alpha bit + PixelFormatType_RGB8, // 3*uint8 + PixelFormatType_RGB16F, // 3*half + PixelFormatType_RGB16I, // 4*int16 + PixelFormatType_RGB16UI, // 4*uint16 + PixelFormatType_RGB32F, // 3*float + PixelFormatType_RGB32I, // 4*int32 + PixelFormatType_RGB32UI, // 4*uint32 + PixelFormatType_RGBA4, // 4*uint4 + PixelFormatType_RGBA8, // 4*uint8 + PixelFormatType_RGBA16F, // 4*half + PixelFormatType_RGBA16I, // 4*int16 + PixelFormatType_RGBA16UI, // 4*uint16 + PixelFormatType_RGBA32F, // 4*float + PixelFormatType_RGBA32I, // 4*int32 + PixelFormatType_RGBA32UI, // 4*uint32 + PixelFormatType_Depth16, + PixelFormatType_Depth24, + PixelFormatType_Depth24Stencil8, + PixelFormatType_Depth32, + PixelFormatType_Stencil1, + PixelFormatType_Stencil4, + PixelFormatType_Stencil8, + PixelFormatType_Stencil16, -enum nzPixelFormat -{ - nzPixelFormat_Undefined = -1, + PixelFormatType_Max = PixelFormatType_Stencil16 + }; - nzPixelFormat_A8, // 1*uint8 - nzPixelFormat_BGR8, // 3*uint8 - nzPixelFormat_BGRA8, // 4*uint8 - nzPixelFormat_DXT1, - nzPixelFormat_DXT3, - nzPixelFormat_DXT5, - nzPixelFormat_L8, // 1*uint8 - nzPixelFormat_LA8, // 2*uint8 - nzPixelFormat_R8, // 1*uint8 - nzPixelFormat_R8I, // 1*int8 - nzPixelFormat_R8UI, // 1*uint8 - nzPixelFormat_R16, // 1*uint16 - nzPixelFormat_R16F, // 1*half - nzPixelFormat_R16I, // 1*int16 - nzPixelFormat_R16UI, // 1*uint16 - nzPixelFormat_R32F, // 1*float - nzPixelFormat_R32I, // 1*uint16 - nzPixelFormat_R32UI, // 1*uint32 - nzPixelFormat_RG8, // 2*int8 - nzPixelFormat_RG8I, // 2*int8 - nzPixelFormat_RG8UI, // 2*uint8 - nzPixelFormat_RG16, // 2*uint16 - nzPixelFormat_RG16F, // 2*half - nzPixelFormat_RG16I, // 2*int16 - nzPixelFormat_RG16UI, // 2*uint16 - nzPixelFormat_RG32F, // 2*float - nzPixelFormat_RG32I, // 2*uint16 - nzPixelFormat_RG32UI, // 2*uint32 - nzPixelFormat_RGB5A1, // 3*uint5 + alpha bit - nzPixelFormat_RGB8, // 3*uint8 - nzPixelFormat_RGB16F, // 3*half - nzPixelFormat_RGB16I, // 4*int16 - nzPixelFormat_RGB16UI, // 4*uint16 - nzPixelFormat_RGB32F, // 3*float - nzPixelFormat_RGB32I, // 4*int32 - nzPixelFormat_RGB32UI, // 4*uint32 - nzPixelFormat_RGBA4, // 4*uint4 - nzPixelFormat_RGBA8, // 4*uint8 - nzPixelFormat_RGBA16F, // 4*half - nzPixelFormat_RGBA16I, // 4*int16 - nzPixelFormat_RGBA16UI, // 4*uint16 - nzPixelFormat_RGBA32F, // 4*float - nzPixelFormat_RGBA32I, // 4*int32 - nzPixelFormat_RGBA32UI, // 4*uint32 - nzPixelFormat_Depth16, - nzPixelFormat_Depth24, - nzPixelFormat_Depth24Stencil8, - nzPixelFormat_Depth32, - nzPixelFormat_Stencil1, - nzPixelFormat_Stencil4, - nzPixelFormat_Stencil8, - nzPixelFormat_Stencil16, + enum PixelFormatTypeType + { + PixelFormatTypeType_Undefined = -1, - nzPixelFormat_Max = nzPixelFormat_Stencil16 -}; + PixelFormatTypeType_Color, + PixelFormatTypeType_Depth, + PixelFormatTypeType_DepthStencil, + PixelFormatTypeType_Stencil, -enum nzPixelFormatType -{ - nzPixelFormatType_Undefined = -1, + PixelFormatTypeType_Max = PixelFormatTypeType_Stencil + }; - nzPixelFormatType_Color, - nzPixelFormatType_Depth, - nzPixelFormatType_DepthStencil, - nzPixelFormatType_Stencil, + enum PixelFlipping + { + PixelFlipping_Horizontally, + PixelFlipping_Vertically, - nzPixelFormatType_Max = nzPixelFormatType_Stencil -}; + PixelFlipping_Max = PixelFlipping_Vertically + }; -enum nzPixelFlipping -{ - nzPixelFlipping_Horizontally, - nzPixelFlipping_Vertically, + enum PrimitiveMode + { + PrimitiveMode_LineList, + PrimitiveMode_LineStrip, + PrimitiveMode_PointList, + PrimitiveMode_TriangleList, + PrimitiveMode_TriangleStrip, + PrimitiveMode_TriangleFan, - nzPixelFlipping_Max = nzPixelFlipping_Vertically -}; + PrimitiveMode_Max = PrimitiveMode_TriangleFan + }; -enum nzPrimitiveMode -{ - nzPrimitiveMode_LineList, - nzPrimitiveMode_LineStrip, - nzPrimitiveMode_PointList, - nzPrimitiveMode_TriangleList, - nzPrimitiveMode_TriangleStrip, - nzPrimitiveMode_TriangleFan, + enum TextAlign + { + TextAlign_Left, + TextAlign_Middle, + TextAlign_Right, - nzPrimitiveMode_Max = nzPrimitiveMode_TriangleFan -}; + TextAlign_Max = TextAlign_Right + }; -enum nzTextAlign -{ - nzTextAlign_Left, - nzTextAlign_Middle, - nzTextAlign_Right, + enum TextStyleFlags + { + TextStyle_Regular = 0x0, - nzTextAlign_Max = nzTextAlign_Right -}; + TextStyle_Bold = 0x1, + TextStyle_Italic = 0x2, + TextStyle_StrikeThrough = 0x4, + TextStyle_Underlined = 0x8, -enum nzTextStyleFlags -{ - nzTextStyle_Regular = 0x0, + TextStyle_Max = TextStyle_Underlined*2-1 + }; - nzTextStyle_Bold = 0x1, - nzTextStyle_Italic = 0x2, - nzTextStyle_StrikeThrough = 0x4, - nzTextStyle_Underlined = 0x8, + enum VertexComponent + { + VertexComponent_Unused = -1, - nzTextStyle_Max = nzTextStyle_Underlined*2-1 -}; + // Nous nous limitons à 16 composants de sommets car c'est le minimum supporté par le GPU + VertexComponent_InstanceData0, + VertexComponent_InstanceData1, + VertexComponent_InstanceData2, + VertexComponent_InstanceData3, + VertexComponent_InstanceData4, + VertexComponent_InstanceData5, + VertexComponent_Color, + VertexComponent_Normal, + VertexComponent_Position, + VertexComponent_Tangent, + VertexComponent_TexCoord, + VertexComponent_Userdata0, + VertexComponent_Userdata1, + VertexComponent_Userdata2, + VertexComponent_Userdata3, + VertexComponent_Userdata4, -enum nzVertexComponent -{ - nzVertexComponent_Unused = -1, + VertexComponent_FirstInstanceData = VertexComponent_InstanceData0, + VertexComponent_FirstVertexData = VertexComponent_Color, + VertexComponent_LastInstanceData = VertexComponent_InstanceData5, + VertexComponent_LastVertexData = VertexComponent_Userdata4, - // Nous nous limitons à 16 composants de sommets car c'est le minimum supporté par le GPU - nzVertexComponent_InstanceData0, - nzVertexComponent_InstanceData1, - nzVertexComponent_InstanceData2, - nzVertexComponent_InstanceData3, - nzVertexComponent_InstanceData4, - nzVertexComponent_InstanceData5, - nzVertexComponent_Color, - nzVertexComponent_Normal, - nzVertexComponent_Position, - nzVertexComponent_Tangent, - nzVertexComponent_TexCoord, - nzVertexComponent_Userdata0, - nzVertexComponent_Userdata1, - nzVertexComponent_Userdata2, - nzVertexComponent_Userdata3, - nzVertexComponent_Userdata4, + VertexComponent_Max = VertexComponent_Userdata4 + }; - nzVertexComponent_FirstInstanceData = nzVertexComponent_InstanceData0, - nzVertexComponent_FirstVertexData = nzVertexComponent_Color, - nzVertexComponent_LastInstanceData = nzVertexComponent_InstanceData5, - nzVertexComponent_LastVertexData = nzVertexComponent_Userdata4, + enum VertexLayout + { + // Déclarations destinées au rendu + VertexLayout_XY, + VertexLayout_XY_Color, + VertexLayout_XY_UV, + VertexLayout_XYZ, + VertexLayout_XYZ_Color, + VertexLayout_XYZ_Color_UV, + VertexLayout_XYZ_Normal, + VertexLayout_XYZ_Normal_UV, + VertexLayout_XYZ_Normal_UV_Tangent, + VertexLayout_XYZ_Normal_UV_Tangent_Skinning, + VertexLayout_XYZ_UV, - nzVertexComponent_Max = nzVertexComponent_Userdata4 -}; + // Déclarations destinées à l'instancing + VertexLayout_Matrix4, -enum nzVertexLayout -{ - // Déclarations destinées au rendu - nzVertexLayout_XY, - nzVertexLayout_XY_Color, - nzVertexLayout_XY_UV, - nzVertexLayout_XYZ, - nzVertexLayout_XYZ_Color, - nzVertexLayout_XYZ_Color_UV, - nzVertexLayout_XYZ_Normal, - nzVertexLayout_XYZ_Normal_UV, - nzVertexLayout_XYZ_Normal_UV_Tangent, - nzVertexLayout_XYZ_Normal_UV_Tangent_Skinning, - nzVertexLayout_XYZ_UV, + VertexLayout_Max = VertexLayout_Matrix4 + }; - // Déclarations destinées à l'instancing - nzVertexLayout_Matrix4, + enum WindowCursor + { + WindowCursor_None, + WindowCursor_Default, - nzVertexLayout_Max = nzVertexLayout_Matrix4 -}; + WindowCursor_Crosshair, + WindowCursor_Hand, + WindowCursor_Help, + WindowCursor_Move, + WindowCursor_Pointer, + WindowCursor_Progress, + WindowCursor_ResizeE, + WindowCursor_ResizeN, + WindowCursor_ResizeNE, + WindowCursor_ResizeNW, + WindowCursor_ResizeS, + WindowCursor_ResizeSE, + WindowCursor_ResizeSW, + WindowCursor_ResizeW, + WindowCursor_Text, + WindowCursor_Wait, -enum nzWindowCursor -{ - nzWindowCursor_None, - nzWindowCursor_Default, + WindowCursor_Max = WindowCursor_Wait + }; - nzWindowCursor_Crosshair, - nzWindowCursor_Hand, - nzWindowCursor_Help, - nzWindowCursor_Move, - nzWindowCursor_Pointer, - nzWindowCursor_Progress, - nzWindowCursor_ResizeE, - nzWindowCursor_ResizeN, - nzWindowCursor_ResizeNE, - nzWindowCursor_ResizeNW, - nzWindowCursor_ResizeS, - nzWindowCursor_ResizeSE, - nzWindowCursor_ResizeSW, - nzWindowCursor_ResizeW, - nzWindowCursor_Text, - nzWindowCursor_Wait, + enum WindowEventType + { + WindowEventType_GainedFocus, + WindowEventType_LostFocus, + WindowEventType_KeyPressed, + WindowEventType_KeyReleased, + WindowEventType_MouseButtonDoubleClicked, + WindowEventType_MouseButtonPressed, + WindowEventType_MouseButtonReleased, + WindowEventType_MouseEntered, + WindowEventType_MouseLeft, + WindowEventType_MouseMoved, + WindowEventType_MouseWheelMoved, + WindowEventType_Moved, + WindowEventType_Quit, + WindowEventType_Resized, + WindowEventType_TextEntered, - nzWindowCursor_Max = nzWindowCursor_Wait -}; + WindowEventType_Max = WindowEventType_TextEntered + }; -enum nzWindowStyleFlags -{ - nzWindowStyle_None = 0x0, - nzWindowStyle_Fullscreen = 0x1, + enum WindowStyleFlags + { + WindowStyle_None = 0x0, + WindowStyle_Fullscreen = 0x1, - nzWindowStyle_Closable = 0x2, - nzWindowStyle_Resizable = 0x4, - nzWindowStyle_Titlebar = 0x8, + WindowStyle_Closable = 0x2, + WindowStyle_Resizable = 0x4, + WindowStyle_Titlebar = 0x8, - nzWindowStyle_Default = nzWindowStyle_Closable | nzWindowStyle_Resizable | nzWindowStyle_Titlebar, - nzWindowStyle_Max = nzWindowStyle_Titlebar*2-1 -}; + WindowStyle_Default = WindowStyle_Closable | WindowStyle_Resizable | WindowStyle_Titlebar, + WindowStyle_Max = WindowStyle_Titlebar*2-1 + }; +} #endif // NAZARA_ENUMS_UTILITY_HPP diff --git a/include/Nazara/Utility/Event.hpp b/include/Nazara/Utility/Event.hpp index 0403bd51e..c5535abff 100644 --- a/include/Nazara/Utility/Event.hpp +++ b/include/Nazara/Utility/Event.hpp @@ -13,106 +13,109 @@ #include #include -struct NzEvent +namespace Nz { - // Utilisé par: - // -nzEventType_KeyPressed - // -nzEventType_KeyReleased - struct KeyEvent - { - NzKeyboard::Key code; - bool alt; - bool control; - bool repeated; - bool shift; - bool system; - }; - - // Utilisé par: - // -nzEventType_MouseButtonDoubleClicked - // -nzEventType_MouseButtonPressed - struct MouseButtonEvent - { - NzMouse::Button button; - unsigned int x; - unsigned int y; - }; - - // Utilisé par: - // -nzEventType_MouseMoved - struct MouseMoveEvent - { - int deltaX; - int deltaY; - unsigned int x; - unsigned int y; - }; - - // Utilisé par: - // -nzEventType_MouseWheelMoved - struct MouseWheelEvent - { - float delta; - }; - - // Utilisé par: - // -nzEventType_Moved - struct PositionEvent - { - int x; - int y; - }; - - // Utilisé par: - // -nzEventType_Resized - struct SizeEvent - { - unsigned int height; - unsigned int width; - }; - - // Utilisé par: - // -nzEventType_TextEntered - struct TextEvent - { - bool repeated; - char32_t character; - }; - - nzEventType type; - - union + struct WindowEvent { // Utilisé par: - // -nzEventType_KeyPressed - // -nzEventType_KeyReleased - KeyEvent key; + // -WindowEventType_KeyPressed + // -WindowEventType_KeyReleased + struct KeyEvent + { + Keyboard::Key code; + bool alt; + bool control; + bool repeated; + bool shift; + bool system; + }; // Utilisé par: - // -nzEventType_MouseButtonDoubleClicked - // -nzEventType_MouseButtonPressed - MouseButtonEvent mouseButton; + // -WindowEventType_MouseButtonDoubleClicked + // -WindowEventType_MouseButtonPressed + struct MouseButtonEvent + { + Mouse::Button button; + unsigned int x; + unsigned int y; + }; // Utilisé par: - // -nzEventType_MouseMoved - MouseMoveEvent mouseMove; + // -WindowEventType_MouseMoved + struct MouseMoveEvent + { + int deltaX; + int deltaY; + unsigned int x; + unsigned int y; + }; // Utilisé par: - // -nzEventType_MouseWheelMoved - MouseWheelEvent mouseWheel; + // -WindowEventType_MouseWheelMoved + struct MouseWheelEvent + { + float delta; + }; // Utilisé par: - // -nzEventType_Moved - PositionEvent position; + // -WindowEventType_Moved + struct PositionEvent + { + int x; + int y; + }; // Utilisé par: - // -nzEventType_Resized - SizeEvent size; + // -WindowEventType_Resized + struct SizeEvent + { + unsigned int height; + unsigned int width; + }; // Utilisé par: - // -nzEventType_TextEntered - TextEvent text; + // -WindowEventType_TextEntered + struct TextEvent + { + bool repeated; + char32_t character; + }; + + WindowEventType type; + + union + { + // Utilisé par: + // -WindowEventType_KeyPressed + // -WindowEventType_KeyReleased + KeyEvent key; + + // Utilisé par: + // -WindowEventType_MouseButtonDoubleClicked + // -WindowEventType_MouseButtonPressed + MouseButtonEvent mouseButton; + + // Utilisé par: + // -WindowEventType_MouseMoved + MouseMoveEvent mouseMove; + + // Utilisé par: + // -WindowEventType_MouseWheelMoved + MouseWheelEvent mouseWheel; + + // Utilisé par: + // -WindowEventType_Moved + PositionEvent position; + + // Utilisé par: + // -WindowEventType_Resized + SizeEvent size; + + // Utilisé par: + // -WindowEventType_TextEntered + TextEvent text; + }; }; -}; +} #endif // NAZARA_EVENT_HPP diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index f0c52cb11..b515b5c21 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -18,144 +18,147 @@ #include #include -struct NAZARA_UTILITY_API NzFontParams +namespace Nz { - bool IsValid() const; -}; - -class NzFont; -class NzFontData; - -struct NzFontGlyph; - -using NzFontConstRef = NzObjectRef; -using NzFontLibrary = NzObjectLibrary; -using NzFontLoader = NzResourceLoader; -using NzFontRef = NzObjectRef; - -class NAZARA_UTILITY_API NzFont : public NzRefCounted, public NzResource -{ - friend NzFontLibrary; - friend NzFontLoader; - friend class NzUtility; - - public: - struct Glyph; - struct SizeInfo; - - NzFont(); - NzFont(const NzFont&) = delete; - NzFont(NzFont&&) = delete; - ~NzFont(); - - void ClearGlyphCache(); - void ClearKerningCache(); - void ClearSizeInfoCache(); - - bool Create(NzFontData* data); - void Destroy(); - - bool ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt32 style, NzFontGlyph* glyph) const; - - const std::shared_ptr& GetAtlas() const; - unsigned int GetCachedGlyphCount(unsigned int characterSize, nzUInt32 style) const; - unsigned int GetCachedGlyphCount() const; - NzString GetFamilyName() const; - int GetKerning(unsigned int characterSize, char32_t first, char32_t second) const; - const Glyph& GetGlyph(unsigned int characterSize, nzUInt32 style, char32_t character) const; - unsigned int GetGlyphBorder() const; - unsigned int GetMinimumStepSize() const; - const SizeInfo& GetSizeInfo(unsigned int characterSize) const; - NzString GetStyleName() const; - + struct NAZARA_UTILITY_API FontParams + { bool IsValid() const; + }; - bool Precache(unsigned int characterSize, nzUInt32 style, char32_t character) const; - bool Precache(unsigned int characterSize, nzUInt32 style, const NzString& characterSet) const; + class Font; + class FontData; - // Open - bool OpenFromFile(const NzString& filePath, const NzFontParams& params = NzFontParams()); - bool OpenFromMemory(const void* data, std::size_t size, const NzFontParams& params = NzFontParams()); - bool OpenFromStream(NzInputStream& stream, const NzFontParams& params = NzFontParams()); + struct FontGlyph; - void SetAtlas(const std::shared_ptr& atlas); - void SetGlyphBorder(unsigned int borderSize); - void SetMinimumStepSize(unsigned int minimumStepSize); + using FontConstRef = ObjectRef; + using FontLibrary = ObjectLibrary; + using FontLoader = ResourceLoader; + using FontRef = ObjectRef; - NzFont& operator=(const NzFont&) = delete; - NzFont& operator=(NzFont&&) = delete; + class NAZARA_UTILITY_API Font : public RefCounted, public Resource + { + friend FontLibrary; + friend FontLoader; + friend class Utility; - static std::shared_ptr GetDefaultAtlas(); - static NzFont* GetDefault(); - static unsigned int GetDefaultGlyphBorder(); - static unsigned int GetDefaultMinimumStepSize(); + public: + struct Glyph; + struct SizeInfo; - template static NzFontRef New(Args&&... args); + Font(); + Font(const Font&) = delete; + Font(Font&&) = delete; + ~Font(); - static void SetDefaultAtlas(const std::shared_ptr& atlas); - static void SetDefaultGlyphBorder(unsigned int borderSize); - static void SetDefaultMinimumStepSize(unsigned int minimumStepSize); + void ClearGlyphCache(); + void ClearKerningCache(); + void ClearSizeInfoCache(); - struct Glyph - { - NzRecti aabb; - NzRectui atlasRect; - bool requireFauxBold; - bool requireFauxItalic; - bool flipped; - bool valid; - int advance; - unsigned int layerIndex; - }; + bool Create(FontData* data); + void Destroy(); - struct SizeInfo - { - int spaceAdvance; - unsigned int lineHeight; - float underlinePosition; - float underlineThickness; - }; + bool ExtractGlyph(unsigned int characterSize, char32_t character, UInt32 style, FontGlyph* glyph) const; - // Signals: - NazaraSignal(OnFontAtlasChanged, const NzFont* /*font*/); - NazaraSignal(OnFontAtlasLayerChanged, const NzFont* /*font*/, NzAbstractImage* /*oldLayer*/, NzAbstractImage* /*newLayer*/); - NazaraSignal(OnFontDestroy, const NzFont* /*font*/); - NazaraSignal(OnFontGlyphCacheCleared, const NzFont* /*font*/); - NazaraSignal(OnFontKerningCacheCleared, const NzFont* /*font*/); - NazaraSignal(OnFontRelease, const NzFont* /*font*/); - NazaraSignal(OnFontSizeInfoCacheCleared, const NzFont* /*font*/); + const std::shared_ptr& GetAtlas() const; + unsigned int GetCachedGlyphCount(unsigned int characterSize, UInt32 style) const; + unsigned int GetCachedGlyphCount() const; + String GetFamilyName() const; + int GetKerning(unsigned int characterSize, char32_t first, char32_t second) const; + const Glyph& GetGlyph(unsigned int characterSize, UInt32 style, char32_t character) const; + unsigned int GetGlyphBorder() const; + unsigned int GetMinimumStepSize() const; + const SizeInfo& GetSizeInfo(unsigned int characterSize) const; + String GetStyleName() const; - private: - using GlyphMap = std::unordered_map; + bool IsValid() const; - nzUInt64 ComputeKey(unsigned int characterSize, nzUInt32 style) const; - void OnAtlasCleared(const NzAbstractAtlas* atlas); - void OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer); - void OnAtlasRelease(const NzAbstractAtlas* atlas); - const Glyph& PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, nzUInt32 style, char32_t character) const; + bool Precache(unsigned int characterSize, UInt32 style, char32_t character) const; + bool Precache(unsigned int characterSize, UInt32 style, const String& characterSet) const; - static bool Initialize(); - static void Uninitialize(); + // Open + bool OpenFromFile(const String& filePath, const FontParams& params = FontParams()); + bool OpenFromMemory(const void* data, std::size_t size, const FontParams& params = FontParams()); + bool OpenFromStream(InputStream& stream, const FontParams& params = FontParams()); - NazaraSlot(NzAbstractAtlas, OnAtlasCleared, m_atlasClearedSlot); - NazaraSlot(NzAbstractAtlas, OnAtlasLayerChange, m_atlasLayerChangeSlot); - NazaraSlot(NzAbstractAtlas, OnAtlasRelease, m_atlasReleaseSlot); + void SetAtlas(const std::shared_ptr& atlas); + void SetGlyphBorder(unsigned int borderSize); + void SetMinimumStepSize(unsigned int minimumStepSize); - std::shared_ptr m_atlas; - std::unique_ptr m_data; - mutable std::unordered_map> m_kerningCache; - mutable std::unordered_map m_glyphes; - mutable std::unordered_map m_sizeInfoCache; - unsigned int m_glyphBorder; - unsigned int m_minimumStepSize; + Font& operator=(const Font&) = delete; + Font& operator=(Font&&) = delete; - static std::shared_ptr s_defaultAtlas; - static NzFontRef s_defaultFont; - static NzFontLibrary::LibraryMap s_library; - static NzFontLoader::LoaderList s_loaders; - static unsigned int s_defaultGlyphBorder; - static unsigned int s_defaultMinimumStepSize; -}; + static std::shared_ptr GetDefaultAtlas(); + static Font* GetDefault(); + static unsigned int GetDefaultGlyphBorder(); + static unsigned int GetDefaultMinimumStepSize(); + + template static FontRef New(Args&&... args); + + static void SetDefaultAtlas(const std::shared_ptr& atlas); + static void SetDefaultGlyphBorder(unsigned int borderSize); + static void SetDefaultMinimumStepSize(unsigned int minimumStepSize); + + struct Glyph + { + Recti aabb; + Rectui atlasRect; + bool requireFauxBold; + bool requireFauxItalic; + bool flipped; + bool valid; + int advance; + unsigned int layerIndex; + }; + + struct SizeInfo + { + int spaceAdvance; + unsigned int lineHeight; + float underlinePosition; + float underlineThickness; + }; + + // Signals: + NazaraSignal(OnFontAtlasChanged, const Font* /*font*/); + NazaraSignal(OnFontAtlasLayerChanged, const Font* /*font*/, AbstractImage* /*oldLayer*/, AbstractImage* /*newLayer*/); + NazaraSignal(OnFontDestroy, const Font* /*font*/); + NazaraSignal(OnFontGlyphCacheCleared, const Font* /*font*/); + NazaraSignal(OnFontKerningCacheCleared, const Font* /*font*/); + NazaraSignal(OnFontRelease, const Font* /*font*/); + NazaraSignal(OnFontSizeInfoCacheCleared, const Font* /*font*/); + + private: + using GlyphMap = std::unordered_map; + + UInt64 ComputeKey(unsigned int characterSize, UInt32 style) const; + void OnAtlasCleared(const AbstractAtlas* atlas); + void OnAtlasLayerChange(const AbstractAtlas* atlas, AbstractImage* oldLayer, AbstractImage* newLayer); + void OnAtlasRelease(const AbstractAtlas* atlas); + const Glyph& PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, UInt32 style, char32_t character) const; + + static bool Initialize(); + static void Uninitialize(); + + NazaraSlot(AbstractAtlas, OnAtlasCleared, m_atlasClearedSlot); + NazaraSlot(AbstractAtlas, OnAtlasLayerChange, m_atlasLayerChangeSlot); + NazaraSlot(AbstractAtlas, OnAtlasRelease, m_atlasReleaseSlot); + + std::shared_ptr m_atlas; + std::unique_ptr m_data; + mutable std::unordered_map> m_kerningCache; + mutable std::unordered_map m_glyphes; + mutable std::unordered_map m_sizeInfoCache; + unsigned int m_glyphBorder; + unsigned int m_minimumStepSize; + + static std::shared_ptr s_defaultAtlas; + static FontRef s_defaultFont; + static FontLibrary::LibraryMap s_library; + static FontLoader::LoaderList s_loaders; + static unsigned int s_defaultGlyphBorder; + static unsigned int s_defaultMinimumStepSize; + }; +} #include diff --git a/include/Nazara/Utility/Font.inl b/include/Nazara/Utility/Font.inl index 904da2075..241915a3e 100644 --- a/include/Nazara/Utility/Font.inl +++ b/include/Nazara/Utility/Font.inl @@ -5,13 +5,16 @@ #include #include -template -NzFontRef NzFont::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzFont(std::forward(args)...)); - object->SetPersistent(false); + template + FontRef Font::New(Args&&... args) + { + std::unique_ptr object(new Font(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Utility/FontData.hpp b/include/Nazara/Utility/FontData.hpp index 7e8408f99..78da99792 100644 --- a/include/Nazara/Utility/FontData.hpp +++ b/include/Nazara/Utility/FontData.hpp @@ -11,29 +11,32 @@ #include #include -struct NzFontGlyph; - -class NAZARA_UTILITY_API NzFontData +namespace Nz { - public: - NzFontData() = default; - virtual ~NzFontData(); + struct FontGlyph; - virtual bool ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt32 style, NzFontGlyph* dst) = 0; + class NAZARA_UTILITY_API FontData + { + public: + FontData() = default; + virtual ~FontData(); - virtual NzString GetFamilyName() const = 0; - virtual NzString GetStyleName() const = 0; + virtual bool ExtractGlyph(unsigned int characterSize, char32_t character, UInt32 style, FontGlyph* dst) = 0; - virtual bool HasKerning() const = 0; + virtual String GetFamilyName() const = 0; + virtual String GetStyleName() const = 0; - virtual bool IsScalable() const = 0; + virtual bool HasKerning() const = 0; - virtual int QueryKerning(unsigned int characterSize, char32_t first, char32_t second) const = 0; - virtual unsigned int QueryLineHeight(unsigned int characterSize) const = 0; - virtual float QueryUnderlinePosition(unsigned int characterSize) const = 0; - virtual float QueryUnderlineThickness(unsigned int characterSize) const = 0; + virtual bool IsScalable() const = 0; - virtual bool SupportsStyle(nzUInt32 style) const = 0; -}; + virtual int QueryKerning(unsigned int characterSize, char32_t first, char32_t second) const = 0; + virtual unsigned int QueryLineHeight(unsigned int characterSize) const = 0; + virtual float QueryUnderlinePosition(unsigned int characterSize) const = 0; + virtual float QueryUnderlineThickness(unsigned int characterSize) const = 0; + + virtual bool SupportsStyle(UInt32 style) const = 0; + }; +} #endif // NAZARA_FONTDATA_HPP diff --git a/include/Nazara/Utility/FontGlyph.hpp b/include/Nazara/Utility/FontGlyph.hpp index 516052be4..2ea194116 100644 --- a/include/Nazara/Utility/FontGlyph.hpp +++ b/include/Nazara/Utility/FontGlyph.hpp @@ -9,11 +9,14 @@ #include -struct NzFontGlyph +namespace Nz { - NzImage image; - NzRecti aabb; - int advance; -}; + struct FontGlyph + { + Image image; + Recti aabb; + int advance; + }; +} #endif // NAZARA_FONTGLYPH_HPP diff --git a/include/Nazara/Utility/Formats/MD5AnimParser.hpp b/include/Nazara/Utility/Formats/MD5AnimParser.hpp index bb9500f01..1187ea886 100644 --- a/include/Nazara/Utility/Formats/MD5AnimParser.hpp +++ b/include/Nazara/Utility/Formats/MD5AnimParser.hpp @@ -15,65 +15,68 @@ #include #include -class NAZARA_UTILITY_API NzMD5AnimParser +namespace Nz { - public: - struct FrameJoint - { - NzQuaternionf orient; - NzVector3f pos; - }; + class NAZARA_UTILITY_API MD5AnimParser + { + public: + struct FrameJoint + { + Quaternionf orient; + Vector3f pos; + }; - struct Frame - { - std::vector joints; - NzBoxf bounds; - }; + struct Frame + { + std::vector joints; + Boxf bounds; + }; - struct Joint - { - NzQuaternionf bindOrient; - NzString name; - NzVector3f bindPos; - int parent; - unsigned int flags; - unsigned int index; - }; + struct Joint + { + Quaternionf bindOrient; + String name; + Vector3f bindPos; + int parent; + unsigned int flags; + unsigned int index; + }; - NzMD5AnimParser(NzInputStream& stream); - ~NzMD5AnimParser(); + MD5AnimParser(InputStream& stream); + ~MD5AnimParser(); - nzTernary Check(); + Ternary Check(); - unsigned int GetAnimatedComponentCount() const; - const Frame* GetFrames() const; - unsigned int GetFrameCount() const; - unsigned int GetFrameRate() const; - const Joint* GetJoints() const; - unsigned int GetJointCount() const; + unsigned int GetAnimatedComponentCount() const; + const Frame* GetFrames() const; + unsigned int GetFrameCount() const; + unsigned int GetFrameRate() const; + const Joint* GetJoints() const; + unsigned int GetJointCount() const; - bool Parse(); + bool Parse(); - private: - bool Advance(bool required = true); - void Error(const NzString& message); - bool ParseBaseframe(); - bool ParseBounds(); - bool ParseFrame(); - bool ParseHierarchy(); - void Warning(const NzString& message); - void UnrecognizedLine(bool error = false); + private: + bool Advance(bool required = true); + void Error(const String& message); + bool ParseBaseframe(); + bool ParseBounds(); + bool ParseFrame(); + bool ParseHierarchy(); + void Warning(const String& message); + void UnrecognizedLine(bool error = false); - std::vector m_animatedComponents; - std::vector m_frames; - std::vector m_joints; - NzInputStream& m_stream; - NzString m_currentLine; - bool m_keepLastLine; - unsigned int m_frameIndex; - unsigned int m_frameRate; - unsigned int m_lineCount; - unsigned int m_streamFlags; -}; + std::vector m_animatedComponents; + std::vector m_frames; + std::vector m_joints; + InputStream& m_stream; + String m_currentLine; + bool m_keepLastLine; + unsigned int m_frameIndex; + unsigned int m_frameRate; + unsigned int m_lineCount; + unsigned int m_streamFlags; + }; +} #endif // NAZARA_FORMATS_MD5ANIMPARSER_HPP diff --git a/include/Nazara/Utility/Formats/MD5MeshParser.hpp b/include/Nazara/Utility/Formats/MD5MeshParser.hpp index 15915a270..9c9fb3f1a 100644 --- a/include/Nazara/Utility/Formats/MD5MeshParser.hpp +++ b/include/Nazara/Utility/Formats/MD5MeshParser.hpp @@ -15,69 +15,72 @@ #include #include -class NAZARA_UTILITY_API NzMD5MeshParser +namespace Nz { - public: - struct Joint - { - NzQuaternionf bindOrient; - NzString name; - NzVector3f bindPos; - int parent; - }; + class NAZARA_UTILITY_API MD5MeshParser + { + public: + struct Joint + { + Quaternionf bindOrient; + String name; + Vector3f bindPos; + int parent; + }; - typedef NzVector3ui Triangle; + typedef Vector3ui Triangle; - struct Vertex - { - NzVector2f uv; - unsigned int startWeight; - unsigned int weightCount; - }; + struct Vertex + { + Vector2f uv; + unsigned int startWeight; + unsigned int weightCount; + }; - struct Weight - { - NzVector3f pos; - float bias; - unsigned int joint; - }; + struct Weight + { + Vector3f pos; + float bias; + unsigned int joint; + }; - struct Mesh - { - std::vector triangles; - std::vector vertices; - std::vector weights; - NzString shader; - }; + struct Mesh + { + std::vector triangles; + std::vector vertices; + std::vector weights; + String shader; + }; - NzMD5MeshParser(NzInputStream& stream); - ~NzMD5MeshParser(); + MD5MeshParser(InputStream& stream); + ~MD5MeshParser(); - nzTernary Check(); + Ternary Check(); - const Joint* GetJoints() const; - unsigned int GetJointCount() const; - const Mesh* GetMeshes() const; - unsigned int GetMeshCount() const; + const Joint* GetJoints() const; + unsigned int GetJointCount() const; + const Mesh* GetMeshes() const; + unsigned int GetMeshCount() const; - bool Parse(); + bool Parse(); - private: - bool Advance(bool required = true); - void Error(const NzString& message); - bool ParseJoints(); - bool ParseMesh(); - void Warning(const NzString& message); - void UnrecognizedLine(bool error = false); + private: + bool Advance(bool required = true); + void Error(const String& message); + bool ParseJoints(); + bool ParseMesh(); + void Warning(const String& message); + void UnrecognizedLine(bool error = false); - std::vector m_joints; - std::vector m_meshes; - NzInputStream& m_stream; - NzString m_currentLine; - bool m_keepLastLine; - unsigned int m_lineCount; - unsigned int m_meshIndex; - unsigned int m_streamFlags; -}; + std::vector m_joints; + std::vector m_meshes; + InputStream& m_stream; + String m_currentLine; + bool m_keepLastLine; + unsigned int m_lineCount; + unsigned int m_meshIndex; + unsigned int m_streamFlags; + }; +} #endif // NAZARA_FORMATS_MD5MESHPARSER_HPP diff --git a/include/Nazara/Utility/Formats/MTLParser.hpp b/include/Nazara/Utility/Formats/MTLParser.hpp index 6247ca926..f9b6ede5a 100644 --- a/include/Nazara/Utility/Formats/MTLParser.hpp +++ b/include/Nazara/Utility/Formats/MTLParser.hpp @@ -14,49 +14,52 @@ #include #include -class NAZARA_UTILITY_API NzMTLParser +namespace Nz { - public: - struct Material - { - NzColor ambient = NzColor::White; - NzColor diffuse = NzColor::White; - NzColor specular = NzColor::White; - NzString alphaMap; - NzString ambientMap; - NzString bumpMap; - NzString decalMap; - NzString diffuseMap; - NzString displacementMap; - NzString reflectionMap; - NzString shininessMap; - NzString specularMap; - float alpha = 1.f; - float refractionIndex = 1.f; - float shininess = 1.f; - unsigned int illumModel = 0; - }; + class NAZARA_UTILITY_API MTLParser + { + public: + struct Material + { + Color ambient = Color::White; + Color diffuse = Color::White; + Color specular = Color::White; + String alphaMap; + String ambientMap; + String bumpMap; + String decalMap; + String diffuseMap; + String displacementMap; + String reflectionMap; + String shininessMap; + String specularMap; + float alpha = 1.f; + float refractionIndex = 1.f; + float shininess = 1.f; + unsigned int illumModel = 0; + }; - NzMTLParser(NzInputStream& stream$); - ~NzMTLParser(); + MTLParser(InputStream& stream$); + ~MTLParser(); - const Material* GetMaterial(const NzString& materialName) const; - const std::unordered_map& GetMaterials() const; + const Material* GetMaterial(const String& materialName) const; + const std::unordered_map& GetMaterials() const; - bool Parse(); + bool Parse(); - private: - bool Advance(bool required = true); - void Error(const NzString& message); - void Warning(const NzString& message); - void UnrecognizedLine(bool error = false); + private: + bool Advance(bool required = true); + void Error(const String& message); + void Warning(const String& message); + void UnrecognizedLine(bool error = false); - std::unordered_map m_materials; - NzInputStream& m_stream; - NzString m_currentLine; - bool m_keepLastLine; - unsigned int m_lineCount; - unsigned int m_streamFlags; -}; + std::unordered_map m_materials; + InputStream& m_stream; + String m_currentLine; + bool m_keepLastLine; + unsigned int m_lineCount; + unsigned int m_streamFlags; + }; +} #endif // NAZARA_FORMATS_MTLPARSER_HPP diff --git a/include/Nazara/Utility/Formats/OBJParser.hpp b/include/Nazara/Utility/Formats/OBJParser.hpp index 2a976bd40..7546db7bd 100644 --- a/include/Nazara/Utility/Formats/OBJParser.hpp +++ b/include/Nazara/Utility/Formats/OBJParser.hpp @@ -15,62 +15,65 @@ #include #include -class NAZARA_UTILITY_API NzOBJParser +namespace Nz { - public: - struct FaceVertex - { - int normal; - int position; - int texCoord; - }; + class NAZARA_UTILITY_API OBJParser + { + public: + struct FaceVertex + { + int normal; + int position; + int texCoord; + }; - struct Face - { - std::vector vertices; - }; + struct Face + { + std::vector vertices; + }; - struct Mesh - { - std::vector faces; - NzString name; - unsigned int material; - }; + struct Mesh + { + std::vector faces; + String name; + unsigned int material; + }; - NzOBJParser(NzInputStream& stream$); - ~NzOBJParser(); + OBJParser(InputStream& stream$); + ~OBJParser(); - const NzString* GetMaterials() const; - unsigned int GetMaterialCount() const; - const Mesh* GetMeshes() const; - unsigned int GetMeshCount() const; - const NzString& GetMtlLib() const; - const NzVector3f* GetNormals() const; - unsigned int GetNormalCount() const; - const NzVector4f* GetPositions() const; - unsigned int GetPositionCount() const; - const NzVector3f* GetTexCoords() const; - unsigned int GetTexCoordCount() const; + const String* GetMaterials() const; + unsigned int GetMaterialCount() const; + const Mesh* GetMeshes() const; + unsigned int GetMeshCount() const; + const String& GetMtlLib() const; + const Vector3f* GetNormals() const; + unsigned int GetNormalCount() const; + const Vector4f* GetPositions() const; + unsigned int GetPositionCount() const; + const Vector3f* GetTexCoords() const; + unsigned int GetTexCoordCount() const; - bool Parse(); + bool Parse(); - private: - bool Advance(bool required = true); - void Error(const NzString& message); - void Warning(const NzString& message); - void UnrecognizedLine(bool error = false); + private: + bool Advance(bool required = true); + void Error(const String& message); + void Warning(const String& message); + void UnrecognizedLine(bool error = false); - std::vector m_meshes; - std::vector m_materials; - std::vector m_normals; - std::vector m_positions; - std::vector m_texCoords; - NzInputStream& m_stream; - NzString m_currentLine; - NzString m_mtlLib; - bool m_keepLastLine; - unsigned int m_lineCount; - unsigned int m_streamFlags; -}; + std::vector m_meshes; + std::vector m_materials; + std::vector m_normals; + std::vector m_positions; + std::vector m_texCoords; + InputStream& m_stream; + String m_currentLine; + String m_mtlLib; + bool m_keepLastLine; + unsigned int m_lineCount; + unsigned int m_streamFlags; + }; +} #endif // NAZARA_FORMATS_OBJPARSER_HPP diff --git a/include/Nazara/Utility/GuillotineImageAtlas.hpp b/include/Nazara/Utility/GuillotineImageAtlas.hpp index cb349361e..f26ae13ea 100644 --- a/include/Nazara/Utility/GuillotineImageAtlas.hpp +++ b/include/Nazara/Utility/GuillotineImageAtlas.hpp @@ -15,53 +15,56 @@ #include #include -class NAZARA_UTILITY_API NzGuillotineImageAtlas : public NzAbstractAtlas +namespace Nz { - public: - NzGuillotineImageAtlas(); - virtual ~NzGuillotineImageAtlas(); + class NAZARA_UTILITY_API GuillotineImageAtlas : public AbstractAtlas + { + public: + GuillotineImageAtlas(); + virtual ~GuillotineImageAtlas(); - void Clear(); - void Free(NzSparsePtr rects, NzSparsePtr layers, unsigned int count); + void Clear(); + void Free(SparsePtr rects, SparsePtr layers, unsigned int count); - NzGuillotineBinPack::FreeRectChoiceHeuristic GetRectChoiceHeuristic() const; - NzGuillotineBinPack::GuillotineSplitHeuristic GetRectSplitHeuristic() const; - NzAbstractImage* GetLayer(unsigned int layerIndex) const; - unsigned int GetLayerCount() const; - nzUInt32 GetStorage() const; + GuillotineBinPack::FreeRectChoiceHeuristic GetRectChoiceHeuristic() const; + GuillotineBinPack::GuillotineSplitHeuristic GetRectSplitHeuristic() const; + AbstractImage* GetLayer(unsigned int layerIndex) const; + unsigned int GetLayerCount() const; + UInt32 GetStorage() const; - bool Insert(const NzImage& image, NzRectui* rect, bool* flipped, unsigned int* layerIndex); + bool Insert(const Image& image, Rectui* rect, bool* flipped, unsigned int* layerIndex); - void SetRectChoiceHeuristic(NzGuillotineBinPack::FreeRectChoiceHeuristic heuristic); - void SetRectSplitHeuristic(NzGuillotineBinPack::GuillotineSplitHeuristic heuristic); + void SetRectChoiceHeuristic(GuillotineBinPack::FreeRectChoiceHeuristic heuristic); + void SetRectSplitHeuristic(GuillotineBinPack::GuillotineSplitHeuristic heuristic); - protected: - struct Layer; + protected: + struct Layer; - virtual NzAbstractImage* ResizeImage(NzAbstractImage* oldImage, const NzVector2ui& size) const; - bool ResizeLayer(Layer& layer, const NzVector2ui& size); + virtual AbstractImage* ResizeImage(AbstractImage* oldImage, const Vector2ui& size) const; + bool ResizeLayer(Layer& layer, const Vector2ui& size); - struct QueuedGlyph - { - NzImage image; - NzRectui rect; - bool flipped; - }; + struct QueuedGlyph + { + Image image; + Rectui rect; + bool flipped; + }; - struct Layer - { - std::vector queuedGlyphs; - std::unique_ptr image; - NzGuillotineBinPack binPack; - unsigned int freedRectangles = 0; - }; + struct Layer + { + std::vector queuedGlyphs; + std::unique_ptr image; + GuillotineBinPack binPack; + unsigned int freedRectangles = 0; + }; - private: - void ProcessGlyphQueue(Layer& layer) const; + private: + void ProcessGlyphQueue(Layer& layer) const; - mutable std::vector m_layers; - NzGuillotineBinPack::FreeRectChoiceHeuristic m_rectChoiceHeuristic; - NzGuillotineBinPack::GuillotineSplitHeuristic m_rectSplitHeuristic; -}; + mutable std::vector m_layers; + GuillotineBinPack::FreeRectChoiceHeuristic m_rectChoiceHeuristic; + GuillotineBinPack::GuillotineSplitHeuristic m_rectSplitHeuristic; + }; +} #endif // NAZARA_GUILLOTINEIMAGEATLAS_HPP diff --git a/include/Nazara/Utility/Icon.hpp b/include/Nazara/Utility/Icon.hpp index 20dc1db4e..4f0397faf 100644 --- a/include/Nazara/Utility/Icon.hpp +++ b/include/Nazara/Utility/Icon.hpp @@ -11,24 +11,27 @@ #include #include -class NzImage; -class NzIconImpl; - -class NAZARA_UTILITY_API NzIcon +namespace Nz { - friend class NzWindowImpl; + class Image; + class IconImpl; - public: - NzIcon(); - ~NzIcon(); + class NAZARA_UTILITY_API Icon + { + friend class WindowImpl; - bool Create(const NzImage& icon); - void Destroy(); + public: + Icon(); + ~Icon(); - bool IsValid() const; + bool Create(const Image& icon); + void Destroy(); - private: - NzIconImpl* m_impl; -}; + bool IsValid() const; + + private: + IconImpl* m_impl; + }; +} #endif // NAZARA_ICON_HPP diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index 67efac84e..794ef9ff4 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -23,147 +23,150 @@ ///TODO: Filtres -struct NAZARA_UTILITY_API NzImageParams +namespace Nz { - // Le format dans lequel l'image doit être chargée (Undefined pour le format le plus proche de l'original) - nzPixelFormat loadFormat = nzPixelFormat_Undefined; + struct NAZARA_UTILITY_API ImageParams + { + // Le format dans lequel l'image doit être chargée (Undefined pour le format le plus proche de l'original) + PixelFormatType loadFormat = PixelFormatType_Undefined; - // Le nombre de niveaux de mipmaps maximum devant être créé - nzUInt8 levelCount = 0; - - bool IsValid() const; -}; - -class NzImage; - -using NzImageConstRef = NzObjectRef; -using NzImageLibrary = NzObjectLibrary; -using NzImageLoader = NzResourceLoader; -using NzImageManager = NzResourceManager; -using NzImageRef = NzObjectRef; - -class NAZARA_UTILITY_API NzImage : public NzAbstractImage, public NzRefCounted, public NzResource -{ - friend NzImageLibrary; - friend NzImageLoader; - friend NzImageManager; - friend class NzUtility; - - public: - struct SharedImage; - - NzImage(); - NzImage(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1); - NzImage(const NzImage& image); - NzImage(SharedImage* sharedImage); - ~NzImage(); - - bool Convert(nzPixelFormat format); - - void Copy(const NzImage& source, const NzBoxui& srcBox, const NzVector3ui& dstPos); - - bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1); - void Destroy(); - - bool Fill(const NzColor& color); - bool Fill(const NzColor& color, const NzBoxui& box); - bool Fill(const NzColor& color, const NzRectui& rect, unsigned int z = 0); - - bool FlipHorizontally(); - bool FlipVertically(); - - const nzUInt8* GetConstPixels(unsigned int x = 0, unsigned int y = 0, unsigned int z = 0, nzUInt8 level = 0) const; - unsigned int GetDepth(nzUInt8 level = 0) const; - nzPixelFormat GetFormat() const; - unsigned int GetHeight(nzUInt8 level = 0) const; - nzUInt8 GetLevelCount() const; - nzUInt8 GetMaxLevel() const; - unsigned int GetMemoryUsage() const; - unsigned int GetMemoryUsage(nzUInt8 level) const; - NzColor GetPixelColor(unsigned int x, unsigned int y = 0, unsigned int z = 0) const; - nzUInt8* GetPixels(unsigned int x = 0, unsigned int y = 0, unsigned int z = 0, nzUInt8 level = 0); - NzVector3ui GetSize(nzUInt8 level = 0) const; - nzImageType GetType() const; - unsigned int GetWidth(nzUInt8 level = 0) const; + // Le nombre de niveaux de mipmaps maximum devant être créé + UInt8 levelCount = 0; bool IsValid() const; + }; - // Load - bool LoadFromFile(const NzString& filePath, const NzImageParams& params = NzImageParams()); - bool LoadFromMemory(const void* data, std::size_t size, const NzImageParams& params = NzImageParams()); - bool LoadFromStream(NzInputStream& stream, const NzImageParams& params = NzImageParams()); + class Image; - // LoadArray - bool LoadArrayFromFile(const NzString& filePath, const NzImageParams& imageParams = NzImageParams(), const NzVector2ui& atlasSize = NzVector2ui(2, 2)); - bool LoadArrayFromImage(const NzImage& image, const NzVector2ui& atlasSize = NzVector2ui(2, 2)); - bool LoadArrayFromMemory(const void* data, std::size_t size, const NzImageParams& imageParams = NzImageParams(), const NzVector2ui& atlasSize = NzVector2ui(2, 2)); - bool LoadArrayFromStream(NzInputStream& stream, const NzImageParams& imageParams = NzImageParams(), const NzVector2ui& atlasSize = NzVector2ui(2, 2)); + using ImageConstRef = ObjectRef; + using ImageLibrary = ObjectLibrary; + using ImageLoader = ResourceLoader; + using ImageManager = ResourceManager; + using ImageRef = ObjectRef; - // LoadCubemap - bool LoadCubemapFromFile(const NzString& filePath, const NzImageParams& imageParams = NzImageParams(), const NzCubemapParams& cubemapParams = NzCubemapParams()); - bool LoadCubemapFromImage(const NzImage& image, const NzCubemapParams& params = NzCubemapParams()); - bool LoadCubemapFromMemory(const void* data, std::size_t size, const NzImageParams& imageParams = NzImageParams(), const NzCubemapParams& cubemapParams = NzCubemapParams()); - bool LoadCubemapFromStream(NzInputStream& stream, const NzImageParams& imageParams = NzImageParams(), const NzCubemapParams& cubemapParams = NzCubemapParams()); + class NAZARA_UTILITY_API Image : public AbstractImage, public RefCounted, public Resource + { + friend ImageLibrary; + friend ImageLoader; + friend ImageManager; + friend class Utility; - void SetLevelCount(nzUInt8 levelCount); - bool SetPixelColor(const NzColor& color, unsigned int x, unsigned int y = 0, unsigned int z = 0); + public: + struct SharedImage; - bool Update(const nzUInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); - bool Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); - bool Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0); + Image(); + Image(ImageType type, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth = 1, UInt8 levelCount = 1); + Image(const Image& image); + Image(SharedImage* sharedImage); + ~Image(); - NzImage& operator=(const NzImage& image); + bool Convert(PixelFormatType format); - static void Copy(nzUInt8* destination, const nzUInt8* source, nzUInt8 bpp, unsigned int width, unsigned int height, unsigned int depth = 1, unsigned int dstWidth = 0, unsigned int dstHeight = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0); - static nzUInt8 GetMaxLevel(unsigned int width, unsigned int height, unsigned int depth = 1); - static nzUInt8 GetMaxLevel(nzImageType type, unsigned int width, unsigned int height, unsigned int depth = 1); - template static NzImageRef New(Args&&... args); + void Copy(const Image& source, const Boxui& srcBox, const Vector3ui& dstPos); - struct SharedImage - { - using PixelContainer = std::vector>; + bool Create(ImageType type, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth = 1, UInt8 levelCount = 1); + void Destroy(); - SharedImage(unsigned short RefCount, nzImageType Type, nzPixelFormat Format, PixelContainer&& Levels, unsigned int Width, unsigned int Height, unsigned int Depth) : - type(Type), - format(Format), - levels(std::move(Levels)), - depth(Depth), - height(Height), - width(Width), - refCount(RefCount) + bool Fill(const Color& color); + bool Fill(const Color& color, const Boxui& box); + bool Fill(const Color& color, const Rectui& rect, unsigned int z = 0); + + bool FlipHorizontally(); + bool FlipVertically(); + + const UInt8* GetConstPixels(unsigned int x = 0, unsigned int y = 0, unsigned int z = 0, UInt8 level = 0) const; + unsigned int GetDepth(UInt8 level = 0) const; + PixelFormatType GetFormat() const; + unsigned int GetHeight(UInt8 level = 0) const; + UInt8 GetLevelCount() const; + UInt8 GetMaxLevel() const; + unsigned int GetMemoryUsage() const; + unsigned int GetMemoryUsage(UInt8 level) const; + Color GetPixelColor(unsigned int x, unsigned int y = 0, unsigned int z = 0) const; + UInt8* GetPixels(unsigned int x = 0, unsigned int y = 0, unsigned int z = 0, UInt8 level = 0); + Vector3ui GetSize(UInt8 level = 0) const; + ImageType GetType() const; + unsigned int GetWidth(UInt8 level = 0) const; + + bool IsValid() const; + + // Load + bool LoadFromFile(const String& filePath, const ImageParams& params = ImageParams()); + bool LoadFromMemory(const void* data, std::size_t size, const ImageParams& params = ImageParams()); + bool LoadFromStream(InputStream& stream, const ImageParams& params = ImageParams()); + + // LoadArray + bool LoadArrayFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2)); + bool LoadArrayFromImage(const Image& image, const Vector2ui& atlasSize = Vector2ui(2, 2)); + bool LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2)); + bool LoadArrayFromStream(InputStream& stream, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2)); + + // LoadCubemap + bool LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); + bool LoadCubemapFromImage(const Image& image, const CubemapParams& params = CubemapParams()); + bool LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); + bool LoadCubemapFromStream(InputStream& stream, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); + + void SetLevelCount(UInt8 levelCount); + bool SetPixelColor(const Color& color, unsigned int x, unsigned int y = 0, unsigned int z = 0); + + bool Update(const UInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0); + bool Update(const UInt8* pixels, const Boxui& box, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0); + bool Update(const UInt8* pixels, const Rectui& rect, unsigned int z = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0, UInt8 level = 0); + + Image& operator=(const Image& image); + + static void Copy(UInt8* destination, const UInt8* source, UInt8 bpp, unsigned int width, unsigned int height, unsigned int depth = 1, unsigned int dstWidth = 0, unsigned int dstHeight = 0, unsigned int srcWidth = 0, unsigned int srcHeight = 0); + static UInt8 GetMaxLevel(unsigned int width, unsigned int height, unsigned int depth = 1); + static UInt8 GetMaxLevel(ImageType type, unsigned int width, unsigned int height, unsigned int depth = 1); + template static ImageRef New(Args&&... args); + + struct SharedImage { - } + using PixelContainer = std::vector>; - nzImageType type; - nzPixelFormat format; - PixelContainer levels; - unsigned int depth; - unsigned int height; - unsigned int width; + SharedImage(unsigned short RefCount, ImageType Type, PixelFormatType Format, PixelContainer&& Levels, unsigned int Width, unsigned int Height, unsigned int Depth) : + type(Type), + format(Format), + levels(std::move(Levels)), + depth(Depth), + height(Height), + width(Width), + refCount(RefCount) + { + } - std::atomic_ushort refCount; + ImageType type; + PixelFormatType format; + PixelContainer levels; + unsigned int depth; + unsigned int height; + unsigned int width; + + std::atomic_ushort refCount; + }; + + static SharedImage emptyImage; + + // Signals: + NazaraSignal(OnImageDestroy, const Image* /*image*/); + NazaraSignal(OnImageRelease, const Image* /*image*/); + + private: + void EnsureOwnership(); + void ReleaseImage(); + + static bool Initialize(); + static void Uninitialize(); + + SharedImage* m_sharedImage; + + static ImageLibrary::LibraryMap s_library; + static ImageLoader::LoaderList s_loaders; + static ImageManager::ManagerMap s_managerMap; + static ImageManager::ManagerParams s_managerParameters; }; - - static SharedImage emptyImage; - - // Signals: - NazaraSignal(OnImageDestroy, const NzImage* /*image*/); - NazaraSignal(OnImageRelease, const NzImage* /*image*/); - - private: - void EnsureOwnership(); - void ReleaseImage(); - - static bool Initialize(); - static void Uninitialize(); - - SharedImage* m_sharedImage; - - static NzImageLibrary::LibraryMap s_library; - static NzImageLoader::LoaderList s_loaders; - static NzImageManager::ManagerMap s_managerMap; - static NzImageManager::ManagerParams s_managerParameters; -}; +} #include diff --git a/include/Nazara/Utility/Image.inl b/include/Nazara/Utility/Image.inl index dfe6934a7..5cb8ef42f 100644 --- a/include/Nazara/Utility/Image.inl +++ b/include/Nazara/Utility/Image.inl @@ -5,13 +5,16 @@ #include #include -template -NzImageRef NzImage::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzImage(std::forward(args)...)); - object->SetPersistent(false); + template + ImageRef Image::New(Args&&... args) + { + std::unique_ptr object(new Image(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Utility/Image.inl.save-failed b/include/Nazara/Utility/Image.inl.save-failed new file mode 100644 index 000000000..5cb8ef42f --- /dev/null +++ b/include/Nazara/Utility/Image.inl.save-failed @@ -0,0 +1,20 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + template + ImageRef Image::New(Args&&... args) + { + std::unique_ptr object(new Image(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); + } +} + +#include diff --git a/include/Nazara/Utility/IndexBuffer.hpp b/include/Nazara/Utility/IndexBuffer.hpp index 2e92ef49b..601e705c9 100644 --- a/include/Nazara/Utility/IndexBuffer.hpp +++ b/include/Nazara/Utility/IndexBuffer.hpp @@ -12,68 +12,71 @@ #include #include -class NzIndexBuffer; - -using NzIndexBufferConstRef = NzObjectRef; -using NzIndexBufferRef = NzObjectRef; - -class NAZARA_UTILITY_API NzIndexBuffer : public NzRefCounted +namespace Nz { - public: - NzIndexBuffer() = default; - NzIndexBuffer(bool largeIndices, NzBuffer* buffer); - NzIndexBuffer(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); - NzIndexBuffer(bool largeIndices, unsigned int length, nzUInt32 storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); - NzIndexBuffer(const NzIndexBuffer& indexBuffer); - ~NzIndexBuffer(); + class IndexBuffer; - unsigned int ComputeCacheMissCount() const; + using IndexBufferConstRef = ObjectRef; + using IndexBufferRef = ObjectRef; - bool Fill(const void* data, unsigned int startIndex, unsigned int length, bool forceDiscard = false); - bool FillRaw(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false); + class NAZARA_UTILITY_API IndexBuffer : public RefCounted + { + public: + IndexBuffer() = default; + IndexBuffer(bool largeIndices, Buffer* buffer); + IndexBuffer(bool largeIndices, Buffer* buffer, unsigned int startOffset, unsigned int endOffset); + IndexBuffer(bool largeIndices, unsigned int length, UInt32 storage = DataStorage_Software, BufferUsage usage = BufferUsage_Static); + IndexBuffer(const IndexBuffer& indexBuffer); + ~IndexBuffer(); - NzBuffer* GetBuffer() const; - unsigned int GetEndOffset() const; - unsigned int GetIndexCount() const; - unsigned int GetStride() const; - unsigned int GetStartOffset() const; + unsigned int ComputeCacheMissCount() const; - bool HasLargeIndices() const; + bool Fill(const void* data, unsigned int startIndex, unsigned int length, bool forceDiscard = false); + bool FillRaw(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false); - bool IsHardware() const; - bool IsValid() const; + Buffer* GetBuffer() const; + unsigned int GetEndOffset() const; + unsigned int GetIndexCount() const; + unsigned int GetStride() const; + unsigned int GetStartOffset() const; - void* Map(nzBufferAccess access, unsigned int startVertex = 0, unsigned int length = 0); - void* Map(nzBufferAccess access, unsigned int startVertex = 0, unsigned int length = 0) const; - void* MapRaw(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0); - void* MapRaw(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0) const; + bool HasLargeIndices() const; - void Optimize(); + bool IsHardware() const; + bool IsValid() const; - void Reset(); - void Reset(bool largeIndices, NzBuffer* buffer); - void Reset(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); - void Reset(bool largeIndices, unsigned int length, nzUInt32 storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); - void Reset(const NzIndexBuffer& indexBuffer); + void* Map(BufferAccess access, unsigned int startVertex = 0, unsigned int length = 0); + void* Map(BufferAccess access, unsigned int startVertex = 0, unsigned int length = 0) const; + void* MapRaw(BufferAccess access, unsigned int offset = 0, unsigned int size = 0); + void* MapRaw(BufferAccess access, unsigned int offset = 0, unsigned int size = 0) const; - bool SetStorage(nzUInt32 storage); + void Optimize(); - void Unmap() const; + void Reset(); + void Reset(bool largeIndices, Buffer* buffer); + void Reset(bool largeIndices, Buffer* buffer, unsigned int startOffset, unsigned int endOffset); + void Reset(bool largeIndices, unsigned int length, UInt32 storage = DataStorage_Software, BufferUsage usage = BufferUsage_Static); + void Reset(const IndexBuffer& indexBuffer); - NzIndexBuffer& operator=(const NzIndexBuffer& indexBuffer); + bool SetStorage(UInt32 storage); - template static NzIndexBufferRef New(Args&&... args); + void Unmap() const; - // Signals: - NazaraSignal(OnIndexBufferRelease, const NzIndexBuffer* /*indexBuffer*/); + IndexBuffer& operator=(const IndexBuffer& indexBuffer); - private: - NzBufferRef m_buffer; - bool m_largeIndices; - unsigned int m_endOffset; - unsigned int m_indexCount; - unsigned int m_startOffset; -}; + template static IndexBufferRef New(Args&&... args); + + // Signals: + NazaraSignal(OnIndexBufferRelease, const IndexBuffer* /*indexBuffer*/); + + private: + BufferRef m_buffer; + bool m_largeIndices; + unsigned int m_endOffset; + unsigned int m_indexCount; + unsigned int m_startOffset; + }; +} #include diff --git a/include/Nazara/Utility/IndexBuffer.inl b/include/Nazara/Utility/IndexBuffer.inl index e9f8d8874..1c1d16a18 100644 --- a/include/Nazara/Utility/IndexBuffer.inl +++ b/include/Nazara/Utility/IndexBuffer.inl @@ -5,13 +5,16 @@ #include #include -template -NzIndexBufferRef NzIndexBuffer::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzIndexBuffer(std::forward(args)...)); - object->SetPersistent(false); + template + IndexBufferRef IndexBuffer::New(Args&&... args) + { + std::unique_ptr object(new IndexBuffer(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Utility/IndexIterator.hpp b/include/Nazara/Utility/IndexIterator.hpp index b0eaa8cb8..7620d3b28 100644 --- a/include/Nazara/Utility/IndexIterator.hpp +++ b/include/Nazara/Utility/IndexIterator.hpp @@ -9,70 +9,73 @@ #include -class NzIndexMapper; - -class NzIndexIterator +namespace Nz { - friend NzIndexMapper; + class IndexMapper; - public: - class Reference; + class IndexIterator + { + friend IndexMapper; - NzIndexIterator(); - NzIndexIterator(const NzIndexIterator& iterator); - ~NzIndexIterator() = default; + public: + class Reference; - Reference operator*() const; + IndexIterator(); + IndexIterator(const IndexIterator& iterator); + ~IndexIterator() = default; - Reference operator[](unsigned int index) const; + Reference operator*() const; - NzIndexIterator& operator=(const NzIndexIterator& iterator); + Reference operator[](unsigned int index) const; - NzIndexIterator operator+(unsigned int indexCount) const; - NzIndexIterator operator-(unsigned int indexCount) const; + IndexIterator& operator=(const IndexIterator& iterator); - NzIndexIterator& operator+=(unsigned int indexCount); - NzIndexIterator& operator-=(unsigned int indexCount); + IndexIterator operator+(unsigned int indexCount) const; + IndexIterator operator-(unsigned int indexCount) const; - NzIndexIterator& operator++(); - NzIndexIterator operator++(int); + IndexIterator& operator+=(unsigned int indexCount); + IndexIterator& operator-=(unsigned int indexCount); - NzIndexIterator& operator--(); - NzIndexIterator operator--(int); + IndexIterator& operator++(); + IndexIterator operator++(int); - friend bool operator==(const NzIndexIterator& lhs, const NzIndexIterator& rhs); - friend bool operator!=(const NzIndexIterator& lhs, const NzIndexIterator& rhs); - friend bool operator<(const NzIndexIterator& lhs, const NzIndexIterator& rhs); - friend bool operator<=(const NzIndexIterator& lhs, const NzIndexIterator& rhs); - friend bool operator>(const NzIndexIterator& lhs, const NzIndexIterator& rhs); - friend bool operator>=(const NzIndexIterator& lhs, const NzIndexIterator& rhs); + IndexIterator& operator--(); + IndexIterator operator--(int); - private: - NzIndexIterator(NzIndexMapper* mapper, unsigned int index); + friend bool operator==(const IndexIterator& lhs, const IndexIterator& rhs); + friend bool operator!=(const IndexIterator& lhs, const IndexIterator& rhs); + friend bool operator<(const IndexIterator& lhs, const IndexIterator& rhs); + friend bool operator<=(const IndexIterator& lhs, const IndexIterator& rhs); + friend bool operator>(const IndexIterator& lhs, const IndexIterator& rhs); + friend bool operator>=(const IndexIterator& lhs, const IndexIterator& rhs); - NzIndexMapper* m_mapper; - unsigned int m_index; -}; + private: + IndexIterator(IndexMapper* mapper, unsigned int index); -class NzIndexIterator::Reference -{ - friend NzIndexIterator; + IndexMapper* m_mapper; + unsigned int m_index; + }; - public: - Reference(const Reference& reference) = default; - ~Reference() = default; + class IndexIterator::Reference + { + friend IndexIterator; - Reference& operator=(nzUInt32 value); - Reference& operator=(const Reference& reference); + public: + Reference(const Reference& reference) = default; + ~Reference() = default; - operator nzUInt32() const; + Reference& operator=(UInt32 value); + Reference& operator=(const Reference& reference); - private: - Reference(NzIndexMapper* mapper, unsigned int index); + operator UInt32() const; - NzIndexMapper* m_mapper; - unsigned int m_index; -}; + private: + Reference(IndexMapper* mapper, unsigned int index); + + IndexMapper* m_mapper; + unsigned int m_index; + }; +} #include diff --git a/include/Nazara/Utility/IndexIterator.inl b/include/Nazara/Utility/IndexIterator.inl index 7ed06f723..f0d3d5a95 100644 --- a/include/Nazara/Utility/IndexIterator.inl +++ b/include/Nazara/Utility/IndexIterator.inl @@ -6,166 +6,169 @@ #include #include -inline NzIndexIterator::NzIndexIterator() : -m_mapper(nullptr), -m_index(0) +namespace Nz { -} + inline IndexIterator::IndexIterator() : + m_mapper(nullptr), + m_index(0) + { + } -inline NzIndexIterator::NzIndexIterator(const NzIndexIterator& iterator) : -m_mapper(iterator.m_mapper), -m_index(iterator.m_index) -{ -} + inline IndexIterator::IndexIterator(const IndexIterator& iterator) : + m_mapper(iterator.m_mapper), + m_index(iterator.m_index) + { + } -inline NzIndexIterator::NzIndexIterator(NzIndexMapper* mapper, unsigned int index) : -m_mapper(mapper), -m_index(index) -{ -} + inline IndexIterator::IndexIterator(IndexMapper* mapper, unsigned int index) : + m_mapper(mapper), + m_index(index) + { + } -inline NzIndexIterator::Reference NzIndexIterator::operator*() const -{ - return Reference(m_mapper, m_index); -} + inline IndexIterator::Reference IndexIterator::operator*() const + { + return Reference(m_mapper, m_index); + } -inline NzIndexIterator::Reference NzIndexIterator::operator[](unsigned int index) const -{ - return Reference(m_mapper, m_index+index); -} + inline IndexIterator::Reference IndexIterator::operator[](unsigned int index) const + { + return Reference(m_mapper, m_index+index); + } -inline NzIndexIterator& NzIndexIterator::operator=(const NzIndexIterator& iterator) -{ - m_mapper = iterator.m_mapper; - m_index = iterator.m_index; + inline IndexIterator& IndexIterator::operator=(const IndexIterator& iterator) + { + m_mapper = iterator.m_mapper; + m_index = iterator.m_index; - return *this; -} + return *this; + } -inline NzIndexIterator NzIndexIterator::operator+(unsigned int indexCount) const -{ - return NzIndexIterator(m_mapper, m_index + indexCount); -} + inline IndexIterator IndexIterator::operator+(unsigned int indexCount) const + { + return IndexIterator(m_mapper, m_index + indexCount); + } -inline NzIndexIterator NzIndexIterator::operator-(unsigned int indexCount) const -{ - return NzIndexIterator(m_mapper, m_index - indexCount); -} + inline IndexIterator IndexIterator::operator-(unsigned int indexCount) const + { + return IndexIterator(m_mapper, m_index - indexCount); + } -inline NzIndexIterator& NzIndexIterator::operator+=(unsigned int indexCount) -{ - m_index += indexCount; + inline IndexIterator& IndexIterator::operator+=(unsigned int indexCount) + { + m_index += indexCount; - return *this; -} + return *this; + } -inline NzIndexIterator& NzIndexIterator::operator-=(unsigned int indexCount) -{ - m_index += indexCount; + inline IndexIterator& IndexIterator::operator-=(unsigned int indexCount) + { + m_index += indexCount; - return *this; -} + return *this; + } -inline NzIndexIterator& NzIndexIterator::operator++() -{ - m_index++; + inline IndexIterator& IndexIterator::operator++() + { + m_index++; - return *this; -} + return *this; + } -inline NzIndexIterator NzIndexIterator::operator++(int) -{ - NzIndexIterator iterator(*this); - operator++(); + inline IndexIterator IndexIterator::operator++(int) + { + IndexIterator iterator(*this); + operator++(); - return iterator; -} + return iterator; + } -inline NzIndexIterator& NzIndexIterator::operator--() -{ - m_index--; + inline IndexIterator& IndexIterator::operator--() + { + m_index--; - return *this; -} + return *this; + } -inline NzIndexIterator NzIndexIterator::operator--(int) -{ - NzIndexIterator iterator(*this); - operator--(); + inline IndexIterator IndexIterator::operator--(int) + { + IndexIterator iterator(*this); + operator--(); - return iterator; -} + return iterator; + } -inline bool operator==(const NzIndexIterator& lhs, const NzIndexIterator& rhs) -{ - return lhs.m_mapper == rhs.m_mapper && lhs.m_index == rhs.m_index; -} + inline bool operator==(const IndexIterator& lhs, const IndexIterator& rhs) + { + return lhs.m_mapper == rhs.m_mapper && lhs.m_index == rhs.m_index; + } -inline bool operator!=(const NzIndexIterator& lhs, const NzIndexIterator& rhs) -{ - return !operator==(lhs, rhs); -} + inline bool operator!=(const IndexIterator& lhs, const IndexIterator& rhs) + { + return !operator==(lhs, rhs); + } -inline bool operator<(const NzIndexIterator& lhs, const NzIndexIterator& rhs) -{ - if (lhs.m_mapper == rhs.m_mapper) - return lhs.m_index < rhs.m_index; - else - return lhs.m_mapper < rhs.m_mapper; -} + inline bool operator<(const IndexIterator& lhs, const IndexIterator& rhs) + { + if (lhs.m_mapper == rhs.m_mapper) + return lhs.m_index < rhs.m_index; + else + return lhs.m_mapper < rhs.m_mapper; + } -inline bool operator<=(const NzIndexIterator& lhs, const NzIndexIterator& rhs) -{ - return !operator<(rhs, lhs); -} + inline bool operator<=(const IndexIterator& lhs, const IndexIterator& rhs) + { + return !operator<(rhs, lhs); + } -inline bool operator>(const NzIndexIterator& lhs, const NzIndexIterator& rhs) -{ - return operator<(rhs, lhs); -} + inline bool operator>(const IndexIterator& lhs, const IndexIterator& rhs) + { + return operator<(rhs, lhs); + } -inline bool operator>=(const NzIndexIterator& lhs, const NzIndexIterator& rhs) -{ - return !operator<(lhs, rhs); -} + inline bool operator>=(const IndexIterator& lhs, const IndexIterator& rhs) + { + return !operator<(lhs, rhs); + } -/**************************NzIndexIterator::Reference*************************/ + /**************************IndexIterator::Reference*************************/ -inline NzIndexIterator::Reference::Reference(NzIndexMapper* mapper, unsigned int index) : -m_mapper(mapper), -m_index(index) -{ -} + inline IndexIterator::Reference::Reference(IndexMapper* mapper, unsigned int index) : + m_mapper(mapper), + m_index(index) + { + } -inline NzIndexIterator::Reference& NzIndexIterator::Reference::operator=(nzUInt32 value) -{ - m_mapper->Set(m_index, value); + inline IndexIterator::Reference& IndexIterator::Reference::operator=(UInt32 value) + { + m_mapper->Set(m_index, value); - return *this; -} + return *this; + } -inline NzIndexIterator::Reference& NzIndexIterator::Reference::operator=(const NzIndexIterator::Reference& reference) -{ - m_mapper->Set(m_index, reference); // Conversion implicite en UInt32 + inline IndexIterator::Reference& IndexIterator::Reference::operator=(const IndexIterator::Reference& reference) + { + m_mapper->Set(m_index, reference); // Conversion implicite en UInt32 - return *this; -} + return *this; + } -inline NzIndexIterator::Reference::operator nzUInt32() const -{ - return m_mapper->Get(m_index); + inline IndexIterator::Reference::operator UInt32() const + { + return m_mapper->Get(m_index); + } } namespace std { template<> - struct iterator_traits + struct iterator_traits { using difference_type = ptrdiff_t; using iterator_category = random_access_iterator_tag; - using reference = const NzIndexIterator::Reference&; - using pointer = const NzIndexIterator::Reference*; - using value_type = NzIndexIterator::Reference; + using reference = const Nz::IndexIterator::Reference&; + using pointer = const Nz::IndexIterator::Reference*; + using value_type = Nz::IndexIterator::Reference; }; } diff --git a/include/Nazara/Utility/IndexMapper.hpp b/include/Nazara/Utility/IndexMapper.hpp index b8ca13535..9dd6a5c46 100644 --- a/include/Nazara/Utility/IndexMapper.hpp +++ b/include/Nazara/Utility/IndexMapper.hpp @@ -11,41 +11,44 @@ #include #include -class NzIndexBuffer; -class NzIndexIterator; -class NzSubMesh; - -using NzIndexMapperGetter = nzUInt32 (*)(const void* buffer, unsigned int i); -using NzIndexMapperSetter = void (*)(void* buffer, unsigned int i, nzUInt32 value); - -class NAZARA_UTILITY_API NzIndexMapper +namespace Nz { - public: - NzIndexMapper(NzIndexBuffer* indexBuffer, nzBufferAccess access = nzBufferAccess_ReadWrite); - NzIndexMapper(const NzIndexBuffer* indexBuffer, nzBufferAccess access = nzBufferAccess_ReadOnly); - NzIndexMapper(const NzSubMesh* subMesh); - ~NzIndexMapper() = default; + class IndexBuffer; + class IndexIterator; + class SubMesh; - nzUInt32 Get(unsigned int i) const; - const NzIndexBuffer* GetBuffer() const; - unsigned int GetIndexCount() const; + using IndexMapperGetter = UInt32 (*)(const void* buffer, unsigned int i); + using IndexMapperSetter = void (*)(void* buffer, unsigned int i, UInt32 value); - void Set(unsigned int i, nzUInt32 value); + class NAZARA_UTILITY_API IndexMapper + { + public: + IndexMapper(IndexBuffer* indexBuffer, BufferAccess access = BufferAccess_ReadWrite); + IndexMapper(const IndexBuffer* indexBuffer, BufferAccess access = BufferAccess_ReadOnly); + IndexMapper(const SubMesh* subMesh); + ~IndexMapper() = default; - void Unmap(); + UInt32 Get(unsigned int i) const; + const IndexBuffer* GetBuffer() const; + unsigned int GetIndexCount() const; - // Méthodes STD - NzIndexIterator begin(); - //NzIndexConstIterator begin() const; - NzIndexIterator end(); - //NzIndexIterator end() const; - // Méthodes STD + void Set(unsigned int i, UInt32 value); - private: - NzBufferMapper m_mapper; - NzIndexMapperGetter m_getter; - NzIndexMapperSetter m_setter; - unsigned int m_indexCount; + void Unmap(); + + // Méthodes STD + IndexIterator begin(); + //IndexConstIterator begin() const; + IndexIterator end(); + //IndexIterator end() const; + // Méthodes STD + + private: + BufferMapper m_mapper; + IndexMapperGetter m_getter; + IndexMapperSetter m_setter; + unsigned int m_indexCount; }; +} #endif // NAZARA_INDEXMAPPER_HPP diff --git a/include/Nazara/Utility/Joint.hpp b/include/Nazara/Utility/Joint.hpp index 59747f3aa..77227a605 100644 --- a/include/Nazara/Utility/Joint.hpp +++ b/include/Nazara/Utility/Joint.hpp @@ -12,35 +12,38 @@ #include #include -class NzSkeleton; - -class NAZARA_UTILITY_API NzJoint : public NzNode +namespace Nz { - public: - NzJoint(NzSkeleton* skeleton); - NzJoint(const NzJoint& joint); - ~NzJoint() = default; + class Skeleton; - void EnsureSkinningMatrixUpdate() const; + class NAZARA_UTILITY_API Joint : public Node + { + public: + Joint(Skeleton* skeleton); + Joint(const Joint& joint); + ~Joint() = default; - const NzMatrix4f& GetInverseBindMatrix() const; - NzString GetName() const; - NzSkeleton* GetSkeleton(); - const NzSkeleton* GetSkeleton() const; - const NzMatrix4f& GetSkinningMatrix() const; + void EnsureSkinningMatrixUpdate() const; - void SetInverseBindMatrix(const NzMatrix4f& matrix); - void SetName(const NzString& name); + const Matrix4f& GetInverseBindMatrix() const; + String GetName() const; + Skeleton* GetSkeleton(); + const Skeleton* GetSkeleton() const; + const Matrix4f& GetSkinningMatrix() const; - private: - void InvalidateNode(); - void UpdateSkinningMatrix() const; + void SetInverseBindMatrix(const Matrix4f& matrix); + void SetName(const String& name); - NzMatrix4f m_inverseBindMatrix; - mutable NzMatrix4f m_skinningMatrix; - NzString m_name; - NzSkeleton* m_skeleton; - mutable bool m_skinningMatrixUpdated; -}; + private: + void InvalidateNode(); + void UpdateSkinningMatrix() const; + + Matrix4f m_inverseBindMatrix; + mutable Matrix4f m_skinningMatrix; + String m_name; + Skeleton* m_skeleton; + mutable bool m_skinningMatrixUpdated; + }; +} #endif // NAZARA_JOINT_HPP diff --git a/include/Nazara/Utility/Joystick.hpp b/include/Nazara/Utility/Joystick.hpp index 457cf0aa1..ce84c9473 100644 --- a/include/Nazara/Utility/Joystick.hpp +++ b/include/Nazara/Utility/Joystick.hpp @@ -10,15 +10,18 @@ #include #include -class NAZARA_UTILITY_API NzJoystick +namespace Nz { - public: - NzJoystick() = delete; - ~NzJoystick() = delete; + class NAZARA_UTILITY_API Joystick + { + public: + Joystick() = delete; + ~Joystick() = delete; - static unsigned int GetMaxJoystickCount(); + static unsigned int GetMaxJoystickCount(); - static void Update(); -}; + static void Update(); + }; +} #endif // NAZARA_JOYSTICK_HPP diff --git a/include/Nazara/Utility/Keyboard.hpp b/include/Nazara/Utility/Keyboard.hpp index a6024756d..8eea51ff5 100644 --- a/include/Nazara/Utility/Keyboard.hpp +++ b/include/Nazara/Utility/Keyboard.hpp @@ -13,160 +13,163 @@ #include #include -class NAZARA_UTILITY_API NzKeyboard +namespace Nz { - public: - enum Key - { - Undefined = -1, + class NAZARA_UTILITY_API Keyboard + { + public: + enum Key + { + Undefined = -1, - // Lettres - A, - B, - C, - D, - E, - F, - G, - H, - I, - J, - K, - L, - M, - N, - O, - P, - Q, - R, - S, - T, - U, - V, - W, - X, - Y, - Z, + // Lettres + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, - // Touches de fonction - F1, - F2, - F3, - F4, - F5, - F6, - F7, - F8, - F9, - F10, - F11, - F12, - F13, - F14, - F15, + // Touches de fonction + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + F13, + F14, + F15, - // Flèches directionnelles - Down, - Left, - Right, - Up, + // Flèches directionnelles + Down, + Left, + Right, + Up, - // Pavé numérique - Add, - Decimal, - Divide, - Multiply, - Numpad0, - Numpad1, - Numpad2, - Numpad3, - Numpad4, - Numpad5, - Numpad6, - Numpad7, - Numpad8, - Numpad9, - Subtract, + // Pavé numérique + Add, + Decimal, + Divide, + Multiply, + Numpad0, + Numpad1, + Numpad2, + Numpad3, + Numpad4, + Numpad5, + Numpad6, + Numpad7, + Numpad8, + Numpad9, + Subtract, - // Divers - Backslash, - Backspace, - Clear, - Comma, - Dash, - Delete, - End, - Equal, - Escape, - Home, - Insert, - LAlt, - LBracket, - LControl, - LShift, - LSystem, - Num0, - Num1, - Num2, - Num3, - Num4, - Num5, - Num6, - Num7, - Num8, - Num9, - PageDown, - PageUp, - Pause, - Period, - Print, - PrintScreen, - Quote, - RAlt, - RBracket, - RControl, - Return, - RShift, - RSystem, - Semicolon, - Slash, - Space, - Tab, - Tilde, + // Divers + Backslash, + Backspace, + Clear, + Comma, + Dash, + Delete, + End, + Equal, + Escape, + Home, + Insert, + LAlt, + LBracket, + LControl, + LShift, + LSystem, + Num0, + Num1, + Num2, + Num3, + Num4, + Num5, + Num6, + Num7, + Num8, + Num9, + PageDown, + PageUp, + Pause, + Period, + Print, + PrintScreen, + Quote, + RAlt, + RBracket, + RControl, + Return, + RShift, + RSystem, + Semicolon, + Slash, + Space, + Tab, + Tilde, - // Touches navigateur - Browser_Back, - Browser_Favorites, - Browser_Forward, - Browser_Home, - Browser_Refresh, - Browser_Search, - Browser_Stop, + // Touches navigateur + Browser_Back, + Browser_Favorites, + Browser_Forward, + Browser_Home, + Browser_Refresh, + Browser_Search, + Browser_Stop, - // Touches de contrôle de lecture - Media_Next, - Media_Play, - Media_Previous, - Media_Stop, + // Touches de contrôle de lecture + Media_Next, + Media_Play, + Media_Previous, + Media_Stop, - // Touches de contrôle du volume - Volume_Down, - Volume_Mute, - Volume_Up, + // Touches de contrôle du volume + Volume_Down, + Volume_Mute, + Volume_Up, - // Touches à verrouillage - CapsLock, - NumLock, - ScrollLock, + // Touches à verrouillage + CapsLock, + NumLock, + ScrollLock, - Count - }; + Count + }; - NzKeyboard() = delete; - ~NzKeyboard() = delete; + Keyboard() = delete; + ~Keyboard() = delete; - static NzString GetKeyName(Key key); - static bool IsKeyPressed(Key key); -}; + static String GetKeyName(Key key); + static bool IsKeyPressed(Key key); + }; +} #endif // NAZARA_KEYBOARD_HPP diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 0bb29401d..691c8f3ed 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -22,127 +22,130 @@ #include #include -struct NAZARA_UTILITY_API NzMeshParams +namespace Nz { - NzMeshParams(); // Vérifie que le storage par défaut est supporté (software autrement) + struct NAZARA_UTILITY_API MeshParams + { + MeshParams(); // Vérifie que le storage par défaut est supporté (software autrement) - // La mise à l'échelle éventuelle que subira le mesh - NzVector3f scale = NzVector3f::Unit(); + // La mise à l'échelle éventuelle que subira le mesh + Vector3f scale = Vector3f::Unit(); - // Si ceci sera le stockage utilisé par les buffers - nzUInt32 storage = nzDataStorage_Hardware; + // Si ceci sera le stockage utilisé par les buffers + UInt32 storage = DataStorage_Hardware; - // Charger une version animée du mesh si possible ? - bool animated = true; + // Charger une version animée du mesh si possible ? + bool animated = true; - // Faut-il centrer le mesh autour de l'origine ? - bool center = false; + // Faut-il centrer le mesh autour de l'origine ? + bool center = false; - // Faut-il retourner les UV ? - bool flipUVs = false; + // Faut-il retourner les UV ? + bool flipUVs = false; - // Faut-il optimiser les index buffers ? (Rendu plus rapide, mais le chargement dure plus longtemps) - bool optimizeIndexBuffers = true; + // Faut-il optimiser les index buffers ? (Rendu plus rapide, mais le chargement dure plus longtemps) + bool optimizeIndexBuffers = true; - bool IsValid() const; -}; - -class NzMesh; -class NzPrimitiveList; - -typedef NzVertexStruct_XYZ_Normal_UV_Tangent NzMeshVertex; -typedef NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning NzSkeletalMeshVertex; - -using NzMeshConstRef = NzObjectRef; -using NzMeshLibrary = NzObjectLibrary; -using NzMeshLoader = NzResourceLoader; -using NzMeshManager = NzResourceManager; -using NzMeshRef = NzObjectRef; - -struct NzMeshImpl; - -class NAZARA_UTILITY_API NzMesh : public NzRefCounted, public NzResource -{ - friend NzMeshLibrary; - friend NzMeshLoader; - friend NzMeshManager; - friend class NzUtility; - - public: - NzMesh() = default; - ~NzMesh(); - - void AddSubMesh(NzSubMesh* subMesh); - void AddSubMesh(const NzString& identifier, NzSubMesh* subMesh); - - NzSubMesh* BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& params = NzMeshParams()); - void BuildSubMeshes(const NzPrimitiveList& list, const NzMeshParams& params = NzMeshParams()); - - bool CreateSkeletal(unsigned int jointCount); - bool CreateStatic(); - void Destroy(); - - void GenerateNormals(); - void GenerateNormalsAndTangents(); - void GenerateTangents(); - - const NzBoxf& GetAABB() const; - NzString GetAnimation() const; - nzAnimationType GetAnimationType() const; - unsigned int GetJointCount() const; - NzString GetMaterial(unsigned int index) const; - unsigned int GetMaterialCount() const; - NzSkeleton* GetSkeleton(); - const NzSkeleton* GetSkeleton() const; - NzSubMesh* GetSubMesh(const NzString& identifier); - NzSubMesh* GetSubMesh(unsigned int index); - const NzSubMesh* GetSubMesh(const NzString& identifier) const; - const NzSubMesh* GetSubMesh(unsigned int index) const; - unsigned int GetSubMeshCount() const; - int GetSubMeshIndex(const NzString& identifier) const; - unsigned int GetTriangleCount() const; - unsigned int GetVertexCount() const; - - bool HasSubMesh(const NzString& identifier) const; - bool HasSubMesh(unsigned int index = 0) const; - - void InvalidateAABB() const; - - bool IsAnimable() const; bool IsValid() const; + }; - bool LoadFromFile(const NzString& filePath, const NzMeshParams& params = NzMeshParams()); - bool LoadFromMemory(const void* data, std::size_t size, const NzMeshParams& params = NzMeshParams()); - bool LoadFromStream(NzInputStream& stream, const NzMeshParams& params = NzMeshParams()); + class Mesh; + class PrimitiveList; - void Recenter(); + typedef VertexStruct_XYZ_Normal_UV_Tangent MeshVertex; + typedef VertexStruct_XYZ_Normal_UV_Tangent_Skinning SkeletalMeshVertex; - void RemoveSubMesh(const NzString& identifier); - void RemoveSubMesh(unsigned int index); + using MeshConstRef = ObjectRef; + using MeshLibrary = ObjectLibrary; + using MeshLoader = ResourceLoader; + using MeshManager = ResourceManager; + using MeshRef = ObjectRef; - void SetAnimation(const NzString& animationPath); - void SetMaterial(unsigned int matIndex, const NzString& materialPath); - void SetMaterialCount(unsigned int matCount); + struct MeshImpl; - void Transform(const NzMatrix4f& matrix); + class NAZARA_UTILITY_API Mesh : public RefCounted, public Resource + { + friend MeshLibrary; + friend MeshLoader; + friend MeshManager; + friend class Utility; - template static NzMeshRef New(Args&&... args); + public: + Mesh() = default; + ~Mesh(); - // Signals: - NazaraSignal(OnMeshDestroy, const NzMesh* /*mesh*/); - NazaraSignal(OnMeshRelease, const NzMesh* /*mesh*/); + void AddSubMesh(SubMesh* subMesh); + void AddSubMesh(const String& identifier, SubMesh* subMesh); - private: - NzMeshImpl* m_impl = nullptr; + SubMesh* BuildSubMesh(const Primitive& primitive, const MeshParams& params = MeshParams()); + void BuildSubMeshes(const PrimitiveList& list, const MeshParams& params = MeshParams()); - static bool Initialize(); - static void Uninitialize(); + bool CreateSkeletal(unsigned int jointCount); + bool CreateStatic(); + void Destroy(); - static NzMeshLibrary::LibraryMap s_library; - static NzMeshLoader::LoaderList s_loaders; - static NzMeshManager::ManagerMap s_managerMap; - static NzMeshManager::ManagerParams s_managerParameters; -}; + void GenerateNormals(); + void GenerateNormalsAndTangents(); + void GenerateTangents(); + + const Boxf& GetAABB() const; + String GetAnimation() const; + AnimationType GetAnimationType() const; + unsigned int GetJointCount() const; + String GetMaterial(unsigned int index) const; + unsigned int GetMaterialCount() const; + Skeleton* GetSkeleton(); + const Skeleton* GetSkeleton() const; + SubMesh* GetSubMesh(const String& identifier); + SubMesh* GetSubMesh(unsigned int index); + const SubMesh* GetSubMesh(const String& identifier) const; + const SubMesh* GetSubMesh(unsigned int index) const; + unsigned int GetSubMeshCount() const; + int GetSubMeshIndex(const String& identifier) const; + unsigned int GetTriangleCount() const; + unsigned int GetVertexCount() const; + + bool HasSubMesh(const String& identifier) const; + bool HasSubMesh(unsigned int index = 0) const; + + void InvalidateAABB() const; + + bool IsAnimable() const; + bool IsValid() const; + + bool LoadFromFile(const String& filePath, const MeshParams& params = MeshParams()); + bool LoadFromMemory(const void* data, std::size_t size, const MeshParams& params = MeshParams()); + bool LoadFromStream(InputStream& stream, const MeshParams& params = MeshParams()); + + void Recenter(); + + void RemoveSubMesh(const String& identifier); + void RemoveSubMesh(unsigned int index); + + void SetAnimation(const String& animationPath); + void SetMaterial(unsigned int matIndex, const String& materialPath); + void SetMaterialCount(unsigned int matCount); + + void Transform(const Matrix4f& matrix); + + template static MeshRef New(Args&&... args); + + // Signals: + NazaraSignal(OnMeshDestroy, const Mesh* /*mesh*/); + NazaraSignal(OnMeshRelease, const Mesh* /*mesh*/); + + private: + MeshImpl* m_impl = nullptr; + + static bool Initialize(); + static void Uninitialize(); + + static MeshLibrary::LibraryMap s_library; + static MeshLoader::LoaderList s_loaders; + static MeshManager::ManagerMap s_managerMap; + static MeshManager::ManagerParams s_managerParameters; + }; +} #include diff --git a/include/Nazara/Utility/Mesh.inl b/include/Nazara/Utility/Mesh.inl index 73252c536..4877e03fe 100644 --- a/include/Nazara/Utility/Mesh.inl +++ b/include/Nazara/Utility/Mesh.inl @@ -5,13 +5,16 @@ #include #include -template -NzMeshRef NzMesh::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzMesh(std::forward(args)...)); - object->SetPersistent(false); + template + MeshRef Mesh::New(Args&&... args) + { + std::unique_ptr object(new Mesh(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Utility/MeshData.hpp b/include/Nazara/Utility/MeshData.hpp index ff12d3681..e9a3021f6 100644 --- a/include/Nazara/Utility/MeshData.hpp +++ b/include/Nazara/Utility/MeshData.hpp @@ -9,14 +9,17 @@ #include -class NzIndexBuffer; -class NzVertexBuffer; - -struct NzMeshData +namespace Nz { - nzPrimitiveMode primitiveMode; - const NzIndexBuffer* indexBuffer; - const NzVertexBuffer* vertexBuffer; -}; + class IndexBuffer; + class VertexBuffer; + + struct MeshData + { + PrimitiveMode primitiveMode; + const IndexBuffer* indexBuffer; + const VertexBuffer* vertexBuffer; + }; +} #endif // NAZARA_MESHDATA_HPP diff --git a/include/Nazara/Utility/Mouse.hpp b/include/Nazara/Utility/Mouse.hpp index 7bfa580b6..47fd7a1e0 100644 --- a/include/Nazara/Utility/Mouse.hpp +++ b/include/Nazara/Utility/Mouse.hpp @@ -13,32 +13,35 @@ #include #include -class NzWindow; - -class NAZARA_UTILITY_API NzMouse +namespace Nz { - public: - enum Button - { - Left, - Middle, - Right, - XButton1, - XButton2, + class Window; - Max = XButton2 - }; + class NAZARA_UTILITY_API Mouse + { + public: + enum Button + { + Left, + Middle, + Right, + XButton1, + XButton2, - NzMouse() = delete; - ~NzMouse() = delete; + Max = XButton2 + }; - static NzVector2i GetPosition(); - static NzVector2i GetPosition(const NzWindow& relativeTo); - static bool IsButtonPressed(Button button); - static void SetPosition(const NzVector2i& position); - static void SetPosition(const NzVector2i& position, const NzWindow& relativeTo, bool ignoreEvent = true); - static void SetPosition(int x, int y); - static void SetPosition(int x, int y, const NzWindow& relativeTo, bool ignoreEvent = true); -}; + Mouse() = delete; + ~Mouse() = delete; + + static Vector2i GetPosition(); + static Vector2i GetPosition(const Window& relativeTo); + static bool IsButtonPressed(Button button); + static void SetPosition(const Vector2i& position); + static void SetPosition(const Vector2i& position, const Window& relativeTo, bool ignoreEvent = true); + static void SetPosition(int x, int y); + static void SetPosition(int x, int y, const Window& relativeTo, bool ignoreEvent = true); + }; +} #endif // NAZARA_MOUSE_HPP diff --git a/include/Nazara/Utility/Node.hpp b/include/Nazara/Utility/Node.hpp index 016eb0047..319a99e25 100644 --- a/include/Nazara/Utility/Node.hpp +++ b/include/Nazara/Utility/Node.hpp @@ -17,110 +17,113 @@ #include #include -class NAZARA_UTILITY_API NzNode +namespace Nz { - public: - NzNode(); - NzNode(const NzNode& node); - virtual ~NzNode(); + class NAZARA_UTILITY_API Node + { + public: + Node(); + Node(const Node& node); + virtual ~Node(); - void EnsureDerivedUpdate() const; - void EnsureTransformMatrixUpdate() const; + void EnsureDerivedUpdate() const; + void EnsureTransformMatrixUpdate() const; - virtual NzVector3f GetBackward() const; - const std::vector& GetChilds() const; - virtual NzVector3f GetDown() const; - virtual NzVector3f GetForward() const; - bool GetInheritPosition() const; - bool GetInheritRotation() const; - bool GetInheritScale() const; - NzVector3f GetInitialPosition() const; - NzQuaternionf GetInitialRotation() const; - NzVector3f GetInitialScale() const; - virtual NzVector3f GetLeft() const; - virtual nzNodeType GetNodeType() const; - const NzNode* GetParent() const; - NzVector3f GetPosition(nzCoordSys coordSys = nzCoordSys_Global) const; - virtual NzVector3f GetRight() const; - NzQuaternionf GetRotation(nzCoordSys coordSys = nzCoordSys_Global) const; - NzVector3f GetScale(nzCoordSys coordSys = nzCoordSys_Global) const; - const NzMatrix4f& GetTransformMatrix() const; - virtual NzVector3f GetUp() const; + virtual Vector3f GetBackward() const; + const std::vector& GetChilds() const; + virtual Vector3f GetDown() const; + virtual Vector3f GetForward() const; + bool GetInheritPosition() const; + bool GetInheritRotation() const; + bool GetInheritScale() const; + Vector3f GetInitialPosition() const; + Quaternionf GetInitialRotation() const; + Vector3f GetInitialScale() const; + virtual Vector3f GetLeft() const; + virtual nzNodeType GetNodeType() const; + const Node* GetParent() const; + Vector3f GetPosition(CoordSys coordSys = CoordSys_Global) const; + virtual Vector3f GetRight() const; + Quaternionf GetRotation(CoordSys coordSys = CoordSys_Global) const; + Vector3f GetScale(CoordSys coordSys = CoordSys_Global) const; + const Matrix4f& GetTransformMatrix() const; + virtual Vector3f GetUp() const; - bool HasChilds() const; + bool HasChilds() const; - NzNode& Interpolate(const NzNode& nodeA, const NzNode& nodeB, float interpolation, nzCoordSys coordSys = nzCoordSys_Global); + Node& Interpolate(const Node& nodeA, const Node& nodeB, float interpolation, CoordSys coordSys = CoordSys_Global); - NzNode& Move(const NzVector3f& movement, nzCoordSys coordSys = nzCoordSys_Local); - NzNode& Move(float movementX, float movementY, float movementZ = 0.f, nzCoordSys coordSys = nzCoordSys_Local); + Node& Move(const Vector3f& movement, CoordSys coordSys = CoordSys_Local); + Node& Move(float movementX, float movementY, float movementZ = 0.f, CoordSys coordSys = CoordSys_Local); - NzNode& Rotate(const NzQuaternionf& rotation, nzCoordSys coordSys = nzCoordSys_Local); + Node& Rotate(const Quaternionf& rotation, CoordSys coordSys = CoordSys_Local); - NzNode& Scale(const NzVector3f& scale); - NzNode& Scale(float scale); - NzNode& Scale(float scaleX, float scaleY, float scaleZ = 1.f); + Node& Scale(const Vector3f& scale); + Node& Scale(float scale); + Node& Scale(float scaleX, float scaleY, float scaleZ = 1.f); - void SetInheritRotation(bool inheritRotation); - void SetInheritScale(bool inheritScale); - void SetInheritPosition(bool inheritPosition); - void SetInitialRotation(const NzQuaternionf& quat); - void SetInitialScale(const NzVector3f& scale); - void SetInitialScale(float scale); - void SetInitialScale(float scaleX, float scaleY, float scaleZ = 1.f); - void SetInitialPosition(const NzVector3f& translation); - void SetInitialPosition(float translationX, float translationXY, float translationZ = 0.f); - void SetParent(const NzNode* node = nullptr, bool keepDerived = false); - void SetParent(const NzNode& node, bool keepDerived = false); - void SetPosition(const NzVector3f& translation, nzCoordSys coordSys = nzCoordSys_Local); - void SetPosition(float translationX, float translationY, float translationZ = 0.f, nzCoordSys coordSys = nzCoordSys_Local); - void SetRotation(const NzQuaternionf& quat, nzCoordSys coordSys = nzCoordSys_Local); - void SetScale(const NzVector3f& scale, nzCoordSys coordSys = nzCoordSys_Local); - void SetScale(float scale, nzCoordSys coordSys = nzCoordSys_Local); - void SetScale(float scaleX, float scaleY, float scaleZ = 1.f, nzCoordSys coordSys = nzCoordSys_Local); - void SetTransformMatrix(const NzMatrix4f& matrix); + void SetInheritRotation(bool inheritRotation); + void SetInheritScale(bool inheritScale); + void SetInheritPosition(bool inheritPosition); + void SetInitialRotation(const Quaternionf& quat); + void SetInitialScale(const Vector3f& scale); + void SetInitialScale(float scale); + void SetInitialScale(float scaleX, float scaleY, float scaleZ = 1.f); + void SetInitialPosition(const Vector3f& translation); + void SetInitialPosition(float translationX, float translationXY, float translationZ = 0.f); + void SetParent(const Node* node = nullptr, bool keepDerived = false); + void SetParent(const Node& node, bool keepDerived = false); + void SetPosition(const Vector3f& translation, CoordSys coordSys = CoordSys_Local); + void SetPosition(float translationX, float translationY, float translationZ = 0.f, CoordSys coordSys = CoordSys_Local); + void SetRotation(const Quaternionf& quat, CoordSys coordSys = CoordSys_Local); + void SetScale(const Vector3f& scale, CoordSys coordSys = CoordSys_Local); + void SetScale(float scale, CoordSys coordSys = CoordSys_Local); + void SetScale(float scaleX, float scaleY, float scaleZ = 1.f, CoordSys coordSys = CoordSys_Local); + void SetTransformMatrix(const Matrix4f& matrix); - // Local -> global - NzVector3f ToGlobalPosition(const NzVector3f& localPosition) const; - NzQuaternionf ToGlobalRotation(const NzQuaternionf& localRotation) const; - NzVector3f ToGlobalScale(const NzVector3f& localScale) const; + // Local -> global + Vector3f ToGlobalPosition(const Vector3f& localPosition) const; + Quaternionf ToGlobalRotation(const Quaternionf& localRotation) const; + Vector3f ToGlobalScale(const Vector3f& localScale) const; - // Global -> local - NzVector3f ToLocalPosition(const NzVector3f& globalPosition) const; - NzQuaternionf ToLocalRotation(const NzQuaternionf& globalRotation) const; - NzVector3f ToLocalScale(const NzVector3f& globalScale) const; + // Global -> local + Vector3f ToLocalPosition(const Vector3f& globalPosition) const; + Quaternionf ToLocalRotation(const Quaternionf& globalRotation) const; + Vector3f ToLocalScale(const Vector3f& globalScale) const; - NzNode& operator=(const NzNode& node); + Node& operator=(const Node& node); - // Signals: - NazaraSignal(OnNodeInvalidation, const NzNode* /*node*/); - NazaraSignal(OnNodeNewParent, const NzNode* /*node*/, const NzNode* /*parent*/); - NazaraSignal(OnNodeRelease, const NzNode* /*node*/); + // Signals: + NazaraSignal(OnNodeInvalidation, const Node* /*node*/); + NazaraSignal(OnNodeNewParent, const Node* /*node*/, const Node* /*parent*/); + NazaraSignal(OnNodeRelease, const Node* /*node*/); - protected: - void AddChild(NzNode* node) const; - virtual void InvalidateNode(); - virtual void OnParenting(const NzNode* parent); - void RemoveChild(NzNode* node) const; - virtual void UpdateDerived() const; - virtual void UpdateTransformMatrix() const; + protected: + void AddChild(Node* node) const; + virtual void InvalidateNode(); + virtual void OnParenting(const Node* parent); + void RemoveChild(Node* node) const; + virtual void UpdateDerived() const; + virtual void UpdateTransformMatrix() const; - mutable std::vector m_childs; - mutable NzMatrix4f m_transformMatrix; - mutable NzQuaternionf m_derivedRotation; - NzQuaternionf m_initialRotation; - NzQuaternionf m_rotation; - mutable NzVector3f m_derivedPosition; - mutable NzVector3f m_derivedScale; - NzVector3f m_initialPosition; - NzVector3f m_initialScale; - NzVector3f m_position; - NzVector3f m_scale; - const NzNode* m_parent; - mutable bool m_derivedUpdated; - bool m_inheritPosition; - bool m_inheritRotation; - bool m_inheritScale; - mutable bool m_transformMatrixUpdated; -}; + mutable std::vector m_childs; + mutable Matrix4f m_transformMatrix; + mutable Quaternionf m_derivedRotation; + Quaternionf m_initialRotation; + Quaternionf m_rotation; + mutable Vector3f m_derivedPosition; + mutable Vector3f m_derivedScale; + Vector3f m_initialPosition; + Vector3f m_initialScale; + Vector3f m_position; + Vector3f m_scale; + const Node* m_parent; + mutable bool m_derivedUpdated; + bool m_inheritPosition; + bool m_inheritRotation; + bool m_inheritScale; + mutable bool m_transformMatrixUpdated; + }; +} #endif // NAZARA_NODE_HPP diff --git a/include/Nazara/Utility/PixelFormat.hpp b/include/Nazara/Utility/PixelFormat.hpp index c7068868a..279d65774 100644 --- a/include/Nazara/Utility/PixelFormat.hpp +++ b/include/Nazara/Utility/PixelFormat.hpp @@ -18,41 +18,44 @@ /// Ce serait plus lent que la conversion spécialisée (qui ne disparaîtra donc pas) mais ça permettrait au moteur de faire la conversion /// entre n'importe quels formats non-compressés. -class NzPixelFormat +namespace Nz { - friend class NzUtility; + class NzPixelFormat + { + friend class Utility; - public: - using ConvertFunction = std::function; - using FlipFunction = std::function; + public: + using ConvertFunction = std::function; + using FlipFunction = std::function; - static bool Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* src, void* dst); - static bool Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* start, const void* end, void* dst); + static bool Convert(PixelFormatType srcFormat, PixelFormatType dstFormat, const void* src, void* dst); + static bool Convert(PixelFormatType srcFormat, PixelFormatType dstFormat, const void* start, const void* end, void* dst); - static bool Flip(nzPixelFlipping flipping, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst); + static bool Flip(PixelFlipping flipping, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst); - static nzUInt8 GetBitsPerPixel(nzPixelFormat format); - static nzUInt8 GetBytesPerPixel(nzPixelFormat format); - static nzPixelFormatType GetType(nzPixelFormat format); + static UInt8 GetBitsPerPixel(PixelFormatType format); + static UInt8 GetBytesPerPixel(PixelFormatType format); + static PixelFormatTypeType GetType(PixelFormatType format); - static bool HasAlpha(nzPixelFormat format); + static bool HasAlpha(PixelFormatType format); - static bool IsCompressed(nzPixelFormat format); - static bool IsConversionSupported(nzPixelFormat srcFormat, nzPixelFormat dstFormat); - static bool IsValid(nzPixelFormat format); + static bool IsCompressed(PixelFormatType format); + static bool IsConversionSupported(PixelFormatType srcFormat, PixelFormatType dstFormat); + static bool IsValid(PixelFormatType format); - static void SetConvertFunction(nzPixelFormat srcFormat, nzPixelFormat dstFormat, ConvertFunction func); - static void SetFlipFunction(nzPixelFlipping flipping, nzPixelFormat format, FlipFunction func); + static void SetConvertFunction(PixelFormatType srcFormat, PixelFormatType dstFormat, ConvertFunction func); + static void SetFlipFunction(PixelFlipping flipping, PixelFormatType format, FlipFunction func); - static NzString ToString(nzPixelFormat format); + static String ToString(PixelFormatType format); - private: - static bool Initialize(); - static void Uninitialize(); + private: + static bool Initialize(); + static void Uninitialize(); - static NAZARA_UTILITY_API ConvertFunction s_convertFunctions[nzPixelFormat_Max+1][nzPixelFormat_Max+1]; - static NAZARA_UTILITY_API std::map s_flipFunctions[nzPixelFlipping_Max+1]; -}; + static NAZARA_UTILITY_API ConvertFunction s_convertFunctions[PixelFormatType_Max+1][PixelFormatType_Max+1]; + static NAZARA_UTILITY_API std::map s_flipFunctions[PixelFlipping_Max+1]; + }; +} #include diff --git a/include/Nazara/Utility/PixelFormat.inl b/include/Nazara/Utility/PixelFormat.inl index 296bdc503..45cc81714 100644 --- a/include/Nazara/Utility/PixelFormat.inl +++ b/include/Nazara/Utility/PixelFormat.inl @@ -7,690 +7,693 @@ #include #include -inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* src, void* dst) +namespace Nz { - if (srcFormat == dstFormat) + inline bool NzPixelFormat::Convert(PixelFormatType srcFormat, PixelFormatType dstFormat, const void* src, void* dst) { - std::memcpy(dst, src, GetBytesPerPixel(srcFormat)); - return true; - } - - #if NAZARA_UTILITY_SAFE - if (IsCompressed(srcFormat)) - { - NazaraError("Cannot convert single pixel from compressed format"); - return false; - } - - if (IsCompressed(dstFormat)) - { - NazaraError("Cannot convert single pixel to compressed format"); - return false; - } - #endif - - ConvertFunction func = s_convertFunctions[srcFormat][dstFormat]; - if (!func) - { - NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported"); - return false; - } - - if (!func(reinterpret_cast(src), reinterpret_cast(src) + GetBytesPerPixel(srcFormat), reinterpret_cast(dst))) - { - NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " failed"); - return false; - } - - return true; -} - -inline bool NzPixelFormat::Convert(nzPixelFormat srcFormat, nzPixelFormat dstFormat, const void* start, const void* end, void* dst) -{ - if (srcFormat == dstFormat) - { - std::memcpy(dst, start, reinterpret_cast(end)-reinterpret_cast(start)); - return true; - } - - ConvertFunction func = s_convertFunctions[srcFormat][dstFormat]; - if (!func) - { - NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported"); - return false; - } - - if (!func(reinterpret_cast(start), reinterpret_cast(end), reinterpret_cast(dst))) - { - NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " failed"); - return false; - } - - return true; -} - -inline bool NzPixelFormat::Flip(nzPixelFlipping flipping, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst) -{ - #if NAZARA_UTILITY_SAFE - if (!IsValid(format)) - { - NazaraError("Invalid pixel format"); - return false; - } - #endif - - auto it = s_flipFunctions[flipping].find(format); - if (it != s_flipFunctions[flipping].end()) - it->second(width, height, depth, reinterpret_cast(src), reinterpret_cast(dst)); - else - { - // Flipping générique + if (srcFormat == dstFormat) + { + std::memcpy(dst, src, GetBytesPerPixel(srcFormat)); + return true; + } #if NAZARA_UTILITY_SAFE - if (IsCompressed(format)) + if (IsCompressed(srcFormat)) { - NazaraError("No function to flip compressed format"); + NazaraError("Cannot convert single pixel from compressed format"); + return false; + } + + if (IsCompressed(dstFormat)) + { + NazaraError("Cannot convert single pixel to compressed format"); return false; } #endif - nzUInt8 bpp = GetBytesPerPixel(format); - unsigned int lineStride = width*bpp; - switch (flipping) + ConvertFunction func = s_convertFunctions[srcFormat][dstFormat]; + if (!func) { - case nzPixelFlipping_Horizontally: - { - if (src == dst) - { - for (unsigned int z = 0; z < depth; ++z) - { - nzUInt8* ptr = reinterpret_cast(dst) + width*height*z; - 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]); - } - } - else - { - for (unsigned int z = 0; z < depth; ++z) - { - const nzUInt8* srcPtr = reinterpret_cast(src); - nzUInt8* dstPtr = reinterpret_cast(dst) + (width-1)*height*depth*bpp; - for (unsigned int y = 0; y < height; ++y) - { - std::memcpy(dstPtr, srcPtr, lineStride); + NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported"); + return false; + } - srcPtr += lineStride; - dstPtr -= lineStride; - } - } - } - break; + if (!func(reinterpret_cast(src), reinterpret_cast(src) + GetBytesPerPixel(srcFormat), reinterpret_cast(dst))) + { + NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " failed"); + return false; + } + + return true; + } + + inline bool NzPixelFormat::Convert(PixelFormatType srcFormat, PixelFormatType dstFormat, const void* start, const void* end, void* dst) + { + if (srcFormat == dstFormat) + { + std::memcpy(dst, start, reinterpret_cast(end)-reinterpret_cast(start)); + return true; + } + + ConvertFunction func = s_convertFunctions[srcFormat][dstFormat]; + if (!func) + { + NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " is not supported"); + return false; + } + + if (!func(reinterpret_cast(start), reinterpret_cast(end), reinterpret_cast(dst))) + { + NazaraError("Pixel format conversion from " + ToString(srcFormat) + " to " + ToString(dstFormat) + " failed"); + return false; + } + + return true; + } + + inline bool NzPixelFormat::Flip(PixelFlipping flipping, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, const void* src, void* dst) + { + #if NAZARA_UTILITY_SAFE + if (!IsValid(format)) + { + NazaraError("Invalid pixel format"); + return false; + } + #endif + + auto it = s_flipFunctions[flipping].find(format); + if (it != s_flipFunctions[flipping].end()) + it->second(width, height, depth, reinterpret_cast(src), reinterpret_cast(dst)); + else + { + // Flipping générique + + #if NAZARA_UTILITY_SAFE + if (IsCompressed(format)) + { + NazaraError("No function to flip compressed format"); + return false; } + #endif - case nzPixelFlipping_Vertically: + UInt8 bpp = GetBytesPerPixel(format); + unsigned int lineStride = width*bpp; + switch (flipping) { - if (src == dst) + case PixelFlipping_Horizontally: { - for (unsigned int z = 0; z < depth; ++z) + if (src == dst) { - nzUInt8* ptr = reinterpret_cast(dst) + width*height*z; - for (unsigned int y = 0; y < height; ++y) + for (unsigned int z = 0; z < depth; ++z) { - 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; + UInt8* ptr = reinterpret_cast(dst) + width*height*z; + 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]); } } - } - else - { - for (unsigned int z = 0; z < depth; ++z) + else { - nzUInt8* ptr = reinterpret_cast(dst) + width*height*z; - for (unsigned int y = 0; y < height; ++y) + for (unsigned int z = 0; z < depth; ++z) { - for (unsigned int x = 0; x < width; ++x) - std::memcpy(&ptr[x*bpp], &ptr[(width-x)*bpp], bpp); + const UInt8* srcPtr = reinterpret_cast(src); + UInt8* dstPtr = reinterpret_cast(dst) + (width-1)*height*depth*bpp; + for (unsigned int y = 0; y < height; ++y) + { + std::memcpy(dstPtr, srcPtr, lineStride); - ptr += lineStride; + srcPtr += lineStride; + dstPtr -= lineStride; + } } } + break; + } + + case PixelFlipping_Vertically: + { + if (src == dst) + { + for (unsigned int z = 0; z < depth; ++z) + { + UInt8* ptr = reinterpret_cast(dst) + width*height*z; + 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; + } + } + } + else + { + for (unsigned int z = 0; z < depth; ++z) + { + UInt8* ptr = reinterpret_cast(dst) + width*height*z; + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width; ++x) + std::memcpy(&ptr[x*bpp], &ptr[(width-x)*bpp], bpp); + + ptr += lineStride; + } + } + } + break; } - break; } } - } - return true; -} - -inline nzUInt8 NzPixelFormat::GetBitsPerPixel(nzPixelFormat format) -{ - switch (format) - { - case nzPixelFormat_A8: - return 8; - - case nzPixelFormat_BGR8: - return 24; - - case nzPixelFormat_BGRA8: - return 32; - - case nzPixelFormat_DXT1: - return 8; - - case nzPixelFormat_DXT3: - return 16; - - case nzPixelFormat_DXT5: - return 16; - - case nzPixelFormat_L8: - return 8; - - case nzPixelFormat_LA8: - return 16; - - case nzPixelFormat_R8: - case nzPixelFormat_R8I: - case nzPixelFormat_R8UI: - return 8; - - case nzPixelFormat_R16: - case nzPixelFormat_R16F: - case nzPixelFormat_R16I: - case nzPixelFormat_R16UI: - return 16; - - case nzPixelFormat_R32F: - case nzPixelFormat_R32I: - case nzPixelFormat_R32UI: - return 32; - - case nzPixelFormat_RG8: - case nzPixelFormat_RG8I: - case nzPixelFormat_RG8UI: - return 16; - - case nzPixelFormat_RG16: - case nzPixelFormat_RG16F: - case nzPixelFormat_RG16I: - case nzPixelFormat_RG16UI: - return 32; - - case nzPixelFormat_RG32F: - case nzPixelFormat_RG32I: - case nzPixelFormat_RG32UI: - return 64; - - case nzPixelFormat_RGB16F: - case nzPixelFormat_RGB16I: - case nzPixelFormat_RGB16UI: - return 48; - - case nzPixelFormat_RGB32F: - case nzPixelFormat_RGB32I: - case nzPixelFormat_RGB32UI: - return 96; - - case nzPixelFormat_RGBA16F: - case nzPixelFormat_RGBA16I: - case nzPixelFormat_RGBA16UI: - return 64; - - case nzPixelFormat_RGBA32F: - case nzPixelFormat_RGBA32I: - case nzPixelFormat_RGBA32UI: - return 128; - - case nzPixelFormat_RGBA4: - return 16; - - case nzPixelFormat_RGB5A1: - return 16; - - case nzPixelFormat_RGB8: - return 24; - - case nzPixelFormat_RGBA8: - return 32; - - case nzPixelFormat_Depth16: - return 16; - - case nzPixelFormat_Depth24: - return 24; - - case nzPixelFormat_Depth24Stencil8: - return 32; - - case nzPixelFormat_Depth32: - return 32; - - case nzPixelFormat_Stencil1: - return 1; - - case nzPixelFormat_Stencil4: - return 2; - - case nzPixelFormat_Stencil8: - return 8; - - case nzPixelFormat_Stencil16: - return 16; - - case nzPixelFormat_Undefined: - break; - } - - NazaraError("Invalid pixel format"); - return 0; -} - -inline nzUInt8 NzPixelFormat::GetBytesPerPixel(nzPixelFormat format) -{ - return GetBitsPerPixel(format)/8; -} - -inline nzPixelFormatType NzPixelFormat::GetType(nzPixelFormat format) -{ - switch (format) - { - case nzPixelFormat_A8: - case nzPixelFormat_BGR8: - case nzPixelFormat_BGRA8: - case nzPixelFormat_DXT1: - case nzPixelFormat_DXT3: - case nzPixelFormat_DXT5: - case nzPixelFormat_L8: - case nzPixelFormat_LA8: - case nzPixelFormat_R8: - case nzPixelFormat_R8I: - case nzPixelFormat_R8UI: - case nzPixelFormat_R16: - case nzPixelFormat_R16F: - case nzPixelFormat_R16I: - case nzPixelFormat_R16UI: - case nzPixelFormat_R32F: - case nzPixelFormat_R32I: - case nzPixelFormat_R32UI: - case nzPixelFormat_RG8: - case nzPixelFormat_RG8I: - case nzPixelFormat_RG8UI: - case nzPixelFormat_RG16: - case nzPixelFormat_RG16F: - case nzPixelFormat_RG16I: - case nzPixelFormat_RG16UI: - case nzPixelFormat_RG32F: - case nzPixelFormat_RG32I: - case nzPixelFormat_RG32UI: - case nzPixelFormat_RGB5A1: - case nzPixelFormat_RGB8: - case nzPixelFormat_RGB16F: - case nzPixelFormat_RGB16I: - case nzPixelFormat_RGB16UI: - case nzPixelFormat_RGB32F: - case nzPixelFormat_RGB32I: - case nzPixelFormat_RGB32UI: - case nzPixelFormat_RGBA4: - case nzPixelFormat_RGBA8: - case nzPixelFormat_RGBA16F: - case nzPixelFormat_RGBA16I: - case nzPixelFormat_RGBA16UI: - case nzPixelFormat_RGBA32F: - case nzPixelFormat_RGBA32I: - case nzPixelFormat_RGBA32UI: - return nzPixelFormatType_Color; - - case nzPixelFormat_Depth16: - case nzPixelFormat_Depth24: - case nzPixelFormat_Depth32: - return nzPixelFormatType_Depth; - - case nzPixelFormat_Depth24Stencil8: - return nzPixelFormatType_DepthStencil; - - case nzPixelFormat_Stencil1: - case nzPixelFormat_Stencil4: - case nzPixelFormat_Stencil8: - case nzPixelFormat_Stencil16: - return nzPixelFormatType_Stencil; - - case nzPixelFormat_Undefined: - break; - } - - NazaraError("Invalid pixel format"); - return nzPixelFormatType_Undefined; -} - -inline bool NzPixelFormat::HasAlpha(nzPixelFormat format) -{ - switch (format) - { - case nzPixelFormat_A8: - case nzPixelFormat_BGRA8: - case nzPixelFormat_DXT3: - case nzPixelFormat_DXT5: - case nzPixelFormat_LA8: - case nzPixelFormat_RGB5A1: - case nzPixelFormat_RGBA16F: - case nzPixelFormat_RGBA16I: - case nzPixelFormat_RGBA16UI: - case nzPixelFormat_RGBA32F: - case nzPixelFormat_RGBA32I: - case nzPixelFormat_RGBA32UI: - case nzPixelFormat_RGBA4: - case nzPixelFormat_RGBA8: - return true; - - case nzPixelFormat_BGR8: - case nzPixelFormat_DXT1: - case nzPixelFormat_L8: - case nzPixelFormat_R8: - case nzPixelFormat_R8I: - case nzPixelFormat_R8UI: - case nzPixelFormat_R16: - case nzPixelFormat_R16F: - case nzPixelFormat_R16I: - case nzPixelFormat_R16UI: - case nzPixelFormat_R32F: - case nzPixelFormat_R32I: - case nzPixelFormat_R32UI: - case nzPixelFormat_RG8: - case nzPixelFormat_RG8I: - case nzPixelFormat_RG8UI: - case nzPixelFormat_RG16: - case nzPixelFormat_RG16F: - case nzPixelFormat_RG16I: - case nzPixelFormat_RG16UI: - case nzPixelFormat_RG32F: - case nzPixelFormat_RG32I: - case nzPixelFormat_RG32UI: - case nzPixelFormat_RGB8: - case nzPixelFormat_RGB16F: - case nzPixelFormat_RGB16I: - case nzPixelFormat_RGB16UI: - case nzPixelFormat_RGB32F: - case nzPixelFormat_RGB32I: - case nzPixelFormat_RGB32UI: - case nzPixelFormat_Depth16: - case nzPixelFormat_Depth24: - case nzPixelFormat_Depth24Stencil8: - case nzPixelFormat_Depth32: - case nzPixelFormat_Stencil1: - case nzPixelFormat_Stencil4: - case nzPixelFormat_Stencil8: - case nzPixelFormat_Stencil16: - return false; - - case nzPixelFormat_Undefined: - break; - } - - NazaraError("Invalid pixel format"); - return false; -} - -inline bool NzPixelFormat::IsCompressed(nzPixelFormat format) -{ - switch (format) - { - case nzPixelFormat_DXT1: - case nzPixelFormat_DXT3: - case nzPixelFormat_DXT5: - return true; - - case nzPixelFormat_A8: - case nzPixelFormat_BGR8: - case nzPixelFormat_BGRA8: - case nzPixelFormat_L8: - case nzPixelFormat_LA8: - case nzPixelFormat_R8: - case nzPixelFormat_R8I: - case nzPixelFormat_R8UI: - case nzPixelFormat_R16: - case nzPixelFormat_R16F: - case nzPixelFormat_R16I: - case nzPixelFormat_R16UI: - case nzPixelFormat_R32F: - case nzPixelFormat_R32I: - case nzPixelFormat_R32UI: - case nzPixelFormat_RG8: - case nzPixelFormat_RG8I: - case nzPixelFormat_RG8UI: - case nzPixelFormat_RG16: - case nzPixelFormat_RG16F: - case nzPixelFormat_RG16I: - case nzPixelFormat_RG16UI: - case nzPixelFormat_RG32F: - case nzPixelFormat_RG32I: - case nzPixelFormat_RG32UI: - case nzPixelFormat_RGB5A1: - case nzPixelFormat_RGB8: - case nzPixelFormat_RGB16F: - case nzPixelFormat_RGB16I: - case nzPixelFormat_RGB16UI: - case nzPixelFormat_RGB32F: - case nzPixelFormat_RGB32I: - case nzPixelFormat_RGB32UI: - case nzPixelFormat_RGBA4: - case nzPixelFormat_RGBA8: - case nzPixelFormat_RGBA16F: - case nzPixelFormat_RGBA16I: - case nzPixelFormat_RGBA16UI: - case nzPixelFormat_RGBA32F: - case nzPixelFormat_RGBA32I: - case nzPixelFormat_RGBA32UI: - case nzPixelFormat_Depth16: - case nzPixelFormat_Depth24: - case nzPixelFormat_Depth24Stencil8: - case nzPixelFormat_Depth32: - case nzPixelFormat_Stencil1: - case nzPixelFormat_Stencil4: - case nzPixelFormat_Stencil8: - case nzPixelFormat_Stencil16: - return false; - - case nzPixelFormat_Undefined: - break; - } - - NazaraError("Invalid pixel format"); - return false; -} - -inline bool NzPixelFormat::IsConversionSupported(nzPixelFormat srcFormat, nzPixelFormat dstFormat) -{ - if (srcFormat == dstFormat) return true; - - return s_convertFunctions[srcFormat][dstFormat] != nullptr; -} - -inline bool NzPixelFormat::IsValid(nzPixelFormat format) -{ - return format != nzPixelFormat_Undefined; -} - -inline void NzPixelFormat::SetConvertFunction(nzPixelFormat srcFormat, nzPixelFormat dstFormat, ConvertFunction func) -{ - s_convertFunctions[srcFormat][dstFormat] = func; -} - -inline void NzPixelFormat::SetFlipFunction(nzPixelFlipping flipping, nzPixelFormat format, FlipFunction func) -{ - s_flipFunctions[flipping][format] = func; -} - -inline NzString NzPixelFormat::ToString(nzPixelFormat format) -{ - switch (format) - { - case nzPixelFormat_A8: - return "A8"; - - case nzPixelFormat_BGR8: - return "BGR8"; - - case nzPixelFormat_BGRA8: - return "BGRA8"; - - case nzPixelFormat_DXT1: - return "DXT1"; - - case nzPixelFormat_DXT3: - return "DXT3"; - - case nzPixelFormat_DXT5: - return "DXT5"; - - case nzPixelFormat_L8: - return "L8"; - - case nzPixelFormat_LA8: - return "LA8"; - - case nzPixelFormat_R8: - return "R8"; - - case nzPixelFormat_R8I: - return "R8I"; - - case nzPixelFormat_R8UI: - return "R8UI"; - - case nzPixelFormat_R16: - return "R16"; - - case nzPixelFormat_R16F: - return "R16F"; - - case nzPixelFormat_R16I: - return "R16I"; - - case nzPixelFormat_R16UI: - return "R16UI"; - - case nzPixelFormat_R32F: - return "R32F"; - - case nzPixelFormat_R32I: - return "R32I"; - - case nzPixelFormat_R32UI: - return "R32UI"; - - case nzPixelFormat_RG8: - return "RG8"; - - case nzPixelFormat_RG8I: - return "RG8I"; - - case nzPixelFormat_RG8UI: - return "RG8UI"; - - case nzPixelFormat_RG16: - return "RG16"; - - case nzPixelFormat_RG16F: - return "RG16F"; - - case nzPixelFormat_RG16I: - return "RG16I"; - - case nzPixelFormat_RG16UI: - return "RG16UI"; - - case nzPixelFormat_RG32F: - return "RG32F"; - - case nzPixelFormat_RG32I: - return "RG32I"; - - case nzPixelFormat_RG32UI: - return "RG32UI"; - - case nzPixelFormat_RGB5A1: - return "RGB5A1"; - - case nzPixelFormat_RGB8: - return "RGB8"; - - case nzPixelFormat_RGB16F: - return "RGB16F"; - - case nzPixelFormat_RGB16I: - return "RGB16I"; - - case nzPixelFormat_RGB16UI: - return "RGB16UI"; - - case nzPixelFormat_RGB32F: - return "RGB32F"; - - case nzPixelFormat_RGB32I: - return "RGB32I"; - - case nzPixelFormat_RGB32UI: - return "RGB32UI"; - - case nzPixelFormat_RGBA4: - return "RGBA4"; - - case nzPixelFormat_RGBA8: - return "RGBA8"; - - case nzPixelFormat_RGBA16F: - return "RGBA16F"; - - case nzPixelFormat_RGBA16I: - return "RGBA16I"; - - case nzPixelFormat_RGBA16UI: - return "RGBA16UI"; - - case nzPixelFormat_RGBA32F: - return "RGBA32F"; - - case nzPixelFormat_RGBA32I: - return "RGBA32I"; - - case nzPixelFormat_RGBA32UI: - return "RGBA32UI"; - - case nzPixelFormat_Depth16: - return "Depth16"; - - case nzPixelFormat_Depth24: - return "Depth24"; - - case nzPixelFormat_Depth24Stencil8: - return "Depth24Stencil8"; - - case nzPixelFormat_Depth32: - return "Depth32"; - - case nzPixelFormat_Stencil1: - return "Stencil1"; - - case nzPixelFormat_Stencil4: - return "Stencil4"; - - case nzPixelFormat_Stencil8: - return "Stencil8"; - - case nzPixelFormat_Stencil16: - return "Stencil16"; - - case nzPixelFormat_Undefined: - return "Undefined"; } - NazaraError("Invalid pixel format"); - return "Invalid format"; + inline UInt8 NzPixelFormat::GetBitsPerPixel(PixelFormatType format) + { + switch (format) + { + case PixelFormatType_A8: + return 8; + + case PixelFormatType_BGR8: + return 24; + + case PixelFormatType_BGRA8: + return 32; + + case PixelFormatType_DXT1: + return 8; + + case PixelFormatType_DXT3: + return 16; + + case PixelFormatType_DXT5: + return 16; + + case PixelFormatType_L8: + return 8; + + case PixelFormatType_LA8: + return 16; + + case PixelFormatType_R8: + case PixelFormatType_R8I: + case PixelFormatType_R8UI: + return 8; + + case PixelFormatType_R16: + case PixelFormatType_R16F: + case PixelFormatType_R16I: + case PixelFormatType_R16UI: + return 16; + + case PixelFormatType_R32F: + case PixelFormatType_R32I: + case PixelFormatType_R32UI: + return 32; + + case PixelFormatType_RG8: + case PixelFormatType_RG8I: + case PixelFormatType_RG8UI: + return 16; + + case PixelFormatType_RG16: + case PixelFormatType_RG16F: + case PixelFormatType_RG16I: + case PixelFormatType_RG16UI: + return 32; + + case PixelFormatType_RG32F: + case PixelFormatType_RG32I: + case PixelFormatType_RG32UI: + return 64; + + case PixelFormatType_RGB16F: + case PixelFormatType_RGB16I: + case PixelFormatType_RGB16UI: + return 48; + + case PixelFormatType_RGB32F: + case PixelFormatType_RGB32I: + case PixelFormatType_RGB32UI: + return 96; + + case PixelFormatType_RGBA16F: + case PixelFormatType_RGBA16I: + case PixelFormatType_RGBA16UI: + return 64; + + case PixelFormatType_RGBA32F: + case PixelFormatType_RGBA32I: + case PixelFormatType_RGBA32UI: + return 128; + + case PixelFormatType_RGBA4: + return 16; + + case PixelFormatType_RGB5A1: + return 16; + + case PixelFormatType_RGB8: + return 24; + + case PixelFormatType_RGBA8: + return 32; + + case PixelFormatType_Depth16: + return 16; + + case PixelFormatType_Depth24: + return 24; + + case PixelFormatType_Depth24Stencil8: + return 32; + + case PixelFormatType_Depth32: + return 32; + + case PixelFormatType_Stencil1: + return 1; + + case PixelFormatType_Stencil4: + return 2; + + case PixelFormatType_Stencil8: + return 8; + + case PixelFormatType_Stencil16: + return 16; + + case PixelFormatType_Undefined: + break; + } + + NazaraError("Invalid pixel format"); + return 0; + } + + inline UInt8 NzPixelFormat::GetBytesPerPixel(PixelFormatType format) + { + return GetBitsPerPixel(format)/8; + } + + inline PixelFormatTypeType NzPixelFormat::GetType(PixelFormatType format) + { + switch (format) + { + case PixelFormatType_A8: + case PixelFormatType_BGR8: + case PixelFormatType_BGRA8: + case PixelFormatType_DXT1: + case PixelFormatType_DXT3: + case PixelFormatType_DXT5: + case PixelFormatType_L8: + case PixelFormatType_LA8: + case PixelFormatType_R8: + case PixelFormatType_R8I: + case PixelFormatType_R8UI: + case PixelFormatType_R16: + case PixelFormatType_R16F: + case PixelFormatType_R16I: + case PixelFormatType_R16UI: + case PixelFormatType_R32F: + case PixelFormatType_R32I: + case PixelFormatType_R32UI: + case PixelFormatType_RG8: + case PixelFormatType_RG8I: + case PixelFormatType_RG8UI: + case PixelFormatType_RG16: + case PixelFormatType_RG16F: + case PixelFormatType_RG16I: + case PixelFormatType_RG16UI: + case PixelFormatType_RG32F: + case PixelFormatType_RG32I: + case PixelFormatType_RG32UI: + case PixelFormatType_RGB5A1: + case PixelFormatType_RGB8: + case PixelFormatType_RGB16F: + case PixelFormatType_RGB16I: + case PixelFormatType_RGB16UI: + case PixelFormatType_RGB32F: + case PixelFormatType_RGB32I: + case PixelFormatType_RGB32UI: + case PixelFormatType_RGBA4: + case PixelFormatType_RGBA8: + case PixelFormatType_RGBA16F: + case PixelFormatType_RGBA16I: + case PixelFormatType_RGBA16UI: + case PixelFormatType_RGBA32F: + case PixelFormatType_RGBA32I: + case PixelFormatType_RGBA32UI: + return PixelFormatTypeType_Color; + + case PixelFormatType_Depth16: + case PixelFormatType_Depth24: + case PixelFormatType_Depth32: + return PixelFormatTypeType_Depth; + + case PixelFormatType_Depth24Stencil8: + return PixelFormatTypeType_DepthStencil; + + case PixelFormatType_Stencil1: + case PixelFormatType_Stencil4: + case PixelFormatType_Stencil8: + case PixelFormatType_Stencil16: + return PixelFormatTypeType_Stencil; + + case PixelFormatType_Undefined: + break; + } + + NazaraError("Invalid pixel format"); + return PixelFormatTypeType_Undefined; + } + + inline bool NzPixelFormat::HasAlpha(PixelFormatType format) + { + switch (format) + { + case PixelFormatType_A8: + case PixelFormatType_BGRA8: + case PixelFormatType_DXT3: + case PixelFormatType_DXT5: + case PixelFormatType_LA8: + case PixelFormatType_RGB5A1: + case PixelFormatType_RGBA16F: + case PixelFormatType_RGBA16I: + case PixelFormatType_RGBA16UI: + case PixelFormatType_RGBA32F: + case PixelFormatType_RGBA32I: + case PixelFormatType_RGBA32UI: + case PixelFormatType_RGBA4: + case PixelFormatType_RGBA8: + return true; + + case PixelFormatType_BGR8: + case PixelFormatType_DXT1: + case PixelFormatType_L8: + case PixelFormatType_R8: + case PixelFormatType_R8I: + case PixelFormatType_R8UI: + case PixelFormatType_R16: + case PixelFormatType_R16F: + case PixelFormatType_R16I: + case PixelFormatType_R16UI: + case PixelFormatType_R32F: + case PixelFormatType_R32I: + case PixelFormatType_R32UI: + case PixelFormatType_RG8: + case PixelFormatType_RG8I: + case PixelFormatType_RG8UI: + case PixelFormatType_RG16: + case PixelFormatType_RG16F: + case PixelFormatType_RG16I: + case PixelFormatType_RG16UI: + case PixelFormatType_RG32F: + case PixelFormatType_RG32I: + case PixelFormatType_RG32UI: + case PixelFormatType_RGB8: + case PixelFormatType_RGB16F: + case PixelFormatType_RGB16I: + case PixelFormatType_RGB16UI: + case PixelFormatType_RGB32F: + case PixelFormatType_RGB32I: + case PixelFormatType_RGB32UI: + case PixelFormatType_Depth16: + case PixelFormatType_Depth24: + case PixelFormatType_Depth24Stencil8: + case PixelFormatType_Depth32: + case PixelFormatType_Stencil1: + case PixelFormatType_Stencil4: + case PixelFormatType_Stencil8: + case PixelFormatType_Stencil16: + return false; + + case PixelFormatType_Undefined: + break; + } + + NazaraError("Invalid pixel format"); + return false; + } + + inline bool NzPixelFormat::IsCompressed(PixelFormatType format) + { + switch (format) + { + case PixelFormatType_DXT1: + case PixelFormatType_DXT3: + case PixelFormatType_DXT5: + return true; + + case PixelFormatType_A8: + case PixelFormatType_BGR8: + case PixelFormatType_BGRA8: + case PixelFormatType_L8: + case PixelFormatType_LA8: + case PixelFormatType_R8: + case PixelFormatType_R8I: + case PixelFormatType_R8UI: + case PixelFormatType_R16: + case PixelFormatType_R16F: + case PixelFormatType_R16I: + case PixelFormatType_R16UI: + case PixelFormatType_R32F: + case PixelFormatType_R32I: + case PixelFormatType_R32UI: + case PixelFormatType_RG8: + case PixelFormatType_RG8I: + case PixelFormatType_RG8UI: + case PixelFormatType_RG16: + case PixelFormatType_RG16F: + case PixelFormatType_RG16I: + case PixelFormatType_RG16UI: + case PixelFormatType_RG32F: + case PixelFormatType_RG32I: + case PixelFormatType_RG32UI: + case PixelFormatType_RGB5A1: + case PixelFormatType_RGB8: + case PixelFormatType_RGB16F: + case PixelFormatType_RGB16I: + case PixelFormatType_RGB16UI: + case PixelFormatType_RGB32F: + case PixelFormatType_RGB32I: + case PixelFormatType_RGB32UI: + case PixelFormatType_RGBA4: + case PixelFormatType_RGBA8: + case PixelFormatType_RGBA16F: + case PixelFormatType_RGBA16I: + case PixelFormatType_RGBA16UI: + case PixelFormatType_RGBA32F: + case PixelFormatType_RGBA32I: + case PixelFormatType_RGBA32UI: + case PixelFormatType_Depth16: + case PixelFormatType_Depth24: + case PixelFormatType_Depth24Stencil8: + case PixelFormatType_Depth32: + case PixelFormatType_Stencil1: + case PixelFormatType_Stencil4: + case PixelFormatType_Stencil8: + case PixelFormatType_Stencil16: + return false; + + case PixelFormatType_Undefined: + break; + } + + NazaraError("Invalid pixel format"); + return false; + } + + inline bool NzPixelFormat::IsConversionSupported(PixelFormatType srcFormat, PixelFormatType dstFormat) + { + if (srcFormat == dstFormat) + return true; + + return s_convertFunctions[srcFormat][dstFormat] != nullptr; + } + + inline bool NzPixelFormat::IsValid(PixelFormatType format) + { + return format != PixelFormatType_Undefined; + } + + inline void NzPixelFormat::SetConvertFunction(PixelFormatType srcFormat, PixelFormatType dstFormat, ConvertFunction func) + { + s_convertFunctions[srcFormat][dstFormat] = func; + } + + inline void NzPixelFormat::SetFlipFunction(PixelFlipping flipping, PixelFormatType format, FlipFunction func) + { + s_flipFunctions[flipping][format] = func; + } + + inline String NzPixelFormat::ToString(PixelFormatType format) + { + switch (format) + { + case PixelFormatType_A8: + return "A8"; + + case PixelFormatType_BGR8: + return "BGR8"; + + case PixelFormatType_BGRA8: + return "BGRA8"; + + case PixelFormatType_DXT1: + return "DXT1"; + + case PixelFormatType_DXT3: + return "DXT3"; + + case PixelFormatType_DXT5: + return "DXT5"; + + case PixelFormatType_L8: + return "L8"; + + case PixelFormatType_LA8: + return "LA8"; + + case PixelFormatType_R8: + return "R8"; + + case PixelFormatType_R8I: + return "R8I"; + + case PixelFormatType_R8UI: + return "R8UI"; + + case PixelFormatType_R16: + return "R16"; + + case PixelFormatType_R16F: + return "R16F"; + + case PixelFormatType_R16I: + return "R16I"; + + case PixelFormatType_R16UI: + return "R16UI"; + + case PixelFormatType_R32F: + return "R32F"; + + case PixelFormatType_R32I: + return "R32I"; + + case PixelFormatType_R32UI: + return "R32UI"; + + case PixelFormatType_RG8: + return "RG8"; + + case PixelFormatType_RG8I: + return "RG8I"; + + case PixelFormatType_RG8UI: + return "RG8UI"; + + case PixelFormatType_RG16: + return "RG16"; + + case PixelFormatType_RG16F: + return "RG16F"; + + case PixelFormatType_RG16I: + return "RG16I"; + + case PixelFormatType_RG16UI: + return "RG16UI"; + + case PixelFormatType_RG32F: + return "RG32F"; + + case PixelFormatType_RG32I: + return "RG32I"; + + case PixelFormatType_RG32UI: + return "RG32UI"; + + case PixelFormatType_RGB5A1: + return "RGB5A1"; + + case PixelFormatType_RGB8: + return "RGB8"; + + case PixelFormatType_RGB16F: + return "RGB16F"; + + case PixelFormatType_RGB16I: + return "RGB16I"; + + case PixelFormatType_RGB16UI: + return "RGB16UI"; + + case PixelFormatType_RGB32F: + return "RGB32F"; + + case PixelFormatType_RGB32I: + return "RGB32I"; + + case PixelFormatType_RGB32UI: + return "RGB32UI"; + + case PixelFormatType_RGBA4: + return "RGBA4"; + + case PixelFormatType_RGBA8: + return "RGBA8"; + + case PixelFormatType_RGBA16F: + return "RGBA16F"; + + case PixelFormatType_RGBA16I: + return "RGBA16I"; + + case PixelFormatType_RGBA16UI: + return "RGBA16UI"; + + case PixelFormatType_RGBA32F: + return "RGBA32F"; + + case PixelFormatType_RGBA32I: + return "RGBA32I"; + + case PixelFormatType_RGBA32UI: + return "RGBA32UI"; + + case PixelFormatType_Depth16: + return "Depth16"; + + case PixelFormatType_Depth24: + return "Depth24"; + + case PixelFormatType_Depth24Stencil8: + return "Depth24Stencil8"; + + case PixelFormatType_Depth32: + return "Depth32"; + + case PixelFormatType_Stencil1: + return "Stencil1"; + + case PixelFormatType_Stencil4: + return "Stencil4"; + + case PixelFormatType_Stencil8: + return "Stencil8"; + + case PixelFormatType_Stencil16: + return "Stencil16"; + + case PixelFormatType_Undefined: + return "Undefined"; + } + + NazaraError("Invalid pixel format"); + return "Invalid format"; + } } #include diff --git a/include/Nazara/Utility/Sequence.hpp b/include/Nazara/Utility/Sequence.hpp index 2497b7d0a..1c6812eb7 100644 --- a/include/Nazara/Utility/Sequence.hpp +++ b/include/Nazara/Utility/Sequence.hpp @@ -11,19 +11,22 @@ #include #include -struct NzSequence +namespace Nz { - NzString name; - unsigned int firstFrame; - unsigned int frameCount; - unsigned int frameRate; -}; + struct Sequence + { + String name; + unsigned int firstFrame; + unsigned int frameCount; + unsigned int frameRate; + }; -struct NzSequenceJoint -{ - NzQuaternionf rotation; - NzVector3f position; - NzVector3f scale; -}; + struct SequenceJoint + { + Quaternionf rotation; + Vector3f position; + Vector3f scale; + }; +} #endif // NAZARA_SEQUENCE_HPP diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index 200031c7c..2d2709679 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -14,58 +14,61 @@ #include #include -class NAZARA_UTILITY_API NzSimpleTextDrawer : public NzAbstractTextDrawer +namespace Nz { - public: - NzSimpleTextDrawer(); - NzSimpleTextDrawer(const NzSimpleTextDrawer& drawer); - NzSimpleTextDrawer(NzSimpleTextDrawer&& drawer); - virtual ~NzSimpleTextDrawer(); + class NAZARA_UTILITY_API SimpleTextDrawer : public AbstractTextDrawer + { + public: + SimpleTextDrawer(); + SimpleTextDrawer(const SimpleTextDrawer& drawer); + SimpleTextDrawer(SimpleTextDrawer&& drawer); + virtual ~SimpleTextDrawer(); - const NzRectui& GetBounds() const; - unsigned int GetCharacterSize() const; - const NzColor& GetColor() const; - NzFont* GetFont() const; - NzFont* GetFont(unsigned int index) const override; - unsigned int GetFontCount() const override; - const Glyph& GetGlyph(unsigned int index) const override; - unsigned int GetGlyphCount() const override; - nzUInt32 GetStyle() const; - const NzString& GetText() const; + const Rectui& GetBounds() const; + unsigned int GetCharacterSize() const; + const Color& GetColor() const; + Font* GetFont() const; + Font* GetFont(unsigned int index) const override; + unsigned int GetFontCount() const override; + const Glyph& GetGlyph(unsigned int index) const override; + unsigned int GetGlyphCount() const override; + UInt32 GetStyle() const; + const String& GetText() const; - void SetCharacterSize(unsigned int characterSize); - void SetColor(const NzColor& color); - void SetFont(NzFont* font); - void SetStyle(nzUInt32 style); - void SetText(const NzString& str); + void SetCharacterSize(unsigned int characterSize); + void SetColor(const Color& color); + void SetFont(Font* font); + void SetStyle(UInt32 style); + void SetText(const String& str); - NzSimpleTextDrawer& operator=(const NzSimpleTextDrawer& drawer) = default; - NzSimpleTextDrawer& operator=(NzSimpleTextDrawer&& drawer); + SimpleTextDrawer& operator=(const SimpleTextDrawer& drawer) = default; + SimpleTextDrawer& operator=(SimpleTextDrawer&& drawer); - static NzSimpleTextDrawer Draw(const NzString& str, unsigned int characterSize, nzUInt32 style = nzTextStyle_Regular, const NzColor& color = NzColor::White); - static NzSimpleTextDrawer Draw(NzFont* font, const NzString& str, unsigned int characterSize, nzUInt32 style = nzTextStyle_Regular, const NzColor& color = NzColor::White); + static SimpleTextDrawer Draw(const String& str, unsigned int characterSize, UInt32 style = TextStyle_Regular, const Color& color = Color::White); + static SimpleTextDrawer Draw(Font* font, const String& str, unsigned int characterSize, UInt32 style = TextStyle_Regular, const Color& color = Color::White); - private: - void ConnectFontSlots(); - void DisconnectFontSlots(); - void OnFontAtlasLayerChanged(const NzFont* font, NzAbstractImage* oldLayer, NzAbstractImage* newLayer); - void OnFontInvalidated(const NzFont* font); - void OnFontRelease(const NzFont* object); - void UpdateGlyphs() const; + private: + void ConnectFontSlots(); + void DisconnectFontSlots(); + void OnFontAtlasLayerChanged(const Font* font, AbstractImage* oldLayer, AbstractImage* newLayer); + void OnFontInvalidated(const Font* font); + void OnFontRelease(const Font* object); + void UpdateGlyphs() const; - NazaraSlot(NzFont, OnFontAtlasChanged, m_atlasChangedSlot); - NazaraSlot(NzFont, OnFontAtlasLayerChanged, m_atlasLayerChangedSlot); - NazaraSlot(NzFont, OnFontGlyphCacheCleared, m_glyphCacheClearedSlot); - NazaraSlot(NzFont, OnFontRelease, m_fontReleaseSlot); + NazaraSlot(Font, OnFontAtlasChanged, m_atlasChangedSlot); + NazaraSlot(Font, OnFontAtlasLayerChanged, m_atlasLayerChangedSlot); + NazaraSlot(Font, OnFontGlyphCacheCleared, m_glyphCacheClearedSlot); + NazaraSlot(Font, OnFontRelease, m_fontReleaseSlot); - mutable std::vector m_glyphs; - NzColor m_color; - NzFontRef m_font; - mutable NzRectui m_bounds; - NzString m_text; - nzUInt32 m_style; - mutable bool m_glyphUpdated; - unsigned int m_characterSize; -}; + mutable std::vector m_glyphs; + Color m_color; + FontRef m_font; + mutable Rectui m_bounds; + String m_text; + UInt32 m_style; + mutable bool m_glyphUpdated; + unsigned int m_characterSize; + }; +} #endif // NAZARA_SIMPLETEXTDRAWER_HPP diff --git a/include/Nazara/Utility/SkeletalMesh.hpp b/include/Nazara/Utility/SkeletalMesh.hpp index 187fb9411..616fb3dec 100644 --- a/include/Nazara/Utility/SkeletalMesh.hpp +++ b/include/Nazara/Utility/SkeletalMesh.hpp @@ -12,44 +12,47 @@ #include #include -class NzSkeletalMesh; - -using NzSkeletalMeshConstRef = NzObjectRef; -using NzSkeletalMeshRef = NzObjectRef; - -class NAZARA_UTILITY_API NzSkeletalMesh final : public NzSubMesh +namespace Nz { - public: - NzSkeletalMesh(const NzMesh* parent); - ~NzSkeletalMesh(); + class SkeletalMesh; - bool Create(NzVertexBuffer* vertexBuffer); - void Destroy(); + using SkeletalMeshConstRef = ObjectRef; + using SkeletalMeshRef = ObjectRef; - const NzBoxf& GetAABB() const override; - nzAnimationType GetAnimationType() const final; - const NzIndexBuffer* GetIndexBuffer() const override; - NzVertexBuffer* GetVertexBuffer(); - const NzVertexBuffer* GetVertexBuffer() const; - unsigned int GetVertexCount() const override; + class NAZARA_UTILITY_API SkeletalMesh final : public SubMesh + { + public: + SkeletalMesh(const Mesh* parent); + ~SkeletalMesh(); - bool IsAnimated() const final; - bool IsValid() const; + bool Create(VertexBuffer* vertexBuffer); + void Destroy(); - void SetAABB(const NzBoxf& aabb); - void SetIndexBuffer(const NzIndexBuffer* indexBuffer); + const Boxf& GetAABB() const override; + AnimationType GetAnimationType() const final; + const IndexBuffer* GetIndexBuffer() const override; + VertexBuffer* GetVertexBuffer(); + const VertexBuffer* GetVertexBuffer() const; + unsigned int GetVertexCount() const override; - template static NzSkeletalMeshRef New(Args&&... args); + bool IsAnimated() const final; + bool IsValid() const; - // Signals: - NazaraSignal(OnSkeletalMeshDestroy, const NzSkeletalMesh* /*skeletalMesh*/); - NazaraSignal(OnSkeletalMeshRelease, const NzSkeletalMesh* /*skeletalMesh*/); + void SetAABB(const Boxf& aabb); + void SetIndexBuffer(const IndexBuffer* indexBuffer); - private: - NzBoxf m_aabb; - NzIndexBufferConstRef m_indexBuffer = nullptr; - NzVertexBufferRef m_vertexBuffer = nullptr; -}; + template static SkeletalMeshRef New(Args&&... args); + + // Signals: + NazaraSignal(OnSkeletalMeshDestroy, const SkeletalMesh* /*skeletalMesh*/); + NazaraSignal(OnSkeletalMeshRelease, const SkeletalMesh* /*skeletalMesh*/); + + private: + Boxf m_aabb; + IndexBufferConstRef m_indexBuffer = nullptr; + VertexBufferRef m_vertexBuffer = nullptr; + }; +} #include diff --git a/include/Nazara/Utility/SkeletalMesh.inl b/include/Nazara/Utility/SkeletalMesh.inl index e6675058d..69119dc87 100644 --- a/include/Nazara/Utility/SkeletalMesh.inl +++ b/include/Nazara/Utility/SkeletalMesh.inl @@ -5,13 +5,16 @@ #include #include -template -NzSkeletalMeshRef NzSkeletalMesh::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzSkeletalMesh(std::forward(args)...)); - object->SetPersistent(false); + template + SkeletalMeshRef SkeletalMesh::New(Args&&... args) + { + std::unique_ptr object(new SkeletalMesh(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Utility/Skeleton.hpp b/include/Nazara/Utility/Skeleton.hpp index 2a88d5feb..fa217e6d4 100644 --- a/include/Nazara/Utility/Skeleton.hpp +++ b/include/Nazara/Utility/Skeleton.hpp @@ -16,64 +16,67 @@ #include #include -class NzSkeleton; - -using NzSkeletonConstRef = NzObjectRef; -using NzSkeletonLibrary = NzObjectLibrary; -using NzSkeletonRef = NzObjectRef; - -struct NzSkeletonImpl; - -class NAZARA_UTILITY_API NzSkeleton : public NzRefCounted +namespace Nz { - friend NzJoint; - friend NzSkeletonLibrary; - friend class NzUtility; + class Skeleton; - public: - NzSkeleton() = default; - NzSkeleton(const NzSkeleton& skeleton); - ~NzSkeleton(); + using SkeletonConstRef = ObjectRef; + using SkeletonLibrary = ObjectLibrary; + using SkeletonRef = ObjectRef; - bool Create(unsigned int jointCount); - void Destroy(); + struct SkeletonImpl; - const NzBoxf& GetAABB() const; - NzJoint* GetJoint(const NzString& jointName); - NzJoint* GetJoint(unsigned int index); - const NzJoint* GetJoint(const NzString& jointName) const; - const NzJoint* GetJoint(unsigned int index) const; - NzJoint* GetJoints(); - const NzJoint* GetJoints() const; - unsigned int GetJointCount() const; - int GetJointIndex(const NzString& jointName) const; + class NAZARA_UTILITY_API Skeleton : public RefCounted + { + friend Joint; + friend SkeletonLibrary; + friend class Utility; - void Interpolate(const NzSkeleton& skeletonA, const NzSkeleton& skeletonB, float interpolation); - void Interpolate(const NzSkeleton& skeletonA, const NzSkeleton& skeletonB, float interpolation, unsigned int* indices, unsigned int indiceCount); + public: + Skeleton() = default; + Skeleton(const Skeleton& skeleton); + ~Skeleton(); - bool IsValid() const; + bool Create(unsigned int jointCount); + void Destroy(); - NzSkeleton& operator=(const NzSkeleton& skeleton); + const Boxf& GetAABB() const; + Joint* GetJoint(const String& jointName); + Joint* GetJoint(unsigned int index); + const Joint* GetJoint(const String& jointName) const; + const Joint* GetJoint(unsigned int index) const; + Joint* GetJoints(); + const Joint* GetJoints() const; + unsigned int GetJointCount() const; + int GetJointIndex(const String& jointName) const; - template static NzSkeletonRef New(Args&&... args); + void Interpolate(const Skeleton& skeletonA, const Skeleton& skeletonB, float interpolation); + void Interpolate(const Skeleton& skeletonA, const Skeleton& skeletonB, float interpolation, unsigned int* indices, unsigned int indiceCount); - // Signals: - NazaraSignal(OnSkeletonDestroy, const NzSkeleton* /*skeleton*/); - NazaraSignal(OnSkeletonJointsInvalidated, const NzSkeleton* /*skeleton*/); - NazaraSignal(OnSkeletonRelease, const NzSkeleton* /*skeleton*/); + bool IsValid() const; - private: - void InvalidateJoints(); - void InvalidateJointMap(); - void UpdateJointMap() const; + Skeleton& operator=(const Skeleton& skeleton); - static bool Initialize(); - static void Uninitialize(); + template static SkeletonRef New(Args&&... args); - NzSkeletonImpl* m_impl = nullptr; + // Signals: + NazaraSignal(OnSkeletonDestroy, const Skeleton* /*skeleton*/); + NazaraSignal(OnSkeletonJointsInvalidated, const Skeleton* /*skeleton*/); + NazaraSignal(OnSkeletonRelease, const Skeleton* /*skeleton*/); - static NzSkeletonLibrary::LibraryMap s_library; -}; + private: + void InvalidateJoints(); + void InvalidateJointMap(); + void UpdateJointMap() const; + + static bool Initialize(); + static void Uninitialize(); + + SkeletonImpl* m_impl = nullptr; + + static SkeletonLibrary::LibraryMap s_library; + }; +} #include diff --git a/include/Nazara/Utility/Skeleton.inl b/include/Nazara/Utility/Skeleton.inl index b91f59822..4c0ef4546 100644 --- a/include/Nazara/Utility/Skeleton.inl +++ b/include/Nazara/Utility/Skeleton.inl @@ -5,13 +5,16 @@ #include #include -template -NzSkeletonRef NzSkeleton::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzSkeleton(std::forward(args)...)); - object->SetPersistent(false); + template + SkeletonRef Skeleton::New(Args&&... args) + { + std::unique_ptr object(new Skeleton(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Utility/StaticMesh.hpp b/include/Nazara/Utility/StaticMesh.hpp index dfc92b8b4..d5fe8907d 100644 --- a/include/Nazara/Utility/StaticMesh.hpp +++ b/include/Nazara/Utility/StaticMesh.hpp @@ -11,48 +11,51 @@ #include #include -class NzStaticMesh; - -using NzStaticMeshConstRef = NzObjectRef; -using NzStaticMeshRef = NzObjectRef; - -class NAZARA_UTILITY_API NzStaticMesh final : public NzSubMesh +namespace Nz { - public: - NzStaticMesh(const NzMesh* parent); - ~NzStaticMesh(); + class StaticMesh; - void Center(); + using StaticMeshConstRef = ObjectRef; + using StaticMeshRef = ObjectRef; - bool Create(NzVertexBuffer* vertexBuffer); - void Destroy(); + class NAZARA_UTILITY_API StaticMesh final : public SubMesh + { + public: + StaticMesh(const Mesh* parent); + ~StaticMesh(); - bool GenerateAABB(); + void Center(); - const NzBoxf& GetAABB() const override; - nzAnimationType GetAnimationType() const final; - const NzIndexBuffer* GetIndexBuffer() const override; - NzVertexBuffer* GetVertexBuffer(); - const NzVertexBuffer* GetVertexBuffer() const; - unsigned int GetVertexCount() const override; + bool Create(VertexBuffer* vertexBuffer); + void Destroy(); - bool IsAnimated() const final; - bool IsValid() const; + bool GenerateAABB(); - void SetAABB(const NzBoxf& aabb); - void SetIndexBuffer(const NzIndexBuffer* indexBuffer); + const Boxf& GetAABB() const override; + AnimationType GetAnimationType() const final; + const IndexBuffer* GetIndexBuffer() const override; + VertexBuffer* GetVertexBuffer(); + const VertexBuffer* GetVertexBuffer() const; + unsigned int GetVertexCount() const override; - template static NzStaticMeshRef New(Args&&... args); + bool IsAnimated() const final; + bool IsValid() const; - // Signals: - NazaraSignal(OnStaticMeshDestroy, const NzStaticMesh* /*staticMesh*/); - NazaraSignal(OnStaticMeshRelease, const NzStaticMesh* /*staticMesh*/); + void SetAABB(const Boxf& aabb); + void SetIndexBuffer(const IndexBuffer* indexBuffer); - private: - NzBoxf m_aabb; - NzIndexBufferConstRef m_indexBuffer = nullptr; - NzVertexBufferRef m_vertexBuffer = nullptr; -}; + template static StaticMeshRef New(Args&&... args); + + // Signals: + NazaraSignal(OnStaticMeshDestroy, const StaticMesh* /*staticMesh*/); + NazaraSignal(OnStaticMeshRelease, const StaticMesh* /*staticMesh*/); + + private: + Boxf m_aabb; + IndexBufferConstRef m_indexBuffer = nullptr; + VertexBufferRef m_vertexBuffer = nullptr; + }; +} #include diff --git a/include/Nazara/Utility/StaticMesh.inl b/include/Nazara/Utility/StaticMesh.inl index 51ea2bcc7..06afcec95 100644 --- a/include/Nazara/Utility/StaticMesh.inl +++ b/include/Nazara/Utility/StaticMesh.inl @@ -5,13 +5,16 @@ #include #include -template -NzStaticMeshRef NzStaticMesh::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzStaticMesh(std::forward(args)...)); - object->SetPersistent(false); + template + StaticMeshRef StaticMesh::New(Args&&... args) + { + std::unique_ptr object(new StaticMesh(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Utility/SubMesh.hpp b/include/Nazara/Utility/SubMesh.hpp index c039dec0c..6eee3a152 100644 --- a/include/Nazara/Utility/SubMesh.hpp +++ b/include/Nazara/Utility/SubMesh.hpp @@ -16,45 +16,48 @@ #include #include -class NzMesh; -class NzSubMesh; - -using NzSubMeshConstRef = NzObjectRef; -using NzSubMeshRef = NzObjectRef; - -class NAZARA_UTILITY_API NzSubMesh : public NzRefCounted +namespace Nz { - friend NzMesh; + class Mesh; + class SubMesh; - public: - NzSubMesh(const NzMesh* parent); - virtual ~NzSubMesh(); + using SubMeshConstRef = ObjectRef; + using SubMeshRef = ObjectRef; - void GenerateNormals(); - void GenerateNormalsAndTangents(); - void GenerateTangents(); + class NAZARA_UTILITY_API SubMesh : public RefCounted + { + friend Mesh; - virtual const NzBoxf& GetAABB() const = 0; - virtual nzAnimationType GetAnimationType() const = 0; - virtual const NzIndexBuffer* GetIndexBuffer() const = 0; - unsigned int GetMaterialIndex() const; - const NzMesh* GetParent() const; - nzPrimitiveMode GetPrimitiveMode() const; - unsigned int GetTriangleCount() const; - virtual unsigned int GetVertexCount() const = 0; + public: + SubMesh(const Mesh* parent); + virtual ~SubMesh(); - virtual bool IsAnimated() const = 0; + void GenerateNormals(); + void GenerateNormalsAndTangents(); + void GenerateTangents(); - void SetMaterialIndex(unsigned int matIndex); - void SetPrimitiveMode(nzPrimitiveMode mode); + virtual const Boxf& GetAABB() const = 0; + virtual AnimationType GetAnimationType() const = 0; + virtual const IndexBuffer* GetIndexBuffer() const = 0; + unsigned int GetMaterialIndex() const; + const Mesh* GetParent() const; + PrimitiveMode GetPrimitiveMode() const; + unsigned int GetTriangleCount() const; + virtual unsigned int GetVertexCount() const = 0; - // Signals: - NazaraSignal(OnSubMeshRelease, const NzSubMesh* /*subMesh*/); + virtual bool IsAnimated() const = 0; - protected: - nzPrimitiveMode m_primitiveMode; - const NzMesh* m_parent; - unsigned int m_matIndex; -}; + void SetMaterialIndex(unsigned int matIndex); + void SetPrimitiveMode(PrimitiveMode mode); + + // Signals: + NazaraSignal(OnSubMeshRelease, const SubMesh* /*subMesh*/); + + protected: + PrimitiveMode m_primitiveMode; + const Mesh* m_parent; + unsigned int m_matIndex; + }; +} #endif // NAZARA_SUBMESH_HPP diff --git a/include/Nazara/Utility/TriangleIterator.hpp b/include/Nazara/Utility/TriangleIterator.hpp index 52b0f935f..0addb1836 100644 --- a/include/Nazara/Utility/TriangleIterator.hpp +++ b/include/Nazara/Utility/TriangleIterator.hpp @@ -11,27 +11,30 @@ #include #include -class NzSubMesh; - -class NAZARA_UTILITY_API NzTriangleIterator +namespace Nz { - public: - NzTriangleIterator(nzPrimitiveMode primitiveMode, const NzIndexBuffer* indexBuffer); - NzTriangleIterator(NzSubMesh* subMesh); - ~NzTriangleIterator() = default; + class SubMesh; - bool Advance(); + class NAZARA_UTILITY_API TriangleIterator + { + public: + TriangleIterator(PrimitiveMode primitiveMode, const IndexBuffer* indexBuffer); + TriangleIterator(SubMesh* subMesh); + ~TriangleIterator() = default; - nzUInt32 operator[](unsigned int i) const; + bool Advance(); - void Unmap(); + UInt32 operator[](unsigned int i) const; - private: - nzPrimitiveMode m_primitiveMode; - nzUInt32 m_triangleIndices[3]; - NzIndexMapper m_indexMapper; - unsigned int m_currentIndex; - unsigned int m_indexCount; -}; + void Unmap(); + + private: + PrimitiveMode m_primitiveMode; + UInt32 m_triangleIndices[3]; + IndexMapper m_indexMapper; + unsigned int m_currentIndex; + unsigned int m_indexCount; + }; +} #endif // NAZARA_TRIANGLEITERATOR_HPP diff --git a/include/Nazara/Utility/Utility.hpp b/include/Nazara/Utility/Utility.hpp index be840afb7..1beb98bcc 100644 --- a/include/Nazara/Utility/Utility.hpp +++ b/include/Nazara/Utility/Utility.hpp @@ -12,23 +12,26 @@ #include #include -class NAZARA_UTILITY_API NzUtility +namespace Nz { - public: - NzUtility() = delete; - ~NzUtility() = delete; + class NAZARA_UTILITY_API Utility + { + public: + Utility() = delete; + ~Utility() = delete; - static bool Initialize(); + static bool Initialize(); - static bool IsInitialized(); + static bool IsInitialized(); - static void Uninitialize(); + static void Uninitialize(); - static unsigned int ComponentCount[nzComponentType_Max+1]; - static std::size_t ComponentStride[nzComponentType_Max+1]; + static unsigned int ComponentCount[ComponentType_Max+1]; + static std::size_t ComponentStride[ComponentType_Max+1]; - private: - static unsigned int s_moduleReferenceCounter; -}; + private: + static unsigned int s_moduleReferenceCounter; + }; +} #endif // NAZARA_UTILITY_HPP diff --git a/include/Nazara/Utility/VertexBuffer.hpp b/include/Nazara/Utility/VertexBuffer.hpp index ee7de3dc0..270d6be9b 100644 --- a/include/Nazara/Utility/VertexBuffer.hpp +++ b/include/Nazara/Utility/VertexBuffer.hpp @@ -14,64 +14,67 @@ #include #include -class NzVertexBuffer; - -using NzVertexBufferConstRef = NzObjectRef; -using NzVertexBufferRef = NzObjectRef; - -class NAZARA_UTILITY_API NzVertexBuffer : public NzRefCounted +namespace Nz { - public: - NzVertexBuffer() = default; - NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer); - NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); - NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzUInt32 storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); - NzVertexBuffer(const NzVertexBuffer& vertexBuffer); - ~NzVertexBuffer(); + class VertexBuffer; - bool Fill(const void* data, unsigned int startVertex, unsigned int length, bool forceDiscard = false); - bool FillRaw(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false); + using VertexBufferConstRef = ObjectRef; + using VertexBufferRef = ObjectRef; - NzBuffer* GetBuffer() const; - unsigned int GetEndOffset() const; - unsigned int GetStartOffset() const; - unsigned int GetStride() const; - unsigned int GetVertexCount() const; - const NzVertexDeclaration* GetVertexDeclaration() const; + class NAZARA_UTILITY_API VertexBuffer : public RefCounted + { + public: + VertexBuffer() = default; + VertexBuffer(const VertexDeclaration* vertexDeclaration, Buffer* buffer); + VertexBuffer(const VertexDeclaration* vertexDeclaration, Buffer* buffer, unsigned int startOffset, unsigned int endOffset); + VertexBuffer(const VertexDeclaration* vertexDeclaration, unsigned int length, UInt32 storage = DataStorage_Software, BufferUsage usage = BufferUsage_Static); + VertexBuffer(const VertexBuffer& vertexBuffer); + ~VertexBuffer(); - bool IsHardware() const; - bool IsValid() const; + bool Fill(const void* data, unsigned int startVertex, unsigned int length, bool forceDiscard = false); + bool FillRaw(const void* data, unsigned int offset, unsigned int size, bool forceDiscard = false); - void* Map(nzBufferAccess access, unsigned int startVertex = 0, unsigned int length = 0); - void* Map(nzBufferAccess access, unsigned int startVertex = 0, unsigned int length = 0) const; - void* MapRaw(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0); - void* MapRaw(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0) const; + Buffer* GetBuffer() const; + unsigned int GetEndOffset() const; + unsigned int GetStartOffset() const; + unsigned int GetStride() const; + unsigned int GetVertexCount() const; + const VertexDeclaration* GetVertexDeclaration() const; - void Reset(); - void Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer); - void Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset); - void Reset(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzUInt32 storage = nzDataStorage_Software, nzBufferUsage usage = nzBufferUsage_Static); - void Reset(const NzVertexBuffer& vertexBuffer); + bool IsHardware() const; + bool IsValid() const; - bool SetStorage(nzUInt32 storage); - void SetVertexDeclaration(const NzVertexDeclaration* vertexDeclaration); + void* Map(BufferAccess access, unsigned int startVertex = 0, unsigned int length = 0); + void* Map(BufferAccess access, unsigned int startVertex = 0, unsigned int length = 0) const; + void* MapRaw(BufferAccess access, unsigned int offset = 0, unsigned int size = 0); + void* MapRaw(BufferAccess access, unsigned int offset = 0, unsigned int size = 0) const; - void Unmap() const; + void Reset(); + void Reset(const VertexDeclaration* vertexDeclaration, Buffer* buffer); + void Reset(const VertexDeclaration* vertexDeclaration, Buffer* buffer, unsigned int startOffset, unsigned int endOffset); + void Reset(const VertexDeclaration* vertexDeclaration, unsigned int length, UInt32 storage = DataStorage_Software, BufferUsage usage = BufferUsage_Static); + void Reset(const VertexBuffer& vertexBuffer); - NzVertexBuffer& operator=(const NzVertexBuffer& vertexBuffer); + bool SetStorage(UInt32 storage); + void SetVertexDeclaration(const VertexDeclaration* vertexDeclaration); - template static NzVertexBufferRef New(Args&&... args); + void Unmap() const; - // Signals: - NazaraSignal(OnVertexBufferRelease, const NzVertexBuffer* /*vertexBuffer*/); + VertexBuffer& operator=(const VertexBuffer& vertexBuffer); - private: - NzBufferRef m_buffer; - NzVertexDeclarationConstRef m_vertexDeclaration; - unsigned int m_endOffset; - unsigned int m_startOffset; - unsigned int m_vertexCount; -}; + template static VertexBufferRef New(Args&&... args); + + // Signals: + NazaraSignal(OnVertexBufferRelease, const VertexBuffer* /*vertexBuffer*/); + + private: + BufferRef m_buffer; + VertexDeclarationConstRef m_vertexDeclaration; + unsigned int m_endOffset; + unsigned int m_startOffset; + unsigned int m_vertexCount; + }; +} #include diff --git a/include/Nazara/Utility/VertexBuffer.inl b/include/Nazara/Utility/VertexBuffer.inl index 59429b31e..24268e9cb 100644 --- a/include/Nazara/Utility/VertexBuffer.inl +++ b/include/Nazara/Utility/VertexBuffer.inl @@ -5,13 +5,16 @@ #include #include -template -NzVertexBufferRef NzVertexBuffer::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzVertexBuffer(std::forward(args)...)); - object->SetPersistent(false); + template + VertexBufferRef VertexBuffer::New(Args&&... args) + { + std::unique_ptr object(new VertexBuffer(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Utility/VertexDeclaration.hpp b/include/Nazara/Utility/VertexDeclaration.hpp index 9ba9edda9..1e29bc9cd 100644 --- a/include/Nazara/Utility/VertexDeclaration.hpp +++ b/include/Nazara/Utility/VertexDeclaration.hpp @@ -15,64 +15,67 @@ #include #include -class NzVertexDeclaration; - -using NzVertexDeclarationConstRef = NzObjectRef; -using NzVertexDeclarationLibrary = NzObjectLibrary; -using NzVertexDeclarationRef = NzObjectRef; - -class NAZARA_UTILITY_API NzVertexDeclaration : public NzRefCounted +namespace Nz { - friend NzVertexDeclarationLibrary; - friend class NzUtility; + class VertexDeclaration; - public: - NzVertexDeclaration(); - NzVertexDeclaration(const NzVertexDeclaration& declaration); - ~NzVertexDeclaration(); + using VertexDeclarationConstRef = ObjectRef; + using VertexDeclarationLibrary = ObjectLibrary; + using VertexDeclarationRef = ObjectRef; - void DisableComponent(nzVertexComponent component); - void EnableComponent(nzVertexComponent component, nzComponentType type, unsigned int offset); + class NAZARA_UTILITY_API VertexDeclaration : public RefCounted + { + friend VertexDeclarationLibrary; + friend class Utility; - void GetComponent(nzVertexComponent component, bool* enabled, nzComponentType* type, unsigned int* offset) const; - unsigned int GetStride() const; + public: + VertexDeclaration(); + VertexDeclaration(const VertexDeclaration& declaration); + ~VertexDeclaration(); - void SetStride(unsigned int stride); + void DisableComponent(VertexComponent component); + void EnableComponent(VertexComponent component, ComponentType type, unsigned int offset); - NzVertexDeclaration& operator=(const NzVertexDeclaration& declaration); + void GetComponent(VertexComponent component, bool* enabled, ComponentType* type, unsigned int* offset) const; + unsigned int GetStride() const; - static NzVertexDeclaration* Get(nzVertexLayout layout); - static bool IsTypeSupported(nzComponentType type); - template static NzVertexDeclarationRef New(Args&&... args); + void SetStride(unsigned int stride); - // Signals: - NazaraSignal(OnVertexDeclarationRelease, const NzVertexDeclaration* /*vertexDeclaration*/); + VertexDeclaration& operator=(const VertexDeclaration& declaration); - private: - static bool Initialize(); - static void Uninitialize(); + static VertexDeclaration* Get(VertexLayout layout); + static bool IsTypeSupported(ComponentType type); + template static VertexDeclarationRef New(Args&&... args); - struct Component - { - nzComponentType type; // Le type de donnée - bool enabled = false; // Ce composant est-il activé ?/ - unsigned int offset; // La position, en octets, de la première donnée + // Signals: + NazaraSignal(OnVertexDeclarationRelease, const VertexDeclaration* /*vertexDeclaration*/); - /* - ** -Lynix: - ** Il serait aussi possible de préciser le stride de façon indépendante, ce que je ne permets pas - ** pour décomplexifier l'interface en enlevant quelque chose que je juge inutile. - ** Si vous pensez que ça peut être utile, n'hésitez pas à me le faire savoir ! - ** PS: Même cas pour le diviseur (instancing) - */ - }; + private: + static bool Initialize(); + static void Uninitialize(); - Component m_components[nzVertexComponent_Max+1]; - unsigned int m_stride; + struct Component + { + ComponentType type; // Le type de donnée + bool enabled = false; // Ce composant est-il activé ?/ + unsigned int offset; // La position, en octets, de la première donnée - static NzVertexDeclaration s_declarations[nzVertexLayout_Max+1]; - static NzVertexDeclarationLibrary::LibraryMap s_library; -}; + /* + ** -Lynix: + ** Il serait aussi possible de préciser le stride de façon indépendante, ce que je ne permets pas + ** pour décomplexifier l'interface en enlevant quelque chose que je juge inutile. + ** Si vous pensez que ça peut être utile, n'hésitez pas à me le faire savoir ! + ** PS: Même cas pour le diviseur (instancing) + */ + }; + + Component m_components[VertexComponent_Max+1]; + unsigned int m_stride; + + static VertexDeclaration s_declarations[VertexLayout_Max+1]; + static VertexDeclarationLibrary::LibraryMap s_library; + }; +} #include diff --git a/include/Nazara/Utility/VertexDeclaration.inl b/include/Nazara/Utility/VertexDeclaration.inl index d0bf546f7..beed900d5 100644 --- a/include/Nazara/Utility/VertexDeclaration.inl +++ b/include/Nazara/Utility/VertexDeclaration.inl @@ -5,13 +5,16 @@ #include #include -template -NzVertexDeclarationRef NzVertexDeclaration::New(Args&&... args) +namespace Nz { - std::unique_ptr object(new NzVertexDeclaration(std::forward(args)...)); - object->SetPersistent(false); + template + VertexDeclarationRef VertexDeclaration::New(Args&&... args) + { + std::unique_ptr object(new VertexDeclaration(std::forward(args)...)); + object->SetPersistent(false); - return object.release(); + return object.release(); + } } #include diff --git a/include/Nazara/Utility/VertexMapper.hpp b/include/Nazara/Utility/VertexMapper.hpp index 4af27d053..3dc9accdb 100644 --- a/include/Nazara/Utility/VertexMapper.hpp +++ b/include/Nazara/Utility/VertexMapper.hpp @@ -13,22 +13,25 @@ #include #include -class NzSubMesh; - -class NAZARA_UTILITY_API NzVertexMapper +namespace Nz { - public: - NzVertexMapper(NzSubMesh* subMesh, nzBufferAccess access = nzBufferAccess_ReadWrite); - NzVertexMapper(NzVertexBuffer* vertexBuffer, nzBufferAccess access = nzBufferAccess_ReadWrite); - ~NzVertexMapper(); + class SubMesh; - template NzSparsePtr GetComponentPtr(nzVertexComponent component); + class NAZARA_UTILITY_API VertexMapper + { + public: + VertexMapper(SubMesh* subMesh, BufferAccess access = BufferAccess_ReadWrite); + VertexMapper(VertexBuffer* vertexBuffer, BufferAccess access = BufferAccess_ReadWrite); + ~VertexMapper(); - void Unmap(); + template SparsePtr GetComponentPtr(VertexComponent component); - private: - NzBufferMapper m_mapper; -}; + void Unmap(); + + private: + BufferMapper m_mapper; + }; +} #include diff --git a/include/Nazara/Utility/VertexMapper.inl b/include/Nazara/Utility/VertexMapper.inl index c2b46a3c9..e2531cdbb 100644 --- a/include/Nazara/Utility/VertexMapper.inl +++ b/include/Nazara/Utility/VertexMapper.inl @@ -5,28 +5,31 @@ #include #include -template -NzSparsePtr NzVertexMapper::GetComponentPtr(nzVertexComponent component) +namespace Nz { - // On récupère la déclaration depuis le buffer - const NzVertexDeclaration* declaration = m_mapper.GetBuffer()->GetVertexDeclaration(); - - // Ensuite le composant qui nous intéresse - bool enabled; - nzComponentType type; - unsigned int offset; - declaration->GetComponent(component, &enabled, &type, &offset); - - if (enabled) + template + SparsePtr VertexMapper::GetComponentPtr(VertexComponent component) { - ///TODO: Vérifier le rapport entre le type de l'attribut et le type template ? - return NzSparsePtr(static_cast(m_mapper.GetPointer()) + offset, declaration->GetStride()); - } - else - { - NazaraError("Attribute 0x" + NzString::Number(component, 16) + " is not enabled"); - return NzSparsePtr(); + // On récupère la déclaration depuis le buffer + const VertexDeclaration* declaration = m_mapper.GetBuffer()->GetVertexDeclaration(); + + // Ensuite le composant qui nous intéresse + bool enabled; + ComponentType type; + unsigned int offset; + declaration->GetComponent(component, &enabled, &type, &offset); + + if (enabled) + { + ///TODO: Vérifier le rapport entre le type de l'attribut et le type template ? + return SparsePtr(static_cast(m_mapper.GetPointer()) + offset, declaration->GetStride()); + } + else + { + NazaraError("Attribute 0x" + String::Number(component, 16) + " is not enabled"); + return SparsePtr(); } } +} #include diff --git a/include/Nazara/Utility/VertexStruct.hpp b/include/Nazara/Utility/VertexStruct.hpp index 5c2bd313d..d9fa1d050 100644 --- a/include/Nazara/Utility/VertexStruct.hpp +++ b/include/Nazara/Utility/VertexStruct.hpp @@ -11,73 +11,76 @@ #include #include -/******************************* Structures 2D *******************************/ - -struct NzVertexStruct_XY +namespace Nz { - NzVector2f position; -}; + /******************************* Structures 2D *******************************/ -struct NzVertexStruct_XY_Color : NzVertexStruct_XY -{ - NzColor color; -}; + struct VertexStruct_XY + { + Vector2f position; + }; -struct NzVertexStruct_XY_UV : NzVertexStruct_XY -{ - NzVector2f uv; -}; + struct VertexStruct_XY_Color : VertexStruct_XY + { + Color color; + }; -struct NzVertexStruct_XY_Color_UV : NzVertexStruct_XY_Color -{ - NzVector2f uv; -}; + struct VertexStruct_XY_UV : VertexStruct_XY + { + Vector2f uv; + }; -/******************************* Structures 3D *******************************/ + struct VertexStruct_XY_Color_UV : VertexStruct_XY_Color + { + Vector2f uv; + }; -struct NzVertexStruct_XYZ -{ - NzVector3f position; -}; + /******************************* Structures 3D *******************************/ -struct NzVertexStruct_XYZ_Color : NzVertexStruct_XYZ -{ - NzColor color; -}; + struct VertexStruct_XYZ + { + Vector3f position; + }; -struct NzVertexStruct_XYZ_Color_UV : NzVertexStruct_XYZ_Color -{ - NzVector2f uv; -}; + struct VertexStruct_XYZ_Color : VertexStruct_XYZ + { + Color color; + }; -struct NzVertexStruct_XYZ_Normal : NzVertexStruct_XYZ -{ - NzVector3f normal; -}; + struct VertexStruct_XYZ_Color_UV : VertexStruct_XYZ_Color + { + Vector2f uv; + }; -struct NzVertexStruct_XYZ_Normal_UV : NzVertexStruct_XYZ_Normal -{ - NzVector2f uv; -}; + struct VertexStruct_XYZ_Normal : VertexStruct_XYZ + { + Vector3f normal; + }; -struct NzVertexStruct_XYZ_Normal_UV_Tangent : NzVertexStruct_XYZ_Normal_UV -{ - NzVector3f tangent; -}; + struct VertexStruct_XYZ_Normal_UV : VertexStruct_XYZ_Normal + { + Vector2f uv; + }; -struct NzVertexStruct_XYZ_UV : NzVertexStruct_XYZ -{ - NzVector2f uv; -}; + struct VertexStruct_XYZ_Normal_UV_Tangent : VertexStruct_XYZ_Normal_UV + { + Vector3f tangent; + }; -/************************* Structures 3D (+ Skinning) ************************/ + struct VertexStruct_XYZ_UV : VertexStruct_XYZ + { + Vector2f uv; + }; -struct NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning : NzVertexStruct_XYZ_Normal_UV_Tangent -{ - nzInt32 weightCount; + /************************* Structures 3D (+ Skinning) ************************/ - NzVector4f weights; - NzVector4i32 jointIndexes; -}; + struct VertexStruct_XYZ_Normal_UV_Tangent_Skinning : VertexStruct_XYZ_Normal_UV_Tangent + { + Int32 weightCount; + + Vector4f weights; + Vector4i32 jointIndexes; + }; +} #endif // NAZARA_VERTEXSTRUCT_HPP diff --git a/include/Nazara/Utility/VideoMode.hpp b/include/Nazara/Utility/VideoMode.hpp index 25f9292cc..dae9a5410 100644 --- a/include/Nazara/Utility/VideoMode.hpp +++ b/include/Nazara/Utility/VideoMode.hpp @@ -13,27 +13,30 @@ #include #include -class NAZARA_UTILITY_API NzVideoMode +namespace Nz { - public: - NzVideoMode(); - NzVideoMode(unsigned int w, unsigned int h, nzUInt8 bpp); + class NAZARA_UTILITY_API VideoMode + { + public: + VideoMode(); + VideoMode(unsigned int w, unsigned int h, UInt8 bpp); - bool IsFullscreenValid() const; + bool IsFullscreenValid() const; - nzUInt8 bitsPerPixel; - unsigned int height; - unsigned int width; + UInt8 bitsPerPixel; + unsigned int height; + unsigned int width; - static NzVideoMode GetDesktopMode(); - static const std::vector& GetFullscreenModes(); -}; + static VideoMode GetDesktopMode(); + static const std::vector& GetFullscreenModes(); + }; -bool operator==(const NzVideoMode& left, const NzVideoMode& right); -bool operator!=(const NzVideoMode& left, const NzVideoMode& right); -bool operator<(const NzVideoMode& left, const NzVideoMode& right); -bool operator<=(const NzVideoMode& left, const NzVideoMode& right); -bool operator>(const NzVideoMode& left, const NzVideoMode& right); -bool operator>=(const NzVideoMode& left, const NzVideoMode& right); + bool operator==(const VideoMode& left, const VideoMode& right); + bool operator!=(const VideoMode& left, const VideoMode& right); + bool operator<(const VideoMode& left, const VideoMode& right); + bool operator<=(const VideoMode& left, const VideoMode& right); + bool operator>(const VideoMode& left, const VideoMode& right); + bool operator>=(const VideoMode& left, const VideoMode& right); +} #endif // NAZARA_VIDEOMODE_HPP diff --git a/include/Nazara/Utility/Window.hpp b/include/Nazara/Utility/Window.hpp index 4effff377..75f066bd8 100644 --- a/include/Nazara/Utility/Window.hpp +++ b/include/Nazara/Utility/Window.hpp @@ -24,99 +24,102 @@ #include #endif -class NzCursor; -class NzImage; -class NzIcon; -class NzWindowImpl; - -class NAZARA_UTILITY_API NzWindow +namespace Nz { - friend NzWindowImpl; - friend class NzMouse; - friend class NzUtility; + class Cursor; + class Image; + class Icon; + class WindowImpl; - public: - NzWindow(); - NzWindow(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default); - NzWindow(NzWindowHandle handle); - NzWindow(const NzWindow&) = delete; - NzWindow(NzWindow&&) = delete; ///TODO - virtual ~NzWindow(); + class NAZARA_UTILITY_API Window + { + friend WindowImpl; + friend class Mouse; + friend class Utility; - void Close(); + public: + Window(); + Window(VideoMode mode, const String& title, UInt32 style = WindowStyle_Default); + Window(WindowHandle handle); + Window(const Window&) = delete; + Window(Window&&) = delete; ///TODO + virtual ~Window(); - bool Create(NzVideoMode mode, const NzString& title, nzUInt32 style = nzWindowStyle_Default); - bool Create(NzWindowHandle handle); + void Close(); - void Destroy(); + bool Create(VideoMode mode, const String& title, UInt32 style = WindowStyle_Default); + bool Create(WindowHandle handle); - void EnableKeyRepeat(bool enable); - void EnableSmoothScrolling(bool enable); + void Destroy(); - NzWindowHandle GetHandle() const; - unsigned int GetHeight() const; - NzVector2i GetPosition() const; - NzVector2ui GetSize() const; - nzUInt32 GetStyle() const; - NzString GetTitle() const; - unsigned int GetWidth() const; + void EnableKeyRepeat(bool enable); + void EnableSmoothScrolling(bool enable); - bool HasFocus() const; + WindowHandle GetHandle() const; + unsigned int GetHeight() const; + Vector2i GetPosition() const; + Vector2ui GetSize() const; + UInt32 GetStyle() const; + String GetTitle() const; + unsigned int GetWidth() const; - bool IsMinimized() const; - bool IsOpen(bool checkClosed = true); - bool IsOpen() const; - bool IsValid() const; - bool IsVisible() const; + bool HasFocus() const; - bool PollEvent(NzEvent* event); + bool IsMinimized() const; + bool IsOpen(bool checkClosed = true); + bool IsOpen() const; + bool IsValid() const; + bool IsVisible() const; - void SetCursor(nzWindowCursor cursor); - void SetCursor(const NzCursor& cursor); - void SetEventListener(bool listener); - void SetFocus(); - void SetIcon(const NzIcon& icon); - void SetMaximumSize(const NzVector2i& maxSize); - void SetMaximumSize(int width, int height); - void SetMinimumSize(const NzVector2i& minSize); - void SetMinimumSize(int width, int height); - void SetPosition(const NzVector2i& position); - void SetPosition(int x, int y); - void SetSize(const NzVector2i& size); - void SetSize(unsigned int width, unsigned int height); - void SetStayOnTop(bool stayOnTop); - void SetTitle(const NzString& title); - void SetVisible(bool visible); + bool PollEvent(WindowEvent* event); - bool WaitEvent(NzEvent* event); + void SetCursor(WindowCursor cursor); + void SetCursor(const Cursor& cursor); + void SetEventListener(bool listener); + void SetFocus(); + void SetIcon(const Icon& icon); + void SetMaximumSize(const Vector2i& maxSize); + void SetMaximumSize(int width, int height); + void SetMinimumSize(const Vector2i& minSize); + void SetMinimumSize(int width, int height); + void SetPosition(const Vector2i& position); + void SetPosition(int x, int y); + void SetSize(const Vector2i& size); + void SetSize(unsigned int width, unsigned int height); + void SetStayOnTop(bool stayOnTop); + void SetTitle(const String& title); + void SetVisible(bool visible); - NzWindow& operator=(const NzWindow&) = delete; - NzWindow& operator=(NzWindow&&) = delete; ///TODO + bool WaitEvent(WindowEvent* event); - protected: - virtual bool OnWindowCreated(); - virtual void OnWindowDestroy(); - virtual void OnWindowResized(); + Window& operator=(const Window&) = delete; + Window& operator=(Window&&) = delete; ///TODO - NzWindowImpl* m_impl; + protected: + virtual bool OnWindowCreated(); + virtual void OnWindowDestroy(); + virtual void OnWindowResized(); - private: - void IgnoreNextMouseEvent(int mouseX, int mouseY) const; - void PushEvent(const NzEvent& event); + WindowImpl* m_impl; - static bool Initialize(); - static void Uninitialize(); + private: + void IgnoreNextMouseEvent(int mouseX, int mouseY) const; + void PushEvent(const WindowEvent& event); - std::queue m_events; - #if NAZARA_UTILITY_THREADED_WINDOW - NzConditionVariable m_eventCondition; - NzMutex m_eventMutex; - NzMutex m_eventConditionMutex; - bool m_eventListener; - bool m_waitForEvent; - #endif - bool m_closed; - bool m_ownsWindow; -}; + static bool Initialize(); + static void Uninitialize(); + + std::queue m_events; + #if NAZARA_UTILITY_THREADED_WINDOW + ConditionVariable m_eventCondition; + Mutex m_eventMutex; + Mutex m_eventConditionMutex; + bool m_eventListener; + bool m_waitForEvent; + #endif + bool m_closed; + bool m_ownsWindow; + }; +} #endif // NAZARA_WINDOW_HPP diff --git a/include/Nazara/Utility/WindowHandle.hpp b/include/Nazara/Utility/WindowHandle.hpp index 6069e3247..63b5dc2ac 100644 --- a/include/Nazara/Utility/WindowHandle.hpp +++ b/include/Nazara/Utility/WindowHandle.hpp @@ -9,15 +9,18 @@ #include -#if defined(NAZARA_PLATFORM_WINDOWS) -// http://msdn.microsoft.com/en-us/library/aa383751(v=vs.85).aspx -typedef void* NzWindowHandle; -#elif defined(NAZARA_PLATFORM_LINUX) -#include -// http://en.wikipedia.org/wiki/Xlib#Data_types -using NzWindowHandle = xcb_window_t; -#else - #error Lack of implementation: WindowHandle -#endif +namespace Nz +{ + #if defined(NAZARA_PLATFORM_WINDOWS) + // http://msdn.microsoft.com/en-us/library/aa383751(v=vs.85).aspx + typedef void* WindowHandle; + #elif defined(NAZARA_PLATFORM_LINUX) + #include + // http://en.wikipedia.org/wiki/Xlib#Data_types + using WindowHandle = xcb_window_t; + #else + #error Lack of implementation: WindowHandle + #endif +} #endif // NAZARA_WINDOWHANDLE_HPP diff --git a/src/Nazara/Audio/Audio.cpp b/src/Nazara/Audio/Audio.cpp index ef1481e50..c0e785865 100644 --- a/src/Nazara/Audio/Audio.cpp +++ b/src/Nazara/Audio/Audio.cpp @@ -14,233 +14,236 @@ #include #include -nzAudioFormat NzAudio::GetAudioFormat(unsigned int channelCount) +namespace Nz { - switch (channelCount) + AudioFormat Audio::GetAudioFormat(unsigned int channelCount) { - case 1: - case 2: - case 4: - case 6: - case 7: - case 8: - return static_cast(channelCount); + switch (channelCount) + { + case 1: + case 2: + case 4: + case 6: + case 7: + case 8: + return static_cast(channelCount); - default: - NazaraError("Invalid channel count: " + NzString::Number(channelCount)); - return nzAudioFormat_Unknown; + default: + NazaraError("Invalid channel count: " + String::Number(channelCount)); + return AudioFormat_Unknown; + } } -} -float NzAudio::GetDopplerFactor() -{ - return alGetFloat(AL_DOPPLER_FACTOR); -} - -float NzAudio::GetGlobalVolume() -{ - ALfloat gain = 0.f; - alGetListenerf(AL_GAIN, &gain); - - return gain*100.f; -} - -NzVector3f NzAudio::GetListenerDirection() -{ - ALfloat orientation[6]; - alGetListenerfv(AL_ORIENTATION, orientation); - - return NzVector3f(orientation[0], orientation[1], orientation[2]); -} - -NzVector3f NzAudio::GetListenerPosition() -{ - NzVector3f position; - alGetListenerfv(AL_POSITION, position); - - return position; -} - -NzQuaternionf NzAudio::GetListenerRotation() -{ - ALfloat orientation[6]; - alGetListenerfv(AL_ORIENTATION, orientation); - - NzVector3f forward(orientation[0], orientation[1], orientation[2]); - - return NzQuaternionf::RotationBetween(NzVector3f::Forward(), forward); -} - -NzVector3f NzAudio::GetListenerVelocity() -{ - NzVector3f velocity; - alGetListenerfv(AL_VELOCITY, velocity); - - return velocity; -} - -float NzAudio::GetSpeedOfSound() -{ - return alGetFloat(AL_SPEED_OF_SOUND); -} - -bool NzAudio::Initialize() -{ - if (s_moduleReferenceCounter > 0) + float Audio::GetDopplerFactor() { + return alGetFloat(AL_DOPPLER_FACTOR); + } + + float Audio::GetGlobalVolume() + { + ALfloat gain = 0.f; + alGetListenerf(AL_GAIN, &gain); + + return gain*100.f; + } + + Vector3f Audio::GetListenerDirection() + { + ALfloat orientation[6]; + alGetListenerfv(AL_ORIENTATION, orientation); + + return Vector3f(orientation[0], orientation[1], orientation[2]); + } + + Vector3f Audio::GetListenerPosition() + { + Vector3f position; + alGetListenerfv(AL_POSITION, position); + + return position; + } + + Quaternionf Audio::GetListenerRotation() + { + ALfloat orientation[6]; + alGetListenerfv(AL_ORIENTATION, orientation); + + Vector3f forward(orientation[0], orientation[1], orientation[2]); + + return Quaternionf::RotationBetween(Vector3f::Forward(), forward); + } + + Vector3f Audio::GetListenerVelocity() + { + Vector3f velocity; + alGetListenerfv(AL_VELOCITY, velocity); + + return velocity; + } + + float Audio::GetSpeedOfSound() + { + return alGetFloat(AL_SPEED_OF_SOUND); + } + + bool Audio::Initialize() + { + if (s_moduleReferenceCounter > 0) + { + s_moduleReferenceCounter++; + return true; // Déjà initialisé + } + + // Initialisation des dépendances + if (!Core::Initialize()) + { + NazaraError("Failed to initialize core module"); + return false; + } + s_moduleReferenceCounter++; - return true; // Déjà initialisé + + // Initialisation du module + CallOnExit onExit(Audio::Uninitialize); + + // Initialisation d'OpenAL + if (!OpenAL::Initialize()) + { + NazaraError("Failed to initialize OpenAL"); + return false; + } + + if (!SoundBuffer::Initialize()) + { + NazaraError("Failed to initialize sound buffers"); + return false; + } + + // Définition de l'orientation par défaut + SetListenerDirection(Vector3f::Forward()); + + // Loaders + Loaders::Register_sndfile(); + + onExit.Reset(); + + NazaraNotice("Initialized: Audio module"); + return true; } - // Initialisation des dépendances - if (!NzCore::Initialize()) + bool Audio::IsFormatSupported(AudioFormat format) { - NazaraError("Failed to initialize core module"); - return false; + if (format == AudioFormat_Unknown) + return false; + + return OpenAL::AudioFormat[format] != 0; } - s_moduleReferenceCounter++; - - // Initialisation du module - NzCallOnExit onExit(NzAudio::Uninitialize); - - // Initialisation d'OpenAL - if (!NzOpenAL::Initialize()) + bool Audio::IsInitialized() { - NazaraError("Failed to initialize OpenAL"); - return false; + return s_moduleReferenceCounter != 0; } - if (!NzSoundBuffer::Initialize()) + void Audio::SetDopplerFactor(float dopplerFactor) { - NazaraError("Failed to initialize sound buffers"); - return false; + alDopplerFactor(dopplerFactor); } - // Définition de l'orientation par défaut - SetListenerDirection(NzVector3f::Forward()); - - // Loaders - NzLoaders_sndfile_Register(); - - onExit.Reset(); - - NazaraNotice("Initialized: Audio module"); - return true; -} - -bool NzAudio::IsFormatSupported(nzAudioFormat format) -{ - if (format == nzAudioFormat_Unknown) - return false; - - return NzOpenAL::AudioFormat[format] != 0; -} - -bool NzAudio::IsInitialized() -{ - return s_moduleReferenceCounter != 0; -} - -void NzAudio::SetDopplerFactor(float dopplerFactor) -{ - alDopplerFactor(dopplerFactor); -} - -void NzAudio::SetGlobalVolume(float volume) -{ - alListenerf(AL_GAIN, volume*0.01f); -} - -void NzAudio::SetListenerDirection(const NzVector3f& direction) -{ - NzVector3f up = NzVector3f::Up(); - - ALfloat orientation[6] = + void Audio::SetGlobalVolume(float volume) { - direction.x, direction.y, direction.z, - up.x, up.y, up.z - }; - - alListenerfv(AL_ORIENTATION, orientation); -} - -void NzAudio::SetListenerDirection(float dirX, float dirY, float dirZ) -{ - NzVector3f up = NzVector3f::Up(); - - ALfloat orientation[6] = - { - dirX, dirY, dirZ, - up.x, up.y, up.z - }; - - alListenerfv(AL_ORIENTATION, orientation); -} - -void NzAudio::SetListenerPosition(const NzVector3f& position) -{ - alListenerfv(AL_POSITION, position); -} - -void NzAudio::SetListenerPosition(float x, float y, float z) -{ - alListener3f(AL_POSITION, x, y, z); -} - -void NzAudio::SetListenerRotation(const NzQuaternionf& rotation) -{ - NzVector3f forward = rotation * NzVector3f::Forward(); - NzVector3f up = NzVector3f::Up(); - - ALfloat orientation[6] = - { - forward.x, forward.y, forward.z, - up.x, up.y, up.z - }; - - alListenerfv(AL_ORIENTATION, orientation); -} - -void NzAudio::SetListenerVelocity(const NzVector3f& velocity) -{ - alListenerfv(AL_VELOCITY, velocity); -} - -void NzAudio::SetListenerVelocity(float velX, float velY, float velZ) -{ - alListener3f(AL_VELOCITY, velX, velY, velZ); -} - -void NzAudio::SetSpeedOfSound(float speed) -{ - alSpeedOfSound(speed); -} - -void NzAudio::Uninitialize() -{ - if (s_moduleReferenceCounter != 1) - { - // Le module est soit encore utilisé, soit pas initialisé - if (s_moduleReferenceCounter > 1) - s_moduleReferenceCounter--; - - return; + alListenerf(AL_GAIN, volume*0.01f); } - // Libération du module - s_moduleReferenceCounter = 0; + void Audio::SetListenerDirection(const Vector3f& direction) + { + Vector3f up = Vector3f::Up(); - // Loaders - NzLoaders_sndfile_Unregister(); + ALfloat orientation[6] = + { + direction.x, direction.y, direction.z, + up.x, up.y, up.z + }; - NzSoundBuffer::Uninitialize(); - NzOpenAL::Uninitialize(); + alListenerfv(AL_ORIENTATION, orientation); + } - NazaraNotice("Uninitialized: Audio module"); + void Audio::SetListenerDirection(float dirX, float dirY, float dirZ) + { + Vector3f up = Vector3f::Up(); - // Libération des dépendances - NzCore::Uninitialize(); + ALfloat orientation[6] = + { + dirX, dirY, dirZ, + up.x, up.y, up.z + }; + + alListenerfv(AL_ORIENTATION, orientation); + } + + void Audio::SetListenerPosition(const Vector3f& position) + { + alListenerfv(AL_POSITION, position); + } + + void Audio::SetListenerPosition(float x, float y, float z) + { + alListener3f(AL_POSITION, x, y, z); + } + + void Audio::SetListenerRotation(const Quaternionf& rotation) + { + Vector3f forward = rotation * Vector3f::Forward(); + Vector3f up = Vector3f::Up(); + + ALfloat orientation[6] = + { + forward.x, forward.y, forward.z, + up.x, up.y, up.z + }; + + alListenerfv(AL_ORIENTATION, orientation); + } + + void Audio::SetListenerVelocity(const Vector3f& velocity) + { + alListenerfv(AL_VELOCITY, velocity); + } + + void Audio::SetListenerVelocity(float velX, float velY, float velZ) + { + alListener3f(AL_VELOCITY, velX, velY, velZ); + } + + void Audio::SetSpeedOfSound(float speed) + { + alSpeedOfSound(speed); + } + + void Audio::Uninitialize() + { + if (s_moduleReferenceCounter != 1) + { + // Le module est soit encore utilisé, soit pas initialisé + if (s_moduleReferenceCounter > 1) + s_moduleReferenceCounter--; + + return; + } + + // Libération du module + s_moduleReferenceCounter = 0; + + // Loaders + Loaders::Unregister_sndfile(); + + SoundBuffer::Uninitialize(); + OpenAL::Uninitialize(); + + NazaraNotice("Uninitialized: Audio module"); + + // Libération des dépendances + Core::Uninitialize(); + } + + unsigned int Audio::s_moduleReferenceCounter = 0; } - -unsigned int NzAudio::s_moduleReferenceCounter = 0; diff --git a/src/Nazara/Audio/Formats/sndfileLoader.cpp b/src/Nazara/Audio/Formats/sndfileLoader.cpp index 3020c8de6..14f932e9e 100644 --- a/src/Nazara/Audio/Formats/sndfileLoader.cpp +++ b/src/Nazara/Audio/Formats/sndfileLoader.cpp @@ -21,373 +21,379 @@ #include #include -namespace +namespace Nz { - sf_count_t GetSize(void* user_data) + namespace Detail { - NzInputStream* stream = static_cast(user_data); - return stream->GetSize(); - } - - sf_count_t Read(void* ptr, sf_count_t count, void* user_data) - { - NzInputStream* stream = static_cast(user_data); - return static_cast(stream->Read(ptr, static_cast(count))); - } - - sf_count_t Seek(sf_count_t offset, int whence, void* user_data) - { - NzInputStream* stream = static_cast(user_data); - switch (whence) + sf_count_t GetSize(void* user_data) { - case SEEK_CUR: - stream->Read(nullptr, static_cast(offset)); - break; - - case SEEK_END: - stream->SetCursorPos(stream->GetSize() + offset); // L'offset est négatif ici - break; - - case SEEK_SET: - stream->SetCursorPos(offset); - break; - - default: - NazaraInternalError("Seek mode not handled"); + InputStream* stream = static_cast(user_data); + return stream->GetSize(); } - return stream->GetCursorPos(); - } + sf_count_t Read(void* ptr, sf_count_t count, void* user_data) + { + InputStream* stream = static_cast(user_data); + return static_cast(stream->Read(ptr, static_cast(count))); + } - sf_count_t Tell(void* user_data) - { - NzInputStream* stream = static_cast(user_data); - return stream->GetCursorPos(); - } - - static SF_VIRTUAL_IO callbacks = {GetSize, Seek, Read, nullptr, Tell}; - - class sndfileStream : public NzSoundStream - { - public: - sndfileStream() : - m_handle(nullptr) + sf_count_t Seek(sf_count_t offset, int whence, void* user_data) + { + InputStream* stream = static_cast(user_data); + switch (whence) { + case SEEK_CUR: + stream->Read(nullptr, static_cast(offset)); + break; + + case SEEK_END: + stream->SetCursorPos(stream->GetSize() + offset); // L'offset est négatif ici + break; + + case SEEK_SET: + stream->SetCursorPos(offset); + break; + + default: + NazaraInternalError("Seek mode not handled"); } - ~sndfileStream() - { - if (m_handle) - sf_close(m_handle); - } + return stream->GetCursorPos(); + } - nzUInt32 GetDuration() const override - { - return m_duration; - } + sf_count_t Tell(void* user_data) + { + InputStream* stream = static_cast(user_data); + return stream->GetCursorPos(); + } - nzAudioFormat GetFormat() const override - { - // Nous avons besoin du nombre de canaux d'origine pour convertir en mono, nous trichons donc un peu... - if (m_mixToMono) - return nzAudioFormat_Mono; - else - return m_format; - } + static SF_VIRTUAL_IO callbacks = {GetSize, Seek, Read, nullptr, Tell}; - nzUInt32 GetSampleCount() const override - { - return m_sampleCount; - } - - nzUInt32 GetSampleRate() const override - { - return m_sampleRate; - } - - bool Open(const NzString& filePath, bool forceMono) - { - // Nous devons gérer nous-même le flux car il doit rester ouvert après le passage du loader - // (les flux automatiquement ouverts par le ResourceLoader étant fermés après celui-ci) - std::unique_ptr file(new NzFile); - if (!file->Open(filePath, nzOpenMode_ReadOnly)) + class sndfileStream : public SoundStream + { + public: + sndfileStream() : + m_handle(nullptr) { - NazaraError("Failed to open stream from file: " + NzError::GetLastError()); - return false; } - m_ownedStream = std::move(file); - return Open(*m_ownedStream, forceMono); - } - - bool Open(const void* data, std::size_t size, bool forceMono) - { - m_ownedStream.reset(new NzMemoryStream(data, size)); - return Open(*m_ownedStream, forceMono); - } - - bool Open(NzInputStream& stream, bool forceMono) - { - SF_INFO infos; - infos.format = 0; // Format inconnu - - m_handle = sf_open_virtual(&callbacks, SFM_READ, &infos, &stream); - if (!m_handle) + ~sndfileStream() { - NazaraError("Failed to open sound: " + NzString(sf_strerror(m_handle))); - return false; + if (m_handle) + sf_close(m_handle); } - // Un peu de RRID - NzCallOnExit onExit([this] + UInt32 GetDuration() const override { - sf_close(m_handle); - m_handle = nullptr; - }); - - m_format = NzAudio::GetAudioFormat(infos.channels); - if (m_format == nzAudioFormat_Unknown) - { - NazaraError("Channel count not handled"); - return false; + return m_duration; } - m_sampleCount = static_cast(infos.channels*infos.frames); - m_sampleRate = infos.samplerate; - - // Durée de la musique (s) = samples / channels*rate - m_duration = static_cast(1000ULL*m_sampleCount / (m_format*m_sampleRate)); - - // https://github.com/LaurentGomila/SFML/issues/271 - // http://www.mega-nerd.com/libsndfile/command.html#SFC_SET_SCALE_FLOAT_INT_READ - ///FIXME: Seulement le Vorbis ? - if (infos.format & SF_FORMAT_VORBIS) - sf_command(m_handle, SFC_SET_SCALE_FLOAT_INT_READ, nullptr, SF_TRUE); - - // On mixera en mono lors de la lecture - if (forceMono && m_format != nzAudioFormat_Mono) + AudioFormat GetFormat() const override { - m_mixToMono = true; - m_sampleCount = static_cast(infos.frames); + // Nous avons besoin du nombre de canaux d'origine pour convertir en mono, nous trichons donc un peu... + if (m_mixToMono) + return AudioFormat_Mono; + else + return m_format; } - else - m_mixToMono = false; - onExit.Reset(); - - return true; - } - - unsigned int Read(void* buffer, unsigned int sampleCount) - { - // Si la musique a été demandée en mono, nous devons la convertir à la volée lors de la lecture - if (m_mixToMono) + UInt32 GetSampleCount() const override { - // On garde un buffer sur le côté pour éviter la réallocation - m_mixBuffer.resize(m_format * sampleCount); - sf_count_t readSampleCount = sf_read_short(m_handle, m_mixBuffer.data(), m_format * sampleCount); - NzMixToMono(m_mixBuffer.data(), static_cast(buffer), m_format, sampleCount); - - return static_cast(readSampleCount / m_format); + return m_sampleCount; } - else - return static_cast(sf_read_short(m_handle, static_cast(buffer), sampleCount)); - } - void Seek(nzUInt32 offset) override - { - sf_seek(m_handle, offset*m_sampleRate / 1000, SEEK_SET); - } + UInt32 GetSampleRate() const override + { + return m_sampleRate; + } - private: - std::vector m_mixBuffer; - std::unique_ptr m_ownedStream; - nzAudioFormat m_format; - SNDFILE* m_handle; - bool m_mixToMono; - nzUInt32 m_duration; - unsigned int m_sampleCount; - unsigned int m_sampleRate; - }; + bool Open(const String& filePath, bool forceMono) + { + // Nous devons gérer nous-même le flux car il doit rester ouvert après le passage du loader + // (les flux automatiquement ouverts par le ResourceLoader étant fermés après celui-ci) + std::unique_ptr file(new File); + if (!file->Open(filePath, OpenMode_ReadOnly)) + { + NazaraError("Failed to open stream from file: " + Error::GetLastError()); + return false; + } - bool IsSupported(const NzString& extension) - { - static std::set supportedExtensions = { - "aiff", "au", "avr", "caf", "flac", "htk", "ircam", "mat4", "mat5", "mpc2k", - "nist","ogg", "pvf", "raw", "rf64", "sd2", "sds", "svx", "voc", "w64", "wav", "wve" + m_ownedStream = std::move(file); + return Open(*m_ownedStream, forceMono); + } + + bool Open(const void* data, std::size_t size, bool forceMono) + { + m_ownedStream.reset(new MemoryStream(data, size)); + return Open(*m_ownedStream, forceMono); + } + + bool Open(InputStream& stream, bool forceMono) + { + SF_INFO infos; + infos.format = 0; // Format inconnu + + m_handle = sf_open_virtual(&callbacks, SFM_READ, &infos, &stream); + if (!m_handle) + { + NazaraError("Failed to open sound: " + String(sf_strerror(m_handle))); + return false; + } + + // Un peu de RRID + CallOnExit onExit([this] + { + sf_close(m_handle); + m_handle = nullptr; + }); + + m_format = Audio::GetAudioFormat(infos.channels); + if (m_format == AudioFormat_Unknown) + { + NazaraError("Channel count not handled"); + return false; + } + + m_sampleCount = static_cast(infos.channels*infos.frames); + m_sampleRate = infos.samplerate; + + // Durée de la musique (s) = samples / channels*rate + m_duration = static_cast(1000ULL*m_sampleCount / (m_format*m_sampleRate)); + + // https://github.com/LaurentGomila/SFML/issues/271 + // http://www.mega-nerd.com/libsndfile/command.html#SFC_SET_SCALE_FLOAT_INT_READ + ///FIXME: Seulement le Vorbis ? + if (infos.format & SF_FORMAT_VORBIS) + sf_command(m_handle, SFC_SET_SCALE_FLOAT_INT_READ, nullptr, SF_TRUE); + + // On mixera en mono lors de la lecture + if (forceMono && m_format != AudioFormat_Mono) + { + m_mixToMono = true; + m_sampleCount = static_cast(infos.frames); + } + else + m_mixToMono = false; + + onExit.Reset(); + + return true; + } + + unsigned int Read(void* buffer, unsigned int sampleCount) + { + // Si la musique a été demandée en mono, nous devons la convertir à la volée lors de la lecture + if (m_mixToMono) + { + // On garde un buffer sur le côté pour éviter la réallocation + m_mixBuffer.resize(m_format * sampleCount); + sf_count_t readSampleCount = sf_read_short(m_handle, m_mixBuffer.data(), m_format * sampleCount); + MixToMono(m_mixBuffer.data(), static_cast(buffer), m_format, sampleCount); + + return static_cast(readSampleCount / m_format); + } + else + return static_cast(sf_read_short(m_handle, static_cast(buffer), sampleCount)); + } + + void Seek(UInt32 offset) override + { + sf_seek(m_handle, offset*m_sampleRate / 1000, SEEK_SET); + } + + private: + std::vector m_mixBuffer; + std::unique_ptr m_ownedStream; + AudioFormat m_format; + SNDFILE* m_handle; + bool m_mixToMono; + UInt32 m_duration; + unsigned int m_sampleCount; + unsigned int m_sampleRate; }; - return supportedExtensions.find(extension) != supportedExtensions.end(); + bool IsSupported(const String& extension) + { + static std::set supportedExtensions = { + "aiff", "au", "avr", "caf", "flac", "htk", "ircam", "mat4", "mat5", "mpc2k", + "nist","ogg", "pvf", "raw", "rf64", "sd2", "sds", "svx", "voc", "w64", "wav", "wve" + }; + + return supportedExtensions.find(extension) != supportedExtensions.end(); + } + + Ternary CheckMusic(InputStream& stream, const MusicParams& parameters) + { + NazaraUnused(parameters); + + SF_INFO info; + info.format = 0; // Format inconnu + + // Si on peut ouvrir le flux, c'est qu'il est dans un format compatible + SNDFILE* file = sf_open_virtual(&callbacks, SFM_READ, &info, &stream); + if (file) + { + sf_close(file); + return Ternary_True; + } + else + return Ternary_False; + } + + bool LoadMusicFile(Music* music, const String& filePath, const MusicParams& parameters) + { + std::unique_ptr musicStream(new sndfileStream); + if (!musicStream->Open(filePath, parameters.forceMono)) + { + NazaraError("Failed to open music stream"); + return false; + } + + if (!music->Create(musicStream.get())) // Transfert de propriété + { + NazaraError("Failed to create music"); + return false; + } + + // Le pointeur a été transféré avec succès, nous pouvons laisser tomber la propriété + musicStream.release(); + + return true; + } + + bool LoadMusicMemory(Music* music, const void* data, std::size_t size, const MusicParams& parameters) + { + std::unique_ptr musicStream(new sndfileStream); + if (!musicStream->Open(data, size, parameters.forceMono)) + { + NazaraError("Failed to open music stream"); + return false; + } + + if (!music->Create(musicStream.get())) // Transfert de propriété + { + NazaraError("Failed to create music"); + return false; + } + + // Le pointeur a été transféré avec succès, nous pouvons laisser tomber la propriété + musicStream.release(); + + return true; + } + + bool LoadMusicStream(Music* music, InputStream& stream, const MusicParams& parameters) + { + std::unique_ptr musicStream(new sndfileStream); + if (!musicStream->Open(stream, parameters.forceMono)) + { + NazaraError("Failed to open music stream"); + return false; + } + + if (!music->Create(musicStream.get())) // Transfert de propriété + { + NazaraError("Failed to create music"); + return false; + } + + // Le pointeur a été transféré avec succès, nous pouvons laisser tomber la propriété + musicStream.release(); + + return true; + } + + Ternary CheckSoundBuffer(InputStream& stream, const SoundBufferParams& parameters) + { + NazaraUnused(parameters); + + SF_INFO info; + info.format = 0; + + SNDFILE* file = sf_open_virtual(&callbacks, SFM_READ, &info, &stream); + if (file) + { + sf_close(file); + return Ternary_True; + } + else + return Ternary_False; + } + + bool LoadSoundBuffer(SoundBuffer* soundBuffer, InputStream& stream, const SoundBufferParams& parameters) + { + SF_INFO info; + info.format = 0; + + SNDFILE* file = sf_open_virtual(&callbacks, SFM_READ, &info, &stream); + if (!file) + { + NazaraError("Failed to load sound file: " + String(sf_strerror(file))); + return false; + } + + // Lynix utilise RAII... + // C'est très efficace ! + // MemoryLeak est confus... + CallOnExit onExit([file] + { + sf_close(file); + }); + + AudioFormat format = Audio::GetAudioFormat(info.channels); + if (format == AudioFormat_Unknown) + { + NazaraError("Channel count not handled"); + return false; + } + + // https://github.com/LaurentGomila/SFML/issues/271 + // http://www.mega-nerd.com/libsndfile/command.html#SFC_SET_SCALE_FLOAT_INT_READ + ///FIXME: Seulement le Vorbis ? + if (info.format & SF_FORMAT_VORBIS) + sf_command(file, SFC_SET_SCALE_FLOAT_INT_READ, nullptr, SF_TRUE); + + unsigned int sampleCount = static_cast(info.frames * info.channels); + std::unique_ptr samples(new Int16[sampleCount]); + + if (sf_read_short(file, samples.get(), sampleCount) != sampleCount) + { + NazaraError("Failed to read samples"); + return false; + } + + // Une conversion en mono est-elle nécessaire ? + if (parameters.forceMono && format != AudioFormat_Mono) + { + // Nous effectuons la conversion en mono dans le même buffer (il va de toute façon être copié) + MixToMono(samples.get(), samples.get(), static_cast(info.channels), static_cast(info.frames)); + + format = AudioFormat_Mono; + sampleCount = static_cast(info.frames); + } + + if (!soundBuffer->Create(format, sampleCount, info.samplerate, samples.get())) + { + NazaraError("Failed to create sound buffer"); + return false; + } + + return true; + } } - nzTernary CheckMusic(NzInputStream& stream, const NzMusicParams& parameters) + namespace Loaders { - NazaraUnused(parameters); - - SF_INFO info; - info.format = 0; // Format inconnu - - // Si on peut ouvrir le flux, c'est qu'il est dans un format compatible - SNDFILE* file = sf_open_virtual(&callbacks, SFM_READ, &info, &stream); - if (file) + void Register_sndfile() { - sf_close(file); - return nzTernary_True; - } - else - return nzTernary_False; - } - - bool LoadMusicFile(NzMusic* music, const NzString& filePath, const NzMusicParams& parameters) - { - std::unique_ptr musicStream(new sndfileStream); - if (!musicStream->Open(filePath, parameters.forceMono)) - { - NazaraError("Failed to open music stream"); - return false; + MusicLoader::RegisterLoader(Detail::IsSupported, Detail::CheckMusic, Detail::LoadMusicStream, Detail::LoadMusicFile, Detail::LoadMusicMemory); + SoundBufferLoader::RegisterLoader(Detail::IsSupported, Detail::CheckSoundBuffer, Detail::LoadSoundBuffer); } - if (!music->Create(musicStream.get())) // Transfert de propriété + void Unregister_sndfile() { - NazaraError("Failed to create music"); - return false; + MusicLoader::UnregisterLoader(Detail::IsSupported, Detail::CheckMusic, Detail::LoadMusicStream, Detail::LoadMusicFile, Detail::LoadMusicMemory); + SoundBufferLoader::UnregisterLoader(Detail::IsSupported, Detail::CheckSoundBuffer, Detail::LoadSoundBuffer); } - - // Le pointeur a été transféré avec succès, nous pouvons laisser tomber la propriété - musicStream.release(); - - return true; - } - - bool LoadMusicMemory(NzMusic* music, const void* data, std::size_t size, const NzMusicParams& parameters) - { - std::unique_ptr musicStream(new sndfileStream); - if (!musicStream->Open(data, size, parameters.forceMono)) - { - NazaraError("Failed to open music stream"); - return false; - } - - if (!music->Create(musicStream.get())) // Transfert de propriété - { - NazaraError("Failed to create music"); - return false; - } - - // Le pointeur a été transféré avec succès, nous pouvons laisser tomber la propriété - musicStream.release(); - - return true; - } - - bool LoadMusicStream(NzMusic* music, NzInputStream& stream, const NzMusicParams& parameters) - { - std::unique_ptr musicStream(new sndfileStream); - if (!musicStream->Open(stream, parameters.forceMono)) - { - NazaraError("Failed to open music stream"); - return false; - } - - if (!music->Create(musicStream.get())) // Transfert de propriété - { - NazaraError("Failed to create music"); - return false; - } - - // Le pointeur a été transféré avec succès, nous pouvons laisser tomber la propriété - musicStream.release(); - - return true; - } - - nzTernary CheckSoundBuffer(NzInputStream& stream, const NzSoundBufferParams& parameters) - { - NazaraUnused(parameters); - - SF_INFO info; - info.format = 0; - - SNDFILE* file = sf_open_virtual(&callbacks, SFM_READ, &info, &stream); - if (file) - { - sf_close(file); - return nzTernary_True; - } - else - return nzTernary_False; - } - - bool LoadSoundBuffer(NzSoundBuffer* soundBuffer, NzInputStream& stream, const NzSoundBufferParams& parameters) - { - SF_INFO info; - info.format = 0; - - SNDFILE* file = sf_open_virtual(&callbacks, SFM_READ, &info, &stream); - if (!file) - { - NazaraError("Failed to load sound file: " + NzString(sf_strerror(file))); - return false; - } - - // Lynix utilise RAII... - // C'est très efficace ! - // MemoryLeak est confus... - NzCallOnExit onExit([file] - { - sf_close(file); - }); - - nzAudioFormat format = NzAudio::GetAudioFormat(info.channels); - if (format == nzAudioFormat_Unknown) - { - NazaraError("Channel count not handled"); - return false; - } - - // https://github.com/LaurentGomila/SFML/issues/271 - // http://www.mega-nerd.com/libsndfile/command.html#SFC_SET_SCALE_FLOAT_INT_READ - ///FIXME: Seulement le Vorbis ? - if (info.format & SF_FORMAT_VORBIS) - sf_command(file, SFC_SET_SCALE_FLOAT_INT_READ, nullptr, SF_TRUE); - - unsigned int sampleCount = static_cast(info.frames * info.channels); - std::unique_ptr samples(new nzInt16[sampleCount]); - - if (sf_read_short(file, samples.get(), sampleCount) != sampleCount) - { - NazaraError("Failed to read samples"); - return false; - } - - // Une conversion en mono est-elle nécessaire ? - if (parameters.forceMono && format != nzAudioFormat_Mono) - { - // Nous effectuons la conversion en mono dans le même buffer (il va de toute façon être copié) - NzMixToMono(samples.get(), samples.get(), static_cast(info.channels), static_cast(info.frames)); - - format = nzAudioFormat_Mono; - sampleCount = static_cast(info.frames); - } - - if (!soundBuffer->Create(format, sampleCount, info.samplerate, samples.get())) - { - NazaraError("Failed to create sound buffer"); - return false; - } - - return true; } } - -void NzLoaders_sndfile_Register() -{ - NzMusicLoader::RegisterLoader(IsSupported, CheckMusic, LoadMusicStream, LoadMusicFile, LoadMusicMemory); - NzSoundBufferLoader::RegisterLoader(IsSupported, CheckSoundBuffer, LoadSoundBuffer); -} - -void NzLoaders_sndfile_Unregister() -{ - NzMusicLoader::UnregisterLoader(IsSupported, CheckMusic, LoadMusicStream, LoadMusicFile, LoadMusicMemory); - NzSoundBufferLoader::UnregisterLoader(IsSupported, CheckSoundBuffer, LoadSoundBuffer); -} diff --git a/src/Nazara/Audio/Formats/sndfileLoader.hpp b/src/Nazara/Audio/Formats/sndfileLoader.hpp index 5ab600bce..01576d5a3 100644 --- a/src/Nazara/Audio/Formats/sndfileLoader.hpp +++ b/src/Nazara/Audio/Formats/sndfileLoader.hpp @@ -9,7 +9,13 @@ #include -void NzLoaders_sndfile_Register(); -void NzLoaders_sndfile_Unregister(); +namespace Nz +{ + namespace Loaders + { + void Register_sndfile(); + void Unregister_sndfile(); + } +} #endif // NAZARA_LOADERS_SNDFILE_HPP diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index eaddfa74c..a1ab56b61 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -11,328 +11,331 @@ #include #include -bool NzMusicParams::IsValid() const +namespace Nz { - return true; -} - -struct NzMusicImpl -{ - ALenum audioFormat; - std::unique_ptr stream; - std::vector chunkSamples; - NzThread thread; - bool loop = false; - bool streaming = false; - unsigned int sampleRate; -}; - -NzMusic::~NzMusic() -{ - Destroy(); -} - -bool NzMusic::Create(NzSoundStream* soundStream) -{ - Destroy(); - - #if NAZARA_AUDIO_SAFE - if (!soundStream) + bool MusicParams::IsValid() const { - NazaraError("Sound stream must be valid"); - return false; + return true; } - #endif - nzAudioFormat format = soundStream->GetFormat(); - - m_impl = new NzMusicImpl; - m_impl->sampleRate = soundStream->GetSampleRate(); - m_impl->audioFormat = NzOpenAL::AudioFormat[format]; - m_impl->chunkSamples.resize(format * m_impl->sampleRate); // Une seconde de samples - m_impl->stream.reset(soundStream); - - return true; -} - -void NzMusic::Destroy() -{ - if (m_impl) + struct MusicImpl { - Stop(); + ALenum audioFormat; + std::unique_ptr stream; + std::vector chunkSamples; + Thread thread; + bool loop = false; + bool streaming = false; + unsigned int sampleRate; + }; - delete m_impl; - m_impl = nullptr; + Music::~Music() + { + Destroy(); } -} -void NzMusic::EnableLooping(bool loop) -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) + bool Music::Create(SoundStream* soundStream) { - NazaraError("Music not created"); - return; + Destroy(); + + #if NAZARA_AUDIO_SAFE + if (!soundStream) + { + NazaraError("Sound stream must be valid"); + return false; + } + #endif + + AudioFormat format = soundStream->GetFormat(); + + m_impl = new MusicImpl; + m_impl->sampleRate = soundStream->GetSampleRate(); + m_impl->audioFormat = OpenAL::AudioFormat[format]; + m_impl->chunkSamples.resize(format * m_impl->sampleRate); // Une seconde de samples + m_impl->stream.reset(soundStream); + + return true; } - #endif - m_impl->loop = loop; -} - -nzUInt32 NzMusic::GetDuration() const -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) + void Music::Destroy() { - NazaraError("Music not created"); + if (m_impl) + { + Stop(); + + delete m_impl; + m_impl = nullptr; + } + } + + void Music::EnableLooping(bool loop) + { + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return; + } + #endif + + m_impl->loop = loop; + } + + UInt32 Music::GetDuration() const + { + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return 0; + } + #endif + + return m_impl->stream->GetDuration(); + } + + AudioFormat Music::GetFormat() const + { + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return AudioFormat_Unknown; + } + #endif + + return m_impl->stream->GetFormat(); + } + + UInt32 Music::GetPlayingOffset() const + { + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return 0; + } + #endif + + ///TODO return 0; } - #endif - return m_impl->stream->GetDuration(); -} - -nzAudioFormat NzMusic::GetFormat() const -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) + UInt32 Music::GetSampleCount() const { - NazaraError("Music not created"); - return nzAudioFormat_Unknown; + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return 0; + } + #endif + + return m_impl->stream->GetSampleCount(); } - #endif - return m_impl->stream->GetFormat(); -} - -nzUInt32 NzMusic::GetPlayingOffset() const -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) + UInt32 Music::GetSampleRate() const { - NazaraError("Music not created"); - return 0; + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return 0; + } + #endif + + return m_impl->stream->GetSampleRate(); } - #endif - ///TODO - return 0; -} - -nzUInt32 NzMusic::GetSampleCount() const -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) + SoundStatus Music::GetStatus() const { - NazaraError("Music not created"); - return 0; + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return SoundStatus_Stopped; + } + #endif + + SoundStatus status = GetInternalStatus(); + + // Pour compenser les éventuels retards (ou le laps de temps entre Play() et la mise en route du thread) + if (m_impl->streaming && status == SoundStatus_Stopped) + status = SoundStatus_Playing; + + return status; } - #endif - return m_impl->stream->GetSampleCount(); -} - -nzUInt32 NzMusic::GetSampleRate() const -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) + bool Music::IsLooping() const { - NazaraError("Music not created"); - return 0; + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return false; + } + #endif + + return m_impl->loop; } - #endif - return m_impl->stream->GetSampleRate(); -} - -nzSoundStatus NzMusic::GetStatus() const -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) + bool Music::OpenFromFile(const String& filePath, const MusicParams& params) { - NazaraError("Music not created"); - return nzSoundStatus_Stopped; + return MusicLoader::LoadFromFile(this, filePath, params); } - #endif - nzSoundStatus status = GetInternalStatus(); - - // Pour compenser les éventuels retards (ou le laps de temps entre Play() et la mise en route du thread) - if (m_impl->streaming && status == nzSoundStatus_Stopped) - status = nzSoundStatus_Playing; - - return status; -} - -bool NzMusic::IsLooping() const -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) + bool Music::OpenFromMemory(const void* data, std::size_t size, const MusicParams& params) { - NazaraError("Music not created"); - return false; + return MusicLoader::LoadFromMemory(this, data, size, params); } - #endif - return m_impl->loop; -} - -bool NzMusic::OpenFromFile(const NzString& filePath, const NzMusicParams& params) -{ - return NzMusicLoader::LoadFromFile(this, filePath, params); -} - -bool NzMusic::OpenFromMemory(const void* data, std::size_t size, const NzMusicParams& params) -{ - return NzMusicLoader::LoadFromMemory(this, data, size, params); -} - -bool NzMusic::OpenFromStream(NzInputStream& stream, const NzMusicParams& params) -{ - return NzMusicLoader::LoadFromStream(this, stream, params); -} - -void NzMusic::Pause() -{ - alSourcePause(m_source); -} - -void NzMusic::Play() -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) + bool Music::OpenFromStream(InputStream& stream, const MusicParams& params) { - NazaraError("Music not created"); - return; + return MusicLoader::LoadFromStream(this, stream, params); } - #endif - // Nous sommes déjà en train de jouer - if (m_impl->streaming) + void Music::Pause() { - // Peut-être sommes-nous en pause - if (GetStatus() != nzSoundStatus_Playing) - alSourcePlay(m_source); + alSourcePause(m_source); + } + + void Music::Play() + { + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return; + } + #endif + + // Nous sommes déjà en train de jouer + if (m_impl->streaming) + { + // Peut-être sommes-nous en pause + if (GetStatus() != SoundStatus_Playing) + alSourcePlay(m_source); + + return; + } + + // Lancement du thread de streaming + m_impl->stream->Seek(0); + m_impl->streaming = true; + m_impl->thread = Thread(&Music::MusicThread, this); return; } - // Lancement du thread de streaming - m_impl->stream->Seek(0); - m_impl->streaming = true; - m_impl->thread = NzThread(&NzMusic::MusicThread, this); - - return; -} - -void NzMusic::SetPlayingOffset(nzUInt32 offset) -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) + void Music::SetPlayingOffset(UInt32 offset) { - NazaraError("Music not created"); - return; - } - #endif + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return; + } + #endif - ///TODO -} - -void NzMusic::Stop() -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) - { - NazaraError("Music not created"); - return; - } - #endif - - if (m_impl->streaming) - { - m_impl->streaming = false; - m_impl->thread.Join(); - } -} - -bool NzMusic::FillAndQueueBuffer(unsigned int buffer) -{ - unsigned int sampleCount = m_impl->chunkSamples.size(); - unsigned int sampleRead = 0; - - // Lecture depuis le stream pour remplir le buffer - for (;;) - { - sampleRead += m_impl->stream->Read(&m_impl->chunkSamples[sampleRead], sampleCount - sampleRead); - if (sampleRead < sampleCount && !m_impl->loop) - break; // Fin du stream (On ne boucle pas) - - m_impl->stream->Seek(0); // On boucle au début du stream et on remplit à nouveau + ///TODO } - // Mise à jour du buffer (envoi à OpenAL) et placement dans la file d'attente - if (sampleRead > 0) + void Music::Stop() { - alBufferData(buffer, m_impl->audioFormat, &m_impl->chunkSamples[0], sampleRead*sizeof(nzInt16), m_impl->sampleRate); - alSourceQueueBuffers(m_source, 1, &buffer); - } + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Music not created"); + return; + } + #endif - return sampleRead != sampleCount; // Fin du stream (N'arrive pas en cas de loop) -} - -void NzMusic::MusicThread() -{ - // Allocation des buffers de streaming - ALuint buffers[NAZARA_AUDIO_STREAMED_BUFFER_COUNT]; - alGenBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers); - - for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMED_BUFFER_COUNT; ++i) - { - if (FillAndQueueBuffer(buffers[i])) - break; // Nous avons atteint la fin du stream, inutile de rajouter des buffers - } - - alSourcePlay(m_source); - - // Boucle de lecture (remplissage de nouveaux buffers au fur et à mesure) - while (m_impl->streaming) - { - // La lecture s'est arrêtée, nous avons atteint la fin du stream - nzSoundStatus status = GetInternalStatus(); - if (status == nzSoundStatus_Stopped) + if (m_impl->streaming) { m_impl->streaming = false; - break; + m_impl->thread.Join(); } - - // On traite les buffers lus - ALint processedCount = 0; - alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount); - - ALuint buffer; - while (processedCount--) - { - alSourceUnqueueBuffers(m_source, 1, &buffer); - if (FillAndQueueBuffer(buffer)) - break; - } - - // On retourne dormir un peu - NzThread::Sleep(50); } - // Arrêt de la lecture du son (dans le cas où ça ne serait pas déjà fait) - alSourceStop(m_source); + bool Music::FillAndQueueBuffer(unsigned int buffer) + { + unsigned int sampleCount = m_impl->chunkSamples.size(); + unsigned int sampleRead = 0; - // On supprime les buffers du stream - ALint queuedBufferCount; - alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queuedBufferCount); + // Lecture depuis le stream pour remplir le buffer + for (;;) + { + sampleRead += m_impl->stream->Read(&m_impl->chunkSamples[sampleRead], sampleCount - sampleRead); + if (sampleRead < sampleCount && !m_impl->loop) + break; // Fin du stream (On ne boucle pas) - ALuint buffer; - for (ALint i = 0; i < queuedBufferCount; ++i) - alSourceUnqueueBuffers(m_source, 1, &buffer); + m_impl->stream->Seek(0); // On boucle au début du stream et on remplit à nouveau + } - alDeleteBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers); + // Mise à jour du buffer (envoi à OpenAL) et placement dans la file d'attente + if (sampleRead > 0) + { + alBufferData(buffer, m_impl->audioFormat, &m_impl->chunkSamples[0], sampleRead*sizeof(Int16), m_impl->sampleRate); + alSourceQueueBuffers(m_source, 1, &buffer); + } + + return sampleRead != sampleCount; // Fin du stream (N'arrive pas en cas de loop) + } + + void Music::MusicThread() + { + // Allocation des buffers de streaming + ALuint buffers[NAZARA_AUDIO_STREAMED_BUFFER_COUNT]; + alGenBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers); + + for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMED_BUFFER_COUNT; ++i) + { + if (FillAndQueueBuffer(buffers[i])) + break; // Nous avons atteint la fin du stream, inutile de rajouter des buffers + } + + alSourcePlay(m_source); + + // Boucle de lecture (remplissage de nouveaux buffers au fur et à mesure) + while (m_impl->streaming) + { + // La lecture s'est arrêtée, nous avons atteint la fin du stream + SoundStatus status = GetInternalStatus(); + if (status == SoundStatus_Stopped) + { + m_impl->streaming = false; + break; + } + + // On traite les buffers lus + ALint processedCount = 0; + alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount); + + ALuint buffer; + while (processedCount--) + { + alSourceUnqueueBuffers(m_source, 1, &buffer); + if (FillAndQueueBuffer(buffer)) + break; + } + + // On retourne dormir un peu + Thread::Sleep(50); + } + + // Arrêt de la lecture du son (dans le cas où ça ne serait pas déjà fait) + alSourceStop(m_source); + + // On supprime les buffers du stream + ALint queuedBufferCount; + alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queuedBufferCount); + + ALuint buffer; + for (ALint i = 0; i < queuedBufferCount; ++i) + alSourceUnqueueBuffers(m_source, 1, &buffer); + + alDeleteBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers); + } + + MusicLoader::LoaderList Music::s_loaders; } - -NzMusicLoader::LoaderList NzMusic::s_loaders; diff --git a/src/Nazara/Audio/OpenAL.cpp b/src/Nazara/Audio/OpenAL.cpp index 138f536bd..72a56f7a7 100644 --- a/src/Nazara/Audio/OpenAL.cpp +++ b/src/Nazara/Audio/OpenAL.cpp @@ -11,459 +11,462 @@ #include #include -namespace +namespace Nz { - NzDynLib s_library; - NzString s_deviceName; - NzString s_rendererName; - NzString s_vendorName; - ALCdevice* s_device = nullptr; - ALCcontext* s_context = nullptr; - unsigned int s_version; - - unsigned int ParseDevices(const char* deviceString, std::vector& devices) + namespace { + DynLib s_library; + String s_deviceName; + String s_rendererName; + String s_vendorName; + ALCdevice* s_device = nullptr; + ALCcontext* s_context = nullptr; + unsigned int s_version; + + unsigned int ParseDevices(const char* deviceString, std::vector& devices) + { + if (!deviceString) + return 0; + + unsigned int startSize = devices.size(); + + unsigned int length; + while ((length = std::strlen(deviceString)) > 0) + { + devices.push_back(String(deviceString, length)); + deviceString += length + 1; + } + + return devices.size() - startSize; + } + } + + OpenALFunc OpenAL::GetEntry(const String& entryPoint) + { + return LoadEntry(entryPoint.GetConstBuffer(), false); + } + + String OpenAL::GetRendererName() + { + return s_rendererName; + } + + String OpenAL::GetVendorName() + { + return s_vendorName; + } + + unsigned int OpenAL::GetVersion() + { + return s_version; + } + + bool OpenAL::Initialize(bool openDevice) + { + if (s_library.IsLoaded()) + return true; + + #if defined(NAZARA_PLATFORM_WINDOWS) + ///FIXME: Est-ce qu'OpenAL Soft est une meilleure implémentation que Creative ? + /// Si on pouvait se résigner à utiliser OpenAL Soft tout le temps, cela nous permettrait d'utiliser les extensions sonores + /// et de donner plus de possibilités techniques au niveau de l'audio. + const char* libs[] = { + "soft_oal.dll", + "wrap_oal.dll", + "openal32.dll" + }; + #elif defined(NAZARA_PLATFORM_LINUX) + const char* libs[] = { + "libopenal.so.1", + "libopenal.so.0", + "libopenal.so" + }; + //#elif defined(NAZARA_PLATFORM_MACOSX) + #else + NazaraError("Unknown OS"); + return false; + #endif + + bool succeeded = false; + for (const char* path : libs) + { + String libPath(path); + if (!s_library.Load(libPath)) + continue; + + try + { + // al + alBuffer3f = reinterpret_cast(LoadEntry("alBuffer3f")); + alBuffer3i = reinterpret_cast(LoadEntry("alBuffer3i")); + alBufferData = reinterpret_cast(LoadEntry("alBufferData")); + alBufferf = reinterpret_cast(LoadEntry("alBufferf")); + alBufferfv = reinterpret_cast(LoadEntry("alBufferfv")); + alBufferi = reinterpret_cast(LoadEntry("alBufferi")); + alBufferiv = reinterpret_cast(LoadEntry("alBufferiv")); + alDeleteBuffers = reinterpret_cast(LoadEntry("alDeleteBuffers")); + alDeleteSources = reinterpret_cast(LoadEntry("alDeleteSources")); + alDisable = reinterpret_cast(LoadEntry("alDisable")); + alDistanceModel = reinterpret_cast(LoadEntry("alDistanceModel")); + alDopplerFactor = reinterpret_cast(LoadEntry("alDopplerFactor")); + alDopplerVelocity = reinterpret_cast(LoadEntry("alDopplerVelocity")); + alEnable = reinterpret_cast(LoadEntry("alEnable")); + alGenBuffers = reinterpret_cast(LoadEntry("alGenBuffers")); + alGenSources = reinterpret_cast(LoadEntry("alGenSources")); + alGetBoolean = reinterpret_cast(LoadEntry("alGetBoolean")); + alGetBooleanv = reinterpret_cast(LoadEntry("alGetBooleanv")); + alGetBuffer3f = reinterpret_cast(LoadEntry("alGetBuffer3f")); + alGetBuffer3i = reinterpret_cast(LoadEntry("alGetBuffer3i")); + alGetBufferf = reinterpret_cast(LoadEntry("alGetBufferf")); + alGetBufferfv = reinterpret_cast(LoadEntry("alGetBufferfv")); + alGetBufferi = reinterpret_cast(LoadEntry("alGetBufferi")); + alGetBufferiv = reinterpret_cast(LoadEntry("alGetBufferiv")); + alGetDouble = reinterpret_cast(LoadEntry("alGetDouble")); + alGetDoublev = reinterpret_cast(LoadEntry("alGetDoublev")); + alGetEnumValue = reinterpret_cast(LoadEntry("alGetEnumValue")); + alGetError = reinterpret_cast(LoadEntry("alGetError")); + alGetFloat = reinterpret_cast(LoadEntry("alGetFloat")); + alGetFloatv = reinterpret_cast(LoadEntry("alGetFloatv")); + alGetInteger = reinterpret_cast(LoadEntry("alGetInteger")); + alGetIntegerv = reinterpret_cast(LoadEntry("alGetIntegerv")); + alGetListener3f = reinterpret_cast(LoadEntry("alGetListener3f")); + alGetListener3i = reinterpret_cast(LoadEntry("alGetListener3i")); + alGetListenerf = reinterpret_cast(LoadEntry("alGetListenerf")); + alGetListenerfv = reinterpret_cast(LoadEntry("alGetListenerfv")); + alGetListeneri = reinterpret_cast(LoadEntry("alGetListeneri")); + alGetListeneriv = reinterpret_cast(LoadEntry("alGetListeneriv")); + alGetProcAddress = reinterpret_cast(LoadEntry("alGetProcAddress")); + alGetSource3f = reinterpret_cast(LoadEntry("alGetSource3f")); + alGetSource3i = reinterpret_cast(LoadEntry("alGetSource3i")); + alGetSourcef = reinterpret_cast(LoadEntry("alGetSourcef")); + alGetSourcefv = reinterpret_cast(LoadEntry("alGetSourcefv")); + alGetSourcei = reinterpret_cast(LoadEntry("alGetSourcei")); + alGetSourceiv = reinterpret_cast(LoadEntry("alGetSourceiv")); + alGetString = reinterpret_cast(LoadEntry("alGetString")); + alIsBuffer = reinterpret_cast(LoadEntry("alIsBuffer")); + alIsEnabled = reinterpret_cast(LoadEntry("alIsEnabled")); + alIsExtensionPresent = reinterpret_cast(LoadEntry("alIsExtensionPresent")); + alIsSource = reinterpret_cast(LoadEntry("alIsSource")); + alListener3f = reinterpret_cast(LoadEntry("alListener3f")); + alListener3i = reinterpret_cast(LoadEntry("alListener3i")); + alListenerf = reinterpret_cast(LoadEntry("alListenerf")); + alListenerfv = reinterpret_cast(LoadEntry("alListenerfv")); + alListeneri = reinterpret_cast(LoadEntry("alListeneri")); + alListeneriv = reinterpret_cast(LoadEntry("alListeneriv")); + alSource3f = reinterpret_cast(LoadEntry("alSource3f")); + alSource3i = reinterpret_cast(LoadEntry("alSource3i")); + alSourcef = reinterpret_cast(LoadEntry("alSourcef")); + alSourcefv = reinterpret_cast(LoadEntry("alSourcefv")); + alSourcei = reinterpret_cast(LoadEntry("alSourcei")); + alSourceiv = reinterpret_cast(LoadEntry("alSourceiv")); + alSourcePause = reinterpret_cast(LoadEntry("alSourcePause")); + alSourcePausev = reinterpret_cast(LoadEntry("alSourcePausev")); + alSourcePlay = reinterpret_cast(LoadEntry("alSourcePlay")); + alSourcePlayv = reinterpret_cast(LoadEntry("alSourcePlayv")); + alSourceQueueBuffers = reinterpret_cast(LoadEntry("alSourceQueueBuffers")); + alSourceRewind = reinterpret_cast(LoadEntry("alSourceRewind")); + alSourceRewindv = reinterpret_cast(LoadEntry("alSourceRewindv")); + alSourceStop = reinterpret_cast(LoadEntry("alSourceStop")); + alSourceStopv = reinterpret_cast(LoadEntry("alSourceStopv")); + alSourceUnqueueBuffers = reinterpret_cast(LoadEntry("alSourceUnqueueBuffers")); + alSpeedOfSound = reinterpret_cast(LoadEntry("alSpeedOfSound")); + + // alc + alcCaptureCloseDevice = reinterpret_cast(LoadEntry("alcCaptureCloseDevice")); + alcCaptureOpenDevice = reinterpret_cast(LoadEntry("alcCaptureOpenDevice")); + alcCaptureSamples = reinterpret_cast(LoadEntry("alcCaptureSamples")); + alcCaptureStart = reinterpret_cast(LoadEntry("alcCaptureStart")); + alcCaptureStop = reinterpret_cast(LoadEntry("alcCaptureStop")); + alcCloseDevice = reinterpret_cast(LoadEntry("alcCloseDevice")); + alcCreateContext = reinterpret_cast(LoadEntry("alcCreateContext")); + alcDestroyContext = reinterpret_cast(LoadEntry("alcDestroyContext")); + alcGetContextsDevice = reinterpret_cast(LoadEntry("alcGetContextsDevice")); + alcGetCurrentContext = reinterpret_cast(LoadEntry("alcGetCurrentContext")); + alcGetEnumValue = reinterpret_cast(LoadEntry("alcGetEnumValue")); + alcGetError = reinterpret_cast(LoadEntry("alcGetError")); + alcGetIntegerv = reinterpret_cast(LoadEntry("alcGetIntegerv")); + alcGetProcAddress = reinterpret_cast(LoadEntry("alcGetProcAddress")); + alcGetString = reinterpret_cast(LoadEntry("alcGetString")); + alcIsExtensionPresent = reinterpret_cast(LoadEntry("alcIsExtensionPresent")); + alcMakeContextCurrent = reinterpret_cast(LoadEntry("alcMakeContextCurrent")); + alcOpenDevice = reinterpret_cast(LoadEntry("alcOpenDevice")); + alcProcessContext = reinterpret_cast(LoadEntry("alcProcessContext")); + alcSuspendContext = reinterpret_cast(LoadEntry("alcSuspendContext")); + + succeeded = true; + break; + } + catch (const std::exception& e) + { + NazaraWarning(libPath + " loading failed: " + String(e.what())); + continue; + } + } + + if (!succeeded) + { + NazaraError("Failed to load OpenAL"); + Uninitialize(); + + return false; + } + + if (openDevice) + OpenDevice(); + + return true; + } + + bool OpenAL::IsInitialized() + { + return s_library.IsLoaded(); + } + + unsigned int OpenAL::QueryInputDevices(std::vector& devices) + { + const char* deviceString = reinterpret_cast(alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER)); if (!deviceString) return 0; - unsigned int startSize = devices.size(); - - unsigned int length; - while ((length = std::strlen(deviceString)) > 0) - { - devices.push_back(NzString(deviceString, length)); - deviceString += length + 1; - } - - return devices.size() - startSize; + return ParseDevices(deviceString, devices); } -} -NzOpenALFunc NzOpenAL::GetEntry(const NzString& entryPoint) -{ - return LoadEntry(entryPoint.GetConstBuffer(), false); -} - -NzString NzOpenAL::GetRendererName() -{ - return s_rendererName; -} - -NzString NzOpenAL::GetVendorName() -{ - return s_vendorName; -} - -unsigned int NzOpenAL::GetVersion() -{ - return s_version; -} - -bool NzOpenAL::Initialize(bool openDevice) -{ - if (s_library.IsLoaded()) - return true; - - #if defined(NAZARA_PLATFORM_WINDOWS) - ///FIXME: Est-ce qu'OpenAL Soft est une meilleure implémentation que Creative ? - /// Si on pouvait se résigner à utiliser OpenAL Soft tout le temps, cela nous permettrait d'utiliser les extensions sonores - /// et de donner plus de possibilités techniques au niveau de l'audio. - const char* libs[] = { - "soft_oal.dll", - "wrap_oal.dll", - "openal32.dll" - }; - #elif defined(NAZARA_PLATFORM_LINUX) - const char* libs[] = { - "libopenal.so.1", - "libopenal.so.0", - "libopenal.so" - }; - //#elif defined(NAZARA_PLATFORM_MACOSX) - #else - NazaraError("Unknown OS"); - return false; - #endif - - bool succeeded = false; - for (const char* path : libs) + unsigned int OpenAL::QueryOutputDevices(std::vector& devices) { - NzString libPath(path); - if (!s_library.Load(libPath)) - continue; + const char* deviceString = reinterpret_cast(alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER)); + if (!deviceString) + return 0; - try - { - // al - alBuffer3f = reinterpret_cast(LoadEntry("alBuffer3f")); - alBuffer3i = reinterpret_cast(LoadEntry("alBuffer3i")); - alBufferData = reinterpret_cast(LoadEntry("alBufferData")); - alBufferf = reinterpret_cast(LoadEntry("alBufferf")); - alBufferfv = reinterpret_cast(LoadEntry("alBufferfv")); - alBufferi = reinterpret_cast(LoadEntry("alBufferi")); - alBufferiv = reinterpret_cast(LoadEntry("alBufferiv")); - alDeleteBuffers = reinterpret_cast(LoadEntry("alDeleteBuffers")); - alDeleteSources = reinterpret_cast(LoadEntry("alDeleteSources")); - alDisable = reinterpret_cast(LoadEntry("alDisable")); - alDistanceModel = reinterpret_cast(LoadEntry("alDistanceModel")); - alDopplerFactor = reinterpret_cast(LoadEntry("alDopplerFactor")); - alDopplerVelocity = reinterpret_cast(LoadEntry("alDopplerVelocity")); - alEnable = reinterpret_cast(LoadEntry("alEnable")); - alGenBuffers = reinterpret_cast(LoadEntry("alGenBuffers")); - alGenSources = reinterpret_cast(LoadEntry("alGenSources")); - alGetBoolean = reinterpret_cast(LoadEntry("alGetBoolean")); - alGetBooleanv = reinterpret_cast(LoadEntry("alGetBooleanv")); - alGetBuffer3f = reinterpret_cast(LoadEntry("alGetBuffer3f")); - alGetBuffer3i = reinterpret_cast(LoadEntry("alGetBuffer3i")); - alGetBufferf = reinterpret_cast(LoadEntry("alGetBufferf")); - alGetBufferfv = reinterpret_cast(LoadEntry("alGetBufferfv")); - alGetBufferi = reinterpret_cast(LoadEntry("alGetBufferi")); - alGetBufferiv = reinterpret_cast(LoadEntry("alGetBufferiv")); - alGetDouble = reinterpret_cast(LoadEntry("alGetDouble")); - alGetDoublev = reinterpret_cast(LoadEntry("alGetDoublev")); - alGetEnumValue = reinterpret_cast(LoadEntry("alGetEnumValue")); - alGetError = reinterpret_cast(LoadEntry("alGetError")); - alGetFloat = reinterpret_cast(LoadEntry("alGetFloat")); - alGetFloatv = reinterpret_cast(LoadEntry("alGetFloatv")); - alGetInteger = reinterpret_cast(LoadEntry("alGetInteger")); - alGetIntegerv = reinterpret_cast(LoadEntry("alGetIntegerv")); - alGetListener3f = reinterpret_cast(LoadEntry("alGetListener3f")); - alGetListener3i = reinterpret_cast(LoadEntry("alGetListener3i")); - alGetListenerf = reinterpret_cast(LoadEntry("alGetListenerf")); - alGetListenerfv = reinterpret_cast(LoadEntry("alGetListenerfv")); - alGetListeneri = reinterpret_cast(LoadEntry("alGetListeneri")); - alGetListeneriv = reinterpret_cast(LoadEntry("alGetListeneriv")); - alGetProcAddress = reinterpret_cast(LoadEntry("alGetProcAddress")); - alGetSource3f = reinterpret_cast(LoadEntry("alGetSource3f")); - alGetSource3i = reinterpret_cast(LoadEntry("alGetSource3i")); - alGetSourcef = reinterpret_cast(LoadEntry("alGetSourcef")); - alGetSourcefv = reinterpret_cast(LoadEntry("alGetSourcefv")); - alGetSourcei = reinterpret_cast(LoadEntry("alGetSourcei")); - alGetSourceiv = reinterpret_cast(LoadEntry("alGetSourceiv")); - alGetString = reinterpret_cast(LoadEntry("alGetString")); - alIsBuffer = reinterpret_cast(LoadEntry("alIsBuffer")); - alIsEnabled = reinterpret_cast(LoadEntry("alIsEnabled")); - alIsExtensionPresent = reinterpret_cast(LoadEntry("alIsExtensionPresent")); - alIsSource = reinterpret_cast(LoadEntry("alIsSource")); - alListener3f = reinterpret_cast(LoadEntry("alListener3f")); - alListener3i = reinterpret_cast(LoadEntry("alListener3i")); - alListenerf = reinterpret_cast(LoadEntry("alListenerf")); - alListenerfv = reinterpret_cast(LoadEntry("alListenerfv")); - alListeneri = reinterpret_cast(LoadEntry("alListeneri")); - alListeneriv = reinterpret_cast(LoadEntry("alListeneriv")); - alSource3f = reinterpret_cast(LoadEntry("alSource3f")); - alSource3i = reinterpret_cast(LoadEntry("alSource3i")); - alSourcef = reinterpret_cast(LoadEntry("alSourcef")); - alSourcefv = reinterpret_cast(LoadEntry("alSourcefv")); - alSourcei = reinterpret_cast(LoadEntry("alSourcei")); - alSourceiv = reinterpret_cast(LoadEntry("alSourceiv")); - alSourcePause = reinterpret_cast(LoadEntry("alSourcePause")); - alSourcePausev = reinterpret_cast(LoadEntry("alSourcePausev")); - alSourcePlay = reinterpret_cast(LoadEntry("alSourcePlay")); - alSourcePlayv = reinterpret_cast(LoadEntry("alSourcePlayv")); - alSourceQueueBuffers = reinterpret_cast(LoadEntry("alSourceQueueBuffers")); - alSourceRewind = reinterpret_cast(LoadEntry("alSourceRewind")); - alSourceRewindv = reinterpret_cast(LoadEntry("alSourceRewindv")); - alSourceStop = reinterpret_cast(LoadEntry("alSourceStop")); - alSourceStopv = reinterpret_cast(LoadEntry("alSourceStopv")); - alSourceUnqueueBuffers = reinterpret_cast(LoadEntry("alSourceUnqueueBuffers")); - alSpeedOfSound = reinterpret_cast(LoadEntry("alSpeedOfSound")); - - // alc - alcCaptureCloseDevice = reinterpret_cast(LoadEntry("alcCaptureCloseDevice")); - alcCaptureOpenDevice = reinterpret_cast(LoadEntry("alcCaptureOpenDevice")); - alcCaptureSamples = reinterpret_cast(LoadEntry("alcCaptureSamples")); - alcCaptureStart = reinterpret_cast(LoadEntry("alcCaptureStart")); - alcCaptureStop = reinterpret_cast(LoadEntry("alcCaptureStop")); - alcCloseDevice = reinterpret_cast(LoadEntry("alcCloseDevice")); - alcCreateContext = reinterpret_cast(LoadEntry("alcCreateContext")); - alcDestroyContext = reinterpret_cast(LoadEntry("alcDestroyContext")); - alcGetContextsDevice = reinterpret_cast(LoadEntry("alcGetContextsDevice")); - alcGetCurrentContext = reinterpret_cast(LoadEntry("alcGetCurrentContext")); - alcGetEnumValue = reinterpret_cast(LoadEntry("alcGetEnumValue")); - alcGetError = reinterpret_cast(LoadEntry("alcGetError")); - alcGetIntegerv = reinterpret_cast(LoadEntry("alcGetIntegerv")); - alcGetProcAddress = reinterpret_cast(LoadEntry("alcGetProcAddress")); - alcGetString = reinterpret_cast(LoadEntry("alcGetString")); - alcIsExtensionPresent = reinterpret_cast(LoadEntry("alcIsExtensionPresent")); - alcMakeContextCurrent = reinterpret_cast(LoadEntry("alcMakeContextCurrent")); - alcOpenDevice = reinterpret_cast(LoadEntry("alcOpenDevice")); - alcProcessContext = reinterpret_cast(LoadEntry("alcProcessContext")); - alcSuspendContext = reinterpret_cast(LoadEntry("alcSuspendContext")); - - succeeded = true; - break; - } - catch (const std::exception& e) - { - NazaraWarning(libPath + " loading failed: " + NzString(e.what())); - continue; - } + return ParseDevices(deviceString, devices); } - if (!succeeded) + bool OpenAL::SetDevice(const String& deviceName) { - NazaraError("Failed to load OpenAL"); - Uninitialize(); + s_deviceName = deviceName; + if (IsInitialized()) + { + CloseDevice(); - return false; + return OpenDevice(); + } + else + return true; } - if (openDevice) - OpenDevice(); - - return true; -} - -bool NzOpenAL::IsInitialized() -{ - return s_library.IsLoaded(); -} - -unsigned int NzOpenAL::QueryInputDevices(std::vector& devices) -{ - const char* deviceString = reinterpret_cast(alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER)); - if (!deviceString) - return 0; - - return ParseDevices(deviceString, devices); -} - -unsigned int NzOpenAL::QueryOutputDevices(std::vector& devices) -{ - const char* deviceString = reinterpret_cast(alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER)); - if (!deviceString) - return 0; - - return ParseDevices(deviceString, devices); -} - -bool NzOpenAL::SetDevice(const NzString& deviceName) -{ - s_deviceName = deviceName; - if (IsInitialized()) + void OpenAL::Uninitialize() { CloseDevice(); - return OpenDevice(); + s_rendererName.Clear(false); + s_vendorName.Clear(false); + s_library.Unload(); } - else - return true; -} -void NzOpenAL::Uninitialize() -{ - CloseDevice(); + ///ATTENTION: La valeur entière est le nombre de canaux possédés par ce format + ALenum OpenAL::AudioFormat[AudioFormat_Max+1] = {0}; // Valeur ajoutées au chargement d'OpenAL - s_rendererName.Clear(false); - s_vendorName.Clear(false); - s_library.Unload(); -} - -///ATTENTION: La valeur entière est le nombre de canaux possédés par ce format -ALenum NzOpenAL::AudioFormat[nzAudioFormat_Max+1] = {0}; // Valeur ajoutées au chargement d'OpenAL - -void NzOpenAL::CloseDevice() -{ - if (s_device) + void OpenAL::CloseDevice() { - if (s_context) + if (s_device) { - alcMakeContextCurrent(nullptr); - alcDestroyContext(s_context); - s_context = nullptr; - } - - if (!alcCloseDevice(s_device)) - // Nous n'avons pas pu fermer le device, ce qui signifie qu'il est en cours d'utilisation - NazaraWarning("Failed to close device"); - - s_device = nullptr; - } -} - -bool NzOpenAL::OpenDevice() -{ - // Initialisation du module - s_device = alcOpenDevice(s_deviceName.IsEmpty() ? nullptr : s_deviceName.GetConstBuffer()); // On choisit le device par défaut - if (!s_device) - { - NazaraError("Failed to open default device"); - return false; - } - - // Un seul contexte nous suffira - s_context = alcCreateContext(s_device, nullptr); - if (!s_context) - { - NazaraError("Failed to create context"); - return false; - } - - if (!alcMakeContextCurrent(s_context)) - { - NazaraError("Failed to activate context"); - return false; - } - - s_rendererName = reinterpret_cast(alGetString(AL_RENDERER)); - s_vendorName = reinterpret_cast(alGetString(AL_VENDOR)); - - const ALchar* version = alGetString(AL_VERSION); - if (version) - { - unsigned int major = version[0] - '0'; - unsigned int minor = version[2] - '0'; - - if (major != 0 && major <= 9) - { - if (minor > 9) + if (s_context) { - NazaraWarning("Unable to retrieve OpenAL minor version (using 0)"); - minor = 0; + alcMakeContextCurrent(nullptr); + alcDestroyContext(s_context); + s_context = nullptr; } - s_version = major*100 + minor*10; + if (!alcCloseDevice(s_device)) + // Nous n'avons pas pu fermer le device, ce qui signifie qu'il est en cours d'utilisation + NazaraWarning("Failed to close device"); - NazaraDebug("OpenAL version: " + NzString::Number(major) + '.' + NzString::Number(minor)); + s_device = nullptr; + } + } + + bool OpenAL::OpenDevice() + { + // Initialisation du module + s_device = alcOpenDevice(s_deviceName.IsEmpty() ? nullptr : s_deviceName.GetConstBuffer()); // On choisit le device par défaut + if (!s_device) + { + NazaraError("Failed to open default device"); + return false; + } + + // Un seul contexte nous suffira + s_context = alcCreateContext(s_device, nullptr); + if (!s_context) + { + NazaraError("Failed to create context"); + return false; + } + + if (!alcMakeContextCurrent(s_context)) + { + NazaraError("Failed to activate context"); + return false; + } + + s_rendererName = reinterpret_cast(alGetString(AL_RENDERER)); + s_vendorName = reinterpret_cast(alGetString(AL_VENDOR)); + + const ALchar* version = alGetString(AL_VERSION); + if (version) + { + unsigned int major = version[0] - '0'; + unsigned int minor = version[2] - '0'; + + if (major != 0 && major <= 9) + { + if (minor > 9) + { + NazaraWarning("Unable to retrieve OpenAL minor version (using 0)"); + minor = 0; + } + + s_version = major*100 + minor*10; + + NazaraDebug("OpenAL version: " + String::Number(major) + '.' + String::Number(minor)); + } + else + { + NazaraDebug("Unable to retrieve OpenAL major version"); + s_version = 0; + } } else { - NazaraDebug("Unable to retrieve OpenAL major version"); + NazaraDebug("Unable to retrieve OpenAL version"); s_version = 0; } + + // On complète le tableau de formats + AudioFormat[AudioFormat_Mono] = AL_FORMAT_MONO16; + AudioFormat[AudioFormat_Stereo] = AL_FORMAT_STEREO16; + + // "The presence of an enum value does not guarantee the applicability of an extension to the current context." + if (alIsExtensionPresent("AL_EXT_MCFORMATS")) + { + AudioFormat[AudioFormat_Quad] = alGetEnumValue("AL_FORMAT_QUAD16"); + AudioFormat[AudioFormat_5_1] = alGetEnumValue("AL_FORMAT_51CHN16"); + AudioFormat[AudioFormat_6_1] = alGetEnumValue("AL_FORMAT_61CHN16"); + AudioFormat[AudioFormat_7_1] = alGetEnumValue("AL_FORMAT_71CHN16"); + } + else if (alIsExtensionPresent("AL_LOKI_quadriphonic")) + AudioFormat[AudioFormat_Quad] = alGetEnumValue("AL_FORMAT_QUAD16_LOKI"); + + return true; } - else + + OpenALFunc OpenAL::LoadEntry(const char* name, bool throwException) { - NazaraDebug("Unable to retrieve OpenAL version"); - s_version = 0; + OpenALFunc entry = reinterpret_cast(s_library.GetSymbol(name)); + if (!entry && throwException) + { + std::ostringstream oss; + oss << "failed to load \"" << name << '"'; + + throw std::runtime_error(oss.str()); + } + + return entry; } - - // On complète le tableau de formats - AudioFormat[nzAudioFormat_Mono] = AL_FORMAT_MONO16; - AudioFormat[nzAudioFormat_Stereo] = AL_FORMAT_STEREO16; - - // "The presence of an enum value does not guarantee the applicability of an extension to the current context." - if (alIsExtensionPresent("AL_EXT_MCFORMATS")) - { - AudioFormat[nzAudioFormat_Quad] = alGetEnumValue("AL_FORMAT_QUAD16"); - AudioFormat[nzAudioFormat_5_1] = alGetEnumValue("AL_FORMAT_51CHN16"); - AudioFormat[nzAudioFormat_6_1] = alGetEnumValue("AL_FORMAT_61CHN16"); - AudioFormat[nzAudioFormat_7_1] = alGetEnumValue("AL_FORMAT_71CHN16"); - } - else if (alIsExtensionPresent("AL_LOKI_quadriphonic")) - AudioFormat[nzAudioFormat_Quad] = alGetEnumValue("AL_FORMAT_QUAD16_LOKI"); - - return true; -} - -NzOpenALFunc NzOpenAL::LoadEntry(const char* name, bool throwException) -{ - NzOpenALFunc entry = reinterpret_cast(s_library.GetSymbol(name)); - if (!entry && throwException) - { - std::ostringstream oss; - oss << "failed to load \"" << name << '"'; - - throw std::runtime_error(oss.str()); - } - - return entry; } // al -NzOpenALDetail::LPALBUFFER3F alBuffer3f = nullptr; -NzOpenALDetail::LPALBUFFER3I alBuffer3i = nullptr; -NzOpenALDetail::LPALBUFFERDATA alBufferData = nullptr; -NzOpenALDetail::LPALBUFFERF alBufferf = nullptr; -NzOpenALDetail::LPALBUFFERFV alBufferfv = nullptr; -NzOpenALDetail::LPALBUFFERI alBufferi = nullptr; -NzOpenALDetail::LPALBUFFERIV alBufferiv = nullptr; -NzOpenALDetail::LPALDELETEBUFFERS alDeleteBuffers = nullptr; -NzOpenALDetail::LPALDELETESOURCES alDeleteSources = nullptr; -NzOpenALDetail::LPALDISABLE alDisable = nullptr; -NzOpenALDetail::LPALDISTANCEMODEL alDistanceModel = nullptr; -NzOpenALDetail::LPALDOPPLERFACTOR alDopplerFactor = nullptr; -NzOpenALDetail::LPALDOPPLERVELOCITY alDopplerVelocity = nullptr; -NzOpenALDetail::LPALENABLE alEnable = nullptr; -NzOpenALDetail::LPALGENBUFFERS alGenBuffers = nullptr; -NzOpenALDetail::LPALGENSOURCES alGenSources = nullptr; -NzOpenALDetail::LPALGETBOOLEAN alGetBoolean = nullptr; -NzOpenALDetail::LPALGETBOOLEANV alGetBooleanv = nullptr; -NzOpenALDetail::LPALGETBUFFER3F alGetBuffer3f = nullptr; -NzOpenALDetail::LPALGETBUFFER3I alGetBuffer3i = nullptr; -NzOpenALDetail::LPALGETBUFFERF alGetBufferf = nullptr; -NzOpenALDetail::LPALGETBUFFERFV alGetBufferfv = nullptr; -NzOpenALDetail::LPALGETBUFFERI alGetBufferi = nullptr; -NzOpenALDetail::LPALGETBUFFERIV alGetBufferiv = nullptr; -NzOpenALDetail::LPALGETDOUBLE alGetDouble = nullptr; -NzOpenALDetail::LPALGETDOUBLEV alGetDoublev = nullptr; -NzOpenALDetail::LPALGETENUMVALUE alGetEnumValue = nullptr; -NzOpenALDetail::LPALGETERROR alGetError = nullptr; -NzOpenALDetail::LPALGETFLOAT alGetFloat = nullptr; -NzOpenALDetail::LPALGETFLOATV alGetFloatv = nullptr; -NzOpenALDetail::LPALGETINTEGER alGetInteger = nullptr; -NzOpenALDetail::LPALGETINTEGERV alGetIntegerv = nullptr; -NzOpenALDetail::LPALGETLISTENER3F alGetListener3f = nullptr; -NzOpenALDetail::LPALGETLISTENER3I alGetListener3i = nullptr; -NzOpenALDetail::LPALGETLISTENERF alGetListenerf = nullptr; -NzOpenALDetail::LPALGETLISTENERFV alGetListenerfv = nullptr; -NzOpenALDetail::LPALGETLISTENERI alGetListeneri = nullptr; -NzOpenALDetail::LPALGETLISTENERIV alGetListeneriv = nullptr; -NzOpenALDetail::LPALGETPROCADDRESS alGetProcAddress = nullptr; -NzOpenALDetail::LPALGETSOURCE3F alGetSource3f = nullptr; -NzOpenALDetail::LPALGETSOURCE3I alGetSource3i = nullptr; -NzOpenALDetail::LPALGETSOURCEF alGetSourcef = nullptr; -NzOpenALDetail::LPALGETSOURCEFV alGetSourcefv = nullptr; -NzOpenALDetail::LPALGETSOURCEI alGetSourcei = nullptr; -NzOpenALDetail::LPALGETSOURCEIV alGetSourceiv = nullptr; -NzOpenALDetail::LPALGETSTRING alGetString = nullptr; -NzOpenALDetail::LPALISBUFFER alIsBuffer = nullptr; -NzOpenALDetail::LPALISENABLED alIsEnabled = nullptr; -NzOpenALDetail::LPALISEXTENSIONPRESENT alIsExtensionPresent = nullptr; -NzOpenALDetail::LPALISSOURCE alIsSource = nullptr; -NzOpenALDetail::LPALLISTENER3F alListener3f = nullptr; -NzOpenALDetail::LPALLISTENER3I alListener3i = nullptr; -NzOpenALDetail::LPALLISTENERF alListenerf = nullptr; -NzOpenALDetail::LPALLISTENERFV alListenerfv = nullptr; -NzOpenALDetail::LPALLISTENERI alListeneri = nullptr; -NzOpenALDetail::LPALLISTENERIV alListeneriv = nullptr; -NzOpenALDetail::LPALSOURCE3F alSource3f = nullptr; -NzOpenALDetail::LPALSOURCE3I alSource3i = nullptr; -NzOpenALDetail::LPALSOURCEF alSourcef = nullptr; -NzOpenALDetail::LPALSOURCEFV alSourcefv = nullptr; -NzOpenALDetail::LPALSOURCEI alSourcei = nullptr; -NzOpenALDetail::LPALSOURCEIV alSourceiv = nullptr; -NzOpenALDetail::LPALSOURCEPAUSE alSourcePause = nullptr; -NzOpenALDetail::LPALSOURCEPAUSEV alSourcePausev = nullptr; -NzOpenALDetail::LPALSOURCEPLAY alSourcePlay = nullptr; -NzOpenALDetail::LPALSOURCEPLAYV alSourcePlayv = nullptr; -NzOpenALDetail::LPALSOURCEQUEUEBUFFERS alSourceQueueBuffers = nullptr; -NzOpenALDetail::LPALSOURCEREWIND alSourceRewind = nullptr; -NzOpenALDetail::LPALSOURCEREWINDV alSourceRewindv = nullptr; -NzOpenALDetail::LPALSOURCESTOP alSourceStop = nullptr; -NzOpenALDetail::LPALSOURCESTOPV alSourceStopv = nullptr; -NzOpenALDetail::LPALSOURCEUNQUEUEBUFFERS alSourceUnqueueBuffers = nullptr; -NzOpenALDetail::LPALSPEEDOFSOUND alSpeedOfSound = nullptr; +OpenALDetail::LPALBUFFER3F alBuffer3f = nullptr; +OpenALDetail::LPALBUFFER3I alBuffer3i = nullptr; +OpenALDetail::LPALBUFFERDATA alBufferData = nullptr; +OpenALDetail::LPALBUFFERF alBufferf = nullptr; +OpenALDetail::LPALBUFFERFV alBufferfv = nullptr; +OpenALDetail::LPALBUFFERI alBufferi = nullptr; +OpenALDetail::LPALBUFFERIV alBufferiv = nullptr; +OpenALDetail::LPALDELETEBUFFERS alDeleteBuffers = nullptr; +OpenALDetail::LPALDELETESOURCES alDeleteSources = nullptr; +OpenALDetail::LPALDISABLE alDisable = nullptr; +OpenALDetail::LPALDISTANCEMODEL alDistanceModel = nullptr; +OpenALDetail::LPALDOPPLERFACTOR alDopplerFactor = nullptr; +OpenALDetail::LPALDOPPLERVELOCITY alDopplerVelocity = nullptr; +OpenALDetail::LPALENABLE alEnable = nullptr; +OpenALDetail::LPALGENBUFFERS alGenBuffers = nullptr; +OpenALDetail::LPALGENSOURCES alGenSources = nullptr; +OpenALDetail::LPALGETBOOLEAN alGetBoolean = nullptr; +OpenALDetail::LPALGETBOOLEANV alGetBooleanv = nullptr; +OpenALDetail::LPALGETBUFFER3F alGetBuffer3f = nullptr; +OpenALDetail::LPALGETBUFFER3I alGetBuffer3i = nullptr; +OpenALDetail::LPALGETBUFFERF alGetBufferf = nullptr; +OpenALDetail::LPALGETBUFFERFV alGetBufferfv = nullptr; +OpenALDetail::LPALGETBUFFERI alGetBufferi = nullptr; +OpenALDetail::LPALGETBUFFERIV alGetBufferiv = nullptr; +OpenALDetail::LPALGETDOUBLE alGetDouble = nullptr; +OpenALDetail::LPALGETDOUBLEV alGetDoublev = nullptr; +OpenALDetail::LPALGETENUMVALUE alGetEnumValue = nullptr; +OpenALDetail::LPALGETERROR alGetError = nullptr; +OpenALDetail::LPALGETFLOAT alGetFloat = nullptr; +OpenALDetail::LPALGETFLOATV alGetFloatv = nullptr; +OpenALDetail::LPALGETINTEGER alGetInteger = nullptr; +OpenALDetail::LPALGETINTEGERV alGetIntegerv = nullptr; +OpenALDetail::LPALGETLISTENER3F alGetListener3f = nullptr; +OpenALDetail::LPALGETLISTENER3I alGetListener3i = nullptr; +OpenALDetail::LPALGETLISTENERF alGetListenerf = nullptr; +OpenALDetail::LPALGETLISTENERFV alGetListenerfv = nullptr; +OpenALDetail::LPALGETLISTENERI alGetListeneri = nullptr; +OpenALDetail::LPALGETLISTENERIV alGetListeneriv = nullptr; +OpenALDetail::LPALGETPROCADDRESS alGetProcAddress = nullptr; +OpenALDetail::LPALGETSOURCE3F alGetSource3f = nullptr; +OpenALDetail::LPALGETSOURCE3I alGetSource3i = nullptr; +OpenALDetail::LPALGETSOURCEF alGetSourcef = nullptr; +OpenALDetail::LPALGETSOURCEFV alGetSourcefv = nullptr; +OpenALDetail::LPALGETSOURCEI alGetSourcei = nullptr; +OpenALDetail::LPALGETSOURCEIV alGetSourceiv = nullptr; +OpenALDetail::LPALGETSTRING alGetString = nullptr; +OpenALDetail::LPALISBUFFER alIsBuffer = nullptr; +OpenALDetail::LPALISENABLED alIsEnabled = nullptr; +OpenALDetail::LPALISEXTENSIONPRESENT alIsExtensionPresent = nullptr; +OpenALDetail::LPALISSOURCE alIsSource = nullptr; +OpenALDetail::LPALLISTENER3F alListener3f = nullptr; +OpenALDetail::LPALLISTENER3I alListener3i = nullptr; +OpenALDetail::LPALLISTENERF alListenerf = nullptr; +OpenALDetail::LPALLISTENERFV alListenerfv = nullptr; +OpenALDetail::LPALLISTENERI alListeneri = nullptr; +OpenALDetail::LPALLISTENERIV alListeneriv = nullptr; +OpenALDetail::LPALSOURCE3F alSource3f = nullptr; +OpenALDetail::LPALSOURCE3I alSource3i = nullptr; +OpenALDetail::LPALSOURCEF alSourcef = nullptr; +OpenALDetail::LPALSOURCEFV alSourcefv = nullptr; +OpenALDetail::LPALSOURCEI alSourcei = nullptr; +OpenALDetail::LPALSOURCEIV alSourceiv = nullptr; +OpenALDetail::LPALSOURCEPAUSE alSourcePause = nullptr; +OpenALDetail::LPALSOURCEPAUSEV alSourcePausev = nullptr; +OpenALDetail::LPALSOURCEPLAY alSourcePlay = nullptr; +OpenALDetail::LPALSOURCEPLAYV alSourcePlayv = nullptr; +OpenALDetail::LPALSOURCEQUEUEBUFFERS alSourceQueueBuffers = nullptr; +OpenALDetail::LPALSOURCEREWIND alSourceRewind = nullptr; +OpenALDetail::LPALSOURCEREWINDV alSourceRewindv = nullptr; +OpenALDetail::LPALSOURCESTOP alSourceStop = nullptr; +OpenALDetail::LPALSOURCESTOPV alSourceStopv = nullptr; +OpenALDetail::LPALSOURCEUNQUEUEBUFFERS alSourceUnqueueBuffers = nullptr; +OpenALDetail::LPALSPEEDOFSOUND alSpeedOfSound = nullptr; // alc -NzOpenALDetail::LPALCCAPTURECLOSEDEVICE alcCaptureCloseDevice = nullptr; -NzOpenALDetail::LPALCCAPTUREOPENDEVICE alcCaptureOpenDevice = nullptr; -NzOpenALDetail::LPALCCAPTURESAMPLES alcCaptureSamples = nullptr; -NzOpenALDetail::LPALCCAPTURESTART alcCaptureStart = nullptr; -NzOpenALDetail::LPALCCAPTURESTOP alcCaptureStop = nullptr; -NzOpenALDetail::LPALCCLOSEDEVICE alcCloseDevice = nullptr; -NzOpenALDetail::LPALCCREATECONTEXT alcCreateContext = nullptr; -NzOpenALDetail::LPALCDESTROYCONTEXT alcDestroyContext = nullptr; -NzOpenALDetail::LPALCGETCONTEXTSDEVICE alcGetContextsDevice = nullptr; -NzOpenALDetail::LPALCGETCURRENTCONTEXT alcGetCurrentContext = nullptr; -NzOpenALDetail::LPALCGETENUMVALUE alcGetEnumValue = nullptr; -NzOpenALDetail::LPALCGETERROR alcGetError = nullptr; -NzOpenALDetail::LPALCGETINTEGERV alcGetIntegerv = nullptr; -NzOpenALDetail::LPALCGETPROCADDRESS alcGetProcAddress = nullptr; -NzOpenALDetail::LPALCGETSTRING alcGetString = nullptr; -NzOpenALDetail::LPALCISEXTENSIONPRESENT alcIsExtensionPresent = nullptr; -NzOpenALDetail::LPALCMAKECONTEXTCURRENT alcMakeContextCurrent = nullptr; -NzOpenALDetail::LPALCOPENDEVICE alcOpenDevice = nullptr; -NzOpenALDetail::LPALCPROCESSCONTEXT alcProcessContext = nullptr; -NzOpenALDetail::LPALCSUSPENDCONTEXT alcSuspendContext = nullptr; +OpenALDetail::LPALCCAPTURECLOSEDEVICE alcCaptureCloseDevice = nullptr; +OpenALDetail::LPALCCAPTUREOPENDEVICE alcCaptureOpenDevice = nullptr; +OpenALDetail::LPALCCAPTURESAMPLES alcCaptureSamples = nullptr; +OpenALDetail::LPALCCAPTURESTART alcCaptureStart = nullptr; +OpenALDetail::LPALCCAPTURESTOP alcCaptureStop = nullptr; +OpenALDetail::LPALCCLOSEDEVICE alcCloseDevice = nullptr; +OpenALDetail::LPALCCREATECONTEXT alcCreateContext = nullptr; +OpenALDetail::LPALCDESTROYCONTEXT alcDestroyContext = nullptr; +OpenALDetail::LPALCGETCONTEXTSDEVICE alcGetContextsDevice = nullptr; +OpenALDetail::LPALCGETCURRENTCONTEXT alcGetCurrentContext = nullptr; +OpenALDetail::LPALCGETENUMVALUE alcGetEnumValue = nullptr; +OpenALDetail::LPALCGETERROR alcGetError = nullptr; +OpenALDetail::LPALCGETINTEGERV alcGetIntegerv = nullptr; +OpenALDetail::LPALCGETPROCADDRESS alcGetProcAddress = nullptr; +OpenALDetail::LPALCGETSTRING alcGetString = nullptr; +OpenALDetail::LPALCISEXTENSIONPRESENT alcIsExtensionPresent = nullptr; +OpenALDetail::LPALCMAKECONTEXTCURRENT alcMakeContextCurrent = nullptr; +OpenALDetail::LPALCOPENDEVICE alcOpenDevice = nullptr; +OpenALDetail::LPALCPROCESSCONTEXT alcProcessContext = nullptr; +OpenALDetail::LPALCSUSPENDCONTEXT alcSuspendContext = nullptr; diff --git a/src/Nazara/Audio/Sound.cpp b/src/Nazara/Audio/Sound.cpp index 4e702a8d5..bcba9a423 100644 --- a/src/Nazara/Audio/Sound.cpp +++ b/src/Nazara/Audio/Sound.cpp @@ -12,162 +12,165 @@ #include #include -NzSound::NzSound(const NzSoundBuffer* soundBuffer) +namespace Nz { - SetBuffer(soundBuffer); -} - -NzSound::NzSound(const NzSound& sound) : -NzSoundEmitter(sound) -{ - SetBuffer(sound.m_buffer); -} - -NzSound::~NzSound() -{ - Stop(); -} - -void NzSound::EnableLooping(bool loop) -{ - alSourcei(m_source, AL_LOOPING, loop); -} - -const NzSoundBuffer* NzSound::GetBuffer() const -{ - return m_buffer; -} - -nzUInt32 NzSound::GetDuration() const -{ - #if NAZARA_AUDIO_SAFE - if (!m_buffer) + Sound::Sound(const SoundBuffer* soundBuffer) { - NazaraError("Invalid sound buffer"); - return 0; - } - #endif - - return m_buffer->GetDuration(); -} - -nzUInt32 NzSound::GetPlayingOffset() const -{ - ALfloat seconds = -1.f; - alGetSourcef(m_source, AL_SEC_OFFSET, &seconds); - - return static_cast(seconds*1000); -} - -nzSoundStatus NzSound::GetStatus() const -{ - return GetInternalStatus(); -} - -bool NzSound::IsLooping() const -{ - ALint loop; - alGetSourcei(m_source, AL_LOOPING, &loop); - - return loop != AL_FALSE; -} - -bool NzSound::IsPlayable() const -{ - return m_buffer != nullptr; -} - -bool NzSound::IsPlaying() const -{ - return GetStatus() == nzSoundStatus_Playing; -} - -bool NzSound::LoadFromFile(const NzString& filePath, const NzSoundBufferParams& params) -{ - NzSoundBufferRef buffer = NzSoundBuffer::New(); - if (!buffer->LoadFromFile(filePath, params)) - { - NazaraError("Failed to load buffer from file (" + filePath + ')'); - return false; + SetBuffer(soundBuffer); } - SetBuffer(buffer); - return true; -} - -bool NzSound::LoadFromMemory(const void* data, std::size_t size, const NzSoundBufferParams& params) -{ - NzSoundBufferRef buffer = NzSoundBuffer::New(); - if (!buffer->LoadFromMemory(data, size, params)) + Sound::Sound(const Sound& sound) : + SoundEmitter(sound) { - NazaraError("Failed to load buffer from memory (" + NzString::Pointer(data) + ')'); - return false; + SetBuffer(sound.m_buffer); } - SetBuffer(buffer); - return true; -} - -bool NzSound::LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params) -{ - NzSoundBufferRef buffer = NzSoundBuffer::New(); - if (!buffer->LoadFromStream(stream, params)) + Sound::~Sound() { - NazaraError("Failed to load buffer from stream"); - return false; + Stop(); } - SetBuffer(buffer); - return true; -} - -void NzSound::Pause() -{ - alSourcePause(m_source); -} - -void NzSound::Play() -{ - #if NAZARA_AUDIO_SAFE - if (!m_buffer) + void Sound::EnableLooping(bool loop) { - NazaraError("Invalid sound buffer"); - return; + alSourcei(m_source, AL_LOOPING, loop); } - #endif - alSourcePlay(m_source); -} - -void NzSound::SetBuffer(const NzSoundBuffer* buffer) -{ - #if NAZARA_AUDIO_SAFE - if (buffer && !buffer->IsValid()) + const SoundBuffer* Sound::GetBuffer() const { - NazaraError("Invalid sound buffer"); - return; + return m_buffer; } - #endif - if (m_buffer == buffer) - return; + UInt32 Sound::GetDuration() const + { + #if NAZARA_AUDIO_SAFE + if (!m_buffer) + { + NazaraError("Invalid sound buffer"); + return 0; + } + #endif - Stop(); + return m_buffer->GetDuration(); + } - m_buffer = buffer; + UInt32 Sound::GetPlayingOffset() const + { + ALfloat seconds = -1.f; + alGetSourcef(m_source, AL_SEC_OFFSET, &seconds); - if (m_buffer) - alSourcei(m_source, AL_BUFFER, m_buffer->GetOpenALBuffer()); - else - alSourcei(m_source, AL_BUFFER, AL_NONE); -} - -void NzSound::SetPlayingOffset(nzUInt32 offset) -{ - alSourcef(m_source, AL_SEC_OFFSET, offset/1000.f); -} - -void NzSound::Stop() -{ - alSourceStop(m_source); + return static_cast(seconds*1000); + } + + SoundStatus Sound::GetStatus() const + { + return GetInternalStatus(); + } + + bool Sound::IsLooping() const + { + ALint loop; + alGetSourcei(m_source, AL_LOOPING, &loop); + + return loop != AL_FALSE; + } + + bool Sound::IsPlayable() const + { + return m_buffer != nullptr; + } + + bool Sound::IsPlaying() const + { + return GetStatus() == SoundStatus_Playing; + } + + bool Sound::LoadFromFile(const String& filePath, const SoundBufferParams& params) + { + SoundBufferRef buffer = SoundBuffer::New(); + if (!buffer->LoadFromFile(filePath, params)) + { + NazaraError("Failed to load buffer from file (" + filePath + ')'); + return false; + } + + SetBuffer(buffer); + return true; + } + + bool Sound::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params) + { + SoundBufferRef buffer = SoundBuffer::New(); + if (!buffer->LoadFromMemory(data, size, params)) + { + NazaraError("Failed to load buffer from memory (" + String::Pointer(data) + ')'); + return false; + } + + SetBuffer(buffer); + return true; + } + + bool Sound::LoadFromStream(InputStream& stream, const SoundBufferParams& params) + { + SoundBufferRef buffer = SoundBuffer::New(); + if (!buffer->LoadFromStream(stream, params)) + { + NazaraError("Failed to load buffer from stream"); + return false; + } + + SetBuffer(buffer); + return true; + } + + void Sound::Pause() + { + alSourcePause(m_source); + } + + void Sound::Play() + { + #if NAZARA_AUDIO_SAFE + if (!m_buffer) + { + NazaraError("Invalid sound buffer"); + return; + } + #endif + + alSourcePlay(m_source); + } + + void Sound::SetBuffer(const SoundBuffer* buffer) + { + #if NAZARA_AUDIO_SAFE + if (buffer && !buffer->IsValid()) + { + NazaraError("Invalid sound buffer"); + return; + } + #endif + + if (m_buffer == buffer) + return; + + Stop(); + + m_buffer = buffer; + + if (m_buffer) + alSourcei(m_source, AL_BUFFER, m_buffer->GetOpenALBuffer()); + else + alSourcei(m_source, AL_BUFFER, AL_NONE); + } + + void Sound::SetPlayingOffset(UInt32 offset) + { + alSourcef(m_source, AL_SEC_OFFSET, offset/1000.f); + } + + void Sound::Stop() + { + alSourceStop(m_source); + } } diff --git a/src/Nazara/Audio/SoundBuffer.cpp b/src/Nazara/Audio/SoundBuffer.cpp index d55a973cd..9b3f9f4ea 100644 --- a/src/Nazara/Audio/SoundBuffer.cpp +++ b/src/Nazara/Audio/SoundBuffer.cpp @@ -14,243 +14,246 @@ ///FIXME: Adapter la création -bool NzSoundBufferParams::IsValid() const +namespace Nz { - return true; -} - -struct NzSoundBufferImpl -{ - ALuint buffer; - nzAudioFormat format; - nzUInt32 duration; - std::unique_ptr samples; - nzUInt32 sampleCount; - nzUInt32 sampleRate; -}; - -NzSoundBuffer::NzSoundBuffer(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples) -{ - Create(format, sampleCount, sampleRate, samples); - - #ifdef NAZARA_DEBUG - if (!m_impl) + bool SoundBufferParams::IsValid() const { - NazaraError("Failed to create sound buffer"); - throw std::runtime_error("Constructor failed"); - } - #endif -} - -NzSoundBuffer::~NzSoundBuffer() -{ - OnSoundBufferRelease(this); - - Destroy(); -} - -bool NzSoundBuffer::Create(nzAudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const nzInt16* samples) -{ - Destroy(); - - #if NAZARA_AUDIO_SAFE - if (!IsFormatSupported(format)) - { - NazaraError("Audio format is not supported"); - return false; + return true; } - if (sampleCount == 0) + struct SoundBufferImpl { - NazaraError("Sample rate must be different from zero"); - return false; + ALuint buffer; + AudioFormat format; + UInt32 duration; + std::unique_ptr samples; + UInt32 sampleCount; + UInt32 sampleRate; + }; + + SoundBuffer::SoundBuffer(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples) + { + Create(format, sampleCount, sampleRate, samples); + + #ifdef NAZARA_DEBUG + if (!m_impl) + { + NazaraError("Failed to create sound buffer"); + throw std::runtime_error("Constructor failed"); + } + #endif } - if (sampleRate == 0) + SoundBuffer::~SoundBuffer() { - NazaraError("Sample rate must be different from zero"); - return false; + OnSoundBufferRelease(this); + + Destroy(); } - if (!samples) + bool SoundBuffer::Create(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples) { - NazaraError("Invalid sample source"); - return false; - } - #endif + Destroy(); - // On vide le stack d'erreurs - while (alGetError() != AL_NO_ERROR); + #if NAZARA_AUDIO_SAFE + if (!IsFormatSupported(format)) + { + NazaraError("Audio format is not supported"); + return false; + } - ALuint buffer; - alGenBuffers(1, &buffer); + if (sampleCount == 0) + { + NazaraError("Sample rate must be different from zero"); + return false; + } - if (alGetError() != AL_NO_ERROR) - { - NazaraError("Failed to create OpenAL buffer"); - return false; + if (sampleRate == 0) + { + NazaraError("Sample rate must be different from zero"); + return false; + } + + if (!samples) + { + NazaraError("Invalid sample source"); + return false; + } + #endif + + // On vide le stack d'erreurs + while (alGetError() != AL_NO_ERROR); + + ALuint buffer; + alGenBuffers(1, &buffer); + + if (alGetError() != AL_NO_ERROR) + { + NazaraError("Failed to create OpenAL buffer"); + return false; + } + + alBufferData(buffer, OpenAL::AudioFormat[format], samples, sampleCount*sizeof(Int16), sampleRate); + + if (alGetError() != AL_NO_ERROR) + { + alDeleteBuffers(1, &buffer); + + NazaraError("Failed to set OpenAL buffer"); + return false; + } + + m_impl = new SoundBufferImpl; + m_impl->buffer = buffer; + m_impl->duration = (1000*sampleCount / (format * sampleRate)); + m_impl->format = format; + m_impl->sampleCount = sampleCount; + m_impl->sampleRate = sampleRate; + m_impl->samples.reset(new Int16[sampleCount]); + std::memcpy(&m_impl->samples[0], samples, sampleCount*sizeof(Int16)); + + return true; } - alBufferData(buffer, NzOpenAL::AudioFormat[format], samples, sampleCount*sizeof(nzInt16), sampleRate); - - if (alGetError() != AL_NO_ERROR) + void SoundBuffer::Destroy() { - alDeleteBuffers(1, &buffer); + if (m_impl) + { + OnSoundBufferDestroy(this); - NazaraError("Failed to set OpenAL buffer"); - return false; + delete m_impl; + m_impl = nullptr; + } } - m_impl = new NzSoundBufferImpl; - m_impl->buffer = buffer; - m_impl->duration = (1000*sampleCount / (format * sampleRate)); - m_impl->format = format; - m_impl->sampleCount = sampleCount; - m_impl->sampleRate = sampleRate; - m_impl->samples.reset(new nzInt16[sampleCount]); - std::memcpy(&m_impl->samples[0], samples, sampleCount*sizeof(nzInt16)); - - return true; -} - -void NzSoundBuffer::Destroy() -{ - if (m_impl) + UInt32 SoundBuffer::GetDuration() const { - OnSoundBufferDestroy(this); + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Sound buffer not created"); + return 0; + } + #endif - delete m_impl; - m_impl = nullptr; - } -} - -nzUInt32 NzSoundBuffer::GetDuration() const -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) - { - NazaraError("Sound buffer not created"); - return 0; - } - #endif - - return m_impl->duration; -} - -nzAudioFormat NzSoundBuffer::GetFormat() const -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) - { - NazaraError("Sound buffer not created"); - return nzAudioFormat_Unknown; - } - #endif - - return m_impl->format; -} - -const nzInt16* NzSoundBuffer::GetSamples() const -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) - { - NazaraError("Sound buffer not created"); - return nullptr; - } - #endif - - return m_impl->samples.get(); -} - -unsigned int NzSoundBuffer::GetSampleCount() const -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) - { - NazaraError("Sound buffer not created"); - return 0; - } - #endif - - return m_impl->sampleCount; -} - -unsigned int NzSoundBuffer::GetSampleRate() const -{ - #if NAZARA_AUDIO_SAFE - if (!m_impl) - { - NazaraError("Sound buffer not created"); - return 0; - } - #endif - - return m_impl->sampleRate; -} - -bool NzSoundBuffer::IsValid() const -{ - return m_impl != nullptr; -} - -bool NzSoundBuffer::LoadFromFile(const NzString& filePath, const NzSoundBufferParams& params) -{ - return NzSoundBufferLoader::LoadFromFile(this, filePath, params); -} - -bool NzSoundBuffer::LoadFromMemory(const void* data, std::size_t size, const NzSoundBufferParams& params) -{ - return NzSoundBufferLoader::LoadFromMemory(this, data, size, params); -} - -bool NzSoundBuffer::LoadFromStream(NzInputStream& stream, const NzSoundBufferParams& params) -{ - return NzSoundBufferLoader::LoadFromStream(this, stream, params); -} - -bool NzSoundBuffer::IsFormatSupported(nzAudioFormat format) -{ - return NzAudio::IsFormatSupported(format); -} - -unsigned int NzSoundBuffer::GetOpenALBuffer() const -{ - #ifdef NAZARA_DEBUG - if (!m_impl) - { - NazaraInternalError("Sound buffer not created"); - return AL_NONE; - } - #endif - - return m_impl->buffer; -} - -bool NzSoundBuffer::Initialize() -{ - if (!NzSoundBufferLibrary::Initialize()) - { - NazaraError("Failed to initialise library"); - return false; + return m_impl->duration; } - if (!NzSoundBufferManager::Initialize()) + AudioFormat SoundBuffer::GetFormat() const { - NazaraError("Failed to initialise manager"); - return false; + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Sound buffer not created"); + return AudioFormat_Unknown; + } + #endif + + return m_impl->format; } - return true; -} + const Int16* SoundBuffer::GetSamples() const + { + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Sound buffer not created"); + return nullptr; + } + #endif -void NzSoundBuffer::Uninitialize() -{ - NzSoundBufferManager::Uninitialize(); - NzSoundBufferLibrary::Uninitialize(); -} + return m_impl->samples.get(); + } -NzSoundBufferLibrary::LibraryMap NzSoundBuffer::s_library; -NzSoundBufferLoader::LoaderList NzSoundBuffer::s_loaders; -NzSoundBufferManager::ManagerMap NzSoundBuffer::s_managerMap; -NzSoundBufferManager::ManagerParams NzSoundBuffer::s_managerParameters; + unsigned int SoundBuffer::GetSampleCount() const + { + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Sound buffer not created"); + return 0; + } + #endif + + return m_impl->sampleCount; + } + + unsigned int SoundBuffer::GetSampleRate() const + { + #if NAZARA_AUDIO_SAFE + if (!m_impl) + { + NazaraError("Sound buffer not created"); + return 0; + } + #endif + + return m_impl->sampleRate; + } + + bool SoundBuffer::IsValid() const + { + return m_impl != nullptr; + } + + bool SoundBuffer::LoadFromFile(const String& filePath, const SoundBufferParams& params) + { + return SoundBufferLoader::LoadFromFile(this, filePath, params); + } + + bool SoundBuffer::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params) + { + return SoundBufferLoader::LoadFromMemory(this, data, size, params); + } + + bool SoundBuffer::LoadFromStream(InputStream& stream, const SoundBufferParams& params) + { + return SoundBufferLoader::LoadFromStream(this, stream, params); + } + + bool SoundBuffer::IsFormatSupported(AudioFormat format) + { + return Audio::IsFormatSupported(format); + } + + unsigned int SoundBuffer::GetOpenALBuffer() const + { + #ifdef NAZARA_DEBUG + if (!m_impl) + { + NazaraInternalError("Sound buffer not created"); + return AL_NONE; + } + #endif + + return m_impl->buffer; + } + + bool SoundBuffer::Initialize() + { + if (!SoundBufferLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } + + if (!SoundBufferManager::Initialize()) + { + NazaraError("Failed to initialise manager"); + return false; + } + + return true; + } + + void SoundBuffer::Uninitialize() + { + SoundBufferManager::Uninitialize(); + SoundBufferLibrary::Uninitialize(); + } + + SoundBufferLibrary::LibraryMap SoundBuffer::s_library; + SoundBufferLoader::LoaderList SoundBuffer::s_loaders; + SoundBufferManager::ManagerMap SoundBuffer::s_managerMap; + SoundBufferManager::ManagerParams SoundBuffer::s_managerParameters; +} diff --git a/src/Nazara/Audio/SoundEmitter.cpp b/src/Nazara/Audio/SoundEmitter.cpp index 47b39a741..cbee8a8f9 100644 --- a/src/Nazara/Audio/SoundEmitter.cpp +++ b/src/Nazara/Audio/SoundEmitter.cpp @@ -9,148 +9,151 @@ #include #include -NzSoundEmitter::NzSoundEmitter() +namespace Nz { - alGenSources(1, &m_source); -} - -NzSoundEmitter::NzSoundEmitter(const NzSoundEmitter& emitter) -{ - alGenSources(1, &m_source); - - SetAttenuation(emitter.GetAttenuation()); - SetMinDistance(emitter.GetMinDistance()); - SetPitch(emitter.GetPitch()); - // Pas de copie de position ou de vitesse - SetVolume(emitter.GetVolume()); -} - -NzSoundEmitter::~NzSoundEmitter() -{ - alDeleteSources(1, &m_source); -} - -void NzSoundEmitter::EnableSpatialization(bool spatialization) -{ - alSourcei(m_source, AL_SOURCE_RELATIVE, !spatialization); -} - -float NzSoundEmitter::GetAttenuation() const -{ - ALfloat attenuation; - alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &attenuation); - - return attenuation; -} - -float NzSoundEmitter::GetMinDistance() const -{ - ALfloat distance; - alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &distance); - - return distance; -} - -float NzSoundEmitter::GetPitch() const -{ - ALfloat pitch; - alGetSourcef(m_source, AL_PITCH, &pitch); - - return pitch; -} - -NzVector3f NzSoundEmitter::GetPosition() const -{ - NzVector3f position; - alGetSourcefv(m_source, AL_POSITION, position); - - return position; -} - -NzVector3f NzSoundEmitter::GetVelocity() const -{ - NzVector3f velocity; - alGetSourcefv(m_source, AL_VELOCITY, velocity); - - return velocity; -} - -float NzSoundEmitter::GetVolume() const -{ - ALfloat gain; - alGetSourcef(m_source, AL_GAIN, &gain); - - return gain * 100.f; -} - -bool NzSoundEmitter::IsSpatialized() const -{ - ALint relative; - alGetSourcei(m_source, AL_SOURCE_RELATIVE, &relative); - - return relative == AL_FALSE; -} - -void NzSoundEmitter::SetAttenuation(float attenuation) -{ - alSourcef(m_source, AL_ROLLOFF_FACTOR, attenuation); -} - -void NzSoundEmitter::SetMinDistance(float minDistance) -{ - alSourcef(m_source, AL_REFERENCE_DISTANCE, minDistance); -} - -void NzSoundEmitter::SetPitch(float pitch) -{ - alSourcef(m_source, AL_PITCH, pitch); -} - -void NzSoundEmitter::SetPosition(const NzVector3f& position) -{ - alSourcefv(m_source, AL_POSITION, position); -} - -void NzSoundEmitter::SetPosition(float x, float y, float z) -{ - alSource3f(m_source, AL_POSITION, x, y, z); -} - -void NzSoundEmitter::SetVelocity(const NzVector3f& velocity) -{ - alSourcefv(m_source, AL_VELOCITY, velocity); -} - -void NzSoundEmitter::SetVelocity(float velX, float velY, float velZ) -{ - alSource3f(m_source, AL_VELOCITY, velX, velY, velZ); -} - -void NzSoundEmitter::SetVolume(float volume) -{ - alSourcef(m_source, AL_GAIN, volume*0.01f); -} - -nzSoundStatus NzSoundEmitter::GetInternalStatus() const -{ - ALint state; - alGetSourcei(m_source, AL_SOURCE_STATE, &state); - - switch (state) + SoundEmitter::SoundEmitter() { - case AL_INITIAL: - case AL_STOPPED: - return nzSoundStatus_Stopped; - - case AL_PAUSED: - return nzSoundStatus_Paused; - - case AL_PLAYING: - return nzSoundStatus_Playing; - - default: - NazaraInternalError("Source state unrecognized"); + alGenSources(1, &m_source); } - return nzSoundStatus_Stopped; + SoundEmitter::SoundEmitter(const SoundEmitter& emitter) + { + alGenSources(1, &m_source); + + SetAttenuation(emitter.GetAttenuation()); + SetMinDistance(emitter.GetMinDistance()); + SetPitch(emitter.GetPitch()); + // Pas de copie de position ou de vitesse + SetVolume(emitter.GetVolume()); + } + + SoundEmitter::~SoundEmitter() + { + alDeleteSources(1, &m_source); + } + + void SoundEmitter::EnableSpatialization(bool spatialization) + { + alSourcei(m_source, AL_SOURCE_RELATIVE, !spatialization); + } + + float SoundEmitter::GetAttenuation() const + { + ALfloat attenuation; + alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &attenuation); + + return attenuation; + } + + float SoundEmitter::GetMinDistance() const + { + ALfloat distance; + alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &distance); + + return distance; + } + + float SoundEmitter::GetPitch() const + { + ALfloat pitch; + alGetSourcef(m_source, AL_PITCH, &pitch); + + return pitch; + } + + Vector3f SoundEmitter::GetPosition() const + { + Vector3f position; + alGetSourcefv(m_source, AL_POSITION, position); + + return position; + } + + Vector3f SoundEmitter::GetVelocity() const + { + Vector3f velocity; + alGetSourcefv(m_source, AL_VELOCITY, velocity); + + return velocity; + } + + float SoundEmitter::GetVolume() const + { + ALfloat gain; + alGetSourcef(m_source, AL_GAIN, &gain); + + return gain * 100.f; + } + + bool SoundEmitter::IsSpatialized() const + { + ALint relative; + alGetSourcei(m_source, AL_SOURCE_RELATIVE, &relative); + + return relative == AL_FALSE; + } + + void SoundEmitter::SetAttenuation(float attenuation) + { + alSourcef(m_source, AL_ROLLOFF_FACTOR, attenuation); + } + + void SoundEmitter::SetMinDistance(float minDistance) + { + alSourcef(m_source, AL_REFERENCE_DISTANCE, minDistance); + } + + void SoundEmitter::SetPitch(float pitch) + { + alSourcef(m_source, AL_PITCH, pitch); + } + + void SoundEmitter::SetPosition(const Vector3f& position) + { + alSourcefv(m_source, AL_POSITION, position); + } + + void SoundEmitter::SetPosition(float x, float y, float z) + { + alSource3f(m_source, AL_POSITION, x, y, z); + } + + void SoundEmitter::SetVelocity(const Vector3f& velocity) + { + alSourcefv(m_source, AL_VELOCITY, velocity); + } + + void SoundEmitter::SetVelocity(float velX, float velY, float velZ) + { + alSource3f(m_source, AL_VELOCITY, velX, velY, velZ); + } + + void SoundEmitter::SetVolume(float volume) + { + alSourcef(m_source, AL_GAIN, volume*0.01f); + } + + SoundStatus SoundEmitter::GetInternalStatus() const + { + ALint state; + alGetSourcei(m_source, AL_SOURCE_STATE, &state); + + switch (state) + { + case AL_INITIAL: + case AL_STOPPED: + return SoundStatus_Stopped; + + case AL_PAUSED: + return SoundStatus_Paused; + + case AL_PLAYING: + return SoundStatus_Playing; + + default: + NazaraInternalError("Source state unrecognized"); + } + + return SoundStatus_Stopped; + } } diff --git a/src/Nazara/Audio/SoundStream.cpp b/src/Nazara/Audio/SoundStream.cpp index a81ea7e41..c243e875f 100644 --- a/src/Nazara/Audio/SoundStream.cpp +++ b/src/Nazara/Audio/SoundStream.cpp @@ -4,4 +4,7 @@ #include -NzSoundStream::~NzSoundStream() = default; +namespace Nz +{ + SoundStream::~SoundStream() = default; +} diff --git a/src/Nazara/Core/AbstractHash.cpp b/src/Nazara/Core/AbstractHash.cpp index b388da5e2..c9d6fa517 100644 --- a/src/Nazara/Core/AbstractHash.cpp +++ b/src/Nazara/Core/AbstractHash.cpp @@ -5,4 +5,7 @@ #include #include -NzAbstractHash::~NzAbstractHash() = default; +namespace Nz +{ + AbstractHash::~AbstractHash() = default; +} diff --git a/src/Nazara/Core/ByteArray.cpp b/src/Nazara/Core/ByteArray.cpp index c5062ed81..33b53913b 100644 --- a/src/Nazara/Core/ByteArray.cpp +++ b/src/Nazara/Core/ByteArray.cpp @@ -7,15 +7,18 @@ #include #include -std::ostream& operator<<(std::ostream& out, const NzByteArray& byteArray) +namespace Nz { - out << byteArray.ToString(); - return out; -} + std::ostream& operator<<(std::ostream& out, const ByteArray& byteArray) + { + out << byteArray.ToString(); + return out; + } -bool NzByteArray::FillHash(NzAbstractHash* hash) const -{ - hash->Append(GetConstBuffer(), GetSize()); + bool ByteArray::FillHash(AbstractHash* hash) const + { + hash->Append(GetConstBuffer(), GetSize()); - return true; + return true; + } } diff --git a/src/Nazara/Core/Clock.cpp b/src/Nazara/Core/Clock.cpp index 8ad7a32a1..7d13b9d95 100644 --- a/src/Nazara/Core/Clock.cpp +++ b/src/Nazara/Core/Clock.cpp @@ -21,93 +21,96 @@ #include -namespace +namespace Nz { - nzUInt64 NzGetMicrosecondsLowPrecision() + namespace Detail { - return NzClockImplGetMilliseconds()*1000ULL; + UInt64 GetMicrosecondsLowPrecision() + { + return ClockImplGetElapsedMilliseconds()*1000ULL; + } + + UInt64 GetElapsedMicrosecondsFirstRun() + { + if (ClockImplInitializeHighPrecision()) + GetElapsedMicroseconds = ClockImplGetElapsedMicroseconds; + else + GetElapsedMicroseconds = GetMicrosecondsLowPrecision; + + return GetElapsedMicroseconds(); + } } - nzUInt64 NzGetMicrosecondsFirstRun() + Clock::Clock(UInt64 startingValue, bool paused) : + m_elapsedTime(startingValue), + m_refTime(GetElapsedMicroseconds()), + m_paused(paused) { - if (NzClockImplInitializeHighPrecision()) - NzGetMicroseconds = NzClockImplGetMicroseconds; + } + + float Clock::GetSeconds() const + { + return GetMicroseconds()/1000000.f; + } + + UInt64 Clock::GetMicroseconds() const + { + NazaraLock(m_mutex); + + UInt64 elapsedMicroseconds = m_elapsedTime; + if (!m_paused) + elapsedMicroseconds += (GetElapsedMicroseconds() - m_refTime); + + return elapsedMicroseconds; + } + + UInt64 Clock::GetMilliseconds() const + { + return GetMicroseconds()/1000; + } + + bool Clock::IsPaused() const + { + NazaraLock(m_mutex); + + return m_paused; + } + + void Clock::Pause() + { + NazaraLock(m_mutex); + + if (!m_paused) + { + m_elapsedTime += GetElapsedMicroseconds() - m_refTime; + m_paused = true; + } else - NzGetMicroseconds = NzGetMicrosecondsLowPrecision; - - return NzGetMicroseconds(); + NazaraWarning("Clock is already paused, ignoring..."); } -} -NzClock::NzClock(nzUInt64 startingValue, bool paused) : -m_elapsedTime(startingValue), -m_refTime(NzGetMicroseconds()), -m_paused(paused) -{ -} - -float NzClock::GetSeconds() const -{ - return GetMicroseconds()/1000000.f; -} - -nzUInt64 NzClock::GetMicroseconds() const -{ - NazaraLock(m_mutex); - - nzUInt64 elapsedMicroseconds = m_elapsedTime; - if (!m_paused) - elapsedMicroseconds += (NzGetMicroseconds() - m_refTime); - - return elapsedMicroseconds; -} - -nzUInt64 NzClock::GetMilliseconds() const -{ - return GetMicroseconds()/1000; -} - -bool NzClock::IsPaused() const -{ - NazaraLock(m_mutex); - - return m_paused; -} - -void NzClock::Pause() -{ - NazaraLock(m_mutex); - - if (!m_paused) + void Clock::Restart() { - m_elapsedTime += NzGetMicroseconds()-m_refTime; - m_paused = true; - } - else - NazaraWarning("Clock is already paused, ignoring..."); -} + NazaraLock(m_mutex); -void NzClock::Restart() -{ - NazaraLock(m_mutex); - - m_elapsedTime = 0; - m_refTime = NzGetMicroseconds(); - m_paused = false; -} - -void NzClock::Unpause() -{ - NazaraLock(m_mutex); - - if (m_paused) - { - m_refTime = NzGetMicroseconds(); + m_elapsedTime = 0; + m_refTime = GetElapsedMicroseconds(); m_paused = false; } - else - NazaraWarning("Clock is not paused, ignoring..."); -} -NzClockFunction NzGetMicroseconds = NzGetMicrosecondsFirstRun; -NzClockFunction NzGetMilliseconds = NzClockImplGetMilliseconds; + void Clock::Unpause() + { + NazaraLock(m_mutex); + + if (m_paused) + { + m_refTime = GetElapsedMicroseconds(); + m_paused = false; + } + else + NazaraWarning("Clock is not paused, ignoring..."); + } + + ClockFunction GetElapsedMicroseconds = Detail::GetElapsedMicrosecondsFirstRun; + ClockFunction GetElapsedMilliseconds = ClockImplGetElapsedMilliseconds; +} diff --git a/src/Nazara/Core/Color.cpp b/src/Nazara/Core/Color.cpp index a6e596021..35128a38d 100644 --- a/src/Nazara/Core/Color.cpp +++ b/src/Nazara/Core/Color.cpp @@ -5,12 +5,15 @@ #include #include -const NzColor NzColor::Black(0, 0, 0); -const NzColor NzColor::Blue(0, 0, 255); -const NzColor NzColor::Cyan(0, 255, 255); -const NzColor NzColor::Green(0, 255, 0); -const NzColor NzColor::Magenta(255, 0, 255); -const NzColor NzColor::Orange(255, 165, 0); -const NzColor NzColor::Red(255, 0, 0); -const NzColor NzColor::Yellow(255, 255, 0); -const NzColor NzColor::White(255, 255, 255); +namespace Nz +{ + const Color Color::Black(0, 0, 0); + const Color Color::Blue(0, 0, 255); + const Color Color::Cyan(0, 255, 255); + const Color Color::Green(0, 255, 0); + const Color Color::Magenta(255, 0, 255); + const Color Color::Orange(255, 165, 0); + const Color Color::Red(255, 0, 0); + const Color Color::Yellow(255, 255, 0); + const Color Color::White(255, 255, 255); +} diff --git a/src/Nazara/Core/ConditionVariable.cpp b/src/Nazara/Core/ConditionVariable.cpp index b9194d233..f893c7f82 100644 --- a/src/Nazara/Core/ConditionVariable.cpp +++ b/src/Nazara/Core/ConditionVariable.cpp @@ -16,34 +16,37 @@ #include -NzConditionVariable::NzConditionVariable() +namespace Nz { - m_impl = new NzConditionVariableImpl; -} + ConditionVariable::ConditionVariable() + { + m_impl = new ConditionVariableImpl; + } -NzConditionVariable::~NzConditionVariable() -{ - delete m_impl; -} + ConditionVariable::~ConditionVariable() + { + delete m_impl; + } -void NzConditionVariable::Signal() -{ - m_impl->Signal(); -} + void ConditionVariable::Signal() + { + m_impl->Signal(); + } -void NzConditionVariable::SignalAll() -{ - m_impl->SignalAll(); -} + void ConditionVariable::SignalAll() + { + m_impl->SignalAll(); + } -void NzConditionVariable::Wait(NzMutex* mutex) -{ - NazaraAssert(mutex != nullptr, "Mutex must be valid"); - m_impl->Wait(mutex->m_impl); -} + void ConditionVariable::Wait(Mutex* mutex) + { + NazaraAssert(mutex != nullptr, "Mutex must be valid"); + m_impl->Wait(mutex->m_impl); + } -bool NzConditionVariable::Wait(NzMutex* mutex, nzUInt32 timeout) -{ - NazaraAssert(mutex != nullptr, "Mutex must be valid"); - return m_impl->Wait(mutex->m_impl, timeout); + bool ConditionVariable::Wait(Mutex* mutex, UInt32 timeout) + { + NazaraAssert(mutex != nullptr, "Mutex must be valid"); + return m_impl->Wait(mutex->m_impl, timeout); + } } diff --git a/src/Nazara/Core/Core.cpp b/src/Nazara/Core/Core.cpp index 7e32de55d..a189a2b94 100644 --- a/src/Nazara/Core/Core.cpp +++ b/src/Nazara/Core/Core.cpp @@ -11,44 +11,47 @@ #include #include -bool NzCore::Initialize() +namespace Nz { - if (s_moduleReferenceCounter > 0) + bool Core::Initialize() { + if (s_moduleReferenceCounter > 0) + { + s_moduleReferenceCounter++; + return true; // Déjà initialisé + } + s_moduleReferenceCounter++; - return true; // Déjà initialisé + + NazaraNotice("Initialized: Core"); + return true; } - s_moduleReferenceCounter++; - - NazaraNotice("Initialized: Core"); - return true; -} - -bool NzCore::IsInitialized() -{ - return s_moduleReferenceCounter != 0; -} - -void NzCore::Uninitialize() -{ - if (s_moduleReferenceCounter != 1) + bool Core::IsInitialized() { - // Le module est soit encore utilisé, soit pas initialisé - if (s_moduleReferenceCounter > 1) - s_moduleReferenceCounter--; - - return; + return s_moduleReferenceCounter != 0; } - // Libération du module - s_moduleReferenceCounter = 0; + void Core::Uninitialize() + { + if (s_moduleReferenceCounter != 1) + { + // Le module est soit encore utilisé, soit pas initialisé + if (s_moduleReferenceCounter > 1) + s_moduleReferenceCounter--; - NzHardwareInfo::Uninitialize(); - NzPluginManager::Uninitialize(); - NzTaskScheduler::Uninitialize(); + return; + } - NazaraNotice("Uninitialized: Core"); + // Libération du module + s_moduleReferenceCounter = 0; + + HardwareInfo::Uninitialize(); + PluginManager::Uninitialize(); + TaskScheduler::Uninitialize(); + + NazaraNotice("Uninitialized: Core"); + } + + unsigned int Core::s_moduleReferenceCounter = 0; } - -unsigned int NzCore::s_moduleReferenceCounter = 0; diff --git a/src/Nazara/Core/Debug/NewOverload.cpp b/src/Nazara/Core/Debug/NewOverload.cpp index b8c16363c..1638b4918 100644 --- a/src/Nazara/Core/Debug/NewOverload.cpp +++ b/src/Nazara/Core/Debug/NewOverload.cpp @@ -10,22 +10,22 @@ void* operator new(std::size_t size) { - return NzMemoryManager::Allocate(size, false); + return Nz::MemoryManager::Allocate(size, false); } void* operator new[](std::size_t size) { - return NzMemoryManager::Allocate(size, true); + return Nz::MemoryManager::Allocate(size, true); } void operator delete(void* pointer) noexcept { - NzMemoryManager::Free(pointer, false); + Nz::MemoryManager::Free(pointer, false); } void operator delete[](void* pointer) noexcept { - NzMemoryManager::Free(pointer, true); + Nz::MemoryManager::Free(pointer, true); } #endif // NAZARA_CORE_MANAGE_MEMORY diff --git a/src/Nazara/Core/Debug/NewRedefinition.cpp b/src/Nazara/Core/Debug/NewRedefinition.cpp index 36a9f2d91..73a467e5c 100644 --- a/src/Nazara/Core/Debug/NewRedefinition.cpp +++ b/src/Nazara/Core/Debug/NewRedefinition.cpp @@ -13,24 +13,24 @@ void* operator new(std::size_t size, const char* file, unsigned int line) { - return NzMemoryManager::Allocate(size, false, file, line); + return Nz::MemoryManager::Allocate(size, false, file, line); } void* operator new[](std::size_t size, const char* file, unsigned int line) { - return NzMemoryManager::Allocate(size, true, file, line); + return Nz::MemoryManager::Allocate(size, true, file, line); } void operator delete(void* ptr, const char* file, unsigned int line) noexcept { - NzMemoryManager::NextFree(file, line); - NzMemoryManager::Free(ptr, false); + Nz::MemoryManager::NextFree(file, line); + Nz::MemoryManager::Free(ptr, false); } void operator delete[](void* ptr, const char* file, unsigned int line) noexcept { - NzMemoryManager::NextFree(file, line); - NzMemoryManager::Free(ptr, true); + Nz::MemoryManager::NextFree(file, line); + Nz::MemoryManager::Free(ptr, true); } #endif // NAZARA_CORE_MANAGE_MEMORY diff --git a/src/Nazara/Core/Directory.cpp b/src/Nazara/Core/Directory.cpp index e500eda06..6d24e714e 100644 --- a/src/Nazara/Core/Directory.cpp +++ b/src/Nazara/Core/Directory.cpp @@ -24,364 +24,367 @@ #include -namespace +namespace Nz { - /*thread_local*/ NzString currentPath(NzDirectoryImpl::GetCurrent()); -} - -NzDirectory::NzDirectory() : -m_pattern('*'), -m_impl(nullptr) -{ -} - -NzDirectory::NzDirectory(const NzString& dirPath) : -m_dirPath(dirPath), -m_pattern('*'), -m_impl(nullptr) -{ -} - -NzDirectory::~NzDirectory() -{ - Close(); -} - -void NzDirectory::Close() -{ - NazaraLock(m_mutex); - - if (m_impl) + namespace { - m_impl->Close(); - delete m_impl; - m_impl = nullptr; - } -} - -bool NzDirectory::Exists() const -{ - NazaraLock(m_mutex); - - if (IsOpen()) - return true; // Le fichier est ouvert, donc il existe - else - return Exists(m_dirPath); -} - -NzString NzDirectory::GetPath() const -{ - NazaraLock(m_mutex); - - return m_dirPath; -} - -NzString NzDirectory::GetPattern() const -{ - NazaraLock(m_mutex); - - return m_pattern; -} - -NzString NzDirectory::GetResultName() const -{ - NazaraLock(m_mutex); - - #if NAZARA_CORE_SAFE - if (!m_impl) - { - NazaraError("Directory not opened"); - return NzString(); - } - #endif - - return m_impl->GetResultName(); -} - -NzString NzDirectory::GetResultPath() const -{ - NazaraLock(m_mutex); - - #if NAZARA_CORE_SAFE - if (!m_impl) - { - NazaraError("Directory not opened"); - return NzString(); - } - #endif - - return m_dirPath + NAZARA_DIRECTORY_SEPARATOR + m_impl->GetResultName(); -} - -nzUInt64 NzDirectory::GetResultSize() const -{ - NazaraLock(m_mutex); - - #if NAZARA_CORE_SAFE - if (!m_impl) - { - NazaraError("Directory not opened"); - return 0; - } - #endif - - return m_impl->GetResultSize(); -} - -bool NzDirectory::IsOpen() const -{ - NazaraLock(m_mutex); - - return m_impl != nullptr; -} - -bool NzDirectory::IsResultDirectory() const -{ - NazaraLock(m_mutex); - - #if NAZARA_CORE_SAFE - if (!m_impl) - { - NazaraError("Directory not opened"); - return false; - } - #endif - - return m_impl->IsResultDirectory(); -} - -bool NzDirectory::NextResult(bool skipDots) -{ - NazaraLock(m_mutex); - - #if NAZARA_CORE_SAFE - if (!m_impl) - { - NazaraError("Directory not opened"); - return false; - } - #endif - - NzString name; - do - { - if (!m_impl->NextResult()) - return false; - - name = m_impl->GetResultName(); - - if (skipDots && (name == '.' || name == "..")) - continue; - - if (name.Match(m_pattern)) - break; - } - while (true); - - return true; -} - -bool NzDirectory::Open() -{ - NazaraLock(m_mutex); - - Close(); - - if (!Exists(m_dirPath)) - return false; - - m_impl = new NzDirectoryImpl(this); - if (!m_impl->Open(m_dirPath)) - { - delete m_impl; - m_impl = nullptr; - - return false; + thread_local String currentPath(DirectoryImpl::GetCurrent()); } - return true; -} - -void NzDirectory::SetPath(const NzString& dirPath) -{ - NazaraLock(m_mutex); - - Close(); - - m_dirPath = NzFile::AbsolutePath(dirPath); -} - -void NzDirectory::SetPattern(const NzString& pattern) -{ - NazaraLock(m_mutex); - - m_pattern = pattern; -} - -bool NzDirectory::Copy(const NzString& sourcePath, const NzString& destPath) -{ - if (sourcePath.IsEmpty() || destPath.IsEmpty()) - return false; - - NzString dirPath(sourcePath); - NzString dest(NzFile::NormalizePath(destPath)); - - if (!Create(destPath, true)) + Directory::Directory() : + m_pattern('*'), + m_impl(nullptr) { - NazaraError("Unable to create \"" + destPath + '"'); - return false; } - NzDirectory dir(dirPath); - if (!dir.Open()) + Directory::Directory(const String& dirPath) : + m_dirPath(dirPath), + m_pattern('*'), + m_impl(nullptr) { - NazaraError("Unable to open \"" + destPath + '"'); - return false; } - while (dir.NextResult(true)) + Directory::~Directory() { - if (dir.IsResultDirectory()) + Close(); + } + + void Directory::Close() + { + NazaraLock(m_mutex); + + if (m_impl) { - if (!Copy(dir.GetResultPath(), dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName())) - return false; - } - else if (!NzFile::Copy(dir.GetResultPath(), dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName())) - { - NazaraError("Failed to copy \"" + dir.GetResultPath() + "\" to \"" + dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName() + '"'); - return false; + m_impl->Close(); + delete m_impl; + m_impl = nullptr; } } - dir.Close(); - - return true; -} - -bool NzDirectory::Create(const NzString& dirPath, bool recursive) -{ - if (dirPath.IsEmpty()) - return false; - - if (recursive) + bool Directory::Exists() const { - NzString path = NzFile::NormalizePath(dirPath); - unsigned int foundPos = path.Find(NAZARA_DIRECTORY_SEPARATOR); - if (foundPos == NzString::npos) - return false; + NazaraLock(m_mutex); - #ifdef NAZARA_PLATFORM_WINDOWS - // Contrairement au disque (Ex: "C:"), le chemin réseau n'est pas considéré comme un dossier (Ex: "\\Laptop") - if (path.Match("\\\\*")) + if (IsOpen()) + return true; // Le fichier est ouvert, donc il existe + else + return Exists(m_dirPath); + } + + String Directory::GetPath() const + { + NazaraLock(m_mutex); + + return m_dirPath; + } + + String Directory::GetPattern() const + { + NazaraLock(m_mutex); + + return m_pattern; + } + + String Directory::GetResultName() const + { + NazaraLock(m_mutex); + + #if NAZARA_CORE_SAFE + if (!m_impl) { - foundPos = path.Find('\\', 2); - if (foundPos == NzString::npos) - return false; - - foundPos = path.Find('\\', foundPos+1); - if (foundPos == NzString::npos) - return false; + NazaraError("Directory not opened"); + return String(); } #endif + return m_impl->GetResultName(); + } + + String Directory::GetResultPath() const + { + NazaraLock(m_mutex); + + #if NAZARA_CORE_SAFE + if (!m_impl) + { + NazaraError("Directory not opened"); + return String(); + } + #endif + + return m_dirPath + NAZARA_DIRECTORY_SEPARATOR + m_impl->GetResultName(); + } + + UInt64 Directory::GetResultSize() const + { + NazaraLock(m_mutex); + + #if NAZARA_CORE_SAFE + if (!m_impl) + { + NazaraError("Directory not opened"); + return 0; + } + #endif + + return m_impl->GetResultSize(); + } + + bool Directory::IsOpen() const + { + NazaraLock(m_mutex); + + return m_impl != nullptr; + } + + bool Directory::IsResultDirectory() const + { + NazaraLock(m_mutex); + + #if NAZARA_CORE_SAFE + if (!m_impl) + { + NazaraError("Directory not opened"); + return false; + } + #endif + + return m_impl->IsResultDirectory(); + } + + bool Directory::NextResult(bool skipDots) + { + NazaraLock(m_mutex); + + #if NAZARA_CORE_SAFE + if (!m_impl) + { + NazaraError("Directory not opened"); + return false; + } + #endif + + String name; do { - NzString p = path.SubString(0, foundPos); - if (p.EndsWith(NAZARA_DIRECTORY_SEPARATOR)) - p = p.SubString(0, -2); - - if (!NzDirectoryImpl::Exists(p) && !NzDirectoryImpl::Create(p)) + if (!m_impl->NextResult()) return false; - if (foundPos == NzString::npos) - break; + name = m_impl->GetResultName(); - foundPos = path.Find(NAZARA_DIRECTORY_SEPARATOR, foundPos+1); + if (skipDots && (name == '.' || name == "..")) + continue; + + if (name.Match(m_pattern)) + break; } while (true); return true; } - else - return NzDirectoryImpl::Create(NzFile::NormalizePath(dirPath)); -} -bool NzDirectory::Exists(const NzString& dirPath) -{ - if (dirPath.IsEmpty()) - return false; - - return NzDirectoryImpl::Exists(NzFile::NormalizePath(dirPath)); -} - -NzString NzDirectory::GetCurrent() -{ - return currentPath; -} - -const char* NzDirectory::GetCurrentFileRelativeToEngine(const char* currentFile) -{ - ///FIXME: Est-ce que cette méthode est au bon endroit ? - static int offset = -1; - - if (offset < 0) + bool Directory::Open() { - const char* directoryFile = __FILE__; - const char* ptr = std::strstr(directoryFile, "NazaraEngine/src/Nazara/Core/Directory.cpp"); - if (ptr) - offset = ptr - directoryFile; - else + NazaraLock(m_mutex); + + Close(); + + if (!Exists(m_dirPath)) + return false; + + m_impl = new DirectoryImpl(this); + if (!m_impl->Open(m_dirPath)) { - ptr = std::strstr(directoryFile, "NazaraEngine\\src\\Nazara\\Core\\Directory.cpp"); - if (ptr) - offset = ptr - directoryFile; - else - offset = 0; + delete m_impl; + m_impl = nullptr; + + return false; } + + return true; } - return ¤tFile[offset]; -} - -bool NzDirectory::Remove(const NzString& dirPath, bool emptyDirectory) -{ - if (dirPath.IsEmpty()) - return false; - - if (emptyDirectory) + void Directory::SetPath(const String& dirPath) { - NzDirectory dir(dirPath); + NazaraLock(m_mutex); + + Close(); + + m_dirPath = File::AbsolutePath(dirPath); + } + + void Directory::SetPattern(const String& pattern) + { + NazaraLock(m_mutex); + + m_pattern = pattern; + } + + bool Directory::Copy(const String& sourcePath, const String& destPath) + { + if (sourcePath.IsEmpty() || destPath.IsEmpty()) + return false; + + String dirPath(sourcePath); + String dest(File::NormalizePath(destPath)); + + if (!Create(destPath, true)) + { + NazaraError("Unable to create \"" + destPath + '"'); + return false; + } + + Directory dir(dirPath); if (!dir.Open()) - return NzDirectoryImpl::Remove(dirPath); // Si on n'arrive pas à ouvrir le dossier, on tente de le supprimer + { + NazaraError("Unable to open \"" + destPath + '"'); + return false; + } while (dir.NextResult(true)) { if (dir.IsResultDirectory()) { - if (!Remove(dir.GetResultPath(), true)) + if (!Copy(dir.GetResultPath(), dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName())) return false; } - else if (!NzFile::Delete(dir.GetResultPath())) + else if (!File::Copy(dir.GetResultPath(), dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName())) { - NazaraError(dir.GetResultPath()); + NazaraError("Failed to copy \"" + dir.GetResultPath() + "\" to \"" + dest + NAZARA_DIRECTORY_SEPARATOR + dir.GetResultName() + '"'); return false; } } dir.Close(); - } - return NzDirectoryImpl::Remove(NzFile::NormalizePath(dirPath)); -} - -bool NzDirectory::SetCurrent(const NzString& dirPath) -{ - NzString path = NzFile::AbsolutePath(dirPath); - if (NzDirectoryImpl::Exists(path)) - { - currentPath = path; return true; } - else - return false; + + bool Directory::Create(const String& dirPath, bool recursive) + { + if (dirPath.IsEmpty()) + return false; + + if (recursive) + { + String path = File::NormalizePath(dirPath); + unsigned int foundPos = path.Find(NAZARA_DIRECTORY_SEPARATOR); + if (foundPos == String::npos) + return false; + + #ifdef NAZARA_PLATFORM_WINDOWS + // Contrairement au disque (Ex: "C:"), le chemin réseau n'est pas considéré comme un dossier (Ex: "\\Laptop") + if (path.Match("\\\\*")) + { + foundPos = path.Find('\\', 2); + if (foundPos == String::npos) + return false; + + foundPos = path.Find('\\', foundPos+1); + if (foundPos == String::npos) + return false; + } + #endif + + do + { + String p = path.SubString(0, foundPos); + if (p.EndsWith(NAZARA_DIRECTORY_SEPARATOR)) + p = p.SubString(0, -2); + + if (!DirectoryImpl::Exists(p) && !DirectoryImpl::Create(p)) + return false; + + if (foundPos == String::npos) + break; + + foundPos = path.Find(NAZARA_DIRECTORY_SEPARATOR, foundPos+1); + } + while (true); + + return true; + } + else + return DirectoryImpl::Create(File::NormalizePath(dirPath)); + } + + bool Directory::Exists(const String& dirPath) + { + if (dirPath.IsEmpty()) + return false; + + return DirectoryImpl::Exists(File::NormalizePath(dirPath)); + } + + String Directory::GetCurrent() + { + return currentPath; + } + + const char* Directory::GetCurrentFileRelativeToEngine(const char* currentFile) + { + ///FIXME: Est-ce que cette méthode est au bon endroit ? + static int offset = -1; + + if (offset < 0) + { + const char* directoryFile = __FILE__; + const char* ptr = std::strstr(directoryFile, "NazaraEngine/src/Nazara/Core/Directory.cpp"); + if (ptr) + offset = ptr - directoryFile; + else + { + ptr = std::strstr(directoryFile, "NazaraEngine\\src\\Nazara\\Core\\Directory.cpp"); + if (ptr) + offset = ptr - directoryFile; + else + offset = 0; + } + } + + return ¤tFile[offset]; + } + + bool Directory::Remove(const String& dirPath, bool emptyDirectory) + { + if (dirPath.IsEmpty()) + return false; + + if (emptyDirectory) + { + Directory dir(dirPath); + if (!dir.Open()) + return DirectoryImpl::Remove(dirPath); // Si on n'arrive pas à ouvrir le dossier, on tente de le supprimer + + while (dir.NextResult(true)) + { + if (dir.IsResultDirectory()) + { + if (!Remove(dir.GetResultPath(), true)) + return false; + } + else if (!File::Delete(dir.GetResultPath())) + { + NazaraError(dir.GetResultPath()); + return false; + } + } + + dir.Close(); + } + + return DirectoryImpl::Remove(File::NormalizePath(dirPath)); + } + + bool Directory::SetCurrent(const String& dirPath) + { + String path = File::AbsolutePath(dirPath); + if (DirectoryImpl::Exists(path)) + { + currentPath = path; + return true; + } + else + return false; + } } diff --git a/src/Nazara/Core/DynLib.cpp b/src/Nazara/Core/DynLib.cpp index 13182213a..39539e7ed 100644 --- a/src/Nazara/Core/DynLib.cpp +++ b/src/Nazara/Core/DynLib.cpp @@ -23,88 +23,91 @@ #include -NzDynLib::NzDynLib() : -m_impl(nullptr) +namespace Nz { -} - -NzDynLib::NzDynLib(NzDynLib&& lib) : -m_lastError(std::move(lib.m_lastError)), -m_impl(lib.m_impl) -{ - lib.m_impl = nullptr; -} - -NzDynLib::~NzDynLib() -{ - Unload(); -} - -NzString NzDynLib::GetLastError() const -{ - NazaraLock(m_mutex) - - return m_lastError; -} - -NzDynLibFunc NzDynLib::GetSymbol(const NzString& symbol) const -{ - NazaraLock(m_mutex) - - #if NAZARA_CORE_SAFE - if (!m_impl) + DynLib::DynLib() : + m_impl(nullptr) { - NazaraError("Library not opened"); - return nullptr; - } - #endif - - return m_impl->GetSymbol(symbol, &m_lastError); -} - -bool NzDynLib::IsLoaded() const -{ - return m_impl != nullptr; -} - -bool NzDynLib::Load(const NzString& libraryPath) -{ - NazaraLock(m_mutex) - - Unload(); - - std::unique_ptr impl(new NzDynLibImpl(this)); - if (!impl->Load(libraryPath, &m_lastError)) - { - NazaraError("Failed to load library: " + m_lastError); - return false; } - m_impl = impl.release(); - - return true; -} - -void NzDynLib::Unload() -{ - NazaraLock(m_mutex) - - if (m_impl) + DynLib::DynLib(DynLib&& lib) : + m_lastError(std::move(lib.m_lastError)), + m_impl(lib.m_impl) { - m_impl->Unload(); - delete m_impl; - m_impl = nullptr; + lib.m_impl = nullptr; + } + + DynLib::~DynLib() + { + Unload(); + } + + String DynLib::GetLastError() const + { + NazaraLock(m_mutex) + + return m_lastError; + } + + DynLibFunc DynLib::GetSymbol(const String& symbol) const + { + NazaraLock(m_mutex) + + #if NAZARA_CORE_SAFE + if (!m_impl) + { + NazaraError("Library not opened"); + return nullptr; + } + #endif + + return m_impl->GetSymbol(symbol, &m_lastError); + } + + bool DynLib::IsLoaded() const + { + return m_impl != nullptr; + } + + bool DynLib::Load(const String& libraryPath) + { + NazaraLock(m_mutex) + + Unload(); + + std::unique_ptr impl(new DynLibImpl(this)); + if (!impl->Load(libraryPath, &m_lastError)) + { + NazaraError("Failed to load library: " + m_lastError); + return false; + } + + m_impl = impl.release(); + + return true; + } + + void DynLib::Unload() + { + NazaraLock(m_mutex) + + if (m_impl) + { + m_impl->Unload(); + delete m_impl; + m_impl = nullptr; + } + } + + DynLib& DynLib::operator=(DynLib&& lib) + { + Unload(); + + m_impl = lib.m_impl; + m_lastError = std::move(lib.m_lastError); + + lib.m_impl = nullptr; + + return *this; } } - -NzDynLib& NzDynLib::operator=(NzDynLib&& lib) -{ - Unload(); - - m_impl = lib.m_impl; - m_lastError = std::move(lib.m_lastError); - - lib.m_impl = nullptr; - - return *this; -} diff --git a/src/Nazara/Core/Error.cpp b/src/Nazara/Core/Error.cpp index 845dab5ed..07b8521b6 100644 --- a/src/Nazara/Core/Error.cpp +++ b/src/Nazara/Core/Error.cpp @@ -16,112 +16,115 @@ #include -void NzError::Error(nzErrorType type, const NzString& error) +namespace Nz { - if (type == nzErrorType_AssertFailed || (s_flags & nzErrorFlag_Silent) == 0 || (s_flags & nzErrorFlag_SilentDisabled) != 0) - NazaraLog->WriteError(type, error); + UInt32 Error::GetFlags() + { + return s_flags; + } - s_lastError = error; - s_lastErrorFile = ""; - s_lastErrorFunction = ""; - s_lastErrorLine = 0; + String Error::GetLastError(const char** file, unsigned int* line, const char** function) + { + if (file) + *file = s_lastErrorFile; - #if NAZARA_CORE_EXIT_ON_ASSERT_FAILURE - if (type == nzErrorType_AssertFailed) - std::abort(); - #endif + if (line) + *line = s_lastErrorLine; - if (type == nzErrorType_AssertFailed || (type != nzErrorType_Warning && - (s_flags & nzErrorFlag_ThrowException) != 0 && (s_flags & nzErrorFlag_ThrowExceptionDisabled) == 0)) - throw std::runtime_error(error); + if (function) + *function = s_lastErrorFunction; + + return s_lastError; + } + + unsigned int Error::GetLastSystemErrorCode() + { + #if defined(NAZARA_PLATFORM_WINDOWS) + return ::GetLastError(); + #elif defined(NAZARA_PLATFORM_POSIX) + return errno; + #else + #error GetLastSystemErrorCode is not implemented on this platform + return 0; + #endif + } + + String Error::GetLastSystemError(unsigned int code) + { + #if defined(NAZARA_PLATFORM_WINDOWS) + wchar_t* buffer = nullptr; + + FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, + code, + 0, + reinterpret_cast(&buffer), + 0, + nullptr); + + String error(String::Unicode(buffer)); + LocalFree(buffer); + + error.Trim(); // Pour une raison inconnue, Windows met deux-trois retours à la ligne après le message + + return error; + #elif defined(NAZARA_PLATFORM_POSIX) + return std::strerror(code); + #else + #error GetLastSystemError is not implemented on this platform + + return String("GetLastSystemError is not implemented on this platform"); + #endif + } + + void Error::SetFlags(UInt32 flags) + { + s_flags = flags; + } + + void Error::Trigger(ErrorType type, const String& error) + { + if (type == ErrorType_AssertFailed || (s_flags & ErrorFlag_Silent) == 0 || (s_flags & ErrorFlag_SilentDisabled) != 0) + NazaraLog->WriteError(type, error); + + s_lastError = error; + s_lastErrorFile = ""; + s_lastErrorFunction = ""; + s_lastErrorLine = 0; + + #if NAZARA_CORE_EXIT_ON_ASSERT_FAILURE + if (type == ErrorType_AssertFailed) + std::abort(); + #endif + + if (type == ErrorType_AssertFailed || (type != ErrorType_Warning && + (s_flags & ErrorFlag_ThrowException) != 0 && (s_flags & ErrorFlag_ThrowExceptionDisabled) == 0)) + throw std::runtime_error(error); + } + + void Error::Trigger(ErrorType type, const String& error, unsigned int line, const char* file, const char* function) + { + if (type == ErrorType_AssertFailed || (s_flags & ErrorFlag_Silent) == 0 || (s_flags & ErrorFlag_SilentDisabled) != 0) + NazaraLog->WriteError(type, error, line, file, function); + + s_lastError = error; + s_lastErrorFile = file; + s_lastErrorFunction = function; + s_lastErrorLine = line; + + #if NAZARA_CORE_EXIT_ON_ASSERT_FAILURE + if (type == ErrorType_AssertFailed) + std::abort(); + #endif + + if (type == ErrorType_AssertFailed || (type != ErrorType_Warning && + (s_flags & ErrorFlag_ThrowException) != 0 && (s_flags & ErrorFlag_ThrowExceptionDisabled) == 0)) + throw std::runtime_error(error); + } + + UInt32 Error::s_flags = ErrorFlag_None; + String Error::s_lastError; + const char* Error::s_lastErrorFunction = ""; + const char* Error::s_lastErrorFile = ""; + unsigned int Error::s_lastErrorLine = 0; } - -void NzError::Error(nzErrorType type, const NzString& error, unsigned int line, const char* file, const char* function) -{ - if (type == nzErrorType_AssertFailed || (s_flags & nzErrorFlag_Silent) == 0 || (s_flags & nzErrorFlag_SilentDisabled) != 0) - NazaraLog->WriteError(type, error, line, file, function); - - s_lastError = error; - s_lastErrorFile = file; - s_lastErrorFunction = function; - s_lastErrorLine = line; - - #if NAZARA_CORE_EXIT_ON_ASSERT_FAILURE - if (type == nzErrorType_AssertFailed) - std::abort(); - #endif - - if (type == nzErrorType_AssertFailed || (type != nzErrorType_Warning && - (s_flags & nzErrorFlag_ThrowException) != 0 && (s_flags & nzErrorFlag_ThrowExceptionDisabled) == 0)) - throw std::runtime_error(error); -} - -nzUInt32 NzError::GetFlags() -{ - return s_flags; -} - -NzString NzError::GetLastError(const char** file, unsigned int* line, const char** function) -{ - if (file) - *file = s_lastErrorFile; - - if (line) - *line = s_lastErrorLine; - - if (function) - *function = s_lastErrorFunction; - - return s_lastError; -} - -unsigned int NzError::GetLastSystemErrorCode() -{ - #if defined(NAZARA_PLATFORM_WINDOWS) - return ::GetLastError(); - #elif defined(NAZARA_PLATFORM_POSIX) - return errno; - #else - #error GetLastSystemErrorCode is not implemented on this platform - return 0; - #endif -} - -NzString NzError::GetLastSystemError(unsigned int code) -{ - #if defined(NAZARA_PLATFORM_WINDOWS) - wchar_t* buffer = nullptr; - - FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, - nullptr, - code, - 0, - reinterpret_cast(&buffer), - 0, - nullptr); - - NzString error(NzString::Unicode(buffer)); - LocalFree(buffer); - - error.Trim(); // Pour une raison inconnue, Windows met deux-trois retours à la ligne après le message - - return error; - #elif defined(NAZARA_PLATFORM_POSIX) - return std::strerror(code); - #else - #error GetLastSystemError is not implemented on this platform - - return NzString("GetLastSystemError is not implemented on this platform"); - #endif -} - -void NzError::SetFlags(nzUInt32 flags) -{ - s_flags = flags; -} - -nzUInt32 NzError::s_flags = nzErrorFlag_None; -NzString NzError::s_lastError; -const char* NzError::s_lastErrorFunction = ""; -const char* NzError::s_lastErrorFile = ""; -unsigned int NzError::s_lastErrorLine = 0; diff --git a/src/Nazara/Core/ErrorFlags.cpp b/src/Nazara/Core/ErrorFlags.cpp index 15a298087..08c1d3e19 100644 --- a/src/Nazara/Core/ErrorFlags.cpp +++ b/src/Nazara/Core/ErrorFlags.cpp @@ -6,26 +6,29 @@ #include #include -NzErrorFlags::NzErrorFlags(nzUInt32 flags, bool replace) : -m_previousFlags(NzError::GetFlags()) +namespace Nz { - SetFlags(flags, replace); -} + ErrorFlags::ErrorFlags(UInt32 flags, bool replace) : + m_previousFlags(Error::GetFlags()) + { + SetFlags(flags, replace); + } -NzErrorFlags::~NzErrorFlags() -{ - NzError::SetFlags(m_previousFlags); -} + ErrorFlags::~ErrorFlags() + { + Error::SetFlags(m_previousFlags); + } -nzUInt32 NzErrorFlags::GetPreviousFlags() const -{ - return m_previousFlags; -} + UInt32 ErrorFlags::GetPreviousFlags() const + { + return m_previousFlags; + } -void NzErrorFlags::SetFlags(nzUInt32 flags, bool replace) -{ - if (!replace) - flags |= m_previousFlags; + void ErrorFlags::SetFlags(UInt32 flags, bool replace) + { + if (!replace) + flags |= m_previousFlags; - NzError::SetFlags(flags); + Error::SetFlags(flags); + } } diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 05ca09a95..2a72262bb 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -29,714 +29,717 @@ #include -NzFile::NzFile() : -m_endianness(nzEndianness_Unknown), -m_impl(nullptr), -m_openMode(nzOpenMode_Current) +namespace Nz { -} - -NzFile::NzFile(const NzString& filePath) : -m_endianness(nzEndianness_Unknown), -m_impl(nullptr), -m_openMode(nzOpenMode_Current) -{ - SetFile(filePath); -} - -NzFile::NzFile(const NzString& filePath, unsigned int openMode) : -m_endianness(nzEndianness_Unknown), -m_impl(nullptr), -m_openMode(openMode) -{ - Open(filePath, openMode); -} - -NzFile::NzFile(NzFile&& file) noexcept : -m_endianness(file.m_endianness), -m_filePath(std::move(file.m_filePath)), -m_impl(file.m_impl), -m_openMode(file.m_openMode) -{ - file.m_impl = nullptr; -} - -NzFile::~NzFile() -{ - Close(); -} - -bool NzFile::Copy(const NzString& newFilePath) -{ - return Copy(m_filePath, newFilePath); -} - -void NzFile::Close() -{ - NazaraLock(m_mutex) - - if (m_impl) + File::File() : + m_endianness(Endianness_Unknown), + m_impl(nullptr), + m_openMode(OpenMode_Current) { - m_impl->Close(); - delete m_impl; - m_impl = nullptr; - } -} - -bool NzFile::Delete() -{ - NazaraLock(m_mutex) - - Close(); - - return Delete(m_filePath); -} - -bool NzFile::EndOfFile() const -{ - NazaraLock(m_mutex) - - #if NAZARA_CORE_SAFE - if (!IsOpen()) - { - NazaraError("File not opened"); - return false; - } - #endif - - return m_impl->EndOfFile(); -} - -bool NzFile::EndOfStream() const -{ - return EndOfFile(); -} - -bool NzFile::Exists() const -{ - NazaraLock(m_mutex) - - if (IsOpen()) - return true; // Le fichier est ouvert, donc il existe - else - return Exists(m_filePath); -} - -void NzFile::Flush() -{ - NazaraLock(m_mutex) - - #if NAZARA_CORE_SAFE - if (!IsOpen()) - { - NazaraError("File not opened"); - return; } - if ((m_openMode & nzOpenMode_ReadWrite) == 0 && (m_openMode & nzOpenMode_WriteOnly) == 0) + File::File(const String& filePath) : + m_endianness(Endianness_Unknown), + m_impl(nullptr), + m_openMode(OpenMode_Current) { - NazaraError("Cannot flush file without write access"); - return; - } - #endif - - m_impl->Flush(); -} - -time_t NzFile::GetCreationTime() const -{ - NazaraLock(m_mutex) - - return GetCreationTime(m_filePath); -} - -nzUInt64 NzFile::GetCursorPos() const -{ - NazaraLock(m_mutex) - - #if NAZARA_CORE_SAFE - if (!IsOpen()) - { - NazaraError("File not opened"); - return false; - } - #endif - - return m_impl->GetCursorPos(); -} - -NzString NzFile::GetDirectory() const -{ - NazaraLock(m_mutex) - - return m_filePath.SubStringTo(NAZARA_DIRECTORY_SEPARATOR, -1, true, true); -} - -NzString NzFile::GetFileName() const -{ - NazaraLock(m_mutex) - - return m_filePath.SubStringFrom(NAZARA_DIRECTORY_SEPARATOR, -1, true); -} - -time_t NzFile::GetLastAccessTime() const -{ - NazaraLock(m_mutex) - - return GetLastAccessTime(m_filePath); -} - -time_t NzFile::GetLastWriteTime() const -{ - NazaraLock(m_mutex) - - return GetLastWriteTime(m_filePath); -} - -NzString NzFile::GetPath() const -{ - NazaraLock(m_mutex) - - return m_filePath; -} - -nzUInt64 NzFile::GetSize() const -{ - NazaraLock(m_mutex) - - return GetSize(m_filePath); -} - -bool NzFile::IsOpen() const -{ - NazaraLock(m_mutex) - - return m_impl != nullptr; -} - -std::size_t NzFile::Read(void* buffer, std::size_t size) -{ - NazaraLock(m_mutex) - - #if NAZARA_CORE_SAFE - if (!IsOpen()) - { - NazaraError("File not opened"); - return 0; + SetFile(filePath); } - if ((m_openMode & nzOpenMode_ReadOnly) == 0 && (m_openMode & nzOpenMode_ReadWrite) == 0) + File::File(const String& filePath, unsigned int openMode) : + m_endianness(Endianness_Unknown), + m_impl(nullptr), + m_openMode(openMode) { - NazaraError("File not opened with read access"); - return 0; - } - #endif - - if (size == 0) - return 0; - - if (buffer) - return m_impl->Read(buffer, size); - else - { - // Si nous ne devons rien lire, nous avançons simplement - nzUInt64 currentPos = m_impl->GetCursorPos(); - - m_impl->SetCursorPos(nzCursorPosition_AtCurrent, size); - - return static_cast(m_impl->GetCursorPos()-currentPos); - } -} - -std::size_t NzFile::Read(void* buffer, std::size_t typeSize, unsigned int count) -{ - std::size_t byteRead = Read(buffer, typeSize*count); - if (byteRead == 0) - return 0; - - if (buffer && typeSize != 1 && m_endianness != nzEndianness_Unknown && m_endianness != NzGetPlatformEndianness()) - { - unsigned int typeCount = byteRead/typeSize; - for (unsigned int i = 0; i < typeCount; ++i) - NzByteSwap(reinterpret_cast(buffer) + i*typeSize, typeSize); + Open(filePath, openMode); } - return byteRead; -} + File::File(File&& file) noexcept : + m_endianness(file.m_endianness), + m_filePath(std::move(file.m_filePath)), + m_impl(file.m_impl), + m_openMode(file.m_openMode) + { + file.m_impl = nullptr; + } -bool NzFile::Rename(const NzString& newFilePath) -{ - NazaraLock(m_mutex) + File::~File() + { + Close(); + } - bool opened = IsOpen(); - Close(); + bool File::Copy(const String& newFilePath) + { + return Copy(m_filePath, newFilePath); + } - bool success = Rename(m_filePath, newFilePath); - if (success) - m_filePath = NormalizePath(newFilePath); + void File::Close() + { + NazaraLock(m_mutex) - if (opened) - Open(); + if (m_impl) + { + m_impl->Close(); + delete m_impl; + m_impl = nullptr; + } + } - return success; -} + bool File::Delete() + { + NazaraLock(m_mutex) -bool NzFile::Open(unsigned int openMode) -{ - NazaraLock(m_mutex) + Close(); - Close(); + return Delete(m_filePath); + } - if (m_filePath.IsEmpty()) - return false; + bool File::EndOfFile() const + { + NazaraLock(m_mutex) + + #if NAZARA_CORE_SAFE + if (!IsOpen()) + { + NazaraError("File not opened"); + return false; + } + #endif + + return m_impl->EndOfFile(); + } + + bool File::EndOfStream() const + { + return EndOfFile(); + } + + bool File::Exists() const + { + NazaraLock(m_mutex) + + if (IsOpen()) + return true; // Le fichier est ouvert, donc il existe + else + return Exists(m_filePath); + } + + void File::Flush() + { + NazaraLock(m_mutex) + + #if NAZARA_CORE_SAFE + if (!IsOpen()) + { + NazaraError("File not opened"); + return; + } + + if ((m_openMode & OpenMode_ReadWrite) == 0 && (m_openMode & OpenMode_WriteOnly) == 0) + { + NazaraError("Cannot flush file without write access"); + return; + } + #endif + + m_impl->Flush(); + } + + time_t File::GetCreationTime() const + { + NazaraLock(m_mutex) + + return GetCreationTime(m_filePath); + } + + UInt64 File::GetCursorPos() const + { + NazaraLock(m_mutex) + + #if NAZARA_CORE_SAFE + if (!IsOpen()) + { + NazaraError("File not opened"); + return false; + } + #endif + + return m_impl->GetCursorPos(); + } + + String File::GetDirectory() const + { + NazaraLock(m_mutex) + + return m_filePath.SubStringTo(NAZARA_DIRECTORY_SEPARATOR, -1, true, true); + } + + String File::GetFileName() const + { + NazaraLock(m_mutex) + + return m_filePath.SubStringFrom(NAZARA_DIRECTORY_SEPARATOR, -1, true); + } + + time_t File::GetLastAccessTime() const + { + NazaraLock(m_mutex) + + return GetLastAccessTime(m_filePath); + } + + time_t File::GetLastWriteTime() const + { + NazaraLock(m_mutex) + + return GetLastWriteTime(m_filePath); + } + + String File::GetPath() const + { + NazaraLock(m_mutex) + + return m_filePath; + } + + UInt64 File::GetSize() const + { + NazaraLock(m_mutex) + + return GetSize(m_filePath); + } + + bool File::IsOpen() const + { + NazaraLock(m_mutex) + + return m_impl != nullptr; + } + + std::size_t File::Read(void* buffer, std::size_t size) + { + NazaraLock(m_mutex) + + #if NAZARA_CORE_SAFE + if (!IsOpen()) + { + NazaraError("File not opened"); + return 0; + } + + if ((m_openMode & OpenMode_ReadOnly) == 0 && (m_openMode & OpenMode_ReadWrite) == 0) + { + NazaraError("File not opened with read access"); + return 0; + } + #endif + + if (size == 0) + return 0; + + if (buffer) + return m_impl->Read(buffer, size); + else + { + // Si nous ne devons rien lire, nous avançons simplement + UInt64 currentPos = m_impl->GetCursorPos(); + + m_impl->SetCursorPos(CursorPosition_AtCurrent, size); + + return static_cast(m_impl->GetCursorPos()-currentPos); + } + } + + std::size_t File::Read(void* buffer, std::size_t typeSize, unsigned int count) + { + std::size_t byteRead = Read(buffer, typeSize*count); + if (byteRead == 0) + return 0; + + if (buffer && typeSize != 1 && m_endianness != Endianness_Unknown && m_endianness != GetPlatformEndianness()) + { + unsigned int typeCount = byteRead/typeSize; + for (unsigned int i = 0; i < typeCount; ++i) + SwapBytes(reinterpret_cast(buffer) + i*typeSize, typeSize); + } + + return byteRead; + } + + bool File::Rename(const String& newFilePath) + { + NazaraLock(m_mutex) + + bool opened = IsOpen(); + Close(); + + bool success = Rename(m_filePath, newFilePath); + if (success) + m_filePath = NormalizePath(newFilePath); + + if (opened) + Open(); + + return success; + } + + bool File::Open(unsigned int openMode) + { + NazaraLock(m_mutex) + + Close(); + + if (m_filePath.IsEmpty()) + return false; + + if (openMode != 0) + m_openMode = openMode; + + if (m_openMode == 0) + return false; + + std::unique_ptr impl(new FileImpl(this)); + if (!impl->Open(m_filePath, m_openMode)) + { + ErrorFlags flags(ErrorFlag_Silent); // Silencieux par défaut + NazaraError("Failed to open \"" + m_filePath + "\": " + Error::GetLastSystemError()); + return false; + } + + m_impl = impl.release(); + + if (m_openMode & OpenMode_Text) + m_streamOptions |= StreamOption_Text; + + return true; + } + + bool File::Open(const String& filePath, unsigned int openMode) + { + NazaraLock(m_mutex) + + Close(); + + SetFile(filePath); + return Open(openMode); + } + + bool File::SetCursorPos(CursorPosition pos, Int64 offset) + { + NazaraLock(m_mutex) + + #if NAZARA_CORE_SAFE + if (!IsOpen()) + { + NazaraError("File not opened"); + return false; + } + #endif + + return m_impl->SetCursorPos(pos, offset); + } + + bool File::SetCursorPos(UInt64 offset) + { + NazaraLock(m_mutex) + + #if NAZARA_CORE_SAFE + if (!IsOpen()) + { + NazaraError("File not opened"); + return false; + } + #endif + + return m_impl->SetCursorPos(CursorPosition_AtBegin, offset); + } + + void File::SetEndianness(Endianness endianness) + { + NazaraLock(m_mutex) + + m_endianness = endianness; + } + + bool File::SetFile(const String& filePath) + { + NazaraLock(m_mutex) + + if (IsOpen()) + { + if (filePath.IsEmpty()) + return false; + + std::unique_ptr impl(new FileImpl(this)); + if (!impl->Open(filePath, m_openMode)) + { + NazaraError("Failed to open new file; " + Error::GetLastSystemError()); + return false; + } + + m_impl->Close(); + delete m_impl; + + m_impl = impl.release(); + } + + m_filePath = AbsolutePath(filePath); + return true; + } + + bool File::SetOpenMode(unsigned int openMode) + { + NazaraLock(m_mutex) + + if (openMode == OpenMode_Current || openMode == m_openMode) + return true; + + if (IsOpen()) + { + std::unique_ptr impl(new FileImpl(this)); + if (!impl->Open(m_filePath, openMode)) + { + NazaraError("Failed to open file with new mode: " + Error::GetLastSystemError()); + return false; + } + + m_impl->Close(); + delete m_impl; + + m_impl = impl.release(); + + if (m_openMode & OpenMode_Text) + m_streamOptions |= StreamOption_Text; + } - if (openMode != 0) m_openMode = openMode; - if (m_openMode == 0) - return false; - - std::unique_ptr impl(new NzFileImpl(this)); - if (!impl->Open(m_filePath, m_openMode)) - { - NzErrorFlags flags(nzErrorFlag_Silent); // Silencieux par défaut - NazaraError("Failed to open \"" + m_filePath + "\": " + NzError::GetLastSystemError()); - return false; + return true; } - m_impl = impl.release(); - - if (m_openMode & nzOpenMode_Text) - m_streamOptions |= nzStreamOption_Text; - - return true; -} - -bool NzFile::Open(const NzString& filePath, unsigned int openMode) -{ - NazaraLock(m_mutex) - - Close(); - - SetFile(filePath); - return Open(openMode); -} - -bool NzFile::SetCursorPos(nzCursorPosition pos, nzInt64 offset) -{ - NazaraLock(m_mutex) - - #if NAZARA_CORE_SAFE - if (!IsOpen()) + bool File::Write(const ByteArray& byteArray) { - NazaraError("File not opened"); - return false; + ByteArray::size_type size = byteArray.GetSize(); + return Write(byteArray.GetConstBuffer(), 1, size) == size; } - #endif - return m_impl->SetCursorPos(pos, offset); -} - -bool NzFile::SetCursorPos(nzUInt64 offset) -{ - NazaraLock(m_mutex) - - #if NAZARA_CORE_SAFE - if (!IsOpen()) + bool File::Write(const String& string) { - NazaraError("File not opened"); - return false; + String temp(string); + + if (m_streamOptions & StreamOption_Text) + { + #if defined(NAZARA_PLATFORM_WINDOWS) + temp.Replace("\n", "\r\n"); + #elif defined(NAZARA_PLATFORM_LINUX) + // Rien à faire + #elif defined(NAZARA_PLATFORM_MACOS) + temp.Replace('\n', '\r'); + #else + #error OS not handled + #endif + } + + unsigned int size = temp.GetSize(); + std::size_t bytesWritten = Write(temp.GetBuffer(), sizeof(char), size); + + return bytesWritten == size*sizeof(char); } - #endif - return m_impl->SetCursorPos(nzCursorPosition_AtBegin, offset); -} + std::size_t File::Write(const void* buffer, std::size_t typeSize, unsigned int count) + { + NazaraLock(m_mutex) -void NzFile::SetEndianness(nzEndianness endianness) -{ - NazaraLock(m_mutex) + #if NAZARA_CORE_SAFE + if (!IsOpen()) + { + NazaraError("File not opened"); + return 0; + } - m_endianness = endianness; -} + if ((m_openMode & OpenMode_ReadWrite) == 0 && (m_openMode & OpenMode_WriteOnly) == 0) + { + NazaraError("File not opened with write access"); + return 0; + } + #endif -bool NzFile::SetFile(const NzString& filePath) -{ - NazaraLock(m_mutex) + if (!buffer || count == 0 || typeSize == 0) + return 0; - if (IsOpen()) + std::size_t bytesWritten; + if (m_endianness != Endianness_Unknown && m_endianness != GetPlatformEndianness() && typeSize != 1) + { + std::unique_ptr buf(new char[count*typeSize]); + std::memcpy(buf.get(), buffer, count*typeSize); + + for (unsigned int i = 0; i < count; ++i) + SwapBytes(&buf[i*typeSize], typeSize); + + bytesWritten = m_impl->Write(buf.get(), count*typeSize); + } + else + bytesWritten = m_impl->Write(buffer, count*typeSize); + + return bytesWritten; + } + + File& File::operator=(const String& filePath) + { + SetFile(filePath); + + return *this; + } + + File& File::operator=(File&& file) noexcept + { + NazaraLock(m_mutex) + + std::swap(m_endianness, file.m_endianness); + std::swap(m_filePath, file.m_filePath); + std::swap(m_impl, file.m_impl); + std::swap(m_openMode, file.m_openMode); + + return *this; + } + + String File::AbsolutePath(const String& filePath) + { + // Je n'utilise pas les fonctions de l'OS car elles ne fonctionnent que pour un chemin existant + String path = NormalizePath(filePath); + if (path.IsEmpty()) + return String(); + + String base; + unsigned int start; + #ifdef NAZARA_PLATFORM_WINDOWS + if (path.Match("?:*")) + start = 1; + else if (path.Match("\\\\*")) + { + base = "\\\\"; + start = 2; + } + else if (path.StartsWith('\\')) // Spécial : '\' fait référence au disque racine + { + String drive = Directory::GetCurrent().SubStringTo('\\'); + String end = path.SubString(1, -1); + if (end.IsEmpty()) + path = drive; + else + path = drive + '\\' + end; + + start = 1; + } + else + { + NazaraError("Path unrecognized"); + return path; + } + #elif defined(NAZARA_PLATFORM_POSIX) + base = '/'; + start = 0; + #else + #error OS case not implemented + #endif + + static String upDir = NAZARA_DIRECTORY_SEPARATOR + String('.'); + + if (path.Find(upDir) == String::npos) + return path; + + std::vector sep; + if (path.Split(sep, NAZARA_DIRECTORY_SEPARATOR) <= 1) + return path; + + // Nous avons un chemin absolu, mais il nous faut un peu le nettoyer + for (unsigned int i = 0; i < sep.size(); ++i) + { + if (sep[i] == '.') + sep.erase(sep.begin() + i--); + else if (sep[i] == "..") + { + if (i > start) // Si nous ne sommes pas dans la partie protégée + sep.erase(sep.begin() + i--); + + sep.erase(sep.begin() + i--); + } + } + + StringStream stream(base); + for (unsigned int i = 0; i < sep.size(); ++i) + { + if (i != sep.size()-1) + stream << sep[i] << NAZARA_DIRECTORY_SEPARATOR; + else + stream << sep[i]; + } + + return stream; + } + + bool File::Copy(const String& sourcePath, const String& targetPath) + { + if (sourcePath.IsEmpty() || targetPath.IsEmpty()) + return false; + + return FileImpl::Copy(NormalizePath(sourcePath), NormalizePath(targetPath)); + } + + bool File::Delete(const String& filePath) { if (filePath.IsEmpty()) return false; - std::unique_ptr impl(new NzFileImpl(this)); - if (!impl->Open(filePath, m_openMode)) - { - NazaraError("Failed to open new file; " + NzError::GetLastSystemError()); - return false; - } - - m_impl->Close(); - delete m_impl; - - m_impl = impl.release(); + return FileImpl::Delete(NormalizePath(filePath)); } - m_filePath = AbsolutePath(filePath); - return true; -} - -bool NzFile::SetOpenMode(unsigned int openMode) -{ - NazaraLock(m_mutex) - - if (openMode == nzOpenMode_Current || openMode == m_openMode) - return true; - - if (IsOpen()) + bool File::Exists(const String& filePath) { - std::unique_ptr impl(new NzFileImpl(this)); - if (!impl->Open(m_filePath, openMode)) - { - NazaraError("Failed to open file with new mode: " + NzError::GetLastSystemError()); + if (filePath.IsEmpty()) return false; - } - m_impl->Close(); - delete m_impl; - - m_impl = impl.release(); - - if (m_openMode & nzOpenMode_Text) - m_streamOptions |= nzStreamOption_Text; + return FileImpl::Exists(NormalizePath(filePath)); } - m_openMode = openMode; - - return true; -} - -bool NzFile::Write(const NzByteArray& byteArray) -{ - NzByteArray::size_type size = byteArray.GetSize(); - return Write(byteArray.GetConstBuffer(), 1, size) == size; -} - -bool NzFile::Write(const NzString& string) -{ - NzString temp(string); - - if (m_streamOptions & nzStreamOption_Text) + time_t File::GetCreationTime(const String& filePath) { - #if defined(NAZARA_PLATFORM_WINDOWS) - temp.Replace("\n", "\r\n"); - #elif defined(NAZARA_PLATFORM_LINUX) - // Rien à faire - #elif defined(NAZARA_PLATFORM_MACOS) - temp.Replace('\n', '\r'); + if (filePath.IsEmpty()) + return 0; + + return FileImpl::GetCreationTime(NormalizePath(filePath)); + } + + String File::GetDirectory(const String& filePath) + { + return filePath.SubStringTo(NAZARA_DIRECTORY_SEPARATOR, -1, true, true); + } + + time_t File::GetLastAccessTime(const String& filePath) + { + if (filePath.IsEmpty()) + return 0; + + return FileImpl::GetLastAccessTime(NormalizePath(filePath)); + } + + time_t File::GetLastWriteTime(const String& filePath) + { + if (filePath.IsEmpty()) + return 0; + + return FileImpl::GetLastWriteTime(NormalizePath(filePath)); + } + + HashDigest File::GetHash(const String& filePath, HashType hash) + { + File file(filePath); + + Hash h(hash); + return h.Process(file); + } + + HashDigest File::GetHash(const String& filePath, AbstractHash* hash) + { + File file(filePath); + + Hash h(hash); + return h.Process(file); + } + + UInt64 File::GetSize(const String& filePath) + { + if (filePath.IsEmpty()) + return 0; + + return FileImpl::GetSize(NormalizePath(filePath)); + } + + bool File::IsAbsolute(const String& filePath) + { + String path(filePath.Trimmed()); + if (path.IsEmpty()) + return false; + + path = NormalizeSeparators(path); + + #ifdef NAZARA_PLATFORM_WINDOWS + if (path.Match("?:*")) // Ex: C:\Hello + return true; + else if (path.Match("\\\\*")) // Ex: \\Laptop + return true; + else if (path.StartsWith('\\')) // Spécial : '\' fait référence au disque racine + return true; + else + return false; + #elif defined(NAZARA_PLATFORM_POSIX) + return path.StartsWith('/'); #else - #error OS not handled + #error OS case not implemented #endif } - unsigned int size = temp.GetSize(); - std::size_t bytesWritten = Write(temp.GetBuffer(), sizeof(char), size); - - return bytesWritten == size*sizeof(char); -} - -std::size_t NzFile::Write(const void* buffer, std::size_t typeSize, unsigned int count) -{ - NazaraLock(m_mutex) - - #if NAZARA_CORE_SAFE - if (!IsOpen()) + String File::NormalizePath(const String& filePath) { - NazaraError("File not opened"); - return 0; - } + String path = NormalizeSeparators(filePath.Trimmed()); - if ((m_openMode & nzOpenMode_ReadWrite) == 0 && (m_openMode & nzOpenMode_WriteOnly) == 0) - { - NazaraError("File not opened with write access"); - return 0; - } - #endif + if (!IsAbsolute(path)) + path = Directory::GetCurrent() + NAZARA_DIRECTORY_SEPARATOR + path; - if (!buffer || count == 0 || typeSize == 0) - return 0; + while (path.EndsWith(NAZARA_DIRECTORY_SEPARATOR)) + path.Resize(-1); - std::size_t bytesWritten; - if (m_endianness != nzEndianness_Unknown && m_endianness != NzGetPlatformEndianness() && typeSize != 1) - { - std::unique_ptr buf(new char[count*typeSize]); - std::memcpy(buf.get(), buffer, count*typeSize); - - for (unsigned int i = 0; i < count; ++i) - NzByteSwap(&buf[i*typeSize], typeSize); - - bytesWritten = m_impl->Write(buf.get(), count*typeSize); - } - else - bytesWritten = m_impl->Write(buffer, count*typeSize); - - return bytesWritten; -} - -NzFile& NzFile::operator=(const NzString& filePath) -{ - SetFile(filePath); - - return *this; -} - -NzFile& NzFile::operator=(NzFile&& file) noexcept -{ - NazaraLock(m_mutex) - - std::swap(m_endianness, file.m_endianness); - std::swap(m_filePath, file.m_filePath); - std::swap(m_impl, file.m_impl); - std::swap(m_openMode, file.m_openMode); - - return *this; -} - -NzString NzFile::AbsolutePath(const NzString& filePath) -{ - // Je n'utilise pas les fonctions de l'OS car elles ne fonctionnent que pour un chemin existant - NzString path = NormalizePath(filePath); - if (path.IsEmpty()) - return NzString(); - - NzString base; - unsigned int start; - #ifdef NAZARA_PLATFORM_WINDOWS - if (path.Match("?:*")) - start = 1; - else if (path.Match("\\\\*")) - { - base = "\\\\"; - start = 2; - } - else if (path.StartsWith('\\')) // Spécial : '\' fait référence au disque racine - { - NzString drive = NzDirectory::GetCurrent().SubStringTo('\\'); - NzString end = path.SubString(1, -1); - if (end.IsEmpty()) - path = drive; - else - path = drive + '\\' + end; - - start = 1; - } - else - { - NazaraError("Path unrecognized"); return path; } - #elif defined(NAZARA_PLATFORM_POSIX) - base = '/'; - start = 0; - #else - #error OS case not implemented - #endif - static NzString upDir = NAZARA_DIRECTORY_SEPARATOR + NzString('.'); - - if (path.Find(upDir) == NzString::npos) - return path; - - std::vector sep; - if (path.Split(sep, NAZARA_DIRECTORY_SEPARATOR) <= 1) - return path; - - // Nous avons un chemin absolu, mais il nous faut un peu le nettoyer - for (unsigned int i = 0; i < sep.size(); ++i) + String File::NormalizeSeparators(const String& filePath) { - if (sep[i] == '.') - sep.erase(sep.begin() + i--); - else if (sep[i] == "..") + String path(filePath); + + #if defined(NAZARA_PLATFORM_WINDOWS) + path.Replace('/', '\\'); + #elif defined(NAZARA_PLATFORM_LINUX) + path.Replace('\\', '/'); + #else + #error OS case not implemented + #endif + + return path; + } + + bool File::Rename(const String& sourcePath, const String& targetPath) + { + if (sourcePath.IsEmpty() || targetPath.IsEmpty()) + return false; + + return FileImpl::Rename(NormalizePath(sourcePath), NormalizePath(targetPath)); + } + + bool File::FillHash(AbstractHash* hash) const + { + File file(m_filePath); + if (!file.Open(OpenMode_ReadOnly)) { - if (i > start) // Si nous ne sommes pas dans la partie protégée - sep.erase(sep.begin() + i--); - - sep.erase(sep.begin() + i--); - } - } - - NzStringStream stream(base); - for (unsigned int i = 0; i < sep.size(); ++i) - { - if (i != sep.size()-1) - stream << sep[i] << NAZARA_DIRECTORY_SEPARATOR; - else - stream << sep[i]; - } - - return stream; -} - -bool NzFile::Copy(const NzString& sourcePath, const NzString& targetPath) -{ - if (sourcePath.IsEmpty() || targetPath.IsEmpty()) - return false; - - return NzFileImpl::Copy(NormalizePath(sourcePath), NormalizePath(targetPath)); -} - -bool NzFile::Delete(const NzString& filePath) -{ - if (filePath.IsEmpty()) - return false; - - return NzFileImpl::Delete(NormalizePath(filePath)); -} - -bool NzFile::Exists(const NzString& filePath) -{ - if (filePath.IsEmpty()) - return false; - - return NzFileImpl::Exists(NormalizePath(filePath)); -} - -time_t NzFile::GetCreationTime(const NzString& filePath) -{ - if (filePath.IsEmpty()) - return 0; - - return NzFileImpl::GetCreationTime(NormalizePath(filePath)); -} - -NzString NzFile::GetDirectory(const NzString& filePath) -{ - return filePath.SubStringTo(NAZARA_DIRECTORY_SEPARATOR, -1, true, true); -} - -time_t NzFile::GetLastAccessTime(const NzString& filePath) -{ - if (filePath.IsEmpty()) - return 0; - - return NzFileImpl::GetLastAccessTime(NormalizePath(filePath)); -} - -time_t NzFile::GetLastWriteTime(const NzString& filePath) -{ - if (filePath.IsEmpty()) - return 0; - - return NzFileImpl::GetLastWriteTime(NormalizePath(filePath)); -} - -NzHashDigest NzFile::GetHash(const NzString& filePath, nzHash hash) -{ - NzFile file(filePath); - - NzHash h(hash); - return h.Hash(file); -} - -NzHashDigest NzFile::GetHash(const NzString& filePath, NzAbstractHash* hash) -{ - NzFile file(filePath); - - NzHash h(hash); - return h.Hash(file); -} - -nzUInt64 NzFile::GetSize(const NzString& filePath) -{ - if (filePath.IsEmpty()) - return 0; - - return NzFileImpl::GetSize(NormalizePath(filePath)); -} - -bool NzFile::IsAbsolute(const NzString& filePath) -{ - NzString path(filePath.Trimmed()); - if (path.IsEmpty()) - return false; - - path = NormalizeSeparators(path); - - #ifdef NAZARA_PLATFORM_WINDOWS - if (path.Match("?:*")) // Ex: C:\Hello - return true; - else if (path.Match("\\\\*")) // Ex: \\Laptop - return true; - else if (path.StartsWith('\\')) // Spécial : '\' fait référence au disque racine - return true; - else - return false; - #elif defined(NAZARA_PLATFORM_POSIX) - return path.StartsWith('/'); - #else - #error OS case not implemented - #endif -} - -NzString NzFile::NormalizePath(const NzString& filePath) -{ - NzString path = NormalizeSeparators(filePath.Trimmed()); - - if (!IsAbsolute(path)) - path = NzDirectory::GetCurrent() + NAZARA_DIRECTORY_SEPARATOR + path; - - while (path.EndsWith(NAZARA_DIRECTORY_SEPARATOR)) - path.Resize(-1); - - return path; -} - -NzString NzFile::NormalizeSeparators(const NzString& filePath) -{ - NzString path(filePath); - - #if defined(NAZARA_PLATFORM_WINDOWS) - path.Replace('/', '\\'); - #elif defined(NAZARA_PLATFORM_LINUX) - path.Replace('\\', '/'); - #else - #error OS case not implemented - #endif - - return path; -} - -bool NzFile::Rename(const NzString& sourcePath, const NzString& targetPath) -{ - if (sourcePath.IsEmpty() || targetPath.IsEmpty()) - return false; - - return NzFileImpl::Rename(NormalizePath(sourcePath), NormalizePath(targetPath)); -} - -bool NzFile::FillHash(NzAbstractHash* hash) const -{ - NzFile file(m_filePath); - if (!file.Open(nzOpenMode_ReadOnly)) - { - NazaraError("Unable to open file"); - return false; - } - - nzUInt64 remainingSize = file.GetSize(); - - char buffer[NAZARA_CORE_FILE_BUFFERSIZE]; - while (remainingSize > 0) - { - unsigned int size = static_cast(std::min(remainingSize, static_cast(NAZARA_CORE_FILE_BUFFERSIZE))); - if (file.Read(&buffer[0], sizeof(char), size) != sizeof(char)*size) - { - NazaraError("Unable to read file"); + NazaraError("Unable to open file"); return false; } - remainingSize -= size; - hash->Append(reinterpret_cast(&buffer[0]), size); - } + UInt64 remainingSize = file.GetSize(); - return true; -} // Fermeture automatique du fichier + char buffer[NAZARA_CORE_FILE_BUFFERSIZE]; + while (remainingSize > 0) + { + unsigned int size = static_cast(std::min(remainingSize, static_cast(NAZARA_CORE_FILE_BUFFERSIZE))); + if (file.Read(&buffer[0], sizeof(char), size) != sizeof(char)*size) + { + NazaraError("Unable to read file"); + return false; + } + + remainingSize -= size; + hash->Append(reinterpret_cast(&buffer[0]), size); + } + + return true; + } // Fermeture automatique du fichier +} diff --git a/src/Nazara/Core/GuillotineBinPack.cpp b/src/Nazara/Core/GuillotineBinPack.cpp index 1d89515db..7015a5f65 100644 --- a/src/Nazara/Core/GuillotineBinPack.cpp +++ b/src/Nazara/Core/GuillotineBinPack.cpp @@ -14,434 +14,437 @@ #include #include -namespace +namespace Nz { - int ScoreBestAreaFit(int width, int height, const NzRectui& freeRectSize) + namespace { - return freeRectSize.width * freeRectSize.height - width * height; - } - - int ScoreBestLongSideFit(int width, int height, const NzRectui& freeRectSize) - { - int leftoverHoriz = std::abs(static_cast(freeRectSize.width - width)); - int leftoverVert = std::abs(static_cast(freeRectSize.height - height)); - int leftover = std::max(leftoverHoriz, leftoverVert); - - return leftover; - } - - int ScoreBestShortSideFit(int width, int height, const NzRectui& freeRectSize) - { - int leftoverHoriz = std::abs(static_cast(freeRectSize.width - width)); - int leftoverVert = std::abs(static_cast(freeRectSize.height - height)); - int leftover = std::min(leftoverHoriz, leftoverVert); - - return leftover; - } - - int ScoreWorstAreaFit(int width, int height, const NzRectui& freeRectSize) - { - return -ScoreBestAreaFit(width, height, freeRectSize); - } - - int ScoreWorstLongSideFit(int width, int height, const NzRectui& freeRectSize) - { - return -ScoreBestLongSideFit(width, height, freeRectSize); - } - - int ScoreWorstShortSideFit(int width, int height, const NzRectui& freeRectSize) - { - return -ScoreBestShortSideFit(width, height, freeRectSize); - } -} - -NzGuillotineBinPack::NzGuillotineBinPack() -{ - Reset(); -} - -NzGuillotineBinPack::NzGuillotineBinPack(unsigned int width, unsigned int height) -{ - Reset(width, height); -} - -NzGuillotineBinPack::NzGuillotineBinPack(const NzVector2ui& size) -{ - Reset(size); -} - -void NzGuillotineBinPack::Clear() -{ - m_freeRectangles.clear(); - m_freeRectangles.push_back(NzRectui(0, 0, m_width, m_height)); - - m_usedArea = 0; -} - -void NzGuillotineBinPack::Expand(unsigned int newWidth, unsigned newHeight) -{ - unsigned int oldWidth = m_width; - unsigned int oldHeight = m_height; - - m_width = std::max(newWidth, m_width); - m_height = std::max(newHeight, m_height); - - if (m_width > oldWidth) - m_freeRectangles.push_back(NzRectui(oldWidth, 0, m_width - oldWidth, oldHeight)); - - if (m_height > oldHeight) - m_freeRectangles.push_back(NzRectui(0, oldHeight, m_width, m_height - oldHeight)); - - // On va ensuite fusionner les rectangles tant que possible - while (MergeFreeRectangles()); -} - -void NzGuillotineBinPack::Expand(const NzVector2ui& newSize) -{ - Expand(newSize.x, newSize.y); -} - -void NzGuillotineBinPack::FreeRectangle(const NzRectui& rect) -{ - ///DOC: Cette méthode ne devrait recevoir que des rectangles calculés par la méthode Insert et peut provoquer de la fragmentation - m_freeRectangles.push_back(rect); - - m_usedArea -= rect.width * rect.height; -} - -unsigned int NzGuillotineBinPack::GetHeight() const -{ - return m_height; -} - -float NzGuillotineBinPack::GetOccupancy() const -{ - return static_cast(m_usedArea)/(m_width*m_height); -} - -NzVector2ui NzGuillotineBinPack::GetSize() const -{ - return NzVector2ui(m_width, m_height); -} - -unsigned int NzGuillotineBinPack::GetWidth() const -{ - return m_width; -} - -bool NzGuillotineBinPack::Insert(NzRectui* rects, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod) -{ - return Insert(rects, nullptr, nullptr, count, merge, rectChoice, splitMethod); -} - -bool NzGuillotineBinPack::Insert(NzRectui* rects, bool* flipped, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod) -{ - return Insert(rects, flipped, nullptr, count, merge, rectChoice, splitMethod); -} - -bool NzGuillotineBinPack::Insert(NzRectui* rects, bool* flipped, bool* inserted, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod) -{ - std::vector remainingRects(count); // La position du rectangle - for (unsigned int i = 0; i < count; ++i) - remainingRects[i] = &rects[i]; - - // Pack rectangles one at a time until we have cleared the rects array of all rectangles. - while (!remainingRects.empty()) - { - // Stores the penalty score of the best rectangle placement - bigger=worse, smaller=better. - bool bestFlipped; - int bestFreeRect; - int bestRect; - int bestScore = std::numeric_limits::max(); - - for (std::size_t i = 0; i < m_freeRectangles.size(); ++i) + int ScoreBestAreaFit(int width, int height, const Rectui& freeRectSize) { - NzRectui& freeRect = m_freeRectangles[i]; + return freeRectSize.width * freeRectSize.height - width * height; + } - for (std::size_t j = 0; j < remainingRects.size(); ++j) + int ScoreBestLongSideFit(int width, int height, const Rectui& freeRectSize) + { + int leftoverHoriz = std::abs(static_cast(freeRectSize.width - width)); + int leftoverVert = std::abs(static_cast(freeRectSize.height - height)); + int leftover = std::max(leftoverHoriz, leftoverVert); + + return leftover; + } + + int ScoreBestShortSideFit(int width, int height, const Rectui& freeRectSize) + { + int leftoverHoriz = std::abs(static_cast(freeRectSize.width - width)); + int leftoverVert = std::abs(static_cast(freeRectSize.height - height)); + int leftover = std::min(leftoverHoriz, leftoverVert); + + return leftover; + } + + int ScoreWorstAreaFit(int width, int height, const Rectui& freeRectSize) + { + return -ScoreBestAreaFit(width, height, freeRectSize); + } + + int ScoreWorstLongSideFit(int width, int height, const Rectui& freeRectSize) + { + return -ScoreBestLongSideFit(width, height, freeRectSize); + } + + int ScoreWorstShortSideFit(int width, int height, const Rectui& freeRectSize) + { + return -ScoreBestShortSideFit(width, height, freeRectSize); + } + } + + GuillotineBinPack::GuillotineBinPack() + { + Reset(); + } + + GuillotineBinPack::GuillotineBinPack(unsigned int width, unsigned int height) + { + Reset(width, height); + } + + GuillotineBinPack::GuillotineBinPack(const Vector2ui& size) + { + Reset(size); + } + + void GuillotineBinPack::Clear() + { + m_freeRectangles.clear(); + m_freeRectangles.push_back(Rectui(0, 0, m_width, m_height)); + + m_usedArea = 0; + } + + void GuillotineBinPack::Expand(unsigned int newWidth, unsigned newHeight) + { + unsigned int oldWidth = m_width; + unsigned int oldHeight = m_height; + + m_width = std::max(newWidth, m_width); + m_height = std::max(newHeight, m_height); + + if (m_width > oldWidth) + m_freeRectangles.push_back(Rectui(oldWidth, 0, m_width - oldWidth, oldHeight)); + + if (m_height > oldHeight) + m_freeRectangles.push_back(Rectui(0, oldHeight, m_width, m_height - oldHeight)); + + // On va ensuite fusionner les rectangles tant que possible + while (MergeFreeRectangles()); + } + + void GuillotineBinPack::Expand(const Vector2ui& newSize) + { + Expand(newSize.x, newSize.y); + } + + void GuillotineBinPack::FreeRectangle(const Rectui& rect) + { + ///DOC: Cette méthode ne devrait recevoir que des rectangles calculés par la méthode Insert et peut provoquer de la fragmentation + m_freeRectangles.push_back(rect); + + m_usedArea -= rect.width * rect.height; + } + + unsigned int GuillotineBinPack::GetHeight() const + { + return m_height; + } + + float GuillotineBinPack::GetOccupancy() const + { + return static_cast(m_usedArea)/(m_width*m_height); + } + + Vector2ui GuillotineBinPack::GetSize() const + { + return Vector2ui(m_width, m_height); + } + + unsigned int GuillotineBinPack::GetWidth() const + { + return m_width; + } + + bool GuillotineBinPack::Insert(Rectui* rects, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod) + { + return Insert(rects, nullptr, nullptr, count, merge, rectChoice, splitMethod); + } + + bool GuillotineBinPack::Insert(Rectui* rects, bool* flipped, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod) + { + return Insert(rects, flipped, nullptr, count, merge, rectChoice, splitMethod); + } + + bool GuillotineBinPack::Insert(Rectui* rects, bool* flipped, bool* inserted, unsigned int count, bool merge, FreeRectChoiceHeuristic rectChoice, GuillotineSplitHeuristic splitMethod) + { + std::vector remainingRects(count); // La position du rectangle + for (unsigned int i = 0; i < count; ++i) + remainingRects[i] = &rects[i]; + + // Pack rectangles one at a time until we have cleared the rects array of all rectangles. + while (!remainingRects.empty()) + { + // Stores the penalty score of the best rectangle placement - bigger=worse, smaller=better. + bool bestFlipped; + int bestFreeRect; + int bestRect; + int bestScore = std::numeric_limits::max(); + + for (std::size_t i = 0; i < m_freeRectangles.size(); ++i) { - NzRectui& rect = *remainingRects[j]; + Rectui& freeRect = m_freeRectangles[i]; - // If this rectangle is a perfect match, we pick it instantly. - if (rect.width == freeRect.width && rect.height == freeRect.height) + for (std::size_t j = 0; j < remainingRects.size(); ++j) { - bestFreeRect = i; - bestRect = j; - bestFlipped = false; - bestScore = std::numeric_limits::min(); - i = m_freeRectangles.size(); // Force a jump out of the outer loop as well - we got an instant fit. - break; - } - // If flipping this rectangle is a perfect match, pick that then. - else if (rect.height == freeRect.width && rect.width == freeRect.height) - { - bestFreeRect = i; - bestRect = j; - bestFlipped = true; - bestScore = std::numeric_limits::min(); - i = m_freeRectangles.size(); // Force a jump out of the outer loop as well - we got an instant fit. - break; - } - // Try if we can fit the rectangle upright. - else if (rect.width <= freeRect.width && rect.height <= freeRect.height) - { - int score = ScoreByHeuristic(rect.width, rect.height, freeRect, rectChoice); - if (score < bestScore) + Rectui& rect = *remainingRects[j]; + + // If this rectangle is a perfect match, we pick it instantly. + if (rect.width == freeRect.width && rect.height == freeRect.height) { bestFreeRect = i; bestRect = j; bestFlipped = false; - bestScore = score; + bestScore = std::numeric_limits::min(); + i = m_freeRectangles.size(); // Force a jump out of the outer loop as well - we got an instant fit. + break; } - } - // If not, then perhaps flipping sideways will make it fit? - else if (rect.height <= freeRect.width && rect.width <= freeRect.height) - { - int score = ScoreByHeuristic(rect.height, rect.width, freeRect, rectChoice); - if (score < bestScore) + // If flipping this rectangle is a perfect match, pick that then. + else if (rect.height == freeRect.width && rect.width == freeRect.height) { bestFreeRect = i; bestRect = j; bestFlipped = true; - bestScore = score; + bestScore = std::numeric_limits::min(); + i = m_freeRectangles.size(); // Force a jump out of the outer loop as well - we got an instant fit. + break; + } + // Try if we can fit the rectangle upright. + else if (rect.width <= freeRect.width && rect.height <= freeRect.height) + { + int score = ScoreByHeuristic(rect.width, rect.height, freeRect, rectChoice); + if (score < bestScore) + { + bestFreeRect = i; + bestRect = j; + bestFlipped = false; + bestScore = score; + } + } + // If not, then perhaps flipping sideways will make it fit? + else if (rect.height <= freeRect.width && rect.width <= freeRect.height) + { + int score = ScoreByHeuristic(rect.height, rect.width, freeRect, rectChoice); + if (score < bestScore) + { + bestFreeRect = i; + bestRect = j; + bestFlipped = true; + bestScore = score; + } + } + } + } + + // If we didn't manage to find any rectangle to pack, abort. + if (bestScore == std::numeric_limits::max()) + { + // Si nous le pouvons, on marque les rectangles n'ayant pas pu être insérés + if (inserted) + { + for (Rectui* rect : remainingRects) + { + unsigned int position = rect - rects; + inserted[position] = false; + } + } + + return false; + } + + // Otherwise, we're good to go and do the actual packing. + unsigned int position = remainingRects[bestRect] - rects; + Rectui& rect = *remainingRects[bestRect]; + rect.x = m_freeRectangles[bestFreeRect].x; + rect.y = m_freeRectangles[bestFreeRect].y; + + if (bestFlipped) + std::swap(rect.width, rect.height); + + if (flipped) + flipped[position] = bestFlipped; + + if (inserted) + inserted[position] = true; + + // Remove the free space we lost in the bin. + SplitFreeRectByHeuristic(m_freeRectangles[bestFreeRect], rect, splitMethod); + m_freeRectangles.erase(m_freeRectangles.begin() + bestFreeRect); + + // Remove the rectangle we just packed from the input list. + remainingRects.erase(remainingRects.begin() + bestRect); + + // Perform a Rectangle Merge step if desired. + if (merge) + MergeFreeRectangles(); + + m_usedArea += rect.width * rect.height; + } + + return true; + } + + bool GuillotineBinPack::MergeFreeRectangles() + { + ///DOC: Renvoie true s'il y a eu fusion (et donc si une fusion est encore possible) + std::size_t oriSize = m_freeRectangles.size(); + + // Do a Theta(n^2) loop to see if any pair of free rectangles could me merged into one. + // Note that we miss any opportunities to merge three rectangles into one. (should call this function again to detect that) + for (std::size_t i = 0; i < m_freeRectangles.size(); ++i) + { + Rectui& firstRect = m_freeRectangles[i]; + + for (std::size_t j = i+1; j < m_freeRectangles.size(); ++j) + { + Rectui& secondRect = m_freeRectangles[j]; + + if (firstRect.width == secondRect.width && firstRect.x == secondRect.x) + { + if (firstRect.y == secondRect.y + secondRect.height) + { + firstRect.y -= secondRect.height; + firstRect.height += secondRect.height; + m_freeRectangles.erase(m_freeRectangles.begin() + j); + --j; + } + else if (firstRect.y + firstRect.height == secondRect.y) + { + firstRect.height += secondRect.height; + m_freeRectangles.erase(m_freeRectangles.begin() + j); + --j; + } + } + else if (firstRect.height == secondRect.height && firstRect.y == secondRect.y) + { + if (firstRect.x == secondRect.x + secondRect.width) + { + firstRect.x -= secondRect.width; + firstRect.width += secondRect.width; + m_freeRectangles.erase(m_freeRectangles.begin() + j); + --j; + } + else if (firstRect.x + firstRect.width == secondRect.x) + { + firstRect.width += secondRect.width; + m_freeRectangles.erase(m_freeRectangles.begin() + j); + --j; } } } } - // If we didn't manage to find any rectangle to pack, abort. - if (bestScore == std::numeric_limits::max()) - { - // Si nous le pouvons, on marque les rectangles n'ayant pas pu être insérés - if (inserted) - { - for (NzRectui* rect : remainingRects) - { - unsigned int position = rect - rects; - inserted[position] = false; - } - } + return m_freeRectangles.size() < oriSize; + } - return false; + void GuillotineBinPack::Reset() + { + m_height = 0; + m_width = 0; + + Clear(); + } + + void GuillotineBinPack::Reset(unsigned int width, unsigned int height) + { + m_height = height; + m_width = width; + + Clear(); + } + + void GuillotineBinPack::Reset(const Vector2ui& size) + { + Reset(size.x, size.y); + } + + void GuillotineBinPack::SplitFreeRectAlongAxis(const Rectui& freeRect, const Rectui& placedRect, bool splitHorizontal) + { + // Form the two new rectangles. + Rectui bottom; + bottom.x = freeRect.x; + bottom.y = freeRect.y + placedRect.height; + bottom.height = freeRect.height - placedRect.height; + + Rectui right; + right.x = freeRect.x + placedRect.width; + right.y = freeRect.y; + right.width = freeRect.width - placedRect.width; + + if (splitHorizontal) + { + bottom.width = freeRect.width; + right.height = placedRect.height; + } + else // Split vertically + { + bottom.width = placedRect.width; + right.height = freeRect.height; } - // Otherwise, we're good to go and do the actual packing. - unsigned int position = remainingRects[bestRect] - rects; - NzRectui& rect = *remainingRects[bestRect]; - rect.x = m_freeRectangles[bestFreeRect].x; - rect.y = m_freeRectangles[bestFreeRect].y; + // Add the new rectangles into the free rectangle pool if they weren't degenerate. + if (bottom.width > 0 && bottom.height > 0) + m_freeRectangles.push_back(bottom); - if (bestFlipped) - std::swap(rect.width, rect.height); - - if (flipped) - flipped[position] = bestFlipped; - - if (inserted) - inserted[position] = true; - - // Remove the free space we lost in the bin. - SplitFreeRectByHeuristic(m_freeRectangles[bestFreeRect], rect, splitMethod); - m_freeRectangles.erase(m_freeRectangles.begin() + bestFreeRect); - - // Remove the rectangle we just packed from the input list. - remainingRects.erase(remainingRects.begin() + bestRect); - - // Perform a Rectangle Merge step if desired. - if (merge) - MergeFreeRectangles(); - - m_usedArea += rect.width * rect.height; + if (right.width > 0 && right.height > 0) + m_freeRectangles.push_back(right); } - return true; -} - -bool NzGuillotineBinPack::MergeFreeRectangles() -{ - ///DOC: Renvoie true s'il y a eu fusion (et donc si une fusion est encore possible) - std::size_t oriSize = m_freeRectangles.size(); - - // Do a Theta(n^2) loop to see if any pair of free rectangles could me merged into one. - // Note that we miss any opportunities to merge three rectangles into one. (should call this function again to detect that) - for (std::size_t i = 0; i < m_freeRectangles.size(); ++i) + void GuillotineBinPack::SplitFreeRectByHeuristic(const Rectui& freeRect, const Rectui& placedRect, GuillotineSplitHeuristic method) { - NzRectui& firstRect = m_freeRectangles[i]; + // Compute the lengths of the leftover area. + const int w = freeRect.width - placedRect.width; + const int h = freeRect.height - placedRect.height; - for (std::size_t j = i+1; j < m_freeRectangles.size(); ++j) + // Placing placedRect into freeRect results in an L-shaped free area, which must be split into + // two disjoint rectangles. This can be achieved with by splitting the L-shape using a single line. + // We have two choices: horizontal or vertical. + + // Use the given heuristic to decide which choice to make. + + bool splitHorizontal; + switch (method) { - NzRectui& secondRect = m_freeRectangles[j]; + case SplitLongerAxis: + // Split along the longer total axis. + splitHorizontal = (freeRect.width > freeRect.height); + break; - if (firstRect.width == secondRect.width && firstRect.x == secondRect.x) - { - if (firstRect.y == secondRect.y + secondRect.height) - { - firstRect.y -= secondRect.height; - firstRect.height += secondRect.height; - m_freeRectangles.erase(m_freeRectangles.begin() + j); - --j; - } - else if (firstRect.y + firstRect.height == secondRect.y) - { - firstRect.height += secondRect.height; - m_freeRectangles.erase(m_freeRectangles.begin() + j); - --j; - } - } - else if (firstRect.height == secondRect.height && firstRect.y == secondRect.y) - { - if (firstRect.x == secondRect.x + secondRect.width) - { - firstRect.x -= secondRect.width; - firstRect.width += secondRect.width; - m_freeRectangles.erase(m_freeRectangles.begin() + j); - --j; - } - else if (firstRect.x + firstRect.width == secondRect.x) - { - firstRect.width += secondRect.width; - m_freeRectangles.erase(m_freeRectangles.begin() + j); - --j; - } - } + case SplitLongerLeftoverAxis: + // Split along the longer leftover axis. + splitHorizontal = (w > h); + break; + + case SplitMaximizeArea: + // Maximize the smaller area == minimize the larger area. + // Tries to make the rectangles more even-sized. + splitHorizontal = (placedRect.width * h <= w * placedRect.height); + break; + + case SplitMinimizeArea: + // Maximize the larger area == minimize the smaller area. + // Tries to make the single bigger rectangle. + splitHorizontal = (placedRect.width * h > w * placedRect.height); + break; + + case SplitShorterAxis: + // Split along the shorter total axis. + splitHorizontal = (freeRect.width <= freeRect.height); + break; + + case SplitShorterLeftoverAxis: + // Split along the shorter leftover axis. + splitHorizontal = (w <= h); + break; + + default: + NazaraError("Split heuristic out of enum (0x" + String::Number(method, 16) + ')'); + splitHorizontal = true; } + + // Perform the actual split. + SplitFreeRectAlongAxis(freeRect, placedRect, splitHorizontal); } - return m_freeRectangles.size() < oriSize; -} - -void NzGuillotineBinPack::Reset() -{ - m_height = 0; - m_width = 0; - - Clear(); -} - -void NzGuillotineBinPack::Reset(unsigned int width, unsigned int height) -{ - m_height = height; - m_width = width; - - Clear(); -} - -void NzGuillotineBinPack::Reset(const NzVector2ui& size) -{ - Reset(size.x, size.y); -} - -void NzGuillotineBinPack::SplitFreeRectAlongAxis(const NzRectui& freeRect, const NzRectui& placedRect, bool splitHorizontal) -{ - // Form the two new rectangles. - NzRectui bottom; - bottom.x = freeRect.x; - bottom.y = freeRect.y + placedRect.height; - bottom.height = freeRect.height - placedRect.height; - - NzRectui right; - right.x = freeRect.x + placedRect.width; - right.y = freeRect.y; - right.width = freeRect.width - placedRect.width; - - if (splitHorizontal) + int GuillotineBinPack::ScoreByHeuristic(int width, int height, const Rectui& freeRect, FreeRectChoiceHeuristic rectChoice) { - bottom.width = freeRect.width; - right.height = placedRect.height; - } - else // Split vertically - { - bottom.width = placedRect.width; - right.height = freeRect.height; - } + switch (rectChoice) + { + case RectBestAreaFit: + return ScoreBestAreaFit(width, height, freeRect); - // Add the new rectangles into the free rectangle pool if they weren't degenerate. - if (bottom.width > 0 && bottom.height > 0) - m_freeRectangles.push_back(bottom); + case RectBestLongSideFit: + return ScoreBestLongSideFit(width, height, freeRect); - if (right.width > 0 && right.height > 0) - m_freeRectangles.push_back(right); -} - -void NzGuillotineBinPack::SplitFreeRectByHeuristic(const NzRectui& freeRect, const NzRectui& placedRect, GuillotineSplitHeuristic method) -{ - // Compute the lengths of the leftover area. - const int w = freeRect.width - placedRect.width; - const int h = freeRect.height - placedRect.height; - - // Placing placedRect into freeRect results in an L-shaped free area, which must be split into - // two disjoint rectangles. This can be achieved with by splitting the L-shape using a single line. - // We have two choices: horizontal or vertical. - - // Use the given heuristic to decide which choice to make. - - bool splitHorizontal; - switch (method) - { - case SplitLongerAxis: - // Split along the longer total axis. - splitHorizontal = (freeRect.width > freeRect.height); - break; - - case SplitLongerLeftoverAxis: - // Split along the longer leftover axis. - splitHorizontal = (w > h); - break; - - case SplitMaximizeArea: - // Maximize the smaller area == minimize the larger area. - // Tries to make the rectangles more even-sized. - splitHorizontal = (placedRect.width * h <= w * placedRect.height); - break; - - case SplitMinimizeArea: - // Maximize the larger area == minimize the smaller area. - // Tries to make the single bigger rectangle. - splitHorizontal = (placedRect.width * h > w * placedRect.height); - break; - - case SplitShorterAxis: - // Split along the shorter total axis. - splitHorizontal = (freeRect.width <= freeRect.height); - break; - - case SplitShorterLeftoverAxis: - // Split along the shorter leftover axis. - splitHorizontal = (w <= h); - break; - - default: - NazaraError("Split heuristic out of enum (0x" + NzString::Number(method, 16) + ')'); - splitHorizontal = true; - } - - // Perform the actual split. - SplitFreeRectAlongAxis(freeRect, placedRect, splitHorizontal); -} - -int NzGuillotineBinPack::ScoreByHeuristic(int width, int height, const NzRectui& freeRect, FreeRectChoiceHeuristic rectChoice) -{ - switch (rectChoice) - { - case RectBestAreaFit: - return ScoreBestAreaFit(width, height, freeRect); - - case RectBestLongSideFit: - return ScoreBestLongSideFit(width, height, freeRect); - - case RectBestShortSideFit: - return ScoreBestShortSideFit(width, height, freeRect); - - case RectWorstAreaFit: - return ScoreWorstAreaFit(width, height, freeRect); - - case RectWorstLongSideFit: - return ScoreWorstLongSideFit(width, height, freeRect); - - case RectWorstShortSideFit: - return ScoreWorstShortSideFit(width, height, freeRect); - } - - NazaraError("Rect choice heuristic out of enum (0x" + NzString::Number(rectChoice, 16) + ')'); - return std::numeric_limits::max(); + case RectBestShortSideFit: + return ScoreBestShortSideFit(width, height, freeRect); + + case RectWorstAreaFit: + return ScoreWorstAreaFit(width, height, freeRect); + + case RectWorstLongSideFit: + return ScoreWorstLongSideFit(width, height, freeRect); + + case RectWorstShortSideFit: + return ScoreWorstShortSideFit(width, height, freeRect); + } + + NazaraError("Rect choice heuristic out of enum (0x" + String::Number(rectChoice, 16) + ')'); + return std::numeric_limits::max(); + } } diff --git a/src/Nazara/Core/HardwareInfo.cpp b/src/Nazara/Core/HardwareInfo.cpp index fddf6b4fc..1ada7a794 100644 --- a/src/Nazara/Core/HardwareInfo.cpp +++ b/src/Nazara/Core/HardwareInfo.cpp @@ -18,224 +18,227 @@ #include -namespace +namespace Nz { - struct VendorString + namespace { - char vendor[13]; // +1 pour le \0 automatiquement ajouté par le compilateur - nzProcessorVendor vendorEnum; - }; - - // Exceptionellement, la valeur "unknown" est intégrée - const char* vendorNames[] = - { - "Unknown", // nzProcessorVendor_Unknown - "Advanced Micro Devices", // nzProcessorVendor_AMD - "Centaur Technology", // nzProcessorVendor_Centaur - "Cyrix Corporation", // nzProcessorVendor_Cyrix - "Intel Corporation", // nzProcessorVendor_Intel - "Kernel-based Virtual Machine", // nzProcessorVendor_KVM - "Microsoft Hyper-V", // nzProcessorVendor_HyperV - "National Semiconductor", // nzProcessorVendor_NSC - "NexGen", // nzProcessorVendor_NexGen - "Rise Technology", // nzProcessorVendor_Rise - "Silicon Integrated Systems", // nzProcessorVendor_SIS - "Transmeta Corporation", // nzProcessorVendor_Transmeta - "United Microelectronics Corporation", // nzProcessorVendor_UMC - "VIA Technologies", // nzProcessorVendor_VIA - "VMware", // nzProcessorVendor_VMware - "Vortex86", // nzProcessorVendor_Vortex - "Xen" // nzProcessorVendor_XenHVM - }; - - static_assert(sizeof(vendorNames)/sizeof(const char*) == nzProcessorVendor_Max+2, "Processor vendor name array is incomplete"); - - VendorString vendorStrings[] = - { - // Triés par ordre alphabétique (Majuscules primant sur minuscules) - {"AMDisbetter!", nzProcessorVendor_AMD}, - {"AuthenticAMD", nzProcessorVendor_AMD}, - {"CentaurHauls", nzProcessorVendor_Centaur}, - {"CyrixInstead", nzProcessorVendor_Cyrix}, - {"GenuineIntel", nzProcessorVendor_Intel}, - {"GenuineTMx86", nzProcessorVendor_Transmeta}, - {"Geode by NSC", nzProcessorVendor_NSC}, - {"KVMKVMKVMKVM", nzProcessorVendor_KVM}, - {"Microsoft Hv", nzProcessorVendor_HyperV}, - {"NexGenDriven", nzProcessorVendor_NexGen}, - {"RiseRiseRise", nzProcessorVendor_Rise}, - {"SiS SiS SiS ", nzProcessorVendor_SIS}, - {"TransmetaCPU", nzProcessorVendor_Transmeta}, - {"UMC UMC UMC ", nzProcessorVendor_UMC}, - {"VIA VIA VIA ", nzProcessorVendor_VIA}, - {"VMwareVMware", nzProcessorVendor_VMware}, - {"Vortex86 SoC", nzProcessorVendor_Vortex}, - {"XenVMMXenVMM", nzProcessorVendor_XenHVM} - }; - - nzProcessorVendor s_vendorEnum = nzProcessorVendor_Unknown; - bool s_capabilities[nzProcessorCap_Max+1] = {false}; - bool s_initialized = false; - - char s_brandString[48] = "Not initialized"; -} - -void NzHardwareInfo::Cpuid(nzUInt32 functionId, nzUInt32 subFunctionId, nzUInt32 result[4]) -{ - return NzHardwareInfoImpl::Cpuid(functionId, subFunctionId, result); -} - -NzString NzHardwareInfo::GetProcessorBrandString() -{ - if (!Initialize()) - NazaraError("Failed to initialize HardwareInfo"); - - return s_brandString; -} - -unsigned int NzHardwareInfo::GetProcessorCount() -{ - ///DOC: Ne nécessite pas l'initialisation de HardwareInfo pour fonctionner - static unsigned int processorCount = std::max(NzHardwareInfoImpl::GetProcessorCount(), 1U); - return processorCount; -} - -nzProcessorVendor NzHardwareInfo::GetProcessorVendor() -{ - if (!Initialize()) - NazaraError("Failed to initialize HardwareInfo"); - - return s_vendorEnum; -} - -NzString NzHardwareInfo::GetProcessorVendorName() -{ - if (!Initialize()) - NazaraError("Failed to initialize HardwareInfo"); - - return vendorNames[s_vendorEnum+1]; -} - -nzUInt64 NzHardwareInfo::GetTotalMemory() -{ - ///DOC: Ne nécessite pas l'initialisation de HardwareInfo pour fonctionner - static nzUInt64 totalMemory = NzHardwareInfoImpl::GetTotalMemory(); - return totalMemory; -} - -bool NzHardwareInfo::HasCapability(nzProcessorCap capability) -{ - #ifdef NAZARA_DEBUG - if (capability > nzProcessorCap_Max) - { - NazaraError("Capability type out of enum"); - return false; - } - #endif - - return s_capabilities[capability]; -} - -bool NzHardwareInfo::Initialize() -{ - if (s_initialized) - return true; - - if (!NzHardwareInfoImpl::IsCpuidSupported()) - { - NazaraError("Cpuid is not supported"); - return false; - } - - s_initialized = true; - - nzUInt32 registers[4]; // Récupère les quatre registres (EAX, EBX, ECX et EDX) - - // Pour plus de clarté - nzUInt32& eax = registers[0]; - nzUInt32& ebx = registers[1]; - nzUInt32& ecx = registers[2]; - nzUInt32& edx = registers[3]; - - // Pour commencer, on va récupérer l'identifiant du constructeur ainsi que l'id de fonction maximal supporté par le CPUID - NzHardwareInfoImpl::Cpuid(0, 0, registers); - - // Attention à l'ordre : EBX, EDX, ECX - nzUInt32 manufacturerId[3] = {ebx, edx, ecx}; - - // Identification du concepteur - s_vendorEnum = nzProcessorVendor_Unknown; - for (const VendorString& vendorString : vendorStrings) - { - if (std::memcmp(manufacturerId, vendorString.vendor, 12) == 0) + struct VendorString { - s_vendorEnum = vendorString.vendorEnum; - break; + char vendor[13]; // +1 pour le \0 automatiquement ajouté par le compilateur + ProcessorVendor vendorEnum; + }; + + // Exceptionellement, la valeur "unknown" est intégrée + const char* vendorNames[] = + { + "Unknown", // ProcessorVendor_Unknown + "Advanced Micro Devices", // ProcessorVendor_AMD + "Centaur Technology", // ProcessorVendor_Centaur + "Cyrix Corporation", // ProcessorVendor_Cyrix + "Intel Corporation", // ProcessorVendor_Intel + "Kernel-based Virtual Machine", // ProcessorVendor_KVM + "Microsoft Hyper-V", // ProcessorVendor_HyperV + "National Semiconductor", // ProcessorVendor_NSC + "NexGen", // ProcessorVendor_NexGen + "Rise Technology", // ProcessorVendor_Rise + "Silicon Integrated Systems", // ProcessorVendor_SIS + "Transmeta Corporation", // ProcessorVendor_Transmeta + "United Microelectronics Corporation", // ProcessorVendor_UMC + "VIA Technologies", // ProcessorVendor_VIA + "VMware", // ProcessorVendor_VMware + "Vortex86", // ProcessorVendor_Vortex + "Xen" // ProcessorVendor_XenHVM + }; + + static_assert(sizeof(vendorNames)/sizeof(const char*) == ProcessorVendor_Max+2, "Processor vendor name array is incomplete"); + + VendorString vendorStrings[] = + { + // Triés par ordre alphabétique (Majuscules primant sur minuscules) + {"AMDisbetter!", ProcessorVendor_AMD}, + {"AuthenticAMD", ProcessorVendor_AMD}, + {"CentaurHauls", ProcessorVendor_Centaur}, + {"CyrixInstead", ProcessorVendor_Cyrix}, + {"GenuineIntel", ProcessorVendor_Intel}, + {"GenuineTMx86", ProcessorVendor_Transmeta}, + {"Geode by NSC", ProcessorVendor_NSC}, + {"KVMKVMKVMKVM", ProcessorVendor_KVM}, + {"Microsoft Hv", ProcessorVendor_HyperV}, + {"NexGenDriven", ProcessorVendor_NexGen}, + {"RiseRiseRise", ProcessorVendor_Rise}, + {"SiS SiS SiS ", ProcessorVendor_SIS}, + {"TransmetaCPU", ProcessorVendor_Transmeta}, + {"UMC UMC UMC ", ProcessorVendor_UMC}, + {"VIA VIA VIA ", ProcessorVendor_VIA}, + {"VMwareVMware", ProcessorVendor_VMware}, + {"Vortex86 SoC", ProcessorVendor_Vortex}, + {"XenVMMXenVMM", ProcessorVendor_XenHVM} + }; + + ProcessorVendor s_vendorEnum = ProcessorVendor_Unknown; + bool s_capabilities[ProcessorCap_Max+1] = {false}; + bool s_initialized = false; + + char s_brandString[48] = "Not initialized"; + } + + void HardwareInfo::Cpuid(UInt32 functionId, UInt32 subFunctionId, UInt32 result[4]) + { + return HardwareInfoImpl::Cpuid(functionId, subFunctionId, result); + } + + String HardwareInfo::GetProcessorBrandString() + { + if (!Initialize()) + NazaraError("Failed to initialize HardwareInfo"); + + return s_brandString; + } + + unsigned int HardwareInfo::GetProcessorCount() + { + ///DOC: Ne nécessite pas l'initialisation de HardwareInfo pour fonctionner + static unsigned int processorCount = std::max(HardwareInfoImpl::GetProcessorCount(), 1U); + return processorCount; + } + + ProcessorVendor HardwareInfo::GetProcessorVendor() + { + if (!Initialize()) + NazaraError("Failed to initialize HardwareInfo"); + + return s_vendorEnum; + } + + String HardwareInfo::GetProcessorVendorName() + { + if (!Initialize()) + NazaraError("Failed to initialize HardwareInfo"); + + return vendorNames[s_vendorEnum+1]; + } + + UInt64 HardwareInfo::GetTotalMemory() + { + ///DOC: Ne nécessite pas l'initialisation de HardwareInfo pour fonctionner + static UInt64 totalMemory = HardwareInfoImpl::GetTotalMemory(); + return totalMemory; + } + + bool HardwareInfo::HasCapability(ProcessorCap capability) + { + #ifdef NAZARA_DEBUG + if (capability > ProcessorCap_Max) + { + NazaraError("Capability type out of enum"); + return false; } + #endif + + return s_capabilities[capability]; } - if (eax >= 1) + bool HardwareInfo::Initialize() { - // Récupération de certaines capacités du processeur (ECX et EDX, fonction 1) - NzHardwareInfoImpl::Cpuid(1, 0, registers); + if (s_initialized) + return true; - s_capabilities[nzProcessorCap_AVX] = (ecx & (1U << 28)) != 0; - s_capabilities[nzProcessorCap_FMA3] = (ecx & (1U << 12)) != 0; - s_capabilities[nzProcessorCap_MMX] = (edx & (1U << 23)) != 0; - s_capabilities[nzProcessorCap_SSE] = (edx & (1U << 25)) != 0; - s_capabilities[nzProcessorCap_SSE2] = (edx & (1U << 26)) != 0; - s_capabilities[nzProcessorCap_SSE3] = (ecx & (1U << 0)) != 0; - s_capabilities[nzProcessorCap_SSSE3] = (ecx & (1U << 9)) != 0; - s_capabilities[nzProcessorCap_SSE41] = (ecx & (1U << 19)) != 0; - s_capabilities[nzProcessorCap_SSE42] = (ecx & (1U << 20)) != 0; - } - - // Récupération de la plus grande fonction étendue supportée (EAX, fonction 0x80000000) - NzHardwareInfoImpl::Cpuid(0x80000000, 0, registers); - - nzUInt32 maxSupportedExtendedFunction = eax; - if (maxSupportedExtendedFunction >= 0x80000001) - { - // Récupération des capacités étendues du processeur (ECX et EDX, fonction 0x80000001) - NzHardwareInfoImpl::Cpuid(0x80000001, 0, registers); - - s_capabilities[nzProcessorCap_x64] = (edx & (1U << 29)) != 0; // Support du 64bits, indépendant de l'OS - s_capabilities[nzProcessorCap_FMA4] = (ecx & (1U << 16)) != 0; - s_capabilities[nzProcessorCap_SSE4a] = (ecx & (1U << 6)) != 0; - s_capabilities[nzProcessorCap_XOP] = (ecx & (1U << 11)) != 0; - - if (maxSupportedExtendedFunction >= 0x80000004) + if (!HardwareInfoImpl::IsCpuidSupported()) { - // Récupération d'une chaîne de caractère décrivant le processeur (EAX, EBX, ECX et EDX, - // fonctions de 0x80000002 à 0x80000004 compris) - char* ptr = &s_brandString[0]; - for (nzUInt32 code = 0x80000002; code <= 0x80000004; ++code) + NazaraError("Cpuid is not supported"); + return false; + } + + s_initialized = true; + + UInt32 registers[4]; // Récupère les quatre registres (EAX, EBX, ECX et EDX) + + // Pour plus de clarté + UInt32& eax = registers[0]; + UInt32& ebx = registers[1]; + UInt32& ecx = registers[2]; + UInt32& edx = registers[3]; + + // Pour commencer, on va récupérer l'identifiant du constructeur ainsi que l'id de fonction maximal supporté par le CPUID + HardwareInfoImpl::Cpuid(0, 0, registers); + + // Attention à l'ordre : EBX, EDX, ECX + UInt32 manufacturerId[3] = {ebx, edx, ecx}; + + // Identification du concepteur + s_vendorEnum = ProcessorVendor_Unknown; + for (const VendorString& vendorString : vendorStrings) + { + if (std::memcmp(manufacturerId, vendorString.vendor, 12) == 0) { - NzHardwareInfoImpl::Cpuid(code, 0, registers); - std::memcpy(ptr, ®isters[0], 4*sizeof(nzUInt32)); // On rajoute les 16 octets à la chaîne - - ptr += 4*sizeof(nzUInt32); + s_vendorEnum = vendorString.vendorEnum; + break; } - - // Le caractère nul faisant partie de la chaîne retournée par le CPUID, pas besoin de le rajouter } + + if (eax >= 1) + { + // Récupération de certaines capacités du processeur (ECX et EDX, fonction 1) + HardwareInfoImpl::Cpuid(1, 0, registers); + + s_capabilities[ProcessorCap_AVX] = (ecx & (1U << 28)) != 0; + s_capabilities[ProcessorCap_FMA3] = (ecx & (1U << 12)) != 0; + s_capabilities[ProcessorCap_MMX] = (edx & (1U << 23)) != 0; + s_capabilities[ProcessorCap_SSE] = (edx & (1U << 25)) != 0; + s_capabilities[ProcessorCap_SSE2] = (edx & (1U << 26)) != 0; + s_capabilities[ProcessorCap_SSE3] = (ecx & (1U << 0)) != 0; + s_capabilities[ProcessorCap_SSSE3] = (ecx & (1U << 9)) != 0; + s_capabilities[ProcessorCap_SSE41] = (ecx & (1U << 19)) != 0; + s_capabilities[ProcessorCap_SSE42] = (ecx & (1U << 20)) != 0; + } + + // Récupération de la plus grande fonction étendue supportée (EAX, fonction 0x80000000) + HardwareInfoImpl::Cpuid(0x80000000, 0, registers); + + UInt32 maxSupportedExtendedFunction = eax; + if (maxSupportedExtendedFunction >= 0x80000001) + { + // Récupération des capacités étendues du processeur (ECX et EDX, fonction 0x80000001) + HardwareInfoImpl::Cpuid(0x80000001, 0, registers); + + s_capabilities[ProcessorCap_x64] = (edx & (1U << 29)) != 0; // Support du 64bits, indépendant de l'OS + s_capabilities[ProcessorCap_FMA4] = (ecx & (1U << 16)) != 0; + s_capabilities[ProcessorCap_SSE4a] = (ecx & (1U << 6)) != 0; + s_capabilities[ProcessorCap_XOP] = (ecx & (1U << 11)) != 0; + + if (maxSupportedExtendedFunction >= 0x80000004) + { + // Récupération d'une chaîne de caractère décrivant le processeur (EAX, EBX, ECX et EDX, + // fonctions de 0x80000002 à 0x80000004 compris) + char* ptr = &s_brandString[0]; + for (UInt32 code = 0x80000002; code <= 0x80000004; ++code) + { + HardwareInfoImpl::Cpuid(code, 0, registers); + std::memcpy(ptr, ®isters[0], 4*sizeof(UInt32)); // On rajoute les 16 octets à la chaîne + + ptr += 4*sizeof(UInt32); + } + + // Le caractère nul faisant partie de la chaîne retournée par le CPUID, pas besoin de le rajouter + } + } + + return true; } - return true; -} + bool HardwareInfo::IsCpuidSupported() + { + return HardwareInfoImpl::IsCpuidSupported(); + } -bool NzHardwareInfo::IsCpuidSupported() -{ - return NzHardwareInfoImpl::IsCpuidSupported(); -} + bool HardwareInfo::IsInitialized() + { + return s_initialized; + } -bool NzHardwareInfo::IsInitialized() -{ - return s_initialized; -} - -void NzHardwareInfo::Uninitialize() -{ - // Rien à faire - s_initialized = false; + void HardwareInfo::Uninitialize() + { + // Rien à faire + s_initialized = false; + } } diff --git a/src/Nazara/Core/Hash.cpp b/src/Nazara/Core/Hash.cpp index 4a7654d77..04043589a 100644 --- a/src/Nazara/Core/Hash.cpp +++ b/src/Nazara/Core/Hash.cpp @@ -14,67 +14,70 @@ #include #include -NzHash::NzHash(nzHash hash) +namespace Nz { - switch (hash) + Hash::Hash(HashType hash) { - case nzHash_Fletcher16: - m_impl = new NzHashFletcher16; - break; + switch (hash) + { + case HashType_Fletcher16: + m_impl = new HashFletcher16; + break; - case nzHash_CRC32: - m_impl = new NzHashCRC32; - break; + case HashType_CRC32: + m_impl = new HashCRC32; + break; - case nzHash_MD5: - m_impl = new NzHashMD5; - break; + case HashType_MD5: + m_impl = new HashMD5; + break; - case nzHash_SHA1: - m_impl = new NzHashSHA1; - break; + case HashType_SHA1: + m_impl = new HashSHA1; + break; - case nzHash_SHA224: - m_impl = new NzHashSHA224; - break; + case HashType_SHA224: + m_impl = new HashSHA224; + break; - case nzHash_SHA256: - m_impl = new NzHashSHA256; - break; + case HashType_SHA256: + m_impl = new HashSHA256; + break; - case nzHash_SHA384: - m_impl = new NzHashSHA384; - break; + case HashType_SHA384: + m_impl = new HashSHA384; + break; - case nzHash_SHA512: - m_impl = new NzHashSHA512; - break; + case HashType_SHA512: + m_impl = new HashSHA512; + break; - case nzHash_Whirlpool: - m_impl = new NzHashWhirlpool; - break; - } -} - -NzHash::NzHash(NzAbstractHash* hashImpl) : -m_impl(hashImpl) -{ -} - -NzHash::~NzHash() -{ - delete m_impl; -} - -NzHashDigest NzHash::Hash(const NzHashable& hashable) -{ - m_impl->Begin(); - if (hashable.FillHash(m_impl)) - return m_impl->End(); - else // Erreur - { - m_impl->End(); - - return NzHashDigest(); + case HashType_Whirlpool: + m_impl = new HashWhirlpool; + break; + } + } + + Hash::Hash(AbstractHash* hashImpl) : + m_impl(hashImpl) + { + } + + Hash::~Hash() + { + delete m_impl; + } + + HashDigest Hash::Process(const Hashable& hashable) + { + m_impl->Begin(); + if (hashable.FillHash(m_impl)) + return m_impl->End(); + else // Erreur + { + m_impl->End(); + + return HashDigest(); + } } } diff --git a/src/Nazara/Core/Hash/CRC32.cpp b/src/Nazara/Core/Hash/CRC32.cpp index af30cb2c7..9459be37e 100644 --- a/src/Nazara/Core/Hash/CRC32.cpp +++ b/src/Nazara/Core/Hash/CRC32.cpp @@ -6,125 +6,128 @@ #include #include -struct NzHashCRC32_state +namespace Nz { - nzUInt32 crc; - const nzUInt32* table; -}; - -namespace -{ - nzUInt32 crc32_reflect(nzUInt32 ref, unsigned int j) + struct HashCRC32_state { - nzUInt32 value = 0; - - for (unsigned int i = 1; i <= j; ++i) - { - if (ref & 1) - value |= 1 << (j - i); - - ref >>= 1; - } - - return value; - } - - static const nzUInt32 crc32_table[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, - 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, - 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, - 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, - 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, - 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, - 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, - 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, - 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, - 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, - 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, - 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, - 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, - 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, - 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, - 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, - 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, - 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d + UInt32 crc; + const UInt32* table; }; -} -NzHashCRC32::NzHashCRC32(nzUInt32 polynomial) -{ - m_state = new NzHashCRC32_state; - - if (polynomial == 0x04c11db7) - m_state->table = crc32_table; // Table précalculée (Bien plus rapide) - else + namespace { - nzUInt32* table = new nzUInt32[256]; - - for (unsigned int i = 0; i < 256; ++i) + UInt32 crc32_reflect(UInt32 ref, unsigned int j) { - table[i] = crc32_reflect(i, 8) << 24; - for (unsigned int j = 0; j < 8; ++j) - table[i] = (table[i] << 1) ^ (table[i] & ((1 << 31) ? polynomial : 0)); + UInt32 value = 0; - table[i] = crc32_reflect(table[i], 32); + for (unsigned int i = 1; i <= j; ++i) + { + if (ref & 1) + value |= 1 << (j - i); + + ref >>= 1; + } + + return value; } - m_state->table = table; + static const UInt32 crc32_table[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d + }; + } + + HashCRC32::HashCRC32(UInt32 polynomial) + { + m_state = new HashCRC32_state; + + if (polynomial == 0x04c11db7) + m_state->table = crc32_table; // Table précalculée (Bien plus rapide) + else + { + UInt32* table = new UInt32[256]; + + for (unsigned int i = 0; i < 256; ++i) + { + table[i] = crc32_reflect(i, 8) << 24; + for (unsigned int j = 0; j < 8; ++j) + table[i] = (table[i] << 1) ^ (table[i] & ((1 << 31) ? polynomial : 0)); + + table[i] = crc32_reflect(table[i], 32); + } + + m_state->table = table; + } + } + + HashCRC32::~HashCRC32() + { + if (m_state->table != crc32_table) + delete[] m_state->table; + + delete m_state; + } + + void HashCRC32::Append(const UInt8* data, unsigned int len) + { + while (len--) + m_state->crc = m_state->table[(m_state->crc ^ *data++) & 0xFF] ^ (m_state->crc >> 8); + } + + void HashCRC32::Begin() + { + m_state->crc = 0xFFFFFFFF; + } + + HashDigest HashCRC32::End() + { + m_state->crc ^= 0xFFFFFFFF; + + #ifdef NAZARA_LITTLE_ENDIAN + SwapBytes(&m_state->crc, sizeof(UInt32)); + #endif + + return HashDigest(GetHashName(), reinterpret_cast(&m_state->crc), 4); + } + + unsigned int HashCRC32::GetDigestLength() + { + return 4; + } + + String HashCRC32::GetHashName() + { + static String hashName = "CRC32"; + return hashName; } } - -NzHashCRC32::~NzHashCRC32() -{ - if (m_state->table != crc32_table) - delete[] m_state->table; - - delete m_state; -} - -void NzHashCRC32::Append(const nzUInt8* data, unsigned int len) -{ - while (len--) - m_state->crc = m_state->table[(m_state->crc ^ *data++) & 0xFF] ^ (m_state->crc >> 8); -} - -void NzHashCRC32::Begin() -{ - m_state->crc = 0xFFFFFFFF; -} - -NzHashDigest NzHashCRC32::End() -{ - m_state->crc ^= 0xFFFFFFFF; - - #ifdef NAZARA_LITTLE_ENDIAN - NzByteSwap(&m_state->crc, sizeof(nzUInt32)); - #endif - - return NzHashDigest(GetHashName(), reinterpret_cast(&m_state->crc), 4); -} - -unsigned int NzHashCRC32::GetDigestLength() -{ - return 4; -} - -NzString NzHashCRC32::GetHashName() -{ - static NzString hashName = "CRC32"; - return hashName; -} diff --git a/src/Nazara/Core/Hash/Fletcher16.cpp b/src/Nazara/Core/Hash/Fletcher16.cpp index 3a608a6b1..66fbae2af 100644 --- a/src/Nazara/Core/Hash/Fletcher16.cpp +++ b/src/Nazara/Core/Hash/Fletcher16.cpp @@ -6,67 +6,70 @@ #include #include -struct NzHashFletcher16_state +namespace Nz { - nzUInt16 sum1; - nzUInt16 sum2; -}; - -NzHashFletcher16::NzHashFletcher16() -{ - m_state = new NzHashFletcher16_state; -} - -NzHashFletcher16::~NzHashFletcher16() -{ - delete m_state; -} - -void NzHashFletcher16::Append(const nzUInt8* data, unsigned int len) -{ - while (len) + struct HashFletcher16_state { - unsigned int tlen = std::min(len, 21U); - len -= tlen; - do - { - m_state->sum1 += *data++; - m_state->sum2 += m_state->sum1; - } - while (--tlen); + UInt16 sum1; + UInt16 sum2; + }; + HashFletcher16::HashFletcher16() + { + m_state = new HashFletcher16_state; + } + + HashFletcher16::~HashFletcher16() + { + delete m_state; + } + + void HashFletcher16::Append(const UInt8* data, unsigned int len) + { + while (len) + { + unsigned int tlen = std::min(len, 21U); + len -= tlen; + do + { + m_state->sum1 += *data++; + m_state->sum2 += m_state->sum1; + } + while (--tlen); + + m_state->sum1 = (m_state->sum1 & 0xff) + (m_state->sum1 >> 8); + m_state->sum2 = (m_state->sum2 & 0xff) + (m_state->sum2 >> 8); + } + } + + void HashFletcher16::Begin() + { + m_state->sum1 = 0xff; + m_state->sum2 = 0xff; + } + + HashDigest HashFletcher16::End() + { m_state->sum1 = (m_state->sum1 & 0xff) + (m_state->sum1 >> 8); m_state->sum2 = (m_state->sum2 & 0xff) + (m_state->sum2 >> 8); + + UInt32 fletcher = (m_state->sum2 << 8) | m_state->sum1; + + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&fletcher, sizeof(UInt32)); + #endif + + return HashDigest(GetHashName(), reinterpret_cast(&fletcher), 2); + } + + unsigned int HashFletcher16::GetDigestLength() + { + return 2; + } + + String HashFletcher16::GetHashName() + { + static String hashName = "Fletcher16"; + return hashName; } } - -void NzHashFletcher16::Begin() -{ - m_state->sum1 = 0xff; - m_state->sum2 = 0xff; -} - -NzHashDigest NzHashFletcher16::End() -{ - m_state->sum1 = (m_state->sum1 & 0xff) + (m_state->sum1 >> 8); - m_state->sum2 = (m_state->sum2 & 0xff) + (m_state->sum2 >> 8); - - nzUInt32 fletcher = (m_state->sum2 << 8) | m_state->sum1; - - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&fletcher, sizeof(nzUInt32)); - #endif - - return NzHashDigest(GetHashName(), reinterpret_cast(&fletcher), 2); -} - -unsigned int NzHashFletcher16::GetDigestLength() -{ - return 2; -} - -NzString NzHashFletcher16::GetHashName() -{ - static NzString hashName = "Fletcher16"; - return hashName; -} diff --git a/src/Nazara/Core/Hash/MD5.cpp b/src/Nazara/Core/Hash/MD5.cpp index 5ac1ff61e..93856c79d 100644 --- a/src/Nazara/Core/Hash/MD5.cpp +++ b/src/Nazara/Core/Hash/MD5.cpp @@ -31,7 +31,7 @@ #include #include -#define T_MASK (static_cast(~0)) +#define T_MASK (static_cast(~0)) #define T1 /* 0xd76aa478 */ (T_MASK ^ 0x28955b87) #define T2 /* 0xe8c7b756 */ (T_MASK ^ 0x173848a9) #define T3 0x242070db @@ -97,267 +97,269 @@ #define T63 0x2ad7d2bb #define T64 /* 0xeb86d391 */ (T_MASK ^ 0x14792c6e) -struct NzHashMD5_state +namespace Nz { - nzUInt32 count[2]; /* message length in bits, lsw first */ - nzUInt32 abcd[4]; /* digest buffer */ - nzUInt8 buf[64]; /* accumulate block */ -}; - -namespace -{ - void md5_process(NzHashMD5_state* state, const nzUInt8* data) + struct HashMD5_state { - nzUInt32 a = state->abcd[0]; - nzUInt32 b = state->abcd[1]; - nzUInt32 c = state->abcd[2]; - nzUInt32 d = state->abcd[3]; - nzUInt32 t; - - #ifdef NAZARA_BIG_ENDIAN - /* Define storage only for big-endian CPUs. */ - nzUInt32 X[16]; - - /* - * On big-endian machines, we must arrange the bytes in the - * right order. - */ - const nzUInt8* xp = data; - int i; - - for (i = 0; i < 16; ++i, xp += 4) - X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); - #else - /* Define storage for little-endian or both types of CPUs. */ - nzUInt32 xbuf[16]; - const nzUInt32* X; - - /* - * On little-endian machines, we can process properly aligned - * data without copying it. - */ - if (!((data - static_cast(nullptr)) & 3)) - { - /* data are properly aligned */ - X = reinterpret_cast(data); - } - else - { - /* not aligned */ - std::memcpy(xbuf, data, 64); - X = xbuf; - } - #endif - - #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) - - /* Round 1. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ - #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) - #define SET(a, b, c, d, k, s, Ti)\ - t = a + F(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 7, T1); - SET(d, a, b, c, 1, 12, T2); - SET(c, d, a, b, 2, 17, T3); - SET(b, c, d, a, 3, 22, T4); - SET(a, b, c, d, 4, 7, T5); - SET(d, a, b, c, 5, 12, T6); - SET(c, d, a, b, 6, 17, T7); - SET(b, c, d, a, 7, 22, T8); - SET(a, b, c, d, 8, 7, T9); - SET(d, a, b, c, 9, 12, T10); - SET(c, d, a, b, 10, 17, T11); - SET(b, c, d, a, 11, 22, T12); - SET(a, b, c, d, 12, 7, T13); - SET(d, a, b, c, 13, 12, T14); - SET(c, d, a, b, 14, 17, T15); - SET(b, c, d, a, 15, 22, T16); - #undef SET - - /* Round 2. */ - /* Let [abcd k s i] denote the operation - a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ - #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) - #define SET(a, b, c, d, k, s, Ti)\ - t = a + G(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 1, 5, T17); - SET(d, a, b, c, 6, 9, T18); - SET(c, d, a, b, 11, 14, T19); - SET(b, c, d, a, 0, 20, T20); - SET(a, b, c, d, 5, 5, T21); - SET(d, a, b, c, 10, 9, T22); - SET(c, d, a, b, 15, 14, T23); - SET(b, c, d, a, 4, 20, T24); - SET(a, b, c, d, 9, 5, T25); - SET(d, a, b, c, 14, 9, T26); - SET(c, d, a, b, 3, 14, T27); - SET(b, c, d, a, 8, 20, T28); - SET(a, b, c, d, 13, 5, T29); - SET(d, a, b, c, 2, 9, T30); - SET(c, d, a, b, 7, 14, T31); - SET(b, c, d, a, 12, 20, T32); - #undef SET - - /* Round 3. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ - #define H(x, y, z) ((x) ^ (y) ^ (z)) - #define SET(a, b, c, d, k, s, Ti)\ - t = a + H(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 5, 4, T33); - SET(d, a, b, c, 8, 11, T34); - SET(c, d, a, b, 11, 16, T35); - SET(b, c, d, a, 14, 23, T36); - SET(a, b, c, d, 1, 4, T37); - SET(d, a, b, c, 4, 11, T38); - SET(c, d, a, b, 7, 16, T39); - SET(b, c, d, a, 10, 23, T40); - SET(a, b, c, d, 13, 4, T41); - SET(d, a, b, c, 0, 11, T42); - SET(c, d, a, b, 3, 16, T43); - SET(b, c, d, a, 6, 23, T44); - SET(a, b, c, d, 9, 4, T45); - SET(d, a, b, c, 12, 11, T46); - SET(c, d, a, b, 15, 16, T47); - SET(b, c, d, a, 2, 23, T48); - #undef SET - - /* Round 4. */ - /* Let [abcd k s t] denote the operation - a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ - #define I(x, y, z) ((y) ^ ((x) | ~(z))) - #define SET(a, b, c, d, k, s, Ti)\ - t = a + I(b,c,d) + X[k] + Ti;\ - a = ROTATE_LEFT(t, s) + b - /* Do the following 16 operations. */ - SET(a, b, c, d, 0, 6, T49); - SET(d, a, b, c, 7, 10, T50); - SET(c, d, a, b, 14, 15, T51); - SET(b, c, d, a, 5, 21, T52); - SET(a, b, c, d, 12, 6, T53); - SET(d, a, b, c, 3, 10, T54); - SET(c, d, a, b, 10, 15, T55); - SET(b, c, d, a, 1, 21, T56); - SET(a, b, c, d, 8, 6, T57); - SET(d, a, b, c, 15, 10, T58); - SET(c, d, a, b, 6, 15, T59); - SET(b, c, d, a, 13, 21, T60); - SET(a, b, c, d, 4, 6, T61); - SET(d, a, b, c, 11, 10, T62); - SET(c, d, a, b, 2, 15, T63); - SET(b, c, d, a, 9, 21, T64); - #undef SET - - /* Then perform the following additions. (That is increment each - of the four registers by the value it had before this block - was started.) */ - state->abcd[0] += a; - state->abcd[1] += b; - state->abcd[2] += c; - state->abcd[3] += d; - } -} - -NzHashMD5::NzHashMD5() -{ - m_state = new NzHashMD5_state; -} - -NzHashMD5::~NzHashMD5() -{ - delete m_state; -} - -void NzHashMD5::Append(const nzUInt8* data, unsigned int len) -{ - const nzUInt8 *p = data; - int left = len; - int offset = (m_state->count[0] >> 3) & 63; - nzUInt32 nbits = len << 3; - - if (len <= 0) - return; - - /* Update the message length. */ - m_state->count[1] += len >> 29; - m_state->count[0] += nbits; - if (m_state->count[0] < nbits) - m_state->count[1]++; - - /* Process an initial partial block. */ - if (offset) - { - int copy = (offset + len > 64 ? 64 - offset : len); - - std::memcpy(m_state->buf + offset, p, copy); - if (offset + copy < 64) - return; - - p += copy; - left -= copy; - md5_process(m_state, m_state->buf); - } - - /* Process full blocks. */ - for (; left >= 64; p += 64, left -= 64) - md5_process(m_state, p); - - /* Process a final partial block. */ - if (left) - std::memcpy(m_state->buf, p, left); -} - -void NzHashMD5::Begin() -{ - m_state->count[0] = m_state->count[1] = 0; - m_state->abcd[0] = 0x67452301; - m_state->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; - m_state->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; - m_state->abcd[3] = 0x10325476; -} - -NzHashDigest NzHashMD5::End() -{ - static const unsigned char pad[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + UInt32 count[2]; /* message length in bits, lsw first */ + UInt32 abcd[4]; /* digest buffer */ + UInt8 buf[64]; /* accumulate block */ }; - nzUInt8 data[8]; - int i; + namespace + { + void md5_process(HashMD5_state* state, const UInt8* data) + { + UInt32 a = state->abcd[0]; + UInt32 b = state->abcd[1]; + UInt32 c = state->abcd[2]; + UInt32 d = state->abcd[3]; + UInt32 t; - /* Save the length before padding. */ - for (i = 0; i < 8; ++i) - data[i] = static_cast(m_state->count[i >> 2] >> ((i & 3) << 3)); - /* Pad to 56 bytes mod 64. */ - Append(pad, ((55 - (m_state->count[0] >> 3)) & 63) + 1); - /* Append the length. */ - Append(data, 8); + #ifdef NAZARA_BIG_ENDIAN + /* Define storage only for big-endian CPUs. */ + UInt32 X[16]; - nzUInt8 digest[16]; - for (i = 0; i < 16; ++i) - digest[i] = static_cast(m_state->abcd[i >> 2] >> ((i & 3) << 3)); + /* + * On big-endian machines, we must arrange the bytes in the + * right order. + */ + const UInt8* xp = data; + int i; - return NzHashDigest(GetHashName(), &digest[0], 16); + for (i = 0; i < 16; ++i, xp += 4) + X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + #else + /* Define storage for little-endian or both types of CPUs. */ + UInt32 xbuf[16]; + const UInt32* X; + + /* + * On little-endian machines, we can process properly aligned + * data without copying it. + */ + if (!((data - static_cast(nullptr)) & 3)) + { + /* data are properly aligned */ + X = reinterpret_cast(data); + } + else + { + /* not aligned */ + std::memcpy(xbuf, data, 64); + X = xbuf; + } + #endif + + #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + + /* Round 1. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ + #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) + #define SET(a, b, c, d, k, s, Ti)\ + t = a + F(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 7, T1); + SET(d, a, b, c, 1, 12, T2); + SET(c, d, a, b, 2, 17, T3); + SET(b, c, d, a, 3, 22, T4); + SET(a, b, c, d, 4, 7, T5); + SET(d, a, b, c, 5, 12, T6); + SET(c, d, a, b, 6, 17, T7); + SET(b, c, d, a, 7, 22, T8); + SET(a, b, c, d, 8, 7, T9); + SET(d, a, b, c, 9, 12, T10); + SET(c, d, a, b, 10, 17, T11); + SET(b, c, d, a, 11, 22, T12); + SET(a, b, c, d, 12, 7, T13); + SET(d, a, b, c, 13, 12, T14); + SET(c, d, a, b, 14, 17, T15); + SET(b, c, d, a, 15, 22, T16); + #undef SET + + /* Round 2. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ + #define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) + #define SET(a, b, c, d, k, s, Ti)\ + t = a + G(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 1, 5, T17); + SET(d, a, b, c, 6, 9, T18); + SET(c, d, a, b, 11, 14, T19); + SET(b, c, d, a, 0, 20, T20); + SET(a, b, c, d, 5, 5, T21); + SET(d, a, b, c, 10, 9, T22); + SET(c, d, a, b, 15, 14, T23); + SET(b, c, d, a, 4, 20, T24); + SET(a, b, c, d, 9, 5, T25); + SET(d, a, b, c, 14, 9, T26); + SET(c, d, a, b, 3, 14, T27); + SET(b, c, d, a, 8, 20, T28); + SET(a, b, c, d, 13, 5, T29); + SET(d, a, b, c, 2, 9, T30); + SET(c, d, a, b, 7, 14, T31); + SET(b, c, d, a, 12, 20, T32); + #undef SET + + /* Round 3. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ + #define H(x, y, z) ((x) ^ (y) ^ (z)) + #define SET(a, b, c, d, k, s, Ti)\ + t = a + H(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 5, 4, T33); + SET(d, a, b, c, 8, 11, T34); + SET(c, d, a, b, 11, 16, T35); + SET(b, c, d, a, 14, 23, T36); + SET(a, b, c, d, 1, 4, T37); + SET(d, a, b, c, 4, 11, T38); + SET(c, d, a, b, 7, 16, T39); + SET(b, c, d, a, 10, 23, T40); + SET(a, b, c, d, 13, 4, T41); + SET(d, a, b, c, 0, 11, T42); + SET(c, d, a, b, 3, 16, T43); + SET(b, c, d, a, 6, 23, T44); + SET(a, b, c, d, 9, 4, T45); + SET(d, a, b, c, 12, 11, T46); + SET(c, d, a, b, 15, 16, T47); + SET(b, c, d, a, 2, 23, T48); + #undef SET + + /* Round 4. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ + #define I(x, y, z) ((y) ^ ((x) | ~(z))) + #define SET(a, b, c, d, k, s, Ti)\ + t = a + I(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 6, T49); + SET(d, a, b, c, 7, 10, T50); + SET(c, d, a, b, 14, 15, T51); + SET(b, c, d, a, 5, 21, T52); + SET(a, b, c, d, 12, 6, T53); + SET(d, a, b, c, 3, 10, T54); + SET(c, d, a, b, 10, 15, T55); + SET(b, c, d, a, 1, 21, T56); + SET(a, b, c, d, 8, 6, T57); + SET(d, a, b, c, 15, 10, T58); + SET(c, d, a, b, 6, 15, T59); + SET(b, c, d, a, 13, 21, T60); + SET(a, b, c, d, 4, 6, T61); + SET(d, a, b, c, 11, 10, T62); + SET(c, d, a, b, 2, 15, T63); + SET(b, c, d, a, 9, 21, T64); + #undef SET + + /* Then perform the following additions. (That is increment each + of the four registers by the value it had before this block + was started.) */ + state->abcd[0] += a; + state->abcd[1] += b; + state->abcd[2] += c; + state->abcd[3] += d; + } + } + + HashMD5::HashMD5() + { + m_state = new HashMD5_state; + } + + HashMD5::~HashMD5() + { + delete m_state; + } + + void HashMD5::Append(const UInt8* data, unsigned int len) + { + const UInt8 *p = data; + int left = len; + int offset = (m_state->count[0] >> 3) & 63; + UInt32 nbits = len << 3; + + if (len <= 0) + return; + + /* Update the message length. */ + m_state->count[1] += len >> 29; + m_state->count[0] += nbits; + if (m_state->count[0] < nbits) + m_state->count[1]++; + + /* Process an initial partial block. */ + if (offset) + { + int copy = (offset + len > 64 ? 64 - offset : len); + + std::memcpy(m_state->buf + offset, p, copy); + if (offset + copy < 64) + return; + + p += copy; + left -= copy; + md5_process(m_state, m_state->buf); + } + + /* Process full blocks. */ + for (; left >= 64; p += 64, left -= 64) + md5_process(m_state, p); + + /* Process a final partial block. */ + if (left) + std::memcpy(m_state->buf, p, left); + } + + void HashMD5::Begin() + { + m_state->count[0] = m_state->count[1] = 0; + m_state->abcd[0] = 0x67452301; + m_state->abcd[1] = /*0xefcdab89*/ T_MASK ^ 0x10325476; + m_state->abcd[2] = /*0x98badcfe*/ T_MASK ^ 0x67452301; + m_state->abcd[3] = 0x10325476; + } + + HashDigest HashMD5::End() + { + static const unsigned char pad[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + + UInt8 data[8]; + int i; + + /* Save the length before padding. */ + for (i = 0; i < 8; ++i) + data[i] = static_cast(m_state->count[i >> 2] >> ((i & 3) << 3)); + /* Pad to 56 bytes mod 64. */ + Append(pad, ((55 - (m_state->count[0] >> 3)) & 63) + 1); + /* Append the length. */ + Append(data, 8); + + UInt8 digest[16]; + for (i = 0; i < 16; ++i) + digest[i] = static_cast(m_state->abcd[i >> 2] >> ((i & 3) << 3)); + + return HashDigest(GetHashName(), &digest[0], 16); + } + + unsigned int HashMD5::GetDigestLength() + { + return 16; + } + + String HashMD5::GetHashName() + { + static String hashName = "MD5"; + return hashName; + } } - -unsigned int NzHashMD5::GetDigestLength() -{ - return 16; -} - -NzString NzHashMD5::GetHashName() -{ - static NzString hashName = "MD5"; - return hashName; -} - diff --git a/src/Nazara/Core/Hash/SHA/Internal.cpp b/src/Nazara/Core/Hash/SHA/Internal.cpp index 03fe266f4..ad5b1d30c 100644 --- a/src/Nazara/Core/Hash/SHA/Internal.cpp +++ b/src/Nazara/Core/Hash/SHA/Internal.cpp @@ -42,1019 +42,1023 @@ #include #include -/*** ENDIAN REVERSAL MACROS *******************************************/ -#ifdef NAZARA_LITTLE_ENDIAN - -#define REVERSE32(w,x) { \ - nzUInt32 tmp = (w); \ - tmp = (tmp >> 16) | (tmp << 16); \ - (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ -} - -#define REVERSE64(w,x) { \ - nzUInt64 tmp = (w); \ - tmp = (tmp >> 32) | (tmp << 32); \ - tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ - ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ - (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ - ((tmp & 0x0000ffff0000ffffULL) << 16); \ -} -#endif - -/* - * Macro for incrementally adding the unsigned 64-bit integer n to the - * unsigned 128-bit integer (represented using a two-element array of - * 64-bit words): - */ -#define ADDINC128(w,n) { \ - (w)[0] += static_cast(n); \ - if ((w)[0] < (n)) { \ - (w)[1]++; \ - } \ -} - - -/*** THE SIX LOGICAL FUNCTIONS ****************************************/ -/* - * Bit shifting and rotation (used by the six SHA-XYZ logical functions: - * - * NOTE: In the original SHA-256/384/512 document, the shift-right - * function was named R and the rotate-right function was called S. - * (See: http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf on the - * web.) - * - * The newer NIST FIPS 180-2 document uses a much clearer naming - * scheme, SHR for shift-right, ROTR for rotate-right, and ROTL for - * rotate-left. (See: - * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf - * on the web.) - * - * WARNING: These macros must be used cautiously, since they reference - * supplied parameters sometimes more than once, and thus could have - * unexpected side-effects if used without taking this into account. - */ -/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ -#define SHR(b,x) ((x) >> (b)) -/* 32-bit Rotate-right (used in SHA-256): */ -#define ROTR32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) -/* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ -#define ROTR64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) -/* 32-bit Rotate-left (used in SHA-1): */ -#define ROTL32(b,x) (((x) << (b)) | ((x) >> (32 - (b)))) - -/* Two logical functions used in SHA-1, SHA-254, SHA-256, SHA-384, and SHA-512: */ -#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) -#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) - -/* Function used in SHA-1: */ -#define Parity(x,y,z) ((x) ^ (y) ^ (z)) - -/* Four logical functions used in SHA-256: */ -#define Sigma0_256(x) (ROTR32(2, (x)) ^ ROTR32(13, (x)) ^ ROTR32(22, (x))) -#define Sigma1_256(x) (ROTR32(6, (x)) ^ ROTR32(11, (x)) ^ ROTR32(25, (x))) -#define sigma0_256(x) (ROTR32(7, (x)) ^ ROTR32(18, (x)) ^ SHR( 3 , (x))) -#define sigma1_256(x) (ROTR32(17, (x)) ^ ROTR32(19, (x)) ^ SHR( 10, (x))) - -/* Four of six logical functions used in SHA-384 and SHA-512: */ -#define Sigma0_512(x) (ROTR64(28, (x)) ^ ROTR64(34, (x)) ^ ROTR64(39, (x))) -#define Sigma1_512(x) (ROTR64(14, (x)) ^ ROTR64(18, (x)) ^ ROTR64(41, (x))) -#define sigma0_512(x) (ROTR64( 1, (x)) ^ ROTR64( 8, (x)) ^ SHR( 7, (x))) -#define sigma1_512(x) (ROTR64(19, (x)) ^ ROTR64(61, (x)) ^ SHR( 6, (x))) - -/*** INTERNAL FUNCTION PROTOTYPES *************************************/ - -/* SHA-224 and SHA-256: */ -void SHA256_Internal_Init(SHA_CTX*, const nzUInt32*); -void SHA256_Internal_Last(SHA_CTX*); -void SHA256_Internal_Transform(SHA_CTX*, const nzUInt32*); - -/* SHA-384 and SHA-512: */ -void SHA512_Internal_Init(SHA_CTX*, const nzUInt64*); -void SHA512_Internal_Last(SHA_CTX*); -void SHA512_Internal_Transform(SHA_CTX*, const nzUInt64*); - - -/*** SHA2 INITIAL HASH VALUES AND CONSTANTS ***************************/ - -/* Hash constant words K for SHA-1: */ -#define K1_0_TO_19 0x5a827999UL -#define K1_20_TO_39 0x6ed9eba1UL -#define K1_40_TO_59 0x8f1bbcdcUL -#define K1_60_TO_79 0xca62c1d6UL - -/* Initial hash value H for SHA-1: */ -const static nzUInt32 sha1_initial_hash_value[5] = { - 0x67452301UL, - 0xefcdab89UL, - 0x98badcfeUL, - 0x10325476UL, - 0xc3d2e1f0UL -}; - -/* Hash constant words K for SHA-224 and SHA-256: */ -const static nzUInt32 K256[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, - 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, - 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, - 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, - 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, - 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, - 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, - 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, - 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, - 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, - 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, - 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, - 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL -}; - -/* Initial hash value H for SHA-224: */ -const static nzUInt32 sha224_initial_hash_value[8] = { - 0xc1059ed8UL, - 0x367cd507UL, - 0x3070dd17UL, - 0xf70e5939UL, - 0xffc00b31UL, - 0x68581511UL, - 0x64f98fa7UL, - 0xbefa4fa4UL -}; - -/* Initial hash value H for SHA-256: */ -const static nzUInt32 sha256_initial_hash_value[8] = { - 0x6a09e667UL, - 0xbb67ae85UL, - 0x3c6ef372UL, - 0xa54ff53aUL, - 0x510e527fUL, - 0x9b05688cUL, - 0x1f83d9abUL, - 0x5be0cd19UL -}; - -/* Hash constant words K for SHA-384 and SHA-512: */ -const static nzUInt64 K512[80] = { - 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, - 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, - 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, - 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, - 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, - 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, - 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, - 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, - 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, - 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, - 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, - 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, - 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, - 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, - 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, - 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, - 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, - 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, - 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, - 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, - 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, - 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, - 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, - 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, - 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, - 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, - 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, - 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, - 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, - 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, - 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, - 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, - 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, - 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, - 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, - 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, - 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, - 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, - 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, - 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL -}; - -/* Initial hash value H for SHA-384 */ -const static nzUInt64 sha384_initial_hash_value[8] = { - 0xcbbb9d5dc1059ed8ULL, - 0x629a292a367cd507ULL, - 0x9159015a3070dd17ULL, - 0x152fecd8f70e5939ULL, - 0x67332667ffc00b31ULL, - 0x8eb44a8768581511ULL, - 0xdb0c2e0d64f98fa7ULL, - 0x47b5481dbefa4fa4ULL -}; - -/* Initial hash value H for SHA-512 */ -const static nzUInt64 sha512_initial_hash_value[8] = { - 0x6a09e667f3bcc908ULL, - 0xbb67ae8584caa73bULL, - 0x3c6ef372fe94f82bULL, - 0xa54ff53a5f1d36f1ULL, - 0x510e527fade682d1ULL, - 0x9b05688c2b3e6c1fULL, - 0x1f83d9abfb41bd6bULL, - 0x5be0cd19137e2179ULL -}; - - -/*** SHA-1: ***********************************************************/ -void SHA1_Init(SHA_CTX* context) +namespace Nz { - /* Sanity check: */ - std::memcpy(context->s1.state, sha1_initial_hash_value, sizeof(nzUInt32) * 5); - std::memset(context->s1.buffer, 0, 64); - context->s1.bitcount = 0; -} -#ifdef NAZARA_LITTLE_ENDIAN + /*** ENDIAN REVERSAL MACROS *******************************************/ + #ifdef NAZARA_LITTLE_ENDIAN -#define ROUND1_0_TO_15(a,b,c,d,e) \ - REVERSE32(*data++, W1[j]); \ - (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \ - K1_0_TO_19 + W1[j]; \ - (b) = ROTL32(30, (b)); \ - j++; + #define REVERSE32(w,x) { \ + UInt32 tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ + } -#else // NAZARA_LITTLE_ENDIAN + #define REVERSE64(w,x) { \ + UInt64 tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ + ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ + (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ + ((tmp & 0x0000ffff0000ffffULL) << 16); \ + } + #endif -#define ROUND1_0_TO_15(a,b,c,d,e) \ - (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \ - K1_0_TO_19 + ( W1[j] = *data++ ); \ - (b) = ROTL32(30, (b)); \ - j++; + /* + * Macro for incrementally adding the unsigned 64-bit integer n to the + * unsigned 128-bit integer (represented using a two-element array of + * 64-bit words): + */ + #define ADDINC128(w,n) { \ + (w)[0] += static_cast(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ + } -#endif // NAZARA_LITTLE_ENDIAN -#define ROUND1_16_TO_19(a,b,c,d,e) \ - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ - (e) = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ - (b) = ROTL32(30, b); \ - j++; + /*** THE SIX LOGICAL FUNCTIONS ****************************************/ + /* + * Bit shifting and rotation (used by the six SHA-XYZ logical functions: + * + * NOTE: In the original SHA-256/384/512 document, the shift-right + * function was named R and the rotate-right function was called S. + * (See: http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf on the + * web.) + * + * The newer NIST FIPS 180-2 document uses a much clearer naming + * scheme, SHR for shift-right, ROTR for rotate-right, and ROTL for + * rotate-left. (See: + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + * on the web.) + * + * WARNING: These macros must be used cautiously, since they reference + * supplied parameters sometimes more than once, and thus could have + * unexpected side-effects if used without taking this into account. + */ + /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ + #define SHR(b,x) ((x) >> (b)) + /* 32-bit Rotate-right (used in SHA-256): */ + #define ROTR32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) + /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ + #define ROTR64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) + /* 32-bit Rotate-left (used in SHA-1): */ + #define ROTL32(b,x) (((x) << (b)) | ((x) >> (32 - (b)))) -#define ROUND1_20_TO_39(a,b,c,d,e) \ - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ - (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ - (b) = ROTL32(30, b); \ - j++; + /* Two logical functions used in SHA-1, SHA-254, SHA-256, SHA-384, and SHA-512: */ + #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) + #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) -#define ROUND1_40_TO_59(a,b,c,d,e) \ - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ - (e) = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ - (b) = ROTL32(30, b); \ - j++; + /* Function used in SHA-1: */ + #define Parity(x,y,z) ((x) ^ (y) ^ (z)) -#define ROUND1_60_TO_79(a,b,c,d,e) \ - T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ - (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ - (b) = ROTL32(30, b); \ - j++; + /* Four logical functions used in SHA-256: */ + #define Sigma0_256(x) (ROTR32(2, (x)) ^ ROTR32(13, (x)) ^ ROTR32(22, (x))) + #define Sigma1_256(x) (ROTR32(6, (x)) ^ ROTR32(11, (x)) ^ ROTR32(25, (x))) + #define sigma0_256(x) (ROTR32(7, (x)) ^ ROTR32(18, (x)) ^ SHR( 3 , (x))) + #define sigma1_256(x) (ROTR32(17, (x)) ^ ROTR32(19, (x)) ^ SHR( 10, (x))) -namespace -{ - void SHA1_Internal_Transform(SHA_CTX* context, const nzUInt32* data) + /* Four of six logical functions used in SHA-384 and SHA-512: */ + #define Sigma0_512(x) (ROTR64(28, (x)) ^ ROTR64(34, (x)) ^ ROTR64(39, (x))) + #define Sigma1_512(x) (ROTR64(14, (x)) ^ ROTR64(18, (x)) ^ ROTR64(41, (x))) + #define sigma0_512(x) (ROTR64( 1, (x)) ^ ROTR64( 8, (x)) ^ SHR( 7, (x))) + #define sigma1_512(x) (ROTR64(19, (x)) ^ ROTR64(61, (x)) ^ SHR( 6, (x))) + + /*** INTERNAL FUNCTION PROTOTYPES *************************************/ + + /* SHA-224 and SHA-256: */ + void SHA256_Internal_Init(SHA_CTX*, const UInt32*); + void SHA256_Internal_Last(SHA_CTX*); + void SHA256_Internal_Transform(SHA_CTX*, const UInt32*); + + /* SHA-384 and SHA-512: */ + void SHA512_Internal_Init(SHA_CTX*, const UInt64*); + void SHA512_Internal_Last(SHA_CTX*); + void SHA512_Internal_Transform(SHA_CTX*, const UInt64*); + + + /*** SHA2 INITIAL HASH VALUES AND CONSTANTS ***************************/ + + /* Hash constant words K for SHA-1: */ + #define K1_0_TO_19 0x5a827999UL + #define K1_20_TO_39 0x6ed9eba1UL + #define K1_40_TO_59 0x8f1bbcdcUL + #define K1_60_TO_79 0xca62c1d6UL + + /* Initial hash value H for SHA-1: */ + const static UInt32 sha1_initial_hash_value[5] = { + 0x67452301UL, + 0xefcdab89UL, + 0x98badcfeUL, + 0x10325476UL, + 0xc3d2e1f0UL + }; + + /* Hash constant words K for SHA-224 and SHA-256: */ + const static UInt32 K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL + }; + + /* Initial hash value H for SHA-224: */ + const static UInt32 sha224_initial_hash_value[8] = { + 0xc1059ed8UL, + 0x367cd507UL, + 0x3070dd17UL, + 0xf70e5939UL, + 0xffc00b31UL, + 0x68581511UL, + 0x64f98fa7UL, + 0xbefa4fa4UL + }; + + /* Initial hash value H for SHA-256: */ + const static UInt32 sha256_initial_hash_value[8] = { + 0x6a09e667UL, + 0xbb67ae85UL, + 0x3c6ef372UL, + 0xa54ff53aUL, + 0x510e527fUL, + 0x9b05688cUL, + 0x1f83d9abUL, + 0x5be0cd19UL + }; + + /* Hash constant words K for SHA-384 and SHA-512: */ + const static UInt64 K512[80] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, + 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, + 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, + 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, + 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, + 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, + 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, + 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, + 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, + 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, + 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, + 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, + 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, + 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, + 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, + 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, + 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, + 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, + 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, + 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, + 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL + }; + + /* Initial hash value H for SHA-384 */ + const static UInt64 sha384_initial_hash_value[8] = { + 0xcbbb9d5dc1059ed8ULL, + 0x629a292a367cd507ULL, + 0x9159015a3070dd17ULL, + 0x152fecd8f70e5939ULL, + 0x67332667ffc00b31ULL, + 0x8eb44a8768581511ULL, + 0xdb0c2e0d64f98fa7ULL, + 0x47b5481dbefa4fa4ULL + }; + + /* Initial hash value H for SHA-512 */ + const static UInt64 sha512_initial_hash_value[8] = { + 0x6a09e667f3bcc908ULL, + 0xbb67ae8584caa73bULL, + 0x3c6ef372fe94f82bULL, + 0xa54ff53a5f1d36f1ULL, + 0x510e527fade682d1ULL, + 0x9b05688c2b3e6c1fULL, + 0x1f83d9abfb41bd6bULL, + 0x5be0cd19137e2179ULL + }; + + + /*** SHA-1: ***********************************************************/ + void SHA1_Init(SHA_CTX* context) { - nzUInt32 a, b, c, d, e; - nzUInt32 T1, *W1; + /* Sanity check: */ + std::memcpy(context->s1.state, sha1_initial_hash_value, sizeof(UInt32) * 5); + std::memset(context->s1.buffer, 0, 64); + context->s1.bitcount = 0; + } + + #ifdef NAZARA_LITTLE_ENDIAN + + #define ROUND1_0_TO_15(a,b,c,d,e) \ + REVERSE32(*data++, W1[j]); \ + (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \ + K1_0_TO_19 + W1[j]; \ + (b) = ROTL32(30, (b)); \ + j++; + + #else // NAZARA_LITTLE_ENDIAN + + #define ROUND1_0_TO_15(a,b,c,d,e) \ + (e) = ROTL32(5, (a)) + Ch((b), (c), (d)) + (e) + \ + K1_0_TO_19 + ( W1[j] = *data++ ); \ + (b) = ROTL32(30, (b)); \ + j++; + + #endif // NAZARA_LITTLE_ENDIAN + + #define ROUND1_16_TO_19(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Ch(b,c,d) + e + K1_0_TO_19 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + + #define ROUND1_20_TO_39(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_20_TO_39 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + + #define ROUND1_40_TO_59(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Maj(b,c,d) + e + K1_40_TO_59 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + + #define ROUND1_60_TO_79(a,b,c,d,e) \ + T1 = W1[(j+13)&0x0f] ^ W1[(j+8)&0x0f] ^ W1[(j+2)&0x0f] ^ W1[j&0x0f]; \ + (e) = ROTL32(5, a) + Parity(b,c,d) + e + K1_60_TO_79 + ( W1[j&0x0f] = ROTL32(1, T1) ); \ + (b) = ROTL32(30, b); \ + j++; + + namespace + { + void SHA1_Internal_Transform(SHA_CTX* context, const UInt32* data) + { + UInt32 a, b, c, d, e; + UInt32 T1, *W1; + int j; + + W1 = reinterpret_cast(context->s1.buffer); + + /* Initialize registers with the prev. intermediate value */ + a = context->s1.state[0]; + b = context->s1.state[1]; + c = context->s1.state[2]; + d = context->s1.state[3]; + e = context->s1.state[4]; + + j = 0; + + /* Rounds 0 to 15 unrolled: */ + ROUND1_0_TO_15(a,b,c,d,e); + ROUND1_0_TO_15(e,a,b,c,d); + ROUND1_0_TO_15(d,e,a,b,c); + ROUND1_0_TO_15(c,d,e,a,b); + ROUND1_0_TO_15(b,c,d,e,a); + ROUND1_0_TO_15(a,b,c,d,e); + ROUND1_0_TO_15(e,a,b,c,d); + ROUND1_0_TO_15(d,e,a,b,c); + ROUND1_0_TO_15(c,d,e,a,b); + ROUND1_0_TO_15(b,c,d,e,a); + ROUND1_0_TO_15(a,b,c,d,e); + ROUND1_0_TO_15(e,a,b,c,d); + ROUND1_0_TO_15(d,e,a,b,c); + ROUND1_0_TO_15(c,d,e,a,b); + ROUND1_0_TO_15(b,c,d,e,a); + ROUND1_0_TO_15(a,b,c,d,e); + + /* Rounds 16 to 19 unrolled: */ + ROUND1_16_TO_19(e,a,b,c,d); + ROUND1_16_TO_19(d,e,a,b,c); + ROUND1_16_TO_19(c,d,e,a,b); + ROUND1_16_TO_19(b,c,d,e,a); + + /* Rounds 20 to 39 unrolled: */ + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + ROUND1_20_TO_39(a,b,c,d,e); + ROUND1_20_TO_39(e,a,b,c,d); + ROUND1_20_TO_39(d,e,a,b,c); + ROUND1_20_TO_39(c,d,e,a,b); + ROUND1_20_TO_39(b,c,d,e,a); + + /* Rounds 40 to 59 unrolled: */ + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + ROUND1_40_TO_59(a,b,c,d,e); + ROUND1_40_TO_59(e,a,b,c,d); + ROUND1_40_TO_59(d,e,a,b,c); + ROUND1_40_TO_59(c,d,e,a,b); + ROUND1_40_TO_59(b,c,d,e,a); + + /* Rounds 60 to 79 unrolled: */ + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + ROUND1_60_TO_79(a,b,c,d,e); + ROUND1_60_TO_79(e,a,b,c,d); + ROUND1_60_TO_79(d,e,a,b,c); + ROUND1_60_TO_79(c,d,e,a,b); + ROUND1_60_TO_79(b,c,d,e,a); + + /* Compute the current intermediate hash value */ + context->s1.state[0] += a; + context->s1.state[1] += b; + context->s1.state[2] += c; + context->s1.state[3] += d; + context->s1.state[4] += e; + } + } + + void SHA1_Update(SHA_CTX* context, const UInt8* data, std::size_t len) + { + if (len == 0) + /* Calling with no data is valid - we do nothing */ + return; + + unsigned int usedspace = (context->s1.bitcount >> 3) % 64; + if (usedspace > 0) + { + /* Calculate how much free space is available in the buffer */ + unsigned int freespace = 64 - usedspace; + + if (len >= freespace) + { + /* Fill the buffer completely and process it */ + std::memcpy(&context->s1.buffer[usedspace], data, freespace); + context->s1.bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA1_Internal_Transform(context, reinterpret_cast(context->s1.buffer)); + } + else + { + /* The buffer is not yet full */ + std::memcpy(&context->s1.buffer[usedspace], data, len); + context->s1.bitcount += len << 3; + return; + } + } + + while (len >= 64) + { + /* Process as many complete blocks as we can */ + SHA1_Internal_Transform(context, reinterpret_cast(data)); + context->s1.bitcount += 512; + len -= 64; + data += 64; + } + + if (len > 0) + { + /* There's left-overs, so save 'em */ + std::memcpy(context->s1.buffer, data, len); + context->s1.bitcount += len << 3; + } + } + + void SHA1_End(SHA_CTX* context, UInt8* digest) + { + UInt32* d = reinterpret_cast(digest); + unsigned int usedspace = (context->s1.bitcount >> 3) % 64; + + if (usedspace == 0) + { + /* Set-up for the last transform: */ + std::memset(context->s1.buffer, 0, 56); + + /* Begin padding with a 1 bit: */ + *context->s1.buffer = 0x80; + } + else + { + /* Begin padding with a 1 bit: */ + context->s1.buffer[usedspace++] = 0x80; + + if (usedspace <= 56) + /* Set-up for the last transform: */ + std::memset(&context->s1.buffer[usedspace], 0, 56 - usedspace); + else + { + if (usedspace < 64) + std::memset(&context->s1.buffer[usedspace], 0, 64 - usedspace); + + /* Do second-to-last transform: */ + SHA1_Internal_Transform(context, reinterpret_cast(context->s1.buffer)); + + /* And set-up for the last transform: */ + std::memset(context->s1.buffer, 0, 56); + } + } + /* Set the bit count: */ + #ifdef NAZARA_LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->s1.bitcount,context->s1.bitcount); + #endif + UInt64* length = reinterpret_cast(&context->s1.buffer[56]); + *length = context->s1.bitcount; + + /* Final transform: */ + SHA1_Internal_Transform(context, reinterpret_cast(context->s1.buffer)); + + /* Save the hash data for output: */ + #ifdef NAZARA_LITTLE_ENDIAN + { + /* Convert TO host byte order */ + for (int j = 0; j < (SHA1_DIGEST_LENGTH >> 2); j++) + { + REVERSE32(context->s1.state[j],context->s1.state[j]); + *d++ = context->s1.state[j]; + } + } + #else + std::memcpy(d, context->s1.state, SHA1_DIGEST_LENGTH); + #endif + } + + + /*** SHA-256: *********************************************************/ + void SHA256_Internal_Init(SHA_CTX* context, const UInt32* ihv) + { + std::memcpy(context->s256.state, ihv, sizeof(UInt32) * 8); + std::memset(context->s256.buffer, 0, 64); + context->s256.bitcount = 0; + } + + void SHA256_Init(SHA_CTX* context) + { + SHA256_Internal_Init(context, sha256_initial_hash_value); + } + + #ifdef NAZARA_LITTLE_ENDIAN + + #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE32(*data++, W256[j]); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + W256[j]; \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + + #else // NAZARA_LITTLE_ENDIAN + + #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + (W256[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + + #endif // NAZARA_LITTLE_ENDIAN + + #define ROUND256(a,b,c,d,e,f,g,h) \ + s0 = W256[(j+1)&0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j+14)&0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + + void SHA256_Internal_Transform(SHA_CTX* context, const UInt32* data) + { + UInt32 a, b, c, d, e, f, g, h; + UInt32 T1, *W256; int j; - W1 = reinterpret_cast(context->s1.buffer); + W256 = reinterpret_cast(context->s256.buffer); /* Initialize registers with the prev. intermediate value */ - a = context->s1.state[0]; - b = context->s1.state[1]; - c = context->s1.state[2]; - d = context->s1.state[3]; - e = context->s1.state[4]; + a = context->s256.state[0]; + b = context->s256.state[1]; + c = context->s256.state[2]; + d = context->s256.state[3]; + e = context->s256.state[4]; + f = context->s256.state[5]; + g = context->s256.state[6]; + h = context->s256.state[7]; j = 0; + do + { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a,b,c,d,e,f,g,h); + ROUND256_0_TO_15(h,a,b,c,d,e,f,g); + ROUND256_0_TO_15(g,h,a,b,c,d,e,f); + ROUND256_0_TO_15(f,g,h,a,b,c,d,e); + ROUND256_0_TO_15(e,f,g,h,a,b,c,d); + ROUND256_0_TO_15(d,e,f,g,h,a,b,c); + ROUND256_0_TO_15(c,d,e,f,g,h,a,b); + ROUND256_0_TO_15(b,c,d,e,f,g,h,a); + } + while (j < 16); - /* Rounds 0 to 15 unrolled: */ - ROUND1_0_TO_15(a,b,c,d,e); - ROUND1_0_TO_15(e,a,b,c,d); - ROUND1_0_TO_15(d,e,a,b,c); - ROUND1_0_TO_15(c,d,e,a,b); - ROUND1_0_TO_15(b,c,d,e,a); - ROUND1_0_TO_15(a,b,c,d,e); - ROUND1_0_TO_15(e,a,b,c,d); - ROUND1_0_TO_15(d,e,a,b,c); - ROUND1_0_TO_15(c,d,e,a,b); - ROUND1_0_TO_15(b,c,d,e,a); - ROUND1_0_TO_15(a,b,c,d,e); - ROUND1_0_TO_15(e,a,b,c,d); - ROUND1_0_TO_15(d,e,a,b,c); - ROUND1_0_TO_15(c,d,e,a,b); - ROUND1_0_TO_15(b,c,d,e,a); - ROUND1_0_TO_15(a,b,c,d,e); + /* Now for the remaining rounds to 64: */ + do + { + UInt32 s0, s1; - /* Rounds 16 to 19 unrolled: */ - ROUND1_16_TO_19(e,a,b,c,d); - ROUND1_16_TO_19(d,e,a,b,c); - ROUND1_16_TO_19(c,d,e,a,b); - ROUND1_16_TO_19(b,c,d,e,a); - - /* Rounds 20 to 39 unrolled: */ - ROUND1_20_TO_39(a,b,c,d,e); - ROUND1_20_TO_39(e,a,b,c,d); - ROUND1_20_TO_39(d,e,a,b,c); - ROUND1_20_TO_39(c,d,e,a,b); - ROUND1_20_TO_39(b,c,d,e,a); - ROUND1_20_TO_39(a,b,c,d,e); - ROUND1_20_TO_39(e,a,b,c,d); - ROUND1_20_TO_39(d,e,a,b,c); - ROUND1_20_TO_39(c,d,e,a,b); - ROUND1_20_TO_39(b,c,d,e,a); - ROUND1_20_TO_39(a,b,c,d,e); - ROUND1_20_TO_39(e,a,b,c,d); - ROUND1_20_TO_39(d,e,a,b,c); - ROUND1_20_TO_39(c,d,e,a,b); - ROUND1_20_TO_39(b,c,d,e,a); - ROUND1_20_TO_39(a,b,c,d,e); - ROUND1_20_TO_39(e,a,b,c,d); - ROUND1_20_TO_39(d,e,a,b,c); - ROUND1_20_TO_39(c,d,e,a,b); - ROUND1_20_TO_39(b,c,d,e,a); - - /* Rounds 40 to 59 unrolled: */ - ROUND1_40_TO_59(a,b,c,d,e); - ROUND1_40_TO_59(e,a,b,c,d); - ROUND1_40_TO_59(d,e,a,b,c); - ROUND1_40_TO_59(c,d,e,a,b); - ROUND1_40_TO_59(b,c,d,e,a); - ROUND1_40_TO_59(a,b,c,d,e); - ROUND1_40_TO_59(e,a,b,c,d); - ROUND1_40_TO_59(d,e,a,b,c); - ROUND1_40_TO_59(c,d,e,a,b); - ROUND1_40_TO_59(b,c,d,e,a); - ROUND1_40_TO_59(a,b,c,d,e); - ROUND1_40_TO_59(e,a,b,c,d); - ROUND1_40_TO_59(d,e,a,b,c); - ROUND1_40_TO_59(c,d,e,a,b); - ROUND1_40_TO_59(b,c,d,e,a); - ROUND1_40_TO_59(a,b,c,d,e); - ROUND1_40_TO_59(e,a,b,c,d); - ROUND1_40_TO_59(d,e,a,b,c); - ROUND1_40_TO_59(c,d,e,a,b); - ROUND1_40_TO_59(b,c,d,e,a); - - /* Rounds 60 to 79 unrolled: */ - ROUND1_60_TO_79(a,b,c,d,e); - ROUND1_60_TO_79(e,a,b,c,d); - ROUND1_60_TO_79(d,e,a,b,c); - ROUND1_60_TO_79(c,d,e,a,b); - ROUND1_60_TO_79(b,c,d,e,a); - ROUND1_60_TO_79(a,b,c,d,e); - ROUND1_60_TO_79(e,a,b,c,d); - ROUND1_60_TO_79(d,e,a,b,c); - ROUND1_60_TO_79(c,d,e,a,b); - ROUND1_60_TO_79(b,c,d,e,a); - ROUND1_60_TO_79(a,b,c,d,e); - ROUND1_60_TO_79(e,a,b,c,d); - ROUND1_60_TO_79(d,e,a,b,c); - ROUND1_60_TO_79(c,d,e,a,b); - ROUND1_60_TO_79(b,c,d,e,a); - ROUND1_60_TO_79(a,b,c,d,e); - ROUND1_60_TO_79(e,a,b,c,d); - ROUND1_60_TO_79(d,e,a,b,c); - ROUND1_60_TO_79(c,d,e,a,b); - ROUND1_60_TO_79(b,c,d,e,a); + ROUND256(a,b,c,d,e,f,g,h); + ROUND256(h,a,b,c,d,e,f,g); + ROUND256(g,h,a,b,c,d,e,f); + ROUND256(f,g,h,a,b,c,d,e); + ROUND256(e,f,g,h,a,b,c,d); + ROUND256(d,e,f,g,h,a,b,c); + ROUND256(c,d,e,f,g,h,a,b); + ROUND256(b,c,d,e,f,g,h,a); + } + while (j < 64); /* Compute the current intermediate hash value */ - context->s1.state[0] += a; - context->s1.state[1] += b; - context->s1.state[2] += c; - context->s1.state[3] += d; - context->s1.state[4] += e; + context->s256.state[0] += a; + context->s256.state[1] += b; + context->s256.state[2] += c; + context->s256.state[3] += d; + context->s256.state[4] += e; + context->s256.state[5] += f; + context->s256.state[6] += g; + context->s256.state[7] += h; } -} -void SHA1_Update(SHA_CTX* context, const nzUInt8* data, std::size_t len) -{ - if (len == 0) - /* Calling with no data is valid - we do nothing */ - return; - - unsigned int usedspace = (context->s1.bitcount >> 3) % 64; - if (usedspace > 0) + void SHA256_Update(SHA_CTX* context, const UInt8 *data, std::size_t len) { - /* Calculate how much free space is available in the buffer */ - unsigned int freespace = 64 - usedspace; - - if (len >= freespace) - { - /* Fill the buffer completely and process it */ - std::memcpy(&context->s1.buffer[usedspace], data, freespace); - context->s1.bitcount += freespace << 3; - len -= freespace; - data += freespace; - SHA1_Internal_Transform(context, reinterpret_cast(context->s1.buffer)); - } - else - { - /* The buffer is not yet full */ - std::memcpy(&context->s1.buffer[usedspace], data, len); - context->s1.bitcount += len << 3; + if (len == 0) + /* Calling with no data is valid - we do nothing */ return; - } - } - while (len >= 64) - { - /* Process as many complete blocks as we can */ - SHA1_Internal_Transform(context, reinterpret_cast(data)); - context->s1.bitcount += 512; - len -= 64; - data += 64; - } - - if (len > 0) - { - /* There's left-overs, so save 'em */ - std::memcpy(context->s1.buffer, data, len); - context->s1.bitcount += len << 3; - } -} - -void SHA1_End(SHA_CTX* context, nzUInt8* digest) -{ - nzUInt32* d = reinterpret_cast(digest); - unsigned int usedspace = (context->s1.bitcount >> 3) % 64; - - if (usedspace == 0) - { - /* Set-up for the last transform: */ - std::memset(context->s1.buffer, 0, 56); - - /* Begin padding with a 1 bit: */ - *context->s1.buffer = 0x80; - } - else - { - /* Begin padding with a 1 bit: */ - context->s1.buffer[usedspace++] = 0x80; - - if (usedspace <= 56) - /* Set-up for the last transform: */ - std::memset(&context->s1.buffer[usedspace], 0, 56 - usedspace); - else + unsigned int usedspace = (context->s256.bitcount >> 3) % 64; + if (usedspace > 0) { - if (usedspace < 64) - std::memset(&context->s1.buffer[usedspace], 0, 64 - usedspace); + /* Calculate how much free space is available in the buffer */ + unsigned int freespace = 64 - usedspace; - /* Do second-to-last transform: */ - SHA1_Internal_Transform(context, reinterpret_cast(context->s1.buffer)); - - /* And set-up for the last transform: */ - std::memset(context->s1.buffer, 0, 56); + if (len >= freespace) + { + /* Fill the buffer completely and process it */ + std::memcpy(&context->s256.buffer[usedspace], data, freespace); + context->s256.bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA256_Internal_Transform(context, reinterpret_cast(context->s256.buffer)); + } + else + { + /* The buffer is not yet full */ + std::memcpy(&context->s256.buffer[usedspace], data, len); + context->s256.bitcount += len << 3; + return; + } } - } - /* Set the bit count: */ -#ifdef NAZARA_LITTLE_ENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->s1.bitcount,context->s1.bitcount); -#endif - nzUInt64* length = reinterpret_cast(&context->s1.buffer[56]); - *length = context->s1.bitcount; - /* Final transform: */ - SHA1_Internal_Transform(context, reinterpret_cast(context->s1.buffer)); - - /* Save the hash data for output: */ -#ifdef NAZARA_LITTLE_ENDIAN - { - /* Convert TO host byte order */ - for (int j = 0; j < (SHA1_DIGEST_LENGTH >> 2); j++) + while (len >= 64) { - REVERSE32(context->s1.state[j],context->s1.state[j]); - *d++ = context->s1.state[j]; + /* Process as many complete blocks as we can */ + SHA256_Internal_Transform(context, reinterpret_cast(data)); + context->s256.bitcount += 512; + len -= 64; + data += 64; } - } -#else - std::memcpy(d, context->s1.state, SHA1_DIGEST_LENGTH); -#endif -} - -/*** SHA-256: *********************************************************/ -void SHA256_Internal_Init(SHA_CTX* context, const nzUInt32* ihv) -{ - std::memcpy(context->s256.state, ihv, sizeof(nzUInt32) * 8); - std::memset(context->s256.buffer, 0, 64); - context->s256.bitcount = 0; -} - -void SHA256_Init(SHA_CTX* context) -{ - SHA256_Internal_Init(context, sha256_initial_hash_value); -} - -#ifdef NAZARA_LITTLE_ENDIAN - -#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - REVERSE32(*data++, W256[j]); \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ - K256[j] + W256[j]; \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ - -#else // NAZARA_LITTLE_ENDIAN - -#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ - K256[j] + (W256[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ - -#endif // NAZARA_LITTLE_ENDIAN - -#define ROUND256(a,b,c,d,e,f,g,h) \ - s0 = W256[(j+1)&0x0f]; \ - s0 = sigma0_256(s0); \ - s1 = W256[(j+14)&0x0f]; \ - s1 = sigma1_256(s1); \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ - (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ - -void SHA256_Internal_Transform(SHA_CTX* context, const nzUInt32* data) -{ - nzUInt32 a, b, c, d, e, f, g, h; - nzUInt32 T1, *W256; - int j; - - W256 = reinterpret_cast(context->s256.buffer); - - /* Initialize registers with the prev. intermediate value */ - a = context->s256.state[0]; - b = context->s256.state[1]; - c = context->s256.state[2]; - d = context->s256.state[3]; - e = context->s256.state[4]; - f = context->s256.state[5]; - g = context->s256.state[6]; - h = context->s256.state[7]; - - j = 0; - do - { - /* Rounds 0 to 15 (unrolled): */ - ROUND256_0_TO_15(a,b,c,d,e,f,g,h); - ROUND256_0_TO_15(h,a,b,c,d,e,f,g); - ROUND256_0_TO_15(g,h,a,b,c,d,e,f); - ROUND256_0_TO_15(f,g,h,a,b,c,d,e); - ROUND256_0_TO_15(e,f,g,h,a,b,c,d); - ROUND256_0_TO_15(d,e,f,g,h,a,b,c); - ROUND256_0_TO_15(c,d,e,f,g,h,a,b); - ROUND256_0_TO_15(b,c,d,e,f,g,h,a); - } - while (j < 16); - - /* Now for the remaining rounds to 64: */ - do - { - nzUInt32 s0, s1; - - ROUND256(a,b,c,d,e,f,g,h); - ROUND256(h,a,b,c,d,e,f,g); - ROUND256(g,h,a,b,c,d,e,f); - ROUND256(f,g,h,a,b,c,d,e); - ROUND256(e,f,g,h,a,b,c,d); - ROUND256(d,e,f,g,h,a,b,c); - ROUND256(c,d,e,f,g,h,a,b); - ROUND256(b,c,d,e,f,g,h,a); - } - while (j < 64); - - /* Compute the current intermediate hash value */ - context->s256.state[0] += a; - context->s256.state[1] += b; - context->s256.state[2] += c; - context->s256.state[3] += d; - context->s256.state[4] += e; - context->s256.state[5] += f; - context->s256.state[6] += g; - context->s256.state[7] += h; -} - -void SHA256_Update(SHA_CTX* context, const nzUInt8 *data, std::size_t len) -{ - if (len == 0) - /* Calling with no data is valid - we do nothing */ - return; - - unsigned int usedspace = (context->s256.bitcount >> 3) % 64; - if (usedspace > 0) - { - /* Calculate how much free space is available in the buffer */ - unsigned int freespace = 64 - usedspace; - - if (len >= freespace) + if (len > 0) { - /* Fill the buffer completely and process it */ - std::memcpy(&context->s256.buffer[usedspace], data, freespace); - context->s256.bitcount += freespace << 3; - len -= freespace; - data += freespace; - SHA256_Internal_Transform(context, reinterpret_cast(context->s256.buffer)); - } - else - { - /* The buffer is not yet full */ - std::memcpy(&context->s256.buffer[usedspace], data, len); + /* There's left-overs, so save 'em */ + std::memcpy(context->s256.buffer, data, len); context->s256.bitcount += len << 3; - return; } } - while (len >= 64) + void SHA256_Internal_Last(SHA_CTX* context) { - /* Process as many complete blocks as we can */ - SHA256_Internal_Transform(context, reinterpret_cast(data)); - context->s256.bitcount += 512; - len -= 64; - data += 64; - } + unsigned int usedspace = (context->s256.bitcount >> 3) % 64; + #ifdef NAZARA_LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->s256.bitcount,context->s256.bitcount); + #endif + if (usedspace > 0) + { + /* Begin padding with a 1 bit: */ + context->s256.buffer[usedspace++] = 0x80; - if (len > 0) - { - /* There's left-overs, so save 'em */ - std::memcpy(context->s256.buffer, data, len); - context->s256.bitcount += len << 3; - } -} + if (usedspace <= 56) + /* Set-up for the last transform: */ + std::memset(&context->s256.buffer[usedspace], 0, 56 - usedspace); + else + { + if (usedspace < 64) + std::memset(&context->s256.buffer[usedspace], 0, 64 - usedspace); -void SHA256_Internal_Last(SHA_CTX* context) -{ - unsigned int usedspace = (context->s256.bitcount >> 3) % 64; -#ifdef NAZARA_LITTLE_ENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->s256.bitcount,context->s256.bitcount); -#endif - if (usedspace > 0) - { - /* Begin padding with a 1 bit: */ - context->s256.buffer[usedspace++] = 0x80; + /* Do second-to-last transform: */ + SHA256_Internal_Transform(context, reinterpret_cast(context->s256.buffer)); - if (usedspace <= 56) - /* Set-up for the last transform: */ - std::memset(&context->s256.buffer[usedspace], 0, 56 - usedspace); + /* And set-up for the last transform: */ + std::memset(context->s256.buffer, 0, 56); + } + } else { - if (usedspace < 64) - std::memset(&context->s256.buffer[usedspace], 0, 64 - usedspace); - - /* Do second-to-last transform: */ - SHA256_Internal_Transform(context, reinterpret_cast(context->s256.buffer)); - - /* And set-up for the last transform: */ + /* Set-up for the last transform: */ std::memset(context->s256.buffer, 0, 56); + + /* Begin padding with a 1 bit: */ + *context->s256.buffer = 0x80; } - } - else - { - /* Set-up for the last transform: */ - std::memset(context->s256.buffer, 0, 56); - /* Begin padding with a 1 bit: */ - *context->s256.buffer = 0x80; + /* Set the bit count: */ + UInt64* length = reinterpret_cast(&context->s256.buffer[56]); + *length = context->s256.bitcount; + + /* Final transform: */ + SHA256_Internal_Transform(context, reinterpret_cast(context->s256.buffer)); } - /* Set the bit count: */ - nzUInt64* length = reinterpret_cast(&context->s256.buffer[56]); - *length = context->s256.bitcount; - - /* Final transform: */ - SHA256_Internal_Transform(context, reinterpret_cast(context->s256.buffer)); -} - -void SHA256_End(SHA_CTX* context, nzUInt8* digest) -{ - nzUInt32* d = reinterpret_cast(digest); - - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest) + void SHA256_End(SHA_CTX* context, UInt8* digest) { - SHA256_Internal_Last(context); + UInt32* d = reinterpret_cast(digest); - /* Save the hash data for output: */ -#ifdef NAZARA_LITTLE_ENDIAN + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest) { - /* Convert TO host byte order */ - for (int j = 0; j < (SHA256_DIGEST_LENGTH >> 2); j++) + SHA256_Internal_Last(context); + + /* Save the hash data for output: */ + #ifdef NAZARA_LITTLE_ENDIAN { - REVERSE32(context->s256.state[j],context->s256.state[j]); - *d++ = context->s256.state[j]; + /* Convert TO host byte order */ + for (int j = 0; j < (SHA256_DIGEST_LENGTH >> 2); j++) + { + REVERSE32(context->s256.state[j],context->s256.state[j]); + *d++ = context->s256.state[j]; + } } + #else + std::memcpy(d, context->s256.state, SHA256_DIGEST_LENGTH); + #endif } -#else - std::memcpy(d, context->s256.state, SHA256_DIGEST_LENGTH); -#endif } -} -/*** SHA-224: *********************************************************/ -void SHA224_Init(SHA_CTX* context) -{ - SHA256_Internal_Init(context, sha224_initial_hash_value); -} - -void SHA224_Update(SHA_CTX* context, const nzUInt8 *data, std::size_t len) -{ - SHA256_Update(context, data, len); -} - -void SHA224_End(SHA_CTX* context, nzUInt8* digest) -{ - nzUInt32* d = reinterpret_cast(digest); - - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest) + /*** SHA-224: *********************************************************/ + void SHA224_Init(SHA_CTX* context) { - SHA256_Internal_Last(context); + SHA256_Internal_Init(context, sha224_initial_hash_value); + } - /* Save the hash data for output: */ -#ifdef NAZARA_LITTLE_ENDIAN + void SHA224_Update(SHA_CTX* context, const UInt8 *data, std::size_t len) + { + SHA256_Update(context, data, len); + } + + void SHA224_End(SHA_CTX* context, UInt8* digest) + { + UInt32* d = reinterpret_cast(digest); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest) { - /* Convert TO host byte order */ - for (int j = 0; j < (SHA224_DIGEST_LENGTH >> 2); j++) + SHA256_Internal_Last(context); + + /* Save the hash data for output: */ + #ifdef NAZARA_LITTLE_ENDIAN { - REVERSE32(context->s256.state[j],context->s256.state[j]); - *d++ = context->s256.state[j]; + /* Convert TO host byte order */ + for (int j = 0; j < (SHA224_DIGEST_LENGTH >> 2); j++) + { + REVERSE32(context->s256.state[j],context->s256.state[j]); + *d++ = context->s256.state[j]; + } } + #else + std::memcpy(d, context->s256.state, SHA224_DIGEST_LENGTH); + #endif } -#else - std::memcpy(d, context->s256.state, SHA224_DIGEST_LENGTH); -#endif } -} -/*** SHA-512: *********************************************************/ -void SHA512_Internal_Init(SHA_CTX* context, const nzUInt64* ihv) -{ - std::memcpy(context->s512.state, ihv, sizeof(nzUInt64) * 8); - std::memset(context->s512.buffer, 0, 128); - context->s512.bitcount[0] = context->s512.bitcount[1] = 0; -} - -void SHA512_Init(SHA_CTX* context) -{ - SHA512_Internal_Init(context, sha512_initial_hash_value); -} - -/* Unrolled SHA-512 round macros: */ -#ifdef NAZARA_LITTLE_ENDIAN - -#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ - REVERSE64(*data++, W512[j]); \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ - K512[j] + W512[j]; \ - (d) += T1, \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ - j++ - - -#else // NAZARA_LITTLE_ENDIAN - -#define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ - K512[j] + (W512[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ - -#endif // NAZARA_LITTLE_ENDIAN - -#define ROUND512(a,b,c,d,e,f,g,h) \ - s0 = W512[(j+1)&0x0f]; \ - s0 = sigma0_512(s0); \ - s1 = W512[(j+14)&0x0f]; \ - s1 = sigma1_512(s1); \ - T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ - (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ - j++ - -void SHA512_Internal_Transform(SHA_CTX* context, const nzUInt64* data) -{ - nzUInt64 a, b, c, d, e, f, g, h, s0, s1; - nzUInt64 T1, *W512 = reinterpret_cast(context->s512.buffer); - int j; - - /* Initialize registers with the prev. intermediate value */ - a = context->s512.state[0]; - b = context->s512.state[1]; - c = context->s512.state[2]; - d = context->s512.state[3]; - e = context->s512.state[4]; - f = context->s512.state[5]; - g = context->s512.state[6]; - h = context->s512.state[7]; - - j = 0; - do + /*** SHA-512: *********************************************************/ + void SHA512_Internal_Init(SHA_CTX* context, const UInt64* ihv) { - ROUND512_0_TO_15(a,b,c,d,e,f,g,h); - ROUND512_0_TO_15(h,a,b,c,d,e,f,g); - ROUND512_0_TO_15(g,h,a,b,c,d,e,f); - ROUND512_0_TO_15(f,g,h,a,b,c,d,e); - ROUND512_0_TO_15(e,f,g,h,a,b,c,d); - ROUND512_0_TO_15(d,e,f,g,h,a,b,c); - ROUND512_0_TO_15(c,d,e,f,g,h,a,b); - ROUND512_0_TO_15(b,c,d,e,f,g,h,a); + std::memcpy(context->s512.state, ihv, sizeof(UInt64) * 8); + std::memset(context->s512.buffer, 0, 128); + context->s512.bitcount[0] = context->s512.bitcount[1] = 0; } - while (j < 16); - /* Now for the remaining rounds up to 79: */ - do + void SHA512_Init(SHA_CTX* context) { - ROUND512(a,b,c,d,e,f,g,h); - ROUND512(h,a,b,c,d,e,f,g); - ROUND512(g,h,a,b,c,d,e,f); - ROUND512(f,g,h,a,b,c,d,e); - ROUND512(e,f,g,h,a,b,c,d); - ROUND512(d,e,f,g,h,a,b,c); - ROUND512(c,d,e,f,g,h,a,b); - ROUND512(b,c,d,e,f,g,h,a); + SHA512_Internal_Init(context, sha512_initial_hash_value); } - while (j < 80); - /* Compute the current intermediate hash value */ - context->s512.state[0] += a; - context->s512.state[1] += b; - context->s512.state[2] += c; - context->s512.state[3] += d; - context->s512.state[4] += e; - context->s512.state[5] += f; - context->s512.state[6] += g; - context->s512.state[7] += h; -} + /* Unrolled SHA-512 round macros: */ + #ifdef NAZARA_LITTLE_ENDIAN -void SHA512_Update(SHA_CTX* context, const nzUInt8 *data, std::size_t len) -{ - if (len == 0) - /* Calling with no data is valid - we do nothing */ - return; + #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE64(*data++, W512[j]); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + W512[j]; \ + (d) += T1, \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ + j++ - unsigned int usedspace = (context->s512.bitcount[0] >> 3) % 128; - if (usedspace > 0) + + #else // NAZARA_LITTLE_ENDIAN + + #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ + K512[j] + (W512[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + + #endif // NAZARA_LITTLE_ENDIAN + + #define ROUND512(a,b,c,d,e,f,g,h) \ + s0 = W512[(j+1)&0x0f]; \ + s0 = sigma0_512(s0); \ + s1 = W512[(j+14)&0x0f]; \ + s1 = sigma1_512(s1); \ + T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ + j++ + + void SHA512_Internal_Transform(SHA_CTX* context, const UInt64* data) { - /* Calculate how much free space is available in the buffer */ - unsigned int freespace = 128 - usedspace; + UInt64 a, b, c, d, e, f, g, h, s0, s1; + UInt64 T1, *W512 = reinterpret_cast(context->s512.buffer); + int j; - if (len >= freespace) + /* Initialize registers with the prev. intermediate value */ + a = context->s512.state[0]; + b = context->s512.state[1]; + c = context->s512.state[2]; + d = context->s512.state[3]; + e = context->s512.state[4]; + f = context->s512.state[5]; + g = context->s512.state[6]; + h = context->s512.state[7]; + + j = 0; + do { - /* Fill the buffer completely and process it */ - std::memcpy(&context->s512.buffer[usedspace], data, freespace); - ADDINC128(context->s512.bitcount, freespace << 3); - len -= freespace; - data += freespace; - SHA512_Internal_Transform(context, reinterpret_cast(context->s512.buffer)); + ROUND512_0_TO_15(a,b,c,d,e,f,g,h); + ROUND512_0_TO_15(h,a,b,c,d,e,f,g); + ROUND512_0_TO_15(g,h,a,b,c,d,e,f); + ROUND512_0_TO_15(f,g,h,a,b,c,d,e); + ROUND512_0_TO_15(e,f,g,h,a,b,c,d); + ROUND512_0_TO_15(d,e,f,g,h,a,b,c); + ROUND512_0_TO_15(c,d,e,f,g,h,a,b); + ROUND512_0_TO_15(b,c,d,e,f,g,h,a); } - else + while (j < 16); + + /* Now for the remaining rounds up to 79: */ + do { - /* The buffer is not yet full */ - std::memcpy(&context->s512.buffer[usedspace], data, len); - ADDINC128(context->s512.bitcount, len << 3); + ROUND512(a,b,c,d,e,f,g,h); + ROUND512(h,a,b,c,d,e,f,g); + ROUND512(g,h,a,b,c,d,e,f); + ROUND512(f,g,h,a,b,c,d,e); + ROUND512(e,f,g,h,a,b,c,d); + ROUND512(d,e,f,g,h,a,b,c); + ROUND512(c,d,e,f,g,h,a,b); + ROUND512(b,c,d,e,f,g,h,a); + } + while (j < 80); + + /* Compute the current intermediate hash value */ + context->s512.state[0] += a; + context->s512.state[1] += b; + context->s512.state[2] += c; + context->s512.state[3] += d; + context->s512.state[4] += e; + context->s512.state[5] += f; + context->s512.state[6] += g; + context->s512.state[7] += h; + } + + void SHA512_Update(SHA_CTX* context, const UInt8 *data, std::size_t len) + { + if (len == 0) + /* Calling with no data is valid - we do nothing */ return; + + unsigned int usedspace = (context->s512.bitcount[0] >> 3) % 128; + if (usedspace > 0) + { + /* Calculate how much free space is available in the buffer */ + unsigned int freespace = 128 - usedspace; + + if (len >= freespace) + { + /* Fill the buffer completely and process it */ + std::memcpy(&context->s512.buffer[usedspace], data, freespace); + ADDINC128(context->s512.bitcount, freespace << 3); + len -= freespace; + data += freespace; + SHA512_Internal_Transform(context, reinterpret_cast(context->s512.buffer)); + } + else + { + /* The buffer is not yet full */ + std::memcpy(&context->s512.buffer[usedspace], data, len); + ADDINC128(context->s512.bitcount, len << 3); + return; + } + } + + while (len >= 128) + { + /* Process as many complete blocks as we can */ + SHA512_Internal_Transform(context, reinterpret_cast(data)); + ADDINC128(context->s512.bitcount, 1024); + len -= 128; + data += 128; + } + + if (len > 0) + { + /* There's left-overs, so save 'em */ + std::memcpy(context->s512.buffer, data, len); + ADDINC128(context->s512.bitcount, len << 3); } } - while (len >= 128) + void SHA512_Internal_Last(SHA_CTX* context) { - /* Process as many complete blocks as we can */ - SHA512_Internal_Transform(context, reinterpret_cast(data)); - ADDINC128(context->s512.bitcount, 1024); - len -= 128; - data += 128; - } + unsigned int usedspace; - if (len > 0) - { - /* There's left-overs, so save 'em */ - std::memcpy(context->s512.buffer, data, len); - ADDINC128(context->s512.bitcount, len << 3); - } -} + usedspace = (context->s512.bitcount[0] >> 3) % 128; + #ifdef NAZARA_LITTLE_ENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->s512.bitcount[0],context->s512.bitcount[0]); + REVERSE64(context->s512.bitcount[1],context->s512.bitcount[1]); + #endif + if (usedspace > 0) + { + /* Begin padding with a 1 bit: */ + context->s512.buffer[usedspace++] = 0x80; -void SHA512_Internal_Last(SHA_CTX* context) -{ - unsigned int usedspace; + if (usedspace <= 112) + /* Set-up for the last transform: */ + std::memset(&context->s512.buffer[usedspace], 0, 112 - usedspace); + else + { + if (usedspace < 128) + std::memset(&context->s512.buffer[usedspace], 0, 128 - usedspace); - usedspace = (context->s512.bitcount[0] >> 3) % 128; -#ifdef NAZARA_LITTLE_ENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->s512.bitcount[0],context->s512.bitcount[0]); - REVERSE64(context->s512.bitcount[1],context->s512.bitcount[1]); -#endif - if (usedspace > 0) - { - /* Begin padding with a 1 bit: */ - context->s512.buffer[usedspace++] = 0x80; + /* Do second-to-last transform: */ + SHA512_Internal_Transform(context, reinterpret_cast(context->s512.buffer)); - if (usedspace <= 112) - /* Set-up for the last transform: */ - std::memset(&context->s512.buffer[usedspace], 0, 112 - usedspace); + /* And set-up for the last transform: */ + std::memset(context->s512.buffer, 0, 112); + } + } else { - if (usedspace < 128) - std::memset(&context->s512.buffer[usedspace], 0, 128 - usedspace); - - /* Do second-to-last transform: */ - SHA512_Internal_Transform(context, reinterpret_cast(context->s512.buffer)); - - /* And set-up for the last transform: */ + /* Prepare for final transform: */ std::memset(context->s512.buffer, 0, 112); + + /* Begin padding with a 1 bit: */ + *context->s512.buffer = 0x80; } - } - else - { - /* Prepare for final transform: */ - std::memset(context->s512.buffer, 0, 112); - /* Begin padding with a 1 bit: */ - *context->s512.buffer = 0x80; + /* Store the length of input data (in bits): */ + UInt64* length = reinterpret_cast(&context->s512.buffer[112]); + length[0] = context->s512.bitcount[1]; + length[1] = context->s512.bitcount[0]; + + /* Final transform: */ + SHA512_Internal_Transform(context, reinterpret_cast(context->s512.buffer)); } - /* Store the length of input data (in bits): */ - nzUInt64* length = reinterpret_cast(&context->s512.buffer[112]); - length[0] = context->s512.bitcount[1]; - length[1] = context->s512.bitcount[0]; - - /* Final transform: */ - SHA512_Internal_Transform(context, reinterpret_cast(context->s512.buffer)); -} - -void SHA512_End(SHA_CTX* context, nzUInt8* digest) -{ - nzUInt64* d = reinterpret_cast(digest); - - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest) + void SHA512_End(SHA_CTX* context, UInt8* digest) { - SHA512_Internal_Last(context); + UInt64* d = reinterpret_cast(digest); - /* Save the hash data for output: */ -#ifdef NAZARA_LITTLE_ENDIAN + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest) { - /* Convert TO host byte order */ - for (int j = 0; j < (SHA512_DIGEST_LENGTH >> 3); j++) + SHA512_Internal_Last(context); + + /* Save the hash data for output: */ + #ifdef NAZARA_LITTLE_ENDIAN { - REVERSE64(context->s512.state[j],context->s512.state[j]); - *d++ = context->s512.state[j]; + /* Convert TO host byte order */ + for (int j = 0; j < (SHA512_DIGEST_LENGTH >> 3); j++) + { + REVERSE64(context->s512.state[j],context->s512.state[j]); + *d++ = context->s512.state[j]; + } } + #else + std::memcpy(d, context->s512.state, SHA512_DIGEST_LENGTH); + #endif } -#else - std::memcpy(d, context->s512.state, SHA512_DIGEST_LENGTH); -#endif } -} -/*** SHA-384: *********************************************************/ -void SHA384_Init(SHA_CTX* context) -{ - SHA512_Internal_Init(context, sha384_initial_hash_value); -} - -void SHA384_Update(SHA_CTX* context, const nzUInt8* data, std::size_t len) -{ - SHA512_Update(context, data, len); -} - -void SHA384_End(SHA_CTX* context, nzUInt8* digest) -{ - nzUInt64* d = reinterpret_cast(digest); - - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest) + /*** SHA-384: *********************************************************/ + void SHA384_Init(SHA_CTX* context) { - SHA512_Internal_Last(context); + SHA512_Internal_Init(context, sha384_initial_hash_value); + } - /* Save the hash data for output: */ -#ifdef NAZARA_LITTLE_ENDIAN + void SHA384_Update(SHA_CTX* context, const UInt8* data, std::size_t len) + { + SHA512_Update(context, data, len); + } + + void SHA384_End(SHA_CTX* context, UInt8* digest) + { + UInt64* d = reinterpret_cast(digest); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest) { - /* Convert TO host byte order */ - for (int j = 0; j < (SHA384_DIGEST_LENGTH >> 3); j++) + SHA512_Internal_Last(context); + + /* Save the hash data for output: */ + #ifdef NAZARA_LITTLE_ENDIAN { - REVERSE64(context->s512.state[j],context->s512.state[j]); - *d++ = context->s512.state[j]; + /* Convert TO host byte order */ + for (int j = 0; j < (SHA384_DIGEST_LENGTH >> 3); j++) + { + REVERSE64(context->s512.state[j],context->s512.state[j]); + *d++ = context->s512.state[j]; + } } + #else + std::memcpy(d, context->s512.state, SHA384_DIGEST_LENGTH); + #endif } -#else - std::memcpy(d, context->s512.state, SHA384_DIGEST_LENGTH); -#endif } } diff --git a/src/Nazara/Core/Hash/SHA/Internal.hpp b/src/Nazara/Core/Hash/SHA/Internal.hpp index 78748bdff..711cec4bb 100644 --- a/src/Nazara/Core/Hash/SHA/Internal.hpp +++ b/src/Nazara/Core/Hash/SHA/Internal.hpp @@ -56,52 +56,55 @@ #define SHA512_DIGEST_LENGTH 64 #define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) -union SHA_CTX +namespace Nz { - /* SHA-1 uses this part of the union: */ - struct - { - nzUInt32 state[5]; - nzUInt64 bitcount; - nzUInt8 buffer[64]; - } s1; + union SHA_CTX + { + /* SHA-1 uses this part of the union: */ + struct + { + UInt32 state[5]; + UInt64 bitcount; + UInt8 buffer[64]; + } s1; - /* SHA-224 and SHA-256 use this part of the union: */ - struct - { - nzUInt32 state[8]; - nzUInt64 bitcount; - nzUInt8 buffer[64]; - } s256; + /* SHA-224 and SHA-256 use this part of the union: */ + struct + { + UInt32 state[8]; + UInt64 bitcount; + UInt8 buffer[64]; + } s256; - /* SHA-384 and SHA-512 use this part of the union: */ - struct - { - nzUInt64 state[8]; - nzUInt64 bitcount[2]; - nzUInt8 buffer[128]; - } s512; -}; + /* SHA-384 and SHA-512 use this part of the union: */ + struct + { + UInt64 state[8]; + UInt64 bitcount[2]; + UInt8 buffer[128]; + } s512; + }; -void SHA1_Init(SHA_CTX*); -void SHA1_Update(SHA_CTX*, const nzUInt8*, std::size_t); -void SHA1_End(SHA_CTX*, nzUInt8*); + void SHA1_Init(SHA_CTX*); + void SHA1_Update(SHA_CTX*, const UInt8*, std::size_t); + void SHA1_End(SHA_CTX*, UInt8*); -void SHA224_Init(SHA_CTX*); -void SHA224_Update(SHA_CTX*, const nzUInt8*, std::size_t); -void SHA224_End(SHA_CTX*, nzUInt8*); + void SHA224_Init(SHA_CTX*); + void SHA224_Update(SHA_CTX*, const UInt8*, std::size_t); + void SHA224_End(SHA_CTX*, UInt8*); -void SHA256_Init(SHA_CTX*); -void SHA256_Update(SHA_CTX*, const nzUInt8*, std::size_t); -void SHA256_End(SHA_CTX*, nzUInt8*); + void SHA256_Init(SHA_CTX*); + void SHA256_Update(SHA_CTX*, const UInt8*, std::size_t); + void SHA256_End(SHA_CTX*, UInt8*); -void SHA384_Init(SHA_CTX*); -void SHA384_Update(SHA_CTX*, const nzUInt8*, std::size_t); -void SHA384_End(SHA_CTX*, nzUInt8*); + void SHA384_Init(SHA_CTX*); + void SHA384_Update(SHA_CTX*, const UInt8*, std::size_t); + void SHA384_End(SHA_CTX*, UInt8*); -void SHA512_Init(SHA_CTX*); -void SHA512_Update(SHA_CTX*, const nzUInt8*, std::size_t); -void SHA512_End(SHA_CTX*, nzUInt8*); + void SHA512_Init(SHA_CTX*); + void SHA512_Update(SHA_CTX*, const UInt8*, std::size_t); + void SHA512_End(SHA_CTX*, UInt8*); +} #endif /* NAZARA_HASH_SHA2_INTERNAL_HPP */ diff --git a/src/Nazara/Core/Hash/SHA1.cpp b/src/Nazara/Core/Hash/SHA1.cpp index b35c3fb4b..8b1725fcb 100644 --- a/src/Nazara/Core/Hash/SHA1.cpp +++ b/src/Nazara/Core/Hash/SHA1.cpp @@ -6,42 +6,45 @@ #include #include -NzHashSHA1::NzHashSHA1() +namespace Nz { - m_state = new SHA_CTX; -} - -NzHashSHA1::~NzHashSHA1() -{ - delete m_state; -} - -void NzHashSHA1::Append(const nzUInt8* data, unsigned int len) -{ - SHA1_Update(m_state, data, len); -} - -void NzHashSHA1::Begin() -{ - SHA1_Init(m_state); -} - -NzHashDigest NzHashSHA1::End() -{ - nzUInt8 digest[SHA1_DIGEST_LENGTH]; - - SHA1_End(m_state, digest); - - return NzHashDigest(GetHashName(), digest, SHA1_DIGEST_LENGTH); -} - -unsigned int NzHashSHA1::GetDigestLength() -{ - return SHA1_DIGEST_LENGTH; -} - -NzString NzHashSHA1::GetHashName() -{ - static NzString hashName = "SHA1"; - return hashName; + HashSHA1::HashSHA1() + { + m_state = new SHA_CTX; + } + + HashSHA1::~HashSHA1() + { + delete m_state; + } + + void HashSHA1::Append(const UInt8* data, unsigned int len) + { + SHA1_Update(m_state, data, len); + } + + void HashSHA1::Begin() + { + SHA1_Init(m_state); + } + + HashDigest HashSHA1::End() + { + UInt8 digest[SHA1_DIGEST_LENGTH]; + + SHA1_End(m_state, digest); + + return HashDigest(GetHashName(), digest, SHA1_DIGEST_LENGTH); + } + + unsigned int HashSHA1::GetDigestLength() + { + return SHA1_DIGEST_LENGTH; + } + + String HashSHA1::GetHashName() + { + static String hashName = "SHA1"; + return hashName; + } } diff --git a/src/Nazara/Core/Hash/SHA224.cpp b/src/Nazara/Core/Hash/SHA224.cpp index fd0a3f12b..ab836e597 100644 --- a/src/Nazara/Core/Hash/SHA224.cpp +++ b/src/Nazara/Core/Hash/SHA224.cpp @@ -6,42 +6,45 @@ #include #include -NzHashSHA224::NzHashSHA224() +namespace Nz { - m_state = new SHA_CTX; -} - -NzHashSHA224::~NzHashSHA224() -{ - delete m_state; -} - -void NzHashSHA224::Append(const nzUInt8* data, unsigned int len) -{ - SHA224_Update(m_state, data, len); -} - -void NzHashSHA224::Begin() -{ - SHA224_Init(m_state); -} - -NzHashDigest NzHashSHA224::End() -{ - nzUInt8 digest[SHA224_DIGEST_LENGTH]; - - SHA224_End(m_state, digest); - - return NzHashDigest(GetHashName(), digest, SHA224_DIGEST_LENGTH); -} - -unsigned int NzHashSHA224::GetDigestLength() -{ - return SHA224_DIGEST_LENGTH; -} - -NzString NzHashSHA224::GetHashName() -{ - static NzString hashName = "SHA224"; - return hashName; + HashSHA224::HashSHA224() + { + m_state = new SHA_CTX; + } + + HashSHA224::~HashSHA224() + { + delete m_state; + } + + void HashSHA224::Append(const UInt8* data, unsigned int len) + { + SHA224_Update(m_state, data, len); + } + + void HashSHA224::Begin() + { + SHA224_Init(m_state); + } + + HashDigest HashSHA224::End() + { + UInt8 digest[SHA224_DIGEST_LENGTH]; + + SHA224_End(m_state, digest); + + return HashDigest(GetHashName(), digest, SHA224_DIGEST_LENGTH); + } + + unsigned int HashSHA224::GetDigestLength() + { + return SHA224_DIGEST_LENGTH; + } + + String HashSHA224::GetHashName() + { + static String hashName = "SHA224"; + return hashName; + } } diff --git a/src/Nazara/Core/Hash/SHA256.cpp b/src/Nazara/Core/Hash/SHA256.cpp index 056f06343..a42764e94 100644 --- a/src/Nazara/Core/Hash/SHA256.cpp +++ b/src/Nazara/Core/Hash/SHA256.cpp @@ -6,42 +6,45 @@ #include #include -NzHashSHA256::NzHashSHA256() +namespace Nz { - m_state = new SHA_CTX; -} - -NzHashSHA256::~NzHashSHA256() -{ - delete m_state; -} - -void NzHashSHA256::Append(const nzUInt8* data, unsigned int len) -{ - SHA256_Update(m_state, data, len); -} - -void NzHashSHA256::Begin() -{ - SHA256_Init(m_state); -} - -NzHashDigest NzHashSHA256::End() -{ - nzUInt8 digest[SHA256_DIGEST_LENGTH]; - - SHA256_End(m_state, digest); - - return NzHashDigest(GetHashName(), digest, SHA256_DIGEST_LENGTH); -} - -unsigned int NzHashSHA256::GetDigestLength() -{ - return SHA256_DIGEST_LENGTH; -} - -NzString NzHashSHA256::GetHashName() -{ - static NzString hashName = "SHA256"; - return hashName; + HashSHA256::HashSHA256() + { + m_state = new SHA_CTX; + } + + HashSHA256::~HashSHA256() + { + delete m_state; + } + + void HashSHA256::Append(const UInt8* data, unsigned int len) + { + SHA256_Update(m_state, data, len); + } + + void HashSHA256::Begin() + { + SHA256_Init(m_state); + } + + HashDigest HashSHA256::End() + { + UInt8 digest[SHA256_DIGEST_LENGTH]; + + SHA256_End(m_state, digest); + + return HashDigest(GetHashName(), digest, SHA256_DIGEST_LENGTH); + } + + unsigned int HashSHA256::GetDigestLength() + { + return SHA256_DIGEST_LENGTH; + } + + String HashSHA256::GetHashName() + { + static String hashName = "SHA256"; + return hashName; + } } diff --git a/src/Nazara/Core/Hash/SHA384.cpp b/src/Nazara/Core/Hash/SHA384.cpp index 816b26dd9..a4aa25961 100644 --- a/src/Nazara/Core/Hash/SHA384.cpp +++ b/src/Nazara/Core/Hash/SHA384.cpp @@ -6,42 +6,45 @@ #include #include -NzHashSHA384::NzHashSHA384() +namespace Nz { - m_state = new SHA_CTX; -} - -NzHashSHA384::~NzHashSHA384() -{ - delete m_state; -} - -void NzHashSHA384::Append(const nzUInt8* data, unsigned int len) -{ - SHA384_Update(m_state, data, len); -} - -void NzHashSHA384::Begin() -{ - SHA384_Init(m_state); -} - -NzHashDigest NzHashSHA384::End() -{ - nzUInt8 digest[SHA384_DIGEST_LENGTH]; - - SHA384_End(m_state, digest); - - return NzHashDigest(GetHashName(), digest, SHA384_DIGEST_LENGTH); -} - -unsigned int NzHashSHA384::GetDigestLength() -{ - return SHA384_DIGEST_LENGTH; -} - -NzString NzHashSHA384::GetHashName() -{ - static NzString hashName = "SHA384"; - return hashName; + HashSHA384::HashSHA384() + { + m_state = new SHA_CTX; + } + + HashSHA384::~HashSHA384() + { + delete m_state; + } + + void HashSHA384::Append(const UInt8* data, unsigned int len) + { + SHA384_Update(m_state, data, len); + } + + void HashSHA384::Begin() + { + SHA384_Init(m_state); + } + + HashDigest HashSHA384::End() + { + UInt8 digest[SHA384_DIGEST_LENGTH]; + + SHA384_End(m_state, digest); + + return HashDigest(GetHashName(), digest, SHA384_DIGEST_LENGTH); + } + + unsigned int HashSHA384::GetDigestLength() + { + return SHA384_DIGEST_LENGTH; + } + + String HashSHA384::GetHashName() + { + static String hashName = "SHA384"; + return hashName; + } } diff --git a/src/Nazara/Core/Hash/SHA512.cpp b/src/Nazara/Core/Hash/SHA512.cpp index 513797448..f246ab0e8 100644 --- a/src/Nazara/Core/Hash/SHA512.cpp +++ b/src/Nazara/Core/Hash/SHA512.cpp @@ -6,42 +6,45 @@ #include #include -NzHashSHA512::NzHashSHA512() +namespace Nz { - m_state = new SHA_CTX; -} - -NzHashSHA512::~NzHashSHA512() -{ - delete m_state; -} - -void NzHashSHA512::Append(const nzUInt8* data, unsigned int len) -{ - SHA512_Update(m_state, data, len); -} - -void NzHashSHA512::Begin() -{ - SHA512_Init(m_state); -} - -NzHashDigest NzHashSHA512::End() -{ - nzUInt8 digest[SHA512_DIGEST_LENGTH]; - - SHA512_End(m_state, digest); - - return NzHashDigest(GetHashName(), digest, SHA512_DIGEST_LENGTH); -} - -unsigned int NzHashSHA512::GetDigestLength() -{ - return SHA512_DIGEST_LENGTH; -} - -NzString NzHashSHA512::GetHashName() -{ - static NzString hashName = "SHA512"; - return hashName; + HashSHA512::HashSHA512() + { + m_state = new SHA_CTX; + } + + HashSHA512::~HashSHA512() + { + delete m_state; + } + + void HashSHA512::Append(const UInt8* data, unsigned int len) + { + SHA512_Update(m_state, data, len); + } + + void HashSHA512::Begin() + { + SHA512_Init(m_state); + } + + HashDigest HashSHA512::End() + { + UInt8 digest[SHA512_DIGEST_LENGTH]; + + SHA512_End(m_state, digest); + + return HashDigest(GetHashName(), digest, SHA512_DIGEST_LENGTH); + } + + unsigned int HashSHA512::GetDigestLength() + { + return SHA512_DIGEST_LENGTH; + } + + String HashSHA512::GetHashName() + { + static String hashName = "SHA512"; + return hashName; + } } diff --git a/src/Nazara/Core/Hash/Whirlpool.cpp b/src/Nazara/Core/Hash/Whirlpool.cpp index 886943f41..b734fdec9 100644 --- a/src/Nazara/Core/Hash/Whirlpool.cpp +++ b/src/Nazara/Core/Hash/Whirlpool.cpp @@ -71,955 +71,958 @@ #define R 10 -struct NzHashWhirlpool_state +namespace Nz { - int bufferBits; // current number of bits on the buffer */ - int bufferPos; // current (possibly incomplete) byte slot on the buffer */ - nzUInt8 bitLength[32]; // global number of hashed bits (256-bit counter) */ - nzUInt8 buffer[64]; // buffer of data to hash */ - nzUInt64 hash[8]; // the hashing state */ -}; - -namespace -{ - const nzUInt64 C0[256] = { - 0x18186018c07830d8ULL, 0x23238c2305af4626ULL, 0xc6c63fc67ef991b8ULL, 0xe8e887e8136fcdfbULL, - 0x878726874ca113cbULL, 0xb8b8dab8a9626d11ULL, 0x0101040108050209ULL, 0x4f4f214f426e9e0dULL, - 0x3636d836adee6c9bULL, 0xa6a6a2a6590451ffULL, 0xd2d26fd2debdb90cULL, 0xf5f5f3f5fb06f70eULL, - 0x7979f979ef80f296ULL, 0x6f6fa16f5fcede30ULL, 0x91917e91fcef3f6dULL, 0x52525552aa07a4f8ULL, - 0x60609d6027fdc047ULL, 0xbcbccabc89766535ULL, 0x9b9b569baccd2b37ULL, 0x8e8e028e048c018aULL, - 0xa3a3b6a371155bd2ULL, 0x0c0c300c603c186cULL, 0x7b7bf17bff8af684ULL, 0x3535d435b5e16a80ULL, - 0x1d1d741de8693af5ULL, 0xe0e0a7e05347ddb3ULL, 0xd7d77bd7f6acb321ULL, 0xc2c22fc25eed999cULL, - 0x2e2eb82e6d965c43ULL, 0x4b4b314b627a9629ULL, 0xfefedffea321e15dULL, 0x575741578216aed5ULL, - 0x15155415a8412abdULL, 0x7777c1779fb6eee8ULL, 0x3737dc37a5eb6e92ULL, 0xe5e5b3e57b56d79eULL, - 0x9f9f469f8cd92313ULL, 0xf0f0e7f0d317fd23ULL, 0x4a4a354a6a7f9420ULL, 0xdada4fda9e95a944ULL, - 0x58587d58fa25b0a2ULL, 0xc9c903c906ca8fcfULL, 0x2929a429558d527cULL, 0x0a0a280a5022145aULL, - 0xb1b1feb1e14f7f50ULL, 0xa0a0baa0691a5dc9ULL, 0x6b6bb16b7fdad614ULL, 0x85852e855cab17d9ULL, - 0xbdbdcebd8173673cULL, 0x5d5d695dd234ba8fULL, 0x1010401080502090ULL, 0xf4f4f7f4f303f507ULL, - 0xcbcb0bcb16c08bddULL, 0x3e3ef83eedc67cd3ULL, 0x0505140528110a2dULL, 0x676781671fe6ce78ULL, - 0xe4e4b7e47353d597ULL, 0x27279c2725bb4e02ULL, 0x4141194132588273ULL, 0x8b8b168b2c9d0ba7ULL, - 0xa7a7a6a7510153f6ULL, 0x7d7de97dcf94fab2ULL, 0x95956e95dcfb3749ULL, 0xd8d847d88e9fad56ULL, - 0xfbfbcbfb8b30eb70ULL, 0xeeee9fee2371c1cdULL, 0x7c7ced7cc791f8bbULL, 0x6666856617e3cc71ULL, - 0xdddd53dda68ea77bULL, 0x17175c17b84b2eafULL, 0x4747014702468e45ULL, 0x9e9e429e84dc211aULL, - 0xcaca0fca1ec589d4ULL, 0x2d2db42d75995a58ULL, 0xbfbfc6bf9179632eULL, 0x07071c07381b0e3fULL, - 0xadad8ead012347acULL, 0x5a5a755aea2fb4b0ULL, 0x838336836cb51befULL, 0x3333cc3385ff66b6ULL, - 0x636391633ff2c65cULL, 0x02020802100a0412ULL, 0xaaaa92aa39384993ULL, 0x7171d971afa8e2deULL, - 0xc8c807c80ecf8dc6ULL, 0x19196419c87d32d1ULL, 0x494939497270923bULL, 0xd9d943d9869aaf5fULL, - 0xf2f2eff2c31df931ULL, 0xe3e3abe34b48dba8ULL, 0x5b5b715be22ab6b9ULL, 0x88881a8834920dbcULL, - 0x9a9a529aa4c8293eULL, 0x262698262dbe4c0bULL, 0x3232c8328dfa64bfULL, 0xb0b0fab0e94a7d59ULL, - 0xe9e983e91b6acff2ULL, 0x0f0f3c0f78331e77ULL, 0xd5d573d5e6a6b733ULL, 0x80803a8074ba1df4ULL, - 0xbebec2be997c6127ULL, 0xcdcd13cd26de87ebULL, 0x3434d034bde46889ULL, 0x48483d487a759032ULL, - 0xffffdbffab24e354ULL, 0x7a7af57af78ff48dULL, 0x90907a90f4ea3d64ULL, 0x5f5f615fc23ebe9dULL, - 0x202080201da0403dULL, 0x6868bd6867d5d00fULL, 0x1a1a681ad07234caULL, 0xaeae82ae192c41b7ULL, - 0xb4b4eab4c95e757dULL, 0x54544d549a19a8ceULL, 0x93937693ece53b7fULL, 0x222288220daa442fULL, - 0x64648d6407e9c863ULL, 0xf1f1e3f1db12ff2aULL, 0x7373d173bfa2e6ccULL, 0x12124812905a2482ULL, - 0x40401d403a5d807aULL, 0x0808200840281048ULL, 0xc3c32bc356e89b95ULL, 0xecec97ec337bc5dfULL, - 0xdbdb4bdb9690ab4dULL, 0xa1a1bea1611f5fc0ULL, 0x8d8d0e8d1c830791ULL, 0x3d3df43df5c97ac8ULL, - 0x97976697ccf1335bULL, 0x0000000000000000ULL, 0xcfcf1bcf36d483f9ULL, 0x2b2bac2b4587566eULL, - 0x7676c57697b3ece1ULL, 0x8282328264b019e6ULL, 0xd6d67fd6fea9b128ULL, 0x1b1b6c1bd87736c3ULL, - 0xb5b5eeb5c15b7774ULL, 0xafaf86af112943beULL, 0x6a6ab56a77dfd41dULL, 0x50505d50ba0da0eaULL, - 0x45450945124c8a57ULL, 0xf3f3ebf3cb18fb38ULL, 0x3030c0309df060adULL, 0xefef9bef2b74c3c4ULL, - 0x3f3ffc3fe5c37edaULL, 0x55554955921caac7ULL, 0xa2a2b2a2791059dbULL, 0xeaea8fea0365c9e9ULL, - 0x656589650fecca6aULL, 0xbabad2bab9686903ULL, 0x2f2fbc2f65935e4aULL, 0xc0c027c04ee79d8eULL, - 0xdede5fdebe81a160ULL, 0x1c1c701ce06c38fcULL, 0xfdfdd3fdbb2ee746ULL, 0x4d4d294d52649a1fULL, - 0x92927292e4e03976ULL, 0x7575c9758fbceafaULL, 0x06061806301e0c36ULL, 0x8a8a128a249809aeULL, - 0xb2b2f2b2f940794bULL, 0xe6e6bfe66359d185ULL, 0x0e0e380e70361c7eULL, 0x1f1f7c1ff8633ee7ULL, - 0x6262956237f7c455ULL, 0xd4d477d4eea3b53aULL, 0xa8a89aa829324d81ULL, 0x96966296c4f43152ULL, - 0xf9f9c3f99b3aef62ULL, 0xc5c533c566f697a3ULL, 0x2525942535b14a10ULL, 0x59597959f220b2abULL, - 0x84842a8454ae15d0ULL, 0x7272d572b7a7e4c5ULL, 0x3939e439d5dd72ecULL, 0x4c4c2d4c5a619816ULL, - 0x5e5e655eca3bbc94ULL, 0x7878fd78e785f09fULL, 0x3838e038ddd870e5ULL, 0x8c8c0a8c14860598ULL, - 0xd1d163d1c6b2bf17ULL, 0xa5a5aea5410b57e4ULL, 0xe2e2afe2434dd9a1ULL, 0x616199612ff8c24eULL, - 0xb3b3f6b3f1457b42ULL, 0x2121842115a54234ULL, 0x9c9c4a9c94d62508ULL, 0x1e1e781ef0663ceeULL, - 0x4343114322528661ULL, 0xc7c73bc776fc93b1ULL, 0xfcfcd7fcb32be54fULL, 0x0404100420140824ULL, - 0x51515951b208a2e3ULL, 0x99995e99bcc72f25ULL, 0x6d6da96d4fc4da22ULL, 0x0d0d340d68391a65ULL, - 0xfafacffa8335e979ULL, 0xdfdf5bdfb684a369ULL, 0x7e7ee57ed79bfca9ULL, 0x242490243db44819ULL, - 0x3b3bec3bc5d776feULL, 0xabab96ab313d4b9aULL, 0xcece1fce3ed181f0ULL, 0x1111441188552299ULL, - 0x8f8f068f0c890383ULL, 0x4e4e254e4a6b9c04ULL, 0xb7b7e6b7d1517366ULL, 0xebeb8beb0b60cbe0ULL, - 0x3c3cf03cfdcc78c1ULL, 0x81813e817cbf1ffdULL, 0x94946a94d4fe3540ULL, 0xf7f7fbf7eb0cf31cULL, - 0xb9b9deb9a1676f18ULL, 0x13134c13985f268bULL, 0x2c2cb02c7d9c5851ULL, 0xd3d36bd3d6b8bb05ULL, - 0xe7e7bbe76b5cd38cULL, 0x6e6ea56e57cbdc39ULL, 0xc4c437c46ef395aaULL, 0x03030c03180f061bULL, - 0x565645568a13acdcULL, 0x44440d441a49885eULL, 0x7f7fe17fdf9efea0ULL, 0xa9a99ea921374f88ULL, - 0x2a2aa82a4d825467ULL, 0xbbbbd6bbb16d6b0aULL, 0xc1c123c146e29f87ULL, 0x53535153a202a6f1ULL, - 0xdcdc57dcae8ba572ULL, 0x0b0b2c0b58271653ULL, 0x9d9d4e9d9cd32701ULL, 0x6c6cad6c47c1d82bULL, - 0x3131c43195f562a4ULL, 0x7474cd7487b9e8f3ULL, 0xf6f6fff6e309f115ULL, 0x464605460a438c4cULL, - 0xacac8aac092645a5ULL, 0x89891e893c970fb5ULL, 0x14145014a04428b4ULL, 0xe1e1a3e15b42dfbaULL, - 0x16165816b04e2ca6ULL, 0x3a3ae83acdd274f7ULL, 0x6969b9696fd0d206ULL, 0x09092409482d1241ULL, - 0x7070dd70a7ade0d7ULL, 0xb6b6e2b6d954716fULL, 0xd0d067d0ceb7bd1eULL, 0xeded93ed3b7ec7d6ULL, - 0xcccc17cc2edb85e2ULL, 0x424215422a578468ULL, 0x98985a98b4c22d2cULL, 0xa4a4aaa4490e55edULL, - 0x2828a0285d885075ULL, 0x5c5c6d5cda31b886ULL, 0xf8f8c7f8933fed6bULL, 0x8686228644a411c2ULL, - }; - - const nzUInt64 C1[256] = { - 0xd818186018c07830ULL, 0x2623238c2305af46ULL, 0xb8c6c63fc67ef991ULL, 0xfbe8e887e8136fcdULL, - 0xcb878726874ca113ULL, 0x11b8b8dab8a9626dULL, 0x0901010401080502ULL, 0x0d4f4f214f426e9eULL, - 0x9b3636d836adee6cULL, 0xffa6a6a2a6590451ULL, 0x0cd2d26fd2debdb9ULL, 0x0ef5f5f3f5fb06f7ULL, - 0x967979f979ef80f2ULL, 0x306f6fa16f5fcedeULL, 0x6d91917e91fcef3fULL, 0xf852525552aa07a4ULL, - 0x4760609d6027fdc0ULL, 0x35bcbccabc897665ULL, 0x379b9b569baccd2bULL, 0x8a8e8e028e048c01ULL, - 0xd2a3a3b6a371155bULL, 0x6c0c0c300c603c18ULL, 0x847b7bf17bff8af6ULL, 0x803535d435b5e16aULL, - 0xf51d1d741de8693aULL, 0xb3e0e0a7e05347ddULL, 0x21d7d77bd7f6acb3ULL, 0x9cc2c22fc25eed99ULL, - 0x432e2eb82e6d965cULL, 0x294b4b314b627a96ULL, 0x5dfefedffea321e1ULL, 0xd5575741578216aeULL, - 0xbd15155415a8412aULL, 0xe87777c1779fb6eeULL, 0x923737dc37a5eb6eULL, 0x9ee5e5b3e57b56d7ULL, - 0x139f9f469f8cd923ULL, 0x23f0f0e7f0d317fdULL, 0x204a4a354a6a7f94ULL, 0x44dada4fda9e95a9ULL, - 0xa258587d58fa25b0ULL, 0xcfc9c903c906ca8fULL, 0x7c2929a429558d52ULL, 0x5a0a0a280a502214ULL, - 0x50b1b1feb1e14f7fULL, 0xc9a0a0baa0691a5dULL, 0x146b6bb16b7fdad6ULL, 0xd985852e855cab17ULL, - 0x3cbdbdcebd817367ULL, 0x8f5d5d695dd234baULL, 0x9010104010805020ULL, 0x07f4f4f7f4f303f5ULL, - 0xddcbcb0bcb16c08bULL, 0xd33e3ef83eedc67cULL, 0x2d0505140528110aULL, 0x78676781671fe6ceULL, - 0x97e4e4b7e47353d5ULL, 0x0227279c2725bb4eULL, 0x7341411941325882ULL, 0xa78b8b168b2c9d0bULL, - 0xf6a7a7a6a7510153ULL, 0xb27d7de97dcf94faULL, 0x4995956e95dcfb37ULL, 0x56d8d847d88e9fadULL, - 0x70fbfbcbfb8b30ebULL, 0xcdeeee9fee2371c1ULL, 0xbb7c7ced7cc791f8ULL, 0x716666856617e3ccULL, - 0x7bdddd53dda68ea7ULL, 0xaf17175c17b84b2eULL, 0x454747014702468eULL, 0x1a9e9e429e84dc21ULL, - 0xd4caca0fca1ec589ULL, 0x582d2db42d75995aULL, 0x2ebfbfc6bf917963ULL, 0x3f07071c07381b0eULL, - 0xacadad8ead012347ULL, 0xb05a5a755aea2fb4ULL, 0xef838336836cb51bULL, 0xb63333cc3385ff66ULL, - 0x5c636391633ff2c6ULL, 0x1202020802100a04ULL, 0x93aaaa92aa393849ULL, 0xde7171d971afa8e2ULL, - 0xc6c8c807c80ecf8dULL, 0xd119196419c87d32ULL, 0x3b49493949727092ULL, 0x5fd9d943d9869aafULL, - 0x31f2f2eff2c31df9ULL, 0xa8e3e3abe34b48dbULL, 0xb95b5b715be22ab6ULL, 0xbc88881a8834920dULL, - 0x3e9a9a529aa4c829ULL, 0x0b262698262dbe4cULL, 0xbf3232c8328dfa64ULL, 0x59b0b0fab0e94a7dULL, - 0xf2e9e983e91b6acfULL, 0x770f0f3c0f78331eULL, 0x33d5d573d5e6a6b7ULL, 0xf480803a8074ba1dULL, - 0x27bebec2be997c61ULL, 0xebcdcd13cd26de87ULL, 0x893434d034bde468ULL, 0x3248483d487a7590ULL, - 0x54ffffdbffab24e3ULL, 0x8d7a7af57af78ff4ULL, 0x6490907a90f4ea3dULL, 0x9d5f5f615fc23ebeULL, - 0x3d202080201da040ULL, 0x0f6868bd6867d5d0ULL, 0xca1a1a681ad07234ULL, 0xb7aeae82ae192c41ULL, - 0x7db4b4eab4c95e75ULL, 0xce54544d549a19a8ULL, 0x7f93937693ece53bULL, 0x2f222288220daa44ULL, - 0x6364648d6407e9c8ULL, 0x2af1f1e3f1db12ffULL, 0xcc7373d173bfa2e6ULL, 0x8212124812905a24ULL, - 0x7a40401d403a5d80ULL, 0x4808082008402810ULL, 0x95c3c32bc356e89bULL, 0xdfecec97ec337bc5ULL, - 0x4ddbdb4bdb9690abULL, 0xc0a1a1bea1611f5fULL, 0x918d8d0e8d1c8307ULL, 0xc83d3df43df5c97aULL, - 0x5b97976697ccf133ULL, 0x0000000000000000ULL, 0xf9cfcf1bcf36d483ULL, 0x6e2b2bac2b458756ULL, - 0xe17676c57697b3ecULL, 0xe68282328264b019ULL, 0x28d6d67fd6fea9b1ULL, 0xc31b1b6c1bd87736ULL, - 0x74b5b5eeb5c15b77ULL, 0xbeafaf86af112943ULL, 0x1d6a6ab56a77dfd4ULL, 0xea50505d50ba0da0ULL, - 0x5745450945124c8aULL, 0x38f3f3ebf3cb18fbULL, 0xad3030c0309df060ULL, 0xc4efef9bef2b74c3ULL, - 0xda3f3ffc3fe5c37eULL, 0xc755554955921caaULL, 0xdba2a2b2a2791059ULL, 0xe9eaea8fea0365c9ULL, - 0x6a656589650feccaULL, 0x03babad2bab96869ULL, 0x4a2f2fbc2f65935eULL, 0x8ec0c027c04ee79dULL, - 0x60dede5fdebe81a1ULL, 0xfc1c1c701ce06c38ULL, 0x46fdfdd3fdbb2ee7ULL, 0x1f4d4d294d52649aULL, - 0x7692927292e4e039ULL, 0xfa7575c9758fbceaULL, 0x3606061806301e0cULL, 0xae8a8a128a249809ULL, - 0x4bb2b2f2b2f94079ULL, 0x85e6e6bfe66359d1ULL, 0x7e0e0e380e70361cULL, 0xe71f1f7c1ff8633eULL, - 0x556262956237f7c4ULL, 0x3ad4d477d4eea3b5ULL, 0x81a8a89aa829324dULL, 0x5296966296c4f431ULL, - 0x62f9f9c3f99b3aefULL, 0xa3c5c533c566f697ULL, 0x102525942535b14aULL, 0xab59597959f220b2ULL, - 0xd084842a8454ae15ULL, 0xc57272d572b7a7e4ULL, 0xec3939e439d5dd72ULL, 0x164c4c2d4c5a6198ULL, - 0x945e5e655eca3bbcULL, 0x9f7878fd78e785f0ULL, 0xe53838e038ddd870ULL, 0x988c8c0a8c148605ULL, - 0x17d1d163d1c6b2bfULL, 0xe4a5a5aea5410b57ULL, 0xa1e2e2afe2434dd9ULL, 0x4e616199612ff8c2ULL, - 0x42b3b3f6b3f1457bULL, 0x342121842115a542ULL, 0x089c9c4a9c94d625ULL, 0xee1e1e781ef0663cULL, - 0x6143431143225286ULL, 0xb1c7c73bc776fc93ULL, 0x4ffcfcd7fcb32be5ULL, 0x2404041004201408ULL, - 0xe351515951b208a2ULL, 0x2599995e99bcc72fULL, 0x226d6da96d4fc4daULL, 0x650d0d340d68391aULL, - 0x79fafacffa8335e9ULL, 0x69dfdf5bdfb684a3ULL, 0xa97e7ee57ed79bfcULL, 0x19242490243db448ULL, - 0xfe3b3bec3bc5d776ULL, 0x9aabab96ab313d4bULL, 0xf0cece1fce3ed181ULL, 0x9911114411885522ULL, - 0x838f8f068f0c8903ULL, 0x044e4e254e4a6b9cULL, 0x66b7b7e6b7d15173ULL, 0xe0ebeb8beb0b60cbULL, - 0xc13c3cf03cfdcc78ULL, 0xfd81813e817cbf1fULL, 0x4094946a94d4fe35ULL, 0x1cf7f7fbf7eb0cf3ULL, - 0x18b9b9deb9a1676fULL, 0x8b13134c13985f26ULL, 0x512c2cb02c7d9c58ULL, 0x05d3d36bd3d6b8bbULL, - 0x8ce7e7bbe76b5cd3ULL, 0x396e6ea56e57cbdcULL, 0xaac4c437c46ef395ULL, 0x1b03030c03180f06ULL, - 0xdc565645568a13acULL, 0x5e44440d441a4988ULL, 0xa07f7fe17fdf9efeULL, 0x88a9a99ea921374fULL, - 0x672a2aa82a4d8254ULL, 0x0abbbbd6bbb16d6bULL, 0x87c1c123c146e29fULL, 0xf153535153a202a6ULL, - 0x72dcdc57dcae8ba5ULL, 0x530b0b2c0b582716ULL, 0x019d9d4e9d9cd327ULL, 0x2b6c6cad6c47c1d8ULL, - 0xa43131c43195f562ULL, 0xf37474cd7487b9e8ULL, 0x15f6f6fff6e309f1ULL, 0x4c464605460a438cULL, - 0xa5acac8aac092645ULL, 0xb589891e893c970fULL, 0xb414145014a04428ULL, 0xbae1e1a3e15b42dfULL, - 0xa616165816b04e2cULL, 0xf73a3ae83acdd274ULL, 0x066969b9696fd0d2ULL, 0x4109092409482d12ULL, - 0xd77070dd70a7ade0ULL, 0x6fb6b6e2b6d95471ULL, 0x1ed0d067d0ceb7bdULL, 0xd6eded93ed3b7ec7ULL, - 0xe2cccc17cc2edb85ULL, 0x68424215422a5784ULL, 0x2c98985a98b4c22dULL, 0xeda4a4aaa4490e55ULL, - 0x752828a0285d8850ULL, 0x865c5c6d5cda31b8ULL, 0x6bf8f8c7f8933fedULL, 0xc28686228644a411ULL, - }; - - const nzUInt64 C2[256] = { - 0x30d818186018c078ULL, 0x462623238c2305afULL, 0x91b8c6c63fc67ef9ULL, 0xcdfbe8e887e8136fULL, - 0x13cb878726874ca1ULL, 0x6d11b8b8dab8a962ULL, 0x0209010104010805ULL, 0x9e0d4f4f214f426eULL, - 0x6c9b3636d836adeeULL, 0x51ffa6a6a2a65904ULL, 0xb90cd2d26fd2debdULL, 0xf70ef5f5f3f5fb06ULL, - 0xf2967979f979ef80ULL, 0xde306f6fa16f5fceULL, 0x3f6d91917e91fcefULL, 0xa4f852525552aa07ULL, - 0xc04760609d6027fdULL, 0x6535bcbccabc8976ULL, 0x2b379b9b569baccdULL, 0x018a8e8e028e048cULL, - 0x5bd2a3a3b6a37115ULL, 0x186c0c0c300c603cULL, 0xf6847b7bf17bff8aULL, 0x6a803535d435b5e1ULL, - 0x3af51d1d741de869ULL, 0xddb3e0e0a7e05347ULL, 0xb321d7d77bd7f6acULL, 0x999cc2c22fc25eedULL, - 0x5c432e2eb82e6d96ULL, 0x96294b4b314b627aULL, 0xe15dfefedffea321ULL, 0xaed5575741578216ULL, - 0x2abd15155415a841ULL, 0xeee87777c1779fb6ULL, 0x6e923737dc37a5ebULL, 0xd79ee5e5b3e57b56ULL, - 0x23139f9f469f8cd9ULL, 0xfd23f0f0e7f0d317ULL, 0x94204a4a354a6a7fULL, 0xa944dada4fda9e95ULL, - 0xb0a258587d58fa25ULL, 0x8fcfc9c903c906caULL, 0x527c2929a429558dULL, 0x145a0a0a280a5022ULL, - 0x7f50b1b1feb1e14fULL, 0x5dc9a0a0baa0691aULL, 0xd6146b6bb16b7fdaULL, 0x17d985852e855cabULL, - 0x673cbdbdcebd8173ULL, 0xba8f5d5d695dd234ULL, 0x2090101040108050ULL, 0xf507f4f4f7f4f303ULL, - 0x8bddcbcb0bcb16c0ULL, 0x7cd33e3ef83eedc6ULL, 0x0a2d050514052811ULL, 0xce78676781671fe6ULL, - 0xd597e4e4b7e47353ULL, 0x4e0227279c2725bbULL, 0x8273414119413258ULL, 0x0ba78b8b168b2c9dULL, - 0x53f6a7a7a6a75101ULL, 0xfab27d7de97dcf94ULL, 0x374995956e95dcfbULL, 0xad56d8d847d88e9fULL, - 0xeb70fbfbcbfb8b30ULL, 0xc1cdeeee9fee2371ULL, 0xf8bb7c7ced7cc791ULL, 0xcc716666856617e3ULL, - 0xa77bdddd53dda68eULL, 0x2eaf17175c17b84bULL, 0x8e45474701470246ULL, 0x211a9e9e429e84dcULL, - 0x89d4caca0fca1ec5ULL, 0x5a582d2db42d7599ULL, 0x632ebfbfc6bf9179ULL, 0x0e3f07071c07381bULL, - 0x47acadad8ead0123ULL, 0xb4b05a5a755aea2fULL, 0x1bef838336836cb5ULL, 0x66b63333cc3385ffULL, - 0xc65c636391633ff2ULL, 0x041202020802100aULL, 0x4993aaaa92aa3938ULL, 0xe2de7171d971afa8ULL, - 0x8dc6c8c807c80ecfULL, 0x32d119196419c87dULL, 0x923b494939497270ULL, 0xaf5fd9d943d9869aULL, - 0xf931f2f2eff2c31dULL, 0xdba8e3e3abe34b48ULL, 0xb6b95b5b715be22aULL, 0x0dbc88881a883492ULL, - 0x293e9a9a529aa4c8ULL, 0x4c0b262698262dbeULL, 0x64bf3232c8328dfaULL, 0x7d59b0b0fab0e94aULL, - 0xcff2e9e983e91b6aULL, 0x1e770f0f3c0f7833ULL, 0xb733d5d573d5e6a6ULL, 0x1df480803a8074baULL, - 0x6127bebec2be997cULL, 0x87ebcdcd13cd26deULL, 0x68893434d034bde4ULL, 0x903248483d487a75ULL, - 0xe354ffffdbffab24ULL, 0xf48d7a7af57af78fULL, 0x3d6490907a90f4eaULL, 0xbe9d5f5f615fc23eULL, - 0x403d202080201da0ULL, 0xd00f6868bd6867d5ULL, 0x34ca1a1a681ad072ULL, 0x41b7aeae82ae192cULL, - 0x757db4b4eab4c95eULL, 0xa8ce54544d549a19ULL, 0x3b7f93937693ece5ULL, 0x442f222288220daaULL, - 0xc86364648d6407e9ULL, 0xff2af1f1e3f1db12ULL, 0xe6cc7373d173bfa2ULL, 0x248212124812905aULL, - 0x807a40401d403a5dULL, 0x1048080820084028ULL, 0x9b95c3c32bc356e8ULL, 0xc5dfecec97ec337bULL, - 0xab4ddbdb4bdb9690ULL, 0x5fc0a1a1bea1611fULL, 0x07918d8d0e8d1c83ULL, 0x7ac83d3df43df5c9ULL, - 0x335b97976697ccf1ULL, 0x0000000000000000ULL, 0x83f9cfcf1bcf36d4ULL, 0x566e2b2bac2b4587ULL, - 0xece17676c57697b3ULL, 0x19e68282328264b0ULL, 0xb128d6d67fd6fea9ULL, 0x36c31b1b6c1bd877ULL, - 0x7774b5b5eeb5c15bULL, 0x43beafaf86af1129ULL, 0xd41d6a6ab56a77dfULL, 0xa0ea50505d50ba0dULL, - 0x8a5745450945124cULL, 0xfb38f3f3ebf3cb18ULL, 0x60ad3030c0309df0ULL, 0xc3c4efef9bef2b74ULL, - 0x7eda3f3ffc3fe5c3ULL, 0xaac755554955921cULL, 0x59dba2a2b2a27910ULL, 0xc9e9eaea8fea0365ULL, - 0xca6a656589650fecULL, 0x6903babad2bab968ULL, 0x5e4a2f2fbc2f6593ULL, 0x9d8ec0c027c04ee7ULL, - 0xa160dede5fdebe81ULL, 0x38fc1c1c701ce06cULL, 0xe746fdfdd3fdbb2eULL, 0x9a1f4d4d294d5264ULL, - 0x397692927292e4e0ULL, 0xeafa7575c9758fbcULL, 0x0c3606061806301eULL, 0x09ae8a8a128a2498ULL, - 0x794bb2b2f2b2f940ULL, 0xd185e6e6bfe66359ULL, 0x1c7e0e0e380e7036ULL, 0x3ee71f1f7c1ff863ULL, - 0xc4556262956237f7ULL, 0xb53ad4d477d4eea3ULL, 0x4d81a8a89aa82932ULL, 0x315296966296c4f4ULL, - 0xef62f9f9c3f99b3aULL, 0x97a3c5c533c566f6ULL, 0x4a102525942535b1ULL, 0xb2ab59597959f220ULL, - 0x15d084842a8454aeULL, 0xe4c57272d572b7a7ULL, 0x72ec3939e439d5ddULL, 0x98164c4c2d4c5a61ULL, - 0xbc945e5e655eca3bULL, 0xf09f7878fd78e785ULL, 0x70e53838e038ddd8ULL, 0x05988c8c0a8c1486ULL, - 0xbf17d1d163d1c6b2ULL, 0x57e4a5a5aea5410bULL, 0xd9a1e2e2afe2434dULL, 0xc24e616199612ff8ULL, - 0x7b42b3b3f6b3f145ULL, 0x42342121842115a5ULL, 0x25089c9c4a9c94d6ULL, 0x3cee1e1e781ef066ULL, - 0x8661434311432252ULL, 0x93b1c7c73bc776fcULL, 0xe54ffcfcd7fcb32bULL, 0x0824040410042014ULL, - 0xa2e351515951b208ULL, 0x2f2599995e99bcc7ULL, 0xda226d6da96d4fc4ULL, 0x1a650d0d340d6839ULL, - 0xe979fafacffa8335ULL, 0xa369dfdf5bdfb684ULL, 0xfca97e7ee57ed79bULL, 0x4819242490243db4ULL, - 0x76fe3b3bec3bc5d7ULL, 0x4b9aabab96ab313dULL, 0x81f0cece1fce3ed1ULL, 0x2299111144118855ULL, - 0x03838f8f068f0c89ULL, 0x9c044e4e254e4a6bULL, 0x7366b7b7e6b7d151ULL, 0xcbe0ebeb8beb0b60ULL, - 0x78c13c3cf03cfdccULL, 0x1ffd81813e817cbfULL, 0x354094946a94d4feULL, 0xf31cf7f7fbf7eb0cULL, - 0x6f18b9b9deb9a167ULL, 0x268b13134c13985fULL, 0x58512c2cb02c7d9cULL, 0xbb05d3d36bd3d6b8ULL, - 0xd38ce7e7bbe76b5cULL, 0xdc396e6ea56e57cbULL, 0x95aac4c437c46ef3ULL, 0x061b03030c03180fULL, - 0xacdc565645568a13ULL, 0x885e44440d441a49ULL, 0xfea07f7fe17fdf9eULL, 0x4f88a9a99ea92137ULL, - 0x54672a2aa82a4d82ULL, 0x6b0abbbbd6bbb16dULL, 0x9f87c1c123c146e2ULL, 0xa6f153535153a202ULL, - 0xa572dcdc57dcae8bULL, 0x16530b0b2c0b5827ULL, 0x27019d9d4e9d9cd3ULL, 0xd82b6c6cad6c47c1ULL, - 0x62a43131c43195f5ULL, 0xe8f37474cd7487b9ULL, 0xf115f6f6fff6e309ULL, 0x8c4c464605460a43ULL, - 0x45a5acac8aac0926ULL, 0x0fb589891e893c97ULL, 0x28b414145014a044ULL, 0xdfbae1e1a3e15b42ULL, - 0x2ca616165816b04eULL, 0x74f73a3ae83acdd2ULL, 0xd2066969b9696fd0ULL, 0x124109092409482dULL, - 0xe0d77070dd70a7adULL, 0x716fb6b6e2b6d954ULL, 0xbd1ed0d067d0ceb7ULL, 0xc7d6eded93ed3b7eULL, - 0x85e2cccc17cc2edbULL, 0x8468424215422a57ULL, 0x2d2c98985a98b4c2ULL, 0x55eda4a4aaa4490eULL, - 0x50752828a0285d88ULL, 0xb8865c5c6d5cda31ULL, 0xed6bf8f8c7f8933fULL, 0x11c28686228644a4ULL, - }; - - const nzUInt64 C3[256] = { - 0x7830d818186018c0ULL, 0xaf462623238c2305ULL, 0xf991b8c6c63fc67eULL, 0x6fcdfbe8e887e813ULL, - 0xa113cb878726874cULL, 0x626d11b8b8dab8a9ULL, 0x0502090101040108ULL, 0x6e9e0d4f4f214f42ULL, - 0xee6c9b3636d836adULL, 0x0451ffa6a6a2a659ULL, 0xbdb90cd2d26fd2deULL, 0x06f70ef5f5f3f5fbULL, - 0x80f2967979f979efULL, 0xcede306f6fa16f5fULL, 0xef3f6d91917e91fcULL, 0x07a4f852525552aaULL, - 0xfdc04760609d6027ULL, 0x766535bcbccabc89ULL, 0xcd2b379b9b569bacULL, 0x8c018a8e8e028e04ULL, - 0x155bd2a3a3b6a371ULL, 0x3c186c0c0c300c60ULL, 0x8af6847b7bf17bffULL, 0xe16a803535d435b5ULL, - 0x693af51d1d741de8ULL, 0x47ddb3e0e0a7e053ULL, 0xacb321d7d77bd7f6ULL, 0xed999cc2c22fc25eULL, - 0x965c432e2eb82e6dULL, 0x7a96294b4b314b62ULL, 0x21e15dfefedffea3ULL, 0x16aed55757415782ULL, - 0x412abd15155415a8ULL, 0xb6eee87777c1779fULL, 0xeb6e923737dc37a5ULL, 0x56d79ee5e5b3e57bULL, - 0xd923139f9f469f8cULL, 0x17fd23f0f0e7f0d3ULL, 0x7f94204a4a354a6aULL, 0x95a944dada4fda9eULL, - 0x25b0a258587d58faULL, 0xca8fcfc9c903c906ULL, 0x8d527c2929a42955ULL, 0x22145a0a0a280a50ULL, - 0x4f7f50b1b1feb1e1ULL, 0x1a5dc9a0a0baa069ULL, 0xdad6146b6bb16b7fULL, 0xab17d985852e855cULL, - 0x73673cbdbdcebd81ULL, 0x34ba8f5d5d695dd2ULL, 0x5020901010401080ULL, 0x03f507f4f4f7f4f3ULL, - 0xc08bddcbcb0bcb16ULL, 0xc67cd33e3ef83eedULL, 0x110a2d0505140528ULL, 0xe6ce78676781671fULL, - 0x53d597e4e4b7e473ULL, 0xbb4e0227279c2725ULL, 0x5882734141194132ULL, 0x9d0ba78b8b168b2cULL, - 0x0153f6a7a7a6a751ULL, 0x94fab27d7de97dcfULL, 0xfb374995956e95dcULL, 0x9fad56d8d847d88eULL, - 0x30eb70fbfbcbfb8bULL, 0x71c1cdeeee9fee23ULL, 0x91f8bb7c7ced7cc7ULL, 0xe3cc716666856617ULL, - 0x8ea77bdddd53dda6ULL, 0x4b2eaf17175c17b8ULL, 0x468e454747014702ULL, 0xdc211a9e9e429e84ULL, - 0xc589d4caca0fca1eULL, 0x995a582d2db42d75ULL, 0x79632ebfbfc6bf91ULL, 0x1b0e3f07071c0738ULL, - 0x2347acadad8ead01ULL, 0x2fb4b05a5a755aeaULL, 0xb51bef838336836cULL, 0xff66b63333cc3385ULL, - 0xf2c65c636391633fULL, 0x0a04120202080210ULL, 0x384993aaaa92aa39ULL, 0xa8e2de7171d971afULL, - 0xcf8dc6c8c807c80eULL, 0x7d32d119196419c8ULL, 0x70923b4949394972ULL, 0x9aaf5fd9d943d986ULL, - 0x1df931f2f2eff2c3ULL, 0x48dba8e3e3abe34bULL, 0x2ab6b95b5b715be2ULL, 0x920dbc88881a8834ULL, - 0xc8293e9a9a529aa4ULL, 0xbe4c0b262698262dULL, 0xfa64bf3232c8328dULL, 0x4a7d59b0b0fab0e9ULL, - 0x6acff2e9e983e91bULL, 0x331e770f0f3c0f78ULL, 0xa6b733d5d573d5e6ULL, 0xba1df480803a8074ULL, - 0x7c6127bebec2be99ULL, 0xde87ebcdcd13cd26ULL, 0xe468893434d034bdULL, 0x75903248483d487aULL, - 0x24e354ffffdbffabULL, 0x8ff48d7a7af57af7ULL, 0xea3d6490907a90f4ULL, 0x3ebe9d5f5f615fc2ULL, - 0xa0403d202080201dULL, 0xd5d00f6868bd6867ULL, 0x7234ca1a1a681ad0ULL, 0x2c41b7aeae82ae19ULL, - 0x5e757db4b4eab4c9ULL, 0x19a8ce54544d549aULL, 0xe53b7f93937693ecULL, 0xaa442f222288220dULL, - 0xe9c86364648d6407ULL, 0x12ff2af1f1e3f1dbULL, 0xa2e6cc7373d173bfULL, 0x5a24821212481290ULL, - 0x5d807a40401d403aULL, 0x2810480808200840ULL, 0xe89b95c3c32bc356ULL, 0x7bc5dfecec97ec33ULL, - 0x90ab4ddbdb4bdb96ULL, 0x1f5fc0a1a1bea161ULL, 0x8307918d8d0e8d1cULL, 0xc97ac83d3df43df5ULL, - 0xf1335b97976697ccULL, 0x0000000000000000ULL, 0xd483f9cfcf1bcf36ULL, 0x87566e2b2bac2b45ULL, - 0xb3ece17676c57697ULL, 0xb019e68282328264ULL, 0xa9b128d6d67fd6feULL, 0x7736c31b1b6c1bd8ULL, - 0x5b7774b5b5eeb5c1ULL, 0x2943beafaf86af11ULL, 0xdfd41d6a6ab56a77ULL, 0x0da0ea50505d50baULL, - 0x4c8a574545094512ULL, 0x18fb38f3f3ebf3cbULL, 0xf060ad3030c0309dULL, 0x74c3c4efef9bef2bULL, - 0xc37eda3f3ffc3fe5ULL, 0x1caac75555495592ULL, 0x1059dba2a2b2a279ULL, 0x65c9e9eaea8fea03ULL, - 0xecca6a656589650fULL, 0x686903babad2bab9ULL, 0x935e4a2f2fbc2f65ULL, 0xe79d8ec0c027c04eULL, - 0x81a160dede5fdebeULL, 0x6c38fc1c1c701ce0ULL, 0x2ee746fdfdd3fdbbULL, 0x649a1f4d4d294d52ULL, - 0xe0397692927292e4ULL, 0xbceafa7575c9758fULL, 0x1e0c360606180630ULL, 0x9809ae8a8a128a24ULL, - 0x40794bb2b2f2b2f9ULL, 0x59d185e6e6bfe663ULL, 0x361c7e0e0e380e70ULL, 0x633ee71f1f7c1ff8ULL, - 0xf7c4556262956237ULL, 0xa3b53ad4d477d4eeULL, 0x324d81a8a89aa829ULL, 0xf4315296966296c4ULL, - 0x3aef62f9f9c3f99bULL, 0xf697a3c5c533c566ULL, 0xb14a102525942535ULL, 0x20b2ab59597959f2ULL, - 0xae15d084842a8454ULL, 0xa7e4c57272d572b7ULL, 0xdd72ec3939e439d5ULL, 0x6198164c4c2d4c5aULL, - 0x3bbc945e5e655ecaULL, 0x85f09f7878fd78e7ULL, 0xd870e53838e038ddULL, 0x8605988c8c0a8c14ULL, - 0xb2bf17d1d163d1c6ULL, 0x0b57e4a5a5aea541ULL, 0x4dd9a1e2e2afe243ULL, 0xf8c24e616199612fULL, - 0x457b42b3b3f6b3f1ULL, 0xa542342121842115ULL, 0xd625089c9c4a9c94ULL, 0x663cee1e1e781ef0ULL, - 0x5286614343114322ULL, 0xfc93b1c7c73bc776ULL, 0x2be54ffcfcd7fcb3ULL, 0x1408240404100420ULL, - 0x08a2e351515951b2ULL, 0xc72f2599995e99bcULL, 0xc4da226d6da96d4fULL, 0x391a650d0d340d68ULL, - 0x35e979fafacffa83ULL, 0x84a369dfdf5bdfb6ULL, 0x9bfca97e7ee57ed7ULL, 0xb44819242490243dULL, - 0xd776fe3b3bec3bc5ULL, 0x3d4b9aabab96ab31ULL, 0xd181f0cece1fce3eULL, 0x5522991111441188ULL, - 0x8903838f8f068f0cULL, 0x6b9c044e4e254e4aULL, 0x517366b7b7e6b7d1ULL, 0x60cbe0ebeb8beb0bULL, - 0xcc78c13c3cf03cfdULL, 0xbf1ffd81813e817cULL, 0xfe354094946a94d4ULL, 0x0cf31cf7f7fbf7ebULL, - 0x676f18b9b9deb9a1ULL, 0x5f268b13134c1398ULL, 0x9c58512c2cb02c7dULL, 0xb8bb05d3d36bd3d6ULL, - 0x5cd38ce7e7bbe76bULL, 0xcbdc396e6ea56e57ULL, 0xf395aac4c437c46eULL, 0x0f061b03030c0318ULL, - 0x13acdc565645568aULL, 0x49885e44440d441aULL, 0x9efea07f7fe17fdfULL, 0x374f88a9a99ea921ULL, - 0x8254672a2aa82a4dULL, 0x6d6b0abbbbd6bbb1ULL, 0xe29f87c1c123c146ULL, 0x02a6f153535153a2ULL, - 0x8ba572dcdc57dcaeULL, 0x2716530b0b2c0b58ULL, 0xd327019d9d4e9d9cULL, 0xc1d82b6c6cad6c47ULL, - 0xf562a43131c43195ULL, 0xb9e8f37474cd7487ULL, 0x09f115f6f6fff6e3ULL, 0x438c4c464605460aULL, - 0x2645a5acac8aac09ULL, 0x970fb589891e893cULL, 0x4428b414145014a0ULL, 0x42dfbae1e1a3e15bULL, - 0x4e2ca616165816b0ULL, 0xd274f73a3ae83acdULL, 0xd0d2066969b9696fULL, 0x2d12410909240948ULL, - 0xade0d77070dd70a7ULL, 0x54716fb6b6e2b6d9ULL, 0xb7bd1ed0d067d0ceULL, 0x7ec7d6eded93ed3bULL, - 0xdb85e2cccc17cc2eULL, 0x578468424215422aULL, 0xc22d2c98985a98b4ULL, 0x0e55eda4a4aaa449ULL, - 0x8850752828a0285dULL, 0x31b8865c5c6d5cdaULL, 0x3fed6bf8f8c7f893ULL, 0xa411c28686228644ULL, - }; - - const nzUInt64 C4[256] = { - 0xc07830d818186018ULL, 0x05af462623238c23ULL, 0x7ef991b8c6c63fc6ULL, 0x136fcdfbe8e887e8ULL, - 0x4ca113cb87872687ULL, 0xa9626d11b8b8dab8ULL, 0x0805020901010401ULL, 0x426e9e0d4f4f214fULL, - 0xadee6c9b3636d836ULL, 0x590451ffa6a6a2a6ULL, 0xdebdb90cd2d26fd2ULL, 0xfb06f70ef5f5f3f5ULL, - 0xef80f2967979f979ULL, 0x5fcede306f6fa16fULL, 0xfcef3f6d91917e91ULL, 0xaa07a4f852525552ULL, - 0x27fdc04760609d60ULL, 0x89766535bcbccabcULL, 0xaccd2b379b9b569bULL, 0x048c018a8e8e028eULL, - 0x71155bd2a3a3b6a3ULL, 0x603c186c0c0c300cULL, 0xff8af6847b7bf17bULL, 0xb5e16a803535d435ULL, - 0xe8693af51d1d741dULL, 0x5347ddb3e0e0a7e0ULL, 0xf6acb321d7d77bd7ULL, 0x5eed999cc2c22fc2ULL, - 0x6d965c432e2eb82eULL, 0x627a96294b4b314bULL, 0xa321e15dfefedffeULL, 0x8216aed557574157ULL, - 0xa8412abd15155415ULL, 0x9fb6eee87777c177ULL, 0xa5eb6e923737dc37ULL, 0x7b56d79ee5e5b3e5ULL, - 0x8cd923139f9f469fULL, 0xd317fd23f0f0e7f0ULL, 0x6a7f94204a4a354aULL, 0x9e95a944dada4fdaULL, - 0xfa25b0a258587d58ULL, 0x06ca8fcfc9c903c9ULL, 0x558d527c2929a429ULL, 0x5022145a0a0a280aULL, - 0xe14f7f50b1b1feb1ULL, 0x691a5dc9a0a0baa0ULL, 0x7fdad6146b6bb16bULL, 0x5cab17d985852e85ULL, - 0x8173673cbdbdcebdULL, 0xd234ba8f5d5d695dULL, 0x8050209010104010ULL, 0xf303f507f4f4f7f4ULL, - 0x16c08bddcbcb0bcbULL, 0xedc67cd33e3ef83eULL, 0x28110a2d05051405ULL, 0x1fe6ce7867678167ULL, - 0x7353d597e4e4b7e4ULL, 0x25bb4e0227279c27ULL, 0x3258827341411941ULL, 0x2c9d0ba78b8b168bULL, - 0x510153f6a7a7a6a7ULL, 0xcf94fab27d7de97dULL, 0xdcfb374995956e95ULL, 0x8e9fad56d8d847d8ULL, - 0x8b30eb70fbfbcbfbULL, 0x2371c1cdeeee9feeULL, 0xc791f8bb7c7ced7cULL, 0x17e3cc7166668566ULL, - 0xa68ea77bdddd53ddULL, 0xb84b2eaf17175c17ULL, 0x02468e4547470147ULL, 0x84dc211a9e9e429eULL, - 0x1ec589d4caca0fcaULL, 0x75995a582d2db42dULL, 0x9179632ebfbfc6bfULL, 0x381b0e3f07071c07ULL, - 0x012347acadad8eadULL, 0xea2fb4b05a5a755aULL, 0x6cb51bef83833683ULL, 0x85ff66b63333cc33ULL, - 0x3ff2c65c63639163ULL, 0x100a041202020802ULL, 0x39384993aaaa92aaULL, 0xafa8e2de7171d971ULL, - 0x0ecf8dc6c8c807c8ULL, 0xc87d32d119196419ULL, 0x7270923b49493949ULL, 0x869aaf5fd9d943d9ULL, - 0xc31df931f2f2eff2ULL, 0x4b48dba8e3e3abe3ULL, 0xe22ab6b95b5b715bULL, 0x34920dbc88881a88ULL, - 0xa4c8293e9a9a529aULL, 0x2dbe4c0b26269826ULL, 0x8dfa64bf3232c832ULL, 0xe94a7d59b0b0fab0ULL, - 0x1b6acff2e9e983e9ULL, 0x78331e770f0f3c0fULL, 0xe6a6b733d5d573d5ULL, 0x74ba1df480803a80ULL, - 0x997c6127bebec2beULL, 0x26de87ebcdcd13cdULL, 0xbde468893434d034ULL, 0x7a75903248483d48ULL, - 0xab24e354ffffdbffULL, 0xf78ff48d7a7af57aULL, 0xf4ea3d6490907a90ULL, 0xc23ebe9d5f5f615fULL, - 0x1da0403d20208020ULL, 0x67d5d00f6868bd68ULL, 0xd07234ca1a1a681aULL, 0x192c41b7aeae82aeULL, - 0xc95e757db4b4eab4ULL, 0x9a19a8ce54544d54ULL, 0xece53b7f93937693ULL, 0x0daa442f22228822ULL, - 0x07e9c86364648d64ULL, 0xdb12ff2af1f1e3f1ULL, 0xbfa2e6cc7373d173ULL, 0x905a248212124812ULL, - 0x3a5d807a40401d40ULL, 0x4028104808082008ULL, 0x56e89b95c3c32bc3ULL, 0x337bc5dfecec97ecULL, - 0x9690ab4ddbdb4bdbULL, 0x611f5fc0a1a1bea1ULL, 0x1c8307918d8d0e8dULL, 0xf5c97ac83d3df43dULL, - 0xccf1335b97976697ULL, 0x0000000000000000ULL, 0x36d483f9cfcf1bcfULL, 0x4587566e2b2bac2bULL, - 0x97b3ece17676c576ULL, 0x64b019e682823282ULL, 0xfea9b128d6d67fd6ULL, 0xd87736c31b1b6c1bULL, - 0xc15b7774b5b5eeb5ULL, 0x112943beafaf86afULL, 0x77dfd41d6a6ab56aULL, 0xba0da0ea50505d50ULL, - 0x124c8a5745450945ULL, 0xcb18fb38f3f3ebf3ULL, 0x9df060ad3030c030ULL, 0x2b74c3c4efef9befULL, - 0xe5c37eda3f3ffc3fULL, 0x921caac755554955ULL, 0x791059dba2a2b2a2ULL, 0x0365c9e9eaea8feaULL, - 0x0fecca6a65658965ULL, 0xb9686903babad2baULL, 0x65935e4a2f2fbc2fULL, 0x4ee79d8ec0c027c0ULL, - 0xbe81a160dede5fdeULL, 0xe06c38fc1c1c701cULL, 0xbb2ee746fdfdd3fdULL, 0x52649a1f4d4d294dULL, - 0xe4e0397692927292ULL, 0x8fbceafa7575c975ULL, 0x301e0c3606061806ULL, 0x249809ae8a8a128aULL, - 0xf940794bb2b2f2b2ULL, 0x6359d185e6e6bfe6ULL, 0x70361c7e0e0e380eULL, 0xf8633ee71f1f7c1fULL, - 0x37f7c45562629562ULL, 0xeea3b53ad4d477d4ULL, 0x29324d81a8a89aa8ULL, 0xc4f4315296966296ULL, - 0x9b3aef62f9f9c3f9ULL, 0x66f697a3c5c533c5ULL, 0x35b14a1025259425ULL, 0xf220b2ab59597959ULL, - 0x54ae15d084842a84ULL, 0xb7a7e4c57272d572ULL, 0xd5dd72ec3939e439ULL, 0x5a6198164c4c2d4cULL, - 0xca3bbc945e5e655eULL, 0xe785f09f7878fd78ULL, 0xddd870e53838e038ULL, 0x148605988c8c0a8cULL, - 0xc6b2bf17d1d163d1ULL, 0x410b57e4a5a5aea5ULL, 0x434dd9a1e2e2afe2ULL, 0x2ff8c24e61619961ULL, - 0xf1457b42b3b3f6b3ULL, 0x15a5423421218421ULL, 0x94d625089c9c4a9cULL, 0xf0663cee1e1e781eULL, - 0x2252866143431143ULL, 0x76fc93b1c7c73bc7ULL, 0xb32be54ffcfcd7fcULL, 0x2014082404041004ULL, - 0xb208a2e351515951ULL, 0xbcc72f2599995e99ULL, 0x4fc4da226d6da96dULL, 0x68391a650d0d340dULL, - 0x8335e979fafacffaULL, 0xb684a369dfdf5bdfULL, 0xd79bfca97e7ee57eULL, 0x3db4481924249024ULL, - 0xc5d776fe3b3bec3bULL, 0x313d4b9aabab96abULL, 0x3ed181f0cece1fceULL, 0x8855229911114411ULL, - 0x0c8903838f8f068fULL, 0x4a6b9c044e4e254eULL, 0xd1517366b7b7e6b7ULL, 0x0b60cbe0ebeb8bebULL, - 0xfdcc78c13c3cf03cULL, 0x7cbf1ffd81813e81ULL, 0xd4fe354094946a94ULL, 0xeb0cf31cf7f7fbf7ULL, - 0xa1676f18b9b9deb9ULL, 0x985f268b13134c13ULL, 0x7d9c58512c2cb02cULL, 0xd6b8bb05d3d36bd3ULL, - 0x6b5cd38ce7e7bbe7ULL, 0x57cbdc396e6ea56eULL, 0x6ef395aac4c437c4ULL, 0x180f061b03030c03ULL, - 0x8a13acdc56564556ULL, 0x1a49885e44440d44ULL, 0xdf9efea07f7fe17fULL, 0x21374f88a9a99ea9ULL, - 0x4d8254672a2aa82aULL, 0xb16d6b0abbbbd6bbULL, 0x46e29f87c1c123c1ULL, 0xa202a6f153535153ULL, - 0xae8ba572dcdc57dcULL, 0x582716530b0b2c0bULL, 0x9cd327019d9d4e9dULL, 0x47c1d82b6c6cad6cULL, - 0x95f562a43131c431ULL, 0x87b9e8f37474cd74ULL, 0xe309f115f6f6fff6ULL, 0x0a438c4c46460546ULL, - 0x092645a5acac8aacULL, 0x3c970fb589891e89ULL, 0xa04428b414145014ULL, 0x5b42dfbae1e1a3e1ULL, - 0xb04e2ca616165816ULL, 0xcdd274f73a3ae83aULL, 0x6fd0d2066969b969ULL, 0x482d124109092409ULL, - 0xa7ade0d77070dd70ULL, 0xd954716fb6b6e2b6ULL, 0xceb7bd1ed0d067d0ULL, 0x3b7ec7d6eded93edULL, - 0x2edb85e2cccc17ccULL, 0x2a57846842421542ULL, 0xb4c22d2c98985a98ULL, 0x490e55eda4a4aaa4ULL, - 0x5d8850752828a028ULL, 0xda31b8865c5c6d5cULL, 0x933fed6bf8f8c7f8ULL, 0x44a411c286862286ULL, - }; - - const nzUInt64 C5[256] = { - 0x18c07830d8181860ULL, 0x2305af462623238cULL, 0xc67ef991b8c6c63fULL, 0xe8136fcdfbe8e887ULL, - 0x874ca113cb878726ULL, 0xb8a9626d11b8b8daULL, 0x0108050209010104ULL, 0x4f426e9e0d4f4f21ULL, - 0x36adee6c9b3636d8ULL, 0xa6590451ffa6a6a2ULL, 0xd2debdb90cd2d26fULL, 0xf5fb06f70ef5f5f3ULL, - 0x79ef80f2967979f9ULL, 0x6f5fcede306f6fa1ULL, 0x91fcef3f6d91917eULL, 0x52aa07a4f8525255ULL, - 0x6027fdc04760609dULL, 0xbc89766535bcbccaULL, 0x9baccd2b379b9b56ULL, 0x8e048c018a8e8e02ULL, - 0xa371155bd2a3a3b6ULL, 0x0c603c186c0c0c30ULL, 0x7bff8af6847b7bf1ULL, 0x35b5e16a803535d4ULL, - 0x1de8693af51d1d74ULL, 0xe05347ddb3e0e0a7ULL, 0xd7f6acb321d7d77bULL, 0xc25eed999cc2c22fULL, - 0x2e6d965c432e2eb8ULL, 0x4b627a96294b4b31ULL, 0xfea321e15dfefedfULL, 0x578216aed5575741ULL, - 0x15a8412abd151554ULL, 0x779fb6eee87777c1ULL, 0x37a5eb6e923737dcULL, 0xe57b56d79ee5e5b3ULL, - 0x9f8cd923139f9f46ULL, 0xf0d317fd23f0f0e7ULL, 0x4a6a7f94204a4a35ULL, 0xda9e95a944dada4fULL, - 0x58fa25b0a258587dULL, 0xc906ca8fcfc9c903ULL, 0x29558d527c2929a4ULL, 0x0a5022145a0a0a28ULL, - 0xb1e14f7f50b1b1feULL, 0xa0691a5dc9a0a0baULL, 0x6b7fdad6146b6bb1ULL, 0x855cab17d985852eULL, - 0xbd8173673cbdbdceULL, 0x5dd234ba8f5d5d69ULL, 0x1080502090101040ULL, 0xf4f303f507f4f4f7ULL, - 0xcb16c08bddcbcb0bULL, 0x3eedc67cd33e3ef8ULL, 0x0528110a2d050514ULL, 0x671fe6ce78676781ULL, - 0xe47353d597e4e4b7ULL, 0x2725bb4e0227279cULL, 0x4132588273414119ULL, 0x8b2c9d0ba78b8b16ULL, - 0xa7510153f6a7a7a6ULL, 0x7dcf94fab27d7de9ULL, 0x95dcfb374995956eULL, 0xd88e9fad56d8d847ULL, - 0xfb8b30eb70fbfbcbULL, 0xee2371c1cdeeee9fULL, 0x7cc791f8bb7c7cedULL, 0x6617e3cc71666685ULL, - 0xdda68ea77bdddd53ULL, 0x17b84b2eaf17175cULL, 0x4702468e45474701ULL, 0x9e84dc211a9e9e42ULL, - 0xca1ec589d4caca0fULL, 0x2d75995a582d2db4ULL, 0xbf9179632ebfbfc6ULL, 0x07381b0e3f07071cULL, - 0xad012347acadad8eULL, 0x5aea2fb4b05a5a75ULL, 0x836cb51bef838336ULL, 0x3385ff66b63333ccULL, - 0x633ff2c65c636391ULL, 0x02100a0412020208ULL, 0xaa39384993aaaa92ULL, 0x71afa8e2de7171d9ULL, - 0xc80ecf8dc6c8c807ULL, 0x19c87d32d1191964ULL, 0x497270923b494939ULL, 0xd9869aaf5fd9d943ULL, - 0xf2c31df931f2f2efULL, 0xe34b48dba8e3e3abULL, 0x5be22ab6b95b5b71ULL, 0x8834920dbc88881aULL, - 0x9aa4c8293e9a9a52ULL, 0x262dbe4c0b262698ULL, 0x328dfa64bf3232c8ULL, 0xb0e94a7d59b0b0faULL, - 0xe91b6acff2e9e983ULL, 0x0f78331e770f0f3cULL, 0xd5e6a6b733d5d573ULL, 0x8074ba1df480803aULL, - 0xbe997c6127bebec2ULL, 0xcd26de87ebcdcd13ULL, 0x34bde468893434d0ULL, 0x487a75903248483dULL, - 0xffab24e354ffffdbULL, 0x7af78ff48d7a7af5ULL, 0x90f4ea3d6490907aULL, 0x5fc23ebe9d5f5f61ULL, - 0x201da0403d202080ULL, 0x6867d5d00f6868bdULL, 0x1ad07234ca1a1a68ULL, 0xae192c41b7aeae82ULL, - 0xb4c95e757db4b4eaULL, 0x549a19a8ce54544dULL, 0x93ece53b7f939376ULL, 0x220daa442f222288ULL, - 0x6407e9c86364648dULL, 0xf1db12ff2af1f1e3ULL, 0x73bfa2e6cc7373d1ULL, 0x12905a2482121248ULL, - 0x403a5d807a40401dULL, 0x0840281048080820ULL, 0xc356e89b95c3c32bULL, 0xec337bc5dfecec97ULL, - 0xdb9690ab4ddbdb4bULL, 0xa1611f5fc0a1a1beULL, 0x8d1c8307918d8d0eULL, 0x3df5c97ac83d3df4ULL, - 0x97ccf1335b979766ULL, 0x0000000000000000ULL, 0xcf36d483f9cfcf1bULL, 0x2b4587566e2b2bacULL, - 0x7697b3ece17676c5ULL, 0x8264b019e6828232ULL, 0xd6fea9b128d6d67fULL, 0x1bd87736c31b1b6cULL, - 0xb5c15b7774b5b5eeULL, 0xaf112943beafaf86ULL, 0x6a77dfd41d6a6ab5ULL, 0x50ba0da0ea50505dULL, - 0x45124c8a57454509ULL, 0xf3cb18fb38f3f3ebULL, 0x309df060ad3030c0ULL, 0xef2b74c3c4efef9bULL, - 0x3fe5c37eda3f3ffcULL, 0x55921caac7555549ULL, 0xa2791059dba2a2b2ULL, 0xea0365c9e9eaea8fULL, - 0x650fecca6a656589ULL, 0xbab9686903babad2ULL, 0x2f65935e4a2f2fbcULL, 0xc04ee79d8ec0c027ULL, - 0xdebe81a160dede5fULL, 0x1ce06c38fc1c1c70ULL, 0xfdbb2ee746fdfdd3ULL, 0x4d52649a1f4d4d29ULL, - 0x92e4e03976929272ULL, 0x758fbceafa7575c9ULL, 0x06301e0c36060618ULL, 0x8a249809ae8a8a12ULL, - 0xb2f940794bb2b2f2ULL, 0xe66359d185e6e6bfULL, 0x0e70361c7e0e0e38ULL, 0x1ff8633ee71f1f7cULL, - 0x6237f7c455626295ULL, 0xd4eea3b53ad4d477ULL, 0xa829324d81a8a89aULL, 0x96c4f43152969662ULL, - 0xf99b3aef62f9f9c3ULL, 0xc566f697a3c5c533ULL, 0x2535b14a10252594ULL, 0x59f220b2ab595979ULL, - 0x8454ae15d084842aULL, 0x72b7a7e4c57272d5ULL, 0x39d5dd72ec3939e4ULL, 0x4c5a6198164c4c2dULL, - 0x5eca3bbc945e5e65ULL, 0x78e785f09f7878fdULL, 0x38ddd870e53838e0ULL, 0x8c148605988c8c0aULL, - 0xd1c6b2bf17d1d163ULL, 0xa5410b57e4a5a5aeULL, 0xe2434dd9a1e2e2afULL, 0x612ff8c24e616199ULL, - 0xb3f1457b42b3b3f6ULL, 0x2115a54234212184ULL, 0x9c94d625089c9c4aULL, 0x1ef0663cee1e1e78ULL, - 0x4322528661434311ULL, 0xc776fc93b1c7c73bULL, 0xfcb32be54ffcfcd7ULL, 0x0420140824040410ULL, - 0x51b208a2e3515159ULL, 0x99bcc72f2599995eULL, 0x6d4fc4da226d6da9ULL, 0x0d68391a650d0d34ULL, - 0xfa8335e979fafacfULL, 0xdfb684a369dfdf5bULL, 0x7ed79bfca97e7ee5ULL, 0x243db44819242490ULL, - 0x3bc5d776fe3b3becULL, 0xab313d4b9aabab96ULL, 0xce3ed181f0cece1fULL, 0x1188552299111144ULL, - 0x8f0c8903838f8f06ULL, 0x4e4a6b9c044e4e25ULL, 0xb7d1517366b7b7e6ULL, 0xeb0b60cbe0ebeb8bULL, - 0x3cfdcc78c13c3cf0ULL, 0x817cbf1ffd81813eULL, 0x94d4fe354094946aULL, 0xf7eb0cf31cf7f7fbULL, - 0xb9a1676f18b9b9deULL, 0x13985f268b13134cULL, 0x2c7d9c58512c2cb0ULL, 0xd3d6b8bb05d3d36bULL, - 0xe76b5cd38ce7e7bbULL, 0x6e57cbdc396e6ea5ULL, 0xc46ef395aac4c437ULL, 0x03180f061b03030cULL, - 0x568a13acdc565645ULL, 0x441a49885e44440dULL, 0x7fdf9efea07f7fe1ULL, 0xa921374f88a9a99eULL, - 0x2a4d8254672a2aa8ULL, 0xbbb16d6b0abbbbd6ULL, 0xc146e29f87c1c123ULL, 0x53a202a6f1535351ULL, - 0xdcae8ba572dcdc57ULL, 0x0b582716530b0b2cULL, 0x9d9cd327019d9d4eULL, 0x6c47c1d82b6c6cadULL, - 0x3195f562a43131c4ULL, 0x7487b9e8f37474cdULL, 0xf6e309f115f6f6ffULL, 0x460a438c4c464605ULL, - 0xac092645a5acac8aULL, 0x893c970fb589891eULL, 0x14a04428b4141450ULL, 0xe15b42dfbae1e1a3ULL, - 0x16b04e2ca6161658ULL, 0x3acdd274f73a3ae8ULL, 0x696fd0d2066969b9ULL, 0x09482d1241090924ULL, - 0x70a7ade0d77070ddULL, 0xb6d954716fb6b6e2ULL, 0xd0ceb7bd1ed0d067ULL, 0xed3b7ec7d6eded93ULL, - 0xcc2edb85e2cccc17ULL, 0x422a578468424215ULL, 0x98b4c22d2c98985aULL, 0xa4490e55eda4a4aaULL, - 0x285d8850752828a0ULL, 0x5cda31b8865c5c6dULL, 0xf8933fed6bf8f8c7ULL, 0x8644a411c2868622ULL, - }; - - const nzUInt64 C6[256] = { - 0x6018c07830d81818ULL, 0x8c2305af46262323ULL, 0x3fc67ef991b8c6c6ULL, 0x87e8136fcdfbe8e8ULL, - 0x26874ca113cb8787ULL, 0xdab8a9626d11b8b8ULL, 0x0401080502090101ULL, 0x214f426e9e0d4f4fULL, - 0xd836adee6c9b3636ULL, 0xa2a6590451ffa6a6ULL, 0x6fd2debdb90cd2d2ULL, 0xf3f5fb06f70ef5f5ULL, - 0xf979ef80f2967979ULL, 0xa16f5fcede306f6fULL, 0x7e91fcef3f6d9191ULL, 0x5552aa07a4f85252ULL, - 0x9d6027fdc0476060ULL, 0xcabc89766535bcbcULL, 0x569baccd2b379b9bULL, 0x028e048c018a8e8eULL, - 0xb6a371155bd2a3a3ULL, 0x300c603c186c0c0cULL, 0xf17bff8af6847b7bULL, 0xd435b5e16a803535ULL, - 0x741de8693af51d1dULL, 0xa7e05347ddb3e0e0ULL, 0x7bd7f6acb321d7d7ULL, 0x2fc25eed999cc2c2ULL, - 0xb82e6d965c432e2eULL, 0x314b627a96294b4bULL, 0xdffea321e15dfefeULL, 0x41578216aed55757ULL, - 0x5415a8412abd1515ULL, 0xc1779fb6eee87777ULL, 0xdc37a5eb6e923737ULL, 0xb3e57b56d79ee5e5ULL, - 0x469f8cd923139f9fULL, 0xe7f0d317fd23f0f0ULL, 0x354a6a7f94204a4aULL, 0x4fda9e95a944dadaULL, - 0x7d58fa25b0a25858ULL, 0x03c906ca8fcfc9c9ULL, 0xa429558d527c2929ULL, 0x280a5022145a0a0aULL, - 0xfeb1e14f7f50b1b1ULL, 0xbaa0691a5dc9a0a0ULL, 0xb16b7fdad6146b6bULL, 0x2e855cab17d98585ULL, - 0xcebd8173673cbdbdULL, 0x695dd234ba8f5d5dULL, 0x4010805020901010ULL, 0xf7f4f303f507f4f4ULL, - 0x0bcb16c08bddcbcbULL, 0xf83eedc67cd33e3eULL, 0x140528110a2d0505ULL, 0x81671fe6ce786767ULL, - 0xb7e47353d597e4e4ULL, 0x9c2725bb4e022727ULL, 0x1941325882734141ULL, 0x168b2c9d0ba78b8bULL, - 0xa6a7510153f6a7a7ULL, 0xe97dcf94fab27d7dULL, 0x6e95dcfb37499595ULL, 0x47d88e9fad56d8d8ULL, - 0xcbfb8b30eb70fbfbULL, 0x9fee2371c1cdeeeeULL, 0xed7cc791f8bb7c7cULL, 0x856617e3cc716666ULL, - 0x53dda68ea77bddddULL, 0x5c17b84b2eaf1717ULL, 0x014702468e454747ULL, 0x429e84dc211a9e9eULL, - 0x0fca1ec589d4cacaULL, 0xb42d75995a582d2dULL, 0xc6bf9179632ebfbfULL, 0x1c07381b0e3f0707ULL, - 0x8ead012347acadadULL, 0x755aea2fb4b05a5aULL, 0x36836cb51bef8383ULL, 0xcc3385ff66b63333ULL, - 0x91633ff2c65c6363ULL, 0x0802100a04120202ULL, 0x92aa39384993aaaaULL, 0xd971afa8e2de7171ULL, - 0x07c80ecf8dc6c8c8ULL, 0x6419c87d32d11919ULL, 0x39497270923b4949ULL, 0x43d9869aaf5fd9d9ULL, - 0xeff2c31df931f2f2ULL, 0xabe34b48dba8e3e3ULL, 0x715be22ab6b95b5bULL, 0x1a8834920dbc8888ULL, - 0x529aa4c8293e9a9aULL, 0x98262dbe4c0b2626ULL, 0xc8328dfa64bf3232ULL, 0xfab0e94a7d59b0b0ULL, - 0x83e91b6acff2e9e9ULL, 0x3c0f78331e770f0fULL, 0x73d5e6a6b733d5d5ULL, 0x3a8074ba1df48080ULL, - 0xc2be997c6127bebeULL, 0x13cd26de87ebcdcdULL, 0xd034bde468893434ULL, 0x3d487a7590324848ULL, - 0xdbffab24e354ffffULL, 0xf57af78ff48d7a7aULL, 0x7a90f4ea3d649090ULL, 0x615fc23ebe9d5f5fULL, - 0x80201da0403d2020ULL, 0xbd6867d5d00f6868ULL, 0x681ad07234ca1a1aULL, 0x82ae192c41b7aeaeULL, - 0xeab4c95e757db4b4ULL, 0x4d549a19a8ce5454ULL, 0x7693ece53b7f9393ULL, 0x88220daa442f2222ULL, - 0x8d6407e9c8636464ULL, 0xe3f1db12ff2af1f1ULL, 0xd173bfa2e6cc7373ULL, 0x4812905a24821212ULL, - 0x1d403a5d807a4040ULL, 0x2008402810480808ULL, 0x2bc356e89b95c3c3ULL, 0x97ec337bc5dfececULL, - 0x4bdb9690ab4ddbdbULL, 0xbea1611f5fc0a1a1ULL, 0x0e8d1c8307918d8dULL, 0xf43df5c97ac83d3dULL, - 0x6697ccf1335b9797ULL, 0x0000000000000000ULL, 0x1bcf36d483f9cfcfULL, 0xac2b4587566e2b2bULL, - 0xc57697b3ece17676ULL, 0x328264b019e68282ULL, 0x7fd6fea9b128d6d6ULL, 0x6c1bd87736c31b1bULL, - 0xeeb5c15b7774b5b5ULL, 0x86af112943beafafULL, 0xb56a77dfd41d6a6aULL, 0x5d50ba0da0ea5050ULL, - 0x0945124c8a574545ULL, 0xebf3cb18fb38f3f3ULL, 0xc0309df060ad3030ULL, 0x9bef2b74c3c4efefULL, - 0xfc3fe5c37eda3f3fULL, 0x4955921caac75555ULL, 0xb2a2791059dba2a2ULL, 0x8fea0365c9e9eaeaULL, - 0x89650fecca6a6565ULL, 0xd2bab9686903babaULL, 0xbc2f65935e4a2f2fULL, 0x27c04ee79d8ec0c0ULL, - 0x5fdebe81a160dedeULL, 0x701ce06c38fc1c1cULL, 0xd3fdbb2ee746fdfdULL, 0x294d52649a1f4d4dULL, - 0x7292e4e039769292ULL, 0xc9758fbceafa7575ULL, 0x1806301e0c360606ULL, 0x128a249809ae8a8aULL, - 0xf2b2f940794bb2b2ULL, 0xbfe66359d185e6e6ULL, 0x380e70361c7e0e0eULL, 0x7c1ff8633ee71f1fULL, - 0x956237f7c4556262ULL, 0x77d4eea3b53ad4d4ULL, 0x9aa829324d81a8a8ULL, 0x6296c4f431529696ULL, - 0xc3f99b3aef62f9f9ULL, 0x33c566f697a3c5c5ULL, 0x942535b14a102525ULL, 0x7959f220b2ab5959ULL, - 0x2a8454ae15d08484ULL, 0xd572b7a7e4c57272ULL, 0xe439d5dd72ec3939ULL, 0x2d4c5a6198164c4cULL, - 0x655eca3bbc945e5eULL, 0xfd78e785f09f7878ULL, 0xe038ddd870e53838ULL, 0x0a8c148605988c8cULL, - 0x63d1c6b2bf17d1d1ULL, 0xaea5410b57e4a5a5ULL, 0xafe2434dd9a1e2e2ULL, 0x99612ff8c24e6161ULL, - 0xf6b3f1457b42b3b3ULL, 0x842115a542342121ULL, 0x4a9c94d625089c9cULL, 0x781ef0663cee1e1eULL, - 0x1143225286614343ULL, 0x3bc776fc93b1c7c7ULL, 0xd7fcb32be54ffcfcULL, 0x1004201408240404ULL, - 0x5951b208a2e35151ULL, 0x5e99bcc72f259999ULL, 0xa96d4fc4da226d6dULL, 0x340d68391a650d0dULL, - 0xcffa8335e979fafaULL, 0x5bdfb684a369dfdfULL, 0xe57ed79bfca97e7eULL, 0x90243db448192424ULL, - 0xec3bc5d776fe3b3bULL, 0x96ab313d4b9aababULL, 0x1fce3ed181f0ceceULL, 0x4411885522991111ULL, - 0x068f0c8903838f8fULL, 0x254e4a6b9c044e4eULL, 0xe6b7d1517366b7b7ULL, 0x8beb0b60cbe0ebebULL, - 0xf03cfdcc78c13c3cULL, 0x3e817cbf1ffd8181ULL, 0x6a94d4fe35409494ULL, 0xfbf7eb0cf31cf7f7ULL, - 0xdeb9a1676f18b9b9ULL, 0x4c13985f268b1313ULL, 0xb02c7d9c58512c2cULL, 0x6bd3d6b8bb05d3d3ULL, - 0xbbe76b5cd38ce7e7ULL, 0xa56e57cbdc396e6eULL, 0x37c46ef395aac4c4ULL, 0x0c03180f061b0303ULL, - 0x45568a13acdc5656ULL, 0x0d441a49885e4444ULL, 0xe17fdf9efea07f7fULL, 0x9ea921374f88a9a9ULL, - 0xa82a4d8254672a2aULL, 0xd6bbb16d6b0abbbbULL, 0x23c146e29f87c1c1ULL, 0x5153a202a6f15353ULL, - 0x57dcae8ba572dcdcULL, 0x2c0b582716530b0bULL, 0x4e9d9cd327019d9dULL, 0xad6c47c1d82b6c6cULL, - 0xc43195f562a43131ULL, 0xcd7487b9e8f37474ULL, 0xfff6e309f115f6f6ULL, 0x05460a438c4c4646ULL, - 0x8aac092645a5acacULL, 0x1e893c970fb58989ULL, 0x5014a04428b41414ULL, 0xa3e15b42dfbae1e1ULL, - 0x5816b04e2ca61616ULL, 0xe83acdd274f73a3aULL, 0xb9696fd0d2066969ULL, 0x2409482d12410909ULL, - 0xdd70a7ade0d77070ULL, 0xe2b6d954716fb6b6ULL, 0x67d0ceb7bd1ed0d0ULL, 0x93ed3b7ec7d6ededULL, - 0x17cc2edb85e2ccccULL, 0x15422a5784684242ULL, 0x5a98b4c22d2c9898ULL, 0xaaa4490e55eda4a4ULL, - 0xa0285d8850752828ULL, 0x6d5cda31b8865c5cULL, 0xc7f8933fed6bf8f8ULL, 0x228644a411c28686ULL, - }; - - const nzUInt64 C7[256] = { - 0x186018c07830d818ULL, 0x238c2305af462623ULL, 0xc63fc67ef991b8c6ULL, 0xe887e8136fcdfbe8ULL, - 0x8726874ca113cb87ULL, 0xb8dab8a9626d11b8ULL, 0x0104010805020901ULL, 0x4f214f426e9e0d4fULL, - 0x36d836adee6c9b36ULL, 0xa6a2a6590451ffa6ULL, 0xd26fd2debdb90cd2ULL, 0xf5f3f5fb06f70ef5ULL, - 0x79f979ef80f29679ULL, 0x6fa16f5fcede306fULL, 0x917e91fcef3f6d91ULL, 0x525552aa07a4f852ULL, - 0x609d6027fdc04760ULL, 0xbccabc89766535bcULL, 0x9b569baccd2b379bULL, 0x8e028e048c018a8eULL, - 0xa3b6a371155bd2a3ULL, 0x0c300c603c186c0cULL, 0x7bf17bff8af6847bULL, 0x35d435b5e16a8035ULL, - 0x1d741de8693af51dULL, 0xe0a7e05347ddb3e0ULL, 0xd77bd7f6acb321d7ULL, 0xc22fc25eed999cc2ULL, - 0x2eb82e6d965c432eULL, 0x4b314b627a96294bULL, 0xfedffea321e15dfeULL, 0x5741578216aed557ULL, - 0x155415a8412abd15ULL, 0x77c1779fb6eee877ULL, 0x37dc37a5eb6e9237ULL, 0xe5b3e57b56d79ee5ULL, - 0x9f469f8cd923139fULL, 0xf0e7f0d317fd23f0ULL, 0x4a354a6a7f94204aULL, 0xda4fda9e95a944daULL, - 0x587d58fa25b0a258ULL, 0xc903c906ca8fcfc9ULL, 0x29a429558d527c29ULL, 0x0a280a5022145a0aULL, - 0xb1feb1e14f7f50b1ULL, 0xa0baa0691a5dc9a0ULL, 0x6bb16b7fdad6146bULL, 0x852e855cab17d985ULL, - 0xbdcebd8173673cbdULL, 0x5d695dd234ba8f5dULL, 0x1040108050209010ULL, 0xf4f7f4f303f507f4ULL, - 0xcb0bcb16c08bddcbULL, 0x3ef83eedc67cd33eULL, 0x05140528110a2d05ULL, 0x6781671fe6ce7867ULL, - 0xe4b7e47353d597e4ULL, 0x279c2725bb4e0227ULL, 0x4119413258827341ULL, 0x8b168b2c9d0ba78bULL, - 0xa7a6a7510153f6a7ULL, 0x7de97dcf94fab27dULL, 0x956e95dcfb374995ULL, 0xd847d88e9fad56d8ULL, - 0xfbcbfb8b30eb70fbULL, 0xee9fee2371c1cdeeULL, 0x7ced7cc791f8bb7cULL, 0x66856617e3cc7166ULL, - 0xdd53dda68ea77bddULL, 0x175c17b84b2eaf17ULL, 0x47014702468e4547ULL, 0x9e429e84dc211a9eULL, - 0xca0fca1ec589d4caULL, 0x2db42d75995a582dULL, 0xbfc6bf9179632ebfULL, 0x071c07381b0e3f07ULL, - 0xad8ead012347acadULL, 0x5a755aea2fb4b05aULL, 0x8336836cb51bef83ULL, 0x33cc3385ff66b633ULL, - 0x6391633ff2c65c63ULL, 0x020802100a041202ULL, 0xaa92aa39384993aaULL, 0x71d971afa8e2de71ULL, - 0xc807c80ecf8dc6c8ULL, 0x196419c87d32d119ULL, 0x4939497270923b49ULL, 0xd943d9869aaf5fd9ULL, - 0xf2eff2c31df931f2ULL, 0xe3abe34b48dba8e3ULL, 0x5b715be22ab6b95bULL, 0x881a8834920dbc88ULL, - 0x9a529aa4c8293e9aULL, 0x2698262dbe4c0b26ULL, 0x32c8328dfa64bf32ULL, 0xb0fab0e94a7d59b0ULL, - 0xe983e91b6acff2e9ULL, 0x0f3c0f78331e770fULL, 0xd573d5e6a6b733d5ULL, 0x803a8074ba1df480ULL, - 0xbec2be997c6127beULL, 0xcd13cd26de87ebcdULL, 0x34d034bde4688934ULL, 0x483d487a75903248ULL, - 0xffdbffab24e354ffULL, 0x7af57af78ff48d7aULL, 0x907a90f4ea3d6490ULL, 0x5f615fc23ebe9d5fULL, - 0x2080201da0403d20ULL, 0x68bd6867d5d00f68ULL, 0x1a681ad07234ca1aULL, 0xae82ae192c41b7aeULL, - 0xb4eab4c95e757db4ULL, 0x544d549a19a8ce54ULL, 0x937693ece53b7f93ULL, 0x2288220daa442f22ULL, - 0x648d6407e9c86364ULL, 0xf1e3f1db12ff2af1ULL, 0x73d173bfa2e6cc73ULL, 0x124812905a248212ULL, - 0x401d403a5d807a40ULL, 0x0820084028104808ULL, 0xc32bc356e89b95c3ULL, 0xec97ec337bc5dfecULL, - 0xdb4bdb9690ab4ddbULL, 0xa1bea1611f5fc0a1ULL, 0x8d0e8d1c8307918dULL, 0x3df43df5c97ac83dULL, - 0x976697ccf1335b97ULL, 0x0000000000000000ULL, 0xcf1bcf36d483f9cfULL, 0x2bac2b4587566e2bULL, - 0x76c57697b3ece176ULL, 0x82328264b019e682ULL, 0xd67fd6fea9b128d6ULL, 0x1b6c1bd87736c31bULL, - 0xb5eeb5c15b7774b5ULL, 0xaf86af112943beafULL, 0x6ab56a77dfd41d6aULL, 0x505d50ba0da0ea50ULL, - 0x450945124c8a5745ULL, 0xf3ebf3cb18fb38f3ULL, 0x30c0309df060ad30ULL, 0xef9bef2b74c3c4efULL, - 0x3ffc3fe5c37eda3fULL, 0x554955921caac755ULL, 0xa2b2a2791059dba2ULL, 0xea8fea0365c9e9eaULL, - 0x6589650fecca6a65ULL, 0xbad2bab9686903baULL, 0x2fbc2f65935e4a2fULL, 0xc027c04ee79d8ec0ULL, - 0xde5fdebe81a160deULL, 0x1c701ce06c38fc1cULL, 0xfdd3fdbb2ee746fdULL, 0x4d294d52649a1f4dULL, - 0x927292e4e0397692ULL, 0x75c9758fbceafa75ULL, 0x061806301e0c3606ULL, 0x8a128a249809ae8aULL, - 0xb2f2b2f940794bb2ULL, 0xe6bfe66359d185e6ULL, 0x0e380e70361c7e0eULL, 0x1f7c1ff8633ee71fULL, - 0x62956237f7c45562ULL, 0xd477d4eea3b53ad4ULL, 0xa89aa829324d81a8ULL, 0x966296c4f4315296ULL, - 0xf9c3f99b3aef62f9ULL, 0xc533c566f697a3c5ULL, 0x25942535b14a1025ULL, 0x597959f220b2ab59ULL, - 0x842a8454ae15d084ULL, 0x72d572b7a7e4c572ULL, 0x39e439d5dd72ec39ULL, 0x4c2d4c5a6198164cULL, - 0x5e655eca3bbc945eULL, 0x78fd78e785f09f78ULL, 0x38e038ddd870e538ULL, 0x8c0a8c148605988cULL, - 0xd163d1c6b2bf17d1ULL, 0xa5aea5410b57e4a5ULL, 0xe2afe2434dd9a1e2ULL, 0x6199612ff8c24e61ULL, - 0xb3f6b3f1457b42b3ULL, 0x21842115a5423421ULL, 0x9c4a9c94d625089cULL, 0x1e781ef0663cee1eULL, - 0x4311432252866143ULL, 0xc73bc776fc93b1c7ULL, 0xfcd7fcb32be54ffcULL, 0x0410042014082404ULL, - 0x515951b208a2e351ULL, 0x995e99bcc72f2599ULL, 0x6da96d4fc4da226dULL, 0x0d340d68391a650dULL, - 0xfacffa8335e979faULL, 0xdf5bdfb684a369dfULL, 0x7ee57ed79bfca97eULL, 0x2490243db4481924ULL, - 0x3bec3bc5d776fe3bULL, 0xab96ab313d4b9aabULL, 0xce1fce3ed181f0ceULL, 0x1144118855229911ULL, - 0x8f068f0c8903838fULL, 0x4e254e4a6b9c044eULL, 0xb7e6b7d1517366b7ULL, 0xeb8beb0b60cbe0ebULL, - 0x3cf03cfdcc78c13cULL, 0x813e817cbf1ffd81ULL, 0x946a94d4fe354094ULL, 0xf7fbf7eb0cf31cf7ULL, - 0xb9deb9a1676f18b9ULL, 0x134c13985f268b13ULL, 0x2cb02c7d9c58512cULL, 0xd36bd3d6b8bb05d3ULL, - 0xe7bbe76b5cd38ce7ULL, 0x6ea56e57cbdc396eULL, 0xc437c46ef395aac4ULL, 0x030c03180f061b03ULL, - 0x5645568a13acdc56ULL, 0x440d441a49885e44ULL, 0x7fe17fdf9efea07fULL, 0xa99ea921374f88a9ULL, - 0x2aa82a4d8254672aULL, 0xbbd6bbb16d6b0abbULL, 0xc123c146e29f87c1ULL, 0x535153a202a6f153ULL, - 0xdc57dcae8ba572dcULL, 0x0b2c0b582716530bULL, 0x9d4e9d9cd327019dULL, 0x6cad6c47c1d82b6cULL, - 0x31c43195f562a431ULL, 0x74cd7487b9e8f374ULL, 0xf6fff6e309f115f6ULL, 0x4605460a438c4c46ULL, - 0xac8aac092645a5acULL, 0x891e893c970fb589ULL, 0x145014a04428b414ULL, 0xe1a3e15b42dfbae1ULL, - 0x165816b04e2ca616ULL, 0x3ae83acdd274f73aULL, 0x69b9696fd0d20669ULL, 0x092409482d124109ULL, - 0x70dd70a7ade0d770ULL, 0xb6e2b6d954716fb6ULL, 0xd067d0ceb7bd1ed0ULL, 0xed93ed3b7ec7d6edULL, - 0xcc17cc2edb85e2ccULL, 0x4215422a57846842ULL, 0x985a98b4c22d2c98ULL, 0xa4aaa4490e55eda4ULL, - 0x28a0285d88507528ULL, 0x5c6d5cda31b8865cULL, 0xf8c7f8933fed6bf8ULL, 0x86228644a411c286ULL, - }; - - const nzUInt64 rc[R + 1] = { - 0x0000000000000000ULL, - 0x1823c6e887b8014fULL, - 0x36a6d2f5796f9152ULL, - 0x60bc9b8ea30c7b35ULL, - 0x1de0d7c22e4bfe57ULL, - 0x157737e59ff04adaULL, - 0x58c9290ab1a06b85ULL, - 0xbd5d10f4cb3e0567ULL, - 0xe427418ba77d95d8ULL, - 0xfbee7c66dd17479eULL, - 0xca2dbf07ad5a8333ULL, - }; - - void processBuffer(NzHashWhirlpool_state* wstate) + struct HashWhirlpool_state { - int i, r; - nzUInt64 K[8]; // the round key - nzUInt64 block[8]; // mu(buffer) - nzUInt64 state[8]; // the cipher state - nzUInt64 L[8]; - nzUInt8 *buffer = wstate->buffer; + int bufferBits; // current number of bits on the buffer */ + int bufferPos; // current (possibly incomplete) byte slot on the buffer */ + UInt8 bitLength[32]; // global number of hashed bits (256-bit counter) */ + UInt8 buffer[64]; // buffer of data to hash */ + UInt64 hash[8]; // the hashing state */ + }; - // map the buffer to a block - for (i = 0; i < 8; i++, buffer += 8) - { - block[i] = - ((static_cast(buffer[0]) ) << 56) ^ - ((static_cast(buffer[1]) & 0xffL) << 48) ^ - ((static_cast(buffer[2]) & 0xffL) << 40) ^ - ((static_cast(buffer[3]) & 0xffL) << 32) ^ - ((static_cast(buffer[4]) & 0xffL) << 24) ^ - ((static_cast(buffer[5]) & 0xffL) << 16) ^ - ((static_cast(buffer[6]) & 0xffL) << 8) ^ - ((static_cast(buffer[7]) & 0xffL) ); - } - - // compute and apply K^0 to the cipher state - state[0] = block[0] ^ (K[0] = wstate->hash[0]); - state[1] = block[1] ^ (K[1] = wstate->hash[1]); - state[2] = block[2] ^ (K[2] = wstate->hash[2]); - state[3] = block[3] ^ (K[3] = wstate->hash[3]); - state[4] = block[4] ^ (K[4] = wstate->hash[4]); - state[5] = block[5] ^ (K[5] = wstate->hash[5]); - state[6] = block[6] ^ (K[6] = wstate->hash[6]); - state[7] = block[7] ^ (K[7] = wstate->hash[7]); - - // iterate over all rounds - for (r = 1; r <= R; r++) - { - // compute K^r from K^{r-1} - L[0] = - C0[static_cast(K[0] >> 56) ] ^ - C1[static_cast(K[7] >> 48) & 0xff] ^ - C2[static_cast(K[6] >> 40) & 0xff] ^ - C3[static_cast(K[5] >> 32) & 0xff] ^ - C4[static_cast(K[4] >> 24) & 0xff] ^ - C5[static_cast(K[3] >> 16) & 0xff] ^ - C6[static_cast(K[2] >> 8) & 0xff] ^ - C7[static_cast(K[1] ) & 0xff] ^ - rc[r]; - L[1] = - C0[static_cast(K[1] >> 56) ] ^ - C1[static_cast(K[0] >> 48) & 0xff] ^ - C2[static_cast(K[7] >> 40) & 0xff] ^ - C3[static_cast(K[6] >> 32) & 0xff] ^ - C4[static_cast(K[5] >> 24) & 0xff] ^ - C5[static_cast(K[4] >> 16) & 0xff] ^ - C6[static_cast(K[3] >> 8) & 0xff] ^ - C7[static_cast(K[2] ) & 0xff]; - L[2] = - C0[static_cast(K[2] >> 56) ] ^ - C1[static_cast(K[1] >> 48) & 0xff] ^ - C2[static_cast(K[0] >> 40) & 0xff] ^ - C3[static_cast(K[7] >> 32) & 0xff] ^ - C4[static_cast(K[6] >> 24) & 0xff] ^ - C5[static_cast(K[5] >> 16) & 0xff] ^ - C6[static_cast(K[4] >> 8) & 0xff] ^ - C7[static_cast(K[3] ) & 0xff]; - L[3] = - C0[static_cast(K[3] >> 56) ] ^ - C1[static_cast(K[2] >> 48) & 0xff] ^ - C2[static_cast(K[1] >> 40) & 0xff] ^ - C3[static_cast(K[0] >> 32) & 0xff] ^ - C4[static_cast(K[7] >> 24) & 0xff] ^ - C5[static_cast(K[6] >> 16) & 0xff] ^ - C6[static_cast(K[5] >> 8) & 0xff] ^ - C7[static_cast(K[4] ) & 0xff]; - L[4] = - C0[static_cast(K[4] >> 56) ] ^ - C1[static_cast(K[3] >> 48) & 0xff] ^ - C2[static_cast(K[2] >> 40) & 0xff] ^ - C3[static_cast(K[1] >> 32) & 0xff] ^ - C4[static_cast(K[0] >> 24) & 0xff] ^ - C5[static_cast(K[7] >> 16) & 0xff] ^ - C6[static_cast(K[6] >> 8) & 0xff] ^ - C7[static_cast(K[5] ) & 0xff]; - L[5] = - C0[static_cast(K[5] >> 56) ] ^ - C1[static_cast(K[4] >> 48) & 0xff] ^ - C2[static_cast(K[3] >> 40) & 0xff] ^ - C3[static_cast(K[2] >> 32) & 0xff] ^ - C4[static_cast(K[1] >> 24) & 0xff] ^ - C5[static_cast(K[0] >> 16) & 0xff] ^ - C6[static_cast(K[7] >> 8) & 0xff] ^ - C7[static_cast(K[6] ) & 0xff]; - L[6] = - C0[static_cast(K[6] >> 56) ] ^ - C1[static_cast(K[5] >> 48) & 0xff] ^ - C2[static_cast(K[4] >> 40) & 0xff] ^ - C3[static_cast(K[3] >> 32) & 0xff] ^ - C4[static_cast(K[2] >> 24) & 0xff] ^ - C5[static_cast(K[1] >> 16) & 0xff] ^ - C6[static_cast(K[0] >> 8) & 0xff] ^ - C7[static_cast(K[7] ) & 0xff]; - L[7] = - C0[static_cast(K[7] >> 56) ] ^ - C1[static_cast(K[6] >> 48) & 0xff] ^ - C2[static_cast(K[5] >> 40) & 0xff] ^ - C3[static_cast(K[4] >> 32) & 0xff] ^ - C4[static_cast(K[3] >> 24) & 0xff] ^ - C5[static_cast(K[2] >> 16) & 0xff] ^ - C6[static_cast(K[1] >> 8) & 0xff] ^ - C7[static_cast(K[0] ) & 0xff]; - K[0] = L[0]; - K[1] = L[1]; - K[2] = L[2]; - K[3] = L[3]; - K[4] = L[4]; - K[5] = L[5]; - K[6] = L[6]; - K[7] = L[7]; - - // apply the r-th round transformation - L[0] = - C0[static_cast(state[0] >> 56) ] ^ - C1[static_cast(state[7] >> 48) & 0xff] ^ - C2[static_cast(state[6] >> 40) & 0xff] ^ - C3[static_cast(state[5] >> 32) & 0xff] ^ - C4[static_cast(state[4] >> 24) & 0xff] ^ - C5[static_cast(state[3] >> 16) & 0xff] ^ - C6[static_cast(state[2] >> 8) & 0xff] ^ - C7[static_cast(state[1] ) & 0xff] ^ - K[0]; - L[1] = - C0[static_cast(state[1] >> 56) ] ^ - C1[static_cast(state[0] >> 48) & 0xff] ^ - C2[static_cast(state[7] >> 40) & 0xff] ^ - C3[static_cast(state[6] >> 32) & 0xff] ^ - C4[static_cast(state[5] >> 24) & 0xff] ^ - C5[static_cast(state[4] >> 16) & 0xff] ^ - C6[static_cast(state[3] >> 8) & 0xff] ^ - C7[static_cast(state[2] ) & 0xff] ^ - K[1]; - L[2] = - C0[static_cast(state[2] >> 56) ] ^ - C1[static_cast(state[1] >> 48) & 0xff] ^ - C2[static_cast(state[0] >> 40) & 0xff] ^ - C3[static_cast(state[7] >> 32) & 0xff] ^ - C4[static_cast(state[6] >> 24) & 0xff] ^ - C5[static_cast(state[5] >> 16) & 0xff] ^ - C6[static_cast(state[4] >> 8) & 0xff] ^ - C7[static_cast(state[3] ) & 0xff] ^ - K[2]; - L[3] = - C0[static_cast(state[3] >> 56) ] ^ - C1[static_cast(state[2] >> 48) & 0xff] ^ - C2[static_cast(state[1] >> 40) & 0xff] ^ - C3[static_cast(state[0] >> 32) & 0xff] ^ - C4[static_cast(state[7] >> 24) & 0xff] ^ - C5[static_cast(state[6] >> 16) & 0xff] ^ - C6[static_cast(state[5] >> 8) & 0xff] ^ - C7[static_cast(state[4] ) & 0xff] ^ - K[3]; - L[4] = - C0[static_cast(state[4] >> 56) ] ^ - C1[static_cast(state[3] >> 48) & 0xff] ^ - C2[static_cast(state[2] >> 40) & 0xff] ^ - C3[static_cast(state[1] >> 32) & 0xff] ^ - C4[static_cast(state[0] >> 24) & 0xff] ^ - C5[static_cast(state[7] >> 16) & 0xff] ^ - C6[static_cast(state[6] >> 8) & 0xff] ^ - C7[static_cast(state[5] ) & 0xff] ^ - K[4]; - L[5] = - C0[static_cast(state[5] >> 56) ] ^ - C1[static_cast(state[4] >> 48) & 0xff] ^ - C2[static_cast(state[3] >> 40) & 0xff] ^ - C3[static_cast(state[2] >> 32) & 0xff] ^ - C4[static_cast(state[1] >> 24) & 0xff] ^ - C5[static_cast(state[0] >> 16) & 0xff] ^ - C6[static_cast(state[7] >> 8) & 0xff] ^ - C7[static_cast(state[6] ) & 0xff] ^ - K[5]; - L[6] = - C0[static_cast(state[6] >> 56) ] ^ - C1[static_cast(state[5] >> 48) & 0xff] ^ - C2[static_cast(state[4] >> 40) & 0xff] ^ - C3[static_cast(state[3] >> 32) & 0xff] ^ - C4[static_cast(state[2] >> 24) & 0xff] ^ - C5[static_cast(state[1] >> 16) & 0xff] ^ - C6[static_cast(state[0] >> 8) & 0xff] ^ - C7[static_cast(state[7] ) & 0xff] ^ - K[6]; - L[7] = - C0[static_cast(state[7] >> 56) ] ^ - C1[static_cast(state[6] >> 48) & 0xff] ^ - C2[static_cast(state[5] >> 40) & 0xff] ^ - C3[static_cast(state[4] >> 32) & 0xff] ^ - C4[static_cast(state[3] >> 24) & 0xff] ^ - C5[static_cast(state[2] >> 16) & 0xff] ^ - C6[static_cast(state[1] >> 8) & 0xff] ^ - C7[static_cast(state[0] ) & 0xff] ^ - K[7]; - state[0] = L[0]; - state[1] = L[1]; - state[2] = L[2]; - state[3] = L[3]; - state[4] = L[4]; - state[5] = L[5]; - state[6] = L[6]; - state[7] = L[7]; - } - - // apply the Miyaguchi-Preneel compression function - wstate->hash[0] ^= state[0] ^ block[0]; - wstate->hash[1] ^= state[1] ^ block[1]; - wstate->hash[2] ^= state[2] ^ block[2]; - wstate->hash[3] ^= state[3] ^ block[3]; - wstate->hash[4] ^= state[4] ^ block[4]; - wstate->hash[5] ^= state[5] ^ block[5]; - wstate->hash[6] ^= state[6] ^ block[6]; - wstate->hash[7] ^= state[7] ^ block[7]; - } -} - -NzHashWhirlpool::NzHashWhirlpool() -{ - m_state = new NzHashWhirlpool_state; -} - -NzHashWhirlpool::~NzHashWhirlpool() -{ - delete m_state; -} - -void NzHashWhirlpool::Append(const nzUInt8* data, unsigned int len) -{ - len *= 8; // Whirlpool fonctionne avec une taille en bits - - int sourcePos = 0; /* index of leftmost source nzUInt8 containing data (1 to 8 bits). */ - int sourceGap = (8 - (static_cast(len) & 7)) & 7; /* space on source[sourcePos]. */ - int bufferRem = m_state->bufferBits & 7; /* occupied bits on buffer[bufferPos]. */ - - nzUInt32 b; - nzUInt8* buffer = m_state->buffer; - nzUInt8* bitLength = m_state->bitLength; - int bufferBits = m_state->bufferBits; - int bufferPos = m_state->bufferPos; - - // tally the length of the added data - nzUInt64 value = len; - nzUInt32 carry = 0; - for (int i = 31; i >= 0 && (carry != 0 || value != 0ULL); i--) + namespace { - carry += bitLength[i] + (static_cast(value) & 0xff); - bitLength[i] = static_cast(carry); + const UInt64 C0[256] = { + 0x18186018c07830d8ULL, 0x23238c2305af4626ULL, 0xc6c63fc67ef991b8ULL, 0xe8e887e8136fcdfbULL, + 0x878726874ca113cbULL, 0xb8b8dab8a9626d11ULL, 0x0101040108050209ULL, 0x4f4f214f426e9e0dULL, + 0x3636d836adee6c9bULL, 0xa6a6a2a6590451ffULL, 0xd2d26fd2debdb90cULL, 0xf5f5f3f5fb06f70eULL, + 0x7979f979ef80f296ULL, 0x6f6fa16f5fcede30ULL, 0x91917e91fcef3f6dULL, 0x52525552aa07a4f8ULL, + 0x60609d6027fdc047ULL, 0xbcbccabc89766535ULL, 0x9b9b569baccd2b37ULL, 0x8e8e028e048c018aULL, + 0xa3a3b6a371155bd2ULL, 0x0c0c300c603c186cULL, 0x7b7bf17bff8af684ULL, 0x3535d435b5e16a80ULL, + 0x1d1d741de8693af5ULL, 0xe0e0a7e05347ddb3ULL, 0xd7d77bd7f6acb321ULL, 0xc2c22fc25eed999cULL, + 0x2e2eb82e6d965c43ULL, 0x4b4b314b627a9629ULL, 0xfefedffea321e15dULL, 0x575741578216aed5ULL, + 0x15155415a8412abdULL, 0x7777c1779fb6eee8ULL, 0x3737dc37a5eb6e92ULL, 0xe5e5b3e57b56d79eULL, + 0x9f9f469f8cd92313ULL, 0xf0f0e7f0d317fd23ULL, 0x4a4a354a6a7f9420ULL, 0xdada4fda9e95a944ULL, + 0x58587d58fa25b0a2ULL, 0xc9c903c906ca8fcfULL, 0x2929a429558d527cULL, 0x0a0a280a5022145aULL, + 0xb1b1feb1e14f7f50ULL, 0xa0a0baa0691a5dc9ULL, 0x6b6bb16b7fdad614ULL, 0x85852e855cab17d9ULL, + 0xbdbdcebd8173673cULL, 0x5d5d695dd234ba8fULL, 0x1010401080502090ULL, 0xf4f4f7f4f303f507ULL, + 0xcbcb0bcb16c08bddULL, 0x3e3ef83eedc67cd3ULL, 0x0505140528110a2dULL, 0x676781671fe6ce78ULL, + 0xe4e4b7e47353d597ULL, 0x27279c2725bb4e02ULL, 0x4141194132588273ULL, 0x8b8b168b2c9d0ba7ULL, + 0xa7a7a6a7510153f6ULL, 0x7d7de97dcf94fab2ULL, 0x95956e95dcfb3749ULL, 0xd8d847d88e9fad56ULL, + 0xfbfbcbfb8b30eb70ULL, 0xeeee9fee2371c1cdULL, 0x7c7ced7cc791f8bbULL, 0x6666856617e3cc71ULL, + 0xdddd53dda68ea77bULL, 0x17175c17b84b2eafULL, 0x4747014702468e45ULL, 0x9e9e429e84dc211aULL, + 0xcaca0fca1ec589d4ULL, 0x2d2db42d75995a58ULL, 0xbfbfc6bf9179632eULL, 0x07071c07381b0e3fULL, + 0xadad8ead012347acULL, 0x5a5a755aea2fb4b0ULL, 0x838336836cb51befULL, 0x3333cc3385ff66b6ULL, + 0x636391633ff2c65cULL, 0x02020802100a0412ULL, 0xaaaa92aa39384993ULL, 0x7171d971afa8e2deULL, + 0xc8c807c80ecf8dc6ULL, 0x19196419c87d32d1ULL, 0x494939497270923bULL, 0xd9d943d9869aaf5fULL, + 0xf2f2eff2c31df931ULL, 0xe3e3abe34b48dba8ULL, 0x5b5b715be22ab6b9ULL, 0x88881a8834920dbcULL, + 0x9a9a529aa4c8293eULL, 0x262698262dbe4c0bULL, 0x3232c8328dfa64bfULL, 0xb0b0fab0e94a7d59ULL, + 0xe9e983e91b6acff2ULL, 0x0f0f3c0f78331e77ULL, 0xd5d573d5e6a6b733ULL, 0x80803a8074ba1df4ULL, + 0xbebec2be997c6127ULL, 0xcdcd13cd26de87ebULL, 0x3434d034bde46889ULL, 0x48483d487a759032ULL, + 0xffffdbffab24e354ULL, 0x7a7af57af78ff48dULL, 0x90907a90f4ea3d64ULL, 0x5f5f615fc23ebe9dULL, + 0x202080201da0403dULL, 0x6868bd6867d5d00fULL, 0x1a1a681ad07234caULL, 0xaeae82ae192c41b7ULL, + 0xb4b4eab4c95e757dULL, 0x54544d549a19a8ceULL, 0x93937693ece53b7fULL, 0x222288220daa442fULL, + 0x64648d6407e9c863ULL, 0xf1f1e3f1db12ff2aULL, 0x7373d173bfa2e6ccULL, 0x12124812905a2482ULL, + 0x40401d403a5d807aULL, 0x0808200840281048ULL, 0xc3c32bc356e89b95ULL, 0xecec97ec337bc5dfULL, + 0xdbdb4bdb9690ab4dULL, 0xa1a1bea1611f5fc0ULL, 0x8d8d0e8d1c830791ULL, 0x3d3df43df5c97ac8ULL, + 0x97976697ccf1335bULL, 0x0000000000000000ULL, 0xcfcf1bcf36d483f9ULL, 0x2b2bac2b4587566eULL, + 0x7676c57697b3ece1ULL, 0x8282328264b019e6ULL, 0xd6d67fd6fea9b128ULL, 0x1b1b6c1bd87736c3ULL, + 0xb5b5eeb5c15b7774ULL, 0xafaf86af112943beULL, 0x6a6ab56a77dfd41dULL, 0x50505d50ba0da0eaULL, + 0x45450945124c8a57ULL, 0xf3f3ebf3cb18fb38ULL, 0x3030c0309df060adULL, 0xefef9bef2b74c3c4ULL, + 0x3f3ffc3fe5c37edaULL, 0x55554955921caac7ULL, 0xa2a2b2a2791059dbULL, 0xeaea8fea0365c9e9ULL, + 0x656589650fecca6aULL, 0xbabad2bab9686903ULL, 0x2f2fbc2f65935e4aULL, 0xc0c027c04ee79d8eULL, + 0xdede5fdebe81a160ULL, 0x1c1c701ce06c38fcULL, 0xfdfdd3fdbb2ee746ULL, 0x4d4d294d52649a1fULL, + 0x92927292e4e03976ULL, 0x7575c9758fbceafaULL, 0x06061806301e0c36ULL, 0x8a8a128a249809aeULL, + 0xb2b2f2b2f940794bULL, 0xe6e6bfe66359d185ULL, 0x0e0e380e70361c7eULL, 0x1f1f7c1ff8633ee7ULL, + 0x6262956237f7c455ULL, 0xd4d477d4eea3b53aULL, 0xa8a89aa829324d81ULL, 0x96966296c4f43152ULL, + 0xf9f9c3f99b3aef62ULL, 0xc5c533c566f697a3ULL, 0x2525942535b14a10ULL, 0x59597959f220b2abULL, + 0x84842a8454ae15d0ULL, 0x7272d572b7a7e4c5ULL, 0x3939e439d5dd72ecULL, 0x4c4c2d4c5a619816ULL, + 0x5e5e655eca3bbc94ULL, 0x7878fd78e785f09fULL, 0x3838e038ddd870e5ULL, 0x8c8c0a8c14860598ULL, + 0xd1d163d1c6b2bf17ULL, 0xa5a5aea5410b57e4ULL, 0xe2e2afe2434dd9a1ULL, 0x616199612ff8c24eULL, + 0xb3b3f6b3f1457b42ULL, 0x2121842115a54234ULL, 0x9c9c4a9c94d62508ULL, 0x1e1e781ef0663ceeULL, + 0x4343114322528661ULL, 0xc7c73bc776fc93b1ULL, 0xfcfcd7fcb32be54fULL, 0x0404100420140824ULL, + 0x51515951b208a2e3ULL, 0x99995e99bcc72f25ULL, 0x6d6da96d4fc4da22ULL, 0x0d0d340d68391a65ULL, + 0xfafacffa8335e979ULL, 0xdfdf5bdfb684a369ULL, 0x7e7ee57ed79bfca9ULL, 0x242490243db44819ULL, + 0x3b3bec3bc5d776feULL, 0xabab96ab313d4b9aULL, 0xcece1fce3ed181f0ULL, 0x1111441188552299ULL, + 0x8f8f068f0c890383ULL, 0x4e4e254e4a6b9c04ULL, 0xb7b7e6b7d1517366ULL, 0xebeb8beb0b60cbe0ULL, + 0x3c3cf03cfdcc78c1ULL, 0x81813e817cbf1ffdULL, 0x94946a94d4fe3540ULL, 0xf7f7fbf7eb0cf31cULL, + 0xb9b9deb9a1676f18ULL, 0x13134c13985f268bULL, 0x2c2cb02c7d9c5851ULL, 0xd3d36bd3d6b8bb05ULL, + 0xe7e7bbe76b5cd38cULL, 0x6e6ea56e57cbdc39ULL, 0xc4c437c46ef395aaULL, 0x03030c03180f061bULL, + 0x565645568a13acdcULL, 0x44440d441a49885eULL, 0x7f7fe17fdf9efea0ULL, 0xa9a99ea921374f88ULL, + 0x2a2aa82a4d825467ULL, 0xbbbbd6bbb16d6b0aULL, 0xc1c123c146e29f87ULL, 0x53535153a202a6f1ULL, + 0xdcdc57dcae8ba572ULL, 0x0b0b2c0b58271653ULL, 0x9d9d4e9d9cd32701ULL, 0x6c6cad6c47c1d82bULL, + 0x3131c43195f562a4ULL, 0x7474cd7487b9e8f3ULL, 0xf6f6fff6e309f115ULL, 0x464605460a438c4cULL, + 0xacac8aac092645a5ULL, 0x89891e893c970fb5ULL, 0x14145014a04428b4ULL, 0xe1e1a3e15b42dfbaULL, + 0x16165816b04e2ca6ULL, 0x3a3ae83acdd274f7ULL, 0x6969b9696fd0d206ULL, 0x09092409482d1241ULL, + 0x7070dd70a7ade0d7ULL, 0xb6b6e2b6d954716fULL, 0xd0d067d0ceb7bd1eULL, 0xeded93ed3b7ec7d6ULL, + 0xcccc17cc2edb85e2ULL, 0x424215422a578468ULL, 0x98985a98b4c22d2cULL, 0xa4a4aaa4490e55edULL, + 0x2828a0285d885075ULL, 0x5c5c6d5cda31b886ULL, 0xf8f8c7f8933fed6bULL, 0x8686228644a411c2ULL, + }; - carry >>= 8; - value >>= 8; + const UInt64 C1[256] = { + 0xd818186018c07830ULL, 0x2623238c2305af46ULL, 0xb8c6c63fc67ef991ULL, 0xfbe8e887e8136fcdULL, + 0xcb878726874ca113ULL, 0x11b8b8dab8a9626dULL, 0x0901010401080502ULL, 0x0d4f4f214f426e9eULL, + 0x9b3636d836adee6cULL, 0xffa6a6a2a6590451ULL, 0x0cd2d26fd2debdb9ULL, 0x0ef5f5f3f5fb06f7ULL, + 0x967979f979ef80f2ULL, 0x306f6fa16f5fcedeULL, 0x6d91917e91fcef3fULL, 0xf852525552aa07a4ULL, + 0x4760609d6027fdc0ULL, 0x35bcbccabc897665ULL, 0x379b9b569baccd2bULL, 0x8a8e8e028e048c01ULL, + 0xd2a3a3b6a371155bULL, 0x6c0c0c300c603c18ULL, 0x847b7bf17bff8af6ULL, 0x803535d435b5e16aULL, + 0xf51d1d741de8693aULL, 0xb3e0e0a7e05347ddULL, 0x21d7d77bd7f6acb3ULL, 0x9cc2c22fc25eed99ULL, + 0x432e2eb82e6d965cULL, 0x294b4b314b627a96ULL, 0x5dfefedffea321e1ULL, 0xd5575741578216aeULL, + 0xbd15155415a8412aULL, 0xe87777c1779fb6eeULL, 0x923737dc37a5eb6eULL, 0x9ee5e5b3e57b56d7ULL, + 0x139f9f469f8cd923ULL, 0x23f0f0e7f0d317fdULL, 0x204a4a354a6a7f94ULL, 0x44dada4fda9e95a9ULL, + 0xa258587d58fa25b0ULL, 0xcfc9c903c906ca8fULL, 0x7c2929a429558d52ULL, 0x5a0a0a280a502214ULL, + 0x50b1b1feb1e14f7fULL, 0xc9a0a0baa0691a5dULL, 0x146b6bb16b7fdad6ULL, 0xd985852e855cab17ULL, + 0x3cbdbdcebd817367ULL, 0x8f5d5d695dd234baULL, 0x9010104010805020ULL, 0x07f4f4f7f4f303f5ULL, + 0xddcbcb0bcb16c08bULL, 0xd33e3ef83eedc67cULL, 0x2d0505140528110aULL, 0x78676781671fe6ceULL, + 0x97e4e4b7e47353d5ULL, 0x0227279c2725bb4eULL, 0x7341411941325882ULL, 0xa78b8b168b2c9d0bULL, + 0xf6a7a7a6a7510153ULL, 0xb27d7de97dcf94faULL, 0x4995956e95dcfb37ULL, 0x56d8d847d88e9fadULL, + 0x70fbfbcbfb8b30ebULL, 0xcdeeee9fee2371c1ULL, 0xbb7c7ced7cc791f8ULL, 0x716666856617e3ccULL, + 0x7bdddd53dda68ea7ULL, 0xaf17175c17b84b2eULL, 0x454747014702468eULL, 0x1a9e9e429e84dc21ULL, + 0xd4caca0fca1ec589ULL, 0x582d2db42d75995aULL, 0x2ebfbfc6bf917963ULL, 0x3f07071c07381b0eULL, + 0xacadad8ead012347ULL, 0xb05a5a755aea2fb4ULL, 0xef838336836cb51bULL, 0xb63333cc3385ff66ULL, + 0x5c636391633ff2c6ULL, 0x1202020802100a04ULL, 0x93aaaa92aa393849ULL, 0xde7171d971afa8e2ULL, + 0xc6c8c807c80ecf8dULL, 0xd119196419c87d32ULL, 0x3b49493949727092ULL, 0x5fd9d943d9869aafULL, + 0x31f2f2eff2c31df9ULL, 0xa8e3e3abe34b48dbULL, 0xb95b5b715be22ab6ULL, 0xbc88881a8834920dULL, + 0x3e9a9a529aa4c829ULL, 0x0b262698262dbe4cULL, 0xbf3232c8328dfa64ULL, 0x59b0b0fab0e94a7dULL, + 0xf2e9e983e91b6acfULL, 0x770f0f3c0f78331eULL, 0x33d5d573d5e6a6b7ULL, 0xf480803a8074ba1dULL, + 0x27bebec2be997c61ULL, 0xebcdcd13cd26de87ULL, 0x893434d034bde468ULL, 0x3248483d487a7590ULL, + 0x54ffffdbffab24e3ULL, 0x8d7a7af57af78ff4ULL, 0x6490907a90f4ea3dULL, 0x9d5f5f615fc23ebeULL, + 0x3d202080201da040ULL, 0x0f6868bd6867d5d0ULL, 0xca1a1a681ad07234ULL, 0xb7aeae82ae192c41ULL, + 0x7db4b4eab4c95e75ULL, 0xce54544d549a19a8ULL, 0x7f93937693ece53bULL, 0x2f222288220daa44ULL, + 0x6364648d6407e9c8ULL, 0x2af1f1e3f1db12ffULL, 0xcc7373d173bfa2e6ULL, 0x8212124812905a24ULL, + 0x7a40401d403a5d80ULL, 0x4808082008402810ULL, 0x95c3c32bc356e89bULL, 0xdfecec97ec337bc5ULL, + 0x4ddbdb4bdb9690abULL, 0xc0a1a1bea1611f5fULL, 0x918d8d0e8d1c8307ULL, 0xc83d3df43df5c97aULL, + 0x5b97976697ccf133ULL, 0x0000000000000000ULL, 0xf9cfcf1bcf36d483ULL, 0x6e2b2bac2b458756ULL, + 0xe17676c57697b3ecULL, 0xe68282328264b019ULL, 0x28d6d67fd6fea9b1ULL, 0xc31b1b6c1bd87736ULL, + 0x74b5b5eeb5c15b77ULL, 0xbeafaf86af112943ULL, 0x1d6a6ab56a77dfd4ULL, 0xea50505d50ba0da0ULL, + 0x5745450945124c8aULL, 0x38f3f3ebf3cb18fbULL, 0xad3030c0309df060ULL, 0xc4efef9bef2b74c3ULL, + 0xda3f3ffc3fe5c37eULL, 0xc755554955921caaULL, 0xdba2a2b2a2791059ULL, 0xe9eaea8fea0365c9ULL, + 0x6a656589650feccaULL, 0x03babad2bab96869ULL, 0x4a2f2fbc2f65935eULL, 0x8ec0c027c04ee79dULL, + 0x60dede5fdebe81a1ULL, 0xfc1c1c701ce06c38ULL, 0x46fdfdd3fdbb2ee7ULL, 0x1f4d4d294d52649aULL, + 0x7692927292e4e039ULL, 0xfa7575c9758fbceaULL, 0x3606061806301e0cULL, 0xae8a8a128a249809ULL, + 0x4bb2b2f2b2f94079ULL, 0x85e6e6bfe66359d1ULL, 0x7e0e0e380e70361cULL, 0xe71f1f7c1ff8633eULL, + 0x556262956237f7c4ULL, 0x3ad4d477d4eea3b5ULL, 0x81a8a89aa829324dULL, 0x5296966296c4f431ULL, + 0x62f9f9c3f99b3aefULL, 0xa3c5c533c566f697ULL, 0x102525942535b14aULL, 0xab59597959f220b2ULL, + 0xd084842a8454ae15ULL, 0xc57272d572b7a7e4ULL, 0xec3939e439d5dd72ULL, 0x164c4c2d4c5a6198ULL, + 0x945e5e655eca3bbcULL, 0x9f7878fd78e785f0ULL, 0xe53838e038ddd870ULL, 0x988c8c0a8c148605ULL, + 0x17d1d163d1c6b2bfULL, 0xe4a5a5aea5410b57ULL, 0xa1e2e2afe2434dd9ULL, 0x4e616199612ff8c2ULL, + 0x42b3b3f6b3f1457bULL, 0x342121842115a542ULL, 0x089c9c4a9c94d625ULL, 0xee1e1e781ef0663cULL, + 0x6143431143225286ULL, 0xb1c7c73bc776fc93ULL, 0x4ffcfcd7fcb32be5ULL, 0x2404041004201408ULL, + 0xe351515951b208a2ULL, 0x2599995e99bcc72fULL, 0x226d6da96d4fc4daULL, 0x650d0d340d68391aULL, + 0x79fafacffa8335e9ULL, 0x69dfdf5bdfb684a3ULL, 0xa97e7ee57ed79bfcULL, 0x19242490243db448ULL, + 0xfe3b3bec3bc5d776ULL, 0x9aabab96ab313d4bULL, 0xf0cece1fce3ed181ULL, 0x9911114411885522ULL, + 0x838f8f068f0c8903ULL, 0x044e4e254e4a6b9cULL, 0x66b7b7e6b7d15173ULL, 0xe0ebeb8beb0b60cbULL, + 0xc13c3cf03cfdcc78ULL, 0xfd81813e817cbf1fULL, 0x4094946a94d4fe35ULL, 0x1cf7f7fbf7eb0cf3ULL, + 0x18b9b9deb9a1676fULL, 0x8b13134c13985f26ULL, 0x512c2cb02c7d9c58ULL, 0x05d3d36bd3d6b8bbULL, + 0x8ce7e7bbe76b5cd3ULL, 0x396e6ea56e57cbdcULL, 0xaac4c437c46ef395ULL, 0x1b03030c03180f06ULL, + 0xdc565645568a13acULL, 0x5e44440d441a4988ULL, 0xa07f7fe17fdf9efeULL, 0x88a9a99ea921374fULL, + 0x672a2aa82a4d8254ULL, 0x0abbbbd6bbb16d6bULL, 0x87c1c123c146e29fULL, 0xf153535153a202a6ULL, + 0x72dcdc57dcae8ba5ULL, 0x530b0b2c0b582716ULL, 0x019d9d4e9d9cd327ULL, 0x2b6c6cad6c47c1d8ULL, + 0xa43131c43195f562ULL, 0xf37474cd7487b9e8ULL, 0x15f6f6fff6e309f1ULL, 0x4c464605460a438cULL, + 0xa5acac8aac092645ULL, 0xb589891e893c970fULL, 0xb414145014a04428ULL, 0xbae1e1a3e15b42dfULL, + 0xa616165816b04e2cULL, 0xf73a3ae83acdd274ULL, 0x066969b9696fd0d2ULL, 0x4109092409482d12ULL, + 0xd77070dd70a7ade0ULL, 0x6fb6b6e2b6d95471ULL, 0x1ed0d067d0ceb7bdULL, 0xd6eded93ed3b7ec7ULL, + 0xe2cccc17cc2edb85ULL, 0x68424215422a5784ULL, 0x2c98985a98b4c22dULL, 0xeda4a4aaa4490e55ULL, + 0x752828a0285d8850ULL, 0x865c5c6d5cda31b8ULL, 0x6bf8f8c7f8933fedULL, 0xc28686228644a411ULL, + }; + + const UInt64 C2[256] = { + 0x30d818186018c078ULL, 0x462623238c2305afULL, 0x91b8c6c63fc67ef9ULL, 0xcdfbe8e887e8136fULL, + 0x13cb878726874ca1ULL, 0x6d11b8b8dab8a962ULL, 0x0209010104010805ULL, 0x9e0d4f4f214f426eULL, + 0x6c9b3636d836adeeULL, 0x51ffa6a6a2a65904ULL, 0xb90cd2d26fd2debdULL, 0xf70ef5f5f3f5fb06ULL, + 0xf2967979f979ef80ULL, 0xde306f6fa16f5fceULL, 0x3f6d91917e91fcefULL, 0xa4f852525552aa07ULL, + 0xc04760609d6027fdULL, 0x6535bcbccabc8976ULL, 0x2b379b9b569baccdULL, 0x018a8e8e028e048cULL, + 0x5bd2a3a3b6a37115ULL, 0x186c0c0c300c603cULL, 0xf6847b7bf17bff8aULL, 0x6a803535d435b5e1ULL, + 0x3af51d1d741de869ULL, 0xddb3e0e0a7e05347ULL, 0xb321d7d77bd7f6acULL, 0x999cc2c22fc25eedULL, + 0x5c432e2eb82e6d96ULL, 0x96294b4b314b627aULL, 0xe15dfefedffea321ULL, 0xaed5575741578216ULL, + 0x2abd15155415a841ULL, 0xeee87777c1779fb6ULL, 0x6e923737dc37a5ebULL, 0xd79ee5e5b3e57b56ULL, + 0x23139f9f469f8cd9ULL, 0xfd23f0f0e7f0d317ULL, 0x94204a4a354a6a7fULL, 0xa944dada4fda9e95ULL, + 0xb0a258587d58fa25ULL, 0x8fcfc9c903c906caULL, 0x527c2929a429558dULL, 0x145a0a0a280a5022ULL, + 0x7f50b1b1feb1e14fULL, 0x5dc9a0a0baa0691aULL, 0xd6146b6bb16b7fdaULL, 0x17d985852e855cabULL, + 0x673cbdbdcebd8173ULL, 0xba8f5d5d695dd234ULL, 0x2090101040108050ULL, 0xf507f4f4f7f4f303ULL, + 0x8bddcbcb0bcb16c0ULL, 0x7cd33e3ef83eedc6ULL, 0x0a2d050514052811ULL, 0xce78676781671fe6ULL, + 0xd597e4e4b7e47353ULL, 0x4e0227279c2725bbULL, 0x8273414119413258ULL, 0x0ba78b8b168b2c9dULL, + 0x53f6a7a7a6a75101ULL, 0xfab27d7de97dcf94ULL, 0x374995956e95dcfbULL, 0xad56d8d847d88e9fULL, + 0xeb70fbfbcbfb8b30ULL, 0xc1cdeeee9fee2371ULL, 0xf8bb7c7ced7cc791ULL, 0xcc716666856617e3ULL, + 0xa77bdddd53dda68eULL, 0x2eaf17175c17b84bULL, 0x8e45474701470246ULL, 0x211a9e9e429e84dcULL, + 0x89d4caca0fca1ec5ULL, 0x5a582d2db42d7599ULL, 0x632ebfbfc6bf9179ULL, 0x0e3f07071c07381bULL, + 0x47acadad8ead0123ULL, 0xb4b05a5a755aea2fULL, 0x1bef838336836cb5ULL, 0x66b63333cc3385ffULL, + 0xc65c636391633ff2ULL, 0x041202020802100aULL, 0x4993aaaa92aa3938ULL, 0xe2de7171d971afa8ULL, + 0x8dc6c8c807c80ecfULL, 0x32d119196419c87dULL, 0x923b494939497270ULL, 0xaf5fd9d943d9869aULL, + 0xf931f2f2eff2c31dULL, 0xdba8e3e3abe34b48ULL, 0xb6b95b5b715be22aULL, 0x0dbc88881a883492ULL, + 0x293e9a9a529aa4c8ULL, 0x4c0b262698262dbeULL, 0x64bf3232c8328dfaULL, 0x7d59b0b0fab0e94aULL, + 0xcff2e9e983e91b6aULL, 0x1e770f0f3c0f7833ULL, 0xb733d5d573d5e6a6ULL, 0x1df480803a8074baULL, + 0x6127bebec2be997cULL, 0x87ebcdcd13cd26deULL, 0x68893434d034bde4ULL, 0x903248483d487a75ULL, + 0xe354ffffdbffab24ULL, 0xf48d7a7af57af78fULL, 0x3d6490907a90f4eaULL, 0xbe9d5f5f615fc23eULL, + 0x403d202080201da0ULL, 0xd00f6868bd6867d5ULL, 0x34ca1a1a681ad072ULL, 0x41b7aeae82ae192cULL, + 0x757db4b4eab4c95eULL, 0xa8ce54544d549a19ULL, 0x3b7f93937693ece5ULL, 0x442f222288220daaULL, + 0xc86364648d6407e9ULL, 0xff2af1f1e3f1db12ULL, 0xe6cc7373d173bfa2ULL, 0x248212124812905aULL, + 0x807a40401d403a5dULL, 0x1048080820084028ULL, 0x9b95c3c32bc356e8ULL, 0xc5dfecec97ec337bULL, + 0xab4ddbdb4bdb9690ULL, 0x5fc0a1a1bea1611fULL, 0x07918d8d0e8d1c83ULL, 0x7ac83d3df43df5c9ULL, + 0x335b97976697ccf1ULL, 0x0000000000000000ULL, 0x83f9cfcf1bcf36d4ULL, 0x566e2b2bac2b4587ULL, + 0xece17676c57697b3ULL, 0x19e68282328264b0ULL, 0xb128d6d67fd6fea9ULL, 0x36c31b1b6c1bd877ULL, + 0x7774b5b5eeb5c15bULL, 0x43beafaf86af1129ULL, 0xd41d6a6ab56a77dfULL, 0xa0ea50505d50ba0dULL, + 0x8a5745450945124cULL, 0xfb38f3f3ebf3cb18ULL, 0x60ad3030c0309df0ULL, 0xc3c4efef9bef2b74ULL, + 0x7eda3f3ffc3fe5c3ULL, 0xaac755554955921cULL, 0x59dba2a2b2a27910ULL, 0xc9e9eaea8fea0365ULL, + 0xca6a656589650fecULL, 0x6903babad2bab968ULL, 0x5e4a2f2fbc2f6593ULL, 0x9d8ec0c027c04ee7ULL, + 0xa160dede5fdebe81ULL, 0x38fc1c1c701ce06cULL, 0xe746fdfdd3fdbb2eULL, 0x9a1f4d4d294d5264ULL, + 0x397692927292e4e0ULL, 0xeafa7575c9758fbcULL, 0x0c3606061806301eULL, 0x09ae8a8a128a2498ULL, + 0x794bb2b2f2b2f940ULL, 0xd185e6e6bfe66359ULL, 0x1c7e0e0e380e7036ULL, 0x3ee71f1f7c1ff863ULL, + 0xc4556262956237f7ULL, 0xb53ad4d477d4eea3ULL, 0x4d81a8a89aa82932ULL, 0x315296966296c4f4ULL, + 0xef62f9f9c3f99b3aULL, 0x97a3c5c533c566f6ULL, 0x4a102525942535b1ULL, 0xb2ab59597959f220ULL, + 0x15d084842a8454aeULL, 0xe4c57272d572b7a7ULL, 0x72ec3939e439d5ddULL, 0x98164c4c2d4c5a61ULL, + 0xbc945e5e655eca3bULL, 0xf09f7878fd78e785ULL, 0x70e53838e038ddd8ULL, 0x05988c8c0a8c1486ULL, + 0xbf17d1d163d1c6b2ULL, 0x57e4a5a5aea5410bULL, 0xd9a1e2e2afe2434dULL, 0xc24e616199612ff8ULL, + 0x7b42b3b3f6b3f145ULL, 0x42342121842115a5ULL, 0x25089c9c4a9c94d6ULL, 0x3cee1e1e781ef066ULL, + 0x8661434311432252ULL, 0x93b1c7c73bc776fcULL, 0xe54ffcfcd7fcb32bULL, 0x0824040410042014ULL, + 0xa2e351515951b208ULL, 0x2f2599995e99bcc7ULL, 0xda226d6da96d4fc4ULL, 0x1a650d0d340d6839ULL, + 0xe979fafacffa8335ULL, 0xa369dfdf5bdfb684ULL, 0xfca97e7ee57ed79bULL, 0x4819242490243db4ULL, + 0x76fe3b3bec3bc5d7ULL, 0x4b9aabab96ab313dULL, 0x81f0cece1fce3ed1ULL, 0x2299111144118855ULL, + 0x03838f8f068f0c89ULL, 0x9c044e4e254e4a6bULL, 0x7366b7b7e6b7d151ULL, 0xcbe0ebeb8beb0b60ULL, + 0x78c13c3cf03cfdccULL, 0x1ffd81813e817cbfULL, 0x354094946a94d4feULL, 0xf31cf7f7fbf7eb0cULL, + 0x6f18b9b9deb9a167ULL, 0x268b13134c13985fULL, 0x58512c2cb02c7d9cULL, 0xbb05d3d36bd3d6b8ULL, + 0xd38ce7e7bbe76b5cULL, 0xdc396e6ea56e57cbULL, 0x95aac4c437c46ef3ULL, 0x061b03030c03180fULL, + 0xacdc565645568a13ULL, 0x885e44440d441a49ULL, 0xfea07f7fe17fdf9eULL, 0x4f88a9a99ea92137ULL, + 0x54672a2aa82a4d82ULL, 0x6b0abbbbd6bbb16dULL, 0x9f87c1c123c146e2ULL, 0xa6f153535153a202ULL, + 0xa572dcdc57dcae8bULL, 0x16530b0b2c0b5827ULL, 0x27019d9d4e9d9cd3ULL, 0xd82b6c6cad6c47c1ULL, + 0x62a43131c43195f5ULL, 0xe8f37474cd7487b9ULL, 0xf115f6f6fff6e309ULL, 0x8c4c464605460a43ULL, + 0x45a5acac8aac0926ULL, 0x0fb589891e893c97ULL, 0x28b414145014a044ULL, 0xdfbae1e1a3e15b42ULL, + 0x2ca616165816b04eULL, 0x74f73a3ae83acdd2ULL, 0xd2066969b9696fd0ULL, 0x124109092409482dULL, + 0xe0d77070dd70a7adULL, 0x716fb6b6e2b6d954ULL, 0xbd1ed0d067d0ceb7ULL, 0xc7d6eded93ed3b7eULL, + 0x85e2cccc17cc2edbULL, 0x8468424215422a57ULL, 0x2d2c98985a98b4c2ULL, 0x55eda4a4aaa4490eULL, + 0x50752828a0285d88ULL, 0xb8865c5c6d5cda31ULL, 0xed6bf8f8c7f8933fULL, 0x11c28686228644a4ULL, + }; + + const UInt64 C3[256] = { + 0x7830d818186018c0ULL, 0xaf462623238c2305ULL, 0xf991b8c6c63fc67eULL, 0x6fcdfbe8e887e813ULL, + 0xa113cb878726874cULL, 0x626d11b8b8dab8a9ULL, 0x0502090101040108ULL, 0x6e9e0d4f4f214f42ULL, + 0xee6c9b3636d836adULL, 0x0451ffa6a6a2a659ULL, 0xbdb90cd2d26fd2deULL, 0x06f70ef5f5f3f5fbULL, + 0x80f2967979f979efULL, 0xcede306f6fa16f5fULL, 0xef3f6d91917e91fcULL, 0x07a4f852525552aaULL, + 0xfdc04760609d6027ULL, 0x766535bcbccabc89ULL, 0xcd2b379b9b569bacULL, 0x8c018a8e8e028e04ULL, + 0x155bd2a3a3b6a371ULL, 0x3c186c0c0c300c60ULL, 0x8af6847b7bf17bffULL, 0xe16a803535d435b5ULL, + 0x693af51d1d741de8ULL, 0x47ddb3e0e0a7e053ULL, 0xacb321d7d77bd7f6ULL, 0xed999cc2c22fc25eULL, + 0x965c432e2eb82e6dULL, 0x7a96294b4b314b62ULL, 0x21e15dfefedffea3ULL, 0x16aed55757415782ULL, + 0x412abd15155415a8ULL, 0xb6eee87777c1779fULL, 0xeb6e923737dc37a5ULL, 0x56d79ee5e5b3e57bULL, + 0xd923139f9f469f8cULL, 0x17fd23f0f0e7f0d3ULL, 0x7f94204a4a354a6aULL, 0x95a944dada4fda9eULL, + 0x25b0a258587d58faULL, 0xca8fcfc9c903c906ULL, 0x8d527c2929a42955ULL, 0x22145a0a0a280a50ULL, + 0x4f7f50b1b1feb1e1ULL, 0x1a5dc9a0a0baa069ULL, 0xdad6146b6bb16b7fULL, 0xab17d985852e855cULL, + 0x73673cbdbdcebd81ULL, 0x34ba8f5d5d695dd2ULL, 0x5020901010401080ULL, 0x03f507f4f4f7f4f3ULL, + 0xc08bddcbcb0bcb16ULL, 0xc67cd33e3ef83eedULL, 0x110a2d0505140528ULL, 0xe6ce78676781671fULL, + 0x53d597e4e4b7e473ULL, 0xbb4e0227279c2725ULL, 0x5882734141194132ULL, 0x9d0ba78b8b168b2cULL, + 0x0153f6a7a7a6a751ULL, 0x94fab27d7de97dcfULL, 0xfb374995956e95dcULL, 0x9fad56d8d847d88eULL, + 0x30eb70fbfbcbfb8bULL, 0x71c1cdeeee9fee23ULL, 0x91f8bb7c7ced7cc7ULL, 0xe3cc716666856617ULL, + 0x8ea77bdddd53dda6ULL, 0x4b2eaf17175c17b8ULL, 0x468e454747014702ULL, 0xdc211a9e9e429e84ULL, + 0xc589d4caca0fca1eULL, 0x995a582d2db42d75ULL, 0x79632ebfbfc6bf91ULL, 0x1b0e3f07071c0738ULL, + 0x2347acadad8ead01ULL, 0x2fb4b05a5a755aeaULL, 0xb51bef838336836cULL, 0xff66b63333cc3385ULL, + 0xf2c65c636391633fULL, 0x0a04120202080210ULL, 0x384993aaaa92aa39ULL, 0xa8e2de7171d971afULL, + 0xcf8dc6c8c807c80eULL, 0x7d32d119196419c8ULL, 0x70923b4949394972ULL, 0x9aaf5fd9d943d986ULL, + 0x1df931f2f2eff2c3ULL, 0x48dba8e3e3abe34bULL, 0x2ab6b95b5b715be2ULL, 0x920dbc88881a8834ULL, + 0xc8293e9a9a529aa4ULL, 0xbe4c0b262698262dULL, 0xfa64bf3232c8328dULL, 0x4a7d59b0b0fab0e9ULL, + 0x6acff2e9e983e91bULL, 0x331e770f0f3c0f78ULL, 0xa6b733d5d573d5e6ULL, 0xba1df480803a8074ULL, + 0x7c6127bebec2be99ULL, 0xde87ebcdcd13cd26ULL, 0xe468893434d034bdULL, 0x75903248483d487aULL, + 0x24e354ffffdbffabULL, 0x8ff48d7a7af57af7ULL, 0xea3d6490907a90f4ULL, 0x3ebe9d5f5f615fc2ULL, + 0xa0403d202080201dULL, 0xd5d00f6868bd6867ULL, 0x7234ca1a1a681ad0ULL, 0x2c41b7aeae82ae19ULL, + 0x5e757db4b4eab4c9ULL, 0x19a8ce54544d549aULL, 0xe53b7f93937693ecULL, 0xaa442f222288220dULL, + 0xe9c86364648d6407ULL, 0x12ff2af1f1e3f1dbULL, 0xa2e6cc7373d173bfULL, 0x5a24821212481290ULL, + 0x5d807a40401d403aULL, 0x2810480808200840ULL, 0xe89b95c3c32bc356ULL, 0x7bc5dfecec97ec33ULL, + 0x90ab4ddbdb4bdb96ULL, 0x1f5fc0a1a1bea161ULL, 0x8307918d8d0e8d1cULL, 0xc97ac83d3df43df5ULL, + 0xf1335b97976697ccULL, 0x0000000000000000ULL, 0xd483f9cfcf1bcf36ULL, 0x87566e2b2bac2b45ULL, + 0xb3ece17676c57697ULL, 0xb019e68282328264ULL, 0xa9b128d6d67fd6feULL, 0x7736c31b1b6c1bd8ULL, + 0x5b7774b5b5eeb5c1ULL, 0x2943beafaf86af11ULL, 0xdfd41d6a6ab56a77ULL, 0x0da0ea50505d50baULL, + 0x4c8a574545094512ULL, 0x18fb38f3f3ebf3cbULL, 0xf060ad3030c0309dULL, 0x74c3c4efef9bef2bULL, + 0xc37eda3f3ffc3fe5ULL, 0x1caac75555495592ULL, 0x1059dba2a2b2a279ULL, 0x65c9e9eaea8fea03ULL, + 0xecca6a656589650fULL, 0x686903babad2bab9ULL, 0x935e4a2f2fbc2f65ULL, 0xe79d8ec0c027c04eULL, + 0x81a160dede5fdebeULL, 0x6c38fc1c1c701ce0ULL, 0x2ee746fdfdd3fdbbULL, 0x649a1f4d4d294d52ULL, + 0xe0397692927292e4ULL, 0xbceafa7575c9758fULL, 0x1e0c360606180630ULL, 0x9809ae8a8a128a24ULL, + 0x40794bb2b2f2b2f9ULL, 0x59d185e6e6bfe663ULL, 0x361c7e0e0e380e70ULL, 0x633ee71f1f7c1ff8ULL, + 0xf7c4556262956237ULL, 0xa3b53ad4d477d4eeULL, 0x324d81a8a89aa829ULL, 0xf4315296966296c4ULL, + 0x3aef62f9f9c3f99bULL, 0xf697a3c5c533c566ULL, 0xb14a102525942535ULL, 0x20b2ab59597959f2ULL, + 0xae15d084842a8454ULL, 0xa7e4c57272d572b7ULL, 0xdd72ec3939e439d5ULL, 0x6198164c4c2d4c5aULL, + 0x3bbc945e5e655ecaULL, 0x85f09f7878fd78e7ULL, 0xd870e53838e038ddULL, 0x8605988c8c0a8c14ULL, + 0xb2bf17d1d163d1c6ULL, 0x0b57e4a5a5aea541ULL, 0x4dd9a1e2e2afe243ULL, 0xf8c24e616199612fULL, + 0x457b42b3b3f6b3f1ULL, 0xa542342121842115ULL, 0xd625089c9c4a9c94ULL, 0x663cee1e1e781ef0ULL, + 0x5286614343114322ULL, 0xfc93b1c7c73bc776ULL, 0x2be54ffcfcd7fcb3ULL, 0x1408240404100420ULL, + 0x08a2e351515951b2ULL, 0xc72f2599995e99bcULL, 0xc4da226d6da96d4fULL, 0x391a650d0d340d68ULL, + 0x35e979fafacffa83ULL, 0x84a369dfdf5bdfb6ULL, 0x9bfca97e7ee57ed7ULL, 0xb44819242490243dULL, + 0xd776fe3b3bec3bc5ULL, 0x3d4b9aabab96ab31ULL, 0xd181f0cece1fce3eULL, 0x5522991111441188ULL, + 0x8903838f8f068f0cULL, 0x6b9c044e4e254e4aULL, 0x517366b7b7e6b7d1ULL, 0x60cbe0ebeb8beb0bULL, + 0xcc78c13c3cf03cfdULL, 0xbf1ffd81813e817cULL, 0xfe354094946a94d4ULL, 0x0cf31cf7f7fbf7ebULL, + 0x676f18b9b9deb9a1ULL, 0x5f268b13134c1398ULL, 0x9c58512c2cb02c7dULL, 0xb8bb05d3d36bd3d6ULL, + 0x5cd38ce7e7bbe76bULL, 0xcbdc396e6ea56e57ULL, 0xf395aac4c437c46eULL, 0x0f061b03030c0318ULL, + 0x13acdc565645568aULL, 0x49885e44440d441aULL, 0x9efea07f7fe17fdfULL, 0x374f88a9a99ea921ULL, + 0x8254672a2aa82a4dULL, 0x6d6b0abbbbd6bbb1ULL, 0xe29f87c1c123c146ULL, 0x02a6f153535153a2ULL, + 0x8ba572dcdc57dcaeULL, 0x2716530b0b2c0b58ULL, 0xd327019d9d4e9d9cULL, 0xc1d82b6c6cad6c47ULL, + 0xf562a43131c43195ULL, 0xb9e8f37474cd7487ULL, 0x09f115f6f6fff6e3ULL, 0x438c4c464605460aULL, + 0x2645a5acac8aac09ULL, 0x970fb589891e893cULL, 0x4428b414145014a0ULL, 0x42dfbae1e1a3e15bULL, + 0x4e2ca616165816b0ULL, 0xd274f73a3ae83acdULL, 0xd0d2066969b9696fULL, 0x2d12410909240948ULL, + 0xade0d77070dd70a7ULL, 0x54716fb6b6e2b6d9ULL, 0xb7bd1ed0d067d0ceULL, 0x7ec7d6eded93ed3bULL, + 0xdb85e2cccc17cc2eULL, 0x578468424215422aULL, 0xc22d2c98985a98b4ULL, 0x0e55eda4a4aaa449ULL, + 0x8850752828a0285dULL, 0x31b8865c5c6d5cdaULL, 0x3fed6bf8f8c7f893ULL, 0xa411c28686228644ULL, + }; + + const UInt64 C4[256] = { + 0xc07830d818186018ULL, 0x05af462623238c23ULL, 0x7ef991b8c6c63fc6ULL, 0x136fcdfbe8e887e8ULL, + 0x4ca113cb87872687ULL, 0xa9626d11b8b8dab8ULL, 0x0805020901010401ULL, 0x426e9e0d4f4f214fULL, + 0xadee6c9b3636d836ULL, 0x590451ffa6a6a2a6ULL, 0xdebdb90cd2d26fd2ULL, 0xfb06f70ef5f5f3f5ULL, + 0xef80f2967979f979ULL, 0x5fcede306f6fa16fULL, 0xfcef3f6d91917e91ULL, 0xaa07a4f852525552ULL, + 0x27fdc04760609d60ULL, 0x89766535bcbccabcULL, 0xaccd2b379b9b569bULL, 0x048c018a8e8e028eULL, + 0x71155bd2a3a3b6a3ULL, 0x603c186c0c0c300cULL, 0xff8af6847b7bf17bULL, 0xb5e16a803535d435ULL, + 0xe8693af51d1d741dULL, 0x5347ddb3e0e0a7e0ULL, 0xf6acb321d7d77bd7ULL, 0x5eed999cc2c22fc2ULL, + 0x6d965c432e2eb82eULL, 0x627a96294b4b314bULL, 0xa321e15dfefedffeULL, 0x8216aed557574157ULL, + 0xa8412abd15155415ULL, 0x9fb6eee87777c177ULL, 0xa5eb6e923737dc37ULL, 0x7b56d79ee5e5b3e5ULL, + 0x8cd923139f9f469fULL, 0xd317fd23f0f0e7f0ULL, 0x6a7f94204a4a354aULL, 0x9e95a944dada4fdaULL, + 0xfa25b0a258587d58ULL, 0x06ca8fcfc9c903c9ULL, 0x558d527c2929a429ULL, 0x5022145a0a0a280aULL, + 0xe14f7f50b1b1feb1ULL, 0x691a5dc9a0a0baa0ULL, 0x7fdad6146b6bb16bULL, 0x5cab17d985852e85ULL, + 0x8173673cbdbdcebdULL, 0xd234ba8f5d5d695dULL, 0x8050209010104010ULL, 0xf303f507f4f4f7f4ULL, + 0x16c08bddcbcb0bcbULL, 0xedc67cd33e3ef83eULL, 0x28110a2d05051405ULL, 0x1fe6ce7867678167ULL, + 0x7353d597e4e4b7e4ULL, 0x25bb4e0227279c27ULL, 0x3258827341411941ULL, 0x2c9d0ba78b8b168bULL, + 0x510153f6a7a7a6a7ULL, 0xcf94fab27d7de97dULL, 0xdcfb374995956e95ULL, 0x8e9fad56d8d847d8ULL, + 0x8b30eb70fbfbcbfbULL, 0x2371c1cdeeee9feeULL, 0xc791f8bb7c7ced7cULL, 0x17e3cc7166668566ULL, + 0xa68ea77bdddd53ddULL, 0xb84b2eaf17175c17ULL, 0x02468e4547470147ULL, 0x84dc211a9e9e429eULL, + 0x1ec589d4caca0fcaULL, 0x75995a582d2db42dULL, 0x9179632ebfbfc6bfULL, 0x381b0e3f07071c07ULL, + 0x012347acadad8eadULL, 0xea2fb4b05a5a755aULL, 0x6cb51bef83833683ULL, 0x85ff66b63333cc33ULL, + 0x3ff2c65c63639163ULL, 0x100a041202020802ULL, 0x39384993aaaa92aaULL, 0xafa8e2de7171d971ULL, + 0x0ecf8dc6c8c807c8ULL, 0xc87d32d119196419ULL, 0x7270923b49493949ULL, 0x869aaf5fd9d943d9ULL, + 0xc31df931f2f2eff2ULL, 0x4b48dba8e3e3abe3ULL, 0xe22ab6b95b5b715bULL, 0x34920dbc88881a88ULL, + 0xa4c8293e9a9a529aULL, 0x2dbe4c0b26269826ULL, 0x8dfa64bf3232c832ULL, 0xe94a7d59b0b0fab0ULL, + 0x1b6acff2e9e983e9ULL, 0x78331e770f0f3c0fULL, 0xe6a6b733d5d573d5ULL, 0x74ba1df480803a80ULL, + 0x997c6127bebec2beULL, 0x26de87ebcdcd13cdULL, 0xbde468893434d034ULL, 0x7a75903248483d48ULL, + 0xab24e354ffffdbffULL, 0xf78ff48d7a7af57aULL, 0xf4ea3d6490907a90ULL, 0xc23ebe9d5f5f615fULL, + 0x1da0403d20208020ULL, 0x67d5d00f6868bd68ULL, 0xd07234ca1a1a681aULL, 0x192c41b7aeae82aeULL, + 0xc95e757db4b4eab4ULL, 0x9a19a8ce54544d54ULL, 0xece53b7f93937693ULL, 0x0daa442f22228822ULL, + 0x07e9c86364648d64ULL, 0xdb12ff2af1f1e3f1ULL, 0xbfa2e6cc7373d173ULL, 0x905a248212124812ULL, + 0x3a5d807a40401d40ULL, 0x4028104808082008ULL, 0x56e89b95c3c32bc3ULL, 0x337bc5dfecec97ecULL, + 0x9690ab4ddbdb4bdbULL, 0x611f5fc0a1a1bea1ULL, 0x1c8307918d8d0e8dULL, 0xf5c97ac83d3df43dULL, + 0xccf1335b97976697ULL, 0x0000000000000000ULL, 0x36d483f9cfcf1bcfULL, 0x4587566e2b2bac2bULL, + 0x97b3ece17676c576ULL, 0x64b019e682823282ULL, 0xfea9b128d6d67fd6ULL, 0xd87736c31b1b6c1bULL, + 0xc15b7774b5b5eeb5ULL, 0x112943beafaf86afULL, 0x77dfd41d6a6ab56aULL, 0xba0da0ea50505d50ULL, + 0x124c8a5745450945ULL, 0xcb18fb38f3f3ebf3ULL, 0x9df060ad3030c030ULL, 0x2b74c3c4efef9befULL, + 0xe5c37eda3f3ffc3fULL, 0x921caac755554955ULL, 0x791059dba2a2b2a2ULL, 0x0365c9e9eaea8feaULL, + 0x0fecca6a65658965ULL, 0xb9686903babad2baULL, 0x65935e4a2f2fbc2fULL, 0x4ee79d8ec0c027c0ULL, + 0xbe81a160dede5fdeULL, 0xe06c38fc1c1c701cULL, 0xbb2ee746fdfdd3fdULL, 0x52649a1f4d4d294dULL, + 0xe4e0397692927292ULL, 0x8fbceafa7575c975ULL, 0x301e0c3606061806ULL, 0x249809ae8a8a128aULL, + 0xf940794bb2b2f2b2ULL, 0x6359d185e6e6bfe6ULL, 0x70361c7e0e0e380eULL, 0xf8633ee71f1f7c1fULL, + 0x37f7c45562629562ULL, 0xeea3b53ad4d477d4ULL, 0x29324d81a8a89aa8ULL, 0xc4f4315296966296ULL, + 0x9b3aef62f9f9c3f9ULL, 0x66f697a3c5c533c5ULL, 0x35b14a1025259425ULL, 0xf220b2ab59597959ULL, + 0x54ae15d084842a84ULL, 0xb7a7e4c57272d572ULL, 0xd5dd72ec3939e439ULL, 0x5a6198164c4c2d4cULL, + 0xca3bbc945e5e655eULL, 0xe785f09f7878fd78ULL, 0xddd870e53838e038ULL, 0x148605988c8c0a8cULL, + 0xc6b2bf17d1d163d1ULL, 0x410b57e4a5a5aea5ULL, 0x434dd9a1e2e2afe2ULL, 0x2ff8c24e61619961ULL, + 0xf1457b42b3b3f6b3ULL, 0x15a5423421218421ULL, 0x94d625089c9c4a9cULL, 0xf0663cee1e1e781eULL, + 0x2252866143431143ULL, 0x76fc93b1c7c73bc7ULL, 0xb32be54ffcfcd7fcULL, 0x2014082404041004ULL, + 0xb208a2e351515951ULL, 0xbcc72f2599995e99ULL, 0x4fc4da226d6da96dULL, 0x68391a650d0d340dULL, + 0x8335e979fafacffaULL, 0xb684a369dfdf5bdfULL, 0xd79bfca97e7ee57eULL, 0x3db4481924249024ULL, + 0xc5d776fe3b3bec3bULL, 0x313d4b9aabab96abULL, 0x3ed181f0cece1fceULL, 0x8855229911114411ULL, + 0x0c8903838f8f068fULL, 0x4a6b9c044e4e254eULL, 0xd1517366b7b7e6b7ULL, 0x0b60cbe0ebeb8bebULL, + 0xfdcc78c13c3cf03cULL, 0x7cbf1ffd81813e81ULL, 0xd4fe354094946a94ULL, 0xeb0cf31cf7f7fbf7ULL, + 0xa1676f18b9b9deb9ULL, 0x985f268b13134c13ULL, 0x7d9c58512c2cb02cULL, 0xd6b8bb05d3d36bd3ULL, + 0x6b5cd38ce7e7bbe7ULL, 0x57cbdc396e6ea56eULL, 0x6ef395aac4c437c4ULL, 0x180f061b03030c03ULL, + 0x8a13acdc56564556ULL, 0x1a49885e44440d44ULL, 0xdf9efea07f7fe17fULL, 0x21374f88a9a99ea9ULL, + 0x4d8254672a2aa82aULL, 0xb16d6b0abbbbd6bbULL, 0x46e29f87c1c123c1ULL, 0xa202a6f153535153ULL, + 0xae8ba572dcdc57dcULL, 0x582716530b0b2c0bULL, 0x9cd327019d9d4e9dULL, 0x47c1d82b6c6cad6cULL, + 0x95f562a43131c431ULL, 0x87b9e8f37474cd74ULL, 0xe309f115f6f6fff6ULL, 0x0a438c4c46460546ULL, + 0x092645a5acac8aacULL, 0x3c970fb589891e89ULL, 0xa04428b414145014ULL, 0x5b42dfbae1e1a3e1ULL, + 0xb04e2ca616165816ULL, 0xcdd274f73a3ae83aULL, 0x6fd0d2066969b969ULL, 0x482d124109092409ULL, + 0xa7ade0d77070dd70ULL, 0xd954716fb6b6e2b6ULL, 0xceb7bd1ed0d067d0ULL, 0x3b7ec7d6eded93edULL, + 0x2edb85e2cccc17ccULL, 0x2a57846842421542ULL, 0xb4c22d2c98985a98ULL, 0x490e55eda4a4aaa4ULL, + 0x5d8850752828a028ULL, 0xda31b8865c5c6d5cULL, 0x933fed6bf8f8c7f8ULL, 0x44a411c286862286ULL, + }; + + const UInt64 C5[256] = { + 0x18c07830d8181860ULL, 0x2305af462623238cULL, 0xc67ef991b8c6c63fULL, 0xe8136fcdfbe8e887ULL, + 0x874ca113cb878726ULL, 0xb8a9626d11b8b8daULL, 0x0108050209010104ULL, 0x4f426e9e0d4f4f21ULL, + 0x36adee6c9b3636d8ULL, 0xa6590451ffa6a6a2ULL, 0xd2debdb90cd2d26fULL, 0xf5fb06f70ef5f5f3ULL, + 0x79ef80f2967979f9ULL, 0x6f5fcede306f6fa1ULL, 0x91fcef3f6d91917eULL, 0x52aa07a4f8525255ULL, + 0x6027fdc04760609dULL, 0xbc89766535bcbccaULL, 0x9baccd2b379b9b56ULL, 0x8e048c018a8e8e02ULL, + 0xa371155bd2a3a3b6ULL, 0x0c603c186c0c0c30ULL, 0x7bff8af6847b7bf1ULL, 0x35b5e16a803535d4ULL, + 0x1de8693af51d1d74ULL, 0xe05347ddb3e0e0a7ULL, 0xd7f6acb321d7d77bULL, 0xc25eed999cc2c22fULL, + 0x2e6d965c432e2eb8ULL, 0x4b627a96294b4b31ULL, 0xfea321e15dfefedfULL, 0x578216aed5575741ULL, + 0x15a8412abd151554ULL, 0x779fb6eee87777c1ULL, 0x37a5eb6e923737dcULL, 0xe57b56d79ee5e5b3ULL, + 0x9f8cd923139f9f46ULL, 0xf0d317fd23f0f0e7ULL, 0x4a6a7f94204a4a35ULL, 0xda9e95a944dada4fULL, + 0x58fa25b0a258587dULL, 0xc906ca8fcfc9c903ULL, 0x29558d527c2929a4ULL, 0x0a5022145a0a0a28ULL, + 0xb1e14f7f50b1b1feULL, 0xa0691a5dc9a0a0baULL, 0x6b7fdad6146b6bb1ULL, 0x855cab17d985852eULL, + 0xbd8173673cbdbdceULL, 0x5dd234ba8f5d5d69ULL, 0x1080502090101040ULL, 0xf4f303f507f4f4f7ULL, + 0xcb16c08bddcbcb0bULL, 0x3eedc67cd33e3ef8ULL, 0x0528110a2d050514ULL, 0x671fe6ce78676781ULL, + 0xe47353d597e4e4b7ULL, 0x2725bb4e0227279cULL, 0x4132588273414119ULL, 0x8b2c9d0ba78b8b16ULL, + 0xa7510153f6a7a7a6ULL, 0x7dcf94fab27d7de9ULL, 0x95dcfb374995956eULL, 0xd88e9fad56d8d847ULL, + 0xfb8b30eb70fbfbcbULL, 0xee2371c1cdeeee9fULL, 0x7cc791f8bb7c7cedULL, 0x6617e3cc71666685ULL, + 0xdda68ea77bdddd53ULL, 0x17b84b2eaf17175cULL, 0x4702468e45474701ULL, 0x9e84dc211a9e9e42ULL, + 0xca1ec589d4caca0fULL, 0x2d75995a582d2db4ULL, 0xbf9179632ebfbfc6ULL, 0x07381b0e3f07071cULL, + 0xad012347acadad8eULL, 0x5aea2fb4b05a5a75ULL, 0x836cb51bef838336ULL, 0x3385ff66b63333ccULL, + 0x633ff2c65c636391ULL, 0x02100a0412020208ULL, 0xaa39384993aaaa92ULL, 0x71afa8e2de7171d9ULL, + 0xc80ecf8dc6c8c807ULL, 0x19c87d32d1191964ULL, 0x497270923b494939ULL, 0xd9869aaf5fd9d943ULL, + 0xf2c31df931f2f2efULL, 0xe34b48dba8e3e3abULL, 0x5be22ab6b95b5b71ULL, 0x8834920dbc88881aULL, + 0x9aa4c8293e9a9a52ULL, 0x262dbe4c0b262698ULL, 0x328dfa64bf3232c8ULL, 0xb0e94a7d59b0b0faULL, + 0xe91b6acff2e9e983ULL, 0x0f78331e770f0f3cULL, 0xd5e6a6b733d5d573ULL, 0x8074ba1df480803aULL, + 0xbe997c6127bebec2ULL, 0xcd26de87ebcdcd13ULL, 0x34bde468893434d0ULL, 0x487a75903248483dULL, + 0xffab24e354ffffdbULL, 0x7af78ff48d7a7af5ULL, 0x90f4ea3d6490907aULL, 0x5fc23ebe9d5f5f61ULL, + 0x201da0403d202080ULL, 0x6867d5d00f6868bdULL, 0x1ad07234ca1a1a68ULL, 0xae192c41b7aeae82ULL, + 0xb4c95e757db4b4eaULL, 0x549a19a8ce54544dULL, 0x93ece53b7f939376ULL, 0x220daa442f222288ULL, + 0x6407e9c86364648dULL, 0xf1db12ff2af1f1e3ULL, 0x73bfa2e6cc7373d1ULL, 0x12905a2482121248ULL, + 0x403a5d807a40401dULL, 0x0840281048080820ULL, 0xc356e89b95c3c32bULL, 0xec337bc5dfecec97ULL, + 0xdb9690ab4ddbdb4bULL, 0xa1611f5fc0a1a1beULL, 0x8d1c8307918d8d0eULL, 0x3df5c97ac83d3df4ULL, + 0x97ccf1335b979766ULL, 0x0000000000000000ULL, 0xcf36d483f9cfcf1bULL, 0x2b4587566e2b2bacULL, + 0x7697b3ece17676c5ULL, 0x8264b019e6828232ULL, 0xd6fea9b128d6d67fULL, 0x1bd87736c31b1b6cULL, + 0xb5c15b7774b5b5eeULL, 0xaf112943beafaf86ULL, 0x6a77dfd41d6a6ab5ULL, 0x50ba0da0ea50505dULL, + 0x45124c8a57454509ULL, 0xf3cb18fb38f3f3ebULL, 0x309df060ad3030c0ULL, 0xef2b74c3c4efef9bULL, + 0x3fe5c37eda3f3ffcULL, 0x55921caac7555549ULL, 0xa2791059dba2a2b2ULL, 0xea0365c9e9eaea8fULL, + 0x650fecca6a656589ULL, 0xbab9686903babad2ULL, 0x2f65935e4a2f2fbcULL, 0xc04ee79d8ec0c027ULL, + 0xdebe81a160dede5fULL, 0x1ce06c38fc1c1c70ULL, 0xfdbb2ee746fdfdd3ULL, 0x4d52649a1f4d4d29ULL, + 0x92e4e03976929272ULL, 0x758fbceafa7575c9ULL, 0x06301e0c36060618ULL, 0x8a249809ae8a8a12ULL, + 0xb2f940794bb2b2f2ULL, 0xe66359d185e6e6bfULL, 0x0e70361c7e0e0e38ULL, 0x1ff8633ee71f1f7cULL, + 0x6237f7c455626295ULL, 0xd4eea3b53ad4d477ULL, 0xa829324d81a8a89aULL, 0x96c4f43152969662ULL, + 0xf99b3aef62f9f9c3ULL, 0xc566f697a3c5c533ULL, 0x2535b14a10252594ULL, 0x59f220b2ab595979ULL, + 0x8454ae15d084842aULL, 0x72b7a7e4c57272d5ULL, 0x39d5dd72ec3939e4ULL, 0x4c5a6198164c4c2dULL, + 0x5eca3bbc945e5e65ULL, 0x78e785f09f7878fdULL, 0x38ddd870e53838e0ULL, 0x8c148605988c8c0aULL, + 0xd1c6b2bf17d1d163ULL, 0xa5410b57e4a5a5aeULL, 0xe2434dd9a1e2e2afULL, 0x612ff8c24e616199ULL, + 0xb3f1457b42b3b3f6ULL, 0x2115a54234212184ULL, 0x9c94d625089c9c4aULL, 0x1ef0663cee1e1e78ULL, + 0x4322528661434311ULL, 0xc776fc93b1c7c73bULL, 0xfcb32be54ffcfcd7ULL, 0x0420140824040410ULL, + 0x51b208a2e3515159ULL, 0x99bcc72f2599995eULL, 0x6d4fc4da226d6da9ULL, 0x0d68391a650d0d34ULL, + 0xfa8335e979fafacfULL, 0xdfb684a369dfdf5bULL, 0x7ed79bfca97e7ee5ULL, 0x243db44819242490ULL, + 0x3bc5d776fe3b3becULL, 0xab313d4b9aabab96ULL, 0xce3ed181f0cece1fULL, 0x1188552299111144ULL, + 0x8f0c8903838f8f06ULL, 0x4e4a6b9c044e4e25ULL, 0xb7d1517366b7b7e6ULL, 0xeb0b60cbe0ebeb8bULL, + 0x3cfdcc78c13c3cf0ULL, 0x817cbf1ffd81813eULL, 0x94d4fe354094946aULL, 0xf7eb0cf31cf7f7fbULL, + 0xb9a1676f18b9b9deULL, 0x13985f268b13134cULL, 0x2c7d9c58512c2cb0ULL, 0xd3d6b8bb05d3d36bULL, + 0xe76b5cd38ce7e7bbULL, 0x6e57cbdc396e6ea5ULL, 0xc46ef395aac4c437ULL, 0x03180f061b03030cULL, + 0x568a13acdc565645ULL, 0x441a49885e44440dULL, 0x7fdf9efea07f7fe1ULL, 0xa921374f88a9a99eULL, + 0x2a4d8254672a2aa8ULL, 0xbbb16d6b0abbbbd6ULL, 0xc146e29f87c1c123ULL, 0x53a202a6f1535351ULL, + 0xdcae8ba572dcdc57ULL, 0x0b582716530b0b2cULL, 0x9d9cd327019d9d4eULL, 0x6c47c1d82b6c6cadULL, + 0x3195f562a43131c4ULL, 0x7487b9e8f37474cdULL, 0xf6e309f115f6f6ffULL, 0x460a438c4c464605ULL, + 0xac092645a5acac8aULL, 0x893c970fb589891eULL, 0x14a04428b4141450ULL, 0xe15b42dfbae1e1a3ULL, + 0x16b04e2ca6161658ULL, 0x3acdd274f73a3ae8ULL, 0x696fd0d2066969b9ULL, 0x09482d1241090924ULL, + 0x70a7ade0d77070ddULL, 0xb6d954716fb6b6e2ULL, 0xd0ceb7bd1ed0d067ULL, 0xed3b7ec7d6eded93ULL, + 0xcc2edb85e2cccc17ULL, 0x422a578468424215ULL, 0x98b4c22d2c98985aULL, 0xa4490e55eda4a4aaULL, + 0x285d8850752828a0ULL, 0x5cda31b8865c5c6dULL, 0xf8933fed6bf8f8c7ULL, 0x8644a411c2868622ULL, + }; + + const UInt64 C6[256] = { + 0x6018c07830d81818ULL, 0x8c2305af46262323ULL, 0x3fc67ef991b8c6c6ULL, 0x87e8136fcdfbe8e8ULL, + 0x26874ca113cb8787ULL, 0xdab8a9626d11b8b8ULL, 0x0401080502090101ULL, 0x214f426e9e0d4f4fULL, + 0xd836adee6c9b3636ULL, 0xa2a6590451ffa6a6ULL, 0x6fd2debdb90cd2d2ULL, 0xf3f5fb06f70ef5f5ULL, + 0xf979ef80f2967979ULL, 0xa16f5fcede306f6fULL, 0x7e91fcef3f6d9191ULL, 0x5552aa07a4f85252ULL, + 0x9d6027fdc0476060ULL, 0xcabc89766535bcbcULL, 0x569baccd2b379b9bULL, 0x028e048c018a8e8eULL, + 0xb6a371155bd2a3a3ULL, 0x300c603c186c0c0cULL, 0xf17bff8af6847b7bULL, 0xd435b5e16a803535ULL, + 0x741de8693af51d1dULL, 0xa7e05347ddb3e0e0ULL, 0x7bd7f6acb321d7d7ULL, 0x2fc25eed999cc2c2ULL, + 0xb82e6d965c432e2eULL, 0x314b627a96294b4bULL, 0xdffea321e15dfefeULL, 0x41578216aed55757ULL, + 0x5415a8412abd1515ULL, 0xc1779fb6eee87777ULL, 0xdc37a5eb6e923737ULL, 0xb3e57b56d79ee5e5ULL, + 0x469f8cd923139f9fULL, 0xe7f0d317fd23f0f0ULL, 0x354a6a7f94204a4aULL, 0x4fda9e95a944dadaULL, + 0x7d58fa25b0a25858ULL, 0x03c906ca8fcfc9c9ULL, 0xa429558d527c2929ULL, 0x280a5022145a0a0aULL, + 0xfeb1e14f7f50b1b1ULL, 0xbaa0691a5dc9a0a0ULL, 0xb16b7fdad6146b6bULL, 0x2e855cab17d98585ULL, + 0xcebd8173673cbdbdULL, 0x695dd234ba8f5d5dULL, 0x4010805020901010ULL, 0xf7f4f303f507f4f4ULL, + 0x0bcb16c08bddcbcbULL, 0xf83eedc67cd33e3eULL, 0x140528110a2d0505ULL, 0x81671fe6ce786767ULL, + 0xb7e47353d597e4e4ULL, 0x9c2725bb4e022727ULL, 0x1941325882734141ULL, 0x168b2c9d0ba78b8bULL, + 0xa6a7510153f6a7a7ULL, 0xe97dcf94fab27d7dULL, 0x6e95dcfb37499595ULL, 0x47d88e9fad56d8d8ULL, + 0xcbfb8b30eb70fbfbULL, 0x9fee2371c1cdeeeeULL, 0xed7cc791f8bb7c7cULL, 0x856617e3cc716666ULL, + 0x53dda68ea77bddddULL, 0x5c17b84b2eaf1717ULL, 0x014702468e454747ULL, 0x429e84dc211a9e9eULL, + 0x0fca1ec589d4cacaULL, 0xb42d75995a582d2dULL, 0xc6bf9179632ebfbfULL, 0x1c07381b0e3f0707ULL, + 0x8ead012347acadadULL, 0x755aea2fb4b05a5aULL, 0x36836cb51bef8383ULL, 0xcc3385ff66b63333ULL, + 0x91633ff2c65c6363ULL, 0x0802100a04120202ULL, 0x92aa39384993aaaaULL, 0xd971afa8e2de7171ULL, + 0x07c80ecf8dc6c8c8ULL, 0x6419c87d32d11919ULL, 0x39497270923b4949ULL, 0x43d9869aaf5fd9d9ULL, + 0xeff2c31df931f2f2ULL, 0xabe34b48dba8e3e3ULL, 0x715be22ab6b95b5bULL, 0x1a8834920dbc8888ULL, + 0x529aa4c8293e9a9aULL, 0x98262dbe4c0b2626ULL, 0xc8328dfa64bf3232ULL, 0xfab0e94a7d59b0b0ULL, + 0x83e91b6acff2e9e9ULL, 0x3c0f78331e770f0fULL, 0x73d5e6a6b733d5d5ULL, 0x3a8074ba1df48080ULL, + 0xc2be997c6127bebeULL, 0x13cd26de87ebcdcdULL, 0xd034bde468893434ULL, 0x3d487a7590324848ULL, + 0xdbffab24e354ffffULL, 0xf57af78ff48d7a7aULL, 0x7a90f4ea3d649090ULL, 0x615fc23ebe9d5f5fULL, + 0x80201da0403d2020ULL, 0xbd6867d5d00f6868ULL, 0x681ad07234ca1a1aULL, 0x82ae192c41b7aeaeULL, + 0xeab4c95e757db4b4ULL, 0x4d549a19a8ce5454ULL, 0x7693ece53b7f9393ULL, 0x88220daa442f2222ULL, + 0x8d6407e9c8636464ULL, 0xe3f1db12ff2af1f1ULL, 0xd173bfa2e6cc7373ULL, 0x4812905a24821212ULL, + 0x1d403a5d807a4040ULL, 0x2008402810480808ULL, 0x2bc356e89b95c3c3ULL, 0x97ec337bc5dfececULL, + 0x4bdb9690ab4ddbdbULL, 0xbea1611f5fc0a1a1ULL, 0x0e8d1c8307918d8dULL, 0xf43df5c97ac83d3dULL, + 0x6697ccf1335b9797ULL, 0x0000000000000000ULL, 0x1bcf36d483f9cfcfULL, 0xac2b4587566e2b2bULL, + 0xc57697b3ece17676ULL, 0x328264b019e68282ULL, 0x7fd6fea9b128d6d6ULL, 0x6c1bd87736c31b1bULL, + 0xeeb5c15b7774b5b5ULL, 0x86af112943beafafULL, 0xb56a77dfd41d6a6aULL, 0x5d50ba0da0ea5050ULL, + 0x0945124c8a574545ULL, 0xebf3cb18fb38f3f3ULL, 0xc0309df060ad3030ULL, 0x9bef2b74c3c4efefULL, + 0xfc3fe5c37eda3f3fULL, 0x4955921caac75555ULL, 0xb2a2791059dba2a2ULL, 0x8fea0365c9e9eaeaULL, + 0x89650fecca6a6565ULL, 0xd2bab9686903babaULL, 0xbc2f65935e4a2f2fULL, 0x27c04ee79d8ec0c0ULL, + 0x5fdebe81a160dedeULL, 0x701ce06c38fc1c1cULL, 0xd3fdbb2ee746fdfdULL, 0x294d52649a1f4d4dULL, + 0x7292e4e039769292ULL, 0xc9758fbceafa7575ULL, 0x1806301e0c360606ULL, 0x128a249809ae8a8aULL, + 0xf2b2f940794bb2b2ULL, 0xbfe66359d185e6e6ULL, 0x380e70361c7e0e0eULL, 0x7c1ff8633ee71f1fULL, + 0x956237f7c4556262ULL, 0x77d4eea3b53ad4d4ULL, 0x9aa829324d81a8a8ULL, 0x6296c4f431529696ULL, + 0xc3f99b3aef62f9f9ULL, 0x33c566f697a3c5c5ULL, 0x942535b14a102525ULL, 0x7959f220b2ab5959ULL, + 0x2a8454ae15d08484ULL, 0xd572b7a7e4c57272ULL, 0xe439d5dd72ec3939ULL, 0x2d4c5a6198164c4cULL, + 0x655eca3bbc945e5eULL, 0xfd78e785f09f7878ULL, 0xe038ddd870e53838ULL, 0x0a8c148605988c8cULL, + 0x63d1c6b2bf17d1d1ULL, 0xaea5410b57e4a5a5ULL, 0xafe2434dd9a1e2e2ULL, 0x99612ff8c24e6161ULL, + 0xf6b3f1457b42b3b3ULL, 0x842115a542342121ULL, 0x4a9c94d625089c9cULL, 0x781ef0663cee1e1eULL, + 0x1143225286614343ULL, 0x3bc776fc93b1c7c7ULL, 0xd7fcb32be54ffcfcULL, 0x1004201408240404ULL, + 0x5951b208a2e35151ULL, 0x5e99bcc72f259999ULL, 0xa96d4fc4da226d6dULL, 0x340d68391a650d0dULL, + 0xcffa8335e979fafaULL, 0x5bdfb684a369dfdfULL, 0xe57ed79bfca97e7eULL, 0x90243db448192424ULL, + 0xec3bc5d776fe3b3bULL, 0x96ab313d4b9aababULL, 0x1fce3ed181f0ceceULL, 0x4411885522991111ULL, + 0x068f0c8903838f8fULL, 0x254e4a6b9c044e4eULL, 0xe6b7d1517366b7b7ULL, 0x8beb0b60cbe0ebebULL, + 0xf03cfdcc78c13c3cULL, 0x3e817cbf1ffd8181ULL, 0x6a94d4fe35409494ULL, 0xfbf7eb0cf31cf7f7ULL, + 0xdeb9a1676f18b9b9ULL, 0x4c13985f268b1313ULL, 0xb02c7d9c58512c2cULL, 0x6bd3d6b8bb05d3d3ULL, + 0xbbe76b5cd38ce7e7ULL, 0xa56e57cbdc396e6eULL, 0x37c46ef395aac4c4ULL, 0x0c03180f061b0303ULL, + 0x45568a13acdc5656ULL, 0x0d441a49885e4444ULL, 0xe17fdf9efea07f7fULL, 0x9ea921374f88a9a9ULL, + 0xa82a4d8254672a2aULL, 0xd6bbb16d6b0abbbbULL, 0x23c146e29f87c1c1ULL, 0x5153a202a6f15353ULL, + 0x57dcae8ba572dcdcULL, 0x2c0b582716530b0bULL, 0x4e9d9cd327019d9dULL, 0xad6c47c1d82b6c6cULL, + 0xc43195f562a43131ULL, 0xcd7487b9e8f37474ULL, 0xfff6e309f115f6f6ULL, 0x05460a438c4c4646ULL, + 0x8aac092645a5acacULL, 0x1e893c970fb58989ULL, 0x5014a04428b41414ULL, 0xa3e15b42dfbae1e1ULL, + 0x5816b04e2ca61616ULL, 0xe83acdd274f73a3aULL, 0xb9696fd0d2066969ULL, 0x2409482d12410909ULL, + 0xdd70a7ade0d77070ULL, 0xe2b6d954716fb6b6ULL, 0x67d0ceb7bd1ed0d0ULL, 0x93ed3b7ec7d6ededULL, + 0x17cc2edb85e2ccccULL, 0x15422a5784684242ULL, 0x5a98b4c22d2c9898ULL, 0xaaa4490e55eda4a4ULL, + 0xa0285d8850752828ULL, 0x6d5cda31b8865c5cULL, 0xc7f8933fed6bf8f8ULL, 0x228644a411c28686ULL, + }; + + const UInt64 C7[256] = { + 0x186018c07830d818ULL, 0x238c2305af462623ULL, 0xc63fc67ef991b8c6ULL, 0xe887e8136fcdfbe8ULL, + 0x8726874ca113cb87ULL, 0xb8dab8a9626d11b8ULL, 0x0104010805020901ULL, 0x4f214f426e9e0d4fULL, + 0x36d836adee6c9b36ULL, 0xa6a2a6590451ffa6ULL, 0xd26fd2debdb90cd2ULL, 0xf5f3f5fb06f70ef5ULL, + 0x79f979ef80f29679ULL, 0x6fa16f5fcede306fULL, 0x917e91fcef3f6d91ULL, 0x525552aa07a4f852ULL, + 0x609d6027fdc04760ULL, 0xbccabc89766535bcULL, 0x9b569baccd2b379bULL, 0x8e028e048c018a8eULL, + 0xa3b6a371155bd2a3ULL, 0x0c300c603c186c0cULL, 0x7bf17bff8af6847bULL, 0x35d435b5e16a8035ULL, + 0x1d741de8693af51dULL, 0xe0a7e05347ddb3e0ULL, 0xd77bd7f6acb321d7ULL, 0xc22fc25eed999cc2ULL, + 0x2eb82e6d965c432eULL, 0x4b314b627a96294bULL, 0xfedffea321e15dfeULL, 0x5741578216aed557ULL, + 0x155415a8412abd15ULL, 0x77c1779fb6eee877ULL, 0x37dc37a5eb6e9237ULL, 0xe5b3e57b56d79ee5ULL, + 0x9f469f8cd923139fULL, 0xf0e7f0d317fd23f0ULL, 0x4a354a6a7f94204aULL, 0xda4fda9e95a944daULL, + 0x587d58fa25b0a258ULL, 0xc903c906ca8fcfc9ULL, 0x29a429558d527c29ULL, 0x0a280a5022145a0aULL, + 0xb1feb1e14f7f50b1ULL, 0xa0baa0691a5dc9a0ULL, 0x6bb16b7fdad6146bULL, 0x852e855cab17d985ULL, + 0xbdcebd8173673cbdULL, 0x5d695dd234ba8f5dULL, 0x1040108050209010ULL, 0xf4f7f4f303f507f4ULL, + 0xcb0bcb16c08bddcbULL, 0x3ef83eedc67cd33eULL, 0x05140528110a2d05ULL, 0x6781671fe6ce7867ULL, + 0xe4b7e47353d597e4ULL, 0x279c2725bb4e0227ULL, 0x4119413258827341ULL, 0x8b168b2c9d0ba78bULL, + 0xa7a6a7510153f6a7ULL, 0x7de97dcf94fab27dULL, 0x956e95dcfb374995ULL, 0xd847d88e9fad56d8ULL, + 0xfbcbfb8b30eb70fbULL, 0xee9fee2371c1cdeeULL, 0x7ced7cc791f8bb7cULL, 0x66856617e3cc7166ULL, + 0xdd53dda68ea77bddULL, 0x175c17b84b2eaf17ULL, 0x47014702468e4547ULL, 0x9e429e84dc211a9eULL, + 0xca0fca1ec589d4caULL, 0x2db42d75995a582dULL, 0xbfc6bf9179632ebfULL, 0x071c07381b0e3f07ULL, + 0xad8ead012347acadULL, 0x5a755aea2fb4b05aULL, 0x8336836cb51bef83ULL, 0x33cc3385ff66b633ULL, + 0x6391633ff2c65c63ULL, 0x020802100a041202ULL, 0xaa92aa39384993aaULL, 0x71d971afa8e2de71ULL, + 0xc807c80ecf8dc6c8ULL, 0x196419c87d32d119ULL, 0x4939497270923b49ULL, 0xd943d9869aaf5fd9ULL, + 0xf2eff2c31df931f2ULL, 0xe3abe34b48dba8e3ULL, 0x5b715be22ab6b95bULL, 0x881a8834920dbc88ULL, + 0x9a529aa4c8293e9aULL, 0x2698262dbe4c0b26ULL, 0x32c8328dfa64bf32ULL, 0xb0fab0e94a7d59b0ULL, + 0xe983e91b6acff2e9ULL, 0x0f3c0f78331e770fULL, 0xd573d5e6a6b733d5ULL, 0x803a8074ba1df480ULL, + 0xbec2be997c6127beULL, 0xcd13cd26de87ebcdULL, 0x34d034bde4688934ULL, 0x483d487a75903248ULL, + 0xffdbffab24e354ffULL, 0x7af57af78ff48d7aULL, 0x907a90f4ea3d6490ULL, 0x5f615fc23ebe9d5fULL, + 0x2080201da0403d20ULL, 0x68bd6867d5d00f68ULL, 0x1a681ad07234ca1aULL, 0xae82ae192c41b7aeULL, + 0xb4eab4c95e757db4ULL, 0x544d549a19a8ce54ULL, 0x937693ece53b7f93ULL, 0x2288220daa442f22ULL, + 0x648d6407e9c86364ULL, 0xf1e3f1db12ff2af1ULL, 0x73d173bfa2e6cc73ULL, 0x124812905a248212ULL, + 0x401d403a5d807a40ULL, 0x0820084028104808ULL, 0xc32bc356e89b95c3ULL, 0xec97ec337bc5dfecULL, + 0xdb4bdb9690ab4ddbULL, 0xa1bea1611f5fc0a1ULL, 0x8d0e8d1c8307918dULL, 0x3df43df5c97ac83dULL, + 0x976697ccf1335b97ULL, 0x0000000000000000ULL, 0xcf1bcf36d483f9cfULL, 0x2bac2b4587566e2bULL, + 0x76c57697b3ece176ULL, 0x82328264b019e682ULL, 0xd67fd6fea9b128d6ULL, 0x1b6c1bd87736c31bULL, + 0xb5eeb5c15b7774b5ULL, 0xaf86af112943beafULL, 0x6ab56a77dfd41d6aULL, 0x505d50ba0da0ea50ULL, + 0x450945124c8a5745ULL, 0xf3ebf3cb18fb38f3ULL, 0x30c0309df060ad30ULL, 0xef9bef2b74c3c4efULL, + 0x3ffc3fe5c37eda3fULL, 0x554955921caac755ULL, 0xa2b2a2791059dba2ULL, 0xea8fea0365c9e9eaULL, + 0x6589650fecca6a65ULL, 0xbad2bab9686903baULL, 0x2fbc2f65935e4a2fULL, 0xc027c04ee79d8ec0ULL, + 0xde5fdebe81a160deULL, 0x1c701ce06c38fc1cULL, 0xfdd3fdbb2ee746fdULL, 0x4d294d52649a1f4dULL, + 0x927292e4e0397692ULL, 0x75c9758fbceafa75ULL, 0x061806301e0c3606ULL, 0x8a128a249809ae8aULL, + 0xb2f2b2f940794bb2ULL, 0xe6bfe66359d185e6ULL, 0x0e380e70361c7e0eULL, 0x1f7c1ff8633ee71fULL, + 0x62956237f7c45562ULL, 0xd477d4eea3b53ad4ULL, 0xa89aa829324d81a8ULL, 0x966296c4f4315296ULL, + 0xf9c3f99b3aef62f9ULL, 0xc533c566f697a3c5ULL, 0x25942535b14a1025ULL, 0x597959f220b2ab59ULL, + 0x842a8454ae15d084ULL, 0x72d572b7a7e4c572ULL, 0x39e439d5dd72ec39ULL, 0x4c2d4c5a6198164cULL, + 0x5e655eca3bbc945eULL, 0x78fd78e785f09f78ULL, 0x38e038ddd870e538ULL, 0x8c0a8c148605988cULL, + 0xd163d1c6b2bf17d1ULL, 0xa5aea5410b57e4a5ULL, 0xe2afe2434dd9a1e2ULL, 0x6199612ff8c24e61ULL, + 0xb3f6b3f1457b42b3ULL, 0x21842115a5423421ULL, 0x9c4a9c94d625089cULL, 0x1e781ef0663cee1eULL, + 0x4311432252866143ULL, 0xc73bc776fc93b1c7ULL, 0xfcd7fcb32be54ffcULL, 0x0410042014082404ULL, + 0x515951b208a2e351ULL, 0x995e99bcc72f2599ULL, 0x6da96d4fc4da226dULL, 0x0d340d68391a650dULL, + 0xfacffa8335e979faULL, 0xdf5bdfb684a369dfULL, 0x7ee57ed79bfca97eULL, 0x2490243db4481924ULL, + 0x3bec3bc5d776fe3bULL, 0xab96ab313d4b9aabULL, 0xce1fce3ed181f0ceULL, 0x1144118855229911ULL, + 0x8f068f0c8903838fULL, 0x4e254e4a6b9c044eULL, 0xb7e6b7d1517366b7ULL, 0xeb8beb0b60cbe0ebULL, + 0x3cf03cfdcc78c13cULL, 0x813e817cbf1ffd81ULL, 0x946a94d4fe354094ULL, 0xf7fbf7eb0cf31cf7ULL, + 0xb9deb9a1676f18b9ULL, 0x134c13985f268b13ULL, 0x2cb02c7d9c58512cULL, 0xd36bd3d6b8bb05d3ULL, + 0xe7bbe76b5cd38ce7ULL, 0x6ea56e57cbdc396eULL, 0xc437c46ef395aac4ULL, 0x030c03180f061b03ULL, + 0x5645568a13acdc56ULL, 0x440d441a49885e44ULL, 0x7fe17fdf9efea07fULL, 0xa99ea921374f88a9ULL, + 0x2aa82a4d8254672aULL, 0xbbd6bbb16d6b0abbULL, 0xc123c146e29f87c1ULL, 0x535153a202a6f153ULL, + 0xdc57dcae8ba572dcULL, 0x0b2c0b582716530bULL, 0x9d4e9d9cd327019dULL, 0x6cad6c47c1d82b6cULL, + 0x31c43195f562a431ULL, 0x74cd7487b9e8f374ULL, 0xf6fff6e309f115f6ULL, 0x4605460a438c4c46ULL, + 0xac8aac092645a5acULL, 0x891e893c970fb589ULL, 0x145014a04428b414ULL, 0xe1a3e15b42dfbae1ULL, + 0x165816b04e2ca616ULL, 0x3ae83acdd274f73aULL, 0x69b9696fd0d20669ULL, 0x092409482d124109ULL, + 0x70dd70a7ade0d770ULL, 0xb6e2b6d954716fb6ULL, 0xd067d0ceb7bd1ed0ULL, 0xed93ed3b7ec7d6edULL, + 0xcc17cc2edb85e2ccULL, 0x4215422a57846842ULL, 0x985a98b4c22d2c98ULL, 0xa4aaa4490e55eda4ULL, + 0x28a0285d88507528ULL, 0x5c6d5cda31b8865cULL, 0xf8c7f8933fed6bf8ULL, 0x86228644a411c286ULL, + }; + + const UInt64 rc[R + 1] = { + 0x0000000000000000ULL, + 0x1823c6e887b8014fULL, + 0x36a6d2f5796f9152ULL, + 0x60bc9b8ea30c7b35ULL, + 0x1de0d7c22e4bfe57ULL, + 0x157737e59ff04adaULL, + 0x58c9290ab1a06b85ULL, + 0xbd5d10f4cb3e0567ULL, + 0xe427418ba77d95d8ULL, + 0xfbee7c66dd17479eULL, + 0xca2dbf07ad5a8333ULL, + }; + + void processBuffer(HashWhirlpool_state* wstate) + { + int i, r; + UInt64 K[8]; // the round key + UInt64 block[8]; // mu(buffer) + UInt64 state[8]; // the cipher state + UInt64 L[8]; + UInt8 *buffer = wstate->buffer; + + // map the buffer to a block + for (i = 0; i < 8; i++, buffer += 8) + { + block[i] = + ((static_cast(buffer[0]) ) << 56) ^ + ((static_cast(buffer[1]) & 0xffL) << 48) ^ + ((static_cast(buffer[2]) & 0xffL) << 40) ^ + ((static_cast(buffer[3]) & 0xffL) << 32) ^ + ((static_cast(buffer[4]) & 0xffL) << 24) ^ + ((static_cast(buffer[5]) & 0xffL) << 16) ^ + ((static_cast(buffer[6]) & 0xffL) << 8) ^ + ((static_cast(buffer[7]) & 0xffL) ); + } + + // compute and apply K^0 to the cipher state + state[0] = block[0] ^ (K[0] = wstate->hash[0]); + state[1] = block[1] ^ (K[1] = wstate->hash[1]); + state[2] = block[2] ^ (K[2] = wstate->hash[2]); + state[3] = block[3] ^ (K[3] = wstate->hash[3]); + state[4] = block[4] ^ (K[4] = wstate->hash[4]); + state[5] = block[5] ^ (K[5] = wstate->hash[5]); + state[6] = block[6] ^ (K[6] = wstate->hash[6]); + state[7] = block[7] ^ (K[7] = wstate->hash[7]); + + // iterate over all rounds + for (r = 1; r <= R; r++) + { + // compute K^r from K^{r-1} + L[0] = + C0[static_cast(K[0] >> 56) ] ^ + C1[static_cast(K[7] >> 48) & 0xff] ^ + C2[static_cast(K[6] >> 40) & 0xff] ^ + C3[static_cast(K[5] >> 32) & 0xff] ^ + C4[static_cast(K[4] >> 24) & 0xff] ^ + C5[static_cast(K[3] >> 16) & 0xff] ^ + C6[static_cast(K[2] >> 8) & 0xff] ^ + C7[static_cast(K[1] ) & 0xff] ^ + rc[r]; + L[1] = + C0[static_cast(K[1] >> 56) ] ^ + C1[static_cast(K[0] >> 48) & 0xff] ^ + C2[static_cast(K[7] >> 40) & 0xff] ^ + C3[static_cast(K[6] >> 32) & 0xff] ^ + C4[static_cast(K[5] >> 24) & 0xff] ^ + C5[static_cast(K[4] >> 16) & 0xff] ^ + C6[static_cast(K[3] >> 8) & 0xff] ^ + C7[static_cast(K[2] ) & 0xff]; + L[2] = + C0[static_cast(K[2] >> 56) ] ^ + C1[static_cast(K[1] >> 48) & 0xff] ^ + C2[static_cast(K[0] >> 40) & 0xff] ^ + C3[static_cast(K[7] >> 32) & 0xff] ^ + C4[static_cast(K[6] >> 24) & 0xff] ^ + C5[static_cast(K[5] >> 16) & 0xff] ^ + C6[static_cast(K[4] >> 8) & 0xff] ^ + C7[static_cast(K[3] ) & 0xff]; + L[3] = + C0[static_cast(K[3] >> 56) ] ^ + C1[static_cast(K[2] >> 48) & 0xff] ^ + C2[static_cast(K[1] >> 40) & 0xff] ^ + C3[static_cast(K[0] >> 32) & 0xff] ^ + C4[static_cast(K[7] >> 24) & 0xff] ^ + C5[static_cast(K[6] >> 16) & 0xff] ^ + C6[static_cast(K[5] >> 8) & 0xff] ^ + C7[static_cast(K[4] ) & 0xff]; + L[4] = + C0[static_cast(K[4] >> 56) ] ^ + C1[static_cast(K[3] >> 48) & 0xff] ^ + C2[static_cast(K[2] >> 40) & 0xff] ^ + C3[static_cast(K[1] >> 32) & 0xff] ^ + C4[static_cast(K[0] >> 24) & 0xff] ^ + C5[static_cast(K[7] >> 16) & 0xff] ^ + C6[static_cast(K[6] >> 8) & 0xff] ^ + C7[static_cast(K[5] ) & 0xff]; + L[5] = + C0[static_cast(K[5] >> 56) ] ^ + C1[static_cast(K[4] >> 48) & 0xff] ^ + C2[static_cast(K[3] >> 40) & 0xff] ^ + C3[static_cast(K[2] >> 32) & 0xff] ^ + C4[static_cast(K[1] >> 24) & 0xff] ^ + C5[static_cast(K[0] >> 16) & 0xff] ^ + C6[static_cast(K[7] >> 8) & 0xff] ^ + C7[static_cast(K[6] ) & 0xff]; + L[6] = + C0[static_cast(K[6] >> 56) ] ^ + C1[static_cast(K[5] >> 48) & 0xff] ^ + C2[static_cast(K[4] >> 40) & 0xff] ^ + C3[static_cast(K[3] >> 32) & 0xff] ^ + C4[static_cast(K[2] >> 24) & 0xff] ^ + C5[static_cast(K[1] >> 16) & 0xff] ^ + C6[static_cast(K[0] >> 8) & 0xff] ^ + C7[static_cast(K[7] ) & 0xff]; + L[7] = + C0[static_cast(K[7] >> 56) ] ^ + C1[static_cast(K[6] >> 48) & 0xff] ^ + C2[static_cast(K[5] >> 40) & 0xff] ^ + C3[static_cast(K[4] >> 32) & 0xff] ^ + C4[static_cast(K[3] >> 24) & 0xff] ^ + C5[static_cast(K[2] >> 16) & 0xff] ^ + C6[static_cast(K[1] >> 8) & 0xff] ^ + C7[static_cast(K[0] ) & 0xff]; + K[0] = L[0]; + K[1] = L[1]; + K[2] = L[2]; + K[3] = L[3]; + K[4] = L[4]; + K[5] = L[5]; + K[6] = L[6]; + K[7] = L[7]; + + // apply the r-th round transformation + L[0] = + C0[static_cast(state[0] >> 56) ] ^ + C1[static_cast(state[7] >> 48) & 0xff] ^ + C2[static_cast(state[6] >> 40) & 0xff] ^ + C3[static_cast(state[5] >> 32) & 0xff] ^ + C4[static_cast(state[4] >> 24) & 0xff] ^ + C5[static_cast(state[3] >> 16) & 0xff] ^ + C6[static_cast(state[2] >> 8) & 0xff] ^ + C7[static_cast(state[1] ) & 0xff] ^ + K[0]; + L[1] = + C0[static_cast(state[1] >> 56) ] ^ + C1[static_cast(state[0] >> 48) & 0xff] ^ + C2[static_cast(state[7] >> 40) & 0xff] ^ + C3[static_cast(state[6] >> 32) & 0xff] ^ + C4[static_cast(state[5] >> 24) & 0xff] ^ + C5[static_cast(state[4] >> 16) & 0xff] ^ + C6[static_cast(state[3] >> 8) & 0xff] ^ + C7[static_cast(state[2] ) & 0xff] ^ + K[1]; + L[2] = + C0[static_cast(state[2] >> 56) ] ^ + C1[static_cast(state[1] >> 48) & 0xff] ^ + C2[static_cast(state[0] >> 40) & 0xff] ^ + C3[static_cast(state[7] >> 32) & 0xff] ^ + C4[static_cast(state[6] >> 24) & 0xff] ^ + C5[static_cast(state[5] >> 16) & 0xff] ^ + C6[static_cast(state[4] >> 8) & 0xff] ^ + C7[static_cast(state[3] ) & 0xff] ^ + K[2]; + L[3] = + C0[static_cast(state[3] >> 56) ] ^ + C1[static_cast(state[2] >> 48) & 0xff] ^ + C2[static_cast(state[1] >> 40) & 0xff] ^ + C3[static_cast(state[0] >> 32) & 0xff] ^ + C4[static_cast(state[7] >> 24) & 0xff] ^ + C5[static_cast(state[6] >> 16) & 0xff] ^ + C6[static_cast(state[5] >> 8) & 0xff] ^ + C7[static_cast(state[4] ) & 0xff] ^ + K[3]; + L[4] = + C0[static_cast(state[4] >> 56) ] ^ + C1[static_cast(state[3] >> 48) & 0xff] ^ + C2[static_cast(state[2] >> 40) & 0xff] ^ + C3[static_cast(state[1] >> 32) & 0xff] ^ + C4[static_cast(state[0] >> 24) & 0xff] ^ + C5[static_cast(state[7] >> 16) & 0xff] ^ + C6[static_cast(state[6] >> 8) & 0xff] ^ + C7[static_cast(state[5] ) & 0xff] ^ + K[4]; + L[5] = + C0[static_cast(state[5] >> 56) ] ^ + C1[static_cast(state[4] >> 48) & 0xff] ^ + C2[static_cast(state[3] >> 40) & 0xff] ^ + C3[static_cast(state[2] >> 32) & 0xff] ^ + C4[static_cast(state[1] >> 24) & 0xff] ^ + C5[static_cast(state[0] >> 16) & 0xff] ^ + C6[static_cast(state[7] >> 8) & 0xff] ^ + C7[static_cast(state[6] ) & 0xff] ^ + K[5]; + L[6] = + C0[static_cast(state[6] >> 56) ] ^ + C1[static_cast(state[5] >> 48) & 0xff] ^ + C2[static_cast(state[4] >> 40) & 0xff] ^ + C3[static_cast(state[3] >> 32) & 0xff] ^ + C4[static_cast(state[2] >> 24) & 0xff] ^ + C5[static_cast(state[1] >> 16) & 0xff] ^ + C6[static_cast(state[0] >> 8) & 0xff] ^ + C7[static_cast(state[7] ) & 0xff] ^ + K[6]; + L[7] = + C0[static_cast(state[7] >> 56) ] ^ + C1[static_cast(state[6] >> 48) & 0xff] ^ + C2[static_cast(state[5] >> 40) & 0xff] ^ + C3[static_cast(state[4] >> 32) & 0xff] ^ + C4[static_cast(state[3] >> 24) & 0xff] ^ + C5[static_cast(state[2] >> 16) & 0xff] ^ + C6[static_cast(state[1] >> 8) & 0xff] ^ + C7[static_cast(state[0] ) & 0xff] ^ + K[7]; + state[0] = L[0]; + state[1] = L[1]; + state[2] = L[2]; + state[3] = L[3]; + state[4] = L[4]; + state[5] = L[5]; + state[6] = L[6]; + state[7] = L[7]; + } + + // apply the Miyaguchi-Preneel compression function + wstate->hash[0] ^= state[0] ^ block[0]; + wstate->hash[1] ^= state[1] ^ block[1]; + wstate->hash[2] ^= state[2] ^ block[2]; + wstate->hash[3] ^= state[3] ^ block[3]; + wstate->hash[4] ^= state[4] ^ block[4]; + wstate->hash[5] ^= state[5] ^ block[5]; + wstate->hash[6] ^= state[6] ^ block[6]; + wstate->hash[7] ^= state[7] ^ block[7]; + } } - // process data in chunks of 8 bits (a more efficient approach would be to take whole-word chunks) - while (len > 8) + HashWhirlpool::HashWhirlpool() { - // N.B. at least source[sourcePos] and source[sourcePos+1] contain data. - // take a byte from the source - b = ((data[sourcePos] << sourceGap) & 0xff) | - ((data[sourcePos + 1] & 0xff) >> (8 - sourceGap)); + m_state = new HashWhirlpool_state; + } - // process this byte - buffer[bufferPos++] |= static_cast(b >> bufferRem); - bufferBits += 8 - bufferRem; // bufferBits = 8*bufferPos; + HashWhirlpool::~HashWhirlpool() + { + delete m_state; + } - if (bufferBits == 512) + void HashWhirlpool::Append(const UInt8* data, unsigned int len) + { + len *= 8; // Whirlpool fonctionne avec une taille en bits + + int sourcePos = 0; /* index of leftmost source UInt8 containing data (1 to 8 bits). */ + int sourceGap = (8 - (static_cast(len) & 7)) & 7; /* space on source[sourcePos]. */ + int bufferRem = m_state->bufferBits & 7; /* occupied bits on buffer[bufferPos]. */ + + UInt32 b; + UInt8* buffer = m_state->buffer; + UInt8* bitLength = m_state->bitLength; + int bufferBits = m_state->bufferBits; + int bufferPos = m_state->bufferPos; + + // tally the length of the added data + UInt64 value = len; + UInt32 carry = 0; + for (int i = 31; i >= 0 && (carry != 0 || value != 0ULL); i--) { + carry += bitLength[i] + (static_cast(value) & 0xff); + bitLength[i] = static_cast(carry); + + carry >>= 8; + value >>= 8; + } + + // process data in chunks of 8 bits (a more efficient approach would be to take whole-word chunks) + while (len > 8) + { + // N.B. at least source[sourcePos] and source[sourcePos+1] contain data. + // take a byte from the source + b = ((data[sourcePos] << sourceGap) & 0xff) | + ((data[sourcePos + 1] & 0xff) >> (8 - sourceGap)); + + // process this byte + buffer[bufferPos++] |= static_cast(b >> bufferRem); + bufferBits += 8 - bufferRem; // bufferBits = 8*bufferPos; + + if (bufferBits == 512) + { + processBuffer(m_state); // process data block + bufferBits = bufferPos = 0; // reset buffer + } + + buffer[bufferPos] = b << (8 - bufferRem); + bufferBits += bufferRem; + + // proceed to remaining data + len -= 8; + sourcePos++; + } + + // now 0 <= sourceBits <= 8; + // furthermore, all data (if any is left) is in source[sourcePos]. + if (len > 0) + { + b = (data[sourcePos] << sourceGap) & 0xff; // bits are left-justified on b. + buffer[bufferPos] |= b >> bufferRem; // process the remaining bits + } + else + b = 0; + + if (bufferRem + len < 8) + // all remaining data fits on buffer[bufferPos], and there still remains some space. + bufferBits += len; + else + { + // buffer[bufferPos] is full + bufferPos++; + bufferBits += 8 - bufferRem; // bufferBits = 8*bufferPos; + len -= 8 - bufferRem; + + // now 0 <= sourceBits < 8; furthermore, all data (if any is left) is in source[sourcePos]. + if (bufferBits == 512) + { + processBuffer(m_state); // process data block + bufferBits = bufferPos = 0; // reset buffer + } + + buffer[bufferPos] = b << (8 - bufferRem); + bufferBits += len; + } + + m_state->bufferBits = bufferBits; + m_state->bufferPos = bufferPos; + } + + void HashWhirlpool::Begin() + { + std::memset(m_state->bitLength, 0, 32); + m_state->bufferBits = m_state->bufferPos = 0; + m_state->buffer[0] = 0; // it's only necessary to cleanup buffer[bufferPos] + for (int i = 0; i < 8; i++) + m_state->hash[i] = 0L; // initial value + } + + HashDigest HashWhirlpool::End() + { + UInt8 result[64]; + + UInt8 *buffer = m_state->buffer; + UInt8 *bitLength = m_state->bitLength; + int bufferBits = m_state->bufferBits; + int bufferPos = m_state->bufferPos; + UInt8 *digest = result; + + // append a '1'-bit + buffer[bufferPos] |= 0x80U >> (bufferBits & 7); + bufferPos++; // all remaining bits on the current UInt8 are set to zero. + + // pad with zero bits to complete (N*WBLOCKBITS - LENGTHBITS) bits: + if (bufferPos > 32) + { + if (bufferPos < 64) + std::memset(&buffer[bufferPos], 0, 64 - bufferPos); + processBuffer(m_state); // process data block - bufferBits = bufferPos = 0; // reset buffer + bufferPos = 0; // reset buffer } - buffer[bufferPos] = b << (8 - bufferRem); - bufferBits += bufferRem; + if (bufferPos < 32) + std::memset(&buffer[bufferPos], 0, 32 - bufferPos); - // proceed to remaining data - len -= 8; - sourcePos++; - } + bufferPos = 32; - // now 0 <= sourceBits <= 8; - // furthermore, all data (if any is left) is in source[sourcePos]. - if (len > 0) - { - b = (data[sourcePos] << sourceGap) & 0xff; // bits are left-justified on b. - buffer[bufferPos] |= b >> bufferRem; // process the remaining bits - } - else - b = 0; - - if (bufferRem + len < 8) - // all remaining data fits on buffer[bufferPos], and there still remains some space. - bufferBits += len; - else - { - // buffer[bufferPos] is full - bufferPos++; - bufferBits += 8 - bufferRem; // bufferBits = 8*bufferPos; - len -= 8 - bufferRem; - - // now 0 <= sourceBits < 8; furthermore, all data (if any is left) is in source[sourcePos]. - if (bufferBits == 512) - { - processBuffer(m_state); // process data block - bufferBits = bufferPos = 0; // reset buffer - } - - buffer[bufferPos] = b << (8 - bufferRem); - bufferBits += len; - } - - m_state->bufferBits = bufferBits; - m_state->bufferPos = bufferPos; -} - -void NzHashWhirlpool::Begin() -{ - std::memset(m_state->bitLength, 0, 32); - m_state->bufferBits = m_state->bufferPos = 0; - m_state->buffer[0] = 0; // it's only necessary to cleanup buffer[bufferPos] - for (int i = 0; i < 8; i++) - m_state->hash[i] = 0L; // initial value -} - -NzHashDigest NzHashWhirlpool::End() -{ - nzUInt8 result[64]; - - nzUInt8 *buffer = m_state->buffer; - nzUInt8 *bitLength = m_state->bitLength; - int bufferBits = m_state->bufferBits; - int bufferPos = m_state->bufferPos; - nzUInt8 *digest = result; - - // append a '1'-bit - buffer[bufferPos] |= 0x80U >> (bufferBits & 7); - bufferPos++; // all remaining bits on the current nzUInt8 are set to zero. - - // pad with zero bits to complete (N*WBLOCKBITS - LENGTHBITS) bits: - if (bufferPos > 32) - { - if (bufferPos < 64) - std::memset(&buffer[bufferPos], 0, 64 - bufferPos); + std::memcpy(&buffer[32], bitLength, 32); // append bit length of hashed data processBuffer(m_state); // process data block - bufferPos = 0; // reset buffer + + // return the completed message digest + for (int i = 0; i < 8; i++) + { + digest[0] = static_cast(m_state->hash[i] >> 56); + digest[1] = static_cast(m_state->hash[i] >> 48); + digest[2] = static_cast(m_state->hash[i] >> 40); + digest[3] = static_cast(m_state->hash[i] >> 32); + digest[4] = static_cast(m_state->hash[i] >> 24); + digest[5] = static_cast(m_state->hash[i] >> 16); + digest[6] = static_cast(m_state->hash[i] >> 8); + digest[7] = static_cast(m_state->hash[i] ); + digest += 8; + } + + m_state->bufferBits = bufferBits; + m_state->bufferPos = bufferPos; + + return HashDigest(GetHashName(), &result[0], 64); } - if (bufferPos < 32) - std::memset(&buffer[bufferPos], 0, 32 - bufferPos); - - bufferPos = 32; - - std::memcpy(&buffer[32], bitLength, 32); // append bit length of hashed data - - processBuffer(m_state); // process data block - - // return the completed message digest - for (int i = 0; i < 8; i++) + unsigned int HashWhirlpool::GetDigestLength() { - digest[0] = static_cast(m_state->hash[i] >> 56); - digest[1] = static_cast(m_state->hash[i] >> 48); - digest[2] = static_cast(m_state->hash[i] >> 40); - digest[3] = static_cast(m_state->hash[i] >> 32); - digest[4] = static_cast(m_state->hash[i] >> 24); - digest[5] = static_cast(m_state->hash[i] >> 16); - digest[6] = static_cast(m_state->hash[i] >> 8); - digest[7] = static_cast(m_state->hash[i] ); - digest += 8; + return 64; } - m_state->bufferBits = bufferBits; - m_state->bufferPos = bufferPos; - - return NzHashDigest(GetHashName(), &result[0], 64); -} - -unsigned int NzHashWhirlpool::GetDigestLength() -{ - return 64; -} - -NzString NzHashWhirlpool::GetHashName() -{ - static NzString hashName = "Whirlpool"; - return hashName; + String HashWhirlpool::GetHashName() + { + static String hashName = "Whirlpool"; + return hashName; + } } diff --git a/src/Nazara/Core/HashDigest.cpp b/src/Nazara/Core/HashDigest.cpp index 4299d7b22..93c23f13c 100644 --- a/src/Nazara/Core/HashDigest.cpp +++ b/src/Nazara/Core/HashDigest.cpp @@ -10,181 +10,184 @@ #include #include -NzHashDigest::NzHashDigest() : -m_digest(nullptr), -m_digestLength(0) +namespace Nz { -} - -NzHashDigest::NzHashDigest(const NzString& hashName, const nzUInt8* digest, unsigned int length) : -m_hashName(hashName), -m_digestLength(length) -{ - if (m_digestLength > 0) + HashDigest::HashDigest() : + m_digest(nullptr), + m_digestLength(0) { - m_digest = new nzUInt8[length]; - std::memcpy(m_digest, digest, length); } - else - m_digest = nullptr; -} -NzHashDigest::NzHashDigest(const NzHashDigest& rhs) : -m_hashName(rhs.m_hashName), -m_digestLength(rhs.m_digestLength) -{ - if (m_digestLength > 0) + HashDigest::HashDigest(const String& hashName, const UInt8* digest, unsigned int length) : + m_hashName(hashName), + m_digestLength(length) { - m_digest = new nzUInt8[m_digestLength]; - std::memcpy(m_digest, rhs.m_digest, m_digestLength); + if (m_digestLength > 0) + { + m_digest = new UInt8[length]; + std::memcpy(m_digest, digest, length); + } + else + m_digest = nullptr; } - else - m_digest = nullptr; -} -NzHashDigest::NzHashDigest(NzHashDigest&& rhs) noexcept : -m_hashName(std::move(rhs.m_hashName)), -m_digest(rhs.m_digest), -m_digestLength(rhs.m_digestLength) -{ - rhs.m_digest = nullptr; - rhs.m_digestLength = 0; -} - -NzHashDigest::~NzHashDigest() -{ - delete[] m_digest; -} - -bool NzHashDigest::IsValid() const -{ - return m_digestLength > 0; -} - -const nzUInt8* NzHashDigest::GetDigest() const -{ - return m_digest; -} - -unsigned int NzHashDigest::GetDigestLength() const -{ - return m_digestLength; -} - -NzString NzHashDigest::GetHashName() const -{ - return m_hashName; -} - -NzString NzHashDigest::ToHex() const -{ - if (m_digestLength == 0) - return NzString(); - - unsigned int length = m_digestLength*2; - - NzString hexOutput(length); - for (unsigned int i = 0; i < m_digestLength; ++i) - std::sprintf(&hexOutput[i*2], "%02x", m_digest[i]); - - return hexOutput; -} - -nzUInt8 NzHashDigest::operator[](unsigned int pos) const -{ - #if NAZARA_CORE_SAFE - if (pos >= m_digestLength) + HashDigest::HashDigest(const HashDigest& rhs) : + m_hashName(rhs.m_hashName), + m_digestLength(rhs.m_digestLength) { - NazaraError("Position out of range"); - return 0; + if (m_digestLength > 0) + { + m_digest = new UInt8[m_digestLength]; + std::memcpy(m_digest, rhs.m_digest, m_digestLength); + } + else + m_digest = nullptr; } - #endif - return m_digest[pos]; -} + HashDigest::HashDigest(HashDigest&& rhs) noexcept : + m_hashName(std::move(rhs.m_hashName)), + m_digest(rhs.m_digest), + m_digestLength(rhs.m_digestLength) + { + rhs.m_digest = nullptr; + rhs.m_digestLength = 0; + } + + HashDigest::~HashDigest() + { + delete[] m_digest; + } + + bool HashDigest::IsValid() const + { + return m_digestLength > 0; + } + + const UInt8* HashDigest::GetDigest() const + { + return m_digest; + } + + unsigned int HashDigest::GetDigestLength() const + { + return m_digestLength; + } + + String HashDigest::GetHashName() const + { + return m_hashName; + } + + String HashDigest::ToHex() const + { + if (m_digestLength == 0) + return String(); + + unsigned int length = m_digestLength*2; + + String hexOutput(length); + for (unsigned int i = 0; i < m_digestLength; ++i) + std::sprintf(&hexOutput[i*2], "%02x", m_digest[i]); + + return hexOutput; + } + + UInt8 HashDigest::operator[](unsigned int pos) const + { + #if NAZARA_CORE_SAFE + if (pos >= m_digestLength) + { + NazaraError("Position out of range"); + return 0; + } + #endif + + return m_digest[pos]; + } + + HashDigest& HashDigest::operator=(const HashDigest& rhs) + { + if (this == &rhs) + return *this; + + m_hashName = rhs.m_hashName; + + m_digestLength = rhs.m_digestLength; + if (m_digestLength > 0) + { + m_digest = new UInt8[m_digestLength]; + std::memcpy(m_digest, rhs.m_digest, m_digestLength); + } + else + m_digest = nullptr; -NzHashDigest& NzHashDigest::operator=(const NzHashDigest& rhs) -{ - if (this == &rhs) return *this; - - m_hashName = rhs.m_hashName; - - m_digestLength = rhs.m_digestLength; - if (m_digestLength > 0) - { - m_digest = new nzUInt8[m_digestLength]; - std::memcpy(m_digest, rhs.m_digest, m_digestLength); } - else - m_digest = nullptr; - return *this; -} - -NzHashDigest& NzHashDigest::operator=(NzHashDigest&& rhs) noexcept -{ - std::swap(m_hashName, rhs.m_hashName); - std::swap(m_digest, rhs.m_digest); - std::swap(m_digestLength, rhs.m_digestLength); - - return *this; -} - -bool NzHashDigest::operator==(const NzHashDigest& rhs) const -{ - if (m_digest == nullptr || rhs.m_digest == nullptr) - return m_digest == rhs.m_digest; - - if (m_digestLength != rhs.m_digestLength) - return false; - - return m_hashName == rhs.m_hashName && std::memcmp(m_digest, rhs.m_digest, m_digestLength) == 0; -} - -bool NzHashDigest::operator!=(const NzHashDigest& rhs) const -{ - return !operator==(rhs); -} - -bool NzHashDigest::operator<(const NzHashDigest& rhs) const -{ - if (rhs.m_digest == nullptr) - return false; - - if (m_digest == nullptr) - return true; - - int cmp = NzString::Compare(m_hashName, rhs.m_hashName); - if (cmp == 0) + HashDigest& HashDigest::operator=(HashDigest&& rhs) noexcept { - cmp = std::memcmp(m_digest, rhs.m_digest, std::min(m_digestLength, rhs.m_digestLength)); + std::swap(m_hashName, rhs.m_hashName); + std::swap(m_digest, rhs.m_digest); + std::swap(m_digestLength, rhs.m_digestLength); + return *this; + } + + bool HashDigest::operator==(const HashDigest& rhs) const + { + if (m_digest == nullptr || rhs.m_digest == nullptr) + return m_digest == rhs.m_digest; + + if (m_digestLength != rhs.m_digestLength) + return false; + + return m_hashName == rhs.m_hashName && std::memcmp(m_digest, rhs.m_digest, m_digestLength) == 0; + } + + bool HashDigest::operator!=(const HashDigest& rhs) const + { + return !operator==(rhs); + } + + bool HashDigest::operator<(const HashDigest& rhs) const + { + if (rhs.m_digest == nullptr) + return false; + + if (m_digest == nullptr) + return true; + + int cmp = String::Compare(m_hashName, rhs.m_hashName); if (cmp == 0) - return m_digestLength < rhs.m_digestLength; + { + cmp = std::memcmp(m_digest, rhs.m_digest, std::min(m_digestLength, rhs.m_digestLength)); + + if (cmp == 0) + return m_digestLength < rhs.m_digestLength; + else + return cmp < 0; + } else return cmp < 0; } - else - return cmp < 0; + + bool HashDigest::operator<=(const HashDigest& rhs) const + { + return !rhs.operator<(*this); + } + + bool HashDigest::operator>(const HashDigest& rhs) const + { + return rhs.operator<(*this); + } + + bool HashDigest::operator>=(const HashDigest& rhs) const + { + return !operator<(rhs); + } } -bool NzHashDigest::operator<=(const NzHashDigest& rhs) const -{ - return !rhs.operator<(*this); -} - -bool NzHashDigest::operator>(const NzHashDigest& rhs) const -{ - return rhs.operator<(*this); -} - -bool NzHashDigest::operator>=(const NzHashDigest& rhs) const -{ - return !operator<(rhs); -} - -std::ostream& operator<<(std::ostream& out, const NzHashDigest& hashstring) +std::ostream& operator<<(std::ostream& out, const Nz::HashDigest& hashstring) { out << hashstring.ToHex(); return out; diff --git a/src/Nazara/Core/Hashable.cpp b/src/Nazara/Core/Hashable.cpp index 6b3f1e074..b3d594f10 100644 --- a/src/Nazara/Core/Hashable.cpp +++ b/src/Nazara/Core/Hashable.cpp @@ -6,16 +6,19 @@ #include #include -NzHashable::~NzHashable() = default; - -NzHashDigest NzHashable::GetHash(nzHash hash) const +namespace Nz { - NzHash h(hash); - return h.Hash(*this); -} + Hashable::~Hashable() = default; -NzHashDigest NzHashable::GetHash(NzAbstractHash* impl) const -{ - NzHash h(impl); - return h.Hash(*this); + HashDigest Hashable::GetHash(HashType hash) const + { + Hash h(hash); + return h.Process(*this); + } + + HashDigest Hashable::GetHash(AbstractHash* impl) const + { + Hash h(impl); + return h.Process(*this); + } } diff --git a/src/Nazara/Core/InputStream.cpp b/src/Nazara/Core/InputStream.cpp index cd231bebf..aa62e8114 100644 --- a/src/Nazara/Core/InputStream.cpp +++ b/src/Nazara/Core/InputStream.cpp @@ -8,61 +8,64 @@ #include #include -NzInputStream::~NzInputStream() = default; - -NzString NzInputStream::ReadLine(unsigned int lineSize) +namespace Nz { - NzString line; - if (lineSize == 0) // Taille maximale indéterminée + InputStream::~InputStream() = default; + + String InputStream::ReadLine(unsigned int lineSize) { - const unsigned int bufferSize = 64; - - char buffer[bufferSize+1]; - buffer[bufferSize] = '\0'; - - unsigned int readSize; - do + String line; + if (lineSize == 0) // Taille maximale indéterminée { - readSize = Read(buffer, bufferSize); + const unsigned int bufferSize = 64; - const char* ptr = std::strchr(buffer, '\n'); - if (ptr) + char buffer[bufferSize+1]; + buffer[bufferSize] = '\0'; + + unsigned int readSize; + do { - unsigned int pos = ptr-buffer; + readSize = Read(buffer, bufferSize); - if (m_streamOptions & nzStreamOption_Text && pos > 0 && buffer[pos-1] == '\r') - line.Append(buffer, pos-1); + const char* ptr = std::strchr(buffer, '\n'); + if (ptr) + { + unsigned int pos = ptr-buffer; + + if (m_streamOptions & StreamOption_Text && pos > 0 && buffer[pos-1] == '\r') + line.Append(buffer, pos-1); + else + line.Append(buffer, pos); + + if (!SetCursorPos(GetCursorPos() - readSize + pos + 1)) + NazaraWarning("Failed to reset cursos pos"); + + break; + } else - line.Append(buffer, pos); + line.Append(buffer, readSize); + } + while (readSize == bufferSize); + } + else + { + line.Set(lineSize, '\0'); + unsigned int readSize = Read(&line[0], lineSize); + unsigned int pos = line.Find('\n'); + if (pos <= readSize) // Faux uniquement si le caractère n'est pas présent (npos étant le plus grand entier) + { + if (m_streamOptions & StreamOption_Text && pos > 0 && line[pos-1] == '\r') + line.Resize(pos); + else + line.Resize(pos+1); if (!SetCursorPos(GetCursorPos() - readSize + pos + 1)) NazaraWarning("Failed to reset cursos pos"); - - break; } else - line.Append(buffer, readSize); + line.Resize(readSize); } - while (readSize == bufferSize); - } - else - { - line.Set(lineSize, '\0'); - unsigned int readSize = Read(&line[0], lineSize); - unsigned int pos = line.Find('\n'); - if (pos <= readSize) // Faux uniquement si le caractère n'est pas présent (npos étant le plus grand entier) - { - if (m_streamOptions & nzStreamOption_Text && pos > 0 && line[pos-1] == '\r') - line.Resize(pos); - else - line.Resize(pos+1); - if (!SetCursorPos(GetCursorPos() - readSize + pos + 1)) - NazaraWarning("Failed to reset cursos pos"); - } - else - line.Resize(readSize); + return line; } - - return line; } diff --git a/src/Nazara/Core/LockGuard.cpp b/src/Nazara/Core/LockGuard.cpp index 4ffaa3aed..b59596a7c 100644 --- a/src/Nazara/Core/LockGuard.cpp +++ b/src/Nazara/Core/LockGuard.cpp @@ -6,13 +6,16 @@ #include #include -NzLockGuard::NzLockGuard(NzMutex& mutex) : -m_mutex(mutex) +namespace Nz { - m_mutex.Lock(); -} + LockGuard::LockGuard(Mutex& mutex) : + m_mutex(mutex) + { + m_mutex.Lock(); + } -NzLockGuard::~NzLockGuard() -{ - m_mutex.Unlock(); + LockGuard::~LockGuard() + { + m_mutex.Unlock(); + } } diff --git a/src/Nazara/Core/Log.cpp b/src/Nazara/Core/Log.cpp index a2602228a..4c8997718 100644 --- a/src/Nazara/Core/Log.cpp +++ b/src/Nazara/Core/Log.cpp @@ -21,142 +21,145 @@ #include -namespace +namespace Nz { - const char* errorType[] = { - "Assert failed: ", // nzErrorType_AssertFailed - "Internal error: ", // nzErrorType_Internal - "Error: ", // nzErrorType_Normal - "Warning: " // nzErrorType_Warning - }; + namespace + { + const char* errorType[] = { + "Assert failed: ", // ErrorType_AssertFailed + "Internal error: ", // ErrorType_Internal + "Error: ", // ErrorType_Normal + "Warning: " // ErrorType_Warning + }; - static_assert(sizeof(errorType)/sizeof(const char*) == nzErrorType_Max+1, "Error type array is incomplete"); -} + static_assert(sizeof(errorType)/sizeof(const char*) == ErrorType_Max+1, "Error type array is incomplete"); + } -NzLog::NzLog() : -m_filePath("NazaraLog.log"), -m_file(nullptr), -m_append(false), -m_enabled(true), -m_writeTime(true) -{ -} + Log::Log() : + m_filePath("NazaraLog.log"), + m_file(nullptr), + m_append(false), + m_enabled(true), + m_writeTime(true) + { + } -NzLog::~NzLog() -{ - delete m_file; -} - -void NzLog::Enable(bool enable) -{ - NazaraLock(m_mutex) - - if (m_enabled == enable) - return; - - m_enabled = enable; - if (!m_enabled && m_file) + Log::~Log() { delete m_file; - m_file = nullptr; } -} -void NzLog::EnableAppend(bool enable) -{ - NazaraLock(m_mutex) - - m_append = enable; - if (!m_append && m_file) + void Log::Enable(bool enable) { - m_file->Delete(); - m_file = nullptr; - } -} + NazaraLock(m_mutex) -void NzLog::EnableDateTime(bool enable) -{ - NazaraLock(m_mutex) + if (m_enabled == enable) + return; - m_writeTime = enable; -} - -NzString NzLog::GetFile() const -{ - NazaraLock(m_mutex) - - if (m_file) - return m_file->GetPath(); - else - return NzString(); -} - -bool NzLog::IsEnabled() const -{ - NazaraLock(m_mutex) - - return m_enabled; -} - -void NzLog::SetFile(const NzString& filePath) -{ - NazaraLock(m_mutex) - - m_filePath = filePath; - if (m_file) - m_file->SetFile(filePath); -} - -void NzLog::Write(const NzString& string) -{ - NazaraLock(m_mutex) - - if (m_enabled) - { - if (!m_file) - m_file = new NzFile(m_filePath, nzOpenMode_Text | nzOpenMode_WriteOnly | ((m_append) ? nzOpenMode_Append : nzOpenMode_Truncate)); - - NzString line; - - if (m_writeTime) + m_enabled = enable; + if (!m_enabled && m_file) { - line.Reserve(23 + string.GetSize() + 1); - line.Set(23, '\0'); // Buffer non-initialisé - - time_t currentTime = std::time(nullptr); - std::strftime(&line[0], 24, "%d/%m/%Y - %H:%M:%S: ", std::localtime(¤tTime)); + delete m_file; + m_file = nullptr; } - else - line.Reserve(string.GetSize() + 1); - - line += string; - line += '\n'; - - if (m_file->IsOpen()) - m_file->Write(line); - - #if NAZARA_CORE_DUPLICATE_LOG_TO_COUT - std::fputs(line.GetConstBuffer(), stdout); - #endif } -} -void NzLog::WriteError(nzErrorType type, const NzString& error) -{ - NzStringStream stream; - stream << errorType[type] << error; - Write(stream); -} + void Log::EnableAppend(bool enable) + { + NazaraLock(m_mutex) -void NzLog::WriteError(nzErrorType type, const NzString& error, unsigned int line, const NzString& file, const NzString& func) -{ - NzStringStream stream; - stream << errorType[type] << error << " (" << file << ':' << line << ": " << func << ')'; - Write(stream); -} + m_append = enable; + if (!m_append && m_file) + { + m_file->Delete(); + m_file = nullptr; + } + } -NzLog* NzLog::Instance() -{ - static NzLog log; - return &log; + void Log::EnableDateTime(bool enable) + { + NazaraLock(m_mutex) + + m_writeTime = enable; + } + + String Log::GetFile() const + { + NazaraLock(m_mutex) + + if (m_file) + return m_file->GetPath(); + else + return String(); + } + + bool Log::IsEnabled() const + { + NazaraLock(m_mutex) + + return m_enabled; + } + + void Log::SetFile(const String& filePath) + { + NazaraLock(m_mutex) + + m_filePath = filePath; + if (m_file) + m_file->SetFile(filePath); + } + + void Log::Write(const String& string) + { + NazaraLock(m_mutex) + + if (m_enabled) + { + if (!m_file) + m_file = new File(m_filePath, OpenMode_Text | OpenMode_WriteOnly | ((m_append) ? OpenMode_Append : OpenMode_Truncate)); + + String line; + + if (m_writeTime) + { + line.Reserve(23 + string.GetSize() + 1); + line.Set(23, '\0'); // Buffer non-initialisé + + time_t currentTime = std::time(nullptr); + std::strftime(&line[0], 24, "%d/%m/%Y - %H:%M:%S: ", std::localtime(¤tTime)); + } + else + line.Reserve(string.GetSize() + 1); + + line += string; + line += '\n'; + + if (m_file->IsOpen()) + m_file->Write(line); + + #if NAZARA_CORE_DUPLICATE_LOG_TO_COUT + std::fputs(line.GetConstBuffer(), stdout); + #endif + } + } + + void Log::WriteError(ErrorType type, const String& error) + { + StringStream stream; + stream << errorType[type] << error; + Write(stream); + } + + void Log::WriteError(ErrorType type, const String& error, unsigned int line, const String& file, const String& func) + { + StringStream stream; + stream << errorType[type] << error << " (" << file << ':' << line << ": " << func << ')'; + Write(stream); + } + + Log* Log::Instance() + { + static Log log; + return &log; +} } diff --git a/src/Nazara/Core/MemoryManager.cpp b/src/Nazara/Core/MemoryManager.cpp index efaa956e3..9a5f5acec 100644 --- a/src/Nazara/Core/MemoryManager.cpp +++ b/src/Nazara/Core/MemoryManager.cpp @@ -17,320 +17,323 @@ // Le seul fichier n'ayant pas à inclure Debug.hpp -namespace +namespace Nz { - constexpr unsigned int s_allocatedId = 0xDEADB33FUL; - constexpr unsigned int s_freedId = 0x4B1DUL; - - struct Block + namespace { - std::size_t size; - const char* file; - Block* prev; - Block* next; - bool array; - unsigned int line; - unsigned int magic; - }; + constexpr unsigned int s_allocatedId = 0xDEADB33FUL; + constexpr unsigned int s_freedId = 0x4B1DUL; - bool s_allocationFilling = true; - bool s_allocationLogging = false; - bool s_initialized = false; - const char* s_logFileName = "NazaraMemory.log"; - thread_local const char* s_nextFreeFile = "(Internal error)"; - thread_local unsigned int s_nextFreeLine = 0; - - Block s_list = - { - 0, - nullptr, - &s_list, - &s_list, - false, - 0, - 0 - }; - - unsigned int s_allocationCount = 0; - unsigned int s_allocatedBlock = 0; - std::size_t s_allocatedSize = 0; - - #if defined(NAZARA_PLATFORM_WINDOWS) - CRITICAL_SECTION s_mutex; - #elif defined(NAZARA_PLATFORM_POSIX) - pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER; - #endif -} - -NzMemoryManager::NzMemoryManager() -{ -} - -NzMemoryManager::~NzMemoryManager() -{ - Uninitialize(); -} - -void* NzMemoryManager::Allocate(std::size_t size, bool multi, const char* file, unsigned int line) -{ - if (!s_initialized) - Initialize(); - - #if defined(NAZARA_PLATFORM_WINDOWS) - EnterCriticalSection(&s_mutex); - #elif defined(NAZARA_PLATFORM_POSIX) - pthread_mutex_lock(&s_mutex); - #endif - - Block* ptr = reinterpret_cast(std::malloc(size+sizeof(Block))); - if (!ptr) - { - char timeStr[23]; - TimeInfo(timeStr); - - FILE* log = std::fopen(s_logFileName, "a"); - - if (file) - std::fprintf(log, "%s Failed to allocate %zu bytes at %s:%u\n", timeStr, size, file, line); - else - std::fprintf(log, "%s Failed to allocate %zu bytes at unknown position\n", timeStr, size); - - std::fclose(log); - - throw std::bad_alloc(); - return nullptr; // Ça me rassure d'avoir un return, aussi inutile soit-il - } - - ptr->array = multi; - ptr->file = file; - ptr->line = line; - ptr->size = size; - ptr->magic = s_allocatedId; - - ptr->prev = s_list.prev; - ptr->next = &s_list; - s_list.prev->next = ptr; - s_list.prev = ptr; - - s_allocatedBlock++; - s_allocatedSize += size; - s_allocationCount++; - - if (s_allocationFilling) - { - nzUInt8* data = reinterpret_cast(ptr) + sizeof(Block); - std::memset(data, 0xFF, size); - } - - if (s_allocationLogging) - { - char timeStr[23]; - TimeInfo(timeStr); - - FILE* log = std::fopen(s_logFileName, "a"); - - if (file) - std::fprintf(log, "%s Allocated %zu bytes at %s:%u\n", timeStr, size, file, line); - else - std::fprintf(log, "%s Allocated %zu bytes at unknown position\n", timeStr, size); - - std::fclose(log); - } - - #if defined(NAZARA_PLATFORM_WINDOWS) - LeaveCriticalSection(&s_mutex); - #elif defined(NAZARA_PLATFORM_POSIX) - pthread_mutex_unlock(&s_mutex); - #endif - - return reinterpret_cast(ptr) + sizeof(Block); -} - -void NzMemoryManager::EnableAllocationFilling(bool allocationFilling) -{ - s_allocationFilling = allocationFilling; -} - -void NzMemoryManager::EnableAllocationLogging(bool logAllocations) -{ - s_allocationLogging = logAllocations; -} - -void NzMemoryManager::Free(void* pointer, bool multi) -{ - if (!pointer) - return; - - Block* ptr = reinterpret_cast(reinterpret_cast(pointer) - sizeof(Block)); - if (ptr->magic != s_allocatedId) - { - char timeStr[23]; - TimeInfo(timeStr); - - FILE* log = std::fopen(s_logFileName, "a"); - - const char* error = (ptr->magic == s_freedId) ? "double-delete" : "possible delete of dangling pointer"; - if (s_nextFreeFile) - std::fprintf(log, "%s Warning: %s at %s:%u\n", timeStr, error, s_nextFreeFile, s_nextFreeLine); - else - std::fprintf(log, "%s Warning: %s at unknown position\n", timeStr, error); - - std::fclose(log); - return; - } - - #if defined(NAZARA_PLATFORM_WINDOWS) - EnterCriticalSection(&s_mutex); - #elif defined(NAZARA_PLATFORM_POSIX) - pthread_mutex_lock(&s_mutex); - #endif - - if (ptr->array != multi) - { - char timeStr[23]; - TimeInfo(timeStr); - - FILE* log = std::fopen(s_logFileName, "a"); - - const char* error = (multi) ? "delete[] after new" : "delete after new[]"; - if (s_nextFreeFile) - std::fprintf(log, "%s Warning: %s at %s:%u\n", timeStr, error, s_nextFreeFile, s_nextFreeLine); - else - std::fprintf(log, "%s Warning: %s at unknown position\n", timeStr, error); - - std::fclose(log); - } - - ptr->magic = s_freedId; - ptr->prev->next = ptr->next; - ptr->next->prev = ptr->prev; - - s_allocatedBlock--; - s_allocatedSize -= ptr->size; - - if (s_allocationFilling) - { - nzUInt8* data = reinterpret_cast(ptr) + sizeof(Block); - std::memset(data, 0xFF, ptr->size); - } - - std::free(ptr); - - s_nextFreeFile = nullptr; - s_nextFreeLine = 0; - - #if defined(NAZARA_PLATFORM_WINDOWS) - LeaveCriticalSection(&s_mutex); - #elif defined(NAZARA_PLATFORM_POSIX) - pthread_mutex_unlock(&s_mutex); - #endif -} - -unsigned int NzMemoryManager::GetAllocatedBlockCount() -{ - return s_allocatedBlock; -} - -std::size_t NzMemoryManager::GetAllocatedSize() -{ - return s_allocatedSize; -} - -unsigned int NzMemoryManager::GetAllocationCount() -{ - return s_allocationCount; -} - -bool NzMemoryManager::IsAllocationFillingEnabled() -{ - return s_allocationFilling; -} - -bool NzMemoryManager::IsAllocationLoggingEnabled() -{ - return s_allocationLogging; -} - -void NzMemoryManager::NextFree(const char* file, unsigned int line) -{ - s_nextFreeFile = file; - s_nextFreeLine = line; -} - -void NzMemoryManager::Initialize() -{ - char timeStr[23]; - TimeInfo(timeStr); - - FILE* file = std::fopen(s_logFileName, "w"); - std::fprintf(file, "%s ==============================\n", timeStr); - std::fprintf(file, "%s Nazara Memory Leak Tracker \n", timeStr); - std::fprintf(file, "%s ==============================\n", timeStr); - std::fclose(file); - - if (std::atexit(Uninitialize) != 0) - { - static NzMemoryManager manager; - } - - #ifdef NAZARA_PLATFORM_WINDOWS - InitializeCriticalSection(&s_mutex); - //#elif defined(NAZARA_PLATFORM_POSIX) is already done in the namespace - #endif - - s_initialized = true; -} - -void NzMemoryManager::TimeInfo(char buffer[23]) -{ - time_t currentTime = std::time(nullptr); - std::strftime(buffer, 23, "%d/%m/%Y - %H:%M:%S:", std::localtime(¤tTime)); -} - -void NzMemoryManager::Uninitialize() -{ - #ifdef NAZARA_PLATFORM_WINDOWS - DeleteCriticalSection(&s_mutex); - #elif defined(NAZARA_PLATFORM_POSIX) - pthread_mutex_destroy(&s_mutex); - #endif - - FILE* log = std::fopen(s_logFileName, "a"); - - char timeStr[23]; - TimeInfo(timeStr); - - std::fprintf(log, "%s Application finished, checking leaks...\n", timeStr); - - if (s_allocatedBlock == 0) - { - std::fprintf(log, "%s ==============================\n", timeStr); - std::fprintf(log, "%s No leak detected \n", timeStr); - std::fprintf(log, "%s ==============================", timeStr); - } - else - { - std::fprintf(log, "%s ==============================\n", timeStr); - std::fprintf(log, "%s Leaks have been detected \n", timeStr); - std::fprintf(log, "%s ==============================\n\n", timeStr); - std::fputs("Leak list:\n", log); - - Block* ptr = s_list.next; - while (ptr != &s_list) + struct Block { - if (ptr->file) - std::fprintf(log, "-0x%p -> %zu bytes allocated at %s:%u\n", reinterpret_cast(ptr) + sizeof(Block), ptr->size, ptr->file, ptr->line); + std::size_t size; + const char* file; + Block* prev; + Block* next; + bool array; + unsigned int line; + unsigned int magic; + }; + + bool s_allocationFilling = true; + bool s_allocationLogging = false; + bool s_initialized = false; + const char* s_logFileName = "NazaraMemory.log"; + thread_local const char* s_nextFreeFile = "(Internal error)"; + thread_local unsigned int s_nextFreeLine = 0; + + Block s_list = + { + 0, + nullptr, + &s_list, + &s_list, + false, + 0, + 0 + }; + + unsigned int s_allocationCount = 0; + unsigned int s_allocatedBlock = 0; + std::size_t s_allocatedSize = 0; + + #if defined(NAZARA_PLATFORM_WINDOWS) + CRITICAL_SECTION s_mutex; + #elif defined(NAZARA_PLATFORM_POSIX) + pthread_mutex_t s_mutex = PTHREAD_MUTEX_INITIALIZER; + #endif + } + + MemoryManager::MemoryManager() + { + } + + MemoryManager::~MemoryManager() + { + Uninitialize(); + } + + void* MemoryManager::Allocate(std::size_t size, bool multi, const char* file, unsigned int line) + { + if (!s_initialized) + Initialize(); + + #if defined(NAZARA_PLATFORM_WINDOWS) + EnterCriticalSection(&s_mutex); + #elif defined(NAZARA_PLATFORM_POSIX) + pthread_mutex_lock(&s_mutex); + #endif + + Block* ptr = reinterpret_cast(std::malloc(size+sizeof(Block))); + if (!ptr) + { + char timeStr[23]; + TimeInfo(timeStr); + + FILE* log = std::fopen(s_logFileName, "a"); + + if (file) + std::fprintf(log, "%s Failed to allocate %zu bytes at %s:%u\n", timeStr, size, file, line); else - std::fprintf(log, "-0x%p -> %zu bytes allocated at unknown position\n", reinterpret_cast(ptr) + sizeof(Block), ptr->size); + std::fprintf(log, "%s Failed to allocate %zu bytes at unknown position\n", timeStr, size); - void* pointer = ptr; - ptr = ptr->next; + std::fclose(log); - std::free(pointer); + throw std::bad_alloc(); + return nullptr; // Ça me rassure d'avoir un return, aussi inutile soit-il } - std::fprintf(log, "\n%u blocks leaked (%zu bytes)", s_allocatedBlock, s_allocatedSize); + ptr->array = multi; + ptr->file = file; + ptr->line = line; + ptr->size = size; + ptr->magic = s_allocatedId; + + ptr->prev = s_list.prev; + ptr->next = &s_list; + s_list.prev->next = ptr; + s_list.prev = ptr; + + s_allocatedBlock++; + s_allocatedSize += size; + s_allocationCount++; + + if (s_allocationFilling) + { + UInt8* data = reinterpret_cast(ptr) + sizeof(Block); + std::memset(data, 0xFF, size); + } + + if (s_allocationLogging) + { + char timeStr[23]; + TimeInfo(timeStr); + + FILE* log = std::fopen(s_logFileName, "a"); + + if (file) + std::fprintf(log, "%s Allocated %zu bytes at %s:%u\n", timeStr, size, file, line); + else + std::fprintf(log, "%s Allocated %zu bytes at unknown position\n", timeStr, size); + + std::fclose(log); + } + + #if defined(NAZARA_PLATFORM_WINDOWS) + LeaveCriticalSection(&s_mutex); + #elif defined(NAZARA_PLATFORM_POSIX) + pthread_mutex_unlock(&s_mutex); + #endif + + return reinterpret_cast(ptr) + sizeof(Block); } - std::fclose(log); + void MemoryManager::EnableAllocationFilling(bool allocationFilling) + { + s_allocationFilling = allocationFilling; + } + + void MemoryManager::EnableAllocationLogging(bool logAllocations) + { + s_allocationLogging = logAllocations; + } + + void MemoryManager::Free(void* pointer, bool multi) + { + if (!pointer) + return; + + Block* ptr = reinterpret_cast(reinterpret_cast(pointer) - sizeof(Block)); + if (ptr->magic != s_allocatedId) + { + char timeStr[23]; + TimeInfo(timeStr); + + FILE* log = std::fopen(s_logFileName, "a"); + + const char* error = (ptr->magic == s_freedId) ? "double-delete" : "possible delete of dangling pointer"; + if (s_nextFreeFile) + std::fprintf(log, "%s Warning: %s at %s:%u\n", timeStr, error, s_nextFreeFile, s_nextFreeLine); + else + std::fprintf(log, "%s Warning: %s at unknown position\n", timeStr, error); + + std::fclose(log); + return; + } + + #if defined(NAZARA_PLATFORM_WINDOWS) + EnterCriticalSection(&s_mutex); + #elif defined(NAZARA_PLATFORM_POSIX) + pthread_mutex_lock(&s_mutex); + #endif + + if (ptr->array != multi) + { + char timeStr[23]; + TimeInfo(timeStr); + + FILE* log = std::fopen(s_logFileName, "a"); + + const char* error = (multi) ? "delete[] after new" : "delete after new[]"; + if (s_nextFreeFile) + std::fprintf(log, "%s Warning: %s at %s:%u\n", timeStr, error, s_nextFreeFile, s_nextFreeLine); + else + std::fprintf(log, "%s Warning: %s at unknown position\n", timeStr, error); + + std::fclose(log); + } + + ptr->magic = s_freedId; + ptr->prev->next = ptr->next; + ptr->next->prev = ptr->prev; + + s_allocatedBlock--; + s_allocatedSize -= ptr->size; + + if (s_allocationFilling) + { + UInt8* data = reinterpret_cast(ptr) + sizeof(Block); + std::memset(data, 0xFF, ptr->size); + } + + std::free(ptr); + + s_nextFreeFile = nullptr; + s_nextFreeLine = 0; + + #if defined(NAZARA_PLATFORM_WINDOWS) + LeaveCriticalSection(&s_mutex); + #elif defined(NAZARA_PLATFORM_POSIX) + pthread_mutex_unlock(&s_mutex); + #endif + } + + unsigned int MemoryManager::GetAllocatedBlockCount() + { + return s_allocatedBlock; + } + + std::size_t MemoryManager::GetAllocatedSize() + { + return s_allocatedSize; + } + + unsigned int MemoryManager::GetAllocationCount() + { + return s_allocationCount; + } + + bool MemoryManager::IsAllocationFillingEnabled() + { + return s_allocationFilling; + } + + bool MemoryManager::IsAllocationLoggingEnabled() + { + return s_allocationLogging; + } + + void MemoryManager::NextFree(const char* file, unsigned int line) + { + s_nextFreeFile = file; + s_nextFreeLine = line; + } + + void MemoryManager::Initialize() + { + char timeStr[23]; + TimeInfo(timeStr); + + FILE* file = std::fopen(s_logFileName, "w"); + std::fprintf(file, "%s ==============================\n", timeStr); + std::fprintf(file, "%s Nazara Memory Leak Tracker \n", timeStr); + std::fprintf(file, "%s ==============================\n", timeStr); + std::fclose(file); + + if (std::atexit(Uninitialize) != 0) + { + static MemoryManager manager; + } + + #ifdef NAZARA_PLATFORM_WINDOWS + InitializeCriticalSection(&s_mutex); + //#elif defined(NAZARA_PLATFORM_POSIX) is already done in the namespace + #endif + + s_initialized = true; + } + + void MemoryManager::TimeInfo(char buffer[23]) + { + time_t currentTime = std::time(nullptr); + std::strftime(buffer, 23, "%d/%m/%Y - %H:%M:%S:", std::localtime(¤tTime)); + } + + void MemoryManager::Uninitialize() + { + #ifdef NAZARA_PLATFORM_WINDOWS + DeleteCriticalSection(&s_mutex); + #elif defined(NAZARA_PLATFORM_POSIX) + pthread_mutex_destroy(&s_mutex); + #endif + + FILE* log = std::fopen(s_logFileName, "a"); + + char timeStr[23]; + TimeInfo(timeStr); + + std::fprintf(log, "%s Application finished, checking leaks...\n", timeStr); + + if (s_allocatedBlock == 0) + { + std::fprintf(log, "%s ==============================\n", timeStr); + std::fprintf(log, "%s No leak detected \n", timeStr); + std::fprintf(log, "%s ==============================", timeStr); + } + else + { + std::fprintf(log, "%s ==============================\n", timeStr); + std::fprintf(log, "%s Leaks have been detected \n", timeStr); + std::fprintf(log, "%s ==============================\n\n", timeStr); + std::fputs("Leak list:\n", log); + + Block* ptr = s_list.next; + while (ptr != &s_list) + { + if (ptr->file) + std::fprintf(log, "-0x%p -> %zu bytes allocated at %s:%u\n", reinterpret_cast(ptr) + sizeof(Block), ptr->size, ptr->file, ptr->line); + else + std::fprintf(log, "-0x%p -> %zu bytes allocated at unknown position\n", reinterpret_cast(ptr) + sizeof(Block), ptr->size); + + void* pointer = ptr; + ptr = ptr->next; + + std::free(pointer); + } + + std::fprintf(log, "\n%u blocks leaked (%zu bytes)", s_allocatedBlock, s_allocatedSize); + } + + std::fclose(log); +} } diff --git a/src/Nazara/Core/MemoryStream.cpp b/src/Nazara/Core/MemoryStream.cpp index f8b391c6e..2fb3ab3df 100644 --- a/src/Nazara/Core/MemoryStream.cpp +++ b/src/Nazara/Core/MemoryStream.cpp @@ -7,47 +7,50 @@ #include #include -NzMemoryStream::NzMemoryStream(const void* ptr, nzUInt64 size) : -m_ptr(reinterpret_cast(ptr)), -m_pos(0), -m_size(size) +namespace Nz { -} - -NzMemoryStream::~NzMemoryStream() -{ -} - -bool NzMemoryStream::EndOfStream() const -{ - return m_pos == m_size; -} - -nzUInt64 NzMemoryStream::GetCursorPos() const -{ - return m_pos; -} - -nzUInt64 NzMemoryStream::GetSize() const -{ - return m_size; -} - -std::size_t NzMemoryStream::Read(void* buffer, std::size_t size) -{ - unsigned int readSize = std::min(static_cast(size), static_cast(m_size-m_pos)); - - if (buffer) - std::memcpy(buffer, &m_ptr[m_pos], readSize); - - m_pos += readSize; - - return readSize; -} - -bool NzMemoryStream::SetCursorPos(nzUInt64 offset) -{ - m_pos = std::min(offset, m_size); - - return true; + MemoryStream::MemoryStream(const void* ptr, UInt64 size) : + m_ptr(reinterpret_cast(ptr)), + m_pos(0), + m_size(size) + { + } + + MemoryStream::~MemoryStream() + { + } + + bool MemoryStream::EndOfStream() const + { + return m_pos == m_size; + } + + UInt64 MemoryStream::GetCursorPos() const + { + return m_pos; + } + + UInt64 MemoryStream::GetSize() const + { + return m_size; + } + + std::size_t MemoryStream::Read(void* buffer, std::size_t size) + { + unsigned int readSize = std::min(static_cast(size), static_cast(m_size-m_pos)); + + if (buffer) + std::memcpy(buffer, &m_ptr[m_pos], readSize); + + m_pos += readSize; + + return readSize; + } + + bool MemoryStream::SetCursorPos(UInt64 offset) + { + m_pos = std::min(offset, m_size); + + return true; + } } diff --git a/src/Nazara/Core/Mutex.cpp b/src/Nazara/Core/Mutex.cpp index ca2929a3a..1245cd801 100644 --- a/src/Nazara/Core/Mutex.cpp +++ b/src/Nazara/Core/Mutex.cpp @@ -14,27 +14,30 @@ #include -NzMutex::NzMutex() +namespace Nz { - m_impl = new NzMutexImpl; -} + Mutex::Mutex() + { + m_impl = new MutexImpl; + } -NzMutex::~NzMutex() -{ - delete m_impl; -} + Mutex::~Mutex() + { + delete m_impl; + } -void NzMutex::Lock() -{ - m_impl->Lock(); -} + void Mutex::Lock() + { + m_impl->Lock(); + } -bool NzMutex::TryLock() -{ - return m_impl->TryLock(); -} + bool Mutex::TryLock() + { + return m_impl->TryLock(); + } -void NzMutex::Unlock() -{ - m_impl->Unlock(); + void Mutex::Unlock() + { + m_impl->Unlock(); + } } diff --git a/src/Nazara/Core/ParameterList.cpp b/src/Nazara/Core/ParameterList.cpp index 663deafe2..5b63218af 100644 --- a/src/Nazara/Core/ParameterList.cpp +++ b/src/Nazara/Core/ParameterList.cpp @@ -10,436 +10,439 @@ #include #include -NzParameterList::NzParameterList(const NzParameterList& list) +namespace Nz { - operator=(list); -} - -NzParameterList::~NzParameterList() -{ - Clear(); -} - -void NzParameterList::Clear() -{ - for (auto it = m_parameters.begin(); it != m_parameters.end(); ++it) - DestroyValue(it->second); - - m_parameters.clear(); -} - -bool NzParameterList::GetBooleanParameter(const NzString& name, bool* value) const -{ - auto it = m_parameters.find(name); - if (it == m_parameters.end()) + ParameterList::ParameterList(const ParameterList& list) { - NazaraError("Parameter \"" + name + "\" is not present"); - return false; + operator=(list); } - switch (it->second.type) + ParameterList::~ParameterList() { - case nzParameterType_Boolean: - *value = it->second.value.boolVal; - return true; + Clear(); + } - case nzParameterType_Integer: - *value = (it->second.value.intVal != 0); - return true; + void ParameterList::Clear() + { + for (auto it = m_parameters.begin(); it != m_parameters.end(); ++it) + DestroyValue(it->second); - case nzParameterType_String: + m_parameters.clear(); + } + + bool ParameterList::GetBooleanParameter(const String& name, bool* value) const + { + auto it = m_parameters.find(name); + if (it == m_parameters.end()) { - bool converted; - if (it->second.value.stringVal.ToBool(&converted, NzString::CaseInsensitive)) - { - *value = converted; - return true; - } - - break; - } - - case nzParameterType_Float: - case nzParameterType_None: - case nzParameterType_Pointer: - case nzParameterType_Userdata: - break; - } - - NazaraError("Parameter value is not representable as a boolean"); - return false; -} - -bool NzParameterList::GetFloatParameter(const NzString& name, float* value) const -{ - auto it = m_parameters.find(name); - if (it == m_parameters.end()) - { - NazaraError("Parameter \"" + name + "\" is not present"); - return false; - } - - switch (it->second.type) - { - case nzParameterType_Float: - *value = it->second.value.floatVal; - return true; - - case nzParameterType_Integer: - *value = static_cast(it->second.value.intVal); - return true; - - case nzParameterType_String: - { - double converted; - if (it->second.value.stringVal.ToDouble(&converted)) - { - *value = static_cast(converted); - return true; - } - - break; - } - - case nzParameterType_Boolean: - case nzParameterType_None: - case nzParameterType_Pointer: - case nzParameterType_Userdata: - break; - } - - NazaraError("Parameter value is not representable as a float"); - return false; -} - -bool NzParameterList::GetIntegerParameter(const NzString& name, int* value) const -{ - auto it = m_parameters.find(name); - if (it == m_parameters.end()) - { - NazaraError("Parameter \"" + name + "\" is not present"); - return false; - } - - switch (it->second.type) - { - case nzParameterType_Boolean: - *value = (it->second.value.boolVal) ? 1 : 0; - return true; - - case nzParameterType_Float: - *value = static_cast(it->second.value.floatVal); - return true; - - case nzParameterType_Integer: - *value = it->second.value.intVal; + NazaraError("Parameter \"" + name + "\" is not present"); return false; - - case nzParameterType_String: - { - long long converted; - if (it->second.value.stringVal.ToInteger(&converted)) - { - if (converted <= std::numeric_limits::max() && converted >= std::numeric_limits::min()) - { - *value = static_cast(converted); - return true; - } - } - break; } - case nzParameterType_None: - case nzParameterType_Pointer: - case nzParameterType_Userdata: - break; - } - - NazaraError("Parameter value is not representable as a integer"); - return false; -} - -bool NzParameterList::GetParameterType(const NzString& name, nzParameterType* type) const -{ - auto it = m_parameters.find(name); - if (it == m_parameters.end()) - return false; - - *type = it->second.type; - - return true; -} - -bool NzParameterList::GetPointerParameter(const NzString& name, void** value) const -{ - auto it = m_parameters.find(name); - if (it == m_parameters.end()) - { - NazaraError("Parameter \"" + name + "\" is not present"); - return false; - } - - switch (it->second.type) - { - case nzParameterType_Pointer: - *value = it->second.value.ptrVal; - return true; - - case nzParameterType_Userdata: - *value = it->second.value.userdataVal->ptr; - return true; - - case nzParameterType_Boolean: - case nzParameterType_Float: - case nzParameterType_Integer: - case nzParameterType_None: - case nzParameterType_String: - break; - } - - NazaraError("Parameter value is not a pointer"); - return false; -} - -bool NzParameterList::GetStringParameter(const NzString& name, NzString* value) const -{ - auto it = m_parameters.find(name); - if (it == m_parameters.end()) - { - NazaraError("Parameter \"" + name + "\" is not present"); - return false; - } - - switch (it->second.type) - { - case nzParameterType_Boolean: - *value = NzString::Boolean(it->second.value.boolVal); - return true; - - case nzParameterType_Float: - *value = NzString::Number(it->second.value.floatVal); - return true; - - case nzParameterType_Integer: - *value = NzString::Number(it->second.value.intVal); - return true; - - case nzParameterType_String: - *value = it->second.value.stringVal; - return true; - - case nzParameterType_Pointer: - *value = NzString::Pointer(it->second.value.ptrVal); - return true; - - case nzParameterType_Userdata: - *value = NzString::Pointer(it->second.value.userdataVal->ptr); - return true; - - case nzParameterType_None: - *value = NzString(); - return true; - } - - NazaraInternalError("Parameter value is not valid"); - return false; -} - -bool NzParameterList::GetUserdataParameter(const NzString& name, void** value) const -{ - auto it = m_parameters.find(name); - if (it == m_parameters.end()) - { - NazaraError("Parameter \"" + name + "\" is not present"); - return false; - } - - if (it->second.type == nzParameterType_Userdata) - { - *value = it->second.value.userdataVal->ptr; - return true; - } - else - { - NazaraError("Parameter value is not a userdata"); - return false; - } -} - -bool NzParameterList::HasParameter(const NzString& name) const -{ - return m_parameters.find(name) != m_parameters.end(); -} - -void NzParameterList::RemoveParameter(const NzString& name) -{ - auto it = m_parameters.find(name); - if (it != m_parameters.end()) - { - DestroyValue(it->second); - m_parameters.erase(it); - } -} - -void NzParameterList::SetParameter(const NzString& name) -{ - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - - parameter.type = nzParameterType_None; -} - -void NzParameterList::SetParameter(const NzString& name, const NzString& value) -{ - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - - parameter.type = nzParameterType_String; - - NzPlacementNew(¶meter.value.stringVal, value); -} - -void NzParameterList::SetParameter(const NzString& name, const char* value) -{ - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - - parameter.type = nzParameterType_String; - - NzPlacementNew(¶meter.value.stringVal, value); -} - -void NzParameterList::SetParameter(const NzString& name, void* value) -{ - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - - parameter.type = nzParameterType_Pointer; - parameter.value.ptrVal = value; -} - -void NzParameterList::SetParameter(const NzString& name, void* value, Destructor destructor) -{ - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - - parameter.type = nzParameterType_Userdata; - parameter.value.userdataVal = new Parameter::UserdataValue(destructor, value); -} - -void NzParameterList::SetParameter(const NzString& name, bool value) -{ - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - - parameter.type = nzParameterType_Boolean; - parameter.value.boolVal = value; -} - -void NzParameterList::SetParameter(const NzString& name, float value) -{ - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - - parameter.type = nzParameterType_Float; - parameter.value.floatVal = value; -} - -void NzParameterList::SetParameter(const NzString& name, int value) -{ - std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); - Parameter& parameter = pair.first->second; - - if (!pair.second) - DestroyValue(parameter); - - parameter.type = nzParameterType_Integer; - parameter.value.intVal = value; -} - -NzParameterList& NzParameterList::operator=(const NzParameterList& list) -{ - Clear(); - - for (auto it = list.m_parameters.begin(); it != list.m_parameters.end(); ++it) - { - Parameter& parameter = m_parameters[it->first]; - switch (it->second.type) { - case nzParameterType_Boolean: - case nzParameterType_Float: - case nzParameterType_Integer: - case nzParameterType_Pointer: - std::memcpy(¶meter, &it->second, sizeof(Parameter)); - break; + case ParameterType_Boolean: + *value = it->second.value.boolVal; + return true; - case nzParameterType_String: - parameter.type = nzParameterType_String; + case ParameterType_Integer: + *value = (it->second.value.intVal != 0); + return true; - NzPlacementNew(¶meter.value.stringVal, it->second.value.stringVal); - break; - - case nzParameterType_Userdata: - parameter.type = nzParameterType_Userdata; - parameter.value.userdataVal = it->second.value.userdataVal; - ++(parameter.value.userdataVal->counter); - break; - - case nzParameterType_None: - parameter.type = nzParameterType_None; - break; - } - } - - return *this; -} - -void NzParameterList::DestroyValue(Parameter& parameter) -{ - switch (parameter.type) - { - case nzParameterType_String: - parameter.value.stringVal.~NzString(); - break; - - case nzParameterType_Userdata: - { - Parameter::UserdataValue* userdata = parameter.value.userdataVal; - if (--userdata->counter == 0) + case ParameterType_String: { - userdata->destructor(userdata->ptr); - delete userdata; + bool converted; + if (it->second.value.stringVal.ToBool(&converted, String::CaseInsensitive)) + { + *value = converted; + return true; + } + + break; } - break; + + case ParameterType_Float: + case ParameterType_None: + case ParameterType_Pointer: + case ParameterType_Userdata: + break; } - case nzParameterType_Boolean: - case nzParameterType_Float: - case nzParameterType_Integer: - case nzParameterType_None: - case nzParameterType_Pointer: - break; + NazaraError("Parameter value is not representable as a boolean"); + return false; + } + + bool ParameterList::GetFloatParameter(const String& name, float* value) const + { + auto it = m_parameters.find(name); + if (it == m_parameters.end()) + { + NazaraError("Parameter \"" + name + "\" is not present"); + return false; + } + + switch (it->second.type) + { + case ParameterType_Float: + *value = it->second.value.floatVal; + return true; + + case ParameterType_Integer: + *value = static_cast(it->second.value.intVal); + return true; + + case ParameterType_String: + { + double converted; + if (it->second.value.stringVal.ToDouble(&converted)) + { + *value = static_cast(converted); + return true; + } + + break; + } + + case ParameterType_Boolean: + case ParameterType_None: + case ParameterType_Pointer: + case ParameterType_Userdata: + break; + } + + NazaraError("Parameter value is not representable as a float"); + return false; + } + + bool ParameterList::GetIntegerParameter(const String& name, int* value) const + { + auto it = m_parameters.find(name); + if (it == m_parameters.end()) + { + NazaraError("Parameter \"" + name + "\" is not present"); + return false; + } + + switch (it->second.type) + { + case ParameterType_Boolean: + *value = (it->second.value.boolVal) ? 1 : 0; + return true; + + case ParameterType_Float: + *value = static_cast(it->second.value.floatVal); + return true; + + case ParameterType_Integer: + *value = it->second.value.intVal; + return false; + + case ParameterType_String: + { + long long converted; + if (it->second.value.stringVal.ToInteger(&converted)) + { + if (converted <= std::numeric_limits::max() && converted >= std::numeric_limits::min()) + { + *value = static_cast(converted); + return true; + } + } + break; + } + + case ParameterType_None: + case ParameterType_Pointer: + case ParameterType_Userdata: + break; + } + + NazaraError("Parameter value is not representable as a integer"); + return false; + } + + bool ParameterList::GetParameterType(const String& name, ParameterType* type) const + { + auto it = m_parameters.find(name); + if (it == m_parameters.end()) + return false; + + *type = it->second.type; + + return true; + } + + bool ParameterList::GetPointerParameter(const String& name, void** value) const + { + auto it = m_parameters.find(name); + if (it == m_parameters.end()) + { + NazaraError("Parameter \"" + name + "\" is not present"); + return false; + } + + switch (it->second.type) + { + case ParameterType_Pointer: + *value = it->second.value.ptrVal; + return true; + + case ParameterType_Userdata: + *value = it->second.value.userdataVal->ptr; + return true; + + case ParameterType_Boolean: + case ParameterType_Float: + case ParameterType_Integer: + case ParameterType_None: + case ParameterType_String: + break; + } + + NazaraError("Parameter value is not a pointer"); + return false; + } + + bool ParameterList::GetStringParameter(const String& name, String* value) const + { + auto it = m_parameters.find(name); + if (it == m_parameters.end()) + { + NazaraError("Parameter \"" + name + "\" is not present"); + return false; + } + + switch (it->second.type) + { + case ParameterType_Boolean: + *value = String::Boolean(it->second.value.boolVal); + return true; + + case ParameterType_Float: + *value = String::Number(it->second.value.floatVal); + return true; + + case ParameterType_Integer: + *value = String::Number(it->second.value.intVal); + return true; + + case ParameterType_String: + *value = it->second.value.stringVal; + return true; + + case ParameterType_Pointer: + *value = String::Pointer(it->second.value.ptrVal); + return true; + + case ParameterType_Userdata: + *value = String::Pointer(it->second.value.userdataVal->ptr); + return true; + + case ParameterType_None: + *value = String(); + return true; + } + + NazaraInternalError("Parameter value is not valid"); + return false; + } + + bool ParameterList::GetUserdataParameter(const String& name, void** value) const + { + auto it = m_parameters.find(name); + if (it == m_parameters.end()) + { + NazaraError("Parameter \"" + name + "\" is not present"); + return false; + } + + if (it->second.type == ParameterType_Userdata) + { + *value = it->second.value.userdataVal->ptr; + return true; + } + else + { + NazaraError("Parameter value is not a userdata"); + return false; + } + } + + bool ParameterList::HasParameter(const String& name) const + { + return m_parameters.find(name) != m_parameters.end(); + } + + void ParameterList::RemoveParameter(const String& name) + { + auto it = m_parameters.find(name); + if (it != m_parameters.end()) + { + DestroyValue(it->second); + m_parameters.erase(it); + } + } + + void ParameterList::SetParameter(const String& name) + { + std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); + Parameter& parameter = pair.first->second; + + if (!pair.second) + DestroyValue(parameter); + + parameter.type = ParameterType_None; + } + + void ParameterList::SetParameter(const String& name, const String& value) + { + std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); + Parameter& parameter = pair.first->second; + + if (!pair.second) + DestroyValue(parameter); + + parameter.type = ParameterType_String; + + PlacementNew(¶meter.value.stringVal, value); + } + + void ParameterList::SetParameter(const String& name, const char* value) + { + std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); + Parameter& parameter = pair.first->second; + + if (!pair.second) + DestroyValue(parameter); + + parameter.type = ParameterType_String; + + PlacementNew(¶meter.value.stringVal, value); + } + + void ParameterList::SetParameter(const String& name, void* value) + { + std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); + Parameter& parameter = pair.first->second; + + if (!pair.second) + DestroyValue(parameter); + + parameter.type = ParameterType_Pointer; + parameter.value.ptrVal = value; + } + + void ParameterList::SetParameter(const String& name, void* value, Destructor destructor) + { + std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); + Parameter& parameter = pair.first->second; + + if (!pair.second) + DestroyValue(parameter); + + parameter.type = ParameterType_Userdata; + parameter.value.userdataVal = new Parameter::UserdataValue(destructor, value); + } + + void ParameterList::SetParameter(const String& name, bool value) + { + std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); + Parameter& parameter = pair.first->second; + + if (!pair.second) + DestroyValue(parameter); + + parameter.type = ParameterType_Boolean; + parameter.value.boolVal = value; + } + + void ParameterList::SetParameter(const String& name, float value) + { + std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); + Parameter& parameter = pair.first->second; + + if (!pair.second) + DestroyValue(parameter); + + parameter.type = ParameterType_Float; + parameter.value.floatVal = value; + } + + void ParameterList::SetParameter(const String& name, int value) + { + std::pair pair = m_parameters.insert(std::make_pair(name, Parameter())); + Parameter& parameter = pair.first->second; + + if (!pair.second) + DestroyValue(parameter); + + parameter.type = ParameterType_Integer; + parameter.value.intVal = value; + } + + ParameterList& ParameterList::operator=(const ParameterList& list) + { + Clear(); + + for (auto it = list.m_parameters.begin(); it != list.m_parameters.end(); ++it) + { + Parameter& parameter = m_parameters[it->first]; + + switch (it->second.type) + { + case ParameterType_Boolean: + case ParameterType_Float: + case ParameterType_Integer: + case ParameterType_Pointer: + std::memcpy(¶meter, &it->second, sizeof(Parameter)); + break; + + case ParameterType_String: + parameter.type = ParameterType_String; + + PlacementNew(¶meter.value.stringVal, it->second.value.stringVal); + break; + + case ParameterType_Userdata: + parameter.type = ParameterType_Userdata; + parameter.value.userdataVal = it->second.value.userdataVal; + ++(parameter.value.userdataVal->counter); + break; + + case ParameterType_None: + parameter.type = ParameterType_None; + break; + } + } + + return *this; + } + + void ParameterList::DestroyValue(Parameter& parameter) + { + switch (parameter.type) + { + case ParameterType_String: + parameter.value.stringVal.~String(); + break; + + case ParameterType_Userdata: + { + Parameter::UserdataValue* userdata = parameter.value.userdataVal; + if (--userdata->counter == 0) + { + userdata->destructor(userdata->ptr); + delete userdata; + } + break; + } + + case ParameterType_Boolean: + case ParameterType_Float: + case ParameterType_Integer: + case ParameterType_None: + case ParameterType_Pointer: + break; + } } } diff --git a/src/Nazara/Core/PluginManager.cpp b/src/Nazara/Core/PluginManager.cpp index 77346ec29..ddfede54c 100644 --- a/src/Nazara/Core/PluginManager.cpp +++ b/src/Nazara/Core/PluginManager.cpp @@ -10,176 +10,179 @@ #include #include -namespace +namespace Nz { - using PluginLoad = int (*)(); - using PluginUnload = void (*)(); - - NzString s_pluginFiles[] = + namespace { - "NazaraAssimp", // nzPlugin_Assimp - "NazaraFreetype" // nzPlugin_FreeType - }; -} + using PluginLoad = int (*)(); + using PluginUnload = void (*)(); -void NzPluginManager::AddDirectory(const NzString& directoryPath) -{ - if (!Initialize()) - { - NazaraError("Failed to initialize PluginManager"); - return; - } - - s_directories.insert(NzFile::AbsolutePath(directoryPath)); -} - -bool NzPluginManager::Initialize() -{ - if (s_initialized) - return true; - - s_initialized = true; - - AddDirectory("."); - AddDirectory("plugins"); - - return true; -} - -bool NzPluginManager::Mount(nzPlugin plugin) -{ - return Mount(s_pluginFiles[plugin]); -} - -bool NzPluginManager::Mount(const NzString& pluginPath, bool appendExtension) -{ - if (!Initialize()) - { - NazaraError("Failed to initialize PluginManager"); - return false; - } - - NzString path = pluginPath; - if (appendExtension && !path.EndsWith(NAZARA_DYNLIB_EXTENSION)) - path += NAZARA_DYNLIB_EXTENSION; - - bool exists = false; - if (!NzFile::IsAbsolute(path)) - { - for (const NzString& dir : s_directories) + String s_pluginFiles[] = { - NzString testPath; - testPath.Reserve(dir.GetSize() + path.GetSize() + 10); + "NazaraAssimp", // Plugin_Assimp + "NazaraFreetype" // Plugin_FreeType + }; + } - testPath = dir; - testPath += NAZARA_DIRECTORY_SEPARATOR; - testPath += path; + void PluginManager::AddDirectory(const String& directoryPath) + { + if (!Initialize()) + { + NazaraError("Failed to initialize PluginManager"); + return; + } - if (NzFile::Exists(testPath)) + s_directories.insert(File::AbsolutePath(directoryPath)); + } + + bool PluginManager::Initialize() + { + if (s_initialized) + return true; + + s_initialized = true; + + AddDirectory("."); + AddDirectory("plugins"); + + return true; + } + + bool PluginManager::Mount(Plugin plugin) + { + return Mount(s_pluginFiles[plugin]); + } + + bool PluginManager::Mount(const String& pluginPath, bool appendExtension) + { + if (!Initialize()) + { + NazaraError("Failed to initialize PluginManager"); + return false; + } + + String path = pluginPath; + if (appendExtension && !path.EndsWith(NAZARA_DYNLIB_EXTENSION)) + path += NAZARA_DYNLIB_EXTENSION; + + bool exists = false; + if (!File::IsAbsolute(path)) + { + for (const String& dir : s_directories) { - path = testPath; - exists = true; - break; + String testPath; + testPath.Reserve(dir.GetSize() + path.GetSize() + 10); + + testPath = dir; + testPath += NAZARA_DIRECTORY_SEPARATOR; + testPath += path; + + if (File::Exists(testPath)) + { + path = testPath; + exists = true; + break; + } } } - } - else if (NzFile::Exists(path)) - exists = true; + else if (File::Exists(path)) + exists = true; - if (!exists) - { - NazaraError("Failed to find plugin file"); - return false; + if (!exists) + { + NazaraError("Failed to find plugin file"); + return false; + } + + std::unique_ptr library(new DynLib); + if (!library->Load(path)) + { + NazaraError("Failed to load plugin"); + return false; + } + + PluginLoad func = reinterpret_cast(library->GetSymbol("PluginLoad")); + if (!func) + { + NazaraError("Failed to get symbol PluginLoad"); + return false; + } + + if (!func()) + { + NazaraError("Plugin failed to load"); + return false; + } + + s_plugins[pluginPath] = library.release(); + + return true; } - std::unique_ptr library(new NzDynLib); - if (!library->Load(path)) + void PluginManager::RemoveDirectory(const String& directoryPath) { - NazaraError("Failed to load plugin"); - return false; + if (!Initialize()) + { + NazaraError("Failed to initialize PluginManager"); + return; + } + + s_directories.erase(File::AbsolutePath(directoryPath)); } - PluginLoad func = reinterpret_cast(library->GetSymbol("NzPluginLoad")); - if (!func) + void PluginManager::Unmount(Plugin plugin) { - NazaraError("Failed to get symbol NzPluginLoad"); - return false; + Unmount(s_pluginFiles[plugin]); } - if (!func()) + void PluginManager::Unmount(const String& pluginPath) { - NazaraError("Plugin failed to load"); - return false; - } + if (!Initialize()) + { + NazaraError("Failed to initialize PluginManager"); + return; + } - s_plugins[pluginPath] = library.release(); + auto it = s_plugins.find(pluginPath); + if (it == s_plugins.end()) + { + NazaraError("Plugin not loaded"); + return; + } - return true; -} - -void NzPluginManager::RemoveDirectory(const NzString& directoryPath) -{ - if (!Initialize()) - { - NazaraError("Failed to initialize PluginManager"); - return; - } - - s_directories.erase(NzFile::AbsolutePath(directoryPath)); -} - -void NzPluginManager::Unmount(nzPlugin plugin) -{ - Unmount(s_pluginFiles[plugin]); -} - -void NzPluginManager::Unmount(const NzString& pluginPath) -{ - if (!Initialize()) - { - NazaraError("Failed to initialize PluginManager"); - return; - } - - auto it = s_plugins.find(pluginPath); - if (it == s_plugins.end()) - { - NazaraError("Plugin not loaded"); - return; - } - - PluginUnload func = reinterpret_cast(it->second->GetSymbol("NzPluginUnload")); - if (func) - func(); - - it->second->Unload(); - delete it->second; - - s_plugins.erase(it); -} - -void NzPluginManager::Uninitialize() -{ - if (!s_initialized) - return; - - s_initialized = false; - - s_directories.clear(); - - for (auto& pair : s_plugins) - { - PluginUnload func = reinterpret_cast(pair.second->GetSymbol("NzPluginUnload")); + PluginUnload func = reinterpret_cast(it->second->GetSymbol("PluginUnload")); if (func) func(); - pair.second->Unload(); - delete pair.second; + it->second->Unload(); + delete it->second; + + s_plugins.erase(it); } - s_plugins.clear(); -} + void PluginManager::Uninitialize() + { + if (!s_initialized) + return; -std::set NzPluginManager::s_directories; -std::unordered_map NzPluginManager::s_plugins; -bool NzPluginManager::s_initialized = false; + s_initialized = false; + + s_directories.clear(); + + for (auto& pair : s_plugins) + { + PluginUnload func = reinterpret_cast(pair.second->GetSymbol("PluginUnload")); + if (func) + func(); + + pair.second->Unload(); + delete pair.second; + } + + s_plugins.clear(); + } + + std::set PluginManager::s_directories; + std::unordered_map PluginManager::s_plugins; + bool PluginManager::s_initialized = false; +} diff --git a/src/Nazara/Core/PrimitiveList.cpp b/src/Nazara/Core/PrimitiveList.cpp index 2636ed415..9c85cea55 100644 --- a/src/Nazara/Core/PrimitiveList.cpp +++ b/src/Nazara/Core/PrimitiveList.cpp @@ -6,112 +6,115 @@ #include #include -void NzPrimitiveList::AddBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzMatrix4f& transformMatrix) +namespace Nz { - m_primitives.push_back(NzPrimitive::Box(lengths, subdivision, transformMatrix)); -} - -void NzPrimitiveList::AddBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation) -{ - m_primitives.push_back(NzPrimitive::Box(lengths, subdivision, position, rotation)); -} - -void NzPrimitiveList::AddCone(float length, float radius, unsigned int subdivision, const NzMatrix4f& transformMatrix) -{ - m_primitives.push_back(NzPrimitive::Cone(length, radius, subdivision, transformMatrix)); -} - -void NzPrimitiveList::AddCone(float length, float radius, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation) -{ - m_primitives.push_back(NzPrimitive::Cone(length, radius, subdivision, position, rotation)); -} - -void NzPrimitiveList::AddCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& transformMatrix) -{ - m_primitives.push_back(NzPrimitive::CubicSphere(size, subdivision, transformMatrix)); -} - -void NzPrimitiveList::AddCubicSphere(float size, unsigned int subdivision, const NzVector3f& position, const NzQuaternionf& rotation) -{ - m_primitives.push_back(NzPrimitive::CubicSphere(size, subdivision, position, rotation)); -} - -void NzPrimitiveList::AddIcoSphere(float size, unsigned int recursionLevel, const NzMatrix4f& transformMatrix) -{ - m_primitives.push_back(NzPrimitive::IcoSphere(size, recursionLevel, transformMatrix)); -} - -void NzPrimitiveList::AddIcoSphere(float size, unsigned int recursionLevel, const NzVector3f& position, const NzQuaternionf& rotation) -{ - m_primitives.push_back(NzPrimitive::IcoSphere(size, recursionLevel, position, rotation)); -} - -void NzPrimitiveList::AddPlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzMatrix4f& transformMatrix) -{ - m_primitives.push_back(NzPrimitive::Plane(size, subdivision, transformMatrix)); -} - -void NzPrimitiveList::AddPlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzPlanef& planeInfo) -{ - m_primitives.push_back(NzPrimitive::Plane(size, subdivision, planeInfo)); -} - -void NzPrimitiveList::AddPlane(const NzVector2f& size, const NzVector2ui& subdivision, const NzVector3f& position, const NzQuaternionf& rotation) -{ - m_primitives.push_back(NzPrimitive::Plane(size, subdivision, position, rotation)); -} - -void NzPrimitiveList::AddUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzMatrix4f& transformMatrix) -{ - m_primitives.push_back(NzPrimitive::UVSphere(size, sliceCount, stackCount, transformMatrix)); -} - -void NzPrimitiveList::AddUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzVector3f& position, const NzQuaternionf& rotation) -{ - m_primitives.push_back(NzPrimitive::UVSphere(size, sliceCount, stackCount, position, rotation)); -} - -NzPrimitive& NzPrimitiveList::GetPrimitive(unsigned int i) -{ - #if NAZARA_CORE_SAFE - if (i >= m_primitives.size()) + void PrimitiveList::AddBox(const Vector3f& lengths, const Vector3ui& subdivision, const Matrix4f& transformMatrix) { - NazaraError("Primitive index out of range (" + NzString::Number(i) + " >= " + NzString::Number(m_primitives.size()) + ')'); - - static NzPrimitive dummy; - return dummy; + m_primitives.push_back(Primitive::Box(lengths, subdivision, transformMatrix)); } - #endif - return m_primitives[i]; -} - -const NzPrimitive& NzPrimitiveList::GetPrimitive(unsigned int i) const -{ - #if NAZARA_CORE_SAFE - if (i >= m_primitives.size()) + void PrimitiveList::AddBox(const Vector3f& lengths, const Vector3ui& subdivision, const Vector3f& position, const Quaternionf& rotation) { - NazaraError("Primitive index out of range (" + NzString::Number(i) + " >= " + NzString::Number(m_primitives.size()) + ')'); - - static NzPrimitive dummy; - return dummy; + m_primitives.push_back(Primitive::Box(lengths, subdivision, position, rotation)); } - #endif - return m_primitives[i]; -} + void PrimitiveList::AddCone(float length, float radius, unsigned int subdivision, const Matrix4f& transformMatrix) + { + m_primitives.push_back(Primitive::Cone(length, radius, subdivision, transformMatrix)); + } -unsigned int NzPrimitiveList::GetSize() const -{ - return m_primitives.size(); -} + void PrimitiveList::AddCone(float length, float radius, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation) + { + m_primitives.push_back(Primitive::Cone(length, radius, subdivision, position, rotation)); + } -NzPrimitive& NzPrimitiveList::operator()(unsigned int i) -{ - return GetPrimitive(i); -} + void PrimitiveList::AddCubicSphere(float size, unsigned int subdivision, const Matrix4f& transformMatrix) + { + m_primitives.push_back(Primitive::CubicSphere(size, subdivision, transformMatrix)); + } -const NzPrimitive& NzPrimitiveList::operator()(unsigned int i) const -{ - return GetPrimitive(i); + void PrimitiveList::AddCubicSphere(float size, unsigned int subdivision, const Vector3f& position, const Quaternionf& rotation) + { + m_primitives.push_back(Primitive::CubicSphere(size, subdivision, position, rotation)); + } + + void PrimitiveList::AddIcoSphere(float size, unsigned int recursionLevel, const Matrix4f& transformMatrix) + { + m_primitives.push_back(Primitive::IcoSphere(size, recursionLevel, transformMatrix)); + } + + void PrimitiveList::AddIcoSphere(float size, unsigned int recursionLevel, const Vector3f& position, const Quaternionf& rotation) + { + m_primitives.push_back(Primitive::IcoSphere(size, recursionLevel, position, rotation)); + } + + void PrimitiveList::AddPlane(const Vector2f& size, const Vector2ui& subdivision, const Matrix4f& transformMatrix) + { + m_primitives.push_back(Primitive::Plane(size, subdivision, transformMatrix)); + } + + void PrimitiveList::AddPlane(const Vector2f& size, const Vector2ui& subdivision, const Planef& planeInfo) + { + m_primitives.push_back(Primitive::Plane(size, subdivision, planeInfo)); + } + + void PrimitiveList::AddPlane(const Vector2f& size, const Vector2ui& subdivision, const Vector3f& position, const Quaternionf& rotation) + { + m_primitives.push_back(Primitive::Plane(size, subdivision, position, rotation)); + } + + void PrimitiveList::AddUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Matrix4f& transformMatrix) + { + m_primitives.push_back(Primitive::UVSphere(size, sliceCount, stackCount, transformMatrix)); + } + + void PrimitiveList::AddUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation) + { + m_primitives.push_back(Primitive::UVSphere(size, sliceCount, stackCount, position, rotation)); + } + + Primitive& PrimitiveList::GetPrimitive(unsigned int i) + { + #if NAZARA_CORE_SAFE + if (i >= m_primitives.size()) + { + NazaraError("Primitive index out of range (" + String::Number(i) + " >= " + String::Number(m_primitives.size()) + ')'); + + static Primitive dummy; + return dummy; + } + #endif + + return m_primitives[i]; + } + + const Primitive& PrimitiveList::GetPrimitive(unsigned int i) const + { + #if NAZARA_CORE_SAFE + if (i >= m_primitives.size()) + { + NazaraError("Primitive index out of range (" + String::Number(i) + " >= " + String::Number(m_primitives.size()) + ')'); + + static Primitive dummy; + return dummy; + } + #endif + + return m_primitives[i]; + } + + unsigned int PrimitiveList::GetSize() const + { + return m_primitives.size(); + } + + Primitive& PrimitiveList::operator()(unsigned int i) + { + return GetPrimitive(i); + } + + const Primitive& PrimitiveList::operator()(unsigned int i) const + { + return GetPrimitive(i); + } } diff --git a/src/Nazara/Core/RefCounted.cpp b/src/Nazara/Core/RefCounted.cpp index 0598fc5d1..db6ea7edf 100644 --- a/src/Nazara/Core/RefCounted.cpp +++ b/src/Nazara/Core/RefCounted.cpp @@ -14,66 +14,68 @@ #include -NzRefCounted::NzRefCounted(bool persistent) : -m_persistent(persistent), -m_referenceCount(0) +namespace Nz { -} - -NzRefCounted::~NzRefCounted() -{ - #if NAZARA_CORE_SAFE - if (m_referenceCount > 0) - NazaraWarning("Resource destroyed while still referenced " + NzString::Number(m_referenceCount) + " time(s)"); - #endif -} - -void NzRefCounted::AddReference() const -{ - m_referenceCount++; -} - -unsigned int NzRefCounted::GetReferenceCount() const -{ - return m_referenceCount; -} - -bool NzRefCounted::IsPersistent() const -{ - return m_persistent; -} - -bool NzRefCounted::RemoveReference() const -{ - #if NAZARA_CORE_SAFE - if (m_referenceCount == 0) + RefCounted::RefCounted(bool persistent) : + m_persistent(persistent), + m_referenceCount(0) { - NazaraError("Impossible to remove reference (Ref. counter is already 0)"); - return false; } - #endif - if (--m_referenceCount == 0 && !m_persistent) + RefCounted::~RefCounted() { - delete this; // Suicide - - return true; + #if NAZARA_CORE_SAFE + if (m_referenceCount > 0) + NazaraWarning("Resource destroyed while still referenced " + String::Number(m_referenceCount) + " time(s)"); + #endif } - else - return false; -} -bool NzRefCounted::SetPersistent(bool persistent, bool checkReferenceCount) -{ - m_persistent = persistent; - - if (checkReferenceCount && !persistent && m_referenceCount == 0) + void RefCounted::AddReference() const { - delete this; - - return true; + m_referenceCount++; } - else - return false; -} + unsigned int RefCounted::GetReferenceCount() const + { + return m_referenceCount; + } + + bool RefCounted::IsPersistent() const + { + return m_persistent; + } + + bool RefCounted::RemoveReference() const + { + #if NAZARA_CORE_SAFE + if (m_referenceCount == 0) + { + NazaraError("Impossible to remove reference (Ref. counter is already 0)"); + return false; + } + #endif + + if (--m_referenceCount == 0 && !m_persistent) + { + delete this; // Suicide + + return true; + } + else + return false; + } + + bool RefCounted::SetPersistent(bool persistent, bool checkReferenceCount) + { + m_persistent = persistent; + + if (checkReferenceCount && !persistent && m_referenceCount == 0) + { + delete this; + + return true; + } + else + return false; + } +} diff --git a/src/Nazara/Core/Resource.cpp b/src/Nazara/Core/Resource.cpp index 789dc91a4..080e4fd22 100644 --- a/src/Nazara/Core/Resource.cpp +++ b/src/Nazara/Core/Resource.cpp @@ -5,14 +5,17 @@ #include #include -NzResource::~NzResource() = default; - -const NzString& NzResource::GetFilePath() const +namespace Nz { - return m_filePath; -} + Resource::~Resource() = default; -void NzResource::SetFilePath(const NzString& filePath) -{ - m_filePath = filePath; + const String& Resource::GetFilePath() const + { + return m_filePath; + } + + void Resource::SetFilePath(const String& filePath) + { + m_filePath = filePath; + } } diff --git a/src/Nazara/Core/Semaphore.cpp b/src/Nazara/Core/Semaphore.cpp index 6cdb83f6d..1a9afdc95 100644 --- a/src/Nazara/Core/Semaphore.cpp +++ b/src/Nazara/Core/Semaphore.cpp @@ -14,32 +14,35 @@ #include -NzSemaphore::NzSemaphore(unsigned int count) +namespace Nz { - m_impl = new NzSemaphoreImpl(count); -} + Semaphore::Semaphore(unsigned int count) + { + m_impl = new SemaphoreImpl(count); + } -NzSemaphore::~NzSemaphore() -{ - delete m_impl; -} + Semaphore::~Semaphore() + { + delete m_impl; + } -unsigned int NzSemaphore::GetCount() const -{ - return m_impl->GetCount(); -} + unsigned int Semaphore::GetCount() const + { + return m_impl->GetCount(); + } -void NzSemaphore::Post() -{ - m_impl->Post(); -} + void Semaphore::Post() + { + m_impl->Post(); + } -void NzSemaphore::Wait() -{ - m_impl->Wait(); -} + void Semaphore::Wait() + { + m_impl->Wait(); + } -bool NzSemaphore::Wait(nzUInt32 timeout) -{ - return m_impl->Wait(timeout); + bool Semaphore::Wait(UInt32 timeout) + { + return m_impl->Wait(timeout); + } } diff --git a/src/Nazara/Core/Stream.cpp b/src/Nazara/Core/Stream.cpp index 77948a382..9e43100bd 100644 --- a/src/Nazara/Core/Stream.cpp +++ b/src/Nazara/Core/Stream.cpp @@ -5,24 +5,27 @@ #include #include -NzStream::~NzStream() = default; - -NzString NzStream::GetDirectory() const +namespace Nz { - return NzString(); -} + Stream::~Stream() = default; -NzString NzStream::GetPath() const -{ - return NzString(); -} + String Stream::GetDirectory() const + { + return String(); + } -unsigned int NzStream::GetStreamOptions() const -{ - return m_streamOptions; -} + String Stream::GetPath() const + { + return String(); + } -void NzStream::SetStreamOptions(unsigned int options) -{ - m_streamOptions = options; + unsigned int Stream::GetStreamOptions() const + { + return m_streamOptions; + } + + void Stream::SetStreamOptions(unsigned int options) + { + m_streamOptions = options; + } } diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index b14ba452c..d7f1aef14 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -19,225 +19,330 @@ #include #include -// Cet algorithme est inspiré de la documentation de Qt -inline unsigned int nzGetNewSize(unsigned int newSize) +namespace Nz { - if (newSize < 20) - return newSize+4; - else + namespace Detail { - if (newSize < (1 << 12)-12) - return NzGetNearestPowerOfTwo(newSize << 1)-12; - else - return newSize + (1 << 11); + // Cet algorithme est inspiré de la documentation de Qt + inline unsigned int GetNewSize(unsigned int newSize) + { + if (newSize < 20) + return newSize+4; + else + { + if (newSize < (1 << 12)-12) + return GetNearestPowerOfTwo(newSize << 1)-12; + else + return newSize + (1 << 11); + } + } + + inline char ToLower(char character) + { + if (character >= 'A' && character <= 'Z') + return character + ('a' - 'A'); + else + return character; + } + + inline char ToUpper(char character) + { + if (character >= 'a' && character <= 'z') + return character + ('A' - 'a'); + else + return character; + } + + inline int Strcasecmp(const char* s1, const char* s2) + { + int ret = 0; + + while (!(ret = static_cast(Detail::ToLower(*s1)) - static_cast(Detail::ToLower(*s2))) && *s2) + ++s1, ++s2; + + return ret != 0 ? (ret > 0 ? 1 : -1) : 0; + } + + inline int Unicodecasecmp(const char* s1, const char* s2) + { + int ret = 0; + utf8::unchecked::iterator it1(s1); + utf8::unchecked::iterator it2(s2); + + while (!(ret = Unicode::GetLowercase(*it1) - Unicode::GetLowercase(*it2)) && *it2) + ++it1, ++it2; + + return ret != 0 ? (ret > 0 ? 1 : -1) : 0; + } } -} -inline char nzToLower(char character) -{ - if (character >= 'A' && character <= 'Z') - return character + ('a' - 'A'); - else - return character; -} - -inline char nzToUpper(char character) -{ - if (character >= 'a' && character <= 'z') - return character + ('A' - 'a'); - else - return character; -} - -inline int nzStrcasecmp(const char* s1, const char* s2) -{ - int ret = 0; - - while (!(ret = static_cast(nzToLower(*s1)) - static_cast(nzToLower(*s2))) && *s2) - ++s1, ++s2; - - return ret != 0 ? (ret > 0 ? 1 : -1) : 0; -} - -inline int nzUnicodecasecmp(const char* s1, const char* s2) -{ - int ret = 0; - utf8::unchecked::iterator it1(s1); - utf8::unchecked::iterator it2(s2); - - while (!(ret = NzUnicode::GetLowercase(*it1) - NzUnicode::GetLowercase(*it2)) && *it2) - ++it1, ++it2; - - return ret != 0 ? (ret > 0 ? 1 : -1) : 0; -} - -NzString::NzString() : -m_sharedString(GetEmptyString()) -{ -} - -NzString::NzString(char character) -{ - if (character != '\0') + String::String() : + m_sharedString(GetEmptyString()) { - m_sharedString = std::make_shared(1); - m_sharedString->string[0] = character; } -} -NzString::NzString(unsigned int rep, char character) -{ - if (rep > 0) + String::String(char character) { - m_sharedString = std::make_shared(rep); - if (character != '\0') - std::memset(m_sharedString->string.get(), character, rep); - } -} - -NzString::NzString(unsigned int rep, const char* string) : -NzString(rep, string, (string) ? std::strlen(string) : 0) -{ -} - -NzString::NzString(unsigned int rep, const char* string, unsigned int length) -{ - unsigned int totalSize = rep*length; - - if (totalSize > 0) - { - m_sharedString = std::make_shared(totalSize); - - for (unsigned int i = 0; i < rep; ++i) - std::memcpy(&m_sharedString->string[i*length], string, length); - } -} - -NzString::NzString(unsigned int rep, const NzString& string) : -NzString(rep, string.GetConstBuffer(), string.GetSize()) -{ -} - -NzString::NzString(const char* string) : -NzString(string, (string) ? std::strlen(string) : 0) -{ -} - -NzString::NzString(const char* string, unsigned int length) -{ - if (length > 0) - { - m_sharedString = std::make_shared(length); - std::memcpy(m_sharedString->string.get(), string, length); - } -} - -NzString::NzString(const std::string& string) : -NzString(string.c_str(), string.size()) -{ -} - -NzString& NzString::Append(char character) -{ - return Insert(m_sharedString->size, character); -} - -NzString& NzString::Append(const char* string) -{ - return Insert(m_sharedString->size, string); -} - -NzString& NzString::Append(const char* string, unsigned int length) -{ - return Insert(m_sharedString->size, string, length); -} - -NzString& NzString::Append(const NzString& string) -{ - return Insert(m_sharedString->size, string); -} - -void NzString::Clear(bool keepBuffer) -{ - if (keepBuffer) - { - EnsureOwnership(true); - m_sharedString->size = 0; - m_sharedString->string.reset(); - } - else - ReleaseString(); -} - -bool NzString::Contains(char character, int start, nzUInt32 flags) const -{ - return Find(character, start, flags) != npos; -} - -bool NzString::Contains(const char* string, int start, nzUInt32 flags) const -{ - return Find(string, start, flags) != npos; -} - -bool NzString::Contains(const NzString& string, int start, nzUInt32 flags) const -{ - return Find(string, start, flags) != npos; -} - -unsigned int NzString::Count(char character, int start, nzUInt32 flags) const -{ - if (character == '\0' || m_sharedString->size == 0) - return 0; - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return 0; - - char* str = &m_sharedString->string[pos]; - unsigned int count = 0; - if (flags & CaseInsensitive) - { - char character_lower = nzToLower(character); - char character_upper = nzToUpper(character); - do { - if (*str == character_lower || *str == character_upper) + m_sharedString = std::make_shared(1); + m_sharedString->string[0] = character; + } + } + + String::String(unsigned int rep, char character) + { + if (rep > 0) + { + m_sharedString = std::make_shared(rep); + + if (character != '\0') + std::memset(m_sharedString->string.get(), character, rep); + } + } + + String::String(unsigned int rep, const char* string) : + String(rep, string, (string) ? std::strlen(string) : 0) + { + } + + String::String(unsigned int rep, const char* string, unsigned int length) + { + unsigned int totalSize = rep*length; + + if (totalSize > 0) + { + m_sharedString = std::make_shared(totalSize); + + for (unsigned int i = 0; i < rep; ++i) + std::memcpy(&m_sharedString->string[i*length], string, length); + } + } + + String::String(unsigned int rep, const String& string) : + String(rep, string.GetConstBuffer(), string.GetSize()) + { + } + + String::String(const char* string) : + String(string, (string) ? std::strlen(string) : 0) + { + } + + String::String(const char* string, unsigned int length) + { + if (length > 0) + { + m_sharedString = std::make_shared(length); + std::memcpy(m_sharedString->string.get(), string, length); + } + } + + String::String(const std::string& string) : + String(string.c_str(), string.size()) + { + } + + String& String::Append(char character) + { + return Insert(m_sharedString->size, character); + } + + String& String::Append(const char* string) + { + return Insert(m_sharedString->size, string); + } + + String& String::Append(const char* string, unsigned int length) + { + return Insert(m_sharedString->size, string, length); + } + + String& String::Append(const String& string) + { + return Insert(m_sharedString->size, string); + } + + void String::Clear(bool keepBuffer) + { + if (keepBuffer) + { + EnsureOwnership(true); + m_sharedString->size = 0; + m_sharedString->string.reset(); + } + else + ReleaseString(); + } + + bool String::Contains(char character, int start, UInt32 flags) const + { + return Find(character, start, flags) != npos; + } + + bool String::Contains(const char* string, int start, UInt32 flags) const + { + return Find(string, start, flags) != npos; + } + + bool String::Contains(const String& string, int start, UInt32 flags) const + { + return Find(string, start, flags) != npos; + } + + unsigned int String::Count(char character, int start, UInt32 flags) const + { + if (character == '\0' || m_sharedString->size == 0) + return 0; + + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return 0; + + char* str = &m_sharedString->string[pos]; + unsigned int count = 0; + if (flags & CaseInsensitive) + { + char character_lower = Detail::ToLower(character); + char character_upper = Detail::ToUpper(character); + do + { + if (*str == character_lower || *str == character_upper) + count++; + } + while (*++str); + } + else + { + while ((str = std::strchr(str, character))) + { count++; + str++; + } } - while (*++str); + + return count; } - else + + unsigned int String::Count(const char* string, int start, UInt32 flags) const { - while ((str = std::strchr(str, character))) + if (!string || !string[0] || m_sharedString->size == 0) + return 0; + + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return 0; + + char* str = &m_sharedString->string[pos]; + unsigned int count = 0; + if (flags & CaseInsensitive) { - count++; - str++; + if (flags & HandleUtf8) + { + while (utf8::internal::is_trail(*str)) + str++; + + utf8::unchecked::iterator it(str); + + const char* t = string; + char32_t c = Unicode::GetLowercase(utf8::unchecked::next(t)); + do + { + if (Unicode::GetLowercase(*it) == c) + { + ++it; + + utf8::unchecked::iterator it2(t); + while (true) + { + if (*it2 == '\0') + { + count++; + break; + } + + if (*it == '\0') + return count; + + if (Unicode::GetLowercase(*it) != Unicode::GetLowercase(*it2)) + break; + + ++it; + ++it2; + } + } + } + while (*++it); + } + else + { + char c = Detail::ToLower(string[0]); + do + { + if (Detail::ToLower(*str) == c) + { + str++; + + const char* ptr = &string[1]; + while (true) + { + if (*ptr == '\0') + { + count++; + break; + } + + if (*str == '\0') + return count; + + if (Detail::ToLower(*str) != Detail::ToLower(*ptr)) + break; + + ptr++; + str++; + } + } + } + while (*++str); + } } + else + { + while ((str = std::strstr(str, string))) + { + count++; + str++; + } + } + + return count; } - return count; -} - -unsigned int NzString::Count(const char* string, int start, nzUInt32 flags) const -{ - if (!string || !string[0] || m_sharedString->size == 0) - return 0; - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return 0; - - char* str = &m_sharedString->string[pos]; - unsigned int count = 0; - if (flags & CaseInsensitive) + unsigned int String::Count(const String& string, int start, UInt32 flags) const { + return Count(string.GetConstBuffer(), start, flags); + } + + unsigned int String::CountAny(const char* string, int start, UInt32 flags) const + { + if (!string || !string[0] || m_sharedString->size == 0) + return 0; + + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return 0; + + char* str = &m_sharedString->string[pos]; + unsigned int count = 0; if (flags & HandleUtf8) { while (utf8::internal::is_trail(*str)) @@ -245,265 +350,258 @@ unsigned int NzString::Count(const char* string, int start, nzUInt32 flags) cons utf8::unchecked::iterator it(str); - const char* t = string; - char32_t c = NzUnicode::GetLowercase(utf8::unchecked::next(t)); - do + if (flags & CaseInsensitive) { - if (NzUnicode::GetLowercase(*it) == c) + do { - ++it; - - utf8::unchecked::iterator it2(t); - while (true) + utf8::unchecked::iterator it2(string); + do { - if (*it2 == '\0') + if (Unicode::GetLowercase(*it) == Unicode::GetLowercase(*it2)) { count++; break; } - - if (*it == '\0') - return count; - - if (NzUnicode::GetLowercase(*it) != NzUnicode::GetLowercase(*it2)) - break; - - ++it; - ++it2; } + while (*++it2); } + while (*++str); + } + else + { + do + { + utf8::unchecked::iterator it2(string); + do + { + if (*it == *it2) + { + count++; + break; + } + } + while (*++it2); + } + while (*++str); } - while (*++it); } else { - char c = nzToLower(string[0]); - do + if (flags & CaseInsensitive) { - if (nzToLower(*str) == c) + do { + const char* c = string; + do + { + if (Detail::ToLower(*str) == Detail::ToLower(*c)) + { + count++; + break; + } + } + while (*++c); + } + while (*++str); + } + else + { + while ((str = std::strpbrk(str, string))) + { + count++; str++; - - const char* ptr = &string[1]; - while (true) - { - if (*ptr == '\0') - { - count++; - break; - } - - if (*str == '\0') - return count; - - if (nzToLower(*str) != nzToLower(*ptr)) - break; - - ptr++; - str++; - } } } - while (*++str); - } - } - else - { - while ((str = std::strstr(str, string))) - { - count++; - str++; } + + return count; } - return count; -} - -unsigned int NzString::Count(const NzString& string, int start, nzUInt32 flags) const -{ - return Count(string.GetConstBuffer(), start, flags); -} - -unsigned int NzString::CountAny(const char* string, int start, nzUInt32 flags) const -{ - if (!string || !string[0] || m_sharedString->size == 0) - return 0; - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return 0; - - char* str = &m_sharedString->string[pos]; - unsigned int count = 0; - if (flags & HandleUtf8) + unsigned int String::CountAny(const String& string, int start, UInt32 flags) const { - while (utf8::internal::is_trail(*str)) - str++; + return CountAny(string.GetConstBuffer(), start, flags); + } - utf8::unchecked::iterator it(str); + bool String::EndsWith(char character, UInt32 flags) const + { + if (m_sharedString->size == 0) + return 0; + + if (flags & CaseInsensitive) + return Detail::ToLower(m_sharedString->string[m_sharedString->size-1]) == Detail::ToLower(character); + else + return m_sharedString->string[m_sharedString->size-1] == character; // character == '\0' sera toujours faux + } + + bool String::EndsWith(const char* string, UInt32 flags) const + { + return EndsWith(string, std::strlen(string), flags); + } + + bool String::EndsWith(const char* string, unsigned int length, UInt32 flags) const + { + if (!string || !string[0] || m_sharedString->size == 0 || length > m_sharedString->size) + return false; if (flags & CaseInsensitive) { - do - { - utf8::unchecked::iterator it2(string); - do - { - if (NzUnicode::GetLowercase(*it) == NzUnicode::GetLowercase(*it2)) - { - count++; - break; - } - } - while (*++it2); - } - while (*++str); + if (flags & HandleUtf8) + return Detail::Unicodecasecmp(&m_sharedString->string[m_sharedString->size - length], string) == 0; + else + return Detail::Strcasecmp(&m_sharedString->string[m_sharedString->size - length], string) == 0; } else - { - do - { - utf8::unchecked::iterator it2(string); - do - { - if (*it == *it2) - { - count++; - break; - } - } - while (*++it2); - } - while (*++str); - } - } - else - { - if (flags & CaseInsensitive) - { - do - { - const char* c = string; - do - { - if (nzToLower(*str) == nzToLower(*c)) - { - count++; - break; - } - } - while (*++c); - } - while (*++str); - } - else - { - while ((str = std::strpbrk(str, string))) - { - count++; - str++; - } - } + return std::strcmp(&m_sharedString->string[m_sharedString->size - length], string) == 0; } - return count; -} - -unsigned int NzString::CountAny(const NzString& string, int start, nzUInt32 flags) const -{ - return CountAny(string.GetConstBuffer(), start, flags); -} - -bool NzString::EndsWith(char character, nzUInt32 flags) const -{ - if (m_sharedString->size == 0) - return 0; - - if (flags & CaseInsensitive) - return nzToLower(m_sharedString->string[m_sharedString->size-1]) == nzToLower(character); - else - return m_sharedString->string[m_sharedString->size-1] == character; // character == '\0' sera toujours faux -} - -bool NzString::EndsWith(const char* string, nzUInt32 flags) const -{ - return EndsWith(string, std::strlen(string), flags); -} - -bool NzString::EndsWith(const char* string, unsigned int length, nzUInt32 flags) const -{ - if (!string || !string[0] || m_sharedString->size == 0 || length > m_sharedString->size) - return false; - - if (flags & CaseInsensitive) + bool String::EndsWith(const String& string, UInt32 flags) const { - if (flags & HandleUtf8) - return nzUnicodecasecmp(&m_sharedString->string[m_sharedString->size - length], string) == 0; - else - return nzStrcasecmp(&m_sharedString->string[m_sharedString->size - length], string) == 0; + return EndsWith(string.GetConstBuffer(), string.m_sharedString->size, flags); } - else - return std::strcmp(&m_sharedString->string[m_sharedString->size - length], string) == 0; -} -bool NzString::EndsWith(const NzString& string, nzUInt32 flags) const -{ - return EndsWith(string.GetConstBuffer(), string.m_sharedString->size, flags); -} - -unsigned int NzString::Find(char character, int start, nzUInt32 flags) const -{ - if (character == '\0' || m_sharedString->size == 0) - return npos; - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return npos; - - if (flags & CaseInsensitive) + unsigned int String::Find(char character, int start, UInt32 flags) const { - char ch = nzToLower(character); - const char* str = m_sharedString->string.get(); - do - { - if (nzToLower(*str) == ch) - return static_cast(str - m_sharedString->string.get()); - } - while (*++str); - - return npos; - } - else - { - char* ch = std::strchr(&m_sharedString->string[pos], character); - if (ch) - return static_cast(ch - m_sharedString->string.get()); - else + if (character == '\0' || m_sharedString->size == 0) return npos; + + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return npos; + + if (flags & CaseInsensitive) + { + char ch = Detail::ToLower(character); + const char* str = m_sharedString->string.get(); + do + { + if (Detail::ToLower(*str) == ch) + return static_cast(str - m_sharedString->string.get()); + } + while (*++str); + + return npos; + } + else + { + char* ch = std::strchr(&m_sharedString->string[pos], character); + if (ch) + return static_cast(ch - m_sharedString->string.get()); + else + return npos; + } } -} -unsigned int NzString::Find(const char* string, int start, nzUInt32 flags) const -{ - if (!string || !string[0] || m_sharedString->size == 0) - return npos; - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return npos; - - char* str = &m_sharedString->string[pos]; - if (flags & CaseInsensitive) + unsigned int String::Find(const char* string, int start, UInt32 flags) const { + if (!string || !string[0] || m_sharedString->size == 0) + return npos; + + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return npos; + + char* str = &m_sharedString->string[pos]; + if (flags & CaseInsensitive) + { + if (flags & HandleUtf8) + { + while (utf8::internal::is_trail(*str)) + str++; + + utf8::unchecked::iterator it(str); + + const char* t = string; + char32_t c = Unicode::GetLowercase(utf8::unchecked::next(t)); + do + { + if (Unicode::GetLowercase(*it) == c) + { + const char* ptrPos = it.base(); + ++it; + + utf8::unchecked::iterator it2(t); + while (true) + { + if (*it2 == '\0') + return static_cast(ptrPos - m_sharedString->string.get()); + + if (*it == '\0') + return npos; + + if (Unicode::GetLowercase(*it) != Unicode::GetLowercase(*it2)) + break; + + ++it; + ++it2; + } + } + } + while (*++it); + } + else + { + char c = Detail::ToLower(string[0]); + do + { + if (Detail::ToLower(*str) == c) + { + char* ptrPos = str; + str++; + + const char* ptr = &string[1]; + while (true) + { + if (*ptr == '\0') + return static_cast(ptrPos - m_sharedString->string.get()); + + if (*str == '\0') + return npos; + + if (Detail::ToLower(*str) != Detail::ToLower(*ptr)) + break; + + ptr++; + str++; + } + } + } + while (*++str); + } + } + else + { + char* ch = std::strstr(&m_sharedString->string[pos], string); + if (ch) + return static_cast(ch - m_sharedString->string.get()); + } + + return npos; + } + + unsigned int String::Find(const String& string, int start, UInt32 flags) const + { + return Find(string.GetConstBuffer(), start, flags); + } + + unsigned int String::FindAny(const char* string, int start, UInt32 flags) const + { + if (m_sharedString->size == 0 || !string || !string[0]) + return npos; + + if (start < 0) + start = std::max(m_sharedString->size+start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return npos; + + char* str = &m_sharedString->string[pos]; if (flags & HandleUtf8) { while (utf8::internal::is_trail(*str)) @@ -511,255 +609,189 @@ unsigned int NzString::Find(const char* string, int start, nzUInt32 flags) const utf8::unchecked::iterator it(str); - const char* t = string; - char32_t c = NzUnicode::GetLowercase(utf8::unchecked::next(t)); - do + if (flags & CaseInsensitive) { - if (NzUnicode::GetLowercase(*it) == c) - { - const char* ptrPos = it.base(); - ++it; - - utf8::unchecked::iterator it2(t); - while (true) - { - if (*it2 == '\0') - return static_cast(ptrPos - m_sharedString->string.get()); - - if (*it == '\0') - return npos; - - if (NzUnicode::GetLowercase(*it) != NzUnicode::GetLowercase(*it2)) - break; - - ++it; - ++it2; - } - } - } - while (*++it); - } - else - { - char c = nzToLower(string[0]); - do - { - if (nzToLower(*str) == c) - { - char* ptrPos = str; - str++; - - const char* ptr = &string[1]; - while (true) - { - if (*ptr == '\0') - return static_cast(ptrPos - m_sharedString->string.get()); - - if (*str == '\0') - return npos; - - if (nzToLower(*str) != nzToLower(*ptr)) - break; - - ptr++; - str++; - } - } - } - while (*++str); - } - } - else - { - char* ch = std::strstr(&m_sharedString->string[pos], string); - if (ch) - return static_cast(ch - m_sharedString->string.get()); - } - - return npos; -} - -unsigned int NzString::Find(const NzString& string, int start, nzUInt32 flags) const -{ - return Find(string.GetConstBuffer(), start, flags); -} - -unsigned int NzString::FindAny(const char* string, int start, nzUInt32 flags) const -{ - if (m_sharedString->size == 0 || !string || !string[0]) - return npos; - - if (start < 0) - start = std::max(m_sharedString->size+start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return npos; - - char* str = &m_sharedString->string[pos]; - if (flags & HandleUtf8) - { - while (utf8::internal::is_trail(*str)) - str++; - - utf8::unchecked::iterator it(str); - - if (flags & CaseInsensitive) - { - do - { - utf8::unchecked::iterator it2(string); - char32_t character = NzUnicode::GetLowercase(*it); do { - if (character == NzUnicode::GetLowercase(*it2)) - return it.base() - m_sharedString->string.get(); - } - while (*++it2); - } - while (*++it); - } - else - { - do - { - utf8::unchecked::iterator it2(string); - do - { - if (*it == *it2) - return it.base() - m_sharedString->string.get(); - } - while (*++it2); - } - while (*++it); - } - } - else - { - if (flags & CaseInsensitive) - { - do - { - const char* c = string; - char character = nzToLower(*str); - do - { - if (character == nzToLower(*c)) - return str - m_sharedString->string.get(); - } - while (*++c); - } - while (*++str); - } - else - { - str = std::strpbrk(str, string); - if (str) - return str - m_sharedString->string.get(); - } - } - - return npos; -} - -unsigned int NzString::FindAny(const NzString& string, int start, nzUInt32 flags) const -{ - return FindAny(string.GetConstBuffer(), start, flags); -} - -unsigned int NzString::FindLast(char character, int start, nzUInt32 flags) const -{ - if (character == '\0' || m_sharedString->size == 0) - return npos; - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return npos; - - char* ptr = &m_sharedString->string[m_sharedString->size-1]; - - if (flags & CaseInsensitive) - { - character = nzToLower(character); - do - { - if (nzToLower(*ptr) == character) - return static_cast(ptr - m_sharedString->string.get()); - } - while (ptr-- != m_sharedString->string.get()); - } - else - { - do - { - if (*ptr == character) - return static_cast(ptr - m_sharedString->string.get()); - } - while (ptr-- != m_sharedString->string.get()); - } - - return npos; -} - -unsigned int NzString::FindLast(const char* string, int start, nzUInt32 flags) const -{ - if (!string || !string[0] || m_sharedString->size == 0) - return npos; - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return npos; - - ///Algo 1.FindLast#3 (Taille du pattern inconnue) - const char* ptr = &m_sharedString->string[pos]; - if (flags & CaseInsensitive) - { - if (flags & HandleUtf8) - { - if (utf8::internal::is_trail(*ptr)) - utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère - - utf8::unchecked::iterator it(ptr); - const char* t = string; - char32_t c = NzUnicode::GetLowercase(utf8::unchecked::next(t)); - do - { - if (NzUnicode::GetLowercase(*it) == c) - { - utf8::unchecked::iterator it2(t); - utf8::unchecked::iterator tIt(it); - ++tIt; - - while (true) + utf8::unchecked::iterator it2(string); + char32_t character = Unicode::GetLowercase(*it); + do { - if (*it2 == '\0') + if (character == Unicode::GetLowercase(*it2)) return it.base() - m_sharedString->string.get(); - - if (tIt.base() > &m_sharedString->string[pos]) - break; - - if (NzUnicode::GetLowercase(*tIt) != NzUnicode::GetLowercase(*it2)) - break; - - ++it2; - ++tIt; } + while (*++it2); } + while (*++it); + } + else + { + do + { + utf8::unchecked::iterator it2(string); + do + { + if (*it == *it2) + return it.base() - m_sharedString->string.get(); + } + while (*++it2); + } + while (*++it); } - while (it--.base() != m_sharedString->string.get()); } else { - char c = nzToLower(string[0]); + if (flags & CaseInsensitive) + { + do + { + const char* c = string; + char character = Detail::ToLower(*str); + do + { + if (character == Detail::ToLower(*c)) + return str - m_sharedString->string.get(); + } + while (*++c); + } + while (*++str); + } + else + { + str = std::strpbrk(str, string); + if (str) + return str - m_sharedString->string.get(); + } + } + + return npos; + } + + unsigned int String::FindAny(const String& string, int start, UInt32 flags) const + { + return FindAny(string.GetConstBuffer(), start, flags); + } + + unsigned int String::FindLast(char character, int start, UInt32 flags) const + { + if (character == '\0' || m_sharedString->size == 0) + return npos; + + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return npos; + + char* ptr = &m_sharedString->string[m_sharedString->size-1]; + + if (flags & CaseInsensitive) + { + character = Detail::ToLower(character); do { - if (nzToLower(*ptr) == c) + if (Detail::ToLower(*ptr) == character) + return static_cast(ptr - m_sharedString->string.get()); + } + while (ptr-- != m_sharedString->string.get()); + } + else + { + do + { + if (*ptr == character) + return static_cast(ptr - m_sharedString->string.get()); + } + while (ptr-- != m_sharedString->string.get()); + } + + return npos; + } + + unsigned int String::FindLast(const char* string, int start, UInt32 flags) const + { + if (!string || !string[0] || m_sharedString->size == 0) + return npos; + + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return npos; + + ///Algo 1.FindLast#3 (Taille du pattern inconnue) + const char* ptr = &m_sharedString->string[pos]; + if (flags & CaseInsensitive) + { + if (flags & HandleUtf8) + { + if (utf8::internal::is_trail(*ptr)) + utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère + + utf8::unchecked::iterator it(ptr); + const char* t = string; + char32_t c = Unicode::GetLowercase(utf8::unchecked::next(t)); + do + { + if (Unicode::GetLowercase(*it) == c) + { + utf8::unchecked::iterator it2(t); + utf8::unchecked::iterator tIt(it); + ++tIt; + + while (true) + { + if (*it2 == '\0') + return it.base() - m_sharedString->string.get(); + + if (tIt.base() > &m_sharedString->string[pos]) + break; + + if (Unicode::GetLowercase(*tIt) != Unicode::GetLowercase(*it2)) + break; + + ++it2; + ++tIt; + } + } + } + while (it--.base() != m_sharedString->string.get()); + } + else + { + char c = Detail::ToLower(string[0]); + do + { + if (Detail::ToLower(*ptr) == c) + { + const char* p = &string[1]; + const char* tPtr = ptr+1; + while (true) + { + if (*p == '\0') + return ptr - m_sharedString->string.get(); + + if (tPtr > &m_sharedString->string[pos]) + break; + + if (Detail::ToLower(*tPtr) != Detail::ToLower(*p)) + break; + + p++; + tPtr++; + } + } + } + while (ptr-- != m_sharedString->string.get()); + } + } + else + { + do + { + if (*ptr == string[0]) { const char* p = &string[1]; const char* tPtr = ptr+1; @@ -771,7 +803,7 @@ unsigned int NzString::FindLast(const char* string, int start, nzUInt32 flags) c if (tPtr > &m_sharedString->string[pos]) break; - if (nzToLower(*tPtr) != nzToLower(*p)) + if (*tPtr != *p) break; p++; @@ -781,101 +813,99 @@ unsigned int NzString::FindLast(const char* string, int start, nzUInt32 flags) c } while (ptr-- != m_sharedString->string.get()); } - } - else - { - do - { - if (*ptr == string[0]) - { - const char* p = &string[1]; - const char* tPtr = ptr+1; - while (true) - { - if (*p == '\0') - return ptr - m_sharedString->string.get(); - if (tPtr > &m_sharedString->string[pos]) - break; - - if (*tPtr != *p) - break; - - p++; - tPtr++; - } - } - } - while (ptr-- != m_sharedString->string.get()); + return npos; } - return npos; -} - -unsigned int NzString::FindLast(const NzString& string, int start, nzUInt32 flags) const -{ - if (string.m_sharedString->size == 0 || string.m_sharedString->size > m_sharedString->size) - return npos; - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size || string.m_sharedString->size > m_sharedString->size) - return npos; - - const char* ptr = &m_sharedString->string[pos]; - const char* limit = &m_sharedString->string[string.m_sharedString->size-1]; - - if (flags & CaseInsensitive) + unsigned int String::FindLast(const String& string, int start, UInt32 flags) const { - if (flags & HandleUtf8) + if (string.m_sharedString->size == 0 || string.m_sharedString->size > m_sharedString->size) + return npos; + + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size || string.m_sharedString->size > m_sharedString->size) + return npos; + + const char* ptr = &m_sharedString->string[pos]; + const char* limit = &m_sharedString->string[string.m_sharedString->size-1]; + + if (flags & CaseInsensitive) { - ///Algo 1.FindLast#3 (Itérateur non-adapté) - if (utf8::internal::is_trail(*ptr)) - utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère - - utf8::unchecked::iterator it(ptr); - const char* t = string.GetConstBuffer(); - char32_t c = NzUnicode::GetLowercase(utf8::unchecked::next(t)); - do + if (flags & HandleUtf8) { - if (NzUnicode::GetLowercase(*it) == c) - { - utf8::unchecked::iterator it2(t); - utf8::unchecked::iterator tIt(it); - ++tIt; + ///Algo 1.FindLast#3 (Itérateur non-adapté) + if (utf8::internal::is_trail(*ptr)) + utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère - while (true) + utf8::unchecked::iterator it(ptr); + const char* t = string.GetConstBuffer(); + char32_t c = Unicode::GetLowercase(utf8::unchecked::next(t)); + do + { + if (Unicode::GetLowercase(*it) == c) { - if (*it2 == '\0') - return it.base() - m_sharedString->string.get(); - - if (tIt.base() > &m_sharedString->string[pos]) - break; - - if (NzUnicode::GetLowercase(*tIt) != NzUnicode::GetLowercase(*it2)) - break; - - ++it2; + utf8::unchecked::iterator it2(t); + utf8::unchecked::iterator tIt(it); ++tIt; + + while (true) + { + if (*it2 == '\0') + return it.base() - m_sharedString->string.get(); + + if (tIt.base() > &m_sharedString->string[pos]) + break; + + if (Unicode::GetLowercase(*tIt) != Unicode::GetLowercase(*it2)) + break; + + ++it2; + ++tIt; + } } } + while (it--.base() != limit); + } + else + { + ///Algo 1.FindLast#4 (Taille du pattern connue) + char c = Detail::ToLower(string.m_sharedString->string[string.m_sharedString->size-1]); + while (true) + { + if (Detail::ToLower(*ptr) == c) + { + const char* p = &string.m_sharedString->string[string.m_sharedString->size-1]; + for (; p >= &string.m_sharedString->string[0]; --p, --ptr) + { + if (Detail::ToLower(*ptr) != Detail::ToLower(*p)) + break; + + if (p == &string.m_sharedString->string[0]) + return ptr-m_sharedString->string.get(); + + if (ptr == m_sharedString->string.get()) + return npos; + } + } + else if (ptr-- <= limit) + break; + } } - while (it--.base() != limit); } else { ///Algo 1.FindLast#4 (Taille du pattern connue) - char c = nzToLower(string.m_sharedString->string[string.m_sharedString->size-1]); while (true) { - if (nzToLower(*ptr) == c) + if (*ptr == string.m_sharedString->string[string.m_sharedString->size-1]) { const char* p = &string.m_sharedString->string[string.m_sharedString->size-1]; for (; p >= &string.m_sharedString->string[0]; --p, --ptr) { - if (nzToLower(*ptr) != nzToLower(*p)) + if (*ptr != *p) break; if (p == &string.m_sharedString->string[0]) @@ -889,1213 +919,1208 @@ unsigned int NzString::FindLast(const NzString& string, int start, nzUInt32 flag break; } } - } - else - { - ///Algo 1.FindLast#4 (Taille du pattern connue) - while (true) - { - if (*ptr == string.m_sharedString->string[string.m_sharedString->size-1]) - { - const char* p = &string.m_sharedString->string[string.m_sharedString->size-1]; - for (; p >= &string.m_sharedString->string[0]; --p, --ptr) - { - if (*ptr != *p) - break; - if (p == &string.m_sharedString->string[0]) - return ptr-m_sharedString->string.get(); - - if (ptr == m_sharedString->string.get()) - return npos; - } - } - else if (ptr-- <= limit) - break; - } + return npos; } - return npos; -} - -unsigned int NzString::FindLastAny(const char* string, int start, nzUInt32 flags) const -{ - if (!string || !string[0] || m_sharedString->size == 0) - return npos; - - if (start < 0) - start = std::max(m_sharedString->size+start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return npos; - - char* str = &m_sharedString->string[pos]; - if (flags & HandleUtf8) + unsigned int String::FindLastAny(const char* string, int start, UInt32 flags) const { - while (utf8::internal::is_trail(*str)) - str++; + if (!string || !string[0] || m_sharedString->size == 0) + return npos; - utf8::unchecked::iterator it(str); + if (start < 0) + start = std::max(m_sharedString->size+start, 0U); - if (flags & CaseInsensitive) + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return npos; + + char* str = &m_sharedString->string[pos]; + if (flags & HandleUtf8) { - do + while (utf8::internal::is_trail(*str)) + str++; + + utf8::unchecked::iterator it(str); + + if (flags & CaseInsensitive) { - utf8::unchecked::iterator it2(string); - char32_t character = NzUnicode::GetLowercase(*it); do { - if (character == NzUnicode::GetLowercase(*it2)) - return it.base() - m_sharedString->string.get(); + utf8::unchecked::iterator it2(string); + char32_t character = Unicode::GetLowercase(*it); + do + { + if (character == Unicode::GetLowercase(*it2)) + return it.base() - m_sharedString->string.get(); + } + while (*++it2); } - while (*++it2); + while (it--.base() != m_sharedString->string.get()); } - while (it--.base() != m_sharedString->string.get()); - } - else - { - do - { - utf8::unchecked::iterator it2(string); - do - { - if (*it == *it2) - return it.base() - m_sharedString->string.get(); - } - while (*++it2); - } - while (it--.base() != m_sharedString->string.get()); - } - } - else - { - if (flags & CaseInsensitive) - { - do - { - const char* c = string; - char character = nzToLower(*str); - do - { - if (character == nzToLower(*c)) - return str - m_sharedString->string.get(); - } - while (*++c); - } - while (str-- != m_sharedString->string.get()); - } - else - { - do - { - const char* c = string; - do - { - if (*str == *c) - return str - m_sharedString->string.get(); - } - while (*++c); - } - while (str-- != m_sharedString->string.get()); - } - } - - return npos; -} - -unsigned int NzString::FindLastAny(const NzString& string, int start, nzUInt32 flags) const -{ - return FindLastAny(string.GetConstBuffer(), start, flags); -} - -unsigned int NzString::FindLastWord(const char* string, int start, nzUInt32 flags) const -{ - if (!string || !string[0] || m_sharedString->size == 0) - return npos; - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return npos; - - ///Algo 2.FindLastWord#1 (Taille du pattern inconnue) - const char* ptr = &m_sharedString->string[pos]; - - if (flags & HandleUtf8) - { - if (utf8::internal::is_trail(*ptr)) - utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère - - utf8::unchecked::iterator it(ptr); - - if (flags & CaseInsensitive) - { - const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument - nzUInt32 c = NzUnicode::GetLowercase(utf8::unchecked::next(t)); - do - { - if (NzUnicode::GetLowercase(*it) == c) - { - if (it.base() != m_sharedString->string.get()) - { - --it; - if (!(NzUnicode::GetCategory(*it++) & NzUnicode::Category_Separator)) - continue; - } - - utf8::unchecked::iterator p(t); - utf8::unchecked::iterator tIt = it; - ++tIt; - - while (true) - { - if (*p == '\0') - { - if (*tIt == '\0' || NzUnicode::GetCategory(*tIt) & NzUnicode::Category_Separator) - return it.base() - m_sharedString->string.get(); - else - break; - } - - if (tIt.base() > &m_sharedString->string[pos]) - break; - - if (NzUnicode::GetLowercase(*tIt) != NzUnicode::GetLowercase(*p)) - break; - - ++p; - ++tIt; - } - } - } - while (it--.base() != m_sharedString->string.get()); - } - else - { - const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument - nzUInt32 c = utf8::unchecked::next(t); - do - { - if (*it == c) - { - if (it.base() != m_sharedString->string.get()) - { - --it; - if (!(NzUnicode::GetCategory(*it++) & NzUnicode::Category_Separator)) - continue; - } - - utf8::unchecked::iterator p(t); - utf8::unchecked::iterator tIt = it; - ++tIt; - - while (true) - { - if (*p == '\0') - { - if (*tIt == '\0' || NzUnicode::GetCategory(*tIt) & NzUnicode::Category_Separator) - return it.base() - m_sharedString->string.get(); - else - break; - } - - if (tIt.base() > &m_sharedString->string[pos]) - break; - - if (*tIt != *p) - break; - - ++p; - ++tIt; - } - } - } - while (it--.base() != m_sharedString->string.get()); - } - } - else - { - if (flags & CaseInsensitive) - { - char c = nzToLower(string[0]); - do - { - if (nzToLower(*ptr) == c) - { - if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) - continue; - - const char* p = &string[1]; - const char* tPtr = ptr+1; - while (true) - { - if (*p == '\0') - { - if (*tPtr == '\0' || std::isspace(*tPtr)) - return ptr-m_sharedString->string.get(); - else - break; - } - - if (tPtr > &m_sharedString->string[pos]) - break; - - if (nzToLower(*tPtr) != nzToLower(*p)) - break; - - p++; - tPtr++; - } - } - } - while (ptr-- != m_sharedString->string.get()); - } - else - { - do - { - if (*ptr == string[0]) - { - if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) - continue; - - const char* p = &string[1]; - const char* tPtr = ptr+1; - while (true) - { - if (*p == '\0') - { - if (*tPtr == '\0' || std::isspace(*tPtr)) - return ptr-m_sharedString->string.get(); - else - break; - } - - if (tPtr > &m_sharedString->string[pos]) - break; - - if (*tPtr != *p) - break; - - p++; - tPtr++; - } - } - } - while (ptr-- != m_sharedString->string.get()); - } - } - - return npos; -} - -unsigned int NzString::FindLastWord(const NzString& string, int start, nzUInt32 flags) const -{ - if (string.m_sharedString->size == 0 || string.m_sharedString->size > m_sharedString->size) - return npos; - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return npos; - - const char* ptr = &m_sharedString->string[pos]; - const char* limit = &m_sharedString->string[string.m_sharedString->size-1]; - - if (flags & HandleUtf8) - { - if (utf8::internal::is_trail(*ptr)) - utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère - - utf8::unchecked::iterator it(ptr); - - if (flags & CaseInsensitive) - { - const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affecte l'itérateur en argument - nzUInt32 c = NzUnicode::GetLowercase(utf8::unchecked::next(t)); - do - { - if (NzUnicode::GetLowercase(*it) == c) - { - if (it.base() != m_sharedString->string.get()) - { - --it; - if (!(NzUnicode::GetCategory(*it++) & NzUnicode::Category_Separator)) - continue; - } - - utf8::unchecked::iterator p(t); - utf8::unchecked::iterator tIt = it; - ++tIt; - - while (true) - { - if (*p == '\0') - { - if (*tIt == '\0' || NzUnicode::GetCategory(*tIt) & NzUnicode::Category_Separator) - return it.base() - m_sharedString->string.get(); - else - break; - } - - if (tIt.base() > &m_sharedString->string[pos]) - break; - - if (NzUnicode::GetLowercase(*tIt) != NzUnicode::GetLowercase(*p)) - break; - - ++p; - ++tIt; - } - } - } - while (it--.base() != m_sharedString->string.get()); - } - else - { - const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affecte l'itérateur en argument - nzUInt32 c = utf8::unchecked::next(t); - do - { - if (*it == c) - { - if (it.base() != m_sharedString->string.get()) - { - --it; - if (!(NzUnicode::GetCategory(*it++) & NzUnicode::Category_Separator)) - continue; - } - - utf8::unchecked::iterator p(t); - utf8::unchecked::iterator tIt = it; - ++tIt; - - while (true) - { - if (*p == '\0') - { - if (*tIt == '\0' || NzUnicode::GetCategory(*tIt) & NzUnicode::Category_Separator) - return it.base() - m_sharedString->string.get(); - else - break; - } - - if (tIt.base() > &m_sharedString->string[pos]) - break; - - if (*tIt != *p) - break; - - ++p; - ++tIt; - } - } - } - while (it--.base() != m_sharedString->string.get()); - } - } - else - { - ///Algo 2.FindLastWord#2 (Taille du pattern connue) - if (flags & CaseInsensitive) - { - char c = nzToLower(string.m_sharedString->string[string.m_sharedString->size-1]); - do - { - if (nzToLower(*ptr) == c) - { - if (*(ptr+1) != '\0' && !std::isspace(*(ptr+1))) - continue; - - const char* p = &string.m_sharedString->string[string.m_sharedString->size-1]; - for (; p >= &string.m_sharedString->string[0]; --p, --ptr) - { - if (nzToLower(*ptr) != nzToLower(*p)) - break; - - if (p == &string.m_sharedString->string[0]) - { - if (ptr == m_sharedString->string.get() || std::isspace(*(ptr-1))) - return ptr-m_sharedString->string.get(); - else - break; - } - - if (ptr == m_sharedString->string.get()) - return npos; - } - } - } - while (ptr-- > limit); - } - else - { - do - { - if (*ptr == string.m_sharedString->string[string.m_sharedString->size-1]) - { - if (*(ptr+1) != '\0' && !std::isspace(*(ptr+1))) - continue; - - const char* p = &string.m_sharedString->string[string.m_sharedString->size-1]; - for (; p >= &string.m_sharedString->string[0]; --p, --ptr) - { - if (*ptr != *p) - break; - - if (p == &string.m_sharedString->string[0]) - { - if (ptr == m_sharedString->string.get() || std::isspace(*(ptr-1))) - return ptr-m_sharedString->string.get(); - else - break; - } - - if (ptr == m_sharedString->string.get()) - return npos; - } - } - } - while (ptr-- > limit); - } - } - - return npos; -} - -unsigned int NzString::FindWord(const char* string, int start, nzUInt32 flags) const -{ - if (!string || !string[0] || m_sharedString->size == 0) - return npos; - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return npos; - - ///Algo 3.FindWord#3 (Taille du pattern inconnue) - const char* ptr = m_sharedString->string.get(); - if (flags & HandleUtf8) - { - if (utf8::internal::is_trail(*ptr)) - utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère - - utf8::unchecked::iterator it(ptr); - - if (flags & CaseInsensitive) - { - const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument - nzUInt32 c = NzUnicode::GetLowercase(utf8::unchecked::next(t)); - - do - { - if (*it == c) - { - if (it.base() != m_sharedString->string.get()) - { - --it; - if (!(NzUnicode::GetCategory(*it++) & NzUnicode::Category_Separator)) - continue; - } - - utf8::unchecked::iterator p(t); - utf8::unchecked::iterator tIt = it; - ++tIt; - - while (true) - { - if (*p == '\0') - { - if (*tIt == '\0' || NzUnicode::GetCategory(*it++) & NzUnicode::Category_Separator) - return it.base() - m_sharedString->string.get(); - else - break; - } - - if (NzUnicode::GetLowercase(*tIt) != NzUnicode::GetLowercase(*p)) - break; - - ++p; - ++tIt; - } - } - } - while (*++ptr); - } - else - { - const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument - nzUInt32 c = NzUnicode::GetLowercase(utf8::unchecked::next(t)); - - do - { - if (*it == c) - { - if (it.base() != m_sharedString->string.get()) - { - --it; - if (!(NzUnicode::GetCategory(*it++) & NzUnicode::Category_Separator)) - continue; - } - - utf8::unchecked::iterator p(t); - utf8::unchecked::iterator tIt = it; - ++tIt; - - while (true) - { - if (*p == '\0') - { - if (*tIt == '\0' || NzUnicode::GetCategory(*it++) & NzUnicode::Category_Separator) - return it.base() - m_sharedString->string.get(); - else - break; - } - - if (*tIt != *p) - break; - - ++p; - ++tIt; - } - } - } - while (*++ptr); - } - } - else - { - if (flags & CaseInsensitive) - { - char c = nzToLower(string[0]); - do - { - if (nzToLower(*ptr) == c) - { - if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) - continue; - - const char* p = &string[1]; - const char* tPtr = ptr+1; - while (true) - { - if (*p == '\0') - { - if (*tPtr == '\0' || std::isspace(*tPtr)) - return ptr - m_sharedString->string.get(); - else - break; - } - - if (nzToLower(*tPtr) != nzToLower(*p)) - break; - - p++; - tPtr++; - } - } - } - while (*++ptr); - } - else - { - do - { - if (*ptr == string[0]) - { - if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) - continue; - - const char* p = &string[1]; - const char* tPtr = ptr+1; - while (true) - { - if (*p == '\0') - { - if (*tPtr == '\0' || std::isspace(*tPtr)) - return ptr - m_sharedString->string.get(); - else - break; - } - - if (*tPtr != *p) - break; - - p++; - tPtr++; - } - } - } - while (*++ptr); - } - } - - return npos; -} - -unsigned int NzString::FindWord(const NzString& string, int start, nzUInt32 flags) const -{ - if (string.m_sharedString->size == 0 || string.m_sharedString->size > m_sharedString->size) - return npos; - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return npos; - - char* ptr = m_sharedString->string.get(); - if (flags & HandleUtf8) - { - ///Algo 3.FindWord#3 (Itérateur trop lent pour #2) - if (utf8::internal::is_trail(*ptr)) - utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère - - utf8::unchecked::iterator it(ptr); - - if (flags & CaseInsensitive) - { - const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affecte l'itérateur en argument - nzUInt32 c = NzUnicode::GetLowercase(utf8::unchecked::next(t)); - - do - { - if (*it == c) - { - if (it.base() != m_sharedString->string.get()) - { - --it; - if (!(NzUnicode::GetCategory(*it++) & NzUnicode::Category_Separator)) - continue; - } - - utf8::unchecked::iterator p(t); - utf8::unchecked::iterator tIt = it; - ++tIt; - - while (true) - { - if (*p == '\0') - { - if (*tIt == '\0' || NzUnicode::GetCategory(*it++) & NzUnicode::Category_Separator) - return it.base() - m_sharedString->string.get(); - else - break; - } - - if (NzUnicode::GetLowercase(*tIt) != NzUnicode::GetLowercase(*p)) - break; - - ++p; - ++tIt; - } - } - } - while (*++ptr); - } - else - { - const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affecte l'itérateur en argument - nzUInt32 c = NzUnicode::GetLowercase(utf8::unchecked::next(t)); - - do - { - if (*it == c) - { - if (it.base() != m_sharedString->string.get()) - { - --it; - if (!(NzUnicode::GetCategory(*it++) & NzUnicode::Category_Separator)) - continue; - } - - utf8::unchecked::iterator p(t); - utf8::unchecked::iterator tIt = it; - ++tIt; - - while (true) - { - if (*p == '\0') - { - if (*tIt == '\0' || NzUnicode::GetCategory(*it++) & NzUnicode::Category_Separator) - return it.base() - m_sharedString->string.get(); - else - break; - } - - if (*tIt != *p) - break; - - ++p; - ++tIt; - } - } - } - while (*++ptr); - } - } - else - { - ///Algo 3.FindWord#2 (Taille du pattern connue) - if (flags & CaseInsensitive) - { - char c = nzToLower(string.m_sharedString->string[0]); - do - { - if (nzToLower(*ptr) == c) - { - if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) - continue; - - const char* p = &string.m_sharedString->string[1]; - const char* tPtr = ptr+1; - while (true) - { - if (*p == '\0') - { - if (*tPtr == '\0' || std::isspace(*tPtr)) - return ptr - m_sharedString->string.get(); - else - break; - } - - if (nzToLower(*tPtr) != nzToLower(*p)) - break; - - p++; - tPtr++; - } - } - } - while (*++ptr); - } - else - { - while ((ptr = std::strstr(ptr, string.GetConstBuffer()))) - { - // Si le mot est bien isolé - if ((ptr == m_sharedString->string.get() || std::isspace(*(ptr-1))) && (*(ptr+m_sharedString->size) == '\0' || std::isspace(*(ptr+m_sharedString->size)))) - return ptr - m_sharedString->string.get(); - - ptr++; - } - } - } - - return npos; -} - -char* NzString::GetBuffer() -{ - EnsureOwnership(); - - return m_sharedString->string.get(); -} - -unsigned int NzString::GetCapacity() const -{ - return m_sharedString->capacity; -} - -const char* NzString::GetConstBuffer() const -{ - return m_sharedString->string.get(); -} - -unsigned int NzString::GetLength() const -{ - return utf8::distance(m_sharedString->string.get(), &m_sharedString->string[m_sharedString->size]); -} - -unsigned int NzString::GetSize() const -{ - return m_sharedString->size; -} - -std::string NzString::GetUtf8String() const -{ - return std::string(m_sharedString->string.get(), m_sharedString->size); -} - -std::u16string NzString::GetUtf16String() const -{ - if (m_sharedString->size == 0) - return std::u16string(); - - std::u16string str; - str.reserve(m_sharedString->size); - - utf8::utf8to16(begin(), end(), std::back_inserter(str)); - - return str; -} - -std::u32string NzString::GetUtf32String() const -{ - if (m_sharedString->size == 0) - return std::u32string(); - - std::u32string str; - str.reserve(m_sharedString->size); - - utf8::utf8to32(begin(), end(), std::back_inserter(str)); - - return str; -} - -std::wstring NzString::GetWideString() const -{ - static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "wchar_t size is not supported"); - if (m_sharedString->size == 0) - return std::wstring(); - - std::wstring str; - str.reserve(m_sharedString->size); - - if (sizeof(wchar_t) == 4) // Je veux du static_if :( - utf8::utf8to32(begin(), end(), std::back_inserter(str)); - else - { - utf8::unchecked::iterator it(m_sharedString->string.get()); - do - { - char32_t cp = *it; - if (cp <= 0xFFFF && (cp < 0xD800 || cp > 0xDFFF)) // @Laurent Gomila - str.push_back(static_cast(cp)); - else - str.push_back(L'?'); - } - while (*it++); - } - - return str; -} - -NzString NzString::GetWord(unsigned int index, nzUInt32 flags) const -{ - unsigned int startPos = GetWordPosition(index, flags); - if (startPos == npos) - return NzString(); - - int endPos = -1; - const char* ptr = &m_sharedString->string[startPos]; - if (flags & HandleUtf8) - { - utf8::unchecked::iterator it(ptr); - do - { - if (NzUnicode::GetCategory(*it) & NzUnicode::Category_Separator) - { - endPos = static_cast(it.base() - m_sharedString->string.get() - 1); - break; - } - } - while (*++it); - } - else - { - do - { - if (std::isspace(*ptr)) - { - endPos = static_cast(ptr - m_sharedString->string.get() - 1); - break; - } - } - while (*++ptr); - } - - return SubString(startPos, endPos); -} - -unsigned int NzString::GetWordPosition(unsigned int index, nzUInt32 flags) const -{ - if (m_sharedString->size == 0) - return npos; - - unsigned int currentWord = 0; - bool inWord = false; - - const char* ptr = m_sharedString->string.get(); - if (flags & HandleUtf8) - { - utf8::unchecked::iterator it(ptr); - do - { - if (NzUnicode::GetCategory(*it) & NzUnicode::Category_Separator) - inWord = false; else { - if (!inWord) + do { - inWord = true; - if (++currentWord > index) - return static_cast(it.base() - m_sharedString->string.get()); + utf8::unchecked::iterator it2(string); + do + { + if (*it == *it2) + return it.base() - m_sharedString->string.get(); + } + while (*++it2); } + while (it--.base() != m_sharedString->string.get()); } } - while (*++it); - } - else - { - do + else { - if (std::isspace(*ptr)) - inWord = false; + if (flags & CaseInsensitive) + { + do + { + const char* c = string; + char character = Detail::ToLower(*str); + do + { + if (character == Detail::ToLower(*c)) + return str - m_sharedString->string.get(); + } + while (*++c); + } + while (str-- != m_sharedString->string.get()); + } else { - if (!inWord) + do { - inWord = true; - if (++currentWord > index) + const char* c = string; + do + { + if (*str == *c) + return str - m_sharedString->string.get(); + } + while (*++c); + } + while (str-- != m_sharedString->string.get()); + } + } + + return npos; + } + + unsigned int String::FindLastAny(const String& string, int start, UInt32 flags) const + { + return FindLastAny(string.GetConstBuffer(), start, flags); + } + + unsigned int String::FindLastWord(const char* string, int start, UInt32 flags) const + { + if (!string || !string[0] || m_sharedString->size == 0) + return npos; + + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return npos; + + ///Algo 2.FindLastWord#1 (Taille du pattern inconnue) + const char* ptr = &m_sharedString->string[pos]; + + if (flags & HandleUtf8) + { + if (utf8::internal::is_trail(*ptr)) + utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère + + utf8::unchecked::iterator it(ptr); + + if (flags & CaseInsensitive) + { + const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument + UInt32 c = Unicode::GetLowercase(utf8::unchecked::next(t)); + do + { + if (Unicode::GetLowercase(*it) == c) + { + if (it.base() != m_sharedString->string.get()) + { + --it; + if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + continue; + } + + utf8::unchecked::iterator p(t); + utf8::unchecked::iterator tIt = it; + ++tIt; + + while (true) + { + if (*p == '\0') + { + if (*tIt == '\0' || Unicode::GetCategory(*tIt) & Unicode::Category_Separator) + return it.base() - m_sharedString->string.get(); + else + break; + } + + if (tIt.base() > &m_sharedString->string[pos]) + break; + + if (Unicode::GetLowercase(*tIt) != Unicode::GetLowercase(*p)) + break; + + ++p; + ++tIt; + } + } + } + while (it--.base() != m_sharedString->string.get()); + } + else + { + const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument + UInt32 c = utf8::unchecked::next(t); + do + { + if (*it == c) + { + if (it.base() != m_sharedString->string.get()) + { + --it; + if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + continue; + } + + utf8::unchecked::iterator p(t); + utf8::unchecked::iterator tIt = it; + ++tIt; + + while (true) + { + if (*p == '\0') + { + if (*tIt == '\0' || Unicode::GetCategory(*tIt) & Unicode::Category_Separator) + return it.base() - m_sharedString->string.get(); + else + break; + } + + if (tIt.base() > &m_sharedString->string[pos]) + break; + + if (*tIt != *p) + break; + + ++p; + ++tIt; + } + } + } + while (it--.base() != m_sharedString->string.get()); + } + } + else + { + if (flags & CaseInsensitive) + { + char c = Detail::ToLower(string[0]); + do + { + if (Detail::ToLower(*ptr) == c) + { + if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) + continue; + + const char* p = &string[1]; + const char* tPtr = ptr+1; + while (true) + { + if (*p == '\0') + { + if (*tPtr == '\0' || std::isspace(*tPtr)) + return ptr-m_sharedString->string.get(); + else + break; + } + + if (tPtr > &m_sharedString->string[pos]) + break; + + if (Detail::ToLower(*tPtr) != Detail::ToLower(*p)) + break; + + p++; + tPtr++; + } + } + } + while (ptr-- != m_sharedString->string.get()); + } + else + { + do + { + if (*ptr == string[0]) + { + if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) + continue; + + const char* p = &string[1]; + const char* tPtr = ptr+1; + while (true) + { + if (*p == '\0') + { + if (*tPtr == '\0' || std::isspace(*tPtr)) + return ptr-m_sharedString->string.get(); + else + break; + } + + if (tPtr > &m_sharedString->string[pos]) + break; + + if (*tPtr != *p) + break; + + p++; + tPtr++; + } + } + } + while (ptr-- != m_sharedString->string.get()); + } + } + + return npos; + } + + unsigned int String::FindLastWord(const String& string, int start, UInt32 flags) const + { + if (string.m_sharedString->size == 0 || string.m_sharedString->size > m_sharedString->size) + return npos; + + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return npos; + + const char* ptr = &m_sharedString->string[pos]; + const char* limit = &m_sharedString->string[string.m_sharedString->size-1]; + + if (flags & HandleUtf8) + { + if (utf8::internal::is_trail(*ptr)) + utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère + + utf8::unchecked::iterator it(ptr); + + if (flags & CaseInsensitive) + { + const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affecte l'itérateur en argument + UInt32 c = Unicode::GetLowercase(utf8::unchecked::next(t)); + do + { + if (Unicode::GetLowercase(*it) == c) + { + if (it.base() != m_sharedString->string.get()) + { + --it; + if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + continue; + } + + utf8::unchecked::iterator p(t); + utf8::unchecked::iterator tIt = it; + ++tIt; + + while (true) + { + if (*p == '\0') + { + if (*tIt == '\0' || Unicode::GetCategory(*tIt) & Unicode::Category_Separator) + return it.base() - m_sharedString->string.get(); + else + break; + } + + if (tIt.base() > &m_sharedString->string[pos]) + break; + + if (Unicode::GetLowercase(*tIt) != Unicode::GetLowercase(*p)) + break; + + ++p; + ++tIt; + } + } + } + while (it--.base() != m_sharedString->string.get()); + } + else + { + const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affecte l'itérateur en argument + UInt32 c = utf8::unchecked::next(t); + do + { + if (*it == c) + { + if (it.base() != m_sharedString->string.get()) + { + --it; + if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + continue; + } + + utf8::unchecked::iterator p(t); + utf8::unchecked::iterator tIt = it; + ++tIt; + + while (true) + { + if (*p == '\0') + { + if (*tIt == '\0' || Unicode::GetCategory(*tIt) & Unicode::Category_Separator) + return it.base() - m_sharedString->string.get(); + else + break; + } + + if (tIt.base() > &m_sharedString->string[pos]) + break; + + if (*tIt != *p) + break; + + ++p; + ++tIt; + } + } + } + while (it--.base() != m_sharedString->string.get()); + } + } + else + { + ///Algo 2.FindLastWord#2 (Taille du pattern connue) + if (flags & CaseInsensitive) + { + char c = Detail::ToLower(string.m_sharedString->string[string.m_sharedString->size-1]); + do + { + if (Detail::ToLower(*ptr) == c) + { + if (*(ptr+1) != '\0' && !std::isspace(*(ptr+1))) + continue; + + const char* p = &string.m_sharedString->string[string.m_sharedString->size-1]; + for (; p >= &string.m_sharedString->string[0]; --p, --ptr) + { + if (Detail::ToLower(*ptr) != Detail::ToLower(*p)) + break; + + if (p == &string.m_sharedString->string[0]) + { + if (ptr == m_sharedString->string.get() || std::isspace(*(ptr-1))) + return ptr-m_sharedString->string.get(); + else + break; + } + + if (ptr == m_sharedString->string.get()) + return npos; + } + } + } + while (ptr-- > limit); + } + else + { + do + { + if (*ptr == string.m_sharedString->string[string.m_sharedString->size-1]) + { + if (*(ptr+1) != '\0' && !std::isspace(*(ptr+1))) + continue; + + const char* p = &string.m_sharedString->string[string.m_sharedString->size-1]; + for (; p >= &string.m_sharedString->string[0]; --p, --ptr) + { + if (*ptr != *p) + break; + + if (p == &string.m_sharedString->string[0]) + { + if (ptr == m_sharedString->string.get() || std::isspace(*(ptr-1))) + return ptr-m_sharedString->string.get(); + else + break; + } + + if (ptr == m_sharedString->string.get()) + return npos; + } + } + } + while (ptr-- > limit); + } + } + + return npos; + } + + unsigned int String::FindWord(const char* string, int start, UInt32 flags) const + { + if (!string || !string[0] || m_sharedString->size == 0) + return npos; + + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return npos; + + ///Algo 3.FindWord#3 (Taille du pattern inconnue) + const char* ptr = m_sharedString->string.get(); + if (flags & HandleUtf8) + { + if (utf8::internal::is_trail(*ptr)) + utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère + + utf8::unchecked::iterator it(ptr); + + if (flags & CaseInsensitive) + { + const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument + UInt32 c = Unicode::GetLowercase(utf8::unchecked::next(t)); + + do + { + if (*it == c) + { + if (it.base() != m_sharedString->string.get()) + { + --it; + if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + continue; + } + + utf8::unchecked::iterator p(t); + utf8::unchecked::iterator tIt = it; + ++tIt; + + while (true) + { + if (*p == '\0') + { + if (*tIt == '\0' || Unicode::GetCategory(*it++) & Unicode::Category_Separator) + return it.base() - m_sharedString->string.get(); + else + break; + } + + if (Unicode::GetLowercase(*tIt) != Unicode::GetLowercase(*p)) + break; + + ++p; + ++tIt; + } + } + } + while (*++ptr); + } + else + { + const char* t = string; // utf8(::unchecked)::next affecte l'itérateur en argument + UInt32 c = Unicode::GetLowercase(utf8::unchecked::next(t)); + + do + { + if (*it == c) + { + if (it.base() != m_sharedString->string.get()) + { + --it; + if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + continue; + } + + utf8::unchecked::iterator p(t); + utf8::unchecked::iterator tIt = it; + ++tIt; + + while (true) + { + if (*p == '\0') + { + if (*tIt == '\0' || Unicode::GetCategory(*it++) & Unicode::Category_Separator) + return it.base() - m_sharedString->string.get(); + else + break; + } + + if (*tIt != *p) + break; + + ++p; + ++tIt; + } + } + } + while (*++ptr); + } + } + else + { + if (flags & CaseInsensitive) + { + char c = Detail::ToLower(string[0]); + do + { + if (Detail::ToLower(*ptr) == c) + { + if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) + continue; + + const char* p = &string[1]; + const char* tPtr = ptr+1; + while (true) + { + if (*p == '\0') + { + if (*tPtr == '\0' || std::isspace(*tPtr)) + return ptr - m_sharedString->string.get(); + else + break; + } + + if (Detail::ToLower(*tPtr) != Detail::ToLower(*p)) + break; + + p++; + tPtr++; + } + } + } + while (*++ptr); + } + else + { + do + { + if (*ptr == string[0]) + { + if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) + continue; + + const char* p = &string[1]; + const char* tPtr = ptr+1; + while (true) + { + if (*p == '\0') + { + if (*tPtr == '\0' || std::isspace(*tPtr)) + return ptr - m_sharedString->string.get(); + else + break; + } + + if (*tPtr != *p) + break; + + p++; + tPtr++; + } + } + } + while (*++ptr); + } + } + + return npos; + } + + unsigned int String::FindWord(const String& string, int start, UInt32 flags) const + { + if (string.m_sharedString->size == 0 || string.m_sharedString->size > m_sharedString->size) + return npos; + + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return npos; + + char* ptr = m_sharedString->string.get(); + if (flags & HandleUtf8) + { + ///Algo 3.FindWord#3 (Itérateur trop lent pour #2) + if (utf8::internal::is_trail(*ptr)) + utf8::unchecked::prior(ptr); // On s'assure d'avoir un pointeur vers le début d'un caractère + + utf8::unchecked::iterator it(ptr); + + if (flags & CaseInsensitive) + { + const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affecte l'itérateur en argument + UInt32 c = Unicode::GetLowercase(utf8::unchecked::next(t)); + + do + { + if (*it == c) + { + if (it.base() != m_sharedString->string.get()) + { + --it; + if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + continue; + } + + utf8::unchecked::iterator p(t); + utf8::unchecked::iterator tIt = it; + ++tIt; + + while (true) + { + if (*p == '\0') + { + if (*tIt == '\0' || Unicode::GetCategory(*it++) & Unicode::Category_Separator) + return it.base() - m_sharedString->string.get(); + else + break; + } + + if (Unicode::GetLowercase(*tIt) != Unicode::GetLowercase(*p)) + break; + + ++p; + ++tIt; + } + } + } + while (*++ptr); + } + else + { + const char* t = string.GetConstBuffer(); // utf8(::unchecked)::next affecte l'itérateur en argument + UInt32 c = Unicode::GetLowercase(utf8::unchecked::next(t)); + + do + { + if (*it == c) + { + if (it.base() != m_sharedString->string.get()) + { + --it; + if (!(Unicode::GetCategory(*it++) & Unicode::Category_Separator)) + continue; + } + + utf8::unchecked::iterator p(t); + utf8::unchecked::iterator tIt = it; + ++tIt; + + while (true) + { + if (*p == '\0') + { + if (*tIt == '\0' || Unicode::GetCategory(*it++) & Unicode::Category_Separator) + return it.base() - m_sharedString->string.get(); + else + break; + } + + if (*tIt != *p) + break; + + ++p; + ++tIt; + } + } + } + while (*++ptr); + } + } + else + { + ///Algo 3.FindWord#2 (Taille du pattern connue) + if (flags & CaseInsensitive) + { + char c = Detail::ToLower(string.m_sharedString->string[0]); + do + { + if (Detail::ToLower(*ptr) == c) + { + if (ptr != m_sharedString->string.get() && !std::isspace(*(ptr-1))) + continue; + + const char* p = &string.m_sharedString->string[1]; + const char* tPtr = ptr+1; + while (true) + { + if (*p == '\0') + { + if (*tPtr == '\0' || std::isspace(*tPtr)) + return ptr - m_sharedString->string.get(); + else + break; + } + + if (Detail::ToLower(*tPtr) != Detail::ToLower(*p)) + break; + + p++; + tPtr++; + } + } + } + while (*++ptr); + } + else + { + while ((ptr = std::strstr(ptr, string.GetConstBuffer()))) + { + // Si le mot est bien isolé + if ((ptr == m_sharedString->string.get() || std::isspace(*(ptr-1))) && (*(ptr+m_sharedString->size) == '\0' || std::isspace(*(ptr+m_sharedString->size)))) return ptr - m_sharedString->string.get(); + + ptr++; } } } - while (*++ptr); + + return npos; } - return npos; -} - -NzString& NzString::Insert(int pos, char character) -{ - return Insert(pos, &character, 1); -} - -NzString& NzString::Insert(int pos, const char* string) -{ - return Insert(pos, string, std::strlen(string)); -} - -NzString& NzString::Insert(int pos, const char* string, unsigned int length) -{ - if (length == 0) - return *this; - - if (pos < 0) - pos = std::max(m_sharedString->size + pos, 0U); - - unsigned int start = std::min(static_cast(pos), m_sharedString->size); - - // Si le buffer est déjà suffisamment grand - if (m_sharedString->capacity >= m_sharedString->size + length) + char* String::GetBuffer() { EnsureOwnership(); - std::memmove(&m_sharedString->string[start+length], &m_sharedString->string[start], m_sharedString->size - start); - std::memcpy(&m_sharedString->string[start], string, length); - - m_sharedString->size += length; - m_sharedString->string[m_sharedString->size] = '\0'; + return m_sharedString->string.get(); } - else + + unsigned int String::GetCapacity() const { - unsigned int newSize = m_sharedString->size + length; - auto newString = std::make_shared(m_sharedString->size + length); + return m_sharedString->capacity; + } - char* ptr = newString->string.get(); + const char* String::GetConstBuffer() const + { + return m_sharedString->string.get(); + } - if (start > 0) + unsigned int String::GetLength() const + { + return utf8::distance(m_sharedString->string.get(), &m_sharedString->string[m_sharedString->size]); + } + + unsigned int String::GetSize() const + { + return m_sharedString->size; + } + + std::string String::GetUtf8String() const + { + return std::string(m_sharedString->string.get(), m_sharedString->size); + } + + std::u16string String::GetUtf16String() const + { + if (m_sharedString->size == 0) + return std::u16string(); + + std::u16string str; + str.reserve(m_sharedString->size); + + utf8::utf8to16(begin(), end(), std::back_inserter(str)); + + return str; + } + + std::u32string String::GetUtf32String() const + { + if (m_sharedString->size == 0) + return std::u32string(); + + std::u32string str; + str.reserve(m_sharedString->size); + + utf8::utf8to32(begin(), end(), std::back_inserter(str)); + + return str; + } + + std::wstring String::GetWideString() const + { + static_assert(sizeof(wchar_t) == 2 || sizeof(wchar_t) == 4, "wchar_t size is not supported"); + if (m_sharedString->size == 0) + return std::wstring(); + + std::wstring str; + str.reserve(m_sharedString->size); + + if (sizeof(wchar_t) == 4) // Je veux du static_if :( + utf8::utf8to32(begin(), end(), std::back_inserter(str)); + else { - std::memcpy(ptr, m_sharedString->string.get(), start*sizeof(char)); - ptr += start; - } - - std::memcpy(ptr, string, length*sizeof(char)); - ptr += length; - - if (m_sharedString->size > start) - std::memcpy(ptr, &m_sharedString->string[start], m_sharedString->size - start); - - m_sharedString = std::move(newString); - } - - return *this; -} - -NzString& NzString::Insert(int pos, const NzString& string) -{ - return Insert(pos, string.GetConstBuffer(), string.m_sharedString->size); -} - -bool NzString::IsEmpty() const -{ - return m_sharedString->size == 0; -} - -bool NzString::IsNull() const -{ - return m_sharedString.get() == GetEmptyString().get(); -} - -bool NzString::IsNumber(nzUInt8 base, nzUInt32 flags) const -{ - #if NAZARA_CORE_SAFE - if (base < 2 || base > 36) - { - NazaraError("Base must be between 2 and 36"); - return false; - } - #endif - - if (m_sharedString->size == 0) - return false; - - NzString check = Simplified(); - if (check.m_sharedString->size == 0) - return false; - - char* ptr = (check.m_sharedString->string[0] == '-') ? &check.m_sharedString->string[1] : check.m_sharedString->string.get(); - - if (base > 10) - { - if (flags & CaseInsensitive) - { - char limitLower = 'a' + base-10 - 1; - char limitUpper = 'A' + base-10 - 1; - + utf8::unchecked::iterator it(m_sharedString->string.get()); do { - char c = *ptr; - if (c != ' ' && (c < '0' || (c > '9' && c < 'A') || (c > limitUpper && c < 'a') || c > limitLower)) - return false; + char32_t cp = *it; + if (cp <= 0xFFFF && (cp < 0xD800 || cp > 0xDFFF)) // @Laurent Gomila + str.push_back(static_cast(cp)); + else + str.push_back(L'?'); } - while (*++ptr); + while (*it++); + } + + return str; + } + + String String::GetWord(unsigned int index, UInt32 flags) const + { + unsigned int startPos = GetWordPosition(index, flags); + if (startPos == npos) + return String(); + + int endPos = -1; + const char* ptr = &m_sharedString->string[startPos]; + if (flags & HandleUtf8) + { + utf8::unchecked::iterator it(ptr); + do + { + if (Unicode::GetCategory(*it) & Unicode::Category_Separator) + { + endPos = static_cast(it.base() - m_sharedString->string.get() - 1); + break; + } + } + while (*++it); } else { - char limit = 'a' + base-10 - 1; + do + { + if (std::isspace(*ptr)) + { + endPos = static_cast(ptr - m_sharedString->string.get() - 1); + break; + } + } + while (*++ptr); + } + + return SubString(startPos, endPos); + } + + unsigned int String::GetWordPosition(unsigned int index, UInt32 flags) const + { + if (m_sharedString->size == 0) + return npos; + + unsigned int currentWord = 0; + bool inWord = false; + + const char* ptr = m_sharedString->string.get(); + if (flags & HandleUtf8) + { + utf8::unchecked::iterator it(ptr); + do + { + if (Unicode::GetCategory(*it) & Unicode::Category_Separator) + inWord = false; + else + { + if (!inWord) + { + inWord = true; + if (++currentWord > index) + return static_cast(it.base() - m_sharedString->string.get()); + } + } + } + while (*++it); + } + else + { + do + { + if (std::isspace(*ptr)) + inWord = false; + else + { + if (!inWord) + { + inWord = true; + if (++currentWord > index) + return ptr - m_sharedString->string.get(); + } + } + } + while (*++ptr); + } + + return npos; + } + + String& String::Insert(int pos, char character) + { + return Insert(pos, &character, 1); + } + + String& String::Insert(int pos, const char* string) + { + return Insert(pos, string, std::strlen(string)); + } + + String& String::Insert(int pos, const char* string, unsigned int length) + { + if (length == 0) + return *this; + + if (pos < 0) + pos = std::max(m_sharedString->size + pos, 0U); + + unsigned int start = std::min(static_cast(pos), m_sharedString->size); + + // Si le buffer est déjà suffisamment grand + if (m_sharedString->capacity >= m_sharedString->size + length) + { + EnsureOwnership(); + + std::memmove(&m_sharedString->string[start+length], &m_sharedString->string[start], m_sharedString->size - start); + std::memcpy(&m_sharedString->string[start], string, length); + + m_sharedString->size += length; + m_sharedString->string[m_sharedString->size] = '\0'; + } + else + { + unsigned int newSize = m_sharedString->size + length; + auto newString = std::make_shared(m_sharedString->size + length); + + char* ptr = newString->string.get(); + + if (start > 0) + { + std::memcpy(ptr, m_sharedString->string.get(), start*sizeof(char)); + ptr += start; + } + + std::memcpy(ptr, string, length*sizeof(char)); + ptr += length; + + if (m_sharedString->size > start) + std::memcpy(ptr, &m_sharedString->string[start], m_sharedString->size - start); + + m_sharedString = std::move(newString); + } + + return *this; + } + + String& String::Insert(int pos, const String& string) + { + return Insert(pos, string.GetConstBuffer(), string.m_sharedString->size); + } + + bool String::IsEmpty() const + { + return m_sharedString->size == 0; + } + + bool String::IsNull() const + { + return m_sharedString.get() == GetEmptyString().get(); + } + + bool String::IsNumber(UInt8 base, UInt32 flags) const + { + #if NAZARA_CORE_SAFE + if (base < 2 || base > 36) + { + NazaraError("Base must be between 2 and 36"); + return false; + } + #endif + + if (m_sharedString->size == 0) + return false; + + String check = Simplified(); + if (check.m_sharedString->size == 0) + return false; + + char* ptr = (check.m_sharedString->string[0] == '-') ? &check.m_sharedString->string[1] : check.m_sharedString->string.get(); + + if (base > 10) + { + if (flags & CaseInsensitive) + { + char limitLower = 'a' + base-10 - 1; + char limitUpper = 'A' + base-10 - 1; + + do + { + char c = *ptr; + if (c != ' ' && (c < '0' || (c > '9' && c < 'A') || (c > limitUpper && c < 'a') || c > limitLower)) + return false; + } + while (*++ptr); + } + else + { + char limit = 'a' + base-10 - 1; + do + { + char c = *ptr; + if (c != ' ' && (c < '0' || (c > '9' && c < 'a') || c > limit)) + return false; + } + while (*++ptr); + } + } + else + { + char limit = '0' + base - 1; + do { char c = *ptr; - if (c != ' ' && (c < '0' || (c > '9' && c < 'a') || c > limit)) + if (c != ' ' && (c < '0' || c > limit)) return false; } while (*++ptr); } - } - else - { - char limit = '0' + base - 1; - do - { - char c = *ptr; - if (c != ' ' && (c < '0' || c > limit)) - return false; - } - while (*++ptr); + return true; } - return true; -} - -bool NzString::Match(const char* pattern) const -{ - if (m_sharedString->size == 0 || !pattern) - return false; - - // Par Jack Handy - akkhandy@hotmail.com - // From : http://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing - const char* str = m_sharedString->string.get(); - while (*str && *pattern != '*') + bool String::Match(const char* pattern) const { - if (*pattern != *str && *pattern != '?') + if (m_sharedString->size == 0 || !pattern) return false; - pattern++; - str++; - } - - const char* cp = nullptr; - const char* mp = nullptr; - while (*str) - { - if (*pattern == '*') + // Par Jack Handy - akkhandy@hotmail.com + // From : http://www.codeproject.com/Articles/1088/Wildcard-string-compare-globbing + const char* str = m_sharedString->string.get(); + while (*str && *pattern != '*') { - if (!*++pattern) - return true; + if (*pattern != *str && *pattern != '?') + return false; - mp = pattern; - cp = str+1; - } - else if (*pattern == *str || *pattern == '?') - { pattern++; str++; } - else + + const char* cp = nullptr; + const char* mp = nullptr; + while (*str) { - pattern = mp; - str = cp++; + if (*pattern == '*') + { + if (!*++pattern) + return true; + + mp = pattern; + cp = str+1; + } + else if (*pattern == *str || *pattern == '?') + { + pattern++; + str++; + } + else + { + pattern = mp; + str = cp++; + } } + + while (*pattern == '*') + pattern++; + + return !*pattern; } - while (*pattern == '*') - pattern++; - - return !*pattern; -} - -bool NzString::Match(const NzString& pattern) const -{ - return Match(pattern.m_sharedString->string.get()); -} - -NzString& NzString::Prepend(char character) -{ - return Insert(0, character); -} - -NzString& NzString::Prepend(const char* string) -{ - return Insert(0, string); -} - -NzString& NzString::Prepend(const char* string, unsigned int length) -{ - return Insert(0, string, length); -} - -NzString& NzString::Prepend(const NzString& string) -{ - return Insert(0, string); -} - -unsigned int NzString::Replace(char oldCharacter, char newCharacter, int start, nzUInt32 flags) -{ - if (oldCharacter == '\0' || oldCharacter == newCharacter) - return 0; - - if (newCharacter == '\0') // Dans ce cas, il faut passer par un algorithme plus complexe - return Replace(NzString(oldCharacter), NzString(), start); - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return npos; - - unsigned int count = 0; - char* ptr = &m_sharedString->string[pos]; - bool found = false; - if (flags & CaseInsensitive) + bool String::Match(const String& pattern) const { - char character_lower = nzToLower(oldCharacter); - char character_upper = nzToUpper(oldCharacter); - do + return Match(pattern.m_sharedString->string.get()); + } + + String& String::Prepend(char character) + { + return Insert(0, character); + } + + String& String::Prepend(const char* string) + { + return Insert(0, string); + } + + String& String::Prepend(const char* string, unsigned int length) + { + return Insert(0, string, length); + } + + String& String::Prepend(const String& string) + { + return Insert(0, string); + } + + unsigned int String::Replace(char oldCharacter, char newCharacter, int start, UInt32 flags) + { + if (oldCharacter == '\0' || oldCharacter == newCharacter) + return 0; + + if (newCharacter == '\0') // Dans ce cas, il faut passer par un algorithme plus complexe + return Replace(String(oldCharacter), String(), start); + + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return npos; + + unsigned int count = 0; + char* ptr = &m_sharedString->string[pos]; + bool found = false; + if (flags & CaseInsensitive) { - if (*ptr == character_lower || *ptr == character_upper) + char character_lower = Detail::ToLower(oldCharacter); + char character_upper = Detail::ToUpper(oldCharacter); + do + { + if (*ptr == character_lower || *ptr == character_upper) + { + if (!found) + { + unsigned int offset = ptr-m_sharedString->string.get(); + + EnsureOwnership(); + + ptr = &m_sharedString->string[offset]; + found = true; + } + + *ptr = newCharacter; + ++count; + } + } + while (*++ptr); + } + else + { + while ((ptr = std::strchr(ptr, oldCharacter))) { if (!found) { @@ -2111,794 +2136,791 @@ unsigned int NzString::Replace(char oldCharacter, char newCharacter, int start, ++count; } } - while (*++ptr); - } - else - { - while ((ptr = std::strchr(ptr, oldCharacter))) - { - if (!found) - { - unsigned int offset = ptr-m_sharedString->string.get(); - EnsureOwnership(); - - ptr = &m_sharedString->string[offset]; - found = true; - } - - *ptr = newCharacter; - ++count; - } + return count; } - return count; -} - -unsigned int NzString::Replace(const char* oldString, const char* replaceString, int start, nzUInt32 flags) -{ - return Replace(oldString, std::strlen(oldString), replaceString, std::strlen(replaceString), start, flags); -} - -unsigned int NzString::Replace(const char* oldString, unsigned int oldLength, const char* replaceString, unsigned int replaceLength, int start, nzUInt32 flags) -{ - if (oldLength == 0) - return 0; - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return 0; - - unsigned int count = 0; - if (oldLength == replaceLength) + unsigned int String::Replace(const char* oldString, const char* replaceString, int start, UInt32 flags) { - bool found = false; - - // Si aucun changement de taille n'est nécessaire, nous pouvons alors utiliser un algorithme bien plus rapide - while ((pos = Find(oldString, pos, flags)) != npos) - { - if (!found) - { - EnsureOwnership(); - found = true; - } - - std::memcpy(&m_sharedString->string[pos], replaceString, oldLength); - pos += oldLength; - - ++count; - } + return Replace(oldString, std::strlen(oldString), replaceString, std::strlen(replaceString), start, flags); } - else ///TODO: Algorithme de remplacement sans changement de buffer (si replaceLength < oldLength) + + unsigned int String::Replace(const char* oldString, unsigned int oldLength, const char* replaceString, unsigned int replaceLength, int start, UInt32 flags) { - unsigned int newSize = m_sharedString->size + Count(oldString)*(replaceLength - oldLength); - if (newSize == m_sharedString->size) // Alors c'est que Count(oldString) == 0 + if (oldLength == 0) return 0; - auto newString = std::make_shared(newSize); + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); - ///Algo 4.Replace#2 - char* ptr = newString->string.get(); - const char* p = m_sharedString->string.get(); + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return 0; - while ((pos = Find(oldString, pos, flags)) != npos) + unsigned int count = 0; + if (oldLength == replaceLength) { - const char* r = &m_sharedString->string[pos]; + bool found = false; - std::memcpy(ptr, p, r-p); - ptr += r-p; - std::memcpy(ptr, replaceString, replaceLength); - ptr += replaceLength; - p = r+oldLength; - pos += oldLength; + // Si aucun changement de taille n'est nécessaire, nous pouvons alors utiliser un algorithme bien plus rapide + while ((pos = Find(oldString, pos, flags)) != npos) + { + if (!found) + { + EnsureOwnership(); + found = true; + } - count++; + std::memcpy(&m_sharedString->string[pos], replaceString, oldLength); + pos += oldLength; + + ++count; + } + } + else ///TODO: Algorithme de remplacement sans changement de buffer (si replaceLength < oldLength) + { + unsigned int newSize = m_sharedString->size + Count(oldString)*(replaceLength - oldLength); + if (newSize == m_sharedString->size) // Alors c'est que Count(oldString) == 0 + return 0; + + auto newString = std::make_shared(newSize); + + ///Algo 4.Replace#2 + char* ptr = newString->string.get(); + const char* p = m_sharedString->string.get(); + + while ((pos = Find(oldString, pos, flags)) != npos) + { + const char* r = &m_sharedString->string[pos]; + + std::memcpy(ptr, p, r-p); + ptr += r-p; + std::memcpy(ptr, replaceString, replaceLength); + ptr += replaceLength; + p = r+oldLength; + pos += oldLength; + + count++; + } + + std::strcpy(ptr, p); + + m_sharedString = std::move(newString); } - std::strcpy(ptr, p); - - m_sharedString = std::move(newString); + return count; } - return count; -} - -unsigned int NzString::Replace(const NzString& oldString, const NzString& replaceString, int start, nzUInt32 flags) -{ - return Replace(oldString.GetConstBuffer(), oldString.m_sharedString->size, replaceString.GetConstBuffer(), replaceString.m_sharedString->size, start, flags); -} - -unsigned int NzString::ReplaceAny(const char* oldCharacters, char replaceCharacter, int start, nzUInt32 flags) -{ - ///FIXME: Ne gère pas l'UTF-8 - if (!oldCharacters || !oldCharacters[0]) - return 0; - - /*if (replaceCharacter == '\0') // Dans ce cas, il faut passer par un algorithme plus complexe - return ReplaceAny(NzString(oldCharacters), NzString(), start);*/ - - if (start < 0) - start = std::max(m_sharedString->size + start, 0U); - - unsigned int pos = static_cast(start); - if (pos >= m_sharedString->size) - return npos; - - unsigned int count = 0; - char* ptr = &m_sharedString->string[pos]; - if (flags & CaseInsensitive) + unsigned int String::Replace(const String& oldString, const String& replaceString, int start, UInt32 flags) { - do + return Replace(oldString.GetConstBuffer(), oldString.m_sharedString->size, replaceString.GetConstBuffer(), replaceString.m_sharedString->size, start, flags); + } + + unsigned int String::ReplaceAny(const char* oldCharacters, char replaceCharacter, int start, UInt32 flags) + { + ///FIXME: Ne gère pas l'UTF-8 + if (!oldCharacters || !oldCharacters[0]) + return 0; + + /*if (replaceCharacter == '\0') // Dans ce cas, il faut passer par un algorithme plus complexe + return ReplaceAny(String(oldCharacters), String(), start);*/ + + if (start < 0) + start = std::max(m_sharedString->size + start, 0U); + + unsigned int pos = static_cast(start); + if (pos >= m_sharedString->size) + return npos; + + unsigned int count = 0; + char* ptr = &m_sharedString->string[pos]; + if (flags & CaseInsensitive) { - const char* c = oldCharacters; - char character = nzToLower(*ptr); - bool found = false; do { - if (character == nzToLower(*c)) + const char* c = oldCharacters; + char character = Detail::ToLower(*ptr); + bool found = false; + do { - if (!found) + if (character == Detail::ToLower(*c)) { - unsigned int offset = ptr-m_sharedString->string.get(); + if (!found) + { + unsigned int offset = ptr-m_sharedString->string.get(); - EnsureOwnership(); + EnsureOwnership(); - ptr = &m_sharedString->string[offset]; - found = true; + ptr = &m_sharedString->string[offset]; + found = true; + } + + *ptr = replaceCharacter; + ++count; + break; } - - *ptr = replaceCharacter; - ++count; - break; } + while (*++c); } - while (*++c); + while (*++ptr); } - while (*++ptr); - } - else - { - bool found = false; - while ((ptr = std::strpbrk(ptr, oldCharacters))) + else { - if (!found) + bool found = false; + while ((ptr = std::strpbrk(ptr, oldCharacters))) { - unsigned int offset = ptr-m_sharedString->string.get(); + if (!found) + { + unsigned int offset = ptr-m_sharedString->string.get(); + EnsureOwnership(); + + ptr = &m_sharedString->string[offset]; + found = true; + } + + *ptr++ = replaceCharacter; + ++count; + } + } + + return count; + } + /* + unsigned int String::ReplaceAny(const char* oldCharacters, const char* replaceString, int start, UInt32 flags) + { + if (start < 0) + { + start = m_sharedString->size+start; + if (start < 0) + start = 0; + } + + unsigned int pos = static_cast(start); + unsigned int oSize = (oldCharacters) ? std::strlen(oldCharacters) : 0; + unsigned int rSize = (replaceString) ? std::strlen(replaceString) : 0; + + if (pos >= m_sharedString->size || m_sharedString->size == 0 || oSize == 0) + return 0; + + unsigned int count = 0; + + if (rSize == 1) // On utilise un algorithme optimisé + { EnsureOwnership(); - ptr = &m_sharedString->string[offset]; - found = true; - } - - *ptr++ = replaceCharacter; - ++count; - } - } - - return count; -} -/* - unsigned int NzString::ReplaceAny(const char* oldCharacters, const char* replaceString, int start, nzUInt32 flags) - { - if (start < 0) - { - start = m_sharedString->size+start; - if (start < 0) - start = 0; - } - - unsigned int pos = static_cast(start); - unsigned int oSize = (oldCharacters) ? std::strlen(oldCharacters) : 0; - unsigned int rSize = (replaceString) ? std::strlen(replaceString) : 0; - - if (pos >= m_sharedString->size || m_sharedString->size == 0 || oSize == 0) - return 0; - - unsigned int count = 0; - - if (rSize == 1) // On utilise un algorithme optimisé - { - EnsureOwnership(); - - f or (; pos < m_sharedString->size; ++pos) - { - for (unsigned int i = 0; i < oSize; ++i) + f or (; pos < m_sharedString->size; ++pos) { - if (m_sharedString->string[pos] == oldCharacters[i]) + for (unsigned int i = 0; i < oSize; ++i) { - m_sharedString->string[pos] = replaceString[0]; - ++count; - - break; - } - } - } - } - else - { - unsigned int newSize; - { - unsigned int count = CountAny(oldCharacters); - newSize = m_sharedString->size - count + count*rSize; - } - char* newString = new char[newSize+1]; - - unsigned int j = 0; - for (unsigned int i = 0; i < m_sharedString->size; ++i) - { - if (i < pos) // Avant la position où on est censé commencer à remplacer, on ne fait que recopier - newString[j++] = m_sharedString->string[i]; - else - { - bool found = false; - for (unsigned int l = 0; l < oSize; ++l) - { - if (m_sharedString->string[i] == oldCharacters[l]) + if (m_sharedString->string[pos] == oldCharacters[i]) { - for (unsigned int k = 0; k < rSize; ++k) - newString[j++] = replaceString[k]; - + m_sharedString->string[pos] = replaceString[0]; ++count; - found = true; - break; // Simple façon d'éviter la ligne après la boucle + + break; } } - - if (!found) - newString[j++] = m_sharedString->string[i]; } } - newString[newSize] = '\0'; - - ReleaseString(); - - m_sharedString->size = newSize; - m_sharedString->string = newString; - } - - return count; - } - - unsigned int NzString::ReplaceAny(const NzString& oldCharacters, const NzString& replaceString, int start, nzUInt32 flags) - { - if (start < 0) - { - start = m_sharedString->size+start; - if (start < 0) - start = 0; - } - - unsigned int pos = static_cast(start); - - if (pos >= m_sharedString->size || m_sharedString->size == 0 || oldCharacters.m_sharedString->size == 0) - return 0; - - unsigned int count = 0; - - if (replaceString.m_sharedString->size == 1) // On utilise un algorithme optimisé - { - EnsureOwnership(); - - char character = replaceString[0]; - for (; pos < m_sharedString->size; ++pos) + else { - for (unsigned int i = 0; i < oldCharacters.m_sharedString->size; ++i) + unsigned int newSize; { - if (m_sharedString->string[pos] == oldCharacters[i]) + unsigned int count = CountAny(oldCharacters); + newSize = m_sharedString->size - count + count*rSize; + } + char* newString = new char[newSize+1]; + + unsigned int j = 0; + for (unsigned int i = 0; i < m_sharedString->size; ++i) + { + if (i < pos) // Avant la position où on est censé commencer à remplacer, on ne fait que recopier + newString[j++] = m_sharedString->string[i]; + else { - m_sharedString->string[pos] = character; - ++count; - break; + bool found = false; + for (unsigned int l = 0; l < oSize; ++l) + { + if (m_sharedString->string[i] == oldCharacters[l]) + { + for (unsigned int k = 0; k < rSize; ++k) + newString[j++] = replaceString[k]; + + ++count; + found = true; + break; // Simple façon d'éviter la ligne après la boucle + } + } + + if (!found) + newString[j++] = m_sharedString->string[i]; } } + newString[newSize] = '\0'; + + ReleaseString(); + + m_sharedString->size = newSize; + m_sharedString->string = newString; } + + return count; } - else + + unsigned int String::ReplaceAny(const String& oldCharacters, const String& replaceString, int start, UInt32 flags) { - unsigned int newSize; + if (start < 0) { - unsigned int count = CountAny(oldCharacters); - newSize = m_sharedString->size - count + count*replaceString.m_sharedString->size; + start = m_sharedString->size+start; + if (start < 0) + start = 0; } - char* newString = new char[newSize+1]; - unsigned int j = 0; - for (unsigned int i = 0; i < m_sharedString->size; ++i) + unsigned int pos = static_cast(start); + + if (pos >= m_sharedString->size || m_sharedString->size == 0 || oldCharacters.m_sharedString->size == 0) + return 0; + + unsigned int count = 0; + + if (replaceString.m_sharedString->size == 1) // On utilise un algorithme optimisé { - if (i < pos) // Avant la position où on est censé commencer à remplacer, on ne fait que recopier - newString[j++] = m_sharedString->string[i]; - else - { - bool found = false; - for (unsigned int l = 0; l < oldCharacters.m_sharedString->size; ++l) - { - if (m_sharedString->string[i] == oldCharacters[l]) - { - for (unsigned int k = 0; k < replaceString.m_sharedString->size; ++k) - newString[j++] = replaceString[k]; + EnsureOwnership(); + char character = replaceString[0]; + for (; pos < m_sharedString->size; ++pos) + { + for (unsigned int i = 0; i < oldCharacters.m_sharedString->size; ++i) + { + if (m_sharedString->string[pos] == oldCharacters[i]) + { + m_sharedString->string[pos] = character; ++count; - found = true; - break; // Simple façon d'éviter la ligne après la boucle + break; } } - - if (!found) - newString[j++] = m_sharedString->string[i]; } } - newString[newSize] = '\0'; + else + { + unsigned int newSize; + { + unsigned int count = CountAny(oldCharacters); + newSize = m_sharedString->size - count + count*replaceString.m_sharedString->size; + } + char* newString = new char[newSize+1]; - ReleaseString(); + unsigned int j = 0; + for (unsigned int i = 0; i < m_sharedString->size; ++i) + { + if (i < pos) // Avant la position où on est censé commencer à remplacer, on ne fait que recopier + newString[j++] = m_sharedString->string[i]; + else + { + bool found = false; + for (unsigned int l = 0; l < oldCharacters.m_sharedString->size; ++l) + { + if (m_sharedString->string[i] == oldCharacters[l]) + { + for (unsigned int k = 0; k < replaceString.m_sharedString->size; ++k) + newString[j++] = replaceString[k]; - m_sharedString->size = newSize; - m_sharedString->string = newString; + ++count; + found = true; + break; // Simple façon d'éviter la ligne après la boucle + } + } + + if (!found) + newString[j++] = m_sharedString->string[i]; + } + } + newString[newSize] = '\0'; + + ReleaseString(); + + m_sharedString->size = newSize; + m_sharedString->string = newString; + } + + return count; } - - return count; - } -*/ -void NzString::Reserve(unsigned int bufferSize) -{ - if (m_sharedString->capacity > bufferSize) - return; - - auto newString = std::make_shared(bufferSize); - newString->size = m_sharedString->size; - - if (m_sharedString->size > 0) - std::memcpy(newString->string.get(), m_sharedString->string.get(), m_sharedString->size); - - m_sharedString = std::move(newString); -} - -NzString& NzString::Resize(int size, char character) -{ - if (size == 0) + */ + void String::Reserve(unsigned int bufferSize) { - Clear(true); - return *this; - } + if (m_sharedString->capacity > bufferSize) + return; - if (size < 0) - size = std::max(m_sharedString->size + size, 0U); + auto newString = std::make_shared(bufferSize); + newString->size = m_sharedString->size; - unsigned int newSize = static_cast(size); - - if (m_sharedString->capacity >= newSize) - { - EnsureOwnership(); - - // We've got the space required, just fill it up - if (character != '\0' && newSize > m_sharedString->size) - std::memset(&m_sharedString->string[m_sharedString->size], character, newSize - m_sharedString->size); - - m_sharedString->size = newSize; - m_sharedString->string[newSize] = '\0'; // Adds the EoS character - } - else // Then we want to make the string bigger - { - auto newString = std::make_shared(newSize); - std::memcpy(newString->string.get(), m_sharedString->string.get(), m_sharedString->size); - - if (character != '\0') - std::memset(&newString->string[m_sharedString->size], character, newSize - m_sharedString->size); + if (m_sharedString->size > 0) + std::memcpy(newString->string.get(), m_sharedString->string.get(), m_sharedString->size); m_sharedString = std::move(newString); } - return *this; -} + String& String::Resize(int size, char character) + { + if (size == 0) + { + Clear(true); + return *this; + } -NzString NzString::Resized(int size, char character) const -{ - if (size < 0) - size = m_sharedString->size + size; + if (size < 0) + size = std::max(m_sharedString->size + size, 0U); - if (size <= 0) - return NzString(); + unsigned int newSize = static_cast(size); + + if (m_sharedString->capacity >= newSize) + { + EnsureOwnership(); + + // We've got the space required, just fill it up + if (character != '\0' && newSize > m_sharedString->size) + std::memset(&m_sharedString->string[m_sharedString->size], character, newSize - m_sharedString->size); + + m_sharedString->size = newSize; + m_sharedString->string[newSize] = '\0'; // Adds the EoS character + } + else // Then we want to make the string bigger + { + auto newString = std::make_shared(newSize); + std::memcpy(newString->string.get(), m_sharedString->string.get(), m_sharedString->size); + + if (character != '\0') + std::memset(&newString->string[m_sharedString->size], character, newSize - m_sharedString->size); + + m_sharedString = std::move(newString); + } - unsigned int newSize = static_cast(size); - if (newSize == m_sharedString->size) return *this; - - auto sharedStr = std::make_shared(newSize); - if (newSize > m_sharedString->size) - { - std::memcpy(sharedStr->string.get(), m_sharedString->string.get(), m_sharedString->size); - if (character != '\0') - std::memset(&sharedStr->string[m_sharedString->size], character, newSize - m_sharedString->size); - } - else - std::memcpy(sharedStr->string.get(), m_sharedString->string.get(), newSize); - - return NzString(std::move(sharedStr)); -} - -NzString& NzString::Reverse() -{ - if (m_sharedString->size != 0) - { - unsigned int i = 0; - unsigned int j = m_sharedString->size-1; - - while (i < j) - std::swap(m_sharedString->string[i++], m_sharedString->string[j--]); } - return *this; -} - -NzString NzString::Reversed() const -{ - if (m_sharedString->size == 0) - return NzString(); - - auto sharedStr = std::make_shared(m_sharedString->size); - - char* ptr = &sharedStr->string[m_sharedString->size - 1]; - char* p = m_sharedString->string.get(); - - do - *ptr-- = *p; - while (*(++p)); - - return NzString(std::move(sharedStr)); -} - -NzString& NzString::Set(char character) -{ - if (character != '\0') + String String::Resized(int size, char character) const { - if (m_sharedString->capacity >= 1) + if (size < 0) + size = m_sharedString->size + size; + + if (size <= 0) + return String(); + + unsigned int newSize = static_cast(size); + if (newSize == m_sharedString->size) + return *this; + + auto sharedStr = std::make_shared(newSize); + if (newSize > m_sharedString->size) { - EnsureOwnership(true); - - m_sharedString->size = 1; - m_sharedString->string[0] = character; - m_sharedString->string[1] = '\0'; + std::memcpy(sharedStr->string.get(), m_sharedString->string.get(), m_sharedString->size); + if (character != '\0') + std::memset(&sharedStr->string[m_sharedString->size], character, newSize - m_sharedString->size); } else - { - auto newString = std::make_shared(1); - newString->string[0] = character; - } + std::memcpy(sharedStr->string.get(), m_sharedString->string.get(), newSize); + + return String(std::move(sharedStr)); } - else - ReleaseString(); - return *this; -} - -NzString& NzString::Set(unsigned int rep, char character) -{ - if (rep > 0) + String& String::Reverse() { - if (m_sharedString->capacity >= rep) + if (m_sharedString->size != 0) { - EnsureOwnership(true); + unsigned int i = 0; + unsigned int j = m_sharedString->size-1; - m_sharedString->size = rep; - m_sharedString->string[rep] = '\0'; + while (i < j) + std::swap(m_sharedString->string[i++], m_sharedString->string[j--]); } - else - m_sharedString = std::make_shared(rep); - if (character != '\0') - std::memset(m_sharedString->string.get(), character, rep); + return *this; } - else - ReleaseString(); - return *this; -} - -NzString& NzString::Set(unsigned int rep, const char* string) -{ - return Set(rep, string, (string) ? std::strlen(string) : 0); -} - -NzString& NzString::Set(unsigned int rep, const char* string, unsigned int length) -{ - unsigned int totalSize = rep*length; - - if (totalSize > 0) + String String::Reversed() const { - if (m_sharedString->capacity >= totalSize) - { - EnsureOwnership(true); + if (m_sharedString->size == 0) + return String(); - m_sharedString->size = totalSize; - m_sharedString->string[totalSize] = '\0'; - } - else - m_sharedString = std::make_shared(totalSize); + auto sharedStr = std::make_shared(m_sharedString->size); - for (unsigned int i = 0; i < rep; ++i) - std::memcpy(&m_sharedString->string[i*length], string, length); - } - else - ReleaseString(); + char* ptr = &sharedStr->string[m_sharedString->size - 1]; + char* p = m_sharedString->string.get(); - return *this; -} - -NzString& NzString::Set(unsigned int rep, const NzString& string) -{ - return Set(rep, string.GetConstBuffer(), string.m_sharedString->size); -} - -NzString& NzString::Set(const char* string) -{ - return Set(string, (string) ? std::strlen(string) : 0); -} - -NzString& NzString::Set(const char* string, unsigned int length) -{ - if (length > 0) - { - if (m_sharedString->capacity >= length) - { - EnsureOwnership(true); - - m_sharedString->size = length; - m_sharedString->string[length] = '\0'; - } - else - m_sharedString = std::make_shared(length); - - std::memcpy(m_sharedString->string.get(), string, length); - } - else - ReleaseString(); - - return *this; -} - -NzString& NzString::Set(const std::string& string) -{ - return Set(string.data(), string.size()); -} - -NzString& NzString::Set(const NzString& string) -{ - m_sharedString = string.m_sharedString; - - return *this; -} - -NzString& NzString::Set(NzString&& string) noexcept -{ - std::swap(m_sharedString, string.m_sharedString); - - return *this; -} - -NzString NzString::Simplified(nzUInt32 flags) const -{ - if (m_sharedString->size == 0) - return NzString(); - - auto newString = std::make_shared(m_sharedString->size); - char* str = newString->string.get(); - char* p = str; - - const char* ptr = m_sharedString->string.get(); - bool inword = false; - if (flags & HandleUtf8) - { - utf8::unchecked::iterator it(ptr); do + *ptr-- = *p; + while (*(++p)); + + return String(std::move(sharedStr)); + } + + String& String::Set(char character) + { + if (character != '\0') { - if (NzUnicode::GetCategory(*it) & NzUnicode::Category_Separator) + if (m_sharedString->capacity >= 1) { - if (inword) - { - *p++ = ' '; - inword = false; - } + EnsureOwnership(true); + + m_sharedString->size = 1; + m_sharedString->string[0] = character; + m_sharedString->string[1] = '\0'; } else { - p = utf8::append(*it, p); - inword = true; + auto newString = std::make_shared(1); + newString->string[0] = character; } } - while (*++it); + else + ReleaseString(); + + return *this; } - else + + String& String::Set(unsigned int rep, char character) { - const char* limit = &m_sharedString->string[m_sharedString->size]; - do + if (rep > 0) { - if (std::isspace(*ptr)) + if (m_sharedString->capacity >= rep) { - if (inword) - { - *p++ = ' '; - inword = false; - } + EnsureOwnership(true); + + m_sharedString->size = rep; + m_sharedString->string[rep] = '\0'; } else - { - *p++ = *ptr; - inword = true; - } + m_sharedString = std::make_shared(rep); + + if (character != '\0') + std::memset(m_sharedString->string.get(), character, rep); } - while (++ptr != limit); + else + ReleaseString(); + + return *this; } - if (!inword && p != str) - p--; - - *p = '\0'; - - return NzString(std::move(newString)); -} - -NzString& NzString::Simplify(nzUInt32 flags) -{ - return Set(Simplified(flags)); -} - -unsigned int NzString::Split(std::vector& result, char separation, int start, nzUInt32 flags) const -{ - if (separation == '\0' || m_sharedString->size == 0) - return 0; - - unsigned int lastSep = Find(separation, start, flags); - if (lastSep == npos) + String& String::Set(unsigned int rep, const char* string) { - result.push_back(*this); - return 1; - } - else if (lastSep != 0) - result.push_back(SubString(0, lastSep-1)); - - while (true) - { - unsigned int sep = Find(separation, lastSep+1, flags); - if (sep == npos) - break; - - if (sep-lastSep > 1) - result.push_back(SubString(lastSep+1, sep-1)); - - lastSep = sep; + return Set(rep, string, (string) ? std::strlen(string) : 0); } - if (lastSep != m_sharedString->size-1) - result.push_back(SubString(lastSep+1)); - - return result.size(); -} - -unsigned int NzString::Split(std::vector& result, const char* separation, int start, nzUInt32 flags) const -{ - return Split(result, separation, std::strlen(separation), start, flags); -} - -unsigned int NzString::Split(std::vector& result, const char* separation, unsigned int length, int start, nzUInt32 flags) const -{ - if (m_sharedString->size == 0) - return 0; - else if (length == 0) + String& String::Set(unsigned int rep, const char* string, unsigned int length) { - result.reserve(m_sharedString->size); - for (unsigned int i = 0; i < m_sharedString->size; ++i) - result.push_back(NzString(m_sharedString->string[i])); + unsigned int totalSize = rep*length; - return m_sharedString->size; - } - else if (length > m_sharedString->size) - { - result.push_back(*this); - return 1; + if (totalSize > 0) + { + if (m_sharedString->capacity >= totalSize) + { + EnsureOwnership(true); + + m_sharedString->size = totalSize; + m_sharedString->string[totalSize] = '\0'; + } + else + m_sharedString = std::make_shared(totalSize); + + for (unsigned int i = 0; i < rep; ++i) + std::memcpy(&m_sharedString->string[i*length], string, length); + } + else + ReleaseString(); + + return *this; } - unsigned int lastSep = Find(separation, start, flags); - unsigned int oldSize = result.size(); - if (lastSep == npos) + String& String::Set(unsigned int rep, const String& string) { - result.push_back(*this); - return 1; - } - else if (lastSep != 0) - result.push_back(SubString(0, lastSep-1)); - - unsigned int sep; - while ((sep = Find(separation, lastSep + length, flags)) != npos) - { - if (sep-lastSep > length) - result.push_back(SubString(lastSep + length, sep-1)); - - lastSep = sep; + return Set(rep, string.GetConstBuffer(), string.m_sharedString->size); } - if (lastSep != m_sharedString->size - length) - result.push_back(SubString(lastSep + length)); - - return result.size()-oldSize; -} - -unsigned int NzString::Split(std::vector& result, const NzString& separation, int start, nzUInt32 flags) const -{ - return Split(result, separation.m_sharedString->string.get(), separation.m_sharedString->size, start, flags); -} - -unsigned int NzString::SplitAny(std::vector& result, const char* separations, int start, nzUInt32 flags) const -{ - if (m_sharedString->size == 0) - return 0; - - unsigned int oldSize = result.size(); - - unsigned int lastSep = FindAny(separations, start, flags); - if (lastSep == npos) + String& String::Set(const char* string) { - result.push_back(*this); - return 1; - } - else if (lastSep != 0) - result.push_back(SubString(0, lastSep-1)); - - unsigned int sep; - while ((sep = FindAny(separations, lastSep+1, flags)) != npos) - { - if (sep-lastSep > 1) - result.push_back(SubString(lastSep+1, sep-1)); - - lastSep = sep; + return Set(string, (string) ? std::strlen(string) : 0); } - if (lastSep != m_sharedString->size-1) - result.push_back(SubString(lastSep+1)); - - return result.size()-oldSize; -} - -unsigned int NzString::SplitAny(std::vector& result, const NzString& separations, int start, nzUInt32 flags) const -{ - return SplitAny(result, separations.m_sharedString->string.get(), start, flags); -} - -bool NzString::StartsWith(char character, nzUInt32 flags) const -{ - if (character == '\0' || m_sharedString->size == 0) - return false; - - if (flags & CaseInsensitive) - return nzToLower(m_sharedString->string[0]) == nzToLower(character); - else - return m_sharedString->string[0] == character; -} - -bool NzString::StartsWith(const char* string, nzUInt32 flags) const -{ - if (!string || !string[0] || m_sharedString->size == 0) - return false; - - if (flags & CaseInsensitive) + String& String::Set(const char* string, unsigned int length) { + if (length > 0) + { + if (m_sharedString->capacity >= length) + { + EnsureOwnership(true); + + m_sharedString->size = length; + m_sharedString->string[length] = '\0'; + } + else + m_sharedString = std::make_shared(length); + + std::memcpy(m_sharedString->string.get(), string, length); + } + else + ReleaseString(); + + return *this; + } + + String& String::Set(const std::string& string) + { + return Set(string.data(), string.size()); + } + + String& String::Set(const String& string) + { + m_sharedString = string.m_sharedString; + + return *this; + } + + String& String::Set(String&& string) noexcept + { + std::swap(m_sharedString, string.m_sharedString); + + return *this; + } + + String String::Simplified(UInt32 flags) const + { + if (m_sharedString->size == 0) + return String(); + + auto newString = std::make_shared(m_sharedString->size); + char* str = newString->string.get(); + char* p = str; + + const char* ptr = m_sharedString->string.get(); + bool inword = false; if (flags & HandleUtf8) { - utf8::unchecked::iterator it(m_sharedString->string.get()); - utf8::unchecked::iterator it2(string); + utf8::unchecked::iterator it(ptr); do { - if (*it2 == '\0') - return true; - - if (NzUnicode::GetLowercase(*it) != NzUnicode::GetLowercase(*it2)) - return false; - - ++it2; + if (Unicode::GetCategory(*it) & Unicode::Category_Separator) + { + if (inword) + { + *p++ = ' '; + inword = false; + } + } + else + { + p = utf8::append(*it, p); + inword = true; + } + } + while (*++it); + } + else + { + const char* limit = &m_sharedString->string[m_sharedString->size]; + do + { + if (std::isspace(*ptr)) + { + if (inword) + { + *p++ = ' '; + inword = false; + } + } + else + { + *p++ = *ptr; + inword = true; + } + } + while (++ptr != limit); + } + + if (!inword && p != str) + p--; + + *p = '\0'; + + return String(std::move(newString)); + } + + String& String::Simplify(UInt32 flags) + { + return Set(Simplified(flags)); + } + + unsigned int String::Split(std::vector& result, char separation, int start, UInt32 flags) const + { + if (separation == '\0' || m_sharedString->size == 0) + return 0; + + unsigned int lastSep = Find(separation, start, flags); + if (lastSep == npos) + { + result.push_back(*this); + return 1; + } + else if (lastSep != 0) + result.push_back(SubString(0, lastSep-1)); + + while (true) + { + unsigned int sep = Find(separation, lastSep+1, flags); + if (sep == npos) + break; + + if (sep-lastSep > 1) + result.push_back(SubString(lastSep+1, sep-1)); + + lastSep = sep; + } + + if (lastSep != m_sharedString->size-1) + result.push_back(SubString(lastSep+1)); + + return result.size(); + } + + unsigned int String::Split(std::vector& result, const char* separation, int start, UInt32 flags) const + { + return Split(result, separation, std::strlen(separation), start, flags); + } + + unsigned int String::Split(std::vector& result, const char* separation, unsigned int length, int start, UInt32 flags) const + { + if (m_sharedString->size == 0) + return 0; + else if (length == 0) + { + result.reserve(m_sharedString->size); + for (unsigned int i = 0; i < m_sharedString->size; ++i) + result.push_back(String(m_sharedString->string[i])); + + return m_sharedString->size; + } + else if (length > m_sharedString->size) + { + result.push_back(*this); + return 1; + } + + unsigned int lastSep = Find(separation, start, flags); + unsigned int oldSize = result.size(); + if (lastSep == npos) + { + result.push_back(*this); + return 1; + } + else if (lastSep != 0) + result.push_back(SubString(0, lastSep-1)); + + unsigned int sep; + while ((sep = Find(separation, lastSep + length, flags)) != npos) + { + if (sep-lastSep > length) + result.push_back(SubString(lastSep + length, sep-1)); + + lastSep = sep; + } + + if (lastSep != m_sharedString->size - length) + result.push_back(SubString(lastSep + length)); + + return result.size()-oldSize; + } + + unsigned int String::Split(std::vector& result, const String& separation, int start, UInt32 flags) const + { + return Split(result, separation.m_sharedString->string.get(), separation.m_sharedString->size, start, flags); + } + + unsigned int String::SplitAny(std::vector& result, const char* separations, int start, UInt32 flags) const + { + if (m_sharedString->size == 0) + return 0; + + unsigned int oldSize = result.size(); + + unsigned int lastSep = FindAny(separations, start, flags); + if (lastSep == npos) + { + result.push_back(*this); + return 1; + } + else if (lastSep != 0) + result.push_back(SubString(0, lastSep-1)); + + unsigned int sep; + while ((sep = FindAny(separations, lastSep+1, flags)) != npos) + { + if (sep-lastSep > 1) + result.push_back(SubString(lastSep+1, sep-1)); + + lastSep = sep; + } + + if (lastSep != m_sharedString->size-1) + result.push_back(SubString(lastSep+1)); + + return result.size()-oldSize; + } + + unsigned int String::SplitAny(std::vector& result, const String& separations, int start, UInt32 flags) const + { + return SplitAny(result, separations.m_sharedString->string.get(), start, flags); + } + + bool String::StartsWith(char character, UInt32 flags) const + { + if (character == '\0' || m_sharedString->size == 0) + return false; + + if (flags & CaseInsensitive) + return Detail::ToLower(m_sharedString->string[0]) == Detail::ToLower(character); + else + return m_sharedString->string[0] == character; + } + + bool String::StartsWith(const char* string, UInt32 flags) const + { + if (!string || !string[0] || m_sharedString->size == 0) + return false; + + if (flags & CaseInsensitive) + { + if (flags & HandleUtf8) + { + utf8::unchecked::iterator it(m_sharedString->string.get()); + utf8::unchecked::iterator it2(string); + do + { + if (*it2 == '\0') + return true; + + if (Unicode::GetLowercase(*it) != Unicode::GetLowercase(*it2)) + return false; + + ++it2; + } + while (*it++); + } + else + { + char* ptr = m_sharedString->string.get(); + const char* s = string; + do + { + if (*s == '\0') + return true; + + if (Detail::ToLower(*ptr) != Detail::ToLower(*s)) + return false; + + s++; + } + while (*ptr++); } - while (*it++); } else { @@ -2909,1307 +2931,1291 @@ bool NzString::StartsWith(const char* string, nzUInt32 flags) const if (*s == '\0') return true; - if (nzToLower(*ptr) != nzToLower(*s)) + if (*ptr != *s) return false; s++; } while (*ptr++); } - } - else - { - char* ptr = m_sharedString->string.get(); - const char* s = string; - do - { - if (*s == '\0') - return true; - if (*ptr != *s) - return false; - - s++; - } - while (*ptr++); + return false; } - return false; -} - -bool NzString::StartsWith(const NzString& string, nzUInt32 flags) const -{ - if (string.m_sharedString->size == 0) - return false; - - if (m_sharedString->size < string.m_sharedString->size) - return false; - - if (flags & CaseInsensitive) + bool String::StartsWith(const String& string, UInt32 flags) const { - if (flags & HandleUtf8) + if (string.m_sharedString->size == 0) + return false; + + if (m_sharedString->size < string.m_sharedString->size) + return false; + + if (flags & CaseInsensitive) { - utf8::unchecked::iterator it(m_sharedString->string.get()); - utf8::unchecked::iterator it2(string.GetConstBuffer()); - do + if (flags & HandleUtf8) { - if (*it2 == '\0') - return true; + utf8::unchecked::iterator it(m_sharedString->string.get()); + utf8::unchecked::iterator it2(string.GetConstBuffer()); + do + { + if (*it2 == '\0') + return true; - if (NzUnicode::GetLowercase(*it) != NzUnicode::GetLowercase(*it2)) - return false; + if (Unicode::GetLowercase(*it) != Unicode::GetLowercase(*it2)) + return false; - ++it2; + ++it2; + } + while (*it++); + } + else + { + char* ptr = m_sharedString->string.get(); + const char* s = string.GetConstBuffer(); + do + { + if (*s == '\0') + return true; + + if (Detail::ToLower(*ptr) != Detail::ToLower(*s)) + return false; + + s++; + } + while (*ptr++); } - while (*it++); } else - { - char* ptr = m_sharedString->string.get(); - const char* s = string.GetConstBuffer(); - do - { - if (*s == '\0') - return true; + return std::memcmp(m_sharedString->string.get(), string.GetConstBuffer(), string.m_sharedString->size) == 0; - if (nzToLower(*ptr) != nzToLower(*s)) - return false; - - s++; - } - while (*ptr++); - } - } - else - return std::memcmp(m_sharedString->string.get(), string.GetConstBuffer(), string.m_sharedString->size) == 0; - - return false; -} - -NzString NzString::SubString(int startPos, int endPos) const -{ - if (startPos < 0) - startPos = std::max(m_sharedString->size+startPos, 0U); - - unsigned int start = static_cast(startPos); - - if (endPos < 0) - { - endPos = m_sharedString->size+endPos; - if (endPos < 0) - return NzString(); - } - - unsigned int minEnd = std::min(static_cast(endPos), m_sharedString->size-1); - - if (start > minEnd || start >= m_sharedString->size) - return NzString(); - - unsigned int size = minEnd-start+1; - - auto str = std::make_shared(size); - std::memcpy(str->string.get(), &m_sharedString->string[start], size); - - return NzString(std::move(str)); -} - -NzString NzString::SubStringFrom(char character, int startPos, bool fromLast, bool include, nzUInt32 flags) const -{ - if (character == '\0') - return *this; - - unsigned int pos; - if (fromLast) - pos = FindLast(character, startPos, flags); - else - pos = Find(character, startPos, flags); - - if (pos == 0 && include) - return *this; - else if (pos == npos) - return NzString(); - - return SubString(pos + ((include) ? 0 : 1)); -} - -NzString NzString::SubStringFrom(const char* string, int startPos, bool fromLast, bool include, nzUInt32 flags) const -{ - return SubStringFrom(string, std::strlen(string), startPos, fromLast, include, flags); -} - -NzString NzString::SubStringFrom(const char* string, unsigned int length, int startPos, bool fromLast, bool include, nzUInt32 flags) const -{ - unsigned int pos; - if (fromLast) - pos = FindLast(string, startPos, flags); - else - pos = Find(string, startPos, flags); - - if (pos == 0 && include) - return *this; - else if (pos == npos) - return NzString(); - - return SubString(pos + ((include) ? 0 : length)); -} - -NzString NzString::SubStringFrom(const NzString& string, int startPos, bool fromLast, bool include, nzUInt32 flags) const -{ - return SubStringFrom(string.GetConstBuffer(), string.m_sharedString->size, startPos, fromLast, include, flags); -} - -NzString NzString::SubStringTo(char character, int startPos, bool toLast, bool include, nzUInt32 flags) const -{ - if (character == '\0') - return *this; - - unsigned int pos; - if (toLast) - pos = FindLast(character, startPos); - else - pos = Find(character, startPos, flags); - - if (pos == 0) - return (include) ? NzString(character) : NzString(); - else if (pos == npos) - return *this; - - return SubString(0, pos+((include) ? 1 : 0)-1); -} - -NzString NzString::SubStringTo(const char* string, int startPos, bool toLast, bool include, nzUInt32 flags) const -{ - return SubStringTo(string, std::strlen(string), startPos, toLast, include, flags); -} - -NzString NzString::SubStringTo(const char* string, unsigned int length, int startPos, bool toLast, bool include, nzUInt32 flags) const -{ - unsigned int pos; - if (toLast) - pos = FindLast(string, startPos, flags); - else - pos = Find(string, startPos, flags); - - if (pos == 0) - return (include) ? string : NzString(); - else if (pos == npos) - return *this; - - return SubString(0, pos+((include) ? length : 0)-1); -} - -NzString NzString::SubStringTo(const NzString& string, int startPos, bool toLast, bool include, nzUInt32 flags) const -{ - return SubStringTo(string.GetConstBuffer(), string.m_sharedString->size, startPos, toLast, include, flags); -} - -void NzString::Swap(NzString& str) -{ - std::swap(m_sharedString, str.m_sharedString); -} - -bool NzString::ToBool(bool* value, nzUInt32 flags) const -{ - if (m_sharedString->size == 0) return false; - - NzString word = GetWord(0); - - if (word[0] == '1') - { - if (value) - *value = true; } - else if (word[0] == '0') - { - if (value) - *value = false; - } - else - { - if (flags & CaseInsensitive) - word = word.ToLower(); // Les mots identifiés sont en ASCII, inutile de passer le flag unicode - if (word == "true") + String String::SubString(int startPos, int endPos) const + { + if (startPos < 0) + startPos = std::max(m_sharedString->size+startPos, 0U); + + unsigned int start = static_cast(startPos); + + if (endPos < 0) + { + endPos = m_sharedString->size+endPos; + if (endPos < 0) + return String(); + } + + unsigned int minEnd = std::min(static_cast(endPos), m_sharedString->size-1); + + if (start > minEnd || start >= m_sharedString->size) + return String(); + + unsigned int size = minEnd-start+1; + + auto str = std::make_shared(size); + std::memcpy(str->string.get(), &m_sharedString->string[start], size); + + return String(std::move(str)); + } + + String String::SubStringFrom(char character, int startPos, bool fromLast, bool include, UInt32 flags) const + { + if (character == '\0') + return *this; + + unsigned int pos; + if (fromLast) + pos = FindLast(character, startPos, flags); + else + pos = Find(character, startPos, flags); + + if (pos == 0 && include) + return *this; + else if (pos == npos) + return String(); + + return SubString(pos + ((include) ? 0 : 1)); + } + + String String::SubStringFrom(const char* string, int startPos, bool fromLast, bool include, UInt32 flags) const + { + return SubStringFrom(string, std::strlen(string), startPos, fromLast, include, flags); + } + + String String::SubStringFrom(const char* string, unsigned int length, int startPos, bool fromLast, bool include, UInt32 flags) const + { + unsigned int pos; + if (fromLast) + pos = FindLast(string, startPos, flags); + else + pos = Find(string, startPos, flags); + + if (pos == 0 && include) + return *this; + else if (pos == npos) + return String(); + + return SubString(pos + ((include) ? 0 : length)); + } + + String String::SubStringFrom(const String& string, int startPos, bool fromLast, bool include, UInt32 flags) const + { + return SubStringFrom(string.GetConstBuffer(), string.m_sharedString->size, startPos, fromLast, include, flags); + } + + String String::SubStringTo(char character, int startPos, bool toLast, bool include, UInt32 flags) const + { + if (character == '\0') + return *this; + + unsigned int pos; + if (toLast) + pos = FindLast(character, startPos); + else + pos = Find(character, startPos, flags); + + if (pos == 0) + return (include) ? String(character) : String(); + else if (pos == npos) + return *this; + + return SubString(0, pos+((include) ? 1 : 0)-1); + } + + String String::SubStringTo(const char* string, int startPos, bool toLast, bool include, UInt32 flags) const + { + return SubStringTo(string, std::strlen(string), startPos, toLast, include, flags); + } + + String String::SubStringTo(const char* string, unsigned int length, int startPos, bool toLast, bool include, UInt32 flags) const + { + unsigned int pos; + if (toLast) + pos = FindLast(string, startPos, flags); + else + pos = Find(string, startPos, flags); + + if (pos == 0) + return (include) ? string : String(); + else if (pos == npos) + return *this; + + return SubString(0, pos+((include) ? length : 0)-1); + } + + String String::SubStringTo(const String& string, int startPos, bool toLast, bool include, UInt32 flags) const + { + return SubStringTo(string.GetConstBuffer(), string.m_sharedString->size, startPos, toLast, include, flags); + } + + void String::Swap(String& str) + { + std::swap(m_sharedString, str.m_sharedString); + } + + bool String::ToBool(bool* value, UInt32 flags) const + { + if (m_sharedString->size == 0) + return false; + + String word = GetWord(0); + + if (word[0] == '1') { if (value) *value = true; } - else if (word == "false") + else if (word[0] == '0') { if (value) *value = false; } else - return false; - } - - return true; -} - -bool NzString::ToDouble(double* value) const -{ - if (m_sharedString->size == 0) - return false; - - if (value) - *value = std::atof(m_sharedString->string.get()); - - return true; -} - -bool NzString::ToInteger(long long* value, nzUInt8 base) const -{ - if (value) - { - bool ok; - *value = NzStringToNumber(*this, base, &ok); - - return ok; - } - else - return IsNumber(base); -} - -NzString NzString::ToLower(nzUInt32 flags) const -{ - if (m_sharedString->size == 0) - return *this; - - if (flags & HandleUtf8) - { - NzString lower; - lower.Reserve(m_sharedString->size); - utf8::unchecked::iterator it(m_sharedString->string.get()); - do - utf8::append(NzUnicode::GetLowercase(*it), std::back_inserter(lower)); - while (*++it); - - return lower; - } - else - { - auto str = std::make_shared(m_sharedString->size); - - char* ptr = m_sharedString->string.get(); - char* s = str->string.get(); - do - *s++ = nzToLower(*ptr); - while (*++ptr); - - *s = '\0'; - - return NzString(std::move(str)); - } -} - -NzString NzString::ToUpper(nzUInt32 flags) const -{ - if (m_sharedString->size == 0) - return *this; - - if (flags & HandleUtf8) - { - NzString upper; - upper.Reserve(m_sharedString->size); - utf8::unchecked::iterator it(m_sharedString->string.get()); - do - utf8::append(NzUnicode::GetUppercase(*it), std::back_inserter(upper)); - while (*++it); - - return upper; - } - else - { - auto str = std::make_shared(m_sharedString->size); - - char* ptr = m_sharedString->string.get(); - char* s = str->string.get(); - do - *s++ = nzToUpper(*ptr); - while (*++ptr); - - *s = '\0'; - - return NzString(std::move(str)); - } -} - -NzString& NzString::Trim(nzUInt32 flags) -{ - return Set(Trimmed(flags)); -} - -NzString& NzString::Trim(char character, nzUInt32 flags) -{ - return Set(Trimmed(character, flags)); -} - -NzString NzString::Trimmed(nzUInt32 flags) const -{ - if (m_sharedString->size == 0) - return *this; - - unsigned int startPos; - unsigned int endPos; - if (flags & HandleUtf8) - { - if ((flags & TrimOnlyRight) == 0) { + if (flags & CaseInsensitive) + word = word.ToLower(); // Les mots identifiés sont en ASCII, inutile de passer le flag unicode + + if (word == "true") + { + if (value) + *value = true; + } + else if (word == "false") + { + if (value) + *value = false; + } + else + return false; + } + + return true; + } + + bool String::ToDouble(double* value) const + { + if (m_sharedString->size == 0) + return false; + + if (value) + *value = std::atof(m_sharedString->string.get()); + + return true; + } + + bool String::ToInteger(long long* value, UInt8 base) const + { + if (value) + { + bool ok; + *value = StringToNumber(*this, base, &ok); + + return ok; + } + else + return IsNumber(base); + } + + String String::ToLower(UInt32 flags) const + { + if (m_sharedString->size == 0) + return *this; + + if (flags & HandleUtf8) + { + String lower; + lower.Reserve(m_sharedString->size); utf8::unchecked::iterator it(m_sharedString->string.get()); do - { - if (NzUnicode::GetCategory(*it) & NzUnicode::Category_Separator) - break; - } + utf8::append(Unicode::GetLowercase(*it), std::back_inserter(lower)); while (*++it); - startPos = it.base() - m_sharedString->string.get(); + return lower; } else - startPos = 0; - - if ((flags & TrimOnlyLeft) == 0) { - utf8::unchecked::iterator it(&m_sharedString->string[m_sharedString->size]); - while ((it--).base() != m_sharedString->string.get()) - { - if (NzUnicode::GetCategory(*it) & NzUnicode::Category_Separator) - break; - } + auto str = std::make_shared(m_sharedString->size); - endPos = it.base() - m_sharedString->string.get(); + char* ptr = m_sharedString->string.get(); + char* s = str->string.get(); + do + *s++ = Detail::ToLower(*ptr); + while (*++ptr); + + *s = '\0'; + + return String(std::move(str)); + } + } + + String String::ToUpper(UInt32 flags) const + { + if (m_sharedString->size == 0) + return *this; + + if (flags & HandleUtf8) + { + String upper; + upper.Reserve(m_sharedString->size); + utf8::unchecked::iterator it(m_sharedString->string.get()); + do + utf8::append(Unicode::GetUppercase(*it), std::back_inserter(upper)); + while (*++it); + + return upper; } else - endPos = m_sharedString->size-1; - } - else - { - startPos = 0; - if ((flags & TrimOnlyRight) == 0) { - for (; startPos < m_sharedString->size; ++startPos) - { - if (!std::isspace(m_sharedString->string[startPos])) - break; - } - } + auto str = std::make_shared(m_sharedString->size); - endPos = m_sharedString->size-1; - if ((flags & TrimOnlyLeft) == 0) - { - for (; endPos > 0; --endPos) - { - if (!std::isspace(m_sharedString->string[endPos])) - break; - } + char* ptr = m_sharedString->string.get(); + char* s = str->string.get(); + do + *s++ = Detail::ToUpper(*ptr); + while (*++ptr); + + *s = '\0'; + + return String(std::move(str)); } } - return SubString(startPos, endPos); -} - -NzString NzString::Trimmed(char character, nzUInt32 flags) const -{ - if (m_sharedString->size == 0) - return *this; - - unsigned int startPos = 0; - unsigned int endPos = m_sharedString->size-1; - if (flags & CaseInsensitive) + String& String::Trim(UInt32 flags) { - char ch = nzToLower(character); - if ((flags & TrimOnlyRight) == 0) + return Set(Trimmed(flags)); + } + + String& String::Trim(char character, UInt32 flags) + { + return Set(Trimmed(character, flags)); + } + + String String::Trimmed(UInt32 flags) const + { + if (m_sharedString->size == 0) + return *this; + + unsigned int startPos; + unsigned int endPos; + if (flags & HandleUtf8) { - for (; startPos < m_sharedString->size; ++startPos) + if ((flags & TrimOnlyRight) == 0) { - if (nzToLower(m_sharedString->string[startPos]) != ch) - break; + utf8::unchecked::iterator it(m_sharedString->string.get()); + do + { + if (Unicode::GetCategory(*it) & Unicode::Category_Separator) + break; + } + while (*++it); + + startPos = it.base() - m_sharedString->string.get(); } - } - - if ((flags & TrimOnlyLeft) == 0) - { - for (; endPos > 0; --endPos) - { - if (nzToLower(m_sharedString->string[endPos]) != ch) - break; - } - } - } - else - { - if ((flags & TrimOnlyRight) == 0) - { - for (; startPos < m_sharedString->size; ++startPos) - { - if (m_sharedString->string[startPos] != character) - break; - } - } - - if ((flags & TrimOnlyLeft) == 0) - { - for (; endPos > 0; --endPos) - { - if (m_sharedString->string[endPos] != character) - break; - } - } - } - - return SubString(startPos, endPos); -} - -char* NzString::begin() -{ - return m_sharedString->string.get(); -} - -const char* NzString::begin() const -{ - return m_sharedString->string.get(); -} - -char* NzString::end() -{ - return &m_sharedString->string[m_sharedString->size]; -} - -const char* NzString::end() const -{ - return &m_sharedString->string[m_sharedString->size]; -} - -void NzString::push_front(char c) -{ - Prepend(c); -} - -void NzString::push_back(char c) -{ - Append(c); -} -/* -char* NzString::rbegin() -{ - return &m_sharedString->string[m_sharedString->size-1]; -} - -const char* NzString::rbegin() const -{ - return &m_sharedString->string[m_sharedString->size-1]; -} - -char* NzString::rend() -{ - return &m_sharedString->string[-1]; -} - -const char* NzString::rend() const -{ - return &m_sharedString->string[-1]; -} -*/ - -NzString::operator std::string() const -{ - return std::string(m_sharedString->string.get(), m_sharedString->size); -} - -char& NzString::operator[](unsigned int pos) -{ - EnsureOwnership(); - - if (pos >= m_sharedString->size) - Resize(pos+1); - - return m_sharedString->string[pos]; -} - -char NzString::operator[](unsigned int pos) const -{ - #if NAZARA_CORE_SAFE - if (pos >= m_sharedString->size) - { - NazaraError("Index out of range (" + Number(pos) + " >= " + Number(m_sharedString->size) + ')'); - return 0; - } - #endif - - return m_sharedString->string[pos]; -} - -NzString& NzString::operator=(char character) -{ - return Set(character); -} - -NzString& NzString::operator=(const char* string) -{ - return Set(string); -} - -NzString& NzString::operator=(const std::string& string) -{ - return Set(string); -} - -NzString& NzString::operator=(const NzString& string) -{ - return Set(string); -} - -NzString& NzString::operator=(NzString&& string) noexcept -{ - return Set(string); -} - -NzString NzString::operator+(char character) const -{ - if (character == '\0') - return *this; - - auto str = std::make_shared(m_sharedString->size + 1); - std::memcpy(str->string.get(), GetConstBuffer(), m_sharedString->size); - str->string[m_sharedString->size] = character; - - return NzString(std::move(str)); -} - -NzString NzString::operator+(const char* string) const -{ - if (!string || !string[0]) - return *this; - - if (m_sharedString->size == 0) - return string; - - unsigned int length = std::strlen(string); - if (length == 0) - return *this; - - auto str = std::make_shared(m_sharedString->size + length); - std::memcpy(str->string.get(), GetConstBuffer(), m_sharedString->size); - std::memcpy(&str->string[m_sharedString->size], string, length+1); - - return NzString(std::move(str)); -} - -NzString NzString::operator+(const std::string& string) const -{ - if (string.empty()) - return *this; - - if (m_sharedString->size == 0) - return string; - - auto str = std::make_shared(m_sharedString->size + string.size()); - std::memcpy(str->string.get(), GetConstBuffer(), m_sharedString->size); - std::memcpy(&str->string[m_sharedString->size], string.c_str(), string.size()+1); - - return NzString(std::move(str)); -} - -NzString NzString::operator+(const NzString& string) const -{ - if (string.m_sharedString->size == 0) - return *this; - - if (m_sharedString->size == 0) - return string; - - auto str = std::make_shared(m_sharedString->size + string.m_sharedString->size); - std::memcpy(str->string.get(), GetConstBuffer(), m_sharedString->size); - std::memcpy(&str->string[m_sharedString->size], string.GetConstBuffer(), string.m_sharedString->size); - - return NzString(std::move(str)); -} - -NzString& NzString::operator+=(char character) -{ - return Insert(m_sharedString->size, character); -} - -NzString& NzString::operator+=(const char* string) -{ - return Insert(m_sharedString->size, string); -} - -NzString& NzString::operator+=(const std::string& string) -{ - return Insert(m_sharedString->size, string.c_str(), string.size()); -} - -NzString& NzString::operator+=(const NzString& string) -{ - return Insert(m_sharedString->size, string); -} - -bool NzString::operator==(char character) const -{ - if (m_sharedString->size == 0) - return character == '\0'; - - if (m_sharedString->size > 1) - return false; - - return m_sharedString->string[0] == character; -} - -bool NzString::operator==(const char* string) const -{ - if (m_sharedString->size == 0) - return !string || !string[0]; - - if (!string || !string[0]) - return false; - - return std::strcmp(GetConstBuffer(), string) == 0; -} - -bool NzString::operator==(const std::string& string) const -{ - if (m_sharedString->size == 0 || string.empty()) - return m_sharedString->size == string.size(); - - if (m_sharedString->size != string.size()) - return false; - - return std::strcmp(GetConstBuffer(), string.c_str()) == 0; -} - -bool NzString::operator!=(char character) const -{ - if (m_sharedString->size == 0) - return character != '\0'; - - if (character == '\0' || m_sharedString->size != 1) - return true; - - if (m_sharedString->size != 1) - return true; - - return m_sharedString->string[0] != character; -} - -bool NzString::operator!=(const char* string) const -{ - if (m_sharedString->size == 0) - return string && string[0]; - - if (!string || !string[0]) - return true; - - return std::strcmp(GetConstBuffer(), string) != 0; -} - -bool NzString::operator!=(const std::string& string) const -{ - if (m_sharedString->size == 0 || string.empty()) - return m_sharedString->size == string.size(); - - if (m_sharedString->size != string.size()) - return false; - - return std::strcmp(GetConstBuffer(), string.c_str()) != 0; -} - -bool NzString::operator<(char character) const -{ - if (character == '\0') - return false; - - if (m_sharedString->size == 0) - return true; - - return m_sharedString->string[0] < character; -} - -bool NzString::operator<(const char* string) const -{ - if (!string || !string[0]) - return false; - - if (m_sharedString->size == 0) - return true; - - return std::strcmp(GetConstBuffer(), string) < 0; -} - -bool NzString::operator<(const std::string& string) const -{ - if (string.empty()) - return false; - - if (m_sharedString->size == 0) - return true; - - return std::strcmp(GetConstBuffer(), string.c_str()) < 0; -} - -bool NzString::operator<=(char character) const -{ - if (m_sharedString->size == 0) - return true; - - if (character == '\0') - return false; - - return m_sharedString->string[0] < character || (m_sharedString->string[0] == character && m_sharedString->size == 1); -} - -bool NzString::operator<=(const char* string) const -{ - if (m_sharedString->size == 0) - return true; - - if (!string || !string[0]) - return false; - - return std::strcmp(GetConstBuffer(), string) <= 0; -} - -bool NzString::operator<=(const std::string& string) const -{ - if (m_sharedString->size == 0) - return true; - - if (string.empty()) - return false; - - return std::strcmp(GetConstBuffer(), string.c_str()) <= 0; -} - -bool NzString::operator>(char character) const -{ - if (m_sharedString->size == 0) - return false; - - if (character == '\0') - return true; - - return m_sharedString->string[0] > character; -} - -bool NzString::operator>(const char* string) const -{ - if (m_sharedString->size == 0) - return false; - - if (!string || !string[0]) - return true; - - return std::strcmp(GetConstBuffer(), string) > 0; -} - -bool NzString::operator>(const std::string& string) const -{ - if (m_sharedString->size == 0) - return false; - - if (string.empty()) - return true; - - return std::strcmp(GetConstBuffer(), string.c_str()) > 0; -} - -bool NzString::operator>=(char character) const -{ - if (character == '\0') - return true; - - if (m_sharedString->size == 0) - return false; - - return m_sharedString->string[0] > character || (m_sharedString->string[0] == character && m_sharedString->size == 1); -} - -bool NzString::operator>=(const char* string) const -{ - if (!string || !string[0]) - return true; - - if (m_sharedString->size == 0) - return false; - - return std::strcmp(GetConstBuffer(), string) >= 0; -} - -bool NzString::operator>=(const std::string& string) const -{ - if (string.empty()) - return true; - - if (m_sharedString->size == 0) - return false; - - return std::strcmp(GetConstBuffer(), string.c_str()) >= 0; -} - -NzString NzString::Boolean(bool boolean) -{ - unsigned int size = (boolean) ? 4 : 5; - - auto str = std::make_shared(size); - std::memcpy(str->string.get(), (boolean) ? "true" : "false", size); - - return NzString(std::move(str)); -} - -int NzString::Compare(const NzString& first, const NzString& second) -{ - if (first.m_sharedString->size == 0) - return (second.m_sharedString->size == 0) ? 0 : -1; - - if (second.m_sharedString->size == 0) - return 1; - - return std::strcmp(first.GetConstBuffer(), second.GetConstBuffer()); -} - -NzString NzString::Number(float number) -{ - std::ostringstream oss; - oss.precision(NAZARA_CORE_DECIMAL_DIGITS); - oss << number; - - return NzString(oss.str()); -} - -NzString NzString::Number(double number) -{ - std::ostringstream oss; - oss.precision(NAZARA_CORE_DECIMAL_DIGITS); - oss << number; - - return NzString(oss.str()); -} - -NzString NzString::Number(long double number) -{ - std::ostringstream oss; - oss.precision(NAZARA_CORE_DECIMAL_DIGITS); - oss << number; - - return NzString(oss.str()); -} - -NzString NzString::Number(signed char number, nzUInt8 radix) -{ - return NzNumberToString(number, radix); -} - -NzString NzString::Number(unsigned char number, nzUInt8 radix) -{ - return NzNumberToString(number, radix); -} - -NzString NzString::Number(short number, nzUInt8 radix) -{ - return NzNumberToString(number, radix); -} - -NzString NzString::Number(unsigned short number, nzUInt8 radix) -{ - return NzNumberToString(number, radix); -} - -NzString NzString::Number(int number, nzUInt8 radix) -{ - return NzNumberToString(number, radix); -} - -NzString NzString::Number(unsigned int number, nzUInt8 radix) -{ - return NzNumberToString(number, radix); -} - -NzString NzString::Number(long number, nzUInt8 radix) -{ - return NzNumberToString(number, radix); -} - -NzString NzString::Number(unsigned long number, nzUInt8 radix) -{ - return NzNumberToString(number, radix); -} - -NzString NzString::Number(long long number, nzUInt8 radix) -{ - return NzNumberToString(number, radix); -} - -NzString NzString::Number(unsigned long long number, nzUInt8 radix) -{ - return NzNumberToString(number, radix); -} - -NzString NzString::Pointer(const void* ptr) -{ - const unsigned int capacity = sizeof(void*)*2 + 2; - - auto str = std::make_shared(capacity); - str->size = std::sprintf(str->string.get(), "0x%p", ptr); - - return NzString(std::move(str)); -} - -NzString NzString::Unicode(char32_t character) -{ - if (character == '\0') - return NzString(); - - unsigned int count = 0; - if (character < 0x80) - count = 1; - else if (character < 0x800) - count = 2; - else if (character < 0x10000) - count = 3; - else - count = 4; - - auto str = std::make_shared(count); - utf8::append(character, str->string.get()); - - return NzString(std::move(str)); -} - -NzString NzString::Unicode(const char* u8String) -{ - return NzString(u8String); -} - -NzString NzString::Unicode(const char16_t* u16String) -{ - if (!u16String || !u16String[0]) - return NzString(); - - const char16_t* ptr = u16String; - unsigned int count = 0; - do - count++; - while (*++ptr); - - count *= 2; // On s'assure d'avoir la place suffisante - - auto str = std::make_shared(count); - - char* r = utf8::utf16to8(u16String, ptr, str->string.get()); - *r = '\0'; - - str->size = r - str->string.get(); - - return NzString(std::move(str)); -} - -NzString NzString::Unicode(const char32_t* u32String) -{ - if (!u32String || !u32String[0]) - return NzString(); - - const char32_t* ptr = u32String; - unsigned int count = 0; - do - { - char32_t cp = *ptr; - if (cp < 0x80) - count += 1; - else if (cp < 0x800) - count += 2; - else if (cp < 0x10000) - count += 3; - else - count += 4; - } - while (*++ptr); - - auto str = std::make_shared(count); - utf8::utf32to8(u32String, ptr, str->string.get()); - - return NzString(std::move(str)); -} - -NzString NzString::Unicode(const wchar_t* wString) -{ - if (!wString || !wString[0]) - return NzString(); - - const wchar_t* ptr = wString; - unsigned int count = 0; - do - { - char32_t cp = *ptr; - if (cp < 0x80) - count += 1; - else if (cp < 0x800) - count += 2; - else if (cp < 0x10000) - count += 3; - else - count += 4; - } - while (*++ptr); - - auto str = std::make_shared(count); - utf8::utf32to8(wString, ptr, str->string.get()); - - return NzString(std::move(str)); -} - -std::istream& operator>>(std::istream& is, NzString& str) -{ - str.Clear(); - - char c; - do - { - is.get(c); - if (c == '\0') - break; - else if (std::isspace(c)) - { - if (str.IsNull()) - continue; else - break; + startPos = 0; + + if ((flags & TrimOnlyLeft) == 0) + { + utf8::unchecked::iterator it(&m_sharedString->string[m_sharedString->size]); + while ((it--).base() != m_sharedString->string.get()) + { + if (Unicode::GetCategory(*it) & Unicode::Category_Separator) + break; + } + + endPos = it.base() - m_sharedString->string.get(); + } + else + endPos = m_sharedString->size-1; } else - str += c; + { + startPos = 0; + if ((flags & TrimOnlyRight) == 0) + { + for (; startPos < m_sharedString->size; ++startPos) + { + if (!std::isspace(m_sharedString->string[startPos])) + break; + } + } + + endPos = m_sharedString->size-1; + if ((flags & TrimOnlyLeft) == 0) + { + for (; endPos > 0; --endPos) + { + if (!std::isspace(m_sharedString->string[endPos])) + break; + } + } + } + + return SubString(startPos, endPos); } - while (true); - return is; -} - -std::ostream& operator<<(std::ostream& os, const NzString& str) -{ - if (str.IsEmpty()) - return os; - - return operator<<(os, str.m_sharedString->string.get()); -} - -NzString operator+(char character, const NzString& string) -{ - if (character == '\0') - return string; - - if (string.IsEmpty()) - return NzString(character); - - auto str = std::make_shared(string.m_sharedString->size + 1); - str->string[0] = character; - std::memcpy(&str->string[1], string.GetConstBuffer(), string.m_sharedString->size); - - return NzString(std::move(str)); -} - -NzString operator+(const char* string, const NzString& nstring) -{ - if (!string || !string[0]) - return nstring; - - if (nstring.IsEmpty()) - return string; - - unsigned int size = std::strlen(string); - unsigned int totalSize = size + nstring.m_sharedString->size; - - auto str = std::make_shared(totalSize); - std::memcpy(str->string.get(), string, size); - std::memcpy(&str->string[size], nstring.GetConstBuffer(), nstring.m_sharedString->size+1); - - return NzString(std::move(str)); -} - -NzString operator+(const std::string& string, const NzString& nstring) -{ - if (string.empty()) - return nstring; - - if (nstring.m_sharedString->size == 0) - return string; - - unsigned int totalSize = string.size() + nstring.m_sharedString->size; - - auto str = std::make_shared(totalSize); - std::memcpy(str->string.get(), string.c_str(), string.size()); - std::memcpy(&str->string[string.size()], nstring.GetConstBuffer(), nstring.m_sharedString->size+1); - - return NzString(std::move(str)); -} - -bool operator==(const NzString& first, const NzString& second) -{ - if (first.m_sharedString->size == 0 || second.m_sharedString->size == 0) - return first.m_sharedString->size == second.m_sharedString->size; - - if (first.m_sharedString->size != second.m_sharedString->size) - return false; - - if (first.m_sharedString == second.m_sharedString) - return true; - - return std::strcmp(first.GetConstBuffer(), second.GetConstBuffer()) == 0; -} - -bool operator!=(const NzString& first, const NzString& second) -{ - return !operator==(first, second); -} - -bool operator<(const NzString& first, const NzString& second) -{ - if (second.m_sharedString->size == 0) - return false; - - if (first.m_sharedString->size == 0) - return true; - - return std::strcmp(first.GetConstBuffer(), second.GetConstBuffer()) < 0; -} - -bool operator<=(const NzString& first, const NzString& second) -{ - return !operator<(second, first); -} - -bool operator>(const NzString& first, const NzString& second) -{ - return second < first; -} - -bool operator>=(const NzString& first, const NzString& second) -{ - return !operator<(first, second); -} - -bool operator==(char character, const NzString& nstring) -{ - return nstring == character; -} - -bool operator==(const char* string, const NzString& nstring) -{ - return nstring == string; -} - -bool operator==(const std::string& string, const NzString& nstring) -{ - return nstring == string; -} - -bool operator!=(char character, const NzString& nstring) -{ - return !operator==(character, nstring); -} - -bool operator!=(const char* string, const NzString& nstring) -{ - return !operator==(string, nstring); -} - -bool operator!=(const std::string& string, const NzString& nstring) -{ - return !operator==(string, nstring); -} - -bool operator<(char character, const NzString& nstring) -{ - return nstring > character; -} - -bool operator<(const char* string, const NzString& nstring) -{ - return nstring > string; -} - -bool operator<(const std::string& string, const NzString& nstring) -{ - return nstring > string; -} - -bool operator<=(char character, const NzString& nstring) -{ - return !operator<(nstring, NzString(character)); -} - -bool operator<=(const char* string, const NzString& nstring) -{ - return !operator<(nstring, string); -} - -bool operator<=(const std::string& string, const NzString& nstring) -{ - return !operator<(nstring, string); -} - -bool operator>(char character, const NzString& nstring) -{ - return nstring < character; -} - -bool operator>(const char* string, const NzString& nstring) -{ - return nstring < string; -} - -bool operator>(const std::string& string, const NzString& nstring) -{ - return nstring < string; -} - -bool operator>=(char character, const NzString& nstring) -{ - return !operator<(character, nstring); -} - -bool operator>=(const char* string, const NzString& nstring) -{ - return !operator<(string, nstring); -} - -bool operator>=(const std::string& string, const NzString& nstring) -{ - return !operator<(string, nstring); -} - -void NzString::EnsureOwnership(bool discardContent) -{ - if (!m_sharedString) - return; - - if (!m_sharedString.unique()) + String String::Trimmed(char character, UInt32 flags) const { - auto newSharedString = std::make_shared(GetSize()); - if (!discardContent) - std::memcpy(newSharedString->string.get(), GetConstBuffer(), GetSize()); + if (m_sharedString->size == 0) + return *this; - m_sharedString = std::move(newSharedString); + unsigned int startPos = 0; + unsigned int endPos = m_sharedString->size-1; + if (flags & CaseInsensitive) + { + char ch = Detail::ToLower(character); + if ((flags & TrimOnlyRight) == 0) + { + for (; startPos < m_sharedString->size; ++startPos) + { + if (Detail::ToLower(m_sharedString->string[startPos]) != ch) + break; + } + } + + if ((flags & TrimOnlyLeft) == 0) + { + for (; endPos > 0; --endPos) + { + if (Detail::ToLower(m_sharedString->string[endPos]) != ch) + break; + } + } + } + else + { + if ((flags & TrimOnlyRight) == 0) + { + for (; startPos < m_sharedString->size; ++startPos) + { + if (m_sharedString->string[startPos] != character) + break; + } + } + + if ((flags & TrimOnlyLeft) == 0) + { + for (; endPos > 0; --endPos) + { + if (m_sharedString->string[endPos] != character) + break; + } + } + } + + return SubString(startPos, endPos); } + + char* String::begin() + { + return m_sharedString->string.get(); + } + + const char* String::begin() const + { + return m_sharedString->string.get(); + } + + char* String::end() + { + return &m_sharedString->string[m_sharedString->size]; + } + + const char* String::end() const + { + return &m_sharedString->string[m_sharedString->size]; + } + + void String::push_front(char c) + { + Prepend(c); + } + + void String::push_back(char c) + { + Append(c); + } + /* + char* String::rbegin() + { + return &m_sharedString->string[m_sharedString->size-1]; + } + + const char* String::rbegin() const + { + return &m_sharedString->string[m_sharedString->size-1]; + } + + char* String::rend() + { + return &m_sharedString->string[-1]; + } + + const char* String::rend() const + { + return &m_sharedString->string[-1]; + } + */ + + String::operator std::string() const + { + return std::string(m_sharedString->string.get(), m_sharedString->size); + } + + char& String::operator[](unsigned int pos) + { + EnsureOwnership(); + + if (pos >= m_sharedString->size) + Resize(pos+1); + + return m_sharedString->string[pos]; + } + + char String::operator[](unsigned int pos) const + { + #if NAZARA_CORE_SAFE + if (pos >= m_sharedString->size) + { + NazaraError("Index out of range (" + Number(pos) + " >= " + Number(m_sharedString->size) + ')'); + return 0; + } + #endif + + return m_sharedString->string[pos]; + } + + String& String::operator=(char character) + { + return Set(character); + } + + String& String::operator=(const char* string) + { + return Set(string); + } + + String& String::operator=(const std::string& string) + { + return Set(string); + } + + String& String::operator=(const String& string) + { + return Set(string); + } + + String& String::operator=(String&& string) noexcept + { + return Set(string); + } + + String String::operator+(char character) const + { + if (character == '\0') + return *this; + + auto str = std::make_shared(m_sharedString->size + 1); + std::memcpy(str->string.get(), GetConstBuffer(), m_sharedString->size); + str->string[m_sharedString->size] = character; + + return String(std::move(str)); + } + + String String::operator+(const char* string) const + { + if (!string || !string[0]) + return *this; + + if (m_sharedString->size == 0) + return string; + + unsigned int length = std::strlen(string); + if (length == 0) + return *this; + + auto str = std::make_shared(m_sharedString->size + length); + std::memcpy(str->string.get(), GetConstBuffer(), m_sharedString->size); + std::memcpy(&str->string[m_sharedString->size], string, length+1); + + return String(std::move(str)); + } + + String String::operator+(const std::string& string) const + { + if (string.empty()) + return *this; + + if (m_sharedString->size == 0) + return string; + + auto str = std::make_shared(m_sharedString->size + string.size()); + std::memcpy(str->string.get(), GetConstBuffer(), m_sharedString->size); + std::memcpy(&str->string[m_sharedString->size], string.c_str(), string.size()+1); + + return String(std::move(str)); + } + + String String::operator+(const String& string) const + { + if (string.m_sharedString->size == 0) + return *this; + + if (m_sharedString->size == 0) + return string; + + auto str = std::make_shared(m_sharedString->size + string.m_sharedString->size); + std::memcpy(str->string.get(), GetConstBuffer(), m_sharedString->size); + std::memcpy(&str->string[m_sharedString->size], string.GetConstBuffer(), string.m_sharedString->size); + + return String(std::move(str)); + } + + String& String::operator+=(char character) + { + return Insert(m_sharedString->size, character); + } + + String& String::operator+=(const char* string) + { + return Insert(m_sharedString->size, string); + } + + String& String::operator+=(const std::string& string) + { + return Insert(m_sharedString->size, string.c_str(), string.size()); + } + + String& String::operator+=(const String& string) + { + return Insert(m_sharedString->size, string); + } + + bool String::operator==(char character) const + { + if (m_sharedString->size == 0) + return character == '\0'; + + if (m_sharedString->size > 1) + return false; + + return m_sharedString->string[0] == character; + } + + bool String::operator==(const char* string) const + { + if (m_sharedString->size == 0) + return !string || !string[0]; + + if (!string || !string[0]) + return false; + + return std::strcmp(GetConstBuffer(), string) == 0; + } + + bool String::operator==(const std::string& string) const + { + if (m_sharedString->size == 0 || string.empty()) + return m_sharedString->size == string.size(); + + if (m_sharedString->size != string.size()) + return false; + + return std::strcmp(GetConstBuffer(), string.c_str()) == 0; + } + + bool String::operator!=(char character) const + { + if (m_sharedString->size == 0) + return character != '\0'; + + if (character == '\0' || m_sharedString->size != 1) + return true; + + if (m_sharedString->size != 1) + return true; + + return m_sharedString->string[0] != character; + } + + bool String::operator!=(const char* string) const + { + if (m_sharedString->size == 0) + return string && string[0]; + + if (!string || !string[0]) + return true; + + return std::strcmp(GetConstBuffer(), string) != 0; + } + + bool String::operator!=(const std::string& string) const + { + if (m_sharedString->size == 0 || string.empty()) + return m_sharedString->size == string.size(); + + if (m_sharedString->size != string.size()) + return false; + + return std::strcmp(GetConstBuffer(), string.c_str()) != 0; + } + + bool String::operator<(char character) const + { + if (character == '\0') + return false; + + if (m_sharedString->size == 0) + return true; + + return m_sharedString->string[0] < character; + } + + bool String::operator<(const char* string) const + { + if (!string || !string[0]) + return false; + + if (m_sharedString->size == 0) + return true; + + return std::strcmp(GetConstBuffer(), string) < 0; + } + + bool String::operator<(const std::string& string) const + { + if (string.empty()) + return false; + + if (m_sharedString->size == 0) + return true; + + return std::strcmp(GetConstBuffer(), string.c_str()) < 0; + } + + bool String::operator<=(char character) const + { + if (m_sharedString->size == 0) + return true; + + if (character == '\0') + return false; + + return m_sharedString->string[0] < character || (m_sharedString->string[0] == character && m_sharedString->size == 1); + } + + bool String::operator<=(const char* string) const + { + if (m_sharedString->size == 0) + return true; + + if (!string || !string[0]) + return false; + + return std::strcmp(GetConstBuffer(), string) <= 0; + } + + bool String::operator<=(const std::string& string) const + { + if (m_sharedString->size == 0) + return true; + + if (string.empty()) + return false; + + return std::strcmp(GetConstBuffer(), string.c_str()) <= 0; + } + + bool String::operator>(char character) const + { + if (m_sharedString->size == 0) + return false; + + if (character == '\0') + return true; + + return m_sharedString->string[0] > character; + } + + bool String::operator>(const char* string) const + { + if (m_sharedString->size == 0) + return false; + + if (!string || !string[0]) + return true; + + return std::strcmp(GetConstBuffer(), string) > 0; + } + + bool String::operator>(const std::string& string) const + { + if (m_sharedString->size == 0) + return false; + + if (string.empty()) + return true; + + return std::strcmp(GetConstBuffer(), string.c_str()) > 0; + } + + bool String::operator>=(char character) const + { + if (character == '\0') + return true; + + if (m_sharedString->size == 0) + return false; + + return m_sharedString->string[0] > character || (m_sharedString->string[0] == character && m_sharedString->size == 1); + } + + bool String::operator>=(const char* string) const + { + if (!string || !string[0]) + return true; + + if (m_sharedString->size == 0) + return false; + + return std::strcmp(GetConstBuffer(), string) >= 0; + } + + bool String::operator>=(const std::string& string) const + { + if (string.empty()) + return true; + + if (m_sharedString->size == 0) + return false; + + return std::strcmp(GetConstBuffer(), string.c_str()) >= 0; + } + + String String::Boolean(bool boolean) + { + unsigned int size = (boolean) ? 4 : 5; + + auto str = std::make_shared(size); + std::memcpy(str->string.get(), (boolean) ? "true" : "false", size); + + return String(std::move(str)); + } + + int String::Compare(const String& first, const String& second) + { + if (first.m_sharedString->size == 0) + return (second.m_sharedString->size == 0) ? 0 : -1; + + if (second.m_sharedString->size == 0) + return 1; + + return std::strcmp(first.GetConstBuffer(), second.GetConstBuffer()); + } + + String String::Number(float number) + { + std::ostringstream oss; + oss.precision(NAZARA_CORE_DECIMAL_DIGITS); + oss << number; + + return String(oss.str()); + } + + String String::Number(double number) + { + std::ostringstream oss; + oss.precision(NAZARA_CORE_DECIMAL_DIGITS); + oss << number; + + return String(oss.str()); + } + + String String::Number(long double number) + { + std::ostringstream oss; + oss.precision(NAZARA_CORE_DECIMAL_DIGITS); + oss << number; + + return String(oss.str()); + } + + String String::Number(signed char number, UInt8 radix) + { + return NumberToString(number, radix); + } + + String String::Number(unsigned char number, UInt8 radix) + { + return NumberToString(number, radix); + } + + String String::Number(short number, UInt8 radix) + { + return NumberToString(number, radix); + } + + String String::Number(unsigned short number, UInt8 radix) + { + return NumberToString(number, radix); + } + + String String::Number(int number, UInt8 radix) + { + return NumberToString(number, radix); + } + + String String::Number(unsigned int number, UInt8 radix) + { + return NumberToString(number, radix); + } + + String String::Number(long number, UInt8 radix) + { + return NumberToString(number, radix); + } + + String String::Number(unsigned long number, UInt8 radix) + { + return NumberToString(number, radix); + } + + String String::Number(long long number, UInt8 radix) + { + return NumberToString(number, radix); + } + + String String::Number(unsigned long long number, UInt8 radix) + { + return NumberToString(number, radix); + } + + String String::Pointer(const void* ptr) + { + const unsigned int capacity = sizeof(void*)*2 + 2; + + auto str = std::make_shared(capacity); + str->size = std::sprintf(str->string.get(), "0x%p", ptr); + + return String(std::move(str)); + } + + String String::Unicode(char32_t character) + { + if (character == '\0') + return String(); + + unsigned int count = 0; + if (character < 0x80) + count = 1; + else if (character < 0x800) + count = 2; + else if (character < 0x10000) + count = 3; + else + count = 4; + + auto str = std::make_shared(count); + utf8::append(character, str->string.get()); + + return String(std::move(str)); + } + + String String::Unicode(const char* u8String) + { + return String(u8String); + } + + String String::Unicode(const char16_t* u16String) + { + if (!u16String || !u16String[0]) + return String(); + + const char16_t* ptr = u16String; + unsigned int count = 0; + do + count++; + while (*++ptr); + + count *= 2; // On s'assure d'avoir la place suffisante + + auto str = std::make_shared(count); + + char* r = utf8::utf16to8(u16String, ptr, str->string.get()); + *r = '\0'; + + str->size = r - str->string.get(); + + return String(std::move(str)); + } + + String String::Unicode(const char32_t* u32String) + { + if (!u32String || !u32String[0]) + return String(); + + const char32_t* ptr = u32String; + unsigned int count = 0; + do + { + char32_t cp = *ptr; + if (cp < 0x80) + count += 1; + else if (cp < 0x800) + count += 2; + else if (cp < 0x10000) + count += 3; + else + count += 4; + } + while (*++ptr); + + auto str = std::make_shared(count); + utf8::utf32to8(u32String, ptr, str->string.get()); + + return String(std::move(str)); + } + + String String::Unicode(const wchar_t* wString) + { + if (!wString || !wString[0]) + return String(); + + const wchar_t* ptr = wString; + unsigned int count = 0; + do + { + char32_t cp = *ptr; + if (cp < 0x80) + count += 1; + else if (cp < 0x800) + count += 2; + else if (cp < 0x10000) + count += 3; + else + count += 4; + } + while (*++ptr); + + auto str = std::make_shared(count); + utf8::utf32to8(wString, ptr, str->string.get()); + + return String(std::move(str)); + } + + std::istream& operator>>(std::istream& is, String& str) + { + str.Clear(); + + char c; + do + { + is.get(c); + if (c == '\0') + break; + else if (std::isspace(c)) + { + if (str.IsNull()) + continue; + else + break; + } + else + str += c; + } + while (true); + + return is; + } + + std::ostream& operator<<(std::ostream& os, const String& str) + { + if (str.IsEmpty()) + return os; + + return operator<<(os, str.m_sharedString->string.get()); + } + + String operator+(char character, const String& string) + { + if (character == '\0') + return string; + + if (string.IsEmpty()) + return String(character); + + auto str = std::make_shared(string.m_sharedString->size + 1); + str->string[0] = character; + std::memcpy(&str->string[1], string.GetConstBuffer(), string.m_sharedString->size); + + return String(std::move(str)); + } + + String operator+(const char* string, const String& nstring) + { + if (!string || !string[0]) + return nstring; + + if (nstring.IsEmpty()) + return string; + + unsigned int size = std::strlen(string); + unsigned int totalSize = size + nstring.m_sharedString->size; + + auto str = std::make_shared(totalSize); + std::memcpy(str->string.get(), string, size); + std::memcpy(&str->string[size], nstring.GetConstBuffer(), nstring.m_sharedString->size+1); + + return String(std::move(str)); + } + + String operator+(const std::string& string, const String& nstring) + { + if (string.empty()) + return nstring; + + if (nstring.m_sharedString->size == 0) + return string; + + unsigned int totalSize = string.size() + nstring.m_sharedString->size; + + auto str = std::make_shared(totalSize); + std::memcpy(str->string.get(), string.c_str(), string.size()); + std::memcpy(&str->string[string.size()], nstring.GetConstBuffer(), nstring.m_sharedString->size+1); + + return String(std::move(str)); + } + + bool operator==(const String& first, const String& second) + { + if (first.m_sharedString->size == 0 || second.m_sharedString->size == 0) + return first.m_sharedString->size == second.m_sharedString->size; + + if (first.m_sharedString->size != second.m_sharedString->size) + return false; + + if (first.m_sharedString == second.m_sharedString) + return true; + + return std::strcmp(first.GetConstBuffer(), second.GetConstBuffer()) == 0; + } + + bool operator!=(const String& first, const String& second) + { + return !operator==(first, second); + } + + bool operator<(const String& first, const String& second) + { + if (second.m_sharedString->size == 0) + return false; + + if (first.m_sharedString->size == 0) + return true; + + return std::strcmp(first.GetConstBuffer(), second.GetConstBuffer()) < 0; + } + + bool operator<=(const String& first, const String& second) + { + return !operator<(second, first); + } + + bool operator>(const String& first, const String& second) + { + return second < first; + } + + bool operator>=(const String& first, const String& second) + { + return !operator<(first, second); + } + + bool operator==(char character, const String& nstring) + { + return nstring == character; + } + + bool operator==(const char* string, const String& nstring) + { + return nstring == string; + } + + bool operator==(const std::string& string, const String& nstring) + { + return nstring == string; + } + + bool operator!=(char character, const String& nstring) + { + return !operator==(character, nstring); + } + + bool operator!=(const char* string, const String& nstring) + { + return !operator==(string, nstring); + } + + bool operator!=(const std::string& string, const String& nstring) + { + return !operator==(string, nstring); + } + + bool operator<(char character, const String& nstring) + { + return nstring > character; + } + + bool operator<(const char* string, const String& nstring) + { + return nstring > string; + } + + bool operator<(const std::string& string, const String& nstring) + { + return nstring > string; + } + + bool operator<=(char character, const String& nstring) + { + return !operator<(nstring, String(character)); + } + + bool operator<=(const char* string, const String& nstring) + { + return !operator<(nstring, string); + } + + bool operator<=(const std::string& string, const String& nstring) + { + return !operator<(nstring, string); + } + + bool operator>(char character, const String& nstring) + { + return nstring < character; + } + + bool operator>(const char* string, const String& nstring) + { + return nstring < string; + } + + bool operator>(const std::string& string, const String& nstring) + { + return nstring < string; + } + + bool operator>=(char character, const String& nstring) + { + return !operator<(character, nstring); + } + + bool operator>=(const char* string, const String& nstring) + { + return !operator<(string, nstring); + } + + bool operator>=(const std::string& string, const String& nstring) + { + return !operator<(string, nstring); + } + + void String::EnsureOwnership(bool discardContent) + { + if (!m_sharedString) + return; + + if (!m_sharedString.unique()) + { + auto newSharedString = std::make_shared(GetSize()); + if (!discardContent) + std::memcpy(newSharedString->string.get(), GetConstBuffer(), GetSize()); + + m_sharedString = std::move(newSharedString); + } + } + + bool String::FillHash(AbstractHash* hash) const + { + hash->Append(reinterpret_cast(GetConstBuffer()), GetSize()); + + return true; + } + + const std::shared_ptr& String::GetEmptyString() + { + static auto emptyString = std::make_shared(); + + return emptyString; + } + + const unsigned int String::npos(std::numeric_limits::max()); } -bool NzString::FillHash(NzAbstractHash* hash) const -{ - hash->Append(reinterpret_cast(GetConstBuffer()), GetSize()); - - return true; -} - -const std::shared_ptr& NzString::GetEmptyString() -{ - static auto emptyString = std::make_shared(); - - return emptyString; -} - -const unsigned int NzString::npos(std::numeric_limits::max()); - namespace std { - istream& getline(istream& is, NzString& str) + istream& getline(istream& is, Nz::String& str) { str.Clear(); @@ -4227,7 +4233,7 @@ namespace std return is; } - istream& getline(istream& is, NzString& str, char delim) + istream& getline(istream& is, Nz::String& str, char delim) { str.Clear(); @@ -4245,7 +4251,7 @@ namespace std return is; } - void swap(NzString& lhs, NzString& rhs) + void swap(Nz::String& lhs, Nz::String& rhs) { lhs.Swap(rhs); } diff --git a/src/Nazara/Core/StringStream.cpp b/src/Nazara/Core/StringStream.cpp index 0871ec871..2c2a8db24 100644 --- a/src/Nazara/Core/StringStream.cpp +++ b/src/Nazara/Core/StringStream.cpp @@ -5,173 +5,176 @@ #include #include -NzStringStream::NzStringStream() : -m_bufferSize(0) +namespace Nz { -} - -NzStringStream::NzStringStream(const NzString& str) : -m_bufferSize(str.GetSize()) -{ - m_strings.push_back(str); -} - -NzString NzStringStream::ToString() const -{ - NzString string; - string.Reserve(m_bufferSize); - - for (const NzString& str : m_strings) - string += str; - - return string; -} - -NzStringStream& NzStringStream::operator<<(bool boolean) -{ - m_strings.push_back(NzString::Boolean(boolean)); - m_bufferSize += m_strings.back().GetSize(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(short number) -{ - m_strings.push_back(NzString::Number(number)); - m_bufferSize += m_strings.back().GetSize(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(unsigned short number) -{ - m_strings.push_back(NzString::Number(number)); - m_bufferSize += m_strings.back().GetSize(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(int number) -{ - m_strings.push_back(NzString::Number(number)); - m_bufferSize += m_strings.back().GetSize(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(unsigned int number) -{ - m_strings.push_back(NzString::Number(number)); - m_bufferSize += m_strings.back().GetSize(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(long number) -{ - m_strings.push_back(NzString::Number(number)); - m_bufferSize += m_strings.back().GetSize(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(unsigned long number) -{ - m_strings.push_back(NzString::Number(number)); - m_bufferSize += m_strings.back().GetSize(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(long long number) -{ - m_strings.push_back(NzString::Number(number)); - m_bufferSize += m_strings.back().GetSize(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(unsigned long long number) -{ - m_strings.push_back(NzString::Number(number)); - m_bufferSize += m_strings.back().GetSize(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(float number) -{ - m_strings.push_back(NzString::Number(number)); - m_bufferSize += m_strings.back().GetSize(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(double number) -{ - m_strings.push_back(NzString::Number(number)); - m_bufferSize += m_strings.back().GetSize(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(long double number) -{ - m_strings.push_back(NzString::Number(number)); - m_bufferSize += m_strings.back().GetSize(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(char character) -{ - m_strings.push_back(NzString(character)); - m_bufferSize++; - - return *this; -} - -NzStringStream& NzStringStream::operator<<(unsigned char character) -{ - m_strings.push_back(NzString(static_cast(character))); - m_bufferSize++; - - return *this; -} - -NzStringStream& NzStringStream::operator<<(const char* string) -{ - m_strings.push_back(string); - m_bufferSize += m_strings.back().GetSize(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(const std::string& string) -{ - m_strings.push_back(string); - m_bufferSize += string.size(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(const NzString& string) -{ - m_strings.push_back(string); - m_bufferSize += string.GetSize(); - - return *this; -} - -NzStringStream& NzStringStream::operator<<(const void* ptr) -{ - m_strings.push_back(NzString::Pointer(ptr)); - m_bufferSize += m_strings.back().GetSize(); - - return *this; -} - -NzStringStream::operator NzString() const -{ - return ToString(); + StringStream::StringStream() : + m_bufferSize(0) + { + } + + StringStream::StringStream(const String& str) : + m_bufferSize(str.GetSize()) + { + m_strings.push_back(str); + } + + String StringStream::ToString() const + { + String string; + string.Reserve(m_bufferSize); + + for (const String& str : m_strings) + string += str; + + return string; + } + + StringStream& StringStream::operator<<(bool boolean) + { + m_strings.push_back(String::Boolean(boolean)); + m_bufferSize += m_strings.back().GetSize(); + + return *this; + } + + StringStream& StringStream::operator<<(short number) + { + m_strings.push_back(String::Number(number)); + m_bufferSize += m_strings.back().GetSize(); + + return *this; + } + + StringStream& StringStream::operator<<(unsigned short number) + { + m_strings.push_back(String::Number(number)); + m_bufferSize += m_strings.back().GetSize(); + + return *this; + } + + StringStream& StringStream::operator<<(int number) + { + m_strings.push_back(String::Number(number)); + m_bufferSize += m_strings.back().GetSize(); + + return *this; + } + + StringStream& StringStream::operator<<(unsigned int number) + { + m_strings.push_back(String::Number(number)); + m_bufferSize += m_strings.back().GetSize(); + + return *this; + } + + StringStream& StringStream::operator<<(long number) + { + m_strings.push_back(String::Number(number)); + m_bufferSize += m_strings.back().GetSize(); + + return *this; + } + + StringStream& StringStream::operator<<(unsigned long number) + { + m_strings.push_back(String::Number(number)); + m_bufferSize += m_strings.back().GetSize(); + + return *this; + } + + StringStream& StringStream::operator<<(long long number) + { + m_strings.push_back(String::Number(number)); + m_bufferSize += m_strings.back().GetSize(); + + return *this; + } + + StringStream& StringStream::operator<<(unsigned long long number) + { + m_strings.push_back(String::Number(number)); + m_bufferSize += m_strings.back().GetSize(); + + return *this; + } + + StringStream& StringStream::operator<<(float number) + { + m_strings.push_back(String::Number(number)); + m_bufferSize += m_strings.back().GetSize(); + + return *this; + } + + StringStream& StringStream::operator<<(double number) + { + m_strings.push_back(String::Number(number)); + m_bufferSize += m_strings.back().GetSize(); + + return *this; + } + + StringStream& StringStream::operator<<(long double number) + { + m_strings.push_back(String::Number(number)); + m_bufferSize += m_strings.back().GetSize(); + + return *this; + } + + StringStream& StringStream::operator<<(char character) + { + m_strings.push_back(String(character)); + m_bufferSize++; + + return *this; + } + + StringStream& StringStream::operator<<(unsigned char character) + { + m_strings.push_back(String(static_cast(character))); + m_bufferSize++; + + return *this; + } + + StringStream& StringStream::operator<<(const char* string) + { + m_strings.push_back(string); + m_bufferSize += m_strings.back().GetSize(); + + return *this; + } + + StringStream& StringStream::operator<<(const std::string& string) + { + m_strings.push_back(string); + m_bufferSize += string.size(); + + return *this; + } + + StringStream& StringStream::operator<<(const String& string) + { + m_strings.push_back(string); + m_bufferSize += string.GetSize(); + + return *this; + } + + StringStream& StringStream::operator<<(const void* ptr) + { + m_strings.push_back(String::Pointer(ptr)); + m_bufferSize += m_strings.back().GetSize(); + + return *this; + } + + StringStream::operator String() const + { + return ToString(); + } } diff --git a/src/Nazara/Core/TaskScheduler.cpp b/src/Nazara/Core/TaskScheduler.cpp index 4e328045e..27d071987 100644 --- a/src/Nazara/Core/TaskScheduler.cpp +++ b/src/Nazara/Core/TaskScheduler.cpp @@ -16,74 +16,77 @@ #include -namespace +namespace Nz { - std::vector s_pendingWorks; - unsigned int s_workerCount = 0; -} - -unsigned int NzTaskScheduler::GetWorkerCount() -{ - return (s_workerCount > 0) ? s_workerCount : NzHardwareInfo::GetProcessorCount(); -} - -bool NzTaskScheduler::Initialize() -{ - return NzTaskSchedulerImpl::Initialize(GetWorkerCount()); -} - -void NzTaskScheduler::Run() -{ - if (!Initialize()) + namespace { - NazaraError("Failed to initialize Task Scheduler"); - return; + std::vector s_pendingWorks; + unsigned int s_workerCount = 0; } - if (!s_pendingWorks.empty()) + unsigned int TaskScheduler::GetWorkerCount() { - NzTaskSchedulerImpl::Run(&s_pendingWorks[0], s_pendingWorks.size()); - s_pendingWorks.clear(); - } -} - -void NzTaskScheduler::SetWorkerCount(unsigned int workerCount) -{ - #ifdef NAZARA_CORE_SAFE - if (NzTaskSchedulerImpl::IsInitialized()) - { - NazaraError("Worker count cannot be set while initialized"); - return; - } - #endif - - s_workerCount = workerCount; -} - -void NzTaskScheduler::Uninitialize() -{ - if (NzTaskSchedulerImpl::IsInitialized()) - NzTaskSchedulerImpl::Uninitialize(); -} - -void NzTaskScheduler::WaitForTasks() -{ - if (!Initialize()) - { - NazaraError("Failed to initialize Task Scheduler"); - return; + return (s_workerCount > 0) ? s_workerCount : HardwareInfo::GetProcessorCount(); } - NzTaskSchedulerImpl::WaitForTasks(); -} - -void NzTaskScheduler::AddTaskFunctor(NzFunctor* taskFunctor) -{ - if (!Initialize()) + bool TaskScheduler::Initialize() { - NazaraError("Failed to initialize Task Scheduler"); - return; + return TaskSchedulerImpl::Initialize(GetWorkerCount()); } - s_pendingWorks.push_back(taskFunctor); + void TaskScheduler::Run() + { + if (!Initialize()) + { + NazaraError("Failed to initialize Task Scheduler"); + return; + } + + if (!s_pendingWorks.empty()) + { + TaskSchedulerImpl::Run(&s_pendingWorks[0], s_pendingWorks.size()); + s_pendingWorks.clear(); + } + } + + void TaskScheduler::SetWorkerCount(unsigned int workerCount) + { + #ifdef NAZARA_CORE_SAFE + if (TaskSchedulerImpl::IsInitialized()) + { + NazaraError("Worker count cannot be set while initialized"); + return; + } + #endif + + s_workerCount = workerCount; + } + + void TaskScheduler::Uninitialize() + { + if (TaskSchedulerImpl::IsInitialized()) + TaskSchedulerImpl::Uninitialize(); + } + + void TaskScheduler::WaitForTasks() + { + if (!Initialize()) + { + NazaraError("Failed to initialize Task Scheduler"); + return; + } + + TaskSchedulerImpl::WaitForTasks(); + } + + void TaskScheduler::AddTaskFunctor(Functor* taskFunctor) + { + if (!Initialize()) + { + NazaraError("Failed to initialize Task Scheduler"); + return; + } + + s_pendingWorks.push_back(taskFunctor); + } } diff --git a/src/Nazara/Core/Thread.cpp b/src/Nazara/Core/Thread.cpp index a31025d68..105067baf 100644 --- a/src/Nazara/Core/Thread.cpp +++ b/src/Nazara/Core/Thread.cpp @@ -19,130 +19,133 @@ #include -NzThread::NzThread() : -m_impl(nullptr) +namespace Nz { -} - -NzThread::NzThread(NzThread&& other) noexcept : -m_impl(other.m_impl) -{ - other.m_impl = nullptr; -} - -NzThread::~NzThread() -{ - if (m_impl) + Thread::Thread() : + m_impl(nullptr) { + } + + Thread::Thread(Thread&& other) noexcept : + m_impl(other.m_impl) + { + other.m_impl = nullptr; + } + + Thread::~Thread() + { + if (m_impl) + { + m_impl->Join(); + delete m_impl; + m_impl = nullptr; + } + } + + void Thread::Detach() + { + if (m_impl) + { + m_impl->Detach(); + delete m_impl; + m_impl = nullptr; + } + } + + Thread::Id Thread::GetId() const + { + return Thread::Id(m_impl); + } + + bool Thread::IsJoinable() const + { + return m_impl != nullptr; + } + + void Thread::Join() + { + #if NAZARA_CORE_SAFE + if (!m_impl) + { + NazaraError("This thread is not joinable"); + return; + } + #endif + m_impl->Join(); delete m_impl; m_impl = nullptr; } -} -void NzThread::Detach() -{ - if (m_impl) + Thread& Thread::operator=(Thread&& thread) { - m_impl->Detach(); - delete m_impl; - m_impl = nullptr; + #if NAZARA_CORE_SAFE + if (m_impl) + { + NazaraError("This thread cannot be joined"); + std::terminate(); + } + #endif + + std::swap(m_impl, thread.m_impl); + return *this; + } + + unsigned int Thread::HardwareConcurrency() + { + return HardwareInfo::GetProcessorCount(); + } + + void Thread::Sleep(UInt32 milliseconds) + { + ThreadImpl::Sleep(milliseconds); + } + + void Thread::CreateImpl(Functor* functor) + { + m_impl = new ThreadImpl(functor); + } + + /*********************************Thread::Id********************************/ + + Thread::Id::Id(ThreadImpl* thread) : + m_id(thread) + { + } + + bool operator==(const Thread::Id& lhs, const Thread::Id& rhs) + { + return lhs.m_id == rhs.m_id; + } + + bool operator!=(const Thread::Id& lhs, const Thread::Id& rhs) + { + return lhs.m_id != rhs.m_id; + } + + bool operator<(const Thread::Id& lhs, const Thread::Id& rhs) + { + return lhs.m_id < rhs.m_id; + } + + bool operator<=(const Thread::Id& lhs, const Thread::Id& rhs) + { + return lhs.m_id <= rhs.m_id; + } + + bool operator>(const Thread::Id& lhs, const Thread::Id& rhs) + { + return lhs.m_id > rhs.m_id; + } + + bool operator>=(const Thread::Id& lhs, const Thread::Id& rhs) + { + return lhs.m_id >= rhs.m_id; + } + + std::ostream& operator<<(std::ostream& o, const Nz::Thread::Id& id) + { + o << id.m_id; + return o; } } - -NzThread::Id NzThread::GetId() const -{ - return NzThread::Id(m_impl); -} - -bool NzThread::IsJoinable() const -{ - return m_impl != nullptr; -} - -void NzThread::Join() -{ - #if NAZARA_CORE_SAFE - if (!m_impl) - { - NazaraError("This thread is not joinable"); - return; - } - #endif - - m_impl->Join(); - delete m_impl; - m_impl = nullptr; -} - -NzThread& NzThread::operator=(NzThread&& thread) -{ - #if NAZARA_CORE_SAFE - if (m_impl) - { - NazaraError("This thread cannot be joined"); - std::terminate(); - } - #endif - - std::swap(m_impl, thread.m_impl); - return *this; -} - -unsigned int NzThread::HardwareConcurrency() -{ - return NzHardwareInfo::GetProcessorCount(); -} - -void NzThread::Sleep(nzUInt32 milliseconds) -{ - NzThreadImpl::Sleep(milliseconds); -} - -void NzThread::CreateImpl(NzFunctor* functor) -{ - m_impl = new NzThreadImpl(functor); -} - -/*********************************NzThread::Id********************************/ - -bool operator==(const NzThread::Id& lhs, const NzThread::Id& rhs) -{ - return lhs.m_id == rhs.m_id; -} - -bool operator!=(const NzThread::Id& lhs, const NzThread::Id& rhs) -{ - return lhs.m_id != rhs.m_id; -} - -bool operator<(const NzThread::Id& lhs, const NzThread::Id& rhs) -{ - return lhs.m_id < rhs.m_id; -} - -bool operator<=(const NzThread::Id& lhs, const NzThread::Id& rhs) -{ - return lhs.m_id <= rhs.m_id; -} - -bool operator>(const NzThread::Id& lhs, const NzThread::Id& rhs) -{ - return lhs.m_id > rhs.m_id; -} - -bool operator>=(const NzThread::Id& lhs, const NzThread::Id& rhs) -{ - return lhs.m_id >= rhs.m_id; -} - -std::ostream& operator<<(std::ostream& o, const NzThread::Id& id) -{ - o << id.m_id; - return o; -} - -NzThread::Id::Id(NzThreadImpl* thread) : -m_id(thread) -{ -} diff --git a/src/Nazara/Core/Unicode.cpp b/src/Nazara/Core/Unicode.cpp index 25b54c20c..c5b0d6917 100644 --- a/src/Nazara/Core/Unicode.cpp +++ b/src/Nazara/Core/Unicode.cpp @@ -7,359 +7,366 @@ #include #if NAZARA_CORE_INCLUDE_UNICODEDATA -struct Character +namespace Nz { - nzUInt16 category; // Le type du caractère - nzUInt8 direction; // Le sens de lecure du caractère - nzUInt32 lowerCase; // Le caractère correspondant en minuscule - nzUInt32 titleCase; // Le caractère correspondant en titre - nzUInt32 upperCase; // Le caractère correspondant en majuscule -}; + struct Character + { + UInt16 category; // Le type du caractère + UInt8 direction; // Le sens de lecure du caractère + UInt32 lowerCase; // Le caractère correspondant en minuscule + UInt32 titleCase; // Le caractère correspondant en titre + UInt32 upperCase; // Le caractère correspondant en majuscule + }; +} #include #else // Implémentation supportant la table ASCII -NzUnicode::Category NzUnicode::GetCategory(char32_t character) +namespace Nz { - switch (character) + Unicode::Category Unicode::GetCategory(char32_t character) { - case '\x00': - case '\x01': - case '\x02': - case '\x03': - case '\x04': - case '\x05': - case '\x06': - case '\x07': - case '\x08': - case '\x09': - case '\x0A': - case '\x0B': - case '\x0C': - case '\x0D': - case '\x0E': - case '\x0F': - case '\x10': - case '\x11': - case '\x12': - case '\x13': - case '\x14': - case '\x15': - case '\x16': - case '\x17': - case '\x18': - case '\x19': - case '\x1A': - case '\x1B': - case '\x1C': - case '\x1D': - case '\x1E': - case '\x1F': - case '\x7F': - return Category_Other_Control; + switch (character) + { + case '\x00': + case '\x01': + case '\x02': + case '\x03': + case '\x04': + case '\x05': + case '\x06': + case '\x07': + case '\x08': + case '\x09': + case '\x0A': + case '\x0B': + case '\x0C': + case '\x0D': + case '\x0E': + case '\x0F': + case '\x10': + case '\x11': + case '\x12': + case '\x13': + case '\x14': + case '\x15': + case '\x16': + case '\x17': + case '\x18': + case '\x19': + case '\x1A': + case '\x1B': + case '\x1C': + case '\x1D': + case '\x1E': + case '\x1F': + case '\x7F': + return Category_Other_Control; - case ' ': - return Category_Separator_Space; + case ' ': + return Category_Separator_Space; - case '!': - case '"': - case '#': - case '$': - case '%': - case '&': - case '\'': - case '*': - case ',': - case '.': - case '/': - case ':': - case ';': - case '?': - case '@': - case '\\': - return Category_Punctuation_Other; + case '!': + case '"': + case '#': + case '$': + case '%': + case '&': + case '\'': + case '*': + case ',': + case '.': + case '/': + case ':': + case ';': + case '?': + case '@': + case '\\': + return Category_Punctuation_Other; - case '(': - case '[': - case '{': - return Category_Punctuation_Open; + case '(': + case '[': + case '{': + return Category_Punctuation_Open; - case ')': - case '}': - case ']': - return Category_Punctuation_Close; + case ')': + case '}': + case ']': + return Category_Punctuation_Close; - case '+': - case '<': - case '=': - case '>': - case '|': - case '~': - return Category_Symbol_Math; + case '+': + case '<': + case '=': + case '>': + case '|': + case '~': + return Category_Symbol_Math; - case '-': - return Category_Punctuation_Dash; + case '-': + return Category_Punctuation_Dash; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return Category_Number_DecimalDigit; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return Category_Number_DecimalDigit; - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - case 'G': - case 'H': - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - case 'Q': - case 'R': - case 'S': - case 'T': - case 'U': - case 'V': - case 'W': - case 'X': - case 'Y': - case 'Z': - return Category_Number_DecimalDigit; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + return Category_Number_DecimalDigit; - case '_': - return Category_Punctuation_Connector; + case '_': + return Category_Punctuation_Connector; - case '^': - case '`': - return Category_Symbol_Modifier; + case '^': + case '`': + return Category_Symbol_Modifier; - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - case 'g': - case 'h': - case 'i': - case 'j': - case 'k': - case 'l': - case 'm': - case 'n': - case 'o': - case 'p': - case 'q': - case 'r': - case 's': - case 't': - case 'u': - case 'v': - case 'w': - case 'x': - case 'y': - case 'z': - return Category_Number_DecimalDigit; + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + return Category_Number_DecimalDigit; - default: - break; + default: + break; + } + + return Category_NoCategory; } - return Category_NoCategory; -} - -NzUnicode::Direction NzUnicode::GetDirection(char32_t character) -{ - switch (character) + Unicode::Direction Unicode::GetDirection(char32_t character) { - case '\x00': - case '\x01': - case '\x02': - case '\x03': - case '\x04': - case '\x05': - case '\x06': - case '\x07': - case '\x08': - case '\x0E': - case '\x0F': - case '\x10': - case '\x11': - case '\x12': - case '\x13': - case '\x14': - case '\x15': - case '\x16': - case '\x17': - case '\x18': - case '\x19': - case '\x1A': - case '\x1B': - case '\x7F': - return Direction_Boundary_Neutral; + switch (character) + { + case '\x00': + case '\x01': + case '\x02': + case '\x03': + case '\x04': + case '\x05': + case '\x06': + case '\x07': + case '\x08': + case '\x0E': + case '\x0F': + case '\x10': + case '\x11': + case '\x12': + case '\x13': + case '\x14': + case '\x15': + case '\x16': + case '\x17': + case '\x18': + case '\x19': + case '\x1A': + case '\x1B': + case '\x7F': + return Direction_Boundary_Neutral; - case '\x09': - case '\x0B': - case '\x1F': - return Direction_Segment_Separator; + case '\x09': + case '\x0B': + case '\x1F': + return Direction_Segment_Separator; - case '\x0A': - case '\x0D': - case '\x1C': - case '\x1D': - case '\x1E': - return Direction_Paragraph_Separator; + case '\x0A': + case '\x0D': + case '\x1C': + case '\x1D': + case '\x1E': + return Direction_Paragraph_Separator; - case '\x0C': - case ' ': - return Direction_White_Space; + case '\x0C': + case ' ': + return Direction_White_Space; - case '!': - case '"': - case '&': - case '\'': - case '(': - case ')': - case '*': - case ';': - case '<': - case '=': - case '>': - case '?': - case '@': - case '[': - case '\\': - case ']': - case '^': - case '_': - case '`': - case '{': - case '|': - case '}': - case '~': - return Direction_Other_Neutral; + case '!': + case '"': + case '&': + case '\'': + case '(': + case ')': + case '*': + case ';': + case '<': + case '=': + case '>': + case '?': + case '@': + case '[': + case '\\': + case ']': + case '^': + case '_': + case '`': + case '{': + case '|': + case '}': + case '~': + return Direction_Other_Neutral; - case '#': - case '$': - case '%': - return Direction_European_Terminator; + case '#': + case '$': + case '%': + return Direction_European_Terminator; - case '+': - case '-': - return Direction_European_Separator; + case '+': + case '-': + return Direction_European_Separator; - case ',': - case '.': - case '/': - case ':': - return Direction_Common_Separator; + case ',': + case '.': + case '/': + case ':': + return Direction_Common_Separator; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - return Direction_European_Number; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + return Direction_European_Number; - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - case 'G': - case 'H': - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'O': - case 'P': - case 'Q': - case 'R': - case 'S': - case 'T': - case 'U': - case 'V': - case 'W': - case 'X': - case 'Y': - case 'Z': - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - case 'g': - case 'h': - case 'i': - case 'j': - case 'k': - case 'l': - case 'm': - case 'n': - case 'o': - case 'p': - case 'q': - case 'r': - case 's': - case 't': - case 'u': - case 'v': - case 'w': - case 'x': - case 'y': - case 'z': - return Direction_Left_To_Right; + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + case 'G': + case 'H': + case 'I': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'O': + case 'P': + case 'Q': + case 'R': + case 'S': + case 'T': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'p': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': + return Direction_Left_To_Right; - default: - break; + default: + break; + } + + return Direction_Boundary_Neutral; } - return Direction_Boundary_Neutral; + char32_t Unicode::GetLowercase(char32_t character) + { + if (character >= 'A' && character <= 'Z') + return character + ('a' - 'A'); + else + return character; + } + + char32_t Unicode::GetTitlecase(char32_t character) + { + return GetUppercase(character); + } + + char32_t Unicode::GetUppercase(char32_t character) + { + if (character >= 'a' && character <= 'z') + return character + ('A' - 'a'); + else + return character; + } } -char32_t NzUnicode::GetLowercase(char32_t character) -{ - if (character >= 'A' && character <= 'Z') - return character + ('a' - 'A'); - else - return character; -} - -char32_t NzUnicode::GetTitlecase(char32_t character) -{ - return GetUppercase(character); -} - -char32_t NzUnicode::GetUppercase(char32_t character) -{ - if (character >= 'a' && character <= 'z') - return character + ('A' - 'a'); - else - return character; -} #endif diff --git a/src/Nazara/Core/Updatable.cpp b/src/Nazara/Core/Updatable.cpp index 79495dcbc..3699b10a6 100644 --- a/src/Nazara/Core/Updatable.cpp +++ b/src/Nazara/Core/Updatable.cpp @@ -5,4 +5,7 @@ #include #include -NzUpdatable::~NzUpdatable() = default; +namespace Nz +{ + Updatable::~Updatable() = default; +} diff --git a/src/Nazara/Core/Win32/ClockImpl.cpp b/src/Nazara/Core/Win32/ClockImpl.cpp index 334b977db..311688d29 100644 --- a/src/Nazara/Core/Win32/ClockImpl.cpp +++ b/src/Nazara/Core/Win32/ClockImpl.cpp @@ -8,35 +8,38 @@ #include #include -namespace +namespace Nz { - LARGE_INTEGER frequency; // La fréquence ne varie pas pas au cours de l'exécution -} - -bool NzClockImplInitializeHighPrecision() -{ - return QueryPerformanceFrequency(&frequency) != 0; -} - -nzUInt64 NzClockImplGetMicroseconds() -{ - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx - //HANDLE thread = GetCurrentThread(); - //DWORD oldMask = SetThreadAffinityMask(thread, 1); - - LARGE_INTEGER time; - QueryPerformanceCounter(&time); - - //SetThreadAffinityMask(thread, oldMask); - - return time.QuadPart*1000000ULL / frequency.QuadPart; -} - -nzUInt64 NzClockImplGetMilliseconds() -{ - #ifdef NAZARA_PLATFORM_WINDOWS_VISTA - return GetTickCount64(); - #else - return GetTickCount(); - #endif + namespace + { + LARGE_INTEGER s_frequency; // La fréquence ne varie pas pas au cours de l'exécution + } + + bool ClockImplInitializeHighPrecision() + { + return QueryPerformanceFrequency(&s_frequency) != 0; + } + + UInt64 ClockImplGetElapsedMicroseconds() + { + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx + //HANDLE thread = GetCurrentThread(); + //DWORD oldMask = SetThreadAffinityMask(thread, 1); + + LARGE_INTEGER time; + QueryPerformanceCounter(&time); + + //SetThreadAffinityMask(thread, oldMask); + + return time.QuadPart*1000000ULL / s_frequency.QuadPart; + } + + UInt64 ClockImplGetElapsedMilliseconds() + { + #ifdef NAZARA_PLATFORM_WINDOWS_VISTA + return GetTickCount64(); + #else + return GetTickCount(); + #endif + } } diff --git a/src/Nazara/Core/Win32/ClockImpl.hpp b/src/Nazara/Core/Win32/ClockImpl.hpp index c73eb5dcf..f1bcf8aaa 100644 --- a/src/Nazara/Core/Win32/ClockImpl.hpp +++ b/src/Nazara/Core/Win32/ClockImpl.hpp @@ -9,8 +9,11 @@ #include -bool NzClockImplInitializeHighPrecision(); -nzUInt64 NzClockImplGetMicroseconds(); -nzUInt64 NzClockImplGetMilliseconds(); +namespace Nz +{ + bool ClockImplInitializeHighPrecision(); + UInt64 ClockImplGetElapsedMicroseconds(); + UInt64 ClockImplGetElapsedMilliseconds(); +} #endif // NAZARA_CLOCKIMPL_WINDOWS_HPP diff --git a/src/Nazara/Core/Win32/ConditionVariableImpl.cpp b/src/Nazara/Core/Win32/ConditionVariableImpl.cpp index 0e1d30539..388a7f587 100644 --- a/src/Nazara/Core/Win32/ConditionVariableImpl.cpp +++ b/src/Nazara/Core/Win32/ConditionVariableImpl.cpp @@ -8,73 +8,77 @@ #include #include -NzConditionVariableImpl::NzConditionVariableImpl() +namespace Nz { - #if NAZARA_CORE_WINDOWS_VISTA - InitializeConditionVariable(&m_cv); - #else - m_count = 0; - m_events[BROADCAST] = CreateEvent(nullptr, true, false, nullptr); // manual-reset event - m_events[SIGNAL] = CreateEvent(nullptr, false, false, nullptr); // auto-reset event - #endif -} - -#if !NAZARA_CORE_WINDOWS_VISTA -NzConditionVariableImpl::~NzConditionVariableImpl() -{ - CloseHandle(m_events[BROADCAST]); - CloseHandle(m_events[SIGNAL]); -} -#endif - -void NzConditionVariableImpl::Signal() -{ - #if NAZARA_CORE_WINDOWS_VISTA - WakeConditionVariable(&m_cv); - #else - if (m_count > 0) - SetEvent(m_events[SIGNAL]); - #endif -} - -void NzConditionVariableImpl::SignalAll() -{ - #if NAZARA_CORE_WINDOWS_VISTA - WakeAllConditionVariable(&m_cv); - #else - if (m_count > 0) - SetEvent(m_events[BROADCAST]); - #endif -} - -void NzConditionVariableImpl::Wait(NzMutexImpl* mutex) -{ - Wait(mutex, INFINITE); -} - -bool NzConditionVariableImpl::Wait(NzMutexImpl* mutex, nzUInt32 timeout) -{ - #if NAZARA_CORE_WINDOWS_VISTA - return SleepConditionVariableCS(&m_cv, &mutex->m_criticalSection, timeout); - #else - m_count++; - - // It's ok to release the mutex here since Win32 - // manual-reset events maintain state when used with SetEvent. - // This avoids the "lost wakeup" bug... - LeaveCriticalSection(&mutex->m_criticalSection); - - // Wait for either event to become signaled due to Signal being called or SignalAll being called. - int result = WaitForMultipleObjects(2, m_events, false, timeout); - - // Some thread called SignalAll - if (--m_count == 0 && result == WAIT_OBJECT_0 + BROADCAST) - // We're the last waiter to be notified or to stop waiting, so reset the manual event. - ResetEvent(m_events[BROADCAST]); - - // Reacquire the mutex. - EnterCriticalSection(&mutex->m_criticalSection); - - return result != WAIT_TIMEOUT; + ConditionVariableImpl::ConditionVariableImpl() + { + #if NAZARA_CORE_WINDOWS_VISTA + InitializeConditionVariable(&m_cv); + #else + m_count = 0; + m_events[BROADCAST] = CreateEvent(nullptr, true, false, nullptr); // manual-reset event + m_events[SIGNAL] = CreateEvent(nullptr, false, false, nullptr); // auto-reset event + #endif + } + + #if !NAZARA_CORE_WINDOWS_VISTA + ConditionVariableImpl::~ConditionVariableImpl() + { + CloseHandle(m_events[BROADCAST]); + CloseHandle(m_events[SIGNAL]); + } #endif + + void ConditionVariableImpl::Signal() + { + #if NAZARA_CORE_WINDOWS_VISTA + WakeConditionVariable(&m_cv); + #else + if (m_count > 0) + SetEvent(m_events[SIGNAL]); + #endif + } + + void ConditionVariableImpl::SignalAll() + { + #if NAZARA_CORE_WINDOWS_VISTA + WakeAllConditionVariable(&m_cv); + #else + if (m_count > 0) + SetEvent(m_events[BROADCAST]); + #endif + } + + void ConditionVariableImpl::Wait(MutexImpl* mutex) + { + Wait(mutex, INFINITE); + } + + bool ConditionVariableImpl::Wait(MutexImpl* mutex, UInt32 timeout) + { + #if NAZARA_CORE_WINDOWS_VISTA + return SleepConditionVariableCS(&m_cv, &mutex->m_criticalSection, timeout); + #else + m_count++; + + // It's ok to release the mutex here since Win32 + // manual-reset events maintain state when used with SetEvent. + // This avoids the "lost wakeup" bug... + LeaveCriticalSection(&mutex->m_criticalSection); + + // Wait for either event to become signaled due to Signal being called or SignalAll being called. + int result = WaitForMultipleObjects(2, m_events, false, timeout); + + // Some thread called SignalAll + if (--m_count == 0 && result == WAIT_OBJECT_0 + BROADCAST) + // We're the last waiter to be notified or to stop waiting, so reset the manual event. + ResetEvent(m_events[BROADCAST]); + + // Reacquire the mutex. + EnterCriticalSection(&mutex->m_criticalSection); + + return result != WAIT_TIMEOUT; + #endif + } + } diff --git a/src/Nazara/Core/Win32/ConditionVariableImpl.hpp b/src/Nazara/Core/Win32/ConditionVariableImpl.hpp index 171c9cd2a..a1bb70deb 100644 --- a/src/Nazara/Core/Win32/ConditionVariableImpl.hpp +++ b/src/Nazara/Core/Win32/ConditionVariableImpl.hpp @@ -13,39 +13,41 @@ #include #include -class NzMutexImpl; - -class NzConditionVariableImpl +namespace Nz { - public: - NzConditionVariableImpl(); - #if NAZARA_CORE_WINDOWS_VISTA - ~NzConditionVariableImpl() = default; - #else - ~NzConditionVariableImpl(); - #endif + class MutexImpl; - void Signal(); - void SignalAll(); + class ConditionVariableImpl + { + public: + ConditionVariableImpl(); + #if NAZARA_CORE_WINDOWS_VISTA + ~ConditionVariableImpl() = default; + #else + ~ConditionVariableImpl(); + #endif - void Wait(NzMutexImpl* mutex); - bool Wait(NzMutexImpl* mutex, nzUInt32 timeout); + void Signal(); + void SignalAll(); - private: - #if NAZARA_CORE_WINDOWS_VISTA - CONDITION_VARIABLE m_cv; - #else - enum - { - SIGNAL, - BROADCAST, - MAX_EVENTS - }; + void Wait(MutexImpl* mutex); + bool Wait(MutexImpl* mutex, UInt32 timeout); - std::atomic_uint m_count; - HANDLE m_events[MAX_EVENTS]; - #endif + private: + #if NAZARA_CORE_WINDOWS_VISTA + CONDITION_VARIABLE m_cv; + #else + enum + { + SIGNAL, + BROADCAST, + MAX_EVENTS + }; -}; + std::atomic_uint m_count; + HANDLE m_events[MAX_EVENTS]; + #endif + }; +} #endif // NAZARA_CONDITIONVARIABLEIMPL_HPP diff --git a/src/Nazara/Core/Win32/DirectoryImpl.cpp b/src/Nazara/Core/Win32/DirectoryImpl.cpp index c0f97ab2b..9901b9c10 100644 --- a/src/Nazara/Core/Win32/DirectoryImpl.cpp +++ b/src/Nazara/Core/Win32/DirectoryImpl.cpp @@ -7,113 +7,116 @@ #include #include -NzDirectoryImpl::NzDirectoryImpl(const NzDirectory* parent) +namespace Nz { - NazaraUnused(parent); -} - -void NzDirectoryImpl::Close() -{ - FindClose(m_handle); -} - -NzString NzDirectoryImpl::GetResultName() const -{ - return NzString::Unicode(m_result.cFileName); -} - -nzUInt64 NzDirectoryImpl::GetResultSize() const -{ - LARGE_INTEGER size; - size.HighPart = m_result.nFileSizeHigh; - size.LowPart = m_result.nFileSizeLow; - - return size.QuadPart; -} - -bool NzDirectoryImpl::IsResultDirectory() const -{ - if (m_result.dwFileAttributes != INVALID_FILE_ATTRIBUTES) - return (m_result.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; - else - return false; -} - -bool NzDirectoryImpl::NextResult() -{ - if (m_firstCall) // Nous devons ignorer le premier appel car FindFirstFile nous a déjà renvoyé des résultats + DirectoryImpl::DirectoryImpl(const Directory* parent) { - m_firstCall = false; - return true; + NazaraUnused(parent); } - if (FindNextFileW(m_handle, &m_result)) - return true; - else + void DirectoryImpl::Close() { - if (GetLastError() != ERROR_NO_MORE_FILES) - NazaraError("Unable to get next result: " + NzError::GetLastSystemError()); - - return false; - } -} - -bool NzDirectoryImpl::Open(const NzString& dirPath) -{ - NzString searchPath = dirPath + "\\*"; - - m_handle = FindFirstFileW(searchPath.GetWideString().data(), &m_result); - if (m_handle == INVALID_HANDLE_VALUE) - { - NazaraError("Unable to open directory: " + NzError::GetLastSystemError()); - return false; + FindClose(m_handle); } - m_firstCall = true; - - return true; -} - -bool NzDirectoryImpl::Create(const NzString& dirPath) -{ - return (CreateDirectoryW(dirPath.GetWideString().data(), nullptr) != 0) || GetLastError() == ERROR_ALREADY_EXISTS; -} - -bool NzDirectoryImpl::Exists(const NzString& dirPath) -{ - DWORD attributes = GetFileAttributesW(dirPath.GetWideString().data()); - if (attributes != INVALID_FILE_ATTRIBUTES) - return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; - else - return false; -} - -NzString NzDirectoryImpl::GetCurrent() -{ - NzString currentPath; - std::unique_ptr path(new wchar_t[MAX_PATH]); - - unsigned int size = GetCurrentDirectoryW(MAX_PATH, path.get()); - if (size > MAX_PATH) // La taille prends en compte le caractère nul + String DirectoryImpl::GetResultName() const { - path.reset(new wchar_t[size]); - if (GetCurrentDirectoryW(size, path.get()) != 0) - currentPath = NzString::Unicode(path.get()); + return String::Unicode(m_result.cFileName); + } + + UInt64 DirectoryImpl::GetResultSize() const + { + LARGE_INTEGER size; + size.HighPart = m_result.nFileSizeHigh; + size.LowPart = m_result.nFileSizeLow; + + return size.QuadPart; + } + + bool DirectoryImpl::IsResultDirectory() const + { + if (m_result.dwFileAttributes != INVALID_FILE_ATTRIBUTES) + return (m_result.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; else - NazaraError("Unable to get current directory: " + NzError::GetLastSystemError()); + return false; } - else if (size == 0) - NazaraError("Unable to get current directory: " + NzError::GetLastSystemError()); - else - currentPath = NzString::Unicode(path.get()); - return currentPath; -} - -bool NzDirectoryImpl::Remove(const NzString& dirPath) -{ - bool success = RemoveDirectoryW(dirPath.GetWideString().data()) != 0; - - DWORD error = GetLastError(); - return success || error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND; + bool DirectoryImpl::NextResult() + { + if (m_firstCall) // Nous devons ignorer le premier appel car FindFirstFile nous a déjà renvoyé des résultats + { + m_firstCall = false; + return true; + } + + if (FindNextFileW(m_handle, &m_result)) + return true; + else + { + if (GetLastError() != ERROR_NO_MORE_FILES) + NazaraError("Unable to get next result: " + Error::GetLastSystemError()); + + return false; + } + } + + bool DirectoryImpl::Open(const String& dirPath) + { + String searchPath = dirPath + "\\*"; + + m_handle = FindFirstFileW(searchPath.GetWideString().data(), &m_result); + if (m_handle == INVALID_HANDLE_VALUE) + { + NazaraError("Unable to open directory: " + Error::GetLastSystemError()); + return false; + } + + m_firstCall = true; + + return true; + } + + bool DirectoryImpl::Create(const String& dirPath) + { + return (CreateDirectoryW(dirPath.GetWideString().data(), nullptr) != 0) || GetLastError() == ERROR_ALREADY_EXISTS; + } + + bool DirectoryImpl::Exists(const String& dirPath) + { + DWORD attributes = GetFileAttributesW(dirPath.GetWideString().data()); + if (attributes != INVALID_FILE_ATTRIBUTES) + return (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0; + else + return false; + } + + String DirectoryImpl::GetCurrent() + { + String currentPath; + std::unique_ptr path(new wchar_t[MAX_PATH]); + + unsigned int size = GetCurrentDirectoryW(MAX_PATH, path.get()); + if (size > MAX_PATH) // La taille prends en compte le caractère nul + { + path.reset(new wchar_t[size]); + if (GetCurrentDirectoryW(size, path.get()) != 0) + currentPath = String::Unicode(path.get()); + else + NazaraError("Unable to get current directory: " + Error::GetLastSystemError()); + } + else if (size == 0) + NazaraError("Unable to get current directory: " + Error::GetLastSystemError()); + else + currentPath = String::Unicode(path.get()); + + return currentPath; + } + + bool DirectoryImpl::Remove(const String& dirPath) + { + bool success = RemoveDirectoryW(dirPath.GetWideString().data()) != 0; + + DWORD error = GetLastError(); + return success || error == ERROR_FILE_NOT_FOUND || error == ERROR_PATH_NOT_FOUND; + } } diff --git a/src/Nazara/Core/Win32/DirectoryImpl.hpp b/src/Nazara/Core/Win32/DirectoryImpl.hpp index 117d04d7f..843587d52 100644 --- a/src/Nazara/Core/Win32/DirectoryImpl.hpp +++ b/src/Nazara/Core/Win32/DirectoryImpl.hpp @@ -10,40 +10,43 @@ #include #include -class NzDirectory; -class NzString; - -class NzDirectoryImpl +namespace Nz { - public: - NzDirectoryImpl(const NzDirectory* parent); - NzDirectoryImpl(const NzDirectoryImpl&) = delete; - NzDirectoryImpl(NzDirectoryImpl&&) = delete; ///TODO - ~NzDirectoryImpl() = default; + class Directory; + class String; - void Close(); + class DirectoryImpl + { + public: + DirectoryImpl(const Directory* parent); + DirectoryImpl(const DirectoryImpl&) = delete; + DirectoryImpl(DirectoryImpl&&) = delete; ///TODO + ~DirectoryImpl() = default; - NzString GetResultName() const; - nzUInt64 GetResultSize() const; + void Close(); - bool IsResultDirectory() const; + String GetResultName() const; + UInt64 GetResultSize() const; - bool NextResult(); + bool IsResultDirectory() const; - bool Open(const NzString& dirPath); + bool NextResult(); - NzDirectoryImpl& operator=(const NzDirectoryImpl&) = delete; - NzDirectoryImpl& operator=(NzDirectoryImpl&&) = delete; ///TODO + bool Open(const String& dirPath); - static bool Create(const NzString& dirPath); - static bool Exists(const NzString& dirPath); - static NzString GetCurrent(); - static bool Remove(const NzString& dirPath); + DirectoryImpl& operator=(const DirectoryImpl&) = delete; + DirectoryImpl& operator=(DirectoryImpl&&) = delete; ///TODO - private: - HANDLE m_handle; - WIN32_FIND_DATAW m_result; - bool m_firstCall; -}; + static bool Create(const String& dirPath); + static bool Exists(const String& dirPath); + static String GetCurrent(); + static bool Remove(const String& dirPath); + + private: + HANDLE m_handle; + WIN32_FIND_DATAW m_result; + bool m_firstCall; + }; +} #endif // NAZARA_DIRECTORYIMPL_HPP diff --git a/src/Nazara/Core/Win32/DynLibImpl.cpp b/src/Nazara/Core/Win32/DynLibImpl.cpp index d1afe2c05..0256e40fb 100644 --- a/src/Nazara/Core/Win32/DynLibImpl.cpp +++ b/src/Nazara/Core/Win32/DynLibImpl.cpp @@ -10,37 +10,41 @@ #include #include -NzDynLibImpl::NzDynLibImpl(NzDynLib* parent) +namespace Nz { - NazaraUnused(parent); -} - -NzDynLibFunc NzDynLibImpl::GetSymbol(const NzString& symbol, NzString* errorMessage) const -{ - NzDynLibFunc sym = reinterpret_cast(GetProcAddress(m_handle, symbol.GetConstBuffer())); - if (!sym) - *errorMessage = NzError::GetLastSystemError(); - - return sym; -} - -bool NzDynLibImpl::Load(const NzString& libraryPath, NzString* errorMessage) -{ - NzString path = libraryPath; - if (!path.EndsWith(".dll")) - path += ".dll"; - - m_handle = LoadLibraryExW(path.GetWideString().data(), nullptr, (NzFile::IsAbsolute(path)) ? LOAD_WITH_ALTERED_SEARCH_PATH : 0); - if (m_handle) - return true; - else + DynLibImpl::DynLibImpl(DynLib* parent) { - *errorMessage = NzError::GetLastSystemError(); - return false; + NazaraUnused(parent); + } + + DynLibFunc DynLibImpl::GetSymbol(const String& symbol, String* errorMessage) const + { + DynLibFunc sym = reinterpret_cast(GetProcAddress(m_handle, symbol.GetConstBuffer())); + if (!sym) + *errorMessage = Error::GetLastSystemError(); + + return sym; + } + + bool DynLibImpl::Load(const String& libraryPath, String* errorMessage) + { + String path = libraryPath; + if (!path.EndsWith(".dll")) + path += ".dll"; + + m_handle = LoadLibraryExW(path.GetWideString().data(), nullptr, (File::IsAbsolute(path)) ? LOAD_WITH_ALTERED_SEARCH_PATH : 0); + if (m_handle) + return true; + else + { + *errorMessage = Error::GetLastSystemError(); + return false; + } + } + + void DynLibImpl::Unload() + { + FreeLibrary(m_handle); } -} -void NzDynLibImpl::Unload() -{ - FreeLibrary(m_handle); } diff --git a/src/Nazara/Core/Win32/DynLibImpl.hpp b/src/Nazara/Core/Win32/DynLibImpl.hpp index 4c6a2e72f..aa2a3a9c1 100644 --- a/src/Nazara/Core/Win32/DynLibImpl.hpp +++ b/src/Nazara/Core/Win32/DynLibImpl.hpp @@ -11,25 +11,28 @@ #include #include -class NzString; - -class NzDynLibImpl +namespace Nz { - public: - NzDynLibImpl(NzDynLib* m_parent); - NzDynLibImpl(const NzDynLibImpl&) = delete; - NzDynLibImpl(NzDynLibImpl&&) = delete; ///TODO? - ~NzDynLibImpl() = default; + class String; - NzDynLibFunc GetSymbol(const NzString& symbol, NzString* errorMessage) const; - bool Load(const NzString& libraryPath, NzString* errorMessage); - void Unload(); + class DynLibImpl + { + public: + DynLibImpl(DynLib* m_parent); + DynLibImpl(const DynLibImpl&) = delete; + DynLibImpl(DynLibImpl&&) = delete; ///TODO? + ~DynLibImpl() = default; - NzDynLibImpl& operator=(const NzDynLibImpl&) = delete; - NzDynLibImpl& operator=(NzDynLibImpl&&) = delete; ///TODO? + DynLibFunc GetSymbol(const String& symbol, String* errorMessage) const; + bool Load(const String& libraryPath, String* errorMessage); + void Unload(); - private: - HMODULE m_handle; -}; + DynLibImpl& operator=(const DynLibImpl&) = delete; + DynLibImpl& operator=(DynLibImpl&&) = delete; ///TODO? + + private: + HMODULE m_handle; + }; +} #endif // NAZARA_DYNLIBIMPL_HPP diff --git a/src/Nazara/Core/Win32/FileImpl.cpp b/src/Nazara/Core/Win32/FileImpl.cpp index a2e4ef192..18f438ea5 100644 --- a/src/Nazara/Core/Win32/FileImpl.cpp +++ b/src/Nazara/Core/Win32/FileImpl.cpp @@ -8,288 +8,291 @@ #include #include -NzFileImpl::NzFileImpl(const NzFile* parent) : -m_endOfFile(false), -m_endOfFileUpdated(true) +namespace Nz { - NazaraUnused(parent); -} - -void NzFileImpl::Close() -{ - CloseHandle(m_handle); -} - -bool NzFileImpl::EndOfFile() const -{ - if (!m_endOfFileUpdated) + FileImpl::FileImpl(const File* parent) : + m_endOfFile(false), + m_endOfFileUpdated(true) { - LARGE_INTEGER fileSize; - if (!GetFileSizeEx(m_handle, &fileSize)) - fileSize.QuadPart = 0; - - m_endOfFile = (GetCursorPos() >= static_cast(fileSize.QuadPart)); - m_endOfFileUpdated = true; + NazaraUnused(parent); } - return m_endOfFile; -} - -void NzFileImpl::Flush() -{ - if (!FlushFileBuffers(m_handle)) - NazaraError("Unable to flush file: " + NzError::GetLastSystemError()); -} - -nzUInt64 NzFileImpl::GetCursorPos() const -{ - LARGE_INTEGER zero; - zero.QuadPart = 0; - - LARGE_INTEGER position; - SetFilePointerEx(m_handle, zero, &position, FILE_CURRENT); - - return position.QuadPart; -} - -bool NzFileImpl::Open(const NzString& filePath, unsigned int mode) -{ - DWORD access; - DWORD shareMode = FILE_SHARE_READ; - DWORD openMode; - if (mode & nzOpenMode_ReadOnly) + void FileImpl::Close() { - access = GENERIC_READ; - openMode = OPEN_EXISTING; + CloseHandle(m_handle); } - else if (mode & nzOpenMode_ReadWrite) + + bool FileImpl::EndOfFile() const { - if (mode & nzOpenMode_Append) - access = FILE_APPEND_DATA; - else - access = GENERIC_READ | GENERIC_WRITE; - - if (mode & nzOpenMode_Truncate) - openMode = CREATE_ALWAYS; - else - openMode = OPEN_ALWAYS; - } - else if (mode & nzOpenMode_WriteOnly) - { - if (mode & nzOpenMode_Append) - access = FILE_APPEND_DATA; - else - access = GENERIC_WRITE; - - if (mode & nzOpenMode_Truncate) - openMode = CREATE_ALWAYS; - else - openMode = OPEN_ALWAYS; - } - else - return false; - - if ((mode & nzOpenMode_Lock) == 0) - shareMode |= FILE_SHARE_WRITE; - - m_handle = CreateFileW(filePath.GetWideString().data(), access, shareMode, nullptr, openMode, 0, nullptr); - return m_handle != INVALID_HANDLE_VALUE; -} - -std::size_t NzFileImpl::Read(void* buffer, std::size_t size) -{ - //nzUInt64 oldCursorPos = GetCursorPos(); - - DWORD read = 0; - if (ReadFile(m_handle, buffer, size, &read, nullptr)) - { - m_endOfFile = (read != size); - m_endOfFileUpdated = true; - - return read; - ///FIXME: D'après la documentation, read vaut 0 si ReadFile atteint la fin du fichier - /// D'après les tests, ce n'est pas le cas, la taille lue est inférieure à la taille en argument, mais pas nulle - /// Peut-être ais-je mal compris la documentation - /// Le correctif (dans le cas où la doc serait vraie) est commenté en début de fonction et après ce commentaire - /// Il est cependant plus lourd, et ne fonctionne pas avec le comportement observé de la fonction - /* - if (read == 0) + if (!m_endOfFileUpdated) { - // Si nous atteignons la fin du fichier, la taille lue vaut 0 - // pour renvoyer le nombre d'octets lus nous comparons la position du curseur - // http://msdn.microsoft.com/en-us/library/windows/desktop/aa365690(v=vs.85).aspx - m_endOfFile = true; + LARGE_INTEGER fileSize; + if (!GetFileSizeEx(m_handle, &fileSize)) + fileSize.QuadPart = 0; + + m_endOfFile = (GetCursorPos() >= static_cast(fileSize.QuadPart)); + m_endOfFileUpdated = true; + } + + return m_endOfFile; + } + + void FileImpl::Flush() + { + if (!FlushFileBuffers(m_handle)) + NazaraError("Unable to flush file: " + Error::GetLastSystemError()); + } + + UInt64 FileImpl::GetCursorPos() const + { + LARGE_INTEGER zero; + zero.QuadPart = 0; + + LARGE_INTEGER position; + SetFilePointerEx(m_handle, zero, &position, FILE_CURRENT); + + return position.QuadPart; + } + + bool FileImpl::Open(const String& filePath, unsigned int mode) + { + DWORD access; + DWORD shareMode = FILE_SHARE_READ; + DWORD openMode; + if (mode & OpenMode_ReadOnly) + { + access = GENERIC_READ; + openMode = OPEN_EXISTING; + } + else if (mode & OpenMode_ReadWrite) + { + if (mode & OpenMode_Append) + access = FILE_APPEND_DATA; + else + access = GENERIC_READ | GENERIC_WRITE; + + if (mode & OpenMode_Truncate) + openMode = CREATE_ALWAYS; + else + openMode = OPEN_ALWAYS; + } + else if (mode & OpenMode_WriteOnly) + { + if (mode & OpenMode_Append) + access = FILE_APPEND_DATA; + else + access = GENERIC_WRITE; + + if (mode & OpenMode_Truncate) + openMode = CREATE_ALWAYS; + else + openMode = OPEN_ALWAYS; + } + else + return false; + + if ((mode & OpenMode_Lock) == 0) + shareMode |= FILE_SHARE_WRITE; + + m_handle = CreateFileW(filePath.GetWideString().data(), access, shareMode, nullptr, openMode, 0, nullptr); + return m_handle != INVALID_HANDLE_VALUE; + } + + std::size_t FileImpl::Read(void* buffer, std::size_t size) + { + //UInt64 oldCursorPos = GetCursorPos(); + + DWORD read = 0; + if (ReadFile(m_handle, buffer, size, &read, nullptr)) + { + m_endOfFile = (read != size); m_endOfFileUpdated = true; - return GetCursorPos()-oldCursorPos; + return read; + ///FIXME: D'après la documentation, read vaut 0 si ReadFile atteint la fin du fichier + /// D'après les tests, ce n'est pas le cas, la taille lue est inférieure à la taille en argument, mais pas nulle + /// Peut-être ais-je mal compris la documentation + /// Le correctif (dans le cas où la doc serait vraie) est commenté en début de fonction et après ce commentaire + /// Il est cependant plus lourd, et ne fonctionne pas avec le comportement observé de la fonction + /* + if (read == 0) + { + // Si nous atteignons la fin du fichier, la taille lue vaut 0 + // pour renvoyer le nombre d'octets lus nous comparons la position du curseur + // http://msdn.microsoft.com/en-us/library/windows/desktop/aa365690(v=vs.85).aspx + m_endOfFile = true; + m_endOfFileUpdated = true; + + return GetCursorPos()-oldCursorPos; + } + else + { + m_endOfFileUpdated = false; + return read; + } + */ } else + return 0; + } + + bool FileImpl::SetCursorPos(CursorPosition pos, Int64 offset) + { + DWORD moveMethod; + switch (pos) { - m_endOfFileUpdated = false; - return read; + case CursorPosition_AtBegin: + moveMethod = FILE_BEGIN; + break; + + case CursorPosition_AtCurrent: + moveMethod = FILE_CURRENT; + break; + + case CursorPosition_AtEnd: + moveMethod = FILE_END; + break; + + default: + NazaraInternalError("Cursor position not handled (0x" + String::Number(pos, 16) + ')'); + return false; } - */ + + LARGE_INTEGER distance; + distance.QuadPart = offset; + + m_endOfFileUpdated = false; + + return SetFilePointerEx(m_handle, distance, nullptr, moveMethod) != 0; } - else - return 0; -} -bool NzFileImpl::SetCursorPos(nzCursorPosition pos, nzInt64 offset) -{ - DWORD moveMethod; - switch (pos) + std::size_t FileImpl::Write(const void* buffer, std::size_t size) { - case nzCursorPosition_AtBegin: - moveMethod = FILE_BEGIN; - break; + DWORD written = 0; - case nzCursorPosition_AtCurrent: - moveMethod = FILE_CURRENT; - break; + LARGE_INTEGER cursorPos; + cursorPos.QuadPart = GetCursorPos(); - case nzCursorPosition_AtEnd: - moveMethod = FILE_END; - break; + LockFile(m_handle, cursorPos.LowPart, cursorPos.HighPart, size, 0); + WriteFile(m_handle, buffer, size, &written, nullptr); + UnlockFile(m_handle, cursorPos.LowPart, cursorPos.HighPart, size, 0); - default: - NazaraInternalError("Cursor position not handled (0x" + NzString::Number(pos, 16) + ')'); + m_endOfFileUpdated = false; + + return written; + } + + bool FileImpl::Copy(const String& sourcePath, const String& targetPath) + { + if (CopyFileW(sourcePath.GetWideString().data(), targetPath.GetWideString().data(), false)) + return true; + else + { + NazaraError("Failed to copy file: " + Error::GetLastSystemError()); return false; + } } - LARGE_INTEGER distance; - distance.QuadPart = offset; - - m_endOfFileUpdated = false; - - return SetFilePointerEx(m_handle, distance, nullptr, moveMethod) != 0; -} - -std::size_t NzFileImpl::Write(const void* buffer, std::size_t size) -{ - DWORD written = 0; - - LARGE_INTEGER cursorPos; - cursorPos.QuadPart = GetCursorPos(); - - LockFile(m_handle, cursorPos.LowPart, cursorPos.HighPart, size, 0); - WriteFile(m_handle, buffer, size, &written, nullptr); - UnlockFile(m_handle, cursorPos.LowPart, cursorPos.HighPart, size, 0); - - m_endOfFileUpdated = false; - - return written; -} - -bool NzFileImpl::Copy(const NzString& sourcePath, const NzString& targetPath) -{ - if (CopyFileW(sourcePath.GetWideString().data(), targetPath.GetWideString().data(), false)) - return true; - else + bool FileImpl::Delete(const String& filePath) { - NazaraError("Failed to copy file: " + NzError::GetLastSystemError()); - return false; + if (DeleteFileW(filePath.GetWideString().data())) + return true; + else + { + NazaraError("Failed to delete file (" + filePath + "): " + Error::GetLastSystemError()); + return false; + } } -} -bool NzFileImpl::Delete(const NzString& filePath) -{ - if (DeleteFileW(filePath.GetWideString().data())) - return true; - else + bool FileImpl::Exists(const String& filePath) { - NazaraError("Failed to delete file (" + filePath + "): " + NzError::GetLastSystemError()); - return false; - } -} + HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); + if (handle == INVALID_HANDLE_VALUE) + return false; -bool NzFileImpl::Exists(const NzString& filePath) -{ - HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); - if (handle == INVALID_HANDLE_VALUE) - return false; - - CloseHandle(handle); - return true; -} - -time_t NzFileImpl::GetCreationTime(const NzString& filePath) -{ - HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); - if (handle == INVALID_HANDLE_VALUE) - return 0; - - FILETIME creationTime; - if (!GetFileTime(handle, &creationTime, nullptr, nullptr)) - { CloseHandle(handle); - - NazaraError("Unable to get creation time: " + NzError::GetLastSystemError()); - return 0; - } - - CloseHandle(handle); - return NzFileTimeToTime(&creationTime); -} - -time_t NzFileImpl::GetLastAccessTime(const NzString& filePath) -{ - HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); - if (handle == INVALID_HANDLE_VALUE) - return 0; - - FILETIME accessTime; - if (!GetFileTime(handle, nullptr, &accessTime, nullptr)) - { - CloseHandle(handle); - - NazaraError("Unable to get last access time: " + NzError::GetLastSystemError()); - return 0; - } - - CloseHandle(handle); - return NzFileTimeToTime(&accessTime); -} - -time_t NzFileImpl::GetLastWriteTime(const NzString& filePath) -{ - HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); - if (handle == INVALID_HANDLE_VALUE) - return 0; - - FILETIME writeTime; - if (!GetFileTime(handle, nullptr, nullptr, &writeTime)) - { - CloseHandle(handle); - - NazaraError("Unable to get last write time: " + NzError::GetLastSystemError()); - return 0; - } - - CloseHandle(handle); - return NzFileTimeToTime(&writeTime); -} - -nzUInt64 NzFileImpl::GetSize(const NzString& filePath) -{ - HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); - if (handle == INVALID_HANDLE_VALUE) - return 0; - - LARGE_INTEGER fileSize; - if (!GetFileSizeEx(handle, &fileSize)) - fileSize.QuadPart = 0; - - CloseHandle(handle); - return fileSize.QuadPart; -} - -bool NzFileImpl::Rename(const NzString& sourcePath, const NzString& targetPath) -{ - if (MoveFileExW(sourcePath.GetWideString().data(), targetPath.GetWideString().data(), MOVEFILE_COPY_ALLOWED)) return true; - else + } + + time_t FileImpl::GetCreationTime(const String& filePath) { - NazaraError("Unable to rename file: " + NzError::GetLastSystemError()); - return false; + HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); + if (handle == INVALID_HANDLE_VALUE) + return 0; + + FILETIME creationTime; + if (!GetFileTime(handle, &creationTime, nullptr, nullptr)) + { + CloseHandle(handle); + + NazaraError("Unable to get creation time: " + Error::GetLastSystemError()); + return 0; + } + + CloseHandle(handle); + return FileTimeToTime(&creationTime); + } + + time_t FileImpl::GetLastAccessTime(const String& filePath) + { + HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); + if (handle == INVALID_HANDLE_VALUE) + return 0; + + FILETIME accessTime; + if (!GetFileTime(handle, nullptr, &accessTime, nullptr)) + { + CloseHandle(handle); + + NazaraError("Unable to get last access time: " + Error::GetLastSystemError()); + return 0; + } + + CloseHandle(handle); + return FileTimeToTime(&accessTime); + } + + time_t FileImpl::GetLastWriteTime(const String& filePath) + { + HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); + if (handle == INVALID_HANDLE_VALUE) + return 0; + + FILETIME writeTime; + if (!GetFileTime(handle, nullptr, nullptr, &writeTime)) + { + CloseHandle(handle); + + NazaraError("Unable to get last write time: " + Error::GetLastSystemError()); + return 0; + } + + CloseHandle(handle); + return FileTimeToTime(&writeTime); + } + + UInt64 FileImpl::GetSize(const String& filePath) + { + HANDLE handle = CreateFileW(filePath.GetWideString().data(), 0, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); + if (handle == INVALID_HANDLE_VALUE) + return 0; + + LARGE_INTEGER fileSize; + if (!GetFileSizeEx(handle, &fileSize)) + fileSize.QuadPart = 0; + + CloseHandle(handle); + return fileSize.QuadPart; + } + + bool FileImpl::Rename(const String& sourcePath, const String& targetPath) + { + if (MoveFileExW(sourcePath.GetWideString().data(), targetPath.GetWideString().data(), MOVEFILE_COPY_ALLOWED)) + return true; + else + { + NazaraError("Unable to rename file: " + Error::GetLastSystemError()); + return false; + } } } diff --git a/src/Nazara/Core/Win32/FileImpl.hpp b/src/Nazara/Core/Win32/FileImpl.hpp index 1e1f2c854..9bc484cc1 100644 --- a/src/Nazara/Core/Win32/FileImpl.hpp +++ b/src/Nazara/Core/Win32/FileImpl.hpp @@ -12,42 +12,45 @@ #include #include -class NzFile; -class NzString; - -class NzFileImpl +namespace Nz { - public: - NzFileImpl(const NzFile* parent); - NzFileImpl(const NzFileImpl&) = delete; - NzFileImpl(NzFileImpl&&) = delete; ///TODO - ~NzFileImpl() = default; + class File; + class String; - void Close(); - bool EndOfFile() const; - void Flush(); - nzUInt64 GetCursorPos() const; - bool Open(const NzString& filePath, unsigned int mode); - std::size_t Read(void* buffer, std::size_t size); - bool SetCursorPos(nzCursorPosition pos, nzInt64 offset); - std::size_t Write(const void* buffer, std::size_t size); + class FileImpl + { + public: + FileImpl(const File* parent); + FileImpl(const FileImpl&) = delete; + FileImpl(FileImpl&&) = delete; ///TODO + ~FileImpl() = default; - NzFileImpl& operator=(const NzFileImpl&) = delete; - NzFileImpl& operator=(NzFileImpl&&) = delete; ///TODO + void Close(); + bool EndOfFile() const; + void Flush(); + UInt64 GetCursorPos() const; + bool Open(const String& filePath, unsigned int mode); + std::size_t Read(void* buffer, std::size_t size); + bool SetCursorPos(CursorPosition pos, Int64 offset); + std::size_t Write(const void* buffer, std::size_t size); - static bool Copy(const NzString& sourcePath, const NzString& targetPath); - static bool Delete(const NzString& filePath); - static bool Exists(const NzString& filePath); - static time_t GetCreationTime(const NzString& filePath); - static time_t GetLastAccessTime(const NzString& filePath); - static time_t GetLastWriteTime(const NzString& filePath); - static nzUInt64 GetSize(const NzString& filePath); - static bool Rename(const NzString& sourcePath, const NzString& targetPath); + FileImpl& operator=(const FileImpl&) = delete; + FileImpl& operator=(FileImpl&&) = delete; ///TODO - private: - HANDLE m_handle; - mutable bool m_endOfFile; - mutable bool m_endOfFileUpdated; -}; + static bool Copy(const String& sourcePath, const String& targetPath); + static bool Delete(const String& filePath); + static bool Exists(const String& filePath); + static time_t GetCreationTime(const String& filePath); + static time_t GetLastAccessTime(const String& filePath); + static time_t GetLastWriteTime(const String& filePath); + static UInt64 GetSize(const String& filePath); + static bool Rename(const String& sourcePath, const String& targetPath); + + private: + HANDLE m_handle; + mutable bool m_endOfFile; + mutable bool m_endOfFileUpdated; + }; +} #endif // NAZARA_FILEIMPL_HPP diff --git a/src/Nazara/Core/Win32/HardwareInfoImpl.cpp b/src/Nazara/Core/Win32/HardwareInfoImpl.cpp index bc6e2344b..7ce5e10a1 100644 --- a/src/Nazara/Core/Win32/HardwareInfoImpl.cpp +++ b/src/Nazara/Core/Win32/HardwareInfoImpl.cpp @@ -12,86 +12,89 @@ #include -void NzHardwareInfoImpl::Cpuid(nzUInt32 functionId, nzUInt32 subFunctionId, nzUInt32 registers[4]) +namespace Nz { -#if defined(NAZARA_COMPILER_MSVC) - static_assert(sizeof(nzUInt32) == sizeof(int), "Assertion failed"); - - // Visual propose une fonction intrinsèque pour le cpuid - __cpuidex(reinterpret_cast(registers), static_cast(functionId), static_cast(subFunctionId)); -#elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL) - // Source: http://stackoverflow.com/questions/1666093/cpuid-implementations-in-c - asm volatile ("cpuid" // Besoin d'être volatile ? - : "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]) // output - : "a" (functionId), "c" (subFunctionId)); // input -#else - NazaraInternalError("Cpuid has been called although it is not supported"); -#endif -} - -unsigned int NzHardwareInfoImpl::GetProcessorCount() -{ - // Plus simple (et plus portable) que de passer par le CPUID - SYSTEM_INFO infos; - GetNativeSystemInfo(&infos); - - return infos.dwNumberOfProcessors; -} - -nzUInt64 NzHardwareInfoImpl::GetTotalMemory() -{ - MEMORYSTATUSEX memStatus; - memStatus.dwLength = sizeof(memStatus); - GlobalMemoryStatusEx(&memStatus); - - return memStatus.ullTotalPhys; -} - -bool NzHardwareInfoImpl::IsCpuidSupported() -{ -#ifdef NAZARA_PLATFORM_x64 - return true; // Toujours supporté sur un processeur 64 bits -#else - #if defined(NAZARA_COMPILER_MSVC) - int supported; - __asm + void HardwareInfoImpl::Cpuid(UInt32 functionId, UInt32 subFunctionId, UInt32 registers[4]) { - pushfd - pop eax - mov ecx, eax - xor eax, 0x200000 - push eax - popfd - pushfd - pop eax - xor eax, ecx - mov supported, eax - push ecx - popfd - }; + #if defined(NAZARA_COMPILER_MSVC) + static_assert(sizeof(UInt32) == sizeof(int), "Assertion failed"); - return supported != 0; + // Visual propose une fonction intrinsèque pour le cpuid + __cpuidex(reinterpret_cast(registers), static_cast(functionId), static_cast(subFunctionId)); #elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL) - int supported; - asm volatile (" pushfl\n" - " pop %%eax\n" - " mov %%eax, %%ecx\n" - " xor $0x200000, %%eax\n" - " push %%eax\n" - " popfl\n" - " pushfl\n" - " pop %%eax\n" - " xor %%ecx, %%eax\n" - " mov %%eax, %0\n" - " push %%ecx\n" - " popfl" - : "=m" (supported) // output - : // input - : "eax", "ecx", "memory"); // clobbered register - - return supported != 0; + // Source: http://stackoverflow.com/questions/1666093/cpuid-implementations-in-c + asm volatile ("cpuid" // Besoin d'être volatile ? + : "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]) // output + : "a" (functionId), "c" (subFunctionId)); // input #else - return false; + NazaraInternalError("Cpuid has been called although it is not supported"); + #endif + } + + unsigned int HardwareInfoImpl::GetProcessorCount() + { + // Plus simple (et plus portable) que de passer par le CPUID + SYSTEM_INFO infos; + GetNativeSystemInfo(&infos); + + return infos.dwNumberOfProcessors; + } + + UInt64 HardwareInfoImpl::GetTotalMemory() + { + MEMORYSTATUSEX memStatus; + memStatus.dwLength = sizeof(memStatus); + GlobalMemoryStatusEx(&memStatus); + + return memStatus.ullTotalPhys; + } + + bool HardwareInfoImpl::IsCpuidSupported() + { + #ifdef NAZARA_PLATFORM_x64 + return true; // Toujours supporté sur un processeur 64 bits + #else + #if defined(NAZARA_COMPILER_MSVC) + int supported; + __asm + { + pushfd + pop eax + mov ecx, eax + xor eax, 0x200000 + push eax + popfd + pushfd + pop eax + xor eax, ecx + mov supported, eax + push ecx + popfd + }; + + return supported != 0; + #elif defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL) + int supported; + asm volatile (" pushfl\n" + " pop %%eax\n" + " mov %%eax, %%ecx\n" + " xor $0x200000, %%eax\n" + " push %%eax\n" + " popfl\n" + " pushfl\n" + " pop %%eax\n" + " xor %%ecx, %%eax\n" + " mov %%eax, %0\n" + " push %%ecx\n" + " popfl" + : "=m" (supported) // output + : // input + : "eax", "ecx", "memory"); // clobbered register + + return supported != 0; + #else + return false; + #endif #endif -#endif +} } diff --git a/src/Nazara/Core/Win32/HardwareInfoImpl.hpp b/src/Nazara/Core/Win32/HardwareInfoImpl.hpp index 0b4d477f8..3f923cfdd 100644 --- a/src/Nazara/Core/Win32/HardwareInfoImpl.hpp +++ b/src/Nazara/Core/Win32/HardwareInfoImpl.hpp @@ -9,13 +9,16 @@ #include -class NzHardwareInfoImpl +namespace Nz { - public: - static void Cpuid(nzUInt32 functionId, nzUInt32 subFunctionId, nzUInt32 registers[4]); - static unsigned int GetProcessorCount(); - static nzUInt64 GetTotalMemory(); - static bool IsCpuidSupported(); -}; + class HardwareInfoImpl + { + public: + static void Cpuid(UInt32 functionId, UInt32 subFunctionId, UInt32 registers[4]); + static unsigned int GetProcessorCount(); + static UInt64 GetTotalMemory(); + static bool IsCpuidSupported(); + }; +} #endif // NAZARA_HARDWAREINFOIMPL_WINDOWS_HPP diff --git a/src/Nazara/Core/Win32/MutexImpl.cpp b/src/Nazara/Core/Win32/MutexImpl.cpp index 81c712077..0dcce2aa3 100644 --- a/src/Nazara/Core/Win32/MutexImpl.cpp +++ b/src/Nazara/Core/Win32/MutexImpl.cpp @@ -5,31 +5,34 @@ #include #include -NzMutexImpl::NzMutexImpl() +namespace Nz { - #if NAZARA_CORE_WINDOWS_CS_SPINLOCKS > 0 - InitializeCriticalSectionAndSpinCount(&m_criticalSection, NAZARA_CORE_WINDOWS_CS_SPINLOCKS); - #else - InitializeCriticalSection(&m_criticalSection); - #endif -} + MutexImpl::MutexImpl() + { + #if NAZARA_CORE_WINDOWS_CS_SPINLOCKS > 0 + InitializeCriticalSectionAndSpinCount(&m_criticalSection, NAZARA_CORE_WINDOWS_CS_SPINLOCKS); + #else + InitializeCriticalSection(&m_criticalSection); + #endif + } -NzMutexImpl::~NzMutexImpl() -{ - DeleteCriticalSection(&m_criticalSection); -} + MutexImpl::~MutexImpl() + { + DeleteCriticalSection(&m_criticalSection); + } -void NzMutexImpl::Lock() -{ - EnterCriticalSection(&m_criticalSection); -} + void MutexImpl::Lock() + { + EnterCriticalSection(&m_criticalSection); + } -bool NzMutexImpl::TryLock() -{ - return TryEnterCriticalSection(&m_criticalSection) != 0; -} + bool MutexImpl::TryLock() + { + return TryEnterCriticalSection(&m_criticalSection) != 0; + } -void NzMutexImpl::Unlock() -{ - LeaveCriticalSection(&m_criticalSection); + void MutexImpl::Unlock() + { + LeaveCriticalSection(&m_criticalSection); + } } diff --git a/src/Nazara/Core/Win32/MutexImpl.hpp b/src/Nazara/Core/Win32/MutexImpl.hpp index 7d87edb1b..8f5ad9010 100644 --- a/src/Nazara/Core/Win32/MutexImpl.hpp +++ b/src/Nazara/Core/Win32/MutexImpl.hpp @@ -10,20 +10,23 @@ #include #include -class NzMutexImpl +namespace Nz { - friend class NzConditionVariableImpl; + class MutexImpl + { + friend class ConditionVariableImpl; - public: - NzMutexImpl(); - ~NzMutexImpl(); + public: + MutexImpl(); + ~MutexImpl(); - void Lock(); - bool TryLock(); - void Unlock(); + void Lock(); + bool TryLock(); + void Unlock(); - private: - CRITICAL_SECTION m_criticalSection; -}; + private: + CRITICAL_SECTION m_criticalSection; + }; +} #endif // NAZARA_MUTEXIMPL_HPP diff --git a/src/Nazara/Core/Win32/SemaphoreImpl.cpp b/src/Nazara/Core/Win32/SemaphoreImpl.cpp index eddba3927..31c329f2e 100644 --- a/src/Nazara/Core/Win32/SemaphoreImpl.cpp +++ b/src/Nazara/Core/Win32/SemaphoreImpl.cpp @@ -8,57 +8,60 @@ #include #include -NzSemaphoreImpl::NzSemaphoreImpl(unsigned int count) +namespace Nz { - m_semaphore = CreateSemaphoreW(nullptr, count, std::numeric_limits::max(), nullptr); - if (!m_semaphore) - NazaraError("Failed to create semaphore: " + NzError::GetLastSystemError()); -} - -NzSemaphoreImpl::~NzSemaphoreImpl() -{ - CloseHandle(m_semaphore); -} - -unsigned int NzSemaphoreImpl::GetCount() const -{ - LONG count; - ReleaseSemaphore(m_semaphore, 0, &count); - return count; -} - -void NzSemaphoreImpl::Post() -{ - #if NAZARA_CORE_SAFE - if (!ReleaseSemaphore(m_semaphore, 1, nullptr)) - NazaraError("Failed to release semaphore: " + NzError::GetLastSystemError()); - #else - ReleaseSemaphore(m_semaphore, 1, nullptr); - #endif -} - -void NzSemaphoreImpl::Wait() -{ - #if NAZARA_CORE_SAFE - if (WaitForSingleObject(m_semaphore, INFINITE) == WAIT_FAILED) - NazaraError("Failed to wait for semaphore: " + NzError::GetLastSystemError()); - #else - WaitForSingleObject(m_semaphore, INFINITE); - #endif -} - -bool NzSemaphoreImpl::Wait(nzUInt32 timeout) -{ - #if NAZARA_CORE_SAFE - DWORD result = WaitForSingleObject(m_semaphore, timeout); - if (result == WAIT_FAILED) + SemaphoreImpl::SemaphoreImpl(unsigned int count) { - NazaraError("Failed to wait for semaphore: " + NzError::GetLastSystemError()); - return false; + m_semaphore = CreateSemaphoreW(nullptr, count, std::numeric_limits::max(), nullptr); + if (!m_semaphore) + NazaraError("Failed to create semaphore: " + Error::GetLastSystemError()); + } + + SemaphoreImpl::~SemaphoreImpl() + { + CloseHandle(m_semaphore); + } + + unsigned int SemaphoreImpl::GetCount() const + { + LONG count; + ReleaseSemaphore(m_semaphore, 0, &count); + return count; + } + + void SemaphoreImpl::Post() + { + #if NAZARA_CORE_SAFE + if (!ReleaseSemaphore(m_semaphore, 1, nullptr)) + NazaraError("Failed to release semaphore: " + Error::GetLastSystemError()); + #else + ReleaseSemaphore(m_semaphore, 1, nullptr); + #endif + } + + void SemaphoreImpl::Wait() + { + #if NAZARA_CORE_SAFE + if (WaitForSingleObject(m_semaphore, INFINITE) == WAIT_FAILED) + NazaraError("Failed to wait for semaphore: " + Error::GetLastSystemError()); + #else + WaitForSingleObject(m_semaphore, INFINITE); + #endif + } + + bool SemaphoreImpl::Wait(UInt32 timeout) + { + #if NAZARA_CORE_SAFE + DWORD result = WaitForSingleObject(m_semaphore, timeout); + if (result == WAIT_FAILED) + { + NazaraError("Failed to wait for semaphore: " + Error::GetLastSystemError()); + return false; + } + else + return result == WAIT_OBJECT_0; + #else + return WaitForSingleObject(m_semaphore, timeout) == WAIT_OBJECT_0; + #endif } - else - return result == WAIT_OBJECT_0; - #else - return WaitForSingleObject(m_semaphore, timeout) == WAIT_OBJECT_0; - #endif } diff --git a/src/Nazara/Core/Win32/SemaphoreImpl.hpp b/src/Nazara/Core/Win32/SemaphoreImpl.hpp index e89c93908..ac60cab1b 100644 --- a/src/Nazara/Core/Win32/SemaphoreImpl.hpp +++ b/src/Nazara/Core/Win32/SemaphoreImpl.hpp @@ -10,19 +10,22 @@ #include #include -class NzSemaphoreImpl +namespace Nz { - public: - NzSemaphoreImpl(unsigned int count); - ~NzSemaphoreImpl(); + class SemaphoreImpl + { + public: + SemaphoreImpl(unsigned int count); + ~SemaphoreImpl(); - unsigned int GetCount() const; - void Post(); - void Wait(); - bool Wait(nzUInt32 timeout); + unsigned int GetCount() const; + void Post(); + void Wait(); + bool Wait(UInt32 timeout); - private: - HANDLE m_semaphore; -}; + private: + HANDLE m_semaphore; + }; +} #endif // NAZARA_SEMAPHOREIMPL_HPP diff --git a/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp b/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp index 4e1439c2d..92fe451b6 100644 --- a/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp +++ b/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp @@ -9,237 +9,240 @@ #include #include -bool NzTaskSchedulerImpl::Initialize(unsigned int workerCount) +namespace Nz { - if (IsInitialized()) - return true; // Déjà initialisé - - #if NAZARA_CORE_SAFE - if (workerCount == 0) + bool TaskSchedulerImpl::Initialize(unsigned int workerCount) { - NazaraError("Invalid worker count ! (0)"); - return false; - } - #endif + if (IsInitialized()) + return true; // Déjà initialisé - s_workerCount = workerCount; - s_doneEvents.reset(new HANDLE[workerCount]); - s_workers.reset(new Worker[workerCount]); - s_workerThreads.reset(new HANDLE[workerCount]); + #if NAZARA_CORE_SAFE + if (workerCount == 0) + { + NazaraError("Invalid worker count ! (0)"); + return false; + } + #endif - // L'identifiant de chaque worker doit rester en vie jusqu'à ce que chaque thread soit correctement lancé - std::unique_ptr workerIDs(new unsigned int[workerCount]); + s_workerCount = workerCount; + s_doneEvents.reset(new HANDLE[workerCount]); + s_workers.reset(new Worker[workerCount]); + s_workerThreads.reset(new HANDLE[workerCount]); - for (unsigned int i = 0; i < workerCount; ++i) - { - // On initialise les évènements, mutex et threads de chaque worker - Worker& worker = s_workers[i]; - InitializeCriticalSection(&worker.queueMutex); - worker.wakeEvent = CreateEventW(nullptr, false, false, nullptr); - worker.running = true; - worker.workCount = 0; + // L'identifiant de chaque worker doit rester en vie jusqu'à ce que chaque thread soit correctement lancé + std::unique_ptr workerIDs(new unsigned int[workerCount]); - s_doneEvents[i] = CreateEventW(nullptr, true, false, nullptr); + for (unsigned int i = 0; i < workerCount; ++i) + { + // On initialise les évènements, mutex et threads de chaque worker + Worker& worker = s_workers[i]; + InitializeCriticalSection(&worker.queueMutex); + worker.wakeEvent = CreateEventW(nullptr, false, false, nullptr); + worker.running = true; + worker.workCount = 0; - // Le thread va se lancer, signaler qu'il est prêt à travailler (s_doneEvents) et attendre d'être réveillé - workerIDs[i] = i; - s_workerThreads[i] = reinterpret_cast(_beginthreadex(nullptr, 0, &WorkerProc, &workerIDs[i], 0, nullptr)); + s_doneEvents[i] = CreateEventW(nullptr, true, false, nullptr); + + // Le thread va se lancer, signaler qu'il est prêt à travailler (s_doneEvents) et attendre d'être réveillé + workerIDs[i] = i; + s_workerThreads[i] = reinterpret_cast(_beginthreadex(nullptr, 0, &WorkerProc, &workerIDs[i], 0, nullptr)); + } + + // On attend que les workers se mettent en attente + WaitForMultipleObjects(s_workerCount, &s_doneEvents[0], true, INFINITE); + + return true; } - // On attend que les workers se mettent en attente - WaitForMultipleObjects(s_workerCount, &s_doneEvents[0], true, INFINITE); - - return true; -} - -bool NzTaskSchedulerImpl::IsInitialized() -{ - return s_workerCount > 0; -} - -void NzTaskSchedulerImpl::Run(NzFunctor** tasks, unsigned int count) -{ - // On s'assure que des tâches ne sont pas déjà en cours - WaitForMultipleObjects(s_workerCount, &s_doneEvents[0], true, INFINITE); - - std::ldiv_t div = std::ldiv(count, s_workerCount); // Division et modulo en une opération, y'a pas de petit profit - for (unsigned int i = 0; i < s_workerCount; ++i) + bool TaskSchedulerImpl::IsInitialized() { - // On va maintenant répartir les tâches entre chaque worker et les envoyer dans la queue de chacun - Worker& worker = s_workers[i]; - unsigned int taskCount = (i == 0) ? div.quot + div.rem : div.quot; - for (unsigned int j = 0; j < taskCount; ++j) - worker.queue.push(*tasks++); - - // On stocke le nombre de tâches à côté dans un entier atomique pour éviter d'entrer inutilement dans une section critique - worker.workCount = taskCount; + return s_workerCount > 0; } - // On les lance une fois qu'ils sont tous initialisés (pour éviter qu'un worker ne passe en pause détectant une absence de travaux) - for (unsigned int i = 0; i < s_workerCount; ++i) + void TaskSchedulerImpl::Run(Functor** tasks, unsigned int count) { - ResetEvent(s_doneEvents[i]); - SetEvent(s_workers[i].wakeEvent); - } -} + // On s'assure que des tâches ne sont pas déjà en cours + WaitForMultipleObjects(s_workerCount, &s_doneEvents[0], true, INFINITE); -void NzTaskSchedulerImpl::Uninitialize() -{ - #ifdef NAZARA_CORE_SAFE - if (s_workerCount == 0) - { - NazaraError("Task scheduler is not initialized"); - return; - } - #endif - - // On commence par vider la queue de chaque worker pour s'assurer qu'ils s'arrêtent - for (unsigned int i = 0; i < s_workerCount; ++i) - { - Worker& worker = s_workers[i]; - worker.running = false; - worker.workCount = 0; - - EnterCriticalSection(&worker.queueMutex); - - std::queue emptyQueue; - std::swap(worker.queue, emptyQueue); // Et on vide la queue (merci std::swap) - - LeaveCriticalSection(&worker.queueMutex); - - // On réveille le worker pour qu'il sorte de la boucle et termine le thread - SetEvent(worker.wakeEvent); - } - - // On attend que chaque thread se termine - WaitForMultipleObjects(s_workerCount, &s_workerThreads[0], true, INFINITE); - - // Et on libère les ressources - for (unsigned int i = 0; i < s_workerCount; ++i) - { - Worker& worker = s_workers[i]; - CloseHandle(s_doneEvents[i]); - CloseHandle(s_workerThreads[i]); - CloseHandle(worker.wakeEvent); - DeleteCriticalSection(&worker.queueMutex); - } - - s_doneEvents.reset(); - s_workers.reset(); - s_workerThreads.reset(); - s_workerCount = 0; -} - -void NzTaskSchedulerImpl::WaitForTasks() -{ - #ifdef NAZARA_CORE_SAFE - if (s_workerCount == 0) - { - NazaraError("Task scheduler is not initialized"); - return; - } - #endif - - WaitForMultipleObjects(s_workerCount, &s_doneEvents[0], true, INFINITE); -} - -NzFunctor* NzTaskSchedulerImpl::StealTask(unsigned int workerID) -{ - bool shouldRetry; - do - { - shouldRetry = false; + std::ldiv_t div = std::ldiv(count, s_workerCount); // Division et modulo en une opération, y'a pas de petit profit for (unsigned int i = 0; i < s_workerCount; ++i) { - // On ne vole pas la famille, ni soi-même. - if (i == workerID) - continue; - + // On va maintenant répartir les tâches entre chaque worker et les envoyer dans la queue de chacun Worker& worker = s_workers[i]; + unsigned int taskCount = (i == 0) ? div.quot + div.rem : div.quot; + for (unsigned int j = 0; j < taskCount; ++j) + worker.queue.push(*tasks++); - // Ce worker a-t-il encore des tâches dans sa file d'attente ? - if (worker.workCount > 0) - { - NzFunctor* task = nullptr; + // On stocke le nombre de tâches à côté dans un entier atomique pour éviter d'entrer inutilement dans une section critique + worker.workCount = taskCount; + } - // Est-ce qu'il utilise la queue maintenant ? - if (TryEnterCriticalSection(&worker.queueMutex)) - { - // Non, super ! Profitons-en pour essayer de lui voler un job - if (!worker.queue.empty()) // On vérifie que la queue n'est pas vide (peut avoir changé avant le verrouillage) - { - // Et hop, on vole la tâche - task = worker.queue.front(); - worker.queue.pop(); - worker.workCount = worker.queue.size(); - } - - LeaveCriticalSection(&worker.queueMutex); - } - else - shouldRetry = true; // Il est encore possible d'avoir un job - - // Avons-nous notre tâche ? - if (task) - return task; // Parfait, sortons de là ! - } + // On les lance une fois qu'ils sont tous initialisés (pour éviter qu'un worker ne passe en pause détectant une absence de travaux) + for (unsigned int i = 0; i < s_workerCount; ++i) + { + ResetEvent(s_doneEvents[i]); + SetEvent(s_workers[i].wakeEvent); } } - while (shouldRetry); - // Bon à priori plus aucun worker n'a de tâche - return nullptr; -} - -unsigned int __stdcall NzTaskSchedulerImpl::WorkerProc(void* userdata) -{ - unsigned int workerID = *reinterpret_cast(userdata); - SetEvent(s_doneEvents[workerID]); - - Worker& worker = s_workers[workerID]; - WaitForSingleObject(worker.wakeEvent, INFINITE); - - while (worker.running) + void TaskSchedulerImpl::Uninitialize() { - NzFunctor* task = nullptr; - - if (worker.workCount > 0) // Permet d'éviter d'entrer inutilement dans une section critique + #ifdef NAZARA_CORE_SAFE + if (s_workerCount == 0) { + NazaraError("Task scheduler is not initialized"); + return; + } + #endif + + // On commence par vider la queue de chaque worker pour s'assurer qu'ils s'arrêtent + for (unsigned int i = 0; i < s_workerCount; ++i) + { + Worker& worker = s_workers[i]; + worker.running = false; + worker.workCount = 0; + EnterCriticalSection(&worker.queueMutex); - if (!worker.queue.empty()) // Nécessaire car le workCount peut être tombé à zéro juste avant l'entrée dans la section critique - { - task = worker.queue.front(); - worker.queue.pop(); - worker.workCount = worker.queue.size(); - } + + std::queue emptyQueue; + std::swap(worker.queue, emptyQueue); // Et on vide la queue (merci std::swap) + LeaveCriticalSection(&worker.queueMutex); + + // On réveille le worker pour qu'il sorte de la boucle et termine le thread + SetEvent(worker.wakeEvent); } - // Que faire quand vous n'avez plus de travail ? - if (!task) - task = StealTask(workerID); // Voler le travail des autres ! + // On attend que chaque thread se termine + WaitForMultipleObjects(s_workerCount, &s_workerThreads[0], true, INFINITE); - if (task) + // Et on libère les ressources + for (unsigned int i = 0; i < s_workerCount; ++i) { - // On exécute la tâche avant de la supprimer - task->Run(); - delete task; - } - else - { - SetEvent(s_doneEvents[workerID]); - WaitForSingleObject(worker.wakeEvent, INFINITE); + Worker& worker = s_workers[i]; + CloseHandle(s_doneEvents[i]); + CloseHandle(s_workerThreads[i]); + CloseHandle(worker.wakeEvent); + DeleteCriticalSection(&worker.queueMutex); } + + s_doneEvents.reset(); + s_workers.reset(); + s_workerThreads.reset(); + s_workerCount = 0; } - // Au cas où un thread attendrait sur WaitForTasks() pendant qu'un autre appellerait Uninitialize() - // Ça ne devrait pas arriver, mais comme ça ne coûte pas grand chose.. - SetEvent(s_doneEvents[workerID]); + void TaskSchedulerImpl::WaitForTasks() + { + #ifdef NAZARA_CORE_SAFE + if (s_workerCount == 0) + { + NazaraError("Task scheduler is not initialized"); + return; + } + #endif - return 0; + WaitForMultipleObjects(s_workerCount, &s_doneEvents[0], true, INFINITE); + } + + Functor* TaskSchedulerImpl::StealTask(unsigned int workerID) + { + bool shouldRetry; + do + { + shouldRetry = false; + for (unsigned int i = 0; i < s_workerCount; ++i) + { + // On ne vole pas la famille, ni soi-même. + if (i == workerID) + continue; + + Worker& worker = s_workers[i]; + + // Ce worker a-t-il encore des tâches dans sa file d'attente ? + if (worker.workCount > 0) + { + Functor* task = nullptr; + + // Est-ce qu'il utilise la queue maintenant ? + if (TryEnterCriticalSection(&worker.queueMutex)) + { + // Non, super ! Profitons-en pour essayer de lui voler un job + if (!worker.queue.empty()) // On vérifie que la queue n'est pas vide (peut avoir changé avant le verrouillage) + { + // Et hop, on vole la tâche + task = worker.queue.front(); + worker.queue.pop(); + worker.workCount = worker.queue.size(); + } + + LeaveCriticalSection(&worker.queueMutex); + } + else + shouldRetry = true; // Il est encore possible d'avoir un job + + // Avons-nous notre tâche ? + if (task) + return task; // Parfait, sortons de là ! + } + } + } + while (shouldRetry); + + // Bon à priori plus aucun worker n'a de tâche + return nullptr; + } + + unsigned int __stdcall TaskSchedulerImpl::WorkerProc(void* userdata) + { + unsigned int workerID = *reinterpret_cast(userdata); + SetEvent(s_doneEvents[workerID]); + + Worker& worker = s_workers[workerID]; + WaitForSingleObject(worker.wakeEvent, INFINITE); + + while (worker.running) + { + Functor* task = nullptr; + + if (worker.workCount > 0) // Permet d'éviter d'entrer inutilement dans une section critique + { + EnterCriticalSection(&worker.queueMutex); + if (!worker.queue.empty()) // Nécessaire car le workCount peut être tombé à zéro juste avant l'entrée dans la section critique + { + task = worker.queue.front(); + worker.queue.pop(); + worker.workCount = worker.queue.size(); + } + LeaveCriticalSection(&worker.queueMutex); + } + + // Que faire quand vous n'avez plus de travail ? + if (!task) + task = StealTask(workerID); // Voler le travail des autres ! + + if (task) + { + // On exécute la tâche avant de la supprimer + task->Run(); + delete task; + } + else + { + SetEvent(s_doneEvents[workerID]); + WaitForSingleObject(worker.wakeEvent, INFINITE); + } + } + + // Au cas où un thread attendrait sur WaitForTasks() pendant qu'un autre appellerait Uninitialize() + // Ça ne devrait pas arriver, mais comme ça ne coûte pas grand chose.. + SetEvent(s_doneEvents[workerID]); + + return 0; + } + + std::unique_ptr TaskSchedulerImpl::s_doneEvents; // Doivent être contigus + std::unique_ptr TaskSchedulerImpl::s_workers; + std::unique_ptr TaskSchedulerImpl::s_workerThreads; // Doivent être contigus + unsigned int TaskSchedulerImpl::s_workerCount; } - -std::unique_ptr NzTaskSchedulerImpl::s_doneEvents; // Doivent être contigus -std::unique_ptr NzTaskSchedulerImpl::s_workers; -std::unique_ptr NzTaskSchedulerImpl::s_workerThreads; // Doivent être contigus -unsigned int NzTaskSchedulerImpl::s_workerCount; diff --git a/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp b/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp index 0eb0fd6e1..3eccebb7c 100644 --- a/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp +++ b/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp @@ -14,35 +14,38 @@ #include #include -class NzTaskSchedulerImpl +namespace Nz { - public: - NzTaskSchedulerImpl() = delete; - ~NzTaskSchedulerImpl() = delete; + class TaskSchedulerImpl + { + public: + TaskSchedulerImpl() = delete; + ~TaskSchedulerImpl() = delete; - static bool Initialize(unsigned int workerCount); - static bool IsInitialized(); - static void Run(NzFunctor** tasks, unsigned int count); - static void Uninitialize(); - static void WaitForTasks(); + static bool Initialize(unsigned int workerCount); + static bool IsInitialized(); + static void Run(Functor** tasks, unsigned int count); + static void Uninitialize(); + static void WaitForTasks(); - private: - static NzFunctor* StealTask(unsigned int workerID); - static unsigned int __stdcall WorkerProc(void* userdata); + private: + static Functor* StealTask(unsigned int workerID); + static unsigned int __stdcall WorkerProc(void* userdata); - struct Worker - { - std::atomic_uint workCount; - std::queue queue; - CRITICAL_SECTION queueMutex; - HANDLE wakeEvent; - volatile bool running; - }; + struct Worker + { + std::atomic_uint workCount; + std::queue queue; + CRITICAL_SECTION queueMutex; + HANDLE wakeEvent; + volatile bool running; + }; - static std::unique_ptr s_doneEvents; // Doivent être contigus - static std::unique_ptr s_workers; - static std::unique_ptr s_workerThreads; // Doivent être contigus - static unsigned int s_workerCount; + static std::unique_ptr s_doneEvents; // Doivent être contigus + static std::unique_ptr s_workers; + static std::unique_ptr s_workerThreads; // Doivent être contigus + static unsigned int s_workerCount; }; +} #endif // NAZARA_TASKSCHEDULERIMPL_HPP diff --git a/src/Nazara/Core/Win32/ThreadImpl.cpp b/src/Nazara/Core/Win32/ThreadImpl.cpp index e654e9158..2d62b860d 100644 --- a/src/Nazara/Core/Win32/ThreadImpl.cpp +++ b/src/Nazara/Core/Win32/ThreadImpl.cpp @@ -8,40 +8,43 @@ #include #include -NzThreadImpl::NzThreadImpl(NzFunctor* functor) +namespace Nz { - m_handle = reinterpret_cast(_beginthreadex(nullptr, 0, &NzThreadImpl::ThreadProc, functor, 0, nullptr)); - if (!m_handle) - NazaraInternalError("Failed to create thread: " + NzError::GetLastSystemError()); -} - -void NzThreadImpl::Detach() -{ - // http://stackoverflow.com/questions/418742/is-it-reasonable-to-call-closehandle-on-a-thread-before-it-terminates - CloseHandle(m_handle); -} - -void NzThreadImpl::Join() -{ - WaitForSingleObject(m_handle, INFINITE); - CloseHandle(m_handle); -} - -unsigned int __stdcall NzThreadImpl::ThreadProc(void* userdata) -{ - NzFunctor* func = static_cast(userdata); - func->Run(); - delete func; - - /* - En C++, il vaut mieux retourner depuis la fonction que de quitter le thread explicitement - Source : http://msdn.microsoft.com/en-us/library/windows/desktop/ms682659(v=vs.85).aspx - */ - - return 0; -} - -void NzThreadImpl::Sleep(nzUInt32 time) -{ - ::Sleep(time); + ThreadImpl::ThreadImpl(Functor* functor) + { + m_handle = reinterpret_cast(_beginthreadex(nullptr, 0, &ThreadImpl::ThreadProc, functor, 0, nullptr)); + if (!m_handle) + NazaraInternalError("Failed to create thread: " + Error::GetLastSystemError()); + } + + void ThreadImpl::Detach() + { + // http://stackoverflow.com/questions/418742/is-it-reasonable-to-call-closehandle-on-a-thread-before-it-terminates + CloseHandle(m_handle); + } + + void ThreadImpl::Join() + { + WaitForSingleObject(m_handle, INFINITE); + CloseHandle(m_handle); + } + + unsigned int __stdcall ThreadImpl::ThreadProc(void* userdata) + { + Functor* func = static_cast(userdata); + func->Run(); + delete func; + + /* + En C++, il vaut mieux retourner depuis la fonction que de quitter le thread explicitement + Source : http://msdn.microsoft.com/en-us/library/windows/desktop/ms682659(v=vs.85).aspx + */ + + return 0; + } + + void ThreadImpl::Sleep(UInt32 time) + { + ::Sleep(time); + } } diff --git a/src/Nazara/Core/Win32/ThreadImpl.hpp b/src/Nazara/Core/Win32/ThreadImpl.hpp index 564f66db9..d036c124c 100644 --- a/src/Nazara/Core/Win32/ThreadImpl.hpp +++ b/src/Nazara/Core/Win32/ThreadImpl.hpp @@ -12,22 +12,25 @@ #include #include -struct NzFunctor; - -class NzThreadImpl +namespace Nz { - public: - NzThreadImpl(NzFunctor* threadFunc); + struct Functor; - void Detach(); - void Join(); + class ThreadImpl + { + public: + ThreadImpl(Functor* threadFunc); - static void Sleep(nzUInt32 time); + void Detach(); + void Join(); - private: - static unsigned int __stdcall ThreadProc(void* userdata); + static void Sleep(UInt32 time); - HANDLE m_handle; -}; + private: + static unsigned int __stdcall ThreadProc(void* userdata); + + HANDLE m_handle; + }; +} #endif // NAZARA_THREADIMPL_HPP diff --git a/src/Nazara/Core/Win32/Time.cpp b/src/Nazara/Core/Win32/Time.cpp index c4802a2f2..9ed58bc46 100644 --- a/src/Nazara/Core/Win32/Time.cpp +++ b/src/Nazara/Core/Win32/Time.cpp @@ -5,21 +5,24 @@ #include #include -time_t NzFileTimeToTime(FILETIME* time) +namespace Nz { - SYSTEMTIME stUTC, stLocal; + time_t FileTimeToTime(FILETIME* time) + { + SYSTEMTIME stUTC, stLocal; - FileTimeToSystemTime(time, &stUTC); - SystemTimeToTzSpecificLocalTime(nullptr, &stUTC, &stLocal); + FileTimeToSystemTime(time, &stUTC); + SystemTimeToTzSpecificLocalTime(nullptr, &stUTC, &stLocal); - std::tm timeinfo; - timeinfo.tm_sec = stLocal.wSecond; - timeinfo.tm_min = stLocal.wMinute; - timeinfo.tm_hour = stLocal.wHour; - timeinfo.tm_mday = stLocal.wDay; - timeinfo.tm_mon = stLocal.wMonth-1; - timeinfo.tm_year = stLocal.wYear-1900; - timeinfo.tm_isdst = -1; + std::tm timeinfo; + timeinfo.tm_sec = stLocal.wSecond; + timeinfo.tm_min = stLocal.wMinute; + timeinfo.tm_hour = stLocal.wHour; + timeinfo.tm_mday = stLocal.wDay; + timeinfo.tm_mon = stLocal.wMonth-1; + timeinfo.tm_year = stLocal.wYear-1900; + timeinfo.tm_isdst = -1; - return std::mktime(&timeinfo); + return std::mktime(&timeinfo); + } } diff --git a/src/Nazara/Core/Win32/Time.hpp b/src/Nazara/Core/Win32/Time.hpp index 4c374ae76..a0ba7da36 100644 --- a/src/Nazara/Core/Win32/Time.hpp +++ b/src/Nazara/Core/Win32/Time.hpp @@ -11,6 +11,9 @@ #include #include -time_t NzFileTimeToTime(FILETIME* time); +namespace Nz +{ + time_t FileTimeToTime(FILETIME* time); +} #endif // NAZARA_WINDOWS_TIME_HPP diff --git a/src/Nazara/Graphics/AbstractBackground.cpp b/src/Nazara/Graphics/AbstractBackground.cpp index 510663c39..628819edd 100644 --- a/src/Nazara/Graphics/AbstractBackground.cpp +++ b/src/Nazara/Graphics/AbstractBackground.cpp @@ -5,6 +5,9 @@ #include #include -NzAbstractBackground::~NzAbstractBackground() = default; +namespace Nz +{ + AbstractBackground::~AbstractBackground() = default; -NzBackgroundLibrary::LibraryMap NzAbstractBackground::s_library; + BackgroundLibrary::LibraryMap AbstractBackground::s_library; +} diff --git a/src/Nazara/Graphics/AbstractRenderQueue.cpp b/src/Nazara/Graphics/AbstractRenderQueue.cpp index df86300f0..d00816f85 100644 --- a/src/Nazara/Graphics/AbstractRenderQueue.cpp +++ b/src/Nazara/Graphics/AbstractRenderQueue.cpp @@ -5,28 +5,31 @@ #include #include -NzAbstractRenderQueue::~NzAbstractRenderQueue() = default; - -void NzAbstractRenderQueue::AddDirectionalLight(const DirectionalLight& light) +namespace Nz { - directionalLights.push_back(light); -} + AbstractRenderQueue::~AbstractRenderQueue() = default; -void NzAbstractRenderQueue::AddPointLight(const PointLight& light) -{ - pointLights.push_back(light); -} + void AbstractRenderQueue::AddDirectionalLight(const DirectionalLight& light) + { + directionalLights.push_back(light); + } -void NzAbstractRenderQueue::AddSpotLight(const SpotLight& light) -{ - spotLights.push_back(light); -} + void AbstractRenderQueue::AddPointLight(const PointLight& light) + { + pointLights.push_back(light); + } -void NzAbstractRenderQueue::Clear(bool fully) -{ - NazaraUnused(fully); + void AbstractRenderQueue::AddSpotLight(const SpotLight& light) + { + spotLights.push_back(light); + } - directionalLights.clear(); - pointLights.clear(); - spotLights.clear(); + void AbstractRenderQueue::Clear(bool fully) + { + NazaraUnused(fully); + + directionalLights.clear(); + pointLights.clear(); + spotLights.clear(); + } } diff --git a/src/Nazara/Graphics/AbstractRenderTechnique.cpp b/src/Nazara/Graphics/AbstractRenderTechnique.cpp index c338091b8..bb152b228 100644 --- a/src/Nazara/Graphics/AbstractRenderTechnique.cpp +++ b/src/Nazara/Graphics/AbstractRenderTechnique.cpp @@ -8,35 +8,38 @@ #include #include -NzAbstractRenderTechnique::NzAbstractRenderTechnique() +namespace Nz { - #ifdef NAZARA_DEBUG - if (!NzRenderer::IsInitialized()) + AbstractRenderTechnique::AbstractRenderTechnique() { - NazaraError("NazaraRenderer is not initialized"); - return; + #ifdef NAZARA_DEBUG + if (!Renderer::IsInitialized()) + { + NazaraError("NazaraRenderer is not initialized"); + return; + } + #endif + + m_instancingEnabled = Renderer::HasCapability(RendererCap_Instancing); } - #endif - m_instancingEnabled = NzRenderer::HasCapability(nzRendererCap_Instancing); -} - -NzAbstractRenderTechnique::~NzAbstractRenderTechnique() = default; - -void NzAbstractRenderTechnique::EnableInstancing(bool instancing) -{ - if (NzRenderer::HasCapability(nzRendererCap_Instancing)) - m_instancingEnabled = instancing; - else if (instancing) - NazaraError("NazaraRenderer does not support instancing"); -} - -NzString NzAbstractRenderTechnique::GetName() const -{ - return NzRenderTechniques::ToString(GetType()); -} - -bool NzAbstractRenderTechnique::IsInstancingEnabled() const -{ - return m_instancingEnabled; + AbstractRenderTechnique::~AbstractRenderTechnique() = default; + + void AbstractRenderTechnique::EnableInstancing(bool instancing) + { + if (Renderer::HasCapability(RendererCap_Instancing)) + m_instancingEnabled = instancing; + else if (instancing) + NazaraError("NazaraRenderer does not support instancing"); + } + + String AbstractRenderTechnique::GetName() const + { + return RenderTechniques::ToString(GetType()); + } + + bool AbstractRenderTechnique::IsInstancingEnabled() const + { + return m_instancingEnabled; + } } diff --git a/src/Nazara/Graphics/AbstractViewer.cpp b/src/Nazara/Graphics/AbstractViewer.cpp index 58feebfa7..cc9a4b96a 100644 --- a/src/Nazara/Graphics/AbstractViewer.cpp +++ b/src/Nazara/Graphics/AbstractViewer.cpp @@ -5,4 +5,7 @@ #include #include -NzAbstractViewer::~NzAbstractViewer() = default; +namespace Nz +{ + AbstractViewer::~AbstractViewer() = default; +} diff --git a/src/Nazara/Graphics/Billboard.cpp b/src/Nazara/Graphics/Billboard.cpp index dbd9d3ad8..1e9de412c 100644 --- a/src/Nazara/Graphics/Billboard.cpp +++ b/src/Nazara/Graphics/Billboard.cpp @@ -10,19 +10,22 @@ #include #include -void NzBillboard::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const +namespace Nz { - if (!m_material) - return; + void Billboard::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const + { + if (!m_material) + return; - renderQueue->AddBillboard(m_material, instanceData.transformMatrix.GetTranslation(), m_size, m_sinCos, m_color); + renderQueue->AddBillboard(m_material, instanceData.transformMatrix.GetTranslation(), m_size, m_sinCos, m_color); + } + + void Billboard::MakeBoundingVolume() const + { + constexpr float sqrt2 = float(M_SQRT2); + + m_boundingVolume.Set(Vector3f(0.f), sqrt2*m_size.x*Vector3f::Right() + sqrt2*m_size.y*Vector3f::Down()); + } + + BillboardLibrary::LibraryMap Billboard::s_library; } - -void NzBillboard::MakeBoundingVolume() const -{ - constexpr float sqrt2 = float(M_SQRT2); - - m_boundingVolume.Set(NzVector3f(0.f), sqrt2*m_size.x*NzVector3f::Right() + sqrt2*m_size.y*NzVector3f::Down()); -} - -NzBillboardLibrary::LibraryMap NzBillboard::s_library; diff --git a/src/Nazara/Graphics/ColorBackground.cpp b/src/Nazara/Graphics/ColorBackground.cpp index fa29d005b..76f717858 100644 --- a/src/Nazara/Graphics/ColorBackground.cpp +++ b/src/Nazara/Graphics/ColorBackground.cpp @@ -7,64 +7,66 @@ #include #include -namespace +namespace Nz { - NzRenderStates BuildRenderStates() + namespace { - NzRenderStates states; - states.depthFunc = nzRendererComparison_Equal; - states.faceCulling = nzFaceSide_Back; - states.parameters[nzRendererParameter_DepthBuffer] = true; - states.parameters[nzRendererParameter_DepthWrite] = false; - states.parameters[nzRendererParameter_FaceCulling] = true; + RenderStates BuildRenderStates() + { + RenderStates states; + states.depthFunc = RendererComparison_Equal; + states.faceCulling = FaceSide_Back; + states.parameters[RendererParameter_DepthBuffer] = true; + states.parameters[RendererParameter_DepthWrite] = false; + states.parameters[RendererParameter_FaceCulling] = true; - return states; + return states; + } + } + + ColorBackground::ColorBackground(const Color& color) : + m_color(color) + { + m_uberShader = UberShaderLibrary::Get("Basic"); + + ParameterList list; + list.SetParameter("UNIFORM_VERTEX_DEPTH", true); + m_uberShaderInstance = m_uberShader->Get(list); + + const Shader* shader = m_uberShaderInstance->GetShader(); + m_materialDiffuseUniform = shader->GetUniformLocation("MaterialDiffuse"); + m_vertexDepthUniform = shader->GetUniformLocation("VertexDepth"); + } + + void ColorBackground::Draw(const AbstractViewer* viewer) const + { + NazaraUnused(viewer); + + static RenderStates states(BuildRenderStates()); + + Renderer::SetRenderStates(states); + + m_uberShaderInstance->Activate(); + + const Shader* shader = m_uberShaderInstance->GetShader(); + shader->SendColor(m_materialDiffuseUniform, m_color); + shader->SendFloat(m_vertexDepthUniform, 1.f); + + Renderer::DrawFullscreenQuad(); + } + + BackgroundType ColorBackground::GetBackgroundType() const + { + return BackgroundType_Color; + } + + Color ColorBackground::GetColor() const + { + return m_color; + } + + void ColorBackground::SetColor(const Color& color) + { + m_color = color; } } - -NzColorBackground::NzColorBackground(const NzColor& color) : -m_color(color) -{ - m_uberShader = NzUberShaderLibrary::Get("Basic"); - - NzParameterList list; - list.SetParameter("UNIFORM_VERTEX_DEPTH", true); - m_uberShaderInstance = m_uberShader->Get(list); - - const NzShader* shader = m_uberShaderInstance->GetShader(); - m_materialDiffuseUniform = shader->GetUniformLocation("MaterialDiffuse"); - m_vertexDepthUniform = shader->GetUniformLocation("VertexDepth"); -} - -void NzColorBackground::Draw(const NzAbstractViewer* viewer) const -{ - NazaraUnused(viewer); - - static NzRenderStates states(BuildRenderStates()); - - NzRenderer::SetRenderStates(states); - - m_uberShaderInstance->Activate(); - - const NzShader* shader = m_uberShaderInstance->GetShader(); - shader->SendColor(m_materialDiffuseUniform, m_color); - shader->SendFloat(m_vertexDepthUniform, 1.f); - - NzRenderer::DrawFullscreenQuad(); -} - -nzBackgroundType NzColorBackground::GetBackgroundType() const -{ - return nzBackgroundType_Color; -} - -NzColor NzColorBackground::GetColor() const -{ - return m_color; -} - -void NzColorBackground::SetColor(const NzColor& color) -{ - m_color = color; -} - diff --git a/src/Nazara/Graphics/DeferredBloomPass.cpp b/src/Nazara/Graphics/DeferredBloomPass.cpp index aab4251a3..0fc80e750 100644 --- a/src/Nazara/Graphics/DeferredBloomPass.cpp +++ b/src/Nazara/Graphics/DeferredBloomPass.cpp @@ -7,161 +7,164 @@ #include #include -NzDeferredBloomPass::NzDeferredBloomPass() : -m_uniformUpdated(false), -m_brightLuminance(0.8f), -m_brightMiddleGrey(0.5f), -m_brightThreshold(0.8f), -m_blurPassCount(5) +namespace Nz { - m_bilinearSampler.SetAnisotropyLevel(1); - m_bilinearSampler.SetFilterMode(nzSamplerFilter_Bilinear); - m_bilinearSampler.SetWrapMode(nzSamplerWrap_Clamp); - - m_bloomBrightShader = NzShaderLibrary::Get("DeferredBloomBright"); - m_bloomFinalShader = NzShaderLibrary::Get("DeferredBloomFinal"); - m_bloomStates.parameters[nzRendererParameter_DepthBuffer] = false; - m_gaussianBlurShader = NzShaderLibrary::Get("DeferredGaussianBlur"); - m_gaussianBlurShaderFilterLocation = m_gaussianBlurShader->GetUniformLocation("Filter"); - - for (unsigned int i = 0; i < 2; ++i) - m_bloomTextures[i] = NzTexture::New(); -} - -NzDeferredBloomPass::~NzDeferredBloomPass() = default; - -unsigned int NzDeferredBloomPass::GetBlurPassCount() const -{ - return m_blurPassCount; -} - -float NzDeferredBloomPass::GetBrightLuminance() const -{ - return m_brightLuminance; -} - -float NzDeferredBloomPass::GetBrightMiddleGrey() const -{ - return m_brightMiddleGrey; -} - -float NzDeferredBloomPass::GetBrightThreshold() const -{ - return m_brightThreshold; -} - -NzTexture* NzDeferredBloomPass::GetTexture(unsigned int i) const -{ - #if NAZARA_GRAPHICS_SAFE - if (i >= 2) + DeferredBloomPass::DeferredBloomPass() : + m_uniformUpdated(false), + m_brightLuminance(0.8f), + m_brightMiddleGrey(0.5f), + m_brightThreshold(0.8f), + m_blurPassCount(5) { - NazaraError("Texture index out of range (" + NzString::Number(i) + " >= 2)"); - return nullptr; - } - #endif + m_bilinearSampler.SetAnisotropyLevel(1); + m_bilinearSampler.SetFilterMode(SamplerFilter_Bilinear); + m_bilinearSampler.SetWrapMode(SamplerWrap_Clamp); - return m_bloomTextures[i]; -} + m_bloomBrightShader = ShaderLibrary::Get("DeferredBloomBright"); + m_bloomFinalShader = ShaderLibrary::Get("DeferredBloomFinal"); + m_bloomStates.parameters[RendererParameter_DepthBuffer] = false; + m_gaussianBlurShader = ShaderLibrary::Get("DeferredGaussianBlur"); + m_gaussianBlurShaderFilterLocation = m_gaussianBlurShader->GetUniformLocation("Filter"); -bool NzDeferredBloomPass::Process(const NzSceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const -{ - NazaraUnused(sceneData); - - NzRenderer::SetRenderStates(m_bloomStates); - NzRenderer::SetTextureSampler(0, m_bilinearSampler); - NzRenderer::SetTextureSampler(1, m_bilinearSampler); - - m_workRTT->SetColorTarget(firstWorkTexture); - NzRenderer::SetTarget(m_workRTT); - NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y)); - - NzRenderer::SetShader(m_bloomBrightShader); - if (!m_uniformUpdated) - { - m_bloomBrightShader->SendFloat(m_bloomBrightShader->GetUniformLocation("BrightLuminance"), m_brightLuminance); - m_bloomBrightShader->SendFloat(m_bloomBrightShader->GetUniformLocation("BrightMiddleGrey"), m_brightMiddleGrey); - m_bloomBrightShader->SendFloat(m_bloomBrightShader->GetUniformLocation("BrightThreshold"), m_brightThreshold); - - m_uniformUpdated = true; + for (unsigned int i = 0; i < 2; ++i) + m_bloomTextures[i] = Texture::New(); } - NzRenderer::SetTexture(0, m_workTextures[secondWorkTexture]); - NzRenderer::DrawFullscreenQuad(); + DeferredBloomPass::~DeferredBloomPass() = default; - NzRenderer::SetTarget(&m_bloomRTT); - NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x/8, m_dimensions.y/8)); - - NzRenderer::SetShader(m_gaussianBlurShader); - - for (unsigned int i = 0; i < m_blurPassCount; ++i) + unsigned int DeferredBloomPass::GetBlurPassCount() const { - m_bloomRTT.SetColorTarget(0); // bloomTextureA - - m_gaussianBlurShader->SendVector(m_gaussianBlurShaderFilterLocation, NzVector2f(1.f, 0.f)); - - NzRenderer::SetTexture(0, (i == 0) ? m_workTextures[firstWorkTexture] : static_cast(m_bloomTextures[1])); - NzRenderer::DrawFullscreenQuad(); - - m_bloomRTT.SetColorTarget(1); // bloomTextureB - - m_gaussianBlurShader->SendVector(m_gaussianBlurShaderFilterLocation, NzVector2f(0.f, 1.f)); - - NzRenderer::SetTexture(0, m_bloomTextures[0]); - NzRenderer::DrawFullscreenQuad(); + return m_blurPassCount; } - m_workRTT->SetColorTarget(firstWorkTexture); - NzRenderer::SetTarget(m_workRTT); - NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y)); - - NzRenderer::SetShader(m_bloomFinalShader); - NzRenderer::SetTexture(0, m_bloomTextures[1]); - NzRenderer::SetTexture(1, m_workTextures[secondWorkTexture]); - NzRenderer::DrawFullscreenQuad(); - - return true; -} - -bool NzDeferredBloomPass::Resize(const NzVector2ui& dimensions) -{ - NzDeferredRenderPass::Resize(dimensions); - - m_bloomRTT.Create(true); - for (unsigned int i = 0; i < 2; ++i) + float DeferredBloomPass::GetBrightLuminance() const { - m_bloomTextures[i]->Create(nzImageType_2D, nzPixelFormat_RGBA8, dimensions.x/8, dimensions.y/8); - m_bloomRTT.AttachTexture(nzAttachmentPoint_Color, i, m_bloomTextures[i]); - } - m_bloomRTT.Unlock(); - - if (!m_bloomRTT.IsComplete()) - { - NazaraError("Incomplete RTT"); - return false; + return m_brightLuminance; } - return true; -} + float DeferredBloomPass::GetBrightMiddleGrey() const + { + return m_brightMiddleGrey; + } -void NzDeferredBloomPass::SetBlurPassCount(unsigned int passCount) -{ - m_blurPassCount = passCount; // N'est pas une uniforme -} + float DeferredBloomPass::GetBrightThreshold() const + { + return m_brightThreshold; + } -void NzDeferredBloomPass::SetBrightLuminance(float luminance) -{ - m_brightLuminance = luminance; - m_uniformUpdated = false; -} + Texture* DeferredBloomPass::GetTexture(unsigned int i) const + { + #if NAZARA_GRAPHICS_SAFE + if (i >= 2) + { + NazaraError("Texture index out of range (" + String::Number(i) + " >= 2)"); + return nullptr; + } + #endif -void NzDeferredBloomPass::SetBrightMiddleGrey(float middleGrey) -{ - m_brightMiddleGrey = middleGrey; - m_uniformUpdated = false; -} + return m_bloomTextures[i]; + } -void NzDeferredBloomPass::SetBrightThreshold(float threshold) -{ - m_brightThreshold = threshold; - m_uniformUpdated = false; + bool DeferredBloomPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const + { + NazaraUnused(sceneData); + + Renderer::SetRenderStates(m_bloomStates); + Renderer::SetTextureSampler(0, m_bilinearSampler); + Renderer::SetTextureSampler(1, m_bilinearSampler); + + m_workRTT->SetColorTarget(firstWorkTexture); + Renderer::SetTarget(m_workRTT); + Renderer::SetViewport(Recti(0, 0, m_dimensions.x, m_dimensions.y)); + + Renderer::SetShader(m_bloomBrightShader); + if (!m_uniformUpdated) + { + m_bloomBrightShader->SendFloat(m_bloomBrightShader->GetUniformLocation("BrightLuminance"), m_brightLuminance); + m_bloomBrightShader->SendFloat(m_bloomBrightShader->GetUniformLocation("BrightMiddleGrey"), m_brightMiddleGrey); + m_bloomBrightShader->SendFloat(m_bloomBrightShader->GetUniformLocation("BrightThreshold"), m_brightThreshold); + + m_uniformUpdated = true; + } + + Renderer::SetTexture(0, m_workTextures[secondWorkTexture]); + Renderer::DrawFullscreenQuad(); + + Renderer::SetTarget(&m_bloomRTT); + Renderer::SetViewport(Recti(0, 0, m_dimensions.x/8, m_dimensions.y/8)); + + Renderer::SetShader(m_gaussianBlurShader); + + for (unsigned int i = 0; i < m_blurPassCount; ++i) + { + m_bloomRTT.SetColorTarget(0); // bloomTextureA + + m_gaussianBlurShader->SendVector(m_gaussianBlurShaderFilterLocation, Vector2f(1.f, 0.f)); + + Renderer::SetTexture(0, (i == 0) ? m_workTextures[firstWorkTexture] : static_cast(m_bloomTextures[1])); + Renderer::DrawFullscreenQuad(); + + m_bloomRTT.SetColorTarget(1); // bloomTextureB + + m_gaussianBlurShader->SendVector(m_gaussianBlurShaderFilterLocation, Vector2f(0.f, 1.f)); + + Renderer::SetTexture(0, m_bloomTextures[0]); + Renderer::DrawFullscreenQuad(); + } + + m_workRTT->SetColorTarget(firstWorkTexture); + Renderer::SetTarget(m_workRTT); + Renderer::SetViewport(Recti(0, 0, m_dimensions.x, m_dimensions.y)); + + Renderer::SetShader(m_bloomFinalShader); + Renderer::SetTexture(0, m_bloomTextures[1]); + Renderer::SetTexture(1, m_workTextures[secondWorkTexture]); + Renderer::DrawFullscreenQuad(); + + return true; + } + + bool DeferredBloomPass::Resize(const Vector2ui& dimensions) + { + DeferredRenderPass::Resize(dimensions); + + m_bloomRTT.Create(true); + for (unsigned int i = 0; i < 2; ++i) + { + m_bloomTextures[i]->Create(ImageType_2D, PixelFormatType_RGBA8, dimensions.x/8, dimensions.y/8); + m_bloomRTT.AttachTexture(AttachmentPoint_Color, i, m_bloomTextures[i]); + } + m_bloomRTT.Unlock(); + + if (!m_bloomRTT.IsComplete()) + { + NazaraError("Incomplete RTT"); + return false; + } + + return true; + } + + void DeferredBloomPass::SetBlurPassCount(unsigned int passCount) + { + m_blurPassCount = passCount; // N'est pas une uniforme + } + + void DeferredBloomPass::SetBrightLuminance(float luminance) + { + m_brightLuminance = luminance; + m_uniformUpdated = false; + } + + void DeferredBloomPass::SetBrightMiddleGrey(float middleGrey) + { + m_brightMiddleGrey = middleGrey; + m_uniformUpdated = false; + } + + void DeferredBloomPass::SetBrightThreshold(float threshold) + { + m_brightThreshold = threshold; + m_uniformUpdated = false; + } } diff --git a/src/Nazara/Graphics/DeferredDOFPass.cpp b/src/Nazara/Graphics/DeferredDOFPass.cpp index 330b24737..f29529749 100644 --- a/src/Nazara/Graphics/DeferredDOFPass.cpp +++ b/src/Nazara/Graphics/DeferredDOFPass.cpp @@ -9,174 +9,177 @@ #include #include -namespace +namespace Nz { - // http://digitalerr0r.wordpress.com/2009/05/16/xna-shader-programming-tutorial-20-depth-of-field/ - NzShaderRef BuildDepthOfFieldShader() + namespace { - const char* fragmentSource = - "#version 140\n" - - "out vec4 RenderTarget0;\n" - - "uniform sampler2D BlurTexture;\n" - "uniform sampler2D ColorTexture;\n" - "uniform sampler2D GBuffer1;\n" - "uniform vec2 InvTargetSize;" "\n" - - "float Distance = 30.0;\n" - "float Range = 10.0;\n" - "float Near = 0.1;\n" - "float Far = (1000.0) / (1000.0 - 0.1);\n" - //"float Far = 50.0;\n" - - "void main()\n" - "{\n" - "vec2 texCoord = gl_FragCoord.xy * InvTargetSize;\n" - - "// Get our original pixel from ColorMap\n" - "vec3 color = textureLod(ColorTexture, texCoord, 0.0).rgb;\n" - - "// Get our bloom pixel from bloom texture\n" - "vec3 blur = textureLod(BlurTexture, texCoord, 0.0).rgb;\n" - - "float depth = textureLod(GBuffer1, texCoord, 0.0).w;\n" - "depth = (2.0 * 0.1) / (1000.0 + 0.1 - depth * (1000.0 - 0.1));" - "depth = 1.0 - depth;\n" - - "float fSceneZ = ( -Near * Far ) / ( depth - Far);\n" - "float blurFactor = clamp(abs(fSceneZ - Distance)/Range, 0.0, 1.0);\n" - - "RenderTarget0 = vec4(mix(color, blur, blurFactor), 1.0);\n" - "}\n"; - - const char* vertexSource = - "#version 140\n" - - "in vec3 VertexPosition;\n" - - "void main()\n" - "{\n" - "\t" "gl_Position = vec4(VertexPosition, 1.0);" "\n" - "}\n"; - - ///TODO: Remplacer ça par des ShaderNode - NzShaderRef shader = NzShader::New(); - if (!shader->Create()) + // http://digitalerr0r.wordpress.com/2009/05/16/xna-shader-programming-tutorial-20-depth-of-field/ + ShaderRef BuildDepthOfFieldShader() { - NazaraError("Failed to load create shader"); - return nullptr; + const char* fragmentSource = + "#version 140\n" + + "out vec4 RenderTarget0;\n" + + "uniform sampler2D BlurTexture;\n" + "uniform sampler2D ColorTexture;\n" + "uniform sampler2D GBuffer1;\n" + "uniform vec2 InvTargetSize;" "\n" + + "float Distance = 30.0;\n" + "float Range = 10.0;\n" + "float Near = 0.1;\n" + "float Far = (1000.0) / (1000.0 - 0.1);\n" + //"float Far = 50.0;\n" + + "void main()\n" + "{\n" + "vec2 texCoord = gl_FragCoord.xy * InvTargetSize;\n" + + "// Get our original pixel from ColorMap\n" + "vec3 color = textureLod(ColorTexture, texCoord, 0.0).rgb;\n" + + "// Get our bloom pixel from bloom texture\n" + "vec3 blur = textureLod(BlurTexture, texCoord, 0.0).rgb;\n" + + "float depth = textureLod(GBuffer1, texCoord, 0.0).w;\n" + "depth = (2.0 * 0.1) / (1000.0 + 0.1 - depth * (1000.0 - 0.1));" + "depth = 1.0 - depth;\n" + + "float fSceneZ = ( -Near * Far ) / ( depth - Far);\n" + "float blurFactor = clamp(abs(fSceneZ - Distance)/Range, 0.0, 1.0);\n" + + "RenderTarget0 = vec4(mix(color, blur, blurFactor), 1.0);\n" + "}\n"; + + const char* vertexSource = + "#version 140\n" + + "in vec3 VertexPosition;\n" + + "void main()\n" + "{\n" + "\t" "gl_Position = vec4(VertexPosition, 1.0);" "\n" + "}\n"; + + ///TODO: Remplacer ça par des ShaderNode + ShaderRef shader = Shader::New(); + if (!shader->Create()) + { + NazaraError("Failed to load create shader"); + return nullptr; + } + + if (!shader->AttachStageFromSource(ShaderStageType_Fragment, fragmentSource)) + { + NazaraError("Failed to load fragment shader"); + return nullptr; + } + + if (!shader->AttachStageFromSource(ShaderStageType_Vertex, vertexSource)) + { + NazaraError("Failed to load vertex shader"); + return nullptr; + } + + if (!shader->Link()) + { + NazaraError("Failed to link shader"); + return nullptr; + } + + return shader; } - - if (!shader->AttachStageFromSource(nzShaderStage_Fragment, fragmentSource)) - { - NazaraError("Failed to load fragment shader"); - return nullptr; - } - - if (!shader->AttachStageFromSource(nzShaderStage_Vertex, vertexSource)) - { - NazaraError("Failed to load vertex shader"); - return nullptr; - } - - if (!shader->Link()) - { - NazaraError("Failed to link shader"); - return nullptr; - } - - return shader; - } -} - -NzDeferredDOFPass::NzDeferredDOFPass() -{ - m_dofShader = BuildDepthOfFieldShader(); - m_dofShader->SendInteger(m_dofShader->GetUniformLocation("ColorTexture"), 0); - m_dofShader->SendInteger(m_dofShader->GetUniformLocation("BlurTexture"), 1); - m_dofShader->SendInteger(m_dofShader->GetUniformLocation("GBuffer1"), 2); - - m_gaussianBlurShader = NzShaderLibrary::Get("DeferredGaussianBlur"); - m_gaussianBlurShaderFilterLocation = m_gaussianBlurShader->GetUniformLocation("Filter"); - - for (unsigned int i = 0; i < 2; ++i) - m_dofTextures[i] = NzTexture::New(); - - m_bilinearSampler.SetAnisotropyLevel(1); - m_bilinearSampler.SetFilterMode(nzSamplerFilter_Bilinear); - m_bilinearSampler.SetWrapMode(nzSamplerWrap_Clamp); - - m_pointSampler.SetAnisotropyLevel(1); - m_pointSampler.SetFilterMode(nzSamplerFilter_Nearest); - m_pointSampler.SetWrapMode(nzSamplerWrap_Clamp); - - m_states.parameters[nzRendererParameter_DepthBuffer] = false; -} - -NzDeferredDOFPass::~NzDeferredDOFPass() = default; - -bool NzDeferredDOFPass::Process(const NzSceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const -{ - NazaraUnused(sceneData); - - NzRenderer::SetTextureSampler(0, m_pointSampler); - NzRenderer::SetTextureSampler(1, m_bilinearSampler); - NzRenderer::SetTextureSampler(2, m_pointSampler); - - NzRenderer::SetTarget(&m_dofRTT); - NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x/4, m_dimensions.y/4)); - - NzRenderer::SetShader(m_gaussianBlurShader); - - const unsigned int dofBlurPass = 2; - for (unsigned int i = 0; i < dofBlurPass; ++i) - { - m_dofRTT.SetColorTarget(0); // dofTextureA - - m_gaussianBlurShader->SendVector(m_gaussianBlurShaderFilterLocation, NzVector2f(1.f, 0.f)); - - NzRenderer::SetTexture(0, (i == 0) ? m_workTextures[secondWorkTexture] : static_cast(m_dofTextures[1])); - NzRenderer::DrawFullscreenQuad(); - - m_dofRTT.SetColorTarget(1); // dofTextureB - - m_gaussianBlurShader->SendVector(m_gaussianBlurShaderFilterLocation, NzVector2f(0.f, 1.f)); - - NzRenderer::SetTexture(0, m_dofTextures[0]); - NzRenderer::DrawFullscreenQuad(); } - m_workRTT->SetColorTarget(firstWorkTexture); - NzRenderer::SetTarget(m_workRTT); - NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y)); - - NzRenderer::SetShader(m_dofShader); - NzRenderer::SetTexture(0, m_workTextures[secondWorkTexture]); - NzRenderer::SetTexture(1, m_dofTextures[1]); - NzRenderer::SetTexture(2, m_GBuffer[1]); - NzRenderer::DrawFullscreenQuad(); - - return true; -} - -bool NzDeferredDOFPass::Resize(const NzVector2ui& dimensions) -{ - NzDeferredRenderPass::Resize(dimensions); - - m_dofRTT.Create(true); - for (unsigned int i = 0; i < 2; ++i) + DeferredDOFPass::DeferredDOFPass() { - m_dofTextures[i]->Create(nzImageType_2D, nzPixelFormat_RGBA8, dimensions.x/4, dimensions.y/4); - m_dofRTT.AttachTexture(nzAttachmentPoint_Color, i, m_dofTextures[i]); - } - m_dofRTT.Unlock(); + m_dofShader = BuildDepthOfFieldShader(); + m_dofShader->SendInteger(m_dofShader->GetUniformLocation("ColorTexture"), 0); + m_dofShader->SendInteger(m_dofShader->GetUniformLocation("BlurTexture"), 1); + m_dofShader->SendInteger(m_dofShader->GetUniformLocation("GBuffer1"), 2); - if (!m_dofRTT.IsComplete()) - { - NazaraError("Incomplete RTT"); - return false; + m_gaussianBlurShader = ShaderLibrary::Get("DeferredGaussianBlur"); + m_gaussianBlurShaderFilterLocation = m_gaussianBlurShader->GetUniformLocation("Filter"); + + for (unsigned int i = 0; i < 2; ++i) + m_dofTextures[i] = Texture::New(); + + m_bilinearSampler.SetAnisotropyLevel(1); + m_bilinearSampler.SetFilterMode(SamplerFilter_Bilinear); + m_bilinearSampler.SetWrapMode(SamplerWrap_Clamp); + + m_pointSampler.SetAnisotropyLevel(1); + m_pointSampler.SetFilterMode(SamplerFilter_Nearest); + m_pointSampler.SetWrapMode(SamplerWrap_Clamp); + + m_states.parameters[RendererParameter_DepthBuffer] = false; } - return true; + DeferredDOFPass::~DeferredDOFPass() = default; + + bool DeferredDOFPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const + { + NazaraUnused(sceneData); + + Renderer::SetTextureSampler(0, m_pointSampler); + Renderer::SetTextureSampler(1, m_bilinearSampler); + Renderer::SetTextureSampler(2, m_pointSampler); + + Renderer::SetTarget(&m_dofRTT); + Renderer::SetViewport(Recti(0, 0, m_dimensions.x/4, m_dimensions.y/4)); + + Renderer::SetShader(m_gaussianBlurShader); + + const unsigned int dofBlurPass = 2; + for (unsigned int i = 0; i < dofBlurPass; ++i) + { + m_dofRTT.SetColorTarget(0); // dofTextureA + + m_gaussianBlurShader->SendVector(m_gaussianBlurShaderFilterLocation, Vector2f(1.f, 0.f)); + + Renderer::SetTexture(0, (i == 0) ? m_workTextures[secondWorkTexture] : static_cast(m_dofTextures[1])); + Renderer::DrawFullscreenQuad(); + + m_dofRTT.SetColorTarget(1); // dofTextureB + + m_gaussianBlurShader->SendVector(m_gaussianBlurShaderFilterLocation, Vector2f(0.f, 1.f)); + + Renderer::SetTexture(0, m_dofTextures[0]); + Renderer::DrawFullscreenQuad(); + } + + m_workRTT->SetColorTarget(firstWorkTexture); + Renderer::SetTarget(m_workRTT); + Renderer::SetViewport(Recti(0, 0, m_dimensions.x, m_dimensions.y)); + + Renderer::SetShader(m_dofShader); + Renderer::SetTexture(0, m_workTextures[secondWorkTexture]); + Renderer::SetTexture(1, m_dofTextures[1]); + Renderer::SetTexture(2, m_GBuffer[1]); + Renderer::DrawFullscreenQuad(); + + return true; + } + + bool DeferredDOFPass::Resize(const Vector2ui& dimensions) + { + DeferredRenderPass::Resize(dimensions); + + m_dofRTT.Create(true); + for (unsigned int i = 0; i < 2; ++i) + { + m_dofTextures[i]->Create(ImageType_2D, PixelFormatType_RGBA8, dimensions.x/4, dimensions.y/4); + m_dofRTT.AttachTexture(AttachmentPoint_Color, i, m_dofTextures[i]); + } + m_dofRTT.Unlock(); + + if (!m_dofRTT.IsComplete()) + { + NazaraError("Incomplete RTT"); + return false; + } + + return true; +} } diff --git a/src/Nazara/Graphics/DeferredFXAAPass.cpp b/src/Nazara/Graphics/DeferredFXAAPass.cpp index 0e903f8a8..3a300392a 100644 --- a/src/Nazara/Graphics/DeferredFXAAPass.cpp +++ b/src/Nazara/Graphics/DeferredFXAAPass.cpp @@ -8,32 +8,35 @@ #include #include -NzDeferredFXAAPass::NzDeferredFXAAPass() +namespace Nz { - m_fxaaShader = NzShaderLibrary::Get("DeferredFXAA"); + DeferredFXAAPass::DeferredFXAAPass() + { + m_fxaaShader = ShaderLibrary::Get("DeferredFXAA"); - m_pointSampler.SetAnisotropyLevel(1); - m_pointSampler.SetFilterMode(nzSamplerFilter_Nearest); - m_pointSampler.SetWrapMode(nzSamplerWrap_Clamp); + m_pointSampler.SetAnisotropyLevel(1); + m_pointSampler.SetFilterMode(SamplerFilter_Nearest); + m_pointSampler.SetWrapMode(SamplerWrap_Clamp); - m_states.parameters[nzRendererParameter_DepthBuffer] = false; -} - -NzDeferredFXAAPass::~NzDeferredFXAAPass() = default; - -bool NzDeferredFXAAPass::Process(const NzSceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const -{ - NazaraUnused(sceneData); - - m_workRTT->SetColorTarget(firstWorkTexture); - NzRenderer::SetTarget(m_workRTT); - NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y)); - - NzRenderer::SetRenderStates(m_states); - NzRenderer::SetShader(m_fxaaShader); - NzRenderer::SetTexture(0, m_workTextures[secondWorkTexture]); - NzRenderer::SetTextureSampler(0, m_pointSampler); - NzRenderer::DrawFullscreenQuad(); - - return true; + m_states.parameters[RendererParameter_DepthBuffer] = false; + } + + DeferredFXAAPass::~DeferredFXAAPass() = default; + + bool DeferredFXAAPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const + { + NazaraUnused(sceneData); + + m_workRTT->SetColorTarget(firstWorkTexture); + Renderer::SetTarget(m_workRTT); + Renderer::SetViewport(Recti(0, 0, m_dimensions.x, m_dimensions.y)); + + Renderer::SetRenderStates(m_states); + Renderer::SetShader(m_fxaaShader); + Renderer::SetTexture(0, m_workTextures[secondWorkTexture]); + Renderer::SetTextureSampler(0, m_pointSampler); + Renderer::DrawFullscreenQuad(); + + return true; + } } diff --git a/src/Nazara/Graphics/DeferredFinalPass.cpp b/src/Nazara/Graphics/DeferredFinalPass.cpp index 3221ade69..6ca1e72c4 100644 --- a/src/Nazara/Graphics/DeferredFinalPass.cpp +++ b/src/Nazara/Graphics/DeferredFinalPass.cpp @@ -8,49 +8,52 @@ #include #include -NzDeferredFinalPass::NzDeferredFinalPass() +namespace Nz { - m_pointSampler.SetAnisotropyLevel(1); - m_pointSampler.SetFilterMode(nzSamplerFilter_Nearest); - m_pointSampler.SetWrapMode(nzSamplerWrap_Clamp); + DeferredFinalPass::DeferredFinalPass() + { + m_pointSampler.SetAnisotropyLevel(1); + m_pointSampler.SetFilterMode(SamplerFilter_Nearest); + m_pointSampler.SetWrapMode(SamplerWrap_Clamp); - m_states.parameters[nzRendererParameter_DepthBuffer] = false; + m_states.parameters[RendererParameter_DepthBuffer] = false; - m_uberShader = NzUberShaderLibrary::Get("Basic"); + m_uberShader = UberShaderLibrary::Get("Basic"); - NzParameterList list; - list.SetParameter("AUTO_TEXCOORDS", true); - list.SetParameter("DIFFUSE_MAPPING", true); - list.SetParameter("TEXTURE_MAPPING", false); + ParameterList list; + list.SetParameter("AUTO_TEXCOORDS", true); + list.SetParameter("DIFFUSE_MAPPING", true); + list.SetParameter("TEXTURE_MAPPING", false); - m_uberShaderInstance = m_uberShader->Get(list); + m_uberShaderInstance = m_uberShader->Get(list); - const NzShader* shader = m_uberShaderInstance->GetShader(); - m_materialDiffuseUniform = shader->GetUniformLocation("MaterialDiffuse"); - m_materialDiffuseMapUniform = shader->GetUniformLocation("MaterialDiffuseMap"); -} - -NzDeferredFinalPass::~NzDeferredFinalPass() = default; - -bool NzDeferredFinalPass::Process(const NzSceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const -{ - NazaraAssert(sceneData.viewer, "Invalid viewer"); - - NazaraUnused(firstWorkTexture); - - sceneData.viewer->ApplyView(); - - NzRenderer::SetRenderStates(m_states); - NzRenderer::SetTexture(0, m_workTextures[secondWorkTexture]); - NzRenderer::SetTextureSampler(0, m_pointSampler); - - m_uberShaderInstance->Activate(); - - const NzShader* shader = m_uberShaderInstance->GetShader(); - shader->SendColor(m_materialDiffuseUniform, NzColor::White); - shader->SendInteger(m_materialDiffuseMapUniform, 0); - - NzRenderer::DrawFullscreenQuad(); - - return false; + const Shader* shader = m_uberShaderInstance->GetShader(); + m_materialDiffuseUniform = shader->GetUniformLocation("MaterialDiffuse"); + m_materialDiffuseMapUniform = shader->GetUniformLocation("MaterialDiffuseMap"); + } + + DeferredFinalPass::~DeferredFinalPass() = default; + + bool DeferredFinalPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const + { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + + NazaraUnused(firstWorkTexture); + + sceneData.viewer->ApplyView(); + + Renderer::SetRenderStates(m_states); + Renderer::SetTexture(0, m_workTextures[secondWorkTexture]); + Renderer::SetTextureSampler(0, m_pointSampler); + + m_uberShaderInstance->Activate(); + + const Shader* shader = m_uberShaderInstance->GetShader(); + shader->SendColor(m_materialDiffuseUniform, Color::White); + shader->SendInteger(m_materialDiffuseMapUniform, 0); + + Renderer::DrawFullscreenQuad(); + + return false; + } } diff --git a/src/Nazara/Graphics/DeferredFogPass.cpp b/src/Nazara/Graphics/DeferredFogPass.cpp index e09967569..af00a7c1d 100644 --- a/src/Nazara/Graphics/DeferredFogPass.cpp +++ b/src/Nazara/Graphics/DeferredFogPass.cpp @@ -9,143 +9,146 @@ #include #include -namespace +namespace Nz { - NzShaderRef BuildFogShader() + namespace { - /*const nzUInt8 fragmentSource[] = { - #include - };*/ - - const char* fragmentSource = - "#version 140\n" - - "out vec4 RenderTarget0;\n" - - "uniform sampler2D ColorTexture;\n" - "uniform sampler2D GBuffer2;\n" - "uniform mat4 InvViewProjMatrix;\n" - "uniform vec2 InvTargetSize;\n" - "uniform vec3 EyePosition;\n" - - "float n = 0.1;" - "float f = 1000.0;" - - "float color_to_float(vec3 color)\n" - "{\n" - "const vec3 byte_to_float = vec3(1.0, 1.0/256, 1.0/(256*256));\n" - "return dot(color, byte_to_float);\n" - "}\n" - - "void main()\n" - "{" - "vec2 texCoord = gl_FragCoord.xy * InvTargetSize;\n" - "\t" "vec3 color = texture(ColorTexture, texCoord).xyz;\n" - "vec4 gVec2 = textureLod(GBuffer2, texCoord, 0.0);\n" - "float depth = color_to_float(gVec2.xyz)*2.0 - 1.0;\n" - "float linearDepth = (2 * n) / (f + n - depth * (f - n));" - - "vec3 viewSpace = vec3(texCoord*2.0 - 1.0, depth);\n" - - "vec4 worldPos = InvViewProjMatrix * vec4(viewSpace, 1.0);\n" - "worldPos.xyz /= worldPos.w;\n" - - /*"float lumThreshold = 0.1;" - "float lumMultipler = 2.0;" - //"float lumFactor = max(dot(color, vec3(0.299, 0.587, 0.114)) - lumThreshold, 0.0) / (1.0-lumThreshold);" - "float fogFactor = (1.0 - clamp(worldPos.y-2.0, 0.0, 1.0)) - lumFactor*lumMultipler;" - "fogFactor += (1.0 - clamp(EyePosition.y-2.5, 0.0, 1.0));" - "fogFactor = clamp(fogFactor, 0.0, 1.0);"*/ - - "float lumThreshold = 0.8;" - "float lumMultipler = 2.0;" - "float luminosity = dot(color, vec3(0.299, 0.587, 0.114));" - "float lumFactor = max(luminosity - lumThreshold, 0.0) / (1.0-lumThreshold);" - - "vec4 fogColor = vec4(0.5, 0.5, 0.5, 1.0);\n" - "vec2 fogrange = vec2(0, 50);\n" - "float fogeffect = clamp( 1.0 - (fogrange.y - linearDepth*0.5*f) / (fogrange.y - fogrange.x) , 0.0, 1.0 ) * fogColor.w;\n" - "fogeffect = max(fogeffect-lumFactor, 0.0);" - - //fogeffect*=(1.0 - int(depth)); - "\t" "vec3 fragmentColor = color*(1.0-fogeffect) + fogColor.rgb * fogeffect;\n" - "\t" "RenderTarget0 = vec4(fragmentColor, 1.0);\n" - "}"; - - const char* vertexSource = - "#version 140\n" - - "in vec3 VertexPosition;\n" - - "void main()\n" - "{\n" - "\t" "gl_Position = vec4(VertexPosition, 1.0);" "\n" - "}\n"; - - ///TODO: Remplacer ça par des ShaderNode - NzShaderRef shader = NzShader::New(); - if (!shader->Create()) + ShaderRef BuildFogShader() { - NazaraError("Failed to load create shader"); - return nullptr; + /*const UInt8 fragmentSource[] = { + #include + };*/ + + const char* fragmentSource = + "#version 140\n" + + "out vec4 RenderTarget0;\n" + + "uniform sampler2D ColorTexture;\n" + "uniform sampler2D GBuffer2;\n" + "uniform mat4 InvViewProjMatrix;\n" + "uniform vec2 InvTargetSize;\n" + "uniform vec3 EyePosition;\n" + + "float n = 0.1;" + "float f = 1000.0;" + + "float color_to_float(vec3 color)\n" + "{\n" + "const vec3 byte_to_float = vec3(1.0, 1.0/256, 1.0/(256*256));\n" + "return dot(color, byte_to_float);\n" + "}\n" + + "void main()\n" + "{" + "vec2 texCoord = gl_FragCoord.xy * InvTargetSize;\n" + "\t" "vec3 color = texture(ColorTexture, texCoord).xyz;\n" + "vec4 gVec2 = textureLod(GBuffer2, texCoord, 0.0);\n" + "float depth = color_to_float(gVec2.xyz)*2.0 - 1.0;\n" + "float linearDepth = (2 * n) / (f + n - depth * (f - n));" + + "vec3 viewSpace = vec3(texCoord*2.0 - 1.0, depth);\n" + + "vec4 worldPos = InvViewProjMatrix * vec4(viewSpace, 1.0);\n" + "worldPos.xyz /= worldPos.w;\n" + + /*"float lumThreshold = 0.1;" + "float lumMultipler = 2.0;" + //"float lumFactor = max(dot(color, vec3(0.299, 0.587, 0.114)) - lumThreshold, 0.0) / (1.0-lumThreshold);" + "float fogFactor = (1.0 - clamp(worldPos.y-2.0, 0.0, 1.0)) - lumFactor*lumMultipler;" + "fogFactor += (1.0 - clamp(EyePosition.y-2.5, 0.0, 1.0));" + "fogFactor = clamp(fogFactor, 0.0, 1.0);"*/ + + "float lumThreshold = 0.8;" + "float lumMultipler = 2.0;" + "float luminosity = dot(color, vec3(0.299, 0.587, 0.114));" + "float lumFactor = max(luminosity - lumThreshold, 0.0) / (1.0-lumThreshold);" + + "vec4 fogColor = vec4(0.5, 0.5, 0.5, 1.0);\n" + "vec2 fogrange = vec2(0, 50);\n" + "float fogeffect = clamp( 1.0 - (fogrange.y - linearDepth*0.5*f) / (fogrange.y - fogrange.x) , 0.0, 1.0 ) * fogColor.w;\n" + "fogeffect = max(fogeffect-lumFactor, 0.0);" + + //fogeffect*=(1.0 - int(depth)); + "\t" "vec3 fragmentColor = color*(1.0-fogeffect) + fogColor.rgb * fogeffect;\n" + "\t" "RenderTarget0 = vec4(fragmentColor, 1.0);\n" + "}"; + + const char* vertexSource = + "#version 140\n" + + "in vec3 VertexPosition;\n" + + "void main()\n" + "{\n" + "\t" "gl_Position = vec4(VertexPosition, 1.0);" "\n" + "}\n"; + + ///TODO: Remplacer ça par des ShaderNode + ShaderRef shader = Shader::New(); + if (!shader->Create()) + { + NazaraError("Failed to load create shader"); + return nullptr; + } + + if (!shader->AttachStageFromSource(ShaderStageType_Fragment, fragmentSource/*String(reinterpret_cast(fragmentSource), sizeof(fragmentSource))*/)) + { + NazaraError("Failed to load fragment shader"); + return nullptr; + } + + if (!shader->AttachStageFromSource(ShaderStageType_Vertex, vertexSource)) + { + NazaraError("Failed to load vertex shader"); + return nullptr; + } + + if (!shader->Link()) + { + NazaraError("Failed to link shader"); + return nullptr; + } + + shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0); + shader->SendInteger(shader->GetUniformLocation("GBuffer2"), 1); + + return shader; } - - if (!shader->AttachStageFromSource(nzShaderStage_Fragment, fragmentSource/*NzString(reinterpret_cast(fragmentSource), sizeof(fragmentSource))*/)) - { - NazaraError("Failed to load fragment shader"); - return nullptr; - } - - if (!shader->AttachStageFromSource(nzShaderStage_Vertex, vertexSource)) - { - NazaraError("Failed to load vertex shader"); - return nullptr; - } - - if (!shader->Link()) - { - NazaraError("Failed to link shader"); - return nullptr; - } - - shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0); - shader->SendInteger(shader->GetUniformLocation("GBuffer2"), 1); - - return shader; } + + DeferredFogPass::DeferredFogPass() + { + m_pointSampler.SetAnisotropyLevel(1); + m_pointSampler.SetFilterMode(SamplerFilter_Nearest); + m_pointSampler.SetWrapMode(SamplerWrap_Clamp); + + m_shader = BuildFogShader(); + m_shaderEyePositionLocation = m_shader->GetUniformLocation("EyePosition"); + + m_states.parameters[RendererParameter_DepthBuffer] = false; + } + + DeferredFogPass::~DeferredFogPass() = default; + + bool DeferredFogPass::Process( const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const + { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + + m_workRTT->SetColorTarget(firstWorkTexture); + Renderer::SetTarget(m_workRTT); + Renderer::SetViewport(Recti(0, 0, m_dimensions.x, m_dimensions.y)); + + Renderer::SetShader(m_shader); + m_shader->SendVector(m_shaderEyePositionLocation, sceneData.viewer->GetEyePosition()); + + Renderer::SetRenderStates(m_states); + Renderer::SetTexture(0, m_workTextures[secondWorkTexture]); + Renderer::SetTexture(1, m_GBuffer[2]); + Renderer::SetTextureSampler(0, m_pointSampler); + Renderer::SetTextureSampler(1, m_pointSampler); + Renderer::DrawFullscreenQuad(); + + return true; } - -NzDeferredFogPass::NzDeferredFogPass() -{ - m_pointSampler.SetAnisotropyLevel(1); - m_pointSampler.SetFilterMode(nzSamplerFilter_Nearest); - m_pointSampler.SetWrapMode(nzSamplerWrap_Clamp); - - m_shader = BuildFogShader(); - m_shaderEyePositionLocation = m_shader->GetUniformLocation("EyePosition"); - - m_states.parameters[nzRendererParameter_DepthBuffer] = false; -} - -NzDeferredFogPass::~NzDeferredFogPass() = default; - -bool NzDeferredFogPass::Process( const NzSceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const -{ - NazaraAssert(sceneData.viewer, "Invalid viewer"); - - m_workRTT->SetColorTarget(firstWorkTexture); - NzRenderer::SetTarget(m_workRTT); - NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y)); - - NzRenderer::SetShader(m_shader); - m_shader->SendVector(m_shaderEyePositionLocation, sceneData.viewer->GetEyePosition()); - - NzRenderer::SetRenderStates(m_states); - NzRenderer::SetTexture(0, m_workTextures[secondWorkTexture]); - NzRenderer::SetTexture(1, m_GBuffer[2]); - NzRenderer::SetTextureSampler(0, m_pointSampler); - NzRenderer::SetTextureSampler(1, m_pointSampler); - NzRenderer::DrawFullscreenQuad(); - - return true; } diff --git a/src/Nazara/Graphics/DeferredForwardPass.cpp b/src/Nazara/Graphics/DeferredForwardPass.cpp index d708ca1df..35daabae8 100644 --- a/src/Nazara/Graphics/DeferredForwardPass.cpp +++ b/src/Nazara/Graphics/DeferredForwardPass.cpp @@ -11,32 +11,35 @@ #include #include -NzDeferredForwardPass::NzDeferredForwardPass() = default; -NzDeferredForwardPass::~NzDeferredForwardPass() = default; - -void NzDeferredForwardPass::Initialize(NzDeferredRenderTechnique* technique) +namespace Nz { - NzDeferredRenderPass::Initialize(technique); + DeferredForwardPass::DeferredForwardPass() = default; + DeferredForwardPass::~DeferredForwardPass() = default; - m_forwardTechnique = technique->GetForwardTechnique(); -} - -bool NzDeferredForwardPass::Process(const NzSceneData& sceneData, unsigned int workTexture, unsigned sceneTexture) const -{ - NazaraAssert(sceneData.viewer, "Invalid viewer"); - NazaraUnused(workTexture); - - m_workRTT->SetColorTarget(sceneTexture); - NzRenderer::SetTarget(m_workRTT); - NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y)); - - if (sceneData.background) - sceneData.background->Draw(sceneData.viewer); - - NzRenderer::SetMatrix(nzMatrixType_Projection, sceneData.viewer->GetProjectionMatrix()); - NzRenderer::SetMatrix(nzMatrixType_View, sceneData.viewer->GetViewMatrix()); - - m_forwardTechnique->Draw(sceneData); - - return false; + void DeferredForwardPass::Initialize(DeferredRenderTechnique* technique) + { + DeferredRenderPass::Initialize(technique); + + m_forwardTechnique = technique->GetForwardTechnique(); + } + + bool DeferredForwardPass::Process(const SceneData& sceneData, unsigned int workTexture, unsigned sceneTexture) const + { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + NazaraUnused(workTexture); + + m_workRTT->SetColorTarget(sceneTexture); + Renderer::SetTarget(m_workRTT); + Renderer::SetViewport(Recti(0, 0, m_dimensions.x, m_dimensions.y)); + + if (sceneData.background) + sceneData.background->Draw(sceneData.viewer); + + Renderer::SetMatrix(MatrixType_Projection, sceneData.viewer->GetProjectionMatrix()); + Renderer::SetMatrix(MatrixType_View, sceneData.viewer->GetViewMatrix()); + + m_forwardTechnique->Draw(sceneData); + + return false; + } } diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index 29733c75b..8b4fbd13e 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -16,244 +16,247 @@ #include #include -NzDeferredGeometryPass::NzDeferredGeometryPass() +namespace Nz { - m_clearShader = NzShaderLibrary::Get("DeferredGBufferClear"); - m_clearStates.parameters[nzRendererParameter_DepthBuffer] = true; - m_clearStates.parameters[nzRendererParameter_FaceCulling] = true; - m_clearStates.parameters[nzRendererParameter_StencilTest] = true; - m_clearStates.depthFunc = nzRendererComparison_Always; - m_clearStates.frontFace.stencilCompare = nzRendererComparison_Always; - m_clearStates.frontFace.stencilPass = nzStencilOperation_Zero; -} - -NzDeferredGeometryPass::~NzDeferredGeometryPass() = default; - -bool NzDeferredGeometryPass::Process(const NzSceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const -{ - NazaraAssert(sceneData.viewer, "Invalid viewer"); - NazaraUnused(firstWorkTexture); - NazaraUnused(secondWorkTexture); - - bool instancingEnabled = m_deferredTechnique->IsInstancingEnabled(); - - m_GBufferRTT->SetColorTargets({0, 1, 2}); // G-Buffer - NzRenderer::SetTarget(m_GBufferRTT); - NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y)); - - NzRenderer::SetRenderStates(m_clearStates); - NzRenderer::SetShader(m_clearShader); - NzRenderer::DrawFullscreenQuad(); - - - NzRenderer::SetMatrix(nzMatrixType_Projection, sceneData.viewer->GetProjectionMatrix()); - NzRenderer::SetMatrix(nzMatrixType_View, sceneData.viewer->GetViewMatrix()); - - const NzShader* lastShader = nullptr; - const ShaderUniforms* shaderUniforms = nullptr; - - for (auto& matIt : m_renderQueue->opaqueModels) + DeferredGeometryPass::DeferredGeometryPass() { - auto& matEntry = matIt.second; + m_clearShader = ShaderLibrary::Get("DeferredGBufferClear"); + m_clearStates.parameters[RendererParameter_DepthBuffer] = true; + m_clearStates.parameters[RendererParameter_FaceCulling] = true; + m_clearStates.parameters[RendererParameter_StencilTest] = true; + m_clearStates.depthFunc = RendererComparison_Always; + m_clearStates.frontFace.stencilCompare = RendererComparison_Always; + m_clearStates.frontFace.stencilPass = nzStencilOperation_Zero; + } - if (matEntry.enabled) + DeferredGeometryPass::~DeferredGeometryPass() = default; + + bool DeferredGeometryPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const + { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + NazaraUnused(firstWorkTexture); + NazaraUnused(secondWorkTexture); + + bool instancingEnabled = m_deferredTechnique->IsInstancingEnabled(); + + m_GBufferRTT->SetColorTargets({0, 1, 2}); // G-Buffer + Renderer::SetTarget(m_GBufferRTT); + Renderer::SetViewport(Recti(0, 0, m_dimensions.x, m_dimensions.y)); + + Renderer::SetRenderStates(m_clearStates); + Renderer::SetShader(m_clearShader); + Renderer::DrawFullscreenQuad(); + + + Renderer::SetMatrix(MatrixType_Projection, sceneData.viewer->GetProjectionMatrix()); + Renderer::SetMatrix(MatrixType_View, sceneData.viewer->GetViewMatrix()); + + const Shader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; + + for (auto& matIt : m_renderQueue->opaqueModels) { - NzDeferredRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; + auto& matEntry = matIt.second; - if (!meshInstances.empty()) + if (matEntry.enabled) { - const NzMaterial* material = matIt.first; + DeferredRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; - bool useInstancing = instancingEnabled && matEntry.instancingEnabled; - - // On commence par récupérer le programme du matériau - nzUInt32 flags = nzShaderFlags_Deferred; - if (useInstancing) - flags |= nzShaderFlags_Instancing; - - const NzShader* shader = material->Apply(flags); - - // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas - if (shader != lastShader) + if (!meshInstances.empty()) { - // Index des uniformes dans le shader - shaderUniforms = GetShaderUniforms(shader); + const Material* material = matIt.first; - // Couleur ambiante de la scène - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position de la caméra - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + bool useInstancing = instancingEnabled && matEntry.instancingEnabled; - lastShader = shader; - } + // On commence par récupérer le programme du matériau + UInt32 flags = ShaderFlags_Deferred; + if (useInstancing) + flags |= ShaderFlags_Instancing; - // Meshes - for (auto& meshIt : meshInstances) - { - const NzMeshData& meshData = meshIt.first; - auto& meshEntry = meshIt.second; + const Shader* shader = material->Apply(flags); - std::vector& instances = meshEntry.instances; - if (!instances.empty()) + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) { - const NzIndexBuffer* indexBuffer = meshData.indexBuffer; - const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer; + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); - // Gestion du draw call avant la boucle de rendu - NzRenderer::DrawCall drawFunc; - NzRenderer::DrawCallInstanced instancedDrawFunc; - unsigned int indexCount; + // Couleur ambiante de la scène + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); - if (indexBuffer) + lastShader = shader; + } + + // Meshes + for (auto& meshIt : meshInstances) + { + const MeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; + + std::vector& instances = meshEntry.instances; + if (!instances.empty()) { - drawFunc = NzRenderer::DrawIndexedPrimitives; - instancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; - indexCount = indexBuffer->GetIndexCount(); - } - else - { - drawFunc = NzRenderer::DrawPrimitives; - instancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; - indexCount = vertexBuffer->GetVertexCount(); - } + const IndexBuffer* indexBuffer = meshData.indexBuffer; + const VertexBuffer* vertexBuffer = meshData.vertexBuffer; - NzRenderer::SetIndexBuffer(indexBuffer); - NzRenderer::SetVertexBuffer(vertexBuffer); + // Gestion du draw call avant la boucle de rendu + Renderer::DrawCall drawFunc; + Renderer::DrawCallInstanced instancedDrawFunc; + unsigned int indexCount; - if (useInstancing) - { - // On récupère le buffer d'instancing du Renderer et on le configure pour fonctionner avec des matrices - NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer(); - instanceBuffer->SetVertexDeclaration(NzVertexDeclaration::Get(nzVertexLayout_Matrix4)); - - const NzMatrix4f* instanceMatrices = &instances[0]; - unsigned int instanceCount = instances.size(); - unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre de matrices que peut contenir le buffer - - while (instanceCount > 0) + if (indexBuffer) { - // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) - unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); - instanceCount -= renderedInstanceCount; - - // On remplit l'instancing buffer avec nos matrices world - instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); - instanceMatrices += renderedInstanceCount; - - // Et on affiche - instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + drawFunc = Renderer::DrawIndexedPrimitives; + instancedDrawFunc = Renderer::DrawIndexedPrimitivesInstanced; + indexCount = indexBuffer->GetIndexCount(); } - } - else - { - // Sans instancing, on doit effectuer un draw call pour chaque instance - // Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances - // À cause du temps de modification du buffer d'instancing - for (const NzMatrix4f& matrix : instances) + else { - NzRenderer::SetMatrix(nzMatrixType_World, matrix); - drawFunc(meshData.primitiveMode, 0, indexCount); + drawFunc = Renderer::DrawPrimitives; + instancedDrawFunc = Renderer::DrawPrimitivesInstanced; + indexCount = vertexBuffer->GetVertexCount(); } - } - instances.clear(); + Renderer::SetIndexBuffer(indexBuffer); + Renderer::SetVertexBuffer(vertexBuffer); + + if (useInstancing) + { + // On récupère le buffer d'instancing du Renderer et on le configure pour fonctionner avec des matrices + VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4)); + + const Matrix4f* instanceMatrices = &instances[0]; + unsigned int instanceCount = instances.size(); + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre de matrices que peut contenir le buffer + + while (instanceCount > 0) + { + // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); + instanceCount -= renderedInstanceCount; + + // On remplit l'instancing buffer avec nos matrices world + instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); + instanceMatrices += renderedInstanceCount; + + // Et on affiche + instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + } + } + else + { + // Sans instancing, on doit effectuer un draw call pour chaque instance + // Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances + // À cause du temps de modification du buffer d'instancing + for (const Matrix4f& matrix : instances) + { + Renderer::SetMatrix(MatrixType_World, matrix); + drawFunc(meshData.primitiveMode, 0, indexCount); + } + } + + instances.clear(); + } } } + + // Et on remet à zéro les données + matEntry.enabled = false; + matEntry.instancingEnabled = false; + } + } + + return false; // On ne fait que remplir le G-Buffer, les work texture ne sont pas affectées + } + + bool DeferredGeometryPass::Resize(const Vector2ui& dimensions) + { + DeferredRenderPass::Resize(dimensions); + + /* + G-Buffer: + Texture0: Diffuse Color + Flags + Texture1: Encoded normal + Texture2: Specular value + Shininess + Texture3: N/A + */ + + try + { + ErrorFlags errFlags(ErrorFlag_ThrowException); + + unsigned int width = dimensions.x; + unsigned int height = dimensions.y; + + m_depthStencilBuffer->Create(PixelFormatType_Depth24Stencil8, width, height); + + m_GBuffer[0]->Create(ImageType_2D, PixelFormatType_RGBA8, width, height); // Texture 0 : Diffuse Color + Specular + m_GBuffer[1]->Create(ImageType_2D, PixelFormatType_RG16F, width, height); // Texture 1 : Encoded normal + m_GBuffer[2]->Create(ImageType_2D, PixelFormatType_RGBA8, width, height); // Texture 2 : Depth (24bits) + Shininess + + m_GBufferRTT->Create(true); + + m_GBufferRTT->AttachTexture(AttachmentPoint_Color, 0, m_GBuffer[0]); + m_GBufferRTT->AttachTexture(AttachmentPoint_Color, 1, m_GBuffer[1]); + m_GBufferRTT->AttachTexture(AttachmentPoint_Color, 2, m_GBuffer[2]); + + // Texture 3 : Emission map ? + + m_GBufferRTT->AttachBuffer(AttachmentPoint_DepthStencil, 0, m_depthStencilBuffer); + + m_GBufferRTT->Unlock(); + + m_workRTT->Create(true); + + for (unsigned int i = 0; i < 2; ++i) + { + m_workTextures[i]->Create(ImageType_2D, PixelFormatType_RGBA8, width, height); + m_workRTT->AttachTexture(AttachmentPoint_Color, i, m_workTextures[i]); } - // Et on remet à zéro les données - matEntry.enabled = false; - matEntry.instancingEnabled = false; + m_workRTT->AttachBuffer(AttachmentPoint_DepthStencil, 0, m_depthStencilBuffer); + + m_workRTT->Unlock(); + + if (!m_workRTT->IsComplete() || !m_GBufferRTT->IsComplete()) + { + NazaraError("Incomplete RTT"); + return false; + } + + return true; } - } - - return false; // On ne fait que remplir le G-Buffer, les work texture ne sont pas affectées -} - -bool NzDeferredGeometryPass::Resize(const NzVector2ui& dimensions) -{ - NzDeferredRenderPass::Resize(dimensions); - - /* - G-Buffer: - Texture0: Diffuse Color + Flags - Texture1: Encoded normal - Texture2: Specular value + Shininess - Texture3: N/A - */ - - try - { - NzErrorFlags errFlags(nzErrorFlag_ThrowException); - - unsigned int width = dimensions.x; - unsigned int height = dimensions.y; - - m_depthStencilBuffer->Create(nzPixelFormat_Depth24Stencil8, width, height); - - m_GBuffer[0]->Create(nzImageType_2D, nzPixelFormat_RGBA8, width, height); // Texture 0 : Diffuse Color + Specular - m_GBuffer[1]->Create(nzImageType_2D, nzPixelFormat_RG16F, width, height); // Texture 1 : Encoded normal - m_GBuffer[2]->Create(nzImageType_2D, nzPixelFormat_RGBA8, width, height); // Texture 2 : Depth (24bits) + Shininess - - m_GBufferRTT->Create(true); - - m_GBufferRTT->AttachTexture(nzAttachmentPoint_Color, 0, m_GBuffer[0]); - m_GBufferRTT->AttachTexture(nzAttachmentPoint_Color, 1, m_GBuffer[1]); - m_GBufferRTT->AttachTexture(nzAttachmentPoint_Color, 2, m_GBuffer[2]); - - // Texture 3 : Emission map ? - - m_GBufferRTT->AttachBuffer(nzAttachmentPoint_DepthStencil, 0, m_depthStencilBuffer); - - m_GBufferRTT->Unlock(); - - m_workRTT->Create(true); - - for (unsigned int i = 0; i < 2; ++i) + catch (const std::exception& e) { - m_workTextures[i]->Create(nzImageType_2D, nzPixelFormat_RGBA8, width, height); - m_workRTT->AttachTexture(nzAttachmentPoint_Color, i, m_workTextures[i]); - } - - m_workRTT->AttachBuffer(nzAttachmentPoint_DepthStencil, 0, m_depthStencilBuffer); - - m_workRTT->Unlock(); - - if (!m_workRTT->IsComplete() || !m_GBufferRTT->IsComplete()) - { - NazaraError("Incomplete RTT"); + NazaraError("Failed to create G-Buffer RTT: " + String(e.what())); return false; } - - return true; } - catch (const std::exception& e) + + const DeferredGeometryPass::ShaderUniforms* DeferredGeometryPass::GetShaderUniforms(const Shader* shader) const { - NazaraError("Failed to create G-Buffer RTT: " + NzString(e.what())); - return false; - } -} + auto it = m_shaderUniforms.find(shader); + if (it == m_shaderUniforms.end()) + { + ShaderUniforms uniforms; + uniforms.shaderReleaseSlot.Connect(shader->OnShaderRelease, this, &DeferredGeometryPass::OnShaderInvalidated); + uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &DeferredGeometryPass::OnShaderInvalidated); -const NzDeferredGeometryPass::ShaderUniforms* NzDeferredGeometryPass::GetShaderUniforms(const NzShader* shader) const -{ - auto it = m_shaderUniforms.find(shader); - if (it == m_shaderUniforms.end()) + uniforms.eyePosition = shader->GetUniformLocation("EyePosition"); + uniforms.sceneAmbient = shader->GetUniformLocation("SceneAmbient"); + uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); + + it = m_shaderUniforms.emplace(shader, std::move(uniforms)).first; + } + + return &it->second; + } + + void DeferredGeometryPass::OnShaderInvalidated(const Shader* shader) const { - ShaderUniforms uniforms; - uniforms.shaderReleaseSlot.Connect(shader->OnShaderRelease, this, &NzDeferredGeometryPass::OnShaderInvalidated); - uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &NzDeferredGeometryPass::OnShaderInvalidated); - - uniforms.eyePosition = shader->GetUniformLocation("EyePosition"); - uniforms.sceneAmbient = shader->GetUniformLocation("SceneAmbient"); - uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); - - it = m_shaderUniforms.emplace(shader, std::move(uniforms)).first; + m_shaderUniforms.erase(shader); } - - return &it->second; -} - -void NzDeferredGeometryPass::OnShaderInvalidated(const NzShader* shader) const -{ - m_shaderUniforms.erase(shader); } diff --git a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp index 34321d345..7fba7478a 100644 --- a/src/Nazara/Graphics/DeferredPhongLightingPass.cpp +++ b/src/Nazara/Graphics/DeferredPhongLightingPass.cpp @@ -11,280 +11,283 @@ #include #include -NzDeferredPhongLightingPass::NzDeferredPhongLightingPass() : -m_lightMeshesDrawing(false) +namespace Nz { - m_directionalLightShader = NzShaderLibrary::Get("DeferredDirectionnalLight"); - m_directionalLightShaderEyePositionLocation = m_directionalLightShader->GetUniformLocation("EyePosition"); - m_directionalLightShaderSceneAmbientLocation = m_directionalLightShader->GetUniformLocation("SceneAmbient"); - - m_directionalLightUniforms.ubo = false; - m_directionalLightUniforms.locations.type = -1; // Type déjà connu - m_directionalLightUniforms.locations.color = m_directionalLightShader->GetUniformLocation("LightColor"); - m_directionalLightUniforms.locations.factors = m_directionalLightShader->GetUniformLocation("LightFactors"); - m_directionalLightUniforms.locations.parameters1 = m_directionalLightShader->GetUniformLocation("LightDirection"); - m_directionalLightUniforms.locations.parameters2 = -1; - m_directionalLightUniforms.locations.parameters3 = -1; - - m_pointSpotLightShader = NzShaderLibrary::Get("DeferredPointSpotLight"); - m_pointSpotLightShaderDiscardLocation = m_pointSpotLightShader->GetUniformLocation("Discard"); - m_pointSpotLightShaderEyePositionLocation = m_pointSpotLightShader->GetUniformLocation("EyePosition"); - m_pointSpotLightShaderSceneAmbientLocation = m_pointSpotLightShader->GetUniformLocation("SceneAmbient"); - - m_pointSpotLightUniforms.ubo = false; - m_pointSpotLightUniforms.locations.type = m_pointSpotLightShader->GetUniformLocation("LightType"); - m_pointSpotLightUniforms.locations.color = m_pointSpotLightShader->GetUniformLocation("LightColor"); - m_pointSpotLightUniforms.locations.factors = m_pointSpotLightShader->GetUniformLocation("LightFactors"); - m_pointSpotLightUniforms.locations.parameters1 = m_pointSpotLightShader->GetUniformLocation("LightParameters1"); - m_pointSpotLightUniforms.locations.parameters2 = m_pointSpotLightShader->GetUniformLocation("LightParameters2"); - m_pointSpotLightUniforms.locations.parameters3 = m_pointSpotLightShader->GetUniformLocation("LightParameters3"); - - m_pointSampler.SetAnisotropyLevel(1); - m_pointSampler.SetFilterMode(nzSamplerFilter_Nearest); - m_pointSampler.SetWrapMode(nzSamplerWrap_Clamp); - - m_cone = NzMesh::New(); - m_cone->CreateStatic(); - m_coneMesh = static_cast(m_cone->BuildSubMesh(NzPrimitive::Cone(1.f, 1.f, 16, NzMatrix4f::Rotate(NzEulerAnglesf(90.f, 0.f, 0.f))))); - - m_sphere = NzMesh::New(); - m_sphere->CreateStatic(); - m_sphereMesh = static_cast(m_sphere->BuildSubMesh(NzPrimitive::IcoSphere(1.f, 1))); -} - -NzDeferredPhongLightingPass::~NzDeferredPhongLightingPass() = default; - -void NzDeferredPhongLightingPass::EnableLightMeshesDrawing(bool enable) -{ - m_lightMeshesDrawing = enable; -} - -bool NzDeferredPhongLightingPass::IsLightMeshesDrawingEnabled() const -{ - return m_lightMeshesDrawing; -} - -bool NzDeferredPhongLightingPass::Process(const NzSceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const -{ - NazaraAssert(sceneData.viewer, "Invalid viewer"); - NazaraUnused(secondWorkTexture); - - m_workRTT->SetColorTarget(firstWorkTexture); - NzRenderer::SetTarget(m_workRTT); - NzRenderer::SetViewport(NzRecti(0, 0, m_dimensions.x, m_dimensions.y)); - - NzRenderer::SetTexture(0, m_GBuffer[0]); - NzRenderer::SetTextureSampler(0, m_pointSampler); - - NzRenderer::SetTexture(1, m_GBuffer[1]); - NzRenderer::SetTextureSampler(1, m_pointSampler); - - NzRenderer::SetTexture(2, m_GBuffer[2]); - NzRenderer::SetTextureSampler(2, m_pointSampler); - - NzRenderer::SetClearColor(NzColor::Black); - NzRenderer::Clear(nzRendererBuffer_Color); - - NzRenderStates lightStates; - lightStates.dstBlend = nzBlendFunc_One; - lightStates.srcBlend = nzBlendFunc_One; - lightStates.parameters[nzRendererParameter_Blend] = true; - lightStates.parameters[nzRendererParameter_DepthBuffer] = false; - lightStates.parameters[nzRendererParameter_DepthWrite] = false; - - // Directional lights - if (!m_renderQueue->directionalLights.empty()) + DeferredPhongLightingPass::DeferredPhongLightingPass() : + m_lightMeshesDrawing(false) { - NzRenderer::SetRenderStates(lightStates); - NzRenderer::SetShader(m_directionalLightShader); - m_directionalLightShader->SendColor(m_directionalLightShaderSceneAmbientLocation, sceneData.ambientColor); - m_directionalLightShader->SendVector(m_directionalLightShaderEyePositionLocation, sceneData.viewer->GetEyePosition()); + m_directionalLightShader = ShaderLibrary::Get("DeferredDirectionnalLight"); + m_directionalLightShaderEyePositionLocation = m_directionalLightShader->GetUniformLocation("EyePosition"); + m_directionalLightShaderSceneAmbientLocation = m_directionalLightShader->GetUniformLocation("SceneAmbient"); - for (auto& light : m_renderQueue->directionalLights) - { - m_directionalLightShader->SendColor(m_directionalLightUniforms.locations.color, light.color); - m_directionalLightShader->SendVector(m_directionalLightUniforms.locations.factors, NzVector2f(light.ambientFactor, light.diffuseFactor)); - m_directionalLightShader->SendVector(m_directionalLightUniforms.locations.parameters1, NzVector4f(light.direction)); + m_directionalLightUniforms.ubo = false; + m_directionalLightUniforms.locations.type = -1; // Type déjà connu + m_directionalLightUniforms.locations.color = m_directionalLightShader->GetUniformLocation("LightColor"); + m_directionalLightUniforms.locations.factors = m_directionalLightShader->GetUniformLocation("LightFactors"); + m_directionalLightUniforms.locations.parameters1 = m_directionalLightShader->GetUniformLocation("LightDirection"); + m_directionalLightUniforms.locations.parameters2 = -1; + m_directionalLightUniforms.locations.parameters3 = -1; - NzRenderer::DrawFullscreenQuad(); - } + m_pointSpotLightShader = ShaderLibrary::Get("DeferredPointSpotLight"); + m_pointSpotLightShaderDiscardLocation = m_pointSpotLightShader->GetUniformLocation("Discard"); + m_pointSpotLightShaderEyePositionLocation = m_pointSpotLightShader->GetUniformLocation("EyePosition"); + m_pointSpotLightShaderSceneAmbientLocation = m_pointSpotLightShader->GetUniformLocation("SceneAmbient"); + + m_pointSpotLightUniforms.ubo = false; + m_pointSpotLightUniforms.locations.type = m_pointSpotLightShader->GetUniformLocation("LightType"); + m_pointSpotLightUniforms.locations.color = m_pointSpotLightShader->GetUniformLocation("LightColor"); + m_pointSpotLightUniforms.locations.factors = m_pointSpotLightShader->GetUniformLocation("LightFactors"); + m_pointSpotLightUniforms.locations.parameters1 = m_pointSpotLightShader->GetUniformLocation("LightParameters1"); + m_pointSpotLightUniforms.locations.parameters2 = m_pointSpotLightShader->GetUniformLocation("LightParameters2"); + m_pointSpotLightUniforms.locations.parameters3 = m_pointSpotLightShader->GetUniformLocation("LightParameters3"); + + m_pointSampler.SetAnisotropyLevel(1); + m_pointSampler.SetFilterMode(SamplerFilter_Nearest); + m_pointSampler.SetWrapMode(SamplerWrap_Clamp); + + m_cone = Mesh::New(); + m_cone->CreateStatic(); + m_coneMesh = static_cast(m_cone->BuildSubMesh(Primitive::Cone(1.f, 1.f, 16, Matrix4f::Rotate(EulerAnglesf(90.f, 0.f, 0.f))))); + + m_sphere = Mesh::New(); + m_sphere->CreateStatic(); + m_sphereMesh = static_cast(m_sphere->BuildSubMesh(Primitive::IcoSphere(1.f, 1))); } - // Point lights/Spot lights - if (!m_renderQueue->pointLights.empty() || !m_renderQueue->spotLights.empty()) + DeferredPhongLightingPass::~DeferredPhongLightingPass() = default; + + void DeferredPhongLightingPass::EnableLightMeshesDrawing(bool enable) { - // http://www.altdevblogaday.com/2011/08/08/stencil-buffer-optimisation-for-deferred-lights/ - lightStates.parameters[nzRendererParameter_StencilTest] = true; - lightStates.faceCulling = nzFaceSide_Front; - lightStates.backFace.stencilMask = 0xFF; - lightStates.backFace.stencilReference = 0; - lightStates.backFace.stencilFail = nzStencilOperation_Keep; - lightStates.backFace.stencilPass = nzStencilOperation_Keep; - lightStates.backFace.stencilZFail = nzStencilOperation_Invert; - lightStates.frontFace.stencilMask = 0xFF; - lightStates.frontFace.stencilReference = 0; - lightStates.frontFace.stencilFail = nzStencilOperation_Keep; - lightStates.frontFace.stencilPass = nzStencilOperation_Keep; - lightStates.frontFace.stencilZFail = nzStencilOperation_Invert; + m_lightMeshesDrawing = enable; + } - NzRenderer::SetRenderStates(lightStates); + bool DeferredPhongLightingPass::IsLightMeshesDrawingEnabled() const + { + return m_lightMeshesDrawing; + } - NzRenderer::SetShader(m_pointSpotLightShader); - m_pointSpotLightShader->SendColor(m_pointSpotLightShaderSceneAmbientLocation, sceneData.ambientColor); - m_pointSpotLightShader->SendVector(m_pointSpotLightShaderEyePositionLocation, sceneData.viewer->GetEyePosition()); + bool DeferredPhongLightingPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const + { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + NazaraUnused(secondWorkTexture); - NzMatrix4f lightMatrix; - lightMatrix.MakeIdentity(); - if (!m_renderQueue->pointLights.empty()) + m_workRTT->SetColorTarget(firstWorkTexture); + Renderer::SetTarget(m_workRTT); + Renderer::SetViewport(Recti(0, 0, m_dimensions.x, m_dimensions.y)); + + Renderer::SetTexture(0, m_GBuffer[0]); + Renderer::SetTextureSampler(0, m_pointSampler); + + Renderer::SetTexture(1, m_GBuffer[1]); + Renderer::SetTextureSampler(1, m_pointSampler); + + Renderer::SetTexture(2, m_GBuffer[2]); + Renderer::SetTextureSampler(2, m_pointSampler); + + Renderer::SetClearColor(Color::Black); + Renderer::Clear(RendererBuffer_Color); + + RenderStates lightStates; + lightStates.dstBlend = BlendFunc_One; + lightStates.srcBlend = BlendFunc_One; + lightStates.parameters[RendererParameter_Blend] = true; + lightStates.parameters[RendererParameter_DepthBuffer] = false; + lightStates.parameters[RendererParameter_DepthWrite] = false; + + // Directional lights + if (!m_renderQueue->directionalLights.empty()) { - const NzIndexBuffer* indexBuffer = m_sphereMesh->GetIndexBuffer(); - NzRenderer::SetIndexBuffer(indexBuffer); - NzRenderer::SetVertexBuffer(m_sphereMesh->GetVertexBuffer()); + Renderer::SetRenderStates(lightStates); + Renderer::SetShader(m_directionalLightShader); + m_directionalLightShader->SendColor(m_directionalLightShaderSceneAmbientLocation, sceneData.ambientColor); + m_directionalLightShader->SendVector(m_directionalLightShaderEyePositionLocation, sceneData.viewer->GetEyePosition()); - m_pointSpotLightShader->SendInteger(m_pointSpotLightUniforms.locations.type, nzLightType_Point); - for (const auto& light : m_renderQueue->pointLights) + for (auto& light : m_renderQueue->directionalLights) { - m_pointSpotLightShader->SendColor(m_pointSpotLightUniforms.locations.color, light.color); - m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.factors, NzVector2f(light.ambientFactor, light.diffuseFactor)); - m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters1, NzVector4f(light.position, light.attenuation)); - m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters2, NzVector4f(0.f, 0.f, 0.f, light.invRadius)); + m_directionalLightShader->SendColor(m_directionalLightUniforms.locations.color, light.color); + m_directionalLightShader->SendVector(m_directionalLightUniforms.locations.factors, Vector2f(light.ambientFactor, light.diffuseFactor)); + m_directionalLightShader->SendVector(m_directionalLightUniforms.locations.parameters1, Vector4f(light.direction)); - lightMatrix.SetScale(NzVector3f(light.radius * 1.1f)); // Pour corriger les imperfections liées à la sphère - lightMatrix.SetTranslation(light.position); - - NzRenderer::SetMatrix(nzMatrixType_World, lightMatrix); - - // Rendu de la sphère dans le stencil buffer - NzRenderer::Enable(nzRendererParameter_ColorWrite, false); - NzRenderer::Enable(nzRendererParameter_DepthBuffer, true); - NzRenderer::Enable(nzRendererParameter_FaceCulling, false); - NzRenderer::SetStencilCompareFunction(nzRendererComparison_Always); - - m_pointSpotLightShader->SendBoolean(m_pointSpotLightShaderDiscardLocation, true); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); - - // Rendu de la sphère comme zone d'effet - NzRenderer::Enable(nzRendererParameter_ColorWrite, true); - NzRenderer::Enable(nzRendererParameter_DepthBuffer, false); - NzRenderer::Enable(nzRendererParameter_FaceCulling, true); - NzRenderer::SetStencilCompareFunction(nzRendererComparison_NotEqual, nzFaceSide_Back); - NzRenderer::SetStencilPassOperation(nzStencilOperation_Zero, nzFaceSide_Back); - - m_pointSpotLightShader->SendBoolean(m_pointSpotLightShaderDiscardLocation, false); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); + Renderer::DrawFullscreenQuad(); } + } - if (m_lightMeshesDrawing) + // Point lights/Spot lights + if (!m_renderQueue->pointLights.empty() || !m_renderQueue->spotLights.empty()) + { + // http://www.altdevblogaday.com/2011/08/08/stencil-buffer-optimisation-for-deferred-lights/ + lightStates.parameters[RendererParameter_StencilTest] = true; + lightStates.faceCulling = FaceSide_Front; + lightStates.backFace.stencilMask = 0xFF; + lightStates.backFace.stencilReference = 0; + lightStates.backFace.stencilFail = nzStencilOperation_Keep; + lightStates.backFace.stencilPass = nzStencilOperation_Keep; + lightStates.backFace.stencilZFail = nzStencilOperation_Invert; + lightStates.frontFace.stencilMask = 0xFF; + lightStates.frontFace.stencilReference = 0; + lightStates.frontFace.stencilFail = nzStencilOperation_Keep; + lightStates.frontFace.stencilPass = nzStencilOperation_Keep; + lightStates.frontFace.stencilZFail = nzStencilOperation_Invert; + + Renderer::SetRenderStates(lightStates); + + Renderer::SetShader(m_pointSpotLightShader); + m_pointSpotLightShader->SendColor(m_pointSpotLightShaderSceneAmbientLocation, sceneData.ambientColor); + m_pointSpotLightShader->SendVector(m_pointSpotLightShaderEyePositionLocation, sceneData.viewer->GetEyePosition()); + + Matrix4f lightMatrix; + lightMatrix.MakeIdentity(); + if (!m_renderQueue->pointLights.empty()) { - NzRenderer::Enable(nzRendererParameter_DepthBuffer, true); - NzRenderer::Enable(nzRendererParameter_DepthWrite, true); - NzRenderer::Enable(nzRendererParameter_FaceCulling, false); - NzRenderer::Enable(nzRendererParameter_StencilTest, false); - NzRenderer::SetFaceFilling(nzFaceFilling_Line); + const IndexBuffer* indexBuffer = m_sphereMesh->GetIndexBuffer(); + Renderer::SetIndexBuffer(indexBuffer); + Renderer::SetVertexBuffer(m_sphereMesh->GetVertexBuffer()); - const NzShader* shader = NzShaderLibrary::Get("DebugSimple"); - static int colorLocation = shader->GetUniformLocation("Color"); - - NzRenderer::SetShader(shader); + m_pointSpotLightShader->SendInteger(m_pointSpotLightUniforms.locations.type, LightType_Point); for (const auto& light : m_renderQueue->pointLights) { - lightMatrix.SetScale(NzVector3f(light.radius * 1.1f)); // Pour corriger les imperfections liées à la sphère + m_pointSpotLightShader->SendColor(m_pointSpotLightUniforms.locations.color, light.color); + m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.factors, Vector2f(light.ambientFactor, light.diffuseFactor)); + m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters1, Vector4f(light.position, light.attenuation)); + m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters2, Vector4f(0.f, 0.f, 0.f, light.invRadius)); + + lightMatrix.SetScale(Vector3f(light.radius * 1.1f)); // Pour corriger les imperfections liées à la sphère lightMatrix.SetTranslation(light.position); - NzRenderer::SetMatrix(nzMatrixType_World, lightMatrix); + Renderer::SetMatrix(MatrixType_World, lightMatrix); - shader->SendColor(colorLocation, light.color); + // Rendu de la sphère dans le stencil buffer + Renderer::Enable(RendererParameter_ColorWrite, false); + Renderer::Enable(RendererParameter_DepthBuffer, true); + Renderer::Enable(RendererParameter_FaceCulling, false); + Renderer::SetStencilCompareFunction(RendererComparison_Always); - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); + m_pointSpotLightShader->SendBoolean(m_pointSpotLightShaderDiscardLocation, true); + + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); + + // Rendu de la sphère comme zone d'effet + Renderer::Enable(RendererParameter_ColorWrite, true); + Renderer::Enable(RendererParameter_DepthBuffer, false); + Renderer::Enable(RendererParameter_FaceCulling, true); + Renderer::SetStencilCompareFunction(RendererComparison_NotEqual, FaceSide_Back); + Renderer::SetStencilPassOperation(nzStencilOperation_Zero, FaceSide_Back); + + m_pointSpotLightShader->SendBoolean(m_pointSpotLightShaderDiscardLocation, false); + + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); } - NzRenderer::Enable(nzRendererParameter_DepthBuffer, false); - NzRenderer::Enable(nzRendererParameter_DepthWrite, false); - NzRenderer::Enable(nzRendererParameter_FaceCulling, true); - NzRenderer::Enable(nzRendererParameter_StencilTest, true); - NzRenderer::SetFaceFilling(nzFaceFilling_Fill); - } - } + if (m_lightMeshesDrawing) + { + Renderer::Enable(RendererParameter_DepthBuffer, true); + Renderer::Enable(RendererParameter_DepthWrite, true); + Renderer::Enable(RendererParameter_FaceCulling, false); + Renderer::Enable(RendererParameter_StencilTest, false); + Renderer::SetFaceFilling(FaceFilling_Line); - if (!m_renderQueue->spotLights.empty()) - { - const NzIndexBuffer* indexBuffer = m_coneMesh->GetIndexBuffer(); - NzRenderer::SetIndexBuffer(indexBuffer); - NzRenderer::SetVertexBuffer(m_coneMesh->GetVertexBuffer()); + const Shader* shader = ShaderLibrary::Get("DebugSimple"); + static int colorLocation = shader->GetUniformLocation("Color"); - m_pointSpotLightShader->SendInteger(m_pointSpotLightUniforms.locations.type, nzLightType_Spot); - for (const auto& light : m_renderQueue->spotLights) - { - m_pointSpotLightShader->SendColor(m_pointSpotLightUniforms.locations.color, light.color); - m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.factors, NzVector2f(light.ambientFactor, light.diffuseFactor)); - m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters1, NzVector4f(light.position, light.attenuation)); - m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters2, NzVector4f(light.direction, light.invRadius)); - m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters3, NzVector2f(light.innerAngleCosine, light.outerAngleCosine)); + Renderer::SetShader(shader); + for (const auto& light : m_renderQueue->pointLights) + { + lightMatrix.SetScale(Vector3f(light.radius * 1.1f)); // Pour corriger les imperfections liées à la sphère + lightMatrix.SetTranslation(light.position); - float baseRadius = light.radius * light.outerAngleTangent * 1.1f; - lightMatrix.MakeTransform(light.position, NzQuaternionf::RotationBetween(NzVector3f::Forward(), light.direction), NzVector3f(baseRadius, baseRadius, light.radius)); + Renderer::SetMatrix(MatrixType_World, lightMatrix); - NzRenderer::SetMatrix(nzMatrixType_World, lightMatrix); + shader->SendColor(colorLocation, light.color); - // Rendu de la sphère dans le stencil buffer - NzRenderer::Enable(nzRendererParameter_ColorWrite, false); - NzRenderer::Enable(nzRendererParameter_DepthBuffer, true); - NzRenderer::Enable(nzRendererParameter_FaceCulling, false); - NzRenderer::SetStencilCompareFunction(nzRendererComparison_Always); + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); + } - m_pointSpotLightShader->SendBoolean(m_pointSpotLightShaderDiscardLocation, true); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); - - // Rendu de la sphère comme zone d'effet - NzRenderer::Enable(nzRendererParameter_ColorWrite, true); - NzRenderer::Enable(nzRendererParameter_DepthBuffer, false); - NzRenderer::Enable(nzRendererParameter_FaceCulling, true); - NzRenderer::SetFaceCulling(nzFaceSide_Front); - NzRenderer::SetStencilCompareFunction(nzRendererComparison_NotEqual, nzFaceSide_Back); - NzRenderer::SetStencilPassOperation(nzStencilOperation_Zero, nzFaceSide_Back); - - m_pointSpotLightShader->SendBoolean(m_pointSpotLightShaderDiscardLocation, false); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); + Renderer::Enable(RendererParameter_DepthBuffer, false); + Renderer::Enable(RendererParameter_DepthWrite, false); + Renderer::Enable(RendererParameter_FaceCulling, true); + Renderer::Enable(RendererParameter_StencilTest, true); + Renderer::SetFaceFilling(FaceFilling_Fill); + } } - if (m_lightMeshesDrawing) + if (!m_renderQueue->spotLights.empty()) { - NzRenderer::Enable(nzRendererParameter_DepthBuffer, true); - NzRenderer::Enable(nzRendererParameter_DepthWrite, true); - NzRenderer::Enable(nzRendererParameter_FaceCulling, false); - NzRenderer::Enable(nzRendererParameter_StencilTest, false); - NzRenderer::SetFaceFilling(nzFaceFilling_Line); + const IndexBuffer* indexBuffer = m_coneMesh->GetIndexBuffer(); + Renderer::SetIndexBuffer(indexBuffer); + Renderer::SetVertexBuffer(m_coneMesh->GetVertexBuffer()); - const NzShader* shader = NzShaderLibrary::Get("DebugSimple"); - static int colorLocation = shader->GetUniformLocation("Color"); - - NzRenderer::SetShader(shader); + m_pointSpotLightShader->SendInteger(m_pointSpotLightUniforms.locations.type, LightType_Spot); for (const auto& light : m_renderQueue->spotLights) { + m_pointSpotLightShader->SendColor(m_pointSpotLightUniforms.locations.color, light.color); + m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.factors, Vector2f(light.ambientFactor, light.diffuseFactor)); + m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters1, Vector4f(light.position, light.attenuation)); + m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters2, Vector4f(light.direction, light.invRadius)); + m_pointSpotLightShader->SendVector(m_pointSpotLightUniforms.locations.parameters3, Vector2f(light.innerAngleCosine, light.outerAngleCosine)); + float baseRadius = light.radius * light.outerAngleTangent * 1.1f; - lightMatrix.MakeTransform(light.position, NzQuaternionf::RotationBetween(NzVector3f::Forward(), light.direction), NzVector3f(baseRadius, baseRadius, light.radius)); + lightMatrix.MakeTransform(light.position, Quaternionf::RotationBetween(Vector3f::Forward(), light.direction), Vector3f(baseRadius, baseRadius, light.radius)); - NzRenderer::SetMatrix(nzMatrixType_World, lightMatrix); + Renderer::SetMatrix(MatrixType_World, lightMatrix); - shader->SendColor(colorLocation, light.color); + // Rendu de la sphère dans le stencil buffer + Renderer::Enable(RendererParameter_ColorWrite, false); + Renderer::Enable(RendererParameter_DepthBuffer, true); + Renderer::Enable(RendererParameter_FaceCulling, false); + Renderer::SetStencilCompareFunction(RendererComparison_Always); - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); + m_pointSpotLightShader->SendBoolean(m_pointSpotLightShaderDiscardLocation, true); + + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); + + // Rendu de la sphère comme zone d'effet + Renderer::Enable(RendererParameter_ColorWrite, true); + Renderer::Enable(RendererParameter_DepthBuffer, false); + Renderer::Enable(RendererParameter_FaceCulling, true); + Renderer::SetFaceCulling(FaceSide_Front); + Renderer::SetStencilCompareFunction(RendererComparison_NotEqual, FaceSide_Back); + Renderer::SetStencilPassOperation(nzStencilOperation_Zero, FaceSide_Back); + + m_pointSpotLightShader->SendBoolean(m_pointSpotLightShaderDiscardLocation, false); + + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); } - NzRenderer::Enable(nzRendererParameter_DepthBuffer, false); - NzRenderer::Enable(nzRendererParameter_DepthWrite, false); - NzRenderer::Enable(nzRendererParameter_FaceCulling, true); - NzRenderer::Enable(nzRendererParameter_StencilTest, true); - NzRenderer::SetFaceFilling(nzFaceFilling_Fill); + if (m_lightMeshesDrawing) + { + Renderer::Enable(RendererParameter_DepthBuffer, true); + Renderer::Enable(RendererParameter_DepthWrite, true); + Renderer::Enable(RendererParameter_FaceCulling, false); + Renderer::Enable(RendererParameter_StencilTest, false); + Renderer::SetFaceFilling(FaceFilling_Line); + + const Shader* shader = ShaderLibrary::Get("DebugSimple"); + static int colorLocation = shader->GetUniformLocation("Color"); + + Renderer::SetShader(shader); + for (const auto& light : m_renderQueue->spotLights) + { + float baseRadius = light.radius * light.outerAngleTangent * 1.1f; + lightMatrix.MakeTransform(light.position, Quaternionf::RotationBetween(Vector3f::Forward(), light.direction), Vector3f(baseRadius, baseRadius, light.radius)); + + Renderer::SetMatrix(MatrixType_World, lightMatrix); + + shader->SendColor(colorLocation, light.color); + + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, indexBuffer->GetIndexCount()); + } + + Renderer::Enable(RendererParameter_DepthBuffer, false); + Renderer::Enable(RendererParameter_DepthWrite, false); + Renderer::Enable(RendererParameter_FaceCulling, true); + Renderer::Enable(RendererParameter_StencilTest, true); + Renderer::SetFaceFilling(FaceFilling_Fill); + } } + + Renderer::Enable(RendererParameter_StencilTest, false); } - NzRenderer::Enable(nzRendererParameter_StencilTest, false); + return true; } - - return true; } diff --git a/src/Nazara/Graphics/DeferredRenderPass.cpp b/src/Nazara/Graphics/DeferredRenderPass.cpp index b71b3dd73..8d688c871 100644 --- a/src/Nazara/Graphics/DeferredRenderPass.cpp +++ b/src/Nazara/Graphics/DeferredRenderPass.cpp @@ -7,42 +7,45 @@ #include #include -NzDeferredRenderPass::NzDeferredRenderPass() : -m_enabled(true) +namespace Nz { -} - -NzDeferredRenderPass::~NzDeferredRenderPass() = default; - -void NzDeferredRenderPass::Enable(bool enable) -{ - m_enabled = enable; -} - -void NzDeferredRenderPass::Initialize(NzDeferredRenderTechnique* technique) -{ - m_deferredTechnique = technique; - m_renderQueue = static_cast(technique->GetRenderQueue()); - - m_depthStencilBuffer = technique->GetDepthStencilBuffer(); - - m_GBufferRTT = technique->GetGBufferRTT(); - for (unsigned int i = 0; i < 3; ++i) - m_GBuffer[i] = technique->GetGBuffer(i); - - m_workRTT = technique->GetWorkRTT(); - for (unsigned int i = 0; i < 2; ++i) - m_workTextures[i] = technique->GetWorkTexture(i); -} - -bool NzDeferredRenderPass::IsEnabled() const -{ - return m_enabled; -} - -bool NzDeferredRenderPass::Resize(const NzVector2ui& dimensions) -{ - m_dimensions = dimensions; - - return true; + DeferredRenderPass::DeferredRenderPass() : + m_enabled(true) + { + } + + DeferredRenderPass::~DeferredRenderPass() = default; + + void DeferredRenderPass::Enable(bool enable) + { + m_enabled = enable; + } + + void DeferredRenderPass::Initialize(DeferredRenderTechnique* technique) + { + m_deferredTechnique = technique; + m_renderQueue = static_cast(technique->GetRenderQueue()); + + m_depthStencilBuffer = technique->GetDepthStencilBuffer(); + + m_GBufferRTT = technique->GetGBufferRTT(); + for (unsigned int i = 0; i < 3; ++i) + m_GBuffer[i] = technique->GetGBuffer(i); + + m_workRTT = technique->GetWorkRTT(); + for (unsigned int i = 0; i < 2; ++i) + m_workTextures[i] = technique->GetWorkTexture(i); + } + + bool DeferredRenderPass::IsEnabled() const + { + return m_enabled; + } + + bool DeferredRenderPass::Resize(const Vector2ui& dimensions) + { + m_dimensions = dimensions; + + return true; + } } diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index 38941b85f..0e4512cdd 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -10,190 +10,193 @@ ///TODO: Rendre les billboards via Deferred Shading si possible -NzDeferredRenderQueue::NzDeferredRenderQueue(NzForwardRenderQueue* forwardQueue) : -m_forwardQueue(forwardQueue) +namespace Nz { -} - -void NzDeferredRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color) -{ - 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) -{ - 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); -} - -void NzDeferredRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) -{ - if (material->IsEnabled(nzRendererParameter_Blend)) - // Un matériau transparent ? J'aime pas, va voir dans la forward queue si j'y suis - m_forwardQueue->AddMesh(material, meshData, meshAABB, transformMatrix); - else + DeferredRenderQueue::DeferredRenderQueue(ForwardRenderQueue* forwardQueue) : + m_forwardQueue(forwardQueue) { - auto it = opaqueModels.find(material); - if (it == opaqueModels.end()) - { - BatchedModelEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &NzDeferredRenderQueue::OnMaterialInvalidation); - - it = opaqueModels.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedModelEntry& entry = it->second; - entry.enabled = true; - - auto& meshMap = entry.meshMap; - - auto it2 = meshMap.find(meshData); - if (it2 == meshMap.end()) - { - MeshInstanceEntry instanceEntry; - if (meshData.indexBuffer) - instanceEntry.indexBufferReleaseSlot.Connect(meshData.indexBuffer->OnIndexBufferRelease, this, &NzDeferredRenderQueue::OnIndexBufferInvalidation); - - instanceEntry.vertexBufferReleaseSlot.Connect(meshData.vertexBuffer->OnVertexBufferRelease, this, &NzDeferredRenderQueue::OnVertexBufferInvalidation); - - it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first; - } - - // On ajoute la matrice à la liste des instances de cet objet - std::vector& instances = it2->second.instances; - instances.push_back(transformMatrix); - - // Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ? - if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) - entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau } -} -void NzDeferredRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay) -{ - m_forwardQueue->AddSprites(material, vertices, spriteCount, overlay); -} - -void NzDeferredRenderQueue::Clear(bool fully) -{ - NzAbstractRenderQueue::Clear(fully); - - if (fully) - opaqueModels.clear(); - - m_forwardQueue->Clear(fully); -} - -void NzDeferredRenderQueue::OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer) -{ - for (auto& modelPair : opaqueModels) + void DeferredRenderQueue::AddBillboard(const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + m_forwardQueue->AddBillboard(material, position, size, sinCos, color); + } + + void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + { + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); + } + + void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + { + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); + } + + void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + { + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); + } + + void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + { + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); + } + + void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + { + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); + } + + void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + { + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); + } + + void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + { + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); + } + + void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + { + m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); + } + + void DeferredRenderQueue::AddDrawable(const Drawable* drawable) + { + m_forwardQueue->AddDrawable(drawable); + } + + void DeferredRenderQueue::AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) + { + if (material->IsEnabled(RendererParameter_Blend)) + // Un matériau transparent ? J'aime pas, va voir dans la forward queue si j'y suis + m_forwardQueue->AddMesh(material, meshData, meshAABB, transformMatrix); + else { - const NzMeshData& renderData = it->first; - if (renderData.indexBuffer == indexBuffer) - it = meshes.erase(it); - else - ++it; + auto it = opaqueModels.find(material); + if (it == opaqueModels.end()) + { + BatchedModelEntry entry; + entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &DeferredRenderQueue::OnMaterialInvalidation); + + it = opaqueModels.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedModelEntry& entry = it->second; + entry.enabled = true; + + auto& meshMap = entry.meshMap; + + auto it2 = meshMap.find(meshData); + if (it2 == meshMap.end()) + { + MeshInstanceEntry instanceEntry; + if (meshData.indexBuffer) + instanceEntry.indexBufferReleaseSlot.Connect(meshData.indexBuffer->OnIndexBufferRelease, this, &DeferredRenderQueue::OnIndexBufferInvalidation); + + instanceEntry.vertexBufferReleaseSlot.Connect(meshData.vertexBuffer->OnVertexBufferRelease, this, &DeferredRenderQueue::OnVertexBufferInvalidation); + + it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first; + } + + // On ajoute la matrice à la liste des instances de cet objet + std::vector& instances = it2->second.instances; + instances.push_back(transformMatrix); + + // Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ? + if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) + entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau } } -} -void NzDeferredRenderQueue::OnMaterialInvalidation(const NzMaterial* material) -{ - opaqueModels.erase(material); -} - -void NzDeferredRenderQueue::OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer) -{ - for (auto& modelPair : opaqueModels) + void DeferredRenderQueue::AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + m_forwardQueue->AddSprites(material, vertices, spriteCount, overlay); + } + + void DeferredRenderQueue::Clear(bool fully) + { + AbstractRenderQueue::Clear(fully); + + if (fully) + opaqueModels.clear(); + + m_forwardQueue->Clear(fully); + } + + void DeferredRenderQueue::OnIndexBufferInvalidation(const IndexBuffer* indexBuffer) + { + for (auto& modelPair : opaqueModels) { - const NzMeshData& renderData = it->first; - if (renderData.vertexBuffer == vertexBuffer) - it = meshes.erase(it); - else - ++it; + MeshInstanceContainer& meshes = modelPair.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.indexBuffer == indexBuffer) + it = meshes.erase(it); + else + ++it; + } } } -} - -bool NzDeferredRenderQueue::BatchedModelMaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2) const -{ - const NzUberShader* uberShader1 = mat1->GetShader(); - const NzUberShader* uberShader2 = mat2->GetShader(); - if (uberShader1 != uberShader2) - return uberShader1 < uberShader2; - - const NzShader* shader1 = mat1->GetShaderInstance(nzShaderFlags_Deferred)->GetShader(); - const NzShader* shader2 = mat2->GetShaderInstance(nzShaderFlags_Deferred)->GetShader(); - if (shader1 != shader2) - return shader1 < shader2; - - const NzTexture* diffuseMap1 = mat1->GetDiffuseMap(); - const NzTexture* diffuseMap2 = mat2->GetDiffuseMap(); - if (diffuseMap1 != diffuseMap2) - return diffuseMap1 < diffuseMap2; - - return mat1 < mat2; -} - -bool NzDeferredRenderQueue::MeshDataComparator::operator()(const NzMeshData& data1, const NzMeshData& data2) const -{ - const NzBuffer* buffer1; - const NzBuffer* buffer2; - - buffer1 = (data1.indexBuffer) ? data1.indexBuffer->GetBuffer() : nullptr; - buffer2 = (data2.indexBuffer) ? data2.indexBuffer->GetBuffer() : nullptr; - if (buffer1 != buffer2) - return buffer1 < buffer2; - - buffer1 = data1.vertexBuffer->GetBuffer(); - buffer2 = data2.vertexBuffer->GetBuffer(); - if (buffer1 != buffer2) - return buffer1 < buffer2; - - return data1.primitiveMode < data2.primitiveMode; + + void DeferredRenderQueue::OnMaterialInvalidation(const Material* material) + { + opaqueModels.erase(material); + } + + void DeferredRenderQueue::OnVertexBufferInvalidation(const VertexBuffer* vertexBuffer) + { + for (auto& modelPair : opaqueModels) + { + MeshInstanceContainer& meshes = modelPair.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.vertexBuffer == vertexBuffer) + it = meshes.erase(it); + else + ++it; + } + } + } + + bool DeferredRenderQueue::BatchedModelMaterialComparator::operator()(const Material* mat1, const Material* mat2) const + { + const UberShader* uberShader1 = mat1->GetShader(); + const UberShader* uberShader2 = mat2->GetShader(); + if (uberShader1 != uberShader2) + return uberShader1 < uberShader2; + + const Shader* shader1 = mat1->GetShaderInstance(ShaderFlags_Deferred)->GetShader(); + const Shader* shader2 = mat2->GetShaderInstance(ShaderFlags_Deferred)->GetShader(); + if (shader1 != shader2) + return shader1 < shader2; + + const Texture* diffuseMap1 = mat1->GetDiffuseMap(); + const Texture* diffuseMap2 = mat2->GetDiffuseMap(); + if (diffuseMap1 != diffuseMap2) + return diffuseMap1 < diffuseMap2; + + return mat1 < mat2; + } + + bool DeferredRenderQueue::MeshDataComparator::operator()(const MeshData& data1, const MeshData& data2) const + { + const Buffer* buffer1; + const Buffer* buffer2; + + buffer1 = (data1.indexBuffer) ? data1.indexBuffer->GetBuffer() : nullptr; + buffer2 = (data2.indexBuffer) ? data2.indexBuffer->GetBuffer() : nullptr; + if (buffer1 != buffer2) + return buffer1 < buffer2; + + buffer1 = data1.vertexBuffer->GetBuffer(); + buffer2 = data2.vertexBuffer->GetBuffer(); + if (buffer1 != buffer2) + return buffer1 < buffer2; + + return data1.primitiveMode < data2.primitiveMode; + } } diff --git a/src/Nazara/Graphics/DeferredRenderTechnique.cpp b/src/Nazara/Graphics/DeferredRenderTechnique.cpp index f660a1e22..5036d7539 100644 --- a/src/Nazara/Graphics/DeferredRenderTechnique.cpp +++ b/src/Nazara/Graphics/DeferredRenderTechnique.cpp @@ -32,543 +32,546 @@ #include #include -namespace +namespace Nz { - const nzUInt8 r_fragmentSource_BloomBright[] = { - #include - }; - - const nzUInt8 r_fragmentSource_BloomFinal[] = { - #include - }; - - const nzUInt8 r_fragmentSource_DirectionalLight[] = { - #include - }; - - const nzUInt8 r_fragmentSource_FXAA[] = { - #include - }; - - const nzUInt8 r_fragmentSource_GBufferClear[] = { - #include - }; - - const nzUInt8 r_fragmentSource_GaussianBlur[] = { - #include - }; - - const nzUInt8 r_fragmentSource_PointSpotLight[] = { - #include - }; - - unsigned int RenderPassPriority[] = + namespace { - 6, // nzRenderPassType_AA - 4, // nzRenderPassType_Bloom - 7, // nzRenderPassType_DOF - 0xFF, // nzRenderPassType_Final - 5, // nzRenderPassType_Fog - 2, // nzRenderPassType_Forward - 1, // nzRenderPassType_Lighting - 0, // nzRenderPassType_Geometry - 3, // nzRenderPassType_SSAO - }; + const UInt8 r_fragmentSource_BloomBright[] = { + #include + }; - static_assert(sizeof(RenderPassPriority)/sizeof(unsigned int) == nzRenderPassType_Max+1, "Render pass priority array is incomplete"); + const UInt8 r_fragmentSource_BloomFinal[] = { + #include + }; - inline NzShaderRef RegisterDeferredShader(const NzString& name, const nzUInt8* fragmentSource, unsigned int fragmentSourceLength, const NzShaderStage& vertexStage, NzString* err) - { - NzErrorFlags errFlags(nzErrorFlag_Silent | nzErrorFlag_ThrowExceptionDisabled); + const UInt8 r_fragmentSource_DirectionalLight[] = { + #include + }; - NzShaderRef shader = NzShader::New(); - if (!shader->Create()) + const UInt8 r_fragmentSource_FXAA[] = { + #include + }; + + const UInt8 r_fragmentSource_GBufferClear[] = { + #include + }; + + const UInt8 r_fragmentSource_GaussianBlur[] = { + #include + }; + + const UInt8 r_fragmentSource_PointSpotLight[] = { + #include + }; + + unsigned int RenderPassPriority[] = { - err->Set("Failed to create shader: " + NzError::GetLastError()); - return nullptr; + 6, // RenderPassType_AA + 4, // RenderPassType_Bloom + 7, // RenderPassType_DOF + 0xFF, // RenderPassType_Final + 5, // RenderPassType_Fog + 2, // RenderPassType_Forward + 1, // RenderPassType_Lighting + 0, // RenderPassType_Geometry + 3, // RenderPassType_SSAO + }; + + static_assert(sizeof(RenderPassPriority)/sizeof(unsigned int) == RenderPassType_Max+1, "Render pass priority array is incomplete"); + + inline ShaderRef RegisterDeferredShader(const String& name, const UInt8* fragmentSource, unsigned int fragmentSourceLength, const ShaderStage& vertexStage, String* err) + { + ErrorFlags errFlags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled); + + ShaderRef shader = Shader::New(); + if (!shader->Create()) + { + err->Set("Failed to create shader: " + Error::GetLastError()); + return nullptr; + } + + if (!shader->AttachStageFromSource(ShaderStageType_Fragment, reinterpret_cast(fragmentSource), fragmentSourceLength)) + { + err->Set("Failed to attach fragment stage: " + Error::GetLastError()); + return nullptr; + } + + shader->AttachStage(ShaderStageType_Vertex, vertexStage); + + if (!shader->Link()) + { + err->Set("Failed to link shader: " + Error::GetLastError()); + return nullptr; + } + + ShaderLibrary::Register(name, shader); + return shader; + } + } + + DeferredRenderTechnique::DeferredRenderTechnique() : + m_renderQueue(static_cast(m_forwardTechnique.GetRenderQueue())), + m_GBufferSize(0U) + { + m_depthStencilBuffer = RenderBuffer::New(); + + for (unsigned int i = 0; i < 2; ++i) + m_workTextures[i] = Texture::New(); + + for (unsigned int i = 0; i < 3; ++i) + m_GBuffer[i] = Texture::New(); + + try + { + ErrorFlags errFlags(ErrorFlag_ThrowException); + + ResetPass(RenderPassType_Final, 0); + ResetPass(RenderPassType_Geometry, 0); + ResetPass(RenderPassType_Lighting, 0); + } + catch (const std::exception& e) + { + ErrorFlags errFlags(ErrorFlag_ThrowExceptionDisabled); + + NazaraError("Failed to add geometry and/or phong lighting pass: " + String(e.what())); + throw; } - if (!shader->AttachStageFromSource(nzShaderStage_Fragment, reinterpret_cast(fragmentSource), fragmentSourceLength)) + try { - err->Set("Failed to attach fragment stage: " + NzError::GetLastError()); - return nullptr; + ErrorFlags errFlags(ErrorFlag_ThrowException); + ResetPass(RenderPassType_AA, 0); + } + catch (const std::exception& e) + { + NazaraWarning("Failed to add FXAA pass: " + String(e.what())); } - shader->AttachStage(nzShaderStage_Vertex, vertexStage); - - if (!shader->Link()) + try { - err->Set("Failed to link shader: " + NzError::GetLastError()); - return nullptr; + ErrorFlags errFlags(ErrorFlag_ThrowException); + ResetPass(RenderPassType_Bloom, 0); + } + catch (const std::exception& e) + { + NazaraWarning("Failed to add bloom pass: " + String(e.what())); } - NzShaderLibrary::Register(name, shader); - return shader; - } -} - -NzDeferredRenderTechnique::NzDeferredRenderTechnique() : -m_renderQueue(static_cast(m_forwardTechnique.GetRenderQueue())), -m_GBufferSize(0U) -{ - m_depthStencilBuffer = NzRenderBuffer::New(); - - for (unsigned int i = 0; i < 2; ++i) - m_workTextures[i] = NzTexture::New(); - - for (unsigned int i = 0; i < 3; ++i) - m_GBuffer[i] = NzTexture::New(); - - try - { - NzErrorFlags errFlags(nzErrorFlag_ThrowException); - - ResetPass(nzRenderPassType_Final, 0); - ResetPass(nzRenderPassType_Geometry, 0); - ResetPass(nzRenderPassType_Lighting, 0); - } - catch (const std::exception& e) - { - NzErrorFlags errFlags(nzErrorFlag_ThrowExceptionDisabled); - - NazaraError("Failed to add geometry and/or phong lighting pass: " + NzString(e.what())); - throw; - } - - try - { - NzErrorFlags errFlags(nzErrorFlag_ThrowException); - ResetPass(nzRenderPassType_AA, 0); - } - catch (const std::exception& e) - { - NazaraWarning("Failed to add FXAA pass: " + NzString(e.what())); - } - - try - { - NzErrorFlags errFlags(nzErrorFlag_ThrowException); - ResetPass(nzRenderPassType_Bloom, 0); - } - catch (const std::exception& e) - { - NazaraWarning("Failed to add bloom pass: " + NzString(e.what())); - } - - try - { - NzErrorFlags errFlags(nzErrorFlag_ThrowException); - - NzDeferredRenderPass* dofPass = ResetPass(nzRenderPassType_DOF, 0); - dofPass->Enable(false); - } - catch (const std::exception& e) - { - NazaraWarning("Failed to add DOF pass: " + NzString(e.what())); - } - - try - { - NzErrorFlags errFlags(nzErrorFlag_ThrowException); - - NzDeferredRenderPass* fogPass = ResetPass(nzRenderPassType_Fog, 0); - fogPass->Enable(false); - } - catch (const std::exception& e) - { - NazaraWarning("Failed to add fog pass: " + NzString(e.what())); - } - - try - { - NzErrorFlags errFlags(nzErrorFlag_ThrowException); - ResetPass(nzRenderPassType_Forward, 0); - } - catch (const std::exception& e) - { - NazaraWarning("Failed to add forward pass: " + NzString(e.what())); - } - - try - { - NzErrorFlags errFlags(nzErrorFlag_ThrowException); - ResetPass(nzRenderPassType_SSAO, 0); - } - catch (const std::exception& e) - { - NazaraWarning("Failed to add SSAO pass: " + NzString(e.what())); - } -} - -NzDeferredRenderTechnique::~NzDeferredRenderTechnique() = default; - -bool NzDeferredRenderTechnique::Draw(const NzSceneData& sceneData) const -{ - NazaraAssert(sceneData.viewer, "Invalid viewer"); - NzRecti viewerViewport = sceneData.viewer->GetViewport(); - - NzVector2ui viewportDimensions(viewerViewport.width, viewerViewport.height); - if (viewportDimensions != m_GBufferSize) - { - if (!Resize(viewportDimensions)) + try { - NazaraError("Failed to update RTT"); + ErrorFlags errFlags(ErrorFlag_ThrowException); + + DeferredRenderPass* dofPass = ResetPass(RenderPassType_DOF, 0); + dofPass->Enable(false); + } + catch (const std::exception& e) + { + NazaraWarning("Failed to add DOF pass: " + String(e.what())); + } + + try + { + ErrorFlags errFlags(ErrorFlag_ThrowException); + + DeferredRenderPass* fogPass = ResetPass(RenderPassType_Fog, 0); + fogPass->Enable(false); + } + catch (const std::exception& e) + { + NazaraWarning("Failed to add fog pass: " + String(e.what())); + } + + try + { + ErrorFlags errFlags(ErrorFlag_ThrowException); + ResetPass(RenderPassType_Forward, 0); + } + catch (const std::exception& e) + { + NazaraWarning("Failed to add forward pass: " + String(e.what())); + } + + try + { + ErrorFlags errFlags(ErrorFlag_ThrowException); + ResetPass(RenderPassType_SSAO, 0); + } + catch (const std::exception& e) + { + NazaraWarning("Failed to add SSAO pass: " + String(e.what())); + } + } + + DeferredRenderTechnique::~DeferredRenderTechnique() = default; + + bool DeferredRenderTechnique::Draw(const SceneData& sceneData) const + { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + Recti viewerViewport = sceneData.viewer->GetViewport(); + + Vector2ui viewportDimensions(viewerViewport.width, viewerViewport.height); + if (viewportDimensions != m_GBufferSize) + { + if (!Resize(viewportDimensions)) + { + NazaraError("Failed to update RTT"); + return false; + } + } + + unsigned int sceneTexture = 0; + unsigned int workTexture = 1; + for (auto& passIt : m_passes) + { + for (auto& passIt2 : passIt.second) + { + const DeferredRenderPass* pass = passIt2.second.get(); + if (pass->IsEnabled()) + { + if (pass->Process(sceneData, workTexture, sceneTexture)) + std::swap(workTexture, sceneTexture); + } + } + } + + return true; + } + + void DeferredRenderTechnique::EnablePass(RenderPassType renderPass, int position, bool enable) + { + auto it = m_passes.find(renderPass); + if (it != m_passes.end()) + { + auto it2 = it->second.find(position); + if (it2 != it->second.end()) + it2->second->Enable(enable); + } + } + + RenderBuffer* DeferredRenderTechnique::GetDepthStencilBuffer() const + { + return m_depthStencilBuffer; + } + + Texture* DeferredRenderTechnique::GetGBuffer(unsigned int i) const + { + #if NAZARA_GRAPHICS_SAFE + if (i >= 3) + { + NazaraError("GBuffer texture index out of range (" + String::Number(i) + " >= 3)"); + return nullptr; + } + #endif + + return m_GBuffer[i]; + } + + RenderTexture* DeferredRenderTechnique::GetGBufferRTT() const + { + return &m_GBufferRTT; + } + + const ForwardRenderTechnique* DeferredRenderTechnique::GetForwardTechnique() const + { + return &m_forwardTechnique; + } + + DeferredRenderPass* DeferredRenderTechnique::GetPass(RenderPassType renderPass, int position) + { + auto it = m_passes.find(renderPass); + if (it != m_passes.end()) + { + auto it2 = it->second.find(position); + if (it2 != it->second.end()) + return it2->second.get(); + } + + return nullptr; + } + + AbstractRenderQueue* DeferredRenderTechnique::GetRenderQueue() + { + return &m_renderQueue; + } + + RenderTechniqueType DeferredRenderTechnique::GetType() const + { + return RenderTechniqueType_DeferredShading; + } + + RenderTexture* DeferredRenderTechnique::GetWorkRTT() const + { + return &m_workRTT; + } + + Texture* DeferredRenderTechnique::GetWorkTexture(unsigned int i) const + { + #if NAZARA_GRAPHICS_SAFE + if (i >= 2) + { + NazaraError("Work texture index out of range (" + String::Number(i) + " >= 2)"); + return nullptr; + } + #endif + + return m_workTextures[i]; + } + + bool DeferredRenderTechnique::IsPassEnabled(RenderPassType renderPass, int position) + { + auto it = m_passes.find(renderPass); + if (it != m_passes.end()) + { + auto it2 = it->second.find(position); + if (it2 != it->second.end()) + return it2->second->IsEnabled(); + } + + return false; + } + + DeferredRenderPass* DeferredRenderTechnique::ResetPass(RenderPassType renderPass, int position) + { + std::unique_ptr smartPtr; // Nous évite un leak en cas d'exception + + switch (renderPass) + { + case RenderPassType_AA: + smartPtr.reset(new DeferredFXAAPass); + break; + + case RenderPassType_Bloom: + smartPtr.reset(new DeferredBloomPass); + break; + + case RenderPassType_DOF: + smartPtr.reset(new DeferredDOFPass); + break; + + case RenderPassType_Final: + smartPtr.reset(new DeferredFinalPass); + break; + + case RenderPassType_Fog: + smartPtr.reset(new DeferredFogPass); + break; + + case RenderPassType_Forward: + smartPtr.reset(new DeferredForwardPass); + break; + + case RenderPassType_Geometry: + smartPtr.reset(new DeferredGeometryPass); + break; + + case RenderPassType_Lighting: + smartPtr.reset(new DeferredPhongLightingPass); + break; + + case RenderPassType_SSAO: + //smartPtr.reset(new DeferredSSAOPass); + break; + } + + DeferredRenderPass* oldPass = GetPass(renderPass, position); + if (oldPass && !oldPass->IsEnabled()) + smartPtr->Enable(false); + + SetPass(renderPass, position, smartPtr.get()); + return smartPtr.release(); + } + + void DeferredRenderTechnique::SetPass(RenderPassType relativeTo, int position, DeferredRenderPass* pass) + { + if (pass) + { + pass->Initialize(this); + if (m_GBufferSize != Vector2ui(0U)) + pass->Resize(m_GBufferSize); + + m_passes[relativeTo][position].reset(pass); + } + else + m_passes[relativeTo].erase(position); + } + + bool DeferredRenderTechnique::IsSupported() + { + // On ne va pas s'embêter à écrire un Deferred Renderer qui ne passe pas par le MRT, ce serait trop lent pour servir... + return OpenGL::GetGLSLVersion() >= 140 && // On ne va pas s'embêter non plus avec le mode de compatibilité + Renderer::HasCapability(RendererCap_RenderTexture) && + Renderer::HasCapability(RendererCap_MultipleRenderTargets) && + Renderer::GetMaxColorAttachments() >= 4 && + Renderer::GetMaxRenderTargets() >= 4; + } + + bool DeferredRenderTechnique::Resize(const Vector2ui& dimensions) const + { + try + { + ErrorFlags errFlags(ErrorFlag_ThrowException); + + for (auto& passIt : m_passes) + for (auto& passIt2 : passIt.second) + passIt2.second->Resize(dimensions); + + m_GBufferSize = dimensions; + + return true; + } + catch (const std::exception& e) + { + NazaraError("Failed to create work RTT/G-Buffer: " + String(e.what())); return false; } } - unsigned int sceneTexture = 0; - unsigned int workTexture = 1; - for (auto& passIt : m_passes) + bool DeferredRenderTechnique::Initialize() { - for (auto& passIt2 : passIt.second) + const char vertexSource_Basic[] = + "#version 140\n" + + "in vec3 VertexPosition;\n" + "uniform mat4 WorldViewProjMatrix;\n" + + "void main()\n" + "{\n" + "gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0);\n" + "}\n"; + + const char vertexSource_PostProcess[] = + "#version 140\n" + + "in vec3 VertexPosition;\n" + + "void main()\n" + "{\n" + "gl_Position = vec4(VertexPosition, 1.0);" + "}\n"; + + ShaderStage basicVertexStage(ShaderStageType_Vertex); + if (!basicVertexStage.IsValid()) { - const NzDeferredRenderPass* pass = passIt2.second.get(); - if (pass->IsEnabled()) - { - if (pass->Process(sceneData, workTexture, sceneTexture)) - std::swap(workTexture, sceneTexture); - } + NazaraError("Failed to create basic vertex shader"); + return false; } - } - return true; -} + basicVertexStage.SetSource(vertexSource_Basic, sizeof(vertexSource_Basic)); -void NzDeferredRenderTechnique::EnablePass(nzRenderPassType renderPass, int position, bool enable) -{ - auto it = m_passes.find(renderPass); - if (it != m_passes.end()) - { - auto it2 = it->second.find(position); - if (it2 != it->second.end()) - it2->second->Enable(enable); - } -} + if (!basicVertexStage.Compile()) + { + NazaraError("Failed to compile basic vertex shader"); + return false; + } -NzRenderBuffer* NzDeferredRenderTechnique::GetDepthStencilBuffer() const -{ - return m_depthStencilBuffer; -} -NzTexture* NzDeferredRenderTechnique::GetGBuffer(unsigned int i) const -{ - #if NAZARA_GRAPHICS_SAFE - if (i >= 3) - { - NazaraError("GBuffer texture index out of range (" + NzString::Number(i) + " >= 3)"); - return nullptr; - } - #endif + ShaderStage ppVertexStage(ShaderStageType_Vertex); + if (!ppVertexStage.IsValid()) + { + NazaraError("Failed to create vertex shader"); + return false; + } - return m_GBuffer[i]; -} + ppVertexStage.SetSource(vertexSource_PostProcess, sizeof(vertexSource_PostProcess)); -NzRenderTexture* NzDeferredRenderTechnique::GetGBufferRTT() const -{ - return &m_GBufferRTT; -} + if (!ppVertexStage.Compile()) + { + NazaraError("Failed to compile vertex shader"); + return false; + } -const NzForwardRenderTechnique* NzDeferredRenderTechnique::GetForwardTechnique() const -{ - return &m_forwardTechnique; -} -NzDeferredRenderPass* NzDeferredRenderTechnique::GetPass(nzRenderPassType renderPass, int position) -{ - auto it = m_passes.find(renderPass); - if (it != m_passes.end()) - { - auto it2 = it->second.find(position); - if (it2 != it->second.end()) - return it2->second.get(); - } + String error; + Shader* shader; - return nullptr; -} + // Shaders critiques (Nécessaires pour le Deferred Shading minimal) + shader = RegisterDeferredShader("DeferredGBufferClear", r_fragmentSource_GBufferClear, sizeof(r_fragmentSource_GBufferClear), ppVertexStage, &error); + if (!shader) + { + NazaraError("Failed to register critical shader: " + error); + return false; + } -NzAbstractRenderQueue* NzDeferredRenderTechnique::GetRenderQueue() -{ - return &m_renderQueue; -} -nzRenderTechniqueType NzDeferredRenderTechnique::GetType() const -{ - return nzRenderTechniqueType_DeferredShading; -} + shader = RegisterDeferredShader("DeferredDirectionnalLight", r_fragmentSource_DirectionalLight, sizeof(r_fragmentSource_DirectionalLight), ppVertexStage, &error); + if (!shader) + { + NazaraError("Failed to register critical shader: " + error); + return false; + } -NzRenderTexture* NzDeferredRenderTechnique::GetWorkRTT() const -{ - return &m_workRTT; -} + shader->SendInteger(shader->GetUniformLocation("GBuffer0"), 0); + shader->SendInteger(shader->GetUniformLocation("GBuffer1"), 1); + shader->SendInteger(shader->GetUniformLocation("GBuffer2"), 2); -NzTexture* NzDeferredRenderTechnique::GetWorkTexture(unsigned int i) const -{ - #if NAZARA_GRAPHICS_SAFE - if (i >= 2) - { - NazaraError("Work texture index out of range (" + NzString::Number(i) + " >= 2)"); - return nullptr; - } - #endif - return m_workTextures[i]; -} + shader = RegisterDeferredShader("DeferredPointSpotLight", r_fragmentSource_PointSpotLight, sizeof(r_fragmentSource_PointSpotLight), basicVertexStage, &error); + if (!shader) + { + NazaraError("Failed to register critical shader: " + error); + return false; + } -bool NzDeferredRenderTechnique::IsPassEnabled(nzRenderPassType renderPass, int position) -{ - auto it = m_passes.find(renderPass); - if (it != m_passes.end()) - { - auto it2 = it->second.find(position); - if (it2 != it->second.end()) - return it2->second->IsEnabled(); - } + shader->SendInteger(shader->GetUniformLocation("GBuffer0"), 0); + shader->SendInteger(shader->GetUniformLocation("GBuffer1"), 1); + shader->SendInteger(shader->GetUniformLocation("GBuffer2"), 2); - return false; -} -NzDeferredRenderPass* NzDeferredRenderTechnique::ResetPass(nzRenderPassType renderPass, int position) -{ - std::unique_ptr smartPtr; // Nous évite un leak en cas d'exception + // Shaders optionnels (S'ils ne sont pas présents, le rendu minimal sera quand même assuré) + shader = RegisterDeferredShader("DeferredBloomBright", r_fragmentSource_BloomBright, sizeof(r_fragmentSource_BloomBright), ppVertexStage, &error); + if (shader) + shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0); + else + { + NazaraWarning("Failed to register bloom (bright pass) shader, certain features will not work: " + error); + } - switch (renderPass) - { - case nzRenderPassType_AA: - smartPtr.reset(new NzDeferredFXAAPass); - break; - case nzRenderPassType_Bloom: - smartPtr.reset(new NzDeferredBloomPass); - break; + shader = RegisterDeferredShader("DeferredBloomFinal", r_fragmentSource_BloomFinal, sizeof(r_fragmentSource_BloomFinal), ppVertexStage, &error); + if (shader) + { + shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0); + shader->SendInteger(shader->GetUniformLocation("BloomTexture"), 1); + } + else + { + NazaraWarning("Failed to register bloom (final pass) shader, certain features will not work: " + error); + } - case nzRenderPassType_DOF: - smartPtr.reset(new NzDeferredDOFPass); - break; - case nzRenderPassType_Final: - smartPtr.reset(new NzDeferredFinalPass); - break; + shader = RegisterDeferredShader("DeferredFXAA", r_fragmentSource_FXAA, sizeof(r_fragmentSource_FXAA), ppVertexStage, &error); + if (shader) + shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0); + else + { + NazaraWarning("Failed to register FXAA shader, certain features will not work: " + error); + } - case nzRenderPassType_Fog: - smartPtr.reset(new NzDeferredFogPass); - break; - case nzRenderPassType_Forward: - smartPtr.reset(new NzDeferredForwardPass); - break; - - case nzRenderPassType_Geometry: - smartPtr.reset(new NzDeferredGeometryPass); - break; - - case nzRenderPassType_Lighting: - smartPtr.reset(new NzDeferredPhongLightingPass); - break; - - case nzRenderPassType_SSAO: - //smartPtr.reset(new NzDeferredSSAOPass); - break; - } - - NzDeferredRenderPass* oldPass = GetPass(renderPass, position); - if (oldPass && !oldPass->IsEnabled()) - smartPtr->Enable(false); - - SetPass(renderPass, position, smartPtr.get()); - return smartPtr.release(); -} - -void NzDeferredRenderTechnique::SetPass(nzRenderPassType relativeTo, int position, NzDeferredRenderPass* pass) -{ - if (pass) - { - pass->Initialize(this); - if (m_GBufferSize != NzVector2ui(0U)) - pass->Resize(m_GBufferSize); - - m_passes[relativeTo][position].reset(pass); - } - else - m_passes[relativeTo].erase(position); -} - -bool NzDeferredRenderTechnique::IsSupported() -{ - // On ne va pas s'embêter à écrire un Deferred Renderer qui ne passe pas par le MRT, ce serait trop lent pour servir... - return NzOpenGL::GetGLSLVersion() >= 140 && // On ne va pas s'embêter non plus avec le mode de compatibilité - NzRenderer::HasCapability(nzRendererCap_RenderTexture) && - NzRenderer::HasCapability(nzRendererCap_MultipleRenderTargets) && - NzRenderer::GetMaxColorAttachments() >= 4 && - NzRenderer::GetMaxRenderTargets() >= 4; -} - -bool NzDeferredRenderTechnique::Resize(const NzVector2ui& dimensions) const -{ - try - { - NzErrorFlags errFlags(nzErrorFlag_ThrowException); - - for (auto& passIt : m_passes) - for (auto& passIt2 : passIt.second) - passIt2.second->Resize(dimensions); - - m_GBufferSize = dimensions; + shader = RegisterDeferredShader("DeferredGaussianBlur", r_fragmentSource_GaussianBlur, sizeof(r_fragmentSource_GaussianBlur), ppVertexStage, &error); + if (shader) + shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0); + else + { + NazaraWarning("Failed to register gaussian blur shader, certain features will not work: " + error); + } return true; } - catch (const std::exception& e) + + void DeferredRenderTechnique::Uninitialize() { - NazaraError("Failed to create work RTT/G-Buffer: " + NzString(e.what())); - return false; + ShaderLibrary::Unregister("DeferredGBufferClear"); + ShaderLibrary::Unregister("DeferredDirectionnalLight"); + ShaderLibrary::Unregister("DeferredPointSpotLight"); + ShaderLibrary::Unregister("DeferredBloomBright"); + ShaderLibrary::Unregister("DeferredBloomFinal"); + ShaderLibrary::Unregister("DeferredFXAA"); + ShaderLibrary::Unregister("DeferredGaussianBlur"); + } + + bool DeferredRenderTechnique::RenderPassComparator::operator()(RenderPassType pass1, RenderPassType pass2) const + { + return RenderPassPriority[pass1] < RenderPassPriority[pass2]; } } - -bool NzDeferredRenderTechnique::Initialize() -{ - const char vertexSource_Basic[] = - "#version 140\n" - - "in vec3 VertexPosition;\n" - "uniform mat4 WorldViewProjMatrix;\n" - - "void main()\n" - "{\n" - "gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0);\n" - "}\n"; - - const char vertexSource_PostProcess[] = - "#version 140\n" - - "in vec3 VertexPosition;\n" - - "void main()\n" - "{\n" - "gl_Position = vec4(VertexPosition, 1.0);" - "}\n"; - - NzShaderStage basicVertexStage(nzShaderStage_Vertex); - if (!basicVertexStage.IsValid()) - { - NazaraError("Failed to create basic vertex shader"); - return false; - } - - basicVertexStage.SetSource(vertexSource_Basic, sizeof(vertexSource_Basic)); - - if (!basicVertexStage.Compile()) - { - NazaraError("Failed to compile basic vertex shader"); - return false; - } - - - NzShaderStage ppVertexStage(nzShaderStage_Vertex); - if (!ppVertexStage.IsValid()) - { - NazaraError("Failed to create vertex shader"); - return false; - } - - ppVertexStage.SetSource(vertexSource_PostProcess, sizeof(vertexSource_PostProcess)); - - if (!ppVertexStage.Compile()) - { - NazaraError("Failed to compile vertex shader"); - return false; - } - - - NzString error; - NzShader* shader; - - // Shaders critiques (Nécessaires pour le Deferred Shading minimal) - shader = RegisterDeferredShader("DeferredGBufferClear", r_fragmentSource_GBufferClear, sizeof(r_fragmentSource_GBufferClear), ppVertexStage, &error); - if (!shader) - { - NazaraError("Failed to register critical shader: " + error); - return false; - } - - - shader = RegisterDeferredShader("DeferredDirectionnalLight", r_fragmentSource_DirectionalLight, sizeof(r_fragmentSource_DirectionalLight), ppVertexStage, &error); - if (!shader) - { - NazaraError("Failed to register critical shader: " + error); - return false; - } - - shader->SendInteger(shader->GetUniformLocation("GBuffer0"), 0); - shader->SendInteger(shader->GetUniformLocation("GBuffer1"), 1); - shader->SendInteger(shader->GetUniformLocation("GBuffer2"), 2); - - - shader = RegisterDeferredShader("DeferredPointSpotLight", r_fragmentSource_PointSpotLight, sizeof(r_fragmentSource_PointSpotLight), basicVertexStage, &error); - if (!shader) - { - NazaraError("Failed to register critical shader: " + error); - return false; - } - - shader->SendInteger(shader->GetUniformLocation("GBuffer0"), 0); - shader->SendInteger(shader->GetUniformLocation("GBuffer1"), 1); - shader->SendInteger(shader->GetUniformLocation("GBuffer2"), 2); - - - // Shaders optionnels (S'ils ne sont pas présents, le rendu minimal sera quand même assuré) - shader = RegisterDeferredShader("DeferredBloomBright", r_fragmentSource_BloomBright, sizeof(r_fragmentSource_BloomBright), ppVertexStage, &error); - if (shader) - shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0); - else - { - NazaraWarning("Failed to register bloom (bright pass) shader, certain features will not work: " + error); - } - - - shader = RegisterDeferredShader("DeferredBloomFinal", r_fragmentSource_BloomFinal, sizeof(r_fragmentSource_BloomFinal), ppVertexStage, &error); - if (shader) - { - shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0); - shader->SendInteger(shader->GetUniformLocation("BloomTexture"), 1); - } - else - { - NazaraWarning("Failed to register bloom (final pass) shader, certain features will not work: " + error); - } - - - shader = RegisterDeferredShader("DeferredFXAA", r_fragmentSource_FXAA, sizeof(r_fragmentSource_FXAA), ppVertexStage, &error); - if (shader) - shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0); - else - { - NazaraWarning("Failed to register FXAA shader, certain features will not work: " + error); - } - - - shader = RegisterDeferredShader("DeferredGaussianBlur", r_fragmentSource_GaussianBlur, sizeof(r_fragmentSource_GaussianBlur), ppVertexStage, &error); - if (shader) - shader->SendInteger(shader->GetUniformLocation("ColorTexture"), 0); - else - { - NazaraWarning("Failed to register gaussian blur shader, certain features will not work: " + error); - } - - return true; -} - -void NzDeferredRenderTechnique::Uninitialize() -{ - NzShaderLibrary::Unregister("DeferredGBufferClear"); - NzShaderLibrary::Unregister("DeferredDirectionnalLight"); - NzShaderLibrary::Unregister("DeferredPointSpotLight"); - NzShaderLibrary::Unregister("DeferredBloomBright"); - NzShaderLibrary::Unregister("DeferredBloomFinal"); - NzShaderLibrary::Unregister("DeferredFXAA"); - NzShaderLibrary::Unregister("DeferredGaussianBlur"); -} - -bool NzDeferredRenderTechnique::RenderPassComparator::operator()(nzRenderPassType pass1, nzRenderPassType pass2) const -{ - return RenderPassPriority[pass1] < RenderPassPriority[pass2]; -} diff --git a/src/Nazara/Graphics/Drawable.cpp b/src/Nazara/Graphics/Drawable.cpp index d6ec401a1..baac1defb 100644 --- a/src/Nazara/Graphics/Drawable.cpp +++ b/src/Nazara/Graphics/Drawable.cpp @@ -5,4 +5,7 @@ #include #include -NzDrawable::~NzDrawable() = default; +namespace Nz +{ + Drawable::~Drawable() = default; +} diff --git a/src/Nazara/Graphics/Formats/MeshLoader.cpp b/src/Nazara/Graphics/Formats/MeshLoader.cpp index 7006631e4..c4056577b 100644 --- a/src/Nazara/Graphics/Formats/MeshLoader.cpp +++ b/src/Nazara/Graphics/Formats/MeshLoader.cpp @@ -10,115 +10,122 @@ #include #include -namespace +namespace Nz { - nzTernary CheckStatic(NzInputStream& stream, const NzModelParameters& parameters) + namespace { - NazaraUnused(stream); - NazaraUnused(parameters); - - return nzTernary_Unknown; - } - - bool LoadStatic(NzModel* model, NzInputStream& stream, const NzModelParameters& parameters) - { - NazaraUnused(parameters); - - NzMeshRef mesh = NzMesh::New(); - if (!mesh->LoadFromStream(stream, parameters.mesh)) + Ternary CheckStatic(InputStream& stream, const ModelParameters& parameters) { - NazaraError("Failed to load model mesh"); - return false; + NazaraUnused(stream); + NazaraUnused(parameters); + + return Ternary_Unknown; } - if (mesh->IsAnimable()) + bool LoadStatic(Model* model, InputStream& stream, const ModelParameters& parameters) { - NazaraError("Can't load animated mesh into static model"); - return false; - } + NazaraUnused(parameters); - model->Reset(); - model->SetMesh(mesh); - - if (parameters.loadMaterials) - { - unsigned int matCount = model->GetMaterialCount(); - - for (unsigned int i = 0; i < matCount; ++i) + MeshRef mesh = Mesh::New(); + if (!mesh->LoadFromStream(stream, parameters.mesh)) { - NzString mat = mesh->GetMaterial(i); - if (!mat.IsEmpty()) + NazaraError("Failed to load model mesh"); + return false; + } + + if (mesh->IsAnimable()) + { + NazaraError("Can't load animated mesh into static model"); + return false; + } + + model->Reset(); + model->SetMesh(mesh); + + if (parameters.loadMaterials) + { + unsigned int matCount = model->GetMaterialCount(); + + for (unsigned int i = 0; i < matCount; ++i) { - NzMaterialRef material = NzMaterial::New(); - if (material->LoadFromFile(mat, parameters.material)) - model->SetMaterial(i, material); - else - NazaraWarning("Failed to load material #" + NzString::Number(i)); + String mat = mesh->GetMaterial(i); + if (!mat.IsEmpty()) + { + MaterialRef material = Material::New(); + if (material->LoadFromFile(mat, parameters.material)) + model->SetMaterial(i, material); + else + NazaraWarning("Failed to load material #" + String::Number(i)); + } } } + + return true; } - return true; - } - - nzTernary CheckAnimated(NzInputStream& stream, const NzSkeletalModelParameters& parameters) - { - NazaraUnused(stream); - NazaraUnused(parameters); - - return nzTernary_Unknown; - } - - bool LoadAnimated(NzSkeletalModel* model, NzInputStream& stream, const NzSkeletalModelParameters& parameters) - { - NazaraUnused(parameters); - - NzMeshRef mesh = NzMesh::New(); - if (!mesh->LoadFromStream(stream, parameters.mesh)) + Ternary CheckAnimated(InputStream& stream, const SkeletalModelParameters& parameters) { - NazaraError("Failed to load model mesh"); - return false; + NazaraUnused(stream); + NazaraUnused(parameters); + + return Ternary_Unknown; } - if (!mesh->IsAnimable()) + bool LoadAnimated(SkeletalModel* model, InputStream& stream, const SkeletalModelParameters& parameters) { - NazaraError("Can't load static mesh into animated model"); - return false; - } + NazaraUnused(parameters); - model->Reset(); - model->SetMesh(mesh); - - if (parameters.loadMaterials) - { - unsigned int matCount = model->GetMaterialCount(); - - for (unsigned int i = 0; i < matCount; ++i) + MeshRef mesh = Mesh::New(); + if (!mesh->LoadFromStream(stream, parameters.mesh)) { - NzString mat = mesh->GetMaterial(i); - if (!mat.IsEmpty()) + NazaraError("Failed to load model mesh"); + return false; + } + + if (!mesh->IsAnimable()) + { + NazaraError("Can't load static mesh into animated model"); + return false; + } + + model->Reset(); + model->SetMesh(mesh); + + if (parameters.loadMaterials) + { + unsigned int matCount = model->GetMaterialCount(); + + for (unsigned int i = 0; i < matCount; ++i) { - NzMaterialRef material = NzMaterial::New(); - if (material->LoadFromFile(mat, parameters.material)) - model->SetMaterial(i, material); - else - NazaraWarning("Failed to load material #" + NzString::Number(i)); + String mat = mesh->GetMaterial(i); + if (!mat.IsEmpty()) + { + MaterialRef material = Material::New(); + if (material->LoadFromFile(mat, parameters.material)) + model->SetMaterial(i, material); + else + NazaraWarning("Failed to load material #" + String::Number(i)); + } } } + + return true; + } + } + + namespace Loaders + { + void RegisterMesh() + { + ModelLoader::RegisterLoader(MeshLoader::IsExtensionSupported, CheckStatic, LoadStatic); + SkeletalModelLoader::RegisterLoader(MeshLoader::IsExtensionSupported, CheckAnimated, LoadAnimated); } - return true; + void UnregisterMesh() + { + ModelLoader::UnregisterLoader(MeshLoader::IsExtensionSupported, CheckStatic, LoadStatic); + SkeletalModelLoader::UnregisterLoader(MeshLoader::IsExtensionSupported, CheckAnimated, LoadAnimated); + } } } -void NzLoaders_Mesh_Register() -{ - NzModelLoader::RegisterLoader(NzMeshLoader::IsExtensionSupported, CheckStatic, LoadStatic); - NzSkeletalModelLoader::RegisterLoader(NzMeshLoader::IsExtensionSupported, CheckAnimated, LoadAnimated); -} - -void NzLoaders_Mesh_Unregister() -{ - NzModelLoader::UnregisterLoader(NzMeshLoader::IsExtensionSupported, CheckStatic, LoadStatic); - NzSkeletalModelLoader::UnregisterLoader(NzMeshLoader::IsExtensionSupported, CheckAnimated, LoadAnimated); -} diff --git a/src/Nazara/Graphics/Formats/MeshLoader.hpp b/src/Nazara/Graphics/Formats/MeshLoader.hpp index 44c5d98e1..db2a08bac 100644 --- a/src/Nazara/Graphics/Formats/MeshLoader.hpp +++ b/src/Nazara/Graphics/Formats/MeshLoader.hpp @@ -9,7 +9,13 @@ #include -void NzLoaders_Mesh_Register(); -void NzLoaders_Mesh_Unregister(); +namespace Nz +{ + namespace Loaders + { + void RegisterMesh(); + void UnregisterMesh(); + } +} #endif // NAZARA_LOADERS_MESH_HPP diff --git a/src/Nazara/Graphics/Formats/OBJLoader.cpp b/src/Nazara/Graphics/Formats/OBJLoader.cpp index 0bbe180c7..4462a2e1d 100644 --- a/src/Nazara/Graphics/Formats/OBJLoader.cpp +++ b/src/Nazara/Graphics/Formats/OBJLoader.cpp @@ -20,298 +20,304 @@ ///TODO: N'avoir qu'un seul VertexBuffer communs à tous les meshes -namespace +namespace Nz { - bool IsSupported(const NzString& extension) + namespace { - return (extension == "obj"); - } - - nzTernary Check(NzInputStream& stream, const NzModelParameters& parameters) - { - NazaraUnused(stream); - NazaraUnused(parameters); - - return nzTernary_Unknown; - } - - bool LoadMaterials(NzModel* model, const NzString& filePath, const NzMaterialParams& parameters, const NzString* materials, const NzOBJParser::Mesh* meshes, unsigned int meshCount) - { - NzFile file(filePath); - if (!file.Open(nzOpenMode_ReadOnly | nzOpenMode_Text)) + bool IsSupported(const String& extension) { - NazaraError("Failed to open MTL file (" + file.GetPath() + ')'); - return false; + return (extension == "obj"); } - NzMTLParser materialParser(file); - if (!materialParser.Parse()) + Ternary Check(InputStream& stream, const ModelParameters& parameters) { - NazaraError("MTL parser failed"); - return false; + NazaraUnused(stream); + NazaraUnused(parameters); + + return Ternary_Unknown; } - std::unordered_map materialCache; - NzString baseDir = file.GetDirectory(); - for (unsigned int i = 0; i < meshCount; ++i) + bool LoadMaterials(Model* model, const String& filePath, const MaterialParams& parameters, const String* materials, const OBJParser::Mesh* meshes, unsigned int meshCount) { - const NzString& matName = materials[meshes[i].material]; - const NzMTLParser::Material* mtlMat = materialParser.GetMaterial(matName); - if (!mtlMat) + File file(filePath); + if (!file.Open(OpenMode_ReadOnly | OpenMode_Text)) { - NazaraWarning("MTL has no material \"" + matName + '"'); - continue; + NazaraError("Failed to open MTL file (" + file.GetPath() + ')'); + return false; } - auto it = materialCache.find(matName); - if (it == materialCache.end()) + MTLParser materialParser(file); + if (!materialParser.Parse()) { - NzMaterialRef material = NzMaterial::New(); - material->SetShader(parameters.shaderName); + NazaraError("MTL parser failed"); + return false; + } - nzUInt8 alphaValue = static_cast(mtlMat->alpha*255.f); - - NzColor ambientColor(mtlMat->ambient); - NzColor diffuseColor(mtlMat->diffuse); - NzColor specularColor(mtlMat->specular); - ambientColor.a = alphaValue; - diffuseColor.a = alphaValue; - specularColor.a = alphaValue; - - material->SetAmbientColor(ambientColor); - material->SetDiffuseColor(diffuseColor); - material->SetSpecularColor(specularColor); - material->SetShininess(mtlMat->shininess); - - bool isTranslucent = (alphaValue != 255); - - if (parameters.loadAlphaMap && !mtlMat->alphaMap.IsEmpty()) + std::unordered_map materialCache; + String baseDir = file.GetDirectory(); + for (unsigned int i = 0; i < meshCount; ++i) + { + const String& matName = materials[meshes[i].material]; + const MTLParser::Material* mtlMat = materialParser.GetMaterial(matName); + if (!mtlMat) { - if (material->SetAlphaMap(baseDir + mtlMat->alphaMap)) - isTranslucent = true; // Une alpha map indique de la transparence + NazaraWarning("MTL has no material \"" + matName + '"'); + continue; + } + + auto it = materialCache.find(matName); + if (it == materialCache.end()) + { + MaterialRef material = Material::New(); + material->SetShader(parameters.shaderName); + + UInt8 alphaValue = static_cast(mtlMat->alpha*255.f); + + Color ambientColor(mtlMat->ambient); + Color diffuseColor(mtlMat->diffuse); + Color specularColor(mtlMat->specular); + ambientColor.a = alphaValue; + diffuseColor.a = alphaValue; + specularColor.a = alphaValue; + + material->SetAmbientColor(ambientColor); + material->SetDiffuseColor(diffuseColor); + material->SetSpecularColor(specularColor); + material->SetShininess(mtlMat->shininess); + + bool isTranslucent = (alphaValue != 255); + + if (parameters.loadAlphaMap && !mtlMat->alphaMap.IsEmpty()) + { + if (material->SetAlphaMap(baseDir + mtlMat->alphaMap)) + isTranslucent = true; // Une alpha map indique de la transparence + else + NazaraWarning("Failed to load alpha map (" + mtlMat->alphaMap + ')'); + } + + if (parameters.loadDiffuseMap && !mtlMat->diffuseMap.IsEmpty()) + { + if (!material->SetDiffuseMap(baseDir + mtlMat->diffuseMap)) + NazaraWarning("Failed to load diffuse map (" + mtlMat->diffuseMap + ')'); + } + + if (parameters.loadSpecularMap && !mtlMat->specularMap.IsEmpty()) + { + if (!material->SetSpecularMap(baseDir + mtlMat->specularMap)) + NazaraWarning("Failed to load specular map (" + mtlMat->specularMap + ')'); + } + + // Si nous avons une alpha map ou des couleurs transparentes, + // nous devons configurer le matériau pour accepter la transparence au mieux + if (isTranslucent) + { + // On paramètre le matériau pour accepter la transparence au mieux + material->Enable(RendererParameter_Blend, true); + material->Enable(RendererParameter_DepthWrite, false); + material->SetDstBlend(BlendFunc_InvSrcAlpha); + material->SetSrcBlend(BlendFunc_SrcAlpha); + } + + it = materialCache.emplace(matName, std::move(material)).first; + } + + model->SetMaterial(meshes[i].material, it->second); + } + + return true; + } + + bool Load(Model* model, InputStream& stream, const ModelParameters& parameters) + { + OBJParser parser(stream); + if (!parser.Parse()) + { + NazaraError("OBJ parser failed"); + return false; + } + + MeshRef mesh = Mesh::New(); + if (!mesh->CreateStatic()) // Ne devrait jamais échouer + { + NazaraInternalError("Failed to create mesh"); + return false; + } + + const String* materials = parser.GetMaterials(); + const Vector4f* positions = parser.GetPositions(); + const Vector3f* normals = parser.GetNormals(); + const Vector3f* texCoords = parser.GetTexCoords(); + + const OBJParser::Mesh* meshes = parser.GetMeshes(); + unsigned int meshCount = parser.GetMeshCount(); + + NazaraAssert(materials != nullptr && positions != nullptr && normals != nullptr && + texCoords != nullptr && meshes != nullptr && meshCount > 0, + "Invalid OBJParser output"); + + // Un conteneur temporaire pour contenir les indices de face avant triangulation + std::vector faceIndices(3); // Comme il y aura au moins trois sommets + for (unsigned int i = 0; i < meshCount; ++i) + { + unsigned int faceCount = meshes[i].faces.size(); + if (faceCount == 0) + continue; + + std::vector indices; + indices.reserve(faceCount*3); // Pire cas si les faces sont des triangles + + // Afin d'utiliser OBJParser::FaceVertex comme clé dans un unordered_map, + // nous devons fournir un foncteur de hash ainsi qu'un foncteur de comparaison + + // Hash + struct FaceVertexHasher + { + std::size_t operator()(const OBJParser::FaceVertex& o) const + { + std::size_t seed = 0; + HashCombine(seed, o.normal); + HashCombine(seed, o.position); + HashCombine(seed, o.texCoord); + + return seed; + } + }; + + // Comparaison + struct FaceVertexComparator + { + bool operator()(const OBJParser::FaceVertex& lhs, const OBJParser::FaceVertex& rhs) const + { + return lhs.normal == rhs.normal && + lhs.position == rhs.position && + lhs.texCoord == rhs.texCoord; + } + }; + + std::unordered_map vertices; + + unsigned int vertexCount = 0; + for (unsigned int j = 0; j < faceCount; ++j) + { + unsigned int faceVertexCount = meshes[i].faces[j].vertices.size(); + faceIndices.resize(faceVertexCount); + + for (unsigned int k = 0; k < faceVertexCount; ++k) + { + const OBJParser::FaceVertex& vertex = meshes[i].faces[j].vertices[k]; + + auto it = vertices.find(vertex); + if (it == vertices.end()) + it = vertices.emplace(vertex, vertexCount++).first; + + faceIndices[k] = it->second; + } + + for (unsigned int k = 1; k < faceVertexCount-1; ++k) + { + indices.push_back(faceIndices[0]); + indices.push_back(faceIndices[k]); + indices.push_back(faceIndices[k+1]); + } + } + + // Création des buffers + IndexBufferRef indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indices.size(), parameters.mesh.storage, BufferUsage_Static); + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.mesh.storage, BufferUsage_Static); + + // Remplissage des indices + IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly); + for (unsigned int j = 0; j < indices.size(); ++j) + indexMapper.Set(j, indices[j]); + + indexMapper.Unmap(); // Pour laisser les autres tâches affecter l'index buffer + + // Remplissage des vertices + bool hasNormals = true; + bool hasTexCoords = true; + BufferMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); + MeshVertex* meshVertices = static_cast(vertexMapper.GetPointer()); + for (auto& vertexPair : vertices) + { + const OBJParser::FaceVertex& vertexIndices = vertexPair.first; + unsigned int index = vertexPair.second; + + MeshVertex& vertex = meshVertices[index]; + + const Vector4f& vec = positions[vertexIndices.position]; + vertex.position.Set(vec.x, vec.y, vec.z); + vertex.position *= parameters.mesh.scale/vec.w; + + if (vertexIndices.normal >= 0) + vertex.normal = normals[vertexIndices.normal]; else - NazaraWarning("Failed to load alpha map (" + mtlMat->alphaMap + ')'); + hasNormals = false; + + if (vertexIndices.texCoord >= 0) + { + const Vector3f& uvw = texCoords[vertexIndices.texCoord]; + vertex.uv.Set(uvw.x, (parameters.mesh.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé + } + else + hasTexCoords = false; } - if (parameters.loadDiffuseMap && !mtlMat->diffuseMap.IsEmpty()) + vertexMapper.Unmap(); + + StaticMeshRef subMesh = StaticMesh::New(mesh); + if (!subMesh->Create(vertexBuffer)) { - if (!material->SetDiffuseMap(baseDir + mtlMat->diffuseMap)) - NazaraWarning("Failed to load diffuse map (" + mtlMat->diffuseMap + ')'); + NazaraError("Failed to create StaticMesh"); + continue; } - if (parameters.loadSpecularMap && !mtlMat->specularMap.IsEmpty()) - { - if (!material->SetSpecularMap(baseDir + mtlMat->specularMap)) - NazaraWarning("Failed to load specular map (" + mtlMat->specularMap + ')'); - } + if (parameters.mesh.optimizeIndexBuffers) + indexBuffer->Optimize(); - // Si nous avons une alpha map ou des couleurs transparentes, - // nous devons configurer le matériau pour accepter la transparence au mieux - if (isTranslucent) - { - // On paramètre le matériau pour accepter la transparence au mieux - material->Enable(nzRendererParameter_Blend, true); - material->Enable(nzRendererParameter_DepthWrite, false); - material->SetDstBlend(nzBlendFunc_InvSrcAlpha); - material->SetSrcBlend(nzBlendFunc_SrcAlpha); - } + subMesh->GenerateAABB(); + subMesh->SetIndexBuffer(indexBuffer); + subMesh->SetMaterialIndex(meshes[i].material); + subMesh->SetPrimitiveMode(PrimitiveMode_TriangleList); - it = materialCache.emplace(matName, std::move(material)).first; + // Ce que nous pouvons générer dépend des données à disposition (par exemple les tangentes nécessitent des coordonnées de texture) + if (hasNormals && hasTexCoords) + subMesh->GenerateTangents(); + else if (hasTexCoords) + subMesh->GenerateNormalsAndTangents(); + else + subMesh->GenerateNormals(); + + mesh->AddSubMesh(meshes[i].name + '_' + materials[meshes[i].material], subMesh); + } + mesh->SetMaterialCount(parser.GetMaterialCount()); + + if (parameters.mesh.center) + mesh->Recenter(); + + model->SetMesh(mesh); + + // On charge les matériaux si demandé + String mtlLib = parser.GetMtlLib(); + if (parameters.loadMaterials && !mtlLib.IsEmpty()) + { + ErrorFlags flags(ErrorFlag_ThrowExceptionDisabled); + LoadMaterials(model, stream.GetDirectory() + mtlLib, parameters.material, materials, meshes, meshCount); } - model->SetMaterial(meshes[i].material, it->second); + return true; } - - return true; } - bool Load(NzModel* model, NzInputStream& stream, const NzModelParameters& parameters) + namespace Loaders { - NzOBJParser parser(stream); - if (!parser.Parse()) + void RegisterOBJ() { - NazaraError("OBJ parser failed"); - return false; + ModelLoader::RegisterLoader(IsSupported, Check, Load); } - NzMeshRef mesh = NzMesh::New(); - if (!mesh->CreateStatic()) // Ne devrait jamais échouer + void UnregisterOBJ() { - NazaraInternalError("Failed to create mesh"); - return false; + ModelLoader::UnregisterLoader(IsSupported, Check, Load); } - - const NzString* materials = parser.GetMaterials(); - const NzVector4f* positions = parser.GetPositions(); - const NzVector3f* normals = parser.GetNormals(); - const NzVector3f* texCoords = parser.GetTexCoords(); - - const NzOBJParser::Mesh* meshes = parser.GetMeshes(); - unsigned int meshCount = parser.GetMeshCount(); - - NazaraAssert(materials != nullptr && positions != nullptr && normals != nullptr && - texCoords != nullptr && meshes != nullptr && meshCount > 0, - "Invalid OBJParser output"); - - // Un conteneur temporaire pour contenir les indices de face avant triangulation - std::vector faceIndices(3); // Comme il y aura au moins trois sommets - for (unsigned int i = 0; i < meshCount; ++i) - { - unsigned int faceCount = meshes[i].faces.size(); - if (faceCount == 0) - continue; - - std::vector indices; - indices.reserve(faceCount*3); // Pire cas si les faces sont des triangles - - // Afin d'utiliser OBJParser::FaceVertex comme clé dans un unordered_map, - // nous devons fournir un foncteur de hash ainsi qu'un foncteur de comparaison - - // Hash - struct FaceVertexHasher - { - std::size_t operator()(const NzOBJParser::FaceVertex& o) const - { - std::size_t seed = 0; - NzHashCombine(seed, o.normal); - NzHashCombine(seed, o.position); - NzHashCombine(seed, o.texCoord); - - return seed; - } - }; - - // Comparaison - struct FaceVertexComparator - { - bool operator()(const NzOBJParser::FaceVertex& lhs, const NzOBJParser::FaceVertex& rhs) const - { - return lhs.normal == rhs.normal && - lhs.position == rhs.position && - lhs.texCoord == rhs.texCoord; - } - }; - - std::unordered_map vertices; - - unsigned int vertexCount = 0; - for (unsigned int j = 0; j < faceCount; ++j) - { - unsigned int faceVertexCount = meshes[i].faces[j].vertices.size(); - faceIndices.resize(faceVertexCount); - - for (unsigned int k = 0; k < faceVertexCount; ++k) - { - const NzOBJParser::FaceVertex& vertex = meshes[i].faces[j].vertices[k]; - - auto it = vertices.find(vertex); - if (it == vertices.end()) - it = vertices.emplace(vertex, vertexCount++).first; - - faceIndices[k] = it->second; - } - - for (unsigned int k = 1; k < faceVertexCount-1; ++k) - { - indices.push_back(faceIndices[0]); - indices.push_back(faceIndices[k]); - indices.push_back(faceIndices[k+1]); - } - } - - // Création des buffers - NzIndexBufferRef indexBuffer = NzIndexBuffer::New(vertexCount > std::numeric_limits::max(), indices.size(), parameters.mesh.storage, nzBufferUsage_Static); - NzVertexBufferRef vertexBuffer = NzVertexBuffer::New(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.mesh.storage, nzBufferUsage_Static); - - // Remplissage des indices - NzIndexMapper indexMapper(indexBuffer, nzBufferAccess_WriteOnly); - for (unsigned int j = 0; j < indices.size(); ++j) - indexMapper.Set(j, indices[j]); - - indexMapper.Unmap(); // Pour laisser les autres tâches affecter l'index buffer - - // Remplissage des vertices - bool hasNormals = true; - bool hasTexCoords = true; - NzBufferMapper vertexMapper(vertexBuffer, nzBufferAccess_WriteOnly); - NzMeshVertex* meshVertices = static_cast(vertexMapper.GetPointer()); - for (auto& vertexPair : vertices) - { - const NzOBJParser::FaceVertex& vertexIndices = vertexPair.first; - unsigned int index = vertexPair.second; - - NzMeshVertex& vertex = meshVertices[index]; - - const NzVector4f& vec = positions[vertexIndices.position]; - vertex.position.Set(vec.x, vec.y, vec.z); - vertex.position *= parameters.mesh.scale/vec.w; - - if (vertexIndices.normal >= 0) - vertex.normal = normals[vertexIndices.normal]; - else - hasNormals = false; - - if (vertexIndices.texCoord >= 0) - { - const NzVector3f& uvw = texCoords[vertexIndices.texCoord]; - vertex.uv.Set(uvw.x, (parameters.mesh.flipUVs) ? 1.f - uvw.y : uvw.y); // Inversion des UVs si demandé - } - else - hasTexCoords = false; - } - - vertexMapper.Unmap(); - - NzStaticMeshRef subMesh = NzStaticMesh::New(mesh); - if (!subMesh->Create(vertexBuffer)) - { - NazaraError("Failed to create StaticMesh"); - continue; - } - - if (parameters.mesh.optimizeIndexBuffers) - indexBuffer->Optimize(); - - subMesh->GenerateAABB(); - subMesh->SetIndexBuffer(indexBuffer); - subMesh->SetMaterialIndex(meshes[i].material); - subMesh->SetPrimitiveMode(nzPrimitiveMode_TriangleList); - - // Ce que nous pouvons générer dépend des données à disposition (par exemple les tangentes nécessitent des coordonnées de texture) - if (hasNormals && hasTexCoords) - subMesh->GenerateTangents(); - else if (hasTexCoords) - subMesh->GenerateNormalsAndTangents(); - else - subMesh->GenerateNormals(); - - mesh->AddSubMesh(meshes[i].name + '_' + materials[meshes[i].material], subMesh); - } - mesh->SetMaterialCount(parser.GetMaterialCount()); - - if (parameters.mesh.center) - mesh->Recenter(); - - model->SetMesh(mesh); - - // On charge les matériaux si demandé - NzString mtlLib = parser.GetMtlLib(); - if (parameters.loadMaterials && !mtlLib.IsEmpty()) - { - NzErrorFlags flags(nzErrorFlag_ThrowExceptionDisabled); - LoadMaterials(model, stream.GetDirectory() + mtlLib, parameters.material, materials, meshes, meshCount); - } - - return true; } } - -void NzLoaders_OBJ_Register() -{ - NzModelLoader::RegisterLoader(IsSupported, Check, Load); -} - -void NzLoaders_OBJ_Unregister() -{ - NzModelLoader::UnregisterLoader(IsSupported, Check, Load); -} diff --git a/src/Nazara/Graphics/Formats/OBJLoader.hpp b/src/Nazara/Graphics/Formats/OBJLoader.hpp index 71f20f8e3..05a3efdff 100644 --- a/src/Nazara/Graphics/Formats/OBJLoader.hpp +++ b/src/Nazara/Graphics/Formats/OBJLoader.hpp @@ -9,7 +9,13 @@ #include -void NzLoaders_OBJ_Register(); -void NzLoaders_OBJ_Unregister(); +namespace Nz +{ + namespace Loaders + { + void RegisterOBJ(); + void UnregisterOBJ(); + } +} #endif // NAZARA_LOADERS_OBJ_HPP diff --git a/src/Nazara/Graphics/Formats/TextureLoader.cpp b/src/Nazara/Graphics/Formats/TextureLoader.cpp index 7fb68e226..1bea108ff 100644 --- a/src/Nazara/Graphics/Formats/TextureLoader.cpp +++ b/src/Nazara/Graphics/Formats/TextureLoader.cpp @@ -8,41 +8,47 @@ #include #include -namespace +namespace Nz { - nzTernary Check(NzInputStream& stream, const NzMaterialParams& parameters) + namespace { - NazaraUnused(stream); - NazaraUnused(parameters); - - return nzTernary_Unknown; - } - - bool Load(NzMaterial* material, NzInputStream& stream, const NzMaterialParams& parameters) - { - NazaraUnused(parameters); - - NzTextureRef texture = NzTexture::New(); - if (!texture->LoadFromStream(stream)) + Ternary Check(InputStream& stream, const MaterialParams& parameters) { - NazaraError("Failed to load diffuse map"); - return false; + NazaraUnused(stream); + NazaraUnused(parameters); + + return Ternary_Unknown; } - material->Reset(); - material->SetDiffuseMap(texture); - material->SetShader(parameters.shaderName); + bool Load(Material* material, InputStream& stream, const MaterialParams& parameters) + { + NazaraUnused(parameters); - return true; + TextureRef texture = Texture::New(); + if (!texture->LoadFromStream(stream)) + { + NazaraError("Failed to load diffuse map"); + return false; + } + + material->Reset(); + material->SetDiffuseMap(texture); + material->SetShader(parameters.shaderName); + + return true; + } + } + + namespace Loaders + { + void RegisterTexture() + { + MaterialLoader::RegisterLoader(ImageLoader::IsExtensionSupported, Check, Load); + } + + void UnregisterTexture() + { + MaterialLoader::UnregisterLoader(ImageLoader::IsExtensionSupported, Check, Load); + } } } - -void NzLoaders_Texture_Register() -{ - NzMaterialLoader::RegisterLoader(NzImageLoader::IsExtensionSupported, Check, Load); -} - -void NzLoaders_Texture_Unregister() -{ - NzMaterialLoader::UnregisterLoader(NzImageLoader::IsExtensionSupported, Check, Load); -} diff --git a/src/Nazara/Graphics/Formats/TextureLoader.hpp b/src/Nazara/Graphics/Formats/TextureLoader.hpp index 4b746b35a..7d071c050 100644 --- a/src/Nazara/Graphics/Formats/TextureLoader.hpp +++ b/src/Nazara/Graphics/Formats/TextureLoader.hpp @@ -9,7 +9,13 @@ #include -void NzLoaders_Texture_Register(); -void NzLoaders_Texture_Unregister(); +namespace Nz +{ + namespace Loaders + { + void RegisterTexture(); + void UnregisterTexture(); + } +} #endif // NAZARA_LOADERS_TEXTURE_HPP diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index 10469b1a5..a6cb47ba1 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -9,631 +9,634 @@ ///TODO: Remplacer les sinus/cosinus par une lookup table (va booster les perfs d'un bon x10) -void NzForwardRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color) +namespace Nz { - NazaraAssert(material, "Invalid material"); - - auto it = billboards.find(material); - if (it == billboards.end()) + void ForwardRenderQueue::AddBillboard(const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &NzForwardRenderQueue::OnMaterialInvalidation); + NazaraAssert(material, "Invalid material"); - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - billboardVector.push_back(BillboardData{color, position, size, sinCos}); -} - -void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr colorPtr) -{ - NazaraAssert(material, "Invalid material"); - - ///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 - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &NzForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[prevSize]; - for (unsigned int i = 0; i < count; ++i) - { - billboardData->center = *positionPtr++; - billboardData->color = *colorPtr++; - billboardData->sinCos = *sinCosPtr++; - billboardData->size = *sizePtr++; - billboardData++; - } -} - -void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr positionPtr, NzSparsePtr sizePtr, NzSparsePtr sinCosPtr, NzSparsePtr alphaPtr) -{ - NazaraAssert(material, "Invalid material"); - - ///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 - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &NzForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[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) -{ - NazaraAssert(material, "Invalid material"); - - ///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 - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &NzForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[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) -{ - NazaraAssert(material, "Invalid material"); - - ///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 - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &NzForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[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) -{ - NazaraAssert(material, "Invalid material"); - - ///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 - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &NzForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[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) -{ - NazaraAssert(material, "Invalid material"); - - ///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 - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &NzForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[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) -{ - NazaraAssert(material, "Invalid material"); - - ///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 - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &NzForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[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) -{ - NazaraAssert(material, "Invalid material"); - - ///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 - - auto it = billboards.find(material); - if (it == billboards.end()) - { - BatchedBillboardEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &NzForwardRenderQueue::OnMaterialInvalidation); - - it = billboards.insert(std::make_pair(material, std::move(entry))).first; - } - - BatchedBillboardEntry& entry = it->second; - - auto& billboardVector = entry.billboards; - unsigned int prevSize = billboardVector.size(); - billboardVector.resize(prevSize + count); - - BillboardData* billboardData = &billboardVector[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 - if (!drawable) - { - NazaraError("Invalid drawable"); - return; - } - #endif - - otherDrawables.push_back(drawable); -} - -void NzForwardRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) -{ - if (material->IsEnabled(nzRendererParameter_Blend)) - { - // Le matériau est transparent, nous devons rendre ce mesh d'une autre façon (après le rendu des objets opaques et en les triant) - unsigned int index = transparentModelData.size(); - transparentModelData.resize(index+1); - - TransparentModelData& data = transparentModelData.back(); - data.material = material; - data.meshData = meshData; - data.squaredBoundingSphere = NzSpheref(transformMatrix.GetTranslation() + meshAABB.GetCenter(), meshAABB.GetSquaredRadius()); - data.transformMatrix = transformMatrix; - - transparentModels.push_back(index); - } - else - { - auto it = opaqueModels.find(material); - if (it == opaqueModels.end()) + auto it = billboards.find(material); + if (it == billboards.end()) { - BatchedModelEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &NzForwardRenderQueue::OnMaterialInvalidation); + BatchedBillboardEntry entry; + entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); - it = opaqueModels.insert(std::make_pair(material, std::move(entry))).first; + it = billboards.insert(std::make_pair(material, std::move(entry))).first; } - BatchedModelEntry& entry = it->second; + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + billboardVector.push_back(BillboardData{color, position, size, sinCos}); + } + + void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + { + NazaraAssert(material, "Invalid material"); + + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + Vector2f 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(&Color::White, 0); // Pareil + + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry; + entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); + + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos = *sinCosPtr++; + billboardData->size = *sizePtr++; + billboardData++; + } + } + + void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + { + NazaraAssert(material, "Invalid material"); + + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + Vector2f 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 + + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry; + entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); + + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = Color(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos = *sinCosPtr++; + billboardData->size = *sizePtr++; + billboardData++; + } + } + + void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + { + NazaraAssert(material, "Invalid material"); + + ///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(&Color::White, 0); // Pareil + + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry; + entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); + + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(ToRadians(*anglePtr)); + float cos = std::cos(ToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos.Set(sin, cos); + billboardData->size = *sizePtr++; + billboardData++; + } + } + + void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + { + NazaraAssert(material, "Invalid material"); + + ///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 + + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry; + entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); + + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(ToRadians(*anglePtr)); + float cos = std::cos(ToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = Color(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos.Set(sin, cos); + billboardData->size = *sizePtr++; + billboardData++; + } + } + + void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + { + NazaraAssert(material, "Invalid material"); + + ///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + Vector2f 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(&Color::White, 0); // Pareil + + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry; + entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); + + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos = *sinCosPtr++; + billboardData->size.Set(*sizePtr++); + billboardData++; + } + } + + void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + { + NazaraAssert(material, "Invalid material"); + + ///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White + Vector2f 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 + + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry; + entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); + + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + billboardData->center = *positionPtr++; + billboardData->color = Color(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos = *sinCosPtr++; + billboardData->size.Set(*sizePtr++); + billboardData++; + } + } + + void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + { + NazaraAssert(material, "Invalid material"); + + ///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(&Color::White, 0); // Pareil + + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry; + entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); + + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(ToRadians(*anglePtr)); + float cos = std::cos(ToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = *colorPtr++; + billboardData->sinCos.Set(sin, cos); + billboardData->size.Set(*sizePtr++); + billboardData++; + } + } + + void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + { + NazaraAssert(material, "Invalid material"); + + ///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 + + auto it = billboards.find(material); + if (it == billboards.end()) + { + BatchedBillboardEntry entry; + entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); + + it = billboards.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBillboardEntry& entry = it->second; + + auto& billboardVector = entry.billboards; + unsigned int prevSize = billboardVector.size(); + billboardVector.resize(prevSize + count); + + BillboardData* billboardData = &billboardVector[prevSize]; + for (unsigned int i = 0; i < count; ++i) + { + float sin = std::sin(ToRadians(*anglePtr)); + float cos = std::cos(ToRadians(*anglePtr)); + anglePtr++; + + billboardData->center = *positionPtr++; + billboardData->color = Color(255, 255, 255, static_cast(255.f * (*alphaPtr++))); + billboardData->sinCos.Set(sin, cos); + billboardData->size.Set(*sizePtr++); + billboardData++; + } + } + + void ForwardRenderQueue::AddDrawable(const Drawable* drawable) + { + #if NAZARA_GRAPHICS_SAFE + if (!drawable) + { + NazaraError("Invalid drawable"); + return; + } + #endif + + otherDrawables.push_back(drawable); + } + + void ForwardRenderQueue::AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) + { + if (material->IsEnabled(RendererParameter_Blend)) + { + // Le matériau est transparent, nous devons rendre ce mesh d'une autre façon (après le rendu des objets opaques et en les triant) + unsigned int index = transparentModelData.size(); + transparentModelData.resize(index+1); + + TransparentModelData& data = transparentModelData.back(); + data.material = material; + data.meshData = meshData; + data.squaredBoundingSphere = Spheref(transformMatrix.GetTranslation() + meshAABB.GetCenter(), meshAABB.GetSquaredRadius()); + data.transformMatrix = transformMatrix; + + transparentModels.push_back(index); + } + else + { + auto it = opaqueModels.find(material); + if (it == opaqueModels.end()) + { + BatchedModelEntry entry; + entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); + + it = opaqueModels.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedModelEntry& entry = it->second; + entry.enabled = true; + + auto& meshMap = entry.meshMap; + + auto it2 = meshMap.find(meshData); + if (it2 == meshMap.end()) + { + MeshInstanceEntry instanceEntry; + instanceEntry.squaredBoundingSphere = meshAABB.GetSquaredBoundingSphere(); + + if (meshData.indexBuffer) + instanceEntry.indexBufferReleaseSlot.Connect(meshData.indexBuffer->OnIndexBufferRelease, this, &ForwardRenderQueue::OnIndexBufferInvalidation); + + instanceEntry.vertexBufferReleaseSlot.Connect(meshData.vertexBuffer->OnVertexBufferRelease, this, &ForwardRenderQueue::OnVertexBufferInvalidation); + + it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first; + } + + std::vector& instances = it2->second.instances; + instances.push_back(transformMatrix); + + // Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ? + if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) + entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau + } + } + + void ForwardRenderQueue::AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) + { + auto matIt = basicSprites.find(material); + if (matIt == basicSprites.end()) + { + BatchedBasicSpriteEntry entry; + entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &ForwardRenderQueue::OnMaterialInvalidation); + + matIt = basicSprites.insert(std::make_pair(material, std::move(entry))).first; + } + + BatchedBasicSpriteEntry& entry = matIt->second; entry.enabled = true; - auto& meshMap = entry.meshMap; + auto& overlayMap = entry.overlayMap; - auto it2 = meshMap.find(meshData); - if (it2 == meshMap.end()) + auto overlayIt = overlayMap.find(overlay); + if (overlayIt == overlayMap.end()) { - MeshInstanceEntry instanceEntry; - instanceEntry.squaredBoundingSphere = meshAABB.GetSquaredBoundingSphere(); + BatchedSpriteEntry overlayEntry; + if (overlay) + overlayEntry.textureReleaseSlot.Connect(overlay->OnTextureRelease, this, &ForwardRenderQueue::OnTextureInvalidation); - if (meshData.indexBuffer) - instanceEntry.indexBufferReleaseSlot.Connect(meshData.indexBuffer->OnIndexBufferRelease, this, &NzForwardRenderQueue::OnIndexBufferInvalidation); - - instanceEntry.vertexBufferReleaseSlot.Connect(meshData.vertexBuffer->OnVertexBufferRelease, this, &NzForwardRenderQueue::OnVertexBufferInvalidation); - - it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first; + overlayIt = overlayMap.insert(std::make_pair(overlay, std::move(overlayEntry))).first; } - std::vector& instances = it2->second.instances; - instances.push_back(transformMatrix); - - // Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ? - if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT) - entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau - } -} - -void NzForwardRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay) -{ - auto matIt = basicSprites.find(material); - if (matIt == basicSprites.end()) - { - BatchedBasicSpriteEntry entry; - entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, &NzForwardRenderQueue::OnMaterialInvalidation); - - matIt = basicSprites.insert(std::make_pair(material, std::move(entry))).first; + auto& spriteVector = overlayIt->second.spriteChains; + spriteVector.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount})); } - BatchedBasicSpriteEntry& entry = matIt->second; - entry.enabled = true; - - auto& overlayMap = entry.overlayMap; - - auto overlayIt = overlayMap.find(overlay); - if (overlayIt == overlayMap.end()) + void ForwardRenderQueue::Clear(bool fully) { - BatchedSpriteEntry overlayEntry; - if (overlay) - overlayEntry.textureReleaseSlot.Connect(overlay->OnTextureRelease, this, &NzForwardRenderQueue::OnTextureInvalidation); + AbstractRenderQueue::Clear(fully); - overlayIt = overlayMap.insert(std::make_pair(overlay, std::move(overlayEntry))).first; - } + otherDrawables.clear(); + transparentModels.clear(); + transparentModelData.clear(); - auto& spriteVector = overlayIt->second.spriteChains; - spriteVector.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount})); -} - -void NzForwardRenderQueue::Clear(bool fully) -{ - NzAbstractRenderQueue::Clear(fully); - - otherDrawables.clear(); - transparentModels.clear(); - transparentModelData.clear(); - - if (fully) - { - basicSprites.clear(); - billboards.clear(); - opaqueModels.clear(); - } -} - -void NzForwardRenderQueue::Sort(const NzAbstractViewer* viewer) -{ - NzPlanef nearPlane = viewer->GetFrustum().GetPlane(nzFrustumPlane_Near); - NzVector3f viewerPos = viewer->GetEyePosition(); - NzVector3f viewerNormal = viewer->GetForward(); - - std::sort(transparentModels.begin(), transparentModels.end(), [this, &nearPlane, &viewerNormal](unsigned int index1, unsigned int index2) - { - const NzSpheref& sphere1 = transparentModelData[index1].squaredBoundingSphere; - const NzSpheref& sphere2 = transparentModelData[index2].squaredBoundingSphere; - - NzVector3f position1 = sphere1.GetNegativeVertex(viewerNormal); - NzVector3f position2 = sphere2.GetNegativeVertex(viewerNormal); - - return nearPlane.Distance(position1) > nearPlane.Distance(position2); - }); - - for (auto& pair : billboards) - { - const NzMaterial* mat = pair.first; - - if (mat->IsDepthSortingEnabled()) + if (fully) { - BatchedBillboardEntry& entry = pair.second; - auto& billboardVector = entry.billboards; + basicSprites.clear(); + billboards.clear(); + opaqueModels.clear(); + } + } - std::sort(billboardVector.begin(), billboardVector.end(), [&viewerPos](const BillboardData& data1, const BillboardData& data2) + void ForwardRenderQueue::Sort(const AbstractViewer* viewer) + { + Planef nearPlane = viewer->GetFrustum().GetPlane(FrustumPlane_Near); + Vector3f viewerPos = viewer->GetEyePosition(); + Vector3f viewerNormal = viewer->GetForward(); + + std::sort(transparentModels.begin(), transparentModels.end(), [this, &nearPlane, &viewerNormal](unsigned int index1, unsigned int index2) + { + const Spheref& sphere1 = transparentModelData[index1].squaredBoundingSphere; + const Spheref& sphere2 = transparentModelData[index2].squaredBoundingSphere; + + Vector3f position1 = sphere1.GetNegativeVertex(viewerNormal); + Vector3f position2 = sphere2.GetNegativeVertex(viewerNormal); + + return nearPlane.Distance(position1) > nearPlane.Distance(position2); + }); + + for (auto& pair : billboards) + { + const Material* mat = pair.first; + + if (mat->IsDepthSortingEnabled()) { - return viewerPos.SquaredDistance(data1.center) > viewerPos.SquaredDistance(data2.center); - }); + BatchedBillboardEntry& entry = pair.second; + auto& billboardVector = entry.billboards; + + std::sort(billboardVector.begin(), billboardVector.end(), [&viewerPos](const BillboardData& data1, const BillboardData& data2) + { + return viewerPos.SquaredDistance(data1.center) > viewerPos.SquaredDistance(data2.center); + }); + } } } -} -void NzForwardRenderQueue::OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer) -{ - for (auto& modelPair : opaqueModels) + void ForwardRenderQueue::OnIndexBufferInvalidation(const IndexBuffer* indexBuffer) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + for (auto& modelPair : opaqueModels) { - const NzMeshData& renderData = it->first; - if (renderData.indexBuffer == indexBuffer) - it = meshes.erase(it); - else - ++it; + MeshInstanceContainer& meshes = modelPair.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.indexBuffer == indexBuffer) + it = meshes.erase(it); + else + ++it; + } } } -} -void NzForwardRenderQueue::OnMaterialInvalidation(const NzMaterial* material) -{ - basicSprites.erase(material); - billboards.erase(material); - opaqueModels.erase(material); -} - -void NzForwardRenderQueue::OnTextureInvalidation(const NzTexture* texture) -{ - for (auto matIt = basicSprites.begin(); matIt != basicSprites.end(); ++matIt) + void ForwardRenderQueue::OnMaterialInvalidation(const Material* material) { - auto& overlayMap = matIt->second.overlayMap; - overlayMap.erase(texture); + basicSprites.erase(material); + billboards.erase(material); + opaqueModels.erase(material); } -} -void NzForwardRenderQueue::OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer) -{ - for (auto& modelPair : opaqueModels) + void ForwardRenderQueue::OnTextureInvalidation(const Texture* texture) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + for (auto matIt = basicSprites.begin(); matIt != basicSprites.end(); ++matIt) { - const NzMeshData& renderData = it->first; - if (renderData.vertexBuffer == vertexBuffer) - it = meshes.erase(it); - else - ++it; + auto& overlayMap = matIt->second.overlayMap; + overlayMap.erase(texture); } } -} - -bool NzForwardRenderQueue::BatchedBillboardComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2) const -{ - const NzUberShader* uberShader1 = mat1->GetShader(); - const NzUberShader* uberShader2 = mat2->GetShader(); - if (uberShader1 != uberShader2) - return uberShader1 < uberShader2; - - const NzShader* shader1 = mat1->GetShaderInstance(nzShaderFlags_Billboard | nzShaderFlags_VertexColor)->GetShader(); - const NzShader* shader2 = mat2->GetShaderInstance(nzShaderFlags_Billboard | nzShaderFlags_VertexColor)->GetShader(); - if (shader1 != shader2) - return shader1 < shader2; - - const NzTexture* diffuseMap1 = mat1->GetDiffuseMap(); - const NzTexture* diffuseMap2 = mat2->GetDiffuseMap(); - if (diffuseMap1 != diffuseMap2) - return diffuseMap1 < diffuseMap2; - - return mat1 < mat2; -} - -bool NzForwardRenderQueue::BatchedModelMaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2) const -{ - const NzUberShader* uberShader1 = mat1->GetShader(); - const NzUberShader* uberShader2 = mat2->GetShader(); - if (uberShader1 != uberShader2) - return uberShader1 < uberShader2; - - const NzShader* shader1 = mat1->GetShaderInstance()->GetShader(); - const NzShader* shader2 = mat2->GetShaderInstance()->GetShader(); - if (shader1 != shader2) - return shader1 < shader2; - - const NzTexture* diffuseMap1 = mat1->GetDiffuseMap(); - const NzTexture* diffuseMap2 = mat2->GetDiffuseMap(); - if (diffuseMap1 != diffuseMap2) - return diffuseMap1 < diffuseMap2; - - return mat1 < mat2; -} - -bool NzForwardRenderQueue::BatchedSpriteMaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2) -{ - const NzUberShader* uberShader1 = mat1->GetShader(); - const NzUberShader* uberShader2 = mat2->GetShader(); - if (uberShader1 != uberShader2) - return uberShader1 < uberShader2; - - const NzShader* shader1 = mat1->GetShaderInstance()->GetShader(); - const NzShader* shader2 = mat2->GetShaderInstance()->GetShader(); - if (shader1 != shader2) - return shader1 < shader2; - - const NzTexture* diffuseMap1 = mat1->GetDiffuseMap(); - const NzTexture* diffuseMap2 = mat2->GetDiffuseMap(); - if (diffuseMap1 != diffuseMap2) - return diffuseMap1 < diffuseMap2; - - return mat1 < mat2; -} - -bool NzForwardRenderQueue::MeshDataComparator::operator()(const NzMeshData& data1, const NzMeshData& data2) const -{ - const NzBuffer* buffer1; - const NzBuffer* buffer2; - - buffer1 = (data1.indexBuffer) ? data1.indexBuffer->GetBuffer() : nullptr; - buffer2 = (data2.indexBuffer) ? data2.indexBuffer->GetBuffer() : nullptr; - if (buffer1 != buffer2) - return buffer1 < buffer2; - - buffer1 = data1.vertexBuffer->GetBuffer(); - buffer2 = data2.vertexBuffer->GetBuffer(); - if (buffer1 != buffer2) - return buffer1 < buffer2; - - return data1.primitiveMode < data2.primitiveMode; + + void ForwardRenderQueue::OnVertexBufferInvalidation(const VertexBuffer* vertexBuffer) + { + for (auto& modelPair : opaqueModels) + { + MeshInstanceContainer& meshes = modelPair.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.vertexBuffer == vertexBuffer) + it = meshes.erase(it); + else + ++it; + } + } + } + + bool ForwardRenderQueue::BatchedBillboardComparator::operator()(const Material* mat1, const Material* mat2) const + { + const UberShader* uberShader1 = mat1->GetShader(); + const UberShader* uberShader2 = mat2->GetShader(); + if (uberShader1 != uberShader2) + return uberShader1 < uberShader2; + + const Shader* shader1 = mat1->GetShaderInstance(ShaderFlags_Billboard | ShaderFlags_VertexColor)->GetShader(); + const Shader* shader2 = mat2->GetShaderInstance(ShaderFlags_Billboard | ShaderFlags_VertexColor)->GetShader(); + if (shader1 != shader2) + return shader1 < shader2; + + const Texture* diffuseMap1 = mat1->GetDiffuseMap(); + const Texture* diffuseMap2 = mat2->GetDiffuseMap(); + if (diffuseMap1 != diffuseMap2) + return diffuseMap1 < diffuseMap2; + + return mat1 < mat2; + } + + bool ForwardRenderQueue::BatchedModelMaterialComparator::operator()(const Material* mat1, const Material* mat2) const + { + const UberShader* uberShader1 = mat1->GetShader(); + const UberShader* uberShader2 = mat2->GetShader(); + if (uberShader1 != uberShader2) + return uberShader1 < uberShader2; + + const Shader* shader1 = mat1->GetShaderInstance()->GetShader(); + const Shader* shader2 = mat2->GetShaderInstance()->GetShader(); + if (shader1 != shader2) + return shader1 < shader2; + + const Texture* diffuseMap1 = mat1->GetDiffuseMap(); + const Texture* diffuseMap2 = mat2->GetDiffuseMap(); + if (diffuseMap1 != diffuseMap2) + return diffuseMap1 < diffuseMap2; + + return mat1 < mat2; + } + + bool ForwardRenderQueue::BatchedSpriteMaterialComparator::operator()(const Material* mat1, const Material* mat2) + { + const UberShader* uberShader1 = mat1->GetShader(); + const UberShader* uberShader2 = mat2->GetShader(); + if (uberShader1 != uberShader2) + return uberShader1 < uberShader2; + + const Shader* shader1 = mat1->GetShaderInstance()->GetShader(); + const Shader* shader2 = mat2->GetShaderInstance()->GetShader(); + if (shader1 != shader2) + return shader1 < shader2; + + const Texture* diffuseMap1 = mat1->GetDiffuseMap(); + const Texture* diffuseMap2 = mat2->GetDiffuseMap(); + if (diffuseMap1 != diffuseMap2) + return diffuseMap1 < diffuseMap2; + + return mat1 < mat2; + } + + bool ForwardRenderQueue::MeshDataComparator::operator()(const MeshData& data1, const MeshData& data2) const + { + const Buffer* buffer1; + const Buffer* buffer2; + + buffer1 = (data1.indexBuffer) ? data1.indexBuffer->GetBuffer() : nullptr; + buffer2 = (data2.indexBuffer) ? data2.indexBuffer->GetBuffer() : nullptr; + if (buffer1 != buffer2) + return buffer1 < buffer2; + + buffer1 = data1.vertexBuffer->GetBuffer(); + buffer2 = data2.vertexBuffer->GetBuffer(); + if (buffer1 != buffer2) + return buffer1 < buffer2; + + return data1.primitiveMode < data2.primitiveMode; + } } diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index f8b5255bb..75768a3fa 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -20,228 +20,320 @@ #include #include -namespace +namespace Nz { - struct BillboardPoint + namespace { - NzColor color; - NzVector3f position; - NzVector2f size; - NzVector2f sinCos; // doit suivre size - NzVector2f uv; - }; - - unsigned int s_maxQuads = std::numeric_limits::max()/6; - unsigned int s_vertexBufferSize = 4*1024*1024; // 4 MiB -} - -NzForwardRenderTechnique::NzForwardRenderTechnique() : -m_vertexBuffer(nzBufferType_Vertex), -m_maxLightPassPerObject(3) -{ - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - m_vertexBuffer.Create(s_vertexBufferSize, nzDataStorage_Hardware, nzBufferUsage_Dynamic); - - m_billboardPointBuffer.Reset(&s_billboardVertexDeclaration, &m_vertexBuffer); - m_spriteBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Color_UV), &m_vertexBuffer); -} - -bool NzForwardRenderTechnique::Draw(const NzSceneData& sceneData) const -{ - NazaraAssert(sceneData.viewer, "Invalid viewer"); - - m_renderQueue.Sort(sceneData.viewer); - - NzRenderer::Enable(nzRendererParameter_DepthBuffer, true); - NzRenderer::Enable(nzRendererParameter_DepthWrite, true); - NzRenderer::Clear(nzRendererBuffer_Depth); - - if (sceneData.background) - sceneData.background->Draw(sceneData.viewer); - - if (!m_renderQueue.opaqueModels.empty()) - DrawOpaqueModels(sceneData); - - if (!m_renderQueue.transparentModels.empty()) - DrawTransparentModels(sceneData); - - if (!m_renderQueue.basicSprites.empty()) - DrawBasicSprites(sceneData); - - if (!m_renderQueue.billboards.empty()) - DrawBillboards(sceneData); - - // Les autres drawables (Exemple: Terrain) - for (const NzDrawable* drawable : m_renderQueue.otherDrawables) - drawable->Draw(); - - return true; -} - -unsigned int NzForwardRenderTechnique::GetMaxLightPassPerObject() const -{ - return m_maxLightPassPerObject; -} - -NzAbstractRenderQueue* NzForwardRenderTechnique::GetRenderQueue() -{ - return &m_renderQueue; -} - -nzRenderTechniqueType NzForwardRenderTechnique::GetType() const -{ - return nzRenderTechniqueType_BasicForward; -} - -void NzForwardRenderTechnique::SetMaxLightPassPerObject(unsigned int passCount) -{ - m_maxLightPassPerObject = passCount; -} - -bool NzForwardRenderTechnique::Initialize() -{ - try - { - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - s_quadIndexBuffer.Reset(false, s_maxQuads*6, nzDataStorage_Hardware, nzBufferUsage_Static); - - NzBufferMapper mapper(s_quadIndexBuffer, nzBufferAccess_WriteOnly); - nzUInt16* indices = static_cast(mapper.GetPointer()); - - for (unsigned int i = 0; i < s_maxQuads; ++i) + struct BillboardPoint { - *indices++ = i*4 + 0; - *indices++ = i*4 + 2; - *indices++ = i*4 + 1; - - *indices++ = i*4 + 2; - *indices++ = i*4 + 3; - *indices++ = i*4 + 1; - } - - mapper.Unmap(); // Inutile de garder le buffer ouvert plus longtemps - - // Quad buffer (utilisé pour l'instancing de billboard et de sprites) - //Note: Les UV sont calculés dans le shader - s_quadVertexBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzDataStorage_Hardware, nzBufferUsage_Static); - - float vertices[2*4] = { - -0.5f, -0.5f, - 0.5f, -0.5f, - -0.5f, 0.5f, - 0.5f, 0.5f, + Color color; + Vector3f position; + Vector2f size; + Vector2f sinCos; // doit suivre size + Vector2f uv; }; - s_quadVertexBuffer.FillRaw(vertices, 0, sizeof(vertices)); - - // Déclaration lors du rendu des billboards par sommet - s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(BillboardPoint, color)); - s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(BillboardPoint, position)); - s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(BillboardPoint, uv)); - s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Userdata0, nzComponentType_Float4, NzOffsetOf(BillboardPoint, size)); // Englobe sincos - - // Declaration utilisée lors du rendu des billboards par instancing - // L'avantage ici est la copie directe (std::memcpy) des données de la RenderQueue vers le buffer GPU - s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData0, nzComponentType_Float3, NzOffsetOf(NzForwardRenderQueue::BillboardData, center)); - s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData1, nzComponentType_Float4, NzOffsetOf(NzForwardRenderQueue::BillboardData, size)); // Englobe sincos - s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData2, nzComponentType_Color, NzOffsetOf(NzForwardRenderQueue::BillboardData, color)); - } - catch (const std::exception& e) - { - NazaraError("Failed to initialise: " + NzString(e.what())); - return false; + unsigned int s_maxQuads = std::numeric_limits::max()/6; + unsigned int s_vertexBufferSize = 4*1024*1024; // 4 MiB } - return true; -} - -void NzForwardRenderTechnique::Uninitialize() -{ - s_quadIndexBuffer.Reset(); - s_quadVertexBuffer.Reset(); -} - -void NzForwardRenderTechnique::ChooseLights(const NzSpheref& object, bool includeDirectionalLights) const -{ - m_lights.clear(); - - // First step: add all the lights into a common list and compute their score, exlucing those who have no chance of lighting the object - // (Those who are too far away). - - if (includeDirectionalLights) + ForwardRenderTechnique::ForwardRenderTechnique() : + m_vertexBuffer(BufferType_Vertex), + m_maxLightPassPerObject(3) { - for (unsigned int i = 0; i < m_renderQueue.directionalLights.size(); ++i) + ErrorFlags flags(ErrorFlag_ThrowException, true); + + m_vertexBuffer.Create(s_vertexBufferSize, DataStorage_Hardware, BufferUsage_Dynamic); + + m_billboardPointBuffer.Reset(&s_billboardVertexDeclaration, &m_vertexBuffer); + m_spriteBuffer.Reset(VertexDeclaration::Get(VertexLayout_XYZ_Color_UV), &m_vertexBuffer); + } + + bool ForwardRenderTechnique::Draw(const SceneData& sceneData) const + { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + + m_renderQueue.Sort(sceneData.viewer); + + Renderer::Enable(RendererParameter_DepthBuffer, true); + Renderer::Enable(RendererParameter_DepthWrite, true); + Renderer::Clear(RendererBuffer_Depth); + + if (sceneData.background) + sceneData.background->Draw(sceneData.viewer); + + if (!m_renderQueue.opaqueModels.empty()) + DrawOpaqueModels(sceneData); + + if (!m_renderQueue.transparentModels.empty()) + DrawTransparentModels(sceneData); + + if (!m_renderQueue.basicSprites.empty()) + DrawBasicSprites(sceneData); + + if (!m_renderQueue.billboards.empty()) + DrawBillboards(sceneData); + + // Les autres drawables (Exemple: Terrain) + for (const Drawable* drawable : m_renderQueue.otherDrawables) + drawable->Draw(); + + return true; + } + + unsigned int ForwardRenderTechnique::GetMaxLightPassPerObject() const + { + return m_maxLightPassPerObject; + } + + AbstractRenderQueue* ForwardRenderTechnique::GetRenderQueue() + { + return &m_renderQueue; + } + + RenderTechniqueType ForwardRenderTechnique::GetType() const + { + return RenderTechniqueType_BasicForward; + } + + void ForwardRenderTechnique::SetMaxLightPassPerObject(unsigned int passCount) + { + m_maxLightPassPerObject = passCount; + } + + bool ForwardRenderTechnique::Initialize() + { + try { - const auto& light = m_renderQueue.directionalLights[i]; - if (IsDirectionalLightSuitable(object, light)) - m_lights.push_back({nzLightType_Directional, ComputeDirectionalLightScore(object, light), i}); + ErrorFlags flags(ErrorFlag_ThrowException, true); + + s_quadIndexBuffer.Reset(false, s_maxQuads*6, DataStorage_Hardware, BufferUsage_Static); + + BufferMapper mapper(s_quadIndexBuffer, BufferAccess_WriteOnly); + UInt16* indices = static_cast(mapper.GetPointer()); + + for (unsigned int i = 0; i < s_maxQuads; ++i) + { + *indices++ = i*4 + 0; + *indices++ = i*4 + 2; + *indices++ = i*4 + 1; + + *indices++ = i*4 + 2; + *indices++ = i*4 + 3; + *indices++ = i*4 + 1; + } + + mapper.Unmap(); // Inutile de garder le buffer ouvert plus longtemps + + // Quad buffer (utilisé pour l'instancing de billboard et de sprites) + //Note: Les UV sont calculés dans le shader + s_quadVertexBuffer.Reset(VertexDeclaration::Get(VertexLayout_XY), 4, DataStorage_Hardware, BufferUsage_Static); + + float vertices[2*4] = { + -0.5f, -0.5f, + 0.5f, -0.5f, + -0.5f, 0.5f, + 0.5f, 0.5f, + }; + + s_quadVertexBuffer.FillRaw(vertices, 0, sizeof(vertices)); + + // Déclaration lors du rendu des billboards par sommet + s_billboardVertexDeclaration.EnableComponent(VertexComponent_Color, ComponentType_Color, NazaraOffsetOf(BillboardPoint, color)); + s_billboardVertexDeclaration.EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(BillboardPoint, position)); + s_billboardVertexDeclaration.EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(BillboardPoint, uv)); + s_billboardVertexDeclaration.EnableComponent(VertexComponent_Userdata0, ComponentType_Float4, NazaraOffsetOf(BillboardPoint, size)); // Englobe sincos + + // Declaration utilisée lors du rendu des billboards par instancing + // L'avantage ici est la copie directe (std::memcpy) des données de la RenderQueue vers le buffer GPU + s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData0, ComponentType_Float3, NazaraOffsetOf(ForwardRenderQueue::BillboardData, center)); + s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData1, ComponentType_Float4, NazaraOffsetOf(ForwardRenderQueue::BillboardData, size)); // Englobe sincos + s_billboardInstanceDeclaration.EnableComponent(VertexComponent_InstanceData2, ComponentType_Color, NazaraOffsetOf(ForwardRenderQueue::BillboardData, color)); + } + catch (const std::exception& e) + { + NazaraError("Failed to initialise: " + String(e.what())); + return false; + } + + return true; + } + + void ForwardRenderTechnique::Uninitialize() + { + s_quadIndexBuffer.Reset(); + s_quadVertexBuffer.Reset(); + } + + void ForwardRenderTechnique::ChooseLights(const Spheref& object, bool includeDirectionalLights) const + { + m_lights.clear(); + + // First step: add all the lights into a common list and compute their score, exlucing those who have no chance of lighting the object + // (Those who are too far away). + + if (includeDirectionalLights) + { + for (unsigned int i = 0; i < m_renderQueue.directionalLights.size(); ++i) + { + const auto& light = m_renderQueue.directionalLights[i]; + if (IsDirectionalLightSuitable(object, light)) + m_lights.push_back({LightType_Directional, ComputeDirectionalLightScore(object, light), i}); + } + } + + for (unsigned int i = 0; i < m_renderQueue.pointLights.size(); ++i) + { + const auto& light = m_renderQueue.pointLights[i]; + if (IsPointLightSuitable(object, light)) + m_lights.push_back({LightType_Point, ComputePointLightScore(object, light), i}); + } + + for (unsigned int i = 0; i < m_renderQueue.spotLights.size(); ++i) + { + const auto& light = m_renderQueue.spotLights[i]; + if (IsSpotLightSuitable(object, light)) + m_lights.push_back({LightType_Spot, ComputeSpotLightScore(object, light), i}); + } + + // Then, sort the lights according to their score + std::sort(m_lights.begin(), m_lights.end(), [](const LightIndex& light1, const LightIndex& light2) + { + return light1.score < light2.score; + }); + } + + void ForwardRenderTechnique::DrawBasicSprites(const SceneData& sceneData) const + { + NazaraAssert(sceneData.viewer, "Invalid viewer"); + + const Shader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; + + Renderer::SetIndexBuffer(&s_quadIndexBuffer); + Renderer::SetMatrix(MatrixType_World, Matrix4f::Identity()); + Renderer::SetVertexBuffer(&m_spriteBuffer); + + for (auto& matIt : m_renderQueue.basicSprites) + { + const Material* material = matIt.first; + auto& matEntry = matIt.second; + + if (matEntry.enabled) + { + auto& overlayMap = matEntry.overlayMap; + for (auto& overlayIt : overlayMap) + { + const Texture* overlay = overlayIt.first; + auto& spriteChainVector = overlayIt.second.spriteChains; + + unsigned int spriteChainCount = spriteChainVector.size(); + if (spriteChainCount > 0) + { + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + UInt32 flags = ShaderFlags_VertexColor; + if (overlay) + flags |= ShaderFlags_TextureOverlay; + + UInt8 overlayUnit; + const Shader* shader = material->Apply(flags, 0, &overlayUnit); + + if (overlay) + { + overlayUnit++; + Renderer::SetTexture(overlayUnit, overlay); + Renderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); + } + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) + { + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); + + // Couleur ambiante de la scène + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Overlay + shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + + lastShader = shader; + } + + unsigned int spriteChain = 0; // Quelle chaîne de sprite traitons-nous + unsigned int spriteChainOffset = 0; // À quel offset dans la dernière chaîne nous sommes-nous arrêtés + + do + { + // On ouvre le buffer en écriture + BufferMapper vertexMapper(m_spriteBuffer, BufferAccess_DiscardAndWrite); + VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + + unsigned int spriteCount = 0; + unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4); + + do + { + ForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; + unsigned int count = std::min(maxSpriteCount - spriteCount, currentChain.spriteCount - spriteChainOffset); + + std::memcpy(vertices, currentChain.vertices + spriteChainOffset*4, 4*count*sizeof(VertexStruct_XYZ_Color_UV)); + vertices += count*4; + + spriteCount += count; + spriteChainOffset += count; + + // Avons-nous traité la chaîne entière ? + if (spriteChainOffset == currentChain.spriteCount) + { + spriteChain++; + spriteChainOffset = 0; + } + } + while (spriteCount < maxSpriteCount && spriteChain < spriteChainCount); + + vertexMapper.Unmap(); + + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, spriteCount*6); + } + while (spriteChain < spriteChainCount); + + spriteChainVector.clear(); + } + } + + // On remet à zéro + matEntry.enabled = false; + } } } - for (unsigned int i = 0; i < m_renderQueue.pointLights.size(); ++i) + void ForwardRenderTechnique::DrawBillboards(const SceneData& sceneData) const { - const auto& light = m_renderQueue.pointLights[i]; - if (IsPointLightSuitable(object, light)) - m_lights.push_back({nzLightType_Point, ComputePointLightScore(object, light), i}); - } + NazaraAssert(sceneData.viewer, "Invalid viewer"); - for (unsigned int i = 0; i < m_renderQueue.spotLights.size(); ++i) - { - const auto& light = m_renderQueue.spotLights[i]; - if (IsSpotLightSuitable(object, light)) - m_lights.push_back({nzLightType_Spot, ComputeSpotLightScore(object, light), i}); - } + const Shader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; - // Then, sort the lights according to their score - std::sort(m_lights.begin(), m_lights.end(), [](const LightIndex& light1, const LightIndex& light2) - { - return light1.score < light2.score; - }); -} - -void NzForwardRenderTechnique::DrawBasicSprites(const NzSceneData& sceneData) const -{ - NazaraAssert(sceneData.viewer, "Invalid viewer"); - - const NzShader* lastShader = nullptr; - const ShaderUniforms* shaderUniforms = nullptr; - - NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); - NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity()); - NzRenderer::SetVertexBuffer(&m_spriteBuffer); - - for (auto& matIt : m_renderQueue.basicSprites) - { - const NzMaterial* material = matIt.first; - auto& matEntry = matIt.second; - - if (matEntry.enabled) + if (Renderer::HasCapability(RendererCap_Instancing)) { - auto& overlayMap = matEntry.overlayMap; - for (auto& overlayIt : overlayMap) - { - const NzTexture* overlay = overlayIt.first; - auto& spriteChainVector = overlayIt.second.spriteChains; + VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(&s_billboardInstanceDeclaration); - unsigned int spriteChainCount = spriteChainVector.size(); - if (spriteChainCount > 0) + Renderer::SetVertexBuffer(&s_quadVertexBuffer); + + for (auto& matIt : m_renderQueue.billboards) + { + const Material* material = matIt.first; + auto& entry = matIt.second; + auto& billboardVector = entry.billboards; + + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) { // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - nzUInt32 flags = nzShaderFlags_VertexColor; - if (overlay) - flags |= nzShaderFlags_TextureOverlay; - - nzUInt8 overlayUnit; - const NzShader* shader = material->Apply(flags, 0, &overlayUnit); - - if (overlay) - { - overlayUnit++; - NzRenderer::SetTexture(overlayUnit, overlay); - NzRenderer::SetTextureSampler(overlayUnit, material->GetDiffuseSampler()); - } + const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_Instancing | ShaderFlags_VertexColor); // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas if (shader != lastShader) @@ -251,362 +343,213 @@ void NzForwardRenderTechnique::DrawBasicSprites(const NzSceneData& sceneData) co // Couleur ambiante de la scène shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Overlay - shader->SendInteger(shaderUniforms->textureOverlay, overlayUnit); // Position de la caméra shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); lastShader = shader; } - unsigned int spriteChain = 0; // Quelle chaîne de sprite traitons-nous - unsigned int spriteChainOffset = 0; // À quel offset dans la dernière chaîne nous sommes-nous arrêtés + const ForwardRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = instanceBuffer->GetVertexCount(); + do + { + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; + + instanceBuffer->Fill(data, 0, renderedBillboardCount, true); + data += renderedBillboardCount; + + Renderer::DrawPrimitivesInstanced(renderedBillboardCount, PrimitiveMode_TriangleStrip, 0, 4); + } + while (billboardCount > 0); + + billboardVector.clear(); + } + } + } + else + { + Renderer::SetIndexBuffer(&s_quadIndexBuffer); + Renderer::SetVertexBuffer(&m_billboardPointBuffer); + + for (auto& matIt : m_renderQueue.billboards) + { + const Material* material = matIt.first; + auto& entry = matIt.second; + auto& billboardVector = entry.billboards; + + unsigned int billboardCount = billboardVector.size(); + if (billboardCount > 0) + { + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + const Shader* shader = material->Apply(ShaderFlags_Billboard | ShaderFlags_VertexColor); + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) + { + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); + + // Couleur ambiante de la scène + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + + lastShader = shader; + } + + const ForwardRenderQueue::BillboardData* data = &billboardVector[0]; + unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount()/4); do { - // On ouvre le buffer en écriture - NzBufferMapper vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite); - NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(vertexMapper.GetPointer()); + unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); + billboardCount -= renderedBillboardCount; - unsigned int spriteCount = 0; - unsigned int maxSpriteCount = std::min(s_maxQuads, m_spriteBuffer.GetVertexCount()/4); + BufferMapper vertexMapper(m_billboardPointBuffer, BufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); + BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); - do + for (unsigned int i = 0; i < renderedBillboardCount; ++i) { - NzForwardRenderQueue::SpriteChain_XYZ_Color_UV& currentChain = spriteChainVector[spriteChain]; - unsigned int count = std::min(maxSpriteCount - spriteCount, currentChain.spriteCount - spriteChainOffset); + const ForwardRenderQueue::BillboardData& billboard = *data++; - std::memcpy(vertices, currentChain.vertices + spriteChainOffset*4, 4*count*sizeof(NzVertexStruct_XYZ_Color_UV)); - vertices += count*4; + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(0.f, 1.f); + vertices++; - spriteCount += count; - spriteChainOffset += count; + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(1.f, 1.f); + vertices++; - // Avons-nous traité la chaîne entière ? - if (spriteChainOffset == currentChain.spriteCount) - { - spriteChain++; - spriteChainOffset = 0; - } + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(0.f, 0.f); + vertices++; + + vertices->color = billboard.color; + vertices->position = billboard.center; + vertices->sinCos = billboard.sinCos; + vertices->size = billboard.size; + vertices->uv.Set(1.f, 0.f); + vertices++; } - while (spriteCount < maxSpriteCount && spriteChain < spriteChainCount); vertexMapper.Unmap(); - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, spriteCount*6); + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, renderedBillboardCount*6); } - while (spriteChain < spriteChainCount); + while (billboardCount > 0); - spriteChainVector.clear(); + billboardVector.clear(); } } - - // On remet à zéro - matEntry.enabled = false; - } - } -} - -void NzForwardRenderTechnique::DrawBillboards(const NzSceneData& sceneData) const -{ - NazaraAssert(sceneData.viewer, "Invalid viewer"); - - const NzShader* lastShader = nullptr; - const ShaderUniforms* shaderUniforms = nullptr; - - if (NzRenderer::HasCapability(nzRendererCap_Instancing)) - { - NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer(); - instanceBuffer->SetVertexDeclaration(&s_billboardInstanceDeclaration); - - NzRenderer::SetVertexBuffer(&s_quadVertexBuffer); - - for (auto& matIt : m_renderQueue.billboards) - { - const NzMaterial* material = matIt.first; - auto& entry = matIt.second; - auto& billboardVector = entry.billboards; - - unsigned int billboardCount = billboardVector.size(); - if (billboardCount > 0) - { - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - const NzShader* shader = material->Apply(nzShaderFlags_Billboard | nzShaderFlags_Instancing | nzShaderFlags_VertexColor); - - // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas - if (shader != lastShader) - { - // Index des uniformes dans le shader - shaderUniforms = GetShaderUniforms(shader); - - // Couleur ambiante de la scène - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position de la caméra - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); - - lastShader = shader; - } - - const NzForwardRenderQueue::BillboardData* data = &billboardVector[0]; - unsigned int maxBillboardPerDraw = instanceBuffer->GetVertexCount(); - do - { - unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); - billboardCount -= renderedBillboardCount; - - instanceBuffer->Fill(data, 0, renderedBillboardCount, true); - data += renderedBillboardCount; - - NzRenderer::DrawPrimitivesInstanced(renderedBillboardCount, nzPrimitiveMode_TriangleStrip, 0, 4); - } - while (billboardCount > 0); - - billboardVector.clear(); - } } } - else + + void ForwardRenderTechnique::DrawOpaqueModels(const SceneData& sceneData) const { - NzRenderer::SetIndexBuffer(&s_quadIndexBuffer); - NzRenderer::SetVertexBuffer(&m_billboardPointBuffer); + NazaraAssert(sceneData.viewer, "Invalid viewer"); - for (auto& matIt : m_renderQueue.billboards) + const Shader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; + + for (auto& matIt : m_renderQueue.opaqueModels) { - const NzMaterial* material = matIt.first; - auto& entry = matIt.second; - auto& billboardVector = entry.billboards; + auto& matEntry = matIt.second; - unsigned int billboardCount = billboardVector.size(); - if (billboardCount > 0) + if (matEntry.enabled) { - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - const NzShader* shader = material->Apply(nzShaderFlags_Billboard | nzShaderFlags_VertexColor); + ForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; - // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas - if (shader != lastShader) + if (!meshInstances.empty()) { - // Index des uniformes dans le shader - shaderUniforms = GetShaderUniforms(shader); + const Material* material = matIt.first; - // Couleur ambiante de la scène - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position de la caméra - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + // Nous utilisons de l'instancing que lorsqu'aucune lumière (autre que directionnelle) n'est active + // Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches + // (Le deferred shading n'a pas ce problème) + bool noPointSpotLight = m_renderQueue.pointLights.empty() && m_renderQueue.spotLights.empty(); + bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || noPointSpotLight) && matEntry.instancingEnabled; - lastShader = shader; - } + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + const Shader* shader = material->Apply((instancing) ? ShaderFlags_Instancing : 0); - const NzForwardRenderQueue::BillboardData* data = &billboardVector[0]; - unsigned int maxBillboardPerDraw = std::min(s_maxQuads, m_billboardPointBuffer.GetVertexCount()/4); - - do - { - unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw); - billboardCount -= renderedBillboardCount; - - NzBufferMapper vertexMapper(m_billboardPointBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4); - BillboardPoint* vertices = reinterpret_cast(vertexMapper.GetPointer()); - - for (unsigned int i = 0; i < renderedBillboardCount; ++i) + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) { - const NzForwardRenderQueue::BillboardData& billboard = *data++; + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(0.f, 1.f); - vertices++; + // Couleur ambiante de la scène + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(1.f, 1.f); - vertices++; - - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(0.f, 0.f); - vertices++; - - vertices->color = billboard.color; - vertices->position = billboard.center; - vertices->sinCos = billboard.sinCos; - vertices->size = billboard.size; - vertices->uv.Set(1.f, 0.f); - vertices++; + lastShader = shader; } - vertexMapper.Unmap(); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, renderedBillboardCount*6); - } - while (billboardCount > 0); - - billboardVector.clear(); - } - } - } -} - -void NzForwardRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) const -{ - NazaraAssert(sceneData.viewer, "Invalid viewer"); - - const NzShader* lastShader = nullptr; - const ShaderUniforms* shaderUniforms = nullptr; - - for (auto& matIt : m_renderQueue.opaqueModels) - { - auto& matEntry = matIt.second; - - if (matEntry.enabled) - { - NzForwardRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; - - if (!meshInstances.empty()) - { - const NzMaterial* material = matIt.first; - - // Nous utilisons de l'instancing que lorsqu'aucune lumière (autre que directionnelle) n'est active - // Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches - // (Le deferred shading n'a pas ce problème) - bool noPointSpotLight = m_renderQueue.pointLights.empty() && m_renderQueue.spotLights.empty(); - bool instancing = m_instancingEnabled && (!material->IsLightingEnabled() || noPointSpotLight) && matEntry.instancingEnabled; - - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - const NzShader* shader = material->Apply((instancing) ? nzShaderFlags_Instancing : 0); - - // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas - if (shader != lastShader) - { - // Index des uniformes dans le shader - shaderUniforms = GetShaderUniforms(shader); - - // Couleur ambiante de la scène - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position de la caméra - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); - - lastShader = shader; - } - - // Meshes - for (auto& meshIt : meshInstances) - { - const NzMeshData& meshData = meshIt.first; - auto& meshEntry = meshIt.second; - - const NzSpheref& squaredBoundingSphere = meshEntry.squaredBoundingSphere; - std::vector& instances = meshEntry.instances; - - if (!instances.empty()) + // Meshes + for (auto& meshIt : meshInstances) { - const NzIndexBuffer* indexBuffer = meshData.indexBuffer; - const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer; + const MeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; - // Gestion du draw call avant la boucle de rendu - NzRenderer::DrawCall drawFunc; - NzRenderer::DrawCallInstanced instancedDrawFunc; - unsigned int indexCount; + const Spheref& squaredBoundingSphere = meshEntry.squaredBoundingSphere; + std::vector& instances = meshEntry.instances; - if (indexBuffer) + if (!instances.empty()) { - drawFunc = NzRenderer::DrawIndexedPrimitives; - instancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced; - indexCount = indexBuffer->GetIndexCount(); - } - else - { - drawFunc = NzRenderer::DrawPrimitives; - instancedDrawFunc = NzRenderer::DrawPrimitivesInstanced; - indexCount = vertexBuffer->GetVertexCount(); - } + const IndexBuffer* indexBuffer = meshData.indexBuffer; + const VertexBuffer* vertexBuffer = meshData.vertexBuffer; - NzRenderer::SetIndexBuffer(indexBuffer); - NzRenderer::SetVertexBuffer(vertexBuffer); + // Gestion du draw call avant la boucle de rendu + Renderer::DrawCall drawFunc; + Renderer::DrawCallInstanced instancedDrawFunc; + unsigned int indexCount; - if (instancing) - { - // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) - NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer(); - instanceBuffer->SetVertexDeclaration(NzVertexDeclaration::Get(nzVertexLayout_Matrix4)); - - // Avec l'instancing, impossible de sélectionner les lumières pour chaque objet - // Du coup, il n'est activé que pour les lumières directionnelles - unsigned int lightCount = m_renderQueue.directionalLights.size(); - unsigned int lightIndex = 0; - nzRendererComparison oldDepthFunc = NzRenderer::GetDepthFunc(); - - unsigned int passCount = (lightCount == 0) ? 1 : (lightCount-1)/NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1; - for (unsigned int pass = 0; pass < passCount; ++pass) + if (indexBuffer) { - if (shaderUniforms->hasLightUniforms) - { - unsigned int renderedLightCount = std::min(lightCount, NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); - lightCount -= renderedLightCount; - - if (pass == 1) - { - // Pour additionner le résultat des calculs de lumière - // Aucune chance d'interférer avec les paramètres du matériau car nous ne rendons que les objets opaques - // (Autrement dit, sans blending) - // Quant à la fonction de profondeur, elle ne doit être appliquée que la première fois - NzRenderer::Enable(nzRendererParameter_Blend, true); - NzRenderer::SetBlendFunc(nzBlendFunc_One, nzBlendFunc_One); - NzRenderer::SetDepthFunc(nzRendererComparison_Equal); - } - - // Sends the uniforms - for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, i*shaderUniforms->lightOffset); - } - - const NzMatrix4f* instanceMatrices = &instances[0]; - unsigned int instanceCount = instances.size(); - unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre maximum d'instances en une fois - - while (instanceCount > 0) - { - // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) - unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); - instanceCount -= renderedInstanceCount; - - // On remplit l'instancing buffer avec nos matrices world - instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); - instanceMatrices += renderedInstanceCount; - - // Et on affiche - instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); - } + drawFunc = Renderer::DrawIndexedPrimitives; + instancedDrawFunc = Renderer::DrawIndexedPrimitivesInstanced; + indexCount = indexBuffer->GetIndexCount(); + } + else + { + drawFunc = Renderer::DrawPrimitives; + instancedDrawFunc = Renderer::DrawPrimitivesInstanced; + indexCount = vertexBuffer->GetVertexCount(); } - // On n'oublie pas de désactiver le blending pour ne pas interférer sur le reste du rendu - NzRenderer::Enable(nzRendererParameter_Blend, false); - NzRenderer::SetDepthFunc(oldDepthFunc); - } - else - { - if (shaderUniforms->hasLightUniforms) + Renderer::SetIndexBuffer(indexBuffer); + Renderer::SetVertexBuffer(vertexBuffer); + + if (instancing) { - for (const NzMatrix4f& matrix : instances) + // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4)); + + // Avec l'instancing, impossible de sélectionner les lumières pour chaque objet + // Du coup, il n'est activé que pour les lumières directionnelles + unsigned int lightCount = m_renderQueue.directionalLights.size(); + unsigned int lightIndex = 0; + RendererComparison oldDepthFunc = Renderer::GetDepthFunc(); + + unsigned int passCount = (lightCount == 0) ? 1 : (lightCount-1)/NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1; + for (unsigned int pass = 0; pass < passCount; ++pass) { - // Choose the lights depending on an object position and apparent radius - ChooseLights(NzSpheref(matrix.GetTranslation() + squaredBoundingSphere.GetPosition(), squaredBoundingSphere.radius)); - - unsigned int lightCount = m_lights.size(); - - NzRenderer::SetMatrix(nzMatrixType_World, matrix); - unsigned int lightIndex = 0; - nzRendererComparison oldDepthFunc = NzRenderer::GetDepthFunc(); // Dans le cas où nous aurions à le changer - - unsigned int passCount = (lightCount == 0) ? 1 : (lightCount-1)/NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1; - for (unsigned int pass = 0; pass < passCount; ++pass) + if (shaderUniforms->hasLightUniforms) { - lightCount -= std::min(lightCount, NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); + unsigned int renderedLightCount = std::min(lightCount, NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); + lightCount -= renderedLightCount; if (pass == 1) { @@ -614,172 +557,232 @@ void NzForwardRenderTechnique::DrawOpaqueModels(const NzSceneData& sceneData) co // Aucune chance d'interférer avec les paramètres du matériau car nous ne rendons que les objets opaques // (Autrement dit, sans blending) // Quant à la fonction de profondeur, elle ne doit être appliquée que la première fois - NzRenderer::Enable(nzRendererParameter_Blend, true); - NzRenderer::SetBlendFunc(nzBlendFunc_One, nzBlendFunc_One); - NzRenderer::SetDepthFunc(nzRendererComparison_Equal); + Renderer::Enable(RendererParameter_Blend, true); + Renderer::SetBlendFunc(BlendFunc_One, BlendFunc_One); + Renderer::SetDepthFunc(RendererComparison_Equal); } - // Sends the light uniforms to the shader + // Sends the uniforms for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset*i); - - // Et on passe à l'affichage - drawFunc(meshData.primitiveMode, 0, indexCount); + SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, i*shaderUniforms->lightOffset); } - NzRenderer::Enable(nzRendererParameter_Blend, false); - NzRenderer::SetDepthFunc(oldDepthFunc); + const Matrix4f* instanceMatrices = &instances[0]; + unsigned int instanceCount = instances.size(); + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre maximum d'instances en une fois + + while (instanceCount > 0) + { + // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); + instanceCount -= renderedInstanceCount; + + // On remplit l'instancing buffer avec nos matrices world + instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); + instanceMatrices += renderedInstanceCount; + + // Et on affiche + instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + } } + + // On n'oublie pas de désactiver le blending pour ne pas interférer sur le reste du rendu + Renderer::Enable(RendererParameter_Blend, false); + Renderer::SetDepthFunc(oldDepthFunc); } else { - // Sans instancing, on doit effectuer un draw call pour chaque instance - // Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances - // À cause du temps de modification du buffer d'instancing - for (const NzMatrix4f& matrix : instances) + if (shaderUniforms->hasLightUniforms) { - NzRenderer::SetMatrix(nzMatrixType_World, matrix); - drawFunc(meshData.primitiveMode, 0, indexCount); + for (const Matrix4f& matrix : instances) + { + // Choose the lights depending on an object position and apparent radius + ChooseLights(Spheref(matrix.GetTranslation() + squaredBoundingSphere.GetPosition(), squaredBoundingSphere.radius)); + + unsigned int lightCount = m_lights.size(); + + Renderer::SetMatrix(MatrixType_World, matrix); + unsigned int lightIndex = 0; + RendererComparison oldDepthFunc = Renderer::GetDepthFunc(); // Dans le cas où nous aurions à le changer + + unsigned int passCount = (lightCount == 0) ? 1 : (lightCount-1)/NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS + 1; + for (unsigned int pass = 0; pass < passCount; ++pass) + { + lightCount -= std::min(lightCount, NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); + + if (pass == 1) + { + // Pour additionner le résultat des calculs de lumière + // Aucune chance d'interférer avec les paramètres du matériau car nous ne rendons que les objets opaques + // (Autrement dit, sans blending) + // Quant à la fonction de profondeur, elle ne doit être appliquée que la première fois + Renderer::Enable(RendererParameter_Blend, true); + Renderer::SetBlendFunc(BlendFunc_One, BlendFunc_One); + Renderer::SetDepthFunc(RendererComparison_Equal); + } + + // Sends the light uniforms to the shader + for (unsigned int i = 0; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) + SendLightUniforms(shader, shaderUniforms->lightUniforms, lightIndex++, shaderUniforms->lightOffset*i); + + // Et on passe à l'affichage + drawFunc(meshData.primitiveMode, 0, indexCount); + } + + Renderer::Enable(RendererParameter_Blend, false); + Renderer::SetDepthFunc(oldDepthFunc); + } + } + else + { + // Sans instancing, on doit effectuer un draw call pour chaque instance + // Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances + // À cause du temps de modification du buffer d'instancing + for (const Matrix4f& matrix : instances) + { + Renderer::SetMatrix(MatrixType_World, matrix); + drawFunc(meshData.primitiveMode, 0, indexCount); + } } } + instances.clear(); } - instances.clear(); } } - } - // Et on remet à zéro les données - matEntry.enabled = false; - matEntry.instancingEnabled = false; + // Et on remet à zéro les données + matEntry.enabled = false; + matEntry.instancingEnabled = false; + } } } -} -void NzForwardRenderTechnique::DrawTransparentModels(const NzSceneData& sceneData) const -{ - NazaraAssert(sceneData.viewer, "Invalid viewer"); - - const NzShader* lastShader = nullptr; - const ShaderUniforms* shaderUniforms = nullptr; - unsigned int lightCount = 0; - - for (unsigned int index : m_renderQueue.transparentModels) + void ForwardRenderTechnique::DrawTransparentModels(const SceneData& sceneData) const { - const NzForwardRenderQueue::TransparentModelData& modelData = m_renderQueue.transparentModelData[index]; + NazaraAssert(sceneData.viewer, "Invalid viewer"); - // Matériau - const NzMaterial* material = modelData.material; + const Shader* lastShader = nullptr; + const ShaderUniforms* shaderUniforms = nullptr; + unsigned int lightCount = 0; - // On commence par appliquer du matériau (et récupérer le shader ainsi activé) - const NzShader* shader = material->Apply(); - - // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas - if (shader != lastShader) + for (unsigned int index : m_renderQueue.transparentModels) { - // Index des uniformes dans le shader - shaderUniforms = GetShaderUniforms(shader); + const ForwardRenderQueue::TransparentModelData& modelData = m_renderQueue.transparentModelData[index]; - // Couleur ambiante de la scène - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position de la caméra - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + // Matériau + const Material* material = modelData.material; - // On envoie les lumières directionnelles s'il y a (Les mêmes pour tous) - if (shaderUniforms->hasLightUniforms) + // On commence par appliquer du matériau (et récupérer le shader ainsi activé) + const Shader* shader = material->Apply(); + + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) { - lightCount = std::min(m_renderQueue.directionalLights.size(), NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); - for (unsigned int i = 0; i < lightCount; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset * i); + // Couleur ambiante de la scène + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + + // On envoie les lumières directionnelles s'il y a (Les mêmes pour tous) + if (shaderUniforms->hasLightUniforms) + { + lightCount = std::min(m_renderQueue.directionalLights.size(), NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); + + for (unsigned int i = 0; i < lightCount; ++i) + SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset * i); + } + + lastShader = shader; } - lastShader = shader; + // Mesh + const Matrix4f& matrix = modelData.transformMatrix; + const MeshData& meshData = modelData.meshData; + + const IndexBuffer* indexBuffer = meshData.indexBuffer; + const VertexBuffer* vertexBuffer = meshData.vertexBuffer; + + // Gestion du draw call avant la boucle de rendu + Renderer::DrawCall drawFunc; + unsigned int indexCount; + + if (indexBuffer) + { + drawFunc = Renderer::DrawIndexedPrimitives; + indexCount = indexBuffer->GetIndexCount(); + } + else + { + drawFunc = Renderer::DrawPrimitives; + indexCount = vertexBuffer->GetVertexCount(); + } + + Renderer::SetIndexBuffer(indexBuffer); + Renderer::SetVertexBuffer(vertexBuffer); + + if (shaderUniforms->hasLightUniforms && lightCount < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS) + { + // Compute the closest lights + Vector3f position = matrix.GetTranslation() + modelData.squaredBoundingSphere.GetPosition(); + float radius = modelData.squaredBoundingSphere.radius; + ChooseLights(Spheref(position, radius), false); + + for (unsigned int i = lightCount; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) + SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset*i); + } + + Renderer::SetMatrix(MatrixType_World, matrix); + drawFunc(meshData.primitiveMode, 0, indexCount); } - - // Mesh - const NzMatrix4f& matrix = modelData.transformMatrix; - const NzMeshData& meshData = modelData.meshData; - - const NzIndexBuffer* indexBuffer = meshData.indexBuffer; - const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer; - - // Gestion du draw call avant la boucle de rendu - NzRenderer::DrawCall drawFunc; - unsigned int indexCount; - - if (indexBuffer) - { - drawFunc = NzRenderer::DrawIndexedPrimitives; - indexCount = indexBuffer->GetIndexCount(); - } - else - { - drawFunc = NzRenderer::DrawPrimitives; - indexCount = vertexBuffer->GetVertexCount(); - } - - NzRenderer::SetIndexBuffer(indexBuffer); - NzRenderer::SetVertexBuffer(vertexBuffer); - - if (shaderUniforms->hasLightUniforms && lightCount < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS) - { - // Compute the closest lights - NzVector3f position = matrix.GetTranslation() + modelData.squaredBoundingSphere.GetPosition(); - float radius = modelData.squaredBoundingSphere.radius; - ChooseLights(NzSpheref(position, radius), false); - - for (unsigned int i = lightCount; i < NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS; ++i) - SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset*i); - } - - NzRenderer::SetMatrix(nzMatrixType_World, matrix); - drawFunc(meshData.primitiveMode, 0, indexCount); } -} -const NzForwardRenderTechnique::ShaderUniforms* NzForwardRenderTechnique::GetShaderUniforms(const NzShader* shader) const -{ - auto it = m_shaderUniforms.find(shader); - if (it == m_shaderUniforms.end()) + const ForwardRenderTechnique::ShaderUniforms* ForwardRenderTechnique::GetShaderUniforms(const Shader* shader) const { - ShaderUniforms uniforms; - uniforms.shaderReleaseSlot.Connect(shader->OnShaderRelease, this, &NzForwardRenderTechnique::OnShaderInvalidated); - uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &NzForwardRenderTechnique::OnShaderInvalidated); - - uniforms.eyePosition = shader->GetUniformLocation("EyePosition"); - uniforms.sceneAmbient = shader->GetUniformLocation("SceneAmbient"); - uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); - - int type0Location = shader->GetUniformLocation("Lights[0].type"); - int type1Location = shader->GetUniformLocation("Lights[1].type"); - - if (type0Location > 0 && type1Location > 0) + auto it = m_shaderUniforms.find(shader); + if (it == m_shaderUniforms.end()) { - uniforms.hasLightUniforms = true; - uniforms.lightOffset = type1Location - type0Location; - uniforms.lightUniforms.ubo = false; - uniforms.lightUniforms.locations.type = type0Location; - uniforms.lightUniforms.locations.color = shader->GetUniformLocation("Lights[0].color"); - uniforms.lightUniforms.locations.factors = shader->GetUniformLocation("Lights[0].factors"); - uniforms.lightUniforms.locations.parameters1 = shader->GetUniformLocation("Lights[0].parameters1"); - uniforms.lightUniforms.locations.parameters2 = shader->GetUniformLocation("Lights[0].parameters2"); - uniforms.lightUniforms.locations.parameters3 = shader->GetUniformLocation("Lights[0].parameters3"); - } - else - uniforms.hasLightUniforms = false; + ShaderUniforms uniforms; + uniforms.shaderReleaseSlot.Connect(shader->OnShaderRelease, this, &ForwardRenderTechnique::OnShaderInvalidated); + uniforms.shaderUniformInvalidatedSlot.Connect(shader->OnShaderUniformInvalidated, this, &ForwardRenderTechnique::OnShaderInvalidated); - it = m_shaderUniforms.emplace(shader, std::move(uniforms)).first; + uniforms.eyePosition = shader->GetUniformLocation("EyePosition"); + uniforms.sceneAmbient = shader->GetUniformLocation("SceneAmbient"); + uniforms.textureOverlay = shader->GetUniformLocation("TextureOverlay"); + + int type0Location = shader->GetUniformLocation("Lights[0].type"); + int type1Location = shader->GetUniformLocation("Lights[1].type"); + + if (type0Location > 0 && type1Location > 0) + { + uniforms.hasLightUniforms = true; + uniforms.lightOffset = type1Location - type0Location; + uniforms.lightUniforms.ubo = false; + uniforms.lightUniforms.locations.type = type0Location; + uniforms.lightUniforms.locations.color = shader->GetUniformLocation("Lights[0].color"); + uniforms.lightUniforms.locations.factors = shader->GetUniformLocation("Lights[0].factors"); + uniforms.lightUniforms.locations.parameters1 = shader->GetUniformLocation("Lights[0].parameters1"); + uniforms.lightUniforms.locations.parameters2 = shader->GetUniformLocation("Lights[0].parameters2"); + uniforms.lightUniforms.locations.parameters3 = shader->GetUniformLocation("Lights[0].parameters3"); + } + else + uniforms.hasLightUniforms = false; + + it = m_shaderUniforms.emplace(shader, std::move(uniforms)).first; + } + + return &it->second; } - return &it->second; -} + void ForwardRenderTechnique::OnShaderInvalidated(const Shader* shader) const + { + m_shaderUniforms.erase(shader); + } -void NzForwardRenderTechnique::OnShaderInvalidated(const NzShader* shader) const -{ - m_shaderUniforms.erase(shader); + IndexBuffer ForwardRenderTechnique::s_quadIndexBuffer; + VertexBuffer ForwardRenderTechnique::s_quadVertexBuffer; + VertexDeclaration ForwardRenderTechnique::s_billboardInstanceDeclaration; + VertexDeclaration ForwardRenderTechnique::s_billboardVertexDeclaration; } - -NzIndexBuffer NzForwardRenderTechnique::s_quadIndexBuffer; -NzVertexBuffer NzForwardRenderTechnique::s_quadVertexBuffer; -NzVertexDeclaration NzForwardRenderTechnique::s_billboardInstanceDeclaration; -NzVertexDeclaration NzForwardRenderTechnique::s_billboardVertexDeclaration; diff --git a/src/Nazara/Graphics/Graphics.cpp b/src/Nazara/Graphics/Graphics.cpp index 935e70559..7560573ef 100644 --- a/src/Nazara/Graphics/Graphics.cpp +++ b/src/Nazara/Graphics/Graphics.cpp @@ -25,165 +25,168 @@ #include #include -bool NzGraphics::Initialize() +namespace Nz { - if (s_moduleReferenceCounter > 0) + bool Graphics::Initialize() { - s_moduleReferenceCounter++; - return true; // Déjà initialisé - } - - // Initialisation des dépendances - if (!NzRenderer::Initialize()) - { - NazaraError("Failed to initialize Renderer module"); - return false; - } - - s_moduleReferenceCounter++; - - // Initialisation du module - NzCallOnExit onExit(NzGraphics::Uninitialize); - - if (!NzMaterial::Initialize()) - { - NazaraError("Failed to initialize materials"); - return false; - } - - if (!NzParticleController::Initialize()) - { - NazaraError("Failed to initialize particle controllers"); - return false; - } - - if (!NzParticleDeclaration::Initialize()) - { - NazaraError("Failed to initialize particle declarations"); - return false; - } - - if (!NzParticleGenerator::Initialize()) - { - NazaraError("Failed to initialize particle generators"); - return false; - } - - if (!NzParticleRenderer::Initialize()) - { - NazaraError("Failed to initialize particle renderers"); - return false; - } - - if (!NzSkinningManager::Initialize()) - { - NazaraError("Failed to initialize skinning manager"); - return false; - } - - if (!NzSkyboxBackground::Initialize()) - { - NazaraError("Failed to initialize skybox backgrounds"); - return false; - } - - // Loaders - NzLoaders_OBJ_Register(); - - // Loaders génériques - NzLoaders_Mesh_Register(); - NzLoaders_Texture_Register(); - - // RenderTechniques - if (!NzForwardRenderTechnique::Initialize()) - { - NazaraError("Failed to initialize Forward Rendering"); - return false; - } - - NzRenderTechniques::Register(NzRenderTechniques::ToString(nzRenderTechniqueType_BasicForward), 0, []() -> NzAbstractRenderTechnique* { return new NzForwardRenderTechnique; }); - - if (NzDeferredRenderTechnique::IsSupported()) - { - if (NzDeferredRenderTechnique::Initialize()) - NzRenderTechniques::Register(NzRenderTechniques::ToString(nzRenderTechniqueType_DeferredShading), 20, []() -> NzAbstractRenderTechnique* { return new NzDeferredRenderTechnique; }); - else + if (s_moduleReferenceCounter > 0) { - NazaraWarning("Failed to initialize Deferred Rendering"); + s_moduleReferenceCounter++; + return true; // Déjà initialisé } - } - NzFont::SetDefaultAtlas(std::make_shared()); - - onExit.Reset(); - - NazaraNotice("Initialized: Graphics module"); - return true; -} - -bool NzGraphics::IsInitialized() -{ - return s_moduleReferenceCounter != 0; -} - -void NzGraphics::Uninitialize() -{ - if (s_moduleReferenceCounter != 1) - { - // Le module est soit encore utilisé, soit pas initialisé - if (s_moduleReferenceCounter > 1) - s_moduleReferenceCounter--; - - return; - } - - // Libération du module - s_moduleReferenceCounter = 0; - - // Libération de l'atlas s'il vient de nous - std::shared_ptr defaultAtlas = NzFont::GetDefaultAtlas(); - if (defaultAtlas && defaultAtlas->GetStorage() & nzDataStorage_Hardware) - { - NzFont::SetDefaultAtlas(nullptr); - - // La police par défaut peut faire vivre un atlas hardware après la libération du module (ce qui va être problématique) - // du coup, si la police par défaut utilise un atlas hardware, on lui enlève. - // Je n'aime pas cette solution mais je n'en ai pas de meilleure sous la main pour l'instant - if (!defaultAtlas.unique()) + // Initialisation des dépendances + if (!Renderer::Initialize()) { - // Encore au moins une police utilise l'atlas - NzFont* defaultFont = NzFont::GetDefault(); - defaultFont->SetAtlas(nullptr); + NazaraError("Failed to initialize Renderer module"); + return false; + } - if (!defaultAtlas.unique()) + s_moduleReferenceCounter++; + + // Initialisation du module + CallOnExit onExit(Graphics::Uninitialize); + + if (!Material::Initialize()) + { + NazaraError("Failed to initialize materials"); + return false; + } + + if (!ParticleController::Initialize()) + { + NazaraError("Failed to initialize particle controllers"); + return false; + } + + if (!ParticleDeclaration::Initialize()) + { + NazaraError("Failed to initialize particle declarations"); + return false; + } + + if (!ParticleGenerator::Initialize()) + { + NazaraError("Failed to initialize particle generators"); + return false; + } + + if (!ParticleRenderer::Initialize()) + { + NazaraError("Failed to initialize particle renderers"); + return false; + } + + if (!SkinningManager::Initialize()) + { + NazaraError("Failed to initialize skinning manager"); + return false; + } + + if (!SkyboxBackground::Initialize()) + { + NazaraError("Failed to initialize skybox backgrounds"); + return false; + } + + // Loaders + Loaders::RegisterOBJ(); + + // Loaders génériques + Loaders::RegisterMesh(); + Loaders::RegisterTexture(); + + // RenderTechniques + if (!ForwardRenderTechnique::Initialize()) + { + NazaraError("Failed to initialize Forward Rendering"); + return false; + } + + RenderTechniques::Register(RenderTechniques::ToString(RenderTechniqueType_BasicForward), 0, []() -> AbstractRenderTechnique* { return new ForwardRenderTechnique; }); + + if (DeferredRenderTechnique::IsSupported()) + { + if (DeferredRenderTechnique::Initialize()) + RenderTechniques::Register(RenderTechniques::ToString(RenderTechniqueType_DeferredShading), 20, []() -> AbstractRenderTechnique* { return new DeferredRenderTechnique; }); + else { - // Toujours pas seuls propriétaires ? Ah ben zut. - NazaraWarning("Default font atlas uses hardware storage and is still used"); + NazaraWarning("Failed to initialize Deferred Rendering"); } } + + Font::SetDefaultAtlas(std::make_shared()); + + onExit.Reset(); + + NazaraNotice("Initialized: Graphics module"); + return true; } - defaultAtlas.reset(); + bool Graphics::IsInitialized() + { + return s_moduleReferenceCounter != 0; + } - // Loaders - NzLoaders_Mesh_Unregister(); - NzLoaders_OBJ_Unregister(); - NzLoaders_Texture_Unregister(); + void Graphics::Uninitialize() + { + if (s_moduleReferenceCounter != 1) + { + // Le module est soit encore utilisé, soit pas initialisé + if (s_moduleReferenceCounter > 1) + s_moduleReferenceCounter--; - NzDeferredRenderTechnique::Uninitialize(); - NzForwardRenderTechnique::Uninitialize(); - NzSkinningManager::Uninitialize(); - NzParticleRenderer::Uninitialize(); - NzParticleGenerator::Uninitialize(); - NzParticleDeclaration::Uninitialize(); - NzParticleController::Uninitialize(); - NzMaterial::Uninitialize(); - NzSkyboxBackground::Uninitialize(); + return; + } - NazaraNotice("Uninitialized: Graphics module"); + // Libération du module + s_moduleReferenceCounter = 0; - // Libération des dépendances - NzRenderer::Uninitialize(); + // Libération de l'atlas s'il vient de nous + std::shared_ptr defaultAtlas = Font::GetDefaultAtlas(); + if (defaultAtlas && defaultAtlas->GetStorage() & DataStorage_Hardware) + { + Font::SetDefaultAtlas(nullptr); + + // La police par défaut peut faire vivre un atlas hardware après la libération du module (ce qui va être problématique) + // du coup, si la police par défaut utilise un atlas hardware, on lui enlève. + // Je n'aime pas cette solution mais je n'en ai pas de meilleure sous la main pour l'instant + if (!defaultAtlas.unique()) + { + // Encore au moins une police utilise l'atlas + Font* defaultFont = Font::GetDefault(); + defaultFont->SetAtlas(nullptr); + + if (!defaultAtlas.unique()) + { + // Toujours pas seuls propriétaires ? Ah ben zut. + NazaraWarning("Default font atlas uses hardware storage and is still used"); + } + } + } + + defaultAtlas.reset(); + + // Loaders + Loaders::UnregisterMesh(); + Loaders::UnregisterOBJ(); + Loaders::UnregisterTexture(); + + DeferredRenderTechnique::Uninitialize(); + ForwardRenderTechnique::Uninitialize(); + SkinningManager::Uninitialize(); + ParticleRenderer::Uninitialize(); + ParticleGenerator::Uninitialize(); + ParticleDeclaration::Uninitialize(); + ParticleController::Uninitialize(); + Material::Uninitialize(); + SkyboxBackground::Uninitialize(); + + NazaraNotice("Uninitialized: Graphics module"); + + // Libération des dépendances + Renderer::Uninitialize(); + } + + unsigned int Graphics::s_moduleReferenceCounter = 0; } - -unsigned int NzGraphics::s_moduleReferenceCounter = 0; diff --git a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp index 16cadbf5a..c8034d7b9 100644 --- a/src/Nazara/Graphics/GuillotineTextureAtlas.cpp +++ b/src/Nazara/Graphics/GuillotineTextureAtlas.cpp @@ -7,42 +7,45 @@ #include #include -nzUInt32 NzGuillotineTextureAtlas::GetStorage() const +namespace Nz { - return nzDataStorage_Hardware; -} - -NzAbstractImage* NzGuillotineTextureAtlas::ResizeImage(NzAbstractImage* oldImage, const NzVector2ui& size) const -{ - std::unique_ptr newTexture(new NzTexture); - if (newTexture->Create(nzImageType_2D, nzPixelFormat_A8, size.x, size.y, 1)) + UInt32 GuillotineTextureAtlas::GetStorage() const { - if (oldImage) + return DataStorage_Hardware; + } + + AbstractImage* GuillotineTextureAtlas::ResizeImage(AbstractImage* oldImage, const Vector2ui& size) const + { + std::unique_ptr newTexture(new Texture); + if (newTexture->Create(ImageType_2D, PixelFormatType_A8, size.x, size.y, 1)) { - NzTexture* oldTexture = static_cast(oldImage); - - // Copie des anciennes données - ///TODO: Copie de texture à texture - NzImage image; - if (!oldTexture->Download(&image)) + if (oldImage) { - NazaraError("Failed to download old texture"); - return nullptr; + Texture* oldTexture = static_cast(oldImage); + + // Copie des anciennes données + ///TODO: Copie de texture à texture + Image image; + if (!oldTexture->Download(&image)) + { + NazaraError("Failed to download old texture"); + return nullptr; + } + + if (!newTexture->Update(image, Rectui(0, 0, image.GetWidth(), image.GetHeight()))) + { + NazaraError("Failed to update texture"); + return nullptr; + } } - if (!newTexture->Update(image, NzRectui(0, 0, image.GetWidth(), image.GetHeight()))) - { - NazaraError("Failed to update texture"); - return nullptr; - } + return newTexture.release(); + } + else + { + // Si on arrive ici c'est que la taille demandée est trop grande pour la carte graphique + // ou que nous manquons de mémoire + return nullptr; } - - return newTexture.release(); - } - else - { - // Si on arrive ici c'est que la taille demandée est trop grande pour la carte graphique - // ou que nous manquons de mémoire - return nullptr; } } diff --git a/src/Nazara/Graphics/InstancedRenderable.cpp b/src/Nazara/Graphics/InstancedRenderable.cpp index e408a45f0..780f11a67 100644 --- a/src/Nazara/Graphics/InstancedRenderable.cpp +++ b/src/Nazara/Graphics/InstancedRenderable.cpp @@ -5,39 +5,42 @@ #include #include -NzInstancedRenderable::~NzInstancedRenderable() +namespace Nz { - OnInstancedRenderableRelease(this); + InstancedRenderable::~InstancedRenderable() + { + OnInstancedRenderableRelease(this); + } + + bool InstancedRenderable::Cull(const Frustumf& frustum, const InstanceData& instanceData) const + { + return frustum.Contains(instanceData.volume); + } + + const BoundingVolumef& InstancedRenderable::GetBoundingVolume() const + { + EnsureBoundingVolumeUpdated(); + + return m_boundingVolume; + } + + void InstancedRenderable::InvalidateData(InstanceData* instanceData, UInt32 flags) const + { + instanceData->flags |= flags; + } + + void InstancedRenderable::UpdateBoundingVolume(InstanceData* instanceData) const + { + NazaraAssert(instanceData, "Invalid instance data"); + NazaraUnused(instanceData); + + instanceData->volume.Update(instanceData->transformMatrix); + } + + void InstancedRenderable::UpdateData(InstanceData* instanceData) const + { + NazaraAssert(instanceData, "Invalid instance data"); + } + + InstancedRenderableLibrary::LibraryMap InstancedRenderable::s_library; } - -bool NzInstancedRenderable::Cull(const NzFrustumf& frustum, const InstanceData& instanceData) const -{ - return frustum.Contains(instanceData.volume); -} - -const NzBoundingVolumef& NzInstancedRenderable::GetBoundingVolume() const -{ - EnsureBoundingVolumeUpdated(); - - return m_boundingVolume; -} - -void NzInstancedRenderable::InvalidateData(InstanceData* instanceData, nzUInt32 flags) const -{ - instanceData->flags |= flags; -} - -void NzInstancedRenderable::UpdateBoundingVolume(InstanceData* instanceData) const -{ - NazaraAssert(instanceData, "Invalid instance data"); - NazaraUnused(instanceData); - - instanceData->volume.Update(instanceData->transformMatrix); -} - -void NzInstancedRenderable::UpdateData(InstanceData* instanceData) const -{ - NazaraAssert(instanceData, "Invalid instance data"); -} - -NzInstancedRenderableLibrary::LibraryMap NzInstancedRenderable::s_library; diff --git a/src/Nazara/Graphics/Light.cpp b/src/Nazara/Graphics/Light.cpp index d9d77809d..4e8822e02 100644 --- a/src/Nazara/Graphics/Light.cpp +++ b/src/Nazara/Graphics/Light.cpp @@ -15,164 +15,167 @@ ///TODO: Utilisation des UBOs ///TODO: Scale ? -NzLight::NzLight(nzLightType type) : -m_type(type) +namespace Nz { - SetAmbientFactor((type == nzLightType_Directional) ? 0.2f : 0.f); - SetAttenuation(0.9f); - SetColor(NzColor::White); - SetDiffuseFactor(1.f); - SetInnerAngle(15.f); - SetOuterAngle(45.f); - SetRadius(5.f); -} - -void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const -{ - switch (m_type) + Light::Light(LightType type) : + m_type(type) { - case nzLightType_Directional: - { - NzAbstractRenderQueue::DirectionalLight light; - light.ambientFactor = m_ambientFactor; - light.color = m_color; - light.diffuseFactor = m_diffuseFactor; - light.direction = transformMatrix.Transform(NzVector3f::Forward(), 0.f); - - renderQueue->AddDirectionalLight(light); - break; - } - - case nzLightType_Point: - { - NzAbstractRenderQueue::PointLight light; - light.ambientFactor = m_ambientFactor; - light.attenuation = m_attenuation; - light.color = m_color; - light.diffuseFactor = m_diffuseFactor; - light.invRadius = m_invRadius; - light.position = transformMatrix.GetTranslation(); - light.radius = m_radius; - - renderQueue->AddPointLight(light); - break; - } - - case nzLightType_Spot: - { - NzAbstractRenderQueue::SpotLight light; - light.ambientFactor = m_ambientFactor; - light.attenuation = m_attenuation; - light.color = m_color; - light.diffuseFactor = m_diffuseFactor; - light.direction = transformMatrix.Transform(NzVector3f::Forward(), 0.f); - light.innerAngleCosine = m_innerAngleCosine; - light.invRadius = m_invRadius; - light.outerAngleCosine = m_outerAngleCosine; - light.outerAngleTangent = m_outerAngleTangent; - light.position = transformMatrix.GetTranslation(); - light.radius = m_radius; - - renderQueue->AddSpotLight(light); - break; - } - - default: - NazaraError("Invalid light type (0x" + NzString::Number(m_type, 16) + ')'); - break; - } -} - -NzLight* NzLight::Clone() const -{ - return new NzLight(*this); -} - -NzLight* NzLight::Create() const -{ - return new NzLight; -} - -bool NzLight::Cull(const NzFrustumf& frustum, const NzMatrix4f& transformMatrix) const -{ - switch (m_type) - { - case nzLightType_Directional: - return true; // Always visible - - case nzLightType_Point: - return frustum.Contains(NzSpheref(transformMatrix.GetTranslation(), m_radius)); // A sphere test is much faster (and precise) - - case nzLightType_Spot: - return frustum.Contains(m_boundingVolume); + SetAmbientFactor((type == LightType_Directional) ? 0.2f : 0.f); + SetAttenuation(0.9f); + SetColor(Color::White); + SetDiffuseFactor(1.f); + SetInnerAngle(15.f); + SetOuterAngle(45.f); + SetRadius(5.f); } - NazaraError("Invalid light type (0x" + NzString::Number(m_type, 16) + ')'); - return false; -} - -void NzLight::UpdateBoundingVolume(const NzMatrix4f& transformMatrix) -{ - switch (m_type) + void Light::AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const { - case nzLightType_Directional: - break; // Nothing to do (bounding volume should be infinite) - - case nzLightType_Point: - m_boundingVolume.Update(transformMatrix.GetTranslation()); // The bounding volume only needs to be shifted - break; - - case nzLightType_Spot: - m_boundingVolume.Update(transformMatrix); - break; - - default: - NazaraError("Invalid light type (0x" + NzString::Number(m_type, 16) + ')'); - break; - } -} - -void NzLight::MakeBoundingVolume() const -{ - switch (m_type) - { - case nzLightType_Directional: - m_boundingVolume.MakeInfinite(); - break; - - case nzLightType_Point: + switch (m_type) { - NzVector3f radius(m_radius * float(M_SQRT3)); - m_boundingVolume.Set(-radius, radius); - break; + case LightType_Directional: + { + AbstractRenderQueue::DirectionalLight light; + light.ambientFactor = m_ambientFactor; + light.color = m_color; + light.diffuseFactor = m_diffuseFactor; + light.direction = transformMatrix.Transform(Vector3f::Forward(), 0.f); + + renderQueue->AddDirectionalLight(light); + break; + } + + case LightType_Point: + { + AbstractRenderQueue::PointLight light; + light.ambientFactor = m_ambientFactor; + light.attenuation = m_attenuation; + light.color = m_color; + light.diffuseFactor = m_diffuseFactor; + light.invRadius = m_invRadius; + light.position = transformMatrix.GetTranslation(); + light.radius = m_radius; + + renderQueue->AddPointLight(light); + break; + } + + case LightType_Spot: + { + AbstractRenderQueue::SpotLight light; + light.ambientFactor = m_ambientFactor; + light.attenuation = m_attenuation; + light.color = m_color; + light.diffuseFactor = m_diffuseFactor; + light.direction = transformMatrix.Transform(Vector3f::Forward(), 0.f); + light.innerAngleCosine = m_innerAngleCosine; + light.invRadius = m_invRadius; + light.outerAngleCosine = m_outerAngleCosine; + light.outerAngleTangent = m_outerAngleTangent; + light.position = transformMatrix.GetTranslation(); + light.radius = m_radius; + + renderQueue->AddSpotLight(light); + break; + } + + default: + NazaraError("Invalid light type (0x" + String::Number(m_type, 16) + ')'); + break; + } + } + + Light* Light::Clone() const + { + return new Light(*this); + } + + Light* Light::Create() const + { + return new Light; + } + + bool Light::Cull(const Frustumf& frustum, const Matrix4f& transformMatrix) const + { + switch (m_type) + { + case LightType_Directional: + return true; // Always visible + + case LightType_Point: + return frustum.Contains(Spheref(transformMatrix.GetTranslation(), m_radius)); // A sphere test is much faster (and precise) + + case LightType_Spot: + return frustum.Contains(m_boundingVolume); } - case nzLightType_Spot: + NazaraError("Invalid light type (0x" + String::Number(m_type, 16) + ')'); + return false; + } + + void Light::UpdateBoundingVolume(const Matrix4f& transformMatrix) + { + switch (m_type) { - // On forme une boite sur l'origine - NzBoxf box(NzVector3f::Zero()); + case LightType_Directional: + break; // Nothing to do (bounding volume should be infinite) - // On calcule le reste des points - NzVector3f base(NzVector3f::Forward()*m_radius); + case LightType_Point: + m_boundingVolume.Update(transformMatrix.GetTranslation()); // The bounding volume only needs to be shifted + break; - // Il nous faut maintenant le rayon du cercle projeté à cette distance - // Tangente = Opposé/Adjaçent <=> Opposé = Adjaçent*Tangente - float radius = m_radius * m_outerAngleTangent; - NzVector3f lExtend = NzVector3f::Left()*radius; - NzVector3f uExtend = NzVector3f::Up()*radius; + case LightType_Spot: + m_boundingVolume.Update(transformMatrix); + break; - // Et on ajoute ensuite les quatres extrémités de la pyramide - box.ExtendTo(base + lExtend + uExtend); - box.ExtendTo(base + lExtend - uExtend); - box.ExtendTo(base - lExtend + uExtend); - box.ExtendTo(base - lExtend - uExtend); - - m_boundingVolume.Set(box); - break; + default: + NazaraError("Invalid light type (0x" + String::Number(m_type, 16) + ')'); + break; } + } - default: - NazaraError("Invalid light type (0x" + NzString::Number(m_type, 16) + ')'); - break; + void Light::MakeBoundingVolume() const + { + switch (m_type) + { + case LightType_Directional: + m_boundingVolume.MakeInfinite(); + break; + + case LightType_Point: + { + Vector3f radius(m_radius * float(M_SQRT3)); + m_boundingVolume.Set(-radius, radius); + break; + } + + case LightType_Spot: + { + // On forme une boite sur l'origine + Boxf box(Vector3f::Zero()); + + // On calcule le reste des points + Vector3f base(Vector3f::Forward()*m_radius); + + // Il nous faut maintenant le rayon du cercle projeté à cette distance + // Tangente = Opposé/Adjaçent <=> Opposé = Adjaçent*Tangente + float radius = m_radius * m_outerAngleTangent; + Vector3f lExtend = Vector3f::Left()*radius; + Vector3f uExtend = Vector3f::Up()*radius; + + // Et on ajoute ensuite les quatres extrémités de la pyramide + box.ExtendTo(base + lExtend + uExtend); + box.ExtendTo(base + lExtend - uExtend); + box.ExtendTo(base - lExtend + uExtend); + box.ExtendTo(base - lExtend - uExtend); + + m_boundingVolume.Set(box); + break; + } + + default: + NazaraError("Invalid light type (0x" + String::Number(m_type, 16) + ')'); + break; + } } } diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index ce569a127..daa6710b4 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -14,798 +14,801 @@ #include #include -namespace +namespace Nz { - const nzUInt8 r_coreFragmentShader[] = { - #include - }; - - const nzUInt8 r_coreVertexShader[] = { - #include - }; - - const nzUInt8 r_compatibilityFragmentShader[] = { - #include - }; - - const nzUInt8 r_compatibilityVertexShader[] = { - #include - }; -} - -bool NzMaterialParams::IsValid() const -{ - if (!NzUberShaderLibrary::Has(shaderName)) - return false; - - return true; -} - -NzMaterial::NzMaterial() -{ - Reset(); -} - -NzMaterial::NzMaterial(const NzMaterial& material) : -NzRefCounted(), -NzResource(material) -{ - Copy(material); -} - -NzMaterial::~NzMaterial() -{ - OnMaterialRelease(this); -} - -const NzShader* NzMaterial::Apply(nzUInt32 shaderFlags, nzUInt8 textureUnit, nzUInt8* lastUsedUnit) const -{ - const ShaderInstance& instance = m_shaders[shaderFlags]; - if (!instance.uberInstance) - GenerateShader(shaderFlags); - - instance.uberInstance->Activate(); - - if (instance.uniforms[nzMaterialUniform_AlphaThreshold] != -1) - instance.shader->SendFloat(instance.uniforms[nzMaterialUniform_AlphaThreshold], m_alphaThreshold); - - if (instance.uniforms[nzMaterialUniform_Ambient] != -1) - instance.shader->SendColor(instance.uniforms[nzMaterialUniform_Ambient], m_ambientColor); - - if (instance.uniforms[nzMaterialUniform_Diffuse] != -1) - instance.shader->SendColor(instance.uniforms[nzMaterialUniform_Diffuse], m_diffuseColor); - - if (instance.uniforms[nzMaterialUniform_Shininess] != -1) - instance.shader->SendFloat(instance.uniforms[nzMaterialUniform_Shininess], m_shininess); - - if (instance.uniforms[nzMaterialUniform_Specular] != -1) - instance.shader->SendColor(instance.uniforms[nzMaterialUniform_Specular], m_specularColor); - - if (m_alphaMap && instance.uniforms[nzMaterialUniform_AlphaMap] != -1) + namespace { - NzRenderer::SetTexture(textureUnit, m_alphaMap); - NzRenderer::SetTextureSampler(textureUnit, m_diffuseSampler); - instance.shader->SendInteger(instance.uniforms[nzMaterialUniform_AlphaMap], textureUnit); - textureUnit++; + const UInt8 r_coreFragmentShader[] = { + #include + }; + + const UInt8 r_coreVertexShader[] = { + #include + }; + + const UInt8 r_compatibilityFragmentShader[] = { + #include + }; + + const UInt8 r_compatibilityVertexShader[] = { + #include + }; } - if (m_diffuseMap && instance.uniforms[nzMaterialUniform_DiffuseMap] != -1) + bool MaterialParams::IsValid() const { - NzRenderer::SetTexture(textureUnit, m_diffuseMap); - NzRenderer::SetTextureSampler(textureUnit, m_diffuseSampler); - instance.shader->SendInteger(instance.uniforms[nzMaterialUniform_DiffuseMap], textureUnit); - textureUnit++; - } - - if (m_emissiveMap && instance.uniforms[nzMaterialUniform_EmissiveMap] != -1) - { - NzRenderer::SetTexture(textureUnit, m_emissiveMap); - NzRenderer::SetTextureSampler(textureUnit, m_diffuseSampler); - instance.shader->SendInteger(instance.uniforms[nzMaterialUniform_EmissiveMap], textureUnit); - textureUnit++; - } - - if (m_heightMap && instance.uniforms[nzMaterialUniform_HeightMap] != -1) - { - NzRenderer::SetTexture(textureUnit, m_heightMap); - NzRenderer::SetTextureSampler(textureUnit, m_diffuseSampler); - instance.shader->SendInteger(instance.uniforms[nzMaterialUniform_HeightMap], textureUnit); - textureUnit++; - } - - if (m_normalMap && instance.uniforms[nzMaterialUniform_NormalMap] != -1) - { - NzRenderer::SetTexture(textureUnit, m_normalMap); - NzRenderer::SetTextureSampler(textureUnit, m_diffuseSampler); - instance.shader->SendInteger(instance.uniforms[nzMaterialUniform_NormalMap], textureUnit); - textureUnit++; - } - - if (m_specularMap && instance.uniforms[nzMaterialUniform_SpecularMap] != -1) - { - NzRenderer::SetTexture(textureUnit, m_specularMap); - NzRenderer::SetTextureSampler(textureUnit, m_specularSampler); - instance.shader->SendInteger(instance.uniforms[nzMaterialUniform_SpecularMap], textureUnit); - textureUnit++; - } - - NzRenderer::SetRenderStates(m_states); - - if (lastUsedUnit) - *lastUsedUnit = textureUnit; - - return instance.shader; -} - -void NzMaterial::Enable(nzRendererParameter renderParameter, bool enable) -{ - #ifdef NAZARA_DEBUG - if (renderParameter > nzRendererParameter_Max) - { - NazaraError("Renderer parameter out of enum"); - return; - } - #endif - - m_states.parameters[renderParameter] = enable; -} - -void NzMaterial::EnableAlphaTest(bool alphaTest) -{ - m_alphaTestEnabled = alphaTest; - - InvalidateShaders(); -} - -void NzMaterial::EnableDepthSorting(bool depthSorting) -{ - m_depthSortingEnabled = depthSorting; -} - -void NzMaterial::EnableLighting(bool lighting) -{ - m_lightingEnabled = lighting; - - InvalidateShaders(); -} - -void NzMaterial::EnableTransform(bool transform) -{ - m_transformEnabled = transform; - - InvalidateShaders(); -} - -NzTexture* NzMaterial::GetAlphaMap() const -{ - return m_alphaMap; -} - -float NzMaterial::GetAlphaThreshold() const -{ - return m_alphaThreshold; -} - -NzColor NzMaterial::GetAmbientColor() const -{ - return m_ambientColor; -} - -nzRendererComparison NzMaterial::GetDepthFunc() const -{ - return m_states.depthFunc; -} - -NzColor NzMaterial::GetDiffuseColor() const -{ - return m_diffuseColor; -} - -NzTextureSampler& NzMaterial::GetDiffuseSampler() -{ - return m_diffuseSampler; -} - -const NzTextureSampler& NzMaterial::GetDiffuseSampler() const -{ - return m_diffuseSampler; -} - -NzTexture* NzMaterial::GetDiffuseMap() const -{ - return m_diffuseMap; -} - -nzBlendFunc NzMaterial::GetDstBlend() const -{ - return m_states.dstBlend; -} - -NzTexture* NzMaterial::GetEmissiveMap() const -{ - return m_emissiveMap; -} - -nzFaceSide NzMaterial::GetFaceCulling() const -{ - return m_states.faceCulling; -} - -nzFaceFilling NzMaterial::GetFaceFilling() const -{ - return m_states.faceFilling; -} - -NzTexture* NzMaterial::GetHeightMap() const -{ - return m_heightMap; -} - -NzTexture* NzMaterial::GetNormalMap() const -{ - return m_normalMap; -} - -const NzRenderStates& NzMaterial::GetRenderStates() const -{ - return m_states; -} - -const NzUberShader* NzMaterial::GetShader() const -{ - return m_uberShader; -} - -const NzUberShaderInstance* NzMaterial::GetShaderInstance(nzUInt32 flags) const -{ - const ShaderInstance& instance = m_shaders[flags]; - if (!instance.uberInstance) - GenerateShader(flags); - - return instance.uberInstance; -} - -float NzMaterial::GetShininess() const -{ - return m_shininess; -} - -NzColor NzMaterial::GetSpecularColor() const -{ - return m_specularColor; -} - -NzTexture* NzMaterial::GetSpecularMap() const -{ - return m_specularMap; -} - -NzTextureSampler& NzMaterial::GetSpecularSampler() -{ - return m_specularSampler; -} - -const NzTextureSampler& NzMaterial::GetSpecularSampler() const -{ - return m_specularSampler; -} - -nzBlendFunc NzMaterial::GetSrcBlend() const -{ - return m_states.srcBlend; -} - -bool NzMaterial::HasAlphaMap() const -{ - return m_alphaMap.IsValid(); -} - -bool NzMaterial::HasDiffuseMap() const -{ - return m_diffuseMap.IsValid(); -} - -bool NzMaterial::HasEmissiveMap() const -{ - return m_emissiveMap.IsValid(); -} - -bool NzMaterial::HasHeightMap() const -{ - return m_heightMap.IsValid(); -} - -bool NzMaterial::HasNormalMap() const -{ - return m_normalMap.IsValid(); -} - -bool NzMaterial::HasSpecularMap() const -{ - return m_specularMap.IsValid(); -} - -bool NzMaterial::IsAlphaTestEnabled() const -{ - return m_alphaTestEnabled; -} - -bool NzMaterial::IsDepthSortingEnabled() const -{ - return m_depthSortingEnabled; -} - -bool NzMaterial::IsEnabled(nzRendererParameter parameter) const -{ - #ifdef NAZARA_DEBUG - if (parameter > nzRendererParameter_Max) - { - NazaraError("Renderer parameter out of enum"); - return false; - } - #endif - - return m_states.parameters[parameter]; -} - -bool NzMaterial::IsLightingEnabled() const -{ - return m_lightingEnabled; -} - -bool NzMaterial::IsTransformEnabled() const -{ - return m_transformEnabled; -} - -bool NzMaterial::LoadFromFile(const NzString& filePath, const NzMaterialParams& params) -{ - return NzMaterialLoader::LoadFromFile(this, filePath, params); -} - -bool NzMaterial::LoadFromMemory(const void* data, std::size_t size, const NzMaterialParams& params) -{ - return NzMaterialLoader::LoadFromMemory(this, data, size, params); -} - -bool NzMaterial::LoadFromStream(NzInputStream& stream, const NzMaterialParams& params) -{ - return NzMaterialLoader::LoadFromStream(this, stream, params); -} - -void NzMaterial::Reset() -{ - OnMaterialReset(this); - - m_alphaMap.Reset(); - m_diffuseMap.Reset(); - m_emissiveMap.Reset(); - m_heightMap.Reset(); - m_normalMap.Reset(); - m_specularMap.Reset(); - m_uberShader.Reset(); - - for (ShaderInstance& instance : m_shaders) - instance.uberInstance = nullptr; - - 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; - m_shininess = 50.f; - m_specularColor = NzColor::White; - m_specularSampler = NzTextureSampler(); - m_states = NzRenderStates(); - m_states.parameters[nzRendererParameter_DepthBuffer] = true; - m_states.parameters[nzRendererParameter_FaceCulling] = true; - m_transformEnabled = true; - - SetShader("Basic"); -} - -bool NzMaterial::SetAlphaMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) - { - texture = NzTextureManager::Get(textureName); - if (!texture) + if (!UberShaderLibrary::Has(shaderName)) return false; + + return true; } - SetAlphaMap(std::move(texture)); - return true; -} - -void NzMaterial::SetAlphaMap(NzTextureRef alphaMap) -{ - m_alphaMap = std::move(alphaMap); - - InvalidateShaders(); -} - -void NzMaterial::SetAlphaThreshold(float alphaThreshold) -{ - m_alphaThreshold = alphaThreshold; -} - -void NzMaterial::SetAmbientColor(const NzColor& ambient) -{ - m_ambientColor = ambient; -} - -void NzMaterial::SetDepthFunc(nzRendererComparison depthFunc) -{ - m_states.depthFunc = depthFunc; -} - -void NzMaterial::SetDiffuseColor(const NzColor& diffuse) -{ - m_diffuseColor = diffuse; -} - -bool NzMaterial::SetDiffuseMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) + Material::Material() { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; + Reset(); } - SetDiffuseMap(std::move(texture)); - return true; -} - -void NzMaterial::SetDiffuseMap(NzTextureRef diffuseMap) -{ - m_diffuseMap = std::move(diffuseMap); - - InvalidateShaders(); -} - -void NzMaterial::SetDiffuseSampler(const NzTextureSampler& sampler) -{ - m_diffuseSampler = sampler; -} - -void NzMaterial::SetDstBlend(nzBlendFunc func) -{ - m_states.dstBlend = func; -} - -bool NzMaterial::SetEmissiveMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) + Material::Material(const Material& material) : + RefCounted(), + Resource(material) { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; + Copy(material); } - SetEmissiveMap(std::move(texture)); - return true; -} - -void NzMaterial::SetEmissiveMap(NzTextureRef emissiveMap) -{ - m_emissiveMap = std::move(emissiveMap); - - InvalidateShaders(); -} - -void NzMaterial::SetFaceCulling(nzFaceSide faceSide) -{ - m_states.faceCulling = faceSide; -} - -void NzMaterial::SetFaceFilling(nzFaceFilling filling) -{ - m_states.faceFilling = filling; -} - -bool NzMaterial::SetHeightMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) + Material::~Material() { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; + OnMaterialRelease(this); } - SetHeightMap(std::move(texture)); - return true; -} - -void NzMaterial::SetHeightMap(NzTextureRef heightMap) -{ - m_heightMap = std::move(heightMap); - - InvalidateShaders(); -} - -bool NzMaterial::SetNormalMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) + const Shader* Material::Apply(UInt32 shaderFlags, UInt8 textureUnit, UInt8* lastUsedUnit) const { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; - } + const ShaderInstance& instance = m_shaders[shaderFlags]; + if (!instance.uberInstance) + GenerateShader(shaderFlags); - SetNormalMap(std::move(texture)); - return true; -} + instance.uberInstance->Activate(); -void NzMaterial::SetNormalMap(NzTextureRef normalMap) -{ - m_normalMap = std::move(normalMap); + if (instance.uniforms[MaterialUniform_AlphaThreshold] != -1) + instance.shader->SendFloat(instance.uniforms[MaterialUniform_AlphaThreshold], m_alphaThreshold); - InvalidateShaders(); -} + if (instance.uniforms[MaterialUniform_Ambient] != -1) + instance.shader->SendColor(instance.uniforms[MaterialUniform_Ambient], m_ambientColor); -void NzMaterial::SetRenderStates(const NzRenderStates& states) -{ - m_states = states; -} + if (instance.uniforms[MaterialUniform_Diffuse] != -1) + instance.shader->SendColor(instance.uniforms[MaterialUniform_Diffuse], m_diffuseColor); -void NzMaterial::SetShader(NzUberShaderConstRef uberShader) -{ - m_uberShader = std::move(uberShader); + if (instance.uniforms[MaterialUniform_Shininess] != -1) + instance.shader->SendFloat(instance.uniforms[MaterialUniform_Shininess], m_shininess); - InvalidateShaders(); -} + if (instance.uniforms[MaterialUniform_Specular] != -1) + instance.shader->SendColor(instance.uniforms[MaterialUniform_Specular], m_specularColor); -bool NzMaterial::SetShader(const NzString& uberShaderName) -{ - NzUberShaderConstRef uberShader = NzUberShaderLibrary::Get(uberShaderName); - if (!uberShader) - return false; - - SetShader(std::move(uberShader)); - return true; -} - -void NzMaterial::SetShininess(float shininess) -{ - m_shininess = shininess; -} - -void NzMaterial::SetSpecularColor(const NzColor& specular) -{ - m_specularColor = specular; -} - -bool NzMaterial::SetSpecularMap(const NzString& textureName) -{ - NzTextureRef texture = NzTextureLibrary::Query(textureName); - if (!texture) - { - texture = NzTextureManager::Get(textureName); - if (!texture) - return false; - } - - SetSpecularMap(std::move(texture)); - return true; -} - -void NzMaterial::SetSpecularMap(NzTextureRef specularMap) -{ - m_specularMap = std::move(specularMap); - - InvalidateShaders(); -} - -void NzMaterial::SetSpecularSampler(const NzTextureSampler& sampler) -{ - m_specularSampler = sampler; -} - -void NzMaterial::SetSrcBlend(nzBlendFunc func) -{ - m_states.srcBlend = func; -} - -NzMaterial& NzMaterial::operator=(const NzMaterial& material) -{ - NzResource::operator=(material); - - Copy(material); - return *this; -} - -NzMaterialRef NzMaterial::GetDefault() -{ - return s_defaultMaterial; -} - -void NzMaterial::Copy(const NzMaterial& material) -{ - // Copie des états de base - m_alphaTestEnabled = material.m_alphaTestEnabled; - m_alphaThreshold = material.m_alphaThreshold; - m_ambientColor = material.m_ambientColor; - m_depthSortingEnabled = material.m_depthSortingEnabled; - m_diffuseColor = material.m_diffuseColor; - m_diffuseSampler = material.m_diffuseSampler; - m_lightingEnabled = material.m_lightingEnabled; - m_shininess = material.m_shininess; - m_specularColor = material.m_specularColor; - m_specularSampler = material.m_specularSampler; - m_states = material.m_states; - m_transformEnabled = material.m_transformEnabled; - - // Copie des références de texture - m_alphaMap = material.m_alphaMap; - m_diffuseMap = material.m_diffuseMap; - m_emissiveMap = material.m_emissiveMap; - m_heightMap = material.m_heightMap; - m_normalMap = material.m_normalMap; - m_specularMap = material.m_specularMap; - - // Copie de la référence vers l'Über-Shader - m_uberShader = material.m_uberShader; - - // On copie les instances de shader par la même occasion - std::memcpy(&m_shaders[0], &material.m_shaders[0], (nzShaderFlags_Max+1)*sizeof(ShaderInstance)); -} - -void NzMaterial::GenerateShader(nzUInt32 flags) const -{ - NzParameterList list; - list.SetParameter("ALPHA_MAPPING", m_alphaMap.IsValid()); - list.SetParameter("ALPHA_TEST", m_alphaTestEnabled); - list.SetParameter("COMPUTE_TBNMATRIX", m_normalMap.IsValid() || m_heightMap.IsValid()); - list.SetParameter("DIFFUSE_MAPPING", m_diffuseMap.IsValid()); - list.SetParameter("EMISSIVE_MAPPING", m_emissiveMap.IsValid()); - list.SetParameter("LIGHTING", m_lightingEnabled); - list.SetParameter("NORMAL_MAPPING", m_normalMap.IsValid()); - list.SetParameter("PARALLAX_MAPPING", m_heightMap.IsValid()); - list.SetParameter("SPECULAR_MAPPING", m_specularMap.IsValid()); - list.SetParameter("TEXTURE_MAPPING", m_alphaMap.IsValid() || m_diffuseMap.IsValid() || m_emissiveMap.IsValid() || - m_normalMap.IsValid() || m_heightMap.IsValid() || m_specularMap.IsValid() || - flags & nzShaderFlags_TextureOverlay); - list.SetParameter("TRANSFORM", m_transformEnabled); - - list.SetParameter("FLAG_BILLBOARD", static_cast(flags & nzShaderFlags_Billboard)); - list.SetParameter("FLAG_DEFERRED", static_cast((flags & nzShaderFlags_Deferred) != 0)); - list.SetParameter("FLAG_INSTANCING", static_cast((flags & nzShaderFlags_Instancing) != 0)); - list.SetParameter("FLAG_TEXTUREOVERLAY", static_cast((flags & nzShaderFlags_TextureOverlay) != 0)); - list.SetParameter("FLAG_VERTEXCOLOR", static_cast((flags & nzShaderFlags_VertexColor) != 0)); - - ShaderInstance& instance = m_shaders[flags]; - instance.uberInstance = m_uberShader->Get(list); - instance.shader = instance.uberInstance->GetShader(); - - #define CacheUniform(name) instance.uniforms[nzMaterialUniform_##name] = instance.shader->GetUniformLocation("Material" #name) - - CacheUniform(AlphaMap); - CacheUniform(AlphaThreshold); - CacheUniform(Ambient); - CacheUniform(Diffuse); - CacheUniform(DiffuseMap); - CacheUniform(EmissiveMap); - CacheUniform(HeightMap); - CacheUniform(NormalMap); - CacheUniform(Shininess); - CacheUniform(Specular); - CacheUniform(SpecularMap); - - #undef CacheUniform -} - -void NzMaterial::InvalidateShaders() -{ - for (ShaderInstance& instance : m_shaders) - instance.uberInstance = nullptr; -} - -bool NzMaterial::Initialize() -{ - if (!NzMaterialLibrary::Initialize()) - { - NazaraError("Failed to initialise library"); - return false; - } - - if (!NzMaterialManager::Initialize()) - { - NazaraError("Failed to initialise manager"); - return false; - } - - bool glsl140 = (NzOpenGL::GetGLSLVersion() >= 140); - - // Basic shader - { - NzUberShaderPreprocessorRef uberShader = NzUberShaderPreprocessor::New(); - - NzString fragmentShader; - NzString vertexShader; - if (glsl140) + if (m_alphaMap && instance.uniforms[MaterialUniform_AlphaMap] != -1) { - fragmentShader.Set(reinterpret_cast(r_coreFragmentShader), sizeof(r_coreFragmentShader)); - vertexShader.Set(reinterpret_cast(r_coreVertexShader), sizeof(r_coreVertexShader)); - } - else - { - fragmentShader.Set(reinterpret_cast(r_compatibilityFragmentShader), sizeof(r_compatibilityFragmentShader)); - vertexShader.Set(reinterpret_cast(r_compatibilityVertexShader), sizeof(r_compatibilityVertexShader)); + Renderer::SetTexture(textureUnit, m_alphaMap); + Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); + instance.shader->SendInteger(instance.uniforms[MaterialUniform_AlphaMap], textureUnit); + textureUnit++; } - uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING"); - uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_INSTANCING FLAG_VERTEXCOLOR TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); + if (m_diffuseMap && instance.uniforms[MaterialUniform_DiffuseMap] != -1) + { + Renderer::SetTexture(textureUnit, m_diffuseMap); + Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); + instance.shader->SendInteger(instance.uniforms[MaterialUniform_DiffuseMap], textureUnit); + textureUnit++; + } - NzUberShaderLibrary::Register("Basic", uberShader); + if (m_emissiveMap && instance.uniforms[MaterialUniform_EmissiveMap] != -1) + { + Renderer::SetTexture(textureUnit, m_emissiveMap); + Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); + instance.shader->SendInteger(instance.uniforms[MaterialUniform_EmissiveMap], textureUnit); + textureUnit++; + } + + if (m_heightMap && instance.uniforms[MaterialUniform_HeightMap] != -1) + { + Renderer::SetTexture(textureUnit, m_heightMap); + Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); + instance.shader->SendInteger(instance.uniforms[MaterialUniform_HeightMap], textureUnit); + textureUnit++; + } + + if (m_normalMap && instance.uniforms[MaterialUniform_NormalMap] != -1) + { + Renderer::SetTexture(textureUnit, m_normalMap); + Renderer::SetTextureSampler(textureUnit, m_diffuseSampler); + instance.shader->SendInteger(instance.uniforms[MaterialUniform_NormalMap], textureUnit); + textureUnit++; + } + + if (m_specularMap && instance.uniforms[MaterialUniform_SpecularMap] != -1) + { + Renderer::SetTexture(textureUnit, m_specularMap); + Renderer::SetTextureSampler(textureUnit, m_specularSampler); + instance.shader->SendInteger(instance.uniforms[MaterialUniform_SpecularMap], textureUnit); + textureUnit++; + } + + Renderer::SetRenderStates(m_states); + + if (lastUsedUnit) + *lastUsedUnit = textureUnit; + + return instance.shader; } - // PhongLighting shader + void Material::Enable(RendererParameter renderParameter, bool enable) { - NzUberShaderPreprocessorRef uberShader = NzUberShaderPreprocessor::New(); - - NzString fragmentShader; - NzString vertexShader; - if (glsl140) + #ifdef NAZARA_DEBUG + if (renderParameter > RendererParameter_Max) { - const nzUInt8 coreFragmentShader[] = { - #include - }; - - const nzUInt8 coreVertexShader[] = { - #include - }; - - fragmentShader.Set(reinterpret_cast(coreFragmentShader), sizeof(coreFragmentShader)); - vertexShader.Set(reinterpret_cast(coreVertexShader), sizeof(coreVertexShader)); + NazaraError("Renderer parameter out of enum"); + return; } - else - { - const nzUInt8 compatibilityFragmentShader[] = { - #include - }; + #endif - const nzUInt8 compatibilityVertexShader[] = { - #include - }; - - fragmentShader.Set(reinterpret_cast(compatibilityFragmentShader), sizeof(compatibilityFragmentShader)); - vertexShader.Set(reinterpret_cast(compatibilityVertexShader), sizeof(compatibilityVertexShader)); - } - - uberShader->SetShader(nzShaderStage_Fragment, fragmentShader, "FLAG_DEFERRED FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING EMISSIVE_MAPPING LIGHTING NORMAL_MAPPING PARALLAX_MAPPING SPECULAR_MAPPING"); - uberShader->SetShader(nzShaderStage_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX LIGHTING PARALLAX_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); - - NzUberShaderLibrary::Register("PhongLighting", uberShader); + m_states.parameters[renderParameter] = enable; } - // Une fois les shaders de base enregistrés, on peut créer le matériau par défaut - s_defaultMaterial = NzMaterial::New(); - s_defaultMaterial->Enable(nzRendererParameter_FaceCulling, false); - s_defaultMaterial->SetFaceFilling(nzFaceFilling_Line); - NzMaterialLibrary::Register("Default", s_defaultMaterial); + void Material::EnableAlphaTest(bool alphaTest) + { + m_alphaTestEnabled = alphaTest; - return true; + InvalidateShaders(); + } + + void Material::EnableDepthSorting(bool depthSorting) + { + m_depthSortingEnabled = depthSorting; + } + + void Material::EnableLighting(bool lighting) + { + m_lightingEnabled = lighting; + + InvalidateShaders(); + } + + void Material::EnableTransform(bool transform) + { + m_transformEnabled = transform; + + InvalidateShaders(); + } + + Texture* Material::GetAlphaMap() const + { + return m_alphaMap; + } + + float Material::GetAlphaThreshold() const + { + return m_alphaThreshold; + } + + Color Material::GetAmbientColor() const + { + return m_ambientColor; + } + + RendererComparison Material::GetDepthFunc() const + { + return m_states.depthFunc; + } + + Color Material::GetDiffuseColor() const + { + return m_diffuseColor; + } + + TextureSampler& Material::GetDiffuseSampler() + { + return m_diffuseSampler; + } + + const TextureSampler& Material::GetDiffuseSampler() const + { + return m_diffuseSampler; + } + + Texture* Material::GetDiffuseMap() const + { + return m_diffuseMap; + } + + BlendFunc Material::GetDstBlend() const + { + return m_states.dstBlend; + } + + Texture* Material::GetEmissiveMap() const + { + return m_emissiveMap; + } + + FaceSide Material::GetFaceCulling() const + { + return m_states.faceCulling; + } + + FaceFilling Material::GetFaceFilling() const + { + return m_states.faceFilling; + } + + Texture* Material::GetHeightMap() const + { + return m_heightMap; + } + + Texture* Material::GetNormalMap() const + { + return m_normalMap; + } + + const RenderStates& Material::GetRenderStates() const + { + return m_states; + } + + const UberShader* Material::GetShader() const + { + return m_uberShader; + } + + const UberShaderInstance* Material::GetShaderInstance(UInt32 flags) const + { + const ShaderInstance& instance = m_shaders[flags]; + if (!instance.uberInstance) + GenerateShader(flags); + + return instance.uberInstance; + } + + float Material::GetShininess() const + { + return m_shininess; + } + + Color Material::GetSpecularColor() const + { + return m_specularColor; + } + + Texture* Material::GetSpecularMap() const + { + return m_specularMap; + } + + TextureSampler& Material::GetSpecularSampler() + { + return m_specularSampler; + } + + const TextureSampler& Material::GetSpecularSampler() const + { + return m_specularSampler; + } + + BlendFunc Material::GetSrcBlend() const + { + return m_states.srcBlend; + } + + bool Material::HasAlphaMap() const + { + return m_alphaMap.IsValid(); + } + + bool Material::HasDiffuseMap() const + { + return m_diffuseMap.IsValid(); + } + + bool Material::HasEmissiveMap() const + { + return m_emissiveMap.IsValid(); + } + + bool Material::HasHeightMap() const + { + return m_heightMap.IsValid(); + } + + bool Material::HasNormalMap() const + { + return m_normalMap.IsValid(); + } + + bool Material::HasSpecularMap() const + { + return m_specularMap.IsValid(); + } + + bool Material::IsAlphaTestEnabled() const + { + return m_alphaTestEnabled; + } + + bool Material::IsDepthSortingEnabled() const + { + return m_depthSortingEnabled; + } + + bool Material::IsEnabled(RendererParameter parameter) const + { + #ifdef NAZARA_DEBUG + if (parameter > RendererParameter_Max) + { + NazaraError("Renderer parameter out of enum"); + return false; + } + #endif + + return m_states.parameters[parameter]; + } + + bool Material::IsLightingEnabled() const + { + return m_lightingEnabled; + } + + bool Material::IsTransformEnabled() const + { + return m_transformEnabled; + } + + bool Material::LoadFromFile(const String& filePath, const MaterialParams& params) + { + return MaterialLoader::LoadFromFile(this, filePath, params); + } + + bool Material::LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params) + { + return MaterialLoader::LoadFromMemory(this, data, size, params); + } + + bool Material::LoadFromStream(InputStream& stream, const MaterialParams& params) + { + return MaterialLoader::LoadFromStream(this, stream, params); + } + + void Material::Reset() + { + OnMaterialReset(this); + + m_alphaMap.Reset(); + m_diffuseMap.Reset(); + m_emissiveMap.Reset(); + m_heightMap.Reset(); + m_normalMap.Reset(); + m_specularMap.Reset(); + m_uberShader.Reset(); + + for (ShaderInstance& instance : m_shaders) + instance.uberInstance = nullptr; + + m_alphaThreshold = 0.2f; + m_alphaTestEnabled = false; + m_ambientColor = Color(128, 128, 128); + m_depthSortingEnabled = false; + m_diffuseColor = Color::White; + m_diffuseSampler = TextureSampler(); + m_lightingEnabled = true; + m_shininess = 50.f; + m_specularColor = Color::White; + m_specularSampler = TextureSampler(); + m_states = RenderStates(); + m_states.parameters[RendererParameter_DepthBuffer] = true; + m_states.parameters[RendererParameter_FaceCulling] = true; + m_transformEnabled = true; + + SetShader("Basic"); + } + + bool Material::SetAlphaMap(const String& textureName) + { + TextureRef texture = TextureLibrary::Query(textureName); + if (!texture) + { + texture = TextureManager::Get(textureName); + if (!texture) + return false; + } + + SetAlphaMap(std::move(texture)); + return true; + } + + void Material::SetAlphaMap(TextureRef alphaMap) + { + m_alphaMap = std::move(alphaMap); + + InvalidateShaders(); + } + + void Material::SetAlphaThreshold(float alphaThreshold) + { + m_alphaThreshold = alphaThreshold; + } + + void Material::SetAmbientColor(const Color& ambient) + { + m_ambientColor = ambient; + } + + void Material::SetDepthFunc(RendererComparison depthFunc) + { + m_states.depthFunc = depthFunc; + } + + void Material::SetDiffuseColor(const Color& diffuse) + { + m_diffuseColor = diffuse; + } + + bool Material::SetDiffuseMap(const String& textureName) + { + TextureRef texture = TextureLibrary::Query(textureName); + if (!texture) + { + texture = TextureManager::Get(textureName); + if (!texture) + return false; + } + + SetDiffuseMap(std::move(texture)); + return true; + } + + void Material::SetDiffuseMap(TextureRef diffuseMap) + { + m_diffuseMap = std::move(diffuseMap); + + InvalidateShaders(); + } + + void Material::SetDiffuseSampler(const TextureSampler& sampler) + { + m_diffuseSampler = sampler; + } + + void Material::SetDstBlend(BlendFunc func) + { + m_states.dstBlend = func; + } + + bool Material::SetEmissiveMap(const String& textureName) + { + TextureRef texture = TextureLibrary::Query(textureName); + if (!texture) + { + texture = TextureManager::Get(textureName); + if (!texture) + return false; + } + + SetEmissiveMap(std::move(texture)); + return true; + } + + void Material::SetEmissiveMap(TextureRef emissiveMap) + { + m_emissiveMap = std::move(emissiveMap); + + InvalidateShaders(); + } + + void Material::SetFaceCulling(FaceSide faceSide) + { + m_states.faceCulling = faceSide; + } + + void Material::SetFaceFilling(FaceFilling filling) + { + m_states.faceFilling = filling; + } + + bool Material::SetHeightMap(const String& textureName) + { + TextureRef texture = TextureLibrary::Query(textureName); + if (!texture) + { + texture = TextureManager::Get(textureName); + if (!texture) + return false; + } + + SetHeightMap(std::move(texture)); + return true; + } + + void Material::SetHeightMap(TextureRef heightMap) + { + m_heightMap = std::move(heightMap); + + InvalidateShaders(); + } + + bool Material::SetNormalMap(const String& textureName) + { + TextureRef texture = TextureLibrary::Query(textureName); + if (!texture) + { + texture = TextureManager::Get(textureName); + if (!texture) + return false; + } + + SetNormalMap(std::move(texture)); + return true; + } + + void Material::SetNormalMap(TextureRef normalMap) + { + m_normalMap = std::move(normalMap); + + InvalidateShaders(); + } + + void Material::SetRenderStates(const RenderStates& states) + { + m_states = states; + } + + void Material::SetShader(UberShaderConstRef uberShader) + { + m_uberShader = std::move(uberShader); + + InvalidateShaders(); + } + + bool Material::SetShader(const String& uberShaderName) + { + UberShaderConstRef uberShader = UberShaderLibrary::Get(uberShaderName); + if (!uberShader) + return false; + + SetShader(std::move(uberShader)); + return true; + } + + void Material::SetShininess(float shininess) + { + m_shininess = shininess; + } + + void Material::SetSpecularColor(const Color& specular) + { + m_specularColor = specular; + } + + bool Material::SetSpecularMap(const String& textureName) + { + TextureRef texture = TextureLibrary::Query(textureName); + if (!texture) + { + texture = TextureManager::Get(textureName); + if (!texture) + return false; + } + + SetSpecularMap(std::move(texture)); + return true; + } + + void Material::SetSpecularMap(TextureRef specularMap) + { + m_specularMap = std::move(specularMap); + + InvalidateShaders(); + } + + void Material::SetSpecularSampler(const TextureSampler& sampler) + { + m_specularSampler = sampler; + } + + void Material::SetSrcBlend(BlendFunc func) + { + m_states.srcBlend = func; + } + + Material& Material::operator=(const Material& material) + { + Resource::operator=(material); + + Copy(material); + return *this; + } + + MaterialRef Material::GetDefault() + { + return s_defaultMaterial; + } + + void Material::Copy(const Material& material) + { + // Copie des états de base + m_alphaTestEnabled = material.m_alphaTestEnabled; + m_alphaThreshold = material.m_alphaThreshold; + m_ambientColor = material.m_ambientColor; + m_depthSortingEnabled = material.m_depthSortingEnabled; + m_diffuseColor = material.m_diffuseColor; + m_diffuseSampler = material.m_diffuseSampler; + m_lightingEnabled = material.m_lightingEnabled; + m_shininess = material.m_shininess; + m_specularColor = material.m_specularColor; + m_specularSampler = material.m_specularSampler; + m_states = material.m_states; + m_transformEnabled = material.m_transformEnabled; + + // Copie des références de texture + m_alphaMap = material.m_alphaMap; + m_diffuseMap = material.m_diffuseMap; + m_emissiveMap = material.m_emissiveMap; + m_heightMap = material.m_heightMap; + m_normalMap = material.m_normalMap; + m_specularMap = material.m_specularMap; + + // Copie de la référence vers l'Über-Shader + m_uberShader = material.m_uberShader; + + // On copie les instances de shader par la même occasion + std::memcpy(&m_shaders[0], &material.m_shaders[0], (ShaderFlags_Max+1)*sizeof(ShaderInstance)); + } + + void Material::GenerateShader(UInt32 flags) const + { + ParameterList list; + list.SetParameter("ALPHA_MAPPING", m_alphaMap.IsValid()); + list.SetParameter("ALPHA_TEST", m_alphaTestEnabled); + list.SetParameter("COMPUTE_TBNMATRIX", m_normalMap.IsValid() || m_heightMap.IsValid()); + list.SetParameter("DIFFUSE_MAPPING", m_diffuseMap.IsValid()); + list.SetParameter("EMISSIVE_MAPPING", m_emissiveMap.IsValid()); + list.SetParameter("LIGHTING", m_lightingEnabled); + list.SetParameter("NORMAL_MAPPING", m_normalMap.IsValid()); + list.SetParameter("PARALLAX_MAPPING", m_heightMap.IsValid()); + list.SetParameter("SPECULAR_MAPPING", m_specularMap.IsValid()); + list.SetParameter("TEXTURE_MAPPING", m_alphaMap.IsValid() || m_diffuseMap.IsValid() || m_emissiveMap.IsValid() || + m_normalMap.IsValid() || m_heightMap.IsValid() || m_specularMap.IsValid() || + flags & ShaderFlags_TextureOverlay); + list.SetParameter("TRANSFORM", m_transformEnabled); + + list.SetParameter("FLAG_BILLBOARD", static_cast(flags & ShaderFlags_Billboard)); + list.SetParameter("FLAG_DEFERRED", static_cast((flags & ShaderFlags_Deferred) != 0)); + list.SetParameter("FLAG_INSTANCING", static_cast((flags & ShaderFlags_Instancing) != 0)); + list.SetParameter("FLAG_TEXTUREOVERLAY", static_cast((flags & ShaderFlags_TextureOverlay) != 0)); + list.SetParameter("FLAG_VERTEXCOLOR", static_cast((flags & ShaderFlags_VertexColor) != 0)); + + ShaderInstance& instance = m_shaders[flags]; + instance.uberInstance = m_uberShader->Get(list); + instance.shader = instance.uberInstance->GetShader(); + + #define CacheUniform(name) instance.uniforms[MaterialUniform_##name] = instance.shader->GetUniformLocation("Material" #name) + + CacheUniform(AlphaMap); + CacheUniform(AlphaThreshold); + CacheUniform(Ambient); + CacheUniform(Diffuse); + CacheUniform(DiffuseMap); + CacheUniform(EmissiveMap); + CacheUniform(HeightMap); + CacheUniform(NormalMap); + CacheUniform(Shininess); + CacheUniform(Specular); + CacheUniform(SpecularMap); + + #undef CacheUniform + } + + void Material::InvalidateShaders() + { + for (ShaderInstance& instance : m_shaders) + instance.uberInstance = nullptr; + } + + bool Material::Initialize() + { + if (!MaterialLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } + + if (!MaterialManager::Initialize()) + { + NazaraError("Failed to initialise manager"); + return false; + } + + bool glsl140 = (OpenGL::GetGLSLVersion() >= 140); + + // Basic shader + { + UberShaderPreprocessorRef uberShader = UberShaderPreprocessor::New(); + + String fragmentShader; + String vertexShader; + if (glsl140) + { + fragmentShader.Set(reinterpret_cast(r_coreFragmentShader), sizeof(r_coreFragmentShader)); + vertexShader.Set(reinterpret_cast(r_coreVertexShader), sizeof(r_coreVertexShader)); + } + else + { + fragmentShader.Set(reinterpret_cast(r_compatibilityFragmentShader), sizeof(r_compatibilityFragmentShader)); + vertexShader.Set(reinterpret_cast(r_compatibilityVertexShader), sizeof(r_compatibilityVertexShader)); + } + + uberShader->SetShader(ShaderStageType_Fragment, fragmentShader, "FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING"); + uberShader->SetShader(ShaderStageType_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_INSTANCING FLAG_VERTEXCOLOR TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); + + UberShaderLibrary::Register("Basic", uberShader); + } + + // PhongLighting shader + { + UberShaderPreprocessorRef uberShader = UberShaderPreprocessor::New(); + + String fragmentShader; + String vertexShader; + if (glsl140) + { + const UInt8 coreFragmentShader[] = { + #include + }; + + const UInt8 coreVertexShader[] = { + #include + }; + + fragmentShader.Set(reinterpret_cast(coreFragmentShader), sizeof(coreFragmentShader)); + vertexShader.Set(reinterpret_cast(coreVertexShader), sizeof(coreVertexShader)); + } + else + { + const UInt8 compatibilityFragmentShader[] = { + #include + }; + + const UInt8 compatibilityVertexShader[] = { + #include + }; + + fragmentShader.Set(reinterpret_cast(compatibilityFragmentShader), sizeof(compatibilityFragmentShader)); + vertexShader.Set(reinterpret_cast(compatibilityVertexShader), sizeof(compatibilityVertexShader)); + } + + uberShader->SetShader(ShaderStageType_Fragment, fragmentShader, "FLAG_DEFERRED FLAG_TEXTUREOVERLAY ALPHA_MAPPING ALPHA_TEST AUTO_TEXCOORDS DIFFUSE_MAPPING EMISSIVE_MAPPING LIGHTING NORMAL_MAPPING PARALLAX_MAPPING SPECULAR_MAPPING"); + uberShader->SetShader(ShaderStageType_Vertex, vertexShader, "FLAG_BILLBOARD FLAG_DEFERRED FLAG_INSTANCING FLAG_VERTEXCOLOR COMPUTE_TBNMATRIX LIGHTING PARALLAX_MAPPING TEXTURE_MAPPING TRANSFORM UNIFORM_VERTEX_DEPTH"); + + UberShaderLibrary::Register("PhongLighting", uberShader); + } + + // Une fois les shaders de base enregistrés, on peut créer le matériau par défaut + s_defaultMaterial = Material::New(); + s_defaultMaterial->Enable(RendererParameter_FaceCulling, false); + s_defaultMaterial->SetFaceFilling(FaceFilling_Line); + MaterialLibrary::Register("Default", s_defaultMaterial); + + return true; + } + + void Material::Uninitialize() + { + s_defaultMaterial.Reset(); + UberShaderLibrary::Unregister("PhongLighting"); + UberShaderLibrary::Unregister("Basic"); + MaterialManager::Uninitialize(); + MaterialLibrary::Uninitialize(); + } + + MaterialLibrary::LibraryMap Material::s_library; + MaterialLoader::LoaderList Material::s_loaders; + MaterialManager::ManagerMap Material::s_managerMap; + MaterialManager::ManagerParams Material::s_managerParameters; + MaterialRef Material::s_defaultMaterial = nullptr; } - -void NzMaterial::Uninitialize() -{ - s_defaultMaterial.Reset(); - NzUberShaderLibrary::Unregister("PhongLighting"); - NzUberShaderLibrary::Unregister("Basic"); - NzMaterialManager::Uninitialize(); - NzMaterialLibrary::Uninitialize(); -} - -NzMaterialLibrary::LibraryMap NzMaterial::s_library; -NzMaterialLoader::LoaderList NzMaterial::s_loaders; -NzMaterialManager::ManagerMap NzMaterial::s_managerMap; -NzMaterialManager::ManagerParams NzMaterial::s_managerParameters; -NzMaterialRef NzMaterial::s_defaultMaterial = nullptr; diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index 44829a4a6..fa7bfabe4 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -10,350 +10,353 @@ #include #include -NzModelParameters::NzModelParameters() +namespace Nz { - material.shaderName = "PhongLighting"; -} - -bool NzModelParameters::IsValid() const -{ - if (loadMaterials && !material.IsValid()) - return false; - - return mesh.IsValid(); -} - -NzModel::NzModel() : -m_matCount(0), -m_skin(0), -m_skinCount(1) -{ -} - -NzModel::~NzModel() -{ - Reset(); -} - -void NzModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const -{ - unsigned int submeshCount = m_mesh->GetSubMeshCount(); - for (unsigned int i = 0; i < submeshCount; ++i) + ModelParameters::ModelParameters() { - const NzStaticMesh* mesh = static_cast(m_mesh->GetSubMesh(i)); - NzMaterial* material = m_materials[mesh->GetMaterialIndex()]; - - NzMeshData meshData; - meshData.indexBuffer = mesh->GetIndexBuffer(); - meshData.primitiveMode = mesh->GetPrimitiveMode(); - meshData.vertexBuffer = mesh->GetVertexBuffer(); - - renderQueue->AddMesh(material, meshData, mesh->GetAABB(), instanceData.transformMatrix); - } -} - -NzMaterial* NzModel::GetMaterial(const NzString& subMeshName) const -{ - #if NAZARA_GRAPHICS_SAFE - if (!m_mesh) - { - NazaraError("Model has no mesh"); - return nullptr; - } - #endif - - NzSubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); - if (!subMesh) - { - NazaraError("Mesh has no submesh \"" + subMeshName + '"'); - return nullptr; + material.shaderName = "PhongLighting"; } - unsigned int matIndex = subMesh->GetMaterialIndex(); - if (matIndex >= m_matCount) + bool ModelParameters::IsValid() const { - NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_matCount) + ')'); - return nullptr; + if (loadMaterials && !material.IsValid()) + return false; + + return mesh.IsValid(); } - return m_materials[m_skin*m_matCount + matIndex]; -} - -NzMaterial* NzModel::GetMaterial(unsigned int matIndex) const -{ - #if NAZARA_GRAPHICS_SAFE - if (matIndex >= m_matCount) + Model::Model() : + m_matCount(0), + m_skin(0), + m_skinCount(1) { - NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_matCount) + ')'); - return nullptr; - } - #endif - - return m_materials[m_skin*m_matCount + matIndex]; -} - -NzMaterial* NzModel::GetMaterial(unsigned int skinIndex, const NzString& subMeshName) const -{ - #if NAZARA_GRAPHICS_SAFE - if (skinIndex >= m_skinCount) - { - NazaraError("Skin index out of range (" + NzString::Number(skinIndex) + " >= " + NzString::Number(m_skinCount) + ')'); - return nullptr; - } - #endif - - NzSubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); - if (!subMesh) - { - NazaraError("Mesh has no submesh \"" + subMeshName + '"'); - return nullptr; } - unsigned int matIndex = subMesh->GetMaterialIndex(); - if (matIndex >= m_matCount) + Model::~Model() { - NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_matCount) + ')'); - return nullptr; + Reset(); } - return m_materials[skinIndex*m_matCount + matIndex]; -} - -NzMaterial* NzModel::GetMaterial(unsigned int skinIndex, unsigned int matIndex) const -{ - #if NAZARA_GRAPHICS_SAFE - if (skinIndex >= m_skinCount) + void Model::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { - NazaraError("Skin index out of range (" + NzString::Number(skinIndex) + " >= " + NzString::Number(m_skinCount) + ')'); - return nullptr; + unsigned int submeshCount = m_mesh->GetSubMeshCount(); + for (unsigned int i = 0; i < submeshCount; ++i) + { + const StaticMesh* mesh = static_cast(m_mesh->GetSubMesh(i)); + Material* material = m_materials[mesh->GetMaterialIndex()]; + + MeshData meshData; + meshData.indexBuffer = mesh->GetIndexBuffer(); + meshData.primitiveMode = mesh->GetPrimitiveMode(); + meshData.vertexBuffer = mesh->GetVertexBuffer(); + + renderQueue->AddMesh(material, meshData, mesh->GetAABB(), instanceData.transformMatrix); + } } - if (matIndex >= m_matCount) + Material* Model::GetMaterial(const String& subMeshName) const { - NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_matCount) + ')'); - return nullptr; + #if NAZARA_GRAPHICS_SAFE + if (!m_mesh) + { + NazaraError("Model has no mesh"); + return nullptr; + } + #endif + + SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); + if (!subMesh) + { + NazaraError("Mesh has no submesh \"" + subMeshName + '"'); + return nullptr; + } + + unsigned int matIndex = subMesh->GetMaterialIndex(); + if (matIndex >= m_matCount) + { + NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); + return nullptr; + } + + return m_materials[m_skin*m_matCount + matIndex]; } - #endif - return m_materials[skinIndex*m_matCount + matIndex]; -} - -unsigned int NzModel::GetMaterialCount() const -{ - return m_matCount; -} - -NzMesh* NzModel::GetMesh() const -{ - return m_mesh; -} - -unsigned int NzModel::GetSkin() const -{ - return m_skin; -} - -unsigned int NzModel::GetSkinCount() const -{ - return m_skinCount; -} - -bool NzModel::IsAnimated() const -{ - return false; -} - -bool NzModel::LoadFromFile(const NzString& filePath, const NzModelParameters& params) -{ - return NzModelLoader::LoadFromFile(this, filePath, params); -} - -bool NzModel::LoadFromMemory(const void* data, std::size_t size, const NzModelParameters& params) -{ - return NzModelLoader::LoadFromMemory(this, data, size, params); -} - -bool NzModel::LoadFromStream(NzInputStream& stream, const NzModelParameters& params) -{ - return NzModelLoader::LoadFromStream(this, stream, params); -} - -void NzModel::Reset() -{ - m_matCount = 0; - m_skinCount = 0; - - if (m_mesh) + Material* Model::GetMaterial(unsigned int matIndex) const { - m_mesh.Reset(); - m_materials.clear(); + #if NAZARA_GRAPHICS_SAFE + if (matIndex >= m_matCount) + { + NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); + return nullptr; + } + #endif + + return m_materials[m_skin*m_matCount + matIndex]; } -} -bool NzModel::SetMaterial(const NzString& subMeshName, NzMaterial* material) -{ - NzSubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); - if (!subMesh) + Material* Model::GetMaterial(unsigned int skinIndex, const String& subMeshName) const + { + #if NAZARA_GRAPHICS_SAFE + if (skinIndex >= m_skinCount) + { + NazaraError("Skin index out of range (" + String::Number(skinIndex) + " >= " + String::Number(m_skinCount) + ')'); + return nullptr; + } + #endif + + SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); + if (!subMesh) + { + NazaraError("Mesh has no submesh \"" + subMeshName + '"'); + return nullptr; + } + + unsigned int matIndex = subMesh->GetMaterialIndex(); + if (matIndex >= m_matCount) + { + NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); + return nullptr; + } + + return m_materials[skinIndex*m_matCount + matIndex]; + } + + Material* Model::GetMaterial(unsigned int skinIndex, unsigned int matIndex) const + { + #if NAZARA_GRAPHICS_SAFE + if (skinIndex >= m_skinCount) + { + NazaraError("Skin index out of range (" + String::Number(skinIndex) + " >= " + String::Number(m_skinCount) + ')'); + return nullptr; + } + + if (matIndex >= m_matCount) + { + NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); + return nullptr; + } + #endif + + return m_materials[skinIndex*m_matCount + matIndex]; + } + + unsigned int Model::GetMaterialCount() const + { + return m_matCount; + } + + Mesh* Model::GetMesh() const + { + return m_mesh; + } + + unsigned int Model::GetSkin() const + { + return m_skin; + } + + unsigned int Model::GetSkinCount() const + { + return m_skinCount; + } + + bool Model::IsAnimated() const { - NazaraError("Mesh has no submesh \"" + subMeshName + '"'); return false; } - unsigned int matIndex = subMesh->GetMaterialIndex(); - if (matIndex >= m_matCount) + bool Model::LoadFromFile(const String& filePath, const ModelParameters& params) { - NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_matCount) + ')'); - return false; + return ModelLoader::LoadFromFile(this, filePath, params); } - unsigned int index = m_skin*m_matCount + matIndex; - - if (material) - m_materials[index] = material; - else - m_materials[index] = NzMaterial::GetDefault(); - - return true; -} - -void NzModel::SetMaterial(unsigned int matIndex, NzMaterial* material) -{ - #if NAZARA_GRAPHICS_SAFE - if (matIndex >= m_matCount) + bool Model::LoadFromMemory(const void* data, std::size_t size, const ModelParameters& params) { - NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_matCount)); - return; - } - #endif - - unsigned int index = m_skin*m_matCount + matIndex; - - if (material) - m_materials[index] = material; - else - m_materials[index] = NzMaterial::GetDefault(); -} - -bool NzModel::SetMaterial(unsigned int skinIndex, const NzString& subMeshName, NzMaterial* material) -{ - #if NAZARA_GRAPHICS_SAFE - if (skinIndex >= m_skinCount) - { - NazaraError("Skin index out of range (" + NzString::Number(skinIndex) + " >= " + NzString::Number(m_skinCount)); - return false; - } - #endif - - NzSubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); - if (!subMesh) - { - NazaraError("Mesh has no submesh \"" + subMeshName + '"'); - return false; + return ModelLoader::LoadFromMemory(this, data, size, params); } - unsigned int matIndex = subMesh->GetMaterialIndex(); - if (matIndex >= m_matCount) + bool Model::LoadFromStream(InputStream& stream, const ModelParameters& params) { - NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_matCount)); - return false; + return ModelLoader::LoadFromStream(this, stream, params); } - unsigned int index = skinIndex*m_matCount + matIndex; - - if (material) - m_materials[index] = material; - else - m_materials[index] = NzMaterial::GetDefault(); - - return true; -} - -void NzModel::SetMaterial(unsigned int skinIndex, unsigned int matIndex, NzMaterial* material) -{ - #if NAZARA_GRAPHICS_SAFE - if (skinIndex >= m_skinCount) - { - NazaraError("Skin index out of range (" + NzString::Number(skinIndex) + " >= " + NzString::Number(m_skinCount)); - return; - } - - if (matIndex >= m_matCount) - { - NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_matCount)); - return; - } - #endif - - unsigned int index = skinIndex*m_matCount + matIndex; - - if (material) - m_materials[index] = material; - else - m_materials[index] = NzMaterial::GetDefault(); -} - -void NzModel::SetMesh(NzMesh* mesh) -{ - #if NAZARA_GRAPHICS_SAFE - if (mesh && !mesh->IsValid()) - { - NazaraError("Invalid mesh"); - return; - } - #endif - - m_mesh = mesh; - - if (m_mesh) - { - m_matCount = mesh->GetMaterialCount(); - m_materials.clear(); - m_materials.resize(m_matCount, NzMaterial::GetDefault()); - m_skinCount = 1; - } - else + void Model::Reset() { m_matCount = 0; - m_materials.clear(); m_skinCount = 0; + + if (m_mesh) + { + m_mesh.Reset(); + m_materials.clear(); + } } - InvalidateBoundingVolume(); -} - -void NzModel::SetSkin(unsigned int skin) -{ - #if NAZARA_GRAPHICS_SAFE - if (skin >= m_skinCount) + bool Model::SetMaterial(const String& subMeshName, Material* material) { - NazaraError("Skin index out of range (" + NzString::Number(skin) + " >= " + NzString::Number(m_skinCount) + ')'); - return; + SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); + if (!subMesh) + { + NazaraError("Mesh has no submesh \"" + subMeshName + '"'); + return false; + } + + unsigned int matIndex = subMesh->GetMaterialIndex(); + if (matIndex >= m_matCount) + { + NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount) + ')'); + return false; + } + + unsigned int index = m_skin*m_matCount + matIndex; + + if (material) + m_materials[index] = material; + else + m_materials[index] = Material::GetDefault(); + + return true; } - #endif - m_skin = skin; -} - -void NzModel::SetSkinCount(unsigned int skinCount) -{ - #if NAZARA_GRAPHICS_SAFE - if (skinCount == 0) + void Model::SetMaterial(unsigned int matIndex, Material* material) { - NazaraError("Skin count must be over zero"); - return; + #if NAZARA_GRAPHICS_SAFE + if (matIndex >= m_matCount) + { + NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount)); + return; + } + #endif + + unsigned int index = m_skin*m_matCount + matIndex; + + if (material) + m_materials[index] = material; + else + m_materials[index] = Material::GetDefault(); } - #endif - m_materials.resize(m_matCount*skinCount, NzMaterial::GetDefault()); - m_skinCount = skinCount; + bool Model::SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material) + { + #if NAZARA_GRAPHICS_SAFE + if (skinIndex >= m_skinCount) + { + NazaraError("Skin index out of range (" + String::Number(skinIndex) + " >= " + String::Number(m_skinCount)); + return false; + } + #endif + + SubMesh* subMesh = m_mesh->GetSubMesh(subMeshName); + if (!subMesh) + { + NazaraError("Mesh has no submesh \"" + subMeshName + '"'); + return false; + } + + unsigned int matIndex = subMesh->GetMaterialIndex(); + if (matIndex >= m_matCount) + { + NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount)); + return false; + } + + unsigned int index = skinIndex*m_matCount + matIndex; + + if (material) + m_materials[index] = material; + else + m_materials[index] = Material::GetDefault(); + + return true; + } + + void Model::SetMaterial(unsigned int skinIndex, unsigned int matIndex, Material* material) + { + #if NAZARA_GRAPHICS_SAFE + if (skinIndex >= m_skinCount) + { + NazaraError("Skin index out of range (" + String::Number(skinIndex) + " >= " + String::Number(m_skinCount)); + return; + } + + if (matIndex >= m_matCount) + { + NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_matCount)); + return; + } + #endif + + unsigned int index = skinIndex*m_matCount + matIndex; + + if (material) + m_materials[index] = material; + else + m_materials[index] = Material::GetDefault(); + } + + void Model::SetMesh(Mesh* mesh) + { + #if NAZARA_GRAPHICS_SAFE + if (mesh && !mesh->IsValid()) + { + NazaraError("Invalid mesh"); + return; + } + #endif + + m_mesh = mesh; + + if (m_mesh) + { + m_matCount = mesh->GetMaterialCount(); + m_materials.clear(); + m_materials.resize(m_matCount, Material::GetDefault()); + m_skinCount = 1; + } + else + { + m_matCount = 0; + m_materials.clear(); + m_skinCount = 0; + } + + InvalidateBoundingVolume(); + } + + void Model::SetSkin(unsigned int skin) + { + #if NAZARA_GRAPHICS_SAFE + if (skin >= m_skinCount) + { + NazaraError("Skin index out of range (" + String::Number(skin) + " >= " + String::Number(m_skinCount) + ')'); + return; + } + #endif + + m_skin = skin; + } + + void Model::SetSkinCount(unsigned int skinCount) + { + #if NAZARA_GRAPHICS_SAFE + if (skinCount == 0) + { + NazaraError("Skin count must be over zero"); + return; + } + #endif + + m_materials.resize(m_matCount*skinCount, Material::GetDefault()); + m_skinCount = skinCount; + } + + void Model::MakeBoundingVolume() const + { + if (m_mesh) + m_boundingVolume.Set(m_mesh->GetAABB()); + else + m_boundingVolume.MakeNull(); + } + + ModelLoader::LoaderList Model::s_loaders; } - -void NzModel::MakeBoundingVolume() const -{ - if (m_mesh) - m_boundingVolume.Set(m_mesh->GetAABB()); - else - m_boundingVolume.MakeNull(); -} - -NzModelLoader::LoaderList NzModel::s_loaders; diff --git a/src/Nazara/Graphics/ParticleController.cpp b/src/Nazara/Graphics/ParticleController.cpp index 53f43e175..252887246 100644 --- a/src/Nazara/Graphics/ParticleController.cpp +++ b/src/Nazara/Graphics/ParticleController.cpp @@ -5,31 +5,34 @@ #include #include -NzParticleController::NzParticleController(const NzParticleController& controller) : -NzRefCounted() +namespace Nz { - NazaraUnused(controller); -} - -NzParticleController::~NzParticleController() -{ - OnParticleControllerRelease(this); -} - -bool NzParticleController::Initialize() -{ - if (!NzParticleControllerLibrary::Initialize()) + ParticleController::ParticleController(const ParticleController& controller) : + RefCounted() { - NazaraError("Failed to initialise library"); - return false; + NazaraUnused(controller); } - return true; -} + ParticleController::~ParticleController() + { + OnParticleControllerRelease(this); + } -void NzParticleController::Uninitialize() -{ - NzParticleControllerLibrary::Uninitialize(); -} + bool ParticleController::Initialize() + { + if (!ParticleControllerLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } -NzParticleControllerLibrary::LibraryMap NzParticleController::s_library; + return true; + } + + void ParticleController::Uninitialize() + { + ParticleControllerLibrary::Uninitialize(); + } + + ParticleControllerLibrary::LibraryMap ParticleController::s_library; +} diff --git a/src/Nazara/Graphics/ParticleDeclaration.cpp b/src/Nazara/Graphics/ParticleDeclaration.cpp index fc2c55c39..8d68b88ce 100644 --- a/src/Nazara/Graphics/ParticleDeclaration.cpp +++ b/src/Nazara/Graphics/ParticleDeclaration.cpp @@ -13,226 +13,229 @@ #include #include -NzParticleDeclaration::NzParticleDeclaration() : -m_stride(0) +namespace Nz { -} - -NzParticleDeclaration::NzParticleDeclaration(const NzParticleDeclaration& declaration) : -NzRefCounted(), -m_stride(declaration.m_stride) -{ - std::memcpy(m_components, declaration.m_components, sizeof(Component)*(nzParticleComponent_Max+1)); -} - -NzParticleDeclaration::~NzParticleDeclaration() -{ - OnParticleDeclarationRelease(this); -} - -void NzParticleDeclaration::DisableComponent(nzParticleComponent component) -{ - #ifdef NAZARA_DEBUG - if (component > nzParticleComponent_Max) + ParticleDeclaration::ParticleDeclaration() : + m_stride(0) { - NazaraError("Vertex component out of enum"); - return; - } - #endif - - #if NAZARA_GRAPHICS_SAFE - if (component == nzParticleComponent_Unused) - { - NazaraError("Cannot disable \"unused\" component"); - return; - } - #endif - - Component& vertexComponent = m_components[component]; - if (vertexComponent.enabled) - { - vertexComponent.enabled = false; - m_stride -= NzUtility::ComponentStride[vertexComponent.type]; - } -} - -void NzParticleDeclaration::EnableComponent(nzParticleComponent component, nzComponentType type, unsigned int offset) -{ - #ifdef NAZARA_DEBUG - if (component > nzParticleComponent_Max) - { - NazaraError("Vertex component out of enum"); - return; - } - #endif - - #if NAZARA_GRAPHICS_SAFE - if (!IsTypeSupported(type)) - { - NazaraError("Component type 0x" + NzString::Number(type, 16) + " is not supported by particle declarations"); - return; - } - #endif - - if (component != nzParticleComponent_Unused) - { - Component& particleComponent = m_components[component]; - if (particleComponent.enabled) - m_stride -= NzUtility::ComponentStride[particleComponent.type]; - else - particleComponent.enabled = true; - - particleComponent.offset = offset; - particleComponent.type = type; } - m_stride += NzUtility::ComponentStride[type]; -} - -void NzParticleDeclaration::GetComponent(nzParticleComponent component, bool* enabled, nzComponentType* type, unsigned int* offset) const -{ - #ifdef NAZARA_DEBUG - if (component > nzParticleComponent_Max) + ParticleDeclaration::ParticleDeclaration(const ParticleDeclaration& declaration) : + RefCounted(), + m_stride(declaration.m_stride) { - NazaraError("Particle component out of enum"); - return; - } - #endif - - #if NAZARA_GRAPHICS_SAFE - if (component == nzParticleComponent_Unused) - { - NazaraError("Cannot get \"unused\" component"); - return; - } - #endif - - const Component& particleComponent = m_components[component]; - - if (enabled) - *enabled = particleComponent.enabled; - - if (type) - *type = particleComponent.type; - - if (offset) - *offset = particleComponent.offset; -} - -unsigned int NzParticleDeclaration::GetStride() const -{ - return m_stride; -} - -void NzParticleDeclaration::SetStride(unsigned int stride) -{ - m_stride = stride; -} - -NzParticleDeclaration& NzParticleDeclaration::operator=(const NzParticleDeclaration& declaration) -{ - std::memcpy(m_components, declaration.m_components, sizeof(Component)*(nzParticleComponent_Max+1)); - m_stride = declaration.m_stride; - - return *this; -} - -NzParticleDeclaration* NzParticleDeclaration::Get(nzParticleLayout layout) -{ - #ifdef NAZARA_DEBUG - if (layout > nzParticleLayout_Max) - { - NazaraError("Particle layout out of enum"); - return nullptr; - } - #endif - - return &s_declarations[layout]; -} - -bool NzParticleDeclaration::IsTypeSupported(nzComponentType type) -{ - switch (type) - { - case nzComponentType_Color: - case nzComponentType_Double1: - case nzComponentType_Double2: - case nzComponentType_Double3: - case nzComponentType_Double4: - case nzComponentType_Float1: - case nzComponentType_Float2: - case nzComponentType_Float3: - case nzComponentType_Float4: - case nzComponentType_Int1: - case nzComponentType_Int2: - case nzComponentType_Int3: - case nzComponentType_Int4: - case nzComponentType_Quaternion: - return true; + std::memcpy(m_components, declaration.m_components, sizeof(Component)*(ParticleComponent_Max+1)); } - NazaraError("Component type not handled (0x" + NzString::Number(type, 16) + ')'); - return false; -} - -bool NzParticleDeclaration::Initialize() -{ - if (!NzParticleDeclarationLibrary::Initialize()) + ParticleDeclaration::~ParticleDeclaration() { - NazaraError("Failed to initialise library"); + OnParticleDeclarationRelease(this); + } + + void ParticleDeclaration::DisableComponent(ParticleComponent component) + { + #ifdef NAZARA_DEBUG + if (component > ParticleComponent_Max) + { + NazaraError("Vertex component out of enum"); + return; + } + #endif + + #if NAZARA_GRAPHICS_SAFE + if (component == ParticleComponent_Unused) + { + NazaraError("Cannot disable \"unused\" component"); + return; + } + #endif + + Component& vertexComponent = m_components[component]; + if (vertexComponent.enabled) + { + vertexComponent.enabled = false; + m_stride -= Utility::ComponentStride[vertexComponent.type]; + } + } + + void ParticleDeclaration::EnableComponent(ParticleComponent component, ComponentType type, unsigned int offset) + { + #ifdef NAZARA_DEBUG + if (component > ParticleComponent_Max) + { + NazaraError("Vertex component out of enum"); + return; + } + #endif + + #if NAZARA_GRAPHICS_SAFE + if (!IsTypeSupported(type)) + { + NazaraError("Component type 0x" + String::Number(type, 16) + " is not supported by particle declarations"); + return; + } + #endif + + if (component != ParticleComponent_Unused) + { + Component& particleComponent = m_components[component]; + if (particleComponent.enabled) + m_stride -= Utility::ComponentStride[particleComponent.type]; + else + particleComponent.enabled = true; + + particleComponent.offset = offset; + particleComponent.type = type; + } + + m_stride += Utility::ComponentStride[type]; + } + + void ParticleDeclaration::GetComponent(ParticleComponent component, bool* enabled, ComponentType* type, unsigned int* offset) const + { + #ifdef NAZARA_DEBUG + if (component > ParticleComponent_Max) + { + NazaraError("Particle component out of enum"); + return; + } + #endif + + #if NAZARA_GRAPHICS_SAFE + if (component == ParticleComponent_Unused) + { + NazaraError("Cannot get \"unused\" component"); + return; + } + #endif + + const Component& particleComponent = m_components[component]; + + if (enabled) + *enabled = particleComponent.enabled; + + if (type) + *type = particleComponent.type; + + if (offset) + *offset = particleComponent.offset; + } + + unsigned int ParticleDeclaration::GetStride() const + { + return m_stride; + } + + void ParticleDeclaration::SetStride(unsigned int stride) + { + m_stride = stride; + } + + ParticleDeclaration& ParticleDeclaration::operator=(const ParticleDeclaration& declaration) + { + std::memcpy(m_components, declaration.m_components, sizeof(Component)*(ParticleComponent_Max+1)); + m_stride = declaration.m_stride; + + return *this; + } + + ParticleDeclaration* ParticleDeclaration::Get(ParticleLayout layout) + { + #ifdef NAZARA_DEBUG + if (layout > ParticleLayout_Max) + { + NazaraError("Particle layout out of enum"); + return nullptr; + } + #endif + + return &s_declarations[layout]; + } + + bool ParticleDeclaration::IsTypeSupported(ComponentType type) + { + switch (type) + { + case ComponentType_Color: + case ComponentType_Double1: + case ComponentType_Double2: + case ComponentType_Double3: + case ComponentType_Double4: + case ComponentType_Float1: + case ComponentType_Float2: + case ComponentType_Float3: + case ComponentType_Float4: + case ComponentType_Int1: + case ComponentType_Int2: + case ComponentType_Int3: + case ComponentType_Int4: + case ComponentType_Quaternion: + return true; + } + + NazaraError("Component type not handled (0x" + String::Number(type, 16) + ')'); return false; } - try + bool ParticleDeclaration::Initialize() { - NzErrorFlags flags(nzErrorFlag_Silent | nzErrorFlag_ThrowException); + if (!ParticleDeclarationLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } - // Layout : Type - NzParticleDeclaration* declaration; + try + { + ErrorFlags flags(ErrorFlag_Silent | ErrorFlag_ThrowException); - // nzParticleLayout_Billboard : NzParticleStruct_Billboard - declaration = &s_declarations[nzParticleLayout_Billboard]; - declaration->EnableComponent(nzParticleComponent_Color, nzComponentType_Color, NzOffsetOf(NzParticleStruct_Billboard, color)); - declaration->EnableComponent(nzParticleComponent_Life, nzComponentType_Int1, NzOffsetOf(NzParticleStruct_Billboard, life)); - declaration->EnableComponent(nzParticleComponent_Normal, nzComponentType_Float3, NzOffsetOf(NzParticleStruct_Billboard, normal)); - declaration->EnableComponent(nzParticleComponent_Position, nzComponentType_Float3, NzOffsetOf(NzParticleStruct_Billboard, position)); - declaration->EnableComponent(nzParticleComponent_Rotation, nzComponentType_Float1, NzOffsetOf(NzParticleStruct_Billboard, rotation)); - declaration->EnableComponent(nzParticleComponent_Velocity, nzComponentType_Float3, NzOffsetOf(NzParticleStruct_Billboard, velocity)); + // Layout : Type + ParticleDeclaration* declaration; - NazaraAssert(declaration->GetStride() == sizeof(NzParticleStruct_Billboard), "Invalid stride for declaration nzParticleLayout_Billboard"); + // ParticleLayout_Billboard : ParticleStruct_Billboard + declaration = &s_declarations[ParticleLayout_Billboard]; + declaration->EnableComponent(ParticleComponent_Color, ComponentType_Color, NazaraOffsetOf(ParticleStruct_Billboard, color)); + declaration->EnableComponent(ParticleComponent_Life, ComponentType_Int1, NazaraOffsetOf(ParticleStruct_Billboard, life)); + declaration->EnableComponent(ParticleComponent_Normal, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, normal)); + declaration->EnableComponent(ParticleComponent_Position, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, position)); + declaration->EnableComponent(ParticleComponent_Rotation, ComponentType_Float1, NazaraOffsetOf(ParticleStruct_Billboard, rotation)); + declaration->EnableComponent(ParticleComponent_Velocity, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Billboard, velocity)); - // nzParticleLayout_Model : NzParticleStruct_Model - declaration = &s_declarations[nzParticleLayout_Model]; - declaration->EnableComponent(nzParticleComponent_Life, nzComponentType_Int1, NzOffsetOf(NzParticleStruct_Model, life)); - declaration->EnableComponent(nzParticleComponent_Position, nzComponentType_Float3, NzOffsetOf(NzParticleStruct_Model, position)); - declaration->EnableComponent(nzParticleComponent_Rotation, nzComponentType_Quaternion, NzOffsetOf(NzParticleStruct_Model, rotation)); - declaration->EnableComponent(nzParticleComponent_Velocity, nzComponentType_Float3, NzOffsetOf(NzParticleStruct_Model, velocity)); + NazaraAssert(declaration->GetStride() == sizeof(ParticleStruct_Billboard), "Invalid stride for declaration ParticleLayout_Billboard"); - NazaraAssert(declaration->GetStride() == sizeof(NzParticleStruct_Model), "Invalid stride for declaration nzParticleLayout_Model"); + // ParticleLayout_Model : ParticleStruct_Model + declaration = &s_declarations[ParticleLayout_Model]; + declaration->EnableComponent(ParticleComponent_Life, ComponentType_Int1, NazaraOffsetOf(ParticleStruct_Model, life)); + declaration->EnableComponent(ParticleComponent_Position, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Model, position)); + declaration->EnableComponent(ParticleComponent_Rotation, ComponentType_Quaternion, NazaraOffsetOf(ParticleStruct_Model, rotation)); + declaration->EnableComponent(ParticleComponent_Velocity, ComponentType_Float3, NazaraOffsetOf(ParticleStruct_Model, velocity)); - // nzParticleLayout_Sprite : NzParticleStruct_Sprite - declaration = &s_declarations[nzParticleLayout_Sprite]; - declaration->EnableComponent(nzParticleComponent_Color, nzComponentType_Color, NzOffsetOf(NzParticleStruct_Sprite, color)); - declaration->EnableComponent(nzParticleComponent_Life, nzComponentType_Int1, NzOffsetOf(NzParticleStruct_Sprite, life)); - declaration->EnableComponent(nzParticleComponent_Position, nzComponentType_Float2, NzOffsetOf(NzParticleStruct_Sprite, position)); - declaration->EnableComponent(nzParticleComponent_Rotation, nzComponentType_Float1, NzOffsetOf(NzParticleStruct_Sprite, rotation)); - declaration->EnableComponent(nzParticleComponent_Velocity, nzComponentType_Float2, NzOffsetOf(NzParticleStruct_Sprite, velocity)); + NazaraAssert(declaration->GetStride() == sizeof(ParticleStruct_Model), "Invalid stride for declaration ParticleLayout_Model"); - NazaraAssert(declaration->GetStride() == sizeof(NzParticleStruct_Sprite), "Invalid stride for declaration nzParticleLayout_Sprite"); - } - catch (const std::exception& e) - { - NazaraError("Failed to initialize particle declarations: " + NzString(e.what())); - return false; + // ParticleLayout_Sprite : ParticleStruct_Sprite + declaration = &s_declarations[ParticleLayout_Sprite]; + declaration->EnableComponent(ParticleComponent_Color, ComponentType_Color, NazaraOffsetOf(ParticleStruct_Sprite, color)); + declaration->EnableComponent(ParticleComponent_Life, ComponentType_Int1, NazaraOffsetOf(ParticleStruct_Sprite, life)); + declaration->EnableComponent(ParticleComponent_Position, ComponentType_Float2, NazaraOffsetOf(ParticleStruct_Sprite, position)); + declaration->EnableComponent(ParticleComponent_Rotation, ComponentType_Float1, NazaraOffsetOf(ParticleStruct_Sprite, rotation)); + declaration->EnableComponent(ParticleComponent_Velocity, ComponentType_Float2, NazaraOffsetOf(ParticleStruct_Sprite, velocity)); + + NazaraAssert(declaration->GetStride() == sizeof(ParticleStruct_Sprite), "Invalid stride for declaration ParticleLayout_Sprite"); + } + catch (const std::exception& e) + { + NazaraError("Failed to initialize particle declarations: " + String(e.what())); + return false; + } + + return true; } - return true; -} + void ParticleDeclaration::Uninitialize() + { + ParticleDeclarationLibrary::Uninitialize(); + } -void NzParticleDeclaration::Uninitialize() -{ - NzParticleDeclarationLibrary::Uninitialize(); + ParticleDeclaration ParticleDeclaration::s_declarations[ParticleLayout_Max+1]; + ParticleDeclarationLibrary::LibraryMap ParticleDeclaration::s_library; } - -NzParticleDeclaration NzParticleDeclaration::s_declarations[nzParticleLayout_Max+1]; -NzParticleDeclarationLibrary::LibraryMap NzParticleDeclaration::s_library; diff --git a/src/Nazara/Graphics/ParticleEmitter.cpp b/src/Nazara/Graphics/ParticleEmitter.cpp index 6dae5c6fd..9e87eb7c0 100644 --- a/src/Nazara/Graphics/ParticleEmitter.cpp +++ b/src/Nazara/Graphics/ParticleEmitter.cpp @@ -12,80 +12,83 @@ #include #include -NzParticleEmitter::NzParticleEmitter() : -m_lagCompensationEnabled(false), -m_emissionAccumulator(0.f), -m_emissionRate(0.f), -m_emissionCount(1) +namespace Nz { -} - -NzParticleEmitter::~NzParticleEmitter() = default; - -void NzParticleEmitter::Emit(NzParticleSystem& system, float elapsedTime) const -{ - if (m_emissionRate > 0.f) + ParticleEmitter::ParticleEmitter() : + m_lagCompensationEnabled(false), + m_emissionAccumulator(0.f), + m_emissionRate(0.f), + m_emissionCount(1) { - // On accumule la partie réelle (pour éviter qu'un taux d'update élevé empêche des particules de se former) - m_emissionAccumulator += elapsedTime*m_emissionRate; + } - float emissionCount = std::floor(m_emissionAccumulator); // Le nombre d'émissions de cette mise à jour - m_emissionAccumulator -= emissionCount; // On enlève la partie entière + ParticleEmitter::~ParticleEmitter() = default; - if (emissionCount >= 1.f) + void ParticleEmitter::Emit(ParticleSystem& system, float elapsedTime) const + { + if (m_emissionRate > 0.f) { - // On calcule le nombre maximum de particules pouvant être émises cette fois-ci - unsigned int emissionCountInt = static_cast(emissionCount); - unsigned int maxParticleCount = emissionCountInt*m_emissionCount; + // On accumule la partie réelle (pour éviter qu'un taux d'update élevé empêche des particules de se former) + m_emissionAccumulator += elapsedTime*m_emissionRate; - // On récupère le nombre de particules qu'il est possible de créer selon l'espace libre - unsigned int particleCount = std::min(maxParticleCount, system.GetMaxParticleCount() - system.GetParticleCount()); - if (particleCount == 0) - return; + float emissionCount = std::floor(m_emissionAccumulator); // Le nombre d'émissions de cette mise à jour + m_emissionAccumulator -= emissionCount; // On enlève la partie entière - // Et on émet nos particules - void* particles = system.GenerateParticles(particleCount); - NzParticleMapper mapper(particles, system.GetDeclaration()); - - SetupParticles(mapper, particleCount); - - if (m_lagCompensationEnabled) + if (emissionCount >= 1.f) { - // On va maintenant appliquer les contrôleurs - float invEmissionRate = 1.f/m_emissionRate; - for (unsigned int i = 1; i <= emissionCountInt; ++i) - system.ApplyControllers(mapper, std::min(m_emissionCount*i, particleCount), invEmissionRate); + // On calcule le nombre maximum de particules pouvant être émises cette fois-ci + unsigned int emissionCountInt = static_cast(emissionCount); + unsigned int maxParticleCount = emissionCountInt*m_emissionCount; + + // On récupère le nombre de particules qu'il est possible de créer selon l'espace libre + unsigned int particleCount = std::min(maxParticleCount, system.GetMaxParticleCount() - system.GetParticleCount()); + if (particleCount == 0) + return; + + // Et on émet nos particules + void* particles = system.GenerateParticles(particleCount); + ParticleMapper mapper(particles, system.GetDeclaration()); + + SetupParticles(mapper, particleCount); + + if (m_lagCompensationEnabled) + { + // On va maintenant appliquer les contrôleurs + float invEmissionRate = 1.f/m_emissionRate; + for (unsigned int i = 1; i <= emissionCountInt; ++i) + system.ApplyControllers(mapper, std::min(m_emissionCount*i, particleCount), invEmissionRate); + } } } } -} -void NzParticleEmitter::EnableLagCompensation(bool enable) -{ - m_lagCompensationEnabled = enable; -} + void ParticleEmitter::EnableLagCompensation(bool enable) + { + m_lagCompensationEnabled = enable; + } -unsigned int NzParticleEmitter::GetEmissionCount() const -{ - return m_emissionCount; -} + unsigned int ParticleEmitter::GetEmissionCount() const + { + return m_emissionCount; + } -float NzParticleEmitter::GetEmissionRate() const -{ - return m_emissionRate; -} + float ParticleEmitter::GetEmissionRate() const + { + return m_emissionRate; + } -bool NzParticleEmitter::IsLagCompensationEnabled() const -{ - return m_lagCompensationEnabled; -} + bool ParticleEmitter::IsLagCompensationEnabled() const + { + return m_lagCompensationEnabled; + } -void NzParticleEmitter::SetEmissionCount(unsigned int count) -{ - m_emissionCount = count; -} + void ParticleEmitter::SetEmissionCount(unsigned int count) + { + m_emissionCount = count; + } -void NzParticleEmitter::SetEmissionRate(float rate) -{ - m_emissionRate = rate; + void ParticleEmitter::SetEmissionRate(float rate) + { + m_emissionRate = rate; + } } diff --git a/src/Nazara/Graphics/ParticleGenerator.cpp b/src/Nazara/Graphics/ParticleGenerator.cpp index 4f12d7e95..d5e3b80ff 100644 --- a/src/Nazara/Graphics/ParticleGenerator.cpp +++ b/src/Nazara/Graphics/ParticleGenerator.cpp @@ -5,31 +5,34 @@ #include #include -NzParticleGenerator::NzParticleGenerator(const NzParticleGenerator& generator) : -NzRefCounted() +namespace Nz { - NazaraUnused(generator); -} - -NzParticleGenerator::~NzParticleGenerator() -{ - OnParticleGeneratorRelease(this); -} - -bool NzParticleGenerator::Initialize() -{ - if (!NzParticleGeneratorLibrary::Initialize()) + ParticleGenerator::ParticleGenerator(const ParticleGenerator& generator) : + RefCounted() { - NazaraError("Failed to initialise library"); - return false; + NazaraUnused(generator); } - return true; -} + ParticleGenerator::~ParticleGenerator() + { + OnParticleGeneratorRelease(this); + } -void NzParticleGenerator::Uninitialize() -{ - NzParticleGeneratorLibrary::Uninitialize(); -} + bool ParticleGenerator::Initialize() + { + if (!ParticleGeneratorLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } -NzParticleGeneratorLibrary::LibraryMap NzParticleGenerator::s_library; + return true; + } + + void ParticleGenerator::Uninitialize() + { + ParticleGeneratorLibrary::Uninitialize(); + } + + ParticleGeneratorLibrary::LibraryMap ParticleGenerator::s_library; +} diff --git a/src/Nazara/Graphics/ParticleMapper.cpp b/src/Nazara/Graphics/ParticleMapper.cpp index 03e1a1082..ce883e6e0 100644 --- a/src/Nazara/Graphics/ParticleMapper.cpp +++ b/src/Nazara/Graphics/ParticleMapper.cpp @@ -6,10 +6,14 @@ #include #include -NzParticleMapper::NzParticleMapper(void* buffer, const NzParticleDeclaration* declaration) : -m_declaration(declaration), -m_ptr(static_cast(buffer)) +namespace Nz { -} + ParticleMapper::ParticleMapper(void* buffer, const ParticleDeclaration* declaration) : + m_declaration(declaration), + m_ptr(static_cast(buffer)) + { + } -NzParticleMapper::~NzParticleMapper() = default; + ParticleMapper::~ParticleMapper() = default; + +} diff --git a/src/Nazara/Graphics/ParticleRenderer.cpp b/src/Nazara/Graphics/ParticleRenderer.cpp index 3102671ce..96ff3dd8a 100644 --- a/src/Nazara/Graphics/ParticleRenderer.cpp +++ b/src/Nazara/Graphics/ParticleRenderer.cpp @@ -5,31 +5,34 @@ #include #include -NzParticleRenderer::NzParticleRenderer(const NzParticleRenderer& renderer) : -NzRefCounted() +namespace Nz { - NazaraUnused(renderer); -} - -NzParticleRenderer::~NzParticleRenderer() -{ - OnParticleRendererRelease(this); -} - -bool NzParticleRenderer::Initialize() -{ - if (!NzParticleRendererLibrary::Initialize()) + ParticleRenderer::ParticleRenderer(const ParticleRenderer& renderer) : + RefCounted() { - NazaraError("Failed to initialise library"); - return false; + NazaraUnused(renderer); } - return true; -} + ParticleRenderer::~ParticleRenderer() + { + OnParticleRendererRelease(this); + } -void NzParticleRenderer::Uninitialize() -{ - NzParticleRendererLibrary::Uninitialize(); -} + bool ParticleRenderer::Initialize() + { + if (!ParticleRendererLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } -NzParticleRendererLibrary::LibraryMap NzParticleRenderer::s_library; + return true; + } + + void ParticleRenderer::Uninitialize() + { + ParticleRendererLibrary::Uninitialize(); + } + + ParticleRendererLibrary::LibraryMap ParticleRenderer::s_library; +} diff --git a/src/Nazara/Graphics/ParticleSystem.cpp b/src/Nazara/Graphics/ParticleSystem.cpp index ebfa3995e..2ac54e4af 100644 --- a/src/Nazara/Graphics/ParticleSystem.cpp +++ b/src/Nazara/Graphics/ParticleSystem.cpp @@ -11,294 +11,296 @@ #include #include -NzParticleSystem::NzParticleSystem(unsigned int maxParticleCount, nzParticleLayout layout) : -NzParticleSystem(maxParticleCount, NzParticleDeclaration::Get(layout)) +namespace Nz { -} - -NzParticleSystem::NzParticleSystem(unsigned int maxParticleCount, NzParticleDeclarationConstRef declaration) : -m_declaration(std::move(declaration)), -m_processing(false), -m_maxParticleCount(maxParticleCount), -m_particleCount(0) -{ - // En cas d'erreur, un constructeur ne peut que lancer une exception - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - m_particleSize = m_declaration->GetStride(); // La taille de chaque particule - - ResizeBuffer(); -} - -NzParticleSystem::NzParticleSystem(const NzParticleSystem& system) : -NzRenderable(system), -m_controllers(system.m_controllers), -m_generators(system.m_generators), -m_declaration(system.m_declaration), -m_renderer(system.m_renderer), -m_processing(false), -m_maxParticleCount(system.m_maxParticleCount), -m_particleCount(system.m_particleCount), -m_particleSize(system.m_particleSize) -{ - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - ResizeBuffer(); - - // On ne copie que les particules vivantes - std::memcpy(m_buffer.data(), system.m_buffer.data(), system.m_particleCount*m_particleSize); -} - -NzParticleSystem::~NzParticleSystem() = default; - -void NzParticleSystem::AddController(NzParticleControllerRef controller) -{ - NazaraAssert(controller, "Invalid particle controller"); - - m_controllers.emplace_back(std::move(controller)); -} - -void NzParticleSystem::AddEmitter(NzParticleEmitter* emitter) -{ - NazaraAssert(emitter, "Invalid particle emitter"); - - m_emitters.emplace_back(emitter); -} - -void NzParticleSystem::AddGenerator(NzParticleGeneratorRef generator) -{ - NazaraAssert(generator, "Invalid particle generator"); - - m_generators.emplace_back(std::move(generator)); -} - -void NzParticleSystem::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const NzMatrix4f& transformMatrix) const -{ - NazaraAssert(m_renderer, "Invalid particle renderer"); - NazaraAssert(renderQueue, "Invalid renderqueue"); - NazaraUnused(transformMatrix); - - if (m_particleCount > 0) + ParticleSystem::ParticleSystem(unsigned int maxParticleCount, ParticleLayout layout) : + ParticleSystem(maxParticleCount, ParticleDeclaration::Get(layout)) { - NzParticleMapper mapper(m_buffer.data(), m_declaration); - m_renderer->Render(*this, mapper, 0, m_particleCount-1, renderQueue); } -} -void NzParticleSystem::ApplyControllers(NzParticleMapper& mapper, unsigned int particleCount, float elapsedTime) -{ - m_processing = true; - - // Pour éviter un verrouillage en cas d'exception - NzCallOnExit onExit([this]() + ParticleSystem::ParticleSystem(unsigned int maxParticleCount, ParticleDeclarationConstRef declaration) : + m_declaration(std::move(declaration)), + m_processing(false), + m_maxParticleCount(maxParticleCount), + m_particleCount(0) { + // En cas d'erreur, un constructeur ne peut que lancer une exception + ErrorFlags flags(ErrorFlag_ThrowException, true); + + m_particleSize = m_declaration->GetStride(); // La taille de chaque particule + + ResizeBuffer(); + } + + ParticleSystem::ParticleSystem(const ParticleSystem& system) : + Renderable(system), + m_controllers(system.m_controllers), + m_generators(system.m_generators), + m_declaration(system.m_declaration), + m_renderer(system.m_renderer), + m_processing(false), + m_maxParticleCount(system.m_maxParticleCount), + m_particleCount(system.m_particleCount), + m_particleSize(system.m_particleSize) + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + + ResizeBuffer(); + + // On ne copie que les particules vivantes + std::memcpy(m_buffer.data(), system.m_buffer.data(), system.m_particleCount*m_particleSize); + } + + ParticleSystem::~ParticleSystem() = default; + + void ParticleSystem::AddController(ParticleControllerRef controller) + { + NazaraAssert(controller, "Invalid particle controller"); + + m_controllers.emplace_back(std::move(controller)); + } + + void ParticleSystem::AddEmitter(ParticleEmitter* emitter) + { + NazaraAssert(emitter, "Invalid particle emitter"); + + m_emitters.emplace_back(emitter); + } + + void ParticleSystem::AddGenerator(ParticleGeneratorRef generator) + { + NazaraAssert(generator, "Invalid particle generator"); + + m_generators.emplace_back(std::move(generator)); + } + + void ParticleSystem::AddToRenderQueue(AbstractRenderQueue* renderQueue, const Matrix4f& transformMatrix) const + { + NazaraAssert(m_renderer, "Invalid particle renderer"); + NazaraAssert(renderQueue, "Invalid renderqueue"); + NazaraUnused(transformMatrix); + + if (m_particleCount > 0) + { + ParticleMapper mapper(m_buffer.data(), m_declaration); + m_renderer->Render(*this, mapper, 0, m_particleCount-1, renderQueue); + } + } + + void ParticleSystem::ApplyControllers(ParticleMapper& mapper, unsigned int particleCount, float elapsedTime) + { + m_processing = true; + + // Pour éviter un verrouillage en cas d'exception + CallOnExit onExit([this]() + { + m_processing = false; + }); + + for (ParticleController* controller : m_controllers) + controller->Apply(*this, mapper, 0, particleCount-1, elapsedTime); + + onExit.CallAndReset(); + + // On tue maintenant les particules mortes durant la mise à jour + if (m_dyingParticles.size() < m_particleCount) + { + // On tue les particules depuis la dernière vers la première (en terme de place), le std::set étant trié via std::greater + // La raison est simple, étant donné que la mort d'une particule signifie le déplacement de la dernière particule du buffer, + // sans cette solution certaines particules pourraient échapper à la mort + for (unsigned int index : m_dyingParticles) + KillParticle(index); + } + else + KillParticles(); // Toutes les particules sont mortes, ceci est beaucoup plus rapide + + m_dyingParticles.clear(); + } + + void* ParticleSystem::CreateParticle() + { + return CreateParticles(1); + } + + void* ParticleSystem::CreateParticles(unsigned int count) + { + if (count == 0) + return nullptr; + + if (m_particleCount + count > m_maxParticleCount) + return nullptr; + + unsigned int particlesIndex = m_particleCount; + m_particleCount += count; + + return &m_buffer[particlesIndex*m_particleSize]; + } + + void* ParticleSystem::GenerateParticle() + { + return GenerateParticles(1); + } + + void* ParticleSystem::GenerateParticles(unsigned int count) + { + void* ptr = CreateParticles(count); + if (!ptr) + return nullptr; + + ParticleMapper mapper(ptr, m_declaration); + for (ParticleGenerator* generator : m_generators) + generator->Generate(*this, mapper, 0, count-1); + + return ptr; + } + + const ParticleDeclarationConstRef& ParticleSystem::GetDeclaration() const + { + return m_declaration; + } + + float ParticleSystem::GetFixedStepSize() const + { + return m_stepSize; + } + + unsigned int ParticleSystem::GetMaxParticleCount() const + { + return m_maxParticleCount; + } + + unsigned int ParticleSystem::GetParticleCount() const + { + return m_particleCount; + } + + unsigned int ParticleSystem::GetParticleSize() const + { + return m_particleSize; + } + + void ParticleSystem::KillParticle(unsigned int index) + { + ///FIXME: Vérifier index + + if (m_processing) + { + // Le buffer est en train d'être modifié, nous ne pouvons pas réduire sa taille, on place alors la particule dans une liste d'attente + m_dyingParticles.insert(index); + return; + } + + // On déplace la dernière particule vivante à la place de celle-ci + if (--m_particleCount > 0) + std::memcpy(&m_buffer[index*m_particleSize], &m_buffer[m_particleCount*m_particleSize], m_particleSize); + } + + void ParticleSystem::KillParticles() + { + m_particleCount = 0; + } + + void ParticleSystem::RemoveController(ParticleController* controller) + { + auto it = std::find(m_controllers.begin(), m_controllers.end(), controller); + if (it != m_controllers.end()) + m_controllers.erase(it); + } + + void ParticleSystem::RemoveEmitter(ParticleEmitter* emitter) + { + auto it = std::find(m_emitters.begin(), m_emitters.end(), emitter); + if (it != m_emitters.end()) + m_emitters.erase(it); + } + + void ParticleSystem::RemoveGenerator(ParticleGenerator* generator) + { + auto it = std::find(m_generators.begin(), m_generators.end(), generator); + if (it != m_generators.end()) + m_generators.erase(it); + } + + void ParticleSystem::SetFixedStepSize(float stepSize) + { + m_stepSize = stepSize; + } + + void ParticleSystem::SetRenderer(ParticleRenderer* renderer) + { + m_renderer = renderer; + } + + void ParticleSystem::Update(float elapsedTime) + { + // Émission + for (ParticleEmitter* emitter : m_emitters) + emitter->Emit(*this, elapsedTime); + + // Mise à jour + if (m_particleCount > 0) + { + ///TODO: Mettre à jour en utilisant des threads + ParticleMapper mapper(m_buffer.data(), m_declaration); + ApplyControllers(mapper, m_particleCount, elapsedTime); + } + } + + void ParticleSystem::UpdateBoundingVolume(const Matrix4f& transformMatrix) + { + NazaraUnused(transformMatrix); + + // Nothing to do here (our bounding volume is global) + } + + ParticleSystem& ParticleSystem::operator=(const ParticleSystem& system) + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + + Renderable::operator=(system); + + m_controllers = system.m_controllers; + m_declaration = system.m_declaration; + m_generators = system.m_generators; + m_maxParticleCount = system.m_maxParticleCount; + m_particleCount = system.m_particleCount; + m_particleSize = system.m_particleSize; + m_renderer = system.m_renderer; + m_stepSize = system.m_stepSize; + + // La copie ne peut pas (ou plutôt ne devrait pas) avoir lieu pendant une mise à jour, inutile de copier + m_dyingParticles.clear(); m_processing = false; - }); + m_stepAccumulator = 0.f; - for (NzParticleController* controller : m_controllers) - controller->Apply(*this, mapper, 0, particleCount-1, elapsedTime); + m_buffer.clear(); // Pour éviter une recopie lors du resize() qui ne servira pas à grand chose + ResizeBuffer(); - onExit.CallAndReset(); + // On ne copie que les particules vivantes + std::memcpy(m_buffer.data(), system.m_buffer.data(), system.m_particleCount*m_particleSize); - // On tue maintenant les particules mortes durant la mise à jour - if (m_dyingParticles.size() < m_particleCount) - { - // On tue les particules depuis la dernière vers la première (en terme de place), le std::set étant trié via std::greater - // La raison est simple, étant donné que la mort d'une particule signifie le déplacement de la dernière particule du buffer, - // sans cette solution certaines particules pourraient échapper à la mort - for (unsigned int index : m_dyingParticles) - KillParticle(index); - } - else - KillParticles(); // Toutes les particules sont mortes, ceci est beaucoup plus rapide - - m_dyingParticles.clear(); -} - -void* NzParticleSystem::CreateParticle() -{ - return CreateParticles(1); -} - -void* NzParticleSystem::CreateParticles(unsigned int count) -{ - if (count == 0) - return nullptr; - - if (m_particleCount + count > m_maxParticleCount) - return nullptr; - - unsigned int particlesIndex = m_particleCount; - m_particleCount += count; - - return &m_buffer[particlesIndex*m_particleSize]; -} - -void* NzParticleSystem::GenerateParticle() -{ - return GenerateParticles(1); -} - -void* NzParticleSystem::GenerateParticles(unsigned int count) -{ - void* ptr = CreateParticles(count); - if (!ptr) - return nullptr; - - NzParticleMapper mapper(ptr, m_declaration); - for (NzParticleGenerator* generator : m_generators) - generator->Generate(*this, mapper, 0, count-1); - - return ptr; -} - -const NzParticleDeclarationConstRef& NzParticleSystem::GetDeclaration() const -{ - return m_declaration; -} - -float NzParticleSystem::GetFixedStepSize() const -{ - return m_stepSize; -} - -unsigned int NzParticleSystem::GetMaxParticleCount() const -{ - return m_maxParticleCount; -} - -unsigned int NzParticleSystem::GetParticleCount() const -{ - return m_particleCount; -} - -unsigned int NzParticleSystem::GetParticleSize() const -{ - return m_particleSize; -} - -void NzParticleSystem::KillParticle(unsigned int index) -{ - ///FIXME: Vérifier index - - if (m_processing) - { - // Le buffer est en train d'être modifié, nous ne pouvons pas réduire sa taille, on place alors la particule dans une liste d'attente - m_dyingParticles.insert(index); - return; + return *this; } - // On déplace la dernière particule vivante à la place de celle-ci - if (--m_particleCount > 0) - std::memcpy(&m_buffer[index*m_particleSize], &m_buffer[m_particleCount*m_particleSize], m_particleSize); -} - -void NzParticleSystem::KillParticles() -{ - m_particleCount = 0; -} - -void NzParticleSystem::RemoveController(NzParticleController* controller) -{ - auto it = std::find(m_controllers.begin(), m_controllers.end(), controller); - if (it != m_controllers.end()) - m_controllers.erase(it); -} - -void NzParticleSystem::RemoveEmitter(NzParticleEmitter* emitter) -{ - auto it = std::find(m_emitters.begin(), m_emitters.end(), emitter); - if (it != m_emitters.end()) - m_emitters.erase(it); -} - -void NzParticleSystem::RemoveGenerator(NzParticleGenerator* generator) -{ - auto it = std::find(m_generators.begin(), m_generators.end(), generator); - if (it != m_generators.end()) - m_generators.erase(it); -} - -void NzParticleSystem::SetFixedStepSize(float stepSize) -{ - m_stepSize = stepSize; -} - -void NzParticleSystem::SetRenderer(NzParticleRenderer* renderer) -{ - m_renderer = renderer; -} - -void NzParticleSystem::Update(float elapsedTime) -{ - // Émission - for (NzParticleEmitter* emitter : m_emitters) - emitter->Emit(*this, elapsedTime); - - // Mise à jour - if (m_particleCount > 0) + void ParticleSystem::MakeBoundingVolume() const { - ///TODO: Mettre à jour en utilisant des threads - NzParticleMapper mapper(m_buffer.data(), m_declaration); - ApplyControllers(mapper, m_particleCount, elapsedTime); + ///TODO: Calculer l'AABB (prendre la taille des particules en compte s'il y a) + m_boundingVolume.MakeInfinite(); + } + + void ParticleSystem::ResizeBuffer() + { + // Histoire de décrire un peu mieux l'erreur en cas d'échec + try + { + m_buffer.resize(m_maxParticleCount*m_particleSize); + } + catch (const std::exception& e) + { + StringStream stream; + stream << "Failed to allocate particle buffer (" << e.what() << ") for " << m_maxParticleCount << " particles of size " << m_particleSize; + + NazaraError(stream.ToString()); + } } } - -void NzParticleSystem::UpdateBoundingVolume(const NzMatrix4f& transformMatrix) -{ - NazaraUnused(transformMatrix); - - // Nothing to do here (our bounding volume is global) -} - -NzParticleSystem& NzParticleSystem::operator=(const NzParticleSystem& system) -{ - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - NzRenderable::operator=(system); - - m_controllers = system.m_controllers; - m_declaration = system.m_declaration; - m_generators = system.m_generators; - m_maxParticleCount = system.m_maxParticleCount; - m_particleCount = system.m_particleCount; - m_particleSize = system.m_particleSize; - m_renderer = system.m_renderer; - m_stepSize = system.m_stepSize; - - // La copie ne peut pas (ou plutôt ne devrait pas) avoir lieu pendant une mise à jour, inutile de copier - m_dyingParticles.clear(); - m_processing = false; - m_stepAccumulator = 0.f; - - m_buffer.clear(); // Pour éviter une recopie lors du resize() qui ne servira pas à grand chose - ResizeBuffer(); - - // On ne copie que les particules vivantes - std::memcpy(m_buffer.data(), system.m_buffer.data(), system.m_particleCount*m_particleSize); - - return *this; -} - -void NzParticleSystem::MakeBoundingVolume() const -{ - ///TODO: Calculer l'AABB (prendre la taille des particules en compte s'il y a) - m_boundingVolume.MakeInfinite(); -} - -void NzParticleSystem::ResizeBuffer() -{ - // Histoire de décrire un peu mieux l'erreur en cas d'échec - try - { - m_buffer.resize(m_maxParticleCount*m_particleSize); - } - catch (const std::exception& e) - { - NzStringStream stream; - stream << "Failed to allocate particle buffer (" << e.what() << ") for " << m_maxParticleCount << " particles of size " << m_particleSize; - - NazaraError(stream.ToString()); - } -} - diff --git a/src/Nazara/Graphics/RenderTechniques.cpp b/src/Nazara/Graphics/RenderTechniques.cpp index 820700451..b21c31218 100644 --- a/src/Nazara/Graphics/RenderTechniques.cpp +++ b/src/Nazara/Graphics/RenderTechniques.cpp @@ -9,157 +9,160 @@ #include #include -namespace +namespace Nz { - const char* techniquesName[] = + namespace { - "Advanced Forward", - "Basic Forward", - "Deferred Shading", - "Light Pre-Pass", - "User" - }; - - static_assert(sizeof(techniquesName)/sizeof(const char*) == nzRenderTechniqueType_Max+1, "Render technique type name array is incomplete"); - - struct RenderTechnique - { - NzRenderTechniques::RenderTechniqueFactory factory; - int ranking; - }; - - std::unordered_map s_renderTechniques; -} - -NzAbstractRenderTechnique* NzRenderTechniques::GetByEnum(nzRenderTechniqueType renderTechnique, int* techniqueRanking) -{ - #ifdef NAZARA_DEBUG - if (renderTechnique > nzRenderTechniqueType_Max) - { - NazaraError("Render technique type out of enum"); - return nullptr; - } - #endif - - return GetByName(techniquesName[renderTechnique], techniqueRanking); -} - -NzAbstractRenderTechnique* NzRenderTechniques::GetByIndex(unsigned int index, int* techniqueRanking) -{ - #if NAZARA_GRAPHICS_SAFE - if (index >= s_renderTechniques.size()) - { - NazaraError("Technique index out of range (" + NzString::Number(index) + " >= " + NzString::Number(s_renderTechniques.size()) + ')'); - return nullptr; - } - #endif - - auto it = s_renderTechniques.begin(); - std::advance(it, index); - - if (techniqueRanking) - *techniqueRanking = it->second.ranking; - - return it->second.factory(); -} - -NzAbstractRenderTechnique* NzRenderTechniques::GetByName(const NzString& name, int* techniqueRanking) -{ - #if NAZARA_GRAPHICS_SAFE - if (name.IsEmpty()) - { - NazaraError("Technique name cannot be empty"); - return nullptr; - } - #endif - - auto it = s_renderTechniques.find(name); - if (it == s_renderTechniques.end()) - { - NazaraError("Technique not found"); - return nullptr; - } - - if (techniqueRanking) - *techniqueRanking = it->second.ranking; - - return it->second.factory(); -} - -NzAbstractRenderTechnique* NzRenderTechniques::GetByRanking(int maxRanking, int* techniqueRanking) -{ - if (maxRanking < 0) - maxRanking = std::numeric_limits::max(); - - int currentRanking = -1; - RenderTechnique* technique = nullptr; - - for (auto it = s_renderTechniques.begin(); it != s_renderTechniques.end(); ++it) - { - int ranking = it->second.ranking; - if (ranking > currentRanking && ranking <= maxRanking) + const char* techniquesName[] = { - currentRanking = ranking; - technique = &(it->second); + "Advanced Forward", + "Basic Forward", + "Deferred Shading", + "Light Pre-Pass", + "User" + }; + + static_assert(sizeof(techniquesName)/sizeof(const char*) == RenderTechniqueType_Max+1, "Render technique type name array is incomplete"); + + struct RenderTechnique + { + RenderTechniques::RenderTechniqueFactory factory; + int ranking; + }; + + std::unordered_map s_renderTechniques; + } + + AbstractRenderTechnique* RenderTechniques::GetByEnum(RenderTechniqueType renderTechnique, int* techniqueRanking) + { + #ifdef NAZARA_DEBUG + if (renderTechnique > RenderTechniqueType_Max) + { + NazaraError("Render technique type out of enum"); + return nullptr; } + #endif + + return GetByName(techniquesName[renderTechnique], techniqueRanking); } - if (!technique) + AbstractRenderTechnique* RenderTechniques::GetByIndex(unsigned int index, int* techniqueRanking) { - NazaraError("No technique found"); - return nullptr; + #if NAZARA_GRAPHICS_SAFE + if (index >= s_renderTechniques.size()) + { + NazaraError("Technique index out of range (" + String::Number(index) + " >= " + String::Number(s_renderTechniques.size()) + ')'); + return nullptr; + } + #endif + + auto it = s_renderTechniques.begin(); + std::advance(it, index); + + if (techniqueRanking) + *techniqueRanking = it->second.ranking; + + return it->second.factory(); } - if (techniqueRanking) - *techniqueRanking = currentRanking; - - return technique->factory(); -} - -unsigned int NzRenderTechniques::GetCount() -{ - return s_renderTechniques.size(); -} - -void NzRenderTechniques::Register(const NzString& name, int ranking, RenderTechniqueFactory factory) -{ - #if NAZARA_GRAPHICS_SAFE - if (name.IsEmpty()) + AbstractRenderTechnique* RenderTechniques::GetByName(const String& name, int* techniqueRanking) { - NazaraError("Technique name cannot be empty"); - return; + #if NAZARA_GRAPHICS_SAFE + if (name.IsEmpty()) + { + NazaraError("Technique name cannot be empty"); + return nullptr; + } + #endif + + auto it = s_renderTechniques.find(name); + if (it == s_renderTechniques.end()) + { + NazaraError("Technique not found"); + return nullptr; + } + + if (techniqueRanking) + *techniqueRanking = it->second.ranking; + + return it->second.factory(); } - if (ranking < 0) + AbstractRenderTechnique* RenderTechniques::GetByRanking(int maxRanking, int* techniqueRanking) { - NazaraError("Technique ranking cannot be negative"); - return; + if (maxRanking < 0) + maxRanking = std::numeric_limits::max(); + + int currentRanking = -1; + RenderTechnique* technique = nullptr; + + for (auto it = s_renderTechniques.begin(); it != s_renderTechniques.end(); ++it) + { + int ranking = it->second.ranking; + if (ranking > currentRanking && ranking <= maxRanking) + { + currentRanking = ranking; + technique = &(it->second); + } + } + + if (!technique) + { + NazaraError("No technique found"); + return nullptr; + } + + if (techniqueRanking) + *techniqueRanking = currentRanking; + + return technique->factory(); } - if (!factory) + unsigned int RenderTechniques::GetCount() { - NazaraError("Technique function must be valid"); - return; + return s_renderTechniques.size(); } - #endif - s_renderTechniques[name] = {factory, ranking}; -} - -NzString NzRenderTechniques::ToString(nzRenderTechniqueType renderTechnique) -{ - #ifdef NAZARA_DEBUG - if (renderTechnique > nzRenderTechniqueType_Max) + void RenderTechniques::Register(const String& name, int ranking, RenderTechniqueFactory factory) { - NazaraError("Render technique type out of enum"); - return NzString("Error"); + #if NAZARA_GRAPHICS_SAFE + if (name.IsEmpty()) + { + NazaraError("Technique name cannot be empty"); + return; + } + + if (ranking < 0) + { + NazaraError("Technique ranking cannot be negative"); + return; + } + + if (!factory) + { + NazaraError("Technique function must be valid"); + return; + } + #endif + + s_renderTechniques[name] = {factory, ranking}; } - #endif - return techniquesName[renderTechnique]; -} + String RenderTechniques::ToString(RenderTechniqueType renderTechnique) + { + #ifdef NAZARA_DEBUG + if (renderTechnique > RenderTechniqueType_Max) + { + NazaraError("Render technique type out of enum"); + return String("Error"); + } + #endif -void NzRenderTechniques::Unregister(const NzString& name) -{ - s_renderTechniques.erase(name); + return techniquesName[renderTechnique]; + } + + void RenderTechniques::Unregister(const String& name) + { + s_renderTechniques.erase(name); + } } diff --git a/src/Nazara/Graphics/Renderable.cpp b/src/Nazara/Graphics/Renderable.cpp index 30140949d..932a8d127 100644 --- a/src/Nazara/Graphics/Renderable.cpp +++ b/src/Nazara/Graphics/Renderable.cpp @@ -5,23 +5,26 @@ #include #include -NzRenderable::~NzRenderable() = default; - -bool NzRenderable::Cull(const NzFrustumf& frustum, const NzMatrix4f& transformMatrix) const +namespace Nz { - NazaraUnused(transformMatrix); + Renderable::~Renderable() = default; - return frustum.Contains(m_boundingVolume); -} - -const NzBoundingVolumef& NzRenderable::GetBoundingVolume() const -{ - EnsureBoundingVolumeUpdated(); - - return m_boundingVolume; -} - -void NzRenderable::UpdateBoundingVolume(const NzMatrix4f& transformMatrix) -{ - m_boundingVolume.Update(transformMatrix); + bool Renderable::Cull(const Frustumf& frustum, const Matrix4f& transformMatrix) const + { + NazaraUnused(transformMatrix); + + return frustum.Contains(m_boundingVolume); + } + + const BoundingVolumef& Renderable::GetBoundingVolume() const + { + EnsureBoundingVolumeUpdated(); + + return m_boundingVolume; + } + + void Renderable::UpdateBoundingVolume(const Matrix4f& transformMatrix) + { + m_boundingVolume.Update(transformMatrix); + } } diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index 9283e2c09..71ff53bb5 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -12,276 +12,279 @@ #include #include -bool NzSkeletalModelParameters::IsValid() const +namespace Nz { - if (!NzModelParameters::IsValid()) - return false; - - if (loadAnimation && !animation.IsValid()) - return false; - - return true; -} - -NzSkeletalModel::NzSkeletalModel() : -m_currentSequence(nullptr), -m_animationEnabled(true) -{ -} - -void NzSkeletalModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const -{ - if (!m_mesh) - return; - - unsigned int submeshCount = m_mesh->GetSubMeshCount(); - for (unsigned int i = 0; i < submeshCount; ++i) + bool SkeletalModelParameters::IsValid() const { - const NzSkeletalMesh* mesh = static_cast(m_mesh->GetSubMesh(i)); - const NzMaterial* material = m_materials[mesh->GetMaterialIndex()]; + if (!ModelParameters::IsValid()) + return false; - NzMeshData meshData; - meshData.indexBuffer = mesh->GetIndexBuffer(); - meshData.primitiveMode = mesh->GetPrimitiveMode(); - meshData.vertexBuffer = NzSkinningManager::GetBuffer(mesh, &m_skeleton); + if (loadAnimation && !animation.IsValid()) + return false; - renderQueue->AddMesh(material, meshData, m_skeleton.GetAABB(), instanceData.transformMatrix); + return true; } -} -void NzSkeletalModel::AdvanceAnimation(float elapsedTime) -{ - #if NAZARA_GRAPHICS_SAFE - if (!m_animation) + SkeletalModel::SkeletalModel() : + m_currentSequence(nullptr), + m_animationEnabled(true) { - NazaraError("Model has no animation"); - return; } - #endif - m_interpolation += m_currentSequence->frameRate * elapsedTime; - while (m_interpolation > 1.f) + void SkeletalModel::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { - m_interpolation -= 1.f; + if (!m_mesh) + return; - unsigned lastFrame = m_currentSequence->firstFrame + m_currentSequence->frameCount - 1; - if (m_nextFrame+1 > lastFrame) + unsigned int submeshCount = m_mesh->GetSubMeshCount(); + for (unsigned int i = 0; i < submeshCount; ++i) { - if (m_animation->IsLoopPointInterpolationEnabled()) + const SkeletalMesh* mesh = static_cast(m_mesh->GetSubMesh(i)); + const Material* material = m_materials[mesh->GetMaterialIndex()]; + + MeshData meshData; + meshData.indexBuffer = mesh->GetIndexBuffer(); + meshData.primitiveMode = mesh->GetPrimitiveMode(); + meshData.vertexBuffer = SkinningManager::GetBuffer(mesh, &m_skeleton); + + renderQueue->AddMesh(material, meshData, m_skeleton.GetAABB(), instanceData.transformMatrix); + } + } + + void SkeletalModel::AdvanceAnimation(float elapsedTime) + { + #if NAZARA_GRAPHICS_SAFE + if (!m_animation) + { + NazaraError("Model has no animation"); + return; + } + #endif + + m_interpolation += m_currentSequence->frameRate * elapsedTime; + while (m_interpolation > 1.f) + { + m_interpolation -= 1.f; + + unsigned lastFrame = m_currentSequence->firstFrame + m_currentSequence->frameCount - 1; + if (m_nextFrame+1 > lastFrame) { - m_currentFrame = m_nextFrame; - m_nextFrame = m_currentSequence->firstFrame; + if (m_animation->IsLoopPointInterpolationEnabled()) + { + m_currentFrame = m_nextFrame; + m_nextFrame = m_currentSequence->firstFrame; + } + else + { + m_currentFrame = m_currentSequence->firstFrame; + m_nextFrame = m_currentFrame+1; + } } else { - m_currentFrame = m_currentSequence->firstFrame; - m_nextFrame = m_currentFrame+1; + m_currentFrame = m_nextFrame; + m_nextFrame++; } } - else - { - m_currentFrame = m_nextFrame; - m_nextFrame++; - } + + m_animation->AnimateSkeleton(&m_skeleton, m_currentFrame, m_nextFrame, m_interpolation); + + InvalidateBoundingVolume(); } - m_animation->AnimateSkeleton(&m_skeleton, m_currentFrame, m_nextFrame, m_interpolation); - - InvalidateBoundingVolume(); -} - -NzSkeletalModel* NzSkeletalModel::Clone() const -{ - return new NzSkeletalModel(*this); -} - -NzSkeletalModel* NzSkeletalModel::Create() const -{ - return new NzSkeletalModel; -} - -void NzSkeletalModel::EnableAnimation(bool animation) -{ - m_animationEnabled = animation; -} - -NzAnimation* NzSkeletalModel::GetAnimation() const -{ - return m_animation; -} - -NzSkeleton* NzSkeletalModel::GetSkeleton() -{ - InvalidateBoundingVolume(); - - return &m_skeleton; -} - -const NzSkeleton* NzSkeletalModel::GetSkeleton() const -{ - return &m_skeleton; -} - -bool NzSkeletalModel::HasAnimation() const -{ - return m_animation != nullptr; -} - -bool NzSkeletalModel::IsAnimated() const -{ - return true; -} - -bool NzSkeletalModel::IsAnimationEnabled() const -{ - return m_animationEnabled; -} - -bool NzSkeletalModel::LoadFromFile(const NzString& filePath, const NzSkeletalModelParameters& params) -{ - return NzSkeletalModelLoader::LoadFromFile(this, filePath, params); -} - -bool NzSkeletalModel::LoadFromMemory(const void* data, std::size_t size, const NzSkeletalModelParameters& params) -{ - return NzSkeletalModelLoader::LoadFromMemory(this, data, size, params); -} - -bool NzSkeletalModel::LoadFromStream(NzInputStream& stream, const NzSkeletalModelParameters& params) -{ - return NzSkeletalModelLoader::LoadFromStream(this, stream, params); -} - -void NzSkeletalModel::Reset() -{ - NzModel::Reset(); - - m_skeleton.Destroy(); -} - -bool NzSkeletalModel::SetAnimation(NzAnimation* animation) -{ - #if NAZARA_GRAPHICS_SAFE - if (!m_mesh) + SkeletalModel* SkeletalModel::Clone() const { - NazaraError("Model has no mesh"); - return false; + return new SkeletalModel(*this); } - if (animation) + SkeletalModel* SkeletalModel::Create() const { - if (!animation->IsValid()) + return new SkeletalModel; + } + + void SkeletalModel::EnableAnimation(bool animation) + { + m_animationEnabled = animation; + } + + Animation* SkeletalModel::GetAnimation() const + { + return m_animation; + } + + Skeleton* SkeletalModel::GetSkeleton() + { + InvalidateBoundingVolume(); + + return &m_skeleton; + } + + const Skeleton* SkeletalModel::GetSkeleton() const + { + return &m_skeleton; + } + + bool SkeletalModel::HasAnimation() const + { + return m_animation != nullptr; + } + + bool SkeletalModel::IsAnimated() const + { + return true; + } + + bool SkeletalModel::IsAnimationEnabled() const + { + return m_animationEnabled; + } + + bool SkeletalModel::LoadFromFile(const String& filePath, const SkeletalModelParameters& params) + { + return SkeletalModelLoader::LoadFromFile(this, filePath, params); + } + + bool SkeletalModel::LoadFromMemory(const void* data, std::size_t size, const SkeletalModelParameters& params) + { + return SkeletalModelLoader::LoadFromMemory(this, data, size, params); + } + + bool SkeletalModel::LoadFromStream(InputStream& stream, const SkeletalModelParameters& params) + { + return SkeletalModelLoader::LoadFromStream(this, stream, params); + } + + void SkeletalModel::Reset() + { + Model::Reset(); + + m_skeleton.Destroy(); + } + + bool SkeletalModel::SetAnimation(Animation* animation) + { + #if NAZARA_GRAPHICS_SAFE + if (!m_mesh) { - NazaraError("Invalid animation"); + NazaraError("Model has no mesh"); return false; } - if (animation->GetType() != m_mesh->GetAnimationType()) + if (animation) { - NazaraError("Animation type must match mesh animation type"); + if (!animation->IsValid()) + { + NazaraError("Invalid animation"); + return false; + } + + if (animation->GetType() != m_mesh->GetAnimationType()) + { + NazaraError("Animation type must match mesh animation type"); + return false; + } + + if (animation->GetJointCount() != m_mesh->GetJointCount()) + { + NazaraError("Animation joint count must match mesh joint count"); + return false; + } + } + #endif + + m_animation = animation; + if (m_animation) + { + m_currentFrame = 0; + m_interpolation = 0.f; + + SetSequence(0); + } + + return true; + } + + void SkeletalModel::SetMesh(Mesh* mesh) + { + #if NAZARA_GRAPHICS_SAFE + if (mesh && mesh->GetAnimationType() != AnimationType_Skeletal) + { + NazaraError("Mesh animation type must be skeletal"); + return; + } + #endif + + Model::SetMesh(mesh); + + if (m_mesh) + { + if (m_animation && m_animation->GetJointCount() != m_mesh->GetJointCount()) + { + NazaraWarning("Animation joint count is not matching new mesh joint count, disabling animation..."); + SetAnimation(nullptr); + } + + m_skeleton = *m_mesh->GetSkeleton(); // Copie du squelette template + } + } + + bool SkeletalModel::SetSequence(const String& sequenceName) + { + ///TODO: Rendre cette erreur "safe" avec le nouveau système de gestions d'erreur (No-log) + #if NAZARA_GRAPHICS_SAFE + if (!m_animation) + { + NazaraError("Model has no animation"); + return false; + } + #endif + + const Sequence* currentSequence = m_animation->GetSequence(sequenceName); + if (!currentSequence) + { + NazaraError("Sequence not found"); return false; } - if (animation->GetJointCount() != m_mesh->GetJointCount()) + m_currentSequence = currentSequence; + m_nextFrame = m_currentSequence->firstFrame; + + return true; + } + + void SkeletalModel::SetSequence(unsigned int sequenceIndex) + { + #if NAZARA_GRAPHICS_SAFE + if (!m_animation) { - NazaraError("Animation joint count must match mesh joint count"); - return false; + NazaraError("Model has no animation"); + return; } - } - #endif + #endif - m_animation = animation; - if (m_animation) - { - m_currentFrame = 0; - m_interpolation = 0.f; - - SetSequence(0); - } - - return true; -} - -void NzSkeletalModel::SetMesh(NzMesh* mesh) -{ - #if NAZARA_GRAPHICS_SAFE - if (mesh && mesh->GetAnimationType() != nzAnimationType_Skeletal) - { - NazaraError("Mesh animation type must be skeletal"); - return; - } - #endif - - NzModel::SetMesh(mesh); - - if (m_mesh) - { - if (m_animation && m_animation->GetJointCount() != m_mesh->GetJointCount()) + const Sequence* currentSequence = m_animation->GetSequence(sequenceIndex); + #if NAZARA_GRAPHICS_SAFE + if (!currentSequence) { - NazaraWarning("Animation joint count is not matching new mesh joint count, disabling animation..."); - SetAnimation(nullptr); + NazaraError("Sequence not found"); + return; } + #endif - m_skeleton = *m_mesh->GetSkeleton(); // Copie du squelette template + m_currentSequence = currentSequence; + m_nextFrame = m_currentSequence->firstFrame; } -} -bool NzSkeletalModel::SetSequence(const NzString& sequenceName) -{ - ///TODO: Rendre cette erreur "safe" avec le nouveau système de gestions d'erreur (No-log) - #if NAZARA_GRAPHICS_SAFE - if (!m_animation) + void SkeletalModel::MakeBoundingVolume() const { - NazaraError("Model has no animation"); - return false; + m_boundingVolume.Set(m_skeleton.GetAABB()); } - #endif - const NzSequence* currentSequence = m_animation->GetSequence(sequenceName); - if (!currentSequence) + void SkeletalModel::Update() { - NazaraError("Sequence not found"); - return false; + /*if (m_animationEnabled && m_animation) + AdvanceAnimation(m_scene->GetUpdateTime());*/ } - m_currentSequence = currentSequence; - m_nextFrame = m_currentSequence->firstFrame; - - return true; + SkeletalModelLoader::LoaderList SkeletalModel::s_loaders; } - -void NzSkeletalModel::SetSequence(unsigned int sequenceIndex) -{ - #if NAZARA_GRAPHICS_SAFE - if (!m_animation) - { - NazaraError("Model has no animation"); - return; - } - #endif - - const NzSequence* currentSequence = m_animation->GetSequence(sequenceIndex); - #if NAZARA_GRAPHICS_SAFE - if (!currentSequence) - { - NazaraError("Sequence not found"); - return; - } - #endif - - m_currentSequence = currentSequence; - m_nextFrame = m_currentSequence->firstFrame; -} - -void NzSkeletalModel::MakeBoundingVolume() const -{ - m_boundingVolume.Set(m_skeleton.GetAABB()); -} - -void NzSkeletalModel::Update() -{ - /*if (m_animationEnabled && m_animation) - AdvanceAnimation(m_scene->GetUpdateTime());*/ -} - -NzSkeletalModelLoader::LoaderList NzSkeletalModel::s_loaders; diff --git a/src/Nazara/Graphics/SkinningManager.cpp b/src/Nazara/Graphics/SkinningManager.cpp index a64a3863e..0f4b3140a 100644 --- a/src/Nazara/Graphics/SkinningManager.cpp +++ b/src/Nazara/Graphics/SkinningManager.cpp @@ -13,183 +13,186 @@ #include #include -namespace +namespace Nz { - struct BufferData + namespace { - NazaraSlot(NzSkeletalMesh, OnSkeletalMeshDestroy, skeletalMeshDestroySlot); - - NzVertexBufferRef buffer; - bool updated; - }; - - using MeshMap = std::unordered_map; - - struct MeshData - { - NazaraSlot(NzSkeleton, OnSkeletonDestroy, skeletonDestroySlot); - NazaraSlot(NzSkeleton, OnSkeletonJointsInvalidated, skeletonJointsInvalidatedSlot); - - MeshMap meshMap; - }; - - struct SkinningData - { - const NzSkeletalMesh* mesh; - const NzSkeleton* skeleton; - NzVertexBuffer* buffer; - }; - - using SkeletonMap = std::unordered_map; - SkeletonMap s_cache; - std::vector s_skinningQueue; - - - void Skin_MonoCPU(const NzSkeletalMesh* mesh, const NzSkeleton* skeleton, NzVertexBuffer* buffer) - { - NzBufferMapper inputMapper(mesh->GetVertexBuffer(), nzBufferAccess_ReadOnly); - NzBufferMapper outputMapper(buffer, nzBufferAccess_DiscardAndWrite); - - NzSkinningData skinningData; - skinningData.inputVertex = static_cast(inputMapper.GetPointer()); - skinningData.outputVertex = static_cast(outputMapper.GetPointer()); - skinningData.joints = skeleton->GetJoints(); - - NzSkinPositionNormalTangent(skinningData, 0, mesh->GetVertexCount()); - } - - void Skin_MultiCPU(const NzSkeletalMesh* mesh, const NzSkeleton* skeleton, NzVertexBuffer* buffer) - { - NzBufferMapper inputMapper(mesh->GetVertexBuffer(), nzBufferAccess_ReadOnly); - NzBufferMapper outputMapper(buffer, nzBufferAccess_DiscardAndWrite); - - NzSkinningData skinningData; - skinningData.inputVertex = static_cast(inputMapper.GetPointer()); - skinningData.outputVertex = static_cast(outputMapper.GetPointer()); - skinningData.joints = skeleton->GetJoints(); - - // Afin d'empêcher les différents threads de vouloir mettre à jour la même matrice en même temps, - // on se charge de la mettre à jour avant de les lancer - unsigned int jointCount = skeleton->GetJointCount(); - for (unsigned int i = 0; i < jointCount; ++i) - skinningData.joints[i].EnsureSkinningMatrixUpdate(); - - unsigned int workerCount = NzTaskScheduler::GetWorkerCount(); - - std::ldiv_t div = std::ldiv(mesh->GetVertexCount(), workerCount); - for (unsigned int i = 0; i < workerCount; ++i) - NzTaskScheduler::AddTask(NzSkinPositionNormalTangent, skinningData, i*div.quot, (i == workerCount-1) ? div.quot + div.rem : div.quot); - - NzTaskScheduler::Run(); - NzTaskScheduler::WaitForTasks(); - } -} - -NzVertexBuffer* NzSkinningManager::GetBuffer(const NzSkeletalMesh* mesh, const NzSkeleton* skeleton) -{ - #if NAZARA_GRAPHICS_SAFE - if (!mesh) - { - NazaraError("Invalid mesh"); - return nullptr; - } - - if (!skeleton) - { - NazaraError("Invalid skeleton"); - return nullptr; - } - #endif - - NzErrorFlags flags(nzErrorFlag_ThrowException); - - SkeletonMap::iterator it = s_cache.find(skeleton); - if (it == s_cache.end()) - { - MeshData meshData; - meshData.skeletonDestroySlot.Connect(skeleton->OnSkeletonDestroy, OnSkeletonRelease); - meshData.skeletonJointsInvalidatedSlot.Connect(skeleton->OnSkeletonJointsInvalidated, OnSkeletonInvalidated); - - it = s_cache.insert(std::make_pair(skeleton, std::move(meshData))).first; - } - - NzVertexBuffer* buffer; - - MeshMap& meshMap = it->second.meshMap; - MeshMap::iterator it2 = meshMap.find(mesh); - if (it2 == meshMap.end()) - { - NzVertexBufferRef vertexBuffer = NzVertexBuffer::New(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), mesh->GetVertexCount(), nzDataStorage_Hardware, nzBufferUsage_Dynamic); - - BufferData data; - data.skeletalMeshDestroySlot.Connect(mesh->OnSkeletalMeshDestroy, OnSkeletalMeshDestroy); - data.buffer = vertexBuffer; - data.updated = true; - - meshMap.insert(std::make_pair(mesh, std::move(data))); - - s_skinningQueue.push_back(SkinningData{mesh, skeleton, vertexBuffer}); - - buffer = vertexBuffer; - } - else - { - BufferData& data = it2->second; - if (!data.updated) + struct BufferData { - s_skinningQueue.push_back(SkinningData{mesh, skeleton, data.buffer}); - data.updated = true; + NazaraSlot(SkeletalMesh, OnSkeletalMeshDestroy, skeletalMeshDestroySlot); + + VertexBufferRef buffer; + bool updated; + }; + + using MeshMap = std::unordered_map; + + struct MeshData + { + NazaraSlot(Skeleton, OnSkeletonDestroy, skeletonDestroySlot); + NazaraSlot(Skeleton, OnSkeletonJointsInvalidated, skeletonJointsInvalidatedSlot); + + MeshMap meshMap; + }; + + struct QueueData + { + const SkeletalMesh* mesh; + const Skeleton* skeleton; + VertexBuffer* buffer; + }; + + using SkeletonMap = std::unordered_map; + SkeletonMap s_cache; + std::vector s_skinningQueue; + + + void Skin_MonoCPU(const SkeletalMesh* mesh, const Skeleton* skeleton, VertexBuffer* buffer) + { + BufferMapper inputMapper(mesh->GetVertexBuffer(), BufferAccess_ReadOnly); + BufferMapper outputMapper(buffer, BufferAccess_DiscardAndWrite); + + SkinningData skinningData; + skinningData.inputVertex = static_cast(inputMapper.GetPointer()); + skinningData.outputVertex = static_cast(outputMapper.GetPointer()); + skinningData.joints = skeleton->GetJoints(); + + SkinPositionNormalTangent(skinningData, 0, mesh->GetVertexCount()); } - buffer = data.buffer; + void Skin_MultiCPU(const SkeletalMesh* mesh, const Skeleton* skeleton, VertexBuffer* buffer) + { + BufferMapper inputMapper(mesh->GetVertexBuffer(), BufferAccess_ReadOnly); + BufferMapper outputMapper(buffer, BufferAccess_DiscardAndWrite); + + SkinningData skinningData; + skinningData.inputVertex = static_cast(inputMapper.GetPointer()); + skinningData.outputVertex = static_cast(outputMapper.GetPointer()); + skinningData.joints = skeleton->GetJoints(); + + // Afin d'empêcher les différents threads de vouloir mettre à jour la même matrice en même temps, + // on se charge de la mettre à jour avant de les lancer + unsigned int jointCount = skeleton->GetJointCount(); + for (unsigned int i = 0; i < jointCount; ++i) + skinningData.joints[i].EnsureSkinningMatrixUpdate(); + + unsigned int workerCount = TaskScheduler::GetWorkerCount(); + + std::ldiv_t div = std::ldiv(mesh->GetVertexCount(), workerCount); + for (unsigned int i = 0; i < workerCount; ++i) + TaskScheduler::AddTask(SkinPositionNormalTangent, skinningData, i*div.quot, (i == workerCount-1) ? div.quot + div.rem : div.quot); + + TaskScheduler::Run(); + TaskScheduler::WaitForTasks(); + } } - return buffer; -} - -void NzSkinningManager::Skin() -{ - for (SkinningData& data : s_skinningQueue) - s_skinFunc(data.mesh, data.skeleton, data.buffer); - - s_skinningQueue.clear(); -} - -bool NzSkinningManager::Initialize() -{ - ///TODO: GPU Skinning - if (NzTaskScheduler::Initialize()) - s_skinFunc = Skin_MultiCPU; - else - s_skinFunc = Skin_MonoCPU; - - return true; // Rien de particulier à faire -} - -void NzSkinningManager::OnSkeletalMeshDestroy(const NzSkeletalMesh* mesh) -{ - for (auto& pair : s_cache) + VertexBuffer* SkinningManager::GetBuffer(const SkeletalMesh* mesh, const Skeleton* skeleton) { - MeshMap& meshMap = pair.second.meshMap; - meshMap.erase(mesh); + #if NAZARA_GRAPHICS_SAFE + if (!mesh) + { + NazaraError("Invalid mesh"); + return nullptr; + } + + if (!skeleton) + { + NazaraError("Invalid skeleton"); + return nullptr; + } + #endif + + ErrorFlags flags(ErrorFlag_ThrowException); + + SkeletonMap::iterator it = s_cache.find(skeleton); + if (it == s_cache.end()) + { + MeshData meshData; + meshData.skeletonDestroySlot.Connect(skeleton->OnSkeletonDestroy, OnSkeletonRelease); + meshData.skeletonJointsInvalidatedSlot.Connect(skeleton->OnSkeletonJointsInvalidated, OnSkeletonInvalidated); + + it = s_cache.insert(std::make_pair(skeleton, std::move(meshData))).first; + } + + VertexBuffer* buffer; + + MeshMap& meshMap = it->second.meshMap; + MeshMap::iterator it2 = meshMap.find(mesh); + if (it2 == meshMap.end()) + { + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), mesh->GetVertexCount(), DataStorage_Hardware, BufferUsage_Dynamic); + + BufferData data; + data.skeletalMeshDestroySlot.Connect(mesh->OnSkeletalMeshDestroy, OnSkeletalMeshDestroy); + data.buffer = vertexBuffer; + data.updated = true; + + meshMap.insert(std::make_pair(mesh, std::move(data))); + + s_skinningQueue.push_back(QueueData{mesh, skeleton, vertexBuffer}); + + buffer = vertexBuffer; + } + else + { + BufferData& data = it2->second; + if (!data.updated) + { + s_skinningQueue.push_back(QueueData{mesh, skeleton, data.buffer}); + data.updated = true; + } + + buffer = data.buffer; + } + + return buffer; } -} -void NzSkinningManager::OnSkeletonInvalidated(const NzSkeleton* skeleton) -{ - for (auto& pair : s_cache.at(skeleton).meshMap) - pair.second.updated = false; -} + void SkinningManager::Skin() + { + for (QueueData& data : s_skinningQueue) + s_skinFunc(data.mesh, data.skeleton, data.buffer); -void NzSkinningManager::OnSkeletonRelease(const NzSkeleton* skeleton) -{ - s_cache.erase(skeleton); -} + s_skinningQueue.clear(); + } -void NzSkinningManager::Uninitialize() -{ - s_cache.clear(); - s_skinningQueue.clear(); -} + bool SkinningManager::Initialize() + { + ///TODO: GPU Skinning + if (TaskScheduler::Initialize()) + s_skinFunc = Skin_MultiCPU; + else + s_skinFunc = Skin_MonoCPU; -NzSkinningManager::SkinFunction NzSkinningManager::s_skinFunc = nullptr; + return true; // Rien de particulier à faire + } + + void SkinningManager::OnSkeletalMeshDestroy(const SkeletalMesh* mesh) + { + for (auto& pair : s_cache) + { + MeshMap& meshMap = pair.second.meshMap; + meshMap.erase(mesh); + } + } + + void SkinningManager::OnSkeletonInvalidated(const Skeleton* skeleton) + { + for (auto& pair : s_cache.at(skeleton).meshMap) + pair.second.updated = false; + } + + void SkinningManager::OnSkeletonRelease(const Skeleton* skeleton) + { + s_cache.erase(skeleton); + } + + void SkinningManager::Uninitialize() + { + s_cache.clear(); + s_skinningQueue.clear(); + } + + SkinningManager::SkinFunction SkinningManager::s_skinFunc = nullptr; +} diff --git a/src/Nazara/Graphics/SkyboxBackground.cpp b/src/Nazara/Graphics/SkyboxBackground.cpp index b528f68d3..1e8678c20 100644 --- a/src/Nazara/Graphics/SkyboxBackground.cpp +++ b/src/Nazara/Graphics/SkyboxBackground.cpp @@ -12,148 +12,151 @@ #include #include -namespace +namespace Nz { - static NzIndexBufferRef s_indexBuffer; - static NzRenderStates s_renderStates; - static NzShaderRef s_shader; - static NzVertexBufferRef s_vertexBuffer; -} - -NzSkyboxBackground::NzSkyboxBackground(NzTextureRef cubemapTexture) -{ - m_sampler.SetWrapMode(nzSamplerWrap_Clamp); // Nécessaire pour ne pas voir les côtés - - SetTexture(std::move(cubemapTexture)); -} - -void NzSkyboxBackground::Draw(const NzAbstractViewer* viewer) const -{ - NzMatrix4f skyboxMatrix(viewer->GetViewMatrix()); - skyboxMatrix.SetTranslation(NzVector3f::Zero()); - - NzRenderer::SetIndexBuffer(s_indexBuffer); - NzRenderer::SetMatrix(nzMatrixType_View, skyboxMatrix); - NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Scale(NzVector3f(viewer->GetZNear()))); - NzRenderer::SetRenderStates(s_renderStates); - NzRenderer::SetShader(s_shader); - NzRenderer::SetTexture(0, m_texture); - NzRenderer::SetTextureSampler(0, m_sampler); - NzRenderer::SetVertexBuffer(s_vertexBuffer); - - NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, 36); - - NzRenderer::SetMatrix(nzMatrixType_View, viewer->GetViewMatrix()); -} - -nzBackgroundType NzSkyboxBackground::GetBackgroundType() const -{ - return nzBackgroundType_Skybox; -} - -bool NzSkyboxBackground::Initialize() -{ - const nzUInt16 indices[6*6] = + namespace { - 0, 1, 2, 0, 2, 3, - 3, 2, 6, 3, 6, 7, - 7, 6, 5, 7, 5, 4, - 4, 5, 1, 4, 1, 0, - 0, 3, 7, 0, 7, 4, - 1, 6, 2, 1, 5, 6 - }; - - const float vertices[8 * 3 * sizeof(float)] = - { - -1.0, 1.0, 1.0, - -1.0, -1.0, 1.0, - 1.0, -1.0, 1.0, - 1.0, 1.0, 1.0, - -1.0, 1.0, -1.0, - -1.0, -1.0, -1.0, - 1.0, -1.0, -1.0, - 1.0, 1.0, -1.0, - }; - - ///TODO: Replace by ShaderNode (probably after Vulkan) - const char* fragmentShaderSource = - "#version 140\n" - - "in vec3 vTexCoord;\n" - - "out vec4 RenderTarget0;\n" - - "uniform samplerCube Skybox;\n" - "uniform float VertexDepth;\n" - - "void main()\n" - "{\n" - " RenderTarget0 = texture(Skybox, vTexCoord);\n" - " gl_FragDepth = VertexDepth;\n" - "}\n"; - - const char* vertexShaderSource = - "#version 140\n" - - "in vec3 VertexPosition;\n" - - "out vec3 vTexCoord;\n" - - "uniform mat4 WorldViewProjMatrix;\n" - - "void main()\n" - "{\n" - " vec4 WVPVertex = WorldViewProjMatrix * vec4(VertexPosition, 1.0);\n" - " gl_Position = WVPVertex.xyww;\n" - " vTexCoord = vec3(VertexPosition.x, VertexPosition.y, -VertexPosition.z);\n" - "}\n"; - - try - { - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - // Index buffer - NzIndexBufferRef indexBuffer = NzIndexBuffer::New(false, 36, nzDataStorage_Hardware, nzBufferUsage_Static); - indexBuffer->Fill(indices, 0, 36); - - // Vertex buffer - NzVertexBufferRef vertexBuffer = NzVertexBuffer::New(NzVertexDeclaration::Get(nzVertexLayout_XYZ), 8, nzDataStorage_Hardware, nzBufferUsage_Static); - vertexBuffer->Fill(vertices, 0, 8); - - // Shader - NzShaderRef shader = NzShader::New(); - shader->Create(); - shader->AttachStageFromSource(nzShaderStage_Fragment, fragmentShaderSource); - shader->AttachStageFromSource(nzShaderStage_Vertex, vertexShaderSource); - shader->Link(); - - shader->SendInteger(shader->GetUniformLocation("Skybox"), 0); - shader->SendFloat(shader->GetUniformLocation("VertexDepth"), 1.f); - - // Renderstates - s_renderStates.depthFunc = nzRendererComparison_Equal; - s_renderStates.faceCulling = nzFaceSide_Front; - s_renderStates.parameters[nzRendererParameter_DepthBuffer] = true; - s_renderStates.parameters[nzRendererParameter_DepthWrite] = false; - s_renderStates.parameters[nzRendererParameter_FaceCulling] = true; - - // Exception-free zone - s_indexBuffer = std::move(indexBuffer); - s_shader = std::move(shader); - s_vertexBuffer = std::move(vertexBuffer); - } - catch (const std::exception& e) - { - NazaraError("Failed to initialise: " + NzString(e.what())); - return false; + static IndexBufferRef s_indexBuffer; + static RenderStates s_renderStates; + static ShaderRef s_shader; + static VertexBufferRef s_vertexBuffer; } - return true; -} + SkyboxBackground::SkyboxBackground(TextureRef cubemapTexture) + { + m_sampler.SetWrapMode(SamplerWrap_Clamp); // Nécessaire pour ne pas voir les côtés -void NzSkyboxBackground::Uninitialize() -{ - s_indexBuffer.Reset(); - s_shader.Reset(); - s_vertexBuffer.Reset(); + SetTexture(std::move(cubemapTexture)); + } + + void SkyboxBackground::Draw(const AbstractViewer* viewer) const + { + Matrix4f skyboxMatrix(viewer->GetViewMatrix()); + skyboxMatrix.SetTranslation(Vector3f::Zero()); + + Renderer::SetIndexBuffer(s_indexBuffer); + Renderer::SetMatrix(MatrixType_View, skyboxMatrix); + Renderer::SetMatrix(MatrixType_World, Matrix4f::Scale(Vector3f(viewer->GetZNear()))); + Renderer::SetRenderStates(s_renderStates); + Renderer::SetShader(s_shader); + Renderer::SetTexture(0, m_texture); + Renderer::SetTextureSampler(0, m_sampler); + Renderer::SetVertexBuffer(s_vertexBuffer); + + Renderer::DrawIndexedPrimitives(PrimitiveMode_TriangleList, 0, 36); + + Renderer::SetMatrix(MatrixType_View, viewer->GetViewMatrix()); + } + + BackgroundType SkyboxBackground::GetBackgroundType() const + { + return BackgroundType_Skybox; + } + + bool SkyboxBackground::Initialize() + { + const UInt16 indices[6*6] = + { + 0, 1, 2, 0, 2, 3, + 3, 2, 6, 3, 6, 7, + 7, 6, 5, 7, 5, 4, + 4, 5, 1, 4, 1, 0, + 0, 3, 7, 0, 7, 4, + 1, 6, 2, 1, 5, 6 + }; + + const float vertices[8 * 3 * sizeof(float)] = + { + -1.0, 1.0, 1.0, + -1.0, -1.0, 1.0, + 1.0, -1.0, 1.0, + 1.0, 1.0, 1.0, + -1.0, 1.0, -1.0, + -1.0, -1.0, -1.0, + 1.0, -1.0, -1.0, + 1.0, 1.0, -1.0, + }; + + ///TODO: Replace by ShaderNode (probably after Vulkan) + const char* fragmentShaderSource = + "#version 140\n" + + "in vec3 vTexCoord;\n" + + "out vec4 RenderTarget0;\n" + + "uniform samplerCube Skybox;\n" + "uniform float VertexDepth;\n" + + "void main()\n" + "{\n" + " RenderTarget0 = texture(Skybox, vTexCoord);\n" + " gl_FragDepth = VertexDepth;\n" + "}\n"; + + const char* vertexShaderSource = + "#version 140\n" + + "in vec3 VertexPosition;\n" + + "out vec3 vTexCoord;\n" + + "uniform mat4 WorldViewProjMatrix;\n" + + "void main()\n" + "{\n" + " vec4 WVPVertex = WorldViewProjMatrix * vec4(VertexPosition, 1.0);\n" + " gl_Position = WVPVertex.xyww;\n" + " vTexCoord = vec3(VertexPosition.x, VertexPosition.y, -VertexPosition.z);\n" + "}\n"; + + try + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + + // Index buffer + IndexBufferRef indexBuffer = IndexBuffer::New(false, 36, DataStorage_Hardware, BufferUsage_Static); + indexBuffer->Fill(indices, 0, 36); + + // Vertex buffer + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ), 8, DataStorage_Hardware, BufferUsage_Static); + vertexBuffer->Fill(vertices, 0, 8); + + // Shader + ShaderRef shader = Shader::New(); + shader->Create(); + shader->AttachStageFromSource(ShaderStageType_Fragment, fragmentShaderSource); + shader->AttachStageFromSource(ShaderStageType_Vertex, vertexShaderSource); + shader->Link(); + + shader->SendInteger(shader->GetUniformLocation("Skybox"), 0); + shader->SendFloat(shader->GetUniformLocation("VertexDepth"), 1.f); + + // Renderstates + s_renderStates.depthFunc = RendererComparison_Equal; + s_renderStates.faceCulling = FaceSide_Front; + s_renderStates.parameters[RendererParameter_DepthBuffer] = true; + s_renderStates.parameters[RendererParameter_DepthWrite] = false; + s_renderStates.parameters[RendererParameter_FaceCulling] = true; + + // Exception-free zone + s_indexBuffer = std::move(indexBuffer); + s_shader = std::move(shader); + s_vertexBuffer = std::move(vertexBuffer); + } + catch (const std::exception& e) + { + NazaraError("Failed to initialise: " + String(e.what())); + return false; + } + + return true; + } + + void SkyboxBackground::Uninitialize() + { + s_indexBuffer.Reset(); + s_shader.Reset(); + s_vertexBuffer.Reset(); + } } diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index af4c5b89c..33a27d1a6 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -9,44 +9,47 @@ #include #include -void NzSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const +namespace Nz { - if (!m_material) - return; + void Sprite::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const + { + if (!m_material) + return; - const NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); - renderQueue->AddSprites(m_material, vertices, 1); + const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); + renderQueue->AddSprites(m_material, vertices, 1); + } + + void Sprite::MakeBoundingVolume() const + { + m_boundingVolume.Set(Vector3f(0.f), m_size.x*Vector3f::Right() + m_size.y*Vector3f::Down()); + } + + void Sprite::UpdateData(InstanceData* instanceData) const + { + instanceData->data.resize(4 * sizeof(VertexStruct_XYZ_Color_UV)); + VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData->data.data()); + + SparsePtr colorPtr(&vertices[0].color, sizeof(VertexStruct_XYZ_Color_UV)); + SparsePtr posPtr(&vertices[0].position, sizeof(VertexStruct_XYZ_Color_UV)); + SparsePtr texCoordPtr(&vertices[0].uv, sizeof(VertexStruct_XYZ_Color_UV)); + + *colorPtr++ = m_color; + *posPtr++ = instanceData->transformMatrix.Transform(Vector3f(0.f)); + *texCoordPtr++ = m_textureCoords.GetCorner(RectCorner_LeftTop); + + *colorPtr++ = m_color; + *posPtr++ = instanceData->transformMatrix.Transform(m_size.x*Vector3f::Right()); + *texCoordPtr++ = m_textureCoords.GetCorner(RectCorner_RightTop); + + *colorPtr++ = m_color; + *posPtr++ = instanceData->transformMatrix.Transform(m_size.y*Vector3f::Down()); + *texCoordPtr++ = m_textureCoords.GetCorner(RectCorner_LeftBottom); + + *colorPtr++ = m_color; + *posPtr++ = instanceData->transformMatrix.Transform(m_size.x*Vector3f::Right() + m_size.y*Vector3f::Down()); + *texCoordPtr++ = m_textureCoords.GetCorner(RectCorner_RightBottom); + } + + SpriteLibrary::LibraryMap Sprite::s_library; } - -void NzSprite::MakeBoundingVolume() const -{ - m_boundingVolume.Set(NzVector3f(0.f), m_size.x*NzVector3f::Right() + m_size.y*NzVector3f::Down()); -} - -void NzSprite::UpdateData(InstanceData* instanceData) const -{ - instanceData->data.resize(4 * sizeof(NzVertexStruct_XYZ_Color_UV)); - NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData->data.data()); - - NzSparsePtr colorPtr(&vertices[0].color, sizeof(NzVertexStruct_XYZ_Color_UV)); - NzSparsePtr posPtr(&vertices[0].position, sizeof(NzVertexStruct_XYZ_Color_UV)); - NzSparsePtr texCoordPtr(&vertices[0].uv, sizeof(NzVertexStruct_XYZ_Color_UV)); - - *colorPtr++ = m_color; - *posPtr++ = instanceData->transformMatrix.Transform(NzVector3f(0.f)); - *texCoordPtr++ = m_textureCoords.GetCorner(nzRectCorner_LeftTop); - - *colorPtr++ = m_color; - *posPtr++ = instanceData->transformMatrix.Transform(m_size.x*NzVector3f::Right()); - *texCoordPtr++ = m_textureCoords.GetCorner(nzRectCorner_RightTop); - - *colorPtr++ = m_color; - *posPtr++ = instanceData->transformMatrix.Transform(m_size.y*NzVector3f::Down()); - *texCoordPtr++ = m_textureCoords.GetCorner(nzRectCorner_LeftBottom); - - *colorPtr++ = m_color; - *posPtr++ = instanceData->transformMatrix.Transform(m_size.x*NzVector3f::Right() + m_size.y*NzVector3f::Down()); - *texCoordPtr++ = m_textureCoords.GetCorner(nzRectCorner_RightBottom); -} - -NzSpriteLibrary::LibraryMap NzSprite::s_library; diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index bcc318a55..820ed557a 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -11,230 +11,233 @@ #include #include -void NzTextSprite::AddToRenderQueue(NzAbstractRenderQueue* renderQueue, const InstanceData& instanceData) const +namespace Nz { - if (!m_material) - return; - - for (auto& pair : m_renderInfos) + void TextSprite::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const { - NzTexture* overlay = pair.first; - RenderIndices& indices = pair.second; + if (!m_material) + return; - if (indices.count > 0) + for (auto& pair : m_renderInfos) { - const NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); - renderQueue->AddSprites(m_material, &vertices[indices.first*4], indices.count, overlay); - } - } -} + Texture* overlay = pair.first; + RenderIndices& indices = pair.second; -void NzTextSprite::Update(const NzAbstractTextDrawer& drawer) -{ - m_atlases.clear(); - - NzCallOnExit clearOnFail([this]() - { - Clear(); - }); - - unsigned int fontCount = drawer.GetFontCount(); - for (unsigned int i = 0; i < fontCount; ++i) - { - NzFont* font = drawer.GetFont(i); - const NzAbstractAtlas* atlas = font->GetAtlas().get(); - NazaraAssert(atlas->GetStorage() & nzDataStorage_Hardware, "Font uses a non-hardware atlas which cannot be used by text sprites"); - - if (m_atlases.find(atlas) == m_atlases.end()) - { - AtlasSlots& slots = m_atlases[atlas]; - - slots.clearSlot.Connect(atlas->OnAtlasCleared, this, &NzTextSprite::OnAtlasInvalidated); - slots.layerChangeSlot.Connect(atlas->OnAtlasLayerChange, this, &NzTextSprite::OnAtlasLayerChange); - slots.releaseSlot.Connect(atlas->OnAtlasRelease, this, &NzTextSprite::OnAtlasInvalidated); - } - } - - unsigned int glyphCount = drawer.GetGlyphCount(); - m_localVertices.resize(glyphCount * 4); - - NzTexture* lastTexture = nullptr; - unsigned int* count = nullptr; - for (unsigned int i = 0; i < glyphCount; ++i) - { - const NzAbstractTextDrawer::Glyph& glyph = drawer.GetGlyph(i); - - NzTexture* texture = static_cast(glyph.atlas); - if (lastTexture != texture) - { - auto pair = m_renderInfos.insert(std::make_pair(texture, RenderIndices{0U, 0U})); - - count = &pair.first->second.count; - lastTexture = texture; - } - - (*count)++; - } - - // Attribution des indices - unsigned int index = 0; - for (auto& pair : m_renderInfos) - { - RenderIndices& indices = pair.second; - - indices.first = index; - - index += indices.count; - indices.count = 0; // On réinitialise count à zéro (on va s'en servir comme compteur dans la boucle suivante) - } - - lastTexture = nullptr; - RenderIndices* indices = nullptr; - for (unsigned int i = 0; i < glyphCount; ++i) - { - const NzAbstractTextDrawer::Glyph& glyph = drawer.GetGlyph(i); - - NzTexture* texture = static_cast(glyph.atlas); - if (lastTexture != texture) - { - indices = &m_renderInfos[texture]; // On a changé de texture, on ajuste le pointeur - lastTexture = texture; - } - - // On commence par transformer les coordonnées entières en flottantes: - NzVector2ui size(texture->GetSize()); - float invWidth = 1.f/size.x; - float invHeight = 1.f/size.y; - - NzRectf uvRect(glyph.atlasRect); - uvRect.x *= invWidth; - uvRect.y *= invHeight; - uvRect.width *= invWidth; - uvRect.height *= invHeight; - - static nzRectCorner normalCorners[4] = {nzRectCorner_LeftTop, nzRectCorner_RightTop, nzRectCorner_LeftBottom, nzRectCorner_RightBottom}; - static nzRectCorner flippedCorners[4] = {nzRectCorner_LeftBottom, nzRectCorner_LeftTop, nzRectCorner_RightBottom, nzRectCorner_RightTop}; - - // Affectation des positions, couleurs, coordonnées de textures - for (unsigned int j = 0; j < 4; ++j) - { - // Remember that indices->count is a counter here, not a count value - m_localVertices[indices->count*4 + j].color = glyph.color; - m_localVertices[indices->count*4 + j].position.Set(glyph.corners[j]); - m_localVertices[indices->count*4 + j].uv.Set(uvRect.GetCorner((glyph.flipped) ? flippedCorners[j] : normalCorners[j])); - } - - // Et on passe au prochain sommet - indices->count++; - } - - m_localBounds = drawer.GetBounds(); - - InvalidateBoundingVolume(); - InvalidateInstanceData(0); - - clearOnFail.Reset(); -} - -void NzTextSprite::MakeBoundingVolume() const -{ - NzRectf bounds(m_localBounds); - NzVector2f max = bounds.GetMaximum(); - NzVector2f min = bounds.GetMinimum(); - - m_boundingVolume.Set(min.x*NzVector3f::Right() + min.y*NzVector3f::Down(), max.x*NzVector3f::Right() + max.y*NzVector3f::Down()); -} - -void NzTextSprite::OnAtlasInvalidated(const NzAbstractAtlas* atlas) -{ - #ifdef NAZARA_DEBUG - if (m_atlases.find(atlas) == m_atlases.end()) - { - NazaraInternalError("Not listening to " + NzString::Pointer(atlas)); - return; - } - #endif - - NazaraWarning("TextSprite " + NzString::Pointer(this) + " has been cleared because atlas " + NzString::Pointer(atlas) + " has been invalidated (cleared or released)"); - Clear(); -} - -void NzTextSprite::OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer) -{ - NazaraUnused(atlas); - - #ifdef NAZARA_DEBUG - if (m_atlases.find(atlas) == m_atlases.end()) - { - NazaraInternalError("Not listening to " + NzString::Pointer(atlas)); - return; - } - #endif - - // La texture d'un atlas vient d'être recréée (changement de taille) - // nous devons ajuster les coordonnées de textures et la texture du rendu - NzTexture* oldTexture = static_cast(oldLayer); - NzTexture* newTexture = static_cast(newLayer); - - // Il est possible que nous n'utilisions pas la texture en question (l'atlas nous prévenant pour chacun de ses layers) - auto it = m_renderInfos.find(oldTexture); - if (it != m_renderInfos.end()) - { - // Nous utilisons bien cette texture, nous devons mettre à jour les coordonnées de texture - RenderIndices indices = std::move(it->second); - - NzVector2ui oldSize(oldTexture->GetSize()); - NzVector2ui newSize(newTexture->GetSize()); - NzVector2f scale = NzVector2f(oldSize)/NzVector2f(newSize); // ratio ancienne et nouvelle taille - - // On va maintenant parcourir toutes les coordonnées de texture concernées pour les multiplier par ce ratio - NzSparsePtr texCoordPtr(&m_localVertices[indices.first].uv, sizeof(NzVertexStruct_XYZ_Color_UV)); - for (unsigned int i = 0; i < indices.count; ++i) - { - for (unsigned int j = 0; j < 4; ++j) - m_localVertices[i*4 + j].uv *= scale; - } - - // Nous enlevons l'ancienne texture et rajoutons la nouvelle à sa place (pour les mêmes indices) - m_renderInfos.erase(it); - m_renderInfos.insert(std::make_pair(newTexture, std::move(indices))); - } -} - -void NzTextSprite::UpdateData(InstanceData* instanceData) const -{ - instanceData->data.resize(m_localVertices.size() * sizeof(NzVertexStruct_XYZ_Color_UV)); - NzVertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData->data.data()); - - NzSparsePtr colorPtr(&vertices[0].color, sizeof(NzVertexStruct_XYZ_Color_UV)); - NzSparsePtr posPtr(&vertices[0].position, sizeof(NzVertexStruct_XYZ_Color_UV)); - NzSparsePtr texCoordPtr(&vertices[0].uv, sizeof(NzVertexStruct_XYZ_Color_UV)); - - // Nous allons maintenant initialiser les sommets finaux (ceux envoyés à la RenderQueue) - // à l'aide du repère, de la matrice et de notre attribut de couleur - for (auto& pair : m_renderInfos) - { - RenderIndices& indices = pair.second; - - NzSparsePtr color = colorPtr + indices.first*4; - NzSparsePtr pos = posPtr + indices.first*4; - NzSparsePtr uv = texCoordPtr + indices.first*4; - NzVertexStruct_XY_Color_UV* localVertex = &m_localVertices[indices.first*4]; - for (unsigned int i = 0; i < indices.count; ++i) - { - for (unsigned int j = 0; j < 4; ++j) + if (indices.count > 0) { - NzVector3f localPos = localVertex->position.x*NzVector3f::Right() + localVertex->position.y*NzVector3f::Down(); - localPos *= m_scale; - - *pos++ = instanceData->transformMatrix.Transform(localPos); - *color++ = m_color * localVertex->color; - *uv++ = localVertex->uv; - - localVertex++; + const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); + renderQueue->AddSprites(m_material, &vertices[indices.first*4], indices.count, overlay); } } } -} -NzTextSpriteLibrary::LibraryMap NzTextSprite::s_library; + void TextSprite::Update(const AbstractTextDrawer& drawer) + { + m_atlases.clear(); + + CallOnExit clearOnFail([this]() + { + Clear(); + }); + + unsigned int fontCount = drawer.GetFontCount(); + for (unsigned int i = 0; i < fontCount; ++i) + { + Font* font = drawer.GetFont(i); + const AbstractAtlas* atlas = font->GetAtlas().get(); + NazaraAssert(atlas->GetStorage() & DataStorage_Hardware, "Font uses a non-hardware atlas which cannot be used by text sprites"); + + if (m_atlases.find(atlas) == m_atlases.end()) + { + AtlasSlots& slots = m_atlases[atlas]; + + slots.clearSlot.Connect(atlas->OnAtlasCleared, this, &TextSprite::OnAtlasInvalidated); + slots.layerChangeSlot.Connect(atlas->OnAtlasLayerChange, this, &TextSprite::OnAtlasLayerChange); + slots.releaseSlot.Connect(atlas->OnAtlasRelease, this, &TextSprite::OnAtlasInvalidated); + } + } + + unsigned int glyphCount = drawer.GetGlyphCount(); + m_localVertices.resize(glyphCount * 4); + + Texture* lastTexture = nullptr; + unsigned int* count = nullptr; + for (unsigned int i = 0; i < glyphCount; ++i) + { + const AbstractTextDrawer::Glyph& glyph = drawer.GetGlyph(i); + + Texture* texture = static_cast(glyph.atlas); + if (lastTexture != texture) + { + auto pair = m_renderInfos.insert(std::make_pair(texture, RenderIndices{0U, 0U})); + + count = &pair.first->second.count; + lastTexture = texture; + } + + (*count)++; + } + + // Attribution des indices + unsigned int index = 0; + for (auto& pair : m_renderInfos) + { + RenderIndices& indices = pair.second; + + indices.first = index; + + index += indices.count; + indices.count = 0; // On réinitialise count à zéro (on va s'en servir comme compteur dans la boucle suivante) + } + + lastTexture = nullptr; + RenderIndices* indices = nullptr; + for (unsigned int i = 0; i < glyphCount; ++i) + { + const AbstractTextDrawer::Glyph& glyph = drawer.GetGlyph(i); + + Texture* texture = static_cast(glyph.atlas); + if (lastTexture != texture) + { + indices = &m_renderInfos[texture]; // On a changé de texture, on ajuste le pointeur + lastTexture = texture; + } + + // On commence par transformer les coordonnées entières en flottantes: + Vector2ui size(texture->GetSize()); + float invWidth = 1.f/size.x; + float invHeight = 1.f/size.y; + + Rectf uvRect(glyph.atlasRect); + uvRect.x *= invWidth; + uvRect.y *= invHeight; + uvRect.width *= invWidth; + uvRect.height *= invHeight; + + static RectCorner normalCorners[4] = {RectCorner_LeftTop, RectCorner_RightTop, RectCorner_LeftBottom, RectCorner_RightBottom}; + static RectCorner flippedCorners[4] = {RectCorner_LeftBottom, RectCorner_LeftTop, RectCorner_RightBottom, RectCorner_RightTop}; + + // Affectation des positions, couleurs, coordonnées de textures + for (unsigned int j = 0; j < 4; ++j) + { + // Remember that indices->count is a counter here, not a count value + m_localVertices[indices->count*4 + j].color = glyph.color; + m_localVertices[indices->count*4 + j].position.Set(glyph.corners[j]); + m_localVertices[indices->count*4 + j].uv.Set(uvRect.GetCorner((glyph.flipped) ? flippedCorners[j] : normalCorners[j])); + } + + // Et on passe au prochain sommet + indices->count++; + } + + m_localBounds = drawer.GetBounds(); + + InvalidateBoundingVolume(); + InvalidateInstanceData(0); + + clearOnFail.Reset(); + } + + void TextSprite::MakeBoundingVolume() const + { + Rectf bounds(m_localBounds); + Vector2f max = bounds.GetMaximum(); + Vector2f min = bounds.GetMinimum(); + + m_boundingVolume.Set(min.x*Vector3f::Right() + min.y*Vector3f::Down(), max.x*Vector3f::Right() + max.y*Vector3f::Down()); + } + + void TextSprite::OnAtlasInvalidated(const AbstractAtlas* atlas) + { + #ifdef NAZARA_DEBUG + if (m_atlases.find(atlas) == m_atlases.end()) + { + NazaraInternalError("Not listening to " + String::Pointer(atlas)); + return; + } + #endif + + NazaraWarning("TextSprite " + String::Pointer(this) + " has been cleared because atlas " + String::Pointer(atlas) + " has been invalidated (cleared or released)"); + Clear(); + } + + void TextSprite::OnAtlasLayerChange(const AbstractAtlas* atlas, AbstractImage* oldLayer, AbstractImage* newLayer) + { + NazaraUnused(atlas); + + #ifdef NAZARA_DEBUG + if (m_atlases.find(atlas) == m_atlases.end()) + { + NazaraInternalError("Not listening to " + String::Pointer(atlas)); + return; + } + #endif + + // La texture d'un atlas vient d'être recréée (changement de taille) + // nous devons ajuster les coordonnées de textures et la texture du rendu + Texture* oldTexture = static_cast(oldLayer); + Texture* newTexture = static_cast(newLayer); + + // Il est possible que nous n'utilisions pas la texture en question (l'atlas nous prévenant pour chacun de ses layers) + auto it = m_renderInfos.find(oldTexture); + if (it != m_renderInfos.end()) + { + // Nous utilisons bien cette texture, nous devons mettre à jour les coordonnées de texture + RenderIndices indices = std::move(it->second); + + Vector2ui oldSize(oldTexture->GetSize()); + Vector2ui newSize(newTexture->GetSize()); + Vector2f scale = Vector2f(oldSize)/Vector2f(newSize); // ratio ancienne et nouvelle taille + + // On va maintenant parcourir toutes les coordonnées de texture concernées pour les multiplier par ce ratio + SparsePtr texCoordPtr(&m_localVertices[indices.first].uv, sizeof(VertexStruct_XYZ_Color_UV)); + for (unsigned int i = 0; i < indices.count; ++i) + { + for (unsigned int j = 0; j < 4; ++j) + m_localVertices[i*4 + j].uv *= scale; + } + + // Nous enlevons l'ancienne texture et rajoutons la nouvelle à sa place (pour les mêmes indices) + m_renderInfos.erase(it); + m_renderInfos.insert(std::make_pair(newTexture, std::move(indices))); + } + } + + void TextSprite::UpdateData(InstanceData* instanceData) const + { + instanceData->data.resize(m_localVertices.size() * sizeof(VertexStruct_XYZ_Color_UV)); + VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData->data.data()); + + SparsePtr colorPtr(&vertices[0].color, sizeof(VertexStruct_XYZ_Color_UV)); + SparsePtr posPtr(&vertices[0].position, sizeof(VertexStruct_XYZ_Color_UV)); + SparsePtr texCoordPtr(&vertices[0].uv, sizeof(VertexStruct_XYZ_Color_UV)); + + // Nous allons maintenant initialiser les sommets finaux (ceux envoyés à la RenderQueue) + // à l'aide du repère, de la matrice et de notre attribut de couleur + for (auto& pair : m_renderInfos) + { + RenderIndices& indices = pair.second; + + SparsePtr color = colorPtr + indices.first*4; + SparsePtr pos = posPtr + indices.first*4; + SparsePtr uv = texCoordPtr + indices.first*4; + VertexStruct_XY_Color_UV* localVertex = &m_localVertices[indices.first*4]; + for (unsigned int i = 0; i < indices.count; ++i) + { + for (unsigned int j = 0; j < 4; ++j) + { + Vector3f localPos = localVertex->position.x*Vector3f::Right() + localVertex->position.y*Vector3f::Down(); + localPos *= m_scale; + + *pos++ = instanceData->transformMatrix.Transform(localPos); + *color++ = m_color * localVertex->color; + *uv++ = localVertex->uv; + + localVertex++; + } + } + } + } + + TextSpriteLibrary::LibraryMap TextSprite::s_library; +} diff --git a/src/Nazara/Graphics/TextureBackground.cpp b/src/Nazara/Graphics/TextureBackground.cpp index d1784b078..9ceb633e6 100644 --- a/src/Nazara/Graphics/TextureBackground.cpp +++ b/src/Nazara/Graphics/TextureBackground.cpp @@ -7,60 +7,63 @@ #include #include -namespace +namespace Nz { - NzRenderStates BuildRenderStates() + namespace { - NzRenderStates states; - states.depthFunc = nzRendererComparison_Equal; - states.faceCulling = nzFaceSide_Back; - states.parameters[nzRendererParameter_DepthBuffer] = true; - states.parameters[nzRendererParameter_DepthWrite] = false; - states.parameters[nzRendererParameter_FaceCulling] = true; + RenderStates BuildRenderStates() + { + RenderStates states; + states.depthFunc = RendererComparison_Equal; + states.faceCulling = FaceSide_Back; + states.parameters[RendererParameter_DepthBuffer] = true; + states.parameters[RendererParameter_DepthWrite] = false; + states.parameters[RendererParameter_FaceCulling] = true; - return states; + return states; + } + } + + TextureBackground::TextureBackground(TextureRef texture) + { + m_uberShader = UberShaderLibrary::Get("Basic"); + + ParameterList list; + list.SetParameter("DIFFUSE_MAPPING", true); + list.SetParameter("TEXTURE_MAPPING", true); + list.SetParameter("UNIFORM_VERTEX_DEPTH", true); + + m_uberShaderInstance = m_uberShader->Get(list); + + const Shader* shader = m_uberShaderInstance->GetShader(); + m_materialDiffuseUniform = shader->GetUniformLocation("MaterialDiffuse"); + m_materialDiffuseMapUniform = shader->GetUniformLocation("MaterialDiffuseMap"); + m_vertexDepthUniform = shader->GetUniformLocation("VertexDepth"); + + SetTexture(std::move(texture)); + } + + void TextureBackground::Draw(const AbstractViewer* viewer) const + { + NazaraUnused(viewer); + + static RenderStates states(BuildRenderStates()); + + Renderer::SetRenderStates(states); + Renderer::SetTexture(0, m_texture); + + m_uberShaderInstance->Activate(); + + const Shader* shader = m_uberShaderInstance->GetShader(); + shader->SendColor(m_materialDiffuseUniform, Color::White); + shader->SendFloat(m_vertexDepthUniform, 1.f); + shader->SendInteger(m_materialDiffuseMapUniform, 0); + + Renderer::DrawFullscreenQuad(); + } + + BackgroundType TextureBackground::GetBackgroundType() const + { + return BackgroundType_Texture; } } - -NzTextureBackground::NzTextureBackground(NzTextureRef texture) -{ - m_uberShader = NzUberShaderLibrary::Get("Basic"); - - NzParameterList list; - list.SetParameter("DIFFUSE_MAPPING", true); - list.SetParameter("TEXTURE_MAPPING", true); - list.SetParameter("UNIFORM_VERTEX_DEPTH", true); - - m_uberShaderInstance = m_uberShader->Get(list); - - const NzShader* shader = m_uberShaderInstance->GetShader(); - m_materialDiffuseUniform = shader->GetUniformLocation("MaterialDiffuse"); - m_materialDiffuseMapUniform = shader->GetUniformLocation("MaterialDiffuseMap"); - m_vertexDepthUniform = shader->GetUniformLocation("VertexDepth"); - - SetTexture(std::move(texture)); -} - -void NzTextureBackground::Draw(const NzAbstractViewer* viewer) const -{ - NazaraUnused(viewer); - - static NzRenderStates states(BuildRenderStates()); - - NzRenderer::SetRenderStates(states); - NzRenderer::SetTexture(0, m_texture); - - m_uberShaderInstance->Activate(); - - const NzShader* shader = m_uberShaderInstance->GetShader(); - shader->SendColor(m_materialDiffuseUniform, NzColor::White); - shader->SendFloat(m_vertexDepthUniform, 1.f); - shader->SendInteger(m_materialDiffuseMapUniform, 0); - - NzRenderer::DrawFullscreenQuad(); -} - -nzBackgroundType NzTextureBackground::GetBackgroundType() const -{ - return nzBackgroundType_Texture; -} diff --git a/src/Nazara/Lua/Lua.cpp b/src/Nazara/Lua/Lua.cpp index 5ea40b97d..9b53443e7 100644 --- a/src/Nazara/Lua/Lua.cpp +++ b/src/Nazara/Lua/Lua.cpp @@ -9,52 +9,55 @@ #include #include -bool NzLua::Initialize() +namespace Nz { - if (s_moduleReferenceCounter > 0) + bool Lua::Initialize() { + if (s_moduleReferenceCounter > 0) + { + s_moduleReferenceCounter++; + return true; // Déjà initialisé + } + + // Initialisation des dépendances + if (!Core::Initialize()) + { + NazaraError("Failed to initialize core module"); + return false; + } + s_moduleReferenceCounter++; - return true; // Déjà initialisé + + // Initialisation du module + + NazaraNotice("Initialized: Lua module"); + return true; } - // Initialisation des dépendances - if (!NzCore::Initialize()) + bool Lua::IsInitialized() { - NazaraError("Failed to initialize core module"); - return false; + return s_moduleReferenceCounter != 0; } - s_moduleReferenceCounter++; - - // Initialisation du module - - NazaraNotice("Initialized: Lua module"); - return true; -} - -bool NzLua::IsInitialized() -{ - return s_moduleReferenceCounter != 0; -} - -void NzLua::Uninitialize() -{ - if (s_moduleReferenceCounter != 1) + void Lua::Uninitialize() { - // Le module est soit encore utilisé, soit pas initialisé - if (s_moduleReferenceCounter > 1) - s_moduleReferenceCounter--; + if (s_moduleReferenceCounter != 1) + { + // Le module est soit encore utilisé, soit pas initialisé + if (s_moduleReferenceCounter > 1) + s_moduleReferenceCounter--; - return; + return; + } + + // Libération du module + s_moduleReferenceCounter = 0; + + NazaraNotice("Uninitialized: Lua module"); + + // Libération des dépendances + Core::Uninitialize(); } - // Libération du module - s_moduleReferenceCounter = 0; - - NazaraNotice("Uninitialized: Lua module"); - - // Libération des dépendances - NzCore::Uninitialize(); + unsigned int Lua::s_moduleReferenceCounter = 0; } - -unsigned int NzLua::s_moduleReferenceCounter = 0; diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp index fe8c3583b..48d3988c9 100644 --- a/src/Nazara/Lua/LuaInstance.cpp +++ b/src/Nazara/Lua/LuaInstance.cpp @@ -17,886 +17,889 @@ #include #include -namespace +namespace Nz { - nzLuaType FromLuaType(int type) + namespace + { + nzLuaType FromLuaType(int type) + { + switch (type) + { + case LUA_TBOOLEAN: + return nzLuaType_Boolean; + + case LUA_TFUNCTION: + return nzLuaType_Function; + + case LUA_TLIGHTUSERDATA: + return nzLuaType_LightUserdata; + + case LUA_TNIL: + return nzLuaType_Nil; + + case LUA_TNONE: + return nzLuaType_None; + + case LUA_TNUMBER: + return nzLuaType_Number; + + case LUA_TSTRING: + return nzLuaType_String; + + case LUA_TTABLE: + return nzLuaType_Table; + + case LUA_TTHREAD: + return nzLuaType_Thread; + + case LUA_TUSERDATA: + return nzLuaType_Userdata; + + default: + return nzLuaType_None; + } + } + + struct StreamData + { + InputStream* stream; + char buffer[NAZARA_CORE_FILE_BUFFERSIZE]; + }; + + int AtPanic(lua_State* state) + { + String lastError(lua_tostring(state, -1)); + + throw std::runtime_error("Lua panic: " + lastError); + } + + const char* StreamReader(lua_State* state, void* data, std::size_t* size) + { + NazaraUnused(state); + + StreamData* streamData = static_cast(data); + + if (streamData->stream->EndOfStream()) + return nullptr; + else + { + *size = streamData->stream->Read(streamData->buffer, NAZARA_CORE_FILE_BUFFERSIZE); + return streamData->buffer; + } + } + + int s_comparisons[] = { + LUA_OPEQ, // nzLuaComparison_Equality + LUA_OPLT, // nzLuaComparison_Less + LUA_OPLE // nzLuaComparison_LessOrEqual + }; + + static_assert(sizeof(s_comparisons)/sizeof(int) == nzLuaComparison_Max+1, "Lua comparison array is incomplete"); + + int s_operations[] = { + LUA_OPADD, // nzLuaOperation_Addition + LUA_OPBAND, // nzLuaOperation_BitwiseAnd + LUA_OPSHL, // nzLuaOperation_BitwiseLeftShift + LUA_OPBNOT, // nzLuaOperation_BitwiseNot + LUA_OPBOR, // nzLuaOperation_BitwiseOr + LUA_OPSHR, // nzLuaOperation_BitwiseRightShift + LUA_OPBXOR, // nzLuaOperation_BitwiseXOr + LUA_OPDIV, // nzLuaOperation_Division + LUA_OPPOW, // nzLuaOperation_Exponentiation + LUA_OPIDIV, // nzLuaOperation_FloorDivision + LUA_OPMUL, // nzLuaOperation_Multiplication + LUA_OPMOD, // nzLuaOperation_Modulo + LUA_OPUNM, // nzLuaOperation_Negation + LUA_OPSUB // nzLuaOperation_Substraction + }; + + static_assert(sizeof(s_operations)/sizeof(int) == nzLuaOperation_Max+1, "Lua operation array is incomplete"); + + int s_types[] = { + LUA_TBOOLEAN, // nzLuaType_Boolean + LUA_TFUNCTION, // nzLuaType_Function + LUA_TLIGHTUSERDATA, // nzLuaType_LightUserdata + LUA_TNIL, // nzLuaType_Nil + LUA_TNUMBER, // nzLuaType_Number + LUA_TNONE, // nzLuaType_None + LUA_TSTRING, // nzLuaType_String + LUA_TTABLE, // nzLuaType_Table + LUA_TTHREAD, // nzLuaType_Thread + LUA_TUSERDATA // nzLuaType_Userdata + }; + + static_assert(sizeof(s_types)/sizeof(int) == nzLuaType_Max+1, "Lua type array is incomplete"); + } + + LuaInstance::LuaInstance() : + m_memoryLimit(0), + m_memoryUsage(0), + m_timeLimit(1000), + m_level(0) + { + m_state = lua_newstate(MemoryAllocator, this); + lua_atpanic(m_state, AtPanic); + lua_sethook(m_state, TimeLimiter, LUA_MASKCOUNT, 1000); + luaL_openlibs(m_state); + } + + LuaInstance::~LuaInstance() + { + lua_close(m_state); + } + + void LuaInstance::ArgCheck(bool condition, unsigned int argNum, const char* error) + { + luaL_argcheck(m_state, condition, argNum, error); + } + + void LuaInstance::ArgCheck(bool condition, unsigned int argNum, const String& error) + { + luaL_argcheck(m_state, condition, argNum, error.GetConstBuffer()); + } + + int LuaInstance::ArgError(unsigned int argNum, const char* error) + { + return luaL_argerror(m_state, argNum, error); + } + + int LuaInstance::ArgError(unsigned int argNum, const String& error) + { + return luaL_argerror(m_state, argNum, error.GetConstBuffer()); + } + + bool LuaInstance::Call(unsigned int argCount) + { + return Run(argCount, LUA_MULTRET); + } + + bool LuaInstance::Call(unsigned int argCount, unsigned int resultCount) + { + return Run(argCount, resultCount); + } + + void LuaInstance::CheckAny(int index) const + { + luaL_checkany(m_state, index); + } + + bool LuaInstance::CheckBoolean(int index) const + { + if (lua_isnoneornil(m_state, index)) + { + const char* msg = lua_pushfstring(m_state, "%s expected, got %s", lua_typename(m_state, LUA_TBOOLEAN), luaL_typename(m_state, index)); + luaL_argerror(m_state, index, msg); // Lance une exception + return false; + } + + return lua_toboolean(m_state, index) != 0; + } + + bool LuaInstance::CheckBoolean(int index, bool defValue) const + { + if (lua_isnoneornil(m_state, index)) + return defValue; + + return lua_toboolean(m_state, index) != 0; + } + + long long LuaInstance::CheckInteger(int index) const + { + return luaL_checkinteger(m_state, index); + } + + long long LuaInstance::CheckInteger(int index, long long defValue) const + { + return luaL_optinteger(m_state, index, defValue); + } + + double LuaInstance::CheckNumber(int index) const + { + return luaL_checknumber(m_state, index); + } + + double LuaInstance::CheckNumber(int index, double defValue) const + { + return luaL_optnumber(m_state, index, defValue); + } + + void LuaInstance::CheckStack(int space, const char* error) const + { + luaL_checkstack(m_state, space, error); + } + + void LuaInstance::CheckStack(int space, const String& error) const + { + CheckStack(space, error.GetConstBuffer()); + } + + const char* LuaInstance::CheckString(int index, std::size_t* length) const + { + return luaL_checklstring(m_state, index, length); + } + + const char* LuaInstance::CheckString(int index, const char* defValue, std::size_t* length) const + { + return luaL_optlstring(m_state, index, defValue, length); + } + + void LuaInstance::CheckType(int index, nzLuaType type) const + { + #ifdef NAZARA_DEBUG + if (type > nzLuaType_Max) + { + NazaraError("Lua type out of enum"); + return; + } + #endif + + luaL_checktype(m_state, index, s_types[type]); + } + + void* LuaInstance::CheckUserdata(int index, const char* tname) const + { + return luaL_checkudata(m_state, index, tname); + } + + void* LuaInstance::CheckUserdata(int index, const String& tname) const + { + return luaL_checkudata(m_state, index, tname.GetConstBuffer()); + } + + bool LuaInstance::Compare(int index1, int index2, nzLuaComparison comparison) const + { + #ifdef NAZARA_DEBUG + if (comparison > nzLuaComparison_Max) + { + NazaraError("Lua comparison out of enum"); + return false; + } + #endif + + return (lua_compare(m_state, index1, index2, s_comparisons[comparison]) != 0); + } + + void LuaInstance::Compute(nzLuaOperation operation) + { + #ifdef NAZARA_DEBUG + if (operation > nzLuaOperation_Max) + { + NazaraError("Lua operation out of enum"); + return; + } + #endif + + lua_arith(m_state, s_operations[operation]); + } + + void LuaInstance::Concatenate(int count) + { + lua_concat(m_state, count); + } + + int LuaInstance::CreateReference() + { + return luaL_ref(m_state, LUA_REGISTRYINDEX); + } + + void LuaInstance::DestroyReference(int ref) + { + luaL_unref(m_state, LUA_REGISTRYINDEX, ref); + } + + String LuaInstance::DumpStack() const + { + StringStream stream; + unsigned int stackTop = GetStackTop(); + stream << stackTop << " entries\n"; + + for (unsigned int i = 1; i <= stackTop; ++i) + { + stream << i << ": "; + switch (GetType(i)) + { + case nzLuaType_Boolean: + stream << "Boolean(" << ToBoolean(i) << ')'; + break; + + case nzLuaType_Function: + stream << "Function(" << ToPointer(i) << ')'; + break; + + case nzLuaType_LightUserdata: + case nzLuaType_Userdata: + stream << "Userdata(" << ToUserdata(i) << ')'; + break; + + case nzLuaType_Nil: + stream << "Nil"; + break; + + case nzLuaType_None: + stream << "None"; + break; + + case nzLuaType_Number: + stream << "Number(" << ToNumber(i) << ')'; + break; + + case nzLuaType_String: + stream << "String(" << ToString(i) << ')'; + break; + + case nzLuaType_Table: + stream << "Table(" << ToPointer(i) << ')'; + break; + + case nzLuaType_Thread: + stream << "Thread(" << ToPointer(i) << ')'; + break; + + default: + stream << "Unknown(" << ToPointer(i) << ')'; + break; + } + + stream << '\n'; + } + + return stream.ToString(); + } + + void LuaInstance::Error(const char* message) + { + luaL_error(m_state, message); + } + + void LuaInstance::Error(const String& message) + { + luaL_error(m_state, message.GetConstBuffer()); + } + + bool LuaInstance::Execute(const String& code) + { + if (code.IsEmpty()) + return true; + + if (luaL_loadstring(m_state, code.GetConstBuffer()) != 0) + { + m_lastError = lua_tostring(m_state, -1); + lua_pop(m_state, 1); + + return false; + } + + return Run(0, 0); + } + + bool LuaInstance::ExecuteFromFile(const String& filePath) + { + File file(filePath); + if (!file.Open(OpenMode_ReadOnly | OpenMode_Text)) + { + NazaraError("Failed to open file"); + return false; + } + + unsigned int length = static_cast(file.GetSize()); + + String source(length, '\0'); + + if (file.Read(&source[0], length) != length) + { + NazaraError("Failed to read file"); + return false; + } + + file.Close(); + + return Execute(source); + } + + bool LuaInstance::ExecuteFromMemory(const void* data, unsigned int size) + { + MemoryStream stream(data, size); + return ExecuteFromStream(stream); + } + + bool LuaInstance::ExecuteFromStream(InputStream& stream) + { + StreamData data; + data.stream = &stream; + + if (lua_load(m_state, StreamReader, &data, "C++", nullptr) != 0) + { + m_lastError = lua_tostring(m_state, -1); + lua_pop(m_state, 1); + + return false; + } + + return Run(0, 0); + } + + int LuaInstance::GetAbsIndex(int index) const + { + return lua_absindex(m_state, index); + } + + nzLuaType LuaInstance::GetField(const char* fieldName, int index) const + { + return FromLuaType(lua_getfield(m_state, index, fieldName)); + } + + nzLuaType LuaInstance::GetField(const String& fieldName, int index) const + { + return FromLuaType(lua_getfield(m_state, index, fieldName.GetConstBuffer())); + } + + nzLuaType LuaInstance::GetGlobal(const char* name) const + { + return FromLuaType(lua_getglobal(m_state, name)); + } + + nzLuaType LuaInstance::GetGlobal(const String& name) const + { + return FromLuaType(lua_getglobal(m_state, name.GetConstBuffer())); + } + + lua_State* LuaInstance::GetInternalState() const + { + return m_state; + } + + String LuaInstance::GetLastError() const + { + return m_lastError; + } + + UInt32 LuaInstance::GetMemoryLimit() const + { + return m_memoryLimit; + } + + UInt32 LuaInstance::GetMemoryUsage() const + { + return m_memoryUsage; + } + + nzLuaType LuaInstance::GetMetatable(const char* tname) const + { + return FromLuaType(luaL_getmetatable(m_state, tname)); + } + + nzLuaType LuaInstance::GetMetatable(const String& tname) const + { + return FromLuaType(luaL_getmetatable(m_state, tname.GetConstBuffer())); + } + + bool LuaInstance::GetMetatable(int index) const + { + return lua_getmetatable(m_state, index) != 0; + } + + unsigned int LuaInstance::GetStackTop() const + { + return lua_gettop(m_state); + } + + nzLuaType LuaInstance::GetTable(int index) const + { + return FromLuaType(lua_gettable(m_state, index)); + } + + UInt32 LuaInstance::GetTimeLimit() const + { + return m_timeLimit; + } + + nzLuaType LuaInstance::GetType(int index) const + { + return FromLuaType(lua_type(m_state, index)); + } + + const char* LuaInstance::GetTypeName(nzLuaType type) const + { + #ifdef NAZARA_DEBUG + if (type > nzLuaType_Max) + { + NazaraError("Lua type out of enum"); + return nullptr; + } + #endif + + return lua_typename(m_state, s_types[type]); + } + + void LuaInstance::Insert(int index) + { + lua_insert(m_state, index); + } + + bool LuaInstance::IsOfType(int index, nzLuaType type) const { switch (type) - { - case LUA_TBOOLEAN: - return nzLuaType_Boolean; - - case LUA_TFUNCTION: - return nzLuaType_Function; - - case LUA_TLIGHTUSERDATA: - return nzLuaType_LightUserdata; - - case LUA_TNIL: - return nzLuaType_Nil; - - case LUA_TNONE: - return nzLuaType_None; - - case LUA_TNUMBER: - return nzLuaType_Number; - - case LUA_TSTRING: - return nzLuaType_String; - - case LUA_TTABLE: - return nzLuaType_Table; - - case LUA_TTHREAD: - return nzLuaType_Thread; - - case LUA_TUSERDATA: - return nzLuaType_Userdata; - - default: - return nzLuaType_None; - } - } - - struct StreamData - { - NzInputStream* stream; - char buffer[NAZARA_CORE_FILE_BUFFERSIZE]; - }; - - int AtPanic(lua_State* state) - { - NzString lastError(lua_tostring(state, -1)); - - throw std::runtime_error("Lua panic: " + lastError); - } - - const char* StreamReader(lua_State* state, void* data, std::size_t* size) - { - NazaraUnused(state); - - StreamData* streamData = static_cast(data); - - if (streamData->stream->EndOfStream()) - return nullptr; - else - { - *size = streamData->stream->Read(streamData->buffer, NAZARA_CORE_FILE_BUFFERSIZE); - return streamData->buffer; - } - } - - int s_comparisons[] = { - LUA_OPEQ, // nzLuaComparison_Equality - LUA_OPLT, // nzLuaComparison_Less - LUA_OPLE // nzLuaComparison_LessOrEqual - }; - - static_assert(sizeof(s_comparisons)/sizeof(int) == nzLuaComparison_Max+1, "Lua comparison array is incomplete"); - - int s_operations[] = { - LUA_OPADD, // nzLuaOperation_Addition - LUA_OPBAND, // nzLuaOperation_BitwiseAnd - LUA_OPSHL, // nzLuaOperation_BitwiseLeftShift - LUA_OPBNOT, // nzLuaOperation_BitwiseNot - LUA_OPBOR, // nzLuaOperation_BitwiseOr - LUA_OPSHR, // nzLuaOperation_BitwiseRightShift - LUA_OPBXOR, // nzLuaOperation_BitwiseXOr - LUA_OPDIV, // nzLuaOperation_Division - LUA_OPPOW, // nzLuaOperation_Exponentiation - LUA_OPIDIV, // nzLuaOperation_FloorDivision - LUA_OPMUL, // nzLuaOperation_Multiplication - LUA_OPMOD, // nzLuaOperation_Modulo - LUA_OPUNM, // nzLuaOperation_Negation - LUA_OPSUB // nzLuaOperation_Substraction - }; - - static_assert(sizeof(s_operations)/sizeof(int) == nzLuaOperation_Max+1, "Lua operation array is incomplete"); - - int s_types[] = { - LUA_TBOOLEAN, // nzLuaType_Boolean - LUA_TFUNCTION, // nzLuaType_Function - LUA_TLIGHTUSERDATA, // nzLuaType_LightUserdata - LUA_TNIL, // nzLuaType_Nil - LUA_TNUMBER, // nzLuaType_Number - LUA_TNONE, // nzLuaType_None - LUA_TSTRING, // nzLuaType_String - LUA_TTABLE, // nzLuaType_Table - LUA_TTHREAD, // nzLuaType_Thread - LUA_TUSERDATA // nzLuaType_Userdata - }; - - static_assert(sizeof(s_types)/sizeof(int) == nzLuaType_Max+1, "Lua type array is incomplete"); -} - -NzLuaInstance::NzLuaInstance() : -m_memoryLimit(0), -m_memoryUsage(0), -m_timeLimit(1000), -m_level(0) -{ - m_state = lua_newstate(MemoryAllocator, this); - lua_atpanic(m_state, AtPanic); - lua_sethook(m_state, TimeLimiter, LUA_MASKCOUNT, 1000); - luaL_openlibs(m_state); -} - -NzLuaInstance::~NzLuaInstance() -{ - lua_close(m_state); -} - -void NzLuaInstance::ArgCheck(bool condition, unsigned int argNum, const char* error) -{ - luaL_argcheck(m_state, condition, argNum, error); -} - -void NzLuaInstance::ArgCheck(bool condition, unsigned int argNum, const NzString& error) -{ - luaL_argcheck(m_state, condition, argNum, error.GetConstBuffer()); -} - -int NzLuaInstance::ArgError(unsigned int argNum, const char* error) -{ - return luaL_argerror(m_state, argNum, error); -} - -int NzLuaInstance::ArgError(unsigned int argNum, const NzString& error) -{ - return luaL_argerror(m_state, argNum, error.GetConstBuffer()); -} - -bool NzLuaInstance::Call(unsigned int argCount) -{ - return Run(argCount, LUA_MULTRET); -} - -bool NzLuaInstance::Call(unsigned int argCount, unsigned int resultCount) -{ - return Run(argCount, resultCount); -} - -void NzLuaInstance::CheckAny(int index) const -{ - luaL_checkany(m_state, index); -} - -bool NzLuaInstance::CheckBoolean(int index) const -{ - if (lua_isnoneornil(m_state, index)) - { - const char* msg = lua_pushfstring(m_state, "%s expected, got %s", lua_typename(m_state, LUA_TBOOLEAN), luaL_typename(m_state, index)); - luaL_argerror(m_state, index, msg); // Lance une exception - return false; - } - - return lua_toboolean(m_state, index) != 0; -} - -bool NzLuaInstance::CheckBoolean(int index, bool defValue) const -{ - if (lua_isnoneornil(m_state, index)) - return defValue; - - return lua_toboolean(m_state, index) != 0; -} - -long long NzLuaInstance::CheckInteger(int index) const -{ - return luaL_checkinteger(m_state, index); -} - -long long NzLuaInstance::CheckInteger(int index, long long defValue) const -{ - return luaL_optinteger(m_state, index, defValue); -} - -double NzLuaInstance::CheckNumber(int index) const -{ - return luaL_checknumber(m_state, index); -} - -double NzLuaInstance::CheckNumber(int index, double defValue) const -{ - return luaL_optnumber(m_state, index, defValue); -} - -void NzLuaInstance::CheckStack(int space, const char* error) const -{ - luaL_checkstack(m_state, space, error); -} - -void NzLuaInstance::CheckStack(int space, const NzString& error) const -{ - CheckStack(space, error.GetConstBuffer()); -} - -const char* NzLuaInstance::CheckString(int index, std::size_t* length) const -{ - return luaL_checklstring(m_state, index, length); -} - -const char* NzLuaInstance::CheckString(int index, const char* defValue, std::size_t* length) const -{ - return luaL_optlstring(m_state, index, defValue, length); -} - -void NzLuaInstance::CheckType(int index, nzLuaType type) const -{ - #ifdef NAZARA_DEBUG - if (type > nzLuaType_Max) - { - NazaraError("Lua type out of enum"); - return; - } - #endif - - luaL_checktype(m_state, index, s_types[type]); -} - -void* NzLuaInstance::CheckUserdata(int index, const char* tname) const -{ - return luaL_checkudata(m_state, index, tname); -} - -void* NzLuaInstance::CheckUserdata(int index, const NzString& tname) const -{ - return luaL_checkudata(m_state, index, tname.GetConstBuffer()); -} - -bool NzLuaInstance::Compare(int index1, int index2, nzLuaComparison comparison) const -{ - #ifdef NAZARA_DEBUG - if (comparison > nzLuaComparison_Max) - { - NazaraError("Lua comparison out of enum"); - return false; - } - #endif - - return (lua_compare(m_state, index1, index2, s_comparisons[comparison]) != 0); -} - -void NzLuaInstance::Compute(nzLuaOperation operation) -{ - #ifdef NAZARA_DEBUG - if (operation > nzLuaOperation_Max) - { - NazaraError("Lua operation out of enum"); - return; - } - #endif - - lua_arith(m_state, s_operations[operation]); -} - -void NzLuaInstance::Concatenate(int count) -{ - lua_concat(m_state, count); -} - -int NzLuaInstance::CreateReference() -{ - return luaL_ref(m_state, LUA_REGISTRYINDEX); -} - -void NzLuaInstance::DestroyReference(int ref) -{ - luaL_unref(m_state, LUA_REGISTRYINDEX, ref); -} - -NzString NzLuaInstance::DumpStack() const -{ - NzStringStream stream; - unsigned int stackTop = GetStackTop(); - stream << stackTop << " entries\n"; - - for (unsigned int i = 1; i <= stackTop; ++i) - { - stream << i << ": "; - switch (GetType(i)) { case nzLuaType_Boolean: - stream << "Boolean(" << ToBoolean(i) << ')'; - break; + return lua_isboolean(m_state, index) != 0; case nzLuaType_Function: - stream << "Function(" << ToPointer(i) << ')'; - break; + return lua_isfunction(m_state, index) != 0; case nzLuaType_LightUserdata: - case nzLuaType_Userdata: - stream << "Userdata(" << ToUserdata(i) << ')'; - break; + return lua_islightuserdata(m_state, index) != 0; case nzLuaType_Nil: - stream << "Nil"; - break; + return lua_isnil(m_state, index) != 0; case nzLuaType_None: - stream << "None"; - break; + return lua_isnone(m_state, index) != 0; case nzLuaType_Number: - stream << "Number(" << ToNumber(i) << ')'; - break; + return lua_isnumber(m_state, index) != 0; case nzLuaType_String: - stream << "String(" << ToString(i) << ')'; - break; + return lua_isstring(m_state, index) != 0; case nzLuaType_Table: - stream << "Table(" << ToPointer(i) << ')'; - break; + return lua_istable(m_state, index) != 0; case nzLuaType_Thread: - stream << "Thread(" << ToPointer(i) << ')'; - break; + return lua_isthread(m_state, index) != 0; - default: - stream << "Unknown(" << ToPointer(i) << ')'; - break; + case nzLuaType_Userdata: + return lua_isuserdata(m_state, index) != 0; } - stream << '\n'; - } - - return stream.ToString(); -} - -void NzLuaInstance::Error(const char* message) -{ - luaL_error(m_state, message); -} - -void NzLuaInstance::Error(const NzString& message) -{ - luaL_error(m_state, message.GetConstBuffer()); -} - -bool NzLuaInstance::Execute(const NzString& code) -{ - if (code.IsEmpty()) - return true; - - if (luaL_loadstring(m_state, code.GetConstBuffer()) != 0) - { - m_lastError = lua_tostring(m_state, -1); - lua_pop(m_state, 1); - + NazaraError("Lua type not handled (0x" + String::Number(type, 16) + ')'); return false; } - return Run(0, 0); -} - -bool NzLuaInstance::ExecuteFromFile(const NzString& filePath) -{ - NzFile file(filePath); - if (!file.Open(nzOpenMode_ReadOnly | nzOpenMode_Text)) + bool LuaInstance::IsOfType(int index, const char* tname) const { - NazaraError("Failed to open file"); - return false; + void* ud = luaL_testudata(m_state, index, tname); + return ud != nullptr; } - unsigned int length = static_cast(file.GetSize()); - - NzString source(length, '\0'); - - if (file.Read(&source[0], length) != length) + bool LuaInstance::IsOfType(int index, const String& tname) const { - NazaraError("Failed to read file"); - return false; + return IsOfType(index, tname.GetConstBuffer()); } - file.Close(); - - return Execute(source); -} - -bool NzLuaInstance::ExecuteFromMemory(const void* data, unsigned int size) -{ - NzMemoryStream stream(data, size); - return ExecuteFromStream(stream); -} - -bool NzLuaInstance::ExecuteFromStream(NzInputStream& stream) -{ - StreamData data; - data.stream = &stream; - - if (lua_load(m_state, StreamReader, &data, "C++", nullptr) != 0) + bool LuaInstance::IsValid(int index) const { - m_lastError = lua_tostring(m_state, -1); - lua_pop(m_state, 1); - - return false; + return lua_isnoneornil(m_state, index) == 0; } - return Run(0, 0); -} - -int NzLuaInstance::GetAbsIndex(int index) const -{ - return lua_absindex(m_state, index); -} - -nzLuaType NzLuaInstance::GetField(const char* fieldName, int index) const -{ - return FromLuaType(lua_getfield(m_state, index, fieldName)); -} - -nzLuaType NzLuaInstance::GetField(const NzString& fieldName, int index) const -{ - return FromLuaType(lua_getfield(m_state, index, fieldName.GetConstBuffer())); -} - -nzLuaType NzLuaInstance::GetGlobal(const char* name) const -{ - return FromLuaType(lua_getglobal(m_state, name)); -} - -nzLuaType NzLuaInstance::GetGlobal(const NzString& name) const -{ - return FromLuaType(lua_getglobal(m_state, name.GetConstBuffer())); -} - -lua_State* NzLuaInstance::GetInternalState() const -{ - return m_state; -} - -NzString NzLuaInstance::GetLastError() const -{ - return m_lastError; -} - -nzUInt32 NzLuaInstance::GetMemoryLimit() const -{ - return m_memoryLimit; -} - -nzUInt32 NzLuaInstance::GetMemoryUsage() const -{ - return m_memoryUsage; -} - -nzLuaType NzLuaInstance::GetMetatable(const char* tname) const -{ - return FromLuaType(luaL_getmetatable(m_state, tname)); -} - -nzLuaType NzLuaInstance::GetMetatable(const NzString& tname) const -{ - return FromLuaType(luaL_getmetatable(m_state, tname.GetConstBuffer())); -} - -bool NzLuaInstance::GetMetatable(int index) const -{ - return lua_getmetatable(m_state, index) != 0; -} - -unsigned int NzLuaInstance::GetStackTop() const -{ - return lua_gettop(m_state); -} - -nzLuaType NzLuaInstance::GetTable(int index) const -{ - return FromLuaType(lua_gettable(m_state, index)); -} - -nzUInt32 NzLuaInstance::GetTimeLimit() const -{ - return m_timeLimit; -} - -nzLuaType NzLuaInstance::GetType(int index) const -{ - return FromLuaType(lua_type(m_state, index)); -} - -const char* NzLuaInstance::GetTypeName(nzLuaType type) const -{ - #ifdef NAZARA_DEBUG - if (type > nzLuaType_Max) + long long LuaInstance::Length(int index) const { - NazaraError("Lua type out of enum"); - return nullptr; - } - #endif - - return lua_typename(m_state, s_types[type]); -} - -void NzLuaInstance::Insert(int index) -{ - lua_insert(m_state, index); -} - -bool NzLuaInstance::IsOfType(int index, nzLuaType type) const -{ - switch (type) - { - case nzLuaType_Boolean: - return lua_isboolean(m_state, index) != 0; - - case nzLuaType_Function: - return lua_isfunction(m_state, index) != 0; - - case nzLuaType_LightUserdata: - return lua_islightuserdata(m_state, index) != 0; - - case nzLuaType_Nil: - return lua_isnil(m_state, index) != 0; - - case nzLuaType_None: - return lua_isnone(m_state, index) != 0; - - case nzLuaType_Number: - return lua_isnumber(m_state, index) != 0; - - case nzLuaType_String: - return lua_isstring(m_state, index) != 0; - - case nzLuaType_Table: - return lua_istable(m_state, index) != 0; - - case nzLuaType_Thread: - return lua_isthread(m_state, index) != 0; - - case nzLuaType_Userdata: - return lua_isuserdata(m_state, index) != 0; + return luaL_len(m_state, index); } - NazaraError("Lua type not handled (0x" + NzString::Number(type, 16) + ')'); - return false; -} - -bool NzLuaInstance::IsOfType(int index, const char* tname) const -{ - void* ud = luaL_testudata(m_state, index, tname); - return ud != nullptr; -} - -bool NzLuaInstance::IsOfType(int index, const NzString& tname) const -{ - return IsOfType(index, tname.GetConstBuffer()); -} - -bool NzLuaInstance::IsValid(int index) const -{ - return lua_isnoneornil(m_state, index) == 0; -} - -long long NzLuaInstance::Length(int index) const -{ - return luaL_len(m_state, index); -} - -void NzLuaInstance::MoveTo(NzLuaInstance* instance, int n) -{ - lua_xmove(m_state, instance->m_state, n); -} - -bool NzLuaInstance::NewMetatable(const char* str) -{ - return luaL_newmetatable(m_state, str) != 0; -} - -bool NzLuaInstance::NewMetatable(const NzString& str) -{ - return luaL_newmetatable(m_state, str.GetConstBuffer()) != 0; -} - -bool NzLuaInstance::Next(int index) -{ - return lua_next(m_state, index) != 0; -} - -void NzLuaInstance::Pop(unsigned int n) -{ - lua_pop(m_state, static_cast(n)); -} - -void NzLuaInstance::PushBoolean(bool value) -{ - lua_pushboolean(m_state, (value) ? 1 : 0); -} - -void NzLuaInstance::PushCFunction(NzLuaCFunction func, unsigned int upvalueCount) -{ - lua_pushcclosure(m_state, func, upvalueCount); -} - -void NzLuaInstance::PushFunction(NzLuaFunction func) -{ - NzLuaFunction* luaFunc = reinterpret_cast(lua_newuserdata(m_state, sizeof(NzLuaFunction))); - NzPlacementNew(luaFunc, std::move(func)); - - lua_pushcclosure(m_state, ProxyFunc, 1); -} - -void NzLuaInstance::PushInteger(long long value) -{ - lua_pushinteger(m_state, value); -} - -void NzLuaInstance::PushLightUserdata(void* value) -{ - lua_pushlightuserdata(m_state, value); -} - -void NzLuaInstance::PushMetatable(const char* str) -{ - luaL_getmetatable(m_state, str); -} - -void NzLuaInstance::PushMetatable(const NzString& str) -{ - luaL_getmetatable(m_state, str.GetConstBuffer()); -} - -void NzLuaInstance::PushNil() -{ - lua_pushnil(m_state); -} - -void NzLuaInstance::PushNumber(double value) -{ - lua_pushnumber(m_state, value); -} - -void NzLuaInstance::PushReference(int ref) -{ - lua_rawgeti(m_state, LUA_REGISTRYINDEX, ref); -} - -void NzLuaInstance::PushString(const char* str) -{ - lua_pushstring(m_state, str); -} - -void NzLuaInstance::PushString(const char* str, unsigned int size) -{ - lua_pushlstring(m_state, str, size); -} - -void NzLuaInstance::PushString(const NzString& str) -{ - lua_pushlstring(m_state, str.GetConstBuffer(), str.GetSize()); -} - -void NzLuaInstance::PushTable(unsigned int sequenceElementCount, unsigned int arrayElementCount) -{ - lua_createtable(m_state, sequenceElementCount, arrayElementCount); -} - -void* NzLuaInstance::PushUserdata(unsigned int size) -{ - return lua_newuserdata(m_state, size); -} - -void NzLuaInstance::PushValue(int index) -{ - lua_pushvalue(m_state, index); -} - -void NzLuaInstance::Remove(int index) -{ - lua_remove(m_state, index); -} - -void NzLuaInstance::Replace(int index) -{ - lua_replace(m_state, index); -} - -void NzLuaInstance::SetField(const char* name, int index) -{ - lua_setfield(m_state, index, name); -} - -void NzLuaInstance::SetField(const NzString& name, int index) -{ - lua_setfield(m_state, index, name.GetConstBuffer()); -} - -void NzLuaInstance::SetGlobal(const char* name) -{ - lua_setglobal(m_state, name); -} - -void NzLuaInstance::SetGlobal(const NzString& name) -{ - lua_setglobal(m_state, name.GetConstBuffer()); -} - -void NzLuaInstance::SetMetatable(const char* tname) -{ - luaL_setmetatable(m_state, tname); -} - -void NzLuaInstance::SetMetatable(const NzString& tname) -{ - luaL_setmetatable(m_state, tname.GetConstBuffer()); -} - -void NzLuaInstance::SetMetatable(int index) -{ - lua_setmetatable(m_state, index); -} - -void NzLuaInstance::SetMemoryLimit(nzUInt32 memoryLimit) -{ - m_memoryLimit = memoryLimit; -} - -void NzLuaInstance::SetTable(int index) -{ - lua_settable(m_state, index); -} - -void NzLuaInstance::SetTimeLimit(nzUInt32 timeLimit) -{ - if (m_timeLimit != timeLimit) + void LuaInstance::MoveTo(LuaInstance* instance, int n) { - if (m_timeLimit == 0) - lua_sethook(m_state, TimeLimiter, LUA_MASKCOUNT, 1000); - else if (timeLimit == 0) - lua_sethook(m_state, TimeLimiter, 0, 1000); - - m_timeLimit = timeLimit; - } -} - -bool NzLuaInstance::ToBoolean(int index) const -{ - return lua_toboolean(m_state, index) != 0; -} - -long long NzLuaInstance::ToInteger(int index, bool* succeeded) const -{ - int success; - long long result = lua_tointegerx(m_state, index, &success); - - if (succeeded) - *succeeded = (success != 0); - - return result; -} - -double NzLuaInstance::ToNumber(int index, bool* succeeded) const -{ - int success; - double result = lua_tonumberx(m_state, index, &success); - - if (succeeded) - *succeeded = (success != 0); - - return result; -} - -const void* NzLuaInstance::ToPointer(int index) const -{ - return lua_topointer(m_state, index); -} - -const char* NzLuaInstance::ToString(int index, std::size_t* length) const -{ - return lua_tolstring(m_state, index, length); -} - -void* NzLuaInstance::ToUserdata(int index) const -{ - return lua_touserdata(m_state, index); -} - -void* NzLuaInstance::ToUserdata(int index, const char* tname) const -{ - return luaL_testudata(m_state, index, tname); -} - -void* NzLuaInstance::ToUserdata(int index, const NzString& tname) const -{ - return luaL_testudata(m_state, index, tname.GetConstBuffer()); -} - -int NzLuaInstance::GetIndexOfUpValue(int upValue) -{ - return lua_upvalueindex(upValue); -} - -NzLuaInstance* NzLuaInstance::GetInstance(lua_State* state) -{ - NzLuaInstance* instance; - lua_getallocf(state, reinterpret_cast(&instance)); - - return instance; -} - -bool NzLuaInstance::Run(int argCount, int resultCount) -{ - if (m_level++ == 0) - m_clock.Restart(); - - int status = lua_pcall(m_state, argCount, resultCount, 0); - - m_level--; - - if (status != 0) - { - m_lastError = lua_tostring(m_state, -1); - lua_pop(m_state, 1); - - return false; + lua_xmove(m_state, instance->m_state, n); } - return true; -} - -void* NzLuaInstance::MemoryAllocator(void* ud, void* ptr, std::size_t osize, std::size_t nsize) -{ - NzLuaInstance* instance = static_cast(ud); - nzUInt32& memoryLimit = instance->m_memoryLimit; - nzUInt32& memoryUsage = instance->m_memoryUsage; - - if (nsize == 0) + bool LuaInstance::NewMetatable(const char* str) { - memoryUsage -= osize; - std::free(ptr); - - return nullptr; + return luaL_newmetatable(m_state, str) != 0; } - else - { - nzUInt32 usage = memoryUsage + nsize; - if (ptr) - usage -= osize; - if (memoryLimit != 0 && usage > memoryLimit) + bool LuaInstance::NewMetatable(const String& str) + { + return luaL_newmetatable(m_state, str.GetConstBuffer()) != 0; + } + + bool LuaInstance::Next(int index) + { + return lua_next(m_state, index) != 0; + } + + void LuaInstance::Pop(unsigned int n) + { + lua_pop(m_state, static_cast(n)); + } + + void LuaInstance::PushBoolean(bool value) + { + lua_pushboolean(m_state, (value) ? 1 : 0); + } + + void LuaInstance::PushCFunction(LuaCFunction func, unsigned int upvalueCount) + { + lua_pushcclosure(m_state, func, upvalueCount); + } + + void LuaInstance::PushFunction(LuaFunction func) + { + LuaFunction* luaFunc = reinterpret_cast(lua_newuserdata(m_state, sizeof(LuaFunction))); + PlacementNew(luaFunc, std::move(func)); + + lua_pushcclosure(m_state, ProxyFunc, 1); + } + + void LuaInstance::PushInteger(long long value) + { + lua_pushinteger(m_state, value); + } + + void LuaInstance::PushLightUserdata(void* value) + { + lua_pushlightuserdata(m_state, value); + } + + void LuaInstance::PushMetatable(const char* str) + { + luaL_getmetatable(m_state, str); + } + + void LuaInstance::PushMetatable(const String& str) + { + luaL_getmetatable(m_state, str.GetConstBuffer()); + } + + void LuaInstance::PushNil() + { + lua_pushnil(m_state); + } + + void LuaInstance::PushNumber(double value) + { + lua_pushnumber(m_state, value); + } + + void LuaInstance::PushReference(int ref) + { + lua_rawgeti(m_state, LUA_REGISTRYINDEX, ref); + } + + void LuaInstance::PushString(const char* str) + { + lua_pushstring(m_state, str); + } + + void LuaInstance::PushString(const char* str, unsigned int size) + { + lua_pushlstring(m_state, str, size); + } + + void LuaInstance::PushString(const String& str) + { + lua_pushlstring(m_state, str.GetConstBuffer(), str.GetSize()); + } + + void LuaInstance::PushTable(unsigned int sequenceElementCount, unsigned int arrayElementCount) + { + lua_createtable(m_state, sequenceElementCount, arrayElementCount); + } + + void* LuaInstance::PushUserdata(unsigned int size) + { + return lua_newuserdata(m_state, size); + } + + void LuaInstance::PushValue(int index) + { + lua_pushvalue(m_state, index); + } + + void LuaInstance::Remove(int index) + { + lua_remove(m_state, index); + } + + void LuaInstance::Replace(int index) + { + lua_replace(m_state, index); + } + + void LuaInstance::SetField(const char* name, int index) + { + lua_setfield(m_state, index, name); + } + + void LuaInstance::SetField(const String& name, int index) + { + lua_setfield(m_state, index, name.GetConstBuffer()); + } + + void LuaInstance::SetGlobal(const char* name) + { + lua_setglobal(m_state, name); + } + + void LuaInstance::SetGlobal(const String& name) + { + lua_setglobal(m_state, name.GetConstBuffer()); + } + + void LuaInstance::SetMetatable(const char* tname) + { + luaL_setmetatable(m_state, tname); + } + + void LuaInstance::SetMetatable(const String& tname) + { + luaL_setmetatable(m_state, tname.GetConstBuffer()); + } + + void LuaInstance::SetMetatable(int index) + { + lua_setmetatable(m_state, index); + } + + void LuaInstance::SetMemoryLimit(UInt32 memoryLimit) + { + m_memoryLimit = memoryLimit; + } + + void LuaInstance::SetTable(int index) + { + lua_settable(m_state, index); + } + + void LuaInstance::SetTimeLimit(UInt32 timeLimit) + { + if (m_timeLimit != timeLimit) { - NazaraError("Lua memory usage is over memory limit (" + NzString::Number(usage) + " > " + NzString::Number(memoryLimit) + ')'); + if (m_timeLimit == 0) + lua_sethook(m_state, TimeLimiter, LUA_MASKCOUNT, 1000); + else if (timeLimit == 0) + lua_sethook(m_state, TimeLimiter, 0, 1000); + + m_timeLimit = timeLimit; + } + } + + bool LuaInstance::ToBoolean(int index) const + { + return lua_toboolean(m_state, index) != 0; + } + + long long LuaInstance::ToInteger(int index, bool* succeeded) const + { + int success; + long long result = lua_tointegerx(m_state, index, &success); + + if (succeeded) + *succeeded = (success != 0); + + return result; + } + + double LuaInstance::ToNumber(int index, bool* succeeded) const + { + int success; + double result = lua_tonumberx(m_state, index, &success); + + if (succeeded) + *succeeded = (success != 0); + + return result; + } + + const void* LuaInstance::ToPointer(int index) const + { + return lua_topointer(m_state, index); + } + + const char* LuaInstance::ToString(int index, std::size_t* length) const + { + return lua_tolstring(m_state, index, length); + } + + void* LuaInstance::ToUserdata(int index) const + { + return lua_touserdata(m_state, index); + } + + void* LuaInstance::ToUserdata(int index, const char* tname) const + { + return luaL_testudata(m_state, index, tname); + } + + void* LuaInstance::ToUserdata(int index, const String& tname) const + { + return luaL_testudata(m_state, index, tname.GetConstBuffer()); + } + + int LuaInstance::GetIndexOfUpValue(int upValue) + { + return lua_upvalueindex(upValue); + } + + LuaInstance* LuaInstance::GetInstance(lua_State* state) + { + LuaInstance* instance; + lua_getallocf(state, reinterpret_cast(&instance)); + + return instance; + } + + bool LuaInstance::Run(int argCount, int resultCount) + { + if (m_level++ == 0) + m_clock.Restart(); + + int status = lua_pcall(m_state, argCount, resultCount, 0); + + m_level--; + + if (status != 0) + { + m_lastError = lua_tostring(m_state, -1); + lua_pop(m_state, 1); + + return false; + } + + return true; + } + + void* LuaInstance::MemoryAllocator(void* ud, void* ptr, std::size_t osize, std::size_t nsize) + { + LuaInstance* instance = static_cast(ud); + UInt32& memoryLimit = instance->m_memoryLimit; + UInt32& memoryUsage = instance->m_memoryUsage; + + if (nsize == 0) + { + memoryUsage -= osize; + std::free(ptr); + return nullptr; } + else + { + UInt32 usage = memoryUsage + nsize; + if (ptr) + usage -= osize; - memoryUsage = usage; + if (memoryLimit != 0 && usage > memoryLimit) + { + NazaraError("Lua memory usage is over memory limit (" + String::Number(usage) + " > " + String::Number(memoryLimit) + ')'); + return nullptr; + } - return std::realloc(ptr, nsize); + memoryUsage = usage; + + return std::realloc(ptr, nsize); + } + } + + int LuaInstance::ProxyFunc(lua_State* state) + { + LuaFunction& func = *static_cast(lua_touserdata(state, lua_upvalueindex(1))); + return func(*GetInstance(state)); + } + + void LuaInstance::TimeLimiter(lua_State* state, lua_Debug* debug) + { + NazaraUnused(debug); + + LuaInstance* instance = GetInstance(state); + if (instance->m_clock.GetMilliseconds() > instance->m_timeLimit) + luaL_error(state, "maximum execution time exceeded"); } } - -int NzLuaInstance::ProxyFunc(lua_State* state) -{ - NzLuaFunction& func = *static_cast(lua_touserdata(state, lua_upvalueindex(1))); - return func(*GetInstance(state)); -} - -void NzLuaInstance::TimeLimiter(lua_State* state, lua_Debug* debug) -{ - NazaraUnused(debug); - - NzLuaInstance* instance = GetInstance(state); - if (instance->m_clock.GetMilliseconds() > instance->m_timeLimit) - luaL_error(state, "maximum execution time exceeded"); -} diff --git a/src/Nazara/Noise/Abstract2DNoise.cpp b/src/Nazara/Noise/Abstract2DNoise.cpp index 562661f9e..51cfeddcc 100644 --- a/src/Nazara/Noise/Abstract2DNoise.cpp +++ b/src/Nazara/Noise/Abstract2DNoise.cpp @@ -8,14 +8,17 @@ #include #include -NzAbstract2DNoise::~NzAbstract2DNoise() = default; - -float NzAbstract2DNoise::GetBasicValue(float x, float y) +namespace Nz { - return this->GetValue(x,y,m_resolution); -} + Abstract2DNoise::~Abstract2DNoise() = default; -float NzAbstract2DNoise::GetMappedValue(float x, float y) -{ - return (this->GetValue(x,y,m_resolution) + m_offset) * m_gain; + float Abstract2DNoise::GetBasicValue(float x, float y) + { + return this->GetValue(x,y,m_resolution); + } + + float Abstract2DNoise::GetMappedValue(float x, float y) + { + return (this->GetValue(x,y,m_resolution) + m_offset) * m_gain; + } } diff --git a/src/Nazara/Noise/Abstract3DNoise.cpp b/src/Nazara/Noise/Abstract3DNoise.cpp index 26abb35ad..6456babec 100644 --- a/src/Nazara/Noise/Abstract3DNoise.cpp +++ b/src/Nazara/Noise/Abstract3DNoise.cpp @@ -8,14 +8,17 @@ #include #include -NzAbstract3DNoise::~NzAbstract3DNoise() = default; - -float NzAbstract3DNoise::GetBasicValue(float x, float y, float z) +namespace Nz { - return this->GetValue(x,y,z,m_resolution); -} + Abstract3DNoise::~Abstract3DNoise() = default; -float NzAbstract3DNoise::GetMappedValue(float x, float y, float z) -{ - return (this->GetValue(x,y,z,m_resolution) + m_offset) * m_gain ; + float Abstract3DNoise::GetBasicValue(float x, float y, float z) + { + return this->GetValue(x,y,z,m_resolution); + } + + float Abstract3DNoise::GetMappedValue(float x, float y, float z) + { + return (this->GetValue(x,y,z,m_resolution) + m_offset) * m_gain ; + } } diff --git a/src/Nazara/Noise/Abstract4DNoise.cpp b/src/Nazara/Noise/Abstract4DNoise.cpp index e6688447a..44bde3b0f 100644 --- a/src/Nazara/Noise/Abstract4DNoise.cpp +++ b/src/Nazara/Noise/Abstract4DNoise.cpp @@ -8,14 +8,17 @@ #include #include -NzAbstract4DNoise::~NzAbstract4DNoise() = default; - -float NzAbstract4DNoise::GetBasicValue(float x, float y, float z, float w) +namespace Nz { - return this->GetValue(x,y,z,w,m_resolution); -} + Abstract4DNoise::~Abstract4DNoise() = default; -float NzAbstract4DNoise::GetMappedValue(float x, float y, float z, float w) -{ - return (this->GetValue(x,y,z,w,m_resolution) + m_offset) * m_gain ; + float Abstract4DNoise::GetBasicValue(float x, float y, float z, float w) + { + return this->GetValue(x,y,z,w,m_resolution); + } + + float Abstract4DNoise::GetMappedValue(float x, float y, float z, float w) + { + return (this->GetValue(x,y,z,w,m_resolution) + m_offset) * m_gain ; + } } diff --git a/src/Nazara/Noise/ComplexNoiseBase.cpp b/src/Nazara/Noise/ComplexNoiseBase.cpp index d3cadd270..c62ad8a8f 100644 --- a/src/Nazara/Noise/ComplexNoiseBase.cpp +++ b/src/Nazara/Noise/ComplexNoiseBase.cpp @@ -8,73 +8,76 @@ #include #include -NzComplexNoiseBase::NzComplexNoiseBase() +namespace Nz { - m_parametersModified = true; - m_lacunarity = 5.0f; - m_hurst = 1.2f; - m_octaves = 3.0f; - - for (int i(0) ; i < m_octaves; ++i) + ComplexNoiseBase::ComplexNoiseBase() { - m_exponent_array[i] = 0; - } -} + m_parametersModified = true; + m_lacunarity = 5.0f; + m_hurst = 1.2f; + m_octaves = 3.0f; -float NzComplexNoiseBase::GetLacunarity() const -{ - - return m_lacunarity; -} - -float NzComplexNoiseBase::GetHurstParameter() const -{ - return m_hurst; -} - -float NzComplexNoiseBase::GetOctaveNumber() const -{ - return m_octaves; -} - -void NzComplexNoiseBase::SetLacunarity(float lacunarity) -{ - m_lacunarity = lacunarity; - m_parametersModified = true; - -} - -void NzComplexNoiseBase::SetHurstParameter(float h) -{ - m_hurst = h; - m_parametersModified = true; -} - -void NzComplexNoiseBase::SetOctavesNumber(float octaves) -{ - if(octaves <= 30.0f) - m_octaves = octaves; - else - m_octaves = 30.0f; - - m_parametersModified = true; -} - -void NzComplexNoiseBase::RecomputeExponentArray() -{ - if(m_parametersModified) - { - float frequency = 1.0; - m_sum = 0.f; - for (int i(0) ; i < static_cast(m_octaves) ; ++i) + for (int i(0) ; i < m_octaves; ++i) { - - m_exponent_array[i] = std::pow( frequency, -m_hurst ); - frequency *= m_lacunarity; - - m_sum += m_exponent_array[i]; - + m_exponent_array[i] = 0; + } + } + + float ComplexNoiseBase::GetLacunarity() const + { + + return m_lacunarity; + } + + float ComplexNoiseBase::GetHurstParameter() const + { + return m_hurst; + } + + float ComplexNoiseBase::GetOctaveNumber() const + { + return m_octaves; + } + + void ComplexNoiseBase::SetLacunarity(float lacunarity) + { + m_lacunarity = lacunarity; + m_parametersModified = true; + + } + + void ComplexNoiseBase::SetHurstParameter(float h) + { + m_hurst = h; + m_parametersModified = true; + } + + void ComplexNoiseBase::SetOctavesNumber(float octaves) + { + if(octaves <= 30.0f) + m_octaves = octaves; + else + m_octaves = 30.0f; + + m_parametersModified = true; + } + + void ComplexNoiseBase::RecomputeExponentArray() + { + if(m_parametersModified) + { + float frequency = 1.0; + m_sum = 0.f; + for (int i(0) ; i < static_cast(m_octaves) ; ++i) + { + + m_exponent_array[i] = std::pow( frequency, -m_hurst ); + frequency *= m_lacunarity; + + m_sum += m_exponent_array[i]; + + } + m_parametersModified = false; } - m_parametersModified = false; } } diff --git a/src/Nazara/Noise/FBM2D.cpp b/src/Nazara/Noise/FBM2D.cpp index 9e35b3c57..5a4670b80 100644 --- a/src/Nazara/Noise/FBM2D.cpp +++ b/src/Nazara/Noise/FBM2D.cpp @@ -9,43 +9,46 @@ #include #include -NzFBM2D::NzFBM2D(nzNoises source, unsigned int seed) +namespace Nz { - switch(source) + FBM2D::FBM2D(NoiseType source, unsigned int seed) { - case PERLIN: - m_source = new NzPerlin2D(); - break; + switch(source) + { + case PERLIN: + m_source = new Perlin2D(); + break; - default: - m_source = new NzSimplex2D(); - break; + default: + m_source = new Simplex2D(); + break; + } + m_source->SetNewSeed(seed); + m_source->ShufflePermutationTable(); + m_noiseType = source; } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; -} -float NzFBM2D::GetValue(float x, float y, float resolution) -{ - this->RecomputeExponentArray(); - - m_value = 0.0; - - for (int i(0); i < m_octaves; ++i) + float FBM2D::GetValue(float x, float y, float resolution) { - m_value += m_source->GetValue(x,y,resolution) * m_exponent_array[i]; - resolution *= m_lacunarity; + this->RecomputeExponentArray(); + + m_value = 0.0; + + for (int i(0); i < m_octaves; ++i) + { + m_value += m_source->GetValue(x,y,resolution) * m_exponent_array[i]; + resolution *= m_lacunarity; + } + m_remainder = m_octaves - static_cast(m_octaves); + + if(!NumberEquals(m_remainder, static_cast(0.0))) + m_value += m_remainder * m_source->GetValue(x,y,resolution) * m_exponent_array[static_cast(m_octaves-1)]; + + return m_value/this->m_sum; } - m_remainder = m_octaves - static_cast(m_octaves); - if(!NzNumberEquals(m_remainder, static_cast(0.0))) - m_value += m_remainder * m_source->GetValue(x,y,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - - return m_value/this->m_sum; -} - -NzFBM2D::~NzFBM2D() -{ - delete m_source; + FBM2D::~FBM2D() + { + delete m_source; + } } diff --git a/src/Nazara/Noise/FBM3D.cpp b/src/Nazara/Noise/FBM3D.cpp index a56a8a90c..f0ee6143e 100644 --- a/src/Nazara/Noise/FBM3D.cpp +++ b/src/Nazara/Noise/FBM3D.cpp @@ -9,43 +9,46 @@ #include #include -NzFBM3D::NzFBM3D(nzNoises source, unsigned int seed) +namespace Nz { - switch(source) + FBM3D::FBM3D(NoiseType source, unsigned int seed) { - case PERLIN: - m_source = new NzPerlin3D(); - break; + switch(source) + { + case PERLIN: + m_source = new Perlin3D(); + break; - default: - m_source = new NzSimplex3D(); - break; + default: + m_source = new Simplex3D(); + break; + } + m_source->SetNewSeed(seed); + m_source->ShufflePermutationTable(); + m_noiseType = source; } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; -} -float NzFBM3D::GetValue(float x, float y, float z, float resolution) -{ - this->RecomputeExponentArray(); - - m_value = 0.0; - - for (int i(0); i < m_octaves; ++i) + float FBM3D::GetValue(float x, float y, float z, float resolution) { - m_value += m_source->GetValue(x,y,z,resolution) * m_exponent_array[i]; - resolution *= m_lacunarity; + this->RecomputeExponentArray(); + + m_value = 0.0; + + for (int i(0); i < m_octaves; ++i) + { + m_value += m_source->GetValue(x,y,z,resolution) * m_exponent_array[i]; + resolution *= m_lacunarity; + } + m_remainder = m_octaves - static_cast(m_octaves); + + if(!NumberEquals(m_remainder, static_cast(0.0))) + m_value += m_remainder * m_source->GetValue(x,y,z,resolution) * m_exponent_array[static_cast(m_octaves-1)]; + + return m_value/this->m_sum; } - m_remainder = m_octaves - static_cast(m_octaves); - if(!NzNumberEquals(m_remainder, static_cast(0.0))) - m_value += m_remainder * m_source->GetValue(x,y,z,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - - return m_value/this->m_sum; -} - -NzFBM3D::~NzFBM3D() -{ - delete m_source; + FBM3D::~FBM3D() + { + delete m_source; + } } diff --git a/src/Nazara/Noise/FBM4D.cpp b/src/Nazara/Noise/FBM4D.cpp index 483ef7a77..dace704d7 100644 --- a/src/Nazara/Noise/FBM4D.cpp +++ b/src/Nazara/Noise/FBM4D.cpp @@ -9,43 +9,46 @@ #include #include -NzFBM4D::NzFBM4D(nzNoises source, unsigned int seed) +namespace Nz { - switch(source) + FBM4D::FBM4D(NoiseType source, unsigned int seed) { - case PERLIN: - m_source = new NzPerlin4D(); - break; + switch(source) + { + case PERLIN: + m_source = new Perlin4D(); + break; - default: - m_source = new NzSimplex4D(); - break; + default: + m_source = new Simplex4D(); + break; + } + m_source->SetNewSeed(seed); + m_source->ShufflePermutationTable(); + m_noiseType = source; } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; -} -float NzFBM4D::GetValue(float x, float y, float z, float w, float resolution) -{ - this->RecomputeExponentArray(); - - m_value = 0.0; - - for (int i(0); i < m_octaves; ++i) + float FBM4D::GetValue(float x, float y, float z, float w, float resolution) { - m_value += m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[i]; - resolution *= m_lacunarity; + this->RecomputeExponentArray(); + + m_value = 0.0; + + for (int i(0); i < m_octaves; ++i) + { + m_value += m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[i]; + resolution *= m_lacunarity; + } + m_remainder = m_octaves - static_cast(m_octaves); + + if(!NumberEquals(m_remainder, static_cast(0.0))) + m_value += m_remainder * m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[static_cast(m_octaves-1)]; + + return m_value/this->m_sum; } - m_remainder = m_octaves - static_cast(m_octaves); - if(!NzNumberEquals(m_remainder, static_cast(0.0))) - m_value += m_remainder * m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - - return m_value/this->m_sum; -} - -NzFBM4D::~NzFBM4D() -{ - delete m_source; + FBM4D::~FBM4D() + { + delete m_source; + } } diff --git a/src/Nazara/Noise/HybridMultiFractal3D.cpp b/src/Nazara/Noise/HybridMultiFractal3D.cpp index 5c584da1f..e97ce3497 100644 --- a/src/Nazara/Noise/HybridMultiFractal3D.cpp +++ b/src/Nazara/Noise/HybridMultiFractal3D.cpp @@ -9,56 +9,59 @@ #include #include -NzHybridMultiFractal3D::NzHybridMultiFractal3D(nzNoises source, unsigned int seed) +namespace Nz { - switch(source) + HybridMultiFractal3D::HybridMultiFractal3D(NoiseType source, unsigned int seed) { - case PERLIN: - m_source = new NzPerlin3D(); - break; + switch(source) + { + case PERLIN: + m_source = new Perlin3D(); + break; - default: - m_source = new NzSimplex3D(); - break; + default: + m_source = new Simplex3D(); + break; + } + m_source->SetNewSeed(seed); + m_source->ShufflePermutationTable(); + m_noiseType = source; } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; -} -float NzHybridMultiFractal3D::GetValue(float x, float y, float z, float resolution) -{ - this->RecomputeExponentArray(); - - m_offset = 1.0f; - - m_value = (m_source->GetValue(x,y,z,resolution) + m_offset) * m_exponent_array[0]; - m_weight = m_value; - m_signal = 0.f; - - resolution *= m_lacunarity; - - for(int i(1) ; i < m_octaves; ++i) + float HybridMultiFractal3D::GetValue(float x, float y, float z, float resolution) { - if (m_weight > 1.f) - m_weight = 1.f; + this->RecomputeExponentArray(); - m_signal = (m_source->GetValue(x,y,z,resolution) + m_offset) * m_exponent_array[i]; - m_value += m_weight * m_signal; + m_offset = 1.0f; - m_weight *= m_signal; + m_value = (m_source->GetValue(x,y,z,resolution) + m_offset) * m_exponent_array[0]; + m_weight = m_value; + m_signal = 0.f; resolution *= m_lacunarity; + + for(int i(1) ; i < m_octaves; ++i) + { + if (m_weight > 1.f) + m_weight = 1.f; + + m_signal = (m_source->GetValue(x,y,z,resolution) + m_offset) * m_exponent_array[i]; + m_value += m_weight * m_signal; + + m_weight *= m_signal; + + resolution *= m_lacunarity; + } + + m_remainder = m_octaves - static_cast(m_octaves); + if (m_remainder > 0.f) + m_value += m_remainder * m_source->GetValue(x,y,z,resolution) * m_exponent_array[static_cast(m_octaves-1)]; + + return m_value/this->m_sum - m_offset; } - m_remainder = m_octaves - static_cast(m_octaves); - if (m_remainder > 0.f) - m_value += m_remainder * m_source->GetValue(x,y,z,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - - return m_value/this->m_sum - m_offset; -} - -NzHybridMultiFractal3D::~NzHybridMultiFractal3D() -{ - delete m_source; + HybridMultiFractal3D::~HybridMultiFractal3D() + { + delete m_source; + } } diff --git a/src/Nazara/Noise/HybridMultiFractal4D.cpp b/src/Nazara/Noise/HybridMultiFractal4D.cpp index d4f60066d..06ddf87a1 100644 --- a/src/Nazara/Noise/HybridMultiFractal4D.cpp +++ b/src/Nazara/Noise/HybridMultiFractal4D.cpp @@ -9,56 +9,59 @@ #include #include -NzHybridMultiFractal4D::NzHybridMultiFractal4D(nzNoises source, unsigned int seed) +namespace Nz { - switch(source) + HybridMultiFractal4D::HybridMultiFractal4D(NoiseType source, unsigned int seed) { - case PERLIN: - m_source = new NzPerlin4D(); - break; + switch(source) + { + case PERLIN: + m_source = new Perlin4D(); + break; - default: - m_source = new NzSimplex4D(); - break; + default: + m_source = new Simplex4D(); + break; + } + m_source->SetNewSeed(seed); + m_source->ShufflePermutationTable(); + m_noiseType = source; } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; -} -float NzHybridMultiFractal4D::GetValue(float x, float y, float z, float w, float resolution) -{ - this->RecomputeExponentArray(); - - m_offset = 1.0f; - - m_value = (m_source->GetValue(x,y,z,w,resolution) + m_offset) * m_exponent_array[0]; - m_weight = m_value; - m_signal = 0.f; - - resolution *= m_lacunarity; - - for(int i(1) ; i < m_octaves; ++i) + float HybridMultiFractal4D::GetValue(float x, float y, float z, float w, float resolution) { - if (m_weight > 1.f) - m_weight = 1.f; + this->RecomputeExponentArray(); - m_signal = (m_source->GetValue(x,y,z,w,resolution) + m_offset) * m_exponent_array[i]; - m_value += m_weight * m_signal; + m_offset = 1.0f; - m_weight *= m_signal; + m_value = (m_source->GetValue(x,y,z,w,resolution) + m_offset) * m_exponent_array[0]; + m_weight = m_value; + m_signal = 0.f; resolution *= m_lacunarity; + + for(int i(1) ; i < m_octaves; ++i) + { + if (m_weight > 1.f) + m_weight = 1.f; + + m_signal = (m_source->GetValue(x,y,z,w,resolution) + m_offset) * m_exponent_array[i]; + m_value += m_weight * m_signal; + + m_weight *= m_signal; + + resolution *= m_lacunarity; + } + + m_remainder = m_octaves - static_cast(m_octaves); + if (m_remainder > 0.f) + m_value += m_remainder * m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[static_cast(m_octaves-1)]; + + return m_value/this->m_sum - m_offset; } - m_remainder = m_octaves - static_cast(m_octaves); - if (m_remainder > 0.f) - m_value += m_remainder * m_source->GetValue(x,y,z,w,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - - return m_value/this->m_sum - m_offset; -} - -NzHybridMultiFractal4D::~NzHybridMultiFractal4D() -{ - delete m_source; + HybridMultiFractal4D::~HybridMultiFractal4D() + { + delete m_source; + } } diff --git a/src/Nazara/Noise/HybridMultifractal2D.cpp b/src/Nazara/Noise/HybridMultifractal2D.cpp index bfd016a5d..007ff78d0 100644 --- a/src/Nazara/Noise/HybridMultifractal2D.cpp +++ b/src/Nazara/Noise/HybridMultifractal2D.cpp @@ -9,56 +9,59 @@ #include #include -NzHybridMultiFractal2D::NzHybridMultiFractal2D(nzNoises source, unsigned int seed) +namespace Nz { - switch(source) + HybridMultiFractal2D::HybridMultiFractal2D(NoiseType source, unsigned int seed) { - case PERLIN: - m_source = new NzPerlin2D(); - break; + switch(source) + { + case PERLIN: + m_source = new Perlin2D(); + break; - default: - m_source = new NzSimplex2D(); - break; + default: + m_source = new Simplex2D(); + break; + } + m_source->SetNewSeed(seed); + m_source->ShufflePermutationTable(); + m_noiseType = source; } - m_source->SetNewSeed(seed); - m_source->ShufflePermutationTable(); - m_noiseType = source; -} -float NzHybridMultiFractal2D::GetValue(float x, float y, float resolution) -{ - this->RecomputeExponentArray(); - - m_offset = 1.0f; - - m_value = (m_source->GetValue(x,y,resolution) + m_offset) * m_exponent_array[0]; - m_weight = m_value; - m_signal = 0.f; - - resolution *= m_lacunarity; - - for(int i(1) ; i < m_octaves; ++i) + float HybridMultiFractal2D::GetValue(float x, float y, float resolution) { - if (m_weight > 1.f) - m_weight = 1.f; + this->RecomputeExponentArray(); - m_signal = (m_source->GetValue(x,y,resolution) + m_offset) * m_exponent_array[i]; - m_value += m_weight * m_signal; + m_offset = 1.0f; - m_weight *= m_signal; + m_value = (m_source->GetValue(x,y,resolution) + m_offset) * m_exponent_array[0]; + m_weight = m_value; + m_signal = 0.f; resolution *= m_lacunarity; + + for(int i(1) ; i < m_octaves; ++i) + { + if (m_weight > 1.f) + m_weight = 1.f; + + m_signal = (m_source->GetValue(x,y,resolution) + m_offset) * m_exponent_array[i]; + m_value += m_weight * m_signal; + + m_weight *= m_signal; + + resolution *= m_lacunarity; + } + + m_remainder = m_octaves - static_cast(m_octaves); + if (m_remainder > 0.f) + m_value += m_remainder * m_source->GetValue(x,y,resolution) * m_exponent_array[static_cast(m_octaves-1)]; + + return m_value/this->m_sum - m_offset; } - m_remainder = m_octaves - static_cast(m_octaves); - if (m_remainder > 0.f) - m_value += m_remainder * m_source->GetValue(x,y,resolution) * m_exponent_array[static_cast(m_octaves-1)]; - - return m_value/this->m_sum - m_offset; -} - -NzHybridMultiFractal2D::~NzHybridMultiFractal2D() -{ - delete m_source; + HybridMultiFractal2D::~HybridMultiFractal2D() + { + delete m_source; + } } diff --git a/src/Nazara/Noise/MappedNoiseBase.cpp b/src/Nazara/Noise/MappedNoiseBase.cpp index 7b520ae87..77d8e0eb3 100644 --- a/src/Nazara/Noise/MappedNoiseBase.cpp +++ b/src/Nazara/Noise/MappedNoiseBase.cpp @@ -10,44 +10,47 @@ #include #include -NzMappedNoiseBase::NzMappedNoiseBase() : m_gain(1.f), m_offset(0.f), m_resolution(30.f) +namespace Nz { - -} - -float NzMappedNoiseBase::GetGain() const -{ - return m_gain; -} - -float NzMappedNoiseBase::GetOffset() const -{ - return m_offset; -} - -float NzMappedNoiseBase::GetResolution() const -{ - return m_resolution; -} - -void NzMappedNoiseBase::SetGain(float gain) -{ - m_gain = gain; -} - -void NzMappedNoiseBase::SetOffset(float offset) -{ - m_offset = offset; -} - -void NzMappedNoiseBase::SetResolution(float resolution) -{ - if (NzNumberEquals(resolution, 0.f)) + MappedNoiseBase::MappedNoiseBase() : m_gain(1.f), m_offset(0.f), m_resolution(30.f) { - NzStringStream ss; - ss << __FILE__ << ':' << __LINE__ << " : resolution cannot be 0.0f"; - throw std::domain_error(ss.ToString()); } - m_resolution = resolution; + + float MappedNoiseBase::GetGain() const + { + return m_gain; + } + + float MappedNoiseBase::GetOffset() const + { + return m_offset; + } + + float MappedNoiseBase::GetResolution() const + { + return m_resolution; + } + + void MappedNoiseBase::SetGain(float gain) + { + m_gain = gain; + } + + void MappedNoiseBase::SetOffset(float offset) + { + m_offset = offset; + } + + void MappedNoiseBase::SetResolution(float resolution) + { + if (NumberEquals(resolution, 0.f)) + { + StringStream ss; + ss << __FILE__ << ':' << __LINE__ << " : resolution cannot be 0.0f"; + + throw std::domain_error(ss.ToString()); + } + m_resolution = resolution; + } } diff --git a/src/Nazara/Noise/Noise.cpp b/src/Nazara/Noise/Noise.cpp index 86fc17a6a..6cfad09c1 100644 --- a/src/Nazara/Noise/Noise.cpp +++ b/src/Nazara/Noise/Noise.cpp @@ -9,54 +9,57 @@ #include #include -bool NzNoise::Initialize() +namespace Nz { - if (s_moduleReferenceCounter > 0) + bool Noise::Initialize() { + if (s_moduleReferenceCounter > 0) + { + s_moduleReferenceCounter++; + return true; // Déjà initialisé + } + + // Initialisation des dépendances + if (!Core::Initialize()) + { + NazaraError("Failed to initialize core module"); + Uninitialize(); + + return false; + } + s_moduleReferenceCounter++; - return true; // Déjà initialisé + + // Initialisation du module + + NazaraNotice("Initialized: Noise module"); + return true; } - // Initialisation des dépendances - if (!NzCore::Initialize()) + bool Noise::IsInitialized() { - NazaraError("Failed to initialize core module"); - Uninitialize(); - - return false; + return s_moduleReferenceCounter != 0; } - s_moduleReferenceCounter++; - - // Initialisation du module - - NazaraNotice("Initialized: Noise module"); - return true; -} - -bool NzNoise::IsInitialized() -{ - return s_moduleReferenceCounter != 0; -} - -void NzNoise::Uninitialize() -{ - if (s_moduleReferenceCounter != 1) + void Noise::Uninitialize() { - // Le module est soit encore utilisé, soit pas initialisé - if (s_moduleReferenceCounter > 1) - s_moduleReferenceCounter--; + if (s_moduleReferenceCounter != 1) + { + // Le module est soit encore utilisé, soit pas initialisé + if (s_moduleReferenceCounter > 1) + s_moduleReferenceCounter--; - return; + return; + } + + // Libération du module + s_moduleReferenceCounter = 0; + + NazaraNotice("Uninitialized: Noise module"); + + // Libération des dépendances + Core::Uninitialize(); } - // Libération du module - s_moduleReferenceCounter = 0; - - NazaraNotice("Uninitialized: Noise module"); - - // Libération des dépendances - NzCore::Uninitialize(); + unsigned int Noise::s_moduleReferenceCounter = 0; } - -unsigned int NzNoise::s_moduleReferenceCounter = 0; diff --git a/src/Nazara/Noise/NoiseBase.cpp b/src/Nazara/Noise/NoiseBase.cpp index 007ffa376..550579227 100644 --- a/src/Nazara/Noise/NoiseBase.cpp +++ b/src/Nazara/Noise/NoiseBase.cpp @@ -7,70 +7,73 @@ #include #include -NzNoiseBase::NzNoiseBase(unsigned int seed) +namespace Nz { - Ua = 16807; - Uc = 0; - Um = 2147483647; - UcurrentSeed = 0; - Uprevious = 0; + NoiseBase::NoiseBase(unsigned int seed) + { + Ua = 16807; + Uc = 0; + Um = 2147483647; + UcurrentSeed = 0; + Uprevious = 0; - SetNewSeed(seed); + SetNewSeed(seed); - for(int i(0) ; i < 512 ; i++) - perm[i] = i & 255; + for(int i(0) ; i < 512 ; i++) + perm[i] = i & 255; -} - -void NzNoiseBase::SetNewSeed(unsigned int seed) -{ - Uprevious = seed; - UcurrentSeed = seed; -} - -unsigned int NzNoiseBase::GetUniformRandomValue() -{ - Ulast = Ua*Uprevious + Uc%Um; - Uprevious = Ulast; - return Ulast; -} - -void NzNoiseBase::ShufflePermutationTable() -{ - int xchanger; - unsigned int ncase; - - for(unsigned int i(0) ; i < 256 ; i++) - perm[i] = i; - - for(unsigned int j(0) ; j < 20 ; ++j) - for (unsigned int i(0); i < 256 ; ++i) - { - ncase = this->GetUniformRandomValue() & 255; - xchanger = perm[i]; - perm[i] = perm[ncase]; - perm[ncase] = xchanger; - } - - for(unsigned int i(256) ; i < 512; ++i) - perm[i] = perm[i & 255]; -} - -int NzNoiseBase::fastfloor(float n) -{ - return (n >= 0) ? static_cast(n) : static_cast(n-1); -} - -int NzNoiseBase::JenkinsHash(int a, int b, int c) -{ - a = a-b; a = a - c; a = a^(static_cast(c) >> 13); - b = b-c; b = b - a; b = b^(a << 8); - c = c-a; c = c - b; c = c^(static_cast(b) >> 13); - a = a-b; a = a - c; a = a^(static_cast(c) >> 12); - b = b-c; b = b - a; b = b^(a << 16); - c = c-a; c = c - b; c = c^(static_cast(b) >> 5); - a = a-b; a = a - c; a = a^(static_cast(c) >> 3); - b = b-c; b = b - a; b = b^(a << 10); - c = c-a; c = c - b; c = c^(static_cast(b) >> 15); - return c; + } + + void NoiseBase::SetNewSeed(unsigned int seed) + { + Uprevious = seed; + UcurrentSeed = seed; + } + + unsigned int NoiseBase::GetUniformRandomValue() + { + Ulast = Ua*Uprevious + Uc%Um; + Uprevious = Ulast; + return Ulast; + } + + void NoiseBase::ShufflePermutationTable() + { + int xchanger; + unsigned int ncase; + + for(unsigned int i(0) ; i < 256 ; i++) + perm[i] = i; + + for(unsigned int j(0) ; j < 20 ; ++j) + for (unsigned int i(0); i < 256 ; ++i) + { + ncase = this->GetUniformRandomValue() & 255; + xchanger = perm[i]; + perm[i] = perm[ncase]; + perm[ncase] = xchanger; + } + + for(unsigned int i(256) ; i < 512; ++i) + perm[i] = perm[i & 255]; + } + + int NoiseBase::fastfloor(float n) + { + return (n >= 0) ? static_cast(n) : static_cast(n-1); + } + + int NoiseBase::JenkinsHash(int a, int b, int c) + { + a = a-b; a = a - c; a = a^(static_cast(c) >> 13); + b = b-c; b = b - a; b = b^(a << 8); + c = c-a; c = c - b; c = c^(static_cast(b) >> 13); + a = a-b; a = a - c; a = a^(static_cast(c) >> 12); + b = b-c; b = b - a; b = b^(a << 16); + c = c-a; c = c - b; c = c^(static_cast(b) >> 5); + a = a-b; a = a - c; a = a^(static_cast(c) >> 3); + b = b-c; b = b - a; b = b^(a << 10); + c = c-a; c = c - b; c = c^(static_cast(b) >> 15); + return c; + } } diff --git a/src/Nazara/Noise/Perlin2D.cpp b/src/Nazara/Noise/Perlin2D.cpp index 02a6e58cb..1d26c01e2 100644 --- a/src/Nazara/Noise/Perlin2D.cpp +++ b/src/Nazara/Noise/Perlin2D.cpp @@ -7,66 +7,69 @@ #include #include -NzPerlin2D::NzPerlin2D() +namespace Nz { - float grad2Temp[][2] = { - {1.f,1.f}, - {-1.f,1.f}, - {1.f,-1.f}, - {-1.f,-1.f}, + Perlin2D::Perlin2D() + { + float grad2Temp[][2] = { + {1.f,1.f}, + {-1.f,1.f}, + {1.f,-1.f}, + {-1.f,-1.f}, - {1.f,0.f}, - {-1.f,0.f}, - {0.f,1.f}, - {0.f,-1.f} - }; + {1.f,0.f}, + {-1.f,0.f}, + {0.f,1.f}, + {0.f,-1.f} + }; - for(int i(0) ; i < 8 ; ++i) - for(int j(0) ; j < 2 ; ++j) - gradient2[i][j] = grad2Temp[i][j]; -} - -NzPerlin2D::NzPerlin2D(unsigned int seed) : NzPerlin2D() -{ - this->SetNewSeed(seed); - this->ShufflePermutationTable(); -} - -float NzPerlin2D::GetValue(float x, float y, float resolution) -{ - x *= resolution; - y *= resolution; - - x0 = fastfloor(x); - y0 = fastfloor(y); - - ii = x0 & 255; - jj = y0 & 255; - - gi0 = perm[ii + perm[jj]] & 7; - gi1 = perm[ii + 1 + perm[jj]] & 7; - gi2 = perm[ii + perm[jj + 1]] & 7; - gi3 = perm[ii + 1 + perm[jj + 1]] & 7; - - temp.x = x-x0; - temp.y = y-y0; - - Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); - Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); - - s = gradient2[gi0][0]*temp.x + gradient2[gi0][1]*temp.y; - - temp.x = x-(x0+1); - t = gradient2[gi1][0]*temp.x + gradient2[gi1][1]*temp.y; - - temp.y = y-(y0+1); - v = gradient2[gi3][0]*temp.x + gradient2[gi3][1]*temp.y; - - temp.x = x-x0; - u = gradient2[gi2][0]*temp.x + gradient2[gi2][1]*temp.y; - - Li1 = s + Cx*(t-s); - Li2 = u + Cx*(v-u); - - return Li1 + Cy*(Li2-Li1); + for(int i(0) ; i < 8 ; ++i) + for(int j(0) ; j < 2 ; ++j) + gradient2[i][j] = grad2Temp[i][j]; + } + + Perlin2D::Perlin2D(unsigned int seed) : Perlin2D() + { + this->SetNewSeed(seed); + this->ShufflePermutationTable(); + } + + float Perlin2D::GetValue(float x, float y, float resolution) + { + x *= resolution; + y *= resolution; + + x0 = fastfloor(x); + y0 = fastfloor(y); + + ii = x0 & 255; + jj = y0 & 255; + + gi0 = perm[ii + perm[jj]] & 7; + gi1 = perm[ii + 1 + perm[jj]] & 7; + gi2 = perm[ii + perm[jj + 1]] & 7; + gi3 = perm[ii + 1 + perm[jj + 1]] & 7; + + temp.x = x-x0; + temp.y = y-y0; + + Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); + Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); + + s = gradient2[gi0][0]*temp.x + gradient2[gi0][1]*temp.y; + + temp.x = x-(x0+1); + t = gradient2[gi1][0]*temp.x + gradient2[gi1][1]*temp.y; + + temp.y = y-(y0+1); + v = gradient2[gi3][0]*temp.x + gradient2[gi3][1]*temp.y; + + temp.x = x-x0; + u = gradient2[gi2][0]*temp.x + gradient2[gi2][1]*temp.y; + + Li1 = s + Cx*(t-s); + Li2 = u + Cx*(v-u); + + return Li1 + Cy*(Li2-Li1); + } } diff --git a/src/Nazara/Noise/Perlin3D.cpp b/src/Nazara/Noise/Perlin3D.cpp index 472707814..2e91154f6 100644 --- a/src/Nazara/Noise/Perlin3D.cpp +++ b/src/Nazara/Noise/Perlin3D.cpp @@ -7,89 +7,92 @@ #include #include -NzPerlin3D::NzPerlin3D() +namespace Nz { - float grad3Temp[][3] = { - {1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0}, - {1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1}, - {0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}, - {1,1,0},{-1,1,0},{0,-1,1},{0,-1,-1} - }; + Perlin3D::Perlin3D() + { + float grad3Temp[][3] = { + {1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0}, + {1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1}, + {0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}, + {1,1,0},{-1,1,0},{0,-1,1},{0,-1,-1} + }; - for(int i(0) ; i < 16 ; ++i) - for(int j(0) ; j < 3 ; ++j) - gradient3[i][j] = grad3Temp[i][j]; -} - -NzPerlin3D::NzPerlin3D(unsigned int seed) : NzPerlin3D() -{ - this->SetNewSeed(seed); - this->ShufflePermutationTable(); -} - -float NzPerlin3D::GetValue(float x, float y, float z, float resolution) -{ - x /= resolution; - y /= resolution; - z /= resolution; - - x0 = fastfloor(x); - y0 = fastfloor(y); - z0 = fastfloor(z); - - ii = x0 & 255; - jj = y0 & 255; - kk = z0 & 255; - - gi0 = perm[ii + perm[jj + perm[kk]]] & 15; - gi1 = perm[ii + 1 + perm[jj + perm[kk]]] & 15; - gi2 = perm[ii + perm[jj + 1 + perm[kk]]] & 15; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk]]] & 15; - - gi4 = perm[ii + perm[jj + perm[kk + 1]]] & 15; - gi5 = perm[ii + 1 + perm[jj + perm[kk + 1]]] & 15; - gi6 = perm[ii + perm[jj + 1 + perm[kk + 1]]] & 15; - gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] & 15; - - temp.x = x-x0; - temp.y = y-y0; - temp.z = z-z0; - - Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); - Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); - Cz = temp.z * temp.z * temp.z * (temp.z * (temp.z * 6 - 15) + 10); - - s[0] = gradient3[gi0][0]*temp.x + gradient3[gi0][1]*temp.y + gradient3[gi0][2]*temp.z; - - temp.x = x-(x0+1); - t[0] = gradient3[gi1][0]*temp.x + gradient3[gi1][1]*temp.y + gradient3[gi1][2]*temp.z; - - temp.y = y-(y0+1); - v[0] = gradient3[gi3][0]*temp.x + gradient3[gi3][1]*temp.y + gradient3[gi3][2]*temp.z; - - temp.x = x-x0; - u[0] = gradient3[gi2][0]*temp.x + gradient3[gi2][1]*temp.y + gradient3[gi2][2]*temp.z; - - temp.y = y-y0; - temp.z = z-(z0+1); - s[1] = gradient3[gi4][0]*temp.x + gradient3[gi4][1]*temp.y + gradient3[gi4][2]*temp.z; - - temp.x = x-(x0+1); - t[1] = gradient3[gi5][0]*temp.x + gradient3[gi5][1]*temp.y + gradient3[gi5][2]*temp.z; - - temp.y = y-(y0+1); - v[1] = gradient3[gi7][0]*temp.x + gradient3[gi7][1]*temp.y + gradient3[gi7][2]*temp.z; - - temp.x = x-x0; - u[1] = gradient3[gi6][0]*temp.x + gradient3[gi6][1]*temp.y + gradient3[gi6][2]*temp.z; - - Li1 = s[0] + Cx*(t[0]-s[0]); - Li2 = u[0] + Cx*(v[0]-u[0]); - Li3 = s[1] + Cx*(t[1]-s[1]); - Li4 = u[1] + Cx*(v[1]-u[1]); - - Li5 = Li1 + Cy*(Li2-Li1); - Li6 = Li3 + Cy*(Li4-Li3); - - return Li5 + Cz*(Li6-Li5); + for(int i(0) ; i < 16 ; ++i) + for(int j(0) ; j < 3 ; ++j) + gradient3[i][j] = grad3Temp[i][j]; + } + + Perlin3D::Perlin3D(unsigned int seed) : Perlin3D() + { + this->SetNewSeed(seed); + this->ShufflePermutationTable(); + } + + float Perlin3D::GetValue(float x, float y, float z, float resolution) + { + x /= resolution; + y /= resolution; + z /= resolution; + + x0 = fastfloor(x); + y0 = fastfloor(y); + z0 = fastfloor(z); + + ii = x0 & 255; + jj = y0 & 255; + kk = z0 & 255; + + gi0 = perm[ii + perm[jj + perm[kk]]] & 15; + gi1 = perm[ii + 1 + perm[jj + perm[kk]]] & 15; + gi2 = perm[ii + perm[jj + 1 + perm[kk]]] & 15; + gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk]]] & 15; + + gi4 = perm[ii + perm[jj + perm[kk + 1]]] & 15; + gi5 = perm[ii + 1 + perm[jj + perm[kk + 1]]] & 15; + gi6 = perm[ii + perm[jj + 1 + perm[kk + 1]]] & 15; + gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] & 15; + + temp.x = x-x0; + temp.y = y-y0; + temp.z = z-z0; + + Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); + Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); + Cz = temp.z * temp.z * temp.z * (temp.z * (temp.z * 6 - 15) + 10); + + s[0] = gradient3[gi0][0]*temp.x + gradient3[gi0][1]*temp.y + gradient3[gi0][2]*temp.z; + + temp.x = x-(x0+1); + t[0] = gradient3[gi1][0]*temp.x + gradient3[gi1][1]*temp.y + gradient3[gi1][2]*temp.z; + + temp.y = y-(y0+1); + v[0] = gradient3[gi3][0]*temp.x + gradient3[gi3][1]*temp.y + gradient3[gi3][2]*temp.z; + + temp.x = x-x0; + u[0] = gradient3[gi2][0]*temp.x + gradient3[gi2][1]*temp.y + gradient3[gi2][2]*temp.z; + + temp.y = y-y0; + temp.z = z-(z0+1); + s[1] = gradient3[gi4][0]*temp.x + gradient3[gi4][1]*temp.y + gradient3[gi4][2]*temp.z; + + temp.x = x-(x0+1); + t[1] = gradient3[gi5][0]*temp.x + gradient3[gi5][1]*temp.y + gradient3[gi5][2]*temp.z; + + temp.y = y-(y0+1); + v[1] = gradient3[gi7][0]*temp.x + gradient3[gi7][1]*temp.y + gradient3[gi7][2]*temp.z; + + temp.x = x-x0; + u[1] = gradient3[gi6][0]*temp.x + gradient3[gi6][1]*temp.y + gradient3[gi6][2]*temp.z; + + Li1 = s[0] + Cx*(t[0]-s[0]); + Li2 = u[0] + Cx*(v[0]-u[0]); + Li3 = s[1] + Cx*(t[1]-s[1]); + Li4 = u[1] + Cx*(v[1]-u[1]); + + Li5 = Li1 + Cy*(Li2-Li1); + Li6 = Li3 + Cy*(Li4-Li3); + + return Li5 + Cz*(Li6-Li5); + } } diff --git a/src/Nazara/Noise/Perlin4D.cpp b/src/Nazara/Noise/Perlin4D.cpp index 4c2cb9051..b321616f6 100644 --- a/src/Nazara/Noise/Perlin4D.cpp +++ b/src/Nazara/Noise/Perlin4D.cpp @@ -7,147 +7,150 @@ #include #include -NzPerlin4D::NzPerlin4D() +namespace Nz { - float grad4Temp[][4] = + Perlin4D::Perlin4D() { - {0,1,1,1}, {0,1,1,-1}, {0,1,-1,1}, {0,1,-1,-1}, - {0,-1,1,1},{0,-1,1,-1},{0,-1,-1,1},{0,-1,-1,-1}, - {1,0,1,1}, {1,0,1,-1}, {1,0,-1,1}, {1,0,-1,-1}, - {-1,0,1,1},{-1,0,1,-1},{-1,0,-1,1},{-1,0,-1,-1}, - {1,1,0,1}, {1,1,0,-1}, {1,-1,0,1}, {1,-1,0,-1}, - {-1,1,0,1},{-1,1,0,-1},{-1,-1,0,1},{-1,-1,0,-1}, - {1,1,1,0}, {1,1,-1,0}, {1,-1,1,0}, {1,-1,-1,0}, - {-1,1,1,0},{-1,1,-1,0},{-1,-1,1,0},{-1,-1,-1,0} - }; + float grad4Temp[][4] = + { + {0,1,1,1}, {0,1,1,-1}, {0,1,-1,1}, {0,1,-1,-1}, + {0,-1,1,1},{0,-1,1,-1},{0,-1,-1,1},{0,-1,-1,-1}, + {1,0,1,1}, {1,0,1,-1}, {1,0,-1,1}, {1,0,-1,-1}, + {-1,0,1,1},{-1,0,1,-1},{-1,0,-1,1},{-1,0,-1,-1}, + {1,1,0,1}, {1,1,0,-1}, {1,-1,0,1}, {1,-1,0,-1}, + {-1,1,0,1},{-1,1,0,-1},{-1,-1,0,1},{-1,-1,0,-1}, + {1,1,1,0}, {1,1,-1,0}, {1,-1,1,0}, {1,-1,-1,0}, + {-1,1,1,0},{-1,1,-1,0},{-1,-1,1,0},{-1,-1,-1,0} + }; - for(int i(0) ; i < 32 ; ++i) - for(int j(0) ; j < 4 ; ++j) - gradient4[i][j] = grad4Temp[i][j]; -} - -NzPerlin4D::NzPerlin4D(unsigned int seed) : NzPerlin4D() -{ - this->SetNewSeed(seed); - this->ShufflePermutationTable(); -} - -float NzPerlin4D::GetValue(float x, float y, float z, float w, float resolution) -{ - x *= resolution; - y *= resolution; - z *= resolution; - w *= resolution; - - x0 = fastfloor(x); - y0 = fastfloor(y); - z0 = fastfloor(z); - w0 = fastfloor(w); - - ii = x0 & 255; - jj = y0 & 255; - kk = z0 & 255; - ll = w0 & 255; - - gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] & 31; - gi1 = perm[ii + 1 + perm[jj + perm[kk + perm[ll]]]] & 31; - gi2 = perm[ii + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; - - gi4 = perm[ii + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; - gi5 = perm[ii + 1 + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; - gi6 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; - gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; - - gi8 = perm[ii + perm[jj + perm[kk + perm[ll + 1]]]] & 31; - gi9 = perm[ii + 1 + perm[jj + perm[kk + perm[ll + 1]]]] & 31; - gi10 = perm[ii + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; - gi11 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; - - gi12 = perm[ii + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi13 = perm[ii + 1 + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi14 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi15 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; - - temp.x = x-x0; - temp.y = y-y0; - temp.z = z-z0; - temp.w = w-w0; - - Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); - Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); - Cz = temp.z * temp.z * temp.z * (temp.z * (temp.z * 6 - 15) + 10); - Cw = temp.w * temp.w * temp.w * (temp.w * (temp.w * 6 - 15) + 10); - - s[0] = gradient4[gi0][0]*temp.x + gradient4[gi0][1]*temp.y + gradient4[gi0][2]*temp.z + gradient4[gi0][3]*temp.w; - - temp.x = x-(x0+1); - t[0] = gradient4[gi1][0]*temp.x + gradient4[gi1][1]*temp.y + gradient4[gi1][2]*temp.z + gradient4[gi1][3]*temp.w; - - temp.y = y-(y0+1); - v[0] = gradient4[gi3][0]*temp.x + gradient4[gi3][1]*temp.y + gradient4[gi3][2]*temp.z + gradient4[gi3][3]*temp.w; - - temp.x = x-x0; - u[0] = gradient4[gi2][0]*temp.x + gradient4[gi2][1]*temp.y + gradient4[gi2][2]*temp.z + gradient4[gi2][3]*temp.w; - - temp.y = y-y0; - temp.z = z-(z0+1); - s[1] = gradient4[gi4][0]*temp.x + gradient4[gi4][1]*temp.y + gradient4[gi4][2]*temp.z + gradient4[gi4][3]*temp.w; - - temp.x = x-(x0+1); - t[1] = gradient4[gi5][0]*temp.x + gradient4[gi5][1]*temp.y + gradient4[gi5][2]*temp.z + gradient4[gi5][3]*temp.w; - - temp.y = y-(y0+1); - v[1] = gradient4[gi7][0]*temp.x + gradient4[gi7][1]*temp.y + gradient4[gi7][2]*temp.z + gradient4[gi7][3]*temp.w; - - temp.x = x-x0; - u[1] = gradient4[gi6][0]*temp.x + gradient4[gi6][1]*temp.y + gradient4[gi6][2]*temp.z + gradient4[gi6][3]*temp.w; - - - temp.y = y-y0; - temp.z = z-z0; - temp.w = w-(w0+1); - s[2] = gradient4[gi8][0]*temp.x + gradient4[gi8][1]*temp.y + gradient4[gi8][2]*temp.z + gradient4[gi8][3]*temp.w; - - temp.x = x-(x0+1); - t[2] = gradient4[gi9][0]*temp.x + gradient4[gi9][1]*temp.y + gradient4[gi9][2]*temp.z + gradient4[gi9][3]*temp.w; - - temp.y = y-(y0+1); - v[2] = gradient4[gi11][0]*temp.x + gradient4[gi11][1]*temp.y + gradient4[gi11][2]*temp.z + gradient4[gi11][3]*temp.w; - - temp.x = x-x0; - u[2] = gradient4[gi10][0]*temp.x + gradient4[gi10][1]*temp.y + gradient4[gi10][2]*temp.z + gradient4[gi10][3]*temp.w; - - - temp.y = y-y0; - temp.z = z-(z0+1); - s[3] = gradient4[gi12][0]*temp.x + gradient4[gi12][1]*temp.y + gradient4[gi12][2]*temp.z + gradient4[gi12][3]*temp.w; - - temp.x = x-(x0+1); - t[3] = gradient4[gi13][0]*temp.x + gradient4[gi13][1]*temp.y + gradient4[gi13][2]*temp.z + gradient4[gi13][3]*temp.w; - - temp.y = y-(y0+1); - v[3] = gradient4[gi15][0]*temp.x + gradient4[gi15][1]*temp.y + gradient4[gi15][2]*temp.z + gradient4[gi15][3]*temp.w; - - temp.x = x-x0; - u[3] = gradient4[gi14][0]*temp.x + gradient4[gi14][1]*temp.y + gradient4[gi14][2]*temp.z + gradient4[gi14][3]*temp.w; - - Li1 = s[0] + Cx*(t[0]-s[0]); - Li2 = u[0] + Cx*(v[0]-u[0]); - Li3 = s[1] + Cx*(t[1]-s[1]); - Li4 = u[1] + Cx*(v[1]-u[1]); - Li5 = s[2] + Cx*(t[2]-s[2]); - Li6 = u[2] + Cx*(v[2]-u[2]); - Li7 = s[3] + Cx*(t[3]-s[3]); - Li8 = u[3] + Cx*(v[3]-u[3]); - - Li9 = Li1 + Cy*(Li2-Li1); - Li10 = Li3 + Cy*(Li4-Li3); - Li11 = Li5 + Cy*(Li6-Li5); - Li12 = Li7 + Cy*(Li8-Li7); - - Li13 = Li9 + Cz*(Li10-Li9); - Li14 = Li11 + Cz*(Li12-Li11); - - return Li13 + Cw*(Li14-Li13); + for(int i(0) ; i < 32 ; ++i) + for(int j(0) ; j < 4 ; ++j) + gradient4[i][j] = grad4Temp[i][j]; + } + + Perlin4D::Perlin4D(unsigned int seed) : Perlin4D() + { + this->SetNewSeed(seed); + this->ShufflePermutationTable(); + } + + float Perlin4D::GetValue(float x, float y, float z, float w, float resolution) + { + x *= resolution; + y *= resolution; + z *= resolution; + w *= resolution; + + x0 = fastfloor(x); + y0 = fastfloor(y); + z0 = fastfloor(z); + w0 = fastfloor(w); + + ii = x0 & 255; + jj = y0 & 255; + kk = z0 & 255; + ll = w0 & 255; + + gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] & 31; + gi1 = perm[ii + 1 + perm[jj + perm[kk + perm[ll]]]] & 31; + gi2 = perm[ii + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; + gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; + + gi4 = perm[ii + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; + gi5 = perm[ii + 1 + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; + gi6 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; + gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; + + gi8 = perm[ii + perm[jj + perm[kk + perm[ll + 1]]]] & 31; + gi9 = perm[ii + 1 + perm[jj + perm[kk + perm[ll + 1]]]] & 31; + gi10 = perm[ii + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; + gi11 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; + + gi12 = perm[ii + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; + gi13 = perm[ii + 1 + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; + gi14 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; + gi15 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; + + temp.x = x-x0; + temp.y = y-y0; + temp.z = z-z0; + temp.w = w-w0; + + Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); + Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); + Cz = temp.z * temp.z * temp.z * (temp.z * (temp.z * 6 - 15) + 10); + Cw = temp.w * temp.w * temp.w * (temp.w * (temp.w * 6 - 15) + 10); + + s[0] = gradient4[gi0][0]*temp.x + gradient4[gi0][1]*temp.y + gradient4[gi0][2]*temp.z + gradient4[gi0][3]*temp.w; + + temp.x = x-(x0+1); + t[0] = gradient4[gi1][0]*temp.x + gradient4[gi1][1]*temp.y + gradient4[gi1][2]*temp.z + gradient4[gi1][3]*temp.w; + + temp.y = y-(y0+1); + v[0] = gradient4[gi3][0]*temp.x + gradient4[gi3][1]*temp.y + gradient4[gi3][2]*temp.z + gradient4[gi3][3]*temp.w; + + temp.x = x-x0; + u[0] = gradient4[gi2][0]*temp.x + gradient4[gi2][1]*temp.y + gradient4[gi2][2]*temp.z + gradient4[gi2][3]*temp.w; + + temp.y = y-y0; + temp.z = z-(z0+1); + s[1] = gradient4[gi4][0]*temp.x + gradient4[gi4][1]*temp.y + gradient4[gi4][2]*temp.z + gradient4[gi4][3]*temp.w; + + temp.x = x-(x0+1); + t[1] = gradient4[gi5][0]*temp.x + gradient4[gi5][1]*temp.y + gradient4[gi5][2]*temp.z + gradient4[gi5][3]*temp.w; + + temp.y = y-(y0+1); + v[1] = gradient4[gi7][0]*temp.x + gradient4[gi7][1]*temp.y + gradient4[gi7][2]*temp.z + gradient4[gi7][3]*temp.w; + + temp.x = x-x0; + u[1] = gradient4[gi6][0]*temp.x + gradient4[gi6][1]*temp.y + gradient4[gi6][2]*temp.z + gradient4[gi6][3]*temp.w; + + + temp.y = y-y0; + temp.z = z-z0; + temp.w = w-(w0+1); + s[2] = gradient4[gi8][0]*temp.x + gradient4[gi8][1]*temp.y + gradient4[gi8][2]*temp.z + gradient4[gi8][3]*temp.w; + + temp.x = x-(x0+1); + t[2] = gradient4[gi9][0]*temp.x + gradient4[gi9][1]*temp.y + gradient4[gi9][2]*temp.z + gradient4[gi9][3]*temp.w; + + temp.y = y-(y0+1); + v[2] = gradient4[gi11][0]*temp.x + gradient4[gi11][1]*temp.y + gradient4[gi11][2]*temp.z + gradient4[gi11][3]*temp.w; + + temp.x = x-x0; + u[2] = gradient4[gi10][0]*temp.x + gradient4[gi10][1]*temp.y + gradient4[gi10][2]*temp.z + gradient4[gi10][3]*temp.w; + + + temp.y = y-y0; + temp.z = z-(z0+1); + s[3] = gradient4[gi12][0]*temp.x + gradient4[gi12][1]*temp.y + gradient4[gi12][2]*temp.z + gradient4[gi12][3]*temp.w; + + temp.x = x-(x0+1); + t[3] = gradient4[gi13][0]*temp.x + gradient4[gi13][1]*temp.y + gradient4[gi13][2]*temp.z + gradient4[gi13][3]*temp.w; + + temp.y = y-(y0+1); + v[3] = gradient4[gi15][0]*temp.x + gradient4[gi15][1]*temp.y + gradient4[gi15][2]*temp.z + gradient4[gi15][3]*temp.w; + + temp.x = x-x0; + u[3] = gradient4[gi14][0]*temp.x + gradient4[gi14][1]*temp.y + gradient4[gi14][2]*temp.z + gradient4[gi14][3]*temp.w; + + Li1 = s[0] + Cx*(t[0]-s[0]); + Li2 = u[0] + Cx*(v[0]-u[0]); + Li3 = s[1] + Cx*(t[1]-s[1]); + Li4 = u[1] + Cx*(v[1]-u[1]); + Li5 = s[2] + Cx*(t[2]-s[2]); + Li6 = u[2] + Cx*(v[2]-u[2]); + Li7 = s[3] + Cx*(t[3]-s[3]); + Li8 = u[3] + Cx*(v[3]-u[3]); + + Li9 = Li1 + Cy*(Li2-Li1); + Li10 = Li3 + Cy*(Li4-Li3); + Li11 = Li5 + Cy*(Li6-Li5); + Li12 = Li7 + Cy*(Li8-Li7); + + Li13 = Li9 + Cz*(Li10-Li9); + Li14 = Li11 + Cz*(Li12-Li11); + + return Li13 + Cw*(Li14-Li13); + } } diff --git a/src/Nazara/Noise/Simplex2D.cpp b/src/Nazara/Noise/Simplex2D.cpp index c94e82977..b5e50c996 100644 --- a/src/Nazara/Noise/Simplex2D.cpp +++ b/src/Nazara/Noise/Simplex2D.cpp @@ -7,85 +7,88 @@ #include #include -NzSimplex2D::NzSimplex2D() +namespace Nz { - float grad2Temp[][2] = {{1,1},{-1,1},{1,-1},{-1,-1}, - {1,0},{-1,0},{0,1},{0,-1}}; - - for(int i(0) ; i < 8 ; ++i) - for(int j(0) ; j < 2 ; ++j) - gradient2[i][j] = grad2Temp[i][j]; - - SkewCoeff2D = 0.5f*(std::sqrt(3.f) - 1.f); - UnskewCoeff2D = (3.f-std::sqrt(3.f))/6.f; -} - -NzSimplex2D::NzSimplex2D(unsigned int seed) : NzSimplex2D() -{ - this->SetNewSeed(seed); - this->ShufflePermutationTable(); -} - -float NzSimplex2D::GetValue(float x, float y, float resolution) -{ - x *= resolution; - y *= resolution; - - sum = (x + y) * SkewCoeff2D; - skewedCubeOrigin.x = fastfloor(x + sum); - skewedCubeOrigin.y = fastfloor(y + sum); - - sum = (skewedCubeOrigin.x + skewedCubeOrigin.y) * UnskewCoeff2D; - unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; - unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; - - unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; - unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; - - if(unskewedDistToOrigin.x > unskewedDistToOrigin.y) + Simplex2D::Simplex2D() { - off1.x = 1; - off1.y = 0; - } - else - { - off1.x = 0; - off1.y = 1; + float grad2Temp[][2] = {{1,1},{-1,1},{1,-1},{-1,-1}, + {1,0},{-1,0},{0,1},{0,-1}}; + + for(int i(0) ; i < 8 ; ++i) + for(int j(0) ; j < 2 ; ++j) + gradient2[i][j] = grad2Temp[i][j]; + + SkewCoeff2D = 0.5f*(std::sqrt(3.f) - 1.f); + UnskewCoeff2D = (3.f-std::sqrt(3.f))/6.f; } - d1 = - unskewedDistToOrigin; + Simplex2D::Simplex2D(unsigned int seed) : Simplex2D() + { + this->SetNewSeed(seed); + this->ShufflePermutationTable(); + } - d2.x = d1.x + off1.x - UnskewCoeff2D; - d2.y = d1.y + off1.y - UnskewCoeff2D; + float Simplex2D::GetValue(float x, float y, float resolution) + { + x *= resolution; + y *= resolution; - d3.x = d1.x + 1.f - 2.f * UnskewCoeff2D; - d3.y = d1.y + 1.f - 2.f * UnskewCoeff2D; + sum = (x + y) * SkewCoeff2D; + skewedCubeOrigin.x = fastfloor(x + sum); + skewedCubeOrigin.y = fastfloor(y + sum); - ii = skewedCubeOrigin.x & 255; - jj = skewedCubeOrigin.y & 255; + sum = (skewedCubeOrigin.x + skewedCubeOrigin.y) * UnskewCoeff2D; + unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; + unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; - gi0 = perm[ii + perm[jj ]] & 7; - gi1 = perm[ii + off1.x + perm[jj + off1.y]] & 7; - gi2 = perm[ii + 1 + perm[jj + 1 ]] & 7; + unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; + unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; - c1 = 0.5f - d1.x * d1.x - d1.y * d1.y; - c2 = 0.5f - d2.x * d2.x - d2.y * d2.y; - c3 = 0.5f - d3.x * d3.x - d3.y * d3.y; + if(unskewedDistToOrigin.x > unskewedDistToOrigin.y) + { + off1.x = 1; + off1.y = 0; + } + else + { + off1.x = 0; + off1.y = 1; + } - if(c1 < 0) - n1 = 0; - else - n1 = c1*c1*c1*c1*(gradient2[gi0][0] * d1.x + gradient2[gi0][1] * d1.y); + d1 = - unskewedDistToOrigin; - if(c2 < 0) - n2 = 0; - else - n2 = c2*c2*c2*c2*(gradient2[gi1][0] * d2.x + gradient2[gi1][1] * d2.y); + d2.x = d1.x + off1.x - UnskewCoeff2D; + d2.y = d1.y + off1.y - UnskewCoeff2D; - if(c3 < 0) - n3 = 0; - else - n3 = c3*c3*c3*c3*(gradient2[gi2][0] * d3.x + gradient2[gi2][1] * d3.y); + d3.x = d1.x + 1.f - 2.f * UnskewCoeff2D; + d3.y = d1.y + 1.f - 2.f * UnskewCoeff2D; - return (n1+n2+n3)*70.f; + ii = skewedCubeOrigin.x & 255; + jj = skewedCubeOrigin.y & 255; + + gi0 = perm[ii + perm[jj ]] & 7; + gi1 = perm[ii + off1.x + perm[jj + off1.y]] & 7; + gi2 = perm[ii + 1 + perm[jj + 1 ]] & 7; + + c1 = 0.5f - d1.x * d1.x - d1.y * d1.y; + c2 = 0.5f - d2.x * d2.x - d2.y * d2.y; + c3 = 0.5f - d3.x * d3.x - d3.y * d3.y; + + if(c1 < 0) + n1 = 0; + else + n1 = c1*c1*c1*c1*(gradient2[gi0][0] * d1.x + gradient2[gi0][1] * d1.y); + + if(c2 < 0) + n2 = 0; + else + n2 = c2*c2*c2*c2*(gradient2[gi1][0] * d2.x + gradient2[gi1][1] * d2.y); + + if(c3 < 0) + n3 = 0; + else + n3 = c3*c3*c3*c3*(gradient2[gi2][0] * d3.x + gradient2[gi2][1] * d3.y); + + return (n1+n2+n3)*70.f; + } } diff --git a/src/Nazara/Noise/Simplex3D.cpp b/src/Nazara/Noise/Simplex3D.cpp index 1907af576..5848f38ce 100644 --- a/src/Nazara/Noise/Simplex3D.cpp +++ b/src/Nazara/Noise/Simplex3D.cpp @@ -7,167 +7,170 @@ #include #include -NzSimplex3D::NzSimplex3D() +namespace Nz { - SkewCoeff3D = 1/3.f; - UnskewCoeff3D = 1/6.f; - - float grad3Temp[][3] = { - {1.f,1.f,0.f}, - {-1.f,1.f,0.f}, - {1.f,-1.f,0.f}, - {-1.f,-1.f,0.f}, - - {1.f,0.f,1.f}, - {-1.f,0.f,1.f}, - {1.f,0.f,-1.f}, - {-1.f,0.f,-1.f}, - - {0.f,1.f,1.f}, - {0.f,-1.f,1.f}, - {0.f,1.f,-1.f}, - {0.f,-1.f,-1.f} - }; - - for(int i(0) ; i < 12 ; ++i) - for(int j(0) ; j < 3 ; ++j) - gradient3[i][j] = grad3Temp[i][j]; -} - -NzSimplex3D::NzSimplex3D(unsigned int seed) : NzSimplex3D() -{ - this->SetNewSeed(seed); - this->ShufflePermutationTable(); -} - -float NzSimplex3D::GetValue(float x, float y, float z, float resolution) -{ - x *= resolution; - y *= resolution; - z *= resolution; - - sum = (x + y + z) * SkewCoeff3D; - skewedCubeOrigin.x = fastfloor(x + sum); - skewedCubeOrigin.y = fastfloor(y + sum); - skewedCubeOrigin.z = fastfloor(z + sum); - - sum = (skewedCubeOrigin.x + skewedCubeOrigin.y + skewedCubeOrigin.z) * UnskewCoeff3D; - unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; - unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; - unskewedCubeOrigin.z = skewedCubeOrigin.z - sum; - - unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; - unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; - unskewedDistToOrigin.z = z - unskewedCubeOrigin.z; - - if(unskewedDistToOrigin.x >= unskewedDistToOrigin.y) + Simplex3D::Simplex3D() { - if(unskewedDistToOrigin.y >= unskewedDistToOrigin.z) + SkewCoeff3D = 1/3.f; + UnskewCoeff3D = 1/6.f; + + float grad3Temp[][3] = { + {1.f,1.f,0.f}, + {-1.f,1.f,0.f}, + {1.f,-1.f,0.f}, + {-1.f,-1.f,0.f}, + + {1.f,0.f,1.f}, + {-1.f,0.f,1.f}, + {1.f,0.f,-1.f}, + {-1.f,0.f,-1.f}, + + {0.f,1.f,1.f}, + {0.f,-1.f,1.f}, + {0.f,1.f,-1.f}, + {0.f,-1.f,-1.f} + }; + + for(int i(0) ; i < 12 ; ++i) + for(int j(0) ; j < 3 ; ++j) + gradient3[i][j] = grad3Temp[i][j]; + } + + Simplex3D::Simplex3D(unsigned int seed) : Simplex3D() + { + this->SetNewSeed(seed); + this->ShufflePermutationTable(); + } + + float Simplex3D::GetValue(float x, float y, float z, float resolution) + { + x *= resolution; + y *= resolution; + z *= resolution; + + sum = (x + y + z) * SkewCoeff3D; + skewedCubeOrigin.x = fastfloor(x + sum); + skewedCubeOrigin.y = fastfloor(y + sum); + skewedCubeOrigin.z = fastfloor(z + sum); + + sum = (skewedCubeOrigin.x + skewedCubeOrigin.y + skewedCubeOrigin.z) * UnskewCoeff3D; + unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; + unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; + unskewedCubeOrigin.z = skewedCubeOrigin.z - sum; + + unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; + unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; + unskewedDistToOrigin.z = z - unskewedCubeOrigin.z; + + if(unskewedDistToOrigin.x >= unskewedDistToOrigin.y) { - off1.x = 1; - off1.y = 0; - off1.z = 0; - off2.x = 1; - off2.y = 1; - off2.z = 0; - } - else if(unskewedDistToOrigin.x >= unskewedDistToOrigin.z) - { - off1.x = 1; - off1.y = 0; - off1.z = 0; - off2.x = 1; - off2.y = 0; - off2.z = 1; + if(unskewedDistToOrigin.y >= unskewedDistToOrigin.z) + { + off1.x = 1; + off1.y = 0; + off1.z = 0; + off2.x = 1; + off2.y = 1; + off2.z = 0; + } + else if(unskewedDistToOrigin.x >= unskewedDistToOrigin.z) + { + off1.x = 1; + off1.y = 0; + off1.z = 0; + off2.x = 1; + off2.y = 0; + off2.z = 1; + } + else + { + off1.x = 0; + off1.y = 0; + off1.z = 1; + off2.x = 1; + off2.y = 0; + off2.z = 1; + } } else { - off1.x = 0; - off1.y = 0; - off1.z = 1; - off2.x = 1; - off2.y = 0; - off2.z = 1; - } - } - else - { - if(unskewedDistToOrigin.y < unskewedDistToOrigin.z) - { - off1.x = 0; - off1.y = 0; - off1.z = 1; - off2.x = 0; - off2.y = 1; - off2.z = 1; - } - else if(unskewedDistToOrigin.x < unskewedDistToOrigin.z) - { - off1.x = 0; - off1.y = 1; - off1.z = 0; - off2.x = 0; - off2.y = 1; - off2.z = 1; + if(unskewedDistToOrigin.y < unskewedDistToOrigin.z) + { + off1.x = 0; + off1.y = 0; + off1.z = 1; + off2.x = 0; + off2.y = 1; + off2.z = 1; + } + else if(unskewedDistToOrigin.x < unskewedDistToOrigin.z) + { + off1.x = 0; + off1.y = 1; + off1.z = 0; + off2.x = 0; + off2.y = 1; + off2.z = 1; + } + else + { + off1.x = 0; + off1.y = 1; + off1.z = 0; + off2.x = 1; + off2.y = 1; + off2.z = 0; + } } + + d1 = unskewedDistToOrigin; + + d2.x = d1.x - off1.x + UnskewCoeff3D; + d2.y = d1.y - off1.y + UnskewCoeff3D; + d2.z = d1.z - off1.z + UnskewCoeff3D; + + d3.x = d1.x - off2.x + 2.f*UnskewCoeff3D; + d3.y = d1.y - off2.y + 2.f*UnskewCoeff3D; + d3.z = d1.z - off2.z + 2.f*UnskewCoeff3D; + + d4.x = d1.x - 1.f + 3.f*UnskewCoeff3D; + d4.y = d1.y - 1.f + 3.f*UnskewCoeff3D; + d4.z = d1.z - 1.f + 3.f*UnskewCoeff3D; + + ii = skewedCubeOrigin.x & 255; + jj = skewedCubeOrigin.y & 255; + kk = skewedCubeOrigin.z & 255; + + gi0 = perm[ii + perm[jj + perm[kk ]]] % 12; + gi1 = perm[ii + off1.x + perm[jj + off1.y + perm[kk + off1.z]]] % 12; + gi2 = perm[ii + off2.x + perm[jj + off2.y + perm[kk + off2.z]]] % 12; + gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 ]]] % 12; + + c1 = 0.6f - d1.x * d1.x - d1.y * d1.y - d1.z * d1.z; + c2 = 0.6f - d2.x * d2.x - d2.y * d2.y - d2.z * d2.z; + c3 = 0.6f - d3.x * d3.x - d3.y * d3.y - d3.z * d3.z; + c4 = 0.6f - d4.x * d4.x - d4.y * d4.y - d4.z * d4.z; + + if(c1 < 0) + n1 = 0; else - { - off1.x = 0; - off1.y = 1; - off1.z = 0; - off2.x = 1; - off2.y = 1; - off2.z = 0; - } + n1 = c1*c1*c1*c1*(gradient3[gi0][0] * d1.x + gradient3[gi0][1] * d1.y + gradient3[gi0][2] * d1.z); + + if(c2 < 0) + n2 = 0; + else + n2 = c2*c2*c2*c2*(gradient3[gi1][0] * d2.x + gradient3[gi1][1] * d2.y + gradient3[gi1][2] * d2.z); + + if(c3 < 0) + n3 = 0; + else + n3 = c3*c3*c3*c3*(gradient3[gi2][0] * d3.x + gradient3[gi2][1] * d3.y + gradient3[gi2][2] * d3.z); + + if(c4 < 0) + n4 = 0; + else + n4 = c4*c4*c4*c4*(gradient3[gi3][0] * d4.x + gradient3[gi3][1] * d4.y + gradient3[gi3][2] * d4.z); + + return (n1+n2+n3+n4)*32; } - - d1 = unskewedDistToOrigin; - - d2.x = d1.x - off1.x + UnskewCoeff3D; - d2.y = d1.y - off1.y + UnskewCoeff3D; - d2.z = d1.z - off1.z + UnskewCoeff3D; - - d3.x = d1.x - off2.x + 2.f*UnskewCoeff3D; - d3.y = d1.y - off2.y + 2.f*UnskewCoeff3D; - d3.z = d1.z - off2.z + 2.f*UnskewCoeff3D; - - d4.x = d1.x - 1.f + 3.f*UnskewCoeff3D; - d4.y = d1.y - 1.f + 3.f*UnskewCoeff3D; - d4.z = d1.z - 1.f + 3.f*UnskewCoeff3D; - - ii = skewedCubeOrigin.x & 255; - jj = skewedCubeOrigin.y & 255; - kk = skewedCubeOrigin.z & 255; - - gi0 = perm[ii + perm[jj + perm[kk ]]] % 12; - gi1 = perm[ii + off1.x + perm[jj + off1.y + perm[kk + off1.z]]] % 12; - gi2 = perm[ii + off2.x + perm[jj + off2.y + perm[kk + off2.z]]] % 12; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 ]]] % 12; - - c1 = 0.6f - d1.x * d1.x - d1.y * d1.y - d1.z * d1.z; - c2 = 0.6f - d2.x * d2.x - d2.y * d2.y - d2.z * d2.z; - c3 = 0.6f - d3.x * d3.x - d3.y * d3.y - d3.z * d3.z; - c4 = 0.6f - d4.x * d4.x - d4.y * d4.y - d4.z * d4.z; - - if(c1 < 0) - n1 = 0; - else - n1 = c1*c1*c1*c1*(gradient3[gi0][0] * d1.x + gradient3[gi0][1] * d1.y + gradient3[gi0][2] * d1.z); - - if(c2 < 0) - n2 = 0; - else - n2 = c2*c2*c2*c2*(gradient3[gi1][0] * d2.x + gradient3[gi1][1] * d2.y + gradient3[gi1][2] * d2.z); - - if(c3 < 0) - n3 = 0; - else - n3 = c3*c3*c3*c3*(gradient3[gi2][0] * d3.x + gradient3[gi2][1] * d3.y + gradient3[gi2][2] * d3.z); - - if(c4 < 0) - n4 = 0; - else - n4 = c4*c4*c4*c4*(gradient3[gi3][0] * d4.x + gradient3[gi3][1] * d4.y + gradient3[gi3][2] * d4.z); - - return (n1+n2+n3+n4)*32; } diff --git a/src/Nazara/Noise/Simplex4D.cpp b/src/Nazara/Noise/Simplex4D.cpp index 8647a0386..b515d5958 100644 --- a/src/Nazara/Noise/Simplex4D.cpp +++ b/src/Nazara/Noise/Simplex4D.cpp @@ -7,160 +7,163 @@ #include #include -NzSimplex4D::NzSimplex4D() +namespace Nz { - SkewCoeff4D = (std::sqrt(5.f) - 1.f)/4.f; - UnskewCoeff4D = (5.f - std::sqrt(5.f))/20.f; - - int lookupTemp4D[][4] = + Simplex4D::Simplex4D() { - {0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0}, - {0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0}, - {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, - {1,2,0,3},{0,0,0,0},{1,3,0,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,3,0,1},{2,3,1,0}, - {1,0,2,3},{1,0,3,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,0,3,1},{0,0,0,0},{2,1,3,0}, - {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, - {2,0,1,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,0,1,2},{3,0,2,1},{0,0,0,0},{3,1,2,0}, - {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0} - }; + SkewCoeff4D = (std::sqrt(5.f) - 1.f)/4.f; + UnskewCoeff4D = (5.f - std::sqrt(5.f))/20.f; - for(int i(0) ; i < 64 ; ++i) - for(int j(0) ; j < 4 ; ++j) - lookupTable4D[i][j] = lookupTemp4D[i][j]; + int lookupTemp4D[][4] = + { + {0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0}, + {0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0}, + {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, + {1,2,0,3},{0,0,0,0},{1,3,0,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,3,0,1},{2,3,1,0}, + {1,0,2,3},{1,0,3,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,0,3,1},{0,0,0,0},{2,1,3,0}, + {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, + {2,0,1,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,0,1,2},{3,0,2,1},{0,0,0,0},{3,1,2,0}, + {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0} + }; - float grad4Temp[][4] = + for(int i(0) ; i < 64 ; ++i) + for(int j(0) ; j < 4 ; ++j) + lookupTable4D[i][j] = lookupTemp4D[i][j]; + + float grad4Temp[][4] = + { + {0.f,1.f,1.f,1.f}, {0.f,1.f,1.f,-1.f}, {0.f,1.f,-1.f,1.f}, {0.f,1.f,-1.f,-1.f}, + {0.f,-1.f,1.f,1.f},{0.f,-1.f,1.f,-1.f},{0.f,-1.f,-1.f,1.f},{0.f,-1.f,-1.f,-1.f}, + {1.f,0.f,1.f,1.f}, {1.f,0.f,1.f,-1.f}, {1.f,0.f,-1.f,1.f}, {1.f,0.f,-1.f,-1.f}, + {-1.f,0.f,1.f,1.f},{-1.f,0.f,1.f,-1.f},{-1.f,0.f,-1.f,1.f},{-1.f,0.f,-1.f,-1.f}, + {1.f,1.f,0.f,1.f}, {1.f,1.f,0.f,-1.f}, {1.f,-1.f,0.f,1.f}, {1.f,-1.f,0.f,-1.f}, + {-1.f,1.f,0.f,1.f},{-1.f,1.f,0.f,-1.f},{-1.f,-1.f,0.f,1.f},{-1.f,-1.f,0.f,-1.f}, + {1.f,1.f,1.f,0.f}, {1.f,1.f,-1.f,0.f}, {1.f,-1.f,1.f,0.f}, {1.f,-1.f,-1.f,0.f}, + {-1.f,1.f,1.f,0.f},{-1.f,1.f,-1.f,0.f},{-1.f,-1.f,1.f,0.f},{-1.f,-1.f,-1.f,0.f} + }; + + for(int i(0) ; i < 32 ; ++i) + for(int j(0) ; j < 4 ; ++j) + gradient4[i][j] = grad4Temp[i][j]; + } + + Simplex4D::Simplex4D(unsigned int seed) : Simplex4D() { - {0.f,1.f,1.f,1.f}, {0.f,1.f,1.f,-1.f}, {0.f,1.f,-1.f,1.f}, {0.f,1.f,-1.f,-1.f}, - {0.f,-1.f,1.f,1.f},{0.f,-1.f,1.f,-1.f},{0.f,-1.f,-1.f,1.f},{0.f,-1.f,-1.f,-1.f}, - {1.f,0.f,1.f,1.f}, {1.f,0.f,1.f,-1.f}, {1.f,0.f,-1.f,1.f}, {1.f,0.f,-1.f,-1.f}, - {-1.f,0.f,1.f,1.f},{-1.f,0.f,1.f,-1.f},{-1.f,0.f,-1.f,1.f},{-1.f,0.f,-1.f,-1.f}, - {1.f,1.f,0.f,1.f}, {1.f,1.f,0.f,-1.f}, {1.f,-1.f,0.f,1.f}, {1.f,-1.f,0.f,-1.f}, - {-1.f,1.f,0.f,1.f},{-1.f,1.f,0.f,-1.f},{-1.f,-1.f,0.f,1.f},{-1.f,-1.f,0.f,-1.f}, - {1.f,1.f,1.f,0.f}, {1.f,1.f,-1.f,0.f}, {1.f,-1.f,1.f,0.f}, {1.f,-1.f,-1.f,0.f}, - {-1.f,1.f,1.f,0.f},{-1.f,1.f,-1.f,0.f},{-1.f,-1.f,1.f,0.f},{-1.f,-1.f,-1.f,0.f} - }; + this->SetNewSeed(seed); + this->ShufflePermutationTable(); + } - for(int i(0) ; i < 32 ; ++i) - for(int j(0) ; j < 4 ; ++j) - gradient4[i][j] = grad4Temp[i][j]; -} - -NzSimplex4D::NzSimplex4D(unsigned int seed) : NzSimplex4D() -{ - this->SetNewSeed(seed); - this->ShufflePermutationTable(); -} - -float NzSimplex4D::GetValue(float x, float y, float z, float w, float resolution) -{ - x *= resolution; - y *= resolution; - z *= resolution; - w *= resolution; - - sum = (x + y + z + w) * SkewCoeff4D; - skewedCubeOrigin.x = fastfloor(x + sum); - skewedCubeOrigin.y = fastfloor(y + sum); - skewedCubeOrigin.z = fastfloor(z + sum); - skewedCubeOrigin.w = fastfloor(w + sum); - - sum = (skewedCubeOrigin.x + skewedCubeOrigin.y + skewedCubeOrigin.z + skewedCubeOrigin.w) * UnskewCoeff4D; - unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; - unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; - unskewedCubeOrigin.z = skewedCubeOrigin.z - sum; - unskewedCubeOrigin.w = skewedCubeOrigin.w - sum; - - unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; - unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; - unskewedDistToOrigin.z = z - unskewedCubeOrigin.z; - unskewedDistToOrigin.w = w - unskewedCubeOrigin.w; - - c1 = (unskewedDistToOrigin.x > unskewedDistToOrigin.y) ? 32 : 0; - c2 = (unskewedDistToOrigin.x > unskewedDistToOrigin.z) ? 16 : 0; - c3 = (unskewedDistToOrigin.y > unskewedDistToOrigin.z) ? 8 : 0; - c4 = (unskewedDistToOrigin.x > unskewedDistToOrigin.w) ? 4 : 0; - c5 = (unskewedDistToOrigin.y > unskewedDistToOrigin.w) ? 2 : 0; - c6 = (unskewedDistToOrigin.z > unskewedDistToOrigin.w) ? 1 : 0; - c = c1 + c2 + c3 + c4 + c5 + c6; - - off1.x = lookupTable4D[c][0] >= 3 ? 1 : 0; - off1.y = lookupTable4D[c][1] >= 3 ? 1 : 0; - off1.z = lookupTable4D[c][2] >= 3 ? 1 : 0; - off1.w = lookupTable4D[c][3] >= 3 ? 1 : 0; - - off2.x = lookupTable4D[c][0] >= 2 ? 1 : 0; - off2.y = lookupTable4D[c][1] >= 2 ? 1 : 0; - off2.z = lookupTable4D[c][2] >= 2 ? 1 : 0; - off2.w = lookupTable4D[c][3] >= 2 ? 1 : 0; - - off3.x = lookupTable4D[c][0] >= 1 ? 1 : 0; - off3.y = lookupTable4D[c][1] >= 1 ? 1 : 0; - off3.z = lookupTable4D[c][2] >= 1 ? 1 : 0; - off3.w = lookupTable4D[c][3] >= 1 ? 1 : 0; - - d1 = unskewedDistToOrigin; - - d2.x = d1.x - off1.x + UnskewCoeff4D; - d2.y = d1.y - off1.y + UnskewCoeff4D; - d2.z = d1.z - off1.z + UnskewCoeff4D; - d2.w = d1.w - off1.w + UnskewCoeff4D; - - d3.x = d1.x - off2.x + 2.f*UnskewCoeff4D; - d3.y = d1.y - off2.y + 2.f*UnskewCoeff4D; - d3.z = d1.z - off2.z + 2.f*UnskewCoeff4D; - d3.w = d1.w - off2.w + 2.f*UnskewCoeff4D; - - d4.x = d1.x - off3.x + 3.f*UnskewCoeff4D; - d4.y = d1.y - off3.y + 3.f*UnskewCoeff4D; - d4.z = d1.z - off3.z + 3.f*UnskewCoeff4D; - d4.w = d1.w - off3.w + 3.f*UnskewCoeff4D; - - d5.x = d1.x - 1.f + 4*UnskewCoeff4D; - d5.y = d1.y - 1.f + 4*UnskewCoeff4D; - d5.z = d1.z - 1.f + 4*UnskewCoeff4D; - d5.w = d1.w - 1.f + 4*UnskewCoeff4D; - - ii = skewedCubeOrigin.x & 255; - jj = skewedCubeOrigin.y & 255; - kk = skewedCubeOrigin.z & 255; - ll = skewedCubeOrigin.w & 255; - - gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] & 31; - gi1 = perm[ii + off1.x + perm[jj + off1.y + perm[kk + off1.z + perm[ll + off1.w]]]] & 31; - gi2 = perm[ii + off2.x + perm[jj + off2.y + perm[kk + off2.z + perm[ll + off2.w]]]] & 31; - gi3 = perm[ii + off3.x + perm[jj + off3.y + perm[kk + off3.z + perm[ll + off3.w]]]] & 31; - gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32; - - c1 = 0.6f - d1.x*d1.x - d1.y*d1.y - d1.z*d1.z - d1.w*d1.w; - c2 = 0.6f - d2.x*d2.x - d2.y*d2.y - d2.z*d2.z - d2.w*d2.w; - c3 = 0.6f - d3.x*d3.x - d3.y*d3.y - d3.z*d3.z - d3.w*d3.w; - c4 = 0.6f - d4.x*d4.x - d4.y*d4.y - d4.z*d4.z - d4.w*d4.w; - c5 = 0.6f - d5.x*d5.x - d5.y*d5.y - d5.z*d5.z - d5.w*d5.w; - - if(c1 < 0) - n1 = 0; - else - n1 = c1*c1*c1*c1*(gradient4[gi0][0]*d1.x + gradient4[gi0][1]*d1.y + gradient4[gi0][2]*d1.z + gradient4[gi0][3]*d1.w); - - if(c2 < 0) - n2 = 0; - else - n2 = c2*c2*c2*c2*(gradient4[gi1][0]*d2.x + gradient4[gi1][1]*d2.y + gradient4[gi1][2]*d2.z + gradient4[gi1][3]*d2.w); - - if(c3 < 0) - n3 = 0; - else - n3 = c3*c3*c3*c3*(gradient4[gi2][0]*d3.x + gradient4[gi2][1]*d3.y + gradient4[gi2][2]*d3.z + gradient4[gi2][3]*d3.w); - - if(c4 < 0) - n4 = 0; - else - n4 = c4*c4*c4*c4*(gradient4[gi3][0]*d4.x + gradient4[gi3][1]*d4.y + gradient4[gi3][2]*d4.z + gradient4[gi3][3]*d4.w); - - if(c5 < 0) - n5 = 0; - else - n5 = c5*c5*c5*c5*(gradient4[gi4][0]*d5.x + gradient4[gi4][1]*d5.y + gradient4[gi4][2]*d5.z + gradient4[gi4][3]*d5.w); - - return (n1+n2+n3+n4+n5)*27.f; + float Simplex4D::GetValue(float x, float y, float z, float w, float resolution) + { + x *= resolution; + y *= resolution; + z *= resolution; + w *= resolution; + + sum = (x + y + z + w) * SkewCoeff4D; + skewedCubeOrigin.x = fastfloor(x + sum); + skewedCubeOrigin.y = fastfloor(y + sum); + skewedCubeOrigin.z = fastfloor(z + sum); + skewedCubeOrigin.w = fastfloor(w + sum); + + sum = (skewedCubeOrigin.x + skewedCubeOrigin.y + skewedCubeOrigin.z + skewedCubeOrigin.w) * UnskewCoeff4D; + unskewedCubeOrigin.x = skewedCubeOrigin.x - sum; + unskewedCubeOrigin.y = skewedCubeOrigin.y - sum; + unskewedCubeOrigin.z = skewedCubeOrigin.z - sum; + unskewedCubeOrigin.w = skewedCubeOrigin.w - sum; + + unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; + unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; + unskewedDistToOrigin.z = z - unskewedCubeOrigin.z; + unskewedDistToOrigin.w = w - unskewedCubeOrigin.w; + + c1 = (unskewedDistToOrigin.x > unskewedDistToOrigin.y) ? 32 : 0; + c2 = (unskewedDistToOrigin.x > unskewedDistToOrigin.z) ? 16 : 0; + c3 = (unskewedDistToOrigin.y > unskewedDistToOrigin.z) ? 8 : 0; + c4 = (unskewedDistToOrigin.x > unskewedDistToOrigin.w) ? 4 : 0; + c5 = (unskewedDistToOrigin.y > unskewedDistToOrigin.w) ? 2 : 0; + c6 = (unskewedDistToOrigin.z > unskewedDistToOrigin.w) ? 1 : 0; + c = c1 + c2 + c3 + c4 + c5 + c6; + + off1.x = lookupTable4D[c][0] >= 3 ? 1 : 0; + off1.y = lookupTable4D[c][1] >= 3 ? 1 : 0; + off1.z = lookupTable4D[c][2] >= 3 ? 1 : 0; + off1.w = lookupTable4D[c][3] >= 3 ? 1 : 0; + + off2.x = lookupTable4D[c][0] >= 2 ? 1 : 0; + off2.y = lookupTable4D[c][1] >= 2 ? 1 : 0; + off2.z = lookupTable4D[c][2] >= 2 ? 1 : 0; + off2.w = lookupTable4D[c][3] >= 2 ? 1 : 0; + + off3.x = lookupTable4D[c][0] >= 1 ? 1 : 0; + off3.y = lookupTable4D[c][1] >= 1 ? 1 : 0; + off3.z = lookupTable4D[c][2] >= 1 ? 1 : 0; + off3.w = lookupTable4D[c][3] >= 1 ? 1 : 0; + + d1 = unskewedDistToOrigin; + + d2.x = d1.x - off1.x + UnskewCoeff4D; + d2.y = d1.y - off1.y + UnskewCoeff4D; + d2.z = d1.z - off1.z + UnskewCoeff4D; + d2.w = d1.w - off1.w + UnskewCoeff4D; + + d3.x = d1.x - off2.x + 2.f*UnskewCoeff4D; + d3.y = d1.y - off2.y + 2.f*UnskewCoeff4D; + d3.z = d1.z - off2.z + 2.f*UnskewCoeff4D; + d3.w = d1.w - off2.w + 2.f*UnskewCoeff4D; + + d4.x = d1.x - off3.x + 3.f*UnskewCoeff4D; + d4.y = d1.y - off3.y + 3.f*UnskewCoeff4D; + d4.z = d1.z - off3.z + 3.f*UnskewCoeff4D; + d4.w = d1.w - off3.w + 3.f*UnskewCoeff4D; + + d5.x = d1.x - 1.f + 4*UnskewCoeff4D; + d5.y = d1.y - 1.f + 4*UnskewCoeff4D; + d5.z = d1.z - 1.f + 4*UnskewCoeff4D; + d5.w = d1.w - 1.f + 4*UnskewCoeff4D; + + ii = skewedCubeOrigin.x & 255; + jj = skewedCubeOrigin.y & 255; + kk = skewedCubeOrigin.z & 255; + ll = skewedCubeOrigin.w & 255; + + gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] & 31; + gi1 = perm[ii + off1.x + perm[jj + off1.y + perm[kk + off1.z + perm[ll + off1.w]]]] & 31; + gi2 = perm[ii + off2.x + perm[jj + off2.y + perm[kk + off2.z + perm[ll + off2.w]]]] & 31; + gi3 = perm[ii + off3.x + perm[jj + off3.y + perm[kk + off3.z + perm[ll + off3.w]]]] & 31; + gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32; + + c1 = 0.6f - d1.x*d1.x - d1.y*d1.y - d1.z*d1.z - d1.w*d1.w; + c2 = 0.6f - d2.x*d2.x - d2.y*d2.y - d2.z*d2.z - d2.w*d2.w; + c3 = 0.6f - d3.x*d3.x - d3.y*d3.y - d3.z*d3.z - d3.w*d3.w; + c4 = 0.6f - d4.x*d4.x - d4.y*d4.y - d4.z*d4.z - d4.w*d4.w; + c5 = 0.6f - d5.x*d5.x - d5.y*d5.y - d5.z*d5.z - d5.w*d5.w; + + if(c1 < 0) + n1 = 0; + else + n1 = c1*c1*c1*c1*(gradient4[gi0][0]*d1.x + gradient4[gi0][1]*d1.y + gradient4[gi0][2]*d1.z + gradient4[gi0][3]*d1.w); + + if(c2 < 0) + n2 = 0; + else + n2 = c2*c2*c2*c2*(gradient4[gi1][0]*d2.x + gradient4[gi1][1]*d2.y + gradient4[gi1][2]*d2.z + gradient4[gi1][3]*d2.w); + + if(c3 < 0) + n3 = 0; + else + n3 = c3*c3*c3*c3*(gradient4[gi2][0]*d3.x + gradient4[gi2][1]*d3.y + gradient4[gi2][2]*d3.z + gradient4[gi2][3]*d3.w); + + if(c4 < 0) + n4 = 0; + else + n4 = c4*c4*c4*c4*(gradient4[gi3][0]*d4.x + gradient4[gi3][1]*d4.y + gradient4[gi3][2]*d4.z + gradient4[gi3][3]*d4.w); + + if(c5 < 0) + n5 = 0; + else + n5 = c5*c5*c5*c5*(gradient4[gi4][0]*d5.x + gradient4[gi4][1]*d5.y + gradient4[gi4][2]*d5.z + gradient4[gi4][3]*d5.w); + + return (n1+n2+n3+n4+n5)*27.f; + } } diff --git a/src/Nazara/Physics/Geom.cpp b/src/Nazara/Physics/Geom.cpp index e2676a0df..29279c64c 100644 --- a/src/Nazara/Physics/Geom.cpp +++ b/src/Nazara/Physics/Geom.cpp @@ -8,429 +8,432 @@ #include #include -namespace +namespace Nz { - NzPhysGeomRef CreateGeomFromPrimitive(const NzPrimitive& primitive) + namespace { - switch (primitive.type) + PhysGeomRef CreateGeomFromPrimitive(const Primitive& primitive) { - case nzPrimitiveType_Box: - return NzBoxGeom::New(primitive.box.lengths, primitive.matrix); + switch (primitive.type) + { + case PrimitiveType_Box: + return BoxGeom::New(primitive.box.lengths, primitive.matrix); - case nzPrimitiveType_Cone: - return NzConeGeom::New(primitive.cone.length, primitive.cone.radius, primitive.matrix); + case PrimitiveType_Cone: + return ConeGeom::New(primitive.cone.length, primitive.cone.radius, primitive.matrix); - case nzPrimitiveType_Plane: - return NzBoxGeom::New(NzVector3f(primitive.plane.size.x, 0.01f, primitive.plane.size.y), primitive.matrix); - ///TODO: PlaneGeom? + case PrimitiveType_Plane: + return BoxGeom::New(Vector3f(primitive.plane.size.x, 0.01f, primitive.plane.size.y), primitive.matrix); + ///TODO: PlaneGeom? - case nzPrimitiveType_Sphere: - return NzSphereGeom::New(primitive.sphere.size, primitive.matrix.GetTranslation()); + case PrimitiveType_Sphere: + return SphereGeom::New(primitive.sphere.size, primitive.matrix.GetTranslation()); + } + + NazaraError("Primitive type not handled (0x" + String::Number(primitive.type, 16) + ')'); + return PhysGeomRef(); } - - NazaraError("Primitive type not handled (0x" + NzString::Number(primitive.type, 16) + ')'); - return NzPhysGeomRef(); } -} -NzPhysGeom::~NzPhysGeom() -{ - for (auto& pair : m_handles) - NewtonDestroyCollision(pair.second); -} - -NzBoxf NzPhysGeom::ComputeAABB(const NzVector3f& translation, const NzQuaternionf& rotation, const NzVector3f& scale) const -{ - return ComputeAABB(NzMatrix4f::Transform(translation, rotation), scale); -} - -NzBoxf NzPhysGeom::ComputeAABB(const NzMatrix4f& offsetMatrix, const NzVector3f& scale) const -{ - NzVector3f min, max; - - // Si nous n'avons aucune instance, nous en créons une temporaire - if (m_handles.empty()) + PhysGeom::~PhysGeom() { - NzPhysWorld world; + for (auto& pair : m_handles) + NewtonDestroyCollision(pair.second); + } - NewtonCollision* collision = CreateHandle(&world); + Boxf PhysGeom::ComputeAABB(const Vector3f& translation, const Quaternionf& rotation, const Vector3f& scale) const + { + return ComputeAABB(Matrix4f::Transform(translation, rotation), scale); + } + + Boxf PhysGeom::ComputeAABB(const Matrix4f& offsetMatrix, const Vector3f& scale) const + { + Vector3f min, max; + + // Si nous n'avons aucune instance, nous en créons une temporaire + if (m_handles.empty()) { - NewtonCollisionCalculateAABB(collision, offsetMatrix, min, max); + PhysWorld world; + + NewtonCollision* collision = CreateHandle(&world); + { + NewtonCollisionCalculateAABB(collision, offsetMatrix, min, max); + } + NewtonDestroyCollision(collision); } - NewtonDestroyCollision(collision); + else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute façon) + NewtonCollisionCalculateAABB(m_handles.begin()->second, offsetMatrix, min, max); + + return Boxf(scale * min, scale * max); } - else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute façon) - NewtonCollisionCalculateAABB(m_handles.begin()->second, offsetMatrix, min, max); - return NzBoxf(scale * min, scale * max); -} - -void NzPhysGeom::ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) const -{ - float inertiaMatrix[3]; - float origin[3]; - - // Si nous n'avons aucune instance, nous en créons une temporaire - if (m_handles.empty()) + void PhysGeom::ComputeInertialMatrix(Vector3f* inertia, Vector3f* center) const { - NzPhysWorld world; + float inertiaMatrix[3]; + float origin[3]; - NewtonCollision* collision = CreateHandle(&world); + // Si nous n'avons aucune instance, nous en créons une temporaire + if (m_handles.empty()) { - NewtonConvexCollisionCalculateInertialMatrix(collision, inertiaMatrix, origin); + PhysWorld world; + + NewtonCollision* collision = CreateHandle(&world); + { + NewtonConvexCollisionCalculateInertialMatrix(collision, inertiaMatrix, origin); + } + NewtonDestroyCollision(collision); } - NewtonDestroyCollision(collision); + else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute façon) + NewtonConvexCollisionCalculateInertialMatrix(m_handles.begin()->second, inertiaMatrix, origin); + + if (inertia) + inertia->Set(inertiaMatrix); + + if (center) + center->Set(origin); } - else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute façon) - NewtonConvexCollisionCalculateInertialMatrix(m_handles.begin()->second, inertiaMatrix, origin); - if (inertia) - inertia->Set(inertiaMatrix); - - if (center) - center->Set(origin); -} - -float NzPhysGeom::ComputeVolume() const -{ - float volume; - - // Si nous n'avons aucune instance, nous en créons une temporaire - if (m_handles.empty()) + float PhysGeom::ComputeVolume() const { - NzPhysWorld world; + float volume; - NewtonCollision* collision = CreateHandle(&world); + // Si nous n'avons aucune instance, nous en créons une temporaire + if (m_handles.empty()) { - volume = NewtonConvexCollisionCalculateVolume(collision); + PhysWorld world; + + NewtonCollision* collision = CreateHandle(&world); + { + volume = NewtonConvexCollisionCalculateVolume(collision); + } + NewtonDestroyCollision(collision); } - NewtonDestroyCollision(collision); + else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute façon) + volume = NewtonConvexCollisionCalculateVolume(m_handles.begin()->second); + + return volume; } - else // Sinon on utilise une instance au hasard (elles sont toutes identiques de toute façon) - volume = NewtonConvexCollisionCalculateVolume(m_handles.begin()->second); - return volume; -} - -NewtonCollision* NzPhysGeom::GetHandle(NzPhysWorld* world) const -{ - auto it = m_handles.find(world); - if (it == m_handles.end()) - it = m_handles.insert(std::make_pair(world, CreateHandle(world))).first; - - return it->second; -} - -NzPhysGeomRef NzPhysGeom::Build(const NzPrimitiveList& list) -{ - unsigned int primitiveCount = list.GetSize(); - - #if NAZARA_PHYSICS_SAFE - if (primitiveCount == 0) + NewtonCollision* PhysGeom::GetHandle(PhysWorld* world) const { - NazaraError("PrimitiveList must have at least one primitive"); - return nullptr; + auto it = m_handles.find(world); + if (it == m_handles.end()) + it = m_handles.insert(std::make_pair(world, CreateHandle(world))).first; + + return it->second; } - #endif - if (primitiveCount > 1) + PhysGeomRef PhysGeom::Build(const PrimitiveList& list) { - std::vector geoms(primitiveCount); + unsigned int primitiveCount = list.GetSize(); - for (unsigned int i = 0; i < primitiveCount; ++i) - geoms[i] = CreateGeomFromPrimitive(list.GetPrimitive(i)); - - return NzCompoundGeom::New(&geoms[0], primitiveCount); - } - else - return CreateGeomFromPrimitive(list.GetPrimitive(0)); -} - -NzPhysGeomLibrary::LibraryMap NzPhysGeom::s_library; - -/********************************** BoxGeom **********************************/ - -NzBoxGeom::NzBoxGeom(const NzVector3f& lengths, const NzMatrix4f& transformMatrix) : -m_matrix(transformMatrix), -m_lengths(lengths) -{ -} - -NzBoxGeom::NzBoxGeom(const NzVector3f& lengths, const NzVector3f& translation, const NzQuaternionf& rotation) : -NzBoxGeom(lengths, NzMatrix4f::Transform(translation, rotation)) -{ -} - -NzBoxf NzBoxGeom::ComputeAABB(const NzMatrix4f& offsetMatrix, const NzVector3f& scale) const -{ - NzVector3f halfLengths(m_lengths * 0.5f); - - NzBoxf aabb(-halfLengths.x, -halfLengths.y, -halfLengths.z, m_lengths.x, m_lengths.y, m_lengths.z); - aabb.Transform(offsetMatrix, true); - aabb *= scale; - - return aabb; -} - -float NzBoxGeom::ComputeVolume() const -{ - return m_lengths.x * m_lengths.y * m_lengths.z; -} - -NzVector3f NzBoxGeom::GetLengths() const -{ - return m_lengths; -} - -nzGeomType NzBoxGeom::GetType() const -{ - return nzGeomType_Box; -} - -NewtonCollision* NzBoxGeom::CreateHandle(NzPhysWorld* world) const -{ - return NewtonCreateBox(world->GetHandle(), m_lengths.x, m_lengths.y, m_lengths.z, 0, m_matrix); -} - -/******************************** CapsuleGeom ********************************/ - -NzCapsuleGeom::NzCapsuleGeom(float length, float radius, const NzMatrix4f& transformMatrix) : -m_matrix(transformMatrix), -m_length(length), -m_radius(radius) -{ -} - -NzCapsuleGeom::NzCapsuleGeom(float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : -NzCapsuleGeom(length, radius, NzMatrix4f::Transform(translation, rotation)) -{ -} - -float NzCapsuleGeom::GetLength() const -{ - return m_length; -} - -float NzCapsuleGeom::GetRadius() const -{ - return m_radius; -} - -nzGeomType NzCapsuleGeom::GetType() const -{ - return nzGeomType_Capsule; -} - -NewtonCollision* NzCapsuleGeom::CreateHandle(NzPhysWorld* world) const -{ - return NewtonCreateCapsule(world->GetHandle(), m_radius, m_length, 0, m_matrix); -} - -/******************************* CompoundGeom ********************************/ - -NzCompoundGeom::NzCompoundGeom(NzPhysGeom** geoms, unsigned int geomCount) -{ - m_geoms.reserve(geomCount); - for (unsigned int i = 0; i < geomCount; ++i) - m_geoms.emplace_back(geoms[i]); -} - -const std::vector& NzCompoundGeom::GetGeoms() const -{ - return m_geoms; -} - -nzGeomType NzCompoundGeom::GetType() const -{ - return nzGeomType_Compound; -} - -NewtonCollision* NzCompoundGeom::CreateHandle(NzPhysWorld* world) const -{ - NewtonCollision* compoundCollision = NewtonCreateCompoundCollision(world->GetHandle(), 0); - - NewtonCompoundCollisionBeginAddRemove(compoundCollision); - for (const NzPhysGeomRef& geom : m_geoms) - { - if (geom->GetType() == nzGeomType_Compound) + #if NAZARA_PHYSICS_SAFE + if (primitiveCount == 0) { - NzCompoundGeom* compoundGeom = static_cast(geom.Get()); - for (const NzPhysGeomRef& piece : compoundGeom->GetGeoms()) - NewtonCompoundCollisionAddSubCollision(compoundCollision, piece->GetHandle(world)); + NazaraError("PrimitiveList must have at least one primitive"); + return nullptr; + } + #endif + + if (primitiveCount > 1) + { + std::vector geoms(primitiveCount); + + for (unsigned int i = 0; i < primitiveCount; ++i) + geoms[i] = CreateGeomFromPrimitive(list.GetPrimitive(i)); + + return CompoundGeom::New(&geoms[0], primitiveCount); } else - NewtonCompoundCollisionAddSubCollision(compoundCollision, geom->GetHandle(world)); + return CreateGeomFromPrimitive(list.GetPrimitive(0)); } - NewtonCompoundCollisionEndAddRemove(compoundCollision); - return compoundCollision; -} + PhysGeomLibrary::LibraryMap PhysGeom::s_library; -/********************************* ConeGeom **********************************/ + /********************************** BoxGeom **********************************/ -NzConeGeom::NzConeGeom(float length, float radius, const NzMatrix4f& transformMatrix) : -m_matrix(transformMatrix), -m_length(length), -m_radius(radius) -{ -} - -NzConeGeom::NzConeGeom(float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : -NzConeGeom(length, radius, NzMatrix4f::Transform(translation, rotation)) -{ -} - -float NzConeGeom::GetLength() const -{ - return m_length; -} - -float NzConeGeom::GetRadius() const -{ - return m_radius; -} - -nzGeomType NzConeGeom::GetType() const -{ - return nzGeomType_Cone; -} - -NewtonCollision* NzConeGeom::CreateHandle(NzPhysWorld* world) const -{ - return NewtonCreateCone(world->GetHandle(), m_radius, m_length, 0, m_matrix); -} - -/****************************** ConvexHullGeom *******************************/ - -NzConvexHullGeom::NzConvexHullGeom(const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const NzMatrix4f& transformMatrix) : -m_matrix(transformMatrix), -m_tolerance(tolerance), -m_vertexStride(stride) -{ - const nzUInt8* ptr = static_cast(vertices); - - m_vertices.resize(vertexCount); - if (stride != sizeof(NzVector3f)) + BoxGeom::BoxGeom(const Vector3f& lengths, const Matrix4f& transformMatrix) : + m_matrix(transformMatrix), + m_lengths(lengths) { - for (unsigned int i = 0; i < vertexCount; ++i) - m_vertices[i] = *reinterpret_cast(ptr + stride*i); } - else // Fast path - std::memcpy(m_vertices.data(), vertices, vertexCount*sizeof(NzVector3f)); -} - -NzConvexHullGeom::NzConvexHullGeom(const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const NzVector3f& translation, const NzQuaternionf& rotation) : -NzConvexHullGeom(vertices, vertexCount, stride, tolerance, NzMatrix4f::Transform(translation, rotation)) -{ -} - -nzGeomType NzConvexHullGeom::GetType() const -{ - return nzGeomType_Compound; -} - -NewtonCollision* NzConvexHullGeom::CreateHandle(NzPhysWorld* world) const -{ - return NewtonCreateConvexHull(world->GetHandle(), m_vertices.size(), reinterpret_cast(m_vertices.data()), sizeof(NzVector3f), m_tolerance, 0, m_matrix); -} - -/******************************* CylinderGeom ********************************/ - -NzCylinderGeom::NzCylinderGeom(float length, float radius, const NzMatrix4f& transformMatrix) : -m_matrix(transformMatrix), -m_length(length), -m_radius(radius) -{ -} - -NzCylinderGeom::NzCylinderGeom(float length, float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : -NzCylinderGeom(length, radius, NzMatrix4f::Transform(translation, rotation)) -{ -} - -float NzCylinderGeom::GetLength() const -{ - return m_length; -} - -float NzCylinderGeom::GetRadius() const -{ - return m_radius; -} - -nzGeomType NzCylinderGeom::GetType() const -{ - return nzGeomType_Cylinder; -} - -NewtonCollision* NzCylinderGeom::CreateHandle(NzPhysWorld* world) const -{ - return NewtonCreateCylinder(world->GetHandle(), m_radius, m_length, 0, m_matrix); -} - -/********************************* NullGeom **********************************/ - -NzNullGeom::NzNullGeom() -{ -} - -nzGeomType NzNullGeom::GetType() const -{ - return nzGeomType_Null; -} - -void NzNullGeom::ComputeInertialMatrix(NzVector3f* inertia, NzVector3f* center) const -{ - if (inertia) - inertia->MakeUnit(); - - if (center) - center->MakeZero(); -} - -NewtonCollision* NzNullGeom::CreateHandle(NzPhysWorld* world) const -{ - return NewtonCreateNull(world->GetHandle()); -} - -/******************************** SphereGeom *********************************/ - -NzSphereGeom::NzSphereGeom(float radius, const NzMatrix4f& transformMatrix) : -NzSphereGeom(radius, transformMatrix.GetTranslation()) -{ -} - -NzSphereGeom::NzSphereGeom(float radius, const NzVector3f& translation, const NzQuaternionf& rotation) : -m_position(translation), -m_radius(radius) -{ - NazaraUnused(rotation); -} - -NzBoxf NzSphereGeom::ComputeAABB(const NzMatrix4f& offsetMatrix, const NzVector3f& scale) const -{ - NzVector3f size(m_radius * NazaraSuffixMacro(M_SQRT3, f) * scale); - NzVector3f position(offsetMatrix.GetTranslation()); - - return NzBoxf(position - size, position + size); -} - -float NzSphereGeom::ComputeVolume() const -{ - return float(M_PI) * m_radius * m_radius * m_radius / 3.f; -} - -float NzSphereGeom::GetRadius() const -{ - return m_radius; -} - -nzGeomType NzSphereGeom::GetType() const -{ - return nzGeomType_Sphere; -} - -NewtonCollision* NzSphereGeom::CreateHandle(NzPhysWorld* world) const -{ - return NewtonCreateSphere(world->GetHandle(), m_radius, 0, NzMatrix4f::Translate(m_position)); + + BoxGeom::BoxGeom(const Vector3f& lengths, const Vector3f& translation, const Quaternionf& rotation) : + BoxGeom(lengths, Matrix4f::Transform(translation, rotation)) + { + } + + Boxf BoxGeom::ComputeAABB(const Matrix4f& offsetMatrix, const Vector3f& scale) const + { + Vector3f halfLengths(m_lengths * 0.5f); + + Boxf aabb(-halfLengths.x, -halfLengths.y, -halfLengths.z, m_lengths.x, m_lengths.y, m_lengths.z); + aabb.Transform(offsetMatrix, true); + aabb *= scale; + + return aabb; + } + + float BoxGeom::ComputeVolume() const + { + return m_lengths.x * m_lengths.y * m_lengths.z; + } + + Vector3f BoxGeom::GetLengths() const + { + return m_lengths; + } + + GeomType BoxGeom::GetType() const + { + return GeomType_Box; + } + + NewtonCollision* BoxGeom::CreateHandle(PhysWorld* world) const + { + return NewtonCreateBox(world->GetHandle(), m_lengths.x, m_lengths.y, m_lengths.z, 0, m_matrix); + } + + /******************************** CapsuleGeom ********************************/ + + CapsuleGeom::CapsuleGeom(float length, float radius, const Matrix4f& transformMatrix) : + m_matrix(transformMatrix), + m_length(length), + m_radius(radius) + { + } + + CapsuleGeom::CapsuleGeom(float length, float radius, const Vector3f& translation, const Quaternionf& rotation) : + CapsuleGeom(length, radius, Matrix4f::Transform(translation, rotation)) + { + } + + float CapsuleGeom::GetLength() const + { + return m_length; + } + + float CapsuleGeom::GetRadius() const + { + return m_radius; + } + + GeomType CapsuleGeom::GetType() const + { + return GeomType_Capsule; + } + + NewtonCollision* CapsuleGeom::CreateHandle(PhysWorld* world) const + { + return NewtonCreateCapsule(world->GetHandle(), m_radius, m_length, 0, m_matrix); + } + + /******************************* CompoundGeom ********************************/ + + CompoundGeom::CompoundGeom(PhysGeom** geoms, unsigned int geomCount) + { + m_geoms.reserve(geomCount); + for (unsigned int i = 0; i < geomCount; ++i) + m_geoms.emplace_back(geoms[i]); + } + + const std::vector& CompoundGeom::GetGeoms() const + { + return m_geoms; + } + + GeomType CompoundGeom::GetType() const + { + return GeomType_Compound; + } + + NewtonCollision* CompoundGeom::CreateHandle(PhysWorld* world) const + { + NewtonCollision* compoundCollision = NewtonCreateCompoundCollision(world->GetHandle(), 0); + + NewtonCompoundCollisionBeginAddRemove(compoundCollision); + for (const PhysGeomRef& geom : m_geoms) + { + if (geom->GetType() == GeomType_Compound) + { + CompoundGeom* compoundGeom = static_cast(geom.Get()); + for (const PhysGeomRef& piece : compoundGeom->GetGeoms()) + NewtonCompoundCollisionAddSubCollision(compoundCollision, piece->GetHandle(world)); + } + else + NewtonCompoundCollisionAddSubCollision(compoundCollision, geom->GetHandle(world)); + } + NewtonCompoundCollisionEndAddRemove(compoundCollision); + + return compoundCollision; + } + + /********************************* ConeGeom **********************************/ + + ConeGeom::ConeGeom(float length, float radius, const Matrix4f& transformMatrix) : + m_matrix(transformMatrix), + m_length(length), + m_radius(radius) + { + } + + ConeGeom::ConeGeom(float length, float radius, const Vector3f& translation, const Quaternionf& rotation) : + ConeGeom(length, radius, Matrix4f::Transform(translation, rotation)) + { + } + + float ConeGeom::GetLength() const + { + return m_length; + } + + float ConeGeom::GetRadius() const + { + return m_radius; + } + + GeomType ConeGeom::GetType() const + { + return GeomType_Cone; + } + + NewtonCollision* ConeGeom::CreateHandle(PhysWorld* world) const + { + return NewtonCreateCone(world->GetHandle(), m_radius, m_length, 0, m_matrix); + } + + /****************************** ConvexHullGeom *******************************/ + + ConvexHullGeom::ConvexHullGeom(const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const Matrix4f& transformMatrix) : + m_matrix(transformMatrix), + m_tolerance(tolerance), + m_vertexStride(stride) + { + const UInt8* ptr = static_cast(vertices); + + m_vertices.resize(vertexCount); + if (stride != sizeof(Vector3f)) + { + for (unsigned int i = 0; i < vertexCount; ++i) + m_vertices[i] = *reinterpret_cast(ptr + stride*i); + } + else // Fast path + std::memcpy(m_vertices.data(), vertices, vertexCount*sizeof(Vector3f)); + } + + ConvexHullGeom::ConvexHullGeom(const void* vertices, unsigned int vertexCount, unsigned int stride, float tolerance, const Vector3f& translation, const Quaternionf& rotation) : + ConvexHullGeom(vertices, vertexCount, stride, tolerance, Matrix4f::Transform(translation, rotation)) + { + } + + GeomType ConvexHullGeom::GetType() const + { + return GeomType_Compound; + } + + NewtonCollision* ConvexHullGeom::CreateHandle(PhysWorld* world) const + { + return NewtonCreateConvexHull(world->GetHandle(), m_vertices.size(), reinterpret_cast(m_vertices.data()), sizeof(Vector3f), m_tolerance, 0, m_matrix); + } + + /******************************* CylinderGeom ********************************/ + + NzCylinderGeom::NzCylinderGeom(float length, float radius, const Matrix4f& transformMatrix) : + m_matrix(transformMatrix), + m_length(length), + m_radius(radius) + { + } + + NzCylinderGeom::NzCylinderGeom(float length, float radius, const Vector3f& translation, const Quaternionf& rotation) : + NzCylinderGeom(length, radius, Matrix4f::Transform(translation, rotation)) + { + } + + float NzCylinderGeom::GetLength() const + { + return m_length; + } + + float NzCylinderGeom::GetRadius() const + { + return m_radius; + } + + GeomType NzCylinderGeom::GetType() const + { + return GeomType_Cylinder; + } + + NewtonCollision* NzCylinderGeom::CreateHandle(PhysWorld* world) const + { + return NewtonCreateCylinder(world->GetHandle(), m_radius, m_length, 0, m_matrix); + } + + /********************************* NullGeom **********************************/ + + NullGeom::NullGeom() + { + } + + GeomType NullGeom::GetType() const + { + return GeomType_Null; + } + + void NullGeom::ComputeInertialMatrix(Vector3f* inertia, Vector3f* center) const + { + if (inertia) + inertia->MakeUnit(); + + if (center) + center->MakeZero(); + } + + NewtonCollision* NullGeom::CreateHandle(PhysWorld* world) const + { + return NewtonCreateNull(world->GetHandle()); + } + + /******************************** SphereGeom *********************************/ + + SphereGeom::SphereGeom(float radius, const Matrix4f& transformMatrix) : + SphereGeom(radius, transformMatrix.GetTranslation()) + { + } + + SphereGeom::SphereGeom(float radius, const Vector3f& translation, const Quaternionf& rotation) : + m_position(translation), + m_radius(radius) + { + NazaraUnused(rotation); + } + + Boxf SphereGeom::ComputeAABB(const Matrix4f& offsetMatrix, const Vector3f& scale) const + { + Vector3f size(m_radius * NazaraSuffixMacro(M_SQRT3, f) * scale); + Vector3f position(offsetMatrix.GetTranslation()); + + return Boxf(position - size, position + size); + } + + float SphereGeom::ComputeVolume() const + { + return float(M_PI) * m_radius * m_radius * m_radius / 3.f; + } + + float SphereGeom::GetRadius() const + { + return m_radius; + } + + GeomType SphereGeom::GetType() const + { + return GeomType_Sphere; + } + + NewtonCollision* SphereGeom::CreateHandle(PhysWorld* world) const + { + return NewtonCreateSphere(world->GetHandle(), m_radius, 0, Matrix4f::Translate(m_position)); + } } diff --git a/src/Nazara/Physics/PhysObject.cpp b/src/Nazara/Physics/PhysObject.cpp index a0d1dd164..1b4816ee6 100644 --- a/src/Nazara/Physics/PhysObject.cpp +++ b/src/Nazara/Physics/PhysObject.cpp @@ -10,356 +10,359 @@ #include #include -NzPhysObject::NzPhysObject(NzPhysWorld* world, const NzMatrix4f& mat) : -NzPhysObject(world, NzNullGeom::New(), mat) +namespace Nz { -} - -NzPhysObject::NzPhysObject(NzPhysWorld* world, NzPhysGeomRef geom, const NzMatrix4f& mat) : -m_matrix(mat), -m_geom(std::move(geom)), -m_forceAccumulator(NzVector3f::Zero()), -m_torqueAccumulator(NzVector3f::Zero()), -m_world(world), -m_gravityFactor(1.f), -m_mass(0.f) -{ - NazaraAssert(m_world, "Invalid world"); - - if (!m_geom) - m_geom = NzNullGeom::New(); - - m_body = NewtonCreateDynamicBody(m_world->GetHandle(), m_geom->GetHandle(m_world), m_matrix); - NewtonBodySetUserData(m_body, this); -} - -NzPhysObject::NzPhysObject(const NzPhysObject& object) : -m_matrix(object.m_matrix), -m_geom(object.m_geom), -m_forceAccumulator(NzVector3f::Zero()), -m_torqueAccumulator(NzVector3f::Zero()), -m_world(object.m_world), -m_gravityFactor(object.m_gravityFactor), -m_mass(0.f) -{ - NazaraAssert(m_world, "Invalid world"); - NazaraAssert(m_geom, "Invalid geometry"); - - m_body = NewtonCreateDynamicBody(m_world->GetHandle(), m_geom->GetHandle(m_world), m_matrix); - NewtonBodySetUserData(m_body, this); - SetMass(object.m_mass); -} - -NzPhysObject::NzPhysObject(NzPhysObject&& object) : -m_matrix(std::move(object.m_matrix)), -m_geom(std::move(object.m_geom)), -m_forceAccumulator(std::move(object.m_forceAccumulator)), -m_torqueAccumulator(std::move(object.m_torqueAccumulator)), -m_body(object.m_body), -m_world(object.m_world), -m_gravityFactor(object.m_gravityFactor), -m_mass(object.m_mass) -{ - object.m_body = nullptr; -} - -NzPhysObject::~NzPhysObject() -{ - if (m_body) - NewtonDestroyBody(m_world->GetHandle(), m_body); -} - -void NzPhysObject::AddForce(const NzVector3f& force, nzCoordSys coordSys) -{ - switch (coordSys) + PhysObject::PhysObject(PhysWorld* world, const Matrix4f& mat) : + PhysObject(world, NullGeom::New(), mat) { - case nzCoordSys_Global: - m_forceAccumulator += force; - break; - - case nzCoordSys_Local: - m_forceAccumulator += GetRotation() * force; - break; } - // On réveille le corps pour que le callback soit appelé et que les forces soient appliquées - NewtonBodySetSleepState(m_body, 0); -} - -void NzPhysObject::AddForce(const NzVector3f& force, const NzVector3f& point, nzCoordSys coordSys) -{ - switch (coordSys) + PhysObject::PhysObject(PhysWorld* world, PhysGeomRef geom, const Matrix4f& mat) : + m_matrix(mat), + m_geom(std::move(geom)), + m_forceAccumulator(Vector3f::Zero()), + m_torqueAccumulator(Vector3f::Zero()), + m_world(world), + m_gravityFactor(1.f), + m_mass(0.f) { - case nzCoordSys_Global: - m_forceAccumulator += force; - m_torqueAccumulator += NzVector3f::CrossProduct(point - GetMassCenter(nzCoordSys_Global), force); - break; + NazaraAssert(m_world, "Invalid world"); - case nzCoordSys_Local: - return AddForce(m_matrix.Transform(force, 0.f), m_matrix.Transform(point), nzCoordSys_Global); + if (!m_geom) + m_geom = NullGeom::New(); + + m_body = NewtonCreateDynamicBody(m_world->GetHandle(), m_geom->GetHandle(m_world), m_matrix); + NewtonBodySetUserData(m_body, this); } - // On réveille le corps pour que le callback soit appelé et que les forces soient appliquées - NewtonBodySetSleepState(m_body, 0); -} - -void NzPhysObject::AddTorque(const NzVector3f& torque, nzCoordSys coordSys) -{ - switch (coordSys) + PhysObject::PhysObject(const PhysObject& object) : + m_matrix(object.m_matrix), + m_geom(object.m_geom), + m_forceAccumulator(Vector3f::Zero()), + m_torqueAccumulator(Vector3f::Zero()), + m_world(object.m_world), + m_gravityFactor(object.m_gravityFactor), + m_mass(0.f) { - case nzCoordSys_Global: - m_torqueAccumulator += torque; - break; + NazaraAssert(m_world, "Invalid world"); + NazaraAssert(m_geom, "Invalid geometry"); - case nzCoordSys_Local: - m_torqueAccumulator += m_matrix.Transform(torque, 0.f); - break; + m_body = NewtonCreateDynamicBody(m_world->GetHandle(), m_geom->GetHandle(m_world), m_matrix); + NewtonBodySetUserData(m_body, this); + SetMass(object.m_mass); } - // On réveille le corps pour que le callback soit appelé et que les forces soient appliquées - NewtonBodySetSleepState(m_body, 0); -} - -void NzPhysObject::EnableAutoSleep(bool autoSleep) -{ - NewtonBodySetAutoSleep(m_body, autoSleep); -} - -NzBoxf NzPhysObject::GetAABB() const -{ - NzVector3f min, max; - NewtonBodyGetAABB(m_body, min, max); - - return NzBoxf(min, max); -} - -NzVector3f NzPhysObject::GetAngularVelocity() const -{ - NzVector3f angularVelocity; - NewtonBodyGetOmega(m_body, angularVelocity); - - return angularVelocity; -} - -const NzPhysGeomRef& NzPhysObject::GetGeom() const -{ - return m_geom; -} - -float NzPhysObject::GetGravityFactor() const -{ - return m_gravityFactor; -} - -NewtonBody* NzPhysObject::GetHandle() const -{ - return m_body; -} - -float NzPhysObject::GetMass() const -{ - return m_mass; -} - -NzVector3f NzPhysObject::GetMassCenter(nzCoordSys coordSys) const -{ - NzVector3f center; - NewtonBodyGetCentreOfMass(m_body, center); - - switch (coordSys) + PhysObject::PhysObject(PhysObject&& object) : + m_matrix(std::move(object.m_matrix)), + m_geom(std::move(object.m_geom)), + m_forceAccumulator(std::move(object.m_forceAccumulator)), + m_torqueAccumulator(std::move(object.m_torqueAccumulator)), + m_body(object.m_body), + m_world(object.m_world), + m_gravityFactor(object.m_gravityFactor), + m_mass(object.m_mass) { - case nzCoordSys_Global: - center = m_matrix.Transform(center); - break; - - case nzCoordSys_Local: - break; // Aucune opération à effectuer sur le centre de rotation + object.m_body = nullptr; } - return center; -} - -const NzMatrix4f& NzPhysObject::GetMatrix() const -{ - return m_matrix; -} - -NzVector3f NzPhysObject::GetPosition() const -{ - return m_matrix.GetTranslation(); -} - -NzQuaternionf NzPhysObject::GetRotation() const -{ - return m_matrix.GetRotation(); -} - -NzVector3f NzPhysObject::GetVelocity() const -{ - NzVector3f velocity; - NewtonBodyGetVelocity(m_body, velocity); - - return velocity; -} - -bool NzPhysObject::IsAutoSleepEnabled() const -{ - return NewtonBodyGetAutoSleep(m_body) != 0; -} - -bool NzPhysObject::IsMoveable() const -{ - return m_mass > 0.f; -} - -bool NzPhysObject::IsSleeping() const -{ - return NewtonBodyGetSleepState(m_body) != 0; -} - -void NzPhysObject::SetAngularVelocity(const NzVector3f& angularVelocity) -{ - NewtonBodySetOmega(m_body, angularVelocity); -} - -void NzPhysObject::SetGeom(NzPhysGeomRef geom) -{ - if (m_geom.Get() != geom) + PhysObject::~PhysObject() { - if (geom) - m_geom = geom; - else - m_geom = NzNullGeom::New(); - - NewtonBodySetCollision(m_body, m_geom->GetHandle(m_world)); - } -} - -void NzPhysObject::SetGravityFactor(float gravityFactor) -{ - m_gravityFactor = gravityFactor; -} - -void NzPhysObject::SetMass(float mass) -{ - if (m_mass > 0.f) - { - float Ix, Iy, Iz; - NewtonBodyGetMassMatrix(m_body, &m_mass, &Ix, &Iy, &Iz); - float scale = mass/m_mass; - NewtonBodySetMassMatrix(m_body, mass, Ix*scale, Iy*scale, Iz*scale); - } - else if (mass > 0.f) - { - NzVector3f inertia, origin; - m_geom->ComputeInertialMatrix(&inertia, &origin); - - NewtonBodySetCentreOfMass(m_body, &origin.x); - NewtonBodySetMassMatrix(m_body, mass, inertia.x*mass, inertia.y*mass, inertia.z*mass); - NewtonBodySetForceAndTorqueCallback(m_body, &ForceAndTorqueCallback); - NewtonBodySetTransformCallback(m_body, &TransformCallback); + if (m_body) + NewtonDestroyBody(m_world->GetHandle(), m_body); } - m_mass = mass; -} - -void NzPhysObject::SetMassCenter(const NzVector3f& center) -{ - if (m_mass > 0.f) - NewtonBodySetCentreOfMass(m_body, center); -} - -void NzPhysObject::SetPosition(const NzVector3f& position) -{ - m_matrix.SetTranslation(position); - UpdateBody(); -} - -void NzPhysObject::SetRotation(const NzQuaternionf& rotation) -{ - m_matrix.SetRotation(rotation); - UpdateBody(); -} - -void NzPhysObject::SetVelocity(const NzVector3f& velocity) -{ - NewtonBodySetVelocity(m_body, velocity); -} - -NzPhysObject& NzPhysObject::operator=(const NzPhysObject& object) -{ - NzPhysObject physObj(object); - return operator=(std::move(physObj)); -} - -void NzPhysObject::UpdateBody() -{ - NewtonBodySetMatrix(m_body, m_matrix); - - if (NzNumberEquals(m_mass, 0.f)) + void PhysObject::AddForce(const Vector3f& force, CoordSys coordSys) { - // http://newtondynamics.com/wiki/index.php5?title=Can_i_dynamicly_move_a_TriMesh%3F - NzVector3f min, max; + switch (coordSys) + { + case CoordSys_Global: + m_forceAccumulator += force; + break; + + case CoordSys_Local: + m_forceAccumulator += GetRotation() * force; + break; + } + + // On réveille le corps pour que le callback soit appelé et que les forces soient appliquées + NewtonBodySetSleepState(m_body, 0); + } + + void PhysObject::AddForce(const Vector3f& force, const Vector3f& point, CoordSys coordSys) + { + switch (coordSys) + { + case CoordSys_Global: + m_forceAccumulator += force; + m_torqueAccumulator += Vector3f::CrossProduct(point - GetMassCenter(CoordSys_Global), force); + break; + + case CoordSys_Local: + return AddForce(m_matrix.Transform(force, 0.f), m_matrix.Transform(point), CoordSys_Global); + } + + // On réveille le corps pour que le callback soit appelé et que les forces soient appliquées + NewtonBodySetSleepState(m_body, 0); + } + + void PhysObject::AddTorque(const Vector3f& torque, CoordSys coordSys) + { + switch (coordSys) + { + case CoordSys_Global: + m_torqueAccumulator += torque; + break; + + case CoordSys_Local: + m_torqueAccumulator += m_matrix.Transform(torque, 0.f); + break; + } + + // On réveille le corps pour que le callback soit appelé et que les forces soient appliquées + NewtonBodySetSleepState(m_body, 0); + } + + void PhysObject::EnableAutoSleep(bool autoSleep) + { + NewtonBodySetAutoSleep(m_body, autoSleep); + } + + Boxf PhysObject::GetAABB() const + { + Vector3f min, max; NewtonBodyGetAABB(m_body, min, max); - NewtonWorldForEachBodyInAABBDo(m_world->GetHandle(), min, max, [](const NewtonBody* const body, void* const userData) - { - NazaraUnused(userData); - NewtonBodySetSleepState(body, 0); - }, nullptr); + return Boxf(min, max); } - /*for (std::set::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it) - (*it)->PhysObjectOnUpdate(this);*/ -} - -NzPhysObject& NzPhysObject::operator=(NzPhysObject&& object) -{ - if (m_body) - NewtonDestroyBody(m_world->GetHandle(), m_body); - - m_body = object.m_body; - m_forceAccumulator = std::move(object.m_forceAccumulator); - m_geom = std::move(object.m_geom); - m_gravityFactor = object.m_gravityFactor; - m_mass = object.m_mass; - m_matrix = std::move(object.m_matrix); - m_torqueAccumulator = std::move(object.m_torqueAccumulator); - m_world = object.m_world; - - object.m_body = nullptr; - - return *this; -} - -void NzPhysObject::ForceAndTorqueCallback(const NewtonBody* body, float timeStep, int threadIndex) -{ - NazaraUnused(timeStep); - NazaraUnused(threadIndex); - - NzPhysObject* me = static_cast(NewtonBodyGetUserData(body)); - - if (!NzNumberEquals(me->m_gravityFactor, 0.f)) - me->m_forceAccumulator += me->m_world->GetGravity() * me->m_gravityFactor * me->m_mass; - - /*for (std::set::iterator it = me->m_listeners.begin(); it != me->m_listeners.end(); ++it) - (*it)->PhysObjectApplyForce(me);*/ - - NewtonBodySetForce(body, me->m_forceAccumulator); - NewtonBodySetTorque(body, me->m_torqueAccumulator); - - me->m_torqueAccumulator.Set(0.f); - me->m_forceAccumulator.Set(0.f); - - ///TODO: Implanter la force gyroscopique? -} - -void NzPhysObject::TransformCallback(const NewtonBody* body, const float* matrix, int threadIndex) -{ - NazaraUnused(threadIndex); - - NzPhysObject* me = static_cast(NewtonBodyGetUserData(body)); - me->m_matrix.Set(matrix); - - /*for (std::set::iterator it = me->m_listeners.begin(); it != me->m_listeners.end(); ++it) - (*it)->PhysObjectOnUpdate(me);*/ + + Vector3f PhysObject::GetAngularVelocity() const + { + Vector3f angularVelocity; + NewtonBodyGetOmega(m_body, angularVelocity); + + return angularVelocity; + } + + const PhysGeomRef& PhysObject::GetGeom() const + { + return m_geom; + } + + float PhysObject::GetGravityFactor() const + { + return m_gravityFactor; + } + + NewtonBody* PhysObject::GetHandle() const + { + return m_body; + } + + float PhysObject::GetMass() const + { + return m_mass; + } + + Vector3f PhysObject::GetMassCenter(CoordSys coordSys) const + { + Vector3f center; + NewtonBodyGetCentreOfMass(m_body, center); + + switch (coordSys) + { + case CoordSys_Global: + center = m_matrix.Transform(center); + break; + + case CoordSys_Local: + break; // Aucune opération à effectuer sur le centre de rotation + } + + return center; + } + + const Matrix4f& PhysObject::GetMatrix() const + { + return m_matrix; + } + + Vector3f PhysObject::GetPosition() const + { + return m_matrix.GetTranslation(); + } + + Quaternionf PhysObject::GetRotation() const + { + return m_matrix.GetRotation(); + } + + Vector3f PhysObject::GetVelocity() const + { + Vector3f velocity; + NewtonBodyGetVelocity(m_body, velocity); + + return velocity; + } + + bool PhysObject::IsAutoSleepEnabled() const + { + return NewtonBodyGetAutoSleep(m_body) != 0; + } + + bool PhysObject::IsMoveable() const + { + return m_mass > 0.f; + } + + bool PhysObject::IsSleeping() const + { + return NewtonBodyGetSleepState(m_body) != 0; + } + + void PhysObject::SetAngularVelocity(const Vector3f& angularVelocity) + { + NewtonBodySetOmega(m_body, angularVelocity); + } + + void PhysObject::SetGeom(PhysGeomRef geom) + { + if (m_geom.Get() != geom) + { + if (geom) + m_geom = geom; + else + m_geom = NullGeom::New(); + + NewtonBodySetCollision(m_body, m_geom->GetHandle(m_world)); + } + } + + void PhysObject::SetGravityFactor(float gravityFactor) + { + m_gravityFactor = gravityFactor; + } + + void PhysObject::SetMass(float mass) + { + if (m_mass > 0.f) + { + float Ix, Iy, Iz; + NewtonBodyGetMassMatrix(m_body, &m_mass, &Ix, &Iy, &Iz); + float scale = mass/m_mass; + NewtonBodySetMassMatrix(m_body, mass, Ix*scale, Iy*scale, Iz*scale); + } + else if (mass > 0.f) + { + Vector3f inertia, origin; + m_geom->ComputeInertialMatrix(&inertia, &origin); + + NewtonBodySetCentreOfMass(m_body, &origin.x); + NewtonBodySetMassMatrix(m_body, mass, inertia.x*mass, inertia.y*mass, inertia.z*mass); + NewtonBodySetForceAndTorqueCallback(m_body, &ForceAndTorqueCallback); + NewtonBodySetTransformCallback(m_body, &TransformCallback); + } + + m_mass = mass; + } + + void PhysObject::SetMassCenter(const Vector3f& center) + { + if (m_mass > 0.f) + NewtonBodySetCentreOfMass(m_body, center); + } + + void PhysObject::SetPosition(const Vector3f& position) + { + m_matrix.SetTranslation(position); + UpdateBody(); + } + + void PhysObject::SetRotation(const Quaternionf& rotation) + { + m_matrix.SetRotation(rotation); + UpdateBody(); + } + + void PhysObject::SetVelocity(const Vector3f& velocity) + { + NewtonBodySetVelocity(m_body, velocity); + } + + PhysObject& PhysObject::operator=(const PhysObject& object) + { + PhysObject physObj(object); + return operator=(std::move(physObj)); + } + + void PhysObject::UpdateBody() + { + NewtonBodySetMatrix(m_body, m_matrix); + + if (NumberEquals(m_mass, 0.f)) + { + // http://newtondynamics.com/wiki/index.php5?title=Can_i_dynamicly_move_a_TriMesh%3F + Vector3f min, max; + NewtonBodyGetAABB(m_body, min, max); + + NewtonWorldForEachBodyInAABBDo(m_world->GetHandle(), min, max, [](const NewtonBody* const body, void* const userData) + { + NazaraUnused(userData); + NewtonBodySetSleepState(body, 0); + }, nullptr); + } + /*for (std::set::iterator it = m_listeners.begin(); it != m_listeners.end(); ++it) + (*it)->PhysObjectOnUpdate(this);*/ + } + + PhysObject& PhysObject::operator=(PhysObject&& object) + { + if (m_body) + NewtonDestroyBody(m_world->GetHandle(), m_body); + + m_body = object.m_body; + m_forceAccumulator = std::move(object.m_forceAccumulator); + m_geom = std::move(object.m_geom); + m_gravityFactor = object.m_gravityFactor; + m_mass = object.m_mass; + m_matrix = std::move(object.m_matrix); + m_torqueAccumulator = std::move(object.m_torqueAccumulator); + m_world = object.m_world; + + object.m_body = nullptr; + + return *this; + } + + void PhysObject::ForceAndTorqueCallback(const NewtonBody* body, float timeStep, int threadIndex) + { + NazaraUnused(timeStep); + NazaraUnused(threadIndex); + + PhysObject* me = static_cast(NewtonBodyGetUserData(body)); + + if (!NumberEquals(me->m_gravityFactor, 0.f)) + me->m_forceAccumulator += me->m_world->GetGravity() * me->m_gravityFactor * me->m_mass; + + /*for (std::set::iterator it = me->m_listeners.begin(); it != me->m_listeners.end(); ++it) + (*it)->PhysObjectApplyForce(me);*/ + + NewtonBodySetForce(body, me->m_forceAccumulator); + NewtonBodySetTorque(body, me->m_torqueAccumulator); + + me->m_torqueAccumulator.Set(0.f); + me->m_forceAccumulator.Set(0.f); + + ///TODO: Implanter la force gyroscopique? + } + + void PhysObject::TransformCallback(const NewtonBody* body, const float* matrix, int threadIndex) + { + NazaraUnused(threadIndex); + + PhysObject* me = static_cast(NewtonBodyGetUserData(body)); + me->m_matrix.Set(matrix); + + /*for (std::set::iterator it = me->m_listeners.begin(); it != me->m_listeners.end(); ++it) + (*it)->PhysObjectOnUpdate(me);*/ + } } diff --git a/src/Nazara/Physics/PhysWorld.cpp b/src/Nazara/Physics/PhysWorld.cpp index 63ef5c886..a3d76429b 100644 --- a/src/Nazara/Physics/PhysWorld.cpp +++ b/src/Nazara/Physics/PhysWorld.cpp @@ -6,57 +6,60 @@ #include #include -NzPhysWorld::NzPhysWorld() : -m_gravity(NzVector3f::Zero()), -m_stepSize(0.005f), -m_timestepAccumulator(0.f) +namespace Nz { - m_world = NewtonCreate(); - NewtonWorldSetUserData(m_world, this); -} - -NzPhysWorld::~NzPhysWorld() -{ - NewtonDestroy(m_world); -} - -NzVector3f NzPhysWorld::GetGravity() const -{ - return m_gravity; -} - -NewtonWorld* NzPhysWorld::GetHandle() const -{ - return m_world; -} - -float NzPhysWorld::GetStepSize() const -{ - return m_stepSize; -} - -void NzPhysWorld::SetGravity(const NzVector3f& gravity) -{ - m_gravity = gravity; -} - -void NzPhysWorld::SetSolverModel(unsigned int model) -{ - NewtonSetSolverModel(m_world, model); -} - -void NzPhysWorld::SetStepSize(float stepSize) -{ - m_stepSize = stepSize; -} - -void NzPhysWorld::Step(float timestep) -{ - m_timestepAccumulator += timestep; - - while (m_timestepAccumulator >= m_stepSize) + PhysWorld::PhysWorld() : + m_gravity(Vector3f::Zero()), + m_stepSize(0.005f), + m_timestepAccumulator(0.f) { - NewtonUpdate(m_world, m_stepSize); - m_timestepAccumulator -= m_stepSize; + m_world = NewtonCreate(); + NewtonWorldSetUserData(m_world, this); + } + + PhysWorld::~PhysWorld() + { + NewtonDestroy(m_world); + } + + Vector3f PhysWorld::GetGravity() const + { + return m_gravity; + } + + NewtonWorld* PhysWorld::GetHandle() const + { + return m_world; + } + + float PhysWorld::GetStepSize() const + { + return m_stepSize; + } + + void PhysWorld::SetGravity(const Vector3f& gravity) + { + m_gravity = gravity; + } + + void PhysWorld::SetSolverModel(unsigned int model) + { + NewtonSetSolverModel(m_world, model); + } + + void PhysWorld::SetStepSize(float stepSize) + { + m_stepSize = stepSize; + } + + void PhysWorld::Step(float timestep) + { + m_timestepAccumulator += timestep; + + while (m_timestepAccumulator >= m_stepSize) + { + NewtonUpdate(m_world, m_stepSize); + m_timestepAccumulator -= m_stepSize; + } } } diff --git a/src/Nazara/Physics/Physics.cpp b/src/Nazara/Physics/Physics.cpp index c54023b2c..3c53ff9ad 100644 --- a/src/Nazara/Physics/Physics.cpp +++ b/src/Nazara/Physics/Physics.cpp @@ -10,57 +10,60 @@ #include #include -unsigned int NzPhysics::GetMemoryUsed() +namespace Nz { - return NewtonGetMemoryUsed(); -} - -bool NzPhysics::Initialize() -{ - if (s_moduleReferenceCounter > 0) + unsigned int Physics::GetMemoryUsed() { + return NewtonGetMemoryUsed(); + } + + bool Physics::Initialize() + { + if (s_moduleReferenceCounter > 0) + { + s_moduleReferenceCounter++; + return true; // Déjà initialisé + } + + // Initialisation des dépendances + if (!Core::Initialize()) + { + NazaraError("Failed to initialize core module"); + return false; + } + s_moduleReferenceCounter++; - return true; // Déjà initialisé + + // Initialisation du module + + NazaraNotice("Initialized: Physics module"); + return true; } - // Initialisation des dépendances - if (!NzCore::Initialize()) + bool Physics::IsInitialized() { - NazaraError("Failed to initialize core module"); - return false; + return s_moduleReferenceCounter != 0; } - s_moduleReferenceCounter++; - - // Initialisation du module - - NazaraNotice("Initialized: Physics module"); - return true; -} - -bool NzPhysics::IsInitialized() -{ - return s_moduleReferenceCounter != 0; -} - -void NzPhysics::Uninitialize() -{ - if (s_moduleReferenceCounter != 1) + void Physics::Uninitialize() { - // Le module est soit encore utilisé, soit pas initialisé - if (s_moduleReferenceCounter > 1) - s_moduleReferenceCounter--; + if (s_moduleReferenceCounter != 1) + { + // Le module est soit encore utilisé, soit pas initialisé + if (s_moduleReferenceCounter > 1) + s_moduleReferenceCounter--; - return; + return; + } + + // Libération du module + s_moduleReferenceCounter = 0; + + NazaraNotice("Uninitialized: Physics module"); + + // Libération des dépendances + Core::Uninitialize(); } - // Libération du module - s_moduleReferenceCounter = 0; - - NazaraNotice("Uninitialized: Physics module"); - - // Libération des dépendances - NzCore::Uninitialize(); + unsigned int Physics::s_moduleReferenceCounter = 0; } - -unsigned int NzPhysics::s_moduleReferenceCounter = 0; diff --git a/src/Nazara/Renderer/Context.cpp b/src/Nazara/Renderer/Context.cpp index 007d32d77..ada25df91 100644 --- a/src/Nazara/Renderer/Context.cpp +++ b/src/Nazara/Renderer/Context.cpp @@ -23,351 +23,354 @@ #include -namespace +namespace Nz { - thread_local const NzContext* s_currentContext = nullptr; - thread_local const NzContext* s_threadContext = nullptr; - - void CALLBACK DebugCallback(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, int length, const char* message, const void* userParam) + namespace { - NazaraUnused(length); + thread_local const Context* s_currentContext = nullptr; + thread_local const Context* s_threadContext = nullptr; - NzStringStream ss; - ss << "OpenGL debug message (ID: 0x" << NzString::Number(id, 16) << "):\n"; - ss << "Sent by context: " << userParam; - ss << "\n-Source: "; - switch (source) + void CALLBACK DebugCallback(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, int length, const char* message, const void* userParam) { - case GL_DEBUG_SOURCE_API: - ss << "OpenGL API"; - break; + NazaraUnused(length); - case GL_DEBUG_SOURCE_WINDOW_SYSTEM: - ss << "Operating system"; - break; - - case GL_DEBUG_SOURCE_SHADER_COMPILER: - ss << "Shader compiler"; - break; - - case GL_DEBUG_SOURCE_THIRD_PARTY: - ss << "Third party"; - break; - - case GL_DEBUG_SOURCE_APPLICATION: - ss << "Application"; - break; - - case GL_DEBUG_SOURCE_OTHER: - ss << "Other"; - break; - - default: - // Peut être rajouté par une extension - ss << "Unknown"; - break; - } - ss << '\n'; - - ss << "-Type: "; - switch (type) - { - case GL_DEBUG_TYPE_ERROR: - ss << "Error"; - break; - - case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: - ss << "Deprecated behavior"; - break; - - case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: - ss << "Undefined behavior"; - break; - - case GL_DEBUG_TYPE_PORTABILITY: - ss << "Portability"; - break; - - case GL_DEBUG_TYPE_PERFORMANCE: - ss << "Performance"; - break; - - case GL_DEBUG_TYPE_OTHER: - ss << "Other"; - break; - - default: - // Peut être rajouté par une extension - ss << "Unknown"; - break; - } - ss << '\n'; - - ss << "-Severity: "; - switch (severity) - { - case GL_DEBUG_SEVERITY_HIGH: - ss << "High"; - break; - - case GL_DEBUG_SEVERITY_MEDIUM: - ss << "Medium"; - break; - - case GL_DEBUG_SEVERITY_LOW: - ss << "Low"; - break; - - default: - // Peut être rajouté par une extension - ss << "Unknown"; - break; - } - ss << '\n'; - - ss << "Message: " << message << '\n'; - - NazaraNotice(ss); - } -} - -NzContext::~NzContext() -{ - OnContextRelease(this); - - Destroy(); -} - -bool NzContext::Create(const NzContextParameters& parameters) -{ - Destroy(); - - m_parameters = parameters; - if (m_parameters.shared && !m_parameters.shareContext) - m_parameters.shareContext = s_reference.get(); - - std::unique_ptr impl(new NzContextImpl); - if (!impl->Create(m_parameters)) - { - NazaraError("Failed to create context implementation"); - return false; - } - - m_impl = impl.release(); - - NzCallOnExit onExit([this] () { Destroy(); }); - - if (!SetActive(true)) - { - NazaraError("Failed to activate context"); - return false; - } - - if (m_parameters.antialiasingLevel > 0) - glEnable(GL_MULTISAMPLE); - - if (m_parameters.debugMode && NzOpenGL::IsSupported(nzOpenGLExtension_DebugOutput)) - { - glDebugMessageCallback(&DebugCallback, this); - - #ifdef NAZARA_DEBUG - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - #endif - } - - onExit.Reset(); - - return true; -} - -void NzContext::Destroy() -{ - if (m_impl) - { - OnContextDestroy(this); - - NzOpenGL::OnContextDestruction(this); - SetActive(false); - - m_impl->Destroy(); - delete m_impl; - m_impl = nullptr; - } -} - -void NzContext::EnableVerticalSync(bool enabled) -{ - #ifdef NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("No context has been created"); - return; - } - #endif - - m_impl->EnableVerticalSync(enabled); -} - -const NzContextParameters& NzContext::GetParameters() const -{ - #ifdef NAZARA_RENDERER_SAFE - if (!m_impl) - NazaraError("No context has been created"); - #endif - - return m_parameters; -} - -bool NzContext::IsActive() const -{ - #ifdef NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("No context has been created"); - return false; - } - #endif - - return s_currentContext == this; -} - -bool NzContext::SetActive(bool active) const -{ - #ifdef NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("No context has been created"); - return false; - } - #endif - - // Si le contexte est déjà activé/désactivé - if ((s_currentContext == this) == active) - return true; - - if (active) - { - if (!m_impl->Activate()) - return false; - - s_currentContext = this; - } - else - { - if (!NzContextImpl::Desactivate()) - return false; - - s_currentContext = nullptr; - } - - NzOpenGL::OnContextChanged(s_currentContext); - - return true; -} - -void NzContext::SwapBuffers() -{ - #ifdef NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("No context has been created"); - return; - } - - if (!m_parameters.doubleBuffered) - { - NazaraError("Context is not double buffered"); - return; - } - #endif - - m_impl->SwapBuffers(); -} - -bool NzContext::EnsureContext() -{ - if (!s_currentContext) - { - if (!s_threadContext) - { - std::unique_ptr context(new NzContext); - if (!context->Create()) + StringStream ss; + ss << "OpenGL debug message (ID: 0x" << String::Number(id, 16) << "):\n"; + ss << "Sent by context: " << userParam; + ss << "\n-Source: "; + switch (source) { - NazaraError("Failed to create context"); + case GL_DEBUG_SOURCE_API: + ss << "OpenGL API"; + break; + + case GL_DEBUG_SOURCE_WINDOW_SYSTEM: + ss << "Operating system"; + break; + + case GL_DEBUG_SOURCE_SHADER_COMPILER: + ss << "Shader compiler"; + break; + + case GL_DEBUG_SOURCE_THIRD_PARTY: + ss << "Third party"; + break; + + case GL_DEBUG_SOURCE_APPLICATION: + ss << "Application"; + break; + + case GL_DEBUG_SOURCE_OTHER: + ss << "Other"; + break; + + default: + // Peut être rajouté par une extension + ss << "Unknown"; + break; + } + ss << '\n'; + + ss << "-Type: "; + switch (type) + { + case GL_DEBUG_TYPE_ERROR: + ss << "Error"; + break; + + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: + ss << "Deprecated behavior"; + break; + + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: + ss << "Undefined behavior"; + break; + + case GL_DEBUG_TYPE_PORTABILITY: + ss << "Portability"; + break; + + case GL_DEBUG_TYPE_PERFORMANCE: + ss << "Performance"; + break; + + case GL_DEBUG_TYPE_OTHER: + ss << "Other"; + break; + + default: + // Peut être rajouté par une extension + ss << "Unknown"; + break; + } + ss << '\n'; + + ss << "-Severity: "; + switch (severity) + { + case GL_DEBUG_SEVERITY_HIGH: + ss << "High"; + break; + + case GL_DEBUG_SEVERITY_MEDIUM: + ss << "Medium"; + break; + + case GL_DEBUG_SEVERITY_LOW: + ss << "Low"; + break; + + default: + // Peut être rajouté par une extension + ss << "Unknown"; + break; + } + ss << '\n'; + + ss << "Message: " << message << '\n'; + + NazaraNotice(ss); + } + } + + Context::~Context() + { + OnContextRelease(this); + + Destroy(); + } + + bool Context::Create(const ContextParameters& parameters) + { + Destroy(); + + m_parameters = parameters; + if (m_parameters.shared && !m_parameters.shareContext) + m_parameters.shareContext = s_reference.get(); + + std::unique_ptr impl(new ContextImpl); + if (!impl->Create(m_parameters)) + { + NazaraError("Failed to create context implementation"); + return false; + } + + m_impl = impl.release(); + + CallOnExit onExit([this] () { Destroy(); }); + + if (!SetActive(true)) + { + NazaraError("Failed to activate context"); + return false; + } + + if (m_parameters.antialiasingLevel > 0) + glEnable(GL_MULTISAMPLE); + + if (m_parameters.debugMode && OpenGL::IsSupported(OpenGLExtension_DebugOutput)) + { + glDebugMessageCallback(&DebugCallback, this); + + #ifdef NAZARA_DEBUG + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + #endif + } + + onExit.Reset(); + + return true; + } + + void Context::Destroy() + { + if (m_impl) + { + OnContextDestroy(this); + + OpenGL::OnContextDestruction(this); + SetActive(false); + + m_impl->Destroy(); + delete m_impl; + m_impl = nullptr; + } + } + + void Context::EnableVerticalSync(bool enabled) + { + #ifdef NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("No context has been created"); + return; + } + #endif + + m_impl->EnableVerticalSync(enabled); + } + + const ContextParameters& Context::GetParameters() const + { + #ifdef NAZARA_RENDERER_SAFE + if (!m_impl) + NazaraError("No context has been created"); + #endif + + return m_parameters; + } + + bool Context::IsActive() const + { + #ifdef NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("No context has been created"); + return false; + } + #endif + + return s_currentContext == this; + } + + bool Context::SetActive(bool active) const + { + #ifdef NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("No context has been created"); + return false; + } + #endif + + // Si le contexte est déjà activé/désactivé + if ((s_currentContext == this) == active) + return true; + + if (active) + { + if (!m_impl->Activate()) return false; + + s_currentContext = this; + } + else + { + if (!ContextImpl::Desactivate()) + return false; + + s_currentContext = nullptr; + } + + OpenGL::OnContextChanged(s_currentContext); + + return true; + } + + void Context::SwapBuffers() + { + #ifdef NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("No context has been created"); + return; + } + + if (!m_parameters.doubleBuffered) + { + NazaraError("Context is not double buffered"); + return; + } + #endif + + m_impl->SwapBuffers(); + } + + bool Context::EnsureContext() + { + if (!s_currentContext) + { + if (!s_threadContext) + { + std::unique_ptr context(new Context); + if (!context->Create()) + { + NazaraError("Failed to create context"); + return false; + } + + s_threadContext = context.get(); + + s_contexts.emplace_back(std::move(context)); } - s_threadContext = context.get(); - - s_contexts.emplace_back(std::move(context)); + if (!s_threadContext->SetActive(true)) + { + NazaraError("Failed to active thread context"); + return false; + } } - if (!s_threadContext->SetActive(true)) + return true; + } + + const Context* Context::GetCurrent() + { + return s_currentContext; + } + + const Context* Context::GetReference() + { + return s_reference.get(); + } + + const Context* Context::GetThreadContext() + { + EnsureContext(); + + return s_threadContext; + } + + bool Context::Initialize() + { + if (!ContextLibrary::Initialize()) { - NazaraError("Failed to active thread context"); + NazaraError("Failed to initialise library"); return false; } + + ContextParameters parameters; + parameters.shared = false; // Difficile de partager le contexte de référence avec lui-même + + std::unique_ptr reference(new Context); + if (!reference->Create(parameters)) + { + NazaraError("Failed to create reference context"); + return false; + } + + // Le contexte de référence doit rester désactivé pour le partage + if (!reference->SetActive(false)) + { + NazaraError("Failed to desactive reference context"); + return false; + } + + s_reference = std::move(reference); + + // Le contexte de référence est partagé par défaut avec les autres contextes + ContextParameters::defaultShareContext = s_reference.get(); + return true; } - return true; -} - -const NzContext* NzContext::GetCurrent() -{ - return s_currentContext; -} - -const NzContext* NzContext::GetReference() -{ - return s_reference.get(); -} - -const NzContext* NzContext::GetThreadContext() -{ - EnsureContext(); - - return s_threadContext; -} - -bool NzContext::Initialize() -{ - if (!NzContextLibrary::Initialize()) + void Context::Uninitialize() { - NazaraError("Failed to initialise library"); - return false; + ContextLibrary::Uninitialize(); + s_contexts.clear(); // On supprime tous les contextes créés + s_reference.reset(); } - NzContextParameters parameters; - parameters.shared = false; // Difficile de partager le contexte de référence avec lui-même - - std::unique_ptr reference(new NzContext); - if (!reference->Create(parameters)) - { - NazaraError("Failed to create reference context"); - return false; - } - - // Le contexte de référence doit rester désactivé pour le partage - if (!reference->SetActive(false)) - { - NazaraError("Failed to desactive reference context"); - return false; - } - - s_reference = std::move(reference); - - // Le contexte de référence est partagé par défaut avec les autres contextes - NzContextParameters::defaultShareContext = s_reference.get(); - return true; + std::unique_ptr Context::s_reference; + std::vector> Context::s_contexts; + ContextLibrary::LibraryMap Context::s_library; } - -void NzContext::Uninitialize() -{ - NzContextLibrary::Uninitialize(); - s_contexts.clear(); // On supprime tous les contextes créés - s_reference.reset(); -} - -std::unique_ptr NzContext::s_reference; -std::vector> NzContext::s_contexts; -NzContextLibrary::LibraryMap NzContext::s_library; diff --git a/src/Nazara/Renderer/ContextParameters.cpp b/src/Nazara/Renderer/ContextParameters.cpp index a7dec4546..9f85bc662 100644 --- a/src/Nazara/Renderer/ContextParameters.cpp +++ b/src/Nazara/Renderer/ContextParameters.cpp @@ -6,27 +6,30 @@ #include #include -// Version majeure d'OpenGL, initialisé par NzOpenGL::Initialize() -nzUInt8 NzContextParameters::defaultMajorVersion; +namespace Nz +{ + // Version majeure d'OpenGL, initialisé par OpenGL::Initialize() + UInt8 ContextParameters::defaultMajorVersion; - // Version majeure d'OpenGL, initialisé par NzOpenGL::Initialize() -nzUInt8 NzContextParameters::defaultMinorVersion; + // Version majeure d'OpenGL, initialisé par OpenGL::Initialize() + UInt8 ContextParameters::defaultMinorVersion; -// Contexte de partage par défaut, initialisé par NzOpenGL::Initialize() -const NzContext* NzContextParameters::defaultShareContext = nullptr; + // Contexte de partage par défaut, initialisé par OpenGL::Initialize() + const Context* ContextParameters::defaultShareContext = nullptr; -// Si possible, garder la compatibilité avec les fonctionnalités dépréciées -bool NzContextParameters::defaultCompatibilityProfile = false; + // Si possible, garder la compatibilité avec les fonctionnalités dépréciées + bool ContextParameters::defaultCompatibilityProfile = false; -// Mode debug d'OpenGL par défaut -#if NAZARA_RENDERER_OPENGL_DEBUG || defined(NAZARA_DEBUG) -bool NzContextParameters::defaultDebugMode = true; -#else -bool NzContextParameters::defaultDebugMode = false; -#endif + // Mode debug d'OpenGL par défaut + #if NAZARA_RENDERER_OPENGL_DEBUG || defined(NAZARA_DEBUG) + bool ContextParameters::defaultDebugMode = true; + #else + bool ContextParameters::defaultDebugMode = false; + #endif -// Active le double-buffering sur les contextes -bool NzContextParameters::defaultDoubleBuffered = false; + // Active le double-buffering sur les contextes + bool ContextParameters::defaultDoubleBuffered = false; -// Active le partage des ressources entre contextes (Via le defaultShareContext) -bool NzContextParameters::defaultShared = true; + // Active le partage des ressources entre contextes (Via le defaultShareContext) + bool ContextParameters::defaultShared = true; +} diff --git a/src/Nazara/Renderer/DebugDrawer.cpp b/src/Nazara/Renderer/DebugDrawer.cpp index 9d3559540..20d24c9d5 100644 --- a/src/Nazara/Renderer/DebugDrawer.cpp +++ b/src/Nazara/Renderer/DebugDrawer.cpp @@ -19,720 +19,723 @@ ///TODO: Améliorer -namespace +namespace Nz { - static NzShader* s_shader = nullptr; - static NzColor s_primaryColor; - static NzColor s_secondaryColor; - static NzRenderStates s_renderStates; - static NzVertexBuffer s_vertexBuffer; - static bool s_initialized = false; - static int s_colorLocation = -1; -} - -void NzDebugDrawer::Draw(const NzBoundingVolumef& volume) -{ - if (!Initialize()) + namespace { - NazaraError("Failed to initialize Debug Drawer"); - return; + static Shader* s_shader = nullptr; + static Color s_primaryColor; + static Color s_secondaryColor; + static RenderStates s_renderStates; + static VertexBuffer s_vertexBuffer; + static bool s_initialized = false; + static int s_colorLocation = -1; } - if (!volume.IsFinite()) - return; - - NzColor oldPrimaryColor = s_primaryColor; - - Draw(volume.aabb); - - s_primaryColor = s_secondaryColor; - Draw(volume.obb); - - s_primaryColor = oldPrimaryColor; -} - -void NzDebugDrawer::Draw(const NzBoxi& box) -{ - Draw(NzBoxf(box)); -} - -void NzDebugDrawer::Draw(const NzBoxf& box) -{ - if (!Initialize()) + void DebugDrawer::Draw(const BoundingVolumef& volume) { - NazaraError("Failed to initialize Debug Drawer"); - return; - } - - NzBufferMapper mapper(s_vertexBuffer, nzBufferAccess_DiscardAndWrite, 0, 24); - NzVertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); - - NzVector3f max, min; - max = box.GetMaximum(); - min = box.GetMinimum(); - - vertex->position.Set(min.x, min.y, min.z); - vertex++; - vertex->position.Set(max.x, min.y, min.z); - vertex++; - - vertex->position.Set(min.x, min.y, min.z); - vertex++; - vertex->position.Set(min.x, max.y, min.z); - vertex++; - - vertex->position.Set(min.x, min.y, min.z); - vertex++; - vertex->position.Set(min.x, min.y, max.z); - vertex++; - - vertex->position.Set(max.x, max.y, max.z); - vertex++; - vertex->position.Set(min.x, max.y, max.z); - vertex++; - - vertex->position.Set(max.x, max.y, max.z); - vertex++; - vertex->position.Set(max.x, min.y, max.z); - vertex++; - - vertex->position.Set(max.x, max.y, max.z); - vertex++; - vertex->position.Set(max.x, max.y, min.z); - vertex++; - - vertex->position.Set(min.x, min.y, max.z); - vertex++; - vertex->position.Set(max.x, min.y, max.z); - vertex++; - - vertex->position.Set(min.x, min.y, max.z); - vertex++; - vertex->position.Set(min.x, max.y, max.z); - vertex++; - - vertex->position.Set(min.x, max.y, min.z); - vertex++; - vertex->position.Set(max.x, max.y, min.z); - vertex++; - - vertex->position.Set(min.x, max.y, min.z); - vertex++; - vertex->position.Set(min.x, max.y, max.z); - vertex++; - - vertex->position.Set(max.x, min.y, min.z); - vertex++; - vertex->position.Set(max.x, max.y, min.z); - vertex++; - - vertex->position.Set(max.x, min.y, min.z); - vertex++; - vertex->position.Set(max.x, min.y, max.z); - vertex++; - - mapper.Unmap(); - - NzRenderer::SetRenderStates(s_renderStates); - NzRenderer::SetShader(s_shader); - NzRenderer::SetVertexBuffer(&s_vertexBuffer); - - s_shader->SendColor(s_colorLocation, s_primaryColor); - - NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, 24); -} - -void NzDebugDrawer::Draw(const NzBoxui& box) -{ - Draw(NzBoxf(box)); -} - -void NzDebugDrawer::Draw(const NzFrustumf& frustum) -{ - if (!Initialize()) - { - NazaraError("Failed to initialize Debug Drawer"); - return; - } - - NzBufferMapper mapper(s_vertexBuffer, nzBufferAccess_DiscardAndWrite, 0, 24); - NzVertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); - - vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftBottom)); - vertex++; - vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightBottom)); - vertex++; - - vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftBottom)); - vertex++; - vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftTop)); - vertex++; - - vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftBottom)); - vertex++; - vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftBottom)); - vertex++; - - vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightTop)); - vertex++; - vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftTop)); - vertex++; - - vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightTop)); - vertex++; - vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightBottom)); - vertex++; - - vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightTop)); - vertex++; - vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightTop)); - vertex++; - - vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftBottom)); - vertex++; - vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightBottom)); - vertex++; - - vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftBottom)); - vertex++; - vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftTop)); - vertex++; - - vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftTop)); - vertex++; - vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightTop)); - vertex++; - - vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearLeftTop)); - vertex++; - vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarLeftTop)); - vertex++; - - vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightBottom)); - vertex++; - vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightTop)); - vertex++; - - vertex->position.Set(frustum.GetCorner(nzBoxCorner_NearRightBottom)); - vertex++; - vertex->position.Set(frustum.GetCorner(nzBoxCorner_FarRightBottom)); - vertex++; - - mapper.Unmap(); - - NzRenderer::SetRenderStates(s_renderStates); - NzRenderer::SetShader(s_shader); - NzRenderer::SetVertexBuffer(&s_vertexBuffer); - - s_shader->SendColor(s_colorLocation, s_primaryColor); - - NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, 24); -} - -void NzDebugDrawer::Draw(const NzOrientedBoxf& orientedBox) -{ - if (!Initialize()) - { - NazaraError("Failed to initialize Debug Drawer"); - return; - } - - NzBufferMapper mapper(s_vertexBuffer, nzBufferAccess_DiscardAndWrite, 0, 24); - NzVertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); - - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftBottom)); - vertex++; - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightBottom)); - vertex++; - - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftBottom)); - vertex++; - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftTop)); - vertex++; - - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftBottom)); - vertex++; - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftBottom)); - vertex++; - - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightTop)); - vertex++; - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftTop)); - vertex++; - - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightTop)); - vertex++; - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightBottom)); - vertex++; - - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightTop)); - vertex++; - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightTop)); - vertex++; - - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftBottom)); - vertex++; - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightBottom)); - vertex++; - - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftBottom)); - vertex++; - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftTop)); - vertex++; - - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftTop)); - vertex++; - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightTop)); - vertex++; - - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearLeftTop)); - vertex++; - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarLeftTop)); - vertex++; - - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightBottom)); - vertex++; - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightTop)); - vertex++; - - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_NearRightBottom)); - vertex++; - vertex->position.Set(orientedBox.GetCorner(nzBoxCorner_FarRightBottom)); - vertex++; - - mapper.Unmap(); - - NzRenderer::SetRenderStates(s_renderStates); - NzRenderer::SetShader(s_shader); - NzRenderer::SetVertexBuffer(&s_vertexBuffer); - - s_shader->SendColor(s_colorLocation, s_primaryColor); - - NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, 24); -} - -void NzDebugDrawer::Draw(const NzSkeleton* skeleton) -{ - if (!Initialize()) - { - NazaraError("Failed to initialize Debug Drawer"); - return; - } - - unsigned int jointCount = skeleton->GetJointCount(); - if (s_vertexBuffer.GetVertexCount() < jointCount*2) - { - NazaraError("Debug buffer not large enougth to draw object"); - return; - } - - NzBufferMapper mapper(s_vertexBuffer, nzBufferAccess_DiscardAndWrite, 0, jointCount*2); - NzVertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); - - unsigned int vertexCount = 0; - for (unsigned int i = 0; i < jointCount; ++i) - { - const NzNode* joint = skeleton->GetJoint(i); - const NzNode* parent = joint->GetParent(); - if (parent) + if (!Initialize()) { - vertex->position = joint->GetPosition(); - vertex++; + NazaraError("Failed to initialize Debug Drawer"); + return; + } - vertex->position = parent->GetPosition(); - vertex++; + if (!volume.IsFinite()) + return; - vertexCount += 2; + Color oldPrimaryColor = s_primaryColor; + + Draw(volume.aabb); + + s_primaryColor = s_secondaryColor; + Draw(volume.obb); + + s_primaryColor = oldPrimaryColor; + } + + void DebugDrawer::Draw(const Boxi& box) + { + Draw(Boxf(box)); + } + + void DebugDrawer::Draw(const Boxf& box) + { + if (!Initialize()) + { + NazaraError("Failed to initialize Debug Drawer"); + return; + } + + BufferMapper mapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, 24); + VertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); + + Vector3f max, min; + max = box.GetMaximum(); + min = box.GetMinimum(); + + vertex->position.Set(min.x, min.y, min.z); + vertex++; + vertex->position.Set(max.x, min.y, min.z); + vertex++; + + vertex->position.Set(min.x, min.y, min.z); + vertex++; + vertex->position.Set(min.x, max.y, min.z); + vertex++; + + vertex->position.Set(min.x, min.y, min.z); + vertex++; + vertex->position.Set(min.x, min.y, max.z); + vertex++; + + vertex->position.Set(max.x, max.y, max.z); + vertex++; + vertex->position.Set(min.x, max.y, max.z); + vertex++; + + vertex->position.Set(max.x, max.y, max.z); + vertex++; + vertex->position.Set(max.x, min.y, max.z); + vertex++; + + vertex->position.Set(max.x, max.y, max.z); + vertex++; + vertex->position.Set(max.x, max.y, min.z); + vertex++; + + vertex->position.Set(min.x, min.y, max.z); + vertex++; + vertex->position.Set(max.x, min.y, max.z); + vertex++; + + vertex->position.Set(min.x, min.y, max.z); + vertex++; + vertex->position.Set(min.x, max.y, max.z); + vertex++; + + vertex->position.Set(min.x, max.y, min.z); + vertex++; + vertex->position.Set(max.x, max.y, min.z); + vertex++; + + vertex->position.Set(min.x, max.y, min.z); + vertex++; + vertex->position.Set(min.x, max.y, max.z); + vertex++; + + vertex->position.Set(max.x, min.y, min.z); + vertex++; + vertex->position.Set(max.x, max.y, min.z); + vertex++; + + vertex->position.Set(max.x, min.y, min.z); + vertex++; + vertex->position.Set(max.x, min.y, max.z); + vertex++; + + mapper.Unmap(); + + Renderer::SetRenderStates(s_renderStates); + Renderer::SetShader(s_shader); + Renderer::SetVertexBuffer(&s_vertexBuffer); + + s_shader->SendColor(s_colorLocation, s_primaryColor); + + Renderer::DrawPrimitives(PrimitiveMode_LineList, 0, 24); + } + + void DebugDrawer::Draw(const Boxui& box) + { + Draw(Boxf(box)); + } + + void DebugDrawer::Draw(const Frustumf& frustum) + { + if (!Initialize()) + { + NazaraError("Failed to initialize Debug Drawer"); + return; + } + + BufferMapper mapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, 24); + VertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); + + vertex->position.Set(frustum.GetCorner(BoxCorner_NearLeftBottom)); + vertex++; + vertex->position.Set(frustum.GetCorner(BoxCorner_NearRightBottom)); + vertex++; + + vertex->position.Set(frustum.GetCorner(BoxCorner_NearLeftBottom)); + vertex++; + vertex->position.Set(frustum.GetCorner(BoxCorner_NearLeftTop)); + vertex++; + + vertex->position.Set(frustum.GetCorner(BoxCorner_NearLeftBottom)); + vertex++; + vertex->position.Set(frustum.GetCorner(BoxCorner_FarLeftBottom)); + vertex++; + + vertex->position.Set(frustum.GetCorner(BoxCorner_FarRightTop)); + vertex++; + vertex->position.Set(frustum.GetCorner(BoxCorner_FarLeftTop)); + vertex++; + + vertex->position.Set(frustum.GetCorner(BoxCorner_FarRightTop)); + vertex++; + vertex->position.Set(frustum.GetCorner(BoxCorner_FarRightBottom)); + vertex++; + + vertex->position.Set(frustum.GetCorner(BoxCorner_FarRightTop)); + vertex++; + vertex->position.Set(frustum.GetCorner(BoxCorner_NearRightTop)); + vertex++; + + vertex->position.Set(frustum.GetCorner(BoxCorner_FarLeftBottom)); + vertex++; + vertex->position.Set(frustum.GetCorner(BoxCorner_FarRightBottom)); + vertex++; + + vertex->position.Set(frustum.GetCorner(BoxCorner_FarLeftBottom)); + vertex++; + vertex->position.Set(frustum.GetCorner(BoxCorner_FarLeftTop)); + vertex++; + + vertex->position.Set(frustum.GetCorner(BoxCorner_NearLeftTop)); + vertex++; + vertex->position.Set(frustum.GetCorner(BoxCorner_NearRightTop)); + vertex++; + + vertex->position.Set(frustum.GetCorner(BoxCorner_NearLeftTop)); + vertex++; + vertex->position.Set(frustum.GetCorner(BoxCorner_FarLeftTop)); + vertex++; + + vertex->position.Set(frustum.GetCorner(BoxCorner_NearRightBottom)); + vertex++; + vertex->position.Set(frustum.GetCorner(BoxCorner_NearRightTop)); + vertex++; + + vertex->position.Set(frustum.GetCorner(BoxCorner_NearRightBottom)); + vertex++; + vertex->position.Set(frustum.GetCorner(BoxCorner_FarRightBottom)); + vertex++; + + mapper.Unmap(); + + Renderer::SetRenderStates(s_renderStates); + Renderer::SetShader(s_shader); + Renderer::SetVertexBuffer(&s_vertexBuffer); + + s_shader->SendColor(s_colorLocation, s_primaryColor); + + Renderer::DrawPrimitives(PrimitiveMode_LineList, 0, 24); + } + + void DebugDrawer::Draw(const OrientedBoxf& orientedBox) + { + if (!Initialize()) + { + NazaraError("Failed to initialize Debug Drawer"); + return; + } + + BufferMapper mapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, 24); + VertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); + + vertex->position.Set(orientedBox.GetCorner(BoxCorner_NearLeftBottom)); + vertex++; + vertex->position.Set(orientedBox.GetCorner(BoxCorner_NearRightBottom)); + vertex++; + + vertex->position.Set(orientedBox.GetCorner(BoxCorner_NearLeftBottom)); + vertex++; + vertex->position.Set(orientedBox.GetCorner(BoxCorner_NearLeftTop)); + vertex++; + + vertex->position.Set(orientedBox.GetCorner(BoxCorner_NearLeftBottom)); + vertex++; + vertex->position.Set(orientedBox.GetCorner(BoxCorner_FarLeftBottom)); + vertex++; + + vertex->position.Set(orientedBox.GetCorner(BoxCorner_FarRightTop)); + vertex++; + vertex->position.Set(orientedBox.GetCorner(BoxCorner_FarLeftTop)); + vertex++; + + vertex->position.Set(orientedBox.GetCorner(BoxCorner_FarRightTop)); + vertex++; + vertex->position.Set(orientedBox.GetCorner(BoxCorner_FarRightBottom)); + vertex++; + + vertex->position.Set(orientedBox.GetCorner(BoxCorner_FarRightTop)); + vertex++; + vertex->position.Set(orientedBox.GetCorner(BoxCorner_NearRightTop)); + vertex++; + + vertex->position.Set(orientedBox.GetCorner(BoxCorner_FarLeftBottom)); + vertex++; + vertex->position.Set(orientedBox.GetCorner(BoxCorner_FarRightBottom)); + vertex++; + + vertex->position.Set(orientedBox.GetCorner(BoxCorner_FarLeftBottom)); + vertex++; + vertex->position.Set(orientedBox.GetCorner(BoxCorner_FarLeftTop)); + vertex++; + + vertex->position.Set(orientedBox.GetCorner(BoxCorner_NearLeftTop)); + vertex++; + vertex->position.Set(orientedBox.GetCorner(BoxCorner_NearRightTop)); + vertex++; + + vertex->position.Set(orientedBox.GetCorner(BoxCorner_NearLeftTop)); + vertex++; + vertex->position.Set(orientedBox.GetCorner(BoxCorner_FarLeftTop)); + vertex++; + + vertex->position.Set(orientedBox.GetCorner(BoxCorner_NearRightBottom)); + vertex++; + vertex->position.Set(orientedBox.GetCorner(BoxCorner_NearRightTop)); + vertex++; + + vertex->position.Set(orientedBox.GetCorner(BoxCorner_NearRightBottom)); + vertex++; + vertex->position.Set(orientedBox.GetCorner(BoxCorner_FarRightBottom)); + vertex++; + + mapper.Unmap(); + + Renderer::SetRenderStates(s_renderStates); + Renderer::SetShader(s_shader); + Renderer::SetVertexBuffer(&s_vertexBuffer); + + s_shader->SendColor(s_colorLocation, s_primaryColor); + + Renderer::DrawPrimitives(PrimitiveMode_LineList, 0, 24); + } + + void DebugDrawer::Draw(const Skeleton* skeleton) + { + if (!Initialize()) + { + NazaraError("Failed to initialize Debug Drawer"); + return; + } + + unsigned int jointCount = skeleton->GetJointCount(); + if (s_vertexBuffer.GetVertexCount() < jointCount*2) + { + NazaraError("Debug buffer not large enougth to draw object"); + return; + } + + BufferMapper mapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, jointCount*2); + VertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); + + unsigned int vertexCount = 0; + for (unsigned int i = 0; i < jointCount; ++i) + { + const Node* joint = skeleton->GetJoint(i); + const Node* parent = joint->GetParent(); + if (parent) + { + vertex->position = joint->GetPosition(); + vertex++; + + vertex->position = parent->GetPosition(); + vertex++; + + vertexCount += 2; + } + } + + mapper.Unmap(); + + if (vertexCount > 0) + { + Renderer::SetRenderStates(s_renderStates); + Renderer::SetShader(s_shader); + Renderer::SetVertexBuffer(&s_vertexBuffer); + + s_shader->SendColor(s_colorLocation, s_primaryColor); + Renderer::DrawPrimitives(PrimitiveMode_LineList, 0, vertexCount); + + s_shader->SendColor(s_colorLocation, s_secondaryColor); + Renderer::DrawPrimitives(PrimitiveMode_PointList, 0, vertexCount); } } - mapper.Unmap(); - - if (vertexCount > 0) + void DebugDrawer::Draw(const Vector3f& position, float size) { - NzRenderer::SetRenderStates(s_renderStates); - NzRenderer::SetShader(s_shader); - NzRenderer::SetVertexBuffer(&s_vertexBuffer); - - s_shader->SendColor(s_colorLocation, s_primaryColor); - NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, vertexCount); - - s_shader->SendColor(s_colorLocation, s_secondaryColor); - NzRenderer::DrawPrimitives(nzPrimitiveMode_PointList, 0, vertexCount); - } -} - -void NzDebugDrawer::Draw(const NzVector3f& position, float size) -{ - Draw(NzBoxf(position.x - size*0.5f, position.y - size*0.5f, position.z - size*0.5f, size, size, size)); -} - -void NzDebugDrawer::DrawAxes(const NzVector3f& position, float size) -{ - NzColor oldPrimaryColor = s_primaryColor; - s_primaryColor = NzColor::Red; - DrawLine(position, position + NzVector3f::UnitX() * 3.f * size / 4.f); - s_primaryColor = NzColor::Green; - DrawLine(position, position + NzVector3f::UnitY() * 3.f * size / 4.f); - s_primaryColor = NzColor::Blue; - DrawLine(position, position + NzVector3f::UnitZ() * 3.f * size / 4.f); - - s_primaryColor = NzColor::Red; - DrawCone(position + NzVector3f::UnitX() * size, NzEulerAnglesf(0.f, 90.f, 0.f), 15, size / 4.f); - s_primaryColor = NzColor::Green; - DrawCone(position + NzVector3f::UnitY() * size, NzEulerAnglesf(-90.f, 0.f, 0.f), 15, size / 4.f); - s_primaryColor = NzColor::Blue; - DrawCone(position + NzVector3f::UnitZ() * size, NzEulerAnglesf(0.f, 0.f, 0.f), 15, size / 4.f); - s_primaryColor = oldPrimaryColor; -} - -void NzDebugDrawer::DrawBinormals(const NzStaticMesh* subMesh) -{ - if (!Initialize()) - { - NazaraError("Failed to initialize Debug Drawer"); - return; + Draw(Boxf(position.x - size*0.5f, position.y - size*0.5f, position.z - size*0.5f, size, size, size)); } - unsigned int normalCount = subMesh->GetVertexCount(); - unsigned int vertexCount = normalCount*2; - if (s_vertexBuffer.GetVertexCount() < vertexCount) + void DebugDrawer::DrawAxes(const Vector3f& position, float size) { - NazaraError("Debug buffer not large enougth to draw object"); - return; + Color oldPrimaryColor = s_primaryColor; + s_primaryColor = Color::Red; + DrawLine(position, position + Vector3f::UnitX() * 3.f * size / 4.f); + s_primaryColor = Color::Green; + DrawLine(position, position + Vector3f::UnitY() * 3.f * size / 4.f); + s_primaryColor = Color::Blue; + DrawLine(position, position + Vector3f::UnitZ() * 3.f * size / 4.f); + + s_primaryColor = Color::Red; + DrawCone(position + Vector3f::UnitX() * size, EulerAnglesf(0.f, 90.f, 0.f), 15, size / 4.f); + s_primaryColor = Color::Green; + DrawCone(position + Vector3f::UnitY() * size, EulerAnglesf(-90.f, 0.f, 0.f), 15, size / 4.f); + s_primaryColor = Color::Blue; + DrawCone(position + Vector3f::UnitZ() * size, EulerAnglesf(0.f, 0.f, 0.f), 15, size / 4.f); + s_primaryColor = oldPrimaryColor; } - NzBufferMapper inputMapper(subMesh->GetVertexBuffer(), nzBufferAccess_ReadOnly); - NzBufferMapper outputMapper(s_vertexBuffer, nzBufferAccess_DiscardAndWrite, 0, vertexCount); - - NzMeshVertex* inputVertex = reinterpret_cast(inputMapper.GetPointer()); - NzVertexStruct_XYZ* outputVertex = reinterpret_cast(outputMapper.GetPointer()); - - for (unsigned int i = 0; i < normalCount; ++i) + void DebugDrawer::DrawBinormals(const StaticMesh* subMesh) { - outputVertex->position = inputVertex->position; - outputVertex++; - - outputVertex->position = inputVertex->position + NzVector3f::CrossProduct(inputVertex->normal, inputVertex->tangent)*0.01f; - outputVertex++; - - inputVertex++; - } - - inputMapper.Unmap(); - outputMapper.Unmap(); - - if (vertexCount > 0) - { - NzRenderer::SetRenderStates(s_renderStates); - NzRenderer::SetShader(s_shader); - NzRenderer::SetVertexBuffer(&s_vertexBuffer); - - s_shader->SendColor(s_colorLocation, s_primaryColor); - NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, vertexCount); - } -} - -void NzDebugDrawer::DrawCone(const NzVector3f& origin, const NzQuaternionf& rotation, float angle, float length) -{ - if (!Initialize()) - { - NazaraError("Failed to initialize Debug Drawer"); - return; - } - - NzMatrix4f transformMatrix; - transformMatrix.MakeIdentity(); - transformMatrix.SetRotation(rotation); - transformMatrix.SetTranslation(origin); - - NzBufferMapper mapper(s_vertexBuffer, nzBufferAccess_DiscardAndWrite, 0, 16); - NzVertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); - - // On calcule le reste des points - NzVector3f base(NzVector3f::Forward()*length); - - // Il nous faut maintenant le rayon du cercle projeté à cette distance - // Tangente = Opposé/Adjaçent <=> Opposé = Adjaçent*Tangente - float radius = length*std::tan(NzDegreeToRadian(angle)); - NzVector3f lExtend = NzVector3f::Left()*radius; - NzVector3f uExtend = NzVector3f::Up()*radius; - - vertex->position.Set(transformMatrix * NzVector3f::Zero()); - vertex++; - vertex->position.Set(transformMatrix * (base + lExtend + uExtend)); - vertex++; - - vertex->position.Set(transformMatrix * (base + lExtend + uExtend)); - vertex++; - vertex->position.Set(transformMatrix * (base + lExtend - uExtend)); - vertex++; - - vertex->position.Set(transformMatrix * NzVector3f::Zero()); - vertex++; - vertex->position.Set(transformMatrix * (base + lExtend - uExtend)); - vertex++; - - vertex->position.Set(transformMatrix * (base + lExtend - uExtend)); - vertex++; - vertex->position.Set(transformMatrix * (base - lExtend - uExtend)); - vertex++; - - vertex->position.Set(transformMatrix * NzVector3f::Zero()); - vertex++; - vertex->position.Set(transformMatrix * (base - lExtend + uExtend)); - vertex++; - - vertex->position.Set(transformMatrix * (base - lExtend + uExtend)); - vertex++; - vertex->position.Set(transformMatrix * (base - lExtend - uExtend)); - vertex++; - - vertex->position.Set(transformMatrix * NzVector3f::Zero()); - vertex++; - vertex->position.Set(transformMatrix * (base - lExtend - uExtend)); - vertex++; - - vertex->position.Set(transformMatrix * (base - lExtend + uExtend)); - vertex++; - vertex->position.Set(transformMatrix * (base + lExtend + uExtend)); - vertex++; - - mapper.Unmap(); - - NzRenderer::SetRenderStates(s_renderStates); - NzRenderer::SetShader(s_shader); - NzRenderer::SetVertexBuffer(&s_vertexBuffer); - - s_shader->SendColor(s_colorLocation, s_primaryColor); - - NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, 16); -} - -void NzDebugDrawer::DrawLine(const NzVector3f& p1, const NzVector3f& p2) -{ - if (!s_initialized && !Initialize()) - { - NazaraError("Failed to initialize Debug Drawer"); - return; - } - - NzVertexStruct_XYZ buffer[2]; - buffer[0].position = p1; - buffer[1].position = p2; - - s_vertexBuffer.Fill(&buffer[0], 0, 2); - - NzRenderer::SetRenderStates(s_renderStates); - NzRenderer::SetShader(s_shader); - NzRenderer::SetVertexBuffer(&s_vertexBuffer); - - s_shader->SendColor(s_colorLocation, s_primaryColor); - NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, 2); -} - -void NzDebugDrawer::DrawPoints(const NzVector3f* ptr, unsigned int pointCount) -{ - static_assert(sizeof(NzVertexStruct_XYZ) == sizeof(NzVector3f), "NzVertexStruct_XYZ is no longer equal to NzVector3f, please rewrite this"); - - if (!s_initialized && !Initialize()) - { - NazaraError("Failed to initialize Debug Drawer"); - return; - } - - if (pointCount > 0) - { - s_vertexBuffer.Fill(ptr, 0, pointCount); - - NzRenderer::SetRenderStates(s_renderStates); - NzRenderer::SetShader(s_shader); - NzRenderer::SetVertexBuffer(&s_vertexBuffer); - - s_shader->SendColor(s_colorLocation, s_primaryColor); - NzRenderer::DrawPrimitives(nzPrimitiveMode_PointList, 0, pointCount); - } -} - -void NzDebugDrawer::DrawNormals(const NzStaticMesh* subMesh) -{ - if (!s_initialized && !Initialize()) - { - NazaraError("Failed to initialize Debug Drawer"); - return; - } - - unsigned int normalCount = subMesh->GetVertexCount(); - unsigned int vertexCount = normalCount*2; - if (s_vertexBuffer.GetVertexCount() < vertexCount) - { - NazaraError("Debug buffer not large enougth to draw object"); - return; - } - - NzBufferMapper inputMapper(subMesh->GetVertexBuffer(), nzBufferAccess_ReadOnly); - NzBufferMapper outputMapper(s_vertexBuffer, nzBufferAccess_DiscardAndWrite, 0, vertexCount); - - NzMeshVertex* inputVertex = reinterpret_cast(inputMapper.GetPointer()); - NzVertexStruct_XYZ* outputVertex = reinterpret_cast(outputMapper.GetPointer()); - - for (unsigned int i = 0; i < normalCount; ++i) - { - outputVertex->position = inputVertex->position; - outputVertex++; - - outputVertex->position = inputVertex->position + inputVertex->normal*0.01f; - outputVertex++; - - inputVertex++; - } - - inputMapper.Unmap(); - outputMapper.Unmap(); - - if (vertexCount > 0) - { - NzRenderer::SetRenderStates(s_renderStates); - NzRenderer::SetShader(s_shader); - NzRenderer::SetVertexBuffer(&s_vertexBuffer); - - s_shader->SendColor(s_colorLocation, s_primaryColor); - NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, vertexCount); - } -} - -void NzDebugDrawer::DrawTangents(const NzStaticMesh* subMesh) -{ - if (!s_initialized && !Initialize()) - { - NazaraError("Failed to initialize Debug Drawer"); - return; - } - - unsigned int tangentCount = subMesh->GetVertexCount(); - unsigned int vertexCount = tangentCount*2; - if (s_vertexBuffer.GetVertexCount() < vertexCount) - { - NazaraError("Debug buffer not large enougth to draw object"); - return; - } - - NzBufferMapper inputMapper(subMesh->GetVertexBuffer(), nzBufferAccess_ReadOnly); - NzBufferMapper outputMapper(s_vertexBuffer, nzBufferAccess_DiscardAndWrite, 0, vertexCount); - - NzMeshVertex* inputVertex = reinterpret_cast(inputMapper.GetPointer()); - NzVertexStruct_XYZ* outputVertex = reinterpret_cast(outputMapper.GetPointer()); - - for (unsigned int i = 0; i < tangentCount; ++i) - { - outputVertex->position = inputVertex->position; - outputVertex++; - - outputVertex->position = inputVertex->position + inputVertex->tangent*0.01f; - outputVertex++; - - inputVertex++; - } - - inputMapper.Unmap(); - outputMapper.Unmap(); - - if (vertexCount > 0) - { - NzRenderer::SetRenderStates(s_renderStates); - NzRenderer::SetShader(s_shader); - NzRenderer::SetVertexBuffer(&s_vertexBuffer); - - s_shader->SendColor(s_colorLocation, s_primaryColor); - NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, vertexCount); - } -} - -void NzDebugDrawer::EnableDepthBuffer(bool depthBuffer) -{ - s_renderStates.parameters[nzRendererParameter_DepthBuffer] = depthBuffer; -} - -float NzDebugDrawer::GetLineWidth() -{ - return s_renderStates.lineWidth; -} - -float NzDebugDrawer::GetPointSize() -{ - return s_renderStates.pointSize; -} - -NzColor NzDebugDrawer::GetPrimaryColor() -{ - return s_primaryColor; -} - -NzColor NzDebugDrawer::GetSecondaryColor() -{ - return s_secondaryColor; -} - -bool NzDebugDrawer::Initialize() -{ - if (!s_initialized) - { - // s_shader - s_shader = NzShaderLibrary::Get("DebugSimple"); - s_colorLocation = s_shader->GetUniformLocation("Color"); - - // s_vertexBuffer - try + if (!Initialize()) { - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - s_vertexBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XYZ), 65365, nzDataStorage_Hardware, nzBufferUsage_Dynamic); - } - catch (const std::exception& e) - { - NazaraError("Failed to create buffer: " + NzString(e.what())); - - Uninitialize(); - return false; + NazaraError("Failed to initialize Debug Drawer"); + return; } - s_primaryColor = NzColor::Red; - s_renderStates.parameters[nzRendererParameter_DepthBuffer] = true; - s_secondaryColor = NzColor::Green; + unsigned int normalCount = subMesh->GetVertexCount(); + unsigned int vertexCount = normalCount*2; + if (s_vertexBuffer.GetVertexCount() < vertexCount) + { + NazaraError("Debug buffer not large enougth to draw object"); + return; + } - s_initialized = true; + BufferMapper inputMapper(subMesh->GetVertexBuffer(), BufferAccess_ReadOnly); + BufferMapper outputMapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, vertexCount); + + MeshVertex* inputVertex = reinterpret_cast(inputMapper.GetPointer()); + VertexStruct_XYZ* outputVertex = reinterpret_cast(outputMapper.GetPointer()); + + for (unsigned int i = 0; i < normalCount; ++i) + { + outputVertex->position = inputVertex->position; + outputVertex++; + + outputVertex->position = inputVertex->position + Vector3f::CrossProduct(inputVertex->normal, inputVertex->tangent)*0.01f; + outputVertex++; + + inputVertex++; + } + + inputMapper.Unmap(); + outputMapper.Unmap(); + + if (vertexCount > 0) + { + Renderer::SetRenderStates(s_renderStates); + Renderer::SetShader(s_shader); + Renderer::SetVertexBuffer(&s_vertexBuffer); + + s_shader->SendColor(s_colorLocation, s_primaryColor); + Renderer::DrawPrimitives(PrimitiveMode_LineList, 0, vertexCount); + } } - return true; -} + void DebugDrawer::DrawCone(const Vector3f& origin, const Quaternionf& rotation, float angle, float length) + { + if (!Initialize()) + { + NazaraError("Failed to initialize Debug Drawer"); + return; + } -bool NzDebugDrawer::IsDepthBufferEnabled() -{ - return s_renderStates.parameters[nzRendererParameter_DepthBuffer]; -} + Matrix4f transformMatrix; + transformMatrix.MakeIdentity(); + transformMatrix.SetRotation(rotation); + transformMatrix.SetTranslation(origin); -void NzDebugDrawer::SetLineWidth(float width) -{ - s_renderStates.lineWidth = width; -} + BufferMapper mapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, 16); + VertexStruct_XYZ* vertex = reinterpret_cast(mapper.GetPointer()); -void NzDebugDrawer::SetPointSize(float size) -{ - s_renderStates.pointSize = size; -} + // On calcule le reste des points + Vector3f base(Vector3f::Forward()*length); -void NzDebugDrawer::SetPrimaryColor(const NzColor& color) -{ - s_primaryColor = color; -} + // Il nous faut maintenant le rayon du cercle projeté à cette distance + // Tangente = Opposé/Adjaçent <=> Opposé = Adjaçent*Tangente + float radius = length*std::tan(NzDegreeToRadian(angle)); + Vector3f lExtend = Vector3f::Left()*radius; + Vector3f uExtend = Vector3f::Up()*radius; -void NzDebugDrawer::SetSecondaryColor(const NzColor& color) -{ - s_secondaryColor = color; -} + vertex->position.Set(transformMatrix * Vector3f::Zero()); + vertex++; + vertex->position.Set(transformMatrix * (base + lExtend + uExtend)); + vertex++; -void NzDebugDrawer::Uninitialize() -{ - s_shader = nullptr; - s_vertexBuffer.Reset(); - s_initialized = false; + vertex->position.Set(transformMatrix * (base + lExtend + uExtend)); + vertex++; + vertex->position.Set(transformMatrix * (base + lExtend - uExtend)); + vertex++; + + vertex->position.Set(transformMatrix * Vector3f::Zero()); + vertex++; + vertex->position.Set(transformMatrix * (base + lExtend - uExtend)); + vertex++; + + vertex->position.Set(transformMatrix * (base + lExtend - uExtend)); + vertex++; + vertex->position.Set(transformMatrix * (base - lExtend - uExtend)); + vertex++; + + vertex->position.Set(transformMatrix * Vector3f::Zero()); + vertex++; + vertex->position.Set(transformMatrix * (base - lExtend + uExtend)); + vertex++; + + vertex->position.Set(transformMatrix * (base - lExtend + uExtend)); + vertex++; + vertex->position.Set(transformMatrix * (base - lExtend - uExtend)); + vertex++; + + vertex->position.Set(transformMatrix * Vector3f::Zero()); + vertex++; + vertex->position.Set(transformMatrix * (base - lExtend - uExtend)); + vertex++; + + vertex->position.Set(transformMatrix * (base - lExtend + uExtend)); + vertex++; + vertex->position.Set(transformMatrix * (base + lExtend + uExtend)); + vertex++; + + mapper.Unmap(); + + Renderer::SetRenderStates(s_renderStates); + Renderer::SetShader(s_shader); + Renderer::SetVertexBuffer(&s_vertexBuffer); + + s_shader->SendColor(s_colorLocation, s_primaryColor); + + Renderer::DrawPrimitives(PrimitiveMode_LineList, 0, 16); + } + + void DebugDrawer::DrawLine(const Vector3f& p1, const Vector3f& p2) + { + if (!s_initialized && !Initialize()) + { + NazaraError("Failed to initialize Debug Drawer"); + return; + } + + VertexStruct_XYZ buffer[2]; + buffer[0].position = p1; + buffer[1].position = p2; + + s_vertexBuffer.Fill(&buffer[0], 0, 2); + + Renderer::SetRenderStates(s_renderStates); + Renderer::SetShader(s_shader); + Renderer::SetVertexBuffer(&s_vertexBuffer); + + s_shader->SendColor(s_colorLocation, s_primaryColor); + Renderer::DrawPrimitives(PrimitiveMode_LineList, 0, 2); + } + + void DebugDrawer::DrawPoints(const Vector3f* ptr, unsigned int pointCount) + { + static_assert(sizeof(VertexStruct_XYZ) == sizeof(Vector3f), "VertexStruct_XYZ is no longer equal to Vector3f, please rewrite this"); + + if (!s_initialized && !Initialize()) + { + NazaraError("Failed to initialize Debug Drawer"); + return; + } + + if (pointCount > 0) + { + s_vertexBuffer.Fill(ptr, 0, pointCount); + + Renderer::SetRenderStates(s_renderStates); + Renderer::SetShader(s_shader); + Renderer::SetVertexBuffer(&s_vertexBuffer); + + s_shader->SendColor(s_colorLocation, s_primaryColor); + Renderer::DrawPrimitives(PrimitiveMode_PointList, 0, pointCount); + } + } + + void DebugDrawer::DrawNormals(const StaticMesh* subMesh) + { + if (!s_initialized && !Initialize()) + { + NazaraError("Failed to initialize Debug Drawer"); + return; + } + + unsigned int normalCount = subMesh->GetVertexCount(); + unsigned int vertexCount = normalCount*2; + if (s_vertexBuffer.GetVertexCount() < vertexCount) + { + NazaraError("Debug buffer not large enougth to draw object"); + return; + } + + BufferMapper inputMapper(subMesh->GetVertexBuffer(), BufferAccess_ReadOnly); + BufferMapper outputMapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, vertexCount); + + MeshVertex* inputVertex = reinterpret_cast(inputMapper.GetPointer()); + VertexStruct_XYZ* outputVertex = reinterpret_cast(outputMapper.GetPointer()); + + for (unsigned int i = 0; i < normalCount; ++i) + { + outputVertex->position = inputVertex->position; + outputVertex++; + + outputVertex->position = inputVertex->position + inputVertex->normal*0.01f; + outputVertex++; + + inputVertex++; + } + + inputMapper.Unmap(); + outputMapper.Unmap(); + + if (vertexCount > 0) + { + Renderer::SetRenderStates(s_renderStates); + Renderer::SetShader(s_shader); + Renderer::SetVertexBuffer(&s_vertexBuffer); + + s_shader->SendColor(s_colorLocation, s_primaryColor); + Renderer::DrawPrimitives(PrimitiveMode_LineList, 0, vertexCount); + } + } + + void DebugDrawer::DrawTangents(const StaticMesh* subMesh) + { + if (!s_initialized && !Initialize()) + { + NazaraError("Failed to initialize Debug Drawer"); + return; + } + + unsigned int tangentCount = subMesh->GetVertexCount(); + unsigned int vertexCount = tangentCount*2; + if (s_vertexBuffer.GetVertexCount() < vertexCount) + { + NazaraError("Debug buffer not large enougth to draw object"); + return; + } + + BufferMapper inputMapper(subMesh->GetVertexBuffer(), BufferAccess_ReadOnly); + BufferMapper outputMapper(s_vertexBuffer, BufferAccess_DiscardAndWrite, 0, vertexCount); + + MeshVertex* inputVertex = reinterpret_cast(inputMapper.GetPointer()); + VertexStruct_XYZ* outputVertex = reinterpret_cast(outputMapper.GetPointer()); + + for (unsigned int i = 0; i < tangentCount; ++i) + { + outputVertex->position = inputVertex->position; + outputVertex++; + + outputVertex->position = inputVertex->position + inputVertex->tangent*0.01f; + outputVertex++; + + inputVertex++; + } + + inputMapper.Unmap(); + outputMapper.Unmap(); + + if (vertexCount > 0) + { + Renderer::SetRenderStates(s_renderStates); + Renderer::SetShader(s_shader); + Renderer::SetVertexBuffer(&s_vertexBuffer); + + s_shader->SendColor(s_colorLocation, s_primaryColor); + Renderer::DrawPrimitives(PrimitiveMode_LineList, 0, vertexCount); + } + } + + void DebugDrawer::EnableDepthBuffer(bool depthBuffer) + { + s_renderStates.parameters[RendererParameter_DepthBuffer] = depthBuffer; + } + + float DebugDrawer::GetLineWidth() + { + return s_renderStates.lineWidth; + } + + float DebugDrawer::GetPointSize() + { + return s_renderStates.pointSize; + } + + Color DebugDrawer::GetPrimaryColor() + { + return s_primaryColor; + } + + Color DebugDrawer::GetSecondaryColor() + { + return s_secondaryColor; + } + + bool DebugDrawer::Initialize() + { + if (!s_initialized) + { + // s_shader + s_shader = ShaderLibrary::Get("DebugSimple"); + s_colorLocation = s_shader->GetUniformLocation("Color"); + + // s_vertexBuffer + try + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + s_vertexBuffer.Reset(VertexDeclaration::Get(VertexLayout_XYZ), 65365, DataStorage_Hardware, BufferUsage_Dynamic); + } + catch (const std::exception& e) + { + NazaraError("Failed to create buffer: " + String(e.what())); + + Uninitialize(); + return false; + } + + s_primaryColor = Color::Red; + s_renderStates.parameters[RendererParameter_DepthBuffer] = true; + s_secondaryColor = Color::Green; + + s_initialized = true; + } + + return true; + } + + bool DebugDrawer::IsDepthBufferEnabled() + { + return s_renderStates.parameters[RendererParameter_DepthBuffer]; + } + + void DebugDrawer::SetLineWidth(float width) + { + s_renderStates.lineWidth = width; + } + + void DebugDrawer::SetPointSize(float size) + { + s_renderStates.pointSize = size; + } + + void DebugDrawer::SetPrimaryColor(const Color& color) + { + s_primaryColor = color; + } + + void DebugDrawer::SetSecondaryColor(const Color& color) + { + s_secondaryColor = color; + } + + void DebugDrawer::Uninitialize() + { + s_shader = nullptr; + s_vertexBuffer.Reset(); + s_initialized = false; + } } diff --git a/src/Nazara/Renderer/GpuQuery.cpp b/src/Nazara/Renderer/GpuQuery.cpp index 37b03ebe7..e39613495 100644 --- a/src/Nazara/Renderer/GpuQuery.cpp +++ b/src/Nazara/Renderer/GpuQuery.cpp @@ -11,123 +11,126 @@ #include #include -NzGpuQuery::NzGpuQuery() : -m_id(0) +namespace Nz { - if (IsSupported()) + GpuQuery::GpuQuery() : + m_id(0) { - NzContext::EnsureContext(); + if (IsSupported()) + { + Context::EnsureContext(); - glGenQueries(1, reinterpret_cast(&m_id)); - } - else - { - NazaraError("Occlusion queries not supported"); - return; + glGenQueries(1, reinterpret_cast(&m_id)); + } + else + { + NazaraError("Occlusion queries not supported"); + return; + } + + #ifdef NAZARA_DEBUG + if (!m_id) + { + NazaraError("Failed to create occlusion query"); + throw std::runtime_error("Constructor failed"); + } + #endif } - #ifdef NAZARA_DEBUG - if (!m_id) + GpuQuery::~GpuQuery() { - NazaraError("Failed to create occlusion query"); - throw std::runtime_error("Constructor failed"); - } - #endif -} + if (m_id) + { + Context::EnsureContext(); -NzGpuQuery::~NzGpuQuery() -{ - if (m_id) - { - NzContext::EnsureContext(); - - GLuint query = static_cast(m_id); - glDeleteQueries(1, &query); - } -} - -void NzGpuQuery::Begin(nzGpuQueryMode mode) -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - #endif - - #if NAZARA_RENDERER_SAFE - if (!IsModeSupported(mode)) - { - NazaraError("Mode (0x" + NzString::Number(mode, 16) + ") not supported"); - return; - } - #endif - - m_mode = mode; - glBeginQuery(NzOpenGL::QueryMode[mode], m_id); -} - -void NzGpuQuery::End() -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - #endif - - glEndQuery(NzOpenGL::QueryMode[m_mode]); -} - -unsigned int NzGpuQuery::GetResult() const -{ - NzContext::EnsureContext(); - - GLuint result; - glGetQueryObjectuiv(m_id, GL_QUERY_RESULT, &result); - - return result; -} - -bool NzGpuQuery::IsResultAvailable() const -{ - NzContext::EnsureContext(); - - GLint available; - glGetQueryObjectiv(m_id, GL_QUERY_RESULT_AVAILABLE, &available); - - return available == GL_TRUE; -} - -unsigned int NzGpuQuery::GetOpenGLID() const -{ - return m_id; -} - -bool NzGpuQuery::IsModeSupported(nzGpuQueryMode mode) -{ - switch (mode) - { - case nzGpuQueryMode_AnySamplesPassed: - case nzGpuQueryMode_TimeElapsed: - return NzOpenGL::GetVersion() >= 330; - - case nzGpuQueryMode_AnySamplesPassedConservative: - return NzOpenGL::GetVersion() >= 430; - - case nzGpuQueryMode_PrimitiveGenerated: - case nzGpuQueryMode_SamplesPassed: - case nzGpuQueryMode_TransformFeedbackPrimitivesWritten: - return true; + GLuint query = static_cast(m_id); + glDeleteQueries(1, &query); + } } - NazaraError("Gpu Query mode not handled (0x" + NzString::Number(mode, 16) + ')'); - return false; -} + void GpuQuery::Begin(GpuQueryMode mode) + { + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } + #endif -bool NzGpuQuery::IsSupported() -{ - return NzRenderer::HasCapability(nzRendererCap_OcclusionQuery); + #if NAZARA_RENDERER_SAFE + if (!IsModeSupported(mode)) + { + NazaraError("Mode (0x" + String::Number(mode, 16) + ") not supported"); + return; + } + #endif + + m_mode = mode; + glBeginQuery(OpenGL::QueryMode[mode], m_id); + } + + void GpuQuery::End() + { + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } + #endif + + glEndQuery(OpenGL::QueryMode[m_mode]); + } + + unsigned int GpuQuery::GetResult() const + { + Context::EnsureContext(); + + GLuint result; + glGetQueryObjectuiv(m_id, GL_QUERY_RESULT, &result); + + return result; + } + + bool GpuQuery::IsResultAvailable() const + { + Context::EnsureContext(); + + GLint available; + glGetQueryObjectiv(m_id, GL_QUERY_RESULT_AVAILABLE, &available); + + return available == GL_TRUE; + } + + unsigned int GpuQuery::GetOpenGLID() const + { + return m_id; + } + + bool GpuQuery::IsModeSupported(GpuQueryMode mode) + { + switch (mode) + { + case GpuQueryMode_AnySamplesPassed: + case GpuQueryMode_TimeElapsed: + return OpenGL::GetVersion() >= 330; + + case GpuQueryMode_AnySamplesPassedConservative: + return OpenGL::GetVersion() >= 430; + + case GpuQueryMode_PrimitiveGenerated: + case GpuQueryMode_SamplesPassed: + case GpuQueryMode_TransformFeedbackPrimitivesWritten: + return true; + } + + NazaraError("Gpu Query mode not handled (0x" + String::Number(mode, 16) + ')'); + return false; + } + + bool GpuQuery::IsSupported() + { + return Renderer::HasCapability(RendererCap_OcclusionQuery); + } } diff --git a/src/Nazara/Renderer/HardwareBuffer.cpp b/src/Nazara/Renderer/HardwareBuffer.cpp index 891ef6289..4005b47a5 100644 --- a/src/Nazara/Renderer/HardwareBuffer.cpp +++ b/src/Nazara/Renderer/HardwareBuffer.cpp @@ -11,124 +11,127 @@ #include #include -NzHardwareBuffer::NzHardwareBuffer(NzBuffer* parent, nzBufferType type) : -m_type(type), -m_parent(parent) +namespace Nz { -} - -NzHardwareBuffer::~NzHardwareBuffer() = default; - -bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage) -{ - NzContext::EnsureContext(); - - m_buffer = 0; - glGenBuffers(1, &m_buffer); - - NzOpenGL::BindBuffer(m_type, m_buffer); - - glBufferData(NzOpenGL::BufferTarget[m_type], size, nullptr, NzOpenGL::BufferUsage[usage]); - - return true; -} - -void NzHardwareBuffer::Destroy() -{ - NzContext::EnsureContext(); - - NzOpenGL::DeleteBuffer(m_type, m_buffer); -} - -bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) -{ - NzContext::EnsureContext(); - - unsigned int totalSize = m_parent->GetSize(); - - if (!forceDiscard) - forceDiscard = (size == totalSize); - - NzOpenGL::BindBuffer(m_type, m_buffer); - - // Il semblerait que glBuffer(Sub)Data soit plus performant que glMapBuffer(Range) en dessous d'un certain seuil - // http://www.stevestreeting.com/2007/03/17/glmapbuffer-vs-glbuffersubdata-the-return/ - if (size < 32*1024) + HardwareBuffer::HardwareBuffer(Buffer* parent, BufferType type) : + m_type(type), + m_parent(parent) { - // http://www.opengl.org/wiki/Buffer_Object_Streaming - if (forceDiscard) - glBufferData(NzOpenGL::BufferTarget[m_type], totalSize, nullptr, NzOpenGL::BufferUsage[m_parent->GetUsage()]); // Discard - - glBufferSubData(NzOpenGL::BufferTarget[m_type], offset, size, data); } - else + + HardwareBuffer::~HardwareBuffer() = default; + + bool HardwareBuffer::Create(unsigned int size, BufferUsage usage) { - void* ptr = Map((forceDiscard) ? nzBufferAccess_DiscardAndWrite : nzBufferAccess_WriteOnly, offset, size); - if (!ptr) + Context::EnsureContext(); + + m_buffer = 0; + glGenBuffers(1, &m_buffer); + + OpenGL::BindBuffer(m_type, m_buffer); + + glBufferData(OpenGL::BufferTarget[m_type], size, nullptr, OpenGL::BufferUsage[usage]); + + return true; + } + + void HardwareBuffer::Destroy() + { + Context::EnsureContext(); + + OpenGL::DeleteBuffer(m_type, m_buffer); + } + + bool HardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) + { + Context::EnsureContext(); + + unsigned int totalSize = m_parent->GetSize(); + + if (!forceDiscard) + forceDiscard = (size == totalSize); + + OpenGL::BindBuffer(m_type, m_buffer); + + // Il semblerait que glBuffer(Sub)Data soit plus performant que glMapBuffer(Range) en dessous d'un certain seuil + // http://www.stevestreeting.com/2007/03/17/glmapbuffer-vs-glbuffersubdata-the-return/ + if (size < 32*1024) { - NazaraError("Failed to map buffer"); + // http://www.opengl.org/wiki/Buffer_Object_Streaming + if (forceDiscard) + glBufferData(OpenGL::BufferTarget[m_type], totalSize, nullptr, OpenGL::BufferUsage[m_parent->GetUsage()]); // Discard + + glBufferSubData(OpenGL::BufferTarget[m_type], offset, size, data); + } + else + { + void* ptr = Map((forceDiscard) ? BufferAccess_DiscardAndWrite : BufferAccess_WriteOnly, offset, size); + if (!ptr) + { + NazaraError("Failed to map buffer"); + return false; + } + + std::memcpy(ptr, data, size); + + Unmap(); + } + + return true; + } + + bool HardwareBuffer::IsHardware() const + { + return true; + } + + void* HardwareBuffer::Map(BufferAccess access, unsigned int offset, unsigned int size) + { + Context::EnsureContext(); + + OpenGL::BindBuffer(m_type, m_buffer); + + if (glMapBufferRange) + return glMapBufferRange(OpenGL::BufferTarget[m_type], offset, size, OpenGL::BufferLockRange[access]); + else + { + // http://www.opengl.org/wiki/Buffer_Object_Streaming + if (access == BufferAccess_DiscardAndWrite) + glBufferData(OpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, OpenGL::BufferUsage[m_parent->GetUsage()]); // Discard + + UInt8* ptr = static_cast(glMapBuffer(OpenGL::BufferTarget[m_type], OpenGL::BufferLock[access])); + if (ptr) + ptr += offset; + + return ptr; + } + } + + bool HardwareBuffer::Unmap() + { + Context::EnsureContext(); + + OpenGL::BindBuffer(m_type, m_buffer); + + if (glUnmapBuffer(OpenGL::BufferTarget[m_type]) != GL_TRUE) + { + glBufferData(OpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, OpenGL::BufferUsage[m_parent->GetUsage()]); + + // Une erreur rare est survenue, nous devons réinitialiser le buffer + NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error : 0x" + String::Number(glGetError(), 16) + ')'); return false; } - std::memcpy(ptr, data, size); - - Unmap(); + return true; } - return true; -} - -bool NzHardwareBuffer::IsHardware() const -{ - return true; -} - -void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size) -{ - NzContext::EnsureContext(); - - NzOpenGL::BindBuffer(m_type, m_buffer); - - if (glMapBufferRange) - return glMapBufferRange(NzOpenGL::BufferTarget[m_type], offset, size, NzOpenGL::BufferLockRange[access]); - else + void HardwareBuffer::Bind() const { - // http://www.opengl.org/wiki/Buffer_Object_Streaming - if (access == nzBufferAccess_DiscardAndWrite) - glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetUsage()]); // Discard - - nzUInt8* ptr = static_cast(glMapBuffer(NzOpenGL::BufferTarget[m_type], NzOpenGL::BufferLock[access])); - if (ptr) - ptr += offset; - - return ptr; + OpenGL::BindBuffer(m_type, m_buffer); } -} -bool NzHardwareBuffer::Unmap() -{ - NzContext::EnsureContext(); - - NzOpenGL::BindBuffer(m_type, m_buffer); - - if (glUnmapBuffer(NzOpenGL::BufferTarget[m_type]) != GL_TRUE) + unsigned int HardwareBuffer::GetOpenGLID() const { - glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetUsage()]); - - // Une erreur rare est survenue, nous devons réinitialiser le buffer - NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')'); - return false; - } - - return true; + return m_buffer; } - -void NzHardwareBuffer::Bind() const -{ - NzOpenGL::BindBuffer(m_type, m_buffer); -} - -unsigned int NzHardwareBuffer::GetOpenGLID() const -{ - return m_buffer; } diff --git a/src/Nazara/Renderer/HardwareBuffer.hpp b/src/Nazara/Renderer/HardwareBuffer.hpp index 5a7c9c107..608a1598d 100644 --- a/src/Nazara/Renderer/HardwareBuffer.hpp +++ b/src/Nazara/Renderer/HardwareBuffer.hpp @@ -11,30 +11,33 @@ #include #include -class NzHardwareBuffer : public NzAbstractBuffer +namespace Nz { - public: - NzHardwareBuffer(NzBuffer* parent, nzBufferType type); - ~NzHardwareBuffer(); + class HardwareBuffer : public AbstractBuffer + { + public: + HardwareBuffer(Buffer* parent, BufferType type); + ~HardwareBuffer(); - bool Create(unsigned int size, nzBufferUsage usage = nzBufferUsage_Static); - void Destroy(); + bool Create(unsigned int size, BufferUsage usage = BufferUsage_Static); + void Destroy(); - bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard); + bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard); - bool IsHardware() const; + bool IsHardware() const; - void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0); - bool Unmap(); + void* Map(BufferAccess access, unsigned int offset = 0, unsigned int size = 0); + bool Unmap(); - // Fonctions OpenGL - void Bind() const; - unsigned int GetOpenGLID() const; + // Fonctions OpenGL + void Bind() const; + unsigned int GetOpenGLID() const; - private: - GLuint m_buffer; - nzBufferType m_type; - NzBuffer* m_parent; -}; + private: + GLuint m_buffer; + BufferType m_type; + Buffer* m_parent; + }; +} #endif // NAZARA_HARDWAREBUFFER_HPP diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index c577f6148..90e2615e4 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -16,2197 +16,2200 @@ #include #include -namespace +namespace Nz { - #ifdef NAZARA_PLATFORM_WINDOWS - HMODULE openGLlibrary; - #endif - - NzOpenGLFunc LoadEntry(const char* name, bool launchException = true) + namespace { + #ifdef NAZARA_PLATFORM_WINDOWS + HMODULE openGLlibrary; + #endif + + OpenGLFunc LoadEntry(const char* name, bool launchException = true) + { + #if defined(NAZARA_PLATFORM_WINDOWS) + OpenGLFunc entry = reinterpret_cast(wglGetProcAddress(name)); + if (!entry) // wglGetProcAddress ne fonctionne pas sur les fonctions OpenGL <= 1.1 + entry = reinterpret_cast(GetProcAddress(openGLlibrary, name)); + #elif defined(NAZARA_PLATFORM_LINUX) + OpenGLFunc entry = reinterpret_cast(GLX::glXGetProcAddress(reinterpret_cast(name))); + #else + #error OS not handled + #endif + + if (!entry && launchException) + { + std::ostringstream oss; + oss << "failed to load \"" << name << '"'; + + throw std::runtime_error(oss.str()); + } + + return entry; + } + + bool LoadLibrary() + { + #ifdef NAZARA_PLATFORM_WINDOWS + openGLlibrary = ::LoadLibraryA("opengl32.dll"); + + return openGLlibrary != nullptr; + #else + return true; + #endif + } + + void UnloadLibrary() + { + #ifdef NAZARA_PLATFORM_WINDOWS + FreeLibrary(openGLlibrary); + #endif + } + + enum GarbageResourceType + { + GarbageResourceType_FrameBuffer, + GarbageResourceType_VertexArray + }; + + struct ContextStates + { + std::vector> garbage; // Les ressources à supprimer dès que possible + GLuint buffersBinding[BufferType_Max+1] = {0}; + GLuint currentProgram = 0; + GLuint samplers[32] = {0}; // 32 est pour l'instant la plus haute limite (GL_TEXTURE31) + GLuint texturesBinding[32] = {0}; // 32 est pour l'instant la plus haute limite (GL_TEXTURE31) + Recti currentScissorBox = Recti(0,0,0,0); + Recti currentViewport = Recti(0,0,0,0); + RenderStates renderStates; // Toujours synchronisé avec OpenGL + const RenderTarget* currentTarget = nullptr; + bool scissorBoxUpdated = true; + bool viewportUpdated = true; + unsigned int textureUnit = 0; + }; + + std::set s_openGLextensionSet; + std::unordered_map s_contexts; + thread_local ContextStates* s_contextStates = nullptr; + String s_rendererName; + String s_vendorName; + bool s_initialized = false; + bool s_openGLextensions[OpenGLExtension_Max+1] = {false}; + unsigned int s_glslVersion = 0; + unsigned int s_openglVersion = 0; + + bool LoadExtensionsString(const String& extensionString) + { + if (extensionString.IsEmpty()) + { + NazaraError("Unable to get extension string"); + return false; + } + + // On peut sûrement faire plus rapide mais comme ça ne se fait qu'une fois et que String implémente le COW... + std::vector ext; + extensionString.Split(ext); + + for (std::vector::iterator it = ext.begin(); it != ext.end(); ++it) + s_openGLextensionSet.insert(*it); + + return true; + } + + bool LoadExtensions3() + { + GLint extensionCount = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount); + + if (extensionCount <= 0) + { + NazaraError("Unable to get extension count"); + return false; + } + + for (int i = 0; i < extensionCount; ++i) + { + String extension(reinterpret_cast(glGetStringi(GL_EXTENSIONS, i))); + if (extension.IsEmpty()) + { + NazaraWarning("Unable to get extension #" + String::Number(i)); + continue; + } + + s_openGLextensionSet.insert(extension); + } + + return true; + } + } + + void OpenGL::ApplyStates(const RenderStates& states) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + RenderStates& currentRenderStates = s_contextStates->renderStates; + + // Les fonctions de blend n'a aucun intérêt sans blending + if (states.parameters[RendererParameter_Blend]) + { + if (currentRenderStates.dstBlend != states.dstBlend || + currentRenderStates.srcBlend != states.srcBlend) + { + glBlendFunc(BlendFunc[states.srcBlend], BlendFunc[states.dstBlend]); + currentRenderStates.dstBlend = states.dstBlend; + currentRenderStates.srcBlend = states.srcBlend; + } + } + + if (states.parameters[RendererParameter_DepthBuffer]) + { + // La comparaison de profondeur n'a aucun intérêt sans depth buffer + if (currentRenderStates.depthFunc != states.depthFunc) + { + glDepthFunc(RendererComparison[states.depthFunc]); + currentRenderStates.depthFunc = states.depthFunc; + } + + // Le DepthWrite n'a aucune importance si le DepthBuffer est désactivé + if (currentRenderStates.parameters[RendererParameter_DepthWrite] != states.parameters[RendererParameter_DepthWrite]) + { + glDepthMask((states.parameters[RendererParameter_DepthWrite]) ? GL_TRUE : GL_FALSE); + currentRenderStates.parameters[RendererParameter_DepthWrite] = states.parameters[RendererParameter_DepthWrite]; + } + } + + // Inutile de changer le mode de face culling s'il n'est pas actif + if (states.parameters[RendererParameter_FaceCulling]) + { + if (currentRenderStates.faceCulling != states.faceCulling) + { + glCullFace(FaceSide[states.faceCulling]); + currentRenderStates.faceCulling = states.faceCulling; + } + } + + if (currentRenderStates.faceFilling != states.faceFilling) + { + glPolygonMode(GL_FRONT_AND_BACK, FaceFilling[states.faceFilling]); + currentRenderStates.faceFilling = states.faceFilling; + } + + // Ici encore, ça ne sert à rien de se soucier des fonctions de stencil sans qu'il soit activé + if (states.parameters[RendererParameter_StencilTest]) + { + for (unsigned int i = 0; i < 2; ++i) + { + GLenum face = (i == 0) ? GL_BACK : GL_FRONT; + const RenderStates::Face& srcStates = (i == 0) ? states.backFace : states.frontFace; + RenderStates::Face& dstStates = (i == 0) ? currentRenderStates.backFace : currentRenderStates.frontFace; + + if (dstStates.stencilCompare != srcStates.stencilCompare || + dstStates.stencilMask != srcStates.stencilMask || + dstStates.stencilReference != srcStates.stencilReference) + { + glStencilFuncSeparate(face, RendererComparison[srcStates.stencilCompare], srcStates.stencilReference, srcStates.stencilMask); + dstStates.stencilCompare = srcStates.stencilCompare; + dstStates.stencilMask = srcStates.stencilMask; + dstStates.stencilReference = srcStates.stencilReference; + } + + if (dstStates.stencilFail != srcStates.stencilFail || + dstStates.stencilPass != srcStates.stencilPass || + dstStates.stencilZFail != srcStates.stencilZFail) + { + glStencilOpSeparate(face, StencilOperation[srcStates.stencilFail], StencilOperation[srcStates.stencilZFail], StencilOperation[srcStates.stencilPass]); + dstStates.stencilFail = srcStates.stencilFail; + dstStates.stencilPass = srcStates.stencilPass; + dstStates.stencilZFail = srcStates.stencilZFail; + } + } + } + + if (!NumberEquals(currentRenderStates.lineWidth, states.lineWidth, 0.001f)) + { + glLineWidth(states.lineWidth); + currentRenderStates.lineWidth = states.lineWidth; + } + + if (!NumberEquals(currentRenderStates.pointSize, states.pointSize, 0.001f)) + { + glPointSize(states.pointSize); + currentRenderStates.pointSize = states.pointSize; + } + + // Paramètres de rendu + if (currentRenderStates.parameters[RendererParameter_Blend] != states.parameters[RendererParameter_Blend]) + { + if (states.parameters[RendererParameter_Blend]) + glEnable(GL_BLEND); + else + glDisable(GL_BLEND); + + currentRenderStates.parameters[RendererParameter_Blend] = states.parameters[RendererParameter_Blend]; + } + + if (currentRenderStates.parameters[RendererParameter_ColorWrite] != states.parameters[RendererParameter_ColorWrite]) + { + GLboolean param = (states.parameters[RendererParameter_ColorWrite]) ? GL_TRUE : GL_FALSE; + glColorMask(param, param, param, param); + + currentRenderStates.parameters[RendererParameter_ColorWrite] = states.parameters[RendererParameter_ColorWrite]; + } + + if (currentRenderStates.parameters[RendererParameter_DepthBuffer] != states.parameters[RendererParameter_DepthBuffer]) + { + if (states.parameters[RendererParameter_DepthBuffer]) + glEnable(GL_DEPTH_TEST); + else + glDisable(GL_DEPTH_TEST); + + currentRenderStates.parameters[RendererParameter_DepthBuffer] = states.parameters[RendererParameter_DepthBuffer]; + } + + if (currentRenderStates.parameters[RendererParameter_FaceCulling] != states.parameters[RendererParameter_FaceCulling]) + { + if (states.parameters[RendererParameter_FaceCulling]) + glEnable(GL_CULL_FACE); + else + glDisable(GL_CULL_FACE); + + currentRenderStates.parameters[RendererParameter_FaceCulling] = states.parameters[RendererParameter_FaceCulling]; + } + + if (currentRenderStates.parameters[RendererParameter_ScissorTest] != states.parameters[RendererParameter_ScissorTest]) + { + if (states.parameters[RendererParameter_ScissorTest]) + glEnable(GL_SCISSOR_TEST); + else + glDisable(GL_SCISSOR_TEST); + + currentRenderStates.parameters[RendererParameter_ScissorTest] = states.parameters[RendererParameter_ScissorTest]; + } + + if (currentRenderStates.parameters[RendererParameter_StencilTest] != states.parameters[RendererParameter_StencilTest]) + { + if (states.parameters[RendererParameter_StencilTest]) + glEnable(GL_STENCIL_TEST); + else + glDisable(GL_STENCIL_TEST); + + currentRenderStates.parameters[RendererParameter_StencilTest] = states.parameters[RendererParameter_StencilTest]; + } + } + + void OpenGL::BindBuffer(BufferType type, GLuint id) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + if (s_contextStates->buffersBinding[type] != id) + { + glBindBuffer(BufferTarget[type], id); + s_contextStates->buffersBinding[type] = id; + } + } + + void OpenGL::BindProgram(GLuint id) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + if (s_contextStates->currentProgram != id) + { + glUseProgram(id); + s_contextStates->currentProgram = id; + } + } + + void OpenGL::BindSampler(GLuint unit, GLuint id) + { + #ifdef NAZARA_DEBUG + if (!glBindSampler) + { + NazaraError("Sampler are not supported"); + return; + } + + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + if (s_contextStates->samplers[unit] != id) + { + glBindSampler(unit, id); + s_contextStates->samplers[unit] = id; + } + } + + void OpenGL::BindScissorBox(const Recti& scissorBox) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + #if NAZARA_RENDERER_SAFE + if (scissorBox.width < 0) + { + NazaraError("Scissor box width must be positive"); + return; + } + + if (scissorBox.height < 0) + { + NazaraError("Scissor box height must be positive"); + return; + } + #endif + + if (s_contextStates->currentScissorBox != scissorBox) + { + if (s_contextStates->currentTarget) + { + unsigned int height = s_contextStates->currentTarget->GetHeight(); + glScissor(scissorBox.x, height - scissorBox.height - scissorBox.y, scissorBox.width, scissorBox.height); + s_contextStates->scissorBoxUpdated = true; + } + else + s_contextStates->scissorBoxUpdated = false; // Sinon on attend d'avoir un target + + s_contextStates->currentScissorBox = scissorBox; + } + } + + void OpenGL::BindTexture(ImageType type, GLuint id) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + if (s_contextStates->texturesBinding[s_contextStates->textureUnit] != id) + { + glBindTexture(TextureTarget[type], id); + s_contextStates->texturesBinding[s_contextStates->textureUnit] = id; + } + } + + void OpenGL::BindTexture(unsigned int textureUnit, ImageType type, GLuint id) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + if (s_contextStates->texturesBinding[textureUnit] != id) + { + BindTextureUnit(textureUnit); + + glBindTexture(TextureTarget[type], id); + s_contextStates->texturesBinding[textureUnit] = id; + } + } + + void OpenGL::BindTextureUnit(unsigned int textureUnit) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + if (s_contextStates->textureUnit != textureUnit) + { + glActiveTexture(GL_TEXTURE0 + textureUnit); + s_contextStates->textureUnit = textureUnit; + } + } + + void OpenGL::BindViewport(const Recti& viewport) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + #if NAZARA_RENDERER_SAFE + if (viewport.width < 0) + { + NazaraError("Viewport width must be positive"); + return; + } + + if (viewport.height < 0) + { + NazaraError("Viewport height must be positive"); + return; + } + #endif + + if (s_contextStates->currentViewport != viewport) + { + if (s_contextStates->currentTarget) + { + unsigned int height = s_contextStates->currentTarget->GetHeight(); + glViewport(viewport.x, height - viewport.height - viewport.y, viewport.width, viewport.height); + s_contextStates->viewportUpdated = true; + } + else + s_contextStates->viewportUpdated = false; // Sinon on attend d'avoir un target + + s_contextStates->currentViewport = viewport; + } + } + + void OpenGL::DeleteBuffer(BufferType type, GLuint id) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + glDeleteBuffers(1, &id); + if (s_contextStates->buffersBinding[type] == id) + s_contextStates->buffersBinding[type] = 0; + } + + void OpenGL::DeleteFrameBuffer(const Context* context, GLuint id) + { + // Si le contexte est actif, ne nous privons pas + if (Context::GetCurrent() == context) + glDeleteFramebuffers(1, &id); + else + s_contexts[context].garbage.emplace_back(GarbageResourceType_FrameBuffer, id); + } + + void OpenGL::DeleteProgram(GLuint id) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + glDeleteProgram(id); + if (s_contextStates->currentProgram == id) + s_contextStates->currentProgram = 0; + } + + void OpenGL::DeleteSampler(GLuint id) + { + #ifdef NAZARA_DEBUG + if (!glDeleteSamplers) + { + NazaraError("Sampler are not supported"); + return; + } + + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + glDeleteSamplers(1, &id); + + for (GLuint& binding : s_contextStates->samplers) + { + if (binding == id) + binding = 0; + } + } + + void OpenGL::DeleteTexture(GLuint id) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + glDeleteTextures(1, &id); + + for (GLuint& binding : s_contextStates->texturesBinding) + { + if (binding == id) + binding = 0; + } + } + + void OpenGL::DeleteVertexArray(const Context* context, GLuint id) + { + // Si le contexte est actif, ne nous privons pas + if (Context::GetCurrent() == context) + glDeleteFramebuffers(1, &id); + else + s_contexts[context].garbage.emplace_back(GarbageResourceType_VertexArray, id); + } + + GLuint OpenGL::GetCurrentBuffer(BufferType type) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return 0; + } + #endif + + return s_contextStates->buffersBinding[type]; + } + + GLuint OpenGL::GetCurrentProgram() + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return 0; + } + #endif + + return s_contextStates->currentProgram; + } + + Recti OpenGL::GetCurrentScissorBox() + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return Recti(); + } + #endif + + return s_contextStates->currentScissorBox; + } + + const RenderTarget* OpenGL::GetCurrentTarget() + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return nullptr; + } + #endif + + return s_contextStates->currentTarget; + } + + GLuint OpenGL::GetCurrentTexture() + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return 0; + } + #endif + + return s_contextStates->texturesBinding[s_contextStates->textureUnit]; + } + + GLuint OpenGL::GetCurrentTexture(unsigned int textureUnit) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return 0; + } + #endif + + return s_contextStates->texturesBinding[textureUnit]; + } + + unsigned int OpenGL::GetCurrentTextureUnit() + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return 0; + } + #endif + + return s_contextStates->textureUnit; + } + + Recti OpenGL::GetCurrentViewport() + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return Recti(); + } + #endif + + return s_contextStates->currentViewport; + } + + OpenGLFunc OpenGL::GetEntry(const String& entryPoint) + { + return LoadEntry(entryPoint.GetConstBuffer(), false); + } + + unsigned int OpenGL::GetGLSLVersion() + { + return s_glslVersion; + } + + String OpenGL::GetRendererName() + { + return s_rendererName; + } + + String OpenGL::GetVendorName() + { + return s_vendorName; + } + + unsigned int OpenGL::GetVersion() + { + return s_openglVersion; + } + + bool OpenGL::Initialize() + { + if (s_initialized) + return true; + + if (!LoadLibrary()) + { + NazaraError("Failed to load OpenGL library"); + return false; + } + + s_initialized = true; + + // En cas d'erreur, on libèrera OpenGL + CallOnExit onExit(OpenGL::Uninitialize); + + // Le chargement des fonctions OpenGL nécessite un contexte OpenGL + ContextParameters parameters; + parameters.majorVersion = 2; + parameters.minorVersion = 0; + parameters.shared = false; + + /* + Note: Même le contexte de chargement nécessite quelques fonctions de base pour correctement s'initialiser + Pour cette raison, deux contextes sont créés, le premier sert à récupérer les fonctions permetttant + de créer le second avec les bons paramètres. + + Non sérieusement si vous avez une meilleure idée, contactez-moi + */ + + /****************************Chargement OpenGL****************************/ + + ///FIXME: I'm really thinking this is a mistake and GLX has no need to be initialized differently (Lynix) + #if defined(NAZARA_PLATFORM_LINUX) + glXCreateContextAttribs = reinterpret_cast(LoadEntry("glXCreateContextAttribsARB", false)); + #endif + + Context loadContext; + if (!loadContext.Create(parameters)) + { + NazaraError("Failed to create load context"); + return false; + } + #if defined(NAZARA_PLATFORM_WINDOWS) - NzOpenGLFunc entry = reinterpret_cast(wglGetProcAddress(name)); - if (!entry) // wglGetProcAddress ne fonctionne pas sur les fonctions OpenGL <= 1.1 - entry = reinterpret_cast(GetProcAddress(openGLlibrary, name)); + wglCreateContextAttribs = reinterpret_cast(LoadEntry("wglCreateContextAttribsARB", false)); + wglChoosePixelFormat = reinterpret_cast(LoadEntry("wglChoosePixelFormatARB", false)); + if (!wglChoosePixelFormat) + wglChoosePixelFormat = reinterpret_cast(LoadEntry("wglChoosePixelFormatEXT", false)); + #endif + + // Récupération de la version d'OpenGL et du GLSL + // Ce code se base sur le fait que la carte graphique renverra un contexte de compatibilité avec la plus haute version supportée + // Ce qui semble vrai chez AMD, NVidia et Intel, mais j'aimerai une preuve que ça sera toujours le cas... + glGetString = reinterpret_cast(LoadEntry("glGetString", false)); + if (!glGetString) + { + NazaraError("Unable to load OpenGL: failed to load glGetString"); + return false; + } + + const GLubyte* version; + unsigned int major; + unsigned int minor; + + version = glGetString(GL_VERSION); + if (!version) + { + NazaraError("Unable to retrieve OpenGL version"); + return false; + } + + major = version[0] - '0'; + minor = version[2] - '0'; + + if (major == 0 || major > 9) + { + NazaraError("Unable to retrieve OpenGL major version"); + return false; + } + + if (minor > 9) // 0 est une valeur correcte ici (ex: OpenGL 3.0) + { + NazaraWarning("Unable to retrieve OpenGL minor version (assuming 0)"); + minor = 0; + } + + s_openglVersion = major*100 + minor*10; // Donnera 330 pour OpenGL 3.3, 410 pour OpenGL 4.1, bien plus facile à comparer + + NazaraDebug("OpenGL version: " + String::Number(major) + '.' + String::Number(minor)); + + // Le moteur ne fonctionnera pas avec OpenGL 1.x, autant s'arrêter là si c'est le cas + if (s_openglVersion < 200) + { + NazaraError("OpenGL " + String::Number(major) + '.' + String::Number(minor) + " detected (2.0 required). Please upgrade your drivers or your video card"); + return false; + } + + // Récupération de la version du GLSL, même technique + version = glGetString(GL_SHADING_LANGUAGE_VERSION); + if (!version) + { + NazaraError("Unable to retrieve GLSL version"); + return false; + } + + major = version[0] - '0'; + minor = version[2] - '0'; + + if (major == 0 || major > 9) + { + NazaraError("Unable to retrieve GLSL major version"); + return false; + } + + if (minor > 9) // 0 est une valeur correcte ici (ex: GLSL 4.0) + { + NazaraWarning("Unable to retrieve GLSL minor version (using 0)"); + minor = 0; + } + + s_glslVersion = major*100 + minor*10; // GLSL 3.3 => 330 + + // Possible uniquement dans le cas où le GLSL vient d'une extension d'OpenGL 1 + // Ce qui est rejeté il y a un moment déjà, mais on doit s'attendre à tout de la part d'un driver... + // (Exemple: Un driver OpenGL 2 mais ne supportant que le GLSL 100) + if (s_glslVersion < 110) + { + NazaraError("GLSL version is too low, please upgrade your drivers or your video card"); + return false; + } + + parameters.debugMode = true; // Certaines extensions n'apparaissent qu'avec un contexte de debug (e.g. ARB_debug_output) + parameters.majorVersion = ContextParameters::defaultMajorVersion = major; + parameters.minorVersion = ContextParameters::defaultMinorVersion = minor; + + if (!loadContext.Create(parameters)) // Destruction implicite du premier contexte + { + NazaraError("Failed to create load context"); + return false; + } + + /****************************************Noyau****************************************/ + + try + { + glActiveTexture = reinterpret_cast(LoadEntry("glActiveTexture")); + glAttachShader = reinterpret_cast(LoadEntry("glAttachShader")); + glBeginQuery = reinterpret_cast(LoadEntry("glBeginQuery")); + glBindAttribLocation = reinterpret_cast(LoadEntry("glBindAttribLocation")); + glBindBuffer = reinterpret_cast(LoadEntry("glBindBuffer")); + glBindTexture = reinterpret_cast(LoadEntry("glBindTexture")); + glBlendFunc = reinterpret_cast(LoadEntry("glBlendFunc")); + glBlendFuncSeparate = reinterpret_cast(LoadEntry("glBlendFuncSeparate")); + glBufferData = reinterpret_cast(LoadEntry("glBufferData")); + glBufferSubData = reinterpret_cast(LoadEntry("glBufferSubData")); + glClear = reinterpret_cast(LoadEntry("glClear")); + glClearColor = reinterpret_cast(LoadEntry("glClearColor")); + glClearDepth = reinterpret_cast(LoadEntry("glClearDepth")); + glClearStencil = reinterpret_cast(LoadEntry("glClearStencil")); + glCreateProgram = reinterpret_cast(LoadEntry("glCreateProgram")); + glCreateShader = reinterpret_cast(LoadEntry("glCreateShader")); + glColorMask = reinterpret_cast(LoadEntry("glColorMask")); + glCullFace = reinterpret_cast(LoadEntry("glCullFace")); + glCompileShader = reinterpret_cast(LoadEntry("glCompileShader")); + glCopyTexSubImage2D = reinterpret_cast(LoadEntry("glCopyTexSubImage2D")); + glDeleteBuffers = reinterpret_cast(LoadEntry("glDeleteBuffers")); + glDeleteQueries = reinterpret_cast(LoadEntry("glDeleteQueries")); + glDeleteProgram = reinterpret_cast(LoadEntry("glDeleteProgram")); + glDeleteShader = reinterpret_cast(LoadEntry("glDeleteShader")); + glDeleteTextures = reinterpret_cast(LoadEntry("glDeleteTextures")); + glDepthFunc = reinterpret_cast(LoadEntry("glDepthFunc")); + glDepthMask = reinterpret_cast(LoadEntry("glDepthMask")); + glDisable = reinterpret_cast(LoadEntry("glDisable")); + glDisableVertexAttribArray = reinterpret_cast(LoadEntry("glDisableVertexAttribArray")); + glDrawArrays = reinterpret_cast(LoadEntry("glDrawArrays")); + glDrawBuffer = reinterpret_cast(LoadEntry("glDrawBuffer")); + glDrawBuffers = reinterpret_cast(LoadEntry("glDrawBuffers")); + glDrawElements = reinterpret_cast(LoadEntry("glDrawElements")); + glEnable = reinterpret_cast(LoadEntry("glEnable")); + glEnableVertexAttribArray = reinterpret_cast(LoadEntry("glEnableVertexAttribArray")); + glEndQuery = reinterpret_cast(LoadEntry("glEndQuery")); + glFlush = reinterpret_cast(LoadEntry("glFlush")); + glGenBuffers = reinterpret_cast(LoadEntry("glGenBuffers")); + glGenQueries = reinterpret_cast(LoadEntry("glGenQueries")); + glGenTextures = reinterpret_cast(LoadEntry("glGenTextures")); + glGetActiveUniform = reinterpret_cast(LoadEntry("glGetActiveUniform")); + glGetBooleanv = reinterpret_cast(LoadEntry("glGetBooleanv")); + glGetBufferParameteriv = reinterpret_cast(LoadEntry("glGetBufferParameteriv")); + glGetError = reinterpret_cast(LoadEntry("glGetError")); + glGetFloatv = reinterpret_cast(LoadEntry("glGetFloatv")); + glGetIntegerv = reinterpret_cast(LoadEntry("glGetIntegerv")); + glGetQueryiv = reinterpret_cast(LoadEntry("glGetQueryiv")); + glGetQueryObjectiv = reinterpret_cast(LoadEntry("glGetQueryObjectiv")); + glGetQueryObjectuiv = reinterpret_cast(LoadEntry("glGetQueryObjectuiv")); + glGetProgramiv = reinterpret_cast(LoadEntry("glGetProgramiv")); + glGetProgramInfoLog = reinterpret_cast(LoadEntry("glGetProgramInfoLog")); + glGetShaderInfoLog = reinterpret_cast(LoadEntry("glGetShaderInfoLog")); + glGetShaderiv = reinterpret_cast(LoadEntry("glGetShaderiv")); + glGetShaderSource = reinterpret_cast(LoadEntry("glGetShaderSource")); + glGetTexImage = reinterpret_cast(LoadEntry("glGetTexImage")); + glGetTexLevelParameterfv = reinterpret_cast(LoadEntry("glGetTexLevelParameterfv")); + glGetTexLevelParameteriv = reinterpret_cast(LoadEntry("glGetTexLevelParameteriv")); + glGetTexParameterfv = reinterpret_cast(LoadEntry("glGetTexParameterfv")); + glGetTexParameteriv = reinterpret_cast(LoadEntry("glGetTexParameteriv")); + glGetUniformLocation = reinterpret_cast(LoadEntry("glGetUniformLocation")); + glIsEnabled = reinterpret_cast(LoadEntry("glIsEnabled")); + glLineWidth = reinterpret_cast(LoadEntry("glLineWidth")); + glLinkProgram = reinterpret_cast(LoadEntry("glLinkProgram")); + glMapBuffer = reinterpret_cast(LoadEntry("glMapBuffer")); + glPixelStorei = reinterpret_cast(LoadEntry("glPixelStorei")); + glPointSize = reinterpret_cast(LoadEntry("glPointSize")); + glPolygonMode = reinterpret_cast(LoadEntry("glPolygonMode")); + glReadPixels = reinterpret_cast(LoadEntry("glReadPixels")); + glScissor = reinterpret_cast(LoadEntry("glScissor")); + glShaderSource = reinterpret_cast(LoadEntry("glShaderSource")); + glStencilFunc = reinterpret_cast(LoadEntry("glStencilFunc")); + glStencilFuncSeparate = reinterpret_cast(LoadEntry("glStencilFuncSeparate")); + glStencilOp = reinterpret_cast(LoadEntry("glStencilOp")); + glStencilOpSeparate = reinterpret_cast(LoadEntry("glStencilOpSeparate")); + glTexImage2D = reinterpret_cast(LoadEntry("glTexImage2D")); + glTexImage3D = reinterpret_cast(LoadEntry("glTexImage3D")); + glTexParameterf = reinterpret_cast(LoadEntry("glTexParameterf")); + glTexParameteri = reinterpret_cast(LoadEntry("glTexParameteri")); + glTexSubImage2D = reinterpret_cast(LoadEntry("glTexSubImage2D")); + glTexSubImage3D = reinterpret_cast(LoadEntry("glTexSubImage3D")); + glUniform1f = reinterpret_cast(LoadEntry("glUniform1f")); + glUniform1i = reinterpret_cast(LoadEntry("glUniform1i")); + glUniform1fv = reinterpret_cast(LoadEntry("glUniform1fv")); + glUniform1iv = reinterpret_cast(LoadEntry("glUniform1iv")); + glUniform2fv = reinterpret_cast(LoadEntry("glUniform2fv")); + glUniform2iv = reinterpret_cast(LoadEntry("glUniform2iv")); + glUniform3fv = reinterpret_cast(LoadEntry("glUniform3fv")); + glUniform3iv = reinterpret_cast(LoadEntry("glUniform3iv")); + glUniform4fv = reinterpret_cast(LoadEntry("glUniform4fv")); + glUniform4iv = reinterpret_cast(LoadEntry("glUniform4iv")); + glUniformMatrix4fv = reinterpret_cast(LoadEntry("glUniformMatrix4fv")); + glUnmapBuffer = reinterpret_cast(LoadEntry("glUnmapBuffer")); + glUseProgram = reinterpret_cast(LoadEntry("glUseProgram")); + glVertexAttrib4f = reinterpret_cast(LoadEntry("glVertexAttrib4f")); + glVertexAttribPointer = reinterpret_cast(LoadEntry("glVertexAttribPointer")); + glViewport = reinterpret_cast(LoadEntry("glViewport")); + } + catch (const std::exception& e) + { + NazaraError("Unable to load OpenGL: " + String(e.what())); + return false; + } + + /****************************************Extensions****************************************/ + + // Fonctions optionnelles + glBindFragDataLocation = reinterpret_cast(LoadEntry("glBindFragDataLocation", false)); + if (!glBindFragDataLocation) + glBindFragDataLocation = reinterpret_cast(LoadEntry("glBindFragDataLocationEXT", false)); + + glDrawTexture = reinterpret_cast(LoadEntry("glDrawTextureNV", false)); + glFramebufferTexture = reinterpret_cast(LoadEntry("glFramebufferTexture", false)); + glGetStringi = reinterpret_cast(LoadEntry("glGetStringi", false)); + glInvalidateBufferData = reinterpret_cast(LoadEntry("glInvalidateBufferData", false)); + glMapBufferRange = reinterpret_cast(LoadEntry("glMapBufferRange", false)); + glVertexAttribIPointer = reinterpret_cast(LoadEntry("glVertexAttribIPointer", false)); + glVertexAttribLPointer = reinterpret_cast(LoadEntry("glVertexAttribLPointer", false)); + + #if defined(NAZARA_PLATFORM_WINDOWS) + wglGetExtensionsStringARB = reinterpret_cast(LoadEntry("wglGetExtensionsStringARB", false)); + wglGetExtensionsStringEXT = reinterpret_cast(LoadEntry("wglGetExtensionsStringEXT", false)); + wglSwapInterval = reinterpret_cast(LoadEntry("wglSwapIntervalEXT", false)); #elif defined(NAZARA_PLATFORM_LINUX) - NzOpenGLFunc entry = reinterpret_cast(GLX::glXGetProcAddress(reinterpret_cast(name))); - #else - #error OS not handled + glXSwapIntervalEXT = reinterpret_cast(LoadEntry("glXSwapIntervalEXT", false)); + NzglXSwapIntervalMESA = reinterpret_cast(LoadEntry("glXSwapIntervalMESA", false)); + glXSwapIntervalSGI = reinterpret_cast(LoadEntry("glXSwapIntervalSGI", false)); #endif - if (!entry && launchException) + if (!glGetStringi || !LoadExtensions3()) { - std::ostringstream oss; - oss << "failed to load \"" << name << '"'; + if (s_openglVersion >= 300) // Dans le cas contraire c'est normal + NazaraWarning("Failed to load OpenGL 3 extension system, switching to OpenGL 2 extension system..."); - throw std::runtime_error(oss.str()); + if (!LoadExtensionsString(reinterpret_cast(glGetString(GL_EXTENSIONS)))) + NazaraWarning("Failed to load extension system"); } - return entry; - } - - bool LoadLibrary() - { #ifdef NAZARA_PLATFORM_WINDOWS - openGLlibrary = ::LoadLibraryA("opengl32.dll"); - - return openGLlibrary != nullptr; - #else - return true; - #endif - } - - void UnloadLibrary() - { - #ifdef NAZARA_PLATFORM_WINDOWS - FreeLibrary(openGLlibrary); - #endif - } - - enum GarbageResourceType - { - GarbageResourceType_FrameBuffer, - GarbageResourceType_VertexArray - }; - - struct ContextStates - { - std::vector> garbage; // Les ressources à supprimer dès que possible - GLuint buffersBinding[nzBufferType_Max+1] = {0}; - GLuint currentProgram = 0; - GLuint samplers[32] = {0}; // 32 est pour l'instant la plus haute limite (GL_TEXTURE31) - GLuint texturesBinding[32] = {0}; // 32 est pour l'instant la plus haute limite (GL_TEXTURE31) - NzRecti currentScissorBox = NzRecti(0,0,0,0); - NzRecti currentViewport = NzRecti(0,0,0,0); - NzRenderStates renderStates; // Toujours synchronisé avec OpenGL - const NzRenderTarget* currentTarget = nullptr; - bool scissorBoxUpdated = true; - bool viewportUpdated = true; - unsigned int textureUnit = 0; - }; - - std::set s_openGLextensionSet; - std::unordered_map s_contexts; - thread_local ContextStates* s_contextStates = nullptr; - NzString s_rendererName; - NzString s_vendorName; - bool s_initialized = false; - bool s_openGLextensions[nzOpenGLExtension_Max+1] = {false}; - unsigned int s_glslVersion = 0; - unsigned int s_openglVersion = 0; - - bool LoadExtensionsString(const NzString& extensionString) - { - if (extensionString.IsEmpty()) { - NazaraError("Unable to get extension string"); + bool loaded; + if (wglGetExtensionsStringARB) + loaded = LoadExtensionsString(reinterpret_cast(wglGetExtensionsStringARB(wglGetCurrentDC()))); + else if (wglGetExtensionsStringEXT) + loaded = LoadExtensionsString(reinterpret_cast(wglGetExtensionsStringEXT())); + else + loaded = false; + + if (!loaded) + NazaraWarning("Failed to load wgl extension string"); + } + #endif + + // AnisotropicFilter + s_openGLextensions[OpenGLExtension_AnisotropicFilter] = IsSupported("GL_EXT_texture_filter_anisotropic"); + + // ConditionalRender + if (s_openglVersion >= 300) + { + try + { + glBeginConditionalRender = reinterpret_cast(LoadEntry("glBeginConditionalRender")); + glEndConditionalRender = reinterpret_cast(LoadEntry("glEndConditionalRender")); + + s_openGLextensions[OpenGLExtension_ConditionalRender] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load Conditional Render: " + String(e.what())); + } + } + + if (!s_openGLextensions[OpenGLExtension_ConditionalRender] && IsSupported("GL_NV_conditional_render")) + { + try + { + glBeginConditionalRender = reinterpret_cast(LoadEntry("glBeginConditionalRenderNV")); + glEndConditionalRender = reinterpret_cast(LoadEntry("glEndConditionalRenderNV")); + + s_openGLextensions[OpenGLExtension_ConditionalRender] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load GL_NV_conditional_render: " + String(e.what())); + } + } + + // DebugOutput + if (s_openglVersion >= 430 || IsSupported("GL_KHR_debug")) + { + try + { + glDebugMessageCallback = reinterpret_cast(LoadEntry("glDebugMessageCallback")); + glDebugMessageControl = reinterpret_cast(LoadEntry("glDebugMessageControl")); + glDebugMessageInsert = reinterpret_cast(LoadEntry("glDebugMessageInsert")); + glGetDebugMessageLog = reinterpret_cast(LoadEntry("glGetDebugMessageLog")); + + s_openGLextensions[OpenGLExtension_DebugOutput] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load GL_KHR_debug: " + String(e.what())); + } + } + + if (!s_openGLextensions[OpenGLExtension_DebugOutput] && IsSupported("GL_ARB_debug_output")) + { + try + { + glDebugMessageCallback = reinterpret_cast(LoadEntry("glDebugMessageCallbackARB")); + glDebugMessageControl = reinterpret_cast(LoadEntry("glDebugMessageControlARB")); + glDebugMessageInsert = reinterpret_cast(LoadEntry("glDebugMessageInsertARB")); + glGetDebugMessageLog = reinterpret_cast(LoadEntry("glGetDebugMessageLogARB")); + + s_openGLextensions[OpenGLExtension_DebugOutput] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load GL_ARB_debug_output: " + String(e.what())); + } + } + + // DrawInstanced + if (s_openglVersion >= 310) + { + try + { + glDrawArraysInstanced = reinterpret_cast(LoadEntry("glDrawArraysInstanced")); + glDrawElementsInstanced = reinterpret_cast(LoadEntry("glDrawElementsInstanced")); + + s_openGLextensions[OpenGLExtension_DrawInstanced] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load Draw Instanced: " + String(e.what())); + } + } + + if (!s_openGLextensions[OpenGLExtension_DrawInstanced] && IsSupported("GL_ARB_draw_instanced")) + { + try + { + glDrawArraysInstanced = reinterpret_cast(LoadEntry("glDrawArraysInstancedARB")); + glDrawElementsInstanced = reinterpret_cast(LoadEntry("glDrawElementsInstancedARB")); + + s_openGLextensions[OpenGLExtension_DrawInstanced] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load GL_ARB_draw_instanced: " + String(e.what())); + } + } + + // FP64 + if (s_openglVersion >= 400 || IsSupported("GL_ARB_gpu_shader_fp64")) + { + try + { + glUniform1d = reinterpret_cast(LoadEntry("glUniform1d")); + glUniform1dv = reinterpret_cast(LoadEntry("glUniform1dv")); + glUniform2dv = reinterpret_cast(LoadEntry("glUniform2dv")); + glUniform3dv = reinterpret_cast(LoadEntry("glUniform3dv")); + glUniform4dv = reinterpret_cast(LoadEntry("glUniform4dv")); + + s_openGLextensions[OpenGLExtension_FP64] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load ARB_gpu_shader_fp64: " + String(e.what())); + } + } + + // FrameBufferObject + if (s_openglVersion >= 300 || IsSupported("GL_ARB_framebuffer_object")) + { + try + { + glBindFramebuffer = reinterpret_cast(LoadEntry("glBindFramebuffer")); + glBindRenderbuffer = reinterpret_cast(LoadEntry("glBindRenderbuffer")); + glBlitFramebuffer = reinterpret_cast(LoadEntry("glBlitFramebuffer")); + glCheckFramebufferStatus = reinterpret_cast(LoadEntry("glCheckFramebufferStatus")); + glDeleteFramebuffers = reinterpret_cast(LoadEntry("glDeleteFramebuffers")); + glDeleteRenderbuffers = reinterpret_cast(LoadEntry("glDeleteRenderbuffers")); + glFramebufferRenderbuffer = reinterpret_cast(LoadEntry("glFramebufferRenderbuffer")); + glFramebufferTexture1D = reinterpret_cast(LoadEntry("glFramebufferTexture1D")); + glFramebufferTexture2D = reinterpret_cast(LoadEntry("glFramebufferTexture2D")); + glFramebufferTexture3D = reinterpret_cast(LoadEntry("glFramebufferTexture3D")); + glFramebufferTextureLayer = reinterpret_cast(LoadEntry("glFramebufferTextureLayer")); + glGenerateMipmap = reinterpret_cast(LoadEntry("glGenerateMipmap")); + glGenFramebuffers = reinterpret_cast(LoadEntry("glGenFramebuffers")); + glGenRenderbuffers = reinterpret_cast(LoadEntry("glGenRenderbuffers")); + glRenderbufferStorage = reinterpret_cast(LoadEntry("glRenderbufferStorage")); + + s_openGLextensions[OpenGLExtension_FrameBufferObject] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load ARB_framebuffer_object: (" + String(e.what()) + ")"); + } + } + + // GetProgramBinary + if (s_openglVersion >= 410 || IsSupported("GL_ARB_get_program_binary")) + { + try + { + glGetProgramBinary = reinterpret_cast(LoadEntry("glGetProgramBinary")); + glProgramBinary = reinterpret_cast(LoadEntry("glProgramBinary")); + glProgramParameteri = reinterpret_cast(LoadEntry("glProgramParameteri")); + + s_openGLextensions[OpenGLExtension_GetProgramBinary] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load ARB_get_program_binary: (" + String(e.what()) + ")"); + } + } + + // InstancedArray + if (s_openglVersion >= 330) + { + try + { + glVertexAttribDivisor = reinterpret_cast(LoadEntry("glVertexAttribDivisor")); + + s_openGLextensions[OpenGLExtension_InstancedArray] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load Instanced Array: " + String(e.what())); + } + } + + if (!s_openGLextensions[OpenGLExtension_InstancedArray] && IsSupported("GL_ARB_instanced_arrays")) + { + try + { + glVertexAttribDivisor = reinterpret_cast(LoadEntry("glVertexAttribDivisorARB")); + + s_openGLextensions[OpenGLExtension_InstancedArray] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load GL_ARB_instanced_arrays: " + String(e.what())); + } + } + + // PixelBufferObject + s_openGLextensions[OpenGLExtension_PixelBufferObject] = (s_openglVersion >= 210 || IsSupported("GL_ARB_pixel_buffer_object")); + + // SamplerObjects + if (s_openglVersion >= 330 || IsSupported("GL_ARB_sampler_objects")) + { + try + { + glBindSampler = reinterpret_cast(LoadEntry("glBindSampler")); + glDeleteSamplers = reinterpret_cast(LoadEntry("glDeleteSamplers")); + glGenSamplers = reinterpret_cast(LoadEntry("glGenSamplers")); + glSamplerParameterf = reinterpret_cast(LoadEntry("glSamplerParameterf")); + glSamplerParameteri = reinterpret_cast(LoadEntry("glSamplerParameteri")); + + s_openGLextensions[OpenGLExtension_SamplerObjects] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load ARB_sampler_objects: (" + String(e.what()) + ")"); + } + } + + // SeparateShaderObjects + if (s_openglVersion >= 400 || IsSupported("GL_ARB_separate_shader_objects")) + { + try + { + glProgramUniform1f = reinterpret_cast(LoadEntry("glProgramUniform1f")); + glProgramUniform1i = reinterpret_cast(LoadEntry("glProgramUniform1i")); + glProgramUniform1fv = reinterpret_cast(LoadEntry("glProgramUniform1fv")); + glProgramUniform1iv = reinterpret_cast(LoadEntry("glProgramUniform1iv")); + glProgramUniform2fv = reinterpret_cast(LoadEntry("glProgramUniform2fv")); + glProgramUniform2iv = reinterpret_cast(LoadEntry("glProgramUniform2iv")); + glProgramUniform3fv = reinterpret_cast(LoadEntry("glProgramUniform3fv")); + glProgramUniform3iv = reinterpret_cast(LoadEntry("glProgramUniform3iv")); + glProgramUniform4fv = reinterpret_cast(LoadEntry("glProgramUniform4fv")); + glProgramUniform4iv = reinterpret_cast(LoadEntry("glProgramUniform4iv")); + glProgramUniformMatrix4fv = reinterpret_cast(LoadEntry("glProgramUniformMatrix4fv")); + + // Si ARB_gpu_shader_fp64 est supporté, alors cette extension donne également accès aux fonctions utilisant des double + if (s_openGLextensions[OpenGLExtension_FP64]) + { + glProgramUniform1d = reinterpret_cast(LoadEntry("glProgramUniform1d")); + glProgramUniform1dv = reinterpret_cast(LoadEntry("glProgramUniform1dv")); + glProgramUniform2dv = reinterpret_cast(LoadEntry("glProgramUniform2dv")); + glProgramUniform3dv = reinterpret_cast(LoadEntry("glProgramUniform3dv")); + glProgramUniform4dv = reinterpret_cast(LoadEntry("glProgramUniform4dv")); + glProgramUniformMatrix4dv = reinterpret_cast(LoadEntry("glProgramUniformMatrix4dv")); + } + + s_openGLextensions[OpenGLExtension_SeparateShaderObjects] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load ARB_separate_shader_objects: (" + String(e.what()) + ")"); + } + } + + // Shader_ImageLoadStore + s_openGLextensions[OpenGLExtension_Shader_ImageLoadStore] = (s_openglVersion >= 420 || IsSupported("GL_ARB_shader_image_load_store")); + + // TextureArray + s_openGLextensions[OpenGLExtension_TextureArray] = (s_openglVersion >= 300 || IsSupported("GL_EXT_texture_array")); + + // TextureCompression_s3tc + s_openGLextensions[OpenGLExtension_TextureCompression_s3tc] = IsSupported("GL_EXT_texture_compression_s3tc"); + + // TextureStorage + if (s_openglVersion >= 420 || IsSupported("GL_ARB_texture_storage")) + { + try + { + glTexStorage1D = reinterpret_cast(LoadEntry("glTexStorage1D")); + glTexStorage2D = reinterpret_cast(LoadEntry("glTexStorage2D")); + glTexStorage3D = reinterpret_cast(LoadEntry("glTexStorage3D")); + + s_openGLextensions[OpenGLExtension_TextureStorage] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load ARB_texture_storage: " + String(e.what())); + } + } + + // VertexArrayObject + if (s_openglVersion >= 300 || IsSupported("GL_ARB_vertex_array_object")) + { + try + { + glBindVertexArray = reinterpret_cast(LoadEntry("glBindVertexArray")); + glDeleteVertexArrays = reinterpret_cast(LoadEntry("glDeleteVertexArrays")); + glGenVertexArrays = reinterpret_cast(LoadEntry("glGenVertexArrays")); + + s_openGLextensions[OpenGLExtension_VertexArrayObjects] = true; + } + catch (const std::exception& e) + { + NazaraWarning("Failed to load ARB_vertex_array_object: " + String(e.what())); + } + } + + // Fonctions de substitut + if (!glGenerateMipmap) + glGenerateMipmap = reinterpret_cast(LoadEntry("glGenerateMipmapEXT", false)); + + /******************************Initialisation*****************************/ + + s_contextStates = nullptr; + s_rendererName = reinterpret_cast(glGetString(GL_RENDERER)); + s_vendorName = reinterpret_cast(glGetString(GL_VENDOR)); + + // On initialise les vrais contextes OpenGL + if (!Context::Initialize()) + { + NazaraError("Failed to initialize contexts"); return false; } - // On peut sûrement faire plus rapide mais comme ça ne se fait qu'une fois et que NzString implémente le COW... - std::vector ext; - extensionString.Split(ext); - - for (std::vector::iterator it = ext.begin(); it != ext.end(); ++it) - s_openGLextensionSet.insert(*it); + // Le contexte OpenGL n'est plus assuré à partir d'ici + onExit.Reset(); return true; } - bool LoadExtensions3() + bool OpenGL::IsInitialized() { - GLint extensionCount = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount); + return s_initialized; + } - if (extensionCount <= 0) + bool OpenGL::IsSupported(OpenGLExtension extension) + { + return s_openGLextensions[extension]; + } + + bool OpenGL::IsSupported(const String& string) + { + return s_openGLextensionSet.find(string) != s_openGLextensionSet.end(); + } + + void OpenGL::SetBuffer(BufferType type, GLuint id) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) { - NazaraError("Unable to get extension count"); - return false; + NazaraError("No context activated"); + return; } + #endif - for (int i = 0; i < extensionCount; ++i) - { - NzString extension(reinterpret_cast(glGetStringi(GL_EXTENSIONS, i))); - if (extension.IsEmpty()) - { - NazaraWarning("Unable to get extension #" + NzString::Number(i)); - continue; - } - - s_openGLextensionSet.insert(extension); - } - - return true; - } -} - -void NzOpenGL::ApplyStates(const NzRenderStates& states) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - NzRenderStates& currentRenderStates = s_contextStates->renderStates; - - // Les fonctions de blend n'a aucun intérêt sans blending - if (states.parameters[nzRendererParameter_Blend]) - { - if (currentRenderStates.dstBlend != states.dstBlend || - currentRenderStates.srcBlend != states.srcBlend) - { - glBlendFunc(BlendFunc[states.srcBlend], BlendFunc[states.dstBlend]); - currentRenderStates.dstBlend = states.dstBlend; - currentRenderStates.srcBlend = states.srcBlend; - } - } - - if (states.parameters[nzRendererParameter_DepthBuffer]) - { - // La comparaison de profondeur n'a aucun intérêt sans depth buffer - if (currentRenderStates.depthFunc != states.depthFunc) - { - glDepthFunc(RendererComparison[states.depthFunc]); - currentRenderStates.depthFunc = states.depthFunc; - } - - // Le DepthWrite n'a aucune importance si le DepthBuffer est désactivé - if (currentRenderStates.parameters[nzRendererParameter_DepthWrite] != states.parameters[nzRendererParameter_DepthWrite]) - { - glDepthMask((states.parameters[nzRendererParameter_DepthWrite]) ? GL_TRUE : GL_FALSE); - currentRenderStates.parameters[nzRendererParameter_DepthWrite] = states.parameters[nzRendererParameter_DepthWrite]; - } - } - - // Inutile de changer le mode de face culling s'il n'est pas actif - if (states.parameters[nzRendererParameter_FaceCulling]) - { - if (currentRenderStates.faceCulling != states.faceCulling) - { - glCullFace(FaceSide[states.faceCulling]); - currentRenderStates.faceCulling = states.faceCulling; - } - } - - if (currentRenderStates.faceFilling != states.faceFilling) - { - glPolygonMode(GL_FRONT_AND_BACK, FaceFilling[states.faceFilling]); - currentRenderStates.faceFilling = states.faceFilling; - } - - // Ici encore, ça ne sert à rien de se soucier des fonctions de stencil sans qu'il soit activé - if (states.parameters[nzRendererParameter_StencilTest]) - { - for (unsigned int i = 0; i < 2; ++i) - { - GLenum face = (i == 0) ? GL_BACK : GL_FRONT; - const NzRenderStates::Face& srcStates = (i == 0) ? states.backFace : states.frontFace; - NzRenderStates::Face& dstStates = (i == 0) ? currentRenderStates.backFace : currentRenderStates.frontFace; - - if (dstStates.stencilCompare != srcStates.stencilCompare || - dstStates.stencilMask != srcStates.stencilMask || - dstStates.stencilReference != srcStates.stencilReference) - { - glStencilFuncSeparate(face, RendererComparison[srcStates.stencilCompare], srcStates.stencilReference, srcStates.stencilMask); - dstStates.stencilCompare = srcStates.stencilCompare; - dstStates.stencilMask = srcStates.stencilMask; - dstStates.stencilReference = srcStates.stencilReference; - } - - if (dstStates.stencilFail != srcStates.stencilFail || - dstStates.stencilPass != srcStates.stencilPass || - dstStates.stencilZFail != srcStates.stencilZFail) - { - glStencilOpSeparate(face, StencilOperation[srcStates.stencilFail], StencilOperation[srcStates.stencilZFail], StencilOperation[srcStates.stencilPass]); - dstStates.stencilFail = srcStates.stencilFail; - dstStates.stencilPass = srcStates.stencilPass; - dstStates.stencilZFail = srcStates.stencilZFail; - } - } - } - - if (!NzNumberEquals(currentRenderStates.lineWidth, states.lineWidth, 0.001f)) - { - glLineWidth(states.lineWidth); - currentRenderStates.lineWidth = states.lineWidth; - } - - if (!NzNumberEquals(currentRenderStates.pointSize, states.pointSize, 0.001f)) - { - glPointSize(states.pointSize); - currentRenderStates.pointSize = states.pointSize; - } - - // Paramètres de rendu - if (currentRenderStates.parameters[nzRendererParameter_Blend] != states.parameters[nzRendererParameter_Blend]) - { - if (states.parameters[nzRendererParameter_Blend]) - glEnable(GL_BLEND); - else - glDisable(GL_BLEND); - - currentRenderStates.parameters[nzRendererParameter_Blend] = states.parameters[nzRendererParameter_Blend]; - } - - if (currentRenderStates.parameters[nzRendererParameter_ColorWrite] != states.parameters[nzRendererParameter_ColorWrite]) - { - GLboolean param = (states.parameters[nzRendererParameter_ColorWrite]) ? GL_TRUE : GL_FALSE; - glColorMask(param, param, param, param); - - currentRenderStates.parameters[nzRendererParameter_ColorWrite] = states.parameters[nzRendererParameter_ColorWrite]; - } - - if (currentRenderStates.parameters[nzRendererParameter_DepthBuffer] != states.parameters[nzRendererParameter_DepthBuffer]) - { - if (states.parameters[nzRendererParameter_DepthBuffer]) - glEnable(GL_DEPTH_TEST); - else - glDisable(GL_DEPTH_TEST); - - currentRenderStates.parameters[nzRendererParameter_DepthBuffer] = states.parameters[nzRendererParameter_DepthBuffer]; - } - - if (currentRenderStates.parameters[nzRendererParameter_FaceCulling] != states.parameters[nzRendererParameter_FaceCulling]) - { - if (states.parameters[nzRendererParameter_FaceCulling]) - glEnable(GL_CULL_FACE); - else - glDisable(GL_CULL_FACE); - - currentRenderStates.parameters[nzRendererParameter_FaceCulling] = states.parameters[nzRendererParameter_FaceCulling]; - } - - if (currentRenderStates.parameters[nzRendererParameter_ScissorTest] != states.parameters[nzRendererParameter_ScissorTest]) - { - if (states.parameters[nzRendererParameter_ScissorTest]) - glEnable(GL_SCISSOR_TEST); - else - glDisable(GL_SCISSOR_TEST); - - currentRenderStates.parameters[nzRendererParameter_ScissorTest] = states.parameters[nzRendererParameter_ScissorTest]; - } - - if (currentRenderStates.parameters[nzRendererParameter_StencilTest] != states.parameters[nzRendererParameter_StencilTest]) - { - if (states.parameters[nzRendererParameter_StencilTest]) - glEnable(GL_STENCIL_TEST); - else - glDisable(GL_STENCIL_TEST); - - currentRenderStates.parameters[nzRendererParameter_StencilTest] = states.parameters[nzRendererParameter_StencilTest]; - } -} - -void NzOpenGL::BindBuffer(nzBufferType type, GLuint id) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - if (s_contextStates->buffersBinding[type] != id) - { - glBindBuffer(BufferTarget[type], id); s_contextStates->buffersBinding[type] = id; } -} -void NzOpenGL::BindProgram(GLuint id) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) + void OpenGL::SetScissorBox(const Recti& scissorBox) { - NazaraError("No context activated"); - return; - } - #endif - - if (s_contextStates->currentProgram != id) - { - glUseProgram(id); - s_contextStates->currentProgram = id; - } -} - -void NzOpenGL::BindSampler(GLuint unit, GLuint id) -{ - #ifdef NAZARA_DEBUG - if (!glBindSampler) - { - NazaraError("Sampler are not supported"); - return; - } - - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - if (s_contextStates->samplers[unit] != id) - { - glBindSampler(unit, id); - s_contextStates->samplers[unit] = id; - } -} - -void NzOpenGL::BindScissorBox(const NzRecti& scissorBox) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - #if NAZARA_RENDERER_SAFE - if (scissorBox.width < 0) - { - NazaraError("Scissor box width must be positive"); - return; - } - - if (scissorBox.height < 0) - { - NazaraError("Scissor box height must be positive"); - return; - } - #endif - - if (s_contextStates->currentScissorBox != scissorBox) - { - if (s_contextStates->currentTarget) + #ifdef NAZARA_DEBUG + if (!s_contextStates) { - unsigned int height = s_contextStates->currentTarget->GetHeight(); - glScissor(scissorBox.x, height - scissorBox.height - scissorBox.y, scissorBox.width, scissorBox.height); - s_contextStates->scissorBoxUpdated = true; + NazaraError("No context activated"); + return; } - else - s_contextStates->scissorBoxUpdated = false; // Sinon on attend d'avoir un target + #endif s_contextStates->currentScissorBox = scissorBox; } -} -void NzOpenGL::BindTexture(nzImageType type, GLuint id) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) + void OpenGL::SetProgram(GLuint id) { - NazaraError("No context activated"); - return; + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + s_contextStates->currentProgram = id; } - #endif - if (s_contextStates->texturesBinding[s_contextStates->textureUnit] != id) + void OpenGL::SetTarget(const RenderTarget* renderTarget) { - glBindTexture(TextureTarget[type], id); + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + + s_contextStates->currentTarget = renderTarget; + if (renderTarget) + { + if (!s_contextStates->scissorBoxUpdated) + { + const Recti& scissorBox = s_contextStates->currentViewport; + + unsigned int height = s_contextStates->currentTarget->GetHeight(); + glScissor(scissorBox.x, height - scissorBox.height - scissorBox.y, scissorBox.width, scissorBox.height); + + s_contextStates->scissorBoxUpdated = true; + } + + if (!s_contextStates->viewportUpdated) + { + const Recti& viewport = s_contextStates->currentViewport; + + unsigned int height = s_contextStates->currentTarget->GetHeight(); + glViewport(viewport.x, height - viewport.height - viewport.y, viewport.width, viewport.height); + + s_contextStates->viewportUpdated = true; + } + } + } + + void OpenGL::SetTexture(GLuint id) + { + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif + s_contextStates->texturesBinding[s_contextStates->textureUnit] = id; } -} -void NzOpenGL::BindTexture(unsigned int textureUnit, nzImageType type, GLuint id) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) + void OpenGL::SetTexture(unsigned int textureUnit, GLuint id) { - NazaraError("No context activated"); - return; - } - #endif + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif - if (s_contextStates->texturesBinding[textureUnit] != id) - { - BindTextureUnit(textureUnit); - - glBindTexture(TextureTarget[type], id); s_contextStates->texturesBinding[textureUnit] = id; } -} -void NzOpenGL::BindTextureUnit(unsigned int textureUnit) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) + void OpenGL::SetTextureUnit(unsigned int textureUnit) { - NazaraError("No context activated"); - return; - } - #endif + #ifdef NAZARA_DEBUG + if (!s_contextStates) + { + NazaraError("No context activated"); + return; + } + #endif - if (s_contextStates->textureUnit != textureUnit) - { - glActiveTexture(GL_TEXTURE0 + textureUnit); s_contextStates->textureUnit = textureUnit; } -} -void NzOpenGL::BindViewport(const NzRecti& viewport) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) + void OpenGL::SetViewport(const Recti& viewport) { - NazaraError("No context activated"); - return; - } - #endif - - #if NAZARA_RENDERER_SAFE - if (viewport.width < 0) - { - NazaraError("Viewport width must be positive"); - return; - } - - if (viewport.height < 0) - { - NazaraError("Viewport height must be positive"); - return; - } - #endif - - if (s_contextStates->currentViewport != viewport) - { - if (s_contextStates->currentTarget) + #ifdef NAZARA_DEBUG + if (!s_contextStates) { - unsigned int height = s_contextStates->currentTarget->GetHeight(); - glViewport(viewport.x, height - viewport.height - viewport.y, viewport.width, viewport.height); - s_contextStates->viewportUpdated = true; + NazaraError("No context activated"); + return; } - else - s_contextStates->viewportUpdated = false; // Sinon on attend d'avoir un target + #endif s_contextStates->currentViewport = viewport; } -} -void NzOpenGL::DeleteBuffer(nzBufferType type, GLuint id) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) + bool OpenGL::TranslateFormat(PixelFormatType pixelFormat, Format* format, FormatType type) { - NazaraError("No context activated"); - return; - } - #endif + // Par défaut + format->swizzle[0] = GL_RED; + format->swizzle[1] = GL_GREEN; + format->swizzle[2] = GL_BLUE; + format->swizzle[3] = GL_ALPHA; - glDeleteBuffers(1, &id); - if (s_contextStates->buffersBinding[type] == id) - s_contextStates->buffersBinding[type] = 0; -} - -void NzOpenGL::DeleteFrameBuffer(const NzContext* context, GLuint id) -{ - // Si le contexte est actif, ne nous privons pas - if (NzContext::GetCurrent() == context) - glDeleteFramebuffers(1, &id); - else - s_contexts[context].garbage.emplace_back(GarbageResourceType_FrameBuffer, id); -} - -void NzOpenGL::DeleteProgram(GLuint id) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - glDeleteProgram(id); - if (s_contextStates->currentProgram == id) - s_contextStates->currentProgram = 0; -} - -void NzOpenGL::DeleteSampler(GLuint id) -{ - #ifdef NAZARA_DEBUG - if (!glDeleteSamplers) - { - NazaraError("Sampler are not supported"); - return; - } - - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - glDeleteSamplers(1, &id); - - for (GLuint& binding : s_contextStates->samplers) - { - if (binding == id) - binding = 0; - } -} - -void NzOpenGL::DeleteTexture(GLuint id) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - glDeleteTextures(1, &id); - - for (GLuint& binding : s_contextStates->texturesBinding) - { - if (binding == id) - binding = 0; - } -} - -void NzOpenGL::DeleteVertexArray(const NzContext* context, GLuint id) -{ - // Si le contexte est actif, ne nous privons pas - if (NzContext::GetCurrent() == context) - glDeleteFramebuffers(1, &id); - else - s_contexts[context].garbage.emplace_back(GarbageResourceType_VertexArray, id); -} - -GLuint NzOpenGL::GetCurrentBuffer(nzBufferType type) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return 0; - } - #endif - - return s_contextStates->buffersBinding[type]; -} - -GLuint NzOpenGL::GetCurrentProgram() -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return 0; - } - #endif - - return s_contextStates->currentProgram; -} - -NzRecti NzOpenGL::GetCurrentScissorBox() -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return NzRecti(); - } - #endif - - return s_contextStates->currentScissorBox; -} - -const NzRenderTarget* NzOpenGL::GetCurrentTarget() -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return nullptr; - } - #endif - - return s_contextStates->currentTarget; -} - -GLuint NzOpenGL::GetCurrentTexture() -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return 0; - } - #endif - - return s_contextStates->texturesBinding[s_contextStates->textureUnit]; -} - -GLuint NzOpenGL::GetCurrentTexture(unsigned int textureUnit) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return 0; - } - #endif - - return s_contextStates->texturesBinding[textureUnit]; -} - -unsigned int NzOpenGL::GetCurrentTextureUnit() -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return 0; - } - #endif - - return s_contextStates->textureUnit; -} - -NzRecti NzOpenGL::GetCurrentViewport() -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return NzRecti(); - } - #endif - - return s_contextStates->currentViewport; -} - -NzOpenGLFunc NzOpenGL::GetEntry(const NzString& entryPoint) -{ - return LoadEntry(entryPoint.GetConstBuffer(), false); -} - -unsigned int NzOpenGL::GetGLSLVersion() -{ - return s_glslVersion; -} - -NzString NzOpenGL::GetRendererName() -{ - return s_rendererName; -} - -NzString NzOpenGL::GetVendorName() -{ - return s_vendorName; -} - -unsigned int NzOpenGL::GetVersion() -{ - return s_openglVersion; -} - -bool NzOpenGL::Initialize() -{ - if (s_initialized) - return true; - - if (!LoadLibrary()) - { - NazaraError("Failed to load OpenGL library"); - return false; - } - - s_initialized = true; - - // En cas d'erreur, on libèrera OpenGL - NzCallOnExit onExit(NzOpenGL::Uninitialize); - - // Le chargement des fonctions OpenGL nécessite un contexte OpenGL - NzContextParameters parameters; - parameters.majorVersion = 2; - parameters.minorVersion = 0; - parameters.shared = false; - - /* - Note: Même le contexte de chargement nécessite quelques fonctions de base pour correctement s'initialiser - Pour cette raison, deux contextes sont créés, le premier sert à récupérer les fonctions permetttant - de créer le second avec les bons paramètres. - - Non sérieusement si vous avez une meilleure idée, contactez-moi - */ - - /****************************Chargement OpenGL****************************/ - - ///FIXME: I'm really thinking this is a mistake and GLX has no need to be initialized differently (Lynix) - #if defined(NAZARA_PLATFORM_LINUX) - glXCreateContextAttribs = reinterpret_cast(LoadEntry("glXCreateContextAttribsARB", false)); - #endif - - NzContext loadContext; - if (!loadContext.Create(parameters)) - { - NazaraError("Failed to create load context"); - return false; - } - - #if defined(NAZARA_PLATFORM_WINDOWS) - wglCreateContextAttribs = reinterpret_cast(LoadEntry("wglCreateContextAttribsARB", false)); - wglChoosePixelFormat = reinterpret_cast(LoadEntry("wglChoosePixelFormatARB", false)); - if (!wglChoosePixelFormat) - wglChoosePixelFormat = reinterpret_cast(LoadEntry("wglChoosePixelFormatEXT", false)); - #endif - - // Récupération de la version d'OpenGL et du GLSL - // Ce code se base sur le fait que la carte graphique renverra un contexte de compatibilité avec la plus haute version supportée - // Ce qui semble vrai chez AMD, NVidia et Intel, mais j'aimerai une preuve que ça sera toujours le cas... - glGetString = reinterpret_cast(LoadEntry("glGetString", false)); - if (!glGetString) - { - NazaraError("Unable to load OpenGL: failed to load glGetString"); - return false; - } - - const GLubyte* version; - unsigned int major; - unsigned int minor; - - version = glGetString(GL_VERSION); - if (!version) - { - NazaraError("Unable to retrieve OpenGL version"); - return false; - } - - major = version[0] - '0'; - minor = version[2] - '0'; - - if (major == 0 || major > 9) - { - NazaraError("Unable to retrieve OpenGL major version"); - return false; - } - - if (minor > 9) // 0 est une valeur correcte ici (ex: OpenGL 3.0) - { - NazaraWarning("Unable to retrieve OpenGL minor version (assuming 0)"); - minor = 0; - } - - s_openglVersion = major*100 + minor*10; // Donnera 330 pour OpenGL 3.3, 410 pour OpenGL 4.1, bien plus facile à comparer - - NazaraDebug("OpenGL version: " + NzString::Number(major) + '.' + NzString::Number(minor)); - - // Le moteur ne fonctionnera pas avec OpenGL 1.x, autant s'arrêter là si c'est le cas - if (s_openglVersion < 200) - { - NazaraError("OpenGL " + NzString::Number(major) + '.' + NzString::Number(minor) + " detected (2.0 required). Please upgrade your drivers or your video card"); - return false; - } - - // Récupération de la version du GLSL, même technique - version = glGetString(GL_SHADING_LANGUAGE_VERSION); - if (!version) - { - NazaraError("Unable to retrieve GLSL version"); - return false; - } - - major = version[0] - '0'; - minor = version[2] - '0'; - - if (major == 0 || major > 9) - { - NazaraError("Unable to retrieve GLSL major version"); - return false; - } - - if (minor > 9) // 0 est une valeur correcte ici (ex: GLSL 4.0) - { - NazaraWarning("Unable to retrieve GLSL minor version (using 0)"); - minor = 0; - } - - s_glslVersion = major*100 + minor*10; // GLSL 3.3 => 330 - - // Possible uniquement dans le cas où le GLSL vient d'une extension d'OpenGL 1 - // Ce qui est rejeté il y a un moment déjà, mais on doit s'attendre à tout de la part d'un driver... - // (Exemple: Un driver OpenGL 2 mais ne supportant que le GLSL 100) - if (s_glslVersion < 110) - { - NazaraError("GLSL version is too low, please upgrade your drivers or your video card"); - return false; - } - - parameters.debugMode = true; // Certaines extensions n'apparaissent qu'avec un contexte de debug (e.g. ARB_debug_output) - parameters.majorVersion = NzContextParameters::defaultMajorVersion = major; - parameters.minorVersion = NzContextParameters::defaultMinorVersion = minor; - - if (!loadContext.Create(parameters)) // Destruction implicite du premier contexte - { - NazaraError("Failed to create load context"); - return false; - } - - /****************************************Noyau****************************************/ - - try - { - glActiveTexture = reinterpret_cast(LoadEntry("glActiveTexture")); - glAttachShader = reinterpret_cast(LoadEntry("glAttachShader")); - glBeginQuery = reinterpret_cast(LoadEntry("glBeginQuery")); - glBindAttribLocation = reinterpret_cast(LoadEntry("glBindAttribLocation")); - glBindBuffer = reinterpret_cast(LoadEntry("glBindBuffer")); - glBindTexture = reinterpret_cast(LoadEntry("glBindTexture")); - glBlendFunc = reinterpret_cast(LoadEntry("glBlendFunc")); - glBlendFuncSeparate = reinterpret_cast(LoadEntry("glBlendFuncSeparate")); - glBufferData = reinterpret_cast(LoadEntry("glBufferData")); - glBufferSubData = reinterpret_cast(LoadEntry("glBufferSubData")); - glClear = reinterpret_cast(LoadEntry("glClear")); - glClearColor = reinterpret_cast(LoadEntry("glClearColor")); - glClearDepth = reinterpret_cast(LoadEntry("glClearDepth")); - glClearStencil = reinterpret_cast(LoadEntry("glClearStencil")); - glCreateProgram = reinterpret_cast(LoadEntry("glCreateProgram")); - glCreateShader = reinterpret_cast(LoadEntry("glCreateShader")); - glColorMask = reinterpret_cast(LoadEntry("glColorMask")); - glCullFace = reinterpret_cast(LoadEntry("glCullFace")); - glCompileShader = reinterpret_cast(LoadEntry("glCompileShader")); - glCopyTexSubImage2D = reinterpret_cast(LoadEntry("glCopyTexSubImage2D")); - glDeleteBuffers = reinterpret_cast(LoadEntry("glDeleteBuffers")); - glDeleteQueries = reinterpret_cast(LoadEntry("glDeleteQueries")); - glDeleteProgram = reinterpret_cast(LoadEntry("glDeleteProgram")); - glDeleteShader = reinterpret_cast(LoadEntry("glDeleteShader")); - glDeleteTextures = reinterpret_cast(LoadEntry("glDeleteTextures")); - glDepthFunc = reinterpret_cast(LoadEntry("glDepthFunc")); - glDepthMask = reinterpret_cast(LoadEntry("glDepthMask")); - glDisable = reinterpret_cast(LoadEntry("glDisable")); - glDisableVertexAttribArray = reinterpret_cast(LoadEntry("glDisableVertexAttribArray")); - glDrawArrays = reinterpret_cast(LoadEntry("glDrawArrays")); - glDrawBuffer = reinterpret_cast(LoadEntry("glDrawBuffer")); - glDrawBuffers = reinterpret_cast(LoadEntry("glDrawBuffers")); - glDrawElements = reinterpret_cast(LoadEntry("glDrawElements")); - glEnable = reinterpret_cast(LoadEntry("glEnable")); - glEnableVertexAttribArray = reinterpret_cast(LoadEntry("glEnableVertexAttribArray")); - glEndQuery = reinterpret_cast(LoadEntry("glEndQuery")); - glFlush = reinterpret_cast(LoadEntry("glFlush")); - glGenBuffers = reinterpret_cast(LoadEntry("glGenBuffers")); - glGenQueries = reinterpret_cast(LoadEntry("glGenQueries")); - glGenTextures = reinterpret_cast(LoadEntry("glGenTextures")); - glGetActiveUniform = reinterpret_cast(LoadEntry("glGetActiveUniform")); - glGetBooleanv = reinterpret_cast(LoadEntry("glGetBooleanv")); - glGetBufferParameteriv = reinterpret_cast(LoadEntry("glGetBufferParameteriv")); - glGetError = reinterpret_cast(LoadEntry("glGetError")); - glGetFloatv = reinterpret_cast(LoadEntry("glGetFloatv")); - glGetIntegerv = reinterpret_cast(LoadEntry("glGetIntegerv")); - glGetQueryiv = reinterpret_cast(LoadEntry("glGetQueryiv")); - glGetQueryObjectiv = reinterpret_cast(LoadEntry("glGetQueryObjectiv")); - glGetQueryObjectuiv = reinterpret_cast(LoadEntry("glGetQueryObjectuiv")); - glGetProgramiv = reinterpret_cast(LoadEntry("glGetProgramiv")); - glGetProgramInfoLog = reinterpret_cast(LoadEntry("glGetProgramInfoLog")); - glGetShaderInfoLog = reinterpret_cast(LoadEntry("glGetShaderInfoLog")); - glGetShaderiv = reinterpret_cast(LoadEntry("glGetShaderiv")); - glGetShaderSource = reinterpret_cast(LoadEntry("glGetShaderSource")); - glGetTexImage = reinterpret_cast(LoadEntry("glGetTexImage")); - glGetTexLevelParameterfv = reinterpret_cast(LoadEntry("glGetTexLevelParameterfv")); - glGetTexLevelParameteriv = reinterpret_cast(LoadEntry("glGetTexLevelParameteriv")); - glGetTexParameterfv = reinterpret_cast(LoadEntry("glGetTexParameterfv")); - glGetTexParameteriv = reinterpret_cast(LoadEntry("glGetTexParameteriv")); - glGetUniformLocation = reinterpret_cast(LoadEntry("glGetUniformLocation")); - glIsEnabled = reinterpret_cast(LoadEntry("glIsEnabled")); - glLineWidth = reinterpret_cast(LoadEntry("glLineWidth")); - glLinkProgram = reinterpret_cast(LoadEntry("glLinkProgram")); - glMapBuffer = reinterpret_cast(LoadEntry("glMapBuffer")); - glPixelStorei = reinterpret_cast(LoadEntry("glPixelStorei")); - glPointSize = reinterpret_cast(LoadEntry("glPointSize")); - glPolygonMode = reinterpret_cast(LoadEntry("glPolygonMode")); - glReadPixels = reinterpret_cast(LoadEntry("glReadPixels")); - glScissor = reinterpret_cast(LoadEntry("glScissor")); - glShaderSource = reinterpret_cast(LoadEntry("glShaderSource")); - glStencilFunc = reinterpret_cast(LoadEntry("glStencilFunc")); - glStencilFuncSeparate = reinterpret_cast(LoadEntry("glStencilFuncSeparate")); - glStencilOp = reinterpret_cast(LoadEntry("glStencilOp")); - glStencilOpSeparate = reinterpret_cast(LoadEntry("glStencilOpSeparate")); - glTexImage2D = reinterpret_cast(LoadEntry("glTexImage2D")); - glTexImage3D = reinterpret_cast(LoadEntry("glTexImage3D")); - glTexParameterf = reinterpret_cast(LoadEntry("glTexParameterf")); - glTexParameteri = reinterpret_cast(LoadEntry("glTexParameteri")); - glTexSubImage2D = reinterpret_cast(LoadEntry("glTexSubImage2D")); - glTexSubImage3D = reinterpret_cast(LoadEntry("glTexSubImage3D")); - glUniform1f = reinterpret_cast(LoadEntry("glUniform1f")); - glUniform1i = reinterpret_cast(LoadEntry("glUniform1i")); - glUniform1fv = reinterpret_cast(LoadEntry("glUniform1fv")); - glUniform1iv = reinterpret_cast(LoadEntry("glUniform1iv")); - glUniform2fv = reinterpret_cast(LoadEntry("glUniform2fv")); - glUniform2iv = reinterpret_cast(LoadEntry("glUniform2iv")); - glUniform3fv = reinterpret_cast(LoadEntry("glUniform3fv")); - glUniform3iv = reinterpret_cast(LoadEntry("glUniform3iv")); - glUniform4fv = reinterpret_cast(LoadEntry("glUniform4fv")); - glUniform4iv = reinterpret_cast(LoadEntry("glUniform4iv")); - glUniformMatrix4fv = reinterpret_cast(LoadEntry("glUniformMatrix4fv")); - glUnmapBuffer = reinterpret_cast(LoadEntry("glUnmapBuffer")); - glUseProgram = reinterpret_cast(LoadEntry("glUseProgram")); - glVertexAttrib4f = reinterpret_cast(LoadEntry("glVertexAttrib4f")); - glVertexAttribPointer = reinterpret_cast(LoadEntry("glVertexAttribPointer")); - glViewport = reinterpret_cast(LoadEntry("glViewport")); - } - catch (const std::exception& e) - { - NazaraError("Unable to load OpenGL: " + NzString(e.what())); - return false; - } - - /****************************************Extensions****************************************/ - - // Fonctions optionnelles - glBindFragDataLocation = reinterpret_cast(LoadEntry("glBindFragDataLocation", false)); - if (!glBindFragDataLocation) - glBindFragDataLocation = reinterpret_cast(LoadEntry("glBindFragDataLocationEXT", false)); - - glDrawTexture = reinterpret_cast(LoadEntry("glDrawTextureNV", false)); - glFramebufferTexture = reinterpret_cast(LoadEntry("glFramebufferTexture", false)); - glGetStringi = reinterpret_cast(LoadEntry("glGetStringi", false)); - glInvalidateBufferData = reinterpret_cast(LoadEntry("glInvalidateBufferData", false)); - glMapBufferRange = reinterpret_cast(LoadEntry("glMapBufferRange", false)); - glVertexAttribIPointer = reinterpret_cast(LoadEntry("glVertexAttribIPointer", false)); - glVertexAttribLPointer = reinterpret_cast(LoadEntry("glVertexAttribLPointer", false)); - - #if defined(NAZARA_PLATFORM_WINDOWS) - wglGetExtensionsStringARB = reinterpret_cast(LoadEntry("wglGetExtensionsStringARB", false)); - wglGetExtensionsStringEXT = reinterpret_cast(LoadEntry("wglGetExtensionsStringEXT", false)); - wglSwapInterval = reinterpret_cast(LoadEntry("wglSwapIntervalEXT", false)); - #elif defined(NAZARA_PLATFORM_LINUX) - glXSwapIntervalEXT = reinterpret_cast(LoadEntry("glXSwapIntervalEXT", false)); - NzglXSwapIntervalMESA = reinterpret_cast(LoadEntry("glXSwapIntervalMESA", false)); - glXSwapIntervalSGI = reinterpret_cast(LoadEntry("glXSwapIntervalSGI", false)); - #endif - - if (!glGetStringi || !LoadExtensions3()) - { - if (s_openglVersion >= 300) // Dans le cas contraire c'est normal - NazaraWarning("Failed to load OpenGL 3 extension system, switching to OpenGL 2 extension system..."); - - if (!LoadExtensionsString(reinterpret_cast(glGetString(GL_EXTENSIONS)))) - NazaraWarning("Failed to load extension system"); - } - - #ifdef NAZARA_PLATFORM_WINDOWS - { - bool loaded; - if (wglGetExtensionsStringARB) - loaded = LoadExtensionsString(reinterpret_cast(wglGetExtensionsStringARB(wglGetCurrentDC()))); - else if (wglGetExtensionsStringEXT) - loaded = LoadExtensionsString(reinterpret_cast(wglGetExtensionsStringEXT())); - else - loaded = false; - - if (!loaded) - NazaraWarning("Failed to load wgl extension string"); - } - #endif - - // AnisotropicFilter - s_openGLextensions[nzOpenGLExtension_AnisotropicFilter] = IsSupported("GL_EXT_texture_filter_anisotropic"); - - // ConditionalRender - if (s_openglVersion >= 300) - { - try + switch (pixelFormat) { - glBeginConditionalRender = reinterpret_cast(LoadEntry("glBeginConditionalRender")); - glEndConditionalRender = reinterpret_cast(LoadEntry("glEndConditionalRender")); - - s_openGLextensions[nzOpenGLExtension_ConditionalRender] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load Conditional Render: " + NzString(e.what())); - } - } - - if (!s_openGLextensions[nzOpenGLExtension_ConditionalRender] && IsSupported("GL_NV_conditional_render")) - { - try - { - glBeginConditionalRender = reinterpret_cast(LoadEntry("glBeginConditionalRenderNV")); - glEndConditionalRender = reinterpret_cast(LoadEntry("glEndConditionalRenderNV")); - - s_openGLextensions[nzOpenGLExtension_ConditionalRender] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load GL_NV_conditional_render: " + NzString(e.what())); - } - } - - // DebugOutput - if (s_openglVersion >= 430 || IsSupported("GL_KHR_debug")) - { - try - { - glDebugMessageCallback = reinterpret_cast(LoadEntry("glDebugMessageCallback")); - glDebugMessageControl = reinterpret_cast(LoadEntry("glDebugMessageControl")); - glDebugMessageInsert = reinterpret_cast(LoadEntry("glDebugMessageInsert")); - glGetDebugMessageLog = reinterpret_cast(LoadEntry("glGetDebugMessageLog")); - - s_openGLextensions[nzOpenGLExtension_DebugOutput] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load GL_KHR_debug: " + NzString(e.what())); - } - } - - if (!s_openGLextensions[nzOpenGLExtension_DebugOutput] && IsSupported("GL_ARB_debug_output")) - { - try - { - glDebugMessageCallback = reinterpret_cast(LoadEntry("glDebugMessageCallbackARB")); - glDebugMessageControl = reinterpret_cast(LoadEntry("glDebugMessageControlARB")); - glDebugMessageInsert = reinterpret_cast(LoadEntry("glDebugMessageInsertARB")); - glGetDebugMessageLog = reinterpret_cast(LoadEntry("glGetDebugMessageLogARB")); - - s_openGLextensions[nzOpenGLExtension_DebugOutput] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load GL_ARB_debug_output: " + NzString(e.what())); - } - } - - // DrawInstanced - if (s_openglVersion >= 310) - { - try - { - glDrawArraysInstanced = reinterpret_cast(LoadEntry("glDrawArraysInstanced")); - glDrawElementsInstanced = reinterpret_cast(LoadEntry("glDrawElementsInstanced")); - - s_openGLextensions[nzOpenGLExtension_DrawInstanced] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load Draw Instanced: " + NzString(e.what())); - } - } - - if (!s_openGLextensions[nzOpenGLExtension_DrawInstanced] && IsSupported("GL_ARB_draw_instanced")) - { - try - { - glDrawArraysInstanced = reinterpret_cast(LoadEntry("glDrawArraysInstancedARB")); - glDrawElementsInstanced = reinterpret_cast(LoadEntry("glDrawElementsInstancedARB")); - - s_openGLextensions[nzOpenGLExtension_DrawInstanced] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load GL_ARB_draw_instanced: " + NzString(e.what())); - } - } - - // FP64 - if (s_openglVersion >= 400 || IsSupported("GL_ARB_gpu_shader_fp64")) - { - try - { - glUniform1d = reinterpret_cast(LoadEntry("glUniform1d")); - glUniform1dv = reinterpret_cast(LoadEntry("glUniform1dv")); - glUniform2dv = reinterpret_cast(LoadEntry("glUniform2dv")); - glUniform3dv = reinterpret_cast(LoadEntry("glUniform3dv")); - glUniform4dv = reinterpret_cast(LoadEntry("glUniform4dv")); - - s_openGLextensions[nzOpenGLExtension_FP64] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load ARB_gpu_shader_fp64: " + NzString(e.what())); - } - } - - // FrameBufferObject - if (s_openglVersion >= 300 || IsSupported("GL_ARB_framebuffer_object")) - { - try - { - glBindFramebuffer = reinterpret_cast(LoadEntry("glBindFramebuffer")); - glBindRenderbuffer = reinterpret_cast(LoadEntry("glBindRenderbuffer")); - glBlitFramebuffer = reinterpret_cast(LoadEntry("glBlitFramebuffer")); - glCheckFramebufferStatus = reinterpret_cast(LoadEntry("glCheckFramebufferStatus")); - glDeleteFramebuffers = reinterpret_cast(LoadEntry("glDeleteFramebuffers")); - glDeleteRenderbuffers = reinterpret_cast(LoadEntry("glDeleteRenderbuffers")); - glFramebufferRenderbuffer = reinterpret_cast(LoadEntry("glFramebufferRenderbuffer")); - glFramebufferTexture1D = reinterpret_cast(LoadEntry("glFramebufferTexture1D")); - glFramebufferTexture2D = reinterpret_cast(LoadEntry("glFramebufferTexture2D")); - glFramebufferTexture3D = reinterpret_cast(LoadEntry("glFramebufferTexture3D")); - glFramebufferTextureLayer = reinterpret_cast(LoadEntry("glFramebufferTextureLayer")); - glGenerateMipmap = reinterpret_cast(LoadEntry("glGenerateMipmap")); - glGenFramebuffers = reinterpret_cast(LoadEntry("glGenFramebuffers")); - glGenRenderbuffers = reinterpret_cast(LoadEntry("glGenRenderbuffers")); - glRenderbufferStorage = reinterpret_cast(LoadEntry("glRenderbufferStorage")); - - s_openGLextensions[nzOpenGLExtension_FrameBufferObject] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load ARB_framebuffer_object: (" + NzString(e.what()) + ")"); - } - } - - // GetProgramBinary - if (s_openglVersion >= 410 || IsSupported("GL_ARB_get_program_binary")) - { - try - { - glGetProgramBinary = reinterpret_cast(LoadEntry("glGetProgramBinary")); - glProgramBinary = reinterpret_cast(LoadEntry("glProgramBinary")); - glProgramParameteri = reinterpret_cast(LoadEntry("glProgramParameteri")); - - s_openGLextensions[nzOpenGLExtension_GetProgramBinary] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load ARB_get_program_binary: (" + NzString(e.what()) + ")"); - } - } - - // InstancedArray - if (s_openglVersion >= 330) - { - try - { - glVertexAttribDivisor = reinterpret_cast(LoadEntry("glVertexAttribDivisor")); - - s_openGLextensions[nzOpenGLExtension_InstancedArray] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load Instanced Array: " + NzString(e.what())); - } - } - - if (!s_openGLextensions[nzOpenGLExtension_InstancedArray] && IsSupported("GL_ARB_instanced_arrays")) - { - try - { - glVertexAttribDivisor = reinterpret_cast(LoadEntry("glVertexAttribDivisorARB")); - - s_openGLextensions[nzOpenGLExtension_InstancedArray] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load GL_ARB_instanced_arrays: " + NzString(e.what())); - } - } - - // PixelBufferObject - s_openGLextensions[nzOpenGLExtension_PixelBufferObject] = (s_openglVersion >= 210 || IsSupported("GL_ARB_pixel_buffer_object")); - - // SamplerObjects - if (s_openglVersion >= 330 || IsSupported("GL_ARB_sampler_objects")) - { - try - { - glBindSampler = reinterpret_cast(LoadEntry("glBindSampler")); - glDeleteSamplers = reinterpret_cast(LoadEntry("glDeleteSamplers")); - glGenSamplers = reinterpret_cast(LoadEntry("glGenSamplers")); - glSamplerParameterf = reinterpret_cast(LoadEntry("glSamplerParameterf")); - glSamplerParameteri = reinterpret_cast(LoadEntry("glSamplerParameteri")); - - s_openGLextensions[nzOpenGLExtension_SamplerObjects] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load ARB_sampler_objects: (" + NzString(e.what()) + ")"); - } - } - - // SeparateShaderObjects - if (s_openglVersion >= 400 || IsSupported("GL_ARB_separate_shader_objects")) - { - try - { - glProgramUniform1f = reinterpret_cast(LoadEntry("glProgramUniform1f")); - glProgramUniform1i = reinterpret_cast(LoadEntry("glProgramUniform1i")); - glProgramUniform1fv = reinterpret_cast(LoadEntry("glProgramUniform1fv")); - glProgramUniform1iv = reinterpret_cast(LoadEntry("glProgramUniform1iv")); - glProgramUniform2fv = reinterpret_cast(LoadEntry("glProgramUniform2fv")); - glProgramUniform2iv = reinterpret_cast(LoadEntry("glProgramUniform2iv")); - glProgramUniform3fv = reinterpret_cast(LoadEntry("glProgramUniform3fv")); - glProgramUniform3iv = reinterpret_cast(LoadEntry("glProgramUniform3iv")); - glProgramUniform4fv = reinterpret_cast(LoadEntry("glProgramUniform4fv")); - glProgramUniform4iv = reinterpret_cast(LoadEntry("glProgramUniform4iv")); - glProgramUniformMatrix4fv = reinterpret_cast(LoadEntry("glProgramUniformMatrix4fv")); - - // Si ARB_gpu_shader_fp64 est supporté, alors cette extension donne également accès aux fonctions utilisant des double - if (s_openGLextensions[nzOpenGLExtension_FP64]) - { - glProgramUniform1d = reinterpret_cast(LoadEntry("glProgramUniform1d")); - glProgramUniform1dv = reinterpret_cast(LoadEntry("glProgramUniform1dv")); - glProgramUniform2dv = reinterpret_cast(LoadEntry("glProgramUniform2dv")); - glProgramUniform3dv = reinterpret_cast(LoadEntry("glProgramUniform3dv")); - glProgramUniform4dv = reinterpret_cast(LoadEntry("glProgramUniform4dv")); - glProgramUniformMatrix4dv = reinterpret_cast(LoadEntry("glProgramUniformMatrix4dv")); - } - - s_openGLextensions[nzOpenGLExtension_SeparateShaderObjects] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load ARB_separate_shader_objects: (" + NzString(e.what()) + ")"); - } - } - - // Shader_ImageLoadStore - s_openGLextensions[nzOpenGLExtension_Shader_ImageLoadStore] = (s_openglVersion >= 420 || IsSupported("GL_ARB_shader_image_load_store")); - - // TextureArray - s_openGLextensions[nzOpenGLExtension_TextureArray] = (s_openglVersion >= 300 || IsSupported("GL_EXT_texture_array")); - - // TextureCompression_s3tc - s_openGLextensions[nzOpenGLExtension_TextureCompression_s3tc] = IsSupported("GL_EXT_texture_compression_s3tc"); - - // TextureStorage - if (s_openglVersion >= 420 || IsSupported("GL_ARB_texture_storage")) - { - try - { - glTexStorage1D = reinterpret_cast(LoadEntry("glTexStorage1D")); - glTexStorage2D = reinterpret_cast(LoadEntry("glTexStorage2D")); - glTexStorage3D = reinterpret_cast(LoadEntry("glTexStorage3D")); - - s_openGLextensions[nzOpenGLExtension_TextureStorage] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load ARB_texture_storage: " + NzString(e.what())); - } - } - - // VertexArrayObject - if (s_openglVersion >= 300 || IsSupported("GL_ARB_vertex_array_object")) - { - try - { - glBindVertexArray = reinterpret_cast(LoadEntry("glBindVertexArray")); - glDeleteVertexArrays = reinterpret_cast(LoadEntry("glDeleteVertexArrays")); - glGenVertexArrays = reinterpret_cast(LoadEntry("glGenVertexArrays")); - - s_openGLextensions[nzOpenGLExtension_VertexArrayObjects] = true; - } - catch (const std::exception& e) - { - NazaraWarning("Failed to load ARB_vertex_array_object: " + NzString(e.what())); - } - } - - // Fonctions de substitut - if (!glGenerateMipmap) - glGenerateMipmap = reinterpret_cast(LoadEntry("glGenerateMipmapEXT", false)); - - /******************************Initialisation*****************************/ - - s_contextStates = nullptr; - s_rendererName = reinterpret_cast(glGetString(GL_RENDERER)); - s_vendorName = reinterpret_cast(glGetString(GL_VENDOR)); - - // On initialise les vrais contextes OpenGL - if (!NzContext::Initialize()) - { - NazaraError("Failed to initialize contexts"); - return false; - } - - // Le contexte OpenGL n'est plus assuré à partir d'ici - onExit.Reset(); - - return true; -} - -bool NzOpenGL::IsInitialized() -{ - return s_initialized; -} - -bool NzOpenGL::IsSupported(nzOpenGLExtension extension) -{ - return s_openGLextensions[extension]; -} - -bool NzOpenGL::IsSupported(const NzString& string) -{ - return s_openGLextensionSet.find(string) != s_openGLextensionSet.end(); -} - -void NzOpenGL::SetBuffer(nzBufferType type, GLuint id) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - s_contextStates->buffersBinding[type] = id; -} - -void NzOpenGL::SetScissorBox(const NzRecti& scissorBox) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - s_contextStates->currentScissorBox = scissorBox; -} - -void NzOpenGL::SetProgram(GLuint id) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - s_contextStates->currentProgram = id; -} - -void NzOpenGL::SetTarget(const NzRenderTarget* renderTarget) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - s_contextStates->currentTarget = renderTarget; - if (renderTarget) - { - if (!s_contextStates->scissorBoxUpdated) - { - const NzRecti& scissorBox = s_contextStates->currentViewport; - - unsigned int height = s_contextStates->currentTarget->GetHeight(); - glScissor(scissorBox.x, height - scissorBox.height - scissorBox.y, scissorBox.width, scissorBox.height); - - s_contextStates->scissorBoxUpdated = true; - } - - if (!s_contextStates->viewportUpdated) - { - const NzRecti& viewport = s_contextStates->currentViewport; - - unsigned int height = s_contextStates->currentTarget->GetHeight(); - glViewport(viewport.x, height - viewport.height - viewport.y, viewport.width, viewport.height); - - s_contextStates->viewportUpdated = true; - } - } -} - -void NzOpenGL::SetTexture(GLuint id) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - s_contextStates->texturesBinding[s_contextStates->textureUnit] = id; -} - -void NzOpenGL::SetTexture(unsigned int textureUnit, GLuint id) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - s_contextStates->texturesBinding[textureUnit] = id; -} - -void NzOpenGL::SetTextureUnit(unsigned int textureUnit) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - s_contextStates->textureUnit = textureUnit; -} - -void NzOpenGL::SetViewport(const NzRecti& viewport) -{ - #ifdef NAZARA_DEBUG - if (!s_contextStates) - { - NazaraError("No context activated"); - return; - } - #endif - - s_contextStates->currentViewport = viewport; -} - -bool NzOpenGL::TranslateFormat(nzPixelFormat pixelFormat, Format* format, FormatType type) -{ - // Par défaut - format->swizzle[0] = GL_RED; - format->swizzle[1] = GL_GREEN; - format->swizzle[2] = GL_BLUE; - format->swizzle[3] = GL_ALPHA; - - switch (pixelFormat) - { - case nzPixelFormat_A8: - if (type == FormatType_Texture) // Format supporté uniquement par les textures - { - if (GetVersion() >= 300) + case PixelFormatType_A8: + if (type == FormatType_Texture) // Format supporté uniquement par les textures { - format->dataFormat = GL_RED; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_R8; + if (GetVersion() >= 300) + { + format->dataFormat = GL_RED; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_R8; - // Simulation du format - format->swizzle[0] = GL_ONE; - format->swizzle[1] = GL_ONE; - format->swizzle[2] = GL_ONE; - format->swizzle[3] = GL_RED; + // Simulation du format + format->swizzle[0] = GL_ONE; + format->swizzle[1] = GL_ONE; + format->swizzle[2] = GL_ONE; + format->swizzle[3] = GL_RED; + } + else + { + // Le bon vieux format GL_ALPHA + format->dataFormat = GL_ALPHA; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_ALPHA; + } + + return true; } else - { - // Le bon vieux format GL_ALPHA - format->dataFormat = GL_ALPHA; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_ALPHA; - } + return false; + case PixelFormatType_BGR8: + format->dataFormat = GL_BGR; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_RGB8; return true; - } - else - return false; - case nzPixelFormat_BGR8: - format->dataFormat = GL_BGR; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_RGB8; - return true; + case PixelFormatType_BGRA8: + format->dataFormat = GL_BGRA; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_RGBA8; + return true; - case nzPixelFormat_BGRA8: - format->dataFormat = GL_BGRA; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_RGBA8; - return true; + case PixelFormatType_DXT1: + format->dataFormat = GL_RGB; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + return true; - case nzPixelFormat_DXT1: - format->dataFormat = GL_RGB; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; - return true; + case PixelFormatType_DXT3: + format->dataFormat = GL_RGBA; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + return true; - case nzPixelFormat_DXT3: - format->dataFormat = GL_RGBA; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; - return true; + case PixelFormatType_DXT5: + format->dataFormat = GL_RGBA; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + return true; - case nzPixelFormat_DXT5: - format->dataFormat = GL_RGBA; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; - return true; - - case nzPixelFormat_L8: - if (type == FormatType_Texture) // Format supporté uniquement par les textures - { - if (GetVersion() >= 300) + case PixelFormatType_L8: + if (type == FormatType_Texture) // Format supporté uniquement par les textures { - format->dataFormat = GL_RED; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_R8; + if (GetVersion() >= 300) + { + format->dataFormat = GL_RED; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_R8; - // Simulation du format - format->swizzle[0] = GL_RED; - format->swizzle[1] = GL_RED; - format->swizzle[2] = GL_RED; - format->swizzle[3] = GL_ONE; + // Simulation du format + format->swizzle[0] = GL_RED; + format->swizzle[1] = GL_RED; + format->swizzle[2] = GL_RED; + format->swizzle[3] = GL_ONE; + } + else + { + format->dataFormat = 0x1909; // GL_LUMINANCE + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = 0x1909; // GL_LUMINANCE + } + + return true; } else + return false; + + case PixelFormatType_LA8: + if (type == FormatType_Texture) // Format supporté uniquement par les textures { - format->dataFormat = 0x1909; // GL_LUMINANCE - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = 0x1909; // GL_LUMINANCE - } + if (GetVersion() >= 300) + { + format->dataFormat = GL_RG; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_RG8; - return true; - } - else - return false; + // Simulation du format + format->swizzle[0] = GL_RED; + format->swizzle[1] = GL_RED; + format->swizzle[2] = GL_RED; + format->swizzle[3] = GL_GREEN; + } + else + { + format->dataFormat = 0x190A; // GL_LUMINANCE_ALPHA + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = 0x190A; // GL_LUMINANCE_ALPHA; + } - case nzPixelFormat_LA8: - if (type == FormatType_Texture) // Format supporté uniquement par les textures - { - if (GetVersion() >= 300) - { - format->dataFormat = GL_RG; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_RG8; - - // Simulation du format - format->swizzle[0] = GL_RED; - format->swizzle[1] = GL_RED; - format->swizzle[2] = GL_RED; - format->swizzle[3] = GL_GREEN; + return true; } + else + return false; + + case PixelFormatType_R8: + format->dataFormat = GL_RED; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_R8; + return true; + + case PixelFormatType_R8I: + format->dataFormat = GL_RED; + format->dataType = GL_BYTE; + format->internalFormat = GL_R8I; + return true; + + case PixelFormatType_R8UI: + format->dataFormat = GL_RED; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_R8UI; + return true; + + case PixelFormatType_R16: + format->dataFormat = GL_RED; + format->dataType = GL_UNSIGNED_SHORT; + format->internalFormat = GL_R16; + return true; + + case PixelFormatType_R16F: + format->dataFormat = GL_RED; + format->dataType = GL_HALF_FLOAT; + format->internalFormat = GL_R16F; + return true; + + case PixelFormatType_R16I: + format->dataFormat = GL_RED; + format->dataType = GL_SHORT; + format->internalFormat = GL_R16I; + return true; + + case PixelFormatType_R16UI: + format->dataFormat = GL_RED; + format->dataType = GL_UNSIGNED_SHORT; + format->internalFormat = GL_R16UI; + return true; + + case PixelFormatType_R32F: + format->dataFormat = GL_RED; + format->dataType = GL_FLOAT; + format->internalFormat = GL_R32F; + return true; + + case PixelFormatType_R32I: + format->dataFormat = GL_RED; + format->dataType = GL_INT; + format->internalFormat = GL_R32I; + return true; + + case PixelFormatType_R32UI: + format->dataFormat = GL_RED; + format->dataType = GL_UNSIGNED_INT; + format->internalFormat = GL_R32UI; + return true; + + case PixelFormatType_RG8: + format->dataFormat = GL_RG; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_RG8; + return true; + + case PixelFormatType_RG8I: + format->dataFormat = GL_RG; + format->dataType = GL_BYTE; + format->internalFormat = GL_RG8I; + return true; + + case PixelFormatType_RG8UI: + format->dataFormat = GL_RG; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_RG8UI; + return true; + + case PixelFormatType_RG16: + format->dataFormat = GL_RG; + format->dataType = GL_UNSIGNED_SHORT; + format->internalFormat = GL_RG16; + return true; + + case PixelFormatType_RG16F: + format->dataFormat = GL_RG; + format->dataType = GL_HALF_FLOAT; + format->internalFormat = GL_RG16F; + return true; + + case PixelFormatType_RG16I: + format->dataFormat = GL_RG; + format->dataType = GL_SHORT; + format->internalFormat = GL_RG16I; + return true; + + case PixelFormatType_RG16UI: + format->dataFormat = GL_RG; + format->dataType = GL_UNSIGNED_SHORT; + format->internalFormat = GL_RG16UI; + return true; + + case PixelFormatType_RG32F: + format->dataFormat = GL_RG; + format->dataType = GL_FLOAT; + format->internalFormat = GL_RG32F; + return true; + + case PixelFormatType_RG32I: + format->dataFormat = GL_RG; + format->dataType = GL_INT; + format->internalFormat = GL_RG32I; + return true; + + case PixelFormatType_RG32UI: + format->dataFormat = GL_RG; + format->dataType = GL_UNSIGNED_INT; + format->internalFormat = GL_RG32UI; + return true; + + case PixelFormatType_RGB5A1: + format->dataFormat = GL_RGBA; + format->dataType = GL_UNSIGNED_SHORT_5_5_5_1; + format->internalFormat = GL_RGB5_A1; + return true; + + case PixelFormatType_RGB8: + format->dataFormat = GL_RGB; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_RGB8; + return true; + + case PixelFormatType_RGB16F: + format->dataFormat = GL_RGB; + format->dataType = GL_HALF_FLOAT; + format->internalFormat = GL_RGB16F; + return true; + + case PixelFormatType_RGB16I: + format->dataFormat = GL_RGB; + format->dataType = GL_SHORT; + format->internalFormat = GL_RGB16I; + return true; + + case PixelFormatType_RGB16UI: + format->dataFormat = GL_RGB; + format->dataType = GL_UNSIGNED_SHORT; + format->internalFormat = GL_RGB16UI; + return true; + + case PixelFormatType_RGB32F: + format->dataFormat = GL_RGB; + format->dataType = GL_FLOAT; + format->internalFormat = GL_RGB32F; + return true; + + case PixelFormatType_RGB32I: + format->dataFormat = GL_RGB; + format->dataType = GL_INT; + format->internalFormat = GL_RGB32I; + return true; + + case PixelFormatType_RGB32UI: + format->dataFormat = GL_RGB; + format->dataType = GL_UNSIGNED_INT; + format->internalFormat = GL_RGB32UI; + return true; + + case PixelFormatType_RGBA4: + format->dataFormat = GL_RGBA; + format->dataType = GL_UNSIGNED_SHORT_4_4_4_4; + format->internalFormat = GL_RGBA4; + return true; + + case PixelFormatType_RGBA8: + format->dataFormat = GL_RGBA; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_RGBA8; + return true; + + case PixelFormatType_RGBA16F: + format->dataFormat = GL_RGBA; + format->dataType = GL_HALF_FLOAT; + format->internalFormat = GL_RGBA16F; + return true; + + case PixelFormatType_RGBA16I: + format->dataFormat = GL_RGBA; + format->dataType = GL_SHORT; + format->internalFormat = GL_RGBA16I; + return true; + + case PixelFormatType_RGBA16UI: + format->dataFormat = GL_RGBA; + format->dataType = GL_INT; + format->internalFormat = GL_RGBA16UI; + return true; + + case PixelFormatType_RGBA32F: + format->dataFormat = GL_RGBA; + format->dataType = GL_FLOAT; + format->internalFormat = GL_RGBA32F; + return true; + + case PixelFormatType_RGBA32I: + format->dataFormat = GL_RGB; + format->dataType = GL_INT; + format->internalFormat = GL_RGB32I; + return true; + + case PixelFormatType_RGBA32UI: + format->dataFormat = GL_RGB; + format->dataType = GL_UNSIGNED_INT; + format->internalFormat = GL_RGB32UI; + return true; + + case PixelFormatType_Depth16: + format->dataFormat = GL_DEPTH_COMPONENT; + format->dataType = GL_UNSIGNED_SHORT; + format->internalFormat = GL_DEPTH_COMPONENT16; + return true; + + case PixelFormatType_Depth24: + format->dataFormat = GL_DEPTH_COMPONENT; + format->dataType = GL_UNSIGNED_INT; + format->internalFormat = GL_DEPTH_COMPONENT24; + return true; + + case PixelFormatType_Depth24Stencil8: + format->dataFormat = GL_DEPTH_STENCIL; + format->dataType = GL_UNSIGNED_INT_24_8; + format->internalFormat = GL_DEPTH24_STENCIL8; + return true; + + case PixelFormatType_Depth32: + format->dataFormat = GL_DEPTH_COMPONENT; + format->dataType = GL_UNSIGNED_BYTE; + format->internalFormat = GL_DEPTH_COMPONENT32; + return true; + + case PixelFormatType_Stencil1: + if (type == FormatType_Texture) // Les formats de stencil ne sont pas supportés par les textures + return false; else { - format->dataFormat = 0x190A; // GL_LUMINANCE_ALPHA - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = 0x190A; // GL_LUMINANCE_ALPHA; + format->dataFormat = GL_NONE; + format->dataType = GL_NONE; + format->internalFormat = GL_STENCIL_INDEX1; + return true; } - return true; - } - else - return false; + case PixelFormatType_Stencil4: + if (type == FormatType_Texture) + return false; + else + { + format->dataFormat = GL_NONE; + format->dataType = GL_NONE; + format->internalFormat = GL_STENCIL_INDEX4; + return true; + } - case nzPixelFormat_R8: - format->dataFormat = GL_RED; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_R8; - return true; + case PixelFormatType_Stencil8: + if (type == FormatType_Texture) + return false; + else + { + format->dataFormat = GL_NONE; + format->dataType = GL_NONE; + format->internalFormat = GL_STENCIL_INDEX8; + return true; + } - case nzPixelFormat_R8I: - format->dataFormat = GL_RED; - format->dataType = GL_BYTE; - format->internalFormat = GL_R8I; - return true; + case PixelFormatType_Stencil16: + if (type == FormatType_Texture) + return false; + else + { + format->dataFormat = GL_NONE; + format->dataType = GL_NONE; + format->internalFormat = GL_STENCIL_INDEX16; + return true; + } - case nzPixelFormat_R8UI: - format->dataFormat = GL_RED; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_R8UI; - return true; - - case nzPixelFormat_R16: - format->dataFormat = GL_RED; - format->dataType = GL_UNSIGNED_SHORT; - format->internalFormat = GL_R16; - return true; - - case nzPixelFormat_R16F: - format->dataFormat = GL_RED; - format->dataType = GL_HALF_FLOAT; - format->internalFormat = GL_R16F; - return true; - - case nzPixelFormat_R16I: - format->dataFormat = GL_RED; - format->dataType = GL_SHORT; - format->internalFormat = GL_R16I; - return true; - - case nzPixelFormat_R16UI: - format->dataFormat = GL_RED; - format->dataType = GL_UNSIGNED_SHORT; - format->internalFormat = GL_R16UI; - return true; - - case nzPixelFormat_R32F: - format->dataFormat = GL_RED; - format->dataType = GL_FLOAT; - format->internalFormat = GL_R32F; - return true; - - case nzPixelFormat_R32I: - format->dataFormat = GL_RED; - format->dataType = GL_INT; - format->internalFormat = GL_R32I; - return true; - - case nzPixelFormat_R32UI: - format->dataFormat = GL_RED; - format->dataType = GL_UNSIGNED_INT; - format->internalFormat = GL_R32UI; - return true; - - case nzPixelFormat_RG8: - format->dataFormat = GL_RG; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_RG8; - return true; - - case nzPixelFormat_RG8I: - format->dataFormat = GL_RG; - format->dataType = GL_BYTE; - format->internalFormat = GL_RG8I; - return true; - - case nzPixelFormat_RG8UI: - format->dataFormat = GL_RG; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_RG8UI; - return true; - - case nzPixelFormat_RG16: - format->dataFormat = GL_RG; - format->dataType = GL_UNSIGNED_SHORT; - format->internalFormat = GL_RG16; - return true; - - case nzPixelFormat_RG16F: - format->dataFormat = GL_RG; - format->dataType = GL_HALF_FLOAT; - format->internalFormat = GL_RG16F; - return true; - - case nzPixelFormat_RG16I: - format->dataFormat = GL_RG; - format->dataType = GL_SHORT; - format->internalFormat = GL_RG16I; - return true; - - case nzPixelFormat_RG16UI: - format->dataFormat = GL_RG; - format->dataType = GL_UNSIGNED_SHORT; - format->internalFormat = GL_RG16UI; - return true; - - case nzPixelFormat_RG32F: - format->dataFormat = GL_RG; - format->dataType = GL_FLOAT; - format->internalFormat = GL_RG32F; - return true; - - case nzPixelFormat_RG32I: - format->dataFormat = GL_RG; - format->dataType = GL_INT; - format->internalFormat = GL_RG32I; - return true; - - case nzPixelFormat_RG32UI: - format->dataFormat = GL_RG; - format->dataType = GL_UNSIGNED_INT; - format->internalFormat = GL_RG32UI; - return true; - - case nzPixelFormat_RGB5A1: - format->dataFormat = GL_RGBA; - format->dataType = GL_UNSIGNED_SHORT_5_5_5_1; - format->internalFormat = GL_RGB5_A1; - return true; - - case nzPixelFormat_RGB8: - format->dataFormat = GL_RGB; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_RGB8; - return true; - - case nzPixelFormat_RGB16F: - format->dataFormat = GL_RGB; - format->dataType = GL_HALF_FLOAT; - format->internalFormat = GL_RGB16F; - return true; - - case nzPixelFormat_RGB16I: - format->dataFormat = GL_RGB; - format->dataType = GL_SHORT; - format->internalFormat = GL_RGB16I; - return true; - - case nzPixelFormat_RGB16UI: - format->dataFormat = GL_RGB; - format->dataType = GL_UNSIGNED_SHORT; - format->internalFormat = GL_RGB16UI; - return true; - - case nzPixelFormat_RGB32F: - format->dataFormat = GL_RGB; - format->dataType = GL_FLOAT; - format->internalFormat = GL_RGB32F; - return true; - - case nzPixelFormat_RGB32I: - format->dataFormat = GL_RGB; - format->dataType = GL_INT; - format->internalFormat = GL_RGB32I; - return true; - - case nzPixelFormat_RGB32UI: - format->dataFormat = GL_RGB; - format->dataType = GL_UNSIGNED_INT; - format->internalFormat = GL_RGB32UI; - return true; - - case nzPixelFormat_RGBA4: - format->dataFormat = GL_RGBA; - format->dataType = GL_UNSIGNED_SHORT_4_4_4_4; - format->internalFormat = GL_RGBA4; - return true; - - case nzPixelFormat_RGBA8: - format->dataFormat = GL_RGBA; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_RGBA8; - return true; - - case nzPixelFormat_RGBA16F: - format->dataFormat = GL_RGBA; - format->dataType = GL_HALF_FLOAT; - format->internalFormat = GL_RGBA16F; - return true; - - case nzPixelFormat_RGBA16I: - format->dataFormat = GL_RGBA; - format->dataType = GL_SHORT; - format->internalFormat = GL_RGBA16I; - return true; - - case nzPixelFormat_RGBA16UI: - format->dataFormat = GL_RGBA; - format->dataType = GL_INT; - format->internalFormat = GL_RGBA16UI; - return true; - - case nzPixelFormat_RGBA32F: - format->dataFormat = GL_RGBA; - format->dataType = GL_FLOAT; - format->internalFormat = GL_RGBA32F; - return true; - - case nzPixelFormat_RGBA32I: - format->dataFormat = GL_RGB; - format->dataType = GL_INT; - format->internalFormat = GL_RGB32I; - return true; - - case nzPixelFormat_RGBA32UI: - format->dataFormat = GL_RGB; - format->dataType = GL_UNSIGNED_INT; - format->internalFormat = GL_RGB32UI; - return true; - - case nzPixelFormat_Depth16: - format->dataFormat = GL_DEPTH_COMPONENT; - format->dataType = GL_UNSIGNED_SHORT; - format->internalFormat = GL_DEPTH_COMPONENT16; - return true; - - case nzPixelFormat_Depth24: - format->dataFormat = GL_DEPTH_COMPONENT; - format->dataType = GL_UNSIGNED_INT; - format->internalFormat = GL_DEPTH_COMPONENT24; - return true; - - case nzPixelFormat_Depth24Stencil8: - format->dataFormat = GL_DEPTH_STENCIL; - format->dataType = GL_UNSIGNED_INT_24_8; - format->internalFormat = GL_DEPTH24_STENCIL8; - return true; - - case nzPixelFormat_Depth32: - format->dataFormat = GL_DEPTH_COMPONENT; - format->dataType = GL_UNSIGNED_BYTE; - format->internalFormat = GL_DEPTH_COMPONENT32; - return true; - - case nzPixelFormat_Stencil1: - if (type == FormatType_Texture) // Les formats de stencil ne sont pas supportés par les textures - return false; - else - { - format->dataFormat = GL_NONE; - format->dataType = GL_NONE; - format->internalFormat = GL_STENCIL_INDEX1; - return true; - } - - case nzPixelFormat_Stencil4: - if (type == FormatType_Texture) - return false; - else - { - format->dataFormat = GL_NONE; - format->dataType = GL_NONE; - format->internalFormat = GL_STENCIL_INDEX4; - return true; - } - - case nzPixelFormat_Stencil8: - if (type == FormatType_Texture) - return false; - else - { - format->dataFormat = GL_NONE; - format->dataType = GL_NONE; - format->internalFormat = GL_STENCIL_INDEX8; - return true; - } - - case nzPixelFormat_Stencil16: - if (type == FormatType_Texture) - return false; - else - { - format->dataFormat = GL_NONE; - format->dataType = GL_NONE; - format->internalFormat = GL_STENCIL_INDEX16; - return true; - } - - case nzPixelFormat_Undefined: - break; - } - - NazaraError("Invalid pixel format"); - return false; -} - -void NzOpenGL::Uninitialize() -{ - if (s_initialized) - { - s_initialized = false; - - NzContext::Uninitialize(); - - for (bool& ext : s_openGLextensions) - ext = false; - - s_glslVersion = 0; - s_openGLextensionSet.clear(); - s_openglVersion = 0; - s_rendererName.Clear(false); - s_vendorName.Clear(false); - - UnloadLibrary(); - } -} - -void NzOpenGL::OnContextChanged(const NzContext* newContext) -{ - s_contextStates = (newContext) ? &s_contexts[newContext] : nullptr; - if (s_contextStates) - { - // On supprime les éventuelles ressources mortes-vivantes (Qui ne peuvent être libérées que dans notre contexte) - for (std::pair& pair : s_contextStates->garbage) - { - switch (pair.first) - { - case GarbageResourceType_FrameBuffer: - glDeleteFramebuffers(1, &pair.second); - break; - - case GarbageResourceType_VertexArray: - glDeleteVertexArrays(1, &pair.second); - break; - } + case PixelFormatType_Undefined: + break; } - s_contextStates->garbage.clear(); + + NazaraError("Invalid pixel format"); + return false; } + + void OpenGL::Uninitialize() + { + if (s_initialized) + { + s_initialized = false; + + Context::Uninitialize(); + + for (bool& ext : s_openGLextensions) + ext = false; + + s_glslVersion = 0; + s_openGLextensionSet.clear(); + s_openglVersion = 0; + s_rendererName.Clear(false); + s_vendorName.Clear(false); + + UnloadLibrary(); + } + } + + void OpenGL::OnContextChanged(const Context* newContext) + { + s_contextStates = (newContext) ? &s_contexts[newContext] : nullptr; + if (s_contextStates) + { + // On supprime les éventuelles ressources mortes-vivantes (Qui ne peuvent être libérées que dans notre contexte) + for (std::pair& pair : s_contextStates->garbage) + { + switch (pair.first) + { + case GarbageResourceType_FrameBuffer: + glDeleteFramebuffers(1, &pair.second); + break; + + case GarbageResourceType_VertexArray: + glDeleteVertexArrays(1, &pair.second); + break; + } + } + s_contextStates->garbage.clear(); + } + } + + void OpenGL::OnContextDestruction(const Context* context) + { + /* + ** Il serait possible d'activer le contexte avant sa destruction afin de libérer les éventuelles ressources mortes-vivantes, + ** mais un driver bien conçu va libérer ces ressources de lui-même. + */ + s_contexts.erase(context); + } + + GLenum OpenGL::Attachment[] = + { + GL_COLOR_ATTACHMENT0, // AttachmentPoint_Color + GL_DEPTH_ATTACHMENT, // AttachmentPoint_Depth + GL_DEPTH_STENCIL_ATTACHMENT, // AttachmentPoint_DepthStencil + GL_STENCIL_ATTACHMENT // AttachmentPoint_Stencil + }; + + static_assert(AttachmentPoint_Max+1 == 4, "Attachment array is incomplete"); + + GLenum OpenGL::BlendFunc[] = + { + GL_DST_ALPHA, // BlendFunc_DestAlpha + GL_DST_COLOR, // BlendFunc_DestColor + GL_SRC_ALPHA, // BlendFunc_SrcAlpha + GL_SRC_COLOR, // BlendFunc_SrcColor + GL_ONE_MINUS_DST_ALPHA, // BlendFunc_InvDestAlpha + GL_ONE_MINUS_DST_COLOR, // BlendFunc_InvDestColor + GL_ONE_MINUS_SRC_ALPHA, // BlendFunc_InvSrcAlpha + GL_ONE_MINUS_SRC_COLOR, // BlendFunc_InvSrcColor + GL_ONE, // BlendFunc_One + GL_ZERO // BlendFunc_Zero + }; + + static_assert(BlendFunc_Max+1 == 10, "Blend func array is incomplete"); + + GLenum OpenGL::BufferLock[] = + { + GL_WRITE_ONLY, // BufferAccess_DiscardAndWrite + GL_READ_ONLY, // BufferAccess_ReadOnly + GL_READ_WRITE, // BufferAccess_ReadWrite + GL_WRITE_ONLY // BufferAccess_WriteOnly + }; + + static_assert(BufferAccess_Max+1 == 4, "Buffer lock array is incomplete"); + + GLenum OpenGL::BufferLockRange[] = + { + // http://www.opengl.org/discussion_boards/showthread.php/170118-VBOs-strangely-slow?p=1198118#post1198118 + GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_WRITE_BIT, // BufferAccess_DiscardAndWrite + GL_MAP_READ_BIT, // BufferAccess_ReadOnly + GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, // BufferAccess_ReadWrite + GL_MAP_WRITE_BIT // BufferAccess_WriteOnly + }; + + static_assert(BufferAccess_Max+1 == 4, "Buffer lock range array is incomplete"); + + GLenum OpenGL::BufferTarget[] = + { + GL_ELEMENT_ARRAY_BUFFER, // BufferType_Index, + GL_ARRAY_BUFFER, // BufferType_Vertex + }; + + static_assert(BufferType_Max+1 == 2, "Buffer target array is incomplete"); + + GLenum OpenGL::BufferTargetBinding[] = + { + GL_ELEMENT_ARRAY_BUFFER_BINDING, // BufferType_Index, + GL_ARRAY_BUFFER_BINDING, // BufferType_Vertex + }; + + static_assert(BufferType_Max+1 == 2, "Buffer target binding array is incomplete"); + + GLenum OpenGL::BufferUsage[] = + { + // D'après la documentation, GL_STREAM_DRAW semble être plus adapté à notre cas (ratio modification/rendu 1:2-3) + // Source: http://www.opengl.org/sdk/docs/man/html/glBufferData.xhtml + GL_STREAM_DRAW, // BufferUsage_Dynamic + GL_STATIC_DRAW // BufferUsage_Static + }; + + static_assert(BufferUsage_Max+1 == 2, "Buffer usage array is incomplete"); + + GLenum OpenGL::ComponentType[] = + { + GL_UNSIGNED_BYTE, // ComponentType_Color + GL_DOUBLE, // ComponentType_Double1 + GL_DOUBLE, // ComponentType_Double2 + GL_DOUBLE, // ComponentType_Double3 + GL_DOUBLE, // ComponentType_Double4 + GL_FLOAT, // ComponentType_Float1 + GL_FLOAT, // ComponentType_Float2 + GL_FLOAT, // ComponentType_Float3 + GL_FLOAT, // ComponentType_Float4 + GL_INT, // ComponentType_Int1 + GL_INT, // ComponentType_Int2 + GL_INT, // ComponentType_Int3 + GL_INT, // ComponentType_Int4 + GL_FLOAT // ComponentType_Quaternion + }; + + static_assert(ComponentType_Max+1 == 14, "Attribute type array is incomplete"); + + GLenum OpenGL::CubemapFace[] = + { + GL_TEXTURE_CUBE_MAP_POSITIVE_X, // CubemapFace_PositiveX + GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // CubemapFace_NegativeX + GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // CubemapFace_PositiveY + GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // CubemapFace_NegativeY + GL_TEXTURE_CUBE_MAP_POSITIVE_Z, // CubemapFace_PositiveZ + GL_TEXTURE_CUBE_MAP_NEGATIVE_Z // CubemapFace_NegativeZ + }; + + static_assert(CubemapFace_Max+1 == 6, "Cubemap face array is incomplete"); + + GLenum OpenGL::FaceFilling[] = + { + GL_FILL, // FaceFilling_Fill + GL_LINE, // FaceFilling_Line + GL_POINT // FaceFilling_Point + }; + + static_assert(FaceFilling_Max+1 == 3, "Face filling array is incomplete"); + + GLenum OpenGL::FaceSide[] = + { + GL_BACK, // FaceSide_Back + GL_FRONT, // FaceSide_Front + GL_FRONT_AND_BACK // FaceSide_FrontAndBack + }; + + static_assert(FaceSide_Max+1 == 3, "Face side array is incomplete"); + + GLenum OpenGL::PrimitiveMode[] = + { + GL_LINES, // PrimitiveMode_LineList + GL_LINE_STRIP, // PrimitiveMode_LineStrip + GL_POINTS, // PrimitiveMode_PointList + GL_TRIANGLES, // PrimitiveMode_TriangleList + GL_TRIANGLE_STRIP, // PrimitiveMode_TriangleStrip + GL_TRIANGLE_FAN // PrimitiveMode_TriangleFan + }; + + static_assert(PrimitiveMode_Max+1 == 6, "Primitive mode array is incomplete"); + + GLenum OpenGL::QueryCondition[] = + { + GL_QUERY_WAIT, // GpuQueryCondition_NoWait + GL_QUERY_BY_REGION_NO_WAIT, // GpuQueryCondition_Region_NoWait + GL_QUERY_BY_REGION_WAIT, // GpuQueryCondition_Region_Wait + GL_QUERY_WAIT // GpuQueryCondition_Wait + }; + + static_assert(GpuQueryCondition_Max+1 == 4, "Query condition array is incomplete"); + + GLenum OpenGL::QueryMode[] = + { + GL_ANY_SAMPLES_PASSED, // GpuQueryMode_AnySamplesPassed + GL_ANY_SAMPLES_PASSED_CONSERVATIVE, // GpuQueryMode_AnySamplesPassedConservative + GL_PRIMITIVES_GENERATED, // GpuQueryMode_PrimitiveGenerated + GL_SAMPLES_PASSED, // GpuQueryMode_SamplesPassed + GL_TIME_ELAPSED, // GpuQueryMode_TimeElapsed + GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN // GpuQueryMode_TransformFeedbackPrimitivesWritten + }; + + static_assert(GpuQueryMode_Max+1 == 6, "Query mode array is incomplete"); + + GLenum OpenGL::RendererComparison[] = + { + GL_ALWAYS, // RendererComparison_Always + GL_EQUAL, // RendererComparison_Equal + GL_GREATER, // RendererComparison_Greater + GL_GEQUAL, // RendererComparison_GreaterOrEqual + GL_LESS, // RendererComparison_Less + GL_LEQUAL, // RendererComparison_LessOrEqual + GL_NEVER, // RendererComparison_Never + GL_NOTEQUAL // RendererComparison_NotEqual + }; + + static_assert(RendererComparison_Max+1 == 8, "Renderer comparison array is incomplete"); + + GLenum OpenGL::RendererParameter[] = + { + GL_BLEND, // RendererParameter_Blend + GL_NONE, // RendererParameter_ColorWrite + GL_DEPTH_TEST, // RendererParameter_DepthBuffer + GL_NONE, // RendererParameter_DepthWrite + GL_CULL_FACE, // RendererParameter_FaceCulling + GL_SCISSOR_TEST, // RendererParameter_ScissorTest + GL_STENCIL_TEST // RendererParameter_StencilTest + }; + + static_assert(RendererParameter_Max+1 == 7, "Renderer parameter array is incomplete"); + + GLenum OpenGL::SamplerWrapMode[] = + { + GL_CLAMP_TO_EDGE, // TextureWrap_Clamp + GL_MIRRORED_REPEAT, // SamplerWrap_MirroredRepeat + GL_REPEAT // TextureWrap_Repeat + }; + + static_assert(SamplerWrap_Max+1 == 3, "Sampler wrap mode array is incomplete"); + + GLenum OpenGL::ShaderStage[] = + { + GL_FRAGMENT_SHADER, // ShaderStageType_Fragment + GL_GEOMETRY_SHADER, // ShaderStageType_Geometry + GL_VERTEX_SHADER // ShaderStageType_Vertex + }; + + static_assert(ShaderStageType_Max+1 == 3, "Shader stage array is incomplete"); + + GLenum OpenGL::StencilOperation[] = + { + GL_DECR, // nzStencilOperation_Decrement + GL_DECR_WRAP, // nzStencilOperation_DecrementNoClamp + GL_INCR, // nzStencilOperation_Increment + GL_INCR_WRAP, // nzStencilOperation_IncrementNoClamp + GL_INVERT, // nzStencilOperation_Invert + GL_KEEP, // nzStencilOperation_Keep + GL_REPLACE, // nzStencilOperation_Replace + GL_ZERO // nzStencilOperation_Zero + }; + + static_assert(nzStencilOperation_Max+1 == 8, "Stencil operation array is incomplete"); + + GLenum OpenGL::TextureTarget[] = + { + GL_TEXTURE_1D, // ImageType_1D + GL_TEXTURE_1D_ARRAY, // ImageType_1D_Array + GL_TEXTURE_2D, // ImageType_2D + GL_TEXTURE_2D_ARRAY, // ImageType_2D_Array + GL_TEXTURE_3D, // ImageType_3D + GL_TEXTURE_CUBE_MAP // ImageType_Cubemap + }; + + static_assert(ImageType_Max+1 == 6, "Texture target array is incomplete"); + + GLenum OpenGL::TextureTargetBinding[] = + { + GL_TEXTURE_BINDING_1D, // ImageType_1D + GL_TEXTURE_BINDING_1D_ARRAY, // ImageType_1D_Array + GL_TEXTURE_BINDING_2D, // ImageType_2D + GL_TEXTURE_BINDING_2D_ARRAY, // ImageType_2D_Array + GL_TEXTURE_BINDING_3D, // ImageType_3D + GL_TEXTURE_BINDING_CUBE_MAP // ImageType_Cubemap + }; + + static_assert(ImageType_Max+1 == 6, "Texture target binding array is incomplete"); + + GLenum OpenGL::TextureTargetProxy[] = + { + GL_PROXY_TEXTURE_1D, // ImageType_1D + GL_PROXY_TEXTURE_1D_ARRAY, // ImageType_1D_Array + GL_PROXY_TEXTURE_2D, // ImageType_2D + GL_PROXY_TEXTURE_2D_ARRAY, // ImageType_2D_Array + GL_PROXY_TEXTURE_3D, // ImageType_3D + GL_PROXY_TEXTURE_CUBE_MAP // ImageType_Cubemap + }; + + static_assert(ImageType_Max+1 == 6, "Texture target proxy array is incomplete"); + + UInt8 OpenGL::VertexComponentIndex[] = + { + 10, // VertexComponent_InstanceData0 + 11, // VertexComponent_InstanceData1 + 12, // VertexComponent_InstanceData2 + 13, // VertexComponent_InstanceData3 + 14, // VertexComponent_InstanceData4 + 15, // VertexComponent_InstanceData5 + 4, // VertexComponent_Color + 2, // VertexComponent_Normal + 0, // VertexComponent_Position + 3, // VertexComponent_Tangent + 1, // VertexComponent_TexCoord + 5, // VertexComponent_Userdata0 + 6, // VertexComponent_Userdata1 + 7, // VertexComponent_Userdata2 + 8, // VertexComponent_Userdata3 + 9 // VertexComponent_Userdata4 + }; + + static_assert(VertexComponent_Max+1 == 16, "Attribute index array is incomplete"); } -void NzOpenGL::OnContextDestruction(const NzContext* context) -{ - /* - ** Il serait possible d'activer le contexte avant sa destruction afin de libérer les éventuelles ressources mortes-vivantes, - ** mais un driver bien conçu va libérer ces ressources de lui-même. - */ - s_contexts.erase(context); -} - -GLenum NzOpenGL::Attachment[] = -{ - GL_COLOR_ATTACHMENT0, // nzAttachmentPoint_Color - GL_DEPTH_ATTACHMENT, // nzAttachmentPoint_Depth - GL_DEPTH_STENCIL_ATTACHMENT, // nzAttachmentPoint_DepthStencil - GL_STENCIL_ATTACHMENT // nzAttachmentPoint_Stencil -}; - -static_assert(nzAttachmentPoint_Max+1 == 4, "Attachment array is incomplete"); - -GLenum NzOpenGL::BlendFunc[] = -{ - GL_DST_ALPHA, // nzBlendFunc_DestAlpha - GL_DST_COLOR, // nzBlendFunc_DestColor - GL_SRC_ALPHA, // nzBlendFunc_SrcAlpha - GL_SRC_COLOR, // nzBlendFunc_SrcColor - GL_ONE_MINUS_DST_ALPHA, // nzBlendFunc_InvDestAlpha - GL_ONE_MINUS_DST_COLOR, // nzBlendFunc_InvDestColor - GL_ONE_MINUS_SRC_ALPHA, // nzBlendFunc_InvSrcAlpha - GL_ONE_MINUS_SRC_COLOR, // nzBlendFunc_InvSrcColor - GL_ONE, // nzBlendFunc_One - GL_ZERO // nzBlendFunc_Zero -}; - -static_assert(nzBlendFunc_Max+1 == 10, "Blend func array is incomplete"); - -GLenum NzOpenGL::BufferLock[] = -{ - GL_WRITE_ONLY, // nzBufferAccess_DiscardAndWrite - GL_READ_ONLY, // nzBufferAccess_ReadOnly - GL_READ_WRITE, // nzBufferAccess_ReadWrite - GL_WRITE_ONLY // nzBufferAccess_WriteOnly -}; - -static_assert(nzBufferAccess_Max+1 == 4, "Buffer lock array is incomplete"); - -GLenum NzOpenGL::BufferLockRange[] = -{ - // http://www.opengl.org/discussion_boards/showthread.php/170118-VBOs-strangely-slow?p=1198118#post1198118 - GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_INVALIDATE_RANGE_BIT | GL_MAP_WRITE_BIT, // nzBufferAccess_DiscardAndWrite - GL_MAP_READ_BIT, // nzBufferAccess_ReadOnly - GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, // nzBufferAccess_ReadWrite - GL_MAP_WRITE_BIT // nzBufferAccess_WriteOnly -}; - -static_assert(nzBufferAccess_Max+1 == 4, "Buffer lock range array is incomplete"); - -GLenum NzOpenGL::BufferTarget[] = -{ - GL_ELEMENT_ARRAY_BUFFER, // nzBufferType_Index, - GL_ARRAY_BUFFER, // nzBufferType_Vertex -}; - -static_assert(nzBufferType_Max+1 == 2, "Buffer target array is incomplete"); - -GLenum NzOpenGL::BufferTargetBinding[] = -{ - GL_ELEMENT_ARRAY_BUFFER_BINDING, // nzBufferType_Index, - GL_ARRAY_BUFFER_BINDING, // nzBufferType_Vertex -}; - -static_assert(nzBufferType_Max+1 == 2, "Buffer target binding array is incomplete"); - -GLenum NzOpenGL::BufferUsage[] = -{ - // D'après la documentation, GL_STREAM_DRAW semble être plus adapté à notre cas (ratio modification/rendu 1:2-3) - // Source: http://www.opengl.org/sdk/docs/man/html/glBufferData.xhtml - GL_STREAM_DRAW, // nzBufferUsage_Dynamic - GL_STATIC_DRAW // nzBufferUsage_Static -}; - -static_assert(nzBufferUsage_Max+1 == 2, "Buffer usage array is incomplete"); - -GLenum NzOpenGL::ComponentType[] = -{ - GL_UNSIGNED_BYTE, // nzComponentType_Color - GL_DOUBLE, // nzComponentType_Double1 - GL_DOUBLE, // nzComponentType_Double2 - GL_DOUBLE, // nzComponentType_Double3 - GL_DOUBLE, // nzComponentType_Double4 - GL_FLOAT, // nzComponentType_Float1 - GL_FLOAT, // nzComponentType_Float2 - GL_FLOAT, // nzComponentType_Float3 - GL_FLOAT, // nzComponentType_Float4 - GL_INT, // nzComponentType_Int1 - GL_INT, // nzComponentType_Int2 - GL_INT, // nzComponentType_Int3 - GL_INT, // nzComponentType_Int4 - GL_FLOAT // nzComponentType_Quaternion -}; - -static_assert(nzComponentType_Max+1 == 14, "Attribute type array is incomplete"); - -GLenum NzOpenGL::CubemapFace[] = -{ - GL_TEXTURE_CUBE_MAP_POSITIVE_X, // nzCubemapFace_PositiveX - GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // nzCubemapFace_NegativeX - GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // nzCubemapFace_PositiveY - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // nzCubemapFace_NegativeY - GL_TEXTURE_CUBE_MAP_POSITIVE_Z, // nzCubemapFace_PositiveZ - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z // nzCubemapFace_NegativeZ -}; - -static_assert(nzCubemapFace_Max+1 == 6, "Cubemap face array is incomplete"); - -GLenum NzOpenGL::FaceFilling[] = -{ - GL_FILL, // nzFaceFilling_Fill - GL_LINE, // nzFaceFilling_Line - GL_POINT // nzFaceFilling_Point -}; - -static_assert(nzFaceFilling_Max+1 == 3, "Face filling array is incomplete"); - -GLenum NzOpenGL::FaceSide[] = -{ - GL_BACK, // nzFaceSide_Back - GL_FRONT, // nzFaceSide_Front - GL_FRONT_AND_BACK // nzFaceSide_FrontAndBack -}; - -static_assert(nzFaceSide_Max+1 == 3, "Face side array is incomplete"); - -GLenum NzOpenGL::PrimitiveMode[] = -{ - GL_LINES, // nzPrimitiveMode_LineList - GL_LINE_STRIP, // nzPrimitiveMode_LineStrip - GL_POINTS, // nzPrimitiveMode_PointList - GL_TRIANGLES, // nzPrimitiveMode_TriangleList - GL_TRIANGLE_STRIP, // nzPrimitiveMode_TriangleStrip - GL_TRIANGLE_FAN // nzPrimitiveMode_TriangleFan -}; - -static_assert(nzPrimitiveMode_Max+1 == 6, "Primitive mode array is incomplete"); - -GLenum NzOpenGL::QueryCondition[] = -{ - GL_QUERY_WAIT, // nzGpuQueryCondition_NoWait - GL_QUERY_BY_REGION_NO_WAIT, // nzGpuQueryCondition_Region_NoWait - GL_QUERY_BY_REGION_WAIT, // nzGpuQueryCondition_Region_Wait - GL_QUERY_WAIT // nzGpuQueryCondition_Wait -}; - -static_assert(nzGpuQueryCondition_Max+1 == 4, "Query condition array is incomplete"); - -GLenum NzOpenGL::QueryMode[] = -{ - GL_ANY_SAMPLES_PASSED, // nzGpuQueryMode_AnySamplesPassed - GL_ANY_SAMPLES_PASSED_CONSERVATIVE, // nzGpuQueryMode_AnySamplesPassedConservative - GL_PRIMITIVES_GENERATED, // nzGpuQueryMode_PrimitiveGenerated - GL_SAMPLES_PASSED, // nzGpuQueryMode_SamplesPassed - GL_TIME_ELAPSED, // nzGpuQueryMode_TimeElapsed - GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN // nzGpuQueryMode_TransformFeedbackPrimitivesWritten -}; - -static_assert(nzGpuQueryMode_Max+1 == 6, "Query mode array is incomplete"); - -GLenum NzOpenGL::RendererComparison[] = -{ - GL_ALWAYS, // nzRendererComparison_Always - GL_EQUAL, // nzRendererComparison_Equal - GL_GREATER, // nzRendererComparison_Greater - GL_GEQUAL, // nzRendererComparison_GreaterOrEqual - GL_LESS, // nzRendererComparison_Less - GL_LEQUAL, // nzRendererComparison_LessOrEqual - GL_NEVER, // nzRendererComparison_Never - GL_NOTEQUAL // nzRendererComparison_NotEqual -}; - -static_assert(nzRendererComparison_Max+1 == 8, "Renderer comparison array is incomplete"); - -GLenum NzOpenGL::RendererParameter[] = -{ - GL_BLEND, // nzRendererParameter_Blend - GL_NONE, // nzRendererParameter_ColorWrite - GL_DEPTH_TEST, // nzRendererParameter_DepthBuffer - GL_NONE, // nzRendererParameter_DepthWrite - GL_CULL_FACE, // nzRendererParameter_FaceCulling - GL_SCISSOR_TEST, // nzRendererParameter_ScissorTest - GL_STENCIL_TEST // nzRendererParameter_StencilTest -}; - -static_assert(nzRendererParameter_Max+1 == 7, "Renderer parameter array is incomplete"); - -GLenum NzOpenGL::SamplerWrapMode[] = -{ - GL_CLAMP_TO_EDGE, // nzTextureWrap_Clamp - GL_MIRRORED_REPEAT, // nzSamplerWrap_MirroredRepeat - GL_REPEAT // nzTextureWrap_Repeat -}; - -static_assert(nzSamplerWrap_Max+1 == 3, "Sampler wrap mode array is incomplete"); - -GLenum NzOpenGL::ShaderStage[] = -{ - GL_FRAGMENT_SHADER, // nzShaderStage_Fragment - GL_GEOMETRY_SHADER, // nzShaderStage_Geometry - GL_VERTEX_SHADER // nzShaderStage_Vertex -}; - -static_assert(nzShaderStage_Max+1 == 3, "Shader stage array is incomplete"); - -GLenum NzOpenGL::StencilOperation[] = -{ - GL_DECR, // nzStencilOperation_Decrement - GL_DECR_WRAP, // nzStencilOperation_DecrementNoClamp - GL_INCR, // nzStencilOperation_Increment - GL_INCR_WRAP, // nzStencilOperation_IncrementNoClamp - GL_INVERT, // nzStencilOperation_Invert - GL_KEEP, // nzStencilOperation_Keep - GL_REPLACE, // nzStencilOperation_Replace - GL_ZERO // nzStencilOperation_Zero -}; - -static_assert(nzStencilOperation_Max+1 == 8, "Stencil operation array is incomplete"); - -GLenum NzOpenGL::TextureTarget[] = -{ - GL_TEXTURE_1D, // nzImageType_1D - GL_TEXTURE_1D_ARRAY, // nzImageType_1D_Array - GL_TEXTURE_2D, // nzImageType_2D - GL_TEXTURE_2D_ARRAY, // nzImageType_2D_Array - GL_TEXTURE_3D, // nzImageType_3D - GL_TEXTURE_CUBE_MAP // nzImageType_Cubemap -}; - -static_assert(nzImageType_Max+1 == 6, "Texture target array is incomplete"); - -GLenum NzOpenGL::TextureTargetBinding[] = -{ - GL_TEXTURE_BINDING_1D, // nzImageType_1D - GL_TEXTURE_BINDING_1D_ARRAY, // nzImageType_1D_Array - GL_TEXTURE_BINDING_2D, // nzImageType_2D - GL_TEXTURE_BINDING_2D_ARRAY, // nzImageType_2D_Array - GL_TEXTURE_BINDING_3D, // nzImageType_3D - GL_TEXTURE_BINDING_CUBE_MAP // nzImageType_Cubemap -}; - -static_assert(nzImageType_Max+1 == 6, "Texture target binding array is incomplete"); - -GLenum NzOpenGL::TextureTargetProxy[] = -{ - GL_PROXY_TEXTURE_1D, // nzImageType_1D - GL_PROXY_TEXTURE_1D_ARRAY, // nzImageType_1D_Array - GL_PROXY_TEXTURE_2D, // nzImageType_2D - GL_PROXY_TEXTURE_2D_ARRAY, // nzImageType_2D_Array - GL_PROXY_TEXTURE_3D, // nzImageType_3D - GL_PROXY_TEXTURE_CUBE_MAP // nzImageType_Cubemap -}; - -static_assert(nzImageType_Max+1 == 6, "Texture target proxy array is incomplete"); - -nzUInt8 NzOpenGL::VertexComponentIndex[] = -{ - 10, // nzVertexComponent_InstanceData0 - 11, // nzVertexComponent_InstanceData1 - 12, // nzVertexComponent_InstanceData2 - 13, // nzVertexComponent_InstanceData3 - 14, // nzVertexComponent_InstanceData4 - 15, // nzVertexComponent_InstanceData5 - 4, // nzVertexComponent_Color - 2, // nzVertexComponent_Normal - 0, // nzVertexComponent_Position - 3, // nzVertexComponent_Tangent - 1, // nzVertexComponent_TexCoord - 5, // nzVertexComponent_Userdata0 - 6, // nzVertexComponent_Userdata1 - 7, // nzVertexComponent_Userdata2 - 8, // nzVertexComponent_Userdata3 - 9 // nzVertexComponent_Userdata4 -}; - -static_assert(nzVertexComponent_Max+1 == 16, "Attribute index array is incomplete"); - PFNGLACTIVETEXTUREPROC glActiveTexture = nullptr; PFNGLATTACHSHADERPROC glAttachShader = nullptr; PFNGLBEGINCONDITIONALRENDERPROC glBeginConditionalRender = nullptr; diff --git a/src/Nazara/Renderer/RenderBuffer.cpp b/src/Nazara/Renderer/RenderBuffer.cpp index f03bc2f62..16a1dda5a 100644 --- a/src/Nazara/Renderer/RenderBuffer.cpp +++ b/src/Nazara/Renderer/RenderBuffer.cpp @@ -9,127 +9,130 @@ #include #include -NzRenderBuffer::NzRenderBuffer() : -m_id(0) +namespace Nz { -} - -NzRenderBuffer::~NzRenderBuffer() -{ - OnRenderBufferRelease(this); - - Destroy(); -} - -bool NzRenderBuffer::Create(nzPixelFormat format, unsigned int width, unsigned int height) -{ - Destroy(); - - #if NAZARA_RENDERER_SAFE - if (width == 0 || height == 0) + RenderBuffer::RenderBuffer() : + m_id(0) { - NazaraError("Invalid size"); - return false; } - if (!NzPixelFormat::IsValid(format)) + RenderBuffer::~RenderBuffer() { - NazaraError("Invalid pixel format"); - return false; - } - #endif + OnRenderBufferRelease(this); - NzOpenGL::Format openglFormat; - if (!NzOpenGL::TranslateFormat(format, &openglFormat, NzOpenGL::FormatType_RenderBuffer)) - { - NazaraError("Failed to translate pixel format \"" + NzPixelFormat::ToString(format) + "\" into OpenGL format"); - return false; + Destroy(); } - GLuint renderBuffer = 0; - - glGenRenderbuffers(1, &renderBuffer); - if (!renderBuffer) + bool RenderBuffer::Create(PixelFormatType format, unsigned int width, unsigned int height) { - NazaraError("Failed to create renderbuffer"); - return false; + Destroy(); + + #if NAZARA_RENDERER_SAFE + if (width == 0 || height == 0) + { + NazaraError("Invalid size"); + return false; + } + + if (!NzPixelFormat::IsValid(format)) + { + NazaraError("Invalid pixel format"); + return false; + } + #endif + + OpenGL::Format openglFormat; + if (!OpenGL::TranslateFormat(format, &openglFormat, OpenGL::FormatType_RenderBuffer)) + { + NazaraError("Failed to translate pixel format \"" + NzPixelFormat::ToString(format) + "\" into OpenGL format"); + return false; + } + + GLuint renderBuffer = 0; + + glGenRenderbuffers(1, &renderBuffer); + if (!renderBuffer) + { + NazaraError("Failed to create renderbuffer"); + return false; + } + + GLint previous; + glGetIntegerv(GL_RENDERBUFFER_BINDING, &previous); + + glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer); + glRenderbufferStorage(GL_RENDERBUFFER, openglFormat.internalFormat, width, height); + + if (previous != 0) + glBindRenderbuffer(GL_RENDERBUFFER, previous); + + m_pixelFormat = format; + m_height = height; + m_id = renderBuffer; + m_width = width; + + return true; } - GLint previous; - glGetIntegerv(GL_RENDERBUFFER_BINDING, &previous); - - glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer); - glRenderbufferStorage(GL_RENDERBUFFER, openglFormat.internalFormat, width, height); - - if (previous != 0) - glBindRenderbuffer(GL_RENDERBUFFER, previous); - - m_pixelFormat = format; - m_height = height; - m_id = renderBuffer; - m_width = width; - - return true; -} - -void NzRenderBuffer::Destroy() -{ - if (m_id) + void RenderBuffer::Destroy() { - OnRenderBufferDestroy(this); + if (m_id) + { + OnRenderBufferDestroy(this); - NzContext::EnsureContext(); + Context::EnsureContext(); - GLuint renderBuffer = m_id; - glDeleteRenderbuffers(1, &renderBuffer); // Les Renderbuffers sont partagés entre les contextes: Ne posera pas de problème - m_id = 0; - } -} - -unsigned int NzRenderBuffer::GetHeight() const -{ - return m_height; -} - -nzPixelFormat NzRenderBuffer::GetFormat() const -{ - return m_pixelFormat; -} - -unsigned int NzRenderBuffer::GetWidth() const -{ - return m_width; -} - -unsigned int NzRenderBuffer::GetOpenGLID() const -{ - return m_id; -} - -bool NzRenderBuffer::IsValid() const -{ - return m_id != 0; -} - -bool NzRenderBuffer::IsSupported() -{ - return NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject); -} - -bool NzRenderBuffer::Initialize() -{ - if (!NzRenderBufferLibrary::Initialize()) - { - NazaraError("Failed to initialise library"); - return false; + GLuint renderBuffer = m_id; + glDeleteRenderbuffers(1, &renderBuffer); // Les Renderbuffers sont partagés entre les contextes: Ne posera pas de problème + m_id = 0; + } } - return true; -} + unsigned int RenderBuffer::GetHeight() const + { + return m_height; + } -void NzRenderBuffer::Uninitialize() -{ - NzRenderBufferLibrary::Uninitialize(); -} + PixelFormatType RenderBuffer::GetFormat() const + { + return m_pixelFormat; + } -NzRenderBufferLibrary::LibraryMap NzRenderBuffer::s_library; + unsigned int RenderBuffer::GetWidth() const + { + return m_width; + } + + unsigned int RenderBuffer::GetOpenGLID() const + { + return m_id; + } + + bool RenderBuffer::IsValid() const + { + return m_id != 0; + } + + bool RenderBuffer::IsSupported() + { + return OpenGL::IsSupported(OpenGLExtension_FrameBufferObject); + } + + bool RenderBuffer::Initialize() + { + if (!RenderBufferLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } + + return true; + } + + void RenderBuffer::Uninitialize() + { + RenderBufferLibrary::Uninitialize(); + } + + RenderBufferLibrary::LibraryMap RenderBuffer::s_library; +} diff --git a/src/Nazara/Renderer/RenderTarget.cpp b/src/Nazara/Renderer/RenderTarget.cpp index 8276aeb3f..717c7497a 100644 --- a/src/Nazara/Renderer/RenderTarget.cpp +++ b/src/Nazara/Renderer/RenderTarget.cpp @@ -6,27 +6,30 @@ #include #include -NzRenderTarget::~NzRenderTarget() +namespace Nz { - OnRenderTargetRelease(this); -} + RenderTarget::~RenderTarget() + { + OnRenderTargetRelease(this); + } -bool NzRenderTarget::IsActive() const -{ - return NzRenderer::GetTarget() == this; -} + bool RenderTarget::IsActive() const + { + return Renderer::GetTarget() == this; + } -bool NzRenderTarget::SetActive(bool active) -{ - if (active) - return NzRenderer::SetTarget(this); - else if (NzRenderer::GetTarget() == this) - return NzRenderer::SetTarget(nullptr); + bool RenderTarget::SetActive(bool active) + { + if (active) + return Renderer::SetTarget(this); + else if (Renderer::GetTarget() == this) + return Renderer::SetTarget(nullptr); - return true; -} + return true; + } -void NzRenderTarget::Desactivate() const -{ - // Seuls les target sans contextes (ex: NzRenderTexture) nécessitent une désactivation + void RenderTarget::Desactivate() const + { + // Seuls les target sans contextes (ex: RenderTexture) nécessitent une désactivation + } } diff --git a/src/Nazara/Renderer/RenderTexture.cpp b/src/Nazara/Renderer/RenderTexture.cpp index 08ac50822..33c64a8ec 100644 --- a/src/Nazara/Renderer/RenderTexture.cpp +++ b/src/Nazara/Renderer/RenderTexture.cpp @@ -17,331 +17,230 @@ #include #include -namespace +namespace Nz { - struct Attachment + namespace { - NazaraSlot(NzRenderBuffer, OnRenderBufferDestroy, renderBufferDestroySlot); - NazaraSlot(NzTexture, OnTextureDestroy, textureDestroySlot); + struct Attachment + { + NazaraSlot(RenderBuffer, OnRenderBufferDestroy, renderBufferDestroySlot); + NazaraSlot(Texture, OnTextureDestroy, textureDestroySlot); - NzRenderBufferRef buffer; - NzTextureRef texture; + RenderBufferRef buffer; + TextureRef texture; - nzAttachmentPoint attachmentPoint; - bool isBuffer; - bool isUsed = false; + AttachmentPoint attachmentPoint; + bool isBuffer; + bool isUsed = false; + unsigned int height; + unsigned int width; + }; + + unsigned int attachmentIndex[AttachmentPoint_Max+1] = + { + 3, // AttachmentPoint_Color + 0, // AttachmentPoint_Depth + 1, // AttachmentPoint_DepthStencil + 2 // AttachmentPoint_Stencil + }; + + AttachmentPoint formatTypeToAttachment[PixelFormatTypeType_Max+1] = + { + AttachmentPoint_Color, // PixelFormatTypeType_Color + AttachmentPoint_Depth, // PixelFormatTypeType_Depth + AttachmentPoint_DepthStencil, // PixelFormatTypeType_DepthStencil + AttachmentPoint_Stencil // PixelFormatTypeType_Stencil + }; + + GLuint lockedPrevious = 0; + UInt8 lockedLevel = 0; + } + + struct RenderTextureImpl + { + NazaraSlot(Context, OnContextDestroy, contextDestroySlot); + + GLuint fbo; + std::vector attachments; + std::vector colorTargets; + mutable std::vector drawBuffers; + const Context* context; + bool complete = false; + bool userDefinedTargets = false; unsigned int height; unsigned int width; }; - unsigned int attachmentIndex[nzAttachmentPoint_Max+1] = + bool RenderTexture::AttachBuffer(AttachmentPoint attachmentPoint, UInt8 index, RenderBuffer* buffer) { - 3, // nzAttachmentPoint_Color - 0, // nzAttachmentPoint_Depth - 1, // nzAttachmentPoint_DepthStencil - 2 // nzAttachmentPoint_Stencil - }; - - nzAttachmentPoint formatTypeToAttachment[nzPixelFormatType_Max+1] = - { - nzAttachmentPoint_Color, // nzPixelFormatType_Color - nzAttachmentPoint_Depth, // nzPixelFormatType_Depth - nzAttachmentPoint_DepthStencil, // nzPixelFormatType_DepthStencil - nzAttachmentPoint_Stencil // nzPixelFormatType_Stencil - }; - - GLuint lockedPrevious = 0; - nzUInt8 lockedLevel = 0; -} - -struct NzRenderTextureImpl -{ - NazaraSlot(NzContext, OnContextDestroy, contextDestroySlot); - - GLuint fbo; - std::vector attachments; - std::vector colorTargets; - mutable std::vector drawBuffers; - const NzContext* context; - bool complete = false; - bool userDefinedTargets = false; - unsigned int height; - unsigned int width; -}; - -bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzRenderBuffer* buffer) -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return false; - } - - if (attachmentPoint != nzAttachmentPoint_Color) - { - if (index > 0) + #if NAZARA_RENDERER_SAFE + if (!m_impl) { - NazaraError("Index must be 0 for non-color attachments"); + NazaraError("Render texture not created"); return false; } - } - else - { - if (index >= NzRenderer::GetMaxColorAttachments()) + + if (attachmentPoint != AttachmentPoint_Color) { - NazaraError("Color index is over max color attachments (" + NzString::Number(index) + " >= " + NzString::Number(NzRenderer::GetMaxColorAttachments()) + ")"); + if (index > 0) + { + NazaraError("Index must be 0 for non-color attachments"); + return false; + } + } + else + { + if (index >= Renderer::GetMaxColorAttachments()) + { + NazaraError("Color index is over max color attachments (" + String::Number(index) + " >= " + String::Number(Renderer::GetMaxColorAttachments()) + ")"); + return false; + } + } + + if (!buffer || !buffer->IsValid()) + { + NazaraError("Invalid render buffer"); return false; } + + unsigned int depthStencilIndex = attachmentIndex[AttachmentPoint_DepthStencil]; + if (m_impl->attachments.size() > depthStencilIndex && m_impl->attachments[depthStencilIndex].isUsed) + { + if (attachmentPoint == AttachmentPoint_Depth) + { + NazaraError("Depth target already attached by DepthStencil attachment"); + return false; + } + else if (attachmentPoint == AttachmentPoint_Stencil) + { + NazaraError("Stencil target already attached by DepthStencil attachment"); + return false; + } + } + + AttachmentPoint targetAttachmentPoint = formatTypeToAttachment[NzPixelFormat::GetType(buffer->GetFormat())]; + if (targetAttachmentPoint != attachmentPoint && targetAttachmentPoint != AttachmentPoint_DepthStencil && + attachmentPoint != AttachmentPoint_Depth && attachmentPoint != AttachmentPoint_Stencil) + { + NazaraError("Pixel format type does not match attachment point type"); + return false; + } + #endif + + if (!Lock()) + { + NazaraError("Failed to lock render texture"); + return false; + } + + // Détachement de l'attache précédente (Si il y a) + Detach(attachmentPoint, index); + + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, OpenGL::Attachment[attachmentPoint]+index, GL_RENDERBUFFER, buffer->GetOpenGLID()); + + Unlock(); + + unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; + if (attachIndex >= m_impl->attachments.size()) + m_impl->attachments.resize(attachIndex+1); + + Attachment& attachment = m_impl->attachments[attachIndex]; + attachment.attachmentPoint = attachmentPoint; + attachment.buffer = buffer; + attachment.renderBufferDestroySlot.Connect(buffer->OnRenderBufferDestroy, std::bind(&RenderTexture::OnRenderBufferDestroy, this, std::placeholders::_1, attachIndex)); + attachment.isBuffer = true; + attachment.isUsed = true; + attachment.height = buffer->GetHeight(); + attachment.width = buffer->GetWidth(); + + InvalidateSize(); + InvalidateTargets(); + + if (attachmentPoint == AttachmentPoint_Color && !m_impl->userDefinedTargets) + m_impl->colorTargets.push_back(index); + + return true; } - if (!buffer || !buffer->IsValid()) + bool RenderTexture::AttachBuffer(AttachmentPoint attachmentPoint, UInt8 index, PixelFormatType format, unsigned int width, unsigned int height) { - NazaraError("Invalid render buffer"); - return false; + RenderBufferRef renderBuffer = RenderBuffer::New(); + if (!renderBuffer->Create(format, width, height)) + { + NazaraError("Failed to create RenderBuffer"); + return false; + } + + if (!AttachBuffer(attachmentPoint, index, renderBuffer)) + { + NazaraError("Failed to attach buffer"); + return false; + } + + return true; } - unsigned int depthStencilIndex = attachmentIndex[nzAttachmentPoint_DepthStencil]; - if (m_impl->attachments.size() > depthStencilIndex && m_impl->attachments[depthStencilIndex].isUsed) + bool RenderTexture::AttachTexture(AttachmentPoint attachmentPoint, UInt8 index, Texture* texture, unsigned int z) { - if (attachmentPoint == nzAttachmentPoint_Depth) + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Render texture not created"); + return false; + } + + if (attachmentPoint != AttachmentPoint_Color) + { + if (index > 0) + { + NazaraError("Index must be 0 for non-color attachments"); + return false; + } + } + else + { + if (index >= Renderer::GetMaxColorAttachments()) + { + NazaraError("Color index is over max color attachments (" + String::Number(index) + " >= " + String::Number(Renderer::GetMaxColorAttachments()) + ")"); + return false; + } + } + + if (attachmentPoint == AttachmentPoint_Stencil) + { + NazaraError("Targeting stencil-only textures is not supported"); + return false; + } + + unsigned int depthStencilIndex = attachmentIndex[AttachmentPoint_DepthStencil]; + if (attachmentPoint == AttachmentPoint_Depth && m_impl->attachments.size() > depthStencilIndex && + m_impl->attachments[depthStencilIndex].isUsed) { NazaraError("Depth target already attached by DepthStencil attachment"); return false; } - else if (attachmentPoint == nzAttachmentPoint_Stencil) + + if (!texture || !texture->IsValid()) { - NazaraError("Stencil target already attached by DepthStencil attachment"); + NazaraError("Invalid texture"); return false; } - } - nzAttachmentPoint targetAttachmentPoint = formatTypeToAttachment[NzPixelFormat::GetType(buffer->GetFormat())]; - if (targetAttachmentPoint != attachmentPoint && targetAttachmentPoint != nzAttachmentPoint_DepthStencil && - attachmentPoint != nzAttachmentPoint_Depth && attachmentPoint != nzAttachmentPoint_Stencil) - { - NazaraError("Pixel format type does not match attachment point type"); - return false; - } - #endif - - if (!Lock()) - { - NazaraError("Failed to lock render texture"); - return false; - } - - // Détachement de l'attache précédente (Si il y a) - Detach(attachmentPoint, index); - - glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_RENDERBUFFER, buffer->GetOpenGLID()); - - Unlock(); - - unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; - if (attachIndex >= m_impl->attachments.size()) - m_impl->attachments.resize(attachIndex+1); - - Attachment& attachment = m_impl->attachments[attachIndex]; - attachment.attachmentPoint = attachmentPoint; - attachment.buffer = buffer; - attachment.renderBufferDestroySlot.Connect(buffer->OnRenderBufferDestroy, std::bind(&NzRenderTexture::OnRenderBufferDestroy, this, std::placeholders::_1, attachIndex)); - attachment.isBuffer = true; - attachment.isUsed = true; - attachment.height = buffer->GetHeight(); - attachment.width = buffer->GetWidth(); - - InvalidateSize(); - InvalidateTargets(); - - if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets) - m_impl->colorTargets.push_back(index); - - return true; -} - -bool NzRenderTexture::AttachBuffer(nzAttachmentPoint attachmentPoint, nzUInt8 index, nzPixelFormat format, unsigned int width, unsigned int height) -{ - NzRenderBufferRef renderBuffer = NzRenderBuffer::New(); - if (!renderBuffer->Create(format, width, height)) - { - NazaraError("Failed to create RenderBuffer"); - return false; - } - - if (!AttachBuffer(attachmentPoint, index, renderBuffer)) - { - NazaraError("Failed to attach buffer"); - return false; - } - - return true; -} - -bool NzRenderTexture::AttachTexture(nzAttachmentPoint attachmentPoint, nzUInt8 index, NzTexture* texture, unsigned int z) -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return false; - } - - if (attachmentPoint != nzAttachmentPoint_Color) - { - if (index > 0) + unsigned int depth = (texture->GetType() == ImageType_Cubemap) ? 6 : texture->GetDepth(); + if (z >= depth) { - NazaraError("Index must be 0 for non-color attachments"); + NazaraError("Z value exceeds depth (" + String::Number(z) + " >= (" + String::Number(depth) + ')'); return false; } - } - else - { - if (index >= NzRenderer::GetMaxColorAttachments()) + + AttachmentPoint targetAttachmentPoint = formatTypeToAttachment[NzPixelFormat::GetType(texture->GetFormat())]; + if (targetAttachmentPoint != attachmentPoint && targetAttachmentPoint != AttachmentPoint_DepthStencil && + attachmentPoint != AttachmentPoint_Depth && attachmentPoint != AttachmentPoint_Stencil) { - NazaraError("Color index is over max color attachments (" + NzString::Number(index) + " >= " + NzString::Number(NzRenderer::GetMaxColorAttachments()) + ")"); + NazaraError("Pixel format type does not match attachment point type"); return false; } - } - - if (attachmentPoint == nzAttachmentPoint_Stencil) - { - NazaraError("Targeting stencil-only textures is not supported"); - return false; - } - - unsigned int depthStencilIndex = attachmentIndex[nzAttachmentPoint_DepthStencil]; - if (attachmentPoint == nzAttachmentPoint_Depth && m_impl->attachments.size() > depthStencilIndex && - m_impl->attachments[depthStencilIndex].isUsed) - { - NazaraError("Depth target already attached by DepthStencil attachment"); - return false; - } - - if (!texture || !texture->IsValid()) - { - NazaraError("Invalid texture"); - return false; - } - - unsigned int depth = (texture->GetType() == nzImageType_Cubemap) ? 6 : texture->GetDepth(); - if (z >= depth) - { - NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')'); - return false; - } - - nzAttachmentPoint targetAttachmentPoint = formatTypeToAttachment[NzPixelFormat::GetType(texture->GetFormat())]; - if (targetAttachmentPoint != attachmentPoint && targetAttachmentPoint != nzAttachmentPoint_DepthStencil && - attachmentPoint != nzAttachmentPoint_Depth && attachmentPoint != nzAttachmentPoint_Stencil) - { - NazaraError("Pixel format type does not match attachment point type"); - return false; - } - #endif - - if (!Lock()) - { - NazaraError("Failed to lock render texture"); - return false; - } - - // Détachement de l'attache précédente (Si il y a) - Detach(attachmentPoint, index); - - switch (texture->GetType()) - { - case nzImageType_1D: - glFramebufferTexture1D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_TEXTURE_1D, texture->GetOpenGLID(), 0); - break; - - case nzImageType_1D_Array: - case nzImageType_2D_Array: - glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, texture->GetOpenGLID(), 0, z); - break; - - case nzImageType_2D: - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_TEXTURE_2D, texture->GetOpenGLID(), 0); - break; - - case nzImageType_3D: - glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_TEXTURE_3D, texture->GetOpenGLID(), 0, z); - break; - - case nzImageType_Cubemap: - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, NzOpenGL::CubemapFace[z], texture->GetOpenGLID(), 0); - break; - } - - Unlock(); - - unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; - if (attachIndex >= m_impl->attachments.size()) - m_impl->attachments.resize(attachIndex+1); - - Attachment& attachment = m_impl->attachments[attachIndex]; - attachment.attachmentPoint = attachmentPoint; - attachment.isBuffer = false; - attachment.isUsed = true; - attachment.height = texture->GetHeight(); - attachment.texture = texture; - attachment.textureDestroySlot.Connect(texture->OnTextureDestroy, std::bind(&NzRenderTexture::OnTextureDestroy, this, std::placeholders::_1, attachIndex)); - attachment.width = texture->GetWidth(); - - InvalidateSize(); - InvalidateTargets(); - - if (attachmentPoint == nzAttachmentPoint_Color && !m_impl->userDefinedTargets) - m_impl->colorTargets.push_back(index); - - return true; -} - -bool NzRenderTexture::Create(bool lock) -{ - if (!IsSupported()) - { - NazaraError("Render textures not supported"); - return false; - } - - Destroy(); - - #if NAZARA_RENDERER_SAFE - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return false; - } - #endif - - std::unique_ptr impl(new NzRenderTextureImpl); - - impl->fbo = 0; - glGenFramebuffers(1, &impl->fbo); - - if (!impl->fbo) - { - NazaraError("Failed to create framebuffer"); - return false; - } - - m_impl = impl.release(); - m_impl->context = NzContext::GetCurrent(); - m_impl->contextDestroySlot.Connect(m_impl->context->OnContextDestroy, this, &NzRenderTexture::OnContextDestroy); - - m_checked = false; - m_drawBuffersUpdated = true; - m_sizeUpdated = false; - m_targetsUpdated = true; - - if (lock) - { - // En cas d'exception, la ressource sera quand même libérée - NzCallOnExit onExit([this] () - { - Destroy(); - }); + #endif if (!Lock()) { @@ -349,497 +248,601 @@ bool NzRenderTexture::Create(bool lock) return false; } - onExit.Reset(); - } + // Détachement de l'attache précédente (Si il y a) + Detach(attachmentPoint, index); - OnRenderTargetParametersChange(this); - OnRenderTargetSizeChange(this); - - return true; -} - -void NzRenderTexture::Destroy() -{ - if (m_impl) - { - if (IsActive()) - NzRenderer::SetTarget(nullptr); - - // Le FBO devant être supprimé dans son contexte d'origine, nous déléguons sa suppression à la classe OpenGL - // Celle-ci va libérer le FBO dès que possible (la prochaine fois que son contexte d'origine sera actif) - NzOpenGL::DeleteFrameBuffer(m_impl->context, m_impl->fbo); - - delete m_impl; // Enlève également une références sur les Texture/RenderBuffer - m_impl = nullptr; - } -} - -void NzRenderTexture::Detach(nzAttachmentPoint attachmentPoint, nzUInt8 index) -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Render texture not created"); - return; - } - - if (attachmentPoint != nzAttachmentPoint_Color && index > 0) - { - NazaraError("Index must be 0 for non-color attachments"); - return; - } - #endif - - unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; - if (attachIndex >= m_impl->attachments.size()) - return; - - Attachment& attachement = m_impl->attachments[attachIndex]; - if (!attachement.isUsed) - return; - - if (!Lock()) - { - NazaraError("Failed to lock render texture"); - return; - } - - attachement.isUsed = false; - - if (attachement.isBuffer) - { - glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, GL_RENDERBUFFER, 0); - - attachement.buffer = nullptr; - attachement.renderBufferDestroySlot.Disconnect(); - } - else - { - if (glFramebufferTexture) - glFramebufferTexture(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, 0, 0); - else - glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, NzOpenGL::Attachment[attachmentPoint]+index, 0, 0, 0); - - attachement.texture = nullptr; - attachement.textureDestroySlot.Disconnect(); - } - - InvalidateSize(); - - if (attachement.attachmentPoint == nzAttachmentPoint_Color) - InvalidateTargets(); - - Unlock(); - - m_checked = false; -} - -unsigned int NzRenderTexture::GetHeight() const -{ - NazaraAssert(m_impl, "Invalid render texture"); - - if (!m_sizeUpdated) - UpdateSize(); - - return m_impl->height; -} - -NzRenderTargetParameters NzRenderTexture::GetParameters() const -{ - NazaraAssert(m_impl, "Invalid render texture"); - - ///TODO - return NzRenderTargetParameters(); -} - -NzVector2ui NzRenderTexture::GetSize() const -{ - NazaraAssert(m_impl, "Invalid render texture"); - - if (!m_sizeUpdated) - UpdateSize(); - - return NzVector2ui(m_impl->width, m_impl->height); -} - -unsigned int NzRenderTexture::GetWidth() const -{ - NazaraAssert(m_impl, "Invalid render texture"); - - if (!m_sizeUpdated) - UpdateSize(); - - return m_impl->width; -} - -bool NzRenderTexture::IsComplete() const -{ - NazaraAssert(m_impl, "Invalid render texture"); - - if (!m_checked) - { - if (!Lock()) + switch (texture->GetType()) { - NazaraError("Failed to lock render texture"); - return false; + case ImageType_1D: + glFramebufferTexture1D(GL_DRAW_FRAMEBUFFER, OpenGL::Attachment[attachmentPoint]+index, GL_TEXTURE_1D, texture->GetOpenGLID(), 0); + break; + + case ImageType_1D_Array: + case ImageType_2D_Array: + glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, OpenGL::Attachment[attachmentPoint]+index, texture->GetOpenGLID(), 0, z); + break; + + case ImageType_2D: + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, OpenGL::Attachment[attachmentPoint]+index, GL_TEXTURE_2D, texture->GetOpenGLID(), 0); + break; + + case ImageType_3D: + glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, OpenGL::Attachment[attachmentPoint]+index, GL_TEXTURE_3D, texture->GetOpenGLID(), 0, z); + break; + + case ImageType_Cubemap: + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, OpenGL::Attachment[attachmentPoint]+index, OpenGL::CubemapFace[z], texture->GetOpenGLID(), 0); + break; } - GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); Unlock(); - m_impl->complete = false; + unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; + if (attachIndex >= m_impl->attachments.size()) + m_impl->attachments.resize(attachIndex+1); - switch (status) + Attachment& attachment = m_impl->attachments[attachIndex]; + attachment.attachmentPoint = attachmentPoint; + attachment.isBuffer = false; + attachment.isUsed = true; + attachment.height = texture->GetHeight(); + attachment.texture = texture; + attachment.textureDestroySlot.Connect(texture->OnTextureDestroy, std::bind(&RenderTexture::OnTextureDestroy, this, std::placeholders::_1, attachIndex)); + attachment.width = texture->GetWidth(); + + InvalidateSize(); + InvalidateTargets(); + + if (attachmentPoint == AttachmentPoint_Color && !m_impl->userDefinedTargets) + m_impl->colorTargets.push_back(index); + + return true; + } + + bool RenderTexture::Create(bool lock) + { + if (!IsSupported()) { - case GL_FRAMEBUFFER_COMPLETE: - m_impl->complete = true; - break; - - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - NazaraError("Incomplete attachment"); - break; - - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: - NazaraInternalError("Incomplete draw buffer"); - break; - - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - NazaraInternalError("Incomplete read buffer"); - break; - - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - NazaraError("Incomplete missing attachment"); - break; - - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: - NazaraError("Incomplete multisample"); - break; - - case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: - NazaraError("Incomplete layer targets"); - break; - - case GL_FRAMEBUFFER_UNSUPPORTED: - NazaraError("Render texture has unsupported attachments"); - break; - - default: - NazaraInternalError("Unknown error"); + NazaraError("Render textures not supported"); + return false; } - m_checked = true; - } + Destroy(); - return m_impl->complete; -} - -bool NzRenderTexture::IsRenderable() const -{ - return IsComplete() && !m_impl->attachments.empty(); -} - -bool NzRenderTexture::Lock() const -{ - NazaraAssert(m_impl, "Invalid render texture"); - - #if NAZARA_RENDERER_SAFE - if (NzContext::GetCurrent() != m_impl->context) - { - NazaraError("RenderTexture cannot be used with this context"); - return false; - } - #endif - - if (lockedLevel++ == 0) - { - GLint previous; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &previous); - - lockedPrevious = previous; - - if (lockedPrevious != m_impl->fbo) - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_impl->fbo); - } - - return true; -} - -void NzRenderTexture::SetColorTargets(const nzUInt8* targets, unsigned int targetCount) const -{ - NazaraAssert(m_impl, "Invalid render texture"); - - #if NAZARA_RENDERER_SAFE - for (unsigned int i = 0; i < targetCount; ++i) - { - unsigned int index = attachmentIndex[nzAttachmentPoint_Color] + targets[i]; - if (index >= m_impl->attachments.size() || !m_impl->attachments[index].isUsed) + #if NAZARA_RENDERER_SAFE + if (Context::GetCurrent() == nullptr) { - NazaraError("Target " + NzString::Number(targets[i]) + " not attached"); + NazaraError("No active context"); + return false; + } + #endif + + std::unique_ptr impl(new RenderTextureImpl); + + impl->fbo = 0; + glGenFramebuffers(1, &impl->fbo); + + if (!impl->fbo) + { + NazaraError("Failed to create framebuffer"); + return false; + } + + m_impl = impl.release(); + m_impl->context = Context::GetCurrent(); + m_impl->contextDestroySlot.Connect(m_impl->context->OnContextDestroy, this, &RenderTexture::OnContextDestroy); + + m_checked = false; + m_drawBuffersUpdated = true; + m_sizeUpdated = false; + m_targetsUpdated = true; + + if (lock) + { + // En cas d'exception, la ressource sera quand même libérée + CallOnExit onExit([this] () + { + Destroy(); + }); + + if (!Lock()) + { + NazaraError("Failed to lock render texture"); + return false; + } + + onExit.Reset(); + } + + OnRenderTargetParametersChange(this); + OnRenderTargetSizeChange(this); + + return true; + } + + void RenderTexture::Destroy() + { + if (m_impl) + { + if (IsActive()) + Renderer::SetTarget(nullptr); + + // Le FBO devant être supprimé dans son contexte d'origine, nous déléguons sa suppression à la classe OpenGL + // Celle-ci va libérer le FBO dès que possible (la prochaine fois que son contexte d'origine sera actif) + OpenGL::DeleteFrameBuffer(m_impl->context, m_impl->fbo); + + delete m_impl; // Enlève également une références sur les Texture/RenderBuffer + m_impl = nullptr; + } + } + + void RenderTexture::Detach(AttachmentPoint attachmentPoint, UInt8 index) + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Render texture not created"); return; } - } - #endif - m_impl->colorTargets.resize(targetCount); - std::memcpy(&m_impl->colorTargets[0], targets, targetCount*sizeof(nzUInt8)); - - m_impl->userDefinedTargets = true; - InvalidateDrawBuffers(); -} - -void NzRenderTexture::SetColorTargets(const std::initializer_list& targets) const -{ - NazaraAssert(m_impl, "Invalid render texture"); - - #if NAZARA_RENDERER_SAFE - for (nzUInt8 target : targets) - { - unsigned int index = attachmentIndex[nzAttachmentPoint_Color] + target; - if (index >= m_impl->attachments.size() || !m_impl->attachments[index].isUsed) + if (attachmentPoint != AttachmentPoint_Color && index > 0) { - NazaraError("Target " + NzString::Number(target) + " not attached"); + NazaraError("Index must be 0 for non-color attachments"); return; } - } - #endif + #endif - m_impl->colorTargets.resize(targets.size()); + unsigned int attachIndex = attachmentIndex[attachmentPoint] + index; + if (attachIndex >= m_impl->attachments.size()) + return; - nzUInt8* ptr = &m_impl->colorTargets[0]; - for (nzUInt8 index : targets) - *ptr++ = index; + Attachment& attachement = m_impl->attachments[attachIndex]; + if (!attachement.isUsed) + return; - m_impl->userDefinedTargets = true; - InvalidateDrawBuffers(); -} + if (!Lock()) + { + NazaraError("Failed to lock render texture"); + return; + } -void NzRenderTexture::Unlock() const -{ - NazaraAssert(m_impl, "Invalid render texture"); + attachement.isUsed = false; - #if NAZARA_RENDERER_SAFE - if (NzContext::GetCurrent() != m_impl->context) - { - NazaraError("RenderTexture cannot be used with this context"); - return; + if (attachement.isBuffer) + { + glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, OpenGL::Attachment[attachmentPoint]+index, GL_RENDERBUFFER, 0); + + attachement.buffer = nullptr; + attachement.renderBufferDestroySlot.Disconnect(); + } + else + { + if (glFramebufferTexture) + glFramebufferTexture(GL_DRAW_FRAMEBUFFER, OpenGL::Attachment[attachmentPoint]+index, 0, 0); + else + glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, OpenGL::Attachment[attachmentPoint]+index, 0, 0, 0); + + attachement.texture = nullptr; + attachement.textureDestroySlot.Disconnect(); + } + + InvalidateSize(); + + if (attachement.attachmentPoint == AttachmentPoint_Color) + InvalidateTargets(); + + Unlock(); + + m_checked = false; } - if (lockedLevel == 0) + unsigned int RenderTexture::GetHeight() const { - NazaraWarning("Unlock called on non-locked texture"); - return; - } - #endif + NazaraAssert(m_impl, "Invalid render texture"); - if (--lockedLevel == 0 && lockedPrevious != m_impl->fbo) // Ici, il est important qu'un FBO soit débindé si l'ancien était 0 - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, lockedPrevious); -} + if (!m_sizeUpdated) + UpdateSize(); -unsigned int NzRenderTexture::GetOpenGLID() const -{ - NazaraAssert(m_impl, "Invalid render texture"); - - #if NAZARA_RENDERER_SAFE - if (NzContext::GetCurrent() != m_impl->context) - { - NazaraError("RenderTexture cannot be used with this context"); - return 0; - } - #endif - - return m_impl->fbo; -} - -bool NzRenderTexture::HasContext() const -{ - return false; -} - -bool NzRenderTexture::IsSupported() -{ - return NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject); -} - -void NzRenderTexture::Blit(NzRenderTexture* src, NzRectui srcRect, NzRenderTexture* dst, NzRectui dstRect, nzUInt32 buffers, bool bilinearFilter) -{ - NazaraAssert(src && src->IsValid(), "Invalid source render texture"); - NazaraAssert(dst && dst->IsValid(), "Invalid destination render texture"); - - #if NAZARA_RENDERER_SAFE - if (srcRect.x+srcRect.width > src->GetWidth() || srcRect.y+srcRect.height > src->GetHeight()) - { - NazaraError("Source rectangle dimensions are out of bounds"); - return; + return m_impl->height; } - if (dstRect.x+dstRect.width > dst->GetWidth() || dstRect.y+dstRect.height > dst->GetHeight()) + RenderTargetParameters RenderTexture::GetParameters() const { - NazaraError("Destination rectangle dimensions are out of bounds"); - return; + NazaraAssert(m_impl, "Invalid render texture"); + + ///TODO + return RenderTargetParameters(); } - if (bilinearFilter && (buffers & nzRendererBuffer_Depth || buffers & nzRendererBuffer_Stencil)) + Vector2ui RenderTexture::GetSize() const { - NazaraError("Filter cannot be bilinear when blitting depth/stencil buffers"); - return; + NazaraAssert(m_impl, "Invalid render texture"); + + if (!m_sizeUpdated) + UpdateSize(); + + return Vector2ui(m_impl->width, m_impl->height); } - #endif - GLbitfield mask = 0; - if (buffers & nzRendererBuffer_Color) - mask |= GL_COLOR_BUFFER_BIT; - - if (buffers & nzRendererBuffer_Depth) - mask |= GL_DEPTH_BUFFER_BIT; - - if (buffers & nzRendererBuffer_Stencil) - mask |= GL_STENCIL_BUFFER_BIT; - - GLint previousDrawBuffer, previousReadBuffer; - glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &previousDrawBuffer); - glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &previousReadBuffer); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst->GetOpenGLID()); - glBindFramebuffer(GL_READ_FRAMEBUFFER, src->GetOpenGLID()); - - glBlitFramebuffer(srcRect.x, srcRect.y, srcRect.x + srcRect.width, srcRect.y + srcRect.height, - dstRect.x, dstRect.y, dstRect.x + dstRect.width, dstRect.y + dstRect.height, - mask, (bilinearFilter) ? GL_LINEAR : GL_NEAREST); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, previousDrawBuffer); - glBindFramebuffer(GL_READ_FRAMEBUFFER, previousReadBuffer); -} - -bool NzRenderTexture::Activate() const -{ - NazaraAssert(m_impl, "Invalid render texture"); - - #if NAZARA_RENDERER_SAFE - if (NzContext::GetCurrent() != m_impl->context) + unsigned int RenderTexture::GetWidth() const + { + NazaraAssert(m_impl, "Invalid render texture"); + + if (!m_sizeUpdated) + UpdateSize(); + + return m_impl->width; + } + + bool RenderTexture::IsComplete() const + { + NazaraAssert(m_impl, "Invalid render texture"); + + if (!m_checked) + { + if (!Lock()) + { + NazaraError("Failed to lock render texture"); + return false; + } + + GLenum status = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER); + Unlock(); + + m_impl->complete = false; + + switch (status) + { + case GL_FRAMEBUFFER_COMPLETE: + m_impl->complete = true; + break; + + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + NazaraError("Incomplete attachment"); + break; + + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: + NazaraInternalError("Incomplete draw buffer"); + break; + + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: + NazaraInternalError("Incomplete read buffer"); + break; + + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + NazaraError("Incomplete missing attachment"); + break; + + case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: + NazaraError("Incomplete multisample"); + break; + + case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: + NazaraError("Incomplete layer targets"); + break; + + case GL_FRAMEBUFFER_UNSUPPORTED: + NazaraError("Render texture has unsupported attachments"); + break; + + default: + NazaraInternalError("Unknown error"); + } + + m_checked = true; + } + + return m_impl->complete; + } + + bool RenderTexture::IsRenderable() const + { + return IsComplete() && !m_impl->attachments.empty(); + } + + bool RenderTexture::Lock() const + { + NazaraAssert(m_impl, "Invalid render texture"); + + #if NAZARA_RENDERER_SAFE + if (Context::GetCurrent() != m_impl->context) + { + NazaraError("RenderTexture cannot be used with this context"); + return false; + } + #endif + + if (lockedLevel++ == 0) + { + GLint previous; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &previous); + + lockedPrevious = previous; + + if (lockedPrevious != m_impl->fbo) + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_impl->fbo); + } + + return true; + } + + void RenderTexture::SetColorTargets(const UInt8* targets, unsigned int targetCount) const + { + NazaraAssert(m_impl, "Invalid render texture"); + + #if NAZARA_RENDERER_SAFE + for (unsigned int i = 0; i < targetCount; ++i) + { + unsigned int index = attachmentIndex[AttachmentPoint_Color] + targets[i]; + if (index >= m_impl->attachments.size() || !m_impl->attachments[index].isUsed) + { + NazaraError("Target " + String::Number(targets[i]) + " not attached"); + return; + } + } + #endif + + m_impl->colorTargets.resize(targetCount); + std::memcpy(&m_impl->colorTargets[0], targets, targetCount*sizeof(UInt8)); + + m_impl->userDefinedTargets = true; + InvalidateDrawBuffers(); + } + + void RenderTexture::SetColorTargets(const std::initializer_list& targets) const + { + NazaraAssert(m_impl, "Invalid render texture"); + + #if NAZARA_RENDERER_SAFE + for (UInt8 target : targets) + { + unsigned int index = attachmentIndex[AttachmentPoint_Color] + target; + if (index >= m_impl->attachments.size() || !m_impl->attachments[index].isUsed) + { + NazaraError("Target " + String::Number(target) + " not attached"); + return; + } + } + #endif + + m_impl->colorTargets.resize(targets.size()); + + UInt8* ptr = &m_impl->colorTargets[0]; + for (UInt8 index : targets) + *ptr++ = index; + + m_impl->userDefinedTargets = true; + InvalidateDrawBuffers(); + } + + void RenderTexture::Unlock() const + { + NazaraAssert(m_impl, "Invalid render texture"); + + #if NAZARA_RENDERER_SAFE + if (Context::GetCurrent() != m_impl->context) + { + NazaraError("RenderTexture cannot be used with this context"); + return; + } + + if (lockedLevel == 0) + { + NazaraWarning("Unlock called on non-locked texture"); + return; + } + #endif + + if (--lockedLevel == 0 && lockedPrevious != m_impl->fbo) // Ici, il est important qu'un FBO soit débindé si l'ancien était 0 + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, lockedPrevious); + } + + unsigned int RenderTexture::GetOpenGLID() const + { + NazaraAssert(m_impl, "Invalid render texture"); + + #if NAZARA_RENDERER_SAFE + if (Context::GetCurrent() != m_impl->context) + { + NazaraError("RenderTexture cannot be used with this context"); + return 0; + } + #endif + + return m_impl->fbo; + } + + bool RenderTexture::HasContext() const { - NazaraError("RenderTexture cannot be used with this context"); return false; } - #endif - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_impl->fbo); - - m_drawBuffersUpdated = false; - - return true; -} - -void NzRenderTexture::Desactivate() const -{ - NazaraAssert(m_impl, "Invalid render texture"); - - #if NAZARA_RENDERER_SAFE - if (NzContext::GetCurrent() != m_impl->context) + bool RenderTexture::IsSupported() { - NazaraError("RenderTexture cannot be used with this context"); - return; + return OpenGL::IsSupported(OpenGLExtension_FrameBufferObject); } - #endif - glFlush(); - - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); -} - -void NzRenderTexture::EnsureTargetUpdated() const -{ - if (!m_drawBuffersUpdated) - UpdateDrawBuffers(); - - for (nzUInt8 index : m_impl->colorTargets) + void RenderTexture::Blit(RenderTexture* src, Rectui srcRect, RenderTexture* dst, Rectui dstRect, UInt32 buffers, bool bilinearFilter) { - Attachment& attachment = m_impl->attachments[attachmentIndex[nzAttachmentPoint_Color] + index]; - if (!attachment.isBuffer) - attachment.texture->InvalidateMipmaps(); - } -} + NazaraAssert(src && src->IsValid(), "Invalid source render texture"); + NazaraAssert(dst && dst->IsValid(), "Invalid destination render texture"); -void NzRenderTexture::OnContextDestroy(const NzContext* context) -{ - NazaraAssert(m_impl, "Invalid internal state"); - NazaraUnused(context); - - #ifdef NAZARA_DEBUG - if (m_impl->context != context) - { - NazaraInternalError("Not listening to " + NzString::Pointer(context)); - return; - } - #endif - - Destroy(); -} - -void NzRenderTexture::OnRenderBufferDestroy(const NzRenderBuffer* renderBuffer, unsigned int attachmentIndex) -{ - NazaraAssert(m_impl, "Invalid internal state"); - NazaraAssert(attachmentIndex < m_impl->attachments.size(), "Invalid attachment index"); - NazaraAssert(m_impl->attachments[attachmentIndex].isBuffer, "Invalid attachment state"); - NazaraUnused(renderBuffer); - - Attachment& attachment = m_impl->attachments[attachmentIndex]; - attachment.buffer = nullptr; - attachment.isUsed = false; - attachment.renderBufferDestroySlot.Disconnect(); - - InvalidateTargets(); -} - -void NzRenderTexture::OnTextureDestroy(const NzTexture* texture, unsigned int attachmentIndex) -{ - NazaraAssert(m_impl, "Invalid internal state"); - NazaraAssert(attachmentIndex < m_impl->attachments.size(), "Invalid attachment index"); - NazaraAssert(!m_impl->attachments[attachmentIndex].isBuffer, "Invalid attachment state"); - NazaraUnused(texture); - - InvalidateTargets(); -} - -void NzRenderTexture::UpdateDrawBuffers() const -{ - if (!m_targetsUpdated) - UpdateTargets(); - - glDrawBuffers(m_impl->drawBuffers.size(), &m_impl->drawBuffers[0]); - - m_drawBuffersUpdated = true; -} - -void NzRenderTexture::UpdateSize() const -{ - m_impl->width = 0; - m_impl->height = 0; - for (Attachment& attachment : m_impl->attachments) - { - if (attachment.isUsed) + #if NAZARA_RENDERER_SAFE + if (srcRect.x+srcRect.width > src->GetWidth() || srcRect.y+srcRect.height > src->GetHeight()) { - m_impl->height = std::max(m_impl->height, attachment.height); - m_impl->width = std::max(m_impl->width, attachment.width); + NazaraError("Source rectangle dimensions are out of bounds"); + return; + } + + if (dstRect.x+dstRect.width > dst->GetWidth() || dstRect.y+dstRect.height > dst->GetHeight()) + { + NazaraError("Destination rectangle dimensions are out of bounds"); + return; + } + + if (bilinearFilter && (buffers & RendererBuffer_Depth || buffers & RendererBuffer_Stencil)) + { + NazaraError("Filter cannot be bilinear when blitting depth/stencil buffers"); + return; + } + #endif + + GLbitfield mask = 0; + if (buffers & RendererBuffer_Color) + mask |= GL_COLOR_BUFFER_BIT; + + if (buffers & RendererBuffer_Depth) + mask |= GL_DEPTH_BUFFER_BIT; + + if (buffers & RendererBuffer_Stencil) + mask |= GL_STENCIL_BUFFER_BIT; + + GLint previousDrawBuffer, previousReadBuffer; + glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &previousDrawBuffer); + glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &previousReadBuffer); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, dst->GetOpenGLID()); + glBindFramebuffer(GL_READ_FRAMEBUFFER, src->GetOpenGLID()); + + glBlitFramebuffer(srcRect.x, srcRect.y, srcRect.x + srcRect.width, srcRect.y + srcRect.height, + dstRect.x, dstRect.y, dstRect.x + dstRect.width, dstRect.y + dstRect.height, + mask, (bilinearFilter) ? GL_LINEAR : GL_NEAREST); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, previousDrawBuffer); + glBindFramebuffer(GL_READ_FRAMEBUFFER, previousReadBuffer); + } + + bool RenderTexture::Activate() const + { + NazaraAssert(m_impl, "Invalid render texture"); + + #if NAZARA_RENDERER_SAFE + if (Context::GetCurrent() != m_impl->context) + { + NazaraError("RenderTexture cannot be used with this context"); + return false; + } + #endif + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_impl->fbo); + + m_drawBuffersUpdated = false; + + return true; + } + + void RenderTexture::Desactivate() const + { + NazaraAssert(m_impl, "Invalid render texture"); + + #if NAZARA_RENDERER_SAFE + if (Context::GetCurrent() != m_impl->context) + { + NazaraError("RenderTexture cannot be used with this context"); + return; + } + #endif + + glFlush(); + + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + } + + void RenderTexture::EnsureTargetUpdated() const + { + if (!m_drawBuffersUpdated) + UpdateDrawBuffers(); + + for (UInt8 index : m_impl->colorTargets) + { + Attachment& attachment = m_impl->attachments[attachmentIndex[AttachmentPoint_Color] + index]; + if (!attachment.isBuffer) + attachment.texture->InvalidateMipmaps(); } } - m_sizeUpdated = true; -} + void RenderTexture::OnContextDestroy(const Context* context) + { + NazaraAssert(m_impl, "Invalid internal state"); + NazaraUnused(context); -void NzRenderTexture::UpdateTargets() const -{ - if (m_impl->colorTargets.empty()) - { - m_impl->drawBuffers.resize(1); - m_impl->drawBuffers[0] = GL_NONE; - } - else - { - m_impl->drawBuffers.resize(m_impl->colorTargets.size()); - GLenum* ptr = &m_impl->drawBuffers[0]; - for (nzUInt8 index : m_impl->colorTargets) - *ptr++ = GL_COLOR_ATTACHMENT0 + index; + #ifdef NAZARA_DEBUG + if (m_impl->context != context) + { + NazaraInternalError("Not listening to " + String::Pointer(context)); + return; + } + #endif + + Destroy(); } - m_targetsUpdated = true; + void RenderTexture::OnRenderBufferDestroy(const RenderBuffer* renderBuffer, unsigned int attachmentIndex) + { + NazaraAssert(m_impl, "Invalid internal state"); + NazaraAssert(attachmentIndex < m_impl->attachments.size(), "Invalid attachment index"); + NazaraAssert(m_impl->attachments[attachmentIndex].isBuffer, "Invalid attachment state"); + NazaraUnused(renderBuffer); + + Attachment& attachment = m_impl->attachments[attachmentIndex]; + attachment.buffer = nullptr; + attachment.isUsed = false; + attachment.renderBufferDestroySlot.Disconnect(); + + InvalidateTargets(); + } + + void RenderTexture::OnTextureDestroy(const Texture* texture, unsigned int attachmentIndex) + { + NazaraAssert(m_impl, "Invalid internal state"); + NazaraAssert(attachmentIndex < m_impl->attachments.size(), "Invalid attachment index"); + NazaraAssert(!m_impl->attachments[attachmentIndex].isBuffer, "Invalid attachment state"); + NazaraUnused(texture); + + InvalidateTargets(); + } + + void RenderTexture::UpdateDrawBuffers() const + { + if (!m_targetsUpdated) + UpdateTargets(); + + glDrawBuffers(m_impl->drawBuffers.size(), &m_impl->drawBuffers[0]); + + m_drawBuffersUpdated = true; + } + + void RenderTexture::UpdateSize() const + { + m_impl->width = 0; + m_impl->height = 0; + for (Attachment& attachment : m_impl->attachments) + { + if (attachment.isUsed) + { + m_impl->height = std::max(m_impl->height, attachment.height); + m_impl->width = std::max(m_impl->width, attachment.width); + } + } + + m_sizeUpdated = true; + } + + void RenderTexture::UpdateTargets() const + { + if (m_impl->colorTargets.empty()) + { + m_impl->drawBuffers.resize(1); + m_impl->drawBuffers[0] = GL_NONE; + } + else + { + m_impl->drawBuffers.resize(m_impl->colorTargets.size()); + GLenum* ptr = &m_impl->drawBuffers[0]; + for (UInt8 index : m_impl->colorTargets) + *ptr++ = GL_COLOR_ATTACHMENT0 + index; + } + + m_targetsUpdated = true; + } } diff --git a/src/Nazara/Renderer/RenderWindow.cpp b/src/Nazara/Renderer/RenderWindow.cpp index 576434c7b..a9effa622 100644 --- a/src/Nazara/Renderer/RenderWindow.cpp +++ b/src/Nazara/Renderer/RenderWindow.cpp @@ -13,277 +13,279 @@ #include #include -NzRenderWindow::NzRenderWindow(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters) : -NzRenderTarget(), NzWindow() +namespace Nz { - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - Create(mode, title, style, parameters); -} - -NzRenderWindow::NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters) : -NzRenderTarget(), NzWindow() -{ - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - Create(handle, parameters); -} - -NzRenderWindow::~NzRenderWindow() -{ - // Nécessaire si NzWindow::Destroy est appelé par son destructeur - OnWindowDestroy(); -} - -bool NzRenderWindow::CopyToImage(NzAbstractImage* image, const NzVector3ui& dstPos) const -{ - #if NAZARA_RENDERER_SAFE - if (!m_context) + RenderWindow::RenderWindow(VideoMode mode, const String& title, UInt32 style, const ContextParameters& parameters) : + RenderTarget(), Window() { - NazaraError("Window has not been created"); - return false; - } - #endif - - return CopyToImage(image, NzRectui(NzVector2ui(0U), GetSize()), dstPos); -} - -bool NzRenderWindow::CopyToImage(NzAbstractImage* image, const NzRectui& rect, const NzVector3ui& dstPos) const -{ - #if NAZARA_RENDERER_SAFE - if (!m_context) - { - NazaraError("Window has not been created"); - return false; - } - #endif - - NzVector2ui windowSize = GetSize(); - - #if NAZARA_RENDERER_SAFE - if (!image) - { - NazaraError("Image must be valid"); - return false; + ErrorFlags flags(ErrorFlag_ThrowException, true); + Create(mode, title, style, parameters); } - if (image->GetFormat() != nzPixelFormat_RGBA8) + RenderWindow::RenderWindow(WindowHandle handle, const ContextParameters& parameters) : + RenderTarget(), Window() { - // Pour plus de facilité, évidemment on peut faire sauter cette règle avec un peu de gestion - NazaraError("Image must be RGBA8-formatted"); - return false; + ErrorFlags flags(ErrorFlag_ThrowException, true); + Create(handle, parameters); } - if (rect.x + rect.width > windowSize.x || rect.y + rect.height > windowSize.y) + RenderWindow::~RenderWindow() { - NazaraError("Rectangle dimensions are out of window's bounds"); - return false; + // Nécessaire si Window::Destroy est appelé par son destructeur + OnWindowDestroy(); } - NzVector3ui imageSize = image->GetSize(); - if (dstPos.x + rect.width > imageSize.x || dstPos.y + rect.height > imageSize.y || dstPos.z > imageSize.z) + bool RenderWindow::CopyToImage(AbstractImage* image, const Vector3ui& dstPos) const { - NazaraError("Cube dimensions are out of image's bounds"); - return false; - } - #endif - - const NzContext* currentContext = NzContext::GetCurrent(); - if (m_context != currentContext) - { - if (!m_context->SetActive(true)) + #if NAZARA_RENDERER_SAFE + if (!m_context) { - NazaraError("Failed to activate context"); + NazaraError("Window has not been created"); + return false; + } + #endif + + return CopyToImage(image, Rectui(Vector2ui(0U), GetSize()), dstPos); + } + + bool RenderWindow::CopyToImage(AbstractImage* image, const Rectui& rect, const Vector3ui& dstPos) const + { + #if NAZARA_RENDERER_SAFE + if (!m_context) + { + NazaraError("Window has not been created"); + return false; + } + #endif + + Vector2ui windowSize = GetSize(); + + #if NAZARA_RENDERER_SAFE + if (!image) + { + NazaraError("Image must be valid"); + return false; + } + + if (image->GetFormat() != PixelFormatType_RGBA8) + { + // Pour plus de facilité, évidemment on peut faire sauter cette règle avec un peu de gestion + NazaraError("Image must be RGBA8-formatted"); + return false; + } + + if (rect.x + rect.width > windowSize.x || rect.y + rect.height > windowSize.y) + { + NazaraError("Rectangle dimensions are out of window's bounds"); + return false; + } + + Vector3ui imageSize = image->GetSize(); + if (dstPos.x + rect.width > imageSize.x || dstPos.y + rect.height > imageSize.y || dstPos.z > imageSize.z) + { + NazaraError("Cube dimensions are out of image's bounds"); + return false; + } + #endif + + const Context* currentContext = Context::GetCurrent(); + if (m_context != currentContext) + { + if (!m_context->SetActive(true)) + { + NazaraError("Failed to activate context"); + return false; + } + } + + ///TODO: Fast-path pour les images en cas de copie du buffer entier + + m_buffer.resize(rect.width*rect.height*4); + glReadPixels(rect.x, windowSize.y - rect.height - rect.y, rect.width, rect.height, GL_RGBA, GL_UNSIGNED_BYTE, m_buffer.data()); + + // Les pixels sont retournés, nous devons envoyer les pixels par rangée + for (unsigned int i = 0; i < rect.height; ++i) + image->Update(&m_buffer[rect.width*4*i], Boxui(dstPos.x, rect.height - i - 1, dstPos.z, rect.width, 1, 1), rect.width); + + if (m_context != currentContext) + { + if (currentContext) + { + if (!currentContext->SetActive(true)) + NazaraWarning("Failed to reset old context"); + } + else + m_context->SetActive(false); + } + + return true; + } + + bool RenderWindow::Create(VideoMode mode, const String& title, UInt32 style, const ContextParameters& parameters) + { + m_parameters = parameters; + return Window::Create(mode, title, style); + } + + bool RenderWindow::Create(WindowHandle handle, const ContextParameters& parameters) + { + m_parameters = parameters; + return Window::Create(handle); + } + + void RenderWindow::Display() + { + if (m_framerateLimit > 0) + { + int remainingTime = 1000/static_cast(m_framerateLimit) - static_cast(m_clock.GetMilliseconds()); + if (remainingTime > 0) + Thread::Sleep(remainingTime); + + m_clock.Restart(); + } + + if (m_context && m_parameters.doubleBuffered) + m_context->SwapBuffers(); + } + + void RenderWindow::EnableVerticalSync(bool enabled) + { + if (m_context) + { + if (!m_context->SetActive(true)) + { + NazaraError("Failed to activate context"); + return; + } + + m_context->EnableVerticalSync(enabled); + } + else + NazaraError("No context"); + } + + unsigned int RenderWindow::GetHeight() const + { + return Window::GetHeight(); + } + + RenderTargetParameters RenderWindow::GetParameters() const + { + if (m_context) + { + const ContextParameters& parameters = m_context->GetParameters(); + return RenderTargetParameters(parameters.antialiasingLevel, parameters.depthBits, parameters.stencilBits); + } + else + { + NazaraError("Window not created/context not initialized"); + return RenderTargetParameters(); + } + } + + unsigned int RenderWindow::GetWidth() const + { + return Window::GetWidth(); + } + + bool RenderWindow::IsRenderable() const + { + return m_impl != nullptr; // Si m_impl est valide, alors m_context l'est aussi + } + + bool RenderWindow::IsValid() const + { + return m_impl != nullptr; + } + + void RenderWindow::SetFramerateLimit(unsigned int limit) + { + m_framerateLimit = limit; + } + + ContextParameters RenderWindow::GetContextParameters() const + { + if (m_context) + return m_context->GetParameters(); + else + { + NazaraError("Window not created/context not initialized"); + return ContextParameters(); + } + } + + bool RenderWindow::HasContext() const + { + return true; + } + + bool RenderWindow::Activate() const + { + if (m_context->SetActive(true)) + { + glDrawBuffer((m_parameters.doubleBuffered) ? GL_BACK : GL_FRONT); + return true; + } + else + { + NazaraError("Failed to activate window's context"); return false; } } - ///TODO: Fast-path pour les images en cas de copie du buffer entier - - m_buffer.resize(rect.width*rect.height*4); - glReadPixels(rect.x, windowSize.y - rect.height - rect.y, rect.width, rect.height, GL_RGBA, GL_UNSIGNED_BYTE, m_buffer.data()); - - // Les pixels sont retournés, nous devons envoyer les pixels par rangée - for (unsigned int i = 0; i < rect.height; ++i) - image->Update(&m_buffer[rect.width*4*i], NzBoxui(dstPos.x, rect.height - i - 1, dstPos.z, rect.width, 1, 1), rect.width); - - if (m_context != currentContext) + void RenderWindow::EnsureTargetUpdated() const { - if (currentContext) - { - if (!currentContext->SetActive(true)) - NazaraWarning("Failed to reset old context"); - } - else - m_context->SetActive(false); + // Rien à faire } - return true; -} - - -bool NzRenderWindow::Create(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters) -{ - m_parameters = parameters; - return NzWindow::Create(mode, title, style); -} - -bool NzRenderWindow::Create(NzWindowHandle handle, const NzContextParameters& parameters) -{ - m_parameters = parameters; - return NzWindow::Create(handle); -} - -void NzRenderWindow::Display() -{ - if (m_framerateLimit > 0) + bool RenderWindow::OnWindowCreated() { - int remainingTime = 1000/static_cast(m_framerateLimit) - static_cast(m_clock.GetMilliseconds()); - if (remainingTime > 0) - NzThread::Sleep(remainingTime); + m_parameters.doubleBuffered = true; + m_parameters.window = GetHandle(); + + std::unique_ptr context(new Context); + if (!context->Create(m_parameters)) + { + NazaraError("Failed to create context"); + return false; + } + + m_context = context.release(); + + if (!SetActive(true)) // Les fenêtres s'activent à la création + NazaraWarning("Failed to activate window"); + + EnableVerticalSync(false); + + Vector2ui size = GetSize(); + + // Le scissorBox/viewport (à la création) est de la taille de la fenêtre + // https://www.opengl.org/sdk/docs/man/xhtml/glGet.xml + OpenGL::SetScissorBox(Recti(0, 0, size.x, size.y)); + OpenGL::SetViewport(Recti(0, 0, size.x, size.y)); + + OnRenderTargetParametersChange(this); + OnRenderTargetSizeChange(this); m_clock.Restart(); - } - if (m_context && m_parameters.doubleBuffered) - m_context->SwapBuffers(); -} - -void NzRenderWindow::EnableVerticalSync(bool enabled) -{ - if (m_context) - { - if (!m_context->SetActive(true)) - { - NazaraError("Failed to activate context"); - return; - } - - m_context->EnableVerticalSync(enabled); - } - else - NazaraError("No context"); -} - -unsigned int NzRenderWindow::GetHeight() const -{ - return NzWindow::GetHeight(); -} - -NzRenderTargetParameters NzRenderWindow::GetParameters() const -{ - if (m_context) - { - const NzContextParameters& parameters = m_context->GetParameters(); - return NzRenderTargetParameters(parameters.antialiasingLevel, parameters.depthBits, parameters.stencilBits); - } - else - { - NazaraError("Window not created/context not initialized"); - return NzRenderTargetParameters(); - } -} - -unsigned int NzRenderWindow::GetWidth() const -{ - return NzWindow::GetWidth(); -} - -bool NzRenderWindow::IsRenderable() const -{ - return m_impl != nullptr; // Si m_impl est valide, alors m_context l'est aussi -} - -bool NzRenderWindow::IsValid() const -{ - return m_impl != nullptr; -} - -void NzRenderWindow::SetFramerateLimit(unsigned int limit) -{ - m_framerateLimit = limit; -} - -NzContextParameters NzRenderWindow::GetContextParameters() const -{ - if (m_context) - return m_context->GetParameters(); - else - { - NazaraError("Window not created/context not initialized"); - return NzContextParameters(); - } -} - -bool NzRenderWindow::HasContext() const -{ - return true; -} - -bool NzRenderWindow::Activate() const -{ - if (m_context->SetActive(true)) - { - glDrawBuffer((m_parameters.doubleBuffered) ? GL_BACK : GL_FRONT); return true; } - else + + void RenderWindow::OnWindowDestroy() { - NazaraError("Failed to activate window's context"); - return false; - } -} + if (m_context) + { + if (IsActive()) + Renderer::SetTarget(nullptr); -void NzRenderWindow::EnsureTargetUpdated() const -{ - // Rien à faire -} - -bool NzRenderWindow::OnWindowCreated() -{ - m_parameters.doubleBuffered = true; - m_parameters.window = GetHandle(); - - std::unique_ptr context(new NzContext); - if (!context->Create(m_parameters)) - { - NazaraError("Failed to create context"); - return false; + delete m_context; + m_context = nullptr; + } } - m_context = context.release(); - - if (!SetActive(true)) // Les fenêtres s'activent à la création - NazaraWarning("Failed to activate window"); - - EnableVerticalSync(false); - - NzVector2ui size = GetSize(); - - // Le scissorBox/viewport (à la création) est de la taille de la fenêtre - // https://www.opengl.org/sdk/docs/man/xhtml/glGet.xml - NzOpenGL::SetScissorBox(NzRecti(0, 0, size.x, size.y)); - NzOpenGL::SetViewport(NzRecti(0, 0, size.x, size.y)); - - OnRenderTargetParametersChange(this); - OnRenderTargetSizeChange(this); - - m_clock.Restart(); - - return true; -} - -void NzRenderWindow::OnWindowDestroy() -{ - if (m_context) + void RenderWindow::OnWindowResized() { - if (IsActive()) - NzRenderer::SetTarget(nullptr); - - delete m_context; - m_context = nullptr; + OnRenderTargetSizeChange(this); } } - -void NzRenderWindow::OnWindowResized() -{ - OnRenderTargetSizeChange(this); -} diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 201a0631c..aae7b263e 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -33,2048 +33,2051 @@ #include #include -namespace +namespace Nz { - const nzUInt8 r_coreFragmentShader[] = { - #include - }; - - const nzUInt8 r_coreVertexShader[] = { - #include - }; - - const nzUInt8 r_compatibilityFragmentShader[] = { - #include - }; - - const nzUInt8 r_compatibilityVertexShader[] = { - #include - }; - - enum ObjectType + namespace { - ObjectType_Context, - ObjectType_IndexBuffer, - ObjectType_VertexBuffer, - ObjectType_VertexDeclaration - }; + const UInt8 r_coreFragmentShader[] = { + #include + }; - enum UpdateFlags - { - Update_None = 0, + const UInt8 r_coreVertexShader[] = { + #include + }; - Update_Matrices = 0x1, - Update_Shader = 0x2, - Update_Textures = 0x4, - Update_VAO = 0x8 - }; + const UInt8 r_compatibilityFragmentShader[] = { + #include + }; - struct MatrixUnit - { - NzMatrix4f matrix; - bool updated; - int location; - }; + const UInt8 r_compatibilityVertexShader[] = { + #include + }; - struct TextureUnit - { - NzTextureSampler sampler; - const NzTexture* texture = nullptr; - bool samplerUpdated = false; - }; - - struct VAO_Entry - { - GLuint vao; - - NazaraSlot(NzIndexBuffer, OnIndexBufferRelease, onIndexBufferReleaseSlot); - NazaraSlot(NzVertexBuffer, OnVertexBufferRelease, onVertexBufferReleaseSlot); - NazaraSlot(NzVertexDeclaration, OnVertexDeclarationRelease, onInstancingDeclarationReleaseSlot); - NazaraSlot(NzVertexDeclaration, OnVertexDeclarationRelease, onVertexDeclarationReleaseSlot); - }; - - using VAO_Key = std::tuple; - using VAO_Map = std::map; - - struct Context_Entry - { - VAO_Map vaoMap; - - NazaraSlot(NzContext, OnContextRelease, onReleaseSlot); - }; - - using Context_Map = std::unordered_map; - - Context_Map s_vaos; - std::vector s_dirtyTextureUnits; - std::vector s_textureUnits; - GLuint s_currentVAO = 0; - NzVertexBuffer s_instanceBuffer; - NzVertexBuffer s_fullscreenQuadBuffer; - MatrixUnit s_matrices[nzMatrixType_Max+1]; - NzRenderStates s_states; - NzVector2ui s_targetSize; - nzUInt8 s_maxAnisotropyLevel; - nzUInt32 s_updateFlags; - const NzIndexBuffer* s_indexBuffer; - const NzRenderTarget* s_target; - const NzShader* s_shader; - const NzVertexBuffer* s_vertexBuffer; - bool s_capabilities[nzRendererCap_Max+1]; - bool s_instancing; - bool s_useSamplerObjects; - bool s_useVertexArrayObjects; - unsigned int s_maxColorAttachments; - unsigned int s_maxRenderTarget; - unsigned int s_maxTextureSize; - unsigned int s_maxTextureUnit; - unsigned int s_maxVertexAttribs; -} - -void NzRenderer::BeginCondition(const NzGpuQuery& query, nzGpuQueryCondition condition) -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - #endif - - #if NAZARA_RENDERER_SAFE - if (!s_capabilities[nzRendererCap_ConditionalRendering]) - { - NazaraError("Conditional rendering is not supported"); - return; - } - #endif - - glBeginConditionalRender(query.GetOpenGLID(), NzOpenGL::QueryCondition[condition]); -} - -void NzRenderer::Clear(nzUInt32 flags) -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - #endif - - if (flags) - { - // On n'oublie pas de mettre à jour la cible - s_target->EnsureTargetUpdated(); - // Les états du rendu sont suceptibles d'influencer glClear - NzOpenGL::ApplyStates(s_states); - - GLenum mask = 0; - - if (flags & nzRendererBuffer_Color) - mask |= GL_COLOR_BUFFER_BIT; - - if (flags & nzRendererBuffer_Depth) - mask |= GL_DEPTH_BUFFER_BIT; - - if (flags & nzRendererBuffer_Stencil) - mask |= GL_STENCIL_BUFFER_BIT; - - glClear(mask); - } -} - -void NzRenderer::DrawFullscreenQuad() -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - #endif - - EnableInstancing(false); - SetIndexBuffer(nullptr); - SetVertexBuffer(&s_fullscreenQuadBuffer); - - if (!EnsureStateUpdate()) - { - NazaraError("Failed to update states: " + NzError::GetLastError()); - return; - } - - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - - if (s_useVertexArrayObjects) - glBindVertexArray(0); -} - -void NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount) -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - - if (mode > nzPrimitiveMode_Max) - { - NazaraError("Primitive mode out of enum"); - return; - } - #endif - - #if NAZARA_RENDERER_SAFE - if (!s_indexBuffer) - { - NazaraError("No index buffer"); - return; - } - #endif - - EnableInstancing(false); - - if (!EnsureStateUpdate()) - { - NazaraError("Failed to update states: " + NzError::GetLastError()); - return; - } - - GLenum type; - nzUInt8* offset = reinterpret_cast(s_indexBuffer->GetStartOffset()); - - if (s_indexBuffer->HasLargeIndices()) - { - offset += firstIndex*sizeof(nzUInt32); - type = GL_UNSIGNED_INT; - } - else - { - offset += firstIndex*sizeof(nzUInt16); - type = GL_UNSIGNED_SHORT; - } - - glDrawElements(NzOpenGL::PrimitiveMode[mode], indexCount, type, offset); - - if (s_useVertexArrayObjects) - glBindVertexArray(0); -} - -void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount) -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - - if (mode > nzPrimitiveMode_Max) - { - NazaraError("Primitive mode out of enum"); - return; - } - #endif - - #if NAZARA_RENDERER_SAFE - if (!s_capabilities[nzRendererCap_Instancing]) - { - NazaraError("Instancing not supported"); - return; - } - - if (!s_indexBuffer) - { - NazaraError("No index buffer"); - return; - } - - if (instanceCount == 0) - { - NazaraError("Instance count must be over zero"); - return; - } - - unsigned int maxInstanceCount = s_instanceBuffer.GetVertexCount(); - if (instanceCount > maxInstanceCount) - { - NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")" ); - return; - } - #endif - - EnableInstancing(true); - - if (!EnsureStateUpdate()) - { - NazaraError("Failed to update states: " + NzError::GetLastError()); - return; - } - - GLenum type; - nzUInt8* offset = reinterpret_cast(s_indexBuffer->GetStartOffset()); - - if (s_indexBuffer->HasLargeIndices()) - { - offset += firstIndex*sizeof(nzUInt32); - type = GL_UNSIGNED_INT; - } - else - { - offset += firstIndex*sizeof(nzUInt16); - type = GL_UNSIGNED_SHORT; - } - - glDrawElementsInstanced(NzOpenGL::PrimitiveMode[mode], indexCount, type, offset, instanceCount); - - if (s_useVertexArrayObjects) - glBindVertexArray(0); -} - -void NzRenderer::DrawPrimitives(nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount) -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - - if (mode > nzPrimitiveMode_Max) - { - NazaraError("Primitive mode out of enum"); - return; - } - #endif - - EnableInstancing(false); - - if (!EnsureStateUpdate()) - { - NazaraError("Failed to update states: " + NzError::GetLastError()); - return; - } - - glDrawArrays(NzOpenGL::PrimitiveMode[mode], firstVertex, vertexCount); - - if (s_useVertexArrayObjects) - glBindVertexArray(0); -} - -void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount) -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - - if (mode > nzPrimitiveMode_Max) - { - NazaraError("Primitive mode out of enum"); - return; - } - #endif - - #if NAZARA_RENDERER_SAFE - if (!s_capabilities[nzRendererCap_Instancing]) - { - NazaraError("Instancing not supported"); - return; - } - - if (instanceCount == 0) - { - NazaraError("Instance count must be over zero"); - return; - } - - unsigned int maxInstanceCount = s_instanceBuffer.GetVertexCount(); - if (instanceCount > maxInstanceCount) - { - NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")" ); - return; - } - #endif - - EnableInstancing(true); - - if (!EnsureStateUpdate()) - { - NazaraError("Failed to update states: " + NzError::GetLastError()); - return; - } - - glDrawArraysInstanced(NzOpenGL::PrimitiveMode[mode], firstVertex, vertexCount, instanceCount); - - if (s_useVertexArrayObjects) - glBindVertexArray(0); -} - -void NzRenderer::Enable(nzRendererParameter parameter, bool enable) -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - - if (parameter > nzRendererParameter_Max) - { - NazaraError("Renderer parameter out of enum"); - return; - } - #endif - - s_states.parameters[parameter] = enable; -} - -void NzRenderer::EndCondition() -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - #endif - - #if NAZARA_RENDERER_SAFE - if (!s_capabilities[nzRendererCap_ConditionalRendering]) - { - NazaraError("Conditional rendering is not supported"); - return; - } - #endif - - glEndConditionalRender(); -} - -void NzRenderer::Flush() -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - #endif - - glFlush(); -} - -nzRendererComparison NzRenderer::GetDepthFunc() -{ - return s_states.depthFunc; -} - -NzVertexBuffer* NzRenderer::GetInstanceBuffer() -{ - #if NAZARA_RENDERER_SAFE - if (!s_capabilities[nzRendererCap_Instancing]) - { - NazaraError("Instancing not supported"); - return nullptr; - } - #endif - - s_updateFlags |= Update_VAO; - return &s_instanceBuffer; -} - -float NzRenderer::GetLineWidth() -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return 0.f; - } - #endif - - return s_states.lineWidth; -} - -NzMatrix4f NzRenderer::GetMatrix(nzMatrixType type) -{ - #ifdef NAZARA_DEBUG - if (type > nzMatrixType_Max) - { - NazaraError("Matrix type out of enum"); - return NzMatrix4f(); - } - #endif - - if (!s_matrices[type].updated) - UpdateMatrix(type); - - return s_matrices[type].matrix; -} - -nzUInt8 NzRenderer::GetMaxAnisotropyLevel() -{ - return s_maxAnisotropyLevel; -} - -unsigned int NzRenderer::GetMaxColorAttachments() -{ - return s_maxColorAttachments; -} - -unsigned int NzRenderer::GetMaxRenderTargets() -{ - return s_maxRenderTarget; -} - -unsigned int NzRenderer::GetMaxTextureSize() -{ - return s_maxTextureSize; -} - -unsigned int NzRenderer::GetMaxTextureUnits() -{ - return s_maxTextureUnit; -} - -unsigned int NzRenderer::GetMaxVertexAttribs() -{ - return s_maxVertexAttribs; -} - -float NzRenderer::GetPointSize() -{ - return s_states.pointSize; -} - -const NzRenderStates& NzRenderer::GetRenderStates() -{ - return s_states; -} - -NzRecti NzRenderer::GetScissorRect() -{ - return NzOpenGL::GetCurrentScissorBox(); -} - -const NzShader* NzRenderer::GetShader() -{ - return s_shader; -} - -const NzRenderTarget* NzRenderer::GetTarget() -{ - return s_target; -} - -NzRecti NzRenderer::GetViewport() -{ - return NzOpenGL::GetCurrentViewport(); -} - -bool NzRenderer::HasCapability(nzRendererCap capability) -{ - #ifdef NAZARA_DEBUG - if (capability > nzRendererCap_Max) - { - NazaraError("Renderer capability out of enum"); - return false; - } - #endif - - return s_capabilities[capability]; -} - -bool NzRenderer::Initialize() -{ - if (s_moduleReferenceCounter > 0) - { - s_moduleReferenceCounter++; - return true; // Déjà initialisé - } - - // Initialisation des dépendances - if (!NzUtility::Initialize()) - { - NazaraError("Failed to initialize Utility module"); - return false; - } - - s_moduleReferenceCounter++; - - // Initialisation du module - NzCallOnExit onExit(NzRenderer::Uninitialize); - - // Initialisation d'OpenGL - if (!NzOpenGL::Initialize()) // Initialise également Context - { - NazaraError("Failed to initialize OpenGL"); - return false; - } - - NzBuffer::SetBufferFactory(nzDataStorage_Hardware, [](NzBuffer* parent, nzBufferType type) -> NzAbstractBuffer* - { - return new NzHardwareBuffer(parent, type); - }); - - for (unsigned int i = 0; i <= nzMatrixType_Max; ++i) - { - MatrixUnit& unit = s_matrices[i]; - unit.location = -1; - unit.matrix.MakeIdentity(); - unit.updated = true; - } - - // Récupération des capacités d'OpenGL - s_capabilities[nzRendererCap_AnisotropicFilter] = NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter); - s_capabilities[nzRendererCap_ConditionalRendering] = NzOpenGL::IsSupported(nzOpenGLExtension_ConditionalRender); - s_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(nzOpenGLExtension_FP64); - s_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5 - s_capabilities[nzRendererCap_Instancing] = NzOpenGL::IsSupported(nzOpenGLExtension_DrawInstanced) && NzOpenGL::IsSupported(nzOpenGLExtension_InstancedArray); - s_capabilities[nzRendererCap_MultipleRenderTargets] = (glBindFragDataLocation != nullptr); // Natif depuis OpenGL 2.0 mais inutile sans glBindFragDataLocation - s_capabilities[nzRendererCap_OcclusionQuery] = true; // Natif depuis OpenGL 1.5 - s_capabilities[nzRendererCap_PixelBufferObject] = NzOpenGL::IsSupported(nzOpenGLExtension_PixelBufferObject); - s_capabilities[nzRendererCap_RenderTexture] = NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject); - s_capabilities[nzRendererCap_Texture3D] = true; // Natif depuis OpenGL 1.2 - s_capabilities[nzRendererCap_TextureCubemap] = true; // Natif depuis OpenGL 1.3 - s_capabilities[nzRendererCap_TextureMulti] = true; // Natif depuis OpenGL 1.3 - s_capabilities[nzRendererCap_TextureNPOT] = true; // Natif depuis OpenGL 2.0 - - NzContext::EnsureContext(); - - if (s_capabilities[nzRendererCap_AnisotropicFilter]) - { - GLfloat maxAnisotropy; - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); - - s_maxAnisotropyLevel = static_cast(maxAnisotropy); - } - else - s_maxAnisotropyLevel = 1; - - if (s_capabilities[nzRendererCap_RenderTexture]) - { - GLint maxColorAttachments; - glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments); - - s_maxColorAttachments = static_cast(maxColorAttachments); - } - else - s_maxColorAttachments = 1; - - if (s_capabilities[nzRendererCap_MultipleRenderTargets]) - { - GLint maxDrawBuffers; - glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); - - s_maxRenderTarget = static_cast(maxDrawBuffers); - } - else - s_maxRenderTarget = 1; - - if (s_capabilities[nzRendererCap_TextureMulti]) - { - GLint maxTextureUnits; - glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits); - - s_maxTextureUnit = static_cast(maxTextureUnits); - } - else - s_maxTextureUnit = 1; - - GLint maxTextureSize; - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); - s_maxTextureSize = maxTextureSize; - - GLint maxVertexAttribs; - glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); - s_maxVertexAttribs = static_cast(maxVertexAttribs); - - s_states = NzRenderStates(); - - s_indexBuffer = nullptr; - s_shader = nullptr; - s_target = nullptr; - s_targetSize.Set(0U); - s_textureUnits.resize(s_maxTextureUnit); - s_useSamplerObjects = NzOpenGL::IsSupported(nzOpenGLExtension_SamplerObjects); - s_useVertexArrayObjects = NzOpenGL::IsSupported(nzOpenGLExtension_VertexArrayObjects); - s_updateFlags = Update_Matrices | Update_Shader | Update_VAO; - s_vertexBuffer = nullptr; - - s_fullscreenQuadBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzDataStorage_Hardware, nzBufferUsage_Static); - - float vertices[4*2] = - { - -1.f, -1.f, - 1.f, -1.f, - -1.f, 1.f, - 1.f, 1.f, - }; - - if (!s_fullscreenQuadBuffer.Fill(vertices, 0, 4)) - { - NazaraError("Failed to fill fullscreen quad buffer"); - return false; - } - - if (s_capabilities[nzRendererCap_Instancing]) - { - try + enum ObjectType { - NzErrorFlags errFlags(nzErrorFlag_ThrowException, true); - s_instanceBuffer.Reset(nullptr, NAZARA_RENDERER_INSTANCE_BUFFER_SIZE, nzDataStorage_Hardware, nzBufferUsage_Dynamic); - } - catch (const std::exception& e) + ObjectType_Context, + ObjectType_IndexBuffer, + ObjectType_VertexBuffer, + ObjectType_VertexDeclaration + }; + + enum UpdateFlags { - s_capabilities[nzRendererCap_Instancing] = false; + Update_None = 0, - NzErrorFlags flags(nzErrorFlag_ThrowExceptionDisabled); - NazaraError("Failed to create instancing buffer: " + NzString(e.what())); - } - } + Update_Matrices = 0x1, + Update_Shader = 0x2, + Update_Textures = 0x4, + Update_VAO = 0x8 + }; - if (!NzRenderBuffer::Initialize()) - { - NazaraError("Failed to initialize render buffers"); - return false; - } - - if (!NzShader::Initialize()) - { - NazaraError("Failed to initialize shaders"); - return false; - } - - if (!NzTexture::Initialize()) - { - NazaraError("Failed to initialize textures"); - return false; - } - - if (!NzTextureSampler::Initialize()) - { - NazaraError("Failed to initialize texture samplers"); - return false; - } - - if (!NzUberShader::Initialize()) - { - NazaraError("Failed to initialize uber shaders"); - return false; - } - - // Création du shader de Debug - NzShaderRef debugShader = NzShader::New(); - if (!debugShader->Create()) - { - NazaraError("Failed to create debug shader"); - return false; - } - - const char* fragmentShader; - const char* vertexShader; - unsigned int fragmentShaderLength; - unsigned int vertexShaderLength; - if (NzOpenGL::GetGLSLVersion() >= 140) - { - fragmentShader = reinterpret_cast(r_coreFragmentShader); - fragmentShaderLength = sizeof(r_coreFragmentShader); - vertexShader = reinterpret_cast(r_coreVertexShader); - vertexShaderLength = sizeof(r_coreVertexShader); - } - else - { - fragmentShader = reinterpret_cast(r_compatibilityFragmentShader); - fragmentShaderLength = sizeof(r_compatibilityFragmentShader); - vertexShader = reinterpret_cast(r_compatibilityVertexShader); - vertexShaderLength = sizeof(r_compatibilityVertexShader); - } - - if (!debugShader->AttachStageFromSource(nzShaderStage_Fragment, fragmentShader, fragmentShaderLength)) - { - NazaraError("Failed to attach fragment stage"); - return false; - } - - if (!debugShader->AttachStageFromSource(nzShaderStage_Vertex, vertexShader, vertexShaderLength)) - { - NazaraError("Failed to attach vertex stage"); - return false; - } - - if (!debugShader->Link()) - { - NazaraError("Failed to link shader"); - return false; - } - - NzShaderLibrary::Register("DebugSimple", debugShader); - - onExit.Reset(); - - NazaraNotice("Initialized: Renderer module"); - return true; -} - -bool NzRenderer::IsComponentTypeSupported(nzComponentType type) -{ - switch (type) - { - case nzComponentType_Color: - case nzComponentType_Float1: - case nzComponentType_Float2: - case nzComponentType_Float3: - case nzComponentType_Float4: - return true; // Supportés nativement - - case nzComponentType_Double1: - case nzComponentType_Double2: - case nzComponentType_Double3: - case nzComponentType_Double4: - return glVertexAttribLPointer != nullptr; // Fonction requise pour envoyer des doubles - - case nzComponentType_Int1: - case nzComponentType_Int2: - case nzComponentType_Int3: - case nzComponentType_Int4: - return glVertexAttribIPointer != nullptr; // Fonction requise pour envoyer des entiers - - case nzComponentType_Quaternion: - return false; - } - - NazaraError("Attribute type not handled (0x" + NzString::Number(type, 16) + ')'); - return false; -} - -bool NzRenderer::IsEnabled(nzRendererParameter parameter) -{ - #ifdef NAZARA_DEBUG - if (parameter > nzRendererParameter_Max) - { - NazaraError("Renderer parameter out of enum"); - return false; - } - #endif - - return s_states.parameters[parameter]; -} - -bool NzRenderer::IsInitialized() -{ - return s_moduleReferenceCounter != 0; -} - -void NzRenderer::SetBlendFunc(nzBlendFunc srcBlend, nzBlendFunc dstBlend) -{ - #ifdef NAZARA_DEBUG - if (srcBlend > nzBlendFunc_Max) - { - NazaraError("Blend func out of enum"); - return; - } - - if (dstBlend > nzBlendFunc_Max) - { - NazaraError("Blend func out of enum"); - return; - } - #endif - - s_states.srcBlend = srcBlend; - s_states.dstBlend = dstBlend; -} - -void NzRenderer::SetClearColor(const NzColor& color) -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - #endif - - glClearColor(color.r/255.f, color.g/255.f, color.b/255.f, color.a/255.f); -} - -void NzRenderer::SetClearColor(nzUInt8 r, nzUInt8 g, nzUInt8 b, nzUInt8 a) -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - #endif - - glClearColor(r/255.f, g/255.f, b/255.f, a/255.f); -} - -void NzRenderer::SetClearDepth(double depth) -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - #endif - - glClearDepth(depth); -} - -void NzRenderer::SetClearStencil(unsigned int value) -{ - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return; - } - #endif - - glClearStencil(value); -} - -void NzRenderer::SetDepthFunc(nzRendererComparison compareFunc) -{ - #ifdef NAZARA_DEBUG - if (compareFunc > nzRendererComparison_Max) - { - NazaraError("Renderer comparison out of enum"); - return; - } - #endif - - s_states.depthFunc = compareFunc; -} - -void NzRenderer::SetFaceCulling(nzFaceSide faceSide) -{ - #ifdef NAZARA_DEBUG - if (faceSide > nzFaceSide_Max) - { - NazaraError("Face side out of enum"); - return; - } - #endif - - s_states.faceCulling = faceSide; -} - -void NzRenderer::SetFaceFilling(nzFaceFilling fillingMode) -{ - #ifdef NAZARA_DEBUG - if (fillingMode > nzFaceFilling_Max) - { - NazaraError("Face filling out of enum"); - return; - } - #endif - - s_states.faceFilling = fillingMode; -} - -void NzRenderer::SetIndexBuffer(const NzIndexBuffer* indexBuffer) -{ - #if NAZARA_RENDERER_SAFE - if (indexBuffer && !indexBuffer->IsHardware()) - { - NazaraError("Buffer must be hardware"); - return; - } - #endif - - if (s_indexBuffer != indexBuffer) - { - s_indexBuffer = indexBuffer; - s_updateFlags |= Update_VAO; - } -} - -void NzRenderer::SetLineWidth(float width) -{ - #if NAZARA_RENDERER_SAFE - if (width <= 0.f) - { - NazaraError("Width must be over zero"); - return; - } - #endif - - s_states.lineWidth = width; -} - -void NzRenderer::SetMatrix(nzMatrixType type, const NzMatrix4f& matrix) -{ - #ifdef NAZARA_DEBUG - if (type > nzMatrixType_Max) - { - NazaraError("Matrix type out of enum"); - return; - } - #endif - - s_matrices[type].matrix = matrix; - s_matrices[type].updated = true; - - // Invalidation des combinaisons - switch (type) - { - // Matrices de base - case nzMatrixType_Projection: - s_matrices[nzMatrixType_InvProjection].updated = false; - s_matrices[nzMatrixType_InvViewProj].updated = false; - s_matrices[nzMatrixType_InvWorldViewProj].updated = false; - s_matrices[nzMatrixType_ViewProj].updated = false; - s_matrices[nzMatrixType_WorldViewProj].updated = false; - break; - - case nzMatrixType_View: - s_matrices[nzMatrixType_InvView].updated = false; - s_matrices[nzMatrixType_InvViewProj].updated = false; - s_matrices[nzMatrixType_InvWorld].updated = false; - s_matrices[nzMatrixType_InvWorldViewProj].updated = false; - s_matrices[nzMatrixType_ViewProj].updated = false; - s_matrices[nzMatrixType_World].updated = false; - s_matrices[nzMatrixType_WorldViewProj].updated = false; - break; - - case nzMatrixType_World: - s_matrices[nzMatrixType_InvWorld].updated = false; - s_matrices[nzMatrixType_InvWorldView].updated = false; - s_matrices[nzMatrixType_InvWorldViewProj].updated = false; - s_matrices[nzMatrixType_WorldView].updated = false; - s_matrices[nzMatrixType_WorldViewProj].updated = false; - break; - - // Matrices combinées - case nzMatrixType_ViewProj: - s_matrices[nzMatrixType_InvViewProj].updated = false; - break; - - case nzMatrixType_WorldView: - s_matrices[nzMatrixType_InvWorldView].updated = false; - s_matrices[nzMatrixType_WorldViewProj].updated = false; - break; - - case nzMatrixType_WorldViewProj: - s_matrices[nzMatrixType_InvWorldViewProj].updated = false; - break; - - case nzMatrixType_InvProjection: - case nzMatrixType_InvView: - case nzMatrixType_InvViewProj: - case nzMatrixType_InvWorld: - case nzMatrixType_InvWorldView: - case nzMatrixType_InvWorldViewProj: - break; - } - - s_updateFlags |= Update_Matrices; -} - -void NzRenderer::SetPointSize(float size) -{ - #if NAZARA_RENDERER_SAFE - if (size <= 0.f) - { - NazaraError("Size must be over zero"); - return; - } - #endif - - s_states.pointSize = size; -} - -void NzRenderer::SetRenderStates(const NzRenderStates& states) -{ - s_states = states; -} - -void NzRenderer::SetScissorRect(const NzRecti& rect) -{ - NzOpenGL::BindScissorBox(rect); -} - -void NzRenderer::SetShader(const NzShader* shader) -{ - #if NAZARA_RENDERER_SAFE - if (shader) - { - if (!shader->IsValid() || !shader->IsLinked()) + struct MatrixUnit { - NazaraError("Invalid shader"); + Matrix4f matrix; + bool updated; + int location; + }; + + struct TextureUnit + { + TextureSampler sampler; + const Texture* texture = nullptr; + bool samplerUpdated = false; + }; + + struct VAO_Entry + { + GLuint vao; + + NazaraSlot(IndexBuffer, OnIndexBufferRelease, onIndexBufferReleaseSlot); + NazaraSlot(VertexBuffer, OnVertexBufferRelease, onVertexBufferReleaseSlot); + NazaraSlot(VertexDeclaration, OnVertexDeclarationRelease, onInstancingDeclarationReleaseSlot); + NazaraSlot(VertexDeclaration, OnVertexDeclarationRelease, onVertexDeclarationReleaseSlot); + }; + + using VAO_Key = std::tuple; + using VAO_Map = std::map; + + struct Context_Entry + { + VAO_Map vaoMap; + + NazaraSlot(Context, OnContextRelease, onReleaseSlot); + }; + + using Context_Map = std::unordered_map; + + Context_Map s_vaos; + std::vector s_dirtyTextureUnits; + std::vector s_textureUnits; + GLuint s_currentVAO = 0; + VertexBuffer s_instanceBuffer; + VertexBuffer s_fullscreenQuadBuffer; + MatrixUnit s_matrices[MatrixType_Max+1]; + RenderStates s_states; + Vector2ui s_targetSize; + UInt8 s_maxAnisotropyLevel; + UInt32 s_updateFlags; + const IndexBuffer* s_indexBuffer; + const RenderTarget* s_target; + const Shader* s_shader; + const VertexBuffer* s_vertexBuffer; + bool s_capabilities[RendererCap_Max+1]; + bool s_instancing; + bool s_useSamplerObjects; + bool s_useVertexArrayObjects; + unsigned int s_maxColorAttachments; + unsigned int s_maxRenderTarget; + unsigned int s_maxTextureSize; + unsigned int s_maxTextureUnit; + unsigned int s_maxVertexAttribs; + } + + void Renderer::BeginCondition(const GpuQuery& query, GpuQueryCondition condition) + { + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); return; } - } - #endif + #endif - if (s_shader != shader) + #if NAZARA_RENDERER_SAFE + if (!s_capabilities[RendererCap_ConditionalRendering]) + { + NazaraError("Conditional rendering is not supported"); + return; + } + #endif + + glBeginConditionalRender(query.GetOpenGLID(), OpenGL::QueryCondition[condition]); + } + + void Renderer::Clear(UInt32 flags) { - s_shader = shader; - s_updateFlags |= Update_Shader; - } -} + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } + #endif -void NzRenderer::SetStencilCompareFunction(nzRendererComparison compareFunc, nzFaceSide faceSide) -{ - #ifdef NAZARA_DEBUG - if (compareFunc > nzRendererComparison_Max) + if (flags) + { + // On n'oublie pas de mettre à jour la cible + s_target->EnsureTargetUpdated(); + // Les états du rendu sont suceptibles d'influencer glClear + OpenGL::ApplyStates(s_states); + + GLenum mask = 0; + + if (flags & RendererBuffer_Color) + mask |= GL_COLOR_BUFFER_BIT; + + if (flags & RendererBuffer_Depth) + mask |= GL_DEPTH_BUFFER_BIT; + + if (flags & RendererBuffer_Stencil) + mask |= GL_STENCIL_BUFFER_BIT; + + glClear(mask); + } + } + + void Renderer::DrawFullscreenQuad() { - NazaraError("Renderer comparison out of enum"); - return; + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } + #endif + + EnableInstancing(false); + SetIndexBuffer(nullptr); + SetVertexBuffer(&s_fullscreenQuadBuffer); + + if (!EnsureStateUpdate()) + { + NazaraError("Failed to update states: " + Error::GetLastError()); + return; + } + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + if (s_useVertexArrayObjects) + glBindVertexArray(0); } - if (faceSide > nzFaceSide_Max) + void Renderer::DrawIndexedPrimitives(PrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount) { - NazaraError("Face side out of enum"); - return; - } - #endif + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } - switch (faceSide) + if (mode > PrimitiveMode_Max) + { + NazaraError("Primitive mode out of enum"); + return; + } + #endif + + #if NAZARA_RENDERER_SAFE + if (!s_indexBuffer) + { + NazaraError("No index buffer"); + return; + } + #endif + + EnableInstancing(false); + + if (!EnsureStateUpdate()) + { + NazaraError("Failed to update states: " + Error::GetLastError()); + return; + } + + GLenum type; + UInt8* offset = reinterpret_cast(s_indexBuffer->GetStartOffset()); + + if (s_indexBuffer->HasLargeIndices()) + { + offset += firstIndex*sizeof(UInt32); + type = GL_UNSIGNED_INT; + } + else + { + offset += firstIndex*sizeof(UInt16); + type = GL_UNSIGNED_SHORT; + } + + glDrawElements(OpenGL::PrimitiveMode[mode], indexCount, type, offset); + + if (s_useVertexArrayObjects) + glBindVertexArray(0); + } + + void Renderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, PrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount) { - case nzFaceSide_Back: - s_states.backFace.stencilCompare = compareFunc; - break; + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } - case nzFaceSide_Front: - s_states.frontFace.stencilCompare = compareFunc; - break; + if (mode > PrimitiveMode_Max) + { + NazaraError("Primitive mode out of enum"); + return; + } + #endif - case nzFaceSide_FrontAndBack: - s_states.backFace.stencilCompare = compareFunc; - s_states.frontFace.stencilCompare = compareFunc; - break; + #if NAZARA_RENDERER_SAFE + if (!s_capabilities[RendererCap_Instancing]) + { + NazaraError("Instancing not supported"); + return; + } + + if (!s_indexBuffer) + { + NazaraError("No index buffer"); + return; + } + + if (instanceCount == 0) + { + NazaraError("Instance count must be over zero"); + return; + } + + unsigned int maxInstanceCount = s_instanceBuffer.GetVertexCount(); + if (instanceCount > maxInstanceCount) + { + NazaraError("Instance count is over maximum instance count (" + String::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")" ); + return; + } + #endif + + EnableInstancing(true); + + if (!EnsureStateUpdate()) + { + NazaraError("Failed to update states: " + Error::GetLastError()); + return; + } + + GLenum type; + UInt8* offset = reinterpret_cast(s_indexBuffer->GetStartOffset()); + + if (s_indexBuffer->HasLargeIndices()) + { + offset += firstIndex*sizeof(UInt32); + type = GL_UNSIGNED_INT; + } + else + { + offset += firstIndex*sizeof(UInt16); + type = GL_UNSIGNED_SHORT; + } + + glDrawElementsInstanced(OpenGL::PrimitiveMode[mode], indexCount, type, offset, instanceCount); + + if (s_useVertexArrayObjects) + glBindVertexArray(0); } -} -void NzRenderer::SetStencilFailOperation(nzStencilOperation failOperation, nzFaceSide faceSide) -{ - #ifdef NAZARA_DEBUG - if (failOperation > nzStencilOperation_Max) + void Renderer::DrawPrimitives(PrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount) { - NazaraError("Stencil fail operation out of enum"); - return; + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } + + if (mode > PrimitiveMode_Max) + { + NazaraError("Primitive mode out of enum"); + return; + } + #endif + + EnableInstancing(false); + + if (!EnsureStateUpdate()) + { + NazaraError("Failed to update states: " + Error::GetLastError()); + return; + } + + glDrawArrays(OpenGL::PrimitiveMode[mode], firstVertex, vertexCount); + + if (s_useVertexArrayObjects) + glBindVertexArray(0); } - if (faceSide > nzFaceSide_Max) + void Renderer::DrawPrimitivesInstanced(unsigned int instanceCount, PrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount) { - NazaraError("Face side out of enum"); - return; - } - #endif + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } - switch (faceSide) + if (mode > PrimitiveMode_Max) + { + NazaraError("Primitive mode out of enum"); + return; + } + #endif + + #if NAZARA_RENDERER_SAFE + if (!s_capabilities[RendererCap_Instancing]) + { + NazaraError("Instancing not supported"); + return; + } + + if (instanceCount == 0) + { + NazaraError("Instance count must be over zero"); + return; + } + + unsigned int maxInstanceCount = s_instanceBuffer.GetVertexCount(); + if (instanceCount > maxInstanceCount) + { + NazaraError("Instance count is over maximum instance count (" + String::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")" ); + return; + } + #endif + + EnableInstancing(true); + + if (!EnsureStateUpdate()) + { + NazaraError("Failed to update states: " + Error::GetLastError()); + return; + } + + glDrawArraysInstanced(OpenGL::PrimitiveMode[mode], firstVertex, vertexCount, instanceCount); + + if (s_useVertexArrayObjects) + glBindVertexArray(0); + } + + void Renderer::Enable(RendererParameter parameter, bool enable) { - case nzFaceSide_Back: - s_states.backFace.stencilFail = failOperation; - break; + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } - case nzFaceSide_Front: - s_states.frontFace.stencilFail = failOperation; - break; + if (parameter > RendererParameter_Max) + { + NazaraError("Renderer parameter out of enum"); + return; + } + #endif - case nzFaceSide_FrontAndBack: - s_states.backFace.stencilFail = failOperation; - s_states.frontFace.stencilFail = failOperation; - break; + s_states.parameters[parameter] = enable; } -} -void NzRenderer::SetStencilMask(nzUInt32 mask, nzFaceSide faceSide) -{ - #ifdef NAZARA_DEBUG - if (faceSide > nzFaceSide_Max) + void Renderer::EndCondition() { - NazaraError("Face side out of enum"); - return; - } - #endif + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } + #endif - switch (faceSide) + #if NAZARA_RENDERER_SAFE + if (!s_capabilities[RendererCap_ConditionalRendering]) + { + NazaraError("Conditional rendering is not supported"); + return; + } + #endif + + glEndConditionalRender(); + } + + void Renderer::Flush() { - case nzFaceSide_Back: - s_states.backFace.stencilMask = mask; - break; + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } + #endif - case nzFaceSide_Front: - s_states.frontFace.stencilMask = mask; - break; - - case nzFaceSide_FrontAndBack: - s_states.backFace.stencilMask = mask; - s_states.frontFace.stencilMask = mask; - break; + glFlush(); } -} -void NzRenderer::SetStencilPassOperation(nzStencilOperation passOperation, nzFaceSide faceSide) -{ - #ifdef NAZARA_DEBUG - if (passOperation > nzStencilOperation_Max) + RendererComparison Renderer::GetDepthFunc() { - NazaraError("Stencil pass operation out of enum"); - return; + return s_states.depthFunc; } - if (faceSide > nzFaceSide_Max) - { - NazaraError("Face side out of enum"); - return; - } - #endif - - switch (faceSide) - { - case nzFaceSide_Back: - s_states.backFace.stencilPass = passOperation; - break; - - case nzFaceSide_Front: - s_states.frontFace.stencilPass = passOperation; - break; - - case nzFaceSide_FrontAndBack: - s_states.backFace.stencilPass = passOperation; - s_states.frontFace.stencilPass = passOperation; - break; - } -} - -void NzRenderer::SetStencilReferenceValue(unsigned int refValue, nzFaceSide faceSide) -{ - #ifdef NAZARA_DEBUG - if (faceSide > nzFaceSide_Max) - { - NazaraError("Face side out of enum"); - return; - } - #endif - - switch (faceSide) - { - case nzFaceSide_Back: - s_states.backFace.stencilReference = refValue; - break; - - case nzFaceSide_Front: - s_states.frontFace.stencilReference = refValue; - break; - - case nzFaceSide_FrontAndBack: - s_states.backFace.stencilReference = refValue; - s_states.frontFace.stencilReference = refValue; - break; - } -} - -void NzRenderer::SetStencilZFailOperation(nzStencilOperation zfailOperation, nzFaceSide faceSide) -{ - #ifdef NAZARA_DEBUG - if (zfailOperation > nzStencilOperation_Max) - { - NazaraError("Stencil pass operation out of enum"); - return; - } - - if (faceSide > nzFaceSide_Max) - { - NazaraError("Face side out of enum"); - return; - } - #endif - - switch (faceSide) - { - case nzFaceSide_Back: - s_states.backFace.stencilZFail = zfailOperation; - break; - - case nzFaceSide_Front: - s_states.frontFace.stencilZFail = zfailOperation; - break; - - case nzFaceSide_FrontAndBack: - s_states.backFace.stencilZFail = zfailOperation; - s_states.frontFace.stencilZFail = zfailOperation; - break; - } -} - -bool NzRenderer::SetTarget(const NzRenderTarget* target) -{ - if (s_target == target) - return true; - - if (s_target) - { - if (!s_target->HasContext()) - s_target->Desactivate(); - - s_target = nullptr; - } - - if (target) + VertexBuffer* Renderer::GetInstanceBuffer() { #if NAZARA_RENDERER_SAFE - if (!target->IsRenderable()) + if (!s_capabilities[RendererCap_Instancing]) { - NazaraError("Target not renderable"); + NazaraError("Instancing not supported"); + return nullptr; + } + #endif + + s_updateFlags |= Update_VAO; + return &s_instanceBuffer; + } + + float Renderer::GetLineWidth() + { + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return 0.f; + } + #endif + + return s_states.lineWidth; + } + + Matrix4f Renderer::GetMatrix(MatrixType type) + { + #ifdef NAZARA_DEBUG + if (type > MatrixType_Max) + { + NazaraError("Matrix type out of enum"); + return Matrix4f(); + } + #endif + + if (!s_matrices[type].updated) + UpdateMatrix(type); + + return s_matrices[type].matrix; + } + + UInt8 Renderer::GetMaxAnisotropyLevel() + { + return s_maxAnisotropyLevel; + } + + unsigned int Renderer::GetMaxColorAttachments() + { + return s_maxColorAttachments; + } + + unsigned int Renderer::GetMaxRenderTargets() + { + return s_maxRenderTarget; + } + + unsigned int Renderer::GetMaxTextureSize() + { + return s_maxTextureSize; + } + + unsigned int Renderer::GetMaxTextureUnits() + { + return s_maxTextureUnit; + } + + unsigned int Renderer::GetMaxVertexAttribs() + { + return s_maxVertexAttribs; + } + + float Renderer::GetPointSize() + { + return s_states.pointSize; + } + + const RenderStates& Renderer::GetRenderStates() + { + return s_states; + } + + Recti Renderer::GetScissorRect() + { + return OpenGL::GetCurrentScissorBox(); + } + + const Shader* Renderer::GetShader() + { + return s_shader; + } + + const RenderTarget* Renderer::GetTarget() + { + return s_target; + } + + Recti Renderer::GetViewport() + { + return OpenGL::GetCurrentViewport(); + } + + bool Renderer::HasCapability(RendererCap capability) + { + #ifdef NAZARA_DEBUG + if (capability > RendererCap_Max) + { + NazaraError("Renderer capability out of enum"); return false; } #endif - if (!target->Activate()) + return s_capabilities[capability]; + } + + bool Renderer::Initialize() + { + if (s_moduleReferenceCounter > 0) { - NazaraError("Failed to activate target"); + s_moduleReferenceCounter++; + return true; // Déjà initialisé + } + + // Initialisation des dépendances + if (!Utility::Initialize()) + { + NazaraError("Failed to initialize Utility module"); return false; } - s_target = target; - } + s_moduleReferenceCounter++; - NzOpenGL::SetTarget(s_target); + // Initialisation du module + CallOnExit onExit(Renderer::Uninitialize); - return true; -} - -void NzRenderer::SetTexture(nzUInt8 unit, const NzTexture* texture) -{ - #if NAZARA_RENDERER_SAFE - if (unit >= s_maxTextureUnit) - { - NazaraError("Texture unit out of range (" + NzString::Number(unit) + " >= " + NzString::Number(s_maxTextureUnit) + ')'); - return; - } - #endif - - if (s_textureUnits[unit].texture != texture) - { - s_textureUnits[unit].texture = texture; - - if (texture) + // Initialisation d'OpenGL + if (!OpenGL::Initialize()) // Initialise également Context { - if (s_textureUnits[unit].sampler.UseMipmaps(texture->HasMipmaps())) - s_textureUnits[unit].samplerUpdated = false; + NazaraError("Failed to initialize OpenGL"); + return false; } - s_dirtyTextureUnits.push_back(unit); - s_updateFlags |= Update_Textures; - } -} - -void NzRenderer::SetTextureSampler(nzUInt8 unit, const NzTextureSampler& sampler) -{ - #if NAZARA_RENDERER_SAFE - if (unit >= s_maxTextureUnit) - { - NazaraError("Texture unit out of range (" + NzString::Number(unit) + " >= " + NzString::Number(s_maxTextureUnit) + ')'); - return; - } - #endif - - s_textureUnits[unit].sampler = sampler; - s_textureUnits[unit].samplerUpdated = false; - - if (s_textureUnits[unit].texture) - s_textureUnits[unit].sampler.UseMipmaps(s_textureUnits[unit].texture->HasMipmaps()); - - s_dirtyTextureUnits.push_back(unit); - s_updateFlags |= Update_Textures; -} - -void NzRenderer::SetVertexBuffer(const NzVertexBuffer* vertexBuffer) -{ - #if NAZARA_RENDERER_SAFE - if (vertexBuffer && !vertexBuffer->IsHardware()) - { - NazaraError("Buffer must be hardware"); - return; - } - #endif - - if (vertexBuffer && s_vertexBuffer != vertexBuffer) - { - s_vertexBuffer = vertexBuffer; - s_updateFlags |= Update_VAO; - } -} - -void NzRenderer::SetViewport(const NzRecti& viewport) -{ - NzOpenGL::BindViewport(viewport); -} - -void NzRenderer::Uninitialize() -{ - if (s_moduleReferenceCounter != 1) - { - // Le module est soit encore utilisé, soit pas initialisé - if (s_moduleReferenceCounter > 1) - s_moduleReferenceCounter--; - - return; - } - - // Libération du module - s_moduleReferenceCounter = 0; - - NzShaderLibrary::Unregister("DebugSimple"); - - NzUberShader::Uninitialize(); - NzTextureSampler::Uninitialize(); - NzTexture::Uninitialize(); - NzShader::Uninitialize(); - NzRenderBuffer::Uninitialize(); - NzDebugDrawer::Uninitialize(); - - s_textureUnits.clear(); - - // Libération des buffers - s_fullscreenQuadBuffer.Reset(); - s_instanceBuffer.Reset(); - - // Libération des VAOs - for (auto& pair : s_vaos) - { - const NzContext* context = pair.first; - const Context_Entry& contextEntry = pair.second; - - for (auto& pair2 : contextEntry.vaoMap) + Buffer::SetBufferFactory(DataStorage_Hardware, [](Buffer* parent, BufferType type) -> AbstractBuffer* { - const VAO_Entry& entry = pair2.second; - NzOpenGL::DeleteVertexArray(context, entry.vao); + return new HardwareBuffer(parent, type); + }); + + for (unsigned int i = 0; i <= MatrixType_Max; ++i) + { + MatrixUnit& unit = s_matrices[i]; + unit.location = -1; + unit.matrix.MakeIdentity(); + unit.updated = true; } + + // Récupération des capacités d'OpenGL + s_capabilities[RendererCap_AnisotropicFilter] = OpenGL::IsSupported(OpenGLExtension_AnisotropicFilter); + s_capabilities[RendererCap_ConditionalRendering] = OpenGL::IsSupported(OpenGLExtension_ConditionalRender); + s_capabilities[RendererCap_FP64] = OpenGL::IsSupported(OpenGLExtension_FP64); + s_capabilities[RendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5 + s_capabilities[RendererCap_Instancing] = OpenGL::IsSupported(OpenGLExtension_DrawInstanced) && OpenGL::IsSupported(OpenGLExtension_InstancedArray); + s_capabilities[RendererCap_MultipleRenderTargets] = (glBindFragDataLocation != nullptr); // Natif depuis OpenGL 2.0 mais inutile sans glBindFragDataLocation + s_capabilities[RendererCap_OcclusionQuery] = true; // Natif depuis OpenGL 1.5 + s_capabilities[RendererCap_PixelBufferObject] = OpenGL::IsSupported(OpenGLExtension_PixelBufferObject); + s_capabilities[RendererCap_RenderTexture] = OpenGL::IsSupported(OpenGLExtension_FrameBufferObject); + s_capabilities[RendererCap_Texture3D] = true; // Natif depuis OpenGL 1.2 + s_capabilities[RendererCap_TextureCubemap] = true; // Natif depuis OpenGL 1.3 + s_capabilities[RendererCap_TextureMulti] = true; // Natif depuis OpenGL 1.3 + s_capabilities[RendererCap_TextureNPOT] = true; // Natif depuis OpenGL 2.0 + + Context::EnsureContext(); + + if (s_capabilities[RendererCap_AnisotropicFilter]) + { + GLfloat maxAnisotropy; + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); + + s_maxAnisotropyLevel = static_cast(maxAnisotropy); + } + else + s_maxAnisotropyLevel = 1; + + if (s_capabilities[RendererCap_RenderTexture]) + { + GLint maxColorAttachments; + glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxColorAttachments); + + s_maxColorAttachments = static_cast(maxColorAttachments); + } + else + s_maxColorAttachments = 1; + + if (s_capabilities[RendererCap_MultipleRenderTargets]) + { + GLint maxDrawBuffers; + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers); + + s_maxRenderTarget = static_cast(maxDrawBuffers); + } + else + s_maxRenderTarget = 1; + + if (s_capabilities[RendererCap_TextureMulti]) + { + GLint maxTextureUnits; + glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits); + + s_maxTextureUnit = static_cast(maxTextureUnits); + } + else + s_maxTextureUnit = 1; + + GLint maxTextureSize; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize); + s_maxTextureSize = maxTextureSize; + + GLint maxVertexAttribs; + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); + s_maxVertexAttribs = static_cast(maxVertexAttribs); + + s_states = RenderStates(); + + s_indexBuffer = nullptr; + s_shader = nullptr; + s_target = nullptr; + s_targetSize.Set(0U); + s_textureUnits.resize(s_maxTextureUnit); + s_useSamplerObjects = OpenGL::IsSupported(OpenGLExtension_SamplerObjects); + s_useVertexArrayObjects = OpenGL::IsSupported(OpenGLExtension_VertexArrayObjects); + s_updateFlags = Update_Matrices | Update_Shader | Update_VAO; + s_vertexBuffer = nullptr; + + s_fullscreenQuadBuffer.Reset(VertexDeclaration::Get(VertexLayout_XY), 4, DataStorage_Hardware, BufferUsage_Static); + + float vertices[4*2] = + { + -1.f, -1.f, + 1.f, -1.f, + -1.f, 1.f, + 1.f, 1.f, + }; + + if (!s_fullscreenQuadBuffer.Fill(vertices, 0, 4)) + { + NazaraError("Failed to fill fullscreen quad buffer"); + return false; + } + + if (s_capabilities[RendererCap_Instancing]) + { + try + { + ErrorFlags errFlags(ErrorFlag_ThrowException, true); + s_instanceBuffer.Reset(nullptr, NAZARA_RENDERER_INSTANCE_BUFFER_SIZE, DataStorage_Hardware, BufferUsage_Dynamic); + } + catch (const std::exception& e) + { + s_capabilities[RendererCap_Instancing] = false; + + ErrorFlags flags(ErrorFlag_ThrowExceptionDisabled); + NazaraError("Failed to create instancing buffer: " + String(e.what())); + } + } + + if (!RenderBuffer::Initialize()) + { + NazaraError("Failed to initialize render buffers"); + return false; + } + + if (!Shader::Initialize()) + { + NazaraError("Failed to initialize shaders"); + return false; + } + + if (!Texture::Initialize()) + { + NazaraError("Failed to initialize textures"); + return false; + } + + if (!TextureSampler::Initialize()) + { + NazaraError("Failed to initialize texture samplers"); + return false; + } + + if (!UberShader::Initialize()) + { + NazaraError("Failed to initialize uber shaders"); + return false; + } + + // Création du shader de Debug + ShaderRef debugShader = Shader::New(); + if (!debugShader->Create()) + { + NazaraError("Failed to create debug shader"); + return false; + } + + const char* fragmentShader; + const char* vertexShader; + unsigned int fragmentShaderLength; + unsigned int vertexShaderLength; + if (OpenGL::GetGLSLVersion() >= 140) + { + fragmentShader = reinterpret_cast(r_coreFragmentShader); + fragmentShaderLength = sizeof(r_coreFragmentShader); + vertexShader = reinterpret_cast(r_coreVertexShader); + vertexShaderLength = sizeof(r_coreVertexShader); + } + else + { + fragmentShader = reinterpret_cast(r_compatibilityFragmentShader); + fragmentShaderLength = sizeof(r_compatibilityFragmentShader); + vertexShader = reinterpret_cast(r_compatibilityVertexShader); + vertexShaderLength = sizeof(r_compatibilityVertexShader); + } + + if (!debugShader->AttachStageFromSource(ShaderStageType_Fragment, fragmentShader, fragmentShaderLength)) + { + NazaraError("Failed to attach fragment stage"); + return false; + } + + if (!debugShader->AttachStageFromSource(ShaderStageType_Vertex, vertexShader, vertexShaderLength)) + { + NazaraError("Failed to attach vertex stage"); + return false; + } + + if (!debugShader->Link()) + { + NazaraError("Failed to link shader"); + return false; + } + + ShaderLibrary::Register("DebugSimple", debugShader); + + onExit.Reset(); + + NazaraNotice("Initialized: Renderer module"); + return true; } - s_vaos.clear(); - NzOpenGL::Uninitialize(); - - NazaraNotice("Uninitialized: Renderer module"); - - // Libération des dépendances - NzUtility::Uninitialize(); -} - -void NzRenderer::EnableInstancing(bool instancing) -{ - if (s_instancing != instancing) + bool Renderer::IsComponentTypeSupported(ComponentType type) { - s_updateFlags |= Update_VAO; - s_instancing = instancing; - } -} + switch (type) + { + case ComponentType_Color: + case ComponentType_Float1: + case ComponentType_Float2: + case ComponentType_Float3: + case ComponentType_Float4: + return true; // Supportés nativement -bool NzRenderer::EnsureStateUpdate() -{ - // Toutes les erreurs sont silencieuses car l'erreur est gérée par la fonction appelante - NzErrorFlags flags(nzErrorFlag_Silent | nzErrorFlag_ThrowExceptionDisabled); + case ComponentType_Double1: + case ComponentType_Double2: + case ComponentType_Double3: + case ComponentType_Double4: + return glVertexAttribLPointer != nullptr; // Fonction requise pour envoyer des doubles - #ifdef NAZARA_DEBUG - if (NzContext::GetCurrent() == nullptr) - { - NazaraError("No active context"); - return false; - } - #endif + case ComponentType_Int1: + case ComponentType_Int2: + case ComponentType_Int3: + case ComponentType_Int4: + return glVertexAttribIPointer != nullptr; // Fonction requise pour envoyer des entiers - #if NAZARA_RENDERER_SAFE - if (!s_shader) - { - NazaraError("No shader"); + case ComponentType_Quaternion: + return false; + } + + NazaraError("Attribute type not handled (0x" + String::Number(type, 16) + ')'); return false; } - if (!s_target) + bool Renderer::IsEnabled(RendererParameter parameter) { - NazaraError("No target"); - return false; - } - #endif - - s_target->EnsureTargetUpdated(); - - s_shader->Bind(); // Active le programme si ce n'est pas déjà le cas - - // Si le programme a été changé depuis la dernière fois - if (s_updateFlags & Update_Shader) - { - // Récupération des indices des variables uniformes (-1 si la variable n'existe pas) - s_matrices[nzMatrixType_Projection].location = s_shader->GetUniformLocation(nzShaderUniform_ProjMatrix); - s_matrices[nzMatrixType_View].location = s_shader->GetUniformLocation(nzShaderUniform_ViewMatrix); - s_matrices[nzMatrixType_World].location = s_shader->GetUniformLocation(nzShaderUniform_WorldMatrix); - - s_matrices[nzMatrixType_ViewProj].location = s_shader->GetUniformLocation(nzShaderUniform_ViewProjMatrix); - s_matrices[nzMatrixType_WorldView].location = s_shader->GetUniformLocation(nzShaderUniform_WorldViewMatrix); - s_matrices[nzMatrixType_WorldViewProj].location = s_shader->GetUniformLocation(nzShaderUniform_WorldViewProjMatrix); - - s_matrices[nzMatrixType_InvProjection].location = s_shader->GetUniformLocation(nzShaderUniform_InvProjMatrix); - s_matrices[nzMatrixType_InvView].location = s_shader->GetUniformLocation(nzShaderUniform_InvViewMatrix); - s_matrices[nzMatrixType_InvViewProj].location = s_shader->GetUniformLocation(nzShaderUniform_InvViewProjMatrix); - s_matrices[nzMatrixType_InvWorld].location = s_shader->GetUniformLocation(nzShaderUniform_InvWorldMatrix); - s_matrices[nzMatrixType_InvWorldView].location = s_shader->GetUniformLocation(nzShaderUniform_InvWorldViewMatrix); - s_matrices[nzMatrixType_InvWorldViewProj].location = s_shader->GetUniformLocation(nzShaderUniform_InvWorldViewProjMatrix); - - s_targetSize.Set(0U); // On force l'envoi des uniformes - s_updateFlags |= Update_Matrices; // Changement de programme, on renvoie toutes les matrices demandées - - s_updateFlags &= ~Update_Shader; - } - - // Envoi des uniformes liées au Renderer - NzVector2ui targetSize(s_target->GetWidth(), s_target->GetHeight()); - if (s_targetSize != targetSize) - { - int location; - - location = s_shader->GetUniformLocation(nzShaderUniform_InvTargetSize); - if (location != -1) - s_shader->SendVector(location, 1.f/NzVector2f(targetSize)); - - location = s_shader->GetUniformLocation(nzShaderUniform_TargetSize); - if (location != -1) - s_shader->SendVector(location, NzVector2f(targetSize)); - - s_targetSize.Set(targetSize); - } - - if (s_updateFlags != Update_None) - { - if (s_updateFlags & Update_Textures) + #ifdef NAZARA_DEBUG + if (parameter > RendererParameter_Max) { - if (s_useSamplerObjects) - { - for (unsigned int i : s_dirtyTextureUnits) - { - TextureUnit& unit = s_textureUnits[i]; + NazaraError("Renderer parameter out of enum"); + return false; + } + #endif - if (unit.texture && !unit.samplerUpdated) - { - unit.sampler.Bind(i); - unit.samplerUpdated = true; - } - } - } - else - { - for (unsigned int i : s_dirtyTextureUnits) - { - TextureUnit& unit = s_textureUnits[i]; + return s_states.parameters[parameter]; + } - if (unit.texture && !unit.samplerUpdated) - { - NzOpenGL::BindTextureUnit(i); - unit.sampler.Apply(unit.texture); - unit.samplerUpdated = true; - } - } - } + bool Renderer::IsInitialized() + { + return s_moduleReferenceCounter != 0; + } - s_dirtyTextureUnits.clear(); // Ne change pas la capacité - s_updateFlags &= ~Update_Textures; + void Renderer::SetBlendFunc(BlendFunc srcBlend, BlendFunc dstBlend) + { + #ifdef NAZARA_DEBUG + if (srcBlend > BlendFunc_Max) + { + NazaraError("Blend func out of enum"); + return; } - if (s_updateFlags & Update_Matrices) + if (dstBlend > BlendFunc_Max) { - for (unsigned int i = 0; i <= nzMatrixType_Max; ++i) - { - MatrixUnit& unit = s_matrices[i]; - if (unit.location != -1) // On ne traite que les matrices existant dans le programme - { - if (!unit.updated) - UpdateMatrix(static_cast(i)); + NazaraError("Blend func out of enum"); + return; + } + #endif - s_shader->SendMatrix(unit.location, unit.matrix); - } - } + s_states.srcBlend = srcBlend; + s_states.dstBlend = dstBlend; + } - s_updateFlags &= ~Update_Matrices; + void Renderer::SetClearColor(const Color& color) + { + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } + #endif + + glClearColor(color.r/255.f, color.g/255.f, color.b/255.f, color.a/255.f); + } + + void Renderer::SetClearColor(UInt8 r, UInt8 g, UInt8 b, UInt8 a) + { + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } + #endif + + glClearColor(r/255.f, g/255.f, b/255.f, a/255.f); + } + + void Renderer::SetClearDepth(double depth) + { + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } + #endif + + glClearDepth(depth); + } + + void Renderer::SetClearStencil(unsigned int value) + { + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return; + } + #endif + + glClearStencil(value); + } + + void Renderer::SetDepthFunc(RendererComparison compareFunc) + { + #ifdef NAZARA_DEBUG + if (compareFunc > RendererComparison_Max) + { + NazaraError("Renderer comparison out of enum"); + return; + } + #endif + + s_states.depthFunc = compareFunc; + } + + void Renderer::SetFaceCulling(FaceSide faceSide) + { + #ifdef NAZARA_DEBUG + if (faceSide > FaceSide_Max) + { + NazaraError("Face side out of enum"); + return; + } + #endif + + s_states.faceCulling = faceSide; + } + + void Renderer::SetFaceFilling(FaceFilling fillingMode) + { + #ifdef NAZARA_DEBUG + if (fillingMode > FaceFilling_Max) + { + NazaraError("Face filling out of enum"); + return; + } + #endif + + s_states.faceFilling = fillingMode; + } + + void Renderer::SetIndexBuffer(const IndexBuffer* indexBuffer) + { + #if NAZARA_RENDERER_SAFE + if (indexBuffer && !indexBuffer->IsHardware()) + { + NazaraError("Buffer must be hardware"); + return; + } + #endif + + if (s_indexBuffer != indexBuffer) + { + s_indexBuffer = indexBuffer; + s_updateFlags |= Update_VAO; + } + } + + void Renderer::SetLineWidth(float width) + { + #if NAZARA_RENDERER_SAFE + if (width <= 0.f) + { + NazaraError("Width must be over zero"); + return; + } + #endif + + s_states.lineWidth = width; + } + + void Renderer::SetMatrix(MatrixType type, const Matrix4f& matrix) + { + #ifdef NAZARA_DEBUG + if (type > MatrixType_Max) + { + NazaraError("Matrix type out of enum"); + return; + } + #endif + + s_matrices[type].matrix = matrix; + s_matrices[type].updated = true; + + // Invalidation des combinaisons + switch (type) + { + // Matrices de base + case MatrixType_Projection: + s_matrices[MatrixType_InvProjection].updated = false; + s_matrices[MatrixType_InvViewProj].updated = false; + s_matrices[MatrixType_InvWorldViewProj].updated = false; + s_matrices[MatrixType_ViewProj].updated = false; + s_matrices[MatrixType_WorldViewProj].updated = false; + break; + + case MatrixType_View: + s_matrices[MatrixType_InvView].updated = false; + s_matrices[MatrixType_InvViewProj].updated = false; + s_matrices[MatrixType_InvWorld].updated = false; + s_matrices[MatrixType_InvWorldViewProj].updated = false; + s_matrices[MatrixType_ViewProj].updated = false; + s_matrices[MatrixType_World].updated = false; + s_matrices[MatrixType_WorldViewProj].updated = false; + break; + + case MatrixType_World: + s_matrices[MatrixType_InvWorld].updated = false; + s_matrices[MatrixType_InvWorldView].updated = false; + s_matrices[MatrixType_InvWorldViewProj].updated = false; + s_matrices[MatrixType_WorldView].updated = false; + s_matrices[MatrixType_WorldViewProj].updated = false; + break; + + // Matrices combinées + case MatrixType_ViewProj: + s_matrices[MatrixType_InvViewProj].updated = false; + break; + + case MatrixType_WorldView: + s_matrices[MatrixType_InvWorldView].updated = false; + s_matrices[MatrixType_WorldViewProj].updated = false; + break; + + case MatrixType_WorldViewProj: + s_matrices[MatrixType_InvWorldViewProj].updated = false; + break; + + case MatrixType_InvProjection: + case MatrixType_InvView: + case MatrixType_InvViewProj: + case MatrixType_InvWorld: + case MatrixType_InvWorldView: + case MatrixType_InvWorldViewProj: + break; } - if (s_updateFlags & Update_VAO) + s_updateFlags |= Update_Matrices; + } + + void Renderer::SetPointSize(float size) + { + #if NAZARA_RENDERER_SAFE + if (size <= 0.f) + { + NazaraError("Size must be over zero"); + return; + } + #endif + + s_states.pointSize = size; + } + + void Renderer::SetRenderStates(const RenderStates& states) + { + s_states = states; + } + + void Renderer::SetScissorRect(const Recti& rect) + { + OpenGL::BindScissorBox(rect); + } + + void Renderer::SetShader(const Shader* shader) + { + #if NAZARA_RENDERER_SAFE + if (shader) + { + if (!shader->IsValid() || !shader->IsLinked()) + { + NazaraError("Invalid shader"); + return; + } + } + #endif + + if (s_shader != shader) + { + s_shader = shader; + s_updateFlags |= Update_Shader; + } + } + + void Renderer::SetStencilCompareFunction(RendererComparison compareFunc, FaceSide faceSide) + { + #ifdef NAZARA_DEBUG + if (compareFunc > RendererComparison_Max) + { + NazaraError("Renderer comparison out of enum"); + return; + } + + if (faceSide > FaceSide_Max) + { + NazaraError("Face side out of enum"); + return; + } + #endif + + switch (faceSide) + { + case FaceSide_Back: + s_states.backFace.stencilCompare = compareFunc; + break; + + case FaceSide_Front: + s_states.frontFace.stencilCompare = compareFunc; + break; + + case FaceSide_FrontAndBack: + s_states.backFace.stencilCompare = compareFunc; + s_states.frontFace.stencilCompare = compareFunc; + break; + } + } + + void Renderer::SetStencilFailOperation(nzStencilOperation failOperation, FaceSide faceSide) + { + #ifdef NAZARA_DEBUG + if (failOperation > nzStencilOperation_Max) + { + NazaraError("Stencil fail operation out of enum"); + return; + } + + if (faceSide > FaceSide_Max) + { + NazaraError("Face side out of enum"); + return; + } + #endif + + switch (faceSide) + { + case FaceSide_Back: + s_states.backFace.stencilFail = failOperation; + break; + + case FaceSide_Front: + s_states.frontFace.stencilFail = failOperation; + break; + + case FaceSide_FrontAndBack: + s_states.backFace.stencilFail = failOperation; + s_states.frontFace.stencilFail = failOperation; + break; + } + } + + void Renderer::SetStencilMask(UInt32 mask, FaceSide faceSide) + { + #ifdef NAZARA_DEBUG + if (faceSide > FaceSide_Max) + { + NazaraError("Face side out of enum"); + return; + } + #endif + + switch (faceSide) + { + case FaceSide_Back: + s_states.backFace.stencilMask = mask; + break; + + case FaceSide_Front: + s_states.frontFace.stencilMask = mask; + break; + + case FaceSide_FrontAndBack: + s_states.backFace.stencilMask = mask; + s_states.frontFace.stencilMask = mask; + break; + } + } + + void Renderer::SetStencilPassOperation(nzStencilOperation passOperation, FaceSide faceSide) + { + #ifdef NAZARA_DEBUG + if (passOperation > nzStencilOperation_Max) + { + NazaraError("Stencil pass operation out of enum"); + return; + } + + if (faceSide > FaceSide_Max) + { + NazaraError("Face side out of enum"); + return; + } + #endif + + switch (faceSide) + { + case FaceSide_Back: + s_states.backFace.stencilPass = passOperation; + break; + + case FaceSide_Front: + s_states.frontFace.stencilPass = passOperation; + break; + + case FaceSide_FrontAndBack: + s_states.backFace.stencilPass = passOperation; + s_states.frontFace.stencilPass = passOperation; + break; + } + } + + void Renderer::SetStencilReferenceValue(unsigned int refValue, FaceSide faceSide) + { + #ifdef NAZARA_DEBUG + if (faceSide > FaceSide_Max) + { + NazaraError("Face side out of enum"); + return; + } + #endif + + switch (faceSide) + { + case FaceSide_Back: + s_states.backFace.stencilReference = refValue; + break; + + case FaceSide_Front: + s_states.frontFace.stencilReference = refValue; + break; + + case FaceSide_FrontAndBack: + s_states.backFace.stencilReference = refValue; + s_states.frontFace.stencilReference = refValue; + break; + } + } + + void Renderer::SetStencilZFailOperation(nzStencilOperation zfailOperation, FaceSide faceSide) + { + #ifdef NAZARA_DEBUG + if (zfailOperation > nzStencilOperation_Max) + { + NazaraError("Stencil pass operation out of enum"); + return; + } + + if (faceSide > FaceSide_Max) + { + NazaraError("Face side out of enum"); + return; + } + #endif + + switch (faceSide) + { + case FaceSide_Back: + s_states.backFace.stencilZFail = zfailOperation; + break; + + case FaceSide_Front: + s_states.frontFace.stencilZFail = zfailOperation; + break; + + case FaceSide_FrontAndBack: + s_states.backFace.stencilZFail = zfailOperation; + s_states.frontFace.stencilZFail = zfailOperation; + break; + } + } + + bool Renderer::SetTarget(const RenderTarget* target) + { + if (s_target == target) + return true; + + if (s_target) + { + if (!s_target->HasContext()) + s_target->Desactivate(); + + s_target = nullptr; + } + + if (target) { #if NAZARA_RENDERER_SAFE - if (!s_vertexBuffer) + if (!target->IsRenderable()) { - NazaraError("No vertex buffer"); + NazaraError("Target not renderable"); return false; } #endif - bool update; - VAO_Map::iterator vaoIt; - - // Si les VAOs sont supportés, on entoure nos appels par ceux-ci - if (s_useVertexArrayObjects) + if (!target->Activate()) { - // Note: Les VAOs ne sont pas partagés entre les contextes, nous avons donc un tableau de VAOs par contexte - const NzContext* context = NzContext::GetCurrent(); - - auto it = s_vaos.find(context); - if (it == s_vaos.end()) - { - Context_Entry entry; - entry.onReleaseSlot.Connect(context->OnContextRelease, OnContextRelease); - - it = s_vaos.insert(std::make_pair(context, std::move(entry))).first; - } - - VAO_Map& vaoMap = it->second.vaoMap; - - // Notre clé est composée de ce qui définit un VAO - const NzVertexDeclaration* vertexDeclaration = s_vertexBuffer->GetVertexDeclaration(); - const NzVertexDeclaration* instancingDeclaration = (s_instancing) ? s_instanceBuffer.GetVertexDeclaration() : nullptr; - VAO_Key key(s_indexBuffer, s_vertexBuffer, vertexDeclaration, instancingDeclaration); - - // On recherche un VAO existant avec notre configuration - vaoIt = vaoMap.find(key); - if (vaoIt == vaoMap.end()) - { - // On créé notre VAO - glGenVertexArrays(1, &s_currentVAO); - glBindVertexArray(s_currentVAO); - - // On l'ajoute à notre liste - VAO_Entry entry; - entry.vao = s_currentVAO; - - // Connect the slots - if (s_indexBuffer) - entry.onIndexBufferReleaseSlot.Connect(s_indexBuffer->OnIndexBufferRelease, OnIndexBufferRelease); - - if (instancingDeclaration) - entry.onInstancingDeclarationReleaseSlot.Connect(instancingDeclaration->OnVertexDeclarationRelease, OnVertexDeclarationRelease); - - entry.onVertexBufferReleaseSlot.Connect(s_vertexBuffer->OnVertexBufferRelease, OnVertexBufferRelease); - entry.onVertexDeclarationReleaseSlot.Connect(vertexDeclaration->OnVertexDeclarationRelease, OnVertexDeclarationRelease); - - vaoIt = vaoMap.insert(std::make_pair(key, std::move(entry))).first; - - // Et on indique qu'on veut le programmer - update = true; - } - else - { - // Notre VAO existe déjà, il est donc inutile de le reprogrammer - s_currentVAO = vaoIt->second.vao; - - update = false; - } - } - else - update = true; // Fallback si les VAOs ne sont pas supportés - - bool updateFailed = false; - - if (update) - { - // Pour éviter la duplication de code, on va utiliser une astuce via une boucle for - for (unsigned int i = 0; i < (s_instancing ? 2U : 1U); ++i) - { - // Selon l'itération nous choisissons un buffer différent - const NzVertexBuffer* vertexBuffer = (i == 0) ? s_vertexBuffer : &s_instanceBuffer; - - NzHardwareBuffer* vertexBufferImpl = static_cast(vertexBuffer->GetBuffer()->GetImpl()); - glBindBuffer(NzOpenGL::BufferTarget[nzBufferType_Vertex], vertexBufferImpl->GetOpenGLID()); - - unsigned int bufferOffset = vertexBuffer->GetStartOffset(); - const NzVertexDeclaration* vertexDeclaration = vertexBuffer->GetVertexDeclaration(); - unsigned int stride = vertexDeclaration->GetStride(); - - // On définit les bornes (une fois de plus selon l'itération) - unsigned int start = (i == 0) ? nzVertexComponent_FirstVertexData : nzVertexComponent_FirstInstanceData; - unsigned int end = (i == 0) ? nzVertexComponent_LastVertexData : nzVertexComponent_LastInstanceData; - for (unsigned int j = start; j <= end; ++j) - { - nzComponentType type; - bool enabled; - unsigned int offset; - vertexDeclaration->GetComponent(static_cast(j), &enabled, &type, &offset); - - if (enabled) - { - if (!IsComponentTypeSupported(type)) - { - NazaraError("Invalid vertex declaration " + NzString::Pointer(vertexDeclaration) + ": Vertex component 0x" + NzString::Number(j, 16) + " (type: 0x" + NzString::Number(type, 16) + ") is not supported"); - updateFailed = true; - break; - } - - glEnableVertexAttribArray(NzOpenGL::VertexComponentIndex[j]); - - switch (type) - { - case nzComponentType_Color: - { - glVertexAttribPointer(NzOpenGL::VertexComponentIndex[j], - NzUtility::ComponentCount[type], - NzOpenGL::ComponentType[type], - GL_TRUE, - stride, - reinterpret_cast(bufferOffset + offset)); - - break; - } - - case nzComponentType_Double1: - case nzComponentType_Double2: - case nzComponentType_Double3: - case nzComponentType_Double4: - { - glVertexAttribLPointer(NzOpenGL::VertexComponentIndex[j], - NzUtility::ComponentCount[type], - NzOpenGL::ComponentType[type], - stride, - reinterpret_cast(bufferOffset + offset)); - - break; - } - - case nzComponentType_Float1: - case nzComponentType_Float2: - case nzComponentType_Float3: - case nzComponentType_Float4: - { - glVertexAttribPointer(NzOpenGL::VertexComponentIndex[j], - NzUtility::ComponentCount[type], - NzOpenGL::ComponentType[type], - GL_FALSE, - stride, - reinterpret_cast(bufferOffset + offset)); - - break; - } - - case nzComponentType_Int1: - case nzComponentType_Int2: - case nzComponentType_Int3: - case nzComponentType_Int4: - { - glVertexAttribIPointer(NzOpenGL::VertexComponentIndex[j], - NzUtility::ComponentCount[type], - NzOpenGL::ComponentType[type], - stride, - reinterpret_cast(bufferOffset + offset)); - - break; - } - - default: - { - NazaraInternalError("Unsupported component type (0x" + NzString::Number(type, 16) + ')'); - break; - } - } - // Les attributs d'instancing ont un diviseur spécifique (pour dépendre de l'instance en cours) - if (i == 1) - glVertexAttribDivisor(NzOpenGL::VertexComponentIndex[j], 1); - } - else - glDisableVertexAttribArray(NzOpenGL::VertexComponentIndex[j]); - } - } - - if (!s_instancing) - { - // Je ne sais pas si c'est vraiment nécessaire de désactiver les attributs, sur mon ordinateur ça ne pose aucun problème - // mais dans le doute, je laisse ça comme ça. - for (unsigned int i = nzVertexComponent_FirstInstanceData; i <= nzVertexComponent_LastInstanceData; ++i) - glDisableVertexAttribArray(NzOpenGL::VertexComponentIndex[i]); - } - - // Et on active l'index buffer (Un seul index buffer par VAO) - if (s_indexBuffer) - { - NzHardwareBuffer* indexBufferImpl = static_cast(s_indexBuffer->GetBuffer()->GetImpl()); - glBindBuffer(NzOpenGL::BufferTarget[nzBufferType_Index], indexBufferImpl->GetOpenGLID()); - } - else - glBindBuffer(NzOpenGL::BufferTarget[nzBufferType_Index], 0); - - // On invalide les bindings des buffers (car nous les avons défini manuellement) - NzOpenGL::SetBuffer(nzBufferType_Index, 0); - NzOpenGL::SetBuffer(nzBufferType_Vertex, 0); + NazaraError("Failed to activate target"); + return false; } - if (s_useVertexArrayObjects) - { - if (update) - { - if (updateFailed) - { - // La création de notre VAO a échoué, libérons-le et marquons-le comme problématique - glDeleteVertexArrays(1, &vaoIt->second.vao); - vaoIt->second.vao = 0; - s_currentVAO = 0; - } - else - glBindVertexArray(0); // On marque la fin de la construction du VAO en le débindant - } - - // En cas de non-support des VAOs, les attributs doivent être respécifiés à chaque frame - s_updateFlags &= ~Update_VAO; - } + s_target = target; } - #ifdef NAZARA_DEBUG - if (s_updateFlags != Update_None && !s_useVertexArrayObjects && s_updateFlags != Update_VAO) - NazaraWarning("Update flags not fully cleared"); - #endif + OpenGL::SetTarget(s_target); + + return true; } - // On bind notre VAO - if (s_useVertexArrayObjects) + void Renderer::SetTexture(UInt8 unit, const Texture* texture) { - if (!s_currentVAO) + #if NAZARA_RENDERER_SAFE + if (unit >= s_maxTextureUnit) { - NazaraError("Failed to create VAO"); + NazaraError("Texture unit out of range (" + String::Number(unit) + " >= " + String::Number(s_maxTextureUnit) + ')'); + return; + } + #endif + + if (s_textureUnits[unit].texture != texture) + { + s_textureUnits[unit].texture = texture; + + if (texture) + { + if (s_textureUnits[unit].sampler.UseMipmaps(texture->HasMipmaps())) + s_textureUnits[unit].samplerUpdated = false; + } + + s_dirtyTextureUnits.push_back(unit); + s_updateFlags |= Update_Textures; + } + } + + void Renderer::SetTextureSampler(UInt8 unit, const TextureSampler& sampler) + { + #if NAZARA_RENDERER_SAFE + if (unit >= s_maxTextureUnit) + { + NazaraError("Texture unit out of range (" + String::Number(unit) + " >= " + String::Number(s_maxTextureUnit) + ')'); + return; + } + #endif + + s_textureUnits[unit].sampler = sampler; + s_textureUnits[unit].samplerUpdated = false; + + if (s_textureUnits[unit].texture) + s_textureUnits[unit].sampler.UseMipmaps(s_textureUnits[unit].texture->HasMipmaps()); + + s_dirtyTextureUnits.push_back(unit); + s_updateFlags |= Update_Textures; + } + + void Renderer::SetVertexBuffer(const VertexBuffer* vertexBuffer) + { + #if NAZARA_RENDERER_SAFE + if (vertexBuffer && !vertexBuffer->IsHardware()) + { + NazaraError("Buffer must be hardware"); + return; + } + #endif + + if (vertexBuffer && s_vertexBuffer != vertexBuffer) + { + s_vertexBuffer = vertexBuffer; + s_updateFlags |= Update_VAO; + } + } + + void Renderer::SetViewport(const Recti& viewport) + { + OpenGL::BindViewport(viewport); + } + + void Renderer::Uninitialize() + { + if (s_moduleReferenceCounter != 1) + { + // Le module est soit encore utilisé, soit pas initialisé + if (s_moduleReferenceCounter > 1) + s_moduleReferenceCounter--; + + return; + } + + // Libération du module + s_moduleReferenceCounter = 0; + + ShaderLibrary::Unregister("DebugSimple"); + + UberShader::Uninitialize(); + TextureSampler::Uninitialize(); + Texture::Uninitialize(); + Shader::Uninitialize(); + RenderBuffer::Uninitialize(); + DebugDrawer::Uninitialize(); + + s_textureUnits.clear(); + + // Libération des buffers + s_fullscreenQuadBuffer.Reset(); + s_instanceBuffer.Reset(); + + // Libération des VAOs + for (auto& pair : s_vaos) + { + const Context* context = pair.first; + const Context_Entry& contextEntry = pair.second; + + for (auto& pair2 : contextEntry.vaoMap) + { + const VAO_Entry& entry = pair2.second; + OpenGL::DeleteVertexArray(context, entry.vao); + } + } + s_vaos.clear(); + + OpenGL::Uninitialize(); + + NazaraNotice("Uninitialized: Renderer module"); + + // Libération des dépendances + Utility::Uninitialize(); + } + + void Renderer::EnableInstancing(bool instancing) + { + if (s_instancing != instancing) + { + s_updateFlags |= Update_VAO; + s_instancing = instancing; + } + } + + bool Renderer::EnsureStateUpdate() + { + // Toutes les erreurs sont silencieuses car l'erreur est gérée par la fonction appelante + ErrorFlags flags(ErrorFlag_Silent | ErrorFlag_ThrowExceptionDisabled); + + #ifdef NAZARA_DEBUG + if (Context::GetCurrent() == nullptr) + { + NazaraError("No active context"); + return false; + } + #endif + + #if NAZARA_RENDERER_SAFE + if (!s_shader) + { + NazaraError("No shader"); return false; } - glBindVertexArray(s_currentVAO); - } - - // On vérifie que les textures actuellement bindées sont bien nos textures - // Ceci à cause du fait qu'il est possible que des opérations sur les textures aient eu lieu - // entre le dernier rendu et maintenant - for (unsigned int i = 0; i < s_maxTextureUnit; ++i) - { - const NzTexture* texture = s_textureUnits[i].texture; - if (texture) + if (!s_target) { - NzOpenGL::BindTexture(i, texture->GetType(), texture->GetOpenGLID()); - texture->EnsureMipmapsUpdate(); + NazaraError("No target"); + return false; } - } + #endif - // Et on termine par envoyer nos états au driver - NzOpenGL::ApplyStates(s_states); + s_target->EnsureTargetUpdated(); - return true; -} + s_shader->Bind(); // Active le programme si ce n'est pas déjà le cas -void NzRenderer::OnContextRelease(const NzContext* context) -{ - s_vaos.erase(context); -} - -void NzRenderer::OnIndexBufferRelease(const NzIndexBuffer* indexBuffer) -{ - for (auto& pair : s_vaos) - { - const NzContext* context = pair.first; - VAO_Map& vaos = pair.second.vaoMap; - - auto it = vaos.begin(); - while (it != vaos.end()) + // Si le programme a été changé depuis la dernière fois + if (s_updateFlags & Update_Shader) { - const VAO_Key& key = it->first; - const NzIndexBuffer* vaoIndexBuffer = std::get<0>(key); + // Récupération des indices des variables uniformes (-1 si la variable n'existe pas) + s_matrices[MatrixType_Projection].location = s_shader->GetUniformLocation(ShaderUniform_ProjMatrix); + s_matrices[MatrixType_View].location = s_shader->GetUniformLocation(ShaderUniform_ViewMatrix); + s_matrices[MatrixType_World].location = s_shader->GetUniformLocation(ShaderUniform_WorldMatrix); - if (vaoIndexBuffer == indexBuffer) + s_matrices[MatrixType_ViewProj].location = s_shader->GetUniformLocation(ShaderUniform_ViewProjMatrix); + s_matrices[MatrixType_WorldView].location = s_shader->GetUniformLocation(ShaderUniform_WorldViewMatrix); + s_matrices[MatrixType_WorldViewProj].location = s_shader->GetUniformLocation(ShaderUniform_WorldViewProjMatrix); + + s_matrices[MatrixType_InvProjection].location = s_shader->GetUniformLocation(ShaderUniform_InvProjMatrix); + s_matrices[MatrixType_InvView].location = s_shader->GetUniformLocation(ShaderUniform_InvViewMatrix); + s_matrices[MatrixType_InvViewProj].location = s_shader->GetUniformLocation(ShaderUniform_InvViewProjMatrix); + s_matrices[MatrixType_InvWorld].location = s_shader->GetUniformLocation(ShaderUniform_InvWorldMatrix); + s_matrices[MatrixType_InvWorldView].location = s_shader->GetUniformLocation(ShaderUniform_InvWorldViewMatrix); + s_matrices[MatrixType_InvWorldViewProj].location = s_shader->GetUniformLocation(ShaderUniform_InvWorldViewProjMatrix); + + s_targetSize.Set(0U); // On force l'envoi des uniformes + s_updateFlags |= Update_Matrices; // Changement de programme, on renvoie toutes les matrices demandées + + s_updateFlags &= ~Update_Shader; + } + + // Envoi des uniformes liées au Renderer + Vector2ui targetSize(s_target->GetWidth(), s_target->GetHeight()); + if (s_targetSize != targetSize) + { + int location; + + location = s_shader->GetUniformLocation(ShaderUniform_InvTargetSize); + if (location != -1) + s_shader->SendVector(location, 1.f/Vector2f(targetSize)); + + location = s_shader->GetUniformLocation(ShaderUniform_TargetSize); + if (location != -1) + s_shader->SendVector(location, Vector2f(targetSize)); + + s_targetSize.Set(targetSize); + } + + if (s_updateFlags != Update_None) + { + if (s_updateFlags & Update_Textures) { - // Suppression du VAO: - // Comme celui-ci est local à son contexte de création, sa suppression n'est possible que si - // son contexte d'origine est actif, sinon il faudra le mettre en file d'attente - // Ceci est géré par la méthode OpenGL::DeleteVertexArray + if (s_useSamplerObjects) + { + for (unsigned int i : s_dirtyTextureUnits) + { + TextureUnit& unit = s_textureUnits[i]; - NzOpenGL::DeleteVertexArray(context, it->second.vao); - vaos.erase(it++); + if (unit.texture && !unit.samplerUpdated) + { + unit.sampler.Bind(i); + unit.samplerUpdated = true; + } + } + } + else + { + for (unsigned int i : s_dirtyTextureUnits) + { + TextureUnit& unit = s_textureUnits[i]; + + if (unit.texture && !unit.samplerUpdated) + { + OpenGL::BindTextureUnit(i); + unit.sampler.Apply(unit.texture); + unit.samplerUpdated = true; + } + } + } + + s_dirtyTextureUnits.clear(); // Ne change pas la capacité + s_updateFlags &= ~Update_Textures; } - else - ++it; - } - } -} -void NzRenderer::OnShaderReleased(const NzShader* shader) -{ - if (s_shader == shader) - { - s_shader = nullptr; - s_updateFlags |= Update_Shader; - } -} - -void NzRenderer::OnTextureReleased(const NzTexture* texture) -{ - for (TextureUnit& unit : s_textureUnits) - { - if (unit.texture == texture) - unit.texture = nullptr; - - // Inutile de changer le flag pour une texture désactivée - } -} - -void NzRenderer::OnVertexBufferRelease(const NzVertexBuffer* vertexBuffer) -{ - for (auto& pair : s_vaos) - { - const NzContext* context = pair.first; - VAO_Map& vaos = pair.second.vaoMap; - - auto it = vaos.begin(); - while (it != vaos.end()) - { - const VAO_Key& key = it->first; - const NzVertexBuffer* vaoVertexBuffer = std::get<1>(key); - - if (vaoVertexBuffer == vertexBuffer) + if (s_updateFlags & Update_Matrices) { - // Suppression du VAO: - // Comme celui-ci est local à son contexte de création, sa suppression n'est possible que si - // son contexte d'origine est actif, sinon il faudra le mettre en file d'attente - // Ceci est géré par la méthode OpenGL::DeleteVertexArray + for (unsigned int i = 0; i <= MatrixType_Max; ++i) + { + MatrixUnit& unit = s_matrices[i]; + if (unit.location != -1) // On ne traite que les matrices existant dans le programme + { + if (!unit.updated) + UpdateMatrix(static_cast(i)); - NzOpenGL::DeleteVertexArray(context, it->second.vao); - vaos.erase(it++); + s_shader->SendMatrix(unit.location, unit.matrix); + } + } + + s_updateFlags &= ~Update_Matrices; } - else - ++it; - } - } -} -void NzRenderer::OnVertexDeclarationRelease(const NzVertexDeclaration* vertexDeclaration) -{ - for (auto& pair : s_vaos) - { - const NzContext* context = pair.first; - VAO_Map& vaos = pair.second.vaoMap; - - auto it = vaos.begin(); - while (it != vaos.end()) - { - const VAO_Key& key = it->first; - const NzVertexDeclaration* vaoVertexDeclaration = std::get<2>(key); - const NzVertexDeclaration* vaoInstancingDeclaration = std::get<3>(key); - - if (vaoVertexDeclaration == vertexDeclaration || vaoInstancingDeclaration == vertexDeclaration) + if (s_updateFlags & Update_VAO) { - // Suppression du VAO: - // Comme celui-ci est local à son contexte de création, sa suppression n'est possible que si - // son contexte d'origine est actif, sinon il faudra le mettre en file d'attente - // Ceci est géré par la méthode OpenGL::DeleteVertexArray + #if NAZARA_RENDERER_SAFE + if (!s_vertexBuffer) + { + NazaraError("No vertex buffer"); + return false; + } + #endif - NzOpenGL::DeleteVertexArray(context, it->second.vao); - vaos.erase(it++); + bool update; + VAO_Map::iterator vaoIt; + + // Si les VAOs sont supportés, on entoure nos appels par ceux-ci + if (s_useVertexArrayObjects) + { + // Note: Les VAOs ne sont pas partagés entre les contextes, nous avons donc un tableau de VAOs par contexte + const Context* context = Context::GetCurrent(); + + auto it = s_vaos.find(context); + if (it == s_vaos.end()) + { + Context_Entry entry; + entry.onReleaseSlot.Connect(context->OnContextRelease, OnContextRelease); + + it = s_vaos.insert(std::make_pair(context, std::move(entry))).first; + } + + VAO_Map& vaoMap = it->second.vaoMap; + + // Notre clé est composée de ce qui définit un VAO + const VertexDeclaration* vertexDeclaration = s_vertexBuffer->GetVertexDeclaration(); + const VertexDeclaration* instancingDeclaration = (s_instancing) ? s_instanceBuffer.GetVertexDeclaration() : nullptr; + VAO_Key key(s_indexBuffer, s_vertexBuffer, vertexDeclaration, instancingDeclaration); + + // On recherche un VAO existant avec notre configuration + vaoIt = vaoMap.find(key); + if (vaoIt == vaoMap.end()) + { + // On créé notre VAO + glGenVertexArrays(1, &s_currentVAO); + glBindVertexArray(s_currentVAO); + + // On l'ajoute à notre liste + VAO_Entry entry; + entry.vao = s_currentVAO; + + // Connect the slots + if (s_indexBuffer) + entry.onIndexBufferReleaseSlot.Connect(s_indexBuffer->OnIndexBufferRelease, OnIndexBufferRelease); + + if (instancingDeclaration) + entry.onInstancingDeclarationReleaseSlot.Connect(instancingDeclaration->OnVertexDeclarationRelease, OnVertexDeclarationRelease); + + entry.onVertexBufferReleaseSlot.Connect(s_vertexBuffer->OnVertexBufferRelease, OnVertexBufferRelease); + entry.onVertexDeclarationReleaseSlot.Connect(vertexDeclaration->OnVertexDeclarationRelease, OnVertexDeclarationRelease); + + vaoIt = vaoMap.insert(std::make_pair(key, std::move(entry))).first; + + // Et on indique qu'on veut le programmer + update = true; + } + else + { + // Notre VAO existe déjà, il est donc inutile de le reprogrammer + s_currentVAO = vaoIt->second.vao; + + update = false; + } + } + else + update = true; // Fallback si les VAOs ne sont pas supportés + + bool updateFailed = false; + + if (update) + { + // Pour éviter la duplication de code, on va utiliser une astuce via une boucle for + for (unsigned int i = 0; i < (s_instancing ? 2U : 1U); ++i) + { + // Selon l'itération nous choisissons un buffer différent + const VertexBuffer* vertexBuffer = (i == 0) ? s_vertexBuffer : &s_instanceBuffer; + + HardwareBuffer* vertexBufferImpl = static_cast(vertexBuffer->GetBuffer()->GetImpl()); + glBindBuffer(OpenGL::BufferTarget[BufferType_Vertex], vertexBufferImpl->GetOpenGLID()); + + unsigned int bufferOffset = vertexBuffer->GetStartOffset(); + const VertexDeclaration* vertexDeclaration = vertexBuffer->GetVertexDeclaration(); + unsigned int stride = vertexDeclaration->GetStride(); + + // On définit les bornes (une fois de plus selon l'itération) + unsigned int start = (i == 0) ? VertexComponent_FirstVertexData : VertexComponent_FirstInstanceData; + unsigned int end = (i == 0) ? VertexComponent_LastVertexData : VertexComponent_LastInstanceData; + for (unsigned int j = start; j <= end; ++j) + { + ComponentType type; + bool enabled; + unsigned int offset; + vertexDeclaration->GetComponent(static_cast(j), &enabled, &type, &offset); + + if (enabled) + { + if (!IsComponentTypeSupported(type)) + { + NazaraError("Invalid vertex declaration " + String::Pointer(vertexDeclaration) + ": Vertex component 0x" + String::Number(j, 16) + " (type: 0x" + String::Number(type, 16) + ") is not supported"); + updateFailed = true; + break; + } + + glEnableVertexAttribArray(OpenGL::VertexComponentIndex[j]); + + switch (type) + { + case ComponentType_Color: + { + glVertexAttribPointer(OpenGL::VertexComponentIndex[j], + Utility::ComponentCount[type], + OpenGL::ComponentType[type], + GL_TRUE, + stride, + reinterpret_cast(bufferOffset + offset)); + + break; + } + + case ComponentType_Double1: + case ComponentType_Double2: + case ComponentType_Double3: + case ComponentType_Double4: + { + glVertexAttribLPointer(OpenGL::VertexComponentIndex[j], + Utility::ComponentCount[type], + OpenGL::ComponentType[type], + stride, + reinterpret_cast(bufferOffset + offset)); + + break; + } + + case ComponentType_Float1: + case ComponentType_Float2: + case ComponentType_Float3: + case ComponentType_Float4: + { + glVertexAttribPointer(OpenGL::VertexComponentIndex[j], + Utility::ComponentCount[type], + OpenGL::ComponentType[type], + GL_FALSE, + stride, + reinterpret_cast(bufferOffset + offset)); + + break; + } + + case ComponentType_Int1: + case ComponentType_Int2: + case ComponentType_Int3: + case ComponentType_Int4: + { + glVertexAttribIPointer(OpenGL::VertexComponentIndex[j], + Utility::ComponentCount[type], + OpenGL::ComponentType[type], + stride, + reinterpret_cast(bufferOffset + offset)); + + break; + } + + default: + { + NazaraInternalError("Unsupported component type (0x" + String::Number(type, 16) + ')'); + break; + } + } + // Les attributs d'instancing ont un diviseur spécifique (pour dépendre de l'instance en cours) + if (i == 1) + glVertexAttribDivisor(OpenGL::VertexComponentIndex[j], 1); + } + else + glDisableVertexAttribArray(OpenGL::VertexComponentIndex[j]); + } + } + + if (!s_instancing) + { + // Je ne sais pas si c'est vraiment nécessaire de désactiver les attributs, sur mon ordinateur ça ne pose aucun problème + // mais dans le doute, je laisse ça comme ça. + for (unsigned int i = VertexComponent_FirstInstanceData; i <= VertexComponent_LastInstanceData; ++i) + glDisableVertexAttribArray(OpenGL::VertexComponentIndex[i]); + } + + // Et on active l'index buffer (Un seul index buffer par VAO) + if (s_indexBuffer) + { + HardwareBuffer* indexBufferImpl = static_cast(s_indexBuffer->GetBuffer()->GetImpl()); + glBindBuffer(OpenGL::BufferTarget[BufferType_Index], indexBufferImpl->GetOpenGLID()); + } + else + glBindBuffer(OpenGL::BufferTarget[BufferType_Index], 0); + + // On invalide les bindings des buffers (car nous les avons défini manuellement) + OpenGL::SetBuffer(BufferType_Index, 0); + OpenGL::SetBuffer(BufferType_Vertex, 0); + } + + if (s_useVertexArrayObjects) + { + if (update) + { + if (updateFailed) + { + // La création de notre VAO a échoué, libérons-le et marquons-le comme problématique + glDeleteVertexArrays(1, &vaoIt->second.vao); + vaoIt->second.vao = 0; + s_currentVAO = 0; + } + else + glBindVertexArray(0); // On marque la fin de la construction du VAO en le débindant + } + + // En cas de non-support des VAOs, les attributs doivent être respécifiés à chaque frame + s_updateFlags &= ~Update_VAO; + } + } + + #ifdef NAZARA_DEBUG + if (s_updateFlags != Update_None && !s_useVertexArrayObjects && s_updateFlags != Update_VAO) + NazaraWarning("Update flags not fully cleared"); + #endif + } + + // On bind notre VAO + if (s_useVertexArrayObjects) + { + if (!s_currentVAO) + { + NazaraError("Failed to create VAO"); + return false; + } + + glBindVertexArray(s_currentVAO); + } + + // On vérifie que les textures actuellement bindées sont bien nos textures + // Ceci à cause du fait qu'il est possible que des opérations sur les textures aient eu lieu + // entre le dernier rendu et maintenant + for (unsigned int i = 0; i < s_maxTextureUnit; ++i) + { + const Texture* texture = s_textureUnits[i].texture; + if (texture) + { + OpenGL::BindTexture(i, texture->GetType(), texture->GetOpenGLID()); + texture->EnsureMipmapsUpdate(); + } + } + + // Et on termine par envoyer nos états au driver + OpenGL::ApplyStates(s_states); + + return true; + } + + void Renderer::OnContextRelease(const Context* context) + { + s_vaos.erase(context); + } + + void Renderer::OnIndexBufferRelease(const IndexBuffer* indexBuffer) + { + for (auto& pair : s_vaos) + { + const Context* context = pair.first; + VAO_Map& vaos = pair.second.vaoMap; + + auto it = vaos.begin(); + while (it != vaos.end()) + { + const VAO_Key& key = it->first; + const IndexBuffer* vaoIndexBuffer = std::get<0>(key); + + if (vaoIndexBuffer == indexBuffer) + { + // Suppression du VAO: + // Comme celui-ci est local à son contexte de création, sa suppression n'est possible que si + // son contexte d'origine est actif, sinon il faudra le mettre en file d'attente + // Ceci est géré par la méthode OpenGL::DeleteVertexArray + + OpenGL::DeleteVertexArray(context, it->second.vao); + vaos.erase(it++); + } + else + ++it; } - else - ++it; } } -} -void NzRenderer::UpdateMatrix(nzMatrixType type) -{ - #ifdef NAZARA_DEBUG - if (type > nzMatrixType_Max) + void Renderer::OnShaderReleased(const Shader* shader) { - NazaraError("Matrix type out of enum"); - return; + if (s_shader == shader) + { + s_shader = nullptr; + s_updateFlags |= Update_Shader; + } } - #endif - switch (type) + void Renderer::OnTextureReleased(const Texture* texture) { - // Matrices de base - case nzMatrixType_Projection: - case nzMatrixType_View: - case nzMatrixType_World: - s_matrices[type].updated = true; - break; + for (TextureUnit& unit : s_textureUnits) + { + if (unit.texture == texture) + unit.texture = nullptr; - // Matrices combinées - case nzMatrixType_ViewProj: - s_matrices[nzMatrixType_ViewProj].matrix = s_matrices[nzMatrixType_View].matrix; - s_matrices[nzMatrixType_ViewProj].matrix.Concatenate(s_matrices[nzMatrixType_Projection].matrix); - s_matrices[nzMatrixType_ViewProj].updated = true; - break; - - case nzMatrixType_WorldView: - s_matrices[nzMatrixType_WorldView].matrix = s_matrices[nzMatrixType_World].matrix; - s_matrices[nzMatrixType_WorldView].matrix.ConcatenateAffine(s_matrices[nzMatrixType_View].matrix); - s_matrices[nzMatrixType_WorldView].updated = true; - break; - - case nzMatrixType_WorldViewProj: - if (!s_matrices[nzMatrixType_WorldView].updated) - UpdateMatrix(nzMatrixType_WorldView); - - s_matrices[nzMatrixType_WorldViewProj].matrix = s_matrices[nzMatrixType_WorldView].matrix; - s_matrices[nzMatrixType_WorldViewProj].matrix.Concatenate(s_matrices[nzMatrixType_Projection].matrix); - s_matrices[nzMatrixType_WorldViewProj].updated = true; - break; - - // Matrices inversées - case nzMatrixType_InvProjection: - if (!s_matrices[nzMatrixType_Projection].updated) - UpdateMatrix(nzMatrixType_Projection); - - if (!s_matrices[nzMatrixType_Projection].matrix.GetInverse(&s_matrices[nzMatrixType_InvProjection].matrix)) - NazaraWarning("Failed to inverse Proj matrix"); - - s_matrices[nzMatrixType_InvProjection].updated = true; - break; - - case nzMatrixType_InvView: - if (!s_matrices[nzMatrixType_View].updated) - UpdateMatrix(nzMatrixType_View); - - if (!s_matrices[nzMatrixType_View].matrix.GetInverse(&s_matrices[nzMatrixType_InvView].matrix)) - NazaraWarning("Failed to inverse View matrix"); - - s_matrices[nzMatrixType_InvView].updated = true; - break; - - case nzMatrixType_InvViewProj: - if (!s_matrices[nzMatrixType_ViewProj].updated) - UpdateMatrix(nzMatrixType_ViewProj); - - if (!s_matrices[nzMatrixType_ViewProj].matrix.GetInverse(&s_matrices[nzMatrixType_InvViewProj].matrix)) - NazaraWarning("Failed to inverse ViewProj matrix"); - - s_matrices[nzMatrixType_InvViewProj].updated = true; - break; - - case nzMatrixType_InvWorld: - if (!s_matrices[nzMatrixType_World].updated) - UpdateMatrix(nzMatrixType_World); - - if (!s_matrices[nzMatrixType_World].matrix.GetInverse(&s_matrices[nzMatrixType_InvWorld].matrix)) - NazaraWarning("Failed to inverse World matrix"); - - s_matrices[nzMatrixType_InvWorld].updated = true; - break; - - case nzMatrixType_InvWorldView: - if (!s_matrices[nzMatrixType_WorldView].updated) - UpdateMatrix(nzMatrixType_WorldView); - - if (!s_matrices[nzMatrixType_WorldView].matrix.GetInverse(&s_matrices[nzMatrixType_InvWorldView].matrix)) - NazaraWarning("Failed to inverse WorldView matrix"); - - s_matrices[nzMatrixType_InvWorldView].updated = true; - break; - - case nzMatrixType_InvWorldViewProj: - if (!s_matrices[nzMatrixType_WorldViewProj].updated) - UpdateMatrix(nzMatrixType_WorldViewProj); - - if (!s_matrices[nzMatrixType_WorldViewProj].matrix.GetInverse(&s_matrices[nzMatrixType_InvWorldViewProj].matrix)) - NazaraWarning("Failed to inverse WorldViewProj matrix"); - - s_matrices[nzMatrixType_InvWorldViewProj].updated = true; - break; + // Inutile de changer le flag pour une texture désactivée + } } -} -unsigned int NzRenderer::s_moduleReferenceCounter = 0; + void Renderer::OnVertexBufferRelease(const VertexBuffer* vertexBuffer) + { + for (auto& pair : s_vaos) + { + const Context* context = pair.first; + VAO_Map& vaos = pair.second.vaoMap; + + auto it = vaos.begin(); + while (it != vaos.end()) + { + const VAO_Key& key = it->first; + const VertexBuffer* vaoVertexBuffer = std::get<1>(key); + + if (vaoVertexBuffer == vertexBuffer) + { + // Suppression du VAO: + // Comme celui-ci est local à son contexte de création, sa suppression n'est possible que si + // son contexte d'origine est actif, sinon il faudra le mettre en file d'attente + // Ceci est géré par la méthode OpenGL::DeleteVertexArray + + OpenGL::DeleteVertexArray(context, it->second.vao); + vaos.erase(it++); + } + else + ++it; + } + } + } + + void Renderer::OnVertexDeclarationRelease(const VertexDeclaration* vertexDeclaration) + { + for (auto& pair : s_vaos) + { + const Context* context = pair.first; + VAO_Map& vaos = pair.second.vaoMap; + + auto it = vaos.begin(); + while (it != vaos.end()) + { + const VAO_Key& key = it->first; + const VertexDeclaration* vaoVertexDeclaration = std::get<2>(key); + const VertexDeclaration* vaoInstancingDeclaration = std::get<3>(key); + + if (vaoVertexDeclaration == vertexDeclaration || vaoInstancingDeclaration == vertexDeclaration) + { + // Suppression du VAO: + // Comme celui-ci est local à son contexte de création, sa suppression n'est possible que si + // son contexte d'origine est actif, sinon il faudra le mettre en file d'attente + // Ceci est géré par la méthode OpenGL::DeleteVertexArray + + OpenGL::DeleteVertexArray(context, it->second.vao); + vaos.erase(it++); + } + else + ++it; + } + } + } + + void Renderer::UpdateMatrix(MatrixType type) + { + #ifdef NAZARA_DEBUG + if (type > MatrixType_Max) + { + NazaraError("Matrix type out of enum"); + return; + } + #endif + + switch (type) + { + // Matrices de base + case MatrixType_Projection: + case MatrixType_View: + case MatrixType_World: + s_matrices[type].updated = true; + break; + + // Matrices combinées + case MatrixType_ViewProj: + s_matrices[MatrixType_ViewProj].matrix = s_matrices[MatrixType_View].matrix; + s_matrices[MatrixType_ViewProj].matrix.Concatenate(s_matrices[MatrixType_Projection].matrix); + s_matrices[MatrixType_ViewProj].updated = true; + break; + + case MatrixType_WorldView: + s_matrices[MatrixType_WorldView].matrix = s_matrices[MatrixType_World].matrix; + s_matrices[MatrixType_WorldView].matrix.ConcatenateAffine(s_matrices[MatrixType_View].matrix); + s_matrices[MatrixType_WorldView].updated = true; + break; + + case MatrixType_WorldViewProj: + if (!s_matrices[MatrixType_WorldView].updated) + UpdateMatrix(MatrixType_WorldView); + + s_matrices[MatrixType_WorldViewProj].matrix = s_matrices[MatrixType_WorldView].matrix; + s_matrices[MatrixType_WorldViewProj].matrix.Concatenate(s_matrices[MatrixType_Projection].matrix); + s_matrices[MatrixType_WorldViewProj].updated = true; + break; + + // Matrices inversées + case MatrixType_InvProjection: + if (!s_matrices[MatrixType_Projection].updated) + UpdateMatrix(MatrixType_Projection); + + if (!s_matrices[MatrixType_Projection].matrix.GetInverse(&s_matrices[MatrixType_InvProjection].matrix)) + NazaraWarning("Failed to inverse Proj matrix"); + + s_matrices[MatrixType_InvProjection].updated = true; + break; + + case MatrixType_InvView: + if (!s_matrices[MatrixType_View].updated) + UpdateMatrix(MatrixType_View); + + if (!s_matrices[MatrixType_View].matrix.GetInverse(&s_matrices[MatrixType_InvView].matrix)) + NazaraWarning("Failed to inverse View matrix"); + + s_matrices[MatrixType_InvView].updated = true; + break; + + case MatrixType_InvViewProj: + if (!s_matrices[MatrixType_ViewProj].updated) + UpdateMatrix(MatrixType_ViewProj); + + if (!s_matrices[MatrixType_ViewProj].matrix.GetInverse(&s_matrices[MatrixType_InvViewProj].matrix)) + NazaraWarning("Failed to inverse ViewProj matrix"); + + s_matrices[MatrixType_InvViewProj].updated = true; + break; + + case MatrixType_InvWorld: + if (!s_matrices[MatrixType_World].updated) + UpdateMatrix(MatrixType_World); + + if (!s_matrices[MatrixType_World].matrix.GetInverse(&s_matrices[MatrixType_InvWorld].matrix)) + NazaraWarning("Failed to inverse World matrix"); + + s_matrices[MatrixType_InvWorld].updated = true; + break; + + case MatrixType_InvWorldView: + if (!s_matrices[MatrixType_WorldView].updated) + UpdateMatrix(MatrixType_WorldView); + + if (!s_matrices[MatrixType_WorldView].matrix.GetInverse(&s_matrices[MatrixType_InvWorldView].matrix)) + NazaraWarning("Failed to inverse WorldView matrix"); + + s_matrices[MatrixType_InvWorldView].updated = true; + break; + + case MatrixType_InvWorldViewProj: + if (!s_matrices[MatrixType_WorldViewProj].updated) + UpdateMatrix(MatrixType_WorldViewProj); + + if (!s_matrices[MatrixType_WorldViewProj].matrix.GetInverse(&s_matrices[MatrixType_InvWorldViewProj].matrix)) + NazaraWarning("Failed to inverse WorldViewProj matrix"); + + s_matrices[MatrixType_InvWorldViewProj].updated = true; + break; + } + } + + unsigned int Renderer::s_moduleReferenceCounter = 0; +} diff --git a/src/Nazara/Renderer/Shader.cpp b/src/Nazara/Renderer/Shader.cpp index f09bbea8b..fbf8d9cfa 100644 --- a/src/Nazara/Renderer/Shader.cpp +++ b/src/Nazara/Renderer/Shader.cpp @@ -10,807 +10,810 @@ #include #include -NzShader::NzShader() : -m_linked(false), -m_program(0) +namespace Nz { -} - -NzShader::~NzShader() -{ - OnShaderRelease(this); - - Destroy(); -} - -void NzShader::AttachStage(nzShaderStage stage, const NzShaderStage& shaderStage) -{ - #if NAZARA_RENDERER_SAFE - if (!m_program) + Shader::Shader() : + m_linked(false), + m_program(0) { - NazaraError("Invalid program"); - return; } - if (!shaderStage.IsValid()) + Shader::~Shader() { - NazaraError("Invalid shader stage"); - return; + OnShaderRelease(this); + + Destroy(); } - if (!shaderStage.IsCompiled()) + void Shader::AttachStage(ShaderStageType stage, const ShaderStage& shaderStage) { - NazaraError("Shader stage must be compiled"); - return; - } - #endif - - unsigned int shader = shaderStage.GetOpenGLID(); - - #if NAZARA_RENDERER_SAFE - if (std::find(m_attachedShaders[stage].begin(), m_attachedShaders[stage].end(), shader) != m_attachedShaders[stage].end()) - { - NazaraError("Shader stage is already attached"); - return; - } - #endif - - glAttachShader(m_program, shader); - m_attachedShaders[stage].push_back(shader); -} - -bool NzShader::AttachStageFromFile(nzShaderStage stage, const NzString& filePath) -{ - NzShaderStage shaderStage(stage); - if (!shaderStage.IsValid()) - { - NazaraError("Failed to create shader stage"); - return false; - } - - shaderStage.SetSourceFromFile(filePath); - - if (!shaderStage.Compile()) - { - NazaraError("Failed to compile stage: " + shaderStage.GetLog()); - return false; - } - - AttachStage(stage, shaderStage); - return true; -} - -bool NzShader::AttachStageFromSource(nzShaderStage stage, const char* source, unsigned int length) -{ - NzShaderStage shaderStage(stage); - if (!shaderStage.IsValid()) - { - NazaraError("Failed to create shader stage"); - return false; - } - - shaderStage.SetSource(source, length); - - if (!shaderStage.Compile()) - { - NazaraError("Failed to compile stage: " + shaderStage.GetLog()); - return false; - } - - AttachStage(stage, shaderStage); - return true; -} - -bool NzShader::AttachStageFromSource(nzShaderStage stage, const NzString& source) -{ - NzShaderStage shaderStage(stage); - if (!shaderStage.IsValid()) - { - NazaraError("Failed to create shader stage"); - return false; - } - - shaderStage.SetSource(source); - - if (!shaderStage.Compile()) - { - NazaraError("Failed to compile stage: " + shaderStage.GetLog()); - return false; - } - - AttachStage(stage, shaderStage); - return true; -} - -void NzShader::Bind() const -{ - NzOpenGL::BindProgram(m_program); -} - -bool NzShader::Create() -{ - NzContext::EnsureContext(); - - m_program = glCreateProgram(); - if (!m_program) - { - NazaraError("Failed to create program"); - return false; - } - - m_linked = false; - - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData0], "InstanceData0"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData1], "InstanceData1"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData2], "InstanceData2"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData3], "InstanceData3"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData4], "InstanceData4"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_InstanceData5], "InstanceData5"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Color], "VertexColor"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Normal], "VertexNormal"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Position], "VertexPosition"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Tangent], "VertexTangent"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_TexCoord], "VertexTexCoord"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata0], "VertexUserdata0"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata1], "VertexUserdata1"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata2], "VertexUserdata2"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata3], "VertexUserdata3"); - glBindAttribLocation(m_program, NzOpenGL::VertexComponentIndex[nzVertexComponent_Userdata4], "VertexUserdata4"); - - if (NzRenderer::HasCapability(nzRendererCap_MultipleRenderTargets)) - { - NzString uniform; - uniform = "RenderTarget"; - - unsigned int maxRenderTargets = NzRenderer::GetMaxRenderTargets(); - for (unsigned int i = 0; i < maxRenderTargets; ++i) + #if NAZARA_RENDERER_SAFE + if (!m_program) { - NzString uniformName = uniform + NzString::Number(i); - glBindFragDataLocation(m_program, i, uniformName.GetConstBuffer()); - } - } - - if (NzOpenGL::IsSupported(nzOpenGLExtension_GetProgramBinary)) - glProgramParameteri(m_program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); - - return true; -} - -void NzShader::Destroy() -{ - if (m_program) - { - OnShaderDestroy(this); - - NzContext::EnsureContext(); - NzOpenGL::DeleteProgram(m_program); - m_program = 0; - } -} - -NzByteArray NzShader::GetBinary() const -{ - NzByteArray byteArray; - - NzContext::EnsureContext(); - - GLint binaryLength = 0; - glGetProgramiv(m_program, GL_PROGRAM_BINARY_LENGTH, &binaryLength); - - if (binaryLength > 0) - { - byteArray.Reserve(sizeof(nzUInt64) + binaryLength); - - nzUInt8* buffer = byteArray.GetBuffer(); - - GLenum binaryFormat; - glGetProgramBinary(m_program, binaryLength, nullptr, &binaryFormat, &buffer[sizeof(nzUInt64)]); - - // On stocke le format au début du binaire - *reinterpret_cast(&buffer[0]) = binaryFormat; - } - - return byteArray; -} - -NzString NzShader::GetLog() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_program) - { - NazaraError("Shader is not initialized"); - return NzString(); - } - #endif - - NzString log; - - GLint length = 0; - glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &length); - if (length > 1) // Le caractère de fin faisant partie du compte - { - log.Set(length - 1, '\0'); // La taille retournée est celle du buffer (Avec caractère de fin) - glGetProgramInfoLog(m_program, length, nullptr, &log[0]); - } - else - log = "No log."; - - return log; -} - -NzString NzShader::GetSourceCode(nzShaderStage stage) const -{ - if (!HasStage(stage)) - return NzString(); - - NzContext::EnsureContext(); - - static const char sep[] = "\n////////////////////////////////////////////////////////////////////////////////\n\n"; - - unsigned int totalLength = 0; - for (unsigned int shader : m_attachedShaders[stage]) - { - GLint length; - glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &length); - - totalLength += length - 1; - } - - totalLength += (m_attachedShaders[stage].size()-1) * (sizeof(sep)/sizeof(char)); - - NzString source(totalLength, '\0'); - - unsigned int offset = 0; - for (unsigned int shader : m_attachedShaders[stage]) - { - if (offset > 0) - { - std::memcpy(&source[offset], sep, sizeof(sep)); - offset += sizeof(sep)/sizeof(char); + NazaraError("Invalid program"); + return; } - GLint length; - glGetShaderSource(shader, totalLength, &length, &source[offset]); + if (!shaderStage.IsValid()) + { + NazaraError("Invalid shader stage"); + return; + } - offset += length; + if (!shaderStage.IsCompiled()) + { + NazaraError("Shader stage must be compiled"); + return; + } + #endif + + unsigned int shader = shaderStage.GetOpenGLID(); + + #if NAZARA_RENDERER_SAFE + if (std::find(m_attachedShaders[stage].begin(), m_attachedShaders[stage].end(), shader) != m_attachedShaders[stage].end()) + { + NazaraError("Shader stage is already attached"); + return; + } + #endif + + glAttachShader(m_program, shader); + m_attachedShaders[stage].push_back(shader); } - return source; -} - -int NzShader::GetUniformLocation(const NzString& name) const -{ - NzContext::EnsureContext(); - - return glGetUniformLocation(m_program, name.GetConstBuffer()); -} - -int NzShader::GetUniformLocation(nzShaderUniform shaderUniform) const -{ - return m_uniformLocations[shaderUniform]; -} - -bool NzShader::HasStage(nzShaderStage stage) const -{ - return !m_attachedShaders[stage].empty(); -} - -bool NzShader::IsBinaryRetrievable() const -{ - return NzOpenGL::IsSupported(nzOpenGLExtension_GetProgramBinary); -} - -bool NzShader::IsLinked() const -{ - return m_linked; -} - -bool NzShader::IsValid() const -{ - return m_program != 0; -} - -bool NzShader::Link() -{ - NzContext::EnsureContext(); - - glLinkProgram(m_program); - - return PostLinkage(); -} - -bool NzShader::LoadFromBinary(const void* buffer, unsigned int size) -{ - #if NAZARA_RENDERER_SAFE - if (!glProgramBinary) + bool Shader::AttachStageFromFile(ShaderStageType stage, const String& filePath) { - NazaraError("GL_ARB_get_program_binary not supported"); - return false; + ShaderStage shaderStage(stage); + if (!shaderStage.IsValid()) + { + NazaraError("Failed to create shader stage"); + return false; + } + + shaderStage.SetSourceFromFile(filePath); + + if (!shaderStage.Compile()) + { + NazaraError("Failed to compile stage: " + shaderStage.GetLog()); + return false; + } + + AttachStage(stage, shaderStage); + return true; } - if (!buffer || size < sizeof(nzUInt64)) + bool Shader::AttachStageFromSource(ShaderStageType stage, const char* source, unsigned int length) { - NazaraError("Invalid buffer"); - return false; + ShaderStage shaderStage(stage); + if (!shaderStage.IsValid()) + { + NazaraError("Failed to create shader stage"); + return false; + } + + shaderStage.SetSource(source, length); + + if (!shaderStage.Compile()) + { + NazaraError("Failed to compile stage: " + shaderStage.GetLog()); + return false; + } + + AttachStage(stage, shaderStage); + return true; } - #endif - NzContext::EnsureContext(); - - const nzUInt8* ptr = reinterpret_cast(buffer); - - // On récupère le format au début du binaire - ///TODO: ByteStream ? - GLenum binaryFormat = static_cast(*reinterpret_cast(&ptr[0])); - ptr += sizeof(nzUInt64); - - glProgramBinary(m_program, binaryFormat, ptr, size - sizeof(nzUInt64)); - - return PostLinkage(); -} - -bool NzShader::LoadFromBinary(const NzByteArray& byteArray) -{ - return LoadFromBinary(byteArray.GetConstBuffer(), byteArray.GetSize()); -} - -void NzShader::SendBoolean(int location, bool value) const -{ - if (location == -1) - return; - - if (glProgramUniform1i) - glProgramUniform1i(m_program, location, value); - else + bool Shader::AttachStageFromSource(ShaderStageType stage, const String& source) { - NzOpenGL::BindProgram(m_program); - glUniform1i(location, value); + ShaderStage shaderStage(stage); + if (!shaderStage.IsValid()) + { + NazaraError("Failed to create shader stage"); + return false; + } + + shaderStage.SetSource(source); + + if (!shaderStage.Compile()) + { + NazaraError("Failed to compile stage: " + shaderStage.GetLog()); + return false; + } + + AttachStage(stage, shaderStage); + return true; } -} -void NzShader::SendColor(int location, const NzColor& color) const -{ - if (location == -1) - return; - - NzVector4f vecColor(color.r/255.f, color.g/255.f, color.b/255.f, color.a/255.f); - - if (glProgramUniform4fv) - glProgramUniform4fv(m_program, location, 1, vecColor); - else + void Shader::Bind() const { - NzOpenGL::BindProgram(m_program); - glUniform4fv(location, 1, vecColor); + OpenGL::BindProgram(m_program); } -} -void NzShader::SendDouble(int location, double value) const -{ - if (location == -1) - return; - - if (glProgramUniform1d) - glProgramUniform1d(m_program, location, value); - else + bool Shader::Create() { - NzOpenGL::BindProgram(m_program); - glUniform1d(location, value); - } -} + Context::EnsureContext(); -void NzShader::SendDoubleArray(int location, const double* values, unsigned int count) const -{ - if (location == -1) - return; + m_program = glCreateProgram(); + if (!m_program) + { + NazaraError("Failed to create program"); + return false; + } - if (glProgramUniform1dv) - glProgramUniform1dv(m_program, location, count, values); - else - { - NzOpenGL::BindProgram(m_program); - glUniform1dv(location, count, values); - } -} + m_linked = false; -void NzShader::SendFloat(int location, float value) const -{ - if (location == -1) - return; + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_InstanceData0], "InstanceData0"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_InstanceData1], "InstanceData1"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_InstanceData2], "InstanceData2"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_InstanceData3], "InstanceData3"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_InstanceData4], "InstanceData4"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_InstanceData5], "InstanceData5"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_Color], "VertexColor"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_Normal], "VertexNormal"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_Position], "VertexPosition"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_Tangent], "VertexTangent"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_TexCoord], "VertexTexCoord"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_Userdata0], "VertexUserdata0"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_Userdata1], "VertexUserdata1"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_Userdata2], "VertexUserdata2"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_Userdata3], "VertexUserdata3"); + glBindAttribLocation(m_program, OpenGL::VertexComponentIndex[VertexComponent_Userdata4], "VertexUserdata4"); - if (glProgramUniform1f) - glProgramUniform1f(m_program, location, value); - else - { - NzOpenGL::BindProgram(m_program); - glUniform1f(location, value); - } -} + if (Renderer::HasCapability(RendererCap_MultipleRenderTargets)) + { + String uniform; + uniform = "RenderTarget"; -void NzShader::SendFloatArray(int location, const float* values, unsigned int count) const -{ - if (location == -1) - return; + unsigned int maxRenderTargets = Renderer::GetMaxRenderTargets(); + for (unsigned int i = 0; i < maxRenderTargets; ++i) + { + String uniformName = uniform + String::Number(i); + glBindFragDataLocation(m_program, i, uniformName.GetConstBuffer()); + } + } - if (glProgramUniform1fv) - glProgramUniform1fv(m_program, location, count, values); - else - { - NzOpenGL::BindProgram(m_program); - glUniform1fv(location, count, values); - } -} - -void NzShader::SendInteger(int location, int value) const -{ - if (location == -1) - return; - - if (glProgramUniform1i) - glProgramUniform1i(m_program, location, value); - else - { - NzOpenGL::BindProgram(m_program); - glUniform1i(location, value); - } -} - -void NzShader::SendIntegerArray(int location, const int* values, unsigned int count) const -{ - if (location == -1) - return; - - if (glProgramUniform1iv) - glProgramUniform1iv(m_program, location, count, values); - else - { - NzOpenGL::BindProgram(m_program); - glUniform1iv(location, count, values); - } -} - -void NzShader::SendMatrix(int location, const NzMatrix4d& matrix) const -{ - if (location == -1) - return; - - if (glProgramUniformMatrix4dv) - glProgramUniformMatrix4dv(m_program, location, 1, GL_FALSE, matrix); - else - { - NzOpenGL::BindProgram(m_program); - glUniformMatrix4dv(location, 1, GL_FALSE, matrix); - } -} - -void NzShader::SendMatrix(int location, const NzMatrix4f& matrix) const -{ - if (location == -1) - return; - - if (glProgramUniformMatrix4fv) - glProgramUniformMatrix4fv(m_program, location, 1, GL_FALSE, matrix); - else - { - NzOpenGL::BindProgram(m_program); - glUniformMatrix4fv(location, 1, GL_FALSE, matrix); - } -} - -void NzShader::SendVector(int location, const NzVector2d& vector) const -{ - if (location == -1) - return; - - if (glProgramUniform2dv) - glProgramUniform2dv(m_program, location, 1, vector); - else - { - NzOpenGL::BindProgram(m_program); - glUniform2dv(location, 1, vector); - } -} - -void NzShader::SendVector(int location, const NzVector2f& vector) const -{ - if (location == -1) - return; - - if (glProgramUniform2fv) - glProgramUniform2fv(m_program, location, 1, vector); - else - { - NzOpenGL::BindProgram(m_program); - glUniform2fv(location, 1, vector); - } -} - -void NzShader::SendVector(int location, const NzVector2i& vector) const -{ - if (location == -1) - return; - - if (glProgramUniform2fv) - glProgramUniform2iv(m_program, location, 1, vector); - else - { - NzOpenGL::BindProgram(m_program); - glUniform2iv(location, 1, vector); - } -} - -void NzShader::SendVector(int location, const NzVector3d& vector) const -{ - if (location == -1) - return; - - if (glProgramUniform3dv) - glProgramUniform3dv(m_program, location, 1, vector); - else - { - NzOpenGL::BindProgram(m_program); - glUniform3dv(location, 1, vector); - } -} - -void NzShader::SendVector(int location, const NzVector3f& vector) const -{ - if (location == -1) - return; - - if (glProgramUniform3fv) - glProgramUniform3fv(m_program, location, 1, vector); - else - { - NzOpenGL::BindProgram(m_program); - glUniform3fv(location, 1, vector); - } -} - -void NzShader::SendVector(int location, const NzVector3i& vector) const -{ - if (location == -1) - return; - - if (glProgramUniform3iv) - glProgramUniform3iv(m_program, location, 1, vector); - else - { - NzOpenGL::BindProgram(m_program); - glUniform3iv(location, 1, vector); - } -} - -void NzShader::SendVector(int location, const NzVector4d& vector) const -{ - if (location == -1) - return; - - if (glProgramUniform4dv) - glProgramUniform4dv(m_program, location, 1, vector); - else - { - NzOpenGL::BindProgram(m_program); - glUniform4dv(location, 1, vector); - } -} - -void NzShader::SendVector(int location, const NzVector4f& vector) const -{ - if (location == -1) - return; - - if (glProgramUniform4fv) - glProgramUniform4fv(m_program, location, 1, vector); - else - { - NzOpenGL::BindProgram(m_program); - glUniform4fv(location, 1, vector); - } -} - -void NzShader::SendVector(int location, const NzVector4i& vector) const -{ - if (location == -1) - return; - - if (glProgramUniform4iv) - glProgramUniform4iv(m_program, location, 1, vector); - else - { - NzOpenGL::BindProgram(m_program); - glUniform4iv(location, 1, vector); - } -} - -void NzShader::SendVectorArray(int location, const NzVector2d* vectors, unsigned int count) const -{ - if (location == -1) - return; - - if (glProgramUniform2dv) - glProgramUniform2dv(m_program, location, count, reinterpret_cast(vectors)); - else - { - NzOpenGL::BindProgram(m_program); - glUniform2dv(location, count, reinterpret_cast(vectors)); - } -} - -void NzShader::SendVectorArray(int location, const NzVector2f* vectors, unsigned int count) const -{ - if (location == -1) - return; - - if (glProgramUniform2fv) - glProgramUniform2fv(m_program, location, count, reinterpret_cast(vectors)); - else - { - NzOpenGL::BindProgram(m_program); - glUniform2fv(location, count, reinterpret_cast(vectors)); - } -} - -void NzShader::SendVectorArray(int location, const NzVector2i* vectors, unsigned int count) const -{ - if (location == -1) - return; - - if (glProgramUniform2iv) - glProgramUniform2iv(m_program, location, count, reinterpret_cast(vectors)); - else - { - NzOpenGL::BindProgram(m_program); - glUniform2iv(location, count, reinterpret_cast(vectors)); - } -} - -void NzShader::SendVectorArray(int location, const NzVector3d* vectors, unsigned int count) const -{ - if (location == -1) - return; - - if (glProgramUniform3dv) - glProgramUniform3dv(m_program, location, count, reinterpret_cast(vectors)); - else - { - NzOpenGL::BindProgram(m_program); - glUniform3dv(location, count, reinterpret_cast(vectors)); - } -} - -void NzShader::SendVectorArray(int location, const NzVector3f* vectors, unsigned int count) const -{ - if (location == -1) - return; - - if (glProgramUniform3fv) - glProgramUniform3fv(m_program, location, count, reinterpret_cast(vectors)); - else - { - NzOpenGL::BindProgram(m_program); - glUniform3fv(location, count, reinterpret_cast(vectors)); - } -} - -void NzShader::SendVectorArray(int location, const NzVector3i* vectors, unsigned int count) const -{ - if (location == -1) - return; - - if (glProgramUniform3iv) - glProgramUniform3iv(m_program, location, count, reinterpret_cast(vectors)); - else - { - NzOpenGL::BindProgram(m_program); - glUniform3iv(location, count, reinterpret_cast(vectors)); - } -} - -void NzShader::SendVectorArray(int location, const NzVector4d* vectors, unsigned int count) const -{ - if (location == -1) - return; - - if (glProgramUniform4dv) - glProgramUniform4dv(m_program, location, count, reinterpret_cast(vectors)); - else - { - NzOpenGL::BindProgram(m_program); - glUniform4dv(location, count, reinterpret_cast(vectors)); - } -} - -void NzShader::SendVectorArray(int location, const NzVector4f* vectors, unsigned int count) const -{ - if (location == -1) - return; - - if (glProgramUniform4fv) - glProgramUniform4fv(m_program, location, count, reinterpret_cast(vectors)); - else - { - NzOpenGL::BindProgram(m_program); - glUniform4fv(location, count, reinterpret_cast(vectors)); - } -} - -void NzShader::SendVectorArray(int location, const NzVector4i* vectors, unsigned int count) const -{ - if (location == -1) - return; - - if (glProgramUniform4iv) - glProgramUniform4iv(m_program, location, count, reinterpret_cast(vectors)); - else - { - NzOpenGL::BindProgram(m_program); - glUniform4iv(location, count, reinterpret_cast(vectors)); - } -} - -unsigned int NzShader::GetOpenGLID() const -{ - return m_program; -} - -bool NzShader::IsStageSupported(nzShaderStage stage) -{ - return NzShaderStage::IsSupported(stage); -} - -bool NzShader::PostLinkage() -{ - GLint success; - glGetProgramiv(m_program, GL_LINK_STATUS, &success); - - m_linked = (success == GL_TRUE); - if (m_linked) - { - // Pour éviter de se tromper entre le nom et la constante - #define CacheUniform(name) m_uniformLocations[nzShaderUniform_##name] = glGetUniformLocation(m_program, #name) - - CacheUniform(InvProjMatrix); - CacheUniform(InvTargetSize); - CacheUniform(InvViewMatrix); - CacheUniform(InvViewProjMatrix); - CacheUniform(InvWorldMatrix); - CacheUniform(InvWorldViewMatrix); - CacheUniform(InvWorldViewProjMatrix); - CacheUniform(ProjMatrix); - CacheUniform(TargetSize); - CacheUniform(ViewMatrix); - CacheUniform(ViewProjMatrix); - CacheUniform(WorldMatrix); - CacheUniform(WorldViewMatrix); - CacheUniform(WorldViewProjMatrix); - - #undef CacheUniform - - OnShaderUniformInvalidated(this); + if (OpenGL::IsSupported(OpenGLExtension_GetProgramBinary)) + glProgramParameteri(m_program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE); return true; } - else - { - NazaraError("Failed to link shader: " + GetLog()); - return false; - } -} -bool NzShader::Initialize() -{ - if (!NzShaderLibrary::Initialize()) + void Shader::Destroy() { - NazaraError("Failed to initialise library"); - return false; + if (m_program) + { + OnShaderDestroy(this); + + Context::EnsureContext(); + OpenGL::DeleteProgram(m_program); + m_program = 0; + } } - return true; -} + ByteArray Shader::GetBinary() const + { + ByteArray byteArray; -void NzShader::Uninitialize() -{ - NzShaderLibrary::Uninitialize(); -} + Context::EnsureContext(); -NzShaderLibrary::LibraryMap NzShader::s_library; + GLint binaryLength = 0; + glGetProgramiv(m_program, GL_PROGRAM_BINARY_LENGTH, &binaryLength); + + if (binaryLength > 0) + { + byteArray.Reserve(sizeof(UInt64) + binaryLength); + + UInt8* buffer = byteArray.GetBuffer(); + + GLenum binaryFormat; + glGetProgramBinary(m_program, binaryLength, nullptr, &binaryFormat, &buffer[sizeof(UInt64)]); + + // On stocke le format au début du binaire + *reinterpret_cast(&buffer[0]) = binaryFormat; + } + + return byteArray; + } + + String Shader::GetLog() const + { + #if NAZARA_RENDERER_SAFE + if (!m_program) + { + NazaraError("Shader is not initialized"); + return String(); + } + #endif + + String log; + + GLint length = 0; + glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &length); + if (length > 1) // Le caractère de fin faisant partie du compte + { + log.Set(length - 1, '\0'); // La taille retournée est celle du buffer (Avec caractère de fin) + glGetProgramInfoLog(m_program, length, nullptr, &log[0]); + } + else + log = "No log."; + + return log; + } + + String Shader::GetSourceCode(ShaderStageType stage) const + { + if (!HasStage(stage)) + return String(); + + Context::EnsureContext(); + + static const char sep[] = "\n////////////////////////////////////////////////////////////////////////////////\n\n"; + + unsigned int totalLength = 0; + for (unsigned int shader : m_attachedShaders[stage]) + { + GLint length; + glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &length); + + totalLength += length - 1; + } + + totalLength += (m_attachedShaders[stage].size()-1) * (sizeof(sep)/sizeof(char)); + + String source(totalLength, '\0'); + + unsigned int offset = 0; + for (unsigned int shader : m_attachedShaders[stage]) + { + if (offset > 0) + { + std::memcpy(&source[offset], sep, sizeof(sep)); + offset += sizeof(sep)/sizeof(char); + } + + GLint length; + glGetShaderSource(shader, totalLength, &length, &source[offset]); + + offset += length; + } + + return source; + } + + int Shader::GetUniformLocation(const String& name) const + { + Context::EnsureContext(); + + return glGetUniformLocation(m_program, name.GetConstBuffer()); + } + + int Shader::GetUniformLocation(ShaderUniform shaderUniform) const + { + return m_uniformLocations[shaderUniform]; + } + + bool Shader::HasStage(ShaderStageType stage) const + { + return !m_attachedShaders[stage].empty(); + } + + bool Shader::IsBinaryRetrievable() const + { + return OpenGL::IsSupported(OpenGLExtension_GetProgramBinary); + } + + bool Shader::IsLinked() const + { + return m_linked; + } + + bool Shader::IsValid() const + { + return m_program != 0; + } + + bool Shader::Link() + { + Context::EnsureContext(); + + glLinkProgram(m_program); + + return PostLinkage(); + } + + bool Shader::LoadFromBinary(const void* buffer, unsigned int size) + { + #if NAZARA_RENDERER_SAFE + if (!glProgramBinary) + { + NazaraError("GL_ARB_get_program_binary not supported"); + return false; + } + + if (!buffer || size < sizeof(UInt64)) + { + NazaraError("Invalid buffer"); + return false; + } + #endif + + Context::EnsureContext(); + + const UInt8* ptr = reinterpret_cast(buffer); + + // On récupère le format au début du binaire + ///TODO: ByteStream ? + GLenum binaryFormat = static_cast(*reinterpret_cast(&ptr[0])); + ptr += sizeof(UInt64); + + glProgramBinary(m_program, binaryFormat, ptr, size - sizeof(UInt64)); + + return PostLinkage(); + } + + bool Shader::LoadFromBinary(const ByteArray& byteArray) + { + return LoadFromBinary(byteArray.GetConstBuffer(), byteArray.GetSize()); + } + + void Shader::SendBoolean(int location, bool value) const + { + if (location == -1) + return; + + if (glProgramUniform1i) + glProgramUniform1i(m_program, location, value); + else + { + OpenGL::BindProgram(m_program); + glUniform1i(location, value); + } + } + + void Shader::SendColor(int location, const Color& color) const + { + if (location == -1) + return; + + Vector4f vecColor(color.r/255.f, color.g/255.f, color.b/255.f, color.a/255.f); + + if (glProgramUniform4fv) + glProgramUniform4fv(m_program, location, 1, vecColor); + else + { + OpenGL::BindProgram(m_program); + glUniform4fv(location, 1, vecColor); + } + } + + void Shader::SendDouble(int location, double value) const + { + if (location == -1) + return; + + if (glProgramUniform1d) + glProgramUniform1d(m_program, location, value); + else + { + OpenGL::BindProgram(m_program); + glUniform1d(location, value); + } + } + + void Shader::SendDoubleArray(int location, const double* values, unsigned int count) const + { + if (location == -1) + return; + + if (glProgramUniform1dv) + glProgramUniform1dv(m_program, location, count, values); + else + { + OpenGL::BindProgram(m_program); + glUniform1dv(location, count, values); + } + } + + void Shader::SendFloat(int location, float value) const + { + if (location == -1) + return; + + if (glProgramUniform1f) + glProgramUniform1f(m_program, location, value); + else + { + OpenGL::BindProgram(m_program); + glUniform1f(location, value); + } + } + + void Shader::SendFloatArray(int location, const float* values, unsigned int count) const + { + if (location == -1) + return; + + if (glProgramUniform1fv) + glProgramUniform1fv(m_program, location, count, values); + else + { + OpenGL::BindProgram(m_program); + glUniform1fv(location, count, values); + } + } + + void Shader::SendInteger(int location, int value) const + { + if (location == -1) + return; + + if (glProgramUniform1i) + glProgramUniform1i(m_program, location, value); + else + { + OpenGL::BindProgram(m_program); + glUniform1i(location, value); + } + } + + void Shader::SendIntegerArray(int location, const int* values, unsigned int count) const + { + if (location == -1) + return; + + if (glProgramUniform1iv) + glProgramUniform1iv(m_program, location, count, values); + else + { + OpenGL::BindProgram(m_program); + glUniform1iv(location, count, values); + } + } + + void Shader::SendMatrix(int location, const Matrix4d& matrix) const + { + if (location == -1) + return; + + if (glProgramUniformMatrix4dv) + glProgramUniformMatrix4dv(m_program, location, 1, GL_FALSE, matrix); + else + { + OpenGL::BindProgram(m_program); + glUniformMatrix4dv(location, 1, GL_FALSE, matrix); + } + } + + void Shader::SendMatrix(int location, const Matrix4f& matrix) const + { + if (location == -1) + return; + + if (glProgramUniformMatrix4fv) + glProgramUniformMatrix4fv(m_program, location, 1, GL_FALSE, matrix); + else + { + OpenGL::BindProgram(m_program); + glUniformMatrix4fv(location, 1, GL_FALSE, matrix); + } + } + + void Shader::SendVector(int location, const Vector2d& vector) const + { + if (location == -1) + return; + + if (glProgramUniform2dv) + glProgramUniform2dv(m_program, location, 1, vector); + else + { + OpenGL::BindProgram(m_program); + glUniform2dv(location, 1, vector); + } + } + + void Shader::SendVector(int location, const Vector2f& vector) const + { + if (location == -1) + return; + + if (glProgramUniform2fv) + glProgramUniform2fv(m_program, location, 1, vector); + else + { + OpenGL::BindProgram(m_program); + glUniform2fv(location, 1, vector); + } + } + + void Shader::SendVector(int location, const Vector2i& vector) const + { + if (location == -1) + return; + + if (glProgramUniform2fv) + glProgramUniform2iv(m_program, location, 1, vector); + else + { + OpenGL::BindProgram(m_program); + glUniform2iv(location, 1, vector); + } + } + + void Shader::SendVector(int location, const Vector3d& vector) const + { + if (location == -1) + return; + + if (glProgramUniform3dv) + glProgramUniform3dv(m_program, location, 1, vector); + else + { + OpenGL::BindProgram(m_program); + glUniform3dv(location, 1, vector); + } + } + + void Shader::SendVector(int location, const Vector3f& vector) const + { + if (location == -1) + return; + + if (glProgramUniform3fv) + glProgramUniform3fv(m_program, location, 1, vector); + else + { + OpenGL::BindProgram(m_program); + glUniform3fv(location, 1, vector); + } + } + + void Shader::SendVector(int location, const Vector3i& vector) const + { + if (location == -1) + return; + + if (glProgramUniform3iv) + glProgramUniform3iv(m_program, location, 1, vector); + else + { + OpenGL::BindProgram(m_program); + glUniform3iv(location, 1, vector); + } + } + + void Shader::SendVector(int location, const Vector4d& vector) const + { + if (location == -1) + return; + + if (glProgramUniform4dv) + glProgramUniform4dv(m_program, location, 1, vector); + else + { + OpenGL::BindProgram(m_program); + glUniform4dv(location, 1, vector); + } + } + + void Shader::SendVector(int location, const Vector4f& vector) const + { + if (location == -1) + return; + + if (glProgramUniform4fv) + glProgramUniform4fv(m_program, location, 1, vector); + else + { + OpenGL::BindProgram(m_program); + glUniform4fv(location, 1, vector); + } + } + + void Shader::SendVector(int location, const Vector4i& vector) const + { + if (location == -1) + return; + + if (glProgramUniform4iv) + glProgramUniform4iv(m_program, location, 1, vector); + else + { + OpenGL::BindProgram(m_program); + glUniform4iv(location, 1, vector); + } + } + + void Shader::SendVectorArray(int location, const Vector2d* vectors, unsigned int count) const + { + if (location == -1) + return; + + if (glProgramUniform2dv) + glProgramUniform2dv(m_program, location, count, reinterpret_cast(vectors)); + else + { + OpenGL::BindProgram(m_program); + glUniform2dv(location, count, reinterpret_cast(vectors)); + } + } + + void Shader::SendVectorArray(int location, const Vector2f* vectors, unsigned int count) const + { + if (location == -1) + return; + + if (glProgramUniform2fv) + glProgramUniform2fv(m_program, location, count, reinterpret_cast(vectors)); + else + { + OpenGL::BindProgram(m_program); + glUniform2fv(location, count, reinterpret_cast(vectors)); + } + } + + void Shader::SendVectorArray(int location, const Vector2i* vectors, unsigned int count) const + { + if (location == -1) + return; + + if (glProgramUniform2iv) + glProgramUniform2iv(m_program, location, count, reinterpret_cast(vectors)); + else + { + OpenGL::BindProgram(m_program); + glUniform2iv(location, count, reinterpret_cast(vectors)); + } + } + + void Shader::SendVectorArray(int location, const Vector3d* vectors, unsigned int count) const + { + if (location == -1) + return; + + if (glProgramUniform3dv) + glProgramUniform3dv(m_program, location, count, reinterpret_cast(vectors)); + else + { + OpenGL::BindProgram(m_program); + glUniform3dv(location, count, reinterpret_cast(vectors)); + } + } + + void Shader::SendVectorArray(int location, const Vector3f* vectors, unsigned int count) const + { + if (location == -1) + return; + + if (glProgramUniform3fv) + glProgramUniform3fv(m_program, location, count, reinterpret_cast(vectors)); + else + { + OpenGL::BindProgram(m_program); + glUniform3fv(location, count, reinterpret_cast(vectors)); + } + } + + void Shader::SendVectorArray(int location, const Vector3i* vectors, unsigned int count) const + { + if (location == -1) + return; + + if (glProgramUniform3iv) + glProgramUniform3iv(m_program, location, count, reinterpret_cast(vectors)); + else + { + OpenGL::BindProgram(m_program); + glUniform3iv(location, count, reinterpret_cast(vectors)); + } + } + + void Shader::SendVectorArray(int location, const Vector4d* vectors, unsigned int count) const + { + if (location == -1) + return; + + if (glProgramUniform4dv) + glProgramUniform4dv(m_program, location, count, reinterpret_cast(vectors)); + else + { + OpenGL::BindProgram(m_program); + glUniform4dv(location, count, reinterpret_cast(vectors)); + } + } + + void Shader::SendVectorArray(int location, const Vector4f* vectors, unsigned int count) const + { + if (location == -1) + return; + + if (glProgramUniform4fv) + glProgramUniform4fv(m_program, location, count, reinterpret_cast(vectors)); + else + { + OpenGL::BindProgram(m_program); + glUniform4fv(location, count, reinterpret_cast(vectors)); + } + } + + void Shader::SendVectorArray(int location, const Vector4i* vectors, unsigned int count) const + { + if (location == -1) + return; + + if (glProgramUniform4iv) + glProgramUniform4iv(m_program, location, count, reinterpret_cast(vectors)); + else + { + OpenGL::BindProgram(m_program); + glUniform4iv(location, count, reinterpret_cast(vectors)); + } + } + + unsigned int Shader::GetOpenGLID() const + { + return m_program; + } + + bool Shader::IsStageSupported(ShaderStageType stage) + { + return ShaderStage::IsSupported(stage); + } + + bool Shader::PostLinkage() + { + GLint success; + glGetProgramiv(m_program, GL_LINK_STATUS, &success); + + m_linked = (success == GL_TRUE); + if (m_linked) + { + // Pour éviter de se tromper entre le nom et la constante + #define CacheUniform(name) m_uniformLocations[ShaderUniform_##name] = glGetUniformLocation(m_program, #name) + + CacheUniform(InvProjMatrix); + CacheUniform(InvTargetSize); + CacheUniform(InvViewMatrix); + CacheUniform(InvViewProjMatrix); + CacheUniform(InvWorldMatrix); + CacheUniform(InvWorldViewMatrix); + CacheUniform(InvWorldViewProjMatrix); + CacheUniform(ProjMatrix); + CacheUniform(TargetSize); + CacheUniform(ViewMatrix); + CacheUniform(ViewProjMatrix); + CacheUniform(WorldMatrix); + CacheUniform(WorldViewMatrix); + CacheUniform(WorldViewProjMatrix); + + #undef CacheUniform + + OnShaderUniformInvalidated(this); + + return true; + } + else + { + NazaraError("Failed to link shader: " + GetLog()); + return false; + } + } + + bool Shader::Initialize() + { + if (!ShaderLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } + + return true; + } + + void Shader::Uninitialize() + { + ShaderLibrary::Uninitialize(); + } + + ShaderLibrary::LibraryMap Shader::s_library; +} diff --git a/src/Nazara/Renderer/ShaderStage.cpp b/src/Nazara/Renderer/ShaderStage.cpp index 24b8248fb..a63dec34e 100644 --- a/src/Nazara/Renderer/ShaderStage.cpp +++ b/src/Nazara/Renderer/ShaderStage.cpp @@ -7,227 +7,230 @@ #include #include -NzShaderStage::NzShaderStage() : -m_compiled(false), -m_id(0) +namespace Nz { -} - -NzShaderStage::NzShaderStage(nzShaderStage stage) : -NzShaderStage() -{ - Create(stage); -} - -NzShaderStage::NzShaderStage(NzShaderStage&& stage) : -m_stage(stage.m_stage), -m_compiled(stage.m_compiled), -m_id(stage.m_id) -{ - stage.m_id = 0; -} - -NzShaderStage::~NzShaderStage() -{ - Destroy(); -} - -bool NzShaderStage::Compile() -{ - #if NAZARA_RENDERER_SAFE - if (!m_id) + ShaderStage::ShaderStage() : + m_compiled(false), + m_id(0) { - NazaraError("Shader stage is not initialized"); - return false; - } - #endif - - glCompileShader(m_id); - - GLint success; - glGetShaderiv(m_id, GL_COMPILE_STATUS, &success); - - m_compiled = (success == GL_TRUE); - if (m_compiled) - return true; - else - { - NazaraError("Failed to compile shader stage: " + GetLog()); - return false; - } -} - -bool NzShaderStage::Create(nzShaderStage stage) -{ - Destroy(); - - m_id = glCreateShader(NzOpenGL::ShaderStage[stage]); - m_stage = stage; - - return (m_id != 0); -} - -void NzShaderStage::Destroy() -{ - m_compiled = false; - if (m_id) - { - glDeleteShader(m_id); - m_id = 0; - } -} - -NzString NzShaderStage::GetLog() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_id) - { - NazaraError("Shader stage is not initialized"); - return NzString(); - } - #endif - - NzString log; - - GLint length = 0; - glGetShaderiv(m_id, GL_INFO_LOG_LENGTH, &length); - if (length > 1) // Le caractère de fin faisant partie du compte - { - log.Set(length - 1, '\0'); // La taille retournée est celle du buffer (Avec caractère de fin) - glGetShaderInfoLog(m_id, length, nullptr, &log[0]); - } - else - log = "No log."; - - return log; -} - -NzString NzShaderStage::GetSource() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_id) - { - NazaraError("Shader stage is not initialized"); - return NzString(); - } - #endif - - NzString source; - - GLint length = 0; - glGetShaderiv(m_id, GL_SHADER_SOURCE_LENGTH, &length); - if (length > 1) // Le caractère de fin compte - { - source.Set(length - 1, '\0'); // La taille retournée est celle du buffer (Avec caractère de fin) - glGetShaderSource(m_id, length, nullptr, &source[0]); } - return source; -} - -bool NzShaderStage::IsCompiled() const -{ - return m_compiled; -} - -bool NzShaderStage::IsValid() const -{ - return m_id != 0; -} - -void NzShaderStage::SetSource(const char* source, unsigned int length) -{ - #if NAZARA_RENDERER_SAFE - if (!m_id) + ShaderStage::ShaderStage(ShaderStageType stage) : + ShaderStage() { - NazaraError("Shader stage is not initialized"); - return; - } - #endif - - glShaderSource(m_id, 1, &source, reinterpret_cast(&length)); -} - -void NzShaderStage::SetSource(const NzString& source) -{ - #if NAZARA_RENDERER_SAFE - if (!m_id) - { - NazaraError("Shader stage is not initialized"); - return; - } - #endif - - const char* tmp = source.GetConstBuffer(); - GLint length = source.GetSize(); - glShaderSource(m_id, 1, &tmp, &length); -} - -bool NzShaderStage::SetSourceFromFile(const NzString& filePath) -{ - #if NAZARA_RENDERER_SAFE - if (!m_id) - { - NazaraError("Shader stage is not initialized"); - return false; - } - #endif - - NzFile file(filePath); - if (!file.Open(nzOpenMode_ReadOnly | nzOpenMode_Text)) - { - NazaraError("Failed to open \"" + filePath + '"'); - return false; + Create(stage); } - unsigned int length = static_cast(file.GetSize()); - - NzString source(length, '\0'); - - if (file.Read(&source[0], length) != length) + ShaderStage::ShaderStage(ShaderStage&& stage) : + m_stage(stage.m_stage), + m_compiled(stage.m_compiled), + m_id(stage.m_id) { - NazaraError("Failed to read program file"); - return false; + stage.m_id = 0; } - file.Close(); - - SetSource(source); - return true; -} - -NzShaderStage& NzShaderStage::operator=(NzShaderStage&& shader) -{ - Destroy(); - - m_compiled = shader.m_compiled; - m_id = shader.m_id; - m_stage = shader.m_stage; - - shader.m_id = 0; - - return *this; -} - -// Fonctions OpenGL -unsigned int NzShaderStage::GetOpenGLID() const -{ - return m_id; -} - -bool NzShaderStage::IsSupported(nzShaderStage stage) -{ - switch (stage) + ShaderStage::~ShaderStage() { - case nzShaderStage_Fragment: - case nzShaderStage_Vertex: - return true; + Destroy(); + } - case nzShaderStage_Geometry: - return NzOpenGL::GetVersion() >= 320; - - default: - NazaraError("Shader stage not handled (0x" + NzString::Number(stage, 16) + ')'); + bool ShaderStage::Compile() + { + #if NAZARA_RENDERER_SAFE + if (!m_id) + { + NazaraError("Shader stage is not initialized"); return false; + } + #endif + + glCompileShader(m_id); + + GLint success; + glGetShaderiv(m_id, GL_COMPILE_STATUS, &success); + + m_compiled = (success == GL_TRUE); + if (m_compiled) + return true; + else + { + NazaraError("Failed to compile shader stage: " + GetLog()); + return false; + } + } + + bool ShaderStage::Create(ShaderStageType stage) + { + Destroy(); + + m_id = glCreateShader(OpenGL::ShaderStage[stage]); + m_stage = stage; + + return (m_id != 0); + } + + void ShaderStage::Destroy() + { + m_compiled = false; + if (m_id) + { + glDeleteShader(m_id); + m_id = 0; + } + } + + String ShaderStage::GetLog() const + { + #if NAZARA_RENDERER_SAFE + if (!m_id) + { + NazaraError("Shader stage is not initialized"); + return String(); + } + #endif + + String log; + + GLint length = 0; + glGetShaderiv(m_id, GL_INFO_LOG_LENGTH, &length); + if (length > 1) // Le caractère de fin faisant partie du compte + { + log.Set(length - 1, '\0'); // La taille retournée est celle du buffer (Avec caractère de fin) + glGetShaderInfoLog(m_id, length, nullptr, &log[0]); + } + else + log = "No log."; + + return log; + } + + String ShaderStage::GetSource() const + { + #if NAZARA_RENDERER_SAFE + if (!m_id) + { + NazaraError("Shader stage is not initialized"); + return String(); + } + #endif + + String source; + + GLint length = 0; + glGetShaderiv(m_id, GL_SHADER_SOURCE_LENGTH, &length); + if (length > 1) // Le caractère de fin compte + { + source.Set(length - 1, '\0'); // La taille retournée est celle du buffer (Avec caractère de fin) + glGetShaderSource(m_id, length, nullptr, &source[0]); + } + + return source; + } + + bool ShaderStage::IsCompiled() const + { + return m_compiled; + } + + bool ShaderStage::IsValid() const + { + return m_id != 0; + } + + void ShaderStage::SetSource(const char* source, unsigned int length) + { + #if NAZARA_RENDERER_SAFE + if (!m_id) + { + NazaraError("Shader stage is not initialized"); + return; + } + #endif + + glShaderSource(m_id, 1, &source, reinterpret_cast(&length)); + } + + void ShaderStage::SetSource(const String& source) + { + #if NAZARA_RENDERER_SAFE + if (!m_id) + { + NazaraError("Shader stage is not initialized"); + return; + } + #endif + + const char* tmp = source.GetConstBuffer(); + GLint length = source.GetSize(); + glShaderSource(m_id, 1, &tmp, &length); + } + + bool ShaderStage::SetSourceFromFile(const String& filePath) + { + #if NAZARA_RENDERER_SAFE + if (!m_id) + { + NazaraError("Shader stage is not initialized"); + return false; + } + #endif + + File file(filePath); + if (!file.Open(OpenMode_ReadOnly | OpenMode_Text)) + { + NazaraError("Failed to open \"" + filePath + '"'); + return false; + } + + unsigned int length = static_cast(file.GetSize()); + + String source(length, '\0'); + + if (file.Read(&source[0], length) != length) + { + NazaraError("Failed to read program file"); + return false; + } + + file.Close(); + + SetSource(source); + return true; + } + + ShaderStage& ShaderStage::operator=(ShaderStage&& shader) + { + Destroy(); + + m_compiled = shader.m_compiled; + m_id = shader.m_id; + m_stage = shader.m_stage; + + shader.m_id = 0; + + return *this; + } + + // Fonctions OpenGL + unsigned int ShaderStage::GetOpenGLID() const + { + return m_id; + } + + bool ShaderStage::IsSupported(ShaderStageType stage) + { + switch (stage) + { + case ShaderStageType_Fragment: + case ShaderStageType_Vertex: + return true; + + case ShaderStageType_Geometry: + return OpenGL::GetVersion() >= 320; + + default: + NazaraError("Shader stage not handled (0x" + String::Number(stage, 16) + ')'); + return false; + } } } diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index 9b9789839..88919a856 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -14,1287 +14,1290 @@ #include #include -struct NzTextureImpl +namespace Nz { - GLuint id; - nzImageType type; - nzPixelFormat format; - nzUInt8 levelCount; - bool mipmapping = false; - bool mipmapsUpdated = true; - unsigned int depth; - unsigned int height; - unsigned int width; -}; - -namespace -{ - inline unsigned int GetLevelSize(unsigned int size, nzUInt8 level) + struct TextureImpl { - // Contrairement à la classe Image, un appel à GetLevelSize(0, level) n'est pas possible - return std::max(size >> level, 1U); + GLuint id; + ImageType type; + PixelFormatType format; + UInt8 levelCount; + bool mipmapping = false; + bool mipmapsUpdated = true; + unsigned int depth; + unsigned int height; + unsigned int width; + }; + + namespace + { + inline unsigned int GetLevelSize(unsigned int size, UInt8 level) + { + // Contrairement à la classe Image, un appel à GetLevelSize(0, level) n'est pas possible + return std::max(size >> level, 1U); + } + + inline void SetUnpackAlignement(UInt8 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); + } } - inline void SetUnpackAlignement(nzUInt8 bpp) + Texture::Texture(ImageType type, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, UInt8 levelCount) { - 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); - } -} - -NzTexture::NzTexture(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount) -{ - NzErrorFlags flags(nzErrorFlag_ThrowException); - Create(type, format, width, height, depth, levelCount); -} - -NzTexture::NzTexture(const NzImage& image) -{ - NzErrorFlags flags(nzErrorFlag_ThrowException); - LoadFromImage(image); -} - -NzTexture::~NzTexture() -{ - OnTextureRelease(this); - - Destroy(); - NzRenderer::OnTextureReleased(this); ///TODO: Gets rid of this -} - -bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount) -{ - Destroy(); - - #if NAZARA_RENDERER_SAFE - if (!IsTypeSupported(type)) - { - NazaraError("Texture's type not supported"); - return false; + ErrorFlags flags(ErrorFlag_ThrowException); + Create(type, format, width, height, depth, levelCount); } - if (!NzPixelFormat::IsValid(format)) + Texture::Texture(const Image& image) { - NazaraError("Invalid pixel format"); - return false; + ErrorFlags flags(ErrorFlag_ThrowException); + LoadFromImage(image); } - if (!IsFormatSupported(format)) + Texture::~Texture() { - NazaraError("Texture's format not supported"); - return false; + OnTextureRelease(this); + + Destroy(); + Renderer::OnTextureReleased(this); ///TODO: Gets rid of this } - if (width == 0) - { - NazaraError("Width must be at least 1 (0)"); - return false; - } - - if (height == 0) - { - NazaraError("Height must be at least 1 (0)"); - return false; - } - - if (depth == 0) - { - NazaraError("Depth must be at least 1 (0)"); - return false; - } - - switch (type) - { - case nzImageType_1D: - if (height > 1) - { - NazaraError("One dimensional texture's height must be 1"); - return false; - } - - if (depth > 1) - { - NazaraError("1D textures must be 1 deep"); - return false; - } - break; - - case nzImageType_1D_Array: - case nzImageType_2D: - if (depth > 1) - { - NazaraError("2D textures must be 1 deep"); - return false; - } - break; - - case nzImageType_2D_Array: - case nzImageType_3D: - break; - - case nzImageType_Cubemap: - if (depth > 1) - { - NazaraError("Cubemaps must be 1 deep"); - return false; - } - - if (width != height) - { - NazaraError("Cubemaps must have square dimensions"); - return false; - } - break; - } - #endif - - NzContext::EnsureContext(); - - if (IsMipmappingSupported()) - levelCount = std::min(levelCount, NzImage::GetMaxLevel(width, height, depth)); - else if (levelCount > 1) - { - NazaraWarning("Mipmapping not supported, reducing level count to 1"); - levelCount = 1; - } - - m_impl = new NzTextureImpl; - m_impl->depth = GetValidSize(depth); - m_impl->format = format; - m_impl->height = GetValidSize(height); - m_impl->levelCount = levelCount; - m_impl->type = type; - m_impl->width = GetValidSize(width); - - glGenTextures(1, &m_impl->id); - NzOpenGL::BindTexture(m_impl->type, m_impl->id); - - // En cas d'erreur (sortie prématurée), on détruit la texture - NzCallOnExit onExit([this]() + bool Texture::Create(ImageType type, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, UInt8 levelCount) { Destroy(); - }); - // On précise le nombre de mipmaps avant la spécification de la texture - // https://www.opengl.org/wiki/Hardware_specifics:_NVidia - SetMipmapRange(0, m_impl->levelCount-1); - if (m_impl->levelCount > 1U) - EnableMipmapping(true); - - // Vérification du support par la carte graphique (texture proxy) - if (!CreateTexture(true)) - { - NazaraError("Texture's parameters not supported by driver"); - return false; - } - - // Création de la texture - if (!CreateTexture(false)) - { - NazaraError("Failed to create texture"); - return false; - } - - onExit.Reset(); - return true; -} - -void NzTexture::Destroy() -{ - if (m_impl) - { - OnTextureDestroy(this); - - NzContext::EnsureContext(); - NzOpenGL::DeleteTexture(m_impl->id); - - delete m_impl; - m_impl = nullptr; - } -} - -bool NzTexture::Download(NzImage* image) const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - - if (!image) - { - NazaraError("Image must be valid"); - return false; - } - #endif - - NzOpenGL::Format format; - if (!NzOpenGL::TranslateFormat(m_impl->format, &format, NzOpenGL::FormatType_Texture)) - { - NazaraError("Failed to get OpenGL format"); - return false; - } - - if (!image->Create(m_impl->type, m_impl->format, m_impl->width, m_impl->height, m_impl->depth, m_impl->levelCount)) - { - NazaraError("Failed to create image"); - return false; - } - - // Téléchargement... - NzOpenGL::BindTexture(m_impl->type, m_impl->id); - for (nzUInt8 level = 0; level < m_impl->levelCount; ++level) - glGetTexImage(NzOpenGL::TextureTarget[m_impl->type], level, format.dataFormat, format.dataType, image->GetPixels(0, 0, 0, level)); - - return true; -} - -bool NzTexture::EnableMipmapping(bool enable) -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - #endif - - if (!IsMipmappingSupported()) - { - NazaraError("Mipmapping not supported"); - return false; - } - - if (m_impl->levelCount == 1) // Transformation d'une texture sans mipmaps vers une texture avec mipmaps - { - ///FIXME: Est-ce que cette opération est seulement possible ? - m_impl->levelCount = NzImage::GetMaxLevel(m_impl->width, m_impl->height, m_impl->depth); - SetMipmapRange(0, m_impl->levelCount-1); - } - - if (!m_impl->mipmapping && enable) - m_impl->mipmapsUpdated = false; - - m_impl->mipmapping = enable; - - return true; -} - -void NzTexture::EnsureMipmapsUpdate() const -{ - if (m_impl->mipmapping && !m_impl->mipmapsUpdated) - { - NzOpenGL::BindTexture(m_impl->type, m_impl->id); - glGenerateMipmap(NzOpenGL::TextureTarget[m_impl->type]); - m_impl->mipmapsUpdated = true; - } -} - -unsigned int NzTexture::GetDepth(nzUInt8 level) const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return 0; - } - #endif - - return GetLevelSize(m_impl->depth, level); -} - -nzPixelFormat NzTexture::GetFormat() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return nzPixelFormat_Undefined; - } - #endif - - return m_impl->format; -} - -unsigned int NzTexture::GetHeight(nzUInt8 level) const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return 0; - } - #endif - - return GetLevelSize(m_impl->height, level); -} - -nzUInt8 NzTexture::GetLevelCount() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return 0; - } - #endif - - return m_impl->levelCount; -} - -nzUInt8 NzTexture::GetMaxLevel() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return 0; - } - #endif - - return NzImage::GetMaxLevel(m_impl->type, m_impl->width, m_impl->height, m_impl->depth); -} - -unsigned int NzTexture::GetMemoryUsage() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return 0; - } - #endif - - unsigned int width = m_impl->width; - unsigned int height = m_impl->height; - unsigned int depth = m_impl->depth; - - unsigned int size = 0; - for (unsigned int i = 0; i < m_impl->levelCount; ++i) - { - size += width * height * depth; - - if (width > 1) - width >>= 1; - - if (height > 1) - height >>= 1; - - if (depth > 1) - depth >>= 1; - } - - if (m_impl->type == nzImageType_Cubemap) - size *= 6; - - return size * NzPixelFormat::GetBytesPerPixel(m_impl->format); -} - -unsigned int NzTexture::GetMemoryUsage(nzUInt8 level) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return 0; - } - - if (level >= m_impl->levelCount) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_impl->levelCount) + ')'); - return 0; - } - #endif - - return (GetLevelSize(m_impl->width, level)) * - (GetLevelSize(m_impl->height, level)) * - ((m_impl->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_impl->depth, level)) * - NzPixelFormat::GetBytesPerPixel(m_impl->format); -} - -NzVector3ui NzTexture::GetSize(nzUInt8 level) const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return NzVector3ui(0, 0, 0); - } - #endif - - return NzVector3ui(GetLevelSize(m_impl->width, level), GetLevelSize(m_impl->height, level), GetLevelSize(m_impl->depth, level)); -} - -nzImageType NzTexture::GetType() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return nzImageType_2D; - } - #endif - - return m_impl->type; -} - -unsigned int NzTexture::GetWidth(nzUInt8 level) const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return 0; - } - #endif - - return GetLevelSize(m_impl->width, level); -} - -bool NzTexture::HasMipmaps() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - #endif - - return m_impl->levelCount > 1; -} - -void NzTexture::InvalidateMipmaps() -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraInternalError("Texture must be valid"); - return; - } - #endif - - m_impl->mipmapsUpdated = false; -} - -bool NzTexture::IsValid() const -{ - return m_impl != nullptr; -} - -bool NzTexture::LoadFromFile(const NzString& filePath, const NzImageParams& params, bool generateMipmaps) -{ - NzImage image; - if (!image.LoadFromFile(filePath, params)) - { - NazaraError("Failed to load image"); - return false; - } - - return LoadFromImage(image, generateMipmaps); -} - -bool NzTexture::LoadFromImage(const NzImage& image, bool generateMipmaps) -{ - #if NAZARA_RENDERER_SAFE - if (!image.IsValid()) - { - NazaraError("Image must be valid"); - return false; - } - #endif - - // Vive le Copy-On-Write - NzImage newImage(image); - - nzPixelFormat format = newImage.GetFormat(); - if (!IsFormatSupported(format)) - { - ///TODO: Sélectionner le format le plus adapté selon les composantes présentes dans le premier format - nzPixelFormat newFormat = (NzPixelFormat::HasAlpha(format)) ? nzPixelFormat_BGRA8 : nzPixelFormat_BGR8; - NazaraWarning("Format " + NzPixelFormat::ToString(format) + " not supported, trying to convert it to " + NzPixelFormat::ToString(newFormat) + "..."); - - if (NzPixelFormat::IsConversionSupported(format, newFormat)) + #if NAZARA_RENDERER_SAFE + if (!IsTypeSupported(type)) { - if (newImage.Convert(newFormat)) + NazaraError("Texture's type not supported"); + return false; + } + + if (!NzPixelFormat::IsValid(format)) + { + NazaraError("Invalid pixel format"); + return false; + } + + if (!IsFormatSupported(format)) + { + NazaraError("Texture's format not supported"); + return false; + } + + if (width == 0) + { + NazaraError("Width must be at least 1 (0)"); + return false; + } + + if (height == 0) + { + NazaraError("Height must be at least 1 (0)"); + return false; + } + + if (depth == 0) + { + NazaraError("Depth must be at least 1 (0)"); + return false; + } + + switch (type) + { + case ImageType_1D: + if (height > 1) + { + NazaraError("One dimensional texture's height must be 1"); + return false; + } + + if (depth > 1) + { + NazaraError("1D textures must be 1 deep"); + return false; + } + break; + + case ImageType_1D_Array: + case ImageType_2D: + if (depth > 1) + { + NazaraError("2D textures must be 1 deep"); + return false; + } + break; + + case ImageType_2D_Array: + case ImageType_3D: + break; + + case ImageType_Cubemap: + if (depth > 1) + { + NazaraError("Cubemaps must be 1 deep"); + return false; + } + + if (width != height) + { + NazaraError("Cubemaps must have square dimensions"); + return false; + } + break; + } + #endif + + Context::EnsureContext(); + + if (IsMipmappingSupported()) + levelCount = std::min(levelCount, Image::GetMaxLevel(width, height, depth)); + else if (levelCount > 1) + { + NazaraWarning("Mipmapping not supported, reducing level count to 1"); + levelCount = 1; + } + + m_impl = new TextureImpl; + m_impl->depth = GetValidSize(depth); + m_impl->format = format; + m_impl->height = GetValidSize(height); + m_impl->levelCount = levelCount; + m_impl->type = type; + m_impl->width = GetValidSize(width); + + glGenTextures(1, &m_impl->id); + OpenGL::BindTexture(m_impl->type, m_impl->id); + + // En cas d'erreur (sortie prématurée), on détruit la texture + CallOnExit onExit([this]() + { + Destroy(); + }); + + // On précise le nombre de mipmaps avant la spécification de la texture + // https://www.opengl.org/wiki/Hardware_specifics:_NVidia + SetMipmapRange(0, m_impl->levelCount-1); + if (m_impl->levelCount > 1U) + EnableMipmapping(true); + + // Vérification du support par la carte graphique (texture proxy) + if (!CreateTexture(true)) + { + NazaraError("Texture's parameters not supported by driver"); + return false; + } + + // Création de la texture + if (!CreateTexture(false)) + { + NazaraError("Failed to create texture"); + return false; + } + + onExit.Reset(); + return true; + } + + void Texture::Destroy() + { + if (m_impl) + { + OnTextureDestroy(this); + + Context::EnsureContext(); + OpenGL::DeleteTexture(m_impl->id); + + delete m_impl; + m_impl = nullptr; + } + } + + bool Texture::Download(Image* image) const + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return false; + } + + if (!image) + { + NazaraError("Image must be valid"); + return false; + } + #endif + + OpenGL::Format format; + if (!OpenGL::TranslateFormat(m_impl->format, &format, OpenGL::FormatType_Texture)) + { + NazaraError("Failed to get OpenGL format"); + return false; + } + + if (!image->Create(m_impl->type, m_impl->format, m_impl->width, m_impl->height, m_impl->depth, m_impl->levelCount)) + { + NazaraError("Failed to create image"); + return false; + } + + // Téléchargement... + OpenGL::BindTexture(m_impl->type, m_impl->id); + for (UInt8 level = 0; level < m_impl->levelCount; ++level) + glGetTexImage(OpenGL::TextureTarget[m_impl->type], level, format.dataFormat, format.dataType, image->GetPixels(0, 0, 0, level)); + + return true; + } + + bool Texture::EnableMipmapping(bool enable) + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return false; + } + #endif + + if (!IsMipmappingSupported()) + { + NazaraError("Mipmapping not supported"); + return false; + } + + if (m_impl->levelCount == 1) // Transformation d'une texture sans mipmaps vers une texture avec mipmaps + { + ///FIXME: Est-ce que cette opération est seulement possible ? + m_impl->levelCount = Image::GetMaxLevel(m_impl->width, m_impl->height, m_impl->depth); + SetMipmapRange(0, m_impl->levelCount-1); + } + + if (!m_impl->mipmapping && enable) + m_impl->mipmapsUpdated = false; + + m_impl->mipmapping = enable; + + return true; + } + + void Texture::EnsureMipmapsUpdate() const + { + if (m_impl->mipmapping && !m_impl->mipmapsUpdated) + { + OpenGL::BindTexture(m_impl->type, m_impl->id); + glGenerateMipmap(OpenGL::TextureTarget[m_impl->type]); + m_impl->mipmapsUpdated = true; + } + } + + unsigned int Texture::GetDepth(UInt8 level) const + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + #endif + + return GetLevelSize(m_impl->depth, level); + } + + PixelFormatType Texture::GetFormat() const + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return PixelFormatType_Undefined; + } + #endif + + return m_impl->format; + } + + unsigned int Texture::GetHeight(UInt8 level) const + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + #endif + + return GetLevelSize(m_impl->height, level); + } + + UInt8 Texture::GetLevelCount() const + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + #endif + + return m_impl->levelCount; + } + + UInt8 Texture::GetMaxLevel() const + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + #endif + + return Image::GetMaxLevel(m_impl->type, m_impl->width, m_impl->height, m_impl->depth); + } + + unsigned int Texture::GetMemoryUsage() const + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + #endif + + unsigned int width = m_impl->width; + unsigned int height = m_impl->height; + unsigned int depth = m_impl->depth; + + unsigned int size = 0; + for (unsigned int i = 0; i < m_impl->levelCount; ++i) + { + size += width * height * depth; + + if (width > 1) + width >>= 1; + + if (height > 1) + height >>= 1; + + if (depth > 1) + depth >>= 1; + } + + if (m_impl->type == ImageType_Cubemap) + size *= 6; + + return size * NzPixelFormat::GetBytesPerPixel(m_impl->format); + } + + unsigned int Texture::GetMemoryUsage(UInt8 level) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + + if (level >= m_impl->levelCount) + { + NazaraError("Level out of bounds (" + String::Number(level) + " >= " + String::Number(m_impl->levelCount) + ')'); + return 0; + } + #endif + + return (GetLevelSize(m_impl->width, level)) * + (GetLevelSize(m_impl->height, level)) * + ((m_impl->type == ImageType_Cubemap) ? 6 : GetLevelSize(m_impl->depth, level)) * + NzPixelFormat::GetBytesPerPixel(m_impl->format); + } + + Vector3ui Texture::GetSize(UInt8 level) const + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return Vector3ui(0, 0, 0); + } + #endif + + return Vector3ui(GetLevelSize(m_impl->width, level), GetLevelSize(m_impl->height, level), GetLevelSize(m_impl->depth, level)); + } + + ImageType Texture::GetType() const + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return ImageType_2D; + } + #endif + + return m_impl->type; + } + + unsigned int Texture::GetWidth(UInt8 level) const + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + #endif + + return GetLevelSize(m_impl->width, level); + } + + bool Texture::HasMipmaps() const + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return false; + } + #endif + + return m_impl->levelCount > 1; + } + + void Texture::InvalidateMipmaps() + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraInternalError("Texture must be valid"); + return; + } + #endif + + m_impl->mipmapsUpdated = false; + } + + bool Texture::IsValid() const + { + return m_impl != nullptr; + } + + bool Texture::LoadFromFile(const String& filePath, const ImageParams& params, bool generateMipmaps) + { + Image image; + if (!image.LoadFromFile(filePath, params)) + { + NazaraError("Failed to load image"); + return false; + } + + return LoadFromImage(image, generateMipmaps); + } + + bool Texture::LoadFromImage(const Image& image, bool generateMipmaps) + { + #if NAZARA_RENDERER_SAFE + if (!image.IsValid()) + { + NazaraError("Image must be valid"); + return false; + } + #endif + + // Vive le Copy-On-Write + Image newImage(image); + + PixelFormatType format = newImage.GetFormat(); + if (!IsFormatSupported(format)) + { + ///TODO: Sélectionner le format le plus adapté selon les composantes présentes dans le premier format + PixelFormatType newFormat = (NzPixelFormat::HasAlpha(format)) ? PixelFormatType_BGRA8 : PixelFormatType_BGR8; + NazaraWarning("Format " + NzPixelFormat::ToString(format) + " not supported, trying to convert it to " + NzPixelFormat::ToString(newFormat) + "..."); + + if (NzPixelFormat::IsConversionSupported(format, newFormat)) { - NazaraWarning("Conversion succeed"); - format = newFormat; + if (newImage.Convert(newFormat)) + { + NazaraWarning("Conversion succeed"); + format = newFormat; + } + else + { + NazaraError("Conversion failed"); + return false; + } } else { - NazaraError("Conversion failed"); + NazaraError("Conversion not supported"); return false; } } + + ImageType type = newImage.GetType(); + UInt8 levelCount = newImage.GetLevelCount(); + if (!Create(type, format, newImage.GetWidth(), newImage.GetHeight(), newImage.GetDepth(), (generateMipmaps) ? 0xFF : levelCount)) + { + NazaraError("Failed to create texture"); + return false; + } + + CallOnExit destroyOnExit([this]() + { + Destroy(); + }); + + if (type == ImageType_Cubemap) + { + for (UInt8 level = 0; level < levelCount; ++level) + { + for (unsigned int i = 0; i <= CubemapFace_Max; ++i) + { + if (!Update(newImage.GetConstPixels(0, 0, i, level), Rectui(0, 0, newImage.GetWidth(level), newImage.GetHeight(level)), i, level)) + { + NazaraError("Failed to update texture"); + return false; + } + } + } + } else { - NazaraError("Conversion not supported"); - return false; - } - } - - nzImageType type = newImage.GetType(); - nzUInt8 levelCount = newImage.GetLevelCount(); - if (!Create(type, format, newImage.GetWidth(), newImage.GetHeight(), newImage.GetDepth(), (generateMipmaps) ? 0xFF : levelCount)) - { - NazaraError("Failed to create texture"); - return false; - } - - NzCallOnExit destroyOnExit([this]() - { - Destroy(); - }); - - if (type == nzImageType_Cubemap) - { - for (nzUInt8 level = 0; level < levelCount; ++level) - { - for (unsigned int i = 0; i <= nzCubemapFace_Max; ++i) + for (UInt8 level = 0; level < levelCount; ++level) { - if (!Update(newImage.GetConstPixels(0, 0, i, level), NzRectui(0, 0, newImage.GetWidth(level), newImage.GetHeight(level)), i, level)) + if (!Update(newImage.GetConstPixels(0, 0, 0, level), level)) { NazaraError("Failed to update texture"); return false; } } } + + destroyOnExit.Reset(); + + return true; } - else + + bool Texture::LoadFromMemory(const void* data, std::size_t size, const ImageParams& params, bool generateMipmaps) { - for (nzUInt8 level = 0; level < levelCount; ++level) + Image image; + if (!image.LoadFromMemory(data, size, params)) { - if (!Update(newImage.GetConstPixels(0, 0, 0, level), level)) - { - NazaraError("Failed to update texture"); + NazaraError("Failed to load image"); + return false; + } + + return LoadFromImage(image, generateMipmaps); + } + + bool Texture::LoadFromStream(InputStream& stream, const ImageParams& params, bool generateMipmaps) + { + Image image; + if (!image.LoadFromStream(stream, params)) + { + NazaraError("Failed to load image"); + return false; + } + + return LoadFromImage(image, generateMipmaps); + } + + bool Texture::LoadArrayFromFile(const String& filePath, const ImageParams& imageParams, bool generateMipmaps, const Vector2ui& atlasSize) + { + Image cubemap; + if (!cubemap.LoadArrayFromFile(filePath, imageParams, atlasSize)) + { + NazaraError("Failed to load cubemap"); + return false; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + bool Texture::LoadArrayFromImage(const Image& image, bool generateMipmaps, const Vector2ui& atlasSize) + { + Image cubemap; + if (!cubemap.LoadArrayFromImage(image, atlasSize)) + { + NazaraError("Failed to load cubemap"); + return false; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + bool Texture::LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams, bool generateMipmaps, const Vector2ui& atlasSize) + { + Image cubemap; + if (!cubemap.LoadArrayFromMemory(data, size, imageParams, atlasSize)) + { + NazaraError("Failed to load cubemap"); + return false; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + bool Texture::LoadArrayFromStream(InputStream& stream, const ImageParams& imageParams, bool generateMipmaps, const Vector2ui& atlasSize) + { + Image cubemap; + if (!cubemap.LoadArrayFromStream(stream, imageParams, atlasSize)) + { + NazaraError("Failed to load cubemap"); + return false; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + bool Texture::LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams, bool generateMipmaps, const CubemapParams& cubemapParams) + { + Image cubemap; + if (!cubemap.LoadCubemapFromFile(filePath, imageParams, cubemapParams)) + { + NazaraError("Failed to load cubemap"); + return false; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + bool Texture::LoadCubemapFromImage(const Image& image, bool generateMipmaps, const CubemapParams& params) + { + Image cubemap; + if (!cubemap.LoadCubemapFromImage(image, params)) + { + NazaraError("Failed to load cubemap"); + return false; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + bool Texture::LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams, bool generateMipmaps, const CubemapParams& cubemapParams) + { + Image cubemap; + if (!cubemap.LoadCubemapFromMemory(data, size, imageParams, cubemapParams)) + { + NazaraError("Failed to load cubemap"); + return false; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + bool Texture::LoadCubemapFromStream(InputStream& stream, const ImageParams& imageParams, bool generateMipmaps, const CubemapParams& cubemapParams) + { + Image cubemap; + if (!cubemap.LoadCubemapFromStream(stream, imageParams, cubemapParams)) + { + NazaraError("Failed to load cubemap"); + return false; + } + + return LoadFromImage(cubemap, generateMipmaps); + } + + bool Texture::LoadFaceFromFile(CubemapFace face, const String& filePath, const ImageParams& params) + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return false; + } + + if (m_impl->type != ImageType_Cubemap) + { + NazaraError("Texture must be a cubemap"); + return false; + } + #endif + + Image image; + if (!image.LoadFromFile(filePath, params)) + { + NazaraError("Failed to load image"); + return false; + } + + if (!image.Convert(m_impl->format)) + { + NazaraError("Failed to convert image to texture format"); + return false; + } + + unsigned int faceSize = m_impl->width; + if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) + { + NazaraError("Image size must match texture face size"); + return false; + } + + return Update(image, Rectui(0, 0, faceSize, faceSize), face); + } + + bool Texture::LoadFaceFromMemory(CubemapFace face, const void* data, std::size_t size, const ImageParams& params) + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return false; + } + + if (m_impl->type != ImageType_Cubemap) + { + NazaraError("Texture must be a cubemap"); + return false; + } + #endif + + Image image; + if (!image.LoadFromMemory(data, size, params)) + { + NazaraError("Failed to load image"); + return false; + } + + if (!image.Convert(m_impl->format)) + { + NazaraError("Failed to convert image to texture format"); + return false; + } + + unsigned int faceSize = m_impl->width; + if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) + { + NazaraError("Image size must match texture face size"); + return false; + } + + return Update(image, Rectui(0, 0, faceSize, faceSize), face); + } + + bool Texture::LoadFaceFromStream(CubemapFace face, InputStream& stream, const ImageParams& params) + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return false; + } + + if (m_impl->type != ImageType_Cubemap) + { + NazaraError("Texture must be a cubemap"); + return false; + } + #endif + + Image image; + if (!image.LoadFromStream(stream, params)) + { + NazaraError("Failed to load image"); + return false; + } + + if (!image.Convert(m_impl->format)) + { + NazaraError("Failed to convert image to texture format"); + return false; + } + + unsigned int faceSize = m_impl->width; + + if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) + { + NazaraError("Image size must match texture face size"); + return false; + } + + return Update(image, Rectui(0, 0, faceSize, faceSize), face); + } + + bool Texture::SetMipmapRange(UInt8 minLevel, UInt8 maxLevel) + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return false; + } + + if (minLevel >= m_impl->levelCount) + { + NazaraError("Minimum level cannot be greater or equal than level count (" + String::Number(minLevel) + " >= " + String::Number(m_impl->levelCount) + ')'); + return false; + } + + if (maxLevel < minLevel) + { + NazaraError("Minimum level cannot be greater than maximum level (" + String::Number(minLevel) + " < " + String::Number(maxLevel) + ')'); + return false; + } + #endif + + OpenGL::BindTexture(m_impl->type, m_impl->id); + glTexParameteri(OpenGL::TextureTarget[m_impl->type], GL_TEXTURE_BASE_LEVEL, minLevel); + glTexParameteri(OpenGL::TextureTarget[m_impl->type], GL_TEXTURE_MAX_LEVEL, maxLevel); + + return true; + } + + bool Texture::Update(const Image& image, UInt8 level) + { + #if NAZARA_RENDERER_SAFE + if (!image.IsValid()) + { + NazaraError("Image must be valid"); + return false; + } + + if (image.GetFormat() != m_impl->format) + { + NazaraError("Image format does not match texture format"); + return false; + } + #endif + + const UInt8* pixels = image.GetConstPixels(0, 0, 0, level); + if (!pixels) + { + NazaraError("Failed to access image's pixels"); + return false; + } + + return Update(pixels, image.GetWidth(level), image.GetHeight(level), level); + } + + bool Texture::Update(const Image& image, const Boxui& box, UInt8 level) + { + #if NAZARA_RENDERER_SAFE + if (!image.IsValid()) + { + NazaraError("Image must be valid"); + return false; + } + + if (image.GetFormat() != m_impl->format) + { + NazaraError("Image format does not match texture format"); + return false; + } + #endif + + const UInt8* pixels = image.GetConstPixels(0, 0, 0, level); + if (!pixels) + { + NazaraError("Failed to access image's pixels"); + return false; + } + + return Update(pixels, box, image.GetWidth(level), image.GetHeight(level), level); + } + + bool Texture::Update(const Image& image, const Rectui& rect, unsigned int z, UInt8 level) + { + #if NAZARA_RENDERER_SAFE + if (!image.IsValid()) + { + NazaraError("Image must be valid"); + return false; + } + + if (image.GetFormat() != m_impl->format) + { + NazaraError("Image format does not match texture format"); + return false; + } + #endif + + const UInt8* pixels = image.GetConstPixels(0, 0, 0, level); + if (!pixels) + { + NazaraError("Failed to access image's pixels"); + return false; + } + + return Update(pixels, rect, z, image.GetWidth(level), image.GetHeight(level), level); + } + + bool Texture::Update(const UInt8* pixels, unsigned int srcWidth, unsigned int srcHeight, UInt8 level) + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return false; + } + #endif + + return Update(pixels, Boxui(GetLevelSize(m_impl->width, level), GetLevelSize(m_impl->height, level), GetLevelSize(m_impl->depth, level)), srcWidth, srcHeight, level); + } + + bool Texture::Update(const UInt8* pixels, const Boxui& box, unsigned int srcWidth, unsigned int srcHeight, UInt8 level) + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return false; + } + + if (!pixels) + { + NazaraError("Invalid pixel source"); + return false; + } + + if (!box.IsValid()) + { + NazaraError("Invalid box"); + return false; + } + + unsigned int width = GetLevelSize(m_impl->width, level); + unsigned int height = GetLevelSize(m_impl->height, level); + unsigned int depth = (m_impl->type == ImageType_Cubemap) ? 6 : GetLevelSize(m_impl->depth, level); + if (box.x+box.width > width || box.y+box.height > height || box.z+box.depth > depth || + (m_impl->type == ImageType_Cubemap && box.depth > 1)) // Nous n'autorisons pas de modifier plus d'une face du cubemap à la fois + { + NazaraError("Cube dimensions are out of bounds"); + return false; + } + + if (level >= m_impl->levelCount) + { + NazaraError("Level out of bounds (" + String::Number(level) + " >= " + String::Number(m_impl->levelCount) + ')'); + return false; + } + #endif + + OpenGL::Format format; + if (!OpenGL::TranslateFormat(m_impl->format, &format, OpenGL::FormatType_Texture)) + { + NazaraError("Failed to get OpenGL format"); + return false; + } + + SetUnpackAlignement(NzPixelFormat::GetBytesPerPixel(m_impl->format)); + glPixelStorei(GL_UNPACK_ROW_LENGTH, srcWidth); + glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, srcHeight); + + OpenGL::BindTexture(m_impl->type, m_impl->id); + switch (m_impl->type) + { + case ImageType_1D: + glTexSubImage1D(GL_TEXTURE_1D, level, box.x, box.width, format.dataFormat, format.dataType, pixels); + break; + + case ImageType_1D_Array: + case ImageType_2D: + glTexSubImage2D(OpenGL::TextureTarget[m_impl->type], level, box.x, box.y, box.width, box.height, format.dataFormat, format.dataType, pixels); + break; + + case ImageType_2D_Array: + case ImageType_3D: + glTexSubImage3D(OpenGL::TextureTarget[m_impl->type], level, box.x, box.y, box.z, box.width, box.height, box.depth, format.dataFormat, format.dataType, pixels); + break; + + case ImageType_Cubemap: + glTexSubImage2D(OpenGL::CubemapFace[box.z], level, box.x, box.y, box.width, box.height, format.dataFormat, format.dataType, pixels); + break; + } + + return true; + } + + bool Texture::Update(const UInt8* pixels, const Rectui& rect, unsigned int z, unsigned int srcWidth, unsigned int srcHeight, UInt8 level) + { + return Update(pixels, Boxui(rect.x, rect.y, z, rect.width, rect.height, 1), srcWidth, srcHeight, level); + } + + unsigned int Texture::GetOpenGLID() const + { + #if NAZARA_RENDERER_SAFE + if (!m_impl) + { + NazaraError("Texture must be valid"); + return 0; + } + #endif + + return m_impl->id; + } + + unsigned int Texture::GetValidSize(unsigned int size) + { + if (Renderer::HasCapability(RendererCap_TextureNPOT)) + return size; + else + { + unsigned int pot = 1; + while (pot < size) + pot <<= 1; + + return pot; + } + } + + bool Texture::IsFormatSupported(PixelFormatType format) + { + switch (format) + { + // Formats de base + case PixelFormatType_A8: + case PixelFormatType_BGR8: + case PixelFormatType_BGRA8: + case PixelFormatType_L8: + case PixelFormatType_LA8: + case PixelFormatType_RGB8: + case PixelFormatType_RGBA8: + return true; + + // Packed formats supportés depuis OpenGL 1.2 + case PixelFormatType_RGB5A1: + case PixelFormatType_RGBA4: + return true; + + // Formats supportés depuis OpenGL 3 + case PixelFormatType_R8: + case PixelFormatType_R8I: + case PixelFormatType_R8UI: + case PixelFormatType_R16: + case PixelFormatType_R16F: + case PixelFormatType_R16I: + case PixelFormatType_R16UI: + case PixelFormatType_R32F: + case PixelFormatType_R32I: + case PixelFormatType_R32UI: + case PixelFormatType_RG8: + case PixelFormatType_RG8I: + case PixelFormatType_RG8UI: + case PixelFormatType_RG16: + case PixelFormatType_RG16F: + case PixelFormatType_RG16I: + case PixelFormatType_RG16UI: + case PixelFormatType_RG32F: + case PixelFormatType_RG32I: + case PixelFormatType_RG32UI: + case PixelFormatType_RGB16F: + case PixelFormatType_RGB16I: + case PixelFormatType_RGB16UI: + case PixelFormatType_RGB32F: + case PixelFormatType_RGB32I: + case PixelFormatType_RGB32UI: + case PixelFormatType_RGBA16F: + case PixelFormatType_RGBA16I: + case PixelFormatType_RGBA16UI: + case PixelFormatType_RGBA32F: + case PixelFormatType_RGBA32I: + case PixelFormatType_RGBA32UI: + return OpenGL::GetVersion() >= 300; + + // Formats de profondeur (Supportés avec les FBOs) + case PixelFormatType_Depth16: + case PixelFormatType_Depth24: + case PixelFormatType_Depth32: + case PixelFormatType_Depth24Stencil8: + return OpenGL::IsSupported(OpenGLExtension_FrameBufferObject); + + // Formats de stencil (Non supportés pour les textures) + case PixelFormatType_Stencil1: + case PixelFormatType_Stencil4: + case PixelFormatType_Stencil8: + case PixelFormatType_Stencil16: return false; - } + + // Formats compressés + case PixelFormatType_DXT1: + case PixelFormatType_DXT3: + case PixelFormatType_DXT5: + return OpenGL::IsSupported(OpenGLExtension_TextureCompression_s3tc); + + case PixelFormatType_Undefined: + break; } - } - destroyOnExit.Reset(); - - return true; -} - -bool NzTexture::LoadFromMemory(const void* data, std::size_t size, const NzImageParams& params, bool generateMipmaps) -{ - NzImage image; - if (!image.LoadFromMemory(data, size, params)) - { - NazaraError("Failed to load image"); + NazaraError("Invalid pixel format"); return false; } - return LoadFromImage(image, generateMipmaps); -} - -bool NzTexture::LoadFromStream(NzInputStream& stream, const NzImageParams& params, bool generateMipmaps) -{ - NzImage image; - if (!image.LoadFromStream(stream, params)) + bool Texture::IsMipmappingSupported() { - NazaraError("Failed to load image"); + return glGenerateMipmap != nullptr; + } + + bool Texture::IsTypeSupported(ImageType type) + { + switch (type) + { + case ImageType_1D: + case ImageType_2D: + case ImageType_3D: + case ImageType_Cubemap: + return true; // Tous supportés nativement dans OpenGL 2 + + case ImageType_1D_Array: + case ImageType_2D_Array: + return OpenGL::IsSupported(OpenGLExtension_TextureArray); + } + + NazaraError("Image type not handled (0x" + String::Number(type, 16) + ')'); return false; } - return LoadFromImage(image, generateMipmaps); -} - -bool NzTexture::LoadArrayFromFile(const NzString& filePath, const NzImageParams& imageParams, bool generateMipmaps, const NzVector2ui& atlasSize) -{ - NzImage cubemap; - if (!cubemap.LoadArrayFromFile(filePath, imageParams, atlasSize)) + bool Texture::CreateTexture(bool proxy) { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); -} - -bool NzTexture::LoadArrayFromImage(const NzImage& image, bool generateMipmaps, const NzVector2ui& atlasSize) -{ - NzImage cubemap; - if (!cubemap.LoadArrayFromImage(image, atlasSize)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); -} - -bool NzTexture::LoadArrayFromMemory(const void* data, std::size_t size, const NzImageParams& imageParams, bool generateMipmaps, const NzVector2ui& atlasSize) -{ - NzImage cubemap; - if (!cubemap.LoadArrayFromMemory(data, size, imageParams, atlasSize)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); -} - -bool NzTexture::LoadArrayFromStream(NzInputStream& stream, const NzImageParams& imageParams, bool generateMipmaps, const NzVector2ui& atlasSize) -{ - NzImage cubemap; - if (!cubemap.LoadArrayFromStream(stream, imageParams, atlasSize)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); -} - -bool NzTexture::LoadCubemapFromFile(const NzString& filePath, const NzImageParams& imageParams, bool generateMipmaps, const NzCubemapParams& cubemapParams) -{ - NzImage cubemap; - if (!cubemap.LoadCubemapFromFile(filePath, imageParams, cubemapParams)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); -} - -bool NzTexture::LoadCubemapFromImage(const NzImage& image, bool generateMipmaps, const NzCubemapParams& params) -{ - NzImage cubemap; - if (!cubemap.LoadCubemapFromImage(image, params)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); -} - -bool NzTexture::LoadCubemapFromMemory(const void* data, std::size_t size, const NzImageParams& imageParams, bool generateMipmaps, const NzCubemapParams& cubemapParams) -{ - NzImage cubemap; - if (!cubemap.LoadCubemapFromMemory(data, size, imageParams, cubemapParams)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); -} - -bool NzTexture::LoadCubemapFromStream(NzInputStream& stream, const NzImageParams& imageParams, bool generateMipmaps, const NzCubemapParams& cubemapParams) -{ - NzImage cubemap; - if (!cubemap.LoadCubemapFromStream(stream, imageParams, cubemapParams)) - { - NazaraError("Failed to load cubemap"); - return false; - } - - return LoadFromImage(cubemap, generateMipmaps); -} - -bool NzTexture::LoadFaceFromFile(nzCubemapFace face, const NzString& filePath, const NzImageParams& params) -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - - if (m_impl->type != nzImageType_Cubemap) - { - NazaraError("Texture must be a cubemap"); - return false; - } - #endif - - NzImage image; - if (!image.LoadFromFile(filePath, params)) - { - NazaraError("Failed to load image"); - return false; - } - - if (!image.Convert(m_impl->format)) - { - NazaraError("Failed to convert image to texture format"); - return false; - } - - unsigned int faceSize = m_impl->width; - if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) - { - NazaraError("Image size must match texture face size"); - return false; - } - - return Update(image, NzRectui(0, 0, faceSize, faceSize), face); -} - -bool NzTexture::LoadFaceFromMemory(nzCubemapFace face, const void* data, std::size_t size, const NzImageParams& params) -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - - if (m_impl->type != nzImageType_Cubemap) - { - NazaraError("Texture must be a cubemap"); - return false; - } - #endif - - NzImage image; - if (!image.LoadFromMemory(data, size, params)) - { - NazaraError("Failed to load image"); - return false; - } - - if (!image.Convert(m_impl->format)) - { - NazaraError("Failed to convert image to texture format"); - return false; - } - - unsigned int faceSize = m_impl->width; - if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) - { - NazaraError("Image size must match texture face size"); - return false; - } - - return Update(image, NzRectui(0, 0, faceSize, faceSize), face); -} - -bool NzTexture::LoadFaceFromStream(nzCubemapFace face, NzInputStream& stream, const NzImageParams& params) -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - - if (m_impl->type != nzImageType_Cubemap) - { - NazaraError("Texture must be a cubemap"); - return false; - } - #endif - - NzImage image; - if (!image.LoadFromStream(stream, params)) - { - NazaraError("Failed to load image"); - return false; - } - - if (!image.Convert(m_impl->format)) - { - NazaraError("Failed to convert image to texture format"); - return false; - } - - unsigned int faceSize = m_impl->width; - - if (image.GetWidth() != faceSize || image.GetHeight() != faceSize) - { - NazaraError("Image size must match texture face size"); - return false; - } - - return Update(image, NzRectui(0, 0, faceSize, faceSize), face); -} - -bool NzTexture::SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel) -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - - if (minLevel >= m_impl->levelCount) - { - NazaraError("Minimum level cannot be greater or equal than level count (" + NzString::Number(minLevel) + " >= " + NzString::Number(m_impl->levelCount) + ')'); - return false; - } - - if (maxLevel < minLevel) - { - NazaraError("Minimum level cannot be greater than maximum level (" + NzString::Number(minLevel) + " < " + NzString::Number(maxLevel) + ')'); - return false; - } - #endif - - NzOpenGL::BindTexture(m_impl->type, m_impl->id); - glTexParameteri(NzOpenGL::TextureTarget[m_impl->type], GL_TEXTURE_BASE_LEVEL, minLevel); - glTexParameteri(NzOpenGL::TextureTarget[m_impl->type], GL_TEXTURE_MAX_LEVEL, maxLevel); - - return true; -} - -bool NzTexture::Update(const NzImage& image, nzUInt8 level) -{ - #if NAZARA_RENDERER_SAFE - if (!image.IsValid()) - { - NazaraError("Image must be valid"); - return false; - } - - if (image.GetFormat() != m_impl->format) - { - NazaraError("Image format does not match texture format"); - return false; - } - #endif - - const nzUInt8* pixels = image.GetConstPixels(0, 0, 0, level); - if (!pixels) - { - NazaraError("Failed to access image's pixels"); - return false; - } - - return Update(pixels, image.GetWidth(level), image.GetHeight(level), level); -} - -bool NzTexture::Update(const NzImage& image, const NzBoxui& box, nzUInt8 level) -{ - #if NAZARA_RENDERER_SAFE - if (!image.IsValid()) - { - NazaraError("Image must be valid"); - return false; - } - - if (image.GetFormat() != m_impl->format) - { - NazaraError("Image format does not match texture format"); - return false; - } - #endif - - const nzUInt8* pixels = image.GetConstPixels(0, 0, 0, level); - if (!pixels) - { - NazaraError("Failed to access image's pixels"); - return false; - } - - return Update(pixels, box, image.GetWidth(level), image.GetHeight(level), level); -} - -bool NzTexture::Update(const NzImage& image, const NzRectui& rect, unsigned int z, nzUInt8 level) -{ - #if NAZARA_RENDERER_SAFE - if (!image.IsValid()) - { - NazaraError("Image must be valid"); - return false; - } - - if (image.GetFormat() != m_impl->format) - { - NazaraError("Image format does not match texture format"); - return false; - } - #endif - - const nzUInt8* pixels = image.GetConstPixels(0, 0, 0, level); - if (!pixels) - { - NazaraError("Failed to access image's pixels"); - return false; - } - - return Update(pixels, rect, z, image.GetWidth(level), image.GetHeight(level), level); -} - -bool NzTexture::Update(const nzUInt8* pixels, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - #endif - - return Update(pixels, NzBoxui(GetLevelSize(m_impl->width, level), GetLevelSize(m_impl->height, level), GetLevelSize(m_impl->depth, level)), srcWidth, srcHeight, level); -} - -bool NzTexture::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return false; - } - - if (!pixels) - { - NazaraError("Invalid pixel source"); - return false; - } - - if (!box.IsValid()) - { - NazaraError("Invalid box"); - return false; - } - - unsigned int width = GetLevelSize(m_impl->width, level); - unsigned int height = GetLevelSize(m_impl->height, level); - unsigned int depth = (m_impl->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_impl->depth, level); - if (box.x+box.width > width || box.y+box.height > height || box.z+box.depth > depth || - (m_impl->type == nzImageType_Cubemap && box.depth > 1)) // Nous n'autorisons pas de modifier plus d'une face du cubemap à la fois - { - NazaraError("Cube dimensions are out of bounds"); - return false; - } - - if (level >= m_impl->levelCount) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_impl->levelCount) + ')'); - return false; - } - #endif - - NzOpenGL::Format format; - if (!NzOpenGL::TranslateFormat(m_impl->format, &format, NzOpenGL::FormatType_Texture)) - { - NazaraError("Failed to get OpenGL format"); - return false; - } - - SetUnpackAlignement(NzPixelFormat::GetBytesPerPixel(m_impl->format)); - glPixelStorei(GL_UNPACK_ROW_LENGTH, srcWidth); - glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, srcHeight); - - NzOpenGL::BindTexture(m_impl->type, m_impl->id); - switch (m_impl->type) - { - case nzImageType_1D: - glTexSubImage1D(GL_TEXTURE_1D, level, box.x, box.width, format.dataFormat, format.dataType, pixels); - break; - - case nzImageType_1D_Array: - case nzImageType_2D: - glTexSubImage2D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, box.y, box.width, box.height, format.dataFormat, format.dataType, pixels); - break; - - case nzImageType_2D_Array: - case nzImageType_3D: - glTexSubImage3D(NzOpenGL::TextureTarget[m_impl->type], level, box.x, box.y, box.z, box.width, box.height, box.depth, format.dataFormat, format.dataType, pixels); - break; - - case nzImageType_Cubemap: - glTexSubImage2D(NzOpenGL::CubemapFace[box.z], level, box.x, box.y, box.width, box.height, format.dataFormat, format.dataType, pixels); - break; - } - - return true; -} - -bool NzTexture::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) -{ - return Update(pixels, NzBoxui(rect.x, rect.y, z, rect.width, rect.height, 1), srcWidth, srcHeight, level); -} - -unsigned int NzTexture::GetOpenGLID() const -{ - #if NAZARA_RENDERER_SAFE - if (!m_impl) - { - NazaraError("Texture must be valid"); - return 0; - } - #endif - - return m_impl->id; -} - -unsigned int NzTexture::GetValidSize(unsigned int size) -{ - if (NzRenderer::HasCapability(nzRendererCap_TextureNPOT)) - return size; - else - { - unsigned int pot = 1; - while (pot < size) - pot <<= 1; - - return pot; - } -} - -bool NzTexture::IsFormatSupported(nzPixelFormat format) -{ - switch (format) - { - // Formats de base - case nzPixelFormat_A8: - case nzPixelFormat_BGR8: - case nzPixelFormat_BGRA8: - case nzPixelFormat_L8: - case nzPixelFormat_LA8: - case nzPixelFormat_RGB8: - case nzPixelFormat_RGBA8: - return true; - - // Packed formats supportés depuis OpenGL 1.2 - case nzPixelFormat_RGB5A1: - case nzPixelFormat_RGBA4: - return true; - - // Formats supportés depuis OpenGL 3 - case nzPixelFormat_R8: - case nzPixelFormat_R8I: - case nzPixelFormat_R8UI: - case nzPixelFormat_R16: - case nzPixelFormat_R16F: - case nzPixelFormat_R16I: - case nzPixelFormat_R16UI: - case nzPixelFormat_R32F: - case nzPixelFormat_R32I: - case nzPixelFormat_R32UI: - case nzPixelFormat_RG8: - case nzPixelFormat_RG8I: - case nzPixelFormat_RG8UI: - case nzPixelFormat_RG16: - case nzPixelFormat_RG16F: - case nzPixelFormat_RG16I: - case nzPixelFormat_RG16UI: - case nzPixelFormat_RG32F: - case nzPixelFormat_RG32I: - case nzPixelFormat_RG32UI: - case nzPixelFormat_RGB16F: - case nzPixelFormat_RGB16I: - case nzPixelFormat_RGB16UI: - case nzPixelFormat_RGB32F: - case nzPixelFormat_RGB32I: - case nzPixelFormat_RGB32UI: - case nzPixelFormat_RGBA16F: - case nzPixelFormat_RGBA16I: - case nzPixelFormat_RGBA16UI: - case nzPixelFormat_RGBA32F: - case nzPixelFormat_RGBA32I: - case nzPixelFormat_RGBA32UI: - return NzOpenGL::GetVersion() >= 300; - - // Formats de profondeur (Supportés avec les FBOs) - case nzPixelFormat_Depth16: - case nzPixelFormat_Depth24: - case nzPixelFormat_Depth32: - case nzPixelFormat_Depth24Stencil8: - return NzOpenGL::IsSupported(nzOpenGLExtension_FrameBufferObject); - - // Formats de stencil (Non supportés pour les textures) - case nzPixelFormat_Stencil1: - case nzPixelFormat_Stencil4: - case nzPixelFormat_Stencil8: - case nzPixelFormat_Stencil16: + OpenGL::Format openGLFormat; + if (!OpenGL::TranslateFormat(m_impl->format, &openGLFormat, OpenGL::FormatType_Texture)) + { + NazaraError("Format " + NzPixelFormat::ToString(m_impl->format) + " not supported by OpenGL"); return false; - - // Formats compressés - case nzPixelFormat_DXT1: - case nzPixelFormat_DXT3: - case nzPixelFormat_DXT5: - return NzOpenGL::IsSupported(nzOpenGLExtension_TextureCompression_s3tc); - - case nzPixelFormat_Undefined: - break; - } - - NazaraError("Invalid pixel format"); - return false; -} - -bool NzTexture::IsMipmappingSupported() -{ - return glGenerateMipmap != nullptr; -} - -bool NzTexture::IsTypeSupported(nzImageType type) -{ - switch (type) - { - case nzImageType_1D: - case nzImageType_2D: - case nzImageType_3D: - case nzImageType_Cubemap: - return true; // Tous supportés nativement dans OpenGL 2 - - case nzImageType_1D_Array: - case nzImageType_2D_Array: - return NzOpenGL::IsSupported(nzOpenGLExtension_TextureArray); - } - - NazaraError("Image type not handled (0x" + NzString::Number(type, 16) + ')'); - return false; -} - -bool NzTexture::CreateTexture(bool proxy) -{ - NzOpenGL::Format openGLFormat; - if (!NzOpenGL::TranslateFormat(m_impl->format, &openGLFormat, NzOpenGL::FormatType_Texture)) - { - NazaraError("Format " + NzPixelFormat::ToString(m_impl->format) + " not supported by OpenGL"); - return false; - } - - GLenum target = (proxy) ? NzOpenGL::TextureTargetProxy[m_impl->type] : NzOpenGL::TextureTarget[m_impl->type]; - switch (m_impl->type) - { - case nzImageType_1D: - { - if (glTexStorage1D && !proxy) // Les drivers AMD semblent ne pas aimer glTexStorage avec un format proxy - glTexStorage1D(target, m_impl->levelCount, openGLFormat.internalFormat, m_impl->width); - else - { - unsigned int w = m_impl->width; - for (nzUInt8 level = 0; level < m_impl->levelCount; ++level) - { - glTexImage1D(target, level, openGLFormat.internalFormat, w, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); - if (w > 1U) - w >>= 1; - } - } - break; } - case nzImageType_1D_Array: - case nzImageType_2D: + GLenum target = (proxy) ? OpenGL::TextureTargetProxy[m_impl->type] : OpenGL::TextureTarget[m_impl->type]; + switch (m_impl->type) { - if (glTexStorage2D && !proxy) - glTexStorage2D(target, m_impl->levelCount, openGLFormat.internalFormat, m_impl->width, m_impl->height); - else + case ImageType_1D: { - unsigned int w = m_impl->width; - unsigned int h = m_impl->height; - for (nzUInt8 level = 0; level < m_impl->levelCount; ++level) + if (glTexStorage1D && !proxy) // Les drivers AMD semblent ne pas aimer glTexStorage avec un format proxy + glTexStorage1D(target, m_impl->levelCount, openGLFormat.internalFormat, m_impl->width); + else { - glTexImage2D(target, level, openGLFormat.internalFormat, w, h, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); - if (w > 1U) - w >>= 1; - - if (h > 1U) - h >>= 1; + unsigned int w = m_impl->width; + for (UInt8 level = 0; level < m_impl->levelCount; ++level) + { + glTexImage1D(target, level, openGLFormat.internalFormat, w, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); + if (w > 1U) + w >>= 1; + } } + break; + } + + case ImageType_1D_Array: + case ImageType_2D: + { + if (glTexStorage2D && !proxy) + glTexStorage2D(target, m_impl->levelCount, openGLFormat.internalFormat, m_impl->width, m_impl->height); + else + { + unsigned int w = m_impl->width; + unsigned int h = m_impl->height; + for (UInt8 level = 0; level < m_impl->levelCount; ++level) + { + glTexImage2D(target, level, openGLFormat.internalFormat, w, h, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); + if (w > 1U) + w >>= 1; + + if (h > 1U) + h >>= 1; + } + } + break; + } + + case ImageType_2D_Array: + case ImageType_3D: + { + if (glTexStorage3D && !proxy) + glTexStorage3D(target, m_impl->levelCount, openGLFormat.internalFormat, m_impl->width, m_impl->height, m_impl->depth); + else + { + unsigned int w = m_impl->width; + unsigned int h = m_impl->height; + unsigned int d = m_impl->depth; + for (UInt8 level = 0; level < m_impl->levelCount; ++level) + { + glTexImage3D(target, level, openGLFormat.internalFormat, w, h, d, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); + if (w > 1U) + w >>= 1; + + if (h > 1U) + h >>= 1; + + if (d > 1U) + d >>= 1; + } + } + break; + } + + case ImageType_Cubemap: + { + if (glTexStorage2D && !proxy) + glTexStorage2D(target, m_impl->levelCount, openGLFormat.internalFormat, m_impl->width, m_impl->height); + else + { + unsigned int size = m_impl->width; // Les cubemaps ont une longueur et largeur identique + for (UInt8 level = 0; level < m_impl->levelCount; ++level) + { + for (GLenum face : OpenGL::CubemapFace) + glTexImage2D(face, level, openGLFormat.internalFormat, size, size, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); + + if (size > 1U) + size >>= 1; + } + } + break; } - break; } - case nzImageType_2D_Array: - case nzImageType_3D: + if (proxy) { - if (glTexStorage3D && !proxy) - glTexStorage3D(target, m_impl->levelCount, openGLFormat.internalFormat, m_impl->width, m_impl->height, m_impl->depth); - else - { - unsigned int w = m_impl->width; - unsigned int h = m_impl->height; - unsigned int d = m_impl->depth; - for (nzUInt8 level = 0; level < m_impl->levelCount; ++level) - { - glTexImage3D(target, level, openGLFormat.internalFormat, w, h, d, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); - if (w > 1U) - w >>= 1; - - if (h > 1U) - h >>= 1; - - if (d > 1U) - d >>= 1; - } - } - break; + GLint internalFormat = 0; + glGetTexLevelParameteriv(target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internalFormat); + if (internalFormat == 0) + return false; } - case nzImageType_Cubemap: + // Application du swizzle + if (!proxy && OpenGL::GetVersion() >= 300) { - if (glTexStorage2D && !proxy) - glTexStorage2D(target, m_impl->levelCount, openGLFormat.internalFormat, m_impl->width, m_impl->height); - else - { - unsigned int size = m_impl->width; // Les cubemaps ont une longueur et largeur identique - for (nzUInt8 level = 0; level < m_impl->levelCount; ++level) - { - for (GLenum face : NzOpenGL::CubemapFace) - glTexImage2D(face, level, openGLFormat.internalFormat, size, size, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr); - - if (size > 1U) - size >>= 1; - } - } - break; + glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, openGLFormat.swizzle[0]); + glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, openGLFormat.swizzle[1]); + glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, openGLFormat.swizzle[2]); + glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, openGLFormat.swizzle[3]); } + + return true; } - if (proxy) + bool Texture::Initialize() { - GLint internalFormat = 0; - glGetTexLevelParameteriv(target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internalFormat); - if (internalFormat == 0) + if (!TextureLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); return false; + } + + if (!TextureManager::Initialize()) + { + NazaraError("Failed to initialise manager"); + return false; + } + + return true; } - // Application du swizzle - if (!proxy && NzOpenGL::GetVersion() >= 300) + void Texture::Uninitialize() { - glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, openGLFormat.swizzle[0]); - glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, openGLFormat.swizzle[1]); - glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, openGLFormat.swizzle[2]); - glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, openGLFormat.swizzle[3]); + TextureManager::Uninitialize(); + TextureLibrary::Uninitialize(); } - return true; + TextureLibrary::LibraryMap Texture::s_library; + TextureManager::ManagerMap Texture::s_managerMap; + TextureManager::ManagerParams Texture::s_managerParameters; } - -bool NzTexture::Initialize() -{ - if (!NzTextureLibrary::Initialize()) - { - NazaraError("Failed to initialise library"); - return false; - } - - if (!NzTextureManager::Initialize()) - { - NazaraError("Failed to initialise manager"); - return false; - } - - return true; -} - -void NzTexture::Uninitialize() -{ - NzTextureManager::Uninitialize(); - NzTextureLibrary::Uninitialize(); -} - -NzTextureLibrary::LibraryMap NzTexture::s_library; -NzTextureManager::ManagerMap NzTexture::s_managerMap; -NzTextureManager::ManagerParams NzTexture::s_managerParameters; diff --git a/src/Nazara/Renderer/TextureSampler.cpp b/src/Nazara/Renderer/TextureSampler.cpp index 3c36c61ff..bd09a943f 100644 --- a/src/Nazara/Renderer/TextureSampler.cpp +++ b/src/Nazara/Renderer/TextureSampler.cpp @@ -12,379 +12,382 @@ #include #include -namespace +namespace Nz { - std::unordered_map s_samplers; - nzUInt8 s_maxAnisotropyLevel; - bool s_useAnisotropicFilter; -} - -NzTextureSampler::NzTextureSampler() : -m_filterMode(nzSamplerFilter_Default), -m_wrapMode(nzSamplerWrap_Default), -m_anisotropicLevel(0), -m_mipmaps(true), -m_samplerId(0) -{ -} - -nzUInt8 NzTextureSampler::GetAnisotropicLevel() const -{ - return m_anisotropicLevel; -} - -nzSamplerFilter NzTextureSampler::GetFilterMode() const -{ - return m_filterMode; -} - -nzSamplerWrap NzTextureSampler::GetWrapMode() const -{ - return m_wrapMode; -} - -void NzTextureSampler::SetAnisotropyLevel(nzUInt8 anisotropyLevel) -{ - #ifdef NAZARA_DEBUG - if (!NzRenderer::IsInitialized()) + namespace { - NazaraError("Renderer module must be initialized"); - return; + std::unordered_map s_samplers; + UInt8 s_maxAnisotropyLevel; + bool s_useAnisotropicFilter; } - #endif - if (m_anisotropicLevel != anisotropyLevel) + TextureSampler::TextureSampler() : + m_filterMode(SamplerFilter_Default), + m_wrapMode(SamplerWrap_Default), + m_anisotropicLevel(0), + m_mipmaps(true), + m_samplerId(0) { + } + + UInt8 TextureSampler::GetAnisotropicLevel() const + { + return m_anisotropicLevel; + } + + SamplerFilter TextureSampler::GetFilterMode() const + { + return m_filterMode; + } + + SamplerWrap TextureSampler::GetWrapMode() const + { + return m_wrapMode; + } + + void TextureSampler::SetAnisotropyLevel(UInt8 anisotropyLevel) + { + #ifdef NAZARA_DEBUG + if (!Renderer::IsInitialized()) + { + NazaraError("Renderer module must be initialized"); + return; + } + #endif + + if (m_anisotropicLevel != anisotropyLevel) + { + if (anisotropyLevel > s_maxAnisotropyLevel) + { + NazaraWarning("Anisotropy level is over maximum anisotropy level (" + String::Number(anisotropyLevel) + " > " + String::Number(s_maxAnisotropyLevel) + ')'); + anisotropyLevel = s_maxAnisotropyLevel; + } + + m_anisotropicLevel = anisotropyLevel; + m_samplerId = 0; + } + } + + void TextureSampler::SetFilterMode(SamplerFilter filterMode) + { + if (m_filterMode != filterMode) + { + m_filterMode = filterMode; + m_samplerId = 0; + } + } + + void TextureSampler::SetWrapMode(SamplerWrap wrapMode) + { + if (m_wrapMode != wrapMode) + { + m_wrapMode = wrapMode; + m_samplerId = 0; + } + } + + UInt8 TextureSampler::GetDefaultAnisotropicLevel() + { + return s_defaultAnisotropyLevel; + } + + SamplerFilter TextureSampler::GetDefaultFilterMode() + { + return s_defaultFilterMode; + } + + SamplerWrap TextureSampler::GetDefaultWrapMode() + { + return s_defaultWrapMode; + } + + void TextureSampler::SetDefaultAnisotropyLevel(UInt8 anisotropyLevel) + { + #if NAZARA_RENDERER_SAFE + if (anisotropyLevel == 0) + { + NazaraError("Default anisotropy level mode cannot be set to default value (0)"); + return; + } + #endif + + #ifdef NAZARA_DEBUG + if (!Renderer::IsInitialized()) + { + NazaraError("Renderer module must be initialized"); + return; + } + #endif + if (anisotropyLevel > s_maxAnisotropyLevel) { - NazaraWarning("Anisotropy level is over maximum anisotropy level (" + NzString::Number(anisotropyLevel) + " > " + NzString::Number(s_maxAnisotropyLevel) + ')'); + NazaraWarning("Anisotropy level is over maximum anisotropy level (" + String::Number(anisotropyLevel) + " > " + String::Number(s_maxAnisotropyLevel)); anisotropyLevel = s_maxAnisotropyLevel; } - m_anisotropicLevel = anisotropyLevel; - m_samplerId = 0; - } -} - -void NzTextureSampler::SetFilterMode(nzSamplerFilter filterMode) -{ - if (m_filterMode != filterMode) - { - m_filterMode = filterMode; - m_samplerId = 0; - } -} - -void NzTextureSampler::SetWrapMode(nzSamplerWrap wrapMode) -{ - if (m_wrapMode != wrapMode) - { - m_wrapMode = wrapMode; - m_samplerId = 0; - } -} - -nzUInt8 NzTextureSampler::GetDefaultAnisotropicLevel() -{ - return s_defaultAnisotropyLevel; -} - -nzSamplerFilter NzTextureSampler::GetDefaultFilterMode() -{ - return s_defaultFilterMode; -} - -nzSamplerWrap NzTextureSampler::GetDefaultWrapMode() -{ - return s_defaultWrapMode; -} - -void NzTextureSampler::SetDefaultAnisotropyLevel(nzUInt8 anisotropyLevel) -{ - #if NAZARA_RENDERER_SAFE - if (anisotropyLevel == 0) - { - NazaraError("Default anisotropy level mode cannot be set to default value (0)"); - return; - } - #endif - - #ifdef NAZARA_DEBUG - if (!NzRenderer::IsInitialized()) - { - NazaraError("Renderer module must be initialized"); - return; - } - #endif - - if (anisotropyLevel > s_maxAnisotropyLevel) - { - NazaraWarning("Anisotropy level is over maximum anisotropy level (" + NzString::Number(anisotropyLevel) + " > " + NzString::Number(s_maxAnisotropyLevel)); - anisotropyLevel = s_maxAnisotropyLevel; - } - - s_defaultAnisotropyLevel = anisotropyLevel; - - if (s_useAnisotropicFilter) - { - for (const std::pair& pair : s_samplers) - { - if (((pair.first >> 5) & 0xFF) == 0) - glSamplerParameterf(pair.second, GL_TEXTURE_MAX_ANISOTROPY_EXT, static_cast(anisotropyLevel)); - } - } -} - -void NzTextureSampler::SetDefaultFilterMode(nzSamplerFilter filterMode) -{ - #if NAZARA_RENDERER_SAFE - if (filterMode == nzSamplerFilter_Default) - { - NazaraError("Default filter mode cannot be set to default enum value (nzSamplerFilter_Default)"); - return; - } - #endif - - s_defaultFilterMode = filterMode; - - for (const std::pair& pair : s_samplers) - { - if (((pair.first >> 1) & 0x3) == nzSamplerFilter_Default) - { - bool mipmaps = pair.first & 0x1; - switch (filterMode) - { - case nzSamplerFilter_Bilinear: - if (mipmaps) - glSamplerParameteri(pair.second, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - else - glSamplerParameteri(pair.second, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - glSamplerParameteri(pair.second, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - break; - - case nzSamplerFilter_Nearest: - if (mipmaps) - glSamplerParameteri(pair.second, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - else - glSamplerParameteri(pair.second, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - glSamplerParameteri(pair.second, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - break; - - case nzSamplerFilter_Trilinear: - if (mipmaps) - glSamplerParameteri(pair.second, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - else - glSamplerParameteri(pair.second, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Filtrage bilinéaire - - glSamplerParameteri(pair.second, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - break; - - default: - NazaraError("Texture filter not handled (0x" + NzString::Number(filterMode, 16) + ')'); - break; - } - } - } -} - -void NzTextureSampler::SetDefaultWrapMode(nzSamplerWrap wrapMode) -{ - #if NAZARA_RENDERER_SAFE - if (wrapMode == nzSamplerWrap_Default) - { - NazaraError("Default wrap mode cannot be set to default enum value (nzSamplerWrap_Default)"); - return; - } - #endif - - s_defaultWrapMode = wrapMode; - - GLenum wrapEnum = NzOpenGL::SamplerWrapMode[wrapMode]; - for (const std::pair& pair : s_samplers) - { - if (((pair.first >> 3) & 0x3) == nzSamplerWrap_Default) - { - glSamplerParameteri(pair.second, GL_TEXTURE_WRAP_R, wrapEnum); - glSamplerParameteri(pair.second, GL_TEXTURE_WRAP_T, wrapEnum); - glSamplerParameteri(pair.second, GL_TEXTURE_WRAP_S, wrapEnum); - } - } -} - -void NzTextureSampler::Apply(const NzTexture* texture) const -{ - nzImageType type = texture->GetType(); - GLenum target = NzOpenGL::TextureTarget[type]; - - NzOpenGL::BindTexture(type, texture->GetOpenGLID()); - - if (s_useAnisotropicFilter) - { - nzUInt8 anisotropyLevel = (m_anisotropicLevel == 0) ? s_defaultAnisotropyLevel : m_anisotropicLevel; - glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, static_cast(anisotropyLevel)); - } - - nzSamplerFilter filterMode = (m_filterMode == nzSamplerFilter_Default) ? s_defaultFilterMode : m_filterMode; - switch (filterMode) - { - case nzSamplerFilter_Bilinear: - if (m_mipmaps) - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); - else - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - break; - - case nzSamplerFilter_Nearest: - if (m_mipmaps) - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); - else - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - break; - - case nzSamplerFilter_Trilinear: - if (m_mipmaps) - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - else - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Filtrage bilinéaire - - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - break; - - default: - NazaraError("Texture filter not handled (0x" + NzString::Number(filterMode, 16) + ')'); - break; - } - - GLenum wrapMode = NzOpenGL::SamplerWrapMode[(m_wrapMode == nzSamplerWrap_Default) ? s_defaultWrapMode : m_wrapMode]; - switch (type) - { - // Notez l'absence de "break" ici - case nzImageType_3D: - glTexParameteri(target, GL_TEXTURE_WRAP_R, wrapMode); - case nzImageType_2D: - case nzImageType_2D_Array: - case nzImageType_Cubemap: - glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode); - case nzImageType_1D: - case nzImageType_1D_Array: - glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode); - break; - } -} - -void NzTextureSampler::Bind(unsigned int unit) const -{ - static_assert(nzSamplerFilter_Max < 0x4, "Maximum sampler filter mode takes more than 2 bits"); - static_assert(nzSamplerWrap_Max < 0x4, "Maximum sampler wrap mode takes more than 2 bits"); - - if (!m_samplerId) - UpdateSamplerId(); - - NzOpenGL::BindSampler(unit, m_samplerId); -} - -unsigned int NzTextureSampler::GetOpenGLID() const -{ - if (!m_samplerId) - UpdateSamplerId(); - - return m_samplerId; -} - -void NzTextureSampler::UpdateSamplerId() const -{ - nzUInt32 key = (((m_mipmaps) ? 1 : 0) << 0) | // 1 bit - (m_filterMode << 1) | // 2 bits - (m_wrapMode << 3) | // 2 bits - (m_anisotropicLevel << 5); // 8 bits - - auto it = s_samplers.find(key); - if (it == s_samplers.end()) - { - GLuint sampler; - glGenSamplers(1, &sampler); + s_defaultAnisotropyLevel = anisotropyLevel; if (s_useAnisotropicFilter) { - nzUInt8 anisotropyLevel = (m_anisotropicLevel == 0) ? s_defaultAnisotropyLevel : m_anisotropicLevel; - glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, static_cast(anisotropyLevel)); + for (const std::pair& pair : s_samplers) + { + if (((pair.first >> 5) & 0xFF) == 0) + glSamplerParameterf(pair.second, GL_TEXTURE_MAX_ANISOTROPY_EXT, static_cast(anisotropyLevel)); + } + } + } + + void TextureSampler::SetDefaultFilterMode(SamplerFilter filterMode) + { + #if NAZARA_RENDERER_SAFE + if (filterMode == SamplerFilter_Default) + { + NazaraError("Default filter mode cannot be set to default enum value (SamplerFilter_Default)"); + return; + } + #endif + + s_defaultFilterMode = filterMode; + + for (const std::pair& pair : s_samplers) + { + if (((pair.first >> 1) & 0x3) == SamplerFilter_Default) + { + bool mipmaps = pair.first & 0x1; + switch (filterMode) + { + case SamplerFilter_Bilinear: + if (mipmaps) + glSamplerParameteri(pair.second, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + else + glSamplerParameteri(pair.second, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glSamplerParameteri(pair.second, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + + case SamplerFilter_Nearest: + if (mipmaps) + glSamplerParameteri(pair.second, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + else + glSamplerParameteri(pair.second, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glSamplerParameteri(pair.second, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + break; + + case SamplerFilter_Trilinear: + if (mipmaps) + glSamplerParameteri(pair.second, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + else + glSamplerParameteri(pair.second, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Filtrage bilinéaire + + glSamplerParameteri(pair.second, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + + default: + NazaraError("Texture filter not handled (0x" + String::Number(filterMode, 16) + ')'); + break; + } + } + } + } + + void TextureSampler::SetDefaultWrapMode(SamplerWrap wrapMode) + { + #if NAZARA_RENDERER_SAFE + if (wrapMode == SamplerWrap_Default) + { + NazaraError("Default wrap mode cannot be set to default enum value (SamplerWrap_Default)"); + return; + } + #endif + + s_defaultWrapMode = wrapMode; + + GLenum wrapEnum = OpenGL::SamplerWrapMode[wrapMode]; + for (const std::pair& pair : s_samplers) + { + if (((pair.first >> 3) & 0x3) == SamplerWrap_Default) + { + glSamplerParameteri(pair.second, GL_TEXTURE_WRAP_R, wrapEnum); + glSamplerParameteri(pair.second, GL_TEXTURE_WRAP_T, wrapEnum); + glSamplerParameteri(pair.second, GL_TEXTURE_WRAP_S, wrapEnum); + } + } + } + + void TextureSampler::Apply(const Texture* texture) const + { + ImageType type = texture->GetType(); + GLenum target = OpenGL::TextureTarget[type]; + + OpenGL::BindTexture(type, texture->GetOpenGLID()); + + if (s_useAnisotropicFilter) + { + UInt8 anisotropyLevel = (m_anisotropicLevel == 0) ? s_defaultAnisotropyLevel : m_anisotropicLevel; + glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, static_cast(anisotropyLevel)); } - nzSamplerFilter filterMode = (m_filterMode == nzSamplerFilter_Default) ? s_defaultFilterMode : m_filterMode; + SamplerFilter filterMode = (m_filterMode == SamplerFilter_Default) ? s_defaultFilterMode : m_filterMode; switch (filterMode) { - case nzSamplerFilter_Bilinear: - glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, (m_mipmaps) ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR); - glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + case SamplerFilter_Bilinear: + if (m_mipmaps) + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + else + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); break; - case nzSamplerFilter_Nearest: - glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, (m_mipmaps) ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST); - glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + case SamplerFilter_Nearest: + if (m_mipmaps) + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); + else + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); break; - case nzSamplerFilter_Trilinear: - // Équivalent au filtrage bilinéaire si les mipmaps sont absentes - glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, (m_mipmaps) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); - glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + case SamplerFilter_Trilinear: + if (m_mipmaps) + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + else + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Filtrage bilinéaire + + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); break; default: - NazaraError("Texture filter not handled (0x" + NzString::Number(filterMode, 16) + ')'); + NazaraError("Texture filter not handled (0x" + String::Number(filterMode, 16) + ')'); break; } - GLenum wrapMode = NzOpenGL::SamplerWrapMode[(m_wrapMode == nzSamplerWrap_Default) ? s_defaultWrapMode : m_wrapMode]; - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, wrapMode); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, wrapMode); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, wrapMode); - - s_samplers[key] = sampler; - m_samplerId = sampler; + GLenum wrapMode = OpenGL::SamplerWrapMode[(m_wrapMode == SamplerWrap_Default) ? s_defaultWrapMode : m_wrapMode]; + switch (type) + { + // Notez l'absence de "break" ici + case ImageType_3D: + glTexParameteri(target, GL_TEXTURE_WRAP_R, wrapMode); + case ImageType_2D: + case ImageType_2D_Array: + case ImageType_Cubemap: + glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode); + case ImageType_1D: + case ImageType_1D_Array: + glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode); + break; + } } - else - m_samplerId = it->second; -} -bool NzTextureSampler::UseMipmaps(bool mipmaps) -{ - if (m_mipmaps != mipmaps) + void TextureSampler::Bind(unsigned int unit) const { - m_mipmaps = mipmaps; - m_samplerId = 0; + static_assert(SamplerFilter_Max < 0x4, "Maximum sampler filter mode takes more than 2 bits"); + static_assert(SamplerWrap_Max < 0x4, "Maximum sampler wrap mode takes more than 2 bits"); - return true; // Renvoie true si la valeur a été changée (Donc s'il faut réappliquer le sampler) + if (!m_samplerId) + UpdateSamplerId(); + + OpenGL::BindSampler(unit, m_samplerId); } - else - return false; -} -bool NzTextureSampler::Initialize() -{ - s_maxAnisotropyLevel = NzRenderer::GetMaxAnisotropyLevel(); - s_useAnisotropicFilter = NzOpenGL::IsSupported(nzOpenGLExtension_AnisotropicFilter); - - return true; -} - -void NzTextureSampler::Uninitialize() -{ - if (!s_samplers.empty()) + unsigned int TextureSampler::GetOpenGLID() const { - NzContext::EnsureContext(); - for (const std::pair& pair : s_samplers) - NzOpenGL::DeleteSampler(pair.second); + if (!m_samplerId) + UpdateSamplerId(); - s_samplers.clear(); + return m_samplerId; } -} -nzUInt8 NzTextureSampler::s_defaultAnisotropyLevel = 1; -nzSamplerFilter NzTextureSampler::s_defaultFilterMode = nzSamplerFilter_Trilinear; -nzSamplerWrap NzTextureSampler::s_defaultWrapMode = nzSamplerWrap_Repeat; + void TextureSampler::UpdateSamplerId() const + { + UInt32 key = (((m_mipmaps) ? 1 : 0) << 0) | // 1 bit + (m_filterMode << 1) | // 2 bits + (m_wrapMode << 3) | // 2 bits + (m_anisotropicLevel << 5); // 8 bits + + auto it = s_samplers.find(key); + if (it == s_samplers.end()) + { + GLuint sampler; + glGenSamplers(1, &sampler); + + if (s_useAnisotropicFilter) + { + UInt8 anisotropyLevel = (m_anisotropicLevel == 0) ? s_defaultAnisotropyLevel : m_anisotropicLevel; + glSamplerParameterf(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, static_cast(anisotropyLevel)); + } + + SamplerFilter filterMode = (m_filterMode == SamplerFilter_Default) ? s_defaultFilterMode : m_filterMode; + switch (filterMode) + { + case SamplerFilter_Bilinear: + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, (m_mipmaps) ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + + case SamplerFilter_Nearest: + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, (m_mipmaps) ? GL_NEAREST_MIPMAP_NEAREST : GL_NEAREST); + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + break; + + case SamplerFilter_Trilinear: + // Équivalent au filtrage bilinéaire si les mipmaps sont absentes + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, (m_mipmaps) ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + break; + + default: + NazaraError("Texture filter not handled (0x" + String::Number(filterMode, 16) + ')'); + break; + } + + GLenum wrapMode = OpenGL::SamplerWrapMode[(m_wrapMode == SamplerWrap_Default) ? s_defaultWrapMode : m_wrapMode]; + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_R, wrapMode); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, wrapMode); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, wrapMode); + + s_samplers[key] = sampler; + m_samplerId = sampler; + } + else + m_samplerId = it->second; + } + + bool TextureSampler::UseMipmaps(bool mipmaps) + { + if (m_mipmaps != mipmaps) + { + m_mipmaps = mipmaps; + m_samplerId = 0; + + return true; // Renvoie true si la valeur a été changée (Donc s'il faut réappliquer le sampler) + } + else + return false; + } + + bool TextureSampler::Initialize() + { + s_maxAnisotropyLevel = Renderer::GetMaxAnisotropyLevel(); + s_useAnisotropicFilter = OpenGL::IsSupported(OpenGLExtension_AnisotropicFilter); + + return true; + } + + void TextureSampler::Uninitialize() + { + if (!s_samplers.empty()) + { + Context::EnsureContext(); + for (const std::pair& pair : s_samplers) + OpenGL::DeleteSampler(pair.second); + + s_samplers.clear(); + } + } + + UInt8 TextureSampler::s_defaultAnisotropyLevel = 1; + SamplerFilter TextureSampler::s_defaultFilterMode = SamplerFilter_Trilinear; + SamplerWrap TextureSampler::s_defaultWrapMode = SamplerWrap_Repeat; +} diff --git a/src/Nazara/Renderer/UberShader.cpp b/src/Nazara/Renderer/UberShader.cpp index 3477354d0..18a3c11fe 100644 --- a/src/Nazara/Renderer/UberShader.cpp +++ b/src/Nazara/Renderer/UberShader.cpp @@ -5,25 +5,28 @@ #include #include -NzUberShader::~NzUberShader() +namespace Nz { - OnUberShaderRelease(this); -} - -bool NzUberShader::Initialize() -{ - if (!NzUberShaderLibrary::Initialize()) + UberShader::~UberShader() { - NazaraError("Failed to initialise library"); - return false; + OnUberShaderRelease(this); } - return true; -} + bool UberShader::Initialize() + { + if (!UberShaderLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } -void NzUberShader::Uninitialize() -{ - NzUberShaderLibrary::Uninitialize(); -} + return true; + } -NzUberShaderLibrary::LibraryMap NzUberShader::s_library; + void UberShader::Uninitialize() + { + UberShaderLibrary::Uninitialize(); + } + + UberShaderLibrary::LibraryMap UberShader::s_library; +} diff --git a/src/Nazara/Renderer/UberShaderInstance.cpp b/src/Nazara/Renderer/UberShaderInstance.cpp index 367c96bf3..ec7043542 100644 --- a/src/Nazara/Renderer/UberShaderInstance.cpp +++ b/src/Nazara/Renderer/UberShaderInstance.cpp @@ -6,14 +6,17 @@ #include #include -NzUberShaderInstance::NzUberShaderInstance(const NzShader* shader) : -m_shader(shader) +namespace Nz { -} + UberShaderInstance::UberShaderInstance(const Shader* shader) : + m_shader(shader) + { + } -NzUberShaderInstance::~NzUberShaderInstance() = default; + UberShaderInstance::~UberShaderInstance() = default; -const NzShader* NzUberShaderInstance::GetShader() const -{ - return m_shader; + const Shader* UberShaderInstance::GetShader() const + { + return m_shader; + } } diff --git a/src/Nazara/Renderer/UberShaderInstancePreprocessor.cpp b/src/Nazara/Renderer/UberShaderInstancePreprocessor.cpp index 422d936b4..166645528 100644 --- a/src/Nazara/Renderer/UberShaderInstancePreprocessor.cpp +++ b/src/Nazara/Renderer/UberShaderInstancePreprocessor.cpp @@ -6,16 +6,19 @@ #include #include -NzUberShaderInstancePreprocessor::NzUberShaderInstancePreprocessor(const NzShader* shader) : -NzUberShaderInstance(shader) +namespace Nz { -} - -NzUberShaderInstancePreprocessor::~NzUberShaderInstancePreprocessor() = default; - -bool NzUberShaderInstancePreprocessor::Activate() const -{ - NzRenderer::SetShader(m_shader); - - return true; + UberShaderInstancePreprocessor::UberShaderInstancePreprocessor(const Shader* shader) : + UberShaderInstance(shader) + { + } + + UberShaderInstancePreprocessor::~UberShaderInstancePreprocessor() = default; + + bool UberShaderInstancePreprocessor::Activate() const + { + Renderer::SetShader(m_shader); + + return true; + } } diff --git a/src/Nazara/Renderer/UberShaderPreprocessor.cpp b/src/Nazara/Renderer/UberShaderPreprocessor.cpp index 6d41cfb7d..2a08088f5 100644 --- a/src/Nazara/Renderer/UberShaderPreprocessor.cpp +++ b/src/Nazara/Renderer/UberShaderPreprocessor.cpp @@ -10,175 +10,178 @@ #include #include -NzUberShaderPreprocessor::~NzUberShaderPreprocessor() +namespace Nz { - OnUberShaderPreprocessorRelease(this); -} - -NzUberShaderInstance* NzUberShaderPreprocessor::Get(const NzParameterList& parameters) const -{ - // Première étape, transformer les paramètres en un flag - nzUInt32 flags = 0; - for (auto it = m_flags.begin(); it != m_flags.end(); ++it) + UberShaderPreprocessor::~UberShaderPreprocessor() { - if (parameters.HasParameter(it->first)) - { - bool value; - if (parameters.GetBooleanParameter(it->first, &value) && value) - flags |= it->second; - } + OnUberShaderPreprocessorRelease(this); } - // Le shader fait-il partie du cache ? - auto shaderIt = m_cache.find(flags); - - // Si non, il nous faut le construire - if (shaderIt == m_cache.end()) + UberShaderInstance* UberShaderPreprocessor::Get(const ParameterList& parameters) const { - try + // Première étape, transformer les paramètres en un flag + UInt32 flags = 0; + for (auto it = m_flags.begin(); it != m_flags.end(); ++it) { - // Une exception sera lancée à la moindre erreur et celle-ci ne sera pas enregistrée dans le log (car traitée dans le bloc catch) - NzErrorFlags errFlags(nzErrorFlag_Silent | nzErrorFlag_ThrowException, true); - - NzShaderRef shader = NzShader::New(); - shader->Create(); - - for (unsigned int i = 0; i <= nzShaderStage_Max; ++i) + if (parameters.HasParameter(it->first)) { - const Shader& shaderStage = m_shaders[i]; - - // Le shader stage est-il activé dans cette version du shader ? - if (shaderStage.present && (flags & shaderStage.requiredFlags) == shaderStage.requiredFlags) - { - nzUInt32 stageFlags = 0; - for (auto it = shaderStage.flags.begin(); it != shaderStage.flags.end(); ++it) - { - if (parameters.HasParameter(it->first)) - { - bool value; - if (parameters.GetBooleanParameter(it->first, &value) && value) - stageFlags |= it->second; - } - } - - auto stageIt = shaderStage.cache.find(stageFlags); - if (stageIt == shaderStage.cache.end()) - { - NzShaderStage stage; - stage.Create(static_cast(i)); - - unsigned int glslVersion = NzOpenGL::GetGLSLVersion(); - - NzStringStream code; - code << "#version " << glslVersion << "\n\n"; - - code << "#define GLSL_VERSION " << glslVersion << "\n\n"; - - code << "#define EARLY_FRAGMENT_TEST " << (glslVersion >= 420 || NzOpenGL::IsSupported(nzOpenGLExtension_Shader_ImageLoadStore)) << "\n\n"; - - for (auto it = shaderStage.flags.begin(); it != shaderStage.flags.end(); ++it) - code << "#define " << it->first << ' ' << ((stageFlags & it->second) ? '1' : '0') << '\n'; - - code << "\n#line 1\n"; // Pour que les éventuelles erreurs du shader se réfèrent à la bonne ligne - code << shaderStage.source; - - stage.SetSource(code); - stage.Compile(); - - stageIt = shaderStage.cache.emplace(flags, std::move(stage)).first; - } - - shader->AttachStage(static_cast(i), stageIt->second); - } + bool value; + if (parameters.GetBooleanParameter(it->first, &value) && value) + flags |= it->second; } - - shader->Link(); - - // On construit l'instant - shaderIt = m_cache.emplace(flags, shader.Get()).first; } - catch (const std::exception&) + + // Le shader fait-il partie du cache ? + auto shaderIt = m_cache.find(flags); + + // Si non, il nous faut le construire + if (shaderIt == m_cache.end()) { - NzErrorFlags errFlags(nzErrorFlag_ThrowExceptionDisabled); + try + { + // Une exception sera lancée à la moindre erreur et celle-ci ne sera pas enregistrée dans le log (car traitée dans le bloc catch) + ErrorFlags errFlags(ErrorFlag_Silent | ErrorFlag_ThrowException, true); - NazaraError("Failed to build UberShader instance: " + NzError::GetLastError()); - throw; + ShaderRef shader = Shader::New(); + shader->Create(); + + for (unsigned int i = 0; i <= ShaderStageType_Max; ++i) + { + const CachedShader& shaderStage = m_shaders[i]; + + // Le shader stage est-il activé dans cette version du shader ? + if (shaderStage.present && (flags & shaderStage.requiredFlags) == shaderStage.requiredFlags) + { + UInt32 stageFlags = 0; + for (auto it = shaderStage.flags.begin(); it != shaderStage.flags.end(); ++it) + { + if (parameters.HasParameter(it->first)) + { + bool value; + if (parameters.GetBooleanParameter(it->first, &value) && value) + stageFlags |= it->second; + } + } + + auto stageIt = shaderStage.cache.find(stageFlags); + if (stageIt == shaderStage.cache.end()) + { + ShaderStage stage; + stage.Create(static_cast(i)); + + unsigned int glslVersion = OpenGL::GetGLSLVersion(); + + StringStream code; + code << "#version " << glslVersion << "\n\n"; + + code << "#define GLSL_VERSION " << glslVersion << "\n\n"; + + code << "#define EARLY_FRAGMENT_TEST " << (glslVersion >= 420 || OpenGL::IsSupported(OpenGLExtension_Shader_ImageLoadStore)) << "\n\n"; + + for (auto it = shaderStage.flags.begin(); it != shaderStage.flags.end(); ++it) + code << "#define " << it->first << ' ' << ((stageFlags & it->second) ? '1' : '0') << '\n'; + + code << "\n#line 1\n"; // Pour que les éventuelles erreurs du shader se réfèrent à la bonne ligne + code << shaderStage.source; + + stage.SetSource(code); + stage.Compile(); + + stageIt = shaderStage.cache.emplace(flags, std::move(stage)).first; + } + + shader->AttachStage(static_cast(i), stageIt->second); + } + } + + shader->Link(); + + // On construit l'instant + shaderIt = m_cache.emplace(flags, shader.Get()).first; + } + catch (const std::exception&) + { + ErrorFlags errFlags(ErrorFlag_ThrowExceptionDisabled); + + NazaraError("Failed to build UberShader instance: " + Error::GetLastError()); + throw; + } } + + return &shaderIt->second; } - return &shaderIt->second; -} - -void NzUberShaderPreprocessor::SetShader(nzShaderStage stage, const NzString& source, const NzString& shaderFlags, const NzString& requiredFlags) -{ - Shader& shader = m_shaders[stage]; - shader.present = true; - shader.source = source; - - // On extrait les flags de la chaîne - std::vector flags; - shaderFlags.Split(flags, ' '); - - for (NzString& flag : flags) + void UberShaderPreprocessor::SetShader(ShaderStageType stage, const String& source, const String& shaderFlags, const String& requiredFlags) { - auto it = m_flags.find(flag); - if (it == m_flags.end()) - m_flags[flag] = 1U << m_flags.size(); + CachedShader& shader = m_shaders[stage]; + shader.present = true; + shader.source = source; - auto it2 = shader.flags.find(flag); - if (it2 == shader.flags.end()) - shader.flags[flag] = 1U << shader.flags.size(); - } + // On extrait les flags de la chaîne + std::vector flags; + shaderFlags.Split(flags, ' '); - // On construit les flags requis pour l'activation du shader - shader.requiredFlags = 0; - - flags.clear(); - requiredFlags.Split(flags, ' '); - - for (NzString& flag : flags) - { - nzUInt32 flagVal; - - auto it = m_flags.find(flag); - if (it == m_flags.end()) + for (String& flag : flags) { - flagVal = 1U << m_flags.size(); - m_flags[flag] = flagVal; + auto it = m_flags.find(flag); + if (it == m_flags.end()) + m_flags[flag] = 1U << m_flags.size(); + + auto it2 = shader.flags.find(flag); + if (it2 == shader.flags.end()) + shader.flags[flag] = 1U << shader.flags.size(); } - else - flagVal = it->second; - shader.requiredFlags |= flagVal; + // On construit les flags requis pour l'activation du shader + shader.requiredFlags = 0; + + flags.clear(); + requiredFlags.Split(flags, ' '); + + for (String& flag : flags) + { + UInt32 flagVal; + + auto it = m_flags.find(flag); + if (it == m_flags.end()) + { + flagVal = 1U << m_flags.size(); + m_flags[flag] = flagVal; + } + else + flagVal = it->second; + + shader.requiredFlags |= flagVal; + } } -} -bool NzUberShaderPreprocessor::SetShaderFromFile(nzShaderStage stage, const NzString& filePath, const NzString& shaderFlags, const NzString& requiredFlags) -{ - NzFile file(filePath); - if (!file.Open(nzOpenMode_ReadOnly | nzOpenMode_Text)) + bool UberShaderPreprocessor::SetShaderFromFile(ShaderStageType stage, const String& filePath, const String& shaderFlags, const String& requiredFlags) { - NazaraError("Failed to open \"" + filePath + '"'); - return false; + File file(filePath); + if (!file.Open(OpenMode_ReadOnly | OpenMode_Text)) + { + NazaraError("Failed to open \"" + filePath + '"'); + return false; + } + + unsigned int length = static_cast(file.GetSize()); + + String source(length, '\0'); + + if (file.Read(&source[0], length) != length) + { + NazaraError("Failed to read program file"); + return false; + } + + file.Close(); + + SetShader(stage, source, shaderFlags, requiredFlags); + return true; } - unsigned int length = static_cast(file.GetSize()); - - NzString source(length, '\0'); - - if (file.Read(&source[0], length) != length) + bool UberShaderPreprocessor::IsSupported() { - NazaraError("Failed to read program file"); - return false; + return true; // Forcément supporté } - - file.Close(); - - SetShader(stage, source, shaderFlags, requiredFlags); - return true; -} - -bool NzUberShaderPreprocessor::IsSupported() -{ - return true; // Forcément supporté } diff --git a/src/Nazara/Renderer/Win32/ContextImpl.cpp b/src/Nazara/Renderer/Win32/ContextImpl.cpp index 7ee7a4497..2f7094f70 100644 --- a/src/Nazara/Renderer/Win32/ContextImpl.cpp +++ b/src/Nazara/Renderer/Win32/ContextImpl.cpp @@ -14,232 +14,235 @@ #include #include -NzContextImpl::NzContextImpl() +namespace Nz { -} - -bool NzContextImpl::Activate() -{ - return wglMakeCurrent(m_deviceContext, m_context) == TRUE; -} - -bool NzContextImpl::Create(NzContextParameters& parameters) -{ - if (parameters.window) + ContextImpl::ContextImpl() { - m_window = static_cast(parameters.window); - m_ownsWindow = false; } - else + + bool ContextImpl::Activate() { - m_window = CreateWindowA("STATIC", nullptr, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, nullptr, nullptr, GetModuleHandle(nullptr), nullptr); - if (!m_window) + return wglMakeCurrent(m_deviceContext, m_context) == TRUE; + } + + bool ContextImpl::Create(ContextParameters& parameters) + { + if (parameters.window) { - NazaraError("Failed to create window"); - return false; - } - - ShowWindow(m_window, SW_HIDE); - m_ownsWindow = true; - } - - // En cas d'exception, la ressource sera quand même libérée - NzCallOnExit onExit([this] () - { - Destroy(); - }); - - m_deviceContext = GetDC(m_window); - if (!m_deviceContext) - { - NazaraError("Failed to get device context"); - return false; - } - - int pixelFormat = 0; - if (parameters.antialiasingLevel > 0) - { - if (wglChoosePixelFormat) - { - bool valid; - UINT numFormats; - - int attributes[] = { - WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, - WGL_SUPPORT_OPENGL_ARB, GL_TRUE, - WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, - WGL_COLOR_BITS_ARB, (parameters.bitsPerPixel == 32) ? 24 : parameters.bitsPerPixel, - WGL_ALPHA_BITS_ARB, (parameters.bitsPerPixel == 32) ? 8 : 0, - WGL_DEPTH_BITS_ARB, parameters.depthBits, - WGL_STENCIL_BITS_ARB, parameters.stencilBits, - WGL_DOUBLE_BUFFER_ARB, (parameters.doubleBuffered) ? GL_TRUE : GL_FALSE, - WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, - WGL_SAMPLES_ARB, parameters.antialiasingLevel, - 0, 0 - }; - - do - { - valid = (wglChoosePixelFormat(m_deviceContext, attributes, nullptr, 1, &pixelFormat, &numFormats) == TRUE); - } - while ((!valid || numFormats == 0) && --attributes[19] > 0); - - if (!valid) - { - NazaraWarning("Could not find a format matching requirements, disabling antialiasing..."); - pixelFormat = 0; - } - - parameters.antialiasingLevel = attributes[19]; + m_window = static_cast(parameters.window); + m_ownsWindow = false; } else { - NazaraWarning("Antialiasing is not supported"); - parameters.antialiasingLevel = 0; + m_window = CreateWindowA("STATIC", nullptr, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, nullptr, nullptr, GetModuleHandle(nullptr), nullptr); + if (!m_window) + { + NazaraError("Failed to create window"); + return false; + } + + ShowWindow(m_window, SW_HIDE); + m_ownsWindow = true; } - } - PIXELFORMATDESCRIPTOR descriptor; - ZeroMemory(&descriptor, sizeof(PIXELFORMATDESCRIPTOR)); - descriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR); - descriptor.nVersion = 1; - - if (pixelFormat == 0) - { - descriptor.cColorBits = parameters.bitsPerPixel; - descriptor.cDepthBits = parameters.depthBits; - descriptor.cStencilBits = parameters.stencilBits; - descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; - descriptor.iPixelType = PFD_TYPE_RGBA; - - if (parameters.bitsPerPixel == 32) - descriptor.cAlphaBits = 8; - - if (parameters.doubleBuffered) - descriptor.dwFlags |= PFD_DOUBLEBUFFER; - - pixelFormat = ChoosePixelFormat(m_deviceContext, &descriptor); - if (pixelFormat == 0) + // En cas d'exception, la ressource sera quand même libérée + CallOnExit onExit([this] () { - NazaraError("Failed to choose pixel format"); + Destroy(); + }); + + m_deviceContext = GetDC(m_window); + if (!m_deviceContext) + { + NazaraError("Failed to get device context"); return false; } - } - if (!SetPixelFormat(m_deviceContext, pixelFormat, &descriptor)) - { - NazaraError("Failed to set pixel format"); - return false; - } - - // Arrivé ici, le format de pixel est choisi, nous récupérons donc les paramètres réels du futur contexte - if (DescribePixelFormat(m_deviceContext, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &descriptor) != 0) - { - parameters.bitsPerPixel = descriptor.cColorBits + descriptor.cAlphaBits; - parameters.depthBits = descriptor.cDepthBits; - parameters.stencilBits = descriptor.cDepthBits; - } - else - NazaraWarning("Failed to get context's parameters"); - - HGLRC shareContext = (parameters.shared) ? static_cast(parameters.shareContext->m_impl)->m_context : nullptr; - - m_context = nullptr; - if (wglCreateContextAttribs) - { - int attributes[4*2+1]; - int* attrib = attributes; - - *attrib++ = WGL_CONTEXT_MAJOR_VERSION_ARB; - *attrib++ = parameters.majorVersion; - - *attrib++ = WGL_CONTEXT_MINOR_VERSION_ARB; - *attrib++ = parameters.minorVersion; - - if (parameters.majorVersion >= 3) + int pixelFormat = 0; + if (parameters.antialiasingLevel > 0) { - *attrib++ = WGL_CONTEXT_PROFILE_MASK_ARB; - *attrib++ = (parameters.compatibilityProfile) ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + if (wglChoosePixelFormat) + { + bool valid; + UINT numFormats; - // Les contextes forward-compatible ne sont plus utilisés pour cette raison : - // http://www.opengl.org/discussion_boards/showthread.php/175052-Forward-compatible-vs-Core-profile + int attributes[] = { + WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, + WGL_SUPPORT_OPENGL_ARB, GL_TRUE, + WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, + WGL_COLOR_BITS_ARB, (parameters.bitsPerPixel == 32) ? 24 : parameters.bitsPerPixel, + WGL_ALPHA_BITS_ARB, (parameters.bitsPerPixel == 32) ? 8 : 0, + WGL_DEPTH_BITS_ARB, parameters.depthBits, + WGL_STENCIL_BITS_ARB, parameters.stencilBits, + WGL_DOUBLE_BUFFER_ARB, (parameters.doubleBuffered) ? GL_TRUE : GL_FALSE, + WGL_SAMPLE_BUFFERS_ARB, GL_TRUE, + WGL_SAMPLES_ARB, parameters.antialiasingLevel, + 0, 0 + }; + + do + { + valid = (wglChoosePixelFormat(m_deviceContext, attributes, nullptr, 1, &pixelFormat, &numFormats) == TRUE); + } + while ((!valid || numFormats == 0) && --attributes[19] > 0); + + if (!valid) + { + NazaraWarning("Could not find a format matching requirements, disabling antialiasing..."); + pixelFormat = 0; + } + + parameters.antialiasingLevel = attributes[19]; + } + else + { + NazaraWarning("Antialiasing is not supported"); + parameters.antialiasingLevel = 0; + } } - if (parameters.debugMode) + PIXELFORMATDESCRIPTOR descriptor; + ZeroMemory(&descriptor, sizeof(PIXELFORMATDESCRIPTOR)); + descriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR); + descriptor.nVersion = 1; + + if (pixelFormat == 0) { - *attrib++ = WGL_CONTEXT_FLAGS_ARB; - *attrib++ = WGL_CONTEXT_DEBUG_BIT_ARB; + descriptor.cColorBits = parameters.bitsPerPixel; + descriptor.cDepthBits = parameters.depthBits; + descriptor.cStencilBits = parameters.stencilBits; + descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; + descriptor.iPixelType = PFD_TYPE_RGBA; + + if (parameters.bitsPerPixel == 32) + descriptor.cAlphaBits = 8; + + if (parameters.doubleBuffered) + descriptor.dwFlags |= PFD_DOUBLEBUFFER; + + pixelFormat = ChoosePixelFormat(m_deviceContext, &descriptor); + if (pixelFormat == 0) + { + NazaraError("Failed to choose pixel format"); + return false; + } } - *attrib++ = 0; - - m_context = wglCreateContextAttribs(m_deviceContext, shareContext, attributes); - } - - if (!m_context) - { - m_context = wglCreateContext(m_deviceContext); - - if (shareContext) + if (!SetPixelFormat(m_deviceContext, pixelFormat, &descriptor)) { - // wglShareLists n'est pas thread-safe (source: SFML) - static NzMutex mutex; - NzLockGuard lock(mutex); - - if (!wglShareLists(shareContext, m_context)) - NazaraWarning("Failed to share the context: " + NzError::GetLastSystemError()); + NazaraError("Failed to set pixel format"); + return false; } - } - if (!m_context) - { - NazaraError("Failed to create context"); - return false; - } + // Arrivé ici, le format de pixel est choisi, nous récupérons donc les paramètres réels du futur contexte + if (DescribePixelFormat(m_deviceContext, pixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &descriptor) != 0) + { + parameters.bitsPerPixel = descriptor.cColorBits + descriptor.cAlphaBits; + parameters.depthBits = descriptor.cDepthBits; + parameters.stencilBits = descriptor.cDepthBits; + } + else + NazaraWarning("Failed to get context's parameters"); - onExit.Reset(); + HGLRC shareContext = (parameters.shared) ? static_cast(parameters.shareContext->m_impl)->m_context : nullptr; - return true; -} - -void NzContextImpl::Destroy() -{ - if (m_context) - { - if (wglGetCurrentContext() == m_context) - wglMakeCurrent(nullptr, nullptr); - - wglDeleteContext(m_context); m_context = nullptr; + if (wglCreateContextAttribs) + { + int attributes[4*2+1]; + int* attrib = attributes; + + *attrib++ = WGL_CONTEXT_MAJOR_VERSION_ARB; + *attrib++ = parameters.majorVersion; + + *attrib++ = WGL_CONTEXT_MINOR_VERSION_ARB; + *attrib++ = parameters.minorVersion; + + if (parameters.majorVersion >= 3) + { + *attrib++ = WGL_CONTEXT_PROFILE_MASK_ARB; + *attrib++ = (parameters.compatibilityProfile) ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB; + + // Les contextes forward-compatible ne sont plus utilisés pour cette raison : + // http://www.opengl.org/discussion_boards/showthread.php/175052-Forward-compatible-vs-Core-profile + } + + if (parameters.debugMode) + { + *attrib++ = WGL_CONTEXT_FLAGS_ARB; + *attrib++ = WGL_CONTEXT_DEBUG_BIT_ARB; + } + + *attrib++ = 0; + + m_context = wglCreateContextAttribs(m_deviceContext, shareContext, attributes); + } + + if (!m_context) + { + m_context = wglCreateContext(m_deviceContext); + + if (shareContext) + { + // wglShareLists n'est pas thread-safe (source: SFML) + static Mutex mutex; + LockGuard lock(mutex); + + if (!wglShareLists(shareContext, m_context)) + NazaraWarning("Failed to share the context: " + Error::GetLastSystemError()); + } + } + + if (!m_context) + { + NazaraError("Failed to create context"); + return false; + } + + onExit.Reset(); + + return true; } - if (m_deviceContext) + void ContextImpl::Destroy() { - ReleaseDC(m_window, m_deviceContext); - m_deviceContext = nullptr; + if (m_context) + { + if (wglGetCurrentContext() == m_context) + wglMakeCurrent(nullptr, nullptr); + + wglDeleteContext(m_context); + m_context = nullptr; + } + + if (m_deviceContext) + { + ReleaseDC(m_window, m_deviceContext); + m_deviceContext = nullptr; + } + + if (m_ownsWindow) + { + DestroyWindow(m_window); + m_window = nullptr; + } } - if (m_ownsWindow) + void ContextImpl::EnableVerticalSync(bool enabled) { - DestroyWindow(m_window); - m_window = nullptr; + if (wglSwapInterval) + wglSwapInterval(enabled ? 1 : 0); + else + NazaraError("Vertical sync not supported"); + } + + void ContextImpl::SwapBuffers() + { + ::SwapBuffers(m_deviceContext); + } + + bool ContextImpl::Desactivate() + { + return wglMakeCurrent(nullptr, nullptr) == TRUE; } } - -void NzContextImpl::EnableVerticalSync(bool enabled) -{ - if (wglSwapInterval) - wglSwapInterval(enabled ? 1 : 0); - else - NazaraError("Vertical sync not supported"); -} - -void NzContextImpl::SwapBuffers() -{ - ::SwapBuffers(m_deviceContext); -} - -bool NzContextImpl::Desactivate() -{ - return wglMakeCurrent(nullptr, nullptr) == TRUE; -} diff --git a/src/Nazara/Renderer/Win32/ContextImpl.hpp b/src/Nazara/Renderer/Win32/ContextImpl.hpp index 4a4b400f0..0e5c7cbc9 100644 --- a/src/Nazara/Renderer/Win32/ContextImpl.hpp +++ b/src/Nazara/Renderer/Win32/ContextImpl.hpp @@ -11,28 +11,31 @@ #include #include -class NzContextImpl +namespace Nz { - public: - NzContextImpl(); + class ContextImpl + { + public: + ContextImpl(); - bool Activate(); + bool Activate(); - bool Create(NzContextParameters& parameters); + bool Create(ContextParameters& parameters); - void Destroy(); + void Destroy(); - void EnableVerticalSync(bool enabled); + void EnableVerticalSync(bool enabled); - void SwapBuffers(); + void SwapBuffers(); - static bool Desactivate(); + static bool Desactivate(); - private: - HDC m_deviceContext; - HGLRC m_context; - HWND m_window; - bool m_ownsWindow; -}; + private: + HDC m_deviceContext; + HGLRC m_context; + HWND m_window; + bool m_ownsWindow; + }; +} #endif // NAZARA_CONTEXTIMPL_HPP diff --git a/src/Nazara/Utility/AbstractAtlas.cpp b/src/Nazara/Utility/AbstractAtlas.cpp index 59b04762e..555b0beae 100644 --- a/src/Nazara/Utility/AbstractAtlas.cpp +++ b/src/Nazara/Utility/AbstractAtlas.cpp @@ -5,7 +5,10 @@ #include #include -NzAbstractAtlas::~NzAbstractAtlas() +namespace Nz { - OnAtlasRelease(this); + AbstractAtlas::~AbstractAtlas() + { + OnAtlasRelease(this); + } } diff --git a/src/Nazara/Utility/AbstractBuffer.cpp b/src/Nazara/Utility/AbstractBuffer.cpp index 76b82b07d..e7bd5ce19 100644 --- a/src/Nazara/Utility/AbstractBuffer.cpp +++ b/src/Nazara/Utility/AbstractBuffer.cpp @@ -5,4 +5,7 @@ #include #include -NzAbstractBuffer::~NzAbstractBuffer() = default; +namespace Nz +{ + AbstractBuffer::~AbstractBuffer() = default; +} diff --git a/src/Nazara/Utility/AbstractImage.cpp b/src/Nazara/Utility/AbstractImage.cpp index 9e5ea28a0..414f60cb4 100644 --- a/src/Nazara/Utility/AbstractImage.cpp +++ b/src/Nazara/Utility/AbstractImage.cpp @@ -6,19 +6,22 @@ #include #include -NzAbstractImage::~NzAbstractImage() = default; - -nzUInt8 NzAbstractImage::GetBytesPerPixel() const +namespace Nz { - return NzPixelFormat::GetBytesPerPixel(GetFormat()); -} + AbstractImage::~AbstractImage() = default; -bool NzAbstractImage::IsCompressed() const -{ - return NzPixelFormat::IsCompressed(GetFormat()); -} + UInt8 AbstractImage::GetBytesPerPixel() const + { + return NzPixelFormat::GetBytesPerPixel(GetFormat()); + } -bool NzAbstractImage::IsCubemap() const -{ - return GetType() == nzImageType_Cubemap; + bool AbstractImage::IsCompressed() const + { + return NzPixelFormat::IsCompressed(GetFormat()); + } + + bool AbstractImage::IsCubemap() const + { + return GetType() == ImageType_Cubemap; + } } diff --git a/src/Nazara/Utility/AbstractTextDrawer.cpp b/src/Nazara/Utility/AbstractTextDrawer.cpp index 289836751..c6eb131ae 100644 --- a/src/Nazara/Utility/AbstractTextDrawer.cpp +++ b/src/Nazara/Utility/AbstractTextDrawer.cpp @@ -5,5 +5,8 @@ #include #include -NzAbstractTextDrawer::~NzAbstractTextDrawer() = default; +namespace Nz +{ + AbstractTextDrawer::~AbstractTextDrawer() = default; +} diff --git a/src/Nazara/Utility/Algorithm.cpp b/src/Nazara/Utility/Algorithm.cpp index 9bfe7e475..dbadfe149 100644 --- a/src/Nazara/Utility/Algorithm.cpp +++ b/src/Nazara/Utility/Algorithm.cpp @@ -32,1135 +32,1138 @@ #include #include -namespace +namespace Nz { - class IcoSphereBuilder + namespace { - public: - explicit IcoSphereBuilder(const NzMatrix4f& matrix) : - m_matrix(matrix) - { - } - - void Generate(float size, unsigned int recursionLevel, const NzRectf& textureCoords, NzVertexPointers vertexPointers, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) - { - // Grandement inspiré de http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html - const float t = (1.f + 2.236067f)/2.f; - - m_cache.clear(); - m_size = size; - m_vertices = vertexPointers; - m_vertexIndex = 0; - - // Sommets de base - AddVertex({-1.f, t, 0.f}); - AddVertex({ 1.f, t, 0.f}); - AddVertex({-1.f, -t, 0.f}); - AddVertex({ 1.f, -t, 0.f}); - - AddVertex({0.f, -1.f, t}); - AddVertex({0.f, 1.f, t}); - AddVertex({0.f, -1.f, -t}); - AddVertex({0.f, 1.f, -t}); - - AddVertex({ t, 0.f, -1.f}); - AddVertex({ t, 0.f, 1.f}); - AddVertex({-t, 0.f, -1.f}); - AddVertex({-t, 0.f, 1.f}); - - std::vector triangles; - triangles.reserve(20 * NzIntegralPow(4, recursionLevel)); - - // Cinq triangles autour du premier point - triangles.push_back({0, 11, 5}); - triangles.push_back({0, 5, 1}); - triangles.push_back({0, 1, 7}); - triangles.push_back({0, 7, 10}); - triangles.push_back({0, 10, 11}); - - // Cinq faces adjaçentes - triangles.push_back({ 1, 5, 9}); - triangles.push_back({ 5, 11, 4}); - triangles.push_back({11, 10, 2}); - triangles.push_back({10, 7, 6}); - triangles.push_back({ 7, 1, 8}); - - // Cinq triangles autour du troisième point - triangles.push_back({3, 9, 4}); - triangles.push_back({3, 4, 2}); - triangles.push_back({3, 2, 6}); - triangles.push_back({3, 6, 8}); - triangles.push_back({3, 8, 9}); - - // Cinq faces adjaçentes - triangles.push_back({4, 9, 5}); - triangles.push_back({2, 4, 11}); - triangles.push_back({6, 2, 10}); - triangles.push_back({8, 6, 7}); - triangles.push_back({9, 8, 1}); - - // Et maintenant on affine la sphère - for (unsigned int i = 0; i < recursionLevel; ++i) + class IcoSphereBuilder + { + public: + explicit IcoSphereBuilder(const Matrix4f& matrix) : + m_matrix(matrix) { - for (NzVector3ui& triangle : triangles) + } + + void Generate(float size, unsigned int recursionLevel, const Rectf& textureCoords, VertexPointers vertexPointers, IndexIterator indices, Boxf* aabb, unsigned int indexOffset) + { + // Grandement inspiré de http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html + const float t = (1.f + 2.236067f)/2.f; + + m_cache.clear(); + m_size = size; + m_vertices = vertexPointers; + m_vertexIndex = 0; + + // Sommets de base + AddVertex({-1.f, t, 0.f}); + AddVertex({ 1.f, t, 0.f}); + AddVertex({-1.f, -t, 0.f}); + AddVertex({ 1.f, -t, 0.f}); + + AddVertex({0.f, -1.f, t}); + AddVertex({0.f, 1.f, t}); + AddVertex({0.f, -1.f, -t}); + AddVertex({0.f, 1.f, -t}); + + AddVertex({ t, 0.f, -1.f}); + AddVertex({ t, 0.f, 1.f}); + AddVertex({-t, 0.f, -1.f}); + AddVertex({-t, 0.f, 1.f}); + + std::vector triangles; + triangles.reserve(20 * IntegralPow(4, recursionLevel)); + + // Cinq triangles autour du premier point + triangles.push_back({0, 11, 5}); + triangles.push_back({0, 5, 1}); + triangles.push_back({0, 1, 7}); + triangles.push_back({0, 7, 10}); + triangles.push_back({0, 10, 11}); + + // Cinq faces adjaçentes + triangles.push_back({ 1, 5, 9}); + triangles.push_back({ 5, 11, 4}); + triangles.push_back({11, 10, 2}); + triangles.push_back({10, 7, 6}); + triangles.push_back({ 7, 1, 8}); + + // Cinq triangles autour du troisième point + triangles.push_back({3, 9, 4}); + triangles.push_back({3, 4, 2}); + triangles.push_back({3, 2, 6}); + triangles.push_back({3, 6, 8}); + triangles.push_back({3, 8, 9}); + + // Cinq faces adjaçentes + triangles.push_back({4, 9, 5}); + triangles.push_back({2, 4, 11}); + triangles.push_back({6, 2, 10}); + triangles.push_back({8, 6, 7}); + triangles.push_back({9, 8, 1}); + + // Et maintenant on affine la sphère + for (unsigned int i = 0; i < recursionLevel; ++i) { - unsigned int a = GetMiddleVertex(triangle.x, triangle.y); - unsigned int b = GetMiddleVertex(triangle.y, triangle.z); - unsigned int c = GetMiddleVertex(triangle.z, triangle.x); + for (Vector3ui& triangle : triangles) + { + unsigned int a = GetMiddleVertex(triangle.x, triangle.y); + unsigned int b = GetMiddleVertex(triangle.y, triangle.z); + unsigned int c = GetMiddleVertex(triangle.z, triangle.x); - triangles.push_back({triangle.x, a, c}); - triangles.push_back({triangle.y, b, a}); - triangles.push_back({triangle.z, c, b}); + triangles.push_back({triangle.x, a, c}); + triangles.push_back({triangle.y, b, a}); + triangles.push_back({triangle.z, c, b}); - triangle.Set(a, b, c); // Réutilisation du triangle + triangle.Set(a, b, c); // Réutilisation du triangle + } + } + + for (const Vector3ui& triangle : triangles) + { + *indices++ = triangle.x + indexOffset; + *indices++ = triangle.y + indexOffset; + *indices++ = triangle.z + indexOffset; + } + + if (aabb) + { + Vector3f totalSize = size * m_matrix.GetScale(); + aabb->Set(-totalSize, totalSize); } } - for (const NzVector3ui& triangle : triangles) + unsigned int AddVertex(const Vector3f& position) { - *indices++ = triangle.x + indexOffset; - *indices++ = triangle.y + indexOffset; - *indices++ = triangle.z + indexOffset; + m_vertices.normalPtr[m_vertexIndex] = Vector3f::Normalize(m_matrix.Transform(position, 0.f)); + m_vertices.positionPtr[m_vertexIndex] = m_matrix.Transform(m_size * position.GetNormal()); + + return m_vertexIndex++; } - if (aabb) + unsigned int GetMiddleVertex(unsigned int index1, unsigned int index2) { - NzVector3f totalSize = size * m_matrix.GetScale(); - aabb->Set(-totalSize, totalSize); + UInt64 key = (static_cast(std::min(index1, index2)) << 32) + static_cast(std::max(index1, index2)); + auto it = m_cache.find(key); + if (it != m_cache.end()) + return it->second; + + Vector3f middle = Vector3f::Lerp(m_vertices.positionPtr[index1], m_vertices.positionPtr[index2], 0.5f); + + unsigned int index = AddVertex(middle); + m_cache[key] = index; + + return index; } - } - unsigned int AddVertex(const NzVector3f& position) - { - m_vertices.normalPtr[m_vertexIndex] = NzVector3f::Normalize(m_matrix.Transform(position, 0.f)); - m_vertices.positionPtr[m_vertexIndex] = m_matrix.Transform(m_size * position.GetNormal()); + private: + std::unordered_map m_cache; + const Matrix4f& m_matrix; + VertexPointers m_vertices; + float m_size; + unsigned int m_vertexIndex; + }; - return m_vertexIndex++; - } - - unsigned int GetMiddleVertex(unsigned int index1, unsigned int index2) - { - nzUInt64 key = (static_cast(std::min(index1, index2)) << 32) + static_cast(std::max(index1, index2)); - auto it = m_cache.find(key); - if (it != m_cache.end()) - return it->second; - - NzVector3f middle = NzVector3f::Lerp(m_vertices.positionPtr[index1], m_vertices.positionPtr[index2], 0.5f); - - unsigned int index = AddVertex(middle); - m_cache[key] = index; - - return index; - } - - private: - std::unordered_map m_cache; - const NzMatrix4f& m_matrix; - NzVertexPointers m_vertices; - float m_size; - unsigned int m_vertexIndex; - }; - - // Source: https://code.google.com/p/vcacne/ - // Auteur: Michael Georgoulpoulos - // Selon ce papier: http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html - // Modifié pour les besoins du moteur - ///TODO: Déplacer dans un fichier à part ? - struct VertexCacheData - { - int position_in_cache = -1; - float current_score = 0.f; - int total_valence = 0; // toatl number of triangles using this vertex - int remaining_valence = 0; // number of triangles using it but not yet rendered - std::vector tri_indices; // indices to the indices that use this vertex - bool calculated; // was the score calculated during this iteration? - - - int FindTriangle(int tri) + // Source: https://code.google.com/p/vcacne/ + // Auteur: Michael Georgoulpoulos + // Selon ce papier: http://home.comcast.net/~tom_forsyth/papers/fast_vert_cache_opt.html + // Modifié pour les besoins du moteur + ///TODO: Déplacer dans un fichier à part ? + struct VertexCacheData { - for (unsigned int i = 0; i < tri_indices.size(); ++i) - if (tri_indices[i] == tri) return i; + int position_in_cache = -1; + float current_score = 0.f; + int total_valence = 0; // toatl number of triangles using this vertex + int remaining_valence = 0; // number of triangles using it but not yet rendered + std::vector tri_indices; // indices to the indices that use this vertex + bool calculated; // was the score calculated during this iteration? - return -1; - } - void MoveTriangleToEnd(int tri) - { - auto it = std::find(tri_indices.begin(), tri_indices.end(), tri); - NazaraAssert(it != tri_indices.end(), "Triangle not found"); - - tri_indices.erase(it); - tri_indices.push_back(tri); - } - }; - - struct TriangleCacheData - { - bool rendered = false; // has the triangle been added to the draw list yet? - float current_score = 0.f; // sum of the score of its vertices - int verts[3] = {-1, -1, -1}; // indices to the triangle's vertices - bool calculated = false; // was the score calculated during this iteration? - }; - - class VertexCache - { - public: - VertexCache() + int FindTriangle(int tri) { - Clear(); - } - - VertexCache(NzIndexIterator indices, unsigned int indexCount) - { - Clear(); - - for (unsigned int i = 0; i < indexCount; ++i) - AddVertex(*indices++); - } - - // the vertex will be placed on top - // if the vertex didn't exist previewsly in - // the cache, then miss count is incermented - void AddVertex(unsigned int v) - { - int w = FindVertex(v); - if (w >= 0) - // remove the vertex from the cache (to reinsert it later on the top) - RemoveVertex(w); - else - // the vertex was not found in the cache - increment misses - m_misses++; - - // shift all vertices down (to make room for the new top vertex) - for (int i=39; i>0; i--) - m_cache[i] = m_cache[i-1]; - - // add the new vertex on top - m_cache[0] = v; - } - - void Clear() - { - for (int i=0; i<40; i++) - m_cache[i] = -1; - - m_misses = 0; - } - - int GetMissCount() const - { - return m_misses; - } - - int GetVertex(int which) const - { - return m_cache[which]; - } - - private: - int FindVertex(int v) const - { - for (int i = 0; i < 32; ++i) - { - if (m_cache[i] == v) - return i; - } + for (unsigned int i = 0; i < tri_indices.size(); ++i) + if (tri_indices[i] == tri) return i; return -1; } - void RemoveVertex(int stack_index) + void MoveTriangleToEnd(int tri) { - for (int i=stack_index; i<38; i++) - m_cache[i] = m_cache[i+1]; + auto it = std::find(tri_indices.begin(), tri_indices.end(), tri); + NazaraAssert(it != tri_indices.end(), "Triangle not found"); + + tri_indices.erase(it); + tri_indices.push_back(tri); } + }; - int m_cache[40]; - int m_misses; // cache miss count - }; + struct TriangleCacheData + { + bool rendered = false; // has the triangle been added to the draw list yet? + float current_score = 0.f; // sum of the score of its vertices + int verts[3] = {-1, -1, -1}; // indices to the triangle's vertices + bool calculated = false; // was the score calculated during this iteration? + }; - class VertexCacheOptimizer - { - public: - enum Result - { - Success, - Fail_BadIndex, - Fail_NoVerts - }; - - VertexCacheOptimizer() - { - // initialize constants - m_cacheDecayPower = 1.5f; - m_lastTriScore = 0.75f; - m_valenceBoostScale = 2.0f; - m_valenceBoostPower = 0.5f; - - m_bestTri = 0; - } - - // stores new indices in place - Result Optimize(NzIndexIterator indices, unsigned int indexCount) - { - if (indexCount == 0) - return Fail_NoVerts; - - // find vertex count - int max_vert = *std::max_element(indices, indices + indexCount); - - Result res = Init(indices, indexCount, max_vert + 1); - if (res != Success) - return res; - - // iterate until Iterate returns false - while (Iterate()); - - // rewrite optimized index list - for (int index : m_drawList) + class VertexCache + { + public: + VertexCache() { - *indices++ = m_triangles[index].verts[0]; - *indices++ = m_triangles[index].verts[1]; - *indices++ = m_triangles[index].verts[2]; + Clear(); } - return Success; - } - - private: - float CalculateVertexScore(unsigned int vertex) const - { - const VertexCacheData* v = &m_vertices[vertex]; - if (v->remaining_valence <= 0) - // No tri needs this vertex! - return -1.0f; - - float ret = 0.0f; - if (v->position_in_cache < 0) + VertexCache(IndexIterator indices, unsigned int indexCount) { - // Vertex is not in FIFO cache - no score. + Clear(); + + for (unsigned int i = 0; i < indexCount; ++i) + AddVertex(*indices++); } - else + + // the vertex will be placed on top + // if the vertex didn't exist previewsly in + // the cache, then miss count is incermented + void AddVertex(unsigned int v) { - if (v->position_in_cache < 3) + int w = FindVertex(v); + if (w >= 0) + // remove the vertex from the cache (to reinsert it later on the top) + RemoveVertex(w); + else + // the vertex was not found in the cache - increment misses + m_misses++; + + // shift all vertices down (to make room for the new top vertex) + for (int i=39; i>0; i--) + m_cache[i] = m_cache[i-1]; + + // add the new vertex on top + m_cache[0] = v; + } + + void Clear() + { + for (int i=0; i<40; i++) + m_cache[i] = -1; + + m_misses = 0; + } + + int GetMissCount() const + { + return m_misses; + } + + int GetVertex(int which) const + { + return m_cache[which]; + } + + private: + int FindVertex(int v) const + { + for (int i = 0; i < 32; ++i) { - // This vertex was used in the last triangle, - // so it has a fixed score, whichever of the three - // it's in. Otherwise, you can get very different - // answers depending on whether you add - // the triangle 1,2,3 or 3,1,2 - which is silly. - ret = m_lastTriScore; + if (m_cache[i] == v) + return i; + } + + return -1; + } + + void RemoveVertex(int stack_index) + { + for (int i=stack_index; i<38; i++) + m_cache[i] = m_cache[i+1]; + } + + int m_cache[40]; + int m_misses; // cache miss count + }; + + class VertexCacheOptimizer + { + public: + enum Result + { + Success, + Fail_BadIndex, + Fail_NoVerts + }; + + VertexCacheOptimizer() + { + // initialize constants + m_cacheDecayPower = 1.5f; + m_lastTriScore = 0.75f; + m_valenceBoostScale = 2.0f; + m_valenceBoostPower = 0.5f; + + m_bestTri = 0; + } + + // stores new indices in place + Result Optimize(IndexIterator indices, unsigned int indexCount) + { + if (indexCount == 0) + return Fail_NoVerts; + + // find vertex count + int max_vert = *std::max_element(indices, indices + indexCount); + + Result res = Init(indices, indexCount, max_vert + 1); + if (res != Success) + return res; + + // iterate until Iterate returns false + while (Iterate()); + + // rewrite optimized index list + for (int index : m_drawList) + { + *indices++ = m_triangles[index].verts[0]; + *indices++ = m_triangles[index].verts[1]; + *indices++ = m_triangles[index].verts[2]; + } + + return Success; + } + + private: + float CalculateVertexScore(unsigned int vertex) const + { + const VertexCacheData* v = &m_vertices[vertex]; + if (v->remaining_valence <= 0) + // No tri needs this vertex! + return -1.0f; + + float ret = 0.0f; + if (v->position_in_cache < 0) + { + // Vertex is not in FIFO cache - no score. } else { - // Points for being high in the cache. - const float Scaler = 1.0f / (32 - 3); - ret = 1.0f - (v->position_in_cache - 3) * Scaler; - ret = std::pow(ret, m_cacheDecayPower); + if (v->position_in_cache < 3) + { + // This vertex was used in the last triangle, + // so it has a fixed score, whichever of the three + // it's in. Otherwise, you can get very different + // answers depending on whether you add + // the triangle 1,2,3 or 3,1,2 - which is silly. + ret = m_lastTriScore; + } + else + { + // Points for being high in the cache. + const float Scaler = 1.0f / (32 - 3); + ret = 1.0f - (v->position_in_cache - 3) * Scaler; + ret = std::pow(ret, m_cacheDecayPower); + } } + + // Bonus points for having a low number of tris still to + // use the vert, so we get rid of lone verts quickly. + float valence_boost = std::pow(static_cast(v->remaining_valence), -m_valenceBoostPower); + ret += m_valenceBoostScale * valence_boost; + + return ret; } - // Bonus points for having a low number of tris still to - // use the vert, so we get rid of lone verts quickly. - float valence_boost = std::pow(static_cast(v->remaining_valence), -m_valenceBoostPower); - ret += m_valenceBoostScale * valence_boost; - - return ret; - } - - // returns the index of the triangle with the highest score - // (or -1, if there aren't any active triangles) - int FullScoreRecalculation() - { - // calculate score for all vertices - for (unsigned int i = 0; i < m_vertices.size(); ++i) - m_vertices[i].current_score = CalculateVertexScore(i); - - // calculate scores for all active triangles - float max_score; - int max_score_tri = -1; - bool first_time = true; - - for (unsigned int i = 0; i < m_triangles.size(); ++i) + // returns the index of the triangle with the highest score + // (or -1, if there aren't any active triangles) + int FullScoreRecalculation() { - if (m_triangles[i].rendered) - continue; + // calculate score for all vertices + for (unsigned int i = 0; i < m_vertices.size(); ++i) + m_vertices[i].current_score = CalculateVertexScore(i); - // sum the score of all the triangle's vertices - float sc = m_vertices[m_triangles[i].verts[0]].current_score + - m_vertices[m_triangles[i].verts[1]].current_score + - m_vertices[m_triangles[i].verts[2]].current_score; + // calculate scores for all active triangles + float max_score; + int max_score_tri = -1; + bool first_time = true; - m_triangles[i].current_score = sc; - - if (first_time || sc > max_score) + for (unsigned int i = 0; i < m_triangles.size(); ++i) { - first_time = false; - max_score = sc; - max_score_tri = i; - } - } + if (m_triangles[i].rendered) + continue; - return max_score_tri; - } + // sum the score of all the triangle's vertices + float sc = m_vertices[m_triangles[i].verts[0]].current_score + + m_vertices[m_triangles[i].verts[1]].current_score + + m_vertices[m_triangles[i].verts[2]].current_score; - Result InitialPass() - { - for (unsigned int i = 0; i < m_indices.size(); ++i) - { - int index = m_indices[i]; - if (index < 0 || index >= static_cast(m_vertices.size())) - return Fail_BadIndex; + m_triangles[i].current_score = sc; - m_vertices[index].total_valence++; - m_vertices[index].remaining_valence++; - - m_vertices[index].tri_indices.push_back(i/3); - } - - m_bestTri = FullScoreRecalculation(); - - return Success; - } - - Result Init(NzIndexIterator indices, unsigned int indexCount, int vertex_count) - { - // clear the draw list - m_drawList.clear(); - - // allocate and initialize vertices and triangles - m_vertices.clear(); // Pour reconstruire tous les éléments - m_vertices.resize(vertex_count); - - m_triangles.clear(); - for (unsigned int i = 0; i < indexCount; i += 3) - { - TriangleCacheData dat; - for (unsigned int j = 0; j < 3; ++j) - dat.verts[j] = indices[i + j]; - - m_triangles.push_back(dat); - } - - // copy the indices - m_indices.resize(indexCount); - for (unsigned int i = 0; i < indexCount; ++i) - m_indices[i] = indices[i]; - - m_vertexCache.Clear(); - m_bestTri = -1; - - return InitialPass(); - } - - void AddTriangleToDrawList(int tri) - { - // reset all cache positions - for (unsigned int i = 0; i < 32; ++i) - { - int ind = m_vertexCache.GetVertex(i); - if (ind < 0) - continue; - - m_vertices[ind].position_in_cache = -1; - } - - TriangleCacheData* t = &m_triangles[tri]; - if (t->rendered) - return; // triangle is already in the draw list - - for (unsigned int i = 0; i < 3; ++i) - { - // add all triangle vertices to the cache - m_vertexCache.AddVertex(t->verts[i]); - - VertexCacheData *v = &m_vertices[t->verts[i]]; - - // decrease remaining velence - v->remaining_valence--; - - // move the added triangle to the end of the vertex's - // triangle index list, so that the first 'remaining_valence' - // triangles in the list are the active ones - v->MoveTriangleToEnd(tri); - } - - m_drawList.push_back(tri); - - t->rendered = true; - - // update all vertex cache positions - for (unsigned int i = 0; i < 32; ++i) - { - int ind = m_vertexCache.GetVertex(i); - if (ind < 0) - continue; - - m_vertices[ind].position_in_cache = i; - } - } - - // Optimization: to avoid duplicate calculations durind the same iteration, - // both vertices and triangles have a 'calculated' flag. This flag - // must be cleared at the beginning of the iteration to all *active* triangles - // that have one or more of their vertices currently cached, and all their - // other vertices. - // If there aren't any active triangles in the cache, the function returns - // false and full recalculation is performed. - bool CleanCalculationFlags() - { - bool ret = false; - for (unsigned int i = 0; i < 32; ++i) - { - int vert = m_vertexCache.GetVertex(i); - if (vert < 0) - continue; - - VertexCacheData *v = &m_vertices[vert]; - - for (int j = 0; j < v->remaining_valence; j++) - { - TriangleCacheData *t = &m_triangles[v->tri_indices[j]]; - - // we actually found a triangle to process - ret = true; - - // clear triangle flag - t->calculated = false; - - // clear vertex flags - for (unsigned int k = 0; k < 3; ++k) - m_vertices[t->verts[k]].calculated = false; - } - } - - return ret; - } - - void TriangleScoreRecalculation(int tri) - { - TriangleCacheData* t = &m_triangles[tri]; - - // calculate vertex scores - float sum = 0.f; - for (unsigned int i = 0; i < 3; ++i) - { - VertexCacheData* v = &m_vertices[t->verts[i]]; - float sc = v->current_score; - if (!v->calculated) - sc = CalculateVertexScore(t->verts[i]); - - v->current_score = sc; - v->calculated = true; - sum += sc; - } - - t->current_score = sum; - t->calculated = true; - } - - int PartialScoreRecalculation() - { - // iterate through all the vertices of the cache - bool first_time = true; - float max_score; - int max_score_tri = -1; - - for (unsigned int i = 0; i < 32; ++i) - { - int vert = m_vertexCache.GetVertex(i); - if (vert < 0) - continue; - - const VertexCacheData* v = &m_vertices[vert]; - - // iterate through all *active* triangles of this vertex - for (int j = 0; j < v->remaining_valence; j++) - { - int tri = v->tri_indices[j]; - TriangleCacheData* t = &m_triangles[tri]; - if (!t->calculated) - // calculate triangle score - TriangleScoreRecalculation(tri); - - float sc = t->current_score; - - // we actually found a triangle to process if (first_time || sc > max_score) { first_time = false; max_score = sc; - max_score_tri = tri; + max_score_tri = i; } } + + return max_score_tri; + } + + Result InitialPass() + { + for (unsigned int i = 0; i < m_indices.size(); ++i) + { + int index = m_indices[i]; + if (index < 0 || index >= static_cast(m_vertices.size())) + return Fail_BadIndex; + + m_vertices[index].total_valence++; + m_vertices[index].remaining_valence++; + + m_vertices[index].tri_indices.push_back(i/3); + } + + m_bestTri = FullScoreRecalculation(); + + return Success; + } + + Result Init(IndexIterator indices, unsigned int indexCount, int vertex_count) + { + // clear the draw list + m_drawList.clear(); + + // allocate and initialize vertices and triangles + m_vertices.clear(); // Pour reconstruire tous les éléments + m_vertices.resize(vertex_count); + + m_triangles.clear(); + for (unsigned int i = 0; i < indexCount; i += 3) + { + TriangleCacheData dat; + for (unsigned int j = 0; j < 3; ++j) + dat.verts[j] = indices[i + j]; + + m_triangles.push_back(dat); + } + + // copy the indices + m_indices.resize(indexCount); + for (unsigned int i = 0; i < indexCount; ++i) + m_indices[i] = indices[i]; + + m_vertexCache.Clear(); + m_bestTri = -1; + + return InitialPass(); + } + + void AddTriangleToDrawList(int tri) + { + // reset all cache positions + for (unsigned int i = 0; i < 32; ++i) + { + int ind = m_vertexCache.GetVertex(i); + if (ind < 0) + continue; + + m_vertices[ind].position_in_cache = -1; + } + + TriangleCacheData* t = &m_triangles[tri]; + if (t->rendered) + return; // triangle is already in the draw list + + for (unsigned int i = 0; i < 3; ++i) + { + // add all triangle vertices to the cache + m_vertexCache.AddVertex(t->verts[i]); + + VertexCacheData *v = &m_vertices[t->verts[i]]; + + // decrease remaining velence + v->remaining_valence--; + + // move the added triangle to the end of the vertex's + // triangle index list, so that the first 'remaining_valence' + // triangles in the list are the active ones + v->MoveTriangleToEnd(tri); + } + + m_drawList.push_back(tri); + + t->rendered = true; + + // update all vertex cache positions + for (unsigned int i = 0; i < 32; ++i) + { + int ind = m_vertexCache.GetVertex(i); + if (ind < 0) + continue; + + m_vertices[ind].position_in_cache = i; + } } - return max_score_tri; - } + // Optimization: to avoid duplicate calculations durind the same iteration, + // both vertices and triangles have a 'calculated' flag. This flag + // must be cleared at the beginning of the iteration to all *active* triangles + // that have one or more of their vertices currently cached, and all their + // other vertices. + // If there aren't any active triangles in the cache, the function returns + // false and full recalculation is performed. + bool CleanCalculationFlags() + { + bool ret = false; + for (unsigned int i = 0; i < 32; ++i) + { + int vert = m_vertexCache.GetVertex(i); + if (vert < 0) + continue; - // returns true while there are more steps to take - // false when optimization is complete - bool Iterate() - { - if (m_drawList.size() == m_triangles.size()) - return false; + VertexCacheData *v = &m_vertices[vert]; - // add the selected triangle to the draw list - AddTriangleToDrawList(m_bestTri); + for (int j = 0; j < v->remaining_valence; j++) + { + TriangleCacheData *t = &m_triangles[v->tri_indices[j]]; - // recalculate vertex and triangle scores and - // select the best triangle for the next iteration - m_bestTri = (CleanCalculationFlags()) ? PartialScoreRecalculation() : FullScoreRecalculation(); + // we actually found a triangle to process + ret = true; - return true; - } + // clear triangle flag + t->calculated = false; - std::vector m_vertices; - std::vector m_triangles; - std::vector m_indices; - int m_bestTri; // the next triangle to add to the render list - VertexCache m_vertexCache; - std::vector m_drawList; + // clear vertex flags + for (unsigned int k = 0; k < 3; ++k) + m_vertices[t->verts[k]].calculated = false; + } + } - // CalculateVertexScore constants - float m_cacheDecayPower; - float m_lastTriScore; - float m_valenceBoostScale; - float m_valenceBoostPower; - }; -} + return ret; + } -/**********************************NzCompute**********************************/ + void TriangleScoreRecalculation(int tri) + { + TriangleCacheData* t = &m_triangles[tri]; -NzBoxf NzComputeAABB(NzSparsePtr positionPtr, unsigned int vertexCount) -{ - NzBoxf aabb; - if (vertexCount > 0) - { - aabb.Set(positionPtr->x, positionPtr->y, positionPtr->z, 0.f, 0.f, 0.f); - --positionPtr; + // calculate vertex scores + float sum = 0.f; + for (unsigned int i = 0; i < 3; ++i) + { + VertexCacheData* v = &m_vertices[t->verts[i]]; + float sc = v->current_score; + if (!v->calculated) + sc = CalculateVertexScore(t->verts[i]); - for (unsigned int i = 1; i < vertexCount; ++i) - aabb.ExtendTo(*positionPtr++); + v->current_score = sc; + v->calculated = true; + sum += sc; + } + + t->current_score = sum; + t->calculated = true; + } + + int PartialScoreRecalculation() + { + // iterate through all the vertices of the cache + bool first_time = true; + float max_score; + int max_score_tri = -1; + + for (unsigned int i = 0; i < 32; ++i) + { + int vert = m_vertexCache.GetVertex(i); + if (vert < 0) + continue; + + const VertexCacheData* v = &m_vertices[vert]; + + // iterate through all *active* triangles of this vertex + for (int j = 0; j < v->remaining_valence; j++) + { + int tri = v->tri_indices[j]; + TriangleCacheData* t = &m_triangles[tri]; + if (!t->calculated) + // calculate triangle score + TriangleScoreRecalculation(tri); + + float sc = t->current_score; + + // we actually found a triangle to process + if (first_time || sc > max_score) + { + first_time = false; + max_score = sc; + max_score_tri = tri; + } + } + } + + return max_score_tri; + } + + // returns true while there are more steps to take + // false when optimization is complete + bool Iterate() + { + if (m_drawList.size() == m_triangles.size()) + return false; + + // add the selected triangle to the draw list + AddTriangleToDrawList(m_bestTri); + + // recalculate vertex and triangle scores and + // select the best triangle for the next iteration + m_bestTri = (CleanCalculationFlags()) ? PartialScoreRecalculation() : FullScoreRecalculation(); + + return true; + } + + std::vector m_vertices; + std::vector m_triangles; + std::vector m_indices; + int m_bestTri; // the next triangle to add to the render list + VertexCache m_vertexCache; + std::vector m_drawList; + + // CalculateVertexScore constants + float m_cacheDecayPower; + float m_lastTriScore; + float m_valenceBoostScale; + float m_valenceBoostPower; + }; } - else - aabb.MakeZero(); - return aabb; -} + /**********************************Compute**********************************/ -void NzComputeBoxIndexVertexCount(const NzVector3ui& subdivision, unsigned int* indexCount, unsigned int* vertexCount) -{ - unsigned int xIndexCount, yIndexCount, zIndexCount; - unsigned int xVertexCount, yVertexCount, zVertexCount; - - NzComputePlaneIndexVertexCount(NzVector2ui(subdivision.y, subdivision.z), &xIndexCount, &xVertexCount); - NzComputePlaneIndexVertexCount(NzVector2ui(subdivision.x, subdivision.z), &yIndexCount, &yVertexCount); - NzComputePlaneIndexVertexCount(NzVector2ui(subdivision.x, subdivision.y), &zIndexCount, &zVertexCount); - - if (indexCount) - *indexCount = xIndexCount*2 + yIndexCount*2 + zIndexCount*2; - - if (vertexCount) - *vertexCount = xVertexCount*2 + yVertexCount*2 + zVertexCount*2; -} - -unsigned int NzComputeCacheMissCount(NzIndexIterator indices, unsigned int indexCount) -{ - VertexCache cache(indices, indexCount); - return cache.GetMissCount(); -} - -void NzComputeConeIndexVertexCount(unsigned int subdivision, unsigned int* indexCount, unsigned int* vertexCount) -{ - if (indexCount) - *indexCount = (subdivision-1)*6; - - if (vertexCount) - *vertexCount = subdivision + 2; -} - -void NzComputeCubicSphereIndexVertexCount(unsigned int subdivision, unsigned int* indexCount, unsigned int* vertexCount) -{ - // Comme tous nos plans sont identiques, on peut optimiser un peu - NzComputePlaneIndexVertexCount(NzVector2ui(subdivision), indexCount, vertexCount); - - if (indexCount) - *indexCount *= 6; - - if (vertexCount) - *vertexCount *= 6; -} - -void NzComputeIcoSphereIndexVertexCount(unsigned int recursionLevel, unsigned int* indexCount, unsigned int* vertexCount) -{ - if (indexCount) - *indexCount = 3 * 20 * NzIntegralPow(4, recursionLevel); - - if (vertexCount) - *vertexCount = NzIntegralPow(4, recursionLevel)*10 + 2; -} - -void NzComputePlaneIndexVertexCount(const NzVector2ui& subdivision, unsigned int* indexCount, unsigned int* vertexCount) -{ - // Le nombre de faces appartenant à un axe est équivalent à 2 exposant la subdivision (1,2,4,8,16,32,...) - unsigned int horizontalFaceCount = (1 << subdivision.x); - unsigned int verticalFaceCount = (1 << subdivision.y); - - // Et le nombre de sommets est ce nombre ajouté de 1 (2,3,5,9,17,33,...) - unsigned int horizontalVertexCount = horizontalFaceCount + 1; - unsigned int verticalVertexCount = verticalFaceCount + 1; - - if (indexCount) - *indexCount = horizontalFaceCount*verticalFaceCount*6; // Six indices sont nécessaires pour décrire une face (deux triangles) - - if (vertexCount) - *vertexCount = horizontalVertexCount*verticalVertexCount; -} - -void NzComputeUvSphereIndexVertexCount(unsigned int sliceCount, unsigned int stackCount, unsigned int* indexCount, unsigned int* vertexCount) -{ - if (indexCount) - *indexCount = (sliceCount-1) * (stackCount-1) * 6; - - if (vertexCount) - *vertexCount = sliceCount * stackCount; -} - -/**********************************NzGenerate*********************************/ - -void NzGenerateBox(const NzVector3f& lengths, const NzVector3ui& subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzVertexPointers vertexPointers, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) -{ - unsigned int xIndexCount, yIndexCount, zIndexCount; - unsigned int xVertexCount, yVertexCount, zVertexCount; - - NzComputePlaneIndexVertexCount(NzVector2ui(subdivision.y, subdivision.z), &xIndexCount, &xVertexCount); - NzComputePlaneIndexVertexCount(NzVector2ui(subdivision.x, subdivision.z), &yIndexCount, &yVertexCount); - NzComputePlaneIndexVertexCount(NzVector2ui(subdivision.x, subdivision.y), &zIndexCount, &zVertexCount); - - NzMatrix4f transform; - NzVector3f halfLengths = lengths/2.f; - - // Face +X - transform.MakeTransform(NzVector3f::UnitX() * halfLengths.x, NzEulerAnglesf(-90.f, 0.f, -90.f)); - NzGeneratePlane(NzVector2ui(subdivision.z, subdivision.y), NzVector2f(lengths.z, lengths.y), NzMatrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset); - indexOffset += xVertexCount; - indices += xIndexCount; - - vertexPointers.positionPtr += xVertexCount; - - if (vertexPointers.normalPtr) - vertexPointers.normalPtr += xVertexCount; - - if (vertexPointers.tangentPtr) - vertexPointers.tangentPtr += xVertexCount; - - if (vertexPointers.uvPtr) - vertexPointers.uvPtr += xVertexCount; - - // Face +Y - transform.MakeTransform(NzVector3f::UnitY() * halfLengths.y, NzEulerAnglesf(0.f, 0.f, 0.f)); - NzGeneratePlane(NzVector2ui(subdivision.x, subdivision.z), NzVector2f(lengths.x, lengths.z), NzMatrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset); - indexOffset += yVertexCount; - indices += yIndexCount; - - vertexPointers.positionPtr += yVertexCount; - - if (vertexPointers.normalPtr) - vertexPointers.normalPtr += yVertexCount; - - if (vertexPointers.tangentPtr) - vertexPointers.tangentPtr += yVertexCount; - - if (vertexPointers.uvPtr) - vertexPointers.uvPtr += yVertexCount; - - // Face +Z - transform.MakeTransform(NzVector3f::UnitZ() * halfLengths.z, NzEulerAnglesf(-90.f, 90.f, 90.f)); - NzGeneratePlane(NzVector2ui(subdivision.x, subdivision.y), NzVector2f(lengths.x, lengths.y), NzMatrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset); - indexOffset += zVertexCount; - indices += zIndexCount; - - vertexPointers.positionPtr += zVertexCount; - - if (vertexPointers.normalPtr) - vertexPointers.normalPtr += zVertexCount; - - if (vertexPointers.tangentPtr) - vertexPointers.tangentPtr += zVertexCount; - - if (vertexPointers.uvPtr) - vertexPointers.uvPtr += zVertexCount; - - // Face -X - transform.MakeTransform(-NzVector3f::UnitX() * halfLengths.x, NzEulerAnglesf(-90.f, 0.f, 90.f)); - NzGeneratePlane(NzVector2ui(subdivision.z, subdivision.y), NzVector2f(lengths.z, lengths.y), NzMatrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset); - indexOffset += xVertexCount; - indices += xIndexCount; - - vertexPointers.positionPtr += xVertexCount; - - if (vertexPointers.normalPtr) - vertexPointers.normalPtr += xVertexCount; - - if (vertexPointers.tangentPtr) - vertexPointers.tangentPtr += xVertexCount; - - if (vertexPointers.uvPtr) - vertexPointers.uvPtr += xVertexCount; - - // Face -Y - transform.MakeTransform(-NzVector3f::UnitY() * halfLengths.y, NzEulerAnglesf(0.f, 0.f, 180.f)); - NzGeneratePlane(NzVector2ui(subdivision.x, subdivision.z), NzVector2f(lengths.x, lengths.z), NzMatrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset); - indexOffset += yVertexCount; - indices += yIndexCount; - - vertexPointers.positionPtr += yVertexCount; - - if (vertexPointers.normalPtr) - vertexPointers.normalPtr += yVertexCount; - - if (vertexPointers.tangentPtr) - vertexPointers.tangentPtr += yVertexCount; - - if (vertexPointers.uvPtr) - vertexPointers.uvPtr += yVertexCount; - - // Face -Z - transform.MakeTransform(-NzVector3f::UnitZ() * halfLengths.z, NzEulerAnglesf(-90.f, -90.f, 90.f)); - NzGeneratePlane(NzVector2ui(subdivision.x, subdivision.y), NzVector2f(lengths.x, lengths.y), NzMatrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset); - indexOffset += zVertexCount; - indices += zIndexCount; - - vertexPointers.positionPtr += zVertexCount; - - if (vertexPointers.normalPtr) - vertexPointers.normalPtr += zVertexCount; - - if (vertexPointers.tangentPtr) - vertexPointers.tangentPtr += zVertexCount; - - if (vertexPointers.uvPtr) - vertexPointers.uvPtr += zVertexCount; - - if (aabb) + Boxf ComputeAABB(SparsePtr positionPtr, unsigned int vertexCount) { - aabb->Set(-halfLengths, halfLengths); - aabb->Transform(matrix, false); - } -} - -void NzGenerateCone(float length, float radius, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzVertexPointers vertexPointers, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) -{ - constexpr float round = 2.f*static_cast(M_PI); - float delta = round/subdivision; - - *vertexPointers.positionPtr++ = matrix.GetTranslation(); // matrix.Transform(NzVector3f(0.f)); - - if (vertexPointers.normalPtr) - *vertexPointers.normalPtr++ = matrix.Transform(NzVector3f::Up(), 0.f); - - for (unsigned int i = 0; i < subdivision; ++i) - { - float angle = delta*i; - *vertexPointers.positionPtr++ = matrix.Transform(NzVector3f(radius*std::sin(angle), -length, radius*std::cos(angle))); - - *indices++ = indexOffset + 0; - *indices++ = indexOffset + i+1; - *indices++ = indexOffset + ((i != subdivision-1) ? i+2 : 1); - - if (i != 0 && i != subdivision-1) + Boxf aabb; + if (vertexCount > 0) { - *indices++ = indexOffset + ((i != subdivision-1) ? i+2 : 1); - *indices++ = indexOffset + i+1; - *indices++ = indexOffset + 1; + aabb.Set(positionPtr->x, positionPtr->y, positionPtr->z, 0.f, 0.f, 0.f); + --positionPtr; + + for (unsigned int i = 1; i < vertexCount; ++i) + aabb.ExtendTo(*positionPtr++); } + else + aabb.MakeZero(); + + return aabb; } - if (aabb) + void ComputeBoxIndexVertexCount(const Vector3ui& subdivision, unsigned int* indexCount, unsigned int* vertexCount) { - aabb->MakeZero(); + unsigned int xIndexCount, yIndexCount, zIndexCount; + unsigned int xVertexCount, yVertexCount, zVertexCount; - // On calcule le reste des points - NzVector3f base(NzVector3f::Down()*length); + ComputePlaneIndexVertexCount(Vector2ui(subdivision.y, subdivision.z), &xIndexCount, &xVertexCount); + ComputePlaneIndexVertexCount(Vector2ui(subdivision.x, subdivision.z), &yIndexCount, &yVertexCount); + ComputePlaneIndexVertexCount(Vector2ui(subdivision.x, subdivision.y), &zIndexCount, &zVertexCount); - NzVector3f lExtend = NzVector3f::Left()*radius; - NzVector3f fExtend = NzVector3f::Forward()*radius; + if (indexCount) + *indexCount = xIndexCount*2 + yIndexCount*2 + zIndexCount*2; - // Et on ajoute ensuite les quatres extrémités de la pyramide - aabb->ExtendTo(base + lExtend + fExtend); - aabb->ExtendTo(base + lExtend - fExtend); - aabb->ExtendTo(base - lExtend + fExtend); - aabb->ExtendTo(base - lExtend - fExtend); - aabb->Transform(matrix, false); - } -} - -void NzGenerateCubicSphere(float size, unsigned int subdivision, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzVertexPointers vertexPointers, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) -{ - ///DOC: Cette fonction va accéder aux pointeurs en écriture ET en lecture - unsigned int vertexCount; - NzComputeBoxIndexVertexCount(NzVector3ui(subdivision), nullptr, &vertexCount); - - // On envoie une matrice identité de sorte à ce que la boîte ne subisse aucune transformation (rendant plus facile l'étape suivante) - NzGenerateBox(NzVector3f(size, size, size), NzVector3ui(subdivision), NzMatrix4f::Identity(), textureCoords, vertexPointers, indices, nullptr, indexOffset); - - if (aabb) - { - NzVector3f totalSize = size * matrix.GetScale(); - aabb->Set(-totalSize, totalSize); + if (vertexCount) + *vertexCount = xVertexCount*2 + yVertexCount*2 + zVertexCount*2; } - for (unsigned int i = 0; i < vertexCount; ++i) + unsigned int ComputeCacheMissCount(IndexIterator indices, unsigned int indexCount) { - NzVector3f normal = vertexPointers.positionPtr->GetNormal(); + VertexCache cache(indices, indexCount); + return cache.GetMissCount(); + } - *vertexPointers.positionPtr++ = matrix.Transform(size * normal); + void ComputeConeIndexVertexCount(unsigned int subdivision, unsigned int* indexCount, unsigned int* vertexCount) + { + if (indexCount) + *indexCount = (subdivision-1)*6; + + if (vertexCount) + *vertexCount = subdivision + 2; + } + + void ComputeCubicSphereIndexVertexCount(unsigned int subdivision, unsigned int* indexCount, unsigned int* vertexCount) + { + // Comme tous nos plans sont identiques, on peut optimiser un peu + ComputePlaneIndexVertexCount(Vector2ui(subdivision), indexCount, vertexCount); + + if (indexCount) + *indexCount *= 6; + + if (vertexCount) + *vertexCount *= 6; + } + + void ComputeIcoSphereIndexVertexCount(unsigned int recursionLevel, unsigned int* indexCount, unsigned int* vertexCount) + { + if (indexCount) + *indexCount = 3 * 20 * IntegralPow(4, recursionLevel); + + if (vertexCount) + *vertexCount = IntegralPow(4, recursionLevel)*10 + 2; + } + + void ComputePlaneIndexVertexCount(const Vector2ui& subdivision, unsigned int* indexCount, unsigned int* vertexCount) + { + // Le nombre de faces appartenant à un axe est équivalent à 2 exposant la subdivision (1,2,4,8,16,32,...) + unsigned int horizontalFaceCount = (1 << subdivision.x); + unsigned int verticalFaceCount = (1 << subdivision.y); + + // Et le nombre de sommets est ce nombre ajouté de 1 (2,3,5,9,17,33,...) + unsigned int horizontalVertexCount = horizontalFaceCount + 1; + unsigned int verticalVertexCount = verticalFaceCount + 1; + + if (indexCount) + *indexCount = horizontalFaceCount*verticalFaceCount*6; // Six indices sont nécessaires pour décrire une face (deux triangles) + + if (vertexCount) + *vertexCount = horizontalVertexCount*verticalVertexCount; + } + + void ComputeUvSphereIndexVertexCount(unsigned int sliceCount, unsigned int stackCount, unsigned int* indexCount, unsigned int* vertexCount) + { + if (indexCount) + *indexCount = (sliceCount-1) * (stackCount-1) * 6; + + if (vertexCount) + *vertexCount = sliceCount * stackCount; + } + + /**********************************Generate*********************************/ + + void GenerateBox(const Vector3f& lengths, const Vector3ui& subdivision, const Matrix4f& matrix, const Rectf& textureCoords, VertexPointers vertexPointers, IndexIterator indices, Boxf* aabb, unsigned int indexOffset) + { + unsigned int xIndexCount, yIndexCount, zIndexCount; + unsigned int xVertexCount, yVertexCount, zVertexCount; + + ComputePlaneIndexVertexCount(Vector2ui(subdivision.y, subdivision.z), &xIndexCount, &xVertexCount); + ComputePlaneIndexVertexCount(Vector2ui(subdivision.x, subdivision.z), &yIndexCount, &yVertexCount); + ComputePlaneIndexVertexCount(Vector2ui(subdivision.x, subdivision.y), &zIndexCount, &zVertexCount); + + Matrix4f transform; + Vector3f halfLengths = lengths/2.f; + + // Face +X + transform.MakeTransform(Vector3f::UnitX() * halfLengths.x, EulerAnglesf(-90.f, 0.f, -90.f)); + GeneratePlane(Vector2ui(subdivision.z, subdivision.y), Vector2f(lengths.z, lengths.y), Matrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset); + indexOffset += xVertexCount; + indices += xIndexCount; + + vertexPointers.positionPtr += xVertexCount; if (vertexPointers.normalPtr) - *vertexPointers.normalPtr++ = normal; + vertexPointers.normalPtr += xVertexCount; - ///FIXME: *vertexPointers.tangentPtr++ = ??? - } -} + if (vertexPointers.tangentPtr) + vertexPointers.tangentPtr += xVertexCount; -void NzGenerateIcoSphere(float size, unsigned int recursionLevel, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzVertexPointers vertexPointers, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) -{ - IcoSphereBuilder builder(matrix); - builder.Generate(size, recursionLevel, textureCoords, vertexPointers, indices, aabb, indexOffset); -} + if (vertexPointers.uvPtr) + vertexPointers.uvPtr += xVertexCount; -void NzGeneratePlane(const NzVector2ui& subdivision, const NzVector2f& size, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzVertexPointers vertexPointers, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) -{ - // Pour plus de facilité, on va construire notre plan en considérant que la normale est de 0,1,0 - // Et appliquer ensuite une matrice "finissant le travail" + // Face +Y + transform.MakeTransform(Vector3f::UnitY() * halfLengths.y, EulerAnglesf(0.f, 0.f, 0.f)); + GeneratePlane(Vector2ui(subdivision.x, subdivision.z), Vector2f(lengths.x, lengths.z), Matrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset); + indexOffset += yVertexCount; + indices += yIndexCount; - // Le nombre de faces appartenant à un axe est équivalent à 2 exposant la subdivision (1,2,4,8,16,32,...) - unsigned int horizontalFaceCount = (1 << subdivision.x); - unsigned int verticalFaceCount = (1 << subdivision.y); + vertexPointers.positionPtr += yVertexCount; - // Et le nombre de sommets est ce nombre ajouté de 1 (2,3,5,9,17,33,...) - unsigned int horizontalVertexCount = horizontalFaceCount + 1; - unsigned int verticalVertexCount = verticalFaceCount + 1; + if (vertexPointers.normalPtr) + vertexPointers.normalPtr += yVertexCount; - NzVector3f normal(NzVector3f::UnitY()); - normal = matrix.Transform(normal, 0.f); - normal.Normalize(); + if (vertexPointers.tangentPtr) + vertexPointers.tangentPtr += yVertexCount; - NzVector3f tangent(1.f, 1.f, 0.f); - tangent = matrix.Transform(tangent, 0.f); - tangent.Normalize(); + if (vertexPointers.uvPtr) + vertexPointers.uvPtr += yVertexCount; - float halfSizeX = size.x / 2.f; - float halfSizeY = size.y / 2.f; + // Face +Z + transform.MakeTransform(Vector3f::UnitZ() * halfLengths.z, EulerAnglesf(-90.f, 90.f, 90.f)); + GeneratePlane(Vector2ui(subdivision.x, subdivision.y), Vector2f(lengths.x, lengths.y), Matrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset); + indexOffset += zVertexCount; + indices += zIndexCount; - float invHorizontalVertexCount = 1.f/(horizontalVertexCount-1); - float invVerticalVertexCount = 1.f/(verticalVertexCount-1); - for (unsigned int x = 0; x < horizontalVertexCount; ++x) - { - for (unsigned int y = 0; y < verticalVertexCount; ++y) + vertexPointers.positionPtr += zVertexCount; + + if (vertexPointers.normalPtr) + vertexPointers.normalPtr += zVertexCount; + + if (vertexPointers.tangentPtr) + vertexPointers.tangentPtr += zVertexCount; + + if (vertexPointers.uvPtr) + vertexPointers.uvPtr += zVertexCount; + + // Face -X + transform.MakeTransform(-Vector3f::UnitX() * halfLengths.x, EulerAnglesf(-90.f, 0.f, 90.f)); + GeneratePlane(Vector2ui(subdivision.z, subdivision.y), Vector2f(lengths.z, lengths.y), Matrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset); + indexOffset += xVertexCount; + indices += xIndexCount; + + vertexPointers.positionPtr += xVertexCount; + + if (vertexPointers.normalPtr) + vertexPointers.normalPtr += xVertexCount; + + if (vertexPointers.tangentPtr) + vertexPointers.tangentPtr += xVertexCount; + + if (vertexPointers.uvPtr) + vertexPointers.uvPtr += xVertexCount; + + // Face -Y + transform.MakeTransform(-Vector3f::UnitY() * halfLengths.y, EulerAnglesf(0.f, 0.f, 180.f)); + GeneratePlane(Vector2ui(subdivision.x, subdivision.z), Vector2f(lengths.x, lengths.z), Matrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset); + indexOffset += yVertexCount; + indices += yIndexCount; + + vertexPointers.positionPtr += yVertexCount; + + if (vertexPointers.normalPtr) + vertexPointers.normalPtr += yVertexCount; + + if (vertexPointers.tangentPtr) + vertexPointers.tangentPtr += yVertexCount; + + if (vertexPointers.uvPtr) + vertexPointers.uvPtr += yVertexCount; + + // Face -Z + transform.MakeTransform(-Vector3f::UnitZ() * halfLengths.z, EulerAnglesf(-90.f, -90.f, 90.f)); + GeneratePlane(Vector2ui(subdivision.x, subdivision.y), Vector2f(lengths.x, lengths.y), Matrix4f::ConcatenateAffine(matrix, transform), textureCoords, vertexPointers, indices, nullptr, indexOffset); + indexOffset += zVertexCount; + indices += zIndexCount; + + vertexPointers.positionPtr += zVertexCount; + + if (vertexPointers.normalPtr) + vertexPointers.normalPtr += zVertexCount; + + if (vertexPointers.tangentPtr) + vertexPointers.tangentPtr += zVertexCount; + + if (vertexPointers.uvPtr) + vertexPointers.uvPtr += zVertexCount; + + if (aabb) { - NzVector3f localPos((2.f*x*invHorizontalVertexCount - 1.f) * halfSizeX, 0.f, (2.f*y*invVerticalVertexCount - 1.f) * halfSizeY); - *vertexPointers.positionPtr++ = matrix * localPos; - - if (vertexPointers.normalPtr) - *vertexPointers.normalPtr++ = normal; - - if (vertexPointers.tangentPtr) - *vertexPointers.tangentPtr++ = tangent; - - if (vertexPointers.uvPtr) - *vertexPointers.uvPtr++ = NzVector2f(textureCoords.x + x*invHorizontalVertexCount*textureCoords.width, textureCoords.y + y*invVerticalVertexCount*textureCoords.height); - - if (x != horizontalVertexCount-1 && y != verticalVertexCount-1) - { - *indices++ = (x+0)*verticalVertexCount + y + 0 + indexOffset; - *indices++ = (x+0)*verticalVertexCount + y + 1 + indexOffset; - *indices++ = (x+1)*verticalVertexCount + y + 0 + indexOffset; - - *indices++ = (x+1)*verticalVertexCount + y + 0 + indexOffset; - *indices++ = (x+0)*verticalVertexCount + y + 1 + indexOffset; - *indices++ = (x+1)*verticalVertexCount + y + 1 + indexOffset; - } + aabb->Set(-halfLengths, halfLengths); + aabb->Transform(matrix, false); } } - if (aabb) - aabb->Set(matrix.Transform(NzVector3f(-halfSizeX, 0.f, -halfSizeY), 0.f), matrix.Transform(NzVector3f(halfSizeX, 0.f, halfSizeY), 0.f)); -} - -void NzGenerateUvSphere(float size, unsigned int sliceCount, unsigned int stackCount, const NzMatrix4f& matrix, const NzRectf& textureCoords, NzVertexPointers vertexPointers, NzIndexIterator indices, NzBoxf* aabb, unsigned int indexOffset) -{ - // http://stackoverflow.com/questions/14080932/implementing-opengl-sphere-example-code - float invSliceCount = 1.f / (sliceCount-1); - float invStackCount = 1.f / (stackCount-1); - - const float pi = static_cast(M_PI); // Pour éviter toute promotion en double - const float pi2 = pi * 2.f; - const float pi_2 = pi / 2.f; - - for (unsigned int stack = 0; stack < stackCount; ++stack) + void GenerateCone(float length, float radius, unsigned int subdivision, const Matrix4f& matrix, const Rectf& textureCoords, VertexPointers vertexPointers, IndexIterator indices, Boxf* aabb, unsigned int indexOffset) { - float stackVal = stack * invStackCount; - float stackValPi = stackVal * pi; - float sinStackValPi = std::sin(stackValPi); + constexpr float round = 2.f*static_cast(M_PI); + float delta = round/subdivision; - for (unsigned int slice = 0; slice < sliceCount; ++slice) + *vertexPointers.positionPtr++ = matrix.GetTranslation(); // matrix.Transform(Vector3f(0.f)); + + if (vertexPointers.normalPtr) + *vertexPointers.normalPtr++ = matrix.Transform(Vector3f::Up(), 0.f); + + for (unsigned int i = 0; i < subdivision; ++i) { - float sliceVal = slice * invSliceCount; - float sliceValPi2 = sliceVal * pi2; + float angle = delta*i; + *vertexPointers.positionPtr++ = matrix.Transform(Vector3f(radius*std::sin(angle), -length, radius*std::cos(angle))); - NzVector3f normal; - normal.y = std::sin(-pi_2 + stackValPi); - normal.x = std::cos(sliceValPi2) * sinStackValPi; - normal.z = std::sin(sliceValPi2) * sinStackValPi; + *indices++ = indexOffset + 0; + *indices++ = indexOffset + i+1; + *indices++ = indexOffset + ((i != subdivision-1) ? i+2 : 1); + + if (i != 0 && i != subdivision-1) + { + *indices++ = indexOffset + ((i != subdivision-1) ? i+2 : 1); + *indices++ = indexOffset + i+1; + *indices++ = indexOffset + 1; + } + } + + if (aabb) + { + aabb->MakeZero(); + + // On calcule le reste des points + Vector3f base(Vector3f::Down()*length); + + Vector3f lExtend = Vector3f::Left()*radius; + Vector3f fExtend = Vector3f::Forward()*radius; + + // Et on ajoute ensuite les quatres extrémités de la pyramide + aabb->ExtendTo(base + lExtend + fExtend); + aabb->ExtendTo(base + lExtend - fExtend); + aabb->ExtendTo(base - lExtend + fExtend); + aabb->ExtendTo(base - lExtend - fExtend); + aabb->Transform(matrix, false); + } + } + + void GenerateCubicSphere(float size, unsigned int subdivision, const Matrix4f& matrix, const Rectf& textureCoords, VertexPointers vertexPointers, IndexIterator indices, Boxf* aabb, unsigned int indexOffset) + { + ///DOC: Cette fonction va accéder aux pointeurs en écriture ET en lecture + unsigned int vertexCount; + ComputeBoxIndexVertexCount(Vector3ui(subdivision), nullptr, &vertexCount); + + // On envoie une matrice identité de sorte à ce que la boîte ne subisse aucune transformation (rendant plus facile l'étape suivante) + GenerateBox(Vector3f(size, size, size), Vector3ui(subdivision), Matrix4f::Identity(), textureCoords, vertexPointers, indices, nullptr, indexOffset); + + if (aabb) + { + Vector3f totalSize = size * matrix.GetScale(); + aabb->Set(-totalSize, totalSize); + } + + for (unsigned int i = 0; i < vertexCount; ++i) + { + Vector3f normal = vertexPointers.positionPtr->GetNormal(); *vertexPointers.positionPtr++ = matrix.Transform(size * normal); if (vertexPointers.normalPtr) - *vertexPointers.normalPtr++ = matrix.Transform(normal, 0.f); + *vertexPointers.normalPtr++ = normal; - if (vertexPointers.uvPtr) - *vertexPointers.uvPtr++ = NzVector2f(textureCoords.x + textureCoords.width*(1.f - sliceVal), textureCoords.y + textureCoords.height*stackVal); + ///FIXME: *vertexPointers.tangentPtr++ = ??? + } + } - if (stack != stackCount-1 && slice != sliceCount-1) + void GenerateIcoSphere(float size, unsigned int recursionLevel, const Matrix4f& matrix, const Rectf& textureCoords, VertexPointers vertexPointers, IndexIterator indices, Boxf* aabb, unsigned int indexOffset) + { + IcoSphereBuilder builder(matrix); + builder.Generate(size, recursionLevel, textureCoords, vertexPointers, indices, aabb, indexOffset); + } + + void GeneratePlane(const Vector2ui& subdivision, const Vector2f& size, const Matrix4f& matrix, const Rectf& textureCoords, VertexPointers vertexPointers, IndexIterator indices, Boxf* aabb, unsigned int indexOffset) + { + // Pour plus de facilité, on va construire notre plan en considérant que la normale est de 0,1,0 + // Et appliquer ensuite une matrice "finissant le travail" + + // Le nombre de faces appartenant à un axe est équivalent à 2 exposant la subdivision (1,2,4,8,16,32,...) + unsigned int horizontalFaceCount = (1 << subdivision.x); + unsigned int verticalFaceCount = (1 << subdivision.y); + + // Et le nombre de sommets est ce nombre ajouté de 1 (2,3,5,9,17,33,...) + unsigned int horizontalVertexCount = horizontalFaceCount + 1; + unsigned int verticalVertexCount = verticalFaceCount + 1; + + Vector3f normal(Vector3f::UnitY()); + normal = matrix.Transform(normal, 0.f); + normal.Normalize(); + + Vector3f tangent(1.f, 1.f, 0.f); + tangent = matrix.Transform(tangent, 0.f); + tangent.Normalize(); + + float halfSizeX = size.x / 2.f; + float halfSizeY = size.y / 2.f; + + float invHorizontalVertexCount = 1.f/(horizontalVertexCount-1); + float invVerticalVertexCount = 1.f/(verticalVertexCount-1); + for (unsigned int x = 0; x < horizontalVertexCount; ++x) + { + for (unsigned int y = 0; y < verticalVertexCount; ++y) { - *indices++ = (stack+0)*sliceCount + (slice+0) + indexOffset; - *indices++ = (stack+1)*sliceCount + (slice+0) + indexOffset; - *indices++ = (stack+0)*sliceCount + (slice+1) + indexOffset; + Vector3f localPos((2.f*x*invHorizontalVertexCount - 1.f) * halfSizeX, 0.f, (2.f*y*invVerticalVertexCount - 1.f) * halfSizeY); + *vertexPointers.positionPtr++ = matrix * localPos; - *indices++ = (stack+0)*sliceCount + (slice+1) + indexOffset; - *indices++ = (stack+1)*sliceCount + (slice+0) + indexOffset; - *indices++ = (stack+1)*sliceCount + (slice+1) + indexOffset; + if (vertexPointers.normalPtr) + *vertexPointers.normalPtr++ = normal; + + if (vertexPointers.tangentPtr) + *vertexPointers.tangentPtr++ = tangent; + + if (vertexPointers.uvPtr) + *vertexPointers.uvPtr++ = Vector2f(textureCoords.x + x*invHorizontalVertexCount*textureCoords.width, textureCoords.y + y*invVerticalVertexCount*textureCoords.height); + + if (x != horizontalVertexCount-1 && y != verticalVertexCount-1) + { + *indices++ = (x+0)*verticalVertexCount + y + 0 + indexOffset; + *indices++ = (x+0)*verticalVertexCount + y + 1 + indexOffset; + *indices++ = (x+1)*verticalVertexCount + y + 0 + indexOffset; + + *indices++ = (x+1)*verticalVertexCount + y + 0 + indexOffset; + *indices++ = (x+0)*verticalVertexCount + y + 1 + indexOffset; + *indices++ = (x+1)*verticalVertexCount + y + 1 + indexOffset; + } } } + + if (aabb) + aabb->Set(matrix.Transform(Vector3f(-halfSizeX, 0.f, -halfSizeY), 0.f), matrix.Transform(Vector3f(halfSizeX, 0.f, halfSizeY), 0.f)); } - if (aabb) + void GenerateUvSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Matrix4f& matrix, const Rectf& textureCoords, VertexPointers vertexPointers, IndexIterator indices, Boxf* aabb, unsigned int indexOffset) { - NzVector3f totalSize = size * matrix.GetScale(); - aabb->Set(-totalSize, totalSize); - } -} + // http://stackoverflow.com/questions/14080932/implementing-opengl-sphere-example-code + float invSliceCount = 1.f / (sliceCount-1); + float invStackCount = 1.f / (stackCount-1); -/**********************************NzOptimize*********************************/ + const float pi = static_cast(M_PI); // Pour éviter toute promotion en double + const float pi2 = pi * 2.f; + const float pi_2 = pi / 2.f; -void NzOptimizeIndices(NzIndexIterator indices, unsigned int indexCount) -{ - VertexCacheOptimizer optimizer; - if (optimizer.Optimize(indices, indexCount) != VertexCacheOptimizer::Success) - NazaraWarning("Indices optimizer failed"); -} - -/************************************NzSkin***********************************/ - -void NzSkinPosition(const NzSkinningData& skinningInfos, unsigned int startVertex, unsigned int vertexCount) -{ - const NzSkeletalMeshVertex* inputVertex = &skinningInfos.inputVertex[startVertex]; - NzMeshVertex* outputVertex = &skinningInfos.outputVertex[startVertex]; - - unsigned int endVertex = startVertex + vertexCount - 1; - for (unsigned int i = startVertex; i <= endVertex; ++i) - { - NzVector3f finalPosition(NzVector3f::Zero()); - - for (int j = 0; j < inputVertex->weightCount; ++j) + for (unsigned int stack = 0; stack < stackCount; ++stack) { - NzMatrix4f mat(skinningInfos.joints[inputVertex->jointIndexes[j]].GetSkinningMatrix()); - mat *= inputVertex->weights[j]; + float stackVal = stack * invStackCount; + float stackValPi = stackVal * pi; + float sinStackValPi = std::sin(stackValPi); - finalPosition += mat.Transform(inputVertex->position); + for (unsigned int slice = 0; slice < sliceCount; ++slice) + { + float sliceVal = slice * invSliceCount; + float sliceValPi2 = sliceVal * pi2; + + Vector3f normal; + normal.y = std::sin(-pi_2 + stackValPi); + normal.x = std::cos(sliceValPi2) * sinStackValPi; + normal.z = std::sin(sliceValPi2) * sinStackValPi; + + *vertexPointers.positionPtr++ = matrix.Transform(size * normal); + + if (vertexPointers.normalPtr) + *vertexPointers.normalPtr++ = matrix.Transform(normal, 0.f); + + if (vertexPointers.uvPtr) + *vertexPointers.uvPtr++ = Vector2f(textureCoords.x + textureCoords.width*(1.f - sliceVal), textureCoords.y + textureCoords.height*stackVal); + + if (stack != stackCount-1 && slice != sliceCount-1) + { + *indices++ = (stack+0)*sliceCount + (slice+0) + indexOffset; + *indices++ = (stack+1)*sliceCount + (slice+0) + indexOffset; + *indices++ = (stack+0)*sliceCount + (slice+1) + indexOffset; + + *indices++ = (stack+0)*sliceCount + (slice+1) + indexOffset; + *indices++ = (stack+1)*sliceCount + (slice+0) + indexOffset; + *indices++ = (stack+1)*sliceCount + (slice+1) + indexOffset; + } + } } - outputVertex->position = finalPosition; - outputVertex->uv = inputVertex->uv; - - inputVertex++; - outputVertex++; - } -} - -void NzSkinPositionNormal(const NzSkinningData& skinningInfos, unsigned int startVertex, unsigned int vertexCount) -{ - const NzSkeletalMeshVertex* inputVertex = &skinningInfos.inputVertex[startVertex]; - NzMeshVertex* outputVertex = &skinningInfos.outputVertex[startVertex]; - - unsigned int endVertex = startVertex + vertexCount - 1; - for (unsigned int i = startVertex; i <= endVertex; ++i) - { - NzVector3f finalPosition(NzVector3f::Zero()); - NzVector3f finalNormal(NzVector3f::Zero()); - - for (int j = 0; j < inputVertex->weightCount; ++j) + if (aabb) { - NzMatrix4f mat(skinningInfos.joints[inputVertex->jointIndexes[j]].GetSkinningMatrix()); - mat *= inputVertex->weights[j]; - - finalPosition += mat.Transform(inputVertex->position); - finalNormal += mat.Transform(inputVertex->normal, 0.f); + Vector3f totalSize = size * matrix.GetScale(); + aabb->Set(-totalSize, totalSize); } - - finalNormal.Normalize(); - - outputVertex->normal = finalNormal; - outputVertex->position = finalPosition; - outputVertex->uv = inputVertex->uv; - - inputVertex++; - outputVertex++; } -} -void NzSkinPositionNormalTangent(const NzSkinningData& skinningInfos, unsigned int startVertex, unsigned int vertexCount) -{ - const NzSkeletalMeshVertex* inputVertex = &skinningInfos.inputVertex[startVertex]; - NzMeshVertex* outputVertex = &skinningInfos.outputVertex[startVertex]; + /**********************************Optimize*********************************/ - unsigned int endVertex = startVertex + vertexCount - 1; - for (unsigned int i = startVertex; i <= endVertex; ++i) + void OptimizeIndices(IndexIterator indices, unsigned int indexCount) { - NzVector3f finalPosition(NzVector3f::Zero()); - NzVector3f finalNormal(NzVector3f::Zero()); - NzVector3f finalTangent(NzVector3f::Zero()); + VertexCacheOptimizer optimizer; + if (optimizer.Optimize(indices, indexCount) != VertexCacheOptimizer::Success) + NazaraWarning("Indices optimizer failed"); + } - for (int j = 0; j < inputVertex->weightCount; ++j) + /************************************Skin***********************************/ + + void SkinPosition(const SkinningData& skinningInfos, unsigned int startVertex, unsigned int vertexCount) + { + const SkeletalMeshVertex* inputVertex = &skinningInfos.inputVertex[startVertex]; + MeshVertex* outputVertex = &skinningInfos.outputVertex[startVertex]; + + unsigned int endVertex = startVertex + vertexCount - 1; + for (unsigned int i = startVertex; i <= endVertex; ++i) { - NzMatrix4f mat(skinningInfos.joints[inputVertex->jointIndexes[j]].GetSkinningMatrix()); - mat *= inputVertex->weights[j]; + Vector3f finalPosition(Vector3f::Zero()); - finalPosition += mat.Transform(inputVertex->position); - finalNormal += mat.Transform(inputVertex->normal, 0.f); - finalTangent += mat.Transform(inputVertex->tangent, 0.f); + for (int j = 0; j < inputVertex->weightCount; ++j) + { + Matrix4f mat(skinningInfos.joints[inputVertex->jointIndexes[j]].GetSkinningMatrix()); + mat *= inputVertex->weights[j]; + + finalPosition += mat.Transform(inputVertex->position); + } + + outputVertex->position = finalPosition; + outputVertex->uv = inputVertex->uv; + + inputVertex++; + outputVertex++; } - - finalNormal.Normalize(); - finalTangent.Normalize(); - - outputVertex->normal = finalNormal; - outputVertex->position = finalPosition; - outputVertex->tangent = finalTangent; - outputVertex->uv = inputVertex->uv; - - inputVertex++; - outputVertex++; } -} -/*********************************NzTransform*********************************/ - -void NzTransformVertices(NzVertexPointers vertexPointers, unsigned int vertexCount, const NzMatrix4f& matrix) -{ - ///DOC: Pointeur read/write - NzVector3f scale = matrix.GetScale(); - - for (unsigned int i = 0; i < vertexCount; ++i) + void SkinPositionNormal(const SkinningData& skinningInfos, unsigned int startVertex, unsigned int vertexCount) { - *vertexPointers.positionPtr++ = matrix.Transform(*vertexPointers.positionPtr); + const SkeletalMeshVertex* inputVertex = &skinningInfos.inputVertex[startVertex]; + MeshVertex* outputVertex = &skinningInfos.outputVertex[startVertex]; - if (vertexPointers.normalPtr) - *vertexPointers.normalPtr++ = matrix.Transform(*vertexPointers.normalPtr, 0.f) / scale; + unsigned int endVertex = startVertex + vertexCount - 1; + for (unsigned int i = startVertex; i <= endVertex; ++i) + { + Vector3f finalPosition(Vector3f::Zero()); + Vector3f finalNormal(Vector3f::Zero()); - if (vertexPointers.tangentPtr) - *vertexPointers.tangentPtr++ = matrix.Transform(*vertexPointers.tangentPtr, 0.f) / scale; + for (int j = 0; j < inputVertex->weightCount; ++j) + { + Matrix4f mat(skinningInfos.joints[inputVertex->jointIndexes[j]].GetSkinningMatrix()); + mat *= inputVertex->weights[j]; + + finalPosition += mat.Transform(inputVertex->position); + finalNormal += mat.Transform(inputVertex->normal, 0.f); + } + + finalNormal.Normalize(); + + outputVertex->normal = finalNormal; + outputVertex->position = finalPosition; + outputVertex->uv = inputVertex->uv; + + inputVertex++; + outputVertex++; + } + } + + void SkinPositionNormalTangent(const SkinningData& skinningInfos, unsigned int startVertex, unsigned int vertexCount) + { + const SkeletalMeshVertex* inputVertex = &skinningInfos.inputVertex[startVertex]; + MeshVertex* outputVertex = &skinningInfos.outputVertex[startVertex]; + + unsigned int endVertex = startVertex + vertexCount - 1; + for (unsigned int i = startVertex; i <= endVertex; ++i) + { + Vector3f finalPosition(Vector3f::Zero()); + Vector3f finalNormal(Vector3f::Zero()); + Vector3f finalTangent(Vector3f::Zero()); + + for (int j = 0; j < inputVertex->weightCount; ++j) + { + Matrix4f mat(skinningInfos.joints[inputVertex->jointIndexes[j]].GetSkinningMatrix()); + mat *= inputVertex->weights[j]; + + finalPosition += mat.Transform(inputVertex->position); + finalNormal += mat.Transform(inputVertex->normal, 0.f); + finalTangent += mat.Transform(inputVertex->tangent, 0.f); + } + + finalNormal.Normalize(); + finalTangent.Normalize(); + + outputVertex->normal = finalNormal; + outputVertex->position = finalPosition; + outputVertex->tangent = finalTangent; + outputVertex->uv = inputVertex->uv; + + inputVertex++; + outputVertex++; + } + } + + /*********************************Transform*********************************/ + + void TransformVertices(VertexPointers vertexPointers, unsigned int vertexCount, const Matrix4f& matrix) + { + ///DOC: Pointeur read/write + Vector3f scale = matrix.GetScale(); + + for (unsigned int i = 0; i < vertexCount; ++i) + { + *vertexPointers.positionPtr++ = matrix.Transform(*vertexPointers.positionPtr); + + if (vertexPointers.normalPtr) + *vertexPointers.normalPtr++ = matrix.Transform(*vertexPointers.normalPtr, 0.f) / scale; + + if (vertexPointers.tangentPtr) + *vertexPointers.tangentPtr++ = matrix.Transform(*vertexPointers.tangentPtr, 0.f) / scale; + } } } diff --git a/src/Nazara/Utility/Animation.cpp b/src/Nazara/Utility/Animation.cpp index 9e0047442..683b4f3a7 100644 --- a/src/Nazara/Utility/Animation.cpp +++ b/src/Nazara/Utility/Animation.cpp @@ -10,530 +10,533 @@ #include #include -struct NzAnimationImpl +namespace Nz { - std::unordered_map sequenceMap; - std::vector sequences; - std::vector sequenceJoints; // Uniquement pour les animations squelettiques - nzAnimationType type; - bool loopPointInterpolation = false; - unsigned int frameCount; - unsigned int jointCount; // Uniquement pour les animations squelettiques -}; - -bool NzAnimationParams::IsValid() const -{ - if (startFrame > endFrame) + struct AnimationImpl { - NazaraError("Start frame index must be smaller than end frame index"); - return false; - } + std::unordered_map sequenceMap; + std::vector sequences; + std::vector sequenceJoints; // Uniquement pour les animations squelettiques + AnimationType type; + bool loopPointInterpolation = false; + unsigned int frameCount; + unsigned int jointCount; // Uniquement pour les animations squelettiques + }; - return true; -} - -NzAnimation::~NzAnimation() -{ - OnAnimationRelease(this); -} - -bool NzAnimation::AddSequence(const NzSequence& sequence) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) + bool AnimationParams::IsValid() const { - NazaraError("Animation not created"); - return false; - } - - if (sequence.frameCount == 0) - { - NazaraError("Sequence frame count must be over zero"); - return false; - } - #endif - - if (m_impl->type == nzAnimationType_Skeletal) - { - unsigned int endFrame = sequence.firstFrame + sequence.frameCount - 1; - if (endFrame >= m_impl->frameCount) + if (startFrame > endFrame) { - m_impl->frameCount = endFrame+1; - m_impl->sequenceJoints.resize(m_impl->frameCount*m_impl->jointCount); - } - } - #if NAZARA_UTILITY_SAFE - else - { - unsigned int endFrame = sequence.firstFrame + sequence.frameCount - 1; - if (endFrame >= m_impl->frameCount) - { - NazaraError("Sequence end frame is over animation end frame"); + NazaraError("Start frame index must be smaller than end frame index"); return false; } - } - #endif - if (!sequence.name.IsEmpty()) + return true; + } + + Animation::~Animation() + { + OnAnimationRelease(this); + } + + bool Animation::AddSequence(const Sequence& sequence) { #if NAZARA_UTILITY_SAFE - auto it = m_impl->sequenceMap.find(sequence.name); - if (it != m_impl->sequenceMap.end()) + if (!m_impl) { - NazaraError("Sequence name \"" + sequence.name + "\" is already used"); + NazaraError("Animation not created"); + return false; + } + + if (sequence.frameCount == 0) + { + NazaraError("Sequence frame count must be over zero"); return false; } #endif - m_impl->sequenceMap[sequence.name] = m_impl->sequences.size(); + if (m_impl->type == AnimationType_Skeletal) + { + unsigned int endFrame = sequence.firstFrame + sequence.frameCount - 1; + if (endFrame >= m_impl->frameCount) + { + m_impl->frameCount = endFrame+1; + m_impl->sequenceJoints.resize(m_impl->frameCount*m_impl->jointCount); + } + } + #if NAZARA_UTILITY_SAFE + else + { + unsigned int endFrame = sequence.firstFrame + sequence.frameCount - 1; + if (endFrame >= m_impl->frameCount) + { + NazaraError("Sequence end frame is over animation end frame"); + return false; + } + } + #endif + + if (!sequence.name.IsEmpty()) + { + #if NAZARA_UTILITY_SAFE + auto it = m_impl->sequenceMap.find(sequence.name); + if (it != m_impl->sequenceMap.end()) + { + NazaraError("Sequence name \"" + sequence.name + "\" is already used"); + return false; + } + #endif + + m_impl->sequenceMap[sequence.name] = m_impl->sequences.size(); + } + + m_impl->sequences.push_back(sequence); + + return true; } - m_impl->sequences.push_back(sequence); + void Animation::AnimateSkeleton(Skeleton* targetSkeleton, unsigned int frameA, unsigned int frameB, float interpolation) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return; + } - return true; + if (m_impl->type != AnimationType_Skeletal) + { + NazaraError("Animation is not skeletal"); + return; + } + + if (!targetSkeleton || !targetSkeleton->IsValid()) + { + NazaraError("Target skeleton is invalid"); + return; + } + + if (targetSkeleton->GetJointCount() != m_impl->jointCount) + { + NazaraError("Target skeleton joint count must match animation joint count"); + return; + } + + if (frameA >= m_impl->frameCount) + { + NazaraError("Frame A is out of range (" + String::Number(frameA) + " >= " + String::Number(m_impl->frameCount) + ')'); + return; + } + + if (frameB >= m_impl->frameCount) + { + NazaraError("Frame B is out of range (" + String::Number(frameB) + " >= " + String::Number(m_impl->frameCount) + ')'); + return; + } + #endif + + #ifdef NAZARA_DEBUG + if (interpolation < 0.f || interpolation > 1.f) + { + NazaraError("Interpolation must be in range [0..1] (Got " + String::Number(interpolation) + ')'); + return; + } + #endif + + for (unsigned int i = 0; i < m_impl->jointCount; ++i) + { + Joint* joint = targetSkeleton->GetJoint(i); + + SequenceJoint& sequenceJointA = m_impl->sequenceJoints[frameA*m_impl->jointCount + i]; + SequenceJoint& sequenceJointB = m_impl->sequenceJoints[frameB*m_impl->jointCount + i]; + + joint->SetPosition(Vector3f::Lerp(sequenceJointA.position, sequenceJointB.position, interpolation)); + joint->SetRotation(Quaternionf::Slerp(sequenceJointA.rotation, sequenceJointB.rotation, interpolation)); + joint->SetScale(Vector3f::Lerp(sequenceJointA.scale, sequenceJointB.scale, interpolation)); + } + } + + bool Animation::CreateSkeletal(unsigned int frameCount, unsigned int jointCount) + { + Destroy(); + + #if NAZARA_UTILITY_SAFE + if (frameCount == 0) + { + NazaraError("Frame count must be over zero"); + return false; + } + #endif + + m_impl = new AnimationImpl; + m_impl->frameCount = frameCount; + m_impl->jointCount = jointCount; + m_impl->sequenceJoints.resize(frameCount*jointCount); + m_impl->type = AnimationType_Skeletal; + + return true; + } + + void Animation::Destroy() + { + if (m_impl) + { + OnAnimationDestroy(this); + + delete m_impl; + m_impl = nullptr; + } + } + + void Animation::EnableLoopPointInterpolation(bool loopPointInterpolation) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return; + } + #endif + + m_impl->loopPointInterpolation = loopPointInterpolation; + } + + unsigned int Animation::GetFrameCount() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return false; + } + #endif + + return m_impl->frameCount; + } + + unsigned int Animation::GetJointCount() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return 0; + } + + if (m_impl->type != AnimationType_Skeletal) + { + NazaraError("Animation is not skeletal"); + return 0; + } + #endif + + return m_impl->jointCount; + } + + Sequence* Animation::GetSequence(const String& sequenceName) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return nullptr; + } + #endif + + auto it = m_impl->sequenceMap.find(sequenceName); + + #if NAZARA_UTILITY_SAFE + if (it == m_impl->sequenceMap.end()) + { + NazaraError("Sequence not found"); + return nullptr; + } + #endif + + return &m_impl->sequences[it->second]; + } + + Sequence* Animation::GetSequence(unsigned int index) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return nullptr; + } + + if (index >= m_impl->sequences.size()) + { + NazaraError("Sequence index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->sequences.size()) + ')'); + return nullptr; + } + #endif + + return &m_impl->sequences[index]; + } + + const Sequence* Animation::GetSequence(const String& sequenceName) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return nullptr; + } + #endif + + auto it = m_impl->sequenceMap.find(sequenceName); + + #if NAZARA_UTILITY_SAFE + if (it == m_impl->sequenceMap.end()) + { + NazaraError("Sequence not found"); + return nullptr; + } + #endif + + return &m_impl->sequences[it->second]; + } + + const Sequence* Animation::GetSequence(unsigned int index) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return nullptr; + } + + if (index >= m_impl->sequences.size()) + { + NazaraError("Sequence index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->sequences.size()) + ')'); + return nullptr; + } + #endif + + return &m_impl->sequences[index]; + } + + unsigned int Animation::GetSequenceCount() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return 0; + } + #endif + + return m_impl->sequences.size(); + } + + int Animation::GetSequenceIndex(const String& sequenceName) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return -1; + } + #endif + + auto it = m_impl->sequenceMap.find(sequenceName); + + #if NAZARA_UTILITY_SAFE + if (it == m_impl->sequenceMap.end()) + { + NazaraError("Sequence not found"); + return -1; + } + #endif + + return it->second; + } + + SequenceJoint* Animation::GetSequenceJoints(unsigned int frameIndex) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return nullptr; + } + + if (m_impl->type != AnimationType_Skeletal) + { + NazaraError("Animation is not skeletal"); + return nullptr; + } + #endif + + return &m_impl->sequenceJoints[frameIndex*m_impl->jointCount]; + } + + const SequenceJoint* Animation::GetSequenceJoints(unsigned int frameIndex) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return nullptr; + } + + if (m_impl->type != AnimationType_Skeletal) + { + NazaraError("Animation is not skeletal"); + return nullptr; + } + #endif + + return &m_impl->sequenceJoints[frameIndex*m_impl->jointCount]; + } + + AnimationType Animation::GetType() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return AnimationType_Static; // Ce qui est une valeur invalide pour Animation + } + #endif + + return m_impl->type; + } + + bool Animation::HasSequence(const String& sequenceName) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return false; + } + #endif + + return m_impl->sequenceMap.find(sequenceName) != m_impl->sequenceMap.end(); + } + + bool Animation::HasSequence(unsigned int index) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return false; + } + #endif + + return index >= m_impl->sequences.size(); + } + + bool Animation::IsLoopPointInterpolationEnabled() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return false; + } + #endif + + return m_impl->loopPointInterpolation; + } + + bool Animation::IsValid() const + { + return m_impl != nullptr; + } + + bool Animation::LoadFromFile(const String& filePath, const AnimationParams& params) + { + return AnimationLoader::LoadFromFile(this, filePath, params); + } + + bool Animation::LoadFromMemory(const void* data, std::size_t size, const AnimationParams& params) + { + return AnimationLoader::LoadFromMemory(this, data, size, params); + } + + bool Animation::LoadFromStream(InputStream& stream, const AnimationParams& params) + { + return AnimationLoader::LoadFromStream(this, stream, params); + } + + void Animation::RemoveSequence(const String& identifier) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return; + } + + auto it = m_impl->sequenceMap.find(identifier); + if (it == m_impl->sequenceMap.end()) + { + NazaraError("Sequence not found"); + return; + } + + int index = it->second; + #else + int index = m_impl->sequenceMap[identifier]; + #endif + + auto it2 = m_impl->sequences.begin(); + std::advance(it2, index); + + m_impl->sequences.erase(it2); + } + + void Animation::RemoveSequence(unsigned int index) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return; + } + + if (index >= m_impl->sequences.size()) + { + NazaraError("Sequence index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->sequences.size()) + ')'); + return; + } + #endif + + auto it = m_impl->sequences.begin(); + std::advance(it, index); + + m_impl->sequences.erase(it); + } + + bool Animation::Initialize() + { + if (!AnimationLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } + + if (!AnimationManager::Initialize()) + { + NazaraError("Failed to initialise manager"); + return false; + } + + return true; + } + + void Animation::Uninitialize() + { + AnimationManager::Uninitialize(); + AnimationLibrary::Uninitialize(); + } + + AnimationLibrary::LibraryMap Animation::s_library; + AnimationLoader::LoaderList Animation::s_loaders; + AnimationManager::ManagerMap Animation::s_managerMap; + AnimationManager::ManagerParams Animation::s_managerParameters; } - -void NzAnimation::AnimateSkeleton(NzSkeleton* targetSkeleton, unsigned int frameA, unsigned int frameB, float interpolation) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return; - } - - if (m_impl->type != nzAnimationType_Skeletal) - { - NazaraError("Animation is not skeletal"); - return; - } - - if (!targetSkeleton || !targetSkeleton->IsValid()) - { - NazaraError("Target skeleton is invalid"); - return; - } - - if (targetSkeleton->GetJointCount() != m_impl->jointCount) - { - NazaraError("Target skeleton joint count must match animation joint count"); - return; - } - - if (frameA >= m_impl->frameCount) - { - NazaraError("Frame A is out of range (" + NzString::Number(frameA) + " >= " + NzString::Number(m_impl->frameCount) + ')'); - return; - } - - if (frameB >= m_impl->frameCount) - { - NazaraError("Frame B is out of range (" + NzString::Number(frameB) + " >= " + NzString::Number(m_impl->frameCount) + ')'); - return; - } - #endif - - #ifdef NAZARA_DEBUG - if (interpolation < 0.f || interpolation > 1.f) - { - NazaraError("Interpolation must be in range [0..1] (Got " + NzString::Number(interpolation) + ')'); - return; - } - #endif - - for (unsigned int i = 0; i < m_impl->jointCount; ++i) - { - NzJoint* joint = targetSkeleton->GetJoint(i); - - NzSequenceJoint& sequenceJointA = m_impl->sequenceJoints[frameA*m_impl->jointCount + i]; - NzSequenceJoint& sequenceJointB = m_impl->sequenceJoints[frameB*m_impl->jointCount + i]; - - joint->SetPosition(NzVector3f::Lerp(sequenceJointA.position, sequenceJointB.position, interpolation)); - joint->SetRotation(NzQuaternionf::Slerp(sequenceJointA.rotation, sequenceJointB.rotation, interpolation)); - joint->SetScale(NzVector3f::Lerp(sequenceJointA.scale, sequenceJointB.scale, interpolation)); - } -} - -bool NzAnimation::CreateSkeletal(unsigned int frameCount, unsigned int jointCount) -{ - Destroy(); - - #if NAZARA_UTILITY_SAFE - if (frameCount == 0) - { - NazaraError("Frame count must be over zero"); - return false; - } - #endif - - m_impl = new NzAnimationImpl; - m_impl->frameCount = frameCount; - m_impl->jointCount = jointCount; - m_impl->sequenceJoints.resize(frameCount*jointCount); - m_impl->type = nzAnimationType_Skeletal; - - return true; -} - -void NzAnimation::Destroy() -{ - if (m_impl) - { - OnAnimationDestroy(this); - - delete m_impl; - m_impl = nullptr; - } -} - -void NzAnimation::EnableLoopPointInterpolation(bool loopPointInterpolation) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return; - } - #endif - - m_impl->loopPointInterpolation = loopPointInterpolation; -} - -unsigned int NzAnimation::GetFrameCount() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return false; - } - #endif - - return m_impl->frameCount; -} - -unsigned int NzAnimation::GetJointCount() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return 0; - } - - if (m_impl->type != nzAnimationType_Skeletal) - { - NazaraError("Animation is not skeletal"); - return 0; - } - #endif - - return m_impl->jointCount; -} - -NzSequence* NzAnimation::GetSequence(const NzString& sequenceName) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return nullptr; - } - #endif - - auto it = m_impl->sequenceMap.find(sequenceName); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->sequenceMap.end()) - { - NazaraError("Sequence not found"); - return nullptr; - } - #endif - - return &m_impl->sequences[it->second]; -} - -NzSequence* NzAnimation::GetSequence(unsigned int index) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return nullptr; - } - - if (index >= m_impl->sequences.size()) - { - NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')'); - return nullptr; - } - #endif - - return &m_impl->sequences[index]; -} - -const NzSequence* NzAnimation::GetSequence(const NzString& sequenceName) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return nullptr; - } - #endif - - auto it = m_impl->sequenceMap.find(sequenceName); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->sequenceMap.end()) - { - NazaraError("Sequence not found"); - return nullptr; - } - #endif - - return &m_impl->sequences[it->second]; -} - -const NzSequence* NzAnimation::GetSequence(unsigned int index) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return nullptr; - } - - if (index >= m_impl->sequences.size()) - { - NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')'); - return nullptr; - } - #endif - - return &m_impl->sequences[index]; -} - -unsigned int NzAnimation::GetSequenceCount() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return 0; - } - #endif - - return m_impl->sequences.size(); -} - -int NzAnimation::GetSequenceIndex(const NzString& sequenceName) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return -1; - } - #endif - - auto it = m_impl->sequenceMap.find(sequenceName); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->sequenceMap.end()) - { - NazaraError("Sequence not found"); - return -1; - } - #endif - - return it->second; -} - -NzSequenceJoint* NzAnimation::GetSequenceJoints(unsigned int frameIndex) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return nullptr; - } - - if (m_impl->type != nzAnimationType_Skeletal) - { - NazaraError("Animation is not skeletal"); - return nullptr; - } - #endif - - return &m_impl->sequenceJoints[frameIndex*m_impl->jointCount]; -} - -const NzSequenceJoint* NzAnimation::GetSequenceJoints(unsigned int frameIndex) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return nullptr; - } - - if (m_impl->type != nzAnimationType_Skeletal) - { - NazaraError("Animation is not skeletal"); - return nullptr; - } - #endif - - return &m_impl->sequenceJoints[frameIndex*m_impl->jointCount]; -} - -nzAnimationType NzAnimation::GetType() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return nzAnimationType_Static; // Ce qui est une valeur invalide pour NzAnimation - } - #endif - - return m_impl->type; -} - -bool NzAnimation::HasSequence(const NzString& sequenceName) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return false; - } - #endif - - return m_impl->sequenceMap.find(sequenceName) != m_impl->sequenceMap.end(); -} - -bool NzAnimation::HasSequence(unsigned int index) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return false; - } - #endif - - return index >= m_impl->sequences.size(); -} - -bool NzAnimation::IsLoopPointInterpolationEnabled() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return false; - } - #endif - - return m_impl->loopPointInterpolation; -} - -bool NzAnimation::IsValid() const -{ - return m_impl != nullptr; -} - -bool NzAnimation::LoadFromFile(const NzString& filePath, const NzAnimationParams& params) -{ - return NzAnimationLoader::LoadFromFile(this, filePath, params); -} - -bool NzAnimation::LoadFromMemory(const void* data, std::size_t size, const NzAnimationParams& params) -{ - return NzAnimationLoader::LoadFromMemory(this, data, size, params); -} - -bool NzAnimation::LoadFromStream(NzInputStream& stream, const NzAnimationParams& params) -{ - return NzAnimationLoader::LoadFromStream(this, stream, params); -} - -void NzAnimation::RemoveSequence(const NzString& identifier) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return; - } - - auto it = m_impl->sequenceMap.find(identifier); - if (it == m_impl->sequenceMap.end()) - { - NazaraError("Sequence not found"); - return; - } - - int index = it->second; - #else - int index = m_impl->sequenceMap[identifier]; - #endif - - auto it2 = m_impl->sequences.begin(); - std::advance(it2, index); - - m_impl->sequences.erase(it2); -} - -void NzAnimation::RemoveSequence(unsigned int index) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return; - } - - if (index >= m_impl->sequences.size()) - { - NazaraError("Sequence index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->sequences.size()) + ')'); - return; - } - #endif - - auto it = m_impl->sequences.begin(); - std::advance(it, index); - - m_impl->sequences.erase(it); -} - -bool NzAnimation::Initialize() -{ - if (!NzAnimationLibrary::Initialize()) - { - NazaraError("Failed to initialise library"); - return false; - } - - if (!NzAnimationManager::Initialize()) - { - NazaraError("Failed to initialise manager"); - return false; - } - - return true; -} - -void NzAnimation::Uninitialize() -{ - NzAnimationManager::Uninitialize(); - NzAnimationLibrary::Uninitialize(); -} - -NzAnimationLibrary::LibraryMap NzAnimation::s_library; -NzAnimationLoader::LoaderList NzAnimation::s_loaders; -NzAnimationManager::ManagerMap NzAnimation::s_managerMap; -NzAnimationManager::ManagerParams NzAnimation::s_managerParameters; diff --git a/src/Nazara/Utility/Buffer.cpp b/src/Nazara/Utility/Buffer.cpp index 82eee5e88..503d6619b 100644 --- a/src/Nazara/Utility/Buffer.cpp +++ b/src/Nazara/Utility/Buffer.cpp @@ -15,287 +15,290 @@ #include #include -namespace +namespace Nz { - NzAbstractBuffer* SoftwareBufferFactory(NzBuffer* parent, nzBufferType type) + namespace { - return new NzSoftwareBuffer(parent, type); - } -} - -NzBuffer::NzBuffer(nzBufferType type) : -m_type(type), -m_impl(nullptr), -m_size(0) -{ -} - -NzBuffer::NzBuffer(nzBufferType type, unsigned int size, nzUInt32 storage, nzBufferUsage usage) : -m_type(type), -m_impl(nullptr) -{ - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - Create(size, storage, usage); -} - -NzBuffer::~NzBuffer() -{ - OnBufferRelease(this); - - Destroy(); -} - -bool NzBuffer::CopyContent(const NzBuffer& buffer) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Buffer must be valid"); - return false; + AbstractBuffer* SoftwareBufferFactory(Buffer* parent, BufferType type) + { + return new SoftwareBuffer(parent, type); + } } - if (!buffer.IsValid()) + Buffer::Buffer(BufferType type) : + m_type(type), + m_impl(nullptr), + m_size(0) { - NazaraError("Source buffer must be valid"); - return false; - } - #endif - - NzBufferMapper mapper(buffer, nzBufferAccess_ReadOnly); - return Fill(mapper.GetPointer(), 0, buffer.GetSize()); -} - -bool NzBuffer::Create(unsigned int size, nzUInt32 storage, nzBufferUsage usage) -{ - Destroy(); - - // Notre buffer est-il supporté ? - if (!IsStorageSupported(storage)) - { - NazaraError("Buffer storage not supported"); - return false; } - std::unique_ptr impl(s_bufferFactories[storage](this, m_type)); - if (!impl->Create(size, usage)) + Buffer::Buffer(BufferType type, unsigned int size, UInt32 storage, BufferUsage usage) : + m_type(type), + m_impl(nullptr) { - NazaraError("Failed to create buffer"); - return false; + ErrorFlags flags(ErrorFlag_ThrowException, true); + Create(size, storage, usage); } - m_impl = impl.release(); - m_size = size; - m_storage = storage; - m_usage = usage; - - return true; // Si on arrive ici c'est que tout s'est bien passé. -} - -void NzBuffer::Destroy() -{ - if (m_impl) + Buffer::~Buffer() { - OnBufferDestroy(this); + OnBufferRelease(this); + Destroy(); + } + + bool Buffer::CopyContent(const Buffer& buffer) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Buffer must be valid"); + return false; + } + + if (!buffer.IsValid()) + { + NazaraError("Source buffer must be valid"); + return false; + } + #endif + + BufferMapper mapper(buffer, BufferAccess_ReadOnly); + return Fill(mapper.GetPointer(), 0, buffer.GetSize()); + } + + bool Buffer::Create(unsigned int size, UInt32 storage, BufferUsage usage) + { + Destroy(); + + // Notre buffer est-il supporté ? + if (!IsStorageSupported(storage)) + { + NazaraError("Buffer storage not supported"); + return false; + } + + std::unique_ptr impl(s_bufferFactories[storage](this, m_type)); + if (!impl->Create(size, usage)) + { + NazaraError("Failed to create buffer"); + return false; + } + + m_impl = impl.release(); + m_size = size; + m_storage = storage; + m_usage = usage; + + return true; // Si on arrive ici c'est que tout s'est bien passé. + } + + void Buffer::Destroy() + { + if (m_impl) + { + OnBufferDestroy(this); + + m_impl->Destroy(); + delete m_impl; + m_impl = nullptr; + } + } + + bool Buffer::Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Buffer not valid"); + return false; + } + + if (offset+size > m_size) + { + NazaraError("Exceeding buffer size (" + String::Number(offset+size) + " > " + String::Number(m_size) + ')'); + return false; + } + #endif + + return m_impl->Fill(data, offset, (size == 0) ? m_size-offset : size, forceDiscard); + } + + AbstractBuffer* Buffer::GetImpl() const + { + return m_impl; + } + + unsigned int Buffer::GetSize() const + { + return m_size; + } + + UInt32 Buffer::GetStorage() const + { + return m_storage; + } + + BufferType Buffer::GetType() const + { + return m_type; + } + + BufferUsage Buffer::GetUsage() const + { + return m_usage; + } + + bool Buffer::IsHardware() const + { + return m_storage & DataStorage_Hardware; + } + + bool Buffer::IsValid() const + { + return m_impl != nullptr; + } + + void* Buffer::Map(BufferAccess access, unsigned int offset, unsigned int size) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Buffer not valid"); + return nullptr; + } + + if (offset+size > m_size) + { + NazaraError("Exceeding buffer size"); + return nullptr; + } + #endif + + return m_impl->Map(access, offset, (size == 0) ? m_size-offset : size); + } + + void* Buffer::Map(BufferAccess access, unsigned int offset, unsigned int size) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Buffer not valid"); + return nullptr; + } + + if (access != BufferAccess_ReadOnly) + { + NazaraError("Buffer access must be read-only when used const"); + return nullptr; + } + + if (offset+size > m_size) + { + NazaraError("Exceeding buffer size"); + return nullptr; + } + #endif + + return m_impl->Map(access, offset, (size == 0) ? m_size-offset : size); + } + + bool Buffer::SetStorage(UInt32 storage) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Buffer not valid"); + return false; + } + #endif + + if (m_storage == storage) + return true; + + if (!IsStorageSupported(storage)) + { + NazaraError("Storage not supported"); + return false; + } + + void* ptr = m_impl->Map(BufferAccess_ReadOnly, 0, m_size); + if (!ptr) + { + NazaraError("Failed to map buffer"); + return false; + } + + CallOnExit unmapMyImpl([this]() + { + m_impl->Unmap(); + }); + + std::unique_ptr impl(s_bufferFactories[storage](this, m_type)); + if (!impl->Create(m_size, m_usage)) + { + NazaraError("Failed to create buffer"); + return false; + } + + CallOnExit destroyImpl([&impl]() + { + impl->Destroy(); + }); + + if (!impl->Fill(ptr, 0, m_size)) + { + NazaraError("Failed to fill buffer"); + return false; + } + + destroyImpl.Reset(); + + unmapMyImpl.CallAndReset(); m_impl->Destroy(); delete m_impl; - m_impl = nullptr; - } -} -bool NzBuffer::Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Buffer not valid"); - return false; - } + m_impl = impl.release(); + m_storage = storage; - if (offset+size > m_size) - { - NazaraError("Exceeding buffer size (" + NzString::Number(offset+size) + " > " + NzString::Number(m_size) + ')'); - return false; - } - #endif - - return m_impl->Fill(data, offset, (size == 0) ? m_size-offset : size, forceDiscard); -} - -NzAbstractBuffer* NzBuffer::GetImpl() const -{ - return m_impl; -} - -unsigned int NzBuffer::GetSize() const -{ - return m_size; -} - -nzUInt32 NzBuffer::GetStorage() const -{ - return m_storage; -} - -nzBufferType NzBuffer::GetType() const -{ - return m_type; -} - -nzBufferUsage NzBuffer::GetUsage() const -{ - return m_usage; -} - -bool NzBuffer::IsHardware() const -{ - return m_storage & nzDataStorage_Hardware; -} - -bool NzBuffer::IsValid() const -{ - return m_impl != nullptr; -} - -void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Buffer not valid"); - return nullptr; - } - - if (offset+size > m_size) - { - NazaraError("Exceeding buffer size"); - return nullptr; - } - #endif - - return m_impl->Map(access, offset, (size == 0) ? m_size-offset : size); -} - -void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Buffer not valid"); - return nullptr; - } - - if (access != nzBufferAccess_ReadOnly) - { - NazaraError("Buffer access must be read-only when used const"); - return nullptr; - } - - if (offset+size > m_size) - { - NazaraError("Exceeding buffer size"); - return nullptr; - } - #endif - - return m_impl->Map(access, offset, (size == 0) ? m_size-offset : size); -} - -bool NzBuffer::SetStorage(nzUInt32 storage) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Buffer not valid"); - return false; - } - #endif - - if (m_storage == storage) return true; - - if (!IsStorageSupported(storage)) - { - NazaraError("Storage not supported"); - return false; } - void* ptr = m_impl->Map(nzBufferAccess_ReadOnly, 0, m_size); - if (!ptr) + void Buffer::Unmap() const { - NazaraError("Failed to map buffer"); - return false; + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Buffer not valid"); + return; + } + #endif + + if (!m_impl->Unmap()) + NazaraWarning("Failed to unmap buffer (it's content may be undefined)"); ///TODO: Unexpected ? } - NzCallOnExit unmapMyImpl([this]() + bool Buffer::IsStorageSupported(UInt32 storage) { - m_impl->Unmap(); - }); - - std::unique_ptr impl(s_bufferFactories[storage](this, m_type)); - if (!impl->Create(m_size, m_usage)) - { - NazaraError("Failed to create buffer"); - return false; + return s_bufferFactories[storage] != nullptr; } - NzCallOnExit destroyImpl([&impl]() + void Buffer::SetBufferFactory(UInt32 storage, BufferFactory func) { - impl->Destroy(); - }); - - if (!impl->Fill(ptr, 0, m_size)) - { - NazaraError("Failed to fill buffer"); - return false; + s_bufferFactories[storage] = func; } - destroyImpl.Reset(); - - unmapMyImpl.CallAndReset(); - m_impl->Destroy(); - delete m_impl; - - m_impl = impl.release(); - m_storage = storage; - - return true; -} - -void NzBuffer::Unmap() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) + bool Buffer::Initialize() { - NazaraError("Buffer not valid"); - return; + s_bufferFactories[DataStorage_Software] = SoftwareBufferFactory; + + return true; } - #endif - if (!m_impl->Unmap()) - NazaraWarning("Failed to unmap buffer (it's content may be undefined)"); ///TODO: Unexpected ? + void Buffer::Uninitialize() + { + std::memset(s_bufferFactories, 0, (DataStorage_Max+1)*sizeof(Buffer::BufferFactory)); + } + + Buffer::BufferFactory Buffer::s_bufferFactories[DataStorage_Max+1] = {nullptr}; } - -bool NzBuffer::IsStorageSupported(nzUInt32 storage) -{ - return s_bufferFactories[storage] != nullptr; -} - -void NzBuffer::SetBufferFactory(nzUInt32 storage, BufferFactory func) -{ - s_bufferFactories[storage] = func; -} - -bool NzBuffer::Initialize() -{ - s_bufferFactories[nzDataStorage_Software] = SoftwareBufferFactory; - - return true; -} - -void NzBuffer::Uninitialize() -{ - std::memset(s_bufferFactories, 0, (nzDataStorage_Max+1)*sizeof(NzBuffer::BufferFactory)); -} - -NzBuffer::BufferFactory NzBuffer::s_bufferFactories[nzDataStorage_Max+1] = {nullptr}; diff --git a/src/Nazara/Utility/Cursor.cpp b/src/Nazara/Utility/Cursor.cpp index cff05c33a..deddbc753 100644 --- a/src/Nazara/Utility/Cursor.cpp +++ b/src/Nazara/Utility/Cursor.cpp @@ -14,50 +14,53 @@ #include -NzCursor::NzCursor() : -m_impl(nullptr) +namespace Nz { -} - -NzCursor::~NzCursor() -{ - Destroy(); -} - -bool NzCursor::Create(const NzImage& cursor, int hotSpotX, int hotSpotY) -{ - Destroy(); - - m_impl = new NzCursorImpl; - if (!m_impl->Create(cursor, hotSpotX, hotSpotY)) + Cursor::Cursor() : + m_impl(nullptr) { - NazaraError("Failed to create cursor implementation"); - delete m_impl; - m_impl = nullptr; - - return false; } - return true; -} - -bool NzCursor::Create(const NzImage& cursor, const NzVector2i& hotSpot) -{ - return Create(cursor, hotSpot.x, hotSpot.y); -} - -void NzCursor::Destroy() -{ - if (m_impl) + Cursor::~Cursor() { - m_impl->Destroy(); + Destroy(); + } - delete m_impl; - m_impl = nullptr; + bool Cursor::Create(const Image& cursor, int hotSpotX, int hotSpotY) + { + Destroy(); + + m_impl = new CursorImpl; + if (!m_impl->Create(cursor, hotSpotX, hotSpotY)) + { + NazaraError("Failed to create cursor implementation"); + delete m_impl; + m_impl = nullptr; + + return false; + } + + return true; + } + + bool Cursor::Create(const Image& cursor, const Vector2i& hotSpot) + { + return Create(cursor, hotSpot.x, hotSpot.y); + } + + void Cursor::Destroy() + { + if (m_impl) + { + m_impl->Destroy(); + + delete m_impl; + m_impl = nullptr; + } + } + + bool Cursor::IsValid() const + { + return m_impl != nullptr; } } - -bool NzCursor::IsValid() const -{ - return m_impl != nullptr; -} diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index 5aad86245..a2e7b2833 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -9,326 +9,389 @@ #include #include -namespace +namespace Nz { - const nzUInt8 r_cabinRegular[] = { - #include - }; -} - -bool NzFontParams::IsValid() const -{ - return true; // Rien à tester -} - -NzFont::NzFont() : -m_glyphBorder(s_defaultGlyphBorder), -m_minimumStepSize(s_defaultMinimumStepSize) -{ - SetAtlas(s_defaultAtlas); -} - -NzFont::~NzFont() -{ - OnFontRelease(this); - - Destroy(); - SetAtlas(nullptr); // On libère l'atlas proprement -} - -void NzFont::ClearGlyphCache() -{ - if (m_atlas) + namespace { - if (m_atlas.unique()) - m_atlas->Clear(); // Appellera OnAtlasCleared - else - { - // Au moins une autre police utilise cet atlas, on vire nos glyphes un par un - for (auto mapIt = m_glyphes.begin(); mapIt != m_glyphes.end(); ++mapIt) - { - GlyphMap& glyphMap = mapIt->second; - for (auto glyphIt = glyphMap.begin(); glyphIt != glyphMap.end(); ++glyphIt) - { - Glyph& glyph = glyphIt->second; - m_atlas->Free(&glyph.atlasRect, &glyph.layerIndex, 1); - } - } - - // Destruction des glyphes mémorisés et notification - m_glyphes.clear(); - - OnFontGlyphCacheCleared(this); - } - } -} - -void NzFont::ClearKerningCache() -{ - m_kerningCache.clear(); - - OnFontKerningCacheCleared(this); -} - -void NzFont::ClearSizeInfoCache() -{ - m_sizeInfoCache.clear(); - - OnFontSizeInfoCacheCleared(this); -} - -bool NzFont::Create(NzFontData* data) -{ - Destroy(); - - #if NAZARA_UTILITY_SAFE - if (!data) - { - NazaraError("Invalid font data"); - return false; - } - #endif - - m_data.reset(data); - return true; -} - -void NzFont::Destroy() -{ - if (m_data) - { - OnFontDestroy(this); - - ClearGlyphCache(); - - m_data.reset(); - m_kerningCache.clear(); - m_sizeInfoCache.clear(); - } -} - -bool NzFont::ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt32 style, NzFontGlyph* glyph) const -{ - #if NAZARA_UTILITY_SAFE - if (!IsValid()) - { - NazaraError("Invalid font"); - return false; - } - #endif - - return m_data->ExtractGlyph(characterSize, character, style, glyph); -} - -const std::shared_ptr& NzFont::GetAtlas() const -{ - return m_atlas; -} - -unsigned int NzFont::GetCachedGlyphCount(unsigned int characterSize, nzUInt32 style) const -{ - nzUInt64 key = ComputeKey(characterSize, style); - auto it = m_glyphes.find(key); - if (it == m_glyphes.end()) - return 0; - - return it->second.size(); -} - -unsigned int NzFont::GetCachedGlyphCount() const -{ - unsigned int count = 0; - for (auto& pair : m_glyphes) - count += pair.second.size(); - - return count; -} - -NzString NzFont::GetFamilyName() const -{ - #if NAZARA_UTILITY_SAFE - if (!IsValid()) - { - NazaraError("Invalid font"); - return NzString("Invalid font"); - } - #endif - - return m_data->GetFamilyName(); -} - -int NzFont::GetKerning(unsigned int characterSize, char32_t first, char32_t second) const -{ - #if NAZARA_UTILITY_SAFE - if (!IsValid()) - { - NazaraError("Invalid font"); - return 0; - } - #endif - - // On utilise un cache car la méthode interne QueryKerning peut se révéler coûteuse (car pouvant induire un changement de taille) - auto& map = m_kerningCache[characterSize]; - - nzUInt64 key = (static_cast(first) << 32) | second; // Combinaison de deux caractères 32 bits dans un nombre 64 bits - - auto it = map.find(key); - if (it == map.end()) - { - // Absent du cache: on va demander l'information à la police - int kerning = m_data->QueryKerning(characterSize, first, second); - map.insert(std::make_pair(key, kerning)); - - return kerning; - } - else - return it->second; // Présent dans le cache, tout va bien -} - -const NzFont::Glyph& NzFont::GetGlyph(unsigned int characterSize, nzUInt32 style, char32_t character) const -{ - nzUInt64 key = ComputeKey(characterSize, style); - return PrecacheGlyph(m_glyphes[key], characterSize, style, character); -} - -unsigned int NzFont::GetGlyphBorder() const -{ - return m_glyphBorder; -} - -unsigned int NzFont::GetMinimumStepSize() const -{ - return m_minimumStepSize; -} - -const NzFont::SizeInfo& NzFont::GetSizeInfo(unsigned int characterSize) const -{ - #if NAZARA_UTILITY_SAFE - if (!IsValid()) - { - NazaraError("Invalid font"); - - static SizeInfo dummy; - return dummy; - } - #endif - - auto it = m_sizeInfoCache.find(characterSize); - if (it == m_sizeInfoCache.end()) - { - SizeInfo sizeInfo; - sizeInfo.lineHeight = m_data->QueryLineHeight(characterSize); - sizeInfo.underlinePosition = m_data->QueryUnderlinePosition(characterSize); - sizeInfo.underlineThickness = m_data->QueryUnderlineThickness(characterSize); - - NzFontGlyph glyph; - if (m_data->ExtractGlyph(characterSize, ' ', nzTextStyle_Regular, &glyph)) - sizeInfo.spaceAdvance = glyph.advance; - else - { - NazaraWarning("Failed to extract space character from font, using half the size"); - sizeInfo.spaceAdvance = characterSize/2; - } - - it = m_sizeInfoCache.insert(std::make_pair(characterSize, sizeInfo)).first; + const UInt8 r_cabinRegular[] = { + #include + }; } - return it->second; -} - -NzString NzFont::GetStyleName() const -{ - #if NAZARA_UTILITY_SAFE - if (!IsValid()) + bool FontParams::IsValid() const { - NazaraError("Invalid font"); - return NzString("Invalid font"); - } - #endif - - return m_data->GetStyleName(); -} - -bool NzFont::IsValid() const -{ - return m_data != nullptr; -} - -bool NzFont::Precache(unsigned int characterSize, nzUInt32 style, char32_t character) const -{ - nzUInt64 key = ComputeKey(characterSize, style); - return PrecacheGlyph(m_glyphes[key], characterSize, style, character).valid; -} - -bool NzFont::Precache(unsigned int characterSize, nzUInt32 style, const NzString& characterSet) const -{ - ///TODO: Itération UTF-8 => UTF-32 sans allocation de buffer (Exposer utf8cpp ?) - std::u32string set = characterSet.GetUtf32String(); - if (set.empty()) - { - NazaraError("Invalid character set"); - return false; + return true; // Rien à tester } - nzUInt64 key = ComputeKey(characterSize, style); - auto& glyphMap = m_glyphes[key]; - for (char32_t character : set) - PrecacheGlyph(glyphMap, characterSize, style, character); - - return true; -} - -bool NzFont::OpenFromFile(const NzString& filePath, const NzFontParams& params) -{ - return NzFontLoader::LoadFromFile(this, filePath, params); -} - -bool NzFont::OpenFromMemory(const void* data, std::size_t size, const NzFontParams& params) -{ - return NzFontLoader::LoadFromMemory(this, data, size, params); -} - -bool NzFont::OpenFromStream(NzInputStream& stream, const NzFontParams& params) -{ - return NzFontLoader::LoadFromStream(this, stream, params); -} - -void NzFont::SetAtlas(const std::shared_ptr& atlas) -{ - if (m_atlas != atlas) + Font::Font() : + m_glyphBorder(s_defaultGlyphBorder), + m_minimumStepSize(s_defaultMinimumStepSize) { - ClearGlyphCache(); + SetAtlas(s_defaultAtlas); + } - m_atlas = atlas; + Font::~Font() + { + OnFontRelease(this); + + Destroy(); + SetAtlas(nullptr); // On libère l'atlas proprement + } + + void Font::ClearGlyphCache() + { if (m_atlas) { - m_atlasClearedSlot.Connect(m_atlas->OnAtlasCleared, this, &NzFont::OnAtlasCleared); - m_atlasLayerChangeSlot.Connect(m_atlas->OnAtlasLayerChange, this, &NzFont::OnAtlasLayerChange); - m_atlasReleaseSlot.Connect(m_atlas->OnAtlasRelease, this, &NzFont::OnAtlasRelease); + if (m_atlas.unique()) + m_atlas->Clear(); // Appellera OnAtlasCleared + else + { + // Au moins une autre police utilise cet atlas, on vire nos glyphes un par un + for (auto mapIt = m_glyphes.begin(); mapIt != m_glyphes.end(); ++mapIt) + { + GlyphMap& glyphMap = mapIt->second; + for (auto glyphIt = glyphMap.begin(); glyphIt != glyphMap.end(); ++glyphIt) + { + Glyph& glyph = glyphIt->second; + m_atlas->Free(&glyph.atlasRect, &glyph.layerIndex, 1); + } + } + + // Destruction des glyphes mémorisés et notification + m_glyphes.clear(); + + OnFontGlyphCacheCleared(this); + } + } + } + + void Font::ClearKerningCache() + { + m_kerningCache.clear(); + + OnFontKerningCacheCleared(this); + } + + void Font::ClearSizeInfoCache() + { + m_sizeInfoCache.clear(); + + OnFontSizeInfoCacheCleared(this); + } + + bool Font::Create(FontData* data) + { + Destroy(); + + #if NAZARA_UTILITY_SAFE + if (!data) + { + NazaraError("Invalid font data"); + return false; + } + #endif + + m_data.reset(data); + return true; + } + + void Font::Destroy() + { + if (m_data) + { + OnFontDestroy(this); + + ClearGlyphCache(); + + m_data.reset(); + m_kerningCache.clear(); + m_sizeInfoCache.clear(); + } + } + + bool Font::ExtractGlyph(unsigned int characterSize, char32_t character, UInt32 style, FontGlyph* glyph) const + { + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Invalid font"); + return false; + } + #endif + + return m_data->ExtractGlyph(characterSize, character, style, glyph); + } + + const std::shared_ptr& Font::GetAtlas() const + { + return m_atlas; + } + + unsigned int Font::GetCachedGlyphCount(unsigned int characterSize, UInt32 style) const + { + UInt64 key = ComputeKey(characterSize, style); + auto it = m_glyphes.find(key); + if (it == m_glyphes.end()) + return 0; + + return it->second.size(); + } + + unsigned int Font::GetCachedGlyphCount() const + { + unsigned int count = 0; + for (auto& pair : m_glyphes) + count += pair.second.size(); + + return count; + } + + String Font::GetFamilyName() const + { + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Invalid font"); + return String("Invalid font"); + } + #endif + + return m_data->GetFamilyName(); + } + + int Font::GetKerning(unsigned int characterSize, char32_t first, char32_t second) const + { + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Invalid font"); + return 0; + } + #endif + + // On utilise un cache car la méthode interne QueryKerning peut se révéler coûteuse (car pouvant induire un changement de taille) + auto& map = m_kerningCache[characterSize]; + + UInt64 key = (static_cast(first) << 32) | second; // Combinaison de deux caractères 32 bits dans un nombre 64 bits + + auto it = map.find(key); + if (it == map.end()) + { + // Absent du cache: on va demander l'information à la police + int kerning = m_data->QueryKerning(characterSize, first, second); + map.insert(std::make_pair(key, kerning)); + + return kerning; } else + return it->second; // Présent dans le cache, tout va bien + } + + const Font::Glyph& Font::GetGlyph(unsigned int characterSize, UInt32 style, char32_t character) const + { + UInt64 key = ComputeKey(characterSize, style); + return PrecacheGlyph(m_glyphes[key], characterSize, style, character); + } + + unsigned int Font::GetGlyphBorder() const + { + return m_glyphBorder; + } + + unsigned int Font::GetMinimumStepSize() const + { + return m_minimumStepSize; + } + + const Font::SizeInfo& Font::GetSizeInfo(unsigned int characterSize) const + { + #if NAZARA_UTILITY_SAFE + if (!IsValid()) { - m_atlasClearedSlot.Disconnect(); - m_atlasLayerChangeSlot.Disconnect(); - m_atlasReleaseSlot.Disconnect(); + NazaraError("Invalid font"); + + static SizeInfo dummy; + return dummy; + } + #endif + + auto it = m_sizeInfoCache.find(characterSize); + if (it == m_sizeInfoCache.end()) + { + SizeInfo sizeInfo; + sizeInfo.lineHeight = m_data->QueryLineHeight(characterSize); + sizeInfo.underlinePosition = m_data->QueryUnderlinePosition(characterSize); + sizeInfo.underlineThickness = m_data->QueryUnderlineThickness(characterSize); + + FontGlyph glyph; + if (m_data->ExtractGlyph(characterSize, ' ', TextStyle_Regular, &glyph)) + sizeInfo.spaceAdvance = glyph.advance; + else + { + NazaraWarning("Failed to extract space character from font, using half the size"); + sizeInfo.spaceAdvance = characterSize/2; + } + + it = m_sizeInfoCache.insert(std::make_pair(characterSize, sizeInfo)).first; } - OnFontAtlasChanged(this); + return it->second; } -} -void NzFont::SetGlyphBorder(unsigned int borderSize) -{ - if (m_glyphBorder != borderSize) + String Font::GetStyleName() const { - m_glyphBorder = borderSize; - ClearGlyphCache(); - } -} + #if NAZARA_UTILITY_SAFE + if (!IsValid()) + { + NazaraError("Invalid font"); + return String("Invalid font"); + } + #endif -void NzFont::SetMinimumStepSize(unsigned int minimumStepSize) -{ - if (m_minimumStepSize != minimumStepSize) + return m_data->GetStyleName(); + } + + bool Font::IsValid() const + { + return m_data != nullptr; + } + + bool Font::Precache(unsigned int characterSize, UInt32 style, char32_t character) const + { + UInt64 key = ComputeKey(characterSize, style); + return PrecacheGlyph(m_glyphes[key], characterSize, style, character).valid; + } + + bool Font::Precache(unsigned int characterSize, UInt32 style, const String& characterSet) const + { + ///TODO: Itération UTF-8 => UTF-32 sans allocation de buffer (Exposer utf8cpp ?) + std::u32string set = characterSet.GetUtf32String(); + if (set.empty()) + { + NazaraError("Invalid character set"); + return false; + } + + UInt64 key = ComputeKey(characterSize, style); + auto& glyphMap = m_glyphes[key]; + for (char32_t character : set) + PrecacheGlyph(glyphMap, characterSize, style, character); + + return true; + } + + bool Font::OpenFromFile(const String& filePath, const FontParams& params) + { + return FontLoader::LoadFromFile(this, filePath, params); + } + + bool Font::OpenFromMemory(const void* data, std::size_t size, const FontParams& params) + { + return FontLoader::LoadFromMemory(this, data, size, params); + } + + bool Font::OpenFromStream(InputStream& stream, const FontParams& params) + { + return FontLoader::LoadFromStream(this, stream, params); + } + + void Font::SetAtlas(const std::shared_ptr& atlas) + { + if (m_atlas != atlas) + { + ClearGlyphCache(); + + m_atlas = atlas; + if (m_atlas) + { + m_atlasClearedSlot.Connect(m_atlas->OnAtlasCleared, this, &Font::OnAtlasCleared); + m_atlasLayerChangeSlot.Connect(m_atlas->OnAtlasLayerChange, this, &Font::OnAtlasLayerChange); + m_atlasReleaseSlot.Connect(m_atlas->OnAtlasRelease, this, &Font::OnAtlasRelease); + } + else + { + m_atlasClearedSlot.Disconnect(); + m_atlasLayerChangeSlot.Disconnect(); + m_atlasReleaseSlot.Disconnect(); + } + + OnFontAtlasChanged(this); + } + } + + void Font::SetGlyphBorder(unsigned int borderSize) + { + if (m_glyphBorder != borderSize) + { + m_glyphBorder = borderSize; + ClearGlyphCache(); + } + } + + void Font::SetMinimumStepSize(unsigned int minimumStepSize) + { + if (m_minimumStepSize != minimumStepSize) + { + #if NAZARA_UTILITY_SAFE + if (minimumStepSize == 0) + { + NazaraError("Minimum step size cannot be zero as it implies division by zero"); + return; + } + #endif + + m_minimumStepSize = minimumStepSize; + ClearGlyphCache(); + } + } + + std::shared_ptr Font::GetDefaultAtlas() + { + return s_defaultAtlas; + } + + Font* Font::GetDefault() + { + // Nous n'initialisons la police par défaut qu'à la demande pour qu'elle prenne + // les paramètres par défaut (qui peuvent avoir étés changés par l'utilisateur), + // et pour ne pas consommer de la mémoire vive inutilement (si elle n'est jamais utilisée, elle n'est jamais ouverte). + + if (!s_defaultFont) + { + FontRef cabin = Font::New(); + if (!cabin->OpenFromMemory(r_cabinRegular, sizeof(r_cabinRegular))) + { + NazaraError("Failed to open default font"); + return nullptr; + } + + s_defaultFont = cabin; + } + + return s_defaultFont; + } + + unsigned int Font::GetDefaultGlyphBorder() + { + return s_defaultGlyphBorder; + } + + unsigned int Font::GetDefaultMinimumStepSize() + { + return s_defaultMinimumStepSize; + } + + void Font::SetDefaultAtlas(const std::shared_ptr& atlas) + { + s_defaultAtlas = atlas; + } + + void Font::SetDefaultGlyphBorder(unsigned int borderSize) + { + s_defaultGlyphBorder = borderSize; + } + + void Font::SetDefaultMinimumStepSize(unsigned int minimumStepSize) { #if NAZARA_UTILITY_SAFE if (minimumStepSize == 0) @@ -338,261 +401,201 @@ void NzFont::SetMinimumStepSize(unsigned int minimumStepSize) } #endif - m_minimumStepSize = minimumStepSize; - ClearGlyphCache(); + s_defaultMinimumStepSize = minimumStepSize; } -} -std::shared_ptr NzFont::GetDefaultAtlas() -{ - return s_defaultAtlas; -} - -NzFont* NzFont::GetDefault() -{ - // Nous n'initialisons la police par défaut qu'à la demande pour qu'elle prenne - // les paramètres par défaut (qui peuvent avoir étés changés par l'utilisateur), - // et pour ne pas consommer de la mémoire vive inutilement (si elle n'est jamais utilisée, elle n'est jamais ouverte). - - if (!s_defaultFont) + UInt64 Font::ComputeKey(unsigned int characterSize, UInt32 style) const { - NzFontRef cabin = NzFont::New(); - if (!cabin->OpenFromMemory(r_cabinRegular, sizeof(r_cabinRegular))) + // On prend le pas en compte + UInt64 sizePart = static_cast((characterSize/m_minimumStepSize)*m_minimumStepSize); + + // Ainsi que le style (uniquement le gras et l'italique, les autres sont gérés par un TextDrawer) + UInt64 stylePart = 0; + + if (style & TextStyle_Bold) + stylePart |= TextStyle_Bold; + + if (style & TextStyle_Italic) + stylePart |= TextStyle_Italic; + + return (stylePart << 32) | sizePart; + } + + void Font::OnAtlasCleared(const AbstractAtlas* atlas) + { + NazaraUnused(atlas); + + #ifdef NAZARA_DEBUG + // Est-ce qu'il s'agit bien de notre atlas ? + if (m_atlas.get() != atlas) { - NazaraError("Failed to open default font"); - return nullptr; + NazaraInternalError("Notified by a non-listening-to resource"); + return; + } + #endif + + // Notre atlas vient d'être vidé, détruisons le cache de glyphe + m_glyphes.clear(); + + OnFontGlyphCacheCleared(this); + } + + void Font::OnAtlasLayerChange(const AbstractAtlas* atlas, AbstractImage* oldLayer, AbstractImage* newLayer) + { + NazaraUnused(atlas); + NazaraUnused(oldLayer); + NazaraUnused(newLayer); + + #ifdef NAZARA_DEBUG + // Est-ce qu'il s'agit bien de notre atlas ? + if (m_atlas.get() != atlas) + { + NazaraInternalError("Notified by a non-listening-to resource"); + return; + } + #endif + + // Pour faciliter le travail des ressources qui nous écoutent + OnFontAtlasLayerChanged(this, oldLayer, newLayer); + } + + void Font::OnAtlasRelease(const AbstractAtlas* atlas) + { + NazaraUnused(atlas); + + #ifdef NAZARA_DEBUG + // Est-ce qu'il s'agit bien de notre atlas ? + if (m_atlas.get() != atlas) + { + NazaraInternalError("Notified by a non-listening-to resource"); + return; + } + #endif + + // Nous ne pouvons pas faire grand chose d'autre que de balancer une erreur à la tête de l'utilisateur avant un potentiel crash... + NazaraError("Atlas has been released while in use"); + } + + const Font::Glyph& Font::PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, UInt32 style, char32_t character) const + { + auto it = glyphMap.find(character); + if (it != glyphMap.end()) // Si le glyphe n'est pas déjà chargé + return it->second; + + Glyph& glyph = glyphMap[character]; // Insertion du glyphe + glyph.valid = false; + + #if NAZARA_UTILITY_SAFE + if (!m_atlas) + { + NazaraError("Font has no atlas"); + return glyph; + } + #endif + + // On vérifie que le style demandé est supporté par la police (dans le cas contraire il devra être simulé au rendu) + glyph.requireFauxBold = false; + glyph.requireFauxItalic = false; + + UInt32 supportedStyle = style; + if (style & TextStyle_Bold && !m_data->SupportsStyle(TextStyle_Bold)) + { + glyph.requireFauxBold = true; + supportedStyle &= ~TextStyle_Bold; } - s_defaultFont = cabin; - } - - return s_defaultFont; -} - -unsigned int NzFont::GetDefaultGlyphBorder() -{ - return s_defaultGlyphBorder; -} - -unsigned int NzFont::GetDefaultMinimumStepSize() -{ - return s_defaultMinimumStepSize; -} - -void NzFont::SetDefaultAtlas(const std::shared_ptr& atlas) -{ - s_defaultAtlas = atlas; -} - -void NzFont::SetDefaultGlyphBorder(unsigned int borderSize) -{ - s_defaultGlyphBorder = borderSize; -} - -void NzFont::SetDefaultMinimumStepSize(unsigned int minimumStepSize) -{ - #if NAZARA_UTILITY_SAFE - if (minimumStepSize == 0) - { - NazaraError("Minimum step size cannot be zero as it implies division by zero"); - return; - } - #endif - - s_defaultMinimumStepSize = minimumStepSize; -} - -nzUInt64 NzFont::ComputeKey(unsigned int characterSize, nzUInt32 style) const -{ - // On prend le pas en compte - nzUInt64 sizePart = static_cast((characterSize/m_minimumStepSize)*m_minimumStepSize); - - // Ainsi que le style (uniquement le gras et l'italique, les autres sont gérés par un TextDrawer) - nzUInt64 stylePart = 0; - - if (style & nzTextStyle_Bold) - stylePart |= nzTextStyle_Bold; - - if (style & nzTextStyle_Italic) - stylePart |= nzTextStyle_Italic; - - return (stylePart << 32) | sizePart; -} - -void NzFont::OnAtlasCleared(const NzAbstractAtlas* atlas) -{ - NazaraUnused(atlas); - - #ifdef NAZARA_DEBUG - // Est-ce qu'il s'agit bien de notre atlas ? - if (m_atlas.get() != atlas) - { - NazaraInternalError("Notified by a non-listening-to resource"); - return; - } - #endif - - // Notre atlas vient d'être vidé, détruisons le cache de glyphe - m_glyphes.clear(); - - OnFontGlyphCacheCleared(this); -} - -void NzFont::OnAtlasLayerChange(const NzAbstractAtlas* atlas, NzAbstractImage* oldLayer, NzAbstractImage* newLayer) -{ - NazaraUnused(atlas); - NazaraUnused(oldLayer); - NazaraUnused(newLayer); - - #ifdef NAZARA_DEBUG - // Est-ce qu'il s'agit bien de notre atlas ? - if (m_atlas.get() != atlas) - { - NazaraInternalError("Notified by a non-listening-to resource"); - return; - } - #endif - - // Pour faciliter le travail des ressources qui nous écoutent - OnFontAtlasLayerChanged(this, oldLayer, newLayer); -} - -void NzFont::OnAtlasRelease(const NzAbstractAtlas* atlas) -{ - NazaraUnused(atlas); - - #ifdef NAZARA_DEBUG - // Est-ce qu'il s'agit bien de notre atlas ? - if (m_atlas.get() != atlas) - { - NazaraInternalError("Notified by a non-listening-to resource"); - return; - } - #endif - - // Nous ne pouvons pas faire grand chose d'autre que de balancer une erreur à la tête de l'utilisateur avant un potentiel crash... - NazaraError("Atlas has been released while in use"); -} - -const NzFont::Glyph& NzFont::PrecacheGlyph(GlyphMap& glyphMap, unsigned int characterSize, nzUInt32 style, char32_t character) const -{ - auto it = glyphMap.find(character); - if (it != glyphMap.end()) // Si le glyphe n'est pas déjà chargé - return it->second; - - Glyph& glyph = glyphMap[character]; // Insertion du glyphe - glyph.valid = false; - - #if NAZARA_UTILITY_SAFE - if (!m_atlas) - { - NazaraError("Font has no atlas"); - return glyph; - } - #endif - - // On vérifie que le style demandé est supporté par la police (dans le cas contraire il devra être simulé au rendu) - glyph.requireFauxBold = false; - glyph.requireFauxItalic = false; - - nzUInt32 supportedStyle = style; - if (style & nzTextStyle_Bold && !m_data->SupportsStyle(nzTextStyle_Bold)) - { - glyph.requireFauxBold = true; - supportedStyle &= ~nzTextStyle_Bold; - } - - if (style & nzTextStyle_Italic && !m_data->SupportsStyle(nzTextStyle_Italic)) - { - glyph.requireFauxItalic = true; - supportedStyle &= ~nzTextStyle_Italic; - } - - // Est-ce que la police supporte le style demandé ? - if (style == supportedStyle) - { - // On extrait le glyphe depuis la police - NzFontGlyph fontGlyph; - if (ExtractGlyph(characterSize, character, style, &fontGlyph)) + if (style & TextStyle_Italic && !m_data->SupportsStyle(TextStyle_Italic)) { - glyph.atlasRect.width = fontGlyph.image.GetWidth(); - glyph.atlasRect.height = fontGlyph.image.GetHeight(); + glyph.requireFauxItalic = true; + supportedStyle &= ~TextStyle_Italic; + } - // Insertion du rectangle dans l'un des atlas - if (glyph.atlasRect.width > 0 && glyph.atlasRect.height > 0) // Si l'image contient quelque chose + // Est-ce que la police supporte le style demandé ? + if (style == supportedStyle) + { + // On extrait le glyphe depuis la police + FontGlyph fontGlyph; + if (ExtractGlyph(characterSize, character, style, &fontGlyph)) { - // Bordure (pour éviter le débordement lors du filtrage) - glyph.atlasRect.width += m_glyphBorder*2; - glyph.atlasRect.height += m_glyphBorder*2; + glyph.atlasRect.width = fontGlyph.image.GetWidth(); + glyph.atlasRect.height = fontGlyph.image.GetHeight(); - // Insertion du rectangle dans l'atlas virtuel - if (!m_atlas->Insert(fontGlyph.image, &glyph.atlasRect, &glyph.flipped, &glyph.layerIndex)) + // Insertion du rectangle dans l'un des atlas + if (glyph.atlasRect.width > 0 && glyph.atlasRect.height > 0) // Si l'image contient quelque chose { - NazaraError("Failed to insert glyph into atlas"); - return glyph; + // Bordure (pour éviter le débordement lors du filtrage) + glyph.atlasRect.width += m_glyphBorder*2; + glyph.atlasRect.height += m_glyphBorder*2; + + // Insertion du rectangle dans l'atlas virtuel + if (!m_atlas->Insert(fontGlyph.image, &glyph.atlasRect, &glyph.flipped, &glyph.layerIndex)) + { + NazaraError("Failed to insert glyph into atlas"); + return glyph; + } + + // Compensation de la bordure (centrage du glyphe) + glyph.atlasRect.x += m_glyphBorder; + glyph.atlasRect.y += m_glyphBorder; + glyph.atlasRect.width -= m_glyphBorder*2; + glyph.atlasRect.height -= m_glyphBorder*2; } - // Compensation de la bordure (centrage du glyphe) - glyph.atlasRect.x += m_glyphBorder; - glyph.atlasRect.y += m_glyphBorder; - glyph.atlasRect.width -= m_glyphBorder*2; - glyph.atlasRect.height -= m_glyphBorder*2; + glyph.aabb = fontGlyph.aabb; + glyph.advance = fontGlyph.advance; + glyph.valid = true; + } + else + { + NazaraWarning("Failed to extract glyph \"" + String::Unicode(character) + "\""); } - - glyph.aabb = fontGlyph.aabb; - glyph.advance = fontGlyph.advance; - glyph.valid = true; } else { - NazaraWarning("Failed to extract glyph \"" + NzString::Unicode(character) + "\""); + // La police ne supporte pas le style demandé, nous allons donc précharger le glyphe supportant le style "minimum" supporté + // et copier ses données + UInt64 newKey = ComputeKey(characterSize, supportedStyle); + const Glyph& referenceGlyph = PrecacheGlyph(m_glyphes[newKey], characterSize, supportedStyle, character); + if (referenceGlyph.valid) + { + glyph.aabb = referenceGlyph.aabb; + glyph.advance = referenceGlyph.advance; + glyph.atlasRect = referenceGlyph.atlasRect; + glyph.flipped = referenceGlyph.flipped; + glyph.layerIndex = referenceGlyph.layerIndex; + glyph.valid = true; + } } + + return glyph; } - else + + bool Font::Initialize() { - // La police ne supporte pas le style demandé, nous allons donc précharger le glyphe supportant le style "minimum" supporté - // et copier ses données - nzUInt64 newKey = ComputeKey(characterSize, supportedStyle); - const Glyph& referenceGlyph = PrecacheGlyph(m_glyphes[newKey], characterSize, supportedStyle, character); - if (referenceGlyph.valid) + if (!FontLibrary::Initialize()) { - glyph.aabb = referenceGlyph.aabb; - glyph.advance = referenceGlyph.advance; - glyph.atlasRect = referenceGlyph.atlasRect; - glyph.flipped = referenceGlyph.flipped; - glyph.layerIndex = referenceGlyph.layerIndex; - glyph.valid = true; + NazaraError("Failed to initialise library"); + return false; } + + s_defaultAtlas.reset(new GuillotineImageAtlas); + s_defaultGlyphBorder = 1; + s_defaultMinimumStepSize = 1; + + return true; } - return glyph; -} - -bool NzFont::Initialize() -{ - if (!NzFontLibrary::Initialize()) + void Font::Uninitialize() { - NazaraError("Failed to initialise library"); - return false; + s_defaultAtlas.reset(); + s_defaultFont.Reset(); + FontLibrary::Uninitialize(); } - s_defaultAtlas.reset(new NzGuillotineImageAtlas); - s_defaultGlyphBorder = 1; - s_defaultMinimumStepSize = 1; - - return true; + std::shared_ptr Font::s_defaultAtlas; + FontRef Font::s_defaultFont; + FontLibrary::LibraryMap Font::s_library; + FontLoader::LoaderList Font::s_loaders; + unsigned int Font::s_defaultGlyphBorder; +unsigned int Font::s_defaultMinimumStepSize; } - -void NzFont::Uninitialize() -{ - s_defaultAtlas.reset(); - s_defaultFont.Reset(); - NzFontLibrary::Uninitialize(); -} - -std::shared_ptr NzFont::s_defaultAtlas; -NzFontRef NzFont::s_defaultFont; -NzFontLibrary::LibraryMap NzFont::s_library; -NzFontLoader::LoaderList NzFont::s_loaders; -unsigned int NzFont::s_defaultGlyphBorder; -unsigned int NzFont::s_defaultMinimumStepSize; diff --git a/src/Nazara/Utility/FontData.cpp b/src/Nazara/Utility/FontData.cpp index 8a9f9d5b5..b9be6b8e7 100644 --- a/src/Nazara/Utility/FontData.cpp +++ b/src/Nazara/Utility/FontData.cpp @@ -5,4 +5,7 @@ #include #include -NzFontData::~NzFontData() = default; +namespace Nz +{ + FontData::~FontData() = default; +} diff --git a/src/Nazara/Utility/Formats/DDSConstants.hpp b/src/Nazara/Utility/Formats/DDSConstants.hpp index 4c1bd28ce..78b9416a5 100644 --- a/src/Nazara/Utility/Formats/DDSConstants.hpp +++ b/src/Nazara/Utility/Formats/DDSConstants.hpp @@ -7,12 +7,14 @@ #ifndef NAZARA_LOADERS_DDS_CONSTANTS_HPP #define NAZARA_LOADERS_DDS_CONSTANTS_HPP +#include + #define DDS_MAGIC 0x20534444 #define DDS_DXT1 0x31545844 #define DDS_DXT3 0x33545844 #define DDS_DXT5 0x35545844 -inline constexpr nzUInt32 FourCC(nzUInt32 a, nzUInt32 b, nzUInt32 c, nzUInt32 d) +inline constexpr Nz::UInt32 FourCC(Nz::UInt32 a, Nz::UInt32 b, Nz::UInt32 c, Nz::UInt32 d) { return a << 0 | b << 8 | @@ -20,7 +22,7 @@ inline constexpr nzUInt32 FourCC(nzUInt32 a, nzUInt32 b, nzUInt32 c, nzUInt32 d) d << 24; } -enum D3D10_RESOURCE_DIMENSION : nzUInt32 +enum D3D10_RESOURCE_DIMENSION : Nz::UInt32 { D3D10_RESOURCE_DIMENSION_UNKNOWN = 0, D3D10_RESOURCE_DIMENSION_BUFFER = 1, @@ -38,7 +40,7 @@ enum D3D10_RESOURCE_MISC D3D10_RESOURCE_MISC_GDI_COMPATIBLE = 0x20L }; -enum D3DFMT : nzUInt32 +enum D3DFMT : Nz::UInt32 { D3DFMT_UNKNOWN = 0, @@ -222,7 +224,7 @@ enum DDS_SAVE DDS_SAVE_MAX }; -enum DXGI_FORMAT : nzUInt32 +enum DXGI_FORMAT : Nz::UInt32 { DXGI_FORMAT_UNKNOWN = 0, DXGI_FORMAT_R32G32B32A32_TYPELESS = 1, @@ -328,47 +330,47 @@ enum DXGI_FORMAT : nzUInt32 struct DDSPixelFormat // DDPIXELFORMAT { - nzUInt32 size; - nzUInt32 flags; - nzUInt32 fourCC; - nzUInt32 bpp; - nzUInt32 redMask; - nzUInt32 greenMask; - nzUInt32 blueMask; - nzUInt32 alphaMask; + Nz::UInt32 size; + Nz::UInt32 flags; + Nz::UInt32 fourCC; + Nz::UInt32 bpp; + Nz::UInt32 redMask; + Nz::UInt32 greenMask; + Nz::UInt32 blueMask; + Nz::UInt32 alphaMask; }; -static_assert(sizeof(DDSPixelFormat) == 8*sizeof(nzUInt32), "DDSPixelFormat must be packed"); +static_assert(sizeof(DDSPixelFormat) == 8*sizeof(Nz::UInt32), "DDSPixelFormat must be packed"); struct DDSHeader { - nzUInt32 size; - nzUInt32 flags; - nzUInt32 height; - nzUInt32 width; - nzUInt32 pitch; - nzUInt32 depth; - nzUInt32 levelCount; - nzUInt32 reserved1[11]; + Nz::UInt32 size; + Nz::UInt32 flags; + Nz::UInt32 height; + Nz::UInt32 width; + Nz::UInt32 pitch; + Nz::UInt32 depth; + Nz::UInt32 levelCount; + Nz::UInt32 reserved1[11]; DDSPixelFormat format; - nzUInt32 ddsCaps1; - nzUInt32 ddsCaps2; - nzUInt32 ddsCaps3; - nzUInt32 ddsCaps4; - nzUInt32 reserved2; + Nz::UInt32 ddsCaps1; + Nz::UInt32 ddsCaps2; + Nz::UInt32 ddsCaps3; + Nz::UInt32 ddsCaps4; + Nz::UInt32 reserved2; }; -static_assert(sizeof(DDSHeader) == 23*sizeof(nzUInt32) + sizeof(DDSPixelFormat), "DDSHeader must be packed"); +static_assert(sizeof(DDSHeader) == 23*sizeof(Nz::UInt32) + sizeof(DDSPixelFormat), "DDSHeader must be packed"); struct DDSHeaderDX10Ext { DXGI_FORMAT dxgiFormat; D3D10_RESOURCE_DIMENSION resourceDimension; - nzUInt32 miscFlag; - nzUInt32 arraySize; - nzUInt32 reserved; + Nz::UInt32 miscFlag; + Nz::UInt32 arraySize; + Nz::UInt32 reserved; }; -static_assert(sizeof(DDSHeaderDX10Ext) == 5*sizeof(nzUInt32), "DDSHeaderDX10Ext must be packed"); +static_assert(sizeof(DDSHeaderDX10Ext) == 5*sizeof(Nz::UInt32), "DDSHeaderDX10Ext must be packed"); #endif // NAZARA_LOADERS_DDS_CONSTANTS_HPP diff --git a/src/Nazara/Utility/Formats/DDSLoader.cpp b/src/Nazara/Utility/Formats/DDSLoader.cpp index 196f94ae6..e51dc15b6 100644 --- a/src/Nazara/Utility/Formats/DDSLoader.cpp +++ b/src/Nazara/Utility/Formats/DDSLoader.cpp @@ -11,113 +11,119 @@ #include #include -namespace +namespace Nz { - bool IsSupported(const NzString& extension) + namespace { - return (extension == "dds"); - } - - nzTernary Check(NzInputStream& stream, const NzImageParams& parameters) - { - NazaraUnused(parameters); - - nzUInt32 magic; - if (stream.Read(&magic, sizeof(nzUInt32)) == sizeof(nzUInt32)) + bool IsSupported(const String& extension) { - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&magic, sizeof(nzUInt32)); - #endif - - if (magic == DDS_MAGIC) - return nzTernary_True; + return (extension == "dds"); } - return nzTernary_False; - } - - bool Load(NzImage* image, NzInputStream& stream, const NzImageParams& parameters) - { - NazaraUnused(parameters); - - DDSHeader header; - if (stream.Read(&header, sizeof(DDSHeader)) != sizeof(DDSHeader)) + Ternary Check(InputStream& stream, const ImageParams& parameters) { - NazaraError("Failed to read DDS header"); - return false; - } + NazaraUnused(parameters); - DDSHeaderDX10Ext headerDX10; - if (header.format.flags & DDPF_FOURCC && header.format.fourCC == D3DFMT_DX10) - { - if (stream.Read(&headerDX10, sizeof(DDSHeaderDX10Ext)) != sizeof(DDSHeaderDX10Ext)) + UInt32 magic; + if (stream.Read(&magic, sizeof(UInt32)) == sizeof(UInt32)) { - NazaraError("Failed to read DDS DX10 extension header"); + #ifdef NAZARA_BIG_ENDIAN + NzByteSwap(&magic, sizeof(UInt32)); + #endif + + if (magic == DDS_MAGIC) + return Ternary_True; + } + + return Ternary_False; + } + + bool Load(Image* image, InputStream& stream, const ImageParams& parameters) + { + NazaraUnused(parameters); + + DDSHeader header; + if (stream.Read(&header, sizeof(DDSHeader)) != sizeof(DDSHeader)) + { + NazaraError("Failed to read DDS header"); return false; } + + DDSHeaderDX10Ext headerDX10; + if (header.format.flags & DDPF_FOURCC && header.format.fourCC == D3DFMT_DX10) + { + if (stream.Read(&headerDX10, sizeof(DDSHeaderDX10Ext)) != sizeof(DDSHeaderDX10Ext)) + { + NazaraError("Failed to read DDS DX10 extension header"); + return false; + } + } + else + { + headerDX10.arraySize = 1; + headerDX10.dxgiFormat = DXGI_FORMAT_UNKNOWN; + headerDX10.miscFlag = 0; + headerDX10.resourceDimension = D3D10_RESOURCE_DIMENSION_UNKNOWN; + } + + #ifdef NAZARA_BIG_ENDIAN + // Les fichiers DDS sont en little endian + NzByteSwap(&header.size, sizeof(UInt32)); + NzByteSwap(&header.flags, sizeof(UInt32)); + NzByteSwap(&header.height, sizeof(UInt32)); + NzByteSwap(&header.width, sizeof(UInt32)); + NzByteSwap(&header.pitch, sizeof(UInt32)); + NzByteSwap(&header.depth, sizeof(UInt32)); + NzByteSwap(&header.levelCount, sizeof(UInt32)); + + // DDS_PixelFormat + NzByteSwap(&header.format.size, sizeof(UInt32)); + NzByteSwap(&header.format.flags, sizeof(UInt32)); + NzByteSwap(&header.format.fourCC, sizeof(UInt32)); + NzByteSwap(&header.format.bpp, sizeof(UInt32)); + NzByteSwap(&header.format.redMask, sizeof(UInt32)); + NzByteSwap(&header.format.greenMask, sizeof(UInt32)); + NzByteSwap(&header.format.blueMask, sizeof(UInt32)); + NzByteSwap(&header.format.alphaMask, sizeof(UInt32)); + + NzByteSwap(&header.ddsCaps1, sizeof(UInt32)); + NzByteSwap(&header.ddsCaps2, sizeof(UInt32)); + NzByteSwap(&header.ddsCaps3, sizeof(UInt32)); + NzByteSwap(&header.ddsCaps4, sizeof(UInt32)); + #endif + + unsigned int width = header.width; + unsigned int height = header.height; + unsigned int depth = std::max(header.depth, 1U); + unsigned int levelCount = (parameters.levelCount > 0) ? std::min(parameters.levelCount, static_cast(header.levelCount)) : header.levelCount; + + // Détermination du type + ImageType type; + if (header.ddsCaps2 & DDSCAPS2_CUBEMAP) + type = ImageType_Cubemap; + else if (header.ddsCaps2 & DDSCAPS2_VOLUME) + type = ImageType_3D; + + // Détermination du format + PixelFormatType format; + + if (parameters.loadFormat != PixelFormatType_Undefined) + image->Convert(parameters.loadFormat); + + return true; } - else + } + + namespace Loaders + { + void RegisterDDS() { - headerDX10.arraySize = 1; - headerDX10.dxgiFormat = DXGI_FORMAT_UNKNOWN; - headerDX10.miscFlag = 0; - headerDX10.resourceDimension = D3D10_RESOURCE_DIMENSION_UNKNOWN; + ImageLoader::RegisterLoader(IsSupported, Check, Load); } - #ifdef NAZARA_BIG_ENDIAN - // Les fichiers DDS sont en little endian - NzByteSwap(&header.size, sizeof(nzUInt32)); - NzByteSwap(&header.flags, sizeof(nzUInt32)); - NzByteSwap(&header.height, sizeof(nzUInt32)); - NzByteSwap(&header.width, sizeof(nzUInt32)); - NzByteSwap(&header.pitch, sizeof(nzUInt32)); - NzByteSwap(&header.depth, sizeof(nzUInt32)); - NzByteSwap(&header.levelCount, sizeof(nzUInt32)); - - // DDS_PixelFormat - NzByteSwap(&header.format.size, sizeof(nzUInt32)); - NzByteSwap(&header.format.flags, sizeof(nzUInt32)); - NzByteSwap(&header.format.fourCC, sizeof(nzUInt32)); - NzByteSwap(&header.format.bpp, sizeof(nzUInt32)); - NzByteSwap(&header.format.redMask, sizeof(nzUInt32)); - NzByteSwap(&header.format.greenMask, sizeof(nzUInt32)); - NzByteSwap(&header.format.blueMask, sizeof(nzUInt32)); - NzByteSwap(&header.format.alphaMask, sizeof(nzUInt32)); - - NzByteSwap(&header.ddsCaps1, sizeof(nzUInt32)); - NzByteSwap(&header.ddsCaps2, sizeof(nzUInt32)); - NzByteSwap(&header.ddsCaps3, sizeof(nzUInt32)); - NzByteSwap(&header.ddsCaps4, sizeof(nzUInt32)); - #endif - - unsigned int width = header.width; - unsigned int height = header.height; - unsigned int depth = std::max(header.depth, 1U); - unsigned int levelCount = (parameters.levelCount > 0) ? std::min(parameters.levelCount, static_cast(header.levelCount)) : header.levelCount; - - // Détermination du type - nzImageType type; - if (header.ddsCaps2 & DDSCAPS2_CUBEMAP) - type = nzImageType_Cubemap; - else if (header.ddsCaps2 & DDSCAPS2_VOLUME) - type = nzImageType_3D; - - // Détermination du format - nzPixelFormat format; - - if (parameters.loadFormat != nzPixelFormat_Undefined) - image->Convert(parameters.loadFormat); - - return true; + void UnregisterDDS() + { + ImageLoader::UnregisterLoader(IsSupported, Check, Load); + } } } - -void NzLoaders_DDS_Register() -{ - NzImageLoader::RegisterLoader(IsSupported, Check, Load); -} - -void NzLoaders_DDS_Unregister() -{ - NzImageLoader::UnregisterLoader(IsSupported, Check, Load); -} diff --git a/src/Nazara/Utility/Formats/DDSLoader.hpp b/src/Nazara/Utility/Formats/DDSLoader.hpp index 9986e2a34..14ee2a01a 100644 --- a/src/Nazara/Utility/Formats/DDSLoader.hpp +++ b/src/Nazara/Utility/Formats/DDSLoader.hpp @@ -9,7 +9,13 @@ #include -void NzLoaders_DDS_Register(); -void NzLoaders_DDS_Unregister(); +namespace Nz +{ + namespace Loaders + { + void RegisterDDS(); + void UnregisterDDS(); + } +} #endif // NAZARA_LOADERS_DDS_HPP diff --git a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp index af1e619ae..23cdc58be 100644 --- a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp +++ b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp @@ -17,437 +17,443 @@ #include #include -namespace +namespace Nz { - class FreeTypeLibrary; - - FT_Library s_library; - std::shared_ptr s_libraryOwner; - float s_invScaleFactor = 1.f / (1 << 6); // 1/64 - - extern "C" - unsigned long FT_StreamRead(FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count) + namespace { - // http://www.freetype.org/freetype2/docs/reference/ft2-system_interface.html#FT_Stream_IoFunc - NzInputStream& inputStream = *static_cast(stream->descriptor.pointer); + class FreeTypeLibrary; - // La valeur de count indique une opération de lecture ou de positionnement - if (count > 0) + FT_Library s_library; + std::shared_ptr s_libraryOwner; + float s_invScaleFactor = 1.f / (1 << 6); // 1/64 + + extern "C" + unsigned long FT_StreamRead(FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count) { - // Dans le premier cas, une erreur est symbolisée par un retour nul - if (inputStream.SetCursorPos(offset)) - return static_cast(inputStream.Read(buffer, count)); - else - return 0; - } - else - { - // Dans le second cas, une erreur est symbolisée par un retour non-nul - if (inputStream.SetCursorPos(offset)) - return 0; - else - return 42; // La réponse à la grande question - } - } + // http://www.freetype.org/freetype2/docs/reference/ft2-system_interface.html#FT_Stream_IoFunc + InputStream& inputStream = *static_cast(stream->descriptor.pointer); - extern "C" - void FT_StreamClose(FT_Stream stream) - { - // http://www.freetype.org/freetype2/docs/reference/ft2-system_interface.html#FT_Stream_CloseFunc - // Les streams dans Nazara ne se ferment pas explicitement - NazaraUnused(stream); - } - - class FreeTypeLibrary - { - // Cette classe ne sert qu'à être utilisée avec un std::shared_ptr - // pour ne libérer FreeType que lorsque plus personne ne l'utilise - - public: - FreeTypeLibrary() = default; - ~FreeTypeLibrary() + // La valeur de count indique une opération de lecture ou de positionnement + if (count > 0) { - FT_Done_FreeType(s_library); - s_library = nullptr; - } - }; - - class FreeTypeStream : public NzFontData - { - public: - FreeTypeStream() : - m_face(nullptr), - m_library(s_libraryOwner), - m_characterSize(0) - { - } - - ~FreeTypeStream() - { - if (m_face) - FT_Done_Face(m_face); - } - - bool Check() - { - // Test d'ouverture (http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Open_Face) - return FT_Open_Face(s_library, &m_args, -1, nullptr) == 0; - } - - bool ExtractGlyph(unsigned int characterSize, char32_t character, nzUInt32 style, NzFontGlyph* dst) override - { - #ifdef NAZARA_DEBUG - if (!dst) - { - NazaraError("Glyph destination cannot be null"); - return false; - } - #endif - - SetCharacterSize(characterSize); - - if (FT_Load_Char(m_face, character, FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_NORMAL) != 0) - { - NazaraError("Failed to load character"); - return false; - } - - FT_GlyphSlot& glyph = m_face->glyph; - - const FT_Pos boldStrength = 2 << 6; - - bool embolden = (style & nzTextStyle_Bold); - - dst->advance = (embolden) ? boldStrength >> 6 : 0; - - if (embolden && glyph->format == FT_GLYPH_FORMAT_OUTLINE) - { - // http://www.freetype.org/freetype2/docs/reference/ft2-outline_processing.html#FT_Outline_Embolden - FT_Outline_Embolden(&glyph->outline, boldStrength); - embolden = false; - } - - // http://www.freetype.org/freetype2/docs/reference/ft2-glyph_management.html#FT_Glyph_To_Bitmap - // Conversion du glyphe vers le format bitmap - // Cette fonction ne fait rien dans le cas où le glyphe est déjà un bitmap - if (FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL) != 0) - { - NazaraError("Failed to convert glyph to bitmap"); - return false; - } - - // Dans le cas où nous voulons des caractères gras mais que nous n'avons pas pu agir plus tôt - // nous demandons à FreeType d'agir directement sur le bitmap généré - if (embolden) - { - // http://www.freetype.org/freetype2/docs/reference/ft2-bitmap_handling.html#FT_Bitmap_Embolden - // "If you want to embolden the bitmap owned by a FT_GlyphSlot_Rec, you should call FT_GlyphSlot_Own_Bitmap on the slot first" - FT_GlyphSlot_Own_Bitmap(glyph); - FT_Bitmap_Embolden(s_library, &glyph->bitmap, boldStrength, boldStrength); - } - - dst->advance += glyph->metrics.horiAdvance >> 6; - dst->aabb.x = glyph->metrics.horiBearingX >> 6; - dst->aabb.y = -(glyph->metrics.horiBearingY >> 6); // Inversion du repère - dst->aabb.width = glyph->metrics.width >> 6; - dst->aabb.height = glyph->metrics.height >> 6; - - unsigned int width = glyph->bitmap.width; - unsigned int height = glyph->bitmap.rows; - - if (width > 0 && height > 0) - { - dst->image.Create(nzImageType_2D, nzPixelFormat_A8, width, height); - nzUInt8* pixels = dst->image.GetPixels(); - - const nzUInt8* data = glyph->bitmap.buffer; - - // Selon la documentation FreeType, le glyphe peut être encodé en format A8 (huit bits d'alpha par pixel) - // ou au format A1 (un bit d'alpha par pixel). - // Cependant dans un cas comme dans l'autre, il nous faut gérer le pitch (les données peuvent ne pas être contigues) - // ainsi que le padding dans le cas du format A1 (Chaque ligne prends un nombre fixe d'octets) - if (glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) - { - // Format A1 - for (unsigned int y = 0; y < height; ++y) - { - for (unsigned int x = 0; x < width; ++x) - *pixels++ = (data[x/8] & ((1 << (7 - x%8)) ? 255 : 0)); - - data += glyph->bitmap.pitch; - } - } - else - { - // Format A8 - if (glyph->bitmap.pitch == static_cast(width*sizeof(nzUInt8))) // Pouvons-nous copier directement ? - dst->image.Update(glyph->bitmap.buffer); - else - { - for (unsigned int y = 0; y < height; ++y) - { - std::memcpy(pixels, data, width*sizeof(nzUInt8)); - data += glyph->bitmap.pitch; - pixels += width*sizeof(nzUInt8); - } - } - } - } - else - dst->image.Destroy(); // On s'assure que l'image ne contient alors rien - - return true; - } - - NzString GetFamilyName() const override - { - return m_face->family_name; - } - - NzString GetStyleName() const override - { - return m_face->style_name; - } - - bool HasKerning() const override - { - return FT_HAS_KERNING(m_face) != 0; - } - - bool IsScalable() const override - { - return FT_IS_SCALABLE(m_face) != 0; - } - - bool Open() - { - return FT_Open_Face(s_library, &m_args, 0, &m_face) == 0; - } - - int QueryKerning(unsigned int characterSize, char32_t first, char32_t second) const override - { - if (FT_HAS_KERNING(m_face)) - { - SetCharacterSize(characterSize); - - FT_Vector kerning; - FT_Get_Kerning(m_face, FT_Get_Char_Index(m_face, first), FT_Get_Char_Index(m_face, second), FT_KERNING_DEFAULT, &kerning); - - if (!FT_IS_SCALABLE(m_face)) - return kerning.x; // Taille déjà précisée en pixels dans ce cas - - return kerning.x >> 6; - } + // Dans le premier cas, une erreur est symbolisée par un retour nul + if (inputStream.SetCursorPos(offset)) + return static_cast(inputStream.Read(buffer, count)); else return 0; } - - unsigned int QueryLineHeight(unsigned int characterSize) const override + else { - SetCharacterSize(characterSize); - - // http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Size_Metrics - return m_face->size->metrics.height >> 6; - } - - float QueryUnderlinePosition(unsigned int characterSize) const override - { - if (FT_IS_SCALABLE(m_face)) - { - SetCharacterSize(characterSize); - - // http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FaceRec - return static_cast(FT_MulFix(m_face->underline_position, m_face->size->metrics.y_scale)) * s_invScaleFactor; - } + // Dans le second cas, une erreur est symbolisée par un retour non-nul + if (inputStream.SetCursorPos(offset)) + return 0; else - return characterSize / 10.f; // Joker ? + return 42; // La réponse à la grande question } + } - float QueryUnderlineThickness(unsigned int characterSize) const override - { - if (FT_IS_SCALABLE(m_face)) + extern "C" + void FT_StreamClose(FT_Stream stream) + { + // http://www.freetype.org/freetype2/docs/reference/ft2-system_interface.html#FT_Stream_CloseFunc + // Les streams dans Nazara ne se ferment pas explicitement + NazaraUnused(stream); + } + + class FreeTypeLibrary + { + // Cette classe ne sert qu'à être utilisée avec un std::shared_ptr + // pour ne libérer FreeType que lorsque plus personne ne l'utilise + + public: + FreeTypeLibrary() = default; + ~FreeTypeLibrary() { - SetCharacterSize(characterSize); - - // http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FaceRec - return static_cast(FT_MulFix(m_face->underline_thickness, m_face->size->metrics.y_scale)) * s_invScaleFactor; + FT_Done_FreeType(s_library); + s_library = nullptr; } - else - return characterSize/15.f; // Joker ? - } - - bool SetFile(const NzString& filePath) - { - std::unique_ptr file(new NzFile); - if (!file->Open(filePath, nzOpenMode_ReadOnly)) - { - NazaraError("Failed to open stream from file: " + NzError::GetLastError()); - return false; - } - m_ownedStream = std::move(file); - - SetStream(*m_ownedStream); - return true; - } - - void SetMemory(const void* data, std::size_t size) - { - m_ownedStream.reset(new NzMemoryStream(data, size)); - SetStream(*m_ownedStream); - } - - void SetStream(NzInputStream& stream) - { - m_stream.base = nullptr; - m_stream.close = FT_StreamClose; - m_stream.descriptor.pointer = &stream; - m_stream.read = FT_StreamRead; - m_stream.pos = 0; - m_stream.size = static_cast(stream.GetSize()); - - m_args.driver = 0; - m_args.flags = FT_OPEN_STREAM; - m_args.stream = &m_stream; - } - - bool SupportsStyle(nzUInt32 style) const override - { - ///TODO - return style == nzTextStyle_Regular || style == nzTextStyle_Bold; - } - - private: - void SetCharacterSize(unsigned int characterSize) const - { - if (m_characterSize != characterSize) - { - FT_Set_Pixel_Sizes(m_face, 0, characterSize); - m_characterSize = characterSize; - } - } - - FT_Open_Args m_args; - FT_Face m_face; - FT_StreamRec m_stream; - std::shared_ptr m_library; - std::unique_ptr m_ownedStream; - mutable unsigned int m_characterSize; - }; - - bool IsSupported(const NzString& extension) - { - ///FIXME: Je suppose qu'il en manque quelques unes.. - static std::set supportedExtensions = { - "afm", "bdf", "cff", "cid", "dfont", "fnt", "fon", "otf", "pfa", "pfb", "pfm", "pfr", "sfnt", "ttc", "tte", "ttf" }; - return supportedExtensions.find(extension) != supportedExtensions.end(); + class FreeTypeStream : public FontData + { + public: + FreeTypeStream() : + m_face(nullptr), + m_library(s_libraryOwner), + m_characterSize(0) + { + } + + ~FreeTypeStream() + { + if (m_face) + FT_Done_Face(m_face); + } + + bool Check() + { + // Test d'ouverture (http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Open_Face) + return FT_Open_Face(s_library, &m_args, -1, nullptr) == 0; + } + + bool ExtractGlyph(unsigned int characterSize, char32_t character, UInt32 style, FontGlyph* dst) override + { + #ifdef NAZARA_DEBUG + if (!dst) + { + NazaraError("Glyph destination cannot be null"); + return false; + } + #endif + + SetCharacterSize(characterSize); + + if (FT_Load_Char(m_face, character, FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_NORMAL) != 0) + { + NazaraError("Failed to load character"); + return false; + } + + FT_GlyphSlot& glyph = m_face->glyph; + + const FT_Pos boldStrength = 2 << 6; + + bool embolden = (style & TextStyle_Bold); + + dst->advance = (embolden) ? boldStrength >> 6 : 0; + + if (embolden && glyph->format == FT_GLYPH_FORMAT_OUTLINE) + { + // http://www.freetype.org/freetype2/docs/reference/ft2-outline_processing.html#FT_Outline_Embolden + FT_Outline_Embolden(&glyph->outline, boldStrength); + embolden = false; + } + + // http://www.freetype.org/freetype2/docs/reference/ft2-glyph_management.html#FT_Glyph_To_Bitmap + // Conversion du glyphe vers le format bitmap + // Cette fonction ne fait rien dans le cas où le glyphe est déjà un bitmap + if (FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL) != 0) + { + NazaraError("Failed to convert glyph to bitmap"); + return false; + } + + // Dans le cas où nous voulons des caractères gras mais que nous n'avons pas pu agir plus tôt + // nous demandons à FreeType d'agir directement sur le bitmap généré + if (embolden) + { + // http://www.freetype.org/freetype2/docs/reference/ft2-bitmap_handling.html#FT_Bitmap_Embolden + // "If you want to embolden the bitmap owned by a FT_GlyphSlot_Rec, you should call FT_GlyphSlot_Own_Bitmap on the slot first" + FT_GlyphSlot_Own_Bitmap(glyph); + FT_Bitmap_Embolden(s_library, &glyph->bitmap, boldStrength, boldStrength); + } + + dst->advance += glyph->metrics.horiAdvance >> 6; + dst->aabb.x = glyph->metrics.horiBearingX >> 6; + dst->aabb.y = -(glyph->metrics.horiBearingY >> 6); // Inversion du repère + dst->aabb.width = glyph->metrics.width >> 6; + dst->aabb.height = glyph->metrics.height >> 6; + + unsigned int width = glyph->bitmap.width; + unsigned int height = glyph->bitmap.rows; + + if (width > 0 && height > 0) + { + dst->image.Create(ImageType_2D, PixelFormatType_A8, width, height); + UInt8* pixels = dst->image.GetPixels(); + + const UInt8* data = glyph->bitmap.buffer; + + // Selon la documentation FreeType, le glyphe peut être encodé en format A8 (huit bits d'alpha par pixel) + // ou au format A1 (un bit d'alpha par pixel). + // Cependant dans un cas comme dans l'autre, il nous faut gérer le pitch (les données peuvent ne pas être contigues) + // ainsi que le padding dans le cas du format A1 (Chaque ligne prends un nombre fixe d'octets) + if (glyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) + { + // Format A1 + for (unsigned int y = 0; y < height; ++y) + { + for (unsigned int x = 0; x < width; ++x) + *pixels++ = (data[x/8] & ((1 << (7 - x%8)) ? 255 : 0)); + + data += glyph->bitmap.pitch; + } + } + else + { + // Format A8 + if (glyph->bitmap.pitch == static_cast(width*sizeof(UInt8))) // Pouvons-nous copier directement ? + dst->image.Update(glyph->bitmap.buffer); + else + { + for (unsigned int y = 0; y < height; ++y) + { + std::memcpy(pixels, data, width*sizeof(UInt8)); + data += glyph->bitmap.pitch; + pixels += width*sizeof(UInt8); + } + } + } + } + else + dst->image.Destroy(); // On s'assure que l'image ne contient alors rien + + return true; + } + + String GetFamilyName() const override + { + return m_face->family_name; + } + + String GetStyleName() const override + { + return m_face->style_name; + } + + bool HasKerning() const override + { + return FT_HAS_KERNING(m_face) != 0; + } + + bool IsScalable() const override + { + return FT_IS_SCALABLE(m_face) != 0; + } + + bool Open() + { + return FT_Open_Face(s_library, &m_args, 0, &m_face) == 0; + } + + int QueryKerning(unsigned int characterSize, char32_t first, char32_t second) const override + { + if (FT_HAS_KERNING(m_face)) + { + SetCharacterSize(characterSize); + + FT_Vector kerning; + FT_Get_Kerning(m_face, FT_Get_Char_Index(m_face, first), FT_Get_Char_Index(m_face, second), FT_KERNING_DEFAULT, &kerning); + + if (!FT_IS_SCALABLE(m_face)) + return kerning.x; // Taille déjà précisée en pixels dans ce cas + + return kerning.x >> 6; + } + else + return 0; + } + + unsigned int QueryLineHeight(unsigned int characterSize) const override + { + SetCharacterSize(characterSize); + + // http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_Size_Metrics + return m_face->size->metrics.height >> 6; + } + + float QueryUnderlinePosition(unsigned int characterSize) const override + { + if (FT_IS_SCALABLE(m_face)) + { + SetCharacterSize(characterSize); + + // http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FaceRec + return static_cast(FT_MulFix(m_face->underline_position, m_face->size->metrics.y_scale)) * s_invScaleFactor; + } + else + return characterSize / 10.f; // Joker ? + } + + float QueryUnderlineThickness(unsigned int characterSize) const override + { + if (FT_IS_SCALABLE(m_face)) + { + SetCharacterSize(characterSize); + + // http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FaceRec + return static_cast(FT_MulFix(m_face->underline_thickness, m_face->size->metrics.y_scale)) * s_invScaleFactor; + } + else + return characterSize/15.f; // Joker ? + } + + bool SetFile(const String& filePath) + { + std::unique_ptr file(new File); + if (!file->Open(filePath, OpenMode_ReadOnly)) + { + NazaraError("Failed to open stream from file: " + Error::GetLastError()); + return false; + } + m_ownedStream = std::move(file); + + SetStream(*m_ownedStream); + return true; + } + + void SetMemory(const void* data, std::size_t size) + { + m_ownedStream.reset(new MemoryStream(data, size)); + SetStream(*m_ownedStream); + } + + void SetStream(InputStream& stream) + { + m_stream.base = nullptr; + m_stream.close = FT_StreamClose; + m_stream.descriptor.pointer = &stream; + m_stream.read = FT_StreamRead; + m_stream.pos = 0; + m_stream.size = static_cast(stream.GetSize()); + + m_args.driver = 0; + m_args.flags = FT_OPEN_STREAM; + m_args.stream = &m_stream; + } + + bool SupportsStyle(UInt32 style) const override + { + ///TODO + return style == TextStyle_Regular || style == TextStyle_Bold; + } + + private: + void SetCharacterSize(unsigned int characterSize) const + { + if (m_characterSize != characterSize) + { + FT_Set_Pixel_Sizes(m_face, 0, characterSize); + m_characterSize = characterSize; + } + } + + FT_Open_Args m_args; + FT_Face m_face; + FT_StreamRec m_stream; + std::shared_ptr m_library; + std::unique_ptr m_ownedStream; + mutable unsigned int m_characterSize; + }; + + bool IsSupported(const String& extension) + { + ///FIXME: Je suppose qu'il en manque quelques unes.. + static std::set supportedExtensions = { + "afm", "bdf", "cff", "cid", "dfont", "fnt", "fon", "otf", "pfa", "pfb", "pfm", "pfr", "sfnt", "ttc", "tte", "ttf" + }; + + return supportedExtensions.find(extension) != supportedExtensions.end(); + } + + Ternary Check(InputStream& stream, const FontParams& parameters) + { + NazaraUnused(parameters); + + FreeTypeStream face; + face.SetStream(stream); + + if (face.Check()) + return Ternary_True; + else + return Ternary_False; + } + + bool LoadFile(Font* font, const String& filePath, const FontParams& parameters) + { + NazaraUnused(parameters); + + std::unique_ptr face(new FreeTypeStream); + + if (!face->SetFile(filePath)) + { + NazaraError("Failed to open file"); + return false; + } + + if (!face->Open()) + { + NazaraError("Failed to open face"); + return false; + } + + if (font->Create(face.get())) + { + face.release(); + return true; + } + else + return false; + } + + bool LoadMemory(Font* font, const void* data, std::size_t size, const FontParams& parameters) + { + NazaraUnused(parameters); + + std::unique_ptr face(new FreeTypeStream); + face->SetMemory(data, size); + + if (!face->Open()) + { + NazaraError("Failed to open face"); + return false; + } + + if (font->Create(face.get())) + { + face.release(); + return true; + } + else + return false; + } + + bool LoadStream(Font* font, InputStream& stream, const FontParams& parameters) + { + NazaraUnused(parameters); + + std::unique_ptr face(new FreeTypeStream); + face->SetStream(stream); + + if (!face->Open()) + { + NazaraError("Failed to open face"); + return false; + } + + if (font->Create(face.get())) + { + face.release(); + return true; + } + else + return false; + } } - nzTernary Check(NzInputStream& stream, const NzFontParams& parameters) + namespace Loaders { - NazaraUnused(parameters); - - FreeTypeStream face; - face.SetStream(stream); - - if (face.Check()) - return nzTernary_True; - else - return nzTernary_False; - } - - bool LoadFile(NzFont* font, const NzString& filePath, const NzFontParams& parameters) - { - NazaraUnused(parameters); - - std::unique_ptr face(new FreeTypeStream); - - if (!face->SetFile(filePath)) + void RegisterFreeType() { - NazaraError("Failed to open file"); - return false; + if (FT_Init_FreeType(&s_library) == 0) + { + s_libraryOwner.reset(new FreeTypeLibrary); + FontLoader::RegisterLoader(IsSupported, Check, LoadStream, LoadFile, LoadMemory); + } + else + { + s_library = nullptr; // On s'assure que le pointeur ne pointe pas sur n'importe quoi + NazaraWarning("Failed to initialize FreeType library"); + } } - if (!face->Open()) + void UnregisterFreeType() { - NazaraError("Failed to open face"); - return false; + if (s_library) + { + FontLoader::UnregisterLoader(IsSupported, Check, LoadStream, LoadFile, LoadMemory); + s_libraryOwner.reset(); + } } - - if (font->Create(face.get())) - { - face.release(); - return true; - } - else - return false; - } - - bool LoadMemory(NzFont* font, const void* data, std::size_t size, const NzFontParams& parameters) - { - NazaraUnused(parameters); - - std::unique_ptr face(new FreeTypeStream); - face->SetMemory(data, size); - - if (!face->Open()) - { - NazaraError("Failed to open face"); - return false; - } - - if (font->Create(face.get())) - { - face.release(); - return true; - } - else - return false; - } - - bool LoadStream(NzFont* font, NzInputStream& stream, const NzFontParams& parameters) - { - NazaraUnused(parameters); - - std::unique_ptr face(new FreeTypeStream); - face->SetStream(stream); - - if (!face->Open()) - { - NazaraError("Failed to open face"); - return false; - } - - if (font->Create(face.get())) - { - face.release(); - return true; - } - else - return false; - } -} - -void NzLoaders_FreeType_Register() -{ - if (FT_Init_FreeType(&s_library) == 0) - { - s_libraryOwner.reset(new FreeTypeLibrary); - NzFontLoader::RegisterLoader(IsSupported, Check, LoadStream, LoadFile, LoadMemory); - } - else - { - s_library = nullptr; // On s'assure que le pointeur ne pointe pas sur n'importe quoi - NazaraWarning("Failed to initialize FreeType library"); - } -} - -void NzLoaders_FreeType_Unregister() -{ - if (s_library) - { - NzFontLoader::UnregisterLoader(IsSupported, Check, LoadStream, LoadFile, LoadMemory); - s_libraryOwner.reset(); } } diff --git a/src/Nazara/Utility/Formats/FreeTypeLoader.hpp b/src/Nazara/Utility/Formats/FreeTypeLoader.hpp index 3d24bfa93..a88e2adae 100644 --- a/src/Nazara/Utility/Formats/FreeTypeLoader.hpp +++ b/src/Nazara/Utility/Formats/FreeTypeLoader.hpp @@ -9,7 +9,13 @@ #include -void NzLoaders_FreeType_Register(); -void NzLoaders_FreeType_Unregister(); +namespace Nz +{ + namespace Loaders + { + void RegisterFreeType(); + void UnregisterFreeType(); + } +} #endif // NAZARA_LOADERS_FREETYPE_HPP diff --git a/src/Nazara/Utility/Formats/MD2Constants.cpp b/src/Nazara/Utility/Formats/MD2Constants.cpp index dde0cb7bd..f80cb0b2c 100644 --- a/src/Nazara/Utility/Formats/MD2Constants.cpp +++ b/src/Nazara/Utility/Formats/MD2Constants.cpp @@ -5,170 +5,173 @@ #include #include -const nzUInt32 md2Ident = 'I' + ('D'<<8) + ('P'<<16) + ('2'<<24); - -const NzVector3f md2Normals[162] = +namespace Nz { - NzVector3f(-0.525731f, 0.000000f, 0.850651f), - NzVector3f(-0.442863f, 0.238856f, 0.864188f), - NzVector3f(-0.295242f, 0.000000f, 0.955423f), - NzVector3f(-0.309017f, 0.500000f, 0.809017f), - NzVector3f(-0.162460f, 0.262866f, 0.951056f), - NzVector3f(0.000000f, 0.000000f, 1.000000f), - NzVector3f(0.000000f, 0.850651f, 0.525731f), - NzVector3f(-0.147621f, 0.716567f, 0.681718f), - NzVector3f(0.147621f, 0.716567f, 0.681718f), - NzVector3f(0.000000f, 0.525731f, 0.850651f), - NzVector3f(0.309017f, 0.500000f, 0.809017f), - NzVector3f(0.525731f, 0.000000f, 0.850651f), - NzVector3f(0.295242f, 0.000000f, 0.955423f), - NzVector3f(0.442863f, 0.238856f, 0.864188f), - NzVector3f(0.162460f, 0.262866f, 0.951056f), - NzVector3f(-0.681718f, 0.147621f, 0.716567f), - NzVector3f(-0.809017f, 0.309017f, 0.500000f), - NzVector3f(-0.587785f, 0.425325f, 0.688191f), - NzVector3f(-0.850651f, 0.525731f, 0.000000f), - NzVector3f(-0.864188f, 0.442863f, 0.238856f), - NzVector3f(-0.716567f, 0.681718f, 0.147621f), - NzVector3f(-0.688191f, 0.587785f, 0.425325f), - NzVector3f(-0.500000f, 0.809017f, 0.309017f), - NzVector3f(-0.238856f, 0.864188f, 0.442863f), - NzVector3f(-0.425325f, 0.688191f, 0.587785f), - NzVector3f(-0.716567f, 0.681718f, -0.147621f), - NzVector3f(-0.500000f, 0.809017f, -0.309017f), - NzVector3f(-0.525731f, 0.850651f, 0.000000f), - NzVector3f(0.000000f, 0.850651f, -0.525731f), - NzVector3f(-0.238856f, 0.864188f, -0.442863f), - NzVector3f(0.000000f, 0.955423f, -0.295242f), - NzVector3f(-0.262866f, 0.951056f, -0.162460f), - NzVector3f(0.000000f, 1.000000f, 0.000000f), - NzVector3f(0.000000f, 0.955423f, 0.295242f), - NzVector3f(-0.262866f, 0.951056f, 0.162460f), - NzVector3f(0.238856f, 0.864188f, 0.442863f), - NzVector3f(0.262866f, 0.951056f, 0.162460f), - NzVector3f(0.500000f, 0.809017f, 0.309017f), - NzVector3f(0.238856f, 0.864188f, -0.442863f), - NzVector3f(0.262866f, 0.951056f, -0.162460f), - NzVector3f(0.500000f, 0.809017f, -0.309017f), - NzVector3f(0.850651f, 0.525731f, 0.000000f), - NzVector3f(0.716567f, 0.681718f, 0.147621f), - NzVector3f(0.716567f, 0.681718f, -0.147621f), - NzVector3f(0.525731f, 0.850651f, 0.000000f), - NzVector3f(0.425325f, 0.688191f, 0.587785f), - NzVector3f(0.864188f, 0.442863f, 0.238856f), - NzVector3f(0.688191f, 0.587785f, 0.425325f), - NzVector3f(0.809017f, 0.309017f, 0.500000f), - NzVector3f(0.681718f, 0.147621f, 0.716567f), - NzVector3f(0.587785f, 0.425325f, 0.688191f), - NzVector3f(0.955423f, 0.295242f, 0.000000f), - NzVector3f(1.000000f, 0.000000f, 0.000000f), - NzVector3f(0.951056f, 0.162460f, 0.262866f), - NzVector3f(0.850651f, -0.525731f, 0.000000f), - NzVector3f(0.955423f, -0.295242f, 0.000000f), - NzVector3f(0.864188f, -0.442863f, 0.238856f), - NzVector3f(0.951056f, -0.162460f, 0.262866f), - NzVector3f(0.809017f, -0.309017f, 0.500000f), - NzVector3f(0.681718f, -0.147621f, 0.716567f), - NzVector3f(0.850651f, 0.000000f, 0.525731f), - NzVector3f(0.864188f, 0.442863f, -0.238856f), - NzVector3f(0.809017f, 0.309017f, -0.500000f), - NzVector3f(0.951056f, 0.162460f, -0.262866f), - NzVector3f(0.525731f, 0.000000f, -0.850651f), - NzVector3f(0.681718f, 0.147621f, -0.716567f), - NzVector3f(0.681718f, -0.147621f, -0.716567f), - NzVector3f(0.850651f, 0.000000f, -0.525731f), - NzVector3f(0.809017f, -0.309017f, -0.500000f), - NzVector3f(0.864188f, -0.442863f, -0.238856f), - NzVector3f(0.951056f, -0.162460f, -0.262866f), - NzVector3f(0.147621f, 0.716567f, -0.681718f), - NzVector3f(0.309017f, 0.500000f, -0.809017f), - NzVector3f(0.425325f, 0.688191f, -0.587785f), - NzVector3f(0.442863f, 0.238856f, -0.864188f), - NzVector3f(0.587785f, 0.425325f, -0.688191f), - NzVector3f(0.688191f, 0.587785f, -0.425325f), - NzVector3f(-0.147621f, 0.716567f, -0.681718f), - NzVector3f(-0.309017f, 0.500000f, -0.809017f), - NzVector3f(0.000000f, 0.525731f, -0.850651f), - NzVector3f(-0.525731f, 0.000000f, -0.850651f), - NzVector3f(-0.442863f, 0.238856f, -0.864188f), - NzVector3f(-0.295242f, 0.000000f, -0.955423f), - NzVector3f(-0.162460f, 0.262866f, -0.951056f), - NzVector3f(0.000000f, 0.000000f, -1.000000f), - NzVector3f(0.295242f, 0.000000f, -0.955423f), - NzVector3f(0.162460f, 0.262866f, -0.951056f), - NzVector3f(-0.442863f, -0.238856f, -0.864188f), - NzVector3f(-0.309017f, -0.500000f, -0.809017f), - NzVector3f(-0.162460f, -0.262866f, -0.951056f), - NzVector3f(0.000000f, -0.850651f, -0.525731f), - NzVector3f(-0.147621f, -0.716567f, -0.681718f), - NzVector3f(0.147621f, -0.716567f, -0.681718f), - NzVector3f(0.000000f, -0.525731f, -0.850651f), - NzVector3f(0.309017f, -0.500000f, -0.809017f), - NzVector3f(0.442863f, -0.238856f, -0.864188f), - NzVector3f(0.162460f, -0.262866f, -0.951056f), - NzVector3f(0.238856f, -0.864188f, -0.442863f), - NzVector3f(0.500000f, -0.809017f, -0.309017f), - NzVector3f(0.425325f, -0.688191f, -0.587785f), - NzVector3f(0.716567f, -0.681718f, -0.147621f), - NzVector3f(0.688191f, -0.587785f, -0.425325f), - NzVector3f(0.587785f, -0.425325f, -0.688191f), - NzVector3f(0.000000f, -0.955423f, -0.295242f), - NzVector3f(0.000000f, -1.000000f, 0.000000f), - NzVector3f(0.262866f, -0.951056f, -0.162460f), - NzVector3f(0.000000f, -0.850651f, 0.525731f), - NzVector3f(0.000000f, -0.955423f, 0.295242f), - NzVector3f(0.238856f, -0.864188f, 0.442863f), - NzVector3f(0.262866f, -0.951056f, 0.162460f), - NzVector3f(0.500000f, -0.809017f, 0.309017f), - NzVector3f(0.716567f, -0.681718f, 0.147621f), - NzVector3f(0.525731f, -0.850651f, 0.000000f), - NzVector3f(-0.238856f, -0.864188f, -0.442863f), - NzVector3f(-0.500000f, -0.809017f, -0.309017f), - NzVector3f(-0.262866f, -0.951056f, -0.162460f), - NzVector3f(-0.850651f, -0.525731f, 0.000000f), - NzVector3f(-0.716567f, -0.681718f, -0.147621f), - NzVector3f(-0.716567f, -0.681718f, 0.147621f), - NzVector3f(-0.525731f, -0.850651f, 0.000000f), - NzVector3f(-0.500000f, -0.809017f, 0.309017f), - NzVector3f(-0.238856f, -0.864188f, 0.442863f), - NzVector3f(-0.262866f, -0.951056f, 0.162460f), - NzVector3f(-0.864188f, -0.442863f, 0.238856f), - NzVector3f(-0.809017f, -0.309017f, 0.500000f), - NzVector3f(-0.688191f, -0.587785f, 0.425325f), - NzVector3f(-0.681718f, -0.147621f, 0.716567f), - NzVector3f(-0.442863f, -0.238856f, 0.864188f), - NzVector3f(-0.587785f, -0.425325f, 0.688191f), - NzVector3f(-0.309017f, -0.500000f, 0.809017f), - NzVector3f(-0.147621f, -0.716567f, 0.681718f), - NzVector3f(-0.425325f, -0.688191f, 0.587785f), - NzVector3f(-0.162460f, -0.262866f, 0.951056f), - NzVector3f(0.442863f, -0.238856f, 0.864188f), - NzVector3f(0.162460f, -0.262866f, 0.951056f), - NzVector3f(0.309017f, -0.500000f, 0.809017f), - NzVector3f(0.147621f, -0.716567f, 0.681718f), - NzVector3f(0.000000f, -0.525731f, 0.850651f), - NzVector3f(0.425325f, -0.688191f, 0.587785f), - NzVector3f(0.587785f, -0.425325f, 0.688191f), - NzVector3f(0.688191f, -0.587785f, 0.425325f), - NzVector3f(-0.955423f, 0.295242f, 0.000000f), - NzVector3f(-0.951056f, 0.162460f, 0.262866f), - NzVector3f(-1.000000f, 0.000000f, 0.000000f), - NzVector3f(-0.850651f, 0.000000f, 0.525731f), - NzVector3f(-0.955423f, -0.295242f, 0.000000f), - NzVector3f(-0.951056f, -0.162460f, 0.262866f), - NzVector3f(-0.864188f, 0.442863f, -0.238856f), - NzVector3f(-0.951056f, 0.162460f, -0.262866f), - NzVector3f(-0.809017f, 0.309017f, -0.500000f), - NzVector3f(-0.864188f, -0.442863f, -0.238856f), - NzVector3f(-0.951056f, -0.162460f, -0.262866f), - NzVector3f(-0.809017f, -0.309017f, -0.500000f), - NzVector3f(-0.681718f, 0.147621f, -0.716567f), - NzVector3f(-0.681718f, -0.147621f, -0.716567f), - NzVector3f(-0.850651f, 0.000000f, -0.525731f), - NzVector3f(-0.688191f, 0.587785f, -0.425325f), - NzVector3f(-0.587785f, 0.425325f, -0.688191f), - NzVector3f(-0.425325f, 0.688191f, -0.587785f), - NzVector3f(-0.425325f, -0.688191f, -0.587785f), - NzVector3f(-0.587785f, -0.425325f, -0.688191f), - NzVector3f(-0.688191f, -0.587785f, -0.425325f) -}; + const UInt32 md2Ident = 'I' + ('D'<<8) + ('P'<<16) + ('2'<<24); + + const Vector3f md2Normals[162] = + { + Vector3f(-0.525731f, 0.000000f, 0.850651f), + Vector3f(-0.442863f, 0.238856f, 0.864188f), + Vector3f(-0.295242f, 0.000000f, 0.955423f), + Vector3f(-0.309017f, 0.500000f, 0.809017f), + Vector3f(-0.162460f, 0.262866f, 0.951056f), + Vector3f(0.000000f, 0.000000f, 1.000000f), + Vector3f(0.000000f, 0.850651f, 0.525731f), + Vector3f(-0.147621f, 0.716567f, 0.681718f), + Vector3f(0.147621f, 0.716567f, 0.681718f), + Vector3f(0.000000f, 0.525731f, 0.850651f), + Vector3f(0.309017f, 0.500000f, 0.809017f), + Vector3f(0.525731f, 0.000000f, 0.850651f), + Vector3f(0.295242f, 0.000000f, 0.955423f), + Vector3f(0.442863f, 0.238856f, 0.864188f), + Vector3f(0.162460f, 0.262866f, 0.951056f), + Vector3f(-0.681718f, 0.147621f, 0.716567f), + Vector3f(-0.809017f, 0.309017f, 0.500000f), + Vector3f(-0.587785f, 0.425325f, 0.688191f), + Vector3f(-0.850651f, 0.525731f, 0.000000f), + Vector3f(-0.864188f, 0.442863f, 0.238856f), + Vector3f(-0.716567f, 0.681718f, 0.147621f), + Vector3f(-0.688191f, 0.587785f, 0.425325f), + Vector3f(-0.500000f, 0.809017f, 0.309017f), + Vector3f(-0.238856f, 0.864188f, 0.442863f), + Vector3f(-0.425325f, 0.688191f, 0.587785f), + Vector3f(-0.716567f, 0.681718f, -0.147621f), + Vector3f(-0.500000f, 0.809017f, -0.309017f), + Vector3f(-0.525731f, 0.850651f, 0.000000f), + Vector3f(0.000000f, 0.850651f, -0.525731f), + Vector3f(-0.238856f, 0.864188f, -0.442863f), + Vector3f(0.000000f, 0.955423f, -0.295242f), + Vector3f(-0.262866f, 0.951056f, -0.162460f), + Vector3f(0.000000f, 1.000000f, 0.000000f), + Vector3f(0.000000f, 0.955423f, 0.295242f), + Vector3f(-0.262866f, 0.951056f, 0.162460f), + Vector3f(0.238856f, 0.864188f, 0.442863f), + Vector3f(0.262866f, 0.951056f, 0.162460f), + Vector3f(0.500000f, 0.809017f, 0.309017f), + Vector3f(0.238856f, 0.864188f, -0.442863f), + Vector3f(0.262866f, 0.951056f, -0.162460f), + Vector3f(0.500000f, 0.809017f, -0.309017f), + Vector3f(0.850651f, 0.525731f, 0.000000f), + Vector3f(0.716567f, 0.681718f, 0.147621f), + Vector3f(0.716567f, 0.681718f, -0.147621f), + Vector3f(0.525731f, 0.850651f, 0.000000f), + Vector3f(0.425325f, 0.688191f, 0.587785f), + Vector3f(0.864188f, 0.442863f, 0.238856f), + Vector3f(0.688191f, 0.587785f, 0.425325f), + Vector3f(0.809017f, 0.309017f, 0.500000f), + Vector3f(0.681718f, 0.147621f, 0.716567f), + Vector3f(0.587785f, 0.425325f, 0.688191f), + Vector3f(0.955423f, 0.295242f, 0.000000f), + Vector3f(1.000000f, 0.000000f, 0.000000f), + Vector3f(0.951056f, 0.162460f, 0.262866f), + Vector3f(0.850651f, -0.525731f, 0.000000f), + Vector3f(0.955423f, -0.295242f, 0.000000f), + Vector3f(0.864188f, -0.442863f, 0.238856f), + Vector3f(0.951056f, -0.162460f, 0.262866f), + Vector3f(0.809017f, -0.309017f, 0.500000f), + Vector3f(0.681718f, -0.147621f, 0.716567f), + Vector3f(0.850651f, 0.000000f, 0.525731f), + Vector3f(0.864188f, 0.442863f, -0.238856f), + Vector3f(0.809017f, 0.309017f, -0.500000f), + Vector3f(0.951056f, 0.162460f, -0.262866f), + Vector3f(0.525731f, 0.000000f, -0.850651f), + Vector3f(0.681718f, 0.147621f, -0.716567f), + Vector3f(0.681718f, -0.147621f, -0.716567f), + Vector3f(0.850651f, 0.000000f, -0.525731f), + Vector3f(0.809017f, -0.309017f, -0.500000f), + Vector3f(0.864188f, -0.442863f, -0.238856f), + Vector3f(0.951056f, -0.162460f, -0.262866f), + Vector3f(0.147621f, 0.716567f, -0.681718f), + Vector3f(0.309017f, 0.500000f, -0.809017f), + Vector3f(0.425325f, 0.688191f, -0.587785f), + Vector3f(0.442863f, 0.238856f, -0.864188f), + Vector3f(0.587785f, 0.425325f, -0.688191f), + Vector3f(0.688191f, 0.587785f, -0.425325f), + Vector3f(-0.147621f, 0.716567f, -0.681718f), + Vector3f(-0.309017f, 0.500000f, -0.809017f), + Vector3f(0.000000f, 0.525731f, -0.850651f), + Vector3f(-0.525731f, 0.000000f, -0.850651f), + Vector3f(-0.442863f, 0.238856f, -0.864188f), + Vector3f(-0.295242f, 0.000000f, -0.955423f), + Vector3f(-0.162460f, 0.262866f, -0.951056f), + Vector3f(0.000000f, 0.000000f, -1.000000f), + Vector3f(0.295242f, 0.000000f, -0.955423f), + Vector3f(0.162460f, 0.262866f, -0.951056f), + Vector3f(-0.442863f, -0.238856f, -0.864188f), + Vector3f(-0.309017f, -0.500000f, -0.809017f), + Vector3f(-0.162460f, -0.262866f, -0.951056f), + Vector3f(0.000000f, -0.850651f, -0.525731f), + Vector3f(-0.147621f, -0.716567f, -0.681718f), + Vector3f(0.147621f, -0.716567f, -0.681718f), + Vector3f(0.000000f, -0.525731f, -0.850651f), + Vector3f(0.309017f, -0.500000f, -0.809017f), + Vector3f(0.442863f, -0.238856f, -0.864188f), + Vector3f(0.162460f, -0.262866f, -0.951056f), + Vector3f(0.238856f, -0.864188f, -0.442863f), + Vector3f(0.500000f, -0.809017f, -0.309017f), + Vector3f(0.425325f, -0.688191f, -0.587785f), + Vector3f(0.716567f, -0.681718f, -0.147621f), + Vector3f(0.688191f, -0.587785f, -0.425325f), + Vector3f(0.587785f, -0.425325f, -0.688191f), + Vector3f(0.000000f, -0.955423f, -0.295242f), + Vector3f(0.000000f, -1.000000f, 0.000000f), + Vector3f(0.262866f, -0.951056f, -0.162460f), + Vector3f(0.000000f, -0.850651f, 0.525731f), + Vector3f(0.000000f, -0.955423f, 0.295242f), + Vector3f(0.238856f, -0.864188f, 0.442863f), + Vector3f(0.262866f, -0.951056f, 0.162460f), + Vector3f(0.500000f, -0.809017f, 0.309017f), + Vector3f(0.716567f, -0.681718f, 0.147621f), + Vector3f(0.525731f, -0.850651f, 0.000000f), + Vector3f(-0.238856f, -0.864188f, -0.442863f), + Vector3f(-0.500000f, -0.809017f, -0.309017f), + Vector3f(-0.262866f, -0.951056f, -0.162460f), + Vector3f(-0.850651f, -0.525731f, 0.000000f), + Vector3f(-0.716567f, -0.681718f, -0.147621f), + Vector3f(-0.716567f, -0.681718f, 0.147621f), + Vector3f(-0.525731f, -0.850651f, 0.000000f), + Vector3f(-0.500000f, -0.809017f, 0.309017f), + Vector3f(-0.238856f, -0.864188f, 0.442863f), + Vector3f(-0.262866f, -0.951056f, 0.162460f), + Vector3f(-0.864188f, -0.442863f, 0.238856f), + Vector3f(-0.809017f, -0.309017f, 0.500000f), + Vector3f(-0.688191f, -0.587785f, 0.425325f), + Vector3f(-0.681718f, -0.147621f, 0.716567f), + Vector3f(-0.442863f, -0.238856f, 0.864188f), + Vector3f(-0.587785f, -0.425325f, 0.688191f), + Vector3f(-0.309017f, -0.500000f, 0.809017f), + Vector3f(-0.147621f, -0.716567f, 0.681718f), + Vector3f(-0.425325f, -0.688191f, 0.587785f), + Vector3f(-0.162460f, -0.262866f, 0.951056f), + Vector3f(0.442863f, -0.238856f, 0.864188f), + Vector3f(0.162460f, -0.262866f, 0.951056f), + Vector3f(0.309017f, -0.500000f, 0.809017f), + Vector3f(0.147621f, -0.716567f, 0.681718f), + Vector3f(0.000000f, -0.525731f, 0.850651f), + Vector3f(0.425325f, -0.688191f, 0.587785f), + Vector3f(0.587785f, -0.425325f, 0.688191f), + Vector3f(0.688191f, -0.587785f, 0.425325f), + Vector3f(-0.955423f, 0.295242f, 0.000000f), + Vector3f(-0.951056f, 0.162460f, 0.262866f), + Vector3f(-1.000000f, 0.000000f, 0.000000f), + Vector3f(-0.850651f, 0.000000f, 0.525731f), + Vector3f(-0.955423f, -0.295242f, 0.000000f), + Vector3f(-0.951056f, -0.162460f, 0.262866f), + Vector3f(-0.864188f, 0.442863f, -0.238856f), + Vector3f(-0.951056f, 0.162460f, -0.262866f), + Vector3f(-0.809017f, 0.309017f, -0.500000f), + Vector3f(-0.864188f, -0.442863f, -0.238856f), + Vector3f(-0.951056f, -0.162460f, -0.262866f), + Vector3f(-0.809017f, -0.309017f, -0.500000f), + Vector3f(-0.681718f, 0.147621f, -0.716567f), + Vector3f(-0.681718f, -0.147621f, -0.716567f), + Vector3f(-0.850651f, 0.000000f, -0.525731f), + Vector3f(-0.688191f, 0.587785f, -0.425325f), + Vector3f(-0.587785f, 0.425325f, -0.688191f), + Vector3f(-0.425325f, 0.688191f, -0.587785f), + Vector3f(-0.425325f, -0.688191f, -0.587785f), + Vector3f(-0.587785f, -0.425325f, -0.688191f), + Vector3f(-0.688191f, -0.587785f, -0.425325f) + }; +} diff --git a/src/Nazara/Utility/Formats/MD2Constants.hpp b/src/Nazara/Utility/Formats/MD2Constants.hpp index 07e574b4c..694f15dae 100644 --- a/src/Nazara/Utility/Formats/MD2Constants.hpp +++ b/src/Nazara/Utility/Formats/MD2Constants.hpp @@ -8,57 +8,60 @@ #include #include -struct MD2_Header +namespace Nz { - nzUInt32 ident; // nombre magique : "IDP2" - nzUInt32 version; // version du format : 8 + struct MD2_Header + { + UInt32 ident; // nombre magique : "IDP2" + UInt32 version; // version du format : 8 - nzUInt32 skinwidth; // largeur texture - nzUInt32 skinheight; // hauteur texture + UInt32 skinwidth; // largeur texture + UInt32 skinheight; // hauteur texture - nzUInt32 framesize; // taille d'une frame en octets + UInt32 framesize; // taille d'une frame en octets - nzUInt32 num_skins; // nombre de skins - nzUInt32 num_vertices; // nombre de vertices par frame - nzUInt32 num_st; // nombre de coordonnées de texture - nzUInt32 num_tris; // nombre de triangles - nzUInt32 num_glcmds; // nombre de commandes opengl - nzUInt32 num_frames; // nombre de frames + UInt32 num_skins; // nombre de skins + UInt32 num_vertices; // nombre de vertices par frame + UInt32 num_st; // nombre de coordonnées de texture + UInt32 num_tris; // nombre de triangles + UInt32 num_glcmds; // nombre de commandes opengl + UInt32 num_frames; // nombre de frames - nzUInt32 offset_skins; // offset données skins - nzUInt32 offset_st; // offset données coordonnées de texture - nzUInt32 offset_tris; // offset données triangles - nzUInt32 offset_frames; // offset données frames - nzUInt32 offset_glcmds; // offset données commandes OpenGL - nzUInt32 offset_end; // offset fin de fichier -}; + UInt32 offset_skins; // offset données skins + UInt32 offset_st; // offset données coordonnées de texture + UInt32 offset_tris; // offset données triangles + UInt32 offset_frames; // offset données frames + UInt32 offset_glcmds; // offset données commandes OpenGL + UInt32 offset_end; // offset fin de fichier + }; -static_assert(sizeof(MD2_Header) == 17*sizeof(nzUInt32), "MD2_Header must be packed"); + static_assert(sizeof(MD2_Header) == 17*sizeof(UInt32), "MD2_Header must be packed"); -struct MD2_Vertex -{ - nzUInt8 x, y, z; - nzUInt8 n; -}; + struct MD2_Vertex + { + UInt8 x, y, z; + UInt8 n; + }; -static_assert(sizeof(MD2_Vertex) == 4*sizeof(nzUInt8), "MD2_Vertex must be packed"); + static_assert(sizeof(MD2_Vertex) == 4*sizeof(UInt8), "MD2_Vertex must be packed"); -struct MD2_TexCoord -{ - nzInt16 u, v; -}; + struct MD2_TexCoord + { + Int16 u, v; + }; -static_assert(sizeof(MD2_TexCoord) == 2*sizeof(nzInt16), "MD2_TexCoord must be packed"); + static_assert(sizeof(MD2_TexCoord) == 2*sizeof(Int16), "MD2_TexCoord must be packed"); -struct MD2_Triangle -{ - nzUInt16 vertices[3]; - nzUInt16 texCoords[3]; -}; + struct MD2_Triangle + { + UInt16 vertices[3]; + UInt16 texCoords[3]; + }; -static_assert(sizeof(MD2_Triangle) == 2*3*sizeof(nzUInt16), "MD2_Triangle must be packed"); + static_assert(sizeof(MD2_Triangle) == 2*3*sizeof(UInt16), "MD2_Triangle must be packed"); -extern const nzUInt32 md2Ident; -extern const NzVector3f md2Normals[162]; + extern const UInt32 md2Ident; + extern const Vector3f md2Normals[162]; +} #endif // NAZARA_LOADERS_MD2_CONSTANTS_HPP diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index 5872b4292..77fca01d1 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -17,230 +17,236 @@ #include #include -namespace +namespace Nz { - bool IsSupported(const NzString& extension) + namespace { - return (extension == "md2"); - } - - nzTernary Check(NzInputStream& stream, const NzMeshParams& parameters) - { - NazaraUnused(parameters); - - nzUInt32 magic[2]; - if (stream.Read(&magic[0], 2*sizeof(nzUInt32)) == 2*sizeof(nzUInt32)) + bool IsSupported(const String& extension) { + return (extension == "md2"); + } + + Ternary Check(InputStream& stream, const MeshParams& parameters) + { + NazaraUnused(parameters); + + UInt32 magic[2]; + if (stream.Read(&magic[0], 2*sizeof(UInt32)) == 2*sizeof(UInt32)) + { + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&magic[0], sizeof(UInt32)); + SwapBytes(&magic[1], sizeof(UInt32)); + #endif + + if (magic[0] == md2Ident && magic[1] == 8) + return Ternary_True; + } + + return Ternary_False; + } + + bool Load(Mesh* mesh, InputStream& stream, const MeshParams& parameters) + { + MD2_Header header; + if (stream.Read(&header, sizeof(MD2_Header)) != sizeof(MD2_Header)) + { + NazaraError("Failed to read header"); + return false; + } + #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&magic[0], sizeof(nzUInt32)); - NzByteSwap(&magic[1], sizeof(nzUInt32)); + SwapBytes(&header.skinwidth, sizeof(UInt32)); + SwapBytes(&header.skinheight, sizeof(UInt32)); + SwapBytes(&header.framesize, sizeof(UInt32)); + SwapBytes(&header.num_skins, sizeof(UInt32)); + SwapBytes(&header.num_vertices, sizeof(UInt32)); + SwapBytes(&header.num_st, sizeof(UInt32)); + SwapBytes(&header.num_tris, sizeof(UInt32)); + SwapBytes(&header.num_glcmds, sizeof(UInt32)); + SwapBytes(&header.num_frames, sizeof(UInt32)); + SwapBytes(&header.offset_skins, sizeof(UInt32)); + SwapBytes(&header.offset_st, sizeof(UInt32)); + SwapBytes(&header.offset_tris, sizeof(UInt32)); + SwapBytes(&header.offset_frames, sizeof(UInt32)); + SwapBytes(&header.offset_glcmds, sizeof(UInt32)); + SwapBytes(&header.offset_end, sizeof(UInt32)); #endif - if (magic[0] == md2Ident && magic[1] == 8) - return nzTernary_True; - } - - return nzTernary_False; - } - - bool Load(NzMesh* mesh, NzInputStream& stream, const NzMeshParams& parameters) - { - MD2_Header header; - if (stream.Read(&header, sizeof(MD2_Header)) != sizeof(MD2_Header)) - { - NazaraError("Failed to read header"); - return false; - } - - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&header.skinwidth, sizeof(nzUInt32)); - NzByteSwap(&header.skinheight, sizeof(nzUInt32)); - NzByteSwap(&header.framesize, sizeof(nzUInt32)); - NzByteSwap(&header.num_skins, sizeof(nzUInt32)); - NzByteSwap(&header.num_vertices, sizeof(nzUInt32)); - NzByteSwap(&header.num_st, sizeof(nzUInt32)); - NzByteSwap(&header.num_tris, sizeof(nzUInt32)); - NzByteSwap(&header.num_glcmds, sizeof(nzUInt32)); - NzByteSwap(&header.num_frames, sizeof(nzUInt32)); - NzByteSwap(&header.offset_skins, sizeof(nzUInt32)); - NzByteSwap(&header.offset_st, sizeof(nzUInt32)); - NzByteSwap(&header.offset_tris, sizeof(nzUInt32)); - NzByteSwap(&header.offset_frames, sizeof(nzUInt32)); - NzByteSwap(&header.offset_glcmds, sizeof(nzUInt32)); - NzByteSwap(&header.offset_end, sizeof(nzUInt32)); - #endif - - if (stream.GetSize() < header.offset_end) - { - NazaraError("Incomplete MD2 file"); - return false; - } - - /// Création du mesh - // Le moteur ne supporte plus les animations image-clé, nous ne pouvons charger qu'en statique - if (!mesh->CreateStatic()) // Ne devrait jamais échouer - { - NazaraInternalError("Failed to create mesh"); - return false; - } - - /// Chargement des skins - if (header.num_skins > 0) - { - mesh->SetMaterialCount(header.num_skins); - stream.SetCursorPos(header.offset_skins); + if (stream.GetSize() < header.offset_end) { - NzString baseDir = stream.GetDirectory(); - char skin[68]; - for (unsigned int i = 0; i < header.num_skins; ++i) + NazaraError("Incomplete MD2 file"); + return false; + } + + /// Création du mesh + // Le moteur ne supporte plus les animations image-clé, nous ne pouvons charger qu'en statique + if (!mesh->CreateStatic()) // Ne devrait jamais échouer + { + NazaraInternalError("Failed to create mesh"); + return false; + } + + /// Chargement des skins + if (header.num_skins > 0) + { + mesh->SetMaterialCount(header.num_skins); + stream.SetCursorPos(header.offset_skins); { - stream.Read(skin, 68*sizeof(char)); - mesh->SetMaterial(i, baseDir + skin); + String baseDir = stream.GetDirectory(); + char skin[68]; + for (unsigned int i = 0; i < header.num_skins; ++i) + { + stream.Read(skin, 68*sizeof(char)); + mesh->SetMaterial(i, baseDir + skin); + } } } - } - /// Chargement des submesh - // Actuellement le loader ne charge qu'un submesh - NzIndexBufferRef indexBuffer = NzIndexBuffer::New(false, header.num_tris*3, parameters.storage, nzBufferUsage_Static); + /// Chargement des submesh + // Actuellement le loader ne charge qu'un submesh + IndexBufferRef indexBuffer = IndexBuffer::New(false, header.num_tris*3, parameters.storage, BufferUsage_Static); - /// Lecture des triangles - std::vector triangles(header.num_tris); + /// Lecture des triangles + std::vector triangles(header.num_tris); - stream.SetCursorPos(header.offset_tris); - stream.Read(&triangles[0], header.num_tris*sizeof(MD2_Triangle)); + stream.SetCursorPos(header.offset_tris); + stream.Read(&triangles[0], header.num_tris*sizeof(MD2_Triangle)); - NzBufferMapper indexMapper(indexBuffer, nzBufferAccess_DiscardAndWrite); - nzUInt16* index = reinterpret_cast(indexMapper.GetPointer()); + BufferMapper indexMapper(indexBuffer, BufferAccess_DiscardAndWrite); + UInt16* index = reinterpret_cast(indexMapper.GetPointer()); + + for (unsigned int i = 0; i < header.num_tris; ++i) + { + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&triangles[i].vertices[0], sizeof(UInt16)); + SwapBytes(&triangles[i].texCoords[0], sizeof(UInt16)); + + SwapBytes(&triangles[i].vertices[1], sizeof(UInt16)); + SwapBytes(&triangles[i].texCoords[1], sizeof(UInt16)); + + SwapBytes(&triangles[i].vertices[2], sizeof(UInt16)); + SwapBytes(&triangles[i].texCoords[2], sizeof(UInt16)); + #endif + + // On respécifie le triangle dans l'ordre attendu + *index++ = triangles[i].vertices[0]; + *index++ = triangles[i].vertices[2]; + *index++ = triangles[i].vertices[1]; + } + + indexMapper.Unmap(); + + if (parameters.optimizeIndexBuffers) + indexBuffer->Optimize(); + + /// Lecture des coordonnées de texture + std::vector texCoords(header.num_st); + + stream.SetCursorPos(header.offset_st); + stream.Read(&texCoords[0], header.num_st*sizeof(MD2_TexCoord)); - for (unsigned int i = 0; i < header.num_tris; ++i) - { #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&triangles[i].vertices[0], sizeof(nzUInt16)); - NzByteSwap(&triangles[i].texCoords[0], sizeof(nzUInt16)); - - NzByteSwap(&triangles[i].vertices[1], sizeof(nzUInt16)); - NzByteSwap(&triangles[i].texCoords[1], sizeof(nzUInt16)); - - NzByteSwap(&triangles[i].vertices[2], sizeof(nzUInt16)); - NzByteSwap(&triangles[i].texCoords[2], sizeof(nzUInt16)); + for (unsigned int i = 0; i < header.num_st; ++i) + { + SwapBytes(&texCoords[i].u, sizeof(Int16)); + SwapBytes(&texCoords[i].v, sizeof(Int16)); + } #endif - // On respécifie le triangle dans l'ordre attendu - *index++ = triangles[i].vertices[0]; - *index++ = triangles[i].vertices[2]; - *index++ = triangles[i].vertices[1]; - } - - indexMapper.Unmap(); - - if (parameters.optimizeIndexBuffers) - indexBuffer->Optimize(); - - /// Lecture des coordonnées de texture - std::vector texCoords(header.num_st); - - stream.SetCursorPos(header.offset_st); - stream.Read(&texCoords[0], header.num_st*sizeof(MD2_TexCoord)); - - #ifdef NAZARA_BIG_ENDIAN - for (unsigned int i = 0; i < header.num_st; ++i) - { - NzByteSwap(&texCoords[i].u, sizeof(nzInt16)); - NzByteSwap(&texCoords[i].v, sizeof(nzInt16)); - } - #endif - - NzVertexBufferRef vertexBuffer = NzVertexBuffer::New(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), header.num_vertices, parameters.storage, nzBufferUsage_Static); - NzStaticMeshRef subMesh = NzStaticMesh::New(mesh); - if (!subMesh->Create(vertexBuffer)) - { - NazaraError("Failed to create SubMesh"); - return false; - } - - /// Chargement des vertices - stream.SetCursorPos(header.offset_frames); - - std::unique_ptr vertices(new MD2_Vertex[header.num_vertices]); - NzVector3f scale, translate; - stream.Read(scale, sizeof(NzVector3f)); - stream.Read(translate, sizeof(NzVector3f)); - stream.Read(nullptr, 16*sizeof(char)); // Nom de la frame, inutile ici - stream.Read(vertices.get(), header.num_vertices*sizeof(MD2_Vertex)); - - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&scale.x, sizeof(float)); - NzByteSwap(&scale.y, sizeof(float)); - NzByteSwap(&scale.z, sizeof(float)); - - NzByteSwap(&translate.x, sizeof(float)); - NzByteSwap(&translate.y, sizeof(float)); - NzByteSwap(&translate.z, sizeof(float)); - #endif - - // Un personnage de taille moyenne fait ~50 unités de haut dans Quake 2 - // Avec Nazara, 1 unité = 1 mètre, nous devons donc adapter l'échelle - NzVector3f s(parameters.scale/29.f); // 50/29 = 1.72 (Soit 1.72 mètre, proche de la taille moyenne d'un individu) - scale *= s; - translate *= s; - - NzBufferMapper vertexMapper(vertexBuffer, nzBufferAccess_DiscardAndWrite); - NzMeshVertex* vertex = reinterpret_cast(vertexMapper.GetPointer()); - - /// Chargement des coordonnées de texture - const unsigned int indexFix[3] = {0, 2, 1}; // Pour respécifier les indices dans le bon ordre - for (unsigned int i = 0; i < header.num_tris; ++i) - { - for (unsigned int j = 0; j < 3; ++j) + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), header.num_vertices, parameters.storage, BufferUsage_Static); + StaticMeshRef subMesh = StaticMesh::New(mesh); + if (!subMesh->Create(vertexBuffer)) { - const unsigned int fixedIndex = indexFix[j]; - const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]]; - float u = static_cast(texC.u) / header.skinwidth; - float v = static_cast(texC.v) / header.skinheight; - - vertex[triangles[i].vertices[fixedIndex]].uv.Set(u, (parameters.flipUVs) ? 1.f - v : v); + NazaraError("Failed to create SubMesh"); + return false; } + + /// Chargement des vertices + stream.SetCursorPos(header.offset_frames); + + std::unique_ptr vertices(new MD2_Vertex[header.num_vertices]); + Vector3f scale, translate; + stream.Read(scale, sizeof(Vector3f)); + stream.Read(translate, sizeof(Vector3f)); + stream.Read(nullptr, 16*sizeof(char)); // Nom de la frame, inutile ici + stream.Read(vertices.get(), header.num_vertices*sizeof(MD2_Vertex)); + + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&scale.x, sizeof(float)); + SwapBytes(&scale.y, sizeof(float)); + SwapBytes(&scale.z, sizeof(float)); + + SwapBytes(&translate.x, sizeof(float)); + SwapBytes(&translate.y, sizeof(float)); + SwapBytes(&translate.z, sizeof(float)); + #endif + + // Un personnage de taille moyenne fait ~50 unités de haut dans Quake 2 + // Avec Nazara, 1 unité = 1 mètre, nous devons donc adapter l'échelle + Vector3f s(parameters.scale/29.f); // 50/29 = 1.72 (Soit 1.72 mètre, proche de la taille moyenne d'un individu) + scale *= s; + translate *= s; + + BufferMapper vertexMapper(vertexBuffer, BufferAccess_DiscardAndWrite); + MeshVertex* vertex = reinterpret_cast(vertexMapper.GetPointer()); + + /// Chargement des coordonnées de texture + const unsigned int indexFix[3] = {0, 2, 1}; // Pour respécifier les indices dans le bon ordre + for (unsigned int i = 0; i < header.num_tris; ++i) + { + for (unsigned int j = 0; j < 3; ++j) + { + const unsigned int fixedIndex = indexFix[j]; + const MD2_TexCoord& texC = texCoords[triangles[i].texCoords[fixedIndex]]; + float u = static_cast(texC.u) / header.skinwidth; + float v = static_cast(texC.v) / header.skinheight; + + vertex[triangles[i].vertices[fixedIndex]].uv.Set(u, (parameters.flipUVs) ? 1.f - v : v); + } + } + + /// Chargement des positions + // Pour que le modèle soit correctement aligné, on génère un quaternion que nous appliquerons à chacune des vertices + Quaternionf rotationQuat = EulerAnglesf(-90.f, 90.f, 0.f); + + for (unsigned int v = 0; v < header.num_vertices; ++v) + { + const MD2_Vertex& vert = vertices[v]; + Vector3f position = rotationQuat * Vector3f(vert.x*scale.x + translate.x, vert.y*scale.y + translate.y, vert.z*scale.z + translate.z); + + vertex->position = position; + vertex->normal = rotationQuat * md2Normals[vert.n]; + + vertex++; + } + + vertexMapper.Unmap(); + + subMesh->SetIndexBuffer(indexBuffer); + subMesh->SetMaterialIndex(0); + + subMesh->GenerateAABB(); + subMesh->GenerateTangents(); + + mesh->AddSubMesh(subMesh); + + if (parameters.center) + mesh->Recenter(); + + return true; } + } - /// Chargement des positions - // Pour que le modèle soit correctement aligné, on génère un quaternion que nous appliquerons à chacune des vertices - NzQuaternionf rotationQuat = NzEulerAnglesf(-90.f, 90.f, 0.f); - - for (unsigned int v = 0; v < header.num_vertices; ++v) + namespace Loaders + { + void RegisterMD2() { - const MD2_Vertex& vert = vertices[v]; - NzVector3f position = rotationQuat * NzVector3f(vert.x*scale.x + translate.x, vert.y*scale.y + translate.y, vert.z*scale.z + translate.z); - - vertex->position = position; - vertex->normal = rotationQuat * md2Normals[vert.n]; - - vertex++; + MeshLoader::RegisterLoader(IsSupported, Check, Load); } - vertexMapper.Unmap(); - - subMesh->SetIndexBuffer(indexBuffer); - subMesh->SetMaterialIndex(0); - - subMesh->GenerateAABB(); - subMesh->GenerateTangents(); - - mesh->AddSubMesh(subMesh); - - if (parameters.center) - mesh->Recenter(); - - return true; + void UnregisterMD2() + { + MeshLoader::UnregisterLoader(IsSupported, Check, Load); + } } } - -void NzLoaders_MD2_Register() -{ - NzMeshLoader::RegisterLoader(IsSupported, Check, Load); -} - -void NzLoaders_MD2_Unregister() -{ - NzMeshLoader::UnregisterLoader(IsSupported, Check, Load); -} diff --git a/src/Nazara/Utility/Formats/MD2Loader.hpp b/src/Nazara/Utility/Formats/MD2Loader.hpp index 57dec180d..3fdafd4d0 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.hpp +++ b/src/Nazara/Utility/Formats/MD2Loader.hpp @@ -9,7 +9,13 @@ #include -void NzLoaders_MD2_Register(); -void NzLoaders_MD2_Unregister(); +namespace Nz +{ + namespace Loaders + { + void RegisterMD2(); + void UnregisterMD2(); + } +} #endif // NAZARA_LOADERS_MD2_HPP diff --git a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp index 2ff789575..513be6636 100644 --- a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp @@ -6,87 +6,93 @@ #include #include -namespace +namespace Nz { - bool IsSupported(const NzString& extension) + namespace { - return (extension == "md5anim"); - } - - nzTernary Check(NzInputStream& stream, const NzAnimationParams& parameters) - { - NazaraUnused(parameters); - - NzMD5AnimParser parser(stream); - return parser.Check(); - } - - bool Load(NzAnimation* animation, NzInputStream& stream, const NzAnimationParams& parameters) - { - ///TODO: Utiliser les paramètres - NzMD5AnimParser parser(stream); - - if (!parser.Parse()) + bool IsSupported(const String& extension) { - NazaraError("MD5Anim parser failed"); - return false; + return (extension == "md5anim"); } - const NzMD5AnimParser::Frame* frames = parser.GetFrames(); - unsigned int frameCount = parser.GetFrameCount(); - unsigned int frameRate = parser.GetFrameRate(); - const NzMD5AnimParser::Joint* joints = parser.GetJoints(); - unsigned int jointCount = parser.GetJointCount(); - - // À ce stade, nous sommes censés avoir assez d'informations pour créer l'animation - animation->CreateSkeletal(frameCount, jointCount); - - NzSequence sequence; - sequence.firstFrame = 0; - sequence.frameCount = frameCount; - sequence.frameRate = frameRate; - sequence.name = stream.GetPath().SubStringFrom(NAZARA_DIRECTORY_SEPARATOR, -1, true); - - animation->AddSequence(sequence); - - NzSequenceJoint* sequenceJoints = animation->GetSequenceJoints(); - - // Pour que le squelette soit correctement aligné, il faut appliquer un quaternion "de correction" aux joints à la base du squelette - NzQuaternionf rotationQuat = NzQuaternionf::RotationBetween(NzVector3f::UnitX(), NzVector3f::Forward()) * - NzQuaternionf::RotationBetween(NzVector3f::UnitZ(), NzVector3f::Up()); - - for (unsigned int i = 0; i < jointCount; ++i) + Ternary Check(InputStream& stream, const AnimationParams& parameters) { - int parent = joints[i].parent; - for (unsigned int j = 0; j < frameCount; ++j) + NazaraUnused(parameters); + + MD5AnimParser parser(stream); + return parser.Check(); + } + + bool Load(Animation* animation, InputStream& stream, const AnimationParams& parameters) + { + ///TODO: Utiliser les paramètres + MD5AnimParser parser(stream); + + if (!parser.Parse()) { - NzSequenceJoint& sequenceJoint = sequenceJoints[j*jointCount + i]; - - if (parent >= 0) - { - sequenceJoint.position = frames[j].joints[i].pos; - sequenceJoint.rotation = frames[j].joints[i].orient; - } - else - { - sequenceJoint.position = rotationQuat * frames[j].joints[i].pos; - sequenceJoint.rotation = rotationQuat * frames[j].joints[i].orient; - } - - sequenceJoint.scale.Set(1.f); + NazaraError("MD5Anim parser failed"); + return false; } + + const MD5AnimParser::Frame* frames = parser.GetFrames(); + unsigned int frameCount = parser.GetFrameCount(); + unsigned int frameRate = parser.GetFrameRate(); + const MD5AnimParser::Joint* joints = parser.GetJoints(); + unsigned int jointCount = parser.GetJointCount(); + + // À ce stade, nous sommes censés avoir assez d'informations pour créer l'animation + animation->CreateSkeletal(frameCount, jointCount); + + Sequence sequence; + sequence.firstFrame = 0; + sequence.frameCount = frameCount; + sequence.frameRate = frameRate; + sequence.name = stream.GetPath().SubStringFrom(NAZARA_DIRECTORY_SEPARATOR, -1, true); + + animation->AddSequence(sequence); + + SequenceJoint* sequenceJoints = animation->GetSequenceJoints(); + + // Pour que le squelette soit correctement aligné, il faut appliquer un quaternion "de correction" aux joints à la base du squelette + Quaternionf rotationQuat = Quaternionf::RotationBetween(Vector3f::UnitX(), Vector3f::Forward()) * + Quaternionf::RotationBetween(Vector3f::UnitZ(), Vector3f::Up()); + + for (unsigned int i = 0; i < jointCount; ++i) + { + int parent = joints[i].parent; + for (unsigned int j = 0; j < frameCount; ++j) + { + SequenceJoint& sequenceJoint = sequenceJoints[j*jointCount + i]; + + if (parent >= 0) + { + sequenceJoint.position = frames[j].joints[i].pos; + sequenceJoint.rotation = frames[j].joints[i].orient; + } + else + { + sequenceJoint.position = rotationQuat * frames[j].joints[i].pos; + sequenceJoint.rotation = rotationQuat * frames[j].joints[i].orient; + } + + sequenceJoint.scale.Set(1.f); + } + } + + return true; + } + } + + namespace Loaders + { + void RegisterMD5Anim() + { + AnimationLoader::RegisterLoader(IsSupported, Check, Load); } - return true; + void UnregisterMD5Anim() + { + AnimationLoader::UnregisterLoader(IsSupported, Check, Load); + } } } - -void NzLoaders_MD5Anim_Register() -{ - NzAnimationLoader::RegisterLoader(IsSupported, Check, Load); -} - -void NzLoaders_MD5Anim_Unregister() -{ - NzAnimationLoader::UnregisterLoader(IsSupported, Check, Load); -} diff --git a/src/Nazara/Utility/Formats/MD5AnimLoader.hpp b/src/Nazara/Utility/Formats/MD5AnimLoader.hpp index 642edb978..b1691ee6b 100644 --- a/src/Nazara/Utility/Formats/MD5AnimLoader.hpp +++ b/src/Nazara/Utility/Formats/MD5AnimLoader.hpp @@ -9,7 +9,13 @@ #include -void NzLoaders_MD5Anim_Register(); -void NzLoaders_MD5Anim_Unregister(); +namespace Nz +{ + namespace Loaders + { + void RegisterMD5Anim(); + void UnregisterMD5Anim(); + } +} #endif // NAZARA_LOADERS_MD5ANIM_HPP diff --git a/src/Nazara/Utility/Formats/MD5AnimParser.cpp b/src/Nazara/Utility/Formats/MD5AnimParser.cpp index f9723ed34..b53a8bd9b 100644 --- a/src/Nazara/Utility/Formats/MD5AnimParser.cpp +++ b/src/Nazara/Utility/Formats/MD5AnimParser.cpp @@ -13,509 +13,512 @@ #include #include -NzMD5AnimParser::NzMD5AnimParser(NzInputStream& stream) : -m_stream(stream), -m_keepLastLine(false), -m_frameIndex(0), -m_frameRate(0), -m_lineCount(0), -m_streamFlags(stream.GetStreamOptions()) +namespace Nz { - if ((m_streamFlags & nzStreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags | nzStreamOption_Text); -} - -NzMD5AnimParser::~NzMD5AnimParser() -{ - if ((m_streamFlags & nzStreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags); -} - -nzTernary NzMD5AnimParser::Check() -{ - if (Advance(false)) + MD5AnimParser::MD5AnimParser(InputStream& stream) : + m_stream(stream), + m_keepLastLine(false), + m_frameIndex(0), + m_frameRate(0), + m_lineCount(0), + m_streamFlags(stream.GetStreamOptions()) { - unsigned int version; - if (std::sscanf(&m_currentLine[0], " MD5Version %u", &version) == 1) - { - if (version == 10) - return nzTernary_True; - } + if ((m_streamFlags & StreamOption_Text) == 0) + m_stream.SetStreamOptions(m_streamFlags | StreamOption_Text); } - return nzTernary_False; -} - -unsigned int NzMD5AnimParser::GetAnimatedComponentCount() const -{ - return m_animatedComponents.size(); -} - -const NzMD5AnimParser::Frame* NzMD5AnimParser::GetFrames() const -{ - return m_frames.data(); -} - -unsigned int NzMD5AnimParser::GetFrameCount() const -{ - return m_frames.size(); -} - -unsigned int NzMD5AnimParser::GetFrameRate() const -{ - return m_frameRate; -} - -const NzMD5AnimParser::Joint* NzMD5AnimParser::GetJoints() const -{ - return m_joints.data(); -} - -unsigned int NzMD5AnimParser::GetJointCount() const -{ - return m_joints.size(); -} - -bool NzMD5AnimParser::Parse() -{ - while (Advance(false)) + MD5AnimParser::~MD5AnimParser() { - switch (m_currentLine[0]) + if ((m_streamFlags & StreamOption_Text) == 0) + m_stream.SetStreamOptions(m_streamFlags); + } + + Ternary MD5AnimParser::Check() + { + if (Advance(false)) { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - case 'M': // MD5Version - if (m_currentLine.GetWord(0) != "MD5Version") - UnrecognizedLine(); - break; - #endif - - case 'b': // baseframe/bounds - if (m_currentLine.StartsWith("baseframe {")) - { - if (!ParseBaseframe()) - { - Error("Failed to parse baseframe"); - return false; - } - } - else if (m_currentLine.StartsWith("bounds {")) - { - if (!ParseBounds()) - { - Error("Failed to parse bounds"); - return false; - } - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - break; - - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - case 'c': // commandline - if (m_currentLine.GetWord(0) != "commandline") - UnrecognizedLine(); - break; - #endif - - case 'f': + unsigned int version; + if (std::sscanf(&m_currentLine[0], " MD5Version %u", &version) == 1) { - unsigned int index; - if (std::sscanf(&m_currentLine[0], "frame %u {", &index) == 1) - { - if (m_frameIndex != index) - { - Error("Unexpected frame index (expected " + NzString::Number(m_frameIndex) + ", got " + NzString::Number(index) + ')'); - return false; - } - - if (!ParseFrame()) - { - Error("Failed to parse frame"); - return false; - } - - m_frameIndex++; - } - else if (std::sscanf(&m_currentLine[0], "frameRate %u", &m_frameRate) != 1) - { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); - #endif - } - break; + if (version == 10) + return Ternary_True; } - - case 'h': // hierarchy - if (m_currentLine.StartsWith("hierarchy {")) - { - if (!ParseHierarchy()) - { - Error("Failed to parse hierarchy"); - return false; - } - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - break; - - case 'n': // num[Frames/Joints] - { - unsigned int count; - if (std::sscanf(&m_currentLine[0], "numAnimatedComponents %u", &count) == 1) - { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - if (!m_animatedComponents.empty()) - Warning("Animated components count is already defined"); - #endif - - m_animatedComponents.resize(count); - } - else if (std::sscanf(&m_currentLine[0], "numFrames %u", &count) == 1) - { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - if (!m_frames.empty()) - Warning("Frame count is already defined"); - #endif - - m_frames.resize(count); - } - else if (std::sscanf(&m_currentLine[0], "numJoints %u", &count) == 1) - { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - if (!m_joints.empty()) - Warning("Joint count is already defined"); - #endif - - m_joints.resize(count); - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - break; - } - - default: - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); - #endif - break; } + + return Ternary_False; } - unsigned int frameCount = m_frames.size(); - if (frameCount == 0) + unsigned int MD5AnimParser::GetAnimatedComponentCount() const { - NazaraError("Frame count is invalid or missing"); - return false; + return m_animatedComponents.size(); } - unsigned int jointCount = m_joints.size(); - if (jointCount == 0) + const MD5AnimParser::Frame* MD5AnimParser::GetFrames() const { - NazaraError("Joint count is invalid or missing"); - return false; + return m_frames.data(); } - if (m_frameIndex != frameCount) + unsigned int MD5AnimParser::GetFrameCount() const { - NazaraError("Missing frame infos: [" + NzString::Number(m_frameIndex) + ',' + NzString::Number(frameCount) + ']'); - return false; + return m_frames.size(); } - if (m_frameRate == 0) + unsigned int MD5AnimParser::GetFrameRate() const { - NazaraWarning("Framerate is either invalid or missing, assuming a default value of 24"); - m_frameRate = 24; + return m_frameRate; } - return true; -} - -bool NzMD5AnimParser::Advance(bool required) -{ - if (!m_keepLastLine) + const MD5AnimParser::Joint* MD5AnimParser::GetJoints() const { - do + return m_joints.data(); + } + + unsigned int MD5AnimParser::GetJointCount() const + { + return m_joints.size(); + } + + bool MD5AnimParser::Parse() + { + while (Advance(false)) { - if (m_stream.EndOfStream()) + switch (m_currentLine[0]) { - if (required) - Error("Incomplete MD5 file"); + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + case 'M': // MD5Version + if (m_currentLine.GetWord(0) != "MD5Version") + UnrecognizedLine(); + break; + #endif + case 'b': // baseframe/bounds + if (m_currentLine.StartsWith("baseframe {")) + { + if (!ParseBaseframe()) + { + Error("Failed to parse baseframe"); + return false; + } + } + else if (m_currentLine.StartsWith("bounds {")) + { + if (!ParseBounds()) + { + Error("Failed to parse bounds"); + return false; + } + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + break; + + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + case 'c': // commandline + if (m_currentLine.GetWord(0) != "commandline") + UnrecognizedLine(); + break; + #endif + + case 'f': + { + unsigned int index; + if (std::sscanf(&m_currentLine[0], "frame %u {", &index) == 1) + { + if (m_frameIndex != index) + { + Error("Unexpected frame index (expected " + String::Number(m_frameIndex) + ", got " + String::Number(index) + ')'); + return false; + } + + if (!ParseFrame()) + { + Error("Failed to parse frame"); + return false; + } + + m_frameIndex++; + } + else if (std::sscanf(&m_currentLine[0], "frameRate %u", &m_frameRate) != 1) + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + UnrecognizedLine(); + #endif + } + break; + } + + case 'h': // hierarchy + if (m_currentLine.StartsWith("hierarchy {")) + { + if (!ParseHierarchy()) + { + Error("Failed to parse hierarchy"); + return false; + } + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + break; + + case 'n': // num[Frames/Joints] + { + unsigned int count; + if (std::sscanf(&m_currentLine[0], "numAnimatedComponents %u", &count) == 1) + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + if (!m_animatedComponents.empty()) + Warning("Animated components count is already defined"); + #endif + + m_animatedComponents.resize(count); + } + else if (std::sscanf(&m_currentLine[0], "numFrames %u", &count) == 1) + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + if (!m_frames.empty()) + Warning("Frame count is already defined"); + #endif + + m_frames.resize(count); + } + else if (std::sscanf(&m_currentLine[0], "numJoints %u", &count) == 1) + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + if (!m_joints.empty()) + Warning("Joint count is already defined"); + #endif + + m_joints.resize(count); + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + break; + } + + default: + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + UnrecognizedLine(); + #endif + break; + } + } + + unsigned int frameCount = m_frames.size(); + if (frameCount == 0) + { + NazaraError("Frame count is invalid or missing"); + return false; + } + + unsigned int jointCount = m_joints.size(); + if (jointCount == 0) + { + NazaraError("Joint count is invalid or missing"); + return false; + } + + if (m_frameIndex != frameCount) + { + NazaraError("Missing frame infos: [" + String::Number(m_frameIndex) + ',' + String::Number(frameCount) + ']'); + return false; + } + + if (m_frameRate == 0) + { + NazaraWarning("Framerate is either invalid or missing, assuming a default value of 24"); + m_frameRate = 24; + } + + return true; + } + + bool MD5AnimParser::Advance(bool required) + { + if (!m_keepLastLine) + { + do + { + if (m_stream.EndOfStream()) + { + if (required) + Error("Incomplete MD5 file"); + + return false; + } + + m_lineCount++; + + m_currentLine = m_stream.ReadLine(); + m_currentLine = m_currentLine.SubStringTo("//"); // On ignore les commentaires + m_currentLine.Simplify(); // Pour un traitement plus simple + } + while (m_currentLine.IsEmpty()); + } + else + m_keepLastLine = false; + + return true; + } + + void MD5AnimParser::Error(const String& message) + { + NazaraError(message + " at line #" + String::Number(m_lineCount)); + } + + bool MD5AnimParser::ParseBaseframe() + { + unsigned int jointCount = m_joints.size(); + if (jointCount == 0) + { + Error("Joint count is invalid or missing"); + return false; + } + + for (unsigned int i = 0; i < jointCount; ++i) + { + if (!Advance()) + return false; + + if (std::sscanf(&m_currentLine[0], "( %f %f %f ) ( %f %f %f )", &m_joints[i].bindPos.x, &m_joints[i].bindPos.y, &m_joints[i].bindPos.z, + &m_joints[i].bindOrient.x, &m_joints[i].bindOrient.y, &m_joints[i].bindOrient.z) != 6) + { + UnrecognizedLine(true); return false; } - - m_lineCount++; - - m_currentLine = m_stream.ReadLine(); - m_currentLine = m_currentLine.SubStringTo("//"); // On ignore les commentaires - m_currentLine.Simplify(); // Pour un traitement plus simple } - while (m_currentLine.IsEmpty()); - } - else - m_keepLastLine = false; - return true; -} - -void NzMD5AnimParser::Error(const NzString& message) -{ - NazaraError(message + " at line #" + NzString::Number(m_lineCount)); -} - -bool NzMD5AnimParser::ParseBaseframe() -{ - unsigned int jointCount = m_joints.size(); - if (jointCount == 0) - { - Error("Joint count is invalid or missing"); - return false; - } - - for (unsigned int i = 0; i < jointCount; ++i) - { if (!Advance()) return false; - if (std::sscanf(&m_currentLine[0], "( %f %f %f ) ( %f %f %f )", &m_joints[i].bindPos.x, &m_joints[i].bindPos.y, &m_joints[i].bindPos.z, - &m_joints[i].bindOrient.x, &m_joints[i].bindOrient.y, &m_joints[i].bindOrient.z) != 6) + if (m_currentLine != '}') { - UnrecognizedLine(true); - return false; + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + Warning("Bounds braces closing not found"); + #endif + + // On tente de survivre à l'erreur + m_keepLastLine = true; } + + return true; } - if (!Advance()) - return false; - - if (m_currentLine != '}') + bool MD5AnimParser::ParseBounds() { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - Warning("Bounds braces closing not found"); - #endif - - // On tente de survivre à l'erreur - m_keepLastLine = true; - } - - return true; -} - -bool NzMD5AnimParser::ParseBounds() -{ - unsigned int frameCount = m_frames.size(); - if (frameCount == 0) - { - Error("Frame count is invalid or missing"); - return false; - } - - for (unsigned int i = 0; i < frameCount; ++i) - { - if (!Advance()) - return false; - - NzVector3f min, max; - if (std::sscanf(&m_currentLine[0], "( %f %f %f ) ( %f %f %f )", &min.x, &min.y, &min.z, &max.x, &max.y, &max.z) != 6) + unsigned int frameCount = m_frames.size(); + if (frameCount == 0) { - UnrecognizedLine(true); + Error("Frame count is invalid or missing"); return false; } - m_frames[i].bounds.Set(min, max); - } - - if (!Advance()) - return false; - - if (m_currentLine != '}') - { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - Warning("Bounds braces closing not found"); - #endif - - // On tente de survivre à l'erreur - m_keepLastLine = true; - } - - return true; -} - -bool NzMD5AnimParser::ParseFrame() -{ - unsigned int animatedComponentsCount = m_animatedComponents.size(); - if (animatedComponentsCount == 0) - { - Error("Animated components count is missing or invalid"); - return false; - } - - unsigned int jointCount = m_joints.size(); - if (jointCount == 0) - { - Error("Joint count is invalid or missing"); - return false; - } - - NzString line; - - unsigned int count = 0; - do - { - if (!Advance()) - return false; - - unsigned int index = 0; - unsigned int size = m_currentLine.GetSize(); - do + for (unsigned int i = 0; i < frameCount; ++i) { - float f; - int read; - if (std::sscanf(&m_currentLine[index], "%f%n", &f, &read) != 1) + if (!Advance()) + return false; + + Vector3f min, max; + if (std::sscanf(&m_currentLine[0], "( %f %f %f ) ( %f %f %f )", &min.x, &min.y, &min.z, &max.x, &max.y, &max.z) != 6) { UnrecognizedLine(true); return false; } - index += read; - - m_animatedComponents[count] = f; - - count++; + m_frames[i].bounds.Set(min, max); } - while (index < size); - } - while (count < animatedComponentsCount); - m_frames[m_frameIndex].joints.resize(jointCount); - - for (unsigned int i = 0; i < jointCount; ++i) - { - NzQuaternionf jointOrient = m_joints[i].bindOrient; - NzVector3f jointPos = m_joints[i].bindPos; - unsigned int j = 0; - - if (m_joints[i].flags & 1) // Px - jointPos.x = m_animatedComponents[m_joints[i].index + j++]; - - if (m_joints[i].flags & 2) // Py - jointPos.y = m_animatedComponents[m_joints[i].index + j++]; - - if (m_joints[i].flags & 4) // Pz - jointPos.z = m_animatedComponents[m_joints[i].index + j++]; - - if (m_joints[i].flags & 8) // Qx - jointOrient.x = m_animatedComponents[m_joints[i].index + j++]; - - if (m_joints[i].flags & 16) // Qy - jointOrient.y = m_animatedComponents[m_joints[i].index + j++]; - - if (m_joints[i].flags & 32) // Qz - jointOrient.z = m_animatedComponents[m_joints[i].index + j++]; - - jointOrient.ComputeW(); - - m_frames[m_frameIndex].joints[i].orient = jointOrient; - m_frames[m_frameIndex].joints[i].pos = jointPos; - } - - if (!Advance(false)) - return true; - - if (m_currentLine != '}') - { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - Warning("Hierarchy braces closing not found"); - #endif - - // On tente de survivre à l'erreur - m_keepLastLine = true; - } - - return true; -} - -bool NzMD5AnimParser::ParseHierarchy() -{ - unsigned int jointCount = m_joints.size(); - if (jointCount == 0) - { - Error("Joint count is invalid or missing"); - return false; - } - - for (unsigned int i = 0; i < jointCount; ++i) - { if (!Advance()) return false; - unsigned int pos = m_currentLine.Find(' '); - if (pos == NzString::npos) + if (m_currentLine != '}') { - UnrecognizedLine(true); + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + Warning("Bounds braces closing not found"); + #endif + + // On tente de survivre à l'erreur + m_keepLastLine = true; + } + + return true; + } + + bool MD5AnimParser::ParseFrame() + { + unsigned int animatedComponentsCount = m_animatedComponents.size(); + if (animatedComponentsCount == 0) + { + Error("Animated components count is missing or invalid"); return false; } - if (pos >= 64) + unsigned int jointCount = m_joints.size(); + if (jointCount == 0) { - NazaraError("Joint name is too long (>= 64 characters)"); + Error("Joint count is invalid or missing"); return false; } - char name[64]; - if (std::sscanf(&m_currentLine[0], "%63s %d %u %u", &name[0], &m_joints[i].parent, &m_joints[i].flags, &m_joints[i].index) != 4) - { - UnrecognizedLine(true); - return false; - } + String line; - m_joints[i].name = name; - m_joints[i].name.Trim('"'); - - int parent = m_joints[i].parent; - if (parent >= 0) + unsigned int count = 0; + do { - if (static_cast(parent) >= jointCount) + if (!Advance()) + return false; + + unsigned int index = 0; + unsigned int size = m_currentLine.GetSize(); + do { - Error("Joint's parent is out of bounds (" + NzString::Number(parent) + " >= " + NzString::Number(jointCount) + ')'); + float f; + int read; + if (std::sscanf(&m_currentLine[index], "%f%n", &f, &read) != 1) + { + UnrecognizedLine(true); + return false; + } + + index += read; + + m_animatedComponents[count] = f; + + count++; + } + while (index < size); + } + while (count < animatedComponentsCount); + + m_frames[m_frameIndex].joints.resize(jointCount); + + for (unsigned int i = 0; i < jointCount; ++i) + { + Quaternionf jointOrient = m_joints[i].bindOrient; + Vector3f jointPos = m_joints[i].bindPos; + unsigned int j = 0; + + if (m_joints[i].flags & 1) // Px + jointPos.x = m_animatedComponents[m_joints[i].index + j++]; + + if (m_joints[i].flags & 2) // Py + jointPos.y = m_animatedComponents[m_joints[i].index + j++]; + + if (m_joints[i].flags & 4) // Pz + jointPos.z = m_animatedComponents[m_joints[i].index + j++]; + + if (m_joints[i].flags & 8) // Qx + jointOrient.x = m_animatedComponents[m_joints[i].index + j++]; + + if (m_joints[i].flags & 16) // Qy + jointOrient.y = m_animatedComponents[m_joints[i].index + j++]; + + if (m_joints[i].flags & 32) // Qz + jointOrient.z = m_animatedComponents[m_joints[i].index + j++]; + + jointOrient.ComputeW(); + + m_frames[m_frameIndex].joints[i].orient = jointOrient; + m_frames[m_frameIndex].joints[i].pos = jointPos; + } + + if (!Advance(false)) + return true; + + if (m_currentLine != '}') + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + Warning("Hierarchy braces closing not found"); + #endif + + // On tente de survivre à l'erreur + m_keepLastLine = true; + } + + return true; + } + + bool MD5AnimParser::ParseHierarchy() + { + unsigned int jointCount = m_joints.size(); + if (jointCount == 0) + { + Error("Joint count is invalid or missing"); + return false; + } + + for (unsigned int i = 0; i < jointCount; ++i) + { + if (!Advance()) + return false; + + unsigned int pos = m_currentLine.Find(' '); + if (pos == String::npos) + { + UnrecognizedLine(true); return false; } + + if (pos >= 64) + { + NazaraError("Joint name is too long (>= 64 characters)"); + return false; + } + + char name[64]; + if (std::sscanf(&m_currentLine[0], "%63s %d %u %u", &name[0], &m_joints[i].parent, &m_joints[i].flags, &m_joints[i].index) != 4) + { + UnrecognizedLine(true); + return false; + } + + m_joints[i].name = name; + m_joints[i].name.Trim('"'); + + int parent = m_joints[i].parent; + if (parent >= 0) + { + if (static_cast(parent) >= jointCount) + { + Error("Joint's parent is out of bounds (" + String::Number(parent) + " >= " + String::Number(jointCount) + ')'); + return false; + } + } } + + if (!Advance()) + return false; + + if (m_currentLine != '}') + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + Warning("Hierarchy braces closing not found"); + #endif + + // On tente de survivre à l'erreur + m_keepLastLine = true; + } + + return true; } - if (!Advance()) - return false; - - if (m_currentLine != '}') + void MD5AnimParser::Warning(const String& message) { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - Warning("Hierarchy braces closing not found"); - #endif - - // On tente de survivre à l'erreur - m_keepLastLine = true; + NazaraWarning(message + " at line #" + String::Number(m_lineCount)); } - return true; -} + void MD5AnimParser::UnrecognizedLine(bool error) + { + String message = "Unrecognized \"" + m_currentLine + '"'; -void NzMD5AnimParser::Warning(const NzString& message) -{ - NazaraWarning(message + " at line #" + NzString::Number(m_lineCount)); -} - -void NzMD5AnimParser::UnrecognizedLine(bool error) -{ - NzString message = "Unrecognized \"" + m_currentLine + '"'; - - if (error) - Error(message); - else - Warning(message); + if (error) + Error(message); + else + Warning(message); + } } diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index 526904460..262892aa8 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -11,293 +11,299 @@ #include #include -namespace +namespace Nz { - bool IsSupported(const NzString& extension) + namespace { - return (extension == "md5mesh"); - } - - nzTernary Check(NzInputStream& stream, const NzMeshParams& parameters) - { - NazaraUnused(parameters); - - NzMD5MeshParser parser(stream); - return parser.Check(); - } - - bool Load(NzMesh* mesh, NzInputStream& stream, const NzMeshParams& parameters) - { - NzMD5MeshParser parser(stream); - if (!parser.Parse()) + bool IsSupported(const String& extension) { - NazaraError("MD5Mesh parser failed"); - return false; + return (extension == "md5mesh"); } - // Pour que le squelette soit correctement aligné, il faut appliquer un quaternion "de correction" aux joints à la base du squelette - NzQuaternionf rotationQuat = NzQuaternionf::RotationBetween(NzVector3f::UnitX(), NzVector3f::Forward()) * - NzQuaternionf::RotationBetween(NzVector3f::UnitZ(), NzVector3f::Up()); - - NzString baseDir = stream.GetDirectory(); - - // Le hellknight de Doom 3 fait ~120 unités, et il est dit qu'il fait trois mètres - // Nous réduisons donc la taille générale des fichiers MD5 de 1/40 - NzVector3f scale(parameters.scale/40.f); - - const NzMD5MeshParser::Joint* joints = parser.GetJoints(); - const NzMD5MeshParser::Mesh* meshes = parser.GetMeshes(); - unsigned int jointCount = parser.GetJointCount(); - unsigned int meshCount = parser.GetMeshCount(); - - if (parameters.animated) + Ternary Check(InputStream& stream, const MeshParams& parameters) { - mesh->CreateSkeletal(jointCount); + NazaraUnused(parameters); - NzSkeleton* skeleton = mesh->GetSkeleton(); - for (unsigned int i = 0; i < jointCount; ++i) - { - NzJoint* joint = skeleton->GetJoint(i); - - int parent = joints[i].parent; - if (parent >= 0) - joint->SetParent(skeleton->GetJoint(parent)); - - joint->SetName(joints[i].name); - - NzMatrix4f bindMatrix; - - if (parent >= 0) - bindMatrix.MakeTransform(joints[i].bindPos, joints[i].bindOrient); - else - bindMatrix.MakeTransform(rotationQuat * joints[i].bindPos, rotationQuat * joints[i].bindOrient); - - joint->SetInverseBindMatrix(bindMatrix.InverseAffine()); - } - - mesh->SetMaterialCount(meshCount); - for (unsigned int i = 0; i < meshCount; ++i) - { - const NzMD5MeshParser::Mesh& md5Mesh = meshes[i]; - - unsigned int indexCount = md5Mesh.triangles.size()*3; - unsigned int vertexCount = md5Mesh.vertices.size(); - - bool largeIndices = (vertexCount > std::numeric_limits::max()); - - NzIndexBufferRef indexBuffer = NzIndexBuffer::New(largeIndices, indexCount, parameters.storage); - NzVertexBufferRef vertexBuffer = NzVertexBuffer::New(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent_Skinning), vertexCount, parameters.storage, nzBufferUsage_Static); - - // Index buffer - NzIndexMapper indexMapper(indexBuffer, nzBufferAccess_DiscardAndWrite); - - // Le format définit un set de triangles nous permettant de retrouver facilement les indices - // Cependant les sommets des triangles ne sont pas spécifiés dans le même ordre que ceux du moteur - // (On parle ici de winding) - unsigned int index = 0; - for (const NzMD5MeshParser::Triangle& triangle : md5Mesh.triangles) - { - // On les respécifie dans le bon ordre (inversion du winding) - indexMapper.Set(index++, triangle.x); - indexMapper.Set(index++, triangle.z); - indexMapper.Set(index++, triangle.y); - } - - indexMapper.Unmap(); - - if (parameters.optimizeIndexBuffers) - indexBuffer->Optimize(); - - // Vertex buffer - struct Weight - { - float bias; - unsigned int jointIndex; - }; - - std::vector tempWeights; - - NzBufferMapper vertexMapper(vertexBuffer, nzBufferAccess_WriteOnly); - NzSkeletalMeshVertex* vertices = static_cast(vertexMapper.GetPointer()); - for (const NzMD5MeshParser::Vertex& vertex : md5Mesh.vertices) - { - // Skinning MD5 (Formule d'Id Tech) - NzVector3f finalPos(NzVector3f::Zero()); - - // On stocke tous les poids dans le tableau temporaire en même temps qu'on calcule la position finale du sommet. - tempWeights.resize(vertex.weightCount); - for (unsigned int j = 0; j < vertex.weightCount; ++j) - { - const NzMD5MeshParser::Weight& weight = md5Mesh.weights[vertex.startWeight + j]; - const NzMD5MeshParser::Joint& joint = joints[weight.joint]; - - finalPos += (joint.bindPos + joint.bindOrient*weight.pos) * weight.bias; - - // Avant d'ajouter les poids, il faut s'assurer qu'il n'y en ait pas plus que le maximum supporté - // et dans le cas contraire, garder les poids les plus importants et les renormaliser - tempWeights[j] = {weight.bias, weight.joint}; - } - - // Avons nous plus de poids que le moteur ne peut en supporter ? - unsigned int weightCount = vertex.weightCount; - if (weightCount > NAZARA_UTILITY_SKINNING_MAX_WEIGHTS) - { - // Pour augmenter la qualité du skinning tout en ne gardant que X poids, on ne garde que les poids - // les plus importants, ayant le plus d'impact sur le sommet final - std::sort(tempWeights.begin(), tempWeights.end(), [] (const Weight& a, const Weight& b) -> bool { - return a.bias > b.bias; - }); - - // Sans oublier bien sûr de renormaliser les poids (que leur somme soit 1) - float weightSum = 0.f; - for (unsigned int j = 0; j < NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; ++j) - weightSum += tempWeights[j].bias; - - for (unsigned int j = 0; j < NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; ++j) - tempWeights[j].bias /= weightSum; - - weightCount = NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; - } - - vertices->weightCount = weightCount; - for (unsigned int j = 0; j < NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; ++j) - { - if (j < weightCount) - { - // On donne une valeur aux poids présents - vertices->weights[j] = tempWeights[j].bias; - vertices->jointIndexes[j] = tempWeights[j].jointIndex; - } - else - { - // Et un poids de 0 sur le joint 0 pour les autres (nécessaire pour le GPU Skinning) - // La raison est que le GPU ne tiendra pas compte du nombre de poids pour des raisons de performances. - vertices->weights[j] = 0.f; - vertices->jointIndexes[j] = 0; - } - } - - vertices->position = finalPos; - vertices->uv.Set(vertex.uv.x, (parameters.flipUVs) ? 1.f - vertex.uv.y : vertex.uv.y); // Inversion des UV si demandé - vertices++; - } - - vertexMapper.Unmap(); - - // Material - mesh->SetMaterial(i, baseDir + md5Mesh.shader); - - // Submesh - NzSkeletalMeshRef subMesh = NzSkeletalMesh::New(mesh); - subMesh->Create(vertexBuffer); - - subMesh->SetIndexBuffer(indexBuffer); - subMesh->GenerateNormalsAndTangents(); - subMesh->SetMaterialIndex(i); - subMesh->SetPrimitiveMode(nzPrimitiveMode_TriangleList); - - mesh->AddSubMesh(subMesh); - - // Animation - // Il est peut-être éventuellement possible que la probabilité que l'animation ait le même nom soit non-nulle. - NzString path = stream.GetPath(); - if (!path.IsEmpty()) - { - path.Replace(".md5mesh", ".md5anim", -8, NzString::CaseInsensitive); - if (NzFile::Exists(path)) - mesh->SetAnimation(path); - } - } + MD5MeshParser parser(stream); + return parser.Check(); } - else + + bool Load(Mesh* mesh, InputStream& stream, const MeshParams& parameters) { - if (!mesh->CreateStatic()) // Ne devrait jamais échouer + MD5MeshParser parser(stream); + if (!parser.Parse()) { - NazaraInternalError("Failed to create mesh"); + NazaraError("MD5Mesh parser failed"); return false; } - mesh->SetMaterialCount(meshCount); - for (unsigned int i = 0; i < meshCount; ++i) + // Pour que le squelette soit correctement aligné, il faut appliquer un quaternion "de correction" aux joints à la base du squelette + Quaternionf rotationQuat = Quaternionf::RotationBetween(Vector3f::UnitX(), Vector3f::Forward()) * + Quaternionf::RotationBetween(Vector3f::UnitZ(), Vector3f::Up()); + + String baseDir = stream.GetDirectory(); + + // Le hellknight de Doom 3 fait ~120 unités, et il est dit qu'il fait trois mètres + // Nous réduisons donc la taille générale des fichiers MD5 de 1/40 + Vector3f scale(parameters.scale/40.f); + + const MD5MeshParser::Joint* joints = parser.GetJoints(); + const MD5MeshParser::Mesh* meshes = parser.GetMeshes(); + unsigned int jointCount = parser.GetJointCount(); + unsigned int meshCount = parser.GetMeshCount(); + + if (parameters.animated) { - const NzMD5MeshParser::Mesh& md5Mesh = meshes[i]; - unsigned int indexCount = md5Mesh.triangles.size()*3; - unsigned int vertexCount = md5Mesh.vertices.size(); + mesh->CreateSkeletal(jointCount); - // Index buffer - bool largeIndices = (vertexCount > std::numeric_limits::max()); - - NzIndexBufferRef indexBuffer = NzIndexBuffer::New(largeIndices, indexCount, parameters.storage); - - NzIndexMapper indexMapper(indexBuffer, nzBufferAccess_DiscardAndWrite); - NzIndexIterator index = indexMapper.begin(); - - for (const NzMD5MeshParser::Triangle& triangle : md5Mesh.triangles) + Skeleton* skeleton = mesh->GetSkeleton(); + for (unsigned int i = 0; i < jointCount; ++i) { - // On les respécifie dans le bon ordre - *index++ = triangle.x; - *index++ = triangle.z; - *index++ = triangle.y; + Joint* joint = skeleton->GetJoint(i); + + int parent = joints[i].parent; + if (parent >= 0) + joint->SetParent(skeleton->GetJoint(parent)); + + joint->SetName(joints[i].name); + + Matrix4f bindMatrix; + + if (parent >= 0) + bindMatrix.MakeTransform(joints[i].bindPos, joints[i].bindOrient); + else + bindMatrix.MakeTransform(rotationQuat * joints[i].bindPos, rotationQuat * joints[i].bindOrient); + + joint->SetInverseBindMatrix(bindMatrix.InverseAffine()); } - indexMapper.Unmap(); - // Vertex buffer - NzVertexBufferRef vertexBuffer = NzVertexBuffer::New(NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage); - NzBufferMapper vertexMapper(vertexBuffer, nzBufferAccess_WriteOnly); - - NzMeshVertex* vertex = reinterpret_cast(vertexMapper.GetPointer()); - for (const NzMD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices) + mesh->SetMaterialCount(meshCount); + for (unsigned int i = 0; i < meshCount; ++i) { - // Skinning MD5 (Formule d'Id Tech) - NzVector3f finalPos(NzVector3f::Zero()); - for (unsigned int j = 0; j < md5Vertex.weightCount; ++j) - { - const NzMD5MeshParser::Weight& weight = md5Mesh.weights[md5Vertex.startWeight + j]; - const NzMD5MeshParser::Joint& joint = joints[weight.joint]; + const MD5MeshParser::Mesh& md5Mesh = meshes[i]; - finalPos += (joint.bindPos + joint.bindOrient*weight.pos) * weight.bias; + unsigned int indexCount = md5Mesh.triangles.size()*3; + unsigned int vertexCount = md5Mesh.vertices.size(); + + bool largeIndices = (vertexCount > std::numeric_limits::max()); + + IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, indexCount, parameters.storage); + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent_Skinning), vertexCount, parameters.storage, BufferUsage_Static); + + // Index buffer + IndexMapper indexMapper(indexBuffer, BufferAccess_DiscardAndWrite); + + // Le format définit un set de triangles nous permettant de retrouver facilement les indices + // Cependant les sommets des triangles ne sont pas spécifiés dans le même ordre que ceux du moteur + // (On parle ici de winding) + unsigned int index = 0; + for (const MD5MeshParser::Triangle& triangle : md5Mesh.triangles) + { + // On les respécifie dans le bon ordre (inversion du winding) + indexMapper.Set(index++, triangle.x); + indexMapper.Set(index++, triangle.z); + indexMapper.Set(index++, triangle.y); } - // On retourne le modèle dans le bon sens - vertex->position = scale * (rotationQuat * finalPos); - vertex->uv.Set(md5Vertex.uv.x, (parameters.flipUVs) ? 1.f - md5Vertex.uv.y : md5Vertex.uv.y); // Inversion des UV si demandé - vertex++; + indexMapper.Unmap(); + + if (parameters.optimizeIndexBuffers) + indexBuffer->Optimize(); + + // Vertex buffer + struct Weight + { + float bias; + unsigned int jointIndex; + }; + + std::vector tempWeights; + + BufferMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); + SkeletalMeshVertex* vertices = static_cast(vertexMapper.GetPointer()); + for (const MD5MeshParser::Vertex& vertex : md5Mesh.vertices) + { + // Skinning MD5 (Formule d'Id Tech) + Vector3f finalPos(Vector3f::Zero()); + + // On stocke tous les poids dans le tableau temporaire en même temps qu'on calcule la position finale du sommet. + tempWeights.resize(vertex.weightCount); + for (unsigned int j = 0; j < vertex.weightCount; ++j) + { + const MD5MeshParser::Weight& weight = md5Mesh.weights[vertex.startWeight + j]; + const MD5MeshParser::Joint& joint = joints[weight.joint]; + + finalPos += (joint.bindPos + joint.bindOrient*weight.pos) * weight.bias; + + // Avant d'ajouter les poids, il faut s'assurer qu'il n'y en ait pas plus que le maximum supporté + // et dans le cas contraire, garder les poids les plus importants et les renormaliser + tempWeights[j] = {weight.bias, weight.joint}; + } + + // Avons nous plus de poids que le moteur ne peut en supporter ? + unsigned int weightCount = vertex.weightCount; + if (weightCount > NAZARA_UTILITY_SKINNING_MAX_WEIGHTS) + { + // Pour augmenter la qualité du skinning tout en ne gardant que X poids, on ne garde que les poids + // les plus importants, ayant le plus d'impact sur le sommet final + std::sort(tempWeights.begin(), tempWeights.end(), [] (const Weight& a, const Weight& b) -> bool { + return a.bias > b.bias; + }); + + // Sans oublier bien sûr de renormaliser les poids (que leur somme soit 1) + float weightSum = 0.f; + for (unsigned int j = 0; j < NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; ++j) + weightSum += tempWeights[j].bias; + + for (unsigned int j = 0; j < NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; ++j) + tempWeights[j].bias /= weightSum; + + weightCount = NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; + } + + vertices->weightCount = weightCount; + for (unsigned int j = 0; j < NAZARA_UTILITY_SKINNING_MAX_WEIGHTS; ++j) + { + if (j < weightCount) + { + // On donne une valeur aux poids présents + vertices->weights[j] = tempWeights[j].bias; + vertices->jointIndexes[j] = tempWeights[j].jointIndex; + } + else + { + // Et un poids de 0 sur le joint 0 pour les autres (nécessaire pour le GPU Skinning) + // La raison est que le GPU ne tiendra pas compte du nombre de poids pour des raisons de performances. + vertices->weights[j] = 0.f; + vertices->jointIndexes[j] = 0; + } + } + + vertices->position = finalPos; + vertices->uv.Set(vertex.uv.x, (parameters.flipUVs) ? 1.f - vertex.uv.y : vertex.uv.y); // Inversion des UV si demandé + vertices++; + } + + vertexMapper.Unmap(); + + // Material + mesh->SetMaterial(i, baseDir + md5Mesh.shader); + + // Submesh + SkeletalMeshRef subMesh = SkeletalMesh::New(mesh); + subMesh->Create(vertexBuffer); + + subMesh->SetIndexBuffer(indexBuffer); + subMesh->GenerateNormalsAndTangents(); + subMesh->SetMaterialIndex(i); + subMesh->SetPrimitiveMode(PrimitiveMode_TriangleList); + + mesh->AddSubMesh(subMesh); + + // Animation + // Il est peut-être éventuellement possible que la probabilité que l'animation ait le même nom soit non-nulle. + String path = stream.GetPath(); + if (!path.IsEmpty()) + { + path.Replace(".md5mesh", ".md5anim", -8, String::CaseInsensitive); + if (File::Exists(path)) + mesh->SetAnimation(path); + } + } + } + else + { + if (!mesh->CreateStatic()) // Ne devrait jamais échouer + { + NazaraInternalError("Failed to create mesh"); + return false; } - vertexMapper.Unmap(); + mesh->SetMaterialCount(meshCount); + for (unsigned int i = 0; i < meshCount; ++i) + { + const MD5MeshParser::Mesh& md5Mesh = meshes[i]; + unsigned int indexCount = md5Mesh.triangles.size()*3; + unsigned int vertexCount = md5Mesh.vertices.size(); - // Submesh - NzStaticMeshRef subMesh = NzStaticMesh::New(mesh); - subMesh->Create(vertexBuffer); + // Index buffer + bool largeIndices = (vertexCount > std::numeric_limits::max()); - if (parameters.optimizeIndexBuffers) - indexBuffer->Optimize(); + IndexBufferRef indexBuffer = IndexBuffer::New(largeIndices, indexCount, parameters.storage); - subMesh->SetIndexBuffer(indexBuffer); - subMesh->GenerateAABB(); - subMesh->GenerateNormalsAndTangents(); - subMesh->SetMaterialIndex(i); + IndexMapper indexMapper(indexBuffer, BufferAccess_DiscardAndWrite); + IndexIterator index = indexMapper.begin(); - mesh->AddSubMesh(subMesh); + for (const MD5MeshParser::Triangle& triangle : md5Mesh.triangles) + { + // On les respécifie dans le bon ordre + *index++ = triangle.x; + *index++ = triangle.z; + *index++ = triangle.y; + } + indexMapper.Unmap(); - // Material - mesh->SetMaterial(i, baseDir + md5Mesh.shader); + // Vertex buffer + VertexBufferRef vertexBuffer = VertexBuffer::New(VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent), vertexCount, parameters.storage); + BufferMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); + + MeshVertex* vertex = reinterpret_cast(vertexMapper.GetPointer()); + for (const MD5MeshParser::Vertex& md5Vertex : md5Mesh.vertices) + { + // Skinning MD5 (Formule d'Id Tech) + Vector3f finalPos(Vector3f::Zero()); + for (unsigned int j = 0; j < md5Vertex.weightCount; ++j) + { + const MD5MeshParser::Weight& weight = md5Mesh.weights[md5Vertex.startWeight + j]; + const MD5MeshParser::Joint& joint = joints[weight.joint]; + + finalPos += (joint.bindPos + joint.bindOrient*weight.pos) * weight.bias; + } + + // On retourne le modèle dans le bon sens + vertex->position = scale * (rotationQuat * finalPos); + vertex->uv.Set(md5Vertex.uv.x, (parameters.flipUVs) ? 1.f - md5Vertex.uv.y : md5Vertex.uv.y); // Inversion des UV si demandé + vertex++; + } + + vertexMapper.Unmap(); + + // Submesh + StaticMeshRef subMesh = StaticMesh::New(mesh); + subMesh->Create(vertexBuffer); + + if (parameters.optimizeIndexBuffers) + indexBuffer->Optimize(); + + subMesh->SetIndexBuffer(indexBuffer); + subMesh->GenerateAABB(); + subMesh->GenerateNormalsAndTangents(); + subMesh->SetMaterialIndex(i); + + mesh->AddSubMesh(subMesh); + + // Material + mesh->SetMaterial(i, baseDir + md5Mesh.shader); + } + + if (parameters.center) + mesh->Recenter(); } - if (parameters.center) - mesh->Recenter(); + return true; + } + } + + namespace Loaders + { + void RegisterMD5Mesh() + { + MeshLoader::RegisterLoader(IsSupported, Check, Load); } - return true; + void UnregisterMD5Mesh() + { + MeshLoader::UnregisterLoader(IsSupported, Check, Load); + } } } - -void NzLoaders_MD5Mesh_Register() -{ - NzMeshLoader::RegisterLoader(IsSupported, Check, Load); -} - -void NzLoaders_MD5Mesh_Unregister() -{ - NzMeshLoader::UnregisterLoader(IsSupported, Check, Load); -} diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.hpp b/src/Nazara/Utility/Formats/MD5MeshLoader.hpp index 2589ca068..02b63d0ff 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.hpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.hpp @@ -9,7 +9,13 @@ #include -void NzLoaders_MD5Mesh_Register(); -void NzLoaders_MD5Mesh_Unregister(); +namespace Nz +{ + namespace Loaders + { + void RegisterMD5Mesh(); + void UnregisterMD5Mesh(); + } +} #endif // NAZARA_LOADERS_MD5MESH_HPP diff --git a/src/Nazara/Utility/Formats/MD5MeshParser.cpp b/src/Nazara/Utility/Formats/MD5MeshParser.cpp index 796aaaaa8..71d6779a4 100644 --- a/src/Nazara/Utility/Formats/MD5MeshParser.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshParser.cpp @@ -19,410 +19,413 @@ #include #include -NzMD5MeshParser::NzMD5MeshParser(NzInputStream& stream) : -m_stream(stream), -m_keepLastLine(false), -m_lineCount(0), -m_meshIndex(0), -m_streamFlags(stream.GetStreamOptions()) +namespace Nz { - if ((m_streamFlags & nzStreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags | nzStreamOption_Text); -} - -NzMD5MeshParser::~NzMD5MeshParser() -{ - if ((m_streamFlags & nzStreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags); -} - -nzTernary NzMD5MeshParser::Check() -{ - if (Advance(false)) + MD5MeshParser::MD5MeshParser(InputStream& stream) : + m_stream(stream), + m_keepLastLine(false), + m_lineCount(0), + m_meshIndex(0), + m_streamFlags(stream.GetStreamOptions()) { - unsigned int version; - if (std::sscanf(&m_currentLine[0], " MD5Version %u", &version) == 1) - { - if (version == 10) - return nzTernary_True; - } + if ((m_streamFlags & StreamOption_Text) == 0) + m_stream.SetStreamOptions(m_streamFlags | StreamOption_Text); } - return nzTernary_False; -} - -const NzMD5MeshParser::Joint* NzMD5MeshParser::GetJoints() const -{ - return m_joints.data(); -} - -unsigned int NzMD5MeshParser::GetJointCount() const -{ - return m_joints.size(); -} - -const NzMD5MeshParser::Mesh* NzMD5MeshParser::GetMeshes() const -{ - return m_meshes.data(); -} - -unsigned int NzMD5MeshParser::GetMeshCount() const -{ - return m_meshes.size(); -} - -bool NzMD5MeshParser::Parse() -{ - while (Advance(false)) + MD5MeshParser::~MD5MeshParser() { - switch (m_currentLine[0]) + if ((m_streamFlags & StreamOption_Text) == 0) + m_stream.SetStreamOptions(m_streamFlags); + } + + Ternary MD5MeshParser::Check() + { + if (Advance(false)) { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - case 'M': // MD5Version - if (m_currentLine.GetWord(0) != "MD5Version") - UnrecognizedLine(); - break; + unsigned int version; + if (std::sscanf(&m_currentLine[0], " MD5Version %u", &version) == 1) + { + if (version == 10) + return Ternary_True; + } + } - case 'c': // commandline - if (m_currentLine.GetWord(0) != "commandline") - UnrecognizedLine(); - break; - #endif + return Ternary_False; + } - case 'j': // joints - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - if (!m_currentLine.StartsWith("joints {")) - { - UnrecognizedLine(); - break; - } - #endif + const MD5MeshParser::Joint* MD5MeshParser::GetJoints() const + { + return m_joints.data(); + } - if (!ParseJoints()) - { - Error("Failed to parse joints"); - return false; - } - break; + unsigned int MD5MeshParser::GetJointCount() const + { + return m_joints.size(); + } - case 'm': // mesh + const MD5MeshParser::Mesh* MD5MeshParser::GetMeshes() const + { + return m_meshes.data(); + } + + unsigned int MD5MeshParser::GetMeshCount() const + { + return m_meshes.size(); + } + + bool MD5MeshParser::Parse() + { + while (Advance(false)) + { + switch (m_currentLine[0]) { #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - if (m_currentLine != "mesh {") - { - UnrecognizedLine(); + case 'M': // MD5Version + if (m_currentLine.GetWord(0) != "MD5Version") + UnrecognizedLine(); + break; + + case 'c': // commandline + if (m_currentLine.GetWord(0) != "commandline") + UnrecognizedLine(); break; - } #endif - if (m_meshIndex >= m_meshes.size()) - { + case 'j': // joints #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - Warning("More meshes than registred"); + if (!m_currentLine.StartsWith("joints {")) + { + UnrecognizedLine(); + break; + } #endif - m_meshes.push_back(Mesh()); + if (!ParseJoints()) + { + Error("Failed to parse joints"); + return false; + } + break; + + case 'm': // mesh + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + if (m_currentLine != "mesh {") + { + UnrecognizedLine(); + break; + } + #endif + + if (m_meshIndex >= m_meshes.size()) + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + Warning("More meshes than registred"); + #endif + + m_meshes.push_back(Mesh()); + } + + if (!ParseMesh()) + { + NazaraError("Failed to parse mesh"); + return false; + } + + m_meshIndex++; + break; } - if (!ParseMesh()) + case 'n': // num[Frames/Joints] { - NazaraError("Failed to parse mesh"); + unsigned int count; + if (std::sscanf(&m_currentLine[0], "numJoints %u", &count) == 1) + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + if (!m_joints.empty()) + Warning("Joint count is already defined"); + #endif + + m_joints.resize(count); + } + else if (std::sscanf(&m_currentLine[0], "numMeshes %u", &count) == 1) + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + if (!m_meshes.empty()) + Warning("Mesh count is already defined"); + #endif + + m_meshes.resize(count); + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + break; + } + + default: + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + UnrecognizedLine(); + #endif + break; + } + } + + return true; + } + + bool MD5MeshParser::Advance(bool required) + { + if (!m_keepLastLine) + { + do + { + if (m_stream.EndOfStream()) + { + if (required) + Error("Incomplete MD5 file"); + return false; } - m_meshIndex++; - break; + m_lineCount++; + + m_currentLine = m_stream.ReadLine(); + m_currentLine = m_currentLine.SubStringTo("//"); // On ignore les commentaires + m_currentLine.Simplify(); // Pour un traitement plus simple } - - case 'n': // num[Frames/Joints] - { - unsigned int count; - if (std::sscanf(&m_currentLine[0], "numJoints %u", &count) == 1) - { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - if (!m_joints.empty()) - Warning("Joint count is already defined"); - #endif - - m_joints.resize(count); - } - else if (std::sscanf(&m_currentLine[0], "numMeshes %u", &count) == 1) - { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - if (!m_meshes.empty()) - Warning("Mesh count is already defined"); - #endif - - m_meshes.resize(count); - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - break; - } - - default: - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); - #endif - break; + while (m_currentLine.IsEmpty()); } + else + m_keepLastLine = false; + + return true; } - return true; -} - -bool NzMD5MeshParser::Advance(bool required) -{ - if (!m_keepLastLine) + void MD5MeshParser::Error(const String& message) { - do - { - if (m_stream.EndOfStream()) - { - if (required) - Error("Incomplete MD5 file"); + NazaraError(message + " at line #" + String::Number(m_lineCount)); + } + bool MD5MeshParser::ParseJoints() + { + unsigned int jointCount = m_joints.size(); + if (jointCount == 0) + { + Error("Joint count is invalid or missing"); + return false; + } + + for (unsigned int i = 0; i < jointCount; ++i) + { + if (!Advance()) + return false; + + unsigned int pos = m_currentLine.Find(' '); + if (pos == String::npos) + { + UnrecognizedLine(true); return false; } - m_lineCount++; + if (pos >= 64) + { + NazaraError("Joint name is too long (>= 64 characters)"); + return false; + } - m_currentLine = m_stream.ReadLine(); - m_currentLine = m_currentLine.SubStringTo("//"); // On ignore les commentaires - m_currentLine.Simplify(); // Pour un traitement plus simple + char name[64]; + if (std::sscanf(&m_currentLine[0], "%63s %d ( %f %f %f ) ( %f %f %f )", &name[0], &m_joints[i].parent, + &m_joints[i].bindPos.x, &m_joints[i].bindPos.y, &m_joints[i].bindPos.z, + &m_joints[i].bindOrient.x, &m_joints[i].bindOrient.y, &m_joints[i].bindOrient.z) != 8) + { + UnrecognizedLine(true); + return false; + } + + m_joints[i].name = name; + m_joints[i].name.Trim('"'); + + int parent = m_joints[i].parent; + if (parent >= 0) + { + if (static_cast(parent) >= jointCount) + { + Error("Joint's parent is out of bounds (" + String::Number(parent) + " >= " + String::Number(jointCount) + ')'); + return false; + } + } + + m_joints[i].bindOrient.ComputeW(); // On calcule la composante W } - while (m_currentLine.IsEmpty()); - } - else - m_keepLastLine = false; - return true; -} - -void NzMD5MeshParser::Error(const NzString& message) -{ - NazaraError(message + " at line #" + NzString::Number(m_lineCount)); -} - -bool NzMD5MeshParser::ParseJoints() -{ - unsigned int jointCount = m_joints.size(); - if (jointCount == 0) - { - Error("Joint count is invalid or missing"); - return false; - } - - for (unsigned int i = 0; i < jointCount; ++i) - { if (!Advance()) return false; - unsigned int pos = m_currentLine.Find(' '); - if (pos == NzString::npos) + if (m_currentLine != '}') { - UnrecognizedLine(true); - return false; + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + Warning("Hierarchy braces closing not found"); + #endif + + // On tente de survivre à l'erreur + m_keepLastLine = true; } - if (pos >= 64) - { - NazaraError("Joint name is too long (>= 64 characters)"); - return false; - } + return true; + } - char name[64]; - if (std::sscanf(&m_currentLine[0], "%63s %d ( %f %f %f ) ( %f %f %f )", &name[0], &m_joints[i].parent, - &m_joints[i].bindPos.x, &m_joints[i].bindPos.y, &m_joints[i].bindPos.z, - &m_joints[i].bindOrient.x, &m_joints[i].bindOrient.y, &m_joints[i].bindOrient.z) != 8) + bool MD5MeshParser::ParseMesh() + { + bool finished = false; + while (!finished && Advance(false)) { - UnrecognizedLine(true); - return false; - } - - m_joints[i].name = name; - m_joints[i].name.Trim('"'); - - int parent = m_joints[i].parent; - if (parent >= 0) - { - if (static_cast(parent) >= jointCount) + switch (m_currentLine[0]) { - Error("Joint's parent is out of bounds (" + NzString::Number(parent) + " >= " + NzString::Number(jointCount) + ')'); - return false; - } - } + case '}': + finished = true; + break; - m_joints[i].bindOrient.ComputeW(); // On calcule la composante W - } + case 's': // shader + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + if (!m_currentLine.StartsWith("shader ")) + { + UnrecognizedLine(); + break; + } + #endif - if (!Advance()) - return false; + m_meshes[m_meshIndex].shader = m_currentLine.SubString(7); + m_meshes[m_meshIndex].shader.Trim('"'); + break; - if (m_currentLine != '}') - { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - Warning("Hierarchy braces closing not found"); - #endif - - // On tente de survivre à l'erreur - m_keepLastLine = true; - } - - return true; -} - -bool NzMD5MeshParser::ParseMesh() -{ - bool finished = false; - while (!finished && Advance(false)) - { - switch (m_currentLine[0]) - { - case '}': - finished = true; - break; - - case 's': // shader - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - if (!m_currentLine.StartsWith("shader ")) + case 'n': // num[tris/verts] { - UnrecognizedLine(); + unsigned int count; + if (std::sscanf(&m_currentLine[0], "numtris %u", &count) == 1) + { + m_meshes[m_meshIndex].triangles.resize(count); + for (unsigned int i = 0; i < count; ++i) + { + if (!Advance()) + return false; + + Triangle& triangle = m_meshes[m_meshIndex].triangles[i]; + unsigned int index; + if (std::sscanf(&m_currentLine[0], "tri %u %u %u %u", &index, &triangle.x, &triangle.y, &triangle.z) != 4) + { + UnrecognizedLine(true); + return false; + } + + if (index != i) + { + Error("Unexpected triangle index (expected " + String::Number(i) + ", got " + String::Number(index) + ')'); + return false; + } + } + } + else if (std::sscanf(&m_currentLine[0], "numverts %u", &count) == 1) + { + m_meshes[m_meshIndex].vertices.resize(count); + for (unsigned int i = 0; i < count; ++i) + { + if (!Advance()) + return false; + + Vertex& vertex = m_meshes[m_meshIndex].vertices[i]; + unsigned int index; + if (std::sscanf(&m_currentLine[0], "vert %u ( %f %f ) %u %u", &index, &vertex.uv.x, &vertex.uv.y, &vertex.startWeight, &vertex.weightCount) != 5) + { + UnrecognizedLine(true); + return false; + } + + if (index != i) + { + Error("Unexpected vertex index (expected " + String::Number(i) + ", got " + String::Number(index) + ')'); + return false; + } + } + } + else if (std::sscanf(&m_currentLine[0], "numweights %u", &count) == 1) + { + m_meshes[m_meshIndex].weights.resize(count); + for (unsigned int i = 0; i < count; ++i) + { + if (!Advance()) + return false; + + Weight& weight = m_meshes[m_meshIndex].weights[i]; + unsigned int index; + if (std::sscanf(&m_currentLine[0], "weight %u %u %f ( %f %f %f )", &index, &weight.joint, &weight.bias, + &weight.pos.x, &weight.pos.y, &weight.pos.z) != 6) + { + UnrecognizedLine(true); + return false; + } + + if (index != i) + { + Error("Unexpected weight index (expected " + String::Number(i) + ", got " + String::Number(index) + ')'); + return false; + } + } + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif break; } - #endif - m_meshes[m_meshIndex].shader = m_currentLine.SubString(7); - m_meshes[m_meshIndex].shader.Trim('"'); - break; - - case 'n': // num[tris/verts] - { - unsigned int count; - if (std::sscanf(&m_currentLine[0], "numtris %u", &count) == 1) - { - m_meshes[m_meshIndex].triangles.resize(count); - for (unsigned int i = 0; i < count; ++i) - { - if (!Advance()) - return false; - - Triangle& triangle = m_meshes[m_meshIndex].triangles[i]; - unsigned int index; - if (std::sscanf(&m_currentLine[0], "tri %u %u %u %u", &index, &triangle.x, &triangle.y, &triangle.z) != 4) - { - UnrecognizedLine(true); - return false; - } - - if (index != i) - { - Error("Unexpected triangle index (expected " + NzString::Number(i) + ", got " + NzString::Number(index) + ')'); - return false; - } - } - } - else if (std::sscanf(&m_currentLine[0], "numverts %u", &count) == 1) - { - m_meshes[m_meshIndex].vertices.resize(count); - for (unsigned int i = 0; i < count; ++i) - { - if (!Advance()) - return false; - - Vertex& vertex = m_meshes[m_meshIndex].vertices[i]; - unsigned int index; - if (std::sscanf(&m_currentLine[0], "vert %u ( %f %f ) %u %u", &index, &vertex.uv.x, &vertex.uv.y, &vertex.startWeight, &vertex.weightCount) != 5) - { - UnrecognizedLine(true); - return false; - } - - if (index != i) - { - Error("Unexpected vertex index (expected " + NzString::Number(i) + ", got " + NzString::Number(index) + ')'); - return false; - } - } - } - else if (std::sscanf(&m_currentLine[0], "numweights %u", &count) == 1) - { - m_meshes[m_meshIndex].weights.resize(count); - for (unsigned int i = 0; i < count; ++i) - { - if (!Advance()) - return false; - - Weight& weight = m_meshes[m_meshIndex].weights[i]; - unsigned int index; - if (std::sscanf(&m_currentLine[0], "weight %u %u %f ( %f %f %f )", &index, &weight.joint, &weight.bias, - &weight.pos.x, &weight.pos.y, &weight.pos.z) != 6) - { - UnrecognizedLine(true); - return false; - } - - if (index != i) - { - Error("Unexpected weight index (expected " + NzString::Number(i) + ", got " + NzString::Number(index) + ')'); - return false; - } - } - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else + default: + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING UnrecognizedLine(); - #endif - break; + #endif + break; } - - default: - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); - #endif - break; } + + if (m_meshes[m_meshIndex].triangles.empty()) + { + NazaraError("Mesh has no triangles"); + return false; + } + + if (m_meshes[m_meshIndex].vertices.empty()) + { + NazaraError("Mesh has no vertices"); + return false; + } + + if (m_meshes[m_meshIndex].weights.empty()) + { + NazaraError("Mesh has no weights"); + return false; + } + + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + if (!finished) + Warning("Mesh braces closing not found"); + #endif + + return true; } - if (m_meshes[m_meshIndex].triangles.empty()) + void MD5MeshParser::Warning(const String& message) { - NazaraError("Mesh has no triangles"); - return false; + NazaraWarning(message + " at line #" + String::Number(m_lineCount)); } - if (m_meshes[m_meshIndex].vertices.empty()) + void MD5MeshParser::UnrecognizedLine(bool error) { - NazaraError("Mesh has no vertices"); - return false; - } + String message = "Unrecognized \"" + m_currentLine + '"'; - if (m_meshes[m_meshIndex].weights.empty()) - { - NazaraError("Mesh has no weights"); - return false; - } - - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - if (!finished) - Warning("Mesh braces closing not found"); - #endif - - return true; + if (error) + Error(message); + else + Warning(message); } - -void NzMD5MeshParser::Warning(const NzString& message) -{ - NazaraWarning(message + " at line #" + NzString::Number(m_lineCount)); -} - -void NzMD5MeshParser::UnrecognizedLine(bool error) -{ - NzString message = "Unrecognized \"" + m_currentLine + '"'; - - if (error) - Error(message); - else - Warning(message); } diff --git a/src/Nazara/Utility/Formats/MTLParser.cpp b/src/Nazara/Utility/Formats/MTLParser.cpp index 4ab5d0f0f..d0c7f05b9 100644 --- a/src/Nazara/Utility/Formats/MTLParser.cpp +++ b/src/Nazara/Utility/Formats/MTLParser.cpp @@ -10,324 +10,327 @@ #include #include -NzMTLParser::NzMTLParser(NzInputStream& stream) : -m_stream(stream), -m_streamFlags(stream.GetStreamOptions()) +namespace Nz { - if ((m_streamFlags & nzStreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags | nzStreamOption_Text); -} - -NzMTLParser::~NzMTLParser() -{ - if ((m_streamFlags & nzStreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags); -} - -const NzMTLParser::Material* NzMTLParser::GetMaterial(const NzString& materialName) const -{ - auto it = m_materials.find(materialName); - if (it != m_materials.end()) - return &it->second; - else - return nullptr; -} - -const std::unordered_map& NzMTLParser::GetMaterials() const -{ - return m_materials; -} - -bool NzMTLParser::Parse() -{ - m_keepLastLine = false; - m_lineCount = 0; - m_materials.clear(); - - Material* currentMaterial = nullptr; - - while (Advance(false)) + MTLParser::MTLParser(InputStream& stream) : + m_stream(stream), + m_streamFlags(stream.GetStreamOptions()) { - NzString keyword = m_currentLine.GetWord(0).ToLower(); - if (keyword == "ka") - { - float r, g, b; - if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3) - { - if (!currentMaterial) - currentMaterial = &m_materials["default"]; + if ((m_streamFlags & StreamOption_Text) == 0) + m_stream.SetStreamOptions(m_streamFlags | StreamOption_Text); + } - currentMaterial->ambient = NzColor(static_cast(r*255.f), static_cast(g*255.f), static_cast(b*255.f)); - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - } - else if (keyword == "kd") - { - float r, g, b; - if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3) - { - if (!currentMaterial) - currentMaterial = &m_materials["default"]; + MTLParser::~MTLParser() + { + if ((m_streamFlags & StreamOption_Text) == 0) + m_stream.SetStreamOptions(m_streamFlags); + } - currentMaterial->diffuse = NzColor(static_cast(r*255.f), static_cast(g*255.f), static_cast(b*255.f)); - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - } - else if (keyword == "ks") - { - float r, g, b; - if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3) - { - if (!currentMaterial) - currentMaterial = &m_materials["default"]; - - currentMaterial->specular = NzColor(static_cast(r*255.f), static_cast(g*255.f), static_cast(b*255.f)); - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - } - else if (keyword == "ni") - { - float density; - if (std::sscanf(&m_currentLine[3], "%f", &density) == 1) - { - if (!currentMaterial) - currentMaterial = &m_materials["default"]; - - currentMaterial->refractionIndex = density; - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - } - else if (keyword == "ns") - { - float coef; - if (std::sscanf(&m_currentLine[3], "%f", &coef) == 1) - { - if (!currentMaterial) - currentMaterial = &m_materials["default"]; - - currentMaterial->shininess = coef; - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - } - else if (keyword == 'd') - { - float alpha; - if (std::sscanf(&m_currentLine[(keyword[0] == 'd') ? 2 : 3], "%f", &alpha) == 1) - { - if (!currentMaterial) - currentMaterial = &m_materials["default"]; - - currentMaterial->alpha = alpha; - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - } - else if (keyword == "tr") - { - float alpha; - if (std::sscanf(&m_currentLine[(keyword[0] == 'd') ? 2 : 3], "%f", &alpha) == 1) - { - if (!currentMaterial) - currentMaterial = &m_materials["default"]; - - currentMaterial->alpha = 1.f - alpha; // tr vaut pour la "valeur de transparence", 0 = opaque - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - } - else if (keyword == "illum") - { - unsigned int model; - if (std::sscanf(&m_currentLine[6], "%u", &model) == 1) - { - if (!currentMaterial) - currentMaterial = &m_materials["default"]; - - currentMaterial->illumModel = model; - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - } - else if (keyword == "map_ka") - { - unsigned int mapPos = m_currentLine.GetWordPosition(1); - if (mapPos != NzString::npos) - { - NzString map = m_currentLine.SubString(mapPos); - if (!currentMaterial) - currentMaterial = &m_materials["default"]; - - currentMaterial->ambientMap = map; - } - } - else if (keyword == "map_kd") - { - unsigned int mapPos = m_currentLine.GetWordPosition(1); - if (mapPos != NzString::npos) - { - NzString map = m_currentLine.SubString(mapPos); - if (!currentMaterial) - currentMaterial = &m_materials["default"]; - - currentMaterial->diffuseMap = map; - } - } - else if (keyword == "map_ks") - { - unsigned int mapPos = m_currentLine.GetWordPosition(1); - if (mapPos != NzString::npos) - { - NzString map = m_currentLine.SubString(mapPos); - if (!currentMaterial) - currentMaterial = &m_materials["default"]; - - currentMaterial->specularMap = map; - } - } - else if (keyword == "map_bump" || keyword == "bump") - { - unsigned int mapPos = m_currentLine.GetWordPosition(1); - if (mapPos != NzString::npos) - { - NzString map = m_currentLine.SubString(mapPos); - if (!currentMaterial) - currentMaterial = &m_materials["default"]; - - currentMaterial->bumpMap = map; - } - } - else if (keyword == "map_d") - { - unsigned int mapPos = m_currentLine.GetWordPosition(1); - if (mapPos != NzString::npos) - { - NzString map = m_currentLine.SubString(mapPos); - if (!currentMaterial) - currentMaterial = &m_materials["default"]; - - currentMaterial->alphaMap = map; - } - } - else if (keyword == "map_decal" || keyword == "decal") - { - unsigned int mapPos = m_currentLine.GetWordPosition(1); - if (mapPos != NzString::npos) - { - NzString map = m_currentLine.SubString(mapPos); - if (!currentMaterial) - currentMaterial = &m_materials["default"]; - - currentMaterial->decalMap = map; - } - } - else if (keyword == "map_disp" || keyword == "disp") - { - unsigned int mapPos = m_currentLine.GetWordPosition(1); - if (mapPos != NzString::npos) - { - NzString map = m_currentLine.SubString(mapPos); - if (!currentMaterial) - currentMaterial = &m_materials["default"]; - - currentMaterial->displacementMap = map; - } - } - else if (keyword == "map_refl" || keyword == "refl") - { - unsigned int mapPos = m_currentLine.GetWordPosition(1); - if (mapPos != NzString::npos) - { - NzString map = m_currentLine.SubString(mapPos); - if (!currentMaterial) - currentMaterial = &m_materials["default"]; - - currentMaterial->reflectionMap = map; - } - } - else if (keyword == "newmtl") - { - NzString materialName = m_currentLine.SubString(m_currentLine.GetWordPosition(1)); - if (!materialName.IsEmpty()) - currentMaterial = &m_materials[materialName]; - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + const MTLParser::Material* MTLParser::GetMaterial(const String& materialName) const + { + auto it = m_materials.find(materialName); + if (it != m_materials.end()) + return &it->second; else - UnrecognizedLine(); - #endif + return nullptr; } - return true; -} - -bool NzMTLParser::Advance(bool required) -{ - if (!m_keepLastLine) + const std::unordered_map& MTLParser::GetMaterials() const { - do - { - if (m_stream.EndOfStream()) - { - if (required) - Error("Incomplete MTL file"); - - return false; - } - - m_lineCount++; - - m_currentLine = m_stream.ReadLine(); - m_currentLine = m_currentLine.SubStringTo("#"); // On ignore les commentaires - m_currentLine.Simplify(); // Pour un traitement plus simple - } - while (m_currentLine.IsEmpty()); + return m_materials; } - else + + bool MTLParser::Parse() + { m_keepLastLine = false; + m_lineCount = 0; + m_materials.clear(); - return true; -} - -void NzMTLParser::Error(const NzString& message) -{ - NazaraError(message + " at line #" + NzString::Number(m_lineCount)); -} - -void NzMTLParser::Warning(const NzString& message) -{ - NazaraWarning(message + " at line #" + NzString::Number(m_lineCount)); -} - -void NzMTLParser::UnrecognizedLine(bool error) -{ - NzString message = "Unrecognized \"" + m_currentLine + '"'; - - if (error) - Error(message); - else - Warning(message); + Material* currentMaterial = nullptr; + + while (Advance(false)) + { + String keyword = m_currentLine.GetWord(0).ToLower(); + if (keyword == "ka") + { + float r, g, b; + if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3) + { + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->ambient = Color(static_cast(r*255.f), static_cast(g*255.f), static_cast(b*255.f)); + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + } + else if (keyword == "kd") + { + float r, g, b; + if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3) + { + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->diffuse = Color(static_cast(r*255.f), static_cast(g*255.f), static_cast(b*255.f)); + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + } + else if (keyword == "ks") + { + float r, g, b; + if (std::sscanf(&m_currentLine[3], "%f %f %f", &r, &g, &b) == 3) + { + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->specular = Color(static_cast(r*255.f), static_cast(g*255.f), static_cast(b*255.f)); + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + } + else if (keyword == "ni") + { + float density; + if (std::sscanf(&m_currentLine[3], "%f", &density) == 1) + { + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->refractionIndex = density; + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + } + else if (keyword == "ns") + { + float coef; + if (std::sscanf(&m_currentLine[3], "%f", &coef) == 1) + { + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->shininess = coef; + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + } + else if (keyword == 'd') + { + float alpha; + if (std::sscanf(&m_currentLine[(keyword[0] == 'd') ? 2 : 3], "%f", &alpha) == 1) + { + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->alpha = alpha; + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + } + else if (keyword == "tr") + { + float alpha; + if (std::sscanf(&m_currentLine[(keyword[0] == 'd') ? 2 : 3], "%f", &alpha) == 1) + { + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->alpha = 1.f - alpha; // tr vaut pour la "valeur de transparence", 0 = opaque + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + } + else if (keyword == "illum") + { + unsigned int model; + if (std::sscanf(&m_currentLine[6], "%u", &model) == 1) + { + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->illumModel = model; + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + } + else if (keyword == "map_ka") + { + unsigned int mapPos = m_currentLine.GetWordPosition(1); + if (mapPos != String::npos) + { + String map = m_currentLine.SubString(mapPos); + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->ambientMap = map; + } + } + else if (keyword == "map_kd") + { + unsigned int mapPos = m_currentLine.GetWordPosition(1); + if (mapPos != String::npos) + { + String map = m_currentLine.SubString(mapPos); + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->diffuseMap = map; + } + } + else if (keyword == "map_ks") + { + unsigned int mapPos = m_currentLine.GetWordPosition(1); + if (mapPos != String::npos) + { + String map = m_currentLine.SubString(mapPos); + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->specularMap = map; + } + } + else if (keyword == "map_bump" || keyword == "bump") + { + unsigned int mapPos = m_currentLine.GetWordPosition(1); + if (mapPos != String::npos) + { + String map = m_currentLine.SubString(mapPos); + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->bumpMap = map; + } + } + else if (keyword == "map_d") + { + unsigned int mapPos = m_currentLine.GetWordPosition(1); + if (mapPos != String::npos) + { + String map = m_currentLine.SubString(mapPos); + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->alphaMap = map; + } + } + else if (keyword == "map_decal" || keyword == "decal") + { + unsigned int mapPos = m_currentLine.GetWordPosition(1); + if (mapPos != String::npos) + { + String map = m_currentLine.SubString(mapPos); + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->decalMap = map; + } + } + else if (keyword == "map_disp" || keyword == "disp") + { + unsigned int mapPos = m_currentLine.GetWordPosition(1); + if (mapPos != String::npos) + { + String map = m_currentLine.SubString(mapPos); + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->displacementMap = map; + } + } + else if (keyword == "map_refl" || keyword == "refl") + { + unsigned int mapPos = m_currentLine.GetWordPosition(1); + if (mapPos != String::npos) + { + String map = m_currentLine.SubString(mapPos); + if (!currentMaterial) + currentMaterial = &m_materials["default"]; + + currentMaterial->reflectionMap = map; + } + } + else if (keyword == "newmtl") + { + String materialName = m_currentLine.SubString(m_currentLine.GetWordPosition(1)); + if (!materialName.IsEmpty()) + currentMaterial = &m_materials[materialName]; + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + } + + return true; + } + + bool MTLParser::Advance(bool required) + { + if (!m_keepLastLine) + { + do + { + if (m_stream.EndOfStream()) + { + if (required) + Error("Incomplete MTL file"); + + return false; + } + + m_lineCount++; + + m_currentLine = m_stream.ReadLine(); + m_currentLine = m_currentLine.SubStringTo("#"); // On ignore les commentaires + m_currentLine.Simplify(); // Pour un traitement plus simple + } + while (m_currentLine.IsEmpty()); + } + else + m_keepLastLine = false; + + return true; + } + + void MTLParser::Error(const String& message) + { + NazaraError(message + " at line #" + String::Number(m_lineCount)); + } + + void MTLParser::Warning(const String& message) + { + NazaraWarning(message + " at line #" + String::Number(m_lineCount)); + } + + void MTLParser::UnrecognizedLine(bool error) + { + String message = "Unrecognized \"" + m_currentLine + '"'; + + if (error) + Error(message); + else + Warning(message); + } } diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index 439c41bd4..a582b2326 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -11,446 +11,449 @@ #include #include -NzOBJParser::NzOBJParser(NzInputStream& stream) : -m_stream(stream), -m_streamFlags(stream.GetStreamOptions()) +namespace Nz { - if ((m_streamFlags & nzStreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags | nzStreamOption_Text); -} - -NzOBJParser::~NzOBJParser() -{ - if ((m_streamFlags & nzStreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags); -} - -const NzString* NzOBJParser::GetMaterials() const -{ - return m_materials.data(); -} - -unsigned int NzOBJParser::GetMaterialCount() const -{ - return m_materials.size(); -} - -const NzOBJParser::Mesh* NzOBJParser::GetMeshes() const -{ - return m_meshes.data(); -} - -unsigned int NzOBJParser::GetMeshCount() const -{ - return m_meshes.size(); -} - -const NzString& NzOBJParser::GetMtlLib() const -{ - return m_mtlLib; -} - -const NzVector3f* NzOBJParser::GetNormals() const -{ - return m_normals.data(); -} - -unsigned int NzOBJParser::GetNormalCount() const -{ - return m_normals.size(); -} - -const NzVector4f* NzOBJParser::GetPositions() const -{ - return m_positions.data(); -} - -unsigned int NzOBJParser::GetPositionCount() const -{ - return m_positions.size(); -} - -const NzVector3f* NzOBJParser::GetTexCoords() const -{ - return m_texCoords.data(); -} - -unsigned int NzOBJParser::GetTexCoordCount() const -{ - return m_texCoords.size(); -} - -bool NzOBJParser::Parse() -{ - NzString matName, meshName; - matName = meshName = "default"; - m_keepLastLine = false; - m_lineCount = 0; - m_meshes.clear(); - m_mtlLib.Clear(); - - m_normals.clear(); - m_positions.clear(); - m_texCoords.clear(); - - // Beaucoup de meshs font plus de 100 sommets, préparons le terrain - m_normals.reserve(100); - m_positions.reserve(100); - m_texCoords.reserve(100); - - // On va regrouper les meshs par nom et par matériau - using FaceVec = std::vector; - using MatPair = std::pair; - std::unordered_map> meshes; - - unsigned int matIndex = 0; - auto GetMaterial = [&meshes, &matIndex] (const NzString& mesh, const NzString& material) -> FaceVec* + OBJParser::OBJParser(InputStream& stream) : + m_stream(stream), + m_streamFlags(stream.GetStreamOptions()) { - auto& map = meshes[mesh]; - auto it = map.find(material); - if (it == map.end()) - it = map.insert(std::make_pair(material, MatPair(FaceVec(), matIndex++))).first; + if ((m_streamFlags & StreamOption_Text) == 0) + m_stream.SetStreamOptions(m_streamFlags | StreamOption_Text); + } - return &(it->second.first); - }; - - // On prépare le mesh par défaut - FaceVec* currentMesh = nullptr; - - while (Advance(false)) + OBJParser::~OBJParser() { - switch (std::tolower(m_currentLine[0])) + if ((m_streamFlags & StreamOption_Text) == 0) + m_stream.SetStreamOptions(m_streamFlags); + } + + const String* OBJParser::GetMaterials() const + { + return m_materials.data(); + } + + unsigned int OBJParser::GetMaterialCount() const + { + return m_materials.size(); + } + + const OBJParser::Mesh* OBJParser::GetMeshes() const + { + return m_meshes.data(); + } + + unsigned int OBJParser::GetMeshCount() const + { + return m_meshes.size(); + } + + const String& OBJParser::GetMtlLib() const + { + return m_mtlLib; + } + + const Vector3f* OBJParser::GetNormals() const + { + return m_normals.data(); + } + + unsigned int OBJParser::GetNormalCount() const + { + return m_normals.size(); + } + + const Vector4f* OBJParser::GetPositions() const + { + return m_positions.data(); + } + + unsigned int OBJParser::GetPositionCount() const + { + return m_positions.size(); + } + + const Vector3f* OBJParser::GetTexCoords() const + { + return m_texCoords.data(); + } + + unsigned int OBJParser::GetTexCoordCount() const + { + return m_texCoords.size(); + } + + bool OBJParser::Parse() + { + String matName, meshName; + matName = meshName = "default"; + m_keepLastLine = false; + m_lineCount = 0; + m_meshes.clear(); + m_mtlLib.Clear(); + + m_normals.clear(); + m_positions.clear(); + m_texCoords.clear(); + + // Beaucoup de meshs font plus de 100 sommets, préparons le terrain + m_normals.reserve(100); + m_positions.reserve(100); + m_texCoords.reserve(100); + + // On va regrouper les meshs par nom et par matériau + using FaceVec = std::vector; + using MatPair = std::pair; + std::unordered_map> meshes; + + unsigned int matIndex = 0; + auto GetMaterial = [&meshes, &matIndex] (const String& mesh, const String& material) -> FaceVec* { - case 'f': // Une face + auto& map = meshes[mesh]; + auto it = map.find(material); + if (it == map.end()) + it = map.insert(std::make_pair(material, MatPair(FaceVec(), matIndex++))).first; + + return &(it->second.first); + }; + + // On prépare le mesh par défaut + FaceVec* currentMesh = nullptr; + + while (Advance(false)) + { + switch (std::tolower(m_currentLine[0])) { - if (m_currentLine.GetSize() < 7) // Le minimum syndical pour définir une face de trois sommets (f 1 2 3) + case 'f': // Une face { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); - #endif - break; - } - - unsigned int vertexCount = m_currentLine.Count(' '); - if (vertexCount < 3) - { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); - #endif - break; - } - - Face face; - face.vertices.resize(vertexCount); - - bool error = false; - unsigned int pos = 2; - for (unsigned int i = 0; i < vertexCount; ++i) - { - int offset; - int& n = face.vertices[i].normal; - int& p = face.vertices[i].position; - int& t = face.vertices[i].texCoord; - - if (std::sscanf(&m_currentLine[pos], "%d/%d/%d%n", &p, &t, &n, &offset) != 3) + if (m_currentLine.GetSize() < 7) // Le minimum syndical pour définir une face de trois sommets (f 1 2 3) { - if (std::sscanf(&m_currentLine[pos], "%d//%d%n", &p, &n, &offset) != 2) + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + UnrecognizedLine(); + #endif + break; + } + + unsigned int vertexCount = m_currentLine.Count(' '); + if (vertexCount < 3) + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + UnrecognizedLine(); + #endif + break; + } + + Face face; + face.vertices.resize(vertexCount); + + bool error = false; + unsigned int pos = 2; + for (unsigned int i = 0; i < vertexCount; ++i) + { + int offset; + int& n = face.vertices[i].normal; + int& p = face.vertices[i].position; + int& t = face.vertices[i].texCoord; + + if (std::sscanf(&m_currentLine[pos], "%d/%d/%d%n", &p, &t, &n, &offset) != 3) { - if (std::sscanf(&m_currentLine[pos], "%d/%d%n", &p, &t, &offset) != 2) + if (std::sscanf(&m_currentLine[pos], "%d//%d%n", &p, &n, &offset) != 2) { - if (std::sscanf(&m_currentLine[pos], "%d%n", &p, &offset) != 1) + if (std::sscanf(&m_currentLine[pos], "%d/%d%n", &p, &t, &offset) != 2) { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); - #endif - error = true; - break; + if (std::sscanf(&m_currentLine[pos], "%d%n", &p, &offset) != 1) + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + UnrecognizedLine(); + #endif + error = true; + break; + } + else + { + n = 0; + t = 0; + } } else - { n = 0; - t = 0; - } } else - n = 0; + t = 0; } - else - t = 0; - } - if (p < 0) - { - p += m_positions.size(); if (p < 0) { - Error("Vertex index out of range (" + NzString::Number(p) + " < 0"); - error = true; - break; + p += m_positions.size(); + if (p < 0) + { + Error("Vertex index out of range (" + String::Number(p) + " < 0"); + error = true; + break; + } } - } - else - p--; + else + p--; - if (n < 0) - { - n += m_normals.size(); if (n < 0) { - Error("Vertex index out of range (" + NzString::Number(n) + " < 0"); - error = true; - break; + n += m_normals.size(); + if (n < 0) + { + Error("Vertex index out of range (" + String::Number(n) + " < 0"); + error = true; + break; + } } - } - else - n--; + else + n--; - if (t < 0) - { - t += m_texCoords.size(); if (t < 0) { - Error("Vertex index out of range (" + NzString::Number(t) + " < 0"); + t += m_texCoords.size(); + if (t < 0) + { + Error("Vertex index out of range (" + String::Number(t) + " < 0"); + error = true; + break; + } + } + else + t--; + + if (static_cast(p) >= m_positions.size()) + { + Error("Vertex index out of range (" + String::Number(p) + " >= " + String::Number(m_positions.size()) + ')'); error = true; break; } + else if (n >= 0 && static_cast(n) >= m_normals.size()) + { + Error("Normal index out of range (" + String::Number(n) + " >= " + String::Number(m_normals.size()) + ')'); + error = true; + break; + } + else if (t >= 0 && static_cast(t) >= m_texCoords.size()) + { + Error("TexCoord index out of range (" + String::Number(t) + " >= " + String::Number(m_texCoords.size()) + ')'); + error = true; + break; + } + + pos += offset; + } + + if (!error) + { + if (!currentMesh) + currentMesh = GetMaterial(meshName, matName); + + currentMesh->push_back(std::move(face)); + } + + break; + } + + case 'm': + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + if (m_currentLine.GetWord(0).ToLower() != "mtllib") + UnrecognizedLine(); + #endif + + m_mtlLib = m_currentLine.SubString(m_currentLine.GetWordPosition(1)); + break; + + case 'g': + case 'o': + { + if (m_currentLine.GetSize() <= 2 || m_currentLine[1] != ' ') + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + UnrecognizedLine(); + #endif + break; + } + + String objectName = m_currentLine.SubString(m_currentLine.GetWordPosition(1)); + if (objectName.IsEmpty()) + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + UnrecognizedLine(); + #endif + break; + } + + meshName = objectName; + currentMesh = GetMaterial(meshName, matName); + break; + } + + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + case 's': + if (m_currentLine.GetSize() <= 2 || m_currentLine[1] == ' ') + { + String param = m_currentLine.SubString(2); + if (param != "all" && param != "on" && param != "off" && !param.IsNumber()) + UnrecognizedLine(); } else - t--; - - if (static_cast(p) >= m_positions.size()) - { - Error("Vertex index out of range (" + NzString::Number(p) + " >= " + NzString::Number(m_positions.size()) + ')'); - error = true; - break; - } - else if (n >= 0 && static_cast(n) >= m_normals.size()) - { - Error("Normal index out of range (" + NzString::Number(n) + " >= " + NzString::Number(m_normals.size()) + ')'); - error = true; - break; - } - else if (t >= 0 && static_cast(t) >= m_texCoords.size()) - { - Error("TexCoord index out of range (" + NzString::Number(t) + " >= " + NzString::Number(m_texCoords.size()) + ')'); - error = true; - break; - } - - pos += offset; - } - - if (!error) - { - if (!currentMesh) - currentMesh = GetMaterial(meshName, matName); - - currentMesh->push_back(std::move(face)); - } - - break; - } - - case 'm': - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - if (m_currentLine.GetWord(0).ToLower() != "mtllib") - UnrecognizedLine(); + UnrecognizedLine(); + break; #endif - m_mtlLib = m_currentLine.SubString(m_currentLine.GetWordPosition(1)); - break; + case 'u': + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + if (m_currentLine.GetWord(0) != "usemtl") + UnrecognizedLine(); + #endif - case 'g': - case 'o': - { - if (m_currentLine.GetSize() <= 2 || m_currentLine[1] != ' ') + matName = m_currentLine.SubString(m_currentLine.GetWordPosition(1)); + if (matName.IsEmpty()) + { + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + UnrecognizedLine(); + #endif + break; + } + + currentMesh = GetMaterial(meshName, matName); + break; + + case 'v': { + String word = m_currentLine.GetWord(0).ToLower(); + if (word == 'v') + { + Vector4f vertex(Vector3f::Zero(), 1.f); + unsigned int paramCount = std::sscanf(&m_currentLine[2], "%f %f %f %f", &vertex.x, &vertex.y, &vertex.z, &vertex.w); + if (paramCount >= 3) + m_positions.push_back(vertex); + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + } + else if (word == "vn") + { + Vector3f normal(Vector3f::Zero()); + unsigned int paramCount = std::sscanf(&m_currentLine[3], "%f %f %f", &normal.x, &normal.y, &normal.z); + if (paramCount == 3) + m_normals.push_back(normal); + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + } + else if (word == "vt") + { + Vector3f uvw(Vector3f::Zero()); + unsigned int paramCount = std::sscanf(&m_currentLine[3], "%f %f %f", &uvw.x, &uvw.y, &uvw.z); + if (paramCount >= 2) + m_texCoords.push_back(uvw); + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + } + #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING + else + UnrecognizedLine(); + #endif + + break; + } + + default: #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING UnrecognizedLine(); #endif break; - } - - NzString objectName = m_currentLine.SubString(m_currentLine.GetWordPosition(1)); - if (objectName.IsEmpty()) - { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); - #endif - break; - } - - meshName = objectName; - currentMesh = GetMaterial(meshName, matName); - break; } - - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - case 's': - if (m_currentLine.GetSize() <= 2 || m_currentLine[1] == ' ') - { - NzString param = m_currentLine.SubString(2); - if (param != "all" && param != "on" && param != "off" && !param.IsNumber()) - UnrecognizedLine(); - } - else - UnrecognizedLine(); - break; - #endif - - case 'u': - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - if (m_currentLine.GetWord(0) != "usemtl") - UnrecognizedLine(); - #endif - - matName = m_currentLine.SubString(m_currentLine.GetWordPosition(1)); - if (matName.IsEmpty()) - { - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); - #endif - break; - } - - currentMesh = GetMaterial(meshName, matName); - break; - - case 'v': - { - NzString word = m_currentLine.GetWord(0).ToLower(); - if (word == 'v') - { - NzVector4f vertex(NzVector3f::Zero(), 1.f); - unsigned int paramCount = std::sscanf(&m_currentLine[2], "%f %f %f %f", &vertex.x, &vertex.y, &vertex.z, &vertex.w); - if (paramCount >= 3) - m_positions.push_back(vertex); - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - } - else if (word == "vn") - { - NzVector3f normal(NzVector3f::Zero()); - unsigned int paramCount = std::sscanf(&m_currentLine[3], "%f %f %f", &normal.x, &normal.y, &normal.z); - if (paramCount == 3) - m_normals.push_back(normal); - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - } - else if (word == "vt") - { - NzVector3f uvw(NzVector3f::Zero()); - unsigned int paramCount = std::sscanf(&m_currentLine[3], "%f %f %f", &uvw.x, &uvw.y, &uvw.z); - if (paramCount >= 2) - m_texCoords.push_back(uvw); - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - } - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - else - UnrecognizedLine(); - #endif - - break; - } - - default: - #if NAZARA_UTILITY_STRICT_RESOURCE_PARSING - UnrecognizedLine(); - #endif - break; } - } - std::unordered_map materials; - m_materials.resize(matIndex); + std::unordered_map materials; + m_materials.resize(matIndex); - for (auto& meshIt : meshes) - { - for (auto& matIt : meshIt.second) + for (auto& meshIt : meshes) { - auto& faceVec = matIt.second.first; - unsigned int index = matIt.second.second; - if (!faceVec.empty()) + for (auto& matIt : meshIt.second) { - Mesh mesh; - mesh.faces = std::move(faceVec); - mesh.name = meshIt.first; - - auto it = materials.find(matIt.first); - if (it == materials.end()) + auto& faceVec = matIt.second.first; + unsigned int index = matIt.second.second; + if (!faceVec.empty()) { - mesh.material = index; - materials[matIt.first] = index; - m_materials[index] = matIt.first; + Mesh mesh; + mesh.faces = std::move(faceVec); + mesh.name = meshIt.first; + + auto it = materials.find(matIt.first); + if (it == materials.end()) + { + mesh.material = index; + materials[matIt.first] = index; + m_materials[index] = matIt.first; + } + else + mesh.material = it->second; + + m_meshes.emplace_back(std::move(mesh)); } - else - mesh.material = it->second; - - m_meshes.emplace_back(std::move(mesh)); } } - } - if (m_meshes.empty()) - { - NazaraError("No meshes"); - return false; - } - - return true; -} - -bool NzOBJParser::Advance(bool required) -{ - if (!m_keepLastLine) - { - do + if (m_meshes.empty()) { - if (m_stream.EndOfStream()) - { - if (required) - Error("Incomplete OBJ file"); - - return false; - } - - m_lineCount++; - - m_currentLine = m_stream.ReadLine(); - m_currentLine = m_currentLine.SubStringTo("#"); // On ignore les commentaires - m_currentLine.Simplify(); // Pour un traitement plus simple + NazaraError("No meshes"); + return false; } - while (m_currentLine.IsEmpty()); + + return true; } - else - m_keepLastLine = false; - return true; -} - -void NzOBJParser::Error(const NzString& message) -{ - NazaraError(message + " at line #" + NzString::Number(m_lineCount)); -} - -void NzOBJParser::Warning(const NzString& message) -{ - NazaraWarning(message + " at line #" + NzString::Number(m_lineCount)); -} - -void NzOBJParser::UnrecognizedLine(bool error) -{ - NzString message = "Unrecognized \"" + m_currentLine + '"'; - - if (error) - Error(message); - else - Warning(message); + bool OBJParser::Advance(bool required) + { + if (!m_keepLastLine) + { + do + { + if (m_stream.EndOfStream()) + { + if (required) + Error("Incomplete OBJ file"); + + return false; + } + + m_lineCount++; + + m_currentLine = m_stream.ReadLine(); + m_currentLine = m_currentLine.SubStringTo("#"); // On ignore les commentaires + m_currentLine.Simplify(); // Pour un traitement plus simple + } + while (m_currentLine.IsEmpty()); + } + else + m_keepLastLine = false; + + return true; + } + + void OBJParser::Error(const String& message) + { + NazaraError(message + " at line #" + String::Number(m_lineCount)); + } + + void OBJParser::Warning(const String& message) + { + NazaraWarning(message + " at line #" + String::Number(m_lineCount)); + } + + void OBJParser::UnrecognizedLine(bool error) + { + String message = "Unrecognized \"" + m_currentLine + '"'; + + if (error) + Error(message); + else + Warning(message); + } } diff --git a/src/Nazara/Utility/Formats/PCXLoader.cpp b/src/Nazara/Utility/Formats/PCXLoader.cpp index 0f2d0450f..98862c517 100644 --- a/src/Nazara/Utility/Formats/PCXLoader.cpp +++ b/src/Nazara/Utility/Formats/PCXLoader.cpp @@ -12,154 +12,101 @@ // Auteur du loader original : David Henry -namespace +namespace Nz { - struct pcx_header + namespace { - nzUInt8 manufacturer; - nzUInt8 version; - nzUInt8 encoding; - nzUInt8 bitsPerPixel; - - nzUInt16 xmin, ymin; - nzUInt16 xmax, ymax; - nzUInt16 horzRes, vertRes; - - nzUInt8 palette[48]; - nzUInt8 reserved; - nzUInt8 numColorPlanes; - - nzUInt16 bytesPerScanLine; - nzUInt16 paletteType; - nzUInt16 horzSize, vertSize; - - nzUInt8 padding[54]; - }; - - static_assert(sizeof(pcx_header) == (6+48+54)*sizeof(nzUInt8) + 10*sizeof(nzUInt16), "pcx_header struct must be packed"); - - bool IsSupported(const NzString& extension) - { - return (extension == "pcx"); - } - - nzTernary Check(NzInputStream& stream, const NzImageParams& parameters) - { - NazaraUnused(parameters); - - nzUInt8 manufacturer; - if (stream.Read(&manufacturer, 1) == 1) + struct pcx_header { - if (manufacturer == 0x0a) - return nzTernary_True; + UInt8 manufacturer; + UInt8 version; + UInt8 encoding; + UInt8 bitsPerPixel; + + UInt16 xmin, ymin; + UInt16 xmax, ymax; + UInt16 horzRes, vertRes; + + UInt8 palette[48]; + UInt8 reserved; + UInt8 numColorPlanes; + + UInt16 bytesPerScanLine; + UInt16 paletteType; + UInt16 horzSize, vertSize; + + UInt8 padding[54]; + }; + + static_assert(sizeof(pcx_header) == (6+48+54)*sizeof(UInt8) + 10*sizeof(UInt16), "pcx_header struct must be packed"); + + bool IsSupported(const String& extension) + { + return (extension == "pcx"); } - return nzTernary_False; - } - - bool Load(NzImage* image, NzInputStream& stream, const NzImageParams& parameters) - { - NazaraUnused(parameters); - - pcx_header header; - if (stream.Read(&header, sizeof(pcx_header)) != sizeof(pcx_header)) + Ternary Check(InputStream& stream, const ImageParams& parameters) { - NazaraError("Failed to read header"); - return false; - } + NazaraUnused(parameters); - #ifdef NAZARA_BIG_ENDIAN - // Les fichiers PCX sont en little endian - NzByteSwap(&header.xmin, sizeof(nzUInt16)); - NzByteSwap(&header.ymin, sizeof(nzUInt16)); - NzByteSwap(&header.xmax, sizeof(nzUInt16)); - NzByteSwap(&header.ymax, sizeof(nzUInt16)); - NzByteSwap(&header.horzRes, sizeof(nzUInt16)); - NzByteSwap(&header.vertRes, sizeof(nzUInt16)); - - NzByteSwap(&header.bytesPerScanLine, sizeof(nzUInt16)); - NzByteSwap(&header.paletteType, sizeof(nzUInt16)); - NzByteSwap(&header.horzSize, sizeof(nzUInt16)); - NzByteSwap(&header.vertSize, sizeof(nzUInt16)); - #endif - - unsigned int bitCount = header.bitsPerPixel * header.numColorPlanes; - unsigned int width = header.xmax - header.xmin+1; - unsigned int height = header.ymax - header.ymin+1; - - if (!image->Create(nzImageType_2D, nzPixelFormat_RGB8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1)) - { - NazaraError("Failed to create image"); - return false; - } - - nzUInt8* pixels = image->GetPixels(); - - int rle_value = 0; - unsigned int rle_count = 0; - - switch (bitCount) - { - case 1: + UInt8 manufacturer; + if (stream.Read(&manufacturer, 1) == 1) { - for (unsigned int y = 0; y < height; ++y) - { - nzUInt8* ptr = &pixels[y * width * 3]; - int bytes = header.bytesPerScanLine; - - /* decode line number y */ - while (bytes--) - { - if (rle_count == 0) - { - if (!stream.Read(&rle_value, 1)) - { - NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')'); - return false; - } - - if (rle_value < 0xc0) - rle_count = 1; - else - { - rle_count = rle_value - 0xc0; - if (!stream.Read(&rle_value, 1)) - { - NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')'); - return false; - } - } - } - - rle_count--; - - for (int i = 7; i >= 0; --i) - { - int colorIndex = ((rle_value & (1 << i)) > 0); - - *ptr++ = header.palette[colorIndex * 3 + 0]; - *ptr++ = header.palette[colorIndex * 3 + 1]; - *ptr++ = header.palette[colorIndex * 3 + 2]; - } - } - } - break; + if (manufacturer == 0x0a) + return Ternary_True; } - case 4: + return Ternary_False; + } + + bool Load(Image* image, InputStream& stream, const ImageParams& parameters) + { + NazaraUnused(parameters); + + pcx_header header; + if (stream.Read(&header, sizeof(pcx_header)) != sizeof(pcx_header)) { - std::unique_ptr colorIndex(new nzUInt8[width]); - std::unique_ptr line(new nzUInt8[header.bytesPerScanLine]); + NazaraError("Failed to read header"); + return false; + } - for (unsigned int y = 0; y < height; ++y) + #ifdef NAZARA_BIG_ENDIAN + // Les fichiers PCX sont en little endian + SwapBytes(&header.xmin, sizeof(UInt16)); + SwapBytes(&header.ymin, sizeof(UInt16)); + SwapBytes(&header.xmax, sizeof(UInt16)); + SwapBytes(&header.ymax, sizeof(UInt16)); + SwapBytes(&header.horzRes, sizeof(UInt16)); + SwapBytes(&header.vertRes, sizeof(UInt16)); + + SwapBytes(&header.bytesPerScanLine, sizeof(UInt16)); + SwapBytes(&header.paletteType, sizeof(UInt16)); + SwapBytes(&header.horzSize, sizeof(UInt16)); + SwapBytes(&header.vertSize, sizeof(UInt16)); + #endif + + unsigned int bitCount = header.bitsPerPixel * header.numColorPlanes; + unsigned int width = header.xmax - header.xmin+1; + unsigned int height = header.ymax - header.ymin+1; + + if (!image->Create(ImageType_2D, PixelFormatType_RGB8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1)) + { + NazaraError("Failed to create image"); + return false; + } + + UInt8* pixels = image->GetPixels(); + + int rle_value = 0; + unsigned int rle_count = 0; + + switch (bitCount) + { + case 1: { - nzUInt8* ptr = &pixels[y * width * 3]; - - std::memset(colorIndex.get(), 0, width); - - for (unsigned int c = 0; c < 4; ++c) + for (unsigned int y = 0; y < height; ++y) { - nzUInt8* pLine = line.get(); + UInt8* ptr = &pixels[y * width * 3]; int bytes = header.bytesPerScanLine; /* decode line number y */ @@ -169,7 +116,7 @@ namespace { if (!stream.Read(&rle_value, 1)) { - NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')'); + NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); return false; } @@ -180,114 +127,125 @@ namespace rle_count = rle_value - 0xc0; if (!stream.Read(&rle_value, 1)) { - NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')'); + NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); return false; } } } rle_count--; - *(pLine++) = rle_value; + + for (int i = 7; i >= 0; --i) + { + int colorIndex = ((rle_value & (1 << i)) > 0); + + *ptr++ = header.palette[colorIndex * 3 + 0]; + *ptr++ = header.palette[colorIndex * 3 + 1]; + *ptr++ = header.palette[colorIndex * 3 + 2]; + } + } + } + break; + } + + case 4: + { + std::unique_ptr colorIndex(new UInt8[width]); + std::unique_ptr line(new UInt8[header.bytesPerScanLine]); + + for (unsigned int y = 0; y < height; ++y) + { + UInt8* ptr = &pixels[y * width * 3]; + + std::memset(colorIndex.get(), 0, width); + + for (unsigned int c = 0; c < 4; ++c) + { + UInt8* pLine = line.get(); + int bytes = header.bytesPerScanLine; + + /* decode line number y */ + while (bytes--) + { + if (rle_count == 0) + { + if (!stream.Read(&rle_value, 1)) + { + NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); + return false; + } + + if (rle_value < 0xc0) + rle_count = 1; + else + { + rle_count = rle_value - 0xc0; + if (!stream.Read(&rle_value, 1)) + { + NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); + return false; + } + } + } + + rle_count--; + *(pLine++) = rle_value; + } + + /* compute line's color indexes */ + for (unsigned int x = 0; x < width; ++x) + { + if (line[x / 8] & (128 >> (x % 8))) + colorIndex[x] += (1 << c); + } } - /* compute line's color indexes */ + /* decode scan line. color index => rgb */ for (unsigned int x = 0; x < width; ++x) { - if (line[x / 8] & (128 >> (x % 8))) - colorIndex[x] += (1 << c); + *ptr++ = header.palette[colorIndex[x] * 3 + 0]; + *ptr++ = header.palette[colorIndex[x] * 3 + 1]; + *ptr++ = header.palette[colorIndex[x] * 3 + 2]; } } - /* decode scan line. color index => rgb */ - for (unsigned int x = 0; x < width; ++x) + break; + } + + case 8: + { + UInt8 palette[768]; + + /* the palette is contained in the last 769 bytes of the file */ + UInt64 curPos = stream.GetCursorPos(); + stream.SetCursorPos(stream.GetSize()-769); + UInt8 magic; + if (!stream.Read(&magic, 1)) { - *ptr++ = header.palette[colorIndex[x] * 3 + 0]; - *ptr++ = header.palette[colorIndex[x] * 3 + 1]; - *ptr++ = header.palette[colorIndex[x] * 3 + 2]; + NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); + return false; } - } - break; - } - - case 8: - { - nzUInt8 palette[768]; - - /* the palette is contained in the last 769 bytes of the file */ - nzUInt64 curPos = stream.GetCursorPos(); - stream.SetCursorPos(stream.GetSize()-769); - nzUInt8 magic; - if (!stream.Read(&magic, 1)) - { - NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')'); - return false; - } - - /* first byte must be equal to 0x0c (12) */ - if (magic != 0x0c) - { - NazaraError("Colormap's first byte must be 0x0c (0x" + NzString::Number(magic, 16) + ')'); - return false; - } - - /* read palette */ - if (stream.Read(palette, 768) != 768) - { - NazaraError("Failed to read palette"); - return false; - } - - stream.SetCursorPos(curPos); - - /* read pixel data */ - for (unsigned int y = 0; y < height; ++y) - { - nzUInt8* ptr = &pixels[y * width * 3]; - int bytes = header.bytesPerScanLine; - - /* decode line number y */ - while (bytes--) + /* first byte must be equal to 0x0c (12) */ + if (magic != 0x0c) { - if (rle_count == 0) - { - if (!stream.Read(&rle_value, 1)) - { - NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')'); - return false; - } - - if (rle_value < 0xc0) - rle_count = 1; - else - { - rle_count = rle_value - 0xc0; - if (!stream.Read(&rle_value, 1)) - { - NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')'); - return false; - } - } - } - - rle_count--; - - *ptr++ = palette[rle_value * 3 + 0]; - *ptr++ = palette[rle_value * 3 + 1]; - *ptr++ = palette[rle_value * 3 + 2]; + NazaraError("Colormap's first byte must be 0x0c (0x" + String::Number(magic, 16) + ')'); + return false; } - } - break; - } - case 24: - { - for (unsigned int y = 0; y < height; ++y) - { - /* for each color plane */ - for (int c = 0; c < 3; ++c) + /* read palette */ + if (stream.Read(palette, 768) != 768) { - nzUInt8* ptr = &pixels[y * width * 3]; + NazaraError("Failed to read palette"); + return false; + } + + stream.SetCursorPos(curPos); + + /* read pixel data */ + for (unsigned int y = 0; y < height; ++y) + { + UInt8* ptr = &pixels[y * width * 3]; int bytes = header.bytesPerScanLine; /* decode line number y */ @@ -297,7 +255,7 @@ namespace { if (!stream.Read(&rle_value, 1)) { - NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')'); + NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); return false; } @@ -308,39 +266,87 @@ namespace rle_count = rle_value - 0xc0; if (!stream.Read(&rle_value, 1)) { - NazaraError("Failed to read stream (byte " + NzString::Number(stream.GetCursorPos()) + ')'); + NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); return false; } } } rle_count--; - ptr[c] = static_cast(rle_value); - ptr += 3; + + *ptr++ = palette[rle_value * 3 + 0]; + *ptr++ = palette[rle_value * 3 + 1]; + *ptr++ = palette[rle_value * 3 + 2]; } } + break; } - break; + + case 24: + { + for (unsigned int y = 0; y < height; ++y) + { + /* for each color plane */ + for (int c = 0; c < 3; ++c) + { + UInt8* ptr = &pixels[y * width * 3]; + int bytes = header.bytesPerScanLine; + + /* decode line number y */ + while (bytes--) + { + if (rle_count == 0) + { + if (!stream.Read(&rle_value, 1)) + { + NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); + return false; + } + + if (rle_value < 0xc0) + rle_count = 1; + else + { + rle_count = rle_value - 0xc0; + if (!stream.Read(&rle_value, 1)) + { + NazaraError("Failed to read stream (byte " + String::Number(stream.GetCursorPos()) + ')'); + return false; + } + } + } + + rle_count--; + ptr[c] = static_cast(rle_value); + ptr += 3; + } + } + } + break; + } + + default: + NazaraError("Unsupported " + String::Number(bitCount) + " bitcount for pcx files"); + return false; } - default: - NazaraError("Unsupported " + NzString::Number(bitCount) + " bitcount for pcx files"); - return false; + if (parameters.loadFormat != PixelFormatType_Undefined) + image->Convert(parameters.loadFormat); + + return true; + } + } + + namespace Loaders + { + void RegisterPCX() + { + ImageLoader::RegisterLoader(IsSupported, Check, Load); } - if (parameters.loadFormat != nzPixelFormat_Undefined) - image->Convert(parameters.loadFormat); - - return true; + void UnregisterPCX() + { + ImageLoader::UnregisterLoader(IsSupported, Check, Load); + } } } - -void NzLoaders_PCX_Register() -{ - NzImageLoader::RegisterLoader(IsSupported, Check, Load); -} - -void NzLoaders_PCX_Unregister() -{ - NzImageLoader::UnregisterLoader(IsSupported, Check, Load); -} diff --git a/src/Nazara/Utility/Formats/PCXLoader.hpp b/src/Nazara/Utility/Formats/PCXLoader.hpp index c3836529f..6ef8d86c1 100644 --- a/src/Nazara/Utility/Formats/PCXLoader.hpp +++ b/src/Nazara/Utility/Formats/PCXLoader.hpp @@ -9,7 +9,13 @@ #include -void NzLoaders_PCX_Register(); -void NzLoaders_PCX_Unregister(); +namespace Nz +{ + namespace Loaders + { + void RegisterPCX(); + void UnregisterPCX(); + } +} #endif // NAZARA_LOADERS_PCX_HPP diff --git a/src/Nazara/Utility/Formats/STBLoader.cpp b/src/Nazara/Utility/Formats/STBLoader.cpp index 1ef8fd2fa..ca6832f55 100644 --- a/src/Nazara/Utility/Formats/STBLoader.cpp +++ b/src/Nazara/Utility/Formats/STBLoader.cpp @@ -13,82 +13,88 @@ #include #include -namespace +namespace Nz { - int Read(void* userdata, char* data, int size) + namespace { - NzInputStream* stream = static_cast(userdata); - return static_cast(stream->Read(data, size)); - } - - void Skip(void* userdata, int size) - { - NzInputStream* stream = static_cast(userdata); - stream->SetCursorPos(static_cast(stream->GetCursorPos()) + static_cast(size)); - } - - int Eof(void* userdata) - { - NzInputStream* stream = static_cast(userdata); - return stream->GetCursorPos() >= stream->GetSize(); - } - - static stbi_io_callbacks callbacks = {Read, Skip, Eof}; - - bool IsSupported(const NzString& extension) - { - static std::set supportedExtensions = {"bmp", "gif", "hdr", "jpg", "jpeg", "pic", "png", "ppm", "pgm", "psd", "tga"}; - return supportedExtensions.find(extension) != supportedExtensions.end(); - } - - nzTernary Check(NzInputStream& stream, const NzImageParams& parameters) - { - NazaraUnused(parameters); - - int width, height, bpp; - if (stbi_info_from_callbacks(&callbacks, &stream, &width, &height, &bpp)) - return nzTernary_True; - else - return nzTernary_False; - } - - bool Load(NzImage* image, NzInputStream& stream, const NzImageParams& parameters) - { - // Je charge tout en RGBA8 et je converti ensuite via la méthode Convert - // Ceci à cause d'un bug de STB lorsqu'il s'agit de charger certaines images (ex: JPG) en "default" - - int width, height, bpp; - nzUInt8* ptr = stbi_load_from_callbacks(&callbacks, &stream, &width, &height, &bpp, STBI_rgb_alpha); - if (!ptr) + int Read(void* userdata, char* data, int size) { - NazaraError("Failed to load image: " + NzString(stbi_failure_reason())); - return false; + InputStream* stream = static_cast(userdata); + return static_cast(stream->Read(data, size)); } - if (!image->Create(nzImageType_2D, nzPixelFormat_RGBA8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1)) + void Skip(void* userdata, int size) { - NazaraError("Failed to create image"); + InputStream* stream = static_cast(userdata); + stream->SetCursorPos(static_cast(stream->GetCursorPos()) + static_cast(size)); + } + + int Eof(void* userdata) + { + InputStream* stream = static_cast(userdata); + return stream->GetCursorPos() >= stream->GetSize(); + } + + static stbi_io_callbacks callbacks = {Read, Skip, Eof}; + + bool IsSupported(const String& extension) + { + static std::set supportedExtensions = {"bmp", "gif", "hdr", "jpg", "jpeg", "pic", "png", "ppm", "pgm", "psd", "tga"}; + return supportedExtensions.find(extension) != supportedExtensions.end(); + } + + Ternary Check(InputStream& stream, const ImageParams& parameters) + { + NazaraUnused(parameters); + + int width, height, bpp; + if (stbi_info_from_callbacks(&callbacks, &stream, &width, &height, &bpp)) + return Ternary_True; + else + return Ternary_False; + } + + bool Load(Image* image, InputStream& stream, const ImageParams& parameters) + { + // Je charge tout en RGBA8 et je converti ensuite via la méthode Convert + // Ceci à cause d'un bug de STB lorsqu'il s'agit de charger certaines images (ex: JPG) en "default" + + int width, height, bpp; + UInt8* ptr = stbi_load_from_callbacks(&callbacks, &stream, &width, &height, &bpp, STBI_rgb_alpha); + if (!ptr) + { + NazaraError("Failed to load image: " + String(stbi_failure_reason())); + return false; + } + + if (!image->Create(ImageType_2D, PixelFormatType_RGBA8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1)) + { + NazaraError("Failed to create image"); + stbi_image_free(ptr); + + return false; + } + + image->Update(ptr); stbi_image_free(ptr); - return false; + if (parameters.loadFormat != PixelFormatType_Undefined) + image->Convert(parameters.loadFormat); + + return true; + } + } + + namespace Loaders + { + void RegisterSTB() + { + ImageLoader::RegisterLoader(IsSupported, Check, Load); } - image->Update(ptr); - stbi_image_free(ptr); - - if (parameters.loadFormat != nzPixelFormat_Undefined) - image->Convert(parameters.loadFormat); - - return true; + void UnregisterSTB() + { + ImageLoader::UnregisterLoader(IsSupported, Check, Load); + } } } - -void NzLoaders_STB_Register() -{ - NzImageLoader::RegisterLoader(IsSupported, Check, Load); -} - -void NzLoaders_STB_Unregister() -{ - NzImageLoader::UnregisterLoader(IsSupported, Check, Load); -} diff --git a/src/Nazara/Utility/Formats/STBLoader.hpp b/src/Nazara/Utility/Formats/STBLoader.hpp index 83e0d9036..4d8917ef5 100644 --- a/src/Nazara/Utility/Formats/STBLoader.hpp +++ b/src/Nazara/Utility/Formats/STBLoader.hpp @@ -9,7 +9,13 @@ #include -void NzLoaders_STB_Register(); -void NzLoaders_STB_Unregister(); +namespace Nz +{ + namespace Loaders + { + void RegisterSTB(); + void UnregisterSTB(); + } +} #endif // NAZARA_LOADERS_STB_HPP diff --git a/src/Nazara/Utility/GuillotineImageAtlas.cpp b/src/Nazara/Utility/GuillotineImageAtlas.cpp index b80e739c6..35beab566 100644 --- a/src/Nazara/Utility/GuillotineImageAtlas.cpp +++ b/src/Nazara/Utility/GuillotineImageAtlas.cpp @@ -6,259 +6,262 @@ #include #include -namespace +namespace Nz { - const unsigned int s_atlasStartSize = 512; -} - -NzGuillotineImageAtlas::NzGuillotineImageAtlas() : -m_rectChoiceHeuristic(NzGuillotineBinPack::RectBestAreaFit), -m_rectSplitHeuristic(NzGuillotineBinPack::SplitMinimizeArea) -{ -} - -NzGuillotineImageAtlas::~NzGuillotineImageAtlas() = default; - -void NzGuillotineImageAtlas::Clear() -{ - m_layers.clear(); - OnAtlasCleared(this); -} - -void NzGuillotineImageAtlas::Free(NzSparsePtr rects, NzSparsePtr layers, unsigned int count) -{ - for (unsigned int i = 0; i < count; ++i) + namespace { - #ifdef NAZARA_DEBUG - if (layers[i] >= m_layers.size()) + const unsigned int s_atlasStartSize = 512; + } + + GuillotineImageAtlas::GuillotineImageAtlas() : + m_rectChoiceHeuristic(GuillotineBinPack::RectBestAreaFit), + m_rectSplitHeuristic(GuillotineBinPack::SplitMinimizeArea) + { + } + + GuillotineImageAtlas::~GuillotineImageAtlas() = default; + + void GuillotineImageAtlas::Clear() + { + m_layers.clear(); + OnAtlasCleared(this); + } + + void GuillotineImageAtlas::Free(SparsePtr rects, SparsePtr layers, unsigned int count) + { + for (unsigned int i = 0; i < count; ++i) { - NazaraWarning("Rectangle #" + NzString::Number(i) + " belong to an out-of-bounds layer (" + NzString::Number(i) + " >= " + NzString::Number(m_layers.size()) + ")"); - continue; + #ifdef NAZARA_DEBUG + if (layers[i] >= m_layers.size()) + { + NazaraWarning("Rectangle #" + String::Number(i) + " belong to an out-of-bounds layer (" + String::Number(i) + " >= " + String::Number(m_layers.size()) + ")"); + continue; + } + #endif + + m_layers[layers[i]].binPack.FreeRectangle(rects[i]); + m_layers[layers[i]].freedRectangles++; + } + } + + GuillotineBinPack::FreeRectChoiceHeuristic GuillotineImageAtlas::GetRectChoiceHeuristic() const + { + return m_rectChoiceHeuristic; + } + + GuillotineBinPack::GuillotineSplitHeuristic GuillotineImageAtlas::GetRectSplitHeuristic() const + { + return m_rectSplitHeuristic; + } + + AbstractImage* GuillotineImageAtlas::GetLayer(unsigned int layerIndex) const + { + #if NAZARA_UTILITY_SAFE + if (layerIndex >= m_layers.size()) + { + NazaraError("Layer index out of range (" + String::Number(layerIndex) + " >= " + String::Number(m_layers.size()) + ')'); + return nullptr; } #endif - m_layers[layers[i]].binPack.FreeRectangle(rects[i]); - m_layers[layers[i]].freedRectangles++; + Layer& layer = m_layers[layerIndex]; + ProcessGlyphQueue(layer); + + return layer.image.get(); } -} -NzGuillotineBinPack::FreeRectChoiceHeuristic NzGuillotineImageAtlas::GetRectChoiceHeuristic() const -{ - return m_rectChoiceHeuristic; -} - -NzGuillotineBinPack::GuillotineSplitHeuristic NzGuillotineImageAtlas::GetRectSplitHeuristic() const -{ - return m_rectSplitHeuristic; -} - -NzAbstractImage* NzGuillotineImageAtlas::GetLayer(unsigned int layerIndex) const -{ - #if NAZARA_UTILITY_SAFE - if (layerIndex >= m_layers.size()) + unsigned int GuillotineImageAtlas::GetLayerCount() const { - NazaraError("Layer index out of range (" + NzString::Number(layerIndex) + " >= " + NzString::Number(m_layers.size()) + ')'); - return nullptr; + return m_layers.size(); } - #endif - Layer& layer = m_layers[layerIndex]; - ProcessGlyphQueue(layer); - - return layer.image.get(); -} - -unsigned int NzGuillotineImageAtlas::GetLayerCount() const -{ - return m_layers.size(); -} - -nzUInt32 NzGuillotineImageAtlas::GetStorage() const -{ - return nzDataStorage_Software; -} - -bool NzGuillotineImageAtlas::Insert(const NzImage& image, NzRectui* rect, bool* flipped, unsigned int* layerIndex) -{ - if (m_layers.empty()) - // On créé une première couche s'il n'y en a pas - m_layers.resize(1); - - // Cette fonction ne fait qu'insérer un rectangle de façon virtuelle, l'insertion des images se fait après - for (unsigned int i = 0; i < m_layers.size(); ++i) + UInt32 GuillotineImageAtlas::GetStorage() const { - Layer& layer = m_layers[i]; + return DataStorage_Software; + } - // Une fois qu'un certain nombre de rectangles ont étés libérés d'une couche, on fusionne les rectangles libres - if (layer.freedRectangles > 10) // Valeur totalement arbitraire + bool GuillotineImageAtlas::Insert(const Image& image, Rectui* rect, bool* flipped, unsigned int* layerIndex) + { + if (m_layers.empty()) + // On créé une première couche s'il n'y en a pas + m_layers.resize(1); + + // Cette fonction ne fait qu'insérer un rectangle de façon virtuelle, l'insertion des images se fait après + for (unsigned int i = 0; i < m_layers.size(); ++i) { - while (layer.binPack.MergeFreeRectangles()); // Tant qu'une fusion est possible - layer.freedRectangles = 0; // Et on repart de zéro + Layer& layer = m_layers[i]; + + // Une fois qu'un certain nombre de rectangles ont étés libérés d'une couche, on fusionne les rectangles libres + if (layer.freedRectangles > 10) // Valeur totalement arbitraire + { + while (layer.binPack.MergeFreeRectangles()); // Tant qu'une fusion est possible + layer.freedRectangles = 0; // Et on repart de zéro + } + + if (layer.binPack.Insert(rect, flipped, 1, false, m_rectChoiceHeuristic, m_rectSplitHeuristic)) + { + // Insertion réussie dans l'une des couches, on place le glyphe en file d'attente + layer.queuedGlyphs.resize(layer.queuedGlyphs.size()+1); + QueuedGlyph& glyph = layer.queuedGlyphs.back(); + glyph.flipped = *flipped; + glyph.image = image; // Merci le Copy-On-Write + glyph.rect = *rect; + + *layerIndex = i; + return true; + } + else if (i == m_layers.size() - 1) // Dernière itération ? + { + // Dernière couche, et le glyphe ne rentre pas, peut-on agrandir la taille de l'image ? + Vector2ui newSize = layer.binPack.GetSize()*2; + if (newSize == Vector2ui::Zero()) + newSize.Set(s_atlasStartSize); + + if (ResizeLayer(layer, newSize)) + { + // Oui on peut ! + layer.binPack.Expand(newSize); // On ajuste l'atlas virtuel + + // Et on relance la boucle sur la nouvelle dernière couche + i--; + } + else + { + // On ne peut plus agrandir la dernière couche, il est temps d'en créer une nouvelle + newSize.Set(s_atlasStartSize); + + Layer newLayer; + if (!ResizeLayer(newLayer, newSize)) + { + // Impossible d'allouer une nouvelle couche, nous manquons probablement de mémoire (ou le glyphe est trop grand) + NazaraError("Failed to allocate new layer, we are probably out of memory"); + return false; + } + + newLayer.binPack.Reset(newSize); + + m_layers.emplace_back(std::move(newLayer)); // Insertion du layer + + // On laisse la boucle insérer toute seule le rectangle à la prochaine itération + } + } } - if (layer.binPack.Insert(rect, flipped, 1, false, m_rectChoiceHeuristic, m_rectSplitHeuristic)) - { - // Insertion réussie dans l'une des couches, on place le glyphe en file d'attente - layer.queuedGlyphs.resize(layer.queuedGlyphs.size()+1); - QueuedGlyph& glyph = layer.queuedGlyphs.back(); - glyph.flipped = *flipped; - glyph.image = image; // Merci le Copy-On-Write - glyph.rect = *rect; + NazaraInternalError("Unknown error"); // Normalement on ne peut pas arriver ici + return false; + } - *layerIndex = i; + void GuillotineImageAtlas::SetRectChoiceHeuristic(GuillotineBinPack::FreeRectChoiceHeuristic heuristic) + { + m_rectChoiceHeuristic = heuristic; + } + + void GuillotineImageAtlas::SetRectSplitHeuristic(GuillotineBinPack::GuillotineSplitHeuristic heuristic) + { + m_rectSplitHeuristic = heuristic; + } + + AbstractImage* GuillotineImageAtlas::ResizeImage(AbstractImage* oldImage, const Vector2ui& size) const + { + std::unique_ptr newImage(new Image(ImageType_2D, PixelFormatType_A8, size.x, size.y)); + if (oldImage) + { + Image& image = *static_cast(oldImage); + newImage->Copy(image, Rectui(size), Vector2ui(0, 0)); // Copie des anciennes données + } + + return newImage.release(); + } + + bool GuillotineImageAtlas::ResizeLayer(Layer& layer, const Vector2ui& size) + { + AbstractImage* oldLayer = layer.image.get(); + + std::unique_ptr newImage(ResizeImage(layer.image.get(), size)); + if (!newImage) + return false; // Nous n'avons pas pu allouer + + if (newImage.get() == oldLayer) // Le layer a été agrandi dans le même objet, pas de souci + { + newImage.release(); // On possède déjà un unique_ptr sur cette ressource return true; } - else if (i == m_layers.size() - 1) // Dernière itération ? - { - // Dernière couche, et le glyphe ne rentre pas, peut-on agrandir la taille de l'image ? - NzVector2ui newSize = layer.binPack.GetSize()*2; - if (newSize == NzVector2ui::Zero()) - newSize.Set(s_atlasStartSize); - if (ResizeLayer(layer, newSize)) - { - // Oui on peut ! - layer.binPack.Expand(newSize); // On ajuste l'atlas virtuel + // On indique à ceux que ça intéresse qu'on a changé de pointeur + // (chose très importante pour ceux qui le stockent) + OnAtlasLayerChange(this, layer.image.get(), newImage.get()); - // Et on relance la boucle sur la nouvelle dernière couche - i--; - } - else - { - // On ne peut plus agrandir la dernière couche, il est temps d'en créer une nouvelle - newSize.Set(s_atlasStartSize); + // Et on ne met à jour le pointeur qu'après (car cette ligne libère également l'ancienne image) + layer.image = std::move(newImage); - Layer newLayer; - if (!ResizeLayer(newLayer, newSize)) - { - // Impossible d'allouer une nouvelle couche, nous manquons probablement de mémoire (ou le glyphe est trop grand) - NazaraError("Failed to allocate new layer, we are probably out of memory"); - return false; - } - - newLayer.binPack.Reset(newSize); - - m_layers.emplace_back(std::move(newLayer)); // Insertion du layer - - // On laisse la boucle insérer toute seule le rectangle à la prochaine itération - } - } - } - - NazaraInternalError("Unknown error"); // Normalement on ne peut pas arriver ici - return false; -} - -void NzGuillotineImageAtlas::SetRectChoiceHeuristic(NzGuillotineBinPack::FreeRectChoiceHeuristic heuristic) -{ - m_rectChoiceHeuristic = heuristic; -} - -void NzGuillotineImageAtlas::SetRectSplitHeuristic(NzGuillotineBinPack::GuillotineSplitHeuristic heuristic) -{ - m_rectSplitHeuristic = heuristic; -} - -NzAbstractImage* NzGuillotineImageAtlas::ResizeImage(NzAbstractImage* oldImage, const NzVector2ui& size) const -{ - std::unique_ptr newImage(new NzImage(nzImageType_2D, nzPixelFormat_A8, size.x, size.y)); - if (oldImage) - { - NzImage& image = *static_cast(oldImage); - newImage->Copy(image, NzRectui(size), NzVector2ui(0, 0)); // Copie des anciennes données - } - - return newImage.release(); -} - -bool NzGuillotineImageAtlas::ResizeLayer(Layer& layer, const NzVector2ui& size) -{ - NzAbstractImage* oldLayer = layer.image.get(); - - std::unique_ptr newImage(ResizeImage(layer.image.get(), size)); - if (!newImage) - return false; // Nous n'avons pas pu allouer - - if (newImage.get() == oldLayer) // Le layer a été agrandi dans le même objet, pas de souci - { - newImage.release(); // On possède déjà un unique_ptr sur cette ressource return true; } - // On indique à ceux que ça intéresse qu'on a changé de pointeur - // (chose très importante pour ceux qui le stockent) - OnAtlasLayerChange(this, layer.image.get(), newImage.get()); - - // Et on ne met à jour le pointeur qu'après (car cette ligne libère également l'ancienne image) - layer.image = std::move(newImage); - - return true; -} - -void NzGuillotineImageAtlas::ProcessGlyphQueue(Layer& layer) const -{ - std::vector pixelBuffer; - - for (QueuedGlyph& glyph : layer.queuedGlyphs) + void GuillotineImageAtlas::ProcessGlyphQueue(Layer& layer) const { - unsigned int glyphWidth = glyph.image.GetWidth(); - unsigned int glyphHeight = glyph.image.GetHeight(); + std::vector pixelBuffer; - // Calcul de l'éventuel padding (pixels de contour) - unsigned int paddingX; - unsigned int paddingY; - if (glyph.flipped) + for (QueuedGlyph& glyph : layer.queuedGlyphs) { - paddingX = (glyph.rect.height - glyphWidth)/2; - paddingY = (glyph.rect.width - glyphHeight)/2; - } - else - { - paddingX = (glyph.rect.width - glyphWidth)/2; - paddingY = (glyph.rect.height - glyphHeight)/2; - } + unsigned int glyphWidth = glyph.image.GetWidth(); + unsigned int glyphHeight = glyph.image.GetHeight(); - if (paddingX > 0 || paddingY > 0) - { - // On remplit les contours - pixelBuffer.resize(glyph.rect.width * glyph.rect.height); - std::memset(pixelBuffer.data(), 0, glyph.rect.width*glyph.rect.height*sizeof(nzUInt8)); - - layer.image->Update(pixelBuffer.data(), glyph.rect); - } - - const nzUInt8* pixels; - // On copie le glyphe dans l'atlas - if (glyph.flipped) - { - pixelBuffer.resize(glyphHeight * glyphWidth); - - // On tourne le glyphe pour qu'il rentre dans le rectangle - const nzUInt8* src = glyph.image.GetConstPixels(); - nzUInt8* ptr = pixelBuffer.data(); - - unsigned int lineStride = glyphWidth*sizeof(nzUInt8); // BPP = 1 - src += lineStride-1; // Départ en haut à droite - for (unsigned int x = 0; x < glyphWidth; ++x) + // Calcul de l'éventuel padding (pixels de contour) + unsigned int paddingX; + unsigned int paddingY; + if (glyph.flipped) { - for (unsigned int y = 0; y < glyphHeight; ++y) - { - *ptr++ = *src; - src += lineStride; - } - - src -= glyphHeight*lineStride + 1; + paddingX = (glyph.rect.height - glyphWidth)/2; + paddingY = (glyph.rect.width - glyphHeight)/2; + } + else + { + paddingX = (glyph.rect.width - glyphWidth)/2; + paddingY = (glyph.rect.height - glyphHeight)/2; } - pixels = pixelBuffer.data(); - std::swap(glyphWidth, glyphHeight); + if (paddingX > 0 || paddingY > 0) + { + // On remplit les contours + pixelBuffer.resize(glyph.rect.width * glyph.rect.height); + std::memset(pixelBuffer.data(), 0, glyph.rect.width*glyph.rect.height*sizeof(UInt8)); + + layer.image->Update(pixelBuffer.data(), glyph.rect); + } + + const UInt8* pixels; + // On copie le glyphe dans l'atlas + if (glyph.flipped) + { + pixelBuffer.resize(glyphHeight * glyphWidth); + + // On tourne le glyphe pour qu'il rentre dans le rectangle + const UInt8* src = glyph.image.GetConstPixels(); + UInt8* ptr = pixelBuffer.data(); + + unsigned int lineStride = glyphWidth*sizeof(UInt8); // BPP = 1 + src += lineStride-1; // Départ en haut à droite + for (unsigned int x = 0; x < glyphWidth; ++x) + { + for (unsigned int y = 0; y < glyphHeight; ++y) + { + *ptr++ = *src; + src += lineStride; + } + + src -= glyphHeight*lineStride + 1; + } + + pixels = pixelBuffer.data(); + std::swap(glyphWidth, glyphHeight); + } + else + pixels = glyph.image.GetConstPixels(); + + layer.image->Update(pixels, Rectui(glyph.rect.x + paddingX, glyph.rect.y + paddingY, glyphWidth, glyphHeight), 0, glyphWidth, glyphHeight); + glyph.image.Destroy(); // On libère l'image dès que possible (pour réduire la consommation) } - else - pixels = glyph.image.GetConstPixels(); - layer.image->Update(pixels, NzRectui(glyph.rect.x + paddingX, glyph.rect.y + paddingY, glyphWidth, glyphHeight), 0, glyphWidth, glyphHeight); - glyph.image.Destroy(); // On libère l'image dès que possible (pour réduire la consommation) + layer.queuedGlyphs.clear(); } - - layer.queuedGlyphs.clear(); } diff --git a/src/Nazara/Utility/Icon.cpp b/src/Nazara/Utility/Icon.cpp index b67b42076..0fa4fba11 100644 --- a/src/Nazara/Utility/Icon.cpp +++ b/src/Nazara/Utility/Icon.cpp @@ -14,45 +14,48 @@ #include -NzIcon::NzIcon() : -m_impl(nullptr) +namespace Nz { -} - -NzIcon::~NzIcon() -{ - Destroy(); -} - -bool NzIcon::Create(const NzImage& icon) -{ - Destroy(); - - m_impl = new NzIconImpl; - if (!m_impl->Create(icon)) + Icon::Icon() : + m_impl(nullptr) { - NazaraError("Failed to create icon implementation"); - delete m_impl; - m_impl = nullptr; - - return false; } - return true; -} - -void NzIcon::Destroy() -{ - if (m_impl) + Icon::~Icon() { - m_impl->Destroy(); + Destroy(); + } - delete m_impl; - m_impl = nullptr; + bool Icon::Create(const Image& icon) + { + Destroy(); + + m_impl = new IconImpl; + if (!m_impl->Create(icon)) + { + NazaraError("Failed to create icon implementation"); + delete m_impl; + m_impl = nullptr; + + return false; + } + + return true; + } + + void Icon::Destroy() + { + if (m_impl) + { + m_impl->Destroy(); + + delete m_impl; + m_impl = nullptr; + } + } + + bool Icon::IsValid() const + { + return m_impl != nullptr; } } - -bool NzIcon::IsValid() const -{ - return m_impl != nullptr; -} diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index e356b4fbb..98dd5117d 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -16,1362 +16,1365 @@ ///TODO: Rendre les méthodes exception-safe (faire usage du RAII) ///FIXME: Gérer correctement les formats utilisant moins d'un octet par pixel -namespace +namespace Nz { - inline unsigned int GetLevelSize(unsigned int size, nzUInt8 level) + namespace { - if (size == 0) // Possible dans le cas d'une image invalide - return 0; - - 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]; - } -} - -bool NzImageParams::IsValid() const -{ - return true; // Rien à vérifier -} - -NzImage::NzImage() : -m_sharedImage(&emptyImage) -{ -} - -NzImage::NzImage(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount) : -m_sharedImage(&emptyImage) -{ - NzErrorFlags flags(nzErrorFlag_ThrowException); - Create(type, format, width, height, depth, levelCount); -} - -NzImage::NzImage(const NzImage& image) : -NzRefCounted(), -NzResource(), -m_sharedImage(image.m_sharedImage) -{ - if (m_sharedImage != &emptyImage) - m_sharedImage->refCount++; -} - -NzImage::NzImage(SharedImage* sharedImage) : -m_sharedImage(sharedImage) -{ -} - -NzImage::~NzImage() -{ - OnImageRelease(this); - - Destroy(); -} - -bool NzImage::Convert(nzPixelFormat newFormat) -{ - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) - { - NazaraError("Image must be valid"); - return false; - } - - if (!NzPixelFormat::IsValid(newFormat)) - { - NazaraError("Invalid pixel format"); - return false; - } - - if (!NzPixelFormat::IsConversionSupported(m_sharedImage->format, newFormat)) - { - NazaraError("Conversion from " + NzPixelFormat::ToString(m_sharedImage->format) + " to " + NzPixelFormat::ToString(newFormat) + " is not supported"); - return false; - } - #endif - - if (m_sharedImage->format == newFormat) - return true; - - SharedImage::PixelContainer levels(m_sharedImage->levels.size()); - - unsigned int width = m_sharedImage->width; - unsigned int height = m_sharedImage->height; - - // Les images 3D et cubemaps sont stockés de la même façon - unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth; - - for (unsigned int i = 0; i < levels.size(); ++i) - { - unsigned int pixelsPerFace = width * height; - levels[i].reset(new nzUInt8[pixelsPerFace * depth * NzPixelFormat::GetBytesPerPixel(newFormat)]); - - nzUInt8* dst = levels[i].get(); - nzUInt8* src = m_sharedImage->levels[i].get(); - unsigned int srcStride = pixelsPerFace * NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); - unsigned int dstStride = pixelsPerFace * NzPixelFormat::GetBytesPerPixel(newFormat); - - for (unsigned int d = 0; d < depth; ++d) + inline unsigned int GetLevelSize(unsigned int size, UInt8 level) { - if (!NzPixelFormat::Convert(m_sharedImage->format, newFormat, src, &src[srcStride], dst)) - { - NazaraError("Failed to convert image"); - return false; - } + if (size == 0) // Possible dans le cas d'une image invalide + return 0; - src += srcStride; - dst += dstStride; + return std::max(size >> level, 1U); } - if (width > 1) - width >>= 1; - - if (height > 1) - height >>= 1; - - if (depth > 1 && m_sharedImage->type != nzImageType_Cubemap) - depth >>= 1; + inline UInt8* GetPixelPtr(UInt8* base, UInt8 bpp, unsigned int x, unsigned int y, unsigned int z, unsigned int width, unsigned int height) + { + return &base[(width*(height*z + y) + x)*bpp]; + } } - SharedImage* newImage = new SharedImage(1, m_sharedImage->type, newFormat, std::move(levels), m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); - - ReleaseImage(); - m_sharedImage = newImage; - - return true; -} - -void NzImage::Copy(const NzImage& source, const NzBoxui& srcBox, const NzVector3ui& dstPos) -{ - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) + bool ImageParams::IsValid() const { - NazaraError("Image must be valid"); - return; + return true; // Rien à vérifier } - if (!source.IsValid()) + Image::Image() : + m_sharedImage(&emptyImage) { - NazaraError("Source image must be valid"); - return; } - if (source.GetFormat() != m_sharedImage->format) + Image::Image(ImageType type, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, UInt8 levelCount) : + m_sharedImage(&emptyImage) { - NazaraError("Source image format does not match destination image format"); - return; - } - #endif - - const nzUInt8* srcPtr = source.GetConstPixels(srcBox.x, srcBox.y, srcBox.z); - #if NAZARA_UTILITY_SAFE - if (!srcPtr) - { - NazaraError("Failed to access pixels"); - return; - } - #endif - - nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); - nzUInt8* dstPtr = GetPixelPtr(m_sharedImage->levels[0].get(), bpp, dstPos.x, dstPos.y, dstPos.z, m_sharedImage->width, m_sharedImage->height); - - Copy(dstPtr, srcPtr, bpp, srcBox.width, srcBox.height, srcBox.depth, m_sharedImage->width, m_sharedImage->height, source.GetWidth(), source.GetHeight()); -} - -bool NzImage::Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount) -{ - Destroy(); - - #if NAZARA_UTILITY_SAFE - if (!NzPixelFormat::IsValid(format)) - { - NazaraError("Invalid pixel format"); - return false; + ErrorFlags flags(ErrorFlag_ThrowException); + Create(type, format, width, height, depth, levelCount); } - if (width == 0) + Image::Image(const Image& image) : + RefCounted(), + Resource(), + m_sharedImage(image.m_sharedImage) { - NazaraError("Width must be at least 1 (0)"); - return false; + if (m_sharedImage != &emptyImage) + m_sharedImage->refCount++; } - if (height == 0) + Image::Image(SharedImage* sharedImage) : + m_sharedImage(sharedImage) { - NazaraError("Height must be at least 1 (0)"); - return false; } - if (depth == 0) + Image::~Image() { - NazaraError("Depth must be at least 1 (0)"); - return false; + OnImageRelease(this); + + Destroy(); } - switch (type) + bool Image::Convert(PixelFormatType newFormat) { - case nzImageType_1D: + #if NAZARA_UTILITY_SAFE + if (m_sharedImage == &emptyImage) + { + NazaraError("Image must be valid"); + return false; + } + + if (!NzPixelFormat::IsValid(newFormat)) + { + NazaraError("Invalid pixel format"); + return false; + } + + if (!NzPixelFormat::IsConversionSupported(m_sharedImage->format, newFormat)) + { + NazaraError("Conversion from " + NzPixelFormat::ToString(m_sharedImage->format) + " to " + NzPixelFormat::ToString(newFormat) + " is not supported"); + return false; + } + #endif + + if (m_sharedImage->format == newFormat) + return true; + + SharedImage::PixelContainer levels(m_sharedImage->levels.size()); + + unsigned int width = m_sharedImage->width; + unsigned int height = m_sharedImage->height; + + // Les images 3D et cubemaps sont stockés de la même façon + unsigned int depth = (m_sharedImage->type == ImageType_Cubemap) ? 6 : m_sharedImage->depth; + + for (unsigned int i = 0; i < levels.size(); ++i) + { + unsigned int pixelsPerFace = width * height; + levels[i].reset(new UInt8[pixelsPerFace * depth * NzPixelFormat::GetBytesPerPixel(newFormat)]); + + UInt8* dst = levels[i].get(); + UInt8* src = m_sharedImage->levels[i].get(); + unsigned int srcStride = pixelsPerFace * NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); + unsigned int dstStride = pixelsPerFace * NzPixelFormat::GetBytesPerPixel(newFormat); + + for (unsigned int d = 0; d < depth; ++d) + { + if (!NzPixelFormat::Convert(m_sharedImage->format, newFormat, src, &src[srcStride], dst)) + { + NazaraError("Failed to convert image"); + return false; + } + + src += srcStride; + dst += dstStride; + } + + if (width > 1) + width >>= 1; + if (height > 1) - { - NazaraError("1D textures must be 1 tall"); - return false; - } + height >>= 1; - if (depth > 1) - { - NazaraError("1D textures must be 1 deep"); - return false; - } - break; - - case nzImageType_1D_Array: - case nzImageType_2D: - if (depth > 1) - { - NazaraError("2D textures must be 1 deep"); - return false; - } - break; - - case nzImageType_2D_Array: - case nzImageType_3D: - break; - - case nzImageType_Cubemap: - if (depth > 1) - { - NazaraError("Cubemaps must be 1 deep"); - return false; - } - - if (width != height) - { - NazaraError("Cubemaps must have square dimensions"); - return false; - } - break; - - default: - NazaraInternalError("Image type not handled"); - return false; - } - #endif - - levelCount = std::min(levelCount, GetMaxLevel(type, width, height, depth)); - - SharedImage::PixelContainer levels(levelCount); - - unsigned int w = width; - unsigned int h = height; - unsigned int d = (type == nzImageType_Cubemap) ? 6 : depth; - - for (unsigned int i = 0; i < levelCount; ++i) - { - // Cette allocation est protégée car sa taille dépend directement de paramètres utilisateurs - try - { - levels[i].reset(new nzUInt8[w * h * d * NzPixelFormat::GetBytesPerPixel(format)]); - - if (w > 1) - w >>= 1; - - if (h > 1) - h >>= 1; - - if (d > 1 && type != nzImageType_Cubemap) - d >>= 1; + if (depth > 1 && m_sharedImage->type != ImageType_Cubemap) + depth >>= 1; } - catch (const std::exception& e) - { - NazaraError("Failed to allocate image's level " + NzString::Number(i) + " (" + NzString(e.what()) + ')'); - return false; - } - } - m_sharedImage = new SharedImage(1, type, format, std::move(levels), width, height, depth); + SharedImage* newImage = new SharedImage(1, m_sharedImage->type, newFormat, std::move(levels), m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); - return true; -} - -void NzImage::Destroy() -{ - if (m_sharedImage != &emptyImage) - { - OnImageDestroy(this); ReleaseImage(); - } -} + m_sharedImage = newImage; -bool NzImage::Fill(const NzColor& color) -{ - ///FIXME: Pourquoi cette méthode alloue une nouvelle image plutôt que de remplir l'existante ? - - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) - { - NazaraError("Image must be valid"); - return false; + return true; } - if (NzPixelFormat::IsCompressed(m_sharedImage->format)) + void Image::Copy(const Image& source, const Boxui& srcBox, const Vector3ui& dstPos) { - NazaraError("Cannot access pixels from compressed image"); - return false; - } - #endif - - nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); - std::unique_ptr colorBuffer(new nzUInt8[bpp]); - if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, colorBuffer.get())) - { - NazaraError("Failed to convert RGBA8 to " + NzPixelFormat::ToString(m_sharedImage->format)); - return false; - } - - SharedImage::PixelContainer levels(m_sharedImage->levels.size()); - - unsigned int width = m_sharedImage->width; - unsigned int height = m_sharedImage->height; - - // Les images 3D et cubemaps sont stockés de la même façon - unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : m_sharedImage->depth; - - for (unsigned int i = 0; i < levels.size(); ++i) - { - unsigned int size = width*height*depth*bpp; - levels[i].reset(new nzUInt8[size]); - - nzUInt8* ptr = levels[i].get(); - nzUInt8* end = &ptr[size]; - - while (ptr < end) + #if NAZARA_UTILITY_SAFE + if (m_sharedImage == &emptyImage) { - std::memcpy(ptr, colorBuffer.get(), bpp); - ptr += bpp; + NazaraError("Image must be valid"); + return; } - if (width > 1U) - width >>= 1; - - if (height > 1U) - height >>= 1; - - if (depth > 1U && m_sharedImage->type != nzImageType_Cubemap) - depth >>= 1; - } - - SharedImage* newImage = new SharedImage(1, m_sharedImage->type, m_sharedImage->format, std::move(levels), m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); - - ReleaseImage(); - m_sharedImage = newImage; - - return true; -} - -bool NzImage::Fill(const NzColor& color, const NzBoxui& box) -{ - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) - { - NazaraError("Image must be valid"); - return false; - } - - if (!box.IsValid()) - { - NazaraError("Invalid rectangle"); - return false; - } - - if (box.x+box.width > m_sharedImage->width || box.y+box.height > m_sharedImage->height || box.z+box.depth > m_sharedImage->depth) - { - NazaraError("Box dimensions are out of bounds"); - return false; - } - #endif - - EnsureOwnership(); - - nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); - std::unique_ptr colorBuffer(new nzUInt8[bpp]); - if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, colorBuffer.get())) - { - NazaraError("Failed to convert RGBA8 to " + NzPixelFormat::ToString(m_sharedImage->format)); - return false; - } - - ///FIXME: L'algorithme a du mal avec un bpp non multiple de 2 - nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->levels[0].get(), bpp, box.x, box.y, box.z, m_sharedImage->width, m_sharedImage->height); - unsigned int srcStride = box.width * bpp; - unsigned int dstStride = m_sharedImage->width * bpp; - unsigned int faceSize = dstStride * m_sharedImage->height; - for (unsigned int z = 0; z < box.depth; ++z) - { - nzUInt8* facePixels = dstPixels; - for (unsigned int y = 0; y < box.height; ++y) + if (!source.IsValid()) { - nzUInt8* start = facePixels; - nzUInt8* end = facePixels + srcStride; + NazaraError("Source image must be valid"); + return; + } + + if (source.GetFormat() != m_sharedImage->format) + { + NazaraError("Source image format does not match destination image format"); + return; + } + #endif + + const UInt8* srcPtr = source.GetConstPixels(srcBox.x, srcBox.y, srcBox.z); + #if NAZARA_UTILITY_SAFE + if (!srcPtr) + { + NazaraError("Failed to access pixels"); + return; + } + #endif + + UInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); + UInt8* dstPtr = GetPixelPtr(m_sharedImage->levels[0].get(), bpp, dstPos.x, dstPos.y, dstPos.z, m_sharedImage->width, m_sharedImage->height); + + Copy(dstPtr, srcPtr, bpp, srcBox.width, srcBox.height, srcBox.depth, m_sharedImage->width, m_sharedImage->height, source.GetWidth(), source.GetHeight()); + } + + bool Image::Create(ImageType type, PixelFormatType format, unsigned int width, unsigned int height, unsigned int depth, UInt8 levelCount) + { + Destroy(); + + #if NAZARA_UTILITY_SAFE + if (!NzPixelFormat::IsValid(format)) + { + NazaraError("Invalid pixel format"); + return false; + } + + if (width == 0) + { + NazaraError("Width must be at least 1 (0)"); + return false; + } + + if (height == 0) + { + NazaraError("Height must be at least 1 (0)"); + return false; + } + + if (depth == 0) + { + NazaraError("Depth must be at least 1 (0)"); + return false; + } + + switch (type) + { + case ImageType_1D: + if (height > 1) + { + NazaraError("1D textures must be 1 tall"); + return false; + } + + if (depth > 1) + { + NazaraError("1D textures must be 1 deep"); + return false; + } + break; + + case ImageType_1D_Array: + case ImageType_2D: + if (depth > 1) + { + NazaraError("2D textures must be 1 deep"); + return false; + } + break; + + case ImageType_2D_Array: + case ImageType_3D: + break; + + case ImageType_Cubemap: + if (depth > 1) + { + NazaraError("Cubemaps must be 1 deep"); + return false; + } + + if (width != height) + { + NazaraError("Cubemaps must have square dimensions"); + return false; + } + break; + + default: + NazaraInternalError("Image type not handled"); + return false; + } + #endif + + levelCount = std::min(levelCount, GetMaxLevel(type, width, height, depth)); + + SharedImage::PixelContainer levels(levelCount); + + unsigned int w = width; + unsigned int h = height; + unsigned int d = (type == ImageType_Cubemap) ? 6 : depth; + + for (unsigned int i = 0; i < levelCount; ++i) + { + // Cette allocation est protégée car sa taille dépend directement de paramètres utilisateurs + try + { + levels[i].reset(new UInt8[w * h * d * NzPixelFormat::GetBytesPerPixel(format)]); + + if (w > 1) + w >>= 1; + + if (h > 1) + h >>= 1; + + if (d > 1 && type != ImageType_Cubemap) + d >>= 1; + } + catch (const std::exception& e) + { + NazaraError("Failed to allocate image's level " + String::Number(i) + " (" + String(e.what()) + ')'); + return false; + } + } + + m_sharedImage = new SharedImage(1, type, format, std::move(levels), width, height, depth); + + return true; + } + + void Image::Destroy() + { + if (m_sharedImage != &emptyImage) + { + OnImageDestroy(this); + ReleaseImage(); + } + } + + bool Image::Fill(const Color& color) + { + ///FIXME: Pourquoi cette méthode alloue une nouvelle image plutôt que de remplir l'existante ? + + #if NAZARA_UTILITY_SAFE + if (m_sharedImage == &emptyImage) + { + NazaraError("Image must be valid"); + return false; + } + + if (NzPixelFormat::IsCompressed(m_sharedImage->format)) + { + NazaraError("Cannot access pixels from compressed image"); + return false; + } + #endif + + UInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); + std::unique_ptr colorBuffer(new UInt8[bpp]); + if (!NzPixelFormat::Convert(PixelFormatType_RGBA8, m_sharedImage->format, &color.r, colorBuffer.get())) + { + NazaraError("Failed to convert RGBA8 to " + NzPixelFormat::ToString(m_sharedImage->format)); + return false; + } + + SharedImage::PixelContainer levels(m_sharedImage->levels.size()); + + unsigned int width = m_sharedImage->width; + unsigned int height = m_sharedImage->height; + + // Les images 3D et cubemaps sont stockés de la même façon + unsigned int depth = (m_sharedImage->type == ImageType_Cubemap) ? 6 : m_sharedImage->depth; + + for (unsigned int i = 0; i < levels.size(); ++i) + { + unsigned int size = width*height*depth*bpp; + levels[i].reset(new UInt8[size]); + + UInt8* ptr = levels[i].get(); + UInt8* end = &ptr[size]; + + while (ptr < end) + { + std::memcpy(ptr, colorBuffer.get(), bpp); + ptr += bpp; + } + + if (width > 1U) + width >>= 1; + + if (height > 1U) + height >>= 1; + + if (depth > 1U && m_sharedImage->type != ImageType_Cubemap) + depth >>= 1; + } + + SharedImage* newImage = new SharedImage(1, m_sharedImage->type, m_sharedImage->format, std::move(levels), m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); + + ReleaseImage(); + m_sharedImage = newImage; + + return true; + } + + bool Image::Fill(const Color& color, const Boxui& box) + { + #if NAZARA_UTILITY_SAFE + if (m_sharedImage == &emptyImage) + { + NazaraError("Image must be valid"); + return false; + } + + if (!box.IsValid()) + { + NazaraError("Invalid rectangle"); + return false; + } + + if (box.x+box.width > m_sharedImage->width || box.y+box.height > m_sharedImage->height || box.z+box.depth > m_sharedImage->depth) + { + NazaraError("Box dimensions are out of bounds"); + return false; + } + #endif + + EnsureOwnership(); + + UInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); + std::unique_ptr colorBuffer(new UInt8[bpp]); + if (!NzPixelFormat::Convert(PixelFormatType_RGBA8, m_sharedImage->format, &color.r, colorBuffer.get())) + { + NazaraError("Failed to convert RGBA8 to " + NzPixelFormat::ToString(m_sharedImage->format)); + return false; + } + + ///FIXME: L'algorithme a du mal avec un bpp non multiple de 2 + UInt8* dstPixels = GetPixelPtr(m_sharedImage->levels[0].get(), bpp, box.x, box.y, box.z, m_sharedImage->width, m_sharedImage->height); + unsigned int srcStride = box.width * bpp; + unsigned int dstStride = m_sharedImage->width * bpp; + unsigned int faceSize = dstStride * m_sharedImage->height; + for (unsigned int z = 0; z < box.depth; ++z) + { + UInt8* facePixels = dstPixels; + for (unsigned int y = 0; y < box.height; ++y) + { + UInt8* start = facePixels; + UInt8* end = facePixels + srcStride; + while (start < end) + { + std::memcpy(start, colorBuffer.get(), bpp); + start += bpp; + } + + facePixels += dstStride; + } + + dstPixels += faceSize; + } + + return true; + } + + bool Image::Fill(const Color& color, const Rectui& rect, unsigned int z) + { + #if NAZARA_UTILITY_SAFE + if (m_sharedImage == &emptyImage) + { + 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 == ImageType_Cubemap) ? 6 : m_sharedImage->depth; + if (z >= depth) + { + NazaraError("Z value exceeds depth (" + String::Number(z) + " >= " + String::Number(depth) + ')'); + return false; + } + #endif + + EnsureOwnership(); + + UInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); + std::unique_ptr colorBuffer(new UInt8[bpp]); + if (!NzPixelFormat::Convert(PixelFormatType_RGBA8, m_sharedImage->format, &color.r, colorBuffer.get())) + { + NazaraError("Failed to convert RGBA8 to " + NzPixelFormat::ToString(m_sharedImage->format)); + return false; + } + + ///FIXME: L'algorithme a du mal avec un bpp non multiple de 2 + UInt8* dstPixels = GetPixelPtr(m_sharedImage->levels[0].get(), 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) + { + UInt8* start = dstPixels; + UInt8* end = dstPixels + srcStride; while (start < end) { std::memcpy(start, colorBuffer.get(), bpp); start += bpp; } - facePixels += dstStride; + dstPixels += dstStride; } - dstPixels += faceSize; + return true; } - return true; -} - -bool NzImage::Fill(const NzColor& color, const NzRectui& rect, unsigned int z) -{ - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) + bool Image::FlipHorizontally() { - 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::GetBytesPerPixel(m_sharedImage->format); - std::unique_ptr colorBuffer(new nzUInt8[bpp]); - if (!NzPixelFormat::Convert(nzPixelFormat_RGBA8, m_sharedImage->format, &color.r, colorBuffer.get())) - { - NazaraError("Failed to convert RGBA8 to " + NzPixelFormat::ToString(m_sharedImage->format)); - return false; - } - - ///FIXME: L'algorithme a du mal avec un bpp non multiple de 2 - nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->levels[0].get(), 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) + #if NAZARA_UTILITY_SAFE + if (m_sharedImage == &emptyImage) { - std::memcpy(start, colorBuffer.get(), bpp); - start += bpp; - } - - dstPixels += dstStride; - } - - return true; -} - -bool NzImage::FlipHorizontally() -{ - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) - { - NazaraError("Image must be valid"); - return false; - } - #endif - - EnsureOwnership(); - - 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->levels.size(); ++level) - { - nzUInt8* ptr = m_sharedImage->levels[level].get(); - if (!NzPixelFormat::Flip(nzPixelFlipping_Horizontally, m_sharedImage->format, width, height, depth, ptr, ptr)) - { - NazaraError("Failed to flip image"); + NazaraError("Image must be valid"); return false; } + #endif - if (width > 1U) - width >>= 1; + EnsureOwnership(); - 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 (m_sharedImage == &emptyImage) - { - NazaraError("Image must be valid"); - return false; - } - - if (NzPixelFormat::IsCompressed(m_sharedImage->format)) - { - NazaraError("Cannot flip compressed image"); - return false; - } - #endif - - EnsureOwnership(); - - 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->levels.size(); ++level) - { - nzUInt8* ptr = m_sharedImage->levels[level].get(); - if (!NzPixelFormat::Flip(nzPixelFlipping_Vertically, m_sharedImage->format, width, height, depth, ptr, ptr)) + unsigned int width = m_sharedImage->width; + unsigned int height = m_sharedImage->height; + unsigned int depth = (m_sharedImage->type == ImageType_Cubemap) ? 6 : m_sharedImage->depth; + for (unsigned int level = 0; level < m_sharedImage->levels.size(); ++level) { - NazaraError("Failed to flip image"); - return false; - } - - if (width > 1U) - width >>= 1; - - if (height > 1U) - height >>= 1; - - if (depth > 1U && m_sharedImage->type != nzImageType_Cubemap) - depth >>= 1; - } - - return true; -} - -const nzUInt8* NzImage::GetConstPixels(unsigned int x, unsigned int y, unsigned int z, nzUInt8 level) const -{ - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) - { - NazaraError("Image must be valid"); - return nullptr; - } - - if (level >= m_sharedImage->levels.size()) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levels.size()) + ')'); - return nullptr; - } - #endif - - unsigned int width = GetLevelSize(m_sharedImage->width, level); - #if NAZARA_UTILITY_SAFE - if (x >= width) - { - NazaraError("X value exceeds width (" + NzString::Number(x) + " >= " + NzString::Number(width) + ')'); - return nullptr; - } - #endif - - unsigned int height = GetLevelSize(m_sharedImage->height, level); - #if NAZARA_UTILITY_SAFE - if (y >= height) - { - NazaraError("Y value exceeds height (" + NzString::Number(y) + " >= " + NzString::Number(height) + ')'); - return nullptr; - } - - 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) + ')'); - return nullptr; - } - #endif - - return GetPixelPtr(m_sharedImage->levels[level].get(), NzPixelFormat::GetBytesPerPixel(m_sharedImage->format), x, y, z, width, height); -} - -unsigned int NzImage::GetDepth(nzUInt8 level) const -{ - #if NAZARA_UTILITY_SAFE - if (level >= m_sharedImage->levels.size()) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levels.size()) + ')'); - return 0; - } - #endif - - return GetLevelSize(m_sharedImage->depth, level); -} - -nzPixelFormat NzImage::GetFormat() const -{ - return m_sharedImage->format; -} - -unsigned int NzImage::GetHeight(nzUInt8 level) const -{ - #if NAZARA_UTILITY_SAFE - if (level >= m_sharedImage->levels.size()) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levels.size()) + ')'); - return 0; - } - #endif - - return GetLevelSize(m_sharedImage->height, level); -} - -nzUInt8 NzImage::GetLevelCount() const -{ - return nzUInt8(m_sharedImage->levels.size()); -} - -nzUInt8 NzImage::GetMaxLevel() const -{ - return GetMaxLevel(m_sharedImage->type, m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); -} - -unsigned int NzImage::GetMemoryUsage() const -{ - unsigned int width = m_sharedImage->width; - unsigned int height = m_sharedImage->height; - unsigned int depth = m_sharedImage->depth; - - unsigned int size = 0; - for (unsigned int i = 0; i < m_sharedImage->levels.size(); ++i) - { - size += width * height * depth; - - if (width > 1) - width >>= 1; - - if (height > 1) - height >>= 1; - - if (depth > 1) - depth >>= 1; - } - - if (m_sharedImage->type == nzImageType_Cubemap) - size *= 6; - - return size * NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); -} - -unsigned int NzImage::GetMemoryUsage(nzUInt8 level) const -{ - return (GetLevelSize(m_sharedImage->width, level)) * - (GetLevelSize(m_sharedImage->height, level)) * - ((m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level)) * - NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); -} - -NzColor NzImage::GetPixelColor(unsigned int x, unsigned int y, unsigned int z) const -{ - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) - { - NazaraError("Image must be valid"); - return NzColor(); - } - - if (NzPixelFormat::IsCompressed(m_sharedImage->format)) - { - NazaraError("Cannot access pixels from compressed image"); - return NzColor(); - } - - if (x >= m_sharedImage->width) - { - NazaraError("X value exceeds width (" + NzString::Number(x) + " >= " + NzString::Number(m_sharedImage->width) + ')'); - return NzColor(); - } - - if (y >= m_sharedImage->height) - { - NazaraError("Y value exceeds height (" + NzString::Number(y) + " >= " + NzString::Number(m_sharedImage->height) + ')'); - return NzColor(); - } - - 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 NzColor(); - } - #endif - - const nzUInt8* pixel = GetPixelPtr(m_sharedImage->levels[0].get(), NzPixelFormat::GetBytesPerPixel(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)) - NazaraError("Failed to convert image's format to RGBA8"); - - return color; -} - -nzUInt8* NzImage::GetPixels(unsigned int x, unsigned int y, unsigned int z, nzUInt8 level) -{ - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) - { - NazaraError("Image must be valid"); - return nullptr; - } - - if (level >= m_sharedImage->levels.size()) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levels.size()) + ')'); - return nullptr; - } - #endif - - unsigned int width = GetLevelSize(m_sharedImage->width, level); - #if NAZARA_UTILITY_SAFE - if (x >= width) - { - NazaraError("X value exceeds width (" + NzString::Number(x) + " >= " + NzString::Number(width) + ')'); - return nullptr; - } - #endif - - unsigned int height = GetLevelSize(m_sharedImage->height, level); - #if NAZARA_UTILITY_SAFE - if (y >= height) - { - NazaraError("Y value exceeds height (" + NzString::Number(y) + " >= " + NzString::Number(height) + ')'); - return nullptr; - } - - 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) + ')'); - return nullptr; - } - - if (level >= m_sharedImage->levels.size()) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levels.size()) + ')'); - return nullptr; - } - #endif - - EnsureOwnership(); - - return GetPixelPtr(m_sharedImage->levels[level].get(), NzPixelFormat::GetBytesPerPixel(m_sharedImage->format), x, y, z, width, height); -} - -NzVector3ui NzImage::GetSize(nzUInt8 level) const -{ - #if NAZARA_UTILITY_SAFE - if (level >= m_sharedImage->levels.size()) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levels.size()) + ')'); - return NzVector3ui::Zero(); - } - #endif - - return NzVector3ui(GetLevelSize(m_sharedImage->width, level), GetLevelSize(m_sharedImage->height, level), GetLevelSize(m_sharedImage->depth, level)); -} - -nzImageType NzImage::GetType() const -{ - return m_sharedImage->type; -} - -unsigned int NzImage::GetWidth(nzUInt8 level) const -{ - #if NAZARA_UTILITY_SAFE - if (level >= m_sharedImage->levels.size()) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levels.size()) + ')'); - return 0; - } - #endif - - return GetLevelSize(m_sharedImage->width, level); -} - -bool NzImage::IsValid() const -{ - return m_sharedImage != &emptyImage; -} - -bool NzImage::LoadFromFile(const NzString& filePath, const NzImageParams& params) -{ - return NzImageLoader::LoadFromFile(this, filePath, params); -} - -bool NzImage::LoadFromMemory(const void* data, std::size_t size, const NzImageParams& params) -{ - return NzImageLoader::LoadFromMemory(this, data, size, params); -} - -bool NzImage::LoadFromStream(NzInputStream& stream, const NzImageParams& params) -{ - return NzImageLoader::LoadFromStream(this, stream, params); -} - -// LoadArray -bool NzImage::LoadArrayFromFile(const NzString& filePath, const NzImageParams& imageParams, const NzVector2ui& atlasSize) -{ - NzImage image; - if (!image.LoadFromFile(filePath, imageParams)) - { - NazaraError("Failed to load image"); - return false; - } - - return LoadArrayFromImage(image, atlasSize); -} - -bool NzImage::LoadArrayFromImage(const NzImage& image, const NzVector2ui& atlasSize) -{ - #if NAZARA_UTILITY_SAFE - if (!image.IsValid()) - { - NazaraError("Image must be valid"); - return false; - } - - if (atlasSize.x == 0) - { - NazaraError("Atlas width must be over zero"); - return false; - } - - if (atlasSize.y == 0) - { - NazaraError("Atlas height must be over zero"); - return false; - } - #endif - - nzImageType type = image.GetType(); - - #if NAZARA_UTILITY_SAFE - if (type != nzImageType_1D && type != nzImageType_2D) - { - NazaraError("Image type not handled (0x" + NzString::Number(type, 16) + ')'); - return false; - } - #endif - - NzVector2ui imageSize(image.GetWidth(), image.GetHeight()); - - if (imageSize.x % atlasSize.x != 0) - { - NazaraWarning("Image width is not divisible by atlas width (" + NzString::Number(imageSize.x) + " mod " + NzString::Number(atlasSize.x) + " != 0)"); - } - - if (imageSize.y % atlasSize.y != 0) - { - NazaraWarning("Image height is not divisible by atlas height (" + NzString::Number(imageSize.y) + " mod " + NzString::Number(atlasSize.y) + " != 0)"); - } - - NzVector2ui faceSize = imageSize/atlasSize; - - unsigned int layerCount = atlasSize.x*atlasSize.y; - - // Selon le type de l'image de base, on va créer un array d'images 2D ou 1D - if (type == nzImageType_2D) - Create(nzImageType_2D_Array, image.GetFormat(), faceSize.x, faceSize.y, layerCount); - else - Create(nzImageType_1D_Array, image.GetFormat(), faceSize.x, layerCount); - - unsigned int layer = 0; - for (unsigned int j = 0; j < atlasSize.y; ++j) - for (unsigned int i = 0; i < atlasSize.x; ++i) - Copy(image, NzRectui(i*faceSize.x, j*faceSize.y, faceSize.x, faceSize.y), NzVector3ui(0, 0, layer++)); - - return true; -} - -bool NzImage::LoadArrayFromMemory(const void* data, std::size_t size, const NzImageParams& imageParams, const NzVector2ui& atlasSize) -{ - NzImage image; - if (!image.LoadFromMemory(data, size, imageParams)) - { - NazaraError("Failed to load image"); - return false; - } - - return LoadArrayFromImage(image, atlasSize); -} - -bool NzImage::LoadArrayFromStream(NzInputStream& stream, const NzImageParams& imageParams, const NzVector2ui& atlasSize) -{ - NzImage image; - if (!image.LoadFromStream(stream, imageParams)) - { - NazaraError("Failed to load image"); - return false; - } - - return LoadArrayFromImage(image, atlasSize); -} - -bool NzImage::LoadCubemapFromFile(const NzString& filePath, const NzImageParams& imageParams, const NzCubemapParams& cubemapParams) -{ - NzImage image; - if (!image.LoadFromFile(filePath, imageParams)) - { - NazaraError("Failed to load image"); - return false; - } - - return LoadCubemapFromImage(image, cubemapParams); -} - -bool NzImage::LoadCubemapFromImage(const NzImage& image, const NzCubemapParams& params) -{ - #if NAZARA_UTILITY_SAFE - if (!image.IsValid()) - { - NazaraError("Image must be valid"); - return false; - } - - nzImageType type = image.GetType(); - if (type != nzImageType_2D) - { - NazaraError("Image type not handled (0x" + NzString::Number(type, 16) + ')'); - return false; - } - #endif - - unsigned int width = image.GetWidth(); - unsigned int height = image.GetHeight(); - unsigned int faceSize = (params.faceSize == 0) ? std::max(width, height)/4 : params.faceSize; - - // Sans cette vérification, celles des rectangles pourrait réussir via un overflow - if (width < faceSize || height < faceSize) - { - NazaraError("Image is too small for this face size"); - return false; - } - - // Calcul et vérification des surfaces - unsigned limitX = width - faceSize; - unsigned limitY = height - faceSize; - - NzVector2ui backPos = params.backPosition * faceSize; - if (backPos.x > limitX || backPos.y > limitY) - { - NazaraError("Back rectangle is out of image"); - return false; - } - - NzVector2ui downPos = params.downPosition * faceSize; - if (downPos.x > limitX || downPos.y > limitY) - { - NazaraError("Down rectangle is out of image"); - return false; - } - - NzVector2ui forwardPos = params.forwardPosition * faceSize; - if (forwardPos.x > limitX || forwardPos.y > limitY) - { - NazaraError("Forward rectangle is out of image"); - return false; - } - - NzVector2ui leftPos = params.leftPosition * faceSize; - if (leftPos.x > limitX || leftPos.y > limitY) - { - NazaraError("Left rectangle is out of image"); - return false; - } - - NzVector2ui rightPos = params.rightPosition * faceSize; - if (rightPos.x > limitX || rightPos.y > limitY) - { - NazaraError("Right rectangle is out of image"); - return false; - } - - NzVector2ui upPos = params.upPosition * faceSize; - if (upPos.x > limitX || upPos.y > limitY) - { - NazaraError("Up rectangle is out of image"); - return false; - } - - Create(nzImageType_Cubemap, image.GetFormat(), faceSize, faceSize); - - #ifdef NAZARA_DEBUG - // Les paramètres sont valides, que Create ne fonctionne pas relèverait d'un bug - if (m_sharedImage == &emptyImage) - { - NazaraInternalError("Failed to create cubemap"); - return false; - } - #endif - - Copy(image, NzRectui(backPos.x, backPos.y, faceSize, faceSize), NzVector3ui(0, 0, nzCubemapFace_NegativeZ)); - Copy(image, NzRectui(downPos.x, downPos.y, faceSize, faceSize), NzVector3ui(0, 0, nzCubemapFace_NegativeY)); - Copy(image, NzRectui(forwardPos.x, forwardPos.y, faceSize, faceSize), NzVector3ui(0, 0, nzCubemapFace_PositiveZ)); - Copy(image, NzRectui(leftPos.x, leftPos.y, faceSize, faceSize), NzVector3ui(0, 0, nzCubemapFace_NegativeX)); - Copy(image, NzRectui(rightPos.x, rightPos.y, faceSize, faceSize), NzVector3ui(0, 0, nzCubemapFace_PositiveX)); - Copy(image, NzRectui(upPos.x, upPos.y, faceSize, faceSize), NzVector3ui(0, 0, nzCubemapFace_PositiveY)); - - return true; -} - -bool NzImage::LoadCubemapFromMemory(const void* data, std::size_t size, const NzImageParams& imageParams, const NzCubemapParams& cubemapParams) -{ - NzImage image; - if (!image.LoadFromMemory(data, size, imageParams)) - { - NazaraError("Failed to load image"); - return false; - } - - return LoadCubemapFromImage(image, cubemapParams); -} - -bool NzImage::LoadCubemapFromStream(NzInputStream& stream, const NzImageParams& imageParams, const NzCubemapParams& cubemapParams) -{ - NzImage image; - if (!image.LoadFromStream(stream, imageParams)) - { - NazaraError("Failed to load image"); - return false; - } - - return LoadCubemapFromImage(image, cubemapParams); -} - -void NzImage::SetLevelCount(nzUInt8 levelCount) -{ - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) - { - NazaraError("Image must be valid"); - return; - } - - if (levelCount == 0) - { - NazaraError("Level count must be positive"); - return; - } - #endif - - levelCount = std::min(levelCount, GetMaxLevel()); - - if (m_sharedImage->levels.size() == levelCount) - return; - - EnsureOwnership(); - - nzUInt8 oldLevelCount = nzUInt8(m_sharedImage->levels.size()); - nzUInt8 maxLevelCount = std::max(levelCount, oldLevelCount); - - m_sharedImage->levels.resize(levelCount); - for (nzUInt8 i = oldLevelCount; i < maxLevelCount; ++i) - m_sharedImage->levels[i].reset(new nzUInt8[GetMemoryUsage(i)]); -} - -bool NzImage::SetPixelColor(const NzColor& color, unsigned int x, unsigned int y, unsigned int z) -{ - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) - { - NazaraError("Image must be valid"); - 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 height (" + NzString::Number(y) + " >= " + NzString::Number(m_sharedImage->height) + ')'); - 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 - - nzUInt8* pixel = GetPixelPtr(m_sharedImage->levels[0].get(), NzPixelFormat::GetBytesPerPixel(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height); - - 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::Update(const nzUInt8* pixels, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) -{ - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) - { - NazaraError("Image must be valid"); - return false; - } - - if (!pixels) - { - NazaraError("Invalid pixel source"); - return false; - } - - if (level >= m_sharedImage->levels.size()) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levels.size()) + ')'); - return false; - } - #endif - - EnsureOwnership(); - - Copy(m_sharedImage->levels[level].get(), pixels, NzPixelFormat::GetBytesPerPixel(m_sharedImage->format), - GetLevelSize(m_sharedImage->width, level), - GetLevelSize(m_sharedImage->height, level), - GetLevelSize(m_sharedImage->depth, level), - 0, 0, - srcWidth, srcHeight); - - return true; -} - -bool NzImage::Update(const nzUInt8* pixels, const NzBoxui& box, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) -{ - #if NAZARA_UTILITY_SAFE - if (m_sharedImage == &emptyImage) - { - NazaraError("Image must be valid"); - return false; - } - - if (!pixels) - { - NazaraError("Invalid pixel source"); - return false; - } - - if (level >= m_sharedImage->levels.size()) - { - NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levels.size()) + ')'); - return false; - } - #endif - - unsigned int width = GetLevelSize(m_sharedImage->width, level); - unsigned int height = GetLevelSize(m_sharedImage->height, level); - - #if NAZARA_UTILITY_SAFE - if (!box.IsValid()) - { - NazaraError("Invalid box"); - return false; - } - - unsigned int depth = (m_sharedImage->type == nzImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level); - if (box.x+box.width > width || box.y+box.height > height || box.z+box.depth > depth || - (m_sharedImage->type == nzImageType_Cubemap && box.depth > 1)) // Nous n'autorisons pas de modifier plus d'une face du cubemap à la fois - { - NazaraError("Box dimensions are out of bounds"); - return false; - } - #endif - - EnsureOwnership(); - - nzUInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); - nzUInt8* dstPixels = GetPixelPtr(m_sharedImage->levels[level].get(), bpp, box.x, box.y, box.z, width, height); - - Copy(dstPixels, pixels, bpp, - box.width, box.height, box.depth, - width, height, - srcWidth, srcHeight); - - return true; -} - -bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z, unsigned int srcWidth, unsigned int srcHeight, nzUInt8 level) -{ - return Update(pixels, NzBoxui(rect.x, rect.y, z, rect.width, rect.height, 1), srcWidth, srcHeight, level); -} - -NzImage& NzImage::operator=(const NzImage& image) -{ - ReleaseImage(); - - m_sharedImage = image.m_sharedImage; - if (m_sharedImage != &emptyImage) - m_sharedImage->refCount++; - - return *this; -} - -void NzImage::Copy(nzUInt8* destination, const nzUInt8* source, nzUInt8 bpp, unsigned int width, unsigned int height, unsigned int depth, unsigned int dstWidth, unsigned int dstHeight, unsigned int srcWidth, unsigned int srcHeight) -{ - if (dstWidth == 0) - dstWidth = width; - - if (dstHeight == 0) - dstHeight = height; - - if (srcWidth == 0) - srcWidth = width; - - if (srcHeight == 0) - srcHeight = height; - - if ((height == 1 || (dstWidth == width && srcWidth == width)) && (depth == 1 || (dstHeight == height && srcHeight == height))) - std::memcpy(destination, source, width*height*depth*bpp); - else - { - unsigned int lineStride = width * bpp; - unsigned int dstLineStride = dstWidth * bpp; - unsigned int dstFaceStride = dstLineStride * dstHeight; - unsigned int srcLineStride = srcWidth * bpp; - unsigned int srcFaceStride = srcLineStride * srcHeight; - - for (unsigned int i = 0; i < depth; ++i) - { - nzUInt8* dstFacePtr = destination; - const nzUInt8* srcFacePtr = source; - for (unsigned int y = 0; y < height; ++y) + UInt8* ptr = m_sharedImage->levels[level].get(); + if (!NzPixelFormat::Flip(PixelFlipping_Horizontally, m_sharedImage->format, width, height, depth, ptr, ptr)) { - std::memcpy(dstFacePtr, srcFacePtr, lineStride); - - dstFacePtr += dstLineStride; - srcFacePtr += srcLineStride; + NazaraError("Failed to flip image"); + return false; } - destination += dstFaceStride; - source += srcFaceStride; + if (width > 1U) + width >>= 1; + + if (height > 1U) + height >>= 1; + + if (depth > 1U && m_sharedImage->type != ImageType_Cubemap) + depth >>= 1; } - } -} -nzUInt8 NzImage::GetMaxLevel(unsigned int width, unsigned int height, unsigned int depth) -{ - // Le niveau maximal est le niveau requis pour la plus grande taille - return std::max(NzIntegralLog2(std::max({width, height, depth})), 1U); -} - -nzUInt8 NzImage::GetMaxLevel(nzImageType type, unsigned int width, unsigned int height, unsigned int depth) -{ - // Pour éviter que la profondeur ne soit comptée dans le calcul des niveaux - switch (type) - { - case nzImageType_1D: - case nzImageType_1D_Array: - return GetMaxLevel(width, 1U, 1U); - - case nzImageType_2D: - case nzImageType_2D_Array: - case nzImageType_Cubemap: - return GetMaxLevel(width, height, 1U); - - case nzImageType_3D: - return GetMaxLevel(width, height, depth); + return true; } - NazaraError("Image type not handled (0x" + NzString::Number(type, 16) + ')'); - return 0; - -} - -void NzImage::EnsureOwnership() -{ - if (m_sharedImage == &emptyImage) - return; - - if (m_sharedImage->refCount > 1) + bool Image::FlipVertically() { - SharedImage::PixelContainer levels(m_sharedImage->levels.size()); - for (unsigned int i = 0; i < levels.size(); ++i) + #if NAZARA_UTILITY_SAFE + if (m_sharedImage == &emptyImage) { - unsigned int size = GetMemoryUsage(i); - levels[i].reset(new nzUInt8[size]); - std::memcpy(levels[i].get(), m_sharedImage->levels[i].get(), size); + NazaraError("Image must be valid"); + return false; } - m_sharedImage->refCount--; - m_sharedImage = new SharedImage(1, m_sharedImage->type, m_sharedImage->format, std::move(levels), m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); + if (NzPixelFormat::IsCompressed(m_sharedImage->format)) + { + NazaraError("Cannot flip compressed image"); + return false; + } + #endif + + EnsureOwnership(); + + unsigned int width = m_sharedImage->width; + unsigned int height = m_sharedImage->height; + unsigned int depth = (m_sharedImage->type == ImageType_Cubemap) ? 6 : m_sharedImage->depth; + for (unsigned int level = 0; level < m_sharedImage->levels.size(); ++level) + { + UInt8* ptr = m_sharedImage->levels[level].get(); + if (!NzPixelFormat::Flip(PixelFlipping_Vertically, m_sharedImage->format, width, height, depth, ptr, ptr)) + { + NazaraError("Failed to flip image"); + return false; + } + + if (width > 1U) + width >>= 1; + + if (height > 1U) + height >>= 1; + + if (depth > 1U && m_sharedImage->type != ImageType_Cubemap) + depth >>= 1; + } + + return true; } -} -void NzImage::ReleaseImage() -{ - if (m_sharedImage == &emptyImage) - return; - - if (--m_sharedImage->refCount == 0) - delete m_sharedImage; - - m_sharedImage = &emptyImage; -} - -bool NzImage::Initialize() -{ - if (!NzImageLibrary::Initialize()) + const UInt8* Image::GetConstPixels(unsigned int x, unsigned int y, unsigned int z, UInt8 level) const { - NazaraError("Failed to initialise library"); - return false; + #if NAZARA_UTILITY_SAFE + if (m_sharedImage == &emptyImage) + { + NazaraError("Image must be valid"); + return nullptr; + } + + if (level >= m_sharedImage->levels.size()) + { + NazaraError("Level out of bounds (" + String::Number(level) + " >= " + String::Number(m_sharedImage->levels.size()) + ')'); + return nullptr; + } + #endif + + unsigned int width = GetLevelSize(m_sharedImage->width, level); + #if NAZARA_UTILITY_SAFE + if (x >= width) + { + NazaraError("X value exceeds width (" + String::Number(x) + " >= " + String::Number(width) + ')'); + return nullptr; + } + #endif + + unsigned int height = GetLevelSize(m_sharedImage->height, level); + #if NAZARA_UTILITY_SAFE + if (y >= height) + { + NazaraError("Y value exceeds height (" + String::Number(y) + " >= " + String::Number(height) + ')'); + return nullptr; + } + + unsigned int depth = (m_sharedImage->type == ImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level); + if (z >= depth) + { + NazaraError("Z value exceeds depth (" + String::Number(z) + " >= " + String::Number(depth) + ')'); + return nullptr; + } + #endif + + return GetPixelPtr(m_sharedImage->levels[level].get(), NzPixelFormat::GetBytesPerPixel(m_sharedImage->format), x, y, z, width, height); } - if (!NzImageManager::Initialize()) + unsigned int Image::GetDepth(UInt8 level) const { - NazaraError("Failed to initialise manager"); - return false; + #if NAZARA_UTILITY_SAFE + if (level >= m_sharedImage->levels.size()) + { + NazaraError("Level out of bounds (" + String::Number(level) + " >= " + String::Number(m_sharedImage->levels.size()) + ')'); + return 0; + } + #endif + + return GetLevelSize(m_sharedImage->depth, level); } - return true; -} + PixelFormatType Image::GetFormat() const + { + return m_sharedImage->format; + } -void NzImage::Uninitialize() -{ - NzImageManager::Uninitialize(); - NzImageLibrary::Uninitialize(); -} + unsigned int Image::GetHeight(UInt8 level) const + { + #if NAZARA_UTILITY_SAFE + if (level >= m_sharedImage->levels.size()) + { + NazaraError("Level out of bounds (" + String::Number(level) + " >= " + String::Number(m_sharedImage->levels.size()) + ')'); + return 0; + } + #endif -NzImage::SharedImage NzImage::emptyImage(0, nzImageType_2D, nzPixelFormat_Undefined, NzImage::SharedImage::PixelContainer(), 0, 0, 0); -NzImageLibrary::LibraryMap NzImage::s_library; -NzImageLoader::LoaderList NzImage::s_loaders; -NzImageManager::ManagerMap NzImage::s_managerMap; -NzImageManager::ManagerParams NzImage::s_managerParameters; + return GetLevelSize(m_sharedImage->height, level); + } + + UInt8 Image::GetLevelCount() const + { + return UInt8(m_sharedImage->levels.size()); + } + + UInt8 Image::GetMaxLevel() const + { + return GetMaxLevel(m_sharedImage->type, m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); + } + + unsigned int Image::GetMemoryUsage() const + { + unsigned int width = m_sharedImage->width; + unsigned int height = m_sharedImage->height; + unsigned int depth = m_sharedImage->depth; + + unsigned int size = 0; + for (unsigned int i = 0; i < m_sharedImage->levels.size(); ++i) + { + size += width * height * depth; + + if (width > 1) + width >>= 1; + + if (height > 1) + height >>= 1; + + if (depth > 1) + depth >>= 1; + } + + if (m_sharedImage->type == ImageType_Cubemap) + size *= 6; + + return size * NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); + } + + unsigned int Image::GetMemoryUsage(UInt8 level) const + { + return (GetLevelSize(m_sharedImage->width, level)) * + (GetLevelSize(m_sharedImage->height, level)) * + ((m_sharedImage->type == ImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level)) * + NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); + } + + Color Image::GetPixelColor(unsigned int x, unsigned int y, unsigned int z) const + { + #if NAZARA_UTILITY_SAFE + if (m_sharedImage == &emptyImage) + { + NazaraError("Image must be valid"); + return Color(); + } + + if (NzPixelFormat::IsCompressed(m_sharedImage->format)) + { + NazaraError("Cannot access pixels from compressed image"); + return Color(); + } + + if (x >= m_sharedImage->width) + { + NazaraError("X value exceeds width (" + String::Number(x) + " >= " + String::Number(m_sharedImage->width) + ')'); + return Color(); + } + + if (y >= m_sharedImage->height) + { + NazaraError("Y value exceeds height (" + String::Number(y) + " >= " + String::Number(m_sharedImage->height) + ')'); + return Color(); + } + + unsigned int depth = (m_sharedImage->type == ImageType_Cubemap) ? 6 : m_sharedImage->depth; + if (z >= depth) + { + NazaraError("Z value exceeds depth (" + String::Number(z) + " >= " + String::Number(depth) + ')'); + return Color(); + } + #endif + + const UInt8* pixel = GetPixelPtr(m_sharedImage->levels[0].get(), NzPixelFormat::GetBytesPerPixel(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height); + + Color color; + if (!NzPixelFormat::Convert(m_sharedImage->format, PixelFormatType_RGBA8, pixel, &color.r)) + NazaraError("Failed to convert image's format to RGBA8"); + + return color; + } + + UInt8* Image::GetPixels(unsigned int x, unsigned int y, unsigned int z, UInt8 level) + { + #if NAZARA_UTILITY_SAFE + if (m_sharedImage == &emptyImage) + { + NazaraError("Image must be valid"); + return nullptr; + } + + if (level >= m_sharedImage->levels.size()) + { + NazaraError("Level out of bounds (" + String::Number(level) + " >= " + String::Number(m_sharedImage->levels.size()) + ')'); + return nullptr; + } + #endif + + unsigned int width = GetLevelSize(m_sharedImage->width, level); + #if NAZARA_UTILITY_SAFE + if (x >= width) + { + NazaraError("X value exceeds width (" + String::Number(x) + " >= " + String::Number(width) + ')'); + return nullptr; + } + #endif + + unsigned int height = GetLevelSize(m_sharedImage->height, level); + #if NAZARA_UTILITY_SAFE + if (y >= height) + { + NazaraError("Y value exceeds height (" + String::Number(y) + " >= " + String::Number(height) + ')'); + return nullptr; + } + + unsigned int depth = (m_sharedImage->type == ImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level); + if (z >= depth) + { + NazaraError("Z value exceeds depth (" + String::Number(z) + " >= " + String::Number(depth) + ')'); + return nullptr; + } + + if (level >= m_sharedImage->levels.size()) + { + NazaraError("Level out of bounds (" + String::Number(level) + " >= " + String::Number(m_sharedImage->levels.size()) + ')'); + return nullptr; + } + #endif + + EnsureOwnership(); + + return GetPixelPtr(m_sharedImage->levels[level].get(), NzPixelFormat::GetBytesPerPixel(m_sharedImage->format), x, y, z, width, height); + } + + Vector3ui Image::GetSize(UInt8 level) const + { + #if NAZARA_UTILITY_SAFE + if (level >= m_sharedImage->levels.size()) + { + NazaraError("Level out of bounds (" + String::Number(level) + " >= " + String::Number(m_sharedImage->levels.size()) + ')'); + return Vector3ui::Zero(); + } + #endif + + return Vector3ui(GetLevelSize(m_sharedImage->width, level), GetLevelSize(m_sharedImage->height, level), GetLevelSize(m_sharedImage->depth, level)); + } + + ImageType Image::GetType() const + { + return m_sharedImage->type; + } + + unsigned int Image::GetWidth(UInt8 level) const + { + #if NAZARA_UTILITY_SAFE + if (level >= m_sharedImage->levels.size()) + { + NazaraError("Level out of bounds (" + String::Number(level) + " >= " + String::Number(m_sharedImage->levels.size()) + ')'); + return 0; + } + #endif + + return GetLevelSize(m_sharedImage->width, level); + } + + bool Image::IsValid() const + { + return m_sharedImage != &emptyImage; + } + + bool Image::LoadFromFile(const String& filePath, const ImageParams& params) + { + return ImageLoader::LoadFromFile(this, filePath, params); + } + + bool Image::LoadFromMemory(const void* data, std::size_t size, const ImageParams& params) + { + return ImageLoader::LoadFromMemory(this, data, size, params); + } + + bool Image::LoadFromStream(InputStream& stream, const ImageParams& params) + { + return ImageLoader::LoadFromStream(this, stream, params); + } + + // LoadArray + bool Image::LoadArrayFromFile(const String& filePath, const ImageParams& imageParams, const Vector2ui& atlasSize) + { + Image image; + if (!image.LoadFromFile(filePath, imageParams)) + { + NazaraError("Failed to load image"); + return false; + } + + return LoadArrayFromImage(image, atlasSize); + } + + bool Image::LoadArrayFromImage(const Image& image, const Vector2ui& atlasSize) + { + #if NAZARA_UTILITY_SAFE + if (!image.IsValid()) + { + NazaraError("Image must be valid"); + return false; + } + + if (atlasSize.x == 0) + { + NazaraError("Atlas width must be over zero"); + return false; + } + + if (atlasSize.y == 0) + { + NazaraError("Atlas height must be over zero"); + return false; + } + #endif + + ImageType type = image.GetType(); + + #if NAZARA_UTILITY_SAFE + if (type != ImageType_1D && type != ImageType_2D) + { + NazaraError("Image type not handled (0x" + String::Number(type, 16) + ')'); + return false; + } + #endif + + Vector2ui imageSize(image.GetWidth(), image.GetHeight()); + + if (imageSize.x % atlasSize.x != 0) + { + NazaraWarning("Image width is not divisible by atlas width (" + String::Number(imageSize.x) + " mod " + String::Number(atlasSize.x) + " != 0)"); + } + + if (imageSize.y % atlasSize.y != 0) + { + NazaraWarning("Image height is not divisible by atlas height (" + String::Number(imageSize.y) + " mod " + String::Number(atlasSize.y) + " != 0)"); + } + + Vector2ui faceSize = imageSize/atlasSize; + + unsigned int layerCount = atlasSize.x*atlasSize.y; + + // Selon le type de l'image de base, on va créer un array d'images 2D ou 1D + if (type == ImageType_2D) + Create(ImageType_2D_Array, image.GetFormat(), faceSize.x, faceSize.y, layerCount); + else + Create(ImageType_1D_Array, image.GetFormat(), faceSize.x, layerCount); + + unsigned int layer = 0; + for (unsigned int j = 0; j < atlasSize.y; ++j) + for (unsigned int i = 0; i < atlasSize.x; ++i) + Copy(image, Rectui(i*faceSize.x, j*faceSize.y, faceSize.x, faceSize.y), Vector3ui(0, 0, layer++)); + + return true; + } + + bool Image::LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams, const Vector2ui& atlasSize) + { + Image image; + if (!image.LoadFromMemory(data, size, imageParams)) + { + NazaraError("Failed to load image"); + return false; + } + + return LoadArrayFromImage(image, atlasSize); + } + + bool Image::LoadArrayFromStream(InputStream& stream, const ImageParams& imageParams, const Vector2ui& atlasSize) + { + Image image; + if (!image.LoadFromStream(stream, imageParams)) + { + NazaraError("Failed to load image"); + return false; + } + + return LoadArrayFromImage(image, atlasSize); + } + + bool Image::LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams, const CubemapParams& cubemapParams) + { + Image image; + if (!image.LoadFromFile(filePath, imageParams)) + { + NazaraError("Failed to load image"); + return false; + } + + return LoadCubemapFromImage(image, cubemapParams); + } + + bool Image::LoadCubemapFromImage(const Image& image, const CubemapParams& params) + { + #if NAZARA_UTILITY_SAFE + if (!image.IsValid()) + { + NazaraError("Image must be valid"); + return false; + } + + ImageType type = image.GetType(); + if (type != ImageType_2D) + { + NazaraError("Image type not handled (0x" + String::Number(type, 16) + ')'); + return false; + } + #endif + + unsigned int width = image.GetWidth(); + unsigned int height = image.GetHeight(); + unsigned int faceSize = (params.faceSize == 0) ? std::max(width, height)/4 : params.faceSize; + + // Sans cette vérification, celles des rectangles pourrait réussir via un overflow + if (width < faceSize || height < faceSize) + { + NazaraError("Image is too small for this face size"); + return false; + } + + // Calcul et vérification des surfaces + unsigned limitX = width - faceSize; + unsigned limitY = height - faceSize; + + Vector2ui backPos = params.backPosition * faceSize; + if (backPos.x > limitX || backPos.y > limitY) + { + NazaraError("Back rectangle is out of image"); + return false; + } + + Vector2ui downPos = params.downPosition * faceSize; + if (downPos.x > limitX || downPos.y > limitY) + { + NazaraError("Down rectangle is out of image"); + return false; + } + + Vector2ui forwardPos = params.forwardPosition * faceSize; + if (forwardPos.x > limitX || forwardPos.y > limitY) + { + NazaraError("Forward rectangle is out of image"); + return false; + } + + Vector2ui leftPos = params.leftPosition * faceSize; + if (leftPos.x > limitX || leftPos.y > limitY) + { + NazaraError("Left rectangle is out of image"); + return false; + } + + Vector2ui rightPos = params.rightPosition * faceSize; + if (rightPos.x > limitX || rightPos.y > limitY) + { + NazaraError("Right rectangle is out of image"); + return false; + } + + Vector2ui upPos = params.upPosition * faceSize; + if (upPos.x > limitX || upPos.y > limitY) + { + NazaraError("Up rectangle is out of image"); + return false; + } + + Create(ImageType_Cubemap, image.GetFormat(), faceSize, faceSize); + + #ifdef NAZARA_DEBUG + // Les paramètres sont valides, que Create ne fonctionne pas relèverait d'un bug + if (m_sharedImage == &emptyImage) + { + NazaraInternalError("Failed to create cubemap"); + return false; + } + #endif + + Copy(image, Rectui(backPos.x, backPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_NegativeZ)); + Copy(image, Rectui(downPos.x, downPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_NegativeY)); + Copy(image, Rectui(forwardPos.x, forwardPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_PositiveZ)); + Copy(image, Rectui(leftPos.x, leftPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_NegativeX)); + Copy(image, Rectui(rightPos.x, rightPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_PositiveX)); + Copy(image, Rectui(upPos.x, upPos.y, faceSize, faceSize), Vector3ui(0, 0, CubemapFace_PositiveY)); + + return true; + } + + bool Image::LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams, const CubemapParams& cubemapParams) + { + Image image; + if (!image.LoadFromMemory(data, size, imageParams)) + { + NazaraError("Failed to load image"); + return false; + } + + return LoadCubemapFromImage(image, cubemapParams); + } + + bool Image::LoadCubemapFromStream(InputStream& stream, const ImageParams& imageParams, const CubemapParams& cubemapParams) + { + Image image; + if (!image.LoadFromStream(stream, imageParams)) + { + NazaraError("Failed to load image"); + return false; + } + + return LoadCubemapFromImage(image, cubemapParams); + } + + void Image::SetLevelCount(UInt8 levelCount) + { + #if NAZARA_UTILITY_SAFE + if (m_sharedImage == &emptyImage) + { + NazaraError("Image must be valid"); + return; + } + + if (levelCount == 0) + { + NazaraError("Level count must be positive"); + return; + } + #endif + + levelCount = std::min(levelCount, GetMaxLevel()); + + if (m_sharedImage->levels.size() == levelCount) + return; + + EnsureOwnership(); + + UInt8 oldLevelCount = UInt8(m_sharedImage->levels.size()); + UInt8 maxLevelCount = std::max(levelCount, oldLevelCount); + + m_sharedImage->levels.resize(levelCount); + for (UInt8 i = oldLevelCount; i < maxLevelCount; ++i) + m_sharedImage->levels[i].reset(new UInt8[GetMemoryUsage(i)]); + } + + bool Image::SetPixelColor(const Color& color, unsigned int x, unsigned int y, unsigned int z) + { + #if NAZARA_UTILITY_SAFE + if (m_sharedImage == &emptyImage) + { + NazaraError("Image must be valid"); + 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 (" + String::Number(x) + " >= " + String::Number(m_sharedImage->width) + ')'); + return false; + } + + if (y >= m_sharedImage->height) + { + NazaraError("Y value exceeds height (" + String::Number(y) + " >= " + String::Number(m_sharedImage->height) + ')'); + return false; + } + + unsigned int depth = (m_sharedImage->type == ImageType_Cubemap) ? 6 : m_sharedImage->depth; + if (z >= depth) + { + NazaraError("Z value exceeds depth (" + String::Number(z) + " >= " + String::Number(depth) + ')'); + return false; + } + #endif + + UInt8* pixel = GetPixelPtr(m_sharedImage->levels[0].get(), NzPixelFormat::GetBytesPerPixel(m_sharedImage->format), x, y, z, m_sharedImage->width, m_sharedImage->height); + + if (!NzPixelFormat::Convert(PixelFormatType_RGBA8, m_sharedImage->format, &color.r, pixel)) + { + NazaraError("Failed to convert RGBA8 to image's format"); + return false; + } + + return true; + } + + bool Image::Update(const UInt8* pixels, unsigned int srcWidth, unsigned int srcHeight, UInt8 level) + { + #if NAZARA_UTILITY_SAFE + if (m_sharedImage == &emptyImage) + { + NazaraError("Image must be valid"); + return false; + } + + if (!pixels) + { + NazaraError("Invalid pixel source"); + return false; + } + + if (level >= m_sharedImage->levels.size()) + { + NazaraError("Level out of bounds (" + String::Number(level) + " >= " + String::Number(m_sharedImage->levels.size()) + ')'); + return false; + } + #endif + + EnsureOwnership(); + + Copy(m_sharedImage->levels[level].get(), pixels, NzPixelFormat::GetBytesPerPixel(m_sharedImage->format), + GetLevelSize(m_sharedImage->width, level), + GetLevelSize(m_sharedImage->height, level), + GetLevelSize(m_sharedImage->depth, level), + 0, 0, + srcWidth, srcHeight); + + return true; + } + + bool Image::Update(const UInt8* pixels, const Boxui& box, unsigned int srcWidth, unsigned int srcHeight, UInt8 level) + { + #if NAZARA_UTILITY_SAFE + if (m_sharedImage == &emptyImage) + { + NazaraError("Image must be valid"); + return false; + } + + if (!pixels) + { + NazaraError("Invalid pixel source"); + return false; + } + + if (level >= m_sharedImage->levels.size()) + { + NazaraError("Level out of bounds (" + String::Number(level) + " >= " + String::Number(m_sharedImage->levels.size()) + ')'); + return false; + } + #endif + + unsigned int width = GetLevelSize(m_sharedImage->width, level); + unsigned int height = GetLevelSize(m_sharedImage->height, level); + + #if NAZARA_UTILITY_SAFE + if (!box.IsValid()) + { + NazaraError("Invalid box"); + return false; + } + + unsigned int depth = (m_sharedImage->type == ImageType_Cubemap) ? 6 : GetLevelSize(m_sharedImage->depth, level); + if (box.x+box.width > width || box.y+box.height > height || box.z+box.depth > depth || + (m_sharedImage->type == ImageType_Cubemap && box.depth > 1)) // Nous n'autorisons pas de modifier plus d'une face du cubemap à la fois + { + NazaraError("Box dimensions are out of bounds"); + return false; + } + #endif + + EnsureOwnership(); + + UInt8 bpp = NzPixelFormat::GetBytesPerPixel(m_sharedImage->format); + UInt8* dstPixels = GetPixelPtr(m_sharedImage->levels[level].get(), bpp, box.x, box.y, box.z, width, height); + + Copy(dstPixels, pixels, bpp, + box.width, box.height, box.depth, + width, height, + srcWidth, srcHeight); + + return true; + } + + bool Image::Update(const UInt8* pixels, const Rectui& rect, unsigned int z, unsigned int srcWidth, unsigned int srcHeight, UInt8 level) + { + return Update(pixels, Boxui(rect.x, rect.y, z, rect.width, rect.height, 1), srcWidth, srcHeight, level); + } + + Image& Image::operator=(const Image& image) + { + ReleaseImage(); + + m_sharedImage = image.m_sharedImage; + if (m_sharedImage != &emptyImage) + m_sharedImage->refCount++; + + return *this; + } + + void Image::Copy(UInt8* destination, const UInt8* source, UInt8 bpp, unsigned int width, unsigned int height, unsigned int depth, unsigned int dstWidth, unsigned int dstHeight, unsigned int srcWidth, unsigned int srcHeight) + { + if (dstWidth == 0) + dstWidth = width; + + if (dstHeight == 0) + dstHeight = height; + + if (srcWidth == 0) + srcWidth = width; + + if (srcHeight == 0) + srcHeight = height; + + if ((height == 1 || (dstWidth == width && srcWidth == width)) && (depth == 1 || (dstHeight == height && srcHeight == height))) + std::memcpy(destination, source, width*height*depth*bpp); + else + { + unsigned int lineStride = width * bpp; + unsigned int dstLineStride = dstWidth * bpp; + unsigned int dstFaceStride = dstLineStride * dstHeight; + unsigned int srcLineStride = srcWidth * bpp; + unsigned int srcFaceStride = srcLineStride * srcHeight; + + for (unsigned int i = 0; i < depth; ++i) + { + UInt8* dstFacePtr = destination; + const UInt8* srcFacePtr = source; + for (unsigned int y = 0; y < height; ++y) + { + std::memcpy(dstFacePtr, srcFacePtr, lineStride); + + dstFacePtr += dstLineStride; + srcFacePtr += srcLineStride; + } + + destination += dstFaceStride; + source += srcFaceStride; + } + } + } + + UInt8 Image::GetMaxLevel(unsigned int width, unsigned int height, unsigned int depth) + { + // Le niveau maximal est le niveau requis pour la plus grande taille + return std::max(IntegralLog2(std::max({width, height, depth})), 1U); + } + + UInt8 Image::GetMaxLevel(ImageType type, unsigned int width, unsigned int height, unsigned int depth) + { + // Pour éviter que la profondeur ne soit comptée dans le calcul des niveaux + switch (type) + { + case ImageType_1D: + case ImageType_1D_Array: + return GetMaxLevel(width, 1U, 1U); + + case ImageType_2D: + case ImageType_2D_Array: + case ImageType_Cubemap: + return GetMaxLevel(width, height, 1U); + + case ImageType_3D: + return GetMaxLevel(width, height, depth); + } + + NazaraError("Image type not handled (0x" + String::Number(type, 16) + ')'); + return 0; + + } + + void Image::EnsureOwnership() + { + if (m_sharedImage == &emptyImage) + return; + + if (m_sharedImage->refCount > 1) + { + SharedImage::PixelContainer levels(m_sharedImage->levels.size()); + for (unsigned int i = 0; i < levels.size(); ++i) + { + unsigned int size = GetMemoryUsage(i); + levels[i].reset(new UInt8[size]); + std::memcpy(levels[i].get(), m_sharedImage->levels[i].get(), size); + } + + m_sharedImage->refCount--; + m_sharedImage = new SharedImage(1, m_sharedImage->type, m_sharedImage->format, std::move(levels), m_sharedImage->width, m_sharedImage->height, m_sharedImage->depth); + } + } + + void Image::ReleaseImage() + { + if (m_sharedImage == &emptyImage) + return; + + if (--m_sharedImage->refCount == 0) + delete m_sharedImage; + + m_sharedImage = &emptyImage; + } + + bool Image::Initialize() + { + if (!ImageLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } + + if (!ImageManager::Initialize()) + { + NazaraError("Failed to initialise manager"); + return false; + } + + return true; + } + + void Image::Uninitialize() + { + ImageManager::Uninitialize(); + ImageLibrary::Uninitialize(); + } + + Image::SharedImage Image::emptyImage(0, ImageType_2D, PixelFormatType_Undefined, Image::SharedImage::PixelContainer(), 0, 0, 0); + ImageLibrary::LibraryMap Image::s_library; + ImageLoader::LoaderList Image::s_loaders; + ImageManager::ManagerMap Image::s_managerMap; + ImageManager::ManagerParams Image::s_managerParameters; +} diff --git a/src/Nazara/Utility/IndexBuffer.cpp b/src/Nazara/Utility/IndexBuffer.cpp index 8176b9614..2f1a46515 100644 --- a/src/Nazara/Utility/IndexBuffer.cpp +++ b/src/Nazara/Utility/IndexBuffer.cpp @@ -12,238 +12,241 @@ #include #include -NzIndexBuffer::NzIndexBuffer(bool largeIndices, NzBuffer* buffer) +namespace Nz { - NzErrorFlags(nzErrorFlag_ThrowException, true); - Reset(largeIndices, buffer); -} - -NzIndexBuffer::NzIndexBuffer(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset) -{ - NzErrorFlags(nzErrorFlag_ThrowException, true); - Reset(largeIndices, buffer, startOffset, endOffset); -} - -NzIndexBuffer::NzIndexBuffer(bool largeIndices, unsigned int length, nzUInt32 storage, nzBufferUsage usage) -{ - NzErrorFlags(nzErrorFlag_ThrowException, true); - Reset(largeIndices, length, storage, usage); -} - -NzIndexBuffer::NzIndexBuffer(const NzIndexBuffer& indexBuffer) : -NzRefCounted(), -m_buffer(indexBuffer.m_buffer), -m_largeIndices(indexBuffer.m_largeIndices), -m_endOffset(indexBuffer.m_endOffset), -m_indexCount(indexBuffer.m_indexCount), -m_startOffset(indexBuffer.m_startOffset) -{ -} - -NzIndexBuffer::~NzIndexBuffer() -{ - OnIndexBufferRelease(this); -} - -unsigned int NzIndexBuffer::ComputeCacheMissCount() const -{ - NzIndexMapper mapper(this); - - return NzComputeCacheMissCount(mapper.begin(), m_indexCount); -} - -bool NzIndexBuffer::Fill(const void* data, unsigned int startIndex, unsigned int length, bool forceDiscard) -{ - unsigned int stride = GetStride(); - return FillRaw(data, startIndex*stride, length*stride, forceDiscard); -} - -bool NzIndexBuffer::FillRaw(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) -{ - #if NAZARA_UTILITY_SAFE - if (m_startOffset + offset + size > m_endOffset) + IndexBuffer::IndexBuffer(bool largeIndices, Buffer* buffer) { - NazaraError("Exceeding virtual buffer size"); - return false; - } - #endif - - return m_buffer->Fill(data, m_startOffset+offset, size, forceDiscard); -} - -NzBuffer* NzIndexBuffer::GetBuffer() const -{ - return m_buffer; -} - -unsigned int NzIndexBuffer::GetEndOffset() const -{ - return m_endOffset; -} - -unsigned int NzIndexBuffer::GetIndexCount() const -{ - return m_indexCount; -} - -unsigned int NzIndexBuffer::GetStride() const -{ - return (m_largeIndices) ? sizeof(nzUInt32) : sizeof(nzUInt16); -} - -unsigned int NzIndexBuffer::GetStartOffset() const -{ - return m_startOffset; -} - -bool NzIndexBuffer::HasLargeIndices() const -{ - return m_largeIndices; -} - -bool NzIndexBuffer::IsHardware() const -{ - return m_buffer->IsHardware(); -} - -bool NzIndexBuffer::IsValid() const -{ - return m_buffer; -} - -void* NzIndexBuffer::Map(nzBufferAccess access, unsigned int startIndex, unsigned int length) -{ - unsigned int stride = GetStride(); - return MapRaw(access, startIndex*stride, length*stride); -} - -void* NzIndexBuffer::Map(nzBufferAccess access, unsigned int startIndex, unsigned int length) const -{ - unsigned int stride = GetStride(); - return MapRaw(access, startIndex*stride, length*stride); -} - -void* NzIndexBuffer::MapRaw(nzBufferAccess access, unsigned int offset, unsigned int size) -{ - #if NAZARA_UTILITY_SAFE - if (!m_buffer) - { - NazaraError("No buffer"); - return nullptr; + ErrorFlags(ErrorFlag_ThrowException, true); + Reset(largeIndices, buffer); } - if (m_startOffset + offset + size > m_endOffset) + IndexBuffer::IndexBuffer(bool largeIndices, Buffer* buffer, unsigned int startOffset, unsigned int endOffset) { - NazaraError("Exceeding virtual buffer size"); - return nullptr; - } - #endif - - return m_buffer->Map(access, offset, size); -} - -void* NzIndexBuffer::MapRaw(nzBufferAccess access, unsigned int offset, unsigned int size) const -{ - #if NAZARA_UTILITY_SAFE - if (m_startOffset + offset + size > m_endOffset) - { - NazaraError("Exceeding virtual buffer size"); - return nullptr; - } - #endif - - return m_buffer->Map(access, offset, size); -} - -void NzIndexBuffer::Optimize() -{ - NzIndexMapper mapper(this); - - NzOptimizeIndices(mapper.begin(), m_indexCount); -} - -void NzIndexBuffer::Reset() -{ - m_buffer.Reset(); -} - -void NzIndexBuffer::Reset(bool largeIndices, NzBuffer* buffer) -{ - Reset(largeIndices, buffer, 0, buffer->GetSize()-1); -} - -void NzIndexBuffer::Reset(bool largeIndices, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset) -{ - #if NAZARA_UTILITY_SAFE - if (!buffer || !buffer->IsValid()) - { - NazaraError("Buffer is invalid"); - return; + ErrorFlags(ErrorFlag_ThrowException, true); + Reset(largeIndices, buffer, startOffset, endOffset); } - if (startOffset > endOffset) + IndexBuffer::IndexBuffer(bool largeIndices, unsigned int length, UInt32 storage, BufferUsage usage) { - NazaraError("Start offset cannot be over end offset"); - return; + ErrorFlags(ErrorFlag_ThrowException, true); + Reset(largeIndices, length, storage, usage); } - unsigned int bufferSize = buffer->GetSize(); - if (startOffset >= bufferSize) + IndexBuffer::IndexBuffer(const IndexBuffer& indexBuffer) : + RefCounted(), + m_buffer(indexBuffer.m_buffer), + m_largeIndices(indexBuffer.m_largeIndices), + m_endOffset(indexBuffer.m_endOffset), + m_indexCount(indexBuffer.m_indexCount), + m_startOffset(indexBuffer.m_startOffset) { - NazaraError("Start offset is over buffer size"); - return; } - if (endOffset >= bufferSize) + IndexBuffer::~IndexBuffer() { - NazaraError("End offset is over buffer size"); - return; + OnIndexBufferRelease(this); } - #endif - unsigned int stride = (largeIndices) ? sizeof(nzUInt32) : sizeof(nzUInt16); + unsigned int IndexBuffer::ComputeCacheMissCount() const + { + IndexMapper mapper(this); - m_buffer = buffer; - m_endOffset = endOffset; - m_indexCount = (endOffset - startOffset) / stride; - m_largeIndices = largeIndices; - m_startOffset = startOffset; -} - -void NzIndexBuffer::Reset(bool largeIndices, unsigned int length, nzUInt32 storage, nzBufferUsage usage) -{ - unsigned int stride = (largeIndices) ? sizeof(nzUInt32) : sizeof(nzUInt16); - - m_endOffset = length * stride; - m_indexCount = length; - m_largeIndices = largeIndices; - m_startOffset = 0; - - m_buffer = NzBuffer::New(nzBufferType_Index, m_endOffset, storage, usage); -} - -void NzIndexBuffer::Reset(const NzIndexBuffer& indexBuffer) -{ - m_buffer = indexBuffer.m_buffer; - m_endOffset = indexBuffer.m_endOffset; - m_indexCount = indexBuffer.m_indexCount; - m_largeIndices = indexBuffer.m_largeIndices; - m_startOffset = indexBuffer.m_startOffset; -} - -bool NzIndexBuffer::SetStorage(nzUInt32 storage) -{ - return m_buffer->SetStorage(storage); -} - -void NzIndexBuffer::Unmap() const -{ - m_buffer->Unmap(); -} - -NzIndexBuffer& NzIndexBuffer::operator=(const NzIndexBuffer& indexBuffer) -{ - Reset(indexBuffer); - - return *this; + return Nz::ComputeCacheMissCount(mapper.begin(), m_indexCount); + } + + bool IndexBuffer::Fill(const void* data, unsigned int startIndex, unsigned int length, bool forceDiscard) + { + unsigned int stride = GetStride(); + return FillRaw(data, startIndex*stride, length*stride, forceDiscard); + } + + bool IndexBuffer::FillRaw(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) + { + #if NAZARA_UTILITY_SAFE + if (m_startOffset + offset + size > m_endOffset) + { + NazaraError("Exceeding virtual buffer size"); + return false; + } + #endif + + return m_buffer->Fill(data, m_startOffset+offset, size, forceDiscard); + } + + Buffer* IndexBuffer::GetBuffer() const + { + return m_buffer; + } + + unsigned int IndexBuffer::GetEndOffset() const + { + return m_endOffset; + } + + unsigned int IndexBuffer::GetIndexCount() const + { + return m_indexCount; + } + + unsigned int IndexBuffer::GetStride() const + { + return (m_largeIndices) ? sizeof(UInt32) : sizeof(UInt16); + } + + unsigned int IndexBuffer::GetStartOffset() const + { + return m_startOffset; + } + + bool IndexBuffer::HasLargeIndices() const + { + return m_largeIndices; + } + + bool IndexBuffer::IsHardware() const + { + return m_buffer->IsHardware(); + } + + bool IndexBuffer::IsValid() const + { + return m_buffer; + } + + void* IndexBuffer::Map(BufferAccess access, unsigned int startIndex, unsigned int length) + { + unsigned int stride = GetStride(); + return MapRaw(access, startIndex*stride, length*stride); + } + + void* IndexBuffer::Map(BufferAccess access, unsigned int startIndex, unsigned int length) const + { + unsigned int stride = GetStride(); + return MapRaw(access, startIndex*stride, length*stride); + } + + void* IndexBuffer::MapRaw(BufferAccess access, unsigned int offset, unsigned int size) + { + #if NAZARA_UTILITY_SAFE + if (!m_buffer) + { + NazaraError("No buffer"); + return nullptr; + } + + if (m_startOffset + offset + size > m_endOffset) + { + NazaraError("Exceeding virtual buffer size"); + return nullptr; + } + #endif + + return m_buffer->Map(access, offset, size); + } + + void* IndexBuffer::MapRaw(BufferAccess access, unsigned int offset, unsigned int size) const + { + #if NAZARA_UTILITY_SAFE + if (m_startOffset + offset + size > m_endOffset) + { + NazaraError("Exceeding virtual buffer size"); + return nullptr; + } + #endif + + return m_buffer->Map(access, offset, size); + } + + void IndexBuffer::Optimize() + { + IndexMapper mapper(this); + + OptimizeIndices(mapper.begin(), m_indexCount); + } + + void IndexBuffer::Reset() + { + m_buffer.Reset(); + } + + void IndexBuffer::Reset(bool largeIndices, Buffer* buffer) + { + Reset(largeIndices, buffer, 0, buffer->GetSize()-1); + } + + void IndexBuffer::Reset(bool largeIndices, Buffer* buffer, unsigned int startOffset, unsigned int endOffset) + { + #if NAZARA_UTILITY_SAFE + if (!buffer || !buffer->IsValid()) + { + NazaraError("Buffer is invalid"); + return; + } + + if (startOffset > endOffset) + { + NazaraError("Start offset cannot be over end offset"); + return; + } + + unsigned int bufferSize = buffer->GetSize(); + if (startOffset >= bufferSize) + { + NazaraError("Start offset is over buffer size"); + return; + } + + if (endOffset >= bufferSize) + { + NazaraError("End offset is over buffer size"); + return; + } + #endif + + unsigned int stride = (largeIndices) ? sizeof(UInt32) : sizeof(UInt16); + + m_buffer = buffer; + m_endOffset = endOffset; + m_indexCount = (endOffset - startOffset) / stride; + m_largeIndices = largeIndices; + m_startOffset = startOffset; + } + + void IndexBuffer::Reset(bool largeIndices, unsigned int length, UInt32 storage, BufferUsage usage) + { + unsigned int stride = (largeIndices) ? sizeof(UInt32) : sizeof(UInt16); + + m_endOffset = length * stride; + m_indexCount = length; + m_largeIndices = largeIndices; + m_startOffset = 0; + + m_buffer = Buffer::New(BufferType_Index, m_endOffset, storage, usage); + } + + void IndexBuffer::Reset(const IndexBuffer& indexBuffer) + { + m_buffer = indexBuffer.m_buffer; + m_endOffset = indexBuffer.m_endOffset; + m_indexCount = indexBuffer.m_indexCount; + m_largeIndices = indexBuffer.m_largeIndices; + m_startOffset = indexBuffer.m_startOffset; + } + + bool IndexBuffer::SetStorage(UInt32 storage) + { + return m_buffer->SetStorage(storage); + } + + void IndexBuffer::Unmap() const + { + m_buffer->Unmap(); + } + + IndexBuffer& IndexBuffer::operator=(const IndexBuffer& indexBuffer) + { + Reset(indexBuffer); + + return *this; + } } diff --git a/src/Nazara/Utility/IndexMapper.cpp b/src/Nazara/Utility/IndexMapper.cpp index ab7419374..e95f9b3cd 100644 --- a/src/Nazara/Utility/IndexMapper.cpp +++ b/src/Nazara/Utility/IndexMapper.cpp @@ -8,143 +8,146 @@ #include #include -namespace +namespace Nz { - nzUInt32 Getter16(const void* buffer, unsigned int i) + namespace { - const nzUInt16* ptr = reinterpret_cast(buffer); - return ptr[i]; + UInt32 Getter16(const void* buffer, unsigned int i) + { + const UInt16* ptr = reinterpret_cast(buffer); + return ptr[i]; + } + + UInt32 Getter32(const void* buffer, unsigned int i) + { + const UInt32* ptr = reinterpret_cast(buffer); + return ptr[i]; + } + + void Setter16(void* buffer, unsigned int i, UInt32 value) + { + UInt16* ptr = reinterpret_cast(buffer); + ptr[i] = static_cast(value); + } + + void Setter32(void* buffer, unsigned int i, UInt32 value) + { + UInt32* ptr = reinterpret_cast(buffer); + ptr[i] = value; + } + + void SetterError(void*, unsigned int, UInt32) + { + NazaraError("Index buffer opened with read-only access"); + } } - nzUInt32 Getter32(const void* buffer, unsigned int i) + IndexMapper::IndexMapper(IndexBuffer* indexBuffer, BufferAccess access) : + m_indexCount(indexBuffer->GetIndexCount()) { - const nzUInt32* ptr = reinterpret_cast(buffer); - return ptr[i]; - } + #if NAZARA_UTILITY_SAFE + if (!indexBuffer) + { + NazaraError("Index buffer must be valid"); + return; + } + #endif - void Setter16(void* buffer, unsigned int i, nzUInt32 value) - { - nzUInt16* ptr = reinterpret_cast(buffer); - ptr[i] = static_cast(value); - } + if (!m_mapper.Map(indexBuffer, access)) + NazaraError("Failed to map buffer"); ///TODO: Unexcepted - void Setter32(void* buffer, unsigned int i, nzUInt32 value) - { - nzUInt32* ptr = reinterpret_cast(buffer); - ptr[i] = value; - } - - void SetterError(void*, unsigned int, nzUInt32) - { - NazaraError("Index buffer opened with read-only access"); - } -} - -NzIndexMapper::NzIndexMapper(NzIndexBuffer* indexBuffer, nzBufferAccess access) : -m_indexCount(indexBuffer->GetIndexCount()) -{ - #if NAZARA_UTILITY_SAFE - if (!indexBuffer) - { - NazaraError("Index buffer must be valid"); - return; - } - #endif - - if (!m_mapper.Map(indexBuffer, access)) - NazaraError("Failed to map buffer"); ///TODO: Unexcepted - - if (indexBuffer->HasLargeIndices()) - { - m_getter = Getter32; - if (access != nzBufferAccess_ReadOnly) - m_setter = Setter32; + if (indexBuffer->HasLargeIndices()) + { + m_getter = Getter32; + if (access != BufferAccess_ReadOnly) + m_setter = Setter32; + else + m_setter = SetterError; + } else - m_setter = SetterError; + { + m_getter = Getter16; + if (access != BufferAccess_ReadOnly) + m_setter = Setter16; + else + m_setter = SetterError; + } } - else + + IndexMapper::IndexMapper(const IndexBuffer* indexBuffer, BufferAccess access) : + m_setter(SetterError), + m_indexCount(indexBuffer->GetIndexCount()) { - m_getter = Getter16; - if (access != nzBufferAccess_ReadOnly) - m_setter = Setter16; + #if NAZARA_UTILITY_SAFE + if (!indexBuffer) + { + NazaraError("Index buffer must be valid"); + return; + } + #endif + + if (!m_mapper.Map(indexBuffer, access)) + NazaraError("Failed to map buffer"); ///TODO: Unexcepted + + if (indexBuffer->HasLargeIndices()) + m_getter = Getter32; else - m_setter = SetterError; + m_getter = Getter16; } -} -NzIndexMapper::NzIndexMapper(const NzIndexBuffer* indexBuffer, nzBufferAccess access) : -m_setter(SetterError), -m_indexCount(indexBuffer->GetIndexCount()) -{ - #if NAZARA_UTILITY_SAFE - if (!indexBuffer) + IndexMapper::IndexMapper(const SubMesh* subMesh) : + IndexMapper(subMesh->GetIndexBuffer()) { - NazaraError("Index buffer must be valid"); - return; } - #endif - if (!m_mapper.Map(indexBuffer, access)) - NazaraError("Failed to map buffer"); ///TODO: Unexcepted - - if (indexBuffer->HasLargeIndices()) - m_getter = Getter32; - else - m_getter = Getter16; -} - -NzIndexMapper::NzIndexMapper(const NzSubMesh* subMesh) : -NzIndexMapper(subMesh->GetIndexBuffer()) -{ -} - -nzUInt32 NzIndexMapper::Get(unsigned int i) const -{ - #if NAZARA_UTILITY_SAFE - if (i >= m_indexCount) + UInt32 IndexMapper::Get(unsigned int i) const { - NazaraError("Index out of range (" + NzString::Number(i) + " >= " + NzString::Number(m_indexCount) + ')'); - return 0; + #if NAZARA_UTILITY_SAFE + if (i >= m_indexCount) + { + NazaraError("Index out of range (" + String::Number(i) + " >= " + String::Number(m_indexCount) + ')'); + return 0; + } + #endif + + return m_getter(m_mapper.GetPointer(), i); } - #endif - return m_getter(m_mapper.GetPointer(), i); -} - -const NzIndexBuffer* NzIndexMapper::GetBuffer() const -{ - return m_mapper.GetBuffer(); -} - -unsigned int NzIndexMapper::GetIndexCount() const -{ - return m_indexCount; -} - -void NzIndexMapper::Set(unsigned int i, nzUInt32 value) -{ - #if NAZARA_UTILITY_SAFE - if (i >= m_indexCount) + const IndexBuffer* IndexMapper::GetBuffer() const { - NazaraError("Index out of range (" + NzString::Number(i) + " >= " + NzString::Number(m_indexCount) + ')'); - return; + return m_mapper.GetBuffer(); } - #endif - m_setter(m_mapper.GetPointer(), i, value); -} + unsigned int IndexMapper::GetIndexCount() const + { + return m_indexCount; + } -void NzIndexMapper::Unmap() -{ - m_mapper.Unmap(); -} + void IndexMapper::Set(unsigned int i, UInt32 value) + { + #if NAZARA_UTILITY_SAFE + if (i >= m_indexCount) + { + NazaraError("Index out of range (" + String::Number(i) + " >= " + String::Number(m_indexCount) + ')'); + return; + } + #endif -NzIndexIterator NzIndexMapper::begin() -{ - return NzIndexIterator(this, 0); -} + m_setter(m_mapper.GetPointer(), i, value); + } -NzIndexIterator NzIndexMapper::end() -{ - return NzIndexIterator(this, m_indexCount); // Post-end + void IndexMapper::Unmap() + { + m_mapper.Unmap(); + } + + IndexIterator IndexMapper::begin() + { + return IndexIterator(this, 0); + } + + IndexIterator IndexMapper::end() + { + return IndexIterator(this, m_indexCount); // Post-end + } } diff --git a/src/Nazara/Utility/Joint.cpp b/src/Nazara/Utility/Joint.cpp index 0e83874ca..4bd040faa 100644 --- a/src/Nazara/Utility/Joint.cpp +++ b/src/Nazara/Utility/Joint.cpp @@ -6,81 +6,84 @@ #include #include -NzJoint::NzJoint(NzSkeleton* skeleton) : -m_skeleton(skeleton), -m_skinningMatrixUpdated(false) +namespace Nz { -} - -NzJoint::NzJoint(const NzJoint& joint) : -NzNode(joint), -m_inverseBindMatrix(joint.m_inverseBindMatrix), -m_name(joint.m_name), -m_skeleton(joint.m_skeleton), -m_skinningMatrixUpdated(false) -{ -} - -void NzJoint::EnsureSkinningMatrixUpdate() const -{ - if (!m_skinningMatrixUpdated) - UpdateSkinningMatrix(); -} - -const NzMatrix4f& NzJoint::GetInverseBindMatrix() const -{ - return m_inverseBindMatrix; -} - -NzString NzJoint::GetName() const -{ - return m_name; -} - -NzSkeleton* NzJoint::GetSkeleton() -{ - return m_skeleton; -} - -const NzSkeleton* NzJoint::GetSkeleton() const -{ - return m_skeleton; -} - -const NzMatrix4f& NzJoint::GetSkinningMatrix() const -{ - if (!m_skinningMatrixUpdated) - UpdateSkinningMatrix(); - - return m_skinningMatrix; -} - -void NzJoint::SetInverseBindMatrix(const NzMatrix4f& matrix) -{ - m_inverseBindMatrix = matrix; - m_skinningMatrixUpdated = false; -} - -void NzJoint::SetName(const NzString& name) -{ - m_name = name; - - m_skeleton->InvalidateJointMap(); -} - -void NzJoint::InvalidateNode() -{ - NzNode::InvalidateNode(); - - m_skinningMatrixUpdated = false; -} - -void NzJoint::UpdateSkinningMatrix() const -{ - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); - - m_skinningMatrix.Set(m_inverseBindMatrix); - m_skinningMatrix.ConcatenateAffine(m_transformMatrix); - m_skinningMatrixUpdated = true; + Joint::Joint(Skeleton* skeleton) : + m_skeleton(skeleton), + m_skinningMatrixUpdated(false) + { + } + + Joint::Joint(const Joint& joint) : + Node(joint), + m_inverseBindMatrix(joint.m_inverseBindMatrix), + m_name(joint.m_name), + m_skeleton(joint.m_skeleton), + m_skinningMatrixUpdated(false) + { + } + + void Joint::EnsureSkinningMatrixUpdate() const + { + if (!m_skinningMatrixUpdated) + UpdateSkinningMatrix(); + } + + const Matrix4f& Joint::GetInverseBindMatrix() const + { + return m_inverseBindMatrix; + } + + String Joint::GetName() const + { + return m_name; + } + + Skeleton* Joint::GetSkeleton() + { + return m_skeleton; + } + + const Skeleton* Joint::GetSkeleton() const + { + return m_skeleton; + } + + const Matrix4f& Joint::GetSkinningMatrix() const + { + if (!m_skinningMatrixUpdated) + UpdateSkinningMatrix(); + + return m_skinningMatrix; + } + + void Joint::SetInverseBindMatrix(const Matrix4f& matrix) + { + m_inverseBindMatrix = matrix; + m_skinningMatrixUpdated = false; + } + + void Joint::SetName(const String& name) + { + m_name = name; + + m_skeleton->InvalidateJointMap(); + } + + void Joint::InvalidateNode() + { + Node::InvalidateNode(); + + m_skinningMatrixUpdated = false; + } + + void Joint::UpdateSkinningMatrix() const + { + if (!m_transformMatrixUpdated) + UpdateTransformMatrix(); + + m_skinningMatrix.Set(m_inverseBindMatrix); + m_skinningMatrix.ConcatenateAffine(m_transformMatrix); + m_skinningMatrixUpdated = true; + } } diff --git a/src/Nazara/Utility/Keyboard.cpp b/src/Nazara/Utility/Keyboard.cpp index 5d29a0a0e..fb0bb05a5 100644 --- a/src/Nazara/Utility/Keyboard.cpp +++ b/src/Nazara/Utility/Keyboard.cpp @@ -14,12 +14,15 @@ #include -NzString NzKeyboard::GetKeyName(Key key) +namespace Nz { - return NzEventImpl::GetKeyName(key); -} + String Keyboard::GetKeyName(Key key) + { + return EventImpl::GetKeyName(key); + } -bool NzKeyboard::IsKeyPressed(Key key) -{ - return NzEventImpl::IsKeyPressed(key); + bool Keyboard::IsKeyPressed(Key key) + { + return EventImpl::IsKeyPressed(key); + } } diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index b0ff758aa..3492916b1 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -23,1010 +23,1012 @@ #include #include -NzMeshParams::NzMeshParams() +namespace Nz { - if (!NzBuffer::IsStorageSupported(storage)) - storage = nzDataStorage_Software; -} - -bool NzMeshParams::IsValid() const -{ - if (!NzBuffer::IsStorageSupported(storage)) + MeshParams::MeshParams() { - NazaraError("Storage not supported"); - return false; + if (!Buffer::IsStorageSupported(storage)) + storage = DataStorage_Software; } - if (scale == NzVector3f::Zero()) + bool MeshParams::IsValid() const { - NazaraError("Invalid scale"); - return false; - } - - return true; -} - -struct NzMeshImpl -{ - NzMeshImpl() - { - materials.resize(1); // Un matériau par défaut - } - - std::unordered_map subMeshMap; - std::vector materials; - std::vector subMeshes; - nzAnimationType animationType; - NzBoxf aabb; - NzSkeleton skeleton; // Uniquement pour les meshs squelettiques - NzString animationPath; - bool aabbUpdated = false; - unsigned int jointCount; // Uniquement pour les meshs squelettiques -}; - -NzMesh::~NzMesh() -{ - OnMeshRelease(this); - - Destroy(); -} - -void NzMesh::AddSubMesh(NzSubMesh* subMesh) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - if (!subMesh) - { - NazaraError("Invalid submesh"); - return; - } - - if (subMesh->GetAnimationType() != m_impl->animationType) - { - NazaraError("Submesh animation type must match mesh animation type"); - return; - } - #endif - - m_impl->aabbUpdated = false; // On invalide l'AABB - m_impl->subMeshes.push_back(subMesh); -} - -void NzMesh::AddSubMesh(const NzString& identifier, NzSubMesh* subMesh) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - if (identifier.IsEmpty()) - { - NazaraError("Identifier is empty"); - return; - } - - auto it = m_impl->subMeshMap.find(identifier); - if (it != m_impl->subMeshMap.end()) - { - NazaraError("SubMesh identifier \"" + identifier + "\" is already used"); - return; - } - - if (!subMesh) - { - NazaraError("Invalid submesh"); - return; - } - - if (m_impl->animationType != subMesh->GetAnimationType()) - { - NazaraError("Submesh animation type must match mesh animation type"); - return; - } - #endif - - int index = m_impl->subMeshes.size(); - - m_impl->aabbUpdated = false; // On invalide l'AABB - m_impl->subMeshes.push_back(subMesh); - m_impl->subMeshMap[identifier] = index; -} - -NzSubMesh* NzMesh::BuildSubMesh(const NzPrimitive& primitive, const NzMeshParams& params) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - - if (m_impl->animationType != nzAnimationType_Static) - { - NazaraError("Mesh must be static"); - return nullptr; - } - - if (!params.IsValid()) - { - NazaraError("Parameters must be valid"); - return nullptr; - } - #endif - - NzBoxf aabb; - NzIndexBufferRef indexBuffer; - NzVertexBufferRef vertexBuffer; - - NzMatrix4f matrix(primitive.matrix); - matrix.ApplyScale(params.scale); - - NzVertexDeclaration* declaration = NzVertexDeclaration::Get(nzVertexLayout_XYZ_Normal_UV_Tangent); - - switch (primitive.type) - { - case nzPrimitiveType_Box: + if (!Buffer::IsStorageSupported(storage)) { - unsigned int indexCount; - unsigned int vertexCount; - NzComputeBoxIndexVertexCount(primitive.box.subdivision, &indexCount, &vertexCount); - - indexBuffer = NzIndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, nzBufferUsage_Static); - vertexBuffer = NzVertexBuffer::New(declaration, vertexCount, params.storage, nzBufferUsage_Static); - - NzVertexMapper vertexMapper(vertexBuffer, nzBufferAccess_WriteOnly); - - NzVertexPointers pointers; - pointers.normalPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Normal); - pointers.positionPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Position); - pointers.tangentPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Tangent); - pointers.uvPtr = vertexMapper.GetComponentPtr(nzVertexComponent_TexCoord); - - NzIndexMapper indexMapper(indexBuffer, nzBufferAccess_WriteOnly); - NzGenerateBox(primitive.box.lengths, primitive.box.subdivision, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb); - break; + NazaraError("Storage not supported"); + return false; } - case nzPrimitiveType_Cone: + if (scale == Vector3f::Zero()) { - unsigned int indexCount; - unsigned int vertexCount; - NzComputeConeIndexVertexCount(primitive.cone.subdivision, &indexCount, &vertexCount); - - indexBuffer = NzIndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, nzBufferUsage_Static); - vertexBuffer = NzVertexBuffer::New(declaration, vertexCount, params.storage, nzBufferUsage_Static); - - NzVertexMapper vertexMapper(vertexBuffer, nzBufferAccess_WriteOnly); - - NzVertexPointers pointers; - pointers.normalPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Normal); - pointers.positionPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Position); - pointers.tangentPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Tangent); - pointers.uvPtr = vertexMapper.GetComponentPtr(nzVertexComponent_TexCoord); - - NzIndexMapper indexMapper(indexBuffer, nzBufferAccess_WriteOnly); - NzGenerateCone(primitive.cone.length, primitive.cone.radius, primitive.cone.subdivision, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb); - break; + NazaraError("Invalid scale"); + return false; } - case nzPrimitiveType_Plane: + return true; + } + + struct MeshImpl + { + MeshImpl() { - unsigned int indexCount; - unsigned int vertexCount; - NzComputePlaneIndexVertexCount(primitive.plane.subdivision, &indexCount, &vertexCount); - - indexBuffer = NzIndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, nzBufferUsage_Static); - vertexBuffer = NzVertexBuffer::New(declaration, vertexCount, params.storage, nzBufferUsage_Static); - - NzVertexMapper vertexMapper(vertexBuffer, nzBufferAccess_WriteOnly); - - NzVertexPointers pointers; - pointers.normalPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Normal); - pointers.positionPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Position); - pointers.tangentPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Tangent); - pointers.uvPtr = vertexMapper.GetComponentPtr(nzVertexComponent_TexCoord); - - NzIndexMapper indexMapper(indexBuffer, nzBufferAccess_WriteOnly); - NzGeneratePlane(primitive.plane.subdivision, primitive.plane.size, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb); - break; + materials.resize(1); // Un matériau par défaut } - case nzPrimitiveType_Sphere: + std::unordered_map subMeshMap; + std::vector materials; + std::vector subMeshes; + AnimationType animationType; + Boxf aabb; + Skeleton skeleton; // Uniquement pour les meshs squelettiques + String animationPath; + bool aabbUpdated = false; + unsigned int jointCount; // Uniquement pour les meshs squelettiques + }; + + Mesh::~Mesh() + { + OnMeshRelease(this); + + Destroy(); + } + + void Mesh::AddSubMesh(SubMesh* subMesh) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) { - switch (primitive.sphere.type) + NazaraError("Mesh not created"); + return; + } + + if (!subMesh) + { + NazaraError("Invalid submesh"); + return; + } + + if (subMesh->GetAnimationType() != m_impl->animationType) + { + NazaraError("Submesh animation type must match mesh animation type"); + return; + } + #endif + + m_impl->aabbUpdated = false; // On invalide l'AABB + m_impl->subMeshes.push_back(subMesh); + } + + void Mesh::AddSubMesh(const String& identifier, SubMesh* subMesh) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return; + } + + if (identifier.IsEmpty()) + { + NazaraError("Identifier is empty"); + return; + } + + auto it = m_impl->subMeshMap.find(identifier); + if (it != m_impl->subMeshMap.end()) + { + NazaraError("SubMesh identifier \"" + identifier + "\" is already used"); + return; + } + + if (!subMesh) + { + NazaraError("Invalid submesh"); + return; + } + + if (m_impl->animationType != subMesh->GetAnimationType()) + { + NazaraError("Submesh animation type must match mesh animation type"); + return; + } + #endif + + int index = m_impl->subMeshes.size(); + + m_impl->aabbUpdated = false; // On invalide l'AABB + m_impl->subMeshes.push_back(subMesh); + m_impl->subMeshMap[identifier] = index; + } + + SubMesh* Mesh::BuildSubMesh(const Primitive& primitive, const MeshParams& params) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return nullptr; + } + + if (m_impl->animationType != AnimationType_Static) + { + NazaraError("Mesh must be static"); + return nullptr; + } + + if (!params.IsValid()) + { + NazaraError("Parameters must be valid"); + return nullptr; + } + #endif + + Boxf aabb; + IndexBufferRef indexBuffer; + VertexBufferRef vertexBuffer; + + Matrix4f matrix(primitive.matrix); + matrix.ApplyScale(params.scale); + + VertexDeclaration* declaration = VertexDeclaration::Get(VertexLayout_XYZ_Normal_UV_Tangent); + + switch (primitive.type) + { + case PrimitiveType_Box: { - case nzSphereType_Cubic: - { - unsigned int indexCount; - unsigned int vertexCount; - NzComputeCubicSphereIndexVertexCount(primitive.sphere.cubic.subdivision, &indexCount, &vertexCount); + unsigned int indexCount; + unsigned int vertexCount; + ComputeBoxIndexVertexCount(primitive.box.subdivision, &indexCount, &vertexCount); - indexBuffer = NzIndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, nzBufferUsage_Static); - vertexBuffer = NzVertexBuffer::New(declaration, vertexCount, params.storage, nzBufferUsage_Static); + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, BufferUsage_Static); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static); - NzVertexMapper vertexMapper(vertexBuffer, nzBufferAccess_ReadWrite); + VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); - NzVertexPointers pointers; - pointers.normalPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Normal); - pointers.positionPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Position); - pointers.tangentPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Tangent); - pointers.uvPtr = vertexMapper.GetComponentPtr(nzVertexComponent_TexCoord); + VertexPointers pointers; + pointers.normalPtr = vertexMapper.GetComponentPtr(VertexComponent_Normal); + pointers.positionPtr = vertexMapper.GetComponentPtr(VertexComponent_Position); + pointers.tangentPtr = vertexMapper.GetComponentPtr(VertexComponent_Tangent); + pointers.uvPtr = vertexMapper.GetComponentPtr(VertexComponent_TexCoord); - NzIndexMapper indexMapper(indexBuffer, nzBufferAccess_WriteOnly); - NzGenerateCubicSphere(primitive.sphere.size, primitive.sphere.cubic.subdivision, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb); - break; - } - - case nzSphereType_Ico: - { - unsigned int indexCount; - unsigned int vertexCount; - NzComputeIcoSphereIndexVertexCount(primitive.sphere.ico.recursionLevel, &indexCount, &vertexCount); - - indexBuffer = NzIndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, nzBufferUsage_Static); - vertexBuffer = NzVertexBuffer::New(declaration, vertexCount, params.storage, nzBufferUsage_Static); - - NzVertexMapper vertexMapper(vertexBuffer, nzBufferAccess_WriteOnly); - - NzVertexPointers pointers; - pointers.normalPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Normal); - pointers.positionPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Position); - pointers.tangentPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Tangent); - pointers.uvPtr = vertexMapper.GetComponentPtr(nzVertexComponent_TexCoord); - - NzIndexMapper indexMapper(indexBuffer, nzBufferAccess_WriteOnly); - NzGenerateIcoSphere(primitive.sphere.size, primitive.sphere.ico.recursionLevel, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb); - break; - } - - case nzSphereType_UV: - { - unsigned int indexCount; - unsigned int vertexCount; - NzComputeUvSphereIndexVertexCount(primitive.sphere.uv.sliceCount, primitive.sphere.uv.stackCount, &indexCount, &vertexCount); - - indexBuffer = NzIndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, nzBufferUsage_Static); - vertexBuffer = NzVertexBuffer::New(declaration, vertexCount, params.storage, nzBufferUsage_Static); - - NzVertexMapper vertexMapper(vertexBuffer, nzBufferAccess_WriteOnly); - - NzVertexPointers pointers; - pointers.normalPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Normal); - pointers.positionPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Position); - pointers.tangentPtr = vertexMapper.GetComponentPtr(nzVertexComponent_Tangent); - pointers.uvPtr = vertexMapper.GetComponentPtr(nzVertexComponent_TexCoord); - - NzIndexMapper indexMapper(indexBuffer, nzBufferAccess_WriteOnly); - NzGenerateUvSphere(primitive.sphere.size, primitive.sphere.uv.sliceCount, primitive.sphere.uv.stackCount, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb); - break; - } + IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly); + GenerateBox(primitive.box.lengths, primitive.box.subdivision, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb); + break; + } + + case PrimitiveType_Cone: + { + unsigned int indexCount; + unsigned int vertexCount; + ComputeConeIndexVertexCount(primitive.cone.subdivision, &indexCount, &vertexCount); + + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, BufferUsage_Static); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static); + + VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); + + VertexPointers pointers; + pointers.normalPtr = vertexMapper.GetComponentPtr(VertexComponent_Normal); + pointers.positionPtr = vertexMapper.GetComponentPtr(VertexComponent_Position); + pointers.tangentPtr = vertexMapper.GetComponentPtr(VertexComponent_Tangent); + pointers.uvPtr = vertexMapper.GetComponentPtr(VertexComponent_TexCoord); + + IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly); + GenerateCone(primitive.cone.length, primitive.cone.radius, primitive.cone.subdivision, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb); + break; + } + + case PrimitiveType_Plane: + { + unsigned int indexCount; + unsigned int vertexCount; + ComputePlaneIndexVertexCount(primitive.plane.subdivision, &indexCount, &vertexCount); + + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, BufferUsage_Static); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static); + + VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); + + VertexPointers pointers; + pointers.normalPtr = vertexMapper.GetComponentPtr(VertexComponent_Normal); + pointers.positionPtr = vertexMapper.GetComponentPtr(VertexComponent_Position); + pointers.tangentPtr = vertexMapper.GetComponentPtr(VertexComponent_Tangent); + pointers.uvPtr = vertexMapper.GetComponentPtr(VertexComponent_TexCoord); + + IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly); + GeneratePlane(primitive.plane.subdivision, primitive.plane.size, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb); + break; + } + + case PrimitiveType_Sphere: + { + switch (primitive.sphere.type) + { + case SphereType_Cubic: + { + unsigned int indexCount; + unsigned int vertexCount; + ComputeCubicSphereIndexVertexCount(primitive.sphere.cubic.subdivision, &indexCount, &vertexCount); + + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, BufferUsage_Static); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static); + + VertexMapper vertexMapper(vertexBuffer, BufferAccess_ReadWrite); + + VertexPointers pointers; + pointers.normalPtr = vertexMapper.GetComponentPtr(VertexComponent_Normal); + pointers.positionPtr = vertexMapper.GetComponentPtr(VertexComponent_Position); + pointers.tangentPtr = vertexMapper.GetComponentPtr(VertexComponent_Tangent); + pointers.uvPtr = vertexMapper.GetComponentPtr(VertexComponent_TexCoord); + + IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly); + GenerateCubicSphere(primitive.sphere.size, primitive.sphere.cubic.subdivision, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb); + break; + } + + case SphereType_Ico: + { + unsigned int indexCount; + unsigned int vertexCount; + ComputeIcoSphereIndexVertexCount(primitive.sphere.ico.recursionLevel, &indexCount, &vertexCount); + + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, BufferUsage_Static); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static); + + VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); + + VertexPointers pointers; + pointers.normalPtr = vertexMapper.GetComponentPtr(VertexComponent_Normal); + pointers.positionPtr = vertexMapper.GetComponentPtr(VertexComponent_Position); + pointers.tangentPtr = vertexMapper.GetComponentPtr(VertexComponent_Tangent); + pointers.uvPtr = vertexMapper.GetComponentPtr(VertexComponent_TexCoord); + + IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly); + GenerateIcoSphere(primitive.sphere.size, primitive.sphere.ico.recursionLevel, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb); + break; + } + + case SphereType_UV: + { + unsigned int indexCount; + unsigned int vertexCount; + ComputeUvSphereIndexVertexCount(primitive.sphere.uv.sliceCount, primitive.sphere.uv.stackCount, &indexCount, &vertexCount); + + indexBuffer = IndexBuffer::New(vertexCount > std::numeric_limits::max(), indexCount, params.storage, BufferUsage_Static); + vertexBuffer = VertexBuffer::New(declaration, vertexCount, params.storage, BufferUsage_Static); + + VertexMapper vertexMapper(vertexBuffer, BufferAccess_WriteOnly); + + VertexPointers pointers; + pointers.normalPtr = vertexMapper.GetComponentPtr(VertexComponent_Normal); + pointers.positionPtr = vertexMapper.GetComponentPtr(VertexComponent_Position); + pointers.tangentPtr = vertexMapper.GetComponentPtr(VertexComponent_Tangent); + pointers.uvPtr = vertexMapper.GetComponentPtr(VertexComponent_TexCoord); + + IndexMapper indexMapper(indexBuffer, BufferAccess_WriteOnly); + GenerateUvSphere(primitive.sphere.size, primitive.sphere.uv.sliceCount, primitive.sphere.uv.stackCount, matrix, primitive.textureCoords, pointers, indexMapper.begin(), &aabb); + break; + } + } + break; } - break; } - } - NzStaticMeshRef subMesh = NzStaticMesh::New(this); - if (!subMesh->Create(vertexBuffer)) - { - NazaraError("Failed to create StaticMesh"); - return nullptr; - } - - if (params.optimizeIndexBuffers) - indexBuffer->Optimize(); - - subMesh->SetAABB(aabb); - subMesh->SetIndexBuffer(indexBuffer); - - AddSubMesh(subMesh); - return subMesh; -} - -void NzMesh::BuildSubMeshes(const NzPrimitiveList& list, const NzMeshParams& params) -{ - unsigned int primitiveCount = list.GetSize(); - - #if NAZARA_UTILITY_SAFE - if (primitiveCount == 0) - { - NazaraError("PrimitiveList must have at least one primitive"); - return; - } - #endif - - for (unsigned int i = 0; i < primitiveCount; ++i) - BuildSubMesh(list.GetPrimitive(i), params); -} - -bool NzMesh::CreateSkeletal(unsigned int jointCount) -{ - Destroy(); - - m_impl = new NzMeshImpl; - m_impl->animationType = nzAnimationType_Skeletal; - m_impl->jointCount = jointCount; - if (!m_impl->skeleton.Create(jointCount)) - { - delete m_impl; - m_impl = nullptr; - - NazaraError("Failed to create skeleton"); - return false; - } - - return true; -} - -bool NzMesh::CreateStatic() -{ - Destroy(); - - m_impl = new NzMeshImpl; - m_impl->animationType = nzAnimationType_Static; - - return true; -} - -void NzMesh::Destroy() -{ - if (m_impl) - { - OnMeshDestroy(this); - - delete m_impl; - m_impl = nullptr; - } -} - -void NzMesh::GenerateNormals() -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif - - for (NzSubMesh* subMesh : m_impl->subMeshes) - subMesh->GenerateNormals(); -} - -void NzMesh::GenerateNormalsAndTangents() -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif - - for (NzSubMesh* subMesh : m_impl->subMeshes) - subMesh->GenerateNormalsAndTangents(); -} - -void NzMesh::GenerateTangents() -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif - - for (NzSubMesh* subMesh : m_impl->subMeshes) - subMesh->GenerateTangents(); -} - -const NzBoxf& NzMesh::GetAABB() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - - static NzBoxf dummy; - return dummy; - } - #endif - - if (!m_impl->aabbUpdated) - { - unsigned int subMeshCount = m_impl->subMeshes.size(); - if (subMeshCount > 0) + StaticMeshRef subMesh = StaticMesh::New(this); + if (!subMesh->Create(vertexBuffer)) { - m_impl->aabb.Set(m_impl->subMeshes[0]->GetAABB()); - for (unsigned int i = 1; i < subMeshCount; ++i) - m_impl->aabb.ExtendTo(m_impl->subMeshes[i]->GetAABB()); + NazaraError("Failed to create StaticMesh"); + return nullptr; } - else - m_impl->aabb.MakeZero(); - m_impl->aabbUpdated = true; + if (params.optimizeIndexBuffers) + indexBuffer->Optimize(); + + subMesh->SetAABB(aabb); + subMesh->SetIndexBuffer(indexBuffer); + + AddSubMesh(subMesh); + return subMesh; } - return m_impl->aabb; -} - -NzString NzMesh::GetAnimation() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) + void Mesh::BuildSubMeshes(const PrimitiveList& list, const MeshParams& params) { - NazaraError("Mesh not created"); - return NzString(); - } - #endif + unsigned int primitiveCount = list.GetSize(); - return m_impl->animationPath; -} - -nzAnimationType NzMesh::GetAnimationType() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nzAnimationType_Static; - } - #endif - - return m_impl->animationType; -} - -unsigned int NzMesh::GetJointCount() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - - if (m_impl->animationType != nzAnimationType_Skeletal) - { - NazaraError("Mesh's animation type is not skeletal"); - return 0; - } - #endif - - return m_impl->jointCount; -} - -NzString NzMesh::GetMaterial(unsigned int index) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return NzString(); - } - - if (index >= m_impl->materials.size()) - { - NazaraError("Material index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->materials.size()) + ')'); - return NzString(); - } - #endif - - return m_impl->materials[index]; -} - -unsigned int NzMesh::GetMaterialCount() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - #endif - - return m_impl->materials.size(); -} - -NzSkeleton* NzMesh::GetSkeleton() -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return nullptr; - } - - if (m_impl->animationType != nzAnimationType_Skeletal) - { - NazaraError("Mesh's animation type is not skeletal"); - return nullptr; - } - #endif - - return &m_impl->skeleton; -} - -const NzSkeleton* NzMesh::GetSkeleton() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Animation not created"); - return nullptr; - } - - if (m_impl->animationType != nzAnimationType_Skeletal) - { - NazaraError("Mesh's animation type is not skeletal"); - return nullptr; - } - #endif - - return &m_impl->skeleton; -} - -NzSubMesh* NzMesh::GetSubMesh(const NzString& identifier) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - #endif - - auto it = m_impl->subMeshMap.find(identifier); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->subMeshMap.end()) - { - NazaraError("SubMesh not found"); - return nullptr; - } - #endif - - return m_impl->subMeshes[it->second]; -} - -NzSubMesh* NzMesh::GetSubMesh(unsigned int index) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - - if (index >= m_impl->subMeshes.size()) - { - NazaraError("SubMesh index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->subMeshes.size()) + ')'); - return nullptr; - } - #endif - - return m_impl->subMeshes[index]; -} - -const NzSubMesh* NzMesh::GetSubMesh(const NzString& identifier) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - #endif - - auto it = m_impl->subMeshMap.find(identifier); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->subMeshMap.end()) - { - NazaraError("SubMesh not found"); - return nullptr; - } - #endif - - return m_impl->subMeshes[it->second]; -} - -const NzSubMesh* NzMesh::GetSubMesh(unsigned int index) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return nullptr; - } - - if (index >= m_impl->subMeshes.size()) - { - NazaraError("SubMesh index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->subMeshes.size()) + ')'); - return nullptr; - } - #endif - - return m_impl->subMeshes[index]; -} - -unsigned int NzMesh::GetSubMeshCount() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - #endif - - return m_impl->subMeshes.size(); -} - -int NzMesh::GetSubMeshIndex(const NzString& identifier) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return -1; - } - #endif - - auto it = m_impl->subMeshMap.find(identifier); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->subMeshMap.end()) - { - NazaraError("SubMesh not found"); - return -1; - } - #endif - - return it->second; -} - -unsigned int NzMesh::GetTriangleCount() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - #endif - - unsigned int triangleCount = 0; - for (NzSubMesh* subMesh : m_impl->subMeshes) - triangleCount += subMesh->GetTriangleCount(); - - return triangleCount; -} - -unsigned int NzMesh::GetVertexCount() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return 0; - } - #endif - - unsigned int vertexCount = 0; - for (NzSubMesh* subMesh : m_impl->subMeshes) - vertexCount += subMesh->GetVertexCount(); - - return vertexCount; -} - -void NzMesh::InvalidateAABB() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif - - m_impl->aabbUpdated = false; -} - -bool NzMesh::HasSubMesh(const NzString& identifier) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return false; - } - #endif - - return m_impl->subMeshMap.find(identifier) != m_impl->subMeshMap.end(); -} - -bool NzMesh::HasSubMesh(unsigned int index) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return false; - } - #endif - - return index < m_impl->subMeshes.size(); -} - -bool NzMesh::IsAnimable() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return false; - } - #endif - - return m_impl->animationType != nzAnimationType_Static; -} - -bool NzMesh::IsValid() const -{ - return m_impl != nullptr; -} - -bool NzMesh::LoadFromFile(const NzString& filePath, const NzMeshParams& params) -{ - return NzMeshLoader::LoadFromFile(this, filePath, params); -} - -bool NzMesh::LoadFromMemory(const void* data, std::size_t size, const NzMeshParams& params) -{ - return NzMeshLoader::LoadFromMemory(this, data, size, params); -} - -bool NzMesh::LoadFromStream(NzInputStream& stream, const NzMeshParams& params) -{ - return NzMeshLoader::LoadFromStream(this, stream, params); -} - -void NzMesh::Recenter() -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - if (m_impl->animationType != nzAnimationType_Static) - { - NazaraError("Mesh must be static"); - return; - } - #endif - - // Le centre de notre mesh est le centre de l'AABB *globale* - NzVector3f center = GetAABB().GetCenter(); - - for (NzSubMesh* subMesh : m_impl->subMeshes) - { - NzStaticMesh* staticMesh = static_cast(subMesh); - - NzBufferMapper mapper(staticMesh->GetVertexBuffer(), nzBufferAccess_ReadWrite); - NzMeshVertex* vertices = static_cast(mapper.GetPointer()); - - unsigned int vertexCount = staticMesh->GetVertexCount(); - for (unsigned int i = 0; i < vertexCount; ++i) + #if NAZARA_UTILITY_SAFE + if (primitiveCount == 0) { - vertices->position -= center; - vertices++; + NazaraError("PrimitiveList must have at least one primitive"); + return; } + #endif - // l'AABB ne change pas de dimensions mais seulement de position, appliquons-lui le même procédé - NzBoxf aabb = staticMesh->GetAABB(); - aabb.Translate(-center); - - staticMesh->SetAABB(aabb); + for (unsigned int i = 0; i < primitiveCount; ++i) + BuildSubMesh(list.GetPrimitive(i), params); } - // Il ne faut pas oublier d'invalider notre AABB - m_impl->aabbUpdated = false; -} - -void NzMesh::RemoveSubMesh(const NzString& identifier) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) + bool Mesh::CreateSkeletal(unsigned int jointCount) { - NazaraError("Mesh not created"); - return; - } + Destroy(); - auto it = m_impl->subMeshMap.find(identifier); - if (it == m_impl->subMeshMap.end()) - { - NazaraError("SubMesh not found"); - return; - } - - unsigned int index = it->second; - #else - unsigned int index = m_impl->subMeshMap[identifier]; - #endif - - // On déplace l'itérateur du début d'une distance de x - auto it2 = m_impl->subMeshes.begin(); - std::advance(it2, index); - m_impl->subMeshes.erase(it2); - - m_impl->aabbUpdated = false; // On invalide l'AABB -} - -void NzMesh::RemoveSubMesh(unsigned int index) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - if (index >= m_impl->subMeshes.size()) - { - NazaraError("SubMesh index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->subMeshes.size()) + ')'); - return; - } - #endif - - // On déplace l'itérateur du début de x - auto it = m_impl->subMeshes.begin(); - std::advance(it, index); - m_impl->subMeshes.erase(it); - - m_impl->aabbUpdated = false; // On invalide l'AABB -} - -void NzMesh::SetAnimation(const NzString& animationPath) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - #endif - - m_impl->animationPath = animationPath; -} - -void NzMesh::SetMaterial(unsigned int matIndex, const NzString& materialPath) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - if (matIndex >= m_impl->materials.size()) - { - NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_impl->materials.size()) + ')'); - return; - } - #endif - - m_impl->materials[matIndex] = materialPath; -} - -void NzMesh::SetMaterialCount(unsigned int matCount) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; - } - - if (matCount == 0) - { - NazaraError("A mesh should have at least a material"); - return; - } - #endif - - m_impl->materials.resize(matCount); - - #ifdef NAZARA_DEBUG - for (NzSubMesh* subMesh : m_impl->subMeshes) - { - unsigned int matIndex = subMesh->GetMaterialIndex(); - if (matIndex >= matCount) + m_impl = new MeshImpl; + m_impl->animationType = AnimationType_Skeletal; + m_impl->jointCount = jointCount; + if (!m_impl->skeleton.Create(jointCount)) { - subMesh->SetMaterialIndex(0); // Pour empêcher un crash - NazaraWarning("SubMesh " + NzString::Pointer(subMesh) + " material index is over mesh new material count (" + NzString::Number(matIndex) + " >= " + NzString::Number(matCount) + "), setting it to first material"); + delete m_impl; + m_impl = nullptr; + + NazaraError("Failed to create skeleton"); + return false; } - } - #endif -} -void NzMesh::Transform(const NzMatrix4f& matrix) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Mesh not created"); - return; + return true; } - if (m_impl->animationType != nzAnimationType_Static) + bool Mesh::CreateStatic() { - NazaraError("Mesh must be static"); - return; + Destroy(); + + m_impl = new MeshImpl; + m_impl->animationType = AnimationType_Static; + + return true; } - #endif - if (matrix.IsIdentity()) - return; - - for (NzSubMesh* subMesh : m_impl->subMeshes) + void Mesh::Destroy() { - NzStaticMesh* staticMesh = static_cast(subMesh); - - NzBufferMapper mapper(staticMesh->GetVertexBuffer(), nzBufferAccess_ReadWrite); - NzMeshVertex* vertices = static_cast(mapper.GetPointer()); - - NzBoxf aabb(vertices->position.x, vertices->position.y, vertices->position.z, 0.f, 0.f, 0.f); - - unsigned int vertexCount = staticMesh->GetVertexCount(); - for (unsigned int i = 0; i < vertexCount; ++i) + if (m_impl) { - vertices->position = matrix.Transform(vertices->position); - aabb.ExtendTo(vertices->position); + OnMeshDestroy(this); - vertices++; + delete m_impl; + m_impl = nullptr; + } + } + + void Mesh::GenerateNormals() + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return; + } + #endif + + for (SubMesh* subMesh : m_impl->subMeshes) + subMesh->GenerateNormals(); + } + + void Mesh::GenerateNormalsAndTangents() + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return; + } + #endif + + for (SubMesh* subMesh : m_impl->subMeshes) + subMesh->GenerateNormalsAndTangents(); + } + + void Mesh::GenerateTangents() + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return; + } + #endif + + for (SubMesh* subMesh : m_impl->subMeshes) + subMesh->GenerateTangents(); + } + + const Boxf& Mesh::GetAABB() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + + static Boxf dummy; + return dummy; + } + #endif + + if (!m_impl->aabbUpdated) + { + unsigned int subMeshCount = m_impl->subMeshes.size(); + if (subMeshCount > 0) + { + m_impl->aabb.Set(m_impl->subMeshes[0]->GetAABB()); + for (unsigned int i = 1; i < subMeshCount; ++i) + m_impl->aabb.ExtendTo(m_impl->subMeshes[i]->GetAABB()); + } + else + m_impl->aabb.MakeZero(); + + m_impl->aabbUpdated = true; } - staticMesh->SetAABB(aabb); + return m_impl->aabb; } - // Il ne faut pas oublier d'invalider notre AABB - m_impl->aabbUpdated = false; -} - -bool NzMesh::Initialize() -{ - if (!NzMeshLibrary::Initialize()) + String Mesh::GetAnimation() const { - NazaraError("Failed to initialise library"); - return false; + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return String(); + } + #endif + + return m_impl->animationPath; } - if (!NzMeshManager::Initialize()) + AnimationType Mesh::GetAnimationType() const { - NazaraError("Failed to initialise manager"); - return false; + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return AnimationType_Static; + } + #endif + + return m_impl->animationType; } - return true; + unsigned int Mesh::GetJointCount() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return 0; + } + + if (m_impl->animationType != AnimationType_Skeletal) + { + NazaraError("Mesh's animation type is not skeletal"); + return 0; + } + #endif + + return m_impl->jointCount; + } + + String Mesh::GetMaterial(unsigned int index) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return String(); + } + + if (index >= m_impl->materials.size()) + { + NazaraError("Material index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->materials.size()) + ')'); + return String(); + } + #endif + + return m_impl->materials[index]; + } + + unsigned int Mesh::GetMaterialCount() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return 0; + } + #endif + + return m_impl->materials.size(); + } + + Skeleton* Mesh::GetSkeleton() + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return nullptr; + } + + if (m_impl->animationType != AnimationType_Skeletal) + { + NazaraError("Mesh's animation type is not skeletal"); + return nullptr; + } + #endif + + return &m_impl->skeleton; + } + + const Skeleton* Mesh::GetSkeleton() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Animation not created"); + return nullptr; + } + + if (m_impl->animationType != AnimationType_Skeletal) + { + NazaraError("Mesh's animation type is not skeletal"); + return nullptr; + } + #endif + + return &m_impl->skeleton; + } + + SubMesh* Mesh::GetSubMesh(const String& identifier) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return nullptr; + } + #endif + + auto it = m_impl->subMeshMap.find(identifier); + + #if NAZARA_UTILITY_SAFE + if (it == m_impl->subMeshMap.end()) + { + NazaraError("SubMesh not found"); + return nullptr; + } + #endif + + return m_impl->subMeshes[it->second]; + } + + SubMesh* Mesh::GetSubMesh(unsigned int index) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return nullptr; + } + + if (index >= m_impl->subMeshes.size()) + { + NazaraError("SubMesh index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->subMeshes.size()) + ')'); + return nullptr; + } + #endif + + return m_impl->subMeshes[index]; + } + + const SubMesh* Mesh::GetSubMesh(const String& identifier) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return nullptr; + } + #endif + + auto it = m_impl->subMeshMap.find(identifier); + + #if NAZARA_UTILITY_SAFE + if (it == m_impl->subMeshMap.end()) + { + NazaraError("SubMesh not found"); + return nullptr; + } + #endif + + return m_impl->subMeshes[it->second]; + } + + const SubMesh* Mesh::GetSubMesh(unsigned int index) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return nullptr; + } + + if (index >= m_impl->subMeshes.size()) + { + NazaraError("SubMesh index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->subMeshes.size()) + ')'); + return nullptr; + } + #endif + + return m_impl->subMeshes[index]; + } + + unsigned int Mesh::GetSubMeshCount() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return 0; + } + #endif + + return m_impl->subMeshes.size(); + } + + int Mesh::GetSubMeshIndex(const String& identifier) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return -1; + } + #endif + + auto it = m_impl->subMeshMap.find(identifier); + + #if NAZARA_UTILITY_SAFE + if (it == m_impl->subMeshMap.end()) + { + NazaraError("SubMesh not found"); + return -1; + } + #endif + + return it->second; + } + + unsigned int Mesh::GetTriangleCount() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return 0; + } + #endif + + unsigned int triangleCount = 0; + for (SubMesh* subMesh : m_impl->subMeshes) + triangleCount += subMesh->GetTriangleCount(); + + return triangleCount; + } + + unsigned int Mesh::GetVertexCount() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return 0; + } + #endif + + unsigned int vertexCount = 0; + for (SubMesh* subMesh : m_impl->subMeshes) + vertexCount += subMesh->GetVertexCount(); + + return vertexCount; + } + + void Mesh::InvalidateAABB() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return; + } + #endif + + m_impl->aabbUpdated = false; + } + + bool Mesh::HasSubMesh(const String& identifier) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return false; + } + #endif + + return m_impl->subMeshMap.find(identifier) != m_impl->subMeshMap.end(); + } + + bool Mesh::HasSubMesh(unsigned int index) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return false; + } + #endif + + return index < m_impl->subMeshes.size(); + } + + bool Mesh::IsAnimable() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return false; + } + #endif + + return m_impl->animationType != AnimationType_Static; + } + + bool Mesh::IsValid() const + { + return m_impl != nullptr; + } + + bool Mesh::LoadFromFile(const String& filePath, const MeshParams& params) + { + return MeshLoader::LoadFromFile(this, filePath, params); + } + + bool Mesh::LoadFromMemory(const void* data, std::size_t size, const MeshParams& params) + { + return MeshLoader::LoadFromMemory(this, data, size, params); + } + + bool Mesh::LoadFromStream(InputStream& stream, const MeshParams& params) + { + return MeshLoader::LoadFromStream(this, stream, params); + } + + void Mesh::Recenter() + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return; + } + + if (m_impl->animationType != AnimationType_Static) + { + NazaraError("Mesh must be static"); + return; + } + #endif + + // Le centre de notre mesh est le centre de l'AABB *globale* + Vector3f center = GetAABB().GetCenter(); + + for (SubMesh* subMesh : m_impl->subMeshes) + { + StaticMesh* staticMesh = static_cast(subMesh); + + BufferMapper mapper(staticMesh->GetVertexBuffer(), BufferAccess_ReadWrite); + MeshVertex* vertices = static_cast(mapper.GetPointer()); + + unsigned int vertexCount = staticMesh->GetVertexCount(); + for (unsigned int i = 0; i < vertexCount; ++i) + { + vertices->position -= center; + vertices++; + } + + // l'AABB ne change pas de dimensions mais seulement de position, appliquons-lui le même procédé + Boxf aabb = staticMesh->GetAABB(); + aabb.Translate(-center); + + staticMesh->SetAABB(aabb); + } + + // Il ne faut pas oublier d'invalider notre AABB + m_impl->aabbUpdated = false; + } + + void Mesh::RemoveSubMesh(const String& identifier) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return; + } + + auto it = m_impl->subMeshMap.find(identifier); + if (it == m_impl->subMeshMap.end()) + { + NazaraError("SubMesh not found"); + return; + } + + unsigned int index = it->second; + #else + unsigned int index = m_impl->subMeshMap[identifier]; + #endif + + // On déplace l'itérateur du début d'une distance de x + auto it2 = m_impl->subMeshes.begin(); + std::advance(it2, index); + m_impl->subMeshes.erase(it2); + + m_impl->aabbUpdated = false; // On invalide l'AABB + } + + void Mesh::RemoveSubMesh(unsigned int index) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return; + } + + if (index >= m_impl->subMeshes.size()) + { + NazaraError("SubMesh index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->subMeshes.size()) + ')'); + return; + } + #endif + + // On déplace l'itérateur du début de x + auto it = m_impl->subMeshes.begin(); + std::advance(it, index); + m_impl->subMeshes.erase(it); + + m_impl->aabbUpdated = false; // On invalide l'AABB + } + + void Mesh::SetAnimation(const String& animationPath) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return; + } + #endif + + m_impl->animationPath = animationPath; + } + + void Mesh::SetMaterial(unsigned int matIndex, const String& materialPath) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return; + } + + if (matIndex >= m_impl->materials.size()) + { + NazaraError("Material index out of range (" + String::Number(matIndex) + " >= " + String::Number(m_impl->materials.size()) + ')'); + return; + } + #endif + + m_impl->materials[matIndex] = materialPath; + } + + void Mesh::SetMaterialCount(unsigned int matCount) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return; + } + + if (matCount == 0) + { + NazaraError("A mesh should have at least a material"); + return; + } + #endif + + m_impl->materials.resize(matCount); + + #ifdef NAZARA_DEBUG + for (SubMesh* subMesh : m_impl->subMeshes) + { + unsigned int matIndex = subMesh->GetMaterialIndex(); + if (matIndex >= matCount) + { + subMesh->SetMaterialIndex(0); // Pour empêcher un crash + NazaraWarning("SubMesh " + String::Pointer(subMesh) + " material index is over mesh new material count (" + String::Number(matIndex) + " >= " + String::Number(matCount) + "), setting it to first material"); + } + } + #endif + } + + void Mesh::Transform(const Matrix4f& matrix) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Mesh not created"); + return; + } + + if (m_impl->animationType != AnimationType_Static) + { + NazaraError("Mesh must be static"); + return; + } + #endif + + if (matrix.IsIdentity()) + return; + + for (SubMesh* subMesh : m_impl->subMeshes) + { + StaticMesh* staticMesh = static_cast(subMesh); + + BufferMapper mapper(staticMesh->GetVertexBuffer(), BufferAccess_ReadWrite); + MeshVertex* vertices = static_cast(mapper.GetPointer()); + + Boxf aabb(vertices->position.x, vertices->position.y, vertices->position.z, 0.f, 0.f, 0.f); + + unsigned int vertexCount = staticMesh->GetVertexCount(); + for (unsigned int i = 0; i < vertexCount; ++i) + { + vertices->position = matrix.Transform(vertices->position); + aabb.ExtendTo(vertices->position); + + vertices++; + } + + staticMesh->SetAABB(aabb); + } + + // Il ne faut pas oublier d'invalider notre AABB + m_impl->aabbUpdated = false; + } + + bool Mesh::Initialize() + { + if (!MeshLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } + + if (!MeshManager::Initialize()) + { + NazaraError("Failed to initialise manager"); + return false; + } + + return true; + } + + void Mesh::Uninitialize() + { + MeshManager::Uninitialize(); + MeshLibrary::Uninitialize(); + } + + MeshLibrary::LibraryMap Mesh::s_library; + MeshLoader::LoaderList Mesh::s_loaders; + MeshManager::ManagerMap Mesh::s_managerMap; + MeshManager::ManagerParams Mesh::s_managerParameters; } - -void NzMesh::Uninitialize() -{ - NzMeshManager::Uninitialize(); - NzMeshLibrary::Uninitialize(); -} - -NzMeshLibrary::LibraryMap NzMesh::s_library; -NzMeshLoader::LoaderList NzMesh::s_loaders; -NzMeshManager::ManagerMap NzMesh::s_managerMap; -NzMeshManager::ManagerParams NzMesh::s_managerParameters; - diff --git a/src/Nazara/Utility/Mouse.cpp b/src/Nazara/Utility/Mouse.cpp index cb720b022..24cec91f7 100644 --- a/src/Nazara/Utility/Mouse.cpp +++ b/src/Nazara/Utility/Mouse.cpp @@ -15,43 +15,46 @@ #include -NzVector2i NzMouse::GetPosition() +namespace Nz { - return NzEventImpl::GetMousePosition(); -} - -NzVector2i NzMouse::GetPosition(const NzWindow& relativeTo) -{ - return NzEventImpl::GetMousePosition(relativeTo); -} - -bool NzMouse::IsButtonPressed(Button button) -{ - return NzEventImpl::IsMouseButtonPressed(button); -} - -void NzMouse::SetPosition(const NzVector2i& position) -{ - NzEventImpl::SetMousePosition(position.x, position.y); -} - -void NzMouse::SetPosition(const NzVector2i& position, const NzWindow& relativeTo, bool ignoreEvent) -{ - if (ignoreEvent && position.x > 0 && position.y > 0) - relativeTo.IgnoreNextMouseEvent(position.x, position.y); - - NzEventImpl::SetMousePosition(position.x, position.y, relativeTo); -} - -void NzMouse::SetPosition(int x, int y) -{ - NzEventImpl::SetMousePosition(x, y); -} - -void NzMouse::SetPosition(int x, int y, const NzWindow& relativeTo, bool ignoreEvent) -{ - if (ignoreEvent && x > 0 && y > 0) - relativeTo.IgnoreNextMouseEvent(x, y); - - NzEventImpl::SetMousePosition(x, y, relativeTo); + Vector2i Mouse::GetPosition() + { + return EventImpl::GetMousePosition(); + } + + Vector2i Mouse::GetPosition(const Window& relativeTo) + { + return EventImpl::GetMousePosition(relativeTo); + } + + bool Mouse::IsButtonPressed(Button button) + { + return EventImpl::IsMouseButtonPressed(button); + } + + void Mouse::SetPosition(const Vector2i& position) + { + EventImpl::SetMousePosition(position.x, position.y); + } + + void Mouse::SetPosition(const Vector2i& position, const Window& relativeTo, bool ignoreEvent) + { + if (ignoreEvent && position.x > 0 && position.y > 0) + relativeTo.IgnoreNextMouseEvent(position.x, position.y); + + EventImpl::SetMousePosition(position.x, position.y, relativeTo); + } + + void Mouse::SetPosition(int x, int y) + { + EventImpl::SetMousePosition(x, y); + } + + void Mouse::SetPosition(int x, int y, const Window& relativeTo, bool ignoreEvent) + { + if (ignoreEvent && x > 0 && y > 0) + relativeTo.IgnoreNextMouseEvent(x, y); + + EventImpl::SetMousePosition(x, y, relativeTo); + } } diff --git a/src/Nazara/Utility/Node.cpp b/src/Nazara/Utility/Node.cpp index d80a3343a..8bb73512a 100644 --- a/src/Nazara/Utility/Node.cpp +++ b/src/Nazara/Utility/Node.cpp @@ -5,712 +5,715 @@ #include #include -NzNode::NzNode() : -m_initialRotation(NzQuaternionf::Identity()), -m_rotation(NzQuaternionf::Identity()), -m_initialPosition(NzVector3f::Zero()), -m_initialScale(NzVector3f(1.f, 1.f, 1.f)), -m_position(NzVector3f::Zero()), -m_scale(NzVector3f(1.f, 1.f, 1.f)), -m_parent(nullptr), -m_derivedUpdated(false), -m_inheritPosition(true), -m_inheritRotation(true), -m_inheritScale(true), -m_transformMatrixUpdated(false) +namespace Nz { -} - -NzNode::NzNode(const NzNode& node) : -m_initialRotation(node.m_initialRotation), -m_rotation(node.m_rotation), -m_initialPosition(node.m_initialPosition), -m_initialScale(node.m_initialScale), -m_position(node.m_position), -m_scale(node.m_scale), -m_parent(nullptr), -m_derivedUpdated(false), -m_inheritPosition(node.m_inheritPosition), -m_inheritRotation(node.m_inheritRotation), -m_inheritScale(node.m_inheritScale), -m_transformMatrixUpdated(false) -{ - SetParent(node.m_parent, false); -} - -NzNode::~NzNode() -{ - OnNodeRelease(this); - - for (NzNode* child : m_childs) + Node::Node() : + m_initialRotation(Quaternionf::Identity()), + m_rotation(Quaternionf::Identity()), + m_initialPosition(Vector3f::Zero()), + m_initialScale(Vector3f(1.f, 1.f, 1.f)), + m_position(Vector3f::Zero()), + m_scale(Vector3f(1.f, 1.f, 1.f)), + m_parent(nullptr), + m_derivedUpdated(false), + m_inheritPosition(true), + m_inheritRotation(true), + m_inheritScale(true), + m_transformMatrixUpdated(false) { - // child->SetParent(nullptr); serait problématique car elle nous appellerait - child->m_parent = nullptr; - child->InvalidateNode(); - child->OnParenting(nullptr); } - SetParent(nullptr); -} - -void NzNode::EnsureDerivedUpdate() const -{ - if (!m_derivedUpdated) - UpdateDerived(); -} - -void NzNode::EnsureTransformMatrixUpdate() const -{ - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); -} - -NzVector3f NzNode::GetBackward() const -{ - if (!m_derivedUpdated) - UpdateDerived(); - - return m_derivedRotation * NzVector3f::Backward(); -} - -const std::vector& NzNode::GetChilds() const -{ - return m_childs; -} - -NzVector3f NzNode::GetDown() const -{ - if (!m_derivedUpdated) - UpdateDerived(); - - return m_derivedRotation * NzVector3f::Down(); -} - -NzVector3f NzNode::GetForward() const -{ - if (!m_derivedUpdated) - UpdateDerived(); - - return m_derivedRotation * NzVector3f::Forward(); -} - -bool NzNode::GetInheritPosition() const -{ - return m_inheritPosition; -} - -bool NzNode::GetInheritRotation() const -{ - return m_inheritRotation; -} - -bool NzNode::GetInheritScale() const -{ - return m_inheritScale; -} - -NzVector3f NzNode::GetInitialPosition() const -{ - return m_initialPosition; -} - -NzQuaternionf NzNode::GetInitialRotation() const -{ - return m_initialRotation; -} - -NzVector3f NzNode::GetInitialScale() const -{ - return m_initialScale; -} - -NzVector3f NzNode::GetLeft() const -{ - if (!m_derivedUpdated) - UpdateDerived(); - - return m_derivedRotation * NzVector3f::Left(); -} - -nzNodeType NzNode::GetNodeType() const -{ - return nzNodeType_Default; -} - -const NzNode* NzNode::GetParent() const -{ - return m_parent; -} - -NzVector3f NzNode::GetPosition(nzCoordSys coordSys) const -{ - switch (coordSys) + Node::Node(const Node& node) : + m_initialRotation(node.m_initialRotation), + m_rotation(node.m_rotation), + m_initialPosition(node.m_initialPosition), + m_initialScale(node.m_initialScale), + m_position(node.m_position), + m_scale(node.m_scale), + m_parent(nullptr), + m_derivedUpdated(false), + m_inheritPosition(node.m_inheritPosition), + m_inheritRotation(node.m_inheritRotation), + m_inheritScale(node.m_inheritScale), + m_transformMatrixUpdated(false) { - case nzCoordSys_Global: - if (!m_derivedUpdated) - UpdateDerived(); - - return m_derivedPosition; - - case nzCoordSys_Local: - return m_position; + SetParent(node.m_parent, false); } - NazaraError("Coordinate system out of enum (0x" + NzString::Number(coordSys, 16) + ')'); - return NzVector3f(); -} - -NzVector3f NzNode::GetRight() const -{ - if (!m_derivedUpdated) - UpdateDerived(); - - return m_derivedRotation * NzVector3f::Right(); -} - -NzQuaternionf NzNode::GetRotation(nzCoordSys coordSys) const -{ - switch (coordSys) + Node::~Node() { - case nzCoordSys_Global: - if (!m_derivedUpdated) - UpdateDerived(); + OnNodeRelease(this); - return m_derivedRotation; - - case nzCoordSys_Local: - return m_rotation; - } - - NazaraError("Coordinate system out of enum (0x" + NzString::Number(coordSys, 16) + ')'); - return NzQuaternionf(); -} - -NzVector3f NzNode::GetScale(nzCoordSys coordSys) const -{ - switch (coordSys) - { - case nzCoordSys_Global: - if (!m_derivedUpdated) - UpdateDerived(); - - return m_derivedScale; - - case nzCoordSys_Local: - return m_scale; - } - - NazaraError("Coordinate system out of enum (0x" + NzString::Number(coordSys, 16) + ')'); - return NzVector3f(); -} - -const NzMatrix4f& NzNode::GetTransformMatrix() const -{ - if (!m_transformMatrixUpdated) - UpdateTransformMatrix(); - - return m_transformMatrix; -} - -NzVector3f NzNode::GetUp() const -{ - if (!m_derivedUpdated) - UpdateDerived(); - - return m_derivedRotation * NzVector3f::Up(); -} - -bool NzNode::HasChilds() const -{ - return !m_childs.empty(); -} - -NzNode& NzNode::Interpolate(const NzNode& nodeA, const NzNode& nodeB, float interpolation, nzCoordSys coordSys) -{ - switch (coordSys) - { - case nzCoordSys_Global: - if (!nodeA.m_derivedUpdated) - nodeA.UpdateDerived(); - - if (!nodeB.m_derivedUpdated) - nodeB.UpdateDerived(); - - m_position = ToLocalPosition(NzVector3f::Lerp(nodeA.m_derivedPosition, nodeB.m_derivedPosition, interpolation)); - m_rotation = ToLocalRotation(NzQuaternionf::Slerp(nodeA.m_derivedRotation, nodeB.m_derivedRotation, interpolation)); - m_scale = ToLocalScale(NzVector3f::Lerp(nodeA.m_derivedScale, nodeB.m_derivedScale, interpolation)); - break; - - case nzCoordSys_Local: - m_position = NzVector3f::Lerp(nodeA.m_position, nodeB.m_position, interpolation); - m_rotation = NzQuaternionf::Slerp(nodeA.m_rotation, nodeB.m_rotation, interpolation); - m_scale = NzVector3f::Lerp(nodeA.m_scale, nodeB.m_scale, interpolation); - break; - } - - InvalidateNode(); - return *this; -} - -NzNode& NzNode::Move(const NzVector3f& movement, nzCoordSys coordSys) -{ - switch (coordSys) - { - case nzCoordSys_Global: + for (Node* child : m_childs) { - if (m_parent) - { - if (!m_parent->m_derivedUpdated) - m_parent->UpdateDerived(); - - m_position += (m_parent->m_derivedRotation.GetConjugate()*(movement - m_parent->m_derivedPosition))/m_parent->m_derivedScale; // Compensation - } - else - m_position += movement; // Rien n'affecte le node - - break; + // child->SetParent(nullptr); serait problématique car elle nous appellerait + child->m_parent = nullptr; + child->InvalidateNode(); + child->OnParenting(nullptr); } - case nzCoordSys_Local: - m_position += m_rotation * movement; - break; + SetParent(nullptr); } - InvalidateNode(); - return *this; -} - -NzNode& NzNode::Move(float moveX, float moveY, float moveZ, nzCoordSys coordSys) -{ - return Move(NzVector3f(moveX, moveY, moveZ), coordSys); -} - -NzNode& NzNode::Rotate(const NzQuaternionf& rotation, nzCoordSys coordSys) -{ - // Évitons toute mauvaise surprise .. - NzQuaternionf q(rotation); - q.Normalize(); - - switch (coordSys) + void Node::EnsureDerivedUpdate() const { - case nzCoordSys_Global: - { - if (!m_derivedUpdated) - UpdateDerived(); - - m_rotation *= m_derivedRotation.GetInverse() * q * m_derivedRotation; ///FIXME: Correct ? - break; - } - - case nzCoordSys_Local: - m_rotation *= q; - break; + if (!m_derivedUpdated) + UpdateDerived(); } - m_rotation.Normalize(); - - InvalidateNode(); - return *this; -} - -NzNode& NzNode::Scale(const NzVector3f& scale) -{ - m_scale *= scale; - - InvalidateNode(); - return *this; -} - -NzNode& NzNode::Scale(float scale) -{ - m_scale *= scale; - - InvalidateNode(); - return *this; -} - -NzNode& NzNode::Scale(float scaleX, float scaleY, float scaleZ) -{ - m_scale.x *= scaleX; - m_scale.y *= scaleY; - m_scale.z *= scaleZ; - - InvalidateNode(); - return *this; -} - -void NzNode::SetInheritPosition(bool inheritPosition) -{ - ///DOC: Un appel redondant est sans effet - if (m_inheritPosition != inheritPosition) + void Node::EnsureTransformMatrixUpdate() const { - m_inheritPosition = inheritPosition; - - InvalidateNode(); + if (!m_transformMatrixUpdated) + UpdateTransformMatrix(); } -} -void NzNode::SetInheritRotation(bool inheritRotation) -{ - ///DOC: Un appel redondant est sans effet - if (m_inheritRotation != inheritRotation) - { - m_inheritRotation = inheritRotation; - - InvalidateNode(); - } -} - -void NzNode::SetInheritScale(bool inheritScale) -{ - ///DOC: Un appel redondant est sans effet - if (m_inheritScale != inheritScale) - { - m_inheritScale = inheritScale; - - InvalidateNode(); - } -} - -void NzNode::SetInitialPosition(const NzVector3f& position) -{ - m_initialPosition = position; - - InvalidateNode(); -} - -void NzNode::SetInitialPosition(float positionX, float positionY, float positionZ) -{ - m_initialPosition.Set(positionX, positionY, positionZ); - - InvalidateNode(); -} - -void NzNode::SetInitialRotation(const NzQuaternionf& rotation) -{ - m_initialRotation = rotation; - m_initialRotation.Normalize(); // Évitons toute mauvaise surprise ... - - InvalidateNode(); -} - -void NzNode::SetInitialScale(const NzVector3f& scale) -{ - m_initialScale = scale; - - InvalidateNode(); -} - -void NzNode::SetInitialScale(float scale) -{ - m_initialScale.Set(scale); - - InvalidateNode(); -} - -void NzNode::SetInitialScale(float scaleX, float scaleY, float scaleZ) -{ - m_initialScale.Set(scaleX, scaleY, scaleZ); - - InvalidateNode(); -} - -void NzNode::SetParent(const NzNode* node, bool keepDerived) -{ - #if NAZARA_UTILITY_SAFE - // On vérifie que le node n'est pas son propre parent - const NzNode* parentNode = node; - while (parentNode) - { - if (parentNode == this) - { - NazaraError("A node cannot be it's own parent"); - return; - } - - parentNode = parentNode->GetParent(); - } - #endif - - if (m_parent == node) - return; - - if (keepDerived) + Vector3f Node::GetBackward() const { if (!m_derivedUpdated) UpdateDerived(); - if (m_parent) - m_parent->RemoveChild(this); - - m_parent = node; - if (m_parent) - m_parent->AddChild(this); - - SetRotation(m_derivedRotation, nzCoordSys_Global); - SetScale(m_derivedScale, nzCoordSys_Global); - SetPosition(m_derivedPosition, nzCoordSys_Global); + return m_derivedRotation * Vector3f::Backward(); } - else - { - if (m_parent) - m_parent->RemoveChild(this); - m_parent = node; - if (m_parent) - m_parent->AddChild(this); + const std::vector& Node::GetChilds() const + { + return m_childs; + } + + Vector3f Node::GetDown() const + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedRotation * Vector3f::Down(); + } + + Vector3f Node::GetForward() const + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedRotation * Vector3f::Forward(); + } + + bool Node::GetInheritPosition() const + { + return m_inheritPosition; + } + + bool Node::GetInheritRotation() const + { + return m_inheritRotation; + } + + bool Node::GetInheritScale() const + { + return m_inheritScale; + } + + Vector3f Node::GetInitialPosition() const + { + return m_initialPosition; + } + + Quaternionf Node::GetInitialRotation() const + { + return m_initialRotation; + } + + Vector3f Node::GetInitialScale() const + { + return m_initialScale; + } + + Vector3f Node::GetLeft() const + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedRotation * Vector3f::Left(); + } + + nzNodeType Node::GetNodeType() const + { + return nzNodeType_Default; + } + + const Node* Node::GetParent() const + { + return m_parent; + } + + Vector3f Node::GetPosition(CoordSys coordSys) const + { + switch (coordSys) + { + case CoordSys_Global: + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedPosition; + + case CoordSys_Local: + return m_position; + } + + NazaraError("Coordinate system out of enum (0x" + String::Number(coordSys, 16) + ')'); + return Vector3f(); + } + + Vector3f Node::GetRight() const + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedRotation * Vector3f::Right(); + } + + Quaternionf Node::GetRotation(CoordSys coordSys) const + { + switch (coordSys) + { + case CoordSys_Global: + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedRotation; + + case CoordSys_Local: + return m_rotation; + } + + NazaraError("Coordinate system out of enum (0x" + String::Number(coordSys, 16) + ')'); + return Quaternionf(); + } + + Vector3f Node::GetScale(CoordSys coordSys) const + { + switch (coordSys) + { + case CoordSys_Global: + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedScale; + + case CoordSys_Local: + return m_scale; + } + + NazaraError("Coordinate system out of enum (0x" + String::Number(coordSys, 16) + ')'); + return Vector3f(); + } + + const Matrix4f& Node::GetTransformMatrix() const + { + if (!m_transformMatrixUpdated) + UpdateTransformMatrix(); + + return m_transformMatrix; + } + + Vector3f Node::GetUp() const + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedRotation * Vector3f::Up(); + } + + bool Node::HasChilds() const + { + return !m_childs.empty(); + } + + Node& Node::Interpolate(const Node& nodeA, const Node& nodeB, float interpolation, CoordSys coordSys) + { + switch (coordSys) + { + case CoordSys_Global: + if (!nodeA.m_derivedUpdated) + nodeA.UpdateDerived(); + + if (!nodeB.m_derivedUpdated) + nodeB.UpdateDerived(); + + m_position = ToLocalPosition(Vector3f::Lerp(nodeA.m_derivedPosition, nodeB.m_derivedPosition, interpolation)); + m_rotation = ToLocalRotation(Quaternionf::Slerp(nodeA.m_derivedRotation, nodeB.m_derivedRotation, interpolation)); + m_scale = ToLocalScale(Vector3f::Lerp(nodeA.m_derivedScale, nodeB.m_derivedScale, interpolation)); + break; + + case CoordSys_Local: + m_position = Vector3f::Lerp(nodeA.m_position, nodeB.m_position, interpolation); + m_rotation = Quaternionf::Slerp(nodeA.m_rotation, nodeB.m_rotation, interpolation); + m_scale = Vector3f::Lerp(nodeA.m_scale, nodeB.m_scale, interpolation); + break; + } + + InvalidateNode(); + return *this; + } + + Node& Node::Move(const Vector3f& movement, CoordSys coordSys) + { + switch (coordSys) + { + case CoordSys_Global: + { + if (m_parent) + { + if (!m_parent->m_derivedUpdated) + m_parent->UpdateDerived(); + + m_position += (m_parent->m_derivedRotation.GetConjugate()*(movement - m_parent->m_derivedPosition))/m_parent->m_derivedScale; // Compensation + } + else + m_position += movement; // Rien n'affecte le node + + break; + } + + case CoordSys_Local: + m_position += m_rotation * movement; + break; + } + + InvalidateNode(); + return *this; + } + + Node& Node::Move(float moveX, float moveY, float moveZ, CoordSys coordSys) + { + return Move(Vector3f(moveX, moveY, moveZ), coordSys); + } + + Node& Node::Rotate(const Quaternionf& rotation, CoordSys coordSys) + { + // Évitons toute mauvaise surprise .. + Quaternionf q(rotation); + q.Normalize(); + + switch (coordSys) + { + case CoordSys_Global: + { + if (!m_derivedUpdated) + UpdateDerived(); + + m_rotation *= m_derivedRotation.GetInverse() * q * m_derivedRotation; ///FIXME: Correct ? + break; + } + + case CoordSys_Local: + m_rotation *= q; + break; + } + + m_rotation.Normalize(); + + InvalidateNode(); + return *this; + } + + Node& Node::Scale(const Vector3f& scale) + { + m_scale *= scale; + + InvalidateNode(); + return *this; + } + + Node& Node::Scale(float scale) + { + m_scale *= scale; + + InvalidateNode(); + return *this; + } + + Node& Node::Scale(float scaleX, float scaleY, float scaleZ) + { + m_scale.x *= scaleX; + m_scale.y *= scaleY; + m_scale.z *= scaleZ; + + InvalidateNode(); + return *this; + } + + void Node::SetInheritPosition(bool inheritPosition) + { + ///DOC: Un appel redondant est sans effet + if (m_inheritPosition != inheritPosition) + { + m_inheritPosition = inheritPosition; + + InvalidateNode(); + } + } + + void Node::SetInheritRotation(bool inheritRotation) + { + ///DOC: Un appel redondant est sans effet + if (m_inheritRotation != inheritRotation) + { + m_inheritRotation = inheritRotation; + + InvalidateNode(); + } + } + + void Node::SetInheritScale(bool inheritScale) + { + ///DOC: Un appel redondant est sans effet + if (m_inheritScale != inheritScale) + { + m_inheritScale = inheritScale; + + InvalidateNode(); + } + } + + void Node::SetInitialPosition(const Vector3f& position) + { + m_initialPosition = position; InvalidateNode(); } - OnParenting(node); -} - -void NzNode::SetParent(const NzNode& node, bool keepDerived) -{ - SetParent(&node, keepDerived); -} - -void NzNode::SetPosition(const NzVector3f& position, nzCoordSys coordSys) -{ - switch (coordSys) + void Node::SetInitialPosition(float positionX, float positionY, float positionZ) { - case nzCoordSys_Global: - if (m_parent && m_inheritPosition) - { - if (!m_parent->m_derivedUpdated) - m_parent->UpdateDerived(); + m_initialPosition.Set(positionX, positionY, positionZ); - m_position = (m_parent->m_derivedRotation.GetConjugate()*(position - m_parent->m_derivedPosition))/m_parent->m_derivedScale - m_initialPosition; - } - else - m_position = position - m_initialPosition; - break; - - case nzCoordSys_Local: - m_position = position; - break; + InvalidateNode(); } - InvalidateNode(); -} - -void NzNode::SetPosition(float positionX, float positionY, float positionZ, nzCoordSys coordSys) -{ - SetPosition(NzVector3f(positionX, positionY, positionZ), coordSys); -} - -void NzNode::SetRotation(const NzQuaternionf& rotation, nzCoordSys coordSys) -{ - // Évitons toute mauvaise surprise .. - NzQuaternionf q(rotation); - q.Normalize(); - - switch (coordSys) + void Node::SetInitialRotation(const Quaternionf& rotation) { - case nzCoordSys_Global: - if (m_parent && m_inheritRotation) - { - NzQuaternionf rot(m_parent->GetRotation() * m_initialRotation); + m_initialRotation = rotation; + m_initialRotation.Normalize(); // Évitons toute mauvaise surprise ... - m_rotation = rot.GetConjugate() * q; - } - else - m_rotation = q; - - break; - - case nzCoordSys_Local: - m_rotation = q; - break; + InvalidateNode(); } - InvalidateNode(); -} - -void NzNode::SetScale(const NzVector3f& scale, nzCoordSys coordSys) -{ - switch (coordSys) + void Node::SetInitialScale(const Vector3f& scale) { - case nzCoordSys_Global: - if (m_parent && m_inheritScale) - m_scale = scale / (m_initialScale * m_parent->GetScale()); - else - m_scale = scale / m_initialScale; - break; + m_initialScale = scale; - case nzCoordSys_Local: - m_scale = scale; - break; + InvalidateNode(); } - InvalidateNode(); -} - -void NzNode::SetScale(float scale, nzCoordSys coordSys) -{ - SetScale(NzVector3f(scale), coordSys); -} - -void NzNode::SetScale(float scaleX, float scaleY, float scaleZ, nzCoordSys coordSys) -{ - SetScale(NzVector3f(scaleX, scaleY, scaleZ), coordSys); -} - -void NzNode::SetTransformMatrix(const NzMatrix4f& matrix) -{ - SetPosition(matrix.GetTranslation(), nzCoordSys_Global); - SetRotation(matrix.GetRotation(), nzCoordSys_Global); - SetScale(matrix.GetScale(), nzCoordSys_Global); - - m_transformMatrix = matrix; - m_transformMatrixUpdated = true; -} - -NzVector3f NzNode::ToGlobalPosition(const NzVector3f& localPosition) const -{ - if (!m_derivedUpdated) - UpdateDerived(); - - return m_derivedPosition + (m_derivedScale * (m_derivedRotation * localPosition)); -} - -NzQuaternionf NzNode::ToGlobalRotation(const NzQuaternionf& localRotation) const -{ - if (!m_derivedUpdated) - UpdateDerived(); - - return m_derivedRotation * localRotation; -} - -NzVector3f NzNode::ToGlobalScale(const NzVector3f& localScale) const -{ - if (!m_derivedUpdated) - UpdateDerived(); - - return m_derivedScale * localScale; -} - -NzVector3f NzNode::ToLocalPosition(const NzVector3f& globalPosition) const -{ - if (!m_derivedUpdated) - UpdateDerived(); - - return (m_derivedRotation.GetConjugate()*(globalPosition - m_derivedPosition))/m_derivedScale; -} - -NzQuaternionf NzNode::ToLocalRotation(const NzQuaternionf& globalRotation) const -{ - if (!m_derivedUpdated) - UpdateDerived(); - - return m_derivedRotation.GetConjugate() * globalRotation; -} - -NzVector3f NzNode::ToLocalScale(const NzVector3f& globalScale) const -{ - if (!m_derivedUpdated) - UpdateDerived(); - - return globalScale / m_derivedScale; -} - -NzNode& NzNode::operator=(const NzNode& node) -{ - SetParent(node.m_parent); - - m_inheritPosition = node.m_inheritPosition; - m_inheritRotation = node.m_inheritRotation; - m_inheritScale = node.m_inheritScale; - m_initialPosition = node.m_initialPosition; - m_initialRotation = node.m_initialRotation; - m_initialScale = node.m_initialScale; - m_position = node.m_position; - m_rotation = node.m_rotation; - m_scale = node.m_scale; - - InvalidateNode(); - - return *this; -} - -void NzNode::AddChild(NzNode* node) const -{ - #ifdef NAZARA_DEBUG - if (std::find(m_childs.begin(), m_childs.end(), node) != m_childs.end()) + void Node::SetInitialScale(float scale) { - NazaraWarning("Child node is already a child of parent node"); - return; + m_initialScale.Set(scale); + + InvalidateNode(); } - #endif - m_childs.push_back(node); -} - -void NzNode::InvalidateNode() -{ - m_derivedUpdated = false; - m_transformMatrixUpdated = false; - - for (NzNode* node : m_childs) - node->InvalidateNode(); - - OnNodeInvalidation(this); -} - -void NzNode::OnParenting(const NzNode* parent) -{ - OnNodeNewParent(this, parent); -} - -void NzNode::RemoveChild(NzNode* node) const -{ - auto it = std::find(m_childs.begin(), m_childs.end(), node); - if (it != m_childs.end()) - m_childs.erase(it); - else - NazaraWarning("Child not found"); -} - -void NzNode::UpdateDerived() const -{ - if (m_parent) + void Node::SetInitialScale(float scaleX, float scaleY, float scaleZ) { - if (!m_parent->m_derivedUpdated) - m_parent->UpdateDerived(); + m_initialScale.Set(scaleX, scaleY, scaleZ); - if (m_inheritPosition) - m_derivedPosition = m_parent->m_derivedRotation*(m_parent->m_derivedScale * (m_initialPosition + m_position)) + m_parent->m_derivedPosition; - else - m_derivedPosition = m_initialPosition + m_position; + InvalidateNode(); + } - if (m_inheritRotation) + void Node::SetParent(const Node* node, bool keepDerived) + { + #if NAZARA_UTILITY_SAFE + // On vérifie que le node n'est pas son propre parent + const Node* parentNode = node; + while (parentNode) { - m_derivedRotation = m_parent->m_derivedRotation * m_initialRotation * m_rotation; - m_derivedRotation.Normalize(); + if (parentNode == this) + { + NazaraError("A node cannot be it's own parent"); + return; + } + + parentNode = parentNode->GetParent(); + } + #endif + + if (m_parent == node) + return; + + if (keepDerived) + { + if (!m_derivedUpdated) + UpdateDerived(); + + if (m_parent) + m_parent->RemoveChild(this); + + m_parent = node; + if (m_parent) + m_parent->AddChild(this); + + SetRotation(m_derivedRotation, CoordSys_Global); + SetScale(m_derivedScale, CoordSys_Global); + SetPosition(m_derivedPosition, CoordSys_Global); } else - m_derivedRotation = m_initialRotation * m_rotation; + { + if (m_parent) + m_parent->RemoveChild(this); - m_derivedScale = m_initialScale * m_scale; - if (m_inheritScale) - m_derivedScale *= m_parent->m_derivedScale; + m_parent = node; + if (m_parent) + m_parent->AddChild(this); + + InvalidateNode(); + } + + OnParenting(node); } - else + + void Node::SetParent(const Node& node, bool keepDerived) { - m_derivedPosition = m_initialPosition + m_position; - m_derivedRotation = m_initialRotation * m_rotation; - m_derivedScale = m_initialScale * m_scale; + SetParent(&node, keepDerived); } - m_derivedUpdated = true; -} + void Node::SetPosition(const Vector3f& position, CoordSys coordSys) + { + switch (coordSys) + { + case CoordSys_Global: + if (m_parent && m_inheritPosition) + { + if (!m_parent->m_derivedUpdated) + m_parent->UpdateDerived(); -void NzNode::UpdateTransformMatrix() const -{ - if (!m_derivedUpdated) - UpdateDerived(); + m_position = (m_parent->m_derivedRotation.GetConjugate()*(position - m_parent->m_derivedPosition))/m_parent->m_derivedScale - m_initialPosition; + } + else + m_position = position - m_initialPosition; + break; - m_transformMatrix.MakeTransform(m_derivedPosition, m_derivedRotation, m_derivedScale); - m_transformMatrixUpdated = true; + case CoordSys_Local: + m_position = position; + break; + } + + InvalidateNode(); + } + + void Node::SetPosition(float positionX, float positionY, float positionZ, CoordSys coordSys) + { + SetPosition(Vector3f(positionX, positionY, positionZ), coordSys); + } + + void Node::SetRotation(const Quaternionf& rotation, CoordSys coordSys) + { + // Évitons toute mauvaise surprise .. + Quaternionf q(rotation); + q.Normalize(); + + switch (coordSys) + { + case CoordSys_Global: + if (m_parent && m_inheritRotation) + { + Quaternionf rot(m_parent->GetRotation() * m_initialRotation); + + m_rotation = rot.GetConjugate() * q; + } + else + m_rotation = q; + + break; + + case CoordSys_Local: + m_rotation = q; + break; + } + + InvalidateNode(); + } + + void Node::SetScale(const Vector3f& scale, CoordSys coordSys) + { + switch (coordSys) + { + case CoordSys_Global: + if (m_parent && m_inheritScale) + m_scale = scale / (m_initialScale * m_parent->GetScale()); + else + m_scale = scale / m_initialScale; + break; + + case CoordSys_Local: + m_scale = scale; + break; + } + + InvalidateNode(); + } + + void Node::SetScale(float scale, CoordSys coordSys) + { + SetScale(Vector3f(scale), coordSys); + } + + void Node::SetScale(float scaleX, float scaleY, float scaleZ, CoordSys coordSys) + { + SetScale(Vector3f(scaleX, scaleY, scaleZ), coordSys); + } + + void Node::SetTransformMatrix(const Matrix4f& matrix) + { + SetPosition(matrix.GetTranslation(), CoordSys_Global); + SetRotation(matrix.GetRotation(), CoordSys_Global); + SetScale(matrix.GetScale(), CoordSys_Global); + + m_transformMatrix = matrix; + m_transformMatrixUpdated = true; + } + + Vector3f Node::ToGlobalPosition(const Vector3f& localPosition) const + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedPosition + (m_derivedScale * (m_derivedRotation * localPosition)); + } + + Quaternionf Node::ToGlobalRotation(const Quaternionf& localRotation) const + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedRotation * localRotation; + } + + Vector3f Node::ToGlobalScale(const Vector3f& localScale) const + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedScale * localScale; + } + + Vector3f Node::ToLocalPosition(const Vector3f& globalPosition) const + { + if (!m_derivedUpdated) + UpdateDerived(); + + return (m_derivedRotation.GetConjugate()*(globalPosition - m_derivedPosition))/m_derivedScale; + } + + Quaternionf Node::ToLocalRotation(const Quaternionf& globalRotation) const + { + if (!m_derivedUpdated) + UpdateDerived(); + + return m_derivedRotation.GetConjugate() * globalRotation; + } + + Vector3f Node::ToLocalScale(const Vector3f& globalScale) const + { + if (!m_derivedUpdated) + UpdateDerived(); + + return globalScale / m_derivedScale; + } + + Node& Node::operator=(const Node& node) + { + SetParent(node.m_parent); + + m_inheritPosition = node.m_inheritPosition; + m_inheritRotation = node.m_inheritRotation; + m_inheritScale = node.m_inheritScale; + m_initialPosition = node.m_initialPosition; + m_initialRotation = node.m_initialRotation; + m_initialScale = node.m_initialScale; + m_position = node.m_position; + m_rotation = node.m_rotation; + m_scale = node.m_scale; + + InvalidateNode(); + + return *this; + } + + void Node::AddChild(Node* node) const + { + #ifdef NAZARA_DEBUG + if (std::find(m_childs.begin(), m_childs.end(), node) != m_childs.end()) + { + NazaraWarning("Child node is already a child of parent node"); + return; + } + #endif + + m_childs.push_back(node); + } + + void Node::InvalidateNode() + { + m_derivedUpdated = false; + m_transformMatrixUpdated = false; + + for (Node* node : m_childs) + node->InvalidateNode(); + + OnNodeInvalidation(this); + } + + void Node::OnParenting(const Node* parent) + { + OnNodeNewParent(this, parent); + } + + void Node::RemoveChild(Node* node) const + { + auto it = std::find(m_childs.begin(), m_childs.end(), node); + if (it != m_childs.end()) + m_childs.erase(it); + else + NazaraWarning("Child not found"); + } + + void Node::UpdateDerived() const + { + if (m_parent) + { + if (!m_parent->m_derivedUpdated) + m_parent->UpdateDerived(); + + if (m_inheritPosition) + m_derivedPosition = m_parent->m_derivedRotation*(m_parent->m_derivedScale * (m_initialPosition + m_position)) + m_parent->m_derivedPosition; + else + m_derivedPosition = m_initialPosition + m_position; + + if (m_inheritRotation) + { + m_derivedRotation = m_parent->m_derivedRotation * m_initialRotation * m_rotation; + m_derivedRotation.Normalize(); + } + else + m_derivedRotation = m_initialRotation * m_rotation; + + m_derivedScale = m_initialScale * m_scale; + if (m_inheritScale) + m_derivedScale *= m_parent->m_derivedScale; + } + else + { + m_derivedPosition = m_initialPosition + m_position; + m_derivedRotation = m_initialRotation * m_rotation; + m_derivedScale = m_initialScale * m_scale; + } + + m_derivedUpdated = true; + } + + void Node::UpdateTransformMatrix() const + { + if (!m_derivedUpdated) + UpdateDerived(); + + m_transformMatrix.MakeTransform(m_derivedPosition, m_derivedRotation, m_derivedScale); + m_transformMatrixUpdated = true; + } } diff --git a/src/Nazara/Utility/PixelFormat.cpp b/src/Nazara/Utility/PixelFormat.cpp index a71e3f700..2b34b3376 100644 --- a/src/Nazara/Utility/PixelFormat.cpp +++ b/src/Nazara/Utility/PixelFormat.cpp @@ -7,1497 +7,1500 @@ #include #include -namespace +namespace Nz { - inline nzUInt8 c4to5(nzUInt8 c) + namespace { - return static_cast(c * (31.f/15.f)); - } + inline UInt8 c4to5(UInt8 c) + { + return static_cast(c * (31.f/15.f)); + } - inline nzUInt8 c4to8(nzUInt8 c) - { - return c << 4; - } + inline UInt8 c4to8(UInt8 c) + { + return c << 4; + } - inline nzUInt8 c5to4(nzUInt8 c) - { - return static_cast(c * (15.f/31.f)); - } + inline UInt8 c5to4(UInt8 c) + { + return static_cast(c * (15.f/31.f)); + } - inline nzUInt8 c5to8(nzUInt8 c) - { - return static_cast(c * (255.f/31.f)); - } + inline UInt8 c5to8(UInt8 c) + { + return static_cast(c * (255.f/31.f)); + } - inline nzUInt8 c8to4(nzUInt8 c) - { - return c >> 4; - } + inline UInt8 c8to4(UInt8 c) + { + return c >> 4; + } - inline nzUInt8 c8to5(nzUInt8 c) - { - return static_cast(c * (31.f/255.f)); - } + inline UInt8 c8to5(UInt8 c) + { + return static_cast(c * (31.f/255.f)); + } - template - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - NazaraUnused(start); - NazaraUnused(dst); - NazaraUnused(end); + template + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) + { + NazaraUnused(start); + NazaraUnused(dst); + NazaraUnused(end); - NazaraInternalError("Conversion from " + NzPixelFormat::ToString(from) + " to " + NzPixelFormat::ToString(to) + " is not supported"); - return nullptr; - } + NazaraInternalError("Conversion from " + NzPixelFormat::ToString(from) + " to " + NzPixelFormat::ToString(to) + " is not supported"); + return nullptr; + } - /**********************************A8***********************************/ - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + /**********************************A8***********************************/ + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = 0xFF; - *dst++ = 0xFF; - *dst++ = 0xFF; - *dst++ = *start; + while (start < end) + { + *dst++ = 0xFF; + *dst++ = 0xFF; + *dst++ = 0xFF; + *dst++ = *start; - start += 1; - } + start += 1; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = 0xFF; - *dst++ = *start; + while (start < end) + { + *dst++ = 0xFF; + *dst++ = *start; - start += 1; - } + start += 1; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *ptr = (static_cast(0x1F) << 11) | - (static_cast(0x1F) << 6) | - (static_cast(0x1F) << 1) | - ((*start > 0xF) ? 1 : 0); // > 128 + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + *ptr = (static_cast(0x1F) << 11) | + (static_cast(0x1F) << 6) | + (static_cast(0x1F) << 1) | + ((*start > 0xF) ? 1 : 0); // > 128 - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - ptr++; - start += 1; - } + ptr++; + start += 1; + } - return reinterpret_cast(ptr); - } + return reinterpret_cast(ptr); + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *ptr = 0xFFF0 | c8to4(*start); + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + *ptr = 0xFFF0 | c8to4(*start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - ptr++; - start += 1; - } + ptr++; + start += 1; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = 0xFF; - *dst++ = 0xFF; - *dst++ = 0xFF; - *dst++ = *start; + while (start < end) + { + *dst++ = 0xFF; + *dst++ = 0xFF; + *dst++ = 0xFF; + *dst++ = *start; - start += 1; - } + start += 1; + } - return dst; - } + return dst; + } - /**********************************BGR8***********************************/ - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + /**********************************BGR8***********************************/ + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[0]; - *dst++ = start[1]; - *dst++ = start[2]; - *dst++ = 0xFF; + while (start < end) + { + *dst++ = start[0]; + *dst++ = start[1]; + *dst++ = start[2]; + *dst++ = 0xFF; - start += 3; - } + start += 3; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = static_cast(start[2] * 0.3f + start[1] * 0.59f + start[0] * 0.11f); + while (start < end) + { + *dst++ = static_cast(start[2] * 0.3f + start[1] * 0.59f + start[0] * 0.11f); - start += 3; - } + start += 3; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = static_cast(start[2] * 0.3f + start[1] * 0.59f + start[0] * 0.11f); - *dst++ = 0xFF; + while (start < end) + { + *dst++ = static_cast(start[2] * 0.3f + start[1] * 0.59f + start[0] * 0.11f); + *dst++ = 0xFF; - start += 3; - } + start += 3; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *ptr = (static_cast(c8to5(start[2])) << 11) | - (static_cast(c8to5(start[1])) << 6) | - (static_cast(c8to5(start[0])) << 1) | - 0x1; + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + *ptr = (static_cast(c8to5(start[2])) << 11) | + (static_cast(c8to5(start[1])) << 6) | + (static_cast(c8to5(start[0])) << 1) | + 0x1; - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - ptr++; - start += 3; - } + ptr++; + start += 3; + } - return reinterpret_cast(ptr); - } + return reinterpret_cast(ptr); + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[2]; - *dst++ = start[1]; - *dst++ = start[0]; + while (start < end) + { + *dst++ = start[2]; + *dst++ = start[1]; + *dst++ = start[0]; - start += 3; - } + start += 3; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *ptr = (static_cast(c8to4(start[2])) << 12) | - (static_cast(c8to4(start[1])) << 8) | - (static_cast(c8to4(start[0])) << 4) | - 0x0F; + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + *ptr = (static_cast(c8to4(start[2])) << 12) | + (static_cast(c8to4(start[1])) << 8) | + (static_cast(c8to4(start[0])) << 4) | + 0x0F; - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - ptr++; - start += 3; - } + ptr++; + start += 3; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[2]; - *dst++ = start[1]; - *dst++ = start[0]; - *dst++ = 0xFF; + while (start < end) + { + *dst++ = start[2]; + *dst++ = start[1]; + *dst++ = start[0]; + *dst++ = 0xFF; - start += 3; - } + start += 3; + } - return dst; - } + return dst; + } - /**********************************BGRA8**********************************/ - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + /**********************************BGRA8**********************************/ + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[3]; + while (start < end) + { + *dst++ = start[3]; - start += 4; - } + start += 4; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[0]; - *dst++ = start[1]; - *dst++ = start[2]; + while (start < end) + { + *dst++ = start[0]; + *dst++ = start[1]; + *dst++ = start[2]; - start += 4; - } + start += 4; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = static_cast(start[2] * 0.3f + start[1] * 0.59f + start[0] * 0.11f); + while (start < end) + { + *dst++ = static_cast(start[2] * 0.3f + start[1] * 0.59f + start[0] * 0.11f); - start += 4; - } + start += 4; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = static_cast(start[2] * 0.3f + start[1] * 0.59f + start[0] * 0.11f); - *dst++ = start[3]; + while (start < end) + { + *dst++ = static_cast(start[2] * 0.3f + start[1] * 0.59f + start[0] * 0.11f); + *dst++ = start[3]; - start += 4; - } + start += 4; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *ptr = (static_cast(c8to4(start[2])) << 12) | - (static_cast(c8to4(start[1])) << 8) | - (static_cast(c8to4(start[0])) << 4) | - (static_cast(c8to4(start[3])) << 0); + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + *ptr = (static_cast(c8to4(start[2])) << 12) | + (static_cast(c8to4(start[1])) << 8) | + (static_cast(c8to4(start[0])) << 4) | + (static_cast(c8to4(start[3])) << 0); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - ptr++; - start += 4; - } + ptr++; + start += 4; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *ptr = (static_cast(c8to5(start[2])) << 11) | - (static_cast(c8to5(start[1])) << 6) | - (static_cast(c8to5(start[0])) << 1) | - ((start[3] > 0xF) ? 1 : 0); // > 128 + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + *ptr = (static_cast(c8to5(start[2])) << 11) | + (static_cast(c8to5(start[1])) << 6) | + (static_cast(c8to5(start[0])) << 1) | + ((start[3] > 0xF) ? 1 : 0); // > 128 - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - ptr++; - start += 4; - } + ptr++; + start += 4; + } - return reinterpret_cast(ptr); - } + return reinterpret_cast(ptr); + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[2]; - *dst++ = start[1]; - *dst++ = start[0]; + while (start < end) + { + *dst++ = start[2]; + *dst++ = start[1]; + *dst++ = start[0]; - start += 4; - } + start += 4; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[2]; - *dst++ = start[1]; - *dst++ = start[0]; - *dst++ = start[3]; + while (start < end) + { + *dst++ = start[2]; + *dst++ = start[1]; + *dst++ = start[0]; + *dst++ = start[3]; - start += 4; - } + start += 4; + } - return dst; - } + return dst; + } - /***********************************L8************************************/ - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + /***********************************L8************************************/ + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[0]; - *dst++ = start[0]; - *dst++ = start[0]; + while (start < end) + { + *dst++ = start[0]; + *dst++ = start[0]; + *dst++ = start[0]; - start += 1; - } + start += 1; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[0]; - *dst++ = start[0]; - *dst++ = start[0]; - *dst++ = 0xFF; + while (start < end) + { + *dst++ = start[0]; + *dst++ = start[0]; + *dst++ = start[0]; + *dst++ = 0xFF; - start += 1; - } + start += 1; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[0]; - *dst++ = 0xFF; + while (start < end) + { + *dst++ = start[0]; + *dst++ = 0xFF; - start += 1; - } + start += 1; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 l = static_cast(c8to5(start[0])); + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + UInt16 l = static_cast(c8to5(start[0])); - *ptr = (l << 11) | - (l << 6) | - (l << 1) | - 1; + *ptr = (l << 11) | + (l << 6) | + (l << 1) | + 1; - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - ptr++; - start += 1; - } + ptr++; + start += 1; + } - return reinterpret_cast(ptr); - } + return reinterpret_cast(ptr); + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[0]; - *dst++ = start[0]; - *dst++ = start[0]; + while (start < end) + { + *dst++ = start[0]; + *dst++ = start[0]; + *dst++ = start[0]; - start += 1; - } + start += 1; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 l = static_cast(c8to4(start[0])); + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + UInt16 l = static_cast(c8to4(start[0])); - *ptr = (l << 12) | - (l << 8) | - (l << 4) | - 0x0F; + *ptr = (l << 12) | + (l << 8) | + (l << 4) | + 0x0F; - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - ptr++; - start += 1; - } + ptr++; + start += 1; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[0]; - *dst++ = start[0]; - *dst++ = start[0]; - *dst++ = 0xFF; + while (start < end) + { + *dst++ = start[0]; + *dst++ = start[0]; + *dst++ = start[0]; + *dst++ = 0xFF; - start += 1; - } + start += 1; + } - return dst; - } + return dst; + } - /***********************************LA8***********************************/ - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + /***********************************LA8***********************************/ + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[1]; + while (start < end) + { + *dst++ = start[1]; - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[0]; - *dst++ = start[0]; - *dst++ = start[0]; + while (start < end) + { + *dst++ = start[0]; + *dst++ = start[0]; + *dst++ = start[0]; - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[0]; - *dst++ = start[0]; - *dst++ = start[0]; - *dst++ = start[1]; + while (start < end) + { + *dst++ = start[0]; + *dst++ = start[0]; + *dst++ = start[0]; + *dst++ = start[1]; - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[0]; + while (start < end) + { + *dst++ = start[0]; - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 l = static_cast(c8to5(start[0])); + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + UInt16 l = static_cast(c8to5(start[0])); - *ptr = (l << 11) | (l << 6) | (l << 1) | ((start[1] > 0xF) ? 1 : 0); + *ptr = (l << 11) | (l << 6) | (l << 1) | ((start[1] > 0xF) ? 1 : 0); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - ptr++; - start += 2; - } + ptr++; + start += 2; + } - return reinterpret_cast(ptr); - } + return reinterpret_cast(ptr); + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[0]; - *dst++ = start[0]; - *dst++ = start[0]; + while (start < end) + { + *dst++ = start[0]; + *dst++ = start[0]; + *dst++ = start[0]; - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 l = static_cast(c8to4(start[0])); + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + UInt16 l = static_cast(c8to4(start[0])); - *ptr = (l << 12) | (l << 8) | (l << 4) | c8to4(start[1]); + *ptr = (l << 12) | (l << 8) | (l << 4) | c8to4(start[1]); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - ptr++; - start += 2; - } + ptr++; + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[0]; - *dst++ = start[0]; - *dst++ = start[0]; - *dst++ = start[1]; + while (start < end) + { + *dst++ = start[0]; + *dst++ = start[0]; + *dst++ = start[0]; + *dst++ = start[1]; - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - /*********************************RGBA4***********************************/ - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + /*********************************RGBA4***********************************/ + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - *dst++ = c4to8(pixel & 0x000F); + *dst++ = c4to8(pixel & 0x000F); - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - *dst++ = c4to8((pixel & 0x00F0) >> 4); - *dst++ = c4to8((pixel & 0x0F00) >> 8); - *dst++ = c4to8((pixel & 0xF000) >> 12); + *dst++ = c4to8((pixel & 0x00F0) >> 4); + *dst++ = c4to8((pixel & 0x0F00) >> 8); + *dst++ = c4to8((pixel & 0xF000) >> 12); - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - *dst++ = c4to8((pixel & 0x00F0) >> 4); - *dst++ = c4to8((pixel & 0x0F00) >> 8); - *dst++ = c4to8((pixel & 0xF000) >> 12); - *dst++ = c4to8((pixel & 0x000F) >> 0); + *dst++ = c4to8((pixel & 0x00F0) >> 4); + *dst++ = c4to8((pixel & 0x0F00) >> 8); + *dst++ = c4to8((pixel & 0xF000) >> 12); + *dst++ = c4to8((pixel & 0x000F) >> 0); - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - nzUInt16 r = c4to8((pixel & 0xF000) >> 12); - nzUInt16 g = c4to8((pixel & 0x0F00) >> 8); - nzUInt16 b = c4to8((pixel & 0x00F0) >> 4); + UInt16 r = c4to8((pixel & 0xF000) >> 12); + UInt16 g = c4to8((pixel & 0x0F00) >> 8); + UInt16 b = c4to8((pixel & 0x00F0) >> 4); - *dst++ = static_cast(r * 0.3f + g * 0.59f + b * 0.11f); + *dst++ = static_cast(r * 0.3f + g * 0.59f + b * 0.11f); - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - nzUInt16 r = c4to8((pixel & 0xF000) >> 12); - nzUInt16 g = c4to8((pixel & 0x0F00) >> 8); - nzUInt16 b = c4to8((pixel & 0x00F0) >> 4); + UInt16 r = c4to8((pixel & 0xF000) >> 12); + UInt16 g = c4to8((pixel & 0x0F00) >> 8); + UInt16 b = c4to8((pixel & 0x00F0) >> 4); - *dst++ = static_cast(r * 0.3f + g * 0.59f + b * 0.11f); - *dst++ = c4to8(pixel & 0x000F); + *dst++ = static_cast(r * 0.3f + g * 0.59f + b * 0.11f); + *dst++ = c4to8(pixel & 0x000F); - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - nzUInt16 r = c4to5((pixel & 0xF000) >> 12); - nzUInt16 g = c4to5((pixel & 0x0F00) >> 8); - nzUInt16 b = c4to5((pixel & 0x00F0) >> 4); - nzUInt16 a = c4to5((pixel & 0x000F) >> 0); + UInt16 r = c4to5((pixel & 0xF000) >> 12); + UInt16 g = c4to5((pixel & 0x0F00) >> 8); + UInt16 b = c4to5((pixel & 0x00F0) >> 4); + UInt16 a = c4to5((pixel & 0x000F) >> 0); - *ptr = (r << 11) | (g << 6) | (b << 1) | ((a > 0x3) ? 1 : 0); + *ptr = (r << 11) | (g << 6) | (b << 1) | ((a > 0x3) ? 1 : 0); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - ptr++; - start += 2; - } + ptr++; + start += 2; + } - return reinterpret_cast(ptr); - } + return reinterpret_cast(ptr); + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - *dst++ = c4to8((pixel & 0xF000) >> 12); - *dst++ = c4to8((pixel & 0x0F00) >> 8); - *dst++ = c4to8((pixel & 0x00F0) >> 4); + *dst++ = c4to8((pixel & 0xF000) >> 12); + *dst++ = c4to8((pixel & 0x0F00) >> 8); + *dst++ = c4to8((pixel & 0x00F0) >> 4); - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - *dst++ = c4to8((pixel & 0xF000) >> 12); - *dst++ = c4to8((pixel & 0x0F00) >> 8); - *dst++ = c4to8((pixel & 0x00F0) >> 4); - *dst++ = c4to8((pixel & 0x000F) >> 0); + *dst++ = c4to8((pixel & 0xF000) >> 12); + *dst++ = c4to8((pixel & 0x0F00) >> 8); + *dst++ = c4to8((pixel & 0x00F0) >> 4); + *dst++ = c4to8((pixel & 0x000F) >> 0); - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - /*********************************RGB5A1**********************************/ - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + /*********************************RGB5A1**********************************/ + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - *dst++ = static_cast((pixel & 0x1)*0xFF); + *dst++ = static_cast((pixel & 0x1)*0xFF); - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - *dst++ = c5to8((pixel & 0x003E) >> 1); - *dst++ = c5to8((pixel & 0x07C0) >> 6); - *dst++ = c5to8((pixel & 0xF800) >> 11); + *dst++ = c5to8((pixel & 0x003E) >> 1); + *dst++ = c5to8((pixel & 0x07C0) >> 6); + *dst++ = c5to8((pixel & 0xF800) >> 11); - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - *dst++ = c5to8((pixel & 0x003E) >> 1); - *dst++ = c5to8((pixel & 0x07C0) >> 6); - *dst++ = c5to8((pixel & 0xF800) >> 11); - *dst++ = static_cast((pixel & 0x1)*0xFF); + *dst++ = c5to8((pixel & 0x003E) >> 1); + *dst++ = c5to8((pixel & 0x07C0) >> 6); + *dst++ = c5to8((pixel & 0xF800) >> 11); + *dst++ = static_cast((pixel & 0x1)*0xFF); - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - nzUInt8 r = c5to8((pixel & 0xF800) >> 11); - nzUInt8 g = c5to8((pixel & 0x07C0) >> 6); - nzUInt8 b = c5to8((pixel & 0x003E) >> 1); + UInt8 r = c5to8((pixel & 0xF800) >> 11); + UInt8 g = c5to8((pixel & 0x07C0) >> 6); + UInt8 b = c5to8((pixel & 0x003E) >> 1); - *dst++ = static_cast(r * 0.3f + g * 0.59f + b * 0.11f); + *dst++ = static_cast(r * 0.3f + g * 0.59f + b * 0.11f); - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - nzUInt8 r = c5to8((pixel & 0xF800) >> 11); - nzUInt8 g = c5to8((pixel & 0x07C0) >> 6); - nzUInt8 b = c5to8((pixel & 0x003E) >> 1); + UInt8 r = c5to8((pixel & 0xF800) >> 11); + UInt8 g = c5to8((pixel & 0x07C0) >> 6); + UInt8 b = c5to8((pixel & 0x003E) >> 1); - *dst++ = static_cast(r * 0.3f + g * 0.59f + b * 0.11f); - *dst++ = static_cast((pixel & 0x1)*0xFF); + *dst++ = static_cast(r * 0.3f + g * 0.59f + b * 0.11f); + *dst++ = static_cast((pixel & 0x1)*0xFF); - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - *dst++ = c5to8((pixel & 0xF800) >> 11); - *dst++ = c5to8((pixel & 0x07C0) >> 6); - *dst++ = c5to8((pixel & 0x003E) >> 1); + *dst++ = c5to8((pixel & 0xF800) >> 11); + *dst++ = c5to8((pixel & 0x07C0) >> 6); + *dst++ = c5to8((pixel & 0x003E) >> 1); - start += 2; - } + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - nzUInt8 r = c5to4((pixel & 0xF800) >> 11); - nzUInt8 g = c5to4((pixel & 0x07C0) >> 6); - nzUInt8 b = c5to4((pixel & 0x003E) >> 1); + UInt8 r = c5to4((pixel & 0xF800) >> 11); + UInt8 g = c5to4((pixel & 0x07C0) >> 6); + UInt8 b = c5to4((pixel & 0x003E) >> 1); - *ptr = (r << 12) | (g << 8) | (b << 4) | ((pixel & 0x1)*0x0F); + *ptr = (r << 12) | (g << 8) | (b << 4) | ((pixel & 0x1)*0x0F); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - ptr++; - start += 2; - } + ptr++; + start += 2; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - nzUInt16 pixel = *reinterpret_cast(start); + while (start < end) + { + UInt16 pixel = *reinterpret_cast(start); - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(&pixel, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(&pixel, sizeof(UInt16)); + #endif - *dst++ = c5to8((pixel & 0xF800) >> 11); - *dst++ = c5to8((pixel & 0x07C0) >> 6); - *dst++ = c5to8((pixel & 0x003E) >> 1); - *dst++ = static_cast((pixel & 0x1)*0xFF); + *dst++ = c5to8((pixel & 0xF800) >> 11); + *dst++ = c5to8((pixel & 0x07C0) >> 6); + *dst++ = c5to8((pixel & 0x003E) >> 1); + *dst++ = static_cast((pixel & 0x1)*0xFF); - start += 2; - } + start += 2; + } - return dst; - } - - /**********************************RGB8***********************************/ - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) - { - *dst++ = start[2]; - *dst++ = start[1]; - *dst++ = start[0]; - - start += 3; + return dst; } - return dst; - } - - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + /**********************************RGB8***********************************/ + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[2]; - *dst++ = start[1]; - *dst++ = start[0]; - *dst++ = 0xFF; + while (start < end) + { + *dst++ = start[2]; + *dst++ = start[1]; + *dst++ = start[0]; - start += 3; - } + start += 3; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = static_cast(start[0] * 0.3f + start[1] * 0.59f + start[2] * 0.11f); + while (start < end) + { + *dst++ = start[2]; + *dst++ = start[1]; + *dst++ = start[0]; + *dst++ = 0xFF; - start += 3; - } + start += 3; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = static_cast(start[0] * 0.3f + start[1] * 0.59f + start[2] * 0.11f); - *dst++ = 0xFF; + while (start < end) + { + *dst++ = static_cast(start[0] * 0.3f + start[1] * 0.59f + start[2] * 0.11f); - start += 3; - } + start += 3; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *ptr = (static_cast(c8to5(start[0])) << 11) | - (static_cast(c8to5(start[1])) << 6) | - (static_cast(c8to5(start[2])) << 1) | - 0x1; + while (start < end) + { + *dst++ = static_cast(start[0] * 0.3f + start[1] * 0.59f + start[2] * 0.11f); + *dst++ = 0xFF; - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + start += 3; + } - ptr++; - start += 3; + return dst; } - return reinterpret_cast(ptr); - } - - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *ptr = (static_cast(c8to4(start[0])) << 12) | - (static_cast(c8to4(start[1])) << 8) | - (static_cast(c8to4(start[2])) << 4) | - 0x0F; + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + *ptr = (static_cast(c8to5(start[0])) << 11) | + (static_cast(c8to5(start[1])) << 6) | + (static_cast(c8to5(start[2])) << 1) | + 0x1; - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - ptr++; - start += 3; - } + ptr++; + start += 3; + } - return dst; - } + return reinterpret_cast(ptr); + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[0]; - *dst++ = start[1]; - *dst++ = start[2]; - *dst++ = 0xFF; + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + *ptr = (static_cast(c8to4(start[0])) << 12) | + (static_cast(c8to4(start[1])) << 8) | + (static_cast(c8to4(start[2])) << 4) | + 0x0F; - start += 3; - } + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - return dst; - } + ptr++; + start += 3; + } - /**********************************RGBA8**********************************/ - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + return dst; + } + + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[3]; + while (start < end) + { + *dst++ = start[0]; + *dst++ = start[1]; + *dst++ = start[2]; + *dst++ = 0xFF; - start += 4; - } + start += 3; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + /**********************************RGBA8**********************************/ + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[2]; - *dst++ = start[1]; - *dst++ = start[0]; + while (start < end) + { + *dst++ = start[3]; - start += 4; - } + start += 4; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[2]; - *dst++ = start[1]; - *dst++ = start[0]; - *dst++ = start[3]; + while (start < end) + { + *dst++ = start[2]; + *dst++ = start[1]; + *dst++ = start[0]; - start += 4; - } + start += 4; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = static_cast(start[0] * 0.3f + start[1] * 0.59f + start[2] * 0.11f); + while (start < end) + { + *dst++ = start[2]; + *dst++ = start[1]; + *dst++ = start[0]; + *dst++ = start[3]; - start += 4; - } + start += 4; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = static_cast(start[0] * 0.3f + start[1] * 0.59f + start[2] * 0.11f); - *dst++ = start[3]; + while (start < end) + { + *dst++ = static_cast(start[0] * 0.3f + start[1] * 0.59f + start[2] * 0.11f); - start += 4; - } + start += 4; + } - return dst; - } + return dst; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *ptr = (static_cast(c8to5(start[0])) << 11) | - (static_cast(c8to5(start[1])) << 6) | - (static_cast(c8to5(start[2])) << 1) | - ((start[3] > 0xF) ? 1 : 0); // > 128 + while (start < end) + { + *dst++ = static_cast(start[0] * 0.3f + start[1] * 0.59f + start[2] * 0.11f); + *dst++ = start[3]; - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + start += 4; + } - ptr++; - start += 4; + return dst; } - return reinterpret_cast(ptr); - } - - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - while (start < end) + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *dst++ = start[0]; - *dst++ = start[1]; - *dst++ = start[2]; + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + *ptr = (static_cast(c8to5(start[0])) << 11) | + (static_cast(c8to5(start[1])) << 6) | + (static_cast(c8to5(start[2])) << 1) | + ((start[3] > 0xF) ? 1 : 0); // > 128 - start += 4; - } + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif - return dst; - } + ptr++; + start += 4; + } - template<> - nzUInt8* ConvertPixels(const nzUInt8* start, const nzUInt8* end, nzUInt8* dst) - { - nzUInt16* ptr = reinterpret_cast(dst); - while (start < end) + return reinterpret_cast(ptr); + } + + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) { - *ptr = (static_cast(c8to4(start[0])) << 12) | - (static_cast(c8to4(start[1])) << 8) | - (static_cast(c8to4(start[2])) << 4) | - (static_cast(c8to4(start[3])) << 0); + while (start < end) + { + *dst++ = start[0]; + *dst++ = start[1]; + *dst++ = start[2]; - #ifdef NAZARA_BIG_ENDIAN - NzByteSwap(ptr, sizeof(nzUInt16)); - #endif + start += 4; + } - ptr++; - start += 4; + return dst; } - return dst; - } - - template - void RegisterConverter() - { - NzPixelFormat::SetConvertFunction(format1, format2, &ConvertPixels); - } + template<> + UInt8* ConvertPixels(const UInt8* start, const UInt8* end, UInt8* dst) + { + UInt16* ptr = reinterpret_cast(dst); + while (start < end) + { + *ptr = (static_cast(c8to4(start[0])) << 12) | + (static_cast(c8to4(start[1])) << 8) | + (static_cast(c8to4(start[2])) << 4) | + (static_cast(c8to4(start[3])) << 0); + + #ifdef NAZARA_BIG_ENDIAN + SwapBytes(ptr, sizeof(UInt16)); + #endif + + ptr++; + start += 4; + } + + return dst; + } + + template + void RegisterConverter() + { + NzPixelFormat::SetConvertFunction(format1, format2, &ConvertPixels); + } + } + + bool NzPixelFormat::Initialize() + { + // Réinitialisation + std::memset(s_convertFunctions, 0, (PixelFormatType_Max+1)*(PixelFormatType_Max+1)*sizeof(NzPixelFormat::ConvertFunction)); + + /***********************************A8************************************/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + + /**********************************BGR8***********************************/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter();/* + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter();*/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + + /**********************************BGRA8**********************************/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter();/* + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter();*/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + + /**********************************DXT1***********************************/ + ///TODO: Décompresseur DXT1 + /* + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + */ + + /**********************************DXT3***********************************/ + ///TODO: Décompresseur DXT3 + /* + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + */ + + /**********************************DXT5***********************************/ + ///TODO: Décompresseur DXT5 + /* + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + */ + + /***********************************L8************************************/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter();/* + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter();*/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + + /***********************************LA8***********************************/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter();/* + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter();*/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + + /**********************************RGBA4**********************************/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter();/* + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter();*/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + + /*********************************RGB5A1**********************************/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter();/* + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter();*/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + + /**********************************RGB8***********************************/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter();/* + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter();*/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + + /**********************************RGBA8**********************************/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter();/* + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + RegisterConverter();*/ + RegisterConverter(); + RegisterConverter(); + RegisterConverter(); + + return true; + } + + void NzPixelFormat::Uninitialize() + { + std::memset(s_convertFunctions, 0, (PixelFormatType_Max+1)*(PixelFormatType_Max+1)*sizeof(NzPixelFormat::ConvertFunction)); + + for (unsigned int i = 0; i <= PixelFlipping_Max; ++i) + s_flipFunctions[i].clear(); + } + + NzPixelFormat::ConvertFunction NzPixelFormat::s_convertFunctions[PixelFormatType_Max+1][PixelFormatType_Max+1]; + std::map NzPixelFormat::s_flipFunctions[PixelFlipping_Max+1]; } - -bool NzPixelFormat::Initialize() -{ - // Réinitialisation - std::memset(s_convertFunctions, 0, (nzPixelFormat_Max+1)*(nzPixelFormat_Max+1)*sizeof(NzPixelFormat::ConvertFunction)); - - /***********************************A8************************************/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - - /**********************************BGR8***********************************/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter();/* - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter();*/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - - /**********************************BGRA8**********************************/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter();/* - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter();*/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - - /**********************************DXT1***********************************/ - ///TODO: Décompresseur DXT1 -/* - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); -*/ - - /**********************************DXT3***********************************/ - ///TODO: Décompresseur DXT3 -/* - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); -*/ - - /**********************************DXT5***********************************/ - ///TODO: Décompresseur DXT5 -/* - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); -*/ - - /***********************************L8************************************/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter();/* - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter();*/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - - /***********************************LA8***********************************/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter();/* - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter();*/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - - /**********************************RGBA4**********************************/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter();/* - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter();*/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - - /*********************************RGB5A1**********************************/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter();/* - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter();*/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - - /**********************************RGB8***********************************/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter();/* - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter();*/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - - /**********************************RGBA8**********************************/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter();/* - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - RegisterConverter();*/ - RegisterConverter(); - RegisterConverter(); - RegisterConverter(); - - return true; -} - -void NzPixelFormat::Uninitialize() -{ - std::memset(s_convertFunctions, 0, (nzPixelFormat_Max+1)*(nzPixelFormat_Max+1)*sizeof(NzPixelFormat::ConvertFunction)); - - for (unsigned int i = 0; i <= nzPixelFlipping_Max; ++i) - s_flipFunctions[i].clear(); -} - -NzPixelFormat::ConvertFunction NzPixelFormat::s_convertFunctions[nzPixelFormat_Max+1][nzPixelFormat_Max+1]; -std::map NzPixelFormat::s_flipFunctions[nzPixelFlipping_Max+1]; diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index 45cd8a5b5..842f8ed20 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -6,373 +6,376 @@ #include #include -NzSimpleTextDrawer::NzSimpleTextDrawer() : -m_color(NzColor::White), -m_style(nzTextStyle_Regular), -m_glyphUpdated(false) +namespace Nz { - SetFont(NzFont::GetDefault()); -} - -NzSimpleTextDrawer::NzSimpleTextDrawer(const NzSimpleTextDrawer& drawer) : -m_color(drawer.m_color), -m_text(drawer.m_text), -m_style(drawer.m_style), -m_glyphUpdated(false), -m_characterSize(drawer.m_characterSize) -{ - SetFont(drawer.m_font); -} - -NzSimpleTextDrawer::NzSimpleTextDrawer(NzSimpleTextDrawer&& drawer) -{ - operator=(std::move(drawer)); -} - - -NzSimpleTextDrawer::~NzSimpleTextDrawer() = default; - -const NzRectui& NzSimpleTextDrawer::GetBounds() const -{ - if (!m_glyphUpdated) - UpdateGlyphs(); - - return m_bounds; -} - -unsigned int NzSimpleTextDrawer::GetCharacterSize() const -{ - return m_characterSize; -} - -const NzColor& NzSimpleTextDrawer::GetColor() const -{ - return m_color; -} - -NzFont* NzSimpleTextDrawer::GetFont() const -{ - return m_font; -} - -NzFont* NzSimpleTextDrawer::GetFont(unsigned int index) const -{ - #if NAZARA_UTILITY_SAFE - if (index > 0) + SimpleTextDrawer::SimpleTextDrawer() : + m_color(Color::White), + m_style(TextStyle_Regular), + m_glyphUpdated(false) { - NazaraError("Font index out of range (" + NzString::Number(index) + " >= 1)"); - return nullptr; + SetFont(Font::GetDefault()); } - #endif - return m_font; -} - -unsigned int NzSimpleTextDrawer::GetFontCount() const -{ - return 1; -} - -const NzAbstractTextDrawer::Glyph& NzSimpleTextDrawer::GetGlyph(unsigned int index) const -{ - if (!m_glyphUpdated) - UpdateGlyphs(); - - return m_glyphs[index]; -} - -unsigned int NzSimpleTextDrawer::GetGlyphCount() const -{ - if (!m_glyphUpdated) - UpdateGlyphs(); - - return m_glyphs.size(); -} - -nzUInt32 NzSimpleTextDrawer::GetStyle() const -{ - return m_style; -} - -const NzString& NzSimpleTextDrawer::GetText() const -{ - return m_text; -} - -void NzSimpleTextDrawer::SetCharacterSize(unsigned int characterSize) -{ - m_characterSize = characterSize; - - m_glyphUpdated = false; -} - -void NzSimpleTextDrawer::SetColor(const NzColor& color) -{ - m_color = color; - - m_glyphUpdated = false; -} - -void NzSimpleTextDrawer::SetFont(NzFont* font) -{ - if (m_font != font) + SimpleTextDrawer::SimpleTextDrawer(const SimpleTextDrawer& drawer) : + m_color(drawer.m_color), + m_text(drawer.m_text), + m_style(drawer.m_style), + m_glyphUpdated(false), + m_characterSize(drawer.m_characterSize) { - m_font = font; + SetFont(drawer.m_font); + } - if (m_font) - ConnectFontSlots(); - else - DisconnectFontSlots(); + SimpleTextDrawer::SimpleTextDrawer(SimpleTextDrawer&& drawer) + { + operator=(std::move(drawer)); + } + + + SimpleTextDrawer::~SimpleTextDrawer() = default; + + const Rectui& SimpleTextDrawer::GetBounds() const + { + if (!m_glyphUpdated) + UpdateGlyphs(); + + return m_bounds; + } + + unsigned int SimpleTextDrawer::GetCharacterSize() const + { + return m_characterSize; + } + + const Color& SimpleTextDrawer::GetColor() const + { + return m_color; + } + + Font* SimpleTextDrawer::GetFont() const + { + return m_font; + } + + Font* SimpleTextDrawer::GetFont(unsigned int index) const + { + #if NAZARA_UTILITY_SAFE + if (index > 0) + { + NazaraError("Font index out of range (" + String::Number(index) + " >= 1)"); + return nullptr; + } + #endif + + return m_font; + } + + unsigned int SimpleTextDrawer::GetFontCount() const + { + return 1; + } + + const AbstractTextDrawer::Glyph& SimpleTextDrawer::GetGlyph(unsigned int index) const + { + if (!m_glyphUpdated) + UpdateGlyphs(); + + return m_glyphs[index]; + } + + unsigned int SimpleTextDrawer::GetGlyphCount() const + { + if (!m_glyphUpdated) + UpdateGlyphs(); + + return m_glyphs.size(); + } + + UInt32 SimpleTextDrawer::GetStyle() const + { + return m_style; + } + + const String& SimpleTextDrawer::GetText() const + { + return m_text; + } + + void SimpleTextDrawer::SetCharacterSize(unsigned int characterSize) + { + m_characterSize = characterSize; m_glyphUpdated = false; } -} -void NzSimpleTextDrawer::SetStyle(nzUInt32 style) -{ - m_style = style; - - m_glyphUpdated = false; -} - -void NzSimpleTextDrawer::SetText(const NzString& str) -{ - m_text = str; - - m_glyphUpdated = false; -} - -NzSimpleTextDrawer& NzSimpleTextDrawer::operator=(NzSimpleTextDrawer&& drawer) -{ - DisconnectFontSlots(); - - m_bounds = std::move(drawer.m_bounds); - m_characterSize = std::move(drawer.m_characterSize); - m_color = std::move(drawer.m_color); - m_glyphs = std::move(drawer.m_glyphs); - m_glyphUpdated = std::move(drawer.m_glyphUpdated); - m_font = std::move(drawer.m_font); - m_style = std::move(drawer.m_style); - m_text = std::move(drawer.m_text); - - // Update slot pointers (TODO: Improve the way of doing this) - ConnectFontSlots(); - - return *this; -} - -NzSimpleTextDrawer NzSimpleTextDrawer::Draw(const NzString& str, unsigned int characterSize, nzUInt32 style, const NzColor& color) -{ - NzSimpleTextDrawer drawer; - drawer.SetCharacterSize(characterSize); - drawer.SetColor(color); - drawer.SetStyle(style); - drawer.SetText(str); - - return drawer; -} - -NzSimpleTextDrawer NzSimpleTextDrawer::Draw(NzFont* font, const NzString& str, unsigned int characterSize, nzUInt32 style, const NzColor& color) -{ - NzSimpleTextDrawer drawer; - drawer.SetCharacterSize(characterSize); - drawer.SetColor(color); - drawer.SetFont(font); - drawer.SetStyle(style); - drawer.SetText(str); - - return drawer; -} - -void NzSimpleTextDrawer::ConnectFontSlots() -{ - m_atlasChangedSlot.Connect(m_font->OnFontAtlasChanged, this, &NzSimpleTextDrawer::OnFontInvalidated); - m_atlasLayerChangedSlot.Connect(m_font->OnFontAtlasLayerChanged, this, &NzSimpleTextDrawer::OnFontAtlasLayerChanged); - m_fontReleaseSlot.Connect(m_font->OnFontRelease, this, &NzSimpleTextDrawer::OnFontRelease); - m_glyphCacheClearedSlot.Connect(m_font->OnFontGlyphCacheCleared, this, &NzSimpleTextDrawer::OnFontInvalidated); -} - -void NzSimpleTextDrawer::DisconnectFontSlots() -{ - m_atlasChangedSlot.Disconnect(); - m_atlasLayerChangedSlot.Disconnect(); - m_fontReleaseSlot.Disconnect(); - m_glyphCacheClearedSlot.Disconnect(); -} - -void NzSimpleTextDrawer::OnFontAtlasLayerChanged(const NzFont* font, NzAbstractImage* oldLayer, NzAbstractImage* newLayer) -{ - NazaraUnused(font); - - #ifdef NAZARA_DEBUG - if (m_font != font) + void SimpleTextDrawer::SetColor(const Color& color) { - NazaraInternalError("Not listening to " + NzString::Pointer(font)); - return; - } - #endif + m_color = color; - // Update atlas layer pointer - // Note: This can happend while updating - for (Glyph& glyph : m_glyphs) - { - if (glyph.atlas == oldLayer) - glyph.atlas = newLayer; - } -} - -void NzSimpleTextDrawer::OnFontInvalidated(const NzFont* font) -{ - NazaraUnused(font); - - #ifdef NAZARA_DEBUG - if (m_font != font) - { - NazaraInternalError("Not listening to " + NzString::Pointer(font)); - return; - } - #endif - - m_glyphUpdated = false; -} - -void NzSimpleTextDrawer::OnFontRelease(const NzFont* font) -{ - NazaraUnused(font); - NazaraUnused(font); - - #ifdef NAZARA_DEBUG - if (m_font != font) - { - NazaraInternalError("Not listening to " + NzString::Pointer(font)); - return; - } - #endif - - SetFont(nullptr); -} - -void NzSimpleTextDrawer::UpdateGlyphs() const -{ - m_bounds.MakeZero(); - m_glyphs.clear(); - m_glyphUpdated = true; - - #if NAZARA_UTILITY_SAFE - if (!m_font || !m_font->IsValid()) - { - NazaraError("Invalid font"); - return; - } - #endif - - if (m_text.IsEmpty()) - return; - - ///TODO: Itération UTF-8 => UTF-32 sans allocation de buffer (Exposer utf8cpp ?) - std::u32string characters = m_text.GetUtf32String(); - if (characters.empty()) - { - NazaraError("Invalid character set"); - return; + m_glyphUpdated = false; } - const NzFont::SizeInfo& sizeInfo = m_font->GetSizeInfo(m_characterSize); - - // "Curseur" de dessin - NzVector2ui drawPos(0, m_characterSize); - - // On calcule les bornes en flottants pour accélérer les calculs (il est coûteux de changer de type trop souvent) - bool firstGlyph = true; - NzRectf textBounds = NzRectf::Zero(); - nzUInt32 previousCharacter = 0; - - m_glyphs.reserve(characters.size()); - for (char32_t character : characters) + void SimpleTextDrawer::SetFont(Font* font) { - if (previousCharacter != 0) - drawPos.x += m_font->GetKerning(m_characterSize, previousCharacter, character); - - previousCharacter = character; - - bool whitespace = true; - switch (character) + if (m_font != font) { - case ' ': - drawPos.x += sizeInfo.spaceAdvance; - break; + m_font = font; - case '\n': - drawPos.x = 0; - drawPos.y += sizeInfo.lineHeight; - break; + if (m_font) + ConnectFontSlots(); + else + DisconnectFontSlots(); - case '\t': - drawPos.x += sizeInfo.spaceAdvance*4; - break; + m_glyphUpdated = false; + } + } - default: - whitespace = false; - break; + void SimpleTextDrawer::SetStyle(UInt32 style) + { + m_style = style; + + m_glyphUpdated = false; + } + + void SimpleTextDrawer::SetText(const String& str) + { + m_text = str; + + m_glyphUpdated = false; + } + + SimpleTextDrawer& SimpleTextDrawer::operator=(SimpleTextDrawer&& drawer) + { + DisconnectFontSlots(); + + m_bounds = std::move(drawer.m_bounds); + m_characterSize = std::move(drawer.m_characterSize); + m_color = std::move(drawer.m_color); + m_glyphs = std::move(drawer.m_glyphs); + m_glyphUpdated = std::move(drawer.m_glyphUpdated); + m_font = std::move(drawer.m_font); + m_style = std::move(drawer.m_style); + m_text = std::move(drawer.m_text); + + // Update slot pointers (TODO: Improve the way of doing this) + ConnectFontSlots(); + + return *this; + } + + SimpleTextDrawer SimpleTextDrawer::Draw(const String& str, unsigned int characterSize, UInt32 style, const Color& color) + { + SimpleTextDrawer drawer; + drawer.SetCharacterSize(characterSize); + drawer.SetColor(color); + drawer.SetStyle(style); + drawer.SetText(str); + + return drawer; + } + + SimpleTextDrawer SimpleTextDrawer::Draw(Font* font, const String& str, unsigned int characterSize, UInt32 style, const Color& color) + { + SimpleTextDrawer drawer; + drawer.SetCharacterSize(characterSize); + drawer.SetColor(color); + drawer.SetFont(font); + drawer.SetStyle(style); + drawer.SetText(str); + + return drawer; + } + + void SimpleTextDrawer::ConnectFontSlots() + { + m_atlasChangedSlot.Connect(m_font->OnFontAtlasChanged, this, &SimpleTextDrawer::OnFontInvalidated); + m_atlasLayerChangedSlot.Connect(m_font->OnFontAtlasLayerChanged, this, &SimpleTextDrawer::OnFontAtlasLayerChanged); + m_fontReleaseSlot.Connect(m_font->OnFontRelease, this, &SimpleTextDrawer::OnFontRelease); + m_glyphCacheClearedSlot.Connect(m_font->OnFontGlyphCacheCleared, this, &SimpleTextDrawer::OnFontInvalidated); + } + + void SimpleTextDrawer::DisconnectFontSlots() + { + m_atlasChangedSlot.Disconnect(); + m_atlasLayerChangedSlot.Disconnect(); + m_fontReleaseSlot.Disconnect(); + m_glyphCacheClearedSlot.Disconnect(); + } + + void SimpleTextDrawer::OnFontAtlasLayerChanged(const Font* font, AbstractImage* oldLayer, AbstractImage* newLayer) + { + NazaraUnused(font); + + #ifdef NAZARA_DEBUG + if (m_font != font) + { + NazaraInternalError("Not listening to " + String::Pointer(font)); + return; + } + #endif + + // Update atlas layer pointer + // Note: This can happend while updating + for (Glyph& glyph : m_glyphs) + { + if (glyph.atlas == oldLayer) + glyph.atlas = newLayer; + } + } + + void SimpleTextDrawer::OnFontInvalidated(const Font* font) + { + NazaraUnused(font); + + #ifdef NAZARA_DEBUG + if (m_font != font) + { + NazaraInternalError("Not listening to " + String::Pointer(font)); + return; + } + #endif + + m_glyphUpdated = false; + } + + void SimpleTextDrawer::OnFontRelease(const Font* font) + { + NazaraUnused(font); + NazaraUnused(font); + + #ifdef NAZARA_DEBUG + if (m_font != font) + { + NazaraInternalError("Not listening to " + String::Pointer(font)); + return; + } + #endif + + SetFont(nullptr); + } + + void SimpleTextDrawer::UpdateGlyphs() const + { + m_bounds.MakeZero(); + m_glyphs.clear(); + m_glyphUpdated = true; + + #if NAZARA_UTILITY_SAFE + if (!m_font || !m_font->IsValid()) + { + NazaraError("Invalid font"); + return; + } + #endif + + if (m_text.IsEmpty()) + return; + + ///TODO: Itération UTF-8 => UTF-32 sans allocation de buffer (Exposer utf8cpp ?) + std::u32string characters = m_text.GetUtf32String(); + if (characters.empty()) + { + NazaraError("Invalid character set"); + return; } - if (whitespace) - continue; // Inutile d'avoir un glyphe pour un espace blanc + const Font::SizeInfo& sizeInfo = m_font->GetSizeInfo(m_characterSize); - const NzFont::Glyph& fontGlyph = m_font->GetGlyph(m_characterSize, m_style, character); - if (!fontGlyph.valid) - continue; // Le glyphe n'a pas été correctement chargé, que pouvons-nous faire d'autre que le passer + // "Curseur" de dessin + Vector2ui drawPos(0, m_characterSize); - Glyph glyph; - glyph.atlas = m_font->GetAtlas()->GetLayer(fontGlyph.layerIndex); - glyph.atlasRect = fontGlyph.atlasRect; - glyph.color = m_color; - glyph.flipped = fontGlyph.flipped; + // On calcule les bornes en flottants pour accélérer les calculs (il est coûteux de changer de type trop souvent) + bool firstGlyph = true; + Rectf textBounds = Rectf::Zero(); + UInt32 previousCharacter = 0; - int advance = fontGlyph.advance; - - NzRectf bounds(fontGlyph.aabb); - bounds.x += drawPos.x; - bounds.y += drawPos.y; - - if (fontGlyph.requireFauxBold) + m_glyphs.reserve(characters.size()); + for (char32_t character : characters) { - // On va agrandir le glyphe pour simuler le gras (idée moisie, mais idée quand même) - NzVector2f center = bounds.GetCenter(); + if (previousCharacter != 0) + drawPos.x += m_font->GetKerning(m_characterSize, previousCharacter, character); - bounds.width *= 1.1f; - bounds.height *= 1.1f; + previousCharacter = character; - // On le replace à la bonne hauteur - NzVector2f offset(bounds.GetCenter() - center); - bounds.y -= offset.y; + bool whitespace = true; + switch (character) + { + case ' ': + drawPos.x += sizeInfo.spaceAdvance; + break; - // On ajuste l'espacement - advance += advance/10; + case '\n': + drawPos.x = 0; + drawPos.y += sizeInfo.lineHeight; + break; + + case '\t': + drawPos.x += sizeInfo.spaceAdvance*4; + break; + + default: + whitespace = false; + break; + } + + if (whitespace) + continue; // Inutile d'avoir un glyphe pour un espace blanc + + const Font::Glyph& fontGlyph = m_font->GetGlyph(m_characterSize, m_style, character); + if (!fontGlyph.valid) + continue; // Le glyphe n'a pas été correctement chargé, que pouvons-nous faire d'autre que le passer + + Glyph glyph; + glyph.atlas = m_font->GetAtlas()->GetLayer(fontGlyph.layerIndex); + glyph.atlasRect = fontGlyph.atlasRect; + glyph.color = m_color; + glyph.flipped = fontGlyph.flipped; + + int advance = fontGlyph.advance; + + Rectf bounds(fontGlyph.aabb); + bounds.x += drawPos.x; + bounds.y += drawPos.y; + + if (fontGlyph.requireFauxBold) + { + // On va agrandir le glyphe pour simuler le gras (idée moisie, mais idée quand même) + Vector2f center = bounds.GetCenter(); + + bounds.width *= 1.1f; + bounds.height *= 1.1f; + + // On le replace à la bonne hauteur + Vector2f offset(bounds.GetCenter() - center); + bounds.y -= offset.y; + + // On ajuste l'espacement + advance += advance/10; + } + + // On "penche" le glyphe pour obtenir un semblant d'italique + float italic = (fontGlyph.requireFauxItalic) ? 0.208f : 0.f; + float italicTop = italic * bounds.y; + float italicBottom = italic * bounds.GetMaximum().y; + + glyph.corners[0].Set(bounds.x - italicTop, bounds.y); + glyph.corners[1].Set(bounds.x + bounds.width - italicTop, bounds.y); + glyph.corners[2].Set(bounds.x - italicBottom, bounds.y + bounds.height); + glyph.corners[3].Set(bounds.x + bounds.width - italicBottom, bounds.y + bounds.height); + + if (firstGlyph) + { + textBounds.Set(glyph.corners[0]); + firstGlyph = false; + } + + for (unsigned int i = 0; i < 4; ++i) + textBounds.ExtendTo(glyph.corners[i]); + + drawPos.x += advance; + m_glyphs.push_back(glyph); } - // On "penche" le glyphe pour obtenir un semblant d'italique - float italic = (fontGlyph.requireFauxItalic) ? 0.208f : 0.f; - float italicTop = italic * bounds.y; - float italicBottom = italic * bounds.GetMaximum().y; - - glyph.corners[0].Set(bounds.x - italicTop, bounds.y); - glyph.corners[1].Set(bounds.x + bounds.width - italicTop, bounds.y); - glyph.corners[2].Set(bounds.x - italicBottom, bounds.y + bounds.height); - glyph.corners[3].Set(bounds.x + bounds.width - italicBottom, bounds.y + bounds.height); - - if (firstGlyph) - { - textBounds.Set(glyph.corners[0]); - firstGlyph = false; - } - - for (unsigned int i = 0; i < 4; ++i) - textBounds.ExtendTo(glyph.corners[i]); - - drawPos.x += advance; - m_glyphs.push_back(glyph); + m_bounds.Set(Rectf(std::floor(textBounds.x), std::floor(textBounds.y), std::ceil(textBounds.width), std::ceil(textBounds.height))); } - - m_bounds.Set(NzRectf(std::floor(textBounds.x), std::floor(textBounds.y), std::ceil(textBounds.width), std::ceil(textBounds.height))); } diff --git a/src/Nazara/Utility/SkeletalMesh.cpp b/src/Nazara/Utility/SkeletalMesh.cpp index 6660a4c33..0f81ac189 100644 --- a/src/Nazara/Utility/SkeletalMesh.cpp +++ b/src/Nazara/Utility/SkeletalMesh.cpp @@ -9,91 +9,94 @@ #include #include -NzSkeletalMesh::NzSkeletalMesh(const NzMesh* parent) : -NzSubMesh(parent) +namespace Nz { -} - -NzSkeletalMesh::~NzSkeletalMesh() -{ - OnSkeletalMeshRelease(this); - - Destroy(); -} - -bool NzSkeletalMesh::Create(NzVertexBuffer* vertexBuffer) -{ - Destroy(); - - #if NAZARA_UTILITY_SAFE - if (!vertexBuffer) + SkeletalMesh::SkeletalMesh(const Mesh* parent) : + SubMesh(parent) { - NazaraError("Invalid vertex buffer"); - return false; } - #endif - m_vertexBuffer = vertexBuffer; - return true; -} - -void NzSkeletalMesh::Destroy() -{ - if (m_vertexBuffer) + SkeletalMesh::~SkeletalMesh() { - OnSkeletalMeshDestroy(this); + OnSkeletalMeshRelease(this); - m_indexBuffer.Reset(); - m_vertexBuffer.Reset(); + Destroy(); + } + + bool SkeletalMesh::Create(VertexBuffer* vertexBuffer) + { + Destroy(); + + #if NAZARA_UTILITY_SAFE + if (!vertexBuffer) + { + NazaraError("Invalid vertex buffer"); + return false; + } + #endif + + m_vertexBuffer = vertexBuffer; + return true; + } + + void SkeletalMesh::Destroy() + { + if (m_vertexBuffer) + { + OnSkeletalMeshDestroy(this); + + m_indexBuffer.Reset(); + m_vertexBuffer.Reset(); + } + } + + const Boxf& SkeletalMesh::GetAABB() const + { + return m_aabb; + } + + AnimationType SkeletalMesh::GetAnimationType() const + { + return AnimationType_Skeletal; + } + + const IndexBuffer* SkeletalMesh::GetIndexBuffer() const + { + return m_indexBuffer; + } + + VertexBuffer* SkeletalMesh::GetVertexBuffer() + { + return m_vertexBuffer; + } + + const VertexBuffer* SkeletalMesh::GetVertexBuffer() const + { + return m_vertexBuffer; + } + + unsigned int SkeletalMesh::GetVertexCount() const + { + return m_vertexBuffer->GetVertexCount(); + } + + bool SkeletalMesh::IsAnimated() const + { + return true; + } + + bool SkeletalMesh::IsValid() const + { + return m_vertexBuffer != nullptr; + } + + void SkeletalMesh::SetAABB(const Boxf& aabb) + { + m_aabb = aabb; + } + + void SkeletalMesh::SetIndexBuffer(const IndexBuffer* indexBuffer) + { + m_indexBuffer = indexBuffer; } } - -const NzBoxf& NzSkeletalMesh::GetAABB() const -{ - return m_aabb; -} - -nzAnimationType NzSkeletalMesh::GetAnimationType() const -{ - return nzAnimationType_Skeletal; -} - -const NzIndexBuffer* NzSkeletalMesh::GetIndexBuffer() const -{ - return m_indexBuffer; -} - -NzVertexBuffer* NzSkeletalMesh::GetVertexBuffer() -{ - return m_vertexBuffer; -} - -const NzVertexBuffer* NzSkeletalMesh::GetVertexBuffer() const -{ - return m_vertexBuffer; -} - -unsigned int NzSkeletalMesh::GetVertexCount() const -{ - return m_vertexBuffer->GetVertexCount(); -} - -bool NzSkeletalMesh::IsAnimated() const -{ - return true; -} - -bool NzSkeletalMesh::IsValid() const -{ - return m_vertexBuffer != nullptr; -} - -void NzSkeletalMesh::SetAABB(const NzBoxf& aabb) -{ - m_aabb = aabb; -} - -void NzSkeletalMesh::SetIndexBuffer(const NzIndexBuffer* indexBuffer) -{ - m_indexBuffer = indexBuffer; -} diff --git a/src/Nazara/Utility/Skeleton.cpp b/src/Nazara/Utility/Skeleton.cpp index 7a5cea3a2..ad5632b90 100644 --- a/src/Nazara/Utility/Skeleton.cpp +++ b/src/Nazara/Utility/Skeleton.cpp @@ -6,439 +6,442 @@ #include #include -struct NzSkeletonImpl +namespace Nz { - std::unordered_map jointMap; - std::vector joints; - NzBoxf aabb; - bool aabbUpdated = false; - bool jointMapUpdated = false; -}; - -NzSkeleton::NzSkeleton(const NzSkeleton& skeleton) : -NzRefCounted(), -m_impl(nullptr) -{ - operator=(skeleton); -} - -NzSkeleton::~NzSkeleton() -{ - OnSkeletonRelease(this); - - Destroy(); -} - -bool NzSkeleton::Create(unsigned int jointCount) -{ - #if NAZARA_UTILITY_SAFE - if (jointCount == 0) + struct SkeletonImpl { - NazaraError("Joint count must be over zero"); - return false; + std::unordered_map jointMap; + std::vector joints; + Boxf aabb; + bool aabbUpdated = false; + bool jointMapUpdated = false; + }; + + Skeleton::Skeleton(const Skeleton& skeleton) : + RefCounted(), + m_impl(nullptr) + { + operator=(skeleton); } - #endif - m_impl = new NzSkeletonImpl; - m_impl->joints.resize(jointCount, NzJoint(this)); - - return true; -} - -void NzSkeleton::Destroy() -{ - if (m_impl) + Skeleton::~Skeleton() { - OnSkeletonDestroy(this); + OnSkeletonRelease(this); - delete m_impl; - m_impl = nullptr; + Destroy(); } -} -const NzBoxf& NzSkeleton::GetAABB() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) + bool Skeleton::Create(unsigned int jointCount) { - NazaraError("Skeleton not created"); - - static NzBoxf dummy; - return dummy; - } - #endif - - if (!m_impl->aabbUpdated) - { - unsigned int jointCount = m_impl->joints.size(); - if (jointCount > 0) + #if NAZARA_UTILITY_SAFE + if (jointCount == 0) { - NzVector3f pos = m_impl->joints[0].GetPosition(); - m_impl->aabb.Set(pos.x, pos.y, pos.z, 0.f, 0.f, 0.f); - for (unsigned int i = 1; i < jointCount; ++i) - m_impl->aabb.ExtendTo(m_impl->joints[i].GetPosition()); + NazaraError("Joint count must be over zero"); + return false; } - else - m_impl->aabb.MakeZero(); + #endif - m_impl->aabbUpdated = true; + m_impl = new SkeletonImpl; + m_impl->joints.resize(jointCount, Joint(this)); + + return true; } - return m_impl->aabb; -} - -NzJoint* NzSkeleton::GetJoint(const NzString& jointName) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) + void Skeleton::Destroy() { - NazaraError("Skeleton not created"); - return nullptr; - } - #endif + if (m_impl) + { + OnSkeletonDestroy(this); - if (!m_impl->jointMapUpdated) - UpdateJointMap(); - - auto it = m_impl->jointMap.find(jointName); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->jointMap.end()) - { - NazaraError("Joint not found"); - return nullptr; - } - #endif - - InvalidateJoints(); - - return &m_impl->joints[it->second]; -} - -NzJoint* NzSkeleton::GetJoint(unsigned int index) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Skeleton not created"); - return nullptr; + delete m_impl; + m_impl = nullptr; + } } - if (index >= m_impl->joints.size()) + const Boxf& Skeleton::GetAABB() const { - NazaraError("Joint index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->joints.size()) + ')'); - return nullptr; - } - #endif + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Skeleton not created"); - InvalidateJoints(); + static Boxf dummy; + return dummy; + } + #endif - return &m_impl->joints[index]; -} + if (!m_impl->aabbUpdated) + { + unsigned int jointCount = m_impl->joints.size(); + if (jointCount > 0) + { + Vector3f pos = m_impl->joints[0].GetPosition(); + m_impl->aabb.Set(pos.x, pos.y, pos.z, 0.f, 0.f, 0.f); + for (unsigned int i = 1; i < jointCount; ++i) + m_impl->aabb.ExtendTo(m_impl->joints[i].GetPosition()); + } + else + m_impl->aabb.MakeZero(); -const NzJoint* NzSkeleton::GetJoint(const NzString& jointName) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Skeleton not created"); - return nullptr; - } - #endif + m_impl->aabbUpdated = true; + } - if (!m_impl->jointMapUpdated) - UpdateJointMap(); - - auto it = m_impl->jointMap.find(jointName); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->jointMap.end()) - { - NazaraError("Joint not found"); - return nullptr; - } - #endif - - return &m_impl->joints[it->second]; -} - -const NzJoint* NzSkeleton::GetJoint(unsigned int index) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Skeleton not created"); - return nullptr; + return m_impl->aabb; } - if (index >= m_impl->joints.size()) + Joint* Skeleton::GetJoint(const String& jointName) { - NazaraError("Joint index out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->joints.size()) + ')'); - return nullptr; - } - #endif + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Skeleton not created"); + return nullptr; + } + #endif - return &m_impl->joints[index]; -} + if (!m_impl->jointMapUpdated) + UpdateJointMap(); -NzJoint* NzSkeleton::GetJoints() -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Skeleton not created"); - return nullptr; - } - #endif - - return &m_impl->joints[0]; -} - -const NzJoint* NzSkeleton::GetJoints() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Skeleton not created"); - return nullptr; - } - #endif - - return &m_impl->joints[0]; -} - -unsigned int NzSkeleton::GetJointCount() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Skeleton not created"); - return 0; - } - #endif - - return m_impl->joints.size(); -} - -int NzSkeleton::GetJointIndex(const NzString& jointName) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Skeleton not created"); - return -1; - } - #endif - - if (!m_impl->jointMapUpdated) - UpdateJointMap(); - - auto it = m_impl->jointMap.find(jointName); - - #if NAZARA_UTILITY_SAFE - if (it == m_impl->jointMap.end()) - { - NazaraError("Joint not found"); - return -1; - } - #endif - - return it->second; -} - -void NzSkeleton::Interpolate(const NzSkeleton& skeletonA, const NzSkeleton& skeletonB, float interpolation) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Skeleton not created"); - return; - } - - if (!skeletonA.IsValid()) - { - NazaraError("Skeleton A is invalid"); - return; - } - - if (!skeletonB.IsValid()) - { - NazaraError("Skeleton B is invalid"); - return; - } - - if (skeletonA.GetJointCount() != skeletonB.GetJointCount() || m_impl->joints.size() != skeletonA.GetJointCount()) - { - NazaraError("Skeletons must have the same joint count"); - return; - } - #endif - - NzJoint* jointsA = &skeletonA.m_impl->joints[0]; - NzJoint* jointsB = &skeletonB.m_impl->joints[0]; - for (unsigned int i = 0; i < m_impl->joints.size(); ++i) - m_impl->joints[i].Interpolate(jointsA[i], jointsB[i], interpolation, nzCoordSys_Local); - - InvalidateJoints(); -} - -void NzSkeleton::Interpolate(const NzSkeleton& skeletonA, const NzSkeleton& skeletonB, float interpolation, unsigned int* indices, unsigned int indiceCount) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Skeleton not created"); - return; - } - - if (!skeletonA.IsValid()) - { - NazaraError("Skeleton A is invalid"); - return; - } - - if (!skeletonB.IsValid()) - { - NazaraError("Skeleton B is invalid"); - return; - } - - if (skeletonA.GetJointCount() != skeletonB.GetJointCount() || m_impl->joints.size() != skeletonA.GetJointCount()) - { - NazaraError("Skeletons must have the same joint count"); - return; - } - #endif - - const NzJoint* jointsA = &skeletonA.m_impl->joints[0]; - const NzJoint* jointsB = &skeletonB.m_impl->joints[0]; - for (unsigned int i = 0; i < indiceCount; ++i) - { - unsigned int index = indices[i]; + auto it = m_impl->jointMap.find(jointName); #if NAZARA_UTILITY_SAFE + if (it == m_impl->jointMap.end()) + { + NazaraError("Joint not found"); + return nullptr; + } + #endif + + InvalidateJoints(); + + return &m_impl->joints[it->second]; + } + + Joint* Skeleton::GetJoint(unsigned int index) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Skeleton not created"); + return nullptr; + } + if (index >= m_impl->joints.size()) { - NazaraError("Index #" + NzString::Number(i) + " out of range (" + NzString::Number(index) + " >= " + NzString::Number(m_impl->joints.size()) + ')'); + NazaraError("Joint index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->joints.size()) + ')'); + return nullptr; + } + #endif + + InvalidateJoints(); + + return &m_impl->joints[index]; + } + + const Joint* Skeleton::GetJoint(const String& jointName) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Skeleton not created"); + return nullptr; + } + #endif + + if (!m_impl->jointMapUpdated) + UpdateJointMap(); + + auto it = m_impl->jointMap.find(jointName); + + #if NAZARA_UTILITY_SAFE + if (it == m_impl->jointMap.end()) + { + NazaraError("Joint not found"); + return nullptr; + } + #endif + + return &m_impl->joints[it->second]; + } + + const Joint* Skeleton::GetJoint(unsigned int index) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Skeleton not created"); + return nullptr; + } + + if (index >= m_impl->joints.size()) + { + NazaraError("Joint index out of range (" + String::Number(index) + " >= " + String::Number(m_impl->joints.size()) + ')'); + return nullptr; + } + #endif + + return &m_impl->joints[index]; + } + + Joint* Skeleton::GetJoints() + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Skeleton not created"); + return nullptr; + } + #endif + + return &m_impl->joints[0]; + } + + const Joint* Skeleton::GetJoints() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Skeleton not created"); + return nullptr; + } + #endif + + return &m_impl->joints[0]; + } + + unsigned int Skeleton::GetJointCount() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Skeleton not created"); + return 0; + } + #endif + + return m_impl->joints.size(); + } + + int Skeleton::GetJointIndex(const String& jointName) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Skeleton not created"); + return -1; + } + #endif + + if (!m_impl->jointMapUpdated) + UpdateJointMap(); + + auto it = m_impl->jointMap.find(jointName); + + #if NAZARA_UTILITY_SAFE + if (it == m_impl->jointMap.end()) + { + NazaraError("Joint not found"); + return -1; + } + #endif + + return it->second; + } + + void Skeleton::Interpolate(const Skeleton& skeletonA, const Skeleton& skeletonB, float interpolation) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Skeleton not created"); + return; + } + + if (!skeletonA.IsValid()) + { + NazaraError("Skeleton A is invalid"); + return; + } + + if (!skeletonB.IsValid()) + { + NazaraError("Skeleton B is invalid"); + return; + } + + if (skeletonA.GetJointCount() != skeletonB.GetJointCount() || m_impl->joints.size() != skeletonA.GetJointCount()) + { + NazaraError("Skeletons must have the same joint count"); return; } #endif - m_impl->joints[index].Interpolate(jointsA[index], jointsB[index], interpolation, nzCoordSys_Local); + Joint* jointsA = &skeletonA.m_impl->joints[0]; + Joint* jointsB = &skeletonB.m_impl->joints[0]; + for (unsigned int i = 0; i < m_impl->joints.size(); ++i) + m_impl->joints[i].Interpolate(jointsA[i], jointsB[i], interpolation, CoordSys_Local); + + InvalidateJoints(); } - InvalidateJoints(); -} - -bool NzSkeleton::IsValid() const -{ - return m_impl != nullptr; -} - -NzSkeleton& NzSkeleton::operator=(const NzSkeleton& skeleton) -{ - if (this == &skeleton) - return *this; - - Destroy(); - - if (skeleton.m_impl) + void Skeleton::Interpolate(const Skeleton& skeletonA, const Skeleton& skeletonB, float interpolation, unsigned int* indices, unsigned int indiceCount) { - m_impl = new NzSkeletonImpl; - m_impl->jointMap = skeleton.m_impl->jointMap; - m_impl->jointMapUpdated = skeleton.m_impl->jointMapUpdated; - m_impl->joints = skeleton.m_impl->joints; - - // Code crade mais son optimisation demanderait de stocker jointCount*sizeof(unsigned int) en plus - // Ce qui, pour juste une copie qui ne se fera que rarement, ne vaut pas le coup - // L'éternel trade-off mémoire/calculs .. - unsigned int jointCount = skeleton.m_impl->joints.size(); - for (unsigned int i = 0; i < jointCount; ++i) + #if NAZARA_UTILITY_SAFE + if (!m_impl) { - const NzNode* parent = skeleton.m_impl->joints[i].GetParent(); - if (parent) + NazaraError("Skeleton not created"); + return; + } + + if (!skeletonA.IsValid()) + { + NazaraError("Skeleton A is invalid"); + return; + } + + if (!skeletonB.IsValid()) + { + NazaraError("Skeleton B is invalid"); + return; + } + + if (skeletonA.GetJointCount() != skeletonB.GetJointCount() || m_impl->joints.size() != skeletonA.GetJointCount()) + { + NazaraError("Skeletons must have the same joint count"); + return; + } + #endif + + const Joint* jointsA = &skeletonA.m_impl->joints[0]; + const Joint* jointsB = &skeletonB.m_impl->joints[0]; + for (unsigned int i = 0; i < indiceCount; ++i) + { + unsigned int index = indices[i]; + + #if NAZARA_UTILITY_SAFE + if (index >= m_impl->joints.size()) { - for (unsigned int j = 0; j < i; ++j) // Le parent se trouve forcément avant nous + NazaraError("Index #" + String::Number(i) + " out of range (" + String::Number(index) + " >= " + String::Number(m_impl->joints.size()) + ')'); + return; + } + #endif + + m_impl->joints[index].Interpolate(jointsA[index], jointsB[index], interpolation, CoordSys_Local); + } + + InvalidateJoints(); + } + + bool Skeleton::IsValid() const + { + return m_impl != nullptr; + } + + Skeleton& Skeleton::operator=(const Skeleton& skeleton) + { + if (this == &skeleton) + return *this; + + Destroy(); + + if (skeleton.m_impl) + { + m_impl = new SkeletonImpl; + m_impl->jointMap = skeleton.m_impl->jointMap; + m_impl->jointMapUpdated = skeleton.m_impl->jointMapUpdated; + m_impl->joints = skeleton.m_impl->joints; + + // Code crade mais son optimisation demanderait de stocker jointCount*sizeof(unsigned int) en plus + // Ce qui, pour juste une copie qui ne se fera que rarement, ne vaut pas le coup + // L'éternel trade-off mémoire/calculs .. + unsigned int jointCount = skeleton.m_impl->joints.size(); + for (unsigned int i = 0; i < jointCount; ++i) + { + const Node* parent = skeleton.m_impl->joints[i].GetParent(); + if (parent) { - if (parent == &skeleton.m_impl->joints[j]) // A-t-on trouvé le parent ? + for (unsigned int j = 0; j < i; ++j) // Le parent se trouve forcément avant nous { - m_impl->joints[i].SetParent(m_impl->joints[j]); // Oui, tout ça pour ça - break; + if (parent == &skeleton.m_impl->joints[j]) // A-t-on trouvé le parent ? + { + m_impl->joints[i].SetParent(m_impl->joints[j]); // Oui, tout ça pour ça + break; + } } } } } + + return *this; } - return *this; -} - -void NzSkeleton::InvalidateJoints() -{ - m_impl->aabbUpdated = false; - - OnSkeletonJointsInvalidated(this); -} - -void NzSkeleton::InvalidateJointMap() -{ - #ifdef NAZARA_DEBUG - if (!m_impl) + void Skeleton::InvalidateJoints() { - NazaraError("Invalid skeleton"); - return; + m_impl->aabbUpdated = false; + + OnSkeletonJointsInvalidated(this); } - #endif - m_impl->jointMapUpdated = false; -} - -void NzSkeleton::UpdateJointMap() const -{ - #ifdef NAZARA_DEBUG - if (!m_impl) + void Skeleton::InvalidateJointMap() { - NazaraError("Invalid skeleton"); - return; - } - #endif - - m_impl->jointMap.clear(); - for (unsigned int i = 0; i < m_impl->joints.size(); ++i) - { - NzString name = m_impl->joints[i].GetName(); - if (!name.IsEmpty()) + #ifdef NAZARA_DEBUG + if (!m_impl) { - #if NAZARA_UTILITY_SAFE - auto it = m_impl->jointMap.find(name); - if (it != m_impl->jointMap.end()) - { - NazaraWarning("Joint name \"" + name + "\" is already present in joint map for joint #" + NzString::Number(it->second)); - continue; - } - #endif - - m_impl->jointMap[name] = i; + NazaraError("Invalid skeleton"); + return; } + #endif + + m_impl->jointMapUpdated = false; } - m_impl->jointMapUpdated = true; -} - -bool NzSkeleton::Initialize() -{ - if (!NzSkeletonLibrary::Initialize()) + void Skeleton::UpdateJointMap() const { - NazaraError("Failed to initialise library"); - return false; + #ifdef NAZARA_DEBUG + if (!m_impl) + { + NazaraError("Invalid skeleton"); + return; + } + #endif + + m_impl->jointMap.clear(); + for (unsigned int i = 0; i < m_impl->joints.size(); ++i) + { + String name = m_impl->joints[i].GetName(); + if (!name.IsEmpty()) + { + #if NAZARA_UTILITY_SAFE + auto it = m_impl->jointMap.find(name); + if (it != m_impl->jointMap.end()) + { + NazaraWarning("Joint name \"" + name + "\" is already present in joint map for joint #" + String::Number(it->second)); + continue; + } + #endif + + m_impl->jointMap[name] = i; + } + } + + m_impl->jointMapUpdated = true; } - return true; -} + bool Skeleton::Initialize() + { + if (!SkeletonLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); + return false; + } -void NzSkeleton::Uninitialize() -{ - NzSkeletonLibrary::Uninitialize(); -} + return true; + } -NzSkeletonLibrary::LibraryMap NzSkeleton::s_library; + void Skeleton::Uninitialize() + { + SkeletonLibrary::Uninitialize(); + } + + SkeletonLibrary::LibraryMap Skeleton::s_library; +} diff --git a/src/Nazara/Utility/SoftwareBuffer.cpp b/src/Nazara/Utility/SoftwareBuffer.cpp index b21259dfa..e9193c8dd 100644 --- a/src/Nazara/Utility/SoftwareBuffer.cpp +++ b/src/Nazara/Utility/SoftwareBuffer.cpp @@ -9,92 +9,95 @@ #include #include -NzSoftwareBuffer::NzSoftwareBuffer(NzBuffer* parent, nzBufferType type) : -m_type(type) +namespace Nz { - NazaraUnused(parent); -} - -NzSoftwareBuffer::~NzSoftwareBuffer() -{ -} - -bool NzSoftwareBuffer::Create(unsigned int size, nzBufferUsage usage) -{ - NazaraUnused(usage); - - // Cette allocation est protégée car sa taille dépend directement de paramètres utilisateurs - try + SoftwareBuffer::SoftwareBuffer(Buffer* parent, BufferType type) : + m_type(type) { - m_buffer = new nzUInt8[size]; - } - catch (const std::exception& e) - { - NazaraError("Failed to allocate software buffer (" + NzString(e.what()) + ')'); - return false; + NazaraUnused(parent); } - m_mapped = false; - - return true; -} - -void NzSoftwareBuffer::Destroy() -{ - delete[] m_buffer; -} - -bool NzSoftwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) -{ - NazaraUnused(forceDiscard); - - #if NAZARA_UTILITY_SAFE - if (m_mapped) + SoftwareBuffer::~SoftwareBuffer() { - NazaraError("Buffer already mapped"); - return false; } - #endif - std::memcpy(&m_buffer[offset], data, size); - - return true; -} - -bool NzSoftwareBuffer::IsHardware() const -{ - return false; -} - -void* NzSoftwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size) -{ - NazaraUnused(access); - NazaraUnused(size); - - #if NAZARA_UTILITY_SAFE - if (m_mapped) + bool SoftwareBuffer::Create(unsigned int size, BufferUsage usage) { - NazaraError("Buffer already mapped"); - return nullptr; - } - #endif + NazaraUnused(usage); - m_mapped = true; + // Cette allocation est protégée car sa taille dépend directement de paramètres utilisateurs + try + { + m_buffer = new UInt8[size]; + } + catch (const std::exception& e) + { + NazaraError("Failed to allocate software buffer (" + String(e.what()) + ')'); + return false; + } - return &m_buffer[offset]; -} + m_mapped = false; -bool NzSoftwareBuffer::Unmap() -{ - #if NAZARA_UTILITY_SAFE - if (!m_mapped) - { - NazaraError("Buffer not mapped"); return true; } - #endif - m_mapped = false; + void SoftwareBuffer::Destroy() + { + delete[] m_buffer; + } - return true; + bool SoftwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) + { + NazaraUnused(forceDiscard); + + #if NAZARA_UTILITY_SAFE + if (m_mapped) + { + NazaraError("Buffer already mapped"); + return false; + } + #endif + + std::memcpy(&m_buffer[offset], data, size); + + return true; + } + + bool SoftwareBuffer::IsHardware() const + { + return false; + } + + void* SoftwareBuffer::Map(BufferAccess access, unsigned int offset, unsigned int size) + { + NazaraUnused(access); + NazaraUnused(size); + + #if NAZARA_UTILITY_SAFE + if (m_mapped) + { + NazaraError("Buffer already mapped"); + return nullptr; + } + #endif + + m_mapped = true; + + return &m_buffer[offset]; + } + + bool SoftwareBuffer::Unmap() + { + #if NAZARA_UTILITY_SAFE + if (!m_mapped) + { + NazaraError("Buffer not mapped"); + return true; + } + #endif + + m_mapped = false; + + return true; + } } diff --git a/src/Nazara/Utility/SoftwareBuffer.hpp b/src/Nazara/Utility/SoftwareBuffer.hpp index abe5419db..ab84b1899 100644 --- a/src/Nazara/Utility/SoftwareBuffer.hpp +++ b/src/Nazara/Utility/SoftwareBuffer.hpp @@ -10,26 +10,29 @@ #include #include -class NzSoftwareBuffer : public NzAbstractBuffer +namespace Nz { - public: - NzSoftwareBuffer(NzBuffer* parent, nzBufferType type); - ~NzSoftwareBuffer(); + class SoftwareBuffer : public AbstractBuffer + { + public: + SoftwareBuffer(Buffer* parent, BufferType type); + ~SoftwareBuffer(); - bool Create(unsigned int size, nzBufferUsage usage = nzBufferUsage_Static); - void Destroy(); + bool Create(unsigned int size, BufferUsage usage = BufferUsage_Static); + void Destroy(); - bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard); + bool Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard); - bool IsHardware() const; + bool IsHardware() const; - void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0); - bool Unmap(); + void* Map(BufferAccess access, unsigned int offset = 0, unsigned int size = 0); + bool Unmap(); - private: - nzBufferType m_type; - nzUInt8* m_buffer; - bool m_mapped; -}; + private: + BufferType m_type; + UInt8* m_buffer; + bool m_mapped; + }; +} #endif // NAZARA_SOFTWAREBUFFER_HPP diff --git a/src/Nazara/Utility/StaticMesh.cpp b/src/Nazara/Utility/StaticMesh.cpp index 8beebd356..6c6056864 100644 --- a/src/Nazara/Utility/StaticMesh.cpp +++ b/src/Nazara/Utility/StaticMesh.cpp @@ -11,116 +11,119 @@ #include #include -NzStaticMesh::NzStaticMesh(const NzMesh* parent) : -NzSubMesh(parent) +namespace Nz { -} - -NzStaticMesh::~NzStaticMesh() -{ - OnStaticMeshRelease(this); - - Destroy(); -} - -void NzStaticMesh::Center() -{ - NzVector3f offset(m_aabb.x + m_aabb.width/2.f, m_aabb.y + m_aabb.height/2.f, m_aabb.z + m_aabb.depth/2.f); - - NzVertexMapper mapper(m_vertexBuffer); - NzSparsePtr position = mapper.GetComponentPtr(nzVertexComponent_Position); - - unsigned int vertexCount = m_vertexBuffer->GetVertexCount(); - for (unsigned int i = 0; i < vertexCount; ++i) - *position++ -= offset; - - m_aabb.x -= offset.x; - m_aabb.y -= offset.y; - m_aabb.z -= offset.z; -} - -bool NzStaticMesh::Create(NzVertexBuffer* vertexBuffer) -{ - Destroy(); - - #if NAZARA_UTILITY_SAFE - if (!vertexBuffer) + StaticMesh::StaticMesh(const Mesh* parent) : + SubMesh(parent) + { + } + + StaticMesh::~StaticMesh() + { + OnStaticMeshRelease(this); + + Destroy(); + } + + void StaticMesh::Center() + { + Vector3f offset(m_aabb.x + m_aabb.width/2.f, m_aabb.y + m_aabb.height/2.f, m_aabb.z + m_aabb.depth/2.f); + + VertexMapper mapper(m_vertexBuffer); + SparsePtr position = mapper.GetComponentPtr(VertexComponent_Position); + + unsigned int vertexCount = m_vertexBuffer->GetVertexCount(); + for (unsigned int i = 0; i < vertexCount; ++i) + *position++ -= offset; + + m_aabb.x -= offset.x; + m_aabb.y -= offset.y; + m_aabb.z -= offset.z; + } + + bool StaticMesh::Create(VertexBuffer* vertexBuffer) + { + Destroy(); + + #if NAZARA_UTILITY_SAFE + if (!vertexBuffer) + { + NazaraError("Invalid vertex buffer"); + return false; + } + #endif + + m_vertexBuffer = vertexBuffer; + return true; + } + + void StaticMesh::Destroy() + { + if (m_vertexBuffer) + { + OnStaticMeshDestroy(this); + + m_indexBuffer.Reset(); + m_vertexBuffer.Reset(); + } + } + + bool StaticMesh::GenerateAABB() + { + // On lock le buffer pour itérer sur toutes les positions et composer notre AABB + VertexMapper mapper(m_vertexBuffer, BufferAccess_ReadOnly); + m_aabb = ComputeAABB(mapper.GetComponentPtr(VertexComponent_Position), m_vertexBuffer->GetVertexCount()); + + return true; + } + + const Boxf& StaticMesh::GetAABB() const + { + return m_aabb; + } + + AnimationType StaticMesh::GetAnimationType() const + { + return AnimationType_Static; + } + + const IndexBuffer* StaticMesh::GetIndexBuffer() const + { + return m_indexBuffer; + } + + VertexBuffer* StaticMesh::GetVertexBuffer() + { + return m_vertexBuffer; + } + + const VertexBuffer* StaticMesh::GetVertexBuffer() const + { + return m_vertexBuffer; + } + + unsigned int StaticMesh::GetVertexCount() const + { + return m_vertexBuffer->GetVertexCount(); + } + + bool StaticMesh::IsAnimated() const { - NazaraError("Invalid vertex buffer"); return false; } - #endif - m_vertexBuffer = vertexBuffer; - return true; -} - -void NzStaticMesh::Destroy() -{ - if (m_vertexBuffer) + bool StaticMesh::IsValid() const { - OnStaticMeshDestroy(this); - - m_indexBuffer.Reset(); - m_vertexBuffer.Reset(); + return m_vertexBuffer != nullptr; } -} -bool NzStaticMesh::GenerateAABB() -{ - // On lock le buffer pour itérer sur toutes les positions et composer notre AABB - NzVertexMapper mapper(m_vertexBuffer, nzBufferAccess_ReadOnly); - m_aabb = NzComputeAABB(mapper.GetComponentPtr(nzVertexComponent_Position), m_vertexBuffer->GetVertexCount()); + void StaticMesh::SetAABB(const Boxf& aabb) + { + m_aabb = aabb; + } - return true; + void StaticMesh::SetIndexBuffer(const IndexBuffer* indexBuffer) + { + m_indexBuffer = indexBuffer; } - -const NzBoxf& NzStaticMesh::GetAABB() const -{ - return m_aabb; -} - -nzAnimationType NzStaticMesh::GetAnimationType() const -{ - return nzAnimationType_Static; -} - -const NzIndexBuffer* NzStaticMesh::GetIndexBuffer() const -{ - return m_indexBuffer; -} - -NzVertexBuffer* NzStaticMesh::GetVertexBuffer() -{ - return m_vertexBuffer; -} - -const NzVertexBuffer* NzStaticMesh::GetVertexBuffer() const -{ - return m_vertexBuffer; -} - -unsigned int NzStaticMesh::GetVertexCount() const -{ - return m_vertexBuffer->GetVertexCount(); -} - -bool NzStaticMesh::IsAnimated() const -{ - return false; -} - -bool NzStaticMesh::IsValid() const -{ - return m_vertexBuffer != nullptr; -} - -void NzStaticMesh::SetAABB(const NzBoxf& aabb) -{ - m_aabb = aabb; -} - -void NzStaticMesh::SetIndexBuffer(const NzIndexBuffer* indexBuffer) -{ - m_indexBuffer = indexBuffer; } diff --git a/src/Nazara/Utility/SubMesh.cpp b/src/Nazara/Utility/SubMesh.cpp index c0deae362..ffe5a05f1 100644 --- a/src/Nazara/Utility/SubMesh.cpp +++ b/src/Nazara/Utility/SubMesh.cpp @@ -12,199 +12,202 @@ #include #include -NzSubMesh::NzSubMesh(const NzMesh* parent) : -NzRefCounted(false), // Un SubMesh n'est pas persistant par défaut -m_primitiveMode(nzPrimitiveMode_TriangleList), -m_parent(parent), -m_matIndex(0) +namespace Nz { -} - -NzSubMesh::~NzSubMesh() -{ - OnSubMeshRelease(this); -} - -void NzSubMesh::GenerateNormals() -{ - NzVertexMapper mapper(this); - unsigned int vertexCount = GetVertexCount(); - - NzSparsePtr normals = mapper.GetComponentPtr(nzVertexComponent_Normal); - NzSparsePtr positions = mapper.GetComponentPtr(nzVertexComponent_Position); - - for (unsigned int i = 0; i < vertexCount; ++i) - normals[i].MakeZero(); - - NzTriangleIterator iterator(this); - do + SubMesh::SubMesh(const Mesh* parent) : + RefCounted(false), // Un SubMesh n'est pas persistant par défaut + m_primitiveMode(PrimitiveMode_TriangleList), + m_parent(parent), + m_matIndex(0) { - NzVector3f pos0 = positions[iterator[0]]; - - NzVector3f dv[2]; - dv[0] = positions[iterator[1]] - pos0; - dv[1] = positions[iterator[2]] - pos0; - - NzVector3f normal = dv[0].CrossProduct(dv[1]); - - for (unsigned int i = 0; i < 3; ++i) - normals[iterator[i]] += normal; - } - while (iterator.Advance()); - - for (unsigned int i = 0; i < vertexCount; ++i) - normals[i].Normalize(); -} - -void NzSubMesh::GenerateNormalsAndTangents() -{ - NzVertexMapper mapper(this); - unsigned int vertexCount = GetVertexCount(); - - NzSparsePtr normals = mapper.GetComponentPtr(nzVertexComponent_Normal); - NzSparsePtr positions = mapper.GetComponentPtr(nzVertexComponent_Position); - NzSparsePtr tangents = mapper.GetComponentPtr(nzVertexComponent_Tangent); - NzSparsePtr texCoords = mapper.GetComponentPtr(nzVertexComponent_TexCoord); - - for (unsigned int i = 0; i < vertexCount; ++i) - { - normals[i].MakeZero(); - tangents[i].MakeZero(); } - NzTriangleIterator iterator(this); - do + SubMesh::~SubMesh() { - NzVector3f pos0 = positions[iterator[0]]; + OnSubMeshRelease(this); + } - NzVector3f dv[2]; - dv[0] = positions[iterator[1]] - pos0; - dv[1] = positions[iterator[2]] - pos0; + void SubMesh::GenerateNormals() + { + VertexMapper mapper(this); + unsigned int vertexCount = GetVertexCount(); - NzVector3f normal = dv[0].CrossProduct(dv[1]); + SparsePtr normals = mapper.GetComponentPtr(VertexComponent_Normal); + SparsePtr positions = mapper.GetComponentPtr(VertexComponent_Position); - NzVector2f uv0 = texCoords[iterator[0]]; + for (unsigned int i = 0; i < vertexCount; ++i) + normals[i].MakeZero(); - NzVector2f duv[2]; - duv[0] = texCoords[iterator[1]] - uv0; - duv[1] = texCoords[iterator[2]] - uv0; - - float coef = 1.f / (duv[0].x*duv[1].y - duv[1].x*duv[0].y); - - NzVector3f tangent; - tangent.x = coef * (dv[0].x*duv[1].y + dv[1].x*(-duv[0].y)); - tangent.y = coef * (dv[0].y*duv[1].y + dv[1].y*(-duv[0].y)); - tangent.z = coef * (dv[0].z*duv[1].y + dv[1].z*(-duv[0].y)); - - for (unsigned int i = 0; i < 3; ++i) + TriangleIterator iterator(this); + do { - nzUInt32 index = iterator[i]; - normals[index] += normal; - tangents[index] += tangent; + Vector3f pos0 = positions[iterator[0]]; + + Vector3f dv[2]; + dv[0] = positions[iterator[1]] - pos0; + dv[1] = positions[iterator[2]] - pos0; + + Vector3f normal = dv[0].CrossProduct(dv[1]); + + for (unsigned int i = 0; i < 3; ++i) + normals[iterator[i]] += normal; + } + while (iterator.Advance()); + + for (unsigned int i = 0; i < vertexCount; ++i) + normals[i].Normalize(); + } + + void SubMesh::GenerateNormalsAndTangents() + { + VertexMapper mapper(this); + unsigned int vertexCount = GetVertexCount(); + + SparsePtr normals = mapper.GetComponentPtr(VertexComponent_Normal); + SparsePtr positions = mapper.GetComponentPtr(VertexComponent_Position); + SparsePtr tangents = mapper.GetComponentPtr(VertexComponent_Tangent); + SparsePtr texCoords = mapper.GetComponentPtr(VertexComponent_TexCoord); + + for (unsigned int i = 0; i < vertexCount; ++i) + { + normals[i].MakeZero(); + tangents[i].MakeZero(); + } + + TriangleIterator iterator(this); + do + { + Vector3f pos0 = positions[iterator[0]]; + + Vector3f dv[2]; + dv[0] = positions[iterator[1]] - pos0; + dv[1] = positions[iterator[2]] - pos0; + + Vector3f normal = dv[0].CrossProduct(dv[1]); + + Vector2f uv0 = texCoords[iterator[0]]; + + Vector2f duv[2]; + duv[0] = texCoords[iterator[1]] - uv0; + duv[1] = texCoords[iterator[2]] - uv0; + + float coef = 1.f / (duv[0].x*duv[1].y - duv[1].x*duv[0].y); + + Vector3f tangent; + tangent.x = coef * (dv[0].x*duv[1].y + dv[1].x*(-duv[0].y)); + tangent.y = coef * (dv[0].y*duv[1].y + dv[1].y*(-duv[0].y)); + tangent.z = coef * (dv[0].z*duv[1].y + dv[1].z*(-duv[0].y)); + + for (unsigned int i = 0; i < 3; ++i) + { + UInt32 index = iterator[i]; + normals[index] += normal; + tangents[index] += tangent; + } + } + while (iterator.Advance()); + + for (unsigned int i = 0; i < vertexCount; ++i) + { + normals[i].Normalize(); + tangents[i].Normalize(); } } - while (iterator.Advance()); - for (unsigned int i = 0; i < vertexCount; ++i) + void SubMesh::GenerateTangents() { - normals[i].Normalize(); - tangents[i].Normalize(); - } -} + VertexMapper mapper(this); -void NzSubMesh::GenerateTangents() -{ - NzVertexMapper mapper(this); + SparsePtr normals = mapper.GetComponentPtr(VertexComponent_Normal); + SparsePtr positions = mapper.GetComponentPtr(VertexComponent_Position); + SparsePtr tangents = mapper.GetComponentPtr(VertexComponent_Tangent); + SparsePtr texCoords = mapper.GetComponentPtr(VertexComponent_TexCoord); - NzSparsePtr normals = mapper.GetComponentPtr(nzVertexComponent_Normal); - NzSparsePtr positions = mapper.GetComponentPtr(nzVertexComponent_Position); - NzSparsePtr tangents = mapper.GetComponentPtr(nzVertexComponent_Tangent); - NzSparsePtr texCoords = mapper.GetComponentPtr(nzVertexComponent_TexCoord); - - NzTriangleIterator iterator(this); - do - { - NzVector3f pos0 = positions[iterator[0]]; - NzVector2f uv0 = texCoords[iterator[0]]; - NzVector2f uv1 = texCoords[iterator[1]]; - NzVector2f uv2 = texCoords[iterator[2]]; - - NzVector3f dv[2]; - dv[0] = positions[iterator[1]] - pos0; - dv[1] = positions[iterator[2]] - pos0; - - float ds[2]; - ds[0] = uv1.x - uv0.x; - ds[1] = uv2.x - uv0.x; - - NzVector3f ppt; - ppt.x = ds[0]*dv[1].x - dv[0].x*ds[1]; - ppt.y = ds[0]*dv[1].y - dv[0].y*ds[1]; - ppt.z = ds[0]*dv[1].z - dv[0].z*ds[1]; - ppt.Normalize(); - - for (unsigned int i = 0; i < 3; ++i) + TriangleIterator iterator(this); + do { - NzVector3f normal = normals[iterator[i]]; - float d = ppt.DotProduct(normal); + Vector3f pos0 = positions[iterator[0]]; + Vector2f uv0 = texCoords[iterator[0]]; + Vector2f uv1 = texCoords[iterator[1]]; + Vector2f uv2 = texCoords[iterator[2]]; - tangents[iterator[i]] = ppt - (d * normal); + Vector3f dv[2]; + dv[0] = positions[iterator[1]] - pos0; + dv[1] = positions[iterator[2]] - pos0; + + float ds[2]; + ds[0] = uv1.x - uv0.x; + ds[1] = uv2.x - uv0.x; + + Vector3f ppt; + ppt.x = ds[0]*dv[1].x - dv[0].x*ds[1]; + ppt.y = ds[0]*dv[1].y - dv[0].y*ds[1]; + ppt.z = ds[0]*dv[1].z - dv[0].z*ds[1]; + ppt.Normalize(); + + for (unsigned int i = 0; i < 3; ++i) + { + Vector3f normal = normals[iterator[i]]; + float d = ppt.DotProduct(normal); + + tangents[iterator[i]] = ppt - (d * normal); + } } + while (iterator.Advance()); } - while (iterator.Advance()); -} -const NzMesh* NzSubMesh::GetParent() const -{ - return m_parent; -} - -nzPrimitiveMode NzSubMesh::GetPrimitiveMode() const -{ - return m_primitiveMode; -} - -unsigned int NzSubMesh::GetTriangleCount() const -{ - const NzIndexBuffer* indexBuffer = GetIndexBuffer(); - unsigned int indexCount; - if (indexBuffer) - indexCount = indexBuffer->GetIndexCount(); - else - indexCount = GetVertexCount(); - - switch (m_primitiveMode) + const Mesh* SubMesh::GetParent() const { - case nzPrimitiveMode_LineList: - case nzPrimitiveMode_LineStrip: - case nzPrimitiveMode_PointList: - return 0; - - case nzPrimitiveMode_TriangleFan: - return (indexCount - 1) / 2; - - case nzPrimitiveMode_TriangleList: - return indexCount / 3; - - case nzPrimitiveMode_TriangleStrip: - return indexCount - 2; + return m_parent; } - NazaraError("Primitive mode not handled (0x" + NzString::Number(m_primitiveMode, 16) + ')'); - return 0; -} + PrimitiveMode SubMesh::GetPrimitiveMode() const + { + return m_primitiveMode; + } -unsigned int NzSubMesh::GetMaterialIndex() const -{ - return m_matIndex; -} + unsigned int SubMesh::GetTriangleCount() const + { + const IndexBuffer* indexBuffer = GetIndexBuffer(); + unsigned int indexCount; + if (indexBuffer) + indexCount = indexBuffer->GetIndexCount(); + else + indexCount = GetVertexCount(); -void NzSubMesh::SetPrimitiveMode(nzPrimitiveMode mode) -{ - m_primitiveMode = mode; -} + switch (m_primitiveMode) + { + case PrimitiveMode_LineList: + case PrimitiveMode_LineStrip: + case PrimitiveMode_PointList: + return 0; -void NzSubMesh::SetMaterialIndex(unsigned int matIndex) -{ - m_matIndex = matIndex; + case PrimitiveMode_TriangleFan: + return (indexCount - 1) / 2; + + case PrimitiveMode_TriangleList: + return indexCount / 3; + + case PrimitiveMode_TriangleStrip: + return indexCount - 2; + } + + NazaraError("Primitive mode not handled (0x" + String::Number(m_primitiveMode, 16) + ')'); + return 0; + } + + unsigned int SubMesh::GetMaterialIndex() const + { + return m_matIndex; + } + + void SubMesh::SetPrimitiveMode(PrimitiveMode mode) + { + m_primitiveMode = mode; + } + + void SubMesh::SetMaterialIndex(unsigned int matIndex) + { + m_matIndex = matIndex; +} } diff --git a/src/Nazara/Utility/TriangleIterator.cpp b/src/Nazara/Utility/TriangleIterator.cpp index 7057d6d8f..0c6830c87 100644 --- a/src/Nazara/Utility/TriangleIterator.cpp +++ b/src/Nazara/Utility/TriangleIterator.cpp @@ -6,75 +6,78 @@ #include #include -NzTriangleIterator::NzTriangleIterator(nzPrimitiveMode primitiveMode, const NzIndexBuffer* indexBuffer) : -m_primitiveMode(primitiveMode), -m_indexMapper(indexBuffer, nzBufferAccess_ReadOnly) +namespace Nz { - m_currentIndex = 3; - m_triangleIndices[0] = m_indexMapper.Get(0); - m_triangleIndices[1] = m_indexMapper.Get(1); - m_triangleIndices[2] = m_indexMapper.Get(2); - - m_indexCount = indexBuffer->GetIndexCount(); -} - -NzTriangleIterator::NzTriangleIterator(NzSubMesh* subMesh) : -NzTriangleIterator(subMesh->GetPrimitiveMode(), subMesh->GetIndexBuffer()) -{ -} - -bool NzTriangleIterator::Advance() -{ - if (m_currentIndex >= m_indexCount) + TriangleIterator::TriangleIterator(PrimitiveMode primitiveMode, const IndexBuffer* indexBuffer) : + m_primitiveMode(primitiveMode), + m_indexMapper(indexBuffer, BufferAccess_ReadOnly) { - Unmap(); - return false; + m_currentIndex = 3; + m_triangleIndices[0] = m_indexMapper.Get(0); + m_triangleIndices[1] = m_indexMapper.Get(1); + m_triangleIndices[2] = m_indexMapper.Get(2); + + m_indexCount = indexBuffer->GetIndexCount(); } - switch (m_primitiveMode) + TriangleIterator::TriangleIterator(SubMesh* subMesh) : + TriangleIterator(subMesh->GetPrimitiveMode(), subMesh->GetIndexBuffer()) { - case nzPrimitiveMode_TriangleFan: - m_triangleIndices[1] = m_indexMapper.Get(m_currentIndex++); - m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++); - break; + } - case nzPrimitiveMode_TriangleList: - m_triangleIndices[0] = m_indexMapper.Get(m_currentIndex++); - m_triangleIndices[1] = m_indexMapper.Get(m_currentIndex++); - m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++); - break; - - case nzPrimitiveMode_TriangleStrip: - m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++); - m_triangleIndices[0] = m_triangleIndices[1]; - m_triangleIndices[1] = m_triangleIndices[2]; - break; - - default: + bool TriangleIterator::Advance() + { + if (m_currentIndex >= m_indexCount) + { + Unmap(); return false; + } + + switch (m_primitiveMode) + { + case PrimitiveMode_TriangleFan: + m_triangleIndices[1] = m_indexMapper.Get(m_currentIndex++); + m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++); + break; + + case PrimitiveMode_TriangleList: + m_triangleIndices[0] = m_indexMapper.Get(m_currentIndex++); + m_triangleIndices[1] = m_indexMapper.Get(m_currentIndex++); + m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++); + break; + + case PrimitiveMode_TriangleStrip: + m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++); + m_triangleIndices[0] = m_triangleIndices[1]; + m_triangleIndices[1] = m_triangleIndices[2]; + break; + + default: + return false; + } + + return true; } - return true; -} - -nzUInt32 NzTriangleIterator::operator[](unsigned int i) const -{ - #if NAZARA_UTILITY_SAFE - if (i >= 3) + UInt32 TriangleIterator::operator[](unsigned int i) const { - NzStringStream ss; - ss << "Index out of range: (" << i << " >= 3)"; + #if NAZARA_UTILITY_SAFE + if (i >= 3) + { + StringStream ss; + ss << "Index out of range: (" << i << " >= 3)"; - NazaraError(ss); - throw std::domain_error(ss.ToString()); + NazaraError(ss); + throw std::domain_error(ss.ToString()); + } + #endif + + return m_triangleIndices[i]; } - #endif - return m_triangleIndices[i]; -} - -void NzTriangleIterator::Unmap() -{ - // Peut très bien être appellé plusieurs fois de suite, seul le premier appel sera pris en compte - m_indexMapper.Unmap(); + void TriangleIterator::Unmap() + { + // Peut très bien être appellé plusieurs fois de suite, seul le premier appel sera pris en compte + m_indexMapper.Unmap(); + } } diff --git a/src/Nazara/Utility/Utility.cpp b/src/Nazara/Utility/Utility.cpp index d647e0424..f83821975 100644 --- a/src/Nazara/Utility/Utility.cpp +++ b/src/Nazara/Utility/Utility.cpp @@ -28,187 +28,190 @@ #include #include -bool NzUtility::Initialize() +namespace Nz { - if (s_moduleReferenceCounter > 0) + bool Utility::Initialize() { + if (s_moduleReferenceCounter > 0) + { + s_moduleReferenceCounter++; + return true; // Déjà initialisé + } + + // Initialisation des dépendances + if (!Core::Initialize()) + { + NazaraError("Failed to initialize core module"); + return false; + } + s_moduleReferenceCounter++; - return true; // Déjà initialisé + + // Initialisation du module + CallOnExit onExit(Utility::Uninitialize); + + if (!Animation::Initialize()) + { + NazaraError("Failed to initialize animations"); + return false; + } + + if (!Buffer::Initialize()) + { + NazaraError("Failed to initialize buffers"); + return false; + } + + if (!Font::Initialize()) + { + NazaraError("Failed to initialize fonts"); + return false; + } + + if (!Image::Initialize()) + { + NazaraError("Failed to initialize images"); + return false; + } + + if (!Mesh::Initialize()) + { + NazaraError("Failed to initialize meshes"); + return false; + } + + if (!NzPixelFormat::Initialize()) + { + NazaraError("Failed to initialize pixel formats"); + return false; + } + + if (!Skeleton::Initialize()) + { + NazaraError("Failed to initialize skeletons"); + return false; + } + + if (!VertexDeclaration::Initialize()) + { + NazaraError("Failed to initialize vertex declarations"); + return false; + } + + if (!Window::Initialize()) + { + NazaraError("Failed to initialize window's system"); + return false; + } + + // On enregistre les loaders pour les extensions + // Il s'agit ici d'une liste LIFO, le dernier loader enregistré possède la priorité + + /// Loaders génériques + // Font + Loaders::RegisterFreeType(); + + // Image + Loaders::RegisterSTB(); // Loader générique (STB) + + /// Loaders spécialisés + // Animation + Loaders::RegisterMD5Anim(); // Loader de fichiers .md5anim (v10) + + // Mesh + Loaders::RegisterMD2(); // Loader de fichiers .md2 (v8) + Loaders::RegisterMD5Mesh(); // Loader de fichiers .md5mesh (v10) + + // Image + Loaders::RegisterPCX(); // Loader de fichiers .pcx (1, 4, 8, 24 bits) + + onExit.Reset(); + + NazaraNotice("Initialized: Utility module"); + return true; } - // Initialisation des dépendances - if (!NzCore::Initialize()) + bool Utility::IsInitialized() { - NazaraError("Failed to initialize core module"); - return false; + return s_moduleReferenceCounter != 0; } - s_moduleReferenceCounter++; - - // Initialisation du module - NzCallOnExit onExit(NzUtility::Uninitialize); - - if (!NzAnimation::Initialize()) + void Utility::Uninitialize() { - NazaraError("Failed to initialize animations"); - return false; + if (s_moduleReferenceCounter != 1) + { + // Le module est soit encore utilisé, soit pas initialisé + if (s_moduleReferenceCounter > 1) + s_moduleReferenceCounter--; + + return; + } + + // Libération du module + s_moduleReferenceCounter = 0; + + Loaders::UnregisterFreeType(); + Loaders::UnregisterMD2(); + Loaders::UnregisterMD5Anim(); + Loaders::UnregisterMD5Mesh(); + Loaders::UnregisterPCX(); + Loaders::UnregisterSTB(); + + Window::Uninitialize(); + VertexDeclaration::Uninitialize(); + Skeleton::Uninitialize(); + NzPixelFormat::Uninitialize(); + Mesh::Uninitialize(); + Image::Uninitialize(); + Font::Uninitialize(); + Buffer::Uninitialize(); + Animation::Uninitialize(); + + NazaraNotice("Uninitialized: Utility module"); + + // Libération des dépendances + Core::Uninitialize(); } - if (!NzBuffer::Initialize()) + unsigned int Utility::ComponentCount[ComponentType_Max+1] = { - NazaraError("Failed to initialize buffers"); - return false; - } + 4, // ComponentType_Color + 1, // ComponentType_Double1 + 2, // ComponentType_Double2 + 3, // ComponentType_Double3 + 4, // ComponentType_Double4 + 1, // ComponentType_Float1 + 2, // ComponentType_Float2 + 3, // ComponentType_Float3 + 4, // ComponentType_Float4 + 1, // ComponentType_Int1 + 2, // ComponentType_Int2 + 3, // ComponentType_Int3 + 4, // ComponentType_Int4 + 4 // ComponentType_Quaternion + }; - if (!NzFont::Initialize()) + static_assert(ComponentType_Max+1 == 14, "Component count array is incomplete"); + + std::size_t Utility::ComponentStride[ComponentType_Max+1] = { - NazaraError("Failed to initialize fonts"); - return false; - } + 4*sizeof(UInt8), // ComponentType_Color + 1*sizeof(double), // ComponentType_Double1 + 2*sizeof(double), // ComponentType_Double2 + 3*sizeof(double), // ComponentType_Double3 + 4*sizeof(double), // ComponentType_Double4 + 1*sizeof(float), // ComponentType_Float1 + 2*sizeof(float), // ComponentType_Float2 + 3*sizeof(float), // ComponentType_Float3 + 4*sizeof(float), // ComponentType_Float4 + 1*sizeof(UInt32), // ComponentType_Int1 + 2*sizeof(UInt32), // ComponentType_Int2 + 3*sizeof(UInt32), // ComponentType_Int3 + 4*sizeof(UInt32), // ComponentType_Int4 + 4*sizeof(float) // ComponentType_Quaternion + }; - if (!NzImage::Initialize()) - { - NazaraError("Failed to initialize images"); - return false; - } + static_assert(ComponentType_Max+1 == 14, "Component stride array is incomplete"); - if (!NzMesh::Initialize()) - { - NazaraError("Failed to initialize meshes"); - return false; - } - - if (!NzPixelFormat::Initialize()) - { - NazaraError("Failed to initialize pixel formats"); - return false; - } - - if (!NzSkeleton::Initialize()) - { - NazaraError("Failed to initialize skeletons"); - return false; - } - - if (!NzVertexDeclaration::Initialize()) - { - NazaraError("Failed to initialize vertex declarations"); - return false; - } - - if (!NzWindow::Initialize()) - { - NazaraError("Failed to initialize window's system"); - return false; - } - - // On enregistre les loaders pour les extensions - // Il s'agit ici d'une liste LIFO, le dernier loader enregistré possède la priorité - - /// Loaders génériques - // Font - NzLoaders_FreeType_Register(); - - // Image - NzLoaders_STB_Register(); // Loader générique (STB) - - /// Loaders spécialisés - // Animation - NzLoaders_MD5Anim_Register(); // Loader de fichiers .md5anim (v10) - - // Mesh - NzLoaders_MD2_Register(); // Loader de fichiers .md2 (v8) - NzLoaders_MD5Mesh_Register(); // Loader de fichiers .md5mesh (v10) - - // Image - NzLoaders_PCX_Register(); // Loader de fichiers .pcx (1, 4, 8, 24 bits) - - onExit.Reset(); - - NazaraNotice("Initialized: Utility module"); - return true; + unsigned int Utility::s_moduleReferenceCounter = 0; } - -bool NzUtility::IsInitialized() -{ - return s_moduleReferenceCounter != 0; -} - -void NzUtility::Uninitialize() -{ - if (s_moduleReferenceCounter != 1) - { - // Le module est soit encore utilisé, soit pas initialisé - if (s_moduleReferenceCounter > 1) - s_moduleReferenceCounter--; - - return; - } - - // Libération du module - s_moduleReferenceCounter = 0; - - NzLoaders_FreeType_Unregister(); - NzLoaders_MD2_Unregister(); - NzLoaders_MD5Anim_Unregister(); - NzLoaders_MD5Mesh_Unregister(); - NzLoaders_PCX_Unregister(); - NzLoaders_STB_Unregister(); - - NzWindow::Uninitialize(); - NzVertexDeclaration::Uninitialize(); - NzSkeleton::Uninitialize(); - NzPixelFormat::Uninitialize(); - NzMesh::Uninitialize(); - NzImage::Uninitialize(); - NzFont::Uninitialize(); - NzBuffer::Uninitialize(); - NzAnimation::Uninitialize(); - - NazaraNotice("Uninitialized: Utility module"); - - // Libération des dépendances - NzCore::Uninitialize(); -} - -unsigned int NzUtility::ComponentCount[nzComponentType_Max+1] = -{ - 4, // nzComponentType_Color - 1, // nzComponentType_Double1 - 2, // nzComponentType_Double2 - 3, // nzComponentType_Double3 - 4, // nzComponentType_Double4 - 1, // nzComponentType_Float1 - 2, // nzComponentType_Float2 - 3, // nzComponentType_Float3 - 4, // nzComponentType_Float4 - 1, // nzComponentType_Int1 - 2, // nzComponentType_Int2 - 3, // nzComponentType_Int3 - 4, // nzComponentType_Int4 - 4 // nzComponentType_Quaternion -}; - -static_assert(nzComponentType_Max+1 == 14, "Component count array is incomplete"); - -std::size_t NzUtility::ComponentStride[nzComponentType_Max+1] = -{ - 4*sizeof(nzUInt8), // nzComponentType_Color - 1*sizeof(double), // nzComponentType_Double1 - 2*sizeof(double), // nzComponentType_Double2 - 3*sizeof(double), // nzComponentType_Double3 - 4*sizeof(double), // nzComponentType_Double4 - 1*sizeof(float), // nzComponentType_Float1 - 2*sizeof(float), // nzComponentType_Float2 - 3*sizeof(float), // nzComponentType_Float3 - 4*sizeof(float), // nzComponentType_Float4 - 1*sizeof(nzUInt32), // nzComponentType_Int1 - 2*sizeof(nzUInt32), // nzComponentType_Int2 - 3*sizeof(nzUInt32), // nzComponentType_Int3 - 4*sizeof(nzUInt32), // nzComponentType_Int4 - 4*sizeof(float) // nzComponentType_Quaternion -}; - -static_assert(nzComponentType_Max+1 == 14, "Component stride array is incomplete"); - -unsigned int NzUtility::s_moduleReferenceCounter = 0; diff --git a/src/Nazara/Utility/VertexBuffer.cpp b/src/Nazara/Utility/VertexBuffer.cpp index 0a1d1b2c0..0bc890340 100644 --- a/src/Nazara/Utility/VertexBuffer.cpp +++ b/src/Nazara/Utility/VertexBuffer.cpp @@ -8,265 +8,268 @@ #include #include -NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer) +namespace Nz { - NzErrorFlags(nzErrorFlag_ThrowException, true); - Reset(vertexDeclaration, buffer); -} - -NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset) -{ - NzErrorFlags(nzErrorFlag_ThrowException, true); - Reset(vertexDeclaration, buffer, startOffset, endOffset); -} - -NzVertexBuffer::NzVertexBuffer(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzUInt32 storage, nzBufferUsage usage) -{ - NzErrorFlags(nzErrorFlag_ThrowException, true); - Reset(vertexDeclaration, length, storage, usage); -} - -NzVertexBuffer::NzVertexBuffer(const NzVertexBuffer& vertexBuffer) : -NzRefCounted(), -m_buffer(vertexBuffer.m_buffer), -m_vertexDeclaration(vertexBuffer.m_vertexDeclaration), -m_endOffset(vertexBuffer.m_endOffset), -m_startOffset(vertexBuffer.m_startOffset), -m_vertexCount(vertexBuffer.m_vertexCount) -{ -} - -NzVertexBuffer::~NzVertexBuffer() -{ - OnVertexBufferRelease(this); -} - -bool NzVertexBuffer::Fill(const void* data, unsigned int startVertex, unsigned int length, bool forceDiscard) -{ - unsigned int stride = m_vertexDeclaration->GetStride(); - return FillRaw(data, startVertex*stride, length*stride, forceDiscard); -} - -bool NzVertexBuffer::FillRaw(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) -{ - #if NAZARA_UTILITY_SAFE - if (!m_buffer) + VertexBuffer::VertexBuffer(const VertexDeclaration* vertexDeclaration, Buffer* buffer) { - NazaraError("No buffer"); - return false; + ErrorFlags(ErrorFlag_ThrowException, true); + Reset(vertexDeclaration, buffer); } - if (m_startOffset + offset + size > m_endOffset) + VertexBuffer::VertexBuffer(const VertexDeclaration* vertexDeclaration, Buffer* buffer, unsigned int startOffset, unsigned int endOffset) { - NazaraError("Exceeding virtual buffer size"); - return false; - } - #endif - - return m_buffer->Fill(data, m_startOffset+offset, size, forceDiscard); -} - -NzBuffer* NzVertexBuffer::GetBuffer() const -{ - return m_buffer; -} - -unsigned int NzVertexBuffer::GetEndOffset() const -{ - return m_endOffset; -} - -unsigned int NzVertexBuffer::GetStartOffset() const -{ - return m_startOffset; -} - -unsigned int NzVertexBuffer::GetStride() const -{ - return m_vertexDeclaration->GetStride(); -} - -unsigned int NzVertexBuffer::GetVertexCount() const -{ - return m_vertexCount; -} - -const NzVertexDeclaration* NzVertexBuffer::GetVertexDeclaration() const -{ - return m_vertexDeclaration; -} - -bool NzVertexBuffer::IsHardware() const -{ - return m_buffer->IsHardware(); -} - -bool NzVertexBuffer::IsValid() const -{ - return m_buffer && m_vertexDeclaration; -} - -void* NzVertexBuffer::Map(nzBufferAccess access, unsigned int startVertex, unsigned int length) -{ - #if NAZARA_UTILITY_SAFE - if (!m_vertexDeclaration) - { - NazaraError("No vertex declaration"); - return nullptr; - } - #endif - - unsigned int stride = m_vertexDeclaration->GetStride(); - - return MapRaw(access, startVertex*stride, length*stride); -} - -void* NzVertexBuffer::Map(nzBufferAccess access, unsigned int startVertex, unsigned int length) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_buffer) - { - NazaraError("No buffer"); - return nullptr; + ErrorFlags(ErrorFlag_ThrowException, true); + Reset(vertexDeclaration, buffer, startOffset, endOffset); } - if (!m_vertexDeclaration) + VertexBuffer::VertexBuffer(const VertexDeclaration* vertexDeclaration, unsigned int length, UInt32 storage, BufferUsage usage) { - NazaraError("No vertex declaration"); - return nullptr; - } - #endif - - unsigned int stride = m_vertexDeclaration->GetStride(); - - return MapRaw(access, startVertex*stride, length*stride); -} - -void* NzVertexBuffer::MapRaw(nzBufferAccess access, unsigned int offset, unsigned int size) -{ - #if NAZARA_UTILITY_SAFE - if (!m_buffer) - { - NazaraError("No buffer"); - return nullptr; + ErrorFlags(ErrorFlag_ThrowException, true); + Reset(vertexDeclaration, length, storage, usage); } - if (m_startOffset + offset + size > m_endOffset) + VertexBuffer::VertexBuffer(const VertexBuffer& vertexBuffer) : + RefCounted(), + m_buffer(vertexBuffer.m_buffer), + m_vertexDeclaration(vertexBuffer.m_vertexDeclaration), + m_endOffset(vertexBuffer.m_endOffset), + m_startOffset(vertexBuffer.m_startOffset), + m_vertexCount(vertexBuffer.m_vertexCount) { - NazaraError("Exceeding virtual buffer size"); - return nullptr; - } - #endif - - return m_buffer->Map(access, offset, size); -} - -void* NzVertexBuffer::MapRaw(nzBufferAccess access, unsigned int offset, unsigned int size) const -{ - #if NAZARA_UTILITY_SAFE - if (m_startOffset + offset + size > m_endOffset) - { - NazaraError("Exceeding virtual buffer size"); - return nullptr; - } - #endif - - return m_buffer->Map(access, offset, size); -} - -void NzVertexBuffer::Reset() -{ - m_buffer.Reset(); - m_vertexDeclaration.Reset(); -} - -void NzVertexBuffer::Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer) -{ - Reset(vertexDeclaration, buffer, 0, buffer->GetSize()-1); -} - -void NzVertexBuffer::Reset(const NzVertexDeclaration* vertexDeclaration, NzBuffer* buffer, unsigned int startOffset, unsigned int endOffset) -{ - #if NAZARA_UTILITY_SAFE - if (!buffer || !buffer->IsValid()) - { - NazaraError("Invalid buffer"); - return; } - if (startOffset > endOffset) + VertexBuffer::~VertexBuffer() { - NazaraError("Start offset cannot be over end offset"); - return; + OnVertexBufferRelease(this); } - unsigned int bufferSize = buffer->GetSize(); - if (startOffset >= bufferSize) + bool VertexBuffer::Fill(const void* data, unsigned int startVertex, unsigned int length, bool forceDiscard) { - NazaraError("Start offset is over buffer size"); - return; + unsigned int stride = m_vertexDeclaration->GetStride(); + return FillRaw(data, startVertex*stride, length*stride, forceDiscard); } - if (endOffset >= bufferSize) + bool VertexBuffer::FillRaw(const void* data, unsigned int offset, unsigned int size, bool forceDiscard) { - NazaraError("End offset is over buffer size"); - return; + #if NAZARA_UTILITY_SAFE + if (!m_buffer) + { + NazaraError("No buffer"); + return false; + } + + if (m_startOffset + offset + size > m_endOffset) + { + NazaraError("Exceeding virtual buffer size"); + return false; + } + #endif + + return m_buffer->Fill(data, m_startOffset+offset, size, forceDiscard); } - #endif - m_buffer = buffer; - m_endOffset = endOffset; - m_startOffset = startOffset; - m_vertexCount = (vertexDeclaration) ? ((endOffset - startOffset) / vertexDeclaration->GetStride()) : 0; - m_vertexDeclaration = vertexDeclaration; -} - -void NzVertexBuffer::Reset(const NzVertexDeclaration* vertexDeclaration, unsigned int length, nzUInt32 storage, nzBufferUsage usage) -{ - m_endOffset = length * ((vertexDeclaration) ? vertexDeclaration->GetStride() : 1); - m_startOffset = 0; - m_vertexCount = length; - - m_buffer = NzBuffer::New(nzBufferType_Vertex, m_endOffset, storage, usage); - m_vertexDeclaration = vertexDeclaration; -} - -void NzVertexBuffer::Reset(const NzVertexBuffer& vertexBuffer) -{ - m_buffer = vertexBuffer.m_buffer; - m_endOffset = vertexBuffer.m_endOffset; - m_startOffset = vertexBuffer.m_startOffset; - m_vertexCount = vertexBuffer.m_vertexCount; - m_vertexDeclaration = vertexBuffer.m_vertexDeclaration; -} - -bool NzVertexBuffer::SetStorage(nzUInt32 storage) -{ - return m_buffer->SetStorage(storage); -} - -void NzVertexBuffer::SetVertexDeclaration(const NzVertexDeclaration* vertexDeclaration) -{ - #if NAZARA_UTILITY_SAFE - if (!vertexDeclaration) + Buffer* VertexBuffer::GetBuffer() const { - NazaraError("Vertex declaration is invalid"); - return; + return m_buffer; } - #endif - m_vertexCount = (m_endOffset - m_startOffset)/vertexDeclaration->GetStride(); - m_vertexDeclaration = vertexDeclaration; -} - -void NzVertexBuffer::Unmap() const -{ - m_buffer->Unmap(); -} - -NzVertexBuffer& NzVertexBuffer::operator=(const NzVertexBuffer& vertexBuffer) -{ - Reset(vertexBuffer); - - return *this; + unsigned int VertexBuffer::GetEndOffset() const + { + return m_endOffset; + } + + unsigned int VertexBuffer::GetStartOffset() const + { + return m_startOffset; + } + + unsigned int VertexBuffer::GetStride() const + { + return m_vertexDeclaration->GetStride(); + } + + unsigned int VertexBuffer::GetVertexCount() const + { + return m_vertexCount; + } + + const VertexDeclaration* VertexBuffer::GetVertexDeclaration() const + { + return m_vertexDeclaration; + } + + bool VertexBuffer::IsHardware() const + { + return m_buffer->IsHardware(); + } + + bool VertexBuffer::IsValid() const + { + return m_buffer && m_vertexDeclaration; + } + + void* VertexBuffer::Map(BufferAccess access, unsigned int startVertex, unsigned int length) + { + #if NAZARA_UTILITY_SAFE + if (!m_vertexDeclaration) + { + NazaraError("No vertex declaration"); + return nullptr; + } + #endif + + unsigned int stride = m_vertexDeclaration->GetStride(); + + return MapRaw(access, startVertex*stride, length*stride); + } + + void* VertexBuffer::Map(BufferAccess access, unsigned int startVertex, unsigned int length) const + { + #if NAZARA_UTILITY_SAFE + if (!m_buffer) + { + NazaraError("No buffer"); + return nullptr; + } + + if (!m_vertexDeclaration) + { + NazaraError("No vertex declaration"); + return nullptr; + } + #endif + + unsigned int stride = m_vertexDeclaration->GetStride(); + + return MapRaw(access, startVertex*stride, length*stride); + } + + void* VertexBuffer::MapRaw(BufferAccess access, unsigned int offset, unsigned int size) + { + #if NAZARA_UTILITY_SAFE + if (!m_buffer) + { + NazaraError("No buffer"); + return nullptr; + } + + if (m_startOffset + offset + size > m_endOffset) + { + NazaraError("Exceeding virtual buffer size"); + return nullptr; + } + #endif + + return m_buffer->Map(access, offset, size); + } + + void* VertexBuffer::MapRaw(BufferAccess access, unsigned int offset, unsigned int size) const + { + #if NAZARA_UTILITY_SAFE + if (m_startOffset + offset + size > m_endOffset) + { + NazaraError("Exceeding virtual buffer size"); + return nullptr; + } + #endif + + return m_buffer->Map(access, offset, size); + } + + void VertexBuffer::Reset() + { + m_buffer.Reset(); + m_vertexDeclaration.Reset(); + } + + void VertexBuffer::Reset(const VertexDeclaration* vertexDeclaration, Buffer* buffer) + { + Reset(vertexDeclaration, buffer, 0, buffer->GetSize()-1); + } + + void VertexBuffer::Reset(const VertexDeclaration* vertexDeclaration, Buffer* buffer, unsigned int startOffset, unsigned int endOffset) + { + #if NAZARA_UTILITY_SAFE + if (!buffer || !buffer->IsValid()) + { + NazaraError("Invalid buffer"); + return; + } + + if (startOffset > endOffset) + { + NazaraError("Start offset cannot be over end offset"); + return; + } + + unsigned int bufferSize = buffer->GetSize(); + if (startOffset >= bufferSize) + { + NazaraError("Start offset is over buffer size"); + return; + } + + if (endOffset >= bufferSize) + { + NazaraError("End offset is over buffer size"); + return; + } + #endif + + m_buffer = buffer; + m_endOffset = endOffset; + m_startOffset = startOffset; + m_vertexCount = (vertexDeclaration) ? ((endOffset - startOffset) / vertexDeclaration->GetStride()) : 0; + m_vertexDeclaration = vertexDeclaration; + } + + void VertexBuffer::Reset(const VertexDeclaration* vertexDeclaration, unsigned int length, UInt32 storage, BufferUsage usage) + { + m_endOffset = length * ((vertexDeclaration) ? vertexDeclaration->GetStride() : 1); + m_startOffset = 0; + m_vertexCount = length; + + m_buffer = Buffer::New(BufferType_Vertex, m_endOffset, storage, usage); + m_vertexDeclaration = vertexDeclaration; + } + + void VertexBuffer::Reset(const VertexBuffer& vertexBuffer) + { + m_buffer = vertexBuffer.m_buffer; + m_endOffset = vertexBuffer.m_endOffset; + m_startOffset = vertexBuffer.m_startOffset; + m_vertexCount = vertexBuffer.m_vertexCount; + m_vertexDeclaration = vertexBuffer.m_vertexDeclaration; + } + + bool VertexBuffer::SetStorage(UInt32 storage) + { + return m_buffer->SetStorage(storage); + } + + void VertexBuffer::SetVertexDeclaration(const VertexDeclaration* vertexDeclaration) + { + #if NAZARA_UTILITY_SAFE + if (!vertexDeclaration) + { + NazaraError("Vertex declaration is invalid"); + return; + } + #endif + + m_vertexCount = (m_endOffset - m_startOffset)/vertexDeclaration->GetStride(); + m_vertexDeclaration = vertexDeclaration; + } + + void VertexBuffer::Unmap() const + { + m_buffer->Unmap(); + } + + VertexBuffer& VertexBuffer::operator=(const VertexBuffer& vertexBuffer) + { + Reset(vertexBuffer); + + return *this; + } } diff --git a/src/Nazara/Utility/VertexDeclaration.cpp b/src/Nazara/Utility/VertexDeclaration.cpp index 8471b1d79..323c62b99 100644 --- a/src/Nazara/Utility/VertexDeclaration.cpp +++ b/src/Nazara/Utility/VertexDeclaration.cpp @@ -13,291 +13,294 @@ #include #include -NzVertexDeclaration::NzVertexDeclaration() : -m_stride(0) +namespace Nz { -} - -NzVertexDeclaration::NzVertexDeclaration(const NzVertexDeclaration& declaration) : -NzRefCounted(), -m_stride(declaration.m_stride) -{ - std::memcpy(m_components, declaration.m_components, sizeof(Component)*(nzVertexComponent_Max+1)); -} - -NzVertexDeclaration::~NzVertexDeclaration() -{ - OnVertexDeclarationRelease(this); -} - -void NzVertexDeclaration::DisableComponent(nzVertexComponent component) -{ - #ifdef NAZARA_DEBUG - if (component > nzVertexComponent_Max) + VertexDeclaration::VertexDeclaration() : + m_stride(0) { - NazaraError("Vertex component out of enum"); - return; } - #endif - #if NAZARA_UTILITY_SAFE - if (component == nzVertexComponent_Unused) + VertexDeclaration::VertexDeclaration(const VertexDeclaration& declaration) : + RefCounted(), + m_stride(declaration.m_stride) { - NazaraError("Cannot disable \"unused\" component"); - return; + std::memcpy(m_components, declaration.m_components, sizeof(Component)*(VertexComponent_Max+1)); } - #endif - Component& vertexComponent = m_components[component]; - if (vertexComponent.enabled) + VertexDeclaration::~VertexDeclaration() { - vertexComponent.enabled = false; - m_stride -= NzUtility::ComponentStride[vertexComponent.type]; + OnVertexDeclarationRelease(this); } -} -void NzVertexDeclaration::EnableComponent(nzVertexComponent component, nzComponentType type, unsigned int offset) -{ - #ifdef NAZARA_DEBUG - if (component > nzVertexComponent_Max) + void VertexDeclaration::DisableComponent(VertexComponent component) { - NazaraError("Vertex component out of enum"); - return; - } - #endif + #ifdef NAZARA_DEBUG + if (component > VertexComponent_Max) + { + NazaraError("Vertex component out of enum"); + return; + } + #endif - #if NAZARA_UTILITY_SAFE - if (!IsTypeSupported(type)) - { - NazaraError("Component type 0x" + NzString::Number(type, 16) + " is not supported by vertex declarations"); - return; - } - #endif + #if NAZARA_UTILITY_SAFE + if (component == VertexComponent_Unused) + { + NazaraError("Cannot disable \"unused\" component"); + return; + } + #endif - if (component != nzVertexComponent_Unused) - { Component& vertexComponent = m_components[component]; if (vertexComponent.enabled) - m_stride -= NzUtility::ComponentStride[vertexComponent.type]; - else - vertexComponent.enabled = true; - - vertexComponent.offset = offset; - vertexComponent.type = type; + { + vertexComponent.enabled = false; + m_stride -= Utility::ComponentStride[vertexComponent.type]; + } } - m_stride += NzUtility::ComponentStride[type]; -} - -void NzVertexDeclaration::GetComponent(nzVertexComponent component, bool* enabled, nzComponentType* type, unsigned int* offset) const -{ - #ifdef NAZARA_DEBUG - if (component > nzVertexComponent_Max) + void VertexDeclaration::EnableComponent(VertexComponent component, ComponentType type, unsigned int offset) { - NazaraError("Vertex component out of enum"); - return; + #ifdef NAZARA_DEBUG + if (component > VertexComponent_Max) + { + NazaraError("Vertex component out of enum"); + return; + } + #endif + + #if NAZARA_UTILITY_SAFE + if (!IsTypeSupported(type)) + { + NazaraError("Component type 0x" + String::Number(type, 16) + " is not supported by vertex declarations"); + return; + } + #endif + + if (component != VertexComponent_Unused) + { + Component& vertexComponent = m_components[component]; + if (vertexComponent.enabled) + m_stride -= Utility::ComponentStride[vertexComponent.type]; + else + vertexComponent.enabled = true; + + vertexComponent.offset = offset; + vertexComponent.type = type; + } + + m_stride += Utility::ComponentStride[type]; } - #endif - #if NAZARA_UTILITY_SAFE - if (component == nzVertexComponent_Unused) + void VertexDeclaration::GetComponent(VertexComponent component, bool* enabled, ComponentType* type, unsigned int* offset) const { - NazaraError("Cannot get \"unused\" component"); - return; + #ifdef NAZARA_DEBUG + if (component > VertexComponent_Max) + { + NazaraError("Vertex component out of enum"); + return; + } + #endif + + #if NAZARA_UTILITY_SAFE + if (component == VertexComponent_Unused) + { + NazaraError("Cannot get \"unused\" component"); + return; + } + #endif + + const Component& vertexComponent = m_components[component]; + + if (enabled) + *enabled = vertexComponent.enabled; + + if (type) + *type = vertexComponent.type; + + if (offset) + *offset = vertexComponent.offset; } - #endif - const Component& vertexComponent = m_components[component]; - - if (enabled) - *enabled = vertexComponent.enabled; - - if (type) - *type = vertexComponent.type; - - if (offset) - *offset = vertexComponent.offset; -} - -unsigned int NzVertexDeclaration::GetStride() const -{ - return m_stride; -} - -void NzVertexDeclaration::SetStride(unsigned int stride) -{ - m_stride = stride; -} - -NzVertexDeclaration& NzVertexDeclaration::operator=(const NzVertexDeclaration& declaration) -{ - std::memcpy(m_components, declaration.m_components, sizeof(Component)*(nzVertexComponent_Max+1)); - m_stride = declaration.m_stride; - - return *this; -} - -NzVertexDeclaration* NzVertexDeclaration::Get(nzVertexLayout layout) -{ - #ifdef NAZARA_DEBUG - if (layout > nzVertexLayout_Max) + unsigned int VertexDeclaration::GetStride() const { - NazaraError("Vertex layout out of enum"); - return nullptr; + return m_stride; } - #endif - return &s_declarations[layout]; -} - -bool NzVertexDeclaration::IsTypeSupported(nzComponentType type) -{ - switch (type) + void VertexDeclaration::SetStride(unsigned int stride) { - case nzComponentType_Color: - case nzComponentType_Double1: - case nzComponentType_Double2: - case nzComponentType_Double3: - case nzComponentType_Double4: - case nzComponentType_Float1: - case nzComponentType_Float2: - case nzComponentType_Float3: - case nzComponentType_Float4: - case nzComponentType_Int1: - case nzComponentType_Int2: - case nzComponentType_Int3: - case nzComponentType_Int4: - return true; + m_stride = stride; + } - case nzComponentType_Quaternion: + VertexDeclaration& VertexDeclaration::operator=(const VertexDeclaration& declaration) + { + std::memcpy(m_components, declaration.m_components, sizeof(Component)*(VertexComponent_Max+1)); + m_stride = declaration.m_stride; + + return *this; + } + + VertexDeclaration* VertexDeclaration::Get(VertexLayout layout) + { + #ifdef NAZARA_DEBUG + if (layout > VertexLayout_Max) + { + NazaraError("Vertex layout out of enum"); + return nullptr; + } + #endif + + return &s_declarations[layout]; + } + + bool VertexDeclaration::IsTypeSupported(ComponentType type) + { + switch (type) + { + case ComponentType_Color: + case ComponentType_Double1: + case ComponentType_Double2: + case ComponentType_Double3: + case ComponentType_Double4: + case ComponentType_Float1: + case ComponentType_Float2: + case ComponentType_Float3: + case ComponentType_Float4: + case ComponentType_Int1: + case ComponentType_Int2: + case ComponentType_Int3: + case ComponentType_Int4: + return true; + + case ComponentType_Quaternion: + return false; + } + + NazaraError("Component type not handled (0x" + String::Number(type, 16) + ')'); + return false; + } + + bool VertexDeclaration::Initialize() + { + if (!VertexDeclarationLibrary::Initialize()) + { + NazaraError("Failed to initialise library"); return false; + } + + try + { + ErrorFlags flags(ErrorFlag_Silent | ErrorFlag_ThrowException); + + // Layout : Type + VertexDeclaration* declaration; + + // VertexLayout_XY : VertexStruct_XY + declaration = &s_declarations[VertexLayout_XY]; + declaration->EnableComponent(VertexComponent_Position, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XY, position)); + + NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XY), "Invalid stride for declaration VertexLayout_XY"); + + // VertexLayout_XY_Color : VertexStruct_XY_Color + declaration = &s_declarations[VertexLayout_XY_Color]; + declaration->EnableComponent(VertexComponent_Position, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XY_Color, position)); + declaration->EnableComponent(VertexComponent_Color, ComponentType_Color, NazaraOffsetOf(VertexStruct_XY_Color, color)); + + NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XY_Color), "Invalid stride for declaration VertexLayout_XY_Color"); + + // VertexLayout_XY_UV : VertexStruct_XY_UV + declaration = &s_declarations[VertexLayout_XY_UV]; + declaration->EnableComponent(VertexComponent_Position, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XY_UV, position)); + declaration->EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XY_UV, uv)); + + NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XY_UV), "Invalid stride for declaration VertexLayout_XY_UV"); + + // VertexLayout_XYZ : VertexStruct_XYZ + declaration = &s_declarations[VertexLayout_XYZ]; + declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ, position)); + + NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ), "Invalid stride for declaration VertexLayout_XYZ"); + + // VertexLayout_XYZ_Color : VertexStruct_XYZ_Color + declaration = &s_declarations[VertexLayout_XYZ_Color]; + declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Color, position)); + declaration->EnableComponent(VertexComponent_Color, ComponentType_Color, NazaraOffsetOf(VertexStruct_XYZ_Color, color)); + + NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ_Color), "Invalid stride for declaration VertexLayout_XYZ_Color"); + + // VertexLayout_XYZ_Color_UV : VertexStruct_XYZ_Color_UV + declaration = &s_declarations[VertexLayout_XYZ_Color_UV]; + declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Color_UV, position)); + declaration->EnableComponent(VertexComponent_Color, ComponentType_Color, NazaraOffsetOf(VertexStruct_XYZ_Color_UV, color)); + declaration->EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XYZ_Color_UV, uv)); + + NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ_Color_UV), "Invalid stride for declaration VertexLayout_XYZ_Color_UV"); + + // VertexLayout_XYZ_Normal : VertexStruct_XYZ_Normal + declaration = &s_declarations[VertexLayout_XYZ_Normal]; + declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal, position)); + declaration->EnableComponent(VertexComponent_Normal, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal, normal)); + + NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ_Normal), "Invalid stride for declaration VertexLayout_XYZ_Normal"); + + // VertexLayout_XYZ_Normal_UV : VertexStruct_XYZ_Normal_UV + declaration = &s_declarations[VertexLayout_XYZ_Normal_UV]; + declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV, position)); + declaration->EnableComponent(VertexComponent_Normal, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV, normal)); + declaration->EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV, uv)); + + NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ_Normal_UV), "Invalid stride for declaration VertexLayout_XYZ_Normal_UV"); + + // VertexLayout_XYZ_Normal_UV_Tangent : VertexStruct_XYZ_Normal_UV_Tangent + declaration = &s_declarations[VertexLayout_XYZ_Normal_UV_Tangent]; + declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent, position)); + declaration->EnableComponent(VertexComponent_Normal, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent, normal)); + declaration->EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent, uv)); + declaration->EnableComponent(VertexComponent_Tangent, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent, tangent)); + + NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ_Normal_UV_Tangent), "Invalid stride for declaration VertexLayout_XYZ_Normal_UV_Tangent"); + + // VertexLayout_XYZ_Normal_UV_Tangent_Skinning : VertexStruct_XYZ_Normal_UV_Tangent_Skinning + declaration = &s_declarations[VertexLayout_XYZ_Normal_UV_Tangent_Skinning]; + declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent_Skinning, position)); + declaration->EnableComponent(VertexComponent_Normal, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent_Skinning, normal)); + declaration->EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent_Skinning, uv)); + declaration->EnableComponent(VertexComponent_Tangent, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent_Skinning, tangent)); + declaration->EnableComponent(VertexComponent_Unused, ComponentType_Int1, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent_Skinning, weightCount)); + declaration->EnableComponent(VertexComponent_Userdata0, ComponentType_Float4, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent_Skinning, weights)); + declaration->EnableComponent(VertexComponent_Userdata1, ComponentType_Int4, NazaraOffsetOf(VertexStruct_XYZ_Normal_UV_Tangent_Skinning, jointIndexes)); + + NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ_Normal_UV_Tangent_Skinning), "Invalid stride for declaration VertexLayout_XYZ_Normal_UV_Tangent_Skinning"); + + // VertexLayout_XYZ_UV : VertexStruct_XYZ_UV + declaration = &s_declarations[VertexLayout_XYZ_UV]; + declaration->EnableComponent(VertexComponent_Position, ComponentType_Float3, NazaraOffsetOf(VertexStruct_XYZ_UV, position)); + declaration->EnableComponent(VertexComponent_TexCoord, ComponentType_Float2, NazaraOffsetOf(VertexStruct_XYZ_UV, uv)); + + NazaraAssert(declaration->GetStride() == sizeof(VertexStruct_XYZ_UV), "Invalid stride for declaration VertexLayout_XYZ_UV"); + + // VertexLayout_Matrix4 : Matrix4f + declaration = &s_declarations[VertexLayout_Matrix4]; + declaration->EnableComponent(VertexComponent_InstanceData0, ComponentType_Float4, NazaraOffsetOf(Matrix4f, m11)); + declaration->EnableComponent(VertexComponent_InstanceData1, ComponentType_Float4, NazaraOffsetOf(Matrix4f, m21)); + declaration->EnableComponent(VertexComponent_InstanceData2, ComponentType_Float4, NazaraOffsetOf(Matrix4f, m31)); + declaration->EnableComponent(VertexComponent_InstanceData3, ComponentType_Float4, NazaraOffsetOf(Matrix4f, m41)); + + NazaraAssert(declaration->GetStride() == sizeof(Matrix4f), "Invalid stride for declaration VertexLayout_Matrix4"); + } + catch (const std::exception& e) + { + NazaraError("Failed to initialize vertex declaration: " + String(e.what())); + return false; + } + + return true; } - NazaraError("Component type not handled (0x" + NzString::Number(type, 16) + ')'); - return false; -} - -bool NzVertexDeclaration::Initialize() -{ - if (!NzVertexDeclarationLibrary::Initialize()) + void VertexDeclaration::Uninitialize() { - NazaraError("Failed to initialise library"); - return false; + VertexDeclarationLibrary::Uninitialize(); } - try - { - NzErrorFlags flags(nzErrorFlag_Silent | nzErrorFlag_ThrowException); - - // Layout : Type - NzVertexDeclaration* declaration; - - // nzVertexLayout_XY : NzVertexStruct_XY - declaration = &s_declarations[nzVertexLayout_XY]; - declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float2, NzOffsetOf(NzVertexStruct_XY, position)); - - NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XY), "Invalid stride for declaration nzVertexLayout_XY"); - - // nzVertexLayout_XY_Color : NzVertexStruct_XY_Color - declaration = &s_declarations[nzVertexLayout_XY_Color]; - declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float2, NzOffsetOf(NzVertexStruct_XY_Color, position)); - declaration->EnableComponent(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(NzVertexStruct_XY_Color, color)); - - NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XY_Color), "Invalid stride for declaration nzVertexLayout_XY_Color"); - - // nzVertexLayout_XY_UV : NzVertexStruct_XY_UV - declaration = &s_declarations[nzVertexLayout_XY_UV]; - declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float2, NzOffsetOf(NzVertexStruct_XY_UV, position)); - declaration->EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(NzVertexStruct_XY_UV, uv)); - - NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XY_UV), "Invalid stride for declaration nzVertexLayout_XY_UV"); - - // nzVertexLayout_XYZ : NzVertexStruct_XYZ - declaration = &s_declarations[nzVertexLayout_XYZ]; - declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ, position)); - - NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XYZ), "Invalid stride for declaration nzVertexLayout_XYZ"); - - // nzVertexLayout_XYZ_Color : NzVertexStruct_XYZ_Color - declaration = &s_declarations[nzVertexLayout_XYZ_Color]; - declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Color, position)); - declaration->EnableComponent(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(NzVertexStruct_XYZ_Color, color)); - - NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XYZ_Color), "Invalid stride for declaration nzVertexLayout_XYZ_Color"); - - // nzVertexLayout_XYZ_Color_UV : NzVertexStruct_XYZ_Color_UV - declaration = &s_declarations[nzVertexLayout_XYZ_Color_UV]; - declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Color_UV, position)); - declaration->EnableComponent(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(NzVertexStruct_XYZ_Color_UV, color)); - declaration->EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(NzVertexStruct_XYZ_Color_UV, uv)); - - NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XYZ_Color_UV), "Invalid stride for declaration nzVertexLayout_XYZ_Color_UV"); - - // nzVertexLayout_XYZ_Normal : NzVertexStruct_XYZ_Normal - declaration = &s_declarations[nzVertexLayout_XYZ_Normal]; - declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Normal, position)); - declaration->EnableComponent(nzVertexComponent_Normal, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Normal, normal)); - - NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XYZ_Normal), "Invalid stride for declaration nzVertexLayout_XYZ_Normal"); - - // nzVertexLayout_XYZ_Normal_UV : NzVertexStruct_XYZ_Normal_UV - declaration = &s_declarations[nzVertexLayout_XYZ_Normal_UV]; - declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Normal_UV, position)); - declaration->EnableComponent(nzVertexComponent_Normal, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Normal_UV, normal)); - declaration->EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(NzVertexStruct_XYZ_Normal_UV, uv)); - - NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XYZ_Normal_UV), "Invalid stride for declaration nzVertexLayout_XYZ_Normal_UV"); - - // nzVertexLayout_XYZ_Normal_UV_Tangent : NzVertexStruct_XYZ_Normal_UV_Tangent - declaration = &s_declarations[nzVertexLayout_XYZ_Normal_UV_Tangent]; - declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Normal_UV_Tangent, position)); - declaration->EnableComponent(nzVertexComponent_Normal, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Normal_UV_Tangent, normal)); - declaration->EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(NzVertexStruct_XYZ_Normal_UV_Tangent, uv)); - declaration->EnableComponent(nzVertexComponent_Tangent, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Normal_UV_Tangent, tangent)); - - NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XYZ_Normal_UV_Tangent), "Invalid stride for declaration nzVertexLayout_XYZ_Normal_UV_Tangent"); - - // nzVertexLayout_XYZ_Normal_UV_Tangent_Skinning : NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning - declaration = &s_declarations[nzVertexLayout_XYZ_Normal_UV_Tangent_Skinning]; - declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning, position)); - declaration->EnableComponent(nzVertexComponent_Normal, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning, normal)); - declaration->EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning, uv)); - declaration->EnableComponent(nzVertexComponent_Tangent, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning, tangent)); - declaration->EnableComponent(nzVertexComponent_Unused, nzComponentType_Int1, NzOffsetOf(NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning, weightCount)); - declaration->EnableComponent(nzVertexComponent_Userdata0, nzComponentType_Float4, NzOffsetOf(NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning, weights)); - declaration->EnableComponent(nzVertexComponent_Userdata1, nzComponentType_Int4, NzOffsetOf(NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning, jointIndexes)); - - NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XYZ_Normal_UV_Tangent_Skinning), "Invalid stride for declaration nzVertexLayout_XYZ_Normal_UV_Tangent_Skinning"); - - // nzVertexLayout_XYZ_UV : NzVertexStruct_XYZ_UV - declaration = &s_declarations[nzVertexLayout_XYZ_UV]; - declaration->EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(NzVertexStruct_XYZ_UV, position)); - declaration->EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(NzVertexStruct_XYZ_UV, uv)); - - NazaraAssert(declaration->GetStride() == sizeof(NzVertexStruct_XYZ_UV), "Invalid stride for declaration nzVertexLayout_XYZ_UV"); - - // nzVertexLayout_Matrix4 : NzMatrix4f - declaration = &s_declarations[nzVertexLayout_Matrix4]; - declaration->EnableComponent(nzVertexComponent_InstanceData0, nzComponentType_Float4, NzOffsetOf(NzMatrix4f, m11)); - declaration->EnableComponent(nzVertexComponent_InstanceData1, nzComponentType_Float4, NzOffsetOf(NzMatrix4f, m21)); - declaration->EnableComponent(nzVertexComponent_InstanceData2, nzComponentType_Float4, NzOffsetOf(NzMatrix4f, m31)); - declaration->EnableComponent(nzVertexComponent_InstanceData3, nzComponentType_Float4, NzOffsetOf(NzMatrix4f, m41)); - - NazaraAssert(declaration->GetStride() == sizeof(NzMatrix4f), "Invalid stride for declaration nzVertexLayout_Matrix4"); - } - catch (const std::exception& e) - { - NazaraError("Failed to initialize vertex declaration: " + NzString(e.what())); - return false; - } - - return true; + VertexDeclaration VertexDeclaration::s_declarations[VertexLayout_Max+1]; + VertexDeclarationLibrary::LibraryMap VertexDeclaration::s_library; } - -void NzVertexDeclaration::Uninitialize() -{ - NzVertexDeclarationLibrary::Uninitialize(); -} - -NzVertexDeclaration NzVertexDeclaration::s_declarations[nzVertexLayout_Max+1]; -NzVertexDeclarationLibrary::LibraryMap NzVertexDeclaration::s_library; diff --git a/src/Nazara/Utility/VertexMapper.cpp b/src/Nazara/Utility/VertexMapper.cpp index 3b30ad3d3..1edbdc7f8 100644 --- a/src/Nazara/Utility/VertexMapper.cpp +++ b/src/Nazara/Utility/VertexMapper.cpp @@ -10,45 +10,48 @@ #include #include -NzVertexMapper::NzVertexMapper(NzSubMesh* subMesh, nzBufferAccess access) +namespace Nz { - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - - NzVertexBuffer* buffer = nullptr; - switch (subMesh->GetAnimationType()) + VertexMapper::VertexMapper(SubMesh* subMesh, BufferAccess access) { - case nzAnimationType_Skeletal: + ErrorFlags flags(ErrorFlag_ThrowException, true); + + VertexBuffer* buffer = nullptr; + switch (subMesh->GetAnimationType()) { - NzSkeletalMesh* skeletalMesh = static_cast(subMesh); - buffer = skeletalMesh->GetVertexBuffer(); - break; + case AnimationType_Skeletal: + { + SkeletalMesh* skeletalMesh = static_cast(subMesh); + buffer = skeletalMesh->GetVertexBuffer(); + break; + } + + case AnimationType_Static: + { + StaticMesh* staticMesh = static_cast(subMesh); + buffer = staticMesh->GetVertexBuffer(); + break; + } } - case nzAnimationType_Static: + if (!buffer) { - NzStaticMesh* staticMesh = static_cast(subMesh); - buffer = staticMesh->GetVertexBuffer(); - break; + NazaraInternalError("Animation type not handled (0x" + String::Number(subMesh->GetAnimationType(), 16) + ')'); } + + m_mapper.Map(buffer, access); } - if (!buffer) + VertexMapper::VertexMapper(VertexBuffer* vertexBuffer, BufferAccess access) { - NazaraInternalError("Animation type not handled (0x" + NzString::Number(subMesh->GetAnimationType(), 16) + ')'); + ErrorFlags flags(ErrorFlag_ThrowException, true); + m_mapper.Map(vertexBuffer, access); } - m_mapper.Map(buffer, access); -} + VertexMapper::~VertexMapper() = default; -NzVertexMapper::NzVertexMapper(NzVertexBuffer* vertexBuffer, nzBufferAccess access) -{ - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - m_mapper.Map(vertexBuffer, access); -} - -NzVertexMapper::~NzVertexMapper() = default; - -void NzVertexMapper::Unmap() -{ - m_mapper.Unmap(); + void VertexMapper::Unmap() + { + m_mapper.Unmap(); + } } diff --git a/src/Nazara/Utility/VideoMode.cpp b/src/Nazara/Utility/VideoMode.cpp index 4ca8ea532..6313ff460 100644 --- a/src/Nazara/Utility/VideoMode.cpp +++ b/src/Nazara/Utility/VideoMode.cpp @@ -16,86 +16,89 @@ #include -NzVideoMode::NzVideoMode() : -bitsPerPixel(0), -height(0), -width(0) +namespace Nz { -} - -NzVideoMode::NzVideoMode(unsigned int w, unsigned int h, nzUInt8 bpp) : -bitsPerPixel(bpp), -height(h), -width(w) -{ -} - -bool NzVideoMode::IsFullscreenValid() const -{ - const std::vector& modes = GetFullscreenModes(); - - return std::binary_search(modes.begin(), modes.end(), *this, std::greater()); -} - -NzVideoMode NzVideoMode::GetDesktopMode() -{ - return NzVideoModeImpl::GetDesktopMode(); -} - -const std::vector& NzVideoMode::GetFullscreenModes() -{ - static std::vector modes; - if (modes.empty()) + VideoMode::VideoMode() : + bitsPerPixel(0), + height(0), + width(0) { - NzVideoModeImpl::GetFullscreenModes(modes); - std::sort(modes.begin(), modes.end(), std::greater()); } - return modes; -} - -bool operator==(const NzVideoMode& left, const NzVideoMode& right) -{ - return left.width == right.width && left.height == right.height && left.bitsPerPixel == right.bitsPerPixel; -} - -bool operator!=(const NzVideoMode& left, const NzVideoMode& right) -{ - return left.width != right.width || left.height != right.height || left.bitsPerPixel != right.bitsPerPixel; -} - -bool operator<(const NzVideoMode& left, const NzVideoMode& right) -{ - if (left.bitsPerPixel == right.bitsPerPixel) + VideoMode::VideoMode(unsigned int w, unsigned int h, UInt8 bpp) : + bitsPerPixel(bpp), + height(h), + width(w) { - if (left.width == right.width) - return left.height < right.height; + } + + bool VideoMode::IsFullscreenValid() const + { + const std::vector& modes = GetFullscreenModes(); + + return std::binary_search(modes.begin(), modes.end(), *this, std::greater()); + } + + VideoMode VideoMode::GetDesktopMode() + { + return VideoModeImpl::GetDesktopMode(); + } + + const std::vector& VideoMode::GetFullscreenModes() + { + static std::vector modes; + if (modes.empty()) + { + VideoModeImpl::GetFullscreenModes(modes); + std::sort(modes.begin(), modes.end(), std::greater()); + } + + return modes; + } + + bool operator==(const VideoMode& left, const VideoMode& right) + { + return left.width == right.width && left.height == right.height && left.bitsPerPixel == right.bitsPerPixel; + } + + bool operator!=(const VideoMode& left, const VideoMode& right) + { + return left.width != right.width || left.height != right.height || left.bitsPerPixel != right.bitsPerPixel; + } + + bool operator<(const VideoMode& left, const VideoMode& right) + { + if (left.bitsPerPixel == right.bitsPerPixel) + { + if (left.width == right.width) + return left.height < right.height; + else + return left.width < right.width; + } else - return left.width < right.width; + return left.bitsPerPixel < right.bitsPerPixel; } - else - return left.bitsPerPixel < right.bitsPerPixel; -} -bool operator<=(const NzVideoMode& left, const NzVideoMode& right) -{ - if (left.bitsPerPixel == right.bitsPerPixel) + bool operator<=(const VideoMode& left, const VideoMode& right) { - if (left.width == right.width) - return left.height <= right.height; + if (left.bitsPerPixel == right.bitsPerPixel) + { + if (left.width == right.width) + return left.height <= right.height; + else + return left.width < right.width; + } else - return left.width < right.width; + return left.bitsPerPixel < right.bitsPerPixel; } - else - return left.bitsPerPixel < right.bitsPerPixel; -} -bool operator>(const NzVideoMode& left, const NzVideoMode& right) -{ - return right < left; -} + bool operator>(const VideoMode& left, const VideoMode& right) + { + return right < left; + } -bool operator>=(const NzVideoMode& left, const NzVideoMode& right) -{ - return right <= left; + bool operator>=(const VideoMode& left, const VideoMode& right) + { + return right <= left; + } } diff --git a/src/Nazara/Utility/VideoModeImpl.hpp b/src/Nazara/Utility/VideoModeImpl.hpp index 229a6de0a..7baeb6478 100644 --- a/src/Nazara/Utility/VideoModeImpl.hpp +++ b/src/Nazara/Utility/VideoModeImpl.hpp @@ -9,13 +9,13 @@ #include -class NzVideoMode; +class VideoMode; -class NzVideoModeImpl +class VideoModeImpl { public: - static NzVideoMode GetDesktopMode(); - static void GetFullscreenModes(std::vector& modes); + static VideoMode GetDesktopMode(); + static void GetFullscreenModes(std::vector& modes); }; #endif // NAZARA_VIDEOMODEIMPL_HPP diff --git a/src/Nazara/Utility/Win32/CursorImpl.cpp b/src/Nazara/Utility/Win32/CursorImpl.cpp index c772c1035..eec8785bb 100644 --- a/src/Nazara/Utility/Win32/CursorImpl.cpp +++ b/src/Nazara/Utility/Win32/CursorImpl.cpp @@ -8,46 +8,49 @@ #include #include -bool NzCursorImpl::Create(const NzImage& cursor, int hotSpotX, int hotSpotY) +namespace Nz { - NzImage windowsCursor(cursor); - if (!windowsCursor.Convert(nzPixelFormat_BGRA8)) + bool CursorImpl::Create(const Image& cursor, int hotSpotX, int hotSpotY) { - NazaraError("Failed to convert cursor to BGRA8"); - return false; + Image windowsCursor(cursor); + if (!windowsCursor.Convert(PixelFormatType_BGRA8)) + { + NazaraError("Failed to convert cursor to BGRA8"); + return false; + } + + HBITMAP bitmap = CreateBitmap(windowsCursor.GetWidth(), windowsCursor.GetHeight(), 1, 32, windowsCursor.GetConstPixels()); + HBITMAP monoBitmap = CreateBitmap(windowsCursor.GetWidth(), windowsCursor.GetHeight(), 1, 1, nullptr); + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms648052(v=vs.85).aspx + ICONINFO iconInfo; + iconInfo.fIcon = FALSE; + iconInfo.xHotspot = hotSpotX; + iconInfo.yHotspot = hotSpotY; + iconInfo.hbmMask = monoBitmap; + iconInfo.hbmColor = bitmap; + + m_cursor = CreateIconIndirect(&iconInfo); + + DeleteObject(bitmap); + DeleteObject(monoBitmap); + + if (!m_cursor) + { + NazaraError("Failed to create cursor: " + Error::GetLastSystemError()); + return false; + } + + return true; } - HBITMAP bitmap = CreateBitmap(windowsCursor.GetWidth(), windowsCursor.GetHeight(), 1, 32, windowsCursor.GetConstPixels()); - HBITMAP monoBitmap = CreateBitmap(windowsCursor.GetWidth(), windowsCursor.GetHeight(), 1, 1, nullptr); - - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms648052(v=vs.85).aspx - ICONINFO iconInfo; - iconInfo.fIcon = FALSE; - iconInfo.xHotspot = hotSpotX; - iconInfo.yHotspot = hotSpotY; - iconInfo.hbmMask = monoBitmap; - iconInfo.hbmColor = bitmap; - - m_cursor = CreateIconIndirect(&iconInfo); - - DeleteObject(bitmap); - DeleteObject(monoBitmap); - - if (!m_cursor) + void CursorImpl::Destroy() { - NazaraError("Failed to create cursor: " + NzError::GetLastSystemError()); - return false; + DestroyIcon(m_cursor); } - return true; -} - -void NzCursorImpl::Destroy() -{ - DestroyIcon(m_cursor); -} - -HCURSOR NzCursorImpl::GetCursor() -{ - return m_cursor; + HCURSOR CursorImpl::GetCursor() + { + return m_cursor; + } } diff --git a/src/Nazara/Utility/Win32/CursorImpl.hpp b/src/Nazara/Utility/Win32/CursorImpl.hpp index 9c9b97841..78662228e 100644 --- a/src/Nazara/Utility/Win32/CursorImpl.hpp +++ b/src/Nazara/Utility/Win32/CursorImpl.hpp @@ -10,18 +10,21 @@ #include #include -class NzImage; - -class NzCursorImpl +namespace Nz { - public: - bool Create(const NzImage& image, int hotSpotX, int hotSpotY); - void Destroy(); + class Image; - HCURSOR GetCursor(); + class CursorImpl + { + public: + bool Create(const Image& image, int hotSpotX, int hotSpotY); + void Destroy(); - private: - HICON m_cursor = nullptr; -}; + HCURSOR GetCursor(); + + private: + HICON m_cursor = nullptr; + }; +} #endif // NAZARA_CURSORIMPL_HPP diff --git a/src/Nazara/Utility/Win32/IconImpl.cpp b/src/Nazara/Utility/Win32/IconImpl.cpp index d4b6970bd..0fdbe087b 100644 --- a/src/Nazara/Utility/Win32/IconImpl.cpp +++ b/src/Nazara/Utility/Win32/IconImpl.cpp @@ -7,44 +7,47 @@ #include #include -bool NzIconImpl::Create(const NzImage& icon) +namespace Nz { - NzImage windowsIcon(icon); // Vive le COW - if (!windowsIcon.Convert(nzPixelFormat_BGRA8)) + bool IconImpl::Create(const Image& icon) { - NazaraError("Failed to convert icon to BGRA8"); - return false; + Image windowsIcon(icon); // Vive le COW + if (!windowsIcon.Convert(PixelFormatType_BGRA8)) + { + NazaraError("Failed to convert icon to BGRA8"); + return false; + } + + HBITMAP bitmap = CreateBitmap(windowsIcon.GetWidth(), windowsIcon.GetHeight(), 1, 32, windowsIcon.GetConstPixels()); + HBITMAP monoBitmap = CreateBitmap(windowsIcon.GetWidth(), windowsIcon.GetHeight(), 1, 1, nullptr); + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms648052(v=vs.85).aspx + ICONINFO iconInfo; + iconInfo.fIcon = TRUE; + iconInfo.hbmMask = monoBitmap; + iconInfo.hbmColor = bitmap; + + m_icon = CreateIconIndirect(&iconInfo); + + DeleteObject(bitmap); + DeleteObject(monoBitmap); + + if (!m_icon) + { + NazaraError("Failed to create icon: " + Error::GetLastSystemError()); + return false; + } + + return true; } - HBITMAP bitmap = CreateBitmap(windowsIcon.GetWidth(), windowsIcon.GetHeight(), 1, 32, windowsIcon.GetConstPixels()); - HBITMAP monoBitmap = CreateBitmap(windowsIcon.GetWidth(), windowsIcon.GetHeight(), 1, 1, nullptr); - - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms648052(v=vs.85).aspx - ICONINFO iconInfo; - iconInfo.fIcon = TRUE; - iconInfo.hbmMask = monoBitmap; - iconInfo.hbmColor = bitmap; - - m_icon = CreateIconIndirect(&iconInfo); - - DeleteObject(bitmap); - DeleteObject(monoBitmap); - - if (!m_icon) + void IconImpl::Destroy() { - NazaraError("Failed to create icon: " + NzError::GetLastSystemError()); - return false; + DestroyIcon(m_icon); } - return true; -} - -void NzIconImpl::Destroy() -{ - DestroyIcon(m_icon); -} - -HICON NzIconImpl::GetIcon() -{ - return m_icon; + HICON IconImpl::GetIcon() + { + return m_icon; + } } diff --git a/src/Nazara/Utility/Win32/IconImpl.hpp b/src/Nazara/Utility/Win32/IconImpl.hpp index 7a77a2662..d3539d9f3 100644 --- a/src/Nazara/Utility/Win32/IconImpl.hpp +++ b/src/Nazara/Utility/Win32/IconImpl.hpp @@ -10,18 +10,21 @@ #include #include -class NzImage; - -class NzIconImpl +namespace Nz { - public: - bool Create(const NzImage& image); - void Destroy(); + class Image; - HICON GetIcon(); + class IconImpl + { + public: + bool Create(const Image& image); + void Destroy(); - private: - HICON m_icon = nullptr; -}; + HICON GetIcon(); + + private: + HICON m_icon = nullptr; + }; +} #endif // NAZARA_ICONIMPL_HPP diff --git a/src/Nazara/Utility/Win32/InputImpl.cpp b/src/Nazara/Utility/Win32/InputImpl.cpp index 306f6b6ca..443e38855 100644 --- a/src/Nazara/Utility/Win32/InputImpl.cpp +++ b/src/Nazara/Utility/Win32/InputImpl.cpp @@ -8,286 +8,289 @@ #include #include -namespace +namespace Nz { - int vKeys[NzKeyboard::Count] = { - // Lettres - 0x41, // Key::A - 0x42, // Key::B - 0x43, // Key::C - 0x44, // Key::D - 0x45, // Key::E - 0x46, // Key::F - 0x47, // Key::G - 0x48, // Key::H - 0x49, // Key::I - 0x4A, // Key::J - 0x4B, // Key::K - 0x4C, // Key::L - 0x4D, // Key::M - 0x4E, // Key::N - 0x4F, // Key::O - 0x50, // Key::P - 0x51, // Key::Q - 0x52, // Key::R - 0x53, // Key::S - 0x54, // Key::T - 0x55, // Key::U - 0x56, // Key::V - 0x57, // Key::W - 0x58, // Key::X - 0x59, // Key::Y - 0x5A, // Key::Z - - // Touches de fonction - VK_F1, // Key::F1 - VK_F2, // Key::F2 - VK_F3, // Key::F3 - VK_F4, // Key::F4 - VK_F5, // Key::F5 - VK_F6, // Key::F6 - VK_F7, // Key::F7 - VK_F8, // Key::F8 - VK_F9, // Key::F9 - VK_F10, // Key::F10 - VK_F11, // Key::F11 - VK_F12, // Key::F12 - VK_F13, // Key::F13 - VK_F14, // Key::F14 - VK_F15, // Key::F15 - - // Flèches directionnelles - VK_DOWN, // Key::Down - VK_LEFT, // Key::Left - VK_RIGHT, // Key::Right - VK_UP, // Key::Up - - // Pavé numérique - VK_ADD, // Key::Add - VK_DECIMAL, // Key::Decimal - VK_DIVIDE, // Key::Divide - VK_MULTIPLY, // Key::Multiply - VK_NUMPAD0, // Key::Numpad0 - VK_NUMPAD1, // Key::Numpad1 - VK_NUMPAD2, // Key::Numpad2 - VK_NUMPAD3, // Key::Numpad3 - VK_NUMPAD4, // Key::Numpad4 - VK_NUMPAD5, // Key::Numpad5 - VK_NUMPAD6, // Key::Numpad6 - VK_NUMPAD7, // Key::Numpad7 - VK_NUMPAD8, // Key::Numpad8 - VK_NUMPAD9, // Key::Numpad9 - VK_SUBTRACT, // Key::Subtract - - // Diverss - VK_OEM_5, // Key::Backslash - VK_BACK, // Key::Backspace - VK_CLEAR, // Key::Clear - VK_OEM_COMMA, // Key::Comma, - VK_OEM_MINUS, // Key::Dash - VK_DELETE, // Key::Delete - VK_END, // Key::End - VK_OEM_PLUS, // Key::Equal - VK_ESCAPE, // Key::Escape - VK_HOME, // Key::Home - VK_INSERT, // Key::Insert - VK_LMENU, // Key::LAlt - VK_OEM_4, // Key::LBracket - VK_LCONTROL, // Key::LControl - VK_LSHIFT, // Key::LShift - VK_LWIN, // Key::LSystem - 0x30, // Key::Num0 - 0x31, // Key::Num1 - 0x32, // Key::Num2 - 0x33, // Key::Num3 - 0x34, // Key::Num4 - 0x35, // Key::Num5 - 0x36, // Key::Num6 - 0x37, // Key::Num7 - 0x38, // Key::Num8 - 0x39, // Key::Num9 - VK_NEXT, // Key::PageDown - VK_PRIOR, // Key::PageUp - VK_PAUSE, // Key::Pause - VK_OEM_PERIOD, // Key::Period - VK_PRINT, // Key::Print - VK_SNAPSHOT, // Key::PrintScreen - VK_OEM_7, // Key::Quote - VK_RMENU, // Key::RAlt - VK_OEM_6, // Key::RBracket - VK_RCONTROL, // Key::RControl - VK_RETURN, // Key::Return - VK_RSHIFT, // Key::RShift - VK_RWIN, // Key::RSystem - VK_OEM_1, // Key::Semicolon - VK_OEM_2, // Key::Slash - VK_SPACE, // Key::Space - VK_TAB, // Key::Tab - VK_OEM_3, // Key::Tilde - - // Touches navigateur - VK_BROWSER_BACK, // Key::Browser_Back - VK_BROWSER_FAVORITES, // Key::Browser_Favorites - VK_BROWSER_FORWARD, // Key::Browser_Forward - VK_BROWSER_HOME, // Key::Browser_Home - VK_BROWSER_REFRESH, // Key::Browser_Refresh - VK_BROWSER_SEARCH, // Key::Browser_Search - VK_BROWSER_STOP, // Key::Browser_Stop - - // Touches de contrôle - VK_MEDIA_NEXT_TRACK, // Key::Media_Next, - VK_MEDIA_PLAY_PAUSE, // Key::Media_PlayPause, - VK_MEDIA_PREV_TRACK, // Key::Media_Previous, - VK_MEDIA_STOP, // Key::Media_Stop, - - // Touches de contrôle du volume - VK_VOLUME_DOWN, // Key::Volume_Down - VK_VOLUME_MUTE, // Key::Volume_Mute - VK_VOLUME_UP, // Key::Volume_Up - - // Touches à verrouillage - VK_CAPITAL, // Key::CapsLock - VK_NUMLOCK, // Key::NumLock - VK_SCROLL // Key::ScrollLock - }; -} - -NzString NzEventImpl::GetKeyName(NzKeyboard::Key key) -{ - // http://www.ffuts.org/blog/mapvirtualkey-getkeynametext-and-a-story-of-how-to/ - int vk = vKeys[key]; - unsigned int code = MapVirtualKeyW(vk, 0) << 16; - - ///FIXME: Liste complète ? - switch (vk) + namespace { - case VK_ATTN: - case VK_DOWN: - case VK_DECIMAL: - case VK_DELETE: - case VK_DIVIDE: - case VK_END: - case VK_HOME: - case VK_INSERT: - case VK_LEFT: - case VK_LWIN: - case VK_OEM_1: - case VK_OEM_2: - case VK_OEM_3: - case VK_OEM_4: - case VK_OEM_5: - case VK_OEM_6: - case VK_OEM_7: - case VK_OEM_CLEAR: - case VK_OEM_COMMA: - case VK_OEM_MINUS: - case VK_OEM_PERIOD: - case VK_OEM_PLUS: - case VK_PAUSE: - case VK_NEXT: - case VK_NUMLOCK: - case VK_PRIOR: - case VK_RIGHT: - case VK_RWIN: - case VK_UP: - code |= 0x1000000; // 24ème bit pour l'extension - break; + int vKeys[Keyboard::Count] = { + // Lettres + 0x41, // Key::A + 0x42, // Key::B + 0x43, // Key::C + 0x44, // Key::D + 0x45, // Key::E + 0x46, // Key::F + 0x47, // Key::G + 0x48, // Key::H + 0x49, // Key::I + 0x4A, // Key::J + 0x4B, // Key::K + 0x4C, // Key::L + 0x4D, // Key::M + 0x4E, // Key::N + 0x4F, // Key::O + 0x50, // Key::P + 0x51, // Key::Q + 0x52, // Key::R + 0x53, // Key::S + 0x54, // Key::T + 0x55, // Key::U + 0x56, // Key::V + 0x57, // Key::W + 0x58, // Key::X + 0x59, // Key::Y + 0x5A, // Key::Z + + // Touches de fonction + VK_F1, // Key::F1 + VK_F2, // Key::F2 + VK_F3, // Key::F3 + VK_F4, // Key::F4 + VK_F5, // Key::F5 + VK_F6, // Key::F6 + VK_F7, // Key::F7 + VK_F8, // Key::F8 + VK_F9, // Key::F9 + VK_F10, // Key::F10 + VK_F11, // Key::F11 + VK_F12, // Key::F12 + VK_F13, // Key::F13 + VK_F14, // Key::F14 + VK_F15, // Key::F15 + + // Flèches directionnelles + VK_DOWN, // Key::Down + VK_LEFT, // Key::Left + VK_RIGHT, // Key::Right + VK_UP, // Key::Up + + // Pavé numérique + VK_ADD, // Key::Add + VK_DECIMAL, // Key::Decimal + VK_DIVIDE, // Key::Divide + VK_MULTIPLY, // Key::Multiply + VK_NUMPAD0, // Key::Numpad0 + VK_NUMPAD1, // Key::Numpad1 + VK_NUMPAD2, // Key::Numpad2 + VK_NUMPAD3, // Key::Numpad3 + VK_NUMPAD4, // Key::Numpad4 + VK_NUMPAD5, // Key::Numpad5 + VK_NUMPAD6, // Key::Numpad6 + VK_NUMPAD7, // Key::Numpad7 + VK_NUMPAD8, // Key::Numpad8 + VK_NUMPAD9, // Key::Numpad9 + VK_SUBTRACT, // Key::Subtract + + // Diverss + VK_OEM_5, // Key::Backslash + VK_BACK, // Key::Backspace + VK_CLEAR, // Key::Clear + VK_OEM_COMMA, // Key::Comma, + VK_OEM_MINUS, // Key::Dash + VK_DELETE, // Key::Delete + VK_END, // Key::End + VK_OEM_PLUS, // Key::Equal + VK_ESCAPE, // Key::Escape + VK_HOME, // Key::Home + VK_INSERT, // Key::Insert + VK_LMENU, // Key::LAlt + VK_OEM_4, // Key::LBracket + VK_LCONTROL, // Key::LControl + VK_LSHIFT, // Key::LShift + VK_LWIN, // Key::LSystem + 0x30, // Key::Num0 + 0x31, // Key::Num1 + 0x32, // Key::Num2 + 0x33, // Key::Num3 + 0x34, // Key::Num4 + 0x35, // Key::Num5 + 0x36, // Key::Num6 + 0x37, // Key::Num7 + 0x38, // Key::Num8 + 0x39, // Key::Num9 + VK_NEXT, // Key::PageDown + VK_PRIOR, // Key::PageUp + VK_PAUSE, // Key::Pause + VK_OEM_PERIOD, // Key::Period + VK_PRINT, // Key::Print + VK_SNAPSHOT, // Key::PrintScreen + VK_OEM_7, // Key::Quote + VK_RMENU, // Key::RAlt + VK_OEM_6, // Key::RBracket + VK_RCONTROL, // Key::RControl + VK_RETURN, // Key::Return + VK_RSHIFT, // Key::RShift + VK_RWIN, // Key::RSystem + VK_OEM_1, // Key::Semicolon + VK_OEM_2, // Key::Slash + VK_SPACE, // Key::Space + VK_TAB, // Key::Tab + VK_OEM_3, // Key::Tilde + + // Touches navigateur + VK_BROWSER_BACK, // Key::Browser_Back + VK_BROWSER_FAVORITES, // Key::Browser_Favorites + VK_BROWSER_FORWARD, // Key::Browser_Forward + VK_BROWSER_HOME, // Key::Browser_Home + VK_BROWSER_REFRESH, // Key::Browser_Refresh + VK_BROWSER_SEARCH, // Key::Browser_Search + VK_BROWSER_STOP, // Key::Browser_Stop + + // Touches de contrôle + VK_MEDIA_NEXT_TRACK, // Key::Media_Next, + VK_MEDIA_PLAY_PAUSE, // Key::Media_PlayPause, + VK_MEDIA_PREV_TRACK, // Key::Media_Previous, + VK_MEDIA_STOP, // Key::Media_Stop, + + // Touches de contrôle du volume + VK_VOLUME_DOWN, // Key::Volume_Down + VK_VOLUME_MUTE, // Key::Volume_Mute + VK_VOLUME_UP, // Key::Volume_Up + + // Touches à verrouillage + VK_CAPITAL, // Key::CapsLock + VK_NUMLOCK, // Key::NumLock + VK_SCROLL // Key::ScrollLock + }; } - wchar_t keyName[20]; // Je ne pense pas que ça dépassera 20 caractères - if (!GetKeyNameTextW(code, &keyName[0], 20)) - return "Unknown"; + String EventImpl::GetKeyName(Keyboard::Key key) + { + // http://www.ffuts.org/blog/mapvirtualkey-getkeynametext-and-a-story-of-how-to/ + int vk = vKeys[key]; + unsigned int code = MapVirtualKeyW(vk, 0) << 16; - return NzString::Unicode(keyName); -} + ///FIXME: Liste complète ? + switch (vk) + { + case VK_ATTN: + case VK_DOWN: + case VK_DECIMAL: + case VK_DELETE: + case VK_DIVIDE: + case VK_END: + case VK_HOME: + case VK_INSERT: + case VK_LEFT: + case VK_LWIN: + case VK_OEM_1: + case VK_OEM_2: + case VK_OEM_3: + case VK_OEM_4: + case VK_OEM_5: + case VK_OEM_6: + case VK_OEM_7: + case VK_OEM_CLEAR: + case VK_OEM_COMMA: + case VK_OEM_MINUS: + case VK_OEM_PERIOD: + case VK_OEM_PLUS: + case VK_PAUSE: + case VK_NEXT: + case VK_NUMLOCK: + case VK_PRIOR: + case VK_RIGHT: + case VK_RWIN: + case VK_UP: + code |= 0x1000000; // 24ème bit pour l'extension + break; + } -NzVector2i NzEventImpl::GetMousePosition() -{ - POINT pos; - GetCursorPos(&pos); + wchar_t keyName[20]; // Je ne pense pas que ça dépassera 20 caractères + if (!GetKeyNameTextW(code, &keyName[0], 20)) + return "Unknown"; - return NzVector2i(pos.x, pos.y); -} + return String::Unicode(keyName); + } -NzVector2i NzEventImpl::GetMousePosition(const NzWindow& relativeTo) -{ - HWND handle = reinterpret_cast(relativeTo.GetHandle()); - if (handle) + Vector2i EventImpl::GetMousePosition() { POINT pos; GetCursorPos(&pos); - ScreenToClient(handle, &pos); - return NzVector2i(pos.x, pos.y); + return Vector2i(pos.x, pos.y); } - else + + Vector2i EventImpl::GetMousePosition(const Window& relativeTo) { - NazaraError("Invalid window handle"); - - // Attention que (-1, -1) est une position tout à fait valide et ne doit pas servir de test - return NzVector2i(-1, -1); - } -} - -bool NzEventImpl::IsKeyPressed(NzKeyboard::Key key) -{ - switch (key) - { - case NzKeyboard::CapsLock: - case NzKeyboard::NumLock: - case NzKeyboard::ScrollLock: - return GetKeyState(vKeys[key]) != 0; - - default: - return (GetAsyncKeyState(vKeys[key]) & 0x8000) != 0; - } -} - -bool NzEventImpl::IsMouseButtonPressed(NzMouse::Button button) -{ - static int vButtons[NzMouse::Max+1] = { - VK_LBUTTON, // Button::Left - VK_MBUTTON, // Button::Middle - VK_RBUTTON, // Button::Right - VK_XBUTTON1, // Button::XButton1 - VK_XBUTTON2 // Button::XButton2 - }; - - // Gestion de l'inversement des boutons de la souris - if (GetSystemMetrics(SM_SWAPBUTTON)) - { - switch (button) + HWND handle = reinterpret_cast(relativeTo.GetHandle()); + if (handle) { - case NzMouse::Left: - button = NzMouse::Right; - break; + POINT pos; + GetCursorPos(&pos); + ScreenToClient(handle, &pos); - case NzMouse::Right: - button = NzMouse::Left; - break; + return Vector2i(pos.x, pos.y); + } + else + { + NazaraError("Invalid window handle"); - default: - break; + // Attention que (-1, -1) est une position tout à fait valide et ne doit pas servir de test + return Vector2i(-1, -1); } } - return (GetAsyncKeyState(vButtons[button]) & 0x8000) != 0; -} - -void NzEventImpl::SetMousePosition(int x, int y) -{ - SetCursorPos(x, y); -} - -void NzEventImpl::SetMousePosition(int x, int y, const NzWindow& relativeTo) -{ - HWND handle = reinterpret_cast(relativeTo.GetHandle()); - if (handle) + bool EventImpl::IsKeyPressed(Keyboard::Key key) { - POINT pos = {x, y}; - ClientToScreen(handle, &pos); - SetCursorPos(pos.x, pos.y); + switch (key) + { + case Keyboard::CapsLock: + case Keyboard::NumLock: + case Keyboard::ScrollLock: + return GetKeyState(vKeys[key]) != 0; + + default: + return (GetAsyncKeyState(vKeys[key]) & 0x8000) != 0; + } } - else - NazaraError("Invalid window handle"); + + bool EventImpl::IsMouseButtonPressed(Mouse::Button button) + { + static int vButtons[Mouse::Max+1] = { + VK_LBUTTON, // Button::Left + VK_MBUTTON, // Button::Middle + VK_RBUTTON, // Button::Right + VK_XBUTTON1, // Button::XButton1 + VK_XBUTTON2 // Button::XButton2 + }; + + // Gestion de l'inversement des boutons de la souris + if (GetSystemMetrics(SM_SWAPBUTTON)) + { + switch (button) + { + case Mouse::Left: + button = Mouse::Right; + break; + + case Mouse::Right: + button = Mouse::Left; + break; + + default: + break; + } + } + + return (GetAsyncKeyState(vButtons[button]) & 0x8000) != 0; + } + + void EventImpl::SetMousePosition(int x, int y) + { + SetCursorPos(x, y); + } + + void EventImpl::SetMousePosition(int x, int y, const Window& relativeTo) + { + HWND handle = reinterpret_cast(relativeTo.GetHandle()); + if (handle) + { + POINT pos = {x, y}; + ClientToScreen(handle, &pos); + SetCursorPos(pos.x, pos.y); + } + else + NazaraError("Invalid window handle"); + } } diff --git a/src/Nazara/Utility/Win32/InputImpl.hpp b/src/Nazara/Utility/Win32/InputImpl.hpp index 0d3f3fb19..b2a0a9302 100644 --- a/src/Nazara/Utility/Win32/InputImpl.hpp +++ b/src/Nazara/Utility/Win32/InputImpl.hpp @@ -12,16 +12,19 @@ #include #include -class NzEventImpl +namespace Nz { - public: - static NzString GetKeyName(NzKeyboard::Key key); - static NzVector2i GetMousePosition(); - static NzVector2i GetMousePosition(const NzWindow& relativeTo); - static bool IsKeyPressed(NzKeyboard::Key key); - static bool IsMouseButtonPressed(NzMouse::Button button); - static void SetMousePosition(int x, int y); - static void SetMousePosition(int x, int y, const NzWindow& relativeTo); -}; + class EventImpl + { + public: + static String GetKeyName(Keyboard::Key key); + static Vector2i GetMousePosition(); + static Vector2i GetMousePosition(const Window& relativeTo); + static bool IsKeyPressed(Keyboard::Key key); + static bool IsMouseButtonPressed(Mouse::Button button); + static void SetMousePosition(int x, int y); + static void SetMousePosition(int x, int y, const Window& relativeTo); + }; +} #endif // NAZARA_INPUTIMPL_HPP diff --git a/src/Nazara/Utility/Win32/VideoModeImpl.cpp b/src/Nazara/Utility/Win32/VideoModeImpl.cpp index c9b1d8489..ab9fe3430 100644 --- a/src/Nazara/Utility/Win32/VideoModeImpl.cpp +++ b/src/Nazara/Utility/Win32/VideoModeImpl.cpp @@ -8,25 +8,28 @@ #include #include -NzVideoMode NzVideoModeImpl::GetDesktopMode() +namespace Nz { - DEVMODE mode; - mode.dmSize = sizeof(DEVMODE); - EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &mode); - - return NzVideoMode(mode.dmPelsWidth, mode.dmPelsHeight, static_cast(mode.dmBitsPerPel)); -} - -void NzVideoModeImpl::GetFullscreenModes(std::vector& modes) -{ - DEVMODE win32Mode; - win32Mode.dmSize = sizeof(DEVMODE); - for (unsigned int i = 0; EnumDisplaySettings(nullptr, i, &win32Mode); ++i) + VideoMode VideoModeImpl::GetDesktopMode() { - NzVideoMode mode(win32Mode.dmPelsWidth, win32Mode.dmPelsHeight, static_cast(win32Mode.dmBitsPerPel)); + DEVMODE mode; + mode.dmSize = sizeof(DEVMODE); + EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &mode); - // Il existe plusieurs modes avec ces trois caractéristques identiques - if (std::find(modes.begin(), modes.end(), mode) == modes.end()) - modes.push_back(mode); + return VideoMode(mode.dmPelsWidth, mode.dmPelsHeight, static_cast(mode.dmBitsPerPel)); } + + void VideoModeImpl::GetFullscreenModes(std::vector& modes) + { + DEVMODE win32Mode; + win32Mode.dmSize = sizeof(DEVMODE); + for (unsigned int i = 0; EnumDisplaySettings(nullptr, i, &win32Mode); ++i) + { + VideoMode mode(win32Mode.dmPelsWidth, win32Mode.dmPelsHeight, static_cast(win32Mode.dmBitsPerPel)); + + // Il existe plusieurs modes avec ces trois caractéristques identiques + if (std::find(modes.begin(), modes.end(), mode) == modes.end()) + modes.push_back(mode); + } +} } diff --git a/src/Nazara/Utility/Win32/VideoModeImpl.hpp b/src/Nazara/Utility/Win32/VideoModeImpl.hpp index 3a53f5e94..722553305 100644 --- a/src/Nazara/Utility/Win32/VideoModeImpl.hpp +++ b/src/Nazara/Utility/Win32/VideoModeImpl.hpp @@ -9,11 +9,14 @@ #include -class NzVideoModeImpl +namespace Nz { - public: - static NzVideoMode GetDesktopMode(); - static void GetFullscreenModes(std::vector& modes); -}; + class VideoModeImpl + { + public: + static VideoMode GetDesktopMode(); + static void GetFullscreenModes(std::vector& modes); + }; +} #endif // NNAZARA_VIDEOMODEIMPL_HPP diff --git a/src/Nazara/Utility/Win32/WindowImpl.cpp b/src/Nazara/Utility/Win32/WindowImpl.cpp index 53d891e22..e910e8acc 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.cpp +++ b/src/Nazara/Utility/Win32/WindowImpl.cpp @@ -34,704 +34,724 @@ #undef IsMinimized // Conflit avec la méthode du même nom -namespace +namespace Nz { - LPTSTR windowsCursors[] = + namespace { - IDC_CROSS, // nzWindowCursor_Crosshair - IDC_ARROW, // nzWindowCursor_Default - IDC_HAND, // nzWindowCursor_Hand - IDC_HAND, // nzWindowCursor_Pointer - IDC_HELP, // nzWindowCursor_Help - IDC_SIZEALL, // nzWindowCursor_Move - nullptr, // nzWindowCursor_None - IDC_APPSTARTING, // nzWindowCursor_Progress - IDC_SIZENS, // nzWindowCursor_ResizeN - IDC_SIZENS, // nzWindowCursor_ResizeS - IDC_SIZENWSE, // nzWindowCursor_ResizeNW - IDC_SIZENWSE, // nzWindowCursor_ResizeSE - IDC_SIZENESW, // nzWindowCursor_ResizeNE - IDC_SIZENESW, // nzWindowCursor_ResizeSW - IDC_SIZEWE, // nzWindowCursor_ResizeE - IDC_SIZEWE, // nzWindowCursor_ResizeW - IDC_IBEAM, // nzWindowCursor_Text - IDC_WAIT // nzWindowCursor_Wait - }; - - static_assert(sizeof(windowsCursors)/sizeof(LPTSTR) == nzWindowCursor_Max+1, "Cursor type array is incomplete"); - - const wchar_t* className = L"Nazara Window"; - NzWindowImpl* fullscreenWindow = nullptr; -} - -NzWindowImpl::NzWindowImpl(NzWindow* parent) : -m_cursor(nullptr), -m_handle(nullptr), -m_callback(0), -m_style(0), -m_maxSize(-1), -m_minSize(-1), -m_parent(parent), -m_keyRepeat(true), -m_mouseInside(false), -m_smoothScrolling(false), -m_scrolling(0) -{ -} - -bool NzWindowImpl::Create(const NzVideoMode& mode, const NzString& title, nzUInt32 style) -{ - bool fullscreen = (style & nzWindowStyle_Fullscreen) != 0; - DWORD win32Style, win32StyleEx; - unsigned int x, y; - unsigned int width = mode.width; - unsigned int height = mode.height; - if (fullscreen) - { - DEVMODE win32Mode; - std::memset(&win32Mode, 0, sizeof(DEVMODE)); - win32Mode.dmBitsPerPel = mode.bitsPerPixel; - win32Mode.dmPelsHeight = mode.height; - win32Mode.dmPelsWidth = mode.width; - win32Mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; - win32Mode.dmSize = sizeof(DEVMODE); - - if (ChangeDisplaySettings(&win32Mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) + LPTSTR windowsCursors[] = { - // Situation extrêmement rare grâce à NzVideoMode::IsValid appelé par NzWindow - NazaraError("Failed to change display settings for fullscreen, this video mode is not supported by your computer"); - fullscreen = false; + IDC_CROSS, // WindowCursor_Crosshair + IDC_ARROW, // WindowCursor_Default + IDC_HAND, // WindowCursor_Hand + IDC_HAND, // WindowCursor_Pointer + IDC_HELP, // WindowCursor_Help + IDC_SIZEALL, // WindowCursor_Move + nullptr, // WindowCursor_None + IDC_APPSTARTING, // WindowCursor_Progress + IDC_SIZENS, // WindowCursor_ResizeN + IDC_SIZENS, // WindowCursor_ResizeS + IDC_SIZENWSE, // WindowCursor_ResizeNW + IDC_SIZENWSE, // WindowCursor_ResizeSE + IDC_SIZENESW, // WindowCursor_ResizeNE + IDC_SIZENESW, // WindowCursor_ResizeSW + IDC_SIZEWE, // WindowCursor_ResizeE + IDC_SIZEWE, // WindowCursor_ResizeW + IDC_IBEAM, // WindowCursor_Text + IDC_WAIT // WindowCursor_Wait + }; + + static_assert(sizeof(windowsCursors)/sizeof(LPTSTR) == WindowCursor_Max+1, "Cursor type array is incomplete"); + + const wchar_t* className = L"Nazara Window"; + WindowImpl* fullscreenWindow = nullptr; + } + + WindowImpl::WindowImpl(Window* parent) : + m_cursor(nullptr), + m_handle(nullptr), + m_callback(0), + m_style(0), + m_maxSize(-1), + m_minSize(-1), + m_parent(parent), + m_keyRepeat(true), + m_mouseInside(false), + m_smoothScrolling(false), + m_scrolling(0) + { + } + + bool WindowImpl::Create(const VideoMode& mode, const String& title, UInt32 style) + { + bool fullscreen = (style & WindowStyle_Fullscreen) != 0; + DWORD win32Style, win32StyleEx; + unsigned int x, y; + unsigned int width = mode.width; + unsigned int height = mode.height; + if (fullscreen) + { + DEVMODE win32Mode; + std::memset(&win32Mode, 0, sizeof(DEVMODE)); + win32Mode.dmBitsPerPel = mode.bitsPerPixel; + win32Mode.dmPelsHeight = mode.height; + win32Mode.dmPelsWidth = mode.width; + win32Mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + win32Mode.dmSize = sizeof(DEVMODE); + + if (ChangeDisplaySettings(&win32Mode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) + { + // Situation extrêmement rare grâce à VideoMode::IsValid appelé par Window + NazaraError("Failed to change display settings for fullscreen, this video mode is not supported by your computer"); + fullscreen = false; + } } - } - // Testé une seconde fois car sa valeur peut changer - if (fullscreen) - { - x = 0; - y = 0; - win32Style = WS_CLIPCHILDREN | WS_POPUP; - - // Pour cacher la barre des tâches - // http://msdn.microsoft.com/en-us/library/windows/desktop/ff700543(v=vs.85).aspx - win32StyleEx = WS_EX_APPWINDOW; - - fullscreenWindow = this; - } - else - { - win32Style = WS_VISIBLE; - if (style & nzWindowStyle_Titlebar) + // Testé une seconde fois car sa valeur peut changer + if (fullscreen) { - win32Style |= WS_CAPTION | WS_MINIMIZEBOX; - if (style & nzWindowStyle_Closable) - win32Style |= WS_SYSMENU; + x = 0; + y = 0; + win32Style = WS_CLIPCHILDREN | WS_POPUP; - if (style & nzWindowStyle_Resizable) - win32Style |= WS_MAXIMIZEBOX | WS_SIZEBOX; + // Pour cacher la barre des tâches + // http://msdn.microsoft.com/en-us/library/windows/desktop/ff700543(v=vs.85).aspx + win32StyleEx = WS_EX_APPWINDOW; + + fullscreenWindow = this; } else - win32Style |= WS_POPUP; + { + win32Style = WS_VISIBLE; + if (style & WindowStyle_Titlebar) + { + win32Style |= WS_CAPTION | WS_MINIMIZEBOX; + if (style & WindowStyle_Closable) + win32Style |= WS_SYSMENU; - win32StyleEx = 0; + if (style & WindowStyle_Resizable) + win32Style |= WS_MAXIMIZEBOX | WS_SIZEBOX; + } + else + win32Style |= WS_POPUP; - RECT rect = {0, 0, static_cast(width), static_cast(height)}; - AdjustWindowRect(&rect, win32Style, false); - width = rect.right-rect.left; - height = rect.bottom-rect.top; + win32StyleEx = 0; - x = (GetSystemMetrics(SM_CXSCREEN) - width)/2; - y = (GetSystemMetrics(SM_CYSCREEN) - height)/2; + RECT rect = {0, 0, static_cast(width), static_cast(height)}; + AdjustWindowRect(&rect, win32Style, false); + width = rect.right-rect.left; + height = rect.bottom-rect.top; + + x = (GetSystemMetrics(SM_CXSCREEN) - width)/2; + y = (GetSystemMetrics(SM_CYSCREEN) - height)/2; + } + + m_callback = 0; + + #if NAZARA_UTILITY_THREADED_WINDOW + Mutex mutex; + ConditionVariable condition; + m_threadActive = true; + + // On attend que la fenêtre soit créée + mutex.Lock(); + m_thread = Thread(WindowThread, &m_handle, win32StyleEx, title.GetWideString().data(), win32Style, x, y, width, height, this, &mutex, &condition); + condition.Wait(&mutex); + mutex.Unlock(); + #else + m_handle = CreateWindowExW(win32StyleEx, className, title.GetWideString().data(), win32Style, x, y, width, height, nullptr, nullptr, GetModuleHandle(nullptr), this); + #endif + + if (!m_handle) + { + NazaraError("Failed to create window: " + Error::GetLastSystemError()); + return false; + } + + if (fullscreen) + { + SetForegroundWindow(m_handle); + ShowWindow(m_handle, SW_SHOW); + } + + m_eventListener = true; + m_ownsWindow = true; + #if !NAZARA_UTILITY_THREADED_WINDOW + m_sizemove = false; + #endif + m_style = style; + + // Récupération de la position/taille de la fenêtre (Après sa création) + RECT clientRect, windowRect; + GetClientRect(m_handle, &clientRect); + GetWindowRect(m_handle, &windowRect); + + m_position.Set(windowRect.left, windowRect.top); + m_size.Set(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top); + + return true; } - m_callback = 0; - - #if NAZARA_UTILITY_THREADED_WINDOW - NzMutex mutex; - NzConditionVariable condition; - m_threadActive = true; - - // On attend que la fenêtre soit créée - mutex.Lock(); - m_thread = NzThread(WindowThread, &m_handle, win32StyleEx, title.GetWideString().data(), win32Style, x, y, width, height, this, &mutex, &condition); - condition.Wait(&mutex); - mutex.Unlock(); - #else - m_handle = CreateWindowExW(win32StyleEx, className, title.GetWideString().data(), win32Style, x, y, width, height, nullptr, nullptr, GetModuleHandle(nullptr), this); - #endif - - if (!m_handle) + bool WindowImpl::Create(WindowHandle handle) { - NazaraError("Failed to create window: " + NzError::GetLastSystemError()); - return false; + m_handle = reinterpret_cast(handle); + + if (!m_handle || !IsWindow(m_handle)) + { + NazaraError("Invalid handle"); + return false; + } + + m_eventListener = false; + m_ownsWindow = false; + #if !NAZARA_UTILITY_THREADED_WINDOW + m_sizemove = false; + #endif + m_style = RetrieveStyle(m_handle); + + RECT clientRect, windowRect; + GetClientRect(m_handle, &clientRect); + GetWindowRect(m_handle, &windowRect); + + m_position.Set(windowRect.left, windowRect.top); + m_size.Set(clientRect.right-clientRect.left, clientRect.bottom-clientRect.top); + + return true; } - if (fullscreen) + void WindowImpl::Destroy() + { + if (m_ownsWindow) + { + #if NAZARA_UTILITY_THREADED_WINDOW + if (m_thread.IsJoinable()) + { + m_threadActive = false; + PostMessageW(m_handle, WM_NULL, 0, 0); // Pour réveiller le thread + + m_thread.Join(); + } + #else + if (m_handle) + DestroyWindow(m_handle); + #endif + } + else + SetEventListener(false); + } + + void WindowImpl::EnableKeyRepeat(bool enable) + { + m_keyRepeat = enable; + } + + void WindowImpl::EnableSmoothScrolling(bool enable) + { + m_smoothScrolling = enable; + } + + WindowHandle WindowImpl::GetHandle() const + { + return m_handle; + } + + unsigned int WindowImpl::GetHeight() const + { + return m_size.y; + } + + Vector2i WindowImpl::GetPosition() const + { + return m_position; + } + + Vector2ui WindowImpl::GetSize() const + { + return m_size; + } + + UInt32 WindowImpl::GetStyle() const + { + return m_style; + } + + String WindowImpl::GetTitle() const + { + unsigned int titleSize = GetWindowTextLengthW(m_handle); + if (titleSize == 0) + return String(); + + titleSize++; // Caractère nul + + std::unique_ptr wTitle(new wchar_t[titleSize]); + GetWindowTextW(m_handle, wTitle.get(), titleSize); + + return String::Unicode(wTitle.get()); + } + + unsigned int WindowImpl::GetWidth() const + { + return m_size.x; + } + + bool WindowImpl::HasFocus() const + { + return GetForegroundWindow() == m_handle; + } + + void WindowImpl::IgnoreNextMouseEvent(int mouseX, int mouseY) + { + // Petite astuce ... + m_mousePos.x = mouseX; + m_mousePos.y = mouseY; + } + + bool WindowImpl::IsMinimized() const + { + return IsIconic(m_handle) == TRUE; + } + + bool WindowImpl::IsVisible() const + { + return IsWindowVisible(m_handle) == TRUE; + } + + void WindowImpl::ProcessEvents(bool block) + { + if (m_ownsWindow) + { + if (block) + WaitMessage(); + + MSG message; + while (PeekMessageW(&message, nullptr, 0, 0, PM_REMOVE)) + { + TranslateMessage(&message); + DispatchMessageW(&message); + } + } + } + + void WindowImpl::SetCursor(WindowCursor cursor) + { + #ifdef NAZARA_DEBUG + if (cursor > WindowCursor_Max) + { + NazaraError("Window cursor out of enum"); + return; + } + #endif + + if (cursor != WindowCursor_None) + m_cursor = reinterpret_cast(LoadImage(nullptr, windowsCursors[cursor], IMAGE_CURSOR, 0, 0, LR_SHARED)); + else + m_cursor = nullptr; + + // Pas besoin de libérer le curseur par la suite s'il est partagé + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx + ::SetCursor(m_cursor); + } + + void WindowImpl::SetCursor(const Cursor& cursor) + { + m_cursor = cursor.m_impl->GetCursor(); + + ::SetCursor(m_cursor); + } + + void WindowImpl::SetEventListener(bool listener) + { + if (m_ownsWindow) + m_eventListener = listener; + else if (listener != m_eventListener) + { + if (listener) + { + SetWindowLongPtr(m_handle, GWLP_USERDATA, reinterpret_cast(this)); + m_callback = SetWindowLongPtr(m_handle, GWLP_WNDPROC, reinterpret_cast(MessageHandler)); + m_eventListener = true; + } + else if (m_eventListener) + { + SetWindowLongPtr(m_handle, GWLP_WNDPROC, m_callback); + m_eventListener = false; + } + } + } + + void WindowImpl::SetFocus() { SetForegroundWindow(m_handle); - ShowWindow(m_handle, SW_SHOW); } - m_eventListener = true; - m_ownsWindow = true; - #if !NAZARA_UTILITY_THREADED_WINDOW - m_sizemove = false; - #endif - m_style = style; - - // Récupération de la position/taille de la fenêtre (Après sa création) - RECT clientRect, windowRect; - GetClientRect(m_handle, &clientRect); - GetWindowRect(m_handle, &windowRect); - - m_position.Set(windowRect.left, windowRect.top); - m_size.Set(clientRect.right - clientRect.left, clientRect.bottom - clientRect.top); - - return true; -} - -bool NzWindowImpl::Create(NzWindowHandle handle) -{ - m_handle = reinterpret_cast(handle); - - if (!m_handle || !IsWindow(m_handle)) + void WindowImpl::SetIcon(const Icon& icon) { - NazaraError("Invalid handle"); - return false; + HICON iconHandle = icon.m_impl->GetIcon(); + + SendMessage(m_handle, WM_SETICON, ICON_BIG, reinterpret_cast(iconHandle)); + SendMessage(m_handle, WM_SETICON, ICON_SMALL, reinterpret_cast(iconHandle)); } - m_eventListener = false; - m_ownsWindow = false; - #if !NAZARA_UTILITY_THREADED_WINDOW - m_sizemove = false; - #endif - m_style = RetrieveStyle(m_handle); - - RECT clientRect, windowRect; - GetClientRect(m_handle, &clientRect); - GetWindowRect(m_handle, &windowRect); - - m_position.Set(windowRect.left, windowRect.top); - m_size.Set(clientRect.right-clientRect.left, clientRect.bottom-clientRect.top); - - return true; -} - -void NzWindowImpl::Destroy() -{ - if (m_ownsWindow) + void WindowImpl::SetMaximumSize(int width, int height) { - #if NAZARA_UTILITY_THREADED_WINDOW - if (m_thread.IsJoinable()) - { - m_threadActive = false; - PostMessageW(m_handle, WM_NULL, 0, 0); // Pour réveiller le thread + RECT rect = {0, 0, width, height}; + AdjustWindowRect(&rect, GetWindowLongPtr(m_handle, GWL_STYLE), false); - m_thread.Join(); - } - #else - if (m_handle) - DestroyWindow(m_handle); - #endif - } - else - SetEventListener(false); -} + if (width != -1) + m_maxSize.x = rect.right-rect.left; + else + m_maxSize.x = -1; -void NzWindowImpl::EnableKeyRepeat(bool enable) -{ - m_keyRepeat = enable; -} - -void NzWindowImpl::EnableSmoothScrolling(bool enable) -{ - m_smoothScrolling = enable; -} - -NzWindowHandle NzWindowImpl::GetHandle() const -{ - return m_handle; -} - -unsigned int NzWindowImpl::GetHeight() const -{ - return m_size.y; -} - -NzVector2i NzWindowImpl::GetPosition() const -{ - return m_position; -} - -NzVector2ui NzWindowImpl::GetSize() const -{ - return m_size; -} - -nzUInt32 NzWindowImpl::GetStyle() const -{ - return m_style; -} - -NzString NzWindowImpl::GetTitle() const -{ - unsigned int titleSize = GetWindowTextLengthW(m_handle); - if (titleSize == 0) - return NzString(); - - titleSize++; // Caractère nul - - std::unique_ptr wTitle(new wchar_t[titleSize]); - GetWindowTextW(m_handle, wTitle.get(), titleSize); - - return NzString::Unicode(wTitle.get()); -} - -unsigned int NzWindowImpl::GetWidth() const -{ - return m_size.x; -} - -bool NzWindowImpl::HasFocus() const -{ - return GetForegroundWindow() == m_handle; -} - -void NzWindowImpl::IgnoreNextMouseEvent(int mouseX, int mouseY) -{ - // Petite astuce ... - m_mousePos.x = mouseX; - m_mousePos.y = mouseY; -} - -bool NzWindowImpl::IsMinimized() const -{ - return IsIconic(m_handle) == TRUE; -} - -bool NzWindowImpl::IsVisible() const -{ - return IsWindowVisible(m_handle) == TRUE; -} - -void NzWindowImpl::ProcessEvents(bool block) -{ - if (m_ownsWindow) - { - if (block) - WaitMessage(); - - MSG message; - while (PeekMessageW(&message, nullptr, 0, 0, PM_REMOVE)) - { - TranslateMessage(&message); - DispatchMessageW(&message); - } - } -} - -void NzWindowImpl::SetCursor(nzWindowCursor cursor) -{ - #ifdef NAZARA_DEBUG - if (cursor > nzWindowCursor_Max) - { - NazaraError("Window cursor out of enum"); - return; - } - #endif - - if (cursor != nzWindowCursor_None) - m_cursor = reinterpret_cast(LoadImage(nullptr, windowsCursors[cursor], IMAGE_CURSOR, 0, 0, LR_SHARED)); - else - m_cursor = nullptr; - - // Pas besoin de libérer le curseur par la suite s'il est partagé - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx - ::SetCursor(m_cursor); -} - -void NzWindowImpl::SetCursor(const NzCursor& cursor) -{ - m_cursor = cursor.m_impl->GetCursor(); - - ::SetCursor(m_cursor); -} - -void NzWindowImpl::SetEventListener(bool listener) -{ - if (m_ownsWindow) - m_eventListener = listener; - else if (listener != m_eventListener) - { - if (listener) - { - SetWindowLongPtr(m_handle, GWLP_USERDATA, reinterpret_cast(this)); - m_callback = SetWindowLongPtr(m_handle, GWLP_WNDPROC, reinterpret_cast(MessageHandler)); - m_eventListener = true; - } - else if (m_eventListener) - { - SetWindowLongPtr(m_handle, GWLP_WNDPROC, m_callback); - m_eventListener = false; - } - } -} - -void NzWindowImpl::SetFocus() -{ - SetForegroundWindow(m_handle); -} - -void NzWindowImpl::SetIcon(const NzIcon& icon) -{ - HICON iconHandle = icon.m_impl->GetIcon(); - - SendMessage(m_handle, WM_SETICON, ICON_BIG, reinterpret_cast(iconHandle)); - SendMessage(m_handle, WM_SETICON, ICON_SMALL, reinterpret_cast(iconHandle)); -} - -void NzWindowImpl::SetMaximumSize(int width, int height) -{ - RECT rect = {0, 0, width, height}; - AdjustWindowRect(&rect, GetWindowLongPtr(m_handle, GWL_STYLE), false); - - if (width != -1) - m_maxSize.x = rect.right-rect.left; - else - m_maxSize.x = -1; - - if (height != -1) - m_maxSize.y = rect.bottom-rect.top; - else - m_maxSize.y = -1; -} - -void NzWindowImpl::SetMinimumSize(int width, int height) -{ - RECT rect = {0, 0, width, height}; - AdjustWindowRect(&rect, GetWindowLongPtr(m_handle, GWL_STYLE), false); - - if (width != -1) - m_minSize.x = rect.right-rect.left; - else - m_minSize.x = -1; - - if (height != -1) - m_minSize.y = rect.bottom-rect.top; - else - m_minSize.y = -1; -} - -void NzWindowImpl::SetPosition(int x, int y) -{ - SetWindowPos(m_handle, nullptr, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); -} - -void NzWindowImpl::SetSize(unsigned int width, unsigned int height) -{ - // SetWindowPos demande la taille totale de la fenêtre - RECT rect = {0, 0, static_cast(width), static_cast(height)}; - AdjustWindowRect(&rect, GetWindowLongPtr(m_handle, GWL_STYLE), false); - - SetWindowPos(m_handle, nullptr, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER); -} - -void NzWindowImpl::SetStayOnTop(bool stayOnTop) -{ - if (stayOnTop) - SetWindowPos(m_handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); - else - SetWindowPos(m_handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); -} - -void NzWindowImpl::SetTitle(const NzString& title) -{ - SetWindowTextW(m_handle, title.GetWideString().data()); -} - -void NzWindowImpl::SetVisible(bool visible) -{ - ShowWindow(m_handle, (visible) ? SW_SHOW : SW_HIDE); -} - -bool NzWindowImpl::HandleMessage(HWND window, UINT message, WPARAM wParam, LPARAM lParam) -{ - // Inutile de récupérer des évènements ne venant pas de notre fenêtre - if (m_handle != window) - return false; - - switch (message) - { - case WM_DESTROY: - if (fullscreenWindow == this) - ChangeDisplaySettings(nullptr, 0); - - break; - - case WM_SETCURSOR: - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms648382(v=vs.85).aspx - if (LOWORD(lParam) == HTCLIENT) - ::SetCursor(m_cursor); - - break; - - case WM_WINDOWPOSCHANGING: - { - WINDOWPOS* pos = reinterpret_cast(lParam); - - pos->cx = std::max(pos->cx, m_minSize.x); - pos->cy = std::max(pos->cy, m_minSize.y); - - if (m_maxSize.x >= 0) - pos->cx = std::min(pos->cx, m_maxSize.x); - - if (m_maxSize.y >= 0) - pos->cy = std::min(pos->cy, m_maxSize.y); - - break; - } - - default: - break; + if (height != -1) + m_maxSize.y = rect.bottom-rect.top; + else + m_maxSize.y = -1; } - if (m_eventListener) + void WindowImpl::SetMinimumSize(int width, int height) { + RECT rect = {0, 0, width, height}; + AdjustWindowRect(&rect, GetWindowLongPtr(m_handle, GWL_STYLE), false); + + if (width != -1) + m_minSize.x = rect.right-rect.left; + else + m_minSize.x = -1; + + if (height != -1) + m_minSize.y = rect.bottom-rect.top; + else + m_minSize.y = -1; + } + + void WindowImpl::SetPosition(int x, int y) + { + SetWindowPos(m_handle, nullptr, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); + } + + void WindowImpl::SetSize(unsigned int width, unsigned int height) + { + // SetWindowPos demande la taille totale de la fenêtre + RECT rect = {0, 0, static_cast(width), static_cast(height)}; + AdjustWindowRect(&rect, GetWindowLongPtr(m_handle, GWL_STYLE), false); + + SetWindowPos(m_handle, nullptr, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOMOVE | SWP_NOZORDER); + } + + void WindowImpl::SetStayOnTop(bool stayOnTop) + { + if (stayOnTop) + SetWindowPos(m_handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW); + else + SetWindowPos(m_handle, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + } + + void WindowImpl::SetTitle(const String& title) + { + SetWindowTextW(m_handle, title.GetWideString().data()); + } + + void WindowImpl::SetVisible(bool visible) + { + ShowWindow(m_handle, (visible) ? SW_SHOW : SW_HIDE); + } + + bool WindowImpl::HandleMessage(HWND window, UINT message, WPARAM wParam, LPARAM lParam) + { + // Inutile de récupérer des évènements ne venant pas de notre fenêtre + if (m_handle != window) + return false; + switch (message) { - case WM_CHAR: + case WM_DESTROY: + if (fullscreenWindow == this) + ChangeDisplaySettings(nullptr, 0); + + break; + + case WM_SETCURSOR: + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms648382(v=vs.85).aspx + if (LOWORD(lParam) == HTCLIENT) + ::SetCursor(m_cursor); + + break; + + case WM_WINDOWPOSCHANGING: { - // http://msdn.microsoft.com/en-us/library/ms646267(VS.85).aspx - bool repeated = ((HIWORD(lParam) & KF_REPEAT) != 0); - if (m_keyRepeat || !repeated) - { - NzEvent event; - event.type = nzEventType_TextEntered; - event.text.character = static_cast(wParam); - event.text.repeated = repeated; - m_parent->PushEvent(event); - } + WINDOWPOS* pos = reinterpret_cast(lParam); + + pos->cx = std::max(pos->cx, m_minSize.x); + pos->cy = std::max(pos->cy, m_minSize.y); + + if (m_maxSize.x >= 0) + pos->cx = std::min(pos->cx, m_maxSize.x); + + if (m_maxSize.y >= 0) + pos->cy = std::min(pos->cy, m_maxSize.y); break; } - case WM_CLOSE: - { - NzEvent event; - event.type = nzEventType_Quit; - m_parent->PushEvent(event); - - return true; // Afin que Windows ne ferme pas la fenêtre automatiquement - } - - #if !NAZARA_UTILITY_THREADED_WINDOW - case WM_ENTERSIZEMOVE: - { - m_sizemove = true; + default: break; - } + } - case WM_EXITSIZEMOVE: + if (m_eventListener) + { + switch (message) { - m_sizemove = false; - - // On vérifie ce qui a changé - RECT clientRect, windowRect; - GetClientRect(m_handle, &clientRect); - GetWindowRect(m_handle, &windowRect); - - NzVector2i position(windowRect.left, windowRect.top); - if (m_position != position) + case WM_CHAR: { - m_position = position; + // http://msdn.microsoft.com/en-us/library/ms646267(VS.85).aspx + bool repeated = ((HIWORD(lParam) & KF_REPEAT) != 0); + if (m_keyRepeat || !repeated) + { + WindowEvent event; + event.type = WindowEventType_TextEntered; + event.text.character = static_cast(wParam); + event.text.repeated = repeated; + m_parent->PushEvent(event); + } - NzEvent event; - event.type = nzEventType_Moved; - event.position.x = position.x; - event.position.y = position.y; - m_parent->PushEvent(event); + break; } - NzVector2ui size(clientRect.right-clientRect.left, clientRect.bottom-clientRect.top); - if (m_size != size) + case WM_CLOSE: { - m_size = size; - - NzEvent event; - event.type = nzEventType_Resized; - event.size.width = size.x; - event.size.height = size.y; + WindowEvent event; + event.type = WindowEventType_Quit; m_parent->PushEvent(event); - } - } - #endif - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - { - // http://msdn.microsoft.com/en-us/library/ms646267(VS.85).aspx - bool repeated = ((HIWORD(lParam) & KF_REPEAT) != 0); - if (m_keyRepeat || !repeated) + return true; // Afin que Windows ne ferme pas la fenêtre automatiquement + } + + #if !NAZARA_UTILITY_THREADED_WINDOW + case WM_ENTERSIZEMOVE: { - NzEvent event; - event.type = nzEventType_KeyPressed; + m_sizemove = true; + break; + } + + case WM_EXITSIZEMOVE: + { + m_sizemove = false; + + // On vérifie ce qui a changé + RECT clientRect, windowRect; + GetClientRect(m_handle, &clientRect); + GetWindowRect(m_handle, &windowRect); + + Vector2i position(windowRect.left, windowRect.top); + if (m_position != position) + { + m_position = position; + + WindowEvent event; + event.type = WindowEventType_Moved; + event.position.x = position.x; + event.position.y = position.y; + m_parent->PushEvent(event); + } + + Vector2ui size(clientRect.right-clientRect.left, clientRect.bottom-clientRect.top); + if (m_size != size) + { + m_size = size; + + WindowEvent event; + event.type = WindowEventType_Resized; + event.size.width = size.x; + event.size.height = size.y; + m_parent->PushEvent(event); + } + } + #endif + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + // http://msdn.microsoft.com/en-us/library/ms646267(VS.85).aspx + bool repeated = ((HIWORD(lParam) & KF_REPEAT) != 0); + if (m_keyRepeat || !repeated) + { + WindowEvent event; + event.type = WindowEventType_KeyPressed; + event.key.code = ConvertVirtualKey(wParam, lParam); + event.key.alt = ((GetAsyncKeyState(VK_MENU) & 0x8000) != 0); + event.key.control = ((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0); + event.key.repeated = repeated; + event.key.shift = ((GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0); + event.key.system = (((GetAsyncKeyState(VK_LWIN) & 0x8000) != 0) || ((GetAsyncKeyState(VK_RWIN) & 0x8000) != 0)); + m_parent->PushEvent(event); + } + + break; + } + + case WM_KEYUP: + case WM_SYSKEYUP: + { + // http://msdn.microsoft.com/en-us/library/ms646267(VS.85).aspx + WindowEvent event; + event.type = WindowEventType_KeyReleased; event.key.code = ConvertVirtualKey(wParam, lParam); event.key.alt = ((GetAsyncKeyState(VK_MENU) & 0x8000) != 0); event.key.control = ((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0); - event.key.repeated = repeated; event.key.shift = ((GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0); - event.key.system = (((GetAsyncKeyState(VK_LWIN) & 0x8000) != 0) || ((GetAsyncKeyState(VK_RWIN) & 0x8000) != 0)); + event.key.system = ((GetAsyncKeyState(VK_LWIN) & 0x8000) || (GetAsyncKeyState(VK_RWIN) & 0x8000)); m_parent->PushEvent(event); + + break; } - break; - } - - case WM_KEYUP: - case WM_SYSKEYUP: - { - // http://msdn.microsoft.com/en-us/library/ms646267(VS.85).aspx - NzEvent event; - event.type = nzEventType_KeyReleased; - event.key.code = ConvertVirtualKey(wParam, lParam); - event.key.alt = ((GetAsyncKeyState(VK_MENU) & 0x8000) != 0); - event.key.control = ((GetAsyncKeyState(VK_CONTROL) & 0x8000) != 0); - event.key.shift = ((GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0); - event.key.system = ((GetAsyncKeyState(VK_LWIN) & 0x8000) || (GetAsyncKeyState(VK_RWIN) & 0x8000)); - m_parent->PushEvent(event); - - break; - } - - case WM_KILLFOCUS: - { - NzEvent event; - event.type = nzEventType_LostFocus; - m_parent->PushEvent(event); - - break; - } - - case WM_LBUTTONDBLCLK: - { - // Cet évènement est généré à la place d'un WM_LBUTTONDOWN lors d'un double-clic. - // Comme nous désirons quand même notifier chaque clic, nous envoyons les deux évènements. - NzEvent event; - event.mouseButton.button = NzMouse::Left; - event.mouseButton.x = GET_X_LPARAM(lParam); - event.mouseButton.y = GET_Y_LPARAM(lParam); - - event.type = nzEventType_MouseButtonDoubleClicked; - m_parent->PushEvent(event); - - event.type = nzEventType_MouseButtonPressed; - m_parent->PushEvent(event); - - break; - } - - case WM_LBUTTONDOWN: - { - NzEvent event; - event.type = nzEventType_MouseButtonPressed; - event.mouseButton.button = NzMouse::Left; - event.mouseButton.x = GET_X_LPARAM(lParam); - event.mouseButton.y = GET_Y_LPARAM(lParam); - m_parent->PushEvent(event); - - break; - } - - case WM_LBUTTONUP: - { - NzEvent event; - event.type = nzEventType_MouseButtonReleased; - event.mouseButton.button = NzMouse::Left; - event.mouseButton.x = GET_X_LPARAM(lParam); - event.mouseButton.y = GET_Y_LPARAM(lParam); - m_parent->PushEvent(event); - - break; - } - - case WM_MBUTTONDBLCLK: - { - NzEvent event; - event.mouseButton.button = NzMouse::Middle; - event.mouseButton.x = GET_X_LPARAM(lParam); - event.mouseButton.y = GET_Y_LPARAM(lParam); - - event.type = nzEventType_MouseButtonDoubleClicked; - m_parent->PushEvent(event); - - event.type = nzEventType_MouseButtonPressed; - m_parent->PushEvent(event); - - break; - } - - case WM_MBUTTONDOWN: - { - NzEvent event; - event.type = nzEventType_MouseButtonPressed; - event.mouseButton.button = NzMouse::Middle; - event.mouseButton.x = GET_X_LPARAM(lParam); - event.mouseButton.y = GET_Y_LPARAM(lParam); - m_parent->PushEvent(event); - - break; - } - - case WM_MBUTTONUP: - { - NzEvent event; - event.type = nzEventType_MouseButtonReleased; - event.mouseButton.button = NzMouse::Middle; - event.mouseButton.x = GET_X_LPARAM(lParam); - event.mouseButton.y = GET_Y_LPARAM(lParam); - m_parent->PushEvent(event); - - break; - } - - // Nécessite un appel précédent à TrackMouseEvent (Fait dans WM_MOUSEMOVE) - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms645615(v=vs.85).aspx - case WM_MOUSELEAVE: - { - m_mouseInside = false; - - NzEvent event; - event.type = nzEventType_MouseLeft; - m_parent->PushEvent(event); - break; - } - - case WM_MOUSEMOVE: - { - int currentX = GET_X_LPARAM(lParam); - int currentY = GET_Y_LPARAM(lParam); - - if (!m_mouseInside) + case WM_KILLFOCUS: { - m_mouseInside = true; - - // On créé un évènement pour être informé de la sortie de la fenêtre - TRACKMOUSEEVENT mouseEvent; - mouseEvent.cbSize = sizeof(TRACKMOUSEEVENT); - mouseEvent.dwFlags = TME_LEAVE; - mouseEvent.hwndTrack = m_handle; - - TrackMouseEvent(&mouseEvent); - - NzEvent event; - event.type = nzEventType_MouseEntered; + WindowEvent event; + event.type = WindowEventType_LostFocus; m_parent->PushEvent(event); - event.type = nzEventType_MouseMoved; + break; + } - // Le delta sera 0 - event.mouseMove.deltaX = 0; - event.mouseMove.deltaY = 0; + case WM_LBUTTONDBLCLK: + { + // Cet évènement est généré à la place d'un WM_LBUTTONDOWN lors d'un double-clic. + // Comme nous désirons quand même notifier chaque clic, nous envoyons les deux évènements. + WindowEvent event; + event.mouseButton.button = Mouse::Left; + event.mouseButton.x = GET_X_LPARAM(lParam); + event.mouseButton.y = GET_Y_LPARAM(lParam); + event.type = WindowEventType_MouseButtonDoubleClicked; + m_parent->PushEvent(event); + + event.type = WindowEventType_MouseButtonPressed; + m_parent->PushEvent(event); + + break; + } + + case WM_LBUTTONDOWN: + { + WindowEvent event; + event.type = WindowEventType_MouseButtonPressed; + event.mouseButton.button = Mouse::Left; + event.mouseButton.x = GET_X_LPARAM(lParam); + event.mouseButton.y = GET_Y_LPARAM(lParam); + m_parent->PushEvent(event); + + break; + } + + case WM_LBUTTONUP: + { + WindowEvent event; + event.type = WindowEventType_MouseButtonReleased; + event.mouseButton.button = Mouse::Left; + event.mouseButton.x = GET_X_LPARAM(lParam); + event.mouseButton.y = GET_Y_LPARAM(lParam); + m_parent->PushEvent(event); + + break; + } + + case WM_MBUTTONDBLCLK: + { + WindowEvent event; + event.mouseButton.button = Mouse::Middle; + event.mouseButton.x = GET_X_LPARAM(lParam); + event.mouseButton.y = GET_Y_LPARAM(lParam); + + event.type = WindowEventType_MouseButtonDoubleClicked; + m_parent->PushEvent(event); + + event.type = WindowEventType_MouseButtonPressed; + m_parent->PushEvent(event); + + break; + } + + case WM_MBUTTONDOWN: + { + WindowEvent event; + event.type = WindowEventType_MouseButtonPressed; + event.mouseButton.button = Mouse::Middle; + event.mouseButton.x = GET_X_LPARAM(lParam); + event.mouseButton.y = GET_Y_LPARAM(lParam); + m_parent->PushEvent(event); + + break; + } + + case WM_MBUTTONUP: + { + WindowEvent event; + event.type = WindowEventType_MouseButtonReleased; + event.mouseButton.button = Mouse::Middle; + event.mouseButton.x = GET_X_LPARAM(lParam); + event.mouseButton.y = GET_Y_LPARAM(lParam); + m_parent->PushEvent(event); + + break; + } + + // Nécessite un appel précédent à TrackMouseEvent (Fait dans WM_MOUSEMOVE) + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms645615(v=vs.85).aspx + case WM_MOUSELEAVE: + { + m_mouseInside = false; + + WindowEvent event; + event.type = WindowEventType_MouseLeft; + m_parent->PushEvent(event); + break; + } + + case WM_MOUSEMOVE: + { + int currentX = GET_X_LPARAM(lParam); + int currentY = GET_Y_LPARAM(lParam); + + if (!m_mouseInside) + { + m_mouseInside = true; + + // On créé un évènement pour être informé de la sortie de la fenêtre + TRACKMOUSEEVENT mouseEvent; + mouseEvent.cbSize = sizeof(TRACKMOUSEEVENT); + mouseEvent.dwFlags = TME_LEAVE; + mouseEvent.hwndTrack = m_handle; + + TrackMouseEvent(&mouseEvent); + + WindowEvent event; + event.type = WindowEventType_MouseEntered; + m_parent->PushEvent(event); + + event.type = WindowEventType_MouseMoved; + + // Le delta sera 0 + event.mouseMove.deltaX = 0; + event.mouseMove.deltaY = 0; + + event.mouseMove.x = currentX; + event.mouseMove.y = currentY; + + m_mousePos.x = currentX; + m_mousePos.y = currentY; + + m_parent->PushEvent(event); + break; + } + + // Si la souris n'a pas bougé (Ou qu'on veut ignorer l'évènement) + if (m_mousePos.x == currentX && m_mousePos.y == currentY) + break; + + WindowEvent event; + event.type = WindowEventType_MouseMoved; + event.mouseMove.deltaX = currentX - m_mousePos.x; + event.mouseMove.deltaY = currentY - m_mousePos.y; event.mouseMove.x = currentX; event.mouseMove.y = currentY; @@ -742,455 +762,438 @@ bool NzWindowImpl::HandleMessage(HWND window, UINT message, WPARAM wParam, LPARA break; } - // Si la souris n'a pas bougé (Ou qu'on veut ignorer l'évènement) - if (m_mousePos.x == currentX && m_mousePos.y == currentY) + case WM_MOUSEWHEEL: + { + if (m_smoothScrolling) + { + WindowEvent event; + event.type = WindowEventType_MouseWheelMoved; + event.mouseWheel.delta = static_cast(GET_WHEEL_DELTA_WPARAM(wParam))/WHEEL_DELTA; + m_parent->PushEvent(event); + } + else + { + m_scrolling += GET_WHEEL_DELTA_WPARAM(wParam); + if (std::abs(m_scrolling) >= WHEEL_DELTA) + { + WindowEvent event; + event.type = WindowEventType_MouseWheelMoved; + event.mouseWheel.delta = static_cast(m_scrolling/WHEEL_DELTA); + m_parent->PushEvent(event); + + m_scrolling %= WHEEL_DELTA; + } + } break; + } - NzEvent event; - event.type = nzEventType_MouseMoved; - event.mouseMove.deltaX = currentX - m_mousePos.x; - event.mouseMove.deltaY = currentY - m_mousePos.y; - event.mouseMove.x = currentX; - event.mouseMove.y = currentY; - - m_mousePos.x = currentX; - m_mousePos.y = currentY; - - m_parent->PushEvent(event); - break; - } - - case WM_MOUSEWHEEL: - { - if (m_smoothScrolling) + case WM_MOVE: { - NzEvent event; - event.type = nzEventType_MouseWheelMoved; - event.mouseWheel.delta = static_cast(GET_WHEEL_DELTA_WPARAM(wParam))/WHEEL_DELTA; + RECT windowRect; + GetWindowRect(m_handle, &windowRect); + + WindowEvent event; + event.type = WindowEventType_Moved; + event.position.x = windowRect.left; + event.position.y = windowRect.top; m_parent->PushEvent(event); + + break; } - else + + case WM_RBUTTONDBLCLK: { - m_scrolling += GET_WHEEL_DELTA_WPARAM(wParam); - if (std::abs(m_scrolling) >= WHEEL_DELTA) - { - NzEvent event; - event.type = nzEventType_MouseWheelMoved; - event.mouseWheel.delta = static_cast(m_scrolling/WHEEL_DELTA); - m_parent->PushEvent(event); + WindowEvent event; + event.mouseButton.button = Mouse::Right; + event.mouseButton.x = GET_X_LPARAM(lParam); + event.mouseButton.y = GET_Y_LPARAM(lParam); - m_scrolling %= WHEEL_DELTA; - } - } - break; - } - - case WM_MOVE: - { - RECT windowRect; - GetWindowRect(m_handle, &windowRect); - - NzEvent event; - event.type = nzEventType_Moved; - event.position.x = windowRect.left; - event.position.y = windowRect.top; - m_parent->PushEvent(event); - - break; - } - - case WM_RBUTTONDBLCLK: - { - NzEvent event; - event.mouseButton.button = NzMouse::Right; - event.mouseButton.x = GET_X_LPARAM(lParam); - event.mouseButton.y = GET_Y_LPARAM(lParam); - - event.type = nzEventType_MouseButtonDoubleClicked; - m_parent->PushEvent(event); - - event.type = nzEventType_MouseButtonPressed; - m_parent->PushEvent(event); - - break; - } - - case WM_RBUTTONDOWN: - { - NzEvent event; - event.type = nzEventType_MouseButtonPressed; - event.mouseButton.button = NzMouse::Right; - event.mouseButton.x = GET_X_LPARAM(lParam); - event.mouseButton.y = GET_Y_LPARAM(lParam); - m_parent->PushEvent(event); - - break; - } - - case WM_RBUTTONUP: - { - NzEvent event; - event.type = nzEventType_MouseButtonReleased; - event.mouseButton.button = NzMouse::Right; - event.mouseButton.x = GET_X_LPARAM(lParam); - event.mouseButton.y = GET_Y_LPARAM(lParam); - m_parent->PushEvent(event); - - break; - } - - case WM_SETFOCUS: - { - NzEvent event; - event.type = nzEventType_GainedFocus; - m_parent->PushEvent(event); - - break; - } - - case WM_SIZE: - { - #if NAZARA_UTILITY_THREADED_WINDOW - if (wParam != SIZE_MINIMIZED) - #else - if (!m_sizemove && wParam != SIZE_MINIMIZED) - #endif - { - RECT rect; - GetClientRect(m_handle, &rect); - - NzVector2ui size(rect.right-rect.left, rect.bottom-rect.top); // On récupère uniquement la taille de la zone client - if (m_size == size) - break; - - m_size = size; - - NzEvent event; - event.type = nzEventType_Resized; - event.size.width = size.x; - event.size.height = size.y; + event.type = WindowEventType_MouseButtonDoubleClicked; m_parent->PushEvent(event); - } - break; - } - case WM_UNICHAR: - { - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646288(v=vs.85).aspx - if (wParam != UNICODE_NOCHAR) + event.type = WindowEventType_MouseButtonPressed; + m_parent->PushEvent(event); + + break; + } + + case WM_RBUTTONDOWN: { - bool repeated = ((HIWORD(lParam) & KF_REPEAT) != 0); - if (m_keyRepeat || !repeated) + WindowEvent event; + event.type = WindowEventType_MouseButtonPressed; + event.mouseButton.button = Mouse::Right; + event.mouseButton.x = GET_X_LPARAM(lParam); + event.mouseButton.y = GET_Y_LPARAM(lParam); + m_parent->PushEvent(event); + + break; + } + + case WM_RBUTTONUP: + { + WindowEvent event; + event.type = WindowEventType_MouseButtonReleased; + event.mouseButton.button = Mouse::Right; + event.mouseButton.x = GET_X_LPARAM(lParam); + event.mouseButton.y = GET_Y_LPARAM(lParam); + m_parent->PushEvent(event); + + break; + } + + case WM_SETFOCUS: + { + WindowEvent event; + event.type = WindowEventType_GainedFocus; + m_parent->PushEvent(event); + + break; + } + + case WM_SIZE: + { + #if NAZARA_UTILITY_THREADED_WINDOW + if (wParam != SIZE_MINIMIZED) + #else + if (!m_sizemove && wParam != SIZE_MINIMIZED) + #endif { - NzEvent event; - event.type = nzEventType_TextEntered; - event.text.character = static_cast(wParam); - event.text.repeated = repeated; + RECT rect; + GetClientRect(m_handle, &rect); + + Vector2ui size(rect.right-rect.left, rect.bottom-rect.top); // On récupère uniquement la taille de la zone client + if (m_size == size) + break; + + m_size = size; + + WindowEvent event; + event.type = WindowEventType_Resized; + event.size.width = size.x; + event.size.height = size.y; m_parent->PushEvent(event); } - - return true; + break; } - } - case WM_XBUTTONDBLCLK: + case WM_UNICHAR: + { + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646288(v=vs.85).aspx + if (wParam != UNICODE_NOCHAR) + { + bool repeated = ((HIWORD(lParam) & KF_REPEAT) != 0); + if (m_keyRepeat || !repeated) + { + WindowEvent event; + event.type = WindowEventType_TextEntered; + event.text.character = static_cast(wParam); + event.text.repeated = repeated; + m_parent->PushEvent(event); + } + + return true; + } + } + + case WM_XBUTTONDBLCLK: + { + WindowEvent event; + if (HIWORD(wParam) == XBUTTON1) + event.mouseButton.button = Mouse::XButton1; + else + event.mouseButton.button = Mouse::XButton2; + + event.mouseButton.x = GET_X_LPARAM(lParam); + event.mouseButton.y = GET_Y_LPARAM(lParam); + + event.type = WindowEventType_MouseButtonDoubleClicked; + m_parent->PushEvent(event); + + event.type = WindowEventType_MouseButtonPressed; + m_parent->PushEvent(event); + + break; + } + + case WM_XBUTTONDOWN: + { + WindowEvent event; + event.type = WindowEventType_MouseButtonPressed; + + if (HIWORD(wParam) == XBUTTON1) + event.mouseButton.button = Mouse::XButton1; + else + event.mouseButton.button = Mouse::XButton2; + + event.mouseButton.x = GET_X_LPARAM(lParam); + event.mouseButton.y = GET_Y_LPARAM(lParam); + m_parent->PushEvent(event); + + break; + } + + case WM_XBUTTONUP: + { + WindowEvent event; + event.type = WindowEventType_MouseButtonReleased; + + if (HIWORD(wParam) == XBUTTON1) + event.mouseButton.button = Mouse::XButton1; + else + event.mouseButton.button = Mouse::XButton2; + + event.mouseButton.x = GET_X_LPARAM(lParam); + event.mouseButton.y = GET_Y_LPARAM(lParam); + m_parent->PushEvent(event); + + break; + } + + default: + break; + } + } + + #if NAZARA_UTILITY_WINDOWS_DISABLE_MENU_KEYS + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646360(v=vs.85).aspx + if (message == WM_SYSCOMMAND && wParam == SC_KEYMENU) + return true; + #endif + + return false; + } + + bool WindowImpl::Initialize() + { + // Nous devons faire un type Unicode pour que la fenêtre le soit également + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms633574(v=vs.85).aspx + WNDCLASSW windowClass; + windowClass.cbClsExtra = 0; + windowClass.cbWndExtra = 0; + windowClass.hbrBackground = nullptr; + windowClass.hCursor = nullptr; // Le curseur est définit dynamiquement + windowClass.hIcon = nullptr; // L'icône est définie dynamiquement + windowClass.hInstance = GetModuleHandle(nullptr); + windowClass.lpfnWndProc = MessageHandler; + windowClass.lpszClassName = className; + windowClass.lpszMenuName = nullptr; + windowClass.style = CS_DBLCLKS; // Gestion du double-clic + + return RegisterClassW(&windowClass) != 0; + } + + void WindowImpl::Uninitialize() + { + UnregisterClassW(className, GetModuleHandle(nullptr)); + } + + Keyboard::Key WindowImpl::ConvertVirtualKey(WPARAM key, LPARAM flags) + { + switch (key) + { + case VK_CONTROL: return (HIWORD(flags) & KF_EXTENDED) ? Keyboard::RControl : Keyboard::LControl; + case VK_MENU: return (HIWORD(flags) & KF_EXTENDED) ? Keyboard::RAlt : Keyboard::LAlt; + case VK_SHIFT: { - NzEvent event; - if (HIWORD(wParam) == XBUTTON1) - event.mouseButton.button = NzMouse::XButton1; - else - event.mouseButton.button = NzMouse::XButton2; - - event.mouseButton.x = GET_X_LPARAM(lParam); - event.mouseButton.y = GET_Y_LPARAM(lParam); - - event.type = nzEventType_MouseButtonDoubleClicked; - m_parent->PushEvent(event); - - event.type = nzEventType_MouseButtonPressed; - m_parent->PushEvent(event); - - break; + static UINT scancode = MapVirtualKey(VK_SHIFT, MAPVK_VK_TO_VSC); + return (((flags >> 16) & 0xFF) == scancode) ? Keyboard::LShift : Keyboard::RShift; } - case WM_XBUTTONDOWN: - { - NzEvent event; - event.type = nzEventType_MouseButtonPressed; - - if (HIWORD(wParam) == XBUTTON1) - event.mouseButton.button = NzMouse::XButton1; - else - event.mouseButton.button = NzMouse::XButton2; - - event.mouseButton.x = GET_X_LPARAM(lParam); - event.mouseButton.y = GET_Y_LPARAM(lParam); - m_parent->PushEvent(event); - - break; - } - - case WM_XBUTTONUP: - { - NzEvent event; - event.type = nzEventType_MouseButtonReleased; - - if (HIWORD(wParam) == XBUTTON1) - event.mouseButton.button = NzMouse::XButton1; - else - event.mouseButton.button = NzMouse::XButton2; - - event.mouseButton.x = GET_X_LPARAM(lParam); - event.mouseButton.y = GET_Y_LPARAM(lParam); - m_parent->PushEvent(event); - - break; - } + case 0x30: return Keyboard::Num0; + case 0x31: return Keyboard::Num1; + case 0x32: return Keyboard::Num2; + case 0x33: return Keyboard::Num3; + case 0x34: return Keyboard::Num4; + case 0x35: return Keyboard::Num5; + case 0x36: return Keyboard::Num6; + case 0x37: return Keyboard::Num7; + case 0x38: return Keyboard::Num8; + case 0x39: return Keyboard::Num9; + case 0x41: return Keyboard::A; + case 0x42: return Keyboard::B; + case 0x43: return Keyboard::C; + case 0x44: return Keyboard::D; + case 0x45: return Keyboard::E; + case 0x46: return Keyboard::F; + case 0x47: return Keyboard::G; + case 0x48: return Keyboard::H; + case 0x49: return Keyboard::I; + case 0x4A: return Keyboard::J; + case 0x4B: return Keyboard::K; + case 0x4C: return Keyboard::L; + case 0x4D: return Keyboard::M; + case 0x4E: return Keyboard::N; + case 0x4F: return Keyboard::O; + case 0x50: return Keyboard::P; + case 0x51: return Keyboard::Q; + case 0x52: return Keyboard::R; + case 0x53: return Keyboard::S; + case 0x54: return Keyboard::T; + case 0x55: return Keyboard::U; + case 0x56: return Keyboard::V; + case 0x57: return Keyboard::W; + case 0x58: return Keyboard::X; + case 0x59: return Keyboard::Y; + case 0x5A: return Keyboard::Z; + case VK_ADD: return Keyboard::Add; + case VK_BACK: return Keyboard::Backspace; + case VK_BROWSER_BACK: return Keyboard::Browser_Back; + case VK_BROWSER_FAVORITES: return Keyboard::Browser_Favorites; + case VK_BROWSER_FORWARD: return Keyboard::Browser_Forward; + case VK_BROWSER_HOME: return Keyboard::Browser_Home; + case VK_BROWSER_REFRESH: return Keyboard::Browser_Refresh; + case VK_BROWSER_SEARCH: return Keyboard::Browser_Search; + case VK_BROWSER_STOP: return Keyboard::Browser_Stop; + case VK_CAPITAL: return Keyboard::CapsLock; + case VK_CLEAR: return Keyboard::Clear; + case VK_DECIMAL: return Keyboard::Decimal; + case VK_DELETE: return Keyboard::Delete; + case VK_DIVIDE: return Keyboard::Divide; + case VK_DOWN: return Keyboard::Down; + case VK_END: return Keyboard::End; + case VK_ESCAPE: return Keyboard::Escape; + case VK_F1: return Keyboard::F1; + case VK_F2: return Keyboard::F2; + case VK_F3: return Keyboard::F3; + case VK_F4: return Keyboard::F4; + case VK_F5: return Keyboard::F5; + case VK_F6: return Keyboard::F6; + case VK_F7: return Keyboard::F7; + case VK_F8: return Keyboard::F8; + case VK_F9: return Keyboard::F9; + case VK_F10: return Keyboard::F10; + case VK_F11: return Keyboard::F11; + case VK_F12: return Keyboard::F12; + case VK_F13: return Keyboard::F13; + case VK_F14: return Keyboard::F14; + case VK_F15: return Keyboard::F15; + case VK_HOME: return Keyboard::Home; + case VK_INSERT: return Keyboard::Insert; + case VK_LEFT: return Keyboard::Left; + case VK_LWIN: return Keyboard::LSystem; + case VK_MEDIA_NEXT_TRACK: return Keyboard::Media_Next; + case VK_MEDIA_PLAY_PAUSE: return Keyboard::Media_Play; + case VK_MEDIA_PREV_TRACK: return Keyboard::Media_Previous; + case VK_MEDIA_STOP: return Keyboard::Media_Stop; + case VK_MULTIPLY: return Keyboard::Multiply; + case VK_NEXT: return Keyboard::PageDown; + case VK_NUMPAD0: return Keyboard::Numpad0; + case VK_NUMPAD1: return Keyboard::Numpad1; + case VK_NUMPAD2: return Keyboard::Numpad2; + case VK_NUMPAD3: return Keyboard::Numpad3; + case VK_NUMPAD4: return Keyboard::Numpad4; + case VK_NUMPAD5: return Keyboard::Numpad5; + case VK_NUMPAD6: return Keyboard::Numpad6; + case VK_NUMPAD7: return Keyboard::Numpad7; + case VK_NUMPAD8: return Keyboard::Numpad8; + case VK_NUMPAD9: return Keyboard::Numpad9; + case VK_NUMLOCK: return Keyboard::NumLock; + case VK_OEM_1: return Keyboard::Semicolon; + case VK_OEM_2: return Keyboard::Slash; + case VK_OEM_3: return Keyboard::Tilde; + case VK_OEM_4: return Keyboard::LBracket; + case VK_OEM_5: return Keyboard::Backslash; + case VK_OEM_6: return Keyboard::RBracket; + case VK_OEM_7: return Keyboard::Quote; + case VK_OEM_COMMA: return Keyboard::Comma; + case VK_OEM_MINUS: return Keyboard::Dash; + case VK_OEM_PERIOD: return Keyboard::Period; + case VK_OEM_PLUS: return Keyboard::Equal; + case VK_RIGHT: return Keyboard::Right; + case VK_PRIOR: return Keyboard::PageUp; + case VK_PAUSE: return Keyboard::Pause; + case VK_PRINT: return Keyboard::Print; + case VK_SCROLL: return Keyboard::ScrollLock; + case VK_SNAPSHOT: return Keyboard::PrintScreen; + case VK_SUBTRACT: return Keyboard::Subtract; + case VK_RETURN: return Keyboard::Return; + case VK_RWIN: return Keyboard::RSystem; + case VK_SPACE: return Keyboard::Space; + case VK_TAB: return Keyboard::Tab; + case VK_UP: return Keyboard::Up; + case VK_VOLUME_DOWN: return Keyboard::Volume_Down; + case VK_VOLUME_MUTE: return Keyboard::Volume_Mute; + case VK_VOLUME_UP: return Keyboard::Volume_Up; default: - break; + return Keyboard::Undefined; } } - #if NAZARA_UTILITY_WINDOWS_DISABLE_MENU_KEYS - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms646360(v=vs.85).aspx - if (message == WM_SYSCOMMAND && wParam == SC_KEYMENU) - return true; - #endif - - return false; -} - -bool NzWindowImpl::Initialize() -{ - // Nous devons faire un type Unicode pour que la fenêtre le soit également - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms633574(v=vs.85).aspx - WNDCLASSW windowClass; - windowClass.cbClsExtra = 0; - windowClass.cbWndExtra = 0; - windowClass.hbrBackground = nullptr; - windowClass.hCursor = nullptr; // Le curseur est définit dynamiquement - windowClass.hIcon = nullptr; // L'icône est définie dynamiquement - windowClass.hInstance = GetModuleHandle(nullptr); - windowClass.lpfnWndProc = MessageHandler; - windowClass.lpszClassName = className; - windowClass.lpszMenuName = nullptr; - windowClass.style = CS_DBLCLKS; // Gestion du double-clic - - return RegisterClassW(&windowClass) != 0; -} - -void NzWindowImpl::Uninitialize() -{ - UnregisterClassW(className, GetModuleHandle(nullptr)); -} - -NzKeyboard::Key NzWindowImpl::ConvertVirtualKey(WPARAM key, LPARAM flags) -{ - switch (key) + LRESULT CALLBACK WindowImpl::MessageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam) { - case VK_CONTROL: return (HIWORD(flags) & KF_EXTENDED) ? NzKeyboard::RControl : NzKeyboard::LControl; - case VK_MENU: return (HIWORD(flags) & KF_EXTENDED) ? NzKeyboard::RAlt : NzKeyboard::LAlt; - case VK_SHIFT: + WindowImpl* me; + if (message == WM_CREATE) { - static UINT scancode = MapVirtualKey(VK_SHIFT, MAPVK_VK_TO_VSC); - return (((flags >> 16) & 0xFF) == scancode) ? NzKeyboard::LShift : NzKeyboard::RShift; + me = reinterpret_cast(reinterpret_cast(lParam)->lpCreateParams); + SetWindowLongPtr(window, GWL_USERDATA, reinterpret_cast(me)); + } + else + me = reinterpret_cast(GetWindowLongPtr(window, GWL_USERDATA)); + + if (me) + { + if (me->HandleMessage(window, message, wParam, lParam)) + return 0; + else if (me->m_callback) + return CallWindowProcW(reinterpret_cast(me->m_callback), window, message, wParam, lParam); } - case 0x30: return NzKeyboard::Num0; - case 0x31: return NzKeyboard::Num1; - case 0x32: return NzKeyboard::Num2; - case 0x33: return NzKeyboard::Num3; - case 0x34: return NzKeyboard::Num4; - case 0x35: return NzKeyboard::Num5; - case 0x36: return NzKeyboard::Num6; - case 0x37: return NzKeyboard::Num7; - case 0x38: return NzKeyboard::Num8; - case 0x39: return NzKeyboard::Num9; - case 0x41: return NzKeyboard::A; - case 0x42: return NzKeyboard::B; - case 0x43: return NzKeyboard::C; - case 0x44: return NzKeyboard::D; - case 0x45: return NzKeyboard::E; - case 0x46: return NzKeyboard::F; - case 0x47: return NzKeyboard::G; - case 0x48: return NzKeyboard::H; - case 0x49: return NzKeyboard::I; - case 0x4A: return NzKeyboard::J; - case 0x4B: return NzKeyboard::K; - case 0x4C: return NzKeyboard::L; - case 0x4D: return NzKeyboard::M; - case 0x4E: return NzKeyboard::N; - case 0x4F: return NzKeyboard::O; - case 0x50: return NzKeyboard::P; - case 0x51: return NzKeyboard::Q; - case 0x52: return NzKeyboard::R; - case 0x53: return NzKeyboard::S; - case 0x54: return NzKeyboard::T; - case 0x55: return NzKeyboard::U; - case 0x56: return NzKeyboard::V; - case 0x57: return NzKeyboard::W; - case 0x58: return NzKeyboard::X; - case 0x59: return NzKeyboard::Y; - case 0x5A: return NzKeyboard::Z; - case VK_ADD: return NzKeyboard::Add; - case VK_BACK: return NzKeyboard::Backspace; - case VK_BROWSER_BACK: return NzKeyboard::Browser_Back; - case VK_BROWSER_FAVORITES: return NzKeyboard::Browser_Favorites; - case VK_BROWSER_FORWARD: return NzKeyboard::Browser_Forward; - case VK_BROWSER_HOME: return NzKeyboard::Browser_Home; - case VK_BROWSER_REFRESH: return NzKeyboard::Browser_Refresh; - case VK_BROWSER_SEARCH: return NzKeyboard::Browser_Search; - case VK_BROWSER_STOP: return NzKeyboard::Browser_Stop; - case VK_CAPITAL: return NzKeyboard::CapsLock; - case VK_CLEAR: return NzKeyboard::Clear; - case VK_DECIMAL: return NzKeyboard::Decimal; - case VK_DELETE: return NzKeyboard::Delete; - case VK_DIVIDE: return NzKeyboard::Divide; - case VK_DOWN: return NzKeyboard::Down; - case VK_END: return NzKeyboard::End; - case VK_ESCAPE: return NzKeyboard::Escape; - case VK_F1: return NzKeyboard::F1; - case VK_F2: return NzKeyboard::F2; - case VK_F3: return NzKeyboard::F3; - case VK_F4: return NzKeyboard::F4; - case VK_F5: return NzKeyboard::F5; - case VK_F6: return NzKeyboard::F6; - case VK_F7: return NzKeyboard::F7; - case VK_F8: return NzKeyboard::F8; - case VK_F9: return NzKeyboard::F9; - case VK_F10: return NzKeyboard::F10; - case VK_F11: return NzKeyboard::F11; - case VK_F12: return NzKeyboard::F12; - case VK_F13: return NzKeyboard::F13; - case VK_F14: return NzKeyboard::F14; - case VK_F15: return NzKeyboard::F15; - case VK_HOME: return NzKeyboard::Home; - case VK_INSERT: return NzKeyboard::Insert; - case VK_LEFT: return NzKeyboard::Left; - case VK_LWIN: return NzKeyboard::LSystem; - case VK_MEDIA_NEXT_TRACK: return NzKeyboard::Media_Next; - case VK_MEDIA_PLAY_PAUSE: return NzKeyboard::Media_Play; - case VK_MEDIA_PREV_TRACK: return NzKeyboard::Media_Previous; - case VK_MEDIA_STOP: return NzKeyboard::Media_Stop; - case VK_MULTIPLY: return NzKeyboard::Multiply; - case VK_NEXT: return NzKeyboard::PageDown; - case VK_NUMPAD0: return NzKeyboard::Numpad0; - case VK_NUMPAD1: return NzKeyboard::Numpad1; - case VK_NUMPAD2: return NzKeyboard::Numpad2; - case VK_NUMPAD3: return NzKeyboard::Numpad3; - case VK_NUMPAD4: return NzKeyboard::Numpad4; - case VK_NUMPAD5: return NzKeyboard::Numpad5; - case VK_NUMPAD6: return NzKeyboard::Numpad6; - case VK_NUMPAD7: return NzKeyboard::Numpad7; - case VK_NUMPAD8: return NzKeyboard::Numpad8; - case VK_NUMPAD9: return NzKeyboard::Numpad9; - case VK_NUMLOCK: return NzKeyboard::NumLock; - case VK_OEM_1: return NzKeyboard::Semicolon; - case VK_OEM_2: return NzKeyboard::Slash; - case VK_OEM_3: return NzKeyboard::Tilde; - case VK_OEM_4: return NzKeyboard::LBracket; - case VK_OEM_5: return NzKeyboard::Backslash; - case VK_OEM_6: return NzKeyboard::RBracket; - case VK_OEM_7: return NzKeyboard::Quote; - case VK_OEM_COMMA: return NzKeyboard::Comma; - case VK_OEM_MINUS: return NzKeyboard::Dash; - case VK_OEM_PERIOD: return NzKeyboard::Period; - case VK_OEM_PLUS: return NzKeyboard::Equal; - case VK_RIGHT: return NzKeyboard::Right; - case VK_PRIOR: return NzKeyboard::PageUp; - case VK_PAUSE: return NzKeyboard::Pause; - case VK_PRINT: return NzKeyboard::Print; - case VK_SCROLL: return NzKeyboard::ScrollLock; - case VK_SNAPSHOT: return NzKeyboard::PrintScreen; - case VK_SUBTRACT: return NzKeyboard::Subtract; - case VK_RETURN: return NzKeyboard::Return; - case VK_RWIN: return NzKeyboard::RSystem; - case VK_SPACE: return NzKeyboard::Space; - case VK_TAB: return NzKeyboard::Tab; - case VK_UP: return NzKeyboard::Up; - case VK_VOLUME_DOWN: return NzKeyboard::Volume_Down; - case VK_VOLUME_MUTE: return NzKeyboard::Volume_Mute; - case VK_VOLUME_UP: return NzKeyboard::Volume_Up; - - default: - return NzKeyboard::Undefined; + return DefWindowProcW(window, message, wParam, lParam); } -} -LRESULT CALLBACK NzWindowImpl::MessageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam) -{ - NzWindowImpl* me; - if (message == WM_CREATE) + UInt32 WindowImpl::RetrieveStyle(HWND handle) { - me = reinterpret_cast(reinterpret_cast(lParam)->lpCreateParams); - SetWindowLongPtr(window, GWL_USERDATA, reinterpret_cast(me)); - } - else - me = reinterpret_cast(GetWindowLongPtr(window, GWL_USERDATA)); + UInt32 style = 0; - if (me) + LONG_PTR winStyle = GetWindowLongPtr(handle, GWL_STYLE); + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx + if (winStyle & WS_CAPTION) + { + style |= WindowStyle_Titlebar; + if (winStyle & WS_SYSMENU) + style |= WindowStyle_Closable; + + if (winStyle & WS_MAXIMIZEBOX) + style |= WindowStyle_Resizable; + } + + if (winStyle & WS_SIZEBOX) + style |= WindowStyle_Resizable; + + // Pour déterminer si la fenêtre est en plein écran, il suffit de vérifier si elle recouvre l'écran + DEVMODE mode; + mode.dmSize = sizeof(DEVMODE); + EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &mode); + + RECT rect; + if (GetWindowRect(handle, &rect)) + { + if (static_cast(rect.right-rect.left) == mode.dmPelsWidth && static_cast(rect.bottom-rect.top) == mode.dmPelsHeight) + style |= WindowStyle_Fullscreen; + } + + return style; + } + + #if NAZARA_UTILITY_THREADED_WINDOW + void WindowImpl::WindowThread(HWND* handle, DWORD styleEx, const wchar_t* title, DWORD style, unsigned int x, unsigned int y, unsigned int width, unsigned int height, WindowImpl* window, Mutex* mutex, ConditionVariable* condition) { - if (me->HandleMessage(window, message, wParam, lParam)) - return 0; - else if (me->m_callback) - return CallWindowProcW(reinterpret_cast(me->m_callback), window, message, wParam, lParam); + HWND& winHandle = *handle; + winHandle = CreateWindowExW(styleEx, className, title, style, x, y, width, height, nullptr, nullptr, GetModuleHandle(nullptr), window); + + mutex->Lock(); + condition->Signal(); + mutex->Unlock(); // mutex et condition sont considérés invalides à partir d'ici + + if (!winHandle) + return; + + while (window->m_threadActive) + window->ProcessEvents(true); + + DestroyWindow(winHandle); } - - return DefWindowProcW(window, message, wParam, lParam); -} - -nzUInt32 NzWindowImpl::RetrieveStyle(HWND handle) -{ - nzUInt32 style = 0; - - LONG_PTR winStyle = GetWindowLongPtr(handle, GWL_STYLE); - - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms632600(v=vs.85).aspx - if (winStyle & WS_CAPTION) - { - style |= nzWindowStyle_Titlebar; - if (winStyle & WS_SYSMENU) - style |= nzWindowStyle_Closable; - - if (winStyle & WS_MAXIMIZEBOX) - style |= nzWindowStyle_Resizable; - } - - if (winStyle & WS_SIZEBOX) - style |= nzWindowStyle_Resizable; - - // Pour déterminer si la fenêtre est en plein écran, il suffit de vérifier si elle recouvre l'écran - DEVMODE mode; - mode.dmSize = sizeof(DEVMODE); - EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &mode); - - RECT rect; - if (GetWindowRect(handle, &rect)) - { - if (static_cast(rect.right-rect.left) == mode.dmPelsWidth && static_cast(rect.bottom-rect.top) == mode.dmPelsHeight) - style |= nzWindowStyle_Fullscreen; - } - - return style; -} - -#if NAZARA_UTILITY_THREADED_WINDOW -void NzWindowImpl::WindowThread(HWND* handle, DWORD styleEx, const wchar_t* title, DWORD style, unsigned int x, unsigned int y, unsigned int width, unsigned int height, NzWindowImpl* window, NzMutex* mutex, NzConditionVariable* condition) -{ - HWND& winHandle = *handle; - winHandle = CreateWindowExW(styleEx, className, title, style, x, y, width, height, nullptr, nullptr, GetModuleHandle(nullptr), window); - - mutex->Lock(); - condition->Signal(); - mutex->Unlock(); // mutex et condition sont considérés invalides à partir d'ici - - if (!winHandle) - return; - - while (window->m_threadActive) - window->ProcessEvents(true); - - DestroyWindow(winHandle); -} #endif +} diff --git a/src/Nazara/Utility/Win32/WindowImpl.hpp b/src/Nazara/Utility/Win32/WindowImpl.hpp index 288150ad9..b0fcf8ae0 100644 --- a/src/Nazara/Utility/Win32/WindowImpl.hpp +++ b/src/Nazara/Utility/Win32/WindowImpl.hpp @@ -20,100 +20,104 @@ #include #include -#if NAZARA_UTILITY_THREADED_WINDOW -class NzConditionVariable; -class NzMutex; -#endif -class NzWindow; - -#undef IsMinimized // Conflit avec la méthode du même nom - -class NzWindowImpl +namespace Nz { - public: - NzWindowImpl(NzWindow* parent); - NzWindowImpl(const NzWindowImpl&) = delete; - NzWindowImpl(NzWindowImpl&&) = delete; ///TODO? - ~NzWindowImpl() = default; + #if NAZARA_UTILITY_THREADED_WINDOW + class ConditionVariable; + class Mutex; + #endif + class Window; - bool Create(const NzVideoMode& mode, const NzString& title, nzUInt32 style); - bool Create(NzWindowHandle handle); + #undef IsMinimized // Conflit avec la méthode du même nom - void Destroy(); + class WindowImpl + { + public: + WindowImpl(Window* parent); + WindowImpl(const WindowImpl&) = delete; + WindowImpl(WindowImpl&&) = delete; ///TODO? + ~WindowImpl() = default; - void EnableKeyRepeat(bool enable); - void EnableSmoothScrolling(bool enable); + bool Create(const VideoMode& mode, const String& title, UInt32 style); + bool Create(WindowHandle handle); - NzWindowHandle GetHandle() const; - unsigned int GetHeight() const; - NzVector2i GetPosition() const; - NzVector2ui GetSize() const; - nzUInt32 GetStyle() const; - NzString GetTitle() const; - unsigned int GetWidth() const; + void Destroy(); - bool HasFocus() const; + void EnableKeyRepeat(bool enable); + void EnableSmoothScrolling(bool enable); - void IgnoreNextMouseEvent(int mouseX, int mouseY); + WindowHandle GetHandle() const; + unsigned int GetHeight() const; + Vector2i GetPosition() const; + Vector2ui GetSize() const; + UInt32 GetStyle() const; + String GetTitle() const; + unsigned int GetWidth() const; - bool IsMinimized() const; - bool IsVisible() const; + bool HasFocus() const; - void ProcessEvents(bool block); + void IgnoreNextMouseEvent(int mouseX, int mouseY); - void SetCursor(nzWindowCursor cursor); - void SetCursor(const NzCursor& cursor); - void SetEventListener(bool listener); - void SetFocus(); - void SetIcon(const NzIcon& icon); - void SetMaximumSize(int width, int height); - void SetMinimumSize(int width, int height); - void SetPosition(int x, int y); - void SetSize(unsigned int width, unsigned int height); - void SetStayOnTop(bool stayOnTop); - void SetTitle(const NzString& title); - void SetVisible(bool visible); + bool IsMinimized() const; + bool IsVisible() const; - NzWindowImpl& operator=(const NzWindowImpl&) = delete; - NzWindowImpl& operator=(NzWindowImpl&&) = delete; ///TODO? + void ProcessEvents(bool block); - static bool Initialize(); - static void Uninitialize(); + void SetCursor(WindowCursor cursor); + void SetCursor(const Cursor& cursor); + void SetEventListener(bool listener); + void SetFocus(); + void SetIcon(const Icon& icon); + void SetMaximumSize(int width, int height); + void SetMinimumSize(int width, int height); + void SetPosition(int x, int y); + void SetSize(unsigned int width, unsigned int height); + void SetStayOnTop(bool stayOnTop); + void SetTitle(const String& title); + void SetVisible(bool visible); - private: - bool HandleMessage(HWND window, UINT message, WPARAM wParam, LPARAM lParam); + WindowImpl& operator=(const WindowImpl&) = delete; + WindowImpl& operator=(WindowImpl&&) = delete; ///TODO? - static NzKeyboard::Key ConvertVirtualKey(WPARAM key, LPARAM flags); - static LRESULT CALLBACK MessageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam); - static nzUInt32 RetrieveStyle(HWND window); - #if NAZARA_UTILITY_THREADED_WINDOW - static void WindowThread(HWND* handle, DWORD styleEx, const wchar_t* title, DWORD style, unsigned int x, unsigned int y, unsigned int width, unsigned int height, NzWindowImpl* window, NzMutex* mutex, NzConditionVariable* condition); - #endif + static bool Initialize(); + static void Uninitialize(); + + private: + bool HandleMessage(HWND window, UINT message, WPARAM wParam, LPARAM lParam); + + static Keyboard::Key ConvertVirtualKey(WPARAM key, LPARAM flags); + static LRESULT CALLBACK MessageHandler(HWND window, UINT message, WPARAM wParam, LPARAM lParam); + static UInt32 RetrieveStyle(HWND window); + #if NAZARA_UTILITY_THREADED_WINDOW + static void WindowThread(HWND* handle, DWORD styleEx, const wchar_t* title, DWORD style, unsigned int x, unsigned int y, unsigned int width, unsigned int height, WindowImpl* window, Mutex* mutex, ConditionVariable* condition); + #endif + + HCURSOR m_cursor; + HWND m_handle; + LONG_PTR m_callback; + UInt32 m_style; + Vector2i m_maxSize; + Vector2i m_minSize; + Vector2i m_mousePos; + Vector2i m_position; + Vector2ui m_size; + #if NAZARA_UTILITY_THREADED_WINDOW + Thread m_thread; + #endif + Window* m_parent; + bool m_eventListener; + bool m_keyRepeat; + bool m_mouseInside; + bool m_ownsWindow; + #if !NAZARA_UTILITY_THREADED_WINDOW + bool m_sizemove; + #endif + bool m_smoothScrolling; + #if NAZARA_UTILITY_THREADED_WINDOW + bool m_threadActive; + #endif + short m_scrolling; + }; +} - HCURSOR m_cursor; - HWND m_handle; - LONG_PTR m_callback; - nzUInt32 m_style; - NzVector2i m_maxSize; - NzVector2i m_minSize; - NzVector2i m_mousePos; - NzVector2i m_position; - NzVector2ui m_size; - #if NAZARA_UTILITY_THREADED_WINDOW - NzThread m_thread; - #endif - NzWindow* m_parent; - bool m_eventListener; - bool m_keyRepeat; - bool m_mouseInside; - bool m_ownsWindow; - #if !NAZARA_UTILITY_THREADED_WINDOW - bool m_sizemove; - #endif - bool m_smoothScrolling; - #if NAZARA_UTILITY_THREADED_WINDOW - bool m_threadActive; - #endif - short m_scrolling; -}; #endif // NAZARA_WINDOWIMPL_HPP diff --git a/src/Nazara/Utility/Window.cpp b/src/Nazara/Utility/Window.cpp index e390aac5e..fec1615af 100644 --- a/src/Nazara/Utility/Window.cpp +++ b/src/Nazara/Utility/Window.cpp @@ -21,721 +21,724 @@ #include -namespace +namespace Nz { - NzWindow* fullscreenWindow = nullptr; -} - -NzWindow::NzWindow() : -#if NAZARA_UTILITY_THREADED_WINDOW -m_impl(nullptr), -m_eventListener(true), -m_waitForEvent(false) -#else -m_impl(nullptr) -#endif -{ -} - -NzWindow::NzWindow(NzVideoMode mode, const NzString& title, nzUInt32 style) : -#if NAZARA_UTILITY_THREADED_WINDOW -m_impl(nullptr), -m_eventListener(true), -m_waitForEvent(false) -#else -m_impl(nullptr) -#endif -{ - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - Create(mode, title, style); -} - -NzWindow::NzWindow(NzWindowHandle handle) : -#if NAZARA_UTILITY_THREADED_WINDOW -m_impl(nullptr), -m_eventListener(true), -m_waitForEvent(false) -#else -m_impl(nullptr) -#endif -{ - NzErrorFlags flags(nzErrorFlag_ThrowException, true); - Create(handle); -} - -NzWindow::~NzWindow() -{ - Destroy(); -} - -void NzWindow::Close() -{ - m_closed = true; // On retarde la fermeture jusqu'au prochain IsOpen -} - -bool NzWindow::Create(NzVideoMode mode, const NzString& title, nzUInt32 style) -{ - // Si la fenêtre est déjà ouverte, nous conservons sa position - bool opened = IsOpen(); - NzVector2i position; - if (opened) - position = m_impl->GetPosition(); - - Destroy(); - - // Inspiré du code de la SFML par Laurent Gomila - if (style & nzWindowStyle_Fullscreen) + namespace { - if (fullscreenWindow) + Window* fullscreenWindow = nullptr; + } + + Window::Window() : + #if NAZARA_UTILITY_THREADED_WINDOW + m_impl(nullptr), + m_eventListener(true), + m_waitForEvent(false) + #else + m_impl(nullptr) + #endif + { + } + + Window::Window(VideoMode mode, const String& title, UInt32 style) : + #if NAZARA_UTILITY_THREADED_WINDOW + m_impl(nullptr), + m_eventListener(true), + m_waitForEvent(false) + #else + m_impl(nullptr) + #endif + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + Create(mode, title, style); + } + + Window::Window(WindowHandle handle) : + #if NAZARA_UTILITY_THREADED_WINDOW + m_impl(nullptr), + m_eventListener(true), + m_waitForEvent(false) + #else + m_impl(nullptr) + #endif + { + ErrorFlags flags(ErrorFlag_ThrowException, true); + Create(handle); + } + + Window::~Window() + { + Destroy(); + } + + void Window::Close() + { + m_closed = true; // On retarde la fermeture jusqu'au prochain IsOpen + } + + bool Window::Create(VideoMode mode, const String& title, UInt32 style) + { + // Si la fenêtre est déjà ouverte, nous conservons sa position + bool opened = IsOpen(); + Vector2i position; + if (opened) + position = m_impl->GetPosition(); + + Destroy(); + + // Inspiré du code de la SFML par Laurent Gomila + if (style & WindowStyle_Fullscreen) { - NazaraError("Window " + NzString::Pointer(fullscreenWindow) + " already in fullscreen mode"); - style &= ~nzWindowStyle_Fullscreen; - } - else - { - if (!mode.IsFullscreenValid()) + if (fullscreenWindow) { - NazaraWarning("Video mode is not fullscreen valid"); - mode = NzVideoMode::GetFullscreenModes()[0]; + NazaraError("Window " + String::Pointer(fullscreenWindow) + " already in fullscreen mode"); + style &= ~WindowStyle_Fullscreen; } + else + { + if (!mode.IsFullscreenValid()) + { + NazaraWarning("Video mode is not fullscreen valid"); + mode = VideoMode::GetFullscreenModes()[0]; + } - fullscreenWindow = this; + fullscreenWindow = this; + } } - } - else if (style & nzWindowStyle_Closable || style & nzWindowStyle_Resizable) - style |= nzWindowStyle_Titlebar; + else if (style & WindowStyle_Closable || style & WindowStyle_Resizable) + style |= WindowStyle_Titlebar; - m_impl = new NzWindowImpl(this); - if (!m_impl->Create(mode, title, style)) - { - NazaraError("Failed to create window implementation"); - delete m_impl; - m_impl = nullptr; - - return false; - } - - m_closed = false; - m_ownsWindow = true; - - if (!OnWindowCreated()) - { - NazaraError("Failed to initialize window extension"); - delete m_impl; - m_impl = nullptr; - - return false; - } - - // Paramètres par défaut - m_impl->EnableKeyRepeat(true); - m_impl->EnableSmoothScrolling(false); - m_impl->SetCursor(nzWindowCursor_Default); - m_impl->SetMaximumSize(-1, -1); - m_impl->SetMinimumSize(-1, -1); - m_impl->SetVisible(true); - - if (opened) - m_impl->SetPosition(position.x, position.y); - - return true; -} - -bool NzWindow::Create(NzWindowHandle handle) -{ - Destroy(); - - m_impl = new NzWindowImpl(this); - if (!m_impl->Create(handle)) - { - NazaraError("Unable to create window implementation"); - delete m_impl; - m_impl = nullptr; - - return false; - } - - m_closed = false; - m_ownsWindow = false; - - if (!OnWindowCreated()) - { - NazaraError("Failed to initialize window's derivate"); - delete m_impl; - m_impl = nullptr; - - return false; - } - - return true; -} - -void NzWindow::Destroy() -{ - if (m_impl) - { - OnWindowDestroy(); - - m_impl->Destroy(); - delete m_impl; - m_impl = nullptr; - - if (fullscreenWindow == this) - fullscreenWindow = nullptr; - } -} - -void NzWindow::EnableKeyRepeat(bool enable) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif - - m_impl->EnableKeyRepeat(enable); -} - -void NzWindow::EnableSmoothScrolling(bool enable) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif - - m_impl->EnableSmoothScrolling(enable); -} - -NzWindowHandle NzWindow::GetHandle() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return static_cast(0); - } - #endif - - return m_impl->GetHandle(); -} - -unsigned int NzWindow::GetHeight() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return 0; - } - #endif - - return m_impl->GetHeight(); -} - -NzVector2i NzWindow::GetPosition() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return NzVector2i::Zero(); - } - #endif - - return m_impl->GetPosition(); -} - -NzVector2ui NzWindow::GetSize() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return NzVector2ui::Zero(); - } - #endif - - return m_impl->GetSize(); -} - -nzUInt32 NzWindow::GetStyle() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return 0; - } - #endif - - return m_impl->GetStyle(); -} - -NzString NzWindow::GetTitle() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return NzString(); - } - #endif - - return m_impl->GetTitle(); -} - -unsigned int NzWindow::GetWidth() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return 0; - } - #endif - - return m_impl->GetWidth(); -} - -bool NzWindow::HasFocus() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return false; - } - #endif - - return m_impl->HasFocus(); -} - -bool NzWindow::IsOpen(bool checkClosed) -{ - if (m_impl) - { - if (m_closed && checkClosed) + m_impl = new WindowImpl(this); + if (!m_impl->Create(mode, title, style)) { - Destroy(); + NazaraError("Failed to create window implementation"); + delete m_impl; + m_impl = nullptr; + return false; } + + m_closed = false; + m_ownsWindow = true; + + if (!OnWindowCreated()) + { + NazaraError("Failed to initialize window extension"); + delete m_impl; + m_impl = nullptr; + + return false; + } + + // Paramètres par défaut + m_impl->EnableKeyRepeat(true); + m_impl->EnableSmoothScrolling(false); + m_impl->SetCursor(WindowCursor_Default); + m_impl->SetMaximumSize(-1, -1); + m_impl->SetMinimumSize(-1, -1); + m_impl->SetVisible(true); + + if (opened) + m_impl->SetPosition(position.x, position.y); + + return true; + } + + bool Window::Create(WindowHandle handle) + { + Destroy(); + + m_impl = new WindowImpl(this); + if (!m_impl->Create(handle)) + { + NazaraError("Unable to create window implementation"); + delete m_impl; + m_impl = nullptr; + + return false; + } + + m_closed = false; + m_ownsWindow = false; + + if (!OnWindowCreated()) + { + NazaraError("Failed to initialize window's derivate"); + delete m_impl; + m_impl = nullptr; + + return false; + } + + return true; + } + + void Window::Destroy() + { + if (m_impl) + { + OnWindowDestroy(); + + m_impl->Destroy(); + delete m_impl; + m_impl = nullptr; + + if (fullscreenWindow == this) + fullscreenWindow = nullptr; + } + } + + void Window::EnableKeyRepeat(bool enable) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->EnableKeyRepeat(enable); + } + + void Window::EnableSmoothScrolling(bool enable) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->EnableSmoothScrolling(enable); + } + + WindowHandle Window::GetHandle() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return static_cast(0); + } + #endif + + return m_impl->GetHandle(); + } + + unsigned int Window::GetHeight() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return 0; + } + #endif + + return m_impl->GetHeight(); + } + + Vector2i Window::GetPosition() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return Vector2i::Zero(); + } + #endif + + return m_impl->GetPosition(); + } + + Vector2ui Window::GetSize() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return Vector2ui::Zero(); + } + #endif + + return m_impl->GetSize(); + } + + UInt32 Window::GetStyle() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return 0; + } + #endif + + return m_impl->GetStyle(); + } + + String Window::GetTitle() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return String(); + } + #endif + + return m_impl->GetTitle(); + } + + unsigned int Window::GetWidth() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return 0; + } + #endif + + return m_impl->GetWidth(); + } + + bool Window::HasFocus() const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return false; + } + #endif + + return m_impl->HasFocus(); + } + + bool Window::IsOpen(bool checkClosed) + { + if (m_impl) + { + if (m_closed && checkClosed) + { + Destroy(); + return false; + } + else + return true; + } else - return true; - } - else - return false; -} - -bool NzWindow::IsOpen() const -{ - return m_impl != nullptr; -} - -bool NzWindow::IsMinimized() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return false; - } - #endif - - return m_impl->IsMinimized(); -} - -bool NzWindow::IsValid() const -{ - return m_impl != nullptr; -} - -bool NzWindow::IsVisible() const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return false; - } - #endif - - return m_impl->IsVisible(); -} - -bool NzWindow::PollEvent(NzEvent* event) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return false; - } - #endif - - #if NAZARA_UTILITY_THREADED_WINDOW - NzLockGuard lock(m_eventMutex); - #else - m_impl->ProcessEvents(false); - #endif - - if (!m_events.empty()) - { - if (event) - *event = m_events.front(); - - m_events.pop(); - - return true; + return false; } - return false; -} - -void NzWindow::SetCursor(nzWindowCursor cursor) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) + bool Window::IsOpen() const { - NazaraError("Window not created"); - return; - } - #endif - - m_impl->SetCursor(cursor); -} - -void NzWindow::SetCursor(const NzCursor& cursor) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; + return m_impl != nullptr; } - if (!cursor.IsValid()) + bool Window::IsMinimized() const { - NazaraError("Cursor is not valid"); - return; + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return false; + } + #endif + + return m_impl->IsMinimized(); } - #endif - m_impl->SetCursor(cursor); -} - -void NzWindow::SetEventListener(bool listener) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) + bool Window::IsValid() const { - NazaraError("Window not created"); - return; + return m_impl != nullptr; } - #endif - #if NAZARA_UTILITY_THREADED_WINDOW - m_impl->SetEventListener(listener); - if (!listener) + bool Window::IsVisible() const { - // On vide la pile des évènements - NzLockGuard lock(m_eventMutex); - while (!m_events.empty()) + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return false; + } + #endif + + return m_impl->IsVisible(); + } + + bool Window::PollEvent(WindowEvent* event) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return false; + } + #endif + + #if NAZARA_UTILITY_THREADED_WINDOW + LockGuard lock(m_eventMutex); + #else + m_impl->ProcessEvents(false); + #endif + + if (!m_events.empty()) + { + if (event) + *event = m_events.front(); + m_events.pop(); - } - #else - if (m_ownsWindow) - { - // Inutile de transmettre l'ordre dans ce cas-là - if (!listener) - NazaraError("A non-threaded window needs to listen to events"); - } - else - m_impl->SetEventListener(listener); - #endif -} -void NzWindow::SetFocus() -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif + return true; + } - m_impl->SetFocus(); -} - -void NzWindow::SetIcon(const NzIcon& icon) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - - if (!icon.IsValid()) - { - NazaraError("Icon is not valid"); - return; - } - #endif - - m_impl->SetIcon(icon); -} - -void NzWindow::SetMaximumSize(const NzVector2i& maxSize) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif - - m_impl->SetMaximumSize(maxSize.x, maxSize.y); -} - -void NzWindow::SetMaximumSize(int width, int height) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif - - m_impl->SetMaximumSize(width, height); -} - -void NzWindow::SetMinimumSize(const NzVector2i& minSize) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif - - m_impl->SetMinimumSize(minSize.x, minSize.y); -} - -void NzWindow::SetMinimumSize(int width, int height) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif - - m_impl->SetMinimumSize(width, height); -} - -void NzWindow::SetPosition(const NzVector2i& position) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif - - m_impl->SetPosition(position.x, position.y); -} - -void NzWindow::SetPosition(int x, int y) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif - - m_impl->SetPosition(x, y); -} - -void NzWindow::SetSize(const NzVector2i& size) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif - - m_impl->SetSize(size.x, size.y); -} - -void NzWindow::SetSize(unsigned int width, unsigned int height) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif - - m_impl->SetSize(width, height); -} - -void NzWindow::SetStayOnTop(bool stayOnTop) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif - - m_impl->SetStayOnTop(stayOnTop); -} - -void NzWindow::SetTitle(const NzString& title) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif - - m_impl->SetTitle(title); -} - -void NzWindow::SetVisible(bool visible) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); - return; - } - #endif - - m_impl->SetVisible(visible); -} - -bool NzWindow::WaitEvent(NzEvent* event) -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) - { - NazaraError("Window not created"); return false; } - #endif - #if NAZARA_UTILITY_THREADED_WINDOW - NzLockGuard lock(m_eventMutex); - - if (m_events.empty()) + void Window::SetCursor(WindowCursor cursor) { - m_waitForEvent = true; - m_eventConditionMutex.Lock(); - m_eventMutex.Unlock(); - m_eventCondition.Wait(&m_eventConditionMutex); - m_eventMutex.Lock(); - m_eventConditionMutex.Unlock(); - m_waitForEvent = false; + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->SetCursor(cursor); } - if (!m_events.empty()) + void Window::SetCursor(const Cursor& cursor) { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + + if (!cursor.IsValid()) + { + NazaraError("Cursor is not valid"); + return; + } + #endif + + m_impl->SetCursor(cursor); + } + + void Window::SetEventListener(bool listener) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + #if NAZARA_UTILITY_THREADED_WINDOW + m_impl->SetEventListener(listener); + if (!listener) + { + // On vide la pile des évènements + LockGuard lock(m_eventMutex); + while (!m_events.empty()) + m_events.pop(); + } + #else + if (m_ownsWindow) + { + // Inutile de transmettre l'ordre dans ce cas-là + if (!listener) + NazaraError("A non-threaded window needs to listen to events"); + } + else + m_impl->SetEventListener(listener); + #endif + } + + void Window::SetFocus() + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->SetFocus(); + } + + void Window::SetIcon(const Icon& icon) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + + if (!icon.IsValid()) + { + NazaraError("Icon is not valid"); + return; + } + #endif + + m_impl->SetIcon(icon); + } + + void Window::SetMaximumSize(const Vector2i& maxSize) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->SetMaximumSize(maxSize.x, maxSize.y); + } + + void Window::SetMaximumSize(int width, int height) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->SetMaximumSize(width, height); + } + + void Window::SetMinimumSize(const Vector2i& minSize) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->SetMinimumSize(minSize.x, minSize.y); + } + + void Window::SetMinimumSize(int width, int height) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->SetMinimumSize(width, height); + } + + void Window::SetPosition(const Vector2i& position) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->SetPosition(position.x, position.y); + } + + void Window::SetPosition(int x, int y) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->SetPosition(x, y); + } + + void Window::SetSize(const Vector2i& size) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->SetSize(size.x, size.y); + } + + void Window::SetSize(unsigned int width, unsigned int height) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->SetSize(width, height); + } + + void Window::SetStayOnTop(bool stayOnTop) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->SetStayOnTop(stayOnTop); + } + + void Window::SetTitle(const String& title) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->SetTitle(title); + } + + void Window::SetVisible(bool visible) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->SetVisible(visible); + } + + bool Window::WaitEvent(WindowEvent* event) + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return false; + } + #endif + + #if NAZARA_UTILITY_THREADED_WINDOW + LockGuard lock(m_eventMutex); + + if (m_events.empty()) + { + m_waitForEvent = true; + m_eventConditionMutex.Lock(); + m_eventMutex.Unlock(); + m_eventCondition.Wait(&m_eventConditionMutex); + m_eventMutex.Lock(); + m_eventConditionMutex.Unlock(); + m_waitForEvent = false; + } + + if (!m_events.empty()) + { + if (event) + *event = m_events.front(); + + m_events.pop(); + + return true; + } + + return false; + #else + while (m_events.empty()) + m_impl->ProcessEvents(true); + if (event) *event = m_events.front(); m_events.pop(); return true; + #endif } - return false; - #else - while (m_events.empty()) - m_impl->ProcessEvents(true); - - if (event) - *event = m_events.front(); - - m_events.pop(); - - return true; - #endif -} - -bool NzWindow::OnWindowCreated() -{ - return true; -} - -void NzWindow::OnWindowDestroy() -{ -} - -void NzWindow::OnWindowResized() -{ -} - -void NzWindow::IgnoreNextMouseEvent(int mouseX, int mouseY) const -{ - #if NAZARA_UTILITY_SAFE - if (!m_impl) + bool Window::OnWindowCreated() { - NazaraError("Window not created"); - return; + return true; } - #endif - m_impl->IgnoreNextMouseEvent(mouseX, mouseY); -} - -void NzWindow::PushEvent(const NzEvent& event) -{ - #if NAZARA_UTILITY_THREADED_WINDOW - m_eventMutex.Lock(); - #endif - - m_events.push(event); - if (event.type == nzEventType_Resized) - OnWindowResized(); - - #if NAZARA_UTILITY_THREADED_WINDOW - m_eventMutex.Unlock(); - - if (m_waitForEvent) + void Window::OnWindowDestroy() { - m_eventConditionMutex.Lock(); - m_eventCondition.Signal(); - m_eventConditionMutex.Unlock(); } - #endif -} -bool NzWindow::Initialize() -{ - return NzWindowImpl::Initialize(); -} + void Window::OnWindowResized() + { + } -void NzWindow::Uninitialize() -{ - NzWindowImpl::Uninitialize(); + void Window::IgnoreNextMouseEvent(int mouseX, int mouseY) const + { + #if NAZARA_UTILITY_SAFE + if (!m_impl) + { + NazaraError("Window not created"); + return; + } + #endif + + m_impl->IgnoreNextMouseEvent(mouseX, mouseY); + } + + void Window::PushEvent(const WindowEvent& event) + { + #if NAZARA_UTILITY_THREADED_WINDOW + m_eventMutex.Lock(); + #endif + + m_events.push(event); + if (event.type == WindowEventType_Resized) + OnWindowResized(); + + #if NAZARA_UTILITY_THREADED_WINDOW + m_eventMutex.Unlock(); + + if (m_waitForEvent) + { + m_eventConditionMutex.Lock(); + m_eventCondition.Signal(); + m_eventConditionMutex.Unlock(); + } + #endif + } + + bool Window::Initialize() + { + return WindowImpl::Initialize(); + } + + void Window::Uninitialize() + { + WindowImpl::Uninitialize(); + } } diff --git a/src/Nazara/Utility/X11/ScopedXCB.inl b/src/Nazara/Utility/X11/ScopedXCB.inl index b5bc7cb71..8b2710a10 100644 --- a/src/Nazara/Utility/X11/ScopedXCB.inl +++ b/src/Nazara/Utility/X11/ScopedXCB.inl @@ -5,40 +5,43 @@ #include #include -template -NzScopedXCB::NzScopedXCB(T* pointer) : -m_pointer(pointer) +namespace Nz { -} + template + ScopedXCB::ScopedXCB(T* pointer) : + m_pointer(pointer) + { + } -template -NzScopedXCB::~NzScopedXCB() -{ - std::free(m_pointer); -} + template + ScopedXCB::~ScopedXCB() + { + std::free(m_pointer); + } -template -T* NzScopedXCB::operator ->() const -{ - return m_pointer; -} + template + T* ScopedXCB::operator ->() const + { + return m_pointer; + } -template -T** NzScopedXCB::operator &() -{ - return &m_pointer; -} + template + T** ScopedXCB::operator &() + { + return &m_pointer; + } -template -NzScopedXCB::operator bool() const -{ - return m_pointer != nullptr; -} + template + ScopedXCB::operator bool() const + { + return m_pointer != nullptr; + } -template -T* NzScopedXCB::get() const -{ - return m_pointer; + template + T* ScopedXCB::get() const + { + return m_pointer; + } } #include diff --git a/tests/Engine/Core/ByteArray.cpp b/tests/Engine/Core/ByteArray.cpp index 54c8754f5..476643d5e 100644 --- a/tests/Engine/Core/ByteArray.cpp +++ b/tests/Engine/Core/ByteArray.cpp @@ -7,7 +7,7 @@ SCENARIO("ByteArray", "[CORE][BYTEARRAY]") { GIVEN("Allocate and raw constructor") { - NzByteArray byteArray(3); + Nz::ByteArray byteArray(3); THEN("Capacity is 3 and size is 0") { @@ -23,7 +23,7 @@ SCENARIO("ByteArray", "[CORE][BYTEARRAY]") { REQUIRE(byteArray.GetSize() == 4); REQUIRE(byteArray.GetCapacity() >= 4); - REQUIRE(byteArray == NzByteArray("data", 4)); + REQUIRE(byteArray == Nz::ByteArray("data", 4)); REQUIRE(byteArray.ToString() == "data"); } } @@ -32,8 +32,8 @@ SCENARIO("ByteArray", "[CORE][BYTEARRAY]") GIVEN("Iterator and default constructor") { std::string anotherDataString("anotherData"); - NzByteArray defaultByte; - NzByteArray anotherData(anotherDataString.begin(), anotherDataString.end()); + Nz::ByteArray defaultByte; + Nz::ByteArray anotherData(anotherDataString.begin(), anotherDataString.end()); WHEN("We assign 'anotherData' with iterator") { @@ -48,11 +48,11 @@ SCENARIO("ByteArray", "[CORE][BYTEARRAY]") GIVEN("Copy and Move constructor") { - NzByteArray originalArray(3, 64); + Nz::ByteArray originalArray(3, 64); WHEN("We copy") { - NzByteArray copyByteArray(originalArray); + Nz::ByteArray copyByteArray(originalArray); THEN("We get a copy") { @@ -60,13 +60,13 @@ SCENARIO("ByteArray", "[CORE][BYTEARRAY]") AND_WHEN("We modify one") { - for (NzByteArray::size_type i = 0; i < copyByteArray.GetSize(); ++i) + for (Nz::ByteArray::size_type i = 0; i < copyByteArray.GetSize(); ++i) copyByteArray[i] = 46; THEN("They are no more equal") { REQUIRE(copyByteArray != originalArray); - REQUIRE(copyByteArray == NzByteArray(3, 46)); + REQUIRE(copyByteArray == Nz::ByteArray(3, 46)); REQUIRE(copyByteArray.GetConstBuffer() != originalArray.GetConstBuffer()); } } @@ -75,18 +75,18 @@ SCENARIO("ByteArray", "[CORE][BYTEARRAY]") WHEN("We move") { - NzByteArray moveByteArray(std::move(originalArray)); + Nz::ByteArray moveByteArray(std::move(originalArray)); THEN("These results are expected") { - REQUIRE(moveByteArray == NzByteArray(3, 64)); + REQUIRE(moveByteArray == Nz::ByteArray(3, 64)); CHECK(originalArray.IsEmpty()); REQUIRE(originalArray.GetCapacity() == 0); REQUIRE(moveByteArray.GetConstBuffer() != originalArray.GetConstBuffer()); AND_WHEN("We modify the empty one") { - originalArray.Prepend(NzByteArray(3, 64)); + originalArray.Prepend(Nz::ByteArray(3, 64)); THEN("They are no more equal") { @@ -100,9 +100,9 @@ SCENARIO("ByteArray", "[CORE][BYTEARRAY]") GIVEN("Two byte array (abc) and (cba)") { - NzByteArray abc("abc", 3); - NzByteArray cba; - cba = std::move(NzByteArray("cba", 3)); + Nz::ByteArray abc("abc", 3); + Nz::ByteArray cba; + cba = std::move(Nz::ByteArray("cba", 3)); WHEN("We do some antagonists operations") { @@ -116,34 +116,34 @@ SCENARIO("ByteArray", "[CORE][BYTEARRAY]") cba.Erase(cba.end() - 1, cba.end()); cba.Erase(cba.end() - 1); - REQUIRE(abc == NzByteArray("c", 1)); - REQUIRE(cba == NzByteArray("c", 1)); + REQUIRE(abc == Nz::ByteArray("c", 1)); + REQUIRE(cba == Nz::ByteArray("c", 1)); std::string ab("ab"); abc.Insert(abc.begin(), ab.begin(), ab.end()); - cba += NzByteArray("ba", 2); + cba += Nz::ByteArray("ba", 2); - REQUIRE(abc == NzByteArray("abc", 3)); - REQUIRE(cba == NzByteArray("cba", 3)); + REQUIRE(abc == Nz::ByteArray("abc", 3)); + REQUIRE(cba == Nz::ByteArray("cba", 3)); abc.PopBack(); cba.PopFront(); - REQUIRE(abc == NzByteArray("ab", 2)); - REQUIRE(cba == NzByteArray("ba", 2)); + REQUIRE(abc == Nz::ByteArray("ab", 2)); + REQUIRE(cba == Nz::ByteArray("ba", 2)); abc.PushBack('c'); cba.PushFront('c'); - REQUIRE(abc == NzByteArray("abc", 3)); - REQUIRE(cba == NzByteArray("cba", 3)); + REQUIRE(abc == Nz::ByteArray("abc", 3)); + REQUIRE(cba == Nz::ByteArray("cba", 3)); } } } GIVEN("One byte array of capacity 10") { - NzByteArray capacityArray(10); + Nz::ByteArray capacityArray(10); WHEN("We reserve for 100") { @@ -167,7 +167,7 @@ SCENARIO("ByteArray", "[CORE][BYTEARRAY]") } } - NzByteArray::const_pointer oldBuffer = capacityArray.GetConstBuffer(); + Nz::ByteArray::const_pointer oldBuffer = capacityArray.GetConstBuffer(); WHEN("We reserve for 5, add 'data' for 4 and then shrink to fit") { capacityArray.Reserve(5); @@ -192,14 +192,14 @@ SCENARIO("ByteArray", "[CORE][BYTEARRAY]") GIVEN("Three byte array") { - NzByteArray first("hello", 5); - NzByteArray second("world", 5); - NzByteArray third; + Nz::ByteArray first("hello", 5); + Nz::ByteArray second("world", 5); + Nz::ByteArray third; WHEN("We swap first and third, then second and third and finally third and first") { - NzByteArray oldFirst(first); - NzByteArray oldSecond(second); + Nz::ByteArray oldFirst(first); + Nz::ByteArray oldSecond(second); first.Swap(third); std::swap(second, third); diff --git a/tests/Engine/Core/Clock.cpp b/tests/Engine/Core/Clock.cpp index 140b2cf57..5b004f885 100644 --- a/tests/Engine/Core/Clock.cpp +++ b/tests/Engine/Core/Clock.cpp @@ -6,8 +6,8 @@ SCENARIO("Clock", "[CORE][CLOCK]") { GIVEN("A clock paused") { - nzUInt64 initialTime = 1; - NzClock clock(initialTime, true); + Nz::UInt64 initialTime = 1; + Nz::Clock clock(initialTime, true); WHEN("We get time") { @@ -21,7 +21,7 @@ SCENARIO("Clock", "[CORE][CLOCK]") clock.Unpause(); THEN("Time must not be the initialTime") { - NzThread::Sleep(1); + Nz::Thread::Sleep(1); REQUIRE(clock.GetMicroseconds() != initialTime); } } diff --git a/tests/Engine/Core/Color.cpp b/tests/Engine/Core/Color.cpp index 36e988613..40ada67c2 100644 --- a/tests/Engine/Core/Color.cpp +++ b/tests/Engine/Core/Color.cpp @@ -5,17 +5,17 @@ SCENARIO("Color", "[CORE][COLOR]") { GIVEN("Two colors, one red (255) and one gray (128)") { - NzColor red(255, 0, 0); - NzColor grey(128); + Nz::Color red(255, 0, 0); + Nz::Color grey(128); WHEN("We do operations") { THEN("These results are expected") { - red += NzColor(0, 0, 0); - grey *= NzColor(255); - REQUIRE((red + grey) == NzColor(255, 128, 128)); - REQUIRE((red * grey) == NzColor(128, 0, 0)); + red += Nz::Color(0, 0, 0); + grey *= Nz::Color(255); + REQUIRE((red + grey) == Nz::Color(255, 128, 128)); + REQUIRE((red * grey) == Nz::Color(128, 0, 0)); } } } diff --git a/tests/Engine/Core/Directory.cpp b/tests/Engine/Core/Directory.cpp index 4b152776d..5e60ed0ca 100644 --- a/tests/Engine/Core/Directory.cpp +++ b/tests/Engine/Core/Directory.cpp @@ -5,28 +5,28 @@ SCENARIO("Directory", "[CORE][DIRECTORY]") { GIVEN("The current directory") { - NzDirectory currentDirectory(NzDirectory::GetCurrent()); + Nz::Directory currentDirectory(Nz::Directory::GetCurrent()); CHECK(currentDirectory.Exists()); currentDirectory.Open(); WHEN("We create a new directory Test Directory") { - NzDirectory::Create("Test Directory"); + Nz::Directory::Create("Test Directory"); THEN("A new directory has been created") { - CHECK(NzDirectory::Exists(currentDirectory.GetCurrent() + "/Test Directory")); + CHECK(Nz::Directory::Exists(currentDirectory.GetCurrent() + "/Test Directory")); CHECK(currentDirectory.IsOpen()); } } AND_WHEN("We delete it") { - NzDirectory::Remove(currentDirectory.GetCurrent() + "/Test Directory", true); + Nz::Directory::Remove(currentDirectory.GetCurrent() + "/Test Directory", true); THEN("It doesn't exist anymore") { - CHECK(!NzDirectory::Exists(currentDirectory.GetCurrent() + "/Test Directory")); + CHECK(!Nz::Directory::Exists(currentDirectory.GetCurrent() + "/Test Directory")); } } } diff --git a/tests/Engine/Core/Error.cpp b/tests/Engine/Core/Error.cpp index fd1a8fa91..e95f6d990 100644 --- a/tests/Engine/Core/Error.cpp +++ b/tests/Engine/Core/Error.cpp @@ -3,7 +3,7 @@ SCENARIO("Error", "[CORE][ERROR]") { - nzUInt32 oldFlags = NzError::GetFlags(); + Nz::UInt32 oldFlags = Nz::Error::GetFlags(); GIVEN("Multiple errors") { @@ -11,18 +11,18 @@ SCENARIO("Error", "[CORE][ERROR]") { THEN("These errors should be written in the log file") { - NzError::Error(nzErrorType_Internal, "nzErrorType_Internal"); - NzError::Error(nzErrorType_Internal, "nzErrorType_Internal", 2, "Error.cpp", "2nd place Internal"); - REQUIRE("nzErrorType_Internal" == NzError::GetLastError()); - NzError::Error(nzErrorType_Normal, "nzErrorType_Normal"); - NzError::Error(nzErrorType_Normal, "nzErrorType_Normal", 2, "Error.cpp", "2nd place Normal"); - REQUIRE("nzErrorType_Normal" == NzError::GetLastError()); - NzError::Error(nzErrorType_Warning, "nzErrorType_Warning"); - NzError::Error(nzErrorType_Warning, "nzErrorType_Warning", 2, "Error.cpp", "2nd place Warning"); - REQUIRE("nzErrorType_Warning" == NzError::GetLastError()); + Nz::Error::Trigger(Nz::ErrorType_Internal, "ErrorType_Internal"); + Nz::Error::Trigger(Nz::ErrorType_Internal, "ErrorType_Internal", 2, "Error.cpp", "2nd place Internal"); + REQUIRE("ErrorType_Internal" == Nz::Error::GetLastError()); + Nz::Error::Trigger(Nz::ErrorType_Normal, "ErrorType_Normal"); + Nz::Error::Trigger(Nz::ErrorType_Normal, "ErrorType_Normal", 2, "Error.cpp", "2nd place Normal"); + REQUIRE("ErrorType_Normal" == Nz::Error::GetLastError()); + Nz::Error::Trigger(Nz::ErrorType_Warning, "ErrorType_Warning"); + Nz::Error::Trigger(Nz::ErrorType_Warning, "ErrorType_Warning", 2, "Error.cpp", "2nd place Warning"); + REQUIRE("ErrorType_Warning" == Nz::Error::GetLastError()); } } } - NzError::SetFlags(oldFlags); + Nz::Error::SetFlags(oldFlags); } diff --git a/tests/Engine/Core/File.cpp b/tests/Engine/Core/File.cpp index 7da5ad689..ae29407cb 100644 --- a/tests/Engine/Core/File.cpp +++ b/tests/Engine/Core/File.cpp @@ -7,14 +7,14 @@ SCENARIO("File", "[CORE][FILE]") { WHEN("We create a new file") { - NzFile file("Test File.txt", nzOpenMode_ReadWrite); - REQUIRE(file.GetDirectory() == NzDirectory::GetCurrent() + NAZARA_DIRECTORY_SEPARATOR); + Nz::File file("Test File.txt", Nz::OpenMode_ReadWrite); + REQUIRE(file.GetDirectory() == Nz::Directory::GetCurrent() + NAZARA_DIRECTORY_SEPARATOR); CHECK(file.IsOpen()); THEN("We are allowed to write 3 times 'Test String'") { const char message[12] = "Test String"; // 11 + '\0' - NzByteArray byteArray(message, 11); + Nz::ByteArray byteArray(message, 11); file.Write("Test String"); file.Write(byteArray); file.Write(message, sizeof(char), 11); @@ -25,11 +25,11 @@ SCENARIO("File", "[CORE][FILE]") char message[12]; REQUIRE(file.Read(message, 11) == 11); message[11] = '\0'; - REQUIRE(NzString(message) == "Test String"); + REQUIRE(Nz::String(message) == "Test String"); REQUIRE(file.Read(message, sizeof(char), 11) == 11); message[11] = '\0'; - REQUIRE(NzString(message) == "Test String"); + REQUIRE(Nz::String(message) == "Test String"); } AND_THEN("We close it") @@ -42,11 +42,11 @@ SCENARIO("File", "[CORE][FILE]") WHEN("We delete this file") { - NzFile::Delete("Test File.txt"); + Nz::File::Delete("Test File.txt"); THEN("It doesn't exist anymore") { - CHECK(!NzFile::Exists("Test File.txt")); + CHECK(!Nz::File::Exists("Test File.txt")); } } } diff --git a/tests/Engine/Core/String.cpp b/tests/Engine/Core/String.cpp index 80e227ef1..a563d0b7f 100644 --- a/tests/Engine/Core/String.cpp +++ b/tests/Engine/Core/String.cpp @@ -5,7 +5,7 @@ SCENARIO("String", "[CORE][STRING]") { GIVEN("One string 'a'") { - NzString aDefaultString(1, 'a'); + Nz::String aDefaultString(1, 'a'); WHEN("We add information") { @@ -25,12 +25,12 @@ SCENARIO("String", "[CORE][STRING]") { CHECK(aDefaultString.Contains('D')); CHECK(aDefaultString.Contains("String", 3)); - CHECK(aDefaultString.Contains(NzString("sTRING"), 3, NzString::CaseInsensitive)); + CHECK(aDefaultString.Contains(Nz::String("sTRING"), 3, Nz::String::CaseInsensitive)); REQUIRE(aDefaultString.FindLast('g') == aDefaultString.GetSize() - 1); - CHECK(aDefaultString.EndsWith('G', NzString::CaseInsensitive)); + CHECK(aDefaultString.EndsWith('G', Nz::String::CaseInsensitive)); aDefaultString.Append(" ng bla"); REQUIRE(aDefaultString.FindWord("ng") == aDefaultString.GetSize() - 6); - //TODO REQUIRE(aDefaultString.FindWord(NzString("ng")) == aDefaultString.GetSize() - 6); + //TODO REQUIRE(aDefaultString.FindWord(String("ng")) == aDefaultString.GetSize() - 6); CHECK(aDefaultString.StartsWith("aD")); } } @@ -62,14 +62,14 @@ SCENARIO("String", "[CORE][STRING]") GIVEN("The string of number 16 in base 16") { - NzString number16; + Nz::String number16; CHECK(number16.IsEmpty()); CHECK(number16.IsNull()); WHEN("We assign to number 16") { - number16 = NzString::Number(16, 16); + number16 = Nz::String::Number(16, 16); THEN("These results are expected") { @@ -85,7 +85,7 @@ SCENARIO("String", "[CORE][STRING]") /* TODO GIVEN("One unicode string") { - NzString unicodeString = NzString::Unicode(U"àéçœÂ官話"); + String unicodeString = String::Unicode(U"àéçœÂ官話"); WHEN("We convert to other UTF") { @@ -96,11 +96,11 @@ SCENARIO("String", "[CORE][STRING]") THEN("The result should be the identity") { char* utf8 = unicodeString.GetUtf8Buffer(); - NzString utf8String = NzString::Unicode(utf8); + String utf8String = String::Unicode(utf8); char16_t* utf16 = unicodeString.GetUtf16Buffer(); - NzString utf16String = NzString::Unicode(utf16); + String utf16String = String::Unicode(utf16); char32_t* utf32 = unicodeString.GetUtf32Buffer(); - NzString utf32String = NzString::Unicode(utf32); + String utf32String = String::Unicode(utf32); REQUIRE(utf8String == utf16String); REQUIRE(utf16String == utf32String); diff --git a/tests/Engine/Core/StringStream.cpp b/tests/Engine/Core/StringStream.cpp index 6d8e35bbf..5efb9e926 100644 --- a/tests/Engine/Core/StringStream.cpp +++ b/tests/Engine/Core/StringStream.cpp @@ -5,67 +5,67 @@ SCENARIO("StringStream", "[CORE][STRINGSTREAM]") { GIVEN("A string stream") { - NzStringStream stringstream("default"); + Nz::StringStream stringStream("default"); WHEN("We add bool and char") { - stringstream << true; + stringStream << true; char valueCharSigned = 64; - stringstream << valueCharSigned; + stringStream << valueCharSigned; unsigned char valueCharUnsigned = 64; - stringstream << valueCharUnsigned; + stringStream << valueCharUnsigned; - REQUIRE(stringstream.ToString() == "defaulttrue@@"); + REQUIRE(stringStream.ToString() == "defaulttrue@@"); } AND_WHEN("We add short and int") { short valueShortSigned = -3; - stringstream << valueShortSigned; + stringStream << valueShortSigned; unsigned short valueShortUnsigned = 3; - stringstream << valueShortUnsigned; + stringStream << valueShortUnsigned; int valueIntSigned = -3; - stringstream << valueIntSigned; + stringStream << valueIntSigned; unsigned int valueIntUnsigned = 3; - stringstream << valueIntUnsigned; + stringStream << valueIntUnsigned; - REQUIRE(stringstream.ToString() == "default-33-33"); + REQUIRE(stringStream.ToString() == "default-33-33"); } AND_WHEN("We add long and long long") { long valueLongSigned = -3; - stringstream << valueLongSigned; + stringStream << valueLongSigned; unsigned long valueLongUnsigned = 3; - stringstream << valueLongUnsigned; + stringStream << valueLongUnsigned; long long valueLongLongSigned = -3; - stringstream << valueLongLongSigned; + stringStream << valueLongLongSigned; unsigned long long valueLongLongUnsigned = 3; - stringstream << valueLongLongUnsigned; + stringStream << valueLongLongUnsigned; - REQUIRE(stringstream.ToString() == "default-33-33"); + REQUIRE(stringStream.ToString() == "default-33-33"); } AND_WHEN("We add floating points") { - stringstream << 3.f; - stringstream << 3.0; - stringstream << 3.0L; + stringStream << 3.f; + stringStream << 3.0; + stringStream << 3.0L; - REQUIRE(stringstream.ToString() == "default333"); + REQUIRE(stringStream.ToString() == "default333"); } AND_WHEN("We add string and pointer") { - stringstream << "3"; - stringstream << std::string("3"); - stringstream << NzString("3"); - stringstream << static_cast(nullptr); + stringStream << "3"; + stringStream << std::string("3"); + stringStream << Nz::String("3"); + stringStream << static_cast(nullptr); - REQUIRE(stringstream.ToString() == (NzString("default333") + NzString::Pointer(nullptr))); + REQUIRE(stringStream.ToString() == (Nz::String("default333") + Nz::String::Pointer(nullptr))); } } } diff --git a/tests/Engine/Math/Algorithm.cpp b/tests/Engine/Math/Algorithm.cpp index f0bcbc0f1..1f37b066d 100644 --- a/tests/Engine/Math/Algorithm.cpp +++ b/tests/Engine/Math/Algorithm.cpp @@ -5,17 +5,17 @@ TEST_CASE("Approach", "[MATH][ALGORITHM]" ) { SECTION("Approach 8 with 5 by 2") { - REQUIRE(NzApproach(5, 8, 2) == 7); + REQUIRE(Nz::Approach(5, 8, 2) == 7); } SECTION("Approach 5 with 8 by 2") { - REQUIRE(NzApproach(8, 5, 2) == 6); + REQUIRE(Nz::Approach(8, 5, 2) == 6); } SECTION("Approach 8 with 8 by 2") { - REQUIRE(NzApproach(8, 8, 2) == 8); + REQUIRE(Nz::Approach(8, 8, 2) == 8); } } @@ -23,17 +23,17 @@ TEST_CASE("Clamp", "[ALGORITHM]" ) { SECTION("Clamp 8 between 5 and 10") { - REQUIRE(NzClamp(8, 5, 10) == 8); + REQUIRE(Nz::Clamp(8, 5, 10) == 8); } SECTION("Clamp 4 between 5 and 10") { - REQUIRE(NzClamp(4, 5, 10) == 5); + REQUIRE(Nz::Clamp(4, 5, 10) == 5); } SECTION("Clamp 12 between 5 and 10") { - REQUIRE(NzClamp(12, 5, 10) == 10); + REQUIRE(Nz::Clamp(12, 5, 10) == 10); } } @@ -41,7 +41,7 @@ TEST_CASE("DegreeToRadian", "[ALGORITHM]" ) { SECTION("Convert 45.f degree to radian") { - REQUIRE(NzDegreeToRadian(45.f) == Approx(M_PI / 4)); + REQUIRE(Nz::NzDegreeToRadian(45.f) == Approx(M_PI / 4)); } } @@ -49,12 +49,12 @@ TEST_CASE("GetNearestPowerOfTwo", "[ALGORITHM]" ) { SECTION("Nearest power of two of 16 = 16") { - REQUIRE(NzGetNearestPowerOfTwo(16) == 16); + REQUIRE(Nz::GetNearestPowerOfTwo(16) == 16); } SECTION("Nearest power of two of 17 = 32") { - REQUIRE(NzGetNearestPowerOfTwo(17) == 32); + REQUIRE(Nz::GetNearestPowerOfTwo(17) == 32); } } @@ -63,55 +63,55 @@ TEST_CASE("GetNumberLength", "[ALGORITHM]" ) SECTION("GetNumberLength of -127 signed char") { signed char minus127 = -127; - REQUIRE(NzGetNumberLength(minus127) == 4); + REQUIRE(Nz::GetNumberLength(minus127) == 4); } SECTION("GetNumberLength of 255 unsigned char") { unsigned char plus255 = 255; - REQUIRE(NzGetNumberLength(plus255) == 3); + REQUIRE(Nz::GetNumberLength(plus255) == 3); } SECTION("GetNumberLength of -1270 signed int") { signed int minus1270 = -1270; - REQUIRE(NzGetNumberLength(minus1270) == 5); + REQUIRE(Nz::GetNumberLength(minus1270) == 5); } SECTION("GetNumberLength of 2550 unsigned int") { unsigned int plus2550 = 2550; - REQUIRE(NzGetNumberLength(plus2550) == 4); + REQUIRE(Nz::GetNumberLength(plus2550) == 4); } SECTION("GetNumberLength of -1270 signed long long") { signed long long minus12700 = -12700; - REQUIRE(NzGetNumberLength(minus12700) == 6); + REQUIRE(Nz::GetNumberLength(minus12700) == 6); } SECTION("GetNumberLength of 2550 unsigned long long") { unsigned long long plus25500 = 25500; - REQUIRE(NzGetNumberLength(plus25500) == 5); + REQUIRE(Nz::GetNumberLength(plus25500) == 5); } SECTION("GetNumberLength of -2.456f float") { float minus2P456 = -2.456f; - REQUIRE(NzGetNumberLength(minus2P456, 3) == 6); + REQUIRE(Nz::GetNumberLength(minus2P456, 3) == 6); } SECTION("GetNumberLength of -2.456 double") { double minus2P456 = -2.456; - REQUIRE(NzGetNumberLength(minus2P456, 3) == 6); + REQUIRE(Nz::GetNumberLength(minus2P456, 3) == 6); } SECTION("GetNumberLength of -2.456 long double") { long double minus2P456 = -2.456L; - REQUIRE(NzGetNumberLength(minus2P456, 3) == 6); + REQUIRE(Nz::GetNumberLength(minus2P456, 3) == 6); } } @@ -119,7 +119,7 @@ TEST_CASE("IntegralPow", "[ALGORITHM]" ) { SECTION("2 to power 4") { - REQUIRE(NzIntegralPow(2, 4) == 16); + REQUIRE(Nz::IntegralPow(2, 4) == 16); } } @@ -127,7 +127,7 @@ TEST_CASE("Lerp", "[ALGORITHM]" ) { SECTION("Lerp 2 to 6 with 0.5") { - REQUIRE(NzLerp(2, 6, 0.5) == 4); + REQUIRE(Nz::Lerp(2, 6, 0.5) == 4); } } @@ -135,7 +135,7 @@ TEST_CASE("MultiplyAdd", "[ALGORITHM]" ) { SECTION("2 * 3 + 1") { - REQUIRE(NzMultiplyAdd(2, 3, 1) == 7); + REQUIRE(Nz::MultiplyAdd(2, 3, 1) == 7); } } @@ -143,12 +143,12 @@ TEST_CASE("NumberEquals", "[ALGORITHM]" ) { SECTION("2.35 and 2.351 should be the same at 0.01") { - CHECK(NzNumberEquals(2.35, 2.35, 0.01)); + CHECK(Nz::NumberEquals(2.35, 2.35, 0.01)); } SECTION("3 and 4 unsigned should be the same at 1") { - CHECK(NzNumberEquals(3U, 4U, 1U)); + CHECK(Nz::NumberEquals(3U, 4U, 1U)); } } @@ -156,17 +156,17 @@ TEST_CASE("NumberToString", "[ALGORITHM]" ) { SECTION("235 to string") { - REQUIRE(NzNumberToString(235) == "235"); + REQUIRE(Nz::NumberToString(235) == "235"); } SECTION("-235 to string") { - REQUIRE(NzNumberToString(-235) == "-235"); + REQUIRE(Nz::NumberToString(-235) == "-235"); } SECTION("16 in base 16 to string") { - REQUIRE(NzNumberToString(16, 16) == "10"); + REQUIRE(Nz::NumberToString(16, 16) == "10"); } } @@ -174,7 +174,7 @@ TEST_CASE("RadianToDegree", "[ALGORITHM]" ) { SECTION("PI / 4 to degree") { - REQUIRE(NzRadianToDegree(M_PI / 4) == Approx(45.f)); + REQUIRE(Nz::RadianToDegree(M_PI / 4) == Approx(45.f)); } } @@ -182,16 +182,16 @@ TEST_CASE("StringToNumber", "[ALGORITHM]" ) { SECTION("235 in string") { - REQUIRE(NzStringToNumber("235") == 235); + REQUIRE(Nz::StringToNumber("235") == 235); } SECTION("-235 in string") { - REQUIRE(NzStringToNumber("-235") == -235); + REQUIRE(Nz::StringToNumber("-235") == -235); } SECTION("16 in base 16 in string") { - REQUIRE(NzStringToNumber("10", 16) == 16); + REQUIRE(Nz::StringToNumber("10", 16) == 16); } } diff --git a/tests/Engine/Math/BoundingVolume.cpp b/tests/Engine/Math/BoundingVolume.cpp index 895999536..05af375bc 100644 --- a/tests/Engine/Math/BoundingVolume.cpp +++ b/tests/Engine/Math/BoundingVolume.cpp @@ -5,8 +5,8 @@ SCENARIO("BoundingVolume", "[MATH][BOUNDINGVOLUME]") { GIVEN("With a null bounding volume and an infinite") { - NzBoundingVolumef nullVolume = NzBoundingVolumef::Null(); - NzBoundingVolumef infiniteVolume = NzBoundingVolumef::Infinite(); + Nz::BoundingVolumef nullVolume = Nz::BoundingVolumef::Null(); + Nz::BoundingVolumef infiniteVolume = Nz::BoundingVolumef::Infinite(); WHEN("We compare them") { @@ -49,18 +49,18 @@ SCENARIO("BoundingVolume", "[MATH][BOUNDINGVOLUME]") { THEN("Everything should be ok") { - REQUIRE(NzBoundingVolumef::Null() == NzBoundingVolumef::Null()); - REQUIRE(NzBoundingVolumef::Infinite() == NzBoundingVolumef::Infinite()); + REQUIRE(Nz::BoundingVolumef::Null() == Nz::BoundingVolumef::Null()); + REQUIRE(Nz::BoundingVolumef::Infinite() == Nz::BoundingVolumef::Infinite()); } } } GIVEN("Two same bounding volume with different constructor") { - NzBoundingVolumef firstCenterAndUnit(0.f, 0.f, 0.f, 1.f, 1.f, 1.f); - NzBoundingVolumef secondCenterAndUnit(NzVector3f::Zero(), NzVector3f::Unit()); - firstCenterAndUnit.Update(NzMatrix4f::Identity()); - secondCenterAndUnit.Update(NzMatrix4f::Identity()); + Nz::BoundingVolumef firstCenterAndUnit(0.f, 0.f, 0.f, 1.f, 1.f, 1.f); + Nz::BoundingVolumef secondCenterAndUnit(Nz::Vector3f::Zero(), Nz::Vector3f::Unit()); + firstCenterAndUnit.Update(Nz::Matrix4f::Identity()); + secondCenterAndUnit.Update(Nz::Matrix4f::Identity()); WHEN("We compare them") { @@ -83,15 +83,15 @@ SCENARIO("BoundingVolume", "[MATH][BOUNDINGVOLUME]") { THEN("There's no problem") { - NzBoundingVolume intVolumeCenterAndUnit(NzBoxi(NzVector3i::Zero(), NzVector3i::Unit())); - NzBoundingVolumef thirdCenterAndUnit(intVolumeCenterAndUnit); + Nz::BoundingVolume intVolumeCenterAndUnit(Nz::Boxi(Nz::Vector3i::Zero(), Nz::Vector3i::Unit())); + Nz::BoundingVolumef thirdCenterAndUnit(intVolumeCenterAndUnit); REQUIRE(thirdCenterAndUnit == secondCenterAndUnit); } } WHEN("We make one twice bigger with a matrix") { - firstCenterAndUnit.Update(NzMatrix4f::Scale(NzVector3f::Unit() * 2.f)); + firstCenterAndUnit.Update(Nz::Matrix4f::Scale(Nz::Vector3f::Unit() * 2.f)); THEN("The local box should be the same but the aabb different") { diff --git a/tests/Engine/Math/Box.cpp b/tests/Engine/Math/Box.cpp index 89e65e0c0..e39e0654c 100644 --- a/tests/Engine/Math/Box.cpp +++ b/tests/Engine/Math/Box.cpp @@ -5,13 +5,13 @@ SCENARIO("Box", "[MATH][BOX]") { GIVEN("Two zero boxes") { - NzBoxf firstZero(NzBoxf::Zero()); - NzBoxf secondZero(NzVector3f::Zero(), NzVector3f::Zero()); + Nz::Boxf firstZero(Nz::Boxf::Zero()); + Nz::Boxf secondZero(Nz::Vector3f::Zero(), Nz::Vector3f::Zero()); WHEN("We multiply them") { firstZero = firstZero * 1.f; - secondZero = secondZero * NzVector3f::Unit() * 3.f; + secondZero = secondZero * Nz::Vector3f::Unit() * 3.f; THEN("They should stay the same") { @@ -24,24 +24,24 @@ SCENARIO("Box", "[MATH][BOX]") GIVEN("Two unit and center boxes") { - NzBoxf firstCenterAndUnit(NzRectf(NzVector2f::Zero(), NzVector2f::Unit())); - NzBoxf secondCenterAndUnit(1.f, 1.f, 1.f); + Nz::Boxf firstCenterAndUnit(Nz::Rectf(Nz::Vector2f::Zero(), Nz::Vector2f::Unit())); + Nz::Boxf secondCenterAndUnit(1.f, 1.f, 1.f); WHEN("We ask for some informations") { THEN("These results are expected") { - REQUIRE(firstCenterAndUnit.GetBoundingSphere() == NzSpheref(NzVector3f::Unit() * 0.5f, std::sqrt(3.f * 0.5f * 0.5f))); - REQUIRE(firstCenterAndUnit.GetCenter() == (NzVector3f::Unit() * 0.5f)); - REQUIRE(firstCenterAndUnit.GetCorner(nzBoxCorner_FarLeftTop) == NzVector3f::UnitY()); - REQUIRE(firstCenterAndUnit.GetLengths() == NzVector3f::Unit()); - REQUIRE(firstCenterAndUnit.GetMaximum() == NzVector3f::Unit()); - REQUIRE(firstCenterAndUnit.GetMinimum() == NzVector3f::Zero()); - REQUIRE(firstCenterAndUnit.GetNegativeVertex(NzVector3f::Unit()) == NzVector3f::Zero()); - REQUIRE(firstCenterAndUnit.GetPosition() == NzVector3f::Zero()); - REQUIRE(firstCenterAndUnit.GetPositiveVertex(NzVector3f::Unit()) == NzVector3f::Unit()); + REQUIRE(firstCenterAndUnit.GetBoundingSphere() == Nz::Spheref(Nz::Vector3f::Unit() * 0.5f, std::sqrt(3.f * 0.5f * 0.5f))); + REQUIRE(firstCenterAndUnit.GetCenter() == (Nz::Vector3f::Unit() * 0.5f)); + REQUIRE(firstCenterAndUnit.GetCorner(Nz::BoxCorner_FarLeftTop) == Nz::Vector3f::UnitY()); + REQUIRE(firstCenterAndUnit.GetLengths() == Nz::Vector3f::Unit()); + REQUIRE(firstCenterAndUnit.GetMaximum() == Nz::Vector3f::Unit()); + REQUIRE(firstCenterAndUnit.GetMinimum() == Nz::Vector3f::Zero()); + REQUIRE(firstCenterAndUnit.GetNegativeVertex(Nz::Vector3f::Unit()) == Nz::Vector3f::Zero()); + REQUIRE(firstCenterAndUnit.GetPosition() == Nz::Vector3f::Zero()); + REQUIRE(firstCenterAndUnit.GetPositiveVertex(Nz::Vector3f::Unit()) == Nz::Vector3f::Unit()); REQUIRE(firstCenterAndUnit.GetRadius() == Approx(std::sqrt(3.f * 0.5f * 0.5f))); - REQUIRE(firstCenterAndUnit.GetSquaredBoundingSphere() == NzSpheref(NzVector3f::Unit() * 0.5f, 3.f * 0.5f * 0.5f)); + REQUIRE(firstCenterAndUnit.GetSquaredBoundingSphere() == Nz::Spheref(Nz::Vector3f::Unit() * 0.5f, 3.f * 0.5f * 0.5f)); REQUIRE(firstCenterAndUnit.GetSquaredRadius() == Approx(3.f * 0.5f * 0.5f)); } } @@ -50,7 +50,7 @@ SCENARIO("Box", "[MATH][BOX]") { THEN("We should have a center and unit") { - NzBoxf thirdCenterAndUnit; + Nz::Boxf thirdCenterAndUnit; CHECK(firstCenterAndUnit.Intersect(secondCenterAndUnit, &thirdCenterAndUnit)); REQUIRE(firstCenterAndUnit == secondCenterAndUnit); } @@ -60,7 +60,7 @@ SCENARIO("Box", "[MATH][BOX]") { THEN("Shouldn't be a problem") { - NzBoxf tmp(NzBoxi(0, 0, 0, 1, 1, 1)); + Nz::Boxf tmp(Nz::Boxi(0, 0, 0, 1, 1, 1)); REQUIRE(tmp == firstCenterAndUnit); } } @@ -68,8 +68,8 @@ SCENARIO("Box", "[MATH][BOX]") GIVEN("Two wrong box (negative width, height and depth") { - NzBoxf firstWrongBox(-NzVector3f::Unit()); - NzBoxf secondWrongBox(-NzVector3f::Unit()); + Nz::Boxf firstWrongBox(-Nz::Vector3f::Unit()); + Nz::Boxf secondWrongBox(-Nz::Vector3f::Unit()); WHEN("We check if valid") { @@ -82,8 +82,8 @@ SCENARIO("Box", "[MATH][BOX]") WHEN("We correct them") { - firstWrongBox.ExtendTo(NzVector3f::Unit()); - secondWrongBox.Transform(NzMatrix4f::Scale(-NzVector3f::Unit())); + firstWrongBox.ExtendTo(Nz::Vector3f::Unit()); + secondWrongBox.Transform(Nz::Matrix4f::Scale(-Nz::Vector3f::Unit())); THEN("They should be valid") { @@ -98,13 +98,13 @@ SCENARIO("Box", "[MATH][BOX]") CHECK(firstWrongBox.Contains(0.f, 0.f, 0.f)); CHECK(secondWrongBox.Contains(0.f, 0.f, 0.f)); - secondWrongBox = secondWrongBox.Lerp(NzBoxf::Zero(), secondWrongBox, 0.f); // Zeroed - secondWrongBox.ExtendTo(NzBoxf(NzVector3f(0.1f, 0.1f, 0.1f), NzVector3f(0.9f, 0.9f, 0.9f))); - secondWrongBox.Translate(NzVector3f(0.05f, 0.05f, 0.05f)); // Box 0.15 to 0.95 + secondWrongBox = secondWrongBox.Lerp(Nz::Boxf::Zero(), secondWrongBox, 0.f); // Zeroed + secondWrongBox.ExtendTo(Nz::Boxf(Nz::Vector3f(0.1f, 0.1f, 0.1f), Nz::Vector3f(0.9f, 0.9f, 0.9f))); + secondWrongBox.Translate(Nz::Vector3f(0.05f, 0.05f, 0.05f)); // Box 0.15 to 0.95 CHECK(firstWrongBox.Contains(secondWrongBox)); - NzBoxf test(1.f, -500.f, -500.f, 1000.f, 1000.f, 1000.f); - CHECK(test.Contains(NzBoxf(500.f, -0.5f, -0.5f, 1.f, 1.f, 1.f))); + Nz::Boxf test(1.f, -500.f, -500.f, 1000.f, 1000.f, 1000.f); + CHECK(test.Contains(Nz::Boxf(500.f, -0.5f, -0.5f, 1.f, 1.f, 1.f))); CHECK(test.Contains(500.f, 0.f, 0.f)); } } diff --git a/tests/Engine/Math/EulerAngles.cpp b/tests/Engine/Math/EulerAngles.cpp index 16168e423..a44efb361 100644 --- a/tests/Engine/Math/EulerAngles.cpp +++ b/tests/Engine/Math/EulerAngles.cpp @@ -5,8 +5,8 @@ SCENARIO("EulerAngles", "[MATH][EULERANGLES]") { GIVEN("Two zero euler angles") { - NzEulerAnglesf firstZero(0.f, 0.f, 0.f); - NzEulerAnglesf secondZero(NzEulerAngles::Zero()); + Nz::EulerAnglesf firstZero(0.f, 0.f, 0.f); + Nz::EulerAnglesf secondZero(Nz::EulerAngles::Zero()); THEN("They should be equal") { @@ -15,12 +15,12 @@ SCENARIO("EulerAngles", "[MATH][EULERANGLES]") WHEN("We do some operations") { - NzEulerAnglesf euler90(90.f, 90.f, 90.f); - NzEulerAnglesf euler270(270.f, 270.f, 270.f); + Nz::EulerAnglesf euler90(90.f, 90.f, 90.f); + Nz::EulerAnglesf euler270(270.f, 270.f, 270.f); - NzEulerAnglesf euler360 = euler90 + euler270; + Nz::EulerAnglesf euler360 = euler90 + euler270; euler360.Normalize(); - NzEulerAnglesf euler0 = euler270 - euler90; + Nz::EulerAnglesf euler0 = euler270 - euler90; euler0 -= euler90; euler0 -= euler90; @@ -36,8 +36,8 @@ SCENARIO("EulerAngles", "[MATH][EULERANGLES]") THEN("They are the same") { REQUIRE(firstZero.ToQuaternion() == secondZero.ToQuaternion()); - REQUIRE(firstZero.ToQuaternion() == NzEulerAnglesf(NzQuaternionf(1.f, 0.f, 0.f, 0.f))); - REQUIRE(secondZero.ToQuaternion() == NzEulerAnglesf(NzQuaternionf(1.f, 0.f, 0.f, 0.f))); + REQUIRE(firstZero.ToQuaternion() == Nz::EulerAnglesf(Nz::Quaternionf(1.f, 0.f, 0.f, 0.f))); + REQUIRE(secondZero.ToQuaternion() == Nz::EulerAnglesf(Nz::Quaternionf(1.f, 0.f, 0.f, 0.f))); } } } @@ -48,32 +48,32 @@ SCENARIO("EulerAngles", "[MATH][EULERANGLES]") { THEN("These results are expected") { - REQUIRE(NzEulerAngles(NzFromDegrees(45.f), 0.f, 0.f) == NzEulerAngles(NzQuaternionf(0.923879504204f, 0.382683455944f, 0.f, 0.f).ToEulerAngles())); - REQUIRE(NzEulerAngles(0.f, NzFromDegrees(45.f), 0.f) == NzEulerAngles(NzQuaternionf(0.923879504204f, 0.f, 0.382683455944f, 0.f).ToEulerAngles())); - REQUIRE(NzEulerAngles(0.f, 0.f, NzFromDegrees(45.f)) == NzEulerAngles(NzQuaternionf(0.923879504204f, 0.f, 0.f, 0.382683455944f).ToEulerAngles())); + REQUIRE(Nz::EulerAngles(Nz::FromDegrees(45.f), 0.f, 0.f) == Nz::EulerAngles(Nz::Quaternionf(0.923879504204f, 0.382683455944f, 0.f, 0.f).ToEulerAngles())); + REQUIRE(Nz::EulerAngles(0.f, Nz::FromDegrees(45.f), 0.f) == Nz::EulerAngles(Nz::Quaternionf(0.923879504204f, 0.f, 0.382683455944f, 0.f).ToEulerAngles())); + REQUIRE(Nz::EulerAngles(0.f, 0.f, Nz::FromDegrees(45.f)) == Nz::EulerAngles(Nz::Quaternionf(0.923879504204f, 0.f, 0.f, 0.382683455944f).ToEulerAngles())); } } } GIVEN("Three euler angles: (0, 22.5, 22.5), (90, 90, 0) and (30, 0, 30)") { - NzEulerAnglesf euler45(NzFromDegrees(0.f), NzFromDegrees(22.5f), NzFromDegrees(22.5f)); - NzEulerAnglesf euler90(NzFromDegrees(90.f), NzFromDegrees(90.f), NzFromDegrees(0.f)); - NzEulerAnglesf euler30(NzFromDegrees(30.f), NzFromDegrees(0.f), NzFromDegrees(30.f)); + Nz::EulerAnglesf euler45(Nz::FromDegrees(0.f), Nz::FromDegrees(22.5f), Nz::FromDegrees(22.5f)); + Nz::EulerAnglesf euler90(Nz::FromDegrees(90.f), Nz::FromDegrees(90.f), Nz::FromDegrees(0.f)); + Nz::EulerAnglesf euler30(Nz::FromDegrees(30.f), Nz::FromDegrees(0.f), Nz::FromDegrees(30.f)); WHEN("We convert them to quaternion") { THEN("And then convert to euler angles, we have identity") { - NzEulerAnglesf tmp = NzQuaternionf(euler45.ToQuaternion()).ToEulerAngles(); + Nz::EulerAnglesf tmp = Nz::Quaternionf(euler45.ToQuaternion()).ToEulerAngles(); REQUIRE(tmp.pitch == Approx(0.f)); REQUIRE(tmp.yaw == Approx(22.5f)); REQUIRE(tmp.roll == Approx(22.5f)); - tmp = NzQuaternionf(euler90.ToQuaternion()).ToEulerAngles(); + tmp = Nz::Quaternionf(euler90.ToQuaternion()).ToEulerAngles(); REQUIRE(tmp.pitch == Approx(90.f)); REQUIRE(tmp.yaw == Approx(90.f)); REQUIRE(tmp.roll == Approx(0.f)); - tmp = NzQuaternionf(euler30.ToQuaternion()).ToEulerAngles(); + tmp = Nz::Quaternionf(euler30.ToQuaternion()).ToEulerAngles(); REQUIRE(tmp.pitch == Approx(30.f)); REQUIRE(tmp.yaw == Approx(0.f)); REQUIRE(tmp.roll == Approx(30.f)); diff --git a/tests/Engine/Math/Frustum.cpp b/tests/Engine/Math/Frustum.cpp index 3b4494fb3..98715940d 100644 --- a/tests/Engine/Math/Frustum.cpp +++ b/tests/Engine/Math/Frustum.cpp @@ -5,25 +5,25 @@ SCENARIO("Frustum", "[MATH][FRUSTUM]") { GIVEN("One frustum (90, 1, 1, 1000, (0, 0, 0), (1, 0, 0))") { - NzFrustumf frustum; - frustum.Build(NzFromDegrees(90.f), 1.f, 1.f, 1000.f, NzVector3f::Zero(), NzVector3f::UnitX()); + Nz::Frustumf frustum; + frustum.Build(Nz::FromDegrees(90.f), 1.f, 1.f, 1000.f, Nz::Vector3f::Zero(), Nz::Vector3f::UnitX()); WHEN("We ask for intersection with objects outside the frustum") { THEN("These results are expected") { - NzBoundingVolumef bv(NzVector3f::Zero(), NzVector3f::Unit()); - bv.Update(NzMatrix4f::Identity()); - REQUIRE(nzIntersectionSide_Outside == frustum.Intersect(bv)); - REQUIRE(nzIntersectionSide_Outside == frustum.Intersect(NzBoxf(NzVector3f::Zero(), NzVector3f::Unit() * 0.9f))); - NzOrientedBoxf obb(NzVector3f::Zero(), NzVector3f::Unit() * 0.9f); - obb.Update(NzMatrix4f::Identity()); - REQUIRE(nzIntersectionSide_Outside == frustum.Intersect(obb)); - REQUIRE(nzIntersectionSide_Outside == frustum.Intersect(NzSpheref(NzVector3f::Zero(), 0.5f))); - NzVector3f tmp = NzVector3f::Zero(); - REQUIRE(nzIntersectionSide_Outside == frustum.Intersect(&tmp, 1)); - tmp = NzVector3f::UnitX() * -10.f; - REQUIRE(nzIntersectionSide_Outside == frustum.Intersect(&tmp, 1)); + Nz::BoundingVolumef bv(Nz::Vector3f::Zero(), Nz::Vector3f::Unit()); + bv.Update(Nz::Matrix4f::Identity()); + REQUIRE(Nz::IntersectionSide_Outside == frustum.Intersect(bv)); + REQUIRE(Nz::IntersectionSide_Outside == frustum.Intersect(Nz::Boxf(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.9f))); + Nz::OrientedBoxf obb(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.9f); + obb.Update(Nz::Matrix4f::Identity()); + REQUIRE(Nz::IntersectionSide_Outside == frustum.Intersect(obb)); + REQUIRE(Nz::IntersectionSide_Outside == frustum.Intersect(Nz::Spheref(Nz::Vector3f::Zero(), 0.5f))); + Nz::Vector3f tmp = Nz::Vector3f::Zero(); + REQUIRE(Nz::IntersectionSide_Outside == frustum.Intersect(&tmp, 1)); + tmp = Nz::Vector3f::UnitX() * -10.f; + REQUIRE(Nz::IntersectionSide_Outside == frustum.Intersect(&tmp, 1)); } } @@ -31,17 +31,17 @@ SCENARIO("Frustum", "[MATH][FRUSTUM]") { THEN("These results are expected") { - NzBoundingVolumef bv(500.f, -0.5f, -0.5f, 1.f, 1.f, 1.f); - bv.Update(NzMatrix4f::Identity()); + Nz::BoundingVolumef bv(500.f, -0.5f, -0.5f, 1.f, 1.f, 1.f); + bv.Update(Nz::Matrix4f::Identity()); - REQUIRE(nzIntersectionSide_Inside == frustum.Intersect(bv)); - REQUIRE(nzIntersectionSide_Inside == frustum.Intersect(NzBoxf(NzVector3f::UnitX() * 500.f, NzVector3f::Unit()))); - NzOrientedBoxf obb(NzVector3f::UnitX() * 100.f, NzVector3f::Unit()); - obb.Update(NzMatrix4f::Identity()); - REQUIRE(nzIntersectionSide_Inside == frustum.Intersect(obb)); - REQUIRE(nzIntersectionSide_Inside == frustum.Intersect(NzSpheref(NzVector3f::UnitX() * 100.f, 0.5f))); - NzVector3f tmp = NzVector3f::UnitX() * 100.f; - REQUIRE(nzIntersectionSide_Inside == frustum.Intersect(&tmp, 1)); + REQUIRE(Nz::IntersectionSide_Inside == frustum.Intersect(bv)); + REQUIRE(Nz::IntersectionSide_Inside == frustum.Intersect(Nz::Boxf(Nz::Vector3f::UnitX() * 500.f, Nz::Vector3f::Unit()))); + Nz::OrientedBoxf obb(Nz::Vector3f::UnitX() * 100.f, Nz::Vector3f::Unit()); + obb.Update(Nz::Matrix4f::Identity()); + REQUIRE(Nz::IntersectionSide_Inside == frustum.Intersect(obb)); + REQUIRE(Nz::IntersectionSide_Inside == frustum.Intersect(Nz::Spheref(Nz::Vector3f::UnitX() * 100.f, 0.5f))); + Nz::Vector3f tmp = Nz::Vector3f::UnitX() * 100.f; + REQUIRE(Nz::IntersectionSide_Inside == frustum.Intersect(&tmp, 1)); } } @@ -49,15 +49,15 @@ SCENARIO("Frustum", "[MATH][FRUSTUM]") { THEN("These results are expected") { - NzBoundingVolumef bv(0.f, -0.25f, -0.25f, 0.5f, 0.5f, 0.5f); - bv.Update(NzMatrix4f::Identity()); + Nz::BoundingVolumef bv(0.f, -0.25f, -0.25f, 0.5f, 0.5f, 0.5f); + bv.Update(Nz::Matrix4f::Identity()); CHECK(!frustum.Contains(bv)); - CHECK(!frustum.Contains(NzBoxf(0.f, -0.25f, -0.25f, 0.5f, 0.5f, 0.5f))); - NzOrientedBoxf obb(0.f, -0.25f, -0.25f, 0.5f, 0.5f, 0.5f); - obb.Update(NzMatrix4f::Identity()); + CHECK(!frustum.Contains(Nz::Boxf(0.f, -0.25f, -0.25f, 0.5f, 0.5f, 0.5f))); + Nz::OrientedBoxf obb(0.f, -0.25f, -0.25f, 0.5f, 0.5f, 0.5f); + obb.Update(Nz::Matrix4f::Identity()); CHECK(!frustum.Contains(obb)); - CHECK(!frustum.Contains(NzSpheref(NzVector3f::Zero(), 0.5f))); - NzVector3f tmp = NzVector3f::Zero(); + CHECK(!frustum.Contains(Nz::Spheref(Nz::Vector3f::Zero(), 0.5f))); + Nz::Vector3f tmp = Nz::Vector3f::Zero(); CHECK(!frustum.Contains(&tmp, 1)); } } @@ -66,15 +66,15 @@ SCENARIO("Frustum", "[MATH][FRUSTUM]") { THEN("These results are expected") { - NzBoundingVolumef bv(500.f, -0.5f, -0.5f, 1.f, 1.f, 1.f); - bv.Update(NzMatrix4f::Identity()); + Nz::BoundingVolumef bv(500.f, -0.5f, -0.5f, 1.f, 1.f, 1.f); + bv.Update(Nz::Matrix4f::Identity()); CHECK(frustum.Contains(bv)); - CHECK(frustum.Contains(NzBoxf(500.f, -0.5f, -0.5f, 1.f, 1.f, 1.f))); - NzOrientedBoxf obb(500.f, -0.5f, -0.5f, 1.f, 1.f, 1.f); - obb.Update(NzMatrix4f::Identity()); + CHECK(frustum.Contains(Nz::Boxf(500.f, -0.5f, -0.5f, 1.f, 1.f, 1.f))); + Nz::OrientedBoxf obb(500.f, -0.5f, -0.5f, 1.f, 1.f, 1.f); + obb.Update(Nz::Matrix4f::Identity()); CHECK(frustum.Contains(obb)); - CHECK(frustum.Contains(NzSpheref(NzVector3f::UnitX() * 500.f, 1.f))); - NzVector3f tmp = NzVector3f::UnitX() * 500.f; + CHECK(frustum.Contains(Nz::Spheref(Nz::Vector3f::UnitX() * 500.f, 1.f))); + Nz::Vector3f tmp = Nz::Vector3f::UnitX() * 500.f; CHECK(frustum.Contains(&tmp, 1)); } } diff --git a/tests/Engine/Math/Matrix4.cpp b/tests/Engine/Math/Matrix4.cpp index 9e31ff4e5..24a56658b 100644 --- a/tests/Engine/Math/Matrix4.cpp +++ b/tests/Engine/Math/Matrix4.cpp @@ -1,12 +1,12 @@ #include #include -SCENARIO("Matrix4", "[MATH][MATRIX4]") +SCENARIO("Matrix4", "[MATH][Matrix4]") { GIVEN("Two identity matrix") { - NzMatrix4f firstIdentity(NzMatrix4::Identity()); - NzMatrix4f secondIdentity(1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f); + Nz::Matrix4f firstIdentity(Nz::Matrix4::Identity()); + Nz::Matrix4f secondIdentity(1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f); WHEN("We compare them") { @@ -16,13 +16,13 @@ SCENARIO("Matrix4", "[MATH][MATRIX4]") } } - WHEN("We multiply the first with a vector") + WHEN("We multiply the first with a Nz::Vector") { - THEN("Vector stay the same") + THEN("Nz::Vector stay the same") { - REQUIRE(firstIdentity.Transform(NzVector2f::Unit()) == NzVector2f::Unit()); - REQUIRE(firstIdentity.Transform(NzVector3f::Unit()) == NzVector3f::Unit()); - REQUIRE(firstIdentity.Transform(NzVector4f(1.f, 1.f, 1.f, 1.f)) == NzVector4f(1.f, 1.f, 1.f, 1.f)); + REQUIRE(firstIdentity.Transform(Nz::Vector2f::Unit()) == Nz::Vector2f::Unit()); + REQUIRE(firstIdentity.Transform(Nz::Vector3f::Unit()) == Nz::Vector3f::Unit()); + REQUIRE(firstIdentity.Transform(Nz::Vector4f(1.f, 1.f, 1.f, 1.f)) == Nz::Vector4f(1.f, 1.f, 1.f, 1.f)); } } @@ -41,12 +41,12 @@ SCENARIO("Matrix4", "[MATH][MATRIX4]") GIVEN("Two different matrix") { - NzMatrix4f matrix1(1.0f, 0.0f, 0.0f, 0.0f, + Nz::Matrix4f matrix1(1.0f, 0.0f, 0.0f, 0.0f, 7.0f, 2.0f, 0.0f, 0.0f, 1.0f, 5.0f, 3.0f, 0.0f, 8.0f, 9.0f, 2.0f, 4.0f); - NzMatrix4f matrix2(1.0f, 1.0f, 2.0f, -1.0f, + Nz::Matrix4f matrix2(1.0f, 1.0f, 2.0f, -1.0f, -2.0f, -1.0f, -2.0f, 2.0f, 4.0f, 2.0f, 5.0f, -4.0f, 5.0f, -3.0f, -7.0f, -6.0f); @@ -62,71 +62,71 @@ SCENARIO("Matrix4", "[MATH][MATRIX4]") WHEN("We multiply the matrix and its inverse") { - NzMatrix4f invMatrix1; + Nz::Matrix4f invMatrix1; matrix1.GetInverse(&invMatrix1); - NzMatrix4f invMatrix2; + Nz::Matrix4f invMatrix2; matrix2.GetInverse(&invMatrix2); THEN("We get the identity") { - NzMatrix4f tmp = matrix1 * invMatrix1; + Nz::Matrix4f tmp = matrix1 * invMatrix1; REQUIRE(tmp.m32 == Approx(0.f)); REQUIRE(tmp.m42 == Approx(0.f)); tmp.m32 = 0.f; tmp.m42 = 0.f; - REQUIRE(tmp == NzMatrix4f::Identity()); - REQUIRE((matrix2 * invMatrix2) == NzMatrix4f::Identity()); + REQUIRE(tmp == Nz::Matrix4f::Identity()); + REQUIRE((matrix2 * invMatrix2) == Nz::Matrix4f::Identity()); } } } GIVEN("One transformed matrix from rotation 45 and translation 0") { - NzMatrix4f transformedMatrix = NzMatrix4f::Transform(NzVector3f::Zero(), NzQuaternionf::Identity()); - REQUIRE(transformedMatrix == NzMatrix4f::Identity()); + Nz::Matrix4f transformedMatrix = Nz::Matrix4f::Transform(Nz::Vector3f::Zero(), Nz::Quaternionf::Identity()); + REQUIRE(transformedMatrix == Nz::Matrix4f::Identity()); WHEN("We compare with the right matrix") { THEN("Rotation around X") { - transformedMatrix.MakeTransform(NzVector3f::Zero(), NzEulerAnglesf(NzFromDegrees(45.f), 0.f, 0.f).ToQuaternion()); - NzMatrix4f rotation45X(1.f, 0.f, 0.f, 0.f, + transformedMatrix.MakeTransform(Nz::Vector3f::Zero(), Nz::EulerAnglesf(Nz::FromDegrees(45.f), 0.f, 0.f).ToQuaternion()); + Nz::Matrix4f rotation45X(1.f, 0.f, 0.f, 0.f, 0.f, std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f, 0.f, -std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f, 0.f, 0.f, 0.f, 1.f); REQUIRE(transformedMatrix == rotation45X); - transformedMatrix.MakeTransform(NzVector3f::Unit(), NzEulerAnglesf(NzFromDegrees(45.f), 0.f, 0.f).ToQuaternion()); - rotation45X.ApplyTranslation(NzVector3f::Unit()); + transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(Nz::FromDegrees(45.f), 0.f, 0.f).ToQuaternion()); + rotation45X.ApplyTranslation(Nz::Vector3f::Unit()); REQUIRE(transformedMatrix == rotation45X); } THEN("Rotation around Y") { - transformedMatrix.MakeTransform(NzVector3f::Zero(), NzEulerAnglesf(0.f, NzFromDegrees(45.f), 0.f).ToQuaternion()); - NzMatrix4f rotation45Y(std::sqrt(2.f) / 2.f, 0.f, -std::sqrt(2.f) / 2.f, 0.f, + transformedMatrix.MakeTransform(Nz::Vector3f::Zero(), Nz::EulerAnglesf(0.f, Nz::FromDegrees(45.f), 0.f).ToQuaternion()); + Nz::Matrix4f rotation45Y(std::sqrt(2.f) / 2.f, 0.f, -std::sqrt(2.f) / 2.f, 0.f, 0.f, 1.f, 0.f, 0.f, std::sqrt(2.f) / 2.f, 0.f, std::sqrt(2.f) / 2.f, 0.f, 0.f, 0.f, 0.f, 1.f); REQUIRE(transformedMatrix == rotation45Y); - transformedMatrix.MakeTransform(NzVector3f::Unit(), NzEulerAnglesf(0.f, NzFromDegrees(45.f), 0.f).ToQuaternion()); - rotation45Y.ApplyTranslation(NzVector3f::Unit()); + transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(0.f, Nz::FromDegrees(45.f), 0.f).ToQuaternion()); + rotation45Y.ApplyTranslation(Nz::Vector3f::Unit()); REQUIRE(transformedMatrix == rotation45Y); } THEN("Rotation around Z") { - transformedMatrix.MakeTransform(NzVector3f::Zero(), NzEulerAnglesf(0.f, 0.f, NzFromDegrees(45.f)).ToQuaternion()); - NzMatrix4f rotation45Z( std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f, 0.f, + transformedMatrix.MakeTransform(Nz::Vector3f::Zero(), Nz::EulerAnglesf(0.f, 0.f, Nz::FromDegrees(45.f)).ToQuaternion()); + Nz::Matrix4f rotation45Z( std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f, 0.f, -std::sqrt(2.f) / 2.f, std::sqrt(2.f) / 2.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f); REQUIRE(transformedMatrix == rotation45Z); - transformedMatrix.MakeTransform(NzVector3f::Unit(), NzEulerAnglesf(NzEulerAnglesf(0.f, 0.f, NzFromDegrees(45.f)).ToQuaternion())); - rotation45Z.ApplyTranslation(NzVector3f::Unit()); + transformedMatrix.MakeTransform(Nz::Vector3f::Unit(), Nz::EulerAnglesf(Nz::EulerAnglesf(0.f, 0.f, Nz::FromDegrees(45.f)).ToQuaternion())); + rotation45Z.ApplyTranslation(Nz::Vector3f::Unit()); REQUIRE(transformedMatrix == rotation45Z); } } diff --git a/tests/Engine/Math/OrientedBox.cpp b/tests/Engine/Math/OrientedBox.cpp index 668ccd851..bd11f58ef 100644 --- a/tests/Engine/Math/OrientedBox.cpp +++ b/tests/Engine/Math/OrientedBox.cpp @@ -5,11 +5,11 @@ SCENARIO("OrientedBox", "[MATH][ORIENTEDBOX]") { GIVEN("Two center and unit oriented boxes") { - NzOrientedBoxf firstCenterAndUnit(0.f, 0.f, 0.f, 1.f, 1.f, 1.f); - NzOrientedBoxf secondCenterAndUnit(NzOrientedBox(NzVector3i::Zero(), NzVector3i::Unit())); + Nz::OrientedBoxf firstCenterAndUnit(0.f, 0.f, 0.f, 1.f, 1.f, 1.f); + Nz::OrientedBoxf secondCenterAndUnit(Nz::OrientedBox(Nz::Vector3i::Zero(), Nz::Vector3i::Unit())); - firstCenterAndUnit.Update(NzMatrix4f::Identity()); - secondCenterAndUnit.Update(NzMatrix4f::Identity()); + firstCenterAndUnit.Update(Nz::Matrix4f::Identity()); + secondCenterAndUnit.Update(Nz::Matrix4f::Identity()); WHEN("We compare them") { @@ -33,11 +33,11 @@ SCENARIO("OrientedBox", "[MATH][ORIENTEDBOX]") THEN("Results are different between operator * and update(ScaleMatrix) but corners are the same") { firstCenterAndUnit *= 2.f; - firstCenterAndUnit.Update(NzMatrix4f::Identity()); - secondCenterAndUnit.Update(NzMatrix4f::Scale(NzVector3f::Unit() * 2.f)); + firstCenterAndUnit.Update(Nz::Matrix4f::Identity()); + secondCenterAndUnit.Update(Nz::Matrix4f::Scale(Nz::Vector3f::Unit() * 2.f)); REQUIRE(firstCenterAndUnit != secondCenterAndUnit); - for (unsigned int i = 0; i <= nzBoxCorner_Max; ++i) + for (unsigned int i = 0; i <= Nz::BoxCorner_Max; ++i) { REQUIRE(firstCenterAndUnit(i) == secondCenterAndUnit(i)); } diff --git a/tests/Engine/Math/Plane.cpp b/tests/Engine/Math/Plane.cpp index 59c6a0ac3..1cab6f385 100644 --- a/tests/Engine/Math/Plane.cpp +++ b/tests/Engine/Math/Plane.cpp @@ -5,8 +5,8 @@ SCENARIO("Plane", "[MATH][PLANE]") { GIVEN("Two planes normal(1, 1, 1), distance 1") { - NzPlanef firstPlane(NzVector3f::Unit().Normalize(), 1.f); - NzPlanef secondPlane(NzPlaned(NzVector3d::Unit().Normalize(), 1.0)); + Nz::Planef firstPlane(Nz::Vector3f::Unit().Normalize(), 1.f); + Nz::Planef secondPlane(Nz::Planed(Nz::Vector3d::Unit().Normalize(), 1.0)); WHEN("We compare them") { @@ -17,36 +17,36 @@ SCENARIO("Plane", "[MATH][PLANE]") AND_THEN("We compare with normal(-1, -1, -1), distance -1") { - REQUIRE(firstPlane == NzPlanef(-NzVector3f::Unit().Normalize(), -1.f)); + REQUIRE(firstPlane == Nz::Planef(-Nz::Vector3f::Unit().Normalize(), -1.f)); } AND_THEN("They have the same distance from the same point") { - NzVector3f point(-2.f, 3.f, 1.f); + Nz::Vector3f point(-2.f, 3.f, 1.f); REQUIRE(firstPlane.Distance(point) == Approx(secondPlane.Distance(point))); REQUIRE(firstPlane.Distance(-2.f, 3.f, 1.f) == Approx(0.1547f)); } AND_THEN("Distance between Plane (0, 1, 0), distance 1 and point (0, 2, 0) should be 1") { - REQUIRE(NzPlanef(NzVector3f::UnitY(), 1.f).Distance(NzVector3f::UnitY() * 2.f) == Approx(1.f)); + REQUIRE(Nz::Planef(Nz::Vector3f::UnitY(), 1.f).Distance(Nz::Vector3f::UnitY() * 2.f) == Approx(1.f)); } AND_THEN("Distance between Plane (0, 1, 0), distance 5 and point (0, 2, 0) should be -3") { - REQUIRE(NzPlanef(NzVector3f::UnitY(), 5.f).Distance(NzVector3f::UnitY() * 2.f) == Approx(-3.f)); + REQUIRE(Nz::Planef(Nz::Vector3f::UnitY(), 5.f).Distance(Nz::Vector3f::UnitY() * 2.f) == Approx(-3.f)); } AND_THEN("Distance between Plane (0, 1, 0), distance 1000 and point (0, 500, 0) and (0, 1500, 0)") { - REQUIRE(NzPlanef(NzVector3f::UnitY(), 1000.f).Distance(NzVector3f::UnitY() * 500.f) == Approx(-500.f)); - REQUIRE(NzPlanef(NzVector3f::UnitY(), 1000.f).Distance(NzVector3f::UnitY() * 1500.f) == Approx(500.f)); + REQUIRE(Nz::Planef(Nz::Vector3f::UnitY(), 1000.f).Distance(Nz::Vector3f::UnitY() * 500.f) == Approx(-500.f)); + REQUIRE(Nz::Planef(Nz::Vector3f::UnitY(), 1000.f).Distance(Nz::Vector3f::UnitY() * 1500.f) == Approx(500.f)); } AND_THEN("Distance between Plane (0, -1, 0), distance -1000 and point (0, 500, 0) and (0, 1500, 0)") { - REQUIRE(NzPlanef(-NzVector3f::UnitY(), -1000.f).Distance(NzVector3f::UnitY() * 500.f) == Approx(500.f)); - REQUIRE(NzPlanef(-NzVector3f::UnitY(), -1000.f).Distance(NzVector3f::UnitY() * 1500.f) == Approx(-500.f)); + REQUIRE(Nz::Planef(-Nz::Vector3f::UnitY(), -1000.f).Distance(Nz::Vector3f::UnitY() * 500.f) == Approx(500.f)); + REQUIRE(Nz::Planef(-Nz::Vector3f::UnitY(), -1000.f).Distance(Nz::Vector3f::UnitY() * 1500.f) == Approx(-500.f)); } } } @@ -55,20 +55,20 @@ SCENARIO("Plane", "[MATH][PLANE]") { WHEN("We do a positive plane") { - NzPlanef xy(NzVector3f(2.f, 1.f, 0.f), NzVector3f(-1.f, 1.f, -1.f), NzVector3f(-1.f, 1.f, 0.f)); + Nz::Planef xy(Nz::Vector3f(2.f, 1.f, 0.f), Nz::Vector3f(-1.f, 1.f, -1.f), Nz::Vector3f(-1.f, 1.f, 0.f)); THEN("It must be equal to XZ distance 1") { - REQUIRE(xy == NzPlanef(NzVector3f::UnitY(), 1.f)); + REQUIRE(xy == Nz::Planef(Nz::Vector3f::UnitY(), 1.f)); } } WHEN("We do a negative plane") { - NzPlanef xy(NzVector3f(0.f, 1.f, 0.f), NzVector3f(1.f, 1.f, 1.f), NzVector3f(-1.f, 1.f, 0.f)); + Nz::Planef xy(Nz::Vector3f(0.f, 1.f, 0.f), Nz::Vector3f(1.f, 1.f, 1.f), Nz::Vector3f(-1.f, 1.f, 0.f)); THEN("It must be equal to XZ distance 1") { - REQUIRE(xy == NzPlanef(-NzVector3f::UnitY(), -1.f)); + REQUIRE(xy == Nz::Planef(-Nz::Vector3f::UnitY(), -1.f)); } } } diff --git a/tests/Engine/Math/Quaternion.cpp b/tests/Engine/Math/Quaternion.cpp index 1007ffed2..65ab201bf 100644 --- a/tests/Engine/Math/Quaternion.cpp +++ b/tests/Engine/Math/Quaternion.cpp @@ -5,8 +5,8 @@ SCENARIO("Quaternion", "[MATH][QUATERNION]") { GIVEN("Two quaternions (0, 1, 0, 0)") { - NzQuaternionf firstQuaternion(NzFromDegrees(180.f), NzVector3f::UnitX()); - NzQuaternionf secondQuaternion(0.f, 1.f, 0.f, 0.f); + Nz::Quaternionf firstQuaternion(Nz::FromDegrees(180.f), Nz::Vector3f::UnitX()); + Nz::Quaternionf secondQuaternion(0.f, 1.f, 0.f, 0.f); WHEN("We compare them") { @@ -23,25 +23,25 @@ SCENARIO("Quaternion", "[MATH][QUATERNION]") { THEN("Multiply with a vectorX is identity") { - REQUIRE((firstQuaternion * NzVector3f::UnitX()) == NzVector3f::UnitX()); + REQUIRE((firstQuaternion * Nz::Vector3f::UnitX()) == Nz::Vector3f::UnitX()); } AND_THEN("Multiply with a vectorY or Z is opposite") { - REQUIRE((firstQuaternion * NzVector3f::UnitY()) == -NzVector3f::UnitY()); - REQUIRE((firstQuaternion * NzVector3f::UnitZ()) == -NzVector3f::UnitZ()); + REQUIRE((firstQuaternion * Nz::Vector3f::UnitY()) == -Nz::Vector3f::UnitY()); + REQUIRE((firstQuaternion * Nz::Vector3f::UnitZ()) == -Nz::Vector3f::UnitZ()); } } } GIVEN("The four unit quaternions") { - NzQuaternionf w(1.f, 0.f, 0.f, 0.f); - NzQuaternionf x(0.f, 1.f, 0.f, 0.f); - NzQuaternionf y(0.f, 0.f, 1.f, 0.f); - NzQuaternionf z(0.f, 0.f, 0.f, 1.f); + Nz::Quaternionf w(1.f, 0.f, 0.f, 0.f); + Nz::Quaternionf x(0.f, 1.f, 0.f, 0.f); + Nz::Quaternionf y(0.f, 0.f, 1.f, 0.f); + Nz::Quaternionf z(0.f, 0.f, 0.f, 1.f); - NzQuaternionf xyzw = x * y * z * w; + Nz::Quaternionf xyzw = x * y * z * w; WHEN("We ask for the norm") { @@ -59,10 +59,10 @@ SCENARIO("Quaternion", "[MATH][QUATERNION]") { THEN("Results shoud follow") { - NzQuaternionf oppositeOfW(-1.f, 0.f, 0.f, 0.f); - NzQuaternionf oppositeOfX = x.GetConjugate(); - NzQuaternionf oppositeOfY = y.GetConjugate(); - NzQuaternionf oppositeOfZ = z.GetConjugate(); + Nz::Quaternionf oppositeOfW(-1.f, 0.f, 0.f, 0.f); + Nz::Quaternionf oppositeOfX = x.GetConjugate(); + Nz::Quaternionf oppositeOfY = y.GetConjugate(); + Nz::Quaternionf oppositeOfZ = z.GetConjugate(); REQUIRE((x * x) == oppositeOfW); REQUIRE((y * y) == oppositeOfW); @@ -81,32 +81,32 @@ SCENARIO("Quaternion", "[MATH][QUATERNION]") GIVEN("Two different quaternions (10, (1, 0, 0) and (20, (1, 0, 0))") { - NzQuaternionf x10 = NzQuaternionf(NzFromDegrees(10.f), NzVector3f::UnitX()); - NzQuaternionf x20 = x10 * x10; + Nz::Quaternionf x10 = Nz::Quaternionf(Nz::FromDegrees(10.f), Nz::Vector3f::UnitX()); + Nz::Quaternionf x20 = x10 * x10; - NzQuaternionf x30a = x10 * x20; - NzQuaternionf x30b = x20 * x10; + Nz::Quaternionf x30a = x10 * x20; + Nz::Quaternionf x30b = x20 * x10; WHEN("We multiply them") { THEN("These results are expected") { - REQUIRE(x20 == NzQuaternionf(NzFromDegrees(20.f), NzVector3f::UnitX())); + REQUIRE(x20 == Nz::Quaternionf(Nz::FromDegrees(20.f), Nz::Vector3f::UnitX())); REQUIRE(x30a == x30b); } } WHEN("Convert euler to quaternion") { - NzQuaternionf X45(NzEulerAnglesf(NzFromDegrees(45.f), 0.f, 0.f)); - NzQuaternionf Y45(NzEulerAnglesf(0.f, NzFromDegrees(45.f), 0.f)); - NzQuaternionf Z45(NzEulerAnglesf(0.f, 0.f, NzFromDegrees(45.f))); + Nz::Quaternionf X45(Nz::EulerAnglesf(Nz::FromDegrees(45.f), 0.f, 0.f)); + Nz::Quaternionf Y45(Nz::EulerAnglesf(0.f, Nz::FromDegrees(45.f), 0.f)); + Nz::Quaternionf Z45(Nz::EulerAnglesf(0.f, 0.f, Nz::FromDegrees(45.f))); THEN("They must be equal") { - REQUIRE(X45 == NzQuaternionf(0.9238795f, 0.38268346f, 0.f, 0.f)); - REQUIRE(Y45 == NzQuaternionf(0.9238795f, 0.f, 0.38268346f, 0.f)); - REQUIRE(Z45 == NzQuaternionf(0.9238795f, 0.f, 0.f, 0.38268346f)); + REQUIRE(X45 == Nz::Quaternionf(0.9238795f, 0.38268346f, 0.f, 0.f)); + REQUIRE(Y45 == Nz::Quaternionf(0.9238795f, 0.f, 0.38268346f, 0.f)); + REQUIRE(Z45 == Nz::Quaternionf(0.9238795f, 0.f, 0.f, 0.38268346f)); } } @@ -117,7 +117,7 @@ SCENARIO("Quaternion", "[MATH][QUATERNION]") REQUIRE(x30a.ToEulerAngles() == x30b.ToEulerAngles()); REQUIRE(x30a.ToEulerAngles().ToQuaternion() == x30b.ToEulerAngles().ToQuaternion()); - NzQuaternionf tmp(1.f, 1.f, 0.f, 0.f); + Nz::Quaternionf tmp(1.f, 1.f, 0.f, 0.f); tmp.Normalize(); REQUIRE(tmp == tmp.ToEulerAngles().ToQuaternion()); } @@ -127,27 +127,27 @@ SCENARIO("Quaternion", "[MATH][QUATERNION]") { THEN("The half of 10 and 30 is 20") { - NzQuaternionf slerpx10x30a = NzQuaternionf::Slerp(x10, x30a, 0.5f); + Nz::Quaternionf slerpx10x30a = Nz::Quaternionf::Slerp(x10, x30a, 0.5f); REQUIRE(slerpx10x30a.w == Approx(x20.w)); REQUIRE(slerpx10x30a.x == Approx(x20.x)); REQUIRE(slerpx10x30a.y == Approx(x20.y)); REQUIRE(slerpx10x30a.z == Approx(x20.z)); - NzQuaternionf slerpx10x30b = NzQuaternionf::Slerp(x10, x30b, 0.5f); + Nz::Quaternionf slerpx10x30b = Nz::Quaternionf::Slerp(x10, x30b, 0.5f); REQUIRE(slerpx10x30b.w == Approx(x20.w)); REQUIRE(slerpx10x30b.x == Approx(x20.x)); REQUIRE(slerpx10x30b.y == Approx(x20.y)); REQUIRE(slerpx10x30b.z == Approx(x20.z)); - REQUIRE(NzQuaternionf::Slerp(x10, x30a, 0.f) == x10); - REQUIRE(NzQuaternionf::Slerp(x10, x30a, 1.f) == x30a); + REQUIRE(Nz::Quaternionf::Slerp(x10, x30a, 0.f) == x10); + REQUIRE(Nz::Quaternionf::Slerp(x10, x30a, 1.f) == x30a); } AND_THEN("The half of 45 is 22.5") { - NzQuaternionf quaterionA(NzFromDegrees(0.f), NzVector3f::UnitZ()); - NzQuaternionf quaterionB(NzFromDegrees(45.f), NzVector3f::UnitZ()); - NzQuaternionf quaternionC = NzQuaternionf::Slerp(quaterionA, quaterionB, 0.5f); + Nz::Quaternionf quaterionA(Nz::FromDegrees(0.f), Nz::Vector3f::UnitZ()); + Nz::Quaternionf quaterionB(Nz::FromDegrees(45.f), Nz::Vector3f::UnitZ()); + Nz::Quaternionf quaternionC = Nz::Quaternionf::Slerp(quaterionA, quaterionB, 0.5f); - NzQuaternionf unitZ225(NzFromDegrees(22.5f), NzVector3f::UnitZ()); + Nz::Quaternionf unitZ225(Nz::FromDegrees(22.5f), Nz::Vector3f::UnitZ()); REQUIRE(quaternionC.w == Approx(unitZ225.w)); REQUIRE(quaternionC.x == Approx(unitZ225.x)); REQUIRE(quaternionC.y == Approx(unitZ225.y)); diff --git a/tests/Engine/Math/Ray.cpp b/tests/Engine/Math/Ray.cpp index 0f2ba34df..df77a34ac 100644 --- a/tests/Engine/Math/Ray.cpp +++ b/tests/Engine/Math/Ray.cpp @@ -1,27 +1,27 @@ #include #include -SCENARIO("Ray", "[RAY]") +SCENARIO("Ray", "[MATH][RAY]") { - GIVEN("Two same rays (0, 0, 0) -> (0, 1, 0)") + GIVEN("Two same Rays (0, 0, 0) -> (0, 1, 0)") { - NzRayf firstRay(NzRay(NzPlane::XY(), NzPlane::YZ())); - NzRayf secondRay(0.f, 0.f, 0.f, 0.f, 1.f, 0.f); + Nz::Rayf ray(Nz::Ray(Nz::Plane::XY(), Nz::Plane::YZ())); + Nz::Rayf secondRay(0.f, 0.f, 0.f, 0.f, 1.f, 0.f); WHEN("We compare them") { THEN("They are the same and Y axis") { - REQUIRE(firstRay == secondRay); - REQUIRE(firstRay == NzRayf::AxisY()); + REQUIRE(ray == secondRay); + REQUIRE(ray == Nz::Rayf::AxisY()); } } WHEN("We ask for the closest point") { - THEN("The point that is multiple on the ray, is at multiple") + THEN("The point that is multiple on the Nz::Ray, is at multiple") { - REQUIRE(firstRay.ClosestPoint(secondRay.GetPoint(1.f)) == Approx(1.f)); + REQUIRE(ray.ClosestPoint(secondRay.GetPoint(1.f)) == Approx(1.f)); } } @@ -32,24 +32,24 @@ SCENARIO("Ray", "[RAY]") float tmpClosest; float tmpFurthest; - CHECK(firstRay.Intersect(NzBoxf(-0.5f, 1.f, -0.5f, 1.f, 1.f, 1.f), &tmpClosest, &tmpFurthest)); - REQUIRE(firstRay.GetPoint(tmpClosest) == NzVector3f::UnitY()); - REQUIRE(firstRay.GetPoint(tmpFurthest) == (NzVector3f::UnitY() * 2.f)); - CHECK(!firstRay.Intersect(NzBoxf(-10.f, 1.f, -10.f, 1.f, 1.f, 1.f), &tmpClosest, &tmpFurthest)); + CHECK(ray.Intersect(Nz::Boxf(-0.5f, 1.f, -0.5f, 1.f, 1.f, 1.f), &tmpClosest, &tmpFurthest)); + REQUIRE(ray.GetPoint(tmpClosest) == Nz::Vector3f::UnitY()); + REQUIRE(ray.GetPoint(tmpFurthest) == (Nz::Vector3f::UnitY() * 2.f)); + CHECK(!ray.Intersect(Nz::Boxf(-10.f, 1.f, -10.f, 1.f, 1.f, 1.f), &tmpClosest, &tmpFurthest)); } - THEN("For the Plane collision's") + THEN("For the Nz::Plane collision's") { float tmpHit; - CHECK(firstRay.Intersect(NzPlanef(NzVector3f::UnitY(), 1.f), &tmpHit)); - REQUIRE(firstRay.GetPoint(tmpHit) == NzVector3f::UnitY()); - CHECK(firstRay.Intersect(NzPlanef::XZ(), &tmpHit)); - REQUIRE(firstRay.GetPoint(tmpHit) == NzVector3f::Zero()); - CHECK(firstRay.Intersect(NzPlanef(NzVector3f::UnitY(), 2.f), &tmpHit)); - REQUIRE(firstRay.GetPoint(tmpHit) == 2.f * NzVector3f::UnitY()); + CHECK(ray.Intersect(Nz::Planef(Nz::Vector3f::UnitY(), 1.f), &tmpHit)); + REQUIRE(ray.GetPoint(tmpHit) == Nz::Vector3f::UnitY()); + CHECK(ray.Intersect(Nz::Planef::XZ(), &tmpHit)); + REQUIRE(ray.GetPoint(tmpHit) == Nz::Vector3f::Zero()); + CHECK(ray.Intersect(Nz::Planef(Nz::Vector3f::UnitY(), 2.f), &tmpHit)); + REQUIRE(ray.GetPoint(tmpHit) == 2.f * Nz::Vector3f::UnitY()); - CHECK(!firstRay.Intersect(NzPlanef(NzVector3f::UnitX(), 1.f))); + CHECK(!ray.Intersect(Nz::Planef(Nz::Vector3f::UnitX(), 1.f))); } THEN("For the Sphere collision's") @@ -57,11 +57,11 @@ SCENARIO("Ray", "[RAY]") float tmpClosest; float tmpFurthest; - CHECK(firstRay.Intersect(NzSpheref(NzVector3f::UnitY(), 0.1f), &tmpClosest, &tmpFurthest)); - REQUIRE(firstRay.GetPoint(tmpClosest) == NzVector3f::UnitY() * 0.9f); - REQUIRE(firstRay.GetPoint(tmpFurthest) == (NzVector3f::UnitY() * 1.1f)); + CHECK(ray.Intersect(Nz::Spheref(Nz::Vector3f::UnitY(), 0.1f), &tmpClosest, &tmpFurthest)); + REQUIRE(ray.GetPoint(tmpClosest) == Nz::Vector3f::UnitY() * 0.9f); + REQUIRE(ray.GetPoint(tmpFurthest) == (Nz::Vector3f::UnitY() * 1.1f)); - CHECK(!firstRay.Intersect(NzSpheref(NzVector3f::UnitX(), 0.9f))); + CHECK(!ray.Intersect(Nz::Spheref(Nz::Vector3f::UnitX(), 0.9f))); } THEN("For the OBB collision's") @@ -69,25 +69,25 @@ SCENARIO("Ray", "[RAY]") float tmpClosest; float tmpFurthest; - NzOrientedBoxf obb(-0.5f, 1.f, -0.5f, 1.f, 1.f, 1.f); - obb.Update(NzMatrix4f::Rotate(NzEulerAnglesf(0.f, 90.f, 0.f).ToQuaternion())); + Nz::OrientedBoxf obb(-0.5f, 1.f, -0.5f, 1.f, 1.f, 1.f); + obb.Update(Nz::Matrix4f::Rotate(Nz::EulerAnglesf(0.f, 90.f, 0.f).ToQuaternion())); - CHECK(firstRay.Intersect(obb, &tmpClosest, &tmpFurthest)); - REQUIRE(firstRay.GetPoint(tmpClosest) == NzVector3f::UnitY()); - REQUIRE(firstRay.GetPoint(tmpFurthest) == (NzVector3f::UnitY() * 2.f)); + CHECK(ray.Intersect(obb, &tmpClosest, &tmpFurthest)); + REQUIRE(ray.GetPoint(tmpClosest) == Nz::Vector3f::UnitY()); + REQUIRE(ray.GetPoint(tmpFurthest) == (Nz::Vector3f::UnitY() * 2.f)); - obb = NzOrientedBoxf(-10.f, 1.f, -10.f, 1.f, 1.f, 1.f); - obb.Update(NzMatrix4f::Rotate(NzEulerAnglesf(0.f, 0.f, 90.f).ToQuaternion())); - CHECK(!firstRay.Intersect(obb, &tmpClosest, &tmpFurthest)); + obb = Nz::OrientedBoxf(-10.f, 1.f, -10.f, 1.f, 1.f, 1.f); + obb.Update(Nz::Matrix4f::Rotate(Nz::EulerAnglesf(0.f, 0.f, 90.f).ToQuaternion())); + CHECK(!ray.Intersect(obb, &tmpClosest, &tmpFurthest)); } THEN("For the bounding volume collision's") { - NzBoundingVolumef nullVolume(nzExtend_Null); - CHECK(!firstRay.Intersect(nullVolume)); + Nz::BoundingVolumef nullVolume(Nz::Extend_Null); + CHECK(!ray.Intersect(nullVolume)); - NzBoundingVolumef infiniteVolume(nzExtend_Infinite); - CHECK(firstRay.Intersect(infiniteVolume)); + Nz::BoundingVolumef infiniteVolume(Nz::Extend_Infinite); + CHECK(ray.Intersect(infiniteVolume)); } } diff --git a/tests/Engine/Math/Rect.cpp b/tests/Engine/Math/Rect.cpp index 60f302206..7a1035f79 100644 --- a/tests/Engine/Math/Rect.cpp +++ b/tests/Engine/Math/Rect.cpp @@ -3,10 +3,10 @@ SCENARIO("Rect", "[MATH][RECT]") { - GIVEN("Two same rectangles center and unit lengths") + GIVEN("Two same Nz::Rectangles center and unit lengths") { - NzRectf firstCenterAndUnit(0.f, 0.f, 1.f, 1.f); - NzRectf secondCenterAndUnit(NzRecti(NzVector2i::Unit(), NzVector2i::Zero())); + Nz::Rectf firstCenterAndUnit(0.f, 0.f, 1.f, 1.f); + Nz::Rectf secondCenterAndUnit(Nz::Recti(Nz::Vector2i::Unit(), Nz::Vector2i::Zero())); WHEN("We ask if they are the same") { @@ -14,20 +14,20 @@ SCENARIO("Rect", "[MATH][RECT]") { REQUIRE(firstCenterAndUnit == secondCenterAndUnit); REQUIRE(firstCenterAndUnit.GetCenter() == secondCenterAndUnit.GetCenter()); - REQUIRE(firstCenterAndUnit.GetCorner(nzRectCorner_LeftBottom) == secondCenterAndUnit.GetCorner(nzRectCorner_LeftBottom)); + REQUIRE(firstCenterAndUnit.GetCorner(Nz::RectCorner_LeftBottom) == secondCenterAndUnit.GetCorner(Nz::RectCorner_LeftBottom)); CHECK(firstCenterAndUnit.IsValid()); } } WHEN("We move one from (0.5, 0.5)") { - firstCenterAndUnit.Translate(NzVector2f(0.5f, 0.5f)); + firstCenterAndUnit.Translate(Nz::Vector2f(0.5f, 0.5f)); THEN("The collision should be (0.5, 0.5) -> (0.5, 0.5)") { - NzRectf tmp; + Nz::Rectf tmp; CHECK(firstCenterAndUnit.Intersect(secondCenterAndUnit, &tmp)); - REQUIRE(tmp == NzRectf(0.5f, 0.5f, 0.5f, 0.5f)); + REQUIRE(tmp == Nz::Rectf(0.5f, 0.5f, 0.5f, 0.5f)); } } @@ -43,12 +43,12 @@ SCENARIO("Rect", "[MATH][RECT]") { THEN("These results are expected") { - REQUIRE(firstCenterAndUnit.GetLengths() == NzVector2f::Unit()); - REQUIRE(firstCenterAndUnit.GetMaximum() == NzVector2f::Unit()); - REQUIRE(firstCenterAndUnit.GetMinimum() == NzVector2f::Zero()); - REQUIRE(firstCenterAndUnit.GetNegativeVertex(NzVector2f::Unit()) == NzVector2f::Zero()); - REQUIRE(firstCenterAndUnit.GetPosition() == NzVector2f::Zero()); - REQUIRE(firstCenterAndUnit.GetPositiveVertex(NzVector2f::Unit()) == NzVector2f::Unit()); + REQUIRE(firstCenterAndUnit.GetLengths() == Nz::Vector2f::Unit()); + REQUIRE(firstCenterAndUnit.GetMaximum() == Nz::Vector2f::Unit()); + REQUIRE(firstCenterAndUnit.GetMinimum() == Nz::Vector2f::Zero()); + REQUIRE(firstCenterAndUnit.GetNegativeVertex(Nz::Vector2f::Unit()) == Nz::Vector2f::Zero()); + REQUIRE(firstCenterAndUnit.GetPosition() == Nz::Vector2f::Zero()); + REQUIRE(firstCenterAndUnit.GetPositiveVertex(Nz::Vector2f::Unit()) == Nz::Vector2f::Unit()); } } diff --git a/tests/Engine/Math/Sphere.cpp b/tests/Engine/Math/Sphere.cpp index ee902eb6a..0f0e509ca 100644 --- a/tests/Engine/Math/Sphere.cpp +++ b/tests/Engine/Math/Sphere.cpp @@ -5,8 +5,8 @@ SCENARIO("Sphere", "[MATH][SPHERE]") { GIVEN("Two same sphere center and unit") { - NzSpheref firstCenterAndUnit(0.f, 0.f, 0.f, 1.f); - NzSpheref secondCenterAndUnit(NzSphere(NzVector3i::Zero(), 1)); + Nz::Spheref firstCenterAndUnit(0.f, 0.f, 0.f, 1.f); + Nz::Spheref secondCenterAndUnit(Nz::Sphere(Nz::Vector3i::Zero(), 1)); WHEN("We compare them") { @@ -21,19 +21,19 @@ SCENARIO("Sphere", "[MATH][SPHERE]") THEN("These results are expected for Contains") { CHECK(firstCenterAndUnit.Contains(0.5f, 0.5f, 0.5f)); - CHECK(firstCenterAndUnit.Contains(NzBoxf(NzVector3f::Zero(), NzVector3f::Unit() * 0.5f))); - CHECK(!firstCenterAndUnit.Contains(NzBoxf(NzVector3f::Zero(), NzVector3f::Unit() * 5.f))); + CHECK(firstCenterAndUnit.Contains(Nz::Boxf(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.5f))); + CHECK(!firstCenterAndUnit.Contains(Nz::Boxf(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 5.f))); } THEN("There are for Intersect") { - CHECK(firstCenterAndUnit.Intersect(NzBoxf(NzVector3f::Zero(), NzVector3f::Unit() * 0.5f))); - CHECK(firstCenterAndUnit.Intersect(NzBoxf(NzVector3f::Zero(), NzVector3f::Unit() * 5.f))); - CHECK(!firstCenterAndUnit.Intersect(NzBoxf(NzVector3f::Unit() * 5.f, NzVector3f::Unit()))); + CHECK(firstCenterAndUnit.Intersect(Nz::Boxf(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 0.5f))); + CHECK(firstCenterAndUnit.Intersect(Nz::Boxf(Nz::Vector3f::Zero(), Nz::Vector3f::Unit() * 5.f))); + CHECK(!firstCenterAndUnit.Intersect(Nz::Boxf(Nz::Vector3f::Unit() * 5.f, Nz::Vector3f::Unit()))); - CHECK(firstCenterAndUnit.Intersect(NzSpheref(NzVector3f::Zero(), 0.5f))); - CHECK(firstCenterAndUnit.Intersect(NzSpheref(NzVector3f::Zero(), 5.f))); - CHECK(!firstCenterAndUnit.Intersect(NzSpheref(NzVector3f::Unit() * 5.f, 1.f))); + CHECK(firstCenterAndUnit.Intersect(Nz::Spheref(Nz::Vector3f::Zero(), 0.5f))); + CHECK(firstCenterAndUnit.Intersect(Nz::Spheref(Nz::Vector3f::Zero(), 5.f))); + CHECK(!firstCenterAndUnit.Intersect(Nz::Spheref(Nz::Vector3f::Unit() * 5.f, 1.f))); } } @@ -41,22 +41,22 @@ SCENARIO("Sphere", "[MATH][SPHERE]") { THEN("These results are expected") { - REQUIRE(firstCenterAndUnit.Distance(NzVector3f::UnitX()) == Approx(1.f)); - REQUIRE(firstCenterAndUnit.SquaredDistance(NzVector3f::UnitX()) == Approx(1.f)); + REQUIRE(firstCenterAndUnit.Distance(Nz::Vector3f::UnitX()) == Approx(1.f)); + REQUIRE(firstCenterAndUnit.SquaredDistance(Nz::Vector3f::UnitX()) == Approx(1.f)); - NzSpheref tmp(NzVector3f::UnitX(), 1.f); - REQUIRE(tmp.Distance(NzVector3f::UnitX() * 4.f) == Approx(3.f)); - REQUIRE(tmp.SquaredDistance(NzVector3f::UnitX() * 4.f) == Approx(9.f)); + Nz::Spheref tmp(Nz::Vector3f::UnitX(), 1.f); + REQUIRE(tmp.Distance(Nz::Vector3f::UnitX() * 4.f) == Approx(3.f)); + REQUIRE(tmp.SquaredDistance(Nz::Vector3f::UnitX() * 4.f) == Approx(9.f)); } } WHEN("We get sphere from box unit and center") { - NzBoxf centerUnitBox(NzVector3f::Unit() * -0.5f, NzVector3f::Unit() * 0.5f); + Nz::Boxf centerUnitBox(Nz::Vector3f::Unit() * -0.5f, Nz::Vector3f::Unit() * 0.5f); THEN("This is equal to sphere center and radius 0.75") { - REQUIRE(centerUnitBox.GetSquaredBoundingSphere() == NzSpheref(NzVector3f::Zero(), 0.75f)); + REQUIRE(centerUnitBox.GetSquaredBoundingSphere() == Nz::Spheref(Nz::Vector3f::Zero(), 0.75f)); } } } diff --git a/tests/Engine/Math/Vector2.cpp b/tests/Engine/Math/Vector2.cpp index 07f7dd5c3..17ae62e72 100644 --- a/tests/Engine/Math/Vector2.cpp +++ b/tests/Engine/Math/Vector2.cpp @@ -7,8 +7,8 @@ SCENARIO("Vector2", "[MATH][VECTOR2]") { GIVEN("Two same vectors (1, 1)") { - NzVector2f firstUnit(1.f); - NzVector2f secondUnit(NzVector2i(NzVector4i(1, 1, 3, 5))); + Nz::Vector2f firstUnit(1.f); + Nz::Vector2f secondUnit(Nz::Vector2i(Nz::Vector4i(1, 1, 3, 5))); WHEN("We compare them") { @@ -20,7 +20,7 @@ SCENARIO("Vector2", "[MATH][VECTOR2]") WHEN("We test the dot product") { - NzVector2f tmp(-1.f, 1.f); + Nz::Vector2f tmp(-1.f, 1.f); THEN("These results are expected") { @@ -32,8 +32,8 @@ SCENARIO("Vector2", "[MATH][VECTOR2]") WHEN("We ask for distance from (-2, -3)") { - NzVector2f tmp(-2.f, -3.f); - NzVector2f tmp2(-1.f, -1.f); + Nz::Vector2f tmp(-2.f, -3.f); + Nz::Vector2f tmp2(-1.f, -1.f); THEN("These are expected") { diff --git a/tests/Engine/Math/Vector3.cpp b/tests/Engine/Math/Vector3.cpp index 49239a9d0..a61016e82 100644 --- a/tests/Engine/Math/Vector3.cpp +++ b/tests/Engine/Math/Vector3.cpp @@ -7,8 +7,8 @@ SCENARIO("Vector3", "[MATH][VECTOR3]") { GIVEN("Two same unit vector") { - NzVector3f firstUnit(1.f, 1.f, 1.f); - NzVector3f secondUnit(NzVector3i(NzVector4i(1, 1, 1, 5))); + Nz::Vector3f firstUnit(1.f, 1.f, 1.f); + Nz::Vector3f secondUnit(Nz::Vector3i(Nz::Vector4i(1, 1, 1, 5))); WHEN("We compare them") { @@ -20,7 +20,7 @@ SCENARIO("Vector3", "[MATH][VECTOR3]") WHEN("We test the dot product") { - NzVector3f tmp(-1.f, 0.f, 1.f); + Nz::Vector3f tmp(-1.f, 0.f, 1.f); THEN("These results are expected") { @@ -34,14 +34,14 @@ SCENARIO("Vector3", "[MATH][VECTOR3]") { THEN("These results are expected") { - REQUIRE(NzVector3f::CrossProduct(NzVector3f::UnitX(), NzVector3f::UnitY()) == NzVector3f::UnitZ()); - REQUIRE(NzVector3f::CrossProduct(NzVector3f(1.f, 2.f, 3.f), NzVector3f(3.f, 2.f, 1.f)) == NzVector3f(-4.f, 8.f, -4.f)); + REQUIRE(Nz::Vector3f::CrossProduct(Nz::Vector3f::UnitX(), Nz::Vector3f::UnitY()) == Nz::Vector3f::UnitZ()); + REQUIRE(Nz::Vector3f::CrossProduct(Nz::Vector3f(1.f, 2.f, 3.f), Nz::Vector3f(3.f, 2.f, 1.f)) == Nz::Vector3f(-4.f, 8.f, -4.f)); } } WHEN("We ask for distance") { - NzVector3f tmp(-1.f, -5.f, -8.f); + Nz::Vector3f tmp(-1.f, -5.f, -8.f); THEN("These are expected") { diff --git a/tests/Engine/Math/Vector4.cpp b/tests/Engine/Math/Vector4.cpp index f2f14daad..cfe91eab7 100644 --- a/tests/Engine/Math/Vector4.cpp +++ b/tests/Engine/Math/Vector4.cpp @@ -7,8 +7,8 @@ SCENARIO("Vector4", "[MATH][VECTOR4]") { GIVEN("Two same unit vector") { - NzVector4f firstUnit(1.f, 1.f, 1.f); - NzVector4f secondUnit(NzVector4i(1, 1, 1, 1)); + Nz::Vector4f firstUnit(1.f, 1.f, 1.f); + Nz::Vector4f secondUnit(Nz::Vector4i(1, 1, 1, 1)); WHEN("We compare them") { @@ -20,7 +20,7 @@ SCENARIO("Vector4", "[MATH][VECTOR4]") WHEN("We test the dot product") { - NzVector4f tmp(-1.f, 0.f, 1.f, 0.f); + Nz::Vector4f tmp(-1.f, 0.f, 1.f, 0.f); THEN("These results are expected") { @@ -31,12 +31,12 @@ SCENARIO("Vector4", "[MATH][VECTOR4]") WHEN("We normalize") { - NzVector4f tmp(1.f, 1.f, 1.f, 3.f); + Nz::Vector4f tmp(1.f, 1.f, 1.f, 3.f); THEN("These results are expected") { - REQUIRE(firstUnit.Normalize() == NzVector4f(1.f, NzVector3f::Unit())); - REQUIRE(tmp.Normalize() == NzVector4f(NzVector3f::Unit() * (1.f / 3.f), 1.f)); + REQUIRE(firstUnit.Normalize() == Nz::Vector4f(1.f, Nz::Vector3f::Unit())); + REQUIRE(tmp.Normalize() == Nz::Vector4f(Nz::Vector3f::Unit() * (1.f / 3.f), 1.f)); } } } From fe2e47478ec0f86f0e27646e22c1b8496e661313 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 25 Sep 2015 23:17:44 +0200 Subject: [PATCH 09/97] Commit forgotten files Former-commit-id: dd296ce0e7c4128c35b41cbe753ffb572858ba6c --- include/Nazara/Physics/Geom.hpp | 14 +++++++------- include/Nazara/Physics/Geom.inl | 4 ++-- include/Nazara/Renderer/RenderStates.inl | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/Nazara/Physics/Geom.hpp b/include/Nazara/Physics/Geom.hpp index 1a82f8445..3db143292 100644 --- a/include/Nazara/Physics/Geom.hpp +++ b/include/Nazara/Physics/Geom.hpp @@ -190,22 +190,22 @@ namespace Nz unsigned int m_vertexStride; }; - class NzCylinderGeom; + class CylinderGeom; - using NzCylinderGeomConstRef = ObjectRef; - using NzCylinderGeomRef = ObjectRef; + using CylinderGeomConstRef = ObjectRef; + using CylinderGeomRef = ObjectRef; - class NAZARA_PHYSICS_API NzCylinderGeom : public PhysGeom + class NAZARA_PHYSICS_API CylinderGeom : public PhysGeom { public: - NzCylinderGeom(float length, float radius, const Matrix4f& transformMatrix = Matrix4f::Identity()); - NzCylinderGeom(float length, float radius, const Vector3f& translation, const Quaternionf& rotation = Quaternionf::Identity()); + CylinderGeom(float length, float radius, const Matrix4f& transformMatrix = Matrix4f::Identity()); + CylinderGeom(float length, float radius, const Vector3f& translation, const Quaternionf& rotation = Quaternionf::Identity()); float GetLength() const; float GetRadius() const; GeomType GetType() const override; - template static NzCylinderGeomRef New(Args&&... args); + template static CylinderGeomRef New(Args&&... args); private: NewtonCollision* CreateHandle(PhysWorld* world) const override; diff --git a/include/Nazara/Physics/Geom.inl b/include/Nazara/Physics/Geom.inl index 1489348ac..9699cac96 100644 --- a/include/Nazara/Physics/Geom.inl +++ b/include/Nazara/Physics/Geom.inl @@ -53,9 +53,9 @@ namespace Nz } template - NzCylinderGeomRef NzCylinderGeom::New(Args&&... args) + CylinderGeomRef CylinderGeom::New(Args&&... args) { - std::unique_ptr object(new NzCylinderGeom(std::forward(args)...)); + std::unique_ptr object(new CylinderGeom(std::forward(args)...)); object->SetPersistent(false); return object.release(); diff --git a/include/Nazara/Renderer/RenderStates.inl b/include/Nazara/Renderer/RenderStates.inl index 498cdee56..6840d3b5f 100644 --- a/include/Nazara/Renderer/RenderStates.inl +++ b/include/Nazara/Renderer/RenderStates.inl @@ -29,11 +29,11 @@ namespace Nz Face& face = (i == 0) ? backFace : frontFace; face.stencilCompare = RendererComparison_Always; - face.stencilFail = nzStencilOperation_Keep; + face.stencilFail = StencilOperation_Keep; face.stencilMask = 0xFFFFFFFF; - face.stencilPass = nzStencilOperation_Keep; + face.stencilPass = StencilOperation_Keep; face.stencilReference = 0; - face.stencilZFail = nzStencilOperation_Keep; + face.stencilZFail = StencilOperation_Keep; } } From 504452a60be6ec52dcfb42b2509789ab715fe9cf Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 26 Sep 2015 21:54:34 +0200 Subject: [PATCH 10/97] Ndk/World: Fix crash with unused-systems Former-commit-id: 2425e885d4f93033d3d6f367944ef2893f043223 --- SDK/include/NDK/World.inl | 5 ++++- SDK/src/NDK/World.cpp | 4 ++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/SDK/include/NDK/World.inl b/SDK/include/NDK/World.inl index 3040e3d6c..a9e22774b 100644 --- a/SDK/include/NDK/World.inl +++ b/SDK/include/NDK/World.inl @@ -136,7 +136,10 @@ namespace Ndk // And then update systems for (auto& systemPtr : m_systems) - systemPtr->Update(elapsedTime); + { + if (systemPtr) + systemPtr->Update(elapsedTime); + } } inline void World::Invalidate() diff --git a/SDK/src/NDK/World.cpp b/SDK/src/NDK/World.cpp index 8db940558..7ee1fde49 100644 --- a/SDK/src/NDK/World.cpp +++ b/SDK/src/NDK/World.cpp @@ -132,6 +132,10 @@ namespace Ndk { for (auto& system : m_systems) { + // Ignore non-existent systems + if (!system) + continue; + // L'entité est-elle enregistrée comme faisant partie du système ? bool partOfSystem = system->HasEntity(entity); From 752518ef146cd62013c043aaf8a774c0aaef827d Mon Sep 17 00:00:00 2001 From: Youri Hubaut Date: Sun, 27 Sep 2015 15:37:45 +0200 Subject: [PATCH 11/97] Fix module compilation on linux Former-commit-id: 205c6578fd50e506ec7d6012e73fea0c14c744d9 --- build/scripts/modules/core.lua | 5 +++++ build/scripts/modules/renderer.lua | 5 +++++ build/scripts/modules/utility.lua | 10 ++++++++++ 3 files changed, 20 insertions(+) diff --git a/build/scripts/modules/core.lua b/build/scripts/modules/core.lua index e5dabac46..7156ef2f6 100644 --- a/build/scripts/modules/core.lua +++ b/build/scripts/modules/core.lua @@ -15,3 +15,8 @@ MODULE.OsFiles.Posix = { "../src/Nazara/Core/Posix/**.hpp", "../src/Nazara/Core/Posix/**.cpp" } + +MODULE.OsLibraries.Posix = { + "dl", + "pthread" +} diff --git a/build/scripts/modules/renderer.lua b/build/scripts/modules/renderer.lua index a15b892f7..7e3edadbe 100644 --- a/build/scripts/modules/renderer.lua +++ b/build/scripts/modules/renderer.lua @@ -24,3 +24,8 @@ MODULE.OsLibraries.Windows = { "opengl32", "winmm" } + +MODULE.OsLibraries.Posix = { + "GL", + "X11" +} diff --git a/build/scripts/modules/utility.lua b/build/scripts/modules/utility.lua index dae90bbf6..1fafbd1a4 100644 --- a/build/scripts/modules/utility.lua +++ b/build/scripts/modules/utility.lua @@ -20,3 +20,13 @@ MODULE.OsLibraries.Windows = { "gdi32" } +MODULE.OsLibraries.Posix = { + "X11", + "xcb", + "xcb-cursor", + "xcb-ewmh", + "xcb-icccm", + "xcb-keysyms", + "xcb-randr" +} + From 37586e72838c9418ab6b837153e2de05173469b6 Mon Sep 17 00:00:00 2001 From: Youri Hubaut Date: Sun, 27 Sep 2015 15:58:49 +0200 Subject: [PATCH 12/97] Switch from Nz prefix to namespace Nz for linux Former-commit-id: 64eeaf3c633254b04910ebd4576fd9e910002be0 --- include/Nazara/Prerequesites.hpp | 1 + include/Nazara/Renderer/OpenGL.hpp | 6 +- include/Nazara/Utility/WindowHandle.hpp | 6 +- src/Nazara/Audio/Debug/NewOverload.cpp | 8 +- src/Nazara/Core/Posix/ClockImpl.cpp | 31 +- src/Nazara/Core/Posix/ClockImpl.hpp | 9 +- .../Core/Posix/ConditionVariableImpl.cpp | 77 +- .../Core/Posix/ConditionVariableImpl.hpp | 29 +- src/Nazara/Core/Posix/DirectoryImpl.cpp | 163 +- src/Nazara/Core/Posix/DirectoryImpl.hpp | 51 +- src/Nazara/Core/Posix/DynLibImpl.cpp | 95 +- src/Nazara/Core/Posix/DynLibImpl.hpp | 28 +- src/Nazara/Core/Posix/FileImpl.cpp | 425 +-- src/Nazara/Core/Posix/FileImpl.hpp | 65 +- src/Nazara/Core/Posix/HardwareInfoImpl.cpp | 103 +- src/Nazara/Core/Posix/HardwareInfoImpl.hpp | 17 +- src/Nazara/Core/Posix/MutexImpl.cpp | 45 +- src/Nazara/Core/Posix/MutexImpl.hpp | 25 +- src/Nazara/Core/Posix/SemaphoreImpl.cpp | 113 +- src/Nazara/Core/Posix/SemaphoreImpl.hpp | 25 +- src/Nazara/Core/Posix/TaskSchedulerImpl.cpp | 339 +- src/Nazara/Core/Posix/TaskSchedulerImpl.hpp | 51 +- src/Nazara/Core/Posix/ThreadImpl.cpp | 121 +- src/Nazara/Core/Posix/ThreadImpl.hpp | 27 +- src/Nazara/Graphics/Debug/NewOverload.cpp | 8 +- .../Graphics/ForwardRenderTechnique.cpp | 2 +- src/Nazara/Lua/Debug/NewOverload.cpp | 8 +- src/Nazara/Noise/Debug/NewOverload.cpp | 8 +- src/Nazara/Physics/Debug/NewOverload.cpp | 8 +- src/Nazara/Renderer/Context.cpp | 2 +- src/Nazara/Renderer/Debug/NewOverload.cpp | 8 +- src/Nazara/Renderer/GLX/ContextImpl.cpp | 499 +-- src/Nazara/Renderer/GLX/ContextImpl.hpp | 39 +- src/Nazara/Renderer/OpenGL.cpp | 20 +- src/Nazara/Utility/Debug/NewOverload.cpp | 8 +- src/Nazara/Utility/X11/CursorImpl.cpp | 263 +- src/Nazara/Utility/X11/CursorImpl.hpp | 24 +- src/Nazara/Utility/X11/Display.cpp | 107 +- src/Nazara/Utility/X11/Display.hpp | 46 +- src/Nazara/Utility/X11/IconImpl.cpp | 211 +- src/Nazara/Utility/X11/IconImpl.hpp | 30 +- src/Nazara/Utility/X11/InputImpl.cpp | 594 ++-- src/Nazara/Utility/X11/InputImpl.hpp | 24 +- src/Nazara/Utility/X11/ScopedXCB.cpp | 327 +- src/Nazara/Utility/X11/ScopedXCB.hpp | 121 +- src/Nazara/Utility/X11/VideoModeImpl.cpp | 281 +- src/Nazara/Utility/X11/VideoModeImpl.hpp | 14 +- src/Nazara/Utility/X11/WindowImpl.cpp | 2955 +++++++++-------- src/Nazara/Utility/X11/WindowImpl.hpp | 183 +- 49 files changed, 3918 insertions(+), 3732 deletions(-) diff --git a/include/Nazara/Prerequesites.hpp b/include/Nazara/Prerequesites.hpp index edc608dff..c2c83626a 100644 --- a/include/Nazara/Prerequesites.hpp +++ b/include/Nazara/Prerequesites.hpp @@ -116,6 +116,7 @@ #endif #elif defined(__linux__) || defined(__unix__) #define NAZARA_PLATFORM_LINUX + #define NAZARA_PLATFORM_GLX #define NAZARA_PLATFORM_POSIX #define NAZARA_PLATFORM_X11 diff --git a/include/Nazara/Renderer/OpenGL.hpp b/include/Nazara/Renderer/OpenGL.hpp index ecac5b526..403a7a534 100644 --- a/include/Nazara/Renderer/OpenGL.hpp +++ b/include/Nazara/Renderer/OpenGL.hpp @@ -21,10 +21,10 @@ #include #if defined(NAZARA_PLATFORM_WINDOWS) #include -#elif defined(NAZARA_PLATFORM_LINUX) +#elif defined(NAZARA_PLATFORM_GLX) namespace GLX { - #include + #include // Defined in a namespace to avoid conflict } #include #endif @@ -329,7 +329,7 @@ NAZARA_RENDERER_API extern PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAtt NAZARA_RENDERER_API extern PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB; NAZARA_RENDERER_API extern PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT; NAZARA_RENDERER_API extern PFNWGLSWAPINTERVALEXTPROC wglSwapInterval; -#elif defined(NAZARA_PLATFORM_LINUX) +#elif defined(NAZARA_PLATFORM_GLX) NAZARA_RENDERER_API extern GLX::PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs; NAZARA_RENDERER_API extern GLX::PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT; NAZARA_RENDERER_API extern GLX::PFNGLXSWAPINTERVALMESAPROC NzglXSwapIntervalMESA; diff --git a/include/Nazara/Utility/WindowHandle.hpp b/include/Nazara/Utility/WindowHandle.hpp index 63b5dc2ac..9b5e34c83 100644 --- a/include/Nazara/Utility/WindowHandle.hpp +++ b/include/Nazara/Utility/WindowHandle.hpp @@ -8,14 +8,16 @@ #define NAZARA_WINDOWHANDLE_HPP #include +#if defined(NAZARA_PLATFORM_X11) +#include +#endif namespace Nz { #if defined(NAZARA_PLATFORM_WINDOWS) // http://msdn.microsoft.com/en-us/library/aa383751(v=vs.85).aspx typedef void* WindowHandle; - #elif defined(NAZARA_PLATFORM_LINUX) - #include + #elif defined(NAZARA_PLATFORM_X11) // http://en.wikipedia.org/wiki/Xlib#Data_types using WindowHandle = xcb_window_t; #else diff --git a/src/Nazara/Audio/Debug/NewOverload.cpp b/src/Nazara/Audio/Debug/NewOverload.cpp index ebab9512a..359db9756 100644 --- a/src/Nazara/Audio/Debug/NewOverload.cpp +++ b/src/Nazara/Audio/Debug/NewOverload.cpp @@ -10,22 +10,22 @@ void* operator new(std::size_t size) { - return NzMemoryManager::Allocate(size, false); + return Nz::MemoryManager::Allocate(size, false); } void* operator new[](std::size_t size) { - return NzMemoryManager::Allocate(size, true); + return Nz::MemoryManager::Allocate(size, true); } void operator delete(void* pointer) noexcept { - NzMemoryManager::Free(pointer, false); + Nz::MemoryManager::Free(pointer, false); } void operator delete[](void* pointer) noexcept { - NzMemoryManager::Free(pointer, true); + Nz::MemoryManager::Free(pointer, true); } #endif // NAZARA_AUDIO_MANAGE_MEMORY diff --git a/src/Nazara/Core/Posix/ClockImpl.cpp b/src/Nazara/Core/Posix/ClockImpl.cpp index 9058760b8..73b45b6e7 100644 --- a/src/Nazara/Core/Posix/ClockImpl.cpp +++ b/src/Nazara/Core/Posix/ClockImpl.cpp @@ -8,21 +8,24 @@ #include #include -bool NzClockImplInitializeHighPrecision() +namespace Nz { - return true; // No initialization needed -} + bool ClockImplInitializeHighPrecision() + { + return true; // No initialization needed + } -nzUInt64 NzClockImplGetMicroseconds() -{ - timeval clock; - gettimeofday(&clock, nullptr); - return static_cast(clock.tv_sec*1000000 + clock.tv_usec); -} + UInt64 ClockImplGetElapsedMicroseconds() + { + timeval clock; + gettimeofday(&clock, nullptr); + return static_cast(clock.tv_sec*1000000 + clock.tv_usec); + } -nzUInt64 NzClockImplGetMilliseconds() -{ - timeval clock; - gettimeofday(&clock, nullptr); - return static_cast(clock.tv_sec*1000 + (clock.tv_usec/1000)); + UInt64 ClockImplGetElapsedMilliseconds() + { + timeval clock; + gettimeofday(&clock, nullptr); + return static_cast(clock.tv_sec*1000 + (clock.tv_usec/1000)); + } } diff --git a/src/Nazara/Core/Posix/ClockImpl.hpp b/src/Nazara/Core/Posix/ClockImpl.hpp index 2628214be..552a00bf6 100644 --- a/src/Nazara/Core/Posix/ClockImpl.hpp +++ b/src/Nazara/Core/Posix/ClockImpl.hpp @@ -9,8 +9,11 @@ #include -bool NzClockImplInitializeHighPrecision(); -nzUInt64 NzClockImplGetMicroseconds(); -nzUInt64 NzClockImplGetMilliseconds(); +namespace Nz +{ + bool ClockImplInitializeHighPrecision(); + UInt64 ClockImplGetElapsedMicroseconds(); + UInt64 ClockImplGetElapsedMilliseconds(); +} #endif // NAZARA_CLOCKIMPL_POSIX_HPP diff --git a/src/Nazara/Core/Posix/ConditionVariableImpl.cpp b/src/Nazara/Core/Posix/ConditionVariableImpl.cpp index 7a8ba8fc3..c1c6e891d 100644 --- a/src/Nazara/Core/Posix/ConditionVariableImpl.cpp +++ b/src/Nazara/Core/Posix/ConditionVariableImpl.cpp @@ -6,42 +6,45 @@ #include #include -NzConditionVariableImpl::NzConditionVariableImpl() +namespace Nz { - pthread_cond_init(&m_cv, nullptr); -} - -NzConditionVariableImpl::~NzConditionVariableImpl() -{ - pthread_cond_destroy(&m_cv); -} - -void NzConditionVariableImpl::Signal() -{ - pthread_cond_signal(&m_cv); -} - -void NzConditionVariableImpl::SignalAll() -{ - pthread_cond_broadcast(&m_cv); -} - -void NzConditionVariableImpl::Wait(NzMutexImpl* mutex) -{ - pthread_cond_wait(&m_cv, &mutex->m_handle); -} - -bool NzConditionVariableImpl::Wait(NzMutexImpl* mutex, nzUInt32 timeout) -{ - // get the current time - timeval tv; - gettimeofday(&tv, nullptr); - - // construct the time limit (current time + time to wait) - timespec ti; - ti.tv_nsec = (tv.tv_usec + (timeout % 1000)) * 1000000; - ti.tv_sec = tv.tv_sec + (timeout / 1000) + (ti.tv_nsec / 1000000000); - ti.tv_nsec %= 1000000000; - - return pthread_cond_timedwait(&m_cv,&mutex->m_handle, &ti) != 0; + ConditionVariableImpl::ConditionVariableImpl() + { + pthread_cond_init(&m_cv, nullptr); + } + + ConditionVariableImpl::~ConditionVariableImpl() + { + pthread_cond_destroy(&m_cv); + } + + void ConditionVariableImpl::Signal() + { + pthread_cond_signal(&m_cv); + } + + void ConditionVariableImpl::SignalAll() + { + pthread_cond_broadcast(&m_cv); + } + + void ConditionVariableImpl::Wait(MutexImpl* mutex) + { + pthread_cond_wait(&m_cv, &mutex->m_handle); + } + + bool ConditionVariableImpl::Wait(MutexImpl* mutex, UInt32 timeout) + { + // get the current time + timeval tv; + gettimeofday(&tv, nullptr); + + // construct the time limit (current time + time to wait) + timespec ti; + ti.tv_nsec = (tv.tv_usec + (timeout % 1000)) * 1000000; + ti.tv_sec = tv.tv_sec + (timeout / 1000) + (ti.tv_nsec / 1000000000); + ti.tv_nsec %= 1000000000; + + return pthread_cond_timedwait(&m_cv,&mutex->m_handle, &ti) != 0; + } } diff --git a/src/Nazara/Core/Posix/ConditionVariableImpl.hpp b/src/Nazara/Core/Posix/ConditionVariableImpl.hpp index a49cbf901..1781711c4 100644 --- a/src/Nazara/Core/Posix/ConditionVariableImpl.hpp +++ b/src/Nazara/Core/Posix/ConditionVariableImpl.hpp @@ -14,22 +14,25 @@ #include #include -class NzMutexImpl; - -class NzConditionVariableImpl +namespace Nz { - public: - NzConditionVariableImpl(); - ~NzConditionVariableImpl(); + class MutexImpl; - void Signal(); - void SignalAll(); + class ConditionVariableImpl + { + public: + ConditionVariableImpl(); + ~ConditionVariableImpl(); - void Wait(NzMutexImpl* mutex); - bool Wait(NzMutexImpl* mutex, nzUInt32 timeout); + void Signal(); + void SignalAll(); - private: - pthread_cond_t m_cv; -}; + void Wait(MutexImpl* mutex); + bool Wait(MutexImpl* mutex, UInt32 timeout); + + private: + pthread_cond_t m_cv; + }; +} #endif // NAZARA_CONDITIONVARIABLEIMPL_HPP diff --git a/src/Nazara/Core/Posix/DirectoryImpl.cpp b/src/Nazara/Core/Posix/DirectoryImpl.cpp index 76155e12c..4abf575b3 100644 --- a/src/Nazara/Core/Posix/DirectoryImpl.cpp +++ b/src/Nazara/Core/Posix/DirectoryImpl.cpp @@ -9,95 +9,98 @@ #include #include -NzDirectoryImpl::NzDirectoryImpl(const NzDirectory* parent) +namespace Nz { - NazaraUnused(parent); -} + DirectoryImpl::DirectoryImpl(const Directory* parent) + { + NazaraUnused(parent); + } -void NzDirectoryImpl::Close() -{ - closedir(m_handle); -} + void DirectoryImpl::Close() + { + closedir(m_handle); + } -NzString NzDirectoryImpl::GetResultName() const -{ - return m_result->d_name; -} + String DirectoryImpl::GetResultName() const + { + return m_result->d_name; + } -nzUInt64 NzDirectoryImpl::GetResultSize() const -{ - struct stat64 resulststat; - stat64(m_result->d_name, &resulststat); + UInt64 DirectoryImpl::GetResultSize() const + { + struct stat64 resulststat; + stat64(m_result->d_name, &resulststat); - return static_cast(resulststat.st_size); -} + return static_cast(resulststat.st_size); + } -bool NzDirectoryImpl::IsResultDirectory() const -{ - struct stat64 filestats; - if (stat64(m_result->d_name, &filestats) == -1) // error - return false; + bool DirectoryImpl::IsResultDirectory() const + { + struct stat64 filestats; + if (stat64(m_result->d_name, &filestats) == -1) // error + return false; - return S_ISDIR(filestats.st_mode); -} + return S_ISDIR(filestats.st_mode); + } + + bool DirectoryImpl::NextResult() + { + if ((m_result = readdir64(m_handle))) + return true; + else + { + if (errno != ENOENT) + NazaraError("Unable to get next result: " + Error::GetLastSystemError()); + + return false; + } + } + + bool DirectoryImpl::Open(const String& dirPath) + { + m_handle = opendir(dirPath.GetConstBuffer()); + if (!m_handle) + { + NazaraError("Unable to open directory: " + Error::GetLastSystemError()); + return false; + } -bool NzDirectoryImpl::NextResult() -{ - if ((m_result = readdir64(m_handle))) return true; - else - { - if (errno != ENOENT) - NazaraError("Unable to get next result: " + NzError::GetLastSystemError()); - - return false; - } -} - -bool NzDirectoryImpl::Open(const NzString& dirPath) -{ - m_handle = opendir(dirPath.GetConstBuffer()); - if (!m_handle) - { - NazaraError("Unable to open directory: " + NzError::GetLastSystemError()); - return false; } - return true; -} - -bool NzDirectoryImpl::Create(const NzString& dirPath) -{ - mode_t permissions; // TODO: check permissions - - return mkdir(dirPath.GetConstBuffer(), permissions) != -1;; -} - -bool NzDirectoryImpl::Exists(const NzString& dirPath) -{ - struct stat64 filestats; - if (stat64(dirPath.GetConstBuffer(), &filestats) == -1) // error - return false; - - return S_ISDIR(filestats.st_mode) || S_ISREG(filestats.st_mode); -} - -NzString NzDirectoryImpl::GetCurrent() -{ - NzString currentPath; - - char path[MAXPATHLEN]; - if (getcwd(path, MAXPATHLEN)) - currentPath = path; - else - NazaraError("Unable to get current directory: " + NzError::GetLastSystemError()); // Bug: initialisation -> if no path for log ! - - return currentPath; -} - -bool NzDirectoryImpl::Remove(const NzString& dirPath) -{ - bool success = rmdir(dirPath.GetConstBuffer()) != -1; - - return success; + bool DirectoryImpl::Create(const String& dirPath) + { + mode_t permissions; // TODO: check permissions + + return mkdir(dirPath.GetConstBuffer(), permissions) != -1;; + } + + bool DirectoryImpl::Exists(const String& dirPath) + { + struct stat64 filestats; + if (stat64(dirPath.GetConstBuffer(), &filestats) == -1) // error + return false; + + return S_ISDIR(filestats.st_mode) || S_ISREG(filestats.st_mode); + } + + String DirectoryImpl::GetCurrent() + { + String currentPath; + + char path[MAXPATHLEN]; + if (getcwd(path, MAXPATHLEN)) + currentPath = path; + else + NazaraError("Unable to get current directory: " + Error::GetLastSystemError()); // Bug: initialisation -> if no path for log ! + + return currentPath; + } + + bool DirectoryImpl::Remove(const String& dirPath) + { + bool success = rmdir(dirPath.GetConstBuffer()) != -1; + + return success; + } } diff --git a/src/Nazara/Core/Posix/DirectoryImpl.hpp b/src/Nazara/Core/Posix/DirectoryImpl.hpp index 858e21930..5f77fbb43 100644 --- a/src/Nazara/Core/Posix/DirectoryImpl.hpp +++ b/src/Nazara/Core/Posix/DirectoryImpl.hpp @@ -8,40 +8,47 @@ #define NAZARA_DIRECTORYIMPL_HPP #include -#include #include #include #include #include -class NzDirectory; -class NzString; - -class NzDirectoryImpl : NzNonCopyable +namespace Nz { - public: - NzDirectoryImpl(const NzDirectory* parent); - ~NzDirectoryImpl() = default; + class Directory; + class String; - void Close(); + class DirectoryImpl + { + public: + DirectoryImpl(const Directory* parent); + DirectoryImpl(const DirectoryImpl&) = delete; + DirectoryImpl(DirectoryImpl&&) = delete; ///TODO + ~DirectoryImpl() = default; - NzString GetResultName() const; - nzUInt64 GetResultSize() const; + void Close(); - bool IsResultDirectory() const; + String GetResultName() const; + UInt64 GetResultSize() const; - bool NextResult(); + bool IsResultDirectory() const; - bool Open(const NzString& dirPath); + bool NextResult(); - static bool Create(const NzString& dirPath); - static bool Exists(const NzString& dirPath); - static NzString GetCurrent(); - static bool Remove(const NzString& dirPath); + bool Open(const String& dirPath); - private: - DIR* m_handle; - dirent64* m_result; -}; + DirectoryImpl& operator=(const DirectoryImpl&) = delete; + DirectoryImpl& operator=(DirectoryImpl&&) = delete; ///TODO + + static bool Create(const String& dirPath); + static bool Exists(const String& dirPath); + static String GetCurrent(); + static bool Remove(const String& dirPath); + + private: + DIR* m_handle; + dirent64* m_result; + }; +} #endif // NAZARA_DIRECTORYIMPL_HPP diff --git a/src/Nazara/Core/Posix/DynLibImpl.cpp b/src/Nazara/Core/Posix/DynLibImpl.cpp index b3bafebda..dbb8463fa 100644 --- a/src/Nazara/Core/Posix/DynLibImpl.cpp +++ b/src/Nazara/Core/Posix/DynLibImpl.cpp @@ -8,55 +8,58 @@ #include #include -NzDynLibImpl::NzDynLibImpl(NzDynLib* parent) +namespace Nz { - NazaraUnused(parent); -} - -NzDynLibFunc NzDynLibImpl::GetSymbol(const NzString& symbol, NzString* errorMessage) const -{ - /* - Il n'est pas standard de cast un pointeur d'objet vers un pointeur de fonction. - Nous devons donc utiliser des techniques diaboliques venant du malin lui-même.. :D - Au moins ce n'est pas aussi terrible qu'un const_cast - -Lynix - */ - union + DynLibImpl::DynLibImpl(DynLib* parent) { - NzDynLibFunc func; - void* pointer; - } converter; + NazaraUnused(parent); + } - dlerror(); // Clear error flag - - converter.pointer = dlsym(m_handle, symbol.GetConstBuffer()); - if (!converter.pointer) - *errorMessage = dlerror(); - - return converter.func; -} - -bool NzDynLibImpl::Load(const NzString& libraryPath, NzString* errorMessage) -{ - NzString path = libraryPath; - - unsigned int pos = path.FindLast(".so"); - if (pos == NzString::npos || (path.GetLength() > pos+3 && path[pos+3] != '.')) - path += ".so"; - - dlerror(); // Clear error flag - m_handle = dlopen(path.GetConstBuffer(), RTLD_LAZY | RTLD_GLOBAL); - - if (m_handle) - return true; - else + DynLibFunc DynLibImpl::GetSymbol(const String& symbol, String* errorMessage) const { - *errorMessage = dlerror(); - return false; + /* + Il n'est pas standard de cast un pointeur d'objet vers un pointeur de fonction. + Nous devons donc utiliser des techniques diaboliques venant du malin lui-même.. :D + Au moins ce n'est pas aussi terrible qu'un const_cast + -Lynix + */ + union + { + DynLibFunc func; + void* pointer; + } converter; + + dlerror(); // Clear error flag + + converter.pointer = dlsym(m_handle, symbol.GetConstBuffer()); + if (!converter.pointer) + *errorMessage = dlerror(); + + return converter.func; + } + + bool DynLibImpl::Load(const String& libraryPath, String* errorMessage) + { + String path = libraryPath; + + unsigned int pos = path.FindLast(".so"); + if (pos == String::npos || (path.GetLength() > pos+3 && path[pos+3] != '.')) + path += ".so"; + + dlerror(); // Clear error flag + m_handle = dlopen(path.GetConstBuffer(), RTLD_LAZY | RTLD_GLOBAL); + + if (m_handle) + return true; + else + { + *errorMessage = dlerror(); + return false; + } + } + + void DynLibImpl::Unload() + { + dlclose(m_handle); } } - -void NzDynLibImpl::Unload() -{ - dlclose(m_handle); -} diff --git a/src/Nazara/Core/Posix/DynLibImpl.hpp b/src/Nazara/Core/Posix/DynLibImpl.hpp index 5e4cac8d5..1f36fa9e3 100644 --- a/src/Nazara/Core/Posix/DynLibImpl.hpp +++ b/src/Nazara/Core/Posix/DynLibImpl.hpp @@ -8,23 +8,25 @@ #define NAZARA_DYNLIBIMPL_HPP #include -#include #include -class NzString; - -class NzDynLibImpl : NzNonCopyable +namespace Nz { - public: - NzDynLibImpl(NzDynLib* m_parent); - ~NzDynLibImpl() = default; + class String; - NzDynLibFunc GetSymbol(const NzString& symbol, NzString* errorMessage) const; - bool Load(const NzString& libraryPath, NzString* errorMessage); - void Unload(); + class DynLibImpl + { + public: + DynLibImpl(DynLib* m_parent); + ~DynLibImpl() = default; - private: - void* m_handle; -}; + DynLibFunc GetSymbol(const String& symbol, String* errorMessage) const; + bool Load(const String& libraryPath, String* errorMessage); + void Unload(); + + private: + void* m_handle; + }; +} #endif // NAZARA_DYNLIBIMPL_HPP diff --git a/src/Nazara/Core/Posix/FileImpl.cpp b/src/Nazara/Core/Posix/FileImpl.cpp index b33dce80b..9c1469817 100644 --- a/src/Nazara/Core/Posix/FileImpl.cpp +++ b/src/Nazara/Core/Posix/FileImpl.cpp @@ -7,236 +7,239 @@ #include #include -NzFileImpl::NzFileImpl(const NzFile* parent) : -m_endOfFile(false), -m_endOfFileUpdated(true) +namespace Nz { - NazaraUnused(parent); -} - -void NzFileImpl::Close() -{ - close(m_fileDescriptor); -} - -bool NzFileImpl::EndOfFile() const -{ - if (!m_endOfFileUpdated) + FileImpl::FileImpl(const File* parent) : + m_endOfFile(false), + m_endOfFileUpdated(true) { - struct stat64 fileSize; - if (fstat64(m_fileDescriptor, &fileSize) == -1) - fileSize.st_size = 0; - - m_endOfFile = (GetCursorPos() >= static_cast(fileSize.st_size)); - m_endOfFileUpdated = true; + NazaraUnused(parent); } - return m_endOfFile; -} - -void NzFileImpl::Flush() -{ - if (fsync(m_fileDescriptor) == -1) - NazaraError("Unable to flush file: " + NzError::GetLastSystemError()); -} - -nzUInt64 NzFileImpl::GetCursorPos() const -{ - off64_t position = lseek64(m_fileDescriptor, 0, SEEK_CUR); - return static_cast(position); -} - -bool NzFileImpl::Open(const NzString& filePath, unsigned int mode) -{ - int flags; - mode_t permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - - if (mode & nzOpenMode_ReadOnly) - flags = O_RDONLY; - else if (mode & nzOpenMode_ReadWrite) + void FileImpl::Close() { - flags = O_CREAT | O_RDWR; - - if (mode & nzOpenMode_Append) - flags |= O_APPEND; - - if (mode & nzOpenMode_Truncate) - flags |= O_TRUNC; - } - else if (mode & nzOpenMode_WriteOnly) - { - flags = O_CREAT | O_WRONLY; - - if (mode & nzOpenMode_Append) - flags |= O_APPEND; - - if (mode & nzOpenMode_Truncate) - flags |= O_TRUNC; - } - else - return false; - -///TODO: lock -// if ((mode & nzOpenMode_Lock) == 0) -// shareMode |= FILE_SHARE_WRITE; - - m_fileDescriptor = open64(filePath.GetConstBuffer(), flags, permissions); - return m_fileDescriptor != -1; -} - -std::size_t NzFileImpl::Read(void* buffer, std::size_t size) -{ - ssize_t bytes; - if ((bytes = read(m_fileDescriptor, buffer, size)) != -1) - { - m_endOfFile = (static_cast(bytes) != size); - m_endOfFileUpdated = true; - - return static_cast(bytes); - } - else - return 0; -} - -bool NzFileImpl::SetCursorPos(nzCursorPosition pos, nzInt64 offset) -{ - int moveMethod; - switch (pos) - { - case nzCursorPosition_AtBegin: - moveMethod = SEEK_SET; - break; - - case nzCursorPosition_AtCurrent: - moveMethod = SEEK_CUR; - break; - - case nzCursorPosition_AtEnd: - moveMethod = SEEK_END; - break; - - default: - NazaraInternalError("Cursor position not handled (0x" + NzString::Number(pos, 16) + ')'); - return false; + close(m_fileDescriptor); } - m_endOfFileUpdated = false; - - return lseek64(m_fileDescriptor, offset, moveMethod) != -1; -} - -std::size_t NzFileImpl::Write(const void* buffer, std::size_t size) -{ - lockf64(m_fileDescriptor, F_LOCK, size); - ssize_t written = write(m_fileDescriptor, buffer, size); - lockf64(m_fileDescriptor, F_ULOCK, size); - - m_endOfFileUpdated = false; - - return written; -} - -bool NzFileImpl::Copy(const NzString& sourcePath, const NzString& targetPath) -{ - int fd1 = open64(sourcePath.GetConstBuffer(), O_RDONLY); - if (fd1 == -1) + bool FileImpl::EndOfFile() const { - NazaraError("Fail to open input file (" + sourcePath + "): " + NzError::GetLastSystemError()); - return false; - } - - mode_t permissions; // TODO : get permission from first file - int fd2 = open64(targetPath.GetConstBuffer(), O_WRONLY | O_TRUNC, permissions); - if (fd2 == -1) - { - NazaraError("Fail to open output file (" + targetPath + "): " + NzError::GetLastSystemError()); // TODO: more info ? - close(fd1); - return false; - } - - char buffer[512]; - ssize_t bytes; - do - { - bytes = read(fd1,buffer,512); - if (bytes == -1) + if (!m_endOfFileUpdated) { - close(fd1); - close(fd2); - NazaraError("An error occured from copy : " + NzError::GetLastSystemError()); + struct stat64 fileSize; + if (fstat64(m_fileDescriptor, &fileSize) == -1) + fileSize.st_size = 0; + + m_endOfFile = (GetCursorPos() >= static_cast(fileSize.st_size)); + m_endOfFileUpdated = true; + } + + return m_endOfFile; + } + + void FileImpl::Flush() + { + if (fsync(m_fileDescriptor) == -1) + NazaraError("Unable to flush file: " + Error::GetLastSystemError()); + } + + UInt64 FileImpl::GetCursorPos() const + { + off64_t position = lseek64(m_fileDescriptor, 0, SEEK_CUR); + return static_cast(position); + } + + bool FileImpl::Open(const String& filePath, unsigned int mode) + { + int flags; + mode_t permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; + + if (mode & OpenMode_ReadOnly) + flags = O_RDONLY; + else if (mode & OpenMode_ReadWrite) + { + flags = O_CREAT | O_RDWR; + + if (mode & OpenMode_Append) + flags |= O_APPEND; + + if (mode & OpenMode_Truncate) + flags |= O_TRUNC; + } + else if (mode & OpenMode_WriteOnly) + { + flags = O_CREAT | O_WRONLY; + + if (mode & OpenMode_Append) + flags |= O_APPEND; + + if (mode & OpenMode_Truncate) + flags |= O_TRUNC; + } + else + return false; + + ///TODO: lock + // if ((mode & OpenMode_Lock) == 0) + // shareMode |= FILE_SHARE_WRITE; + + m_fileDescriptor = open64(filePath.GetConstBuffer(), flags, permissions); + return m_fileDescriptor != -1; + } + + std::size_t FileImpl::Read(void* buffer, std::size_t size) + { + ssize_t bytes; + if ((bytes = read(m_fileDescriptor, buffer, size)) != -1) + { + m_endOfFile = (static_cast(bytes) != size); + m_endOfFileUpdated = true; + + return static_cast(bytes); + } + else + return 0; + } + + bool FileImpl::SetCursorPos(CursorPosition pos, Int64 offset) + { + int moveMethod; + switch (pos) + { + case CursorPosition_AtBegin: + moveMethod = SEEK_SET; + break; + + case CursorPosition_AtCurrent: + moveMethod = SEEK_CUR; + break; + + case CursorPosition_AtEnd: + moveMethod = SEEK_END; + break; + + default: + NazaraInternalError("Cursor position not handled (0x" + String::Number(pos, 16) + ')'); + return false; + } + + m_endOfFileUpdated = false; + + return lseek64(m_fileDescriptor, offset, moveMethod) != -1; + } + + std::size_t FileImpl::Write(const void* buffer, std::size_t size) + { + lockf64(m_fileDescriptor, F_LOCK, size); + ssize_t written = write(m_fileDescriptor, buffer, size); + lockf64(m_fileDescriptor, F_ULOCK, size); + + m_endOfFileUpdated = false; + + return written; + } + + bool FileImpl::Copy(const String& sourcePath, const String& targetPath) + { + int fd1 = open64(sourcePath.GetConstBuffer(), O_RDONLY); + if (fd1 == -1) + { + NazaraError("Fail to open input file (" + sourcePath + "): " + Error::GetLastSystemError()); return false; } - write(fd2,buffer,bytes); - } - while (bytes == 512); - close(fd1); - close(fd2); - return true; -} + mode_t permissions; // TODO : get permission from first file + int fd2 = open64(targetPath.GetConstBuffer(), O_WRONLY | O_TRUNC, permissions); + if (fd2 == -1) + { + NazaraError("Fail to open output file (" + targetPath + "): " + Error::GetLastSystemError()); // TODO: more info ? + close(fd1); + return false; + } -bool NzFileImpl::Delete(const NzString& filePath) -{ - bool success = unlink(filePath.GetConstBuffer()) != -1; + char buffer[512]; + ssize_t bytes; + do + { + bytes = read(fd1,buffer,512); + if (bytes == -1) + { + close(fd1); + close(fd2); + NazaraError("An error occured from copy : " + Error::GetLastSystemError()); + return false; + } + write(fd2,buffer,bytes); + } + while (bytes == 512); - if (success) + close(fd1); + close(fd2); return true; - else + } + + bool FileImpl::Delete(const String& filePath) { - NazaraError("Failed to delete file (" + filePath + "): " + NzError::GetLastSystemError()); + bool success = unlink(filePath.GetConstBuffer()) != -1; + + if (success) + return true; + else + { + NazaraError("Failed to delete file (" + filePath + "): " + Error::GetLastSystemError()); + return false; + } + } + + bool FileImpl::Exists(const String& filePath) + { + const char* path = filePath.GetConstBuffer(); + if (access(path, F_OK) != -1) + return true; + return false; } -} -bool NzFileImpl::Exists(const NzString& filePath) -{ - const char* path = filePath.GetConstBuffer(); - if (access(path, F_OK) != -1) - return true; - - return false; -} - -time_t NzFileImpl::GetCreationTime(const NzString& filePath) -{ - NazaraWarning("Posix has no creation time information"); - - return 0; -} - -time_t NzFileImpl::GetLastAccessTime(const NzString& filePath) -{ - struct stat64 stats; - stat64(filePath.GetConstBuffer(), &stats); - - return stats.st_atime; -} - -time_t NzFileImpl::GetLastWriteTime(const NzString& filePath) -{ - struct stat64 stats; - stat64(filePath.GetConstBuffer(), &stats); - - return stats.st_mtime; -} - -nzUInt64 NzFileImpl::GetSize(const NzString& filePath) -{ - struct stat64 stats; - stat64(filePath.GetConstBuffer(), &stats); - - return static_cast(stats.st_size); -} - -bool NzFileImpl::Rename(const NzString& sourcePath, const NzString& targetPath) -{ - bool success = std::rename(sourcePath.GetConstBuffer(), targetPath.GetConstBuffer()) != -1; - - if (success) - return true; - else + time_t FileImpl::GetCreationTime(const String& filePath) { - NazaraError("Unable to rename file: " + NzError::GetLastSystemError()); - return false; + NazaraWarning("Posix has no creation time information"); + + return 0; + } + + time_t FileImpl::GetLastAccessTime(const String& filePath) + { + struct stat64 stats; + stat64(filePath.GetConstBuffer(), &stats); + + return stats.st_atime; + } + + time_t FileImpl::GetLastWriteTime(const String& filePath) + { + struct stat64 stats; + stat64(filePath.GetConstBuffer(), &stats); + + return stats.st_mtime; + } + + UInt64 FileImpl::GetSize(const String& filePath) + { + struct stat64 stats; + stat64(filePath.GetConstBuffer(), &stats); + + return static_cast(stats.st_size); + } + + bool FileImpl::Rename(const String& sourcePath, const String& targetPath) + { + bool success = std::rename(sourcePath.GetConstBuffer(), targetPath.GetConstBuffer()) != -1; + + if (success) + return true; + else + { + NazaraError("Unable to rename file: " + Error::GetLastSystemError()); + return false; + } } } diff --git a/src/Nazara/Core/Posix/FileImpl.hpp b/src/Nazara/Core/Posix/FileImpl.hpp index eda3f5400..6531dc70b 100644 --- a/src/Nazara/Core/Posix/FileImpl.hpp +++ b/src/Nazara/Core/Posix/FileImpl.hpp @@ -13,44 +13,51 @@ #include #include -#include #include #include #include #include #include -class NzFile; -class NzString; - -class NzFileImpl : NzNonCopyable +namespace Nz { - public: - NzFileImpl(const NzFile* parent); - ~NzFileImpl() = default; + class File; + class String; - void Close(); - bool EndOfFile() const; - void Flush(); - nzUInt64 GetCursorPos() const; - bool Open(const NzString& filePath, unsigned int mode); - std::size_t Read(void* buffer, std::size_t size); - bool SetCursorPos(nzCursorPosition pos, nzInt64 offset); - std::size_t Write(const void* buffer, std::size_t size); + class FileImpl + { + public: + FileImpl(const File* parent); + FileImpl(const FileImpl&) = delete; + FileImpl(FileImpl&&) = delete; ///TODO + ~FileImpl() = default; - static bool Copy(const NzString& sourcePath, const NzString& targetPath); - static bool Delete(const NzString& filePath); - static bool Exists(const NzString& filePath); - static time_t GetCreationTime(const NzString& filePath); - static time_t GetLastAccessTime(const NzString& filePath); - static time_t GetLastWriteTime(const NzString& filePath); - static nzUInt64 GetSize(const NzString& filePath); - static bool Rename(const NzString& sourcePath, const NzString& targetPath); + void Close(); + bool EndOfFile() const; + void Flush(); + UInt64 GetCursorPos() const; + bool Open(const String& filePath, unsigned int mode); + std::size_t Read(void* buffer, std::size_t size); + bool SetCursorPos(CursorPosition pos, Int64 offset); + std::size_t Write(const void* buffer, std::size_t size); - private: - int m_fileDescriptor; - mutable bool m_endOfFile; - mutable bool m_endOfFileUpdated; -}; + FileImpl& operator=(const FileImpl&) = delete; + FileImpl& operator=(FileImpl&&) = delete; ///TODO + + static bool Copy(const String& sourcePath, const String& targetPath); + static bool Delete(const String& filePath); + static bool Exists(const String& filePath); + static time_t GetCreationTime(const String& filePath); + static time_t GetLastAccessTime(const String& filePath); + static time_t GetLastWriteTime(const String& filePath); + static UInt64 GetSize(const String& filePath); + static bool Rename(const String& sourcePath, const String& targetPath); + + private: + int m_fileDescriptor; + mutable bool m_endOfFile; + mutable bool m_endOfFileUpdated; + }; +} #endif // NAZARA_FILEIMPL_HPP diff --git a/src/Nazara/Core/Posix/HardwareInfoImpl.cpp b/src/Nazara/Core/Posix/HardwareInfoImpl.cpp index 31713defd..0058832a8 100644 --- a/src/Nazara/Core/Posix/HardwareInfoImpl.cpp +++ b/src/Nazara/Core/Posix/HardwareInfoImpl.cpp @@ -6,58 +6,61 @@ #include #include -void NzHardwareInfoImpl::Cpuid(nzUInt32 functionId, nzUInt32 subFunctionId, nzUInt32 registers[4]) +namespace Nz { -#if defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL) - // Source: http://stackoverflow.com/questions/1666093/cpuid-implementations-in-c - asm volatile ("cpuid" // Besoin d'être volatile ? - : "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]) // output - : "a" (functionId), "c" (subFunctionId)); // input -#else - NazaraInternalError("Cpuid has been called although it is not supported"); -#endif -} - -unsigned int NzHardwareInfoImpl::GetProcessorCount() -{ - // Plus simple (et plus portable) que de passer par le CPUID - return sysconf(_SC_NPROCESSORS_CONF); -} - -nzUInt64 NzHardwareInfoImpl::GetTotalMemory() -{ - nzUInt64 pages = sysconf(_SC_PHYS_PAGES); - nzUInt64 page_size = sysconf(_SC_PAGE_SIZE); - - return pages * page_size; -} - -bool NzHardwareInfoImpl::IsCpuidSupported() -{ -#ifdef NAZARA_PLATFORM_x64 - return true; // Toujours supporté sur un processeur 64 bits -#else + void HardwareInfoImpl::Cpuid(UInt32 functionId, UInt32 subFunctionId, UInt32 registers[4]) + { #if defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL) - int supported; - asm volatile (" pushfl\n" - " pop %%eax\n" - " mov %%eax, %%ecx\n" - " xor $0x200000, %%eax\n" - " push %%eax\n" - " popfl\n" - " pushfl\n" - " pop %%eax\n" - " xor %%ecx, %%eax\n" - " mov %%eax, %0\n" - " push %%ecx\n" - " popfl" - : "=m" (supported) // output - : // input - : "eax", "ecx", "memory"); // clobbered register - - return supported != 0; + // Source: http://stackoverflow.com/questions/1666093/cpuid-implementations-in-c + asm volatile ("cpuid" // Besoin d'être volatile ? + : "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]) // output + : "a" (functionId), "c" (subFunctionId)); // input #else - return false; + NazaraInternalError("Cpuid has been called although it is not supported"); #endif -#endif + } + + unsigned int HardwareInfoImpl::GetProcessorCount() + { + // Plus simple (et plus portable) que de passer par le CPUID + return sysconf(_SC_NPROCESSORS_CONF); + } + + UInt64 HardwareInfoImpl::GetTotalMemory() + { + UInt64 pages = sysconf(_SC_PHYS_PAGES); + UInt64 page_size = sysconf(_SC_PAGE_SIZE); + + return pages * page_size; + } + + bool HardwareInfoImpl::IsCpuidSupported() + { + #ifdef NAZARA_PLATFORM_x64 + return true; // Toujours supporté sur un processeur 64 bits + #else + #if defined(NAZARA_COMPILER_CLANG) || defined(NAZARA_COMPILER_GCC) || defined(NAZARA_COMPILER_INTEL) + int supported; + asm volatile (" pushfl\n" + " pop %%eax\n" + " mov %%eax, %%ecx\n" + " xor $0x200000, %%eax\n" + " push %%eax\n" + " popfl\n" + " pushfl\n" + " pop %%eax\n" + " xor %%ecx, %%eax\n" + " mov %%eax, %0\n" + " push %%ecx\n" + " popfl" + : "=m" (supported) // output + : // input + : "eax", "ecx", "memory"); // clobbered register + + return supported != 0; + #else + return false; + #endif + #endif + } } diff --git a/src/Nazara/Core/Posix/HardwareInfoImpl.hpp b/src/Nazara/Core/Posix/HardwareInfoImpl.hpp index ef05a7aeb..671802c52 100644 --- a/src/Nazara/Core/Posix/HardwareInfoImpl.hpp +++ b/src/Nazara/Core/Posix/HardwareInfoImpl.hpp @@ -10,13 +10,16 @@ #include #include -class NzHardwareInfoImpl +namespace Nz { - public: - static void Cpuid(nzUInt32 functionId, nzUInt32 subFunctionId, nzUInt32 registers[4]); - static unsigned int GetProcessorCount(); - static nzUInt64 GetTotalMemory(); - static bool IsCpuidSupported(); -}; + class HardwareInfoImpl + { + public: + static void Cpuid(UInt32 functionId, UInt32 subFunctionId, UInt32 registers[4]); + static unsigned int GetProcessorCount(); + static UInt64 GetTotalMemory(); + static bool IsCpuidSupported(); + }; +} #endif // NAZARA_HARDWAREINFOIMPL_POSIX_HPP diff --git a/src/Nazara/Core/Posix/MutexImpl.cpp b/src/Nazara/Core/Posix/MutexImpl.cpp index c53ad61ff..a19720000 100644 --- a/src/Nazara/Core/Posix/MutexImpl.cpp +++ b/src/Nazara/Core/Posix/MutexImpl.cpp @@ -5,31 +5,34 @@ #include #include -NzMutexImpl::NzMutexImpl() +namespace Nz { - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + MutexImpl::MutexImpl() + { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&m_handle, &attr); -} + pthread_mutex_init(&m_handle, &attr); + } -NzMutexImpl::~NzMutexImpl() -{ - pthread_mutex_destroy(&m_handle); -} + MutexImpl::~MutexImpl() + { + pthread_mutex_destroy(&m_handle); + } -void NzMutexImpl::Lock() -{ - pthread_mutex_lock(&m_handle); -} + void MutexImpl::Lock() + { + pthread_mutex_lock(&m_handle); + } -bool NzMutexImpl::TryLock() -{ - return pthread_mutex_trylock(&m_handle) == 0; -} + bool MutexImpl::TryLock() + { + return pthread_mutex_trylock(&m_handle) == 0; + } -void NzMutexImpl::Unlock() -{ - pthread_mutex_unlock(&m_handle); + void MutexImpl::Unlock() + { + pthread_mutex_unlock(&m_handle); + } } diff --git a/src/Nazara/Core/Posix/MutexImpl.hpp b/src/Nazara/Core/Posix/MutexImpl.hpp index ff1d0455f..5437ce043 100644 --- a/src/Nazara/Core/Posix/MutexImpl.hpp +++ b/src/Nazara/Core/Posix/MutexImpl.hpp @@ -9,20 +9,23 @@ #include -class NzMutexImpl +namespace Nz { - friend class NzConditionVariableImpl; + class MutexImpl + { + friend class ConditionVariableImpl; - public: - NzMutexImpl(); - ~NzMutexImpl(); + public: + MutexImpl(); + ~MutexImpl(); - void Lock(); - bool TryLock(); - void Unlock(); + void Lock(); + bool TryLock(); + void Unlock(); - private: - pthread_mutex_t m_handle; -}; + private: + pthread_mutex_t m_handle; + }; +} #endif // NAZARA_MUTEXIMPL_HPP diff --git a/src/Nazara/Core/Posix/SemaphoreImpl.cpp b/src/Nazara/Core/Posix/SemaphoreImpl.cpp index baa70f10a..4342cf1c6 100644 --- a/src/Nazara/Core/Posix/SemaphoreImpl.cpp +++ b/src/Nazara/Core/Posix/SemaphoreImpl.cpp @@ -9,63 +9,66 @@ #include #include -NzSemaphoreImpl::NzSemaphoreImpl(unsigned int count) +namespace Nz { - if(sem_init(&m_semaphore, 0, count) != 0) - NazaraError("Failed to create semaphore: " + NzError::GetLastSystemError()); -} - -NzSemaphoreImpl::~NzSemaphoreImpl() -{ - sem_destroy(&m_semaphore); -} - -unsigned int NzSemaphoreImpl::GetCount() const -{ - int count=0; - sem_getvalue(const_cast(&m_semaphore), &count); - return static_cast(count); -} - -void NzSemaphoreImpl::Post() -{ - #if NAZARA_CORE_SAFE - if (sem_post(&m_semaphore)==-1) - NazaraError("Failed to release semaphore: " + NzError::GetLastSystemError()); - #else - sem_post(&m_semaphore); - #endif -} - -void NzSemaphoreImpl::Wait() -{ - #if NAZARA_CORE_SAFE - if (sem_wait(&m_semaphore) == -1 ) - NazaraError("Failed to wait for semaphore: " + NzError::GetLastSystemError()); - #else - sem_wait(&m_semaphore); - #endif -} - -bool NzSemaphoreImpl::Wait(nzUInt32 timeout) -{ - timeval tv; - gettimeofday(&tv, nullptr); - - timespec ti; - ti.tv_nsec = (tv.tv_usec + (timeout % 1000)) * 1000000; - ti.tv_sec = tv.tv_sec + (timeout / 1000) + (ti.tv_nsec / 1000000000); - ti.tv_nsec %= 1000000000; - - #if NAZARA_CORE_SAFE - if (sem_timedwait(&m_semaphore, &ti) != 0) + SemaphoreImpl::SemaphoreImpl(unsigned int count) { - NazaraError("Failed to wait for semaphore: " + NzError::GetLastSystemError()); - return false; + if(sem_init(&m_semaphore, 0, count) != 0) + NazaraError("Failed to create semaphore: " + Error::GetLastSystemError()); } - return true; - #else - return sem_timedwait(&m_semaphore, &ti) != 0; - #endif + SemaphoreImpl::~SemaphoreImpl() + { + sem_destroy(&m_semaphore); + } + + unsigned int SemaphoreImpl::GetCount() const + { + int count=0; + sem_getvalue(const_cast(&m_semaphore), &count); + return static_cast(count); + } + + void SemaphoreImpl::Post() + { + #if NAZARA_CORE_SAFE + if (sem_post(&m_semaphore)==-1) + NazaraError("Failed to release semaphore: " + Error::GetLastSystemError()); + #else + sem_post(&m_semaphore); + #endif + } + + void SemaphoreImpl::Wait() + { + #if NAZARA_CORE_SAFE + if (sem_wait(&m_semaphore) == -1 ) + NazaraError("Failed to wait for semaphore: " + Error::GetLastSystemError()); + #else + sem_wait(&m_semaphore); + #endif + } + + bool SemaphoreImpl::Wait(UInt32 timeout) + { + timeval tv; + gettimeofday(&tv, nullptr); + + timespec ti; + ti.tv_nsec = (tv.tv_usec + (timeout % 1000)) * 1000000; + ti.tv_sec = tv.tv_sec + (timeout / 1000) + (ti.tv_nsec / 1000000000); + ti.tv_nsec %= 1000000000; + + #if NAZARA_CORE_SAFE + if (sem_timedwait(&m_semaphore, &ti) != 0) + { + NazaraError("Failed to wait for semaphore: " + Error::GetLastSystemError()); + return false; + } + + return true; + #else + return sem_timedwait(&m_semaphore, &ti) != 0; + #endif + } } diff --git a/src/Nazara/Core/Posix/SemaphoreImpl.hpp b/src/Nazara/Core/Posix/SemaphoreImpl.hpp index 1708d3be4..c1dedc6b9 100644 --- a/src/Nazara/Core/Posix/SemaphoreImpl.hpp +++ b/src/Nazara/Core/Posix/SemaphoreImpl.hpp @@ -10,19 +10,22 @@ #include #include -class NzSemaphoreImpl +namespace Nz { - public: - NzSemaphoreImpl(unsigned int count); - ~NzSemaphoreImpl(); + class SemaphoreImpl + { + public: + SemaphoreImpl(unsigned int count); + ~SemaphoreImpl(); - unsigned int GetCount() const; - void Post(); - void Wait(); - bool Wait(nzUInt32 timeout); + unsigned int GetCount() const; + void Post(); + void Wait(); + bool Wait(UInt32 timeout); - private: - sem_t m_semaphore; -}; + private: + sem_t m_semaphore; + }; +} #endif // NAZARA_SEMAPHOREIMPL_HPP diff --git a/src/Nazara/Core/Posix/TaskSchedulerImpl.cpp b/src/Nazara/Core/Posix/TaskSchedulerImpl.cpp index 9b0acd270..b04fdcfd9 100644 --- a/src/Nazara/Core/Posix/TaskSchedulerImpl.cpp +++ b/src/Nazara/Core/Posix/TaskSchedulerImpl.cpp @@ -7,186 +7,189 @@ #include #include -bool NzTaskSchedulerImpl::Initialize(unsigned int workerCount) +namespace Nz { - if (IsInitialized()) - return true; // Déjà initialisé - - #if NAZARA_CORE_SAFE - if (workerCount == 0) + bool TaskSchedulerImpl::Initialize(unsigned int workerCount) { - NazaraError("Invalid worker count ! (0)"); - return false; - } - #endif + if (IsInitialized()) + return true; // Déjà initialisé - s_workerCount = workerCount; - s_isDone = false; - s_isWaiting = false; - s_shouldFinish = false; - - s_threads.reset(new pthread_t[workerCount]); - - // On initialise les conditions variables, mutex et barrière. - pthread_cond_init(&s_cvEmpty, nullptr); - pthread_cond_init(&s_cvNotEmpty, nullptr); - pthread_mutex_init(&s_mutexQueue, nullptr); - pthread_barrier_init(&s_barrier, nullptr, workerCount + 1); - - for (unsigned int i = 0; i < s_workerCount; ++i) - { - // Le thread va se lancer, attendre que tous se créent et attendre d'être réveillé. - pthread_create(&s_threads[i], nullptr, WorkerProc, nullptr); - } - - pthread_barrier_wait(&s_barrier); // On attend que les enfants soient bien créés. - - return true; -} - -bool NzTaskSchedulerImpl::IsInitialized() -{ - return s_workerCount > 0; -} - -void NzTaskSchedulerImpl::Run(NzFunctor** tasks, unsigned int count) -{ - // On s'assure que des tâches ne sont pas déjà en cours - Wait(); - - pthread_mutex_lock(&s_mutexQueue); - s_isDone = false; - - while (count--) - s_tasks.push(*tasks++); - - pthread_cond_signal(&s_cvNotEmpty); - pthread_mutex_unlock(&s_mutexQueue); -} - -void NzTaskSchedulerImpl::Uninitialize() -{ - #ifdef NAZARA_CORE_SAFE - if (s_workerCount == 0) - { - NazaraError("Task scheduler is not initialized"); - return; - } - #endif - - // On réveille les threads pour qu'ils sortent de la boucle et terminent. - pthread_mutex_lock(&s_mutexQueue); - // On commence par vider la queue et demander qu'ils s'arrêtent. - std::queue emptyQueue; - std::swap(s_tasks, emptyQueue); - s_shouldFinish = true; - pthread_cond_broadcast(&s_cvNotEmpty); - pthread_mutex_unlock(&s_mutexQueue); - - // On attend que chaque thread se termine - for (unsigned int i = 0; i < s_workerCount; ++i) - pthread_join(s_threads[i], nullptr); - - // Et on libère les ressources - pthread_barrier_destroy(&s_barrier); - pthread_cond_destroy(&s_cvEmpty); - pthread_cond_destroy(&s_cvNotEmpty); - pthread_mutex_destroy(&s_mutexQueue); - - s_workerCount = 0; -} - -void NzTaskSchedulerImpl::WaitForTasks() -{ - #ifdef NAZARA_CORE_SAFE - if (s_workerCount == 0) - { - NazaraError("Task scheduler is not initialized"); - return; - } - #endif - - Wait(); -} - -NzFunctor* NzTaskSchedulerImpl::PopQueue() -{ - NzFunctor* task = nullptr; - - pthread_mutex_lock(&s_mutexQueue); - - if (!s_tasks.empty()) - { - task = s_tasks.front(); - s_tasks.pop(); - } - - pthread_mutex_unlock(&s_mutexQueue); - - return task; -} - -void NzTaskSchedulerImpl::Wait() -{ - if (s_isDone) - return; - - pthread_mutex_lock(&s_mutexQueue); - s_isWaiting = true; - pthread_cond_broadcast(&s_cvNotEmpty); - pthread_cond_wait(&s_cvEmpty, &s_mutexQueue); - pthread_mutex_unlock(&s_mutexQueue); - - s_isDone = true; -} - -void* NzTaskSchedulerImpl::WorkerProc(void* /*userdata*/) -{ - // On s'assure que tous les threads soient correctement lancés. - pthread_barrier_wait(&s_barrier); - - // On quitte s'il doit terminer. - while (!s_shouldFinish) - { - NzFunctor* task = PopQueue(); - - if (task) + #if NAZARA_CORE_SAFE + if (workerCount == 0) { - // On exécute la tâche avant de la supprimer - task->Run(); - delete task; + NazaraError("Invalid worker count ! (0)"); + return false; } - else + #endif + + s_workerCount = workerCount; + s_isDone = false; + s_isWaiting = false; + s_shouldFinish = false; + + s_threads.reset(new pthread_t[workerCount]); + + // On initialise les conditions variables, mutex et barrière. + pthread_cond_init(&s_cvEmpty, nullptr); + pthread_cond_init(&s_cvNotEmpty, nullptr); + pthread_mutex_init(&s_mutexQueue, nullptr); + pthread_barrier_init(&s_barrier, nullptr, workerCount + 1); + + for (unsigned int i = 0; i < s_workerCount; ++i) { - pthread_mutex_lock(&s_mutexQueue); - if (s_tasks.empty()) - s_isDone = true; + // Le thread va se lancer, attendre que tous se créent et attendre d'être réveillé. + pthread_create(&s_threads[i], nullptr, WorkerProc, nullptr); + } - while (!(!s_tasks.empty() || s_isWaiting || s_shouldFinish)) - pthread_cond_wait(&s_cvNotEmpty, &s_mutexQueue); + pthread_barrier_wait(&s_barrier); // On attend que les enfants soient bien créés. - if (s_tasks.empty() && s_isWaiting) + return true; + } + + bool TaskSchedulerImpl::IsInitialized() + { + return s_workerCount > 0; + } + + void TaskSchedulerImpl::Run(Functor** tasks, unsigned int count) + { + // On s'assure que des tâches ne sont pas déjà en cours + Wait(); + + pthread_mutex_lock(&s_mutexQueue); + s_isDone = false; + + while (count--) + s_tasks.push(*tasks++); + + pthread_cond_signal(&s_cvNotEmpty); + pthread_mutex_unlock(&s_mutexQueue); + } + + void TaskSchedulerImpl::Uninitialize() + { + #ifdef NAZARA_CORE_SAFE + if (s_workerCount == 0) + { + NazaraError("Task scheduler is not initialized"); + return; + } + #endif + + // On réveille les threads pour qu'ils sortent de la boucle et terminent. + pthread_mutex_lock(&s_mutexQueue); + // On commence par vider la queue et demander qu'ils s'arrêtent. + std::queue emptyQueue; + std::swap(s_tasks, emptyQueue); + s_shouldFinish = true; + pthread_cond_broadcast(&s_cvNotEmpty); + pthread_mutex_unlock(&s_mutexQueue); + + // On attend que chaque thread se termine + for (unsigned int i = 0; i < s_workerCount; ++i) + pthread_join(s_threads[i], nullptr); + + // Et on libère les ressources + pthread_barrier_destroy(&s_barrier); + pthread_cond_destroy(&s_cvEmpty); + pthread_cond_destroy(&s_cvNotEmpty); + pthread_mutex_destroy(&s_mutexQueue); + + s_workerCount = 0; + } + + void TaskSchedulerImpl::WaitForTasks() + { + #ifdef NAZARA_CORE_SAFE + if (s_workerCount == 0) + { + NazaraError("Task scheduler is not initialized"); + return; + } + #endif + + Wait(); + } + + Functor* TaskSchedulerImpl::PopQueue() + { + Functor* task = nullptr; + + pthread_mutex_lock(&s_mutexQueue); + + if (!s_tasks.empty()) + { + task = s_tasks.front(); + s_tasks.pop(); + } + + pthread_mutex_unlock(&s_mutexQueue); + + return task; + } + + void TaskSchedulerImpl::Wait() + { + if (s_isDone) + return; + + pthread_mutex_lock(&s_mutexQueue); + s_isWaiting = true; + pthread_cond_broadcast(&s_cvNotEmpty); + pthread_cond_wait(&s_cvEmpty, &s_mutexQueue); + pthread_mutex_unlock(&s_mutexQueue); + + s_isDone = true; + } + + void* TaskSchedulerImpl::WorkerProc(void* /*userdata*/) + { + // On s'assure que tous les threads soient correctement lancés. + pthread_barrier_wait(&s_barrier); + + // On quitte s'il doit terminer. + while (!s_shouldFinish) + { + Functor* task = PopQueue(); + + if (task) { - // On prévient le thread qui attend que les tâches soient effectuées. - s_isWaiting = false; - pthread_cond_signal(&s_cvEmpty); + // On exécute la tâche avant de la supprimer + task->Run(); + delete task; } + else + { + pthread_mutex_lock(&s_mutexQueue); + if (s_tasks.empty()) + s_isDone = true; - pthread_mutex_unlock(&s_mutexQueue); + while (!(!s_tasks.empty() || s_isWaiting || s_shouldFinish)) + pthread_cond_wait(&s_cvNotEmpty, &s_mutexQueue); + + if (s_tasks.empty() && s_isWaiting) + { + // On prévient le thread qui attend que les tâches soient effectuées. + s_isWaiting = false; + pthread_cond_signal(&s_cvEmpty); + } + + pthread_mutex_unlock(&s_mutexQueue); + } } + + return nullptr; } - return nullptr; + std::queue TaskSchedulerImpl::s_tasks; + std::unique_ptr TaskSchedulerImpl::s_threads; + std::atomic TaskSchedulerImpl::s_isDone; + std::atomic TaskSchedulerImpl::s_isWaiting; + std::atomic TaskSchedulerImpl::s_shouldFinish; + unsigned int TaskSchedulerImpl::s_workerCount; + + pthread_mutex_t TaskSchedulerImpl::s_mutexQueue; + pthread_cond_t TaskSchedulerImpl::s_cvEmpty; + pthread_cond_t TaskSchedulerImpl::s_cvNotEmpty; + pthread_barrier_t TaskSchedulerImpl::s_barrier; } - -std::queue NzTaskSchedulerImpl::s_tasks; -std::unique_ptr NzTaskSchedulerImpl::s_threads; -std::atomic NzTaskSchedulerImpl::s_isDone; -std::atomic NzTaskSchedulerImpl::s_isWaiting; -std::atomic NzTaskSchedulerImpl::s_shouldFinish; -unsigned int NzTaskSchedulerImpl::s_workerCount; - -pthread_mutex_t NzTaskSchedulerImpl::s_mutexQueue; -pthread_cond_t NzTaskSchedulerImpl::s_cvEmpty; -pthread_cond_t NzTaskSchedulerImpl::s_cvNotEmpty; -pthread_barrier_t NzTaskSchedulerImpl::s_barrier; diff --git a/src/Nazara/Core/Posix/TaskSchedulerImpl.hpp b/src/Nazara/Core/Posix/TaskSchedulerImpl.hpp index 632e65370..e132e4686 100644 --- a/src/Nazara/Core/Posix/TaskSchedulerImpl.hpp +++ b/src/Nazara/Core/Posix/TaskSchedulerImpl.hpp @@ -14,34 +14,37 @@ #include #include -class NzTaskSchedulerImpl +namespace Nz { - public: - NzTaskSchedulerImpl() = delete; - ~NzTaskSchedulerImpl() = delete; + class TaskSchedulerImpl + { + public: + TaskSchedulerImpl() = delete; + ~TaskSchedulerImpl() = delete; - static bool Initialize(unsigned int workerCount); - static bool IsInitialized(); - static void Run(NzFunctor** tasks, unsigned int count); - static void Uninitialize(); - static void WaitForTasks(); + static bool Initialize(unsigned int workerCount); + static bool IsInitialized(); + static void Run(Functor** tasks, unsigned int count); + static void Uninitialize(); + static void WaitForTasks(); - private: - static NzFunctor* PopQueue(); - static void Wait(); - static void* WorkerProc(void* userdata); + private: + static Functor* PopQueue(); + static void Wait(); + static void* WorkerProc(void* userdata); - static std::queue s_tasks; - static std::unique_ptr s_threads; - static std::atomic s_isDone; - static std::atomic s_isWaiting; - static std::atomic s_shouldFinish; - static unsigned int s_workerCount; + static std::queue s_tasks; + static std::unique_ptr s_threads; + static std::atomic s_isDone; + static std::atomic s_isWaiting; + static std::atomic s_shouldFinish; + static unsigned int s_workerCount; - static pthread_mutex_t s_mutexQueue; - static pthread_cond_t s_cvEmpty; - static pthread_cond_t s_cvNotEmpty; - static pthread_barrier_t s_barrier; -}; + static pthread_mutex_t s_mutexQueue; + static pthread_cond_t s_cvEmpty; + static pthread_cond_t s_cvNotEmpty; + static pthread_barrier_t s_barrier; + }; +} #endif // NAZARA_TASKSCHEDULERIMPL_HPP diff --git a/src/Nazara/Core/Posix/ThreadImpl.cpp b/src/Nazara/Core/Posix/ThreadImpl.cpp index 77099e3c0..c16424328 100644 --- a/src/Nazara/Core/Posix/ThreadImpl.cpp +++ b/src/Nazara/Core/Posix/ThreadImpl.cpp @@ -9,64 +9,67 @@ #include #include -NzThreadImpl::NzThreadImpl(NzFunctor* functor) +namespace Nz { - int error = pthread_create(&m_handle, nullptr, &NzThreadImpl::ThreadProc, functor); - if (error != 0) - NazaraInternalError("Failed to create thread: " + NzError::GetLastSystemError()); -} - -void NzThreadImpl::Detach() -{ - pthread_detach(m_handle); -} - -void NzThreadImpl::Join() -{ - pthread_join(m_handle, nullptr); -} - -void* NzThreadImpl::ThreadProc(void* userdata) -{ - NzFunctor* func = static_cast(userdata); - func->Run(); - delete func; - - return nullptr; -} - -void NzThreadImpl::Sleep(nzUInt32 time) -{ - // code from SFML2 Unix SleepImpl.cpp source https://github.com/LaurentGomila/SFML/blob/master/src/SFML/System/Unix/SleepImpl.cpp - - // usleep is not reliable enough (it might block the - // whole process instead of just the current thread) - // so we must use pthread_cond_timedwait instead - - // this implementation is inspired from Qt - - // get the current time - timeval tv; - gettimeofday(&tv, nullptr); - - // construct the time limit (current time + time to wait) - timespec ti; - ti.tv_nsec = (tv.tv_usec + (time % 1000)) * 1000; - ti.tv_sec = tv.tv_sec + (time / 1000) + (ti.tv_nsec / 1000000000); - ti.tv_nsec %= 1000000000; - - // create a mutex and thread condition - pthread_mutex_t mutex; - pthread_mutex_init(&mutex, nullptr); - pthread_cond_t condition; - pthread_cond_init(&condition, nullptr); - - // wait... - pthread_mutex_lock(&mutex); - pthread_cond_timedwait(&condition, &mutex, &ti); - pthread_mutex_unlock(&mutex); - - // destroy the mutex and condition - pthread_cond_destroy(&condition); - pthread_mutex_destroy(&mutex); + ThreadImpl::ThreadImpl(Functor* functor) + { + int error = pthread_create(&m_handle, nullptr, &ThreadImpl::ThreadProc, functor); + if (error != 0) + NazaraInternalError("Failed to create thread: " + Error::GetLastSystemError()); + } + + void ThreadImpl::Detach() + { + pthread_detach(m_handle); + } + + void ThreadImpl::Join() + { + pthread_join(m_handle, nullptr); + } + + void* ThreadImpl::ThreadProc(void* userdata) + { + Functor* func = static_cast(userdata); + func->Run(); + delete func; + + return nullptr; + } + + void ThreadImpl::Sleep(UInt32 time) + { + // code from SFML2 Unix SleepImpl.cpp source https://github.com/LaurentGomila/SFML/blob/master/src/SFML/System/Unix/SleepImpl.cpp + + // usleep is not reliable enough (it might block the + // whole process instead of just the current thread) + // so we must use pthread_cond_timedwait instead + + // this implementation is inspired from Qt + + // get the current time + timeval tv; + gettimeofday(&tv, nullptr); + + // construct the time limit (current time + time to wait) + timespec ti; + ti.tv_nsec = (tv.tv_usec + (time % 1000)) * 1000; + ti.tv_sec = tv.tv_sec + (time / 1000) + (ti.tv_nsec / 1000000000); + ti.tv_nsec %= 1000000000; + + // create a mutex and thread condition + pthread_mutex_t mutex; + pthread_mutex_init(&mutex, nullptr); + pthread_cond_t condition; + pthread_cond_init(&condition, nullptr); + + // wait... + pthread_mutex_lock(&mutex); + pthread_cond_timedwait(&condition, &mutex, &ti); + pthread_mutex_unlock(&mutex); + + // destroy the mutex and condition + pthread_cond_destroy(&condition); + pthread_mutex_destroy(&mutex); + } } diff --git a/src/Nazara/Core/Posix/ThreadImpl.hpp b/src/Nazara/Core/Posix/ThreadImpl.hpp index f1674d902..1ed6f3c8a 100644 --- a/src/Nazara/Core/Posix/ThreadImpl.hpp +++ b/src/Nazara/Core/Posix/ThreadImpl.hpp @@ -10,22 +10,25 @@ #include #include -struct NzFunctor; - -class NzThreadImpl +namespace Nz { - public: - NzThreadImpl(NzFunctor* threadFunc); + struct Functor; - void Detach(); - void Join(); + class ThreadImpl + { + public: + ThreadImpl(Functor* threadFunc); - static void Sleep(nzUInt32 time); + void Detach(); + void Join(); - private: - static void* ThreadProc(void* userdata); + static void Sleep(UInt32 time); - pthread_t m_handle; -}; + private: + static void* ThreadProc(void* userdata); + + pthread_t m_handle; + }; +} #endif // NAZARA_THREADIMPL_HPP diff --git a/src/Nazara/Graphics/Debug/NewOverload.cpp b/src/Nazara/Graphics/Debug/NewOverload.cpp index 3cd2de7dc..6c5b5c8f0 100644 --- a/src/Nazara/Graphics/Debug/NewOverload.cpp +++ b/src/Nazara/Graphics/Debug/NewOverload.cpp @@ -10,22 +10,22 @@ void* operator new(std::size_t size) { - return NzMemoryManager::Allocate(size, false); + return Nz::MemoryManager::Allocate(size, false); } void* operator new[](std::size_t size) { - return NzMemoryManager::Allocate(size, true); + return Nz::MemoryManager::Allocate(size, true); } void operator delete(void* pointer) noexcept { - NzMemoryManager::Free(pointer, false); + Nz::MemoryManager::Free(pointer, false); } void operator delete[](void* pointer) noexcept { - NzMemoryManager::Free(pointer, true); + Nz::MemoryManager::Free(pointer, true); } #endif // NAZARA_GRAPHICS_MANAGE_MEMORY diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 75768a3fa..6eeb41575 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -689,7 +689,7 @@ namespace Nz // On envoie les lumières directionnelles s'il y a (Les mêmes pour tous) if (shaderUniforms->hasLightUniforms) { - lightCount = std::min(m_renderQueue.directionalLights.size(), NazaraSuffixMacro(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS, U)); + lightCount = std::min(m_renderQueue.directionalLights.size(), static_cast(NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS)); for (unsigned int i = 0; i < lightCount; ++i) SendLightUniforms(shader, shaderUniforms->lightUniforms, i, shaderUniforms->lightOffset * i); diff --git a/src/Nazara/Lua/Debug/NewOverload.cpp b/src/Nazara/Lua/Debug/NewOverload.cpp index 2f0f42402..e7cf94bd6 100644 --- a/src/Nazara/Lua/Debug/NewOverload.cpp +++ b/src/Nazara/Lua/Debug/NewOverload.cpp @@ -10,22 +10,22 @@ void* operator new(std::size_t size) { - return NzMemoryManager::Allocate(size, false); + return Nz::MemoryManager::Allocate(size, false); } void* operator new[](std::size_t size) { - return NzMemoryManager::Allocate(size, true); + return Nz::MemoryManager::Allocate(size, true); } void operator delete(void* pointer) noexcept { - NzMemoryManager::Free(pointer, false); + Nz::MemoryManager::Free(pointer, false); } void operator delete[](void* pointer) noexcept { - NzMemoryManager::Free(pointer, true); + Nz::MemoryManager::Free(pointer, true); } #endif // NAZARA_LUA_MANAGE_MEMORY diff --git a/src/Nazara/Noise/Debug/NewOverload.cpp b/src/Nazara/Noise/Debug/NewOverload.cpp index a8b96c450..1e2da7321 100644 --- a/src/Nazara/Noise/Debug/NewOverload.cpp +++ b/src/Nazara/Noise/Debug/NewOverload.cpp @@ -10,22 +10,22 @@ void* operator new(std::size_t size) { - return NzMemoryManager::Allocate(size, false); + return Nz::MemoryManager::Allocate(size, false); } void* operator new[](std::size_t size) { - return NzMemoryManager::Allocate(size, true); + return Nz::MemoryManager::Allocate(size, true); } void operator delete(void* pointer) noexcept { - NzMemoryManager::Free(pointer, false); + Nz::MemoryManager::Free(pointer, false); } void operator delete[](void* pointer) noexcept { - NzMemoryManager::Free(pointer, true); + Nz::MemoryManager::Free(pointer, true); } #endif // NAZARA_NOISE_MANAGE_MEMORY diff --git a/src/Nazara/Physics/Debug/NewOverload.cpp b/src/Nazara/Physics/Debug/NewOverload.cpp index 4e991cb2c..b7ca2c243 100644 --- a/src/Nazara/Physics/Debug/NewOverload.cpp +++ b/src/Nazara/Physics/Debug/NewOverload.cpp @@ -10,22 +10,22 @@ void* operator new(std::size_t size) { - return NzMemoryManager::Allocate(size, false); + return Nz::MemoryManager::Allocate(size, false); } void* operator new[](std::size_t size) { - return NzMemoryManager::Allocate(size, true); + return Nz::MemoryManager::Allocate(size, true); } void operator delete(void* pointer) noexcept { - NzMemoryManager::Free(pointer, false); + Nz::MemoryManager::Free(pointer, false); } void operator delete[](void* pointer) noexcept { - NzMemoryManager::Free(pointer, true); + Nz::MemoryManager::Free(pointer, true); } #endif // NAZARA_PHYSICS_MANAGE_MEMORY diff --git a/src/Nazara/Renderer/Context.cpp b/src/Nazara/Renderer/Context.cpp index ada25df91..69919d094 100644 --- a/src/Nazara/Renderer/Context.cpp +++ b/src/Nazara/Renderer/Context.cpp @@ -14,7 +14,7 @@ #if defined(NAZARA_PLATFORM_WINDOWS) #include -#elif defined(NAZARA_PLATFORM_LINUX) +#elif defined(NAZARA_PLATFORM_GLX) #include #define CALLBACK #else diff --git a/src/Nazara/Renderer/Debug/NewOverload.cpp b/src/Nazara/Renderer/Debug/NewOverload.cpp index 72563a400..6ef952271 100644 --- a/src/Nazara/Renderer/Debug/NewOverload.cpp +++ b/src/Nazara/Renderer/Debug/NewOverload.cpp @@ -10,22 +10,22 @@ void* operator new(std::size_t size) { - return NzMemoryManager::Allocate(size, false); + return Nz::MemoryManager::Allocate(size, false); } void* operator new[](std::size_t size) { - return NzMemoryManager::Allocate(size, true); + return Nz::MemoryManager::Allocate(size, true); } void operator delete(void* pointer) noexcept { - NzMemoryManager::Free(pointer, false); + Nz::MemoryManager::Free(pointer, false); } void operator delete[](void* pointer) noexcept { - NzMemoryManager::Free(pointer, true); + Nz::MemoryManager::Free(pointer, true); } #endif // NAZARA_RENDERER_MANAGE_MEMORY diff --git a/src/Nazara/Renderer/GLX/ContextImpl.cpp b/src/Nazara/Renderer/GLX/ContextImpl.cpp index 967305d7d..8bff9793a 100644 --- a/src/Nazara/Renderer/GLX/ContextImpl.cpp +++ b/src/Nazara/Renderer/GLX/ContextImpl.cpp @@ -12,286 +12,289 @@ using namespace GLX; -namespace +namespace Nz { - Display* m_display; - int m_sharedDisplay = 0; - - bool ctxErrorOccurred = false; - int ctxErrorHandler( Display* /*dpy*/, XErrorEvent* /*ev*/ ) + namespace { - ctxErrorOccurred = true; - return 0; + Display* m_display; + int m_sharedDisplay = 0; + + bool ctxErrorOccurred = false; + int ctxErrorHandler( Display* /*dpy*/, XErrorEvent* /*ev*/ ) + { + ctxErrorOccurred = true; + return 0; + } } -} -NzContextImpl::NzContextImpl() : -m_colormap(0), -m_context(0), -m_window(0), -m_ownsWindow(false) -{ - if (m_sharedDisplay == 0) - m_display = XOpenDisplay(nullptr); - - ++m_sharedDisplay; -} - -NzContextImpl::~NzContextImpl() -{ - Destroy(); - - if (--m_sharedDisplay == 0) + ContextImpl::ContextImpl() : + m_colormap(0), + m_context(0), + m_window(0), + m_ownsWindow(false) { - XCloseDisplay(m_display); - m_display = nullptr; + if (m_sharedDisplay == 0) + m_display = XOpenDisplay(nullptr); + + ++m_sharedDisplay; } -} -bool NzContextImpl::Activate() -{ - return glXMakeCurrent(m_display, m_window, m_context) == true; -} - -bool NzContextImpl::Create(NzContextParameters& parameters) -{ - // En cas d'exception, la ressource sera quand même libérée - NzCallOnExit onExit([this] () + ContextImpl::~ContextImpl() { Destroy(); - }); - // Get a matching FB config - static int visual_attribs[] = - { - GLX_X_RENDERABLE, True, - GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, - GLX_BUFFER_SIZE, parameters.bitsPerPixel, - GLX_ALPHA_SIZE, (parameters.bitsPerPixel == 32) ? 8 : 0, - GLX_DEPTH_SIZE, parameters.depthBits, - GLX_STENCIL_SIZE, parameters.stencilBits, - GLX_DOUBLEBUFFER, True, - GLX_SAMPLE_BUFFERS, (parameters.antialiasingLevel > 0) ? True : False, - GLX_SAMPLES, parameters.antialiasingLevel, - None - }; - - int glx_major = 0; - int glx_minor = 0; - // FBConfigs were added in GLX version 1.3. - if (!glXQueryVersion(m_display, &glx_major, &glx_minor) || ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) - { - NazaraError("Invalid GLX version, version > 1.3 is required."); - return false; - } - - int fbcount; - GLXFBConfig* fbc = glXChooseFBConfig(m_display, XDefaultScreen(m_display), visual_attribs, &fbcount); - if (!fbc) - { - NazaraError("Failed to retrieve a framebuffer config"); - return false; - } - - // Pick the FB config/visual with the most samples per pixel - int best_fbc = -1; - int worst_fbc = -1; - int best_num_samp = -1; - int worst_num_samp = 999; - - for (int i = 0; i < fbcount; ++i) - { - XVisualInfo* vi = glXGetVisualFromFBConfig(m_display, fbc[i]); - - if (vi) + if (--m_sharedDisplay == 0) { - int samp_buf = 0, samples = 0; - glXGetFBConfigAttrib(m_display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf); - glXGetFBConfigAttrib(m_display, fbc[i], GLX_SAMPLES , &samples ); - - if ((best_fbc < 0) || (samp_buf && (samples > best_num_samp))) - { - best_fbc = i; - best_num_samp = samples; - } - if ((worst_fbc < 0) || !samp_buf || (samples < worst_num_samp)) - { - worst_fbc = i; - worst_num_samp = samples; - } + XCloseDisplay(m_display); + m_display = nullptr; } - XFree(vi); } - GLXFBConfig bestFbc = fbc[best_fbc]; - - // Be sure to free the FBConfig list allocated by glXChooseFBConfig() - XFree(fbc); - - // Get a visual - XVisualInfo* vi = glXGetVisualFromFBConfig(m_display, bestFbc); - if (!vi) + bool ContextImpl::Activate() { - NazaraError("Failed to get best VisualInfo"); - return false; + return glXMakeCurrent(m_display, m_window, m_context) == true; } - // If context is shared by multiple windows - if (parameters.window) + bool ContextImpl::Create(ContextParameters& parameters) { - m_window = parameters.window; - m_ownsWindow = false; - } - else - { - XSetWindowAttributes swa; - swa.colormap = m_colormap = XCreateColormap( - m_display, - XRootWindow( - m_display, - vi->screen), - vi->visual, - AllocNone - ); - - swa.background_pixmap = None; - swa.border_pixel = 0; - swa.event_mask = StructureNotifyMask; - - if (!m_colormap) + // En cas d'exception, la ressource sera quand même libérée + CallOnExit onExit([this] () { - NazaraError("Failed to create colormap for context"); + Destroy(); + }); + + // Get a matching FB config + static int visual_attribs[] = + { + GLX_X_RENDERABLE, True, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, + GLX_BUFFER_SIZE, parameters.bitsPerPixel, + GLX_ALPHA_SIZE, (parameters.bitsPerPixel == 32) ? 8 : 0, + GLX_DEPTH_SIZE, parameters.depthBits, + GLX_STENCIL_SIZE, parameters.stencilBits, + GLX_DOUBLEBUFFER, True, + GLX_SAMPLE_BUFFERS, (parameters.antialiasingLevel > 0) ? True : False, + GLX_SAMPLES, parameters.antialiasingLevel, + None + }; + + int glx_major = 0; + int glx_minor = 0; + // FBConfigs were added in GLX version 1.3. + if (!glXQueryVersion(m_display, &glx_major, &glx_minor) || ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1)) + { + NazaraError("Invalid GLX version, version > 1.3 is required."); return false; } - m_window = XCreateWindow( - m_display, - XRootWindow( - m_display, - vi->screen), - 0, 0, // X, Y - 1, 1, // W H - 0, - vi->depth, - InputOutput, - vi->visual, - CWBorderPixel | CWColormap | CWEventMask, - &swa - ); - - m_ownsWindow = true; - } - - if (!m_window) - { - NazaraError("Failed to create window"); - return false; - } - - // Done with the visual info data - XFree(vi); - - // Install an X error handler so the application won't exit if GL 3.0 - // context allocation fails. - // - // Note this error handler is global. All display connections in all threads - // of a process use the same error handler, so be sure to guard against other - // threads issuing X commands while this code is running. - ctxErrorOccurred = false; - int (*oldHandler)(Display*, XErrorEvent*) = - XSetErrorHandler(&ctxErrorHandler); - - // Check for the GLX_ARB_create_context extension string and the function. - // If either is not present, use GLX 1.3 context creation method. - if (!glXCreateContextAttribs) - { - NazaraWarning("glXCreateContextAttribs() not found. Using old-style GLX context"); - m_context = glXCreateNewContext(m_display, bestFbc, GLX_RGBA_TYPE, parameters.shared ? parameters.shareContext->m_impl->m_context : 0, True); - } - // If it does, try to get a GL 3.0 context! - else - { - int profile = parameters.compatibilityProfile ? GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : GLX_CONTEXT_CORE_PROFILE_BIT_ARB; - int debug = parameters.debugMode ? GLX_CONTEXT_DEBUG_BIT_ARB : 0; - - int major = 3;//parameters.majorVersion; - int minor = 3;//parameters.minorVersion; - - int context_attribs[] = + int fbcount; + GLXFBConfig* fbc = glXChooseFBConfig(m_display, XDefaultScreen(m_display), visual_attribs, &fbcount); + if (!fbc) { - GLX_CONTEXT_MAJOR_VERSION_ARB, major, - GLX_CONTEXT_MINOR_VERSION_ARB, minor, - GLX_CONTEXT_PROFILE_MASK_ARB, profile, - GLX_CONTEXT_FLAGS_ARB, debug, - None, None - }; + NazaraError("Failed to retrieve a framebuffer config"); + return false; + } - m_context = glXCreateContextAttribs( - m_display, - bestFbc, - parameters.shared ? parameters.shareContext->m_impl->m_context : 0, - True, - context_attribs - ); + // Pick the FB config/visual with the most samples per pixel + int best_fbc = -1; + int worst_fbc = -1; + int best_num_samp = -1; + int worst_num_samp = 999; + + for (int i = 0; i < fbcount; ++i) + { + XVisualInfo* vi = glXGetVisualFromFBConfig(m_display, fbc[i]); + + if (vi) + { + int samp_buf = 0, samples = 0; + glXGetFBConfigAttrib(m_display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf); + glXGetFBConfigAttrib(m_display, fbc[i], GLX_SAMPLES , &samples ); + + if ((best_fbc < 0) || (samp_buf && (samples > best_num_samp))) + { + best_fbc = i; + best_num_samp = samples; + } + if ((worst_fbc < 0) || !samp_buf || (samples < worst_num_samp)) + { + worst_fbc = i; + worst_num_samp = samples; + } + } + XFree(vi); + } + + GLXFBConfig bestFbc = fbc[best_fbc]; + + // Be sure to free the FBConfig list allocated by glXChooseFBConfig() + XFree(fbc); + + // Get a visual + XVisualInfo* vi = glXGetVisualFromFBConfig(m_display, bestFbc); + if (!vi) + { + NazaraError("Failed to get best VisualInfo"); + return false; + } + + // If context is shared by multiple windows + if (parameters.window) + { + m_window = parameters.window; + m_ownsWindow = false; + } + else + { + XSetWindowAttributes swa; + swa.colormap = m_colormap = XCreateColormap( + m_display, + XRootWindow( + m_display, + vi->screen), + vi->visual, + AllocNone + ); + + swa.background_pixmap = None; + swa.border_pixel = 0; + swa.event_mask = StructureNotifyMask; + + if (!m_colormap) + { + NazaraError("Failed to create colormap for context"); + return false; + } + + m_window = XCreateWindow( + m_display, + XRootWindow( + m_display, + vi->screen), + 0, 0, // X, Y + 1, 1, // W H + 0, + vi->depth, + InputOutput, + vi->visual, + CWBorderPixel | CWColormap | CWEventMask, + &swa + ); + + m_ownsWindow = true; + } + + if (!m_window) + { + NazaraError("Failed to create window"); + return false; + } + + // Done with the visual info data + XFree(vi); + + // Install an X error handler so the application won't exit if GL 3.0 + // context allocation fails. + // + // Note this error handler is global. All display connections in all threads + // of a process use the same error handler, so be sure to guard against other + // threads issuing X commands while this code is running. + ctxErrorOccurred = false; + int (*oldHandler)(Display*, XErrorEvent*) = + XSetErrorHandler(&ctxErrorHandler); + + // Check for the GLX_ARB_create_context extension string and the function. + // If either is not present, use GLX 1.3 context creation method. + if (!glXCreateContextAttribs) + { + NazaraWarning("glXCreateContextAttribs() not found. Using old-style GLX context"); + m_context = glXCreateNewContext(m_display, bestFbc, GLX_RGBA_TYPE, parameters.shared ? parameters.shareContext->m_impl->m_context : 0, True); + } + // If it does, try to get a GL 3.0 context! + else + { + int profile = parameters.compatibilityProfile ? GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + int debug = parameters.debugMode ? GLX_CONTEXT_DEBUG_BIT_ARB : 0; + + int major = 3;//parameters.majorVersion; + int minor = 3;//parameters.minorVersion; + + int context_attribs[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, major, + GLX_CONTEXT_MINOR_VERSION_ARB, minor, + GLX_CONTEXT_PROFILE_MASK_ARB, profile, + GLX_CONTEXT_FLAGS_ARB, debug, + None, None + }; + + m_context = glXCreateContextAttribs( + m_display, + bestFbc, + parameters.shared ? parameters.shareContext->m_impl->m_context : 0, + True, + context_attribs + ); + } + + // Sync to ensure any errors generated are processed. + XSync(m_display, False); + XSetErrorHandler(oldHandler); + if (ctxErrorOccurred || !m_context) + { + NazaraError("Failed to create context, check the version"); + return false; + } + + onExit.Reset(); + + return true; } - // Sync to ensure any errors generated are processed. - XSync(m_display, False); - XSetErrorHandler(oldHandler); - if (ctxErrorOccurred || !m_context) + void ContextImpl::Destroy() { - NazaraError("Failed to create context, check the version"); - return false; + // Destroy the context + if (m_context) + { + if (glXGetCurrentContext() == m_context) + glXMakeCurrent(m_display, None, nullptr); + glXDestroyContext(m_display, m_context); + m_context = nullptr; + } + + // Destroy the window if we own it + if (m_ownsWindow && m_window) + { + XFreeColormap(m_display, m_colormap); + XDestroyWindow(m_display, m_window); + m_ownsWindow = false; + m_window = 0; + XFlush(m_display); + } } - onExit.Reset(); - - return true; -} - -void NzContextImpl::Destroy() -{ - // Destroy the context - if (m_context) + void ContextImpl::EnableVerticalSync(bool enabled) { - if (glXGetCurrentContext() == m_context) - glXMakeCurrent(m_display, None, nullptr); - glXDestroyContext(m_display, m_context); - m_context = nullptr; + if (glXSwapIntervalEXT) + glXSwapIntervalEXT(m_display, glXGetCurrentDrawable(), enabled ? 1 : 0); + else if (NzglXSwapIntervalMESA) + NzglXSwapIntervalMESA(enabled ? 1 : 0); + else if (glXSwapIntervalSGI) + glXSwapIntervalSGI(enabled ? 1 : 0); + else + NazaraError("Vertical sync not supported"); } - // Destroy the window if we own it - if (m_ownsWindow && m_window) + void ContextImpl::SwapBuffers() { - XFreeColormap(m_display, m_colormap); - XDestroyWindow(m_display, m_window); - m_ownsWindow = false; - m_window = 0; - XFlush(m_display); + if (m_window) + glXSwapBuffers(m_display, m_window); + } + + bool ContextImpl::Desactivate() + { + return glXMakeCurrent(m_display, None, nullptr) == true; } } - -void NzContextImpl::EnableVerticalSync(bool enabled) -{ - if (glXSwapIntervalEXT) - glXSwapIntervalEXT(m_display, glXGetCurrentDrawable(), enabled ? 1 : 0); - else if (NzglXSwapIntervalMESA) - NzglXSwapIntervalMESA(enabled ? 1 : 0); - else if (glXSwapIntervalSGI) - glXSwapIntervalSGI(enabled ? 1 : 0); - else - NazaraError("Vertical sync not supported"); -} - -void NzContextImpl::SwapBuffers() -{ - if (m_window) - glXSwapBuffers(m_display, m_window); -} - -bool NzContextImpl::Desactivate() -{ - return glXMakeCurrent(m_display, None, nullptr) == true; -} diff --git a/src/Nazara/Renderer/GLX/ContextImpl.hpp b/src/Nazara/Renderer/GLX/ContextImpl.hpp index 0a3a8b8dc..40bbd5fc7 100644 --- a/src/Nazara/Renderer/GLX/ContextImpl.hpp +++ b/src/Nazara/Renderer/GLX/ContextImpl.hpp @@ -9,31 +9,34 @@ #include -class NzContextParameters; - -class NzContextImpl +namespace Nz { - public: - NzContextImpl(); - ~NzContextImpl(); + class ContextParameters; - bool Activate(); + class ContextImpl + { + public: + ContextImpl(); + ~ContextImpl(); - bool Create(NzContextParameters& parameters); + bool Activate(); - void Destroy(); + bool Create(ContextParameters& parameters); - void EnableVerticalSync(bool enabled); + void Destroy(); - void SwapBuffers(); + void EnableVerticalSync(bool enabled); - static bool Desactivate(); + void SwapBuffers(); - private: - GLX::Colormap m_colormap; - GLX::GLXContext m_context; - GLX::Window m_window; - bool m_ownsWindow; -}; + static bool Desactivate(); + + private: + GLX::Colormap m_colormap; + GLX::GLXContext m_context; + GLX::Window m_window; + bool m_ownsWindow; + }; +} #endif // NAZARA_CONTEXTIMPL_HPP diff --git a/src/Nazara/Renderer/OpenGL.cpp b/src/Nazara/Renderer/OpenGL.cpp index c1e0e544e..5cc0865ea 100644 --- a/src/Nazara/Renderer/OpenGL.cpp +++ b/src/Nazara/Renderer/OpenGL.cpp @@ -9,6 +9,9 @@ #include #include #include +#if defined(NAZARA_PLATFORM_GLX) +#include +#endif // NAZARA_PLATFORM_GLX #include #include #include @@ -30,7 +33,7 @@ namespace Nz OpenGLFunc entry = reinterpret_cast(wglGetProcAddress(name)); if (!entry) // wglGetProcAddress ne fonctionne pas sur les fonctions OpenGL <= 1.1 entry = reinterpret_cast(GetProcAddress(openGLlibrary, name)); - #elif defined(NAZARA_PLATFORM_LINUX) + #elif defined(NAZARA_PLATFORM_GLX) OpenGLFunc entry = reinterpret_cast(GLX::glXGetProcAddress(reinterpret_cast(name))); #else #error OS not handled @@ -716,6 +719,15 @@ namespace Nz if (s_initialized) return true; + #if defined(NAZARA_PLATFORM_GLX) + Initializer display; + if (!display) + { + NazaraError("Failed to load display library"); + return false; + } + #endif + if (!LoadLibrary()) { NazaraError("Failed to load OpenGL library"); @@ -1004,7 +1016,7 @@ namespace Nz wglGetExtensionsStringARB = reinterpret_cast(LoadEntry("wglGetExtensionsStringARB", false)); wglGetExtensionsStringEXT = reinterpret_cast(LoadEntry("wglGetExtensionsStringEXT", false)); wglSwapInterval = reinterpret_cast(LoadEntry("wglSwapIntervalEXT", false)); - #elif defined(NAZARA_PLATFORM_LINUX) + #elif defined(NAZARA_PLATFORM_GLX) glXSwapIntervalEXT = reinterpret_cast(LoadEntry("glXSwapIntervalEXT", false)); NzglXSwapIntervalMESA = reinterpret_cast(LoadEntry("glXSwapIntervalMESA", false)); glXSwapIntervalSGI = reinterpret_cast(LoadEntry("glXSwapIntervalSGI", false)); @@ -2242,9 +2254,9 @@ PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = nullptr; PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = nullptr; PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT = nullptr; PFNWGLSWAPINTERVALEXTPROC wglSwapInterval = nullptr; -#elif defined(NAZARA_PLATFORM_LINUX) +#elif defined(NAZARA_PLATFORM_GLX) GLX::PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = nullptr; GLX::PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = nullptr; GLX::PFNGLXSWAPINTERVALMESAPROC NzglXSwapIntervalMESA = nullptr; GLX::PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = nullptr; -#endif \ No newline at end of file +#endif diff --git a/src/Nazara/Utility/Debug/NewOverload.cpp b/src/Nazara/Utility/Debug/NewOverload.cpp index 0ab389a70..00dc7f90c 100644 --- a/src/Nazara/Utility/Debug/NewOverload.cpp +++ b/src/Nazara/Utility/Debug/NewOverload.cpp @@ -10,22 +10,22 @@ void* operator new(std::size_t size) { - return NzMemoryManager::Allocate(size, false); + return Nz::MemoryManager::Allocate(size, false); } void* operator new[](std::size_t size) { - return NzMemoryManager::Allocate(size, true); + return Nz::MemoryManager::Allocate(size, true); } void operator delete(void* pointer) noexcept { - NzMemoryManager::Free(pointer, false); + Nz::MemoryManager::Free(pointer, false); } void operator delete[](void* pointer) noexcept { - NzMemoryManager::Free(pointer, true); + Nz::MemoryManager::Free(pointer, true); } #endif // NAZARA_UTILITY_MANAGE_MEMORY diff --git a/src/Nazara/Utility/X11/CursorImpl.cpp b/src/Nazara/Utility/X11/CursorImpl.cpp index 1ccde5e70..8cdde5170 100644 --- a/src/Nazara/Utility/X11/CursorImpl.cpp +++ b/src/Nazara/Utility/X11/CursorImpl.cpp @@ -12,150 +12,153 @@ #include #include -bool NzCursorImpl::Create(const NzImage& cursor, int hotSpotX, int hotSpotY) +namespace Nz { - NzImage cursorImage(cursor); // Vive le COW - if (!cursorImage.Convert(nzPixelFormat_BGRA8)) + bool CursorImpl::Create(const Image& cursor, int hotSpotX, int hotSpotY) { - NazaraError("Failed to convert cursor to BGRA8"); - return false; - } + Image cursorImage(cursor); // Vive le COW + if (!cursorImage.Convert(Nz::PixelFormatType_BGRA8)) + { + NazaraError("Failed to convert cursor to BGRA8"); + return false; + } - auto width = cursorImage.GetWidth(); - auto height = cursorImage.GetHeight(); + auto width = cursorImage.GetWidth(); + auto height = cursorImage.GetHeight(); - NzScopedXCBConnection connection; + ScopedXCBConnection connection; - xcb_screen_t* screen = X11::XCBDefaultScreen(connection); + xcb_screen_t* screen = X11::XCBDefaultScreen(connection); - NzScopedXCB error(nullptr); - NzScopedXCB formatsReply = xcb_render_query_pict_formats_reply( - connection, - xcb_render_query_pict_formats(connection), - &error); - - if (!formatsReply || error) - { - NazaraError("Failed to get pict formats"); - return false; - } - - xcb_render_pictforminfo_t* fmt = xcb_render_util_find_standard_format( - formatsReply.get(), - XCB_PICT_STANDARD_ARGB_32); - - if (!fmt) - { - NazaraError("Failed to find format PICT_STANDARD_ARGB_32"); - return false; - } - - xcb_image_t* xi = xcb_image_create( - width, height, - XCB_IMAGE_FORMAT_Z_PIXMAP, - 32, 32, 32, 32, - XCB_IMAGE_ORDER_LSB_FIRST, - XCB_IMAGE_ORDER_MSB_FIRST, - 0, 0, 0); - - if (!xi) - { - NazaraError("Failed to create image for cursor"); - return false; - } - - std::unique_ptr data(new uint8_t[xi->stride * height]); - - if (!data) - { - xcb_image_destroy(xi); - NazaraError("Failed to allocate memory for cursor image"); - return false; - } - - xi->data = data.get(); - - std::copy(cursorImage.GetConstPixels(), cursorImage.GetConstPixels() + cursorImage.GetBytesPerPixel() * width * height, xi->data); - - xcb_render_picture_t pic = XCB_NONE; - - NzCallOnExit onExit([&](){ - xcb_image_destroy(xi); - if (pic != XCB_NONE) - xcb_render_free_picture(connection, pic); - }); - - NzXCBPixmap pix(connection); - if (!pix.Create(32, screen->root, width, height)) - { - NazaraError("Failed to create pixmap for cursor"); - return false; - } - - pic = xcb_generate_id(connection); - if (!X11::CheckCookie( - connection, - xcb_render_create_picture( + ScopedXCB error(nullptr); + ScopedXCB formatsReply = xcb_render_query_pict_formats_reply( connection, - pic, - pix, - fmt->id, - 0, - nullptr - ))) - { - NazaraError("Failed to create render picture for cursor"); - return false; - } + xcb_render_query_pict_formats(connection), + &error); - NzXCBGContext gc(connection); - if (!gc.Create(pix, 0, nullptr)) - { - NazaraError("Failed to create gcontext for cursor"); - return false; - } + if (!formatsReply || error) + { + NazaraError("Failed to get pict formats"); + return false; + } - if (!X11::CheckCookie( - connection, - xcb_image_put( + xcb_render_pictforminfo_t* fmt = xcb_render_util_find_standard_format( + formatsReply.get(), + XCB_PICT_STANDARD_ARGB_32); + + if (!fmt) + { + NazaraError("Failed to find format PICT_STANDARD_ARGB_32"); + return false; + } + + xcb_image_t* xi = xcb_image_create( + width, height, + XCB_IMAGE_FORMAT_Z_PIXMAP, + 32, 32, 32, 32, + XCB_IMAGE_ORDER_LSB_FIRST, + XCB_IMAGE_ORDER_MSB_FIRST, + 0, 0, 0); + + if (!xi) + { + NazaraError("Failed to create image for cursor"); + return false; + } + + std::unique_ptr data(new uint8_t[xi->stride * height]); + + if (!data) + { + xcb_image_destroy(xi); + NazaraError("Failed to allocate memory for cursor image"); + return false; + } + + xi->data = data.get(); + + std::copy(cursorImage.GetConstPixels(), cursorImage.GetConstPixels() + cursorImage.GetBytesPerPixel() * width * height, xi->data); + + xcb_render_picture_t pic = XCB_NONE; + + CallOnExit onExit([&](){ + xcb_image_destroy(xi); + if (pic != XCB_NONE) + xcb_render_free_picture(connection, pic); + }); + + XCBPixmap pix(connection); + if (!pix.Create(32, screen->root, width, height)) + { + NazaraError("Failed to create pixmap for cursor"); + return false; + } + + pic = xcb_generate_id(connection); + if (!X11::CheckCookie( connection, - pix, - gc, - xi, - 0, 0, - 0 - ))) - { - NazaraError("Failed to put image for cursor"); - return false; - } + xcb_render_create_picture( + connection, + pic, + pix, + fmt->id, + 0, + nullptr + ))) + { + NazaraError("Failed to create render picture for cursor"); + return false; + } - m_cursor = xcb_generate_id(connection); - if (!X11::CheckCookie( - connection, - xcb_render_create_cursor( + XCBGContext gc(connection); + if (!gc.Create(pix, 0, nullptr)) + { + NazaraError("Failed to create gcontext for cursor"); + return false; + } + + if (!X11::CheckCookie( connection, - m_cursor, - pic, - hotSpotX, hotSpotY - ))) - { - NazaraError("Failed to create cursor"); - return false; + xcb_image_put( + connection, + pix, + gc, + xi, + 0, 0, + 0 + ))) + { + NazaraError("Failed to put image for cursor"); + return false; + } + + m_cursor = xcb_generate_id(connection); + if (!X11::CheckCookie( + connection, + xcb_render_create_cursor( + connection, + m_cursor, + pic, + hotSpotX, hotSpotY + ))) + { + NazaraError("Failed to create cursor"); + return false; + } + + return true; } - return true; -} + void CursorImpl::Destroy() + { + ScopedXCBConnection connection; -void NzCursorImpl::Destroy() -{ - NzScopedXCBConnection connection; + xcb_free_cursor(connection, m_cursor); + m_cursor = 0; + } - xcb_free_cursor(connection, m_cursor); - m_cursor = 0; -} - -xcb_cursor_t NzCursorImpl::GetCursor() -{ - return m_cursor; + xcb_cursor_t CursorImpl::GetCursor() + { + return m_cursor; + } } diff --git a/src/Nazara/Utility/X11/CursorImpl.hpp b/src/Nazara/Utility/X11/CursorImpl.hpp index b20555623..41d91bcb1 100644 --- a/src/Nazara/Utility/X11/CursorImpl.hpp +++ b/src/Nazara/Utility/X11/CursorImpl.hpp @@ -7,20 +7,24 @@ #ifndef NAZARA_CURSORIMPL_HPP #define NAZARA_CURSORIMPL_HPP +#include #include -class NzImage; - -class NzCursorImpl +namespace Nz { - public: - bool Create(const NzImage& image, int hotSpotX, int hotSpotY); - void Destroy(); + class Image; - xcb_cursor_t GetCursor(); + class CursorImpl + { + public: + bool Create(const Image& image, int hotSpotX, int hotSpotY); + void Destroy(); - private: - xcb_cursor_t m_cursor; -}; + xcb_cursor_t GetCursor(); + + private: + xcb_cursor_t m_cursor; + }; +} #endif // NAZARA_CURSORIMPL_HPP diff --git a/src/Nazara/Utility/X11/Display.cpp b/src/Nazara/Utility/X11/Display.cpp index 99e0abe03..d61543dfd 100644 --- a/src/Nazara/Utility/X11/Display.cpp +++ b/src/Nazara/Utility/X11/Display.cpp @@ -4,32 +4,34 @@ #include #include +#include +#include #include #include #include -namespace +namespace Nz { - // The shared display and its reference counter - xcb_connection_t* sharedConnection = nullptr; - int screen_nbr = 0; - unsigned int referenceCountConnection = 0; - - xcb_key_symbols_t* sharedkeySymbol; - unsigned int referenceCountKeySymbol = 0; - - xcb_ewmh_connection_t* sharedEwmhConnection; - unsigned int referenceCountEwmhConnection = 0; - - using AtomMap = std::map; - AtomMap atoms; -} - -namespace X11 -{ - bool CheckCookie(xcb_connection_t* connection, xcb_void_cookie_t cookie) + namespace { - NzScopedXCB error(xcb_request_check( + // The shared display and its reference counter + xcb_connection_t* sharedConnection = nullptr; + int screen_nbr = 0; + unsigned int referenceCountConnection = 0; + + xcb_key_symbols_t* sharedkeySymbol = nullptr; + unsigned int referenceCountKeySymbol = 0; + + xcb_ewmh_connection_t* sharedEwmhConnection = nullptr; + unsigned int referenceCountEwmhConnection = 0; + + using AtomMap = std::map; + AtomMap atoms; + } + + bool X11::CheckCookie(xcb_connection_t* connection, xcb_void_cookie_t cookie) + { + ScopedXCB error(xcb_request_check( connection, cookie )); @@ -40,36 +42,36 @@ namespace X11 return true; } - void CloseConnection(xcb_connection_t* connection) + void X11::CloseConnection(xcb_connection_t* connection) { NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server"); --referenceCountConnection; } - void CloseEWMHConnection(xcb_ewmh_connection_t* ewmh_connection) + void X11::CloseEWMHConnection(xcb_ewmh_connection_t* ewmh_connection) { NazaraAssert(ewmh_connection == sharedEwmhConnection, "The model is meant for one connection to X11 server"); --referenceCountEwmhConnection; } - xcb_atom_t GetAtom(const std::string& name, bool onlyIfExists) + xcb_atom_t X11::GetAtom(const String& name, bool onlyIfExists) { AtomMap::const_iterator iter = atoms.find(name); if (iter != atoms.end()) return iter->second; - NzScopedXCB error(nullptr); + ScopedXCB error(nullptr); xcb_connection_t* connection = OpenConnection(); - NzScopedXCB reply(xcb_intern_atom_reply( + ScopedXCB reply(xcb_intern_atom_reply( connection, xcb_intern_atom( connection, onlyIfExists, - name.size(), - name.c_str() + name.GetSize(), + name.GetConstBuffer() ), &error )); @@ -87,8 +89,16 @@ namespace X11 return reply->atom; } - void Initialize() + bool X11::Initialize() { + if (IsInitialized()) + { + s_moduleReferenceCounter++; + return true; // Déjà initialisé + } + + s_moduleReferenceCounter++; + NazaraAssert(referenceCountConnection == 0, "Initialize should be called before anything"); NazaraAssert(referenceCountKeySymbol == 0, "Initialize should be called before anything"); NazaraAssert(referenceCountEwmhConnection == 0, "Initialize should be called before anything"); @@ -125,9 +135,17 @@ namespace X11 OpenEWMHConnection(sharedConnection); } + + NazaraNotice("Initialized: Utility module"); + return true; } - xcb_key_symbols_t* XCBKeySymbolsAlloc(xcb_connection_t* connection) + bool X11::IsInitialized() + { + return s_moduleReferenceCounter != 0; + } + + xcb_key_symbols_t* X11::XCBKeySymbolsAlloc(xcb_connection_t* connection) { NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server"); @@ -135,20 +153,20 @@ namespace X11 return sharedkeySymbol; } - void XCBKeySymbolsFree(xcb_key_symbols_t* keySymbols) + void X11::XCBKeySymbolsFree(xcb_key_symbols_t* keySymbols) { NazaraAssert(keySymbols == sharedkeySymbol, "The model is meant for one connection to X11 server"); --referenceCountKeySymbol; } - xcb_connection_t* OpenConnection() + xcb_connection_t* X11::OpenConnection() { ++referenceCountConnection; return sharedConnection; } - xcb_ewmh_connection_t* OpenEWMHConnection(xcb_connection_t* connection) + xcb_ewmh_connection_t* X11::OpenEWMHConnection(xcb_connection_t* connection) { NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server"); @@ -156,8 +174,19 @@ namespace X11 return sharedEwmhConnection; } - void Uninitialize() + void X11::Uninitialize() { + if (s_moduleReferenceCounter != 1) + { + // Le module est soit encore utilisé, soit pas initialisé + if (s_moduleReferenceCounter > 1) + s_moduleReferenceCounter--; + + return; + } + + s_moduleReferenceCounter = 0; + { NazaraAssert(referenceCountEwmhConnection == 1, "Uninitialize should be called after anything or a close is missing"); CloseEWMHConnection(sharedEwmhConnection); @@ -179,9 +208,11 @@ namespace X11 xcb_disconnect(sharedConnection); } + + NazaraNotice("Uninitialized: Display module"); } - xcb_window_t XCBDefaultRootWindow(xcb_connection_t* connection) + xcb_window_t X11::XCBDefaultRootWindow(xcb_connection_t* connection) { NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server"); xcb_screen_t* screen = XCBDefaultScreen(connection); @@ -190,19 +221,19 @@ namespace X11 return XCB_NONE; } - xcb_screen_t* XCBDefaultScreen(xcb_connection_t* connection) + xcb_screen_t* X11::XCBDefaultScreen(xcb_connection_t* connection) { NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server"); return XCBScreenOfDisplay(connection, screen_nbr); } - int XCBScreen(xcb_connection_t* connection) + int X11::XCBScreen(xcb_connection_t* connection) { NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server"); return screen_nbr; } - xcb_screen_t* XCBScreenOfDisplay(xcb_connection_t* connection, int screen_nbr) + xcb_screen_t* X11::XCBScreenOfDisplay(xcb_connection_t* connection, int screen_nbr) { NazaraAssert(connection == sharedConnection, "The model is meant for one connection to X11 server"); xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_get_setup(connection)); @@ -215,4 +246,6 @@ namespace X11 return nullptr; } + + unsigned int X11::s_moduleReferenceCounter = 0; } diff --git a/src/Nazara/Utility/X11/Display.hpp b/src/Nazara/Utility/X11/Display.hpp index a1b0e56e5..95177e2d2 100644 --- a/src/Nazara/Utility/X11/Display.hpp +++ b/src/Nazara/Utility/X11/Display.hpp @@ -7,35 +7,47 @@ #ifndef NAZARA_X11DISPLAY_HPP #define NAZARA_X11DISPLAY_HPP +#include #include #include -#include -#include typedef struct _XCBKeySymbols xcb_key_symbols_t; -namespace X11 +namespace Nz { - bool CheckCookie(xcb_connection_t* connection, xcb_void_cookie_t cookie); - void CloseConnection(xcb_connection_t* connection); - void CloseEWMHConnection(xcb_ewmh_connection_t* ewmh_connection); + class String; - xcb_atom_t GetAtom(const std::string& name, bool onlyIfExists = false); + class X11 + { + public: + X11() = delete; + ~X11() = delete; - void Initialize(); + static bool CheckCookie(xcb_connection_t* connection, xcb_void_cookie_t cookie); + static void CloseConnection(xcb_connection_t* connection); + static void CloseEWMHConnection(xcb_ewmh_connection_t* ewmh_connection); - xcb_key_symbols_t* XCBKeySymbolsAlloc(xcb_connection_t* connection); - void XCBKeySymbolsFree(xcb_key_symbols_t* keySymbols); + static xcb_atom_t GetAtom(const String& name, bool onlyIfExists = false); - xcb_connection_t* OpenConnection(); - xcb_ewmh_connection_t* OpenEWMHConnection(xcb_connection_t* connection); + static bool Initialize(); + static bool IsInitialized(); - void Uninitialize(); + static xcb_key_symbols_t* XCBKeySymbolsAlloc(xcb_connection_t* connection); + static void XCBKeySymbolsFree(xcb_key_symbols_t* keySymbols); - xcb_screen_t* XCBDefaultScreen(xcb_connection_t* connection); - xcb_window_t XCBDefaultRootWindow(xcb_connection_t* connection); - int XCBScreen(xcb_connection_t* connection); - xcb_screen_t* XCBScreenOfDisplay(xcb_connection_t* connection, int screen_nbr); + static xcb_connection_t* OpenConnection(); + static xcb_ewmh_connection_t* OpenEWMHConnection(xcb_connection_t* connection); + + static void Uninitialize(); + + static xcb_screen_t* XCBDefaultScreen(xcb_connection_t* connection); + static xcb_window_t XCBDefaultRootWindow(xcb_connection_t* connection); + static int XCBScreen(xcb_connection_t* connection); + static xcb_screen_t* XCBScreenOfDisplay(xcb_connection_t* connection, int screen_nbr); + + private: + static unsigned int s_moduleReferenceCounter; + }; } #endif // NAZARA_X11DISPLAY_HPP diff --git a/src/Nazara/Utility/X11/IconImpl.cpp b/src/Nazara/Utility/X11/IconImpl.cpp index 3eb3bd1ab..030cbdf8b 100644 --- a/src/Nazara/Utility/X11/IconImpl.cpp +++ b/src/Nazara/Utility/X11/IconImpl.cpp @@ -10,125 +10,128 @@ #include #include -NzIconImpl::NzIconImpl() +namespace Nz { - NzScopedXCBConnection connection; - - m_iconPixmap.Connect(connection); - m_maskPixmap.Connect(connection); -} - -bool NzIconImpl::Create(const NzImage& icon) -{ - NzImage iconImage(icon); // Vive le COW - if (!iconImage.Convert(nzPixelFormat_BGRA8)) + IconImpl::IconImpl() { - NazaraError("Failed to convert icon to BGRA8"); - return false; + ScopedXCBConnection connection; + + m_iconPixmap.Connect(connection); + m_maskPixmap.Connect(connection); } - auto width = iconImage.GetWidth(); - auto height = iconImage.GetHeight(); - - NzScopedXCBConnection connection; - - xcb_screen_t* screen = X11::XCBDefaultScreen(connection); - - if (!m_iconPixmap.Create( - screen->root_depth, - screen->root, - width, - height)) + bool IconImpl::Create(const Image& icon) { - NazaraError("Failed to create icon pixmap"); - return false; - } - - NzCallOnExit onExit([this](){ - Destroy(); - }); - - NzXCBGContext iconGC(connection); - - if (!iconGC.Create( - m_iconPixmap, - 0, - nullptr)) - { - NazaraError("Failed to create icon gc"); - return false; - } - - if (!X11::CheckCookie( - connection, - xcb_put_image( - connection, - XCB_IMAGE_FORMAT_Z_PIXMAP, - m_iconPixmap, - iconGC, - width, - height, - 0, - 0, - 0, - screen->root_depth, - width * height * 4, - iconImage.GetConstPixels() - ))) - { - NazaraError("Failed to put image for icon"); - return false; - } - - // Create the mask pixmap (must have 1 bit depth) - std::size_t pitch = (width + 7) / 8; - static std::vector maskPixels(pitch * height, 0); - for (std::size_t j = 0; j < height; ++j) - { - for (std::size_t i = 0; i < pitch; ++i) + Image iconImage(icon); // Vive le COW + if (!iconImage.Convert(Nz::PixelFormatType_BGRA8)) { - for (std::size_t k = 0; k < 8; ++k) + NazaraError("Failed to convert icon to BGRA8"); + return false; + } + + auto width = iconImage.GetWidth(); + auto height = iconImage.GetHeight(); + + ScopedXCBConnection connection; + + xcb_screen_t* screen = X11::XCBDefaultScreen(connection); + + if (!m_iconPixmap.Create( + screen->root_depth, + screen->root, + width, + height)) + { + NazaraError("Failed to create icon pixmap"); + return false; + } + + CallOnExit onExit([this](){ + Destroy(); + }); + + XCBGContext iconGC(connection); + + if (!iconGC.Create( + m_iconPixmap, + 0, + nullptr)) + { + NazaraError("Failed to create icon gc"); + return false; + } + + if (!X11::CheckCookie( + connection, + xcb_put_image( + connection, + XCB_IMAGE_FORMAT_Z_PIXMAP, + m_iconPixmap, + iconGC, + width, + height, + 0, + 0, + 0, + screen->root_depth, + width * height * 4, + iconImage.GetConstPixels() + ))) + { + NazaraError("Failed to put image for icon"); + return false; + } + + // Create the mask pixmap (must have 1 bit depth) + std::size_t pitch = (width + 7) / 8; + static std::vector maskPixels(pitch * height, 0); + for (std::size_t j = 0; j < height; ++j) + { + for (std::size_t i = 0; i < pitch; ++i) { - if (i * 8 + k < width) + for (std::size_t k = 0; k < 8; ++k) { - nzUInt8 opacity = (iconImage.GetConstPixels()[(i * 8 + k + j * width) * 4 + 3] > 0) ? 1 : 0; - maskPixels[i + j * pitch] |= (opacity << k); + if (i * 8 + k < width) + { + UInt8 opacity = (iconImage.GetConstPixels()[(i * 8 + k + j * width) * 4 + 3] > 0) ? 1 : 0; + maskPixels[i + j * pitch] |= (opacity << k); + } } } } + + if (!m_maskPixmap.CreatePixmapFromBitmapData( + X11::XCBDefaultRootWindow(connection), + reinterpret_cast(&maskPixels[0]), + width, + height, + 1, + 0, + 1, + nullptr)) + { + NazaraError("Failed to create mask pixmap for icon"); + return false; + } + + onExit.Reset(); + + return true; } - if (!m_maskPixmap.CreatePixmapFromBitmapData( - X11::XCBDefaultRootWindow(connection), - reinterpret_cast(&maskPixels[0]), - width, - height, - 1, - 0, - 1, - nullptr)) + void IconImpl::Destroy() { - NazaraError("Failed to create mask pixmap for icon"); - return false; + m_iconPixmap.Destroy(); + m_maskPixmap.Destroy(); } - onExit.Reset(); + xcb_pixmap_t IconImpl::GetIcon() + { + return m_iconPixmap; + } - return true; -} - -void NzIconImpl::Destroy() -{ - m_iconPixmap.Destroy(); - m_maskPixmap.Destroy(); -} - -xcb_pixmap_t NzIconImpl::GetIcon() -{ - return m_iconPixmap; -} - -xcb_pixmap_t NzIconImpl::GetMask() -{ - return m_maskPixmap; + xcb_pixmap_t IconImpl::GetMask() + { + return m_maskPixmap; + } } diff --git a/src/Nazara/Utility/X11/IconImpl.hpp b/src/Nazara/Utility/X11/IconImpl.hpp index bf968f367..1e8b301bc 100644 --- a/src/Nazara/Utility/X11/IconImpl.hpp +++ b/src/Nazara/Utility/X11/IconImpl.hpp @@ -7,24 +7,28 @@ #ifndef NAZARA_ICONIMPL_HPP #define NAZARA_ICONIMPL_HPP +#include #include -class NzImage; - -class NzIconImpl +namespace Nz { - public: - NzIconImpl(); + class Image; - bool Create(const NzImage& image); - void Destroy(); + class IconImpl + { + public: + IconImpl(); - xcb_pixmap_t GetIcon(); - xcb_pixmap_t GetMask(); + bool Create(const Image& image); + void Destroy(); - private: - NzXCBPixmap m_iconPixmap; - NzXCBPixmap m_maskPixmap; -}; + xcb_pixmap_t GetIcon(); + xcb_pixmap_t GetMask(); + + private: + XCBPixmap m_iconPixmap; + XCBPixmap m_maskPixmap; + }; +} #endif // NAZARA_ICONIMPL_HPP diff --git a/src/Nazara/Utility/X11/InputImpl.cpp b/src/Nazara/Utility/X11/InputImpl.cpp index 442b1e544..e21fdae96 100644 --- a/src/Nazara/Utility/X11/InputImpl.cpp +++ b/src/Nazara/Utility/X11/InputImpl.cpp @@ -12,215 +12,186 @@ #include #include -namespace +namespace Nz { - - KeySym GetKeySym(NzKeyboard::Key key) + namespace { - // X11 keysym correspondant - KeySym keysym = 0; - switch (key) + KeySym GetKeySym(Keyboard::Key key) { - // Lettres - case NzKeyboard::A: keysym = XK_A; break; - case NzKeyboard::B: keysym = XK_B; break; - case NzKeyboard::C: keysym = XK_C; break; - case NzKeyboard::D: keysym = XK_D; break; - case NzKeyboard::E: keysym = XK_E; break; - case NzKeyboard::F: keysym = XK_F; break; - case NzKeyboard::G: keysym = XK_G; break; - case NzKeyboard::H: keysym = XK_H; break; - case NzKeyboard::I: keysym = XK_I; break; - case NzKeyboard::J: keysym = XK_J; break; - case NzKeyboard::K: keysym = XK_K; break; - case NzKeyboard::L: keysym = XK_L; break; - case NzKeyboard::M: keysym = XK_M; break; - case NzKeyboard::N: keysym = XK_N; break; - case NzKeyboard::O: keysym = XK_O; break; - case NzKeyboard::P: keysym = XK_P; break; - case NzKeyboard::Q: keysym = XK_Q; break; - case NzKeyboard::R: keysym = XK_R; break; - case NzKeyboard::S: keysym = XK_S; break; - case NzKeyboard::T: keysym = XK_T; break; - case NzKeyboard::U: keysym = XK_U; break; - case NzKeyboard::V: keysym = XK_V; break; - case NzKeyboard::W: keysym = XK_W; break; - case NzKeyboard::X: keysym = XK_X; break; - case NzKeyboard::Y: keysym = XK_Y; break; - case NzKeyboard::Z: keysym = XK_Z; break; + // X11 keysym correspondant + KeySym keysym = 0; + switch (key) + { + // Lettres + case Keyboard::A: keysym = XK_A; break; + case Keyboard::B: keysym = XK_B; break; + case Keyboard::C: keysym = XK_C; break; + case Keyboard::D: keysym = XK_D; break; + case Keyboard::E: keysym = XK_E; break; + case Keyboard::F: keysym = XK_F; break; + case Keyboard::G: keysym = XK_G; break; + case Keyboard::H: keysym = XK_H; break; + case Keyboard::I: keysym = XK_I; break; + case Keyboard::J: keysym = XK_J; break; + case Keyboard::K: keysym = XK_K; break; + case Keyboard::L: keysym = XK_L; break; + case Keyboard::M: keysym = XK_M; break; + case Keyboard::N: keysym = XK_N; break; + case Keyboard::O: keysym = XK_O; break; + case Keyboard::P: keysym = XK_P; break; + case Keyboard::Q: keysym = XK_Q; break; + case Keyboard::R: keysym = XK_R; break; + case Keyboard::S: keysym = XK_S; break; + case Keyboard::T: keysym = XK_T; break; + case Keyboard::U: keysym = XK_U; break; + case Keyboard::V: keysym = XK_V; break; + case Keyboard::W: keysym = XK_W; break; + case Keyboard::X: keysym = XK_X; break; + case Keyboard::Y: keysym = XK_Y; break; + case Keyboard::Z: keysym = XK_Z; break; - // Touches de fonction - case NzKeyboard::F1: keysym = XK_F1; break; - case NzKeyboard::F2: keysym = XK_F2; break; - case NzKeyboard::F3: keysym = XK_F3; break; - case NzKeyboard::F4: keysym = XK_F4; break; - case NzKeyboard::F5: keysym = XK_F5; break; - case NzKeyboard::F6: keysym = XK_F6; break; - case NzKeyboard::F7: keysym = XK_F7; break; - case NzKeyboard::F8: keysym = XK_F8; break; - case NzKeyboard::F9: keysym = XK_F9; break; - case NzKeyboard::F10: keysym = XK_F10; break; - case NzKeyboard::F11: keysym = XK_F11; break; - case NzKeyboard::F12: keysym = XK_F12; break; - case NzKeyboard::F13: keysym = XK_F13; break; - case NzKeyboard::F14: keysym = XK_F14; break; - case NzKeyboard::F15: keysym = XK_F15; break; + // Touches de fonction + case Keyboard::F1: keysym = XK_F1; break; + case Keyboard::F2: keysym = XK_F2; break; + case Keyboard::F3: keysym = XK_F3; break; + case Keyboard::F4: keysym = XK_F4; break; + case Keyboard::F5: keysym = XK_F5; break; + case Keyboard::F6: keysym = XK_F6; break; + case Keyboard::F7: keysym = XK_F7; break; + case Keyboard::F8: keysym = XK_F8; break; + case Keyboard::F9: keysym = XK_F9; break; + case Keyboard::F10: keysym = XK_F10; break; + case Keyboard::F11: keysym = XK_F11; break; + case Keyboard::F12: keysym = XK_F12; break; + case Keyboard::F13: keysym = XK_F13; break; + case Keyboard::F14: keysym = XK_F14; break; + case Keyboard::F15: keysym = XK_F15; break; - // Flèches directionnelles - case NzKeyboard::Down: keysym = XK_Down; break; - case NzKeyboard::Left: keysym = XK_Left; break; - case NzKeyboard::Right: keysym = XK_Right; break; - case NzKeyboard::Up: keysym = XK_Up; break; + // Flèches directionnelles + case Keyboard::Down: keysym = XK_Down; break; + case Keyboard::Left: keysym = XK_Left; break; + case Keyboard::Right: keysym = XK_Right; break; + case Keyboard::Up: keysym = XK_Up; break; - // Pavé numérique - case NzKeyboard::Add: keysym = XK_KP_Add; break; - case NzKeyboard::Decimal: keysym = XK_KP_Decimal; break; - case NzKeyboard::Divide: keysym = XK_KP_Divide; break; - case NzKeyboard::Multiply: keysym = XK_KP_Multiply; break; - case NzKeyboard::Numpad0: keysym = XK_KP_0; break; - case NzKeyboard::Numpad1: keysym = XK_KP_1; break; - case NzKeyboard::Numpad2: keysym = XK_KP_2; break; - case NzKeyboard::Numpad3: keysym = XK_KP_3; break; - case NzKeyboard::Numpad4: keysym = XK_KP_4; break; - case NzKeyboard::Numpad5: keysym = XK_KP_5; break; - case NzKeyboard::Numpad6: keysym = XK_KP_6; break; - case NzKeyboard::Numpad7: keysym = XK_KP_7; break; - case NzKeyboard::Numpad8: keysym = XK_KP_8; break; - case NzKeyboard::Numpad9: keysym = XK_KP_9; break; - case NzKeyboard::Subtract: keysym = XK_KP_Subtract; break; + // Pavé numérique + case Keyboard::Add: keysym = XK_KP_Add; break; + case Keyboard::Decimal: keysym = XK_KP_Decimal; break; + case Keyboard::Divide: keysym = XK_KP_Divide; break; + case Keyboard::Multiply: keysym = XK_KP_Multiply; break; + case Keyboard::Numpad0: keysym = XK_KP_0; break; + case Keyboard::Numpad1: keysym = XK_KP_1; break; + case Keyboard::Numpad2: keysym = XK_KP_2; break; + case Keyboard::Numpad3: keysym = XK_KP_3; break; + case Keyboard::Numpad4: keysym = XK_KP_4; break; + case Keyboard::Numpad5: keysym = XK_KP_5; break; + case Keyboard::Numpad6: keysym = XK_KP_6; break; + case Keyboard::Numpad7: keysym = XK_KP_7; break; + case Keyboard::Numpad8: keysym = XK_KP_8; break; + case Keyboard::Numpad9: keysym = XK_KP_9; break; + case Keyboard::Subtract: keysym = XK_KP_Subtract; break; - // Divers - case NzKeyboard::Backslash: keysym = XK_backslash; break; - case NzKeyboard::Backspace: keysym = XK_BackSpace; break; - case NzKeyboard::Clear: keysym = XK_Clear; break; - case NzKeyboard::Comma: keysym = XK_comma; break; - case NzKeyboard::Dash: keysym = XK_minus; break; - case NzKeyboard::Delete: keysym = XK_Delete; break; - case NzKeyboard::End: keysym = XK_End; break; - case NzKeyboard::Equal: keysym = XK_equal; break; - case NzKeyboard::Escape: keysym = XK_Escape; break; - case NzKeyboard::Home: keysym = XK_Home; break; - case NzKeyboard::Insert: keysym = XK_Insert; break; - case NzKeyboard::LAlt: keysym = XK_Alt_L; break; - case NzKeyboard::LBracket: keysym = XK_bracketleft; break; - case NzKeyboard::LControl: keysym = XK_Control_L; break; - case NzKeyboard::LShift: keysym = XK_Shift_L; break; - case NzKeyboard::LSystem: keysym = XK_Super_L; break; - case NzKeyboard::Num0: keysym = XK_0; break; - case NzKeyboard::Num1: keysym = XK_1; break; - case NzKeyboard::Num2: keysym = XK_2; break; - case NzKeyboard::Num3: keysym = XK_3; break; - case NzKeyboard::Num4: keysym = XK_4; break; - case NzKeyboard::Num5: keysym = XK_5; break; - case NzKeyboard::Num6: keysym = XK_6; break; - case NzKeyboard::Num7: keysym = XK_7; break; - case NzKeyboard::Num8: keysym = XK_8; break; - case NzKeyboard::Num9: keysym = XK_9; break; - case NzKeyboard::PageDown: keysym = XK_Page_Down; break; - case NzKeyboard::PageUp: keysym = XK_Page_Up; break; - case NzKeyboard::Pause: keysym = XK_Pause; break; - case NzKeyboard::Period: keysym = XK_period; break; - case NzKeyboard::Print: keysym = XK_Print; break; - case NzKeyboard::PrintScreen: keysym = XK_Sys_Req; break; - case NzKeyboard::Quote: keysym = XK_quotedbl; break; - case NzKeyboard::RAlt: keysym = XK_Alt_R; break; - case NzKeyboard::RBracket: keysym = XK_bracketright; break; - case NzKeyboard::RControl: keysym = XK_Control_R; break; - case NzKeyboard::Return: keysym = XK_Return; break; - case NzKeyboard::RShift: keysym = XK_Shift_R; break; - case NzKeyboard::RSystem: keysym = XK_Super_R; break; - case NzKeyboard::Semicolon: keysym = XK_semicolon; break; - case NzKeyboard::Slash: keysym = XK_slash; break; - case NzKeyboard::Space: keysym = XK_space; break; - case NzKeyboard::Tab: keysym = XK_Tab; break; - case NzKeyboard::Tilde: keysym = XK_grave; break; + // Divers + case Keyboard::Backslash: keysym = XK_backslash; break; + case Keyboard::Backspace: keysym = XK_BackSpace; break; + case Keyboard::Clear: keysym = XK_Clear; break; + case Keyboard::Comma: keysym = XK_comma; break; + case Keyboard::Dash: keysym = XK_minus; break; + case Keyboard::Delete: keysym = XK_Delete; break; + case Keyboard::End: keysym = XK_End; break; + case Keyboard::Equal: keysym = XK_equal; break; + case Keyboard::Escape: keysym = XK_Escape; break; + case Keyboard::Home: keysym = XK_Home; break; + case Keyboard::Insert: keysym = XK_Insert; break; + case Keyboard::LAlt: keysym = XK_Alt_L; break; + case Keyboard::LBracket: keysym = XK_bracketleft; break; + case Keyboard::LControl: keysym = XK_Control_L; break; + case Keyboard::LShift: keysym = XK_Shift_L; break; + case Keyboard::LSystem: keysym = XK_Super_L; break; + case Keyboard::Num0: keysym = XK_0; break; + case Keyboard::Num1: keysym = XK_1; break; + case Keyboard::Num2: keysym = XK_2; break; + case Keyboard::Num3: keysym = XK_3; break; + case Keyboard::Num4: keysym = XK_4; break; + case Keyboard::Num5: keysym = XK_5; break; + case Keyboard::Num6: keysym = XK_6; break; + case Keyboard::Num7: keysym = XK_7; break; + case Keyboard::Num8: keysym = XK_8; break; + case Keyboard::Num9: keysym = XK_9; break; + case Keyboard::PageDown: keysym = XK_Page_Down; break; + case Keyboard::PageUp: keysym = XK_Page_Up; break; + case Keyboard::Pause: keysym = XK_Pause; break; + case Keyboard::Period: keysym = XK_period; break; + case Keyboard::Print: keysym = XK_Print; break; + case Keyboard::PrintScreen: keysym = XK_Sys_Req; break; + case Keyboard::Quote: keysym = XK_quotedbl; break; + case Keyboard::RAlt: keysym = XK_Alt_R; break; + case Keyboard::RBracket: keysym = XK_bracketright; break; + case Keyboard::RControl: keysym = XK_Control_R; break; + case Keyboard::Return: keysym = XK_Return; break; + case Keyboard::RShift: keysym = XK_Shift_R; break; + case Keyboard::RSystem: keysym = XK_Super_R; break; + case Keyboard::Semicolon: keysym = XK_semicolon; break; + case Keyboard::Slash: keysym = XK_slash; break; + case Keyboard::Space: keysym = XK_space; break; + case Keyboard::Tab: keysym = XK_Tab; break; + case Keyboard::Tilde: keysym = XK_grave; break; - // Touches navigateur - case NzKeyboard::Browser_Back: keysym = XF86XK_Back; break; - case NzKeyboard::Browser_Favorites: keysym = XF86XK_Favorites; break; - case NzKeyboard::Browser_Forward: keysym = XF86XK_Forward; break; - case NzKeyboard::Browser_Home: keysym = XF86XK_HomePage; break; - case NzKeyboard::Browser_Refresh: keysym = XF86XK_Refresh; break; - case NzKeyboard::Browser_Search: keysym = XF86XK_Search; break; - case NzKeyboard::Browser_Stop: keysym = XF86XK_Stop; break; + // Touches navigateur + case Keyboard::Browser_Back: keysym = XF86XK_Back; break; + case Keyboard::Browser_Favorites: keysym = XF86XK_Favorites; break; + case Keyboard::Browser_Forward: keysym = XF86XK_Forward; break; + case Keyboard::Browser_Home: keysym = XF86XK_HomePage; break; + case Keyboard::Browser_Refresh: keysym = XF86XK_Refresh; break; + case Keyboard::Browser_Search: keysym = XF86XK_Search; break; + case Keyboard::Browser_Stop: keysym = XF86XK_Stop; break; - // Touches de contrôle - case NzKeyboard::Media_Next: keysym = XF86XK_AudioNext; break; - case NzKeyboard::Media_Play: keysym = XF86XK_AudioPlay; break; - case NzKeyboard::Media_Previous: keysym = XF86XK_AudioPrev; break; - case NzKeyboard::Media_Stop: keysym = XF86XK_AudioStop; break; + // Touches de contrôle + case Keyboard::Media_Next: keysym = XF86XK_AudioNext; break; + case Keyboard::Media_Play: keysym = XF86XK_AudioPlay; break; + case Keyboard::Media_Previous: keysym = XF86XK_AudioPrev; break; + case Keyboard::Media_Stop: keysym = XF86XK_AudioStop; break; - // Touches de contrôle du volume - case NzKeyboard::Volume_Down: keysym = XF86XK_AudioLowerVolume; break; - case NzKeyboard::Volume_Mute: keysym = XF86XK_AudioMute; break; - case NzKeyboard::Volume_Up: keysym = XF86XK_AudioRaiseVolume; break; + // Touches de contrôle du volume + case Keyboard::Volume_Down: keysym = XF86XK_AudioLowerVolume; break; + case Keyboard::Volume_Mute: keysym = XF86XK_AudioMute; break; + case Keyboard::Volume_Up: keysym = XF86XK_AudioRaiseVolume; break; - // Touches à verrouillage - case NzKeyboard::CapsLock: keysym = XK_Caps_Lock; break; - case NzKeyboard::NumLock: keysym = XK_Num_Lock; break; - case NzKeyboard::ScrollLock: keysym = XK_Scroll_Lock; break; + // Touches à verrouillage + case Keyboard::CapsLock: keysym = XK_Caps_Lock; break; + case Keyboard::NumLock: keysym = XK_Num_Lock; break; + case Keyboard::ScrollLock: keysym = XK_Scroll_Lock; break; - default: break; + default: break; + } + + // Sanity checks + if (key < 0 || key >= Keyboard::Count || keysym == 0) + NazaraWarning("Key " + String::Number(key) + " is not handled in Keyboard"); + + return keysym; } - - // Sanity checks - if (key < 0 || key >= NzKeyboard::Count || keysym == 0) - NazaraWarning("Key " + NzString::Number(key) + " is not handled in NzKeyboard"); - - return keysym; - } -} - -NzString NzEventImpl::GetKeyName(NzKeyboard::Key key) -{ - KeySym keySym = GetKeySym(key); - - // XKeysymToString returns a static area. - return XKeysymToString(keySym); -} - -NzVector2i NzEventImpl::GetMousePosition() -{ - NzScopedXCBConnection connection; - - NzScopedXCB error(nullptr); - - NzScopedXCB pointer( - xcb_query_pointer_reply( - connection, - xcb_query_pointer( - connection, - X11::XCBDefaultRootWindow(connection) - ), - &error - ) - ); - - if (error) - { - NazaraError("Failed to query pointer"); - return NzVector2i(-1, -1); } - return NzVector2i(pointer->root_x, pointer->root_y); -} - -NzVector2i NzEventImpl::GetMousePosition(const NzWindow& relativeTo) -{ - NzWindowHandle handle = relativeTo.GetHandle(); - if (handle) + String EventImpl::GetKeyName(Keyboard::Key key) { - // Open a connection with the X server - NzScopedXCBConnection connection; + KeySym keySym = GetKeySym(key); - NzScopedXCB error(nullptr); + // XKeysymToString returns a static area. + return XKeysymToString(keySym); + } - NzScopedXCB pointer( + Vector2i EventImpl::GetMousePosition() + { + ScopedXCBConnection connection; + + ScopedXCB error(nullptr); + + ScopedXCB pointer( xcb_query_pointer_reply( connection, xcb_query_pointer( connection, - handle + X11::XCBDefaultRootWindow(connection) ), &error ) @@ -229,143 +200,174 @@ NzVector2i NzEventImpl::GetMousePosition(const NzWindow& relativeTo) if (error) { NazaraError("Failed to query pointer"); - return NzVector2i(-1, -1); + return Vector2i(-1, -1); } - return NzVector2i(pointer->win_x, pointer->win_y); + return Vector2i(pointer->root_x, pointer->root_y); } - else + + Vector2i EventImpl::GetMousePosition(const Window& relativeTo) { - NazaraError("No window handle"); - return NzVector2i(-1, -1); + WindowHandle handle = relativeTo.GetHandle(); + if (handle) + { + // Open a connection with the X server + ScopedXCBConnection connection; + + ScopedXCB error(nullptr); + + ScopedXCB pointer( + xcb_query_pointer_reply( + connection, + xcb_query_pointer( + connection, + handle + ), + &error + ) + ); + + if (error) + { + NazaraError("Failed to query pointer"); + return Vector2i(-1, -1); + } + + return Vector2i(pointer->win_x, pointer->win_y); + } + else + { + NazaraError("No window handle"); + return Vector2i(-1, -1); + } } -} -bool NzEventImpl::IsKeyPressed(NzKeyboard::Key key) -{ - NzScopedXCBConnection connection; - - xcb_keysym_t keySym = GetKeySym(key); - - xcb_key_symbols_t* keySymbols = X11::XCBKeySymbolsAlloc(connection); - if (!keySymbols) + bool EventImpl::IsKeyPressed(Keyboard::Key key) { - NazaraError("Failed to alloc key symbols"); - return false; - } + ScopedXCBConnection connection; - NzScopedXCB keyCode = xcb_key_symbols_get_keycode(keySymbols, keySym); - if (!keyCode) - { - NazaraError("Failed to get key code"); - return false; - } - X11::XCBKeySymbolsFree(keySymbols); + xcb_keysym_t keySym = GetKeySym(key); - NzScopedXCB error(nullptr); + xcb_key_symbols_t* keySymbols = X11::XCBKeySymbolsAlloc(connection); + if (!keySymbols) + { + NazaraError("Failed to alloc key symbols"); + return false; + } - // Get the whole keyboard state - NzScopedXCB keymap( - xcb_query_keymap_reply( - connection, - xcb_query_keymap(connection), - &error - ) - ); + ScopedXCB keyCode = xcb_key_symbols_get_keycode(keySymbols, keySym); + if (!keyCode) + { + NazaraError("Failed to get key code"); + return false; + } + X11::XCBKeySymbolsFree(keySymbols); - if (error) - { - NazaraError("Failed to query keymap"); - return false; - } + ScopedXCB error(nullptr); - // Check our keycode - return (keymap->keys[*keyCode.get() / 8] & (1 << (*keyCode.get() % 8))) != 0; -} - -bool NzEventImpl::IsMouseButtonPressed(NzMouse::Button button) -{ - NzScopedXCBConnection connection; - - NzScopedXCB error(nullptr); - - // Get pointer mask - NzScopedXCB pointer( - xcb_query_pointer_reply( - connection, - xcb_query_pointer( + // Get the whole keyboard state + ScopedXCB keymap( + xcb_query_keymap_reply( connection, - X11::XCBDefaultRootWindow(connection) - ), - &error - ) - ); + xcb_query_keymap(connection), + &error + ) + ); - if (error) + if (error) + { + NazaraError("Failed to query keymap"); + return false; + } + + // Check our keycode + return (keymap->keys[*keyCode.get() / 8] & (1 << (*keyCode.get() % 8))) != 0; + } + + bool EventImpl::IsMouseButtonPressed(Mouse::Button button) { - NazaraError("Failed to query pointer"); + ScopedXCBConnection connection; + + ScopedXCB error(nullptr); + + // Get pointer mask + ScopedXCB pointer( + xcb_query_pointer_reply( + connection, + xcb_query_pointer( + connection, + X11::XCBDefaultRootWindow(connection) + ), + &error + ) + ); + + if (error) + { + NazaraError("Failed to query pointer"); + return false; + } + + uint16_t buttons = pointer->mask; + + switch (button) + { + case Mouse::Left: return buttons & XCB_BUTTON_MASK_1; + case Mouse::Right: return buttons & XCB_BUTTON_MASK_3; + case Mouse::Middle: return buttons & XCB_BUTTON_MASK_2; + case Mouse::XButton1: return false; // not supported by X + case Mouse::XButton2: return false; // not supported by X + } + + NazaraError("Mouse button not supported."); return false; } - uint16_t buttons = pointer->mask; - - switch (button) + void EventImpl::SetMousePosition(int x, int y) { - case NzMouse::Left: return buttons & XCB_BUTTON_MASK_1; - case NzMouse::Right: return buttons & XCB_BUTTON_MASK_3; - case NzMouse::Middle: return buttons & XCB_BUTTON_MASK_2; - case NzMouse::XButton1: return false; // not supported by X - case NzMouse::XButton2: return false; // not supported by X - } + ScopedXCBConnection connection; - NazaraError("Mouse button not supported."); - return false; -} + xcb_window_t root = X11::XCBDefaultRootWindow(connection); -void NzEventImpl::SetMousePosition(int x, int y) -{ - NzScopedXCBConnection connection; - - xcb_window_t root = X11::XCBDefaultRootWindow(connection); - - if (!X11::CheckCookie( - connection, - xcb_warp_pointer( - connection, - None, // Source window - root, // Destination window - 0, 0, // Source position - 0, 0, // Source size - x, y // Destination position - )) - ) - NazaraError("Failed to set mouse position"); - - xcb_flush(connection); -} - -void NzEventImpl::SetMousePosition(int x, int y, const NzWindow& relativeTo) -{ - NzScopedXCBConnection connection; - - NzWindowHandle handle = relativeTo.GetHandle(); - if (handle) - { if (!X11::CheckCookie( connection, xcb_warp_pointer( connection, - None, // Source window - handle, // Destination window - 0, 0, // Source position - 0, 0, // Source size - x, y // Destination position + None, // Source window + root, // Destination window + 0, 0, // Source position + 0, 0, // Source size + x, y // Destination position )) ) - NazaraError("Failed to set mouse position relative to window"); + NazaraError("Failed to set mouse position"); xcb_flush(connection); } - else - NazaraError("No window handle"); + + void EventImpl::SetMousePosition(int x, int y, const Window& relativeTo) + { + ScopedXCBConnection connection; + + WindowHandle handle = relativeTo.GetHandle(); + if (handle) + { + if (!X11::CheckCookie( + connection, + xcb_warp_pointer( + connection, + None, // Source window + handle, // Destination window + 0, 0, // Source position + 0, 0, // Source size + x, y // Destination position + )) + ) + NazaraError("Failed to set mouse position relative to window"); + + xcb_flush(connection); + } + else + NazaraError("No window handle"); + } } diff --git a/src/Nazara/Utility/X11/InputImpl.hpp b/src/Nazara/Utility/X11/InputImpl.hpp index e99726740..608585b1e 100644 --- a/src/Nazara/Utility/X11/InputImpl.hpp +++ b/src/Nazara/Utility/X11/InputImpl.hpp @@ -7,21 +7,25 @@ #ifndef NAZARA_INPUTIMPL_HPP #define NAZARA_INPUTIMPL_HPP +#include #include #include #include #include -class NzEventImpl +namespace Nz { - public: - static NzString GetKeyName(NzKeyboard::Key key); - static NzVector2i GetMousePosition(); - static NzVector2i GetMousePosition(const NzWindow& relativeTo); - static bool IsKeyPressed(NzKeyboard::Key key); - static bool IsMouseButtonPressed(NzMouse::Button button); - static void SetMousePosition(int x, int y); - static void SetMousePosition(int x, int y, const NzWindow& relativeTo); -}; + class EventImpl + { + public: + static String GetKeyName(Keyboard::Key key); + static Vector2i GetMousePosition(); + static Vector2i GetMousePosition(const Window& relativeTo); + static bool IsKeyPressed(Keyboard::Key key); + static bool IsMouseButtonPressed(Mouse::Button button); + static void SetMousePosition(int x, int y); + static void SetMousePosition(int x, int y, const Window& relativeTo); + }; +} #endif // NAZARA_INPUTIMPL_HPP diff --git a/src/Nazara/Utility/X11/ScopedXCB.cpp b/src/Nazara/Utility/X11/ScopedXCB.cpp index 296213e79..49bd76b26 100644 --- a/src/Nazara/Utility/X11/ScopedXCB.cpp +++ b/src/Nazara/Utility/X11/ScopedXCB.cpp @@ -8,189 +8,192 @@ #include #include -/*********************************************** - NzScopedXCBConnection -***********************************************/ - -NzScopedXCBConnection::NzScopedXCBConnection() : -m_connection(nullptr) +namespace Nz { - m_connection = X11::OpenConnection(); -} + /*********************************************** + ScopedXCBConnection + ***********************************************/ -NzScopedXCBConnection::~NzScopedXCBConnection() -{ - X11::CloseConnection(m_connection); -} + ScopedXCBConnection::ScopedXCBConnection() : + m_connection(nullptr) + { + m_connection = X11::OpenConnection(); + } -NzScopedXCBConnection::operator xcb_connection_t*() const -{ - return m_connection; -} + ScopedXCBConnection::~ScopedXCBConnection() + { + X11::CloseConnection(m_connection); + } -/*********************************************** - NzScopedXCBEWMHConnection -***********************************************/ + ScopedXCBConnection::operator xcb_connection_t*() const + { + return m_connection; + } -NzScopedXCBEWMHConnection::NzScopedXCBEWMHConnection(xcb_connection_t* connection) : -m_ewmhConnection(nullptr) -{ - m_ewmhConnection = X11::OpenEWMHConnection(connection); -} + /*********************************************** + ScopedXCBEWMHConnection + ***********************************************/ -NzScopedXCBEWMHConnection::~NzScopedXCBEWMHConnection() -{ - X11::CloseEWMHConnection(m_ewmhConnection); -} + ScopedXCBEWMHConnection::ScopedXCBEWMHConnection(xcb_connection_t* connection) : + m_ewmhConnection(nullptr) + { + m_ewmhConnection = X11::OpenEWMHConnection(connection); + } -xcb_ewmh_connection_t* NzScopedXCBEWMHConnection::operator ->() const -{ - return m_ewmhConnection; -} + ScopedXCBEWMHConnection::~ScopedXCBEWMHConnection() + { + X11::CloseEWMHConnection(m_ewmhConnection); + } -NzScopedXCBEWMHConnection::operator xcb_ewmh_connection_t*() const -{ - return m_ewmhConnection; -} + xcb_ewmh_connection_t* ScopedXCBEWMHConnection::operator ->() const + { + return m_ewmhConnection; + } -/*********************************************** - NzXCBGContext -***********************************************/ + ScopedXCBEWMHConnection::operator xcb_ewmh_connection_t*() const + { + return m_ewmhConnection; + } -NzXCBGContext::NzXCBGContext(xcb_connection_t* connection) : -m_connection(connection), -m_gcontext(XCB_NONE) -{ - NazaraAssert(connection, "Connection must have been established"); -} + /*********************************************** + XCBGContext + ***********************************************/ -NzXCBGContext::~NzXCBGContext() -{ - Destroy(); -} + XCBGContext::XCBGContext(xcb_connection_t* connection) : + m_connection(connection), + m_gcontext(XCB_NONE) + { + NazaraAssert(connection, "Connection must have been established"); + } -bool NzXCBGContext::Create(xcb_drawable_t drawable, uint32_t value_mask, const uint32_t* value_list) -{ - NazaraAssert(m_gcontext == XCB_NONE, "Context must have been destroyed before or just created"); + XCBGContext::~XCBGContext() + { + Destroy(); + } - m_gcontext = xcb_generate_id(m_connection); + bool XCBGContext::Create(xcb_drawable_t drawable, uint32_t value_mask, const uint32_t* value_list) + { + NazaraAssert(m_gcontext == XCB_NONE, "Context must have been destroyed before or just created"); - return X11::CheckCookie( - m_connection, - xcb_create_gc( + m_gcontext = xcb_generate_id(m_connection); + + return X11::CheckCookie( + m_connection, + xcb_create_gc( + m_connection, + m_gcontext, + drawable, + value_mask, + value_list + )); + } + + void XCBGContext::Destroy() + { + if (m_gcontext == XCB_NONE) + return; + + if (!X11::CheckCookie( + m_connection, + xcb_free_gc( + m_connection, + m_gcontext + )) + ) + NazaraError("Failed to free gcontext"); + + m_gcontext = XCB_NONE; + } + + XCBGContext::operator xcb_gcontext_t() const + { + return m_gcontext; + } + + /*********************************************** + XCBPixmap + ***********************************************/ + + XCBPixmap::XCBPixmap() : + m_connection(nullptr), + m_pixmap(XCB_NONE) + { + } + + XCBPixmap::XCBPixmap(xcb_connection_t* connection) : + m_connection(connection), + m_pixmap(XCB_NONE) + { + } + + XCBPixmap::~XCBPixmap() + { + Destroy(); + } + + void XCBPixmap::Connect(xcb_connection_t* connection) + { + NazaraAssert(connection && !m_connection, "Connection must be established"); + + m_connection = connection; + } + + bool XCBPixmap::Create(uint8_t depth, xcb_drawable_t drawable, uint16_t width, uint16_t height) + { + NazaraAssert(m_pixmap == XCB_NONE, "Pixmap must have been destroyed before or just created"); + + m_pixmap = xcb_generate_id(m_connection); + + return X11::CheckCookie( + m_connection, + xcb_create_pixmap( + m_connection, + depth, + m_pixmap, + drawable, + width, + height + )); + } + + bool XCBPixmap::CreatePixmapFromBitmapData(xcb_drawable_t drawable, uint8_t* data, uint32_t width, uint32_t height, uint32_t depth, uint32_t fg, uint32_t bg, xcb_gcontext_t* gcp) + { + NazaraAssert(m_pixmap == XCB_NONE, "Pixmap must have been destroyed before or just created"); + + m_pixmap = xcb_create_pixmap_from_bitmap_data( m_connection, - m_gcontext, - drawable, - value_mask, - value_list - )); -} - -void NzXCBGContext::Destroy() -{ - if (m_gcontext == XCB_NONE) - return; - - if (!X11::CheckCookie( - m_connection, - xcb_free_gc( - m_connection, - m_gcontext - )) - ) - NazaraError("Failed to free gcontext"); - - m_gcontext = XCB_NONE; -} - -NzXCBGContext::operator xcb_gcontext_t() const -{ - return m_gcontext; -} - -/*********************************************** - NzXCBPixmap -***********************************************/ - -NzXCBPixmap::NzXCBPixmap() : -m_connection(nullptr), -m_pixmap(XCB_NONE) -{ -} - -NzXCBPixmap::NzXCBPixmap(xcb_connection_t* connection) : -m_connection(connection), -m_pixmap(XCB_NONE) -{ -} - -NzXCBPixmap::~NzXCBPixmap() -{ - Destroy(); -} - -void NzXCBPixmap::Connect(xcb_connection_t* connection) -{ - NazaraAssert(connection && !m_connection, "Connection must be established"); - - m_connection = connection; -} - -bool NzXCBPixmap::Create(uint8_t depth, xcb_drawable_t drawable, uint16_t width, uint16_t height) -{ - NazaraAssert(m_pixmap == XCB_NONE, "Pixmap must have been destroyed before or just created"); - - m_pixmap = xcb_generate_id(m_connection); - - return X11::CheckCookie( - m_connection, - xcb_create_pixmap( - m_connection, - depth, - m_pixmap, drawable, + data, width, - height - )); -} + height, + depth, + fg, + bg, + gcp + ); -bool NzXCBPixmap::CreatePixmapFromBitmapData(xcb_drawable_t drawable, uint8_t* data, uint32_t width, uint32_t height, uint32_t depth, uint32_t fg, uint32_t bg, xcb_gcontext_t* gcp) -{ - NazaraAssert(m_pixmap == XCB_NONE, "Pixmap must have been destroyed before or just created"); + return m_pixmap != XCB_NONE; + } - m_pixmap = xcb_create_pixmap_from_bitmap_data( - m_connection, - drawable, - data, - width, - height, - depth, - fg, - bg, - gcp - ); + void XCBPixmap::Destroy() + { + if (m_pixmap == XCB_NONE) + return; - return m_pixmap != XCB_NONE; -} - -void NzXCBPixmap::Destroy() -{ - if (m_pixmap == XCB_NONE) - return; - - if (!X11::CheckCookie( - m_connection, - xcb_free_pixmap( + if (!X11::CheckCookie( m_connection, - m_pixmap - )) - ) - NazaraError("Failed to free pixmap"); + xcb_free_pixmap( + m_connection, + m_pixmap + )) + ) + NazaraError("Failed to free pixmap"); - m_pixmap = XCB_NONE; -} + m_pixmap = XCB_NONE; + } -NzXCBPixmap::operator xcb_pixmap_t() const -{ - return m_pixmap; + XCBPixmap::operator xcb_pixmap_t() const + { + return m_pixmap; + } } diff --git a/src/Nazara/Utility/X11/ScopedXCB.hpp b/src/Nazara/Utility/X11/ScopedXCB.hpp index 35ef9009b..452379bc4 100644 --- a/src/Nazara/Utility/X11/ScopedXCB.hpp +++ b/src/Nazara/Utility/X11/ScopedXCB.hpp @@ -7,88 +7,93 @@ #ifndef NAZARA_SCOPEDXCB_HPP #define NAZARA_SCOPEDXCB_HPP +#include +#include #include -class NzScopedXCBConnection +namespace Nz { - public: - NzScopedXCBConnection(); - ~NzScopedXCBConnection(); + class ScopedXCBConnection + { + public: + ScopedXCBConnection(); + ~ScopedXCBConnection(); - operator xcb_connection_t*() const; + operator xcb_connection_t*() const; - private: - xcb_connection_t* m_connection; -}; + private: + xcb_connection_t* m_connection; + }; -class NzScopedXCBEWMHConnection -{ - public: - NzScopedXCBEWMHConnection(xcb_connection_t* connection); - ~NzScopedXCBEWMHConnection(); + class ScopedXCBEWMHConnection + { + public: + ScopedXCBEWMHConnection(xcb_connection_t* connection); + ~ScopedXCBEWMHConnection(); - xcb_ewmh_connection_t* operator ->() const; + xcb_ewmh_connection_t* operator ->() const; - operator xcb_ewmh_connection_t*() const; + operator xcb_ewmh_connection_t*() const; - private: - xcb_ewmh_connection_t* m_ewmhConnection; -}; + private: + xcb_ewmh_connection_t* m_ewmhConnection; + }; -template -class NzScopedXCB -{ - public: - NzScopedXCB(T* pointer); - ~NzScopedXCB(); + template + class ScopedXCB + { + public: + ScopedXCB(T* pointer); + ~ScopedXCB(); - T* operator ->() const; - T** operator &(); + T* operator ->() const; + T** operator &(); - operator bool() const; + operator bool() const; - T* get() const; + T* get() const; - private: - T* m_pointer; -}; + private: + T* m_pointer; + }; -class NzXCBGContext -{ - public: - NzXCBGContext(xcb_connection_t* connection); - ~NzXCBGContext(); + class XCBGContext + { + public: + XCBGContext(xcb_connection_t* connection); + ~XCBGContext(); - bool Create(xcb_drawable_t drawable, uint32_t value_mask, const uint32_t* value_list); + bool Create(xcb_drawable_t drawable, uint32_t value_mask, const uint32_t* value_list); - void Destroy(); + void Destroy(); - operator xcb_gcontext_t() const; + operator xcb_gcontext_t() const; - private: - xcb_connection_t* m_connection; - xcb_gcontext_t m_gcontext; -}; + private: + xcb_connection_t* m_connection; + xcb_gcontext_t m_gcontext; + }; -class NzXCBPixmap -{ - public: - NzXCBPixmap(); - NzXCBPixmap(xcb_connection_t* connection); - ~NzXCBPixmap(); + class XCBPixmap + { + public: + XCBPixmap(); + XCBPixmap(xcb_connection_t* connection); + ~XCBPixmap(); - void Connect(xcb_connection_t* connection); - bool Create(uint8_t depth, xcb_drawable_t drawable, uint16_t width, uint16_t height); - bool CreatePixmapFromBitmapData(xcb_drawable_t drawable, uint8_t* data, uint32_t width, uint32_t height, uint32_t depth, uint32_t fg, uint32_t bg, xcb_gcontext_t* gcp); + void Connect(xcb_connection_t* connection); + bool Create(uint8_t depth, xcb_drawable_t drawable, uint16_t width, uint16_t height); + bool CreatePixmapFromBitmapData(xcb_drawable_t drawable, uint8_t* data, uint32_t width, uint32_t height, uint32_t depth, uint32_t fg, uint32_t bg, xcb_gcontext_t* gcp); - void Destroy(); + void Destroy(); - operator xcb_pixmap_t() const; + operator xcb_pixmap_t() const; - private: - xcb_connection_t* m_connection; - xcb_pixmap_t m_pixmap; -}; + private: + xcb_connection_t* m_connection; + xcb_pixmap_t m_pixmap; + }; +} #include diff --git a/src/Nazara/Utility/X11/VideoModeImpl.cpp b/src/Nazara/Utility/X11/VideoModeImpl.cpp index dcdec7f97..e0b9a5ce7 100644 --- a/src/Nazara/Utility/X11/VideoModeImpl.cpp +++ b/src/Nazara/Utility/X11/VideoModeImpl.cpp @@ -10,156 +10,159 @@ #include #include -NzVideoMode NzVideoModeImpl::GetDesktopMode() +namespace Nz { - NzVideoMode desktopMode; - - NzScopedXCBConnection connection; - - // Retrieve the default screen - xcb_screen_t* screen = X11::XCBDefaultScreen(connection); - - NzScopedXCB error(nullptr); - - // Check if the RandR extension is present - const xcb_query_extension_reply_t* randrExt = xcb_get_extension_data(connection, &xcb_randr_id); - - if (!randrExt || !randrExt->present) + VideoMode VideoModeImpl::GetDesktopMode() { - // Randr extension is not supported: we cannot get the video modes - NazaraError("Failed to use the RandR extension while trying to get the desktop video mode"); - return desktopMode; - } + VideoMode desktopMode; - // Load RandR and check its version - NzScopedXCB randrVersion(xcb_randr_query_version_reply( - connection, - xcb_randr_query_version( - connection, - 1, - 1 - ), - &error - )); + ScopedXCBConnection connection; - if (error) - { - NazaraError("Failed to load the RandR extension while trying to get the desktop video mode"); - return desktopMode; - } + // Retrieve the default screen + xcb_screen_t* screen = X11::XCBDefaultScreen(connection); - // Get the current configuration - NzScopedXCB config(xcb_randr_get_screen_info_reply( - connection, - xcb_randr_get_screen_info( - connection, - screen->root - ), - &error - )); + ScopedXCB error(nullptr); - if (error) - { - // Failed to get the screen configuration - NazaraError("Failed to retrieve the screen configuration while trying to get the desktop video mode"); - return desktopMode; - } + // Check if the RandR extension is present + const xcb_query_extension_reply_t* randrExt = xcb_get_extension_data(connection, &xcb_randr_id); - // Get the current video mode - xcb_randr_mode_t currentMode = config->sizeID; - - // Get the available screen sizes - int nbSizes = xcb_randr_get_screen_info_sizes_length(config.get()); - xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get()); - if (sizes && (nbSizes > 0)) - { - desktopMode = NzVideoMode(sizes[currentMode].width, sizes[currentMode].height, screen->root_depth); - - if (config->rotation == XCB_RANDR_ROTATION_ROTATE_90 || - config->rotation == XCB_RANDR_ROTATION_ROTATE_270) - std::swap(desktopMode.width, desktopMode.height); - } - else - { - NazaraError("Failed to retrieve any screen sizes while trying to get the desktop video mode"); - } - - return desktopMode; -} - -void NzVideoModeImpl::GetFullscreenModes(std::vector& modes) -{ - NzScopedXCBConnection connection; - - // Retrieve the default screen - xcb_screen_t* screen = X11::XCBDefaultScreen(connection); - - NzScopedXCB error(nullptr); - - const xcb_query_extension_reply_t* randrExt = xcb_get_extension_data(connection, &xcb_randr_id); - - if (!randrExt || !randrExt->present) - { - // Randr extension is not supported: we cannot get the video modes - NazaraError("Failed to use the RandR extension while trying to get the supported video modes"); - return; - } - - // Load RandR and check its version - NzScopedXCB randrVersion(xcb_randr_query_version_reply( - connection, - xcb_randr_query_version( - connection, - 1, - 1 - ), - &error - )); - - if (error) - { - NazaraError("Failed to load the RandR extension while trying to get the supported video modes"); - return; - } - - // Get the current configuration - NzScopedXCB config(xcb_randr_get_screen_info_reply( - connection, - xcb_randr_get_screen_info( - connection, - screen->root - ), - &error - )); - - if (error) - { - // Failed to get the screen configuration - NazaraError("Failed to retrieve the screen configuration while trying to get the supported video modes"); - return; - } - - // Get the available screen sizes - xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get()); - if (sizes && (config->nSizes > 0)) - { - // Get the list of supported depths - xcb_depth_iterator_t iter = xcb_screen_allowed_depths_iterator(screen); - // Combine depths and sizes to fill the array of supported modes - for (; iter.rem; xcb_depth_next(&iter)) + if (!randrExt || !randrExt->present) { - for (int j = 0; j < config->nSizes; ++j) + // Randr extension is not supported: we cannot get the video modes + NazaraError("Failed to use the RandR extension while trying to get the desktop video mode"); + return desktopMode; + } + + // Load RandR and check its version + ScopedXCB randrVersion(xcb_randr_query_version_reply( + connection, + xcb_randr_query_version( + connection, + 1, + 1 + ), + &error + )); + + if (error) + { + NazaraError("Failed to load the RandR extension while trying to get the desktop video mode"); + return desktopMode; + } + + // Get the current configuration + ScopedXCB config(xcb_randr_get_screen_info_reply( + connection, + xcb_randr_get_screen_info( + connection, + screen->root + ), + &error + )); + + if (error) + { + // Failed to get the screen configuration + NazaraError("Failed to retrieve the screen configuration while trying to get the desktop video mode"); + return desktopMode; + } + + // Get the current video mode + xcb_randr_mode_t currentMode = config->sizeID; + + // Get the available screen sizes + int nbSizes = xcb_randr_get_screen_info_sizes_length(config.get()); + xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get()); + if (sizes && (nbSizes > 0)) + { + desktopMode = VideoMode(sizes[currentMode].width, sizes[currentMode].height, screen->root_depth); + + if (config->rotation == XCB_RANDR_ROTATION_ROTATE_90 || + config->rotation == XCB_RANDR_ROTATION_ROTATE_270) + std::swap(desktopMode.width, desktopMode.height); + } + else + { + NazaraError("Failed to retrieve any screen sizes while trying to get the desktop video mode"); + } + + return desktopMode; + } + + void VideoModeImpl::GetFullscreenModes(std::vector& modes) + { + ScopedXCBConnection connection; + + // Retrieve the default screen + xcb_screen_t* screen = X11::XCBDefaultScreen(connection); + + ScopedXCB error(nullptr); + + const xcb_query_extension_reply_t* randrExt = xcb_get_extension_data(connection, &xcb_randr_id); + + if (!randrExt || !randrExt->present) + { + // Randr extension is not supported: we cannot get the video modes + NazaraError("Failed to use the RandR extension while trying to get the supported video modes"); + return; + } + + // Load RandR and check its version + ScopedXCB randrVersion(xcb_randr_query_version_reply( + connection, + xcb_randr_query_version( + connection, + 1, + 1 + ), + &error + )); + + if (error) + { + NazaraError("Failed to load the RandR extension while trying to get the supported video modes"); + return; + } + + // Get the current configuration + ScopedXCB config(xcb_randr_get_screen_info_reply( + connection, + xcb_randr_get_screen_info( + connection, + screen->root + ), + &error + )); + + if (error) + { + // Failed to get the screen configuration + NazaraError("Failed to retrieve the screen configuration while trying to get the supported video modes"); + return; + } + + // Get the available screen sizes + xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get()); + if (sizes && (config->nSizes > 0)) + { + // Get the list of supported depths + xcb_depth_iterator_t iter = xcb_screen_allowed_depths_iterator(screen); + // Combine depths and sizes to fill the array of supported modes + for (; iter.rem; xcb_depth_next(&iter)) { - // Convert to VideoMode - NzVideoMode mode(sizes[j].width, sizes[j].height, iter.data->depth); + for (int j = 0; j < config->nSizes; ++j) + { + // Convert to VideoMode + VideoMode mode(sizes[j].width, sizes[j].height, iter.data->depth); - if (config->rotation == XCB_RANDR_ROTATION_ROTATE_90 || - config->rotation == XCB_RANDR_ROTATION_ROTATE_270) - std::swap(mode.width, mode.height); + if (config->rotation == XCB_RANDR_ROTATION_ROTATE_90 || + config->rotation == XCB_RANDR_ROTATION_ROTATE_270) + std::swap(mode.width, mode.height); - // Add it only if it is not already in the array - if (std::find(modes.begin(), modes.end(), mode) == modes.end()) - modes.push_back(mode); + // Add it only if it is not already in the array + if (std::find(modes.begin(), modes.end(), mode) == modes.end()) + modes.push_back(mode); + } } } } diff --git a/src/Nazara/Utility/X11/VideoModeImpl.hpp b/src/Nazara/Utility/X11/VideoModeImpl.hpp index 3a53f5e94..2e63e8a09 100644 --- a/src/Nazara/Utility/X11/VideoModeImpl.hpp +++ b/src/Nazara/Utility/X11/VideoModeImpl.hpp @@ -7,13 +7,17 @@ #ifndef NAZARA_VIDEOMODEIMPL_HPP #define NAZARA_VIDEOMODEIMPL_HPP +#include #include -class NzVideoModeImpl +namespace Nz { - public: - static NzVideoMode GetDesktopMode(); - static void GetFullscreenModes(std::vector& modes); -}; + class VideoModeImpl + { + public: + static VideoMode GetDesktopMode(); + static void GetFullscreenModes(std::vector& modes); + }; +} #endif // NNAZARA_VIDEOMODEIMPL_HPP diff --git a/src/Nazara/Utility/X11/WindowImpl.cpp b/src/Nazara/Utility/X11/WindowImpl.cpp index 4087ba58d..ecb8f1cc4 100644 --- a/src/Nazara/Utility/X11/WindowImpl.cpp +++ b/src/Nazara/Utility/X11/WindowImpl.cpp @@ -23,1555 +23,1564 @@ #include /* - Icon working sometimes - EnableKeyRepeat (Working but is it the right behaviour ?) - Fullscreen (No alt + tab) - Smooth scroll (???) - Thread (Not tested a lot) - Event listener // ? - Cleanup // Done ? + Things to do left: + + Icon working sometimes (No idea) + EnableKeyRepeat (Working but is it the right behaviour ?) + Fullscreen (No alt + tab) + Smooth scroll (No equivalent for X11) + Threaded window (Not tested a lot) + Event listener (Not tested) + Cleanup + IsVisible (Not working as expected) + SetStayOnTop (Equivalent for X11 ?) + Opengl Context (glXCreateContextAttribs should be loaded like in window and the version for the context should be the one of NzContextParameters) + */ -namespace +namespace Nz { - NzWindowImpl* fullscreenWindow = nullptr; - - const uint32_t eventMask = XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_BUTTON_PRESS | - XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_MOTION | - XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_KEY_PRESS | - XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW; - - xcb_cursor_t hiddenCursor = 0; - - xcb_connection_t* connection = nullptr; - - void CreateHiddenCursor() + namespace { - NzXCBPixmap cursorPixmap(connection); + Nz::WindowImpl* fullscreenWindow = nullptr; - xcb_window_t window = X11::XCBDefaultRootWindow(connection); + const uint32_t eventMask = XCB_EVENT_MASK_FOCUS_CHANGE | XCB_EVENT_MASK_BUTTON_PRESS | + XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_BUTTON_MOTION | + XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_KEY_PRESS | + XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | + XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW; - if (!cursorPixmap.Create( - 1, - window, - 1, - 1 - )) + xcb_cursor_t hiddenCursor = 0; + + xcb_connection_t* connection = nullptr; + + void CreateHiddenCursor() { - NazaraError("Failed to create pixmap for hidden cursor"); - return; - } + XCBPixmap cursorPixmap(connection); - hiddenCursor = xcb_generate_id(connection); + xcb_window_t window = X11::XCBDefaultRootWindow(connection); - // Create the cursor, using the pixmap as both the shape and the mask of the cursor - if (!X11::CheckCookie( - connection, - xcb_create_cursor( - connection, - hiddenCursor, - cursorPixmap, - cursorPixmap, - 0, 0, 0, // Foreground RGB color - 0, 0, 0, // Background RGB color - 0, // X - 0 // Y - )) - ) - NazaraError("Failed to create hidden cursor"); - } -} + if (!cursorPixmap.Create( + 1, + window, + 1, + 1 + )) + { + NazaraError("Failed to create pixmap for hidden cursor"); + return; + } -NzWindowImpl::NzWindowImpl(NzWindow* parent) : -m_window(0), -m_style(0), -m_parent(parent), -m_smoothScrolling(false), -m_scrolling(0), -m_mousePos(0, 0), -m_keyRepeat(true) -{ - std::memset(&m_size_hints, 0, sizeof(m_size_hints)); -} - -NzWindowImpl::~NzWindowImpl() -{ - // Cleanup graphical resources - CleanUp(); - - // We clean up the event queue - UpdateEventQueue(nullptr); - UpdateEventQueue(nullptr); -} - -bool NzWindowImpl::Create(const NzVideoMode& mode, const NzString& title, nzUInt32 style) -{ - bool fullscreen = (style & nzWindowStyle_Fullscreen) != 0; - m_eventListener = true; - m_ownsWindow = true; - m_style = style; - - std::memset(&m_oldVideoMode, 0, sizeof(m_oldVideoMode)); - - m_screen = X11::XCBDefaultScreen(connection); - - // Compute position and size - int left = fullscreen ? 0 : (m_screen->width_in_pixels - mode.width) / 2; - int top = fullscreen ? 0 : (m_screen->height_in_pixels - mode.height) / 2; - int width = mode.width; - int height = mode.height; - - // Define the window attributes - xcb_colormap_t colormap = xcb_generate_id(connection); - xcb_create_colormap(connection, XCB_COLORMAP_ALLOC_NONE, colormap, m_screen->root, m_screen->root_visual); - const uint32_t value_list[] = { fullscreen, eventMask, colormap }; - - NzCallOnExit onExit([&](){ - if (!X11::CheckCookie( - connection, - xcb_free_colormap( - connection, - colormap - )) - ) - NazaraError("Failed to free colormap"); - }); - - // Create the window - m_window = xcb_generate_id(connection); - - if (!X11::CheckCookie( - connection, - xcb_create_window_checked( - connection, - XCB_COPY_FROM_PARENT, - m_window, - m_screen->root, - left, top, - width, height, - 0, - XCB_WINDOW_CLASS_INPUT_OUTPUT, - m_screen->root_visual, - XCB_CW_EVENT_MASK | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_COLORMAP, - value_list - ))) - { - NazaraError("Failed to create window"); - return false; - } - - // Flush the commands queue - xcb_flush(connection); - - // We get default normal hints for the new window - NzScopedXCB error(nullptr); - xcb_icccm_get_wm_normal_hints_reply( - connection, - xcb_icccm_get_wm_normal_hints( - connection, - m_window), - &m_size_hints, - &error - ); - if (error) - NazaraError("Failed to get size hints"); - - // And we modify the size and the position. - xcb_icccm_size_hints_set_position(&m_size_hints, false, left, top); - xcb_icccm_size_hints_set_size(&m_size_hints, false, width, height); - if (!UpdateNormalHints()) - NazaraError("Failed to set window configuration"); - - // Do some common initializations - CommonInitialize(); - - if (!(m_style & nzWindowStyle_Fullscreen)) - SetMotifHints(); - - // Flush the commands queue - xcb_flush(connection); - - // Set the window's name - SetTitle(title); - - #if NAZARA_UTILITY_THREADED_WINDOW - NzMutex mutex; - NzConditionVariable condition; - m_threadActive = true; - - // We wait that thread is well launched - mutex.Lock(); - m_thread = NzThread(WindowThread, this, &mutex, &condition); - condition.Wait(&mutex); - mutex.Unlock(); - #endif - - // Set fullscreen video mode and switch to fullscreen if necessary - if (fullscreen) - { - SetPosition(0, 0); - SetVideoMode(mode); - SwitchToFullscreen(); - } - - return true; -} - -bool NzWindowImpl::Create(NzWindowHandle handle) -{ - std::memset(&m_oldVideoMode, 0, sizeof(m_oldVideoMode)); - - m_screen = X11::XCBDefaultScreen(connection); - - if (!handle) - { - NazaraError("Invalid handle"); - return false; - } - - // Save the window handle - m_window = handle; - - m_ownsWindow = false; - m_eventListener = false; - - NzScopedXCB error(nullptr); - - // We try to get informations from the shared window. - xcb_icccm_get_wm_normal_hints_reply( - connection, - xcb_icccm_get_wm_normal_hints( - connection, - m_window), - &m_size_hints, - &error - ); - - if (error) - { - NazaraError("Failed to obtain sizes and positions"); - return false; - } - - // Do some common initializations - CommonInitialize(); - - // Flush the commands queue - xcb_flush(connection); - - return true; -} - -void NzWindowImpl::Destroy() -{ - if (m_ownsWindow) - { - #if NAZARA_UTILITY_THREADED_WINDOW - if (m_thread.IsJoinable()) - { - m_threadActive = false; - m_thread.Join(); - } - #else - // Destroy the window - if (m_window && m_ownsWindow) - { - // Unhide the mouse cursor (in case it was hidden) - SetCursor(nzWindowCursor_Default); + hiddenCursor = xcb_generate_id(connection); + // Create the cursor, using the pixmap as both the shape and the mask of the cursor if (!X11::CheckCookie( connection, - xcb_destroy_window( + xcb_create_cursor( connection, - m_window + hiddenCursor, + cursorPixmap, + cursorPixmap, + 0, 0, 0, // Foreground RGB color + 0, 0, 0, // Background RGB color + 0, // X + 0 // Y )) ) - NazaraError("Failed to destroy window"); - - xcb_flush(connection); + NazaraError("Failed to create hidden cursor"); } - #endif - } - else - SetEventListener(false); -} - -void NzWindowImpl::EnableKeyRepeat(bool enable) -{ - m_keyRepeat = enable; -} - -void NzWindowImpl::EnableSmoothScrolling(bool enable) -{ - m_smoothScrolling = enable; -} - -NzWindowHandle NzWindowImpl::GetHandle() const -{ - return m_window; -} - -unsigned int NzWindowImpl::GetHeight() const -{ - return m_size_hints.height; -} - -NzVector2i NzWindowImpl::GetPosition() const -{ - return { m_size_hints.x, m_size_hints.y }; -} - -NzVector2ui NzWindowImpl::GetSize() const -{ - return NzVector2ui(m_size_hints.width, m_size_hints.height); -} - -nzUInt32 NzWindowImpl::GetStyle() const -{ - return m_style; -} - -NzString NzWindowImpl::GetTitle() const -{ - NzScopedXCBEWMHConnection ewmhConnection(connection); - - NzScopedXCB error(nullptr); - - xcb_ewmh_get_utf8_strings_reply_t data; - xcb_ewmh_get_wm_name_reply(ewmhConnection, - xcb_ewmh_get_wm_name(ewmhConnection, m_window), &data, &error); - - if (error) - NazaraError("Failed to get window's title"); - - NzString tmp(data.strings, data.strings_len); - - xcb_ewmh_get_utf8_strings_reply_wipe(&data); - - return tmp; -} - -unsigned int NzWindowImpl::GetWidth() const -{ - return m_size_hints.width; -} - -bool NzWindowImpl::HasFocus() const -{ - NzScopedXCB error(nullptr); - - NzScopedXCB reply(xcb_get_input_focus_reply( - connection, - xcb_get_input_focus_unchecked( - connection - ), - &error - )); - - if (error) - NazaraError("Failed to check if window has focus"); - - return (reply->focus == m_window); -} - -void NzWindowImpl::IgnoreNextMouseEvent(int mouseX, int mouseY) -{ - // Petite astuce ... - m_mousePos.x = mouseX; - m_mousePos.y = mouseY; -} - -bool NzWindowImpl::IsMinimized() const -{ - NzScopedXCBEWMHConnection ewmhConnection(connection); - - NzScopedXCB error(nullptr); - bool isMinimized = false; - - xcb_ewmh_get_atoms_reply_t atomReply; - if (xcb_ewmh_get_wm_state_reply(ewmhConnection, - xcb_ewmh_get_wm_state(ewmhConnection, m_window), &atomReply, &error) == 1) - { - for (unsigned int i = 0; i < atomReply.atoms_len; i++) - if (atomReply.atoms[i] == ewmhConnection->_NET_WM_STATE_HIDDEN) - isMinimized = true; - - xcb_ewmh_get_atoms_reply_wipe(&atomReply); } - if (error) - NazaraError("Failed to determine if window is minimized"); - - return isMinimized; -} - -bool NzWindowImpl::IsVisible() const -{ - return !IsMinimized(); // Visibility event ? -} - -void NzWindowImpl::ProcessEvents(bool block) -{ - if (m_ownsWindow) + WindowImpl::WindowImpl(Window* parent) : + m_window(0), + m_style(0), + m_parent(parent), + m_smoothScrolling(false), + m_scrolling(0), + m_mousePos(0, 0), + m_keyRepeat(true) { - xcb_generic_event_t* event = nullptr; + std::memset(&m_size_hints, 0, sizeof(m_size_hints)); + } - if (block) + WindowImpl::~WindowImpl() + { + // Cleanup graphical resources + CleanUp(); + + // We clean up the event queue + UpdateEventQueue(nullptr); + UpdateEventQueue(nullptr); + } + + bool WindowImpl::Create(const VideoMode& mode, const String& title, UInt32 style) + { + bool fullscreen = (style & Nz::WindowStyle_Fullscreen) != 0; + m_eventListener = true; + m_ownsWindow = true; + m_style = style; + + std::memset(&m_oldVideoMode, 0, sizeof(m_oldVideoMode)); + + m_screen = X11::XCBDefaultScreen(connection); + + // Compute position and size + int left = fullscreen ? 0 : (m_screen->width_in_pixels - mode.width) / 2; + int top = fullscreen ? 0 : (m_screen->height_in_pixels - mode.height) / 2; + int width = mode.width; + int height = mode.height; + + // Define the window attributes + xcb_colormap_t colormap = xcb_generate_id(connection); + xcb_create_colormap(connection, XCB_COLORMAP_ALLOC_NONE, colormap, m_screen->root, m_screen->root_visual); + const uint32_t value_list[] = { fullscreen, eventMask, colormap }; + + CallOnExit onExit([&](){ + if (!X11::CheckCookie( + connection, + xcb_free_colormap( + connection, + colormap + )) + ) + NazaraError("Failed to free colormap"); + }); + + // Create the window + m_window = xcb_generate_id(connection); + + if (!X11::CheckCookie( + connection, + xcb_create_window_checked( + connection, + XCB_COPY_FROM_PARENT, + m_window, + m_screen->root, + left, top, + width, height, + 0, + XCB_WINDOW_CLASS_INPUT_OUTPUT, + m_screen->root_visual, + XCB_CW_EVENT_MASK | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_COLORMAP, + value_list + ))) { - event = xcb_wait_for_event(connection); - if (event) + NazaraError("Failed to create window"); + return false; + } + + // Flush the commands queue + xcb_flush(connection); + + // We get default normal hints for the new window + ScopedXCB error(nullptr); + xcb_icccm_get_wm_normal_hints_reply( + connection, + xcb_icccm_get_wm_normal_hints( + connection, + m_window), + &m_size_hints, + &error + ); + if (error) + NazaraError("Failed to get size hints"); + + // And we modify the size and the position. + xcb_icccm_size_hints_set_position(&m_size_hints, false, left, top); + xcb_icccm_size_hints_set_size(&m_size_hints, false, width, height); + if (!UpdateNormalHints()) + NazaraError("Failed to set window configuration"); + + // Do some common initializations + CommonInitialize(); + + if (!(m_style & Nz::WindowStyle_Fullscreen)) + SetMotifHints(); + + // Flush the commands queue + xcb_flush(connection); + + // Set the window's name + SetTitle(title); + + #if NAZARA_UTILITY_THREADED_WINDOW + Mutex mutex; + ConditionVariable condition; + m_threadActive = true; + + // We wait that thread is well launched + mutex.Lock(); + m_thread = Thread(WindowThread, this, &mutex, &condition); + condition.Wait(&mutex); + mutex.Unlock(); + #endif + + // Set fullscreen video mode and switch to fullscreen if necessary + if (fullscreen) + { + SetPosition(0, 0); + SetVideoMode(mode); + SwitchToFullscreen(); + } + + return true; + } + + bool WindowImpl::Create(WindowHandle handle) + { + std::memset(&m_oldVideoMode, 0, sizeof(m_oldVideoMode)); + + m_screen = X11::XCBDefaultScreen(connection); + + if (!handle) + { + NazaraError("Invalid handle"); + return false; + } + + // Save the window handle + m_window = handle; + + m_ownsWindow = false; + m_eventListener = false; + + ScopedXCB error(nullptr); + + // We try to get informations from the shared window. + xcb_icccm_get_wm_normal_hints_reply( + connection, + xcb_icccm_get_wm_normal_hints( + connection, + m_window), + &m_size_hints, + &error + ); + + if (error) + { + NazaraError("Failed to obtain sizes and positions"); + return false; + } + + // Do some common initializations + CommonInitialize(); + + // Flush the commands queue + xcb_flush(connection); + + return true; + } + + void WindowImpl::Destroy() + { + if (m_ownsWindow) + { + #if NAZARA_UTILITY_THREADED_WINDOW + if (m_thread.IsJoinable()) { - UpdateEventQueue(event); - ProcessEvent(event); + m_threadActive = false; + m_thread.Join(); } + #else + // Destroy the window + if (m_window && m_ownsWindow) + { + // Unhide the mouse cursor (in case it was hidden) + SetCursor(Nz::WindowCursor_Default); + + if (!X11::CheckCookie( + connection, + xcb_destroy_window( + connection, + m_window + )) + ) + NazaraError("Failed to destroy window"); + + xcb_flush(connection); + } + #endif } else - { - event = xcb_poll_for_event(connection); - while (event) - { - UpdateEventQueue(event); - xcb_generic_event_t* tmp = xcb_poll_for_event(connection); - UpdateEventQueue(tmp); - ProcessEvent(event); - if (tmp) - ProcessEvent(tmp); - event = xcb_poll_for_event(connection); - } - } + SetEventListener(false); } -} -void NzWindowImpl::SetCursor(nzWindowCursor windowCursor) -{ - if (windowCursor == nzWindowCursor_None) - SetCursor(hiddenCursor); - else + void WindowImpl::EnableKeyRepeat(bool enable) { - const char* name = ConvertWindowCursorToXName(windowCursor); - - xcb_cursor_context_t* ctx; - if (xcb_cursor_context_new(connection, m_screen, &ctx) >= 0) - { - xcb_cursor_t cursor = xcb_cursor_load_cursor(ctx, name); - SetCursor(cursor); - xcb_free_cursor(connection, cursor); - xcb_cursor_context_free(ctx); - } + m_keyRepeat = enable; } -} -void NzWindowImpl::SetCursor(const NzCursor& cursor) -{ - if (!cursor.IsValid()) + void WindowImpl::EnableSmoothScrolling(bool enable) { - NazaraError("Cursor is not valid"); - return; + m_smoothScrolling = enable; } - SetCursor(cursor.m_impl->GetCursor()); -} - -void NzWindowImpl::SetEventListener(bool listener) -{ - if (m_ownsWindow) - m_eventListener = listener; - else if (listener != m_eventListener) + WindowHandle WindowImpl::GetHandle() const { - if (listener) - { - const uint32_t value_list[] = { eventMask }; - - if (!X11::CheckCookie( - connection, - xcb_change_window_attributes( - connection, - m_window, - XCB_CW_EVENT_MASK, - value_list - )) - ) - NazaraError("Failed to change event for listener"); - - m_eventListener = true; - } - else if (m_eventListener) - { - const uint32_t value_list[] = { XCB_EVENT_MASK_NO_EVENT }; - - if (!X11::CheckCookie( - connection, - xcb_change_window_attributes( - connection, - m_window, - XCB_CW_EVENT_MASK, - value_list - )) - ) - NazaraError("Failed to change event for listener"); - - m_eventListener = false; - } + return m_window; } -} -void NzWindowImpl::SetFocus() -{ - if (!X11::CheckCookie( - connection, - xcb_set_input_focus( + unsigned int WindowImpl::GetHeight() const + { + return m_size_hints.height; + } + + Vector2i WindowImpl::GetPosition() const + { + return { m_size_hints.x, m_size_hints.y }; + } + + Vector2ui WindowImpl::GetSize() const + { + return Vector2ui(m_size_hints.width, m_size_hints.height); + } + + UInt32 WindowImpl::GetStyle() const + { + return m_style; + } + + String WindowImpl::GetTitle() const + { + ScopedXCBEWMHConnection ewmhConnection(connection); + + ScopedXCB error(nullptr); + + xcb_ewmh_get_utf8_strings_reply_t data; + xcb_ewmh_get_wm_name_reply(ewmhConnection, + xcb_ewmh_get_wm_name(ewmhConnection, m_window), &data, &error); + + if (error) + NazaraError("Failed to get window's title"); + + String tmp(data.strings, data.strings_len); + + xcb_ewmh_get_utf8_strings_reply_wipe(&data); + + return tmp; + } + + unsigned int WindowImpl::GetWidth() const + { + return m_size_hints.width; + } + + bool WindowImpl::HasFocus() const + { + ScopedXCB error(nullptr); + + ScopedXCB reply(xcb_get_input_focus_reply( connection, - XCB_INPUT_FOCUS_POINTER_ROOT, - m_window, - XCB_CURRENT_TIME - )) - ) - NazaraError("Failed to set input focus"); - - const uint32_t values[] = { XCB_STACK_MODE_ABOVE }; - - if (!X11::CheckCookie( - connection, - xcb_configure_window( - connection, - m_window, - XCB_CONFIG_WINDOW_STACK_MODE, - values - )) - ) - NazaraError("Failed to set focus"); -} - -void NzWindowImpl::SetIcon(const NzIcon& icon) -{ - if (!icon.IsValid()) - { - NazaraError("Icon is not valid"); - return; - } - - xcb_pixmap_t icon_pixmap = icon.m_impl->GetIcon(); - xcb_pixmap_t mask_pixmap = icon.m_impl->GetMask(); - - NzScopedXCB error(nullptr); - - xcb_icccm_wm_hints_t hints; - std::memset(&hints, 0, sizeof(hints)); - - xcb_icccm_get_wm_hints_reply( - connection, - xcb_icccm_get_wm_hints( - connection, - m_window), - &hints, - &error - ); - - if (error) - NazaraError("Failed to get wm hints"); - - xcb_icccm_wm_hints_set_icon_pixmap(&hints, icon_pixmap); - xcb_icccm_wm_hints_set_icon_mask(&hints, mask_pixmap); - - if (!X11::CheckCookie( - connection, - xcb_icccm_set_wm_hints( - connection, - m_window, - &hints - )) - ) - NazaraError("Failed to set wm hints"); - - xcb_flush(connection); -} - -void NzWindowImpl::SetMaximumSize(int width, int height) -{ - if (width < 0) - width = m_screen->width_in_pixels; - if (height < 0) - height = m_screen->height_in_pixels; - - xcb_icccm_size_hints_set_max_size(&m_size_hints, width, height); - if (!UpdateNormalHints()) - NazaraError("Failed to set maximum size"); - - xcb_flush(connection); -} - -void NzWindowImpl::SetMinimumSize(int width, int height) -{ - xcb_icccm_size_hints_set_min_size(&m_size_hints, width, height); - if (!UpdateNormalHints()) - NazaraError("Failed to set minimum size"); - - xcb_flush(connection); -} - -void NzWindowImpl::SetPosition(int x, int y) -{ - xcb_icccm_size_hints_set_position(&m_size_hints, true, x, y); - if (!UpdateNormalHints()) - NazaraError("Failed to set size hints position"); - - const uint32_t values[] = { static_cast(x), static_cast(y) }; - if (!X11::CheckCookie( - connection, - xcb_configure_window( - connection, - m_window, - XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, - values - )) - ) - NazaraError("Failed to set position"); - - xcb_flush(connection); -} - -void NzWindowImpl::SetSize(unsigned int width, unsigned int height) -{ - xcb_icccm_size_hints_set_size(&m_size_hints, true, width, height); - if (!UpdateNormalHints()) - NazaraError("Failed to set size hints sizes"); - - const uint32_t values[] = { width, height }; - if (!X11::CheckCookie( - connection, - xcb_configure_window( - connection, - m_window, - XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, - values - )) - ) - NazaraError("Failed to set sizes"); - - xcb_flush(connection); -} - -void NzWindowImpl::SetStayOnTop(bool stayOnTop) -{ - NzScopedXCBEWMHConnection ewmhConnection(connection); - - xcb_atom_t onTop; // It is not really working - if (stayOnTop) - onTop = ewmhConnection->_NET_WM_STATE_ABOVE; - else - onTop = ewmhConnection->_NET_WM_STATE_BELOW; - - if (!X11::CheckCookie( - connection, - xcb_ewmh_set_wm_state( - ewmhConnection, - m_window, - 1, - &onTop - )) - ) - NazaraError("Failed to set stay on top"); - - xcb_flush(connection); -} - -void NzWindowImpl::SetTitle(const NzString& title) -{ - NzScopedXCBEWMHConnection ewmhConnection(connection); - - if (!X11::CheckCookie( - connection, - xcb_ewmh_set_wm_name( - ewmhConnection, - m_window, - title.GetSize(), - title.GetConstBuffer() - )) - ) - NazaraError("Failed to set title"); - - xcb_flush(connection); -} - -void NzWindowImpl::SetVisible(bool visible) -{ - if (visible) - { - if (!X11::CheckCookie( - connection, - xcb_map_window( - connection, - m_window - )) - ) - NazaraError("Failed to change window visibility to visible"); - } - else - { - if (!X11::CheckCookie( - connection, - xcb_unmap_window( - connection, - m_window - )) - ) - NazaraError("Failed to change window visibility to invisible"); - } - - xcb_flush(connection); -} - -bool NzWindowImpl::Initialize() -{ - X11::Initialize(); - - connection = X11::OpenConnection(); - - // Create the hidden cursor - CreateHiddenCursor(); - - return true; -} - -void NzWindowImpl::Uninitialize() -{ - // Destroy the cursor - if (hiddenCursor) - { - xcb_free_cursor(connection, hiddenCursor); - hiddenCursor = 0; - } - - X11::CloseConnection(connection); - - X11::Uninitialize(); -} - -void NzWindowImpl::CleanUp() -{ - // Restore the previous video mode (in case we were running in fullscreen) - ResetVideoMode(); -} - -xcb_keysym_t NzWindowImpl::ConvertKeyCodeToKeySym(xcb_keycode_t keycode, uint16_t state) -{ - xcb_key_symbols_t* keysyms = X11::XCBKeySymbolsAlloc(connection); - if (!keysyms) - { - NazaraError("Failed to get key symbols"); - return XCB_NONE; - } - - int col = state & XCB_MOD_MASK_SHIFT ? 1 : 0; - const int altGrOffset = 4; - if (state & XCB_MOD_MASK_5) - col += altGrOffset; - xcb_keysym_t keysym = xcb_key_symbols_get_keysym(keysyms, keycode, col); - if (keysym == XCB_NO_SYMBOL) - keysym = xcb_key_symbols_get_keysym(keysyms, keycode, col ^ 0x1); - X11::XCBKeySymbolsFree(keysyms); - - return keysym; -} - -NzKeyboard::Key NzWindowImpl::ConvertVirtualKey(xcb_keysym_t symbol) -{ - // First convert to uppercase (to avoid dealing with two different keysyms for the same key) - KeySym lower, key; - XConvertCase(symbol, &lower, &key); - - switch (key) - { - // Lettres - case XK_A: return NzKeyboard::A; - case XK_B: return NzKeyboard::B; - case XK_C: return NzKeyboard::C; - case XK_D: return NzKeyboard::D; - case XK_E: return NzKeyboard::E; - case XK_F: return NzKeyboard::F; - case XK_G: return NzKeyboard::G; - case XK_H: return NzKeyboard::H; - case XK_I: return NzKeyboard::I; - case XK_J: return NzKeyboard::J; - case XK_K: return NzKeyboard::K; - case XK_L: return NzKeyboard::L; - case XK_M: return NzKeyboard::M; - case XK_N: return NzKeyboard::N; - case XK_O: return NzKeyboard::O; - case XK_P: return NzKeyboard::P; - case XK_Q: return NzKeyboard::Q; - case XK_R: return NzKeyboard::R; - case XK_S: return NzKeyboard::S; - case XK_T: return NzKeyboard::T; - case XK_U: return NzKeyboard::U; - case XK_V: return NzKeyboard::V; - case XK_W: return NzKeyboard::W; - case XK_X: return NzKeyboard::X; - case XK_Y: return NzKeyboard::Y; - case XK_Z: return NzKeyboard::Z; - - // Touches de fonction - case XK_F1: return NzKeyboard::F1; - case XK_F2: return NzKeyboard::F2; - case XK_F3: return NzKeyboard::F3; - case XK_F4: return NzKeyboard::F4; - case XK_F5: return NzKeyboard::F5; - case XK_F6: return NzKeyboard::F6; - case XK_F7: return NzKeyboard::F7; - case XK_F8: return NzKeyboard::F8; - case XK_F9: return NzKeyboard::F9; - case XK_F10: return NzKeyboard::F10; - case XK_F11: return NzKeyboard::F11; - case XK_F12: return NzKeyboard::F12; - case XK_F13: return NzKeyboard::F13; - case XK_F14: return NzKeyboard::F14; - case XK_F15: return NzKeyboard::F15; - - // Flèches directionnelles - case XK_Down: return NzKeyboard::Down; - case XK_Left: return NzKeyboard::Left; - case XK_Right: return NzKeyboard::Right; - case XK_Up: return NzKeyboard::Up; - - // Pavé numérique - case XK_KP_Add: return NzKeyboard::Add; - case XK_KP_Decimal: return NzKeyboard::Decimal; - case XK_KP_Delete: return NzKeyboard::Decimal; - case XK_KP_Divide: return NzKeyboard::Divide; - case XK_KP_Multiply: return NzKeyboard::Multiply; - case XK_KP_Insert: return NzKeyboard::Numpad0; - case XK_KP_End: return NzKeyboard::Numpad1; - case XK_KP_Down: return NzKeyboard::Numpad2; - case XK_KP_Page_Down: return NzKeyboard::Numpad3; - case XK_KP_Left: return NzKeyboard::Numpad4; - case XK_KP_Begin: return NzKeyboard::Numpad5; - case XK_KP_Right: return NzKeyboard::Numpad6; - case XK_KP_Home: return NzKeyboard::Numpad7; - case XK_KP_Up: return NzKeyboard::Numpad8; - case XK_KP_Page_Up: return NzKeyboard::Numpad9; - case XK_KP_Enter: return NzKeyboard::Return; - case XK_KP_Subtract: return NzKeyboard::Subtract; - - // Divers - case XK_backslash: return NzKeyboard::Backslash; - case XK_BackSpace: return NzKeyboard::Backspace; - case XK_Clear: return NzKeyboard::Clear; - case XK_comma: return NzKeyboard::Comma; - case XK_minus: return NzKeyboard::Dash; - case XK_Delete: return NzKeyboard::Delete; - case XK_End: return NzKeyboard::End; - case XK_equal: return NzKeyboard::Equal; - case XK_Escape: return NzKeyboard::Escape; - case XK_Home: return NzKeyboard::Home; - case XK_Insert: return NzKeyboard::Insert; - case XK_Alt_L: return NzKeyboard::LAlt; - case XK_bracketleft: return NzKeyboard::LBracket; - case XK_Control_L: return NzKeyboard::LControl; - case XK_Shift_L: return NzKeyboard::LShift; - case XK_Super_L: return NzKeyboard::LSystem; - case XK_0: return NzKeyboard::Num0; - case XK_1: return NzKeyboard::Num1; - case XK_2: return NzKeyboard::Num2; - case XK_3: return NzKeyboard::Num3; - case XK_4: return NzKeyboard::Num4; - case XK_5: return NzKeyboard::Num5; - case XK_6: return NzKeyboard::Num6; - case XK_7: return NzKeyboard::Num7; - case XK_8: return NzKeyboard::Num8; - case XK_9: return NzKeyboard::Num9; - case XK_Page_Down: return NzKeyboard::PageDown; - case XK_Page_Up: return NzKeyboard::PageUp; - case XK_Pause: return NzKeyboard::Pause; - case XK_period: return NzKeyboard::Period; - case XK_Print: return NzKeyboard::Print; - case XK_Sys_Req: return NzKeyboard::PrintScreen; - case XK_quotedbl: return NzKeyboard::Quote; - case XK_Alt_R: return NzKeyboard::RAlt; - case XK_bracketright: return NzKeyboard::RBracket; - case XK_Control_R: return NzKeyboard::RControl; - case XK_Return: return NzKeyboard::Return; - case XK_Shift_R: return NzKeyboard::RShift; - case XK_Super_R: return NzKeyboard::RSystem; - case XK_semicolon: return NzKeyboard::Semicolon; - case XK_slash: return NzKeyboard::Slash; - case XK_space: return NzKeyboard::Space; - case XK_Tab: return NzKeyboard::Tab; - case XK_grave: return NzKeyboard::Tilde; - - // Touches navigateur - case XF86XK_Back: return NzKeyboard::Browser_Back; - case XF86XK_Favorites: return NzKeyboard::Browser_Favorites; - case XF86XK_Forward: return NzKeyboard::Browser_Forward; - case XF86XK_HomePage: return NzKeyboard::Browser_Home; - case XF86XK_Refresh: return NzKeyboard::Browser_Refresh; - case XF86XK_Search: return NzKeyboard::Browser_Search; - case XF86XK_Stop: return NzKeyboard::Browser_Stop; - - // Touches de contrôle - case XF86XK_AudioNext: return NzKeyboard::Media_Next; - case XF86XK_AudioPlay: return NzKeyboard::Media_Play; - case XF86XK_AudioPrev: return NzKeyboard::Media_Previous; - case XF86XK_AudioStop: return NzKeyboard::Media_Stop; - - // Touches de contrôle du volume - case XF86XK_AudioLowerVolume: return NzKeyboard::Volume_Down; - case XF86XK_AudioMute: return NzKeyboard::Volume_Mute; - case XF86XK_AudioRaiseVolume: return NzKeyboard::Volume_Up; - - // Touches à verrouillage - case XK_Caps_Lock: return NzKeyboard::CapsLock; - case XK_Num_Lock: return NzKeyboard::NumLock; - case XK_Scroll_Lock: return NzKeyboard::ScrollLock; - - default: - return NzKeyboard::Undefined; - } -} - -const char* NzWindowImpl::ConvertWindowCursorToXName(nzWindowCursor cursor) -{ - // http://gnome-look.org/content/preview.php?preview=1&id=128170&file1=128170-1.png&file2=&file3=&name=Dummy+X11+cursors&PHPSESSID=6 - switch (cursor) - { - case nzWindowCursor_Crosshair: - return "crosshair"; - case nzWindowCursor_Default: - return "left_ptr"; - case nzWindowCursor_Hand: - return "hand"; - case nzWindowCursor_Help: - return "help"; - case nzWindowCursor_Move: - return "fleur"; - case nzWindowCursor_None: - return "none"; // Handled in set cursor - case nzWindowCursor_Pointer: - return "hand"; - case nzWindowCursor_Progress: - return "watch"; - case nzWindowCursor_ResizeE: - return "right_side"; - case nzWindowCursor_ResizeN: - return "top_side"; - case nzWindowCursor_ResizeNE: - return "top_right_corner"; - case nzWindowCursor_ResizeNW: - return "top_left_corner"; - case nzWindowCursor_ResizeS: - return "bottom_side"; - case nzWindowCursor_ResizeSE: - return "bottom_right_corner"; - case nzWindowCursor_ResizeSW: - return "bottom_left_corner"; - case nzWindowCursor_ResizeW: - return "left_side"; - case nzWindowCursor_Text: - return "xterm"; - case nzWindowCursor_Wait: - return "watch"; - } - - NazaraError("Cursor is not handled by enumeration"); - return "X_cursor"; -} - -void NzWindowImpl::CommonInitialize() -{ - // Show the window - SetVisible(true); - - // Raise the window and grab input focus - SetFocus(); - - xcb_atom_t protocols[] = - { - X11::GetAtom("WM_DELETE_WINDOW"), - }; - - if (!X11::CheckCookie( - connection, - xcb_icccm_set_wm_protocols( - connection, - m_window, - X11::GetAtom("WM_PROTOCOLS"), - sizeof(protocols), - protocols - )) - ) - NazaraError("Failed to get atom for deleting a window"); - - // Flush the commands queue - xcb_flush(connection); -} - -void NzWindowImpl::ProcessEvent(xcb_generic_event_t* windowEvent) -{ - if (!m_eventListener) - return; - - // Convert the xcb event to a NzEvent - switch (windowEvent->response_type & ~0x80) - { - // Destroy event - case XCB_DESTROY_NOTIFY: - { - // The window is about to be destroyed: we must cleanup resources - CleanUp(); - break; - } - - // Gain focus event - case XCB_FOCUS_IN: - { - const uint32_t value_list[] = { eventMask }; - xcb_change_window_attributes(connection, m_window, XCB_CW_EVENT_MASK, value_list); - - NzEvent event; - event.type = nzEventType_GainedFocus; - m_parent->PushEvent(event); - - break; - } - - // Lost focus event - case XCB_FOCUS_OUT: - { - NzEvent event; - event.type = nzEventType_LostFocus; - m_parent->PushEvent(event); - - const uint32_t values[] = { XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_FOCUS_CHANGE }; - xcb_change_window_attributes(connection, m_window, XCB_CW_EVENT_MASK, values); - - break; - } - - // Resize event - case XCB_CONFIGURE_NOTIFY: - { - xcb_configure_notify_event_t* configureNotifyEvent = (xcb_configure_notify_event_t*)windowEvent; - // ConfigureNotify can be triggered for other reasons, check if the size has actually changed - if ((configureNotifyEvent->width != m_size_hints.width) || (configureNotifyEvent->height != m_size_hints.width)) - { - NzEvent event; - event.type = nzEventType_Resized; - event.size.width = configureNotifyEvent->width; - event.size.height = configureNotifyEvent->height; - m_parent->PushEvent(event); - - m_size_hints.width = configureNotifyEvent->width; - m_size_hints.height = configureNotifyEvent->height; - } - if ((configureNotifyEvent->x != m_size_hints.x) || (configureNotifyEvent->y != m_size_hints.y)) - { - NzEvent event; - event.type = nzEventType_Moved; - event.size.width = configureNotifyEvent->x; - event.size.height = configureNotifyEvent->y; - m_parent->PushEvent(event); - - m_size_hints.x = configureNotifyEvent->x; - m_size_hints.y = configureNotifyEvent->y; - } - break; - } - - // Close event - case XCB_CLIENT_MESSAGE: - { - xcb_client_message_event_t* clientMessageEvent = (xcb_client_message_event_t*)windowEvent; - - if (clientMessageEvent->type != X11::GetAtom("WM_PROTOCOLS")) - break; - if (clientMessageEvent->data.data32[0] == X11::GetAtom("WM_DELETE_WINDOW")) - { - NzEvent event; - event.type = nzEventType_Quit; - m_parent->PushEvent(event); - } - - break; - } - - // Key down event - case XCB_KEY_PRESS: - { - xcb_key_press_event_t* keyPressEvent = (xcb_key_press_event_t*)windowEvent; - - if (!m_keyRepeat && m_eventQueue.curr && m_eventQueue.next) - { - xcb_key_press_event_t* current = (xcb_key_release_event_t*)m_eventQueue.curr; - // keyPressEvent == next - - if ((current->time == keyPressEvent->time) && (current->detail == keyPressEvent->detail)) - break; - } - - auto keysym = ConvertKeyCodeToKeySym(keyPressEvent->detail, keyPressEvent->state); - - NzEvent event; - event.type = nzEventType_KeyPressed; - event.key.code = ConvertVirtualKey(keysym); - event.key.alt = keyPressEvent->state & XCB_MOD_MASK_1; - event.key.control = keyPressEvent->state & XCB_MOD_MASK_CONTROL; - event.key.shift = keyPressEvent->state & XCB_MOD_MASK_SHIFT; - event.key.system = keyPressEvent->state & XCB_MOD_MASK_4; - m_parent->PushEvent(event); - - char32_t codePoint = static_cast(keysym); - - // WTF if (std::isprint(codePoint, std::locale(""))) + handle combining ? - { - NzEvent event; - event.type = nzEventType_TextEntered; - event.text.character = codePoint; - event.text.repeated = false; - m_parent->PushEvent(event); - } - - break; - } - - // Key up event - case XCB_KEY_RELEASE: - { - xcb_key_release_event_t* keyReleaseEvent = (xcb_key_release_event_t*)windowEvent; - - if (!m_keyRepeat && m_eventQueue.curr && m_eventQueue.next) - { - // keyReleaseEvent == current - xcb_key_press_event_t* next = (xcb_key_press_event_t*)m_eventQueue.next; - - if ((keyReleaseEvent->time == next->time) && (keyReleaseEvent->detail == next->detail)) - break; - } - - auto keysym = ConvertKeyCodeToKeySym(keyReleaseEvent->detail, keyReleaseEvent->state); - - NzEvent event; - event.type = nzEventType_KeyReleased; - event.key.code = ConvertVirtualKey(keysym); - event.key.alt = keyReleaseEvent->state & XCB_MOD_MASK_1; - event.key.control = keyReleaseEvent->state & XCB_MOD_MASK_CONTROL; - event.key.shift = keyReleaseEvent->state & XCB_MOD_MASK_SHIFT; - event.key.system = keyReleaseEvent->state & XCB_MOD_MASK_4; - m_parent->PushEvent(event); - - break; - } - - // Mouse button pressed - case XCB_BUTTON_PRESS: - { - xcb_button_press_event_t* buttonPressEvent = (xcb_button_press_event_t*)windowEvent; - - NzEvent event; - event.type = nzEventType_MouseButtonPressed; - event.mouseButton.x = buttonPressEvent->event_x; - event.mouseButton.y = buttonPressEvent->event_y; - - if (buttonPressEvent->detail == XCB_BUTTON_INDEX_1) - event.mouseButton.button = NzMouse::Left; - else if (buttonPressEvent->detail == XCB_BUTTON_INDEX_2) - event.mouseButton.button = NzMouse::Middle; - else if (buttonPressEvent->detail == XCB_BUTTON_INDEX_3) - event.mouseButton.button = NzMouse::Right; - else if (buttonPressEvent->detail == XCB_BUTTON_INDEX_4) - event.mouseButton.button = NzMouse::XButton1; - else if (buttonPressEvent->detail == XCB_BUTTON_INDEX_5) - event.mouseButton.button = NzMouse::XButton2; - else - NazaraWarning("Mouse button not handled"); - - m_parent->PushEvent(event); - - break; - } - - // Mouse button released - case XCB_BUTTON_RELEASE: - { - xcb_button_release_event_t* buttonReleaseEvent = (xcb_button_release_event_t*)windowEvent; - - NzEvent event; - - switch (buttonReleaseEvent->detail) - { - case XCB_BUTTON_INDEX_4: - case XCB_BUTTON_INDEX_5: - { - event.type = nzEventType_MouseWheelMoved; - event.mouseWheel.delta = (buttonReleaseEvent->detail == XCB_BUTTON_INDEX_4) ? 1 : -1; - break; - } - default: - { - event.type = nzEventType_MouseButtonReleased; - event.mouseButton.x = buttonReleaseEvent->event_x; - event.mouseButton.y = buttonReleaseEvent->event_y; - - if (buttonReleaseEvent->detail == XCB_BUTTON_INDEX_1) - event.mouseButton.button = NzMouse::Left; - else if (buttonReleaseEvent->detail == XCB_BUTTON_INDEX_2) - event.mouseButton.button = NzMouse::Middle; - else if (buttonReleaseEvent->detail == XCB_BUTTON_INDEX_3) - event.mouseButton.button = NzMouse::Right; - else if (buttonReleaseEvent->detail == XCB_BUTTON_INDEX_4) - event.mouseButton.button = NzMouse::XButton1; - else if (buttonReleaseEvent->detail == XCB_BUTTON_INDEX_5) - event.mouseButton.button = NzMouse::XButton2; - else - NazaraWarning("Mouse button not handled"); - } - } - - m_parent->PushEvent(event); - - break; - } - - // Mouse moved - case XCB_MOTION_NOTIFY: - { - xcb_motion_notify_event_t* motionNotifyEvent = (xcb_motion_notify_event_t*)windowEvent; - - if (m_mousePos.x == motionNotifyEvent->event_x && m_mousePos.y == motionNotifyEvent->event_y) - break; - - NzEvent event; - event.type = nzEventType_MouseMoved; - event.mouseMove.deltaX = motionNotifyEvent->event_x - m_mousePos.x; - event.mouseMove.deltaY = motionNotifyEvent->event_y - m_mousePos.y; - event.mouseMove.x = motionNotifyEvent->event_x; - event.mouseMove.y = motionNotifyEvent->event_y; - m_parent->PushEvent(event); - - m_mousePos.x = motionNotifyEvent->event_x; - m_mousePos.y = motionNotifyEvent->event_y; - - break; - } - - // Mouse entered - case XCB_ENTER_NOTIFY: - { - NzEvent event; - event.type = nzEventType_MouseEntered; - m_parent->PushEvent(event); - - break; - } - - // Mouse left - case XCB_LEAVE_NOTIFY: - { - NzEvent event; - event.type = nzEventType_MouseLeft; - m_parent->PushEvent(event); - - break; - } - - // Parent window changed - case XCB_REPARENT_NOTIFY: - { - // Catch reparent events to properly apply fullscreen on - // some "strange" window managers (like Awesome) which - // seem to make use of temporary parents during mapping - if (m_style & nzWindowStyle_Fullscreen) - SwitchToFullscreen(); - - break; - } - } -} - -void NzWindowImpl::ResetVideoMode() -{ - if (fullscreenWindow == this) - { - // Get current screen info - NzScopedXCB error(nullptr); - - // Reset the video mode - NzScopedXCB setScreenConfig(xcb_randr_set_screen_config_reply( - connection, - xcb_randr_set_screen_config( - connection, - m_oldVideoMode.root, - XCB_CURRENT_TIME, - m_oldVideoMode.config_timestamp, - m_oldVideoMode.sizeID, - m_oldVideoMode.rotation, - m_oldVideoMode.rate + xcb_get_input_focus_unchecked( + connection ), &error )); if (error) - NazaraError("Failed to reset old screen configuration"); + NazaraError("Failed to check if window has focus"); - // Reset the fullscreen window - fullscreenWindow = nullptr; + return (reply->focus == m_window); } -} -void NzWindowImpl::SetCursor(xcb_cursor_t cursor) -{ - if (!X11::CheckCookie( - connection, - xcb_change_window_attributes( - connection, - m_window, - XCB_CW_CURSOR, - &cursor - )) - ) - NazaraError("Failed to change mouse cursor"); - - xcb_flush(connection); -} - -void NzWindowImpl::SetMotifHints() -{ - NzScopedXCB error(nullptr); - - const char MOTIF_WM_HINTS[] = "_MOTIF_WM_HINTS"; - NzScopedXCB hintsAtomReply(xcb_intern_atom_reply( - connection, - xcb_intern_atom( - connection, - 0, - sizeof(MOTIF_WM_HINTS) - 1, - MOTIF_WM_HINTS - ), - &error - )); - - if (!error && hintsAtomReply) + void WindowImpl::IgnoreNextMouseEvent(int mouseX, int mouseY) { - const uint32_t MWM_HINTS_FUNCTIONS = 1 << 0; - const uint32_t MWM_HINTS_DECORATIONS = 1 << 1; + // Petite astuce ... + m_mousePos.x = mouseX; + m_mousePos.y = mouseY; + } - //const uint32_t MWM_DECOR_ALL = 1 << 0; - const uint32_t MWM_DECOR_BORDER = 1 << 1; - const uint32_t MWM_DECOR_RESIZEH = 1 << 2; - const uint32_t MWM_DECOR_TITLE = 1 << 3; - const uint32_t MWM_DECOR_MENU = 1 << 4; - const uint32_t MWM_DECOR_MINIMIZE = 1 << 5; - const uint32_t MWM_DECOR_MAXIMIZE = 1 << 6; + bool WindowImpl::IsMinimized() const + { + ScopedXCBEWMHConnection ewmhConnection(connection); - //const uint32_t MWM_FUNC_ALL = 1 << 0; - const uint32_t MWM_FUNC_RESIZE = 1 << 1; - const uint32_t MWM_FUNC_MOVE = 1 << 2; - const uint32_t MWM_FUNC_MINIMIZE = 1 << 3; - const uint32_t MWM_FUNC_MAXIMIZE = 1 << 4; - const uint32_t MWM_FUNC_CLOSE = 1 << 5; + ScopedXCB error(nullptr); + bool isMinimized = false; - struct MotifWMHints + xcb_ewmh_get_atoms_reply_t atomReply; + if (xcb_ewmh_get_wm_state_reply(ewmhConnection, + xcb_ewmh_get_wm_state(ewmhConnection, m_window), &atomReply, &error) == 1) { - uint32_t flags; - uint32_t functions; - uint32_t decorations; - int32_t inputMode; - uint32_t state; - }; + for (unsigned int i = 0; i < atomReply.atoms_len; i++) + if (atomReply.atoms[i] == ewmhConnection->_NET_WM_STATE_HIDDEN) + isMinimized = true; - MotifWMHints hints; - hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS; - hints.decorations = 0; - hints.functions = 0; - hints.inputMode = 0; - hints.state = 0; - - if (m_style & nzWindowStyle_Titlebar) - { - hints.decorations |= MWM_DECOR_BORDER | MWM_DECOR_TITLE | MWM_DECOR_MINIMIZE | MWM_DECOR_MENU; - hints.functions |= MWM_FUNC_MOVE | MWM_FUNC_MINIMIZE; + xcb_ewmh_get_atoms_reply_wipe(&atomReply); } - if (m_style & nzWindowStyle_Resizable) - { - hints.decorations |= MWM_DECOR_MAXIMIZE | MWM_DECOR_RESIZEH; - hints.functions |= MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE; - } - if (m_style & nzWindowStyle_Closable) - { - hints.decorations |= 0; - hints.functions |= MWM_FUNC_CLOSE; - } - - NzScopedXCB error(xcb_request_check( - connection, - xcb_change_property_checked( - connection, - XCB_PROP_MODE_REPLACE, - m_window, - hintsAtomReply->atom, - hintsAtomReply->atom, - 32, - 5, - &hints - ) - )); if (error) - NazaraError("xcb_change_property failed, could not set window hints"); - } - else - NazaraError("Failed to request _MOTIF_WM_HINTS atom."); -} + NazaraError("Failed to determine if window is minimized"); -void NzWindowImpl::SetVideoMode(const NzVideoMode& mode) -{ - // Skip mode switching if the new mode is equal to the desktop mode - if (mode == NzVideoMode::GetDesktopMode()) - return; - - NzScopedXCB error(nullptr); - - // Check if the RandR extension is present - const xcb_query_extension_reply_t* randrExt = xcb_get_extension_data(connection, &xcb_randr_id); - - if (!randrExt || !randrExt->present) - { - // RandR extension is not supported: we cannot use fullscreen mode - NazaraError("Fullscreen is not supported, switching to window mode"); - return; + return isMinimized; } - // Load RandR and check its version - NzScopedXCB randrVersion(xcb_randr_query_version_reply( - connection, - xcb_randr_query_version( - connection, - 1, - 1 - ), - &error - )); - - if (error) + bool WindowImpl::IsVisible() const { - NazaraError("Failed to load RandR, switching to window mode"); - return; + return !IsMinimized(); // Visibility event ? } - // Get the current configuration - NzScopedXCB config(xcb_randr_get_screen_info_reply( - connection, - xcb_randr_get_screen_info( - connection, - m_screen->root - ), - &error - )); - - if (error || !config) + void WindowImpl::ProcessEvents(bool block) { - // Failed to get the screen configuration - NazaraError("Failed to get the current screen configuration for fullscreen mode, switching to window mode"); - return; - } - - // Save the current video mode before we switch to fullscreen - m_oldVideoMode = *config.get(); - - // Get the available screen sizes - xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get()); - - if (!sizes || !config->nSizes) - { - NazaraError("Failed to get the fullscreen sizes, switching to window mode"); - return; - } - - // Search for a matching size - for (int i = 0; i < config->nSizes; ++i) - { - if (config->rotation == XCB_RANDR_ROTATION_ROTATE_90 || - config->rotation == XCB_RANDR_ROTATION_ROTATE_270) - std::swap(sizes[i].height, sizes[i].width); - - if ((sizes[i].width == static_cast(mode.width)) && - (sizes[i].height == static_cast(mode.height))) + if (m_ownsWindow) { - // Switch to fullscreen mode - NzScopedXCB setScreenConfig(xcb_randr_set_screen_config_reply( + xcb_generic_event_t* event = nullptr; + + if (block) + { + event = xcb_wait_for_event(connection); + if (event) + { + UpdateEventQueue(event); + ProcessEvent(event); + } + } + else + { + event = xcb_poll_for_event(connection); + while (event) + { + UpdateEventQueue(event); + xcb_generic_event_t* tmp = xcb_poll_for_event(connection); + UpdateEventQueue(tmp); + ProcessEvent(event); + if (tmp) + ProcessEvent(tmp); + event = xcb_poll_for_event(connection); + } + } + } + } + + void WindowImpl::SetCursor(Nz::WindowCursor windowCursor) + { + if (windowCursor == Nz::WindowCursor_None) + SetCursor(hiddenCursor); + else + { + const char* name = ConvertWindowCursorToXName(windowCursor); + + xcb_cursor_context_t* ctx; + if (xcb_cursor_context_new(connection, m_screen, &ctx) >= 0) + { + xcb_cursor_t cursor = xcb_cursor_load_cursor(ctx, name); + SetCursor(cursor); + xcb_free_cursor(connection, cursor); + xcb_cursor_context_free(ctx); + } + } + } + + void WindowImpl::SetCursor(const Cursor& cursor) + { + if (!cursor.IsValid()) + { + NazaraError("Cursor is not valid"); + return; + } + + SetCursor(cursor.m_impl->GetCursor()); + } + + void WindowImpl::SetEventListener(bool listener) + { + if (m_ownsWindow) + m_eventListener = listener; + else if (listener != m_eventListener) + { + if (listener) + { + const uint32_t value_list[] = { eventMask }; + + if (!X11::CheckCookie( + connection, + xcb_change_window_attributes( + connection, + m_window, + XCB_CW_EVENT_MASK, + value_list + )) + ) + NazaraError("Failed to change event for listener"); + + m_eventListener = true; + } + else if (m_eventListener) + { + const uint32_t value_list[] = { XCB_EVENT_MASK_NO_EVENT }; + + if (!X11::CheckCookie( + connection, + xcb_change_window_attributes( + connection, + m_window, + XCB_CW_EVENT_MASK, + value_list + )) + ) + NazaraError("Failed to change event for listener"); + + m_eventListener = false; + } + } + } + + void WindowImpl::SetFocus() + { + if (!X11::CheckCookie( + connection, + xcb_set_input_focus( + connection, + XCB_INPUT_FOCUS_POINTER_ROOT, + m_window, + XCB_CURRENT_TIME + )) + ) + NazaraError("Failed to set input focus"); + + const uint32_t values[] = { XCB_STACK_MODE_ABOVE }; + + if (!X11::CheckCookie( + connection, + xcb_configure_window( + connection, + m_window, + XCB_CONFIG_WINDOW_STACK_MODE, + values + )) + ) + NazaraError("Failed to set focus"); + } + + void WindowImpl::SetIcon(const Icon& icon) + { + if (!icon.IsValid()) + { + NazaraError("Icon is not valid"); + return; + } + + xcb_pixmap_t icon_pixmap = icon.m_impl->GetIcon(); + xcb_pixmap_t mask_pixmap = icon.m_impl->GetMask(); + + ScopedXCB error(nullptr); + + xcb_icccm_wm_hints_t hints; + std::memset(&hints, 0, sizeof(hints)); + + xcb_icccm_get_wm_hints_reply( + connection, + xcb_icccm_get_wm_hints( + connection, + m_window), + &hints, + &error + ); + + if (error) + NazaraError("Failed to get wm hints"); + + xcb_icccm_wm_hints_set_icon_pixmap(&hints, icon_pixmap); + xcb_icccm_wm_hints_set_icon_mask(&hints, mask_pixmap); + + if (!X11::CheckCookie( + connection, + xcb_icccm_set_wm_hints( + connection, + m_window, + &hints + )) + ) + NazaraError("Failed to set wm hints"); + + xcb_flush(connection); + } + + void WindowImpl::SetMaximumSize(int width, int height) + { + if (width < 0) + width = m_screen->width_in_pixels; + if (height < 0) + height = m_screen->height_in_pixels; + + xcb_icccm_size_hints_set_max_size(&m_size_hints, width, height); + if (!UpdateNormalHints()) + NazaraError("Failed to set maximum size"); + + xcb_flush(connection); + } + + void WindowImpl::SetMinimumSize(int width, int height) + { + xcb_icccm_size_hints_set_min_size(&m_size_hints, width, height); + if (!UpdateNormalHints()) + NazaraError("Failed to set minimum size"); + + xcb_flush(connection); + } + + void WindowImpl::SetPosition(int x, int y) + { + xcb_icccm_size_hints_set_position(&m_size_hints, true, x, y); + if (!UpdateNormalHints()) + NazaraError("Failed to set size hints position"); + + const uint32_t values[] = { static_cast(x), static_cast(y) }; + if (!X11::CheckCookie( + connection, + xcb_configure_window( + connection, + m_window, + XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, + values + )) + ) + NazaraError("Failed to set position"); + + xcb_flush(connection); + } + + void WindowImpl::SetSize(unsigned int width, unsigned int height) + { + xcb_icccm_size_hints_set_size(&m_size_hints, true, width, height); + if (!UpdateNormalHints()) + NazaraError("Failed to set size hints sizes"); + + const uint32_t values[] = { width, height }; + if (!X11::CheckCookie( + connection, + xcb_configure_window( + connection, + m_window, + XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, + values + )) + ) + NazaraError("Failed to set sizes"); + + xcb_flush(connection); + } + + void WindowImpl::SetStayOnTop(bool stayOnTop) + { + ScopedXCBEWMHConnection ewmhConnection(connection); + + xcb_atom_t onTop; // It is not really working + if (stayOnTop) + onTop = ewmhConnection->_NET_WM_STATE_ABOVE; + else + onTop = ewmhConnection->_NET_WM_STATE_BELOW; + + if (!X11::CheckCookie( + connection, + xcb_ewmh_set_wm_state( + ewmhConnection, + m_window, + 1, + &onTop + )) + ) + NazaraError("Failed to set stay on top"); + + xcb_flush(connection); + } + + void WindowImpl::SetTitle(const String& title) + { + ScopedXCBEWMHConnection ewmhConnection(connection); + + if (!X11::CheckCookie( + connection, + xcb_ewmh_set_wm_name( + ewmhConnection, + m_window, + title.GetSize(), + title.GetConstBuffer() + )) + ) + NazaraError("Failed to set title"); + + xcb_flush(connection); + } + + void WindowImpl::SetVisible(bool visible) + { + if (visible) + { + if (!X11::CheckCookie( + connection, + xcb_map_window( + connection, + m_window + )) + ) + NazaraError("Failed to change window visibility to visible"); + } + else + { + if (!X11::CheckCookie( + connection, + xcb_unmap_window( + connection, + m_window + )) + ) + NazaraError("Failed to change window visibility to invisible"); + } + + xcb_flush(connection); + } + + bool WindowImpl::Initialize() + { + X11::Initialize(); + + connection = X11::OpenConnection(); + + // Create the hidden cursor + CreateHiddenCursor(); + + return true; + } + + void WindowImpl::Uninitialize() + { + // Destroy the cursor + if (hiddenCursor) + { + xcb_free_cursor(connection, hiddenCursor); + hiddenCursor = 0; + } + + X11::CloseConnection(connection); + + X11::Uninitialize(); + } + + void WindowImpl::CleanUp() + { + // Restore the previous video mode (in case we were running in fullscreen) + ResetVideoMode(); + } + + xcb_keysym_t WindowImpl::ConvertKeyCodeToKeySym(xcb_keycode_t keycode, uint16_t state) + { + xcb_key_symbols_t* keysyms = X11::XCBKeySymbolsAlloc(connection); + if (!keysyms) + { + NazaraError("Failed to get key symbols"); + return XCB_NONE; + } + + int col = state & XCB_MOD_MASK_SHIFT ? 1 : 0; + const int altGrOffset = 4; + if (state & XCB_MOD_MASK_5) + col += altGrOffset; + xcb_keysym_t keysym = xcb_key_symbols_get_keysym(keysyms, keycode, col); + if (keysym == XCB_NO_SYMBOL) + keysym = xcb_key_symbols_get_keysym(keysyms, keycode, col ^ 0x1); + X11::XCBKeySymbolsFree(keysyms); + + return keysym; + } + + Keyboard::Key WindowImpl::ConvertVirtualKey(xcb_keysym_t symbol) + { + // First convert to uppercase (to avoid dealing with two different keysyms for the same key) + KeySym lower, key; + XConvertCase(symbol, &lower, &key); + + switch (key) + { + // Lettres + case XK_A: return Keyboard::A; + case XK_B: return Keyboard::B; + case XK_C: return Keyboard::C; + case XK_D: return Keyboard::D; + case XK_E: return Keyboard::E; + case XK_F: return Keyboard::F; + case XK_G: return Keyboard::G; + case XK_H: return Keyboard::H; + case XK_I: return Keyboard::I; + case XK_J: return Keyboard::J; + case XK_K: return Keyboard::K; + case XK_L: return Keyboard::L; + case XK_M: return Keyboard::M; + case XK_N: return Keyboard::N; + case XK_O: return Keyboard::O; + case XK_P: return Keyboard::P; + case XK_Q: return Keyboard::Q; + case XK_R: return Keyboard::R; + case XK_S: return Keyboard::S; + case XK_T: return Keyboard::T; + case XK_U: return Keyboard::U; + case XK_V: return Keyboard::V; + case XK_W: return Keyboard::W; + case XK_X: return Keyboard::X; + case XK_Y: return Keyboard::Y; + case XK_Z: return Keyboard::Z; + + // Touches de fonction + case XK_F1: return Keyboard::F1; + case XK_F2: return Keyboard::F2; + case XK_F3: return Keyboard::F3; + case XK_F4: return Keyboard::F4; + case XK_F5: return Keyboard::F5; + case XK_F6: return Keyboard::F6; + case XK_F7: return Keyboard::F7; + case XK_F8: return Keyboard::F8; + case XK_F9: return Keyboard::F9; + case XK_F10: return Keyboard::F10; + case XK_F11: return Keyboard::F11; + case XK_F12: return Keyboard::F12; + case XK_F13: return Keyboard::F13; + case XK_F14: return Keyboard::F14; + case XK_F15: return Keyboard::F15; + + // Flèches directionnelles + case XK_Down: return Keyboard::Down; + case XK_Left: return Keyboard::Left; + case XK_Right: return Keyboard::Right; + case XK_Up: return Keyboard::Up; + + // Pavé numérique + case XK_KP_Add: return Keyboard::Add; + case XK_KP_Decimal: return Keyboard::Decimal; + case XK_KP_Delete: return Keyboard::Decimal; + case XK_KP_Divide: return Keyboard::Divide; + case XK_KP_Multiply: return Keyboard::Multiply; + case XK_KP_Insert: return Keyboard::Numpad0; + case XK_KP_End: return Keyboard::Numpad1; + case XK_KP_Down: return Keyboard::Numpad2; + case XK_KP_Page_Down: return Keyboard::Numpad3; + case XK_KP_Left: return Keyboard::Numpad4; + case XK_KP_Begin: return Keyboard::Numpad5; + case XK_KP_Right: return Keyboard::Numpad6; + case XK_KP_Home: return Keyboard::Numpad7; + case XK_KP_Up: return Keyboard::Numpad8; + case XK_KP_Page_Up: return Keyboard::Numpad9; + case XK_KP_Enter: return Keyboard::Return; + case XK_KP_Subtract: return Keyboard::Subtract; + + // Divers + case XK_backslash: return Keyboard::Backslash; + case XK_BackSpace: return Keyboard::Backspace; + case XK_Clear: return Keyboard::Clear; + case XK_comma: return Keyboard::Comma; + case XK_minus: return Keyboard::Dash; + case XK_Delete: return Keyboard::Delete; + case XK_End: return Keyboard::End; + case XK_equal: return Keyboard::Equal; + case XK_Escape: return Keyboard::Escape; + case XK_Home: return Keyboard::Home; + case XK_Insert: return Keyboard::Insert; + case XK_Alt_L: return Keyboard::LAlt; + case XK_bracketleft: return Keyboard::LBracket; + case XK_Control_L: return Keyboard::LControl; + case XK_Shift_L: return Keyboard::LShift; + case XK_Super_L: return Keyboard::LSystem; + case XK_0: return Keyboard::Num0; + case XK_1: return Keyboard::Num1; + case XK_2: return Keyboard::Num2; + case XK_3: return Keyboard::Num3; + case XK_4: return Keyboard::Num4; + case XK_5: return Keyboard::Num5; + case XK_6: return Keyboard::Num6; + case XK_7: return Keyboard::Num7; + case XK_8: return Keyboard::Num8; + case XK_9: return Keyboard::Num9; + case XK_Page_Down: return Keyboard::PageDown; + case XK_Page_Up: return Keyboard::PageUp; + case XK_Pause: return Keyboard::Pause; + case XK_period: return Keyboard::Period; + case XK_Print: return Keyboard::Print; + case XK_Sys_Req: return Keyboard::PrintScreen; + case XK_quotedbl: return Keyboard::Quote; + case XK_Alt_R: return Keyboard::RAlt; + case XK_bracketright: return Keyboard::RBracket; + case XK_Control_R: return Keyboard::RControl; + case XK_Return: return Keyboard::Return; + case XK_Shift_R: return Keyboard::RShift; + case XK_Super_R: return Keyboard::RSystem; + case XK_semicolon: return Keyboard::Semicolon; + case XK_slash: return Keyboard::Slash; + case XK_space: return Keyboard::Space; + case XK_Tab: return Keyboard::Tab; + case XK_grave: return Keyboard::Tilde; + + // Touches navigateur + case XF86XK_Back: return Keyboard::Browser_Back; + case XF86XK_Favorites: return Keyboard::Browser_Favorites; + case XF86XK_Forward: return Keyboard::Browser_Forward; + case XF86XK_HomePage: return Keyboard::Browser_Home; + case XF86XK_Refresh: return Keyboard::Browser_Refresh; + case XF86XK_Search: return Keyboard::Browser_Search; + case XF86XK_Stop: return Keyboard::Browser_Stop; + + // Touches de contrôle + case XF86XK_AudioNext: return Keyboard::Media_Next; + case XF86XK_AudioPlay: return Keyboard::Media_Play; + case XF86XK_AudioPrev: return Keyboard::Media_Previous; + case XF86XK_AudioStop: return Keyboard::Media_Stop; + + // Touches de contrôle du volume + case XF86XK_AudioLowerVolume: return Keyboard::Volume_Down; + case XF86XK_AudioMute: return Keyboard::Volume_Mute; + case XF86XK_AudioRaiseVolume: return Keyboard::Volume_Up; + + // Touches à verrouillage + case XK_Caps_Lock: return Keyboard::CapsLock; + case XK_Num_Lock: return Keyboard::NumLock; + case XK_Scroll_Lock: return Keyboard::ScrollLock; + + default: + return Keyboard::Undefined; + } + } + + const char* WindowImpl::ConvertWindowCursorToXName(Nz::WindowCursor cursor) + { + // http://gnome-look.org/content/preview.php?preview=1&id=128170&file1=128170-1.png&file2=&file3=&name=Dummy+X11+cursors&PHPSESSID=6 + switch (cursor) + { + case Nz::WindowCursor_Crosshair: + return "crosshair"; + case Nz::WindowCursor_Default: + return "left_ptr"; + case Nz::WindowCursor_Hand: + return "hand"; + case Nz::WindowCursor_Help: + return "help"; + case Nz::WindowCursor_Move: + return "fleur"; + case Nz::WindowCursor_None: + return "none"; // Handled in set cursor + case Nz::WindowCursor_Pointer: + return "hand"; + case Nz::WindowCursor_Progress: + return "watch"; + case Nz::WindowCursor_ResizeE: + return "right_side"; + case Nz::WindowCursor_ResizeN: + return "top_side"; + case Nz::WindowCursor_ResizeNE: + return "top_right_corner"; + case Nz::WindowCursor_ResizeNW: + return "top_left_corner"; + case Nz::WindowCursor_ResizeS: + return "bottom_side"; + case Nz::WindowCursor_ResizeSE: + return "bottom_right_corner"; + case Nz::WindowCursor_ResizeSW: + return "bottom_left_corner"; + case Nz::WindowCursor_ResizeW: + return "left_side"; + case Nz::WindowCursor_Text: + return "xterm"; + case Nz::WindowCursor_Wait: + return "watch"; + } + + NazaraError("Cursor is not handled by enumeration"); + return "X_cursor"; + } + + void WindowImpl::CommonInitialize() + { + // Show the window + SetVisible(true); + + // Raise the window and grab input focus + SetFocus(); + + xcb_atom_t protocols[] = + { + X11::GetAtom("WM_DELETE_WINDOW"), + }; + + if (!X11::CheckCookie( + connection, + xcb_icccm_set_wm_protocols( + connection, + m_window, + X11::GetAtom("WM_PROTOCOLS"), + sizeof(protocols), + protocols + )) + ) + NazaraError("Failed to get atom for deleting a window"); + + // Flush the commands queue + xcb_flush(connection); + } + + void WindowImpl::ProcessEvent(xcb_generic_event_t* windowEvent) + { + if (!m_eventListener) + return; + + // Convert the xcb event to a Event + switch (windowEvent->response_type & ~0x80) + { + // Destroy event + case XCB_DESTROY_NOTIFY: + { + // The window is about to be destroyed: we must cleanup resources + CleanUp(); + break; + } + + // Gain focus event + case XCB_FOCUS_IN: + { + const uint32_t value_list[] = { eventMask }; + xcb_change_window_attributes(connection, m_window, XCB_CW_EVENT_MASK, value_list); + + WindowEvent event; + event.type = Nz::WindowEventType_GainedFocus; + m_parent->PushEvent(event); + + break; + } + + // Lost focus event + case XCB_FOCUS_OUT: + { + WindowEvent event; + event.type = Nz::WindowEventType_LostFocus; + m_parent->PushEvent(event); + + const uint32_t values[] = { XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_FOCUS_CHANGE }; + xcb_change_window_attributes(connection, m_window, XCB_CW_EVENT_MASK, values); + + break; + } + + // Resize event + case XCB_CONFIGURE_NOTIFY: + { + xcb_configure_notify_event_t* configureNotifyEvent = (xcb_configure_notify_event_t*)windowEvent; + // ConfigureNotify can be triggered for other reasons, check if the size has actually changed + if ((configureNotifyEvent->width != m_size_hints.width) || (configureNotifyEvent->height != m_size_hints.width)) + { + WindowEvent event; + event.type = Nz::WindowEventType_Resized; + event.size.width = configureNotifyEvent->width; + event.size.height = configureNotifyEvent->height; + m_parent->PushEvent(event); + + m_size_hints.width = configureNotifyEvent->width; + m_size_hints.height = configureNotifyEvent->height; + } + if ((configureNotifyEvent->x != m_size_hints.x) || (configureNotifyEvent->y != m_size_hints.y)) + { + WindowEvent event; + event.type = Nz::WindowEventType_Moved; + event.size.width = configureNotifyEvent->x; + event.size.height = configureNotifyEvent->y; + m_parent->PushEvent(event); + + m_size_hints.x = configureNotifyEvent->x; + m_size_hints.y = configureNotifyEvent->y; + } + break; + } + + // Close event + case XCB_CLIENT_MESSAGE: + { + xcb_client_message_event_t* clientMessageEvent = (xcb_client_message_event_t*)windowEvent; + + if (clientMessageEvent->type != X11::GetAtom("WM_PROTOCOLS")) + break; + if (clientMessageEvent->data.data32[0] == X11::GetAtom("WM_DELETE_WINDOW")) + { + WindowEvent event; + event.type = Nz::WindowEventType_Quit; + m_parent->PushEvent(event); + } + + break; + } + + // Key down event + case XCB_KEY_PRESS: + { + xcb_key_press_event_t* keyPressEvent = (xcb_key_press_event_t*)windowEvent; + + if (!m_keyRepeat && m_eventQueue.curr && m_eventQueue.next) + { + xcb_key_press_event_t* current = (xcb_key_release_event_t*)m_eventQueue.curr; + // keyPressEvent == next + + if ((current->time == keyPressEvent->time) && (current->detail == keyPressEvent->detail)) + break; + } + + auto keysym = ConvertKeyCodeToKeySym(keyPressEvent->detail, keyPressEvent->state); + + WindowEvent event; + event.type = Nz::WindowEventType_KeyPressed; + event.key.code = ConvertVirtualKey(keysym); + event.key.alt = keyPressEvent->state & XCB_MOD_MASK_1; + event.key.control = keyPressEvent->state & XCB_MOD_MASK_CONTROL; + event.key.shift = keyPressEvent->state & XCB_MOD_MASK_SHIFT; + event.key.system = keyPressEvent->state & XCB_MOD_MASK_4; + m_parent->PushEvent(event); + + char32_t codePoint = static_cast(keysym); + + // WTF if (std::isprint(codePoint, std::locale(""))) + handle combining ? + { + WindowEvent event; + event.type = Nz::WindowEventType_TextEntered; + event.text.character = codePoint; + event.text.repeated = false; + m_parent->PushEvent(event); + } + + break; + } + + // Key up event + case XCB_KEY_RELEASE: + { + xcb_key_release_event_t* keyReleaseEvent = (xcb_key_release_event_t*)windowEvent; + + if (!m_keyRepeat && m_eventQueue.curr && m_eventQueue.next) + { + // keyReleaseEvent == current + xcb_key_press_event_t* next = (xcb_key_press_event_t*)m_eventQueue.next; + + if ((keyReleaseEvent->time == next->time) && (keyReleaseEvent->detail == next->detail)) + break; + } + + auto keysym = ConvertKeyCodeToKeySym(keyReleaseEvent->detail, keyReleaseEvent->state); + + WindowEvent event; + event.type = Nz::WindowEventType_KeyReleased; + event.key.code = ConvertVirtualKey(keysym); + event.key.alt = keyReleaseEvent->state & XCB_MOD_MASK_1; + event.key.control = keyReleaseEvent->state & XCB_MOD_MASK_CONTROL; + event.key.shift = keyReleaseEvent->state & XCB_MOD_MASK_SHIFT; + event.key.system = keyReleaseEvent->state & XCB_MOD_MASK_4; + m_parent->PushEvent(event); + + break; + } + + // Mouse button pressed + case XCB_BUTTON_PRESS: + { + xcb_button_press_event_t* buttonPressEvent = (xcb_button_press_event_t*)windowEvent; + + WindowEvent event; + event.type = Nz::WindowEventType_MouseButtonPressed; + event.mouseButton.x = buttonPressEvent->event_x; + event.mouseButton.y = buttonPressEvent->event_y; + + if (buttonPressEvent->detail == XCB_BUTTON_INDEX_1) + event.mouseButton.button = Mouse::Left; + else if (buttonPressEvent->detail == XCB_BUTTON_INDEX_2) + event.mouseButton.button = Mouse::Middle; + else if (buttonPressEvent->detail == XCB_BUTTON_INDEX_3) + event.mouseButton.button = Mouse::Right; + else if (buttonPressEvent->detail == XCB_BUTTON_INDEX_4) + event.mouseButton.button = Mouse::XButton1; + else if (buttonPressEvent->detail == XCB_BUTTON_INDEX_5) + event.mouseButton.button = Mouse::XButton2; + else + NazaraWarning("Mouse button not handled"); + + m_parent->PushEvent(event); + + break; + } + + // Mouse button released + case XCB_BUTTON_RELEASE: + { + xcb_button_release_event_t* buttonReleaseEvent = (xcb_button_release_event_t*)windowEvent; + + WindowEvent event; + + switch (buttonReleaseEvent->detail) + { + case XCB_BUTTON_INDEX_4: + case XCB_BUTTON_INDEX_5: + { + event.type = Nz::WindowEventType_MouseWheelMoved; + event.mouseWheel.delta = (buttonReleaseEvent->detail == XCB_BUTTON_INDEX_4) ? 1 : -1; + break; + } + default: + { + event.type = Nz::WindowEventType_MouseButtonReleased; + event.mouseButton.x = buttonReleaseEvent->event_x; + event.mouseButton.y = buttonReleaseEvent->event_y; + + if (buttonReleaseEvent->detail == XCB_BUTTON_INDEX_1) + event.mouseButton.button = Mouse::Left; + else if (buttonReleaseEvent->detail == XCB_BUTTON_INDEX_2) + event.mouseButton.button = Mouse::Middle; + else if (buttonReleaseEvent->detail == XCB_BUTTON_INDEX_3) + event.mouseButton.button = Mouse::Right; + else if (buttonReleaseEvent->detail == XCB_BUTTON_INDEX_4) + event.mouseButton.button = Mouse::XButton1; + else if (buttonReleaseEvent->detail == XCB_BUTTON_INDEX_5) + event.mouseButton.button = Mouse::XButton2; + else + NazaraWarning("Mouse button not handled"); + } + } + + m_parent->PushEvent(event); + + break; + } + + // Mouse moved + case XCB_MOTION_NOTIFY: + { + xcb_motion_notify_event_t* motionNotifyEvent = (xcb_motion_notify_event_t*)windowEvent; + + if (m_mousePos.x == motionNotifyEvent->event_x && m_mousePos.y == motionNotifyEvent->event_y) + break; + + WindowEvent event; + event.type = Nz::WindowEventType_MouseMoved; + event.mouseMove.deltaX = motionNotifyEvent->event_x - m_mousePos.x; + event.mouseMove.deltaY = motionNotifyEvent->event_y - m_mousePos.y; + event.mouseMove.x = motionNotifyEvent->event_x; + event.mouseMove.y = motionNotifyEvent->event_y; + m_parent->PushEvent(event); + + m_mousePos.x = motionNotifyEvent->event_x; + m_mousePos.y = motionNotifyEvent->event_y; + + break; + } + + // Mouse entered + case XCB_ENTER_NOTIFY: + { + WindowEvent event; + event.type = Nz::WindowEventType_MouseEntered; + m_parent->PushEvent(event); + + break; + } + + // Mouse left + case XCB_LEAVE_NOTIFY: + { + WindowEvent event; + event.type = Nz::WindowEventType_MouseLeft; + m_parent->PushEvent(event); + + break; + } + + // Parent window changed + case XCB_REPARENT_NOTIFY: + { + // Catch reparent events to properly apply fullscreen on + // some "strange" window managers (like Awesome) which + // seem to make use of temporary parents during mapping + if (m_style & Nz::WindowStyle_Fullscreen) + SwitchToFullscreen(); + + break; + } + } + } + + void WindowImpl::ResetVideoMode() + { + if (fullscreenWindow == this) + { + // Get current screen info + ScopedXCB error(nullptr); + + // Reset the video mode + ScopedXCB setScreenConfig(xcb_randr_set_screen_config_reply( connection, xcb_randr_set_screen_config( connection, - config->root, + m_oldVideoMode.root, XCB_CURRENT_TIME, - config->config_timestamp, - i, - config->rotation, - config->rate + m_oldVideoMode.config_timestamp, + m_oldVideoMode.sizeID, + m_oldVideoMode.rotation, + m_oldVideoMode.rate ), &error )); if (error) - NazaraError("Failed to set new screen configuration"); + NazaraError("Failed to reset old screen configuration"); - // Set "this" as the current fullscreen window - fullscreenWindow = this; - return; + // Reset the fullscreen window + fullscreenWindow = nullptr; } } - NazaraError("Failed to find matching fullscreen size, switching to window mode"); -} - -void NzWindowImpl::SwitchToFullscreen() -{ - SetFocus(); - - NzScopedXCBEWMHConnection ewmhConnection(connection); - - if (!X11::CheckCookie( - connection, - xcb_ewmh_set_wm_state( - ewmhConnection, - m_window, - 1, - &ewmhConnection->_NET_WM_STATE_FULLSCREEN - )) - ) - NazaraError("Failed to switch to fullscreen"); -} - -void NzWindowImpl::UpdateEventQueue(xcb_generic_event_t* event) -{ - std::free(m_eventQueue.curr); - m_eventQueue.curr = m_eventQueue.next; - m_eventQueue.next = event; -} - -bool NzWindowImpl::UpdateNormalHints() -{ - return X11::CheckCookie( - connection, - xcb_icccm_set_wm_normal_hints( + void WindowImpl::SetCursor(xcb_cursor_t cursor) + { + if (!X11::CheckCookie( connection, - m_window, - &m_size_hints + xcb_change_window_attributes( + connection, + m_window, + XCB_CW_CURSOR, + &cursor + )) + ) + NazaraError("Failed to change mouse cursor"); + + xcb_flush(connection); + } + + void WindowImpl::SetMotifHints() + { + ScopedXCB error(nullptr); + + const char MOTIF_WM_HINTS[] = "_MOTIF_WM_HINTS"; + ScopedXCB hintsAtomReply(xcb_intern_atom_reply( + connection, + xcb_intern_atom( + connection, + 0, + sizeof(MOTIF_WM_HINTS) - 1, + MOTIF_WM_HINTS + ), + &error )); + + if (!error && hintsAtomReply) + { + const uint32_t MWM_HINTS_FUNCTIONS = 1 << 0; + const uint32_t MWM_HINTS_DECORATIONS = 1 << 1; + + //const uint32_t MWM_DECOR_ALL = 1 << 0; + const uint32_t MWM_DECOR_BORDER = 1 << 1; + const uint32_t MWM_DECOR_RESIZEH = 1 << 2; + const uint32_t MWM_DECOR_TITLE = 1 << 3; + const uint32_t MWM_DECOR_MENU = 1 << 4; + const uint32_t MWM_DECOR_MINIMIZE = 1 << 5; + const uint32_t MWM_DECOR_MAXIMIZE = 1 << 6; + + //const uint32_t MWM_FUNC_ALL = 1 << 0; + const uint32_t MWM_FUNC_RESIZE = 1 << 1; + const uint32_t MWM_FUNC_MOVE = 1 << 2; + const uint32_t MWM_FUNC_MINIMIZE = 1 << 3; + const uint32_t MWM_FUNC_MAXIMIZE = 1 << 4; + const uint32_t MWM_FUNC_CLOSE = 1 << 5; + + struct MotifWMHints + { + uint32_t flags; + uint32_t functions; + uint32_t decorations; + int32_t inputMode; + uint32_t state; + }; + + MotifWMHints hints; + hints.flags = MWM_HINTS_FUNCTIONS | MWM_HINTS_DECORATIONS; + hints.decorations = 0; + hints.functions = 0; + hints.inputMode = 0; + hints.state = 0; + + if (m_style & Nz::WindowStyle_Titlebar) + { + hints.decorations |= MWM_DECOR_BORDER | MWM_DECOR_TITLE | MWM_DECOR_MINIMIZE | MWM_DECOR_MENU; + hints.functions |= MWM_FUNC_MOVE | MWM_FUNC_MINIMIZE; + } + if (m_style & Nz::WindowStyle_Resizable) + { + hints.decorations |= MWM_DECOR_MAXIMIZE | MWM_DECOR_RESIZEH; + hints.functions |= MWM_FUNC_MAXIMIZE | MWM_FUNC_RESIZE; + } + if (m_style & Nz::WindowStyle_Closable) + { + hints.decorations |= 0; + hints.functions |= MWM_FUNC_CLOSE; + } + + ScopedXCB error(xcb_request_check( + connection, + xcb_change_property_checked( + connection, + XCB_PROP_MODE_REPLACE, + m_window, + hintsAtomReply->atom, + hintsAtomReply->atom, + 32, + 5, + &hints + ) + )); + + if (error) + NazaraError("xcb_change_property failed, could not set window hints"); + } + else + NazaraError("Failed to request _MOTIF_WM_HINTS atom."); + } + + void WindowImpl::SetVideoMode(const VideoMode& mode) + { + // Skip mode switching if the new mode is equal to the desktop mode + if (mode == VideoMode::GetDesktopMode()) + return; + + ScopedXCB error(nullptr); + + // Check if the RandR extension is present + const xcb_query_extension_reply_t* randrExt = xcb_get_extension_data(connection, &xcb_randr_id); + + if (!randrExt || !randrExt->present) + { + // RandR extension is not supported: we cannot use fullscreen mode + NazaraError("Fullscreen is not supported, switching to window mode"); + return; + } + + // Load RandR and check its version + ScopedXCB randrVersion(xcb_randr_query_version_reply( + connection, + xcb_randr_query_version( + connection, + 1, + 1 + ), + &error + )); + + if (error) + { + NazaraError("Failed to load RandR, switching to window mode"); + return; + } + + // Get the current configuration + ScopedXCB config(xcb_randr_get_screen_info_reply( + connection, + xcb_randr_get_screen_info( + connection, + m_screen->root + ), + &error + )); + + if (error || !config) + { + // Failed to get the screen configuration + NazaraError("Failed to get the current screen configuration for fullscreen mode, switching to window mode"); + return; + } + + // Save the current video mode before we switch to fullscreen + m_oldVideoMode = *config.get(); + + // Get the available screen sizes + xcb_randr_screen_size_t* sizes = xcb_randr_get_screen_info_sizes(config.get()); + + if (!sizes || !config->nSizes) + { + NazaraError("Failed to get the fullscreen sizes, switching to window mode"); + return; + } + + // Search for a matching size + for (int i = 0; i < config->nSizes; ++i) + { + if (config->rotation == XCB_RANDR_ROTATION_ROTATE_90 || + config->rotation == XCB_RANDR_ROTATION_ROTATE_270) + std::swap(sizes[i].height, sizes[i].width); + + if ((sizes[i].width == static_cast(mode.width)) && + (sizes[i].height == static_cast(mode.height))) + { + // Switch to fullscreen mode + ScopedXCB setScreenConfig(xcb_randr_set_screen_config_reply( + connection, + xcb_randr_set_screen_config( + connection, + config->root, + XCB_CURRENT_TIME, + config->config_timestamp, + i, + config->rotation, + config->rate + ), + &error + )); + + if (error) + NazaraError("Failed to set new screen configuration"); + + // Set "this" as the current fullscreen window + fullscreenWindow = this; + return; + } + } + + NazaraError("Failed to find matching fullscreen size, switching to window mode"); + } + + void WindowImpl::SwitchToFullscreen() + { + SetFocus(); + + ScopedXCBEWMHConnection ewmhConnection(connection); + + if (!X11::CheckCookie( + connection, + xcb_ewmh_set_wm_state( + ewmhConnection, + m_window, + 1, + &ewmhConnection->_NET_WM_STATE_FULLSCREEN + )) + ) + NazaraError("Failed to switch to fullscreen"); + } + + void WindowImpl::UpdateEventQueue(xcb_generic_event_t* event) + { + std::free(m_eventQueue.curr); + m_eventQueue.curr = m_eventQueue.next; + m_eventQueue.next = event; + } + + bool WindowImpl::UpdateNormalHints() + { + return X11::CheckCookie( + connection, + xcb_icccm_set_wm_normal_hints( + connection, + m_window, + &m_size_hints + )); + } + + #if NAZARA_UTILITY_THREADED_WINDOW + void WindowImpl::WindowThread(WindowImpl* window, Mutex* mutex, ConditionVariable* condition) + { + mutex->Lock(); + condition->Signal(); + mutex->Unlock(); // mutex et condition sont considérés invalides à partir d'ici + + if (!window->m_window) + return; + + while (window->m_threadActive) + window->ProcessEvents(true); + + window->Destroy(); + } + #endif } - -#if NAZARA_UTILITY_THREADED_WINDOW -void NzWindowImpl::WindowThread(NzWindowImpl* window, NzMutex* mutex, NzConditionVariable* condition) -{ - mutex->Lock(); - condition->Signal(); - mutex->Unlock(); // mutex et condition sont considérés invalides à partir d'ici - - if (!window->m_window) - return; - - while (window->m_threadActive) - window->ProcessEvents(true); - - window->Destroy(); -} -#endif diff --git a/src/Nazara/Utility/X11/WindowImpl.hpp b/src/Nazara/Utility/X11/WindowImpl.hpp index 8245699b2..6a0e26391 100644 --- a/src/Nazara/Utility/X11/WindowImpl.hpp +++ b/src/Nazara/Utility/X11/WindowImpl.hpp @@ -9,118 +9,127 @@ #ifndef NAZARA_WINDOWIMPL_HPP #define NAZARA_WINDOWIMPL_HPP -#include +#include #include #include #include #include +#include #include #include -#include -#if NAZARA_UTILITY_THREADED_WINDOW -class NzConditionVariable; -class NzMutex; -#endif -class NzCursor; -class NzIcon; -class NzVideoMode; -class NzWindow; - -class NzWindowImpl : NzNonCopyable +namespace Nz { - public: - NzWindowImpl(NzWindow* parent); - ~NzWindowImpl(); + #if NAZARA_UTILITY_THREADED_WINDOW + class ConditionVariable; + class Mutex; + #endif + class Cursor; + class Icon; + class VideoMode; + class Window; - bool Create(const NzVideoMode& mode, const NzString& title, nzUInt32 style); - bool Create(NzWindowHandle handle); + class WindowImpl + { + public: + WindowImpl(Window* parent); + WindowImpl(const WindowImpl&) = delete; + WindowImpl(WindowImpl&&) = delete; ///TODO? + ~WindowImpl(); - void Destroy(); + bool Create(const VideoMode& mode, const String& title, UInt32 style); + bool Create(WindowHandle handle); - void EnableKeyRepeat(bool enable); - void EnableSmoothScrolling(bool enable); + void Destroy(); - NzWindowHandle GetHandle() const; - unsigned int GetHeight() const; - NzVector2i GetPosition() const; - NzVector2ui GetSize() const; - nzUInt32 GetStyle() const; - NzString GetTitle() const; - unsigned int GetWidth() const; + void EnableKeyRepeat(bool enable); + void EnableSmoothScrolling(bool enable); - bool HasFocus() const; + WindowHandle GetHandle() const; + unsigned int GetHeight() const; + Vector2i GetPosition() const; + Vector2ui GetSize() const; + UInt32 GetStyle() const; + String GetTitle() const; + unsigned int GetWidth() const; - void IgnoreNextMouseEvent(int mouseX, int mouseY); + bool HasFocus() const; - bool IsMinimized() const; - bool IsVisible() const; + void IgnoreNextMouseEvent(int mouseX, int mouseY); - void ProcessEvents(bool block); + bool IsMinimized() const; + bool IsVisible() const; - void SetCursor(nzWindowCursor cursor); - void SetCursor(const NzCursor& cursor); - void SetEventListener(bool listener); - void SetFocus(); - void SetIcon(const NzIcon& icon); - void SetMaximumSize(int width, int height); - void SetMinimumSize(int width, int height); - void SetPosition(int x, int y); - void SetSize(unsigned int width, unsigned int height); - void SetStayOnTop(bool stayOnTop); - void SetTitle(const NzString& title); - void SetVisible(bool visible); + void ProcessEvents(bool block); - static bool Initialize(); - static void Uninitialize(); + void SetCursor(WindowCursor cursor); + void SetCursor(const Cursor& cursor); + void SetEventListener(bool listener); + void SetFocus(); + void SetIcon(const Icon& icon); + void SetMaximumSize(int width, int height); + void SetMinimumSize(int width, int height); + void SetPosition(int x, int y); + void SetSize(unsigned int width, unsigned int height); + void SetStayOnTop(bool stayOnTop); + void SetTitle(const String& title); + void SetVisible(bool visible); - private: + WindowImpl& operator=(const WindowImpl&) = delete; + WindowImpl& operator=(WindowImpl&&) = delete; ///TODO? - void CleanUp(); - xcb_keysym_t ConvertKeyCodeToKeySym(xcb_keycode_t keycode, uint16_t state); - NzKeyboard::Key ConvertVirtualKey(xcb_keysym_t symbol); - const char* ConvertWindowCursorToXName(nzWindowCursor cursor); - void CommonInitialize(); + static bool Initialize(); + static void Uninitialize(); - void ProcessEvent(xcb_generic_event_t* windowEvent); + private: - void ResetVideoMode(); + void CleanUp(); + xcb_keysym_t ConvertKeyCodeToKeySym(xcb_keycode_t keycode, uint16_t state); + Keyboard::Key ConvertVirtualKey(xcb_keysym_t symbol); + const char* ConvertWindowCursorToXName(WindowCursor cursor); + void CommonInitialize(); - void SetCursor(xcb_cursor_t cursor); - void SetMotifHints(); - void SetVideoMode(const NzVideoMode& mode); - void SwitchToFullscreen(); + void ProcessEvent(xcb_generic_event_t* windowEvent); - bool UpdateNormalHints(); - void UpdateEventQueue(xcb_generic_event_t* event); + void ResetVideoMode(); - #if NAZARA_UTILITY_THREADED_WINDOW - static void WindowThread(NzWindowImpl* window, NzMutex* mutex, NzConditionVariable* condition); - #endif + void SetCursor(xcb_cursor_t cursor); + void SetMotifHints(); + void SetVideoMode(const VideoMode& mode); + void SwitchToFullscreen(); - xcb_window_t m_window; - xcb_screen_t* m_screen; - xcb_randr_get_screen_info_reply_t m_oldVideoMode; - xcb_size_hints_t m_size_hints; - nzUInt32 m_style; - #if NAZARA_UTILITY_THREADED_WINDOW - NzThread m_thread; - #endif - NzWindow* m_parent; - bool m_eventListener; - bool m_ownsWindow; - bool m_smoothScrolling; - #if NAZARA_UTILITY_THREADED_WINDOW - bool m_threadActive; - #endif - short m_scrolling; - NzVector2i m_mousePos; - bool m_keyRepeat; + bool UpdateNormalHints(); + void UpdateEventQueue(xcb_generic_event_t* event); + + #if NAZARA_UTILITY_THREADED_WINDOW + static void WindowThread(WindowImpl* window, Mutex* mutex, ConditionVariable* condition); + #endif + + xcb_window_t m_window; + xcb_screen_t* m_screen; + xcb_randr_get_screen_info_reply_t m_oldVideoMode; + xcb_size_hints_t m_size_hints; + UInt32 m_style; + #if NAZARA_UTILITY_THREADED_WINDOW + Thread m_thread; + #endif + Window* m_parent; + bool m_eventListener; + bool m_ownsWindow; + bool m_smoothScrolling; + #if NAZARA_UTILITY_THREADED_WINDOW + bool m_threadActive; + #endif + short m_scrolling; + Vector2i m_mousePos; + bool m_keyRepeat; + + struct + { + xcb_generic_event_t* curr = nullptr; + xcb_generic_event_t* next = nullptr; + } m_eventQueue; + }; +} - struct - { - xcb_generic_event_t* curr = nullptr; - xcb_generic_event_t* next = nullptr; - } m_eventQueue; -}; #endif // NAZARA_WINDOWIMPL_HPP From 20e8ef1436889d1844077e533978367f38927800 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 27 Sep 2015 18:28:43 +0200 Subject: [PATCH 13/97] Update module template Former-commit-id: 49040d563978c2b565f55cab38c92cf7d0a8496a --- .../build/scripts/module/modulename.lua | 33 -------- .../build/scripts/modules/modulename.lua | 15 ++++ .../include/Nazara/ModuleName/ClassName.hpp | 19 +++-- .../include/Nazara/ModuleName/ModuleName.hpp | 23 +++--- .../src/Nazara/ModuleName/ClassName.cpp | 26 +++--- .../Nazara/ModuleName/Debug/NewOverload.cpp | 8 +- .../src/Nazara/ModuleName/ModuleName.cpp | 82 ++++++++++--------- 7 files changed, 102 insertions(+), 104 deletions(-) delete mode 100644 NazaraModuleTemplate/build/scripts/module/modulename.lua create mode 100644 NazaraModuleTemplate/build/scripts/modules/modulename.lua diff --git a/NazaraModuleTemplate/build/scripts/module/modulename.lua b/NazaraModuleTemplate/build/scripts/module/modulename.lua deleted file mode 100644 index cd24f2d12..000000000 --- a/NazaraModuleTemplate/build/scripts/module/modulename.lua +++ /dev/null @@ -1,33 +0,0 @@ -if (not _OPTIONS["united"]) then - project "NazaraModuleName" -end - -files -{ - "../include/Nazara/ModuleName/**.hpp", - "../include/Nazara/ModuleName/**.inl", - "../src/Nazara/ModuleName/**.hpp", - "../src/Nazara/ModuleName/**.cpp" -} - -if (os.is("windows")) then - excludes { "../src/Nazara/ModuleName/Posix/*.hpp", "../src/Nazara/ModuleName/Posix/*.cpp" } -else - excludes { "../src/Nazara/ModuleName/Win32/*.hpp", "../src/Nazara/ModuleName/Win32/*.cpp" } -end - -if (_OPTIONS["united"]) then - excludes "../src/Nazara/ModuleName/Debug/NewOverload.cpp" -else - configuration "DebugStatic" - links "NazaraCore-s-d" - - configuration "ReleaseStatic" - links "NazaraCore-s" - - configuration "DebugDLL" - links "NazaraCore-d" - - configuration "ReleaseDLL" - links "NazaraCore" -end \ No newline at end of file diff --git a/NazaraModuleTemplate/build/scripts/modules/modulename.lua b/NazaraModuleTemplate/build/scripts/modules/modulename.lua new file mode 100644 index 000000000..7f954dd6a --- /dev/null +++ b/NazaraModuleTemplate/build/scripts/modules/modulename.lua @@ -0,0 +1,15 @@ +MODULE.Name = "ModuleName" + +MODULE.Libraries = { + "NazaraCore" +} + +MODULE.OsFiles.Windows = { + "../src/Nazara/ModuleName/Win32/**.hpp", + "../src/Nazara/ModuleName/Win32/**.cpp" +} + +MODULE.OsFiles.Posix = { + "../src/Nazara/ModuleName/Posix/**.hpp", + "../src/Nazara/ModuleName/Posix/**.cpp" +} diff --git a/NazaraModuleTemplate/include/Nazara/ModuleName/ClassName.hpp b/NazaraModuleTemplate/include/Nazara/ModuleName/ClassName.hpp index b3fcc13e2..46bdc8cd9 100644 --- a/NazaraModuleTemplate/include/Nazara/ModuleName/ClassName.hpp +++ b/NazaraModuleTemplate/include/Nazara/ModuleName/ClassName.hpp @@ -9,17 +9,20 @@ #include -class NAZARA_API NzClassName +namespace Nz { - public: - NzClassName(); + class NAZARA_MODULENAME_API API ClassName + { + public: + ClassName(); - int GetAttribute() const; + int GetAttribute() const; - void SetAttribute(int attribute); + void SetAttribute(int attribute); - private: - int m_attribute; -}; + private: + int m_attribute; + }; +} #endif // NAZARA_CLASSNAME_HPP diff --git a/NazaraModuleTemplate/include/Nazara/ModuleName/ModuleName.hpp b/NazaraModuleTemplate/include/Nazara/ModuleName/ModuleName.hpp index 96d9322c9..58284f519 100644 --- a/NazaraModuleTemplate/include/Nazara/ModuleName/ModuleName.hpp +++ b/NazaraModuleTemplate/include/Nazara/ModuleName/ModuleName.hpp @@ -10,20 +10,23 @@ #include #include -class NAZARA_API NzModuleName +namespace Nz { - public: - NzModuleName() = delete; - ~NzModuleName() = delete; + class NAZARA_MODULENAME_API ModuleName + { + public: + ModuleName() = delete; + ~ModuleName() = delete; - static bool Initialize(); + static bool Initialize(); - static bool IsInitialized(); + static bool IsInitialized(); - static void Uninitialize(); + static void Uninitialize(); - private: - static unsigned int s_moduleReferenceCounter; -}; + private: + static unsigned int s_moduleReferenceCounter; + }; +} #endif // NAZARA_MODULENAME_HPP diff --git a/NazaraModuleTemplate/src/Nazara/ModuleName/ClassName.cpp b/NazaraModuleTemplate/src/Nazara/ModuleName/ClassName.cpp index cd6ac9ac7..636cb270c 100644 --- a/NazaraModuleTemplate/src/Nazara/ModuleName/ClassName.cpp +++ b/NazaraModuleTemplate/src/Nazara/ModuleName/ClassName.cpp @@ -5,17 +5,21 @@ #include #include -NzClassName::NzClassName() : -m_attribute(42) +namespace Nz { + ClassName::ClassName() : + m_attribute(42) + { + } + + int ClassName::GetAttribute() const + { + return m_attribute; + } + + void ClassName::SetAttribute(int attribute) + { + m_attribute = attribute; + } } -int NzClassName::GetAttribute() const -{ - return m_attribute; -} - -void NzClassName::SetAttribute(int attribute) -{ - m_attribute = attribute; -} diff --git a/NazaraModuleTemplate/src/Nazara/ModuleName/Debug/NewOverload.cpp b/NazaraModuleTemplate/src/Nazara/ModuleName/Debug/NewOverload.cpp index 468fb119e..a9a767c1d 100644 --- a/NazaraModuleTemplate/src/Nazara/ModuleName/Debug/NewOverload.cpp +++ b/NazaraModuleTemplate/src/Nazara/ModuleName/Debug/NewOverload.cpp @@ -10,22 +10,22 @@ void* operator new(std::size_t size) { - return NzMemoryManager::Allocate(size, false); + return Nz::MemoryManager::Allocate(size, false); } void* operator new[](std::size_t size) { - return NzMemoryManager::Allocate(size, true); + return Nz::MemoryManager::Allocate(size, true); } void operator delete(void* pointer) noexcept { - NzMemoryManager::Free(pointer, false); + Nz::MemoryManager::Free(pointer, false); } void operator delete[](void* pointer) noexcept { - NzMemoryManager::Free(pointer, true); + Nz::MemoryManager::Free(pointer, true); } #endif // NAZARA_MODULENAME_MANAGE_MEMORY diff --git a/NazaraModuleTemplate/src/Nazara/ModuleName/ModuleName.cpp b/NazaraModuleTemplate/src/Nazara/ModuleName/ModuleName.cpp index 09b3d093b..1ae75d7ad 100644 --- a/NazaraModuleTemplate/src/Nazara/ModuleName/ModuleName.cpp +++ b/NazaraModuleTemplate/src/Nazara/ModuleName/ModuleName.cpp @@ -10,55 +10,61 @@ #include #include -bool NzModuleName::Initialize() +namespace Nz { - if (s_moduleReferenceCounter > 0) + bool ModuleName::Initialize() { + if (s_moduleReferenceCounter > 0) + { + s_moduleReferenceCounter++; + return true; // Already initialized + } + + // Initialize module dependencies + if (!NzCore::Initialize()) + { + NazaraError("Failed to initialize core module"); + return false; + } + s_moduleReferenceCounter++; - return true; // Déjà initialisé + + CallOnExit onExit(ModuleName::Uninitialize); + + // Initialize module here + + onExit.Reset(); + + NazaraNotice("Initialized: ModuleName module"); + return true; } - // Initialisation des dépendances - if (!NzCore::Initialize()) + bool ModuleName::IsInitialized() { - NazaraError("Failed to initialize core module"); - return false; + return s_moduleReferenceCounter != 0; } - s_moduleReferenceCounter++; - - // Initialisation du module - NzCallOnExit onExit(NzModuleName::Uninitialize); - - onExit.Reset(); - - NazaraNotice("Initialized: ModuleName module"); - return true; -} - -bool NzModuleName::IsInitialized() -{ - return s_moduleReferenceCounter != 0; -} - -void NzModuleName::Uninitialize() -{ - if (s_moduleReferenceCounter != 1) + void ModuleName::Uninitialize() { - // Le module est soit encore utilisé, soit pas initialisé - if (s_moduleReferenceCounter > 1) - s_moduleReferenceCounter--; + if (s_moduleReferenceCounter != 1) + { + // Le module est soit encore utilisé, soit pas initialisé + if (s_moduleReferenceCounter > 1) + s_moduleReferenceCounter--; - return; + return; + } + + s_moduleReferenceCounter = 0; + + // Uninitialize module here + + NazaraNotice("Uninitialized: ModuleName module"); + + // Free module dependencies + Core::Uninitialize(); } - // Libération du module - s_moduleReferenceCounter = 0; - - NazaraNotice("Uninitialized: ModuleName module"); - - // Libération des dépendances - NzCore::Uninitialize(); + unsigned int ModuleName::s_moduleReferenceCounter = 0; } -unsigned int NzModuleName::s_moduleReferenceCounter = 0; From 6fe20d067ab27a6a47c09aa52c1978428562f2d1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Sep 2015 00:40:51 +0200 Subject: [PATCH 14/97] Audio: Fix Enums.hpp header guard Former-commit-id: 2bc99eb04bf63173a9627385de1de40fe18b434e --- include/Nazara/Audio/Enums.hpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Audio/Enums.hpp b/include/Nazara/Audio/Enums.hpp index e88a2fa92..b8d3e3ec6 100644 --- a/include/Nazara/Audio/Enums.hpp +++ b/include/Nazara/Audio/Enums.hpp @@ -4,12 +4,11 @@ #pragma once -#ifndef NAZARA_ENUMS_HPP -#define NAZARA_ENUMS_HPP +#ifndef NAZARA_ENUMS_AUDIO_HPP +#define NAZARA_ENUMS_AUDIO_HPP namespace Nz { - enum AudioFormat { AudioFormat_Unknown = -1, @@ -33,4 +32,4 @@ namespace Nz }; } -#endif // NAZARA_ENUMS_HPP +#endif // NAZARA_ENUMS_AUDIO_HPP From 7db9be3cfb61d261428ea9cad609b084ec1ce807 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Sep 2015 00:41:24 +0200 Subject: [PATCH 15/97] Disable memory manager for every module Former-commit-id: 4c6e0a87de57bf55780cc9dfee280cc198d06704 --- NazaraModuleTemplate/include/Nazara/ModuleName/ConfigCheck.hpp | 2 +- include/Nazara/Audio/ConfigCheck.hpp | 2 +- include/Nazara/Graphics/ConfigCheck.hpp | 2 +- include/Nazara/Lua/ConfigCheck.hpp | 2 +- include/Nazara/Noise/ConfigCheck.hpp | 2 +- include/Nazara/Physics/ConfigCheck.hpp | 2 +- include/Nazara/Renderer/ConfigCheck.hpp | 2 +- include/Nazara/Utility/ConfigCheck.hpp | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/NazaraModuleTemplate/include/Nazara/ModuleName/ConfigCheck.hpp b/NazaraModuleTemplate/include/Nazara/ModuleName/ConfigCheck.hpp index 941cd832c..8decf9091 100644 --- a/NazaraModuleTemplate/include/Nazara/ModuleName/ConfigCheck.hpp +++ b/NazaraModuleTemplate/include/Nazara/ModuleName/ConfigCheck.hpp @@ -16,7 +16,7 @@ // On force la valeur de MANAGE_MEMORY en mode debug #if defined(NAZARA_DEBUG) && !NAZARA_MODULENAME_MANAGE_MEMORY #undef NAZARA_MODULENAME_MANAGE_MEMORY - #define NAZARA_MODULENAME_MANAGE_MEMORY 1 + #define NAZARA_MODULENAME_MANAGE_MEMORY 0 #endif #endif // NAZARA_CONFIG_CHECK_MODULENAME_HPP diff --git a/include/Nazara/Audio/ConfigCheck.hpp b/include/Nazara/Audio/ConfigCheck.hpp index 546f77dd0..9ed35c1a4 100644 --- a/include/Nazara/Audio/ConfigCheck.hpp +++ b/include/Nazara/Audio/ConfigCheck.hpp @@ -15,7 +15,7 @@ // On force la valeur de MANAGE_MEMORY en mode debug #if defined(NAZARA_DEBUG) && !NAZARA_AUDIO_MANAGE_MEMORY #undef NAZARA_AUDIO_MANAGE_MEMORY - #define NAZARA_AUDIO_MANAGE_MEMORY 1 + #define NAZARA_AUDIO_MANAGE_MEMORY 0 #endif NazaraCheckTypeAndVal(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, integral, >, 0, " shall be a strictly positive integer"); diff --git a/include/Nazara/Graphics/ConfigCheck.hpp b/include/Nazara/Graphics/ConfigCheck.hpp index 1365688ac..e93c8e0ec 100644 --- a/include/Nazara/Graphics/ConfigCheck.hpp +++ b/include/Nazara/Graphics/ConfigCheck.hpp @@ -15,7 +15,7 @@ // On force la valeur de MANAGE_MEMORY en mode debug #if defined(NAZARA_DEBUG) && !NAZARA_GRAPHICS_MANAGE_MEMORY #undef NAZARA_GRAPHICS_MANAGE_MEMORY - #define NAZARA_GRAPHICS_MANAGE_MEMORY 1 + #define NAZARA_GRAPHICS_MANAGE_MEMORY 0 #endif NazaraCheckTypeAndVal(NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT, integral, >, 0, " shall be a strictly positive integer"); diff --git a/include/Nazara/Lua/ConfigCheck.hpp b/include/Nazara/Lua/ConfigCheck.hpp index 246fe1d52..1701205c8 100644 --- a/include/Nazara/Lua/ConfigCheck.hpp +++ b/include/Nazara/Lua/ConfigCheck.hpp @@ -12,7 +12,7 @@ // On force la valeur de MANAGE_MEMORY en mode debug #if defined(NAZARA_DEBUG) && !NAZARA_LUA_MANAGE_MEMORY #undef NAZARA_LUA_MANAGE_MEMORY - #define NAZARA_LUA_MANAGE_MEMORY 1 + #define NAZARA_LUA_MANAGE_MEMORY 0 #endif #endif // NAZARA_CONFIG_CHECK_LUA_HPP diff --git a/include/Nazara/Noise/ConfigCheck.hpp b/include/Nazara/Noise/ConfigCheck.hpp index 04bbcdeeb..f7682bd28 100644 --- a/include/Nazara/Noise/ConfigCheck.hpp +++ b/include/Nazara/Noise/ConfigCheck.hpp @@ -12,7 +12,7 @@ // On force la valeur de MANAGE_MEMORY en mode debug #if defined(NAZARA_DEBUG) && !NAZARA_NOISE_MANAGE_MEMORY #undef NAZARA_NOISE_MANAGE_MEMORY - #define NAZARA_NOISE_MANAGE_MEMORY 1 + #define NAZARA_NOISE_MANAGE_MEMORY 0 #endif #endif // NAZARA_CONFIG_CHECK_NOISE_HPP diff --git a/include/Nazara/Physics/ConfigCheck.hpp b/include/Nazara/Physics/ConfigCheck.hpp index 3ec7c9599..5721e2660 100644 --- a/include/Nazara/Physics/ConfigCheck.hpp +++ b/include/Nazara/Physics/ConfigCheck.hpp @@ -12,7 +12,7 @@ // On force la valeur de MANAGE_MEMORY en mode debug #if defined(NAZARA_DEBUG) && !NAZARA_PHYSICS_MANAGE_MEMORY #undef NAZARA_PHYSICS_MANAGE_MEMORY - #define NAZARA_PHYSICS_MANAGE_MEMORY 1 + #define NAZARA_PHYSICS_MANAGE_MEMORY 0 #endif #endif // NAZARA_CONFIG_CHECK_PHYSICS_HPP diff --git a/include/Nazara/Renderer/ConfigCheck.hpp b/include/Nazara/Renderer/ConfigCheck.hpp index a90e79785..71cc3d5eb 100644 --- a/include/Nazara/Renderer/ConfigCheck.hpp +++ b/include/Nazara/Renderer/ConfigCheck.hpp @@ -15,7 +15,7 @@ // On force la valeur de MANAGE_MEMORY en mode debug #if defined(NAZARA_DEBUG) && !NAZARA_RENDERER_MANAGE_MEMORY #undef NAZARA_RENDERER_MANAGE_MEMORY - #define NAZARA_RENDERER_MANAGE_MEMORY 1 + #define NAZARA_RENDERER_MANAGE_MEMORY 0 #endif NazaraCheckTypeAndVal(NAZARA_RENDERER_INSTANCE_BUFFER_SIZE, integral, >, 0, " shall be a strictly positive integer"); diff --git a/include/Nazara/Utility/ConfigCheck.hpp b/include/Nazara/Utility/ConfigCheck.hpp index 0018b6e9d..01d224a7a 100644 --- a/include/Nazara/Utility/ConfigCheck.hpp +++ b/include/Nazara/Utility/ConfigCheck.hpp @@ -15,7 +15,7 @@ // On force la valeur de MANAGE_MEMORY en mode debug #if defined(NAZARA_DEBUG) && !NAZARA_UTILITY_MANAGE_MEMORY #undef NAZARA_UTILITY_MANAGE_MEMORY - #define NAZARA_UTILITY_MANAGE_MEMORY 1 + #define NAZARA_UTILITY_MANAGE_MEMORY 0 #endif NazaraCheckTypeAndVal(NAZARA_UTILITY_SKINNING_MAX_WEIGHTS, integral, >, 0, " shall be a strictly positive integer"); From 0112d5746f53025e6e221e6a4bd3ab6574df7bd1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Sep 2015 00:41:36 +0200 Subject: [PATCH 16/97] Update/fix module template Former-commit-id: ec7daea1a67eb2b3124148bcc7cc46bc9566d16c --- .../include/Nazara/ModuleName/ClassName.hpp | 4 ++-- .../include/Nazara/ModuleName/Config.hpp | 10 ++++++++++ .../include/Nazara/ModuleName/DebugOff.hpp | 4 ++-- .../include/Nazara/ModuleName/ModuleName.hpp | 1 + .../src/Nazara/ModuleName/ModuleName.cpp | 4 ++-- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/NazaraModuleTemplate/include/Nazara/ModuleName/ClassName.hpp b/NazaraModuleTemplate/include/Nazara/ModuleName/ClassName.hpp index 46bdc8cd9..e4866c2bc 100644 --- a/NazaraModuleTemplate/include/Nazara/ModuleName/ClassName.hpp +++ b/NazaraModuleTemplate/include/Nazara/ModuleName/ClassName.hpp @@ -7,11 +7,11 @@ #ifndef NAZARA_CLASSNAME_HPP #define NAZARA_CLASSNAME_HPP -#include +#include namespace Nz { - class NAZARA_MODULENAME_API API ClassName + class NAZARA_MODULENAME_API ClassName { public: ClassName(); diff --git a/NazaraModuleTemplate/include/Nazara/ModuleName/Config.hpp b/NazaraModuleTemplate/include/Nazara/ModuleName/Config.hpp index a72f02c69..7f620bb59 100644 --- a/NazaraModuleTemplate/include/Nazara/ModuleName/Config.hpp +++ b/NazaraModuleTemplate/include/Nazara/ModuleName/Config.hpp @@ -40,4 +40,14 @@ /// Vérification des valeurs et types de certaines constantes #include +#if !defined(NAZARA_STATIC) + #ifdef NAZARA_MODULENAME_BUILD + #define NAZARA_MODULENAME_API NAZARA_EXPORT + #else + #define NAZARA_MODULENAME_API NAZARA_IMPORT + #endif +#else + #define NAZARA_MODULENAME_API +#endif + #endif // NAZARA_CONFIG_MODULENAME_HPP diff --git a/NazaraModuleTemplate/include/Nazara/ModuleName/DebugOff.hpp b/NazaraModuleTemplate/include/Nazara/ModuleName/DebugOff.hpp index b2106a5f4..3e9cda8eb 100644 --- a/NazaraModuleTemplate/include/Nazara/ModuleName/DebugOff.hpp +++ b/NazaraModuleTemplate/include/Nazara/ModuleName/DebugOff.hpp @@ -1,9 +1,9 @@ -// Copyright (C) 2014 AUTHORS +// Copyright (C) YEAR AUTHORS // This file is part of the "Nazara Engine - Module name" // For conditions of distribution and use, see copyright notice in Config.hpp // On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp -#if NAZARA_MODULENAME_HPP +#if NAZARA_MODULENAME_MANAGE_MEMORY #undef delete #undef new #endif diff --git a/NazaraModuleTemplate/include/Nazara/ModuleName/ModuleName.hpp b/NazaraModuleTemplate/include/Nazara/ModuleName/ModuleName.hpp index 58284f519..031f37d9a 100644 --- a/NazaraModuleTemplate/include/Nazara/ModuleName/ModuleName.hpp +++ b/NazaraModuleTemplate/include/Nazara/ModuleName/ModuleName.hpp @@ -9,6 +9,7 @@ #include #include +#include namespace Nz { diff --git a/NazaraModuleTemplate/src/Nazara/ModuleName/ModuleName.cpp b/NazaraModuleTemplate/src/Nazara/ModuleName/ModuleName.cpp index 1ae75d7ad..e286520f8 100644 --- a/NazaraModuleTemplate/src/Nazara/ModuleName/ModuleName.cpp +++ b/NazaraModuleTemplate/src/Nazara/ModuleName/ModuleName.cpp @@ -21,7 +21,7 @@ namespace Nz } // Initialize module dependencies - if (!NzCore::Initialize()) + if (!Core::Initialize()) { NazaraError("Failed to initialize core module"); return false; @@ -48,7 +48,7 @@ namespace Nz { if (s_moduleReferenceCounter != 1) { - // Le module est soit encore utilisé, soit pas initialisé + // Either the module is not initialized, either it was initialized multiple times if (s_moduleReferenceCounter > 1) s_moduleReferenceCounter--; From 05056d41de7bf92c3829d01e53b104f3b4bc4e3e Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Sep 2015 00:41:59 +0200 Subject: [PATCH 17/97] Build: Fix project generation for Linux Former-commit-id: 9e0787779d9c8fa84f3f41a6f75e7bf29be403d4 --- build/scripts/common.lua | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index b1da33015..90afe4217 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -6,6 +6,8 @@ function NazaraBuild:Execute() end if (self.Actions[_ACTION] == nil) then + local makeLibDir = os.is("windows") and "mingw" or "gmake" + if (#self.OrderedExtLibs > 0) then solution("NazaraExtlibs") platforms({"x32", "x64"}) @@ -28,12 +30,12 @@ function NazaraBuild:Execute() libdirs("../extlibs/lib/common/x64") configuration({"codeblocks or codelite or gmake", "x32"}) - libdirs("../extlibs/lib/mingw/x86") - targetdir("../extlibs/lib/mingw/x86") + libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") + targetdir("../extlibs/lib/" .. makeLibDir .. "/x86") configuration({"codeblocks or codelite or gmake", "x64"}) - libdirs("../extlibs/lib/mingw/x64") - targetdir("../extlibs/lib/mingw/x64") + libdirs("../extlibs/lib/" .. makeLibDir .. "/x64") + targetdir("../extlibs/lib/" .. makeLibDir .. "/x64") configuration("vs*") buildoptions("/MP") @@ -71,7 +73,7 @@ function NazaraBuild:Execute() targetsuffix("-s") configuration("codeblocks or codelite or gmake or xcode3 or xcode4") - buildoptions("-std=c++14") + buildoptions({"-fPIC", "-std=c++14"}) for k, libTable in ipairs(self.OrderedExtLibs) do project(libTable.Name) @@ -171,14 +173,14 @@ function NazaraBuild:Execute() libdirs("../extlibs/lib/common/x64") configuration({"codeblocks or codelite or gmake", "x32"}) - libdirs("../extlibs/lib/mingw/x86") - libdirs("../lib/mingw/x86") - targetdir("../lib/mingw/x86") + libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") + libdirs("../lib/" .. makeLibDir .. "/x86") + targetdir("../lib/" .. makeLibDir .. "/x86") configuration({"codeblocks or codelite or gmake", "x64"}) - libdirs("../extlibs/lib/mingw/x64") - libdirs("../lib/mingw/x64") - targetdir("../lib/mingw/x64") + libdirs("../extlibs/lib/" .. makeLibDir .. "/x64") + libdirs("../lib/" .. makeLibDir .. "/x64") + targetdir("../lib/" .. makeLibDir .. "/x64") configuration({"vs*", "x32"}) libdirs("../extlibs/lib/msvc/x86") @@ -268,17 +270,17 @@ function NazaraBuild:Execute() libdirs("../extlibs/lib/common/x64") configuration({"codeblocks or codelite or gmake", "x32"}) - libdirs("../extlibs/lib/mingw/x86") - libdirs("../lib/mingw/x86") + libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") + libdirs("../lib/" .. makeLibDir .. "/x86") if (toolTable.Kind == "library") then - targetdir("../lib/mingw/x86") + targetdir("../lib/" .. makeLibDir .. "/x86") end configuration({"codeblocks or codelite or gmake", "x64"}) - libdirs("../extlibs/lib/mingw/x64") - libdirs("../lib/mingw/x64") + libdirs("../extlibs/lib/" .. makeLibDir .. "/x64") + libdirs("../lib/" .. makeLibDir .. "/x64") if (toolTable.Kind == "library") then - targetdir("../lib/mingw/x64") + targetdir("../lib/" .. makeLibDir .. "/x64") end configuration({"vs*", "x32"}) @@ -379,10 +381,10 @@ function NazaraBuild:Execute() libdirs("../extlibs/lib/common/x64") configuration({"codeblocks or codelite or gmake", "x32"}) - libdirs("../lib/mingw/x86") + libdirs("../lib/" .. makeLibDir .. "/x86") configuration({"codeblocks or codelite or gmake", "x64"}) - libdirs("../lib/mingw/x64") + libdirs("../lib/" .. makeLibDir .. "/x64") configuration({"vs*", "x32"}) libdirs("../lib/msvc/x86") From f54eb0402f8d22af2f733b19966b9941a9a095ee Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Sep 2015 12:41:41 +0200 Subject: [PATCH 18/97] Examples: Fix MeshInfos Former-commit-id: b6c5ea953f60d2b22eaa6aae06d1618efdb09bc1 --- examples/MeshInfos/main.cpp | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/examples/MeshInfos/main.cpp b/examples/MeshInfos/main.cpp index 839c20f31..ba55d2686 100644 --- a/examples/MeshInfos/main.cpp +++ b/examples/MeshInfos/main.cpp @@ -11,7 +11,7 @@ int main() { // Pour charger des ressources, il est impératif d'initialiser le module utilitaire - Initializer utility; + Nz::Initializer utility; if (!utility) { // Ça n'a pas fonctionné, le pourquoi se trouve dans le fichier NazaraLog.log @@ -22,7 +22,7 @@ int main() for (;;) { - Directory resourceDirectory("resources/"); + Nz::Directory resourceDirectory("resources/"); if (!resourceDirectory.Open()) { std::cerr << "Failed to open resource directory" << std::endl; @@ -30,12 +30,12 @@ int main() return EXIT_FAILURE; } - std::vector models; + std::vector models; while (resourceDirectory.NextResult()) { - String path = resourceDirectory.GetResultName(); - String ext = path.SubStringFrom('.', -1, true); // Tout ce qui vient après le dernier '.' de la chaîne - if (MeshLoader::IsExtensionSupported(ext)) // L'extension est-elle supportée par le MeshLoader ? + Nz::String path = resourceDirectory.GetResultName(); + Nz::String ext = path.SubStringFrom('.', -1, true); // Tout ce qui vient après le dernier '.' de la chaîne + if (Nz::MeshLoader::IsExtensionSupported(ext)) // L'extension est-elle supportée par le MeshLoader ? models.push_back(path); } @@ -67,7 +67,7 @@ int main() if (iChoice == 0) break; - Mesh mesh; + Nz::Mesh mesh; if (!mesh.LoadFromFile("resources/" + models[iChoice-1])) { std::cout << "Failed to load mesh" << std::endl; @@ -77,11 +77,11 @@ int main() switch (mesh.GetAnimationType()) { - case AnimationType_Skeletal: + case Nz::AnimationType_Skeletal: std::cout << "This is a skeletal-animated mesh" << std::endl; break; - case AnimationType_Static: + case Nz::AnimationType_Static: std::cout << "This is a static mesh" << std::endl; break; @@ -92,9 +92,9 @@ int main() if (mesh.IsAnimable()) { - if (mesh.GetAnimationType() == AnimationType_Skeletal) + if (mesh.GetAnimationType() == Nz::AnimationType_Skeletal) { - const Skeleton* skeleton = mesh.GetSkeleton(); + const Nz::Skeleton* skeleton = mesh.GetSkeleton(); unsigned int jointCount = skeleton->GetJointCount(); std::cout << "It has a skeleton made of " << skeleton->GetJointCount() << " joint(s)." << std::endl; std::cout << "Print joints ? (Y/N) "; @@ -107,10 +107,10 @@ int main() { for (unsigned int i = 0; i < jointCount; ++i) { - const Joint* joint = skeleton->GetJoint(i); + const Nz::Joint* joint = skeleton->GetJoint(i); std::cout << "\t" << (i+1) << ": " << joint->GetName(); - const Joint* parent = static_cast(joint->GetParent()); + const Nz::Joint* parent = static_cast(joint->GetParent()); if (parent) std::cout << " (Parent: " << parent->GetName() << ')'; @@ -119,10 +119,10 @@ int main() } } - String animationPath = mesh.GetAnimation(); + Nz::String animationPath = mesh.GetAnimation(); if (!animationPath.IsEmpty()) { - Animation animation; + Nz::Animation animation; if (animation.LoadFromFile(animationPath)) { unsigned int sequenceCount = animation.GetSequenceCount(); @@ -137,7 +137,7 @@ int main() { for (unsigned int i = 0; i < sequenceCount; ++i) { - const Sequence* sequence = animation.GetSequence(i); + const Nz::Sequence* sequence = animation.GetSequence(i); std::cout << "\t" << (i+1) << ": " << sequence->name << std::endl; std::cout << "\t\tStart frame: " << sequence->firstFrame << std::endl; std::cout << "\t\tFrame count: " << sequence->frameCount << std::endl; @@ -153,7 +153,7 @@ int main() std::cout << "It's animable but has no animation information" << std::endl; } - Boxf cube = mesh.GetAABB(); + Nz::Boxf cube = mesh.GetAABB(); std::cout << "Mesh is " << cube.width << " units wide, " << cube.height << " units height and " << cube.depth << " units depth" << std::endl; unsigned int materialCount = mesh.GetMaterialCount(); From 1db673f9be012eb21eb087b894e8c073232149a3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Sep 2015 13:56:33 +0200 Subject: [PATCH 19/97] Example: Update FirstScene for NDK Former-commit-id: d14aad9f6a616796b92b78934e413b588a8e3185 --- examples/FirstScene/build.lua | 3 +- examples/FirstScene/main.cpp | 277 ++++++++++++++++++++-------------- 2 files changed, 165 insertions(+), 115 deletions(-) diff --git a/examples/FirstScene/build.lua b/examples/FirstScene/build.lua index b7f8a146a..bdcdf8bca 100644 --- a/examples/FirstScene/build.lua +++ b/examples/FirstScene/build.lua @@ -10,5 +10,6 @@ EXAMPLE.Libraries = { "NazaraCore", "NazaraGraphics", "NazaraRenderer", - "NazaraUtility" + "NazaraUtility", + "NazaraSDK" } diff --git a/examples/FirstScene/main.cpp b/examples/FirstScene/main.cpp index 9ed702a69..24fef574f 100644 --- a/examples/FirstScene/main.cpp +++ b/examples/FirstScene/main.cpp @@ -15,18 +15,25 @@ #include // Module graphique #include // Module de rendu #include // Module utilitaire +#include +#include +#include +#include +#include +#include +#include #include // Petite fonction permettant de rendre le déplacement de la caméra moins ridige -NzVector3f DampedString(const NzVector3f& currentPos, const NzVector3f& targetPos, float frametime, float springStrength = 3.f); +Nz::Vector3f DampedString(const Nz::Vector3f& currentPos, const Nz::Vector3f& targetPos, float frametime, float springStrength = 3.f); int main() { - // Pour commencer, nous initialisons le module Graphique, celui-ci va provoquer l'initialisation (dans l'ordre), - // du noyau (Core), Utility, Renderer. + // Pour commencer, nous initialisons le SDK de Nazara, celui-ci va préparer le terrain en initialisant le moteur, + // les composants, systèmes, etc. // NzInitializer est une classe RAII appelant Initialize dans son constructeur et Uninitialize dans son destructeur. // Autrement dit, une fois ceci fait nous n'avons plus à nous soucier de la libération du moteur. - NzInitializer nazara; + Nz::Initializer nazara; if (!nazara) { // Une erreur s'est produite dans l'initialisation d'un des modules @@ -36,17 +43,16 @@ int main() return EXIT_FAILURE; } - // Nazara étant initialisé, nous pouvons créer la scène - // Une scène représente tout ce qui est visible par une ou plusieurs caméras. - // La plupart du temps vous n'aurez pas besoin de plus d'une scène, mais cela peut se révéler utile pour mieux - // organiser et optimiser le rendu. - // Par exemple, une pièce contenant une télévision, laquelle affichant des images provenant d'une Camera - // Le rendu sera alors plus efficace en créant deux scènes, une pour la pièce et l'autre pour les images de la télé. - // Cela diminuera le nombre de SceneNode à gérer pour chaque scène, et vous permettra même de ne pas afficher la scène - // affichée dans la télé si cette dernière n'est pas visible dans la première scène. - NzScene scene; + // Nazara étant initialisé, nous pouvons créer le monde pour contenir notre scène. + // Dans un ECS, le monde représente bien ce que son nom indique, c'est l'ensemble de ce qui existe au niveau de l'application. + // Il contient les systèmes et les entités, ces dernières contiennent les composants. + // Il est possible d'utiliser plusieurs mondes au sein d'une même application, par exemple pour gérer un mélange de 2D et de 3D, + // mais nous verrons cela dans un prochain exemple. + Ndk::World world; - // La première chose que nous faisons est d'ajouter un background (fond) à la scène. + // Nous pouvons maintenant ajouter des systèmes, mais dans cet exemple nous nous contenterons de ceux de base. + + // La première chose que nous faisons est d'ajouter un background (fond) à notre scène. // Il en existe plusieurs types, le moteur inclut pour l'instant trois d'entre eux: // -ColorBackground: Une couleur unie en fond // -SkyboxBackground: Une skybox en fond, un cube à six faces rendu autour de la caméra (En perdant la notion de distance) @@ -56,53 +62,59 @@ int main() // Pour commencer il faut charger une texture de type cubemap, certaines images sont assemblées de cette façon, // comme celle que nous allons utiliser. // En réalité les textures "cubemap" regroupent six faces en une, pour faciliter leur utilisation. - NzTexture* texture = new NzTexture; + + // Nous créons une nouvelle texture et prenons une référence sur celle-ci (à la manière des pointeurs intelligents) + Nz::TextureRef texture = Nz::Texture::New(); if (texture->LoadCubemapFromFile("resources/skybox-space.png")) { // Si la création du cubemap a fonctionné - // Nous indiquons que la texture est "non-persistente", autrement dit elle sera libérée automatiquement par le moteur - // à l'instant précis où elle ne sera plus utilisée, dans ce cas-ci, ce sera à la libération de l'objet skybox, - // ceci arrivant lorsqu'un autre background est affecté à la scène, ou lorsque la scène sera libérée - texture->SetPersistent(false); + // Nous créons alors le background à partir de notre texture (celui-ci va référencer notre texture, notre pointeur ne sert alors plus à rien). + Nz::SkyboxBackgroundRef skybox = Nz::SkyboxBackground::New(std::move(texture)); - // Nous créons le background en lui affectant la texture - NzSkyboxBackground* background = new NzSkyboxBackground(texture); + // Accédons maintenant au système de rendu faisant partie du monde + Ndk::RenderSystem& renderSystem = world.GetSystem(); // Une assertion valide la précondition "le système doit faire partie du monde" - // Nous pouvons en profiter pour paramétrer le background. - // Cependant, nous n'avons rien de spécial à faire ici, nous pouvons donc l'envoyer à la scène. - scene.SetBackground(background); + // Nous assignons ensuite notre skybox comme "fond par défaut" du système + // La notion "par défaut" existe parce qu'une caméra pourrait utiliser son propre fond lors du rendu, + // le fond par défaut est utilisé lorsque la caméra n'a pas de fond propre assigné + renderSystem.SetDefaultBackground(std::move(skybox)); - // Comme indiqué plus haut, la scène s'occupera automatiquement de la libération de notre background + // Notre skybox est maintenant référencée par le système, lui-même appartenant au monde, aucune libération explicite n'est nécessaire } else - { - delete texture; // Le chargement a échoué, nous libérons la texture + // Le chargement a échoué std::cout << "Failed to load skybox" << std::endl; - } // Ensuite, nous allons rajouter un modèle à notre scène. + // Les modèles représentent, globalement, tout ce qui est visible en trois dimensions. // Nous choisirons ici un vaisseau spatial (Quoi de mieux pour une scène spatiale ?) - NzModel* spaceship = scene.CreateNode(); // Création depuis la scène - // Une structure permettant de paramétrer le chargement des modèles - NzModelParameters params; + // Encore une fois, nous récupérons une référence plutôt que l'objet lui-même (cela va être très utile par la suite) + Nz::ModelRef spaceshipModel = Nz::Model::New(); - // Le format OBJ ne précise aucune échelle pour ses données, contrairement à Nazara (une unité = un mètre). - // Comme le vaisseau est très grand (Des centaines de mètres de long), nous allons le rendre plus petit - // pour les besoins de la démo. + // Nous allons charger notre modèle depuis un fichier, mais nous pouvons ajuster le modèle lors du chargement via + // une structure permettant de paramétrer le chargement des modèles + Nz::ModelParameters params; + + // Le format OBJ ne précise aucune échelle pour ses données, contrairement à Nazara (une unité = un mètre en 3D). + // Comme le vaisseau est très grand (Des centaines de mètres de long), nous allons le rendre plus petit pour les besoins de la démo. // Ce paramètre sert à indiquer la mise à l'échelle désirée lors du chargement du modèle. params.mesh.scale.Set(0.01f); // Un centième de la taille originelle - // Les UVs de ce fichier sont retournées (repère OpenGL, origine coin bas-gauche) par rapport à ce que le moteur attend - // Nous devons dire au moteur de les retourner lors du chargement + // Les UVs de ce fichier sont retournées (repère OpenGL, origine coin bas-gauche) par rapport à ce que le moteur attend (haut-gauche) + // Nous devons donc indiquer au moteur de les retourner lors du chargement params.mesh.flipUVs = true; + // Nazara va par défaut optimiser les modèles pour un rendu plus rapide, cela peut prendre du temps et n'est pas nécessaire ici + params.mesh.optimizeIndexBuffers = false; + // On charge ensuite le modèle depuis son fichier // Le moteur va charger le fichier et essayer de retrouver les fichiers associés (comme les matériaux, textures, ...) - if (!spaceship->LoadFromFile("resources/Spaceship/spaceship.obj", params)) + if (!spaceshipModel->LoadFromFile("resources/Spaceship/spaceship.obj", params)) { + // Si le chargement a échoué (fichier inexistant/invalide), il ne sert à rien de continuer std::cout << "Failed to load spaceship" << std::endl; std::getchar(); @@ -111,15 +123,18 @@ int main() // Nous voulons afficher quelques statistiques relatives au modèle, comme le nombre de sommets et de triangles // Pour cela, nous devons accéder au mesh (maillage 3D) - NzMesh* mesh = spaceship->GetMesh(); + // Note: Si nous voulions stocker le mesh pour nous en servir après, nous devrions alors récupérer une référence pour nous assurer + // qu'il ne sera pas supprimé tant que nous l'utilisons, mais ici nous faisons un accès direct et ne nous servons plus du pointeur par la suite + // Il est donc acceptable d'utiliser un pointeur nu ici. + Nz::Mesh* mesh = spaceshipModel->GetMesh(); std::cout << mesh->GetVertexCount() << " sommets" << std::endl; std::cout << mesh->GetTriangleCount() << " triangles" << std::endl; // En revanche, le format OBJ ne précise pas l'utilisation d'une normal map, nous devons donc la charger manuellement // Pour commencer on récupère le matériau du mesh, celui-ci en possède plusieurs mais celui qui nous intéresse, // celui de la coque, est le second (Cela est bien entendu lié au modèle en lui-même) - NzMaterial* material = spaceship->GetMaterial(1); + Nz::Material* material = spaceshipModel->GetMaterial(1); // Encore une fois nous ne faisons qu'un accès direct. // On lui indique ensuite le chemin vers la normal map if (!material->SetNormalMap("resources/Spaceship/Texture/normal.png")) @@ -129,27 +144,58 @@ int main() std::cout << "Failed to load normal map" << std::endl; } - // Nous avons besoin également d'une caméra, pour des raisons évidentes, celle-ci sera à l'écart du modèle + // Bien, nous avons un modèle valide, mais celui-ci ne consiste qu'en des informations de rendu, de matériaux et de textures. + // Commençons donc par créer une entité vide, cela se fait en demandant au monde de générer une nouvelle entité. + Ndk::EntityHandle spaceship = world.CreateEntity(); + + // Note: Nous ne récupérons pas l'entité directement mais un "handle" vers elle, ce dernier est un pointeur intelligent non-propriétaire. + // Pour des raisons techniques, le pointeur de l'entité peut venir à changer, ou l'entité être simplement détruite pour n'importe quelle raison. + // Le Handle nous permet de maintenir un pointeur valide vers notre entité, et invalidé automatiquement à sa mort. + + // Nous avons désormais une entité, mais celle-ci ne contient rien et n'a d'autre propriété qu'un identifiant + // Nous devons donc lui rajouter les composants que nous voulons. + + // Un NodeComponent donne à notre entité une position, rotation, échelle, et nous permet de l'attacher à d'autres entités (ce que nous ne ferons pas ici). + // Étant donné que par défaut, un NodeComponent se place en (0,0,0) sans rotation et avec une échelle de 1,1,1 et que cela nous convient, + // nous n'avons pas besoin d'agir sur le composant créé. + spaceship->AddComponent(); + + // Bien, notre entité nouvellement créé dispose maintenant d'une position dans la scène, mais est toujours invisible + // Nous lui ajoutons donc un GraphicsComponent + Ndk::GraphicsComponent& spaceshipGraphics = spaceship->AddComponent(); + + // Ce composant sert de point d'attache pour tous les renderables instanciés (tels que les modèles, les sprites, le texte, etc.) + // Cela signifie également qu'un modèle peut être attaché à autant d'entités que nécessaire. + // Note: Afin de maximiser les performances, essayez d'avoir le moins de renderables instanciés/matériaux et autres ressources possible + // le moteur fonctionne selon le batching et regroupera par exemple tous les modèles identiques ensembles lors du rendu. + spaceshipGraphics.Attach(spaceshipModel); + + // Nous avons besoin également d'une caméra pour servir de point de vue à notre scène, celle-ci sera à l'écart du modèle // regardant dans sa direction. // On conserve la rotation à part via des angles d'eulers pour la caméra free-fly - NzEulerAnglesf camAngles(0.f, -20.f, 0.f); + Nz::EulerAnglesf camAngles(0.f, -20.f, 0.f); - NzCamera camera; - camera.SetPosition(0.f, 0.25f, 2.f); // On place la caméra à l'écart - camera.SetRotation(camAngles); + // Nous créons donc une seconde entité + // Note: La création d'entité est une opération légère au sein du moteur, mais plus vous aurez d'entités et plus le processeur devra travailler. + Ndk::EntityHandle camera = world.CreateEntity(); + + // Notre caméra a elle aussi besoin d'être positionnée dans la scène + Ndk::NodeComponent& cameraNode = camera->AddComponent(); + cameraNode.SetPosition(0.f, 0.25f, 2.f); // On place la caméra à l'écart + cameraNode.SetRotation(camAngles); + + // Et dispose d'un composant pour chaque point de vue de la scène, le CameraComponent + Ndk::CameraComponent& cameraComp = camera->AddComponent(); // Et on n'oublie pas de définir les plans délimitant le champs de vision // (Seul ce qui se trouvera entre les deux plans sera rendu) // La distance entre l'oeil et le plan éloigné - camera.SetZFar(5000.f); + cameraComp.SetZFar(5000.f); // La distance entre l'oeil et le plan rapproché (0 est une valeur interdite car la division par zéro l'est également) - camera.SetZNear(0.1f); - - // On indique à la scène que le viewer (Le point de vue) sera la caméra - scene.SetViewer(camera); + cameraComp.SetZNear(0.1f); // Attention que le ratio entre les deux (zFar/zNear) doit rester raisonnable, dans le cas contraire vous risquez un phénomène // de "Z-Fighting" (Impossibilité de déduire quelle surface devrait apparaître en premier) sur les surfaces éloignées. @@ -160,40 +206,47 @@ int main() // -PointLight: Lumière située à un endroit précis, envoyant de la lumière finie dans toutes les directions // -SpotLight: Lumière située à un endroit précis, envoyant de la lumière vers un endroit donné, avec un angle de diffusion - // Nous créons une lumière directionnelle pour représenter la nébuleuse de notre skybox - NzLight* nebulaLight = scene.CreateNode(nzLightType_Directional); + // Nous allons créer une lumière directionnelle pour représenter la nébuleuse de notre skybox + // Encore une fois, nous créons notre entité + Ndk::EntityHandle nebulaLight = world.CreateEntity(); + + // Lui ajoutons une position dans la scène + Ndk::NodeComponent& nebulaLightNode = nebulaLight->AddComponent(); + + // Et ensuite le composant principal, le LightComponent + Ndk::LightComponent& nebulaLightComp = nebulaLight->AddComponent(Nz::LightType_Directional); // Il nous faut ensuite configurer la lumière // Pour commencer, sa couleur, la nébuleuse étant d'une couleur jaune, j'ai choisi ces valeurs - nebulaLight->SetColor(NzColor(255, 182, 90)); + nebulaLightComp.SetColor(Nz::Color(255, 182, 90)); // Nous appliquons ensuite une rotation de sorte que la lumière dans la même direction que la nébuleuse - nebulaLight->SetRotation(NzEulerAnglesf(0.f, 102.f, 0.f)); + nebulaLightNode.SetRotation(Nz::EulerAnglesf(0.f, 102.f, 0.f)); // Nous allons maintenant créer la fenêtre, dans laquelle nous ferons nos rendus // Celle-ci demande des paramètres plus complexes // Pour commencer le mode vidéo, celui-ci va définir la taille de la zone de rendu et le nombre de bits par pixels - NzVideoMode mode = NzVideoMode::GetDesktopMode(); // Nous récupérons le mode vidéo du bureau + Nz::VideoMode mode = Nz::VideoMode::GetDesktopMode(); // Nous récupérons le mode vidéo du bureau // Nous allons prendre les trois quarts de la résolution du bureau pour notre fenêtre - mode.width *= 3.f/4.f; - mode.height *= 3.f/4.f; + mode.width = 3 * mode.width / 4; + mode.height = 3 * mode.height / 4; // Maintenant le titre, rien de plus simple... - NzString windowTitle = "Nazara Demo - First scene"; + Nz::String windowTitle = "Nazara Demo - First scene"; // Ensuite, le "style" de la fenêtre, possède-t-elle des bordures, peut-on cliquer sur la croix de fermeture, // peut-on la redimensionner, ... - nzWindowStyleFlags style = nzWindowStyle_Default; // Nous prenons le style par défaut, autorisant tout ce que je viens de citer + Nz::WindowStyleFlags style = Nz::WindowStyle_Default; // Nous prenons le style par défaut, autorisant tout ce que je viens de citer // Ensuite, les paramètres du contexte de rendu // On peut configurer le niveau d'antialiasing, le nombre de bits du depth buffer et le nombre de bits du stencil buffer // Nous désirons avoir un peu d'antialiasing (4x), les valeurs par défaut pour le reste nous conviendrons très bien - NzRenderTargetParameters parameters; + Nz::RenderTargetParameters parameters; parameters.antialiasingLevel = 4; - NzRenderWindow window(mode, windowTitle, style, parameters); + Nz::RenderWindow window(mode, windowTitle, style, parameters); if (!window.IsValid()) { std::cout << "Failed to create render window" << std::endl; @@ -203,62 +256,63 @@ int main() } // On fait disparaître le curseur de la souris - window.SetCursor(nzWindowCursor_None); + window.SetCursor(Nz::WindowCursor_None); // On lie la caméra à la fenêtre - camera.SetTarget(window); + cameraComp.SetTarget(&window); // Et on créé deux horloges pour gérer le temps - NzClock secondClock, updateClock; + Nz::Clock secondClock, updateClock; + Nz::UInt64 updateAccumulator = 0; // Ainsi qu'un compteur de FPS improvisé unsigned int fps = 0; // Quelques variables de plus pour notre caméra bool smoothMovement = true; - NzVector3f targetPos = camera.GetPosition(); + Nz::Vector3f targetPos = cameraNode.GetPosition(); // Début de la boucle de rendu du programme while (window.IsOpen()) { // Ensuite nous allons traiter les évènements (Étape indispensable pour la fenêtre) - NzEvent event; + Nz::WindowEvent event; while (window.PollEvent(&event)) { switch (event.type) { - case nzEventType_MouseMoved: // La souris a bougé + case Nz::WindowEventType_MouseMoved: // La souris a bougé { // Gestion de la caméra free-fly (Rotation) float sensitivity = 0.3f; // Sensibilité de la souris // On modifie l'angle de la caméra grâce au déplacement relatif sur X de la souris - camAngles.yaw = NzNormalizeAngle(camAngles.yaw - event.mouseMove.deltaX*sensitivity); + camAngles.yaw = Nz::NormalizeAngle(camAngles.yaw - event.mouseMove.deltaX*sensitivity); // Idem, mais pour éviter les problèmes de calcul de la matrice de vue, on restreint les angles - camAngles.pitch = NzClamp(camAngles.pitch - event.mouseMove.deltaY*sensitivity, -89.f, 89.f); + camAngles.pitch = Nz::Clamp(camAngles.pitch - event.mouseMove.deltaY*sensitivity, -89.f, 89.f); // On applique les angles d'Euler à notre caméra - camera.SetRotation(camAngles); + cameraNode.SetRotation(camAngles); // Pour éviter que le curseur ne sorte de l'écran, nous le renvoyons au centre de la fenêtre // Cette fonction est codée de sorte à ne pas provoquer d'évènement MouseMoved - NzMouse::SetPosition(window.GetWidth()/2, window.GetHeight()/2, window); + Nz::Mouse::SetPosition(window.GetWidth()/2, window.GetHeight()/2, window); break; } - case nzEventType_Quit: // L'utilisateur a cliqué sur la croix, ou l'OS veut terminer notre programme + case Nz::WindowEventType_Quit: // L'utilisateur a cliqué sur la croix, ou l'OS veut terminer notre programme window.Close(); // On demande la fermeture de la fenêtre (Qui aura lieu au prochain tour de boucle) break; - case nzEventType_KeyPressed: // Une touche a été pressée ! - if (event.key.code == NzKeyboard::Key::Escape) + case Nz::WindowEventType_KeyPressed: // Une touche a été pressée ! + if (event.key.code == Nz::Keyboard::Key::Escape) window.Close(); - else if (event.key.code == NzKeyboard::F1) + else if (event.key.code == Nz::Keyboard::F1) { if (smoothMovement) { - targetPos = camera.GetPosition(); + targetPos = cameraNode.GetPosition(); smoothMovement = false; } else @@ -271,68 +325,63 @@ int main() } } + Nz::UInt64 elapsedUS = updateClock.GetMicroseconds(); + // On relance l'horloge + updateClock.Restart(); + // Mise à jour (Caméra) - if (updateClock.GetMilliseconds() >= 1000/60) // 60 fois par seconde + const Nz::UInt64 updateRate = 1000000 / 60; // 60 fois par seconde + updateAccumulator += elapsedUS; + + if (updateAccumulator >= updateRate) { - // Le temps écoulé depuis la dernière fois que ce bloc a été exécuté - float elapsedTime = updateClock.GetSeconds(); + // Le temps écoulé en seconde depuis la dernière fois que ce bloc a été exécuté + float elapsedTime = updateAccumulator / 1000000.f; + std::cout << elapsedTime << std::endl; // Vitesse de déplacement de la caméra float cameraSpeed = 3.f * elapsedTime; // Trois mètres par seconde // Si la touche espace est enfoncée, notre vitesse de déplacement est multipliée par deux - if (NzKeyboard::IsKeyPressed(NzKeyboard::Space)) + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Space)) cameraSpeed *= 2.f; // Pour que nos déplacement soient liés à la rotation de la caméra, nous allons utiliser // les directions locales de la caméra // Si la flèche du haut ou la touche Z (vive ZQSD) est pressée, on avance - if (NzKeyboard::IsKeyPressed(NzKeyboard::Up) || NzKeyboard::IsKeyPressed(NzKeyboard::Z)) - targetPos += camera.GetForward() * cameraSpeed; + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Up) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Z)) + targetPos += cameraNode.GetForward() * cameraSpeed; // Si la flèche du bas ou la touche S est pressée, on recule - if (NzKeyboard::IsKeyPressed(NzKeyboard::Down) || NzKeyboard::IsKeyPressed(NzKeyboard::S)) - targetPos += camera.GetBackward() * cameraSpeed; + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Down) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::S)) + targetPos += cameraNode.GetBackward() * cameraSpeed; // Etc... - if (NzKeyboard::IsKeyPressed(NzKeyboard::Left) || NzKeyboard::IsKeyPressed(NzKeyboard::Q)) - targetPos += camera.GetLeft() * cameraSpeed; + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Left) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Q)) + targetPos += cameraNode.GetLeft() * cameraSpeed; // Etc... - if (NzKeyboard::IsKeyPressed(NzKeyboard::Right) || NzKeyboard::IsKeyPressed(NzKeyboard::D)) - targetPos += camera.GetRight() * cameraSpeed; + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::Right) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::D)) + targetPos += cameraNode.GetRight() * cameraSpeed; // Majuscule pour monter, notez l'utilisation d'une direction globale (Non-affectée par la rotation) - if (NzKeyboard::IsKeyPressed(NzKeyboard::LShift) || NzKeyboard::IsKeyPressed(NzKeyboard::RShift)) - targetPos += NzVector3f::Up() * cameraSpeed; + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LShift) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RShift)) + targetPos += Nz::Vector3f::Up() * cameraSpeed; // Contrôle (Gauche ou droite) pour descendre dans l'espace global, etc... - if (NzKeyboard::IsKeyPressed(NzKeyboard::LControl) || NzKeyboard::IsKeyPressed(NzKeyboard::RControl)) - targetPos += NzVector3f::Down() * cameraSpeed; + if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::LControl) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::RControl)) + targetPos += Nz::Vector3f::Down() * cameraSpeed; - camera.SetPosition((smoothMovement) ? DampedString(camera.GetPosition(), targetPos, elapsedTime) : targetPos, nzCoordSys_Global); + cameraNode.SetPosition((smoothMovement) ? DampedString(cameraNode.GetPosition(), targetPos, elapsedTime) : targetPos, Nz::CoordSys_Global); - // On relance l'horloge - updateClock.Restart(); + updateAccumulator = 0; } - // Rendu de la scène: - // On procède maintenant au rendu de la scène en elle-même, celui-ci se décompose en quatre étapes distinctes - - // Pour commencer, on met à jour la scène, ceci appelle la méthode Update de tous les SceneNode enregistrés - // pour la mise à jour globale (Scene::RegisterForUpdate) - scene.Update(); - - // Ensuite il y a le calcul de visibilité, la scène se sert de la caméra active pour effectuer un test de visibilité - // afin de faire une liste des SceneNode visibles (Ex: Frustum culling) - scene.Cull(); - - // Ensuite il y a la mise à jour des SceneNode enregistrés pour la mise à jour visible (Exemple: Terrain) - scene.UpdateVisible(); - - // Pour terminer, il y a l'affichage en lui-même, de façon organisée et optimisée (Batching) - scene.Draw(); + // Et maintenant pour rendre la scène, il nous suffit de mettre à jour le monde en lui envoyant le temps depuis la dernière mise à jour + // Note: La plupart des systèmes, à l'exception de celui de rendu, ont une fréquence de mise à jour fixe (modifiable) + // Il n'est donc pas nécessaire de limiter vous-même les mises à jour du monde + world.Update(elapsedUS / 1000000.f); // Après avoir dessiné sur la fenêtre, il faut s'assurer qu'elle affiche cela // Cet appel ne fait rien d'autre qu'échanger les buffers de rendu (Double Buffering) @@ -344,7 +393,7 @@ int main() if (secondClock.GetMilliseconds() >= 1000) // Toutes les secondes { // Et on insère ces données dans le titre de la fenêtre - window.SetTitle(windowTitle + " - " + NzString::Number(fps) + " FPS"); + window.SetTitle(windowTitle + " - " + Nz::String::Number(fps) + " FPS"); /* Note: En C++11 il est possible d'insérer de l'Unicode de façon standard, quel que soit l'encodage du fichier, @@ -364,7 +413,7 @@ int main() return EXIT_SUCCESS; } -NzVector3f DampedString(const NzVector3f& currentPos, const NzVector3f& targetPos, float frametime, float springStrength) +Nz::Vector3f DampedString(const Nz::Vector3f& currentPos, const Nz::Vector3f& targetPos, float frametime, float springStrength) { // Je ne suis pas l'auteur de cette fonction // Je l'ai reprise du programme "Floaty Camera Example" et adaptée au C++ @@ -372,13 +421,13 @@ NzVector3f DampedString(const NzVector3f& currentPos, const NzVector3f& targetPo // Tout le mérite revient à l'auteur (Qui me permettra ainsi d'améliorer les démos, voire même le moteur) // calculate the displacement between the target and the current position - NzVector3f displacement = targetPos - currentPos; + Nz::Vector3f displacement = targetPos - currentPos; // whats the distance between them? float displacementLength = displacement.GetLength(); // Stops small position fluctuations (integration errors probably - since only using euler) - if (NzNumberEquals(displacementLength, 0.f)) + if (Nz::NumberEquals(displacementLength, 0.f)) return currentPos; float invDisplacementLength = 1.f/displacementLength; From 5fbd035f12947dfb8c490d261a738b3872ab40cf Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Sep 2015 21:26:29 +0200 Subject: [PATCH 20/97] Noise: Remove HybridMultifractal2D.hpp to rename it Former-commit-id: 96808cea7606d361e0825642411ab63d5e9a9bb2 --- include/Nazara/Noise/HybridMultifractal2D.hpp | 36 ------------------- 1 file changed, 36 deletions(-) delete mode 100644 include/Nazara/Noise/HybridMultifractal2D.hpp diff --git a/include/Nazara/Noise/HybridMultifractal2D.hpp b/include/Nazara/Noise/HybridMultifractal2D.hpp deleted file mode 100644 index 4b0ad9bc6..000000000 --- a/include/Nazara/Noise/HybridMultifractal2D.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2015 Rémi Bèges -// This file is part of the "Nazara Engine". -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef HYBRIDMULTIFRACTAL2D_HPP -#define HYBRIDMULTIFRACTAL2D_HPP - -#include -#include -#include - -namespace Nz -{ - class NAZARA_NOISE_API HybridMultiFractal2D : public Abstract2DNoise, public ComplexNoiseBase - { - public: - HybridMultiFractal2D(NoiseType source, unsigned int seed); - ~HybridMultiFractal2D(); - - float GetValue(float x, float y, float resolution); - - private: - Abstract2DNoise* m_source; - float m_value; - float m_remainder; - float m_offset; - float m_weight; - float m_signal; - NoiseType m_noiseType; - }; -} - -#endif // HYBRIDMULTIFRACTAL2D_HPP - From a959207ea3fce4f8f38889c6a379c013dd58d073 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Sep 2015 21:26:52 +0200 Subject: [PATCH 21/97] Noise: Rename HybridMultiFractal2D filename Former-commit-id: dfffba919c4872e8306893f405437be0c6add630 --- include/Nazara/Noise/HybridMultiFractal2D.hpp | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 include/Nazara/Noise/HybridMultiFractal2D.hpp diff --git a/include/Nazara/Noise/HybridMultiFractal2D.hpp b/include/Nazara/Noise/HybridMultiFractal2D.hpp new file mode 100644 index 000000000..4b0ad9bc6 --- /dev/null +++ b/include/Nazara/Noise/HybridMultiFractal2D.hpp @@ -0,0 +1,36 @@ +// Copyright (C) 2015 Rémi Bèges +// This file is part of the "Nazara Engine". +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef HYBRIDMULTIFRACTAL2D_HPP +#define HYBRIDMULTIFRACTAL2D_HPP + +#include +#include +#include + +namespace Nz +{ + class NAZARA_NOISE_API HybridMultiFractal2D : public Abstract2DNoise, public ComplexNoiseBase + { + public: + HybridMultiFractal2D(NoiseType source, unsigned int seed); + ~HybridMultiFractal2D(); + + float GetValue(float x, float y, float resolution); + + private: + Abstract2DNoise* m_source; + float m_value; + float m_remainder; + float m_offset; + float m_weight; + float m_signal; + NoiseType m_noiseType; + }; +} + +#endif // HYBRIDMULTIFRACTAL2D_HPP + From b711f47304ceca979d78ca3497a21339e51ad172 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Sep 2015 21:27:17 +0200 Subject: [PATCH 22/97] Build: Make compiling with make easier by adding a native plateform Former-commit-id: 2b12eff243fba3ce25a3cd4634ac18b351b18f49 --- build/scripts/common.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index 90afe4217..bb837d79b 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -10,7 +10,7 @@ function NazaraBuild:Execute() if (#self.OrderedExtLibs > 0) then solution("NazaraExtlibs") - platforms({"x32", "x64"}) + platforms({"native", "x32", "x64"}) -- Configuration générale configurations({ @@ -99,7 +99,7 @@ function NazaraBuild:Execute() end solution("NazaraEngine") - platforms({"x32", "x64"}) + platforms({"native", "x32", "x64"}) -- Configuration générale configurations({ From 69d98fa724590b204964b82ef8feff80e18e98fd Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 28 Sep 2015 21:38:33 +0200 Subject: [PATCH 23/97] Revert "Build: Make compiling with make easier by adding a native plateform" This reverts commit ee268879a325e3f62741e57dbe8790fbcc78498f [formerly 3720c0c8924e277e5cab757cc1950adba88bd66b]. Former-commit-id: 2314caedebd2b98ea2fba756c27d4edc76fb0e5c --- build/scripts/common.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/scripts/common.lua b/build/scripts/common.lua index bb837d79b..90afe4217 100644 --- a/build/scripts/common.lua +++ b/build/scripts/common.lua @@ -10,7 +10,7 @@ function NazaraBuild:Execute() if (#self.OrderedExtLibs > 0) then solution("NazaraExtlibs") - platforms({"native", "x32", "x64"}) + platforms({"x32", "x64"}) -- Configuration générale configurations({ @@ -99,7 +99,7 @@ function NazaraBuild:Execute() end solution("NazaraEngine") - platforms({"native", "x32", "x64"}) + platforms({"x32", "x64"}) -- Configuration générale configurations({ From fe680c038bea9bd6708ea2f8a870f8ab200788aa Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 3 Nov 2015 22:34:09 +0100 Subject: [PATCH 24/97] Core/String: Fix crash Former-commit-id: dc3199cfe9fb299000a5c07b26bd6ac611130459 --- src/Nazara/Core/String.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index d7f1aef14..fc63ebe06 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -88,6 +88,8 @@ namespace Nz m_sharedString = std::make_shared(1); m_sharedString->string[0] = character; } + else + m_sharedString = GetEmptyString(); } String::String(unsigned int rep, char character) @@ -99,6 +101,8 @@ namespace Nz if (character != '\0') std::memset(m_sharedString->string.get(), character, rep); } + else + m_sharedString = GetEmptyString(); } String::String(unsigned int rep, const char* string) : @@ -117,6 +121,8 @@ namespace Nz for (unsigned int i = 0; i < rep; ++i) std::memcpy(&m_sharedString->string[i*length], string, length); } + else + m_sharedString = GetEmptyString(); } String::String(unsigned int rep, const String& string) : @@ -136,6 +142,8 @@ namespace Nz m_sharedString = std::make_shared(length); std::memcpy(m_sharedString->string.get(), string, length); } + else + m_sharedString = GetEmptyString(); } String::String(const std::string& string) : From dfa6f06337e982056b297adce5349f6c302c2103 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 3 Nov 2015 22:34:46 +0100 Subject: [PATCH 25/97] Core/Error: Make NazaraAssert blocklike (fixing integration) Former-commit-id: c6b7e10e30504ef14ef83d0a4d07f17adfd7b026 --- include/Nazara/Core/Error.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Core/Error.hpp b/include/Nazara/Core/Error.hpp index f970b5ba8..badfa39c2 100644 --- a/include/Nazara/Core/Error.hpp +++ b/include/Nazara/Core/Error.hpp @@ -14,9 +14,9 @@ #include #if NAZARA_CORE_ENABLE_ASSERTS || defined(NAZARA_DEBUG) - #define NazaraAssert(a, err) if (!(a)) Nz::Error::Trigger(Nz::ErrorType_AssertFailed, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) + #define NazaraAssert(a, err) do { if (!(a)) Nz::Error::Trigger(Nz::ErrorType_AssertFailed, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION); } while (false) #else - #define NazaraAssert(a, err) + #define NazaraAssert(a, err) do {} while (false) #endif #define NazaraError(err) Nz::Error::Trigger(Nz::ErrorType_Normal, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) From 1bbf038cc6d40f37ffaebd1ef2d8134497055a74 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 9 Nov 2015 15:02:25 +0100 Subject: [PATCH 26/97] Network: First commit Former-commit-id: ec8697acc51569f5043e4f70e4cf42f1c5dc487c --- build/scripts/modules/network.lua | 19 + include/Nazara/Network.hpp | 44 ++ include/Nazara/Network/AbstractSocket.hpp | 63 ++ include/Nazara/Network/AbstractSocket.inl | 45 ++ include/Nazara/Network/Algorithm.hpp | 21 + include/Nazara/Network/Algorithm.inl | 7 + include/Nazara/Network/Config.hpp | 53 ++ include/Nazara/Network/ConfigCheck.hpp | 20 + include/Nazara/Network/Debug.hpp | 8 + include/Nazara/Network/DebugOff.hpp | 9 + include/Nazara/Network/Enums.hpp | 61 ++ include/Nazara/Network/IpAddress.hpp | 102 ++++ include/Nazara/Network/IpAddress.inl | 205 +++++++ include/Nazara/Network/Network.hpp | 33 ++ include/Nazara/Network/SocketHandle.hpp | 27 + include/Nazara/Network/TcpBase.hpp | 42 ++ include/Nazara/Network/TcpBase.inl | 36 ++ include/Nazara/Network/TcpClient.hpp | 54 ++ include/Nazara/Network/TcpClient.inl | 37 ++ include/Nazara/Network/TcpServer.hpp | 43 ++ include/Nazara/Network/TcpServer.inl | 47 ++ include/Nazara/Network/UdpSocket.hpp | 50 ++ include/Nazara/Network/UdpSocket.inl | 66 +++ src/Nazara/Network/AbstractSocket.cpp | 108 ++++ src/Nazara/Network/Algorithm.cpp | 257 +++++++++ src/Nazara/Network/Debug/NewOverload.cpp | 31 + src/Nazara/Network/IpAddress.cpp | 164 ++++++ src/Nazara/Network/Network.cpp | 84 +++ src/Nazara/Network/SystemSocket.hpp | 10 + src/Nazara/Network/TcpBase.cpp | 30 + src/Nazara/Network/TcpClient.cpp | 207 +++++++ src/Nazara/Network/TcpServer.cpp | 63 ++ src/Nazara/Network/UdpSocket.cpp | 79 +++ src/Nazara/Network/Win32/IpAddressImpl.cpp | 240 ++++++++ src/Nazara/Network/Win32/IpAddressImpl.hpp | 30 + src/Nazara/Network/Win32/SocketImpl.cpp | 639 +++++++++++++++++++++ src/Nazara/Network/Win32/SocketImpl.hpp | 63 ++ 37 files changed, 3097 insertions(+) create mode 100644 build/scripts/modules/network.lua create mode 100644 include/Nazara/Network.hpp create mode 100644 include/Nazara/Network/AbstractSocket.hpp create mode 100644 include/Nazara/Network/AbstractSocket.inl create mode 100644 include/Nazara/Network/Algorithm.hpp create mode 100644 include/Nazara/Network/Algorithm.inl create mode 100644 include/Nazara/Network/Config.hpp create mode 100644 include/Nazara/Network/ConfigCheck.hpp create mode 100644 include/Nazara/Network/Debug.hpp create mode 100644 include/Nazara/Network/DebugOff.hpp create mode 100644 include/Nazara/Network/Enums.hpp create mode 100644 include/Nazara/Network/IpAddress.hpp create mode 100644 include/Nazara/Network/IpAddress.inl create mode 100644 include/Nazara/Network/Network.hpp create mode 100644 include/Nazara/Network/SocketHandle.hpp create mode 100644 include/Nazara/Network/TcpBase.hpp create mode 100644 include/Nazara/Network/TcpBase.inl create mode 100644 include/Nazara/Network/TcpClient.hpp create mode 100644 include/Nazara/Network/TcpClient.inl create mode 100644 include/Nazara/Network/TcpServer.hpp create mode 100644 include/Nazara/Network/TcpServer.inl create mode 100644 include/Nazara/Network/UdpSocket.hpp create mode 100644 include/Nazara/Network/UdpSocket.inl create mode 100644 src/Nazara/Network/AbstractSocket.cpp create mode 100644 src/Nazara/Network/Algorithm.cpp create mode 100644 src/Nazara/Network/Debug/NewOverload.cpp create mode 100644 src/Nazara/Network/IpAddress.cpp create mode 100644 src/Nazara/Network/Network.cpp create mode 100644 src/Nazara/Network/SystemSocket.hpp create mode 100644 src/Nazara/Network/TcpBase.cpp create mode 100644 src/Nazara/Network/TcpClient.cpp create mode 100644 src/Nazara/Network/TcpServer.cpp create mode 100644 src/Nazara/Network/UdpSocket.cpp create mode 100644 src/Nazara/Network/Win32/IpAddressImpl.cpp create mode 100644 src/Nazara/Network/Win32/IpAddressImpl.hpp create mode 100644 src/Nazara/Network/Win32/SocketImpl.cpp create mode 100644 src/Nazara/Network/Win32/SocketImpl.hpp diff --git a/build/scripts/modules/network.lua b/build/scripts/modules/network.lua new file mode 100644 index 000000000..8cf8b068a --- /dev/null +++ b/build/scripts/modules/network.lua @@ -0,0 +1,19 @@ +MODULE.Name = "Network" + +MODULE.Libraries = { + "NazaraCore" +} + +MODULE.OsFiles.Windows = { + "../src/Nazara/Network/Win32/**.hpp", + "../src/Nazara/Network/Win32/**.cpp" +} + +MODULE.OsFiles.Posix = { + "../src/Nazara/Network/Posix/**.hpp", + "../src/Nazara/Network/Posix/**.cpp" +} + +MODULE.OsLibraries.Windows = { + "ws2_32" +} diff --git a/include/Nazara/Network.hpp b/include/Nazara/Network.hpp new file mode 100644 index 000000000..fe2948399 --- /dev/null +++ b/include/Nazara/Network.hpp @@ -0,0 +1,44 @@ +// This file was automatically generated on 09 Nov 2015 at 13:52:47 + +/* + Nazara Engine - Network module + + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#pragma once + +#ifndef NAZARA_GLOBAL_NETWORK_HPP +#define NAZARA_GLOBAL_NETWORK_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // NAZARA_GLOBAL_NETWORK_HPP diff --git a/include/Nazara/Network/AbstractSocket.hpp b/include/Nazara/Network/AbstractSocket.hpp new file mode 100644 index 000000000..8c9fa5df5 --- /dev/null +++ b/include/Nazara/Network/AbstractSocket.hpp @@ -0,0 +1,63 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_ABSTRACTSOCKET_HPP +#define NAZARA_ABSTRACTSOCKET_HPP + +#include +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_NETWORK_API AbstractSocket + { + public: + AbstractSocket(const AbstractSocket&) = delete; + AbstractSocket(AbstractSocket&& abstractSocket); + virtual ~AbstractSocket(); + + void Close(); + + void EnableBlocking(bool blocking); + + inline SocketError GetLastError() const; + inline SocketHandle GetNativeHandle() const; + inline SocketState GetState() const; + inline SocketType GetType() const; + + inline bool IsBlockingEnabled() const; + + unsigned int QueryAvailableBytes() const; + + // Slots + NazaraSignal(OnStateChange, const AbstractSocket* /*socket*/, SocketState /*oldState*/, SocketState /*newState*/); + + protected: + AbstractSocket(SocketType type); + + inline void ChangeState(SocketState newState); + + virtual void OnClose(); + virtual void OnOpened(); + + bool Open(NetProtocol protocol); + void Open(SocketHandle existingHandle); + + NetProtocol m_protocol; + SocketError m_lastError; + SocketHandle m_handle; + SocketState m_state; + SocketType m_type; + bool m_isBlockingEnabled; + }; +} + +#include + +#endif // NAZARA_ABSTRACTSOCKET_HPP \ No newline at end of file diff --git a/include/Nazara/Network/AbstractSocket.inl b/include/Nazara/Network/AbstractSocket.inl new file mode 100644 index 000000000..cf75726b0 --- /dev/null +++ b/include/Nazara/Network/AbstractSocket.inl @@ -0,0 +1,45 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include + +namespace Nz +{ + inline SocketError AbstractSocket::GetLastError() const + { + return m_lastError; + } + + inline SocketHandle AbstractSocket::GetNativeHandle() const + { + return m_handle; + } + + inline SocketState AbstractSocket::GetState() const + { + return m_state; + } + + inline SocketType AbstractSocket::GetType() const + { + return m_type; + } + + inline bool AbstractSocket::IsBlockingEnabled() const + { + return m_isBlockingEnabled; + } + + inline void AbstractSocket::ChangeState(SocketState newState) + { + if (m_state != newState) + { + SocketState oldState = m_state; + m_state = newState; + OnStateChange(this, oldState, m_state); + } + } +} + +#include diff --git a/include/Nazara/Network/Algorithm.hpp b/include/Nazara/Network/Algorithm.hpp new file mode 100644 index 000000000..554f67d37 --- /dev/null +++ b/include/Nazara/Network/Algorithm.hpp @@ -0,0 +1,21 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_ALGORITHM_NETWORK_HPP +#define NAZARA_ALGORITHM_NETWORK_HPP + +#include +#include +#include + +namespace Nz +{ + bool ParseIPAddress(const char* addressPtr, UInt8 result[16], UInt16* port = nullptr, bool* isIPv6 = nullptr, const char** endOfRead = nullptr); +} + +#include + +#endif // NAZARA_ALGORITHM_NETWORK_HPP diff --git a/include/Nazara/Network/Algorithm.inl b/include/Nazara/Network/Algorithm.inl new file mode 100644 index 000000000..ecf609987 --- /dev/null +++ b/include/Nazara/Network/Algorithm.inl @@ -0,0 +1,7 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include + +#include diff --git a/include/Nazara/Network/Config.hpp b/include/Nazara/Network/Config.hpp new file mode 100644 index 000000000..727108061 --- /dev/null +++ b/include/Nazara/Network/Config.hpp @@ -0,0 +1,53 @@ +/* + Nazara Engine - Network module + + Copyright (C) 2015 Jérôme "Lynix" Leclercq (Lynix680@gmail.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. +*/ + +#pragma once + +#ifndef NAZARA_CONFIG_NETWORK_HPP +#define NAZARA_CONFIG_NETWORK_HPP + +/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci + +// Utilise le MemoryManager pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes) +#define NAZARA_NETWORK_MANAGE_MEMORY 0 + +// Active les tests de sécurité basés sur le code (Conseillé pour le développement) +#define NAZARA_NETWORK_SAFE 1 + +/// Chaque modification d'un paramètre ci-dessous implique une modification (souvent mineure) du code + +/// Vérification des valeurs et types de certaines constantes +#include + +#if defined(NAZARA_STATIC) + #define NAZARA_NETWORK_API +#else + #ifdef NAZARA_NETWORK_BUILD + #define NAZARA_NETWORK_API NAZARA_EXPORT + #else + #define NAZARA_NETWORK_API NAZARA_IMPORT + #endif +#endif + +#endif // NAZARA_CONFIG_NETWORK_HPP diff --git a/include/Nazara/Network/ConfigCheck.hpp b/include/Nazara/Network/ConfigCheck.hpp new file mode 100644 index 000000000..73513ebc9 --- /dev/null +++ b/include/Nazara/Network/ConfigCheck.hpp @@ -0,0 +1,20 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_CONFIG_CHECK_NETWORK_HPP +#define NAZARA_CONFIG_CHECK_NETWORK_HPP + +/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp + +#include + +// On force la valeur de MANAGE_MEMORY en mode debug +#if defined(NAZARA_DEBUG) && !NAZARA_NETWORK_MANAGE_MEMORY + #undef NAZARA_NETWORK_MANAGE_MEMORY + #define NAZARA_NETWORK_MANAGE_MEMORY 0 +#endif + +#endif // NAZARA_CONFIG_CHECK_NETWORK_HPP diff --git a/include/Nazara/Network/Debug.hpp b/include/Nazara/Network/Debug.hpp new file mode 100644 index 000000000..458bcf548 --- /dev/null +++ b/include/Nazara/Network/Debug.hpp @@ -0,0 +1,8 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#if NAZARA_MODULENAME_MANAGE_MEMORY + #include +#endif diff --git a/include/Nazara/Network/DebugOff.hpp b/include/Nazara/Network/DebugOff.hpp new file mode 100644 index 000000000..9ae8c8e69 --- /dev/null +++ b/include/Nazara/Network/DebugOff.hpp @@ -0,0 +1,9 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp +#if NAZARA_MODULENAME_MANAGE_MEMORY + #undef delete + #undef new +#endif diff --git a/include/Nazara/Network/Enums.hpp b/include/Nazara/Network/Enums.hpp new file mode 100644 index 000000000..b2184ab64 --- /dev/null +++ b/include/Nazara/Network/Enums.hpp @@ -0,0 +1,61 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_ENUMS_NETWORK_HPP +#define NAZARA_ENUMS_NETWORK_HPP + +namespace Nz +{ + enum NetProtocol + { + NetProtocol_Any, + NetProtocol_IPv4, + NetProtocol_IPv6, + + NetProtocol_Max = NetProtocol_IPv6 + }; + + enum SocketError + { + SocketError_NoError, + + SocketError_AddressNotAvailable, //< The address is already in use (when binding/listening) + SocketError_ConnectionClosed, //< The connection has been closed + SocketError_ConnectionRefused, //< The connection attempt was refused + SocketError_DatagramSize, //< The datagram size is over the system limit + SocketError_Internal, //< The error is coming from the engine + SocketError_NetworkError, //< The network system has failed (maybe network is down) + SocketError_NotInitialized, //< Nazara network has not been initialized + SocketError_NotSupported, //< The operation is not supported (e.g. creating a bluetooth socket on a system without any bluetooth adaptater) + SocketError_ResourceError, //< The operating system lacks the resources to proceed (e.g. memory/socket descriptor) + SocketError_UnreachableHost, //< The host is not reachable + SocketError_TimedOut, //< The operation timed out + SocketError_Unknown, //< The last operation failed with an unlisted error code + + SocketError_Max = SocketError_Unknown + }; + + enum SocketState + { + SocketState_Bound, //< The socket is currently bound + SocketState_Connecting, //< The socket is currently connecting + SocketState_Connected, //< The socket is currently connected + SocketState_NotConnected, //< The socket is not connected (or has been disconnected) + + SocketState_Max = SocketState_NotConnected + }; + + enum SocketType + { + SocketType_Raw, + SocketType_TCP, + SocketType_UDP, + + SocketType_Max = SocketType_UDP + }; +} + +#endif // NAZARA_ENUMS_NETWORK_HPP diff --git a/include/Nazara/Network/IpAddress.hpp b/include/Nazara/Network/IpAddress.hpp new file mode 100644 index 000000000..b426f1c16 --- /dev/null +++ b/include/Nazara/Network/IpAddress.hpp @@ -0,0 +1,102 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_IPADDRESS_HPP +#define NAZARA_IPADDRESS_HPP + +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + struct HostnameInfo; + + class NAZARA_NETWORK_API IpAddress + { + public: + using IPv4 = std::array; //< four 8bits blocks + using IPv6 = std::array; //< eight 16bits blocks + + inline IpAddress(); + inline IpAddress(const IPv4& ip, UInt16 port = 0); + inline IpAddress(const IPv6& ip, UInt16 port = 0); + inline IpAddress(const UInt8& a, const UInt8& b, const UInt8& c, const UInt8& d, UInt16 port = 0); + inline IpAddress(const UInt16& a, const UInt16& b, const UInt16& c, const UInt16& d, const UInt16& e, const UInt16& f, const UInt16& g, const UInt16& h, UInt16 port = 0); + inline IpAddress(const char* address); + inline IpAddress(const String& address); + IpAddress(const IpAddress&) = default; + IpAddress(IpAddress&&) = default; + ~IpAddress() = default; + + bool BuildFromAddress(const char* address); + + inline UInt16 GetPort() const; + inline NetProtocol GetProtocol() const; + + bool IsLoopback() const; + inline bool IsValid() const; + + inline void SetPort(UInt16 port); + + inline IPv4 ToIPv4() const; + inline IPv6 ToIPv6() const; + String ToString() const; + inline UInt32 ToUInt32() const; + + inline operator bool() const; + + IpAddress& operator=(const IpAddress&) = default; + IpAddress& operator=(IpAddress&&) = default; + + static String ResolveAddress(const IpAddress& address, String* service = nullptr); + static std::vector ResolveHostname(NetProtocol procol, const String& hostname, const String& protocol = "http"); + + inline friend std::ostream& operator<<(std::ostream& out, const IpAddress& address); + + inline friend bool operator==(const IpAddress& first, const IpAddress& second); + inline friend bool operator!=(const IpAddress& first, const IpAddress& second); + inline friend bool operator<(const IpAddress& first, const IpAddress& second); + inline friend bool operator<=(const IpAddress& first, const IpAddress& second); + inline friend bool operator>(const IpAddress& first, const IpAddress& second); + inline friend bool operator>=(const IpAddress& first, const IpAddress& second); + + static IpAddress AnyIpV4; + static IpAddress AnyIpV6; + static IpAddress BroadcastIpV4; + static IpAddress Invalid; + static IpAddress LoopbackIpV4; + static IpAddress LoopbackIpV6; + + private: + union + { + IPv4 m_ipv4; + IPv6 m_ipv6; + }; + + NetProtocol m_protocol; + UInt16 m_port; + bool m_isValid; + }; + + struct HostnameInfo + { + IpAddress address; + String canonicalName; + int flags; + int family; + int socketType; + }; + +} + +#include + +#endif // NAZARA_IPADDRESS_HPP diff --git a/include/Nazara/Network/IpAddress.inl b/include/Nazara/Network/IpAddress.inl new file mode 100644 index 000000000..f12361081 --- /dev/null +++ b/include/Nazara/Network/IpAddress.inl @@ -0,0 +1,205 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + inline IpAddress::IpAddress() : + m_isValid(false) + { + } + + inline IpAddress::IpAddress(const IPv4& ip, UInt16 port) : + m_isValid(true), + m_ipv4(ip), + m_protocol(NetProtocol_IPv4), + m_port(port) + { + } + + inline IpAddress::IpAddress(const IPv6& ip, UInt16 port) : + m_isValid(true), + m_ipv6(ip), + m_protocol(NetProtocol_IPv6), + m_port(port) + { + } + + inline IpAddress::IpAddress(const UInt8& a, const UInt8& b, const UInt8& c, const UInt8& d, UInt16 port) : + IpAddress(IPv4{a, b, c, d}, port) + { + } + + inline IpAddress::IpAddress(const UInt16& a, const UInt16& b, const UInt16& c, const UInt16& d, const UInt16& e, const UInt16& f, const UInt16& g, const UInt16& h, UInt16 port) : + IpAddress(IPv6{a, b, c, d, e, f, g, h}, port) + { + } + + inline IpAddress::IpAddress(const char* address) + { + BuildFromAddress(address); + } + + inline IpAddress::IpAddress(const String& address) + { + BuildFromAddress(address.GetConstBuffer()); + } + + inline UInt16 IpAddress::GetPort() const + { + return m_port; + } + + inline NetProtocol IpAddress::GetProtocol() const + { + return m_protocol; + } + + inline bool IpAddress::IsValid() const + { + return m_isValid; + } + + inline void IpAddress::SetPort(UInt16 port) + { + m_port = port; + } + + inline IpAddress::IPv4 IpAddress::ToIPv4() const + { + NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv4, "Address is not a valid IPv4"); + + return m_ipv4; + } + + inline IpAddress::IPv6 IpAddress::ToIPv6() const + { + NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv6, "IP is not a valid IPv6"); + + return m_ipv6; + } + + inline UInt32 IpAddress::ToUInt32() const + { + NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv4, "Address is not a valid IPv4"); + + return UInt32(m_ipv4[0]) << 24 | + UInt32(m_ipv4[1]) << 16 | + UInt32(m_ipv4[2]) << 8 | + UInt32(m_ipv4[3]) << 0; + } + + inline IpAddress::operator bool() const + { + return IsValid(); + } + + inline std::ostream& operator<<(std::ostream& out, const IpAddress& address) + { + out << "IpAddress(" << address.ToString() << ')'; + return out; + } + + inline bool operator==(const IpAddress& first, const IpAddress& second) + { + // We need to check the validity of each address before comparing them + if (!first.m_isValid || !second.m_isValid) + return first.m_isValid == second.m_isValid; + + // Then the protocol + if (first.m_protocol != second.m_protocol) + return false; + + // Each protocol has its variables to compare + switch (first.m_protocol) + { + case NetProtocol_IPv4: + { + if (first.m_ipv4 != second.m_ipv4) + return false; + + break; + } + + case NetProtocol_IPv6: + { + if (first.m_ipv6 != second.m_ipv6) + return false; + + break; + } + } + + // Check the port, in case there is one + if (first.m_port != second.m_port) + return false; + + return true; + } + + inline bool operator!=(const IpAddress& first, const IpAddress& second) + { + return !operator==(first, second); + } + + inline bool operator<(const IpAddress& first, const IpAddress& second) + { + // If the second address is invalid, there's no way we're lower than it + if (!second.m_isValid) + return false; + + // By this point, the second address is valid, thus check our validity + if (!first.m_isValid) + return true; // Invalid address are lower than valid one + + // Compare protocols + if (first.m_protocol != second.m_protocol) + return first.m_protocol < second.m_protocol; + + // Compare IP (thanks to std::array comparison operator) + switch (first.m_protocol) + { + case NetProtocol_IPv4: + { + if (first.m_ipv4 != second.m_ipv4) + return first.m_ipv4 < second.m_ipv4; + + break; + } + + case NetProtocol_IPv6: + { + if (first.m_ipv6 != second.m_ipv6) + return first.m_ipv6 < second.m_ipv6; + + break; + } + } + + // Compare port + if (first.m_port != second.m_port) + return first.m_port < second.m_port; + + return false; //< Same address + } + + inline bool operator<=(const IpAddress& first, const IpAddress& second) + { + return !operator<(second, first); + } + + inline bool operator>(const IpAddress& first, const IpAddress& second) + { + return second < first; + } + + inline bool operator>=(const IpAddress& first, const IpAddress& second) + { + return !operator<(first, second); + } +} + +#include diff --git a/include/Nazara/Network/Network.hpp b/include/Nazara/Network/Network.hpp new file mode 100644 index 000000000..93b0e921f --- /dev/null +++ b/include/Nazara/Network/Network.hpp @@ -0,0 +1,33 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_MODULENAME_HPP +#define NAZARA_MODULENAME_HPP + +#include +#include +#include + +namespace Nz +{ + class NAZARA_NETWORK_API Network + { + public: + Network() = delete; + ~Network() = delete; + + static bool Initialize(); + + static bool IsInitialized(); + + static void Uninitialize(); + + private: + static unsigned int s_moduleReferenceCounter; + }; +} + +#endif // NAZARA_MODULENAME_HPP diff --git a/include/Nazara/Network/SocketHandle.hpp b/include/Nazara/Network/SocketHandle.hpp new file mode 100644 index 000000000..2a09b80c3 --- /dev/null +++ b/include/Nazara/Network/SocketHandle.hpp @@ -0,0 +1,27 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_SOCKETHANDLE_HPP +#define NAZARA_SOCKETHANDLE_HPP + +#include + +#if defined(NAZARA_PLATFORM_WINDOWS) + #include +#endif + +namespace Nz +{ + #if defined(NAZARA_PLATFORM_WINDOWS) + using SocketHandle = UINT_PTR; + #elif defined(NAZARA_PLATFORM_POSIX) + using SocketHandle = int; + #else + #error Lack of implementation: SocketHandle + #endif +} + +#endif // NAZARA_SOCKETHANDLE_HPP diff --git a/include/Nazara/Network/TcpBase.hpp b/include/Nazara/Network/TcpBase.hpp new file mode 100644 index 000000000..0d7035026 --- /dev/null +++ b/include/Nazara/Network/TcpBase.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_TCPBASE_HPP +#define NAZARA_TCPBASE_HPP + +#include +#include + +namespace Nz +{ + class NAZARA_NETWORK_API TcpBase : public AbstractSocket + { + public: + ~TcpBase() = default; + + inline bool IsLowDelayEnabled() const; + inline bool IsKeepAliveEnabled() const; + + // Slots + NazaraSignal(OnStateChange, const TcpBase* /*socket*/, SocketState /*newState*/); + + protected: + TcpBase(); + TcpBase(TcpBase&& tcpBase); + + virtual void OnOpened() override; + + SocketState m_state; + UInt64 m_keepAliveInterval; + UInt64 m_keepAliveTime; + bool m_isLowDelayEnabled; + bool m_isKeepAliveEnabled; + }; +} + +#include + +#endif // NAZARA_TCPBASE_HPP \ No newline at end of file diff --git a/include/Nazara/Network/TcpBase.inl b/include/Nazara/Network/TcpBase.inl new file mode 100644 index 000000000..2a1d77d56 --- /dev/null +++ b/include/Nazara/Network/TcpBase.inl @@ -0,0 +1,36 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + inline TcpBase::TcpBase() : + AbstractSocket(SocketType_TCP) + { + } + + inline TcpBase::TcpBase(TcpBase&& tcpBase) : + AbstractSocket(std::move(tcpBase)), + m_state(tcpBase.m_state), + m_keepAliveInterval(tcpBase.m_keepAliveInterval), + m_keepAliveTime(tcpBase.m_keepAliveTime), + m_isLowDelayEnabled(tcpBase.m_isLowDelayEnabled), + m_isKeepAliveEnabled(tcpBase.m_isKeepAliveEnabled) + { + } + + inline bool TcpBase::IsLowDelayEnabled() const + { + return m_isLowDelayEnabled; + } + + inline bool TcpBase::IsKeepAliveEnabled() const + { + return m_isKeepAliveEnabled; + } +} + +#include diff --git a/include/Nazara/Network/TcpClient.hpp b/include/Nazara/Network/TcpClient.hpp new file mode 100644 index 000000000..ce8c6a282 --- /dev/null +++ b/include/Nazara/Network/TcpClient.hpp @@ -0,0 +1,54 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_TCPCLIENT_HPP +#define NAZARA_TCPCLIENT_HPP + +#include +#include +#include +#include + +namespace Nz +{ + class NAZARA_NETWORK_API TcpClient : public TcpBase + { + friend class TcpServer; + + public: + TcpClient() = default; + inline TcpClient(TcpClient&& tcpClient); + ~TcpClient() = default; + + SocketState Connect(const IpAddress& remoteAddress, UInt64 msTimeout = 3000); + inline void Disconnect(); + + void EnableLowDelay(bool lowDelay); + void EnableKeepAlive(bool keepAlive, UInt64 msTime = 10000, UInt64 msInterval = 1000); + + inline UInt64 GetKeepAliveInterval() const; + inline UInt64 GetKeepAliveTime() const; + inline IpAddress GetRemoteAddress() const; + + SocketState QueryState(); + + bool Receive(void* buffer, std::size_t size, std::size_t* received); + + bool Send(const void* buffer, std::size_t size, std::size_t* sent); + + private: + void OnClose() override; + void OnOpened() override; + + void Reset(SocketHandle handle, const IpAddress& peerAddress); + + IpAddress m_peerAddress; + }; +} + +#include + +#endif // NAZARA_TCPCLIENT_HPP \ No newline at end of file diff --git a/include/Nazara/Network/TcpClient.inl b/include/Nazara/Network/TcpClient.inl new file mode 100644 index 000000000..6b981000b --- /dev/null +++ b/include/Nazara/Network/TcpClient.inl @@ -0,0 +1,37 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + inline TcpClient::TcpClient(TcpClient&& tcpClient) : + TcpBase(std::move(tcpClient)), + m_peerAddress(std::move(tcpClient.m_peerAddress)) + { + } + + inline void TcpClient::Disconnect() + { + Close(); + } + + inline UInt64 TcpClient::GetKeepAliveInterval() const + { + return m_keepAliveInterval; + } + + inline UInt64 TcpClient::GetKeepAliveTime() const + { + return m_keepAliveTime; + } + + inline IpAddress TcpClient::GetRemoteAddress() const + { + return m_peerAddress; + } +} + +#include diff --git a/include/Nazara/Network/TcpServer.hpp b/include/Nazara/Network/TcpServer.hpp new file mode 100644 index 000000000..92b8a22a7 --- /dev/null +++ b/include/Nazara/Network/TcpServer.hpp @@ -0,0 +1,43 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_TCPSERVER_HPP +#define NAZARA_TCPSERVER_HPP + +#include +#include +#include + +namespace Nz +{ + class TcpClient; + + class NAZARA_NETWORK_API TcpServer : public TcpBase + { + public: + TcpServer() = default; + inline TcpServer(TcpServer&& tcpServer); + ~TcpServer() = default; + + bool AcceptClient(TcpClient* newClient); + + inline IpAddress GetBoundAddress() const; + inline UInt16 GetBoundPort() const; + + inline SocketState Listen(NetProtocol protocol, UInt16 port, unsigned int queueSize = 10); + SocketState Listen(const IpAddress& address, unsigned int queueSize = 10); + + private: + void OnClose() override; + void OnOpened() override; + + IpAddress m_boundAddress; + }; +} + +#include + +#endif // NAZARA_TCPSERVER_HPP \ No newline at end of file diff --git a/include/Nazara/Network/TcpServer.inl b/include/Nazara/Network/TcpServer.inl new file mode 100644 index 000000000..dfcdab110 --- /dev/null +++ b/include/Nazara/Network/TcpServer.inl @@ -0,0 +1,47 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +namespace Nz +{ + inline TcpServer::TcpServer(TcpServer&& tcpServer) : + TcpBase(std::move(tcpServer)), + m_boundAddress(std::move(tcpServer.m_boundAddress)) + { + } + + inline IpAddress TcpServer::GetBoundAddress() const + { + return m_boundAddress; + } + + inline UInt16 TcpServer::GetBoundPort() const + { + return m_boundAddress.GetPort(); + } + + inline SocketState TcpServer::Listen(NetProtocol protocol, UInt16 port, unsigned int queueSize) + { + NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO + + IpAddress any; + switch (protocol) + { + case NetProtocol_IPv4: + any = IpAddress::AnyIpV4; + break; + + case NetProtocol_IPv6: + any = IpAddress::AnyIpV6; + break; + } + + any.SetPort(port); + return Listen(any, queueSize); + } +} + +#include diff --git a/include/Nazara/Network/UdpSocket.hpp b/include/Nazara/Network/UdpSocket.hpp new file mode 100644 index 000000000..4730f4793 --- /dev/null +++ b/include/Nazara/Network/UdpSocket.hpp @@ -0,0 +1,50 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_UDPSOCKET_HPP +#define NAZARA_UDPSOCKET_HPP + +#include +#include +#include + +namespace Nz +{ + class NAZARA_NETWORK_API UdpSocket : public AbstractSocket + { + public: + inline UdpSocket(); + inline UdpSocket(NetProtocol protocol); + inline UdpSocket(UdpSocket&& udpSocket); + ~UdpSocket() = default; + + inline SocketState Bind(UInt16 port); + SocketState Bind(const IpAddress& address); + + inline bool Create(NetProtocol protocol); + + inline IpAddress GetBoundAddress() const; + inline UInt16 GetBoundPort() const; + inline SocketState GetState() const; + + unsigned int QueryMaxDatagramSize(); + + bool Receive(void* buffer, std::size_t size, IpAddress* from, std::size_t* received); + + bool Send(const IpAddress& to, const void* buffer, std::size_t size, std::size_t* sent); + + private: + void OnClose() override; + void OnOpened() override; + + IpAddress m_boundAddress; + SocketState m_state; + }; +} + +#include + +#endif // NAZARA_UDPSOCKET_HPP \ No newline at end of file diff --git a/include/Nazara/Network/UdpSocket.inl b/include/Nazara/Network/UdpSocket.inl new file mode 100644 index 000000000..a77aeca3b --- /dev/null +++ b/include/Nazara/Network/UdpSocket.inl @@ -0,0 +1,66 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include + +namespace Nz +{ + inline UdpSocket::UdpSocket() : + AbstractSocket(SocketType_UDP) + { + } + + inline UdpSocket::UdpSocket(NetProtocol protocol) : + UdpSocket() + { + Create(protocol); + } + + inline UdpSocket::UdpSocket(UdpSocket&& udpSocket) : + AbstractSocket(std::move(udpSocket)), + m_boundAddress(std::move(udpSocket.m_boundAddress)), + m_state(udpSocket.m_state) + { + } + + inline SocketState UdpSocket::Bind(UInt16 port) + { + IpAddress any; + switch (m_protocol) + { + case NetProtocol_IPv4: + any = IpAddress::AnyIpV4; + break; + + case NetProtocol_IPv6: + any = IpAddress::AnyIpV6; + break; + } + + any.SetPort(port); + return Bind(any); + } + + bool UdpSocket::Create(NetProtocol protocol) + { + return Open(protocol); + } + + inline IpAddress UdpSocket::GetBoundAddress() const + { + return m_boundAddress; + } + + inline UInt16 UdpSocket::GetBoundPort() const + { + return m_boundAddress.GetPort(); + } + + inline SocketState UdpSocket::GetState() const + { + return m_state; + } +} + +#include diff --git a/src/Nazara/Network/AbstractSocket.cpp b/src/Nazara/Network/AbstractSocket.cpp new file mode 100644 index 000000000..bcbf8c638 --- /dev/null +++ b/src/Nazara/Network/AbstractSocket.cpp @@ -0,0 +1,108 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +#if defined(NAZARA_PLATFORM_WINDOWS) +#include +#else +#error Missing implementation: Socket +#endif + +namespace Nz +{ + AbstractSocket::AbstractSocket(SocketType type) : + m_handle(SocketImpl::InvalidHandle), + m_state(SocketState_NotConnected), + m_type(type), + m_isBlockingEnabled(true) + { + } + + AbstractSocket::AbstractSocket(AbstractSocket&& abstractSocket) : + m_protocol(abstractSocket.m_protocol), + m_lastError(abstractSocket.m_lastError), + m_handle(abstractSocket.m_handle), + m_state(abstractSocket.m_state), + m_type(abstractSocket.m_type), + m_isBlockingEnabled(abstractSocket.m_isBlockingEnabled) + { + abstractSocket.m_handle = SocketImpl::InvalidHandle; + } + + AbstractSocket::~AbstractSocket() + { + Close(); + } + + void AbstractSocket::Close() + { + if (m_handle != SocketImpl::InvalidHandle) + { + OnClose(); + + SocketImpl::Close(m_handle); + m_handle = SocketImpl::InvalidHandle; + } + } + + void AbstractSocket::EnableBlocking(bool blocking) + { + if (m_isBlockingEnabled != blocking) + { + if (m_handle != SocketImpl::InvalidHandle) + SocketImpl::SetBlocking(m_handle, blocking, &m_lastError); + + m_isBlockingEnabled = blocking; + } + } + + unsigned int AbstractSocket::QueryAvailableBytes() const + { + if (m_handle == SocketImpl::InvalidHandle) + return 0; + + return SocketImpl::QueryAvailableBytes(m_handle); + } + + void AbstractSocket::OnClose() + { + ChangeState(SocketState_NotConnected); + } + + void AbstractSocket::OnOpened() + { + SocketError error; + if (!SocketImpl::SetBlocking(m_handle, m_isBlockingEnabled, &error)) + NazaraWarning("Failed to set socket blocking mode (0x" + String::Number(ERROR, 16) + ')'); + } + + bool AbstractSocket::Open(NetProtocol protocol) + { + if (m_handle == SocketImpl::InvalidHandle || m_protocol != protocol) + { + SocketHandle handle = SocketImpl::Create(protocol, m_type, &m_lastError); + if (handle == SocketImpl::InvalidHandle) + return false; + + m_protocol = protocol; + Open(handle); + } + + return true; + } + + void AbstractSocket::Open(SocketHandle handle) + { + NazaraAssert(handle != SocketImpl::InvalidHandle, "Invalid handle"); + + Close(); + + m_handle = handle; + OnOpened(); + } +} \ No newline at end of file diff --git a/src/Nazara/Network/Algorithm.cpp b/src/Nazara/Network/Algorithm.cpp new file mode 100644 index 000000000..628e9cf45 --- /dev/null +++ b/src/Nazara/Network/Algorithm.cpp @@ -0,0 +1,257 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + namespace Detail + { + bool ParseDecimal(const char* str, unsigned int* number, const char** endOfRead) + { + const char* ptr = str; + unsigned int val = 0; + while (*ptr >= '0' && *ptr <= '9') + { + val *= 10; + val += *ptr - '0'; + + ++ptr; + } + + if (str == ptr) + return false; + + if (number) + *number = val; + + if (endOfRead) + *endOfRead = ptr; + + return true; + } + + bool ParseHexadecimal(const char* str, unsigned int* number, const char** endOfRead) + { + const char* ptr = str; + unsigned int val = 0; + while ((*ptr >= '0' && *ptr <= '9') || ((*ptr & 0x5F) >= 'A' && (*ptr & 0x5F) <= 'F')) + { + val *= 16; + val += (*ptr > '9') ? ((*ptr & 0x5F) - 'A' + 10) : *ptr - '0'; + + ++ptr; + } + + if (str == ptr) + return false; + + if (number) + *number = val; + + if (endOfRead) + *endOfRead = ptr; + + return true; + } + } + + // From http://rosettacode.org/wiki/Parse_an_IP_Address + // Parse a textual IPv4 or IPv6 address, optionally with port, into a binary + // array (for the address, in host order), and an optionally provided port. + // Also, indicate which of those forms (4 or 6) was parsed. + bool ParseIPAddress(const char* addressPtr, UInt8 result[16], UInt16* port, bool* isIPv6, const char** endOfRead) + { + NazaraAssert(addressPtr, "Invalid address string"); + NazaraAssert(result, "Invalid result pointer"); + + //find first colon, dot, and open bracket + const char* colonPtr = std::strchr(addressPtr, ':'); + const char* dotPtr = std::strchr(addressPtr, '.'); + const char* openBracketPtr = std::strchr(addressPtr, '['); + + // we'll consider this to (probably) be IPv6 if we find an open + // bracket, or an absence of dots, or if there is a colon, and it + // precedes any dots that may or may not be there + bool detectedIPv6 = openBracketPtr || !dotPtr || (colonPtr && (!dotPtr || colonPtr < dotPtr)); + + // OK, now do a little further sanity check our initial guess... + if (detectedIPv6) + { + // if open bracket, then must have close bracket that follows somewhere + const char* closeBracketPtr = std::strchr(addressPtr, ']'); + if (openBracketPtr && (!closeBracketPtr || closeBracketPtr < openBracketPtr)) + return false; + } + else // probably ipv4 + { + // dots must exist, and precede any colons + if (!dotPtr || (colonPtr && colonPtr < dotPtr)) + return false; + } + + // OK, there should be no correctly formed strings which are miscategorized, + // and now any format errors will be found out as we continue parsing + // according to plan. + if (!detectedIPv6) //try to parse as IPv4 + { + // 4 dotted quad decimal; optional port if there is a colon + // since there are just 4, and because the last one can be terminated + // differently, I'm just going to unroll any potential loop. + UInt8* resultPtr = result; + + for (unsigned int i = 0; i < 4; ++i) + { + unsigned int value; + if (!Detail::ParseDecimal(addressPtr, &value, &addressPtr) || value > 255) //must be in range and followed by dot and nonempty + return false; + + if (i != 3) + { + if (*addressPtr != '.') + return false; + + addressPtr++; + } + + *resultPtr++ = static_cast(value); + } + } + else // try to parse as IPv6 + { + UInt8* resultPtr; + UInt8* zeroLoc; + + // up to 8 16-bit hex quantities, separated by colons, with at most one + // empty quantity, acting as a stretchy run of zeros. optional port + // if there are brackets followed by colon and decimal port number. + // A further form allows an ipv4 dotted quad instead of the last two + // 16-bit quantities, but only if in the ipv4 space ::ffff:x:x . + + if (openBracketPtr) // start past the open bracket, if it exists + addressPtr = openBracketPtr + 1; + + resultPtr = result; + zeroLoc = nullptr; // if we find a 'zero compression' location + + bool mappedIPv4 = false; + unsigned int i; + for (i = 0; i < 8; ++i) // we've got up to 8 of these, so we will use a loop + { + const char* savedPtr = addressPtr; + unsigned int value; // get value; these are hex + if (!Detail::ParseHexadecimal(addressPtr, &value, &addressPtr)) // if empty, we are zero compressing; note the loc + { + if (zeroLoc) //there can be only one! + { + // unless it's a terminal empty field, then this is OK, it just means we're done with the host part + if (resultPtr == zeroLoc) + { + --i; + break; + } + + return false; // otherwise, it's a format error + } + + if (*addressPtr != ':') // empty field can only be via : + return false; + + if (i == 0 && *++addressPtr != ':') // leading zero compression requires an extra peek, and adjustment + return false; + + zeroLoc = resultPtr; + ++addressPtr; + } + else + { + if ('.' == *addressPtr) // special case of ipv4 convenience notation + { + addressPtr = savedPtr; + + // who knows how to parse ipv4? we do! + UInt8 result[16]; + bool isIPv6; + if (!ParseIPAddress(addressPtr, result, nullptr, &isIPv6, &addressPtr) || isIPv6) // must parse and must be ipv4 + return false; + + // transfer addrlocal into the present location + for (unsigned int j = 0; j < 4; ++j) + *(resultPtr++) = result[j]; + + ++i; // pretend like we took another short, since the ipv4 effectively is two shorts + mappedIPv4 = true; // remember how we got here for further validation later + break; // totally done with address + } + + if (value > 65535) // must be 16 bit quantity + return false; + + *(resultPtr++) = value >> 8; + *(resultPtr++) = value & 0xFF; + + if (*addressPtr == ':') // typical case inside; carry on + ++addressPtr; + else // some other terminating character; done with this parsing parts + break; + } + } + + // handle any zero compression we found + if (zeroLoc) + { + std::ptrdiff_t nHead = (int) (zeroLoc - result); // how much before zero compression + std::ptrdiff_t nTail = i * 2 - nHead; // how much after zero compression + std::ptrdiff_t nZeros = 16 - nTail - nHead; // how much zeros + std::memmove(&result[16 - nTail], zeroLoc, nTail); // scootch stuff down + std::memset(zeroLoc, 0, nZeros); // clear the compressed zeros + } + + // validation of ipv4 subspace ::ffff:x.x + if (mappedIPv4) + { + static const UInt8 abyPfx[] = {0,0, 0,0, 0,0, 0,0, 0,0, 0xFF,0xFF}; + if (std::memcmp(result, abyPfx, sizeof(abyPfx)) != 0) + return false; + } + + // close bracket + if (openBracketPtr) + { + if (*addressPtr != ']') + return false; + + ++addressPtr; + } + } + + // if asked to read the port + if (port) + { + if (*addressPtr == ':') // have port part + { + ++addressPtr; // past the colon + + unsigned int portValue; + if (!Detail::ParseDecimal(addressPtr, &portValue, nullptr) || portValue > 65535) + return false; + + if (port) + *port = static_cast(portValue); + } + else // finished just with IP address + *port = 0; // indicate we have no port part + } + + if (isIPv6) + *isIPv6 = detectedIPv6; + + if (endOfRead) + *endOfRead = addressPtr; + + return true; + } +} diff --git a/src/Nazara/Network/Debug/NewOverload.cpp b/src/Nazara/Network/Debug/NewOverload.cpp new file mode 100644 index 000000000..80be1880c --- /dev/null +++ b/src/Nazara/Network/Debug/NewOverload.cpp @@ -0,0 +1,31 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#if NAZARA_NETWORK_MANAGE_MEMORY + +#include +#include // Is this necessary ? + +void* operator new(std::size_t size) +{ + return Nz::MemoryManager::Allocate(size, false); +} + +void* operator new[](std::size_t size) +{ + return Nz::MemoryManager::Allocate(size, true); +} + +void operator delete(void* pointer) noexcept +{ + Nz::MemoryManager::Free(pointer, false); +} + +void operator delete[](void* pointer) noexcept +{ + Nz::MemoryManager::Free(pointer, true); +} + +#endif // NAZARA_NETWORK_MANAGE_MEMORY diff --git a/src/Nazara/Network/IpAddress.cpp b/src/Nazara/Network/IpAddress.cpp new file mode 100644 index 000000000..41654eb4e --- /dev/null +++ b/src/Nazara/Network/IpAddress.cpp @@ -0,0 +1,164 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include + +#if defined(NAZARA_PLATFORM_WINDOWS) +#include +#else +#error Missing implementation: Network +#endif + +#include + +namespace Nz +{ + bool IpAddress::BuildFromAddress(const char* address) + { + m_isValid = false; + + bool isIPv6; + UInt8 result[16]; + if (!ParseIPAddress(address, result, &m_port, &isIPv6, nullptr)) + return false; + + m_isValid = true; + if (isIPv6) + { + m_protocol = NetProtocol_IPv6; + + for (unsigned int i = 0; i < 8; ++i) + m_ipv6[i] = UInt32(result[i*2]) << 8 | result[i*2 + 1]; + } + else + { + m_protocol = NetProtocol_IPv4; + + for (unsigned int i = 0; i < 4; ++i) + m_ipv4[i] = result[i]; + } + + return true; + } + + bool IpAddress::IsLoopback() const + { + if (!m_isValid) + return false; + + NazaraAssert(m_protocol <= NetProtocol_Max, "Protocol has value out of enum"); + switch (m_protocol) + { + case NetProtocol_IPv4: + return m_ipv4[0] == 127; + + case NetProtocol_IPv6: + return m_ipv6 == LoopbackIpV6.m_ipv6; // Only compare the ip value + } + + NazaraInternalError("Invalid protocol for IpAddress (0x" + String::Number(m_protocol) + ')'); + return false; + } + + String IpAddress::ToString() const + { + StringStream stream; + + if (m_isValid) + { + NazaraAssert(m_protocol <= NetProtocol_Max, "Protocol has value out of enum"); + switch (m_protocol) + { + case NetProtocol_IPv4: + for (unsigned int i = 0; i < 4; ++i) + { + stream << int(m_ipv4[i]); + if (i != 3) + stream << '.'; + } + break; + + case NetProtocol_IPv6: + // Canonical representation of an IPv6 + // https://tools.ietf.org/html/rfc5952 + + // Find the longest zero sequence + int f0 = -1; + int l0 = -1; + + for (unsigned int i = 0; i < 8; ++i) + { + if (m_ipv6[i] == 0) + { + unsigned int j; + for (j = i + 1; j < 8; ++j) + { + if (m_ipv6[j] != 0) + break; + } + + if (j - i > std::max(l0 - f0, 1)) + { + f0 = i; + l0 = j; + } + } + } + + // We need brackets around our IPv6 address if we have a port + if (m_port != 0) + stream << '['; + + for (unsigned int i = 0; i < 8; ++i) + { + if (i == f0) + { + stream << "::"; + i = l0; + if (i >= 8) + break; + } + else if (i != 0) + stream << ':'; + + stream << String::Number(m_ipv6[i], 16).ToLower(); + } + + if (m_port != 0) + stream << ']'; + break; + } + + if (m_port != 0) + stream << ':' << m_port; + } + + return stream; + } + + String IpAddress::ResolveAddress(const IpAddress& address, String* service) + { + String hostname; + IpAddressImpl::ResolveAddress(address, &hostname, service); + + return hostname; + } + + std::vector IpAddress::ResolveHostname(NetProtocol protocol, const String& hostname, const String& service) + { + return IpAddressImpl::ResolveHostname(protocol, hostname, service); + } + + IpAddress IpAddress::AnyIpV4(0, 0, 0, 0); + IpAddress IpAddress::AnyIpV6(0, 0, 0, 0, 0, 0, 0, 0, 0); + IpAddress IpAddress::BroadcastIpV4(255, 255, 255, 255); + IpAddress IpAddress::Invalid; + IpAddress IpAddress::LoopbackIpV4(127, 0, 0, 1); + IpAddress IpAddress::LoopbackIpV6(0, 0, 0, 0, 0, 0, 0, 1); +} diff --git a/src/Nazara/Network/Network.cpp b/src/Nazara/Network/Network.cpp new file mode 100644 index 000000000..ffe4842ca --- /dev/null +++ b/src/Nazara/Network/Network.cpp @@ -0,0 +1,84 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include +#include + +#if defined(NAZARA_PLATFORM_WINDOWS) +#include +#else +#error Missing implementation: Network +#endif + +#include + +namespace Nz +{ + bool Network::Initialize() + { + if (s_moduleReferenceCounter > 0) + { + s_moduleReferenceCounter++; + return true; // Already initialized + } + + // Initialize module dependencies + if (!Core::Initialize()) + { + NazaraError("Failed to initialize core module"); + return false; + } + + s_moduleReferenceCounter++; + + CallOnExit onExit(Network::Uninitialize); + + // Initialize module here + if (!SocketImpl::Initialize()) + { + NazaraError("Failed to initialize socket implementation"); + return false; + } + + onExit.Reset(); + + NazaraNotice("Initialized: Network module"); + return true; + } + + bool Network::IsInitialized() + { + return s_moduleReferenceCounter != 0; + } + + void Network::Uninitialize() + { + if (s_moduleReferenceCounter != 1) + { + // Either the module is not initialized, either it was initialized multiple times + if (s_moduleReferenceCounter > 1) + s_moduleReferenceCounter--; + + return; + } + + s_moduleReferenceCounter = 0; + + // Uninitialize module here + SocketImpl::Uninitialize(); + + NazaraNotice("Uninitialized: Network module"); + + // Free module dependencies + Core::Uninitialize(); + } + + unsigned int Network::s_moduleReferenceCounter = 0; +} + diff --git a/src/Nazara/Network/SystemSocket.hpp b/src/Nazara/Network/SystemSocket.hpp new file mode 100644 index 000000000..95b7dff37 --- /dev/null +++ b/src/Nazara/Network/SystemSocket.hpp @@ -0,0 +1,10 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#ifdef NAZARA_PLATFORM_WINDOWS +#include +#include +#elif defined(NAZARA_PLATFORM_POSIX) +#include +#endif \ No newline at end of file diff --git a/src/Nazara/Network/TcpBase.cpp b/src/Nazara/Network/TcpBase.cpp new file mode 100644 index 000000000..3f9f173eb --- /dev/null +++ b/src/Nazara/Network/TcpBase.cpp @@ -0,0 +1,30 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include + +#if defined(NAZARA_PLATFORM_WINDOWS) +#include +#else +#error Missing implementation: Socket +#endif + +namespace Nz +{ + void TcpBase::OnOpened() + { + AbstractSocket::OnOpened(); + + m_isLowDelayEnabled = false; //< Nagle's algorithm, is this enabled everywhere? + m_isKeepAliveEnabled = false; //< default documentation value, OS can change this (TODO: Query OS default value) + m_keepAliveInterval = 1000; //< default documentation value, OS can change this (TODO: Query OS default value) + m_keepAliveTime = 7200000; //< default documentation value, OS can change this (TODO: Query OS default value) + + ChangeState(SocketState_NotConnected); + } +} \ No newline at end of file diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp new file mode 100644 index 000000000..0c41db30e --- /dev/null +++ b/src/Nazara/Network/TcpClient.cpp @@ -0,0 +1,207 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include + +#if defined(NAZARA_PLATFORM_WINDOWS) +#include +#else +#error Missing implementation: Socket +#endif + +namespace Nz +{ + SocketState TcpClient::Connect(const IpAddress& remoteAddress, UInt64 msTimeout) + { + NazaraAssert(remoteAddress.IsValid(), "Invalid remote address"); + NazaraAssert(remoteAddress.GetPort() != 0, "Remote address has no port"); + + Open(remoteAddress.GetProtocol()); + + CallOnExit restoreBlocking; + if (m_isBlockingEnabled) + { + SocketImpl::SetBlocking(m_handle, false); + restoreBlocking.Reset([this] () + { + SocketImpl::SetBlocking(m_handle, true); + }); + } + + SocketState state; + if (msTimeout > 0) + state = SocketImpl::Connect(m_handle, remoteAddress, msTimeout, &m_lastError); + else + state = SocketImpl::Connect(m_handle, remoteAddress, &m_lastError); + + if (state != SocketState_NotConnected) + m_peerAddress = remoteAddress; + + ChangeState(state); + return state; + } + + void TcpClient::EnableLowDelay(bool lowDelay) + { + if (m_isLowDelayEnabled != lowDelay) + { + SocketImpl::SetBlocking(m_handle, lowDelay, &m_lastError); + m_isLowDelayEnabled = lowDelay; + } + } + + void TcpClient::EnableKeepAlive(bool keepAlive, UInt64 msTime, UInt64 msInterval) + { + if (m_isKeepAliveEnabled != keepAlive || m_keepAliveTime != msTime || m_keepAliveInterval != msInterval) + { + SocketImpl::SetKeepAlive(m_handle, keepAlive, msTime, msInterval, &m_lastError); + m_isKeepAliveEnabled = keepAlive; + m_keepAliveInterval = msInterval; + m_keepAliveTime = msTime; + } + } + + SocketState TcpClient::QueryState() + { + // Check our state depending on our last state + switch (m_state) + { + case SocketState_Connecting: + { + // If we were connecting, check how it's going + SocketError getError; + SocketError error = SocketImpl::GetLastError(m_handle, &getError); + + if (getError != SocketError_NoError) + break; //< Do not update state if we cannot get socket state + + if (error == SocketError_NoError) + { + // No error yet, we're still connecting or connected, check that by connecting again + return Connect(m_peerAddress, 0); + } + else + { + // Our connection attempt failed + m_lastError = error; + ChangeState(SocketState_NotConnected); + } + + break; + } + + default: + { + // Check our peer address, if it works we're connected + SocketError error; + m_peerAddress = SocketImpl::QueryPeerAddress(m_handle, &error); + if (m_peerAddress == IpAddress::Invalid) + { + // Other errors mean a problem while getting the peer address + if (error == SocketError_ConnectionClosed) + ChangeState(SocketState_NotConnected); + } + else + ChangeState(SocketState_Connected); // If we are not connecting and have a peer address, we are connected + + break; + } + } + + return m_state; + } + + bool TcpClient::Receive(void* buffer, std::size_t size, std::size_t* received) + { + NazaraAssert(buffer && size > 0, "Invalid buffer"); + + int read; + if (!SocketImpl::Receive(m_handle, buffer, static_cast(size), &read, &m_lastError)) + { + switch (m_lastError) + { + case SocketError_ConnectionClosed: + case SocketError_ConnectionRefused: + ChangeState(SocketState_NotConnected); + break; + + default: + break; + } + + return false; + } + + if (received) + *received = read; + + ChangeState(SocketState_Connected); + return true; + } + + bool TcpClient::Send(const void* buffer, std::size_t size, std::size_t* sent) + { + NazaraAssert(buffer && size > 0, "Invalid buffer"); + + CallOnExit updateSent; + std::size_t totalByteSent = 0; + if (sent) + { + updateSent.Reset([sent, &totalByteSent] () + { + *sent = totalByteSent; + }); + } + + while (totalByteSent < size) + { + int sendSize = static_cast(std::min(size - totalByteSent, std::numeric_limits::max())); //< Handle very large send + int sentSize; + if (!SocketImpl::Send(m_handle, reinterpret_cast(buffer) + totalByteSent, sendSize, &sentSize, &m_lastError)) + { + switch (m_lastError) + { + case SocketError_ConnectionClosed: + case SocketError_ConnectionRefused: + ChangeState(SocketState_NotConnected); + break; + + default: + break; + } + + return false; + } + + totalByteSent += sentSize; + } + + ChangeState(SocketState_Connected); + return true; + } + + void TcpClient::OnClose() + { + TcpBase::OnClose(); + + m_peerAddress = IpAddress::Invalid; + } + + void TcpClient::OnOpened() + { + TcpBase::OnOpened(); + + m_peerAddress = IpAddress::Invalid; + } + + void TcpClient::Reset(SocketHandle handle, const IpAddress& peerAddress) + { + Open(handle); + m_peerAddress = peerAddress; + } +} \ No newline at end of file diff --git a/src/Nazara/Network/TcpServer.cpp b/src/Nazara/Network/TcpServer.cpp new file mode 100644 index 000000000..5cc999f1c --- /dev/null +++ b/src/Nazara/Network/TcpServer.cpp @@ -0,0 +1,63 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include + +#if defined(NAZARA_PLATFORM_WINDOWS) +#include +#else +#error Missing implementation: Socket +#endif + +namespace Nz +{ + bool TcpServer::AcceptClient(TcpClient* newClient) + { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Server isn't listening"); + NazaraAssert(newClient, "Invalid client socket"); + + IpAddress clientAddress; + SocketHandle handle = SocketImpl::Accept(m_handle, &clientAddress, &m_lastError); + if (handle != SocketImpl::InvalidHandle) + { + newClient->Reset(handle, clientAddress); + return true; + } + else + return false; + } + + SocketState TcpServer::Listen(const IpAddress& address, unsigned int queueSize) + { + NazaraAssert(address.IsValid(), "Invalid address"); + + Open(address.GetProtocol()); + + SocketState state = SocketImpl::Listen(m_handle, address, queueSize, &m_lastError); + if (state == SocketState_Bound) + m_boundAddress = SocketImpl::QuerySocketAddress(m_handle); + + ChangeState(state); + return state; + } + + void TcpServer::OnClose() + { + TcpBase::OnClose(); + + m_boundAddress = IpAddress::Invalid; + } + + void TcpServer::OnOpened() + { + TcpBase::OnOpened(); + + m_boundAddress = IpAddress::Invalid; + } +} \ No newline at end of file diff --git a/src/Nazara/Network/UdpSocket.cpp b/src/Nazara/Network/UdpSocket.cpp new file mode 100644 index 000000000..b73afaf20 --- /dev/null +++ b/src/Nazara/Network/UdpSocket.cpp @@ -0,0 +1,79 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Utility module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +#if defined(NAZARA_PLATFORM_WINDOWS) +#include +#else +#error Missing implementation: Socket +#endif + +namespace Nz +{ + SocketState UdpSocket::Bind(const IpAddress& address) + { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Socket hasn't been created"); + NazaraAssert(address.IsValid(), "Invalid address"); + + SocketState state = SocketImpl::Bind(m_handle, address, &m_lastError); + if (state == SocketState_Bound) + m_boundAddress = SocketImpl::QuerySocketAddress(m_handle); + + ChangeState(state); + return state; + } + + unsigned int UdpSocket::QueryMaxDatagramSize() + { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Socket hasn't been created"); + + return SocketImpl::QueryMaxDatagramSize(m_handle, &m_lastError); + } + + bool UdpSocket::Receive(void* buffer, std::size_t size, IpAddress* from, std::size_t* received) + { + NazaraAssert(buffer && size > 0, "Invalid buffer"); + + int read; + if (!SocketImpl::ReceiveFrom(m_handle, buffer, static_cast(size), from, &read, &m_lastError)) + return false; + + if (received) + *received = read; + + return true; + } + + bool UdpSocket::Send(const IpAddress& to, const void* buffer, std::size_t size, std::size_t* sent) + { + NazaraAssert(to.IsValid(), "Invalid ip address"); + NazaraAssert(to.GetProtocol() == m_protocol, "IP Address has a different protocol than the socket"); + NazaraAssert(buffer && size > 0, "Invalid buffer"); + + int byteSent; + if (!SocketImpl::SendTo(m_handle, buffer, static_cast(size), to, &byteSent, &m_lastError)) + return false; + + if (sent) + *sent = byteSent; + + return true; + } + + void UdpSocket::OnClose() + { + m_boundAddress = IpAddress::Invalid; + + ChangeState(SocketState_NotConnected); + } + + void UdpSocket::OnOpened() + { + m_boundAddress = IpAddress::Invalid; + + ChangeState(SocketState_NotConnected); + } +} \ No newline at end of file diff --git a/src/Nazara/Network/Win32/IpAddressImpl.cpp b/src/Nazara/Network/Win32/IpAddressImpl.cpp new file mode 100644 index 000000000..0ded6dbdc --- /dev/null +++ b/src/Nazara/Network/Win32/IpAddressImpl.cpp @@ -0,0 +1,240 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include + +namespace Nz +{ + namespace Detail + { + #if NAZARA_CORE_WINDOWS_VISTA + using addrinfoImpl = addrinfoW; + + int GetAddressInfo(const String& hostname, const String& service, const addrinfoImpl* hints, addrinfoImpl** results) + { + return GetAddrInfoW(hostname.GetWideString().c_str(), service.GetWideString().c_str(), &hints, &servinfo); + } + + int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service) + { + std::array hostnameBuffer; + std::array serviceBuffer; + + int result = GetNameInfoW(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), NI_NUMERICSERV); + if (result == 0) + { + if (hostname) + hostname->Set(hostnameBuffer.data()); + + if (service) + service->Set(serviceBuffer.data()); + } + + return result; + } + + void FreeAddressInfo(addrinfoImpl* results) + { + FreeAddrInfoW(results); + } + #else + using addrinfoImpl = addrinfo; + + int GetAddressInfo(const String& hostname, const String& service, const addrinfoImpl* hints, addrinfoImpl** results) + { + return getaddrinfo(hostname.GetConstBuffer(), service.GetConstBuffer(), hints, results); + } + + int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service) + { + std::array hostnameBuffer; + std::array serviceBuffer; + + int result = getnameinfo(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), NI_NUMERICSERV); + if (result == 0) + { + if (hostname) + hostname->Set(hostnameBuffer.data()); + + if (service) + service->Set(serviceBuffer.data()); + } + + return result; + } + + void FreeAddressInfo(addrinfoImpl* results) + { + freeaddrinfo(results); + } + #endif + } + + IpAddress IpAddressImpl::FromAddrinfo(const addrinfo* info) + { + switch (info->ai_family) + { + case AF_INET: + { + sockaddr_in* ipv4 = reinterpret_cast(info->ai_addr); + + auto& rawIpV4 = ipv4->sin_addr.S_un.S_un_b; + return IpAddress(rawIpV4.s_b1, rawIpV4.s_b2, rawIpV4.s_b3, rawIpV4.s_b4, ntohs(ipv4->sin_port)); + } + + case AF_INET6: + { + sockaddr_in6* ipv6 = reinterpret_cast(info->ai_addr); + + auto& rawIpV6 = ipv6->sin6_addr.u.Word; + return IpAddress(rawIpV6[0], rawIpV6[1], rawIpV6[2], rawIpV6[3], rawIpV6[4], rawIpV6[5], rawIpV6[6], rawIpV6[7], ntohs(ipv6->sin6_port)); + } + } + + return IpAddress(); + } + + IpAddress IpAddressImpl::FromAddrinfo(const addrinfoW* info) + { + switch (info->ai_family) + { + case AF_INET: + { + sockaddr_in* ipv4 = reinterpret_cast(info->ai_addr); + + return FromSockAddr(ipv4); + } + + case AF_INET6: + { + sockaddr_in6* ipv6 = reinterpret_cast(info->ai_addr); + + return FromSockAddr(ipv6); + } + } + + return IpAddress(); + } + + IpAddress IpAddressImpl::FromSockAddr(const sockaddr* address) + { + switch (address->sa_family) + { + case AF_INET: + return FromSockAddr(reinterpret_cast(address)); + + case AF_INET6: + return FromSockAddr(reinterpret_cast(address)); + } + + return IpAddress(); + } + + IpAddress IpAddressImpl::FromSockAddr(const sockaddr_in* addressv4) + { + auto& rawIpV4 = addressv4->sin_addr.S_un.S_un_b; + return IpAddress(rawIpV4.s_b1, rawIpV4.s_b2, rawIpV4.s_b3, rawIpV4.s_b4, ntohs(addressv4->sin_port)); + } + + IpAddress IpAddressImpl::FromSockAddr(const sockaddr_in6* addressv6) + { + auto& rawIpV6 = addressv6->sin6_addr.u.Word; + return IpAddress(rawIpV6[0], rawIpV6[1], rawIpV6[2], rawIpV6[3], rawIpV6[4], rawIpV6[5], rawIpV6[6], rawIpV6[7], ntohs(addressv6->sin6_port)); + } + + bool IpAddressImpl::ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service) + { + SockAddrBuffer socketAddress; + socklen_t socketAddressLen = ToSockAddr(ipAddress, socketAddress.data()); + + return Detail::GetHostnameInfo(reinterpret_cast(socketAddress.data()), socketAddressLen, hostname, service) == 0; + } + + std::vector IpAddressImpl::ResolveHostname(NetProtocol procol, const String& hostname, const String& service) + { + std::vector results; + + Detail::addrinfoImpl hints; + std::memset(&hints, 0, sizeof(Detail::addrinfoImpl)); + hints.ai_family = SocketImpl::TranslateNetProtocolToAF(procol); + hints.ai_socktype = SOCK_STREAM; + + Detail::addrinfoImpl* servinfo; + int rv; + if ((rv = Detail::GetAddressInfo(hostname, service, &hints, &servinfo)) != 0) + { + fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + return results; + } + + CallOnExit onExit([servinfo]() + { + Detail::FreeAddressInfo(servinfo); + }); + + // loop through all the results and connect to the first we can + for (Detail::addrinfoImpl* p = servinfo; p != nullptr; p = p->ai_next) + { + HostnameInfo result; + result.address = FromAddrinfo(p); + result.canonicalName = String::Unicode(p->ai_canonname); + result.family = p->ai_family; + result.flags = p->ai_flags; + result.socketType = p->ai_socktype; + + results.push_back(result); + } + + return results; + } + + socklen_t IpAddressImpl::ToSockAddr(const IpAddress& ipAddress, void* buffer) + { + if (ipAddress.IsValid()) + { + switch (ipAddress.GetProtocol()) + { + case NetProtocol_IPv4: + { + sockaddr_in* socketAddress = reinterpret_cast(buffer); + + std::memset(socketAddress, 0, sizeof(sockaddr_in)); + socketAddress->sin_family = AF_INET; + socketAddress->sin_port = htons(ipAddress.GetPort()); + socketAddress->sin_addr.S_un.S_addr = htonl(ipAddress.ToUInt32()); + + return sizeof(sockaddr_in); + } + + case NetProtocol_IPv6: + { + sockaddr_in6* socketAddress = reinterpret_cast(buffer); + + std::memset(socketAddress, 0, sizeof(sockaddr_in6)); + socketAddress->sin6_family = AF_INET6; + socketAddress->sin6_port = htons(ipAddress.GetPort()); + + IpAddress::IPv6 address = ipAddress.ToIPv6(); + for (unsigned int i = 0; i < 8; ++i) + socketAddress->sin6_addr.u.Word[i] = htons(address[i]); + + IN6_ADDR any = in6addr_any; + + return sizeof(sockaddr_in6); + } + + default: + NazaraInternalError("Unhandled ip protocol (0x" + String::Number(ipAddress.GetProtocol()) + ')'); + break; + } + } + + NazaraError("Invalid ip address"); + return 0; + } +} diff --git a/src/Nazara/Network/Win32/IpAddressImpl.hpp b/src/Nazara/Network/Win32/IpAddressImpl.hpp new file mode 100644 index 000000000..57e6bbcc5 --- /dev/null +++ b/src/Nazara/Network/Win32/IpAddressImpl.hpp @@ -0,0 +1,30 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include + +namespace Nz +{ + class IpAddressImpl + { + public: + using SockAddrBuffer = std::array; + + IpAddressImpl() = delete; + ~IpAddressImpl() = delete; + + static IpAddress FromAddrinfo(const addrinfo* info); + static IpAddress FromAddrinfo(const addrinfoW* info); + static IpAddress FromSockAddr(const sockaddr* address); + static IpAddress FromSockAddr(const sockaddr_in* addressv4); + static IpAddress FromSockAddr(const sockaddr_in6* addressv6); + + static bool ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service); + static std::vector ResolveHostname(NetProtocol procol, const String& hostname, const String& service); + + static socklen_t ToSockAddr(const IpAddress& ipAddress, void* buffer); + }; +} diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp new file mode 100644 index 000000000..3ff57da52 --- /dev/null +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -0,0 +1,639 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + SocketHandle SocketImpl::Accept(SocketHandle handle, IpAddress* address, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + int bufferLength = static_cast(nameBuffer.size()); + + SocketHandle newClient = accept(handle, reinterpret_cast(&nameBuffer), &bufferLength); + if (newClient != InvalidHandle) + { + if (address) + *address = IpAddressImpl::FromSockAddr(reinterpret_cast(&nameBuffer)); + + if (error) + *error = SocketError_NoError; + } + else + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + } + + return newClient; + } + + SocketState SocketImpl::Bind(SocketHandle handle, const IpAddress& address, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(address.IsValid(), "Invalid address"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + int bufferLength = IpAddressImpl::ToSockAddr(address, nameBuffer.data()); + + if (bind(handle, reinterpret_cast(&nameBuffer), bufferLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return SocketState_NotConnected; + } + + if (error) + *error = SocketError_NoError; + + return SocketState_Bound; + } + + SocketHandle SocketImpl::Create(NetProtocol protocol, SocketType type, SocketError* error) + { + NazaraAssert(protocol != NetProtocol_Any, "Any protocol is not supported for socket creation"); + NazaraAssert(type <= SocketType_Max, "Type has value out of enum"); + + SocketHandle handle = socket(TranslateNetProtocolToAF(protocol), TranslateSocketTypeToSock(type), 0); + if (handle == InvalidHandle && error != nullptr) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return handle; + } + + void SocketImpl::Close(SocketHandle handle) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + if (closesocket(handle) == SOCKET_ERROR) + NazaraWarning("Failed to close socket: " + Error::GetLastSystemError(WSAGetLastError())); + } + + void SocketImpl::ClearErrorCode(SocketHandle handle) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + if (GetLastError(handle, nullptr) < 0) + NazaraWarning("Failed to clear socket error code: " + Error::GetLastSystemError(WSAGetLastError())); + } + + SocketState SocketImpl::Connect(SocketHandle handle, const IpAddress& address, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(address.IsValid(), "Invalid address"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + int bufferLength = IpAddressImpl::ToSockAddr(address, nameBuffer.data()); + + if (error) + *error = SocketError_NoError; + + // Clear socket error status + ClearErrorCode(handle); + + if (connect(handle, reinterpret_cast(nameBuffer.data()), bufferLength) == SOCKET_ERROR) + { + int errorCode = WSAGetLastError(); + switch (errorCode) //< Check for "normal errors" first + { + case WSAEALREADY: + case WSAEWOULDBLOCK: + return SocketState_Connecting; + + case WSAEISCONN: + return SocketState_Connected; + } + + if (error) + { + if (errorCode == WSAEADDRNOTAVAIL) + *error = SocketError_ConnectionRefused; //< ConnectionRefused seems more legit than AddressNotAvailable in connect case + else + *error = TranslateWSAErrorToSocketError(errorCode); + } + + return SocketState_NotConnected; + } + + return SocketState_Connected; + } + + SocketState SocketImpl::Connect(SocketHandle handle, const IpAddress& address, UInt64 msTimeout, SocketError* error) + { + SocketState state = Connect(handle, address, error); + if (state == SocketState_Connecting) + { + // http://developerweb.net/viewtopic.php?id=3196 + fd_set localSet; + FD_ZERO(&localSet); + FD_SET(handle, &localSet); + + timeval tv; + tv.tv_sec = static_cast(msTimeout / 1000ULL); + tv.tv_usec = static_cast((msTimeout % 1000ULL) * 1000ULL); + + int ret = select(0, nullptr, &localSet, &localSet, (msTimeout > 0) ? &tv : nullptr); + if (ret > 0) + { + int code = GetLastErrorCode(handle, error); + if (code < 0) //< GetLastSocketError() failed + return SocketState_NotConnected; + + if (code) + { + if (error) + *error = TranslateWSAErrorToSocketError(code); + + return SocketState_NotConnected; + } + } + else if (ret == 0) + { + if (error) + *error = SocketError_TimedOut; + + return SocketState_NotConnected; + } + else + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return SocketState_NotConnected; + } + + if (error) + *error = SocketError_NoError; + + state = SocketState_Connected; + } + + return state; + } + + bool SocketImpl::Initialize() + { + int errorCode = WSAStartup(MAKEWORD(2, 2), &s_WSA); + if (errorCode != 0) + { + NazaraError("Failed to initialize Windows Socket 2.2: " + Error::GetLastSystemError(errorCode)); + return false; + } + + NazaraDebug("Initialized Windows Socket " + String::Number(LOBYTE(s_WSA.wVersion)) + '.' + String::Number(HIBYTE(s_WSA.wVersion)) + " (" + String(s_WSA.szDescription) + ')'); + return true; + } + + SocketError SocketImpl::GetLastError(SocketHandle handle, SocketError* error) + { + int code = GetLastErrorCode(handle, error); + if (code < 0) + return SocketError_Internal; + + return TranslateWSAErrorToSocketError(code); + } + + int SocketImpl::GetLastErrorCode() + { + return WSAGetLastError(); + } + + int SocketImpl::GetLastErrorCode(SocketHandle handle, SocketError* error) + { + int code; + int codeLength = sizeof(code); + + if (getsockopt(handle, SOL_SOCKET, SO_ERROR, reinterpret_cast(&code), &codeLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return -1; + } + + if (error) + *error = SocketError_NoError; + + return code; + } + + SocketState SocketImpl::Listen(SocketHandle handle, const IpAddress& address, unsigned queueSize, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(address.IsValid(), "Invalid address"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + int bufferLength = IpAddressImpl::ToSockAddr(address, nameBuffer.data()); + + if (bind(handle, reinterpret_cast(&nameBuffer), bufferLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return SocketState_NotConnected; + } + + if (listen(handle, queueSize) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return SocketState_NotConnected; + } + + if (error) + *error = SocketError_NoError; + + return SocketState_Bound; + } + + unsigned int SocketImpl::QueryAvailableBytes(SocketHandle handle, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + u_long availableBytes; + if (ioctlsocket(handle, FIONREAD, &availableBytes) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + availableBytes = 0; + } + + if (error) + *error = SocketError_NoError; + + return availableBytes; + } + + unsigned int SocketImpl::QueryMaxDatagramSize(SocketHandle handle, SocketError* error) + { + unsigned int code; + int codeLength = sizeof(code); + + if (getsockopt(handle, SOL_SOCKET, SO_MAX_MSG_SIZE, reinterpret_cast(&code), &codeLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return -1; + } + + if (error) + *error = SocketError_NoError; + + return code; + } + + IpAddress SocketImpl::QueryPeerAddress(SocketHandle handle, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + int bufferLength = static_cast(nameBuffer.size()); + + if (getpeername(handle, reinterpret_cast(nameBuffer.data()), &bufferLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return IpAddress(); + } + + if (error) + *error = SocketError_NoError; + + return IpAddressImpl::FromSockAddr(reinterpret_cast(nameBuffer.data())); + } + + IpAddress SocketImpl::QuerySocketAddress(SocketHandle handle, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + int bufferLength = static_cast(nameBuffer.size()); + + if (getsockname(handle, reinterpret_cast(nameBuffer.data()), &bufferLength) == SOCKET_ERROR) + { + if (error) + { + int errorCode = WSAGetLastError(); + if (errorCode == WSAEINVAL) + *error = SocketError_NoError; + else + *error = TranslateWSAErrorToSocketError(errorCode); + } + + return IpAddress(); + } + + if (error) + *error = SocketError_NoError; + + return IpAddressImpl::FromSockAddr(reinterpret_cast(nameBuffer.data())); + } + + + bool SocketImpl::Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(buffer && length > 0, "Invalid buffer"); + + int byteRead = recv(handle, reinterpret_cast(buffer), length, 0); + if (byteRead == SOCKET_ERROR) + { + int errorCode = WSAGetLastError(); + switch (errorCode) + { + case WSAEWOULDBLOCK: + { + // If we have no data and are not blocking, return true with 0 byte read + byteRead = 0; + break; + } + + default: + { + if (error) + *error = TranslateWSAErrorToSocketError(errorCode); + + return false; //< Error + } + } + } + else if (byteRead == 0) + { + if (error) + *error = SocketError_ConnectionClosed; + + return false; //< Connection has been closed + } + + if (read) + *read = byteRead; + + if (error) + *error = SocketError_NoError; + + return true; + } + + bool SocketImpl::ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(buffer && length > 0, "Invalid buffer"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + int bufferLength = static_cast(nameBuffer.size()); + + IpAddress senderIp; + + int byteRead = recvfrom(handle, reinterpret_cast(buffer), length, 0, reinterpret_cast(&nameBuffer), &bufferLength); + if (byteRead == SOCKET_ERROR) + { + int errorCode = WSAGetLastError(); + switch (errorCode) + { + case WSAEWOULDBLOCK: + { + // If we have no data and are not blocking, return true with 0 byte read + byteRead = 0; + senderIp = IpAddress::Invalid; + break; + } + + default: + { + if (error) + *error = TranslateWSAErrorToSocketError(errorCode); + + return false; //< Error + } + } + } + else if (byteRead == 0) + { + if (error) + *error = SocketError_ConnectionClosed; + + return false; //< Connection closed + } + else // else we received something + senderIp = IpAddressImpl::FromSockAddr(reinterpret_cast(&nameBuffer)); + + if (from) + *from = senderIp; + + if (read) + *read = byteRead; + + if (error) + *error = SocketError_NoError; + + return true; + } + + bool SocketImpl::Send(SocketHandle handle, const void* buffer, int length, int* sent, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(buffer && length > 0, "Invalid buffer"); + + int byteSent = send(handle, reinterpret_cast(buffer), length, 0); + if (byteSent == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return false; //< Error + } + + if (sent) + *sent = byteSent; + + if (error) + *error = SocketError_NoError; + + return true; + } + + bool SocketImpl::SendTo(SocketHandle handle, const void* buffer, int length, const IpAddress& to, int* sent, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + NazaraAssert(buffer && length > 0, "Invalid buffer"); + + IpAddressImpl::SockAddrBuffer nameBuffer; + int bufferLength = IpAddressImpl::ToSockAddr(to, nameBuffer.data()); + + int byteSent = sendto(handle, reinterpret_cast(buffer), length, 0, reinterpret_cast(nameBuffer.data()), bufferLength); + if (byteSent == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return false; //< Error + } + + if (sent) + *sent = byteSent; + + if (error) + *error = SocketError_NoError; + + return true; + } + + bool SocketImpl::SetBlocking(SocketHandle handle, bool blocking, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + u_long block = (blocking) ? 0 : 1; + if (ioctlsocket(handle, FIONBIO, &block) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return false; //< Error + } + + if (error) + *error = SocketError_NoError; + + return true; + } + + bool SocketImpl::SetKeepAlive(SocketHandle handle, bool enabled, UInt64 msTime, UInt64 msInterval, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + tcp_keepalive keepAlive; + keepAlive.onoff = (enabled) ? 1 : 0; + keepAlive.keepaliveinterval = static_cast(msInterval); + keepAlive.keepalivetime = static_cast(msTime); + + DWORD dummy; //< byteReturned + if (!WSAIoctl(handle, SIO_KEEPALIVE_VALS, &keepAlive, sizeof(keepAlive), nullptr, 0, &dummy, nullptr, nullptr)) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return false; //< Error + } + + if (error) + *error = SocketError_NoError; + + return true; + } + + SocketError SocketImpl::TranslateWSAErrorToSocketError(int error) + { + switch (error) + { + case 0: + return SocketError_NoError; + + // Engine error + case WSAEACCES: + case WSAEBADF: + case WSAEINVAL: + case WSAEFAULT: + case WSAENOTSOCK: + case WSAEPROTOTYPE: + case WSA_INVALID_HANDLE: + return SocketError_Internal; + + case WSAEADDRNOTAVAIL: + case WSAEADDRINUSE: + return SocketError_AddressNotAvailable; + + case WSAEAFNOSUPPORT: + case WSAEPFNOSUPPORT: + case WSAEOPNOTSUPP: + case WSAEPROTONOSUPPORT: + case WSAESOCKTNOSUPPORT: + return SocketError_NotSupported; + + // Those are not errors and should have been handled before the call + case WSAEALREADY: + case WSAEISCONN: + case WSAEWOULDBLOCK: + return SocketError_Internal; + + case WSAECONNREFUSED: + return SocketError_ConnectionRefused; + + case WSAEMSGSIZE: + return SocketError_DatagramSize; + + case WSAEMFILE: + case WSAENOBUFS: + case WSA_NOT_ENOUGH_MEMORY: + return SocketError_ResourceError; + + case WSAENOTCONN: + case WSAESHUTDOWN: + return SocketError_ConnectionClosed; + + case WSAEHOSTUNREACH: + return SocketError_UnreachableHost; + + case WSAENETDOWN: + case WSAENETUNREACH: + return SocketError_NetworkError; + + case WSANOTINITIALISED: + return SocketError_NotInitialized; + + case WSAETIMEDOUT: + return SocketError_TimedOut; + } + + NazaraWarning("Unhandled WinSock error: " + Error::GetLastSystemError(error) + " (" + String::Number(error) + ')'); + return SocketError_Unknown; + } + + int SocketImpl::TranslateNetProtocolToAF(NetProtocol protocol) + { + NazaraAssert(protocol <= NetProtocol_Max, "Protocol has value out of enum"); + + static int addressFamily[] = { + AF_UNSPEC, //< NetProtocol_Any + AF_INET, //< NetProtocol_IPv4 + AF_INET6 //< NetProtocol_IPv6 + }; + static_assert(sizeof(addressFamily) / sizeof(int) == NetProtocol_Max + 1, "Address family array is incomplete"); + + return addressFamily[protocol]; + } + + int SocketImpl::TranslateSocketTypeToSock(SocketType type) + { + NazaraAssert(type <= SocketType_Max, "Socket type has value out of enum"); + + static int socketType[] = { + SOCK_RAW, //< SocketType_Raw + SOCK_STREAM, //< SocketType_TCP + SOCK_DGRAM //< SocketType_UDP + }; + static_assert(sizeof(socketType) / sizeof(int) == SocketType_Max + 1, "Socket type array is incomplete"); + + return socketType[type]; + } + + void SocketImpl::Uninitialize() + { + WSACleanup(); + } + + SocketHandle SocketImpl::InvalidHandle = INVALID_SOCKET; + WSADATA SocketImpl::s_WSA; +} diff --git a/src/Nazara/Network/Win32/SocketImpl.hpp b/src/Nazara/Network/Win32/SocketImpl.hpp new file mode 100644 index 000000000..9eb2c11ff --- /dev/null +++ b/src/Nazara/Network/Win32/SocketImpl.hpp @@ -0,0 +1,63 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Network module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + class SocketImpl + { + public: + SocketImpl() = delete; + ~SocketImpl() = delete; + + static SocketHandle Accept(SocketHandle handle, IpAddress* address, SocketError* error); + + static SocketState Bind(SocketHandle handle, const IpAddress& address, SocketError* error); + + static SocketHandle Create(NetProtocol protocol, SocketType type, SocketError* error); + + static void ClearErrorCode(SocketHandle handle); + static void Close(SocketHandle handle); + + static SocketState Connect(SocketHandle handle, const IpAddress& address, SocketError* error); + static SocketState Connect(SocketHandle handle, const IpAddress& address, UInt64 msTimeout, SocketError* error); + + static bool Initialize(); + + static SocketError GetLastError(SocketHandle handle, SocketError* error = nullptr); + static int GetLastErrorCode(); + static int GetLastErrorCode(SocketHandle handle, SocketError* error = nullptr); + + static SocketState Listen(SocketHandle handle, const IpAddress& address, unsigned queueSize, SocketError* error); + + static unsigned int QueryAvailableBytes(SocketHandle handle, SocketError* error = nullptr); + static unsigned int QueryMaxDatagramSize(SocketHandle handle, SocketError* error = nullptr); + static IpAddress QueryPeerAddress(SocketHandle handle, SocketError* error = nullptr); + static IpAddress QuerySocketAddress(SocketHandle handle, SocketError* error = nullptr); + + static bool Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error); + static bool ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error); + + static bool Send(SocketHandle handle, const void* buffer, int length, int* sent, SocketError* error); + static bool SendTo(SocketHandle handle, const void* buffer, int length, const IpAddress& to, int* sent, SocketError* error); + + static bool SetBlocking(SocketHandle handle, bool blocking, SocketError* error = nullptr); + static bool SetKeepAlive(SocketHandle handle, bool enabled, UInt64 msTime, UInt64 msInterval, SocketError* error = nullptr); + + static SocketError TranslateWSAErrorToSocketError(int error); + static int TranslateNetProtocolToAF(NetProtocol protocol); + static int TranslateSocketTypeToSock(SocketType type); + + static void Uninitialize(); + + static SocketHandle InvalidHandle; + + private: + static WSADATA s_WSA; + }; +} From 2a70758f08876f36c761f34138e71dab561d62f1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 10 Nov 2015 12:14:59 +0100 Subject: [PATCH 27/97] Network: Get rid of now useless TcpBase Former-commit-id: 5a682d6d58cc5e2b8bea19dbfc9acb1133b35337 --- include/Nazara/Network/TcpBase.hpp | 42 ---------------------------- include/Nazara/Network/TcpBase.inl | 36 ------------------------ include/Nazara/Network/TcpClient.hpp | 13 +++++++-- include/Nazara/Network/TcpClient.inl | 23 +++++++++++++-- include/Nazara/Network/TcpServer.hpp | 6 ++-- include/Nazara/Network/TcpServer.inl | 7 ++++- src/Nazara/Network/TcpBase.cpp | 30 -------------------- src/Nazara/Network/TcpClient.cpp | 8 ++++-- src/Nazara/Network/TcpServer.cpp | 4 +-- 9 files changed, 48 insertions(+), 121 deletions(-) delete mode 100644 include/Nazara/Network/TcpBase.hpp delete mode 100644 include/Nazara/Network/TcpBase.inl delete mode 100644 src/Nazara/Network/TcpBase.cpp diff --git a/include/Nazara/Network/TcpBase.hpp b/include/Nazara/Network/TcpBase.hpp deleted file mode 100644 index 0d7035026..000000000 --- a/include/Nazara/Network/TcpBase.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Network module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_TCPBASE_HPP -#define NAZARA_TCPBASE_HPP - -#include -#include - -namespace Nz -{ - class NAZARA_NETWORK_API TcpBase : public AbstractSocket - { - public: - ~TcpBase() = default; - - inline bool IsLowDelayEnabled() const; - inline bool IsKeepAliveEnabled() const; - - // Slots - NazaraSignal(OnStateChange, const TcpBase* /*socket*/, SocketState /*newState*/); - - protected: - TcpBase(); - TcpBase(TcpBase&& tcpBase); - - virtual void OnOpened() override; - - SocketState m_state; - UInt64 m_keepAliveInterval; - UInt64 m_keepAliveTime; - bool m_isLowDelayEnabled; - bool m_isKeepAliveEnabled; - }; -} - -#include - -#endif // NAZARA_TCPBASE_HPP \ No newline at end of file diff --git a/include/Nazara/Network/TcpBase.inl b/include/Nazara/Network/TcpBase.inl deleted file mode 100644 index 2a1d77d56..000000000 --- a/include/Nazara/Network/TcpBase.inl +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Network module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include - -namespace Nz -{ - inline TcpBase::TcpBase() : - AbstractSocket(SocketType_TCP) - { - } - - inline TcpBase::TcpBase(TcpBase&& tcpBase) : - AbstractSocket(std::move(tcpBase)), - m_state(tcpBase.m_state), - m_keepAliveInterval(tcpBase.m_keepAliveInterval), - m_keepAliveTime(tcpBase.m_keepAliveTime), - m_isLowDelayEnabled(tcpBase.m_isLowDelayEnabled), - m_isKeepAliveEnabled(tcpBase.m_isKeepAliveEnabled) - { - } - - inline bool TcpBase::IsLowDelayEnabled() const - { - return m_isLowDelayEnabled; - } - - inline bool TcpBase::IsKeepAliveEnabled() const - { - return m_isKeepAliveEnabled; - } -} - -#include diff --git a/include/Nazara/Network/TcpClient.hpp b/include/Nazara/Network/TcpClient.hpp index ce8c6a282..c3b0ccc00 100644 --- a/include/Nazara/Network/TcpClient.hpp +++ b/include/Nazara/Network/TcpClient.hpp @@ -9,17 +9,17 @@ #include #include -#include +#include #include namespace Nz { - class NAZARA_NETWORK_API TcpClient : public TcpBase + class NAZARA_NETWORK_API TcpClient : public AbstractSocket { friend class TcpServer; public: - TcpClient() = default; + inline TcpClient(); inline TcpClient(TcpClient&& tcpClient); ~TcpClient() = default; @@ -33,6 +33,9 @@ namespace Nz inline UInt64 GetKeepAliveTime() const; inline IpAddress GetRemoteAddress() const; + inline bool IsLowDelayEnabled() const; + inline bool IsKeepAliveEnabled() const; + SocketState QueryState(); bool Receive(void* buffer, std::size_t size, std::size_t* received); @@ -46,6 +49,10 @@ namespace Nz void Reset(SocketHandle handle, const IpAddress& peerAddress); IpAddress m_peerAddress; + UInt64 m_keepAliveInterval; + UInt64 m_keepAliveTime; + bool m_isLowDelayEnabled; + bool m_isKeepAliveEnabled; }; } diff --git a/include/Nazara/Network/TcpClient.inl b/include/Nazara/Network/TcpClient.inl index 6b981000b..417902035 100644 --- a/include/Nazara/Network/TcpClient.inl +++ b/include/Nazara/Network/TcpClient.inl @@ -7,9 +7,18 @@ namespace Nz { + inline TcpClient::TcpClient() : + AbstractSocket(SocketType_TCP) + { + } + inline TcpClient::TcpClient(TcpClient&& tcpClient) : - TcpBase(std::move(tcpClient)), - m_peerAddress(std::move(tcpClient.m_peerAddress)) + AbstractSocket(std::move(tcpClient)), + m_peerAddress(std::move(tcpClient.m_peerAddress)), + m_keepAliveInterval(tcpClient.m_keepAliveInterval), + m_keepAliveTime(tcpClient.m_keepAliveTime), + m_isLowDelayEnabled(tcpClient.m_isLowDelayEnabled), + m_isKeepAliveEnabled(tcpClient.m_isKeepAliveEnabled) { } @@ -32,6 +41,16 @@ namespace Nz { return m_peerAddress; } + + inline bool TcpClient::IsLowDelayEnabled() const + { + return m_isLowDelayEnabled; + } + + inline bool TcpClient::IsKeepAliveEnabled() const + { + return m_isKeepAliveEnabled; + } } #include diff --git a/include/Nazara/Network/TcpServer.hpp b/include/Nazara/Network/TcpServer.hpp index 92b8a22a7..da1b48e73 100644 --- a/include/Nazara/Network/TcpServer.hpp +++ b/include/Nazara/Network/TcpServer.hpp @@ -8,17 +8,17 @@ #define NAZARA_TCPSERVER_HPP #include -#include +#include #include namespace Nz { class TcpClient; - class NAZARA_NETWORK_API TcpServer : public TcpBase + class NAZARA_NETWORK_API TcpServer : public AbstractSocket { public: - TcpServer() = default; + inline TcpServer(); inline TcpServer(TcpServer&& tcpServer); ~TcpServer() = default; diff --git a/include/Nazara/Network/TcpServer.inl b/include/Nazara/Network/TcpServer.inl index dfcdab110..905320888 100644 --- a/include/Nazara/Network/TcpServer.inl +++ b/include/Nazara/Network/TcpServer.inl @@ -7,8 +7,13 @@ namespace Nz { + inline TcpServer::TcpServer() : + AbstractSocket(SocketType_TCP) + { + } + inline TcpServer::TcpServer(TcpServer&& tcpServer) : - TcpBase(std::move(tcpServer)), + AbstractSocket(std::move(tcpServer)), m_boundAddress(std::move(tcpServer.m_boundAddress)) { } diff --git a/src/Nazara/Network/TcpBase.cpp b/src/Nazara/Network/TcpBase.cpp deleted file mode 100644 index 3f9f173eb..000000000 --- a/src/Nazara/Network/TcpBase.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Utility module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include - -#if defined(NAZARA_PLATFORM_WINDOWS) -#include -#else -#error Missing implementation: Socket -#endif - -namespace Nz -{ - void TcpBase::OnOpened() - { - AbstractSocket::OnOpened(); - - m_isLowDelayEnabled = false; //< Nagle's algorithm, is this enabled everywhere? - m_isKeepAliveEnabled = false; //< default documentation value, OS can change this (TODO: Query OS default value) - m_keepAliveInterval = 1000; //< default documentation value, OS can change this (TODO: Query OS default value) - m_keepAliveTime = 7200000; //< default documentation value, OS can change this (TODO: Query OS default value) - - ChangeState(SocketState_NotConnected); - } -} \ No newline at end of file diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 0c41db30e..8a4c2f453 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -187,15 +187,19 @@ namespace Nz void TcpClient::OnClose() { - TcpBase::OnClose(); + AbstractSocket::OnClose(); m_peerAddress = IpAddress::Invalid; } void TcpClient::OnOpened() { - TcpBase::OnOpened(); + AbstractSocket::OnOpened(); + m_isLowDelayEnabled = false; //< Nagle's algorithm, is this enabled everywhere? + m_isKeepAliveEnabled = false; //< default documentation value, OS can change this (TODO: Query OS default value) + m_keepAliveInterval = 1000; //< default documentation value, OS can change this (TODO: Query OS default value) + m_keepAliveTime = 7200000; //< default documentation value, OS can change this (TODO: Query OS default value) m_peerAddress = IpAddress::Invalid; } diff --git a/src/Nazara/Network/TcpServer.cpp b/src/Nazara/Network/TcpServer.cpp index 5cc999f1c..2aa42956b 100644 --- a/src/Nazara/Network/TcpServer.cpp +++ b/src/Nazara/Network/TcpServer.cpp @@ -49,14 +49,14 @@ namespace Nz void TcpServer::OnClose() { - TcpBase::OnClose(); + AbstractSocket::OnClose(); m_boundAddress = IpAddress::Invalid; } void TcpServer::OnOpened() { - TcpBase::OnOpened(); + AbstractSocket::OnOpened(); m_boundAddress = IpAddress::Invalid; } From 890e5c75d6ff760f30122d2f0a24ef9aa70154e3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 10 Nov 2015 12:17:30 +0100 Subject: [PATCH 28/97] Network/AbstractSocket: Update OnStateChange signal Now it is called before the state changes really Former-commit-id: 3eec47302a971d798e1a75415377243bd743ce3f --- include/Nazara/Network/AbstractSocket.hpp | 2 +- include/Nazara/Network/AbstractSocket.inl | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/include/Nazara/Network/AbstractSocket.hpp b/include/Nazara/Network/AbstractSocket.hpp index 8c9fa5df5..9062fbfa8 100644 --- a/include/Nazara/Network/AbstractSocket.hpp +++ b/include/Nazara/Network/AbstractSocket.hpp @@ -36,7 +36,7 @@ namespace Nz unsigned int QueryAvailableBytes() const; // Slots - NazaraSignal(OnStateChange, const AbstractSocket* /*socket*/, SocketState /*oldState*/, SocketState /*newState*/); + NazaraSignal(OnStateChange, const AbstractSocket* /*socket*/, SocketState /*newState*/); protected: AbstractSocket(SocketType type); diff --git a/include/Nazara/Network/AbstractSocket.inl b/include/Nazara/Network/AbstractSocket.inl index cf75726b0..ffb33f093 100644 --- a/include/Nazara/Network/AbstractSocket.inl +++ b/include/Nazara/Network/AbstractSocket.inl @@ -35,9 +35,8 @@ namespace Nz { if (m_state != newState) { - SocketState oldState = m_state; + OnStateChange(this, m_state); m_state = newState; - OnStateChange(this, oldState, m_state); } } } From 2efaa9dad675b50ad95686669f7b27c87f1f8e21 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 10 Nov 2015 12:19:03 +0100 Subject: [PATCH 29/97] Network/Socket: Rename ChangeState to UpdateState Former-commit-id: 96f1909e002c0d1bc7a3ebd173fae799b6ba4770 --- include/Nazara/Network/AbstractSocket.hpp | 2 +- include/Nazara/Network/AbstractSocket.inl | 2 +- src/Nazara/Network/AbstractSocket.cpp | 2 +- src/Nazara/Network/TcpClient.cpp | 16 ++++++++-------- src/Nazara/Network/TcpServer.cpp | 2 +- src/Nazara/Network/UdpSocket.cpp | 6 +++--- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/include/Nazara/Network/AbstractSocket.hpp b/include/Nazara/Network/AbstractSocket.hpp index 9062fbfa8..caa6bbaaf 100644 --- a/include/Nazara/Network/AbstractSocket.hpp +++ b/include/Nazara/Network/AbstractSocket.hpp @@ -41,7 +41,7 @@ namespace Nz protected: AbstractSocket(SocketType type); - inline void ChangeState(SocketState newState); + inline void UpdateState(SocketState newState); virtual void OnClose(); virtual void OnOpened(); diff --git a/include/Nazara/Network/AbstractSocket.inl b/include/Nazara/Network/AbstractSocket.inl index ffb33f093..5987afe00 100644 --- a/include/Nazara/Network/AbstractSocket.inl +++ b/include/Nazara/Network/AbstractSocket.inl @@ -31,7 +31,7 @@ namespace Nz return m_isBlockingEnabled; } - inline void AbstractSocket::ChangeState(SocketState newState) + inline void AbstractSocket::UpdateState(SocketState newState) { if (m_state != newState) { diff --git a/src/Nazara/Network/AbstractSocket.cpp b/src/Nazara/Network/AbstractSocket.cpp index bcbf8c638..bdd1a7d35 100644 --- a/src/Nazara/Network/AbstractSocket.cpp +++ b/src/Nazara/Network/AbstractSocket.cpp @@ -71,7 +71,7 @@ namespace Nz void AbstractSocket::OnClose() { - ChangeState(SocketState_NotConnected); + UpdateState(SocketState_NotConnected); } void AbstractSocket::OnOpened() diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 8a4c2f453..72db8fa5a 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -42,7 +42,7 @@ namespace Nz if (state != SocketState_NotConnected) m_peerAddress = remoteAddress; - ChangeState(state); + UpdateState(state); return state; } @@ -89,7 +89,7 @@ namespace Nz { // Our connection attempt failed m_lastError = error; - ChangeState(SocketState_NotConnected); + UpdateState(SocketState_NotConnected); } break; @@ -104,10 +104,10 @@ namespace Nz { // Other errors mean a problem while getting the peer address if (error == SocketError_ConnectionClosed) - ChangeState(SocketState_NotConnected); + UpdateState(SocketState_NotConnected); } else - ChangeState(SocketState_Connected); // If we are not connecting and have a peer address, we are connected + UpdateState(SocketState_Connected); // If we are not connecting and have a peer address, we are connected break; } @@ -127,7 +127,7 @@ namespace Nz { case SocketError_ConnectionClosed: case SocketError_ConnectionRefused: - ChangeState(SocketState_NotConnected); + UpdateState(SocketState_NotConnected); break; default: @@ -140,7 +140,7 @@ namespace Nz if (received) *received = read; - ChangeState(SocketState_Connected); + UpdateState(SocketState_Connected); return true; } @@ -168,7 +168,7 @@ namespace Nz { case SocketError_ConnectionClosed: case SocketError_ConnectionRefused: - ChangeState(SocketState_NotConnected); + UpdateState(SocketState_NotConnected); break; default: @@ -181,7 +181,7 @@ namespace Nz totalByteSent += sentSize; } - ChangeState(SocketState_Connected); + UpdateState(SocketState_Connected); return true; } diff --git a/src/Nazara/Network/TcpServer.cpp b/src/Nazara/Network/TcpServer.cpp index 2aa42956b..096603b8f 100644 --- a/src/Nazara/Network/TcpServer.cpp +++ b/src/Nazara/Network/TcpServer.cpp @@ -43,7 +43,7 @@ namespace Nz if (state == SocketState_Bound) m_boundAddress = SocketImpl::QuerySocketAddress(m_handle); - ChangeState(state); + UpdateState(state); return state; } diff --git a/src/Nazara/Network/UdpSocket.cpp b/src/Nazara/Network/UdpSocket.cpp index b73afaf20..b73ef8da2 100644 --- a/src/Nazara/Network/UdpSocket.cpp +++ b/src/Nazara/Network/UdpSocket.cpp @@ -22,7 +22,7 @@ namespace Nz if (state == SocketState_Bound) m_boundAddress = SocketImpl::QuerySocketAddress(m_handle); - ChangeState(state); + UpdateState(state); return state; } @@ -67,13 +67,13 @@ namespace Nz { m_boundAddress = IpAddress::Invalid; - ChangeState(SocketState_NotConnected); + UpdateState(SocketState_NotConnected); } void UdpSocket::OnOpened() { m_boundAddress = IpAddress::Invalid; - ChangeState(SocketState_NotConnected); + UpdateState(SocketState_NotConnected); } } \ No newline at end of file From 64cd9edd6b1387804f8e9069fdae8b937ae09551 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 10 Nov 2015 12:43:30 +0100 Subject: [PATCH 30/97] Network/AbstractSocket: Fix comment Former-commit-id: f74b61def45195a8e5b82f499fbbc05ce0cc492c --- include/Nazara/Network/AbstractSocket.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Network/AbstractSocket.hpp b/include/Nazara/Network/AbstractSocket.hpp index caa6bbaaf..1eab38241 100644 --- a/include/Nazara/Network/AbstractSocket.hpp +++ b/include/Nazara/Network/AbstractSocket.hpp @@ -35,7 +35,7 @@ namespace Nz unsigned int QueryAvailableBytes() const; - // Slots + // Signals: NazaraSignal(OnStateChange, const AbstractSocket* /*socket*/, SocketState /*newState*/); protected: From 5f0aa64555b5d3302150b03b2835bcda86e98c2e Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 10 Nov 2015 12:47:33 +0100 Subject: [PATCH 31/97] Network/TcpClient: Fix clients from TcpServer state Former-commit-id: 39d0884471fb2b0d6a8a12634b26a2f5da894a58 --- src/Nazara/Network/TcpClient.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 72db8fa5a..583c50f44 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -207,5 +207,6 @@ namespace Nz { Open(handle); m_peerAddress = peerAddress; + UpdateState(SocketState_Connected); } } \ No newline at end of file From 4ad1a47064ec5c66e71f86842a4216bc820a8da3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 10 Nov 2015 13:24:25 +0100 Subject: [PATCH 32/97] Network: Add ResolveError handling Former-commit-id: 0dc3d109284e8b475577bf44cbaeb503c4baae73 --- include/Nazara/Network/Enums.hpp | 16 ++++++ include/Nazara/Network/IpAddress.hpp | 4 +- src/Nazara/Network/IpAddress.cpp | 8 +-- src/Nazara/Network/Win32/IpAddressImpl.cpp | 64 ++++++++++++++++++++-- src/Nazara/Network/Win32/IpAddressImpl.hpp | 5 +- 5 files changed, 83 insertions(+), 14 deletions(-) diff --git a/include/Nazara/Network/Enums.hpp b/include/Nazara/Network/Enums.hpp index b2184ab64..87eab41ae 100644 --- a/include/Nazara/Network/Enums.hpp +++ b/include/Nazara/Network/Enums.hpp @@ -9,6 +9,22 @@ namespace Nz { + enum ResolveError + { + ResolveError_NoError, + + ResolveError_Internal, //< An internal error occured + ResolveError_ResourceError, //< The operating system lacks the resources to proceed (insufficient memory) + ResolveError_NonRecoverable, //< An nonrecoverable error occured + ResolveError_NotFound, //< No such host is known + ResolveError_NotInitialized, //< Nazara network has not been initialized + ResolveError_ProtocolNotSupported, //< A specified protocol is not supported by the server + ResolveError_TemporaryFailure, //< A temporary failure occured, try again + ResolveError_Unknown, //< The last operation failed with an unlisted error code + + ResolveError_Max = ResolveError_TemporaryFailure + }; + enum NetProtocol { NetProtocol_Any, diff --git a/include/Nazara/Network/IpAddress.hpp b/include/Nazara/Network/IpAddress.hpp index b426f1c16..e7ae9bd23 100644 --- a/include/Nazara/Network/IpAddress.hpp +++ b/include/Nazara/Network/IpAddress.hpp @@ -55,8 +55,8 @@ namespace Nz IpAddress& operator=(const IpAddress&) = default; IpAddress& operator=(IpAddress&&) = default; - static String ResolveAddress(const IpAddress& address, String* service = nullptr); - static std::vector ResolveHostname(NetProtocol procol, const String& hostname, const String& protocol = "http"); + static String ResolveAddress(const IpAddress& address, String* service = nullptr, ResolveError* error = nullptr); + static std::vector ResolveHostname(NetProtocol procol, const String& hostname, const String& protocol = "http", ResolveError* error = nullptr); inline friend std::ostream& operator<<(std::ostream& out, const IpAddress& address); diff --git a/src/Nazara/Network/IpAddress.cpp b/src/Nazara/Network/IpAddress.cpp index 41654eb4e..7dfe07056 100644 --- a/src/Nazara/Network/IpAddress.cpp +++ b/src/Nazara/Network/IpAddress.cpp @@ -142,17 +142,17 @@ namespace Nz return stream; } - String IpAddress::ResolveAddress(const IpAddress& address, String* service) + String IpAddress::ResolveAddress(const IpAddress& address, String* service, ResolveError* error) { String hostname; - IpAddressImpl::ResolveAddress(address, &hostname, service); + IpAddressImpl::ResolveAddress(address, &hostname, service, error); return hostname; } - std::vector IpAddress::ResolveHostname(NetProtocol protocol, const String& hostname, const String& service) + std::vector IpAddress::ResolveHostname(NetProtocol protocol, const String& hostname, const String& service, ResolveError* error) { - return IpAddressImpl::ResolveHostname(protocol, hostname, service); + return IpAddressImpl::ResolveHostname(protocol, hostname, service, error); } IpAddress IpAddress::AnyIpV4(0, 0, 0, 0); diff --git a/src/Nazara/Network/Win32/IpAddressImpl.cpp b/src/Nazara/Network/Win32/IpAddressImpl.cpp index 0ded6dbdc..360513ff5 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.cpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.cpp @@ -147,15 +147,26 @@ namespace Nz return IpAddress(rawIpV6[0], rawIpV6[1], rawIpV6[2], rawIpV6[3], rawIpV6[4], rawIpV6[5], rawIpV6[6], rawIpV6[7], ntohs(addressv6->sin6_port)); } - bool IpAddressImpl::ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service) + bool IpAddressImpl::ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service, ResolveError* error) { SockAddrBuffer socketAddress; socklen_t socketAddressLen = ToSockAddr(ipAddress, socketAddress.data()); - return Detail::GetHostnameInfo(reinterpret_cast(socketAddress.data()), socketAddressLen, hostname, service) == 0; + if (Detail::GetHostnameInfo(reinterpret_cast(socketAddress.data()), socketAddressLen, hostname, service) != 0) + { + if (error) + *error = TranslateWSAErrorToResolveError(WSAGetLastError()); + + return false; + } + + if (error) + *error = ResolveError_NoError; + + return true; } - std::vector IpAddressImpl::ResolveHostname(NetProtocol procol, const String& hostname, const String& service) + std::vector IpAddressImpl::ResolveHostname(NetProtocol procol, const String& hostname, const String& service, ResolveError* error) { std::vector results; @@ -165,10 +176,11 @@ namespace Nz hints.ai_socktype = SOCK_STREAM; Detail::addrinfoImpl* servinfo; - int rv; - if ((rv = Detail::GetAddressInfo(hostname, service, &hints, &servinfo)) != 0) + if (Detail::GetAddressInfo(hostname, service, &hints, &servinfo) != 0) { - fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); + if (error) + *error = TranslateWSAErrorToResolveError(WSAGetLastError()); + return results; } @@ -190,6 +202,9 @@ namespace Nz results.push_back(result); } + if (error) + *error = ResolveError_NoError; + return results; } @@ -237,4 +252,41 @@ namespace Nz NazaraError("Invalid ip address"); return 0; } + + ResolveError IpAddressImpl::TranslateWSAErrorToResolveError(int error) + { + switch (error) + { + case 0: + return ResolveError_NoError; + + // Engine error + case WSAEFAULT: + case WSAEINVAL: + return ResolveError_Internal; + + case WSAEAFNOSUPPORT: + case WSAESOCKTNOSUPPORT: + case WSASERVICE_NOT_FOUND: + return ResolveError_ProtocolNotSupported; + + case WSAHOST_NOT_FOUND: + return ResolveError_NotFound; + + case WSANO_RECOVERY: + return ResolveError_NonRecoverable; + + case WSANOTINITIALISED: + return ResolveError_NotInitialized; + + case WSA_NOT_ENOUGH_MEMORY: + return ResolveError_ResourceError; + + case WSATRY_AGAIN: + return ResolveError_TemporaryFailure; + } + + NazaraWarning("Unhandled WinSock error: " + Error::GetLastSystemError(error) + " (" + String::Number(error) + ')'); + return ResolveError_Unknown; + } } diff --git a/src/Nazara/Network/Win32/IpAddressImpl.hpp b/src/Nazara/Network/Win32/IpAddressImpl.hpp index 57e6bbcc5..ad3ca6689 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.hpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.hpp @@ -22,9 +22,10 @@ namespace Nz static IpAddress FromSockAddr(const sockaddr_in* addressv4); static IpAddress FromSockAddr(const sockaddr_in6* addressv6); - static bool ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service); - static std::vector ResolveHostname(NetProtocol procol, const String& hostname, const String& service); + static bool ResolveAddress(const IpAddress& ipAddress, String* hostname, String* service, ResolveError* error); + static std::vector ResolveHostname(NetProtocol procol, const String& hostname, const String& service, ResolveError* error); static socklen_t ToSockAddr(const IpAddress& ipAddress, void* buffer); + static ResolveError TranslateWSAErrorToResolveError(int error); }; } From 65bc2d46e7ef74e1db3497f114ca4206e56a45db Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 10 Nov 2015 13:26:47 +0100 Subject: [PATCH 33/97] Network/Win32: Update comment Former-commit-id: 8e8592279e3df84c88ea14b9698dbb172ee21566 --- src/Nazara/Network/Win32/SocketImpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 3ff57da52..83ffaf55c 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -145,7 +145,7 @@ namespace Nz if (ret > 0) { int code = GetLastErrorCode(handle, error); - if (code < 0) //< GetLastSocketError() failed + if (code < 0) //< GetLastErrorCode() failed return SocketState_NotConnected; if (code) From 66daa6833334f25f4ba3df4db0539485378b7fa1 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 10 Nov 2015 13:35:09 +0100 Subject: [PATCH 34/97] Network: Little clean up Former-commit-id: 594fbfbbe9051ac4ec7b647f9e2eb1a74d640a69 --- include/Nazara/Network/IpAddress.hpp | 4 ++-- src/Nazara/Network/Win32/IpAddressImpl.cpp | 8 +++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/include/Nazara/Network/IpAddress.hpp b/include/Nazara/Network/IpAddress.hpp index e7ae9bd23..5ac902a66 100644 --- a/include/Nazara/Network/IpAddress.hpp +++ b/include/Nazara/Network/IpAddress.hpp @@ -91,8 +91,8 @@ namespace Nz IpAddress address; String canonicalName; int flags; - int family; - int socketType; + int family; //< TODO: NetProtocol + int socketType; //< TODO: SocketType }; } diff --git a/src/Nazara/Network/Win32/IpAddressImpl.cpp b/src/Nazara/Network/Win32/IpAddressImpl.cpp index 360513ff5..5715859ca 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.cpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.cpp @@ -96,7 +96,7 @@ namespace Nz } } - return IpAddress(); + return IpAddress::Invalid; } IpAddress IpAddressImpl::FromAddrinfo(const addrinfoW* info) @@ -118,7 +118,7 @@ namespace Nz } } - return IpAddress(); + return IpAddress::Invalid; } IpAddress IpAddressImpl::FromSockAddr(const sockaddr* address) @@ -132,7 +132,7 @@ namespace Nz return FromSockAddr(reinterpret_cast(address)); } - return IpAddress(); + return IpAddress::Invalid; } IpAddress IpAddressImpl::FromSockAddr(const sockaddr_in* addressv4) @@ -238,8 +238,6 @@ namespace Nz for (unsigned int i = 0; i < 8; ++i) socketAddress->sin6_addr.u.Word[i] = htons(address[i]); - IN6_ADDR any = in6addr_any; - return sizeof(sockaddr_in6); } From dd987e6b71c07dcb554ca0ae4a8e24076e12b947 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 10 Nov 2015 13:53:23 +0100 Subject: [PATCH 35/97] Network: Fix global header Former-commit-id: 13b207375cecf63722f45d24d0de5f756fe0a815 --- include/Nazara/Network.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/include/Nazara/Network.hpp b/include/Nazara/Network.hpp index fe2948399..d5c731be7 100644 --- a/include/Nazara/Network.hpp +++ b/include/Nazara/Network.hpp @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include From fd09cdbf1e83f9aabd9976748ecbd587c2f30502 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 10 Nov 2015 13:55:42 +0100 Subject: [PATCH 36/97] Network/TcpClient: Replace Connect overload by WaitForConnected method Former-commit-id: 11ff81ea975f79a51f6342a9a574a23d18c0180f --- include/Nazara/Network/TcpClient.hpp | 4 +- src/Nazara/Network/TcpClient.cpp | 57 ++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 9 deletions(-) diff --git a/include/Nazara/Network/TcpClient.hpp b/include/Nazara/Network/TcpClient.hpp index c3b0ccc00..cd7f1dc16 100644 --- a/include/Nazara/Network/TcpClient.hpp +++ b/include/Nazara/Network/TcpClient.hpp @@ -23,7 +23,7 @@ namespace Nz inline TcpClient(TcpClient&& tcpClient); ~TcpClient() = default; - SocketState Connect(const IpAddress& remoteAddress, UInt64 msTimeout = 3000); + SocketState Connect(const IpAddress& remoteAddress); inline void Disconnect(); void EnableLowDelay(bool lowDelay); @@ -42,6 +42,8 @@ namespace Nz bool Send(const void* buffer, std::size_t size, std::size_t* sent); + bool WaitForConnected(UInt64 msTimeout = 3000); + private: void OnClose() override; void OnOpened() override; diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 583c50f44..14d06ac97 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -16,7 +16,7 @@ namespace Nz { - SocketState TcpClient::Connect(const IpAddress& remoteAddress, UInt64 msTimeout) + SocketState TcpClient::Connect(const IpAddress& remoteAddress) { NazaraAssert(remoteAddress.IsValid(), "Invalid remote address"); NazaraAssert(remoteAddress.GetPort() != 0, "Remote address has no port"); @@ -33,12 +33,7 @@ namespace Nz }); } - SocketState state; - if (msTimeout > 0) - state = SocketImpl::Connect(m_handle, remoteAddress, msTimeout, &m_lastError); - else - state = SocketImpl::Connect(m_handle, remoteAddress, &m_lastError); - + SocketState state = SocketImpl::Connect(m_handle, remoteAddress, &m_lastError); if (state != SocketState_NotConnected) m_peerAddress = remoteAddress; @@ -48,6 +43,8 @@ namespace Nz void TcpClient::EnableLowDelay(bool lowDelay) { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); + if (m_isLowDelayEnabled != lowDelay) { SocketImpl::SetBlocking(m_handle, lowDelay, &m_lastError); @@ -57,6 +54,8 @@ namespace Nz void TcpClient::EnableKeepAlive(bool keepAlive, UInt64 msTime, UInt64 msInterval) { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); + if (m_isKeepAliveEnabled != keepAlive || m_keepAliveTime != msTime || m_keepAliveInterval != msInterval) { SocketImpl::SetKeepAlive(m_handle, keepAlive, msTime, msInterval, &m_lastError); @@ -83,7 +82,7 @@ namespace Nz if (error == SocketError_NoError) { // No error yet, we're still connecting or connected, check that by connecting again - return Connect(m_peerAddress, 0); + return Connect(m_peerAddress); } else { @@ -118,6 +117,7 @@ namespace Nz bool TcpClient::Receive(void* buffer, std::size_t size, std::size_t* received) { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); NazaraAssert(buffer && size > 0, "Invalid buffer"); int read; @@ -146,6 +146,7 @@ namespace Nz bool TcpClient::Send(const void* buffer, std::size_t size, std::size_t* sent) { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); NazaraAssert(buffer && size > 0, "Invalid buffer"); CallOnExit updateSent; @@ -185,6 +186,46 @@ namespace Nz return true; } + bool TcpClient::WaitForConnected(UInt64 msTimeout) + { + switch (m_state) + { + case SocketState_Connected: + return true; + + case SocketState_Connecting: + { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); + + CallOnExit restoreBlocking; + if (m_isBlockingEnabled) + { + SocketImpl::SetBlocking(m_handle, false); + restoreBlocking.Reset([this] () + { + SocketImpl::SetBlocking(m_handle, true); + }); + } + + SocketState newState = SocketImpl::Connect(m_handle, m_peerAddress, msTimeout, &m_lastError); + NazaraAssert(newState != SocketState_Connecting, "Invalid internal return"); + + // Prevent valid peer adddress in non-connected state + if (newState == SocketState_NotConnected) + m_peerAddress = IpAddress::Invalid; + + UpdateState(newState); + return m_state == SocketState_Connected; + } + + case SocketState_NotConnected: + return false; + } + + NazaraInternalError("Unhandled socket state (0x" + String::Number(m_state, 16) + ')'); + return false; + } + void TcpClient::OnClose() { AbstractSocket::OnClose(); From 3b9c736c168eca59b36040e2ff216bde66dd0417 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 10 Nov 2015 14:42:36 +0100 Subject: [PATCH 37/97] Network/AbstractSocket: Fix state sent to OnStateChange Former-commit-id: ae83ea675153d7954187c12d93d7c8c42d8e1dfc --- include/Nazara/Network/AbstractSocket.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Nazara/Network/AbstractSocket.inl b/include/Nazara/Network/AbstractSocket.inl index 5987afe00..8bebabfdb 100644 --- a/include/Nazara/Network/AbstractSocket.inl +++ b/include/Nazara/Network/AbstractSocket.inl @@ -35,7 +35,7 @@ namespace Nz { if (m_state != newState) { - OnStateChange(this, m_state); + OnStateChange(this, newState); m_state = newState; } } From a26c979d8496448a1d1fac56a6a6249cb3afcf39 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 10 Nov 2015 14:45:59 +0100 Subject: [PATCH 38/97] Network/TcpClient: Add Connect overload resolving hostname Former-commit-id: 5c667a14c591e4e9cb898a8d4c83fedf161179fd --- include/Nazara/Network/Enums.hpp | 2 ++ include/Nazara/Network/IpAddress.hpp | 4 ++-- include/Nazara/Network/TcpClient.hpp | 1 + src/Nazara/Network/TcpClient.cpp | 28 ++++++++++++++++++++++++++++ 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Network/Enums.hpp b/include/Nazara/Network/Enums.hpp index 87eab41ae..5481d22a9 100644 --- a/include/Nazara/Network/Enums.hpp +++ b/include/Nazara/Network/Enums.hpp @@ -46,6 +46,7 @@ namespace Nz SocketError_NetworkError, //< The network system has failed (maybe network is down) SocketError_NotInitialized, //< Nazara network has not been initialized SocketError_NotSupported, //< The operation is not supported (e.g. creating a bluetooth socket on a system without any bluetooth adaptater) + SocketError_ResolveError, //< The hostname couldn't be resolved (more information in ResolveError code) SocketError_ResourceError, //< The operating system lacks the resources to proceed (e.g. memory/socket descriptor) SocketError_UnreachableHost, //< The host is not reachable SocketError_TimedOut, //< The operation timed out @@ -60,6 +61,7 @@ namespace Nz SocketState_Connecting, //< The socket is currently connecting SocketState_Connected, //< The socket is currently connected SocketState_NotConnected, //< The socket is not connected (or has been disconnected) + SocketState_Resolving, //< The socket is currently resolving a hostname SocketState_Max = SocketState_NotConnected }; diff --git a/include/Nazara/Network/IpAddress.hpp b/include/Nazara/Network/IpAddress.hpp index 5ac902a66..c9fa5c5b9 100644 --- a/include/Nazara/Network/IpAddress.hpp +++ b/include/Nazara/Network/IpAddress.hpp @@ -29,8 +29,8 @@ namespace Nz inline IpAddress(const IPv6& ip, UInt16 port = 0); inline IpAddress(const UInt8& a, const UInt8& b, const UInt8& c, const UInt8& d, UInt16 port = 0); inline IpAddress(const UInt16& a, const UInt16& b, const UInt16& c, const UInt16& d, const UInt16& e, const UInt16& f, const UInt16& g, const UInt16& h, UInt16 port = 0); - inline IpAddress(const char* address); - inline IpAddress(const String& address); + inline explicit IpAddress(const char* address); + inline explicit IpAddress(const String& address); IpAddress(const IpAddress&) = default; IpAddress(IpAddress&&) = default; ~IpAddress() = default; diff --git a/include/Nazara/Network/TcpClient.hpp b/include/Nazara/Network/TcpClient.hpp index cd7f1dc16..7dbe2f1a6 100644 --- a/include/Nazara/Network/TcpClient.hpp +++ b/include/Nazara/Network/TcpClient.hpp @@ -24,6 +24,7 @@ namespace Nz ~TcpClient() = default; SocketState Connect(const IpAddress& remoteAddress); + SocketState Connect(const String& hostName, NetProtocol protocol = NetProtocol_Any, const String& service = "http", ResolveError* error = nullptr); inline void Disconnect(); void EnableLowDelay(bool lowDelay); diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 14d06ac97..ab825bb89 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -41,6 +41,34 @@ namespace Nz return state; } + SocketState TcpClient::Connect(const String& hostName, NetProtocol protocol, const String& service, ResolveError* error) + { + Disconnect(); + + UpdateState(SocketState_Resolving); + std::vector results = IpAddress::ResolveHostname(protocol, hostName, service, error); + if (results.empty()) + { + m_lastError = SocketError_ResolveError; + + UpdateState(SocketState_NotConnected); + return m_state; + } + + IpAddress hostnameAddress; + for (const HostnameInfo& result : results) + { + //TODO: Check PF_ type (TCP) + if (!result.address) + continue; + + hostnameAddress = result.address; + break; //< Take first valid address + } + + return Connect(hostnameAddress); + } + void TcpClient::EnableLowDelay(bool lowDelay) { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); From 5d6e6b2d4522cef8d6a8a6744e6193d60f604fba Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 12 Nov 2015 00:29:10 +0100 Subject: [PATCH 39/97] Fix errors and warnings Former-commit-id: a3ba309633f198f82c1d0277d750d867cad4ba44 --- SDK/src/NDK/Entity.cpp | 2 +- include/Nazara/Graphics/Billboard.inl | 4 ++-- include/Nazara/Network/Debug.hpp | 2 +- include/Nazara/Network/DebugOff.hpp | 2 +- include/Nazara/Network/IpAddress.inl | 23 ++++++++++++++-------- include/Nazara/Network/TcpServer.inl | 4 ++++ include/Nazara/Network/UdpSocket.inl | 4 ++++ src/Nazara/Core/String.cpp | 1 - src/Nazara/Graphics/Material.cpp | 2 -- src/Nazara/Network/Algorithm.cpp | 9 +++++---- src/Nazara/Network/IpAddress.cpp | 17 +++++++++++----- src/Nazara/Network/TcpClient.cpp | 6 +++++- src/Nazara/Network/Win32/IpAddressImpl.cpp | 5 +++-- src/Nazara/Renderer/Renderer.cpp | 4 ++-- 14 files changed, 55 insertions(+), 30 deletions(-) diff --git a/SDK/src/NDK/Entity.cpp b/SDK/src/NDK/Entity.cpp index d26a8f953..42ecf36b1 100644 --- a/SDK/src/NDK/Entity.cpp +++ b/SDK/src/NDK/Entity.cpp @@ -12,9 +12,9 @@ namespace Ndk Entity::Entity(Entity&& entity) : m_components(std::move(entity.m_components)), m_handles(std::move(entity.m_handles)), - m_id(entity.m_id), m_componentBits(std::move(entity.m_componentBits)), m_systemBits(std::move(entity.m_systemBits)), + m_id(entity.m_id), m_world(entity.m_world), m_valid(entity.m_valid) { diff --git a/include/Nazara/Graphics/Billboard.inl b/include/Nazara/Graphics/Billboard.inl index 4a8cde469..c9760d0d1 100644 --- a/include/Nazara/Graphics/Billboard.inl +++ b/include/Nazara/Graphics/Billboard.inl @@ -35,9 +35,9 @@ namespace Nz InstancedRenderable(billboard), m_color(billboard.m_color), m_material(billboard.m_material), - m_rotation(billboard.m_rotation), m_sinCos(billboard.m_sinCos), - m_size(billboard.m_size) + m_size(billboard.m_size), + m_rotation(billboard.m_rotation) { } diff --git a/include/Nazara/Network/Debug.hpp b/include/Nazara/Network/Debug.hpp index 458bcf548..0826a3ecc 100644 --- a/include/Nazara/Network/Debug.hpp +++ b/include/Nazara/Network/Debug.hpp @@ -3,6 +3,6 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#if NAZARA_MODULENAME_MANAGE_MEMORY +#if NAZARA_NETWORK_MANAGE_MEMORY #include #endif diff --git a/include/Nazara/Network/DebugOff.hpp b/include/Nazara/Network/DebugOff.hpp index 9ae8c8e69..dd45ac45c 100644 --- a/include/Nazara/Network/DebugOff.hpp +++ b/include/Nazara/Network/DebugOff.hpp @@ -3,7 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp // On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp -#if NAZARA_MODULENAME_MANAGE_MEMORY +#if NAZARA_NETWORK_MANAGE_MEMORY #undef delete #undef new #endif diff --git a/include/Nazara/Network/IpAddress.inl b/include/Nazara/Network/IpAddress.inl index f12361081..c9aab3065 100644 --- a/include/Nazara/Network/IpAddress.inl +++ b/include/Nazara/Network/IpAddress.inl @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include namespace Nz @@ -13,31 +14,31 @@ namespace Nz } inline IpAddress::IpAddress(const IPv4& ip, UInt16 port) : - m_isValid(true), m_ipv4(ip), m_protocol(NetProtocol_IPv4), - m_port(port) + m_port(port), + m_isValid(true) { } - + inline IpAddress::IpAddress(const IPv6& ip, UInt16 port) : - m_isValid(true), m_ipv6(ip), m_protocol(NetProtocol_IPv6), - m_port(port) + m_port(port), + m_isValid(true) { } - + inline IpAddress::IpAddress(const UInt8& a, const UInt8& b, const UInt8& c, const UInt8& d, UInt16 port) : IpAddress(IPv4{a, b, c, d}, port) { } - + inline IpAddress::IpAddress(const UInt16& a, const UInt16& b, const UInt16& c, const UInt16& d, const UInt16& e, const UInt16& f, const UInt16& g, const UInt16& h, UInt16 port) : IpAddress(IPv6{a, b, c, d, e, f, g, h}, port) { } - + inline IpAddress::IpAddress(const char* address) { BuildFromAddress(address); @@ -116,6 +117,9 @@ namespace Nz // Each protocol has its variables to compare switch (first.m_protocol) { + case NetProtocol_Any: + break; + case NetProtocol_IPv4: { if (first.m_ipv4 != second.m_ipv4) @@ -162,6 +166,9 @@ namespace Nz // Compare IP (thanks to std::array comparison operator) switch (first.m_protocol) { + case NetProtocol_Any: + break; + case NetProtocol_IPv4: { if (first.m_ipv4 != second.m_ipv4) diff --git a/include/Nazara/Network/TcpServer.inl b/include/Nazara/Network/TcpServer.inl index 905320888..42092b41b 100644 --- a/include/Nazara/Network/TcpServer.inl +++ b/include/Nazara/Network/TcpServer.inl @@ -35,6 +35,10 @@ namespace Nz IpAddress any; switch (protocol) { + case NetProtocol_Any: + NazaraInternalError("Invalid protocol Any at this point"); + return SocketState_NotConnected; + case NetProtocol_IPv4: any = IpAddress::AnyIpV4; break; diff --git a/include/Nazara/Network/UdpSocket.inl b/include/Nazara/Network/UdpSocket.inl index a77aeca3b..fbfe7f6ab 100644 --- a/include/Nazara/Network/UdpSocket.inl +++ b/include/Nazara/Network/UdpSocket.inl @@ -29,6 +29,10 @@ namespace Nz IpAddress any; switch (m_protocol) { + case NetProtocol_Any: + NazaraInternalError("Invalid protocol Any at this point"); + return SocketState_NotConnected; + case NetProtocol_IPv4: any = IpAddress::AnyIpV4; break; diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index fc63ebe06..a8e462d5d 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -1912,7 +1912,6 @@ namespace Nz } else { - unsigned int newSize = m_sharedString->size + length; auto newString = std::make_shared(m_sharedString->size + length); char* ptr = newString->string.get(); diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 15e851c78..9d34c9995 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -724,8 +724,6 @@ namespace Nz return false; } - bool glsl140 = (OpenGL::GetGLSLVersion() >= 140); - // Basic shader { UberShaderPreprocessorRef uberShader = UberShaderPreprocessor::New(); diff --git a/src/Nazara/Network/Algorithm.cpp b/src/Nazara/Network/Algorithm.cpp index 628e9cf45..273169005 100644 --- a/src/Nazara/Network/Algorithm.cpp +++ b/src/Nazara/Network/Algorithm.cpp @@ -4,6 +4,7 @@ #include #include +#include #include namespace Nz @@ -173,14 +174,14 @@ namespace Nz addressPtr = savedPtr; // who knows how to parse ipv4? we do! - UInt8 result[16]; - bool isIPv6; - if (!ParseIPAddress(addressPtr, result, nullptr, &isIPv6, &addressPtr) || isIPv6) // must parse and must be ipv4 + UInt8 ipv4[16]; + bool ipv6; + if (!ParseIPAddress(addressPtr, ipv4, nullptr, &ipv6, &addressPtr) || ipv6) // must parse and must be ipv4 return false; // transfer addrlocal into the present location for (unsigned int j = 0; j < 4; ++j) - *(resultPtr++) = result[j]; + *(resultPtr++) = ipv4[j]; ++i; // pretend like we took another short, since the ipv4 effectively is two shorts mappedIPv4 = true; // remember how we got here for further validation later diff --git a/src/Nazara/Network/IpAddress.cpp b/src/Nazara/Network/IpAddress.cpp index 7dfe07056..473ce579f 100644 --- a/src/Nazara/Network/IpAddress.cpp +++ b/src/Nazara/Network/IpAddress.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #if defined(NAZARA_PLATFORM_WINDOWS) @@ -55,6 +56,9 @@ namespace Nz NazaraAssert(m_protocol <= NetProtocol_Max, "Protocol has value out of enum"); switch (m_protocol) { + case NetProtocol_Any: + break; + case NetProtocol_IPv4: return m_ipv4[0] == 127; @@ -69,12 +73,15 @@ namespace Nz String IpAddress::ToString() const { StringStream stream; - + if (m_isValid) { NazaraAssert(m_protocol <= NetProtocol_Max, "Protocol has value out of enum"); switch (m_protocol) { + case NetProtocol_Any: + break; + case NetProtocol_IPv4: for (unsigned int i = 0; i < 4; ++i) { @@ -89,8 +96,8 @@ namespace Nz // https://tools.ietf.org/html/rfc5952 // Find the longest zero sequence - int f0 = -1; - int l0 = -1; + unsigned int f0 = std::numeric_limits::max(); + unsigned int l0 = std::numeric_limits::max(); for (unsigned int i = 0; i < 8; ++i) { @@ -138,7 +145,7 @@ namespace Nz if (m_port != 0) stream << ':' << m_port; } - + return stream; } @@ -146,7 +153,7 @@ namespace Nz { String hostname; IpAddressImpl::ResolveAddress(address, &hostname, service, error); - + return hostname; } diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index ab825bb89..22d93c08e 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -218,6 +218,10 @@ namespace Nz { switch (m_state) { + case SocketState_Bound: + case SocketState_Resolving: + break; + case SocketState_Connected: return true; @@ -278,4 +282,4 @@ namespace Nz m_peerAddress = peerAddress; UpdateState(SocketState_Connected); } -} \ No newline at end of file +} diff --git a/src/Nazara/Network/Win32/IpAddressImpl.cpp b/src/Nazara/Network/Win32/IpAddressImpl.cpp index 5715859ca..1a5de9ada 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.cpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace Nz @@ -64,7 +65,7 @@ namespace Nz if (service) service->Set(serviceBuffer.data()); } - + return result; } @@ -95,7 +96,7 @@ namespace Nz return IpAddress(rawIpV6[0], rawIpV6[1], rawIpV6[2], rawIpV6[3], rawIpV6[4], rawIpV6[5], rawIpV6[6], rawIpV6[7], ntohs(ipv6->sin6_port)); } } - + return IpAddress::Invalid; } diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 23167dae9..7c2ba3459 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -1546,7 +1546,7 @@ namespace Nz glBindBuffer(OpenGL::BufferTarget[BufferType_Vertex], vertexBufferImpl->GetOpenGLID()); unsigned int bufferOffset = vertexBuffer->GetStartOffset(); - const VertexDeclaration* vertexDeclaration = vertexBuffer->GetVertexDeclaration(); + vertexDeclaration = vertexBuffer->GetVertexDeclaration(); unsigned int stride = vertexDeclaration->GetStride(); // On définit les bornes (une fois de plus selon l'itération) @@ -1934,4 +1934,4 @@ namespace Nz } unsigned int Renderer::s_moduleReferenceCounter = 0; -} \ No newline at end of file +} From 81221fbf0b13267edade5837a3227c9bea62662d Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 12 Nov 2015 13:19:21 +0100 Subject: [PATCH 40/97] Network/TcpClient: Fix LowDelay Former-commit-id: 70fc4224ae7f8913e27a3a3cf234500db262f73c --- src/Nazara/Network/TcpClient.cpp | 4 ++-- src/Nazara/Network/Win32/SocketImpl.cpp | 19 +++++++++++++++++++ src/Nazara/Network/Win32/SocketImpl.hpp | 1 + 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index ab825bb89..745c23fd6 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -75,7 +75,7 @@ namespace Nz if (m_isLowDelayEnabled != lowDelay) { - SocketImpl::SetBlocking(m_handle, lowDelay, &m_lastError); + SocketImpl::SetNoDelay(m_handle, lowDelay, &m_lastError); m_isLowDelayEnabled = lowDelay; } } @@ -238,7 +238,7 @@ namespace Nz SocketState newState = SocketImpl::Connect(m_handle, m_peerAddress, msTimeout, &m_lastError); NazaraAssert(newState != SocketState_Connecting, "Invalid internal return"); - // Prevent valid peer adddress in non-connected state + // Prevent valid peer address in non-connected state if (newState == SocketState_NotConnected) m_peerAddress = IpAddress::Invalid; diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 83ffaf55c..ecb9b678b 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -534,6 +534,25 @@ namespace Nz return true; } + bool SocketImpl::SetNoDelay(SocketHandle handle, bool nodelay, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + BOOL option = nodelay; + if (setsockopt(handle, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast(&option), sizeof(option)) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return false; //< Error + } + + if (error) + *error = SocketError_NoError; + + return true; + } + SocketError SocketImpl::TranslateWSAErrorToSocketError(int error) { switch (error) diff --git a/src/Nazara/Network/Win32/SocketImpl.hpp b/src/Nazara/Network/Win32/SocketImpl.hpp index 9eb2c11ff..f1c94e737 100644 --- a/src/Nazara/Network/Win32/SocketImpl.hpp +++ b/src/Nazara/Network/Win32/SocketImpl.hpp @@ -48,6 +48,7 @@ namespace Nz static bool SetBlocking(SocketHandle handle, bool blocking, SocketError* error = nullptr); static bool SetKeepAlive(SocketHandle handle, bool enabled, UInt64 msTime, UInt64 msInterval, SocketError* error = nullptr); + static bool SetNoDelay(SocketHandle handle, bool nodelay, SocketError* error = nullptr); static SocketError TranslateWSAErrorToSocketError(int error); static int TranslateNetProtocolToAF(NetProtocol protocol); From f28e1a7d9b42b521b7a66c77519f21860c3a9710 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 12 Nov 2015 13:35:46 +0100 Subject: [PATCH 41/97] Network/UdpSocket: Add broadcasting option Former-commit-id: bde428efc5e9c77cf3e64ec04d58d72613f1d8de --- include/Nazara/Network/UdpSocket.hpp | 5 +++++ include/Nazara/Network/UdpSocket.inl | 5 +++++ src/Nazara/Network/UdpSocket.cpp | 12 ++++++++++++ src/Nazara/Network/Win32/SocketImpl.cpp | 19 +++++++++++++++++++ src/Nazara/Network/Win32/SocketImpl.hpp | 1 + 5 files changed, 42 insertions(+) diff --git a/include/Nazara/Network/UdpSocket.hpp b/include/Nazara/Network/UdpSocket.hpp index 4730f4793..e6577bec7 100644 --- a/include/Nazara/Network/UdpSocket.hpp +++ b/include/Nazara/Network/UdpSocket.hpp @@ -26,10 +26,14 @@ namespace Nz inline bool Create(NetProtocol protocol); + void EnableBroadcasting(bool broadcasting); + inline IpAddress GetBoundAddress() const; inline UInt16 GetBoundPort() const; inline SocketState GetState() const; + inline bool IsBroadcastingEnabled() const; + unsigned int QueryMaxDatagramSize(); bool Receive(void* buffer, std::size_t size, IpAddress* from, std::size_t* received); @@ -42,6 +46,7 @@ namespace Nz IpAddress m_boundAddress; SocketState m_state; + bool m_isBroadCastingEnabled; }; } diff --git a/include/Nazara/Network/UdpSocket.inl b/include/Nazara/Network/UdpSocket.inl index a77aeca3b..d412c45bc 100644 --- a/include/Nazara/Network/UdpSocket.inl +++ b/include/Nazara/Network/UdpSocket.inl @@ -61,6 +61,11 @@ namespace Nz { return m_state; } + + inline bool UdpSocket::IsBroadcastingEnabled() const + { + return m_isBroadCastingEnabled; + } } #include diff --git a/src/Nazara/Network/UdpSocket.cpp b/src/Nazara/Network/UdpSocket.cpp index b73ef8da2..6bece4f28 100644 --- a/src/Nazara/Network/UdpSocket.cpp +++ b/src/Nazara/Network/UdpSocket.cpp @@ -26,6 +26,17 @@ namespace Nz return state; } + void UdpSocket::EnableBroadcasting(bool broadcasting) + { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); + + if (m_isBroadCastingEnabled != broadcasting) + { + SocketImpl::SetBroadcasting(m_handle, broadcasting, &m_lastError); + m_isBroadCastingEnabled = broadcasting; + } + } + unsigned int UdpSocket::QueryMaxDatagramSize() { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Socket hasn't been created"); @@ -73,6 +84,7 @@ namespace Nz void UdpSocket::OnOpened() { m_boundAddress = IpAddress::Invalid; + m_isBroadCastingEnabled = false; UpdateState(SocketState_NotConnected); } diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index ecb9b678b..5e1834e6b 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -509,6 +509,25 @@ namespace Nz return true; } + + bool SocketImpl::SetBroadcasting(SocketHandle handle, bool broadcasting, SocketError* error) + { + NazaraAssert(handle != InvalidHandle, "Invalid handle"); + + BOOL option = broadcasting; + if (setsockopt(handle, SOL_SOCKET, SO_BROADCAST, reinterpret_cast(&option), sizeof(option)) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return false; //< Error + } + + if (error) + *error = SocketError_NoError; + + return true; + } bool SocketImpl::SetKeepAlive(SocketHandle handle, bool enabled, UInt64 msTime, UInt64 msInterval, SocketError* error) { diff --git a/src/Nazara/Network/Win32/SocketImpl.hpp b/src/Nazara/Network/Win32/SocketImpl.hpp index f1c94e737..ad58c76f0 100644 --- a/src/Nazara/Network/Win32/SocketImpl.hpp +++ b/src/Nazara/Network/Win32/SocketImpl.hpp @@ -47,6 +47,7 @@ namespace Nz static bool SendTo(SocketHandle handle, const void* buffer, int length, const IpAddress& to, int* sent, SocketError* error); static bool SetBlocking(SocketHandle handle, bool blocking, SocketError* error = nullptr); + static bool SetBroadcasting(SocketHandle handle, bool broadcasting, SocketError* error = nullptr); static bool SetKeepAlive(SocketHandle handle, bool enabled, UInt64 msTime, UInt64 msInterval, SocketError* error = nullptr); static bool SetNoDelay(SocketHandle handle, bool nodelay, SocketError* error = nullptr); From b77c50fe58236a018336c0b5b853d4ff5f1e23bb Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 12 Nov 2015 14:54:47 +0100 Subject: [PATCH 42/97] Network/TcpClient: Fix peer address not updated if Connect() fails Former-commit-id: 1c8f9d5e20f6266d40233e7ad0ecf7b12fee0127 --- src/Nazara/Network/TcpClient.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 745c23fd6..ed9842631 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -34,8 +34,7 @@ namespace Nz } SocketState state = SocketImpl::Connect(m_handle, remoteAddress, &m_lastError); - if (state != SocketState_NotConnected) - m_peerAddress = remoteAddress; + m_peerAddress = (state != SocketState_NotConnected) ? remoteAddress : IpAddress::Invalid; UpdateState(state); return state; @@ -109,7 +108,7 @@ namespace Nz if (error == SocketError_NoError) { - // No error yet, we're still connecting or connected, check that by connecting again + // No error yet, we're still connecting or connected, check that by calling Connect again return Connect(m_peerAddress); } else @@ -243,7 +242,7 @@ namespace Nz m_peerAddress = IpAddress::Invalid; UpdateState(newState); - return m_state == SocketState_Connected; + return newState == SocketState_Connected; } case SocketState_NotConnected: From 328083638e2530869af994e0bd25c589ffe06aa4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 13 Nov 2015 13:07:24 +0100 Subject: [PATCH 43/97] Network/UdpSocket: Improve code Former-commit-id: 66ad787d036b6c855dd2a0872c2ceecff9a1674e --- src/Nazara/Network/UdpSocket.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Nazara/Network/UdpSocket.cpp b/src/Nazara/Network/UdpSocket.cpp index 6bece4f28..fb813b3d6 100644 --- a/src/Nazara/Network/UdpSocket.cpp +++ b/src/Nazara/Network/UdpSocket.cpp @@ -76,16 +76,16 @@ namespace Nz void UdpSocket::OnClose() { - m_boundAddress = IpAddress::Invalid; + AbstractSocket::OnClose(); - UpdateState(SocketState_NotConnected); + m_boundAddress = IpAddress::Invalid; } void UdpSocket::OnOpened() { + AbstractSocket::OnOpened(); + m_boundAddress = IpAddress::Invalid; m_isBroadCastingEnabled = false; - - UpdateState(SocketState_NotConnected); } -} \ No newline at end of file +} From 8935aa895d4b6197b0b4a82f48b654643b730767 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 13 Nov 2015 13:07:49 +0100 Subject: [PATCH 44/97] Network/SocketImpl: Fix QueryAvailableBytes error handling on Windows Former-commit-id: 7b1c17a66416201ebea620eb8f992092b511adb8 --- src/Nazara/Network/Win32/SocketImpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 5e1834e6b..8d408cd20 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -266,7 +266,7 @@ namespace Nz if (error) *error = TranslateWSAErrorToSocketError(WSAGetLastError()); - availableBytes = 0; + return 0; } if (error) From 5325513bd886bd708fc7ed0d2259661925e9c067 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 13 Nov 2015 14:01:18 +0100 Subject: [PATCH 45/97] Network/TcpClient: Allow configuration before connection Former-commit-id: 65c81f994ae5b9e9cce0132e2a86b1918879b24f --- include/Nazara/Network/TcpClient.inl | 6 +++++- src/Nazara/Network/AbstractSocket.cpp | 6 +++--- src/Nazara/Network/TcpClient.cpp | 24 ++++++++++++++---------- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/include/Nazara/Network/TcpClient.inl b/include/Nazara/Network/TcpClient.inl index 417902035..60c879497 100644 --- a/include/Nazara/Network/TcpClient.inl +++ b/include/Nazara/Network/TcpClient.inl @@ -8,7 +8,11 @@ namespace Nz { inline TcpClient::TcpClient() : - AbstractSocket(SocketType_TCP) + AbstractSocket(SocketType_TCP), + m_keepAliveInterval(1000), //TODO: Query OS default value + m_keepAliveTime(7'200'000), //TODO: Query OS default value + m_isKeepAliveEnabled(false), //TODO: Query OS default value + m_isLowDelayEnabled(false) //TODO: Query OS default value { } diff --git a/src/Nazara/Network/AbstractSocket.cpp b/src/Nazara/Network/AbstractSocket.cpp index bdd1a7d35..d86f93501 100644 --- a/src/Nazara/Network/AbstractSocket.cpp +++ b/src/Nazara/Network/AbstractSocket.cpp @@ -76,9 +76,9 @@ namespace Nz void AbstractSocket::OnOpened() { - SocketError error; - if (!SocketImpl::SetBlocking(m_handle, m_isBlockingEnabled, &error)) - NazaraWarning("Failed to set socket blocking mode (0x" + String::Number(ERROR, 16) + ')'); + SocketError errorCode; + if (!SocketImpl::SetBlocking(m_handle, m_isBlockingEnabled, &errorCode)) + NazaraWarning("Failed to set socket blocking mode (0x" + String::Number(errorCode, 16) + ')'); } bool AbstractSocket::Open(NetProtocol protocol) diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index c668058a4..87094cb36 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -70,22 +70,22 @@ namespace Nz void TcpClient::EnableLowDelay(bool lowDelay) { - NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); - if (m_isLowDelayEnabled != lowDelay) { - SocketImpl::SetNoDelay(m_handle, lowDelay, &m_lastError); + if (m_handle != SocketImpl::InvalidHandle) + SocketImpl::SetNoDelay(m_handle, lowDelay, &m_lastError); + m_isLowDelayEnabled = lowDelay; } } void TcpClient::EnableKeepAlive(bool keepAlive, UInt64 msTime, UInt64 msInterval) { - NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); - if (m_isKeepAliveEnabled != keepAlive || m_keepAliveTime != msTime || m_keepAliveInterval != msInterval) { - SocketImpl::SetKeepAlive(m_handle, keepAlive, msTime, msInterval, &m_lastError); + if (m_handle != SocketImpl::InvalidHandle) + SocketImpl::SetKeepAlive(m_handle, keepAlive, msTime, msInterval, &m_lastError); + m_isKeepAliveEnabled = keepAlive; m_keepAliveInterval = msInterval; m_keepAliveTime = msTime; @@ -268,10 +268,14 @@ namespace Nz { AbstractSocket::OnOpened(); - m_isLowDelayEnabled = false; //< Nagle's algorithm, is this enabled everywhere? - m_isKeepAliveEnabled = false; //< default documentation value, OS can change this (TODO: Query OS default value) - m_keepAliveInterval = 1000; //< default documentation value, OS can change this (TODO: Query OS default value) - m_keepAliveTime = 7200000; //< default documentation value, OS can change this (TODO: Query OS default value) + SocketError errorCode; + + if (!SocketImpl::SetNoDelay(m_handle, m_isLowDelayEnabled, &errorCode)) + NazaraWarning("Failed to set socket no delay mode (0x" + String::Number(errorCode, 16) + ')'); + + if (!SocketImpl::SetKeepAlive(m_handle, m_isKeepAliveEnabled, m_keepAliveTime, m_keepAliveInterval, &errorCode)) + NazaraWarning("Failed to set socket keep alive mode (0x" + String::Number(errorCode, 16) + ')'); + m_peerAddress = IpAddress::Invalid; } From a324f44901795baaeee8c76e09b8f846d80ab05f Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 13 Nov 2015 14:01:36 +0100 Subject: [PATCH 46/97] Network/TcpClient: Fix QueryState() when connection failed Former-commit-id: 15824535922186c0601ade8bfbbe76866b7cd5ff --- src/Nazara/Network/TcpClient.cpp | 76 +++++++++++++++++--------------- 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 87094cb36..6e4dec7b8 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -94,50 +94,56 @@ namespace Nz SocketState TcpClient::QueryState() { - // Check our state depending on our last state - switch (m_state) + // Only check state if we have a valid handle, else we're not connected. + if (m_handle != SocketImpl::InvalidHandle) { - case SocketState_Connecting: + // Check our state depending on our last state + switch (m_state) { - // If we were connecting, check how it's going - SocketError getError; - SocketError error = SocketImpl::GetLastError(m_handle, &getError); - - if (getError != SocketError_NoError) - break; //< Do not update state if we cannot get socket state - - if (error == SocketError_NoError) + case SocketState_Connecting: { - // No error yet, we're still connecting or connected, check that by calling Connect again - return Connect(m_peerAddress); - } - else - { - // Our connection attempt failed - m_lastError = error; - UpdateState(SocketState_NotConnected); - } + // If we were connecting, check how it's going + SocketError getError; + SocketError error = SocketImpl::GetLastError(m_handle, &getError); - break; - } + if (getError != SocketError_NoError) + break; //< Do not update state if we cannot get socket state - default: - { - // Check our peer address, if it works we're connected - SocketError error; - m_peerAddress = SocketImpl::QueryPeerAddress(m_handle, &error); - if (m_peerAddress == IpAddress::Invalid) - { - // Other errors mean a problem while getting the peer address - if (error == SocketError_ConnectionClosed) + if (error == SocketError_NoError) + { + // No error yet, we're still connecting or connected, check that by calling Connect again + return Connect(m_peerAddress); + } + else + { + // Our connection attempt failed + m_lastError = error; UpdateState(SocketState_NotConnected); - } - else - UpdateState(SocketState_Connected); // If we are not connecting and have a peer address, we are connected + } - break; + break; + } + + default: + { + // Check our peer address, if it works we're connected + SocketError error; + m_peerAddress = SocketImpl::QueryPeerAddress(m_handle, &error); + if (m_peerAddress == IpAddress::Invalid) + { + // Other errors mean a problem while getting the peer address + if (error == SocketError_ConnectionClosed) + UpdateState(SocketState_NotConnected); + } + else + UpdateState(SocketState_Connected); // If we are not connecting and have a peer address, we are connected + + break; + } } } + else + UpdateState(SocketState_NotConnected); return m_state; } From 3a4acd95847b543b07f0e9031c8dd4e75c1b987a Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 13 Nov 2015 14:17:43 +0100 Subject: [PATCH 47/97] Network/TcpClient: Remove unreliable QueryState() Former-commit-id: 75d61ca0d84150a278c168c81af4c755e8a74d91 --- include/Nazara/Network/TcpClient.hpp | 2 - src/Nazara/Network/TcpClient.cpp | 56 ---------------------------- 2 files changed, 58 deletions(-) diff --git a/include/Nazara/Network/TcpClient.hpp b/include/Nazara/Network/TcpClient.hpp index 7dbe2f1a6..ef696fac3 100644 --- a/include/Nazara/Network/TcpClient.hpp +++ b/include/Nazara/Network/TcpClient.hpp @@ -37,8 +37,6 @@ namespace Nz inline bool IsLowDelayEnabled() const; inline bool IsKeepAliveEnabled() const; - SocketState QueryState(); - bool Receive(void* buffer, std::size_t size, std::size_t* received); bool Send(const void* buffer, std::size_t size, std::size_t* sent); diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 6e4dec7b8..41c48ac1c 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -92,62 +92,6 @@ namespace Nz } } - SocketState TcpClient::QueryState() - { - // Only check state if we have a valid handle, else we're not connected. - if (m_handle != SocketImpl::InvalidHandle) - { - // Check our state depending on our last state - switch (m_state) - { - case SocketState_Connecting: - { - // If we were connecting, check how it's going - SocketError getError; - SocketError error = SocketImpl::GetLastError(m_handle, &getError); - - if (getError != SocketError_NoError) - break; //< Do not update state if we cannot get socket state - - if (error == SocketError_NoError) - { - // No error yet, we're still connecting or connected, check that by calling Connect again - return Connect(m_peerAddress); - } - else - { - // Our connection attempt failed - m_lastError = error; - UpdateState(SocketState_NotConnected); - } - - break; - } - - default: - { - // Check our peer address, if it works we're connected - SocketError error; - m_peerAddress = SocketImpl::QueryPeerAddress(m_handle, &error); - if (m_peerAddress == IpAddress::Invalid) - { - // Other errors mean a problem while getting the peer address - if (error == SocketError_ConnectionClosed) - UpdateState(SocketState_NotConnected); - } - else - UpdateState(SocketState_Connected); // If we are not connecting and have a peer address, we are connected - - break; - } - } - } - else - UpdateState(SocketState_NotConnected); - - return m_state; - } - bool TcpClient::Receive(void* buffer, std::size_t size, std::size_t* received) { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); From 1b4ac70ac3b1b654bbe5ca543dc52d00894ffd22 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 13 Nov 2015 18:21:26 +0100 Subject: [PATCH 48/97] Network/SocketImpl: Fix SetKeepAlive Former-commit-id: 490857d9a34ed1492710666695965bc930691c0b --- src/Nazara/Network/Win32/SocketImpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 8d408cd20..37c435c9e 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -539,7 +539,7 @@ namespace Nz keepAlive.keepalivetime = static_cast(msTime); DWORD dummy; //< byteReturned - if (!WSAIoctl(handle, SIO_KEEPALIVE_VALS, &keepAlive, sizeof(keepAlive), nullptr, 0, &dummy, nullptr, nullptr)) + if (WSAIoctl(handle, SIO_KEEPALIVE_VALS, &keepAlive, sizeof(keepAlive), nullptr, 0, &dummy, nullptr, nullptr) == SOCKET_ERROR) { if (error) *error = TranslateWSAErrorToSocketError(WSAGetLastError()); From e8aa649cfc4afdbb130334cad910930daedc7e97 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 14 Nov 2015 02:12:10 +0100 Subject: [PATCH 49/97] Network/HostnameInfo: Replace family/socketType raw value by engine enumeration Former-commit-id: 40adb7654b5a741c5fa12c1b866e3b427b1be5e9 --- include/Nazara/Network/Enums.hpp | 6 ++- include/Nazara/Network/IpAddress.hpp | 5 +-- include/Nazara/Network/IpAddress.inl | 2 + include/Nazara/Network/TcpServer.inl | 2 + include/Nazara/Network/UdpSocket.inl | 3 ++ src/Nazara/Network/IpAddress.cpp | 6 +++ src/Nazara/Network/TcpClient.cpp | 4 +- src/Nazara/Network/Win32/IpAddressImpl.cpp | 48 ++++++++++++++++++---- src/Nazara/Network/Win32/IpAddressImpl.hpp | 2 + src/Nazara/Network/Win32/SocketImpl.cpp | 10 +++-- 10 files changed, 70 insertions(+), 18 deletions(-) diff --git a/include/Nazara/Network/Enums.hpp b/include/Nazara/Network/Enums.hpp index 5481d22a9..21c96dde4 100644 --- a/include/Nazara/Network/Enums.hpp +++ b/include/Nazara/Network/Enums.hpp @@ -30,8 +30,9 @@ namespace Nz NetProtocol_Any, NetProtocol_IPv4, NetProtocol_IPv6, + NetProtocol_Unknown, - NetProtocol_Max = NetProtocol_IPv6 + NetProtocol_Max = NetProtocol_Unknown }; enum SocketError @@ -71,8 +72,9 @@ namespace Nz SocketType_Raw, SocketType_TCP, SocketType_UDP, + SocketType_Unknown, - SocketType_Max = SocketType_UDP + SocketType_Max = SocketType_Unknown }; } diff --git a/include/Nazara/Network/IpAddress.hpp b/include/Nazara/Network/IpAddress.hpp index c9fa5c5b9..32def1031 100644 --- a/include/Nazara/Network/IpAddress.hpp +++ b/include/Nazara/Network/IpAddress.hpp @@ -89,10 +89,9 @@ namespace Nz struct HostnameInfo { IpAddress address; + NetProtocol protocol; + SocketType socketType; String canonicalName; - int flags; - int family; //< TODO: NetProtocol - int socketType; //< TODO: SocketType }; } diff --git a/include/Nazara/Network/IpAddress.inl b/include/Nazara/Network/IpAddress.inl index c9aab3065..425fa6fee 100644 --- a/include/Nazara/Network/IpAddress.inl +++ b/include/Nazara/Network/IpAddress.inl @@ -118,6 +118,7 @@ namespace Nz switch (first.m_protocol) { case NetProtocol_Any: + case NetProtocol_Unknown: break; case NetProtocol_IPv4: @@ -167,6 +168,7 @@ namespace Nz switch (first.m_protocol) { case NetProtocol_Any: + case NetProtocol_Unknown: break; case NetProtocol_IPv4: diff --git a/include/Nazara/Network/TcpServer.inl b/include/Nazara/Network/TcpServer.inl index 42092b41b..5350a58ee 100644 --- a/include/Nazara/Network/TcpServer.inl +++ b/include/Nazara/Network/TcpServer.inl @@ -31,11 +31,13 @@ namespace Nz inline SocketState TcpServer::Listen(NetProtocol protocol, UInt16 port, unsigned int queueSize) { NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO + NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol"); IpAddress any; switch (protocol) { case NetProtocol_Any: + case NetProtocol_Unknown: NazaraInternalError("Invalid protocol Any at this point"); return SocketState_NotConnected; diff --git a/include/Nazara/Network/UdpSocket.inl b/include/Nazara/Network/UdpSocket.inl index 4a75da130..9ad4d067b 100644 --- a/include/Nazara/Network/UdpSocket.inl +++ b/include/Nazara/Network/UdpSocket.inl @@ -30,6 +30,7 @@ namespace Nz switch (m_protocol) { case NetProtocol_Any: + case NetProtocol_Unknown: NazaraInternalError("Invalid protocol Any at this point"); return SocketState_NotConnected; @@ -48,6 +49,8 @@ namespace Nz bool UdpSocket::Create(NetProtocol protocol) { + NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol"); + return Open(protocol); } diff --git a/src/Nazara/Network/IpAddress.cpp b/src/Nazara/Network/IpAddress.cpp index 473ce579f..b44412aca 100644 --- a/src/Nazara/Network/IpAddress.cpp +++ b/src/Nazara/Network/IpAddress.cpp @@ -57,6 +57,7 @@ namespace Nz switch (m_protocol) { case NetProtocol_Any: + case NetProtocol_Unknown: break; case NetProtocol_IPv4: @@ -80,6 +81,7 @@ namespace Nz switch (m_protocol) { case NetProtocol_Any: + case NetProtocol_Unknown: break; case NetProtocol_IPv4: @@ -151,6 +153,8 @@ namespace Nz String IpAddress::ResolveAddress(const IpAddress& address, String* service, ResolveError* error) { + NazaraAssert(address.IsValid(), "Invalid address"); + String hostname; IpAddressImpl::ResolveAddress(address, &hostname, service, error); @@ -159,6 +163,8 @@ namespace Nz std::vector IpAddress::ResolveHostname(NetProtocol protocol, const String& hostname, const String& service, ResolveError* error) { + NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol"); + return IpAddressImpl::ResolveHostname(protocol, hostname, service, error); } diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 41c48ac1c..4c13c5c03 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -57,10 +57,12 @@ namespace Nz IpAddress hostnameAddress; for (const HostnameInfo& result : results) { - //TODO: Check PF_ type (TCP) if (!result.address) continue; + if (result.socketType != SocketType_TCP) + continue; + hostnameAddress = result.address; break; //< Take first valid address } diff --git a/src/Nazara/Network/Win32/IpAddressImpl.cpp b/src/Nazara/Network/Win32/IpAddressImpl.cpp index 1a5de9ada..9b8e383fc 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.cpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.cpp @@ -21,12 +21,12 @@ namespace Nz return GetAddrInfoW(hostname.GetWideString().c_str(), service.GetWideString().c_str(), &hints, &servinfo); } - int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service) + int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service, INT flags) { std::array hostnameBuffer; std::array serviceBuffer; - int result = GetNameInfoW(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), NI_NUMERICSERV); + int result = GetNameInfoW(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), flags); if (result == 0) { if (hostname) @@ -51,12 +51,12 @@ namespace Nz return getaddrinfo(hostname.GetConstBuffer(), service.GetConstBuffer(), hints, results); } - int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service) + int GetHostnameInfo(sockaddr* socketAddress, socklen_t socketLen, String* hostname, String* service, INT flags) { std::array hostnameBuffer; std::array serviceBuffer; - int result = getnameinfo(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), NI_NUMERICSERV); + int result = getnameinfo(socketAddress, socketLen, hostnameBuffer.data(), hostnameBuffer.size(), serviceBuffer.data(), serviceBuffer.size(), flags); if (result == 0) { if (hostname) @@ -153,7 +153,7 @@ namespace Nz SockAddrBuffer socketAddress; socklen_t socketAddressLen = ToSockAddr(ipAddress, socketAddress.data()); - if (Detail::GetHostnameInfo(reinterpret_cast(socketAddress.data()), socketAddressLen, hostname, service) != 0) + if (Detail::GetHostnameInfo(reinterpret_cast(socketAddress.data()), socketAddressLen, hostname, service, NI_NUMERICSERV) != 0) { if (error) *error = TranslateWSAErrorToResolveError(WSAGetLastError()); @@ -196,9 +196,8 @@ namespace Nz HostnameInfo result; result.address = FromAddrinfo(p); result.canonicalName = String::Unicode(p->ai_canonname); - result.family = p->ai_family; - result.flags = p->ai_flags; - result.socketType = p->ai_socktype; + result.protocol = TranslatePFToNetProtocol(p->ai_family); + result.socketType = TranslateSockToNetProtocol(p->ai_socktype); results.push_back(result); } @@ -252,6 +251,39 @@ namespace Nz return 0; } + NetProtocol IpAddressImpl::TranslatePFToNetProtocol(int family) + { + switch (family) + { + case PF_INET: + return NetProtocol_IPv4; + + case PF_INET6: + return NetProtocol_IPv6; + + default: + return NetProtocol_Unknown; + } + } + + SocketType IpAddressImpl::TranslateSockToNetProtocol(int socketType) + { + switch (socketType) + { + case SOCK_STREAM: + return SocketType_TCP; + + case SOCK_DGRAM: + return SocketType_UDP; + + case SOCK_RAW: + return SocketType_Raw; + + default: + return SocketType_Unknown; + } + } + ResolveError IpAddressImpl::TranslateWSAErrorToResolveError(int error) { switch (error) diff --git a/src/Nazara/Network/Win32/IpAddressImpl.hpp b/src/Nazara/Network/Win32/IpAddressImpl.hpp index ad3ca6689..4b27bef32 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.hpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.hpp @@ -26,6 +26,8 @@ namespace Nz static std::vector ResolveHostname(NetProtocol procol, const String& hostname, const String& service, ResolveError* error); static socklen_t ToSockAddr(const IpAddress& ipAddress, void* buffer); + static NetProtocol TranslatePFToNetProtocol(int family); + static SocketType TranslateSockToNetProtocol(int socketType); static ResolveError TranslateWSAErrorToResolveError(int error); }; } diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 37c435c9e..ede89d2ea 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -646,7 +646,8 @@ namespace Nz static int addressFamily[] = { AF_UNSPEC, //< NetProtocol_Any AF_INET, //< NetProtocol_IPv4 - AF_INET6 //< NetProtocol_IPv6 + AF_INET6, //< NetProtocol_IPv6 + -1 //< NetProtocol_Unknown }; static_assert(sizeof(addressFamily) / sizeof(int) == NetProtocol_Max + 1, "Address family array is incomplete"); @@ -658,9 +659,10 @@ namespace Nz NazaraAssert(type <= SocketType_Max, "Socket type has value out of enum"); static int socketType[] = { - SOCK_RAW, //< SocketType_Raw - SOCK_STREAM, //< SocketType_TCP - SOCK_DGRAM //< SocketType_UDP + SOCK_RAW, //< SocketType_Raw + SOCK_STREAM, //< SocketType_TCP + SOCK_DGRAM, //< SocketType_UDP + -1 //< SocketType_Unknown }; static_assert(sizeof(socketType) / sizeof(int) == SocketType_Max + 1, "Socket type array is incomplete"); From a128c2aacbffafdea7ec193034c8d0e2f5b8db2a Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 14 Nov 2015 02:12:40 +0100 Subject: [PATCH 50/97] Network/HostnameInfo: Fix empty canonical name on Windows Former-commit-id: 5cbe995eaf14305d70d2ccd43b8d3120c4b6ad2e --- src/Nazara/Network/Win32/IpAddressImpl.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Nazara/Network/Win32/IpAddressImpl.cpp b/src/Nazara/Network/Win32/IpAddressImpl.cpp index 9b8e383fc..b23ceae04 100644 --- a/src/Nazara/Network/Win32/IpAddressImpl.cpp +++ b/src/Nazara/Network/Win32/IpAddressImpl.cpp @@ -174,6 +174,7 @@ namespace Nz Detail::addrinfoImpl hints; std::memset(&hints, 0, sizeof(Detail::addrinfoImpl)); hints.ai_family = SocketImpl::TranslateNetProtocolToAF(procol); + hints.ai_flags = AI_CANONNAME; hints.ai_socktype = SOCK_STREAM; Detail::addrinfoImpl* servinfo; From 6a3eb6822504b81b5b608210c2e15ddc09db6ded Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 14 Nov 2015 11:43:06 +0100 Subject: [PATCH 51/97] Core/String: Fix heap corruption Former-commit-id: cf3f1172a43b7ddb9b8e8e9521e3dc1258fa6c21 --- src/Nazara/Core/String.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index a8e462d5d..d39f9adb1 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -4195,9 +4195,9 @@ namespace Nz if (!m_sharedString.unique()) { - auto newSharedString = std::make_shared(GetSize()); + auto newSharedString = std::make_shared(GetSize(), GetCapacity()); if (!discardContent) - std::memcpy(newSharedString->string.get(), GetConstBuffer(), GetSize()); + std::memcpy(newSharedString->string.get(), GetConstBuffer(), GetSize()+1); m_sharedString = std::move(newSharedString); } From 682b8811f540ba448631274c979e8655a24e7cc8 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 14 Nov 2015 11:43:24 +0100 Subject: [PATCH 52/97] Graphics/TextSprite: Fix crash Former-commit-id: c659044edff45afc7eec91065619bdfb402bc32d --- src/Nazara/Graphics/TextSprite.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index 820ed557a..b746756d9 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -217,6 +217,8 @@ namespace Nz for (auto& pair : m_renderInfos) { RenderIndices& indices = pair.second; + if (indices.count == 0) + continue; //< Ignore empty render indices SparsePtr color = colorPtr + indices.first*4; SparsePtr pos = posPtr + indices.first*4; From b64ea6f53451776cdacf4d89085bb5f5251b792b Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 14 Nov 2015 17:37:03 +0100 Subject: [PATCH 53/97] Core/String: Fix missing modifications Former-commit-id: ac0e45fcc8caf8135542cb2fa6ab02b22182735a --- include/Nazara/Core/String.hpp | 1 + include/Nazara/Core/String.inl | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 06b9d2c09..c7cc5418a 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -317,6 +317,7 @@ namespace Nz { inline SharedString(); inline SharedString(unsigned int strSize); + inline SharedString(unsigned int strSize, unsigned int strCapacity); unsigned int capacity; unsigned int size; diff --git a/include/Nazara/Core/String.inl b/include/Nazara/Core/String.inl index 656a56121..49157777f 100644 --- a/include/Nazara/Core/String.inl +++ b/include/Nazara/Core/String.inl @@ -23,12 +23,20 @@ namespace Nz } inline String::SharedString::SharedString(unsigned int strSize) : - capacity(strSize), + capacity(strSize), size(strSize), string(new char[strSize + 1]) { string[strSize] = '\0'; } + + inline String::SharedString::SharedString(unsigned int strSize, unsigned int strCapacity) : + capacity(strCapacity), + size(strSize), + string(new char[strCapacity + 1]) + { + string[strSize] = '\0'; + } } namespace std From 0cda3c1d145b9020e2224105f55ce567a37e1386 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 16 Nov 2015 10:05:45 +0100 Subject: [PATCH 54/97] Network/SocketImpl: Add query methods I'm still not sure I will use them Former-commit-id: 1c023a51372b6864ebd7f09142ff9adeced72dd0 --- src/Nazara/Network/Win32/SocketImpl.cpp | 57 +++++++++++++++++++++++++ src/Nazara/Network/Win32/SocketImpl.hpp | 3 ++ 2 files changed, 60 insertions(+) diff --git a/src/Nazara/Network/Win32/SocketImpl.cpp b/src/Nazara/Network/Win32/SocketImpl.cpp index 37c435c9e..7fd34405a 100644 --- a/src/Nazara/Network/Win32/SocketImpl.cpp +++ b/src/Nazara/Network/Win32/SocketImpl.cpp @@ -275,6 +275,44 @@ namespace Nz return availableBytes; } + bool SocketImpl::QueryBroadcasting(SocketHandle handle, SocketError* error) + { + BOOL code; + int codeLength = sizeof(code); + + if (getsockopt(handle, SOL_SOCKET, SO_BROADCAST, reinterpret_cast(&code), &codeLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return false; + } + + if (error) + *error = SocketError_NoError; + + return code == TRUE; + } + + bool SocketImpl::QueryKeepAlive(SocketHandle handle, SocketError* error) + { + BOOL code; + int codeLength = sizeof(code); + + if (getsockopt(handle, SOL_SOCKET, SO_KEEPALIVE, reinterpret_cast(&code), &codeLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return false; + } + + if (error) + *error = SocketError_NoError; + + return code == TRUE; + } + unsigned int SocketImpl::QueryMaxDatagramSize(SocketHandle handle, SocketError* error) { unsigned int code; @@ -294,6 +332,25 @@ namespace Nz return code; } + bool SocketImpl::QueryNoDelay(SocketHandle handle, SocketError* error) + { + BOOL code; + int codeLength = sizeof(code); + + if (getsockopt(handle, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast(&code), &codeLength) == SOCKET_ERROR) + { + if (error) + *error = TranslateWSAErrorToSocketError(WSAGetLastError()); + + return false; + } + + if (error) + *error = SocketError_NoError; + + return code == TRUE; + } + IpAddress SocketImpl::QueryPeerAddress(SocketHandle handle, SocketError* error) { NazaraAssert(handle != InvalidHandle, "Invalid handle"); diff --git a/src/Nazara/Network/Win32/SocketImpl.hpp b/src/Nazara/Network/Win32/SocketImpl.hpp index ad58c76f0..8f6b1f72d 100644 --- a/src/Nazara/Network/Win32/SocketImpl.hpp +++ b/src/Nazara/Network/Win32/SocketImpl.hpp @@ -36,7 +36,10 @@ namespace Nz static SocketState Listen(SocketHandle handle, const IpAddress& address, unsigned queueSize, SocketError* error); static unsigned int QueryAvailableBytes(SocketHandle handle, SocketError* error = nullptr); + static bool QueryBroadcasting(SocketHandle handle, SocketError* error = nullptr); + static bool QueryKeepAlive(SocketHandle handle, SocketError* error = nullptr); static unsigned int QueryMaxDatagramSize(SocketHandle handle, SocketError* error = nullptr); + static bool QueryNoDelay(SocketHandle handle, SocketError* error = nullptr); static IpAddress QueryPeerAddress(SocketHandle handle, SocketError* error = nullptr); static IpAddress QuerySocketAddress(SocketHandle handle, SocketError* error = nullptr); From 21f223f1c7bd45d0b49383c66900155992aaceb4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 16 Nov 2015 14:04:39 +0100 Subject: [PATCH 55/97] Core: Reworked hashes -Removed HashDigest class (replaced by ByteArray) -Removed Hashable/Hash classes (replaced by ComputeHash function and Hashable template struct) -Fixed ByteArray operator<< -Renamed File::GetHash to File::ComputeHash Former-commit-id: cc5eaf2d4c88a556878190b8205e66713512e2d2 --- include/Nazara/Core/AbstractHash.hpp | 11 +- include/Nazara/Core/Algorithm.hpp | 9 ++ include/Nazara/Core/Algorithm.inl | 16 ++ include/Nazara/Core/ByteArray.hpp | 14 +- include/Nazara/Core/ByteArray.inl | 21 +++ include/Nazara/Core/File.hpp | 15 +- include/Nazara/Core/File.inl | 56 +++++++ include/Nazara/Core/Hash.hpp | 36 ----- include/Nazara/Core/Hash/CRC32.hpp | 12 +- include/Nazara/Core/Hash/Fletcher16.hpp | 12 +- include/Nazara/Core/Hash/MD5.hpp | 12 +- include/Nazara/Core/Hash/SHA1.hpp | 12 +- include/Nazara/Core/Hash/SHA224.hpp | 12 +- include/Nazara/Core/Hash/SHA256.hpp | 12 +- include/Nazara/Core/Hash/SHA384.hpp | 12 +- include/Nazara/Core/Hash/SHA512.hpp | 12 +- include/Nazara/Core/Hash/Whirlpool.hpp | 12 +- include/Nazara/Core/HashDigest.hpp | 56 ------- include/Nazara/Core/Hashable.hpp | 39 ----- include/Nazara/Core/String.hpp | 11 +- include/Nazara/Core/String.inl | 11 ++ src/Nazara/Core/AbstractHash.cpp | 48 ++++++ src/Nazara/Core/ByteArray.cpp | 11 +- src/Nazara/Core/File.cpp | 45 ------ src/Nazara/Core/Hash.cpp | 83 ---------- src/Nazara/Core/Hash/CRC32.cpp | 11 +- src/Nazara/Core/Hash/Fletcher16.cpp | 11 +- src/Nazara/Core/Hash/MD5.cpp | 11 +- src/Nazara/Core/Hash/SHA1.cpp | 11 +- src/Nazara/Core/Hash/SHA224.cpp | 11 +- src/Nazara/Core/Hash/SHA256.cpp | 11 +- src/Nazara/Core/Hash/SHA384.cpp | 11 +- src/Nazara/Core/Hash/SHA512.cpp | 11 +- src/Nazara/Core/Hash/Whirlpool.cpp | 11 +- src/Nazara/Core/HashDigest.cpp | 194 ------------------------ src/Nazara/Core/Hashable.cpp | 24 --- src/Nazara/Core/String.cpp | 8 - 37 files changed, 294 insertions(+), 621 deletions(-) create mode 100644 include/Nazara/Core/File.inl delete mode 100644 include/Nazara/Core/Hash.hpp delete mode 100644 include/Nazara/Core/HashDigest.hpp delete mode 100644 include/Nazara/Core/Hashable.hpp delete mode 100644 src/Nazara/Core/Hash.cpp delete mode 100644 src/Nazara/Core/HashDigest.cpp delete mode 100644 src/Nazara/Core/Hashable.cpp diff --git a/include/Nazara/Core/AbstractHash.hpp b/include/Nazara/Core/AbstractHash.hpp index 7314b1b59..bc0a1a4a9 100644 --- a/include/Nazara/Core/AbstractHash.hpp +++ b/include/Nazara/Core/AbstractHash.hpp @@ -8,10 +8,12 @@ #define NAZARA_ABSTRACTHASH_HPP #include +#include +#include namespace Nz { - class HashDigest; + class ByteArray; class NAZARA_CORE_API AbstractHash { @@ -23,10 +25,15 @@ namespace Nz virtual void Append(const UInt8* data, unsigned int len) = 0; virtual void Begin() = 0; - virtual HashDigest End() = 0; + virtual ByteArray End() = 0; + + virtual unsigned int GetDigestLength() const = 0; + virtual const char* GetHashName() const = 0; AbstractHash& operator=(const AbstractHash&) = delete; AbstractHash& operator=(AbstractHash&&) = default; + + static std::unique_ptr Get(HashType hash); }; } diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index b91250049..5670b57d6 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -8,15 +8,24 @@ #define NAZARA_ALGORITHM_CORE_HPP #include +#include #include #include namespace Nz { + class AbstractHash; + class ByteArray; + template auto Apply(F&& fn, Tuple&& t); template auto Apply(O& object, F&& fn, Tuple&& t); + template ByteArray ComputeHash(HashType hash, const T& v); + template ByteArray ComputeHash(AbstractHash* hash, const T& v); template void HashCombine(std::size_t& seed, const T& v); + template + struct Hashable; + template struct TypeTag {}; } diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index b01c1e176..25e4ecdb2 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -6,6 +6,7 @@ // Merci à Ryan "FullMetal Alchemist" Lahfa // Merci aussi à Freedom de siteduzero.com +#include #include namespace Nz @@ -41,6 +42,21 @@ namespace Nz return Detail::ApplyImplMethod(object, std::forward(fn), std::forward(t), std::make_index_sequence()); } + + template + ByteArray ComputeHash(HashType hash, const T& v) + { + return ComputeHash(AbstractHash::Get(hash).get(), v); + } + + template + ByteArray ComputeHash(AbstractHash* hash, const T& v) + { + hash->Begin(); + Hashable()(v, hash); + return hash->End(); + } + // Algorithme venant de CityHash par Google // http://stackoverflow.com/questions/8513911/how-to-create-a-good-hash-combine-with-64-bit-output-inspired-by-boosthash-co template diff --git a/include/Nazara/Core/ByteArray.hpp b/include/Nazara/Core/ByteArray.hpp index 926c53fd1..8be45779b 100644 --- a/include/Nazara/Core/ByteArray.hpp +++ b/include/Nazara/Core/ByteArray.hpp @@ -8,8 +8,6 @@ #define NAZARA_BYTEARRAY_HPP #include -#include -#include #include #include @@ -17,7 +15,7 @@ namespace Nz { class AbstractHash; - class NAZARA_CORE_API ByteArray : public Hashable + class NAZARA_CORE_API ByteArray { using Container = std::vector; @@ -90,6 +88,7 @@ namespace Nz inline void ShrinkToFit(); inline void Swap(ByteArray& other); + inline String ToHex() const; inline String ToString() const; // STL interface @@ -109,6 +108,8 @@ namespace Nz inline size_type size() const noexcept; // Operators + NAZARA_CORE_API friend std::ostream& operator<<(std::ostream& out, const Nz::ByteArray& byteArray); + inline reference operator[](size_type pos); inline const_reference operator[](size_type pos) const; inline ByteArray& operator=(const ByteArray& array) = default; @@ -124,13 +125,12 @@ namespace Nz inline bool operator>=(const ByteArray& rhs) const; private: - bool FillHash(AbstractHash* hash) const; - Container m_array; }; -} -NAZARA_CORE_API std::ostream& operator<<(std::ostream& out, const Nz::ByteArray& byteArray); + template<> + struct Hashable; +} namespace std { diff --git a/include/Nazara/Core/ByteArray.inl b/include/Nazara/Core/ByteArray.inl index 25d90c7eb..1542ce991 100644 --- a/include/Nazara/Core/ByteArray.inl +++ b/include/Nazara/Core/ByteArray.inl @@ -193,6 +193,17 @@ namespace Nz m_array.swap(other.m_array); } + inline String ByteArray::ToHex() const + { + unsigned int length = m_array.size() * 2; + + String hexOutput(length, '\0'); + for (unsigned int i = 0; i < m_array.size(); ++i) + std::sprintf(&hexOutput[i * 2], "%02x", m_array[i]); + + return hexOutput; + } + inline String ByteArray::ToString() const { return String(reinterpret_cast(GetConstBuffer()), GetSize()); @@ -321,6 +332,16 @@ namespace Nz { return m_array >= rhs.m_array; } + + template<> + struct Hashable + { + bool operator()(const ByteArray& byteArray, AbstractHash* hash) const + { + hash->Append(byteArray.GetConstBuffer(), byteArray.GetSize()); + return true; + } + }; } namespace std diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index d73c27823..8f8f6bc94 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include #include @@ -28,7 +26,7 @@ namespace Nz { class FileImpl; - class NAZARA_CORE_API File : public Hashable, public InputStream + class NAZARA_CORE_API File : public InputStream { public: File(); @@ -83,6 +81,8 @@ namespace Nz File& operator=(File&& file) noexcept; static String AbsolutePath(const String& filePath); + static inline ByteArray ComputeHash(HashType hash, const String& filePath); + static inline ByteArray ComputeHash(AbstractHash* hash, const String& filePath); static bool Copy(const String& sourcePath, const String& targetPath); static bool Delete(const String& filePath); static bool Exists(const String& filePath); @@ -90,8 +90,6 @@ namespace Nz static String GetDirectory(const String& filePath); static time_t GetLastAccessTime(const String& filePath); static time_t GetLastWriteTime(const String& filePath); - static HashDigest GetHash(const String& filePath, HashType hash); - static HashDigest GetHash(const String& filePath, AbstractHash* hash); static UInt64 GetSize(const String& filePath); static bool IsAbsolute(const String& filePath); static String NormalizePath(const String& filePath); @@ -99,8 +97,6 @@ namespace Nz static bool Rename(const String& sourcePath, const String& targetPath); private: - bool FillHash(AbstractHash* hash) const; - NazaraMutexAttrib(m_mutex, mutable) Endianness m_endianness; @@ -108,6 +104,11 @@ namespace Nz FileImpl* m_impl; unsigned int m_openMode; }; + + template<> + struct Hashable; } +#include + #endif // NAZARA_FILE_HPP diff --git a/include/Nazara/Core/File.inl b/include/Nazara/Core/File.inl new file mode 100644 index 000000000..c5603c320 --- /dev/null +++ b/include/Nazara/Core/File.inl @@ -0,0 +1,56 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + inline ByteArray File::ComputeHash(HashType hash, const String& filePath) + { + return ComputeHash(AbstractHash::Get(hash).get(), filePath); + } + + inline ByteArray File::ComputeHash(AbstractHash* hash, const String& filePath) + { + return Nz::ComputeHash(hash, File(filePath)); + } + + template<> + struct Hashable + { + bool operator()(const Nz::File& originalFile, AbstractHash* hash) const + { + + File file(originalFile.GetPath()); + if (!file.Open(OpenMode_ReadOnly)) + { + NazaraError("Unable to open file"); + return false; + } + + UInt64 remainingSize = file.GetSize(); + + char buffer[NAZARA_CORE_FILE_BUFFERSIZE]; + while (remainingSize > 0) + { + unsigned int size = static_cast(std::min(remainingSize, static_cast(NAZARA_CORE_FILE_BUFFERSIZE))); + if (file.Read(&buffer[0], sizeof(char), size) != sizeof(char)*size) + { + NazaraError("Unable to read file"); + return false; + } + + remainingSize -= size; + hash->Append(reinterpret_cast(&buffer[0]), size); + } + + return true; + } + }; +} + +#include diff --git a/include/Nazara/Core/Hash.hpp b/include/Nazara/Core/Hash.hpp deleted file mode 100644 index a9a152a2b..000000000 --- a/include/Nazara/Core/Hash.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_HASH_HPP -#define NAZARA_HASH_HPP - -#include -#include -#include -#include - -namespace Nz -{ - class NAZARA_CORE_API Hash - { - public: - Hash(HashType hash); - Hash(AbstractHash* hashImpl); - Hash(const Hash&) = delete; - Hash(Hash&&) = delete; ///TODO - ~Hash(); - - HashDigest Process(const Hashable& hashable); - - Hash& operator=(const Hash&) = delete; - Hash& operator=(Hash&&) = delete; ///TODO - - private: - AbstractHash* m_impl; - }; -} - -#endif // NAZARA_HASH_HPP diff --git a/include/Nazara/Core/Hash/CRC32.hpp b/include/Nazara/Core/Hash/CRC32.hpp index 602432897..1898ffae4 100644 --- a/include/Nazara/Core/Hash/CRC32.hpp +++ b/include/Nazara/Core/Hash/CRC32.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include namespace Nz { @@ -21,12 +21,12 @@ namespace Nz HashCRC32(UInt32 polynomial = 0x04c11db7); virtual ~HashCRC32(); - void Append(const UInt8* data, unsigned int len); - void Begin(); - HashDigest End(); + void Append(const UInt8* data, unsigned int len) override; + void Begin() override; + ByteArray End() override; - static unsigned int GetDigestLength(); - static String GetHashName(); + unsigned int GetDigestLength() const override; + const char* GetHashName() const override; private: HashCRC32_state* m_state; diff --git a/include/Nazara/Core/Hash/Fletcher16.hpp b/include/Nazara/Core/Hash/Fletcher16.hpp index de84ecfeb..a4e296f38 100644 --- a/include/Nazara/Core/Hash/Fletcher16.hpp +++ b/include/Nazara/Core/Hash/Fletcher16.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include namespace Nz @@ -22,12 +22,12 @@ namespace Nz HashFletcher16(); virtual ~HashFletcher16(); - void Append(const UInt8* data, unsigned int len); - void Begin(); - HashDigest End(); + void Append(const UInt8* data, unsigned int len) override; + void Begin() override; + ByteArray End() override; - static unsigned int GetDigestLength(); - static String GetHashName(); + unsigned int GetDigestLength() const override; + const char* GetHashName() const override; private: HashFletcher16_state* m_state; diff --git a/include/Nazara/Core/Hash/MD5.hpp b/include/Nazara/Core/Hash/MD5.hpp index b3723c7ed..20fee5e38 100644 --- a/include/Nazara/Core/Hash/MD5.hpp +++ b/include/Nazara/Core/Hash/MD5.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include namespace Nz { @@ -21,12 +21,12 @@ namespace Nz HashMD5(); virtual ~HashMD5(); - void Append(const UInt8* data, unsigned int len); - void Begin(); - HashDigest End(); + void Append(const UInt8* data, unsigned int len) override; + void Begin() override; + ByteArray End() override; - static unsigned int GetDigestLength(); - static String GetHashName(); + unsigned int GetDigestLength() const override; + const char* GetHashName() const override; private: HashMD5_state* m_state; diff --git a/include/Nazara/Core/Hash/SHA1.hpp b/include/Nazara/Core/Hash/SHA1.hpp index abce7daee..4f80d3ca1 100644 --- a/include/Nazara/Core/Hash/SHA1.hpp +++ b/include/Nazara/Core/Hash/SHA1.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include namespace Nz { @@ -21,12 +21,12 @@ namespace Nz HashSHA1(); virtual ~HashSHA1(); - void Append(const UInt8* data, unsigned int len); - void Begin(); - HashDigest End(); + void Append(const UInt8* data, unsigned int len) override; + void Begin() override; + ByteArray End() override; - static unsigned int GetDigestLength(); - static String GetHashName(); + unsigned int GetDigestLength() const override; + const char* GetHashName() const override; private: SHA_CTX* m_state; diff --git a/include/Nazara/Core/Hash/SHA224.hpp b/include/Nazara/Core/Hash/SHA224.hpp index f6f30da1c..9d97e3193 100644 --- a/include/Nazara/Core/Hash/SHA224.hpp +++ b/include/Nazara/Core/Hash/SHA224.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include namespace Nz { @@ -21,12 +21,12 @@ namespace Nz HashSHA224(); virtual ~HashSHA224(); - void Append(const UInt8* data, unsigned int len); - void Begin(); - HashDigest End(); + void Append(const UInt8* data, unsigned int len) override; + void Begin() override; + ByteArray End() override; - static unsigned int GetDigestLength(); - static String GetHashName(); + unsigned int GetDigestLength() const override; + const char* GetHashName() const override; private: SHA_CTX* m_state; diff --git a/include/Nazara/Core/Hash/SHA256.hpp b/include/Nazara/Core/Hash/SHA256.hpp index 7d7b672af..5398f363b 100644 --- a/include/Nazara/Core/Hash/SHA256.hpp +++ b/include/Nazara/Core/Hash/SHA256.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include namespace Nz { @@ -21,12 +21,12 @@ namespace Nz HashSHA256(); virtual ~HashSHA256(); - void Append(const UInt8* data, unsigned int len); - void Begin(); - HashDigest End(); + void Append(const UInt8* data, unsigned int len) override; + void Begin() override; + ByteArray End() override; - static unsigned int GetDigestLength(); - static String GetHashName(); + unsigned int GetDigestLength() const override; + const char* GetHashName() const override; private: SHA_CTX* m_state; diff --git a/include/Nazara/Core/Hash/SHA384.hpp b/include/Nazara/Core/Hash/SHA384.hpp index 8c03cac90..a84fc8a4e 100644 --- a/include/Nazara/Core/Hash/SHA384.hpp +++ b/include/Nazara/Core/Hash/SHA384.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include namespace Nz { @@ -21,12 +21,12 @@ namespace Nz HashSHA384(); virtual ~HashSHA384(); - void Append(const UInt8* data, unsigned int len); - void Begin(); - HashDigest End(); + void Append(const UInt8* data, unsigned int len) override; + void Begin() override; + ByteArray End() override; - static unsigned int GetDigestLength(); - static String GetHashName(); + unsigned int GetDigestLength() const override; + const char* GetHashName() const override; private: SHA_CTX* m_state; diff --git a/include/Nazara/Core/Hash/SHA512.hpp b/include/Nazara/Core/Hash/SHA512.hpp index 799022266..7a49aaf72 100644 --- a/include/Nazara/Core/Hash/SHA512.hpp +++ b/include/Nazara/Core/Hash/SHA512.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include namespace Nz { @@ -21,12 +21,12 @@ namespace Nz HashSHA512(); virtual ~HashSHA512(); - void Append(const UInt8* data, unsigned int len); - void Begin(); - HashDigest End(); + void Append(const UInt8* data, unsigned int len) override; + void Begin() override; + ByteArray End() override; - static unsigned int GetDigestLength(); - static String GetHashName(); + unsigned int GetDigestLength() const override; + const char* GetHashName() const override; private: SHA_CTX* m_state; diff --git a/include/Nazara/Core/Hash/Whirlpool.hpp b/include/Nazara/Core/Hash/Whirlpool.hpp index 9d49a5ecf..0da68015a 100644 --- a/include/Nazara/Core/Hash/Whirlpool.hpp +++ b/include/Nazara/Core/Hash/Whirlpool.hpp @@ -7,7 +7,7 @@ #include #include -#include +#include namespace Nz { @@ -19,12 +19,12 @@ namespace Nz HashWhirlpool(); virtual ~HashWhirlpool(); - void Append(const UInt8* data, unsigned int len); - void Begin(); - HashDigest End(); + void Append(const UInt8* data, unsigned int len) override; + void Begin() override; + ByteArray End() override; - static unsigned int GetDigestLength(); - static String GetHashName(); + unsigned int GetDigestLength() const; + const char* GetHashName() const; private: HashWhirlpool_state* m_state; diff --git a/include/Nazara/Core/HashDigest.hpp b/include/Nazara/Core/HashDigest.hpp deleted file mode 100644 index 902104de1..000000000 --- a/include/Nazara/Core/HashDigest.hpp +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_HASHDIGEST_HPP -#define NAZARA_HASHDIGEST_HPP - -///TODO: Remplacer par ByteArray - -#include -#include -#include - -namespace Nz -{ - class NAZARA_CORE_API HashDigest - { - public: - HashDigest(); - HashDigest(const String& hashName, const UInt8* digest, unsigned int length); - HashDigest(const HashDigest& rhs); - HashDigest(HashDigest&& rhs) noexcept; - ~HashDigest(); - - bool IsValid() const; - - const UInt8* GetDigest() const; - unsigned int GetDigestLength() const; - String GetHashName() const; - - String ToHex() const; - - UInt8 operator[](unsigned int pos) const; - - HashDigest& operator=(const HashDigest& rhs); - HashDigest& operator=(HashDigest&& rhs) noexcept; - - bool operator==(const HashDigest& rhs) const; - bool operator!=(const HashDigest& rhs) const; - bool operator<(const HashDigest& rhs) const; - bool operator<=(const HashDigest& rhs) const; - bool operator>(const HashDigest& rhs) const; - bool operator>=(const HashDigest& rhs) const; - - NAZARA_CORE_API friend std::ostream& operator<<(std::ostream& out, const HashDigest& string); - - private: - String m_hashName; - UInt8* m_digest; - unsigned int m_digestLength; - }; -} - -#endif // NAZARA_HASHDIGEST_HPP diff --git a/include/Nazara/Core/Hashable.hpp b/include/Nazara/Core/Hashable.hpp deleted file mode 100644 index 3c79b319f..000000000 --- a/include/Nazara/Core/Hashable.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef HASHABLE_HPP_INCLUDED -#define HASHABLE_HPP_INCLUDED - -#include -#include - -namespace Nz -{ - class AbstractHash; - class HashDigest; - - class NAZARA_CORE_API Hashable - { - friend class Hash; - - public: - Hashable() = default; - Hashable(const Hashable&) = default; - Hashable(Hashable&&) = default; - virtual ~Hashable(); - - HashDigest GetHash(HashType hash) const; - HashDigest GetHash(AbstractHash* impl) const; - - Hashable& operator=(const Hashable&) = default; - Hashable& operator=(Hashable&&) = default; - - private: - virtual bool FillHash(AbstractHash* impl) const = 0; - }; -} - -#endif // HASHABLE_HPP_INCLUDED diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index c7cc5418a..61af938d1 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -8,7 +8,7 @@ #define NAZARA_STRING_HPP #include -#include +#include #include #include #include @@ -20,7 +20,7 @@ namespace Nz class AbstractHash; class HashDigest; - class NAZARA_CORE_API String : public Hashable + class NAZARA_CORE_API String { public: enum Flags @@ -306,7 +306,6 @@ namespace Nz String(std::shared_ptr&& sharedString); void EnsureOwnership(bool discardContent = false); - bool FillHash(AbstractHash* hash) const; inline void ReleaseString(); static const std::shared_ptr& GetEmptyString(); @@ -324,6 +323,9 @@ namespace Nz std::unique_ptr string; }; }; + + template<> + struct Hashable; } namespace std @@ -331,6 +333,9 @@ namespace std NAZARA_CORE_API istream& getline(istream& is, Nz::String& str); NAZARA_CORE_API istream& getline(istream& is, Nz::String& str, char delim); NAZARA_CORE_API void swap(Nz::String& lhs, Nz::String& rhs); + + template<> + struct hash; } #include diff --git a/include/Nazara/Core/String.inl b/include/Nazara/Core/String.inl index 49157777f..cc323d697 100644 --- a/include/Nazara/Core/String.inl +++ b/include/Nazara/Core/String.inl @@ -2,6 +2,7 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include namespace Nz @@ -37,6 +38,16 @@ namespace Nz { string[strSize] = '\0'; } + + template<> + struct Hashable + { + bool operator()(const String& str, AbstractHash* hash) const + { + hash->Append(reinterpret_cast(str.GetConstBuffer()), str.GetSize()); + return true; + } + }; } namespace std diff --git a/src/Nazara/Core/AbstractHash.cpp b/src/Nazara/Core/AbstractHash.cpp index c9d6fa517..f0e82bb19 100644 --- a/src/Nazara/Core/AbstractHash.cpp +++ b/src/Nazara/Core/AbstractHash.cpp @@ -3,9 +3,57 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include namespace Nz { AbstractHash::~AbstractHash() = default; + + std::unique_ptr AbstractHash::Get(HashType type) + { + NazaraAssert(type <= HashType_Max, "Hash type value out of enum"); + + switch (type) + { + case HashType_Fletcher16: + return std::unique_ptr(new HashFletcher16); + + case HashType_CRC32: + return std::unique_ptr(new HashCRC32); + + case HashType_MD5: + return std::unique_ptr(new HashMD5); + + case HashType_SHA1: + return std::unique_ptr(new HashSHA1); + + case HashType_SHA224: + return std::unique_ptr(new HashSHA224); + + case HashType_SHA256: + return std::unique_ptr(new HashSHA256); + + case HashType_SHA384: + return std::unique_ptr(new HashSHA384); + + case HashType_SHA512: + return std::unique_ptr(new HashSHA512); + + case HashType_Whirlpool: + return std::unique_ptr(new HashWhirlpool); + } + + NazaraInternalError("Hash type not handled (0x" + String::Number(type, 16) + ')'); + return std::unique_ptr(); + } } diff --git a/src/Nazara/Core/ByteArray.cpp b/src/Nazara/Core/ByteArray.cpp index 33b53913b..cc5734822 100644 --- a/src/Nazara/Core/ByteArray.cpp +++ b/src/Nazara/Core/ByteArray.cpp @@ -9,16 +9,9 @@ namespace Nz { - std::ostream& operator<<(std::ostream& out, const ByteArray& byteArray) + std::ostream& operator<<(std::ostream& out, const Nz::ByteArray& byteArray) { - out << byteArray.ToString(); + out << byteArray.ToHex(); return out; } - - bool ByteArray::FillHash(AbstractHash* hash) const - { - hash->Append(GetConstBuffer(), GetSize()); - - return true; - } } diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 2a72262bb..9c83b708d 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -7,7 +7,6 @@ #include #include #include -#include #include #include #include @@ -631,22 +630,6 @@ namespace Nz return FileImpl::GetLastWriteTime(NormalizePath(filePath)); } - HashDigest File::GetHash(const String& filePath, HashType hash) - { - File file(filePath); - - Hash h(hash); - return h.Process(file); - } - - HashDigest File::GetHash(const String& filePath, AbstractHash* hash) - { - File file(filePath); - - Hash h(hash); - return h.Process(file); - } - UInt64 File::GetSize(const String& filePath) { if (filePath.IsEmpty()) @@ -714,32 +697,4 @@ namespace Nz return FileImpl::Rename(NormalizePath(sourcePath), NormalizePath(targetPath)); } - - bool File::FillHash(AbstractHash* hash) const - { - File file(m_filePath); - if (!file.Open(OpenMode_ReadOnly)) - { - NazaraError("Unable to open file"); - return false; - } - - UInt64 remainingSize = file.GetSize(); - - char buffer[NAZARA_CORE_FILE_BUFFERSIZE]; - while (remainingSize > 0) - { - unsigned int size = static_cast(std::min(remainingSize, static_cast(NAZARA_CORE_FILE_BUFFERSIZE))); - if (file.Read(&buffer[0], sizeof(char), size) != sizeof(char)*size) - { - NazaraError("Unable to read file"); - return false; - } - - remainingSize -= size; - hash->Append(reinterpret_cast(&buffer[0]), size); - } - - return true; - } // Fermeture automatique du fichier } diff --git a/src/Nazara/Core/Hash.cpp b/src/Nazara/Core/Hash.cpp deleted file mode 100644 index 04043589a..000000000 --- a/src/Nazara/Core/Hash.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace Nz -{ - Hash::Hash(HashType hash) - { - switch (hash) - { - case HashType_Fletcher16: - m_impl = new HashFletcher16; - break; - - case HashType_CRC32: - m_impl = new HashCRC32; - break; - - case HashType_MD5: - m_impl = new HashMD5; - break; - - case HashType_SHA1: - m_impl = new HashSHA1; - break; - - case HashType_SHA224: - m_impl = new HashSHA224; - break; - - case HashType_SHA256: - m_impl = new HashSHA256; - break; - - case HashType_SHA384: - m_impl = new HashSHA384; - break; - - case HashType_SHA512: - m_impl = new HashSHA512; - break; - - case HashType_Whirlpool: - m_impl = new HashWhirlpool; - break; - } - } - - Hash::Hash(AbstractHash* hashImpl) : - m_impl(hashImpl) - { - } - - Hash::~Hash() - { - delete m_impl; - } - - HashDigest Hash::Process(const Hashable& hashable) - { - m_impl->Begin(); - if (hashable.FillHash(m_impl)) - return m_impl->End(); - else // Erreur - { - m_impl->End(); - - return HashDigest(); - } - } -} diff --git a/src/Nazara/Core/Hash/CRC32.cpp b/src/Nazara/Core/Hash/CRC32.cpp index 9459be37e..edf3ba8c2 100644 --- a/src/Nazara/Core/Hash/CRC32.cpp +++ b/src/Nazara/Core/Hash/CRC32.cpp @@ -109,7 +109,7 @@ namespace Nz m_state->crc = 0xFFFFFFFF; } - HashDigest HashCRC32::End() + ByteArray HashCRC32::End() { m_state->crc ^= 0xFFFFFFFF; @@ -117,17 +117,16 @@ namespace Nz SwapBytes(&m_state->crc, sizeof(UInt32)); #endif - return HashDigest(GetHashName(), reinterpret_cast(&m_state->crc), 4); + return ByteArray(reinterpret_cast(&m_state->crc), 4); } - unsigned int HashCRC32::GetDigestLength() + unsigned int HashCRC32::GetDigestLength() const { return 4; } - String HashCRC32::GetHashName() + const char* HashCRC32::GetHashName() const { - static String hashName = "CRC32"; - return hashName; + return "CRC32"; } } diff --git a/src/Nazara/Core/Hash/Fletcher16.cpp b/src/Nazara/Core/Hash/Fletcher16.cpp index 66fbae2af..c4ab978e8 100644 --- a/src/Nazara/Core/Hash/Fletcher16.cpp +++ b/src/Nazara/Core/Hash/Fletcher16.cpp @@ -48,7 +48,7 @@ namespace Nz m_state->sum2 = 0xff; } - HashDigest HashFletcher16::End() + ByteArray HashFletcher16::End() { m_state->sum1 = (m_state->sum1 & 0xff) + (m_state->sum1 >> 8); m_state->sum2 = (m_state->sum2 & 0xff) + (m_state->sum2 >> 8); @@ -59,17 +59,16 @@ namespace Nz SwapBytes(&fletcher, sizeof(UInt32)); #endif - return HashDigest(GetHashName(), reinterpret_cast(&fletcher), 2); + return ByteArray(reinterpret_cast(&fletcher), 2); } - unsigned int HashFletcher16::GetDigestLength() + unsigned int HashFletcher16::GetDigestLength() const { return 2; } - String HashFletcher16::GetHashName() + const char* HashFletcher16::GetHashName() const { - static String hashName = "Fletcher16"; - return hashName; + return "Fletcher16"; } } diff --git a/src/Nazara/Core/Hash/MD5.cpp b/src/Nazara/Core/Hash/MD5.cpp index 93856c79d..127a1f8cb 100644 --- a/src/Nazara/Core/Hash/MD5.cpp +++ b/src/Nazara/Core/Hash/MD5.cpp @@ -325,7 +325,7 @@ namespace Nz m_state->abcd[3] = 0x10325476; } - HashDigest HashMD5::End() + ByteArray HashMD5::End() { static const unsigned char pad[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -349,17 +349,16 @@ namespace Nz for (i = 0; i < 16; ++i) digest[i] = static_cast(m_state->abcd[i >> 2] >> ((i & 3) << 3)); - return HashDigest(GetHashName(), &digest[0], 16); + return ByteArray(&digest[0], 16); } - unsigned int HashMD5::GetDigestLength() + unsigned int HashMD5::GetDigestLength() const { return 16; } - String HashMD5::GetHashName() + const char* HashMD5::GetHashName() const { - static String hashName = "MD5"; - return hashName; + return "MD5"; } } diff --git a/src/Nazara/Core/Hash/SHA1.cpp b/src/Nazara/Core/Hash/SHA1.cpp index 8b1725fcb..1ed49e69c 100644 --- a/src/Nazara/Core/Hash/SHA1.cpp +++ b/src/Nazara/Core/Hash/SHA1.cpp @@ -28,23 +28,22 @@ namespace Nz SHA1_Init(m_state); } - HashDigest HashSHA1::End() + ByteArray HashSHA1::End() { UInt8 digest[SHA1_DIGEST_LENGTH]; SHA1_End(m_state, digest); - return HashDigest(GetHashName(), digest, SHA1_DIGEST_LENGTH); + return ByteArray(digest, SHA1_DIGEST_LENGTH); } - unsigned int HashSHA1::GetDigestLength() + unsigned int HashSHA1::GetDigestLength() const { return SHA1_DIGEST_LENGTH; } - String HashSHA1::GetHashName() + const char* HashSHA1::GetHashName() const { - static String hashName = "SHA1"; - return hashName; + return "SHA1"; } } diff --git a/src/Nazara/Core/Hash/SHA224.cpp b/src/Nazara/Core/Hash/SHA224.cpp index ab836e597..57b95e965 100644 --- a/src/Nazara/Core/Hash/SHA224.cpp +++ b/src/Nazara/Core/Hash/SHA224.cpp @@ -28,23 +28,22 @@ namespace Nz SHA224_Init(m_state); } - HashDigest HashSHA224::End() + ByteArray HashSHA224::End() { UInt8 digest[SHA224_DIGEST_LENGTH]; SHA224_End(m_state, digest); - return HashDigest(GetHashName(), digest, SHA224_DIGEST_LENGTH); + return ByteArray(digest, SHA224_DIGEST_LENGTH); } - unsigned int HashSHA224::GetDigestLength() + unsigned int HashSHA224::GetDigestLength() const { return SHA224_DIGEST_LENGTH; } - String HashSHA224::GetHashName() + const char* HashSHA224::GetHashName() const { - static String hashName = "SHA224"; - return hashName; + return "SHA224"; } } diff --git a/src/Nazara/Core/Hash/SHA256.cpp b/src/Nazara/Core/Hash/SHA256.cpp index a42764e94..202820594 100644 --- a/src/Nazara/Core/Hash/SHA256.cpp +++ b/src/Nazara/Core/Hash/SHA256.cpp @@ -28,23 +28,22 @@ namespace Nz SHA256_Init(m_state); } - HashDigest HashSHA256::End() + ByteArray HashSHA256::End() { UInt8 digest[SHA256_DIGEST_LENGTH]; SHA256_End(m_state, digest); - return HashDigest(GetHashName(), digest, SHA256_DIGEST_LENGTH); + return ByteArray(digest, SHA256_DIGEST_LENGTH); } - unsigned int HashSHA256::GetDigestLength() + unsigned int HashSHA256::GetDigestLength() const { return SHA256_DIGEST_LENGTH; } - String HashSHA256::GetHashName() + const char* HashSHA256::GetHashName() const { - static String hashName = "SHA256"; - return hashName; + return "SHA256"; } } diff --git a/src/Nazara/Core/Hash/SHA384.cpp b/src/Nazara/Core/Hash/SHA384.cpp index a4aa25961..fe1498cbe 100644 --- a/src/Nazara/Core/Hash/SHA384.cpp +++ b/src/Nazara/Core/Hash/SHA384.cpp @@ -28,23 +28,22 @@ namespace Nz SHA384_Init(m_state); } - HashDigest HashSHA384::End() + ByteArray HashSHA384::End() { UInt8 digest[SHA384_DIGEST_LENGTH]; SHA384_End(m_state, digest); - return HashDigest(GetHashName(), digest, SHA384_DIGEST_LENGTH); + return ByteArray(digest, SHA384_DIGEST_LENGTH); } - unsigned int HashSHA384::GetDigestLength() + unsigned int HashSHA384::GetDigestLength() const { return SHA384_DIGEST_LENGTH; } - String HashSHA384::GetHashName() + const char* HashSHA384::GetHashName() const { - static String hashName = "SHA384"; - return hashName; + return "SHA384"; } } diff --git a/src/Nazara/Core/Hash/SHA512.cpp b/src/Nazara/Core/Hash/SHA512.cpp index f246ab0e8..562836998 100644 --- a/src/Nazara/Core/Hash/SHA512.cpp +++ b/src/Nazara/Core/Hash/SHA512.cpp @@ -28,23 +28,22 @@ namespace Nz SHA512_Init(m_state); } - HashDigest HashSHA512::End() + ByteArray HashSHA512::End() { UInt8 digest[SHA512_DIGEST_LENGTH]; SHA512_End(m_state, digest); - return HashDigest(GetHashName(), digest, SHA512_DIGEST_LENGTH); + return ByteArray(digest, SHA512_DIGEST_LENGTH); } - unsigned int HashSHA512::GetDigestLength() + unsigned int HashSHA512::GetDigestLength() const { return SHA512_DIGEST_LENGTH; } - String HashSHA512::GetHashName() + const char* HashSHA512::GetHashName() const { - static String hashName = "SHA512"; - return hashName; + return "SHA512"; } } diff --git a/src/Nazara/Core/Hash/Whirlpool.cpp b/src/Nazara/Core/Hash/Whirlpool.cpp index b734fdec9..9be283775 100644 --- a/src/Nazara/Core/Hash/Whirlpool.cpp +++ b/src/Nazara/Core/Hash/Whirlpool.cpp @@ -962,7 +962,7 @@ namespace Nz m_state->hash[i] = 0L; // initial value } - HashDigest HashWhirlpool::End() + ByteArray HashWhirlpool::End() { UInt8 result[64]; @@ -1012,17 +1012,16 @@ namespace Nz m_state->bufferBits = bufferBits; m_state->bufferPos = bufferPos; - return HashDigest(GetHashName(), &result[0], 64); + return ByteArray(&result[0], 64); } - unsigned int HashWhirlpool::GetDigestLength() + unsigned int HashWhirlpool::GetDigestLength() const { return 64; } - String HashWhirlpool::GetHashName() + const char* HashWhirlpool::GetHashName() const { - static String hashName = "Whirlpool"; - return hashName; + return "Whirlpool"; } } diff --git a/src/Nazara/Core/HashDigest.cpp b/src/Nazara/Core/HashDigest.cpp deleted file mode 100644 index 93c23f13c..000000000 --- a/src/Nazara/Core/HashDigest.cpp +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include -#include -#include - -namespace Nz -{ - HashDigest::HashDigest() : - m_digest(nullptr), - m_digestLength(0) - { - } - - HashDigest::HashDigest(const String& hashName, const UInt8* digest, unsigned int length) : - m_hashName(hashName), - m_digestLength(length) - { - if (m_digestLength > 0) - { - m_digest = new UInt8[length]; - std::memcpy(m_digest, digest, length); - } - else - m_digest = nullptr; - } - - HashDigest::HashDigest(const HashDigest& rhs) : - m_hashName(rhs.m_hashName), - m_digestLength(rhs.m_digestLength) - { - if (m_digestLength > 0) - { - m_digest = new UInt8[m_digestLength]; - std::memcpy(m_digest, rhs.m_digest, m_digestLength); - } - else - m_digest = nullptr; - } - - HashDigest::HashDigest(HashDigest&& rhs) noexcept : - m_hashName(std::move(rhs.m_hashName)), - m_digest(rhs.m_digest), - m_digestLength(rhs.m_digestLength) - { - rhs.m_digest = nullptr; - rhs.m_digestLength = 0; - } - - HashDigest::~HashDigest() - { - delete[] m_digest; - } - - bool HashDigest::IsValid() const - { - return m_digestLength > 0; - } - - const UInt8* HashDigest::GetDigest() const - { - return m_digest; - } - - unsigned int HashDigest::GetDigestLength() const - { - return m_digestLength; - } - - String HashDigest::GetHashName() const - { - return m_hashName; - } - - String HashDigest::ToHex() const - { - if (m_digestLength == 0) - return String(); - - unsigned int length = m_digestLength*2; - - String hexOutput(length); - for (unsigned int i = 0; i < m_digestLength; ++i) - std::sprintf(&hexOutput[i*2], "%02x", m_digest[i]); - - return hexOutput; - } - - UInt8 HashDigest::operator[](unsigned int pos) const - { - #if NAZARA_CORE_SAFE - if (pos >= m_digestLength) - { - NazaraError("Position out of range"); - return 0; - } - #endif - - return m_digest[pos]; - } - - HashDigest& HashDigest::operator=(const HashDigest& rhs) - { - if (this == &rhs) - return *this; - - m_hashName = rhs.m_hashName; - - m_digestLength = rhs.m_digestLength; - if (m_digestLength > 0) - { - m_digest = new UInt8[m_digestLength]; - std::memcpy(m_digest, rhs.m_digest, m_digestLength); - } - else - m_digest = nullptr; - - return *this; - } - - HashDigest& HashDigest::operator=(HashDigest&& rhs) noexcept - { - std::swap(m_hashName, rhs.m_hashName); - std::swap(m_digest, rhs.m_digest); - std::swap(m_digestLength, rhs.m_digestLength); - - return *this; - } - - bool HashDigest::operator==(const HashDigest& rhs) const - { - if (m_digest == nullptr || rhs.m_digest == nullptr) - return m_digest == rhs.m_digest; - - if (m_digestLength != rhs.m_digestLength) - return false; - - return m_hashName == rhs.m_hashName && std::memcmp(m_digest, rhs.m_digest, m_digestLength) == 0; - } - - bool HashDigest::operator!=(const HashDigest& rhs) const - { - return !operator==(rhs); - } - - bool HashDigest::operator<(const HashDigest& rhs) const - { - if (rhs.m_digest == nullptr) - return false; - - if (m_digest == nullptr) - return true; - - int cmp = String::Compare(m_hashName, rhs.m_hashName); - if (cmp == 0) - { - cmp = std::memcmp(m_digest, rhs.m_digest, std::min(m_digestLength, rhs.m_digestLength)); - - if (cmp == 0) - return m_digestLength < rhs.m_digestLength; - else - return cmp < 0; - } - else - return cmp < 0; - } - - bool HashDigest::operator<=(const HashDigest& rhs) const - { - return !rhs.operator<(*this); - } - - bool HashDigest::operator>(const HashDigest& rhs) const - { - return rhs.operator<(*this); - } - - bool HashDigest::operator>=(const HashDigest& rhs) const - { - return !operator<(rhs); - } -} - -std::ostream& operator<<(std::ostream& out, const Nz::HashDigest& hashstring) -{ - out << hashstring.ToHex(); - return out; -} diff --git a/src/Nazara/Core/Hashable.cpp b/src/Nazara/Core/Hashable.cpp deleted file mode 100644 index b3d594f10..000000000 --- a/src/Nazara/Core/Hashable.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include - -namespace Nz -{ - Hashable::~Hashable() = default; - - HashDigest Hashable::GetHash(HashType hash) const - { - Hash h(hash); - return h.Process(*this); - } - - HashDigest Hashable::GetHash(AbstractHash* impl) const - { - Hash h(impl); - return h.Process(*this); - } -} diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index d39f9adb1..cfddcf49d 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -5,7 +5,6 @@ ///TODO: Réécrire une bonne partie des algorithmes employés (Relu jusqu'à 3538) #include -#include #include #include #include @@ -4203,13 +4202,6 @@ namespace Nz } } - bool String::FillHash(AbstractHash* hash) const - { - hash->Append(reinterpret_cast(GetConstBuffer()), GetSize()); - - return true; - } - const std::shared_ptr& String::GetEmptyString() { static auto emptyString = std::make_shared(); From 9f7468d94072877e31eea3afd060ff834099489e Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 16 Nov 2015 14:05:04 +0100 Subject: [PATCH 56/97] Core/ByteArray: Fix missing include Former-commit-id: f1f90e4be3d7af42114f0bbe48e351584ab16e77 --- include/Nazara/Core/ByteArray.inl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/Nazara/Core/ByteArray.inl b/include/Nazara/Core/ByteArray.inl index 1542ce991..13c846c05 100644 --- a/include/Nazara/Core/ByteArray.inl +++ b/include/Nazara/Core/ByteArray.inl @@ -2,6 +2,8 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include + namespace Nz { inline ByteArray::ByteArray(size_type n) : From fb920f001699823d87593d1077fc57815e1d35c4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 17 Nov 2015 12:47:13 +0100 Subject: [PATCH 57/97] Core: Add OutputStream class Former-commit-id: a6b8f642e263833c75a338cc23266c94edbced6f --- include/Nazara/Core/File.hpp | 23 ++++++++-------- include/Nazara/Core/InputStream.hpp | 2 +- include/Nazara/Core/OutputStream.hpp | 28 +++++++++++++++++++ src/Nazara/Core/File.cpp | 31 +++++---------------- src/Nazara/Core/OutputStream.cpp | 40 ++++++++++++++++++++++++++++ src/Nazara/Core/String.cpp | 1 - 6 files changed, 88 insertions(+), 37 deletions(-) create mode 100644 include/Nazara/Core/OutputStream.hpp create mode 100644 src/Nazara/Core/OutputStream.cpp diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index 8f8f6bc94..a01433be2 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_FILE @@ -26,7 +27,7 @@ namespace Nz { class FileImpl; - class NAZARA_CORE_API File : public InputStream + class NAZARA_CORE_API File : public InputStream, public OutputStream { public: File(); @@ -42,38 +43,38 @@ namespace Nz bool Delete(); bool EndOfFile() const; - bool EndOfStream() const; + bool EndOfStream() const override; bool Exists() const; - void Flush(); + void Flush() override; time_t GetCreationTime() const; - UInt64 GetCursorPos() const; - String GetDirectory() const; + UInt64 GetCursorPos() const override; + String GetDirectory() const override; String GetFileName() const; time_t GetLastAccessTime() const; time_t GetLastWriteTime() const; - String GetPath() const; - UInt64 GetSize() const; + String GetPath() const override; + UInt64 GetSize() const override; bool IsOpen() const; bool Open(unsigned int openMode = OpenMode_Current); bool Open(const String& filePath, unsigned int openMode = OpenMode_Current); - std::size_t Read(void* buffer, std::size_t size); + std::size_t Read(void* buffer, std::size_t size) override; std::size_t Read(void* buffer, std::size_t typeSize, unsigned int count); bool Rename(const String& newFilePath); bool SetCursorPos(CursorPosition pos, Int64 offset = 0); - bool SetCursorPos(UInt64 offset); + bool SetCursorPos(UInt64 offset) override; void SetEndianness(Endianness endianness); bool SetFile(const String& filePath); bool SetOpenMode(unsigned int openMode); - bool Write(const Nz::ByteArray& byteArray); - bool Write(const String& string); + using OutputStream::Write; + std::size_t Write(const void* buffer, std::size_t size) override; std::size_t Write(const void* buffer, std::size_t typeSize, unsigned int count); File& operator=(const String& filePath); diff --git a/include/Nazara/Core/InputStream.hpp b/include/Nazara/Core/InputStream.hpp index 1aea60cd8..17539aaa1 100644 --- a/include/Nazara/Core/InputStream.hpp +++ b/include/Nazara/Core/InputStream.hpp @@ -12,7 +12,7 @@ namespace Nz { - class NAZARA_CORE_API InputStream : public Stream + class NAZARA_CORE_API InputStream : public virtual Stream { public: virtual ~InputStream(); diff --git a/include/Nazara/Core/OutputStream.hpp b/include/Nazara/Core/OutputStream.hpp new file mode 100644 index 000000000..70d7ef40c --- /dev/null +++ b/include/Nazara/Core/OutputStream.hpp @@ -0,0 +1,28 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_OUTPUTSTREAM_HPP +#define NAZARA_OUTPUTSTREAM_HPP + +#include +#include + +namespace Nz +{ + class NAZARA_CORE_API OutputStream : public virtual Stream + { + public: + virtual ~OutputStream(); + + virtual void Flush() = 0; + + bool Write(const ByteArray& byteArray); + bool Write(const String& string); + virtual std::size_t Write(const void* buffer, std::size_t size) = 0; + }; +} + +#endif // NAZARA_OUTPUTSTREAM_HPP diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 9c83b708d..977b0353f 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -416,33 +416,16 @@ namespace Nz return true; } - bool File::Write(const ByteArray& byteArray) + std::size_t File::Write(const void* buffer, std::size_t size) { - ByteArray::size_type size = byteArray.GetSize(); - return Write(byteArray.GetConstBuffer(), 1, size) == size; - } + NazaraAssert(IsOpen(), "File is not open"); + NazaraAssert(m_openMode & OpenMode_ReadWrite || m_openMode & OpenMode_WriteOnly, "File not opened with write access"); + NazaraLock(m_mutex) - bool File::Write(const String& string) - { - String temp(string); + if (!buffer || size == 0) + return 0; - if (m_streamOptions & StreamOption_Text) - { - #if defined(NAZARA_PLATFORM_WINDOWS) - temp.Replace("\n", "\r\n"); - #elif defined(NAZARA_PLATFORM_LINUX) - // Rien à faire - #elif defined(NAZARA_PLATFORM_MACOS) - temp.Replace('\n', '\r'); - #else - #error OS not handled - #endif - } - - unsigned int size = temp.GetSize(); - std::size_t bytesWritten = Write(temp.GetBuffer(), sizeof(char), size); - - return bytesWritten == size*sizeof(char); + return m_impl->Write(buffer, size); } std::size_t File::Write(const void* buffer, std::size_t typeSize, unsigned int count) diff --git a/src/Nazara/Core/OutputStream.cpp b/src/Nazara/Core/OutputStream.cpp new file mode 100644 index 000000000..b9bc8a420 --- /dev/null +++ b/src/Nazara/Core/OutputStream.cpp @@ -0,0 +1,40 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include +#include +#include + +namespace Nz +{ + OutputStream::~OutputStream() = default; + + bool OutputStream::Write(const ByteArray& byteArray) + { + ByteArray::size_type size = byteArray.GetSize(); + return Write(byteArray.GetConstBuffer(), size) == size; + } + + bool OutputStream::Write(const String& string) + { + String temp(string); + + if (m_streamOptions & StreamOption_Text) + { + #if defined(NAZARA_PLATFORM_WINDOWS) + temp.Replace("\n", "\r\n"); + #elif defined(NAZARA_PLATFORM_LINUX) + // Nothing to do + #elif defined(NAZARA_PLATFORM_MACOS) + temp.Replace('\n', '\r'); + #endif + } + + std::size_t size = temp.GetSize(); + return Write(temp.GetConstBuffer(), size) == size; + } +} diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index cfddcf49d..d5230577a 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -4205,7 +4205,6 @@ namespace Nz const std::shared_ptr& String::GetEmptyString() { static auto emptyString = std::make_shared(); - return emptyString; } From 8371ce068f0109c05717c4087741523f89e3e096 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 17 Nov 2015 13:19:44 +0100 Subject: [PATCH 58/97] Core: Update Stream interface Add Open Mode to Stream level, Add IsReadable() and IsWritable() Former-commit-id: 0da5fa798c0f3bd3bf1545cb57f6bc923b222de8 --- include/Nazara/Core/File.hpp | 6 +- include/Nazara/Core/InputStream.hpp | 5 ++ include/Nazara/Core/InputStream.inl | 11 +++ include/Nazara/Core/OutputStream.hpp | 5 ++ include/Nazara/Core/OutputStream.inl | 11 +++ include/Nazara/Core/Stream.hpp | 16 +++-- include/Nazara/Core/Stream.inl | 37 ++++++++++ src/Nazara/Core/File.cpp | 103 ++++++--------------------- src/Nazara/Core/MemoryStream.cpp | 1 + src/Nazara/Core/Posix/FileImpl.cpp | 5 +- src/Nazara/Core/Posix/FileImpl.hpp | 2 +- src/Nazara/Core/Stream.cpp | 10 --- src/Nazara/Core/Win32/FileImpl.cpp | 2 +- src/Nazara/Core/Win32/FileImpl.hpp | 2 +- 14 files changed, 114 insertions(+), 102 deletions(-) create mode 100644 include/Nazara/Core/InputStream.inl create mode 100644 include/Nazara/Core/OutputStream.inl create mode 100644 include/Nazara/Core/Stream.inl diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index a01433be2..d6a819c9f 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -32,7 +32,7 @@ namespace Nz public: File(); File(const String& filePath); - File(const String& filePath, unsigned int openMode); + File(const String& filePath, UInt32 openMode); File(const File&) = delete; File(File&& file) noexcept; ~File(); @@ -71,7 +71,7 @@ namespace Nz bool SetCursorPos(UInt64 offset) override; void SetEndianness(Endianness endianness); bool SetFile(const String& filePath); - bool SetOpenMode(unsigned int openMode); + bool SetOpenMode(UInt32 openMode); using OutputStream::Write; std::size_t Write(const void* buffer, std::size_t size) override; @@ -102,8 +102,8 @@ namespace Nz Endianness m_endianness; String m_filePath; + UInt32 m_openMode; FileImpl* m_impl; - unsigned int m_openMode; }; template<> diff --git a/include/Nazara/Core/InputStream.hpp b/include/Nazara/Core/InputStream.hpp index 17539aaa1..ec67be839 100644 --- a/include/Nazara/Core/InputStream.hpp +++ b/include/Nazara/Core/InputStream.hpp @@ -23,7 +23,12 @@ namespace Nz virtual std::size_t Read(void* buffer, std::size_t size) = 0; virtual String ReadLine(unsigned int lineSize = 0); + + protected: + inline InputStream(); }; } +#include + #endif // NAZARA_INPUTSTREAM_HPP diff --git a/include/Nazara/Core/InputStream.inl b/include/Nazara/Core/InputStream.inl new file mode 100644 index 000000000..35912da00 --- /dev/null +++ b/include/Nazara/Core/InputStream.inl @@ -0,0 +1,11 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +namespace Nz +{ + inline InputStream::InputStream() : + Stream(OpenMode_Current) + { + } +} diff --git a/include/Nazara/Core/OutputStream.hpp b/include/Nazara/Core/OutputStream.hpp index 70d7ef40c..363270ea5 100644 --- a/include/Nazara/Core/OutputStream.hpp +++ b/include/Nazara/Core/OutputStream.hpp @@ -22,7 +22,12 @@ namespace Nz bool Write(const ByteArray& byteArray); bool Write(const String& string); virtual std::size_t Write(const void* buffer, std::size_t size) = 0; + + protected: + inline OutputStream(); }; } +#include + #endif // NAZARA_OUTPUTSTREAM_HPP diff --git a/include/Nazara/Core/OutputStream.inl b/include/Nazara/Core/OutputStream.inl new file mode 100644 index 000000000..51766a889 --- /dev/null +++ b/include/Nazara/Core/OutputStream.inl @@ -0,0 +1,11 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +namespace Nz +{ + inline OutputStream::OutputStream() : + Stream(OpenMode_Current) + { + } +} diff --git a/include/Nazara/Core/Stream.hpp b/include/Nazara/Core/Stream.hpp index 11154cb4d..a00c09661 100644 --- a/include/Nazara/Core/Stream.hpp +++ b/include/Nazara/Core/Stream.hpp @@ -16,7 +16,6 @@ namespace Nz class NAZARA_CORE_API Stream { public: - Stream() = default; Stream(const Stream&) = default; Stream(Stream&&) = default; virtual ~Stream(); @@ -24,17 +23,26 @@ namespace Nz virtual UInt64 GetCursorPos() const = 0; virtual String GetDirectory() const; virtual String GetPath() const; - unsigned int GetStreamOptions() const; + inline UInt32 GetOpenMode() const; + inline UInt32 GetStreamOptions() const; + + inline bool IsReadable() const; + inline bool IsWritable() const; virtual bool SetCursorPos(UInt64 offset) = 0; - void SetStreamOptions(unsigned int options); + void SetStreamOptions(UInt32 options); Stream& operator=(const Stream&) = default; Stream& operator=(Stream&&) = default; protected: - unsigned int m_streamOptions = 0; + inline Stream(UInt32 openMode); + + UInt32 m_openMode; + UInt32 m_streamOptions; }; } +#include + #endif // NAZARA_STREAM_HPP diff --git a/include/Nazara/Core/Stream.inl b/include/Nazara/Core/Stream.inl new file mode 100644 index 000000000..905c9276e --- /dev/null +++ b/include/Nazara/Core/Stream.inl @@ -0,0 +1,37 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +namespace Nz +{ + inline Stream::Stream(UInt32 openMode) : + m_openMode(openMode), + m_streamOptions(0) + { + } + + inline UInt32 Stream::GetOpenMode() const + { + return m_openMode; + } + + inline UInt32 Stream::GetStreamOptions() const + { + return m_streamOptions; + } + + inline bool Stream::IsReadable() const + { + return m_openMode & OpenMode_ReadOnly || m_openMode & OpenMode_ReadWrite; + } + + inline bool Stream::IsWritable() const + { + return m_openMode & OpenMode_ReadWrite || m_openMode & OpenMode_WriteOnly; + } + + inline void Stream::SetStreamOptions(UInt32 options) + { + m_streamOptions = options; + } +} diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 977b0353f..8e3841866 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -31,29 +31,28 @@ namespace Nz { File::File() : + Stream(OpenMode_Current), m_endianness(Endianness_Unknown), - m_impl(nullptr), - m_openMode(OpenMode_Current) + m_impl(nullptr) { } File::File(const String& filePath) : - m_endianness(Endianness_Unknown), - m_impl(nullptr), - m_openMode(OpenMode_Current) + File() { SetFile(filePath); } - File::File(const String& filePath, unsigned int openMode) : - m_endianness(Endianness_Unknown), - m_impl(nullptr), - m_openMode(openMode) + File::File(const String& filePath, UInt32 openMode) : + File() { Open(filePath, openMode); } File::File(File&& file) noexcept : + Stream(std::move(file)), + InputStream(std::move(file)), + OutputStream(std::move(file)), m_endianness(file.m_endianness), m_filePath(std::move(file.m_filePath)), m_impl(file.m_impl), @@ -127,19 +126,8 @@ namespace Nz { NazaraLock(m_mutex) - #if NAZARA_CORE_SAFE - if (!IsOpen()) - { - NazaraError("File not opened"); - return; - } - - if ((m_openMode & OpenMode_ReadWrite) == 0 && (m_openMode & OpenMode_WriteOnly) == 0) - { - NazaraError("Cannot flush file without write access"); - return; - } - #endif + NazaraAssert(IsOpen(), "File is not open"); + NazaraAssert(IsWritable(), "File not opened with write access"); m_impl->Flush(); } @@ -155,13 +143,7 @@ namespace Nz { NazaraLock(m_mutex) - #if NAZARA_CORE_SAFE - if (!IsOpen()) - { - NazaraError("File not opened"); - return false; - } - #endif + NazaraAssert(IsOpen(), "File is not opened"); return m_impl->GetCursorPos(); } @@ -219,19 +201,8 @@ namespace Nz { NazaraLock(m_mutex) - #if NAZARA_CORE_SAFE - if (!IsOpen()) - { - NazaraError("File not opened"); - return 0; - } - - if ((m_openMode & OpenMode_ReadOnly) == 0 && (m_openMode & OpenMode_ReadWrite) == 0) - { - NazaraError("File not opened with read access"); - return 0; - } - #endif + NazaraAssert(IsOpen(), "File is not opened"); + NazaraAssert(IsReadable(), "File not opened with read access"); if (size == 0) return 0; @@ -245,7 +216,7 @@ namespace Nz m_impl->SetCursorPos(CursorPosition_AtCurrent, size); - return static_cast(m_impl->GetCursorPos()-currentPos); + return static_cast(m_impl->GetCursorPos() - currentPos); } } @@ -327,13 +298,7 @@ namespace Nz { NazaraLock(m_mutex) - #if NAZARA_CORE_SAFE - if (!IsOpen()) - { - NazaraError("File not opened"); - return false; - } - #endif + NazaraAssert(IsOpen(), "File is not opened"); return m_impl->SetCursorPos(pos, offset); } @@ -342,13 +307,7 @@ namespace Nz { NazaraLock(m_mutex) - #if NAZARA_CORE_SAFE - if (!IsOpen()) - { - NazaraError("File not opened"); - return false; - } - #endif + NazaraAssert(IsOpen(), "File is not opened"); return m_impl->SetCursorPos(CursorPosition_AtBegin, offset); } @@ -418,10 +377,11 @@ namespace Nz std::size_t File::Write(const void* buffer, std::size_t size) { - NazaraAssert(IsOpen(), "File is not open"); - NazaraAssert(m_openMode & OpenMode_ReadWrite || m_openMode & OpenMode_WriteOnly, "File not opened with write access"); NazaraLock(m_mutex) + NazaraAssert(IsOpen(), "File is not opened"); + NazaraAssert(IsWritable(), "File not opened with write access"); + if (!buffer || size == 0) return 0; @@ -430,26 +390,11 @@ namespace Nz std::size_t File::Write(const void* buffer, std::size_t typeSize, unsigned int count) { - NazaraLock(m_mutex) - - #if NAZARA_CORE_SAFE - if (!IsOpen()) - { - NazaraError("File not opened"); - return 0; - } - - if ((m_openMode & OpenMode_ReadWrite) == 0 && (m_openMode & OpenMode_WriteOnly) == 0) - { - NazaraError("File not opened with write access"); - return 0; - } - #endif - if (!buffer || count == 0 || typeSize == 0) return 0; - std::size_t bytesWritten; + NazaraLock(m_mutex) + if (m_endianness != Endianness_Unknown && m_endianness != GetPlatformEndianness() && typeSize != 1) { std::unique_ptr buf(new char[count*typeSize]); @@ -458,12 +403,10 @@ namespace Nz for (unsigned int i = 0; i < count; ++i) SwapBytes(&buf[i*typeSize], typeSize); - bytesWritten = m_impl->Write(buf.get(), count*typeSize); + return Write(buf.get(), count*typeSize); } else - bytesWritten = m_impl->Write(buffer, count*typeSize); - - return bytesWritten; + return Write(buffer, count*typeSize); } File& File::operator=(const String& filePath) diff --git a/src/Nazara/Core/MemoryStream.cpp b/src/Nazara/Core/MemoryStream.cpp index 2fb3ab3df..3c07d1fee 100644 --- a/src/Nazara/Core/MemoryStream.cpp +++ b/src/Nazara/Core/MemoryStream.cpp @@ -10,6 +10,7 @@ namespace Nz { MemoryStream::MemoryStream(const void* ptr, UInt64 size) : + Stream(OpenMode_ReadOnly), m_ptr(reinterpret_cast(ptr)), m_pos(0), m_size(size) diff --git a/src/Nazara/Core/Posix/FileImpl.cpp b/src/Nazara/Core/Posix/FileImpl.cpp index 9c1469817..d0d0bf7ee 100644 --- a/src/Nazara/Core/Posix/FileImpl.cpp +++ b/src/Nazara/Core/Posix/FileImpl.cpp @@ -18,7 +18,8 @@ namespace Nz void FileImpl::Close() { - close(m_fileDescriptor); + if (m_fileDescriptor != -1) + close(m_fileDescriptor); } bool FileImpl::EndOfFile() const @@ -48,7 +49,7 @@ namespace Nz return static_cast(position); } - bool FileImpl::Open(const String& filePath, unsigned int mode) + bool FileImpl::Open(const String& filePath, UInt32 mode) { int flags; mode_t permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; diff --git a/src/Nazara/Core/Posix/FileImpl.hpp b/src/Nazara/Core/Posix/FileImpl.hpp index 6531dc70b..844bebd29 100644 --- a/src/Nazara/Core/Posix/FileImpl.hpp +++ b/src/Nazara/Core/Posix/FileImpl.hpp @@ -36,7 +36,7 @@ namespace Nz bool EndOfFile() const; void Flush(); UInt64 GetCursorPos() const; - bool Open(const String& filePath, unsigned int mode); + bool Open(const String& filePath, UInt32 mode); std::size_t Read(void* buffer, std::size_t size); bool SetCursorPos(CursorPosition pos, Int64 offset); std::size_t Write(const void* buffer, std::size_t size); diff --git a/src/Nazara/Core/Stream.cpp b/src/Nazara/Core/Stream.cpp index 9e43100bd..f3bdb8fe4 100644 --- a/src/Nazara/Core/Stream.cpp +++ b/src/Nazara/Core/Stream.cpp @@ -18,14 +18,4 @@ namespace Nz { return String(); } - - unsigned int Stream::GetStreamOptions() const - { - return m_streamOptions; - } - - void Stream::SetStreamOptions(unsigned int options) - { - m_streamOptions = options; - } } diff --git a/src/Nazara/Core/Win32/FileImpl.cpp b/src/Nazara/Core/Win32/FileImpl.cpp index 18f438ea5..113915c66 100644 --- a/src/Nazara/Core/Win32/FileImpl.cpp +++ b/src/Nazara/Core/Win32/FileImpl.cpp @@ -54,7 +54,7 @@ namespace Nz return position.QuadPart; } - bool FileImpl::Open(const String& filePath, unsigned int mode) + bool FileImpl::Open(const String& filePath, UInt32 mode) { DWORD access; DWORD shareMode = FILE_SHARE_READ; diff --git a/src/Nazara/Core/Win32/FileImpl.hpp b/src/Nazara/Core/Win32/FileImpl.hpp index 9bc484cc1..0f3745abc 100644 --- a/src/Nazara/Core/Win32/FileImpl.hpp +++ b/src/Nazara/Core/Win32/FileImpl.hpp @@ -29,7 +29,7 @@ namespace Nz bool EndOfFile() const; void Flush(); UInt64 GetCursorPos() const; - bool Open(const String& filePath, unsigned int mode); + bool Open(const String& filePath, UInt32 mode); std::size_t Read(void* buffer, std::size_t size); bool SetCursorPos(CursorPosition pos, Int64 offset); std::size_t Write(const void* buffer, std::size_t size); From 131d047517fed683c47b7ac7d1c9536daa93a2ed Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 17 Nov 2015 13:21:12 +0100 Subject: [PATCH 59/97] Regenerate global headers Former-commit-id: 07a0b81c1840da5d9f1f59e9ba328c24a72e45ad --- include/Nazara/Core.hpp | 6 ++---- include/Nazara/Graphics.hpp | 3 ++- include/Nazara/Noise.hpp | 4 ++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/Nazara/Core.hpp b/include/Nazara/Core.hpp index 6ee347b88..2e83b252d 100644 --- a/include/Nazara/Core.hpp +++ b/include/Nazara/Core.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 24 Jun 2015 at 13:55:50 +// This file was automatically generated on 17 Nov 2015 at 13:20:45 /* Nazara Engine - Core module @@ -49,9 +49,6 @@ #include #include #include -#include -#include -#include #include #include #include @@ -64,6 +61,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Graphics.hpp b/include/Nazara/Graphics.hpp index 5b3c94d39..465aeb999 100644 --- a/include/Nazara/Graphics.hpp +++ b/include/Nazara/Graphics.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 24 Jun 2015 at 13:55:50 +// This file was automatically generated on 17 Nov 2015 at 13:20:45 /* Nazara Engine - Graphics module @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Noise.hpp b/include/Nazara/Noise.hpp index 9ab591763..45b240378 100644 --- a/include/Nazara/Noise.hpp +++ b/include/Nazara/Noise.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 24 Jun 2015 at 13:55:50 +// This file was automatically generated on 17 Nov 2015 at 13:20:45 /* Nazara Engine - Noise module @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include From a1bb10425517eb58085b2f635976bb576c610c2f Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 17 Nov 2015 14:05:46 +0100 Subject: [PATCH 60/97] Core/File: Fix crash Former-commit-id: ee797ea7ba228fa814f2c87250c6dd6c32a9982f --- include/Nazara/Core/File.hpp | 1 - src/Nazara/Core/File.cpp | 11 +++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index d6a819c9f..d95a5857c 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -102,7 +102,6 @@ namespace Nz Endianness m_endianness; String m_filePath; - UInt32 m_openMode; FileImpl* m_impl; }; diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 8e3841866..8cf59b3d2 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -55,8 +55,7 @@ namespace Nz OutputStream(std::move(file)), m_endianness(file.m_endianness), m_filePath(std::move(file.m_filePath)), - m_impl(file.m_impl), - m_openMode(file.m_openMode) + m_impl(file.m_impl) { file.m_impl = nullptr; } @@ -382,17 +381,21 @@ namespace Nz NazaraAssert(IsOpen(), "File is not opened"); NazaraAssert(IsWritable(), "File not opened with write access"); - if (!buffer || size == 0) + if (size == 0) return 0; + NazaraAssert(buffer, "Invalid buffer"); + return m_impl->Write(buffer, size); } std::size_t File::Write(const void* buffer, std::size_t typeSize, unsigned int count) { - if (!buffer || count == 0 || typeSize == 0) + if (count == 0 || typeSize == 0) return 0; + NazaraAssert(buffer, "Invalid buffer"); + NazaraLock(m_mutex) if (m_endianness != Endianness_Unknown && m_endianness != GetPlatformEndianness() && typeSize != 1) From ddc343a630b4c388e1aaa71e51945c48f2265107 Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 17 Nov 2015 14:06:57 +0100 Subject: [PATCH 61/97] Core: Rename MemoryStream to MemoryView, add MemoryStream Former-commit-id: c180d5f34fa7c477f35c4b70ebf7b64e3f35fe3d --- include/Nazara/Core.hpp | 1 + include/Nazara/Core/InputStream.hpp | 2 +- include/Nazara/Core/MemoryStream.hpp | 33 +++++++----- include/Nazara/Core/MemoryView.hpp | 42 +++++++++++++++ include/Nazara/Core/OutputStream.hpp | 2 +- include/Nazara/Core/ResourceLoader.inl | 4 +- src/Nazara/Audio/Formats/sndfileLoader.cpp | 4 +- src/Nazara/Core/Log.cpp | 2 +- src/Nazara/Core/MemoryStream.cpp | 42 +++++++++------ src/Nazara/Core/MemoryView.cpp | 52 +++++++++++++++++++ src/Nazara/Lua/LuaInstance.cpp | 4 +- src/Nazara/Utility/Formats/FreeTypeLoader.cpp | 4 +- src/Nazara/Utility/Formats/STBLoader.cpp | 2 +- 13 files changed, 153 insertions(+), 41 deletions(-) create mode 100644 include/Nazara/Core/MemoryView.hpp create mode 100644 src/Nazara/Core/MemoryView.cpp diff --git a/include/Nazara/Core.hpp b/include/Nazara/Core.hpp index 2e83b252d..7f16775d8 100644 --- a/include/Nazara/Core.hpp +++ b/include/Nazara/Core.hpp @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Nazara/Core/InputStream.hpp b/include/Nazara/Core/InputStream.hpp index ec67be839..9bd66f91b 100644 --- a/include/Nazara/Core/InputStream.hpp +++ b/include/Nazara/Core/InputStream.hpp @@ -12,7 +12,7 @@ namespace Nz { - class NAZARA_CORE_API InputStream : public virtual Stream + class NAZARA_CORE_API InputStream : virtual public Stream { public: virtual ~InputStream(); diff --git a/include/Nazara/Core/MemoryStream.hpp b/include/Nazara/Core/MemoryStream.hpp index a6cf6ea70..30c2fa58a 100644 --- a/include/Nazara/Core/MemoryStream.hpp +++ b/include/Nazara/Core/MemoryStream.hpp @@ -9,33 +9,38 @@ #include #include +#include +#include namespace Nz { - class NAZARA_CORE_API MemoryStream : public InputStream + class NAZARA_CORE_API MemoryStream : public InputStream, public OutputStream { public: - MemoryStream(const void* ptr, UInt64 size); - MemoryStream(const MemoryStream&) = delete; - MemoryStream(MemoryStream&&) = delete; ///TODO - ~MemoryStream(); + MemoryStream(const void* ptr, unsigned int size); + MemoryStream(const MemoryStream&) = default; + MemoryStream(MemoryStream&&) = default; + ~MemoryStream() = default; - bool EndOfStream() const; + bool EndOfStream() const override; - UInt64 GetCursorPos() const; - UInt64 GetSize() const; + void Flush() override; - std::size_t Read(void* buffer, std::size_t size); + UInt64 GetCursorPos() const override; + UInt64 GetSize() const override; - bool SetCursorPos(UInt64 offset); + std::size_t Read(void* buffer, std::size_t size) override; - MemoryStream& operator=(const MemoryStream&) = delete; - MemoryStream& operator=(MemoryStream&&) = delete; ///TODO + bool SetCursorPos(UInt64 offset) override; + + std::size_t Write(const void* buffer, std::size_t size) override; + + MemoryStream& operator=(const MemoryStream&) = default; + MemoryStream& operator=(MemoryStream&&) = default; private: - const UInt8* m_ptr; + std::vector m_buffer; UInt64 m_pos; - UInt64 m_size; }; } diff --git a/include/Nazara/Core/MemoryView.hpp b/include/Nazara/Core/MemoryView.hpp new file mode 100644 index 000000000..47fdc87f0 --- /dev/null +++ b/include/Nazara/Core/MemoryView.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_MEMORYVIEW_HPP +#define NAZARA_MEMORYVIEW_HPP + +#include +#include + +namespace Nz +{ + class NAZARA_CORE_API MemoryView : public InputStream + { + public: + MemoryView(const void* ptr, UInt64 size); + MemoryView(const MemoryView&) = delete; + MemoryView(MemoryView&&) = delete; ///TODO + ~MemoryView() = default; + + bool EndOfStream() const override; + + UInt64 GetCursorPos() const override; + UInt64 GetSize() const override; + + std::size_t Read(void* buffer, std::size_t size) override; + + bool SetCursorPos(UInt64 offset) override; + + MemoryView& operator=(const MemoryView&) = delete; + MemoryView& operator=(MemoryView&&) = delete; ///TODO + + private: + const UInt8* m_ptr; + UInt64 m_pos; + UInt64 m_size; + }; +} + +#endif // NAZARA_MEMORYVIEW_HPP diff --git a/include/Nazara/Core/OutputStream.hpp b/include/Nazara/Core/OutputStream.hpp index 363270ea5..2f475d4b4 100644 --- a/include/Nazara/Core/OutputStream.hpp +++ b/include/Nazara/Core/OutputStream.hpp @@ -12,7 +12,7 @@ namespace Nz { - class NAZARA_CORE_API OutputStream : public virtual Stream + class NAZARA_CORE_API OutputStream : virtual public Stream { public: virtual ~OutputStream(); diff --git a/include/Nazara/Core/ResourceLoader.inl b/include/Nazara/Core/ResourceLoader.inl index fd4b9d4e3..3f78ca7ff 100644 --- a/include/Nazara/Core/ResourceLoader.inl +++ b/include/Nazara/Core/ResourceLoader.inl @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include namespace Nz @@ -139,7 +139,7 @@ namespace Nz } #endif - MemoryStream stream(data, size); + MemoryView stream(data, size); bool found = false; for (Loader& loader : Type::s_loaders) diff --git a/src/Nazara/Audio/Formats/sndfileLoader.cpp b/src/Nazara/Audio/Formats/sndfileLoader.cpp index 14f932e9e..fb8725a37 100644 --- a/src/Nazara/Audio/Formats/sndfileLoader.cpp +++ b/src/Nazara/Audio/Formats/sndfileLoader.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -124,7 +124,7 @@ namespace Nz bool Open(const void* data, std::size_t size, bool forceMono) { - m_ownedStream.reset(new MemoryStream(data, size)); + m_ownedStream.reset(new MemoryView(data, size)); return Open(*m_ownedStream, forceMono); } diff --git a/src/Nazara/Core/Log.cpp b/src/Nazara/Core/Log.cpp index 4c8997718..af9f9ef14 100644 --- a/src/Nazara/Core/Log.cpp +++ b/src/Nazara/Core/Log.cpp @@ -161,5 +161,5 @@ namespace Nz { static Log log; return &log; -} + } } diff --git a/src/Nazara/Core/MemoryStream.cpp b/src/Nazara/Core/MemoryStream.cpp index 3c07d1fee..99aa04b26 100644 --- a/src/Nazara/Core/MemoryStream.cpp +++ b/src/Nazara/Core/MemoryStream.cpp @@ -9,21 +9,22 @@ namespace Nz { - MemoryStream::MemoryStream(const void* ptr, UInt64 size) : - Stream(OpenMode_ReadOnly), - m_ptr(reinterpret_cast(ptr)), - m_pos(0), - m_size(size) - { - } - - MemoryStream::~MemoryStream() + MemoryStream::MemoryStream(const void* ptr, unsigned int size) : + Stream(OpenMode_ReadWrite), + m_pos(0) { + m_buffer.resize(size); + std::memcpy(m_buffer.data(), ptr, size); } bool MemoryStream::EndOfStream() const { - return m_pos == m_size; + return m_pos >= m_buffer.size(); + } + + void MemoryStream::Flush() + { + // Nothing to flush } UInt64 MemoryStream::GetCursorPos() const @@ -33,25 +34,36 @@ namespace Nz UInt64 MemoryStream::GetSize() const { - return m_size; + return m_buffer.size(); } std::size_t MemoryStream::Read(void* buffer, std::size_t size) { - unsigned int readSize = std::min(static_cast(size), static_cast(m_size-m_pos)); + std::size_t readSize = std::min(size, static_cast(m_buffer.size() - m_pos)); if (buffer) - std::memcpy(buffer, &m_ptr[m_pos], readSize); + std::memcpy(buffer, m_buffer.data() + m_pos, readSize); m_pos += readSize; - return readSize; } bool MemoryStream::SetCursorPos(UInt64 offset) { - m_pos = std::min(offset, m_size); + m_pos = std::min(offset, m_buffer.size()); return true; } + + std::size_t MemoryStream::Write(const void* buffer, std::size_t size) + { + std::size_t endPos = static_cast(m_pos + size); + if (endPos > m_buffer.size()) + m_buffer.resize(endPos); + + std::memcpy(m_buffer.data(), buffer, size); + + m_pos = endPos; + return size; + } } diff --git a/src/Nazara/Core/MemoryView.cpp b/src/Nazara/Core/MemoryView.cpp new file mode 100644 index 000000000..b5a47c776 --- /dev/null +++ b/src/Nazara/Core/MemoryView.cpp @@ -0,0 +1,52 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include +#include +#include + +namespace Nz +{ + MemoryView::MemoryView(const void* ptr, UInt64 size) : + Stream(OpenMode_ReadOnly), + m_ptr(reinterpret_cast(ptr)), + m_pos(0), + m_size(size) + { + } + + bool MemoryView::EndOfStream() const + { + return m_pos >= m_size; + } + + UInt64 MemoryView::GetCursorPos() const + { + return m_pos; + } + + UInt64 MemoryView::GetSize() const + { + return m_size; + } + + std::size_t MemoryView::Read(void* buffer, std::size_t size) + { + std::size_t readSize = std::min(size, static_cast(m_size - m_pos)); + + if (buffer) + std::memcpy(buffer, &m_ptr[m_pos], readSize); + + m_pos += readSize; + return readSize; + } + + bool MemoryView::SetCursorPos(UInt64 offset) + { + m_pos = std::min(offset, m_size); + + return true; + } +} diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp index 7b1e603b2..d5b8e3e1d 100644 --- a/src/Nazara/Lua/LuaInstance.cpp +++ b/src/Nazara/Lua/LuaInstance.cpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include #include @@ -418,7 +418,7 @@ namespace Nz bool LuaInstance::ExecuteFromMemory(const void* data, unsigned int size) { - MemoryStream stream(data, size); + MemoryView stream(data, size); return ExecuteFromStream(stream); } diff --git a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp index 23cdc58be..f859e327f 100644 --- a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp +++ b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp @@ -9,7 +9,7 @@ #include FT_OUTLINE_H #include #include -#include +#include #include #include #include @@ -294,7 +294,7 @@ namespace Nz void SetMemory(const void* data, std::size_t size) { - m_ownedStream.reset(new MemoryStream(data, size)); + m_ownedStream.reset(new MemoryView(data, size)); SetStream(*m_ownedStream); } diff --git a/src/Nazara/Utility/Formats/STBLoader.cpp b/src/Nazara/Utility/Formats/STBLoader.cpp index ca6832f55..86d23644e 100644 --- a/src/Nazara/Utility/Formats/STBLoader.cpp +++ b/src/Nazara/Utility/Formats/STBLoader.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include #include From 00423c42110e0af7c5d191609f6390f3b8604896 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 18 Nov 2015 18:27:01 +0100 Subject: [PATCH 62/97] Core/File: Remove useless SetOpenMode method (equivalent to Open) Former-commit-id: e02f4f758adfd2c0870920997acac71a47d51c3f --- include/Nazara/Core/File.hpp | 1 - src/Nazara/Core/File.cpp | 30 ------------------------------ 2 files changed, 31 deletions(-) diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index d95a5857c..b5496310a 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -71,7 +71,6 @@ namespace Nz bool SetCursorPos(UInt64 offset) override; void SetEndianness(Endianness endianness); bool SetFile(const String& filePath); - bool SetOpenMode(UInt32 openMode); using OutputStream::Write; std::size_t Write(const void* buffer, std::size_t size) override; diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 8cf59b3d2..f4e3f3895 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -344,36 +344,6 @@ namespace Nz return true; } - bool File::SetOpenMode(unsigned int openMode) - { - NazaraLock(m_mutex) - - if (openMode == OpenMode_Current || openMode == m_openMode) - return true; - - if (IsOpen()) - { - std::unique_ptr impl(new FileImpl(this)); - if (!impl->Open(m_filePath, openMode)) - { - NazaraError("Failed to open file with new mode: " + Error::GetLastSystemError()); - return false; - } - - m_impl->Close(); - delete m_impl; - - m_impl = impl.release(); - - if (m_openMode & OpenMode_Text) - m_streamOptions |= StreamOption_Text; - } - - m_openMode = openMode; - - return true; - } - std::size_t File::Write(const void* buffer, std::size_t size) { NazaraLock(m_mutex) From 167f3e4a27680dd324a3765dce7363d7f550ecc3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 18 Nov 2015 18:28:56 +0100 Subject: [PATCH 63/97] Core: Switch Hashable struct to HashAppend function Former-commit-id: 2a20eca0e75bf4067d390f4f5e446de78f26799c --- include/Nazara/Core/Algorithm.hpp | 4 ++-- include/Nazara/Core/Algorithm.inl | 4 +++- include/Nazara/Core/ByteArray.hpp | 3 +-- include/Nazara/Core/ByteArray.inl | 12 ++++------- include/Nazara/Core/File.hpp | 3 +-- include/Nazara/Core/File.inl | 36 +------------------------------ include/Nazara/Core/String.hpp | 3 +-- include/Nazara/Core/String.inl | 12 ++++------- src/Nazara/Core/File.cpp | 28 ++++++++++++++++++++++++ 9 files changed, 45 insertions(+), 60 deletions(-) diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index 5670b57d6..d70aff30b 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -24,10 +24,10 @@ namespace Nz template void HashCombine(std::size_t& seed, const T& v); template - struct Hashable; + struct TypeTag {}; + template - struct TypeTag {}; } #include diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 25e4ecdb2..3912f615a 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -53,7 +53,9 @@ namespace Nz ByteArray ComputeHash(AbstractHash* hash, const T& v) { hash->Begin(); - Hashable()(v, hash); + + HashAppend(hash, v); + return hash->End(); } diff --git a/include/Nazara/Core/ByteArray.hpp b/include/Nazara/Core/ByteArray.hpp index 8be45779b..90f9c5d03 100644 --- a/include/Nazara/Core/ByteArray.hpp +++ b/include/Nazara/Core/ByteArray.hpp @@ -128,8 +128,7 @@ namespace Nz Container m_array; }; - template<> - struct Hashable; + inline bool HashAppend(AbstractHash* hash, const ByteArray& byteArray); } namespace std diff --git a/include/Nazara/Core/ByteArray.inl b/include/Nazara/Core/ByteArray.inl index 13c846c05..ada835e3e 100644 --- a/include/Nazara/Core/ByteArray.inl +++ b/include/Nazara/Core/ByteArray.inl @@ -335,15 +335,11 @@ namespace Nz return m_array >= rhs.m_array; } - template<> - struct Hashable + inline bool HashAppend(AbstractHash* hash, const ByteArray& byteArray) { - bool operator()(const ByteArray& byteArray, AbstractHash* hash) const - { - hash->Append(byteArray.GetConstBuffer(), byteArray.GetSize()); - return true; - } - }; + hash->Append(byteArray.GetConstBuffer(), byteArray.GetSize()); + return true; + } } namespace std diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index b5496310a..18ed54b98 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -104,8 +104,7 @@ namespace Nz FileImpl* m_impl; }; - template<> - struct Hashable; + NAZARA_CORE_API bool HashAppend(AbstractHash* hash, const File& originalFile); } #include diff --git a/include/Nazara/Core/File.inl b/include/Nazara/Core/File.inl index c5603c320..818d0098f 100644 --- a/include/Nazara/Core/File.inl +++ b/include/Nazara/Core/File.inl @@ -3,8 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include -#include +#include #include namespace Nz @@ -18,39 +17,6 @@ namespace Nz { return Nz::ComputeHash(hash, File(filePath)); } - - template<> - struct Hashable - { - bool operator()(const Nz::File& originalFile, AbstractHash* hash) const - { - - File file(originalFile.GetPath()); - if (!file.Open(OpenMode_ReadOnly)) - { - NazaraError("Unable to open file"); - return false; - } - - UInt64 remainingSize = file.GetSize(); - - char buffer[NAZARA_CORE_FILE_BUFFERSIZE]; - while (remainingSize > 0) - { - unsigned int size = static_cast(std::min(remainingSize, static_cast(NAZARA_CORE_FILE_BUFFERSIZE))); - if (file.Read(&buffer[0], sizeof(char), size) != sizeof(char)*size) - { - NazaraError("Unable to read file"); - return false; - } - - remainingSize -= size; - hash->Append(reinterpret_cast(&buffer[0]), size); - } - - return true; - } - }; } #include diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 61af938d1..988ed96d3 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -324,8 +324,7 @@ namespace Nz }; }; - template<> - struct Hashable; + inline bool HashAppend(AbstractHash* hash, const String& string); } namespace std diff --git a/include/Nazara/Core/String.inl b/include/Nazara/Core/String.inl index cc323d697..202cec2e6 100644 --- a/include/Nazara/Core/String.inl +++ b/include/Nazara/Core/String.inl @@ -39,15 +39,11 @@ namespace Nz string[strSize] = '\0'; } - template<> - struct Hashable + inline bool HashAppend(AbstractHash* hash, const String& string) { - bool operator()(const String& str, AbstractHash* hash) const - { - hash->Append(reinterpret_cast(str.GetConstBuffer()), str.GetSize()); - return true; - } - }; + hash->Append(reinterpret_cast(string.GetConstBuffer()), string.GetSize()); + return true; + } } namespace std diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index f4e3f3895..eedfc99a6 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -596,4 +596,32 @@ namespace Nz return FileImpl::Rename(NormalizePath(sourcePath), NormalizePath(targetPath)); } + + NAZARA_CORE_API bool HashAppend(AbstractHash* hash, const File& originalFile) + { + File file(originalFile.GetPath()); + if (!file.Open(OpenMode_ReadOnly)) + { + NazaraError("Unable to open file"); + return false; + } + + UInt64 remainingSize = file.GetSize(); + + char buffer[NAZARA_CORE_FILE_BUFFERSIZE]; + while (remainingSize > 0) + { + unsigned int size = static_cast(std::min(remainingSize, static_cast(NAZARA_CORE_FILE_BUFFERSIZE))); + if (file.Read(&buffer[0], sizeof(char), size) != sizeof(char)*size) + { + NazaraError("Unable to read file"); + return false; + } + + remainingSize -= size; + hash->Append(reinterpret_cast(&buffer[0]), size); + } + + return true; + }; } From be01b6f3b4b18aba29f2677b1ef93798b1ab1fda Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 18 Nov 2015 18:29:20 +0100 Subject: [PATCH 64/97] Core: Add serialization interface Former-commit-id: cfa749dba1b6f23ef8f38519e0bc9ad9492e3db3 --- include/Nazara/Core/Algorithm.hpp | 10 +++++ include/Nazara/Core/Algorithm.inl | 55 ++++++++++++++++++++++++++++ include/Nazara/Core/InputStream.hpp | 3 ++ include/Nazara/Core/InputStream.inl | 11 ++++++ include/Nazara/Core/OutputStream.hpp | 6 +++ include/Nazara/Core/OutputStream.inl | 11 ++++++ include/Nazara/Core/Stream.hpp | 3 +- include/Nazara/Core/String.hpp | 5 ++- src/Nazara/Core/Stream.cpp | 1 + src/Nazara/Core/String.cpp | 21 +++++++++++ 10 files changed, 124 insertions(+), 2 deletions(-) diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index d70aff30b..a00d81280 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -9,8 +9,11 @@ #include #include +#include +#include #include #include +#include namespace Nz { @@ -26,8 +29,15 @@ namespace Nz template struct TypeTag {}; + inline bool Serialize(OutputStream* output, bool value); template + std::enable_if_t::value, bool> Serialize(OutputStream* output, T value); + + inline bool Unserialize(InputStream* input, bool* value); + + template + std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value); } #include diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 3912f615a..c6fbb4fb1 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -7,6 +7,7 @@ // Merci aussi à Freedom de siteduzero.com #include +#include #include namespace Nz @@ -75,6 +76,60 @@ namespace Nz seed = static_cast(b * kMul); } + + inline bool Serialize(OutputStream* output, bool value) + { + UInt8 buffer = (value) ? 1 : 0; + return output->Write(&buffer, 1) == 1; + } + + template + std::enable_if_t::value, bool> Serialize(OutputStream* output, T value) + { + if (output->Write(&value, sizeof(T)) == sizeof(T)) + { + // Write down everything as little endian + #if NAZARA_BIG_ENDIAN + SwapBytes(&value, sizeof(T)); + #endif + + return true; + } + else + return false; + } + + inline bool Unserialize(InputStream* input, bool* value) + { + NazaraAssert(value, "Invalid pointer"); + + UInt8 buffer; + if (input->Read(&buffer, 1) == 1) + { + *value = (buffer == 1); + return true; + } + else + return false; + } + + template + std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value) + { + NazaraAssert(value, "Invalid pointer"); + + if (input->Read(value, sizeof(T)) == sizeof(T)) + { + // Write down everything as little endian + #if NAZARA_BIG_ENDIAN + SwapBytes(&value, sizeof(T)); + #endif + + return true; + } + else + return false; + } } #include diff --git a/include/Nazara/Core/InputStream.hpp b/include/Nazara/Core/InputStream.hpp index 9bd66f91b..f431afe14 100644 --- a/include/Nazara/Core/InputStream.hpp +++ b/include/Nazara/Core/InputStream.hpp @@ -24,6 +24,9 @@ namespace Nz virtual std::size_t Read(void* buffer, std::size_t size) = 0; virtual String ReadLine(unsigned int lineSize = 0); + template + InputStream& operator>>(T& value); + protected: inline InputStream(); }; diff --git a/include/Nazara/Core/InputStream.inl b/include/Nazara/Core/InputStream.inl index 35912da00..a9a796032 100644 --- a/include/Nazara/Core/InputStream.inl +++ b/include/Nazara/Core/InputStream.inl @@ -2,10 +2,21 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include + namespace Nz { inline InputStream::InputStream() : Stream(OpenMode_Current) { } + + template + InputStream& InputStream::operator>>(T& value) + { + if (!Unserialize(this, &value)) + NazaraError("Failed to unserialize value"); + + return *this; + } } diff --git a/include/Nazara/Core/OutputStream.hpp b/include/Nazara/Core/OutputStream.hpp index 2f475d4b4..6ace7e403 100644 --- a/include/Nazara/Core/OutputStream.hpp +++ b/include/Nazara/Core/OutputStream.hpp @@ -12,6 +12,9 @@ namespace Nz { + class ByteArray; + class String; + class NAZARA_CORE_API OutputStream : virtual public Stream { public: @@ -23,6 +26,9 @@ namespace Nz bool Write(const String& string); virtual std::size_t Write(const void* buffer, std::size_t size) = 0; + template + OutputStream& operator<<(const T& value); + protected: inline OutputStream(); }; diff --git a/include/Nazara/Core/OutputStream.inl b/include/Nazara/Core/OutputStream.inl index 51766a889..098f012b7 100644 --- a/include/Nazara/Core/OutputStream.inl +++ b/include/Nazara/Core/OutputStream.inl @@ -2,10 +2,21 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include + namespace Nz { inline OutputStream::OutputStream() : Stream(OpenMode_Current) { } + + template + OutputStream& OutputStream::operator<<(const T& value) + { + if (!Serialize(this, value)) + NazaraError("Failed to serialize value"); + + return *this; + } } diff --git a/include/Nazara/Core/Stream.hpp b/include/Nazara/Core/Stream.hpp index a00c09661..85095e324 100644 --- a/include/Nazara/Core/Stream.hpp +++ b/include/Nazara/Core/Stream.hpp @@ -9,10 +9,11 @@ #include #include -#include namespace Nz { + class String; //< Do not include String.hpp in this file + class NAZARA_CORE_API Stream { public: diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 988ed96d3..c48e2552b 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -8,7 +8,6 @@ #define NAZARA_STRING_HPP #include -#include #include #include #include @@ -19,6 +18,8 @@ namespace Nz { class AbstractHash; class HashDigest; + class InputStream; + class OutputStream; class NAZARA_CORE_API String { @@ -325,6 +326,8 @@ namespace Nz }; inline bool HashAppend(AbstractHash* hash, const String& string); + NAZARA_CORE_API bool Serialize(OutputStream* output, const String& string); + NAZARA_CORE_API bool Unserialize(InputStream* input, String* string); } namespace std diff --git a/src/Nazara/Core/Stream.cpp b/src/Nazara/Core/Stream.cpp index f3bdb8fe4..8a6951887 100644 --- a/src/Nazara/Core/Stream.cpp +++ b/src/Nazara/Core/Stream.cpp @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include namespace Nz diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index d5230577a..8aa2e5da7 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -5,6 +5,7 @@ ///TODO: Réécrire une bonne partie des algorithmes employés (Relu jusqu'à 3538) #include +#include #include #include #include @@ -4208,6 +4209,26 @@ namespace Nz return emptyString; } + bool Serialize(OutputStream* output, const String& string) + { + if (!Serialize(output, string.GetSize())) + return false; + + output->Write(string.GetConstBuffer(), string.GetSize()); + return true; + } + + bool Unserialize(InputStream* input, String* string) + { + UInt32 size; + if (!Unserialize(input, &size)) + return false; + + string->Resize(size); + input->Read(string->GetBuffer(), size); + return true; + } + const unsigned int String::npos(std::numeric_limits::max()); } From 3fb9e5736039e5be91bf873212c78be951f2ac49 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 18 Nov 2015 18:49:38 +0100 Subject: [PATCH 65/97] Core/Serialization: Add correct endianness handling Core/File: Remove endianness handling Former-commit-id: 6f7bba52057f36c507a024f7a7ea873658a3cfd3 --- include/Nazara/Core/Algorithm.hpp | 8 ++--- include/Nazara/Core/Algorithm.inl | 33 ++++++++++-------- include/Nazara/Core/Endianness.hpp | 2 +- include/Nazara/Core/Endianness.inl | 2 +- include/Nazara/Core/File.hpp | 3 -- include/Nazara/Core/InputStream.inl | 2 +- include/Nazara/Core/OutputStream.inl | 2 +- include/Nazara/Core/Stream.hpp | 8 +++-- include/Nazara/Core/Stream.inl | 11 ++++++ include/Nazara/Core/String.hpp | 5 +-- src/Nazara/Core/File.cpp | 50 ---------------------------- src/Nazara/Core/String.cpp | 8 ++--- 12 files changed, 51 insertions(+), 83 deletions(-) diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index a00d81280..2f4d770d0 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -29,15 +29,15 @@ namespace Nz template struct TypeTag {}; - inline bool Serialize(OutputStream* output, bool value); + inline bool Serialize(OutputStream* output, bool value, Endianness dataEndianness); template - std::enable_if_t::value, bool> Serialize(OutputStream* output, T value); + std::enable_if_t::value, bool> Serialize(OutputStream* output, T value, Endianness dataEndianness); - inline bool Unserialize(InputStream* input, bool* value); + inline bool Unserialize(InputStream* input, bool* value, Endianness dataEndianness); template - std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value); + std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value, Endianness dataEndianness); } #include diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index c6fbb4fb1..6fed14897 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -77,21 +77,25 @@ namespace Nz seed = static_cast(b * kMul); } - inline bool Serialize(OutputStream* output, bool value) + inline bool Serialize(OutputStream* output, bool value, Endianness dataEndianness) { + NazaraAssert(output, "Invalid stream"); + NazaraUnused(dataEndianness); + + ///TODO: Handle bits writing (Serializing 8 bits should only use one byte) UInt8 buffer = (value) ? 1 : 0; return output->Write(&buffer, 1) == 1; } template - std::enable_if_t::value, bool> Serialize(OutputStream* output, T value) + std::enable_if_t::value, bool> Serialize(OutputStream* output, T value, Endianness dataEndianness) { + NazaraAssert(output, "Invalid stream"); + if (output->Write(&value, sizeof(T)) == sizeof(T)) { - // Write down everything as little endian - #if NAZARA_BIG_ENDIAN - SwapBytes(&value, sizeof(T)); - #endif + if (dataEndianness != Endianness_Unknown && dataEndianness != GetPlatformEndianness()) + SwapBytes(&value, sizeof(T)); return true; } @@ -99,9 +103,11 @@ namespace Nz return false; } - inline bool Unserialize(InputStream* input, bool* value) + inline bool Unserialize(InputStream* input, bool* value, Endianness dataEndianness) { - NazaraAssert(value, "Invalid pointer"); + NazaraAssert(input, "Invalid stream"); + NazaraAssert(value, "Invalid data pointer"); + NazaraUnused(dataEndianness); UInt8 buffer; if (input->Read(&buffer, 1) == 1) @@ -114,16 +120,15 @@ namespace Nz } template - std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value) + std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value, Endianness dataEndianness) { - NazaraAssert(value, "Invalid pointer"); + NazaraAssert(input, "Invalid stream"); + NazaraAssert(value, "Invalid data pointer"); if (input->Read(value, sizeof(T)) == sizeof(T)) { - // Write down everything as little endian - #if NAZARA_BIG_ENDIAN - SwapBytes(&value, sizeof(T)); - #endif + if (dataEndianness != Endianness_Unknown && dataEndianness != GetPlatformEndianness()) + SwapBytes(&value, sizeof(T)); return true; } diff --git a/include/Nazara/Core/Endianness.hpp b/include/Nazara/Core/Endianness.hpp index a97687dac..62cac093d 100644 --- a/include/Nazara/Core/Endianness.hpp +++ b/include/Nazara/Core/Endianness.hpp @@ -27,7 +27,7 @@ namespace Nz { - inline Endianness GetPlatformEndianness(); + inline constexpr Endianness GetPlatformEndianness(); inline void SwapBytes(void* buffer, unsigned int size); } diff --git a/include/Nazara/Core/Endianness.inl b/include/Nazara/Core/Endianness.inl index 3d489c567..96e4fdf8a 100644 --- a/include/Nazara/Core/Endianness.inl +++ b/include/Nazara/Core/Endianness.inl @@ -7,7 +7,7 @@ namespace Nz { - inline Endianness GetPlatformEndianness() + inline constexpr Endianness GetPlatformEndianness() { #if defined(NAZARA_BIG_ENDIAN) return Endianness_BigEndian; diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index 18ed54b98..c3dde211c 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -64,7 +64,6 @@ namespace Nz bool Open(const String& filePath, unsigned int openMode = OpenMode_Current); std::size_t Read(void* buffer, std::size_t size) override; - std::size_t Read(void* buffer, std::size_t typeSize, unsigned int count); bool Rename(const String& newFilePath); bool SetCursorPos(CursorPosition pos, Int64 offset = 0); @@ -74,7 +73,6 @@ namespace Nz using OutputStream::Write; std::size_t Write(const void* buffer, std::size_t size) override; - std::size_t Write(const void* buffer, std::size_t typeSize, unsigned int count); File& operator=(const String& filePath); File& operator=(const File&) = delete; @@ -99,7 +97,6 @@ namespace Nz private: NazaraMutexAttrib(m_mutex, mutable) - Endianness m_endianness; String m_filePath; FileImpl* m_impl; }; diff --git a/include/Nazara/Core/InputStream.inl b/include/Nazara/Core/InputStream.inl index a9a796032..4e8abe925 100644 --- a/include/Nazara/Core/InputStream.inl +++ b/include/Nazara/Core/InputStream.inl @@ -14,7 +14,7 @@ namespace Nz template InputStream& InputStream::operator>>(T& value) { - if (!Unserialize(this, &value)) + if (!Unserialize(this, &value, m_dataEndianness)) NazaraError("Failed to unserialize value"); return *this; diff --git a/include/Nazara/Core/OutputStream.inl b/include/Nazara/Core/OutputStream.inl index 098f012b7..95f0f03e0 100644 --- a/include/Nazara/Core/OutputStream.inl +++ b/include/Nazara/Core/OutputStream.inl @@ -14,7 +14,7 @@ namespace Nz template OutputStream& OutputStream::operator<<(const T& value) { - if (!Serialize(this, value)) + if (!Serialize(this, value, m_dataEndianness)) NazaraError("Failed to serialize value"); return *this; diff --git a/include/Nazara/Core/Stream.hpp b/include/Nazara/Core/Stream.hpp index 85095e324..0abaaab63 100644 --- a/include/Nazara/Core/Stream.hpp +++ b/include/Nazara/Core/Stream.hpp @@ -8,6 +8,7 @@ #define NAZARA_STREAM_HPP #include +#include #include namespace Nz @@ -24,6 +25,7 @@ namespace Nz virtual UInt64 GetCursorPos() const = 0; virtual String GetDirectory() const; virtual String GetPath() const; + inline Endianness GetDataEndianness() const; inline UInt32 GetOpenMode() const; inline UInt32 GetStreamOptions() const; @@ -31,14 +33,16 @@ namespace Nz inline bool IsWritable() const; virtual bool SetCursorPos(UInt64 offset) = 0; - void SetStreamOptions(UInt32 options); + inline void SetDataEndianness(Endianness endiannes); + inline void SetStreamOptions(UInt32 options); Stream& operator=(const Stream&) = default; Stream& operator=(Stream&&) = default; protected: inline Stream(UInt32 openMode); - + + Endianness m_dataEndianness; UInt32 m_openMode; UInt32 m_streamOptions; }; diff --git a/include/Nazara/Core/Stream.inl b/include/Nazara/Core/Stream.inl index 905c9276e..4c9bb138f 100644 --- a/include/Nazara/Core/Stream.inl +++ b/include/Nazara/Core/Stream.inl @@ -5,11 +5,17 @@ namespace Nz { inline Stream::Stream(UInt32 openMode) : + m_dataEndianness(Endianness_Unknown), m_openMode(openMode), m_streamOptions(0) { } + inline Endianness Stream::GetDataEndianness() const + { + return m_dataEndianness; + } + inline UInt32 Stream::GetOpenMode() const { return m_openMode; @@ -30,6 +36,11 @@ namespace Nz return m_openMode & OpenMode_ReadWrite || m_openMode & OpenMode_WriteOnly; } + inline void Stream::SetDataEndianness(Endianness endiannes) + { + m_dataEndianness = endiannes; + } + inline void Stream::SetStreamOptions(UInt32 options) { m_streamOptions = options; diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index c48e2552b..17ef58aab 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -8,6 +8,7 @@ #define NAZARA_STRING_HPP #include +#include #include #include #include @@ -326,8 +327,8 @@ namespace Nz }; inline bool HashAppend(AbstractHash* hash, const String& string); - NAZARA_CORE_API bool Serialize(OutputStream* output, const String& string); - NAZARA_CORE_API bool Unserialize(InputStream* input, String* string); + NAZARA_CORE_API bool Serialize(OutputStream* output, const String& string, Endianness dataEndianness); + NAZARA_CORE_API bool Unserialize(InputStream* input, String* string, Endianness dataEndianness); } namespace std diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index eedfc99a6..cc5674d2f 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -32,7 +32,6 @@ namespace Nz { File::File() : Stream(OpenMode_Current), - m_endianness(Endianness_Unknown), m_impl(nullptr) { } @@ -53,7 +52,6 @@ namespace Nz Stream(std::move(file)), InputStream(std::move(file)), OutputStream(std::move(file)), - m_endianness(file.m_endianness), m_filePath(std::move(file.m_filePath)), m_impl(file.m_impl) { @@ -219,22 +217,6 @@ namespace Nz } } - std::size_t File::Read(void* buffer, std::size_t typeSize, unsigned int count) - { - std::size_t byteRead = Read(buffer, typeSize*count); - if (byteRead == 0) - return 0; - - if (buffer && typeSize != 1 && m_endianness != Endianness_Unknown && m_endianness != GetPlatformEndianness()) - { - unsigned int typeCount = byteRead/typeSize; - for (unsigned int i = 0; i < typeCount; ++i) - SwapBytes(reinterpret_cast(buffer) + i*typeSize, typeSize); - } - - return byteRead; - } - bool File::Rename(const String& newFilePath) { NazaraLock(m_mutex) @@ -311,13 +293,6 @@ namespace Nz return m_impl->SetCursorPos(CursorPosition_AtBegin, offset); } - void File::SetEndianness(Endianness endianness) - { - NazaraLock(m_mutex) - - m_endianness = endianness; - } - bool File::SetFile(const String& filePath) { NazaraLock(m_mutex) @@ -359,29 +334,6 @@ namespace Nz return m_impl->Write(buffer, size); } - std::size_t File::Write(const void* buffer, std::size_t typeSize, unsigned int count) - { - if (count == 0 || typeSize == 0) - return 0; - - NazaraAssert(buffer, "Invalid buffer"); - - NazaraLock(m_mutex) - - if (m_endianness != Endianness_Unknown && m_endianness != GetPlatformEndianness() && typeSize != 1) - { - std::unique_ptr buf(new char[count*typeSize]); - std::memcpy(buf.get(), buffer, count*typeSize); - - for (unsigned int i = 0; i < count; ++i) - SwapBytes(&buf[i*typeSize], typeSize); - - return Write(buf.get(), count*typeSize); - } - else - return Write(buffer, count*typeSize); - } - File& File::operator=(const String& filePath) { SetFile(filePath); @@ -393,10 +345,8 @@ namespace Nz { NazaraLock(m_mutex) - std::swap(m_endianness, file.m_endianness); std::swap(m_filePath, file.m_filePath); std::swap(m_impl, file.m_impl); - std::swap(m_openMode, file.m_openMode); return *this; } diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 8aa2e5da7..6ad60a3cb 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -4209,19 +4209,19 @@ namespace Nz return emptyString; } - bool Serialize(OutputStream* output, const String& string) + bool Serialize(OutputStream* output, const String& string, Endianness dataEndianness) { - if (!Serialize(output, string.GetSize())) + if (!Serialize(output, string.GetSize(), dataEndianness)) return false; output->Write(string.GetConstBuffer(), string.GetSize()); return true; } - bool Unserialize(InputStream* input, String* string) + bool Unserialize(InputStream* input, String* string, Endianness dataEndianness) { UInt32 size; - if (!Unserialize(input, &size)) + if (!Unserialize(input, &size, dataEndianness)) return false; string->Resize(size); From 6eada337b82e40cbab7b2378acd3b11d53f1e433 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 19 Nov 2015 12:18:27 +0100 Subject: [PATCH 66/97] Core/File: Fix compilation Former-commit-id: 69d173fe734dde3d0ca0f008826addce0d5d50bf --- include/Nazara/Core/File.hpp | 1 - src/Nazara/Core/File.cpp | 4 ++-- tests/Engine/Core/File.cpp | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index c3dde211c..d0a66e09c 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -68,7 +68,6 @@ namespace Nz bool SetCursorPos(CursorPosition pos, Int64 offset = 0); bool SetCursorPos(UInt64 offset) override; - void SetEndianness(Endianness endianness); bool SetFile(const String& filePath); using OutputStream::Write; diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index cc5674d2f..7ad8669e0 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -561,8 +561,8 @@ namespace Nz char buffer[NAZARA_CORE_FILE_BUFFERSIZE]; while (remainingSize > 0) { - unsigned int size = static_cast(std::min(remainingSize, static_cast(NAZARA_CORE_FILE_BUFFERSIZE))); - if (file.Read(&buffer[0], sizeof(char), size) != sizeof(char)*size) + std::size_t size = std::min(static_cast(remainingSize), NAZARA_CORE_FILE_BUFFERSIZE); + if (file.Read(&buffer[0], size) != size) { NazaraError("Unable to read file"); return false; diff --git a/tests/Engine/Core/File.cpp b/tests/Engine/Core/File.cpp index ae29407cb..c00af74d1 100644 --- a/tests/Engine/Core/File.cpp +++ b/tests/Engine/Core/File.cpp @@ -17,7 +17,7 @@ SCENARIO("File", "[CORE][FILE]") Nz::ByteArray byteArray(message, 11); file.Write("Test String"); file.Write(byteArray); - file.Write(message, sizeof(char), 11); + file.Write(message, 11); } AND_THEN("We can retrieve 3 times 'Test String'") @@ -27,7 +27,7 @@ SCENARIO("File", "[CORE][FILE]") message[11] = '\0'; REQUIRE(Nz::String(message) == "Test String"); - REQUIRE(file.Read(message, sizeof(char), 11) == 11); + REQUIRE(file.Read(message, 11) == 11); message[11] = '\0'; REQUIRE(Nz::String(message) == "Test String"); } From bc4eb96af21123c03785157f18bee3a4618c8637 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 19 Nov 2015 12:30:30 +0100 Subject: [PATCH 67/97] Core/File: Fix StreamOption_Text staying if reopened Former-commit-id: b5d73fb753b8c38aa088ed793791efbbdbb404b5 --- src/Nazara/Core/File.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index 7ad8669e0..c84fff7b9 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -261,6 +261,8 @@ namespace Nz if (m_openMode & OpenMode_Text) m_streamOptions |= StreamOption_Text; + else + m_streamOptions &= ~StreamOption_Text; return true; } From 1c8a09f90c09bfa64ea6f50bf743a99204ec4e80 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 19 Nov 2015 13:25:07 +0100 Subject: [PATCH 68/97] Core: Replace serialization arguments by context structures Also fixed some endianness errors Former-commit-id: 450849e681a9b002c3d501a856a8481470d08dea --- include/Nazara/Core/Algorithm.hpp | 11 ++++--- include/Nazara/Core/Algorithm.inl | 39 +++++++++--------------- include/Nazara/Core/InputStream.hpp | 8 +++++ include/Nazara/Core/InputStream.inl | 43 ++++++++++++++++++++++++++- include/Nazara/Core/OutputStream.hpp | 8 +++++ include/Nazara/Core/OutputStream.inl | 43 ++++++++++++++++++++++++++- include/Nazara/Core/Serialization.hpp | 34 +++++++++++++++++++++ include/Nazara/Core/String.hpp | 12 ++++---- src/Nazara/Core/String.cpp | 12 ++++---- 9 files changed, 164 insertions(+), 46 deletions(-) create mode 100644 include/Nazara/Core/Serialization.hpp diff --git a/include/Nazara/Core/Algorithm.hpp b/include/Nazara/Core/Algorithm.hpp index 2f4d770d0..cbbd8af04 100644 --- a/include/Nazara/Core/Algorithm.hpp +++ b/include/Nazara/Core/Algorithm.hpp @@ -9,8 +9,7 @@ #include #include -#include -#include +#include #include #include #include @@ -29,15 +28,15 @@ namespace Nz template struct TypeTag {}; - inline bool Serialize(OutputStream* output, bool value, Endianness dataEndianness); + inline bool Serialize(SerializationContext& context, bool value); template - std::enable_if_t::value, bool> Serialize(OutputStream* output, T value, Endianness dataEndianness); + std::enable_if_t::value, bool> Serialize(SerializationContext& context, T value); - inline bool Unserialize(InputStream* input, bool* value, Endianness dataEndianness); + inline bool Unserialize(UnserializationContext& context, bool* value); template - std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value, Endianness dataEndianness); + std::enable_if_t::value, bool> Unserialize(UnserializationContext& context, T* value); } #include diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 6fed14897..4c2f81f7e 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -8,6 +8,8 @@ #include #include +#include +#include #include namespace Nz @@ -77,40 +79,28 @@ namespace Nz seed = static_cast(b * kMul); } - inline bool Serialize(OutputStream* output, bool value, Endianness dataEndianness) + inline bool Serialize(SerializationContext& context, bool value) { - NazaraAssert(output, "Invalid stream"); - NazaraUnused(dataEndianness); - ///TODO: Handle bits writing (Serializing 8 bits should only use one byte) UInt8 buffer = (value) ? 1 : 0; - return output->Write(&buffer, 1) == 1; + return context.stream->Write(&buffer, 1) == 1; } template - std::enable_if_t::value, bool> Serialize(OutputStream* output, T value, Endianness dataEndianness) + std::enable_if_t::value, bool> Serialize(SerializationContext& context, T value) { - NazaraAssert(output, "Invalid stream"); + if (context.endianness != Endianness_Unknown && context.endianness != GetPlatformEndianness()) + SwapBytes(&value, sizeof(T)); - if (output->Write(&value, sizeof(T)) == sizeof(T)) - { - if (dataEndianness != Endianness_Unknown && dataEndianness != GetPlatformEndianness()) - SwapBytes(&value, sizeof(T)); - - return true; - } - else - return false; + return context.stream->Write(&value, sizeof(T)) == sizeof(T); } - inline bool Unserialize(InputStream* input, bool* value, Endianness dataEndianness) + inline bool Unserialize(UnserializationContext& context, bool* value) { - NazaraAssert(input, "Invalid stream"); NazaraAssert(value, "Invalid data pointer"); - NazaraUnused(dataEndianness); UInt8 buffer; - if (input->Read(&buffer, 1) == 1) + if (context.stream->Read(&buffer, 1) == 1) { *value = (buffer == 1); return true; @@ -120,15 +110,14 @@ namespace Nz } template - std::enable_if_t::value, bool> Unserialize(InputStream* input, T* value, Endianness dataEndianness) + std::enable_if_t::value, bool> Unserialize(UnserializationContext& context, T* value) { - NazaraAssert(input, "Invalid stream"); NazaraAssert(value, "Invalid data pointer"); - if (input->Read(value, sizeof(T)) == sizeof(T)) + if (context.stream->Read(value, sizeof(T)) == sizeof(T)) { - if (dataEndianness != Endianness_Unknown && dataEndianness != GetPlatformEndianness()) - SwapBytes(&value, sizeof(T)); + if (context.endianness != Endianness_Unknown && context.endianness != GetPlatformEndianness()) + SwapBytes(value, sizeof(T)); return true; } diff --git a/include/Nazara/Core/InputStream.hpp b/include/Nazara/Core/InputStream.hpp index f431afe14..19555cac4 100644 --- a/include/Nazara/Core/InputStream.hpp +++ b/include/Nazara/Core/InputStream.hpp @@ -8,6 +8,7 @@ #define NAZARA_INPUTSTREAM_HPP #include +#include #include namespace Nz @@ -15,6 +16,8 @@ namespace Nz class NAZARA_CORE_API InputStream : virtual public Stream { public: + inline InputStream(const InputStream& stream); + inline InputStream(InputStream&& stream) noexcept; virtual ~InputStream(); virtual bool EndOfStream() const = 0; @@ -27,8 +30,13 @@ namespace Nz template InputStream& operator>>(T& value); + inline InputStream& operator=(const InputStream& stream); + inline InputStream& operator=(InputStream&& stream) noexcept; + protected: inline InputStream(); + + UnserializationContext m_unserializationContext; }; } diff --git a/include/Nazara/Core/InputStream.inl b/include/Nazara/Core/InputStream.inl index 4e8abe925..00d1e2131 100644 --- a/include/Nazara/Core/InputStream.inl +++ b/include/Nazara/Core/InputStream.inl @@ -3,20 +3,61 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include +#include namespace Nz { inline InputStream::InputStream() : Stream(OpenMode_Current) { + m_unserializationContext.stream = this; + } + + inline InputStream::InputStream(const InputStream& stream) : + Stream(stream), + m_unserializationContext(stream.m_unserializationContext) + { + m_unserializationContext.stream = this; + } + + inline InputStream::InputStream(InputStream&& stream) noexcept : + Stream(std::move(stream)), + m_unserializationContext(std::move(stream.m_unserializationContext)) + { + m_unserializationContext.stream = this; } template InputStream& InputStream::operator>>(T& value) { - if (!Unserialize(this, &value, m_dataEndianness)) + m_unserializationContext.endianness = m_dataEndianness; //< In case m_dataEndianness changed + + if (!Unserialize(m_unserializationContext, &value)) NazaraError("Failed to unserialize value"); return *this; } + + inline InputStream& InputStream::operator=(const InputStream& stream) + { + Stream::operator=(stream); + + m_unserializationContext = stream.m_unserializationContext; + m_unserializationContext.stream = this; + + return *this; + } + + inline InputStream& InputStream::operator=(InputStream&& stream) noexcept + { + Stream::operator=(std::move(stream)); + + m_unserializationContext = std::move(stream.m_unserializationContext); + m_unserializationContext.stream = this; + + return *this; + } } + +#include diff --git a/include/Nazara/Core/OutputStream.hpp b/include/Nazara/Core/OutputStream.hpp index 6ace7e403..47e7c4bde 100644 --- a/include/Nazara/Core/OutputStream.hpp +++ b/include/Nazara/Core/OutputStream.hpp @@ -8,6 +8,7 @@ #define NAZARA_OUTPUTSTREAM_HPP #include +#include #include namespace Nz @@ -18,6 +19,8 @@ namespace Nz class NAZARA_CORE_API OutputStream : virtual public Stream { public: + inline OutputStream(const OutputStream& stream); + inline OutputStream(OutputStream&& stream) noexcept; virtual ~OutputStream(); virtual void Flush() = 0; @@ -29,8 +32,13 @@ namespace Nz template OutputStream& operator<<(const T& value); + inline OutputStream& operator=(const OutputStream& stream); + inline OutputStream& operator=(OutputStream&& stream) noexcept; + protected: inline OutputStream(); + + SerializationContext m_serializationContext; }; } diff --git a/include/Nazara/Core/OutputStream.inl b/include/Nazara/Core/OutputStream.inl index 95f0f03e0..3d8cbb65a 100644 --- a/include/Nazara/Core/OutputStream.inl +++ b/include/Nazara/Core/OutputStream.inl @@ -3,20 +3,61 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include +#include namespace Nz { inline OutputStream::OutputStream() : Stream(OpenMode_Current) { + m_serializationContext.stream = this; + } + + inline OutputStream::OutputStream(const OutputStream& stream) : + Stream(stream), + m_serializationContext(stream.m_serializationContext) + { + m_serializationContext.stream = this; + } + + inline OutputStream::OutputStream(OutputStream&& stream) noexcept : + Stream(std::move(stream)), + m_serializationContext(std::move(stream.m_serializationContext)) + { + m_serializationContext.stream = this; } template OutputStream& OutputStream::operator<<(const T& value) { - if (!Serialize(this, value, m_dataEndianness)) + m_serializationContext.endianness = m_dataEndianness; //< In case m_dataEndianness changed + + if (!Serialize(m_serializationContext, value)) NazaraError("Failed to serialize value"); return *this; } + + inline OutputStream& OutputStream::operator=(const OutputStream& stream) + { + Stream::operator=(stream); + + m_serializationContext = stream.m_serializationContext; + m_serializationContext.stream = this; + + return *this; + } + + inline OutputStream& OutputStream::operator=(OutputStream&& stream) noexcept + { + Stream::operator=(std::move(stream)); + + m_serializationContext = std::move(stream.m_serializationContext); + m_serializationContext.stream = this; + + return *this; + } } + +#include diff --git a/include/Nazara/Core/Serialization.hpp b/include/Nazara/Core/Serialization.hpp new file mode 100644 index 000000000..fc82cc0c7 --- /dev/null +++ b/include/Nazara/Core/Serialization.hpp @@ -0,0 +1,34 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_SERIALIZATION_HPP +#define NAZARA_SERIALIZATION_HPP + +#include +#include +#include +#include +#include + +namespace Nz +{ + class InputStream; + class OutputStream; + + struct SerializationContext + { + OutputStream* stream; + Endianness endianness; + }; + + struct UnserializationContext + { + InputStream* stream; + Endianness endianness; + }; +} + +#endif // NAZARA_SERIALIZATION_HPP diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 17ef58aab..7bfb21e5b 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -17,11 +18,6 @@ namespace Nz { - class AbstractHash; - class HashDigest; - class InputStream; - class OutputStream; - class NAZARA_CORE_API String { public: @@ -326,9 +322,11 @@ namespace Nz }; }; + class AbstractHash; + inline bool HashAppend(AbstractHash* hash, const String& string); - NAZARA_CORE_API bool Serialize(OutputStream* output, const String& string, Endianness dataEndianness); - NAZARA_CORE_API bool Unserialize(InputStream* input, String* string, Endianness dataEndianness); + NAZARA_CORE_API bool Serialize(SerializationContext& context, const String& string); + NAZARA_CORE_API bool Unserialize(UnserializationContext& context, String* string); } namespace std diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 6ad60a3cb..b81facd2e 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -4209,23 +4209,23 @@ namespace Nz return emptyString; } - bool Serialize(OutputStream* output, const String& string, Endianness dataEndianness) + bool Serialize(SerializationContext& context, const String& string) { - if (!Serialize(output, string.GetSize(), dataEndianness)) + if (!Serialize(context, string.GetSize())) return false; - output->Write(string.GetConstBuffer(), string.GetSize()); + context.stream->Write(string.GetConstBuffer(), string.GetSize()); return true; } - bool Unserialize(InputStream* input, String* string, Endianness dataEndianness) + bool Unserialize(UnserializationContext& context, String* string) { UInt32 size; - if (!Unserialize(input, &size, dataEndianness)) + if (!Unserialize(context, &size)) return false; string->Resize(size); - input->Read(string->GetBuffer(), size); + context.stream->Read(string->GetBuffer(), size); return true; } From 11f85ab9bb26c498376a780f39ffd1c30a7e3e97 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 19 Nov 2015 13:57:39 +0100 Subject: [PATCH 69/97] Core/MemoryStream: Add default constructor and getters Former-commit-id: dde0bbc7e697512d94275a807e18299eb271197e --- include/Nazara/Core/MemoryStream.hpp | 9 ++++++-- src/Nazara/Core/MemoryStream.cpp | 33 +++++++++++++++++++++++----- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/include/Nazara/Core/MemoryStream.hpp b/include/Nazara/Core/MemoryStream.hpp index 30c2fa58a..465abf745 100644 --- a/include/Nazara/Core/MemoryStream.hpp +++ b/include/Nazara/Core/MemoryStream.hpp @@ -8,24 +8,29 @@ #define NAZARA_MEMORYSTREAM_HPP #include +#include #include #include -#include namespace Nz { class NAZARA_CORE_API MemoryStream : public InputStream, public OutputStream { public: + MemoryStream(); MemoryStream(const void* ptr, unsigned int size); MemoryStream(const MemoryStream&) = default; MemoryStream(MemoryStream&&) = default; ~MemoryStream() = default; + void Clear(); + bool EndOfStream() const override; void Flush() override; + const ByteArray& GetBuffer() const; + const UInt8* GetData() const; UInt64 GetCursorPos() const override; UInt64 GetSize() const override; @@ -39,7 +44,7 @@ namespace Nz MemoryStream& operator=(MemoryStream&&) = default; private: - std::vector m_buffer; + ByteArray m_buffer; UInt64 m_pos; }; } diff --git a/src/Nazara/Core/MemoryStream.cpp b/src/Nazara/Core/MemoryStream.cpp index 99aa04b26..0bd11573b 100644 --- a/src/Nazara/Core/MemoryStream.cpp +++ b/src/Nazara/Core/MemoryStream.cpp @@ -9,12 +9,23 @@ namespace Nz { - MemoryStream::MemoryStream(const void* ptr, unsigned int size) : + MemoryStream::MemoryStream() : Stream(OpenMode_ReadWrite), m_pos(0) { - m_buffer.resize(size); - std::memcpy(m_buffer.data(), ptr, size); + } + + MemoryStream::MemoryStream(const void* ptr, unsigned int size) : + MemoryStream() + { + m_buffer.Resize(size); + std::memcpy(m_buffer.GetBuffer(), ptr, size); + } + + void MemoryStream::Clear() + { + m_buffer.Clear(); + m_pos = 0; } bool MemoryStream::EndOfStream() const @@ -27,11 +38,21 @@ namespace Nz // Nothing to flush } + const ByteArray& MemoryStream::GetBuffer() const + { + return m_buffer; + } + UInt64 MemoryStream::GetCursorPos() const { return m_pos; } + const UInt8* MemoryStream::GetData() const + { + return m_buffer.GetConstBuffer(); + } + UInt64 MemoryStream::GetSize() const { return m_buffer.size(); @@ -42,7 +63,7 @@ namespace Nz std::size_t readSize = std::min(size, static_cast(m_buffer.size() - m_pos)); if (buffer) - std::memcpy(buffer, m_buffer.data() + m_pos, readSize); + std::memcpy(buffer, m_buffer.GetBuffer() + m_pos, readSize); m_pos += readSize; return readSize; @@ -59,9 +80,9 @@ namespace Nz { std::size_t endPos = static_cast(m_pos + size); if (endPos > m_buffer.size()) - m_buffer.resize(endPos); + m_buffer.Resize(endPos); - std::memcpy(m_buffer.data(), buffer, size); + std::memcpy(m_buffer.GetBuffer(), buffer, size); m_pos = endPos; return size; From 35b27bbe676534a62d85c392d52dc4b025d2e6f6 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 19 Nov 2015 14:03:26 +0100 Subject: [PATCH 70/97] Core/MemoryStream: Add hash overload for MemoryStream Former-commit-id: ab618e0db87bd85994a3b11a29c7f38e28d8aae3 --- include/Nazara/Core/MemoryStream.hpp | 8 ++++++++ include/Nazara/Core/MemoryStream.inl | 15 +++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 include/Nazara/Core/MemoryStream.inl diff --git a/include/Nazara/Core/MemoryStream.hpp b/include/Nazara/Core/MemoryStream.hpp index 465abf745..861d28d40 100644 --- a/include/Nazara/Core/MemoryStream.hpp +++ b/include/Nazara/Core/MemoryStream.hpp @@ -47,6 +47,14 @@ namespace Nz ByteArray m_buffer; UInt64 m_pos; }; + + class AbstractHash; + + inline bool HashAppend(AbstractHash* hash, const String& string); + NAZARA_CORE_API bool Serialize(SerializationContext& context, const String& string); + NAZARA_CORE_API bool Unserialize(UnserializationContext& context, String* string); } +#include + #endif // NAZARA_MEMORYSTREAM_HPP diff --git a/include/Nazara/Core/MemoryStream.inl b/include/Nazara/Core/MemoryStream.inl new file mode 100644 index 000000000..61b2f0bb4 --- /dev/null +++ b/include/Nazara/Core/MemoryStream.inl @@ -0,0 +1,15 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include + +namespace Nz +{ + inline bool HashAppend(AbstractHash* hash, const MemoryStream& stream) + { + return HashAppend(hash, stream.GetBuffer()); + } +} + +#include From a47e5633d456ca199c6dc4cc5a4c42519409a146 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 19 Nov 2015 14:04:00 +0100 Subject: [PATCH 71/97] Core/String: Fix (Un)Serialize not checking string read/write Former-commit-id: 8d6f907fcaf20374b713851a102dfc4b0003a39d --- src/Nazara/Core/String.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index b81facd2e..33656ef95 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -4214,8 +4214,7 @@ namespace Nz if (!Serialize(context, string.GetSize())) return false; - context.stream->Write(string.GetConstBuffer(), string.GetSize()); - return true; + return context.stream->Write(string.GetConstBuffer(), string.GetSize()) == string.GetSize(); } bool Unserialize(UnserializationContext& context, String* string) @@ -4225,8 +4224,7 @@ namespace Nz return false; string->Resize(size); - context.stream->Read(string->GetBuffer(), size); - return true; + return context.stream->Read(string->GetBuffer(), size) == size; } const unsigned int String::npos(std::numeric_limits::max()); From ed961f5ba8194ad60f6d579c9dea45042b7fd39a Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 20 Nov 2015 13:52:49 +0100 Subject: [PATCH 72/97] Core: Merge InputStream and OutputStream to Stream Remove serialization support from Stream Former-commit-id: 7a761e4fcd07cab561f13e4709c4492ed18da88a --- include/Nazara/Audio/Music.hpp | 2 +- include/Nazara/Audio/Sound.hpp | 2 +- include/Nazara/Audio/SoundBuffer.hpp | 4 +- include/Nazara/Audio/SoundEmitter.hpp | 1 - include/Nazara/Core.hpp | 2 - include/Nazara/Core/Algorithm.inl | 3 +- include/Nazara/Core/ByteArray.inl | 7 ++ include/Nazara/Core/Enums.hpp | 6 +- include/Nazara/Core/File.hpp | 15 ++- include/Nazara/Core/InputStream.hpp | 45 --------- include/Nazara/Core/InputStream.inl | 63 ------------ include/Nazara/Core/MemoryStream.hpp | 16 ++-- include/Nazara/Core/MemoryView.hpp | 10 +- include/Nazara/Core/OutputStream.hpp | 47 --------- include/Nazara/Core/OutputStream.inl | 63 ------------ include/Nazara/Core/ResourceLoader.hpp | 8 +- include/Nazara/Core/ResourceLoader.inl | 4 +- include/Nazara/Core/Serialization.hpp | 7 +- include/Nazara/Core/Stream.hpp | 26 ++++- include/Nazara/Core/Stream.inl | 44 +++++++-- include/Nazara/Graphics/Material.hpp | 2 +- include/Nazara/Graphics/Model.hpp | 2 +- include/Nazara/Graphics/SkeletalModel.hpp | 2 +- include/Nazara/Lua/LuaInstance.hpp | 4 +- include/Nazara/Renderer/Texture.hpp | 8 +- include/Nazara/Utility/Animation.hpp | 2 +- include/Nazara/Utility/Font.hpp | 2 +- .../Nazara/Utility/Formats/MD5AnimParser.hpp | 6 +- .../Nazara/Utility/Formats/MD5MeshParser.hpp | 6 +- include/Nazara/Utility/Formats/MTLParser.hpp | 6 +- include/Nazara/Utility/Formats/OBJParser.hpp | 6 +- include/Nazara/Utility/Image.hpp | 8 +- include/Nazara/Utility/Mesh.hpp | 4 +- src/Nazara/Audio/Formats/sndfileLoader.cpp | 22 ++--- src/Nazara/Audio/Music.cpp | 2 +- src/Nazara/Audio/Sound.cpp | 2 +- src/Nazara/Audio/SoundBuffer.cpp | 2 +- src/Nazara/Core/File.cpp | 96 +++++++++---------- src/Nazara/Core/InputStream.cpp | 71 -------------- src/Nazara/Core/MemoryStream.cpp | 28 +++--- src/Nazara/Core/MemoryView.cpp | 21 +++- src/Nazara/Core/OutputStream.cpp | 40 -------- src/Nazara/Core/Stream.cpp | 84 ++++++++++++++++ src/Nazara/Graphics/Formats/MeshLoader.cpp | 8 +- src/Nazara/Graphics/Formats/OBJLoader.cpp | 4 +- src/Nazara/Graphics/Formats/TextureLoader.cpp | 4 +- src/Nazara/Graphics/Material.cpp | 2 +- src/Nazara/Graphics/Model.cpp | 2 +- src/Nazara/Graphics/SkeletalModel.cpp | 2 +- src/Nazara/Lua/LuaInstance.cpp | 4 +- src/Nazara/Renderer/Texture.cpp | 8 +- src/Nazara/Utility/Animation.cpp | 2 +- src/Nazara/Utility/Font.cpp | 2 +- src/Nazara/Utility/Formats/DDSLoader.cpp | 6 +- src/Nazara/Utility/Formats/FreeTypeLoader.cpp | 12 +-- src/Nazara/Utility/Formats/MD2Loader.cpp | 6 +- src/Nazara/Utility/Formats/MD5AnimLoader.cpp | 4 +- src/Nazara/Utility/Formats/MD5AnimParser.cpp | 10 +- src/Nazara/Utility/Formats/MD5MeshLoader.cpp | 4 +- src/Nazara/Utility/Formats/MD5MeshParser.cpp | 10 +- src/Nazara/Utility/Formats/MTLParser.cpp | 10 +- src/Nazara/Utility/Formats/OBJParser.cpp | 10 +- src/Nazara/Utility/Formats/PCXLoader.cpp | 6 +- src/Nazara/Utility/Formats/STBLoader.cpp | 12 +-- src/Nazara/Utility/Image.cpp | 6 +- src/Nazara/Utility/Mesh.cpp | 2 +- 66 files changed, 372 insertions(+), 565 deletions(-) delete mode 100644 include/Nazara/Core/InputStream.hpp delete mode 100644 include/Nazara/Core/InputStream.inl delete mode 100644 include/Nazara/Core/OutputStream.hpp delete mode 100644 include/Nazara/Core/OutputStream.inl delete mode 100644 src/Nazara/Core/InputStream.cpp delete mode 100644 src/Nazara/Core/OutputStream.cpp diff --git a/include/Nazara/Audio/Music.hpp b/include/Nazara/Audio/Music.hpp index b8b17956e..50935ac79 100644 --- a/include/Nazara/Audio/Music.hpp +++ b/include/Nazara/Audio/Music.hpp @@ -55,7 +55,7 @@ namespace Nz bool OpenFromFile(const String& filePath, const MusicParams& params = MusicParams()); bool OpenFromMemory(const void* data, std::size_t size, const MusicParams& params = MusicParams()); - bool OpenFromStream(InputStream& stream, const MusicParams& params = MusicParams()); + bool OpenFromStream(Stream& stream, const MusicParams& params = MusicParams()); void Pause(); void Play(); diff --git a/include/Nazara/Audio/Sound.hpp b/include/Nazara/Audio/Sound.hpp index a8de761de..23d6f11bd 100644 --- a/include/Nazara/Audio/Sound.hpp +++ b/include/Nazara/Audio/Sound.hpp @@ -36,7 +36,7 @@ namespace Nz bool LoadFromFile(const String& filePath, const SoundBufferParams& params = SoundBufferParams()); bool LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params = SoundBufferParams()); - bool LoadFromStream(InputStream& stream, const SoundBufferParams& params = SoundBufferParams()); + bool LoadFromStream(Stream& stream, const SoundBufferParams& params = SoundBufferParams()); void Pause(); void Play(); diff --git a/include/Nazara/Audio/SoundBuffer.hpp b/include/Nazara/Audio/SoundBuffer.hpp index 883825524..b144e71ad 100644 --- a/include/Nazara/Audio/SoundBuffer.hpp +++ b/include/Nazara/Audio/SoundBuffer.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include @@ -18,6 +17,7 @@ #include #include #include +#include namespace Nz { @@ -67,7 +67,7 @@ namespace Nz bool LoadFromFile(const String& filePath, const SoundBufferParams& params = SoundBufferParams()); bool LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params = SoundBufferParams()); - bool LoadFromStream(InputStream& stream, const SoundBufferParams& params = SoundBufferParams()); + bool LoadFromStream(Stream& stream, const SoundBufferParams& params = SoundBufferParams()); static bool IsFormatSupported(AudioFormat format); template static SoundBufferRef New(Args&&... args); diff --git a/include/Nazara/Audio/SoundEmitter.hpp b/include/Nazara/Audio/SoundEmitter.hpp index d05045114..d56cd1bca 100644 --- a/include/Nazara/Audio/SoundEmitter.hpp +++ b/include/Nazara/Audio/SoundEmitter.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include ///TODO: Faire hériter SoundEmitter de Node diff --git a/include/Nazara/Core.hpp b/include/Nazara/Core.hpp index 7f16775d8..a1d87c0a2 100644 --- a/include/Nazara/Core.hpp +++ b/include/Nazara/Core.hpp @@ -50,7 +50,6 @@ #include #include #include -#include #include #include #include @@ -62,7 +61,6 @@ #include #include #include -#include #include #include #include diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 4c2f81f7e..6e3d8853a 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -8,8 +8,7 @@ #include #include -#include -#include +#include #include namespace Nz diff --git a/include/Nazara/Core/ByteArray.inl b/include/Nazara/Core/ByteArray.inl index ada835e3e..19d7e115b 100644 --- a/include/Nazara/Core/ByteArray.inl +++ b/include/Nazara/Core/ByteArray.inl @@ -59,6 +59,13 @@ namespace Nz return m_array.back(); } + inline void ByteArray::Clear(bool keepBuffer) + { + m_array.clear(); + if (!keepBuffer) + m_array.shrink_to_fit(); + } + inline ByteArray::iterator ByteArray::Erase(const_iterator pos) { return m_array.erase(pos); diff --git a/include/Nazara/Core/Enums.hpp b/include/Nazara/Core/Enums.hpp index 02c92af35..a5de16a44 100644 --- a/include/Nazara/Core/Enums.hpp +++ b/include/Nazara/Core/Enums.hpp @@ -80,11 +80,12 @@ namespace Nz OpenMode_Append = 0x01, // Empêche l'écriture sur la partie déjà existante et met le curseur à la fin OpenMode_Lock = 0x02, // Empêche le fichier d'être modifié tant qu'il est ouvert OpenMode_ReadOnly = 0x04, // Ouvre uniquement en lecture - OpenMode_ReadWrite = 0x08, // Ouvre en lecture/écriture OpenMode_Text = 0x10, // Ouvre en mode texte OpenMode_Truncate = 0x20, // Créé le fichier s'il n'existe pas et le vide s'il existe OpenMode_WriteOnly = 0x40, // Ouvre uniquement en écriture, créé le fichier s'il n'existe pas + OpenMode_ReadWrite = OpenMode_ReadOnly | OpenMode_WriteOnly, // Ouvre en lecture/écriture + OpenMode_Max = OpenMode_WriteOnly }; @@ -173,7 +174,8 @@ namespace Nz { StreamOption_None = 0, - StreamOption_Text = 0x1, + StreamOption_Sequential = 0x1, + StreamOption_Text = 0x2, StreamOption_Max = StreamOption_Text*2-1 }; diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index d0a66e09c..02ecb153a 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -11,8 +11,7 @@ #include #include #include -#include -#include +#include #include #if NAZARA_CORE_THREADSAFE && NAZARA_THREADSAFETY_FILE @@ -27,7 +26,7 @@ namespace Nz { class FileImpl; - class NAZARA_CORE_API File : public InputStream, public OutputStream + class NAZARA_CORE_API File : public Stream { public: File(); @@ -47,8 +46,6 @@ namespace Nz bool Exists() const; - void Flush() override; - time_t GetCreationTime() const; UInt64 GetCursorPos() const override; String GetDirectory() const override; @@ -63,16 +60,12 @@ namespace Nz bool Open(unsigned int openMode = OpenMode_Current); bool Open(const String& filePath, unsigned int openMode = OpenMode_Current); - std::size_t Read(void* buffer, std::size_t size) override; bool Rename(const String& newFilePath); bool SetCursorPos(CursorPosition pos, Int64 offset = 0); bool SetCursorPos(UInt64 offset) override; bool SetFile(const String& filePath); - using OutputStream::Write; - std::size_t Write(const void* buffer, std::size_t size) override; - File& operator=(const String& filePath); File& operator=(const File&) = delete; File& operator=(File&& file) noexcept; @@ -96,6 +89,10 @@ namespace Nz private: NazaraMutexAttrib(m_mutex, mutable) + void FlushStream() override; + std::size_t ReadBlock(void* buffer, std::size_t size) override; + std::size_t WriteBlock(const void* buffer, std::size_t size) override; + String m_filePath; FileImpl* m_impl; }; diff --git a/include/Nazara/Core/InputStream.hpp b/include/Nazara/Core/InputStream.hpp deleted file mode 100644 index 19555cac4..000000000 --- a/include/Nazara/Core/InputStream.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_INPUTSTREAM_HPP -#define NAZARA_INPUTSTREAM_HPP - -#include -#include -#include - -namespace Nz -{ - class NAZARA_CORE_API InputStream : virtual public Stream - { - public: - inline InputStream(const InputStream& stream); - inline InputStream(InputStream&& stream) noexcept; - virtual ~InputStream(); - - virtual bool EndOfStream() const = 0; - - virtual UInt64 GetSize() const = 0; - - virtual std::size_t Read(void* buffer, std::size_t size) = 0; - virtual String ReadLine(unsigned int lineSize = 0); - - template - InputStream& operator>>(T& value); - - inline InputStream& operator=(const InputStream& stream); - inline InputStream& operator=(InputStream&& stream) noexcept; - - protected: - inline InputStream(); - - UnserializationContext m_unserializationContext; - }; -} - -#include - -#endif // NAZARA_INPUTSTREAM_HPP diff --git a/include/Nazara/Core/InputStream.inl b/include/Nazara/Core/InputStream.inl deleted file mode 100644 index 00d1e2131..000000000 --- a/include/Nazara/Core/InputStream.inl +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include - -namespace Nz -{ - inline InputStream::InputStream() : - Stream(OpenMode_Current) - { - m_unserializationContext.stream = this; - } - - inline InputStream::InputStream(const InputStream& stream) : - Stream(stream), - m_unserializationContext(stream.m_unserializationContext) - { - m_unserializationContext.stream = this; - } - - inline InputStream::InputStream(InputStream&& stream) noexcept : - Stream(std::move(stream)), - m_unserializationContext(std::move(stream.m_unserializationContext)) - { - m_unserializationContext.stream = this; - } - - template - InputStream& InputStream::operator>>(T& value) - { - m_unserializationContext.endianness = m_dataEndianness; //< In case m_dataEndianness changed - - if (!Unserialize(m_unserializationContext, &value)) - NazaraError("Failed to unserialize value"); - - return *this; - } - - inline InputStream& InputStream::operator=(const InputStream& stream) - { - Stream::operator=(stream); - - m_unserializationContext = stream.m_unserializationContext; - m_unserializationContext.stream = this; - - return *this; - } - - inline InputStream& InputStream::operator=(InputStream&& stream) noexcept - { - Stream::operator=(std::move(stream)); - - m_unserializationContext = std::move(stream.m_unserializationContext); - m_unserializationContext.stream = this; - - return *this; - } -} - -#include diff --git a/include/Nazara/Core/MemoryStream.hpp b/include/Nazara/Core/MemoryStream.hpp index 861d28d40..7328b7707 100644 --- a/include/Nazara/Core/MemoryStream.hpp +++ b/include/Nazara/Core/MemoryStream.hpp @@ -9,12 +9,11 @@ #include #include -#include -#include +#include namespace Nz { - class NAZARA_CORE_API MemoryStream : public InputStream, public OutputStream + class NAZARA_CORE_API MemoryStream : public Stream { public: MemoryStream(); @@ -27,23 +26,22 @@ namespace Nz bool EndOfStream() const override; - void Flush() override; const ByteArray& GetBuffer() const; const UInt8* GetData() const; UInt64 GetCursorPos() const override; UInt64 GetSize() const override; - std::size_t Read(void* buffer, std::size_t size) override; - bool SetCursorPos(UInt64 offset) override; - std::size_t Write(const void* buffer, std::size_t size) override; - MemoryStream& operator=(const MemoryStream&) = default; MemoryStream& operator=(MemoryStream&&) = default; private: + void FlushStream() override; + std::size_t ReadBlock(void* buffer, std::size_t size) override; + std::size_t WriteBlock(const void* buffer, std::size_t size) override; + ByteArray m_buffer; UInt64 m_pos; }; @@ -55,6 +53,6 @@ namespace Nz NAZARA_CORE_API bool Unserialize(UnserializationContext& context, String* string); } -#include +#include #endif // NAZARA_MEMORYSTREAM_HPP diff --git a/include/Nazara/Core/MemoryView.hpp b/include/Nazara/Core/MemoryView.hpp index 47fdc87f0..e746ef47a 100644 --- a/include/Nazara/Core/MemoryView.hpp +++ b/include/Nazara/Core/MemoryView.hpp @@ -8,11 +8,11 @@ #define NAZARA_MEMORYVIEW_HPP #include -#include +#include namespace Nz { - class NAZARA_CORE_API MemoryView : public InputStream + class NAZARA_CORE_API MemoryView : public Stream { public: MemoryView(const void* ptr, UInt64 size); @@ -25,14 +25,16 @@ namespace Nz UInt64 GetCursorPos() const override; UInt64 GetSize() const override; - std::size_t Read(void* buffer, std::size_t size) override; - bool SetCursorPos(UInt64 offset) override; MemoryView& operator=(const MemoryView&) = delete; MemoryView& operator=(MemoryView&&) = delete; ///TODO private: + void FlushStream() override; + std::size_t ReadBlock(void* buffer, std::size_t size) override; + std::size_t WriteBlock(const void* buffer, std::size_t size) override; + const UInt8* m_ptr; UInt64 m_pos; UInt64 m_size; diff --git a/include/Nazara/Core/OutputStream.hpp b/include/Nazara/Core/OutputStream.hpp deleted file mode 100644 index 47e7c4bde..000000000 --- a/include/Nazara/Core/OutputStream.hpp +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_OUTPUTSTREAM_HPP -#define NAZARA_OUTPUTSTREAM_HPP - -#include -#include -#include - -namespace Nz -{ - class ByteArray; - class String; - - class NAZARA_CORE_API OutputStream : virtual public Stream - { - public: - inline OutputStream(const OutputStream& stream); - inline OutputStream(OutputStream&& stream) noexcept; - virtual ~OutputStream(); - - virtual void Flush() = 0; - - bool Write(const ByteArray& byteArray); - bool Write(const String& string); - virtual std::size_t Write(const void* buffer, std::size_t size) = 0; - - template - OutputStream& operator<<(const T& value); - - inline OutputStream& operator=(const OutputStream& stream); - inline OutputStream& operator=(OutputStream&& stream) noexcept; - - protected: - inline OutputStream(); - - SerializationContext m_serializationContext; - }; -} - -#include - -#endif // NAZARA_OUTPUTSTREAM_HPP diff --git a/include/Nazara/Core/OutputStream.inl b/include/Nazara/Core/OutputStream.inl deleted file mode 100644 index 3d8cbb65a..000000000 --- a/include/Nazara/Core/OutputStream.inl +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include - -namespace Nz -{ - inline OutputStream::OutputStream() : - Stream(OpenMode_Current) - { - m_serializationContext.stream = this; - } - - inline OutputStream::OutputStream(const OutputStream& stream) : - Stream(stream), - m_serializationContext(stream.m_serializationContext) - { - m_serializationContext.stream = this; - } - - inline OutputStream::OutputStream(OutputStream&& stream) noexcept : - Stream(std::move(stream)), - m_serializationContext(std::move(stream.m_serializationContext)) - { - m_serializationContext.stream = this; - } - - template - OutputStream& OutputStream::operator<<(const T& value) - { - m_serializationContext.endianness = m_dataEndianness; //< In case m_dataEndianness changed - - if (!Serialize(m_serializationContext, value)) - NazaraError("Failed to serialize value"); - - return *this; - } - - inline OutputStream& OutputStream::operator=(const OutputStream& stream) - { - Stream::operator=(stream); - - m_serializationContext = stream.m_serializationContext; - m_serializationContext.stream = this; - - return *this; - } - - inline OutputStream& OutputStream::operator=(OutputStream&& stream) noexcept - { - Stream::operator=(std::move(stream)); - - m_serializationContext = std::move(stream.m_serializationContext); - m_serializationContext.stream = this; - - return *this; - } -} - -#include diff --git a/include/Nazara/Core/ResourceLoader.hpp b/include/Nazara/Core/ResourceLoader.hpp index 64d9d81d7..73b2dfa52 100644 --- a/include/Nazara/Core/ResourceLoader.hpp +++ b/include/Nazara/Core/ResourceLoader.hpp @@ -16,7 +16,7 @@ namespace Nz { - class InputStream; + class Stream; template class ResourceLoader @@ -27,8 +27,8 @@ namespace Nz using ExtensionGetter = bool (*)(const String& extension); using FileLoader = bool (*)(Type* resource, const String& filePath, const Parameters& parameters); using MemoryLoader = bool (*)(Type* resource, const void* data, std::size_t size, const Parameters& parameters); - using StreamChecker = Ternary (*)(InputStream& stream, const Parameters& parameters); - using StreamLoader = bool (*)(Type* resource, InputStream& stream, const Parameters& parameters); + using StreamChecker = Ternary (*)(Stream& stream, const Parameters& parameters); + using StreamLoader = bool (*)(Type* resource, Stream& stream, const Parameters& parameters); ResourceLoader() = delete; ~ResourceLoader() = delete; @@ -37,7 +37,7 @@ namespace Nz static bool LoadFromFile(Type* resource, const String& filePath, const Parameters& parameters = Parameters()); static bool LoadFromMemory(Type* resource, const void* data, unsigned int size, const Parameters& parameters = Parameters()); - static bool LoadFromStream(Type* resource, InputStream& stream, const Parameters& parameters = Parameters()); + static bool LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters = Parameters()); static void RegisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr); static void UnregisterLoader(ExtensionGetter extensionGetter, StreamChecker checkFunc, StreamLoader streamLoader, FileLoader fileLoader = nullptr, MemoryLoader memoryLoader = nullptr); diff --git a/include/Nazara/Core/ResourceLoader.inl b/include/Nazara/Core/ResourceLoader.inl index 3f78ca7ff..e3f7c4577 100644 --- a/include/Nazara/Core/ResourceLoader.inl +++ b/include/Nazara/Core/ResourceLoader.inl @@ -5,8 +5,8 @@ #include #include #include -#include #include +#include #include namespace Nz @@ -199,7 +199,7 @@ namespace Nz } template - bool ResourceLoader::LoadFromStream(Type* resource, InputStream& stream, const Parameters& parameters) + bool ResourceLoader::LoadFromStream(Type* resource, Stream& stream, const Parameters& parameters) { #if NAZARA_CORE_SAFE if (!parameters.IsValid()) diff --git a/include/Nazara/Core/Serialization.hpp b/include/Nazara/Core/Serialization.hpp index fc82cc0c7..36e77caea 100644 --- a/include/Nazara/Core/Serialization.hpp +++ b/include/Nazara/Core/Serialization.hpp @@ -15,18 +15,17 @@ namespace Nz { - class InputStream; - class OutputStream; + class Stream; struct SerializationContext { - OutputStream* stream; + Stream* stream; Endianness endianness; }; struct UnserializationContext { - InputStream* stream; + Stream* stream; Endianness endianness; }; } diff --git a/include/Nazara/Core/Stream.hpp b/include/Nazara/Core/Stream.hpp index 0abaaab63..ff4195802 100644 --- a/include/Nazara/Core/Stream.hpp +++ b/include/Nazara/Core/Stream.hpp @@ -13,6 +13,7 @@ namespace Nz { + class ByteArray; class String; //< Do not include String.hpp in this file class NAZARA_CORE_API Stream @@ -22,19 +23,33 @@ namespace Nz Stream(Stream&&) = default; virtual ~Stream(); + virtual bool EndOfStream() const = 0; + + inline void EnableTextMode(bool textMode); + + inline void Flush(); + virtual UInt64 GetCursorPos() const = 0; virtual String GetDirectory() const; virtual String GetPath() const; - inline Endianness GetDataEndianness() const; inline UInt32 GetOpenMode() const; inline UInt32 GetStreamOptions() const; + virtual UInt64 GetSize() const = 0; + + inline std::size_t Read(void* buffer, std::size_t size); + virtual String ReadLine(unsigned int lineSize = 0); + inline bool IsReadable() const; + inline bool IsSequential() const; + inline bool IsTextModeEnabled() const; inline bool IsWritable() const; virtual bool SetCursorPos(UInt64 offset) = 0; - inline void SetDataEndianness(Endianness endiannes); - inline void SetStreamOptions(UInt32 options); + + bool Write(const ByteArray& byteArray); + bool Write(const String& string); + inline std::size_t Write(const void* buffer, std::size_t size); Stream& operator=(const Stream&) = default; Stream& operator=(Stream&&) = default; @@ -42,7 +57,10 @@ namespace Nz protected: inline Stream(UInt32 openMode); - Endianness m_dataEndianness; + virtual void FlushStream() = 0; + virtual std::size_t ReadBlock(void* buffer, std::size_t size) = 0; + virtual std::size_t WriteBlock(const void* buffer, std::size_t size) = 0; + UInt32 m_openMode; UInt32 m_streamOptions; }; diff --git a/include/Nazara/Core/Stream.inl b/include/Nazara/Core/Stream.inl index 4c9bb138f..a7e17a099 100644 --- a/include/Nazara/Core/Stream.inl +++ b/include/Nazara/Core/Stream.inl @@ -2,18 +2,29 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include + namespace Nz { inline Stream::Stream(UInt32 openMode) : - m_dataEndianness(Endianness_Unknown), m_openMode(openMode), m_streamOptions(0) { } - inline Endianness Stream::GetDataEndianness() const + inline void Stream::EnableTextMode(bool textMode) { - return m_dataEndianness; + if (textMode) + m_streamOptions |= StreamOption_Text; + else + m_streamOptions &= ~StreamOption_Text; + } + + inline void Stream::Flush() + { + NazaraAssert(IsWritable(), "Stream is not writable"); + + FlushStream(); } inline UInt32 Stream::GetOpenMode() const @@ -28,21 +39,36 @@ namespace Nz inline bool Stream::IsReadable() const { - return m_openMode & OpenMode_ReadOnly || m_openMode & OpenMode_ReadWrite; + return (m_openMode & OpenMode_ReadOnly) != 0; + } + + inline bool Stream::IsSequential() const + { + return (m_streamOptions & StreamOption_Sequential) != 0; + } + + inline bool Stream::IsTextModeEnabled() const + { + return (m_streamOptions & StreamOption_Text) != 0; } inline bool Stream::IsWritable() const { - return m_openMode & OpenMode_ReadWrite || m_openMode & OpenMode_WriteOnly; + return (m_openMode & OpenMode_WriteOnly) != 0; } - inline void Stream::SetDataEndianness(Endianness endiannes) + inline std::size_t Stream::Read(void* buffer, std::size_t size) { - m_dataEndianness = endiannes; + NazaraAssert(IsReadable(), "Stream is not readable"); + + return ReadBlock(buffer, size); } - inline void Stream::SetStreamOptions(UInt32 options) + inline std::size_t Stream::Write(const void* buffer, std::size_t size) { - m_streamOptions = options; + NazaraAssert(IsWritable(), "Stream is not writable"); + + return WriteBlock(buffer, size); } + } diff --git a/include/Nazara/Graphics/Material.hpp b/include/Nazara/Graphics/Material.hpp index 7e55f285a..8f6cdb920 100644 --- a/include/Nazara/Graphics/Material.hpp +++ b/include/Nazara/Graphics/Material.hpp @@ -106,7 +106,7 @@ namespace Nz bool LoadFromFile(const String& filePath, const MaterialParams& params = MaterialParams()); bool LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params = MaterialParams()); - bool LoadFromStream(InputStream& stream, const MaterialParams& params = MaterialParams()); + bool LoadFromStream(Stream& stream, const MaterialParams& params = MaterialParams()); void Reset(); diff --git a/include/Nazara/Graphics/Model.hpp b/include/Nazara/Graphics/Model.hpp index 2655fdedd..9f7506c12 100644 --- a/include/Nazara/Graphics/Model.hpp +++ b/include/Nazara/Graphics/Model.hpp @@ -58,7 +58,7 @@ namespace Nz bool LoadFromFile(const String& filePath, const ModelParameters& params = ModelParameters()); bool LoadFromMemory(const void* data, std::size_t size, const ModelParameters& params = ModelParameters()); - bool LoadFromStream(InputStream& stream, const ModelParameters& params = ModelParameters()); + bool LoadFromStream(Stream& stream, const ModelParameters& params = ModelParameters()); void Reset(); diff --git a/include/Nazara/Graphics/SkeletalModel.hpp b/include/Nazara/Graphics/SkeletalModel.hpp index 976411133..059d6b835 100644 --- a/include/Nazara/Graphics/SkeletalModel.hpp +++ b/include/Nazara/Graphics/SkeletalModel.hpp @@ -59,7 +59,7 @@ namespace Nz bool LoadFromFile(const String& filePath, const SkeletalModelParameters& params = SkeletalModelParameters()); bool LoadFromMemory(const void* data, std::size_t size, const SkeletalModelParameters& params = SkeletalModelParameters()); - bool LoadFromStream(InputStream& stream, const SkeletalModelParameters& params = SkeletalModelParameters()); + bool LoadFromStream(Stream& stream, const SkeletalModelParameters& params = SkeletalModelParameters()); void Reset(); diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index 2b8b14f84..24e9a4f7d 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -73,7 +73,7 @@ namespace Nz bool Execute(const String& code); bool ExecuteFromFile(const String& filePath); bool ExecuteFromMemory(const void* data, unsigned int size); - bool ExecuteFromStream(InputStream& stream); + bool ExecuteFromStream(Stream& stream); int GetAbsIndex(int index) const; LuaType GetField(const char* fieldName, int index = -1) const; diff --git a/include/Nazara/Renderer/Texture.hpp b/include/Nazara/Renderer/Texture.hpp index 1bf4d9877..15f3c11ec 100644 --- a/include/Nazara/Renderer/Texture.hpp +++ b/include/Nazara/Renderer/Texture.hpp @@ -75,24 +75,24 @@ namespace Nz bool LoadFromFile(const String& filePath, const ImageParams& params = ImageParams(), bool generateMipmaps = true); bool LoadFromImage(const Image& image, bool generateMipmaps = true); bool LoadFromMemory(const void* data, std::size_t size, const ImageParams& params = ImageParams(), bool generateMipmaps = true); - bool LoadFromStream(InputStream& stream, const ImageParams& params = ImageParams(), bool generateMipmaps = true); + bool LoadFromStream(Stream& stream, const ImageParams& params = ImageParams(), bool generateMipmaps = true); // LoadArray bool LoadArrayFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); bool LoadArrayFromImage(const Image& image, bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); bool LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); - bool LoadArrayFromStream(InputStream& stream, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); + bool LoadArrayFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const Vector2ui& atlasSize = Vector2ui(2, 2)); // LoadCubemap bool LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); bool LoadCubemapFromImage(const Image& image, bool generateMipmaps = true, const CubemapParams& params = CubemapParams()); bool LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); - bool LoadCubemapFromStream(InputStream& stream, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); + bool LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), bool generateMipmaps = true, const CubemapParams& cubemapParams = CubemapParams()); // LoadFace bool LoadFaceFromFile(CubemapFace face, const String& filePath, const ImageParams& params = ImageParams()); bool LoadFaceFromMemory(CubemapFace face, const void* data, std::size_t size, const ImageParams& params = ImageParams()); - bool LoadFaceFromStream(CubemapFace face, InputStream& stream, const ImageParams& params = ImageParams()); + bool LoadFaceFromStream(CubemapFace face, Stream& stream, const ImageParams& params = ImageParams()); bool SetMipmapRange(UInt8 minLevel, UInt8 maxLevel); diff --git a/include/Nazara/Utility/Animation.hpp b/include/Nazara/Utility/Animation.hpp index b4f5dde47..162d86e35 100644 --- a/include/Nazara/Utility/Animation.hpp +++ b/include/Nazara/Utility/Animation.hpp @@ -83,7 +83,7 @@ namespace Nz bool LoadFromFile(const String& filePath, const AnimationParams& params = AnimationParams()); bool LoadFromMemory(const void* data, std::size_t size, const AnimationParams& params = AnimationParams()); - bool LoadFromStream(InputStream& stream, const AnimationParams& params = AnimationParams()); + bool LoadFromStream(Stream& stream, const AnimationParams& params = AnimationParams()); void RemoveSequence(const String& sequenceName); void RemoveSequence(unsigned int index); diff --git a/include/Nazara/Utility/Font.hpp b/include/Nazara/Utility/Font.hpp index b515b5c21..ef801d5a2 100644 --- a/include/Nazara/Utility/Font.hpp +++ b/include/Nazara/Utility/Font.hpp @@ -78,7 +78,7 @@ namespace Nz // Open bool OpenFromFile(const String& filePath, const FontParams& params = FontParams()); bool OpenFromMemory(const void* data, std::size_t size, const FontParams& params = FontParams()); - bool OpenFromStream(InputStream& stream, const FontParams& params = FontParams()); + bool OpenFromStream(Stream& stream, const FontParams& params = FontParams()); void SetAtlas(const std::shared_ptr& atlas); void SetGlyphBorder(unsigned int borderSize); diff --git a/include/Nazara/Utility/Formats/MD5AnimParser.hpp b/include/Nazara/Utility/Formats/MD5AnimParser.hpp index 1187ea886..cfba9fdc4 100644 --- a/include/Nazara/Utility/Formats/MD5AnimParser.hpp +++ b/include/Nazara/Utility/Formats/MD5AnimParser.hpp @@ -8,7 +8,7 @@ #define NAZARA_FORMATS_MD5ANIMPARSER_HPP #include -#include +#include #include #include #include @@ -42,7 +42,7 @@ namespace Nz unsigned int index; }; - MD5AnimParser(InputStream& stream); + MD5AnimParser(Stream& stream); ~MD5AnimParser(); Ternary Check(); @@ -69,7 +69,7 @@ namespace Nz std::vector m_animatedComponents; std::vector m_frames; std::vector m_joints; - InputStream& m_stream; + Stream& m_stream; String m_currentLine; bool m_keepLastLine; unsigned int m_frameIndex; diff --git a/include/Nazara/Utility/Formats/MD5MeshParser.hpp b/include/Nazara/Utility/Formats/MD5MeshParser.hpp index 9c9fb3f1a..5d114bdbb 100644 --- a/include/Nazara/Utility/Formats/MD5MeshParser.hpp +++ b/include/Nazara/Utility/Formats/MD5MeshParser.hpp @@ -8,7 +8,7 @@ #define NAZARA_FORMATS_MD5MESHPARSER_HPP #include -#include +#include #include #include #include @@ -52,7 +52,7 @@ namespace Nz String shader; }; - MD5MeshParser(InputStream& stream); + MD5MeshParser(Stream& stream); ~MD5MeshParser(); Ternary Check(); @@ -74,7 +74,7 @@ namespace Nz std::vector m_joints; std::vector m_meshes; - InputStream& m_stream; + Stream& m_stream; String m_currentLine; bool m_keepLastLine; unsigned int m_lineCount; diff --git a/include/Nazara/Utility/Formats/MTLParser.hpp b/include/Nazara/Utility/Formats/MTLParser.hpp index f9b6ede5a..d58148ec7 100644 --- a/include/Nazara/Utility/Formats/MTLParser.hpp +++ b/include/Nazara/Utility/Formats/MTLParser.hpp @@ -9,7 +9,7 @@ #include #include -#include +#include #include #include #include @@ -39,7 +39,7 @@ namespace Nz unsigned int illumModel = 0; }; - MTLParser(InputStream& stream$); + MTLParser(Stream& stream$); ~MTLParser(); const Material* GetMaterial(const String& materialName) const; @@ -54,7 +54,7 @@ namespace Nz void UnrecognizedLine(bool error = false); std::unordered_map m_materials; - InputStream& m_stream; + Stream& m_stream; String m_currentLine; bool m_keepLastLine; unsigned int m_lineCount; diff --git a/include/Nazara/Utility/Formats/OBJParser.hpp b/include/Nazara/Utility/Formats/OBJParser.hpp index 7546db7bd..3decd248f 100644 --- a/include/Nazara/Utility/Formats/OBJParser.hpp +++ b/include/Nazara/Utility/Formats/OBJParser.hpp @@ -8,7 +8,7 @@ #define NAZARA_FORMATS_OBJPARSER_HPP #include -#include +#include #include #include #include @@ -39,7 +39,7 @@ namespace Nz unsigned int material; }; - OBJParser(InputStream& stream$); + OBJParser(Stream& stream$); ~OBJParser(); const String* GetMaterials() const; @@ -67,7 +67,7 @@ namespace Nz std::vector m_normals; std::vector m_positions; std::vector m_texCoords; - InputStream& m_stream; + Stream& m_stream; String m_currentLine; String m_mtlLib; bool m_keepLastLine; diff --git a/include/Nazara/Utility/Image.hpp b/include/Nazara/Utility/Image.hpp index 794ef9ff4..ed9772a88 100644 --- a/include/Nazara/Utility/Image.hpp +++ b/include/Nazara/Utility/Image.hpp @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -17,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -93,19 +93,19 @@ namespace Nz // Load bool LoadFromFile(const String& filePath, const ImageParams& params = ImageParams()); bool LoadFromMemory(const void* data, std::size_t size, const ImageParams& params = ImageParams()); - bool LoadFromStream(InputStream& stream, const ImageParams& params = ImageParams()); + bool LoadFromStream(Stream& stream, const ImageParams& params = ImageParams()); // LoadArray bool LoadArrayFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2)); bool LoadArrayFromImage(const Image& image, const Vector2ui& atlasSize = Vector2ui(2, 2)); bool LoadArrayFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2)); - bool LoadArrayFromStream(InputStream& stream, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2)); + bool LoadArrayFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), const Vector2ui& atlasSize = Vector2ui(2, 2)); // LoadCubemap bool LoadCubemapFromFile(const String& filePath, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); bool LoadCubemapFromImage(const Image& image, const CubemapParams& params = CubemapParams()); bool LoadCubemapFromMemory(const void* data, std::size_t size, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); - bool LoadCubemapFromStream(InputStream& stream, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); + bool LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams = ImageParams(), const CubemapParams& cubemapParams = CubemapParams()); void SetLevelCount(UInt8 levelCount); bool SetPixelColor(const Color& color, unsigned int x, unsigned int y = 0, unsigned int z = 0); diff --git a/include/Nazara/Utility/Mesh.hpp b/include/Nazara/Utility/Mesh.hpp index 691c8f3ed..17857704a 100644 --- a/include/Nazara/Utility/Mesh.hpp +++ b/include/Nazara/Utility/Mesh.hpp @@ -8,7 +8,6 @@ #define NAZARA_MESH_HPP #include -#include #include #include #include @@ -16,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -115,7 +115,7 @@ namespace Nz bool LoadFromFile(const String& filePath, const MeshParams& params = MeshParams()); bool LoadFromMemory(const void* data, std::size_t size, const MeshParams& params = MeshParams()); - bool LoadFromStream(InputStream& stream, const MeshParams& params = MeshParams()); + bool LoadFromStream(Stream& stream, const MeshParams& params = MeshParams()); void Recenter(); diff --git a/src/Nazara/Audio/Formats/sndfileLoader.cpp b/src/Nazara/Audio/Formats/sndfileLoader.cpp index fb8725a37..4cf99fee7 100644 --- a/src/Nazara/Audio/Formats/sndfileLoader.cpp +++ b/src/Nazara/Audio/Formats/sndfileLoader.cpp @@ -13,8 +13,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -27,19 +27,19 @@ namespace Nz { sf_count_t GetSize(void* user_data) { - InputStream* stream = static_cast(user_data); + Stream* stream = static_cast(user_data); return stream->GetSize(); } sf_count_t Read(void* ptr, sf_count_t count, void* user_data) { - InputStream* stream = static_cast(user_data); + Stream* stream = static_cast(user_data); return static_cast(stream->Read(ptr, static_cast(count))); } sf_count_t Seek(sf_count_t offset, int whence, void* user_data) { - InputStream* stream = static_cast(user_data); + Stream* stream = static_cast(user_data); switch (whence) { case SEEK_CUR: @@ -63,7 +63,7 @@ namespace Nz sf_count_t Tell(void* user_data) { - InputStream* stream = static_cast(user_data); + Stream* stream = static_cast(user_data); return stream->GetCursorPos(); } @@ -128,7 +128,7 @@ namespace Nz return Open(*m_ownedStream, forceMono); } - bool Open(InputStream& stream, bool forceMono) + bool Open(Stream& stream, bool forceMono) { SF_INFO infos; infos.format = 0; // Format inconnu @@ -203,7 +203,7 @@ namespace Nz private: std::vector m_mixBuffer; - std::unique_ptr m_ownedStream; + std::unique_ptr m_ownedStream; AudioFormat m_format; SNDFILE* m_handle; bool m_mixToMono; @@ -222,7 +222,7 @@ namespace Nz return supportedExtensions.find(extension) != supportedExtensions.end(); } - Ternary CheckMusic(InputStream& stream, const MusicParams& parameters) + Ternary CheckMusic(Stream& stream, const MusicParams& parameters) { NazaraUnused(parameters); @@ -282,7 +282,7 @@ namespace Nz return true; } - bool LoadMusicStream(Music* music, InputStream& stream, const MusicParams& parameters) + bool LoadMusicStream(Music* music, Stream& stream, const MusicParams& parameters) { std::unique_ptr musicStream(new sndfileStream); if (!musicStream->Open(stream, parameters.forceMono)) @@ -303,7 +303,7 @@ namespace Nz return true; } - Ternary CheckSoundBuffer(InputStream& stream, const SoundBufferParams& parameters) + Ternary CheckSoundBuffer(Stream& stream, const SoundBufferParams& parameters) { NazaraUnused(parameters); @@ -320,7 +320,7 @@ namespace Nz return Ternary_False; } - bool LoadSoundBuffer(SoundBuffer* soundBuffer, InputStream& stream, const SoundBufferParams& parameters) + bool LoadSoundBuffer(SoundBuffer* soundBuffer, Stream& stream, const SoundBufferParams& parameters) { SF_INFO info; info.format = 0; diff --git a/src/Nazara/Audio/Music.cpp b/src/Nazara/Audio/Music.cpp index a1ab56b61..8ff8e2a7f 100644 --- a/src/Nazara/Audio/Music.cpp +++ b/src/Nazara/Audio/Music.cpp @@ -189,7 +189,7 @@ namespace Nz return MusicLoader::LoadFromMemory(this, data, size, params); } - bool Music::OpenFromStream(InputStream& stream, const MusicParams& params) + bool Music::OpenFromStream(Stream& stream, const MusicParams& params) { return MusicLoader::LoadFromStream(this, stream, params); } diff --git a/src/Nazara/Audio/Sound.cpp b/src/Nazara/Audio/Sound.cpp index bcba9a423..31ef3af27 100644 --- a/src/Nazara/Audio/Sound.cpp +++ b/src/Nazara/Audio/Sound.cpp @@ -110,7 +110,7 @@ namespace Nz return true; } - bool Sound::LoadFromStream(InputStream& stream, const SoundBufferParams& params) + bool Sound::LoadFromStream(Stream& stream, const SoundBufferParams& params) { SoundBufferRef buffer = SoundBuffer::New(); if (!buffer->LoadFromStream(stream, params)) diff --git a/src/Nazara/Audio/SoundBuffer.cpp b/src/Nazara/Audio/SoundBuffer.cpp index 9b3f9f4ea..10edc74f8 100644 --- a/src/Nazara/Audio/SoundBuffer.cpp +++ b/src/Nazara/Audio/SoundBuffer.cpp @@ -206,7 +206,7 @@ namespace Nz return SoundBufferLoader::LoadFromMemory(this, data, size, params); } - bool SoundBuffer::LoadFromStream(InputStream& stream, const SoundBufferParams& params) + bool SoundBuffer::LoadFromStream(Stream& stream, const SoundBufferParams& params) { return SoundBufferLoader::LoadFromStream(this, stream, params); } diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index c84fff7b9..c6ad0e257 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -50,8 +50,6 @@ namespace Nz File::File(File&& file) noexcept : Stream(std::move(file)), - InputStream(std::move(file)), - OutputStream(std::move(file)), m_filePath(std::move(file.m_filePath)), m_impl(file.m_impl) { @@ -119,16 +117,6 @@ namespace Nz return Exists(m_filePath); } - void File::Flush() - { - NazaraLock(m_mutex) - - NazaraAssert(IsOpen(), "File is not open"); - NazaraAssert(IsWritable(), "File not opened with write access"); - - m_impl->Flush(); - } - time_t File::GetCreationTime() const { NazaraLock(m_mutex) @@ -194,29 +182,6 @@ namespace Nz return m_impl != nullptr; } - std::size_t File::Read(void* buffer, std::size_t size) - { - NazaraLock(m_mutex) - - NazaraAssert(IsOpen(), "File is not opened"); - NazaraAssert(IsReadable(), "File not opened with read access"); - - if (size == 0) - return 0; - - if (buffer) - return m_impl->Read(buffer, size); - else - { - // Si nous ne devons rien lire, nous avançons simplement - UInt64 currentPos = m_impl->GetCursorPos(); - - m_impl->SetCursorPos(CursorPosition_AtCurrent, size); - - return static_cast(m_impl->GetCursorPos() - currentPos); - } - } - bool File::Rename(const String& newFilePath) { NazaraLock(m_mutex) @@ -321,21 +286,6 @@ namespace Nz return true; } - std::size_t File::Write(const void* buffer, std::size_t size) - { - NazaraLock(m_mutex) - - NazaraAssert(IsOpen(), "File is not opened"); - NazaraAssert(IsWritable(), "File not opened with write access"); - - if (size == 0) - return 0; - - NazaraAssert(buffer, "Invalid buffer"); - - return m_impl->Write(buffer, size); - } - File& File::operator=(const String& filePath) { SetFile(filePath); @@ -549,6 +499,52 @@ namespace Nz return FileImpl::Rename(NormalizePath(sourcePath), NormalizePath(targetPath)); } + void File::FlushStream() + { + NazaraLock(m_mutex) + + NazaraAssert(IsOpen(), "File is not open"); + + m_impl->Flush(); + } + + std::size_t File::ReadBlock(void* buffer, std::size_t size) + { + NazaraLock(m_mutex) + + NazaraAssert(IsOpen(), "File is not opened"); + + if (size == 0) + return 0; + + if (buffer) + return m_impl->Read(buffer, size); + else + { + // Si nous ne devons rien lire, nous avançons simplement + UInt64 currentPos = m_impl->GetCursorPos(); + + m_impl->SetCursorPos(CursorPosition_AtCurrent, size); + + return static_cast(m_impl->GetCursorPos() - currentPos); + } + } + + std::size_t File::WriteBlock(const void* buffer, std::size_t size) + { + NazaraLock(m_mutex) + + NazaraAssert(IsOpen(), "File is not opened"); + + if (size == 0) + return 0; + + NazaraAssert(buffer, "Invalid buffer"); + + return m_impl->Write(buffer, size); + } + + NAZARA_CORE_API bool HashAppend(AbstractHash* hash, const File& originalFile) { File file(originalFile.GetPath()); diff --git a/src/Nazara/Core/InputStream.cpp b/src/Nazara/Core/InputStream.cpp deleted file mode 100644 index aa62e8114..000000000 --- a/src/Nazara/Core/InputStream.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include - -namespace Nz -{ - InputStream::~InputStream() = default; - - String InputStream::ReadLine(unsigned int lineSize) - { - String line; - if (lineSize == 0) // Taille maximale indéterminée - { - const unsigned int bufferSize = 64; - - char buffer[bufferSize+1]; - buffer[bufferSize] = '\0'; - - unsigned int readSize; - do - { - readSize = Read(buffer, bufferSize); - - const char* ptr = std::strchr(buffer, '\n'); - if (ptr) - { - unsigned int pos = ptr-buffer; - - if (m_streamOptions & StreamOption_Text && pos > 0 && buffer[pos-1] == '\r') - line.Append(buffer, pos-1); - else - line.Append(buffer, pos); - - if (!SetCursorPos(GetCursorPos() - readSize + pos + 1)) - NazaraWarning("Failed to reset cursos pos"); - - break; - } - else - line.Append(buffer, readSize); - } - while (readSize == bufferSize); - } - else - { - line.Set(lineSize, '\0'); - unsigned int readSize = Read(&line[0], lineSize); - unsigned int pos = line.Find('\n'); - if (pos <= readSize) // Faux uniquement si le caractère n'est pas présent (npos étant le plus grand entier) - { - if (m_streamOptions & StreamOption_Text && pos > 0 && line[pos-1] == '\r') - line.Resize(pos); - else - line.Resize(pos+1); - - if (!SetCursorPos(GetCursorPos() - readSize + pos + 1)) - NazaraWarning("Failed to reset cursos pos"); - } - else - line.Resize(readSize); - } - - return line; - } -} diff --git a/src/Nazara/Core/MemoryStream.cpp b/src/Nazara/Core/MemoryStream.cpp index 0bd11573b..f92d6a3c0 100644 --- a/src/Nazara/Core/MemoryStream.cpp +++ b/src/Nazara/Core/MemoryStream.cpp @@ -33,11 +33,6 @@ namespace Nz return m_pos >= m_buffer.size(); } - void MemoryStream::Flush() - { - // Nothing to flush - } - const ByteArray& MemoryStream::GetBuffer() const { return m_buffer; @@ -58,7 +53,19 @@ namespace Nz return m_buffer.size(); } - std::size_t MemoryStream::Read(void* buffer, std::size_t size) + bool MemoryStream::SetCursorPos(UInt64 offset) + { + m_pos = std::min(offset, m_buffer.size()); + + return true; + } + + void MemoryStream::FlushStream() + { + // Nothing to flush + } + + std::size_t MemoryStream::ReadBlock(void* buffer, std::size_t size) { std::size_t readSize = std::min(size, static_cast(m_buffer.size() - m_pos)); @@ -69,14 +76,7 @@ namespace Nz return readSize; } - bool MemoryStream::SetCursorPos(UInt64 offset) - { - m_pos = std::min(offset, m_buffer.size()); - - return true; - } - - std::size_t MemoryStream::Write(const void* buffer, std::size_t size) + std::size_t MemoryStream::WriteBlock(const void* buffer, std::size_t size) { std::size_t endPos = static_cast(m_pos + size); if (endPos > m_buffer.size()) diff --git a/src/Nazara/Core/MemoryView.cpp b/src/Nazara/Core/MemoryView.cpp index b5a47c776..f86200b90 100644 --- a/src/Nazara/Core/MemoryView.cpp +++ b/src/Nazara/Core/MemoryView.cpp @@ -32,7 +32,19 @@ namespace Nz return m_size; } - std::size_t MemoryView::Read(void* buffer, std::size_t size) + bool MemoryView::SetCursorPos(UInt64 offset) + { + m_pos = std::min(offset, m_size); + + return true; + } + + void MemoryView::FlushStream() + { + NazaraInternalError("FlushStream has been called on a MemoryView"); + } + + std::size_t MemoryView::ReadBlock(void* buffer, std::size_t size) { std::size_t readSize = std::min(size, static_cast(m_size - m_pos)); @@ -43,10 +55,9 @@ namespace Nz return readSize; } - bool MemoryView::SetCursorPos(UInt64 offset) + std::size_t MemoryView::WriteBlock(const void* buffer, std::size_t size) { - m_pos = std::min(offset, m_size); - - return true; + NazaraInternalError("WriteBlock has been called on a MemoryView"); + return 0; } } diff --git a/src/Nazara/Core/OutputStream.cpp b/src/Nazara/Core/OutputStream.cpp deleted file mode 100644 index b9bc8a420..000000000 --- a/src/Nazara/Core/OutputStream.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include -#include -#include - -namespace Nz -{ - OutputStream::~OutputStream() = default; - - bool OutputStream::Write(const ByteArray& byteArray) - { - ByteArray::size_type size = byteArray.GetSize(); - return Write(byteArray.GetConstBuffer(), size) == size; - } - - bool OutputStream::Write(const String& string) - { - String temp(string); - - if (m_streamOptions & StreamOption_Text) - { - #if defined(NAZARA_PLATFORM_WINDOWS) - temp.Replace("\n", "\r\n"); - #elif defined(NAZARA_PLATFORM_LINUX) - // Nothing to do - #elif defined(NAZARA_PLATFORM_MACOS) - temp.Replace('\n', '\r'); - #endif - } - - std::size_t size = temp.GetSize(); - return Write(temp.GetConstBuffer(), size) == size; - } -} diff --git a/src/Nazara/Core/Stream.cpp b/src/Nazara/Core/Stream.cpp index 8a6951887..484057341 100644 --- a/src/Nazara/Core/Stream.cpp +++ b/src/Nazara/Core/Stream.cpp @@ -3,6 +3,8 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include +#include #include #include @@ -19,4 +21,86 @@ namespace Nz { return String(); } + + String Stream::ReadLine(unsigned int lineSize) + { + String line; + if (lineSize == 0) // Taille maximale indéterminée + { + const unsigned int bufferSize = 64; + + char buffer[bufferSize + 1]; + buffer[bufferSize] = '\0'; + + unsigned int readSize; + do + { + readSize = Read(buffer, bufferSize); + + const char* ptr = std::strchr(buffer, '\n'); + if (ptr) + { + unsigned int pos = ptr - buffer; + + if (m_streamOptions & StreamOption_Text && pos > 0 && buffer[pos - 1] == '\r') + line.Append(buffer, pos - 1); + else + line.Append(buffer, pos); + + if (!SetCursorPos(GetCursorPos() - readSize + pos + 1)) + NazaraWarning("Failed to reset cursos pos"); + + break; + } + else + line.Append(buffer, readSize); + } + while (readSize == bufferSize); + } + else + { + line.Set(lineSize, '\0'); + unsigned int readSize = Read(&line[0], lineSize); + unsigned int pos = line.Find('\n'); + if (pos <= readSize) // Faux uniquement si le caractère n'est pas présent (npos étant le plus grand entier) + { + if (m_streamOptions & StreamOption_Text && pos > 0 && line[pos - 1] == '\r') + line.Resize(pos); + else + line.Resize(pos + 1); + + if (!SetCursorPos(GetCursorPos() - readSize + pos + 1)) + NazaraWarning("Failed to reset cursos pos"); + } + else + line.Resize(readSize); + } + + return line; + } + + bool Stream::Write(const ByteArray& byteArray) + { + ByteArray::size_type size = byteArray.GetSize(); + return Write(byteArray.GetConstBuffer(), size) == size; + } + + bool Stream::Write(const String& string) + { + String temp(string); + + if (m_streamOptions & StreamOption_Text) + { + #if defined(NAZARA_PLATFORM_WINDOWS) + temp.Replace("\n", "\r\n"); + #elif defined(NAZARA_PLATFORM_LINUX) + // Nothing to do + #elif defined(NAZARA_PLATFORM_MACOS) + temp.Replace('\n', '\r'); + #endif + } + + std::size_t size = temp.GetSize(); + return Write(temp.GetConstBuffer(), size) == size; + } } diff --git a/src/Nazara/Graphics/Formats/MeshLoader.cpp b/src/Nazara/Graphics/Formats/MeshLoader.cpp index c4056577b..bce371e51 100644 --- a/src/Nazara/Graphics/Formats/MeshLoader.cpp +++ b/src/Nazara/Graphics/Formats/MeshLoader.cpp @@ -14,7 +14,7 @@ namespace Nz { namespace { - Ternary CheckStatic(InputStream& stream, const ModelParameters& parameters) + Ternary CheckStatic(Stream& stream, const ModelParameters& parameters) { NazaraUnused(stream); NazaraUnused(parameters); @@ -22,7 +22,7 @@ namespace Nz return Ternary_Unknown; } - bool LoadStatic(Model* model, InputStream& stream, const ModelParameters& parameters) + bool LoadStatic(Model* model, Stream& stream, const ModelParameters& parameters) { NazaraUnused(parameters); @@ -63,7 +63,7 @@ namespace Nz return true; } - Ternary CheckAnimated(InputStream& stream, const SkeletalModelParameters& parameters) + Ternary CheckAnimated(Stream& stream, const SkeletalModelParameters& parameters) { NazaraUnused(stream); NazaraUnused(parameters); @@ -71,7 +71,7 @@ namespace Nz return Ternary_Unknown; } - bool LoadAnimated(SkeletalModel* model, InputStream& stream, const SkeletalModelParameters& parameters) + bool LoadAnimated(SkeletalModel* model, Stream& stream, const SkeletalModelParameters& parameters) { NazaraUnused(parameters); diff --git a/src/Nazara/Graphics/Formats/OBJLoader.cpp b/src/Nazara/Graphics/Formats/OBJLoader.cpp index 4462a2e1d..b295811d4 100644 --- a/src/Nazara/Graphics/Formats/OBJLoader.cpp +++ b/src/Nazara/Graphics/Formats/OBJLoader.cpp @@ -29,7 +29,7 @@ namespace Nz return (extension == "obj"); } - Ternary Check(InputStream& stream, const ModelParameters& parameters) + Ternary Check(Stream& stream, const ModelParameters& parameters) { NazaraUnused(stream); NazaraUnused(parameters); @@ -127,7 +127,7 @@ namespace Nz return true; } - bool Load(Model* model, InputStream& stream, const ModelParameters& parameters) + bool Load(Model* model, Stream& stream, const ModelParameters& parameters) { OBJParser parser(stream); if (!parser.Parse()) diff --git a/src/Nazara/Graphics/Formats/TextureLoader.cpp b/src/Nazara/Graphics/Formats/TextureLoader.cpp index 1bea108ff..2f8dc2910 100644 --- a/src/Nazara/Graphics/Formats/TextureLoader.cpp +++ b/src/Nazara/Graphics/Formats/TextureLoader.cpp @@ -12,7 +12,7 @@ namespace Nz { namespace { - Ternary Check(InputStream& stream, const MaterialParams& parameters) + Ternary Check(Stream& stream, const MaterialParams& parameters) { NazaraUnused(stream); NazaraUnused(parameters); @@ -20,7 +20,7 @@ namespace Nz return Ternary_Unknown; } - bool Load(Material* material, InputStream& stream, const MaterialParams& parameters) + bool Load(Material* material, Stream& stream, const MaterialParams& parameters) { NazaraUnused(parameters); diff --git a/src/Nazara/Graphics/Material.cpp b/src/Nazara/Graphics/Material.cpp index 9d34c9995..0781c6919 100644 --- a/src/Nazara/Graphics/Material.cpp +++ b/src/Nazara/Graphics/Material.cpp @@ -370,7 +370,7 @@ namespace Nz return MaterialLoader::LoadFromMemory(this, data, size, params); } - bool Material::LoadFromStream(InputStream& stream, const MaterialParams& params) + bool Material::LoadFromStream(Stream& stream, const MaterialParams& params) { return MaterialLoader::LoadFromStream(this, stream, params); } diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index fa7bfabe4..954f3ff01 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -175,7 +175,7 @@ namespace Nz return ModelLoader::LoadFromMemory(this, data, size, params); } - bool Model::LoadFromStream(InputStream& stream, const ModelParameters& params) + bool Model::LoadFromStream(Stream& stream, const ModelParameters& params) { return ModelLoader::LoadFromStream(this, stream, params); } diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index 71ff53bb5..97889764d 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -149,7 +149,7 @@ namespace Nz return SkeletalModelLoader::LoadFromMemory(this, data, size, params); } - bool SkeletalModel::LoadFromStream(InputStream& stream, const SkeletalModelParameters& params) + bool SkeletalModel::LoadFromStream(Stream& stream, const SkeletalModelParameters& params) { return SkeletalModelLoader::LoadFromStream(this, stream, params); } diff --git a/src/Nazara/Lua/LuaInstance.cpp b/src/Nazara/Lua/LuaInstance.cpp index d5b8e3e1d..e1ed81644 100644 --- a/src/Nazara/Lua/LuaInstance.cpp +++ b/src/Nazara/Lua/LuaInstance.cpp @@ -62,7 +62,7 @@ namespace Nz struct StreamData { - InputStream* stream; + Stream* stream; char buffer[NAZARA_CORE_FILE_BUFFERSIZE]; }; @@ -422,7 +422,7 @@ namespace Nz return ExecuteFromStream(stream); } - bool LuaInstance::ExecuteFromStream(InputStream& stream) + bool LuaInstance::ExecuteFromStream(Stream& stream) { StreamData data; data.stream = &stream; diff --git a/src/Nazara/Renderer/Texture.cpp b/src/Nazara/Renderer/Texture.cpp index f52cfd7ee..fea1e2d6b 100644 --- a/src/Nazara/Renderer/Texture.cpp +++ b/src/Nazara/Renderer/Texture.cpp @@ -599,7 +599,7 @@ namespace Nz return LoadFromImage(image, generateMipmaps); } - bool Texture::LoadFromStream(InputStream& stream, const ImageParams& params, bool generateMipmaps) + bool Texture::LoadFromStream(Stream& stream, const ImageParams& params, bool generateMipmaps) { Image image; if (!image.LoadFromStream(stream, params)) @@ -647,7 +647,7 @@ namespace Nz return LoadFromImage(cubemap, generateMipmaps); } - bool Texture::LoadArrayFromStream(InputStream& stream, const ImageParams& imageParams, bool generateMipmaps, const Vector2ui& atlasSize) + bool Texture::LoadArrayFromStream(Stream& stream, const ImageParams& imageParams, bool generateMipmaps, const Vector2ui& atlasSize) { Image cubemap; if (!cubemap.LoadArrayFromStream(stream, imageParams, atlasSize)) @@ -695,7 +695,7 @@ namespace Nz return LoadFromImage(cubemap, generateMipmaps); } - bool Texture::LoadCubemapFromStream(InputStream& stream, const ImageParams& imageParams, bool generateMipmaps, const CubemapParams& cubemapParams) + bool Texture::LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams, bool generateMipmaps, const CubemapParams& cubemapParams) { Image cubemap; if (!cubemap.LoadCubemapFromStream(stream, imageParams, cubemapParams)) @@ -785,7 +785,7 @@ namespace Nz return Update(image, Rectui(0, 0, faceSize, faceSize), face); } - bool Texture::LoadFaceFromStream(CubemapFace face, InputStream& stream, const ImageParams& params) + bool Texture::LoadFaceFromStream(CubemapFace face, Stream& stream, const ImageParams& params) { #if NAZARA_RENDERER_SAFE if (!m_impl) diff --git a/src/Nazara/Utility/Animation.cpp b/src/Nazara/Utility/Animation.cpp index 683b4f3a7..bbd57b1df 100644 --- a/src/Nazara/Utility/Animation.cpp +++ b/src/Nazara/Utility/Animation.cpp @@ -458,7 +458,7 @@ namespace Nz return AnimationLoader::LoadFromMemory(this, data, size, params); } - bool Animation::LoadFromStream(InputStream& stream, const AnimationParams& params) + bool Animation::LoadFromStream(Stream& stream, const AnimationParams& params) { return AnimationLoader::LoadFromStream(this, stream, params); } diff --git a/src/Nazara/Utility/Font.cpp b/src/Nazara/Utility/Font.cpp index a2e7b2833..b7cefb362 100644 --- a/src/Nazara/Utility/Font.cpp +++ b/src/Nazara/Utility/Font.cpp @@ -290,7 +290,7 @@ namespace Nz return FontLoader::LoadFromMemory(this, data, size, params); } - bool Font::OpenFromStream(InputStream& stream, const FontParams& params) + bool Font::OpenFromStream(Stream& stream, const FontParams& params) { return FontLoader::LoadFromStream(this, stream, params); } diff --git a/src/Nazara/Utility/Formats/DDSLoader.cpp b/src/Nazara/Utility/Formats/DDSLoader.cpp index eb6bd2d6d..b38ed4470 100644 --- a/src/Nazara/Utility/Formats/DDSLoader.cpp +++ b/src/Nazara/Utility/Formats/DDSLoader.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include @@ -20,7 +20,7 @@ namespace Nz return (extension == "dds"); } - Ternary Check(InputStream& stream, const ImageParams& parameters) + Ternary Check(Stream& stream, const ImageParams& parameters) { NazaraUnused(parameters); @@ -38,7 +38,7 @@ namespace Nz return Ternary_False; } - bool Load(Image* image, InputStream& stream, const ImageParams& parameters) + bool Load(Image* image, Stream& stream, const ImageParams& parameters) { NazaraUnused(parameters); diff --git a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp index f859e327f..2f5c2ef8f 100644 --- a/src/Nazara/Utility/Formats/FreeTypeLoader.cpp +++ b/src/Nazara/Utility/Formats/FreeTypeLoader.cpp @@ -8,8 +8,8 @@ #include FT_BITMAP_H #include FT_OUTLINE_H #include -#include #include +#include #include #include #include @@ -31,7 +31,7 @@ namespace Nz unsigned long FT_StreamRead(FT_Stream stream, unsigned long offset, unsigned char* buffer, unsigned long count) { // http://www.freetype.org/freetype2/docs/reference/ft2-system_interface.html#FT_Stream_IoFunc - InputStream& inputStream = *static_cast(stream->descriptor.pointer); + Stream& inputStream = *static_cast(stream->descriptor.pointer); // La valeur de count indique une opération de lecture ou de positionnement if (count > 0) @@ -298,7 +298,7 @@ namespace Nz SetStream(*m_ownedStream); } - void SetStream(InputStream& stream) + void SetStream(Stream& stream) { m_stream.base = nullptr; m_stream.close = FT_StreamClose; @@ -332,7 +332,7 @@ namespace Nz FT_Face m_face; FT_StreamRec m_stream; std::shared_ptr m_library; - std::unique_ptr m_ownedStream; + std::unique_ptr m_ownedStream; mutable unsigned int m_characterSize; }; @@ -346,7 +346,7 @@ namespace Nz return supportedExtensions.find(extension) != supportedExtensions.end(); } - Ternary Check(InputStream& stream, const FontParams& parameters) + Ternary Check(Stream& stream, const FontParams& parameters) { NazaraUnused(parameters); @@ -408,7 +408,7 @@ namespace Nz return false; } - bool LoadStream(Font* font, InputStream& stream, const FontParams& parameters) + bool LoadStream(Font* font, Stream& stream, const FontParams& parameters) { NazaraUnused(parameters); diff --git a/src/Nazara/Utility/Formats/MD2Loader.cpp b/src/Nazara/Utility/Formats/MD2Loader.cpp index 77fca01d1..ea685cc6f 100644 --- a/src/Nazara/Utility/Formats/MD2Loader.cpp +++ b/src/Nazara/Utility/Formats/MD2Loader.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include @@ -26,7 +26,7 @@ namespace Nz return (extension == "md2"); } - Ternary Check(InputStream& stream, const MeshParams& parameters) + Ternary Check(Stream& stream, const MeshParams& parameters) { NazaraUnused(parameters); @@ -45,7 +45,7 @@ namespace Nz return Ternary_False; } - bool Load(Mesh* mesh, InputStream& stream, const MeshParams& parameters) + bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) { MD2_Header header; if (stream.Read(&header, sizeof(MD2_Header)) != sizeof(MD2_Header)) diff --git a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp index 513be6636..1950037c1 100644 --- a/src/Nazara/Utility/Formats/MD5AnimLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5AnimLoader.cpp @@ -15,7 +15,7 @@ namespace Nz return (extension == "md5anim"); } - Ternary Check(InputStream& stream, const AnimationParams& parameters) + Ternary Check(Stream& stream, const AnimationParams& parameters) { NazaraUnused(parameters); @@ -23,7 +23,7 @@ namespace Nz return parser.Check(); } - bool Load(Animation* animation, InputStream& stream, const AnimationParams& parameters) + bool Load(Animation* animation, Stream& stream, const AnimationParams& parameters) { ///TODO: Utiliser les paramètres MD5AnimParser parser(stream); diff --git a/src/Nazara/Utility/Formats/MD5AnimParser.cpp b/src/Nazara/Utility/Formats/MD5AnimParser.cpp index b53a8bd9b..321ee8692 100644 --- a/src/Nazara/Utility/Formats/MD5AnimParser.cpp +++ b/src/Nazara/Utility/Formats/MD5AnimParser.cpp @@ -15,22 +15,22 @@ namespace Nz { - MD5AnimParser::MD5AnimParser(InputStream& stream) : + MD5AnimParser::MD5AnimParser(Stream& stream) : m_stream(stream), m_keepLastLine(false), m_frameIndex(0), m_frameRate(0), m_lineCount(0), - m_streamFlags(stream.GetStreamOptions()) + m_streamFlags(stream.GetStreamOptions()) //< Saves stream flags { - if ((m_streamFlags & StreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags | StreamOption_Text); + m_stream.EnableTextMode(true); } MD5AnimParser::~MD5AnimParser() { + // Reset stream flags if ((m_streamFlags & StreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags); + m_stream.EnableTextMode(false); } Ternary MD5AnimParser::Check() diff --git a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp index 262892aa8..9bf16f055 100644 --- a/src/Nazara/Utility/Formats/MD5MeshLoader.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshLoader.cpp @@ -20,7 +20,7 @@ namespace Nz return (extension == "md5mesh"); } - Ternary Check(InputStream& stream, const MeshParams& parameters) + Ternary Check(Stream& stream, const MeshParams& parameters) { NazaraUnused(parameters); @@ -28,7 +28,7 @@ namespace Nz return parser.Check(); } - bool Load(Mesh* mesh, InputStream& stream, const MeshParams& parameters) + bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters) { MD5MeshParser parser(stream); if (!parser.Parse()) diff --git a/src/Nazara/Utility/Formats/MD5MeshParser.cpp b/src/Nazara/Utility/Formats/MD5MeshParser.cpp index 71d6779a4..d8dfcb304 100644 --- a/src/Nazara/Utility/Formats/MD5MeshParser.cpp +++ b/src/Nazara/Utility/Formats/MD5MeshParser.cpp @@ -21,21 +21,21 @@ namespace Nz { - MD5MeshParser::MD5MeshParser(InputStream& stream) : + MD5MeshParser::MD5MeshParser(Stream& stream) : m_stream(stream), m_keepLastLine(false), m_lineCount(0), m_meshIndex(0), - m_streamFlags(stream.GetStreamOptions()) + m_streamFlags(stream.GetStreamOptions()) //< Saves stream flags { - if ((m_streamFlags & StreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags | StreamOption_Text); + m_stream.EnableTextMode(true); } MD5MeshParser::~MD5MeshParser() { + // Reset stream flags if ((m_streamFlags & StreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags); + m_stream.EnableTextMode(false); } Ternary MD5MeshParser::Check() diff --git a/src/Nazara/Utility/Formats/MTLParser.cpp b/src/Nazara/Utility/Formats/MTLParser.cpp index d0c7f05b9..2398ccb3f 100644 --- a/src/Nazara/Utility/Formats/MTLParser.cpp +++ b/src/Nazara/Utility/Formats/MTLParser.cpp @@ -12,18 +12,18 @@ namespace Nz { - MTLParser::MTLParser(InputStream& stream) : + MTLParser::MTLParser(Stream& stream) : m_stream(stream), - m_streamFlags(stream.GetStreamOptions()) + m_streamFlags(stream.GetStreamOptions()) //< Saves stream flags { - if ((m_streamFlags & StreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags | StreamOption_Text); + m_stream.EnableTextMode(true); } MTLParser::~MTLParser() { + // Reset stream flags if ((m_streamFlags & StreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags); + m_stream.EnableTextMode(false); } const MTLParser::Material* MTLParser::GetMaterial(const String& materialName) const diff --git a/src/Nazara/Utility/Formats/OBJParser.cpp b/src/Nazara/Utility/Formats/OBJParser.cpp index a582b2326..64132f586 100644 --- a/src/Nazara/Utility/Formats/OBJParser.cpp +++ b/src/Nazara/Utility/Formats/OBJParser.cpp @@ -13,18 +13,18 @@ namespace Nz { - OBJParser::OBJParser(InputStream& stream) : + OBJParser::OBJParser(Stream& stream) : m_stream(stream), - m_streamFlags(stream.GetStreamOptions()) + m_streamFlags(stream.GetStreamOptions()) //< Saves stream flags { - if ((m_streamFlags & StreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags | StreamOption_Text); + m_stream.EnableTextMode(true); } OBJParser::~OBJParser() { + // Reset stream flags if ((m_streamFlags & StreamOption_Text) == 0) - m_stream.SetStreamOptions(m_streamFlags); + m_stream.EnableTextMode(false); } const String* OBJParser::GetMaterials() const diff --git a/src/Nazara/Utility/Formats/PCXLoader.cpp b/src/Nazara/Utility/Formats/PCXLoader.cpp index 98862c517..c337409bf 100644 --- a/src/Nazara/Utility/Formats/PCXLoader.cpp +++ b/src/Nazara/Utility/Formats/PCXLoader.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include #include #include @@ -45,7 +45,7 @@ namespace Nz return (extension == "pcx"); } - Ternary Check(InputStream& stream, const ImageParams& parameters) + Ternary Check(Stream& stream, const ImageParams& parameters) { NazaraUnused(parameters); @@ -59,7 +59,7 @@ namespace Nz return Ternary_False; } - bool Load(Image* image, InputStream& stream, const ImageParams& parameters) + bool Load(Image* image, Stream& stream, const ImageParams& parameters) { NazaraUnused(parameters); diff --git a/src/Nazara/Utility/Formats/STBLoader.cpp b/src/Nazara/Utility/Formats/STBLoader.cpp index 86d23644e..75d185e82 100644 --- a/src/Nazara/Utility/Formats/STBLoader.cpp +++ b/src/Nazara/Utility/Formats/STBLoader.cpp @@ -7,8 +7,8 @@ #include #include #include -#include #include +#include #include #include #include @@ -19,19 +19,19 @@ namespace Nz { int Read(void* userdata, char* data, int size) { - InputStream* stream = static_cast(userdata); + Stream* stream = static_cast(userdata); return static_cast(stream->Read(data, size)); } void Skip(void* userdata, int size) { - InputStream* stream = static_cast(userdata); + Stream* stream = static_cast(userdata); stream->SetCursorPos(static_cast(stream->GetCursorPos()) + static_cast(size)); } int Eof(void* userdata) { - InputStream* stream = static_cast(userdata); + Stream* stream = static_cast(userdata); return stream->GetCursorPos() >= stream->GetSize(); } @@ -43,7 +43,7 @@ namespace Nz return supportedExtensions.find(extension) != supportedExtensions.end(); } - Ternary Check(InputStream& stream, const ImageParams& parameters) + Ternary Check(Stream& stream, const ImageParams& parameters) { NazaraUnused(parameters); @@ -54,7 +54,7 @@ namespace Nz return Ternary_False; } - bool Load(Image* image, InputStream& stream, const ImageParams& parameters) + bool Load(Image* image, Stream& stream, const ImageParams& parameters) { // Je charge tout en RGBA8 et je converti ensuite via la méthode Convert // Ceci à cause d'un bug de STB lorsqu'il s'agit de charger certaines images (ex: JPG) en "default" diff --git a/src/Nazara/Utility/Image.cpp b/src/Nazara/Utility/Image.cpp index 8d88aae4c..8af7d7923 100644 --- a/src/Nazara/Utility/Image.cpp +++ b/src/Nazara/Utility/Image.cpp @@ -831,7 +831,7 @@ namespace Nz return ImageLoader::LoadFromMemory(this, data, size, params); } - bool Image::LoadFromStream(InputStream& stream, const ImageParams& params) + bool Image::LoadFromStream(Stream& stream, const ImageParams& params) { return ImageLoader::LoadFromStream(this, stream, params); } @@ -923,7 +923,7 @@ namespace Nz return LoadArrayFromImage(image, atlasSize); } - bool Image::LoadArrayFromStream(InputStream& stream, const ImageParams& imageParams, const Vector2ui& atlasSize) + bool Image::LoadArrayFromStream(Stream& stream, const ImageParams& imageParams, const Vector2ui& atlasSize) { Image image; if (!image.LoadFromStream(stream, imageParams)) @@ -1054,7 +1054,7 @@ namespace Nz return LoadCubemapFromImage(image, cubemapParams); } - bool Image::LoadCubemapFromStream(InputStream& stream, const ImageParams& imageParams, const CubemapParams& cubemapParams) + bool Image::LoadCubemapFromStream(Stream& stream, const ImageParams& imageParams, const CubemapParams& cubemapParams) { Image image; if (!image.LoadFromStream(stream, imageParams)) diff --git a/src/Nazara/Utility/Mesh.cpp b/src/Nazara/Utility/Mesh.cpp index 3492916b1..82c903cae 100644 --- a/src/Nazara/Utility/Mesh.cpp +++ b/src/Nazara/Utility/Mesh.cpp @@ -795,7 +795,7 @@ namespace Nz return MeshLoader::LoadFromMemory(this, data, size, params); } - bool Mesh::LoadFromStream(InputStream& stream, const MeshParams& params) + bool Mesh::LoadFromStream(Stream& stream, const MeshParams& params) { return MeshLoader::LoadFromStream(this, stream, params); } From c93e4e901e16b47ba5380ffa15e75643ad5fb9a3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 20 Nov 2015 14:23:10 +0100 Subject: [PATCH 73/97] Core: Add Serializer/Unserializer Former-commit-id: 50fdf56da4fef46ec78995cb8fc277cbc9a11ebc --- include/Nazara/Core.hpp | 6 +- include/Nazara/Core/MemoryStream.hpp | 58 ------------------ include/Nazara/Core/MemoryStream.inl | 15 ----- include/Nazara/Core/Serializer.hpp | 44 ++++++++++++++ include/Nazara/Core/Serializer.inl | 45 ++++++++++++++ include/Nazara/Core/Unserializer.hpp | 44 ++++++++++++++ include/Nazara/Core/Unserializer.inl | 45 ++++++++++++++ src/Nazara/Core/MemoryStream.cpp | 90 ---------------------------- 8 files changed, 182 insertions(+), 165 deletions(-) delete mode 100644 include/Nazara/Core/MemoryStream.hpp delete mode 100644 include/Nazara/Core/MemoryStream.inl create mode 100644 include/Nazara/Core/Serializer.hpp create mode 100644 include/Nazara/Core/Serializer.inl create mode 100644 include/Nazara/Core/Unserializer.hpp create mode 100644 include/Nazara/Core/Unserializer.inl delete mode 100644 src/Nazara/Core/MemoryStream.cpp diff --git a/include/Nazara/Core.hpp b/include/Nazara/Core.hpp index a1d87c0a2..50aecb311 100644 --- a/include/Nazara/Core.hpp +++ b/include/Nazara/Core.hpp @@ -1,4 +1,4 @@ -// This file was automatically generated on 17 Nov 2015 at 13:20:45 +// This file was automatically generated on 20 Nov 2015 at 14:22:32 /* Nazara Engine - Core module @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include @@ -70,6 +69,8 @@ #include #include #include +#include +#include #include #include #include @@ -78,6 +79,7 @@ #include #include #include +#include #include #endif // NAZARA_GLOBAL_CORE_HPP diff --git a/include/Nazara/Core/MemoryStream.hpp b/include/Nazara/Core/MemoryStream.hpp deleted file mode 100644 index 7328b7707..000000000 --- a/include/Nazara/Core/MemoryStream.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#pragma once - -#ifndef NAZARA_MEMORYSTREAM_HPP -#define NAZARA_MEMORYSTREAM_HPP - -#include -#include -#include - -namespace Nz -{ - class NAZARA_CORE_API MemoryStream : public Stream - { - public: - MemoryStream(); - MemoryStream(const void* ptr, unsigned int size); - MemoryStream(const MemoryStream&) = default; - MemoryStream(MemoryStream&&) = default; - ~MemoryStream() = default; - - void Clear(); - - bool EndOfStream() const override; - - - const ByteArray& GetBuffer() const; - const UInt8* GetData() const; - UInt64 GetCursorPos() const override; - UInt64 GetSize() const override; - - bool SetCursorPos(UInt64 offset) override; - - MemoryStream& operator=(const MemoryStream&) = default; - MemoryStream& operator=(MemoryStream&&) = default; - - private: - void FlushStream() override; - std::size_t ReadBlock(void* buffer, std::size_t size) override; - std::size_t WriteBlock(const void* buffer, std::size_t size) override; - - ByteArray m_buffer; - UInt64 m_pos; - }; - - class AbstractHash; - - inline bool HashAppend(AbstractHash* hash, const String& string); - NAZARA_CORE_API bool Serialize(SerializationContext& context, const String& string); - NAZARA_CORE_API bool Unserialize(UnserializationContext& context, String* string); -} - -#include - -#endif // NAZARA_MEMORYSTREAM_HPP diff --git a/include/Nazara/Core/MemoryStream.inl b/include/Nazara/Core/MemoryStream.inl deleted file mode 100644 index 61b2f0bb4..000000000 --- a/include/Nazara/Core/MemoryStream.inl +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include - -namespace Nz -{ - inline bool HashAppend(AbstractHash* hash, const MemoryStream& stream) - { - return HashAppend(hash, stream.GetBuffer()); - } -} - -#include diff --git a/include/Nazara/Core/Serializer.hpp b/include/Nazara/Core/Serializer.hpp new file mode 100644 index 000000000..95ca33190 --- /dev/null +++ b/include/Nazara/Core/Serializer.hpp @@ -0,0 +1,44 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_SERIALIZER_HPP +#define NAZARA_SERIALIZER_HPP + +#include +#include + +namespace Nz +{ + class Stream; + + class Serializer + { + public: + inline Serializer(Stream& stream); + Serializer(const Serializer&) = default; + Serializer(Serializer&&) = default; + ~Serializer() = default; + + inline Endianness GetDataEndianness() const; + inline Stream& GetStream() const; + + inline void SetDataEndianness(Endianness endiannes); + inline void SetStream(Stream& stream); + + template + Serializer& operator<<(const T& value); + + Serializer& operator=(const Serializer&) = default; + Serializer& operator=(Serializer&&) = default; + + private: + SerializationContext m_serializationContext; + }; +} + +#include + +#endif // NAZARA_SERIALIZER_HPP diff --git a/include/Nazara/Core/Serializer.inl b/include/Nazara/Core/Serializer.inl new file mode 100644 index 000000000..a61315090 --- /dev/null +++ b/include/Nazara/Core/Serializer.inl @@ -0,0 +1,45 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include + +namespace Nz +{ + inline Serializer::Serializer(Stream& stream) + { + m_serializationContext.endianness = Endianness_BigEndian; + m_serializationContext.stream = &stream; + } + + inline Endianness Serializer::GetDataEndianness() const + { + return m_serializationContext.endianness; + } + + inline Stream& Serializer::GetStream() const + { + return *m_serializationContext.stream; + } + + inline void Serializer::SetDataEndianness(Endianness endiannes) + { + m_serializationContext.endianness = endiannes; + } + + inline void Serializer::SetStream(Stream& stream) + { + m_serializationContext.stream = &stream; + } + + template + Serializer& Serializer::operator<<(const T& value) + { + if (!Serialize(m_serializationContext, value)) + NazaraError("Failed to serialize value"); + + return *this; + } +} + +#include diff --git a/include/Nazara/Core/Unserializer.hpp b/include/Nazara/Core/Unserializer.hpp new file mode 100644 index 000000000..359fc1a7d --- /dev/null +++ b/include/Nazara/Core/Unserializer.hpp @@ -0,0 +1,44 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef NAZARA_UNSERIALIZER_HPP +#define NAZARA_UNSERIALIZER_HPP + +#include +#include + +namespace Nz +{ + class Stream; + + class Unserializer + { + public: + inline Unserializer(Stream& stream); + Unserializer(const Unserializer&) = default; + Unserializer(Unserializer&&) = default; + ~Unserializer() = default; + + inline Endianness GetDataEndianness() const; + inline Stream& GetStream() const; + + inline void SetDataEndianness(Endianness endiannes); + inline void SetStream(Stream& stream); + + template + Unserializer& operator>>(T& value); + + Unserializer& operator=(const Unserializer&) = default; + Unserializer& operator=(Unserializer&&) = default; + + private: + UnserializationContext m_unserializationContext; + }; +} + +#include + +#endif // NAZARA_UNSERIALIZER_HPP diff --git a/include/Nazara/Core/Unserializer.inl b/include/Nazara/Core/Unserializer.inl new file mode 100644 index 000000000..97f91214f --- /dev/null +++ b/include/Nazara/Core/Unserializer.inl @@ -0,0 +1,45 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Core module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include + +namespace Nz +{ + inline Unserializer::Unserializer(Stream& stream) + { + m_unserializationContext.endianness = Endianness_BigEndian; + m_unserializationContext.stream = &stream; + } + + inline Endianness Unserializer::GetDataEndianness() const + { + return m_unserializationContext.endianness; + } + + inline Stream& Unserializer::GetStream() const + { + return *m_unserializationContext.stream; + } + + inline void Unserializer::SetDataEndianness(Endianness endiannes) + { + m_unserializationContext.endianness = endiannes; + } + + inline void Unserializer::SetStream(Stream& stream) + { + m_unserializationContext.stream = &stream; + } + + template + Unserializer& Unserializer::operator>>(T& value) + { + if (!Unserialize(m_unserializationContext, &value)) + NazaraError("Failed to serialize value"); + + return *this; + } +} + +#include diff --git a/src/Nazara/Core/MemoryStream.cpp b/src/Nazara/Core/MemoryStream.cpp deleted file mode 100644 index f92d6a3c0..000000000 --- a/src/Nazara/Core/MemoryStream.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (C) 2015 Jérôme Leclercq -// This file is part of the "Nazara Engine - Core module" -// For conditions of distribution and use, see copyright notice in Config.hpp - -#include -#include -#include -#include - -namespace Nz -{ - MemoryStream::MemoryStream() : - Stream(OpenMode_ReadWrite), - m_pos(0) - { - } - - MemoryStream::MemoryStream(const void* ptr, unsigned int size) : - MemoryStream() - { - m_buffer.Resize(size); - std::memcpy(m_buffer.GetBuffer(), ptr, size); - } - - void MemoryStream::Clear() - { - m_buffer.Clear(); - m_pos = 0; - } - - bool MemoryStream::EndOfStream() const - { - return m_pos >= m_buffer.size(); - } - - const ByteArray& MemoryStream::GetBuffer() const - { - return m_buffer; - } - - UInt64 MemoryStream::GetCursorPos() const - { - return m_pos; - } - - const UInt8* MemoryStream::GetData() const - { - return m_buffer.GetConstBuffer(); - } - - UInt64 MemoryStream::GetSize() const - { - return m_buffer.size(); - } - - bool MemoryStream::SetCursorPos(UInt64 offset) - { - m_pos = std::min(offset, m_buffer.size()); - - return true; - } - - void MemoryStream::FlushStream() - { - // Nothing to flush - } - - std::size_t MemoryStream::ReadBlock(void* buffer, std::size_t size) - { - std::size_t readSize = std::min(size, static_cast(m_buffer.size() - m_pos)); - - if (buffer) - std::memcpy(buffer, m_buffer.GetBuffer() + m_pos, readSize); - - m_pos += readSize; - return readSize; - } - - std::size_t MemoryStream::WriteBlock(const void* buffer, std::size_t size) - { - std::size_t endPos = static_cast(m_pos + size); - if (endPos > m_buffer.size()) - m_buffer.Resize(endPos); - - std::memcpy(m_buffer.GetBuffer(), buffer, size); - - m_pos = endPos; - return size; - } -} From b0d26759945f1e1e9d8970b72ba3a95de16acfa3 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sun, 22 Nov 2015 15:53:31 +0100 Subject: [PATCH 74/97] Network/Algorithm: Fix external linking Former-commit-id: 7ad005245e1a93d0c2a8981d654dcfce462fcbd7 --- include/Nazara/Network/Algorithm.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Network/Algorithm.hpp b/include/Nazara/Network/Algorithm.hpp index 554f67d37..ec8164ef4 100644 --- a/include/Nazara/Network/Algorithm.hpp +++ b/include/Nazara/Network/Algorithm.hpp @@ -8,12 +8,13 @@ #define NAZARA_ALGORITHM_NETWORK_HPP #include +#include #include #include namespace Nz { - bool ParseIPAddress(const char* addressPtr, UInt8 result[16], UInt16* port = nullptr, bool* isIPv6 = nullptr, const char** endOfRead = nullptr); + NAZARA_NETWORK_API bool ParseIPAddress(const char* addressPtr, UInt8 result[16], UInt16* port = nullptr, bool* isIPv6 = nullptr, const char** endOfRead = nullptr); } #include From 7f220ce48ce0a46dd7246bbba92458e7339475cc Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 23 Nov 2015 13:45:35 +0100 Subject: [PATCH 75/97] Core/Serialization: Add bit serialization Former-commit-id: dbaf3a2d40a85955b4d48efba72a5df9d92d0eb1 --- include/Nazara/Core/Algorithm.inl | 46 +++++++++++++++++++++------ include/Nazara/Core/Serialization.hpp | 4 +++ include/Nazara/Core/Serializer.hpp | 2 +- include/Nazara/Core/Serializer.inl | 14 ++++++++ include/Nazara/Core/Stream.inl | 2 +- include/Nazara/Core/Unserializer.inl | 1 + 6 files changed, 58 insertions(+), 11 deletions(-) diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 6e3d8853a..2e9661dd9 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -80,14 +80,33 @@ namespace Nz inline bool Serialize(SerializationContext& context, bool value) { - ///TODO: Handle bits writing (Serializing 8 bits should only use one byte) - UInt8 buffer = (value) ? 1 : 0; - return context.stream->Write(&buffer, 1) == 1; + if (context.currentBitPos == 8) + { + context.currentBitPos = 0; + context.currentByte = 0; + } + + if (value) + context.currentByte |= 1 << context.currentBitPos; + + if (++context.currentBitPos >= 8) + return Serialize(context, context.currentByte); + else + return true; } template std::enable_if_t::value, bool> Serialize(SerializationContext& context, T value) { + // Flush bits if a writing is in progress + if (context.currentBitPos != 8) + { + context.currentBitPos = 8; + + if (!Serialize(context, context.currentByte)) + NazaraWarning("Failed to flush bits"); + } + if (context.endianness != Endianness_Unknown && context.endianness != GetPlatformEndianness()) SwapBytes(&value, sizeof(T)); @@ -98,14 +117,20 @@ namespace Nz { NazaraAssert(value, "Invalid data pointer"); - UInt8 buffer; - if (context.stream->Read(&buffer, 1) == 1) + if (context.currentBitPos == 8) { - *value = (buffer == 1); - return true; + if (!Unserialize(context, &context.currentByte)) + return false; + + context.currentBitPos = 0; } - else - return false; + + if (value) + *value = (context.currentByte & (1 << context.currentBitPos)) != 0; + + context.currentBitPos++; + + return true; } template @@ -113,6 +138,9 @@ namespace Nz { NazaraAssert(value, "Invalid data pointer"); + // Reset bit position + context.currentBitPos = 8; + if (context.stream->Read(value, sizeof(T)) == sizeof(T)) { if (context.endianness != Endianness_Unknown && context.endianness != GetPlatformEndianness()) diff --git a/include/Nazara/Core/Serialization.hpp b/include/Nazara/Core/Serialization.hpp index 36e77caea..409aa6ace 100644 --- a/include/Nazara/Core/Serialization.hpp +++ b/include/Nazara/Core/Serialization.hpp @@ -21,12 +21,16 @@ namespace Nz { Stream* stream; Endianness endianness; + UInt8 currentBitPos; + UInt8 currentByte; }; struct UnserializationContext { Stream* stream; Endianness endianness; + UInt8 currentBitPos; + UInt8 currentByte; }; } diff --git a/include/Nazara/Core/Serializer.hpp b/include/Nazara/Core/Serializer.hpp index 95ca33190..994e85a19 100644 --- a/include/Nazara/Core/Serializer.hpp +++ b/include/Nazara/Core/Serializer.hpp @@ -20,7 +20,7 @@ namespace Nz inline Serializer(Stream& stream); Serializer(const Serializer&) = default; Serializer(Serializer&&) = default; - ~Serializer() = default; + ~Serializer(); inline Endianness GetDataEndianness() const; inline Stream& GetStream() const; diff --git a/include/Nazara/Core/Serializer.inl b/include/Nazara/Core/Serializer.inl index a61315090..168d7f812 100644 --- a/include/Nazara/Core/Serializer.inl +++ b/include/Nazara/Core/Serializer.inl @@ -2,16 +2,29 @@ // This file is part of the "Nazara Engine - Core module" // For conditions of distribution and use, see copyright notice in Config.hpp +#include #include namespace Nz { inline Serializer::Serializer(Stream& stream) { + m_serializationContext.currentBitPos = 8; m_serializationContext.endianness = Endianness_BigEndian; m_serializationContext.stream = &stream; } + inline Serializer::~Serializer() + { + if (m_serializationContext.currentBitPos != 8) + { + m_serializationContext.currentBitPos = 8; //< To prevent Serialize to flush bits itself + + if (!Serialize(m_serializationContext, m_serializationContext.currentByte)) + NazaraWarning("Failed to flush bits at serializer destruction"); + } + } + inline Endianness Serializer::GetDataEndianness() const { return m_serializationContext.endianness; @@ -43,3 +56,4 @@ namespace Nz } #include +#include "Serializer.hpp" diff --git a/include/Nazara/Core/Stream.inl b/include/Nazara/Core/Stream.inl index a7e17a099..6c5098060 100644 --- a/include/Nazara/Core/Stream.inl +++ b/include/Nazara/Core/Stream.inl @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include "Stream.hpp" namespace Nz { @@ -70,5 +71,4 @@ namespace Nz return WriteBlock(buffer, size); } - } diff --git a/include/Nazara/Core/Unserializer.inl b/include/Nazara/Core/Unserializer.inl index 97f91214f..3a832504a 100644 --- a/include/Nazara/Core/Unserializer.inl +++ b/include/Nazara/Core/Unserializer.inl @@ -8,6 +8,7 @@ namespace Nz { inline Unserializer::Unserializer(Stream& stream) { + m_unserializationContext.currentBitPos = 8; m_unserializationContext.endianness = Endianness_BigEndian; m_unserializationContext.stream = &stream; } From 6829863d81ea0a483a93ea268d5817f7123c8b6e Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 23 Nov 2015 14:15:29 +0100 Subject: [PATCH 76/97] Core/Enum: Rename OpenMode_Current to NotOpen Former-commit-id: f4395871d68d8f6da5ca6dbcda2177ad6aae2fc8 --- include/Nazara/Core/Enums.hpp | 2 +- include/Nazara/Core/File.hpp | 4 ++-- src/Nazara/Core/File.cpp | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Core/Enums.hpp b/include/Nazara/Core/Enums.hpp index a5de16a44..1fd884799 100644 --- a/include/Nazara/Core/Enums.hpp +++ b/include/Nazara/Core/Enums.hpp @@ -75,7 +75,7 @@ namespace Nz enum OpenModeFlags { - OpenMode_Current = 0x00, // Utilise le mode d'ouverture actuel + OpenMode_NotOpen = 0x00, // Utilise le mode d'ouverture actuel OpenMode_Append = 0x01, // Empêche l'écriture sur la partie déjà existante et met le curseur à la fin OpenMode_Lock = 0x02, // Empêche le fichier d'être modifié tant qu'il est ouvert diff --git a/include/Nazara/Core/File.hpp b/include/Nazara/Core/File.hpp index 02ecb153a..6b905fbac 100644 --- a/include/Nazara/Core/File.hpp +++ b/include/Nazara/Core/File.hpp @@ -57,8 +57,8 @@ namespace Nz bool IsOpen() const; - bool Open(unsigned int openMode = OpenMode_Current); - bool Open(const String& filePath, unsigned int openMode = OpenMode_Current); + bool Open(unsigned int openMode = OpenMode_NotOpen); + bool Open(const String& filePath, unsigned int openMode = OpenMode_NotOpen); bool Rename(const String& newFilePath); diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index c6ad0e257..c21073efe 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -31,7 +31,7 @@ namespace Nz { File::File() : - Stream(OpenMode_Current), + Stream(OpenMode_NotOpen), m_impl(nullptr) { } From 4721bf80c384e31ac40fcc6667f2e2117cc757ae Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 23 Nov 2015 18:22:12 +0100 Subject: [PATCH 77/97] Network/TcpClient: Make TcpClient a Stream Former-commit-id: 2176748166ae84b609d5a336495e6ff3550a765d --- include/Nazara/Core/Stream.hpp | 2 +- include/Nazara/Core/Stream.inl | 4 +- include/Nazara/Network/TcpClient.hpp | 13 ++++- include/Nazara/Network/TcpClient.inl | 2 + src/Nazara/Core/File.cpp | 11 ++--- src/Nazara/Network/TcpClient.cpp | 71 ++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 10 deletions(-) diff --git a/include/Nazara/Core/Stream.hpp b/include/Nazara/Core/Stream.hpp index ff4195802..63d7e781b 100644 --- a/include/Nazara/Core/Stream.hpp +++ b/include/Nazara/Core/Stream.hpp @@ -55,7 +55,7 @@ namespace Nz Stream& operator=(Stream&&) = default; protected: - inline Stream(UInt32 openMode); + inline Stream(UInt32 streamOptions = StreamOption_None, UInt32 openMode = OpenMode_NotOpen); virtual void FlushStream() = 0; virtual std::size_t ReadBlock(void* buffer, std::size_t size) = 0; diff --git a/include/Nazara/Core/Stream.inl b/include/Nazara/Core/Stream.inl index 6c5098060..104d5e300 100644 --- a/include/Nazara/Core/Stream.inl +++ b/include/Nazara/Core/Stream.inl @@ -7,9 +7,9 @@ namespace Nz { - inline Stream::Stream(UInt32 openMode) : + inline Stream::Stream(UInt32 streamOptions, UInt32 openMode) : m_openMode(openMode), - m_streamOptions(0) + m_streamOptions(streamOptions) { } diff --git a/include/Nazara/Network/TcpClient.hpp b/include/Nazara/Network/TcpClient.hpp index ef696fac3..f06a43836 100644 --- a/include/Nazara/Network/TcpClient.hpp +++ b/include/Nazara/Network/TcpClient.hpp @@ -9,12 +9,13 @@ #include #include +#include #include #include namespace Nz { - class NAZARA_NETWORK_API TcpClient : public AbstractSocket + class NAZARA_NETWORK_API TcpClient : public AbstractSocket, public Stream { friend class TcpServer; @@ -30,9 +31,13 @@ namespace Nz void EnableLowDelay(bool lowDelay); void EnableKeepAlive(bool keepAlive, UInt64 msTime = 10000, UInt64 msInterval = 1000); + bool EndOfStream() const override; + + UInt64 GetCursorPos() const override; inline UInt64 GetKeepAliveInterval() const; inline UInt64 GetKeepAliveTime() const; inline IpAddress GetRemoteAddress() const; + UInt64 GetSize() const override; inline bool IsLowDelayEnabled() const; inline bool IsKeepAliveEnabled() const; @@ -41,13 +46,19 @@ namespace Nz bool Send(const void* buffer, std::size_t size, std::size_t* sent); + bool SetCursorPos(UInt64 offset) override; + bool WaitForConnected(UInt64 msTimeout = 3000); private: + void FlushStream() override; + void OnClose() override; void OnOpened() override; + std::size_t ReadBlock(void* buffer, std::size_t size) override; void Reset(SocketHandle handle, const IpAddress& peerAddress); + std::size_t WriteBlock(const void* buffer, std::size_t size) override; IpAddress m_peerAddress; UInt64 m_keepAliveInterval; diff --git a/include/Nazara/Network/TcpClient.inl b/include/Nazara/Network/TcpClient.inl index 60c879497..5348d2152 100644 --- a/include/Nazara/Network/TcpClient.inl +++ b/include/Nazara/Network/TcpClient.inl @@ -9,6 +9,7 @@ namespace Nz { inline TcpClient::TcpClient() : AbstractSocket(SocketType_TCP), + Stream(StreamOption_Sequential), m_keepAliveInterval(1000), //TODO: Query OS default value m_keepAliveTime(7'200'000), //TODO: Query OS default value m_isKeepAliveEnabled(false), //TODO: Query OS default value @@ -18,6 +19,7 @@ namespace Nz inline TcpClient::TcpClient(TcpClient&& tcpClient) : AbstractSocket(std::move(tcpClient)), + Stream(std::move(tcpClient)), m_peerAddress(std::move(tcpClient.m_peerAddress)), m_keepAliveInterval(tcpClient.m_keepAliveInterval), m_keepAliveTime(tcpClient.m_keepAliveTime), diff --git a/src/Nazara/Core/File.cpp b/src/Nazara/Core/File.cpp index c21073efe..db71f2d95 100644 --- a/src/Nazara/Core/File.cpp +++ b/src/Nazara/Core/File.cpp @@ -31,7 +31,6 @@ namespace Nz { File::File() : - Stream(OpenMode_NotOpen), m_impl(nullptr) { } @@ -75,6 +74,8 @@ namespace Nz m_impl->Close(); delete m_impl; m_impl = nullptr; + + m_openMode = OpenMode_NotOpen; } } @@ -208,20 +209,18 @@ namespace Nz if (m_filePath.IsEmpty()) return false; - if (openMode != 0) - m_openMode = openMode; - - if (m_openMode == 0) + if (openMode == OpenMode_NotOpen) return false; std::unique_ptr impl(new FileImpl(this)); - if (!impl->Open(m_filePath, m_openMode)) + if (!impl->Open(m_filePath, openMode)) { ErrorFlags flags(ErrorFlag_Silent); // Silencieux par défaut NazaraError("Failed to open \"" + m_filePath + "\": " + Error::GetLastSystemError()); return false; } + m_openMode = openMode; m_impl = impl.release(); if (m_openMode & OpenMode_Text) diff --git a/src/Nazara/Network/TcpClient.cpp b/src/Nazara/Network/TcpClient.cpp index 4c13c5c03..b91dfaffd 100644 --- a/src/Nazara/Network/TcpClient.cpp +++ b/src/Nazara/Network/TcpClient.cpp @@ -94,6 +94,22 @@ namespace Nz } } + bool TcpClient::EndOfStream() const + { + return QueryAvailableBytes() == 0; + } + + UInt64 TcpClient::GetCursorPos() const + { + NazaraError("GetCursorPos() cannot be used on sequential streams"); + return 0; + } + + UInt64 TcpClient::GetSize() const + { + return QueryAvailableBytes(); + } + bool TcpClient::Receive(void* buffer, std::size_t size, std::size_t* received) { NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); @@ -165,6 +181,12 @@ namespace Nz return true; } + bool TcpClient::SetCursorPos(UInt64 offset) + { + NazaraError("SetCursorPos() cannot be used on sequential streams"); + return false; + } + bool TcpClient::WaitForConnected(UInt64 msTimeout) { switch (m_state) @@ -209,10 +231,15 @@ namespace Nz return false; } + void TcpClient::FlushStream() + { + } + void TcpClient::OnClose() { AbstractSocket::OnClose(); + m_openMode = OpenMode_NotOpen; m_peerAddress = IpAddress::Invalid; } @@ -229,12 +256,56 @@ namespace Nz NazaraWarning("Failed to set socket keep alive mode (0x" + String::Number(errorCode, 16) + ')'); m_peerAddress = IpAddress::Invalid; + m_openMode = OpenMode_ReadWrite; + } + + std::size_t TcpClient::ReadBlock(void* buffer, std::size_t size) + { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); + + CallOnExit restoreBlocking; + if (!m_isBlockingEnabled) + { + SocketImpl::SetBlocking(m_handle, true); + restoreBlocking.Reset([this] () + { + SocketImpl::SetBlocking(m_handle, false); + }); + } + + std::size_t received; + if (!Receive(buffer, size, &received)) + received = 0; + + return received; } void TcpClient::Reset(SocketHandle handle, const IpAddress& peerAddress) { Open(handle); m_peerAddress = peerAddress; + m_openMode = OpenMode_ReadWrite; UpdateState(SocketState_Connected); } + + std::size_t TcpClient::WriteBlock(const void* buffer, std::size_t size) + { + NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle"); + + CallOnExit restoreBlocking; + if (!m_isBlockingEnabled) + { + SocketImpl::SetBlocking(m_handle, true); + restoreBlocking.Reset([this] () + { + SocketImpl::SetBlocking(m_handle, false); + }); + } + + std::size_t sent; + if (!Send(buffer, size, &sent)) + sent = 0; + + return sent; + } } From bbe8a776e896d64f64463252ed66d4daf739905e Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 25 Nov 2015 18:19:26 +0100 Subject: [PATCH 78/97] Fix a shitloads of warnings on VS Former-commit-id: fca61118f4e0530ed2eaaf9ff96de29806aa5aa8 --- include/Nazara/Core/AbstractHash.hpp | 4 +- include/Nazara/Core/ByteArray.inl | 4 +- include/Nazara/Core/Color.inl | 18 +- include/Nazara/Core/Error.hpp | 4 +- include/Nazara/Core/Hash/CRC32.hpp | 4 +- include/Nazara/Core/Hash/Fletcher16.hpp | 4 +- include/Nazara/Core/Hash/MD5.hpp | 4 +- include/Nazara/Core/Hash/SHA1.hpp | 4 +- include/Nazara/Core/Hash/SHA224.hpp | 4 +- include/Nazara/Core/Hash/SHA256.hpp | 4 +- include/Nazara/Core/Hash/SHA384.hpp | 4 +- include/Nazara/Core/Hash/SHA512.hpp | 4 +- include/Nazara/Core/Hash/Whirlpool.hpp | 4 +- include/Nazara/Core/PrimitiveList.hpp | 7 +- include/Nazara/Core/String.hpp | 150 +++---- include/Nazara/Core/String.inl | 4 +- include/Nazara/Core/StringStream.hpp | 2 +- include/Nazara/Math/Algorithm.hpp | 2 +- include/Nazara/Math/Algorithm.inl | 5 +- include/Nazara/Math/Vector3.inl | 4 +- include/Nazara/Utility/VertexDeclaration.hpp | 12 +- include/Nazara/Utility/VertexMapper.inl | 2 +- src/Nazara/Core/Directory.cpp | 36 +- src/Nazara/Core/GuillotineBinPack.cpp | 16 +- src/Nazara/Core/Hash/CRC32.cpp | 4 +- src/Nazara/Core/Hash/Fletcher16.cpp | 6 +- src/Nazara/Core/Hash/MD5.cpp | 4 +- src/Nazara/Core/Hash/SHA1.cpp | 4 +- src/Nazara/Core/Hash/SHA224.cpp | 4 +- src/Nazara/Core/Hash/SHA256.cpp | 4 +- src/Nazara/Core/Hash/SHA384.cpp | 4 +- src/Nazara/Core/Hash/SHA512.cpp | 4 +- src/Nazara/Core/Hash/Whirlpool.cpp | 8 +- src/Nazara/Core/MemoryManager.cpp | 1 - src/Nazara/Core/PrimitiveList.cpp | 26 +- src/Nazara/Core/Stream.cpp | 8 +- src/Nazara/Core/String.cpp | 408 +++++++++---------- src/Nazara/Core/Win32/TaskSchedulerImpl.cpp | 20 +- src/Nazara/Core/Win32/TaskSchedulerImpl.hpp | 10 +- src/Nazara/Renderer/Renderer.cpp | 2 +- src/Nazara/Utility/Algorithm.cpp | 12 +- src/Nazara/Utility/VertexDeclaration.cpp | 8 +- 42 files changed, 406 insertions(+), 437 deletions(-) diff --git a/include/Nazara/Core/AbstractHash.hpp b/include/Nazara/Core/AbstractHash.hpp index bc0a1a4a9..f3c848ed3 100644 --- a/include/Nazara/Core/AbstractHash.hpp +++ b/include/Nazara/Core/AbstractHash.hpp @@ -23,11 +23,11 @@ namespace Nz AbstractHash(AbstractHash&&) = default; virtual ~AbstractHash(); - virtual void Append(const UInt8* data, unsigned int len) = 0; + virtual void Append(const UInt8* data, std::size_t len) = 0; virtual void Begin() = 0; virtual ByteArray End() = 0; - virtual unsigned int GetDigestLength() const = 0; + virtual std::size_t GetDigestLength() const = 0; virtual const char* GetHashName() const = 0; AbstractHash& operator=(const AbstractHash&) = delete; diff --git a/include/Nazara/Core/ByteArray.inl b/include/Nazara/Core/ByteArray.inl index 19d7e115b..1597758fd 100644 --- a/include/Nazara/Core/ByteArray.inl +++ b/include/Nazara/Core/ByteArray.inl @@ -204,10 +204,10 @@ namespace Nz inline String ByteArray::ToHex() const { - unsigned int length = m_array.size() * 2; + std::size_t length = m_array.size() * 2; String hexOutput(length, '\0'); - for (unsigned int i = 0; i < m_array.size(); ++i) + for (std::size_t i = 0; i < m_array.size(); ++i) std::sprintf(&hexOutput[i * 2], "%02x", m_array[i]); return hexOutput; diff --git a/include/Nazara/Core/Color.inl b/include/Nazara/Core/Color.inl index 8bf6dd414..ac576eee3 100644 --- a/include/Nazara/Core/Color.inl +++ b/include/Nazara/Core/Color.inl @@ -54,22 +54,24 @@ namespace Nz inline Color Color::operator+(const Color& color) const { + ///TODO: Improve this shit Color c; - c.r = std::min(static_cast(r) + static_cast(color.r), 255U); - c.g = std::min(static_cast(g) + static_cast(color.g), 255U); - c.b = std::min(static_cast(b) + static_cast(color.b), 255U); - c.a = std::min(static_cast(a) + static_cast(color.a), 255U); + c.r = static_cast(std::min(static_cast(r) + static_cast(color.r), 255U)); + c.g = static_cast(std::min(static_cast(g) + static_cast(color.g), 255U)); + c.b = static_cast(std::min(static_cast(b) + static_cast(color.b), 255U)); + c.a = static_cast(std::min(static_cast(a) + static_cast(color.a), 255U)); return c; } inline Color Color::operator*(const Color& color) const { + ///TODO: Improve this shit Color c; - c.r = (static_cast(r) * static_cast(color.r)) / 255U; - c.g = (static_cast(g) * static_cast(color.g)) / 255U; - c.b = (static_cast(b) * static_cast(color.b)) / 255U; - c.a = (static_cast(a) * static_cast(color.a)) / 255U; + c.r = static_cast((static_cast(r) * static_cast(color.r)) / 255U); + c.g = static_cast((static_cast(g) * static_cast(color.g)) / 255U); + c.b = static_cast((static_cast(b) * static_cast(color.b)) / 255U); + c.a = static_cast((static_cast(a) * static_cast(color.a)) / 255U); return c; } diff --git a/include/Nazara/Core/Error.hpp b/include/Nazara/Core/Error.hpp index badfa39c2..b210c2e1d 100644 --- a/include/Nazara/Core/Error.hpp +++ b/include/Nazara/Core/Error.hpp @@ -14,9 +14,9 @@ #include #if NAZARA_CORE_ENABLE_ASSERTS || defined(NAZARA_DEBUG) - #define NazaraAssert(a, err) do { if (!(a)) Nz::Error::Trigger(Nz::ErrorType_AssertFailed, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION); } while (false) + #define NazaraAssert(a, err) if (!(a)) Nz::Error::Trigger(Nz::ErrorType_AssertFailed, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) #else - #define NazaraAssert(a, err) do {} while (false) + #define NazaraAssert(a, err) for (;;) break #endif #define NazaraError(err) Nz::Error::Trigger(Nz::ErrorType_Normal, err, __LINE__, Nz::Directory::GetCurrentFileRelativeToEngine(__FILE__), NAZARA_FUNCTION) diff --git a/include/Nazara/Core/Hash/CRC32.hpp b/include/Nazara/Core/Hash/CRC32.hpp index 1898ffae4..79da031b3 100644 --- a/include/Nazara/Core/Hash/CRC32.hpp +++ b/include/Nazara/Core/Hash/CRC32.hpp @@ -21,11 +21,11 @@ namespace Nz HashCRC32(UInt32 polynomial = 0x04c11db7); virtual ~HashCRC32(); - void Append(const UInt8* data, unsigned int len) override; + void Append(const UInt8* data, std::size_t len) override; void Begin() override; ByteArray End() override; - unsigned int GetDigestLength() const override; + std::size_t GetDigestLength() const override; const char* GetHashName() const override; private: diff --git a/include/Nazara/Core/Hash/Fletcher16.hpp b/include/Nazara/Core/Hash/Fletcher16.hpp index a4e296f38..6bc95db68 100644 --- a/include/Nazara/Core/Hash/Fletcher16.hpp +++ b/include/Nazara/Core/Hash/Fletcher16.hpp @@ -22,11 +22,11 @@ namespace Nz HashFletcher16(); virtual ~HashFletcher16(); - void Append(const UInt8* data, unsigned int len) override; + void Append(const UInt8* data, std::size_t len) override; void Begin() override; ByteArray End() override; - unsigned int GetDigestLength() const override; + std::size_t GetDigestLength() const override; const char* GetHashName() const override; private: diff --git a/include/Nazara/Core/Hash/MD5.hpp b/include/Nazara/Core/Hash/MD5.hpp index 20fee5e38..1c8bd0d25 100644 --- a/include/Nazara/Core/Hash/MD5.hpp +++ b/include/Nazara/Core/Hash/MD5.hpp @@ -21,11 +21,11 @@ namespace Nz HashMD5(); virtual ~HashMD5(); - void Append(const UInt8* data, unsigned int len) override; + void Append(const UInt8* data, std::size_t len) override; void Begin() override; ByteArray End() override; - unsigned int GetDigestLength() const override; + std::size_t GetDigestLength() const override; const char* GetHashName() const override; private: diff --git a/include/Nazara/Core/Hash/SHA1.hpp b/include/Nazara/Core/Hash/SHA1.hpp index 4f80d3ca1..8e410adb7 100644 --- a/include/Nazara/Core/Hash/SHA1.hpp +++ b/include/Nazara/Core/Hash/SHA1.hpp @@ -21,11 +21,11 @@ namespace Nz HashSHA1(); virtual ~HashSHA1(); - void Append(const UInt8* data, unsigned int len) override; + void Append(const UInt8* data, std::size_t len) override; void Begin() override; ByteArray End() override; - unsigned int GetDigestLength() const override; + std::size_t GetDigestLength() const override; const char* GetHashName() const override; private: diff --git a/include/Nazara/Core/Hash/SHA224.hpp b/include/Nazara/Core/Hash/SHA224.hpp index 9d97e3193..48893c8d0 100644 --- a/include/Nazara/Core/Hash/SHA224.hpp +++ b/include/Nazara/Core/Hash/SHA224.hpp @@ -21,11 +21,11 @@ namespace Nz HashSHA224(); virtual ~HashSHA224(); - void Append(const UInt8* data, unsigned int len) override; + void Append(const UInt8* data, std::size_t len) override; void Begin() override; ByteArray End() override; - unsigned int GetDigestLength() const override; + std::size_t GetDigestLength() const override; const char* GetHashName() const override; private: diff --git a/include/Nazara/Core/Hash/SHA256.hpp b/include/Nazara/Core/Hash/SHA256.hpp index 5398f363b..1adf5ad52 100644 --- a/include/Nazara/Core/Hash/SHA256.hpp +++ b/include/Nazara/Core/Hash/SHA256.hpp @@ -21,11 +21,11 @@ namespace Nz HashSHA256(); virtual ~HashSHA256(); - void Append(const UInt8* data, unsigned int len) override; + void Append(const UInt8* data, std::size_t len) override; void Begin() override; ByteArray End() override; - unsigned int GetDigestLength() const override; + std::size_t GetDigestLength() const override; const char* GetHashName() const override; private: diff --git a/include/Nazara/Core/Hash/SHA384.hpp b/include/Nazara/Core/Hash/SHA384.hpp index a84fc8a4e..54643cbbd 100644 --- a/include/Nazara/Core/Hash/SHA384.hpp +++ b/include/Nazara/Core/Hash/SHA384.hpp @@ -21,11 +21,11 @@ namespace Nz HashSHA384(); virtual ~HashSHA384(); - void Append(const UInt8* data, unsigned int len) override; + void Append(const UInt8* data, std::size_t len) override; void Begin() override; ByteArray End() override; - unsigned int GetDigestLength() const override; + std::size_t GetDigestLength() const override; const char* GetHashName() const override; private: diff --git a/include/Nazara/Core/Hash/SHA512.hpp b/include/Nazara/Core/Hash/SHA512.hpp index 7a49aaf72..a17726b74 100644 --- a/include/Nazara/Core/Hash/SHA512.hpp +++ b/include/Nazara/Core/Hash/SHA512.hpp @@ -21,11 +21,11 @@ namespace Nz HashSHA512(); virtual ~HashSHA512(); - void Append(const UInt8* data, unsigned int len) override; + void Append(const UInt8* data, std::size_t len) override; void Begin() override; ByteArray End() override; - unsigned int GetDigestLength() const override; + std::size_t GetDigestLength() const override; const char* GetHashName() const override; private: diff --git a/include/Nazara/Core/Hash/Whirlpool.hpp b/include/Nazara/Core/Hash/Whirlpool.hpp index 0da68015a..600e23b25 100644 --- a/include/Nazara/Core/Hash/Whirlpool.hpp +++ b/include/Nazara/Core/Hash/Whirlpool.hpp @@ -19,11 +19,11 @@ namespace Nz HashWhirlpool(); virtual ~HashWhirlpool(); - void Append(const UInt8* data, unsigned int len) override; + void Append(const UInt8* data, std::size_t len) override; void Begin() override; ByteArray End() override; - unsigned int GetDigestLength() const; + std::size_t GetDigestLength() const; const char* GetHashName() const; private: diff --git a/include/Nazara/Core/PrimitiveList.hpp b/include/Nazara/Core/PrimitiveList.hpp index d7fe83a0c..79d2363c2 100644 --- a/include/Nazara/Core/PrimitiveList.hpp +++ b/include/Nazara/Core/PrimitiveList.hpp @@ -13,6 +13,7 @@ namespace Nz { + ///TODO: Inline this class NAZARA_CORE_API PrimitiveList { public: @@ -35,9 +36,9 @@ namespace Nz void AddUVSphere(float size, unsigned int sliceCount = 4, unsigned int stackCount = 4, const Matrix4f& transformMatrix = Matrix4f::Identity()); void AddUVSphere(float size, unsigned int sliceCount, unsigned int stackCount, const Vector3f& position, const Quaternionf& rotation = Quaternionf::Identity()); - Primitive& GetPrimitive(unsigned int i); - const Primitive& GetPrimitive(unsigned int i) const; - unsigned int GetSize() const; + Primitive& GetPrimitive(std::size_t i); + const Primitive& GetPrimitive(std::size_t i) const; + std::size_t GetSize() const; PrimitiveList& operator=(const PrimitiveList&) = default; PrimitiveList& operator=(PrimitiveList&&) = default; diff --git a/include/Nazara/Core/String.hpp b/include/Nazara/Core/String.hpp index 7bfb21e5b..405eb7a19 100644 --- a/include/Nazara/Core/String.hpp +++ b/include/Nazara/Core/String.hpp @@ -32,12 +32,12 @@ namespace Nz String(); explicit String(char character); - String(unsigned int rep, char character); - String(unsigned int rep, const char* string); - String(unsigned int rep, const char* string, unsigned int length); - String(unsigned int rep, const String& string); + String(std::size_t rep, char character); + String(std::size_t rep, const char* string); + String(std::size_t rep, const char* string, std::size_t length); + String(std::size_t rep, const String& string); String(const char* string); - String(const char* string, unsigned int length); + String(const char* string, std::size_t length); String(const std::string& string); String(const String& string) = default; String(String&& string) noexcept = default; @@ -45,57 +45,57 @@ namespace Nz String& Append(char character); String& Append(const char* string); - String& Append(const char* string, unsigned int length); + String& Append(const char* string, std::size_t length); String& Append(const String& string); void Clear(bool keepBuffer = false); - bool Contains(char character, int start = 0, UInt32 flags = None) const; - bool Contains(const char* string, int start = 0, UInt32 flags = None) const; - bool Contains(const String& string, int start = 0, UInt32 flags = None) const; + bool Contains(char character, std::intmax_t start = 0, UInt32 flags = None) const; + bool Contains(const char* string, std::intmax_t start = 0, UInt32 flags = None) const; + bool Contains(const String& string, std::intmax_t start = 0, UInt32 flags = None) const; - unsigned int Count(char character, int start = 0, UInt32 flags = None) const; - unsigned int Count(const char* string, int start = 0, UInt32 flags = None) const; - unsigned int Count(const String& string, int start = 0, UInt32 flags = None) const; - unsigned int CountAny(const char* string, int start = 0, UInt32 flags = None) const; - unsigned int CountAny(const String& string, int start = 0, UInt32 flags = None) const; + unsigned int Count(char character, std::intmax_t start = 0, UInt32 flags = None) const; + unsigned int Count(const char* string, std::intmax_t start = 0, UInt32 flags = None) const; + unsigned int Count(const String& string, std::intmax_t start = 0, UInt32 flags = None) const; + unsigned int CountAny(const char* string, std::intmax_t start = 0, UInt32 flags = None) const; + unsigned int CountAny(const String& string, std::intmax_t start = 0, UInt32 flags = None) const; bool EndsWith(char character, UInt32 flags = None) const; bool EndsWith(const char* string, UInt32 flags = None) const; - bool EndsWith(const char* string, unsigned int length, UInt32 flags = None) const; + bool EndsWith(const char* string, std::size_t length, UInt32 flags = None) const; bool EndsWith(const String& string, UInt32 flags = None) const; - unsigned int Find(char character, int start = 0, UInt32 flags = None) const; - unsigned int Find(const char* string, int start = 0, UInt32 flags = None) const; - unsigned int Find(const String& string, int start = 0, UInt32 flags = None) const; - unsigned int FindAny(const char* string, int start = 0, UInt32 flags = None) const; - unsigned int FindAny(const String& string, int start = 0, UInt32 flags = None) const; - unsigned int FindLast(char character, int start = -1, UInt32 flags = None) const; - unsigned int FindLast(const char *string, int start = -1, UInt32 flags = None) const; - unsigned int FindLast(const String& string, int start = -1, UInt32 flags = None) const; - unsigned int FindLastAny(const char* string, int start = -1, UInt32 flags = None) const; - unsigned int FindLastAny(const String& string, int start = -1, UInt32 flags = None) const; - unsigned int FindLastWord(const char* string, int start = -1, UInt32 flags = None) const; - unsigned int FindLastWord(const String& string, int start = -1, UInt32 flags = None) const; - unsigned int FindWord(const char* string, int start = 0, UInt32 flags = None) const; - unsigned int FindWord(const String& string, int start = 0, UInt32 flags = None) const; + std::size_t Find(char character, std::intmax_t start = 0, UInt32 flags = None) const; + std::size_t Find(const char* string, std::intmax_t start = 0, UInt32 flags = None) const; + std::size_t Find(const String& string, std::intmax_t start = 0, UInt32 flags = None) const; + std::size_t FindAny(const char* string, std::intmax_t start = 0, UInt32 flags = None) const; + std::size_t FindAny(const String& string, std::intmax_t start = 0, UInt32 flags = None) const; + std::size_t FindLast(char character, std::intmax_t start = -1, UInt32 flags = None) const; + std::size_t FindLast(const char *string, std::intmax_t start = -1, UInt32 flags = None) const; + std::size_t FindLast(const String& string, std::intmax_t start = -1, UInt32 flags = None) const; + std::size_t FindLastAny(const char* string, std::intmax_t start = -1, UInt32 flags = None) const; + std::size_t FindLastAny(const String& string, std::intmax_t start = -1, UInt32 flags = None) const; + std::size_t FindLastWord(const char* string, std::intmax_t start = -1, UInt32 flags = None) const; + std::size_t FindLastWord(const String& string, std::intmax_t start = -1, UInt32 flags = None) const; + std::size_t FindWord(const char* string, std::intmax_t start = 0, UInt32 flags = None) const; + std::size_t FindWord(const String& string, std::intmax_t start = 0, UInt32 flags = None) const; char* GetBuffer(); - unsigned int GetCapacity() const; + std::size_t GetCapacity() const; const char* GetConstBuffer() const; - unsigned int GetLength() const; - unsigned int GetSize() const; + std::size_t GetLength() const; + std::size_t GetSize() const; std::string GetUtf8String() const; std::u16string GetUtf16String() const; std::u32string GetUtf32String() const; std::wstring GetWideString() const; String GetWord(unsigned int index, UInt32 flags = None) const; - unsigned int GetWordPosition(unsigned int index, UInt32 flags = None) const; + std::size_t GetWordPosition(unsigned int index, UInt32 flags = None) const; - String& Insert(int pos, char character); - String& Insert(int pos, const char* string); - String& Insert(int pos, const char* string, unsigned int length); - String& Insert(int pos, const String& string); + String& Insert(std::intmax_t pos, char character); + String& Insert(std::intmax_t pos, const char* string); + String& Insert(std::intmax_t pos, const char* string, std::size_t length); + String& Insert(std::intmax_t pos, const String& string); bool IsEmpty() const; bool IsNull() const; @@ -106,32 +106,32 @@ namespace Nz String& Prepend(char character); String& Prepend(const char* string); - String& Prepend(const char* string, unsigned int length); + String& Prepend(const char* string, std::size_t length); String& Prepend(const String& string); - unsigned int Replace(char oldCharacter, char newCharacter, int start = 0, UInt32 flags = None); - unsigned int Replace(const char* oldString, const char* replaceString, int start = 0, UInt32 flags = None); - unsigned int Replace(const char* oldString, unsigned int oldLength, const char* replaceString, unsigned int replaceLength, int start = 0, UInt32 flags = None); - unsigned int Replace(const String& oldString, const String& replaceString, int start = 0, UInt32 flags = None); - unsigned int ReplaceAny(const char* oldCharacters, char replaceCharacter, int start = 0, UInt32 flags = None); - //unsigned int ReplaceAny(const char* oldCharacters, const char* replaceString, int start = 0, UInt32 flags = None); - //unsigned int ReplaceAny(const String& oldCharacters, const String& replaceString, int start = 0, UInt32 flags = None); + unsigned int Replace(char oldCharacter, char newCharacter, std::intmax_t start = 0, UInt32 flags = None); + unsigned int Replace(const char* oldString, const char* replaceString, std::intmax_t start = 0, UInt32 flags = None); + unsigned int Replace(const char* oldString, std::size_t oldLength, const char* replaceString, std::size_t replaceLength, std::intmax_t start = 0, UInt32 flags = None); + unsigned int Replace(const String& oldString, const String& replaceString, std::intmax_t start = 0, UInt32 flags = None); + unsigned int ReplaceAny(const char* oldCharacters, char replaceCharacter, std::intmax_t start = 0, UInt32 flags = None); + //unsigned int ReplaceAny(const char* oldCharacters, const char* replaceString, std::intmax_t start = 0, UInt32 flags = None); + //unsigned int ReplaceAny(const String& oldCharacters, const String& replaceString, std::intmax_t start = 0, UInt32 flags = None); - void Reserve(unsigned int bufferSize); + void Reserve(std::size_t bufferSize); - String& Resize(int size, char character = ' '); - String Resized(int size, char character = ' ') const; + String& Resize(std::intmax_t size, char character = ' '); + String Resized(std::intmax_t size, char character = ' ') const; String& Reverse(); String Reversed() const; String& Set(char character); - String& Set(unsigned int rep, char character); - String& Set(unsigned int rep, const char* string); - String& Set(unsigned int rep, const char* string, unsigned int length); - String& Set(unsigned int rep, const String& string); + String& Set(std::size_t rep, char character); + String& Set(std::size_t rep, const char* string); + String& Set(std::size_t rep, const char* string, std::size_t length); + String& Set(std::size_t rep, const String& string); String& Set(const char* string); - String& Set(const char* string, unsigned int length); + String& Set(const char* string, std::size_t length); String& Set(const std::string& string); String& Set(const String& string); String& Set(String&& string) noexcept; @@ -139,26 +139,26 @@ namespace Nz String Simplified(UInt32 flags = None) const; String& Simplify(UInt32 flags = None); - unsigned int Split(std::vector& result, char separation = ' ', int start = 0, UInt32 flags = None) const; - unsigned int Split(std::vector& result, const char* separation, int start = 0, UInt32 flags = None) const; - unsigned int Split(std::vector& result, const char* separation, unsigned int length, int start = 0, UInt32 flags = None) const; - unsigned int Split(std::vector& result, const String& separation, int start = 0, UInt32 flags = None) const; - unsigned int SplitAny(std::vector& result, const char* separations, int start = 0, UInt32 flags = None) const; - unsigned int SplitAny(std::vector& result, const String& separations, int start = 0, UInt32 flags = None) const; + unsigned int Split(std::vector& result, char separation = ' ', std::intmax_t start = 0, UInt32 flags = None) const; + unsigned int Split(std::vector& result, const char* separation, std::intmax_t start = 0, UInt32 flags = None) const; + unsigned int Split(std::vector& result, const char* separation, std::size_t length, std::intmax_t start = 0, UInt32 flags = None) const; + unsigned int Split(std::vector& result, const String& separation, std::intmax_t start = 0, UInt32 flags = None) const; + unsigned int SplitAny(std::vector& result, const char* separations, std::intmax_t start = 0, UInt32 flags = None) const; + unsigned int SplitAny(std::vector& result, const String& separations, std::intmax_t start = 0, UInt32 flags = None) const; bool StartsWith(char character, UInt32 flags = None) const; bool StartsWith(const char* string, UInt32 flags = None) const; bool StartsWith(const String& string, UInt32 flags = None) const; - String SubString(int startPos, int endPos = -1) const; - String SubStringFrom(char character, int startPos = 0, bool fromLast = false, bool include = false, UInt32 flags = None) const; - String SubStringFrom(const char *string, int startPos = 0, bool fromLast = false, bool include = false, UInt32 flags = None) const; - String SubStringFrom(const char *string, unsigned int length, int startPos = 0, bool fromLast = false, bool include = false, UInt32 flags = None) const; - String SubStringFrom(const String& string, int startPos = 0, bool fromLast = false, bool include = false, UInt32 flags = None) const; - String SubStringTo(char character, int startPos = 0, bool toLast = false, bool include = false, UInt32 flags = None) const; - String SubStringTo(const char *string, int startPos = 0, bool toLast = false, bool include = false, UInt32 flags = None) const; - String SubStringTo(const char *string, unsigned int length, int startPos = 0, bool toLast = false, bool include = false, UInt32 flags = None) const; - String SubStringTo(const String& string, int startPos = 0, bool toLast = false, bool include = false, UInt32 flags = None) const; + String SubString(std::intmax_t startPos, std::intmax_t endPos = -1) const; + String SubStringFrom(char character, std::intmax_t startPos = 0, bool fromLast = false, bool include = false, UInt32 flags = None) const; + String SubStringFrom(const char* string, std::intmax_t startPos = 0, bool fromLast = false, bool include = false, UInt32 flags = None) const; + String SubStringFrom(const char* string, std::size_t length, std::intmax_t startPos = 0, bool fromLast = false, bool include = false, UInt32 flags = None) const; + String SubStringFrom(const String& string, std::intmax_t startPos = 0, bool fromLast = false, bool include = false, UInt32 flags = None) const; + String SubStringTo(char character, std::intmax_t startPos = 0, bool toLast = false, bool include = false, UInt32 flags = None) const; + String SubStringTo(const char* string, std::intmax_t startPos = 0, bool toLast = false, bool include = false, UInt32 flags = None) const; + String SubStringTo(const char* string, std::size_t length, std::intmax_t startPos = 0, bool toLast = false, bool include = false, UInt32 flags = None) const; + String SubStringTo(const String& string, std::intmax_t startPos = 0, bool toLast = false, bool include = false, UInt32 flags = None) const; void Swap(String& str); @@ -193,8 +193,8 @@ namespace Nz operator std::string() const; - char& operator[](unsigned int pos); - char operator[](unsigned int pos) const; + char& operator[](std::size_t pos); + char operator[](std::size_t pos) const; String& operator=(char character); String& operator=(const char* string); @@ -296,7 +296,7 @@ namespace Nz NAZARA_CORE_API friend bool operator>=(const char* string, const String& nstring); NAZARA_CORE_API friend bool operator>=(const std::string& string, const String& nstring); - static const unsigned int npos; + static const std::size_t npos; private: struct SharedString; @@ -313,11 +313,11 @@ namespace Nz struct SharedString { inline SharedString(); - inline SharedString(unsigned int strSize); - inline SharedString(unsigned int strSize, unsigned int strCapacity); + inline SharedString(std::size_t strSize); + inline SharedString(std::size_t strSize, std::size_t strCapacity); - unsigned int capacity; - unsigned int size; + std::size_t capacity; + std::size_t size; std::unique_ptr string; }; }; diff --git a/include/Nazara/Core/String.inl b/include/Nazara/Core/String.inl index 202cec2e6..93ff32312 100644 --- a/include/Nazara/Core/String.inl +++ b/include/Nazara/Core/String.inl @@ -23,7 +23,7 @@ namespace Nz { } - inline String::SharedString::SharedString(unsigned int strSize) : + inline String::SharedString::SharedString(std::size_t strSize) : capacity(strSize), size(strSize), string(new char[strSize + 1]) @@ -31,7 +31,7 @@ namespace Nz string[strSize] = '\0'; } - inline String::SharedString::SharedString(unsigned int strSize, unsigned int strCapacity) : + inline String::SharedString::SharedString(std::size_t strSize, std::size_t strCapacity) : capacity(strCapacity), size(strSize), string(new char[strCapacity + 1]) diff --git a/include/Nazara/Core/StringStream.hpp b/include/Nazara/Core/StringStream.hpp index c34209433..da68e8b27 100644 --- a/include/Nazara/Core/StringStream.hpp +++ b/include/Nazara/Core/StringStream.hpp @@ -50,7 +50,7 @@ namespace Nz private: std::vector m_strings; - unsigned int m_bufferSize; + std::size_t m_bufferSize; }; } diff --git a/include/Nazara/Math/Algorithm.hpp b/include/Nazara/Math/Algorithm.hpp index 17d0fc7e4..841c3569a 100644 --- a/include/Nazara/Math/Algorithm.hpp +++ b/include/Nazara/Math/Algorithm.hpp @@ -36,7 +36,7 @@ namespace Nz template constexpr T FromDegrees(T degrees); template constexpr T FromRadians(T radians); template constexpr T DegreeToRadian(T degrees); - unsigned int GetNearestPowerOfTwo(unsigned int number); + template T GetNearestPowerOfTwo(T number); unsigned int GetNumberLength(signed char number); unsigned int GetNumberLength(unsigned char number); unsigned int GetNumberLength(int number); diff --git a/include/Nazara/Math/Algorithm.inl b/include/Nazara/Math/Algorithm.inl index b02e0acf3..1a4fceded 100644 --- a/include/Nazara/Math/Algorithm.inl +++ b/include/Nazara/Math/Algorithm.inl @@ -156,10 +156,11 @@ namespace Nz #endif } - inline unsigned int GetNearestPowerOfTwo(unsigned int number) + template + T GetNearestPowerOfTwo(T number) { ///TODO: Marquer comme constexpr en C++14 - unsigned int x = 1; + T 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) x <<= 1; diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index bfb026c81..0626cb8eb 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -109,13 +109,13 @@ namespace Nz template T Vector3::GetLength() const { - return std::sqrt(GetSquaredLength()); + return static_cast(std::sqrt(GetSquaredLength())); } template float Vector3::GetLengthf() const { - return std::sqrt(static_cast(GetSquaredLength())); + return std::sqrt(static_cast(GetSquaredLength())); } template diff --git a/include/Nazara/Utility/VertexDeclaration.hpp b/include/Nazara/Utility/VertexDeclaration.hpp index 1e29bc9cd..f5dea6457 100644 --- a/include/Nazara/Utility/VertexDeclaration.hpp +++ b/include/Nazara/Utility/VertexDeclaration.hpp @@ -34,12 +34,12 @@ namespace Nz ~VertexDeclaration(); void DisableComponent(VertexComponent component); - void EnableComponent(VertexComponent component, ComponentType type, unsigned int offset); + void EnableComponent(VertexComponent component, ComponentType type, std::size_t offset); - void GetComponent(VertexComponent component, bool* enabled, ComponentType* type, unsigned int* offset) const; - unsigned int GetStride() const; + void GetComponent(VertexComponent component, bool* enabled, ComponentType* type, std::size_t* offset) const; + std::size_t GetStride() const; - void SetStride(unsigned int stride); + void SetStride(std::size_t stride); VertexDeclaration& operator=(const VertexDeclaration& declaration); @@ -58,7 +58,7 @@ namespace Nz { ComponentType type; // Le type de donnée bool enabled = false; // Ce composant est-il activé ?/ - unsigned int offset; // La position, en octets, de la première donnée + std::size_t offset; // La position, en octets, de la première donnée /* ** -Lynix: @@ -70,7 +70,7 @@ namespace Nz }; Component m_components[VertexComponent_Max+1]; - unsigned int m_stride; + std::size_t m_stride; static VertexDeclaration s_declarations[VertexLayout_Max+1]; static VertexDeclarationLibrary::LibraryMap s_library; diff --git a/include/Nazara/Utility/VertexMapper.inl b/include/Nazara/Utility/VertexMapper.inl index e2531cdbb..7b36743eb 100644 --- a/include/Nazara/Utility/VertexMapper.inl +++ b/include/Nazara/Utility/VertexMapper.inl @@ -16,7 +16,7 @@ namespace Nz // Ensuite le composant qui nous intéresse bool enabled; ComponentType type; - unsigned int offset; + std::size_t offset; declaration->GetComponent(component, &enabled, &type, &offset); if (enabled) diff --git a/src/Nazara/Core/Directory.cpp b/src/Nazara/Core/Directory.cpp index 6d24e714e..7f8a90dcc 100644 --- a/src/Nazara/Core/Directory.cpp +++ b/src/Nazara/Core/Directory.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #if defined(NAZARA_PLATFORM_WINDOWS) @@ -165,7 +166,7 @@ namespace Nz #endif String name; - do + for (;;) { if (!m_impl->NextResult()) return false; @@ -178,7 +179,6 @@ namespace Nz if (name.Match(m_pattern)) break; } - while (true); return true; } @@ -268,7 +268,7 @@ namespace Nz if (recursive) { String path = File::NormalizePath(dirPath); - unsigned int foundPos = path.Find(NAZARA_DIRECTORY_SEPARATOR); + std::size_t foundPos = path.Find(NAZARA_DIRECTORY_SEPARATOR); if (foundPos == String::npos) return false; @@ -280,13 +280,13 @@ namespace Nz if (foundPos == String::npos) return false; - foundPos = path.Find('\\', foundPos+1); + foundPos = path.Find('\\', foundPos + 1); if (foundPos == String::npos) return false; } #endif - do + for (;;) { String p = path.SubString(0, foundPos); if (p.EndsWith(NAZARA_DIRECTORY_SEPARATOR)) @@ -298,9 +298,8 @@ namespace Nz if (foundPos == String::npos) break; - foundPos = path.Find(NAZARA_DIRECTORY_SEPARATOR, foundPos+1); + foundPos = path.Find(NAZARA_DIRECTORY_SEPARATOR, foundPos + 1); } - while (true); return true; } @@ -324,25 +323,14 @@ namespace Nz const char* Directory::GetCurrentFileRelativeToEngine(const char* currentFile) { ///FIXME: Est-ce que cette méthode est au bon endroit ? - static int offset = -1; + const char* ptr = std::strstr(currentFile, "NazaraEngine/"); + if (!ptr) + ptr = std::strstr(currentFile, "NazaraEngine\\"); - if (offset < 0) - { - const char* directoryFile = __FILE__; - const char* ptr = std::strstr(directoryFile, "NazaraEngine/src/Nazara/Core/Directory.cpp"); - if (ptr) - offset = ptr - directoryFile; - else - { - ptr = std::strstr(directoryFile, "NazaraEngine\\src\\Nazara\\Core\\Directory.cpp"); - if (ptr) - offset = ptr - directoryFile; - else - offset = 0; - } - } + if (!ptr) + ptr = currentFile; - return ¤tFile[offset]; + return ptr; } bool Directory::Remove(const String& dirPath, bool emptyDirectory) diff --git a/src/Nazara/Core/GuillotineBinPack.cpp b/src/Nazara/Core/GuillotineBinPack.cpp index 7015a5f65..b3aedccc0 100644 --- a/src/Nazara/Core/GuillotineBinPack.cpp +++ b/src/Nazara/Core/GuillotineBinPack.cpp @@ -152,9 +152,9 @@ namespace Nz { // Stores the penalty score of the best rectangle placement - bigger=worse, smaller=better. bool bestFlipped; - int bestFreeRect; - int bestRect; - int bestScore = std::numeric_limits::max(); + std::size_t bestFreeRect; + std::size_t bestRect; + std::size_t bestScore = std::numeric_limits::max(); for (std::size_t i = 0; i < m_freeRectangles.size(); ++i) { @@ -170,7 +170,7 @@ namespace Nz bestFreeRect = i; bestRect = j; bestFlipped = false; - bestScore = std::numeric_limits::min(); + bestScore = std::numeric_limits::min(); i = m_freeRectangles.size(); // Force a jump out of the outer loop as well - we got an instant fit. break; } @@ -180,7 +180,7 @@ namespace Nz bestFreeRect = i; bestRect = j; bestFlipped = true; - bestScore = std::numeric_limits::min(); + bestScore = std::numeric_limits::min(); i = m_freeRectangles.size(); // Force a jump out of the outer loop as well - we got an instant fit. break; } @@ -212,14 +212,14 @@ namespace Nz } // If we didn't manage to find any rectangle to pack, abort. - if (bestScore == std::numeric_limits::max()) + if (bestScore == std::numeric_limits::max()) { // Si nous le pouvons, on marque les rectangles n'ayant pas pu être insérés if (inserted) { for (Rectui* rect : remainingRects) { - unsigned int position = rect - rects; + std::ptrdiff_t position = rect - rects; inserted[position] = false; } } @@ -228,7 +228,7 @@ namespace Nz } // Otherwise, we're good to go and do the actual packing. - unsigned int position = remainingRects[bestRect] - rects; + std::ptrdiff_t position = remainingRects[bestRect] - rects; Rectui& rect = *remainingRects[bestRect]; rect.x = m_freeRectangles[bestFreeRect].x; rect.y = m_freeRectangles[bestFreeRect].y; diff --git a/src/Nazara/Core/Hash/CRC32.cpp b/src/Nazara/Core/Hash/CRC32.cpp index edf3ba8c2..a7d0a87dc 100644 --- a/src/Nazara/Core/Hash/CRC32.cpp +++ b/src/Nazara/Core/Hash/CRC32.cpp @@ -98,7 +98,7 @@ namespace Nz delete m_state; } - void HashCRC32::Append(const UInt8* data, unsigned int len) + void HashCRC32::Append(const UInt8* data, std::size_t len) { while (len--) m_state->crc = m_state->table[(m_state->crc ^ *data++) & 0xFF] ^ (m_state->crc >> 8); @@ -120,7 +120,7 @@ namespace Nz return ByteArray(reinterpret_cast(&m_state->crc), 4); } - unsigned int HashCRC32::GetDigestLength() const + std::size_t HashCRC32::GetDigestLength() const { return 4; } diff --git a/src/Nazara/Core/Hash/Fletcher16.cpp b/src/Nazara/Core/Hash/Fletcher16.cpp index c4ab978e8..447a7ed3b 100644 --- a/src/Nazara/Core/Hash/Fletcher16.cpp +++ b/src/Nazara/Core/Hash/Fletcher16.cpp @@ -24,11 +24,11 @@ namespace Nz delete m_state; } - void HashFletcher16::Append(const UInt8* data, unsigned int len) + void HashFletcher16::Append(const UInt8* data, std::size_t len) { while (len) { - unsigned int tlen = std::min(len, 21U); + std::size_t tlen = std::min(len, 21U); len -= tlen; do { @@ -62,7 +62,7 @@ namespace Nz return ByteArray(reinterpret_cast(&fletcher), 2); } - unsigned int HashFletcher16::GetDigestLength() const + std::size_t HashFletcher16::GetDigestLength() const { return 2; } diff --git a/src/Nazara/Core/Hash/MD5.cpp b/src/Nazara/Core/Hash/MD5.cpp index 127a1f8cb..53082d4cc 100644 --- a/src/Nazara/Core/Hash/MD5.cpp +++ b/src/Nazara/Core/Hash/MD5.cpp @@ -277,7 +277,7 @@ namespace Nz delete m_state; } - void HashMD5::Append(const UInt8* data, unsigned int len) + void HashMD5::Append(const UInt8* data, std::size_t len) { const UInt8 *p = data; int left = len; @@ -352,7 +352,7 @@ namespace Nz return ByteArray(&digest[0], 16); } - unsigned int HashMD5::GetDigestLength() const + std::size_t HashMD5::GetDigestLength() const { return 16; } diff --git a/src/Nazara/Core/Hash/SHA1.cpp b/src/Nazara/Core/Hash/SHA1.cpp index 1ed49e69c..6550d343d 100644 --- a/src/Nazara/Core/Hash/SHA1.cpp +++ b/src/Nazara/Core/Hash/SHA1.cpp @@ -18,7 +18,7 @@ namespace Nz delete m_state; } - void HashSHA1::Append(const UInt8* data, unsigned int len) + void HashSHA1::Append(const UInt8* data, std::size_t len) { SHA1_Update(m_state, data, len); } @@ -37,7 +37,7 @@ namespace Nz return ByteArray(digest, SHA1_DIGEST_LENGTH); } - unsigned int HashSHA1::GetDigestLength() const + std::size_t HashSHA1::GetDigestLength() const { return SHA1_DIGEST_LENGTH; } diff --git a/src/Nazara/Core/Hash/SHA224.cpp b/src/Nazara/Core/Hash/SHA224.cpp index 57b95e965..d071e9345 100644 --- a/src/Nazara/Core/Hash/SHA224.cpp +++ b/src/Nazara/Core/Hash/SHA224.cpp @@ -18,7 +18,7 @@ namespace Nz delete m_state; } - void HashSHA224::Append(const UInt8* data, unsigned int len) + void HashSHA224::Append(const UInt8* data, std::size_t len) { SHA224_Update(m_state, data, len); } @@ -37,7 +37,7 @@ namespace Nz return ByteArray(digest, SHA224_DIGEST_LENGTH); } - unsigned int HashSHA224::GetDigestLength() const + std::size_t HashSHA224::GetDigestLength() const { return SHA224_DIGEST_LENGTH; } diff --git a/src/Nazara/Core/Hash/SHA256.cpp b/src/Nazara/Core/Hash/SHA256.cpp index 202820594..9b5f56983 100644 --- a/src/Nazara/Core/Hash/SHA256.cpp +++ b/src/Nazara/Core/Hash/SHA256.cpp @@ -18,7 +18,7 @@ namespace Nz delete m_state; } - void HashSHA256::Append(const UInt8* data, unsigned int len) + void HashSHA256::Append(const UInt8* data, std::size_t len) { SHA256_Update(m_state, data, len); } @@ -37,7 +37,7 @@ namespace Nz return ByteArray(digest, SHA256_DIGEST_LENGTH); } - unsigned int HashSHA256::GetDigestLength() const + std::size_t HashSHA256::GetDigestLength() const { return SHA256_DIGEST_LENGTH; } diff --git a/src/Nazara/Core/Hash/SHA384.cpp b/src/Nazara/Core/Hash/SHA384.cpp index fe1498cbe..3f647260e 100644 --- a/src/Nazara/Core/Hash/SHA384.cpp +++ b/src/Nazara/Core/Hash/SHA384.cpp @@ -18,7 +18,7 @@ namespace Nz delete m_state; } - void HashSHA384::Append(const UInt8* data, unsigned int len) + void HashSHA384::Append(const UInt8* data, std::size_t len) { SHA384_Update(m_state, data, len); } @@ -37,7 +37,7 @@ namespace Nz return ByteArray(digest, SHA384_DIGEST_LENGTH); } - unsigned int HashSHA384::GetDigestLength() const + std::size_t HashSHA384::GetDigestLength() const { return SHA384_DIGEST_LENGTH; } diff --git a/src/Nazara/Core/Hash/SHA512.cpp b/src/Nazara/Core/Hash/SHA512.cpp index 562836998..af56d937a 100644 --- a/src/Nazara/Core/Hash/SHA512.cpp +++ b/src/Nazara/Core/Hash/SHA512.cpp @@ -18,7 +18,7 @@ namespace Nz delete m_state; } - void HashSHA512::Append(const UInt8* data, unsigned int len) + void HashSHA512::Append(const UInt8* data, std::size_t len) { SHA512_Update(m_state, data, len); } @@ -37,7 +37,7 @@ namespace Nz return ByteArray(digest, SHA512_DIGEST_LENGTH); } - unsigned int HashSHA512::GetDigestLength() const + std::size_t HashSHA512::GetDigestLength() const { return SHA512_DIGEST_LENGTH; } diff --git a/src/Nazara/Core/Hash/Whirlpool.cpp b/src/Nazara/Core/Hash/Whirlpool.cpp index 9be283775..c3e7380ae 100644 --- a/src/Nazara/Core/Hash/Whirlpool.cpp +++ b/src/Nazara/Core/Hash/Whirlpool.cpp @@ -866,12 +866,12 @@ namespace Nz delete m_state; } - void HashWhirlpool::Append(const UInt8* data, unsigned int len) + void HashWhirlpool::Append(const UInt8* data, std::size_t len) { - len *= 8; // Whirlpool fonctionne avec une taille en bits + len *= 8; // Whirlpool works with bits int sourcePos = 0; /* index of leftmost source UInt8 containing data (1 to 8 bits). */ - int sourceGap = (8 - (static_cast(len) & 7)) & 7; /* space on source[sourcePos]. */ + int sourceGap = (8 - (static_cast(len) & 7)) & 7; /* space on source[sourcePos]. */ int bufferRem = m_state->bufferBits & 7; /* occupied bits on buffer[bufferPos]. */ UInt32 b; @@ -1015,7 +1015,7 @@ namespace Nz return ByteArray(&result[0], 64); } - unsigned int HashWhirlpool::GetDigestLength() const + std::size_t HashWhirlpool::GetDigestLength() const { return 64; } diff --git a/src/Nazara/Core/MemoryManager.cpp b/src/Nazara/Core/MemoryManager.cpp index 9a5f5acec..db58f2299 100644 --- a/src/Nazara/Core/MemoryManager.cpp +++ b/src/Nazara/Core/MemoryManager.cpp @@ -100,7 +100,6 @@ namespace Nz std::fclose(log); throw std::bad_alloc(); - return nullptr; // Ça me rassure d'avoir un return, aussi inutile soit-il } ptr->array = multi; diff --git a/src/Nazara/Core/PrimitiveList.cpp b/src/Nazara/Core/PrimitiveList.cpp index 9c85cea55..a9d2fc6ee 100644 --- a/src/Nazara/Core/PrimitiveList.cpp +++ b/src/Nazara/Core/PrimitiveList.cpp @@ -73,37 +73,21 @@ namespace Nz m_primitives.push_back(Primitive::UVSphere(size, sliceCount, stackCount, position, rotation)); } - Primitive& PrimitiveList::GetPrimitive(unsigned int i) + Primitive& PrimitiveList::GetPrimitive(std::size_t i) { - #if NAZARA_CORE_SAFE - if (i >= m_primitives.size()) - { - NazaraError("Primitive index out of range (" + String::Number(i) + " >= " + String::Number(m_primitives.size()) + ')'); - - static Primitive dummy; - return dummy; - } - #endif + NazaraAssert(i < m_primitives.size(), "Primitive index out of range"); return m_primitives[i]; } - const Primitive& PrimitiveList::GetPrimitive(unsigned int i) const + const Primitive& PrimitiveList::GetPrimitive(std::size_t i) const { - #if NAZARA_CORE_SAFE - if (i >= m_primitives.size()) - { - NazaraError("Primitive index out of range (" + String::Number(i) + " >= " + String::Number(m_primitives.size()) + ')'); - - static Primitive dummy; - return dummy; - } - #endif + NazaraAssert(i < m_primitives.size(), "Primitive index out of range"); return m_primitives[i]; } - unsigned int PrimitiveList::GetSize() const + std::size_t PrimitiveList::GetSize() const { return m_primitives.size(); } diff --git a/src/Nazara/Core/Stream.cpp b/src/Nazara/Core/Stream.cpp index 484057341..78760ccea 100644 --- a/src/Nazara/Core/Stream.cpp +++ b/src/Nazara/Core/Stream.cpp @@ -32,7 +32,7 @@ namespace Nz char buffer[bufferSize + 1]; buffer[bufferSize] = '\0'; - unsigned int readSize; + std::size_t readSize; do { readSize = Read(buffer, bufferSize); @@ -40,7 +40,7 @@ namespace Nz const char* ptr = std::strchr(buffer, '\n'); if (ptr) { - unsigned int pos = ptr - buffer; + std::ptrdiff_t pos = ptr - buffer; if (m_streamOptions & StreamOption_Text && pos > 0 && buffer[pos - 1] == '\r') line.Append(buffer, pos - 1); @@ -60,8 +60,8 @@ namespace Nz else { line.Set(lineSize, '\0'); - unsigned int readSize = Read(&line[0], lineSize); - unsigned int pos = line.Find('\n'); + std::size_t readSize = Read(&line[0], lineSize); + std::size_t pos = line.Find('\n'); if (pos <= readSize) // Faux uniquement si le caractère n'est pas présent (npos étant le plus grand entier) { if (m_streamOptions & StreamOption_Text && pos > 0 && line[pos - 1] == '\r') diff --git a/src/Nazara/Core/String.cpp b/src/Nazara/Core/String.cpp index 33656ef95..4d63cd87f 100644 --- a/src/Nazara/Core/String.cpp +++ b/src/Nazara/Core/String.cpp @@ -24,7 +24,7 @@ namespace Nz namespace Detail { // Cet algorithme est inspiré de la documentation de Qt - inline unsigned int GetNewSize(unsigned int newSize) + inline std::size_t GetNewSize(std::size_t newSize) { if (newSize < 20) return newSize+4; @@ -57,7 +57,7 @@ namespace Nz { int ret = 0; - while (!(ret = static_cast(Detail::ToLower(*s1)) - static_cast(Detail::ToLower(*s2))) && *s2) + while (((ret = static_cast(Detail::ToLower(*s1)) - static_cast(Detail::ToLower(*s2))) != 0) && *s2) ++s1, ++s2; return ret != 0 ? (ret > 0 ? 1 : -1) : 0; @@ -69,7 +69,7 @@ namespace Nz utf8::unchecked::iterator it1(s1); utf8::unchecked::iterator it2(s2); - while (!(ret = Unicode::GetLowercase(*it1) - Unicode::GetLowercase(*it2)) && *it2) + while (((ret = Unicode::GetLowercase(*it1) - Unicode::GetLowercase(*it2)) != 0) && *it2) ++it1, ++it2; return ret != 0 ? (ret > 0 ? 1 : -1) : 0; @@ -92,7 +92,7 @@ namespace Nz m_sharedString = GetEmptyString(); } - String::String(unsigned int rep, char character) + String::String(std::size_t rep, char character) { if (rep > 0) { @@ -105,27 +105,27 @@ namespace Nz m_sharedString = GetEmptyString(); } - String::String(unsigned int rep, const char* string) : + String::String(std::size_t rep, const char* string) : String(rep, string, (string) ? std::strlen(string) : 0) { } - String::String(unsigned int rep, const char* string, unsigned int length) + String::String(std::size_t rep, const char* string, std::size_t length) { - unsigned int totalSize = rep*length; + std::size_t totalSize = rep*length; if (totalSize > 0) { m_sharedString = std::make_shared(totalSize); - for (unsigned int i = 0; i < rep; ++i) + for (std::size_t i = 0; i < rep; ++i) std::memcpy(&m_sharedString->string[i*length], string, length); } else m_sharedString = GetEmptyString(); } - String::String(unsigned int rep, const String& string) : + String::String(std::size_t rep, const String& string) : String(rep, string.GetConstBuffer(), string.GetSize()) { } @@ -135,7 +135,7 @@ namespace Nz { } - String::String(const char* string, unsigned int length) + String::String(const char* string, std::size_t length) { if (length > 0) { @@ -161,7 +161,7 @@ namespace Nz return Insert(m_sharedString->size, string); } - String& String::Append(const char* string, unsigned int length) + String& String::Append(const char* string, std::size_t length) { return Insert(m_sharedString->size, string, length); } @@ -183,30 +183,30 @@ namespace Nz ReleaseString(); } - bool String::Contains(char character, int start, UInt32 flags) const + bool String::Contains(char character, std::intmax_t start, UInt32 flags) const { return Find(character, start, flags) != npos; } - bool String::Contains(const char* string, int start, UInt32 flags) const + bool String::Contains(const char* string, std::intmax_t start, UInt32 flags) const { return Find(string, start, flags) != npos; } - bool String::Contains(const String& string, int start, UInt32 flags) const + bool String::Contains(const String& string, std::intmax_t start, UInt32 flags) const { return Find(string, start, flags) != npos; } - unsigned int String::Count(char character, int start, UInt32 flags) const + unsigned int String::Count(char character, std::intmax_t start, UInt32 flags) const { if (character == '\0' || m_sharedString->size == 0) return 0; if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return 0; @@ -225,7 +225,7 @@ namespace Nz } else { - while ((str = std::strchr(str, character))) + while ((str = std::strchr(str, character)) != nullptr) { count++; str++; @@ -235,15 +235,15 @@ namespace Nz return count; } - unsigned int String::Count(const char* string, int start, UInt32 flags) const + unsigned int String::Count(const char* string, std::intmax_t start, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) return 0; if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return 0; @@ -267,7 +267,7 @@ namespace Nz ++it; utf8::unchecked::iterator it2(t); - while (true) + for (;;) { if (*it2 == '\0') { @@ -298,7 +298,7 @@ namespace Nz str++; const char* ptr = &string[1]; - while (true) + for (;;) { if (*ptr == '\0') { @@ -322,7 +322,7 @@ namespace Nz } else { - while ((str = std::strstr(str, string))) + while ((str = std::strstr(str, string)) != nullptr) { count++; str++; @@ -332,20 +332,20 @@ namespace Nz return count; } - unsigned int String::Count(const String& string, int start, UInt32 flags) const + unsigned int String::Count(const String& string, std::intmax_t start, UInt32 flags) const { return Count(string.GetConstBuffer(), start, flags); } - unsigned int String::CountAny(const char* string, int start, UInt32 flags) const + unsigned int String::CountAny(const char* string, std::intmax_t start, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) return 0; if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return 0; @@ -414,7 +414,7 @@ namespace Nz } else { - while ((str = std::strpbrk(str, string))) + while ((str = std::strpbrk(str, string)) != nullptr) { count++; str++; @@ -425,7 +425,7 @@ namespace Nz return count; } - unsigned int String::CountAny(const String& string, int start, UInt32 flags) const + unsigned int String::CountAny(const String& string, std::intmax_t start, UInt32 flags) const { return CountAny(string.GetConstBuffer(), start, flags); } @@ -446,7 +446,7 @@ namespace Nz return EndsWith(string, std::strlen(string), flags); } - bool String::EndsWith(const char* string, unsigned int length, UInt32 flags) const + bool String::EndsWith(const char* string, std::size_t length, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0 || length > m_sharedString->size) return false; @@ -467,15 +467,15 @@ namespace Nz return EndsWith(string.GetConstBuffer(), string.m_sharedString->size, flags); } - unsigned int String::Find(char character, int start, UInt32 flags) const + std::size_t String::Find(char character, std::intmax_t start, UInt32 flags) const { if (character == '\0' || m_sharedString->size == 0) return npos; if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return npos; @@ -486,7 +486,7 @@ namespace Nz do { if (Detail::ToLower(*str) == ch) - return static_cast(str - m_sharedString->string.get()); + return str - m_sharedString->string.get(); } while (*++str); @@ -496,21 +496,21 @@ namespace Nz { char* ch = std::strchr(&m_sharedString->string[pos], character); if (ch) - return static_cast(ch - m_sharedString->string.get()); + return ch - m_sharedString->string.get(); else return npos; } } - unsigned int String::Find(const char* string, int start, UInt32 flags) const + std::size_t String::Find(const char* string, std::intmax_t start, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) return npos; if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return npos; @@ -534,10 +534,10 @@ namespace Nz ++it; utf8::unchecked::iterator it2(t); - while (true) + for (;;) { if (*it2 == '\0') - return static_cast(ptrPos - m_sharedString->string.get()); + return ptrPos - m_sharedString->string.get(); if (*it == '\0') return npos; @@ -563,10 +563,10 @@ namespace Nz str++; const char* ptr = &string[1]; - while (true) + for (;;) { if (*ptr == '\0') - return static_cast(ptrPos - m_sharedString->string.get()); + return ptrPos - m_sharedString->string.get(); if (*str == '\0') return npos; @@ -586,26 +586,26 @@ namespace Nz { char* ch = std::strstr(&m_sharedString->string[pos], string); if (ch) - return static_cast(ch - m_sharedString->string.get()); + return ch - m_sharedString->string.get(); } return npos; } - unsigned int String::Find(const String& string, int start, UInt32 flags) const + std::size_t String::Find(const String& string, std::intmax_t start, UInt32 flags) const { return Find(string.GetConstBuffer(), start, flags); } - unsigned int String::FindAny(const char* string, int start, UInt32 flags) const + std::size_t String::FindAny(const char* string, std::intmax_t start, UInt32 flags) const { if (m_sharedString->size == 0 || !string || !string[0]) return npos; if (start < 0) - start = std::max(m_sharedString->size+start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return npos; @@ -675,20 +675,20 @@ namespace Nz return npos; } - unsigned int String::FindAny(const String& string, int start, UInt32 flags) const + std::size_t String::FindAny(const String& string, std::intmax_t start, UInt32 flags) const { return FindAny(string.GetConstBuffer(), start, flags); } - unsigned int String::FindLast(char character, int start, UInt32 flags) const + std::size_t String::FindLast(char character, std::intmax_t start, UInt32 flags) const { if (character == '\0' || m_sharedString->size == 0) return npos; if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return npos; @@ -700,7 +700,7 @@ namespace Nz do { if (Detail::ToLower(*ptr) == character) - return static_cast(ptr - m_sharedString->string.get()); + return ptr - m_sharedString->string.get(); } while (ptr-- != m_sharedString->string.get()); } @@ -709,7 +709,7 @@ namespace Nz do { if (*ptr == character) - return static_cast(ptr - m_sharedString->string.get()); + return ptr - m_sharedString->string.get(); } while (ptr-- != m_sharedString->string.get()); } @@ -717,15 +717,15 @@ namespace Nz return npos; } - unsigned int String::FindLast(const char* string, int start, UInt32 flags) const + std::size_t String::FindLast(const char* string, std::intmax_t start, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) return npos; if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return npos; @@ -749,7 +749,7 @@ namespace Nz utf8::unchecked::iterator tIt(it); ++tIt; - while (true) + for (;;) { if (*it2 == '\0') return it.base() - m_sharedString->string.get(); @@ -776,7 +776,7 @@ namespace Nz { const char* p = &string[1]; const char* tPtr = ptr+1; - while (true) + for (;;) { if (*p == '\0') return ptr - m_sharedString->string.get(); @@ -803,7 +803,7 @@ namespace Nz { const char* p = &string[1]; const char* tPtr = ptr+1; - while (true) + for (;;) { if (*p == '\0') return ptr - m_sharedString->string.get(); @@ -825,15 +825,15 @@ namespace Nz return npos; } - unsigned int String::FindLast(const String& string, int start, UInt32 flags) const + std::size_t String::FindLast(const String& string, std::intmax_t start, UInt32 flags) const { if (string.m_sharedString->size == 0 || string.m_sharedString->size > m_sharedString->size) return npos; if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size || string.m_sharedString->size > m_sharedString->size) return npos; @@ -859,7 +859,7 @@ namespace Nz utf8::unchecked::iterator tIt(it); ++tIt; - while (true) + for (;;) { if (*it2 == '\0') return it.base() - m_sharedString->string.get(); @@ -881,7 +881,7 @@ namespace Nz { ///Algo 1.FindLast#4 (Taille du pattern connue) char c = Detail::ToLower(string.m_sharedString->string[string.m_sharedString->size-1]); - while (true) + for (;;) { if (Detail::ToLower(*ptr) == c) { @@ -906,7 +906,7 @@ namespace Nz else { ///Algo 1.FindLast#4 (Taille du pattern connue) - while (true) + for (;;) { if (*ptr == string.m_sharedString->string[string.m_sharedString->size-1]) { @@ -931,15 +931,15 @@ namespace Nz return npos; } - unsigned int String::FindLastAny(const char* string, int start, UInt32 flags) const + std::size_t String::FindLastAny(const char* string, std::intmax_t start, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) return npos; if (start < 0) - start = std::max(m_sharedString->size+start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return npos; @@ -1017,20 +1017,20 @@ namespace Nz return npos; } - unsigned int String::FindLastAny(const String& string, int start, UInt32 flags) const + std::size_t String::FindLastAny(const String& string, std::intmax_t start, UInt32 flags) const { return FindLastAny(string.GetConstBuffer(), start, flags); } - unsigned int String::FindLastWord(const char* string, int start, UInt32 flags) const + std::size_t String::FindLastWord(const char* string, std::intmax_t start, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) return npos; if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return npos; @@ -1063,7 +1063,7 @@ namespace Nz utf8::unchecked::iterator tIt = it; ++tIt; - while (true) + for (;;) { if (*p == '\0') { @@ -1105,7 +1105,7 @@ namespace Nz utf8::unchecked::iterator tIt = it; ++tIt; - while (true) + for (;;) { if (*p == '\0') { @@ -1143,7 +1143,7 @@ namespace Nz const char* p = &string[1]; const char* tPtr = ptr+1; - while (true) + for (;;) { if (*p == '\0') { @@ -1177,7 +1177,7 @@ namespace Nz const char* p = &string[1]; const char* tPtr = ptr+1; - while (true) + for (;;) { if (*p == '\0') { @@ -1205,15 +1205,15 @@ namespace Nz return npos; } - unsigned int String::FindLastWord(const String& string, int start, UInt32 flags) const + std::size_t String::FindLastWord(const String& string, std::intmax_t start, UInt32 flags) const { if (string.m_sharedString->size == 0 || string.m_sharedString->size > m_sharedString->size) return npos; if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return npos; @@ -1246,7 +1246,7 @@ namespace Nz utf8::unchecked::iterator tIt = it; ++tIt; - while (true) + for (;;) { if (*p == '\0') { @@ -1288,7 +1288,7 @@ namespace Nz utf8::unchecked::iterator tIt = it; ++tIt; - while (true) + for (;;) { if (*p == '\0') { @@ -1381,15 +1381,15 @@ namespace Nz return npos; } - unsigned int String::FindWord(const char* string, int start, UInt32 flags) const + std::size_t String::FindWord(const char* string, std::intmax_t start, UInt32 flags) const { if (!string || !string[0] || m_sharedString->size == 0) return npos; if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return npos; @@ -1422,7 +1422,7 @@ namespace Nz utf8::unchecked::iterator tIt = it; ++tIt; - while (true) + for (;;) { if (*p == '\0') { @@ -1462,7 +1462,7 @@ namespace Nz utf8::unchecked::iterator tIt = it; ++tIt; - while (true) + for (;;) { if (*p == '\0') { @@ -1497,7 +1497,7 @@ namespace Nz const char* p = &string[1]; const char* tPtr = ptr+1; - while (true) + for (;;) { if (*p == '\0') { @@ -1528,7 +1528,7 @@ namespace Nz const char* p = &string[1]; const char* tPtr = ptr+1; - while (true) + for (;;) { if (*p == '\0') { @@ -1553,15 +1553,15 @@ namespace Nz return npos; } - unsigned int String::FindWord(const String& string, int start, UInt32 flags) const + std::size_t String::FindWord(const String& string, std::intmax_t start, UInt32 flags) const { if (string.m_sharedString->size == 0 || string.m_sharedString->size > m_sharedString->size) return npos; if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return npos; @@ -1594,7 +1594,7 @@ namespace Nz utf8::unchecked::iterator tIt = it; ++tIt; - while (true) + for (;;) { if (*p == '\0') { @@ -1634,7 +1634,7 @@ namespace Nz utf8::unchecked::iterator tIt = it; ++tIt; - while (true) + for (;;) { if (*p == '\0') { @@ -1670,7 +1670,7 @@ namespace Nz const char* p = &string.m_sharedString->string[1]; const char* tPtr = ptr+1; - while (true) + for (;;) { if (*p == '\0') { @@ -1692,7 +1692,7 @@ namespace Nz } else { - while ((ptr = std::strstr(ptr, string.GetConstBuffer()))) + while ((ptr = std::strstr(ptr, string.GetConstBuffer())) != nullptr) { // Si le mot est bien isolé if ((ptr == m_sharedString->string.get() || std::isspace(*(ptr-1))) && (*(ptr+m_sharedString->size) == '\0' || std::isspace(*(ptr+m_sharedString->size)))) @@ -1713,7 +1713,7 @@ namespace Nz return m_sharedString->string.get(); } - unsigned int String::GetCapacity() const + std::size_t String::GetCapacity() const { return m_sharedString->capacity; } @@ -1723,12 +1723,12 @@ namespace Nz return m_sharedString->string.get(); } - unsigned int String::GetLength() const + std::size_t String::GetLength() const { return utf8::distance(m_sharedString->string.get(), &m_sharedString->string[m_sharedString->size]); } - unsigned int String::GetSize() const + std::size_t String::GetSize() const { return m_sharedString->size; } @@ -1794,11 +1794,11 @@ namespace Nz String String::GetWord(unsigned int index, UInt32 flags) const { - unsigned int startPos = GetWordPosition(index, flags); + std::size_t startPos = GetWordPosition(index, flags); if (startPos == npos) return String(); - int endPos = -1; + std::intmax_t endPos = -1; const char* ptr = &m_sharedString->string[startPos]; if (flags & HandleUtf8) { @@ -1807,7 +1807,7 @@ namespace Nz { if (Unicode::GetCategory(*it) & Unicode::Category_Separator) { - endPos = static_cast(it.base() - m_sharedString->string.get() - 1); + endPos = static_cast(it.base() - m_sharedString->string.get() - 1); break; } } @@ -1819,7 +1819,7 @@ namespace Nz { if (std::isspace(*ptr)) { - endPos = static_cast(ptr - m_sharedString->string.get() - 1); + endPos = static_cast(ptr - m_sharedString->string.get() - 1); break; } } @@ -1829,7 +1829,7 @@ namespace Nz return SubString(startPos, endPos); } - unsigned int String::GetWordPosition(unsigned int index, UInt32 flags) const + std::size_t String::GetWordPosition(unsigned int index, UInt32 flags) const { if (m_sharedString->size == 0) return npos; @@ -1851,7 +1851,7 @@ namespace Nz { inWord = true; if (++currentWord > index) - return static_cast(it.base() - m_sharedString->string.get()); + return it.base() - m_sharedString->string.get(); } } } @@ -1879,25 +1879,25 @@ namespace Nz return npos; } - String& String::Insert(int pos, char character) + String& String::Insert(std::intmax_t pos, char character) { return Insert(pos, &character, 1); } - String& String::Insert(int pos, const char* string) + String& String::Insert(std::intmax_t pos, const char* string) { return Insert(pos, string, std::strlen(string)); } - String& String::Insert(int pos, const char* string, unsigned int length) + String& String::Insert(std::intmax_t pos, const char* string, std::size_t length) { if (length == 0) return *this; if (pos < 0) - pos = std::max(m_sharedString->size + pos, 0U); + pos = std::max(m_sharedString->size + pos, 0); - unsigned int start = std::min(static_cast(pos), m_sharedString->size); + std::size_t start = std::min(pos, m_sharedString->size); // Si le buffer est déjà suffisamment grand if (m_sharedString->capacity >= m_sharedString->size + length) @@ -1934,7 +1934,7 @@ namespace Nz return *this; } - String& String::Insert(int pos, const String& string) + String& String::Insert(std::intmax_t pos, const String& string) { return Insert(pos, string.GetConstBuffer(), string.m_sharedString->size); } @@ -2073,7 +2073,7 @@ namespace Nz return Insert(0, string); } - String& String::Prepend(const char* string, unsigned int length) + String& String::Prepend(const char* string, std::size_t length) { return Insert(0, string, length); } @@ -2083,7 +2083,7 @@ namespace Nz return Insert(0, string); } - unsigned int String::Replace(char oldCharacter, char newCharacter, int start, UInt32 flags) + unsigned int String::Replace(char oldCharacter, char newCharacter, std::intmax_t start, UInt32 flags) { if (oldCharacter == '\0' || oldCharacter == newCharacter) return 0; @@ -2092,9 +2092,9 @@ namespace Nz return Replace(String(oldCharacter), String(), start); if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return npos; @@ -2111,7 +2111,7 @@ namespace Nz { if (!found) { - unsigned int offset = ptr-m_sharedString->string.get(); + std::ptrdiff_t offset = ptr - m_sharedString->string.get(); EnsureOwnership(); @@ -2127,11 +2127,11 @@ namespace Nz } else { - while ((ptr = std::strchr(ptr, oldCharacter))) + while ((ptr = std::strchr(ptr, oldCharacter)) != nullptr) { if (!found) { - unsigned int offset = ptr-m_sharedString->string.get(); + std::ptrdiff_t offset = ptr-m_sharedString->string.get(); EnsureOwnership(); @@ -2147,20 +2147,20 @@ namespace Nz return count; } - unsigned int String::Replace(const char* oldString, const char* replaceString, int start, UInt32 flags) + unsigned int String::Replace(const char* oldString, const char* replaceString, std::intmax_t start, UInt32 flags) { return Replace(oldString, std::strlen(oldString), replaceString, std::strlen(replaceString), start, flags); } - unsigned int String::Replace(const char* oldString, unsigned int oldLength, const char* replaceString, unsigned int replaceLength, int start, UInt32 flags) + unsigned int String::Replace(const char* oldString, std::size_t oldLength, const char* replaceString, std::size_t replaceLength, std::intmax_t start, UInt32 flags) { if (oldLength == 0) return 0; if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return 0; @@ -2186,7 +2186,7 @@ namespace Nz } else ///TODO: Algorithme de remplacement sans changement de buffer (si replaceLength < oldLength) { - unsigned int newSize = m_sharedString->size + Count(oldString)*(replaceLength - oldLength); + std::size_t newSize = m_sharedString->size + Count(oldString)*(replaceLength - oldLength); if (newSize == m_sharedString->size) // Alors c'est que Count(oldString) == 0 return 0; @@ -2218,12 +2218,12 @@ namespace Nz return count; } - unsigned int String::Replace(const String& oldString, const String& replaceString, int start, UInt32 flags) + unsigned int String::Replace(const String& oldString, const String& replaceString, std::intmax_t start, UInt32 flags) { return Replace(oldString.GetConstBuffer(), oldString.m_sharedString->size, replaceString.GetConstBuffer(), replaceString.m_sharedString->size, start, flags); } - unsigned int String::ReplaceAny(const char* oldCharacters, char replaceCharacter, int start, UInt32 flags) + unsigned int String::ReplaceAny(const char* oldCharacters, char replaceCharacter, std::intmax_t start, UInt32 flags) { ///FIXME: Ne gère pas l'UTF-8 if (!oldCharacters || !oldCharacters[0]) @@ -2233,9 +2233,9 @@ namespace Nz return ReplaceAny(String(oldCharacters), String(), start);*/ if (start < 0) - start = std::max(m_sharedString->size + start, 0U); + start = std::max(m_sharedString->size + start, 0); - unsigned int pos = static_cast(start); + std::size_t pos = static_cast(start); if (pos >= m_sharedString->size) return npos; @@ -2254,7 +2254,7 @@ namespace Nz { if (!found) { - unsigned int offset = ptr-m_sharedString->string.get(); + std::ptrdiff_t offset = ptr - m_sharedString->string.get(); EnsureOwnership(); @@ -2274,11 +2274,11 @@ namespace Nz else { bool found = false; - while ((ptr = std::strpbrk(ptr, oldCharacters))) + while ((ptr = std::strpbrk(ptr, oldCharacters)) != nullptr) { if (!found) { - unsigned int offset = ptr-m_sharedString->string.get(); + std::ptrdiff_t offset = ptr - m_sharedString->string.get(); EnsureOwnership(); @@ -2294,7 +2294,7 @@ namespace Nz return count; } /* - unsigned int String::ReplaceAny(const char* oldCharacters, const char* replaceString, int start, UInt32 flags) + unsigned int String::ReplaceAny(const char* oldCharacters, const char* replaceString, std::intmax_t start, UInt32 flags) { if (start < 0) { @@ -2375,7 +2375,7 @@ namespace Nz return count; } - unsigned int String::ReplaceAny(const String& oldCharacters, const String& replaceString, int start, UInt32 flags) + unsigned int String::ReplaceAny(const String& oldCharacters, const String& replaceString, std::intmax_t start, UInt32 flags) { if (start < 0) { @@ -2454,7 +2454,8 @@ namespace Nz return count; } */ - void String::Reserve(unsigned int bufferSize) + + void String::Reserve(std::size_t bufferSize) { if (m_sharedString->capacity > bufferSize) return; @@ -2468,7 +2469,7 @@ namespace Nz m_sharedString = std::move(newString); } - String& String::Resize(int size, char character) + String& String::Resize(std::intmax_t size, char character) { if (size == 0) { @@ -2477,10 +2478,9 @@ namespace Nz } if (size < 0) - size = std::max(m_sharedString->size + size, 0U); - - unsigned int newSize = static_cast(size); + size = std::max(m_sharedString->size + size, 0); + std::size_t newSize = static_cast(size); if (m_sharedString->capacity >= newSize) { EnsureOwnership(); @@ -2506,7 +2506,7 @@ namespace Nz return *this; } - String String::Resized(int size, char character) const + String String::Resized(std::intmax_t size, char character) const { if (size < 0) size = m_sharedString->size + size; @@ -2514,7 +2514,7 @@ namespace Nz if (size <= 0) return String(); - unsigned int newSize = static_cast(size); + std::size_t newSize = static_cast(size); if (newSize == m_sharedString->size) return *this; @@ -2535,8 +2535,8 @@ namespace Nz { if (m_sharedString->size != 0) { - unsigned int i = 0; - unsigned int j = m_sharedString->size-1; + std::size_t i = 0; + std::size_t j = m_sharedString->size-1; while (i < j) std::swap(m_sharedString->string[i++], m_sharedString->string[j--]); @@ -2586,7 +2586,7 @@ namespace Nz return *this; } - String& String::Set(unsigned int rep, char character) + String& String::Set(std::size_t rep, char character) { if (rep > 0) { @@ -2609,14 +2609,14 @@ namespace Nz return *this; } - String& String::Set(unsigned int rep, const char* string) + String& String::Set(std::size_t rep, const char* string) { return Set(rep, string, (string) ? std::strlen(string) : 0); } - String& String::Set(unsigned int rep, const char* string, unsigned int length) + String& String::Set(std::size_t rep, const char* string, std::size_t length) { - unsigned int totalSize = rep*length; + std::size_t totalSize = rep*length; if (totalSize > 0) { @@ -2630,7 +2630,7 @@ namespace Nz else m_sharedString = std::make_shared(totalSize); - for (unsigned int i = 0; i < rep; ++i) + for (std::size_t i = 0; i < rep; ++i) std::memcpy(&m_sharedString->string[i*length], string, length); } else @@ -2639,7 +2639,7 @@ namespace Nz return *this; } - String& String::Set(unsigned int rep, const String& string) + String& String::Set(std::size_t rep, const String& string) { return Set(rep, string.GetConstBuffer(), string.m_sharedString->size); } @@ -2649,7 +2649,7 @@ namespace Nz return Set(string, (string) ? std::strlen(string) : 0); } - String& String::Set(const char* string, unsigned int length) + String& String::Set(const char* string, std::size_t length) { if (length > 0) { @@ -2757,12 +2757,12 @@ namespace Nz return Set(Simplified(flags)); } - unsigned int String::Split(std::vector& result, char separation, int start, UInt32 flags) const + unsigned int String::Split(std::vector& result, char separation, std::intmax_t start, UInt32 flags) const { if (separation == '\0' || m_sharedString->size == 0) return 0; - unsigned int lastSep = Find(separation, start, flags); + std::size_t lastSep = Find(separation, start, flags); if (lastSep == npos) { result.push_back(*this); @@ -2771,9 +2771,9 @@ namespace Nz else if (lastSep != 0) result.push_back(SubString(0, lastSep-1)); - while (true) + for (;;) { - unsigned int sep = Find(separation, lastSep+1, flags); + std::size_t sep = Find(separation, lastSep+1, flags); if (sep == npos) break; @@ -2789,19 +2789,19 @@ namespace Nz return result.size(); } - unsigned int String::Split(std::vector& result, const char* separation, int start, UInt32 flags) const + unsigned int String::Split(std::vector& result, const char* separation, std::intmax_t start, UInt32 flags) const { return Split(result, separation, std::strlen(separation), start, flags); } - unsigned int String::Split(std::vector& result, const char* separation, unsigned int length, int start, UInt32 flags) const + unsigned int String::Split(std::vector& result, const char* separation, std::size_t length, std::intmax_t start, UInt32 flags) const { if (m_sharedString->size == 0) return 0; else if (length == 0) { result.reserve(m_sharedString->size); - for (unsigned int i = 0; i < m_sharedString->size; ++i) + for (std::size_t i = 0; i < m_sharedString->size; ++i) result.push_back(String(m_sharedString->string[i])); return m_sharedString->size; @@ -2812,8 +2812,8 @@ namespace Nz return 1; } - unsigned int lastSep = Find(separation, start, flags); - unsigned int oldSize = result.size(); + std::size_t lastSep = Find(separation, start, flags); + std::size_t oldSize = result.size(); if (lastSep == npos) { result.push_back(*this); @@ -2822,7 +2822,7 @@ namespace Nz else if (lastSep != 0) result.push_back(SubString(0, lastSep-1)); - unsigned int sep; + std::size_t sep; while ((sep = Find(separation, lastSep + length, flags)) != npos) { if (sep-lastSep > length) @@ -2837,19 +2837,19 @@ namespace Nz return result.size()-oldSize; } - unsigned int String::Split(std::vector& result, const String& separation, int start, UInt32 flags) const + unsigned int String::Split(std::vector& result, const String& separation, std::intmax_t start, UInt32 flags) const { return Split(result, separation.m_sharedString->string.get(), separation.m_sharedString->size, start, flags); } - unsigned int String::SplitAny(std::vector& result, const char* separations, int start, UInt32 flags) const + unsigned int String::SplitAny(std::vector& result, const char* separations, std::intmax_t start, UInt32 flags) const { if (m_sharedString->size == 0) return 0; - unsigned int oldSize = result.size(); + std::size_t oldSize = result.size(); - unsigned int lastSep = FindAny(separations, start, flags); + std::size_t lastSep = FindAny(separations, start, flags); if (lastSep == npos) { result.push_back(*this); @@ -2858,7 +2858,7 @@ namespace Nz else if (lastSep != 0) result.push_back(SubString(0, lastSep-1)); - unsigned int sep; + std::size_t sep; while ((sep = FindAny(separations, lastSep+1, flags)) != npos) { if (sep-lastSep > 1) @@ -2873,7 +2873,7 @@ namespace Nz return result.size()-oldSize; } - unsigned int String::SplitAny(std::vector& result, const String& separations, int start, UInt32 flags) const + unsigned int String::SplitAny(std::vector& result, const String& separations, std::intmax_t start, UInt32 flags) const { return SplitAny(result, separations.m_sharedString->string.get(), start, flags); } @@ -2998,12 +2998,12 @@ namespace Nz return false; } - String String::SubString(int startPos, int endPos) const + String String::SubString(std::intmax_t startPos, std::intmax_t endPos) const { if (startPos < 0) - startPos = std::max(m_sharedString->size+startPos, 0U); + startPos = std::max(m_sharedString->size + startPos, 0); - unsigned int start = static_cast(startPos); + std::size_t start = static_cast(startPos); if (endPos < 0) { @@ -3012,12 +3012,11 @@ namespace Nz return String(); } - unsigned int minEnd = std::min(static_cast(endPos), m_sharedString->size-1); - + std::size_t minEnd = std::min(static_cast(endPos), m_sharedString->size - 1); if (start > minEnd || start >= m_sharedString->size) return String(); - unsigned int size = minEnd-start+1; + std::size_t size = minEnd - start + 1; auto str = std::make_shared(size); std::memcpy(str->string.get(), &m_sharedString->string[start], size); @@ -3025,12 +3024,12 @@ namespace Nz return String(std::move(str)); } - String String::SubStringFrom(char character, int startPos, bool fromLast, bool include, UInt32 flags) const + String String::SubStringFrom(char character, std::intmax_t startPos, bool fromLast, bool include, UInt32 flags) const { if (character == '\0') return *this; - unsigned int pos; + std::size_t pos; if (fromLast) pos = FindLast(character, startPos, flags); else @@ -3044,14 +3043,14 @@ namespace Nz return SubString(pos + ((include) ? 0 : 1)); } - String String::SubStringFrom(const char* string, int startPos, bool fromLast, bool include, UInt32 flags) const + String String::SubStringFrom(const char* string, std::intmax_t startPos, bool fromLast, bool include, UInt32 flags) const { return SubStringFrom(string, std::strlen(string), startPos, fromLast, include, flags); } - String String::SubStringFrom(const char* string, unsigned int length, int startPos, bool fromLast, bool include, UInt32 flags) const + String String::SubStringFrom(const char* string, std::size_t length, std::intmax_t startPos, bool fromLast, bool include, UInt32 flags) const { - unsigned int pos; + std::size_t pos; if (fromLast) pos = FindLast(string, startPos, flags); else @@ -3065,17 +3064,17 @@ namespace Nz return SubString(pos + ((include) ? 0 : length)); } - String String::SubStringFrom(const String& string, int startPos, bool fromLast, bool include, UInt32 flags) const + String String::SubStringFrom(const String& string, std::intmax_t startPos, bool fromLast, bool include, UInt32 flags) const { return SubStringFrom(string.GetConstBuffer(), string.m_sharedString->size, startPos, fromLast, include, flags); } - String String::SubStringTo(char character, int startPos, bool toLast, bool include, UInt32 flags) const + String String::SubStringTo(char character, std::intmax_t startPos, bool toLast, bool include, UInt32 flags) const { if (character == '\0') return *this; - unsigned int pos; + std::size_t pos; if (toLast) pos = FindLast(character, startPos); else @@ -3089,14 +3088,14 @@ namespace Nz return SubString(0, pos+((include) ? 1 : 0)-1); } - String String::SubStringTo(const char* string, int startPos, bool toLast, bool include, UInt32 flags) const + String String::SubStringTo(const char* string, std::intmax_t startPos, bool toLast, bool include, UInt32 flags) const { return SubStringTo(string, std::strlen(string), startPos, toLast, include, flags); } - String String::SubStringTo(const char* string, unsigned int length, int startPos, bool toLast, bool include, UInt32 flags) const + String String::SubStringTo(const char* string, std::size_t length, std::intmax_t startPos, bool toLast, bool include, UInt32 flags) const { - unsigned int pos; + std::size_t pos; if (toLast) pos = FindLast(string, startPos, flags); else @@ -3110,7 +3109,7 @@ namespace Nz return SubString(0, pos+((include) ? length : 0)-1); } - String String::SubStringTo(const String& string, int startPos, bool toLast, bool include, UInt32 flags) const + String String::SubStringTo(const String& string, std::intmax_t startPos, bool toLast, bool include, UInt32 flags) const { return SubStringTo(string.GetConstBuffer(), string.m_sharedString->size, startPos, toLast, include, flags); } @@ -3262,8 +3261,8 @@ namespace Nz if (m_sharedString->size == 0) return *this; - unsigned int startPos; - unsigned int endPos; + std::size_t startPos; + std::size_t endPos; if (flags & HandleUtf8) { if ((flags & TrimOnlyRight) == 0) @@ -3326,8 +3325,8 @@ namespace Nz if (m_sharedString->size == 0) return *this; - unsigned int startPos = 0; - unsigned int endPos = m_sharedString->size-1; + std::size_t startPos = 0; + std::size_t endPos = m_sharedString->size-1; if (flags & CaseInsensitive) { char ch = Detail::ToLower(character); @@ -3429,7 +3428,7 @@ namespace Nz return std::string(m_sharedString->string.get(), m_sharedString->size); } - char& String::operator[](unsigned int pos) + char& String::operator[](std::size_t pos) { EnsureOwnership(); @@ -3439,7 +3438,7 @@ namespace Nz return m_sharedString->string[pos]; } - char String::operator[](unsigned int pos) const + char String::operator[](std::size_t pos) const { #if NAZARA_CORE_SAFE if (pos >= m_sharedString->size) @@ -3497,7 +3496,7 @@ namespace Nz if (m_sharedString->size == 0) return string; - unsigned int length = std::strlen(string); + std::size_t length = std::strlen(string); if (length == 0) return *this; @@ -3761,7 +3760,7 @@ namespace Nz String String::Boolean(bool boolean) { - unsigned int size = (boolean) ? 4 : 5; + std::size_t size = (boolean) ? 4 : 5; auto str = std::make_shared(size); std::memcpy(str->string.get(), (boolean) ? "true" : "false", size); @@ -3859,7 +3858,7 @@ namespace Nz String String::Pointer(const void* ptr) { - const unsigned int capacity = sizeof(void*)*2 + 2; + const std::size_t capacity = sizeof(void*)*2 + 2; auto str = std::make_shared(capacity); str->size = std::sprintf(str->string.get(), "0x%p", ptr); @@ -3872,7 +3871,7 @@ namespace Nz if (character == '\0') return String(); - unsigned int count = 0; + std::size_t count = 0; if (character < 0x80) count = 1; else if (character < 0x800) @@ -3899,7 +3898,7 @@ namespace Nz return String(); const char16_t* ptr = u16String; - unsigned int count = 0; + std::size_t count = 0; do count++; while (*++ptr); @@ -3922,7 +3921,7 @@ namespace Nz return String(); const char32_t* ptr = u32String; - unsigned int count = 0; + std::size_t count = 0; do { char32_t cp = *ptr; @@ -3949,7 +3948,7 @@ namespace Nz return String(); const wchar_t* ptr = wString; - unsigned int count = 0; + std::size_t count = 0; do { char32_t cp = *ptr; @@ -3975,7 +3974,7 @@ namespace Nz str.Clear(); char c; - do + for (;;) { is.get(c); if (c == '\0') @@ -3990,7 +3989,6 @@ namespace Nz else str += c; } - while (true); return is; } @@ -4026,8 +4024,8 @@ namespace Nz if (nstring.IsEmpty()) return string; - unsigned int size = std::strlen(string); - unsigned int totalSize = size + nstring.m_sharedString->size; + std::size_t size = std::strlen(string); + std::size_t totalSize = size + nstring.m_sharedString->size; auto str = std::make_shared(totalSize); std::memcpy(str->string.get(), string, size); @@ -4044,7 +4042,7 @@ namespace Nz if (nstring.m_sharedString->size == 0) return string; - unsigned int totalSize = string.size() + nstring.m_sharedString->size; + std::size_t totalSize = string.size() + nstring.m_sharedString->size; auto str = std::make_shared(totalSize); std::memcpy(str->string.get(), string.c_str(), string.size()); @@ -4227,7 +4225,7 @@ namespace Nz return context.stream->Read(string->GetBuffer(), size) == size; } - const unsigned int String::npos(std::numeric_limits::max()); + const std::size_t String::npos(std::numeric_limits::max()); } namespace std @@ -4237,7 +4235,8 @@ namespace std str.Clear(); char c; - do + + for (;;) { is.get(c); if (c != '\n' && c != '\0') @@ -4245,7 +4244,6 @@ namespace std else break; } - while (true); return is; } @@ -4255,7 +4253,8 @@ namespace std str.Clear(); char c; - do + + for (;;) { is.get(c); if (c != delim && c != '\0') @@ -4263,7 +4262,6 @@ namespace std else break; } - while (true); return is; } diff --git a/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp b/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp index 92fe451b6..c93859d68 100644 --- a/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp +++ b/src/Nazara/Core/Win32/TaskSchedulerImpl.cpp @@ -11,7 +11,7 @@ namespace Nz { - bool TaskSchedulerImpl::Initialize(unsigned int workerCount) + bool TaskSchedulerImpl::Initialize(std::size_t workerCount) { if (IsInitialized()) return true; // Déjà initialisé @@ -30,9 +30,9 @@ namespace Nz s_workerThreads.reset(new HANDLE[workerCount]); // L'identifiant de chaque worker doit rester en vie jusqu'à ce que chaque thread soit correctement lancé - std::unique_ptr workerIDs(new unsigned int[workerCount]); + std::unique_ptr workerIDs(new std::size_t[workerCount]); - for (unsigned int i = 0; i < workerCount; ++i) + for (std::size_t i = 0; i < workerCount; ++i) { // On initialise les évènements, mutex et threads de chaque worker Worker& worker = s_workers[i]; @@ -59,18 +59,18 @@ namespace Nz return s_workerCount > 0; } - void TaskSchedulerImpl::Run(Functor** tasks, unsigned int count) + void TaskSchedulerImpl::Run(Functor** tasks, std::size_t count) { // On s'assure que des tâches ne sont pas déjà en cours WaitForMultipleObjects(s_workerCount, &s_doneEvents[0], true, INFINITE); std::ldiv_t div = std::ldiv(count, s_workerCount); // Division et modulo en une opération, y'a pas de petit profit - for (unsigned int i = 0; i < s_workerCount; ++i) + for (std::size_t i = 0; i < s_workerCount; ++i) { // On va maintenant répartir les tâches entre chaque worker et les envoyer dans la queue de chacun Worker& worker = s_workers[i]; - unsigned int taskCount = (i == 0) ? div.quot + div.rem : div.quot; - for (unsigned int j = 0; j < taskCount; ++j) + std::size_t taskCount = (i == 0) ? div.quot + div.rem : div.quot; + for (std::size_t j = 0; j < taskCount; ++j) worker.queue.push(*tasks++); // On stocke le nombre de tâches à côté dans un entier atomique pour éviter d'entrer inutilement dans une section critique @@ -145,13 +145,13 @@ namespace Nz WaitForMultipleObjects(s_workerCount, &s_doneEvents[0], true, INFINITE); } - Functor* TaskSchedulerImpl::StealTask(unsigned int workerID) + Functor* TaskSchedulerImpl::StealTask(std::size_t workerID) { bool shouldRetry; do { shouldRetry = false; - for (unsigned int i = 0; i < s_workerCount; ++i) + for (std::size_t i = 0; i < s_workerCount; ++i) { // On ne vole pas la famille, ni soi-même. if (i == workerID) @@ -244,5 +244,5 @@ namespace Nz std::unique_ptr TaskSchedulerImpl::s_doneEvents; // Doivent être contigus std::unique_ptr TaskSchedulerImpl::s_workers; std::unique_ptr TaskSchedulerImpl::s_workerThreads; // Doivent être contigus - unsigned int TaskSchedulerImpl::s_workerCount; + std::size_t TaskSchedulerImpl::s_workerCount; } diff --git a/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp b/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp index 3eccebb7c..00fdec634 100644 --- a/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp +++ b/src/Nazara/Core/Win32/TaskSchedulerImpl.hpp @@ -22,19 +22,19 @@ namespace Nz TaskSchedulerImpl() = delete; ~TaskSchedulerImpl() = delete; - static bool Initialize(unsigned int workerCount); + static bool Initialize(std::size_t workerCount); static bool IsInitialized(); - static void Run(Functor** tasks, unsigned int count); + static void Run(Functor** tasks, std::size_t count); static void Uninitialize(); static void WaitForTasks(); private: - static Functor* StealTask(unsigned int workerID); + static Functor* StealTask(std::size_t workerID); static unsigned int __stdcall WorkerProc(void* userdata); struct Worker { - std::atomic_uint workCount; + std::atomic_size_t workCount; std::queue queue; CRITICAL_SECTION queueMutex; HANDLE wakeEvent; @@ -44,7 +44,7 @@ namespace Nz static std::unique_ptr s_doneEvents; // Doivent être contigus static std::unique_ptr s_workers; static std::unique_ptr s_workerThreads; // Doivent être contigus - static unsigned int s_workerCount; + static std::size_t s_workerCount; }; } diff --git a/src/Nazara/Renderer/Renderer.cpp b/src/Nazara/Renderer/Renderer.cpp index 7c2ba3459..57cc8522f 100644 --- a/src/Nazara/Renderer/Renderer.cpp +++ b/src/Nazara/Renderer/Renderer.cpp @@ -1556,7 +1556,7 @@ namespace Nz { ComponentType type; bool enabled; - unsigned int offset; + std::size_t offset; vertexDeclaration->GetComponent(static_cast(j), &enabled, &type, &offset); if (enabled) diff --git a/src/Nazara/Utility/Algorithm.cpp b/src/Nazara/Utility/Algorithm.cpp index dbadfe149..d22021cd2 100644 --- a/src/Nazara/Utility/Algorithm.cpp +++ b/src/Nazara/Utility/Algorithm.cpp @@ -379,9 +379,8 @@ namespace Nz m_vertices[i].current_score = CalculateVertexScore(i); // calculate scores for all active triangles - float max_score; + float max_score = std::numeric_limits::lowest(); int max_score_tri = -1; - bool first_time = true; for (unsigned int i = 0; i < m_triangles.size(); ++i) { @@ -395,9 +394,8 @@ namespace Nz m_triangles[i].current_score = sc; - if (first_time || sc > max_score) + if (sc > max_score) { - first_time = false; max_score = sc; max_score_tri = i; } @@ -564,8 +562,7 @@ namespace Nz int PartialScoreRecalculation() { // iterate through all the vertices of the cache - bool first_time = true; - float max_score; + float max_score = std::numeric_limits::lowest(); int max_score_tri = -1; for (unsigned int i = 0; i < 32; ++i) @@ -588,9 +585,8 @@ namespace Nz float sc = t->current_score; // we actually found a triangle to process - if (first_time || sc > max_score) + if (sc > max_score) { - first_time = false; max_score = sc; max_score_tri = tri; } diff --git a/src/Nazara/Utility/VertexDeclaration.cpp b/src/Nazara/Utility/VertexDeclaration.cpp index 323c62b99..998f12f8b 100644 --- a/src/Nazara/Utility/VertexDeclaration.cpp +++ b/src/Nazara/Utility/VertexDeclaration.cpp @@ -58,7 +58,7 @@ namespace Nz } } - void VertexDeclaration::EnableComponent(VertexComponent component, ComponentType type, unsigned int offset) + void VertexDeclaration::EnableComponent(VertexComponent component, ComponentType type, std::size_t offset) { #ifdef NAZARA_DEBUG if (component > VertexComponent_Max) @@ -91,7 +91,7 @@ namespace Nz m_stride += Utility::ComponentStride[type]; } - void VertexDeclaration::GetComponent(VertexComponent component, bool* enabled, ComponentType* type, unsigned int* offset) const + void VertexDeclaration::GetComponent(VertexComponent component, bool* enabled, ComponentType* type, std::size_t* offset) const { #ifdef NAZARA_DEBUG if (component > VertexComponent_Max) @@ -121,12 +121,12 @@ namespace Nz *offset = vertexComponent.offset; } - unsigned int VertexDeclaration::GetStride() const + std::size_t VertexDeclaration::GetStride() const { return m_stride; } - void VertexDeclaration::SetStride(unsigned int stride) + void VertexDeclaration::SetStride(std::size_t stride) { m_stride = stride; } From b5fb11b5c26c67ebaa2cf33caf163db9625bfd05 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 25 Nov 2015 18:19:38 +0100 Subject: [PATCH 79/97] Core/Serializer: Add FlushBits method Former-commit-id: 64b8d4277001ab763dc92c0a157ebce72a8bfef8 --- include/Nazara/Core/Serializer.hpp | 2 ++ include/Nazara/Core/Serializer.inl | 22 +++++++++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/include/Nazara/Core/Serializer.hpp b/include/Nazara/Core/Serializer.hpp index 994e85a19..ae35f2254 100644 --- a/include/Nazara/Core/Serializer.hpp +++ b/include/Nazara/Core/Serializer.hpp @@ -25,6 +25,8 @@ namespace Nz inline Endianness GetDataEndianness() const; inline Stream& GetStream() const; + inline bool FlushBits(); + inline void SetDataEndianness(Endianness endiannes); inline void SetStream(Stream& stream); diff --git a/include/Nazara/Core/Serializer.inl b/include/Nazara/Core/Serializer.inl index 168d7f812..69c433ad0 100644 --- a/include/Nazara/Core/Serializer.inl +++ b/include/Nazara/Core/Serializer.inl @@ -16,13 +16,8 @@ namespace Nz inline Serializer::~Serializer() { - if (m_serializationContext.currentBitPos != 8) - { - m_serializationContext.currentBitPos = 8; //< To prevent Serialize to flush bits itself - - if (!Serialize(m_serializationContext, m_serializationContext.currentByte)) - NazaraWarning("Failed to flush bits at serializer destruction"); - } + if (!FlushBits()) + NazaraWarning("Failed to flush bits at serializer destruction"); } inline Endianness Serializer::GetDataEndianness() const @@ -35,6 +30,19 @@ namespace Nz return *m_serializationContext.stream; } + inline bool Serializer::FlushBits() + { + if (m_serializationContext.currentBitPos != 8) + { + m_serializationContext.currentBitPos = 8; //< To prevent Serialize to flush bits itself + + if (!Serialize(m_serializationContext, m_serializationContext.currentByte)) + return false; + } + + return true; + } + inline void Serializer::SetDataEndianness(Endianness endiannes) { m_serializationContext.endianness = endiannes; From 4619099a01bbbb2cb45ea2672c43a3373b490c24 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 25 Nov 2015 18:20:02 +0100 Subject: [PATCH 80/97] Core/SimpleTextDrawer: Fix assignment operator Former-commit-id: 52aa69ef0712d142ab36eae6dedf084c32a08012 --- include/Nazara/Utility/SimpleTextDrawer.hpp | 2 +- src/Nazara/Utility/SimpleTextDrawer.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Utility/SimpleTextDrawer.hpp b/include/Nazara/Utility/SimpleTextDrawer.hpp index 2d2709679..22b52f293 100644 --- a/include/Nazara/Utility/SimpleTextDrawer.hpp +++ b/include/Nazara/Utility/SimpleTextDrawer.hpp @@ -41,7 +41,7 @@ namespace Nz void SetStyle(UInt32 style); void SetText(const String& str); - SimpleTextDrawer& operator=(const SimpleTextDrawer& drawer) = default; + SimpleTextDrawer& operator=(const SimpleTextDrawer& drawer); SimpleTextDrawer& operator=(SimpleTextDrawer&& drawer); static SimpleTextDrawer Draw(const String& str, unsigned int characterSize, UInt32 style = TextStyle_Regular, const Color& color = Color::White); diff --git a/src/Nazara/Utility/SimpleTextDrawer.cpp b/src/Nazara/Utility/SimpleTextDrawer.cpp index 842f8ed20..6f7393dd9 100644 --- a/src/Nazara/Utility/SimpleTextDrawer.cpp +++ b/src/Nazara/Utility/SimpleTextDrawer.cpp @@ -144,6 +144,19 @@ namespace Nz m_glyphUpdated = false; } + SimpleTextDrawer& SimpleTextDrawer::operator=(const SimpleTextDrawer& drawer) + { + m_characterSize = drawer.m_characterSize; + m_color = drawer.m_color; + m_style = drawer.m_style; + m_text = drawer.m_text; + + m_glyphUpdated = false; + SetFont(drawer.m_font); + + return *this; + } + SimpleTextDrawer& SimpleTextDrawer::operator=(SimpleTextDrawer&& drawer) { DisconnectFontSlots(); From 72a6148d1b864d4004c7327f47b07a270145808b Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 25 Nov 2015 18:20:17 +0100 Subject: [PATCH 81/97] Core/MemoryView: Fix OpenMode Former-commit-id: 71c88a9583981236650551b8bc0884abc04aeec5 --- src/Nazara/Core/MemoryView.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Nazara/Core/MemoryView.cpp b/src/Nazara/Core/MemoryView.cpp index f86200b90..a630241d5 100644 --- a/src/Nazara/Core/MemoryView.cpp +++ b/src/Nazara/Core/MemoryView.cpp @@ -10,7 +10,7 @@ namespace Nz { MemoryView::MemoryView(const void* ptr, UInt64 size) : - Stream(OpenMode_ReadOnly), + Stream(StreamOption_None, OpenMode_ReadOnly), m_ptr(reinterpret_cast(ptr)), m_pos(0), m_size(size) From 1e5cad5b241f78e215850100814d74705743c5c4 Mon Sep 17 00:00:00 2001 From: Lynix Date: Wed, 25 Nov 2015 18:28:33 +0100 Subject: [PATCH 82/97] Core/Unicode: Fix Unicode export Former-commit-id: 670984e75c25b3986f7cde250db073421e4b935a --- include/Nazara/Core/Unicode.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/Nazara/Core/Unicode.hpp b/include/Nazara/Core/Unicode.hpp index 6aa8794ce..631d8f8bd 100644 --- a/include/Nazara/Core/Unicode.hpp +++ b/include/Nazara/Core/Unicode.hpp @@ -8,10 +8,11 @@ #define NAZARA_UNICODE_HPP #include +#include namespace Nz { - class Unicode + class NAZARA_CORE_API Unicode { public: Unicode() = delete; From 5d3e4d7aeb6ca119b3faaa325d7d62423f785283 Mon Sep 17 00:00:00 2001 From: Lynix Date: Thu, 26 Nov 2015 23:57:48 +0100 Subject: [PATCH 83/97] Core/GuillotineBinPack: Fix search error Former-commit-id: 8b7428f59b0a1258c8096df2f784910523dee79d --- src/Nazara/Core/GuillotineBinPack.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Nazara/Core/GuillotineBinPack.cpp b/src/Nazara/Core/GuillotineBinPack.cpp index b3aedccc0..05f8736b5 100644 --- a/src/Nazara/Core/GuillotineBinPack.cpp +++ b/src/Nazara/Core/GuillotineBinPack.cpp @@ -154,7 +154,7 @@ namespace Nz bool bestFlipped; std::size_t bestFreeRect; std::size_t bestRect; - std::size_t bestScore = std::numeric_limits::max(); + int bestScore = std::numeric_limits::max(); for (std::size_t i = 0; i < m_freeRectangles.size(); ++i) { @@ -170,7 +170,7 @@ namespace Nz bestFreeRect = i; bestRect = j; bestFlipped = false; - bestScore = std::numeric_limits::min(); + bestScore = std::numeric_limits::min(); i = m_freeRectangles.size(); // Force a jump out of the outer loop as well - we got an instant fit. break; } @@ -180,7 +180,7 @@ namespace Nz bestFreeRect = i; bestRect = j; bestFlipped = true; - bestScore = std::numeric_limits::min(); + bestScore = std::numeric_limits::min(); i = m_freeRectangles.size(); // Force a jump out of the outer loop as well - we got an instant fit. break; } @@ -212,7 +212,7 @@ namespace Nz } // If we didn't manage to find any rectangle to pack, abort. - if (bestScore == std::numeric_limits::max()) + if (bestScore == std::numeric_limits::max()) { // Si nous le pouvons, on marque les rectangles n'ayant pas pu être insérés if (inserted) From 0a0e6d00f770e171b2a5eb9f910a684d618db316 Mon Sep 17 00:00:00 2001 From: Lynix Date: Fri, 27 Nov 2015 23:38:54 +0100 Subject: [PATCH 84/97] Graphics: Add render order Former-commit-id: 881ae69c214e024846dc0165f3476f76f5bcc0b5 --- .../NDK/Components/GraphicsComponent.hpp | 2 +- .../NDK/Components/GraphicsComponent.inl | 3 +- .../Nazara/Graphics/AbstractRenderQueue.hpp | 24 +-- .../Nazara/Graphics/DeferredRenderQueue.hpp | 36 ++-- .../Nazara/Graphics/ForwardRenderQueue.hpp | 44 ++-- .../Graphics/ForwardRenderTechnique.hpp | 8 +- .../Nazara/Graphics/InstancedRenderable.hpp | 1 + src/Nazara/Graphics/Billboard.cpp | 2 +- src/Nazara/Graphics/DeferredGeometryPass.cpp | 179 ++++++++-------- src/Nazara/Graphics/DeferredRenderQueue.cpp | 123 +++++++---- src/Nazara/Graphics/ForwardRenderQueue.cpp | 192 ++++++++++++------ .../Graphics/ForwardRenderTechnique.cpp | 46 +++-- src/Nazara/Graphics/Model.cpp | 2 +- src/Nazara/Graphics/SkeletalModel.cpp | 2 +- src/Nazara/Graphics/Sprite.cpp | 2 +- src/Nazara/Graphics/TextSprite.cpp | 2 +- 16 files changed, 404 insertions(+), 264 deletions(-) diff --git a/SDK/include/NDK/Components/GraphicsComponent.hpp b/SDK/include/NDK/Components/GraphicsComponent.hpp index 8d1e3e2f7..4a3ee80c9 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.hpp +++ b/SDK/include/NDK/Components/GraphicsComponent.hpp @@ -24,7 +24,7 @@ namespace Ndk inline void AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const; - inline void Attach(Nz::InstancedRenderableRef renderable); + inline void Attach(Nz::InstancedRenderableRef renderable, int renderOrder = 0); inline void EnsureTransformMatrixUpdate() const; diff --git a/SDK/include/NDK/Components/GraphicsComponent.inl b/SDK/include/NDK/Components/GraphicsComponent.inl index 56b003b00..c571384f8 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.inl +++ b/SDK/include/NDK/Components/GraphicsComponent.inl @@ -32,10 +32,11 @@ namespace Ndk } } - inline void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable) + inline void GraphicsComponent::Attach(Nz::InstancedRenderableRef renderable, int renderOrder) { m_renderables.emplace_back(m_transformMatrix); Renderable& r = m_renderables.back(); + r.data.renderOrder = renderOrder; r.renderable = std::move(renderable); r.renderableInvalidationSlot.Connect(r.renderable->OnInstancedRenderableInvalidateData, std::bind(&GraphicsComponent::InvalidateRenderableData, this, std::placeholders::_1, std::placeholders::_2, m_renderables.size()-1)); } diff --git a/include/Nazara/Graphics/AbstractRenderQueue.hpp b/include/Nazara/Graphics/AbstractRenderQueue.hpp index d5e4554b9..6c069e1d9 100644 --- a/include/Nazara/Graphics/AbstractRenderQueue.hpp +++ b/include/Nazara/Graphics/AbstractRenderQueue.hpp @@ -38,21 +38,21 @@ namespace Nz // 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 Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) = 0; - virtual void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) = 0; - virtual void AddDrawable(const Drawable* drawable) = 0; + virtual void AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) = 0; + virtual void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) = 0; + virtual void AddDrawable(int renderOrder, const Drawable* drawable) = 0; virtual void AddDirectionalLight(const DirectionalLight& light); - virtual void AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) = 0; + virtual void AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) = 0; virtual void AddPointLight(const PointLight& light); virtual void AddSpotLight(const SpotLight& light); - virtual void AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) = 0; + virtual void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) = 0; virtual void Clear(bool fully = false); diff --git a/include/Nazara/Graphics/DeferredRenderQueue.hpp b/include/Nazara/Graphics/DeferredRenderQueue.hpp index b69204174..76bff6926 100644 --- a/include/Nazara/Graphics/DeferredRenderQueue.hpp +++ b/include/Nazara/Graphics/DeferredRenderQueue.hpp @@ -29,18 +29,18 @@ namespace Nz DeferredRenderQueue(ForwardRenderQueue* forwardQueue); ~DeferredRenderQueue() = default; - void AddBillboard(const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; - void AddDrawable(const Drawable* drawable) override; - void AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; - void AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; + void AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddDrawable(int renderOrder, const Drawable* drawable) override; + void AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; + void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; void Clear(bool fully = false); @@ -75,7 +75,17 @@ namespace Nz typedef std::map ModelBatches; - ModelBatches opaqueModels; + struct Layer + { + ModelBatches opaqueModels; + unsigned int clearCount = 0; + }; + + std::map layers; + + private: + Layer& GetLayer(unsigned int i); ///TODO: Inline + ForwardRenderQueue* m_forwardQueue; void OnIndexBufferInvalidation(const IndexBuffer* indexBuffer); diff --git a/include/Nazara/Graphics/ForwardRenderQueue.hpp b/include/Nazara/Graphics/ForwardRenderQueue.hpp index df3d82a81..3a5d3ef33 100644 --- a/include/Nazara/Graphics/ForwardRenderQueue.hpp +++ b/include/Nazara/Graphics/ForwardRenderQueue.hpp @@ -31,18 +31,18 @@ namespace Nz ForwardRenderQueue() = default; ~ForwardRenderQueue() = default; - void AddBillboard(const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; - void AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; - void AddDrawable(const Drawable* drawable) override; - void AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; - void AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; + void AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos = Vector2f(0.f, 1.f), const Color& color = Color::White) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr = nullptr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr = nullptr) override; + void AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) override; + void AddDrawable(int renderOrder, const Drawable* drawable) override; + void AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) override; + void AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay = nullptr) override; void Clear(bool fully = false); @@ -145,14 +145,22 @@ namespace Nz typedef std::vector TransparentModelContainer; - BatchedBillboardContainer billboards; - BasicSpriteBatches basicSprites; - ModelBatches opaqueModels; - TransparentModelContainer transparentModels; - std::vector transparentModelData; - std::vector otherDrawables; + struct Layer + { + BatchedBillboardContainer billboards; + BasicSpriteBatches basicSprites; + ModelBatches opaqueModels; + TransparentModelContainer transparentModels; + std::vector transparentModelData; + std::vector otherDrawables; + unsigned int clearCount = 0; + }; + + std::map layers; private: + Layer& GetLayer(int i); ///TODO: Inline + void OnIndexBufferInvalidation(const IndexBuffer* indexBuffer); void OnMaterialInvalidation(const Material* material); void OnTextureInvalidation(const Texture* texture); diff --git a/include/Nazara/Graphics/ForwardRenderTechnique.hpp b/include/Nazara/Graphics/ForwardRenderTechnique.hpp index 855eb9461..920a6c0bd 100644 --- a/include/Nazara/Graphics/ForwardRenderTechnique.hpp +++ b/include/Nazara/Graphics/ForwardRenderTechnique.hpp @@ -39,10 +39,10 @@ namespace Nz struct ShaderUniforms; void ChooseLights(const Spheref& object, bool includeDirectionalLights = true) const; - void DrawBasicSprites(const SceneData& sceneData) const; - void DrawBillboards(const SceneData& sceneData) const; - void DrawOpaqueModels(const SceneData& sceneData) const; - void DrawTransparentModels(const SceneData& sceneData) const; + void DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; + void DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; + void DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; + void DrawTransparentModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const; const ShaderUniforms* GetShaderUniforms(const Shader* shader) const; void OnShaderInvalidated(const Shader* shader) const; void SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset) const; diff --git a/include/Nazara/Graphics/InstancedRenderable.hpp b/include/Nazara/Graphics/InstancedRenderable.hpp index f3f17d866..561cc4c97 100644 --- a/include/Nazara/Graphics/InstancedRenderable.hpp +++ b/include/Nazara/Graphics/InstancedRenderable.hpp @@ -64,6 +64,7 @@ namespace Nz BoundingVolumef volume; Matrix4f& transformMatrix; UInt32 flags; + int renderOrder; }; protected: diff --git a/src/Nazara/Graphics/Billboard.cpp b/src/Nazara/Graphics/Billboard.cpp index 1e9de412c..3e5173c89 100644 --- a/src/Nazara/Graphics/Billboard.cpp +++ b/src/Nazara/Graphics/Billboard.cpp @@ -17,7 +17,7 @@ namespace Nz if (!m_material) return; - renderQueue->AddBillboard(m_material, instanceData.transformMatrix.GetTranslation(), m_size, m_sinCos, m_color); + renderQueue->AddBillboard(instanceData.renderOrder, m_material, instanceData.transformMatrix.GetTranslation(), m_size, m_sinCos, m_color); } void Billboard::MakeBoundingVolume() const diff --git a/src/Nazara/Graphics/DeferredGeometryPass.cpp b/src/Nazara/Graphics/DeferredGeometryPass.cpp index 3781cd23f..2ae39ed9b 100644 --- a/src/Nazara/Graphics/DeferredGeometryPass.cpp +++ b/src/Nazara/Graphics/DeferredGeometryPass.cpp @@ -54,118 +54,123 @@ namespace Nz const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; - for (auto& matIt : m_renderQueue->opaqueModels) + for (auto& pair : m_renderQueue->layers) { - auto& matEntry = matIt.second; + DeferredRenderQueue::Layer& layer = pair.second; - if (matEntry.enabled) + for (auto& matIt : layer.opaqueModels) { - DeferredRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; + auto& matEntry = matIt.second; - if (!meshInstances.empty()) + if (matEntry.enabled) { - const Material* material = matIt.first; + DeferredRenderQueue::MeshInstanceContainer& meshInstances = matEntry.meshMap; - bool useInstancing = instancingEnabled && matEntry.instancingEnabled; - - // On commence par récupérer le programme du matériau - UInt32 flags = ShaderFlags_Deferred; - if (useInstancing) - flags |= ShaderFlags_Instancing; - - const Shader* shader = material->Apply(flags); - - // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas - if (shader != lastShader) + if (!meshInstances.empty()) { - // Index des uniformes dans le shader - shaderUniforms = GetShaderUniforms(shader); + const Material* material = matIt.first; - // Couleur ambiante de la scène - shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); - // Position de la caméra - shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); + bool useInstancing = instancingEnabled && matEntry.instancingEnabled; - lastShader = shader; - } + // On commence par récupérer le programme du matériau + UInt32 flags = ShaderFlags_Deferred; + if (useInstancing) + flags |= ShaderFlags_Instancing; - // Meshes - for (auto& meshIt : meshInstances) - { - const MeshData& meshData = meshIt.first; - auto& meshEntry = meshIt.second; + const Shader* shader = material->Apply(flags); - std::vector& instances = meshEntry.instances; - if (!instances.empty()) + // Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas + if (shader != lastShader) { - const IndexBuffer* indexBuffer = meshData.indexBuffer; - const VertexBuffer* vertexBuffer = meshData.vertexBuffer; + // Index des uniformes dans le shader + shaderUniforms = GetShaderUniforms(shader); - // Gestion du draw call avant la boucle de rendu - Renderer::DrawCall drawFunc; - Renderer::DrawCallInstanced instancedDrawFunc; - unsigned int indexCount; + // Couleur ambiante de la scène + shader->SendColor(shaderUniforms->sceneAmbient, sceneData.ambientColor); + // Position de la caméra + shader->SendVector(shaderUniforms->eyePosition, sceneData.viewer->GetEyePosition()); - if (indexBuffer) + lastShader = shader; + } + + // Meshes + for (auto& meshIt : meshInstances) + { + const MeshData& meshData = meshIt.first; + auto& meshEntry = meshIt.second; + + std::vector& instances = meshEntry.instances; + if (!instances.empty()) { - drawFunc = Renderer::DrawIndexedPrimitives; - instancedDrawFunc = Renderer::DrawIndexedPrimitivesInstanced; - indexCount = indexBuffer->GetIndexCount(); - } - else - { - drawFunc = Renderer::DrawPrimitives; - instancedDrawFunc = Renderer::DrawPrimitivesInstanced; - indexCount = vertexBuffer->GetVertexCount(); - } + const IndexBuffer* indexBuffer = meshData.indexBuffer; + const VertexBuffer* vertexBuffer = meshData.vertexBuffer; - Renderer::SetIndexBuffer(indexBuffer); - Renderer::SetVertexBuffer(vertexBuffer); + // Gestion du draw call avant la boucle de rendu + Renderer::DrawCall drawFunc; + Renderer::DrawCallInstanced instancedDrawFunc; + unsigned int indexCount; - if (useInstancing) - { - // On récupère le buffer d'instancing du Renderer et on le configure pour fonctionner avec des matrices - VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); - instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4)); - - const Matrix4f* instanceMatrices = &instances[0]; - unsigned int instanceCount = instances.size(); - unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre de matrices que peut contenir le buffer - - while (instanceCount > 0) + if (indexBuffer) { - // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) - unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); - instanceCount -= renderedInstanceCount; - - // On remplit l'instancing buffer avec nos matrices world - instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); - instanceMatrices += renderedInstanceCount; - - // Et on affiche - instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + drawFunc = Renderer::DrawIndexedPrimitives; + instancedDrawFunc = Renderer::DrawIndexedPrimitivesInstanced; + indexCount = indexBuffer->GetIndexCount(); } - } - else - { - // Sans instancing, on doit effectuer un draw call pour chaque instance - // Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances - // À cause du temps de modification du buffer d'instancing - for (const Matrix4f& matrix : instances) + else { - Renderer::SetMatrix(MatrixType_World, matrix); - drawFunc(meshData.primitiveMode, 0, indexCount); + drawFunc = Renderer::DrawPrimitives; + instancedDrawFunc = Renderer::DrawPrimitivesInstanced; + indexCount = vertexBuffer->GetVertexCount(); } - } - instances.clear(); + Renderer::SetIndexBuffer(indexBuffer); + Renderer::SetVertexBuffer(vertexBuffer); + + if (useInstancing) + { + // On récupère le buffer d'instancing du Renderer et on le configure pour fonctionner avec des matrices + VertexBuffer* instanceBuffer = Renderer::GetInstanceBuffer(); + instanceBuffer->SetVertexDeclaration(VertexDeclaration::Get(VertexLayout_Matrix4)); + + const Matrix4f* instanceMatrices = &instances[0]; + unsigned int instanceCount = instances.size(); + unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre de matrices que peut contenir le buffer + + while (instanceCount > 0) + { + // On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing) + unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount); + instanceCount -= renderedInstanceCount; + + // On remplit l'instancing buffer avec nos matrices world + instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true); + instanceMatrices += renderedInstanceCount; + + // Et on affiche + instancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount); + } + } + else + { + // Sans instancing, on doit effectuer un draw call pour chaque instance + // Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances + // À cause du temps de modification du buffer d'instancing + for (const Matrix4f& matrix : instances) + { + Renderer::SetMatrix(MatrixType_World, matrix); + drawFunc(meshData.primitiveMode, 0, indexCount); + } + } + + instances.clear(); + } } } - } - // Et on remet à zéro les données - matEntry.enabled = false; - matEntry.instancingEnabled = false; + // Et on remet à zéro les données + matEntry.enabled = false; + matEntry.instancingEnabled = false; + } } } diff --git a/src/Nazara/Graphics/DeferredRenderQueue.cpp b/src/Nazara/Graphics/DeferredRenderQueue.cpp index 0e4512cdd..5bd0931e3 100644 --- a/src/Nazara/Graphics/DeferredRenderQueue.cpp +++ b/src/Nazara/Graphics/DeferredRenderQueue.cpp @@ -17,63 +17,66 @@ namespace Nz { } - void DeferredRenderQueue::AddBillboard(const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) + void DeferredRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) { - m_forwardQueue->AddBillboard(material, position, size, sinCos, color); + m_forwardQueue->AddBillboard(renderOrder, material, position, size, sinCos, color); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, colorPtr); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, alphaPtr); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, colorPtr); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, colorPtr); } - void DeferredRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + void DeferredRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) { - m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr); + m_forwardQueue->AddBillboards(renderOrder, material, count, positionPtr, sizePtr, anglePtr, alphaPtr); } - void DeferredRenderQueue::AddDrawable(const Drawable* drawable) + void DeferredRenderQueue::AddDrawable(int renderOrder, const Drawable* drawable) { - m_forwardQueue->AddDrawable(drawable); + m_forwardQueue->AddDrawable(renderOrder, drawable); } - void DeferredRenderQueue::AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) + void DeferredRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) { if (material->IsEnabled(RendererParameter_Blend)) // Un matériau transparent ? J'aime pas, va voir dans la forward queue si j'y suis - m_forwardQueue->AddMesh(material, meshData, meshAABB, transformMatrix); + m_forwardQueue->AddMesh(renderOrder, material, meshData, meshAABB, transformMatrix); else { + Layer& currentLayer = GetLayer(renderOrder); + auto& opaqueModels = currentLayer.opaqueModels; + auto it = opaqueModels.find(material); if (it == opaqueModels.end()) { @@ -110,9 +113,9 @@ namespace Nz } } - void DeferredRenderQueue::AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) + void DeferredRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) { - m_forwardQueue->AddSprites(material, vertices, spriteCount, overlay); + m_forwardQueue->AddSprites(renderOrder, material, vertices, spriteCount, overlay); } void DeferredRenderQueue::Clear(bool fully) @@ -120,44 +123,80 @@ namespace Nz AbstractRenderQueue::Clear(fully); if (fully) - opaqueModels.clear(); + layers.clear(); + else + { + for (auto it = layers.begin(); it != layers.end(); ++it) + { + Layer& layer = it->second; + if (layer.clearCount++ >= 100) + it = layers.erase(it); + } + } m_forwardQueue->Clear(fully); } + DeferredRenderQueue::Layer& DeferredRenderQueue::GetLayer(unsigned int i) + { + auto it = layers.find(i); + if (it == layers.end()) + it = layers.insert(std::make_pair(i, Layer())).first; + + Layer& layer = it->second; + layer.clearCount = 0; + + return layer; + } + void DeferredRenderQueue::OnIndexBufferInvalidation(const IndexBuffer* indexBuffer) { - for (auto& modelPair : opaqueModels) + for (auto& pair : layers) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + Layer& layer = pair.second; + + for (auto& modelPair : layer.opaqueModels) { - const MeshData& renderData = it->first; - if (renderData.indexBuffer == indexBuffer) - it = meshes.erase(it); - else - ++it; + MeshInstanceContainer& meshes = modelPair.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.indexBuffer == indexBuffer) + it = meshes.erase(it); + else + ++it; + } } } } void DeferredRenderQueue::OnMaterialInvalidation(const Material* material) { - opaqueModels.erase(material); + for (auto& pair : layers) + { + Layer& layer = pair.second; + + layer.opaqueModels.erase(material); + } } void DeferredRenderQueue::OnVertexBufferInvalidation(const VertexBuffer* vertexBuffer) { - for (auto& modelPair : opaqueModels) + for (auto& pair : layers) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + Layer& layer = pair.second; + + for (auto& modelPair : layer.opaqueModels) { - const MeshData& renderData = it->first; - if (renderData.vertexBuffer == vertexBuffer) - it = meshes.erase(it); - else - ++it; + MeshInstanceContainer& meshes = modelPair.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.vertexBuffer == vertexBuffer) + it = meshes.erase(it); + else + ++it; + } } } } diff --git a/src/Nazara/Graphics/ForwardRenderQueue.cpp b/src/Nazara/Graphics/ForwardRenderQueue.cpp index a6cb47ba1..d9527a646 100644 --- a/src/Nazara/Graphics/ForwardRenderQueue.cpp +++ b/src/Nazara/Graphics/ForwardRenderQueue.cpp @@ -11,10 +11,12 @@ namespace Nz { - void ForwardRenderQueue::AddBillboard(const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) + void ForwardRenderQueue::AddBillboard(int renderOrder, const Material* material, const Vector3f& position, const Vector2f& size, const Vector2f& sinCos, const Color& color) { NazaraAssert(material, "Invalid material"); + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -30,7 +32,7 @@ namespace Nz billboardVector.push_back(BillboardData{color, position, size, sinCos}); } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); @@ -43,6 +45,8 @@ namespace Nz if (!colorPtr) colorPtr.Reset(&Color::White, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -69,7 +73,7 @@ namespace Nz } } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); @@ -84,6 +88,8 @@ namespace Nz if (!alphaPtr) alphaPtr.Reset(&defaultAlpha, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -110,7 +116,7 @@ namespace Nz } } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); @@ -123,6 +129,8 @@ namespace Nz if (!colorPtr) colorPtr.Reset(&Color::White, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -153,7 +161,7 @@ namespace Nz } } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); @@ -168,6 +176,8 @@ namespace Nz if (!alphaPtr) alphaPtr.Reset(&defaultAlpha, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -198,7 +208,7 @@ namespace Nz } } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); @@ -211,6 +221,8 @@ namespace Nz if (!colorPtr) colorPtr.Reset(&Color::White, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -237,7 +249,7 @@ namespace Nz } } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr sinCosPtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); @@ -252,6 +264,8 @@ namespace Nz if (!alphaPtr) alphaPtr.Reset(&defaultAlpha, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -278,7 +292,7 @@ namespace Nz } } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr colorPtr) { NazaraAssert(material, "Invalid material"); @@ -291,6 +305,8 @@ namespace Nz if (!colorPtr) colorPtr.Reset(&Color::White, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -321,7 +337,7 @@ namespace Nz } } - void ForwardRenderQueue::AddBillboards(const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) + void ForwardRenderQueue::AddBillboards(int renderOrder, const Material* material, unsigned int count, SparsePtr positionPtr, SparsePtr sizePtr, SparsePtr anglePtr, SparsePtr alphaPtr) { NazaraAssert(material, "Invalid material"); @@ -336,6 +352,8 @@ namespace Nz if (!alphaPtr) alphaPtr.Reset(&defaultAlpha, 0); // Pareil + auto& billboards = GetLayer(renderOrder).billboards; + auto it = billboards.find(material); if (it == billboards.end()) { @@ -366,7 +384,7 @@ namespace Nz } } - void ForwardRenderQueue::AddDrawable(const Drawable* drawable) + void ForwardRenderQueue::AddDrawable(int renderOrder, const Drawable* drawable) { #if NAZARA_GRAPHICS_SAFE if (!drawable) @@ -376,13 +394,19 @@ namespace Nz } #endif + auto& otherDrawables = GetLayer(renderOrder).otherDrawables; + otherDrawables.push_back(drawable); } - void ForwardRenderQueue::AddMesh(const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) + void ForwardRenderQueue::AddMesh(int renderOrder, const Material* material, const MeshData& meshData, const Boxf& meshAABB, const Matrix4f& transformMatrix) { if (material->IsEnabled(RendererParameter_Blend)) { + Layer& currentLayer = GetLayer(renderOrder); + auto& transparentModels = currentLayer.transparentModels; + auto& transparentModelData = currentLayer.transparentModelData; + // Le matériau est transparent, nous devons rendre ce mesh d'une autre façon (après le rendu des objets opaques et en les triant) unsigned int index = transparentModelData.size(); transparentModelData.resize(index+1); @@ -397,6 +421,9 @@ namespace Nz } else { + Layer& currentLayer = GetLayer(renderOrder); + auto& opaqueModels = currentLayer.opaqueModels; + auto it = opaqueModels.find(material); if (it == opaqueModels.end()) { @@ -434,8 +461,11 @@ namespace Nz } } - void ForwardRenderQueue::AddSprites(const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) + void ForwardRenderQueue::AddSprites(int renderOrder, const Material* material, const VertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const Texture* overlay) { + Layer& currentLayer = GetLayer(renderOrder); + auto& basicSprites = currentLayer.basicSprites; + auto matIt = basicSprites.find(material); if (matIt == basicSprites.end()) { @@ -468,15 +498,22 @@ namespace Nz { AbstractRenderQueue::Clear(fully); - otherDrawables.clear(); - transparentModels.clear(); - transparentModelData.clear(); - if (fully) + layers.clear(); + else { - basicSprites.clear(); - billboards.clear(); - opaqueModels.clear(); + for (auto it = layers.begin(); it != layers.end(); ++it) + { + Layer& layer = it->second; + if (layer.clearCount++ >= 100) + it = layers.erase(it); + else + { + layer.otherDrawables.clear(); + layer.transparentModels.clear(); + layer.transparentModelData.clear(); + } + } } } @@ -486,78 +523,113 @@ namespace Nz Vector3f viewerPos = viewer->GetEyePosition(); Vector3f viewerNormal = viewer->GetForward(); - std::sort(transparentModels.begin(), transparentModels.end(), [this, &nearPlane, &viewerNormal](unsigned int index1, unsigned int index2) + for (auto& pair : layers) { - const Spheref& sphere1 = transparentModelData[index1].squaredBoundingSphere; - const Spheref& sphere2 = transparentModelData[index2].squaredBoundingSphere; + Layer& layer = pair.second; - Vector3f position1 = sphere1.GetNegativeVertex(viewerNormal); - Vector3f position2 = sphere2.GetNegativeVertex(viewerNormal); - - return nearPlane.Distance(position1) > nearPlane.Distance(position2); - }); - - for (auto& pair : billboards) - { - const Material* mat = pair.first; - - if (mat->IsDepthSortingEnabled()) + std::sort(layer.transparentModels.begin(), layer.transparentModels.end(), [&layer, &nearPlane, &viewerNormal] (unsigned int index1, unsigned int index2) { - BatchedBillboardEntry& entry = pair.second; - auto& billboardVector = entry.billboards; + const Spheref& sphere1 = layer.transparentModelData[index1].squaredBoundingSphere; + const Spheref& sphere2 = layer.transparentModelData[index2].squaredBoundingSphere; - std::sort(billboardVector.begin(), billboardVector.end(), [&viewerPos](const BillboardData& data1, const BillboardData& data2) + Vector3f position1 = sphere1.GetNegativeVertex(viewerNormal); + Vector3f position2 = sphere2.GetNegativeVertex(viewerNormal); + + return nearPlane.Distance(position1) > nearPlane.Distance(position2); + }); + + for (auto& pair : layer.billboards) + { + const Material* mat = pair.first; + + if (mat->IsDepthSortingEnabled()) { - return viewerPos.SquaredDistance(data1.center) > viewerPos.SquaredDistance(data2.center); - }); + BatchedBillboardEntry& entry = pair.second; + auto& billboardVector = entry.billboards; + + std::sort(billboardVector.begin(), billboardVector.end(), [&viewerPos] (const BillboardData& data1, const BillboardData& data2) + { + return viewerPos.SquaredDistance(data1.center) > viewerPos.SquaredDistance(data2.center); + }); + } } } } + ForwardRenderQueue::Layer& ForwardRenderQueue::GetLayer(int i) + { + auto it = layers.find(i); + if (it == layers.end()) + it = layers.insert(std::make_pair(i, Layer())).first; + + Layer& layer = it->second; + layer.clearCount = 0; + + return layer; + } + void ForwardRenderQueue::OnIndexBufferInvalidation(const IndexBuffer* indexBuffer) { - for (auto& modelPair : opaqueModels) + for (auto& pair : layers) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + Layer& layer = pair.second; + + for (auto& modelPair : layer.opaqueModels) { - const MeshData& renderData = it->first; - if (renderData.indexBuffer == indexBuffer) - it = meshes.erase(it); - else - ++it; + MeshInstanceContainer& meshes = modelPair.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.indexBuffer == indexBuffer) + it = meshes.erase(it); + else + ++it; + } } } } void ForwardRenderQueue::OnMaterialInvalidation(const Material* material) { - basicSprites.erase(material); - billboards.erase(material); - opaqueModels.erase(material); + for (auto& pair : layers) + { + Layer& layer = pair.second; + + layer.basicSprites.erase(material); + layer.billboards.erase(material); + layer.opaqueModels.erase(material); + } } void ForwardRenderQueue::OnTextureInvalidation(const Texture* texture) { - for (auto matIt = basicSprites.begin(); matIt != basicSprites.end(); ++matIt) + for (auto& pair : layers) { - auto& overlayMap = matIt->second.overlayMap; - overlayMap.erase(texture); + Layer& layer = pair.second; + for (auto matIt = layer.basicSprites.begin(); matIt != layer.basicSprites.end(); ++matIt) + { + auto& overlayMap = matIt->second.overlayMap; + overlayMap.erase(texture); + } } } void ForwardRenderQueue::OnVertexBufferInvalidation(const VertexBuffer* vertexBuffer) { - for (auto& modelPair : opaqueModels) + for (auto& pair : layers) { - MeshInstanceContainer& meshes = modelPair.second.meshMap; - for (auto it = meshes.begin(); it != meshes.end();) + Layer& layer = pair.second; + for (auto& modelPair : layer.opaqueModels) { - const MeshData& renderData = it->first; - if (renderData.vertexBuffer == vertexBuffer) - it = meshes.erase(it); - else - ++it; + MeshInstanceContainer& meshes = modelPair.second.meshMap; + for (auto it = meshes.begin(); it != meshes.end();) + { + const MeshData& renderData = it->first; + if (renderData.vertexBuffer == vertexBuffer) + it = meshes.erase(it); + else + ++it; + } } } } diff --git a/src/Nazara/Graphics/ForwardRenderTechnique.cpp b/src/Nazara/Graphics/ForwardRenderTechnique.cpp index 6eeb41575..2db03b7f9 100644 --- a/src/Nazara/Graphics/ForwardRenderTechnique.cpp +++ b/src/Nazara/Graphics/ForwardRenderTechnique.cpp @@ -62,21 +62,25 @@ namespace Nz if (sceneData.background) sceneData.background->Draw(sceneData.viewer); - if (!m_renderQueue.opaqueModels.empty()) - DrawOpaqueModels(sceneData); + for (auto& pair : m_renderQueue.layers) + { + ForwardRenderQueue::Layer& layer = pair.second; - if (!m_renderQueue.transparentModels.empty()) - DrawTransparentModels(sceneData); + if (!layer.opaqueModels.empty()) + DrawOpaqueModels(sceneData, layer); - if (!m_renderQueue.basicSprites.empty()) - DrawBasicSprites(sceneData); + if (!layer.transparentModels.empty()) + DrawTransparentModels(sceneData, layer); - if (!m_renderQueue.billboards.empty()) - DrawBillboards(sceneData); + if (!layer.basicSprites.empty()) + DrawBasicSprites(sceneData, layer); - // Les autres drawables (Exemple: Terrain) - for (const Drawable* drawable : m_renderQueue.otherDrawables) - drawable->Draw(); + if (!layer.billboards.empty()) + DrawBillboards(sceneData, layer); + + for (const Drawable* drawable : layer.otherDrawables) + drawable->Draw(); + } return true; } @@ -203,7 +207,7 @@ namespace Nz }); } - void ForwardRenderTechnique::DrawBasicSprites(const SceneData& sceneData) const + void ForwardRenderTechnique::DrawBasicSprites(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -214,7 +218,7 @@ namespace Nz Renderer::SetMatrix(MatrixType_World, Matrix4f::Identity()); Renderer::SetVertexBuffer(&m_spriteBuffer); - for (auto& matIt : m_renderQueue.basicSprites) + for (auto& matIt : layer.basicSprites) { const Material* material = matIt.first; auto& matEntry = matIt.second; @@ -309,7 +313,7 @@ namespace Nz } } - void ForwardRenderTechnique::DrawBillboards(const SceneData& sceneData) const + void ForwardRenderTechnique::DrawBillboards(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -323,7 +327,7 @@ namespace Nz Renderer::SetVertexBuffer(&s_quadVertexBuffer); - for (auto& matIt : m_renderQueue.billboards) + for (auto& matIt : layer.billboards) { const Material* material = matIt.first; auto& entry = matIt.second; @@ -372,7 +376,7 @@ namespace Nz Renderer::SetIndexBuffer(&s_quadIndexBuffer); Renderer::SetVertexBuffer(&m_billboardPointBuffer); - for (auto& matIt : m_renderQueue.billboards) + for (auto& matIt : layer.billboards) { const Material* material = matIt.first; auto& entry = matIt.second; @@ -454,14 +458,14 @@ namespace Nz } } - void ForwardRenderTechnique::DrawOpaqueModels(const SceneData& sceneData) const + void ForwardRenderTechnique::DrawOpaqueModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); const Shader* lastShader = nullptr; const ShaderUniforms* shaderUniforms = nullptr; - for (auto& matIt : m_renderQueue.opaqueModels) + for (auto& matIt : layer.opaqueModels) { auto& matEntry = matIt.second; @@ -657,7 +661,7 @@ namespace Nz } } - void ForwardRenderTechnique::DrawTransparentModels(const SceneData& sceneData) const + void ForwardRenderTechnique::DrawTransparentModels(const SceneData& sceneData, ForwardRenderQueue::Layer& layer) const { NazaraAssert(sceneData.viewer, "Invalid viewer"); @@ -665,9 +669,9 @@ namespace Nz const ShaderUniforms* shaderUniforms = nullptr; unsigned int lightCount = 0; - for (unsigned int index : m_renderQueue.transparentModels) + for (unsigned int index : layer.transparentModels) { - const ForwardRenderQueue::TransparentModelData& modelData = m_renderQueue.transparentModelData[index]; + const ForwardRenderQueue::TransparentModelData& modelData = layer.transparentModelData[index]; // Matériau const Material* material = modelData.material; diff --git a/src/Nazara/Graphics/Model.cpp b/src/Nazara/Graphics/Model.cpp index 954f3ff01..e8954a886 100644 --- a/src/Nazara/Graphics/Model.cpp +++ b/src/Nazara/Graphics/Model.cpp @@ -50,7 +50,7 @@ namespace Nz meshData.primitiveMode = mesh->GetPrimitiveMode(); meshData.vertexBuffer = mesh->GetVertexBuffer(); - renderQueue->AddMesh(material, meshData, mesh->GetAABB(), instanceData.transformMatrix); + renderQueue->AddMesh(instanceData.renderOrder, material, meshData, mesh->GetAABB(), instanceData.transformMatrix); } } diff --git a/src/Nazara/Graphics/SkeletalModel.cpp b/src/Nazara/Graphics/SkeletalModel.cpp index 97889764d..12bf10b6d 100644 --- a/src/Nazara/Graphics/SkeletalModel.cpp +++ b/src/Nazara/Graphics/SkeletalModel.cpp @@ -47,7 +47,7 @@ namespace Nz meshData.primitiveMode = mesh->GetPrimitiveMode(); meshData.vertexBuffer = SkinningManager::GetBuffer(mesh, &m_skeleton); - renderQueue->AddMesh(material, meshData, m_skeleton.GetAABB(), instanceData.transformMatrix); + renderQueue->AddMesh(instanceData.renderOrder, material, meshData, m_skeleton.GetAABB(), instanceData.transformMatrix); } } diff --git a/src/Nazara/Graphics/Sprite.cpp b/src/Nazara/Graphics/Sprite.cpp index 33a27d1a6..970254294 100644 --- a/src/Nazara/Graphics/Sprite.cpp +++ b/src/Nazara/Graphics/Sprite.cpp @@ -17,7 +17,7 @@ namespace Nz return; const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); - renderQueue->AddSprites(m_material, vertices, 1); + renderQueue->AddSprites(instanceData.renderOrder, m_material, vertices, 1); } void Sprite::MakeBoundingVolume() const diff --git a/src/Nazara/Graphics/TextSprite.cpp b/src/Nazara/Graphics/TextSprite.cpp index b746756d9..4ea284a42 100644 --- a/src/Nazara/Graphics/TextSprite.cpp +++ b/src/Nazara/Graphics/TextSprite.cpp @@ -26,7 +26,7 @@ namespace Nz if (indices.count > 0) { const VertexStruct_XYZ_Color_UV* vertices = reinterpret_cast(instanceData.data.data()); - renderQueue->AddSprites(m_material, &vertices[indices.first*4], indices.count, overlay); + renderQueue->AddSprites(instanceData.renderOrder, m_material, &vertices[indices.first*4], indices.count, overlay); } } } From 6bc285cb00c34061941144782fb5aa8c219a8a19 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 28 Nov 2015 02:07:56 +0100 Subject: [PATCH 85/97] Fix compilation for GCC Former-commit-id: 7c51c59904fa86f952b704d175b09b32640d9395 --- include/Nazara/Core/Algorithm.inl | 7 ++++--- include/Nazara/Math/Vector3.inl | 2 +- src/Nazara/Core/Stream.cpp | 1 + 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/include/Nazara/Core/Algorithm.inl b/include/Nazara/Core/Algorithm.inl index 2e9661dd9..7c117e626 100644 --- a/include/Nazara/Core/Algorithm.inl +++ b/include/Nazara/Core/Algorithm.inl @@ -7,6 +7,7 @@ // Merci aussi à Freedom de siteduzero.com #include +#include #include #include #include @@ -45,17 +46,17 @@ namespace Nz return Detail::ApplyImplMethod(object, std::forward(fn), std::forward(t), std::make_index_sequence()); } - template + template ByteArray ComputeHash(HashType hash, const T& v) { return ComputeHash(AbstractHash::Get(hash).get(), v); } - template + template ByteArray ComputeHash(AbstractHash* hash, const T& v) { hash->Begin(); - + HashAppend(hash, v); return hash->End(); diff --git a/include/Nazara/Math/Vector3.inl b/include/Nazara/Math/Vector3.inl index 0626cb8eb..9a04ad97b 100644 --- a/include/Nazara/Math/Vector3.inl +++ b/include/Nazara/Math/Vector3.inl @@ -115,7 +115,7 @@ namespace Nz template float Vector3::GetLengthf() const { - return std::sqrt(static_cast(GetSquaredLength())); + return std::sqrt(static_cast(GetSquaredLength())); } template diff --git a/src/Nazara/Core/Stream.cpp b/src/Nazara/Core/Stream.cpp index 78760ccea..f8aab413e 100644 --- a/src/Nazara/Core/Stream.cpp +++ b/src/Nazara/Core/Stream.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include namespace Nz From 89156199344d43e94c9c9b862150ec1cef36e949 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 28 Nov 2015 02:51:42 +0100 Subject: [PATCH 86/97] Lua: Add automatic method binding Former-commit-id: fccd5f3682f6581db6b6b5976f4d0d3e0afa324c --- include/Nazara/Lua/LuaClass.hpp | 16 ++-- include/Nazara/Lua/LuaClass.inl | 39 ++++++++ include/Nazara/Lua/LuaInstance.hpp | 2 + include/Nazara/Lua/LuaInstance.inl | 143 ++++++++++++++++++++++++----- 4 files changed, 169 insertions(+), 31 deletions(-) diff --git a/include/Nazara/Lua/LuaClass.hpp b/include/Nazara/Lua/LuaClass.hpp index 4f47f36f1..96e271a31 100644 --- a/include/Nazara/Lua/LuaClass.hpp +++ b/include/Nazara/Lua/LuaClass.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include //#include @@ -22,12 +23,12 @@ namespace Nz //static_assert(std::is_same::value || std::is_base_of::value, "P must be a base of T"); public: - using ClassFunc = int (*)(LuaInstance& lua, T& instance); - using ClassIndexFunc = bool (*)(LuaInstance& lua, T& instance); - using ConstructorFunc = T* (*)(LuaInstance& lua); - using FinalizerFunc = bool (*)(LuaInstance& lua, T& instance); - using StaticIndexFunc = bool (*)(LuaInstance& lua); - using StaticFunc = int (*)(LuaInstance& lua); + using ClassFunc = std::function; + using ClassIndexFunc = std::function; + using ConstructorFunc = std::function; + using FinalizerFunc = std::function; + using StaticIndexFunc = std::function; + using StaticFunc = std::function; LuaClass(const String& name); @@ -41,9 +42,12 @@ namespace Nz void SetFinalizer(FinalizerFunc finalizer); void SetGetter(ClassIndexFunc getter); void SetMethod(const String& name, ClassFunc method); + template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...)); + template std::enable_if_t::value> SetMethod(const String& name, R(P::*func)(Args...) const); void SetSetter(ClassIndexFunc setter); void SetStaticGetter(StaticIndexFunc getter); void SetStaticMethod(const String& name, StaticFunc func); + template void SetStaticMethod(const String& name, R(*func)(Args...)); void SetStaticSetter(StaticIndexFunc getter); private: diff --git a/include/Nazara/Lua/LuaClass.inl b/include/Nazara/Lua/LuaClass.inl index 9fa445ffa..545fa08ba 100644 --- a/include/Nazara/Lua/LuaClass.inl +++ b/include/Nazara/Lua/LuaClass.inl @@ -174,6 +174,32 @@ namespace Nz { m_methods[name] = method; } + + template + template + std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...)) + { + SetMethod(name, [func] (LuaInstance& instance, T& object) -> int + { + LuaImplMethodProxy handler(instance, object); + handler.ProcessArgs(); + + return handler.Invoke(func); + }); + } + + template + template + std::enable_if_t::value> LuaClass::SetMethod(const String& name, R(P::*func)(Args...) const) + { + SetMethod(name, [func] (LuaInstance& instance, T& object) -> int + { + LuaImplMethodProxy handler(instance, object); + handler.ProcessArgs(); + + return handler.Invoke(func); + }); + } template void LuaClass::SetSetter(ClassIndexFunc setter) @@ -193,6 +219,19 @@ namespace Nz m_staticMethods[name] = method; } + template + template + void LuaClass::SetStaticMethod(const String& name, R(*func)(Args...)) + { + SetStaticMethod(name, [func] (LuaInstance& instance) -> int + { + LuaImplFunctionProxy handler(instance); + handler.ProcessArgs(); + + return handler.Invoke(func); + }); + } + template void LuaClass::SetStaticSetter(StaticIndexFunc setter) { diff --git a/include/Nazara/Lua/LuaInstance.hpp b/include/Nazara/Lua/LuaInstance.hpp index 24e9a4f7d..1124ce72a 100644 --- a/include/Nazara/Lua/LuaInstance.hpp +++ b/include/Nazara/Lua/LuaInstance.hpp @@ -42,6 +42,7 @@ namespace Nz bool Call(unsigned int argCount); bool Call(unsigned int argCount, unsigned int resultCount); + template T Check(int index); void CheckAny(int index) const; bool CheckBoolean(int index) const; bool CheckBoolean(int index, bool defValue) const; @@ -110,6 +111,7 @@ namespace Nz void Pop(unsigned int n = 1U); + template int Push(T arg); void PushBoolean(bool value); void PushCFunction(LuaCFunction func, unsigned int upvalueCount = 0); void PushFunction(LuaFunction func); diff --git a/include/Nazara/Lua/LuaInstance.inl b/include/Nazara/Lua/LuaInstance.inl index beef1fe6d..0274bb0be 100644 --- a/include/Nazara/Lua/LuaInstance.inl +++ b/include/Nazara/Lua/LuaInstance.inl @@ -23,9 +23,22 @@ namespace Nz return static_cast(instance.CheckNumber(index)); } - int LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + template + std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) { - return static_cast(instance.CheckInteger(index)); + return static_cast(LuaImplQueryArg(instance, index, TypeTag::type>())); + } + + template + std::enable_if_t::value && !std::is_unsigned::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + { + return static_cast(instance.CheckInteger(index)); + } + + template + std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) + { + return static_cast(LuaImplQueryArg(instance, index, TypeTag::type>())); } std::string LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) @@ -50,51 +63,62 @@ namespace Nz return LuaImplQueryArg(instance, index, TypeTag()); } - template - std::enable_if_t::value, T> LuaImplQueryArg(LuaInstance& instance, unsigned int index, TypeTag) - { - return static_cast(LuaImplQueryArg(instance, index, TypeTag::type>())); - } - // Function returns - int LuaImplReplyVal(LuaInstance& instance, bool&& val, TypeTag) + int LuaImplReplyVal(LuaInstance& instance, bool val, TypeTag) { instance.PushBoolean(val); return 1; } - int LuaImplReplyVal(LuaInstance& instance, double&& val, TypeTag) + int LuaImplReplyVal(LuaInstance& instance, double val, TypeTag) { instance.PushNumber(val); return 1; } - int LuaImplReplyVal(LuaInstance& instance, float&& val, TypeTag) + int LuaImplReplyVal(LuaInstance& instance, float val, TypeTag) { instance.PushNumber(val); return 1; } - int LuaImplReplyVal(LuaInstance& instance, int&& val, TypeTag) + template + std::enable_if_t::value, int> LuaImplReplyVal(LuaInstance& instance, T val, TypeTag) + { + using EnumT = typename std::underlying_type::type; + + return LuaImplReplyVal(instance, static_cast(val), TypeTag()); + } + + template + std::enable_if_t::value && !std::is_unsigned::value, int> LuaImplReplyVal(LuaInstance& instance, T val, TypeTag) { instance.PushInteger(val); return 1; } - int LuaImplReplyVal(LuaInstance& instance, std::string&& val, TypeTag) + template + std::enable_if_t::value, int> LuaImplReplyVal(LuaInstance& instance, T val, TypeTag) + { + using SignedT = typename std::make_signed::type; + + return LuaImplReplyVal(instance, static_cast(val), TypeTag()); + } + + int LuaImplReplyVal(LuaInstance& instance, std::string val, TypeTag) { instance.PushString(val.c_str(), val.size()); return 1; } - int LuaImplReplyVal(LuaInstance& instance, String&& val, TypeTag) + int LuaImplReplyVal(LuaInstance& instance, String val, TypeTag) { instance.PushString(std::move(val)); return 1; } template - int LuaImplReplyVal(LuaInstance& instance, std::pair&& val, TypeTag>) + int LuaImplReplyVal(LuaInstance& instance, std::pair val, TypeTag>) { int retVal = 0; @@ -104,14 +128,6 @@ namespace Nz return retVal; } - template - std::enable_if_t::value, int> LuaImplReplyVal(LuaInstance& instance, T&& val, TypeTag) - { - using SignedT = typename std::make_signed::type; - - return LuaImplReplyVal(instance, val, TypeTag()); - } - template class LuaImplFunctionProxy { @@ -152,12 +168,89 @@ namespace Nz } private: - LuaInstance& m_instance; std::tuple m_args; + LuaInstance& m_instance; }; + template + class LuaImplMethodProxy + { + public: + LuaImplMethodProxy(LuaInstance& instance, T& object) : + m_instance(instance), + m_object(object) + { + } + + template + void ProcessArgs() + { + } + + template + void ProcessArgs() + { + std::get(m_args) = std::move(LuaImplQueryArg(m_instance, N + 1, TypeTag())); + } + + template + void ProcessArgs() + { + ProcessArgs(); + ProcessArgs(); + } + + void ProcessArgs() + { + ProcessArgs<0, Args...>(); + } + + template + std::enable_if_t::value, int> Invoke(void(P::*func)(Args...)) + { + Apply(m_object, func, m_args); + return 0; + } + + template + std::enable_if_t::value, int> Invoke(Ret(P::*func)(Args...)) + { + return LuaImplReplyVal(m_instance, std::move(Apply(m_object, func, m_args)), TypeTag()); + } + + template + std::enable_if_t::value, int> Invoke(void(P::*func)(Args...) const) + { + Apply(m_object, func, m_args); + return 0; + } + + template + std::enable_if_t::value, int> Invoke(Ret(P::*func)(Args...) const) + { + return LuaImplReplyVal(m_instance, std::move(Apply(m_object, func, m_args)), TypeTag()); + } + + private: + std::tuple m_args; + LuaInstance& m_instance; + T& m_object; + }; + + template + T LuaInstance::Check(int index) + { + return LuaImplQueryArg(*this, index, TypeTag()); + } + + template + int LuaInstance::Push(T arg) + { + return LuaImplReplyVal(*this, std::move(arg), TypeTag()); + } + template - void LuaInstance::PushFunction(R(*func)(Args...)) + void LuaInstance::PushFunction(R (*func)(Args...)) { PushFunction([func](LuaInstance& instance) -> int { From 840c591b6e546d63d9cbbd7b039c288281145243 Mon Sep 17 00:00:00 2001 From: Lynix Date: Sat, 28 Nov 2015 13:53:26 +0100 Subject: [PATCH 87/97] Fix linking problem in United mode Former-commit-id: 6c78f8bb7fba17bda69a622a8028c59d2fadcca2 --- src/Nazara/Network/{Algorithm.cpp => AlgorithmNetwork.cpp} | 0 src/Nazara/Utility/{Algorithm.cpp => AlgorithmUtility.cpp} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename src/Nazara/Network/{Algorithm.cpp => AlgorithmNetwork.cpp} (100%) rename src/Nazara/Utility/{Algorithm.cpp => AlgorithmUtility.cpp} (100%) diff --git a/src/Nazara/Network/Algorithm.cpp b/src/Nazara/Network/AlgorithmNetwork.cpp similarity index 100% rename from src/Nazara/Network/Algorithm.cpp rename to src/Nazara/Network/AlgorithmNetwork.cpp diff --git a/src/Nazara/Utility/Algorithm.cpp b/src/Nazara/Utility/AlgorithmUtility.cpp similarity index 100% rename from src/Nazara/Utility/Algorithm.cpp rename to src/Nazara/Utility/AlgorithmUtility.cpp From 9b0e903e31c371650c30e5458696182912ce27b9 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 30 Nov 2015 12:50:55 +0100 Subject: [PATCH 88/97] Core/Win32: Fix file opening in ReadWrite mode Former-commit-id: 58feae9f282529b8067fae52e81d29bdada154f9 --- src/Nazara/Core/Win32/FileImpl.cpp | 36 +++++++++++------------------- 1 file changed, 13 insertions(+), 23 deletions(-) diff --git a/src/Nazara/Core/Win32/FileImpl.cpp b/src/Nazara/Core/Win32/FileImpl.cpp index 113915c66..8c479c798 100644 --- a/src/Nazara/Core/Win32/FileImpl.cpp +++ b/src/Nazara/Core/Win32/FileImpl.cpp @@ -56,40 +56,30 @@ namespace Nz bool FileImpl::Open(const String& filePath, UInt32 mode) { - DWORD access; + DWORD access = 0; DWORD shareMode = FILE_SHARE_READ; - DWORD openMode; + DWORD openMode = 0; + if (mode & OpenMode_ReadOnly) { - access = GENERIC_READ; - openMode = OPEN_EXISTING; + access |= GENERIC_READ; + + if ((mode & OpenMode_WriteOnly) == 0) + openMode |= OPEN_EXISTING; } - else if (mode & OpenMode_ReadWrite) + + if (mode & OpenMode_WriteOnly) { if (mode & OpenMode_Append) - access = FILE_APPEND_DATA; + access |= FILE_APPEND_DATA; else - access = GENERIC_READ | GENERIC_WRITE; + access |= GENERIC_WRITE; if (mode & OpenMode_Truncate) - openMode = CREATE_ALWAYS; + openMode |= CREATE_ALWAYS; else - openMode = OPEN_ALWAYS; + openMode |= OPEN_ALWAYS; } - else if (mode & OpenMode_WriteOnly) - { - if (mode & OpenMode_Append) - access = FILE_APPEND_DATA; - else - access = GENERIC_WRITE; - - if (mode & OpenMode_Truncate) - openMode = CREATE_ALWAYS; - else - openMode = OPEN_ALWAYS; - } - else - return false; if ((mode & OpenMode_Lock) == 0) shareMode |= FILE_SHARE_WRITE; From 5e8f8549af85eeb81fc2b076b5f1a4e7d783f5ee Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 30 Nov 2015 12:50:56 +0100 Subject: [PATCH 89/97] Core/Posix: Fix file opening in ReadWrite mode Former-commit-id: 7c4a5d3e31e9449fa3c23cfad58523ed54b7834a --- src/Nazara/Core/Posix/FileImpl.cpp | 32 ++++++++++-------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/src/Nazara/Core/Posix/FileImpl.cpp b/src/Nazara/Core/Posix/FileImpl.cpp index d0d0bf7ee..ddd8d4253 100644 --- a/src/Nazara/Core/Posix/FileImpl.cpp +++ b/src/Nazara/Core/Posix/FileImpl.cpp @@ -18,8 +18,8 @@ namespace Nz void FileImpl::Close() { - if (m_fileDescriptor != -1) - close(m_fileDescriptor); + if (m_fileDescriptor != -1) + close(m_fileDescriptor); } bool FileImpl::EndOfFile() const @@ -54,30 +54,20 @@ namespace Nz int flags; mode_t permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - if (mode & OpenMode_ReadOnly) - flags = O_RDONLY; - else if (mode & OpenMode_ReadWrite) - { + if (mode & OpenMode_ReadWrite) flags = O_CREAT | O_RDWR; - - if (mode & OpenMode_Append) - flags |= O_APPEND; - - if (mode & OpenMode_Truncate) - flags |= O_TRUNC; - } + else if (mode & OpenMode_ReadOnly) + flags = O_RDONLY; else if (mode & OpenMode_WriteOnly) - { flags = O_CREAT | O_WRONLY; - - if (mode & OpenMode_Append) - flags |= O_APPEND; - - if (mode & OpenMode_Truncate) - flags |= O_TRUNC; - } else return false; + + if (mode & OpenMode_Append) + flags |= O_APPEND; + + if (mode & OpenMode_Truncate) + flags |= O_TRUNC; ///TODO: lock // if ((mode & OpenMode_Lock) == 0) From 26681b48b727207f9520fc78b4d5895ee5371425 Mon Sep 17 00:00:00 2001 From: Lynix Date: Mon, 30 Nov 2015 18:19:38 +0100 Subject: [PATCH 90/97] Sdk/GraphicsComponent: Fix copy constructor Former-commit-id: 8007e8c374d2c9442bc45b6c911666ba5f3a39b1 --- SDK/include/NDK/Components/GraphicsComponent.inl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDK/include/NDK/Components/GraphicsComponent.inl b/SDK/include/NDK/Components/GraphicsComponent.inl index c571384f8..b51bf94f7 100644 --- a/SDK/include/NDK/Components/GraphicsComponent.inl +++ b/SDK/include/NDK/Components/GraphicsComponent.inl @@ -13,7 +13,7 @@ namespace Ndk { m_renderables.reserve(graphicsComponent.m_renderables.size()); for (const Renderable& r : graphicsComponent.m_renderables) - Attach(r.renderable); + Attach(r.renderable, r.data.renderOrder); } inline void GraphicsComponent::AddToRenderQueue(Nz::AbstractRenderQueue* renderQueue) const From f71886e66d86c0e034bd62f06ccb72f0cefe23cb Mon Sep 17 00:00:00 2001 From: Lynix Date: Tue, 1 Dec 2015 13:40:40 +0100 Subject: [PATCH 91/97] Add Doxygen file Former-commit-id: 2413ae175784c830c88bc282e58d0c4880e70202 --- .gitignore | 3 + Doxyfile | 2458 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 2461 insertions(+) create mode 100644 Doxyfile diff --git a/.gitignore b/.gitignore index 12828f0a7..e029f58b2 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ lib/* # Feature page build/scripts/features/index.html +# Documentation +doc + # Codeblocks build/**/*.cbp build/**/*.cbp diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 000000000..6ab581011 --- /dev/null +++ b/Doxyfile @@ -0,0 +1,2458 @@ +# Doxyfile 1.8.10 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all text +# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv +# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv +# for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +PROJECT_NAME = "Nazara Engine" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +PROJECT_NUMBER = 0.1 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "A fast, complete, cross-platform API designed for game development" + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = LogoMini.png + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where doxygen was started. If +# left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- +# directories (in 2 levels) under the output directory of each output format and +# will distribute the generated files over these directories. Enabling this +# option can be useful when feeding doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise causes +# performance problems for the file system. +# The default value is: NO. + +CREATE_SUBDIRS = NO + +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, +# Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but +# less readable) file names. This can be useful is your file systems doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the +# first line (until the first dot) of a Javadoc-style comment as the brief +# description. If set to NO, the Javadoc-style will behave just like regular Qt- +# style comments (thus requiring an explicit @brief command for a brief +# description.) +# The default value is: NO. + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first +# line (until the first dot) of a Qt-style comment as the brief description. If +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus +# requiring an explicit \brief command for a brief description.) +# The default value is: NO. + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:\n" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". You can put \n's in the value part of an alias to insert +# newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding "class=itcl::class" +# will allow you to use the command class in the itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, +# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: +# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: +# Fortran. In the later case the parser tries to guess whether the code is fixed +# or free formatted code, this is the default for Fortran type files), VHDL. For +# instance to make doxygen treat .inc files as Fortran files (default is PHP), +# and .f files as C (default is Fortran), use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you can +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When enabled doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen +# will parse them like normal C++ but will assume all classes use public instead +# of private inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend +# (class|struct|union) declarations. If set to NO, these declarations will be +# included in the documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file +# names in lower-case letters. If set to YES, upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. +# The default value is: system dependent. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. +# +# Note that if you run doxygen from a directory containing a file called +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some parameters +# in a documented function, or documenting parameters that don't exist or using +# markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, doxygen will only warn about wrong or incomplete +# parameter documentation, but not about the absence of documentation. +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +INPUT = include \ + src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: http://www.gnu.org/software/libiconv) for the list of +# possible encodings. +# The default value is: UTF-8. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by doxygen. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, +# *.vhdl, *.ucf, *.qsf, *.as and *.js. + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.idl \ + *.ddl \ + *.odl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.cs \ + *.d \ + *.php \ + *.php4 \ + *.php5 \ + *.phtml \ + *.inc \ + *.m \ + *.markdown \ + *.md \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.for \ + *.tcl \ + *.vhd \ + *.vhdl \ + *.ucf \ + *.qsf \ + *.as \ + *.js \ + *.hpp \ + *.inl \ + *.cpp + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories use the pattern */test/* + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# classes and enums directly into the documentation. +# The default value is: NO. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# function all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see http://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the config file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the +# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the +# cost of reduced performance. This can be particularly helpful with template +# rich C++ code for which doxygen's built-in parser lacks the necessary type +# information. +# Note: The availability of this option depends on whether or not doxygen was +# compiled with the --with-libclang option. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +ALPHABETICAL_INDEX = YES + +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in +# which the alphabetical index list will be split. +# Minimum value: 1, maximum value: 20, default value: 5. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all classes will +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag +# can be used to specify a prefix (or a list of prefixes) that should be ignored +# while generating the index headers. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). For an example see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_STYLESHEET = + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a colorwheel, see +# http://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use grayscales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting this +# to YES can help to show when doxygen was last run and thus if the +# documentation is up to date. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: http://developer.apple.com/tools/xcode/), introduced with +# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a +# Makefile in the HTML output directory. Running make will produce the docset in +# that directory and running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on +# Windows. +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the master .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- +# folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- +# filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location of Qt's +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the +# generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine-tune the look of the index. As an example, the default style +# sheet generated by doxygen has an example that shows how to put an image at +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has +# the same information as the tab index, you could consider setting +# DISABLE_INDEX to YES when enabling this option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are not +# supported properly for IE 6.0, but are supported on all modern browsers. +# +# Note that when changing this option you need to delete any form_*.png files in +# the HTML output directory before the changes have effect. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# http://www.mathjax.org) which uses client side Javascript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. See the MathJax site (see: +# http://docs.mathjax.org/en/latest/output.html) for more details. +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility), NativeMML (i.e. MathML) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from http://www.mathjax.org before deployment. +# The default value is: http://cdn.mathjax.org/mathjax/latest. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for +# the HTML output. The underlying search engine uses javascript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the javascript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /