From 0a024e745fafc856a01eb1c05f3960328667d7d2 Mon Sep 17 00:00:00 2001 From: h4570 Date: Wed, 3 Aug 2022 10:37:27 +0200 Subject: [PATCH] renderer cleanup, demo changes --- ROADMAP.txt | 1 + demo/inc/states/game/enemy/enemy.hpp | 42 ++++++++++ demo/inc/states/game/game_state.hpp | 2 + demo/inc/states/game/player/player.hpp | 3 +- demo/src/states/game/enemy/enemy.cpp | 82 +++++++++++++++++++ demo/src/states/game/game_state.cpp | 20 ++--- demo/src/states/game/player/player.cpp | 11 +-- demo/src/states/game/player/weapon.cpp | 4 + demo/src/states/game/skybox/skybox.cpp | 1 - demo/src/states/game/terrain/terrain.cpp | 6 +- .../pipeline/dynamic/core/bag/dynpip_bag.hpp | 4 +- .../dynamic/core/bag/dynpip_info_bag.hpp} | 17 ++-- .../3d/pipeline/dynamic/core/dynpip_core.hpp | 8 +- .../3d/pipeline/dynamic/dynamic_pipeline.hpp | 12 ++- .../pipeline/shared/bag/pipeline_info_bag.hpp | 34 +++++--- .../bag/pipeline_info_bag_frustum_culling.hpp | 22 +++++ .../3d/pipeline/shared/pipeline_options.hpp | 2 +- .../pipeline/static/core/bag/stapip_bag.hpp | 4 +- .../static/core/bag/stapip_info_bag.hpp | 41 ++++++++++ .../3d/pipeline/static/core/stapip_core.hpp | 3 +- .../3d/pipeline/static/static_pipeline.hpp | 2 +- engine/src/loaders/3d/md2/md2_loader.cpp | 3 - .../src/loaders/3d/tyrobj/tyrobj_loader.cpp | 3 +- .../3d/pipeline/dynamic/core/dynpip_core.cpp | 11 +-- .../3d/pipeline/dynamic/dynamic_pipeline.cpp | 69 ++++++++-------- .../3d/pipeline/static/core/stapip_core.cpp | 12 +-- .../3d/pipeline/static/static_pipeline.cpp | 59 +++++++------ 27 files changed, 329 insertions(+), 149 deletions(-) create mode 100644 demo/inc/states/game/enemy/enemy.hpp create mode 100644 demo/src/states/game/enemy/enemy.cpp rename engine/{src/renderer/3d/pipeline/shared/bag/pipeline_info_bag.cpp => inc/renderer/3d/pipeline/dynamic/core/bag/dynpip_info_bag.hpp} (61%) create mode 100644 engine/inc/renderer/3d/pipeline/shared/bag/pipeline_info_bag_frustum_culling.hpp create mode 100644 engine/inc/renderer/3d/pipeline/static/core/bag/stapip_info_bag.hpp diff --git a/ROADMAP.txt b/ROADMAP.txt index e7e68d2..d24cb33 100644 --- a/ROADMAP.txt +++ b/ROADMAP.txt @@ -35,6 +35,7 @@ because Mesh rendering uses only core.render() - [3D] Add drawBBox(x, y , color, size) - [File] Async file loading - [tyrobj] Add multicolor support to tyrobj +- [Tyrobj] Improve obj importing for multiple usemtl with same names - [Renderer] Interlacing - [General] Add cpp lint checker in GitHub - [General] Control generated id to avoid duplication. Maybe Just increment from 0? Add interface IIdentificable? diff --git a/demo/inc/states/game/enemy/enemy.hpp b/demo/inc/states/game/enemy/enemy.hpp new file mode 100644 index 0000000..82251df --- /dev/null +++ b/demo/inc/states/game/enemy/enemy.hpp @@ -0,0 +1,42 @@ +/* +# ______ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2022, tyra - https://github.com/h4570/tyra +# Licenced under Apache License 2.0 +# Sandro Sobczyński +*/ + +#pragma once + +#include +#include +#include "states/game/renderer/renderer_dynamic_pair.hpp" +#include + +using Tyra::DynamicMesh; +using Tyra::DynPipOptions; +using Tyra::Renderer; +using Tyra::TextureRepository; +using Tyra::Vec4; + +namespace Demo { + +class Enemy { + public: + Enemy(TextureRepository* repo); + ~Enemy(); + + DynamicMesh* bodyMesh; + DynamicMesh* gunMesh; + DynPipOptions* options; + std::vector pairs; + + void update(const Vec4& playerPosition); + + private: + void allocateOptions(); +}; + +} // namespace Demo diff --git a/demo/inc/states/game/game_state.hpp b/demo/inc/states/game/game_state.hpp index bfc8542..7785c2c 100644 --- a/demo/inc/states/game/game_state.hpp +++ b/demo/inc/states/game/game_state.hpp @@ -17,6 +17,7 @@ #include "./terrain/terrain.hpp" #include "./skybox/skybox.hpp" #include "./debug_object.hpp" +#include "./enemy/enemy.hpp" namespace Demo { @@ -44,6 +45,7 @@ class GameState : public State { GameRenderer renderer; Player* player; + Enemy* enemy; Terrain* terrain; Skybox* skybox; DebugObject* dbgObj; diff --git a/demo/inc/states/game/player/player.hpp b/demo/inc/states/game/player/player.hpp index 9c797af..3cb2736 100644 --- a/demo/inc/states/game/player/player.hpp +++ b/demo/inc/states/game/player/player.hpp @@ -30,8 +30,7 @@ class Player { const Vec4& getPosition() const { return position; } CameraInfo3D getCameraInfo() { return camera.getCameraInfo(); } - std::vector staticPairs; - std::vector dynamicPairs; + RendererStaticPair* pair; void update(const float& terrainHeight); diff --git a/demo/src/states/game/enemy/enemy.cpp b/demo/src/states/game/enemy/enemy.cpp new file mode 100644 index 0000000..588b432 --- /dev/null +++ b/demo/src/states/game/enemy/enemy.cpp @@ -0,0 +1,82 @@ +/* +# ______ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2022, tyra - https://github.com/h4570/tyra +# Licenced under Apache License 2.0 +# Sandro Sobczyński +*/ + +#include "states/game/enemy/enemy.hpp" +#include +#include + +using Tyra::FileUtils; +using Tyra::TyrobjLoader; + +namespace Demo { + +Enemy::Enemy(TextureRepository* repo) { + TyrobjLoader loader; + + auto* bodyData = loader.load( + FileUtils::fromCwd("game/models/soldier/soldier.obj"), 4, 30.0F, true); + bodyData->normalsEnabled = false; + bodyMesh = new DynamicMesh(*bodyData); + + TYRA_LOG("First vertex: ", bodyData->frames[0]->vertices[0].getPrint()); + TYRA_LOG("Last vertex: ", + bodyData->frames[0] + ->vertices[bodyData->frames[0]->verticesCount - 1] + .getPrint()); + + TYRA_LOG("First index: ", bodyData->materials[0]->vertexFaces[0]); + TYRA_LOG( + "Last index: ", + bodyData->materials[0]->vertexFaces[bodyData->materials[0]->count - 1]); + + delete bodyData; + + bodyMesh->getMaterial(0)->color.r = 16.0F; + bodyMesh->getMaterial(0)->color.g = 16.0F; + bodyMesh->getMaterial(0)->color.b = 16.0F; + + bodyMesh->playAnimation(0, bodyMesh->getFramesCount() - 1); + bodyMesh->setAnimSpeed(0.15F); + + repo->addByMesh(bodyMesh, FileUtils::fromCwd("game/models/soldier/"), "png"); + + // auto* headData = loader.load( + // FileUtils::fromCwd("game/models/soldier/head.md2"), scale, true); + // headData->normalsEnabled = false; + // headMesh = new DynamicMesh(*headData); + // delete headData; + + // headMesh->getMaterial(0)->color.r = 16.0F; + // headMesh->getMaterial(0)->color.g = 16.0F; + // headMesh->getMaterial(0)->color.b = 16.0F; + + // repo->addByMesh(headMesh, FileUtils::fromCwd("game/models/soldier/"), + // "png"); + + allocateOptions(); + + pairs.push_back(new RendererDynamicPair{bodyMesh, options}); + // pairs.push_back(new RendererDynamicPair{gunMesh, options}); +} + +Enemy::~Enemy() { + delete bodyMesh; + // delete gunMesh; + delete options; + for (auto* pair : pairs) { + delete pair; + } +} + +void Enemy::update(const Vec4& playerPosition) { bodyMesh->animate(); } + +void Enemy::allocateOptions() { options = new DynPipOptions(); } + +} // namespace Demo diff --git a/demo/src/states/game/game_state.cpp b/demo/src/states/game/game_state.cpp index 7512ad9..70dcccd 100644 --- a/demo/src/states/game/game_state.cpp +++ b/demo/src/states/game/game_state.cpp @@ -28,10 +28,12 @@ void GameState::onStart() { engine->audio.stopSong(); + auto* repository = &engine->renderer.core.texture.repository; player = new Player(engine); - terrain = new Terrain(&engine->renderer.core.texture.repository); - skybox = new Skybox(&engine->renderer.core.texture.repository); - dbgObj = new DebugObject(&engine->renderer.core.texture.repository); + enemy = new Enemy(repository); + terrain = new Terrain(repository); + skybox = new Skybox(repository); + dbgObj = new DebugObject(repository); initialized = true; } @@ -40,6 +42,7 @@ GlobalStateType GameState::onFinish() { if (!initialized) return STATE_EXIT; delete player; + delete enemy; delete terrain; delete skybox; delete dbgObj; @@ -54,23 +57,20 @@ void GameState::update() { fpsChecker = 0; } - // TODO: Get next player position and calculate all stuf for NEXT position - // (not current!) - // TODO: Implement collision skybox->update(player->getPosition()); auto cameraInfo = player->getCameraInfo(); engine->renderer.beginFrame(cameraInfo); + dbgObj->setPosition(*cameraInfo.looksAt); float terrainHeight = terrain->getHeightOffset(player->getPosition()); player->update(terrainHeight); - - dbgObj->setPosition(*cameraInfo.looksAt); + enemy->update(player->getPosition()); renderer.clear(); { renderer.add(skybox->pair); - renderer.add(player->staticPairs); - renderer.add(player->dynamicPairs); + renderer.add(player->pair); + renderer.add(enemy->pairs); renderer.add(terrain->pair); renderer.add(dbgObj->pair); } diff --git a/demo/src/states/game/player/player.cpp b/demo/src/states/game/player/player.cpp index 365c260..bab95f0 100644 --- a/demo/src/states/game/player/player.cpp +++ b/demo/src/states/game/player/player.cpp @@ -16,21 +16,14 @@ Player::Player(Engine* engine) : position(0.0F), weapon(&engine->renderer.core.texture.repository), camera(&engine->pad) { - staticPairs.push_back(new RendererStaticPair{weapon.mesh, weapon.options}); + pair = new RendererStaticPair{weapon.mesh, weapon.options}; pad = &engine->pad; position = Vec4(3.0F, 50.0F, 0.0F); camera.lookAt = Vec4(0.0F, 0.0F, -30.0F); speed = 2.0F; } -Player::~Player() { - for (auto pair : staticPairs) { - delete pair; - } - for (auto pair : dynamicPairs) { - delete pair; - } -} +Player::~Player() { delete pair; } void Player::update(const float& terrainHeight) { handlePlayerPosition(terrainHeight); diff --git a/demo/src/states/game/player/weapon.cpp b/demo/src/states/game/player/weapon.cpp index c97b53a..8aeab03 100644 --- a/demo/src/states/game/player/weapon.cpp +++ b/demo/src/states/game/player/weapon.cpp @@ -25,6 +25,10 @@ Weapon::Weapon(TextureRepository* repo) { mesh = new StaticMesh(*data); delete data; + mesh->getMaterial(0)->color.r = 64.0F; + mesh->getMaterial(0)->color.g = 64.0F; + mesh->getMaterial(0)->color.b = 64.0F; + mesh->translation.translateX(2.85F); mesh->translation.translateY(-3.40F); mesh->translation.translateZ(-10.50F); diff --git a/demo/src/states/game/skybox/skybox.cpp b/demo/src/states/game/skybox/skybox.cpp index 05c8767..8048f6b 100644 --- a/demo/src/states/game/skybox/skybox.cpp +++ b/demo/src/states/game/skybox/skybox.cpp @@ -27,7 +27,6 @@ Skybox::Skybox(TextureRepository* repo) { for (u32 i = 0; i < mesh->getMaterialsCount(); i++) { auto* material = mesh->getMaterial(i); - material->print(); material->color.r = 16.0F; material->color.g = 16.0F; material->color.b = 16.0F; diff --git a/demo/src/states/game/terrain/terrain.cpp b/demo/src/states/game/terrain/terrain.cpp index 8f3fa06..f1d1a07 100644 --- a/demo/src/states/game/terrain/terrain.cpp +++ b/demo/src/states/game/terrain/terrain.cpp @@ -27,9 +27,9 @@ Terrain::Terrain(TextureRepository* repo) FileUtils::fromCwd("game/models/terrain/terrain.obj"), 1, 25.0F, true); data->normalsEnabled = false; mesh = new StaticMesh(*data); - mesh->getMaterial(0)->color.r = 96.0F; - mesh->getMaterial(0)->color.g = 96.0F; - mesh->getMaterial(0)->color.b = 96.0F; + mesh->getMaterial(0)->color.r = 32.0F; + mesh->getMaterial(0)->color.g = 32.0F; + mesh->getMaterial(0)->color.b = 32.0F; delete data; repo->addByMesh(mesh, FileUtils::fromCwd("game/models/terrain/"), "png"); diff --git a/engine/inc/renderer/3d/pipeline/dynamic/core/bag/dynpip_bag.hpp b/engine/inc/renderer/3d/pipeline/dynamic/core/bag/dynpip_bag.hpp index 0b71e26..c5e3766 100644 --- a/engine/inc/renderer/3d/pipeline/dynamic/core/bag/dynpip_bag.hpp +++ b/engine/inc/renderer/3d/pipeline/dynamic/core/bag/dynpip_bag.hpp @@ -12,7 +12,7 @@ #include "math/vec4.hpp" -#include "renderer/3d/pipeline/shared/bag/pipeline_info_bag.hpp" +#include "./dynpip_info_bag.hpp" #include "./dynpip_color_bag.hpp" #include "./dynpip_lighting_bag.hpp" #include "./dynpip_texture_bag.hpp" @@ -31,7 +31,7 @@ class DynPipBag { ~DynPipBag(); /** Mandatory. Object info. */ - PipelineInfoBag* info; + DynPipInfoBag* info; /** Mandatory. Object color(s). */ DynPipColorBag* color; diff --git a/engine/src/renderer/3d/pipeline/shared/bag/pipeline_info_bag.cpp b/engine/inc/renderer/3d/pipeline/dynamic/core/bag/dynpip_info_bag.hpp similarity index 61% rename from engine/src/renderer/3d/pipeline/shared/bag/pipeline_info_bag.cpp rename to engine/inc/renderer/3d/pipeline/dynamic/core/bag/dynpip_info_bag.hpp index 17300c9..d03094b 100644 --- a/engine/src/renderer/3d/pipeline/shared/bag/pipeline_info_bag.cpp +++ b/engine/inc/renderer/3d/pipeline/dynamic/core/bag/dynpip_info_bag.hpp @@ -8,19 +8,16 @@ # Sandro Sobczyński */ +#pragma once + #include "renderer/3d/pipeline/shared/bag/pipeline_info_bag.hpp" namespace Tyra { -PipelineInfoBag::PipelineInfoBag() { - shadingType = TyraShadingFlat; - transformationType = TyraMVP; - textureMappingType = TyraLinear; - blendingEnabled = true; - antiAliasingEnabled = false; - model = nullptr; -} - -PipelineInfoBag::~PipelineInfoBag() {} +class DynPipInfoBag : public PipelineInfoBag { + public: + DynPipInfoBag() {} + ~DynPipInfoBag() {} +}; } // namespace Tyra diff --git a/engine/inc/renderer/3d/pipeline/dynamic/core/dynpip_core.hpp b/engine/inc/renderer/3d/pipeline/dynamic/core/dynpip_core.hpp index 23db40c..0c7144a 100644 --- a/engine/inc/renderer/3d/pipeline/dynamic/core/dynpip_core.hpp +++ b/engine/inc/renderer/3d/pipeline/dynamic/core/dynpip_core.hpp @@ -28,18 +28,16 @@ class DynPipCore { void init(RendererCore* t_core); /** Force starting VU1 program instead of continueing */ - void clear() { qbufferRenderer.clearLastProgramName(); } - void updatePrimLod(PipelineInfoBag* bag); + void begin(PipelineInfoBag* bag); /** * Send model matrix, lighting data and other * repetitve stuff to VU1 */ - void initParts(DynPipBag* data); + void sendObjectDataToVU1(DynPipBag* data); /** Render 3D via "bags" */ - void renderPart(DynPipBag** bags, const u32& count, - const bool& frustumCull = true); + void render(DynPipBag** bags, const u32& count); /** Get max vert count of VU1 qbuffer (for optimizations) */ u32 getMaxVertCountByParams(const bool& isLightingEnabled, diff --git a/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp b/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp index b77a604..100ff21 100644 --- a/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp +++ b/engine/inc/renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp @@ -53,18 +53,16 @@ class DynamicPipeline : public Renderer3DPipeline { DynPipBag* buffers; static const u32 halfBuffersCount; - void setBuffer(DynPipBag* buffers, DynPipBag* buffer, u16* bufferIndex, - const PipelineFrustumCulling& frustumCulling); + void setBuffer(DynPipBag* buffers, DynPipBag* buffer, u16* bufferIndex); - void sendRestOfBuffers(DynPipBag* buffers, u16* bufferIndex, - const PipelineFrustumCulling& frustumCulling); + void sendRestOfBuffers(DynPipBag* buffers, u16* bufferIndex); void addVertices(MeshMaterialFrame* materialFrameFrom, MeshMaterialFrame* materialFrameTo, DynPipBag* bag, const u32& startIndex) const; - PipelineInfoBag* getInfoBag(DynamicMesh* mesh, const DynPipOptions* options, - M4x4* model) const; + DynPipInfoBag* getInfoBag(DynamicMesh* mesh, const DynPipOptions* options, + M4x4* model) const; DynPipColorBag* getColorBag(MeshMaterial* material) const; @@ -82,7 +80,7 @@ class DynamicPipeline : public Renderer3DPipeline { void setLightingColorsCache(PipelineLightingOptions* lightingOptions); void freeBuffer(DynPipBag* bag); void setBuffersDefaultVars(DynPipBag* buffers, DynamicMesh* mesh, - PipelineInfoBag* infoBag); + DynPipInfoBag* infoBag); void setBuffersColorBag(DynPipBag* buffers, DynPipColorBag* colorBag); }; diff --git a/engine/inc/renderer/3d/pipeline/shared/bag/pipeline_info_bag.hpp b/engine/inc/renderer/3d/pipeline/shared/bag/pipeline_info_bag.hpp index 0655fcf..e1e538e 100644 --- a/engine/inc/renderer/3d/pipeline/shared/bag/pipeline_info_bag.hpp +++ b/engine/inc/renderer/3d/pipeline/shared/bag/pipeline_info_bag.hpp @@ -16,33 +16,43 @@ #include "../pipeline_shading_type.hpp" #include "../pipeline_texture_mapping_type.hpp" #include "../pipeline_transformation_type.hpp" +#include "./pipeline_info_bag_frustum_culling.hpp" namespace Tyra { class PipelineInfoBag { public: - PipelineInfoBag(); - ~PipelineInfoBag(); + PipelineInfoBag() { + shadingType = TyraShadingFlat; + transformationType = TyraMVP; + textureMappingType = TyraLinear; + blendingEnabled = true; + antiAliasingEnabled = false; + model = nullptr; + frustumCulling = PipelineInfoBagFrustumCulling_None; + } + ~PipelineInfoBag() {} /** Mandatory. Model matrix */ M4x4* model; + /** Flat or gouraud */ PipelineShadingType shadingType; + + /** Linear or nearest */ PipelineTextureMappingType textureMappingType; + + /** Multiply by model matrix by view-projection or projection matrix */ PipelineTransformationType transformationType; + + /** Blending texture with color */ bool blendingEnabled; + + /** Anti-aliasing */ bool antiAliasingEnabled; - /** - * @brief Experimental! False -> disables "clip against each plane" algorithm. - * Default: True. - * - * Full clip checks are slow, but they are - * preventing visual artifacts, which can happen - * for big 3D objects (or objects near camera eyes) - * Force enabled in dynamic pipe, because of efficiency. - */ - bool fullClipChecks; + /** Type of frustum culling */ + PipelineInfoBagFrustumCulling frustumCulling; }; } // namespace Tyra diff --git a/engine/inc/renderer/3d/pipeline/shared/bag/pipeline_info_bag_frustum_culling.hpp b/engine/inc/renderer/3d/pipeline/shared/bag/pipeline_info_bag_frustum_culling.hpp new file mode 100644 index 0000000..51a9ed2 --- /dev/null +++ b/engine/inc/renderer/3d/pipeline/shared/bag/pipeline_info_bag_frustum_culling.hpp @@ -0,0 +1,22 @@ +/* +# ______ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2022, tyra - https://github.com/h4570/tyra +# Licenced under Apache License 2.0 +# Sandro Sobczyński +*/ + +#pragma once + +namespace Tyra { + +enum PipelineInfoBagFrustumCulling { + /** No frustum culling */ + PipelineInfoBagFrustumCulling_None = 0, + /** Frustum culling of parts of an object */ + PipelineInfoBagFrustumCulling_Precise = 2, +}; + +} diff --git a/engine/inc/renderer/3d/pipeline/shared/pipeline_options.hpp b/engine/inc/renderer/3d/pipeline/shared/pipeline_options.hpp index a71fde8..3a8ef88 100644 --- a/engine/inc/renderer/3d/pipeline/shared/pipeline_options.hpp +++ b/engine/inc/renderer/3d/pipeline/shared/pipeline_options.hpp @@ -45,7 +45,7 @@ class PipelineOptions { /** Anti-aliasing */ bool antiAliasingEnabled; - /** Multiply by model matrix by MVP or MP */ + /** Multiply by model matrix by view-projection or projection matrix */ PipelineTransformationType transformationType; /** Optional */ diff --git a/engine/inc/renderer/3d/pipeline/static/core/bag/stapip_bag.hpp b/engine/inc/renderer/3d/pipeline/static/core/bag/stapip_bag.hpp index a89d93c..391a719 100644 --- a/engine/inc/renderer/3d/pipeline/static/core/bag/stapip_bag.hpp +++ b/engine/inc/renderer/3d/pipeline/static/core/bag/stapip_bag.hpp @@ -11,7 +11,7 @@ #pragma once #include "math/vec4.hpp" -#include "renderer/3d/pipeline/shared/bag/pipeline_info_bag.hpp" +#include "./stapip_info_bag.hpp" #include "./stapip_color_bag.hpp" #include "./stapip_lighting_bag.hpp" #include "./stapip_texture_bag.hpp" @@ -31,7 +31,7 @@ class StaPipBag { ~StaPipBag(); /** Mandatory. Object info. */ - PipelineInfoBag* info; + StaPipInfoBag* info; /** Mandatory. Object color(s). */ StaPipColorBag* color; diff --git a/engine/inc/renderer/3d/pipeline/static/core/bag/stapip_info_bag.hpp b/engine/inc/renderer/3d/pipeline/static/core/bag/stapip_info_bag.hpp new file mode 100644 index 0000000..d907881 --- /dev/null +++ b/engine/inc/renderer/3d/pipeline/static/core/bag/stapip_info_bag.hpp @@ -0,0 +1,41 @@ +/* +# ______ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2022, tyra - https://github.com/h4570/tyra +# Licenced under Apache License 2.0 +# Sandro Sobczyński +*/ + +#pragma once + +#include "renderer/3d/pipeline/shared/bag/pipeline_info_bag.hpp" +#include "renderer/3d/pipeline/static/stapip_ztest.hpp" + +namespace Tyra { + +class StaPipInfoBag : public PipelineInfoBag { + public: + StaPipInfoBag() { + fullClipChecks = false; + zTestType = StaPipZTest_Standard; + } + ~StaPipInfoBag() {} + + /** + * @brief Experimental! False -> disables "clip against each plane" algorithm. + * Default: True. + * + * Full clip checks are slow, but they are + * preventing visual artifacts, which can happen + * for big 3D objects (or objects near camera eyes) + * Force enabled in dynamic pipe, because of efficiency. + */ + bool fullClipChecks; + + /** @brief Type of z buffer testing. */ + StaPipZTest zTestType; +}; + +} // namespace Tyra diff --git a/engine/inc/renderer/3d/pipeline/static/core/stapip_core.hpp b/engine/inc/renderer/3d/pipeline/static/core/stapip_core.hpp index 8b4de13..94c8b25 100644 --- a/engine/inc/renderer/3d/pipeline/static/core/stapip_core.hpp +++ b/engine/inc/renderer/3d/pipeline/static/core/stapip_core.hpp @@ -29,8 +29,7 @@ class StaPipCore { void init(RendererCore* t_core); /** Render 3D via "bags" */ - void render(StaPipBag* bag, const bool& frustumCull, const StaPipZTest& zTest, - StaPipBagPackagesBBox* bbox = nullptr); + void render(StaPipBag* bag, StaPipBagPackagesBBox* bbox = nullptr); /** Get max vert count of VU1 qbuffer (for optimizations) */ u32 getMaxVertCountByParams(const bool& isSingleColor, diff --git a/engine/inc/renderer/3d/pipeline/static/static_pipeline.hpp b/engine/inc/renderer/3d/pipeline/static/static_pipeline.hpp index 1131bc0..936e956 100644 --- a/engine/inc/renderer/3d/pipeline/static/static_pipeline.hpp +++ b/engine/inc/renderer/3d/pipeline/static/static_pipeline.hpp @@ -53,7 +53,7 @@ class StaticPipeline : public Renderer3DPipeline { void addVertices(MeshMaterialFrame* materialFrame, StaPipBag* bag) const; - PipelineInfoBag* getInfoBag(StaticMesh* mesh, const StaPipOptions* options, + StaPipInfoBag* getInfoBag(StaticMesh* mesh, const StaPipOptions* options, M4x4* model) const; StaPipColorBag* getColorBag(MeshMaterial* material, diff --git a/engine/src/loaders/3d/md2/md2_loader.cpp b/engine/src/loaders/3d/md2/md2_loader.cpp index d067e11..e1cddaa 100644 --- a/engine/src/loaders/3d/md2/md2_loader.cpp +++ b/engine/src/loaders/3d/md2/md2_loader.cpp @@ -149,9 +149,6 @@ MeshBuilderData* MD2Loader::load(const char* fullpath, const float& scale, texCoord_t* texCoord; - TYRA_LOG("Skin width: ", header.skinwidth, - " Skin height: ", header.skinheight); - for (u32 i = 0; i < stsCount; i++) { texCoord = reinterpret_cast(&stsBuffer[sizeof(texCoord_t) * i]); diff --git a/engine/src/loaders/3d/tyrobj/tyrobj_loader.cpp b/engine/src/loaders/3d/tyrobj/tyrobj_loader.cpp index 98e94c7..0712549 100644 --- a/engine/src/loaders/3d/tyrobj/tyrobj_loader.cpp +++ b/engine/src/loaders/3d/tyrobj/tyrobj_loader.cpp @@ -243,8 +243,7 @@ void TyrobjLoader::readFaces(TyraobjReadInfo* info, FILE* file, &normalIndex[1], &vertexIndex[2], &coordIndex[2], &normalIndex[2]); } break; - /** Loaded only two digits (V, VT) succesfuly. Not setting - VN. */ + /** Loaded only two digits (V, VT) succesfuly. Not setting VN. */ case 3: { fscanf(file, "%d/%d/ %d/%d/ %d/%d/\n", &vertexIndex[0], &coordIndex[0], &vertexIndex[1], &coordIndex[1], &vertexIndex[2], &coordIndex[2]); diff --git a/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_core.cpp b/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_core.cpp index 4b2aa64..725bf20 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_core.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/core/dynpip_core.cpp @@ -56,7 +56,7 @@ u32 DynPipCore::getMaxVertCountByParams(const bool& isLightingEnabled, ->getMaxVertCount(qbufferRenderer.getBufferSize()); } -void DynPipCore::initParts(DynPipBag* bag) { +void DynPipCore::sendObjectDataToVU1(DynPipBag* bag) { RendererCoreTextureBuffers* texBuffers = nullptr; if (bag->texture) { auto temp = rendererCore->texture.useTexture(bag->texture->texture); @@ -74,7 +74,9 @@ void DynPipCore::initParts(DynPipBag* bag) { delete texBuffers; } -void DynPipCore::updatePrimLod(PipelineInfoBag* bag) { +void DynPipCore::begin(PipelineInfoBag* bag) { + qbufferRenderer.clearLastProgramName(); + prim.antialiasing = bag->antiAliasingEnabled; prim.blending = bag->blendingEnabled; prim.shading = bag->shadingType; @@ -88,8 +90,7 @@ void DynPipCore::updatePrimLod(PipelineInfoBag* bag) { } } -void DynPipCore::renderPart(DynPipBag** bags, const u32& count, - const bool& frustumCull) { +void DynPipCore::render(DynPipBag** bags, const u32& count) { if (count <= 0) return; TYRA_ASSERT( @@ -113,7 +114,7 @@ void DynPipCore::renderPart(DynPipBag** bags, const u32& count, bags[0]->texture->coordinatesTo), "If you want texture, please provide texture and coordinates!"); - if (!frustumCull) { + if (bags[0]->info->frustumCulling == PipelineInfoBagFrustumCulling_None) { qbufferRenderer.render(bags, count); return; } diff --git a/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp b/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp index 7cb1653..8c42e0a 100644 --- a/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp +++ b/engine/src/renderer/3d/pipeline/dynamic/dynamic_pipeline.cpp @@ -9,6 +9,7 @@ */ #include "renderer/3d/pipeline/dynamic/dynamic_pipeline.hpp" +#include "renderer/3d/pipeline/shared/bag/pipeline_info_bag.hpp" namespace Tyra { @@ -49,13 +50,18 @@ void DynamicPipeline::onUseEnd() { } void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) { + bool optionsManuallyAllocated = false; + + if (!options) { + options = new DynPipOptions(); + optionsManuallyAllocated = true; + } + auto model = mesh->getModelMatrix(); auto* infoBag = getInfoBag(mesh, options, &model); PipelineDirLightsBag* dirLights = nullptr; - auto frustumCulling = - options ? options->frustumCulling : PipelineFrustumCulling_Simple; - if (frustumCulling == PipelineFrustumCulling_Simple) { + if (options->frustumCulling == PipelineFrustumCulling_Simple) { auto* frameTo = mesh->getFrame(mesh->getNextAnimationFrame()); if (frameTo->getBBox().isInFrustum( rendererCore->renderer3D.frustumPlanes.getAll(), model) == @@ -74,8 +80,7 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) { u16 bufferIndex = 0; setBuffersDefaultVars(buffers, mesh, infoBag); - core.clear(); - core.updatePrimLod(infoBag); + core.begin(infoBag); for (u32 i = 0; i < mesh->getMaterialsCount(); i++) { auto* material = mesh->getMaterial(i); @@ -110,28 +115,29 @@ void DynamicPipeline::render(DynamicMesh* mesh, const DynPipOptions* options) { dirLights, startIndex); if (!isPartInitialized) { - core.initParts(&buffer); + core.sendObjectDataToVU1(&buffer); isPartInitialized = true; } - setBuffer(buffers, &buffer, &bufferIndex, frustumCulling); + setBuffer(buffers, &buffer, &bufferIndex); } delete colorBag; } - sendRestOfBuffers(buffers, &bufferIndex, frustumCulling); + sendRestOfBuffers(buffers, &bufferIndex); if (dirLights) { delete dirLights; } delete infoBag; + + if (optionsManuallyAllocated) delete options; } void DynamicPipeline::setBuffer(DynPipBag* buffers, DynPipBag* buffer, - u16* bufferIndex, - const PipelineFrustumCulling& frustumCulling) { + u16* bufferIndex) { auto isEndOf1stDBuffer = *bufferIndex == halfBuffersCount - 1; auto isEndOf2ndDBuffer = *bufferIndex == buffersCount - 1; @@ -143,8 +149,7 @@ void DynamicPipeline::setBuffer(DynPipBag* buffers, DynPipBag* buffer, for (u32 i = 0; i < halfBuffersCount; i++) sendBuffers[i] = &buffers[offset + i]; - core.renderPart(sendBuffers, halfBuffersCount, - frustumCulling == PipelineFrustumCulling_Precise); + core.render(sendBuffers, halfBuffersCount); delete[] sendBuffers; } @@ -155,9 +160,7 @@ void DynamicPipeline::setBuffer(DynPipBag* buffers, DynPipBag* buffer, *bufferIndex += 1; } -void DynamicPipeline::sendRestOfBuffers( - DynPipBag* buffers, u16* bufferIndex, - const PipelineFrustumCulling& frustumCulling) { +void DynamicPipeline::sendRestOfBuffers(DynPipBag* buffers, u16* bufferIndex) { auto isEndOf1stDBuffer = *bufferIndex <= halfBuffersCount - 1; u32 offset = isEndOf1stDBuffer ? 0 : halfBuffersCount; @@ -170,15 +173,14 @@ void DynamicPipeline::sendRestOfBuffers( sendBuffers[i] = &buffers[offset + i]; } - core.renderPart(sendBuffers, size, - frustumCulling == PipelineFrustumCulling_Precise); + core.render(sendBuffers, size); delete[] sendBuffers; } void DynamicPipeline::setBuffersDefaultVars(DynPipBag* buffers, DynamicMesh* mesh, - PipelineInfoBag* infoBag) { + DynPipInfoBag* infoBag) { for (u32 i = 0; i < buffersCount; i++) { buffers[i].info = infoBag; buffers[i].interpolation = mesh->getAnimState().interpolation; @@ -202,25 +204,20 @@ void DynamicPipeline::freeBuffer(DynPipBag* bag) { } } -PipelineInfoBag* DynamicPipeline::getInfoBag(DynamicMesh* mesh, - const DynPipOptions* options, - M4x4* model) const { - auto* result = new PipelineInfoBag(); - - if (options) { - result->antiAliasingEnabled = options->antiAliasingEnabled; - result->blendingEnabled = options->blendingEnabled; - result->shadingType = options->shadingType; - result->textureMappingType = options->textureMappingType; - result->transformationType = options->transformationType; - } else { - result->antiAliasingEnabled = false; - result->blendingEnabled = true; - result->shadingType = TyraShadingFlat; - result->textureMappingType = TyraLinear; - result->transformationType = TyraMVP; - } +DynPipInfoBag* DynamicPipeline::getInfoBag(DynamicMesh* mesh, + const DynPipOptions* options, + M4x4* model) const { + auto* result = new DynPipInfoBag(); + result->antiAliasingEnabled = options->antiAliasingEnabled; + result->blendingEnabled = options->blendingEnabled; + result->shadingType = options->shadingType; + result->textureMappingType = options->textureMappingType; + result->transformationType = options->transformationType; + result->frustumCulling = + options->frustumCulling == PipelineFrustumCulling_Precise + ? PipelineInfoBagFrustumCulling_Precise + : PipelineInfoBagFrustumCulling_None; result->model = model; return result; diff --git a/engine/src/renderer/3d/pipeline/static/core/stapip_core.cpp b/engine/src/renderer/3d/pipeline/static/core/stapip_core.cpp index b05a3fd..cc669df 100644 --- a/engine/src/renderer/3d/pipeline/static/core/stapip_core.cpp +++ b/engine/src/renderer/3d/pipeline/static/core/stapip_core.cpp @@ -72,10 +72,12 @@ u32 StaPipCore::getMaxVertCountByParams(const bool& isSingleColor, ->getMaxVertCount(isSingleColor, qbufferRenderer.getBufferSize()); } -void StaPipCore::render(StaPipBag* bag, const bool& frustumCull, - const StaPipZTest& zTest, StaPipBagPackagesBBox* bbox) { +void StaPipCore::render(StaPipBag* bag, StaPipBagPackagesBBox* bbox) { if (bag->count <= 0) return; + bool frustumCull = + bag->info->frustumCulling == PipelineInfoBagFrustumCulling_Precise; + TYRA_ASSERT(bag->vertices != nullptr, "Vertices are required in 3D render bag!"); TYRA_ASSERT(bag->info != nullptr, "Info bag is required in 3D render bag!"); @@ -100,7 +102,7 @@ void StaPipCore::render(StaPipBag* bag, const bool& frustumCull, (!bag->info->fullClipChecks && !frustumCull), "Please disable clip checks and frustum culling if not using MVP " "matrix!"); - TYRA_ASSERT(!(frustumCull == false && bag->info->fullClipChecks == true), + TYRA_ASSERT(!(!frustumCull && bag->info->fullClipChecks == true), "Full clip checks are not supported with frustum culling = off!"); u32 maxVertCount = getMaxVertCountByBag(bag); @@ -128,7 +130,7 @@ void StaPipCore::render(StaPipBag* bag, const bool& frustumCull, } } - if (zTest == StaPipZTest_AllPass) { + if (bag->info->zTestType == StaPipZTest_AllPass) { rendererCore->gs.setAllPassZTest(); } @@ -208,7 +210,7 @@ void StaPipCore::render(StaPipBag* bag, const bool& frustumCull, qbufferRenderer.flushBuffers(); - if (zTest == StaPipZTest_AllPass) { + if (bag->info->zTestType == StaPipZTest_AllPass) { rendererCore->gs.setStandardZTest(); } diff --git a/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp b/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp index 73e8332..72c2b3b 100644 --- a/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp +++ b/engine/src/renderer/3d/pipeline/static/static_pipeline.cpp @@ -10,6 +10,7 @@ #include "renderer/3d/pipeline/static/static_pipeline.hpp" #include "debug/debug.hpp" +#include "renderer/3d/pipeline/static/core/bag/stapip_info_bag.hpp" namespace Tyra { @@ -37,15 +38,18 @@ void StaticPipeline::onUseEnd() { } void StaticPipeline::render(StaticMesh* mesh, const StaPipOptions* options) { + bool optionsManuallyAllocated = false; + + if (!options) { + options = new StaPipOptions(); + optionsManuallyAllocated = true; + } + auto model = mesh->getModelMatrix(); auto* infoBag = getInfoBag(mesh, options, &model); - auto zTesting = options ? options->zTestType : StaPipZTest_Standard; - auto frustumCulling = - options ? options->frustumCulling : PipelineFrustumCulling_Simple; - TYRA_ASSERT( - !(frustumCulling != PipelineFrustumCulling_Precise && + !(options->frustumCulling != PipelineFrustumCulling_Precise && infoBag->fullClipChecks == true), "Full clip checks are only supported with frustum culling == Precise!"); TYRA_ASSERT(options->transformationType == TyraMVP || @@ -54,7 +58,7 @@ void StaticPipeline::render(StaticMesh* mesh, const StaPipOptions* options) { "Please disable clip checks and frustum culling if not using MVP " "matrix!"); - if (frustumCulling == PipelineFrustumCulling_Simple) { + if (options->frustumCulling == PipelineFrustumCulling_Simple) { auto* frame = mesh->getFrame(); if (frame->getBBox().isInFrustum( rendererCore->renderer3D.frustumPlanes.getAll(), model) == @@ -68,21 +72,19 @@ void StaticPipeline::render(StaticMesh* mesh, const StaPipOptions* options) { for (u32 i = 0; i < mesh->getMaterialsCount(); i++) { auto* material = mesh->getMaterial(i); auto* materialFrame = material->getFrame(0); - StaPipBag bag; addVertices(materialFrame, &bag); bag.info = infoBag; bag.color = getColorBag(material, materialFrame); bag.texture = getTextureBag(material, materialFrame); bag.lighting = getLightingBag(materialFrame, &model, options); - - core.render(&bag, frustumCulling == PipelineFrustumCulling_Precise, - zTesting); + core.render(&bag); deallocDrawBags(&bag, material); } - delete infoBag; + + if (optionsManuallyAllocated) delete options; } void StaticPipeline::addVertices(MeshMaterialFrame* materialFrame, @@ -91,27 +93,22 @@ void StaticPipeline::addVertices(MeshMaterialFrame* materialFrame, bag->vertices = materialFrame->getVertices(); } -PipelineInfoBag* StaticPipeline::getInfoBag(StaticMesh* mesh, - const StaPipOptions* options, - M4x4* model) const { - auto* result = new PipelineInfoBag(); - - if (options) { - result->antiAliasingEnabled = options->antiAliasingEnabled; - result->blendingEnabled = options->blendingEnabled; - result->shadingType = options->shadingType; - result->fullClipChecks = options->fullClipChecks; - result->textureMappingType = options->textureMappingType; - result->transformationType = options->transformationType; - } else { - result->antiAliasingEnabled = false; - result->blendingEnabled = true; - result->shadingType = TyraShadingFlat; - result->textureMappingType = TyraLinear; - result->fullClipChecks = false; - result->transformationType = TyraMVP; - } +StaPipInfoBag* StaticPipeline::getInfoBag(StaticMesh* mesh, + const StaPipOptions* options, + M4x4* model) const { + auto* result = new StaPipInfoBag(); + result->antiAliasingEnabled = options->antiAliasingEnabled; + result->blendingEnabled = options->blendingEnabled; + result->shadingType = options->shadingType; + result->textureMappingType = options->textureMappingType; + result->transformationType = options->transformationType; + result->frustumCulling = + options->frustumCulling == PipelineFrustumCulling_Precise + ? PipelineInfoBagFrustumCulling_Precise + : PipelineInfoBagFrustumCulling_None; + result->fullClipChecks = options->fullClipChecks; + result->zTestType = options->zTestType; result->model = model; return result;