diff --git a/ROADMAP.txt b/ROADMAP.txt index e927708..c7af531 100644 --- a/ROADMAP.txt +++ b/ROADMAP.txt @@ -1,9 +1,5 @@ ------------ Tyra's v2.0 roadmap to publish on GitHub ------------ -- [General] CI in Github via docker image - -- [Tutorials] 1. Hello world! - explain init(), loop() and what should be inside them (every tutorial should be well commented!) - - [Tutorials] 2. 2D - explain beginFrame(), endFrame() - [Tutorials] 3. Minecraft cube - explain this pipeline, and explain that there are many 3D pipelines @@ -15,12 +11,15 @@ abstract 3D object class, and what it have (animation etc) explain that this is lower-level abstract rendering, it have the all the features as Mesh rendering, because Mesh rendering uses only core.render() -- [Tutorials] 6. Animation in Mesh rendering rendering, explain the API +- [Tutorials] 6. Animation in Mesh rendering, explain the API - [Tutorials] 7. Directional lights in Mesh rendering - [Tutorials] 8. Render skybox, and show that stdPipOptions.noClipChecks must be set to false, to turn on clip algorithms (prevent glitches) +- own game +- usb + - [General] Check all left TODOs -> Github issues - [General] Readme Credits: clipping, obj loader @@ -28,6 +27,7 @@ because Mesh rendering uses only core.render() ------------ Github issues for Tyra v2 ------------ - [Demo] porzadek z konstruktorami bbox - [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 diff --git a/engine/inc/file/file_utils.hpp b/engine/inc/file/file_utils.hpp index 793e85b..7d66d75 100644 --- a/engine/inc/file/file_utils.hpp +++ b/engine/inc/file/file_utils.hpp @@ -19,7 +19,16 @@ class FileUtils { FileUtils(); ~FileUtils(); + /** + * Get current working directory. + * Example: "host:" or "mass:" + */ static std::string getCwd(); + + /** + * Add current working directory prefix to path + * Example: "host:..." or "mass:..." + */ static std::string fromCwd(const std::string& relativePath); static std::string fromCwd(const char* relativePath); diff --git a/engine/inc/packet2/packet2_tyra_utils.hpp b/engine/inc/packet2/packet2_tyra_utils.hpp index 25c6ddf..0d3f504 100644 --- a/engine/inc/packet2/packet2_tyra_utils.hpp +++ b/engine/inc/packet2/packet2_tyra_utils.hpp @@ -18,6 +18,17 @@ namespace Tyra { class Packet2TyraUtils { public: + inline static void addUnpackData(packet2_t* packet2, + const u32& t_dest_address, + const void* t_data, const u32& t_size, + const u8& t_use_top) { + packet2_chain_ref(packet2, t_data, t_size, 0, 0, 0); + packet2_vif_stcycl(packet2, 0, 0x0101, 0); + packet2_vif_open_unpack(packet2, P2_UNPACK_V4_32, t_dest_address, t_use_top, + 0, 1, 0); + packet2_vif_close_unpack_manual(packet2, t_size); + } + inline static void addM4x4(packet2_t* packet2, const M4x4& val) { *(reinterpret_cast(packet2->next)) = val; packet2_advance_next(packet2, sizeof(MATRIX)); diff --git a/engine/inc/renderer/2d/renderer_2d.hpp b/engine/inc/renderer/2d/renderer_2d.hpp index 3ddc22b..83bafab 100644 --- a/engine/inc/renderer/2d/renderer_2d.hpp +++ b/engine/inc/renderer/2d/renderer_2d.hpp @@ -21,7 +21,8 @@ class Renderer2D { ~Renderer2D(); void init(RendererCore* rendererCore); - void render(Sprite* sprite); + void render(const Sprite* sprite); + void render(const Sprite& sprite); private: RendererCore* core; diff --git a/engine/inc/renderer/3d/pipeline/dynamic/core/bag/dynpip_color_bag.hpp b/engine/inc/renderer/3d/pipeline/dynamic/core/bag/dynpip_color_bag.hpp index 8a97f2d..2e58e93 100644 --- a/engine/inc/renderer/3d/pipeline/dynamic/core/bag/dynpip_color_bag.hpp +++ b/engine/inc/renderer/3d/pipeline/dynamic/core/bag/dynpip_color_bag.hpp @@ -23,7 +23,7 @@ class DynPipColorBag { ~DynPipColorBag(); /** Mandatory */ - Color* single; + const Color* single; }; } // namespace Tyra diff --git a/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp b/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp index ee51ce7..3d936c8 100644 --- a/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp +++ b/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp @@ -45,7 +45,8 @@ class DynamicPipeline : public Renderer3DPipeline { * Render dynamic model. * This render() method is a bridge to core.render() method. */ - void render(DynamicMesh* mesh, const DynPipOptions* options = nullptr); + void render(const DynamicMesh& mesh, const DynPipOptions* options = nullptr); + void render(const DynamicMesh* mesh, const DynPipOptions* options = nullptr); private: RendererCore* rendererCore; @@ -57,29 +58,29 @@ class DynamicPipeline : public Renderer3DPipeline { void sendRestOfBuffers(DynPipBag* buffers, u16* bufferIndex); - void addVertices(MeshMaterialFrame* materialFrameFrom, - MeshMaterialFrame* materialFrameTo, DynPipBag* bag, + void addVertices(const MeshMaterialFrame* materialFrameFrom, + const MeshMaterialFrame* materialFrameTo, DynPipBag* bag, const u32& startIndex) const; - DynPipInfoBag* getInfoBag(DynamicMesh* mesh, const DynPipOptions* options, - M4x4* model) const; + DynPipInfoBag* getInfoBag(const DynamicMesh* mesh, + const DynPipOptions* options, M4x4* model) const; - DynPipColorBag* getColorBag(MeshMaterial* material) const; + DynPipColorBag* getColorBag(const MeshMaterial* material) const; DynPipTextureBag* getTextureBag(Texture* texture, - MeshMaterialFrame* materialFrameFrom, - MeshMaterialFrame* materialFrameTo, + const MeshMaterialFrame* materialFrameFrom, + const MeshMaterialFrame* materialFrameTo, const u32& startIndex); - DynPipLightingBag* getLightingBag(MeshMaterialFrame* materialFrameFrom, - MeshMaterialFrame* materialFrameTo, + DynPipLightingBag* getLightingBag(const MeshMaterialFrame* materialFrameFrom, + const MeshMaterialFrame* materialFrameTo, M4x4* model, const DynPipOptions* options, PipelineDirLightsBag* dirLightsBag, const u32& startIndex) const; void setLightingColorsCache(PipelineLightingOptions* lightingOptions); void freeBuffer(DynPipBag* bag); - void setBuffersDefaultVars(DynPipBag* buffers, DynamicMesh* mesh, + void setBuffersDefaultVars(DynPipBag* buffers, const DynamicMesh* mesh, DynPipInfoBag* infoBag); void setBuffersColorBag(DynPipBag* buffers, DynPipColorBag* colorBag); }; diff --git a/engine/inc/renderer/3d/pipeline/static/core/bag/packaging/stapip_bag_package.hpp b/engine/inc/renderer/3d/pipeline/static/core/bag/packaging/stapip_bag_package.hpp index 5e48519..92e0c59 100644 --- a/engine/inc/renderer/3d/pipeline/static/core/bag/packaging/stapip_bag_package.hpp +++ b/engine/inc/renderer/3d/pipeline/static/core/bag/packaging/stapip_bag_package.hpp @@ -22,10 +22,10 @@ class StaPipBagPackage { StaPipBag* bag; - Vec4* vertices; - Vec4* sts; - Vec4* normals; - Vec4* colors; + const Vec4* vertices; + const Vec4* sts; + const Vec4* normals; + const Vec4* colors; /** maxVertCount is max value, because we decided to put max maxVertCount * verts to single quad buffer in VU1 */ u16 size; diff --git a/engine/inc/renderer/3d/pipeline/static/core/bag/stapip_color_bag.hpp b/engine/inc/renderer/3d/pipeline/static/core/bag/stapip_color_bag.hpp index f65f320..a93e520 100644 --- a/engine/inc/renderer/3d/pipeline/static/core/bag/stapip_color_bag.hpp +++ b/engine/inc/renderer/3d/pipeline/static/core/bag/stapip_color_bag.hpp @@ -23,10 +23,10 @@ class StaPipColorBag { ~StaPipColorBag(); /** Optional. Single color for all vertices. */ - Color* single; + const Color* single; /** Optional. Color per vertex. */ - Color* many; + const Color* many; }; } // namespace Tyra diff --git a/engine/inc/renderer/3d/pipeline/static/static_pipeline.hpp b/engine/inc/renderer/3d/pipeline/static/static_pipeline.hpp index 2ce4fe7..9ee9a80 100644 --- a/engine/inc/renderer/3d/pipeline/static/static_pipeline.hpp +++ b/engine/inc/renderer/3d/pipeline/static/static_pipeline.hpp @@ -45,28 +45,30 @@ class StaticPipeline : public Renderer3DPipeline { * Render static model * This render() method is a bridge to core.render() method. */ - void render(StaticMesh* mesh, const StaPipOptions* options = nullptr); + void render(const StaticMesh& mesh, const StaPipOptions* options = nullptr); + void render(const StaticMesh* mesh, const StaPipOptions* options = nullptr); private: RendererCore* rendererCore; Vec4* colorsCache; - void addVertices(MeshMaterialFrame* materialFrame, StaPipBag* bag) const; + void addVertices(const MeshMaterialFrame* materialFrame, + StaPipBag* bag) const; - StaPipInfoBag* getInfoBag(StaticMesh* mesh, const StaPipOptions* options, - M4x4* model) const; + StaPipInfoBag* getInfoBag(const StaticMesh* mesh, + const StaPipOptions* options, M4x4* model) const; - StaPipColorBag* getColorBag(MeshMaterial* material, - MeshMaterialFrame* materialFrame) const; + StaPipColorBag* getColorBag(const MeshMaterial* material, + const MeshMaterialFrame* materialFrame) const; - StaPipTextureBag* getTextureBag(MeshMaterial* material, - MeshMaterialFrame* materialFrame); + StaPipTextureBag* getTextureBag(const MeshMaterial* material, + const MeshMaterialFrame* materialFrame); - StaPipLightingBag* getLightingBag(MeshMaterialFrame* materialFrame, + StaPipLightingBag* getLightingBag(const MeshMaterialFrame* materialFrame, M4x4* model, const StaPipOptions* options) const; - void deallocDrawBags(StaPipBag* bag, MeshMaterial* material) const; + void deallocDrawBags(StaPipBag* bag, const MeshMaterial* material) const; void setLightingColorsCache(PipelineLightingOptions* lightingOptions); }; diff --git a/engine/inc/renderer/core/2d/renderer_core_2d.hpp b/engine/inc/renderer/core/2d/renderer_core_2d.hpp index 8796307..aaa1d4d 100644 --- a/engine/inc/renderer/core/2d/renderer_core_2d.hpp +++ b/engine/inc/renderer/core/2d/renderer_core_2d.hpp @@ -27,8 +27,8 @@ class RendererCore2D { void init(RendererSettings* settings, clutbuffer_t* clutBuffer); - void render(Sprite* sprite, const RendererCoreTextureBuffers& texBuffers, - Texture* texture); + void render(const Sprite& sprite, + const RendererCoreTextureBuffers& texBuffers, Texture* texture); private: void setPrim(); diff --git a/engine/inc/renderer/core/texture/texture_repository.hpp b/engine/inc/renderer/core/texture/texture_repository.hpp index a5582bf..09c10fb 100644 --- a/engine/inc/renderer/core/texture/texture_repository.hpp +++ b/engine/inc/renderer/core/texture/texture_repository.hpp @@ -108,6 +108,8 @@ class TextureRepository { * Texture IS destructed. */ void free(const u32& t_texId); + void free(const Texture* t_tex); + void free(const Texture& t_tex); private: std::vector textures; diff --git a/engine/src/renderer/2d/renderer_2d.cpp b/engine/src/renderer/2d/renderer_2d.cpp index 8752b99..eba4861 100644 --- a/engine/src/renderer/2d/renderer_2d.cpp +++ b/engine/src/renderer/2d/renderer_2d.cpp @@ -17,11 +17,13 @@ Renderer2D::~Renderer2D() {} void Renderer2D::init(RendererCore* t_rendererCore) { core = t_rendererCore; } -void Renderer2D::render(Sprite* sprite) { - auto* texture = core->texture.repository.getBySpriteOrMesh(sprite->id); +void Renderer2D::render(const Sprite* sprite) { render(*sprite); } + +void Renderer2D::render(const Sprite& sprite) { + auto* texture = core->texture.repository.getBySpriteOrMesh(sprite.id); TYRA_ASSERT( - texture, "Texture for sprite with id: ", sprite->id, + texture, "Texture for sprite with id: ", sprite.id, "Was not found in texture repository! Did you forget to add texture?"); auto texBuffers = core->texture.useTexture(texture); 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 05e7f4b..17c1bed 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_renderer.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_renderer.cpp @@ -11,6 +11,8 @@ #include "renderer/3d/pipeline/dynamic/core/dynpip_renderer.hpp" #include "renderer/3d/pipeline/dynamic/core/programs/dynpip_vu1_shared_defines.h" #include +#include +#include "packet2/packet2_tyra_utils.hpp" namespace Tyra { @@ -114,8 +116,8 @@ void DynPipRenderer::sendObjectData( if (singleColorEnabled) // Color is placed in 4th slot of // VU1_LIGHTS_MATRIX_ADDR - packet2_utils_vu_add_unpack_data(objectDataPacket, VU1_SINGLE_COLOR_ADDR, - bag->color->single->rgba, 1, false); + Packet2TyraUtils::addUnpackData(objectDataPacket, VU1_SINGLE_COLOR_ADDR, + bag->color->single->rgba, 1, false); packet2_utils_vu_open_unpack(objectDataPacket, VU1_OPTIONS_ADDR, false); { diff --git a/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp b/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp index cdfd096..88be920 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp @@ -51,7 +51,13 @@ void DynamicPipeline::onUseEnd() { core.deallocateOnUse(); } -void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) { +void DynamicPipeline::render(const DynamicMesh& mesh, + const DynPipOptions* options) { + render(&mesh, options); +} + +void DynamicPipeline::render(const DynamicMesh* mesh, + const DynPipOptions* options) { bool optionsManuallyAllocated = false; if (!options) { @@ -185,7 +191,7 @@ void DynamicPipeline::sendRestOfBuffers(DynPipBag* buffers, u16* bufferIndex) { } void DynamicPipeline::setBuffersDefaultVars(DynPipBag* buffers, - DynamicMesh* mesh, + const DynamicMesh* mesh, DynPipInfoBag* infoBag) { for (u32 i = 0; i < buffersCount; i++) { buffers[i].info = infoBag; @@ -210,7 +216,7 @@ void DynamicPipeline::freeBuffer(DynPipBag* bag) { } } -DynPipInfoBag* DynamicPipeline::getInfoBag(DynamicMesh* mesh, +DynPipInfoBag* DynamicPipeline::getInfoBag(const DynamicMesh* mesh, const DynPipOptions* options, M4x4* model) const { auto* result = new DynPipInfoBag(); @@ -230,22 +236,23 @@ DynPipInfoBag* DynamicPipeline::getInfoBag(DynamicMesh* mesh, return result; } -void DynamicPipeline::addVertices(MeshMaterialFrame* materialFrameFrom, - MeshMaterialFrame* materialFrameTo, +void DynamicPipeline::addVertices(const MeshMaterialFrame* materialFrameFrom, + const MeshMaterialFrame* materialFrameTo, DynPipBag* bag, const u32& startIndex) const { bag->verticesFrom = &materialFrameFrom->vertices[startIndex]; bag->verticesTo = &materialFrameTo->vertices[startIndex]; } -DynPipColorBag* DynamicPipeline::getColorBag(MeshMaterial* material) const { +DynPipColorBag* DynamicPipeline::getColorBag( + const MeshMaterial* material) const { auto* result = new DynPipColorBag(); result->single = &material->ambient; return result; } DynPipTextureBag* DynamicPipeline::getTextureBag( - Texture* texture, MeshMaterialFrame* materialFrameFrom, - MeshMaterialFrame* materialFrameTo, const u32& startIndex) { + Texture* texture, const MeshMaterialFrame* materialFrameFrom, + const MeshMaterialFrame* materialFrameTo, const u32& startIndex) { if (!materialFrameFrom->textureCoords) return nullptr; auto* result = new DynPipTextureBag(); @@ -259,9 +266,10 @@ DynPipTextureBag* DynamicPipeline::getTextureBag( } DynPipLightingBag* DynamicPipeline::getLightingBag( - MeshMaterialFrame* materialFrameFrom, MeshMaterialFrame* materialFrameTo, - M4x4* model, const DynPipOptions* options, - PipelineDirLightsBag* dirLightsBag, const u32& startIndex) const { + const MeshMaterialFrame* materialFrameFrom, + const MeshMaterialFrame* materialFrameTo, M4x4* model, + const DynPipOptions* options, PipelineDirLightsBag* dirLightsBag, + const u32& startIndex) const { if (!materialFrameFrom->normals || options == nullptr || options->lighting == nullptr) return nullptr; diff --git a/engine/src/renderer/3d/pipeline/static/core/bag/packaging/stapip_bag_packager.cpp b/engine/src/renderer/3d/pipeline/static/core/bag/packaging/stapip_bag_packager.cpp index 30cb8a5..b8044a6 100644 --- a/engine/src/renderer/3d/pipeline/static/core/bag/packaging/stapip_bag_packager.cpp +++ b/engine/src/renderer/3d/pipeline/static/core/bag/packaging/stapip_bag_packager.cpp @@ -43,7 +43,8 @@ StaPipBagPackage* StaPipBagPackager::create(u16* o_size, StaPipBag* data, if (data->texture) result[i].sts = &data->texture->coordinates[i * size]; if (data->color->many) - result[i].colors = reinterpret_cast(&data->color->many[i * size]); + result[i].colors = + reinterpret_cast(&data->color->many[i * size]); if (data->lighting) result[i].normals = &data->lighting->normals[i * size]; diff --git a/engine/src/renderer/3d/pipeline/static/core/stapip_qbuffer.cpp b/engine/src/renderer/3d/pipeline/static/core/stapip_qbuffer.cpp index 38db9a6..a43fb0a 100644 --- a/engine/src/renderer/3d/pipeline/static/core/stapip_qbuffer.cpp +++ b/engine/src/renderer/3d/pipeline/static/core/stapip_qbuffer.cpp @@ -37,10 +37,12 @@ void StaPipQBuffer::fillByPointer(const StaPipBagPackage& pkg) { deallocateDynamicData(); - vertices = pkg.vertices; - sts = pkg.sts; - colors = pkg.colors; - normals = pkg.normals; + // Too bad, but in reality const is not violated. + // This class needs refactor + vertices = const_cast(pkg.vertices); + sts = const_cast(pkg.sts); + colors = const_cast(pkg.colors); + normals = const_cast(pkg.normals); size = pkg.size; bag = pkg.bag; } diff --git a/engine/src/renderer/3d/pipeline/static/core/stapip_qbuffer_renderer.cpp b/engine/src/renderer/3d/pipeline/static/core/stapip_qbuffer_renderer.cpp index 4877369..1bf1adc 100644 --- a/engine/src/renderer/3d/pipeline/static/core/stapip_qbuffer_renderer.cpp +++ b/engine/src/renderer/3d/pipeline/static/core/stapip_qbuffer_renderer.cpp @@ -10,6 +10,7 @@ #include "renderer/3d/pipeline/static/core/stapip_qbuffer_renderer.hpp" #include "renderer/3d/pipeline/static/core/programs/stapip_vu1_shared_defines.h" +#include "packet2/packet2_tyra_utils.hpp" // #define TYRA_QBUFF_RENDERER_VERBOSE_LOG 1 @@ -135,8 +136,8 @@ void StaPipQBufferRenderer::sendObjectData( if (singleColorEnabled) // Color is placed in 4th slot of // VU1_LIGHTS_MATRIX_ADDR - packet2_utils_vu_add_unpack_data(objectDataPacket, VU1_SINGLE_COLOR_ADDR, - bag->color->single->rgba, 1, false); + Packet2TyraUtils::addUnpackData(objectDataPacket, VU1_SINGLE_COLOR_ADDR, + bag->color->single->rgba, 1, false); packet2_utils_vu_open_unpack(objectDataPacket, VU1_OPTIONS_ADDR, false); { diff --git a/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp b/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp index d9ec05e..a4ac831 100644 --- a/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp +++ b/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp @@ -39,7 +39,13 @@ void StaticPipeline::onUseEnd() { core.deallocateOnUse(); } -void StaticPipeline::render(StaticMesh* mesh, const StaPipOptions* options) { +void StaticPipeline::render(const StaticMesh& mesh, + const StaPipOptions* options) { + render(&mesh, options); +} + +void StaticPipeline::render(const StaticMesh* mesh, + const StaPipOptions* options) { bool optionsManuallyAllocated = false; if (!options) { @@ -89,13 +95,13 @@ void StaticPipeline::render(StaticMesh* mesh, const StaPipOptions* options) { if (optionsManuallyAllocated) delete options; } -void StaticPipeline::addVertices(MeshMaterialFrame* materialFrame, +void StaticPipeline::addVertices(const MeshMaterialFrame* materialFrame, StaPipBag* bag) const { bag->count = materialFrame->count; bag->vertices = materialFrame->vertices; } -StaPipInfoBag* StaticPipeline::getInfoBag(StaticMesh* mesh, +StaPipInfoBag* StaticPipeline::getInfoBag(const StaticMesh* mesh, const StaPipOptions* options, M4x4* model) const { auto* result = new StaPipInfoBag(); @@ -117,7 +123,8 @@ StaPipInfoBag* StaticPipeline::getInfoBag(StaticMesh* mesh, } StaPipColorBag* StaticPipeline::getColorBag( - MeshMaterial* material, MeshMaterialFrame* materialFrame) const { + const MeshMaterial* material, + const MeshMaterialFrame* materialFrame) const { auto* result = new StaPipColorBag(); if (material->lightmapFlag) { @@ -130,7 +137,7 @@ StaPipColorBag* StaticPipeline::getColorBag( } StaPipTextureBag* StaticPipeline::getTextureBag( - MeshMaterial* material, MeshMaterialFrame* materialFrame) { + const MeshMaterial* material, const MeshMaterialFrame* materialFrame) { if (!materialFrame->textureCoords) return nullptr; auto* result = new StaPipTextureBag(); @@ -149,7 +156,7 @@ StaPipTextureBag* StaticPipeline::getTextureBag( } StaPipLightingBag* StaticPipeline::getLightingBag( - MeshMaterialFrame* materialFrame, M4x4* model, + const MeshMaterialFrame* materialFrame, M4x4* model, const StaPipOptions* options) const { if (!materialFrame->normals || options == nullptr || options->lighting == nullptr) @@ -181,7 +188,7 @@ void StaticPipeline::setLightingColorsCache( } void StaticPipeline::deallocDrawBags(StaPipBag* bag, - MeshMaterial* material) const { + const MeshMaterial* material) const { if (bag->texture) { delete bag->texture; } diff --git a/engine/src/renderer/core/2d/renderer_core_2d.cpp b/engine/src/renderer/core/2d/renderer_core_2d.cpp index fb4e07e..3f4f397 100644 --- a/engine/src/renderer/core/2d/renderer_core_2d.cpp +++ b/engine/src/renderer/core/2d/renderer_core_2d.cpp @@ -62,15 +62,15 @@ void RendererCore2D::init(RendererSettings* t_settings, clutBuffer = t_clutBuffer; } -void RendererCore2D::render(Sprite* sprite, +void RendererCore2D::render(const Sprite& sprite, const RendererCoreTextureBuffers& texBuffers, Texture* texture) { auto* rect = rects[context]; float sizeX, sizeY; - if (sprite->mode == MODE_REPEAT) { - sizeX = sprite->size.x; - sizeY = sprite->size.y; + if (sprite.mode == MODE_REPEAT) { + sizeX = sprite.size.x; + sizeY = sprite.size.y; } else { sizeX = static_cast(texture->getWidth()); sizeY = static_cast(texture->getHeight()); @@ -84,24 +84,24 @@ void RendererCore2D::render(Sprite* sprite, else if (sizeY > sizeX) texS = texMax / (sizeY / sizeX); - rect->t0.s = sprite->flipHorizontal ? texS : 0.0F; - rect->t0.t = sprite->flipVertical ? texT : 0.0F; - rect->t1.s = sprite->flipHorizontal ? 0.0F : texS; - rect->t1.t = sprite->flipVertical ? 0.0F : texT; + rect->t0.s = sprite.flipHorizontal ? texS : 0.0F; + rect->t0.t = sprite.flipVertical ? texT : 0.0F; + rect->t1.s = sprite.flipHorizontal ? 0.0F : texS; + rect->t1.t = sprite.flipVertical ? 0.0F : texT; - rect->color.r = sprite->color.r; - rect->color.g = sprite->color.g; - rect->color.b = sprite->color.b; - rect->color.a = sprite->color.a; + rect->color.r = sprite.color.r; + rect->color.g = sprite.color.g; + rect->color.b = sprite.color.b; + rect->color.a = sprite.color.a; rect->color.q = 0; - rect->v0.x = sprite->position.x; - rect->v0.y = sprite->position.y; + rect->v0.x = sprite.position.x; + rect->v0.y = sprite.position.y; // rect->v0.y /= 2.0F; // interlacing rect->v0.z = (u32)-1; - rect->v1.x = (sprite->size.x * sprite->scale) + sprite->position.x; - rect->v1.y = (sprite->size.y * sprite->scale) + sprite->position.y; + rect->v1.x = (sprite.size.x * sprite.scale) + sprite.position.x; + rect->v1.y = (sprite.size.y * sprite.scale) + sprite.position.y; // rect->v1.y /= 2.0F; // interlacing rect->v1.z = (u32)-1; diff --git a/engine/src/renderer/core/texture/texture_repository.cpp b/engine/src/renderer/core/texture/texture_repository.cpp index cd67740..17f3c2a 100644 --- a/engine/src/renderer/core/texture/texture_repository.cpp +++ b/engine/src/renderer/core/texture/texture_repository.cpp @@ -56,6 +56,10 @@ void TextureRepository::removeById(const u32& t_texId) { removeByIndex(index); } +void TextureRepository::free(const Texture* t_tex) { free(t_tex->id); } + +void TextureRepository::free(const Texture& t_tex) { free(t_tex.id); } + void TextureRepository::free(const u32& t_texId) { s32 index = getIndexOf(t_texId); auto* tex = textures[index]; diff --git a/tutorials/01-hello/inc/tutorial_01.hpp b/tutorials/01-hello/inc/tutorial_01.hpp index 2c6258d..a8011e0 100644 --- a/tutorials/01-hello/inc/tutorial_01.hpp +++ b/tutorials/01-hello/inc/tutorial_01.hpp @@ -10,54 +10,30 @@ #pragma once -#include -#include -#include "renderer/3d/pipeline/minecraft/minecraft_pipeline.hpp" -#include "renderer/3d/pipeline/static/static_pipeline.hpp" -#include "renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp" -#include "renderer/3d/mesh/static/static_mesh.hpp" +/** We can include all of Tyra classes via this single line: */ +#include namespace Tyra { +/** Tutorial01 is a name of our game class */ class Tutorial01 : public Game { public: Tutorial01(Engine* engine); ~Tutorial01(); + /** + * This function will be called once, + * immediatly after initializing Tyra features + */ void init(); + + /** + * This function will be called every frame + */ void loop(); private: Engine* engine; - - StaticMesh* skybox; - DynamicMesh* cube; - StaticMesh* staticMesh; - DynamicMesh* warrior; - u8 warriorsCount; - DynamicMesh** warriors; - u32 picturesCount; - Sprite** pictures; - audsrv_adpcm_t* adpcmSample; - Timer adpcmTimer; - - Vec4 cameraPosition, cameraLookAt; - - MinecraftPipeline mcPip; - DynamicPipeline dynpip; - StaticPipeline stapip; - StaPipOptions* skyboxOptions; - StaPipOptions* staOptions; - DynPipOptions* dynOptions; - Texture* warriorTex; - Texture* blocksTex; - Texture* blocksTex2; - - u32 blocksCount; - std::vector blocks; - M4x4* translations; - M4x4* rotations; - M4x4* scales; }; } // namespace Tyra diff --git a/tutorials/01-hello/src/main.cpp b/tutorials/01-hello/src/main.cpp index af3ac58..07f8870 100644 --- a/tutorials/01-hello/src/main.cpp +++ b/tutorials/01-hello/src/main.cpp @@ -11,10 +11,33 @@ #include "engine.hpp" #include "tutorial_01.hpp" +/** + * Hello, thank you for choosing Tyra engine! + * + * In this tutorial we will learn how to: + * - Initialize engine and game class + * - Use debug functions + * - Print "Hello world" to the screen + */ + int main() { + /** + * This is a class which contains + * all features of Tyra. + */ Tyra::Engine engine; + + /** + * This is a class with our game code. + */ Tyra::Tutorial01 game(&engine); + + /** + * We need to insert our game class into engine. + */ engine.run(&game); - SleepThread(); + + /** Continuation in file tutorial_01.hpp */ + return 0; } diff --git a/tutorials/01-hello/src/tutorial_01.cpp b/tutorials/01-hello/src/tutorial_01.cpp index 331c920..2b08a15 100644 --- a/tutorials/01-hello/src/tutorial_01.cpp +++ b/tutorials/01-hello/src/tutorial_01.cpp @@ -8,300 +8,52 @@ # Sandro Sobczyński */ +#include #include "tutorial_01.hpp" -#include "file/file_utils.hpp" -#include "loaders/3d/md2_loader/md2_loader.hpp" -#include "loaders/3d/obj_loader/obj_loader.hpp" -#include "thread/threading.hpp" namespace Tyra { -float getRandomFloat(float a, float b) { - float random = ((float)rand()) / (float)RAND_MAX; - float diff = b - a; - float r = random * diff; - return a + r; +/** Lets save pointer to engine class */ +Tutorial01::Tutorial01(Engine* t_engine) : engine(t_engine) {} + +Tutorial01::~Tutorial01() {} + +void Tutorial01::init() { + /** + * There are 5 debug functions in Tyra engine. + * + * TYRA_LOG() -> Prints log message + * + * TYRA_WARN() -> Prints warning message + * + * TYRA_ERROR() -> Prints error message + * + * TYRA_ASSERT() -> Checks if condition is true, otherwise prints error + * message + * + * TYRA_BREAKPOINT() -> Freeze program in current place + * + * Every function has infinite number of various-typed arguments. + */ + + short positiveNumber = -1; // Change it to -1 and see what happen! + + TYRA_LOG("Hello world!"); + + TYRA_WARN("Something weird happened! ", + "Number should be positive, but is: ", -1); + + TYRA_ERROR("Something really bad happened!"); + + /** First argument is our check argument */ + TYRA_ASSERT(positiveNumber > 0, "Number should be positive!", + "Please check the code!", "Current value:", (int)positiveNumber); } -int getRandomInt(int a, int b) { return (rand() % (b - a + 1)) + a; } +void Tutorial01::loop() { + /** Uncomment following line, to check the game loop! */ -Tutorial01 ::Tutorial01(Engine* t_engine) { engine = t_engine; } -Tutorial01 ::~Tutorial01() {} - -StaticMesh* getStaticMesh(Renderer* renderer); -DynamicMesh* getWarrior(Renderer* renderer); -StaticMesh* getSkybox(Renderer* renderer); -DynamicMesh* getCube(Renderer* renderer); -StaPipOptions* getStaPipOptions(); -DynPipOptions* getDynPipOptions(); -void setPipelineOptions(PipelineOptions* options); -Sprite* get2DPicture(Renderer* renderer); - -void Tutorial01 ::init() { - // Song - engine->audio.song.load(FileUtils::fromCwd("mafikizolo-loot.wav")); - engine->audio.song.inLoop = true; - engine->audio.song.setVolume(30); - - adpcmSample = engine->audio.adpcm.load(FileUtils::fromCwd("walk.adpcm")); - engine->audio.adpcm.setVolume(80, 1); - - engine->renderer.setClearScreenColor(Color(64.0F, 64.0F, 64.0F)); - - staticMesh = getStaticMesh(&engine->renderer); - skybox = getSkybox(&engine->renderer); - - cube = getCube(&engine->renderer); - - warrior = getWarrior(&engine->renderer); - warriorTex = engine->renderer.core.texture.repository.getBySpriteOrMesh( - warrior->materials[0]->id); - - warriorsCount = 22; - warriors = new DynamicMesh*[warriorsCount]; - for (u8 i = 0; i < warriorsCount; i++) { - warriors[i] = new DynamicMesh(*warrior); - warriors[i]->translation.translateX(-40.0F + static_cast(i) * 4); - warriors[i]->translation.translateY(30.0F); - warriors[i]->translation.translateZ(-10.0F); - warriors[i]->translation.rotateX(-1.5F); - warriorTex->addLink(warriors[i]->materials[0]->id); - warriors[i]->animation.speed = getRandomFloat(0.1F, 0.9F); - } - - staOptions = getStaPipOptions(); - - skyboxOptions = new StaPipOptions(); - skyboxOptions->fullClipChecks = true; - skyboxOptions->frustumCulling = PipelineFrustumCulling_Precise; - - dynOptions = getDynPipOptions(); - - cameraPosition = Vec4(0.0F, 0.0F, 20.0F); - cameraLookAt = *warrior->getPosition(); - - blocksTex = engine->renderer.core.texture.repository.add( - FileUtils::fromCwd("blocks.png")); - blocksTex2 = engine->renderer.core.texture.repository.add( - FileUtils::fromCwd("texture_atlas.png")); - - mcPip.setRenderer(&engine->renderer.core); - dynpip.setRenderer(&engine->renderer.core); - stapip.setRenderer(&engine->renderer.core); - - picturesCount = 3; - pictures = new Sprite*[picturesCount]; - for (u32 i = 0; i < picturesCount; i++) - pictures[i] = get2DPicture(&engine->renderer); - - u32 rows = 4; // 64 - u32 columns = 4; // 64 - blocksCount = rows * columns; - - float offset = 4.0F; - translations = new M4x4[blocksCount]; - rotations = new M4x4[blocksCount]; - scales = new M4x4[blocksCount]; - float center = (rows / 2.0F) * offset; - auto* color = new Color(128.0F, 128.0F, 128.0F, 128.0F); - - for (u32 i = 0; i < blocksCount; i++) { - u32 column = i % columns; - u32 row = i / rows; - - translations[i].identity(); - rotations[i].identity(); - scales[i].identity(); - - translations[i].translateX(row * offset - center); - translations[i].translateY(column * offset - center); - translations[i].translateZ(-10.0F); - - // u32 randRow = rand() % (rows + 1); - // u32 randColumn = rand() % (columns + 1); - u32 randRow = 0; - u32 randColumn = 0; - - McpipBlock* block = new McpipBlock(); - block->textureOffset = - new Vec4(mcPip.getTextureOffset() * randRow, - mcPip.getTextureOffset() * randColumn, 0.0F, 1.0F); - - block->color = color; - blocks.push_back(block); - } - - // engine->audio.play(); - // engine->renderer.setFrameLimit(false); -} - -u32 counter = 0; - -void Tutorial01 ::loop() { - if (counter++ > 100) { - TYRA_LOG("Free RAM: ", engine->info.getAvailableRAM(), " MB"); - TYRA_LOG("FPS: ", engine->info.getFps()); - counter = 0; - } - - for (u8 i = 0; i < warriorsCount; i++) warriors[i]->update(); - cube->update(); - - skybox->rotation.rotateY(0.02F); - - engine->renderer.beginFrame(CameraInfo3D(&cameraPosition, &cameraLookAt)); - { - for (u32 i = 0; i < blocksCount; i++) { - // rotations[i].rotateX(0.04F); - rotations[i].rotateY(0.04F); - // rotations[i].rotateZ(0.01F); - - if (blocks[i]->model) { - delete blocks[i]->model; - } - blocks[i]->model = new M4x4(translations[i] * rotations[i] * scales[i]); - } - - for (u32 i = 0; i < picturesCount; i++) - engine->renderer.renderer2D.render(pictures[i]); - - engine->renderer.renderer3D.usePipeline(&stapip); - { - stapip.render(staticMesh, staOptions); - stapip.render(skybox, skyboxOptions); - } - - engine->renderer.renderer3D.usePipeline(&dynpip); - { - // dynpip.render(cube); - Threading::switchThread(); - for (u8 i = 0; i < warriorsCount; i++) { - dynpip.render(warriors[i], dynOptions); - if (i == 5) Threading::switchThread(); - if (i == 10) Threading::switchThread(); - if (i == 15) Threading::switchThread(); - } - } - - engine->renderer.renderer3D.usePipeline(&mcPip); - { mcPip.render(blocks, blocksTex2, true); } - } - engine->renderer.endFrame(); -} - -StaticMesh* getStaticMesh(Renderer* renderer) { - MD2Loader loader; - MD2LoaderOptions options; - options.scale = .08F; - - auto* data = loader.load(FileUtils::fromCwd("warrior.md2"), options); - auto* result = new StaticMesh(*data); - // result->translation.translateZ(-30.0F); - delete data; - - renderer->core.texture.repository.addByMesh(result, FileUtils::getCwd(), - "png"); - - return result; -} - -StaticMesh* getSkybox(Renderer* renderer) { - ObjLoader loader; - ObjLoaderOptions options; - options.flipUVs = true; - options.scale = 200.0F; - auto* data = loader.load(FileUtils::fromCwd("skybox/skybox.obj"), options); - auto* result = new StaticMesh(*data); - // result->translation.translateZ(-30.0F); - delete data; - - renderer->core.texture.repository.addByMesh( - result, FileUtils::fromCwd("skybox/"), "png"); - - return result; -} - -DynamicMesh* getWarrior(Renderer* renderer) { - MD2Loader loader; - MD2LoaderOptions options; - options.scale = .08F; - auto* data = loader.load(FileUtils::fromCwd("warrior.md2"), options); - auto* result = new DynamicMesh(*data); - // result->translation.translateZ(-30.0F); - delete data; - - renderer->core.texture.repository.addByMesh(result, FileUtils::getCwd(), - "png"); - - result->animation.speed = 0.15F; - - return result; -} - -DynamicMesh* getCube(Renderer* renderer) { - ObjLoader loader; - ObjLoaderOptions options; - options.animation.count = 2; - options.scale = 3.0F; - auto* data = loader.load(FileUtils::fromCwd("untitled.obj"), options); - data->normalsEnabled = false; - data->textureCoordsEnabled = false; - auto* result = new DynamicMesh(*data); - result->translation.translateZ(-30.0F); - delete data; - - result->animation.speed = 0.15F; - - return result; -} - -Sprite* get2DPicture(Renderer* renderer) { - auto* sprite = new Sprite; - - sprite->size.set(128.0F, 128.0F); - sprite->position.set(300.0F, 280.0F); - - renderer->core.texture.repository.add(FileUtils::fromCwd("reward.png")) - ->addLink(sprite->id); - - return sprite; -} - -StaPipOptions* getStaPipOptions() { - auto* options = new StaPipOptions(); - setPipelineOptions(options); - return options; -} - -DynPipOptions* getDynPipOptions() { - auto* options = new DynPipOptions(); - setPipelineOptions(options); - return options; -} - -void setPipelineOptions(PipelineOptions* options) { - auto* ambientColor = new Color(32.0F, 32.0F, 32.0F, 32.0F); - auto* directionalColors = new Color[3]; - for (int i = 0; i < 3; i++) directionalColors[i].set(0.0F, 0.0F, 0.0F, 1.0F); - auto* directionalDirections = new Vec4[3]; - for (int i = 0; i < 3; i++) - directionalDirections[i].set(1.0F, 1.0F, 1.0F, 1.0F); - - auto* lightingOptions = new PipelineLightingOptions(); // Memory leak! - lightingOptions->ambientColor = ambientColor; - lightingOptions->directionalColors = directionalColors; - lightingOptions->directionalDirections = directionalDirections; - - options->shadingType = Tyra::TyraShadingGouraud; - options->blendingEnabled = true; - options->antiAliasingEnabled = false; - options->lighting = lightingOptions; - - directionalDirections[0].set(-1.0F, 0.0F, 0.0F); - directionalColors[0].set(0.0F, 96.0F, 0.0F); - - directionalDirections[1].set(1.0F, 0.0F, 0.0F); - directionalColors[1].set(96.0F, 0.0F, 0.0F); + // TYRA_LOG("Loop!"); } } // namespace Tyra diff --git a/tutorials/02-sprite/Makefile b/tutorials/02-sprite/Makefile new file mode 100644 index 0000000..0ecc73a --- /dev/null +++ b/tutorials/02-sprite/Makefile @@ -0,0 +1,24 @@ +TARGET := tutorial_01.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/02-sprite/bin/.gitignore b/tutorials/02-sprite/bin/.gitignore new file mode 100644 index 0000000..44c5ea8 --- /dev/null +++ b/tutorials/02-sprite/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/02-sprite/inc/tutorial_02.hpp b/tutorials/02-sprite/inc/tutorial_02.hpp new file mode 100644 index 0000000..f30479f --- /dev/null +++ b/tutorials/02-sprite/inc/tutorial_02.hpp @@ -0,0 +1,36 @@ +/* +# _____ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2022, tyra - https://github.com/h4570/tyra +# Licensed under Apache License 2.0 +# Sandro Sobczyński +*/ + +#pragma once + +#include +#include + +namespace Tyra { + +class Tutorial02 : public Game { + public: + Tutorial02(Engine* engine); + ~Tutorial02(); + + void init(); + void loop(); + + private: + void loadTexture(); + void loadSprite(); + + Engine* engine; + + Sprite sprite; + Texture* texture; +}; + +} // namespace Tyra diff --git a/tutorials/02-sprite/obj/.gitignore b/tutorials/02-sprite/obj/.gitignore new file mode 100644 index 0000000..44c5ea8 --- /dev/null +++ b/tutorials/02-sprite/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/02-sprite/res/.gitignore b/tutorials/02-sprite/res/.gitignore new file mode 100644 index 0000000..44c5ea8 --- /dev/null +++ b/tutorials/02-sprite/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/02-sprite/run.ps1 b/tutorials/02-sprite/run.ps1 new file mode 100644 index 0000000..74646cc --- /dev/null +++ b/tutorials/02-sprite/run.ps1 @@ -0,0 +1,4 @@ +$ConfigFile = Join-Path $PSScriptRoot '../../windows-pcsx2.ps1' +. $ConfigFile + +RunPCSX2 diff --git a/tutorials/02-sprite/src/main.cpp b/tutorials/02-sprite/src/main.cpp new file mode 100644 index 0000000..dc470e1 --- /dev/null +++ b/tutorials/02-sprite/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_02.hpp" + +/** + * In this tutorial we will learn how to: + * - Load png file and create texture from it + * - Create sprite class + * - Clear screen and render sprite + */ + +int main() { + Tyra::Engine engine; + Tyra::Tutorial02 game(&engine); + engine.run(&game); + return 0; +} diff --git a/tutorials/02-sprite/src/tutorial_02.cpp b/tutorials/02-sprite/src/tutorial_02.cpp new file mode 100644 index 0000000..6267ede --- /dev/null +++ b/tutorials/02-sprite/src/tutorial_02.cpp @@ -0,0 +1,66 @@ +/* +# _____ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2022, tyra - https://github.com/h4570/tyra +# Licensed under Apache License 2.0 +# Sandro Sobczyński +*/ + +#include +#include "tutorial_02.hpp" + +namespace Tyra { + +Tutorial02::Tutorial02(Engine* t_engine) : engine(t_engine) { + texture = nullptr; +} + +Tutorial02::~Tutorial02() { + if (texture != nullptr) { + engine->renderer.core.texture.repository.free(texture); + } +} + +void Tutorial02::init() { + engine->renderer.setClearScreenColor(Color(32.0F, 32.0F, 32.0F)); + + loadSprite(); + loadTexture(); +} + +void Tutorial02::loop() { + auto& renderer = engine->renderer; + + renderer.beginFrame(); + renderer.renderer2D.render(sprite); + renderer.endFrame(); +} + +void Tutorial02::loadSprite() { + const auto& screenSettings = engine->renderer.core.getSettings(); + + sprite.mode = SpriteMode::MODE_STRETCH; + sprite.size = Vec2(256.0F, 128.0F); + sprite.position = + Vec2(screenSettings.getWidth() / 2.0F - sprite.size.x / 2.0F, + screenSettings.getHeight() / 2.0F - sprite.size.y / 2.0F); + + TYRA_LOG("Sprite created!"); +} + +void Tutorial02::loadTexture() { + auto& renderer = engine->renderer; + auto& rendererCore = renderer.core; + auto& textureRepository = rendererCore.texture.repository; + + auto filepath = FileUtils::fromCwd("tyra.png"); + texture = textureRepository.add(filepath); + + texture->addLink(sprite.id); + + TYRA_LOG("Texture loaded!"); +} + +} // namespace Tyra