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_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
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ class NAZARA_API NzOpenGL
|
||||||
enum FormatType
|
enum FormatType
|
||||||
{
|
{
|
||||||
FormatType_RenderBuffer,
|
FormatType_RenderBuffer,
|
||||||
// FormatType_MultisampleTexture,
|
// FormatType_MultisampleTexture,
|
||||||
FormatType_Texture
|
FormatType_Texture
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -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];
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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] =
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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, ¶ms[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;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue