Greatly improved Renderer
Separated Viewport from Scissor rect Improved performances Removed Lock/Unlock system from Shader/Texture class Former-commit-id: f54bca6de58fe9d495d9192dc0d761f92594ee86
This commit is contained in:
parent
76c19624d8
commit
4f3060a40d
|
|
@ -113,9 +113,10 @@ enum nzRendererParameter
|
|||
nzRendererParameter_DepthTest,
|
||||
nzRendererParameter_DepthWrite,
|
||||
nzRendererParameter_FaceCulling,
|
||||
nzRendererParameter_Stencil,
|
||||
nzRendererParameter_ScissorTest,
|
||||
nzRendererParameter_StencilTest,
|
||||
|
||||
nzRendererParameter_Max = nzRendererParameter_Stencil
|
||||
nzRendererParameter_Max = nzRendererParameter_StencilTest
|
||||
};
|
||||
|
||||
enum nzSamplerFilter
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class NAZARA_API NzOpenGL
|
|||
enum FormatType
|
||||
{
|
||||
FormatType_RenderBuffer,
|
||||
// FormatType_MultisampleTexture,
|
||||
// FormatType_MultisampleTexture,
|
||||
FormatType_Texture
|
||||
};
|
||||
|
||||
|
|
@ -65,15 +65,33 @@ class NAZARA_API NzOpenGL
|
|||
NzOpenGL() = delete;
|
||||
~NzOpenGL() = delete;
|
||||
|
||||
static void BindBuffer(nzBufferType type, GLuint id);
|
||||
static void BindProgram(GLuint id);
|
||||
static void BindTexture(nzImageType type, GLuint id);
|
||||
|
||||
static void DeleteBuffer(nzBufferType type, GLuint id);
|
||||
static void DeleteProgram(GLuint id);
|
||||
static void DeleteTexture(GLuint id);
|
||||
|
||||
static GLuint GetCurrentBuffer(nzBufferType type);
|
||||
static GLuint GetCurrentProgram();
|
||||
static GLuint GetCurrentTexture();
|
||||
static NzOpenGLFunc GetEntry(const NzString& entryPoint);
|
||||
static NzString GetRendererName();
|
||||
static unsigned int GetTextureUnit();
|
||||
static NzString GetVendorName();
|
||||
static unsigned int GetVersion();
|
||||
|
||||
static bool Initialize();
|
||||
|
||||
static bool IsInitialized();
|
||||
static bool IsSupported(nzOpenGLExtension extension);
|
||||
static bool IsSupported(const NzString& string);
|
||||
|
||||
static void SetTextureUnit(unsigned int textureUnit);
|
||||
|
||||
static bool TranslateFormat(nzPixelFormat pixelFormat, Format* format, FormatType target);
|
||||
|
||||
static void Uninitialize();
|
||||
|
||||
static GLenum Attachment[nzAttachmentPoint_Max+1];
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ class NAZARA_API NzRenderer
|
|||
static unsigned int GetMaxRenderTargets();
|
||||
static unsigned int GetMaxTextureUnits();
|
||||
static float GetPointSize();
|
||||
static NzRectui GetScissorRect();
|
||||
static const NzShader* GetShader();
|
||||
static const NzRenderTarget* GetTarget();
|
||||
static NzRectui GetViewport();
|
||||
|
|
@ -72,12 +73,13 @@ class NAZARA_API NzRenderer
|
|||
static void SetDepthFunc(nzRendererComparison compareFunc);
|
||||
static void SetFaceCulling(nzFaceCulling cullingMode);
|
||||
static void SetFaceFilling(nzFaceFilling fillingMode);
|
||||
static bool SetIndexBuffer(const NzIndexBuffer* indexBuffer);
|
||||
static void SetIndexBuffer(const NzIndexBuffer* indexBuffer);
|
||||
static void SetInstancingData(const InstancingData* instancingData, unsigned int instanceCount);
|
||||
static void SetLineWidth(float size);
|
||||
static void SetMatrix(nzMatrixType type, const NzMatrix4f& matrix);
|
||||
static void SetPointSize(float size);
|
||||
static bool SetShader(const NzShader* shader);
|
||||
static void SetScissorRect(const NzRectui& viewport);
|
||||
static void SetShader(const NzShader* shader);
|
||||
static void SetStencilCompareFunction(nzRendererComparison compareFunc);
|
||||
static void SetStencilFailOperation(nzStencilOperation failOperation);
|
||||
static void SetStencilMask(nzUInt32 mask);
|
||||
|
|
@ -87,13 +89,14 @@ class NAZARA_API NzRenderer
|
|||
static bool SetTarget(const NzRenderTarget* target);
|
||||
static void SetTexture(nzUInt8 unit, const NzTexture* texture);
|
||||
static void SetTextureSampler(nzUInt8 textureUnit, const NzTextureSampler& sampler);
|
||||
static bool SetVertexBuffer(const NzVertexBuffer* vertexBuffer);
|
||||
static void SetVertexBuffer(const NzVertexBuffer* vertexBuffer);
|
||||
static void SetViewport(const NzRectui& viewport);
|
||||
|
||||
static void Uninitialize();
|
||||
|
||||
private:
|
||||
static bool EnsureStateUpdate(bool instancing);
|
||||
static void EnableInstancing(bool instancing);
|
||||
static bool EnsureStateUpdate();
|
||||
|
||||
static unsigned int s_moduleReferenceCounter;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -57,8 +57,6 @@ class NAZARA_API NzShader : public NzResource, NzNonCopyable
|
|||
bool Load(nzShaderType type, const NzString& source);
|
||||
bool LoadFromFile(nzShaderType type, const NzString& source);
|
||||
|
||||
bool Lock();
|
||||
|
||||
bool SendBoolean(int location, bool value) const;
|
||||
bool SendColor(int location, const NzColor& color) const;
|
||||
bool SendDouble(int location, double value) const;
|
||||
|
|
@ -76,8 +74,6 @@ class NAZARA_API NzShader : public NzResource, NzNonCopyable
|
|||
|
||||
void SetFlags(nzUInt32 flags);
|
||||
|
||||
void Unlock();
|
||||
|
||||
NzShader& operator=(NzShader&& shader);
|
||||
|
||||
static bool IsLanguageSupported(nzShaderLanguage language);
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ class NAZARA_API NzTexture : public NzResource, NzNonCopyable
|
|||
explicit NzTexture(const NzImage& image);
|
||||
~NzTexture();
|
||||
|
||||
bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1, bool lock = false);
|
||||
bool Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth = 1, nzUInt8 levelCount = 1);
|
||||
void Destroy();
|
||||
|
||||
bool Download(NzImage* image) const;
|
||||
|
|
@ -72,8 +72,6 @@ class NAZARA_API NzTexture : public NzResource, NzNonCopyable
|
|||
bool LoadFaceFromMemory(nzCubemapFace face, const void* data, std::size_t size, const NzImageParams& params = NzImageParams());
|
||||
bool LoadFaceFromStream(nzCubemapFace face, NzInputStream& stream, const NzImageParams& params = NzImageParams());
|
||||
|
||||
bool Lock();
|
||||
|
||||
bool SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel);
|
||||
|
||||
bool Update(const NzImage& image, nzUInt8 level = 0);
|
||||
|
|
@ -87,8 +85,6 @@ class NAZARA_API NzTexture : public NzResource, NzNonCopyable
|
|||
bool UpdateFace(nzCubemapFace face, const nzUInt8* pixels, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0);
|
||||
bool UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRectui& rect, unsigned int srcWidth = 0, unsigned int srcHeight = 0, nzUInt8 level = 0);
|
||||
|
||||
void Unlock();
|
||||
|
||||
// Fonctions OpenGL
|
||||
bool Bind() const;
|
||||
unsigned int GetOpenGLID() const;
|
||||
|
|
|
|||
|
|
@ -130,11 +130,7 @@ void NzDebugDrawer::Draw(const NzCubef& cube)
|
|||
|
||||
const NzShader* oldShader = NzRenderer::GetShader();
|
||||
|
||||
if (!NzRenderer::SetShader(shader))
|
||||
{
|
||||
NazaraError("Failed to set debug shader");
|
||||
return;
|
||||
}
|
||||
NzRenderer::SetShader(shader);
|
||||
|
||||
bool depthTestActive = NzRenderer::IsEnabled(nzRendererParameter_DepthTest);
|
||||
if (depthTestActive != depthTest)
|
||||
|
|
@ -154,8 +150,7 @@ void NzDebugDrawer::Draw(const NzCubef& cube)
|
|||
if (depthTestActive != depthTest)
|
||||
NzRenderer::Enable(nzRendererParameter_DepthTest, depthTestActive);
|
||||
|
||||
if (!NzRenderer::SetShader(oldShader))
|
||||
NazaraWarning("Failed to reset shader");
|
||||
NzRenderer::SetShader(oldShader);
|
||||
}
|
||||
|
||||
void NzDebugDrawer::Draw(const NzCubeui& cube)
|
||||
|
|
@ -238,11 +233,7 @@ void NzDebugDrawer::Draw(const NzFrustumf& frustum)
|
|||
|
||||
const NzShader* oldShader = NzRenderer::GetShader();
|
||||
|
||||
if (!NzRenderer::SetShader(shader))
|
||||
{
|
||||
NazaraError("Failed to set debug shader");
|
||||
return;
|
||||
}
|
||||
NzRenderer::SetShader(shader);
|
||||
|
||||
bool depthTestActive = NzRenderer::IsEnabled(nzRendererParameter_DepthTest);
|
||||
if (depthTestActive != depthTest)
|
||||
|
|
@ -262,8 +253,7 @@ void NzDebugDrawer::Draw(const NzFrustumf& frustum)
|
|||
if (depthTestActive != depthTest)
|
||||
NzRenderer::Enable(nzRendererParameter_DepthTest, depthTestActive);
|
||||
|
||||
if (!NzRenderer::SetShader(oldShader))
|
||||
NazaraWarning("Failed to reset shader");
|
||||
NzRenderer::SetShader(oldShader);
|
||||
}
|
||||
|
||||
void NzDebugDrawer::Draw(const NzOrientedCubef& orientedCube)
|
||||
|
|
@ -341,11 +331,7 @@ void NzDebugDrawer::Draw(const NzOrientedCubef& orientedCube)
|
|||
|
||||
const NzShader* oldShader = NzRenderer::GetShader();
|
||||
|
||||
if (!NzRenderer::SetShader(shader))
|
||||
{
|
||||
NazaraError("Failed to set debug shader");
|
||||
return;
|
||||
}
|
||||
NzRenderer::SetShader(shader);
|
||||
|
||||
bool depthTestActive = NzRenderer::IsEnabled(nzRendererParameter_DepthTest);
|
||||
if (depthTestActive != depthTest)
|
||||
|
|
@ -365,8 +351,7 @@ void NzDebugDrawer::Draw(const NzOrientedCubef& orientedCube)
|
|||
if (depthTestActive != depthTest)
|
||||
NzRenderer::Enable(nzRendererParameter_DepthTest, depthTestActive);
|
||||
|
||||
if (!NzRenderer::SetShader(oldShader))
|
||||
NazaraWarning("Failed to reset shader");
|
||||
NzRenderer::SetShader(oldShader);
|
||||
}
|
||||
|
||||
void NzDebugDrawer::Draw(const NzSkeleton* skeleton)
|
||||
|
|
@ -410,11 +395,7 @@ void NzDebugDrawer::Draw(const NzSkeleton* skeleton)
|
|||
{
|
||||
const NzShader* oldShader = NzRenderer::GetShader();
|
||||
|
||||
if (!NzRenderer::SetShader(shader))
|
||||
{
|
||||
NazaraError("Failed to set debug shader");
|
||||
return;
|
||||
}
|
||||
NzRenderer::SetShader(shader);
|
||||
|
||||
bool depthTestActive = NzRenderer::IsEnabled(nzRendererParameter_DepthTest);
|
||||
if (depthTestActive != depthTest)
|
||||
|
|
@ -440,8 +421,7 @@ void NzDebugDrawer::Draw(const NzSkeleton* skeleton)
|
|||
if (depthTestActive != depthTest)
|
||||
NzRenderer::Enable(nzRendererParameter_DepthTest, depthTestActive);
|
||||
|
||||
if (!NzRenderer::SetShader(oldShader))
|
||||
NazaraWarning("Failed to reset shader");
|
||||
NzRenderer::SetShader(oldShader);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -12,12 +12,6 @@
|
|||
#include <Nazara/Utility/VertexDeclaration.hpp>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
GLuint lockedPrevious = 0;
|
||||
nzUInt8 lockedLevel = 0;
|
||||
}
|
||||
|
||||
NzGLSLShader::NzGLSLShader(NzShader* parent) :
|
||||
m_parent(parent)
|
||||
{
|
||||
|
|
@ -25,14 +19,6 @@ m_parent(parent)
|
|||
|
||||
bool NzGLSLShader::Bind()
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (lockedLevel > 0)
|
||||
{
|
||||
NazaraError("Cannot bind shader while a shader is locked");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
|
|
@ -41,7 +27,7 @@ bool NzGLSLShader::Bind()
|
|||
}
|
||||
#endif
|
||||
|
||||
glUseProgram(m_program);
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -160,8 +146,7 @@ void NzGLSLShader::Destroy()
|
|||
glDeleteShader(shader);
|
||||
}
|
||||
|
||||
if (m_program)
|
||||
glDeleteProgram(m_program);
|
||||
NzOpenGL::DeleteProgram(m_program);
|
||||
}
|
||||
|
||||
NzString NzGLSLShader::GetLog() const
|
||||
|
|
@ -270,38 +255,14 @@ bool NzGLSLShader::Load(nzShaderType type, const NzString& source)
|
|||
}
|
||||
}
|
||||
|
||||
bool NzGLSLShader::Lock()
|
||||
{
|
||||
if (lockedLevel++ == 0)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLint previous;
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, &previous);
|
||||
|
||||
lockedPrevious = previous;
|
||||
|
||||
if (lockedPrevious != m_program)
|
||||
glUseProgram(m_program);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzGLSLShader::SendBoolean(int location, bool value)
|
||||
{
|
||||
if (glProgramUniform1i)
|
||||
glProgramUniform1i(m_program, location, value);
|
||||
else
|
||||
{
|
||||
if (!Lock())
|
||||
{
|
||||
NazaraError("Failed to lock shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
glUniform1i(location, value);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -315,14 +276,8 @@ bool NzGLSLShader::SendColor(int location, const NzColor& color)
|
|||
glProgramUniform4fv(m_program, location, 1, vecColor);
|
||||
else
|
||||
{
|
||||
if (!Lock())
|
||||
{
|
||||
NazaraError("Failed to lock shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
glUniform4fv(location, 1, vecColor);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -334,14 +289,8 @@ bool NzGLSLShader::SendDouble(int location, double value)
|
|||
glProgramUniform1d(m_program, location, value);
|
||||
else
|
||||
{
|
||||
if (!Lock())
|
||||
{
|
||||
NazaraError("Failed to lock shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
glUniform1d(location, value);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -353,14 +302,8 @@ bool NzGLSLShader::SendFloat(int location, float value)
|
|||
glProgramUniform1f(m_program, location, value);
|
||||
else
|
||||
{
|
||||
if (!Lock())
|
||||
{
|
||||
NazaraError("Failed to lock shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
glUniform1f(location, value);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -372,14 +315,8 @@ bool NzGLSLShader::SendInteger(int location, int value)
|
|||
glProgramUniform1i(m_program, location, value);
|
||||
else
|
||||
{
|
||||
if (!Lock())
|
||||
{
|
||||
NazaraError("Failed to lock shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
glUniform1i(location, value);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -391,14 +328,8 @@ bool NzGLSLShader::SendMatrix(int location, const NzMatrix4d& matrix)
|
|||
glProgramUniformMatrix4dv(m_program, location, 1, GL_FALSE, matrix);
|
||||
else
|
||||
{
|
||||
if (!Lock())
|
||||
{
|
||||
NazaraError("Failed to lock shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
glUniformMatrix4dv(location, 1, GL_FALSE, matrix);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -410,14 +341,8 @@ bool NzGLSLShader::SendMatrix(int location, const NzMatrix4f& matrix)
|
|||
glProgramUniformMatrix4fv(m_program, location, 1, GL_FALSE, matrix);
|
||||
else
|
||||
{
|
||||
if (!Lock())
|
||||
{
|
||||
NazaraError("Failed to lock shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
glUniformMatrix4fv(location, 1, GL_FALSE, matrix);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -495,14 +420,8 @@ bool NzGLSLShader::SendTexture(int location, const NzTexture* texture, nzUInt8*
|
|||
glProgramUniform1i(m_program, location, unit);
|
||||
else
|
||||
{
|
||||
if (!Lock())
|
||||
{
|
||||
NazaraError("Failed to lock shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
glUniform1i(location, unit);
|
||||
Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -522,14 +441,8 @@ bool NzGLSLShader::SendVector(int location, const NzVector2d& vector)
|
|||
glProgramUniform2dv(m_program, location, 1, vector);
|
||||
else
|
||||
{
|
||||
if (!Lock())
|
||||
{
|
||||
NazaraError("Failed to lock shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
glUniform2dv(location, 1, vector);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -541,14 +454,8 @@ bool NzGLSLShader::SendVector(int location, const NzVector2f& vector)
|
|||
glProgramUniform2fv(m_program, location, 1, vector);
|
||||
else
|
||||
{
|
||||
if (!Lock())
|
||||
{
|
||||
NazaraError("Failed to lock shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
glUniform2fv(location, 1, vector);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -560,14 +467,8 @@ bool NzGLSLShader::SendVector(int location, const NzVector3d& vector)
|
|||
glProgramUniform3dv(m_program, location, 1, vector);
|
||||
else
|
||||
{
|
||||
if (!Lock())
|
||||
{
|
||||
NazaraError("Failed to lock shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
glUniform3dv(location, 1, vector);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -579,14 +480,8 @@ bool NzGLSLShader::SendVector(int location, const NzVector3f& vector)
|
|||
glProgramUniform3fv(m_program, location, 1, vector);
|
||||
else
|
||||
{
|
||||
if (!Lock())
|
||||
{
|
||||
NazaraError("Failed to lock shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
glUniform3fv(location, 1, vector);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -598,14 +493,8 @@ bool NzGLSLShader::SendVector(int location, const NzVector4d& vector)
|
|||
glProgramUniform4dv(m_program, location, 1, vector);
|
||||
else
|
||||
{
|
||||
if (!Lock())
|
||||
{
|
||||
NazaraError("Failed to lock shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
glUniform4dv(location, 1, vector);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -617,54 +506,13 @@ bool NzGLSLShader::SendVector(int location, const NzVector4f& vector)
|
|||
glProgramUniform4fv(m_program, location, 1, vector);
|
||||
else
|
||||
{
|
||||
if (!Lock())
|
||||
{
|
||||
NazaraError("Failed to lock shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzOpenGL::BindProgram(m_program);
|
||||
glUniform4fv(location, 1, vector);
|
||||
Unlock();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzGLSLShader::Unbind()
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
void NzGLSLShader::Unlock()
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (lockedLevel == 0)
|
||||
{
|
||||
NazaraWarning("Unlock called on non-locked texture");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (--lockedLevel == 0 && lockedPrevious != m_program)
|
||||
glUseProgram(lockedPrevious);
|
||||
}
|
||||
|
||||
void NzGLSLShader::OnResourceCreated(const NzResource* resource, int index)
|
||||
{
|
||||
NazaraUnused(resource);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ class NzGLSLShader : public NzShaderImpl, NzResourceListener
|
|||
bool IsLoaded(nzShaderType type) const;
|
||||
|
||||
bool Load(nzShaderType type, const NzString& source);
|
||||
bool Lock();
|
||||
|
||||
bool SendBoolean(int location, bool value);
|
||||
bool SendColor(int location, const NzColor& color);
|
||||
|
|
@ -55,9 +54,6 @@ class NzGLSLShader : public NzShaderImpl, NzResourceListener
|
|||
bool SendVector(int location, const NzVector4d& vector);
|
||||
bool SendVector(int location, const NzVector4f& vector);
|
||||
|
||||
void Unbind();
|
||||
void Unlock();
|
||||
|
||||
private:
|
||||
void OnResourceCreated(const NzResource* resource, int index) override;
|
||||
void OnResourceDestroy(const NzResource* resource, int index) override;
|
||||
|
|
|
|||
|
|
@ -86,16 +86,9 @@ bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage)
|
|||
m_buffer = 0;
|
||||
glGenBuffers(1, &m_buffer);
|
||||
|
||||
GLint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], &previous);
|
||||
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||
NzOpenGL::BindBuffer(m_type, m_buffer);
|
||||
glBufferData(NzOpenGL::BufferTarget[m_type], size, nullptr, NzOpenGL::BufferUsage[usage]);
|
||||
|
||||
// Pour ne pas perturber le rendu, on n'interfère pas avec le binding déjà présent
|
||||
if (previous != 0)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +96,7 @@ void NzHardwareBuffer::Destroy()
|
|||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
glDeleteBuffers(1, &m_buffer);
|
||||
NzOpenGL::DeleteBuffer(m_type, m_buffer);
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size, bool forceDiscard)
|
||||
|
|
@ -115,11 +108,7 @@ bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
|
|||
if (!forceDiscard)
|
||||
forceDiscard = (size == totalSize);
|
||||
|
||||
GLuint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
if (previous != m_buffer)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||
NzOpenGL::BindBuffer(m_type, m_buffer);
|
||||
|
||||
// http://www.opengl.org/wiki/Vertex_Specification_Best_Practices
|
||||
if (forceDiscard)
|
||||
|
|
@ -151,10 +140,6 @@ bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
|
|||
}
|
||||
}
|
||||
|
||||
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -172,52 +157,28 @@ void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned
|
|||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
// Pour ne pas perturber le rendu, on n'interfère pas avec le binding déjà présent
|
||||
GLuint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
if (previous != m_buffer)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||
NzOpenGL::BindBuffer(m_type, m_buffer);
|
||||
|
||||
if (access == nzBufferAccess_DiscardAndWrite)
|
||||
glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetUsage()]); // Discard
|
||||
|
||||
void* ptr = mapBuffer(m_type, access, offset, size);
|
||||
|
||||
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return ptr;
|
||||
return mapBuffer(m_type, access, offset, size);
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::Unmap()
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLuint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
if (previous != m_buffer)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||
NzOpenGL::BindBuffer(m_type, m_buffer);
|
||||
|
||||
if (glUnmapBuffer(NzOpenGL::BufferTarget[m_type]) != GL_TRUE)
|
||||
{
|
||||
// Une erreur rare est survenue, nous devons réinitialiser le buffer
|
||||
NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
|
||||
|
||||
glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetStorage()]);
|
||||
|
||||
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
// Une erreur rare est survenue, nous devons réinitialiser le buffer
|
||||
NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérations chaînées)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <cstring>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
|
@ -58,11 +59,15 @@ namespace
|
|||
}
|
||||
|
||||
std::set<NzString> s_openGLextensionSet;
|
||||
GLuint s_buffersBinding[nzBufferType_Max+1];
|
||||
GLuint s_currentProgram;
|
||||
GLuint s_texturesBinding[32]; // 32 est pour l'instant la plus haute limite (GL_TEXTURE31)
|
||||
const char* s_rendererName = nullptr;
|
||||
const char* s_vendorName = nullptr;
|
||||
bool s_initialized = false;
|
||||
bool s_openGLextensions[nzOpenGLExtension_Max+1] = {false};
|
||||
unsigned int s_openglVersion = 0;
|
||||
unsigned int s_textureUnit = 0;
|
||||
|
||||
bool LoadExtensionsString(const NzString& extensionString)
|
||||
{
|
||||
|
|
@ -109,6 +114,64 @@ namespace
|
|||
}
|
||||
}
|
||||
|
||||
void NzOpenGL::BindBuffer(nzBufferType type, GLuint id)
|
||||
{
|
||||
if (s_buffersBinding[type] != id)
|
||||
{
|
||||
glBindBuffer(BufferTarget[type], id);
|
||||
s_buffersBinding[type] = id;
|
||||
}
|
||||
}
|
||||
|
||||
void NzOpenGL::BindProgram(GLuint id)
|
||||
{
|
||||
if (s_currentProgram != id)
|
||||
{
|
||||
glUseProgram(id);
|
||||
s_currentProgram = id;
|
||||
}
|
||||
}
|
||||
|
||||
void NzOpenGL::BindTexture(nzImageType type, GLuint id)
|
||||
{
|
||||
if (s_texturesBinding[s_textureUnit] != id)
|
||||
{
|
||||
glBindTexture(TextureTarget[type], id);
|
||||
s_texturesBinding[s_textureUnit] = id;
|
||||
}
|
||||
}
|
||||
|
||||
void NzOpenGL::DeleteBuffer(nzBufferType type, GLuint id)
|
||||
{
|
||||
glDeleteBuffers(1, &id);
|
||||
if (s_buffersBinding[type] == id)
|
||||
s_buffersBinding[type] = 0;
|
||||
}
|
||||
|
||||
void NzOpenGL::DeleteProgram(GLuint id)
|
||||
{
|
||||
glDeleteProgram(id);
|
||||
if (s_currentProgram == id)
|
||||
s_currentProgram = 0;
|
||||
}
|
||||
|
||||
void NzOpenGL::DeleteTexture(GLuint id)
|
||||
{
|
||||
glDeleteTextures(1, &id);
|
||||
if (s_texturesBinding[s_textureUnit] == id)
|
||||
s_texturesBinding[s_textureUnit] = 0;
|
||||
}
|
||||
|
||||
GLuint NzOpenGL::GetCurrentBuffer(nzBufferType type)
|
||||
{
|
||||
return s_buffersBinding[type];
|
||||
}
|
||||
|
||||
GLuint NzOpenGL::GetCurrentProgram()
|
||||
{
|
||||
return s_currentProgram;
|
||||
}
|
||||
|
||||
NzOpenGLFunc NzOpenGL::GetEntry(const NzString& entryPoint)
|
||||
{
|
||||
return LoadEntry(entryPoint.GetConstBuffer(), false);
|
||||
|
|
@ -119,6 +182,11 @@ NzString NzOpenGL::GetRendererName()
|
|||
return s_rendererName;
|
||||
}
|
||||
|
||||
unsigned int NzOpenGL::GetTextureUnit()
|
||||
{
|
||||
return s_textureUnit;
|
||||
}
|
||||
|
||||
NzString NzOpenGL::GetVendorName()
|
||||
{
|
||||
return s_vendorName;
|
||||
|
|
@ -629,7 +697,12 @@ bool NzOpenGL::Initialize()
|
|||
return false;
|
||||
}
|
||||
|
||||
std::memset(s_buffersBinding, 0, (nzBufferType_Max+1)*sizeof(GLuint));
|
||||
std::memset(s_texturesBinding, 0, 32*sizeof(GLuint));
|
||||
|
||||
s_currentProgram = 0;
|
||||
s_rendererName = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
|
||||
s_textureUnit = 0;
|
||||
s_vendorName = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
|
||||
|
||||
return true;
|
||||
|
|
@ -650,6 +723,15 @@ bool NzOpenGL::IsSupported(const NzString& string)
|
|||
return s_openGLextensionSet.find(string) != s_openGLextensionSet.end();
|
||||
}
|
||||
|
||||
void NzOpenGL::SetTextureUnit(unsigned int textureUnit)
|
||||
{
|
||||
if (s_textureUnit != textureUnit)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + textureUnit);
|
||||
s_textureUnit = textureUnit;
|
||||
}
|
||||
}
|
||||
|
||||
bool NzOpenGL::TranslateFormat(nzPixelFormat pixelFormat, Format* format, FormatType type)
|
||||
{
|
||||
switch (pixelFormat)
|
||||
|
|
@ -936,12 +1018,13 @@ GLenum NzOpenGL::RendererComparison[nzRendererComparison_Max+1] =
|
|||
|
||||
GLenum NzOpenGL::RendererParameter[nzRendererParameter_Max+1] =
|
||||
{
|
||||
GL_BLEND, // nzRendererParameter_Blend
|
||||
GL_NONE, // nzRendererParameter_ColorWrite
|
||||
GL_DEPTH_TEST, // nzRendererParameter_DepthTest
|
||||
GL_NONE, // nzRendererParameter_DepthWrite
|
||||
GL_CULL_FACE, // nzRendererParameter_FaceCulling
|
||||
GL_STENCIL_TEST // nzRendererParameter_Stencil
|
||||
GL_BLEND, // nzRendererParameter_Blend
|
||||
GL_NONE, // nzRendererParameter_ColorWrite
|
||||
GL_DEPTH_TEST, // nzRendererParameter_DepthTest
|
||||
GL_NONE, // nzRendererParameter_DepthWrite
|
||||
GL_CULL_FACE, // nzRendererParameter_FaceCulling
|
||||
GL_SCISSOR_TEST, // nzRendererParameter_ScissorTest
|
||||
GL_STENCIL_TEST // nzRendererParameter_StencilTest
|
||||
};
|
||||
|
||||
GLenum NzOpenGL::SamplerWrapMode[nzSamplerWrap_Max+1] =
|
||||
|
|
|
|||
|
|
@ -124,7 +124,7 @@ bool NzRenderWindow::CopyToTexture(NzTexture* texture) const
|
|||
|
||||
NzVector2ui size = GetSize();
|
||||
|
||||
if (!texture->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1, true))
|
||||
if (!texture->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1))
|
||||
{
|
||||
NazaraError("Failed to create texture");
|
||||
return false;
|
||||
|
|
@ -143,8 +143,6 @@ bool NzRenderWindow::CopyToTexture(NzTexture* texture) const
|
|||
m_context->SetActive(false);
|
||||
}
|
||||
|
||||
texture->Unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,13 +41,24 @@ namespace
|
|||
nzMatrixCombination_Max = nzMatrixCombination_WorldViewProj
|
||||
};
|
||||
|
||||
enum UpdateFlags
|
||||
{
|
||||
Update_None = 0,
|
||||
|
||||
Update_Matrices = 0x01,
|
||||
Update_Shader = 0x02,
|
||||
Update_StencilFunc = 0x04,
|
||||
Update_StencilOp = 0x08,
|
||||
Update_Textures = 0x10,
|
||||
Update_VAO = 0x20,
|
||||
};
|
||||
|
||||
struct TextureUnit
|
||||
{
|
||||
NzTextureSampler sampler;
|
||||
const NzTexture* texture = nullptr;
|
||||
bool samplerUpdated = false;
|
||||
bool textureUpdated = true;
|
||||
bool updated = true;
|
||||
};
|
||||
|
||||
NzBufferImpl* HardwareBufferFunction(NzBuffer* parent, nzBufferType type)
|
||||
|
|
@ -61,6 +72,7 @@ namespace
|
|||
|
||||
std::map<VAO_Key, unsigned int> s_vaos;
|
||||
std::vector<TextureUnit> s_textureUnits;
|
||||
std::vector<unsigned int> s_dirtyTextureUnits;
|
||||
NzBuffer* s_instancingBuffer = nullptr;
|
||||
NzVertexBuffer* s_quadBuffer = nullptr;
|
||||
NzMatrix4f s_matrix[totalMatrixCount];
|
||||
|
|
@ -76,18 +88,17 @@ namespace
|
|||
nzStencilOperation s_stencilZFail;
|
||||
nzUInt8 s_maxAnisotropyLevel;
|
||||
nzUInt32 s_stencilMask;
|
||||
nzUInt32 s_updateFlags;
|
||||
const NzIndexBuffer* s_indexBuffer;
|
||||
const NzRenderTarget* s_target;
|
||||
const NzShader* s_shader;
|
||||
const NzVertexBuffer* s_vertexBuffer;
|
||||
const NzVertexDeclaration* s_vertexDeclaration;
|
||||
bool s_capabilities[nzRendererCap_Max+1];
|
||||
bool s_instancing;
|
||||
bool s_matrixUpdated[totalMatrixCount];
|
||||
bool s_stencilFuncUpdated;
|
||||
bool s_stencilOpUpdated;
|
||||
bool s_useSamplerObjects;
|
||||
bool s_useVertexArrayObjects;
|
||||
bool s_vaoUpdated;
|
||||
int s_matrixLocation[totalMatrixCount];
|
||||
unsigned int s_maxRenderTarget;
|
||||
unsigned int s_maxTextureUnit;
|
||||
|
|
@ -145,7 +156,9 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!EnsureStateUpdate(false))
|
||||
EnableInstancing(false);
|
||||
|
||||
if (!EnsureStateUpdate())
|
||||
{
|
||||
NazaraError("Failed to update states");
|
||||
return;
|
||||
|
|
@ -214,7 +227,9 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!EnsureStateUpdate(true))
|
||||
EnableInstancing(true);
|
||||
|
||||
if (!EnsureStateUpdate())
|
||||
{
|
||||
NazaraError("Failed to update states");
|
||||
return;
|
||||
|
|
@ -257,7 +272,9 @@ void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVer
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!EnsureStateUpdate(false))
|
||||
EnableInstancing(false);
|
||||
|
||||
if (!EnsureStateUpdate())
|
||||
{
|
||||
NazaraError("Failed to update states");
|
||||
return;
|
||||
|
|
@ -302,7 +319,9 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!EnsureStateUpdate(true))
|
||||
EnableInstancing(true);
|
||||
|
||||
if (!EnsureStateUpdate())
|
||||
{
|
||||
NazaraError("Failed to update states");
|
||||
return;
|
||||
|
|
@ -415,13 +434,13 @@ void NzRenderer::DrawTexture(unsigned int unit, const NzRectf& rect, const NzVec
|
|||
SetShader(shader);
|
||||
SetVertexBuffer(s_quadBuffer);
|
||||
|
||||
if (!EnsureStateUpdate(true))
|
||||
if (!EnsureStateUpdate())
|
||||
{
|
||||
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));
|
||||
shader->SendMatrix(s_matrixLocation[nzMatrixCombination_WorldViewProj], NzMatrix4f::Ortho(0.f, s_targetSize.x, 0.f, s_targetSize.y, 0.f));
|
||||
|
||||
glDrawArrays(NzOpenGL::PrimitiveType[nzPrimitiveType_TriangleStrip], 0, 4);
|
||||
|
||||
|
|
@ -429,9 +448,6 @@ void NzRenderer::DrawTexture(unsigned int unit, const NzRectf& rect, const NzVec
|
|||
Enable(nzRendererParameter_FaceCulling, faceCulling);
|
||||
SetShader(oldShader);
|
||||
SetVertexBuffer(oldBuffer);
|
||||
|
||||
s_matrixUpdated[nzMatrixCombination_WorldViewProj] = false;
|
||||
s_vaoUpdated = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -577,6 +593,22 @@ float NzRenderer::GetPointSize()
|
|||
return pointSize;
|
||||
}
|
||||
|
||||
NzRectui NzRenderer::GetScissorRect()
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return NzRectui();
|
||||
}
|
||||
#endif
|
||||
|
||||
GLint params[4];
|
||||
glGetIntegerv(GL_SCISSOR_BOX, ¶ms[0]);
|
||||
|
||||
return NzRectui(params[0], params[1], params[2], params[3]);
|
||||
}
|
||||
|
||||
const NzShader* NzRenderer::GetShader()
|
||||
{
|
||||
return s_shader;
|
||||
|
|
@ -711,6 +743,7 @@ bool NzRenderer::Initialize()
|
|||
else
|
||||
s_maxTextureUnit = 1;
|
||||
|
||||
s_dirtyTextureUnits.reserve(s_maxTextureUnit);
|
||||
s_dstBlend = nzBlendFunc_Zero;
|
||||
s_faceCulling = nzFaceCulling_Back;
|
||||
s_faceFilling = nzFaceFilling_Fill;
|
||||
|
|
@ -719,9 +752,7 @@ bool NzRenderer::Initialize()
|
|||
s_srcBlend = nzBlendFunc_One;
|
||||
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;
|
||||
|
|
@ -729,9 +760,9 @@ bool NzRenderer::Initialize()
|
|||
s_textureUnits.resize(s_maxTextureUnit);
|
||||
s_useSamplerObjects = NzOpenGL::IsSupported(nzOpenGLExtension_SamplerObjects);
|
||||
s_useVertexArrayObjects = NzOpenGL::IsSupported(nzOpenGLExtension_VertexArrayObjects);
|
||||
s_vaoUpdated = false;
|
||||
s_vertexBuffer = nullptr;
|
||||
s_vertexDeclaration = nullptr;
|
||||
s_updateFlags = (Update_Matrices | Update_Shader | Update_VAO);
|
||||
|
||||
NzVertexElement elements[2];
|
||||
elements[0].offset = 0;
|
||||
|
|
@ -945,23 +976,21 @@ void NzRenderer::SetFaceFilling(nzFaceFilling fillingMode)
|
|||
}
|
||||
}
|
||||
|
||||
bool NzRenderer::SetIndexBuffer(const NzIndexBuffer* indexBuffer)
|
||||
void NzRenderer::SetIndexBuffer(const NzIndexBuffer* indexBuffer)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (indexBuffer && !indexBuffer->IsHardware() && !indexBuffer->IsSequential())
|
||||
{
|
||||
NazaraError("Buffer must be hardware");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (s_indexBuffer != indexBuffer)
|
||||
{
|
||||
s_indexBuffer = indexBuffer;
|
||||
s_vaoUpdated = false;
|
||||
s_updateFlags |= Update_VAO;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzRenderer::SetInstancingData(const NzRenderer::InstancingData* instancingData, unsigned int instanceCount)
|
||||
|
|
@ -1042,6 +1071,8 @@ void NzRenderer::SetMatrix(nzMatrixType type, const NzMatrix4f& matrix)
|
|||
s_matrixUpdated[nzMatrixCombination_WorldView] = false;
|
||||
|
||||
s_matrixUpdated[nzMatrixCombination_WorldViewProj] = false; // Toujours invalidée
|
||||
|
||||
s_updateFlags |= Update_Matrices;
|
||||
}
|
||||
|
||||
void NzRenderer::SetPointSize(float size)
|
||||
|
|
@ -1065,51 +1096,51 @@ void NzRenderer::SetPointSize(float size)
|
|||
glPointSize(size);
|
||||
}
|
||||
|
||||
bool NzRenderer::SetShader(const NzShader* shader)
|
||||
void NzRenderer::SetScissorRect(const NzRectui& rect)
|
||||
{
|
||||
if (s_shader == shader)
|
||||
return true;
|
||||
|
||||
if (s_shader)
|
||||
s_shader->m_impl->Unbind();
|
||||
|
||||
if (shader)
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!shader->IsCompiled())
|
||||
{
|
||||
NazaraError("Shader is not compiled");
|
||||
shader = nullptr;
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
unsigned int height = s_target->GetHeight();
|
||||
|
||||
if (!shader->m_impl->Bind())
|
||||
{
|
||||
NazaraError("Failed to bind shader");
|
||||
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");
|
||||
|
||||
///FIXME: Peut être optimisé
|
||||
for (unsigned int i = 0; i < totalMatrixCount; ++i)
|
||||
s_matrixUpdated[i] = false;
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!s_target)
|
||||
{
|
||||
NazaraError("Renderer has no target");
|
||||
return;
|
||||
}
|
||||
|
||||
s_shader = shader;
|
||||
unsigned int width = s_target->GetWidth();
|
||||
if (rect.x+rect.width > width || rect.y+rect.height > height)
|
||||
{
|
||||
NazaraError("Rectangle dimensions are out of bounds");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
glScissor(rect.x, height-rect.height-rect.y, rect.width, rect.height);
|
||||
}
|
||||
|
||||
void NzRenderer::SetShader(const NzShader* shader)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (shader && !shader->IsCompiled())
|
||||
{
|
||||
NazaraError("Shader is not compiled");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (s_shader != shader)
|
||||
{
|
||||
s_shader = shader;
|
||||
s_updateFlags |= Update_Shader;
|
||||
}
|
||||
}
|
||||
|
||||
void NzRenderer::SetStencilCompareFunction(nzRendererComparison compareFunc)
|
||||
|
|
@ -1125,7 +1156,7 @@ void NzRenderer::SetStencilCompareFunction(nzRendererComparison compareFunc)
|
|||
if (compareFunc != s_stencilCompare)
|
||||
{
|
||||
s_stencilCompare = compareFunc;
|
||||
s_stencilFuncUpdated = false;
|
||||
s_updateFlags |= Update_StencilFunc;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1142,7 +1173,7 @@ void NzRenderer::SetStencilFailOperation(nzStencilOperation failOperation)
|
|||
if (failOperation != s_stencilFail)
|
||||
{
|
||||
s_stencilFail = failOperation;
|
||||
s_stencilOpUpdated = false;
|
||||
s_updateFlags |= Update_StencilOp;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1151,7 +1182,7 @@ void NzRenderer::SetStencilMask(nzUInt32 mask)
|
|||
if (mask != s_stencilMask)
|
||||
{
|
||||
s_stencilMask = mask;
|
||||
s_stencilFuncUpdated = false;
|
||||
s_updateFlags |= Update_StencilFunc;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1168,7 +1199,7 @@ void NzRenderer::SetStencilPassOperation(nzStencilOperation passOperation)
|
|||
if (passOperation != s_stencilPass)
|
||||
{
|
||||
s_stencilPass = passOperation;
|
||||
s_stencilOpUpdated = false;
|
||||
s_updateFlags |= Update_StencilOp;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1177,7 +1208,7 @@ void NzRenderer::SetStencilReferenceValue(unsigned int refValue)
|
|||
if (refValue != s_stencilReference)
|
||||
{
|
||||
s_stencilReference = refValue;
|
||||
s_stencilFuncUpdated = false;
|
||||
s_updateFlags |= Update_StencilFunc;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1194,7 +1225,7 @@ void NzRenderer::SetStencilZFailOperation(nzStencilOperation zfailOperation)
|
|||
if (zfailOperation != s_stencilZFail)
|
||||
{
|
||||
s_stencilZFail = zfailOperation;
|
||||
s_stencilOpUpdated = false;
|
||||
s_updateFlags |= Update_StencilOp;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1253,9 +1284,10 @@ void NzRenderer::SetTexture(nzUInt8 unit, const NzTexture* texture)
|
|||
{
|
||||
if (s_textureUnits[unit].sampler.UseMipmaps(texture->HasMipmaps()))
|
||||
s_textureUnits[unit].samplerUpdated = false;
|
||||
|
||||
s_textureUnits[unit].updated = false;
|
||||
}
|
||||
|
||||
s_dirtyTextureUnits.push_back(unit);
|
||||
s_updateFlags |= Update_Textures;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1271,19 +1303,21 @@ void NzRenderer::SetTextureSampler(nzUInt8 unit, const NzTextureSampler& sampler
|
|||
|
||||
s_textureUnits[unit].sampler = sampler;
|
||||
s_textureUnits[unit].samplerUpdated = false;
|
||||
s_textureUnits[unit].updated = false;
|
||||
|
||||
if (s_textureUnits[unit].texture)
|
||||
s_textureUnits[unit].sampler.UseMipmaps(s_textureUnits[unit].texture->HasMipmaps());
|
||||
|
||||
s_dirtyTextureUnits.push_back(unit);
|
||||
s_updateFlags |= Update_Textures;
|
||||
}
|
||||
|
||||
bool NzRenderer::SetVertexBuffer(const NzVertexBuffer* vertexBuffer)
|
||||
void NzRenderer::SetVertexBuffer(const NzVertexBuffer* vertexBuffer)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (vertexBuffer && !vertexBuffer->IsHardware())
|
||||
{
|
||||
NazaraError("Buffer must be hardware");
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -1295,10 +1329,8 @@ bool NzRenderer::SetVertexBuffer(const NzVertexBuffer* vertexBuffer)
|
|||
if (s_vertexDeclaration != vertexDeclaration)
|
||||
s_vertexDeclaration = vertexDeclaration;
|
||||
|
||||
s_vaoUpdated = false;
|
||||
s_updateFlags |= Update_VAO;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzRenderer::SetViewport(const NzRectui& viewport)
|
||||
|
|
@ -1329,7 +1361,6 @@ void NzRenderer::SetViewport(const NzRectui& viewport)
|
|||
#endif
|
||||
|
||||
glViewport(viewport.x, height-viewport.height-viewport.y, viewport.width, viewport.height);
|
||||
glScissor(viewport.x, height-viewport.height-viewport.y, viewport.width, viewport.height);
|
||||
}
|
||||
|
||||
void NzRenderer::Uninitialize()
|
||||
|
|
@ -1381,8 +1412,20 @@ void NzRenderer::Uninitialize()
|
|||
NzUtility::Uninitialize();
|
||||
}
|
||||
|
||||
bool NzRenderer::EnsureStateUpdate(bool instancing)
|
||||
void NzRenderer::EnableInstancing(bool instancing)
|
||||
{
|
||||
if (s_instancing != instancing)
|
||||
{
|
||||
s_updateFlags |= Update_VAO;
|
||||
s_instancing = instancing;
|
||||
}
|
||||
}
|
||||
|
||||
bool NzRenderer::EnsureStateUpdate()
|
||||
{
|
||||
if (s_updateFlags == Update_None)
|
||||
return true;
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
|
|
@ -1391,30 +1434,57 @@ bool NzRenderer::EnsureStateUpdate(bool instancing)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!s_shader)
|
||||
{
|
||||
NazaraError("No shader");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
NzShaderImpl* shaderImpl;
|
||||
|
||||
// Il est plus rapide d'opérer sur l'implémentation du shader directement
|
||||
NzShaderImpl* shaderImpl = s_shader->m_impl;
|
||||
shaderImpl->BindTextures();
|
||||
|
||||
if (s_useSamplerObjects)
|
||||
if (s_updateFlags & Update_Shader)
|
||||
{
|
||||
///FIXME: Itère sur toutes les unités (Dont beaucoup inutilisées)
|
||||
for (unsigned int i = 0; i < s_textureUnits.size(); ++i)
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!s_shader)
|
||||
{
|
||||
TextureUnit& unit = s_textureUnits[i];
|
||||
NazaraError("No shader");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!unit.updated)
|
||||
// Il est plus rapide d'opérer sur l'implémentation du shader directement
|
||||
shaderImpl = s_shader->m_impl;
|
||||
shaderImpl->Bind();
|
||||
shaderImpl->BindTextures();
|
||||
|
||||
// Récupération des indices des variables uniformes (-1 si la variable n'existe pas)
|
||||
s_matrixLocation[nzMatrixType_Projection] = shaderImpl->GetUniformLocation("ProjMatrix");
|
||||
s_matrixLocation[nzMatrixType_View] = shaderImpl->GetUniformLocation("ViewMatrix");
|
||||
s_matrixLocation[nzMatrixType_World] = shaderImpl->GetUniformLocation("WorldMatrix");
|
||||
|
||||
s_matrixLocation[nzMatrixCombination_ViewProj] = shaderImpl->GetUniformLocation("ViewProjMatrix");
|
||||
s_matrixLocation[nzMatrixCombination_WorldView] = shaderImpl->GetUniformLocation("WorldViewMatrix");
|
||||
s_matrixLocation[nzMatrixCombination_WorldViewProj] = shaderImpl->GetUniformLocation("WorldViewProjMatrix");
|
||||
|
||||
s_updateFlags |= Update_Matrices;
|
||||
for (unsigned int i = 0; i < totalMatrixCount; ++i)
|
||||
{
|
||||
if (s_matrixLocation[i] != -1)
|
||||
s_matrixUpdated[i] = false;
|
||||
else
|
||||
s_matrixUpdated[i] = false;
|
||||
}
|
||||
|
||||
s_updateFlags &= ~Update_Shader;
|
||||
}
|
||||
else
|
||||
shaderImpl = s_shader->m_impl;
|
||||
|
||||
if (s_updateFlags & Update_Textures)
|
||||
{
|
||||
if (s_useSamplerObjects)
|
||||
{
|
||||
for (unsigned int i : s_dirtyTextureUnits)
|
||||
{
|
||||
TextureUnit& unit = s_textureUnits[i];
|
||||
|
||||
if (!unit.textureUpdated)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
NzOpenGL::SetTextureUnit(i);
|
||||
unit.texture->Bind();
|
||||
|
||||
unit.textureUpdated = true;
|
||||
|
|
@ -1425,83 +1495,83 @@ bool NzRenderer::EnsureStateUpdate(bool instancing)
|
|||
unit.sampler.Bind(i);
|
||||
unit.samplerUpdated = true;
|
||||
}
|
||||
|
||||
unit.updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
///FIXME: Itère sur toutes les unités (Dont beaucoup inutilisées)
|
||||
for (unsigned int i = 0; i < s_textureUnits.size(); ++i)
|
||||
else
|
||||
{
|
||||
TextureUnit& unit = s_textureUnits[i];
|
||||
|
||||
if (!unit.updated)
|
||||
for (unsigned int i : s_dirtyTextureUnits)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
TextureUnit& unit = s_textureUnits[i];
|
||||
|
||||
NzOpenGL::SetTextureUnit(i);
|
||||
|
||||
unit.texture->Bind();
|
||||
unit.textureUpdated = true;
|
||||
|
||||
unit.sampler.Apply(unit.texture);
|
||||
unit.samplerUpdated = true;
|
||||
|
||||
unit.updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
s_dirtyTextureUnits.clear(); // Ne change pas la capacité
|
||||
s_updateFlags &= ~Update_Textures;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i <= nzMatrixType_Max; ++i)
|
||||
if (s_updateFlags & Update_Matrices)
|
||||
{
|
||||
if (!s_matrixUpdated[i])
|
||||
for (unsigned int i = 0; i <= nzMatrixType_Max; ++i)
|
||||
{
|
||||
shaderImpl->SendMatrix(s_matrixLocation[i], s_matrix[i]);
|
||||
s_matrixUpdated[i] = true;
|
||||
if (!s_matrixUpdated[i])
|
||||
{
|
||||
shaderImpl->SendMatrix(s_matrixLocation[i], s_matrix[i]);
|
||||
s_matrixUpdated[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Cas spéciaux car il faut recalculer la matrice
|
||||
if (!s_matrixUpdated[nzMatrixCombination_ViewProj])
|
||||
{
|
||||
s_matrix[nzMatrixCombination_ViewProj] = s_matrix[nzMatrixType_View];
|
||||
s_matrix[nzMatrixCombination_ViewProj].Concatenate(s_matrix[nzMatrixType_Projection]);
|
||||
|
||||
shaderImpl->SendMatrix(s_matrixLocation[nzMatrixCombination_ViewProj], s_matrix[nzMatrixCombination_ViewProj]);
|
||||
s_matrixUpdated[nzMatrixCombination_ViewProj] = true;
|
||||
}
|
||||
|
||||
if (!s_matrixUpdated[nzMatrixCombination_WorldView])
|
||||
{
|
||||
s_matrix[nzMatrixCombination_WorldView] = s_matrix[nzMatrixType_World];
|
||||
s_matrix[nzMatrixCombination_WorldView].ConcatenateAffine(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[nzMatrixCombination_WorldViewProj].Concatenate(s_matrix[nzMatrixType_Projection]);
|
||||
|
||||
shaderImpl->SendMatrix(s_matrixLocation[nzMatrixCombination_WorldViewProj], s_matrix[nzMatrixCombination_WorldViewProj]);
|
||||
s_matrixUpdated[nzMatrixCombination_WorldViewProj] = true;
|
||||
}
|
||||
|
||||
s_updateFlags &= ~Update_Matrices;
|
||||
}
|
||||
|
||||
// Cas spéciaux car il faut recalculer la matrice
|
||||
if (!s_matrixUpdated[nzMatrixCombination_ViewProj])
|
||||
{
|
||||
s_matrix[nzMatrixCombination_ViewProj] = s_matrix[nzMatrixType_View];
|
||||
s_matrix[nzMatrixCombination_ViewProj].Concatenate(s_matrix[nzMatrixType_Projection]);
|
||||
|
||||
shaderImpl->SendMatrix(s_matrixLocation[nzMatrixCombination_ViewProj], s_matrix[nzMatrixCombination_ViewProj]);
|
||||
s_matrixUpdated[nzMatrixCombination_ViewProj] = true;
|
||||
}
|
||||
|
||||
if (!s_matrixUpdated[nzMatrixCombination_WorldView])
|
||||
{
|
||||
s_matrix[nzMatrixCombination_WorldView] = s_matrix[nzMatrixType_World];
|
||||
s_matrix[nzMatrixCombination_WorldView].ConcatenateAffine(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[nzMatrixCombination_WorldViewProj].Concatenate(s_matrix[nzMatrixType_Projection]);
|
||||
|
||||
shaderImpl->SendMatrix(s_matrixLocation[nzMatrixCombination_WorldViewProj], s_matrix[nzMatrixCombination_WorldViewProj]);
|
||||
s_matrixUpdated[nzMatrixCombination_WorldViewProj] = true;
|
||||
}
|
||||
|
||||
if (!s_stencilFuncUpdated)
|
||||
if (s_updateFlags & Update_StencilFunc)
|
||||
{
|
||||
glStencilFunc(NzOpenGL::RendererComparison[s_stencilCompare], s_stencilReference, s_stencilMask);
|
||||
s_stencilFuncUpdated = true;
|
||||
s_updateFlags &= ~Update_StencilFunc;
|
||||
}
|
||||
|
||||
if (!s_stencilOpUpdated)
|
||||
if (s_updateFlags & Update_StencilOp)
|
||||
{
|
||||
glStencilOp(NzOpenGL::StencilOperation[s_stencilFail], NzOpenGL::StencilOperation[s_stencilZFail], NzOpenGL::StencilOperation[s_stencilPass]);
|
||||
s_stencilOpUpdated = true;
|
||||
s_updateFlags &= ~Update_StencilOp;
|
||||
}
|
||||
|
||||
if (!s_vaoUpdated)
|
||||
if (s_updateFlags & Update_VAO)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!s_vertexBuffer)
|
||||
|
|
@ -1526,7 +1596,7 @@ bool NzRenderer::EnsureStateUpdate(bool instancing)
|
|||
// 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(), s_indexBuffer, s_vertexBuffer, s_vertexDeclaration, instancing);
|
||||
auto key = std::make_tuple(NzContext::GetCurrent(), s_indexBuffer, s_vertexBuffer, s_vertexDeclaration, s_instancing);
|
||||
auto it = s_vaos.find(key);
|
||||
if (it == s_vaos.end())
|
||||
{
|
||||
|
|
@ -1577,7 +1647,7 @@ bool NzRenderer::EnsureStateUpdate(bool instancing)
|
|||
glDisableVertexAttribArray(NzOpenGL::AttributeIndex[i]);
|
||||
}
|
||||
|
||||
if (instancing)
|
||||
if (s_instancing)
|
||||
{
|
||||
static_cast<NzHardwareBuffer*>(s_instancingBuffer->GetImpl())->Bind();
|
||||
|
||||
|
|
@ -1611,9 +1681,14 @@ bool NzRenderer::EnsureStateUpdate(bool instancing)
|
|||
glBindVertexArray(vao);
|
||||
}
|
||||
|
||||
s_vaoUpdated = true;
|
||||
s_updateFlags &= ~Update_VAO;
|
||||
}
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (s_updateFlags != Update_None)
|
||||
NazaraWarning("Update flags not fully cleared");
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -298,19 +298,6 @@ bool NzShader::LoadFromFile(nzShaderType type, const NzString& filePath)
|
|||
return m_impl->Load(type, source);
|
||||
}
|
||||
|
||||
bool NzShader::Lock()
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Shader not created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->Lock();
|
||||
}
|
||||
|
||||
bool NzShader::SendBoolean(int location, bool value) const
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
|
|
@ -612,19 +599,6 @@ void NzShader::SetFlags(nzUInt32 flags)
|
|||
m_flags = flags;
|
||||
}
|
||||
|
||||
void NzShader::Unlock()
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Shader not created");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
return m_impl->Unlock();
|
||||
}
|
||||
|
||||
NzShader& NzShader::operator=(NzShader&& shader)
|
||||
{
|
||||
Destroy();
|
||||
|
|
|
|||
|
|
@ -34,8 +34,6 @@ class NzShaderImpl
|
|||
|
||||
virtual bool Load(nzShaderType type, const NzString& source) = 0;
|
||||
|
||||
virtual bool Lock() = 0;
|
||||
|
||||
virtual bool SendBoolean(int location, bool value) = 0;
|
||||
virtual bool SendColor(int location, const NzColor& color) = 0;
|
||||
virtual bool SendDouble(int location, double value) = 0;
|
||||
|
|
@ -50,9 +48,6 @@ class NzShaderImpl
|
|||
virtual bool SendVector(int location, const NzVector3f& vector) = 0;
|
||||
virtual bool SendVector(int location, const NzVector4d& vector) = 0;
|
||||
virtual bool SendVector(int location, const NzVector4f& vector) = 0;
|
||||
|
||||
virtual void Unbind() = 0;
|
||||
virtual void Unlock() = 0;
|
||||
};
|
||||
|
||||
#endif // NAZARA_SHADERIMPL_HPP
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@ namespace
|
|||
}
|
||||
|
||||
GLenum target = (proxy) ? NzOpenGL::TextureTargetProxy[impl->type] : NzOpenGL::TextureTarget[impl->type];
|
||||
GLint previous;
|
||||
glGetIntegerv(NzOpenGL::TextureTargetBinding[impl->type], &previous);
|
||||
switch (impl->type)
|
||||
{
|
||||
case nzImageType_1D:
|
||||
|
|
@ -137,25 +135,6 @@ namespace
|
|||
return true;
|
||||
}
|
||||
|
||||
static unsigned short lockedLevel[nzImageType_Max+1] = {0};
|
||||
static GLuint lockedPrevious[nzImageType_Max+1] = {0};
|
||||
|
||||
void LockTexture(NzTextureImpl* impl)
|
||||
{
|
||||
if (lockedLevel[impl->type]++ == 0)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLint previous;
|
||||
glGetIntegerv(NzOpenGL::TextureTargetBinding[impl->type], &previous);
|
||||
|
||||
lockedPrevious[impl->type] = static_cast<GLuint>(previous);
|
||||
|
||||
if (lockedPrevious[impl->type] != impl->id)
|
||||
glBindTexture(NzOpenGL::TextureTarget[impl->type], impl->id);
|
||||
}
|
||||
}
|
||||
|
||||
inline void SetUnpackAlignement(nzUInt8 bpp)
|
||||
{
|
||||
if (bpp % 8 == 0)
|
||||
|
|
@ -167,28 +146,6 @@ namespace
|
|||
else
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
}
|
||||
|
||||
void UnlockTexture(NzTextureImpl* impl)
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (lockedLevel[impl->type] == 0)
|
||||
{
|
||||
NazaraError("Unlock called on non-locked texture");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (--lockedLevel[impl->type] == 0 && lockedPrevious[impl->type] != impl->id)
|
||||
glBindTexture(NzOpenGL::TextureTarget[impl->type], lockedPrevious[impl->type]);
|
||||
}
|
||||
}
|
||||
|
||||
NzTexture::NzTexture(const NzImage& image)
|
||||
|
|
@ -209,7 +166,7 @@ NzTexture::~NzTexture()
|
|||
Destroy();
|
||||
}
|
||||
|
||||
bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount, bool lock)
|
||||
bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int width, unsigned int height, unsigned int depth, nzUInt8 levelCount)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
|
|
@ -305,7 +262,7 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
|
|||
levelCount = 1;
|
||||
}
|
||||
|
||||
NzTextureImpl* impl = new NzTextureImpl;
|
||||
std::unique_ptr<NzTextureImpl> impl(new NzTextureImpl);
|
||||
glGenTextures(1, &impl->id);
|
||||
|
||||
impl->depth = GetValidSize(depth);
|
||||
|
|
@ -315,38 +272,31 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
|
|||
impl->type = type;
|
||||
impl->width = GetValidSize(width);
|
||||
|
||||
LockTexture(impl);
|
||||
NzOpenGL::BindTexture(impl->type, impl->id);
|
||||
|
||||
// Vérification du support par la carte graphique
|
||||
/*if (!CreateTexture(impl, true))
|
||||
{
|
||||
NazaraError("Texture's parameters not supported by driver");
|
||||
UnlockTexture(impl);
|
||||
glDeleteTextures(1, &impl->id);
|
||||
delete impl;
|
||||
NzOpenGL::DeleteTexture(m_impl->id);
|
||||
|
||||
NazaraError("Texture's parameters not supported by driver");
|
||||
return false;
|
||||
}*/
|
||||
|
||||
// Création de la texture
|
||||
if (!CreateTexture(impl, false))
|
||||
if (!CreateTexture(impl.get(), false))
|
||||
{
|
||||
NazaraError("Failed to create texture");
|
||||
UnlockTexture(impl);
|
||||
glDeleteTextures(1, &impl->id);
|
||||
delete impl;
|
||||
NzOpenGL::DeleteTexture(m_impl->id);
|
||||
|
||||
NazaraError("Failed to create texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_impl = impl;
|
||||
m_impl = impl.release();
|
||||
|
||||
if (m_impl->levelCount > 1U)
|
||||
EnableMipmapping(true);
|
||||
|
||||
if (!lock)
|
||||
UnlockTexture(impl);
|
||||
|
||||
NotifyCreated();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -358,8 +308,8 @@ void NzTexture::Destroy()
|
|||
NotifyDestroy();
|
||||
|
||||
NzContext::EnsureContext();
|
||||
NzOpenGL::DeleteTexture(m_impl->id);
|
||||
|
||||
glDeleteTextures(1, &m_impl->id);
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
|
|
@ -394,13 +344,12 @@ bool NzTexture::Download(NzImage* image) const
|
|||
return false;
|
||||
}
|
||||
|
||||
LockTexture(m_impl);
|
||||
|
||||
unsigned int width = m_impl->width;
|
||||
unsigned int height = m_impl->height;
|
||||
unsigned int depth = m_impl->depth;
|
||||
|
||||
// Téléchargement...
|
||||
NzOpenGL::BindTexture(m_impl->type, m_impl->id);
|
||||
for (nzUInt8 level = 0; level < m_impl->levelCount; ++level)
|
||||
{
|
||||
glGetTexImage(NzOpenGL::TextureTarget[m_impl->type], level, format.dataFormat, format.dataType, image->GetPixels(level));
|
||||
|
|
@ -415,8 +364,6 @@ bool NzTexture::Download(NzImage* image) const
|
|||
depth >>= 1;
|
||||
}
|
||||
|
||||
UnlockTexture(m_impl);
|
||||
|
||||
// Inversion de la texture pour le repère d'OpenGL
|
||||
if (!image->FlipVertically())
|
||||
NazaraWarning("Failed to flip image");
|
||||
|
|
@ -639,7 +586,7 @@ bool NzTexture::LoadFromImage(const NzImage& image, bool generateMipmaps)
|
|||
|
||||
nzImageType type = newImage.GetType();
|
||||
nzUInt8 levelCount = newImage.GetLevelCount();
|
||||
if (!Create(type, format, newImage.GetWidth(), newImage.GetHeight(), newImage.GetDepth(), (generateMipmaps) ? 0xFF : levelCount, true))
|
||||
if (!Create(type, format, newImage.GetWidth(), newImage.GetHeight(), newImage.GetDepth(), (generateMipmaps) ? 0xFF : levelCount))
|
||||
{
|
||||
NazaraError("Failed to create texture");
|
||||
return false;
|
||||
|
|
@ -675,8 +622,6 @@ bool NzTexture::LoadFromImage(const NzImage& image, bool generateMipmaps)
|
|||
}
|
||||
}
|
||||
|
||||
UnlockTexture(m_impl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -784,7 +729,7 @@ bool NzTexture::LoadCubemapFromImage(const NzImage& image, bool generateMipmaps,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!Create(nzImageType_Cubemap, image.GetFormat(), faceSize, faceSize, 1, (generateMipmaps) ? 0xFF : 1, true))
|
||||
if (!Create(nzImageType_Cubemap, image.GetFormat(), faceSize, faceSize, 1, (generateMipmaps) ? 0xFF : 1))
|
||||
{
|
||||
NazaraError("Failed to create texture");
|
||||
return false;
|
||||
|
|
@ -797,8 +742,6 @@ bool NzTexture::LoadCubemapFromImage(const NzImage& image, bool generateMipmaps,
|
|||
UpdateFace(nzCubemapFace_PositiveY, image.GetConstPixels(upPos.x, upPos.y), width, height);
|
||||
UpdateFace(nzCubemapFace_PositiveZ, image.GetConstPixels(forwardPos.x, forwardPos.y), width, height);
|
||||
|
||||
UnlockTexture(m_impl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -946,21 +889,6 @@ bool NzTexture::LoadFaceFromStream(nzCubemapFace face, NzInputStream& stream, co
|
|||
return UpdateFace(face, image);
|
||||
}
|
||||
|
||||
bool NzTexture::Lock()
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Texture must be valid");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
LockTexture(m_impl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzTexture::SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
|
|
@ -983,10 +911,9 @@ bool NzTexture::SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel)
|
|||
}
|
||||
#endif
|
||||
|
||||
LockTexture(m_impl);
|
||||
NzOpenGL::BindTexture(m_impl->type, m_impl->id);
|
||||
glTexParameteri(NzOpenGL::TextureTarget[m_impl->type], GL_TEXTURE_BASE_LEVEL, minLevel);
|
||||
glTexParameteri(NzOpenGL::TextureTarget[m_impl->type], GL_TEXTURE_MAX_LEVEL, maxLevel);
|
||||
UnlockTexture(m_impl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1158,7 +1085,7 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, unsigned int
|
|||
|
||||
SetUnpackAlignement(bpp);
|
||||
|
||||
LockTexture(m_impl);
|
||||
NzOpenGL::BindTexture(m_impl->type, m_impl->id);
|
||||
switch (m_impl->type)
|
||||
{
|
||||
case nzImageType_1D:
|
||||
|
|
@ -1179,7 +1106,6 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, unsigned int
|
|||
NazaraError("Update used on a cubemap texture, please enable safe mode");
|
||||
break;
|
||||
}
|
||||
UnlockTexture(m_impl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1304,37 +1230,15 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe
|
|||
|
||||
SetUnpackAlignement(bpp);
|
||||
|
||||
LockTexture(m_impl);
|
||||
NzOpenGL::BindTexture(m_impl->type, m_impl->id);
|
||||
glTexSubImage2D(NzOpenGL::CubemapFace[face], level, rect.x, height-rect.height-rect.y, rect.width, rect.height, format.dataFormat, format.dataType, flipped.get());
|
||||
UnlockTexture(m_impl);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzTexture::Unlock()
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Texture must be valid");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
UnlockTexture(m_impl);
|
||||
}
|
||||
|
||||
bool NzTexture::Bind() const
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (lockedLevel[m_impl->type] > 0)
|
||||
{
|
||||
NazaraError("Cannot bind texture while a texture is locked");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
glBindTexture(NzOpenGL::TextureTarget[m_impl->type], m_impl->id);
|
||||
NzOpenGL::BindTexture(m_impl->type, m_impl->id);
|
||||
|
||||
if (m_impl->mipmapping && !m_impl->mipmapsUpdated)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue