diff --git a/tutorials/11-texture-region-repeat/Makefile b/tutorials/11-texture-region-repeat/Makefile new file mode 100644 index 0000000..081fcc6 --- /dev/null +++ b/tutorials/11-texture-region-repeat/Makefile @@ -0,0 +1,24 @@ +TARGET := tutorial_11.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/11-texture-region-repeat/inc/tutorial_11.hpp b/tutorials/11-texture-region-repeat/inc/tutorial_11.hpp new file mode 100644 index 0000000..d63c0bd --- /dev/null +++ b/tutorials/11-texture-region-repeat/inc/tutorial_11.hpp @@ -0,0 +1,58 @@ +/* +# _____ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2024, tyra - https://github.com/h4570/tyra +# Licensed under Apache License 2.0 +# Wellington Carvalho +*/ + +#pragma once + +#include +#include + +namespace Tyra { + +class Tutorial11 : public Game { + public: + Tutorial11(Engine* engine); + ~Tutorial11(); + + void init(); + void loop(); + + private: + void setDrawData(); + void loadBags(); + + void setTextureRegionRepeat(); + void setTextureDefaultWrap(); + + const u8 MAX_TILES = 4; + u8 TILE_COL = 0; + u8 TILE_ROW = 0; + + u8 shouldFlipTextureSettings = false; + float limitTimeToFlip = 2.00f; + float elapsedTime = 0; + + Engine* engine; + + Vec4 cameraPosition, cameraLookAt; + M4x4 translation, rotation, scale, model; + Texture* UVCheckerTex; + + std::array vertices; + std::array colors; + std::array uvMap; + + StaticPipeline stapip; + std::unique_ptr bag; + std::unique_ptr infoBag; + std::unique_ptr colorBag; + std::unique_ptr texBag; +}; + +} // namespace Tyra diff --git a/tutorials/11-texture-region-repeat/run.ps1 b/tutorials/11-texture-region-repeat/run.ps1 new file mode 100644 index 0000000..74646cc --- /dev/null +++ b/tutorials/11-texture-region-repeat/run.ps1 @@ -0,0 +1,4 @@ +$ConfigFile = Join-Path $PSScriptRoot '../../windows-pcsx2.ps1' +. $ConfigFile + +RunPCSX2 diff --git a/tutorials/11-texture-region-repeat/src/main.cpp b/tutorials/11-texture-region-repeat/src/main.cpp new file mode 100644 index 0000000..4518901 --- /dev/null +++ b/tutorials/11-texture-region-repeat/src/main.cpp @@ -0,0 +1,24 @@ +/* +# _____ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2024, tyra - https://github.com/h4570/tyra +# Licensed under Apache License 2.0 +# Wellington Carvalho +*/ + +#include "engine.hpp" +#include "tutorial_11.hpp" + +/** + * In this tutorial we will learn: + * - How to use texture in repeate mode of GS + */ + +int main() { + Tyra::Engine engine; + Tyra::Tutorial11 game(&engine); + engine.run(&game); + return 0; +} diff --git a/tutorials/11-texture-region-repeat/src/tutorial_11.cpp b/tutorials/11-texture-region-repeat/src/tutorial_11.cpp new file mode 100644 index 0000000..03508a7 --- /dev/null +++ b/tutorials/11-texture-region-repeat/src/tutorial_11.cpp @@ -0,0 +1,178 @@ +/* +# _____ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2024, tyra - https://github.com/h4570/tyra +# Licensed under Apache License 2.0 +# Wellington Carvalho +*/ + +#include +#include "tutorial_11.hpp" + +namespace Tyra { + +Tutorial11::Tutorial11(Engine* t_engine) : engine(t_engine) { + translation = M4x4::Identity; + rotation = M4x4::Identity; + scale = M4x4::Identity; + model = M4x4::Identity; + + rotation.rotateY(Math::PI); +} + +Tutorial11::~Tutorial11() {} + +void Tutorial11::init() { + stapip.setRenderer(&engine->renderer.core); + + cameraPosition = Vec4(0.0F, 0.0F, -10.0F); + cameraLookAt.unit(); + + UVCheckerTex = engine->renderer.getTextureRepository().add( + FileUtils::fromCwd("uv_checker.png")); + + setDrawData(); + loadBags(); +} + +void Tutorial11::loop() { + const auto deltaTime = + std::min(1.0f / static_cast(engine->info.getFps()), + static_cast(1.0 / 60.0f)); + elapsedTime += deltaTime; + + if (elapsedTime > limitTimeToFlip) { + elapsedTime -= limitTimeToFlip; + shouldFlipTextureSettings = !shouldFlipTextureSettings; + shouldFlipTextureSettings ? setTextureRegionRepeat() + : setTextureDefaultWrap(); + + // Update texture packet info after change wrap settings + engine->renderer.core.texture.updateTextureInfo(UVCheckerTex); + } + + model = translation * rotation * scale; + + engine->renderer.beginFrame(CameraInfo3D(&cameraPosition, &cameraLookAt)); + { + engine->renderer.renderer3D.usePipeline(stapip); + + /** + * Lets draw manually via "bags". + * You can do the same thing with dynamic pipeline. + */ + stapip.core.render(bag.get()); + } + engine->renderer.endFrame(); +} + +void Tutorial11::setDrawData() { + vertices = { + // Tri 1 + Vec4(-3.0F, -3.0F, 0.0F), + Vec4(3.0F, -3.0F, 0.0F), + Vec4(-3.0F, 3.0F, 0.0F), + + // Tri 2 + Vec4(3.0F, -3.0F, 0.0F), + Vec4(-3.0F, 3.0F, 0.0F), + Vec4(3.0F, 3.0F, 0.0F), + }; + + colors = { + Color(128.0F, 128.0F, 128.0F), Color(128.0F, 128.0F, 128.0F), + Color(128.0F, 128.0F, 128.0F), Color(128.0F, 128.0F, 128.0F), + Color(128.0F, 128.0F, 128.0F), Color(128.0F, 128.0F, 128.0F), + }; + + setTextureDefaultWrap(); +} + +void Tutorial11::setTextureDefaultWrap() { + uvMap = {Vec4(0.0f, 1.0F, 1.0F, 0.0f), Vec4(0.0f + 1, 1.0F, 1.0F, 0.0f), + Vec4(0.0f, 0.0f, 1.0F, 0.0f), + + Vec4(0.0f + 1, 1.0F, 1.0F, 0.0f), Vec4(0.0f, 0.0f, 1.0F, 0.0f), + Vec4(0.0f + 1.0F, 0.0f, 1.0F, 0.0f)}; + + TYRA_LOG("Reseting texture wrap settings"); + UVCheckerTex->setDefaultWrapSettings(); +} + +void Tutorial11::setTextureRegionRepeat() { + const float _scale = 1.0f / (float)MAX_TILES; + const Vec4 scale = + Vec4(MAX_TILES > 0 ? _scale * MAX_TILES : _scale, + MAX_TILES > 0 ? _scale * MAX_TILES : _scale, 1.0f, 0.0f); + + uvMap = { + Vec4(TILE_COL, TILE_ROW + 1.0F, 1.0F, 0.0f) * scale, + Vec4(TILE_COL + 1, TILE_ROW + 1.0F, 1.0F, 0.0f) * scale, + Vec4(TILE_COL, TILE_ROW, 1.0F, 0.0f) * scale, + + Vec4(TILE_COL + 1, TILE_ROW + 1.0F, 1.0F, 0.0f) * scale, + Vec4(TILE_COL, TILE_ROW, 1.0F, 0.0f) * scale, + Vec4(TILE_COL + 1.0F, TILE_ROW, 1.0F, 0.0f) * scale, + }; + + const auto tileW = (UVCheckerTex->getWidth() * _scale) - 1; + const auto tileH = (UVCheckerTex->getHeight() * _scale) - 1; + const auto tileU = TILE_COL * tileW + TILE_COL; + const auto tileV = TILE_ROW * tileH + TILE_ROW; + + int minu = tileW; + int minv = tileH; + int maxu = tileU; + int maxv = tileV; + + TYRA_LOG("Changing the texture wraping..."); + UVCheckerTex->setWrapSettings(TextureWrap::RegionRepeat, + TextureWrap::RegionRepeat, minu, minv, maxu, + maxv); + + TILE_COL++; + if (TILE_COL >= MAX_TILES) { + TILE_COL %= MAX_TILES; + TILE_ROW = (TILE_ROW + 1) % MAX_TILES; + } +} + +void Tutorial11::loadBags() { + /** + * Create info bag and fill it with model matrix and shading type. + * Keep rest of the options as default. + */ + infoBag = std::make_unique(); + infoBag->model = &model; + infoBag->shadingType = TyraShadingGouraud; + infoBag->textureMappingType = TyraNearest; + + /** Create colors bag and set data pointer */ + colorBag = std::make_unique(); + colorBag->many = colors.begin(); + + texBag = std::make_unique(); + texBag.get()->texture = UVCheckerTex; + texBag.get()->coordinates = uvMap.data(); + + /** + * Create main bag and set: + * - vertices data + * - vertices count + * - pointers to other bags + * + * You can add here lighting and texture bag as well. + * If you want to have deeper look of this feature, please + * read static_pipeline.cpp code file. + */ + bag = std::make_unique(); + bag->color = colorBag.get(); + bag->texture = texBag.get(); + bag->info = infoBag.get(); + bag->vertices = vertices.begin(); + bag->count = vertices.size(); +} + +} // namespace Tyra