Remade instancing
Former-commit-id: b297ed84e86a714c58d42219cc1dd8337e3a732c
This commit is contained in:
parent
c75887f600
commit
69d150272f
|
|
@ -17,13 +17,20 @@ class NzScene;
|
||||||
class NAZARA_API NzAbstractRenderTechnique : NzNonCopyable
|
class NAZARA_API NzAbstractRenderTechnique : NzNonCopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NzAbstractRenderTechnique() = default;
|
NzAbstractRenderTechnique();
|
||||||
virtual ~NzAbstractRenderTechnique();
|
virtual ~NzAbstractRenderTechnique();
|
||||||
|
|
||||||
virtual void Clear(const NzScene* scene) = 0;
|
virtual void Clear(const NzScene* scene) = 0;
|
||||||
virtual void Draw(const NzScene* scene) = 0;
|
virtual void Draw(const NzScene* scene) = 0;
|
||||||
|
|
||||||
|
virtual void EnableInstancing(bool instancing);
|
||||||
|
|
||||||
virtual NzAbstractRenderQueue* GetRenderQueue() = 0;
|
virtual NzAbstractRenderQueue* GetRenderQueue() = 0;
|
||||||
|
|
||||||
|
virtual bool IsInstancingEnabled() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool m_instancingEnabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NAZARA_ABSTRACTRENDERTECHNIQUE_HPP
|
#endif // NAZARA_ABSTRACTRENDERTECHNIQUE_HPP
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||||
|
|
||||||
// Le nombre maximum d'instances pouvant être géré par le Renderer
|
// Le nombre maximum d'instances pouvant être géré par le Renderer
|
||||||
#define NAZARA_RENDERER_MAX_INSTANCES 8192
|
#define NAZARA_RENDERER_INSTANCE_BUFFER_SIZE 8192*64
|
||||||
|
|
||||||
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
||||||
#define NAZARA_RENDERER_MEMORYLEAKTRACKER 0
|
#define NAZARA_RENDERER_MEMORYLEAKTRACKER 0
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,10 @@ class NAZARA_API NzRenderer
|
||||||
|
|
||||||
static void Enable(nzRendererParameter parameter, bool enable);
|
static void Enable(nzRendererParameter parameter, bool enable);
|
||||||
|
|
||||||
|
|
||||||
static void Flush();
|
static void Flush();
|
||||||
|
|
||||||
|
static NzVertexBuffer* GetInstanceBuffer();
|
||||||
static float GetLineWidth();
|
static float GetLineWidth();
|
||||||
static NzMatrix4f GetMatrix(nzMatrixType type);
|
static NzMatrix4f GetMatrix(nzMatrixType type);
|
||||||
static nzUInt8 GetMaxAnisotropyLevel();
|
static nzUInt8 GetMaxAnisotropyLevel();
|
||||||
|
|
@ -72,8 +74,6 @@ class NAZARA_API NzRenderer
|
||||||
static void SetFaceCulling(nzFaceCulling cullingMode);
|
static void SetFaceCulling(nzFaceCulling cullingMode);
|
||||||
static void SetFaceFilling(nzFaceFilling fillingMode);
|
static void SetFaceFilling(nzFaceFilling fillingMode);
|
||||||
static void SetIndexBuffer(const NzIndexBuffer* indexBuffer);
|
static void SetIndexBuffer(const NzIndexBuffer* indexBuffer);
|
||||||
static void SetInstancingData(const void* instancingData, unsigned int instanceCount);
|
|
||||||
static void SetInstancingDeclaration(const NzVertexDeclaration* declaration, unsigned int* newMaxInstanceCount);
|
|
||||||
static void SetLineWidth(float size);
|
static void SetLineWidth(float size);
|
||||||
static void SetMatrix(nzMatrixType type, const NzMatrix4f& matrix);
|
static void SetMatrix(nzMatrixType type, const NzMatrix4f& matrix);
|
||||||
static void SetPointSize(float size);
|
static void SetPointSize(float size);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,34 @@
|
||||||
// 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/AbstractRenderTechnique.hpp>
|
#include <Nazara/Graphics/AbstractRenderTechnique.hpp>
|
||||||
|
#include <Nazara/Core/Error.hpp>
|
||||||
|
#include <Nazara/Renderer/Renderer.hpp>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
|
NzAbstractRenderTechnique::NzAbstractRenderTechnique()
|
||||||
|
{
|
||||||
|
#ifdef NAZARA_DEBUG
|
||||||
|
if (!NzRenderer::IsInitialized())
|
||||||
|
{
|
||||||
|
NazaraError("NazaraRenderer is not initialized");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_instancingEnabled = NzRenderer::HasCapability(nzRendererCap_Instancing);
|
||||||
|
}
|
||||||
|
|
||||||
NzAbstractRenderTechnique::~NzAbstractRenderTechnique() = default;
|
NzAbstractRenderTechnique::~NzAbstractRenderTechnique() = default;
|
||||||
|
|
||||||
|
void NzAbstractRenderTechnique::EnableInstancing(bool instancing)
|
||||||
|
{
|
||||||
|
if (NzRenderer::HasCapability(nzRendererCap_Instancing))
|
||||||
|
m_instancingEnabled = instancing;
|
||||||
|
else if (instancing)
|
||||||
|
NazaraError("NazaraRenderer does not support instancing");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzAbstractRenderTechnique::IsInstancingEnabled() const
|
||||||
|
{
|
||||||
|
return m_instancingEnabled;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -150,8 +150,16 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||||
{
|
{
|
||||||
const NzMaterial* material = matIt.first;
|
const NzMaterial* material = matIt.first;
|
||||||
|
|
||||||
|
// Nous utilisons de l'instancing lorsqu'aucune lumière (autre que directionnelle) n'est active
|
||||||
|
// Ceci car l'instancing n'est pas compatible avec la recherche des lumières les plus proches
|
||||||
|
// (Le deferred shading n'a pas ce problème)
|
||||||
|
|
||||||
|
///FIXME: l'instancing fait-il réellement gagner en performances ?
|
||||||
|
///TODO: Activer l'instancing uniquement si plusieurs instances sont à rendre ?
|
||||||
|
bool instancing = m_instancingEnabled && m_renderQueue.lights.empty();
|
||||||
|
|
||||||
// On commence par récupérer le programme du matériau
|
// On commence par récupérer le programme du matériau
|
||||||
const NzShaderProgram* program = material->GetShaderProgram(nzShaderTarget_Model, 0);
|
const NzShaderProgram* program = material->GetShaderProgram(nzShaderTarget_Model, (instancing) ? nzShaderFlags_Instancing : 0);
|
||||||
|
|
||||||
unsigned int lightCount = 0;
|
unsigned int lightCount = 0;
|
||||||
|
|
||||||
|
|
@ -198,39 +206,79 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||||
|
|
||||||
// Gestion du draw call avant la boucle de rendu
|
// Gestion du draw call avant la boucle de rendu
|
||||||
std::function<void(nzPrimitiveMode, unsigned int, unsigned int)> drawFunc;
|
std::function<void(nzPrimitiveMode, unsigned int, unsigned int)> drawFunc;
|
||||||
|
std::function<void(unsigned int, nzPrimitiveMode, unsigned int, unsigned int)> instancedDrawFunc;
|
||||||
unsigned int indexCount;
|
unsigned int indexCount;
|
||||||
|
|
||||||
if (indexBuffer)
|
if (indexBuffer)
|
||||||
{
|
{
|
||||||
drawFunc = NzRenderer::DrawIndexedPrimitives;
|
drawFunc = NzRenderer::DrawIndexedPrimitives;
|
||||||
indexCount = indexBuffer->GetIndexCount();
|
indexCount = indexBuffer->GetIndexCount();
|
||||||
|
instancedDrawFunc = NzRenderer::DrawIndexedPrimitivesInstanced;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
drawFunc = NzRenderer::DrawPrimitives;
|
drawFunc = NzRenderer::DrawPrimitives;
|
||||||
indexCount = vertexBuffer->GetVertexCount();
|
indexCount = vertexBuffer->GetVertexCount();
|
||||||
|
instancedDrawFunc = NzRenderer::DrawPrimitivesInstanced;
|
||||||
}
|
}
|
||||||
|
|
||||||
NzRenderer::SetIndexBuffer(indexBuffer);
|
NzRenderer::SetIndexBuffer(indexBuffer);
|
||||||
NzRenderer::SetVertexBuffer(vertexBuffer);
|
NzRenderer::SetVertexBuffer(vertexBuffer);
|
||||||
|
|
||||||
for (const NzForwardRenderQueue::StaticData& data : staticData)
|
nzPrimitiveMode primitiveMode = mesh->GetPrimitiveMode();
|
||||||
|
if (instancing)
|
||||||
{
|
{
|
||||||
// Calcul des lumières les plus proches
|
NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer();
|
||||||
if (lightCount < m_maxLightsPerObject && !m_renderQueue.lights.empty())
|
|
||||||
|
instanceBuffer->SetVertexDeclaration(NzVertexDeclaration::Get(nzVertexLayout_Matrix4));
|
||||||
|
|
||||||
|
unsigned int stride = instanceBuffer->GetStride();
|
||||||
|
|
||||||
|
const NzForwardRenderQueue::StaticData* data = &staticData[0];
|
||||||
|
unsigned int instanceCount = staticData.size();
|
||||||
|
unsigned int maxInstanceCount = instanceBuffer->GetVertexCount();
|
||||||
|
|
||||||
|
while (instanceCount > 0)
|
||||||
{
|
{
|
||||||
unsigned int count = lightManager.FindClosestLights(&m_renderQueue.lights[0], m_renderQueue.lights.size(), data.aabb.GetCenter(), data.aabb.GetSquaredRadius());
|
unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount);
|
||||||
count -= lightCount;
|
instanceCount -= renderedInstanceCount;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < count; ++i)
|
NzBufferMapper<NzVertexBuffer> mapper(instanceBuffer, nzBufferAccess_DiscardAndWrite);
|
||||||
lightManager.GetLight(i)->Enable(program, lightCount++);
|
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(mapper.GetPointer());
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < renderedInstanceCount; ++i)
|
||||||
|
{
|
||||||
|
std::memcpy(ptr, data->transformMatrix, sizeof(float)*16);
|
||||||
|
|
||||||
|
data++;
|
||||||
|
ptr += stride;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapper.Unmap();
|
||||||
|
|
||||||
|
instancedDrawFunc(renderedInstanceCount, primitiveMode, 0, indexCount);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const NzForwardRenderQueue::StaticData& data : staticData)
|
||||||
|
{
|
||||||
|
// Calcul des lumières les plus proches
|
||||||
|
if (lightCount < m_maxLightsPerObject && !m_renderQueue.lights.empty())
|
||||||
|
{
|
||||||
|
unsigned int count = lightManager.FindClosestLights(&m_renderQueue.lights[0], m_renderQueue.lights.size(), data.aabb.GetCenter(), data.aabb.GetSquaredRadius());
|
||||||
|
count -= lightCount;
|
||||||
|
|
||||||
for (unsigned int i = lightCount; i < 3; ++i) ///TODO: Constante sur le nombre maximum de lumières
|
for (unsigned int i = 0; i < count; ++i)
|
||||||
NzLight::Disable(program, i);
|
lightManager.GetLight(i)->Enable(program, lightCount++);
|
||||||
|
}
|
||||||
|
|
||||||
NzRenderer::SetMatrix(nzMatrixType_World, data.transformMatrix);
|
for (unsigned int i = lightCount; i < 3; ++i) ///TODO: Constante sur le nombre maximum de lumières
|
||||||
drawFunc(mesh->GetPrimitiveMode(), 0, indexCount);
|
NzLight::Disable(program, i);
|
||||||
|
|
||||||
|
NzRenderer::SetMatrix(nzMatrixType_World, data.transformMatrix);
|
||||||
|
drawFunc(primitiveMode, 0, indexCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
staticData.clear();
|
staticData.clear();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,8 +69,8 @@ namespace
|
||||||
std::set<unsigned int> s_dirtyTextureUnits;
|
std::set<unsigned int> s_dirtyTextureUnits;
|
||||||
std::vector<TextureUnit> s_textureUnits;
|
std::vector<TextureUnit> s_textureUnits;
|
||||||
GLuint s_currentVAO = 0;
|
GLuint s_currentVAO = 0;
|
||||||
NzVertexBuffer* s_instancingBuffer = nullptr;
|
NzVertexBuffer s_instanceBuffer;
|
||||||
NzVertexBuffer* s_fullscreenQuadBuffer = nullptr;
|
NzVertexBuffer s_fullscreenQuadBuffer;
|
||||||
MatrixUnit s_matrices[nzMatrixType_Max+1];
|
MatrixUnit s_matrices[nzMatrixType_Max+1];
|
||||||
NzRenderStates s_states;
|
NzRenderStates s_states;
|
||||||
NzVector2ui s_targetSize;
|
NzVector2ui s_targetSize;
|
||||||
|
|
@ -133,7 +133,7 @@ void NzRenderer::DrawFullscreenQuad()
|
||||||
|
|
||||||
EnableInstancing(false);
|
EnableInstancing(false);
|
||||||
SetIndexBuffer(nullptr);
|
SetIndexBuffer(nullptr);
|
||||||
SetVertexBuffer(s_fullscreenQuadBuffer);
|
SetVertexBuffer(&s_fullscreenQuadBuffer);
|
||||||
|
|
||||||
if (!EnsureStateUpdate())
|
if (!EnsureStateUpdate())
|
||||||
{
|
{
|
||||||
|
|
@ -142,6 +142,9 @@ void NzRenderer::DrawFullscreenQuad()
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
|
||||||
|
if (s_useVertexArrayObjects)
|
||||||
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount)
|
void NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount)
|
||||||
|
|
@ -191,7 +194,9 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode mode, unsigned int firstI
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawElements(NzOpenGL::PrimitiveMode[mode], indexCount, type, offset);
|
glDrawElements(NzOpenGL::PrimitiveMode[mode], indexCount, type, offset);
|
||||||
glBindVertexArray(0);
|
|
||||||
|
if (s_useVertexArrayObjects)
|
||||||
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount)
|
void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount)
|
||||||
|
|
@ -229,7 +234,8 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instanceCount > NAZARA_RENDERER_MAX_INSTANCES)
|
unsigned int maxInstanceCount = s_instanceBuffer.GetVertexCount();
|
||||||
|
if (instanceCount > maxInstanceCount)
|
||||||
{
|
{
|
||||||
NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")" );
|
NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")" );
|
||||||
return;
|
return;
|
||||||
|
|
@ -259,7 +265,9 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawElementsInstanced(NzOpenGL::PrimitiveMode[mode], indexCount, type, offset, instanceCount);
|
glDrawElementsInstanced(NzOpenGL::PrimitiveMode[mode], indexCount, type, offset, instanceCount);
|
||||||
glBindVertexArray(0);
|
|
||||||
|
if (s_useVertexArrayObjects)
|
||||||
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::DrawPrimitives(nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount)
|
void NzRenderer::DrawPrimitives(nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount)
|
||||||
|
|
@ -287,7 +295,9 @@ void NzRenderer::DrawPrimitives(nzPrimitiveMode mode, unsigned int firstVertex,
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawArrays(NzOpenGL::PrimitiveMode[mode], firstVertex, vertexCount);
|
glDrawArrays(NzOpenGL::PrimitiveMode[mode], firstVertex, vertexCount);
|
||||||
glBindVertexArray(0);
|
|
||||||
|
if (s_useVertexArrayObjects)
|
||||||
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount)
|
void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount)
|
||||||
|
|
@ -319,7 +329,8 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instanceCount > NAZARA_RENDERER_MAX_INSTANCES)
|
unsigned int maxInstanceCount = s_instanceBuffer.GetVertexCount();
|
||||||
|
if (instanceCount > maxInstanceCount)
|
||||||
{
|
{
|
||||||
NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")" );
|
NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")" );
|
||||||
return;
|
return;
|
||||||
|
|
@ -335,7 +346,9 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawArraysInstanced(NzOpenGL::PrimitiveMode[mode], firstVertex, vertexCount, instanceCount);
|
glDrawArraysInstanced(NzOpenGL::PrimitiveMode[mode], firstVertex, vertexCount, instanceCount);
|
||||||
glBindVertexArray(0);
|
|
||||||
|
if (s_useVertexArrayObjects)
|
||||||
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::Enable(nzRendererParameter parameter, bool enable)
|
void NzRenderer::Enable(nzRendererParameter parameter, bool enable)
|
||||||
|
|
@ -370,6 +383,20 @@ void NzRenderer::Flush()
|
||||||
glFlush();
|
glFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NzVertexBuffer* NzRenderer::GetInstanceBuffer()
|
||||||
|
{
|
||||||
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
if (!s_capabilities[nzRendererCap_Instancing])
|
||||||
|
{
|
||||||
|
NazaraError("Instancing not supported");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
s_updateFlags |= Update_VAO;
|
||||||
|
return &s_instanceBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
float NzRenderer::GetLineWidth()
|
float NzRenderer::GetLineWidth()
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
|
|
@ -579,7 +606,8 @@ bool NzRenderer::Initialize()
|
||||||
s_vertexBuffer = nullptr;
|
s_vertexBuffer = nullptr;
|
||||||
s_updateFlags = (Update_Matrices | Update_Program | Update_VAO);
|
s_updateFlags = (Update_Matrices | Update_Program | Update_VAO);
|
||||||
|
|
||||||
s_fullscreenQuadBuffer = new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzBufferStorage_Hardware, nzBufferUsage_Static);
|
s_fullscreenQuadBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_XY), 4, nzBufferStorage_Hardware, nzBufferUsage_Static);
|
||||||
|
|
||||||
float vertices[4*2] =
|
float vertices[4*2] =
|
||||||
{
|
{
|
||||||
-1.f, -1.f,
|
-1.f, -1.f,
|
||||||
|
|
@ -588,7 +616,7 @@ bool NzRenderer::Initialize()
|
||||||
1.f, 1.f,
|
1.f, 1.f,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!s_fullscreenQuadBuffer->Fill(vertices, 0, 4))
|
if (!s_fullscreenQuadBuffer.Fill(vertices, 0, 4))
|
||||||
{
|
{
|
||||||
NazaraError("Failed to fill fullscreen quad buffer");
|
NazaraError("Failed to fill fullscreen quad buffer");
|
||||||
Uninitialize();
|
Uninitialize();
|
||||||
|
|
@ -600,17 +628,14 @@ bool NzRenderer::Initialize()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
s_instancingBuffer = new NzVertexBuffer(NzVertexDeclaration::Get(nzVertexLayout_Matrix4), NAZARA_RENDERER_MAX_INSTANCES, nzBufferStorage_Hardware, nzBufferUsage_Dynamic);
|
s_instanceBuffer.Reset(NzVertexDeclaration::Get(nzVertexLayout_Matrix4), NAZARA_RENDERER_INSTANCE_BUFFER_SIZE/sizeof(NzMatrix4f), nzBufferStorage_Hardware, nzBufferUsage_Dynamic);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
s_capabilities[nzRendererCap_Instancing] = false;
|
s_capabilities[nzRendererCap_Instancing] = false;
|
||||||
s_instancingBuffer = nullptr;
|
|
||||||
NazaraError("Failed to create instancing buffer: " + NzString(e.what())); ///TODO: Noexcept
|
NazaraError("Failed to create instancing buffer: " + NzString(e.what())); ///TODO: Noexcept
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
s_instancingBuffer = nullptr;
|
|
||||||
|
|
||||||
if (!NzMaterial::Initialize())
|
if (!NzMaterial::Initialize())
|
||||||
{
|
{
|
||||||
|
|
@ -788,61 +813,6 @@ void NzRenderer::SetIndexBuffer(const NzIndexBuffer* indexBuffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::SetInstancingData(const void* instancingData, unsigned int instanceCount)
|
|
||||||
{
|
|
||||||
#if NAZARA_RENDERER_SAFE
|
|
||||||
if (!s_capabilities[nzRendererCap_Instancing])
|
|
||||||
{
|
|
||||||
NazaraError("Instancing not supported");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!instancingData)
|
|
||||||
{
|
|
||||||
NazaraError("Instancing data must be valid");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instanceCount == 0)
|
|
||||||
{
|
|
||||||
NazaraError("Instance count must be over 0");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int maxInstanceCount = s_instancingBuffer->GetVertexCount();
|
|
||||||
if (instanceCount > maxInstanceCount)
|
|
||||||
{
|
|
||||||
NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " + NzString::Number(maxInstanceCount) + ")");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!s_instancingBuffer->FillVertices(instancingData, 0, instanceCount, true))
|
|
||||||
NazaraError("Failed to fill instancing buffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
void NzRenderer::SetInstancingDeclaration(const NzVertexDeclaration* declaration, unsigned int* newMaxInstanceCount)
|
|
||||||
{
|
|
||||||
#if NAZARA_RENDERER_SAFE
|
|
||||||
if (!s_capabilities[nzRendererCap_Instancing])
|
|
||||||
{
|
|
||||||
NazaraError("Instancing not supported");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!declaration)
|
|
||||||
{
|
|
||||||
NazaraError("Declaration must be valid");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
s_instancingBuffer->SetVertexDeclaration(declaration);
|
|
||||||
|
|
||||||
if (newMaxInstanceCount)
|
|
||||||
*newMaxInstanceCount = s_instancingBuffer->GetVertexCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
void NzRenderer::SetLineWidth(float width)
|
void NzRenderer::SetLineWidth(float width)
|
||||||
{
|
{
|
||||||
#if NAZARA_RENDERER_SAFE
|
#if NAZARA_RENDERER_SAFE
|
||||||
|
|
@ -1185,11 +1155,8 @@ void NzRenderer::Uninitialize()
|
||||||
NzDebugDrawer::Uninitialize();
|
NzDebugDrawer::Uninitialize();
|
||||||
|
|
||||||
// Libération des buffers
|
// Libération des buffers
|
||||||
delete s_fullscreenQuadBuffer;
|
s_fullscreenQuadBuffer.Reset();
|
||||||
delete s_instancingBuffer;
|
s_instanceBuffer.Reset();
|
||||||
|
|
||||||
s_fullscreenQuadBuffer = nullptr;
|
|
||||||
s_instancingBuffer = nullptr;
|
|
||||||
|
|
||||||
// Libération des VAOs
|
// Libération des VAOs
|
||||||
for (auto& pair : s_vaos)
|
for (auto& pair : s_vaos)
|
||||||
|
|
@ -1419,8 +1386,11 @@ bool NzRenderer::EnsureStateUpdate()
|
||||||
|
|
||||||
if (s_instancing)
|
if (s_instancing)
|
||||||
{
|
{
|
||||||
bufferOffset = s_instancingBuffer->GetStartOffset();
|
NzHardwareBuffer* instanceBufferImpl = static_cast<NzHardwareBuffer*>(s_instanceBuffer.GetBuffer()->GetImpl());
|
||||||
vertexDeclaration = s_instancingBuffer->GetVertexDeclaration();
|
instanceBufferImpl->Bind();
|
||||||
|
|
||||||
|
bufferOffset = s_instanceBuffer.GetStartOffset();
|
||||||
|
vertexDeclaration = s_instanceBuffer.GetVertexDeclaration();
|
||||||
stride = vertexDeclaration->GetStride();
|
stride = vertexDeclaration->GetStride();
|
||||||
for (unsigned int i = nzAttributeUsage_FirstInstanceData; i <= nzAttributeUsage_LastInstanceData; ++i)
|
for (unsigned int i = nzAttributeUsage_FirstInstanceData; i <= nzAttributeUsage_LastInstanceData; ++i)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue