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/RenderTarget.hpp>
|
||||
#include <Nazara/Renderer/Shader.hpp>
|
||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||
#include <Nazara/Renderer/ShaderImpl.hpp>
|
||||
#include <Nazara/Renderer/Loaders/Texture.hpp>
|
||||
#include <Nazara/Utility/BufferImpl.hpp>
|
||||
|
|
@ -466,6 +467,14 @@ bool NzRenderer::Initialize(bool initializeDebugDrawer)
|
|||
if (initializeDebugDrawer && !NzDebugDrawer::Initialize())
|
||||
NazaraWarning("Failed to initialize debug drawer"); // Non-critique
|
||||
|
||||
if (!NzShaderBuilder::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize shader builder");
|
||||
Uninitialize();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!NzTextureSampler::Initialize())
|
||||
{
|
||||
NazaraError("Failed to initialize texture sampler");
|
||||
|
|
@ -1019,6 +1028,7 @@ void NzRenderer::Uninitialize()
|
|||
NzLoaders_Texture_Unregister();
|
||||
|
||||
NzDebugDrawer::Uninitialize();
|
||||
NzShaderBuilder::Uninitialize();
|
||||
NzTextureSampler::Uninitialize();
|
||||
|
||||
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