Added ShaderBuilder
Former-commit-id: 0eee75821b7bb4b2b69a020c8e79f3cbe18b522f
This commit is contained in:
parent
a9e82f6014
commit
df7b11d1d2
|
|
@ -0,0 +1,28 @@
|
||||||
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_SHADERBUILDER_HPP
|
||||||
|
#define NAZARA_SHADERBUILDER_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
#include <Nazara/Renderer/Shader.hpp>
|
||||||
|
|
||||||
|
class NAZARA_API NzShaderBuilder
|
||||||
|
{
|
||||||
|
friend class NzRenderer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
NzShaderBuilder() = delete;
|
||||||
|
~NzShaderBuilder() = delete;
|
||||||
|
|
||||||
|
static const NzShader* Get(nzUInt32 flags);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool Initialize();
|
||||||
|
static void Uninitialize();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_SHADER_HPP
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include <Nazara/Renderer/Material.hpp>
|
#include <Nazara/Renderer/Material.hpp>
|
||||||
#include <Nazara/Renderer/RenderTarget.hpp>
|
#include <Nazara/Renderer/RenderTarget.hpp>
|
||||||
#include <Nazara/Renderer/Shader.hpp>
|
#include <Nazara/Renderer/Shader.hpp>
|
||||||
|
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||||
#include <Nazara/Renderer/ShaderImpl.hpp>
|
#include <Nazara/Renderer/ShaderImpl.hpp>
|
||||||
#include <Nazara/Renderer/Loaders/Texture.hpp>
|
#include <Nazara/Renderer/Loaders/Texture.hpp>
|
||||||
#include <Nazara/Utility/BufferImpl.hpp>
|
#include <Nazara/Utility/BufferImpl.hpp>
|
||||||
|
|
@ -466,6 +467,14 @@ bool NzRenderer::Initialize(bool initializeDebugDrawer)
|
||||||
if (initializeDebugDrawer && !NzDebugDrawer::Initialize())
|
if (initializeDebugDrawer && !NzDebugDrawer::Initialize())
|
||||||
NazaraWarning("Failed to initialize debug drawer"); // Non-critique
|
NazaraWarning("Failed to initialize debug drawer"); // Non-critique
|
||||||
|
|
||||||
|
if (!NzShaderBuilder::Initialize())
|
||||||
|
{
|
||||||
|
NazaraError("Failed to initialize shader builder");
|
||||||
|
Uninitialize();
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!NzTextureSampler::Initialize())
|
if (!NzTextureSampler::Initialize())
|
||||||
{
|
{
|
||||||
NazaraError("Failed to initialize texture sampler");
|
NazaraError("Failed to initialize texture sampler");
|
||||||
|
|
@ -1019,6 +1028,7 @@ void NzRenderer::Uninitialize()
|
||||||
NzLoaders_Texture_Unregister();
|
NzLoaders_Texture_Unregister();
|
||||||
|
|
||||||
NzDebugDrawer::Uninitialize();
|
NzDebugDrawer::Uninitialize();
|
||||||
|
NzShaderBuilder::Uninitialize();
|
||||||
NzTextureSampler::Uninitialize();
|
NzTextureSampler::Uninitialize();
|
||||||
|
|
||||||
NzContext::EnsureContext();
|
NzContext::EnsureContext();
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,200 @@
|
||||||
|
// Copyright (C) 2012 Jérôme Leclercq
|
||||||
|
// This file is part of the "Nazara Engine - Renderer module"
|
||||||
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
|
#include <Nazara/Renderer/OpenGL.hpp>
|
||||||
|
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||||
|
#include <Nazara/Renderer/Renderer.hpp>
|
||||||
|
#include <Nazara/Renderer/Shader.hpp>
|
||||||
|
#include <map>
|
||||||
|
#include <Nazara/Renderer/Debug.hpp>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
std::map<nzUInt32, NzShader*> s_shaders;
|
||||||
|
|
||||||
|
NzString BuildFragmentShaderSource(nzUInt32 flags)
|
||||||
|
{
|
||||||
|
bool glsl140 = (NzOpenGL::GetVersion() >= 300);
|
||||||
|
bool useMRT = (glsl140 && NzRenderer::HasCapability(nzRendererCap_MultipleRenderTargets));
|
||||||
|
|
||||||
|
NzString inKW = (glsl140) ? "in" : "varying";
|
||||||
|
NzString fragmentColorKW = (glsl140) ? "RenderTarget0" : "gl_FragColor";
|
||||||
|
|
||||||
|
NzString sourceCode;
|
||||||
|
sourceCode.Reserve(256); // Le shader peut faire plus, mais cela évite déjà beaucoup de petites allocations
|
||||||
|
|
||||||
|
/********************Version de GLSL********************/
|
||||||
|
sourceCode = "#version ";
|
||||||
|
if (glsl140)
|
||||||
|
sourceCode += "140\n";
|
||||||
|
else
|
||||||
|
sourceCode += "110\n";
|
||||||
|
|
||||||
|
sourceCode += '\n';
|
||||||
|
|
||||||
|
/********************Uniformes********************/
|
||||||
|
if ((flags & nzShaderBuilder_DiffuseMapping) == 0 || flags & nzShaderBuilder_Lighting)
|
||||||
|
sourceCode += "uniform vec3 DiffuseColor;\n";
|
||||||
|
|
||||||
|
if (flags & nzShaderBuilder_DiffuseMapping)
|
||||||
|
sourceCode += "uniform sampler2D DiffuseMap;\n";
|
||||||
|
|
||||||
|
sourceCode += '\n';
|
||||||
|
|
||||||
|
/********************Entrant********************/
|
||||||
|
if (flags & nzShaderBuilder_DiffuseMapping)
|
||||||
|
{
|
||||||
|
sourceCode += inKW;
|
||||||
|
sourceCode += " vec2 vTexCoord;\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceCode += '\n';
|
||||||
|
|
||||||
|
/********************Sortant********************/
|
||||||
|
if (useMRT)
|
||||||
|
sourceCode += "out vec4 RenderTarget0;\n";
|
||||||
|
|
||||||
|
sourceCode += '\n';
|
||||||
|
|
||||||
|
/********************Code********************/
|
||||||
|
sourceCode += "void main()\n{\n";
|
||||||
|
|
||||||
|
sourceCode += '\t';
|
||||||
|
sourceCode += fragmentColorKW;
|
||||||
|
if (flags & nzShaderBuilder_DiffuseMapping)
|
||||||
|
sourceCode += " = texture2D(DiffuseMap, vTexCoord);\n";
|
||||||
|
else
|
||||||
|
sourceCode += " = vec4(DiffuseColor, 1.0);\n";
|
||||||
|
|
||||||
|
sourceCode += '}';
|
||||||
|
|
||||||
|
sourceCode += '\n';
|
||||||
|
|
||||||
|
return sourceCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
NzString BuildVertexShaderSource(nzUInt32 flags)
|
||||||
|
{
|
||||||
|
bool glsl140 = (NzOpenGL::GetVersion() >= 300);
|
||||||
|
|
||||||
|
NzString inKW = (glsl140) ? "in" : "attribute";
|
||||||
|
NzString outKW = (glsl140) ? "out" : "varying";
|
||||||
|
|
||||||
|
NzString sourceCode;
|
||||||
|
sourceCode.Reserve(256); // Le shader peut faire plus, mais cela évite déjà beaucoup de petites allocations
|
||||||
|
|
||||||
|
/********************Version de GLSL********************/
|
||||||
|
sourceCode = "#version ";
|
||||||
|
if (glsl140)
|
||||||
|
sourceCode += "140\n";
|
||||||
|
else
|
||||||
|
sourceCode += "110\n";
|
||||||
|
|
||||||
|
sourceCode += '\n';
|
||||||
|
|
||||||
|
/********************Uniformes********************/
|
||||||
|
sourceCode += "uniform mat4 WorldViewProjMatrix;\n";
|
||||||
|
|
||||||
|
sourceCode += '\n';
|
||||||
|
|
||||||
|
/********************Entrant********************/
|
||||||
|
sourceCode += inKW;
|
||||||
|
sourceCode += " vec3 Position;\n";
|
||||||
|
|
||||||
|
if (flags & nzShaderBuilder_Lighting || flags & nzShaderBuilder_NormalMapping || flags & nzShaderBuilder_ParallaxMapping)
|
||||||
|
{
|
||||||
|
sourceCode += inKW;
|
||||||
|
sourceCode += " vec3 Normal;\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & nzShaderBuilder_Lighting)
|
||||||
|
{
|
||||||
|
sourceCode += inKW;
|
||||||
|
sourceCode += " vec3 Tangent;\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & nzShaderBuilder_DiffuseMapping || flags & nzShaderBuilder_Lighting || flags & nzShaderBuilder_NormalMapping || flags & nzShaderBuilder_ParallaxMapping)
|
||||||
|
{
|
||||||
|
sourceCode += inKW;
|
||||||
|
sourceCode += " vec2 TexCoord0;\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceCode += '\n';
|
||||||
|
|
||||||
|
/********************Sortant********************/
|
||||||
|
if (flags & nzShaderBuilder_DiffuseMapping)
|
||||||
|
{
|
||||||
|
sourceCode += outKW;
|
||||||
|
sourceCode += " vec2 vTexCoord;\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceCode += '\n';
|
||||||
|
|
||||||
|
/********************Code********************/
|
||||||
|
sourceCode += "void main()\n{\n";
|
||||||
|
|
||||||
|
sourceCode += "\tgl_Position = WorldViewProjMatrix * vec4(Position, 1.0);\n";
|
||||||
|
|
||||||
|
if (flags & nzShaderBuilder_DiffuseMapping)
|
||||||
|
sourceCode += "\tvTexCoord = TexCoord0;\n";
|
||||||
|
|
||||||
|
sourceCode += '}';
|
||||||
|
|
||||||
|
sourceCode += '\n';
|
||||||
|
|
||||||
|
return sourceCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const NzShader* NzShaderBuilder::Get(nzUInt32 flags)
|
||||||
|
{
|
||||||
|
auto it = s_shaders.find(flags);
|
||||||
|
if (it == s_shaders.end())
|
||||||
|
{
|
||||||
|
// Alors nous créons le shader
|
||||||
|
NzShader* shader = new NzShader;
|
||||||
|
if (!shader->Create(nzShaderLanguage_GLSL))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to create shader");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shader->Load(nzShaderType_Fragment, BuildFragmentShaderSource(flags)))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to load fragment shader: " + shader->GetLog());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shader->Load(nzShaderType_Vertex, BuildVertexShaderSource(flags)))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to load vertex shader: " + shader->GetLog());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!shader->Compile())
|
||||||
|
{
|
||||||
|
NazaraError("Failed to compile shader: " + shader->GetLog());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
s_shaders[flags] = shader;
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzShaderBuilder::Initialize()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzShaderBuilder::Uninitialize()
|
||||||
|
{
|
||||||
|
for (auto it : s_shaders)
|
||||||
|
delete it.second;
|
||||||
|
|
||||||
|
s_shaders.clear();
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue