Big UberShader update
-Added GRAPHICS_MAX_LIGHTPERPASS macro -Added glGetActiveUniform OpenGL function -Added (Uber)ShaderLibrary -Added (Uber)ShaderName parameter to models -Changed uniform system -Fixed Node copying -Moved Material class to Graphics module -Optimized lights -Remade Shader class -Renamed Node::Invalidate to Node::InvalidateNode -Renamed ShaderProgram to Shader Former-commit-id: 15f0cad52969e91a2442e7d750ba2dc412f3549d
This commit is contained in:
@@ -8,17 +8,16 @@
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/ErrorFlags.hpp>
|
||||
#include <Nazara/Core/Log.hpp>
|
||||
#include <Nazara/Renderer/AbstractShaderProgram.hpp>
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <Nazara/Renderer/DebugDrawer.hpp>
|
||||
#include <Nazara/Renderer/HardwareBuffer.hpp>
|
||||
#include <Nazara/Renderer/Material.hpp>
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||
#include <Nazara/Renderer/ShaderProgram.hpp>
|
||||
#include <Nazara/Renderer/ShaderProgramManager.hpp>
|
||||
#include <Nazara/Renderer/Loaders/Texture.hpp>
|
||||
#include <Nazara/Renderer/Shader.hpp>
|
||||
#include <Nazara/Renderer/ShaderLibrary.hpp>
|
||||
#include <Nazara/Renderer/Texture.hpp>
|
||||
#include <Nazara/Renderer/UberShaderLibrary.hpp>
|
||||
#include <Nazara/Utility/AbstractBuffer.hpp>
|
||||
#include <Nazara/Utility/IndexBuffer.hpp>
|
||||
#include <Nazara/Utility/Utility.hpp>
|
||||
@@ -48,7 +47,7 @@ namespace
|
||||
Update_None = 0,
|
||||
|
||||
Update_Matrices = 0x1,
|
||||
Update_Program = 0x2,
|
||||
Update_Shader = 0x2,
|
||||
Update_Textures = 0x4,
|
||||
Update_VAO = 0x8
|
||||
};
|
||||
@@ -84,7 +83,7 @@ namespace
|
||||
nzUInt32 s_updateFlags;
|
||||
const NzIndexBuffer* s_indexBuffer;
|
||||
const NzRenderTarget* s_target;
|
||||
const NzShaderProgram* s_program;
|
||||
const NzShader* s_shader;
|
||||
const NzVertexBuffer* s_vertexBuffer;
|
||||
const NzVertexDeclaration* s_instancingDeclaration;
|
||||
bool s_capabilities[nzRendererCap_Max+1];
|
||||
@@ -605,9 +604,9 @@ NzRecti NzRenderer::GetScissorRect()
|
||||
return NzOpenGL::GetCurrentScissorBox();
|
||||
}
|
||||
|
||||
const NzShaderProgram* NzRenderer::GetShaderProgram()
|
||||
const NzShader* NzRenderer::GetShader()
|
||||
{
|
||||
return s_program;
|
||||
return s_shader;
|
||||
}
|
||||
|
||||
const NzRenderTarget* NzRenderer::GetTarget()
|
||||
@@ -734,14 +733,14 @@ bool NzRenderer::Initialize()
|
||||
s_states = NzRenderStates();
|
||||
|
||||
s_indexBuffer = nullptr;
|
||||
s_program = nullptr;
|
||||
s_shader = nullptr;
|
||||
s_target = nullptr;
|
||||
s_targetSize.Set(0U);
|
||||
s_textureUnits.resize(s_maxTextureUnit);
|
||||
s_useSamplerObjects = NzOpenGL::IsSupported(nzOpenGLExtension_SamplerObjects);
|
||||
s_useVertexArrayObjects = NzOpenGL::IsSupported(nzOpenGLExtension_VertexArrayObjects);
|
||||
s_updateFlags = (Update_Matrices | Update_Shader | Update_VAO);
|
||||
s_vertexBuffer = nullptr;
|
||||
s_updateFlags = (Update_Matrices | Update_Program | Update_VAO);
|
||||
|
||||
s_fullscreenQuadBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzBufferStorage_Hardware, nzBufferUsage_Static);
|
||||
|
||||
@@ -769,19 +768,15 @@ bool NzRenderer::Initialize()
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
s_capabilities[nzRendererCap_Instancing] = false;
|
||||
NazaraError("Failed to create instancing buffer: " + NzString(e.what())); ///TODO: Noexcept
|
||||
|
||||
NzErrorFlags flags(nzErrorFlag_ThrowExceptionDisabled);
|
||||
NazaraError("Failed to create instancing buffer: " + NzString(e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
if (!NzMaterial::Initialize())
|
||||
if (!NzShaderLibrary::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize materials");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NzShaderProgramManager::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize shader program manager");
|
||||
NazaraError("Failed to initialize shader library");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -791,8 +786,77 @@ bool NzRenderer::Initialize()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Loaders
|
||||
NzLoaders_Texture_Register();
|
||||
if (!NzUberShaderLibrary::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize uber shader library");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Création du shader de Debug
|
||||
std::unique_ptr<NzShader> shader(new NzShader);
|
||||
shader->SetPersistent(false);
|
||||
|
||||
if (!shader->Create())
|
||||
{
|
||||
NazaraError("Failed to create debug shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
const nzUInt8 coreFragmentShader[] = {
|
||||
#include <Nazara/Renderer/Resources/Shaders/Debug/core.frag.h>
|
||||
};
|
||||
|
||||
const nzUInt8 coreVertexShader[] = {
|
||||
#include <Nazara/Renderer/Resources/Shaders/Debug/core.vert.h>
|
||||
};
|
||||
|
||||
const nzUInt8 compatibilityFragmentShader[] = {
|
||||
#include <Nazara/Renderer/Resources/Shaders/Debug/compatibility.frag.h>
|
||||
};
|
||||
|
||||
const nzUInt8 compatibilityVertexShader[] = {
|
||||
#include <Nazara/Renderer/Resources/Shaders/Debug/compatibility.vert.h>
|
||||
};
|
||||
|
||||
const char* fragmentShader;
|
||||
const char* vertexShader;
|
||||
unsigned int fragmentShaderLength;
|
||||
unsigned int vertexShaderLength;
|
||||
if (NzOpenGL::GetGLSLVersion() >= 140)
|
||||
{
|
||||
fragmentShader = reinterpret_cast<const char*>(coreFragmentShader);
|
||||
fragmentShaderLength = sizeof(coreFragmentShader);
|
||||
vertexShader = reinterpret_cast<const char*>(coreVertexShader);
|
||||
vertexShaderLength = sizeof(coreVertexShader);
|
||||
}
|
||||
else
|
||||
{
|
||||
fragmentShader = reinterpret_cast<const char*>(compatibilityFragmentShader);
|
||||
fragmentShaderLength = sizeof(compatibilityFragmentShader);
|
||||
vertexShader = reinterpret_cast<const char*>(compatibilityVertexShader);
|
||||
vertexShaderLength = sizeof(compatibilityVertexShader);
|
||||
}
|
||||
|
||||
if (!shader->AttachStageFromSource(nzShaderStage_Fragment, fragmentShader, fragmentShaderLength))
|
||||
{
|
||||
NazaraError("Failed to attach fragment stage");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!shader->AttachStageFromSource(nzShaderStage_Vertex, vertexShader, vertexShaderLength))
|
||||
{
|
||||
NazaraError("Failed to attach vertex stage");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!shader->Link())
|
||||
{
|
||||
NazaraError("Failed to link shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzShaderLibrary::Register("DebugSimple", shader.get());
|
||||
shader.release();
|
||||
|
||||
onExit.Reset();
|
||||
|
||||
@@ -1051,20 +1115,23 @@ void NzRenderer::SetScissorRect(const NzRecti& rect)
|
||||
NzOpenGL::BindScissorBox(rect);
|
||||
}
|
||||
|
||||
void NzRenderer::SetShaderProgram(const NzShaderProgram* program)
|
||||
void NzRenderer::SetShader(const NzShader* shader)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (program && !program->IsCompiled())
|
||||
if (shader)
|
||||
{
|
||||
NazaraError("Shader program is not compiled");
|
||||
return;
|
||||
if (!shader->IsValid() || !shader->IsLinked())
|
||||
{
|
||||
NazaraError("Invalid shader");
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (s_program != program)
|
||||
if (s_shader != shader)
|
||||
{
|
||||
s_program = program;
|
||||
s_updateFlags |= Update_Program;
|
||||
s_shader = shader;
|
||||
s_updateFlags |= Update_Shader;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1373,16 +1440,15 @@ void NzRenderer::Uninitialize()
|
||||
// Libération du module
|
||||
s_moduleReferenceCounter = 0;
|
||||
|
||||
s_textureUnits.clear();
|
||||
|
||||
// Loaders
|
||||
NzLoaders_Texture_Unregister();
|
||||
NzShaderLibrary::Unregister("DebugSimple");
|
||||
|
||||
NzUberShaderLibrary::Uninitialize();
|
||||
NzTextureSampler::Uninitialize();
|
||||
NzShaderProgramManager::Uninitialize();
|
||||
NzMaterial::Uninitialize();
|
||||
NzShaderLibrary::Uninitialize();
|
||||
NzDebugDrawer::Uninitialize();
|
||||
|
||||
s_textureUnits.clear();
|
||||
|
||||
// Libération des buffers
|
||||
s_fullscreenQuadBuffer.Reset();
|
||||
s_instanceBuffer.Reset();
|
||||
@@ -1447,9 +1513,9 @@ bool NzRenderer::EnsureStateUpdate()
|
||||
#endif
|
||||
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!s_program)
|
||||
if (!s_shader)
|
||||
{
|
||||
NazaraError("No shader program");
|
||||
NazaraError("No shader");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1462,49 +1528,46 @@ bool NzRenderer::EnsureStateUpdate()
|
||||
|
||||
s_target->EnsureTargetUpdated();
|
||||
|
||||
NzAbstractShaderProgram* programImpl = s_program->m_impl;
|
||||
programImpl->Bind(); // Active le programme si ce n'est pas déjà le cas
|
||||
s_shader->Bind(); // Active le programme si ce n'est pas déjà le cas
|
||||
|
||||
// Si le programme a été changé depuis la dernière fois
|
||||
if (s_updateFlags & Update_Program)
|
||||
if (s_updateFlags & Update_Shader)
|
||||
{
|
||||
// Récupération des indices des variables uniformes (-1 si la variable n'existe pas)
|
||||
s_matrices[nzMatrixType_Projection].location = programImpl->GetUniformLocation(nzShaderUniform_ProjMatrix);
|
||||
s_matrices[nzMatrixType_View].location = programImpl->GetUniformLocation(nzShaderUniform_ViewMatrix);
|
||||
s_matrices[nzMatrixType_World].location = programImpl->GetUniformLocation(nzShaderUniform_WorldMatrix);
|
||||
s_matrices[nzMatrixType_Projection].location = s_shader->GetUniformLocation(nzShaderUniform_ProjMatrix);
|
||||
s_matrices[nzMatrixType_View].location = s_shader->GetUniformLocation(nzShaderUniform_ViewMatrix);
|
||||
s_matrices[nzMatrixType_World].location = s_shader->GetUniformLocation(nzShaderUniform_WorldMatrix);
|
||||
|
||||
s_matrices[nzMatrixType_ViewProj].location = programImpl->GetUniformLocation(nzShaderUniform_ViewProjMatrix);
|
||||
s_matrices[nzMatrixType_WorldView].location = programImpl->GetUniformLocation(nzShaderUniform_WorldViewMatrix);
|
||||
s_matrices[nzMatrixType_WorldViewProj].location = programImpl->GetUniformLocation(nzShaderUniform_WorldViewProjMatrix);
|
||||
s_matrices[nzMatrixType_ViewProj].location = s_shader->GetUniformLocation(nzShaderUniform_ViewProjMatrix);
|
||||
s_matrices[nzMatrixType_WorldView].location = s_shader->GetUniformLocation(nzShaderUniform_WorldViewMatrix);
|
||||
s_matrices[nzMatrixType_WorldViewProj].location = s_shader->GetUniformLocation(nzShaderUniform_WorldViewProjMatrix);
|
||||
|
||||
s_matrices[nzMatrixType_InvProjection].location = programImpl->GetUniformLocation(nzShaderUniform_InvProjMatrix);
|
||||
s_matrices[nzMatrixType_InvView].location = programImpl->GetUniformLocation(nzShaderUniform_InvViewMatrix);
|
||||
s_matrices[nzMatrixType_InvViewProj].location = programImpl->GetUniformLocation(nzShaderUniform_InvViewProjMatrix);
|
||||
s_matrices[nzMatrixType_InvWorld].location = programImpl->GetUniformLocation(nzShaderUniform_InvWorldMatrix);
|
||||
s_matrices[nzMatrixType_InvWorldView].location = programImpl->GetUniformLocation(nzShaderUniform_InvWorldViewMatrix);
|
||||
s_matrices[nzMatrixType_InvWorldViewProj].location = programImpl->GetUniformLocation(nzShaderUniform_InvWorldViewProjMatrix);
|
||||
s_matrices[nzMatrixType_InvProjection].location = s_shader->GetUniformLocation(nzShaderUniform_InvProjMatrix);
|
||||
s_matrices[nzMatrixType_InvView].location = s_shader->GetUniformLocation(nzShaderUniform_InvViewMatrix);
|
||||
s_matrices[nzMatrixType_InvViewProj].location = s_shader->GetUniformLocation(nzShaderUniform_InvViewProjMatrix);
|
||||
s_matrices[nzMatrixType_InvWorld].location = s_shader->GetUniformLocation(nzShaderUniform_InvWorldMatrix);
|
||||
s_matrices[nzMatrixType_InvWorldView].location = s_shader->GetUniformLocation(nzShaderUniform_InvWorldViewMatrix);
|
||||
s_matrices[nzMatrixType_InvWorldViewProj].location = s_shader->GetUniformLocation(nzShaderUniform_InvWorldViewProjMatrix);
|
||||
|
||||
s_targetSize.Set(0U); // On force l'envoi des uniformes
|
||||
s_updateFlags |= Update_Matrices; // Changement de programme, on renvoie toutes les matrices demandées
|
||||
|
||||
s_updateFlags &= ~Update_Program;
|
||||
s_updateFlags &= ~Update_Shader;
|
||||
}
|
||||
|
||||
programImpl->BindTextures();
|
||||
|
||||
// Envoi des uniformes liées au Renderer
|
||||
NzVector2ui targetSize(s_target->GetWidth(), s_target->GetHeight());
|
||||
if (s_targetSize != targetSize)
|
||||
{
|
||||
int location;
|
||||
|
||||
location = programImpl->GetUniformLocation(nzShaderUniform_InvTargetSize);
|
||||
location = s_shader->GetUniformLocation(nzShaderUniform_InvTargetSize);
|
||||
if (location != -1)
|
||||
programImpl->SendVector(location, 1.f/NzVector2f(targetSize));
|
||||
s_shader->SendVector(location, 1.f/NzVector2f(targetSize));
|
||||
|
||||
location = programImpl->GetUniformLocation(nzShaderUniform_TargetSize);
|
||||
location = s_shader->GetUniformLocation(nzShaderUniform_TargetSize);
|
||||
if (location != -1)
|
||||
programImpl->SendVector(location, NzVector2f(targetSize));
|
||||
s_shader->SendVector(location, NzVector2f(targetSize));
|
||||
|
||||
s_targetSize.Set(targetSize);
|
||||
}
|
||||
@@ -1570,7 +1633,7 @@ bool NzRenderer::EnsureStateUpdate()
|
||||
if (!unit.updated)
|
||||
UpdateMatrix(static_cast<nzMatrixType>(i));
|
||||
|
||||
programImpl->SendMatrix(unit.location, unit.matrix);
|
||||
s_shader->SendMatrix(unit.location, unit.matrix);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1744,7 +1807,7 @@ bool NzRenderer::EnsureStateUpdate()
|
||||
glBindVertexArray(s_currentVAO);
|
||||
|
||||
// On vérifie que les textures actuellement bindées sont bien nos textures
|
||||
// Ceci à cause du fait qu'il est possible que des opérations sur les textures ait eu lieu
|
||||
// Ceci à cause du fait qu'il est possible que des opérations sur les textures aient eu lieu
|
||||
// entre le dernier rendu et maintenant
|
||||
for (unsigned int i = 0; i < s_maxTextureUnit; ++i)
|
||||
{
|
||||
@@ -1753,18 +1816,18 @@ bool NzRenderer::EnsureStateUpdate()
|
||||
NzOpenGL::BindTexture(i, texture->GetType(), texture->GetOpenGLID());
|
||||
}
|
||||
|
||||
// Et on termine par envoyer nos états à OpenGL
|
||||
// Et on termine par envoyer nos états au driver
|
||||
NzOpenGL::ApplyStates(s_states);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzRenderer::OnProgramReleased(const NzShaderProgram* program)
|
||||
void NzRenderer::OnShaderReleased(const NzShader* shader)
|
||||
{
|
||||
if (s_program == program)
|
||||
if (s_shader == shader)
|
||||
{
|
||||
s_program = nullptr;
|
||||
s_updateFlags |= Update_Program;
|
||||
s_shader = nullptr;
|
||||
s_updateFlags |= Update_Shader;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user