Added Texture backgrounds

Former-commit-id: 8aa98a9b8bee5fbf1b5eefa958a7b9095b784cf5
This commit is contained in:
Lynix 2013-03-22 11:15:17 +01:00
parent aecc5919d3
commit ea2cc97169
4 changed files with 234 additions and 8 deletions

View File

@ -0,0 +1,30 @@
// Copyright (C) 2013 Jérôme Leclercq
// This file is part of the "Nazara Engine - 2D Module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_TEXTUREBACKGROUND_HPP
#define NAZARA_TEXTUREBACKGROUND_HPP
#include <Nazara/Prerequesites.hpp>
#include <Nazara/2D/Background.hpp>
#include <Nazara/Renderer/Texture.hpp>
class NAZARA_API NzTextureBackground : public NzBackground
{
public:
NzTextureBackground(NzTexture* texture);
void Draw() const;
nzBackgroundType GetBackgroundType() const;
NzTexture* GetTexture() const;
void SetTexture(NzTexture* texture);
private:
NzTextureRef m_texture;
};
#endif // NAZARA_TEXTUREBACKGROUND_HPP

View File

@ -40,6 +40,7 @@ class NAZARA_API NzRenderer
static void DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveType primitive, unsigned int firstIndex, unsigned int indexCount);
static void DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount);
static void DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveType primitive, 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 Enable(nzRendererParameter parameter, bool enable);

View File

@ -0,0 +1,44 @@
// Copyright (C) 2013 Jérôme Leclercq
// This file is part of the "Nazara Engine - 2D Module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/2D/TextureBackground.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Renderer/RenderTarget.hpp>
#include <Nazara/2D/Debug.hpp>
NzTextureBackground::NzTextureBackground(NzTexture* texture) :
m_texture(texture)
{
}
void NzTextureBackground::Draw() const
{
const NzRenderTarget* target = NzRenderer::GetTarget();
NzRectui viewport = NzRenderer::GetViewport();
// Sous forme de flottants pour la division flottante
float width = target->GetWidth();
float height = target->GetHeight();
NzVector2f uv0(viewport.x/width, viewport.y/height);
NzVector2f uv1((viewport.x+viewport.width)/width, (viewport.y+viewport.height)/height);
NzRenderer::SetTexture(0, m_texture);
NzRenderer::DrawTexture(0, NzRectf(0.f, 0.f, width, height), uv0, uv1, 1.f);
}
nzBackgroundType NzTextureBackground::GetBackgroundType() const
{
return nzBackgroundType_Texture;
}
NzTexture* NzTextureBackground::GetTexture() const
{
return m_texture;
}
void NzTextureBackground::SetTexture(NzTexture* texture)
{
m_texture = texture;
}

View File

@ -61,7 +61,9 @@ namespace
std::map<VAO_Key, unsigned int> s_vaos;
std::vector<TextureUnit> s_textureUnits;
NzBuffer* s_instancingBuffer = nullptr;
NzVertexBuffer* s_quadBuffer = nullptr;
NzMatrix4f s_matrix[totalMatrixCount];
NzVector2ui s_targetSize;
nzBlendFunc s_srcBlend;
nzBlendFunc s_dstBlend;
nzFaceCulling s_faceCulling;
@ -308,6 +310,130 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive
glDrawArraysInstanced(NzOpenGL::PrimitiveType[primitive], firstVertex, vertexCount, instanceCount);
}
void NzRenderer::DrawTexture(unsigned int unit, const NzRectf& rect, const NzVector2f& uv0, const NzVector2f& uv1, float z)
{
#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);
if (!EnsureStateUpdate(true))
{
NazaraError("Failed to update states");
return;
}
shader->SendMatrix(shader->GetUniformLocation("WorldViewProjMatrix"), NzMatrix4f::Ortho(0.f, s_targetSize.x, 0.f, s_targetSize.y, 0.f));
glDrawArrays(NzOpenGL::PrimitiveType[nzPrimitiveType_TriangleStrip], 0, 4);
// Restauration
Enable(nzRendererParameter_FaceCulling, faceCulling);
SetShader(oldShader);
SetVertexBuffer(oldBuffer);
s_matrixUpdated[nzMatrixCombination_WorldViewProj] = false;
s_vaoUpdated = false;
}
}
void NzRenderer::Enable(nzRendererParameter parameter, bool enable)
{
#ifdef NAZARA_DEBUG
@ -611,6 +737,28 @@ bool NzRenderer::Initialize(bool initializeDebugDrawer)
s_vertexBuffer = nullptr;
s_vertexDeclaration = nullptr;
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;
NzVertexDeclaration* declaration = new NzVertexDeclaration;
if (!declaration->Create(elements, 2))
{
NazaraError("Failed to create quad declaration");
Uninitialize();
return false;
}
declaration->SetPersistent(false, false);
s_quadBuffer = new NzVertexBuffer(declaration, 4, nzBufferStorage_Hardware, nzBufferUsage_Dynamic);
if (initializeDebugDrawer && !NzDebugDrawer::Initialize())
NazaraWarning("Failed to initialize debug drawer"); // Non-critique
@ -1086,6 +1234,7 @@ bool NzRenderer::SetTarget(const NzRenderTarget* target)
}
s_target = target;
s_targetSize.Set(target->GetWidth(), target->GetHeight());
}
return true;
@ -1101,19 +1250,19 @@ void NzRenderer::SetTexture(nzUInt8 unit, const NzTexture* texture)
}
#endif
if (!texture) // Pas besoin de mettre à jour s'il n'y a pas de texture
return;
if (s_textureUnits[unit].texture != texture)
{
s_textureUnits[unit].texture = texture;
s_textureUnits[unit].textureUpdated = false;
if (texture)
{
if (s_textureUnits[unit].sampler.UseMipmaps(texture->HasMipmaps()))
s_textureUnits[unit].samplerUpdated = false;
s_textureUnits[unit].updated = false;
}
}
}
void NzRenderer::SetTextureSampler(nzUInt8 unit, const NzTextureSampler& sampler)
@ -1144,7 +1293,7 @@ bool NzRenderer::SetVertexBuffer(const NzVertexBuffer* vertexBuffer)
}
#endif
if (s_vertexBuffer != vertexBuffer)
if (vertexBuffer && s_vertexBuffer != vertexBuffer)
{
s_vertexBuffer = vertexBuffer;
@ -1214,7 +1363,9 @@ void NzRenderer::Uninitialize()
NzShaderBuilder::Uninitialize();
NzTextureSampler::Uninitialize();
// Libération du buffer d'instancing
// Libération des buffers
delete s_quadBuffer;
if (s_instancingBuffer)
{
delete s_instancingBuffer;