From 5f5f28b3fb9439cd81104c7af5615007f91968c8 Mon Sep 17 00:00:00 2001 From: h4570 Date: Wed, 10 Aug 2022 22:42:27 +0200 Subject: [PATCH] skip not used materials --- demo/src/states/game/terrain/terrain.cpp | 1 + .../inc/loaders/3d/obj_loader/obj_loader.hpp | 16 ++-- .../src/loaders/3d/obj_loader/obj_loader.cpp | 90 +++++++++---------- engine/src/renderer/3d/mesh/mesh.cpp | 10 ++- engine/src/renderer/3d/mesh/mesh_material.cpp | 20 +++-- .../renderer/3d/mesh/mesh_material_frame.cpp | 11 ++- 6 files changed, 83 insertions(+), 65 deletions(-) diff --git a/demo/src/states/game/terrain/terrain.cpp b/demo/src/states/game/terrain/terrain.cpp index 551e09e..bb9ed58 100644 --- a/demo/src/states/game/terrain/terrain.cpp +++ b/demo/src/states/game/terrain/terrain.cpp @@ -55,6 +55,7 @@ Terrain::~Terrain() { void Terrain::allocateOptions() { options = new StaPipOptions(); + options->frustumCulling = Tyra::PipelineFrustumCulling_None; options->shadingType = Tyra::TyraShadingGouraud; options->blendingEnabled = true; options->antiAliasingEnabled = false; diff --git a/engine/inc/loaders/3d/obj_loader/obj_loader.hpp b/engine/inc/loaders/3d/obj_loader/obj_loader.hpp index 06ce534..7e92ea2 100644 --- a/engine/inc/loaders/3d/obj_loader/obj_loader.hpp +++ b/engine/inc/loaders/3d/obj_loader/obj_loader.hpp @@ -29,6 +29,11 @@ struct ObjLoaderOptions { ObjLoaderAnimationOptions animation; }; +struct MaterialVertexCount { + size_t materialId; + int count; +}; + /** Class responsible for loading & parsing obj files */ class ObjLoader : public Loader { public: @@ -45,13 +50,12 @@ class ObjLoader : public Loader { void addOutputMaterialsAndFrames( MeshBuilderData* output, const tinyobj::attrib_t& attrib, const std::vector& shapes, - const std::vector& materials, - const u16& framesCount); + const std::vector& materials, const u16& framesCount, + std::vector& materialVertexCounts); - void scan(MeshBuilderData* output, const tinyobj::attrib_t& attrib, - const std::vector& shapes, - const std::vector& materials, - const u16& frameIndex); + std::vector scan( + const std::vector& shapes, + const std::vector& materials); void importFrame(MeshBuilderData* output, const tinyobj::attrib_t& attrib, const std::vector& shapes, diff --git a/engine/src/loaders/3d/obj_loader/obj_loader.cpp b/engine/src/loaders/3d/obj_loader/obj_loader.cpp index de0e142..b540f27 100644 --- a/engine/src/loaders/3d/obj_loader/obj_loader.cpp +++ b/engine/src/loaders/3d/obj_loader/obj_loader.cpp @@ -92,12 +92,11 @@ MeshBuilderData* ObjLoader::load(const char* fullpath, "mtlib in obj file"); if (i == 1) { + auto scanResult = scan(shapes, materials); addOutputMaterialsAndFrames(result, attrib, shapes, materials, - options.animation.count); + options.animation.count, scanResult); } - scan(result, attrib, shapes, materials, i - 1); - importFrame(result, attrib, shapes, materials, i - 1, options.scale, options.flipUVs, options.animation.count); } @@ -105,10 +104,38 @@ MeshBuilderData* ObjLoader::load(const char* fullpath, return result; } +std::vector ObjLoader::scan( + const std::vector& shapes, + const std::vector& materials) { + std::vector result; + + for (size_t i = 0; i < materials.size(); i++) { + MaterialVertexCount counter = {i, 0}; + result.push_back(counter); + } + + for (size_t s = 0; s < shapes.size(); s++) { + const auto& mesh = shapes[s].mesh; + + for (size_t f = 0; f < mesh.num_face_vertices.size(); f++) { + const auto& materialId = mesh.material_ids[f]; + const auto& vertCountPerFace = size_t(mesh.num_face_vertices[f]); + + TYRA_ASSERT(vertCountPerFace == 3, + "TinyObjLoader should triangulate mesh, internal error!"); + + result[materialId].count += vertCountPerFace; + } + } + + return result; +} + void ObjLoader::addOutputMaterialsAndFrames( MeshBuilderData* output, const tinyobj::attrib_t& attrib, const std::vector& shapes, - const std::vector& materials, const u16& framesCount) { + const std::vector& materials, const u16& framesCount, + std::vector& materialVertexCounts) { if (attrib.texcoords.size()) output->textureCoordsEnabled = true; if (attrib.normals.size()) output->normalsEnabled = true; @@ -129,6 +156,17 @@ void ObjLoader::addOutputMaterialsAndFrames( for (size_t j = 0; j < framesCount; j++) { auto* frame = new MeshBuilderMaterialFrameData(); + + const auto& counter = materialVertexCounts[i]; + + frame->count = counter.count; + frame->vertices = new Vec4[counter.count]; + + if (output->textureCoordsEnabled) + frame->textureCoords = new Vec4[counter.count]; + + if (output->normalsEnabled) frame->normals = new Vec4[counter.count]; + material->frames.push_back(frame); } @@ -136,50 +174,6 @@ void ObjLoader::addOutputMaterialsAndFrames( } } -void ObjLoader::scan(MeshBuilderData* output, const tinyobj::attrib_t& attrib, - const std::vector& shapes, - const std::vector& materials, - const u16& frameIndex) { - struct MaterialVertexCount { - size_t materialId; - int count; - }; - - std::vector materialVertexCounts; - for (size_t i = 0; i < materials.size(); i++) { - MaterialVertexCount counter = {i, 0}; - materialVertexCounts.push_back(counter); - } - - for (size_t s = 0; s < shapes.size(); s++) { - const auto& mesh = shapes[s].mesh; - - for (size_t f = 0; f < mesh.num_face_vertices.size(); f++) { - const auto& materialId = mesh.material_ids[f]; - const auto& vertCountPerFace = size_t(mesh.num_face_vertices[f]); - - TYRA_ASSERT(vertCountPerFace == 3, - "TinyObjLoader should triangulate mesh, internal error!"); - - materialVertexCounts[materialId].count += vertCountPerFace; - } - } - - for (size_t i = 0; i < materials.size(); i++) { - const auto& counter = materialVertexCounts[i]; - - auto* outFrame = output->materials[i]->frames[frameIndex]; - - outFrame->count = counter.count; - outFrame->vertices = new Vec4[counter.count]; - - if (output->textureCoordsEnabled) - outFrame->textureCoords = new Vec4[counter.count]; - - if (output->normalsEnabled) outFrame->normals = new Vec4[counter.count]; - } -} - void ObjLoader::importFrame(MeshBuilderData* output, const tinyobj::attrib_t& attrib, const std::vector& shapes, diff --git a/engine/src/renderer/3d/mesh/mesh.cpp b/engine/src/renderer/3d/mesh/mesh.cpp index e9ed82d..74f2410 100644 --- a/engine/src/renderer/3d/mesh/mesh.cpp +++ b/engine/src/renderer/3d/mesh/mesh.cpp @@ -20,7 +20,15 @@ Mesh::Mesh(const MeshBuilderData& data) { "Materials count must be greater than 0"); for (u32 i = 0; i < data.materials.size(); i++) { - materials.push_back(new MeshMaterial(data, i)); + auto* material = new MeshMaterial(data, i); + + if (material->frames.size() == 0) { + TYRA_WARN("Found empty material: ", material->name, ". Skipping..."); + delete material; + continue; + } + + materials.push_back(material); } isMother = true; diff --git a/engine/src/renderer/3d/mesh/mesh_material.cpp b/engine/src/renderer/3d/mesh/mesh_material.cpp index a4d6b75..07c9b10 100644 --- a/engine/src/renderer/3d/mesh/mesh_material.cpp +++ b/engine/src/renderer/3d/mesh/mesh_material.cpp @@ -45,14 +45,22 @@ MeshMaterial::MeshMaterial(const MeshBuilderData& data, u32 lastVertexCount = 0; for (u32 i = 0; i < material->frames.size(); i++) { - frames.push_back(new MeshMaterialFrame(data, i, materialIndex)); + if (material->frames[i]->count > 0) { + frames.push_back(new MeshMaterialFrame(data, i, materialIndex)); - if (i > 0) { - TYRA_ASSERT(frames[i]->count == lastVertexCount, - "Vertex count must be the same for all frames"); + if (i > 0) { + TYRA_ASSERT(frames[i]->count == lastVertexCount, + "Vertex count must be the same for all frames"); + } + + lastVertexCount = frames[i]->count; + } else { // We will not use it, lets clean it up + auto* frame = material->frames[i]; + if (frame->vertices != nullptr) delete[] frame->vertices; + if (frame->normals != nullptr) delete[] frame->normals; + if (frame->textureCoords != nullptr) delete[] frame->textureCoords; + if (frame->colors != nullptr) delete[] frame->colors; } - - lastVertexCount = frames[i]->count; } isMother = true; diff --git a/engine/src/renderer/3d/mesh/mesh_material_frame.cpp b/engine/src/renderer/3d/mesh/mesh_material_frame.cpp index 4326df5..07519f6 100644 --- a/engine/src/renderer/3d/mesh/mesh_material_frame.cpp +++ b/engine/src/renderer/3d/mesh/mesh_material_frame.cpp @@ -21,17 +21,20 @@ namespace Tyra { MeshMaterialFrame::MeshMaterialFrame(const MeshBuilderData& data, const u32& frameIndex, const u32& materialIndex) { + auto* material = data.materials[materialIndex]; + TYRA_ASSERT(materialIndex < data.materials.size(), "Provided index \"", materialIndex, "\" is out of range"); - TYRA_ASSERT(frameIndex < data.materials[materialIndex]->frames.size(), - "Provided index \"", frameIndex, "\" is out of range"); + TYRA_ASSERT(frameIndex < material->frames.size(), "Provided index \"", + frameIndex, "\" is out of range"); id = rand() % 1000000; - auto* frame = data.materials[materialIndex]->frames[frameIndex]; + auto* frame = material->frames[frameIndex]; - TYRA_ASSERT(frame->count > 0, "Vertex count must be greater than 0"); + TYRA_ASSERT(frame->count > 0, "Vertex count must be greater than 0", + "Material name: ", material->name); TYRA_ASSERT(frame->vertices != nullptr, "Vertex array can't be null"); TYRA_ASSERT(!data.normalsEnabled || frame->normals != nullptr, "Normal array can't be null");