Added Renderer::DrawFullscreenQuad
Made [Color|Texture]Background use a new shader-based algorithm Former-commit-id: cfd319b33712c270726eb697e258d61db2ca6835
This commit is contained in:
parent
1a6e55881b
commit
984ade783a
|
|
@ -10,11 +10,13 @@
|
|||
#include <Nazara/Prerequesites.hpp>
|
||||
#include <Nazara/Core/Color.hpp>
|
||||
#include <Nazara/Graphics/AbstractBackground.hpp>
|
||||
#include <Nazara/Renderer/Shader.hpp>
|
||||
|
||||
class NAZARA_API NzColorBackground : public NzAbstractBackground
|
||||
{
|
||||
public:
|
||||
NzColorBackground(const NzColor& color = NzColor::Black);
|
||||
~NzColorBackground();
|
||||
|
||||
void Draw(const NzScene* scene) const;
|
||||
|
||||
|
|
@ -25,6 +27,7 @@ class NAZARA_API NzColorBackground : public NzAbstractBackground
|
|||
|
||||
private:
|
||||
NzColor m_color;
|
||||
NzShaderRef m_shader;
|
||||
};
|
||||
|
||||
#endif // NAZARA_COLORBACKGROUND_HPP
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class NAZARA_API NzRenderer
|
|||
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);
|
||||
NAZARA_DEPRECATED("Don't use this or you will have cancer") static void DrawTexture(unsigned int unit, const NzRectf& rect, const NzVector2f& uv0, const NzVector2f& uv1, float z = 0.f);
|
||||
static void DrawFullscreenQuad();
|
||||
|
||||
static void Enable(nzRendererParameter parameter, bool enable);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,21 +2,111 @@
|
|||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Graphics/ColorBackground.hpp>
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Graphics/ColorBackGround.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
NzShader* BuildShader()
|
||||
{
|
||||
const char* fragmentSource110 =
|
||||
"#version 110\n"
|
||||
"uniform vec4 Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = Color;\n"
|
||||
"}\n";
|
||||
|
||||
const char* fragmentSource140 =
|
||||
"#version 140\n"
|
||||
"out vec4 RenderTarget0;\n"
|
||||
"uniform vec4 Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" RenderTarget0 = Color;\n"
|
||||
"}\n";
|
||||
|
||||
const char* vertexSource110 =
|
||||
"#version 110\n"
|
||||
"attribute vec2 VertexPosition;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(VertexPosition, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
const char* vertexSource140 =
|
||||
"#version 140\n"
|
||||
"in vec2 VertexPosition;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(VertexPosition, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
///TODO: Remplacer ça par des ShaderNode
|
||||
std::unique_ptr<NzShader> shader(new NzShader(nzShaderLanguage_GLSL));
|
||||
shader->SetPersistent(false);
|
||||
|
||||
bool useGLSL140 = (NzOpenGL::GetVersion() >= 310);
|
||||
|
||||
if (!shader->Load(nzShaderType_Fragment, (useGLSL140) ? fragmentSource140 : fragmentSource110))
|
||||
{
|
||||
NazaraError("Failed to load fragment shader");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!shader->Load(nzShaderType_Vertex, (useGLSL140) ? vertexSource140 : vertexSource110))
|
||||
{
|
||||
NazaraError("Failed to load vertex shader");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!shader->Compile())
|
||||
{
|
||||
NazaraError("Failed to compile shader");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return shader.release();
|
||||
}
|
||||
|
||||
static NzShader* s_shader = nullptr;
|
||||
static unsigned int s_colorLocation;
|
||||
}
|
||||
|
||||
NzColorBackground::NzColorBackground(const NzColor& color) :
|
||||
m_color(color)
|
||||
{
|
||||
if (!s_shader)
|
||||
{
|
||||
s_shader = BuildShader();
|
||||
s_colorLocation = s_shader->GetUniformLocation("Color");
|
||||
}
|
||||
|
||||
m_shader = s_shader;
|
||||
}
|
||||
|
||||
NzColorBackground::~NzColorBackground()
|
||||
{
|
||||
if (m_shader.Reset())
|
||||
s_shader = nullptr;
|
||||
}
|
||||
|
||||
void NzColorBackground::Draw(const NzScene* scene) const
|
||||
{
|
||||
NazaraUnused(scene);
|
||||
|
||||
NzRenderer::SetClearColor(m_color);
|
||||
NzRenderer::Clear(nzRendererClear_Color);
|
||||
static NzRenderStates states;
|
||||
|
||||
m_shader->SendColor(s_colorLocation, m_color);
|
||||
|
||||
NzRenderer::SetRenderStates(states);
|
||||
NzRenderer::SetShader(m_shader);
|
||||
|
||||
NzRenderer::DrawFullscreenQuad();
|
||||
}
|
||||
|
||||
nzBackgroundType NzColorBackground::GetBackgroundType() const
|
||||
|
|
@ -33,3 +123,4 @@ void NzColorBackground::SetColor(const NzColor& color)
|
|||
{
|
||||
m_color = color;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,32 +2,123 @@
|
|||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Graphics/TextureBackground.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
NzTextureBackground::NzTextureBackground(NzTexture* texture) :
|
||||
m_texture(texture)
|
||||
namespace
|
||||
{
|
||||
NzShader* BuildShader()
|
||||
{
|
||||
const char* fragmentSource110 =
|
||||
"#version 110\n"
|
||||
"varying vec2 vTexCoord;\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = texture(Texture, vTexCoord);\n"
|
||||
"}\n";
|
||||
|
||||
const char* fragmentSource140 =
|
||||
"#version 140\n"
|
||||
"in vec2 vTexCoord;\n"
|
||||
"out vec4 RenderTarget0;\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" RenderTarget0 = texture(Texture, vTexCoord);\n"
|
||||
"}\n";
|
||||
|
||||
const char* vertexSource110 =
|
||||
"#version 110\n"
|
||||
"attribute vec2 VertexPosition;\n"
|
||||
"varying vec2 vTexCoord;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(VertexPosition, 0.0, 1.0);\n"
|
||||
" vTexCoord = vec2((VertexPosition.x + 1.0)*0.5, (VertexPosition.y + 1.0)*0.5);\n"
|
||||
"}\n";
|
||||
|
||||
const char* vertexSource140 =
|
||||
"#version 140\n"
|
||||
"in vec2 VertexPosition;\n"
|
||||
"out vec2 vTexCoord;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(VertexPosition, 0.0, 1.0);\n"
|
||||
" vTexCoord = vec2((VertexPosition.x + 1.0)*0.5, (VertexPosition.y + 1.0)*0.5);\n"
|
||||
"}\n";
|
||||
|
||||
///TODO: Remplacer ça par des ShaderNode
|
||||
std::unique_ptr<NzShader> shader(new NzShader(nzShaderLanguage_GLSL));
|
||||
shader->SetPersistent(false);
|
||||
|
||||
bool useGLSL140 = (NzOpenGL::GetVersion() >= 310);
|
||||
|
||||
if (!shader->Load(nzShaderType_Fragment, (useGLSL140) ? fragmentSource140 : fragmentSource110))
|
||||
{
|
||||
NazaraError("Failed to load fragment shader");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!shader->Load(nzShaderType_Vertex, (useGLSL140) ? vertexSource140 : vertexSource110))
|
||||
{
|
||||
NazaraError("Failed to load vertex shader");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!shader->Compile())
|
||||
{
|
||||
NazaraError("Failed to compile shader");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return shader.release();
|
||||
}
|
||||
|
||||
static NzShader* s_shader = nullptr;
|
||||
static unsigned int s_textureLocation;
|
||||
}
|
||||
|
||||
NzTextureBackground::NzTextureBackground()
|
||||
{
|
||||
if (!s_shader)
|
||||
{
|
||||
s_shader = BuildShader();
|
||||
s_textureLocation = s_shader->GetUniformLocation("Texture");
|
||||
}
|
||||
|
||||
m_shader = s_shader;
|
||||
}
|
||||
|
||||
NzTextureBackground::NzTextureBackground(NzTexture* texture) :
|
||||
NzTextureBackground()
|
||||
{
|
||||
m_texture = texture;
|
||||
}
|
||||
|
||||
NzTextureBackground::~NzTextureBackground()
|
||||
{
|
||||
if (m_shader.Reset())
|
||||
s_shader = nullptr;
|
||||
}
|
||||
|
||||
void NzTextureBackground::Draw(const NzScene* scene) const
|
||||
{
|
||||
NazaraUnused(scene);
|
||||
|
||||
const NzRenderTarget* target = NzRenderer::GetTarget();
|
||||
NzRectui viewport = NzRenderer::GetViewport();
|
||||
static NzRenderStates states;
|
||||
|
||||
// Sous forme de flottants pour la division flottante
|
||||
float width = static_cast<float>(target->GetWidth());
|
||||
float height = static_cast<float>(target->GetHeight());
|
||||
|
||||
NzVector2f uv0(viewport.x/width, viewport.y/height);
|
||||
NzVector2f uv1((viewport.x+viewport.width)/width, (viewport.y+viewport.height)/height);
|
||||
m_shader->SendInteger(s_textureLocation, 0);
|
||||
|
||||
NzRenderer::SetRenderStates(states);
|
||||
NzRenderer::SetShader(m_shader);
|
||||
NzRenderer::SetTexture(0, m_texture);
|
||||
NzRenderer::DrawTexture(0, NzRectf(0.f, 0.f, width, height), uv0, uv1, 1.f);
|
||||
|
||||
NzRenderer::DrawFullscreenQuad();
|
||||
}
|
||||
|
||||
nzBackgroundType NzTextureBackground::GetBackgroundType() const
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ namespace
|
|||
std::vector<TextureUnit> s_textureUnits;
|
||||
GLuint s_currentVAO = 0;
|
||||
NzBuffer* s_instancingBuffer = nullptr;
|
||||
NzVertexBuffer* s_quadBuffer = nullptr;
|
||||
NzVertexBuffer* s_fullscreenQuadBuffer = nullptr;
|
||||
NzMatrix4f s_matrix[totalMatrixCount];
|
||||
NzRenderStates s_states;
|
||||
NzVector2ui s_targetSize;
|
||||
|
|
@ -329,109 +329,10 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive
|
|||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void NzRenderer::DrawTexture(unsigned int unit, const NzRectf& rect, const NzVector2f& uv0, const NzVector2f& uv1, float z)
|
||||
void NzRenderer::DrawFullscreenQuad()
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (unit >= s_textureUnits.size())
|
||||
{
|
||||
NazaraError("Texture unit out of range (" + NzString::Number(unit) + " >= " + NzString::Number(s_textureUnits.size()) + ')');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!s_textureUnits[unit].texture)
|
||||
{
|
||||
NazaraError("No texture at unit #" + NzString::Number(unit));
|
||||
return;
|
||||
}
|
||||
|
||||
if (z < 0.f || z > 1.f)
|
||||
{
|
||||
NazaraError("Z must be in range [0..1] (Got " + NzString::Number(z) + ')');
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
const NzTexture* texture = s_textureUnits[unit].texture;
|
||||
|
||||
if (glDrawTexture)
|
||||
{
|
||||
float xCorrect = 2.f/s_targetSize.x;
|
||||
float yCorrect = 2.f/s_targetSize.y;
|
||||
|
||||
NzVector2f coords[2] =
|
||||
{
|
||||
{rect.x, rect.y},
|
||||
{rect.x+rect.width, rect.y+rect.height}
|
||||
};
|
||||
|
||||
for (unsigned int i = 0; i < 2; ++i)
|
||||
{
|
||||
coords[i].x *= xCorrect;
|
||||
coords[i].x -= 1.f;
|
||||
|
||||
coords[i].y *= yCorrect;
|
||||
coords[i].y -= 1.f;
|
||||
}
|
||||
|
||||
const NzTextureSampler& sampler = s_textureUnits[unit].sampler;
|
||||
GLuint samplerId;
|
||||
if (s_useSamplerObjects)
|
||||
samplerId = sampler.GetOpenGLID();
|
||||
else
|
||||
{
|
||||
sampler.Apply(texture);
|
||||
samplerId = 0;
|
||||
}
|
||||
|
||||
glDrawTexture(texture->GetOpenGLID(), samplerId,
|
||||
coords[0].x, coords[0].y, coords[1].x, coords[1].y,
|
||||
z,
|
||||
uv0.x, 1.f-uv0.y, uv1.x, 1.f-uv1.y); // Inversion des UV sur Y
|
||||
}
|
||||
else
|
||||
{
|
||||
///FIXME: Remplacer cette immondice (Code fonctionnel mais à vomir)
|
||||
// Ce code est horrible mais la version optimisée demanderait des fonctionnalités pas encore implémentées, à venir...
|
||||
|
||||
float vertices[4*(3 + 2)] =
|
||||
{
|
||||
rect.x, rect.y, z,
|
||||
uv0.x, uv0.y,
|
||||
|
||||
rect.x+rect.width, rect.y, z,
|
||||
uv1.x, uv0.y,
|
||||
|
||||
rect.x, rect.y+rect.height, z,
|
||||
uv0.x, uv1.y,
|
||||
|
||||
rect.x+rect.width, rect.y+rect.height, z,
|
||||
uv1.x, uv1.y
|
||||
};
|
||||
|
||||
if (!s_quadBuffer->Fill(vertices, 0, 4, true))
|
||||
{
|
||||
NazaraError("Failed to fill vertex buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
const NzShader* oldShader = s_shader;
|
||||
const NzVertexBuffer* oldBuffer = s_vertexBuffer;
|
||||
|
||||
const NzShader* shader = NzShaderBuilder::Get(nzShaderFlags_DiffuseMapping | nzShaderFlags_FlipUVs);
|
||||
shader->SendTexture(shader->GetUniformLocation("MaterialDiffuseMap"), texture);
|
||||
|
||||
bool faceCulling = IsEnabled(nzRendererParameter_FaceCulling);
|
||||
Enable(nzRendererParameter_FaceCulling, false);
|
||||
SetShader(shader);
|
||||
SetVertexBuffer(s_quadBuffer);
|
||||
SetIndexBuffer(nullptr);
|
||||
SetVertexBuffer(s_fullscreenQuadBuffer);
|
||||
|
||||
if (!EnsureStateUpdate())
|
||||
{
|
||||
|
|
@ -439,15 +340,7 @@ void NzRenderer::DrawTexture(unsigned int unit, const NzRectf& rect, const NzVec
|
|||
return;
|
||||
}
|
||||
|
||||
shader->SendMatrix(s_matrixLocation[nzMatrixCombination_WorldViewProj], NzMatrix4f::Ortho(0.f, s_targetSize.x, 0.f, s_targetSize.y, 0.f));
|
||||
|
||||
glDrawArrays(NzOpenGL::PrimitiveMode[nzPrimitiveMode_TriangleStrip], 0, 4);
|
||||
|
||||
// Restauration
|
||||
Enable(nzRendererParameter_FaceCulling, faceCulling);
|
||||
SetShader(oldShader);
|
||||
SetVertexBuffer(oldBuffer);
|
||||
}
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
}
|
||||
|
||||
void NzRenderer::Enable(nzRendererParameter parameter, bool enable)
|
||||
|
|
@ -732,19 +625,15 @@ bool NzRenderer::Initialize()
|
|||
s_vertexBuffer = nullptr;
|
||||
s_updateFlags = (Update_Matrices | Update_Shader | Update_VAO);
|
||||
|
||||
NzVertexElement elements[2];
|
||||
elements[0].offset = 0;
|
||||
elements[0].type = nzElementType_Float3;
|
||||
elements[0].usage = nzElementUsage_Position;
|
||||
|
||||
elements[1].offset = 3*sizeof(float);
|
||||
elements[1].type = nzElementType_Float2;
|
||||
elements[1].usage = nzElementUsage_TexCoord;
|
||||
NzVertexElement element;
|
||||
element.offset = 0;
|
||||
element.type = nzElementType_Float2;
|
||||
element.usage = nzElementUsage_Position;
|
||||
|
||||
std::unique_ptr<NzVertexDeclaration> declaration(new NzVertexDeclaration);
|
||||
if (!declaration->Create(elements, 2))
|
||||
if (!declaration->Create(&element, 1))
|
||||
{
|
||||
NazaraError("Failed to create quad declaration");
|
||||
NazaraError("Failed to create fullscreen quad declaration");
|
||||
Uninitialize();
|
||||
|
||||
return false;
|
||||
|
|
@ -752,9 +641,25 @@ bool NzRenderer::Initialize()
|
|||
|
||||
declaration->SetPersistent(false);
|
||||
|
||||
s_quadBuffer = new NzVertexBuffer(declaration.get(), 4, nzBufferStorage_Hardware, nzBufferUsage_Dynamic);
|
||||
s_fullscreenQuadBuffer = new NzVertexBuffer(declaration.get(), 4, nzBufferStorage_Hardware, nzBufferUsage_Static);
|
||||
declaration.release();
|
||||
|
||||
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");
|
||||
Uninitialize();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NzMaterial::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize materials");
|
||||
|
|
@ -1306,7 +1211,7 @@ void NzRenderer::Uninitialize()
|
|||
NzTextureSampler::Uninitialize();
|
||||
|
||||
// Libération des buffers
|
||||
delete s_quadBuffer;
|
||||
delete s_fullscreenQuadBuffer;
|
||||
|
||||
if (s_instancingBuffer)
|
||||
{
|
||||
|
|
@ -1396,7 +1301,6 @@ bool NzRenderer::EnsureStateUpdate()
|
|||
{
|
||||
TextureUnit& unit = s_textureUnits[i];
|
||||
|
||||
///FIXME: Cet appel ne fait-il pas redondance avec le rebinding des textures avant le return ?
|
||||
if (!unit.textureUpdated)
|
||||
{
|
||||
NzOpenGL::SetTextureUnit(i);
|
||||
|
|
|
|||
Loading…
Reference in New Issue