Added ShaderProgram::LoadFromBinary
Former-commit-id: fdc6b06173954bb9c382ed73e7cd9bb0c5fd01a5
This commit is contained in:
parent
ae53b01ca1
commit
059ea21b41
|
|
@ -58,6 +58,8 @@ class NAZARA_API NzShaderProgram : public NzResource, NzNonCopyable
|
||||||
bool IsLoaded(nzShaderType type) const;
|
bool IsLoaded(nzShaderType type) const;
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
|
|
||||||
|
bool LoadFromBinary(const void* buffer, unsigned int size);
|
||||||
|
bool LoadFromBinary(const NzByteArray& byteArray);
|
||||||
bool LoadShader(nzShaderType type, const NzString& source);
|
bool LoadShader(nzShaderType type, const NzString& source);
|
||||||
bool LoadShaderFromFile(nzShaderType type, const NzString& source);
|
bool LoadShaderFromFile(nzShaderType type, const NzString& source);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ class NzAbstractShaderProgram
|
||||||
virtual bool IsBinaryRetrievable() const = 0;
|
virtual bool IsBinaryRetrievable() const = 0;
|
||||||
virtual bool IsLoaded(nzShaderType type) const = 0;
|
virtual bool IsLoaded(nzShaderType type) const = 0;
|
||||||
|
|
||||||
|
virtual bool LoadFromBinary(const void* buffer, unsigned int size) = 0;
|
||||||
virtual bool LoadShader(nzShaderType type, const NzString& source) = 0;
|
virtual bool LoadShader(nzShaderType type, const NzString& source) = 0;
|
||||||
|
|
||||||
virtual bool SendBoolean(int location, bool value) = 0;
|
virtual bool SendBoolean(int location, bool value) = 0;
|
||||||
|
|
|
||||||
|
|
@ -48,72 +48,11 @@ bool NzGLSLProgram::Compile()
|
||||||
{
|
{
|
||||||
NzContext::EnsureContext();
|
NzContext::EnsureContext();
|
||||||
|
|
||||||
m_idCache.clear();
|
PreLinkage();
|
||||||
m_textures.clear();
|
|
||||||
|
|
||||||
if (NzOpenGL::IsSupported(nzOpenGLExtension_GetProgramBinary))
|
|
||||||
glProgramParameteri(m_program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
|
|
||||||
|
|
||||||
glLinkProgram(m_program);
|
glLinkProgram(m_program);
|
||||||
|
|
||||||
GLint success;
|
return PostLinkage();
|
||||||
glGetProgramiv(m_program, GL_LINK_STATUS, &success);
|
|
||||||
|
|
||||||
if (success == GL_TRUE)
|
|
||||||
{
|
|
||||||
static NzString successStr("Linkage successful");
|
|
||||||
m_log = successStr;
|
|
||||||
|
|
||||||
// Pour éviter de se tromper entre le nom et la constante
|
|
||||||
#define CacheUniform(name) m_uniformLocations[nzShaderUniform_##name] = GetUniformLocation(#name)
|
|
||||||
|
|
||||||
CacheUniform(CameraPosition);
|
|
||||||
CacheUniform(InvTargetSize);
|
|
||||||
CacheUniform(MaterialAlphaMap);
|
|
||||||
CacheUniform(MaterialAlphaThreshold);
|
|
||||||
CacheUniform(MaterialAmbient);
|
|
||||||
CacheUniform(MaterialDiffuse);
|
|
||||||
CacheUniform(MaterialDiffuseMap);
|
|
||||||
CacheUniform(MaterialEmissiveMap);
|
|
||||||
CacheUniform(MaterialHeightMap);
|
|
||||||
CacheUniform(MaterialNormalMap);
|
|
||||||
CacheUniform(MaterialShininess);
|
|
||||||
CacheUniform(MaterialSpecular);
|
|
||||||
CacheUniform(MaterialSpecularMap);
|
|
||||||
CacheUniform(ProjMatrix);
|
|
||||||
CacheUniform(SceneAmbient);
|
|
||||||
CacheUniform(TargetSize);
|
|
||||||
CacheUniform(ViewMatrix);
|
|
||||||
CacheUniform(ViewProjMatrix);
|
|
||||||
CacheUniform(WorldMatrix);
|
|
||||||
CacheUniform(WorldViewMatrix);
|
|
||||||
CacheUniform(WorldViewProjMatrix);
|
|
||||||
|
|
||||||
#undef CacheUniform
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// On remplit le log avec l'erreur de compilation
|
|
||||||
GLint length = 0;
|
|
||||||
glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &length);
|
|
||||||
if (length > 1)
|
|
||||||
{
|
|
||||||
m_log.Clear(true);
|
|
||||||
m_log.Reserve(length+15-2); // La taille retournée est celle du buffer (Avec caractère de fin)
|
|
||||||
m_log.Prepend("Linkage error: ");
|
|
||||||
m_log.Resize(length+15-2); // Extension du buffer d'écriture pour ajouter le log
|
|
||||||
|
|
||||||
glGetProgramInfoLog(m_program, length-1, nullptr, &m_log[19]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_log = "Linkage failed but no info log found";
|
|
||||||
|
|
||||||
NazaraError(m_log);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzGLSLProgram::Create()
|
bool NzGLSLProgram::Create()
|
||||||
|
|
@ -160,6 +99,9 @@ bool NzGLSLProgram::Create()
|
||||||
for (int i = 0; i <= nzShaderType_Max; ++i)
|
for (int i = 0; i <= nzShaderType_Max; ++i)
|
||||||
m_shaders[i] = 0;
|
m_shaders[i] = 0;
|
||||||
|
|
||||||
|
if (NzOpenGL::IsSupported(nzOpenGLExtension_GetProgramBinary))
|
||||||
|
glProgramParameteri(m_program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,21 +121,20 @@ NzByteArray NzGLSLProgram::GetBinary() const
|
||||||
|
|
||||||
NzContext::EnsureContext();
|
NzContext::EnsureContext();
|
||||||
|
|
||||||
GLint binaryLength;
|
GLint binaryLength = 0;
|
||||||
glGetProgramiv(m_program, GL_PROGRAM_BINARY_LENGTH, &binaryLength);
|
glGetProgramiv(m_program, GL_PROGRAM_BINARY_LENGTH, &binaryLength);
|
||||||
|
|
||||||
if (binaryLength > 0)
|
if (binaryLength > 0)
|
||||||
{
|
{
|
||||||
byteArray.Resize(sizeof(nzUInt64) + binaryLength);
|
byteArray.Resize(sizeof(nzUInt64) + binaryLength);
|
||||||
|
|
||||||
nzUInt8* ptr = byteArray.GetBuffer();
|
nzUInt8* buffer = byteArray.GetBuffer();
|
||||||
|
|
||||||
GLenum binaryFormat;
|
GLenum binaryFormat;
|
||||||
glGetProgramBinary(m_program, binaryLength, nullptr, &binaryFormat, &ptr[sizeof(nzUInt64)]);
|
glGetProgramBinary(m_program, binaryLength, nullptr, &binaryFormat, &buffer[sizeof(nzUInt64)]);
|
||||||
|
|
||||||
// On stocke le format au début du binaire
|
// On stocke le format au début du binaire
|
||||||
nzUInt64* format = reinterpret_cast<nzUInt64*>(&ptr[0]);
|
*reinterpret_cast<nzUInt64*>(&buffer[0]) = binaryFormat;
|
||||||
*format = binaryFormat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return byteArray;
|
return byteArray;
|
||||||
|
|
@ -211,11 +152,11 @@ nzShaderLanguage NzGLSLProgram::GetLanguage() const
|
||||||
|
|
||||||
NzString NzGLSLProgram::GetSourceCode(nzShaderType type) const
|
NzString NzGLSLProgram::GetSourceCode(nzShaderType type) const
|
||||||
{
|
{
|
||||||
NzString source;
|
|
||||||
|
|
||||||
NzContext::EnsureContext();
|
NzContext::EnsureContext();
|
||||||
|
|
||||||
GLint length;
|
NzString source;
|
||||||
|
|
||||||
|
GLint length = 0;
|
||||||
glGetShaderiv(m_shaders[type], GL_SHADER_SOURCE_LENGTH, &length);
|
glGetShaderiv(m_shaders[type], GL_SHADER_SOURCE_LENGTH, &length);
|
||||||
if (length > 1)
|
if (length > 1)
|
||||||
{
|
{
|
||||||
|
|
@ -258,6 +199,32 @@ bool NzGLSLProgram::IsLoaded(nzShaderType type) const
|
||||||
return m_shaders[type] != 0;
|
return m_shaders[type] != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NzGLSLProgram::LoadFromBinary(const void* buffer, unsigned int size)
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (!glProgramBinary)
|
||||||
|
{
|
||||||
|
NazaraError("GL_ARB_get_program_binary not supported");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NzContext::EnsureContext();
|
||||||
|
|
||||||
|
const nzUInt8* ptr = reinterpret_cast<const nzUInt8*>(buffer);
|
||||||
|
|
||||||
|
// On récupère le format au début du binaire
|
||||||
|
///TODO: ByteStream ?
|
||||||
|
GLenum binaryFormat = static_cast<GLenum>(*reinterpret_cast<const nzUInt64*>(&ptr[0]));
|
||||||
|
ptr += sizeof(nzUInt64);
|
||||||
|
|
||||||
|
PreLinkage();
|
||||||
|
|
||||||
|
glProgramBinary(m_program, binaryFormat, ptr, size-sizeof(nzUInt64));
|
||||||
|
|
||||||
|
return PostLinkage();
|
||||||
|
}
|
||||||
|
|
||||||
bool NzGLSLProgram::LoadShader(nzShaderType type, const NzString& source)
|
bool NzGLSLProgram::LoadShader(nzShaderType type, const NzString& source)
|
||||||
{
|
{
|
||||||
NzContext::EnsureContext();
|
NzContext::EnsureContext();
|
||||||
|
|
@ -615,3 +582,72 @@ void NzGLSLProgram::OnResourceReleased(const NzResource* resource, int index)
|
||||||
|
|
||||||
resource->RemoveResourceListener(this);
|
resource->RemoveResourceListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NzGLSLProgram::PreLinkage()
|
||||||
|
{
|
||||||
|
m_idCache.clear();
|
||||||
|
m_textures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzGLSLProgram::PostLinkage()
|
||||||
|
{
|
||||||
|
// On suppose qu'un contexte OpenGL est actif à l'appel de cette fonction
|
||||||
|
GLint success;
|
||||||
|
glGetProgramiv(m_program, GL_LINK_STATUS, &success);
|
||||||
|
|
||||||
|
if (success == GL_TRUE)
|
||||||
|
{
|
||||||
|
static NzString successStr("Linkage successful");
|
||||||
|
m_log = successStr;
|
||||||
|
|
||||||
|
// Pour éviter de se tromper entre le nom et la constante
|
||||||
|
#define CacheUniform(name) m_uniformLocations[nzShaderUniform_##name] = GetUniformLocation(#name)
|
||||||
|
|
||||||
|
CacheUniform(CameraPosition);
|
||||||
|
CacheUniform(InvTargetSize);
|
||||||
|
CacheUniform(MaterialAlphaMap);
|
||||||
|
CacheUniform(MaterialAlphaThreshold);
|
||||||
|
CacheUniform(MaterialAmbient);
|
||||||
|
CacheUniform(MaterialDiffuse);
|
||||||
|
CacheUniform(MaterialDiffuseMap);
|
||||||
|
CacheUniform(MaterialEmissiveMap);
|
||||||
|
CacheUniform(MaterialHeightMap);
|
||||||
|
CacheUniform(MaterialNormalMap);
|
||||||
|
CacheUniform(MaterialShininess);
|
||||||
|
CacheUniform(MaterialSpecular);
|
||||||
|
CacheUniform(MaterialSpecularMap);
|
||||||
|
CacheUniform(ProjMatrix);
|
||||||
|
CacheUniform(SceneAmbient);
|
||||||
|
CacheUniform(TargetSize);
|
||||||
|
CacheUniform(ViewMatrix);
|
||||||
|
CacheUniform(ViewProjMatrix);
|
||||||
|
CacheUniform(WorldMatrix);
|
||||||
|
CacheUniform(WorldViewMatrix);
|
||||||
|
CacheUniform(WorldViewProjMatrix);
|
||||||
|
|
||||||
|
#undef CacheUniform
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// On remplit le log avec l'erreur de compilation
|
||||||
|
GLint length = 0;
|
||||||
|
glGetProgramiv(m_program, GL_INFO_LOG_LENGTH, &length);
|
||||||
|
if (length > 1)
|
||||||
|
{
|
||||||
|
m_log.Clear(true);
|
||||||
|
m_log.Reserve(length+15-2); // La taille retournée est celle du buffer (Avec caractère de fin)
|
||||||
|
m_log.Prepend("Linkage error: ");
|
||||||
|
m_log.Resize(length+15-2); // Extension du buffer d'écriture pour ajouter le log
|
||||||
|
|
||||||
|
glGetProgramInfoLog(m_program, length-1, nullptr, &m_log[19]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_log = "Linkage failed but no info log found";
|
||||||
|
|
||||||
|
NazaraError(m_log);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ class NzGLSLProgram : public NzAbstractShaderProgram, NzResourceListener
|
||||||
bool IsBinaryRetrievable() const;
|
bool IsBinaryRetrievable() const;
|
||||||
bool IsLoaded(nzShaderType type) const;
|
bool IsLoaded(nzShaderType type) const;
|
||||||
|
|
||||||
|
bool LoadFromBinary(const void* buffer, unsigned int size);
|
||||||
bool LoadShader(nzShaderType type, const NzString& source);
|
bool LoadShader(nzShaderType type, const NzString& source);
|
||||||
|
|
||||||
bool SendBoolean(int location, bool value);
|
bool SendBoolean(int location, bool value);
|
||||||
|
|
@ -62,6 +63,8 @@ class NzGLSLProgram : public NzAbstractShaderProgram, NzResourceListener
|
||||||
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;
|
||||||
void OnResourceReleased(const NzResource* resource, int index) override;
|
void OnResourceReleased(const NzResource* resource, int index) override;
|
||||||
|
void PreLinkage();
|
||||||
|
bool PostLinkage();
|
||||||
|
|
||||||
struct TextureSlot
|
struct TextureSlot
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,8 @@ bool NzShaderProgram::Compile()
|
||||||
|
|
||||||
void NzShaderProgram::Destroy()
|
void NzShaderProgram::Destroy()
|
||||||
{
|
{
|
||||||
|
m_compiled = false;
|
||||||
|
|
||||||
if (m_impl)
|
if (m_impl)
|
||||||
{
|
{
|
||||||
NotifyDestroy();
|
NotifyDestroy();
|
||||||
|
|
@ -128,7 +130,19 @@ NzByteArray NzShaderProgram::GetBinary() const
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return m_impl->GetBinary();
|
NzByteArray binary(m_impl->GetBinary());
|
||||||
|
if (binary.IsEmpty())
|
||||||
|
return NzByteArray();
|
||||||
|
|
||||||
|
NzByteArray byteArray;
|
||||||
|
|
||||||
|
///TODO: ByteStream
|
||||||
|
|
||||||
|
nzUInt32 language = static_cast<nzUInt32>(m_impl->GetLanguage());
|
||||||
|
byteArray.Append(&language, sizeof(nzUInt32));
|
||||||
|
byteArray.Append(binary);
|
||||||
|
|
||||||
|
return byteArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
nzUInt32 NzShaderProgram::GetFlags() const
|
nzUInt32 NzShaderProgram::GetFlags() const
|
||||||
|
|
@ -286,6 +300,43 @@ bool NzShaderProgram::IsValid() const
|
||||||
return m_impl != nullptr;
|
return m_impl != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NzShaderProgram::LoadFromBinary(const void* buffer, unsigned int size)
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (size <= sizeof(nzUInt32))
|
||||||
|
{
|
||||||
|
NazaraError("Invalid binary");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
///TODO: ByteStream
|
||||||
|
const nzUInt8* ptr = static_cast<const nzUInt8*>(buffer);
|
||||||
|
|
||||||
|
nzShaderLanguage language = static_cast<nzShaderLanguage>(*reinterpret_cast<const nzUInt32*>(&ptr[0]));
|
||||||
|
ptr += sizeof(nzUInt32);
|
||||||
|
|
||||||
|
if (!Create(language))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to create shader");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_impl->LoadFromBinary(ptr, size-sizeof(nzUInt32)))
|
||||||
|
{
|
||||||
|
m_compiled = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzShaderProgram::LoadFromBinary(const NzByteArray& byteArray)
|
||||||
|
{
|
||||||
|
return LoadFromBinary(byteArray.GetConstBuffer(), byteArray.GetSize());
|
||||||
|
}
|
||||||
|
|
||||||
bool NzShaderProgram::LoadShader(nzShaderType type, const NzString& source)
|
bool NzShaderProgram::LoadShader(nzShaderType type, const NzString& source)
|
||||||
{
|
{
|
||||||
#if NAZARA_RENDERER_SAFE
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue