diff --git a/ROADMAP.txt b/ROADMAP.txt index 91b185b..5bda416 100644 --- a/ROADMAP.txt +++ b/ROADMAP.txt @@ -22,10 +22,10 @@ because Mesh rendering uses only core.render() ------------ Github issues for Tyra v2 ------------ - [Demo] porzadek z konstruktorami bbox +- [General] smart pointers and std::array instead of raw pointers - [renderer] fog - [General] CI in Github via docker image - [renderer] bbox parts optimization -- [General] smart pointers and std::array instead of raw pointers - [md2] refactor - [2D] Add zbuffer support (z-index) - [3DUtility] Add zbuffer support (z-index) diff --git a/engine/inc/loaders/3d/obj_loader/obj_loader.hpp b/engine/inc/loaders/3d/obj_loader/obj_loader.hpp index 7ae333a..febef5d 100644 --- a/engine/inc/loaders/3d/obj_loader/obj_loader.hpp +++ b/engine/inc/loaders/3d/obj_loader/obj_loader.hpp @@ -15,6 +15,7 @@ #include #include "renderer/models/color.hpp" #include "loaders/3d/obj_loader/tiny_obj_loader.hpp" +#include namespace Tyra { @@ -40,11 +41,12 @@ class ObjLoader : public Loader { ObjLoader(); ~ObjLoader(); - MeshBuilderData* load(const char* fullpath); - MeshBuilderData* load(const char* fullpath, const ObjLoaderOptions& options); - MeshBuilderData* load(const std::string& fullpath); - MeshBuilderData* load(const std::string& fullpath, - const ObjLoaderOptions& options); + std::unique_ptr load(const char* fullpath); + std::unique_ptr load(const char* fullpath, + const ObjLoaderOptions& options); + std::unique_ptr load(const std::string& fullpath); + std::unique_ptr load(const std::string& fullpath, + const ObjLoaderOptions& options); private: void addOutputMaterialsAndFrames( diff --git a/engine/inc/renderer/3d/mesh/dynamic/dynamic_mesh.hpp b/engine/inc/renderer/3d/mesh/dynamic/dynamic_mesh.hpp index 16cf9bf..4fb994d 100644 --- a/engine/inc/renderer/3d/mesh/dynamic/dynamic_mesh.hpp +++ b/engine/inc/renderer/3d/mesh/dynamic/dynamic_mesh.hpp @@ -18,8 +18,8 @@ namespace Tyra { class DynamicMesh : public Mesh { public: - explicit DynamicMesh(const MeshBuilderData& data); - explicit DynamicMesh(const DynamicMesh& mesh); + explicit DynamicMesh(const MeshBuilderData* data); + DynamicMesh(const DynamicMesh& mesh); ~DynamicMesh(); std::vector frames; diff --git a/engine/inc/renderer/3d/mesh/mesh.hpp b/engine/inc/renderer/3d/mesh/mesh.hpp index 7d6b0f1..afb293f 100644 --- a/engine/inc/renderer/3d/mesh/mesh.hpp +++ b/engine/inc/renderer/3d/mesh/mesh.hpp @@ -19,8 +19,8 @@ namespace Tyra { class Mesh { public: - explicit Mesh(const MeshBuilderData& data); - explicit Mesh(const Mesh& mesh); + explicit Mesh(const MeshBuilderData* data); + Mesh(const Mesh& mesh); ~Mesh(); u8 isMother; diff --git a/engine/inc/renderer/3d/mesh/static/static_mesh.hpp b/engine/inc/renderer/3d/mesh/static/static_mesh.hpp index a712b88..d991f29 100644 --- a/engine/inc/renderer/3d/mesh/static/static_mesh.hpp +++ b/engine/inc/renderer/3d/mesh/static/static_mesh.hpp @@ -18,7 +18,7 @@ namespace Tyra { class StaticMesh : public Mesh { public: - StaticMesh(const MeshBuilderData& data); + explicit StaticMesh(const MeshBuilderData* data); StaticMesh(const StaticMesh& mesh); ~StaticMesh(); diff --git a/engine/inc/renderer/core/texture/texture_repository.hpp b/engine/inc/renderer/core/texture/texture_repository.hpp index 09c10fb..519b3cc 100644 --- a/engine/inc/renderer/core/texture/texture_repository.hpp +++ b/engine/inc/renderer/core/texture/texture_repository.hpp @@ -15,6 +15,7 @@ #include #include "./models/texture.hpp" #include "renderer/3d/mesh/mesh.hpp" +#include "renderer/core/2d/sprite/sprite.hpp" #include "loaders/texture/base/texture_loader_selector.hpp" #include @@ -32,11 +33,14 @@ class TextureRepository { /** * Returns single texture. * nullptr if not found. - * @param t_id - * For 3D: MeshMaterial id. - * For 2D: Sprite id. */ - Texture* getBySpriteOrMesh(const u32& t_id) const; + Texture* getBySpriteId(const u32& t_id) const; + + /** + * Returns single texture. + * nullptr if not found. + */ + Texture* getByMeshMaterialId(const u32& t_id) const; /** * Returns single texture. @@ -50,14 +54,6 @@ class TextureRepository { */ const s32 getIndexOf(const u32& t_texId) const; - // ---- - // Setters - // ---- - - // ---- - // Other - // ---- - /** * Add unlinked texture. * @param fullpath Full path to texture file. Example: "host:texture.png" @@ -81,37 +77,38 @@ class TextureRepository { /** * Add linked textures in given path for mesh material names. */ - void addByMesh(Mesh* mesh, const char* directory, const char* extension); + void addByMesh(const Mesh* mesh, const char* directory, + const char* extension); /** * Add linked textures in given path for mesh material names. */ - inline void addByMesh(Mesh* mesh, const std::string& directory, + inline void addByMesh(const Mesh* mesh, const std::string& directory, const char* extension) { addByMesh(mesh, directory.c_str(), extension); } /** * Remove texture from repository. - * Texture is NOT destructed. + * Texture IS destructed. */ - void removeByIndex(const u32& t_index); + void free(const u32& texId); + void free(const Texture* tex); + void free(const Texture& tex); + void freeBySprite(const Sprite& sprite); + void freeByMesh(const Mesh& mesh); + void freeByMesh(const Mesh* mesh); /** * Remove texture from repository. * Texture is NOT destructed. + * Not recommended. */ void removeById(const u32& t_texId); - /** - * Remove texture from repository. - * Texture IS destructed. - */ - void free(const u32& t_texId); - void free(const Texture* t_tex); - void free(const Texture& t_tex); - private: + void removeByIndex(const u32& t_index); + std::vector textures; TextureLoaderSelector texLoaderSelector; }; diff --git a/engine/src/loaders/3d/obj_loader/obj_loader.cpp b/engine/src/loaders/3d/obj_loader/obj_loader.cpp index c2e4ac7..f7f2346 100644 --- a/engine/src/loaders/3d/obj_loader/obj_loader.cpp +++ b/engine/src/loaders/3d/obj_loader/obj_loader.cpp @@ -28,21 +28,21 @@ ObjLoader::ObjLoader() {} ObjLoader::~ObjLoader() {} -MeshBuilderData* ObjLoader::load(const char* fullpath) { +std::unique_ptr ObjLoader::load(const char* fullpath) { return load(fullpath, ObjLoaderOptions()); } -MeshBuilderData* ObjLoader::load(const std::string& fullpath) { +std::unique_ptr ObjLoader::load(const std::string& fullpath) { return load(fullpath.c_str(), ObjLoaderOptions()); } -MeshBuilderData* ObjLoader::load(const std::string& fullpath, - const ObjLoaderOptions& options) { +std::unique_ptr ObjLoader::load( + const std::string& fullpath, const ObjLoaderOptions& options) { return load(fullpath.c_str(), options); } -MeshBuilderData* ObjLoader::load(const char* fullpath, - const ObjLoaderOptions& options) { +std::unique_ptr ObjLoader::load( + const char* fullpath, const ObjLoaderOptions& options) { std::string path = fullpath; std::string basePath = getPathFromFilename(path); @@ -50,8 +50,7 @@ MeshBuilderData* ObjLoader::load(const char* fullpath, auto rawFilename = getFilenameWithoutExtension(path); auto extension = getExtensionOfFilename(path); - - auto* result = new MeshBuilderData(); + auto result = std::make_unique(); tinyobj::ObjReaderConfig readerConfig; readerConfig.triangulate = options.animation.count == 1; @@ -93,11 +92,11 @@ MeshBuilderData* ObjLoader::load(const char* fullpath, if (i == 1) { auto scanResult = scan(shapes, materials); - addOutputMaterialsAndFrames(result, attrib, shapes, materials, + addOutputMaterialsAndFrames(result.get(), attrib, shapes, materials, options.animation.count, scanResult); } - importFrame(result, attrib, shapes, materials, i - 1, options.scale, + importFrame(result.get(), attrib, shapes, materials, i - 1, options.scale, options.flipUVs, options.animation.count); } diff --git a/engine/src/renderer/2d/renderer_2d.cpp b/engine/src/renderer/2d/renderer_2d.cpp index eba4861..c65c946 100644 --- a/engine/src/renderer/2d/renderer_2d.cpp +++ b/engine/src/renderer/2d/renderer_2d.cpp @@ -20,7 +20,7 @@ void Renderer2D::init(RendererCore* t_rendererCore) { core = t_rendererCore; } void Renderer2D::render(const Sprite* sprite) { render(*sprite); } void Renderer2D::render(const Sprite& sprite) { - auto* texture = core->texture.repository.getBySpriteOrMesh(sprite.id); + auto* texture = core->texture.repository.getBySpriteId(sprite.id); TYRA_ASSERT( texture, "Texture for sprite with id: ", sprite.id, diff --git a/engine/src/renderer/3d/mesh/dynamic/dynamic_mesh.cpp b/engine/src/renderer/3d/mesh/dynamic/dynamic_mesh.cpp index 1817d9d..c4a16e1 100644 --- a/engine/src/renderer/3d/mesh/dynamic/dynamic_mesh.cpp +++ b/engine/src/renderer/3d/mesh/dynamic/dynamic_mesh.cpp @@ -15,15 +15,15 @@ namespace Tyra { -DynamicMesh::DynamicMesh(const MeshBuilderData& data) : Mesh(data) { - if (data.materials[0]->frames.size() == 1) { +DynamicMesh::DynamicMesh(const MeshBuilderData* data) : Mesh(data) { + if (data->materials[0]->frames.size() == 1) { TYRA_WARN( "Frames count should be greater than 1 for DynamicMesh! Maybe you " "should use StaticMesh?"); } - for (u32 i = 0; i < data.materials[0]->frames.size(); i++) { - frames.push_back(new MeshFrame(data, i)); + for (u32 i = 0; i < data->materials[0]->frames.size(); i++) { + frames.push_back(new MeshFrame(*data, i)); } animation.resetAll(frames); diff --git a/engine/src/renderer/3d/mesh/mesh.cpp b/engine/src/renderer/3d/mesh/mesh.cpp index 347e295..58c6dec 100644 --- a/engine/src/renderer/3d/mesh/mesh.cpp +++ b/engine/src/renderer/3d/mesh/mesh.cpp @@ -13,14 +13,14 @@ namespace Tyra { -Mesh::Mesh(const MeshBuilderData& data) { +Mesh::Mesh(const MeshBuilderData* data) { init(); - TYRA_ASSERT(data.materials.size() > 0, + TYRA_ASSERT(data->materials.size() > 0, "Materials count must be greater than 0"); - for (u32 i = 0; i < data.materials.size(); i++) { - auto* material = new MeshMaterial(data, i); + for (u32 i = 0; i < data->materials.size(); i++) { + auto* material = new MeshMaterial(*data, i); if (material->frames.size() == 0) { TYRA_WARN("Found empty material: ", material->name, ". Skipping..."); diff --git a/engine/src/renderer/3d/mesh/static/static_mesh.cpp b/engine/src/renderer/3d/mesh/static/static_mesh.cpp index 0194ef1..c465400 100644 --- a/engine/src/renderer/3d/mesh/static/static_mesh.cpp +++ b/engine/src/renderer/3d/mesh/static/static_mesh.cpp @@ -13,12 +13,12 @@ namespace Tyra { -StaticMesh::StaticMesh(const MeshBuilderData& data) : Mesh(data) { - if (data.materials[0]->frames.size() > 1) +StaticMesh::StaticMesh(const MeshBuilderData* data) : Mesh(data) { + if (data->materials[0]->frames.size() > 1) TYRA_WARN("Static meshes should have only one frame, but ", - data.materials[0]->frames.size(), " frames were found"); + data->materials[0]->frames.size(), " frames were found"); - frame = new MeshFrame(data, 0); + frame = new MeshFrame(*data, 0); } StaticMesh::StaticMesh(const StaticMesh& mesh) : Mesh(mesh) { diff --git a/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp b/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp index 88be920..bcc5164 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp @@ -106,7 +106,7 @@ void DynamicPipeline::render(const DynamicMesh* mesh, u8 isPartInitialized = false; auto* texture = - rendererCore->texture.repository.getBySpriteOrMesh(material->id); + rendererCore->texture.repository.getByMeshMaterialId(material->id); TYRA_ASSERT( texture, "Texture for material: ", material->name, "Id: ", material->id, diff --git a/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp b/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp index a4ac831..5a7d24f 100644 --- a/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp +++ b/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp @@ -143,7 +143,7 @@ StaPipTextureBag* StaticPipeline::getTextureBag( auto* result = new StaPipTextureBag(); result->texture = - rendererCore->texture.repository.getBySpriteOrMesh(material->id); + rendererCore->texture.repository.getByMeshMaterialId(material->id); TYRA_ASSERT( result->texture, "Texture for material: ", material->name, diff --git a/engine/src/renderer/core/texture/texture_repository.cpp b/engine/src/renderer/core/texture/texture_repository.cpp index 17f3c2a..4fa47d5 100644 --- a/engine/src/renderer/core/texture/texture_repository.cpp +++ b/engine/src/renderer/core/texture/texture_repository.cpp @@ -22,7 +22,14 @@ TextureRepository::~TextureRepository() { } } -Texture* TextureRepository::getBySpriteOrMesh(const u32& t_id) const { +Texture* TextureRepository::getBySpriteId(const u32& t_id) const { + for (u32 i = 0; i < textures.size(); i++) { + if (textures[i]->isLinkedWith(t_id)) return textures[i]; + } + return nullptr; +} + +Texture* TextureRepository::getByMeshMaterialId(const u32& t_id) const { for (u32 i = 0; i < textures.size(); i++) { if (textures[i]->isLinkedWith(t_id)) return textures[i]; } @@ -56,6 +63,26 @@ void TextureRepository::removeById(const u32& t_texId) { removeByIndex(index); } +void TextureRepository::freeByMesh(const Mesh& mesh) { + for (auto* material : mesh.materials) { + auto* texture = getByMeshMaterialId(material->id); + + if (texture != nullptr) { + free(texture); + } + } +} + +void TextureRepository::freeByMesh(const Mesh* mesh) { freeByMesh(*mesh); } + +void TextureRepository::freeBySprite(const Sprite& sprite) { + auto* texture = getBySpriteId(sprite.id); + + if (texture != nullptr) { + free(texture); + } +} + void TextureRepository::free(const Texture* t_tex) { free(t_tex->id); } void TextureRepository::free(const Texture& t_tex) { free(t_tex.id); } @@ -81,7 +108,7 @@ Texture* TextureRepository::add(const char* fullpath) { return texture; } -void TextureRepository::addByMesh(Mesh* mesh, const char* directory, +void TextureRepository::addByMesh(const Mesh* mesh, const char* directory, const char* extension) { auto& loader = texLoaderSelector.getLoaderByExtension(extension); diff --git a/tutorials/02-sprite/inc/tutorial_02.hpp b/tutorials/02-sprite/inc/tutorial_02.hpp index 2a4fbbb..34ef153 100644 --- a/tutorials/02-sprite/inc/tutorial_02.hpp +++ b/tutorials/02-sprite/inc/tutorial_02.hpp @@ -29,7 +29,6 @@ class Tutorial02 : public Game { Engine* engine; Sprite sprite; - Texture* texture; }; } // namespace Tyra diff --git a/tutorials/02-sprite/src/tutorial_02.cpp b/tutorials/02-sprite/src/tutorial_02.cpp index 6695bf7..f4066f6 100644 --- a/tutorials/02-sprite/src/tutorial_02.cpp +++ b/tutorials/02-sprite/src/tutorial_02.cpp @@ -13,20 +13,10 @@ namespace Tyra { -Tutorial02::Tutorial02(Engine* t_engine) : engine(t_engine) { - /** Lets set default value, to prevent nullptr bugs */ - texture = nullptr; -} +Tutorial02::Tutorial02(Engine* t_engine) : engine(t_engine) {} Tutorial02::~Tutorial02() { - if (texture != nullptr) { - /** - * free() function in texture repository is - * removing texture from repository and calling - * texture destructor - */ - engine->renderer.core.texture.repository.free(texture); - } + engine->renderer.getTextureRepository().freeBySprite(sprite); } void Tutorial02::init() { @@ -111,7 +101,7 @@ void Tutorial02::loadTexture() { * 8bpp and 4bpp are the fastest. * All of these formats can be easily exported via GIMP. */ - texture = textureRepository.add(filepath); + auto* texture = textureRepository.add(filepath); /** Let's assign this texture to sprite. */ texture->addLink(sprite.id); diff --git a/tutorials/03-minecraft/src/tutorial_03.cpp b/tutorials/03-minecraft/src/tutorial_03.cpp index 9297d2c..aeb5f09 100644 --- a/tutorials/03-minecraft/src/tutorial_03.cpp +++ b/tutorials/03-minecraft/src/tutorial_03.cpp @@ -14,12 +14,13 @@ namespace Tyra { Tutorial03::Tutorial03(Engine* t_engine) : engine(t_engine) { + /** Lets set default value, to prevent nullptr bugs */ textureAtlas = nullptr; } Tutorial03::~Tutorial03() { if (textureAtlas != nullptr) { - engine->renderer.core.texture.repository.free(textureAtlas); + engine->renderer.getTextureRepository().free(textureAtlas); } } diff --git a/tutorials/04-de_dust2/Makefile b/tutorials/04-de_dust2/Makefile new file mode 100644 index 0000000..9789c77 --- /dev/null +++ b/tutorials/04-de_dust2/Makefile @@ -0,0 +1,24 @@ +TARGET := tutorial_04.elf +ENGINEDIR := ../../engine + +#The Directories, Source, Includes, Objects, Binary and Resources +SRCDIR := src +INCDIR := inc +BUILDDIR := obj +TARGETDIR := bin +RESDIR := res +SRCEXT := cpp +VSMEXT := vsm +VCLEXT := vcl +VCLPPEXT := vclpp +DEPEXT := d +OBJEXT := o + +#Flags, Libraries and Includes +CFLAGS := +LIB := +LIBDIRS := +INC := -I$(INCDIR) +INCDEP := -I$(INCDIR) + +include ../Makefile.tutorials-base \ No newline at end of file diff --git a/tutorials/04-de_dust2/bin/.gitignore b/tutorials/04-de_dust2/bin/.gitignore new file mode 100644 index 0000000..44c5ea8 --- /dev/null +++ b/tutorials/04-de_dust2/bin/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/tutorials/04-de_dust2/inc/tutorial_04.hpp b/tutorials/04-de_dust2/inc/tutorial_04.hpp new file mode 100644 index 0000000..9131a95 --- /dev/null +++ b/tutorials/04-de_dust2/inc/tutorial_04.hpp @@ -0,0 +1,35 @@ +/* +# _____ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2022, tyra - https://github.com/h4570/tyra +# Licensed under Apache License 2.0 +# Sandro Sobczyński +*/ + +#pragma once + +#include +#include + +namespace Tyra { + +class Tutorial04 : public Game { + public: + Tutorial04(Engine* engine); + ~Tutorial04(); + + void init(); + void loop(); + + private: + void loadMesh(); + + Engine* engine; + + std::unique_ptr mesh; + StaPipOptions renderOptions; +}; + +} // namespace Tyra diff --git a/tutorials/04-de_dust2/obj/.gitignore b/tutorials/04-de_dust2/obj/.gitignore new file mode 100644 index 0000000..44c5ea8 --- /dev/null +++ b/tutorials/04-de_dust2/obj/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/tutorials/04-de_dust2/res/.gitignore b/tutorials/04-de_dust2/res/.gitignore new file mode 100644 index 0000000..44c5ea8 --- /dev/null +++ b/tutorials/04-de_dust2/res/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore \ No newline at end of file diff --git a/tutorials/04-de_dust2/run.ps1 b/tutorials/04-de_dust2/run.ps1 new file mode 100644 index 0000000..74646cc --- /dev/null +++ b/tutorials/04-de_dust2/run.ps1 @@ -0,0 +1,4 @@ +$ConfigFile = Join-Path $PSScriptRoot '../../windows-pcsx2.ps1' +. $ConfigFile + +RunPCSX2 diff --git a/tutorials/04-de_dust2/src/main.cpp b/tutorials/04-de_dust2/src/main.cpp new file mode 100644 index 0000000..8c1dc96 --- /dev/null +++ b/tutorials/04-de_dust2/src/main.cpp @@ -0,0 +1,26 @@ +/* +# _____ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2022, tyra - https://github.com/h4570/tyra +# Licensed under Apache License 2.0 +# Sandro Sobczyński +*/ + +#include "engine.hpp" +#include "tutorial_04.hpp" + +/** + * In this tutorial we will learn: + * - How to get pad input and move the camera + * - What is static pipeline and how to use it + * - What is mesh (StaticMesh) and how to load it from .obj file + */ + +int main() { + Tyra::Engine engine; + Tyra::Tutorial04 game(&engine); + engine.run(&game); + return 0; +} diff --git a/tutorials/04-de_dust2/src/tutorial_04.cpp b/tutorials/04-de_dust2/src/tutorial_04.cpp new file mode 100644 index 0000000..ec573f7 --- /dev/null +++ b/tutorials/04-de_dust2/src/tutorial_04.cpp @@ -0,0 +1,39 @@ +/* +# _____ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2022, tyra - https://github.com/h4570/tyra +# Licensed under Apache License 2.0 +# Sandro Sobczyński +*/ + +#include +#include "tutorial_04.hpp" + +namespace Tyra { + +Tutorial04::Tutorial04(Engine* t_engine) : engine(t_engine) {} + +Tutorial04::~Tutorial04() { + engine->renderer.getTextureRepository().freeByMesh(mesh.get()); +} + +void Tutorial04::init() { loadMesh(); } + +void Tutorial04::loop() {} + +void Tutorial04::loadMesh() { + ObjLoader loader; + ObjLoaderOptions options; + options.flipUVs = true; + options.scale = 200.0F; + auto data = loader.load(FileUtils::fromCwd("de_dust2/de_dust2.obj"), options); + + mesh = std::make_unique(data.get()); + + engine->renderer.getTextureRepository().addByMesh( + mesh.get(), FileUtils::fromCwd("de_dust2/"), "png"); +} + +} // namespace Tyra