It is now possible to send uniforms to shader when they are not mounted; Added shader locking

This commit is contained in:
Lynix 2012-05-04 08:56:35 +02:00
parent a4cbe46e15
commit a215920818
5 changed files with 77 additions and 2 deletions

View File

@ -55,6 +55,8 @@ class NAZARA_API NzShader
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(const NzString& name, bool value); bool SendBoolean(const NzString& name, bool value);
bool SendDouble(const NzString& name, double value); bool SendDouble(const NzString& name, double value);
bool SendFloat(const NzString& name, float value); bool SendFloat(const NzString& name, float value);
@ -62,12 +64,12 @@ class NAZARA_API NzShader
bool SendMatrix(const NzString& name, const NzMatrix4d& matrix); bool SendMatrix(const NzString& name, const NzMatrix4d& matrix);
bool SendMatrix(const NzString& name, const NzMatrix4f& matrix); bool SendMatrix(const NzString& name, const NzMatrix4f& matrix);
void Unlock();
static bool IsLanguageSupported(nzShaderLanguage language); static bool IsLanguageSupported(nzShaderLanguage language);
static bool IsTypeSupported(nzShaderType type); static bool IsTypeSupported(nzShaderType type);
private: private:
bool CommitUniforms();
NzShaderImpl* m_impl; NzShaderImpl* m_impl;
bool m_compiled; bool m_compiled;
}; };

View File

@ -245,44 +245,72 @@ bool NzGLSLShader::Load(nzShaderType type, const NzString& source)
} }
} }
bool NzGLSLShader::Lock() const
{
if (m_lockedLevel++ == 0)
{
GLint previous;
glGetIntegerv(GL_CURRENT_PROGRAM, &previous);
m_lockedPrevious = previous;
if (m_lockedPrevious != m_program)
glUseProgram(m_program);
}
return true;
}
bool NzGLSLShader::SendBoolean(const NzString& name, bool value) bool NzGLSLShader::SendBoolean(const NzString& name, bool value)
{ {
Lock();
glUniform1i(GetUniformLocation(name), value); glUniform1i(GetUniformLocation(name), value);
Unlock();
return true; return true;
} }
bool NzGLSLShader::SendDouble(const NzString& name, double value) bool NzGLSLShader::SendDouble(const NzString& name, double value)
{ {
Lock();
glUniform1d(GetUniformLocation(name), value); glUniform1d(GetUniformLocation(name), value);
Unlock();
return true; return true;
} }
bool NzGLSLShader::SendFloat(const NzString& name, float value) bool NzGLSLShader::SendFloat(const NzString& name, float value)
{ {
Lock();
glUniform1f(GetUniformLocation(name), value); glUniform1f(GetUniformLocation(name), value);
Unlock();
return true; return true;
} }
bool NzGLSLShader::SendInteger(const NzString& name, int value) bool NzGLSLShader::SendInteger(const NzString& name, int value)
{ {
Lock();
glUniform1i(GetUniformLocation(name), value); glUniform1i(GetUniformLocation(name), value);
Unlock();
return true; return true;
} }
bool NzGLSLShader::SendMatrix(const NzString& name, const NzMatrix4d& matrix) bool NzGLSLShader::SendMatrix(const NzString& name, const NzMatrix4d& matrix)
{ {
Lock();
glUniformMatrix4dv(GetUniformLocation(name), 1, GL_FALSE, matrix); glUniformMatrix4dv(GetUniformLocation(name), 1, GL_FALSE, matrix);
Unlock();
return true; return true;
} }
bool NzGLSLShader::SendMatrix(const NzString& name, const NzMatrix4f& matrix) bool NzGLSLShader::SendMatrix(const NzString& name, const NzMatrix4f& matrix)
{ {
Lock();
glUniformMatrix4fv(GetUniformLocation(name), 1, GL_FALSE, matrix); glUniformMatrix4fv(GetUniformLocation(name), 1, GL_FALSE, matrix);
Unlock();
return true; return true;
} }
@ -292,6 +320,18 @@ void NzGLSLShader::Unbind()
glUseProgram(0); glUseProgram(0);
} }
void NzGLSLShader::Unlock() const
{
if (m_lockedLevel == 0)
{
NazaraWarning("Unlock called on non-locked texture");
return;
}
if (--m_lockedLevel == 0 && m_lockedPrevious != m_program)
glUseProgram(m_lockedPrevious);
}
bool NzGLSLShader::UpdateVertexBuffer(const NzVertexBuffer* vertexBuffer, const NzVertexDeclaration* vertexDeclaration) bool NzGLSLShader::UpdateVertexBuffer(const NzVertexBuffer* vertexBuffer, const NzVertexDeclaration* vertexDeclaration)
{ {
vertexBuffer->GetBuffer()->GetImpl()->Bind(); vertexBuffer->GetBuffer()->GetImpl()->Bind();

View File

@ -34,6 +34,7 @@ class NzGLSLShader : public NzShaderImpl
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() const;
bool SendBoolean(const NzString& name, bool value); bool SendBoolean(const NzString& name, bool value);
bool SendDouble(const NzString& name, double value); bool SendDouble(const NzString& name, double value);
@ -43,13 +44,16 @@ class NzGLSLShader : public NzShaderImpl
bool SendMatrix(const NzString& name, const NzMatrix4f& matrix); bool SendMatrix(const NzString& name, const NzMatrix4f& matrix);
void Unbind(); void Unbind();
void Unlock() const;
private: private:
bool UpdateVertexBuffer(const NzVertexBuffer* vertexBuffer, const NzVertexDeclaration* vertexDeclaration); bool UpdateVertexBuffer(const NzVertexBuffer* vertexBuffer, const NzVertexDeclaration* vertexDeclaration);
mutable std::map<NzString, GLint> m_idCache; mutable std::map<NzString, GLint> m_idCache;
mutable GLuint m_lockedPrevious;
GLuint m_program; GLuint m_program;
GLuint m_shaders[nzShaderType_Count]; GLuint m_shaders[nzShaderType_Count];
mutable nzUInt8 m_lockedLevel;
NzShader* m_parent; NzShader* m_parent;
NzString m_log; NzString m_log;
}; };

View File

@ -267,6 +267,19 @@ 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(const NzString& name, bool value) bool NzShader::SendBoolean(const NzString& name, bool value)
{ {
#if NAZARA_RENDERER_SAFE #if NAZARA_RENDERER_SAFE
@ -357,6 +370,19 @@ bool NzShader::SendMatrix(const NzString& name, const NzMatrix4f& matrix)
return m_impl->SendMatrix(name, matrix); return m_impl->SendMatrix(name, matrix);
} }
void NzShader::Unlock()
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return;
}
#endif
return m_impl->Unlock();
}
bool NzShader::IsLanguageSupported(nzShaderLanguage language) bool NzShader::IsLanguageSupported(nzShaderLanguage language)
{ {
switch (language) switch (language)

View File

@ -36,6 +36,8 @@ class NzShaderImpl
virtual bool Load(nzShaderType type, const NzString& source) = 0; virtual bool Load(nzShaderType type, const NzString& source) = 0;
virtual bool Lock() const = 0;
virtual bool SendBoolean(const NzString& name, bool value) = 0; virtual bool SendBoolean(const NzString& name, bool value) = 0;
virtual bool SendDouble(const NzString& name, double value) = 0; virtual bool SendDouble(const NzString& name, double value) = 0;
virtual bool SendFloat(const NzString& name, float value) = 0; virtual bool SendFloat(const NzString& name, float value) = 0;
@ -44,6 +46,7 @@ class NzShaderImpl
virtual bool SendMatrix(const NzString& name, const NzMatrix4f& matrix) = 0; virtual bool SendMatrix(const NzString& name, const NzMatrix4f& matrix) = 0;
virtual void Unbind() = 0; virtual void Unbind() = 0;
virtual void Unlock() const = 0;
protected: protected:
virtual bool UpdateVertexBuffer(const NzVertexBuffer* vertexBuffer, const NzVertexDeclaration* vertexDeclaration) = 0; virtual bool UpdateVertexBuffer(const NzVertexBuffer* vertexBuffer, const NzVertexDeclaration* vertexDeclaration) = 0;