Graphics/Backgrounds: Update backgrounds to new coding-style
Former-commit-id: 9f96b93706fd8417d6262392f0ce9ab9ca1985c3
This commit is contained in:
@@ -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 <Nazara/Graphics/SkyboxBackground.hpp>
|
||||
#include <Nazara/Graphics/Camera.hpp>
|
||||
#include <Nazara/Graphics/Scene.hpp>
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Graphics/AbstractViewer.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Utility/IndexBuffer.hpp>
|
||||
#include <Nazara/Utility/VertexBuffer.hpp>
|
||||
@@ -19,217 +14,31 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
NzIndexBuffer* BuildIndexBuffer()
|
||||
{
|
||||
std::unique_ptr<NzIndexBuffer> 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<NzShader> 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<NzVertexBuffer> 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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user