Added support for billboads
Improved ForwardRenderTechnique code Former-commit-id: 2386de85c26839565f087885ffcb098ef263bdfa
This commit is contained in:
parent
aeec8ee0f4
commit
659eb31757
|
|
@ -8,7 +8,9 @@
|
||||||
#define NAZARA_ABSTRACTRENDERQUEUE_HPP
|
#define NAZARA_ABSTRACTRENDERQUEUE_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
#include <Nazara/Core/Color.hpp>
|
||||||
#include <Nazara/Core/NonCopyable.hpp>
|
#include <Nazara/Core/NonCopyable.hpp>
|
||||||
|
#include <Nazara/Core/SparsePtr.hpp>
|
||||||
#include <Nazara/Math/Box.hpp>
|
#include <Nazara/Math/Box.hpp>
|
||||||
#include <Nazara/Math/Matrix4.hpp>
|
#include <Nazara/Math/Matrix4.hpp>
|
||||||
#include <Nazara/Utility/Enums.hpp>
|
#include <Nazara/Utility/Enums.hpp>
|
||||||
|
|
@ -25,6 +27,8 @@ class NAZARA_API NzAbstractRenderQueue : NzNonCopyable
|
||||||
NzAbstractRenderQueue() = default;
|
NzAbstractRenderQueue() = default;
|
||||||
virtual ~NzAbstractRenderQueue();
|
virtual ~NzAbstractRenderQueue();
|
||||||
|
|
||||||
|
virtual void AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos = NzVector2f(0.f, 1.f), const NzColor& color = NzColor::White) = 0;
|
||||||
|
virtual void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr<const NzVector3f> positionPtr, NzSparsePtr<const NzVector2f> sizePtr, NzSparsePtr<const NzVector2f> sinCosPtr = nullptr, NzSparsePtr<const NzColor> colorPtr = nullptr) = 0;
|
||||||
virtual void AddDrawable(const NzDrawable* drawable) = 0;
|
virtual void AddDrawable(const NzDrawable* drawable) = 0;
|
||||||
virtual void AddLight(const NzLight* light) = 0;
|
virtual void AddLight(const NzLight* light) = 0;
|
||||||
virtual void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) = 0;
|
virtual void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) = 0;
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzResourc
|
||||||
NzDeferredRenderQueue(NzForwardRenderQueue* forwardQueue);
|
NzDeferredRenderQueue(NzForwardRenderQueue* forwardQueue);
|
||||||
~NzDeferredRenderQueue();
|
~NzDeferredRenderQueue();
|
||||||
|
|
||||||
|
void AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos = NzVector2f(0.f, 1.f), const NzColor& color = NzColor::White) override;
|
||||||
|
void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr<const NzVector3f> positionPtr, NzSparsePtr<const NzVector2f> sizePtr, NzSparsePtr<const NzVector2f> sinCosPtr = nullptr, NzSparsePtr<const NzColor> colorPtr = nullptr) override;
|
||||||
void AddDrawable(const NzDrawable* drawable) override;
|
void AddDrawable(const NzDrawable* drawable) override;
|
||||||
void AddLight(const NzLight* light) override;
|
void AddLight(const NzLight* light) override;
|
||||||
void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override;
|
void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override;
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource
|
||||||
NzForwardRenderQueue() = default;
|
NzForwardRenderQueue() = default;
|
||||||
~NzForwardRenderQueue();
|
~NzForwardRenderQueue();
|
||||||
|
|
||||||
|
void AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos = NzVector2f(0.f, 1.f), const NzColor& color = NzColor::White) override;
|
||||||
|
void AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr<const NzVector3f> positionPtr, NzSparsePtr<const NzVector2f> sizePtr, NzSparsePtr<const NzVector2f> sinCosPtr = nullptr, NzSparsePtr<const NzColor> colorPtr = nullptr) override;
|
||||||
void AddDrawable(const NzDrawable* drawable) override;
|
void AddDrawable(const NzDrawable* drawable) override;
|
||||||
void AddLight(const NzLight* light) override;
|
void AddLight(const NzLight* light) override;
|
||||||
void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override;
|
void AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix) override;
|
||||||
|
|
@ -43,6 +45,14 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource
|
||||||
bool OnResourceDestroy(const NzResource* resource, int index) override;
|
bool OnResourceDestroy(const NzResource* resource, int index) override;
|
||||||
void OnResourceReleased(const NzResource* resource, int index) override;
|
void OnResourceReleased(const NzResource* resource, int index) override;
|
||||||
|
|
||||||
|
struct BillboardData
|
||||||
|
{
|
||||||
|
NzColor color;
|
||||||
|
NzVector3f center;
|
||||||
|
NzVector2f size;
|
||||||
|
NzVector2f sinCos;
|
||||||
|
};
|
||||||
|
|
||||||
struct TransparentModelData
|
struct TransparentModelData
|
||||||
{
|
{
|
||||||
NzMatrix4f transformMatrix;
|
NzMatrix4f transformMatrix;
|
||||||
|
|
@ -68,11 +78,13 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource
|
||||||
|
|
||||||
typedef std::map<NzMeshData, std::pair<NzSpheref, std::vector<NzMatrix4f>>, MeshDataComparator> MeshInstanceContainer;
|
typedef std::map<NzMeshData, std::pair<NzSpheref, std::vector<NzMatrix4f>>, MeshDataComparator> MeshInstanceContainer;
|
||||||
typedef std::map<const NzMaterial*, std::tuple<bool, bool, MeshInstanceContainer>, BatchedModelMaterialComparator> ModelBatches;
|
typedef std::map<const NzMaterial*, std::tuple<bool, bool, MeshInstanceContainer>, BatchedModelMaterialComparator> ModelBatches;
|
||||||
|
typedef std::map<const NzMaterial*, std::vector<BillboardData>> BatchedBillboardContainer;
|
||||||
typedef std::map<const NzMaterial*, std::vector<const NzSprite*>> BatchedSpriteContainer;
|
typedef std::map<const NzMaterial*, std::vector<const NzSprite*>> BatchedSpriteContainer;
|
||||||
typedef std::vector<const NzLight*> LightContainer;
|
typedef std::vector<const NzLight*> LightContainer;
|
||||||
typedef std::vector<unsigned int> TransparentModelContainer;
|
typedef std::vector<unsigned int> TransparentModelContainer;
|
||||||
|
|
||||||
ModelBatches opaqueModels;
|
ModelBatches opaqueModels;
|
||||||
|
BatchedBillboardContainer billboards;
|
||||||
BatchedSpriteContainer sprites;
|
BatchedSpriteContainer sprites;
|
||||||
TransparentModelContainer transparentModels;
|
TransparentModelContainer transparentModels;
|
||||||
std::vector<TransparentModelData> transparentModelData;
|
std::vector<TransparentModelData> transparentModelData;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class NAZARA_API NzForwardRenderTechnique : public NzAbstractRenderTechnique, Nz
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NzForwardRenderTechnique();
|
NzForwardRenderTechnique();
|
||||||
~NzForwardRenderTechnique();
|
~NzForwardRenderTechnique() = default;
|
||||||
|
|
||||||
void Clear(const NzScene* scene) const;
|
void Clear(const NzScene* scene) const;
|
||||||
bool Draw(const NzScene* scene) const;
|
bool Draw(const NzScene* scene) const;
|
||||||
|
|
@ -31,9 +31,13 @@ class NAZARA_API NzForwardRenderTechnique : public NzAbstractRenderTechnique, Nz
|
||||||
|
|
||||||
void SetMaxLightPassPerObject(unsigned int passCount);
|
void SetMaxLightPassPerObject(unsigned int passCount);
|
||||||
|
|
||||||
|
static bool Initialize();
|
||||||
|
static void Uninitialize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct LightUniforms;
|
struct LightUniforms;
|
||||||
|
|
||||||
|
void DrawBillboards(const NzScene* scene) const;
|
||||||
void DrawOpaqueModels(const NzScene* scene) const;
|
void DrawOpaqueModels(const NzScene* scene) const;
|
||||||
void DrawSprites(const NzScene* scene) const;
|
void DrawSprites(const NzScene* scene) const;
|
||||||
void DrawTransparentModels(const NzScene* scene) const;
|
void DrawTransparentModels(const NzScene* scene) const;
|
||||||
|
|
@ -49,12 +53,19 @@ class NAZARA_API NzForwardRenderTechnique : public NzAbstractRenderTechnique, Nz
|
||||||
};
|
};
|
||||||
|
|
||||||
mutable std::unordered_map<const NzShader*, LightUniforms> m_lightUniforms;
|
mutable std::unordered_map<const NzShader*, LightUniforms> m_lightUniforms;
|
||||||
|
NzBuffer m_vertexBuffer;
|
||||||
mutable NzForwardRenderQueue m_renderQueue;
|
mutable NzForwardRenderQueue m_renderQueue;
|
||||||
NzIndexBufferRef m_indexBuffer;
|
|
||||||
mutable NzLightManager m_directionalLights;
|
mutable NzLightManager m_directionalLights;
|
||||||
mutable NzLightManager m_lights;
|
mutable NzLightManager m_lights;
|
||||||
|
NzVertexBuffer m_billboardPointBuffer;
|
||||||
NzVertexBuffer m_spriteBuffer;
|
NzVertexBuffer m_spriteBuffer;
|
||||||
unsigned int m_maxLightPassPerObject;
|
unsigned int m_maxLightPassPerObject;
|
||||||
|
|
||||||
|
static NzIndexBuffer s_quadIndexBuffer;
|
||||||
|
static NzVertexBuffer s_quadVertexBuffer;
|
||||||
|
static NzVertexDeclaration s_billboardInstanceDeclaration;
|
||||||
|
static NzVertexDeclaration s_billboardVertexDeclaration;
|
||||||
|
static NzVertexDeclaration s_spriteDeclaration;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NAZARA_FORWARDRENDERTECHNIQUE_HPP
|
#endif // NAZARA_FORWARDRENDERTECHNIQUE_HPP
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,18 @@ NzDeferredRenderQueue::~NzDeferredRenderQueue()
|
||||||
Clear(true);
|
Clear(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NzDeferredRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color)
|
||||||
|
{
|
||||||
|
///TODO: Rendre les billboards via Deferred Shading si possible
|
||||||
|
m_forwardQueue->AddBillboard(material, position, size, sinCos, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzDeferredRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr<const NzVector3f> positionPtr, NzSparsePtr<const NzVector2f> sizePtr, NzSparsePtr<const NzVector2f> sinCosPtr, NzSparsePtr<const NzColor> colorPtr)
|
||||||
|
{
|
||||||
|
///TODO: Rendre les billboards via Deferred Shading si possible
|
||||||
|
m_forwardQueue->AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr);
|
||||||
|
}
|
||||||
|
|
||||||
void NzDeferredRenderQueue::AddDrawable(const NzDrawable* drawable)
|
void NzDeferredRenderQueue::AddDrawable(const NzDrawable* drawable)
|
||||||
{
|
{
|
||||||
m_forwardQueue->AddDrawable(drawable);
|
m_forwardQueue->AddDrawable(drawable);
|
||||||
|
|
@ -81,8 +93,10 @@ void NzDeferredRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData
|
||||||
bool& enableInstancing = std::get<1>(it->second);
|
bool& enableInstancing = std::get<1>(it->second);
|
||||||
MeshInstanceContainer& meshMap = std::get<2>(it->second);
|
MeshInstanceContainer& meshMap = std::get<2>(it->second);
|
||||||
|
|
||||||
|
// On indique la présence de modèles dans cette partie de la map
|
||||||
used = true;
|
used = true;
|
||||||
|
|
||||||
|
// Si nous insérons ce mesh pour la première fois, nous ajoutons des listeners sur ses buffers
|
||||||
MeshInstanceContainer::iterator it2 = meshMap.find(meshData);
|
MeshInstanceContainer::iterator it2 = meshMap.find(meshData);
|
||||||
if (it2 == meshMap.end())
|
if (it2 == meshMap.end())
|
||||||
{
|
{
|
||||||
|
|
@ -94,6 +108,7 @@ void NzDeferredRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData
|
||||||
meshData.vertexBuffer->AddResourceListener(this, ResourceType_VertexBuffer);
|
meshData.vertexBuffer->AddResourceListener(this, ResourceType_VertexBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// On ajoute la matrice à la liste des instances de cet objet
|
||||||
std::vector<NzMatrix4f>& instances = it2->second;
|
std::vector<NzMatrix4f>& instances = it2->second;
|
||||||
instances.push_back(transformMatrix);
|
instances.push_back(transformMatrix);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,37 @@ NzForwardRenderQueue::~NzForwardRenderQueue()
|
||||||
Clear(true);
|
Clear(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NzForwardRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color)
|
||||||
|
{
|
||||||
|
billboards[material].push_back(BillboardData{color, position, size, sinCos});
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzForwardRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr<const NzVector3f> positionPtr, NzSparsePtr<const NzVector2f> sizePtr, NzSparsePtr<const NzVector2f> sinCosPtr, NzSparsePtr<const NzColor> colorPtr)
|
||||||
|
{
|
||||||
|
///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seont remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
|
||||||
|
NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
|
||||||
|
|
||||||
|
if (!sinCosPtr)
|
||||||
|
sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
|
||||||
|
|
||||||
|
if (!colorPtr)
|
||||||
|
colorPtr.Reset(&NzColor::White, 0); // Pareil
|
||||||
|
|
||||||
|
std::vector<BillboardData>& billboardVec = billboards[material];
|
||||||
|
unsigned int prevSize = billboardVec.size();
|
||||||
|
billboardVec.resize(prevSize + count);
|
||||||
|
|
||||||
|
BillboardData* billboardData = &billboardVec[prevSize];
|
||||||
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
billboardData->center = *positionPtr++;
|
||||||
|
billboardData->color = *colorPtr++;
|
||||||
|
billboardData->sinCos = *sinCosPtr++;
|
||||||
|
billboardData->size = *sizePtr++;
|
||||||
|
billboardData++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NzForwardRenderQueue::AddDrawable(const NzDrawable* drawable)
|
void NzForwardRenderQueue::AddDrawable(const NzDrawable* drawable)
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
|
@ -72,6 +103,7 @@ void NzForwardRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData&
|
||||||
{
|
{
|
||||||
if (material->IsEnabled(nzRendererParameter_Blend))
|
if (material->IsEnabled(nzRendererParameter_Blend))
|
||||||
{
|
{
|
||||||
|
// Le matériau est transparent, nous devons rendre ce mesh d'une autre façon (après le rendu des objets opaques et en les triant)
|
||||||
unsigned int index = transparentModelData.size();
|
unsigned int index = transparentModelData.size();
|
||||||
transparentModelData.resize(index+1);
|
transparentModelData.resize(index+1);
|
||||||
|
|
||||||
|
|
@ -88,6 +120,7 @@ void NzForwardRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData&
|
||||||
ModelBatches::iterator it = opaqueModels.find(material);
|
ModelBatches::iterator it = opaqueModels.find(material);
|
||||||
if (it == opaqueModels.end())
|
if (it == opaqueModels.end())
|
||||||
{
|
{
|
||||||
|
// Première utilisation du matériau, ajoutons-nous comme listener
|
||||||
it = opaqueModels.insert(std::make_pair(material, ModelBatches::mapped_type())).first;
|
it = opaqueModels.insert(std::make_pair(material, ModelBatches::mapped_type())).first;
|
||||||
material->AddResourceListener(this, ResourceType_Material);
|
material->AddResourceListener(this, ResourceType_Material);
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +199,8 @@ void NzForwardRenderQueue::Clear(bool fully)
|
||||||
renderData.vertexBuffer->RemoveResourceListener(this);
|
renderData.vertexBuffer->RemoveResourceListener(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
billboards.clear();
|
||||||
opaqueModels.clear();
|
opaqueModels.clear();
|
||||||
sprites.clear();
|
sprites.clear();
|
||||||
}
|
}
|
||||||
|
|
@ -174,6 +209,7 @@ void NzForwardRenderQueue::Clear(bool fully)
|
||||||
void NzForwardRenderQueue::Sort(const NzAbstractViewer* viewer)
|
void NzForwardRenderQueue::Sort(const NzAbstractViewer* viewer)
|
||||||
{
|
{
|
||||||
NzPlanef nearPlane = viewer->GetFrustum().GetPlane(nzFrustumPlane_Near);
|
NzPlanef nearPlane = viewer->GetFrustum().GetPlane(nzFrustumPlane_Near);
|
||||||
|
NzVector3f viewerPos = viewer->GetEyePosition();
|
||||||
NzVector3f viewerNormal = viewer->GetForward();
|
NzVector3f viewerNormal = viewer->GetForward();
|
||||||
|
|
||||||
std::sort(transparentModels.begin(), transparentModels.end(), [this, &nearPlane, &viewerNormal](unsigned int index1, unsigned int index2)
|
std::sort(transparentModels.begin(), transparentModels.end(), [this, &nearPlane, &viewerNormal](unsigned int index1, unsigned int index2)
|
||||||
|
|
@ -186,6 +222,20 @@ void NzForwardRenderQueue::Sort(const NzAbstractViewer* viewer)
|
||||||
|
|
||||||
return nearPlane.Distance(position1) > nearPlane.Distance(position2);
|
return nearPlane.Distance(position1) > nearPlane.Distance(position2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
for (auto& pair : billboards)
|
||||||
|
{
|
||||||
|
const NzMaterial* mat = pair.first;
|
||||||
|
auto& container = pair.second;
|
||||||
|
|
||||||
|
if (mat->IsEnabled(nzRendererParameter_Blend))
|
||||||
|
{
|
||||||
|
std::sort(container.begin(), container.end(), [&viewerPos](const BillboardData& data1, const BillboardData& data2)
|
||||||
|
{
|
||||||
|
return viewerPos.SquaredDistance(data1.center) > viewerPos.SquaredDistance(data2.center);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int index)
|
bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int index)
|
||||||
|
|
@ -210,8 +260,13 @@ bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind
|
||||||
}
|
}
|
||||||
|
|
||||||
case ResourceType_Material:
|
case ResourceType_Material:
|
||||||
opaqueModels.erase(static_cast<const NzMaterial*>(resource));
|
{
|
||||||
|
const NzMaterial* material = static_cast<const NzMaterial*>(resource);
|
||||||
|
|
||||||
|
billboards.erase(material);
|
||||||
|
opaqueModels.erase(material);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ResourceType_VertexBuffer:
|
case ResourceType_VertexBuffer:
|
||||||
{
|
{
|
||||||
|
|
@ -299,7 +354,6 @@ bool NzForwardRenderQueue::BatchedModelMaterialComparator::operator()(const NzMa
|
||||||
|
|
||||||
const NzShader* shader1 = mat1->GetShaderInstance()->GetShader();
|
const NzShader* shader1 = mat1->GetShaderInstance()->GetShader();
|
||||||
const NzShader* shader2 = mat2->GetShaderInstance()->GetShader();
|
const NzShader* shader2 = mat2->GetShaderInstance()->GetShader();
|
||||||
|
|
||||||
if (shader1 != shader2)
|
if (shader1 != shader2)
|
||||||
return shader1 < shader2;
|
return shader1 < shader2;
|
||||||
|
|
||||||
|
|
@ -320,7 +374,6 @@ bool NzForwardRenderQueue::BatchedSpriteMaterialComparator::operator()(const NzM
|
||||||
|
|
||||||
const NzShader* shader1 = mat1->GetShaderInstance()->GetShader();
|
const NzShader* shader1 = mat1->GetShaderInstance()->GetShader();
|
||||||
const NzShader* shader2 = mat2->GetShaderInstance()->GetShader();
|
const NzShader* shader2 = mat2->GetShaderInstance()->GetShader();
|
||||||
|
|
||||||
if (shader1 != shader2)
|
if (shader1 != shader2)
|
||||||
return shader1 < shader2;
|
return shader1 < shader2;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Graphics/ForwardRenderTechnique.hpp>
|
#include <Nazara/Graphics/ForwardRenderTechnique.hpp>
|
||||||
|
#include <Nazara/Core/ErrorFlags.hpp>
|
||||||
|
#include <Nazara/Core/OffsetOf.hpp>
|
||||||
#include <Nazara/Graphics/AbstractBackground.hpp>
|
#include <Nazara/Graphics/AbstractBackground.hpp>
|
||||||
#include <Nazara/Graphics/Camera.hpp>
|
#include <Nazara/Graphics/Camera.hpp>
|
||||||
#include <Nazara/Graphics/Drawable.hpp>
|
#include <Nazara/Graphics/Drawable.hpp>
|
||||||
|
|
@ -22,46 +24,36 @@
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
static NzIndexBuffer* s_indexBuffer = nullptr;
|
struct BillboardPoint
|
||||||
unsigned int s_maxSprites = 8192;
|
|
||||||
|
|
||||||
NzIndexBuffer* BuildIndexBuffer()
|
|
||||||
{
|
{
|
||||||
std::unique_ptr<NzIndexBuffer> indexBuffer(new NzIndexBuffer(false, s_maxSprites*6, nzBufferStorage_Hardware, nzBufferUsage_Static));
|
NzColor color;
|
||||||
indexBuffer->SetPersistent(false);
|
NzVector3f position;
|
||||||
|
NzVector2f size;
|
||||||
|
NzVector2f sinCos; // doit suivre size
|
||||||
|
NzVector2f uv;
|
||||||
|
};
|
||||||
|
|
||||||
NzBufferMapper<NzIndexBuffer> mapper(indexBuffer.get(), nzBufferAccess_WriteOnly);
|
struct SpriteVertex
|
||||||
nzUInt16* indices = static_cast<nzUInt16*>(mapper.GetPointer());
|
{
|
||||||
|
NzColor color;
|
||||||
|
NzVector3f position;
|
||||||
|
NzVector2f uv;
|
||||||
|
};
|
||||||
|
|
||||||
for (unsigned int i = 0; i < s_maxSprites; ++i)
|
unsigned int s_maxBillboardSprites = std::numeric_limits<nzUInt16>::max()/6;
|
||||||
{
|
unsigned int s_vertexBufferSize = 1024*1024; // 1 MB
|
||||||
*indices++ = i*4 + 0;
|
|
||||||
*indices++ = i*4 + 2;
|
|
||||||
*indices++ = i*4 + 1;
|
|
||||||
|
|
||||||
*indices++ = i*4 + 2;
|
|
||||||
*indices++ = i*4 + 3;
|
|
||||||
*indices++ = i*4 + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return indexBuffer.release();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NzForwardRenderTechnique::NzForwardRenderTechnique() :
|
NzForwardRenderTechnique::NzForwardRenderTechnique() :
|
||||||
m_spriteBuffer(NzVertexDeclaration::Get(nzVertexLayout_XYZ_UV), s_maxSprites*4, nzBufferStorage_Hardware, nzBufferUsage_Dynamic),
|
m_vertexBuffer(nzBufferType_Vertex),
|
||||||
m_maxLightPassPerObject(3)
|
m_maxLightPassPerObject(3)
|
||||||
{
|
{
|
||||||
if (!s_indexBuffer)
|
NzErrorFlags flags(nzErrorFlag_ThrowException, true);
|
||||||
s_indexBuffer = BuildIndexBuffer();
|
|
||||||
|
|
||||||
m_indexBuffer = s_indexBuffer;
|
m_vertexBuffer.Create(s_vertexBufferSize, nzBufferStorage_Hardware, nzBufferUsage_Dynamic);
|
||||||
}
|
|
||||||
|
|
||||||
NzForwardRenderTechnique::~NzForwardRenderTechnique()
|
m_billboardPointBuffer.Reset(&s_billboardVertexDeclaration, &m_vertexBuffer);
|
||||||
{
|
m_spriteBuffer.Reset(&s_spriteDeclaration, &m_vertexBuffer);
|
||||||
if (m_indexBuffer.Reset())
|
|
||||||
s_indexBuffer = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzForwardRenderTechnique::Clear(const NzScene* scene) const
|
void NzForwardRenderTechnique::Clear(const NzScene* scene) const
|
||||||
|
|
@ -87,6 +79,9 @@ bool NzForwardRenderTechnique::Draw(const NzScene* scene) const
|
||||||
if (!m_renderQueue.transparentModels.empty())
|
if (!m_renderQueue.transparentModels.empty())
|
||||||
DrawTransparentModels(scene);
|
DrawTransparentModels(scene);
|
||||||
|
|
||||||
|
if (!m_renderQueue.billboards.empty())
|
||||||
|
DrawBillboards(scene);
|
||||||
|
|
||||||
if (!m_renderQueue.sprites.empty())
|
if (!m_renderQueue.sprites.empty())
|
||||||
DrawSprites(scene);
|
DrawSprites(scene);
|
||||||
|
|
||||||
|
|
@ -162,6 +157,208 @@ void NzForwardRenderTechnique::SetMaxLightPassPerObject(unsigned int passCount)
|
||||||
m_maxLightPassPerObject = passCount;
|
m_maxLightPassPerObject = passCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NzForwardRenderTechnique::Initialize()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
NzErrorFlags flags(nzErrorFlag_ThrowException, true);
|
||||||
|
|
||||||
|
s_quadIndexBuffer.Reset(false, s_maxBillboardSprites*6, nzBufferStorage_Hardware, nzBufferUsage_Static);
|
||||||
|
|
||||||
|
NzBufferMapper<NzIndexBuffer> mapper(s_quadIndexBuffer, nzBufferAccess_WriteOnly);
|
||||||
|
nzUInt16* indices = static_cast<nzUInt16*>(mapper.GetPointer());
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < s_maxBillboardSprites; ++i)
|
||||||
|
{
|
||||||
|
*indices++ = i*4 + 0;
|
||||||
|
*indices++ = i*4 + 2;
|
||||||
|
*indices++ = i*4 + 1;
|
||||||
|
|
||||||
|
*indices++ = i*4 + 2;
|
||||||
|
*indices++ = i*4 + 3;
|
||||||
|
*indices++ = i*4 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapper.Unmap(); // Inutile de garder le buffer ouvert plus longtemps
|
||||||
|
|
||||||
|
// Quad buffer (utilisé pour l'instancing de billboard et de sprites)
|
||||||
|
//Note: Les UV sont calculés dans le shader
|
||||||
|
s_quadVertexBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzBufferStorage_Hardware, nzBufferUsage_Static);
|
||||||
|
|
||||||
|
float vertices[2*4] = {
|
||||||
|
-0.5f, -0.5f,
|
||||||
|
0.5f, -0.5f,
|
||||||
|
-0.5f, 0.5f,
|
||||||
|
0.5f, 0.5f,
|
||||||
|
};
|
||||||
|
|
||||||
|
s_quadVertexBuffer.FillRaw(vertices, 0, sizeof(vertices));
|
||||||
|
|
||||||
|
// Déclaration lors du rendu des billboards par sommet
|
||||||
|
s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(BillboardPoint, color));
|
||||||
|
s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(BillboardPoint, position));
|
||||||
|
s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(BillboardPoint, uv));
|
||||||
|
s_billboardVertexDeclaration.EnableComponent(nzVertexComponent_Userdata0, nzComponentType_Float4, NzOffsetOf(BillboardPoint, size)); // Englobe sincos
|
||||||
|
|
||||||
|
// Declaration utilisée lors du rendu des billboards par instancing
|
||||||
|
// L'avantage ici est la copie directe (std::memcpy) des données de la RenderQueue vers le buffer GPU
|
||||||
|
s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData0, nzComponentType_Float3, NzOffsetOf(NzForwardRenderQueue::BillboardData, center));
|
||||||
|
s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData1, nzComponentType_Float4, NzOffsetOf(NzForwardRenderQueue::BillboardData, size)); // Englobe sincos
|
||||||
|
s_billboardInstanceDeclaration.EnableComponent(nzVertexComponent_InstanceData2, nzComponentType_Color, NzOffsetOf(NzForwardRenderQueue::BillboardData, color));
|
||||||
|
|
||||||
|
s_spriteDeclaration.EnableComponent(nzVertexComponent_Color, nzComponentType_Color, NzOffsetOf(SpriteVertex, color));
|
||||||
|
s_spriteDeclaration.EnableComponent(nzVertexComponent_Position, nzComponentType_Float3, NzOffsetOf(SpriteVertex, position));
|
||||||
|
s_spriteDeclaration.EnableComponent(nzVertexComponent_TexCoord, nzComponentType_Float2, NzOffsetOf(SpriteVertex, uv));
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (const std::exception& e)
|
||||||
|
{
|
||||||
|
NazaraError("Failed to initialise: " + NzString(e.what()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzForwardRenderTechnique::Uninitialize()
|
||||||
|
{
|
||||||
|
s_quadIndexBuffer.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzForwardRenderTechnique::DrawBillboards(const NzScene* scene) const
|
||||||
|
{
|
||||||
|
NzAbstractViewer* viewer = scene->GetViewer();
|
||||||
|
const NzShader* lastShader = nullptr;
|
||||||
|
|
||||||
|
if (NzRenderer::HasCapability(nzRendererCap_Instancing))
|
||||||
|
{
|
||||||
|
NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer();
|
||||||
|
instanceBuffer->SetVertexDeclaration(&s_billboardInstanceDeclaration);
|
||||||
|
|
||||||
|
NzRenderer::SetVertexBuffer(&s_quadVertexBuffer);
|
||||||
|
|
||||||
|
for (auto& matIt : m_renderQueue.billboards)
|
||||||
|
{
|
||||||
|
const NzMaterial* material = matIt.first;
|
||||||
|
auto& billboardVector = matIt.second;
|
||||||
|
|
||||||
|
unsigned int billboardCount = billboardVector.size();
|
||||||
|
if (billboardCount > 0)
|
||||||
|
{
|
||||||
|
// On commence par appliquer du matériau (et récupérer le shader ainsi activé)
|
||||||
|
const NzShader* shader = material->Apply(nzShaderFlags_Billboard | nzShaderFlags_Instancing | nzShaderFlags_VertexColor);
|
||||||
|
|
||||||
|
// Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas
|
||||||
|
if (shader != lastShader)
|
||||||
|
{
|
||||||
|
// Couleur ambiante de la scène
|
||||||
|
shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor());
|
||||||
|
// Position de la caméra
|
||||||
|
shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition());
|
||||||
|
|
||||||
|
lastShader = shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NzForwardRenderQueue::BillboardData* data = &billboardVector[0];
|
||||||
|
unsigned int maxBillboardPerDraw = instanceBuffer->GetVertexCount();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw);
|
||||||
|
billboardCount -= renderedBillboardCount;
|
||||||
|
|
||||||
|
instanceBuffer->Fill(data, 0, renderedBillboardCount, true);
|
||||||
|
data += renderedBillboardCount;
|
||||||
|
|
||||||
|
NzRenderer::DrawPrimitivesInstanced(renderedBillboardCount, nzPrimitiveMode_TriangleStrip, 0, 4);
|
||||||
|
}
|
||||||
|
while (billboardCount > 0);
|
||||||
|
|
||||||
|
billboardVector.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NzRenderer::SetIndexBuffer(&s_quadIndexBuffer);
|
||||||
|
NzRenderer::SetVertexBuffer(&m_billboardPointBuffer);
|
||||||
|
|
||||||
|
for (auto& matIt : m_renderQueue.billboards)
|
||||||
|
{
|
||||||
|
const NzMaterial* material = matIt.first;
|
||||||
|
auto& billboardVector = matIt.second;
|
||||||
|
|
||||||
|
unsigned int billboardCount = billboardVector.size();
|
||||||
|
if (billboardCount > 0)
|
||||||
|
{
|
||||||
|
// On commence par appliquer du matériau (et récupérer le shader ainsi activé)
|
||||||
|
const NzShader* shader = material->Apply(nzShaderFlags_Billboard | nzShaderFlags_VertexColor);
|
||||||
|
|
||||||
|
// Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas
|
||||||
|
if (shader != lastShader)
|
||||||
|
{
|
||||||
|
// Couleur ambiante de la scène
|
||||||
|
shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor());
|
||||||
|
// Position de la caméra
|
||||||
|
shader->SendVector(shader->GetUniformLocation(nzShaderUniform_EyePosition), viewer->GetEyePosition());
|
||||||
|
|
||||||
|
lastShader = shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
const NzForwardRenderQueue::BillboardData* data = &billboardVector[0];
|
||||||
|
unsigned int maxBillboardPerDraw = std::min(s_maxBillboardSprites, m_billboardPointBuffer.GetVertexCount()/4);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
unsigned int renderedBillboardCount = std::min(billboardCount, maxBillboardPerDraw);
|
||||||
|
billboardCount -= renderedBillboardCount;
|
||||||
|
|
||||||
|
NzBufferMapper<NzVertexBuffer> vertexMapper(m_billboardPointBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedBillboardCount*4);
|
||||||
|
BillboardPoint* vertices = reinterpret_cast<BillboardPoint*>(vertexMapper.GetPointer());
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < renderedBillboardCount; ++i)
|
||||||
|
{
|
||||||
|
const NzForwardRenderQueue::BillboardData& billboard = *data++;
|
||||||
|
|
||||||
|
vertices->color = billboard.color;
|
||||||
|
vertices->position = billboard.center;
|
||||||
|
vertices->sinCos = billboard.sinCos;
|
||||||
|
vertices->size = billboard.size;
|
||||||
|
vertices->uv.Set(0.f, 1.f);
|
||||||
|
vertices++;
|
||||||
|
|
||||||
|
vertices->color = billboard.color;
|
||||||
|
vertices->position = billboard.center;
|
||||||
|
vertices->sinCos = billboard.sinCos;
|
||||||
|
vertices->size = billboard.size;
|
||||||
|
vertices->uv.Set(1.f, 1.f);
|
||||||
|
vertices++;
|
||||||
|
|
||||||
|
vertices->color = billboard.color;
|
||||||
|
vertices->position = billboard.center;
|
||||||
|
vertices->sinCos = billboard.sinCos;
|
||||||
|
vertices->size = billboard.size;
|
||||||
|
vertices->uv.Set(0.f, 0.f);
|
||||||
|
vertices++;
|
||||||
|
|
||||||
|
vertices->color = billboard.color;
|
||||||
|
vertices->position = billboard.center;
|
||||||
|
vertices->sinCos = billboard.sinCos;
|
||||||
|
vertices->size = billboard.size;
|
||||||
|
vertices->uv.Set(1.f, 0.f);
|
||||||
|
vertices++;
|
||||||
|
}
|
||||||
|
|
||||||
|
vertexMapper.Unmap();
|
||||||
|
|
||||||
|
NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, renderedBillboardCount*6);
|
||||||
|
}
|
||||||
|
while (billboardCount > 0);
|
||||||
|
|
||||||
|
billboardVector.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const
|
void NzForwardRenderTechnique::DrawOpaqueModels(const NzScene* scene) const
|
||||||
{
|
{
|
||||||
NzAbstractViewer* viewer = scene->GetViewer();
|
NzAbstractViewer* viewer = scene->GetViewer();
|
||||||
|
|
@ -378,7 +575,7 @@ void NzForwardRenderTechnique::DrawSprites(const NzScene* scene) const
|
||||||
NzAbstractViewer* viewer = scene->GetViewer();
|
NzAbstractViewer* viewer = scene->GetViewer();
|
||||||
const NzShader* lastShader = nullptr;
|
const NzShader* lastShader = nullptr;
|
||||||
|
|
||||||
NzRenderer::SetIndexBuffer(m_indexBuffer);
|
NzRenderer::SetIndexBuffer(&s_quadIndexBuffer);
|
||||||
NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity());
|
NzRenderer::SetMatrix(nzMatrixType_World, NzMatrix4f::Identity());
|
||||||
NzRenderer::SetVertexBuffer(&m_spriteBuffer);
|
NzRenderer::SetVertexBuffer(&m_spriteBuffer);
|
||||||
|
|
||||||
|
|
@ -391,7 +588,7 @@ void NzForwardRenderTechnique::DrawSprites(const NzScene* scene) const
|
||||||
if (spriteCount > 0)
|
if (spriteCount > 0)
|
||||||
{
|
{
|
||||||
// On commence par appliquer du matériau (et récupérer le shader ainsi activé)
|
// On commence par appliquer du matériau (et récupérer le shader ainsi activé)
|
||||||
const NzShader* shader = material->Apply();
|
const NzShader* shader = material->Apply(nzShaderFlags_VertexColor);
|
||||||
|
|
||||||
// Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas
|
// Les uniformes sont conservées au sein d'un programme, inutile de les renvoyer tant qu'il ne change pas
|
||||||
if (shader != lastShader)
|
if (shader != lastShader)
|
||||||
|
|
@ -405,36 +602,47 @@ void NzForwardRenderTechnique::DrawSprites(const NzScene* scene) const
|
||||||
}
|
}
|
||||||
|
|
||||||
const NzSprite** spritePtr = &spriteVector[0];
|
const NzSprite** spritePtr = &spriteVector[0];
|
||||||
|
unsigned int maxSpritePerDraw = std::min(s_maxBillboardSprites, m_spriteBuffer.GetVertexCount()/4);
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
unsigned int renderedSpriteCount = std::min(spriteCount, 64U);
|
unsigned int renderedSpriteCount = std::min(spriteCount, maxSpritePerDraw);
|
||||||
spriteCount -= renderedSpriteCount;
|
spriteCount -= renderedSpriteCount;
|
||||||
|
|
||||||
NzBufferMapper<NzVertexBuffer> vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedSpriteCount*4);
|
NzBufferMapper<NzVertexBuffer> vertexMapper(m_spriteBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedSpriteCount*4);
|
||||||
NzVertexStruct_XYZ_UV* vertices = reinterpret_cast<NzVertexStruct_XYZ_UV*>(vertexMapper.GetPointer());
|
SpriteVertex* vertices = reinterpret_cast<SpriteVertex*>(vertexMapper.GetPointer());
|
||||||
|
|
||||||
for (unsigned int i = 0; i < renderedSpriteCount; ++i)
|
for (unsigned int i = 0; i < renderedSpriteCount; ++i)
|
||||||
{
|
{
|
||||||
const NzSprite* sprite = *spritePtr++;
|
const NzSprite* sprite = *spritePtr++;
|
||||||
|
|
||||||
|
const NzColor& color = sprite->GetColor();
|
||||||
const NzRectf& textureCoords = sprite->GetTextureCoords();
|
const NzRectf& textureCoords = sprite->GetTextureCoords();
|
||||||
const NzVector2f& halfSize = sprite->GetSize()*0.5f;
|
NzVector2f size = sprite->GetSize();
|
||||||
NzVector3f center = sprite->GetPosition();
|
NzVector3f origin = sprite->GetPosition();
|
||||||
|
NzVector3f scale = sprite->GetScale();
|
||||||
NzQuaternionf rotation = sprite->GetRotation();
|
NzQuaternionf rotation = sprite->GetRotation();
|
||||||
|
|
||||||
vertices->position = center + rotation * NzVector3f(-halfSize.x, -halfSize.y, 0.f);
|
size.x *= scale.x;
|
||||||
vertices->uv.Set(textureCoords.x, textureCoords.y + textureCoords.height);
|
size.y *= scale.y;
|
||||||
vertices++;
|
|
||||||
|
|
||||||
vertices->position = center + rotation * NzVector3f(halfSize.x, -halfSize.y, 0.f);
|
vertices->color = color;
|
||||||
vertices->uv.Set(textureCoords.width, textureCoords.y + textureCoords.height);
|
vertices->position = origin;
|
||||||
vertices++;
|
|
||||||
|
|
||||||
vertices->position = center + rotation * NzVector3f(-halfSize.x, halfSize.y, 0.f);
|
|
||||||
vertices->uv.Set(textureCoords.x, textureCoords.y);
|
vertices->uv.Set(textureCoords.x, textureCoords.y);
|
||||||
vertices++;
|
vertices++;
|
||||||
|
|
||||||
vertices->position = center + rotation * NzVector3f(halfSize.x, halfSize.y, 0.f);
|
vertices->color = color;
|
||||||
vertices->uv.Set(textureCoords.width, textureCoords.y);
|
vertices->position = origin + rotation * NzVector3f(size.x, 0.f, 0.f);
|
||||||
|
vertices->uv.Set(textureCoords.x + textureCoords.width, textureCoords.y);
|
||||||
|
vertices++;
|
||||||
|
|
||||||
|
vertices->color = color;
|
||||||
|
vertices->position = origin + rotation * NzVector3f(0.f, size.y, 0.f);
|
||||||
|
vertices->uv.Set(textureCoords.x, textureCoords.y + textureCoords.height);
|
||||||
|
vertices++;
|
||||||
|
|
||||||
|
vertices->color = color;
|
||||||
|
vertices->position = origin + rotation * NzVector3f(size.x, size.y, 0.f);
|
||||||
|
vertices->uv.Set(textureCoords.x + textureCoords.width, textureCoords.y + textureCoords.height);
|
||||||
vertices++;
|
vertices++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -557,3 +765,9 @@ const NzForwardRenderTechnique::LightUniforms* NzForwardRenderTechnique::GetLigh
|
||||||
return &(pair.first->second);
|
return &(pair.first->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NzIndexBuffer NzForwardRenderTechnique::s_quadIndexBuffer;
|
||||||
|
NzVertexBuffer NzForwardRenderTechnique::s_quadVertexBuffer;
|
||||||
|
NzVertexDeclaration NzForwardRenderTechnique::s_billboardInstanceDeclaration;
|
||||||
|
NzVertexDeclaration NzForwardRenderTechnique::s_billboardVertexDeclaration;
|
||||||
|
NzVertexDeclaration NzForwardRenderTechnique::s_spriteDeclaration;
|
||||||
|
|
|
||||||
|
|
@ -65,12 +65,22 @@ bool NzGraphics::Initialize()
|
||||||
NzLoaders_Texture_Register();
|
NzLoaders_Texture_Register();
|
||||||
|
|
||||||
// RenderTechniques
|
// RenderTechniques
|
||||||
|
if (!NzForwardRenderTechnique::Initialize())
|
||||||
|
{
|
||||||
|
NazaraError("Failed to initialize Forward Rendering");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
NzRenderTechniques::Register(NzRenderTechniques::ToString(nzRenderTechniqueType_BasicForward), 0, []() -> NzAbstractRenderTechnique* { return new NzForwardRenderTechnique; });
|
NzRenderTechniques::Register(NzRenderTechniques::ToString(nzRenderTechniqueType_BasicForward), 0, []() -> NzAbstractRenderTechnique* { return new NzForwardRenderTechnique; });
|
||||||
|
|
||||||
if (NzDeferredRenderTechnique::IsSupported())
|
if (NzDeferredRenderTechnique::IsSupported())
|
||||||
{
|
{
|
||||||
NzDeferredRenderTechnique::Initialize();
|
if (NzDeferredRenderTechnique::Initialize())
|
||||||
NzRenderTechniques::Register(NzRenderTechniques::ToString(nzRenderTechniqueType_DeferredShading), 20, []() -> NzAbstractRenderTechnique* { return new NzDeferredRenderTechnique; });
|
NzRenderTechniques::Register(NzRenderTechniques::ToString(nzRenderTechniqueType_DeferredShading), 20, []() -> NzAbstractRenderTechnique* { return new NzDeferredRenderTechnique; });
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NazaraWarning("Failed to initialize Deferred Rendering");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onExit.Reset();
|
onExit.Reset();
|
||||||
|
|
@ -104,6 +114,7 @@ void NzGraphics::Uninitialize()
|
||||||
NzLoaders_Texture_Unregister();
|
NzLoaders_Texture_Unregister();
|
||||||
|
|
||||||
NzDeferredRenderTechnique::Uninitialize();
|
NzDeferredRenderTechnique::Uninitialize();
|
||||||
|
NzForwardRenderTechnique::Uninitialize();
|
||||||
NzMaterial::Uninitialize();
|
NzMaterial::Uninitialize();
|
||||||
NzParticleDeclaration::Uninitialize();
|
NzParticleDeclaration::Uninitialize();
|
||||||
NzSkinningManager::Uninitialize();
|
NzSkinningManager::Uninitialize();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue