Graphics/DeferredRenderQueue: Replace listener by signals

Former-commit-id: b874409b523a1bfd6d9dd0d74c0f28189411bcca
This commit is contained in:
Lynix 2015-06-07 18:09:37 +02:00
parent c0c6179acc
commit 65c4409f9c
3 changed files with 42 additions and 128 deletions

View File

@ -22,7 +22,7 @@
class NzForwardRenderQueue; class NzForwardRenderQueue;
class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzObjectListener class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue
{ {
public: public:
NzDeferredRenderQueue(NzForwardRenderQueue* forwardQueue); NzDeferredRenderQueue(NzForwardRenderQueue* forwardQueue);
@ -50,15 +50,10 @@ class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzObjectL
struct MeshInstanceEntry struct MeshInstanceEntry
{ {
MeshInstanceEntry(NzObjectListener* listener, int indexBufferValue, int vertexBufferValue) : NazaraSlot(NzIndexBuffer, OnIndexBufferRelease, indexBufferReleaseSlot);
indexBufferListener(listener, indexBufferValue), NazaraSlot(NzVertexBuffer, OnVertexBufferRelease, vertexBufferReleaseSlot);
vertexBufferListener(listener, vertexBufferValue)
{
}
std::vector<NzMatrix4f> instances; std::vector<NzMatrix4f> instances;
NzIndexBufferConstListener indexBufferListener;
NzVertexBufferConstListener vertexBufferListener;
}; };
typedef std::map<NzMeshData, MeshInstanceEntry, MeshDataComparator> MeshInstanceContainer; typedef std::map<NzMeshData, MeshInstanceEntry, MeshDataComparator> MeshInstanceContainer;
@ -70,12 +65,8 @@ class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzObjectL
struct BatchedModelEntry struct BatchedModelEntry
{ {
BatchedModelEntry(NzObjectListener* listener, int materialValue) : NazaraSlot(NzMaterial, OnMaterialRelease, materialReleaseSlot);
materialListener(listener, materialValue)
{
}
NzMaterialConstListener materialListener;
MeshInstanceContainer meshMap; MeshInstanceContainer meshMap;
bool enabled = false; bool enabled = false;
bool instancingEnabled = false; bool instancingEnabled = false;
@ -86,9 +77,9 @@ class NAZARA_API NzDeferredRenderQueue : public NzAbstractRenderQueue, NzObjectL
ModelBatches opaqueModels; ModelBatches opaqueModels;
NzForwardRenderQueue* m_forwardQueue; NzForwardRenderQueue* m_forwardQueue;
private: void OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer);
bool OnObjectDestroy(const NzRefCounted* object, int index) override; void OnMaterialInvalidation(const NzMaterial* material);
void OnObjectReleased(const NzRefCounted* object, int index) override; void OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer);
}; };
#endif // NAZARA_DEFERREDRENDERQUEUE_HPP #endif // NAZARA_DEFERREDRENDERQUEUE_HPP

View File

@ -47,12 +47,6 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue
void Sort(const NzAbstractViewer* viewer); void Sort(const NzAbstractViewer* viewer);
private:
void OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer);
void OnMaterialInvalidation(const NzMaterial* material);
void OnTextureInvalidation(const NzTexture* texture);
void OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer);
/// Billboards /// Billboards
struct BillboardData struct BillboardData
{ {
@ -156,6 +150,12 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue
TransparentModelContainer transparentModels; TransparentModelContainer transparentModels;
std::vector<TransparentModelData> transparentModelData; std::vector<TransparentModelData> transparentModelData;
std::vector<const NzDrawable*> otherDrawables; std::vector<const NzDrawable*> otherDrawables;
private:
void OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer);
void OnMaterialInvalidation(const NzMaterial* material);
void OnTextureInvalidation(const NzTexture* texture);
void OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer);
}; };
#endif // NAZARA_FORWARDRENDERQUEUE_HPP #endif // NAZARA_FORWARDRENDERQUEUE_HPP

View File

@ -10,16 +10,6 @@
///TODO: Rendre les billboards via Deferred Shading si possible ///TODO: Rendre les billboards via Deferred Shading si possible
namespace
{
enum ObjectType
{
ObjectType_IndexBuffer,
ObjectType_Material,
ObjectType_VertexBuffer
};
}
NzDeferredRenderQueue::NzDeferredRenderQueue(NzForwardRenderQueue* forwardQueue) : NzDeferredRenderQueue::NzDeferredRenderQueue(NzForwardRenderQueue* forwardQueue) :
m_forwardQueue(forwardQueue) m_forwardQueue(forwardQueue)
{ {
@ -85,8 +75,8 @@ void NzDeferredRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData
auto it = opaqueModels.find(material); auto it = opaqueModels.find(material);
if (it == opaqueModels.end()) if (it == opaqueModels.end())
{ {
BatchedModelEntry entry(this, ObjectType_Material); BatchedModelEntry entry;
entry.materialListener = material; entry.materialReleaseSlot.Connect(material->OnMaterialRelease, this, OnMaterialInvalidation);
it = opaqueModels.insert(std::make_pair(material, std::move(entry))).first; it = opaqueModels.insert(std::make_pair(material, std::move(entry))).first;
} }
@ -99,9 +89,11 @@ void NzDeferredRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData
auto it2 = meshMap.find(meshData); auto it2 = meshMap.find(meshData);
if (it2 == meshMap.end()) if (it2 == meshMap.end())
{ {
MeshInstanceEntry instanceEntry(this, ObjectType_IndexBuffer, ObjectType_VertexBuffer); MeshInstanceEntry instanceEntry;
instanceEntry.indexBufferListener = meshData.indexBuffer; if (meshData.indexBuffer)
instanceEntry.vertexBufferListener = meshData.vertexBuffer; instanceEntry.indexBufferReleaseSlot.Connect(meshData.indexBuffer->OnIndexBufferRelease, this, OnIndexBufferInvalidation);
instanceEntry.vertexBufferReleaseSlot.Connect(meshData.vertexBuffer->OnVertexBufferRelease, this, OnVertexBufferInvalidation);
it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first; it2 = meshMap.insert(std::make_pair(meshData, std::move(instanceEntry))).first;
} }
@ -131,110 +123,41 @@ void NzDeferredRenderQueue::Clear(bool fully)
m_forwardQueue->Clear(fully); m_forwardQueue->Clear(fully);
} }
bool NzDeferredRenderQueue::OnObjectDestroy(const NzRefCounted* object, int index) void NzDeferredRenderQueue::OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer)
{ {
switch (index)
{
case ObjectType_IndexBuffer:
{
for (auto& modelPair : opaqueModels) for (auto& modelPair : opaqueModels)
{ {
MeshInstanceContainer& meshes = modelPair.second.meshMap; MeshInstanceContainer& meshes = modelPair.second.meshMap;
for (auto it = meshes.begin(); it != meshes.end();) for (auto it = meshes.begin(); it != meshes.end();)
{ {
const NzMeshData& renderData = it->first; const NzMeshData& renderData = it->first;
if (renderData.indexBuffer == object) if (renderData.indexBuffer == indexBuffer)
it = meshes.erase(it); it = meshes.erase(it);
else else
++it; ++it;
} }
} }
break;
}
case ObjectType_Material:
{
const NzMaterial* material = static_cast<const NzMaterial*>(object);
opaqueModels.erase(material);
break;
}
case ObjectType_VertexBuffer:
{
for (auto& modelPair : opaqueModels)
{
MeshInstanceContainer& meshes = modelPair.second.meshMap;
for (auto it = meshes.begin(); it != meshes.end();)
{
const NzMeshData& renderData = it->first;
if (renderData.vertexBuffer == object)
it = meshes.erase(it);
else
++it;
}
}
break;
}
}
return false; // Nous ne voulons plus recevoir d'évènement de cette ressource
} }
void NzDeferredRenderQueue::OnObjectReleased(const NzRefCounted* object, int index) void NzDeferredRenderQueue::OnMaterialInvalidation(const NzMaterial* material)
{ {
// La ressource vient d'être libérée, nous ne pouvons donc plus utiliser la méthode traditionnelle de recherche opaqueModels.erase(material);
// des pointeurs stockés (À cause de la fonction de triage utilisant des spécificités des ressources) }
switch (index) void NzDeferredRenderQueue::OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer)
{ {
case ObjectType_IndexBuffer:
{
for (auto& modelPair : opaqueModels) for (auto& modelPair : opaqueModels)
{ {
MeshInstanceContainer& meshes = modelPair.second.meshMap; MeshInstanceContainer& meshes = modelPair.second.meshMap;
for (auto it = meshes.begin(); it != meshes.end();) for (auto it = meshes.begin(); it != meshes.end();)
{ {
const NzMeshData& renderData = it->first; const NzMeshData& renderData = it->first;
if (renderData.indexBuffer == object) if (renderData.vertexBuffer == vertexBuffer)
it = meshes.erase(it); it = meshes.erase(it);
else else
++it; ++it;
} }
} }
break;
}
case ObjectType_Material:
{
for (auto it = opaqueModels.begin(); it != opaqueModels.end(); ++it)
{
if (it->first == object)
{
opaqueModels.erase(it);
break;
}
}
break;
}
case ObjectType_VertexBuffer:
{
for (auto& modelPair : opaqueModels)
{
MeshInstanceContainer& meshes = modelPair.second.meshMap;
for (auto it = meshes.begin(); it != meshes.end();)
{
const NzMeshData& renderData = it->first;
if (renderData.vertexBuffer == object)
it = meshes.erase(it);
else
++it;
}
}
break;
}
}
} }
bool NzDeferredRenderQueue::BatchedModelMaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2) bool NzDeferredRenderQueue::BatchedModelMaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2)