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:
Lynix 2013-05-03 02:58:35 +02:00
parent 76c19624d8
commit 4f3060a40d
15 changed files with 389 additions and 561 deletions

View File

@ -113,9 +113,10 @@ enum nzRendererParameter
nzRendererParameter_DepthTest, nzRendererParameter_DepthTest,
nzRendererParameter_DepthWrite, nzRendererParameter_DepthWrite,
nzRendererParameter_FaceCulling, nzRendererParameter_FaceCulling,
nzRendererParameter_Stencil, nzRendererParameter_ScissorTest,
nzRendererParameter_StencilTest,
nzRendererParameter_Max = nzRendererParameter_Stencil nzRendererParameter_Max = nzRendererParameter_StencilTest
}; };
enum nzSamplerFilter enum nzSamplerFilter

View File

@ -65,15 +65,33 @@ class NAZARA_API NzOpenGL
NzOpenGL() = delete; NzOpenGL() = delete;
~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 NzOpenGLFunc GetEntry(const NzString& entryPoint);
static NzString GetRendererName(); static NzString GetRendererName();
static unsigned int GetTextureUnit();
static NzString GetVendorName(); static NzString GetVendorName();
static unsigned int GetVersion(); static unsigned int GetVersion();
static bool Initialize(); static bool Initialize();
static bool IsInitialized(); static bool IsInitialized();
static bool IsSupported(nzOpenGLExtension extension); static bool IsSupported(nzOpenGLExtension extension);
static bool IsSupported(const NzString& string); static bool IsSupported(const NzString& string);
static void SetTextureUnit(unsigned int textureUnit);
static bool TranslateFormat(nzPixelFormat pixelFormat, Format* format, FormatType target); static bool TranslateFormat(nzPixelFormat pixelFormat, Format* format, FormatType target);
static void Uninitialize(); static void Uninitialize();
static GLenum Attachment[nzAttachmentPoint_Max+1]; static GLenum Attachment[nzAttachmentPoint_Max+1];

View File

@ -53,6 +53,7 @@ class NAZARA_API NzRenderer
static unsigned int GetMaxRenderTargets(); static unsigned int GetMaxRenderTargets();
static unsigned int GetMaxTextureUnits(); static unsigned int GetMaxTextureUnits();
static float GetPointSize(); static float GetPointSize();
static NzRectui GetScissorRect();
static const NzShader* GetShader(); static const NzShader* GetShader();
static const NzRenderTarget* GetTarget(); static const NzRenderTarget* GetTarget();
static NzRectui GetViewport(); static NzRectui GetViewport();
@ -72,12 +73,13 @@ class NAZARA_API NzRenderer
static void SetDepthFunc(nzRendererComparison compareFunc); static void SetDepthFunc(nzRendererComparison compareFunc);
static void SetFaceCulling(nzFaceCulling cullingMode); static void SetFaceCulling(nzFaceCulling cullingMode);
static void SetFaceFilling(nzFaceFilling fillingMode); 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 SetInstancingData(const InstancingData* instancingData, unsigned int instanceCount);
static void SetLineWidth(float size); static void SetLineWidth(float size);
static void SetMatrix(nzMatrixType type, const NzMatrix4f& matrix); static void SetMatrix(nzMatrixType type, const NzMatrix4f& matrix);
static void SetPointSize(float size); 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 SetStencilCompareFunction(nzRendererComparison compareFunc);
static void SetStencilFailOperation(nzStencilOperation failOperation); static void SetStencilFailOperation(nzStencilOperation failOperation);
static void SetStencilMask(nzUInt32 mask); static void SetStencilMask(nzUInt32 mask);
@ -87,13 +89,14 @@ class NAZARA_API NzRenderer
static bool SetTarget(const NzRenderTarget* target); static bool SetTarget(const NzRenderTarget* target);
static void SetTexture(nzUInt8 unit, const NzTexture* texture); static void SetTexture(nzUInt8 unit, const NzTexture* texture);
static void SetTextureSampler(nzUInt8 textureUnit, const NzTextureSampler& sampler); 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 SetViewport(const NzRectui& viewport);
static void Uninitialize(); static void Uninitialize();
private: private:
static bool EnsureStateUpdate(bool instancing); static void EnableInstancing(bool instancing);
static bool EnsureStateUpdate();
static unsigned int s_moduleReferenceCounter; static unsigned int s_moduleReferenceCounter;
}; };

View File

@ -57,8 +57,6 @@ class NAZARA_API NzShader : public NzResource, NzNonCopyable
bool Load(nzShaderType type, const NzString& source); bool Load(nzShaderType type, const NzString& source);
bool LoadFromFile(nzShaderType type, const NzString& source); bool LoadFromFile(nzShaderType type, const NzString& source);
bool Lock();
bool SendBoolean(int location, bool value) const; bool SendBoolean(int location, bool value) const;
bool SendColor(int location, const NzColor& color) const; bool SendColor(int location, const NzColor& color) const;
bool SendDouble(int location, double value) const; bool SendDouble(int location, double value) const;
@ -76,8 +74,6 @@ class NAZARA_API NzShader : public NzResource, NzNonCopyable
void SetFlags(nzUInt32 flags); void SetFlags(nzUInt32 flags);
void Unlock();
NzShader& operator=(NzShader&& shader); NzShader& operator=(NzShader&& shader);
static bool IsLanguageSupported(nzShaderLanguage language); static bool IsLanguageSupported(nzShaderLanguage language);

View File

@ -34,7 +34,7 @@ class NAZARA_API NzTexture : public NzResource, NzNonCopyable
explicit NzTexture(const NzImage& image); explicit NzTexture(const NzImage& image);
~NzTexture(); ~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(); void Destroy();
bool Download(NzImage* image) const; 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 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 LoadFaceFromStream(nzCubemapFace face, NzInputStream& stream, const NzImageParams& params = NzImageParams());
bool Lock();
bool SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel); bool SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel);
bool Update(const NzImage& image, nzUInt8 level = 0); 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, 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); 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 // Fonctions OpenGL
bool Bind() const; bool Bind() const;
unsigned int GetOpenGLID() const; unsigned int GetOpenGLID() const;

View File

@ -130,11 +130,7 @@ void NzDebugDrawer::Draw(const NzCubef& cube)
const NzShader* oldShader = NzRenderer::GetShader(); const NzShader* oldShader = NzRenderer::GetShader();
if (!NzRenderer::SetShader(shader)) NzRenderer::SetShader(shader);
{
NazaraError("Failed to set debug shader");
return;
}
bool depthTestActive = NzRenderer::IsEnabled(nzRendererParameter_DepthTest); bool depthTestActive = NzRenderer::IsEnabled(nzRendererParameter_DepthTest);
if (depthTestActive != depthTest) if (depthTestActive != depthTest)
@ -154,8 +150,7 @@ void NzDebugDrawer::Draw(const NzCubef& cube)
if (depthTestActive != depthTest) if (depthTestActive != depthTest)
NzRenderer::Enable(nzRendererParameter_DepthTest, depthTestActive); NzRenderer::Enable(nzRendererParameter_DepthTest, depthTestActive);
if (!NzRenderer::SetShader(oldShader)) NzRenderer::SetShader(oldShader);
NazaraWarning("Failed to reset shader");
} }
void NzDebugDrawer::Draw(const NzCubeui& cube) void NzDebugDrawer::Draw(const NzCubeui& cube)
@ -238,11 +233,7 @@ void NzDebugDrawer::Draw(const NzFrustumf& frustum)
const NzShader* oldShader = NzRenderer::GetShader(); const NzShader* oldShader = NzRenderer::GetShader();
if (!NzRenderer::SetShader(shader)) NzRenderer::SetShader(shader);
{
NazaraError("Failed to set debug shader");
return;
}
bool depthTestActive = NzRenderer::IsEnabled(nzRendererParameter_DepthTest); bool depthTestActive = NzRenderer::IsEnabled(nzRendererParameter_DepthTest);
if (depthTestActive != depthTest) if (depthTestActive != depthTest)
@ -262,8 +253,7 @@ void NzDebugDrawer::Draw(const NzFrustumf& frustum)
if (depthTestActive != depthTest) if (depthTestActive != depthTest)
NzRenderer::Enable(nzRendererParameter_DepthTest, depthTestActive); NzRenderer::Enable(nzRendererParameter_DepthTest, depthTestActive);
if (!NzRenderer::SetShader(oldShader)) NzRenderer::SetShader(oldShader);
NazaraWarning("Failed to reset shader");
} }
void NzDebugDrawer::Draw(const NzOrientedCubef& orientedCube) void NzDebugDrawer::Draw(const NzOrientedCubef& orientedCube)
@ -341,11 +331,7 @@ void NzDebugDrawer::Draw(const NzOrientedCubef& orientedCube)
const NzShader* oldShader = NzRenderer::GetShader(); const NzShader* oldShader = NzRenderer::GetShader();
if (!NzRenderer::SetShader(shader)) NzRenderer::SetShader(shader);
{
NazaraError("Failed to set debug shader");
return;
}
bool depthTestActive = NzRenderer::IsEnabled(nzRendererParameter_DepthTest); bool depthTestActive = NzRenderer::IsEnabled(nzRendererParameter_DepthTest);
if (depthTestActive != depthTest) if (depthTestActive != depthTest)
@ -365,8 +351,7 @@ void NzDebugDrawer::Draw(const NzOrientedCubef& orientedCube)
if (depthTestActive != depthTest) if (depthTestActive != depthTest)
NzRenderer::Enable(nzRendererParameter_DepthTest, depthTestActive); NzRenderer::Enable(nzRendererParameter_DepthTest, depthTestActive);
if (!NzRenderer::SetShader(oldShader)) NzRenderer::SetShader(oldShader);
NazaraWarning("Failed to reset shader");
} }
void NzDebugDrawer::Draw(const NzSkeleton* skeleton) void NzDebugDrawer::Draw(const NzSkeleton* skeleton)
@ -410,11 +395,7 @@ void NzDebugDrawer::Draw(const NzSkeleton* skeleton)
{ {
const NzShader* oldShader = NzRenderer::GetShader(); const NzShader* oldShader = NzRenderer::GetShader();
if (!NzRenderer::SetShader(shader)) NzRenderer::SetShader(shader);
{
NazaraError("Failed to set debug shader");
return;
}
bool depthTestActive = NzRenderer::IsEnabled(nzRendererParameter_DepthTest); bool depthTestActive = NzRenderer::IsEnabled(nzRendererParameter_DepthTest);
if (depthTestActive != depthTest) if (depthTestActive != depthTest)
@ -440,8 +421,7 @@ void NzDebugDrawer::Draw(const NzSkeleton* skeleton)
if (depthTestActive != depthTest) if (depthTestActive != depthTest)
NzRenderer::Enable(nzRendererParameter_DepthTest, depthTestActive); NzRenderer::Enable(nzRendererParameter_DepthTest, depthTestActive);
if (!NzRenderer::SetShader(oldShader)) NzRenderer::SetShader(oldShader);
NazaraWarning("Failed to reset shader");
} }
} }
/* /*

View File

@ -12,12 +12,6 @@
#include <Nazara/Utility/VertexDeclaration.hpp> #include <Nazara/Utility/VertexDeclaration.hpp>
#include <Nazara/Renderer/Debug.hpp> #include <Nazara/Renderer/Debug.hpp>
namespace
{
GLuint lockedPrevious = 0;
nzUInt8 lockedLevel = 0;
}
NzGLSLShader::NzGLSLShader(NzShader* parent) : NzGLSLShader::NzGLSLShader(NzShader* parent) :
m_parent(parent) m_parent(parent)
{ {
@ -25,14 +19,6 @@ m_parent(parent)
bool NzGLSLShader::Bind() 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 #ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr) if (NzContext::GetCurrent() == nullptr)
{ {
@ -41,7 +27,7 @@ bool NzGLSLShader::Bind()
} }
#endif #endif
glUseProgram(m_program); NzOpenGL::BindProgram(m_program);
return true; return true;
} }
@ -160,8 +146,7 @@ void NzGLSLShader::Destroy()
glDeleteShader(shader); glDeleteShader(shader);
} }
if (m_program) NzOpenGL::DeleteProgram(m_program);
glDeleteProgram(m_program);
} }
NzString NzGLSLShader::GetLog() const 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) bool NzGLSLShader::SendBoolean(int location, bool value)
{ {
if (glProgramUniform1i) if (glProgramUniform1i)
glProgramUniform1i(m_program, location, value); glProgramUniform1i(m_program, location, value);
else else
{ {
if (!Lock()) NzOpenGL::BindProgram(m_program);
{
NazaraError("Failed to lock shader");
return false;
}
glUniform1i(location, value); glUniform1i(location, value);
Unlock();
} }
return true; return true;
@ -315,14 +276,8 @@ bool NzGLSLShader::SendColor(int location, const NzColor& color)
glProgramUniform4fv(m_program, location, 1, vecColor); glProgramUniform4fv(m_program, location, 1, vecColor);
else else
{ {
if (!Lock()) NzOpenGL::BindProgram(m_program);
{
NazaraError("Failed to lock shader");
return false;
}
glUniform4fv(location, 1, vecColor); glUniform4fv(location, 1, vecColor);
Unlock();
} }
return true; return true;
@ -334,14 +289,8 @@ bool NzGLSLShader::SendDouble(int location, double value)
glProgramUniform1d(m_program, location, value); glProgramUniform1d(m_program, location, value);
else else
{ {
if (!Lock()) NzOpenGL::BindProgram(m_program);
{
NazaraError("Failed to lock shader");
return false;
}
glUniform1d(location, value); glUniform1d(location, value);
Unlock();
} }
return true; return true;
@ -353,14 +302,8 @@ bool NzGLSLShader::SendFloat(int location, float value)
glProgramUniform1f(m_program, location, value); glProgramUniform1f(m_program, location, value);
else else
{ {
if (!Lock()) NzOpenGL::BindProgram(m_program);
{
NazaraError("Failed to lock shader");
return false;
}
glUniform1f(location, value); glUniform1f(location, value);
Unlock();
} }
return true; return true;
@ -372,14 +315,8 @@ bool NzGLSLShader::SendInteger(int location, int value)
glProgramUniform1i(m_program, location, value); glProgramUniform1i(m_program, location, value);
else else
{ {
if (!Lock()) NzOpenGL::BindProgram(m_program);
{
NazaraError("Failed to lock shader");
return false;
}
glUniform1i(location, value); glUniform1i(location, value);
Unlock();
} }
return true; return true;
@ -391,14 +328,8 @@ bool NzGLSLShader::SendMatrix(int location, const NzMatrix4d& matrix)
glProgramUniformMatrix4dv(m_program, location, 1, GL_FALSE, matrix); glProgramUniformMatrix4dv(m_program, location, 1, GL_FALSE, matrix);
else else
{ {
if (!Lock()) NzOpenGL::BindProgram(m_program);
{
NazaraError("Failed to lock shader");
return false;
}
glUniformMatrix4dv(location, 1, GL_FALSE, matrix); glUniformMatrix4dv(location, 1, GL_FALSE, matrix);
Unlock();
} }
return true; return true;
@ -410,14 +341,8 @@ bool NzGLSLShader::SendMatrix(int location, const NzMatrix4f& matrix)
glProgramUniformMatrix4fv(m_program, location, 1, GL_FALSE, matrix); glProgramUniformMatrix4fv(m_program, location, 1, GL_FALSE, matrix);
else else
{ {
if (!Lock()) NzOpenGL::BindProgram(m_program);
{
NazaraError("Failed to lock shader");
return false;
}
glUniformMatrix4fv(location, 1, GL_FALSE, matrix); glUniformMatrix4fv(location, 1, GL_FALSE, matrix);
Unlock();
} }
return true; return true;
@ -495,14 +420,8 @@ bool NzGLSLShader::SendTexture(int location, const NzTexture* texture, nzUInt8*
glProgramUniform1i(m_program, location, unit); glProgramUniform1i(m_program, location, unit);
else else
{ {
if (!Lock()) NzOpenGL::BindProgram(m_program);
{
NazaraError("Failed to lock shader");
return false;
}
glUniform1i(location, unit); glUniform1i(location, unit);
Unlock();
} }
} }
@ -522,14 +441,8 @@ bool NzGLSLShader::SendVector(int location, const NzVector2d& vector)
glProgramUniform2dv(m_program, location, 1, vector); glProgramUniform2dv(m_program, location, 1, vector);
else else
{ {
if (!Lock()) NzOpenGL::BindProgram(m_program);
{
NazaraError("Failed to lock shader");
return false;
}
glUniform2dv(location, 1, vector); glUniform2dv(location, 1, vector);
Unlock();
} }
return true; return true;
@ -541,14 +454,8 @@ bool NzGLSLShader::SendVector(int location, const NzVector2f& vector)
glProgramUniform2fv(m_program, location, 1, vector); glProgramUniform2fv(m_program, location, 1, vector);
else else
{ {
if (!Lock()) NzOpenGL::BindProgram(m_program);
{
NazaraError("Failed to lock shader");
return false;
}
glUniform2fv(location, 1, vector); glUniform2fv(location, 1, vector);
Unlock();
} }
return true; return true;
@ -560,14 +467,8 @@ bool NzGLSLShader::SendVector(int location, const NzVector3d& vector)
glProgramUniform3dv(m_program, location, 1, vector); glProgramUniform3dv(m_program, location, 1, vector);
else else
{ {
if (!Lock()) NzOpenGL::BindProgram(m_program);
{
NazaraError("Failed to lock shader");
return false;
}
glUniform3dv(location, 1, vector); glUniform3dv(location, 1, vector);
Unlock();
} }
return true; return true;
@ -579,14 +480,8 @@ bool NzGLSLShader::SendVector(int location, const NzVector3f& vector)
glProgramUniform3fv(m_program, location, 1, vector); glProgramUniform3fv(m_program, location, 1, vector);
else else
{ {
if (!Lock()) NzOpenGL::BindProgram(m_program);
{
NazaraError("Failed to lock shader");
return false;
}
glUniform3fv(location, 1, vector); glUniform3fv(location, 1, vector);
Unlock();
} }
return true; return true;
@ -598,14 +493,8 @@ bool NzGLSLShader::SendVector(int location, const NzVector4d& vector)
glProgramUniform4dv(m_program, location, 1, vector); glProgramUniform4dv(m_program, location, 1, vector);
else else
{ {
if (!Lock()) NzOpenGL::BindProgram(m_program);
{
NazaraError("Failed to lock shader");
return false;
}
glUniform4dv(location, 1, vector); glUniform4dv(location, 1, vector);
Unlock();
} }
return true; return true;
@ -617,54 +506,13 @@ bool NzGLSLShader::SendVector(int location, const NzVector4f& vector)
glProgramUniform4fv(m_program, location, 1, vector); glProgramUniform4fv(m_program, location, 1, vector);
else else
{ {
if (!Lock()) NzOpenGL::BindProgram(m_program);
{
NazaraError("Failed to lock shader");
return false;
}
glUniform4fv(location, 1, vector); glUniform4fv(location, 1, vector);
Unlock();
} }
return true; 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) void NzGLSLShader::OnResourceCreated(const NzResource* resource, int index)
{ {
NazaraUnused(resource); NazaraUnused(resource);

View File

@ -38,7 +38,6 @@ class NzGLSLShader : public NzShaderImpl, NzResourceListener
bool IsLoaded(nzShaderType type) const; bool IsLoaded(nzShaderType type) const;
bool Load(nzShaderType type, const NzString& source); bool Load(nzShaderType type, const NzString& source);
bool Lock();
bool SendBoolean(int location, bool value); bool SendBoolean(int location, bool value);
bool SendColor(int location, const NzColor& color); 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 NzVector4d& vector);
bool SendVector(int location, const NzVector4f& vector); bool SendVector(int location, const NzVector4f& vector);
void Unbind();
void Unlock();
private: private:
void OnResourceCreated(const NzResource* resource, int index) override; void OnResourceCreated(const NzResource* resource, int index) override;
void OnResourceDestroy(const NzResource* resource, int index) override; void OnResourceDestroy(const NzResource* resource, int index) override;

View File

@ -86,16 +86,9 @@ bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage)
m_buffer = 0; m_buffer = 0;
glGenBuffers(1, &m_buffer); glGenBuffers(1, &m_buffer);
GLint previous; NzOpenGL::BindBuffer(m_type, m_buffer);
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], &previous);
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
glBufferData(NzOpenGL::BufferTarget[m_type], size, nullptr, NzOpenGL::BufferUsage[usage]); 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; return true;
} }
@ -103,7 +96,7 @@ void NzHardwareBuffer::Destroy()
{ {
NzContext::EnsureContext(); 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) 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) if (!forceDiscard)
forceDiscard = (size == totalSize); forceDiscard = (size == totalSize);
GLuint previous; NzOpenGL::BindBuffer(m_type, m_buffer);
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
if (previous != m_buffer)
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
// http://www.opengl.org/wiki/Vertex_Specification_Best_Practices // http://www.opengl.org/wiki/Vertex_Specification_Best_Practices
if (forceDiscard) 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; return true;
} }
@ -172,52 +157,28 @@ void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned
{ {
NzContext::EnsureContext(); NzContext::EnsureContext();
// Pour ne pas perturber le rendu, on n'interfère pas avec le binding déjà présent NzOpenGL::BindBuffer(m_type, m_buffer);
GLuint previous;
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
if (previous != m_buffer)
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
if (access == nzBufferAccess_DiscardAndWrite) if (access == nzBufferAccess_DiscardAndWrite)
glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetUsage()]); // Discard glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetUsage()]); // Discard
void* ptr = mapBuffer(m_type, access, offset, size); return 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;
} }
bool NzHardwareBuffer::Unmap() bool NzHardwareBuffer::Unmap()
{ {
NzContext::EnsureContext(); NzContext::EnsureContext();
GLuint previous; NzOpenGL::BindBuffer(m_type, m_buffer);
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
if (previous != m_buffer)
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
if (glUnmapBuffer(NzOpenGL::BufferTarget[m_type]) != GL_TRUE) 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()]); 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) // Une erreur rare est survenue, nous devons réinitialiser le buffer
if (previous != m_buffer && previous != 0) NazaraError("Failed to unmap buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
return false; 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; return true;
} }

View File

@ -5,6 +5,7 @@
#include <Nazara/Renderer/OpenGL.hpp> #include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Core/Error.hpp> #include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Context.hpp> #include <Nazara/Renderer/Context.hpp>
#include <cstring>
#include <set> #include <set>
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
@ -58,11 +59,15 @@ namespace
} }
std::set<NzString> s_openGLextensionSet; 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_rendererName = nullptr;
const char* s_vendorName = nullptr; const char* s_vendorName = nullptr;
bool s_initialized = false; bool s_initialized = false;
bool s_openGLextensions[nzOpenGLExtension_Max+1] = {false}; bool s_openGLextensions[nzOpenGLExtension_Max+1] = {false};
unsigned int s_openglVersion = 0; unsigned int s_openglVersion = 0;
unsigned int s_textureUnit = 0;
bool LoadExtensionsString(const NzString& extensionString) 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) NzOpenGLFunc NzOpenGL::GetEntry(const NzString& entryPoint)
{ {
return LoadEntry(entryPoint.GetConstBuffer(), false); return LoadEntry(entryPoint.GetConstBuffer(), false);
@ -119,6 +182,11 @@ NzString NzOpenGL::GetRendererName()
return s_rendererName; return s_rendererName;
} }
unsigned int NzOpenGL::GetTextureUnit()
{
return s_textureUnit;
}
NzString NzOpenGL::GetVendorName() NzString NzOpenGL::GetVendorName()
{ {
return s_vendorName; return s_vendorName;
@ -629,7 +697,12 @@ bool NzOpenGL::Initialize()
return false; 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_rendererName = reinterpret_cast<const char*>(glGetString(GL_RENDERER));
s_textureUnit = 0;
s_vendorName = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); s_vendorName = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
return true; return true;
@ -650,6 +723,15 @@ bool NzOpenGL::IsSupported(const NzString& string)
return s_openGLextensionSet.find(string) != s_openGLextensionSet.end(); 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) bool NzOpenGL::TranslateFormat(nzPixelFormat pixelFormat, Format* format, FormatType type)
{ {
switch (pixelFormat) switch (pixelFormat)
@ -941,7 +1023,8 @@ GLenum NzOpenGL::RendererParameter[nzRendererParameter_Max+1] =
GL_DEPTH_TEST, // nzRendererParameter_DepthTest GL_DEPTH_TEST, // nzRendererParameter_DepthTest
GL_NONE, // nzRendererParameter_DepthWrite GL_NONE, // nzRendererParameter_DepthWrite
GL_CULL_FACE, // nzRendererParameter_FaceCulling GL_CULL_FACE, // nzRendererParameter_FaceCulling
GL_STENCIL_TEST // nzRendererParameter_Stencil GL_SCISSOR_TEST, // nzRendererParameter_ScissorTest
GL_STENCIL_TEST // nzRendererParameter_StencilTest
}; };
GLenum NzOpenGL::SamplerWrapMode[nzSamplerWrap_Max+1] = GLenum NzOpenGL::SamplerWrapMode[nzSamplerWrap_Max+1] =

View File

@ -124,7 +124,7 @@ bool NzRenderWindow::CopyToTexture(NzTexture* texture) const
NzVector2ui size = GetSize(); 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"); NazaraError("Failed to create texture");
return false; return false;
@ -143,8 +143,6 @@ bool NzRenderWindow::CopyToTexture(NzTexture* texture) const
m_context->SetActive(false); m_context->SetActive(false);
} }
texture->Unlock();
return true; return true;
} }

View File

@ -41,13 +41,24 @@ namespace
nzMatrixCombination_Max = nzMatrixCombination_WorldViewProj 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 struct TextureUnit
{ {
NzTextureSampler sampler; NzTextureSampler sampler;
const NzTexture* texture = nullptr; const NzTexture* texture = nullptr;
bool samplerUpdated = false; bool samplerUpdated = false;
bool textureUpdated = true; bool textureUpdated = true;
bool updated = true;
}; };
NzBufferImpl* HardwareBufferFunction(NzBuffer* parent, nzBufferType type) NzBufferImpl* HardwareBufferFunction(NzBuffer* parent, nzBufferType type)
@ -61,6 +72,7 @@ namespace
std::map<VAO_Key, unsigned int> s_vaos; std::map<VAO_Key, unsigned int> s_vaos;
std::vector<TextureUnit> s_textureUnits; std::vector<TextureUnit> s_textureUnits;
std::vector<unsigned int> s_dirtyTextureUnits;
NzBuffer* s_instancingBuffer = nullptr; NzBuffer* s_instancingBuffer = nullptr;
NzVertexBuffer* s_quadBuffer = nullptr; NzVertexBuffer* s_quadBuffer = nullptr;
NzMatrix4f s_matrix[totalMatrixCount]; NzMatrix4f s_matrix[totalMatrixCount];
@ -76,18 +88,17 @@ namespace
nzStencilOperation s_stencilZFail; nzStencilOperation s_stencilZFail;
nzUInt8 s_maxAnisotropyLevel; nzUInt8 s_maxAnisotropyLevel;
nzUInt32 s_stencilMask; nzUInt32 s_stencilMask;
nzUInt32 s_updateFlags;
const NzIndexBuffer* s_indexBuffer; const NzIndexBuffer* s_indexBuffer;
const NzRenderTarget* s_target; const NzRenderTarget* s_target;
const NzShader* s_shader; const NzShader* s_shader;
const NzVertexBuffer* s_vertexBuffer; const NzVertexBuffer* s_vertexBuffer;
const NzVertexDeclaration* s_vertexDeclaration; const NzVertexDeclaration* s_vertexDeclaration;
bool s_capabilities[nzRendererCap_Max+1]; bool s_capabilities[nzRendererCap_Max+1];
bool s_instancing;
bool s_matrixUpdated[totalMatrixCount]; bool s_matrixUpdated[totalMatrixCount];
bool s_stencilFuncUpdated;
bool s_stencilOpUpdated;
bool s_useSamplerObjects; bool s_useSamplerObjects;
bool s_useVertexArrayObjects; bool s_useVertexArrayObjects;
bool s_vaoUpdated;
int s_matrixLocation[totalMatrixCount]; int s_matrixLocation[totalMatrixCount];
unsigned int s_maxRenderTarget; unsigned int s_maxRenderTarget;
unsigned int s_maxTextureUnit; unsigned int s_maxTextureUnit;
@ -145,7 +156,9 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
} }
#endif #endif
if (!EnsureStateUpdate(false)) EnableInstancing(false);
if (!EnsureStateUpdate())
{ {
NazaraError("Failed to update states"); NazaraError("Failed to update states");
return; return;
@ -214,7 +227,9 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr
} }
#endif #endif
if (!EnsureStateUpdate(true)) EnableInstancing(true);
if (!EnsureStateUpdate())
{ {
NazaraError("Failed to update states"); NazaraError("Failed to update states");
return; return;
@ -257,7 +272,9 @@ void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVer
} }
#endif #endif
if (!EnsureStateUpdate(false)) EnableInstancing(false);
if (!EnsureStateUpdate())
{ {
NazaraError("Failed to update states"); NazaraError("Failed to update states");
return; return;
@ -302,7 +319,9 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive
} }
#endif #endif
if (!EnsureStateUpdate(true)) EnableInstancing(true);
if (!EnsureStateUpdate())
{ {
NazaraError("Failed to update states"); NazaraError("Failed to update states");
return; return;
@ -415,13 +434,13 @@ void NzRenderer::DrawTexture(unsigned int unit, const NzRectf& rect, const NzVec
SetShader(shader); SetShader(shader);
SetVertexBuffer(s_quadBuffer); SetVertexBuffer(s_quadBuffer);
if (!EnsureStateUpdate(true)) if (!EnsureStateUpdate())
{ {
NazaraError("Failed to update states"); NazaraError("Failed to update states");
return; 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); 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); Enable(nzRendererParameter_FaceCulling, faceCulling);
SetShader(oldShader); SetShader(oldShader);
SetVertexBuffer(oldBuffer); SetVertexBuffer(oldBuffer);
s_matrixUpdated[nzMatrixCombination_WorldViewProj] = false;
s_vaoUpdated = false;
} }
} }
@ -577,6 +593,22 @@ float NzRenderer::GetPointSize()
return pointSize; 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, &params[0]);
return NzRectui(params[0], params[1], params[2], params[3]);
}
const NzShader* NzRenderer::GetShader() const NzShader* NzRenderer::GetShader()
{ {
return s_shader; return s_shader;
@ -711,6 +743,7 @@ bool NzRenderer::Initialize()
else else
s_maxTextureUnit = 1; s_maxTextureUnit = 1;
s_dirtyTextureUnits.reserve(s_maxTextureUnit);
s_dstBlend = nzBlendFunc_Zero; s_dstBlend = nzBlendFunc_Zero;
s_faceCulling = nzFaceCulling_Back; s_faceCulling = nzFaceCulling_Back;
s_faceFilling = nzFaceFilling_Fill; s_faceFilling = nzFaceFilling_Fill;
@ -719,9 +752,7 @@ bool NzRenderer::Initialize()
s_srcBlend = nzBlendFunc_One; s_srcBlend = nzBlendFunc_One;
s_stencilCompare = nzRendererComparison_Always; s_stencilCompare = nzRendererComparison_Always;
s_stencilFail = nzStencilOperation_Keep; s_stencilFail = nzStencilOperation_Keep;
s_stencilFuncUpdated = true;
s_stencilMask = 0xFFFFFFFF; s_stencilMask = 0xFFFFFFFF;
s_stencilOpUpdated = true;
s_stencilPass = nzStencilOperation_Keep; s_stencilPass = nzStencilOperation_Keep;
s_stencilReference = 0; s_stencilReference = 0;
s_stencilZFail = nzStencilOperation_Keep; s_stencilZFail = nzStencilOperation_Keep;
@ -729,9 +760,9 @@ bool NzRenderer::Initialize()
s_textureUnits.resize(s_maxTextureUnit); s_textureUnits.resize(s_maxTextureUnit);
s_useSamplerObjects = NzOpenGL::IsSupported(nzOpenGLExtension_SamplerObjects); s_useSamplerObjects = NzOpenGL::IsSupported(nzOpenGLExtension_SamplerObjects);
s_useVertexArrayObjects = NzOpenGL::IsSupported(nzOpenGLExtension_VertexArrayObjects); s_useVertexArrayObjects = NzOpenGL::IsSupported(nzOpenGLExtension_VertexArrayObjects);
s_vaoUpdated = false;
s_vertexBuffer = nullptr; s_vertexBuffer = nullptr;
s_vertexDeclaration = nullptr; s_vertexDeclaration = nullptr;
s_updateFlags = (Update_Matrices | Update_Shader | Update_VAO);
NzVertexElement elements[2]; NzVertexElement elements[2];
elements[0].offset = 0; 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 NAZARA_RENDERER_SAFE
if (indexBuffer && !indexBuffer->IsHardware() && !indexBuffer->IsSequential()) if (indexBuffer && !indexBuffer->IsHardware() && !indexBuffer->IsSequential())
{ {
NazaraError("Buffer must be hardware"); NazaraError("Buffer must be hardware");
return false; return;
} }
#endif #endif
if (s_indexBuffer != indexBuffer) if (s_indexBuffer != indexBuffer)
{ {
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) 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_WorldView] = false;
s_matrixUpdated[nzMatrixCombination_WorldViewProj] = false; // Toujours invalidée s_matrixUpdated[nzMatrixCombination_WorldViewProj] = false; // Toujours invalidée
s_updateFlags |= Update_Matrices;
} }
void NzRenderer::SetPointSize(float size) void NzRenderer::SetPointSize(float size)
@ -1065,51 +1096,51 @@ void NzRenderer::SetPointSize(float size)
glPointSize(size); glPointSize(size);
} }
bool NzRenderer::SetShader(const NzShader* shader) void NzRenderer::SetScissorRect(const NzRectui& rect)
{ {
if (s_shader == shader) #ifdef NAZARA_DEBUG
return true; if (NzContext::GetCurrent() == nullptr)
if (s_shader)
s_shader->m_impl->Unbind();
if (shader)
{ {
#if NAZARA_RENDERER_SAFE NazaraError("No active context");
if (!shader->IsCompiled()) return;
{
NazaraError("Shader is not compiled");
shader = nullptr;
return false;
} }
#endif #endif
if (!shader->m_impl->Bind()) unsigned int height = s_target->GetHeight();
#if NAZARA_RENDERER_SAFE
if (!s_target)
{ {
NazaraError("Failed to bind shader"); NazaraError("Renderer has no target");
shader = nullptr; return;
return false;
} }
// Récupération des indices des variables uniformes (-1 si la variable n'existe pas) unsigned int width = s_target->GetWidth();
s_matrixLocation[nzMatrixType_Projection] = shader->GetUniformLocation("ProjMatrix"); if (rect.x+rect.width > width || rect.y+rect.height > height)
s_matrixLocation[nzMatrixType_View] = shader->GetUniformLocation("ViewMatrix"); {
s_matrixLocation[nzMatrixType_World] = shader->GetUniformLocation("WorldMatrix"); NazaraError("Rectangle dimensions are out of bounds");
return;
}
#endif
s_matrixLocation[nzMatrixCombination_ViewProj] = shader->GetUniformLocation("ViewProjMatrix"); glScissor(rect.x, height-rect.height-rect.y, rect.width, rect.height);
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;
} }
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_shader = shader;
s_updateFlags |= Update_Shader;
return true; }
} }
void NzRenderer::SetStencilCompareFunction(nzRendererComparison compareFunc) void NzRenderer::SetStencilCompareFunction(nzRendererComparison compareFunc)
@ -1125,7 +1156,7 @@ void NzRenderer::SetStencilCompareFunction(nzRendererComparison compareFunc)
if (compareFunc != s_stencilCompare) if (compareFunc != s_stencilCompare)
{ {
s_stencilCompare = compareFunc; s_stencilCompare = compareFunc;
s_stencilFuncUpdated = false; s_updateFlags |= Update_StencilFunc;
} }
} }
@ -1142,7 +1173,7 @@ void NzRenderer::SetStencilFailOperation(nzStencilOperation failOperation)
if (failOperation != s_stencilFail) if (failOperation != s_stencilFail)
{ {
s_stencilFail = failOperation; s_stencilFail = failOperation;
s_stencilOpUpdated = false; s_updateFlags |= Update_StencilOp;
} }
} }
@ -1151,7 +1182,7 @@ void NzRenderer::SetStencilMask(nzUInt32 mask)
if (mask != s_stencilMask) if (mask != s_stencilMask)
{ {
s_stencilMask = mask; s_stencilMask = mask;
s_stencilFuncUpdated = false; s_updateFlags |= Update_StencilFunc;
} }
} }
@ -1168,7 +1199,7 @@ void NzRenderer::SetStencilPassOperation(nzStencilOperation passOperation)
if (passOperation != s_stencilPass) if (passOperation != s_stencilPass)
{ {
s_stencilPass = passOperation; s_stencilPass = passOperation;
s_stencilOpUpdated = false; s_updateFlags |= Update_StencilOp;
} }
} }
@ -1177,7 +1208,7 @@ void NzRenderer::SetStencilReferenceValue(unsigned int refValue)
if (refValue != s_stencilReference) if (refValue != s_stencilReference)
{ {
s_stencilReference = refValue; s_stencilReference = refValue;
s_stencilFuncUpdated = false; s_updateFlags |= Update_StencilFunc;
} }
} }
@ -1194,7 +1225,7 @@ void NzRenderer::SetStencilZFailOperation(nzStencilOperation zfailOperation)
if (zfailOperation != s_stencilZFail) if (zfailOperation != s_stencilZFail)
{ {
s_stencilZFail = zfailOperation; 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())) if (s_textureUnits[unit].sampler.UseMipmaps(texture->HasMipmaps()))
s_textureUnits[unit].samplerUpdated = false; 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].sampler = sampler;
s_textureUnits[unit].samplerUpdated = false; s_textureUnits[unit].samplerUpdated = false;
s_textureUnits[unit].updated = false;
if (s_textureUnits[unit].texture) if (s_textureUnits[unit].texture)
s_textureUnits[unit].sampler.UseMipmaps(s_textureUnits[unit].texture->HasMipmaps()); 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 NAZARA_RENDERER_SAFE
if (vertexBuffer && !vertexBuffer->IsHardware()) if (vertexBuffer && !vertexBuffer->IsHardware())
{ {
NazaraError("Buffer must be hardware"); NazaraError("Buffer must be hardware");
return false; return;
} }
#endif #endif
@ -1295,10 +1329,8 @@ bool NzRenderer::SetVertexBuffer(const NzVertexBuffer* vertexBuffer)
if (s_vertexDeclaration != vertexDeclaration) if (s_vertexDeclaration != vertexDeclaration)
s_vertexDeclaration = vertexDeclaration; s_vertexDeclaration = vertexDeclaration;
s_vaoUpdated = false; s_updateFlags |= Update_VAO;
} }
return true;
} }
void NzRenderer::SetViewport(const NzRectui& viewport) void NzRenderer::SetViewport(const NzRectui& viewport)
@ -1329,7 +1361,6 @@ void NzRenderer::SetViewport(const NzRectui& viewport)
#endif #endif
glViewport(viewport.x, height-viewport.height-viewport.y, viewport.width, viewport.height); 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() void NzRenderer::Uninitialize()
@ -1381,8 +1412,20 @@ void NzRenderer::Uninitialize()
NzUtility::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 #ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr) if (NzContext::GetCurrent() == nullptr)
{ {
@ -1391,6 +1434,10 @@ bool NzRenderer::EnsureStateUpdate(bool instancing)
} }
#endif #endif
NzShaderImpl* shaderImpl;
if (s_updateFlags & Update_Shader)
{
#if NAZARA_RENDERER_SAFE #if NAZARA_RENDERER_SAFE
if (!s_shader) if (!s_shader)
{ {
@ -1400,21 +1447,44 @@ bool NzRenderer::EnsureStateUpdate(bool instancing)
#endif #endif
// Il est plus rapide d'opérer sur l'implémentation du shader directement // Il est plus rapide d'opérer sur l'implémentation du shader directement
NzShaderImpl* shaderImpl = s_shader->m_impl; shaderImpl = s_shader->m_impl;
shaderImpl->Bind();
shaderImpl->BindTextures(); 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) if (s_useSamplerObjects)
{ {
///FIXME: Itère sur toutes les unités (Dont beaucoup inutilisées) for (unsigned int i : s_dirtyTextureUnits)
for (unsigned int i = 0; i < s_textureUnits.size(); ++i)
{ {
TextureUnit& unit = s_textureUnits[i]; TextureUnit& unit = s_textureUnits[i];
if (!unit.updated)
{
if (!unit.textureUpdated) if (!unit.textureUpdated)
{ {
glActiveTexture(GL_TEXTURE0 + i); NzOpenGL::SetTextureUnit(i);
unit.texture->Bind(); unit.texture->Bind();
unit.textureUpdated = true; unit.textureUpdated = true;
@ -1425,33 +1495,30 @@ bool NzRenderer::EnsureStateUpdate(bool instancing)
unit.sampler.Bind(i); unit.sampler.Bind(i);
unit.samplerUpdated = true; unit.samplerUpdated = true;
} }
unit.updated = true;
}
} }
} }
else else
{ {
///FIXME: Itère sur toutes les unités (Dont beaucoup inutilisées) for (unsigned int i : s_dirtyTextureUnits)
for (unsigned int i = 0; i < s_textureUnits.size(); ++i)
{ {
TextureUnit& unit = s_textureUnits[i]; TextureUnit& unit = s_textureUnits[i];
if (!unit.updated) NzOpenGL::SetTextureUnit(i);
{
glActiveTexture(GL_TEXTURE0 + i);
unit.texture->Bind(); unit.texture->Bind();
unit.textureUpdated = true; unit.textureUpdated = true;
unit.sampler.Apply(unit.texture); unit.sampler.Apply(unit.texture);
unit.samplerUpdated = true; unit.samplerUpdated = true;
unit.updated = true;
}
} }
} }
s_dirtyTextureUnits.clear(); // Ne change pas la capacité
s_updateFlags &= ~Update_Textures;
}
if (s_updateFlags & Update_Matrices)
{
for (unsigned int i = 0; i <= nzMatrixType_Max; ++i) for (unsigned int i = 0; i <= nzMatrixType_Max; ++i)
{ {
if (!s_matrixUpdated[i]) if (!s_matrixUpdated[i])
@ -1489,19 +1556,22 @@ bool NzRenderer::EnsureStateUpdate(bool instancing)
s_matrixUpdated[nzMatrixCombination_WorldViewProj] = true; s_matrixUpdated[nzMatrixCombination_WorldViewProj] = true;
} }
if (!s_stencilFuncUpdated) s_updateFlags &= ~Update_Matrices;
}
if (s_updateFlags & Update_StencilFunc)
{ {
glStencilFunc(NzOpenGL::RendererComparison[s_stencilCompare], s_stencilReference, s_stencilMask); 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]); 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 NAZARA_RENDERER_SAFE
if (!s_vertexBuffer) if (!s_vertexBuffer)
@ -1526,7 +1596,7 @@ bool NzRenderer::EnsureStateUpdate(bool instancing)
// On recherche si un VAO existe déjà avec notre configuration // 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 // 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); auto it = s_vaos.find(key);
if (it == s_vaos.end()) if (it == s_vaos.end())
{ {
@ -1577,7 +1647,7 @@ bool NzRenderer::EnsureStateUpdate(bool instancing)
glDisableVertexAttribArray(NzOpenGL::AttributeIndex[i]); glDisableVertexAttribArray(NzOpenGL::AttributeIndex[i]);
} }
if (instancing) if (s_instancing)
{ {
static_cast<NzHardwareBuffer*>(s_instancingBuffer->GetImpl())->Bind(); static_cast<NzHardwareBuffer*>(s_instancingBuffer->GetImpl())->Bind();
@ -1611,9 +1681,14 @@ bool NzRenderer::EnsureStateUpdate(bool instancing)
glBindVertexArray(vao); 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; return true;
} }

View File

@ -298,19 +298,6 @@ bool NzShader::LoadFromFile(nzShaderType type, const NzString& filePath)
return m_impl->Load(type, source); 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 bool NzShader::SendBoolean(int location, bool value) const
{ {
#if NAZARA_RENDERER_SAFE #if NAZARA_RENDERER_SAFE
@ -612,19 +599,6 @@ void NzShader::SetFlags(nzUInt32 flags)
m_flags = 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) NzShader& NzShader::operator=(NzShader&& shader)
{ {
Destroy(); Destroy();

View File

@ -34,8 +34,6 @@ class NzShaderImpl
virtual bool Load(nzShaderType type, const NzString& source) = 0; virtual bool Load(nzShaderType type, const NzString& source) = 0;
virtual bool Lock() = 0;
virtual bool SendBoolean(int location, bool value) = 0; virtual bool SendBoolean(int location, bool value) = 0;
virtual bool SendColor(int location, const NzColor& color) = 0; virtual bool SendColor(int location, const NzColor& color) = 0;
virtual bool SendDouble(int location, double value) = 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 NzVector3f& vector) = 0;
virtual bool SendVector(int location, const NzVector4d& vector) = 0; virtual bool SendVector(int location, const NzVector4d& vector) = 0;
virtual bool SendVector(int location, const NzVector4f& vector) = 0; virtual bool SendVector(int location, const NzVector4f& vector) = 0;
virtual void Unbind() = 0;
virtual void Unlock() = 0;
}; };
#endif // NAZARA_SHADERIMPL_HPP #endif // NAZARA_SHADERIMPL_HPP

View File

@ -37,8 +37,6 @@ namespace
} }
GLenum target = (proxy) ? NzOpenGL::TextureTargetProxy[impl->type] : NzOpenGL::TextureTarget[impl->type]; GLenum target = (proxy) ? NzOpenGL::TextureTargetProxy[impl->type] : NzOpenGL::TextureTarget[impl->type];
GLint previous;
glGetIntegerv(NzOpenGL::TextureTargetBinding[impl->type], &previous);
switch (impl->type) switch (impl->type)
{ {
case nzImageType_1D: case nzImageType_1D:
@ -137,25 +135,6 @@ namespace
return true; 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) inline void SetUnpackAlignement(nzUInt8 bpp)
{ {
if (bpp % 8 == 0) if (bpp % 8 == 0)
@ -167,28 +146,6 @@ namespace
else else
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 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) NzTexture::NzTexture(const NzImage& image)
@ -209,7 +166,7 @@ NzTexture::~NzTexture()
Destroy(); 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(); Destroy();
@ -305,7 +262,7 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
levelCount = 1; levelCount = 1;
} }
NzTextureImpl* impl = new NzTextureImpl; std::unique_ptr<NzTextureImpl> impl(new NzTextureImpl);
glGenTextures(1, &impl->id); glGenTextures(1, &impl->id);
impl->depth = GetValidSize(depth); impl->depth = GetValidSize(depth);
@ -315,38 +272,31 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
impl->type = type; impl->type = type;
impl->width = GetValidSize(width); impl->width = GetValidSize(width);
LockTexture(impl); NzOpenGL::BindTexture(impl->type, impl->id);
// Vérification du support par la carte graphique // Vérification du support par la carte graphique
/*if (!CreateTexture(impl, true)) /*if (!CreateTexture(impl, true))
{ {
NazaraError("Texture's parameters not supported by driver"); NzOpenGL::DeleteTexture(m_impl->id);
UnlockTexture(impl);
glDeleteTextures(1, &impl->id);
delete impl;
NazaraError("Texture's parameters not supported by driver");
return false; return false;
}*/ }*/
// Création de la texture // Création de la texture
if (!CreateTexture(impl, false)) if (!CreateTexture(impl.get(), false))
{ {
NazaraError("Failed to create texture"); NzOpenGL::DeleteTexture(m_impl->id);
UnlockTexture(impl);
glDeleteTextures(1, &impl->id);
delete impl;
NazaraError("Failed to create texture");
return false; return false;
} }
m_impl = impl; m_impl = impl.release();
if (m_impl->levelCount > 1U) if (m_impl->levelCount > 1U)
EnableMipmapping(true); EnableMipmapping(true);
if (!lock)
UnlockTexture(impl);
NotifyCreated(); NotifyCreated();
return true; return true;
} }
@ -358,8 +308,8 @@ void NzTexture::Destroy()
NotifyDestroy(); NotifyDestroy();
NzContext::EnsureContext(); NzContext::EnsureContext();
NzOpenGL::DeleteTexture(m_impl->id);
glDeleteTextures(1, &m_impl->id);
delete m_impl; delete m_impl;
m_impl = nullptr; m_impl = nullptr;
} }
@ -394,13 +344,12 @@ bool NzTexture::Download(NzImage* image) const
return false; return false;
} }
LockTexture(m_impl);
unsigned int width = m_impl->width; unsigned int width = m_impl->width;
unsigned int height = m_impl->height; unsigned int height = m_impl->height;
unsigned int depth = m_impl->depth; unsigned int depth = m_impl->depth;
// Téléchargement... // Téléchargement...
NzOpenGL::BindTexture(m_impl->type, m_impl->id);
for (nzUInt8 level = 0; level < m_impl->levelCount; ++level) for (nzUInt8 level = 0; level < m_impl->levelCount; ++level)
{ {
glGetTexImage(NzOpenGL::TextureTarget[m_impl->type], level, format.dataFormat, format.dataType, image->GetPixels(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; depth >>= 1;
} }
UnlockTexture(m_impl);
// Inversion de la texture pour le repère d'OpenGL // Inversion de la texture pour le repère d'OpenGL
if (!image->FlipVertically()) if (!image->FlipVertically())
NazaraWarning("Failed to flip image"); NazaraWarning("Failed to flip image");
@ -639,7 +586,7 @@ bool NzTexture::LoadFromImage(const NzImage& image, bool generateMipmaps)
nzImageType type = newImage.GetType(); nzImageType type = newImage.GetType();
nzUInt8 levelCount = newImage.GetLevelCount(); 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"); NazaraError("Failed to create texture");
return false; return false;
@ -675,8 +622,6 @@ bool NzTexture::LoadFromImage(const NzImage& image, bool generateMipmaps)
} }
} }
UnlockTexture(m_impl);
return true; return true;
} }
@ -784,7 +729,7 @@ bool NzTexture::LoadCubemapFromImage(const NzImage& image, bool generateMipmaps,
return false; 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"); NazaraError("Failed to create texture");
return false; 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_PositiveY, image.GetConstPixels(upPos.x, upPos.y), width, height);
UpdateFace(nzCubemapFace_PositiveZ, image.GetConstPixels(forwardPos.x, forwardPos.y), width, height); UpdateFace(nzCubemapFace_PositiveZ, image.GetConstPixels(forwardPos.x, forwardPos.y), width, height);
UnlockTexture(m_impl);
return true; return true;
} }
@ -946,21 +889,6 @@ bool NzTexture::LoadFaceFromStream(nzCubemapFace face, NzInputStream& stream, co
return UpdateFace(face, image); 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) bool NzTexture::SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel)
{ {
#if NAZARA_RENDERER_SAFE #if NAZARA_RENDERER_SAFE
@ -983,10 +911,9 @@ bool NzTexture::SetMipmapRange(nzUInt8 minLevel, nzUInt8 maxLevel)
} }
#endif #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_BASE_LEVEL, minLevel);
glTexParameteri(NzOpenGL::TextureTarget[m_impl->type], GL_TEXTURE_MAX_LEVEL, maxLevel); glTexParameteri(NzOpenGL::TextureTarget[m_impl->type], GL_TEXTURE_MAX_LEVEL, maxLevel);
UnlockTexture(m_impl);
return true; return true;
} }
@ -1158,7 +1085,7 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, unsigned int
SetUnpackAlignement(bpp); SetUnpackAlignement(bpp);
LockTexture(m_impl); NzOpenGL::BindTexture(m_impl->type, m_impl->id);
switch (m_impl->type) switch (m_impl->type)
{ {
case nzImageType_1D: 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"); NazaraError("Update used on a cubemap texture, please enable safe mode");
break; break;
} }
UnlockTexture(m_impl);
return true; return true;
} }
@ -1304,37 +1230,15 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe
SetUnpackAlignement(bpp); 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()); 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; 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 bool NzTexture::Bind() const
{ {
#if NAZARA_RENDERER_SAFE NzOpenGL::BindTexture(m_impl->type, m_impl->id);
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);
if (m_impl->mipmapping && !m_impl->mipmapsUpdated) if (m_impl->mipmapping && !m_impl->mipmapsUpdated)
{ {