From b35b1e0125147f67eef98025b3567968fe81f21f Mon Sep 17 00:00:00 2001 From: Engin Manap Date: Mon, 23 Dec 2024 22:43:47 +0100 Subject: [PATCH] WIP render based on material Fix transparent objects not visible Fix requiring copies for iteration (because of const) --- src/Occlusion/RenderList.cpp | 2 +- src/Occlusion/RenderList.h | 26 +++++++++----------------- src/World.cpp | 7 +++---- src/World.h | 2 +- 4 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/Occlusion/RenderList.cpp b/src/Occlusion/RenderList.cpp index bea0b1d5..da15d808 100644 --- a/src/Occlusion/RenderList.cpp +++ b/src/Occlusion/RenderList.cpp @@ -16,7 +16,7 @@ void RenderList::addMeshMaterial(const std::shared_ptr &material meshIterator->second.isAnimated = meshIterator->second.isAnimated || model->isAnimated(); meshIterator->second.boneTransforms = model->getBoneTransforms(); materialIterator->second.maxDepthPerMesh[meshAsset] = std::max(materialIterator->second.maxDepthPerMesh[meshAsset], maxDepth);//This is the max depth of this material - this->materialRenderPriorityMap.clear();//Why? because we don't know if we need to sort the list again + materialIterator->second.meshRenderPriorityMap.clear();//Why? because we don't know if we need to sort the list again maxDepthPerMaterial[material] = std::max(maxDepthPerMaterial[material], maxDepth); materialRenderPriorityMap.clear();//Why? because we don't know if we need to sort the list again } diff --git a/src/Occlusion/RenderList.h b/src/Occlusion/RenderList.h index ea8e72a2..f920df6b 100644 --- a/src/Occlusion/RenderList.h +++ b/src/Occlusion/RenderList.h @@ -27,11 +27,11 @@ struct PerMeshRenderInformation { class RenderList { struct PerMaterialRenderInformation { class perMaterialIterator { - PerMaterialRenderInformation& perMaterialRenderInformation; + const PerMaterialRenderInformation& perMaterialRenderInformation; std::multimap>::const_reverse_iterator it; bool end; public: - explicit perMaterialIterator(PerMaterialRenderInformation& perMaterialRenderInformation) : perMaterialRenderInformation(perMaterialRenderInformation), end(false) { + explicit perMaterialIterator(const PerMaterialRenderInformation& perMaterialRenderInformation) : perMaterialRenderInformation(perMaterialRenderInformation), end(false) { if (perMaterialRenderInformation.meshRenderPriorityMap.empty()) { for (auto &materialEntry : perMaterialRenderInformation.maxDepthPerMesh) { perMaterialRenderInformation.meshRenderPriorityMap.insert(std::make_pair(materialEntry.second, materialEntry.first)); @@ -43,14 +43,6 @@ class RenderList { } } - perMaterialIterator& operator=(const perMaterialIterator& other) { - if (this != &other) { - perMaterialRenderInformation = other.perMaterialRenderInformation; - it = other.it; - end = other.end; - } - return *this; - } bool isEnd() const { return end; } @@ -71,7 +63,7 @@ class RenderList { }; std::unordered_map,PerMeshRenderInformation> meshesToRender; std::unordered_map, float> maxDepthPerMesh; //this map is created same time as meshes to render, but it is a pre transform container, as ordering by value not possible(or logical) in maps. - std::multimap> meshRenderPriorityMap; //this map is created after first two values are created. It is just a sorted container to use sorting of materials + mutable std::multimap> meshRenderPriorityMap; //this map is created after first two values are created. It is just a sorted container to use sorting of materials std::unordered_map, PerMeshRenderInformation>::iterator getOrCreateMeshEntry(const std::shared_ptr &meshAsset) { std::unordered_map, PerMeshRenderInformation>::iterator it = meshesToRender.find(meshAsset); if (it == meshesToRender.end()) { @@ -85,10 +77,10 @@ class RenderList { public: class RenderListIterator { - RenderList& renderList; + const RenderList& renderList; bool end; std::multimap>::reverse_iterator materialPriorityIt; - PerMaterialRenderInformation::perMaterialIterator* perMaterialIterator = nullptr; + mutable PerMaterialRenderInformation::perMaterialIterator* perMaterialIterator = nullptr; public: @@ -96,12 +88,12 @@ class RenderList { * Provides an iterator that automatically iterates through materials and meshes, using depth information as ordering. * Using this iterator is prone to iterator invalidation. Thats why we don't remove items while any of these are on the fly. */ - explicit RenderListIterator(RenderList& renderList) : renderList(renderList), end(false) + explicit RenderListIterator(const RenderList& renderList) : renderList(renderList), end(false) , materialPriorityIt(renderList.materialRenderPriorityMap.rbegin()) { if (materialPriorityIt == renderList.materialRenderPriorityMap.rend()) { end = true; } else { - perMaterialIterator = new PerMaterialRenderInformation::perMaterialIterator(renderList.perMaterialMeshMap[materialPriorityIt->second]); + perMaterialIterator = new PerMaterialRenderInformation::perMaterialIterator(renderList.perMaterialMeshMap.at(materialPriorityIt->second)); } } ~RenderListIterator() { @@ -146,7 +138,7 @@ class RenderList { private: std::unordered_map, PerMaterialRenderInformation> perMaterialMeshMap; //Each mesh has its own render information std::unordered_map, float> maxDepthPerMaterial; //this map is created same time as meshes to render, but it is a pre transform container, as ordering by value not possible(or logical) in maps. - std::multimap> materialRenderPriorityMap; //this map is created after first two values are created. It is just a sorted container to use sorting of materials + mutable std::multimap> materialRenderPriorityMap; //this map is created after first two values are created. It is just a sorted container to use sorting of materials std::unordered_map, PerMaterialRenderInformation>::iterator getOrCreateMaterialEntry(const std::shared_ptr &material) { std::unordered_map, PerMaterialRenderInformation>::iterator it = perMaterialMeshMap.find(material); @@ -160,7 +152,7 @@ class RenderList { public: void addMeshMaterial(const std::shared_ptr &material, const std::shared_ptr &meshAsset, Model *model, uint32_t lod, float maxDepth); void removeMeshMaterial(const std::shared_ptr &material, const std::shared_ptr &meshAsset, uint32_t modelId); - RenderListIterator getIterator() { + RenderListIterator getIterator() const { if (materialRenderPriorityMap.empty()) { //first fill the map for (auto &materialEntry : maxDepthPerMaterial) { diff --git a/src/World.cpp b/src/World.cpp index 6830ff36..7113a6a8 100755 --- a/src/World.cpp +++ b/src/World.cpp @@ -854,8 +854,7 @@ void World::renderDebug(const std::shared_ptr& renderProgram [[ debugDrawer->flushDraws(); } - - void World::renderSingleRenderList(const std::shared_ptr &renderProgram, RenderList& renderList) const { + void World::renderSingleRenderList(const std::shared_ptr &renderProgram, const RenderList& renderList) const { int diffuseMapAttachPoint = 1; int ambientMapAttachPoint = 2; int specularMapAttachPoint = 3; @@ -925,7 +924,7 @@ void World::renderCameraByTag(const std::shared_ptr &renderProg if (!VisibilityRequest::vectorComparator(renderListEntry.first, tags)) { continue; } - RenderList renderList = renderListEntry.second; + const RenderList& renderList = renderListEntry.second; renderSingleRenderList(renderProgram, renderList); } } @@ -981,7 +980,7 @@ void World::renderLight(unsigned int lightIndex, unsigned int renderLayer, const if (!VisibilityRequest::vectorComparator(iterator.first, tags)) { continue; } - RenderList renderList = iterator.second; + const RenderList& renderList = iterator.second; renderSingleRenderList(renderProgram, renderList); } } diff --git a/src/World.h b/src/World.h index b2f22cc7..92aaa9be 100644 --- a/src/World.h +++ b/src/World.h @@ -415,7 +415,7 @@ class World { void renderSky(const std::shared_ptr& renderProgram, const std::string &cameraName [[gnu::unused]], const std::vector &tags [[gnu::unused]]) const; void renderDebug(const std::shared_ptr& renderProgram, const std::string &cameraName [[gnu::unused]], const std::vector &tags [[gnu::unused]]) const; - void renderSingleRenderList(const std::shared_ptr &renderProgram, RenderList& renderList) const; + void renderSingleRenderList(const std::shared_ptr &renderProgram, const RenderList& renderList) const; void renderPlayerAttachmentsRecursiveByTag(PhysicalRenderable *attachment, uint64_t renderTag, const std::shared_ptr &renderProgram, std::vector &alreadyRenderedModelIds) const;