Refactored mathematics module

Added AABBs
Added code examples
Added experimental support for texture arrays (1D/2D)
Added initialisers (new way of initialising modules)
Added global headers (Plus a global header generator script)
Added pattern support for directory
Added support for spinlocks critical section on Windows
Added NzRenderWindow::SetFramerateLimit
Core project now includes Mathematics files
Fixed color implementation using double
Fixed declaration needing renderer include
Fixed MLT not clearing nextFree(File/Line) after Free
Fixed move operators not being noexcept
Fixed thread-safety (Now working correctly - If I'm lucky)
Moved Resource to core
New interface for modules
New interface for the renderer
Put some global functions to anonymous namespace
Removed empty modules
Renamed ThreadCondition to ConditionVariable
Replaced redirect to cerr log option by duplicate to cout
Setting mouse position relative to a window will make this window ignore
the event
Shaders sending methods no longer takes the uniform variable name (it's
using ID instead)
Using new OpenGL 4.3 header
This commit is contained in:
Lynix
2012-08-08 04:44:17 +02:00
parent 06eda4eba9
commit b442ab0bd2
142 changed files with 6861 additions and 2326 deletions

View File

@@ -6,6 +6,7 @@
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Core/Color.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/HardwareBuffer.hpp>
@@ -18,6 +19,7 @@
#include <Nazara/Utility/VertexBuffer.hpp>
#include <Nazara/Utility/VertexDeclaration.hpp>
#include <stdexcept>
#include <tuple>
#include <Nazara/Renderer/Debug.hpp>
namespace
@@ -61,7 +63,6 @@ namespace
GL_FILL // nzFaceFilling_Fill
};
const GLenum openglPrimitive[] =
{
GL_LINES, // nzPrimitiveType_LineList,
@@ -131,28 +132,47 @@ namespace
GL_ZERO // nzStencilOperation_Zero
};
///FIXME: Solution temporaire pour plus de facilité
enum nzMatrixCombination
{
nzMatrixCombination_ViewProj = nzMatrixType_Max+1,
nzMatrixCombination_WorldView,
nzMatrixCombination_WorldViewProj,
nzMatrixCombination_Max = nzMatrixCombination_WorldViewProj
};
NzBufferImpl* HardwareBufferFunction(NzBuffer* parent, nzBufferType type)
{
return new NzHardwareBuffer(parent, type);
}
}
NzRenderer::NzRenderer()
{
#if NAZARA_RENDERER_SAFE
if (s_instance)
throw std::runtime_error("Renderer already instanced");
#endif
typedef std::tuple<const NzContext*, const NzIndexBuffer*, const NzVertexBuffer*, const NzVertexDeclaration*> VAO_Key;
s_instance = this;
}
constexpr unsigned int totalMatrixCount = nzMatrixCombination_Max+1;
NzRenderer::~NzRenderer()
{
if (s_initialized)
Uninitialize();
s_instance = nullptr;
std::map<VAO_Key, unsigned int> s_vaos;
NzMatrix4f s_matrix[totalMatrixCount];
int s_matrixLocation[totalMatrixCount];
bool s_matrixUpdated[totalMatrixCount];
nzRendererComparison s_stencilCompare;
nzStencilOperation s_stencilFail;
nzStencilOperation s_stencilPass;
nzStencilOperation s_stencilZFail;
nzUInt32 s_stencilMask;
const NzIndexBuffer* s_indexBuffer;
NzRenderTarget* s_target;
NzShader* s_shader;
const NzVertexBuffer* s_vertexBuffer;
const NzVertexDeclaration* s_vertexDeclaration;
bool s_vaoUpdated;
bool s_capabilities[nzRendererCap_Max+1];
bool s_stencilFuncUpdated;
bool s_stencilOpUpdated;
unsigned int s_maxAnisotropyLevel;
unsigned int s_maxRenderTarget;
unsigned int s_maxTextureUnit;
unsigned int s_stencilReference;
}
void NzRenderer::Clear(unsigned long flags)
@@ -190,8 +210,10 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
NazaraError("No active context");
return;
}
#endif
if (!m_indexBuffer)
#if NAZARA_RENDERER_SAFE
if (!s_indexBuffer)
{
NazaraError("No index buffer");
return;
@@ -204,11 +226,11 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
return;
}
if (m_indexBuffer->IsSequential())
glDrawArrays(openglPrimitive[primitive], m_indexBuffer->GetStartIndex(), m_indexBuffer->GetIndexCount());
if (s_indexBuffer->IsSequential())
glDrawArrays(openglPrimitive[primitive], s_indexBuffer->GetStartIndex(), s_indexBuffer->GetIndexCount());
else
{
nzUInt8 indexSize = m_indexBuffer->GetIndexSize();
nzUInt8 indexSize = s_indexBuffer->GetIndexSize();
GLenum type;
switch (indexSize)
@@ -230,7 +252,7 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
return;
}
glDrawElements(openglPrimitive[primitive], indexCount, type, reinterpret_cast<const nzUInt8*>(m_indexBuffer->GetPointer()) + firstIndex*indexSize);
glDrawElements(openglPrimitive[primitive], indexCount, type, reinterpret_cast<const nzUInt8*>(s_indexBuffer->GetPointer()) + firstIndex*indexSize);
}
}
@@ -282,33 +304,70 @@ void NzRenderer::Enable(nzRendererParameter parameter, bool enable)
break;
}
}
unsigned int NzRenderer::GetMaxAnisotropyLevel() const
/*
NzMatrix4f NzRenderer::GetMatrix(nzMatrixCombination combination)
{
return m_maxAnisotropyLevel;
switch (combination)
{
case nzMatrixCombination_ViewProj:
if (!s_matrixUpdated[nzMatrixCombination_ViewProj])
{
s_matrix[nzMatrixCombination_ViewProj] = s_matrix[nzMatrixType_View] * s_matrix[nzMatrixType_Projection];
s_matrixUpdated[nzMatrixCombination_ViewProj] = true;
}
break;
case nzMatrixCombination_WorldView:
if (!s_matrixUpdated[nzMatrixCombination_WorldView])
{
s_matrix[nzMatrixCombination_WorldView] = NzMatrix4f::ConcatenateAffine(s_matrix[nzMatrixType_World], s_matrix[nzMatrixType_View]);
s_matrixUpdated[nzMatrixCombination_WorldView] = true;
}
break;
case nzMatrixCombination_WorldViewProj:
if (!s_matrixUpdated[nzMatrixCombination_WorldViewProj])
{
s_matrix[nzMatrixCombination_WorldViewProj] = s_matrix[nzMatrixCombination_WorldView] * s_matrix[nzMatrixType_Projection];
s_matrixUpdated[nzMatrixCombination_WorldViewProj] = true;
}
break;
}
return m_matrix[combination];
}
*/
NzMatrix4f NzRenderer::GetMatrix(nzMatrixType type)
{
return s_matrix[type];
}
unsigned int NzRenderer::GetMaxRenderTargets() const
unsigned int NzRenderer::GetMaxAnisotropyLevel()
{
return m_maxRenderTarget;
return s_maxAnisotropyLevel;
}
unsigned int NzRenderer::GetMaxTextureUnits() const
unsigned int NzRenderer::GetMaxRenderTargets()
{
return m_maxTextureUnit;
return s_maxRenderTarget;
}
NzShader* NzRenderer::GetShader() const
unsigned int NzRenderer::GetMaxTextureUnits()
{
return m_shader;
return s_maxTextureUnit;
}
NzRenderTarget* NzRenderer::GetTarget() const
NzShader* NzRenderer::GetShader()
{
return m_target;
return s_shader;
}
NzRectui NzRenderer::GetViewport() const
NzRenderTarget* NzRenderer::GetTarget()
{
return s_target;
}
NzRectui NzRenderer::GetViewport()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
@@ -324,103 +383,110 @@ NzRectui NzRenderer::GetViewport() const
return NzRectui(params[0], params[1], params[2], params[3]);
}
bool NzRenderer::HasCapability(nzRendererCap capability) const
bool NzRenderer::HasCapability(nzRendererCap capability)
{
return m_capabilities[capability];
return s_capabilities[capability];
}
bool NzRenderer::Initialize()
{
#if NAZARA_RENDERER_SAFE
if (s_initialized)
if (s_moduleReferenceCouter++ != 0)
return true; // Déjà initialisé
// Initialisation des dépendances
if (!NzUtility::Initialize())
{
NazaraError("Renderer already initialized");
return true;
}
#endif
// Initialisation du module Utility
if (!NzUtility::IsInitialized())
{
m_utilityModule = new NzUtility;
m_utilityModule->Initialize();
}
else
m_utilityModule = nullptr;
if (NzOpenGL::Initialize())
{
NzContext::EnsureContext();
m_indexBuffer = nullptr;
m_shader = nullptr;
m_stencilCompare = nzRendererComparison_Always;
m_stencilFail = nzStencilOperation_Keep;
m_stencilFuncUpdated = true;
m_stencilMask = 0xFFFFFFFF;
m_stencilOpUpdated = true;
m_stencilPass = nzStencilOperation_Keep;
m_stencilReference = 0;
m_stencilZFail = nzStencilOperation_Keep;
m_target = nullptr;
m_vaoUpdated = false;
m_vertexBuffer = nullptr;
m_vertexDeclaration = nullptr;
// Récupération des capacités
m_capabilities[nzRendererCap_AnisotropicFilter] = NzOpenGL::IsSupported(NzOpenGL::AnisotropicFilter);
m_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(NzOpenGL::FP64);
m_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5
m_capabilities[nzRendererCap_MultipleRenderTargets] = true; // Natif depuis OpenGL 2.0
m_capabilities[nzRendererCap_OcclusionQuery] = true; // Natif depuis OpenGL 1.5
m_capabilities[nzRendererCap_PixelBufferObject] = NzOpenGL::IsSupported(NzOpenGL::PixelBufferObject);
m_capabilities[nzRendererCap_Texture3D] = NzOpenGL::IsSupported(NzOpenGL::Texture3D);
m_capabilities[nzRendererCap_TextureCubemap] = true; // Natif depuis OpenGL 1.3
m_capabilities[nzRendererCap_TextureMulti] = true; // Natif depuis OpenGL 1.3
m_capabilities[nzRendererCap_TextureNPOT] = true; // Natif depuis OpenGL 2.0
if (m_capabilities[nzRendererCap_AnisotropicFilter])
{
GLint maxAnisotropy;
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy);
m_maxAnisotropyLevel = static_cast<unsigned int>(maxAnisotropy);
}
else
m_maxAnisotropyLevel = 1;
if (m_capabilities[nzRendererCap_MultipleRenderTargets])
{
GLint maxDrawBuffers;
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
m_maxRenderTarget = static_cast<unsigned int>(maxDrawBuffers);
}
else
m_maxRenderTarget = 1;
if (m_capabilities[nzRendererCap_TextureMulti])
{
GLint maxTextureUnits;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
GLint maxVertexAttribs;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
// Impossible de binder plus de texcoords que d'attributes (en sachant qu'un certain nombre est déjà pris par les autres attributs)
m_maxTextureUnit = static_cast<unsigned int>(std::min(maxTextureUnits, maxVertexAttribs-attribIndex[nzElementUsage_TexCoord]));
}
else
m_maxTextureUnit = 1;
NzBuffer::SetBufferFunction(nzBufferStorage_Hardware, HardwareBufferFunction);
s_initialized = true;
return true;
}
else
NazaraError("Failed to initialize utility module");
return false;
}
// Initialisation du module
if (!NzOpenGL::Initialize())
{
NazaraError("Failed to initialize OpenGL");
return false;
}
NzContext::EnsureContext();
for (unsigned int i = 0; i < totalMatrixCount; ++i)
{
s_matrix[i].MakeIdentity();
s_matrixLocation[i] = -1;
s_matrixUpdated[i] = false;
}
s_indexBuffer = nullptr;
s_shader = nullptr;
s_stencilCompare = nzRendererComparison_Always;
s_stencilFail = nzStencilOperation_Keep;
s_stencilFuncUpdated = true;
s_stencilMask = 0xFFFFFFFF;
s_stencilOpUpdated = true;
s_stencilPass = nzStencilOperation_Keep;
s_stencilReference = 0;
s_stencilZFail = nzStencilOperation_Keep;
s_target = nullptr;
s_vaoUpdated = false;
s_vertexBuffer = nullptr;
s_vertexDeclaration = nullptr;
// Récupération des capacités
s_capabilities[nzRendererCap_AnisotropicFilter] = NzOpenGL::IsSupported(NzOpenGL::AnisotropicFilter);
s_capabilities[nzRendererCap_FP64] = NzOpenGL::IsSupported(NzOpenGL::FP64);
s_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5
s_capabilities[nzRendererCap_MultipleRenderTargets] = true; // Natif depuis OpenGL 2.0
s_capabilities[nzRendererCap_OcclusionQuery] = true; // Natif depuis OpenGL 1.5
s_capabilities[nzRendererCap_PixelBufferObject] = NzOpenGL::IsSupported(NzOpenGL::PixelBufferObject);
s_capabilities[nzRendererCap_Texture3D] = NzOpenGL::IsSupported(NzOpenGL::Texture3D);
s_capabilities[nzRendererCap_TextureCubemap] = true; // Natif depuis OpenGL 1.3
s_capabilities[nzRendererCap_TextureMulti] = true; // Natif depuis OpenGL 1.3
s_capabilities[nzRendererCap_TextureNPOT] = true; // Natif depuis OpenGL 2.0
if (s_capabilities[nzRendererCap_AnisotropicFilter])
{
GLint maxAnisotropy;
glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy);
s_maxAnisotropyLevel = static_cast<unsigned int>(maxAnisotropy);
}
else
s_maxAnisotropyLevel = 1;
if (s_capabilities[nzRendererCap_MultipleRenderTargets])
{
GLint maxDrawBuffers;
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
s_maxRenderTarget = static_cast<unsigned int>(maxDrawBuffers);
}
else
s_maxRenderTarget = 1;
if (s_capabilities[nzRendererCap_TextureMulti])
{
GLint maxTextureUnits;
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTextureUnits);
GLint maxVertexAttribs;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
// Impossible de binder plus de texcoords que d'attributes (en sachant qu'un certain nombre est déjà pris par les autres attributs)
s_maxTextureUnit = static_cast<unsigned int>(std::min(maxTextureUnits, maxVertexAttribs-attribIndex[nzElementUsage_TexCoord]));
}
else
s_maxTextureUnit = 1;
NzBuffer::SetBufferFunction(nzBufferStorage_Hardware, HardwareBufferFunction);
NazaraNotice("Initialized: Renderer module");
return true;
}
bool NzRenderer::IsInitialized()
{
return s_moduleReferenceCouter != 0;
}
void NzRenderer::SetBlendFunc(nzBlendFunc src, nzBlendFunc dest)
@@ -524,22 +590,43 @@ bool NzRenderer::SetIndexBuffer(const NzIndexBuffer* indexBuffer)
}
#endif
if (indexBuffer != m_indexBuffer)
if (s_indexBuffer != indexBuffer)
{
m_indexBuffer = indexBuffer;
m_vaoUpdated = false;
s_indexBuffer = indexBuffer;
s_vaoUpdated = false;
}
return true;
}
void NzRenderer::SetMatrix(nzMatrixType type, const NzMatrix4f& matrix)
{
s_matrix[type] = matrix;
// Cas particulier, la matrice projection doit être inversée sur l'axe Y à cause des conventions d'OpenGL
if (type == nzMatrixType_Projection)
s_matrix[type] *= NzMatrix4f::Scale(NzVector3f(1.f, -1.f, 1.f));
// Invalidation des combinaisons
switch (type)
{
case nzMatrixType_View:
case nzMatrixType_World:
s_matrixUpdated[nzMatrixCombination_WorldView] = false;
case nzMatrixType_Projection:
s_matrixUpdated[nzMatrixCombination_WorldViewProj] = false;
s_matrixUpdated[nzMatrixCombination_ViewProj] = false;
break;
}
}
bool NzRenderer::SetShader(NzShader* shader)
{
if (shader == m_shader)
if (s_shader == shader)
return true;
if (m_shader)
m_shader->m_impl->Unbind();
if (s_shader)
s_shader->m_impl->Unbind();
if (shader)
{
@@ -547,7 +634,7 @@ bool NzRenderer::SetShader(NzShader* shader)
if (!shader->IsCompiled())
{
NazaraError("Shader is not compiled");
m_shader = nullptr;
shader = nullptr;
return false;
}
@@ -556,78 +643,87 @@ bool NzRenderer::SetShader(NzShader* shader)
if (!shader->m_impl->Bind())
{
NazaraError("Failed to bind shader");
m_shader = nullptr;
shader = nullptr;
return false;
}
// Récupération des indices des variables uniformes (-1 si la variable n'existe pas)
s_matrixLocation[nzMatrixType_Projection] = shader->GetUniformLocation("ProjMatrix");
s_matrixLocation[nzMatrixType_View] = shader->GetUniformLocation("ViewMatrix");
s_matrixLocation[nzMatrixType_World] = shader->GetUniformLocation("WorldMatrix");
s_matrixLocation[nzMatrixCombination_ViewProj] = shader->GetUniformLocation("ViewProjMatrix");
s_matrixLocation[nzMatrixCombination_WorldView] = shader->GetUniformLocation("WorldViewMatrix");
s_matrixLocation[nzMatrixCombination_WorldViewProj] = shader->GetUniformLocation("WorldViewProjMatrix");
}
m_shader = shader;
s_shader = shader;
return true;
}
void NzRenderer::SetStencilCompareFunction(nzRendererComparison compareFunc)
{
if (compareFunc != m_stencilCompare)
if (compareFunc != s_stencilCompare)
{
m_stencilCompare = compareFunc;
m_stencilFuncUpdated = false;
s_stencilCompare = compareFunc;
s_stencilFuncUpdated = false;
}
}
void NzRenderer::SetStencilFailOperation(nzStencilOperation failOperation)
{
if (failOperation != m_stencilFail)
if (failOperation != s_stencilFail)
{
m_stencilFail = failOperation;
m_stencilOpUpdated = false;
s_stencilFail = failOperation;
s_stencilOpUpdated = false;
}
}
void NzRenderer::SetStencilMask(nzUInt32 mask)
{
if (mask != m_stencilMask)
if (mask != s_stencilMask)
{
m_stencilMask = mask;
m_stencilFuncUpdated = false;
s_stencilMask = mask;
s_stencilFuncUpdated = false;
}
}
void NzRenderer::SetStencilPassOperation(nzStencilOperation passOperation)
{
if (passOperation != m_stencilPass)
if (passOperation != s_stencilPass)
{
m_stencilPass = passOperation;
m_stencilOpUpdated = false;
s_stencilPass = passOperation;
s_stencilOpUpdated = false;
}
}
void NzRenderer::SetStencilReferenceValue(unsigned int refValue)
{
if (refValue != m_stencilReference)
if (refValue != s_stencilReference)
{
m_stencilReference = refValue;
m_stencilFuncUpdated = false;
s_stencilReference = refValue;
s_stencilFuncUpdated = false;
}
}
void NzRenderer::SetStencilZFailOperation(nzStencilOperation zfailOperation)
{
if (zfailOperation != m_stencilZFail)
if (zfailOperation != s_stencilZFail)
{
m_stencilZFail = zfailOperation;
m_stencilOpUpdated = false;
s_stencilZFail = zfailOperation;
s_stencilOpUpdated = false;
}
}
bool NzRenderer::SetTarget(NzRenderTarget* target)
{
if (target == m_target)
if (s_target == target)
return true;
if (m_target && !m_target->HasContext())
m_target->Desactivate();
if (s_target && !target->HasContext())
s_target->Desactivate();
if (target)
{
@@ -640,17 +736,17 @@ bool NzRenderer::SetTarget(NzRenderTarget* target)
#endif
if (target->Activate())
m_target = target;
s_target = target;
else
{
NazaraError("Failed to activate target");
m_target = nullptr;
s_target = nullptr;
return false;
}
}
else
m_target = nullptr;
s_target = nullptr;
return true;
}
@@ -665,10 +761,10 @@ bool NzRenderer::SetVertexBuffer(const NzVertexBuffer* vertexBuffer)
}
#endif
if (m_vertexBuffer != vertexBuffer)
if (s_vertexBuffer != vertexBuffer)
{
m_vertexBuffer = vertexBuffer;
m_vaoUpdated = false;
s_vertexBuffer = vertexBuffer;
s_vaoUpdated = false;
}
return true;
@@ -676,10 +772,10 @@ bool NzRenderer::SetVertexBuffer(const NzVertexBuffer* vertexBuffer)
bool NzRenderer::SetVertexDeclaration(const NzVertexDeclaration* vertexDeclaration)
{
if (m_vertexDeclaration != vertexDeclaration)
if (s_vertexDeclaration != vertexDeclaration)
{
m_vertexDeclaration = vertexDeclaration;
m_vaoUpdated = false;
s_vertexDeclaration = vertexDeclaration;
s_vaoUpdated = false;
}
return true;
@@ -695,16 +791,16 @@ void NzRenderer::SetViewport(const NzRectui& viewport)
}
#endif
unsigned int height = m_target->GetHeight();
unsigned int height = s_target->GetHeight();
#if NAZARA_RENDERER_SAFE
if (!m_target)
if (!s_target)
{
NazaraError("Renderer has no target");
return;
}
unsigned int width = m_target->GetWidth();
unsigned int width = s_target->GetWidth();
if (viewport.x+viewport.width > width || viewport.y+viewport.height > height)
{
NazaraError("Rectangle dimensions are out of bounds");
@@ -718,20 +814,14 @@ void NzRenderer::SetViewport(const NzRectui& viewport)
void NzRenderer::Uninitialize()
{
#if NAZARA_RENDERER_SAFE
if (!s_initialized)
{
NazaraError("Renderer not initialized");
return;
}
#endif
if (--s_moduleReferenceCouter != 0)
return; // Encore utili
// Libération du module
NzContext::EnsureContext();
s_initialized = false;
// Libération des VAOs
for (auto it = m_vaos.begin(); it != m_vaos.end(); ++it)
for (auto it = s_vaos.begin(); it != s_vaos.end(); ++it)
{
GLuint vao = static_cast<GLuint>(it->second);
glDeleteVertexArrays(1, &vao);
@@ -739,26 +829,10 @@ void NzRenderer::Uninitialize()
NzOpenGL::Uninitialize();
if (m_utilityModule)
{
delete m_utilityModule;
m_utilityModule = nullptr;
}
}
NazaraNotice("Uninitialized: Renderer module");
NzRenderer* NzRenderer::Instance()
{
#if defined(NAZARA_DEBUG)
if (!s_instance)
NazaraError("Renderer not instanced");
#endif
return s_instance;
}
bool NzRenderer::IsInitialized()
{
return s_initialized;
// Libération des dépendances
NzUtility::Uninitialize();
}
bool NzRenderer::EnsureStateUpdate()
@@ -771,28 +845,76 @@ bool NzRenderer::EnsureStateUpdate()
}
#endif
if (!m_stencilFuncUpdated)
#if NAZARA_RENDERER_SAFE
if (!s_shader)
{
glStencilFunc(rendererComparison[m_stencilCompare], m_stencilReference, m_stencilMask);
m_stencilFuncUpdated = true;
NazaraError("No shader");
return false;
}
#endif
// Il est plus rapide d'opérer sur l'implémentation du shader directement
NzShaderImpl* shaderImpl = s_shader->m_impl;
if (!shaderImpl->BindTextures())
NazaraWarning("Failed to bind textures");
for (unsigned int i = 0; i <= nzMatrixType_Max; ++i)
{
if (!s_matrixUpdated[i])
{
shaderImpl->SendMatrix(s_matrixLocation[i], s_matrix[i]);
s_matrixUpdated[i] = true;
}
}
if (!m_stencilOpUpdated)
// Cas spéciaux car il faut recalculer la matrice
if (!s_matrixUpdated[nzMatrixCombination_ViewProj])
{
glStencilOp(stencilOperation[m_stencilFail], stencilOperation[m_stencilZFail], stencilOperation[m_stencilPass]);
m_stencilOpUpdated = true;
s_matrix[nzMatrixCombination_ViewProj] = s_matrix[nzMatrixType_View] * s_matrix[nzMatrixType_Projection];
shaderImpl->SendMatrix(s_matrixLocation[nzMatrixCombination_ViewProj], s_matrix[nzMatrixCombination_ViewProj]);
s_matrixUpdated[nzMatrixCombination_ViewProj] = true;
}
if (!m_vaoUpdated)
if (!s_matrixUpdated[nzMatrixCombination_WorldView])
{
s_matrix[nzMatrixCombination_WorldView] = NzMatrix4f::ConcatenateAffine(s_matrix[nzMatrixType_World], s_matrix[nzMatrixType_View]);
shaderImpl->SendMatrix(s_matrixLocation[nzMatrixCombination_WorldView], s_matrix[nzMatrixCombination_WorldView]);
s_matrixUpdated[nzMatrixCombination_WorldView] = true;
}
if (!s_matrixUpdated[nzMatrixCombination_WorldViewProj])
{
s_matrix[nzMatrixCombination_WorldViewProj] = s_matrix[nzMatrixCombination_WorldView] * s_matrix[nzMatrixType_Projection];
shaderImpl->SendMatrix(s_matrixLocation[nzMatrixCombination_WorldViewProj], s_matrix[nzMatrixCombination_WorldViewProj]);
s_matrixUpdated[nzMatrixCombination_WorldViewProj] = true;
}
if (!s_stencilFuncUpdated)
{
glStencilFunc(rendererComparison[s_stencilCompare], s_stencilReference, s_stencilMask);
s_stencilFuncUpdated = true;
}
if (!s_stencilOpUpdated)
{
glStencilOp(stencilOperation[s_stencilFail], stencilOperation[s_stencilZFail], stencilOperation[s_stencilPass]);
s_stencilOpUpdated = true;
}
if (!s_vaoUpdated)
{
#if NAZARA_RENDERER_SAFE
if (!m_vertexBuffer)
if (!s_vertexBuffer)
{
NazaraError("No vertex buffer");
return false;
}
if (!m_vertexDeclaration)
if (!s_vertexDeclaration)
{
NazaraError("No vertex declaration");
return false;
@@ -809,16 +931,16 @@ bool NzRenderer::EnsureStateUpdate()
// On recherche si un VAO existe déjà avec notre configuration
// Note: Les VAOs ne sont pas partagés entre les contextes, ces derniers font donc partie de notre configuration
auto key = std::make_tuple(NzContext::GetCurrent(), m_indexBuffer, m_vertexBuffer, m_vertexDeclaration);
auto it = m_vaos.find(key);
if (it == m_vaos.end())
auto key = std::make_tuple(NzContext::GetCurrent(), s_indexBuffer, s_vertexBuffer, s_vertexDeclaration);
auto it = s_vaos.find(key);
if (it == s_vaos.end())
{
// On créé notre VAO
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// On l'ajoute à notre liste
m_vaos.insert(std::make_pair(key, static_cast<unsigned int>(vao)));
s_vaos.insert(std::make_pair(key, static_cast<unsigned int>(vao)));
// Et on indique qu'on veut le programmer
update = true;
@@ -836,15 +958,15 @@ bool NzRenderer::EnsureStateUpdate()
if (update)
{
NzHardwareBuffer* vertexBuffer = static_cast<NzHardwareBuffer*>(m_vertexBuffer->GetBuffer()->GetImpl());
vertexBuffer->Bind();
NzHardwareBuffer* vertexBufferImpl = static_cast<NzHardwareBuffer*>(s_vertexBuffer->GetBuffer()->GetImpl());
vertexBufferImpl->Bind();
const nzUInt8* buffer = reinterpret_cast<const nzUInt8*>(m_vertexBuffer->GetPointer());
const nzUInt8* buffer = reinterpret_cast<const nzUInt8*>(s_vertexBuffer->GetPointer());
unsigned int stride = m_vertexDeclaration->GetStride(nzElementStream_VertexData);
unsigned int stride = s_vertexDeclaration->GetStride(nzElementStream_VertexData);
for (unsigned int i = 0; i <= nzElementUsage_Max; ++i)
{
const NzVertexElement* element = m_vertexDeclaration->GetElement(nzElementStream_VertexData, static_cast<nzElementUsage>(i));
const NzVertexElement* element = s_vertexDeclaration->GetElement(nzElementStream_VertexData, static_cast<nzElementUsage>(i));
if (element)
{
@@ -860,10 +982,10 @@ bool NzRenderer::EnsureStateUpdate()
glDisableVertexAttribArray(attribIndex[i]);
}
if (m_indexBuffer)
if (s_indexBuffer)
{
NzHardwareBuffer* indexBuffer = static_cast<NzHardwareBuffer*>(m_indexBuffer->GetBuffer()->GetImpl());
indexBuffer->Bind();
NzHardwareBuffer* indexBufferImpl = static_cast<NzHardwareBuffer*>(s_indexBuffer->GetBuffer()->GetImpl());
indexBufferImpl->Bind();
}
}
@@ -877,11 +999,10 @@ bool NzRenderer::EnsureStateUpdate()
glBindVertexArray(vao);
}
m_vaoUpdated = true;
s_vaoUpdated = true;
}
return true;
}
NzRenderer* NzRenderer::s_instance = nullptr;
bool NzRenderer::s_initialized = false;
unsigned int NzRenderer::s_moduleReferenceCouter = 0;