From 3a64995b684cabc245f17bba9cfceb3ac49318d8 Mon Sep 17 00:00:00 2001 From: Engin Manap Date: Fri, 27 Dec 2024 17:30:39 +0100 Subject: [PATCH] Fix editor previews use wrong/invalid materials Turns out it was a single line fix, but I did fix other issues with it, including issue #153 fixed. --- src/API/Graphics/GraphicsProgram.cpp | 1 + src/API/Graphics/GraphicsProgram.h | 2 +- src/Editor/Editor.cpp | 6 +-- src/Editor/Editor.h | 2 +- src/GameObjects/Model.cpp | 28 +++-------- src/GameObjects/Model.h | 6 +-- src/Occlusion/RenderList.cpp | 52 +++++++++++++++++++- src/Occlusion/RenderList.h | 9 +++- src/World.cpp | 72 +++------------------------- src/World.h | 4 +- 10 files changed, 79 insertions(+), 103 deletions(-) diff --git a/src/API/Graphics/GraphicsProgram.cpp b/src/API/Graphics/GraphicsProgram.cpp index 819e6f65..bcbe8ca7 100644 --- a/src/API/Graphics/GraphicsProgram.cpp +++ b/src/API/Graphics/GraphicsProgram.cpp @@ -46,6 +46,7 @@ GraphicsProgram::~GraphicsProgram() { //TODO remove with material editor void GraphicsProgram::setSamplersAndUBOs() { + graphicsWrapper->attachMaterialUBO(getID()); //TODO these will be configurable with material editor int diffuseMapAttachPoint = 1; diff --git a/src/API/Graphics/GraphicsProgram.h b/src/API/Graphics/GraphicsProgram.h index f141ff96..a8e91913 100644 --- a/src/API/Graphics/GraphicsProgram.h +++ b/src/API/Graphics/GraphicsProgram.h @@ -82,7 +82,7 @@ class GraphicsProgram { return graphicsProgramAsset->getProgramName(); } - bool IsMaterialRequired() const { + bool isMaterialRequired() const { return materialRequired; } diff --git a/src/Editor/Editor.cpp b/src/Editor/Editor.cpp index 34db8c97..76e68523 100644 --- a/src/Editor/Editor.cpp +++ b/src/Editor/Editor.cpp @@ -1230,11 +1230,9 @@ void Editor::createObjectTreeRecursive(PhysicalRenderable *physicalRenderable, u } } -void Editor::renderSelectedObject(Model* model) { +void Editor::renderSelectedObject(Model* model) const { backgroundRenderStage->activate(true); - std::vector modelIndexes; - modelIndexes.push_back(glm::uvec4(model->getWorldObjectID(),0,0,0)); - model->renderWithProgramInstanced(modelIndexes, *(graphicsProgram.get()), 0); + model->convertToRenderList(0, 0).render(world->graphicsWrapper, graphicsProgram); world->renderPipeline->reActivateLastStage(); } diff --git a/src/Editor/Editor.h b/src/Editor/Editor.h index 294b2117..3aad0599 100644 --- a/src/Editor/Editor.h +++ b/src/Editor/Editor.h @@ -49,7 +49,7 @@ class Editor { ImGuiTreeNodeFlags nodeFlags, ImGuiTreeNodeFlags leafFlags, std::vector parentage); - void renderSelectedObject(Model* model); + void renderSelectedObject(Model* model) const; void setTransformToModel(Model *model, const glm::vec3 &newObjectPosition); }; diff --git a/src/GameObjects/Model.cpp b/src/GameObjects/Model.cpp index 02a93c37..cea5c0f4 100644 --- a/src/GameObjects/Model.cpp +++ b/src/GameObjects/Model.cpp @@ -9,6 +9,7 @@ #include "Utils/HardCodedTags.h" #include #include +#include #ifdef CEREAL_SUPPORT #include @@ -191,37 +192,20 @@ void Model::renderWithProgram(std::shared_ptr program, uint32_t } else { program->setUniform("isAnimated", false); } - if(program->IsMaterialRequired()) { + if(program->isMaterialRequired()) { this->activateTexturesOnly((*iter)->material); } graphicsWrapper->render(program->getID(), (*iter)->mesh->getVao(), (*iter)->mesh->getEbo(), (*iter)->mesh->getTriangleCount()[lodLevel] * 3); } } -void Model::renderWithProgramInstanced(const std::vector &modelIndices, GraphicsProgram &program, uint32_t lodLevel) { +RenderList Model::convertToRenderList(uint32_t lodLevel, float depth) const { + RenderList renderList; for (auto iter = meshMetaData.begin(); iter != meshMetaData.end(); ++iter) { - if (animated) { - //set all of the bones to unitTransform for testing - program.setUniformArray("boneTransformArray[0]", boneTransforms); - program.setUniform("isAnimated", true); - } else { - program.setUniform("isAnimated", false); - } - if(program.IsMaterialRequired()) { - std::vector modelIndicesWithMaterialIndex = modelIndices; - for (size_t i = 0; i < modelIndicesWithMaterialIndex.size(); ++i) { - modelIndicesWithMaterialIndex[i].y = (*iter)->material->getMaterialIndex(); - } - graphicsWrapper->setModelIndexesUBO(modelIndicesWithMaterialIndex); - this->activateTexturesOnly((*iter)->material); - graphicsWrapper->renderInstanced(program.getID(), (*iter)->mesh->getVao(), (*iter)->mesh->getEbo(), (*iter)->mesh->getTriangleCount()[lodLevel] * 3, (*iter)->mesh->getOffsets()[lodLevel], modelIndices.size()); - - } else { - graphicsWrapper->setModelIndexesUBO(modelIndices); - graphicsWrapper->renderInstanced(program.getID(), (*iter)->mesh->getVao(), (*iter)->mesh->getEbo(), (*iter)->mesh->getTriangleCount()[lodLevel] * 3, (*iter)->mesh->getOffsets()[lodLevel], modelIndices.size()); - } + renderList.addMeshMaterial((*iter)->material, (*iter)->mesh, this, lodLevel, depth); } + return renderList; } bool Model::fillObjects(tinyxml2::XMLDocument &document, tinyxml2::XMLElement *objectsNode) const { diff --git a/src/GameObjects/Model.h b/src/GameObjects/Model.h index 28ad3837..4d324f59 100644 --- a/src/GameObjects/Model.h +++ b/src/GameObjects/Model.h @@ -19,7 +19,7 @@ #include "Sound.h" class ActorInterface; - +class RenderList; class Model : public PhysicalRenderable, public GameObject { public: struct MeshMeta { @@ -114,7 +114,7 @@ class Model : public PhysicalRenderable, public GameObject { void renderWithProgram(std::shared_ptr program, uint32_t lodLevel) override; - + RenderList convertToRenderList(uint32_t lodLevel, float depth) const; void renderWithProgramInstanced(const std::vector & modelIndices, GraphicsProgram &program, uint32_t lodLevel); bool isAnimated() const { return animated;} @@ -191,7 +191,7 @@ class Model : public PhysicalRenderable, public GameObject { return GameObject::MODEL; } - std::vector* getBoneTransforms() {return &boneTransforms;} + const std::vector* getBoneTransforms() const {return &boneTransforms;} std::string getName() const override { return name + "_" + std::to_string(objectID); diff --git a/src/Occlusion/RenderList.cpp b/src/Occlusion/RenderList.cpp index 018f64a7..30b5b67d 100644 --- a/src/Occlusion/RenderList.cpp +++ b/src/Occlusion/RenderList.cpp @@ -5,7 +5,7 @@ #include "RenderList.h" #include "../GameObjects/Model.h" -void RenderList::addMeshMaterial(const std::shared_ptr &material, const std::shared_ptr &meshAsset, Model *model, uint32_t lod, float maxDepth) { +void RenderList::addMeshMaterial(const std::shared_ptr &material, const std::shared_ptr &meshAsset, const Model *model, uint32_t lod, float maxDepth) { auto materialIterator = getOrCreateMaterialEntry(material); auto meshIterator = materialIterator->second.getOrCreateMeshEntry(meshAsset); auto requestedObjectIterator = std::find_if(meshIterator->second.indices.begin(), meshIterator->second.indices.end(), [model](const glm::uvec4& entry) { return entry.x == model->getWorldObjectID(); }); @@ -58,6 +58,56 @@ void RenderList::removeModelFromAll(uint32_t modelId) { } } +void RenderList::render(GraphicsInterface *graphicsWrapper, const std::shared_ptr &renderProgram) const { + int diffuseMapAttachPoint = 1; + int ambientMapAttachPoint = 2; + int specularMapAttachPoint = 3; + int opacityMapAttachPoint = 4; + int normalMapAttachPoint = 5; + + //now render all of the meshes + for (auto renderListIterator = this->getIterator(); !renderListIterator.isEnd(); ++renderListIterator) { + if (renderProgram->isMaterialRequired()) { + const auto& material = renderListIterator.getMaterial(); + //activate textures + if(material->hasDiffuseMap()) { + graphicsWrapper->attachTexture(material->getDiffuseTexture()->getID(), diffuseMapAttachPoint); + } + if(material->hasAmbientMap()) { + graphicsWrapper->attachTexture(material->getAmbientTexture()->getID(), ambientMapAttachPoint); + } + + if(material->hasSpecularMap()) { + graphicsWrapper->attachTexture(material->getSpecularTexture()->getID(), specularMapAttachPoint); + } + + if(material->hasOpacityMap()) { + graphicsWrapper->attachTexture(material->getOpacityTexture()->getID(), opacityMapAttachPoint); + } + + if(material->hasNormalMap()) { + graphicsWrapper->attachTexture(material->getNormalTexture()->getID(), normalMapAttachPoint); + } + } + + + if (renderListIterator.get().indices.empty()) { + std::cerr << "Empty meshInfo" << std::endl; + continue; + } + if (renderListIterator.get().isAnimated) { + //set all of the bones to unitTransform for testing + renderProgram->setUniformArray("boneTransformArray[0]", *renderListIterator.get().boneTransforms); + renderProgram->setUniform("isAnimated", true); + } else { + renderProgram->setUniform("isAnimated", false); + } + + graphicsWrapper->setModelIndexesUBO(renderListIterator.get().indices); + graphicsWrapper->renderInstanced(renderProgram->getID(), renderListIterator.getMesh()->getVao(), renderListIterator.getMesh()->getEbo(), renderListIterator.getMesh()->getTriangleCount()[renderListIterator.get().lod] * 3, renderListIterator.getMesh()->getOffsets()[renderListIterator.get().lod], renderListIterator.get().indices.size()); + } +} + void RenderList::cleanUpEmptyRenderLists() { //When a model is no longer visible, it will be removed. That means it is possible some Per Mesh Render Informations have no indices. We should clean them up auto materialIterator = perMaterialMeshMap.begin(); diff --git a/src/Occlusion/RenderList.h b/src/Occlusion/RenderList.h index f42896e4..72c272c4 100644 --- a/src/Occlusion/RenderList.h +++ b/src/Occlusion/RenderList.h @@ -12,6 +12,8 @@ #include #include +class GraphicsInterface; +class GraphicsProgram; class MeshAsset; class Material; class Model; @@ -21,7 +23,7 @@ struct PerMeshRenderInformation { uint32_t lod = 0; //Max level of detail. Since we use instanced rendering, using single LOD for all meshes is faster than multiple draw calls (at least in my testing) bool isAnimated = false; float depth = 0; //max depth for this mesh set - std::vector* boneTransforms = nullptr;//known wrong, as it will only work for one model id. Placeholder until bone transform index lookup implementation + const std::vector* boneTransforms = nullptr;//known wrong, as it will only work for one model id. Placeholder until bone transform index lookup implementation }; class RenderList { @@ -150,7 +152,7 @@ class RenderList { return it; } public: - void addMeshMaterial(const std::shared_ptr &material, const std::shared_ptr &meshAsset, Model *model, uint32_t lod, float maxDepth); + void addMeshMaterial(const std::shared_ptr &material, const std::shared_ptr &meshAsset, const Model *model, uint32_t lod, float maxDepth); void removeMeshMaterial(const std::shared_ptr &material, const std::shared_ptr &meshAsset, uint32_t modelId); void removeModelFromAll(uint32_t modelId); RenderListIterator getIterator() const { @@ -163,6 +165,9 @@ class RenderList { return RenderListIterator(*this); } + + void render(GraphicsInterface* graphicsWrapper, const std::shared_ptr &renderProgram) const; + void cleanUpEmptyRenderLists(); void clear() { diff --git a/src/World.cpp b/src/World.cpp index 7113a6a8..8df5a10a 100755 --- a/src/World.cpp +++ b/src/World.cpp @@ -53,13 +53,8 @@ SDL2MultiThreading::Condition VisibilityRequest::condition; //FIXME this variable doesn't looks like it belongs here - void World::setupRenderForPipeline() { - for (const auto& stageInfo:renderPipeline->getStages()) { - for(const auto& graphicsProgram:stageInfo.programs) { - graphicsWrapper->attachMaterialUBO(graphicsProgram->getID()); - } - } - } +void World::setupRenderForPipeline() const { +} World::World(const std::string &name, PlayerInfo startingPlayerType, InputHandler *inputHandler, std::shared_ptr assetManager, OptionsUtil::Options *options) @@ -854,57 +849,6 @@ void World::renderDebug(const std::shared_ptr& renderProgram [[ debugDrawer->flushDraws(); } - void World::renderSingleRenderList(const std::shared_ptr &renderProgram, const RenderList& renderList) const { - int diffuseMapAttachPoint = 1; - int ambientMapAttachPoint = 2; - int specularMapAttachPoint = 3; - int opacityMapAttachPoint = 4; - int normalMapAttachPoint = 5; - - //now render all of the meshes - for (auto renderListIterator = renderList.getIterator(); !renderListIterator.isEnd(); ++renderListIterator) { - - const auto& material = renderListIterator.getMaterial(); - {//activate textures - if(material->hasDiffuseMap()) { - graphicsWrapper->attachTexture(material->getDiffuseTexture()->getID(), diffuseMapAttachPoint); - } - if(material->hasAmbientMap()) { - graphicsWrapper->attachTexture(material->getAmbientTexture()->getID(), ambientMapAttachPoint); - } - - if(material->hasSpecularMap()) { - graphicsWrapper->attachTexture(material->getSpecularTexture()->getID(), specularMapAttachPoint); - } - - if(material->hasOpacityMap()) { - graphicsWrapper->attachTexture(material->getOpacityTexture()->getID(), opacityMapAttachPoint); - } - - if(material->hasNormalMap()) { - graphicsWrapper->attachTexture(material->getNormalTexture()->getID(), normalMapAttachPoint); - } - - } - - - if (renderListIterator.get().indices.empty()) { - std::cerr << "Empty meshInfo" << std::endl; - continue; - } - if (renderListIterator.get().isAnimated) { - //set all of the bones to unitTransform for testing - renderProgram->setUniformArray("boneTransformArray[0]", *renderListIterator.get().boneTransforms); - renderProgram->setUniform("isAnimated", true); - } else { - renderProgram->setUniform("isAnimated", false); - } - - graphicsWrapper->setModelIndexesUBO(renderListIterator.get().indices); - graphicsWrapper->renderInstanced(renderProgram->getID(), renderListIterator.getMesh()->getVao(), renderListIterator.getMesh()->getEbo(), renderListIterator.getMesh()->getTriangleCount()[renderListIterator.get().lod] * 3, renderListIterator.getMesh()->getOffsets()[renderListIterator.get().lod], renderListIterator.get().indices.size()); - } - } - void World::renderCameraByTag(const std::shared_ptr &renderProgram, const std::string &cameraName, const std::vector &tags) const { uint64_t hashedCameraTag = HashUtil::hashString(cameraName); tempRenderedObjectsSet.clear(); @@ -925,7 +869,7 @@ void World::renderCameraByTag(const std::shared_ptr &renderProg continue; } const RenderList& renderList = renderListEntry.second; - renderSingleRenderList(renderProgram, renderList); + renderList.render(graphicsWrapper, renderProgram); } } } @@ -953,10 +897,8 @@ void World::renderPlayerAttachmentsRecursiveByTag(PhysicalRenderable *attachment } if(std::find(alreadyRenderedModelIds.begin(), alreadyRenderedModelIds.end(), attachmentObject->getWorldObjectID()) == alreadyRenderedModelIds.end() && attachmentObject->hasTag(renderTag)) { alreadyRenderedModelIds.emplace_back(attachmentObject->getWorldObjectID()); - std::vector temp; - temp.push_back(glm::uvec4(attachmentObject->getWorldObjectID(), 0, 0, 0)); if(attachmentObject->getTypeID() == GameObject::MODEL) { - (static_cast(attachment))->renderWithProgramInstanced(temp, *(renderProgram), 0);//it is guaranteed to be very close to the player. + static_cast(attachment)->convertToRenderList(0,0.0f).render(graphicsWrapper, renderProgram); } } for (const auto &child: children) { @@ -981,7 +923,7 @@ void World::renderLight(unsigned int lightIndex, unsigned int renderLayer, const continue; } const RenderList& renderList = iterator.second; - renderSingleRenderList(renderProgram, renderList); + renderList.render(graphicsWrapper, renderProgram); } } @@ -1016,9 +958,7 @@ void World::ImGuiFrameSetup(std::shared_ptr graphicsProgram, co playerPlaceHolder->getTransformation()->setTranslate(physicalPlayer->getPosition()); playerPlaceHolder->getTransformation()->setOrientation(physicalPlayer->getLookDirectionQuaternion()); - std::vector temp; - temp.push_back(glm::uvec4(playerPlaceHolder->getWorldObjectID(), 0, 0, 0)); - playerPlaceHolder->renderWithProgramInstanced(temp, *(graphicsProgram.get()), 0); + playerPlaceHolder->convertToRenderList(0,0).render(graphicsWrapper, graphicsProgram); } editor->renderEditor(); } diff --git a/src/World.h b/src/World.h index 92aaa9be..2838e30c 100644 --- a/src/World.h +++ b/src/World.h @@ -359,7 +359,7 @@ class World { void addLight(Light *light); - void setupRenderForPipeline(); + void setupRenderForPipeline() const; World(const std::string &name, PlayerInfo startingPlayerType, InputHandler *inputHandler, std::shared_ptr assetManager, OptionsUtil::Options *options); @@ -415,8 +415,6 @@ 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, const RenderList& renderList) const; - void renderPlayerAttachmentsRecursiveByTag(PhysicalRenderable *attachment, uint64_t renderTag, const std::shared_ptr &renderProgram, std::vector &alreadyRenderedModelIds) const;