From e359bcbe2b32d53de7f9948266bb4732ea5a7ee9 Mon Sep 17 00:00:00 2001 From: h4570 Date: Mon, 29 Aug 2022 19:00:47 +0200 Subject: [PATCH] patch 1 --- demo/src/states/game/enemy/enemy_manager.cpp | 2 +- demo/src/states/game/player/weapon.cpp | 2 +- demo/src/states/game/skybox/skybox.cpp | 2 +- demo/src/states/game/terrain/terrain.cpp | 2 +- engine/inc/file/file_utils.hpp | 5 ++ .../loaders/3d/builder/mesh_builder_data.hpp | 2 +- .../3d/builder/mesh_builder_material_data.hpp | 2 + .../inc/loaders/3d/md2_loader/md2_loader.hpp | 3 +- .../inc/loaders/3d/obj_loader/obj_loader.hpp | 4 +- engine/inc/loaders/loader.hpp | 25 -------- .../loaders/texture/base/texture_loader.hpp | 3 +- engine/inc/renderer/3d/mesh/mesh_material.hpp | 5 +- .../pipeline/dynamic/core/dynpip_renderer.hpp | 3 +- .../3d/pipeline/dynamic/dynamic_pipeline.hpp | 2 +- engine/src/file/file_utils.cpp | 28 +++++++++ .../loaders/3d/builder/mesh_builder_data.cpp | 5 +- .../src/loaders/3d/md2_loader/md2_loader.cpp | 13 ++-- .../src/loaders/3d/obj_loader/obj_loader.cpp | 60 +++++++++++++------ engine/src/loaders/loader.cpp | 42 ------------- engine/src/loaders/texture/png_loader.cpp | 3 +- engine/src/renderer/3d/mesh/mesh_material.cpp | 23 +++++-- .../renderer/3d/mesh/mesh_material_frame.cpp | 15 ++--- .../pipeline/dynamic/core/dynpip_renderer.cpp | 8 +-- .../3d/pipeline/dynamic/dynamic_pipeline.cpp | 40 +++++++++---- .../3d/pipeline/static/static_pipeline.cpp | 4 +- .../core/texture/texture_repository.cpp | 6 +- tutorials/04-de_dust2/src/tutorial_04.cpp | 7 ++- tutorials/05-animation/src/tutorial_05.cpp | 2 + tutorials/07-lighting/src/tutorial_07.cpp | 9 +-- tutorials/08-skybox-debug/src/tutorial_08.cpp | 1 - 30 files changed, 175 insertions(+), 153 deletions(-) delete mode 100644 engine/inc/loaders/loader.hpp delete mode 100644 engine/src/loaders/loader.cpp diff --git a/demo/src/states/game/enemy/enemy_manager.cpp b/demo/src/states/game/enemy/enemy_manager.cpp index 7701beab..91d82973 100644 --- a/demo/src/states/game/enemy/enemy_manager.cpp +++ b/demo/src/states/game/enemy/enemy_manager.cpp @@ -30,7 +30,7 @@ EnemyManager::EnemyManager(Engine* engine, const Heightmap& heightmap) { auto data = loader.load(FileUtils::fromCwd("game/models/zombie/zombie.obj"), objOptions); - data->normalsEnabled = false; + data->loadNormals = false; motherMesh = new DynamicMesh(data.get()); bodyTexture = textureRepo->add( diff --git a/demo/src/states/game/player/weapon.cpp b/demo/src/states/game/player/weapon.cpp index c3144e6d..e5cc0270 100644 --- a/demo/src/states/game/player/weapon.cpp +++ b/demo/src/states/game/player/weapon.cpp @@ -28,7 +28,7 @@ Weapon::Weapon(Engine* engine) { auto* repo = &engine->renderer.core.texture.repository; auto data = loader.load(FileUtils::fromCwd("game/models/ak47/ak47.obj"), objOptions); - data->normalsEnabled = false; + data->loadNormals = false; mesh = new StaticMesh(data.get()); mesh->translation.translateX(2.85F); diff --git a/demo/src/states/game/skybox/skybox.cpp b/demo/src/states/game/skybox/skybox.cpp index a59acc47..8e369f6a 100644 --- a/demo/src/states/game/skybox/skybox.cpp +++ b/demo/src/states/game/skybox/skybox.cpp @@ -25,7 +25,7 @@ Skybox::Skybox(TextureRepository* repo) { auto data = loader.load(FileUtils::fromCwd("game/models/skybox/skybox.obj"), objOptions); - data->normalsEnabled = false; + data->loadNormals = false; mesh = new StaticMesh(data.get()); repo->addByMesh(mesh, FileUtils::fromCwd("game/models/skybox/"), "png"); diff --git a/demo/src/states/game/terrain/terrain.cpp b/demo/src/states/game/terrain/terrain.cpp index 6848bfc2..ab743869 100644 --- a/demo/src/states/game/terrain/terrain.cpp +++ b/demo/src/states/game/terrain/terrain.cpp @@ -29,7 +29,7 @@ Terrain::Terrain(TextureRepository* repo) auto data = loader.load(FileUtils::fromCwd("game/models/terrain/terrain.obj"), objOptions); - data->normalsEnabled = false; + data->loadNormals = false; mesh = new StaticMesh(data.get()); repo->addByMesh(mesh, FileUtils::fromCwd("game/models/terrain/"), "png"); diff --git a/engine/inc/file/file_utils.hpp b/engine/inc/file/file_utils.hpp index 7d66d75d..dd5507d5 100644 --- a/engine/inc/file/file_utils.hpp +++ b/engine/inc/file/file_utils.hpp @@ -32,6 +32,11 @@ class FileUtils { static std::string fromCwd(const std::string& relativePath); static std::string fromCwd(const char* relativePath); + static std::string getFilenameFromPath(const std::string& path); + static std::string getPathFromFilename(const std::string& path); + static std::string getFilenameWithoutExtension(const std::string& filename); + static std::string getExtensionOfFilename(const std::string& filename); + const char* getElfName() const { return elfName; }; const char* getElfPath() const { return elfPath; }; diff --git a/engine/inc/loaders/3d/builder/mesh_builder_data.hpp b/engine/inc/loaders/3d/builder/mesh_builder_data.hpp index 0affd4af..1ef56366 100644 --- a/engine/inc/loaders/3d/builder/mesh_builder_data.hpp +++ b/engine/inc/loaders/3d/builder/mesh_builder_data.hpp @@ -28,7 +28,7 @@ class MeshBuilderData { std::vector materials; - bool textureCoordsEnabled, normalsEnabled, lightMapEnabled; + bool loadNormals, loadLightmap; }; } // namespace Tyra diff --git a/engine/inc/loaders/3d/builder/mesh_builder_material_data.hpp b/engine/inc/loaders/3d/builder/mesh_builder_material_data.hpp index ecde268c..78b417be 100644 --- a/engine/inc/loaders/3d/builder/mesh_builder_material_data.hpp +++ b/engine/inc/loaders/3d/builder/mesh_builder_material_data.hpp @@ -13,6 +13,7 @@ #include #include +#include #include "./mesh_builder_material_frame_data.hpp" #include "renderer/models/color.hpp" @@ -25,6 +26,7 @@ class MeshBuilderMaterialData { std::vector frames; std::string name; + std::optional texturePath; Color ambient; }; diff --git a/engine/inc/loaders/3d/md2_loader/md2_loader.hpp b/engine/inc/loaders/3d/md2_loader/md2_loader.hpp index da6d9a40..95b5af02 100644 --- a/engine/inc/loaders/3d/md2_loader/md2_loader.hpp +++ b/engine/inc/loaders/3d/md2_loader/md2_loader.hpp @@ -10,7 +10,6 @@ #pragma once -#include "../../loader.hpp" #include "../builder/mesh_builder_data.hpp" #include #include @@ -23,7 +22,7 @@ struct MD2LoaderOptions { }; /** Class responsible for loading & parsing Quake's II ".md2" 3D files */ -class MD2Loader : public Loader { +class MD2Loader { public: static std::unique_ptr load(const char* fullpath); static std::unique_ptr load(const char* fullpath, diff --git a/engine/inc/loaders/3d/obj_loader/obj_loader.hpp b/engine/inc/loaders/3d/obj_loader/obj_loader.hpp index 6282f916..3c37d320 100644 --- a/engine/inc/loaders/3d/obj_loader/obj_loader.hpp +++ b/engine/inc/loaders/3d/obj_loader/obj_loader.hpp @@ -10,12 +10,12 @@ #pragma once -#include "../../loader.hpp" #include "../builder/mesh_builder_data.hpp" #include #include "renderer/models/color.hpp" #include "loaders/3d/obj_loader/tiny_obj_loader.hpp" #include +#include namespace Tyra { @@ -36,7 +36,7 @@ struct MaterialVertexCount { }; /** Class responsible for loading & parsing obj files */ -class ObjLoader : public Loader { +class ObjLoader { public: static std::unique_ptr load(const char* fullpath); static std::unique_ptr load(const char* fullpath, diff --git a/engine/inc/loaders/loader.hpp b/engine/inc/loaders/loader.hpp deleted file mode 100644 index 5aac03bd..00000000 --- a/engine/inc/loaders/loader.hpp +++ /dev/null @@ -1,25 +0,0 @@ -/* -# _____ ____ ___ -# | \/ ____| |___| -# | | | \ | | -#----------------------------------------------------------------------- -# Copyright 2022, tyra - https://github.com/h4570/tyra -# Licensed under Apache License 2.0 -# Sandro Sobczyński -*/ - -#pragma once - -#include - -namespace Tyra { - -class Loader { - protected: - static std::string getFilenameFromPath(const std::string& path); - static std::string getPathFromFilename(const std::string& path); - static std::string getFilenameWithoutExtension(const std::string& filename); - static std::string getExtensionOfFilename(const std::string& filename); -}; - -} // namespace Tyra diff --git a/engine/inc/loaders/texture/base/texture_loader.hpp b/engine/inc/loaders/texture/base/texture_loader.hpp index bb52d4a3..ba766216 100644 --- a/engine/inc/loaders/texture/base/texture_loader.hpp +++ b/engine/inc/loaders/texture/base/texture_loader.hpp @@ -10,13 +10,12 @@ #pragma once -#include "loaders/loader.hpp" #include "loaders/texture/builder/texture_builder_data.hpp" #include "renderer/core/texture/models/texture_bpp.hpp" #include namespace Tyra { -class TextureLoader : public Loader { +class TextureLoader { public: /** * @brief Loads texture data from file. diff --git a/engine/inc/renderer/3d/mesh/mesh_material.hpp b/engine/inc/renderer/3d/mesh/mesh_material.hpp index 2d8b5e8f..fce96949 100644 --- a/engine/inc/renderer/3d/mesh/mesh_material.hpp +++ b/engine/inc/renderer/3d/mesh/mesh_material.hpp @@ -13,6 +13,7 @@ #include "debug/debug.hpp" #include "./mesh_material_frame.hpp" #include "loaders/3d/builder/mesh_builder_data.hpp" +#include namespace Tyra { @@ -23,11 +24,9 @@ class MeshMaterial { ~MeshMaterial(); bool isMother, lightmapFlag; - u32 id; - std::string name; - + std::optional textureName; Color ambient; std::vector frames; diff --git a/engine/inc/renderer/3d/pipeline/dynamic/core/dynpip_renderer.hpp b/engine/inc/renderer/3d/pipeline/dynamic/core/dynpip_renderer.hpp index 31a8fc72..b7fefcad 100644 --- a/engine/inc/renderer/3d/pipeline/dynamic/core/dynpip_renderer.hpp +++ b/engine/inc/renderer/3d/pipeline/dynamic/core/dynpip_renderer.hpp @@ -44,8 +44,7 @@ class DynPipRenderer { void uploadPrograms(); void setDoubleBuffer(); - void addBufferDataToPacket(DynPipVU1Program* program, DynPipBag** bags, - const u32& count); + void addBufferDataToPacket(DynPipBag** bags, const u32& count); void sendPacket(); prim_t* prim; diff --git a/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp b/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp index 9fd03bd2..751f9987 100644 --- a/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp +++ b/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp @@ -59,7 +59,7 @@ class DynamicPipeline : public Renderer3DPipeline { void setBuffer(DynPipBag* buffers, DynPipBag* buffer, u16* bufferIndex); - void sendRestOfBuffers(DynPipBag* buffers, u16* bufferIndex); + void sendRestOfBuffers(DynPipBag* buffers, const u16& bufferIndex); void addVertices(const MeshMaterialFrame* materialFrameFrom, const MeshMaterialFrame* materialFrameTo, DynPipBag* bag, diff --git a/engine/src/file/file_utils.cpp b/engine/src/file/file_utils.cpp index e4e30a8b..7277baf2 100644 --- a/engine/src/file/file_utils.cpp +++ b/engine/src/file/file_utils.cpp @@ -64,4 +64,32 @@ std::string FileUtils::fromCwd(const char* file) { auto cwd = getCwd(); return cwd + file; } + +std::string FileUtils::getFilenameFromPath(const std::string& path) { + std::string filename = path.substr(path.find_last_of("/\\") + 1); + if (filename.size() == path.size()) { + filename = path.substr(path.find_last_of(":\\") + 1); + } + return filename; +} + +std::string FileUtils::getPathFromFilename(const std::string& path) { + std::string basepath = path.substr(0, path.find_last_of("/\\")); + if (basepath.size() == path.size()) { + basepath = path.substr(0, path.find_last_of(":\\")); + } + return basepath; +} + +std::string FileUtils::getFilenameWithoutExtension( + const std::string& filename) { + auto lastindex = filename.find_last_of("."); + return filename.substr(0, lastindex); +} + +std::string FileUtils::getExtensionOfFilename(const std::string& filename) { + auto lastindex = filename.find_last_of("."); + return filename.substr(lastindex + 1); +} + } // namespace Tyra diff --git a/engine/src/loaders/3d/builder/mesh_builder_data.cpp b/engine/src/loaders/3d/builder/mesh_builder_data.cpp index eb9fb0d1..ff979464 100644 --- a/engine/src/loaders/3d/builder/mesh_builder_data.cpp +++ b/engine/src/loaders/3d/builder/mesh_builder_data.cpp @@ -14,9 +14,8 @@ namespace Tyra { MeshBuilderData::MeshBuilderData() { - textureCoordsEnabled = false; - normalsEnabled = false; - lightMapEnabled = false; + loadNormals = false; + loadLightmap = false; } MeshBuilderData::~MeshBuilderData() { diff --git a/engine/src/loaders/3d/md2_loader/md2_loader.cpp b/engine/src/loaders/3d/md2_loader/md2_loader.cpp index 73093794..3ff4adfb 100644 --- a/engine/src/loaders/3d/md2_loader/md2_loader.cpp +++ b/engine/src/loaders/3d/md2_loader/md2_loader.cpp @@ -13,7 +13,7 @@ #include #include "debug/debug.hpp" #include "loaders/3d/md2_loader/anorms.hpp" -#include "loaders/loader.hpp" +#include "file/file_utils.hpp" namespace Tyra { @@ -88,7 +88,7 @@ std::unique_ptr MD2Loader::load(const char* fullpath, std::string path = fullpath; TYRA_ASSERT(!path.empty(), "Provided path is empty!"); - auto filename = getFilenameFromPath(path); + auto filename = FileUtils::getFilenameFromPath(path); FILE* file = fopen(fullpath, "rb"); TYRA_ASSERT(file != nullptr, "Failed to load: ", filename); @@ -122,12 +122,13 @@ std::unique_ptr MD2Loader::load(const char* fullpath, auto result = std::make_unique(); auto* material = new MeshBuilderMaterialData(); - material->name = getFilenameWithoutExtension(filename); + material->name = FileUtils::getFilenameWithoutExtension(filename); + material->texturePath = material->name; + material->texturePath.value().append(".png"); result->materials.push_back(material); - result->normalsEnabled = true; - result->textureCoordsEnabled = true; - result->lightMapEnabled = false; + result->loadNormals = true; + result->loadLightmap = false; Vec4** tempVertices = new Vec4*[framesCount]; Vec4** tempNormals = new Vec4*[framesCount]; diff --git a/engine/src/loaders/3d/obj_loader/obj_loader.cpp b/engine/src/loaders/3d/obj_loader/obj_loader.cpp index dd7e8907..be8109f8 100644 --- a/engine/src/loaders/3d/obj_loader/obj_loader.cpp +++ b/engine/src/loaders/3d/obj_loader/obj_loader.cpp @@ -10,13 +10,13 @@ #include #include -#include #include #include "math/vec2.hpp" #include "math/vec4.hpp" #include "renderer/models/color.hpp" #include "debug/debug.hpp" #include "loaders/3d/obj_loader/obj_loader.hpp" +#include "file/file_utils.hpp" #define TINYOBJLOADER_USE_MAPBOX_EARCUT #define TINYOBJLOADER_IMPLEMENTATION @@ -40,12 +40,12 @@ std::unique_ptr ObjLoader::load( std::unique_ptr ObjLoader::load( const char* fullpath, const ObjLoaderOptions& options) { std::string path = fullpath; - std::string basePath = getPathFromFilename(path); + std::string basePath = FileUtils::getPathFromFilename(path); TYRA_ASSERT(!path.empty(), "Provided path is empty!"); - auto rawFilename = getFilenameWithoutExtension(path); - auto extension = getExtensionOfFilename(path); + auto rawFilename = FileUtils::getFilenameWithoutExtension(path); + auto extension = FileUtils::getExtensionOfFilename(path); auto result = std::make_unique(); tinyobj::ObjReaderConfig readerConfig; @@ -131,9 +131,7 @@ void ObjLoader::addOutputMaterialsAndFrames( const std::vector& shapes, const std::vector& materials, const u16& framesCount, std::vector& materialVertexCounts) { - if (attrib.texcoords.size()) output->textureCoordsEnabled = true; - - if (attrib.normals.size()) output->normalsEnabled = true; + if (attrib.normals.size()) output->loadNormals = true; TYRA_ASSERT(materials.size() > 0, "No material data found! Please add .mtl " @@ -145,6 +143,10 @@ void ObjLoader::addOutputMaterialsAndFrames( material->name = materials[i].name; + if (!materials[i].diffuse_texname.empty()) { + material->texturePath = materials[i].diffuse_texname; + } + material->ambient.set(materials[i].diffuse[0] * 128.0F, materials[i].diffuse[1] * 128.0F, materials[i].diffuse[2] * 128.0F, 128.0F); @@ -157,10 +159,11 @@ void ObjLoader::addOutputMaterialsAndFrames( frame->count = counter.count; frame->vertices = new Vec4[counter.count]; - if (output->textureCoordsEnabled) + if (material->texturePath.has_value()) { frame->textureCoords = new Vec4[counter.count]; + } - if (output->normalsEnabled) frame->normals = new Vec4[counter.count]; + if (output->loadNormals) frame->normals = new Vec4[counter.count]; material->frames.push_back(frame); } @@ -186,6 +189,8 @@ void ObjLoader::importFrame(MeshBuilderData* output, materialInsertControls.push_back(control); } + std::vector materialIdsWithTextureWarning; + // Loop over shapes for (size_t s = 0; s < shapes.size(); s++) { const auto& mesh = shapes[s].mesh; @@ -197,7 +202,8 @@ void ObjLoader::importFrame(MeshBuilderData* output, auto& materialInsertControl = materialInsertControls[materialId]; size_t vertCountPerFace = size_t(mesh.num_face_vertices[f]); - auto* outFrame = output->materials[materialId]->frames[frameIndex]; + auto* outMaterial = output->materials[materialId]; + auto* outFrame = outMaterial->frames[frameIndex]; TYRA_ASSERT(count == 1 || vertCountPerFace == 3, "Please triangulate obj files if you are animating!", @@ -232,14 +238,32 @@ void ObjLoader::importFrame(MeshBuilderData* output, // Check if `texcoord_index` is zero or positive. negative = // notexcoord data if (idx.texcoord_index >= 0) { - tinyobj::real_t tx = - attrib.texcoords[2 * size_t(idx.texcoord_index) + 0]; - tinyobj::real_t ty = - attrib.texcoords[2 * size_t(idx.texcoord_index) + 1]; - - auto finalY = invertY ? 1.0F - ty : ty; - outFrame->textureCoords[materialInsertControl.inserted].set( - tx, finalY, 1.0F, 0.0F); + if (outMaterial->texturePath.has_value()) { + tinyobj::real_t tx = + attrib.texcoords[2 * size_t(idx.texcoord_index) + 0]; + tinyobj::real_t ty = + attrib.texcoords[2 * size_t(idx.texcoord_index) + 1]; + + auto finalY = invertY ? 1.0F - ty : ty; + outFrame->textureCoords[materialInsertControl.inserted].set( + tx, finalY, 1.0F, 0.0F); + } else { + auto warningWasNotPrinted = + std::find(materialIdsWithTextureWarning.begin(), + materialIdsWithTextureWarning.end(), + materialId) == materialIdsWithTextureWarning.end(); + + if (frameIndex == 0 && warningWasNotPrinted) { + materialIdsWithTextureWarning.push_back(materialId); + + TYRA_WARN( + "Material \"", outMaterial->name, + "\" has texture coordinates, but texture path was not found " + "in .mtl file! ", + "Please consider adding texture path to map_Kd field in .mtl " + "file!"); + } + } } materialInsertControl.inserted++; diff --git a/engine/src/loaders/loader.cpp b/engine/src/loaders/loader.cpp deleted file mode 100644 index e63bf553..00000000 --- a/engine/src/loaders/loader.cpp +++ /dev/null @@ -1,42 +0,0 @@ - -/* -# _____ ____ ___ -# | \/ ____| |___| -# | | | \ | | -#----------------------------------------------------------------------- -# Copyright 2022, tyra - https://github.com/h4570/tyra -# Licensed under Apache License 2.0 -# Sandro Sobczyński -*/ - -#include "loaders/loader.hpp" - -namespace Tyra { - -std::string Loader::getFilenameFromPath(const std::string& path) { - std::string filename = path.substr(path.find_last_of("/\\") + 1); - if (filename.size() == path.size()) { - filename = path.substr(path.find_last_of(":\\") + 1); - } - return filename; -} - -std::string Loader::getPathFromFilename(const std::string& path) { - std::string basepath = path.substr(0, path.find_last_of("/\\")); - if (basepath.size() == path.size()) { - basepath = path.substr(0, path.find_last_of(":\\")); - } - return basepath; -} - -std::string Loader::getFilenameWithoutExtension(const std::string& filename) { - auto lastindex = filename.find_last_of("."); - return filename.substr(0, lastindex); -} - -std::string Loader::getExtensionOfFilename(const std::string& filename) { - auto lastindex = filename.find_last_of("."); - return filename.substr(lastindex + 1); -} - -} // namespace Tyra diff --git a/engine/src/loaders/texture/png_loader.cpp b/engine/src/loaders/texture/png_loader.cpp index f0551d9b..b1b2e6a0 100644 --- a/engine/src/loaders/texture/png_loader.cpp +++ b/engine/src/loaders/texture/png_loader.cpp @@ -16,6 +16,7 @@ #include #include #include "loaders/texture/png_loader.hpp" +#include "file/file_utils.hpp" namespace Tyra { @@ -32,7 +33,7 @@ TextureBuilderData* PngLoader::load(const char* fullPath) { std::string path = fullPath; TYRA_ASSERT(!path.empty(), "Provided path is empty!"); - auto filename = getFilenameFromPath(path); + auto filename = FileUtils::getFilenameFromPath(path); FILE* file = fopen(fullPath, "rb"); TYRA_ASSERT(file != nullptr, "Failed to load ", fullPath); diff --git a/engine/src/renderer/3d/mesh/mesh_material.cpp b/engine/src/renderer/3d/mesh/mesh_material.cpp index 79d83ed2..cd58fc4c 100644 --- a/engine/src/renderer/3d/mesh/mesh_material.cpp +++ b/engine/src/renderer/3d/mesh/mesh_material.cpp @@ -14,6 +14,7 @@ #include #include #include "renderer/3d/mesh/mesh_material.hpp" +#include "file/file_utils.hpp" namespace Tyra { @@ -29,7 +30,7 @@ MeshMaterial::MeshMaterial(const MeshBuilderData& data, id = rand() % 1000000; - if (data.lightMapEnabled) { + if (data.loadLightmap) { lightmapFlag = true; TYRA_ASSERT(material->frames[0]->colors != nullptr, "Colors faces are required"); @@ -38,8 +39,15 @@ MeshMaterial::MeshMaterial(const MeshBuilderData& data, } ambient.set(material->ambient); - name = material->name; + + if (material->texturePath.has_value()) { + auto textureFilename = + FileUtils::getFilenameFromPath(material->texturePath.value()); + + textureName = FileUtils::getFilenameWithoutExtension(textureFilename); + } + TYRA_ASSERT(name.length() > 0, "MeshMaterial name cannot be empty"); u32 lastVertexCount = 0; @@ -71,7 +79,7 @@ MeshMaterial::MeshMaterial(const MeshMaterial& mesh) { lightmapFlag = mesh.lightmapFlag; name = mesh.name; - + textureName = mesh.textureName; ambient.set(128.0F, 128.0F, 128.0F, 128.0F); for (u32 i = 0; i < mesh.frames.size(); i++) { @@ -112,9 +120,14 @@ std::string MeshMaterial::getPrint(const char* name) const { res << std::endl; res << std::fixed << std::setprecision(2); res << "Id: " << id << ", " << std::endl; - res << "Name: " << name << ", " << std::endl; + res << "Name: " << this->name << ", " << std::endl; + + if (textureName.has_value()) { + res << "Texture path: " << textureName.value() << ", " << std::endl; + } + res << "Frames count: " << frames.size() << ", " << std::endl; - res << "Single color?: " << static_cast(lightmapFlag) << std::endl; + res << "Lightmap?: " << static_cast(lightmapFlag) << std::endl; res << ")"; return res.str(); diff --git a/engine/src/renderer/3d/mesh/mesh_material_frame.cpp b/engine/src/renderer/3d/mesh/mesh_material_frame.cpp index 9ec0a8c2..8ed67e27 100644 --- a/engine/src/renderer/3d/mesh/mesh_material_frame.cpp +++ b/engine/src/renderer/3d/mesh/mesh_material_frame.cpp @@ -36,11 +36,12 @@ MeshMaterialFrame::MeshMaterialFrame(const MeshBuilderData& data, 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, + TYRA_ASSERT(!data.loadNormals || frame->normals != nullptr, "Normal array can't be null"); - TYRA_ASSERT(!data.textureCoordsEnabled || frame->textureCoords != nullptr, - "Texture coordinate array can't be null"); - TYRA_ASSERT(!data.lightMapEnabled || frame->colors != nullptr, + TYRA_ASSERT( + !material->texturePath.has_value() || frame->textureCoords != nullptr, + "Texture coordinate array can't be null"); + TYRA_ASSERT(!data.loadLightmap || frame->colors != nullptr, "Color array can't be null"); bbox = new BBox(frame->vertices, frame->count); @@ -48,7 +49,7 @@ MeshMaterialFrame::MeshMaterialFrame(const MeshBuilderData& data, count = frame->count; vertices = frame->vertices; - if (data.normalsEnabled) { + if (data.loadNormals) { normals = frame->normals; } else { if (frame->normals != nullptr) delete[] frame->normals; @@ -56,7 +57,7 @@ MeshMaterialFrame::MeshMaterialFrame(const MeshBuilderData& data, normals = nullptr; } - if (data.textureCoordsEnabled) { + if (material->texturePath.has_value()) { textureCoords = frame->textureCoords; } else { if (frame->textureCoords != nullptr) delete[] frame->textureCoords; @@ -64,7 +65,7 @@ MeshMaterialFrame::MeshMaterialFrame(const MeshBuilderData& data, textureCoords = nullptr; } - if (data.lightMapEnabled) { + if (data.loadLightmap) { colors = frame->colors; } else { if (frame->colors != nullptr) delete[] frame->colors; diff --git a/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_renderer.cpp b/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_renderer.cpp index 17c1beda..fef2f6f3 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_renderer.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_renderer.cpp @@ -160,19 +160,19 @@ void DynPipRenderer::sendObjectData( void DynPipRenderer::render(DynPipBag** bags, const u32& count) { if (count <= 0) return; - auto* program = programsRepo->getProgramByBag(bags[0]); - addBufferDataToPacket(program, bags, count); + addBufferDataToPacket(bags, count); sendPacket(); } -void DynPipRenderer::addBufferDataToPacket(DynPipVU1Program* program, - DynPipBag** bags, const u32& count) { +void DynPipRenderer::addBufferDataToPacket(DynPipBag** bags, const u32& count) { currentPacket = packets[context]; packet2_reset(currentPacket, false); for (u32 i = 0; i < count; i++) { if (bags[i]->count <= 0) continue; + auto* program = programsRepo->getProgramByBag(bags[i]); + program->addBufferDataToPacket(currentPacket, bags[i], prim); if (lastProgramName != program->getName()) { diff --git a/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp b/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp index 35983d06..806d4c9c 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp @@ -35,6 +35,11 @@ void DynamicPipeline::onUse() { buffers = new DynPipBag[buffersCount]; + for (u32 i = 0; i < buffersCount; i++) { + buffers[i].texture = nullptr; + buffers[i].lighting = nullptr; + } + auto packetSize = buffersCount * 5.1F; // 5.1 = packet2_get_qw_count / buffersCount @@ -96,11 +101,12 @@ void DynamicPipeline::render(const DynamicMesh* mesh, for (u32 i = 0; i < mesh->materials.size(); i++) { auto* material = mesh->materials[i]; + auto* frameFrom = material->frames[mesh->animation.getState().currentFrame]; auto* frameTo = material->frames[mesh->animation.getState().nextFrame]; auto partSize = core.getMaxVertCountByParams( - options && options->lighting, material->frames[0]->textureCoords); + options && options->lighting, material->textureName.has_value()); u32 partsCount = ceil(frameFrom->count / static_cast(partSize)); @@ -109,13 +115,17 @@ void DynamicPipeline::render(const DynamicMesh* mesh, setBuffersColorBag(buffers, colorBag); u8 isPartInitialized = false; - auto* texture = - rendererCore->texture.repository.getByMeshMaterialId(material->id); + Texture* texture = nullptr; - TYRA_ASSERT(texture, "Texture for material: ", material->name, - "Id: ", material->id, - "Was not found in texture repository! Did you forget to add " - "texture or disable texture coords loading in mesh?"); + if (material->textureName.has_value()) { + texture = + rendererCore->texture.repository.getByMeshMaterialId(material->id); + + TYRA_ASSERT(texture, "Texture for material: ", material->name, + "Id: ", material->id, + "Was not found in texture repository! Did you forget to add " + "texture or disable texture coords loading in mesh?"); + } for (u32 k = 0; k < partsCount; k++) { auto& buffer = buffers[bufferIndex]; @@ -127,6 +137,7 @@ void DynamicPipeline::render(const DynamicMesh* mesh, u32 startIndex = k * partSize; addVertices(frameFrom, frameTo, &buffer, startIndex); + buffer.texture = getTextureBag(texture, frameFrom, frameTo, startIndex); buffer.lighting = getLightingBag(frameFrom, frameTo, &model, options, dirLights, startIndex); @@ -139,11 +150,13 @@ void DynamicPipeline::render(const DynamicMesh* mesh, setBuffer(buffers, &buffer, &bufferIndex); } + sendRestOfBuffers(buffers, bufferIndex); + bufferIndex = 0; + core.begin(infoBag); + delete colorBag; } - sendRestOfBuffers(buffers, &bufferIndex); - if (dirLights) { delete dirLights; } @@ -177,11 +190,12 @@ void DynamicPipeline::setBuffer(DynPipBag* buffers, DynPipBag* buffer, *bufferIndex += 1; } -void DynamicPipeline::sendRestOfBuffers(DynPipBag* buffers, u16* bufferIndex) { - auto isEndOf1stDBuffer = *bufferIndex <= halfBuffersCount - 1; +void DynamicPipeline::sendRestOfBuffers(DynPipBag* buffers, + const u16& bufferIndex) { + auto isEndOf1stDBuffer = bufferIndex <= halfBuffersCount - 1; u32 offset = isEndOf1stDBuffer ? 0 : halfBuffersCount; - u32 size = *bufferIndex - offset; + u32 size = bufferIndex - offset; if (size <= 0) return; @@ -258,7 +272,7 @@ DynPipColorBag* DynamicPipeline::getColorBag( DynPipTextureBag* DynamicPipeline::getTextureBag( Texture* texture, const MeshMaterialFrame* materialFrameFrom, const MeshMaterialFrame* materialFrameTo, const u32& startIndex) { - if (!materialFrameFrom->textureCoords) return nullptr; + if (!materialFrameFrom->textureCoords || texture == nullptr) return nullptr; auto* result = new DynPipTextureBag(); diff --git a/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp b/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp index 9c2e127f..3d7d3193 100644 --- a/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp +++ b/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp @@ -65,6 +65,7 @@ void StaticPipeline::render(const StaticMesh* mesh, !(options->frustumCulling != PipelineFrustumCulling_Precise && infoBag->fullClipChecks == true), "Full clip checks are only supported with frustum culling == Precise!"); + TYRA_ASSERT(options->transformationType == TyraMVP || (!options->fullClipChecks && options->frustumCulling == PipelineFrustumCulling_None), @@ -146,7 +147,8 @@ StaPipColorBag* StaticPipeline::getColorBag( StaPipTextureBag* StaticPipeline::getTextureBag( const MeshMaterial* material, const MeshMaterialFrame* materialFrame) { - if (!materialFrame->textureCoords) return nullptr; + if (!materialFrame->textureCoords || !material->textureName.has_value()) + return nullptr; auto* result = new StaPipTextureBag(); diff --git a/engine/src/renderer/core/texture/texture_repository.cpp b/engine/src/renderer/core/texture/texture_repository.cpp index 4fa47d55..726504d4 100644 --- a/engine/src/renderer/core/texture/texture_repository.cpp +++ b/engine/src/renderer/core/texture/texture_repository.cpp @@ -116,8 +116,12 @@ void TextureRepository::addByMesh(const Mesh* mesh, const char* directory, if (dirFixed.back() != '/' && dirFixed.back() != ':') dirFixed += "/"; for (u32 i = 0; i < mesh->materials.size(); i++) { + if (!mesh->materials[i]->textureName.has_value()) { + continue; + } + std::string fullPath = - dirFixed + mesh->materials[i]->name + "." + extension; + dirFixed + mesh->materials[i]->textureName.value() + "." + extension; auto* data = loader.load(fullPath.c_str()); Texture* texture = new Texture(data); diff --git a/tutorials/04-de_dust2/src/tutorial_04.cpp b/tutorials/04-de_dust2/src/tutorial_04.cpp index a987da22..2f1314c0 100644 --- a/tutorials/04-de_dust2/src/tutorial_04.cpp +++ b/tutorials/04-de_dust2/src/tutorial_04.cpp @@ -51,7 +51,7 @@ void Tutorial04::loadMesh() { /** * Load mesh data - * Texture names are the material names "usemtl " + * Texture file names are loaded from .mtl file (map_Kd field). */ auto data = ObjLoader::load(FileUtils::fromCwd("de_dust2/de_dust2.obj"), options); @@ -67,8 +67,9 @@ void Tutorial04::loadMesh() { renderOptions.frustumCulling = Tyra::PipelineFrustumCulling_None; /** - * Function which load all textures into texture repository, - * based on material names. + * Function which load all textures into texture repository. + * It will automatically extract filename from path (map_Kd) and add + * proper extension. */ engine->renderer.getTextureRepository().addByMesh( mesh.get(), FileUtils::fromCwd("de_dust2/"), "png"); diff --git a/tutorials/05-animation/src/tutorial_05.cpp b/tutorials/05-animation/src/tutorial_05.cpp index c5233c54..ddbd56ec 100644 --- a/tutorials/05-animation/src/tutorial_05.cpp +++ b/tutorials/05-animation/src/tutorial_05.cpp @@ -21,6 +21,8 @@ Tutorial05::~Tutorial05() { } void Tutorial05::init() { + engine->renderer.setClearScreenColor(Color(32.0F, 32.0F, 32.0F)); + dynpip.setRenderer(&engine->renderer.core); cameraPosition = Vec4(0.0F, 0.0F, -10.0F); diff --git a/tutorials/07-lighting/src/tutorial_07.cpp b/tutorials/07-lighting/src/tutorial_07.cpp index b9f82be0..dae3701c 100644 --- a/tutorials/07-lighting/src/tutorial_07.cpp +++ b/tutorials/07-lighting/src/tutorial_07.cpp @@ -76,12 +76,9 @@ void Tutorial07::loadMeshWithLightmap() { auto data = ObjLoader::load(FileUtils::fromCwd("cup.obj"), options); /** - * We don't want to load texture coordinates, - * because this obj file has no texture. - * - * Anyways you can use texture as well. + * This model has no texture (it was exported without UV data), + * but you can use lighting with textures as well. */ - data->textureCoordsEnabled = false; /** Lets add lightmap manually */ setLightmap(data.get()); @@ -120,7 +117,7 @@ void Tutorial07::setDirectionalLightsOptions() { void Tutorial07::setLightmap(MeshBuilderData* data) { /** Information for mesh, that data has lightmap */ - data->lightMapEnabled = true; + data->loadLightmap = true; /** This object file has only 1 material */ auto* material = data->materials[0]; diff --git a/tutorials/08-skybox-debug/src/tutorial_08.cpp b/tutorials/08-skybox-debug/src/tutorial_08.cpp index f7d00492..aef56f59 100644 --- a/tutorials/08-skybox-debug/src/tutorial_08.cpp +++ b/tutorials/08-skybox-debug/src/tutorial_08.cpp @@ -92,7 +92,6 @@ void Tutorial08::loadCupMesh() { options.scale = 3.0F; auto data = ObjLoader::load(FileUtils::fromCwd("cup/cup.obj"), options); - data->textureCoordsEnabled = false; cupMesh = std::make_unique(data.get());