Added ShaderManager (Experimental)
Former-commit-id: 327e373f2b932e31184e88c5f29bd5bd8fa3ba46
This commit is contained in:
@@ -2,101 +2,23 @@
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#ifndef NAZARA_RENDERER_OPENGL
|
||||
#define NAZARA_RENDERER_OPENGL // Nécessaire pour inclure les headers OpenGL
|
||||
#endif
|
||||
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Graphics/ColorBackGround.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||
#include <Nazara/Renderer/ShaderManager.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
NzShader* BuildShader()
|
||||
{
|
||||
const char* fragmentSource110 =
|
||||
"#version 110\n"
|
||||
"uniform vec4 Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = Color;\n"
|
||||
"}\n";
|
||||
|
||||
const char* fragmentSource140 =
|
||||
"#version 140\n"
|
||||
"out vec4 RenderTarget0;\n"
|
||||
"uniform vec4 Color;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" RenderTarget0 = Color;\n"
|
||||
"}\n";
|
||||
|
||||
const char* vertexSource110 =
|
||||
"#version 110\n"
|
||||
"attribute vec2 VertexPosition;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(VertexPosition, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
const char* vertexSource140 =
|
||||
"#version 140\n"
|
||||
"in vec2 VertexPosition;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(VertexPosition, 0.0, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
///TODO: Remplacer ça par des ShaderNode
|
||||
std::unique_ptr<NzShader> shader(new NzShader(nzShaderLanguage_GLSL));
|
||||
shader->SetPersistent(false);
|
||||
|
||||
bool useGLSL140 = (NzOpenGL::GetVersion() >= 310);
|
||||
|
||||
if (!shader->Load(nzShaderType_Fragment, (useGLSL140) ? fragmentSource140 : fragmentSource110))
|
||||
{
|
||||
NazaraError("Failed to load fragment shader");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!shader->Load(nzShaderType_Vertex, (useGLSL140) ? vertexSource140 : vertexSource110))
|
||||
{
|
||||
NazaraError("Failed to load vertex shader");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!shader->Compile())
|
||||
{
|
||||
NazaraError("Failed to compile shader");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return shader.release();
|
||||
}
|
||||
|
||||
static NzShader* s_shader = nullptr;
|
||||
static unsigned int s_colorLocation;
|
||||
}
|
||||
|
||||
NzColorBackground::NzColorBackground(const NzColor& color) :
|
||||
m_color(color)
|
||||
{
|
||||
if (!s_shader)
|
||||
{
|
||||
s_shader = BuildShader();
|
||||
s_colorLocation = s_shader->GetUniformLocation("Color");
|
||||
}
|
||||
NzShaderManagerParams params;
|
||||
params.target = nzShaderTarget_FullscreenQuad;
|
||||
params.flags = 0;
|
||||
params.fullscreenQuad.alphaMapping = false;
|
||||
params.fullscreenQuad.alphaTest = false;
|
||||
params.fullscreenQuad.diffuseMapping = false;
|
||||
|
||||
m_shader = s_shader;
|
||||
}
|
||||
|
||||
NzColorBackground::~NzColorBackground()
|
||||
{
|
||||
if (m_shader.Reset())
|
||||
s_shader = nullptr;
|
||||
m_shader = NzShaderManager::Get(params);
|
||||
}
|
||||
|
||||
void NzColorBackground::Draw(const NzScene* scene) const
|
||||
@@ -105,7 +27,7 @@ void NzColorBackground::Draw(const NzScene* scene) const
|
||||
|
||||
static NzRenderStates states;
|
||||
|
||||
m_shader->SendColor(s_colorLocation, m_color);
|
||||
m_shader->SendColor(m_shader->GetUniformLocation(nzShaderUniform_MaterialDiffuse), m_color);
|
||||
|
||||
NzRenderer::SetRenderStates(states);
|
||||
NzRenderer::SetShader(m_shader);
|
||||
|
||||
@@ -142,7 +142,14 @@ void NzForwardRenderQueue::AddModel(const NzModel* model)
|
||||
if (pair2.second)
|
||||
staticMesh->AddResourceListener(this, ResourceType_StaticMesh);
|
||||
|
||||
pair2.first->second.push_back(transformMatrix);
|
||||
std::vector<StaticData>& staticDataContainer = pair2.first->second;
|
||||
|
||||
staticDataContainer.resize(staticDataContainer.size()+1);
|
||||
StaticData& data = staticDataContainer.back();
|
||||
|
||||
data.aabb = staticMesh->GetAABB();
|
||||
data.aabb.Transform(transformMatrix);
|
||||
data.transformMatrix = transformMatrix;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -257,31 +264,22 @@ bool NzForwardRenderQueue::StaticMeshComparator::operator()(const NzStaticMesh*
|
||||
return buffer1 < buffer2;
|
||||
}
|
||||
|
||||
bool NzForwardRenderQueue::MaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2)
|
||||
bool NzForwardRenderQueue::ModelMaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2)
|
||||
{
|
||||
const NzShader* shader1 = mat1->GetCustomShader();
|
||||
const NzShader* shader2 = mat2->GetCustomShader();
|
||||
|
||||
if (shader1)
|
||||
///TODO: Comparaison des shaders
|
||||
for (unsigned int i = 0; i <= nzShaderFlags_Max; ++i)
|
||||
{
|
||||
if (shader2)
|
||||
{
|
||||
if (shader1 != shader2)
|
||||
return shader1 < shader2;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
else if (shader2)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
nzUInt32 shaderFlags1 = mat1->GetShaderFlags();
|
||||
nzUInt32 shaderFlags2 = mat2->GetShaderFlags();
|
||||
const NzShader* shader1 = mat1->GetShader(nzShaderTarget_Model, i);
|
||||
const NzShader* shader2 = mat2->GetShader(nzShaderTarget_Model, i);
|
||||
|
||||
if (shaderFlags1 != shaderFlags2)
|
||||
return shaderFlags1 < shaderFlags2;
|
||||
if (shader1 != shader2)
|
||||
return shader1 < shader2;
|
||||
}
|
||||
|
||||
const NzTexture* diffuseMap1 = mat1->GetDiffuseMap();
|
||||
const NzTexture* diffuseMap2 = mat2->GetDiffuseMap();
|
||||
if (diffuseMap1 != diffuseMap2)
|
||||
return diffuseMap1 < diffuseMap2;
|
||||
|
||||
return mat1 < mat2;
|
||||
}
|
||||
|
||||
@@ -10,20 +10,107 @@
|
||||
#include <Nazara/Renderer/Config.hpp>
|
||||
#include <Nazara/Renderer/Material.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||
#include <Nazara/Utility/BufferMapper.hpp>
|
||||
#include <Nazara/Utility/StaticMesh.hpp>
|
||||
#include <Nazara/Utility/VertexStruct.hpp>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
struct LightComparator
|
||||
class LightManager
|
||||
{
|
||||
bool operator()(const NzLight* light1, const NzLight* light2)
|
||||
{
|
||||
return light1->GetPosition().SquaredDistance(pos) < light2->GetPosition().SquaredDistance(pos);
|
||||
}
|
||||
public:
|
||||
LightManager() = default;
|
||||
~LightManager() = default;
|
||||
|
||||
NzVector3f pos;
|
||||
unsigned int FindClosestLights(const NzLight** lights, unsigned int lightCount, const NzSpheref& object)
|
||||
{
|
||||
for (Light& light : m_lights)
|
||||
{
|
||||
light.light = nullptr;
|
||||
light.score = std::numeric_limits<unsigned int>::max(); // Nous jouons au Golf
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < lightCount; ++i)
|
||||
{
|
||||
const NzLight* light = *lights;
|
||||
|
||||
unsigned int score = std::numeric_limits<unsigned int>::max();
|
||||
switch (light->GetLightType())
|
||||
{
|
||||
case nzLightType_Directional:
|
||||
score = 0; // Lumière choisie d'office
|
||||
break;
|
||||
|
||||
case nzLightType_Point:
|
||||
{
|
||||
NzSpheref lightSphere(light->GetPosition(), light->GetRadius());
|
||||
|
||||
if (lightSphere.Intersect(object))
|
||||
score = static_cast<unsigned int>(light->GetPosition().SquaredDistance(object.GetPosition())*1000.f);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case nzLightType_Spot:
|
||||
{
|
||||
NzSpheref lightSphere(light->GetPosition(), light->GetRadius());
|
||||
|
||||
///TODO: Attribuer bonus/malus selon l'angle du spot ?
|
||||
if (lightSphere.Intersect(object))
|
||||
score = static_cast<unsigned int>(light->GetPosition().SquaredDistance(object.GetPosition())*1000.f);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (score < m_lights[0].score)
|
||||
{
|
||||
unsigned int j;
|
||||
for (j = 1; j < 3; ++j) ///TODO: Constante
|
||||
{
|
||||
if (score > m_lights[j].score)
|
||||
break;
|
||||
}
|
||||
|
||||
j--; // Position de la nouvelle lumière
|
||||
|
||||
// Décalage
|
||||
std::memcpy(&m_lights[0], &m_lights[1], j*sizeof(Light));
|
||||
|
||||
m_lights[j].light = light;
|
||||
m_lights[j].score = score;
|
||||
}
|
||||
|
||||
lights++;
|
||||
}
|
||||
|
||||
unsigned int i;
|
||||
for (i = 0; i < 3; ++i) ///TODO: Constante
|
||||
{
|
||||
if (m_lights[i].light)
|
||||
break;
|
||||
}
|
||||
|
||||
return 3-i; ///TODO: Constante
|
||||
}
|
||||
|
||||
const NzLight* GetLight(unsigned int i) const
|
||||
{
|
||||
///TODO: Constante
|
||||
return m_lights[3-i-1].light; // Les lumières sont stockées dans l'ordre inverse (De la plus éloignée à la plus proche)
|
||||
}
|
||||
|
||||
private:
|
||||
struct Light
|
||||
{
|
||||
const NzLight* light;
|
||||
unsigned int score;
|
||||
};
|
||||
|
||||
Light m_lights[3]; ///TODO: Constante
|
||||
};
|
||||
}
|
||||
|
||||
@@ -46,15 +133,11 @@ void NzForwardRenderTechnique::Clear(const NzScene* scene)
|
||||
void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||
{
|
||||
///TODO: Regrouper les activations par méthode
|
||||
LightComparator lightComparator;
|
||||
LightManager lightManager;
|
||||
|
||||
const NzCamera* camera = scene->GetActiveCamera();
|
||||
const NzShader* lastShader = nullptr;
|
||||
|
||||
// Externes à la boucle pour conserver leur valeurs si le shader ne change pas
|
||||
unsigned int lightCount = 0;
|
||||
int lightCountLocation = -1;
|
||||
|
||||
// Rendu des modèles opaques
|
||||
for (auto& matIt : m_renderQueue.opaqueModels)
|
||||
{
|
||||
@@ -66,18 +149,13 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||
const NzMaterial* material = matIt.first;
|
||||
|
||||
// On commence par récupérer le shader du matériau
|
||||
const NzShader* shader;
|
||||
if (material->HasCustomShader())
|
||||
shader = material->GetCustomShader();
|
||||
else
|
||||
shader = NzShaderBuilder::Get(material->GetShaderFlags());
|
||||
const NzShader* shader = material->GetShader(nzShaderTarget_Model, 0);
|
||||
|
||||
unsigned int lightCount = 0;
|
||||
|
||||
// Les uniformes sont conservées au sein du shader, inutile de les renvoyer tant que le shader reste le même
|
||||
if (shader != lastShader)
|
||||
{
|
||||
// On récupère l'information sur l'éclairage en même temps que la position de l'uniforme "LightCount"
|
||||
lightCountLocation = shader->GetUniformLocation(nzShaderUniform_LightCount);
|
||||
|
||||
NzRenderer::SetShader(shader);
|
||||
|
||||
// Couleur ambiante de la scène
|
||||
@@ -85,18 +163,11 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||
// Position de la caméra
|
||||
shader->SendVector(shader->GetUniformLocation(nzShaderUniform_CameraPosition), camera->GetPosition());
|
||||
|
||||
lightCount = 0;
|
||||
|
||||
// On envoie les lumières directionnelles s'il y a (Les mêmes pour tous)
|
||||
if (lightCountLocation != -1)
|
||||
{
|
||||
for (const NzLight* light : m_renderQueue.directionnalLights)
|
||||
{
|
||||
light->Apply(shader, lightCount++);
|
||||
if (lightCount > NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT)
|
||||
break; // Prévenons les bêtises des utilisateurs
|
||||
}
|
||||
}
|
||||
lightCount = m_renderQueue.directionnalLights.size();
|
||||
for (unsigned int i = 0; i < lightCount; ++i)
|
||||
m_renderQueue.directionnalLights[i]->Enable(shader, i);
|
||||
|
||||
lastShader = shader;
|
||||
}
|
||||
|
||||
@@ -116,8 +187,9 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||
for (auto& subMeshIt : staticContainer)
|
||||
{
|
||||
const NzStaticMesh* mesh = subMeshIt.first;
|
||||
std::vector<NzMatrix4f>& matrices = subMeshIt.second;
|
||||
if (!matrices.empty())
|
||||
std::vector<NzForwardRenderQueue::StaticData>& staticData = subMeshIt.second;
|
||||
|
||||
if (!staticData.empty())
|
||||
{
|
||||
const NzIndexBuffer* indexBuffer = mesh->GetIndexBuffer();
|
||||
const NzVertexBuffer* vertexBuffer = mesh->GetVertexBuffer();
|
||||
@@ -140,28 +212,25 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||
NzRenderer::SetIndexBuffer(indexBuffer);
|
||||
NzRenderer::SetVertexBuffer(vertexBuffer);
|
||||
|
||||
for (const NzMatrix4f& matrix : matrices)
|
||||
for (const NzForwardRenderQueue::StaticData& data : staticData)
|
||||
{
|
||||
// Calcul des lumières les plus proches
|
||||
///TODO: LightManager ?
|
||||
if (lightCountLocation != -1)
|
||||
if (lightCount < m_maxLightsPerObject && !m_renderQueue.lights.empty())
|
||||
{
|
||||
std::vector<const NzLight*>& lights = m_renderQueue.lights;
|
||||
unsigned int count = lightManager.FindClosestLights(&m_renderQueue.lights[0], m_renderQueue.lights.size(), data.aabb.GetBoundingSphere());
|
||||
count -= lightCount;
|
||||
|
||||
lightComparator.pos = matrix.GetTranslation();
|
||||
std::sort(lights.begin(), lights.end(), lightComparator);
|
||||
|
||||
unsigned int max = std::min(std::min(NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT - lightCount, m_maxLightsPerObject), static_cast<unsigned int>(lights.size()));
|
||||
for (unsigned int i = 0; i < max; ++i)
|
||||
lights[i]->Apply(shader, lightCount++);
|
||||
|
||||
shader->SendInteger(lightCountLocation, lightCount);
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
lightManager.GetLight(i)->Enable(shader, lightCount++);
|
||||
}
|
||||
|
||||
NzRenderer::SetMatrix(nzMatrixType_World, matrix);
|
||||
for (unsigned int i = lightCount; i < 3; ++i) ///TODO: Constante sur le nombre maximum de lumières
|
||||
NzLight::Disable(shader, i);
|
||||
|
||||
NzRenderer::SetMatrix(nzMatrixType_World, data.transformMatrix);
|
||||
drawFunc(mesh->GetPrimitiveMode(), 0, indexCount);
|
||||
}
|
||||
matrices.clear();
|
||||
staticData.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -175,18 +244,13 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||
m_renderQueue.transparentSkeletalModels[pair.first].material;
|
||||
|
||||
// On commence par récupérer le shader du matériau
|
||||
const NzShader* shader;
|
||||
if (material->HasCustomShader())
|
||||
shader = material->GetCustomShader();
|
||||
else
|
||||
shader = NzShaderBuilder::Get(material->GetShaderFlags());
|
||||
const NzShader* shader = material->GetShader(nzShaderTarget_Model, 0);
|
||||
|
||||
unsigned int lightCount = 0;
|
||||
|
||||
// Les uniformes sont conservées au sein du shader, inutile de les renvoyer tant que le shader reste le même
|
||||
if (shader != lastShader)
|
||||
{
|
||||
// On récupère l'information sur l'éclairage en même temps que la position de l'uniforme "LightCount"
|
||||
lightCountLocation = shader->GetUniformLocation(nzShaderUniform_LightCount);
|
||||
|
||||
NzRenderer::SetShader(shader);
|
||||
|
||||
// Couleur ambiante de la scène
|
||||
@@ -194,18 +258,11 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||
// Position de la caméra
|
||||
shader->SendVector(shader->GetUniformLocation(nzShaderUniform_CameraPosition), camera->GetPosition());
|
||||
|
||||
lightCount = 0;
|
||||
|
||||
// On envoie les lumières directionnelles s'il y a (Les mêmes pour tous)
|
||||
if (lightCountLocation != -1)
|
||||
{
|
||||
for (const NzLight* light : m_renderQueue.directionnalLights)
|
||||
{
|
||||
light->Apply(shader, lightCount++);
|
||||
if (lightCount > NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT)
|
||||
break; // Prévenons les bêtises des utilisateurs
|
||||
}
|
||||
}
|
||||
lightCount = m_renderQueue.directionnalLights.size();
|
||||
for (unsigned int i = 0; i < lightCount; ++i)
|
||||
m_renderQueue.directionnalLights[i]->Enable(shader, i);
|
||||
|
||||
lastShader = shader;
|
||||
}
|
||||
|
||||
@@ -241,21 +298,18 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||
NzRenderer::SetVertexBuffer(vertexBuffer);
|
||||
|
||||
// Calcul des lumières les plus proches
|
||||
///TODO: LightManager ?
|
||||
if (lightCountLocation != -1)
|
||||
if (lightCount < m_maxLightsPerObject && !m_renderQueue.lights.empty())
|
||||
{
|
||||
std::vector<const NzLight*>& lights = m_renderQueue.lights;
|
||||
unsigned int count = lightManager.FindClosestLights(&m_renderQueue.lights[0], m_renderQueue.lights.size(), staticModel.aabb.GetBoundingSphere());
|
||||
count -= lightCount;
|
||||
|
||||
lightComparator.pos = matrix.GetTranslation();
|
||||
std::sort(lights.begin(), lights.end(), lightComparator);
|
||||
|
||||
unsigned int max = std::min(std::min(NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT - lightCount, m_maxLightsPerObject), static_cast<unsigned int>(lights.size()));
|
||||
for (unsigned int i = 0; i < max; ++i)
|
||||
lights[i]->Apply(shader, lightCount++);
|
||||
|
||||
shader->SendInteger(lightCountLocation, lightCount);
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
lightManager.GetLight(i)->Enable(shader, lightCount++);
|
||||
}
|
||||
|
||||
for (unsigned int i = lightCount; i < 3; ++i) ///TODO: Constante sur le nombre maximum de lumières
|
||||
NzLight::Disable(shader, i);
|
||||
|
||||
NzRenderer::SetMatrix(nzMatrixType_World, matrix);
|
||||
drawFunc(mesh->GetPrimitiveMode(), 0, indexCount);
|
||||
}
|
||||
@@ -265,6 +319,51 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||
}
|
||||
}
|
||||
|
||||
// Les billboards
|
||||
/*if (!m_renderQueue.billboards.empty())
|
||||
{
|
||||
//NzRenderer::SetIndexBuffer(m_billboardIndexBuffer);
|
||||
NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity());
|
||||
NzRenderer::SetShader(m_billboardShader);
|
||||
NzRenderer::SetVertexBuffer(m_billboardVertexBuffer);
|
||||
|
||||
m_billboardShader->SendVector(s_cameraForwardLocation, camera->GetForward());
|
||||
m_billboardShader->SendVector(s_cameraUpLocation, camera->GetUp());
|
||||
m_billboardShader->SendVector(s_worldUpLocation, NzVector3f::Up());
|
||||
|
||||
// Couleur ambiante de la scène
|
||||
m_billboardShader->SendColor(m_billboardShader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor());
|
||||
// Position de la caméra
|
||||
m_billboardShader->SendVector(m_billboardShader->GetUniformLocation(nzShaderUniform_CameraPosition), camera->GetPosition());
|
||||
|
||||
lightCount = 0;
|
||||
|
||||
// On envoie les lumières directionnelles s'il y a (Les mêmes pour tous)
|
||||
m_renderQueue.lights[0]->Apply(m_billboardShader, 0);
|
||||
|
||||
for (auto& matIt : m_renderQueue.billboards)
|
||||
{
|
||||
const NzMaterial* material = matIt.first;
|
||||
auto& billboards = matIt.second;
|
||||
|
||||
material->Apply(m_billboardShader);
|
||||
|
||||
unsigned int billboardCount = billboards.size();
|
||||
const NzForwardRenderQueue::BillboardData* data = &billboards[0];
|
||||
while (billboardCount > 0)
|
||||
{
|
||||
unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboards);
|
||||
billboardCount -= renderedBillboardCount;
|
||||
|
||||
m_billboardVertexBuffer->FillVertices(data, 0, renderedBillboardCount, true);
|
||||
data += renderedBillboardCount;
|
||||
|
||||
NzRenderer::DrawPrimitives(nzPrimitiveMode_PointList, 0, renderedBillboardCount);
|
||||
}
|
||||
billboards.clear();
|
||||
}
|
||||
}*/
|
||||
|
||||
// Les autres drawables (Exemple: Terrain)
|
||||
for (const NzDrawable* drawable : m_renderQueue.otherDrawables)
|
||||
drawable->Draw();
|
||||
@@ -282,5 +381,5 @@ NzAbstractRenderQueue* NzForwardRenderTechnique::GetRenderQueue()
|
||||
|
||||
void NzForwardRenderTechnique::SetMaxLightsPerObject(unsigned int lightCount)
|
||||
{
|
||||
m_maxLightsPerObject = lightCount;
|
||||
m_maxLightsPerObject = lightCount; ///TODO: Vérifier par rapport à la constante
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const
|
||||
renderQueue->AddLight(this);
|
||||
}
|
||||
|
||||
void NzLight::Apply(const NzShader* shader, unsigned int lightUnit) const
|
||||
void NzLight::Enable(const NzShader* shader, unsigned int lightUnit) const
|
||||
{
|
||||
/*
|
||||
struct Light
|
||||
@@ -66,6 +66,7 @@ void NzLight::Apply(const NzShader* shader, unsigned int lightUnit) const
|
||||
-P3: float cosInnerAngle + float cosOuterAngle
|
||||
*/
|
||||
|
||||
///TODO: Optimiser
|
||||
int typeLocation = shader->GetUniformLocation("Lights[0].type");
|
||||
int ambientLocation = shader->GetUniformLocation("Lights[0].ambient");
|
||||
int diffuseLocation = shader->GetUniformLocation("Lights[0].diffuse");
|
||||
@@ -217,6 +218,12 @@ NzLight& NzLight::operator=(const NzLight& light)
|
||||
return *this;
|
||||
}
|
||||
|
||||
void NzLight::Disable(const NzShader* shader, unsigned int lightUnit)
|
||||
{
|
||||
///TODO: Optimiser
|
||||
shader->SendInteger(shader->GetUniformLocation("Lights[" + NzString::Number(lightUnit) + "].type"), -1);
|
||||
}
|
||||
|
||||
void NzLight::Invalidate()
|
||||
{
|
||||
NzSceneNode::Invalidate();
|
||||
|
||||
@@ -2,99 +2,22 @@
|
||||
// This file is part of the "Nazara Engine - Graphics module"
|
||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||
|
||||
#ifndef NAZARA_RENDERER_OPENGL
|
||||
#define NAZARA_RENDERER_OPENGL // Nécessaire pour inclure les headers OpenGL
|
||||
#endif
|
||||
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Graphics/TextureBackground.hpp>
|
||||
#include <Nazara/Renderer/Renderer.hpp>
|
||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||
#include <Nazara/Renderer/ShaderManager.hpp>
|
||||
#include <memory>
|
||||
#include <Nazara/Graphics/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
static NzShader* s_shader = nullptr;
|
||||
static int s_textureLocation;
|
||||
|
||||
NzShader* BuildShader()
|
||||
{
|
||||
const char* fragmentSource110 =
|
||||
"#version 110\n"
|
||||
"varying vec2 vTexCoord;\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_FragColor = texture(Texture, vTexCoord);\n"
|
||||
"}\n";
|
||||
|
||||
const char* fragmentSource140 =
|
||||
"#version 140\n"
|
||||
"in vec2 vTexCoord;\n"
|
||||
"out vec4 RenderTarget0;\n"
|
||||
"uniform sampler2D Texture;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" RenderTarget0 = texture(Texture, vTexCoord);\n"
|
||||
"}\n";
|
||||
|
||||
const char* vertexSource110 =
|
||||
"#version 110\n"
|
||||
"attribute vec2 VertexPosition;\n"
|
||||
"varying vec2 vTexCoord;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(VertexPosition, 0.0, 1.0);\n"
|
||||
" vTexCoord = vec2((VertexPosition.x + 1.0)*0.5, (VertexPosition.y + 1.0)*0.5);\n"
|
||||
"}\n";
|
||||
|
||||
const char* vertexSource140 =
|
||||
"#version 140\n"
|
||||
"in vec2 VertexPosition;\n"
|
||||
"out vec2 vTexCoord;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = vec4(VertexPosition, 0.0, 1.0);\n"
|
||||
" vTexCoord = vec2((VertexPosition.x + 1.0)*0.5, (VertexPosition.y + 1.0)*0.5);\n"
|
||||
"}\n";
|
||||
|
||||
///TODO: Remplacer ça par des ShaderNode
|
||||
std::unique_ptr<NzShader> shader(new NzShader(nzShaderLanguage_GLSL));
|
||||
shader->SetPersistent(false);
|
||||
|
||||
bool useGLSL140 = (NzOpenGL::GetVersion() >= 310);
|
||||
|
||||
if (!shader->Load(nzShaderType_Fragment, (useGLSL140) ? fragmentSource140 : fragmentSource110))
|
||||
{
|
||||
NazaraError("Failed to load fragment shader");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!shader->Load(nzShaderType_Vertex, (useGLSL140) ? vertexSource140 : vertexSource110))
|
||||
{
|
||||
NazaraError("Failed to load vertex shader");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!shader->Compile())
|
||||
{
|
||||
NazaraError("Failed to compile shader");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
s_textureLocation = shader->GetUniformLocation("Texture");
|
||||
|
||||
return shader.release();
|
||||
}
|
||||
}
|
||||
|
||||
NzTextureBackground::NzTextureBackground()
|
||||
{
|
||||
if (!s_shader)
|
||||
s_shader = BuildShader();
|
||||
NzShaderManagerParams params;
|
||||
params.target = nzShaderTarget_FullscreenQuad;
|
||||
params.flags = 0;
|
||||
params.fullscreenQuad.alphaMapping = false;
|
||||
params.fullscreenQuad.alphaTest = false;
|
||||
params.fullscreenQuad.diffuseMapping = true;
|
||||
|
||||
m_shader = s_shader;
|
||||
m_shader = NzShaderManager::Get(params);
|
||||
}
|
||||
|
||||
NzTextureBackground::NzTextureBackground(NzTexture* texture) :
|
||||
@@ -103,19 +26,14 @@ NzTextureBackground()
|
||||
m_texture = texture;
|
||||
}
|
||||
|
||||
NzTextureBackground::~NzTextureBackground()
|
||||
{
|
||||
if (m_shader.Reset())
|
||||
s_shader = nullptr;
|
||||
}
|
||||
|
||||
void NzTextureBackground::Draw(const NzScene* scene) const
|
||||
{
|
||||
NazaraUnused(scene);
|
||||
|
||||
static NzRenderStates states;
|
||||
|
||||
m_shader->SendInteger(s_textureLocation, 0);
|
||||
m_shader->SendColor(m_shader->GetUniformLocation(nzShaderUniform_MaterialDiffuse), NzColor::White);
|
||||
m_shader->SendInteger(m_shader->GetUniformLocation(nzShaderUniform_MaterialDiffuseMap), 0);
|
||||
|
||||
NzRenderer::SetRenderStates(states);
|
||||
NzRenderer::SetShader(m_shader);
|
||||
|
||||
Reference in New Issue
Block a user