Added new abstract renderqueue rendering

Former-commit-id: 35e66174ccc3de3b43571f12a149e6d3c59cc2c9
This commit is contained in:
Lynix
2014-05-28 01:00:18 +02:00
parent d09f6def2b
commit c901b5808e
7 changed files with 407 additions and 518 deletions

View File

@@ -58,10 +58,9 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor
if (used)
{
bool& renderQueueInstancing = std::get<1>(matIt.second);
NzDeferredRenderQueue::BatchedSkeletalMeshContainer& skeletalContainer = std::get<2>(matIt.second);
NzDeferredRenderQueue::BatchedStaticMeshContainer& staticContainer = std::get<3>(matIt.second);
NzDeferredRenderQueue::MeshInstanceContainer& meshInstances = std::get<2>(matIt.second);
if (!skeletalContainer.empty() || !staticContainer.empty())
if (!meshInstances.empty())
{
const NzMaterial* material = matIt.first;
@@ -88,26 +87,16 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor
lastShader = shader;
}
// Meshs squelettiques
/*if (!skeletalContainer.empty())
// Meshes
for (auto& meshIt : meshInstances)
{
NzRenderer::SetVertexBuffer(m_skinningBuffer); // Vertex buffer commun
for (auto& subMeshIt : container)
{
///TODO
}
}*/
const NzMeshData& meshData = meshIt.first;
std::vector<NzMatrix4f>& instances = meshIt.second;
// Meshs statiques
for (auto& subMeshIt : staticContainer)
{
const NzStaticMesh* mesh = subMeshIt.first;
std::vector<NzDeferredRenderQueue::StaticData>& staticData = subMeshIt.second;
if (!staticData.empty())
if (!instances.empty())
{
const NzIndexBuffer* indexBuffer = mesh->GetIndexBuffer();
const NzVertexBuffer* vertexBuffer = mesh->GetVertexBuffer();
const NzIndexBuffer* indexBuffer = meshData.indexBuffer;
const NzVertexBuffer* vertexBuffer = meshData.vertexBuffer;
// Gestion du draw call avant la boucle de rendu
std::function<void(nzPrimitiveMode, unsigned int, unsigned int)> DrawFunc;
@@ -130,49 +119,43 @@ bool NzDeferredGeometryPass::Process(const NzScene* scene, unsigned int firstWor
NzRenderer::SetIndexBuffer(indexBuffer);
NzRenderer::SetVertexBuffer(vertexBuffer);
nzPrimitiveMode primitiveMode = mesh->GetPrimitiveMode();
if (useInstancing)
{
// On récupère le buffer d'instancing du Renderer et on le configure pour fonctionner avec des matrices
NzVertexBuffer* instanceBuffer = NzRenderer::GetInstanceBuffer();
instanceBuffer->SetVertexDeclaration(NzVertexDeclaration::Get(nzVertexLayout_Matrix4));
unsigned int stride = instanceBuffer->GetStride();
const NzDeferredRenderQueue::StaticData* data = &staticData[0];
unsigned int instanceCount = staticData.size();
unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre de sommets maximum avec la déclaration donnée plus hautg
const NzMatrix4f* instanceMatrices = &instances[0];
unsigned int instanceCount = instances.size();
unsigned int maxInstanceCount = instanceBuffer->GetVertexCount(); // Le nombre de matrices que peut contenir le buffer
while (instanceCount > 0)
{
// On calcule le nombre d'instances que l'on pourra afficher cette fois-ci (Selon la taille du buffer d'instancing)
unsigned int renderedInstanceCount = std::min(instanceCount, maxInstanceCount);
instanceCount -= renderedInstanceCount;
NzBufferMapper<NzVertexBuffer> mapper(instanceBuffer, nzBufferAccess_DiscardAndWrite, 0, renderedInstanceCount);
nzUInt8* ptr = reinterpret_cast<nzUInt8*>(mapper.GetPointer());
// On remplit l'instancing buffer avec nos matrices world
instanceBuffer->Fill(instanceMatrices, 0, renderedInstanceCount, true);
instanceMatrices += renderedInstanceCount;
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);
// Et on affiche
InstancedDrawFunc(renderedInstanceCount, meshData.primitiveMode, 0, indexCount);
}
}
else
{
for (const NzDeferredRenderQueue::StaticData& data : staticData)
// Sans instancing, on doit effectuer un drawcall pour chaque instance
// Cela reste néanmoins plus rapide que l'instancing en dessous d'un certain nombre d'instances
// À cause du temps de modification du buffer d'instancing
for (const NzMatrix4f& matrix : instances)
{
NzRenderer::SetMatrix(nzMatrixType_World, data.transformMatrix);
DrawFunc(primitiveMode, 0, indexCount);
NzRenderer::SetMatrix(nzMatrixType_World, matrix);
DrawFunc(meshData.primitiveMode, 0, indexCount);
}
}
staticData.clear();
instances.clear();
}
}
}