Added Renderer::DrawFullscreenQuad

Made [Color|Texture]Background use a new shader-based algorithm


Former-commit-id: cfd319b33712c270726eb697e258d61db2ca6835
This commit is contained in:
Lynix
2013-06-27 12:54:20 +02:00
parent 1a6e55881b
commit 984ade783a
5 changed files with 232 additions and 143 deletions

View File

@@ -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,125 +329,18 @@ 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
SetIndexBuffer(nullptr);
SetVertexBuffer(s_fullscreenQuadBuffer);
#if NAZARA_RENDERER_SAFE
if (unit >= s_textureUnits.size())
if (!EnsureStateUpdate())
{
NazaraError("Texture unit out of range (" + NzString::Number(unit) + " >= " + NzString::Number(s_textureUnits.size()) + ')');
NazaraError("Failed to update states");
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);
if (!EnsureStateUpdate())
{
NazaraError("Failed to update states");
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);