diff --git a/include/Nazara/Graphics/AbstractBackground.hpp b/include/Nazara/Graphics/AbstractBackground.hpp index 9bccde7c7..b557ee871 100644 --- a/include/Nazara/Graphics/AbstractBackground.hpp +++ b/include/Nazara/Graphics/AbstractBackground.hpp @@ -8,12 +8,19 @@ #define NAZARA_ABSTRACTBACKGROUND_HPP #include +#include +#include #include #include +class NzAbstractBackground; class NzAbstractViewer; -class NAZARA_GRAPHICS_API NzAbstractBackground +using NzBackgroundConstRef = NzObjectRef; +using NzBackgroundLibrary = NzObjectLibrary; +using NzBackgroundRef = NzObjectRef; + +class NAZARA_GRAPHICS_API NzAbstractBackground : public NzRefCounted { public: NzAbstractBackground() = default; @@ -22,6 +29,9 @@ class NAZARA_GRAPHICS_API NzAbstractBackground virtual void Draw(const NzAbstractViewer* viewer) const = 0; virtual nzBackgroundType GetBackgroundType() const = 0; + + private: + static NzBackgroundLibrary::LibraryMap s_library; }; #endif // NAZARA_ABSTRACTBACKGROUND_HPP diff --git a/include/Nazara/Graphics/ColorBackground.hpp b/include/Nazara/Graphics/ColorBackground.hpp index aa00fd154..c769ba15d 100644 --- a/include/Nazara/Graphics/ColorBackground.hpp +++ b/include/Nazara/Graphics/ColorBackground.hpp @@ -12,6 +12,11 @@ #include #include +class NzColorBackground; + +using NzColorBackgroundConstRef = NzObjectRef; +using NzColorBackgroundRef = NzObjectRef; + class NAZARA_GRAPHICS_API NzColorBackground : public NzAbstractBackground { public: @@ -24,6 +29,8 @@ class NAZARA_GRAPHICS_API NzColorBackground : public NzAbstractBackground void SetColor(const NzColor& color); + template static NzColorBackgroundRef New(Args&&... args); + private: NzColor m_color; NzUberShaderConstRef m_uberShader; @@ -32,4 +39,6 @@ class NAZARA_GRAPHICS_API NzColorBackground : public NzAbstractBackground int m_vertexDepthUniform; }; +#include + #endif // NAZARA_COLORBACKGROUND_HPP diff --git a/include/Nazara/Graphics/ColorBackground.inl b/include/Nazara/Graphics/ColorBackground.inl new file mode 100644 index 000000000..c082703f0 --- /dev/null +++ b/include/Nazara/Graphics/ColorBackground.inl @@ -0,0 +1,17 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +template +NzColorBackgroundRef NzColorBackground::New(Args&&... args) +{ + std::unique_ptr object(new NzColorBackground(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); +} + +#include diff --git a/include/Nazara/Graphics/SkyboxBackground.hpp b/include/Nazara/Graphics/SkyboxBackground.hpp index 29a170c79..7148ce4b3 100644 --- a/include/Nazara/Graphics/SkyboxBackground.hpp +++ b/include/Nazara/Graphics/SkyboxBackground.hpp @@ -15,23 +15,33 @@ #include #include +class NzSkyboxBackground; + +using NzSkyboxBackgroundConstRef = NzObjectRef; +using NzSkyboxBackgroundRef = NzObjectRef; + class NAZARA_GRAPHICS_API NzSkyboxBackground : public NzAbstractBackground { public: - NzSkyboxBackground(); - NzSkyboxBackground(NzTexture* cubemapTexture); - ~NzSkyboxBackground(); + NzSkyboxBackground(NzTextureRef cubemapTexture = NzTextureRef()); + ~NzSkyboxBackground() = default; void Draw(const NzAbstractViewer* viewer) const; nzBackgroundType GetBackgroundType() const; - NzTexture* GetTexture() const; - const NzTextureSampler& GetTextureSampler(); + inline const NzTextureRef& GetTexture() const; + inline NzTextureSampler& GetTextureSampler(); + inline const NzTextureSampler& GetTextureSampler() const; - void SetTexture(NzTexture* cubemapTexture); - void SetTextureSampler(const NzTextureSampler& sampler); + inline void SetTexture(NzTextureRef cubemapTexture); + inline void SetTextureSampler(const NzTextureSampler& sampler); + + template static NzSkyboxBackgroundRef New(Args&&... args); private: + static bool Initialize(); + static void Uninitialize(); + NzTextureRef m_texture; NzTextureSampler m_sampler; NzIndexBufferRef m_indexBuffer; @@ -39,4 +49,6 @@ class NAZARA_GRAPHICS_API NzSkyboxBackground : public NzAbstractBackground NzVertexBufferRef m_vertexBuffer; }; +#include + #endif // NAZARA_SKYBOXBACKGROUND_HPP diff --git a/include/Nazara/Graphics/SkyboxBackground.inl b/include/Nazara/Graphics/SkyboxBackground.inl new file mode 100644 index 000000000..f8105bd30 --- /dev/null +++ b/include/Nazara/Graphics/SkyboxBackground.inl @@ -0,0 +1,45 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +inline const NzTextureRef& NzSkyboxBackground::GetTexture() const +{ + return m_texture; +} + +inline NzTextureSampler& NzSkyboxBackground::GetTextureSampler() +{ + return m_sampler; +} + +inline const NzTextureSampler& NzSkyboxBackground::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"); + + m_texture = std::move(cubemapTexture); +} + +void NzSkyboxBackground::SetTextureSampler(const NzTextureSampler& sampler) +{ + m_sampler = sampler; +} + +template +NzSkyboxBackgroundRef NzSkyboxBackground::New(Args&&... args) +{ + std::unique_ptr object(new NzSkyboxBackground(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 78e25e2fb..0bd8804bb 100644 --- a/include/Nazara/Graphics/TextureBackground.hpp +++ b/include/Nazara/Graphics/TextureBackground.hpp @@ -12,18 +12,24 @@ #include #include +class NzTextureBackground; + +using NzTextureBackgroundConstRef = NzObjectRef; +using NzTextureBackgroundRef = NzObjectRef; + class NAZARA_GRAPHICS_API NzTextureBackground : public NzAbstractBackground { public: - NzTextureBackground(); - NzTextureBackground(NzTexture* texture); + NzTextureBackground(NzTextureRef texture = NzTextureRef()); void Draw(const NzAbstractViewer* viewer) const; nzBackgroundType GetBackgroundType() const; - NzTexture* GetTexture() const; + inline const NzTextureRef& GetTexture() const; - void SetTexture(NzTexture* texture); + inline void SetTexture(NzTextureRef texture); + + template static NzTextureBackgroundRef New(Args&&... args); private: NzTextureRef m_texture; @@ -34,4 +40,6 @@ class NAZARA_GRAPHICS_API NzTextureBackground : public NzAbstractBackground int m_vertexDepthUniform; }; +#include + #endif // NAZARA_TEXTUREBACKGROUND_HPP diff --git a/include/Nazara/Graphics/TextureBackground.inl b/include/Nazara/Graphics/TextureBackground.inl new file mode 100644 index 000000000..7016b4c9a --- /dev/null +++ b/include/Nazara/Graphics/TextureBackground.inl @@ -0,0 +1,29 @@ +// Copyright (C) 2015 Jérôme Leclercq +// This file is part of the "Nazara Engine - Graphics module" +// For conditions of distribution and use, see copyright notice in Config.hpp + +#include +#include + +inline const NzTextureRef& NzTextureBackground::GetTexture() const +{ + return m_texture; +} + +inline void NzTextureBackground::SetTexture(NzTextureRef texture) +{ + NazaraAssert(!texture || texture->IsValid(), "Invalid texture"); + + m_texture = std::move(texture); +} + +template +NzTextureBackgroundRef NzTextureBackground::New(Args&&... args) +{ + std::unique_ptr object(new NzTextureBackground(std::forward(args)...)); + object->SetPersistent(false); + + return object.release(); +} + +#include diff --git a/src/Nazara/Graphics/AbstractBackground.cpp b/src/Nazara/Graphics/AbstractBackground.cpp index 5792b448f..510663c39 100644 --- a/src/Nazara/Graphics/AbstractBackground.cpp +++ b/src/Nazara/Graphics/AbstractBackground.cpp @@ -6,3 +6,5 @@ #include NzAbstractBackground::~NzAbstractBackground() = default; + +NzBackgroundLibrary::LibraryMap NzAbstractBackground::s_library; diff --git a/src/Nazara/Graphics/SkyboxBackground.cpp b/src/Nazara/Graphics/SkyboxBackground.cpp index e9e14ba56..c0346c679 100644 --- a/src/Nazara/Graphics/SkyboxBackground.cpp +++ b/src/Nazara/Graphics/SkyboxBackground.cpp @@ -2,14 +2,9 @@ // This file is part of the "Nazara Engine - Graphics module" // For conditions of distribution and use, see copyright notice in Config.hpp -#ifndef NAZARA_RENDERER_OPENGL -#define NAZARA_RENDERER_OPENGL // Nécessaire pour inclure les headers OpenGL -#endif - #include -#include -#include -#include +#include +#include #include #include #include @@ -19,217 +14,31 @@ namespace { - NzIndexBuffer* BuildIndexBuffer() - { - std::unique_ptr indexBuffer(new NzIndexBuffer(false, 36, nzDataStorage_Hardware, nzBufferUsage_Static)); - indexBuffer->SetPersistent(false); - - nzUInt16 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 - }; - - if (!indexBuffer->Fill(indices, 0, 36)) - { - NazaraError("Failed to create index buffer"); - return nullptr; - } - - return indexBuffer.release(); - } - - 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" - - "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* 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" - - "in vec3 VertexPosition;\n" - - "out 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"; - - ///TODO: Remplacer ça par des ShaderNode - std::unique_ptr shader(new NzShader); - shader->SetPersistent(false); - - if (!shader->Create()) - { - NazaraError("Failed to create shader"); - return nullptr; - } - - bool useGLSL140 = (NzOpenGL::GetVersion() >= 310); - - if (!shader->AttachStageFromSource(nzShaderStage_Fragment, (useGLSL140) ? fragmentSource140 : fragmentSource110)) - { - NazaraError("Failed to load fragment shader"); - return nullptr; - } - - if (!shader->AttachStageFromSource(nzShaderStage_Vertex, (useGLSL140) ? vertexSource140 : vertexSource110)) - { - NazaraError("Failed to load vertex shader"); - return nullptr; - } - - if (!shader->Link()) - { - NazaraError("Failed to link shader"); - return nullptr; - } - - shader->SendInteger(shader->GetUniformLocation("Skybox"), 0); - shader->SendFloat(shader->GetUniformLocation("VertexDepth"), 1.f); - - return shader.release(); - } - - NzRenderStates BuildRenderStates() - { - NzRenderStates states; - states.depthFunc = nzRendererComparison_Equal; - states.faceCulling = nzFaceSide_Front; - states.parameters[nzRendererParameter_DepthBuffer] = true; - states.parameters[nzRendererParameter_DepthWrite] = false; - states.parameters[nzRendererParameter_FaceCulling] = true; - - return states; - } - - NzVertexBuffer* BuildVertexBuffer() - { - std::unique_ptr vertexBuffer(new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ), 8, nzDataStorage_Hardware, nzBufferUsage_Static)); - vertexBuffer->SetPersistent(false); - - float vertices[8*(sizeof(float)*3)] = - { - -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, - }; - - if (!vertexBuffer->Fill(vertices, 0, 8)) - { - NazaraError("Failed to create vertex buffer"); - return nullptr; - } - - return vertexBuffer.release(); - } - - static NzIndexBuffer* s_indexBuffer = nullptr; - static NzShader* s_shader = nullptr; - static NzVertexBuffer* s_vertexBuffer = nullptr; + static NzIndexBufferRef s_indexBuffer; + static NzRenderStates s_renderStates; + static NzShaderRef s_shader; + static NzVertexBufferRef s_vertexBuffer; } -NzSkyboxBackground::NzSkyboxBackground() +NzSkyboxBackground::NzSkyboxBackground(NzTextureRef cubemapTexture) { - if (!s_indexBuffer) - s_indexBuffer = BuildIndexBuffer(); - - if (!s_shader) - s_shader = BuildShader(); - - if (!s_vertexBuffer) - s_vertexBuffer = BuildVertexBuffer(); - m_indexBuffer = s_indexBuffer; m_sampler.SetWrapMode(nzSamplerWrap_Clamp); // Nécessaire pour ne pas voir les côtés m_shader = s_shader; m_vertexBuffer = s_vertexBuffer; -} -NzSkyboxBackground::NzSkyboxBackground(NzTexture* cubemapTexture) : -NzSkyboxBackground() -{ - SetTexture(cubemapTexture); -} - -NzSkyboxBackground::~NzSkyboxBackground() -{ - if (m_indexBuffer.Reset()) - s_indexBuffer = nullptr; - - if (m_shader.Reset()) - s_shader = nullptr; - - if (m_vertexBuffer.Reset()) - s_vertexBuffer = nullptr; + SetTexture(std::move(cubemapTexture)); } void NzSkyboxBackground::Draw(const NzAbstractViewer* viewer) const { - static NzRenderStates states(BuildRenderStates()); - NzMatrix4f skyboxMatrix(viewer->GetViewMatrix()); skyboxMatrix.SetTranslation(NzVector3f::Zero()); NzRenderer::SetIndexBuffer(m_indexBuffer); NzRenderer::SetMatrix(nzMatrixType_View, skyboxMatrix); NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Scale(NzVector3f(viewer->GetZNear()))); - NzRenderer::SetRenderStates(states); + NzRenderer::SetRenderStates(s_renderStates); NzRenderer::SetShader(m_shader); NzRenderer::SetTexture(0, m_texture); NzRenderer::SetTextureSampler(0, m_sampler); @@ -245,29 +54,107 @@ nzBackgroundType NzSkyboxBackground::GetBackgroundType() const return nzBackgroundType_Skybox; } -NzTexture* NzSkyboxBackground::GetTexture() const +bool NzSkyboxBackground::Initialize() { - return m_texture; -} - -void NzSkyboxBackground::SetTexture(NzTexture* cubemapTexture) -{ - #if NAZARA_GRAPHICS_SAFE - if (cubemapTexture) + const nzUInt16 indices[6*6] = { - if (!cubemapTexture->IsValid()) - { - NazaraError("Texture must be valid"); - return; - } + 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 + }; - if (!cubemapTexture->IsCubemap()) - { - NazaraError("Texture must be a cubemap"); - return; - } + 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" + " gl_Position = WorldViewProjMatrix * vec4(VertexPosition, 1.0);\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->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; } - #endif - m_texture = cubemapTexture; + return true; +} + +void NzSkyboxBackground::Uninitialize() +{ + s_indexBuffer.Reset(); + s_shader.Reset(); + s_vertexBuffer.Reset(); } diff --git a/src/Nazara/Graphics/TextureBackground.cpp b/src/Nazara/Graphics/TextureBackground.cpp index 3d5664a18..d1784b078 100644 --- a/src/Nazara/Graphics/TextureBackground.cpp +++ b/src/Nazara/Graphics/TextureBackground.cpp @@ -22,7 +22,7 @@ namespace } } -NzTextureBackground::NzTextureBackground() +NzTextureBackground::NzTextureBackground(NzTextureRef texture) { m_uberShader = NzUberShaderLibrary::Get("Basic"); @@ -37,12 +37,8 @@ NzTextureBackground::NzTextureBackground() m_materialDiffuseUniform = shader->GetUniformLocation("MaterialDiffuse"); m_materialDiffuseMapUniform = shader->GetUniformLocation("MaterialDiffuseMap"); m_vertexDepthUniform = shader->GetUniformLocation("VertexDepth"); -} -NzTextureBackground::NzTextureBackground(NzTexture* texture) : -NzTextureBackground() -{ - m_texture = texture; + SetTexture(std::move(texture)); } void NzTextureBackground::Draw(const NzAbstractViewer* viewer) const @@ -68,13 +64,3 @@ nzBackgroundType NzTextureBackground::GetBackgroundType() const { return nzBackgroundType_Texture; } - -NzTexture* NzTextureBackground::GetTexture() const -{ - return m_texture; -} - -void NzTextureBackground::SetTexture(NzTexture* texture) -{ - m_texture = texture; -}