From 989d2702e86805b88e13f14fac15ddbe02400601 Mon Sep 17 00:00:00 2001 From: h4570 Date: Tue, 23 Aug 2022 22:31:07 +0200 Subject: [PATCH] finished tutorial 7 --- ROADMAP.txt | 4 +- engine/inc/renderer/3d/mesh/mesh_material.hpp | 2 +- .../3d/pipeline/dynamic/dynamic_pipeline.hpp | 2 +- .../3d/pipeline/static/static_pipeline.hpp | 2 +- engine/inc/renderer/models/color.hpp | 4 + engine/src/renderer/3d/mesh/mesh_material.cpp | 4 +- .../3d/pipeline/dynamic/dynamic_pipeline.cpp | 7 +- .../3d/pipeline/static/static_pipeline.cpp | 14 +- engine/src/renderer/models/color.cpp | 24 +++ template/02-sprite/Makefile | 24 +++ template/02-sprite/bin/.gitignore | 4 + template/02-sprite/inc/tutorial_02.hpp | 34 +++++ template/02-sprite/obj/.gitignore | 4 + template/02-sprite/res/.gitignore | 4 + template/02-sprite/run.ps1 | 4 + template/02-sprite/src/main.cpp | 26 ++++ template/02-sprite/src/tutorial_02.cpp | 112 ++++++++++++++ tutorials/01-hello/src/tutorial_01.cpp | 2 +- tutorials/05-animation/src/tutorial_05.cpp | 2 +- tutorials/06-audio/inc/tutorial_06.hpp | 2 + tutorials/06-audio/src/tutorial_06.cpp | 27 +++- tutorials/07-lighting/inc/tutorial_07.hpp | 18 +++ tutorials/07-lighting/src/tutorial_07.cpp | 137 +++++++++++++++++- tutorials/08-skybox-debug/src/main.cpp | 1 + 24 files changed, 439 insertions(+), 25 deletions(-) create mode 100644 template/02-sprite/Makefile create mode 100644 template/02-sprite/bin/.gitignore create mode 100644 template/02-sprite/inc/tutorial_02.hpp create mode 100644 template/02-sprite/obj/.gitignore create mode 100644 template/02-sprite/res/.gitignore create mode 100644 template/02-sprite/run.ps1 create mode 100644 template/02-sprite/src/main.cpp create mode 100644 template/02-sprite/src/tutorial_02.cpp diff --git a/ROADMAP.txt b/ROADMAP.txt index a6f2a85..7b10116 100644 --- a/ROADMAP.txt +++ b/ROADMAP.txt @@ -1,11 +1,10 @@ ------------ Tyra's v2.0 roadmap to publish on GitHub ------------ -- [Tutorials] 5 -- [Tutorials] 6 - [Tutorials] 7 - [Tutorials] 8 - [Tutorials] 9. +- [Renderer] Check ee clipping on de_dust2, add decimate to de_dust2? - [General] Check all left TODOs -> Github issues - [General] Readme Credits: clipping, obj loader - [Video] How to setup environment @@ -19,7 +18,6 @@ - [Demo] BBox constructors - [General] Add cpp lint checker in GitHub / static code analysis - [General] Smart pointers and std::array instead of raw pointers -- [Renderer] Check ee clipping on de_dust2, add decimate to de_dust2? - [General] Control generated id to avoid duplication. Maybe Just increment from 0? Add interface IIdentificable? - [renderer] fog - [General] CI in Github via docker image diff --git a/engine/inc/renderer/3d/mesh/mesh_material.hpp b/engine/inc/renderer/3d/mesh/mesh_material.hpp index 88cfc18..2d8b5e8 100644 --- a/engine/inc/renderer/3d/mesh/mesh_material.hpp +++ b/engine/inc/renderer/3d/mesh/mesh_material.hpp @@ -22,7 +22,7 @@ class MeshMaterial { explicit MeshMaterial(const MeshMaterial& material); ~MeshMaterial(); - u8 isMother, lightmapFlag; + bool isMother, lightmapFlag; u32 id; diff --git a/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp b/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp index 725f9df..9fd03bd 100644 --- a/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp +++ b/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp @@ -49,7 +49,7 @@ class DynamicPipeline : public Renderer3DPipeline { */ void render(const DynamicMesh* mesh); void render(const DynamicMesh* mesh, const DynPipOptions& options); - void render(const DynamicMesh* mesh, const DynPipOptions* options = nullptr); + void render(const DynamicMesh* mesh, const DynPipOptions* options); private: RendererCore* rendererCore; diff --git a/engine/inc/renderer/3d/pipeline/static/static_pipeline.hpp b/engine/inc/renderer/3d/pipeline/static/static_pipeline.hpp index fdcd96a..859fe9b 100644 --- a/engine/inc/renderer/3d/pipeline/static/static_pipeline.hpp +++ b/engine/inc/renderer/3d/pipeline/static/static_pipeline.hpp @@ -48,7 +48,7 @@ class StaticPipeline : public Renderer3DPipeline { */ void render(const StaticMesh* mesh); void render(const StaticMesh* mesh, const StaPipOptions& options); - void render(const StaticMesh* mesh, const StaPipOptions* options = nullptr); + void render(const StaticMesh* mesh, const StaPipOptions* options); private: StapipBagBBoxesCacher cacher; diff --git a/engine/inc/renderer/models/color.hpp b/engine/inc/renderer/models/color.hpp index 0799c8e..069951c 100644 --- a/engine/inc/renderer/models/color.hpp +++ b/engine/inc/renderer/models/color.hpp @@ -53,6 +53,10 @@ class Color { void operator-=(const float& v); void operator*=(const float& v); void operator/=(const float& v); + Color operator+(const float& v) const; + Color operator-(const float& v) const; + Color operator*(const float& v) const; + Color operator/(const float& v) const; inline void set(const Color& v) { copy(this, v.rgba); } inline void set(const float* v) { copy(this, v); } diff --git a/engine/src/renderer/3d/mesh/mesh_material.cpp b/engine/src/renderer/3d/mesh/mesh_material.cpp index 4d84cef..79d83ed 100644 --- a/engine/src/renderer/3d/mesh/mesh_material.cpp +++ b/engine/src/renderer/3d/mesh/mesh_material.cpp @@ -30,11 +30,11 @@ MeshMaterial::MeshMaterial(const MeshBuilderData& data, id = rand() % 1000000; if (data.lightMapEnabled) { - lightmapFlag = false; + lightmapFlag = true; TYRA_ASSERT(material->frames[0]->colors != nullptr, "Colors faces are required"); } else { - lightmapFlag = true; + lightmapFlag = false; } ambient.set(material->ambient); diff --git a/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp b/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp index 2315dc8..35983d0 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp @@ -112,9 +112,10 @@ void DynamicPipeline::render(const DynamicMesh* mesh, auto* 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?"); + 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]; diff --git a/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp b/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp index f87824c..240c49d 100644 --- a/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp +++ b/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp @@ -96,7 +96,7 @@ void StaticPipeline::render(const StaticMesh* mesh, u32 maxVertCount = core.getMaxVertCountByBag(&bag); StaPipBagPackagesBBox* bbox = nullptr; - if (bag.info->frustumCulling == PipelineFrustumCulling_Precise) { + if (bag.info->frustumCulling == PipelineInfoBagFrustumCulling_Precise) { bbox = cacher.getBBoxesByMesh(materialFrame, maxVertCount); } @@ -143,9 +143,9 @@ StaPipColorBag* StaticPipeline::getColorBag( auto* result = new StaPipColorBag(); if (material->lightmapFlag) { - result->single = &material->ambient; - } else { result->many = materialFrame->colors; + } else { + result->single = &material->ambient; } return result; @@ -160,10 +160,10 @@ StaPipTextureBag* StaticPipeline::getTextureBag( result->texture = rendererCore->texture.repository.getByMeshMaterialId(material->id); - TYRA_ASSERT( - result->texture, "Texture for material: ", material->name, - "Id: ", material->id, - "Was not found in texture repository! Did you forget to add texture?"); + TYRA_ASSERT(result->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?"); result->coordinates = materialFrame->textureCoords; diff --git a/engine/src/renderer/models/color.cpp b/engine/src/renderer/models/color.cpp index a86203e..5723a12 100644 --- a/engine/src/renderer/models/color.cpp +++ b/engine/src/renderer/models/color.cpp @@ -47,6 +47,30 @@ void Color::operator/=(const float& v) { a /= v; } +Color Color::operator+(const float& v) const { + Color result = *this; + result += v; + return result; +} + +Color Color::operator-(const float& v) const { + Color result = *this; + result -= v; + return result; +} + +Color Color::operator*(const float& v) const { + Color result = *this; + result *= v; + return result; +} + +Color Color::operator/(const float& v) const { + Color result = *this; + result /= v; + return result; +} + void Color::set(const float& t_r, const float& t_g, const float& t_b, const float& t_a) { r = t_r; diff --git a/template/02-sprite/Makefile b/template/02-sprite/Makefile new file mode 100644 index 0000000..7c46faf --- /dev/null +++ b/template/02-sprite/Makefile @@ -0,0 +1,24 @@ +TARGET := tutorial_02.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/template/02-sprite/bin/.gitignore b/template/02-sprite/bin/.gitignore new file mode 100644 index 0000000..44c5ea8 --- /dev/null +++ b/template/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/template/02-sprite/inc/tutorial_02.hpp b/template/02-sprite/inc/tutorial_02.hpp new file mode 100644 index 0000000..34ef153 --- /dev/null +++ b/template/02-sprite/inc/tutorial_02.hpp @@ -0,0 +1,34 @@ +/* +# _____ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2022, tyra - https://github.com/h4570/tyra +# Licensed under Apache License 2.0 +# Sandro Sobczyński +*/ + +#pragma once + +#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; +}; + +} // namespace Tyra diff --git a/template/02-sprite/obj/.gitignore b/template/02-sprite/obj/.gitignore new file mode 100644 index 0000000..44c5ea8 --- /dev/null +++ b/template/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/template/02-sprite/res/.gitignore b/template/02-sprite/res/.gitignore new file mode 100644 index 0000000..44c5ea8 --- /dev/null +++ b/template/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/template/02-sprite/run.ps1 b/template/02-sprite/run.ps1 new file mode 100644 index 0000000..74646cc --- /dev/null +++ b/template/02-sprite/run.ps1 @@ -0,0 +1,4 @@ +$ConfigFile = Join-Path $PSScriptRoot '../../windows-pcsx2.ps1' +. $ConfigFile + +RunPCSX2 diff --git a/template/02-sprite/src/main.cpp b/template/02-sprite/src/main.cpp new file mode 100644 index 0000000..dc470e1 --- /dev/null +++ b/template/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/template/02-sprite/src/tutorial_02.cpp b/template/02-sprite/src/tutorial_02.cpp new file mode 100644 index 0000000..f4066f6 --- /dev/null +++ b/template/02-sprite/src/tutorial_02.cpp @@ -0,0 +1,112 @@ +/* +# _____ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# 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) {} + +Tutorial02::~Tutorial02() { + engine->renderer.getTextureRepository().freeBySprite(sprite); +} + +void Tutorial02::init() { + engine->renderer.setClearScreenColor(Color(32.0F, 32.0F, 32.0F)); + + /** Sprite contains rectangle information. */ + loadSprite(); + + /** Texture contains png image. */ + loadTexture(); +} + +void Tutorial02::loop() { + auto& renderer = engine->renderer; + + /** Begin frame will clear our screen. */ + renderer.beginFrame(); + + /** Render sprite. */ + renderer.renderer2D.render(sprite); + + /** End frame will perform vsync. */ + renderer.endFrame(); +} + +void Tutorial02::loadSprite() { + const auto& screenSettings = engine->renderer.core.getSettings(); + + sprite.mode = SpriteMode::MODE_STRETCH; + + /** Let's scale it down */ + sprite.size = Vec2(256.0F, 128.0F); + + /** Set it in screen center */ + 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() { + /** + * Renderer has high layer functions, + * which allows to render: + * - Sprite (2D) + * - Mesh (3D) + * + * It uses ONLY low layer functions which are in renderer.core + */ + auto& renderer = engine->renderer; + + /** + * TextureRepository is a repository of textures. + * It is a singleton class, with all game textures. + * We are linking these textures with sprite's (2D) and mesh (3D) materials. + */ + auto& textureRepository = renderer.getTextureRepository(); + + /** + * Texture is stored in "res" directory. + * Content of "res" directory is automatically copied into + * "bin" directory, which contains our final game. + * + * File utils automatically add's device prefix to the path, + * based on current working directory. + * + * In PS2 world: + * - USB has a "mass:" prefix + * - Our PC in PS2Link has a "host:" prefix + * - Our PC in PCSX2 has a "host:" prefix + */ + auto filepath = FileUtils::fromCwd("tyra.png"); + + /** + * Tyra supports following PNG formats: + * 32bpp (RGBA) + * 24bpp (RGB) + * 8bpp, palletized (RGBA) + * 4bpp, palletized (RGBA) + * + * 8bpp and 4bpp are the fastest. + * All of these formats can be easily exported via GIMP. + */ + auto* texture = textureRepository.add(filepath); + + /** Let's assign this texture to sprite. */ + texture->addLink(sprite.id); + + TYRA_LOG("Texture loaded!"); +} + +} // namespace Tyra diff --git a/tutorials/01-hello/src/tutorial_01.cpp b/tutorials/01-hello/src/tutorial_01.cpp index 2b08a15..84d92d4 100644 --- a/tutorials/01-hello/src/tutorial_01.cpp +++ b/tutorials/01-hello/src/tutorial_01.cpp @@ -36,7 +36,7 @@ void Tutorial01::init() { * Every function has infinite number of various-typed arguments. */ - short positiveNumber = -1; // Change it to -1 and see what happen! + short positiveNumber = 1; // Change it to -1 and see what happen! TYRA_LOG("Hello world!"); diff --git a/tutorials/05-animation/src/tutorial_05.cpp b/tutorials/05-animation/src/tutorial_05.cpp index b0ae989..6394a0f 100644 --- a/tutorials/05-animation/src/tutorial_05.cpp +++ b/tutorials/05-animation/src/tutorial_05.cpp @@ -35,7 +35,7 @@ void Tutorial05::loop() { { engine->renderer.renderer3D.usePipeline(dynpip); - dynpip.render(zombieMesh.get(), renderOptions); + dynpip.render(zombieMesh.get()); dynpip.render(warriorMesh.get(), renderOptions); } engine->renderer.endFrame(); diff --git a/tutorials/06-audio/inc/tutorial_06.hpp b/tutorials/06-audio/inc/tutorial_06.hpp index 6082c44..1e33532 100644 --- a/tutorials/06-audio/inc/tutorial_06.hpp +++ b/tutorials/06-audio/inc/tutorial_06.hpp @@ -24,6 +24,8 @@ class Tutorial06 : public Game { private: Engine* engine; + + audsrv_adpcm_t* sample; }; } // namespace Tyra diff --git a/tutorials/06-audio/src/tutorial_06.cpp b/tutorials/06-audio/src/tutorial_06.cpp index fd166d5..bcdbbee 100644 --- a/tutorials/06-audio/src/tutorial_06.cpp +++ b/tutorials/06-audio/src/tutorial_06.cpp @@ -17,8 +17,31 @@ Tutorial06::Tutorial06(Engine* t_engine) : engine(t_engine) {} Tutorial06::~Tutorial06() {} -void Tutorial06::init() {} +void Tutorial06::init() { + /** 16bit 22kHz wav file */ + engine->audio.song.load(FileUtils::fromCwd("kayah-supermenka.wav")); + engine->audio.song.inLoop = true; + engine->audio.song.setVolume(60); + engine->audio.song.play(); -void Tutorial06::loop() {} + /** 16bit 22kHz wav file converted to adpcm sample */ + sample = engine->audio.adpcm.load(FileUtils::fromCwd("shoot.adpcm")); + /** Set volume for channel 0 */ + engine->audio.adpcm.setVolume(30, 0); +} + +void Tutorial06::loop() { + engine->renderer.beginFrame(); + { + /** Play ADPCM if (X) button is clicked! */ + if (engine->pad.getClicked().Cross) { + /** Try to play sample in channel 0 */ + if (engine->audio.adpcm.tryPlay(sample, 0) == ADPCM_CHANNEL_USED) { + TYRA_WARN("Channel is busy, please use another channel!"); + } + } + } + engine->renderer.endFrame(); +} } // namespace Tyra diff --git a/tutorials/07-lighting/inc/tutorial_07.hpp b/tutorials/07-lighting/inc/tutorial_07.hpp index b3e9639..ae2dcd1 100644 --- a/tutorials/07-lighting/inc/tutorial_07.hpp +++ b/tutorials/07-lighting/inc/tutorial_07.hpp @@ -23,7 +23,25 @@ class Tutorial07 : public Game { void loop(); private: + void loadMeshWithLightmap(); + void setDirectionalLightsOptions(); + void setLightmap(MeshBuilderData* data); + void switchBetweenLightmapAndDirectional(); + + int counter, switcher; + Engine* engine; + + Vec4 cameraPosition, cameraLookAt; + + StaticPipeline stapip; + StaPipOptions renderOptions; + std::unique_ptr mesh; + + PipelineLightingOptions renderLightingOptions; + Color directionalAmbientColor; + std::array directionalColors; + std::array directionalDirections; }; } // namespace Tyra diff --git a/tutorials/07-lighting/src/tutorial_07.cpp b/tutorials/07-lighting/src/tutorial_07.cpp index 2878ccc..7b4b6db 100644 --- a/tutorials/07-lighting/src/tutorial_07.cpp +++ b/tutorials/07-lighting/src/tutorial_07.cpp @@ -13,12 +13,143 @@ namespace Tyra { -Tutorial07::Tutorial07(Engine* t_engine) : engine(t_engine) {} +Tutorial07::Tutorial07(Engine* t_engine) : engine(t_engine) { + counter = 101; + switcher = 0; +} Tutorial07::~Tutorial07() {} -void Tutorial07::init() {} +void Tutorial07::init() { + engine->renderer.setClearScreenColor(Color(32.0F, 32.0F, 32.0F)); -void Tutorial07::loop() {} + stapip.setRenderer(&engine->renderer.core); + + cameraPosition = Vec4(0.0F, 0.0F, -10.0F); + cameraLookAt.unit(); + + /** + * Directional lights are dynamic lights with infinite range. + * + * Lightmap is a fast, pregenerated lightmap for a mesh. + * It is very useful for meshes like terrain, buildings, etc.. + * + * Lightmap in PS2 world is done by old school color-per-vertex. + */ + + loadMeshWithLightmap(); + setDirectionalLightsOptions(); +} + +void Tutorial07::loop() { + switchBetweenLightmapAndDirectional(); + + /** Rotate the mesh to see the effect static vs dynamic lights */ + mesh->rotation.rotateY(0.05F); + + engine->renderer.beginFrame(CameraInfo3D(&cameraPosition, &cameraLookAt)); + { + engine->renderer.renderer3D.usePipeline(stapip); + + /** Switch between dynamic directional lights / static lightmap */ + if (switcher == 0) { + stapip.render(mesh.get(), renderOptions); + } else { + stapip.render(mesh.get()); + } + } + engine->renderer.endFrame(); +} + +void Tutorial07::loadMeshWithLightmap() { + ObjLoaderOptions options; + options.scale = 2.0F; + + 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. + */ + data->textureCoordsEnabled = false; + + /** Lets add lightmap manually */ + setLightmap(data.get()); + + mesh = std::make_unique(data.get()); + mesh->translation.translateY(-1.0F); + mesh->rotation.rotateX(1.0F); +} + +void Tutorial07::setDirectionalLightsOptions() { + // Set ambient color + directionalAmbientColor.set(16.0F, 32.0F, 16.0F); + + // Reset colors and directions + for (int i = 0; i < 3; i++) { + directionalColors[i].set(0.0F, 0.0F, 0.0F, 1.0F); + directionalDirections[i].set(1.0F, 1.0F, 1.0F, 1.0F); + } + + // Set light and direction 1 + directionalDirections[0].set(-1.0F, 0.3F, 0.3F); + directionalColors[0].set(16.0F, 16.0F, 96.0F); + + // Set light and direction 2 + directionalDirections[1].set(0.0F, -1.0F, 1.0F); + directionalColors[1].set(96.0F, 16.0F, 16.0F); + + // Set render options + renderLightingOptions.ambientColor = &directionalAmbientColor; + renderLightingOptions.directionalColors = directionalColors.begin(); + renderLightingOptions.directionalDirections = directionalDirections.begin(); + renderOptions.shadingType = TyraShadingGouraud; + renderOptions.blendingEnabled = true; + renderOptions.lighting = &renderLightingOptions; +} + +void Tutorial07::setLightmap(MeshBuilderData* data) { + /** Information for mesh, that data has lightmap */ + data->lightMapEnabled = true; + + /** This object file has only 1 material */ + auto* material = data->materials[0]; + + /** Static mesh so 1 frame */ + auto* frame = material->frames[0]; + + /** + * You can load your pregenerated lightmap here. + * In tutorial we will generate some random lightmap. + * + * Dont worry about dynamic allocation, + * it will be handled by Mesh class. + */ + frame->colors = new Color[frame->count]; + for (u32 i = 0; i < frame->count; i++) { + auto randomLight = 0.1F + ((2.0F + frame->vertices[i].x) / 4.0F); + frame->colors[i] = material->ambient * randomLight; + frame->colors[i].a = 128.0F; + } +} + +void Tutorial07::switchBetweenLightmapAndDirectional() { + if (counter++ > 100) { + counter = 0; + switcher = !switcher; + + auto* material = mesh->materials[0]; + + if (switcher == 0) { + material->lightmapFlag = false; + TYRA_LOG("Directional lights!"); + } else { + material->lightmapFlag = true; + TYRA_LOG("Lightmap!"); + } + } +} } // namespace Tyra diff --git a/tutorials/08-skybox-debug/src/main.cpp b/tutorials/08-skybox-debug/src/main.cpp index d1eff22..e0d760a 100644 --- a/tutorials/08-skybox-debug/src/main.cpp +++ b/tutorials/08-skybox-debug/src/main.cpp @@ -15,6 +15,7 @@ * In this tutorial we will learn: * - How to render skybox and what is "ALLPASS" rendering method * - How to render debug lines and bboxes + * - How to get available RAM and FPS count */ int main() {