diff --git a/ROADMAP.txt b/ROADMAP.txt index f03a0ae..99a4446 100644 --- a/ROADMAP.txt +++ b/ROADMAP.txt @@ -1,10 +1,9 @@ ------------ Tyra's v2.0 roadmap to publish on GitHub ------------ -- [Renderer] utility functions - [Demo] Red screen on hit -- [Demo] Count of killed zombies -- [Demo] Crosshair -- [Demo] 2D Health bar +- [HUD] Count of killed zombies +- [HUD] Crosshair +- [HUD] 2D Health bar - [Demo] Game over screen - [Demo] Game fadein with audio information about island - [General] USB test @@ -36,6 +35,7 @@ because Mesh rendering uses only core.render() ------------ Github issues for Tyra v2 ------------ - [renderer] fog - [renderer] bbox parts optimization +- [General] smart pointers and std::array instead of raw pointers - [md2] refactor - [2D] Fixed font support - [File] Async file loading diff --git a/demo/inc/states/game/debug_object.hpp b/demo/inc/states/game/debug_object.hpp deleted file mode 100644 index c3175ad..0000000 --- a/demo/inc/states/game/debug_object.hpp +++ /dev/null @@ -1,40 +0,0 @@ -/* -# _____ ____ ___ -# | \/ ____| |___| -# | | | \ | | -#----------------------------------------------------------------------- -# Copyright 2022, tyra - https://github.com/h4570/tyra -# Licensed under Apache License 2.0 -# Sandro Sobczyński -*/ - -#pragma once - -#include -#include "states/game/renderer/renderer_static_pair.hpp" - -using Tyra::Renderer; -using Tyra::StaPipOptions; -using Tyra::StaticMesh; -using Tyra::TextureRepository; -using Tyra::Vec4; - -namespace Demo { - -class DebugObject { - public: - DebugObject(TextureRepository* repo); - ~DebugObject(); - - StaticMesh* mesh; - StaPipOptions* options; - RendererStaticPair* pair; - - void setPosition(const Vec4& v); - - private: - float rotator; - void allocateOptions(); -}; - -} // namespace Demo diff --git a/demo/inc/states/game/game_state.hpp b/demo/inc/states/game/game_state.hpp index e6033d1..079c964 100644 --- a/demo/inc/states/game/game_state.hpp +++ b/demo/inc/states/game/game_state.hpp @@ -17,7 +17,6 @@ #include "./terrain/terrain.hpp" #include "./skybox/skybox.hpp" #include "./ship/ship.hpp" -#include "./debug_object.hpp" #include "./enemy/enemy_manager.hpp" namespace Demo { @@ -50,7 +49,6 @@ class GameState : public State { Terrain* terrain; Skybox* skybox; Ship* ship; - DebugObject* dbgObj; }; } // namespace Demo diff --git a/demo/inc/states/game/player/player.hpp b/demo/inc/states/game/player/player.hpp index 0f6e55c..a2e92e7 100644 --- a/demo/inc/states/game/player/player.hpp +++ b/demo/inc/states/game/player/player.hpp @@ -20,6 +20,7 @@ using Tyra::Engine; using Tyra::Pad; +using Tyra::Renderer3DUtility; using Tyra::Vec4; namespace Demo { @@ -41,6 +42,7 @@ class Player { private: void handlePlayerPosition(const Heightmap& heightmap, const float& terrainHeight); + Renderer3DUtility* utility; float speed; Pad* pad; diff --git a/demo/inc/states/game/renderer/game_renderer.hpp b/demo/inc/states/game/renderer/game_renderer.hpp index 89888a4..4f57415 100644 --- a/demo/inc/states/game/renderer/game_renderer.hpp +++ b/demo/inc/states/game/renderer/game_renderer.hpp @@ -32,6 +32,7 @@ class GameRenderer { void clear(); + void renderSkybox(const RendererStaticPair& pair); void render(); private: diff --git a/demo/src/states/game/debug_object.cpp b/demo/src/states/game/debug_object.cpp deleted file mode 100644 index 68a63d0..0000000 --- a/demo/src/states/game/debug_object.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* -# _____ ____ ___ -# | \/ ____| |___| -# | | | \ | | -#----------------------------------------------------------------------- -# Copyright 2022, tyra - https://github.com/h4570/tyra -# Licensed under Apache License 2.0 -# Sandro Sobczyński -*/ - -#include "states/game/debug_object.hpp" - -using Tyra::Color; -using Tyra::FileUtils; -using Tyra::ObjLoader; -using Tyra::ObjLoaderOptions; - -namespace Demo { - -DebugObject::DebugObject(TextureRepository* repo) { - ObjLoader loader; - - ObjLoaderOptions objOptions; - objOptions.flipUVs = true; - objOptions.scale = .5F; - - auto* data = - loader.load(FileUtils::fromCwd("game/models/debug.obj"), objOptions); - data->normalsEnabled = false; - data->textureCoordsEnabled = false; - mesh = new StaticMesh(*data); - delete data; - - rotator = 0.0F; - allocateOptions(); - - pair = new RendererStaticPair{mesh, options}; -} - -void DebugObject::setPosition(const Vec4& v) { - mesh->translation.identity(); - mesh->rotation.identity(); - mesh->translation.translate(v); - mesh->rotation.rotateX(rotator); - mesh->rotation.rotateY(rotator); - mesh->rotation.rotateZ(rotator); - - rotator += 0.05F; - if (rotator >= 360.0F) rotator = 0.0F; -} - -DebugObject::~DebugObject() { - delete mesh; - delete options; - delete pair; -} - -void DebugObject::allocateOptions() { - options = new StaPipOptions(); - options->shadingType = Tyra::TyraShadingGouraud; - options->blendingEnabled = false; - options->antiAliasingEnabled = false; -} - -} // namespace Demo diff --git a/demo/src/states/game/enemy/enemy.cpp b/demo/src/states/game/enemy/enemy.cpp index 064fa6d..de2cfe4 100644 --- a/demo/src/states/game/enemy/enemy.cpp +++ b/demo/src/states/game/enemy/enemy.cpp @@ -92,15 +92,12 @@ void Enemy::handlePlayerShoot(const PlayerShootAction& shootAction) { } const auto& ray = shootAction.ray.value(); + auto bbox = mesh->getCurrentBoundingBox().getTransformed(mesh->getModelMatrix()); auto isOnEnemy = ray.intersectBox(bbox.min(), bbox.max()); - utility->drawBBox(bbox); - utility->drawLine(ray.origin, ray.direction); - utility->drawPoint(*mesh->getPosition()); - if (isOnEnemy) { mesh->setPosition(spawnPoint); TYRA_LOG("Enemy hit!"); diff --git a/demo/src/states/game/enemy/enemy_manager.cpp b/demo/src/states/game/enemy/enemy_manager.cpp index 9705cbc..251d635 100644 --- a/demo/src/states/game/enemy/enemy_manager.cpp +++ b/demo/src/states/game/enemy/enemy_manager.cpp @@ -43,7 +43,7 @@ EnemyManager::EnemyManager(Engine* engine, const Heightmap& heightmap) { auto* sample = engine->audio.adpcm.load( FileUtils::fromCwd("game/models/zombie/punch.adpcm")); - const int enemyCount = 2; + const int enemyCount = 10; for (int i = 0; i < enemyCount; i++) { EnemyInfo info; info.adpcmChannel = 9 + i; diff --git a/demo/src/states/game/game_state.cpp b/demo/src/states/game/game_state.cpp index a7f92ae..b3164f9 100644 --- a/demo/src/states/game/game_state.cpp +++ b/demo/src/states/game/game_state.cpp @@ -39,7 +39,6 @@ void GameState::onStart() { enemyManager = new EnemyManager(engine, terrain->heightmap); ship = new Ship(repository); skybox = new Skybox(repository); - dbgObj = new DebugObject(repository); initialized = true; } @@ -52,41 +51,41 @@ GlobalStateType GameState::onFinish() { delete terrain; delete ship; delete skybox; - delete dbgObj; initialized = false; return STATE_EXIT; } void GameState::update() { + // Begin frame + player->update(terrain->heightmap); + auto cameraInfo = player->getCameraInfo(); + engine->renderer.beginFrame(cameraInfo); + + // Clear screen and render skybox + renderer.clear(); + skybox->update(player->getPosition()); + renderer.renderSkybox(*skybox->pair); // First, because of ALLPASS + + // Check fps if (fpsChecker++ > 50) { TYRA_LOG("FPS: ", engine->info.getFps(), " RAM: ", engine->info.getAvailableRAM()); fpsChecker = 0; } - player->update(terrain->heightmap); - skybox->update(player->getPosition()); + // Game logic auto shootAction = player->getShootAction(); enemyManager->update(terrain->heightmap, player->getPosition(), shootAction); - auto cameraInfo = player->getCameraInfo(); - dbgObj->setPosition(*cameraInfo.looksAt); + // Render other stuff + renderer.add(ship->pair); + renderer.add(player->pair); + renderer.add(enemyManager->getPairs()); + renderer.add(terrain->pair); + renderer.render(); - engine->renderer.beginFrame(cameraInfo); - { - renderer.clear(); - { - renderer.add(skybox->pair); // First, because of ALLPASS - renderer.add(ship->pair); - renderer.add(dbgObj->pair); - - renderer.add(player->pair); - renderer.add(enemyManager->getPairs()); - renderer.add(terrain->pair); - } - renderer.render(); - } + // End frame engine->renderer.endFrame(); } diff --git a/demo/src/states/game/player/player.cpp b/demo/src/states/game/player/player.cpp index 80db7e8..ade770c 100644 --- a/demo/src/states/game/player/player.cpp +++ b/demo/src/states/game/player/player.cpp @@ -19,6 +19,8 @@ Player::Player(Engine* engine) position = Vec4(3.0F, 50.0F, 0.0F); camera.lookAt = Vec4(0.0F, 0.0F, -30.0F); speed = 5.0F; + + utility = &engine->renderer.renderer3D.utility; } Player::~Player() { delete pair; } @@ -39,6 +41,11 @@ PlayerShootAction Player::getShootAction() const { action.ray = Ray(camera.position, camera.lookAt.getNormalized()); } + utility->drawBox(camera.lookAt, 1.0F); + + // utility->drawLine(ray.origin, ray.direction); + utility->drawLine(camera.position + Vec4(0.0F, 1.0F, 0.0F), camera.lookAt); + return action; } diff --git a/demo/src/states/game/renderer/game_renderer.cpp b/demo/src/states/game/renderer/game_renderer.cpp index 51344e7..406358c 100644 --- a/demo/src/states/game/renderer/game_renderer.cpp +++ b/demo/src/states/game/renderer/game_renderer.cpp @@ -46,6 +46,11 @@ void GameRenderer::clear() { dynamicPairs.clear(); } +void GameRenderer::renderSkybox(const RendererStaticPair& pair) { + renderer->renderer3D.usePipeline(&stpip); + stpip.render(pair.mesh, pair.options); +} + void GameRenderer::render() { if (staticPairs.size()) { renderer->renderer3D.usePipeline(&stpip); diff --git a/engine/inc/renderer/3d/bbox/bbox.hpp b/engine/inc/renderer/3d/bbox/bbox.hpp index 7fe5f6a..2a69efd 100644 --- a/engine/inc/renderer/3d/bbox/bbox.hpp +++ b/engine/inc/renderer/3d/bbox/bbox.hpp @@ -19,13 +19,17 @@ namespace Tyra { /** Bounding box with more features */ class BBox : public CoreBBox { public: + BBox(const BBox& t_bbox); explicit BBox(CoreBBox** t_bboxes, const u32& count); explicit BBox(Vec4* t_vertices, u32* faces, u32 t_count); explicit BBox(Vec4* t_vertices, u32 t_count); explicit BBox(const BBox& t_bbox, const M4x4& t_matrix); - explicit BBox(const BBox& t_bbox); explicit BBox(Vec4* t_vertices); + static BBox create(const Vec4& center, const float& size); + + void operator=(const BBox& v); + const float& getHeight() const { return _height; } const float& getDepth() const { return _depth; } const float& getWidth() const { return _width; } diff --git a/engine/inc/renderer/3d/pipeline/minecraft/programs/as_is/mcpip_clip.hpp b/engine/inc/renderer/3d/pipeline/minecraft/programs/as_is/mcpip_clip.hpp index eaeab15..41803ef 100644 --- a/engine/inc/renderer/3d/pipeline/minecraft/programs/as_is/mcpip_clip.hpp +++ b/engine/inc/renderer/3d/pipeline/minecraft/programs/as_is/mcpip_clip.hpp @@ -18,7 +18,7 @@ #include "../../mcpip_block.hpp" #include "../../data/mcpip_block_data.hpp" #include "./mcpip_vu1_as_is_shared_defines.h" -#include "renderer/core/3d/clipper/ee_clip_algorithm.hpp" +#include "renderer/core/3d/clipper/planes_clip_algorithm.hpp" namespace Tyra { @@ -27,7 +27,7 @@ class McpipClip { McpipClip(); ~McpipClip(); - EEClipAlgorithm algorithm; + PlanesClipAlgorithm algorithm; EEClipAlgorithmSettings algoSettings; void init(RendererCore* core, McpipBlockData* t_singleBlockData, @@ -52,14 +52,16 @@ class McpipClip { u16 vu1DBufferSize; Vec4 inputVerts[3]; - EEClipVertexPtrs inputTriangle[3]; - EEClipVertex clippedTriangle[9]; + PlanesClipVertexPtrs inputTriangle[3]; + PlanesClipVertex clippedTriangle[9]; Vec4 vertexBuffers[2][108]; Vec4 texCoordBuffers[2][108]; - void addCorrections(std::vector* vertices, McpipBlock* block); - void moveDataToBuffer(std::vector* vertices, const u8& context); + void addCorrections(std::vector* vertices, + McpipBlock* block); + void moveDataToBuffer(std::vector* vertices, + const u8& context); void addDataToPacket(packet2_t* packet, const u8& context, McpipBlock* block, const int& count, RendererCoreTextureBuffers* texBuffers); diff --git a/engine/inc/renderer/3d/pipeline/static/core/bag/packaging/stapip_bag_packager.hpp b/engine/inc/renderer/3d/pipeline/static/core/bag/packaging/stapip_bag_packager.hpp index d530f3f..7e6184d 100644 --- a/engine/inc/renderer/3d/pipeline/static/core/bag/packaging/stapip_bag_packager.hpp +++ b/engine/inc/renderer/3d/pipeline/static/core/bag/packaging/stapip_bag_packager.hpp @@ -12,7 +12,7 @@ #include "renderer/core/3d/bbox/core_bbox.hpp" #include "renderer/core/3d/renderer_3d_frustum_planes.hpp" -#include "renderer/core/3d/clipper/ee_clip_algorithm.hpp" +#include "renderer/core/3d/clipper/planes_clip_algorithm.hpp" #include "./stapip_bag_packages_bbox.hpp" #include "./stapip_bag_package.hpp" #include "../stapip_bag.hpp" diff --git a/engine/inc/renderer/3d/pipeline/static/core/stapip_clipper.hpp b/engine/inc/renderer/3d/pipeline/static/core/stapip_clipper.hpp index 6d7765f..d6e4c13 100644 --- a/engine/inc/renderer/3d/pipeline/static/core/stapip_clipper.hpp +++ b/engine/inc/renderer/3d/pipeline/static/core/stapip_clipper.hpp @@ -14,7 +14,7 @@ #include "debug/debug.hpp" #include "./stapip_qbuffer.hpp" #include "renderer/renderer_settings.hpp" -#include "renderer/core/3d/clipper/ee_clip_algorithm.hpp" +#include "renderer/core/3d/clipper/planes_clip_algorithm.hpp" namespace Tyra { @@ -36,15 +36,15 @@ class StaPipClipper { private: u32 maxVertCount; - EEClipAlgorithm algorithm; + PlanesClipAlgorithm algorithm; M4x4* mvp; Vec4 inputVerts[3]; - EEClipVertexPtrs inputTriangle[3]; - EEClipVertex clippedTriangle[9]; + PlanesClipVertexPtrs inputTriangle[3]; + PlanesClipVertex clippedTriangle[9]; - void perspectiveDivide(std::vector* vertices); - void moveDataToBuffer(const std::vector& vertices, + void perspectiveDivide(std::vector* vertices); + void moveDataToBuffer(const std::vector& vertices, StaPipQBuffer* buffer); }; diff --git a/engine/inc/renderer/3d/renderer_3d_utility.hpp b/engine/inc/renderer/3d/renderer_3d_utility.hpp index efda9ad..cb05fe4 100644 --- a/engine/inc/renderer/3d/renderer_3d_utility.hpp +++ b/engine/inc/renderer/3d/renderer_3d_utility.hpp @@ -14,10 +14,16 @@ #include "renderer/models/color.hpp" #include "renderer/core/3d/bbox/core_bbox.hpp" #include "../core/renderer_core.hpp" +#include "renderer/core/3d/clipper/planes_clip_algorithm.hpp" namespace Tyra { -/** Debug functions, with bad performance. */ +/** + * Debug functions, with bad performance. + * + * Remember that you need to use them AFTER ALLPASS rendering. + * (for example after skybox), otherwise colors will not work. + */ class Renderer3DUtility { public: Renderer3DUtility(); @@ -25,8 +31,8 @@ class Renderer3DUtility { void init(RendererCore* core); - void drawPoint(const Vec4& v); - void drawPoint(const Vec4& v, const Color& color); + void drawBox(const Vec4& v, const float& size); + void drawBox(const Vec4& v, const float& size, const Color& color); void drawLine(const Vec4& from, const Vec4& to); void drawLine(const Vec4& from, const Vec4& to, const Color& color); @@ -35,10 +41,26 @@ class Renderer3DUtility { void drawBBox(const CoreBBox& v, const Color& color); private: + std::array clippedVerts; + std::array clipInput; + RendererCore* core; - prim_t basePrim; - color_t baseColor; + prim_t prim; + + void fillBBoxVertices(std::array, 6>& v, + const CoreBBox& bbox); + + color_t getGSColor(const Color& color); + + /** + * @return true - To draw + * @return false - To skip (outside view frustum) + */ + bool calcLineVertices(xyz_t* outputArray, const Vec4& a, const Vec4& b, + const u8& displayOffset); + + PlanesClipAlgorithm planesClipAlgorithm; }; } // namespace Tyra diff --git a/engine/inc/renderer/core/2d/renderer_core_2d.hpp b/engine/inc/renderer/core/2d/renderer_core_2d.hpp index bb3aa09..8796307 100644 --- a/engine/inc/renderer/core/2d/renderer_core_2d.hpp +++ b/engine/inc/renderer/core/2d/renderer_core_2d.hpp @@ -37,7 +37,7 @@ class RendererCore2D { prim_t prim; lod_t lod; - static const float GS_CENTER; + static const float GS_DRAW_AREA; static const float SCREEN_CENTER; u8 context; diff --git a/engine/inc/renderer/core/3d/bbox/core_bbox.hpp b/engine/inc/renderer/core/3d/bbox/core_bbox.hpp index c30fdab..a9d8445 100644 --- a/engine/inc/renderer/core/3d/bbox/core_bbox.hpp +++ b/engine/inc/renderer/core/3d/bbox/core_bbox.hpp @@ -21,17 +21,31 @@ namespace Tyra { /** Bounding box */ class CoreBBox { public: - explicit CoreBBox(); + CoreBBox(); + CoreBBox(const CoreBBox& t_bbox); explicit CoreBBox(Vec4* t_vertices, u32* faces, u32 t_count); explicit CoreBBox(Vec4* t_vertices, u32 t_count); explicit CoreBBox(Vec4* t_vertices); - explicit CoreBBox(const CoreBBox& t_bbox); explicit CoreBBox(CoreBBox** t_bboxes, const u32& count); explicit CoreBBox(const std::vector& t_bboxes, const u32& startIndex, const u32& stopIndex); + static CoreBBox create(const Vec4& center, const float& size); + + /** + * 0 - lowX, lowY, lowZ + * 1 - lowX, lowY, hiZ + * 2 - lowX, hiY, lowZ + * 3 - lowX, hiY, hiZ + * 4 - hiX, lowY, lowZ + * 5 - hiX, lowY, hiZ + * 6 - hiX, hiY, lowZ + * 7 - hiX, hiY, hiZ + */ Vec4 vertices[8]; + void operator=(const CoreBBox& v); + const Vec4& operator[](const u8& i) const { return vertices[i]; } const u8 getVertexCount() const { return 8; } @@ -41,13 +55,14 @@ class CoreBBox { void print(const std::string& name) const { print(name.c_str()); } std::string getPrint(const char* name = nullptr) const; -/** - * @brief Check if bbox is in view frustum - * - * @param frustumPlanes Available in engine.renderer.core.renderer3D.frustumPlanes - * @param model Model matrix - * @param margins Optional margins - */ + /** + * @brief Check if bbox is in view frustum + * + * @param frustumPlanes Available in + * engine.renderer.core.renderer3D.frustumPlanes + * @param model Model matrix + * @param margins Optional margins + */ CoreBBoxFrustum isInFrustum(const Plane* frustumPlanes, const M4x4& model, const float* margins = nullptr) const; }; diff --git a/engine/inc/renderer/core/3d/clipper/ee_clip_algorithm.hpp b/engine/inc/renderer/core/3d/clipper/planes_clip_algorithm.hpp similarity index 69% rename from engine/inc/renderer/core/3d/clipper/ee_clip_algorithm.hpp rename to engine/inc/renderer/core/3d/clipper/planes_clip_algorithm.hpp index 8878ebf..80b5161 100644 --- a/engine/inc/renderer/core/3d/clipper/ee_clip_algorithm.hpp +++ b/engine/inc/renderer/core/3d/clipper/planes_clip_algorithm.hpp @@ -11,7 +11,7 @@ #pragma once #include -#include "./ee_clip_vertex.hpp" +#include "./planes_clip_vertex.hpp" #include "debug/debug.hpp" #include "renderer/renderer_settings.hpp" @@ -21,30 +21,30 @@ struct EEClipAlgorithmSettings { bool lerpNormals, lerpTexCoords, lerpColors; }; -class EEClipAlgorithm { +class PlanesClipAlgorithm { public: - EEClipAlgorithm(); - ~EEClipAlgorithm(); + PlanesClipAlgorithm(); + ~PlanesClipAlgorithm(); void init(const RendererSettings& settings); - u8 clip(EEClipVertex* o_vertices, EEClipVertexPtrs* i_vertices, + u8 clip(PlanesClipVertex* o_vertices, PlanesClipVertexPtrs* i_vertices, const EEClipAlgorithmSettings& settings); static float clipMargin; private: float halfWidth, halfHeight, near, far; - EEClipVertex* tempVertices; + PlanesClipVertex* tempVertices; - float getValueByPlane(const EEClipVertex& v, const int& plane); + float getValueByPlane(const PlanesClipVertex& v, const int& plane); bool isInside(const int& plane, const float& v, const float& w, const float& planeLimitValue); /** @return clipped size */ - u8 clipAgainstPlane(EEClipVertex* original, const u8& originalSize, - EEClipVertex* clipped, const int& plane, + u8 clipAgainstPlane(PlanesClipVertex* original, const u8& originalSize, + PlanesClipVertex* clipped, const int& plane, const float& planeLimitValue, const EEClipAlgorithmSettings& settings); }; diff --git a/engine/inc/renderer/core/3d/clipper/ee_clip_vertex.hpp b/engine/inc/renderer/core/3d/clipper/planes_clip_vertex.hpp similarity index 89% rename from engine/inc/renderer/core/3d/clipper/ee_clip_vertex.hpp rename to engine/inc/renderer/core/3d/clipper/planes_clip_vertex.hpp index 78cce8c..b6cf407 100644 --- a/engine/inc/renderer/core/3d/clipper/ee_clip_vertex.hpp +++ b/engine/inc/renderer/core/3d/clipper/planes_clip_vertex.hpp @@ -14,11 +14,11 @@ namespace Tyra { -struct EEClipVertex { +struct PlanesClipVertex { Vec4 position, normal, st, color; }; -struct EEClipVertexPtrs { +struct PlanesClipVertexPtrs { Vec4 *position, *normal, *st, *color; }; diff --git a/engine/src/renderer/3d/bbox/bbox.cpp b/engine/src/renderer/3d/bbox/bbox.cpp index 5e4d9ee..b96a38f 100644 --- a/engine/src/renderer/3d/bbox/bbox.cpp +++ b/engine/src/renderer/3d/bbox/bbox.cpp @@ -102,6 +102,16 @@ Vec4 BBox::max() const { return _max; } +BBox BBox::create(const Vec4& center, const float& size) { + auto core = CoreBBox::create(center, size); + return BBox(core.vertices); +} + +void BBox::operator=(const BBox& v) { + for (auto i = 0; i < 8; i++) Vec4::copy(&vertices[i], v.vertices[i].xyzw); + setData(); +} + void BBox::getMinMax(Vec4* res_min, Vec4* res_max) const { Vec4 temp = Vec4(); diff --git a/engine/src/renderer/3d/pipeline/minecraft/programs/as_is/mcpip_clip.cpp b/engine/src/renderer/3d/pipeline/minecraft/programs/as_is/mcpip_clip.cpp index 279dae1..16125df 100644 --- a/engine/src/renderer/3d/pipeline/minecraft/programs/as_is/mcpip_clip.cpp +++ b/engine/src/renderer/3d/pipeline/minecraft/programs/as_is/mcpip_clip.cpp @@ -60,7 +60,7 @@ void McpipClip::initStaticPacket() { void McpipClip::addData(McpipBlock* block, const bool& isMulti, RendererCoreTextureBuffers* texBuffers, packet2_t* packet, const u8& context) { - std::vector clippedVertices; + std::vector clippedVertices; auto mvp = rendererCore->renderer3D.getViewProj() * (*block->model); const auto* blockData = isMulti ? multiBlockData : singleBlockData; @@ -92,7 +92,7 @@ void McpipClip::addData(McpipBlock* block, const bool& isMulti, addDataToPacket(packet, context, block, clippedVertices.size(), texBuffers); } -void McpipClip::addCorrections(std::vector* vertices, +void McpipClip::addCorrections(std::vector* vertices, McpipBlock* block) { for (u32 i = 0; i < vertices->size(); i++) { (*vertices)[i].position /= (*vertices)[i].position.w; // Perspective divide @@ -100,7 +100,7 @@ void McpipClip::addCorrections(std::vector* vertices, } } -void McpipClip::moveDataToBuffer(std::vector* vertices, +void McpipClip::moveDataToBuffer(std::vector* vertices, const u8& context) { for (u32 i = 0; i < vertices->size(); i++) { vertexBuffers[context][i].set(vertices->at(i).position); diff --git a/engine/src/renderer/3d/pipeline/static/core/stapip_clipper.cpp b/engine/src/renderer/3d/pipeline/static/core/stapip_clipper.cpp index dba95e5..46ca129 100644 --- a/engine/src/renderer/3d/pipeline/static/core/stapip_clipper.cpp +++ b/engine/src/renderer/3d/pipeline/static/core/stapip_clipper.cpp @@ -31,7 +31,7 @@ void StaPipClipper::clip(StaPipQBuffer* buffer) { buffer->bag->texture != nullptr, buffer->bag->color->many != nullptr}; - std::vector clippedVertices; + std::vector clippedVertices; for (u32 i = 0; i < buffer->size / 3; i++) { for (u8 j = 0; j < 3; j++) { @@ -63,14 +63,14 @@ void StaPipClipper::clip(StaPipQBuffer* buffer) { moveDataToBuffer(clippedVertices, buffer); } -void StaPipClipper::perspectiveDivide(std::vector* vertices) { +void StaPipClipper::perspectiveDivide(std::vector* vertices) { for (u32 i = 0; i < vertices->size(); i++) { (*vertices)[i].position /= (*vertices)[i].position.w; } } -void StaPipClipper::moveDataToBuffer(const std::vector& vertices, - StaPipQBuffer* buffer) { +void StaPipClipper::moveDataToBuffer( + const std::vector& vertices, StaPipQBuffer* buffer) { buffer->reallocateManually(vertices.size()); for (u32 i = 0; i < vertices.size(); i++) { diff --git a/engine/src/renderer/3d/renderer_3d_utility.cpp b/engine/src/renderer/3d/renderer_3d_utility.cpp index 23beeaf..275781d 100644 --- a/engine/src/renderer/3d/renderer_3d_utility.cpp +++ b/engine/src/renderer/3d/renderer_3d_utility.cpp @@ -23,83 +23,85 @@ Renderer3DUtility::Renderer3DUtility() {} Renderer3DUtility::~Renderer3DUtility() {} +#define TYRA_UTILS_LINE_REGLIST \ + ((u64)GIF_REG_XYZ2) << 0 | ((u64)GIF_REG_XYZ2) << 4 + void Renderer3DUtility::init(RendererCore* t_core) { core = t_core; - basePrim.type = PRIM_LINE; - basePrim.shading = PRIM_SHADE_FLAT; - basePrim.mapping = DRAW_DISABLE; - basePrim.fogging = DRAW_DISABLE; - basePrim.blending = DRAW_DISABLE; - basePrim.antialiasing = DRAW_DISABLE; - basePrim.mapping_type = PRIM_MAP_ST; - basePrim.colorfix = PRIM_UNFIXED; + prim.type = PRIM_LINE; + prim.shading = PRIM_SHADE_FLAT; + prim.mapping = DRAW_DISABLE; + prim.fogging = DRAW_DISABLE; + prim.blending = DRAW_DISABLE; + prim.antialiasing = DRAW_ENABLE; + prim.mapping_type = PRIM_MAP_ST; + prim.colorfix = PRIM_UNFIXED; - baseColor.r = 0x80; - baseColor.g = 0x80; - baseColor.b = 0x80; - baseColor.a = 0x80; - baseColor.q = 1.0F; + const auto& settings = core->getSettings(); + planesClipAlgorithm.init(settings); } -void Renderer3DUtility::drawPoint(const Vec4& v) { - drawPoint(v, Color(128.0F, 0.0F, 0.0F, 128.0F)); +void Renderer3DUtility::drawBox(const Vec4& v, const float& size) { + drawBox(v, size, Color(192.0F, 32.0F, 32.0F, 128.0F)); } void Renderer3DUtility::drawLine(const Vec4& from, const Vec4& to) { - drawLine(from, to, Color(255.0F, 32.0F, 32.0F, 128.0F)); + drawLine(from, to, Color(192.0F, 32.0F, 32.0F, 128.0F)); } void Renderer3DUtility::drawBBox(const CoreBBox& v) { - drawBBox(v, Color(255.0F, 32.0F, 32.0F, 128.0F)); + drawBBox(v, Color(192.0F, 32.0F, 32.0F, 128.0F)); } -void Renderer3DUtility::drawPoint(const Vec4& v, const Color& color) { - // TODO +void Renderer3DUtility::drawBox(const Vec4& v, const float& size, + const Color& color) { + auto bbox = CoreBBox::create(v, size); + drawBBox(bbox, color); } void Renderer3DUtility::drawLine(const Vec4& from, const Vec4& to, const Color& color) { - const u16 packetSize = 20; - auto* packet = packet2_create(20, P2_TYPE_NORMAL, P2_MODE_CHAIN, false); + const u8 vertCount = 2; + const s8 thickness = 2; + s16 packetSize = 8 * thickness; + prim.type = PRIM_LINE; + auto gsColor = getGSColor(color); - auto mvp = core->renderer3D.getViewProj(); - std::array inputVerts; - std::array inputColors; - inputVerts[0] = mvp * from; - inputVerts[1] = mvp * to; - inputColors[0] = {color.r, color.g, color.b, color.a}; - inputColors[1] = {color.r, color.g, color.b, color.a}; + auto* packet = + packet2_create(packetSize, P2_TYPE_NORMAL, P2_MODE_CHAIN, false); - std::array outputVerts; - std::array outputColors; + std::array inputVerts; + inputVerts[0] = from; + inputVerts[1] = to; - draw_convert_xyz(outputVerts.data(), 2048, 2048, - static_cast(0xFFFFFF / 32.0F), 2, - reinterpret_cast(inputVerts.data())); - draw_convert_rgbq(outputColors.data(), 2, - reinterpret_cast(inputVerts.data()), - inputColors.data(), 0x80); + std::array outputVerts; packet2_chain_open_end(packet, 0, 0); + packet2_update(packet, draw_prim_start(packet->next, 0, &prim, &gsColor)); - basePrim.type = PRIM_LINE; + for (s8 i = 0; i < thickness; i++) { + auto draw = + calcLineVertices(outputVerts.data(), inputVerts[0], inputVerts[1], i); + + if (!draw) { + packet2_free(packet); + return; + } + + packet2_add_u64(packet, outputVerts[0].xyz); + packet2_add_u64(packet, outputVerts[1].xyz); + } + + packet2_pad128(packet, 0); packet2_update(packet, - draw_prim_start(packet->next, 0, &basePrim, &baseColor)); - for (auto i = 0; i < 2; i++) { - packet2_add_u64(packet, outputColors[i].rgbaq); - packet2_add_u64(packet, outputVerts[i].xyz); - } - packet2_update(packet, draw_prim_end(packet->next, 2, DRAW_RGBAQ_REGLIST)); + draw_prim_end(packet->next, 2, TYRA_UTILS_LINE_REGLIST)); packet2_update(packet, draw_finish(packet->next)); packet2_chain_close_tag(packet); - TYRA_ASSERT(packet2_get_qw_count(packet) < packetSize, - "To small packet size!"); - dma_channel_wait(DMA_CHANNEL_GIF, 0); dma_channel_send_packet2(packet, DMA_CHANNEL_GIF, true); dma_channel_wait(DMA_CHANNEL_GIF, 0); @@ -108,7 +110,189 @@ void Renderer3DUtility::drawLine(const Vec4& from, const Vec4& to, } void Renderer3DUtility::drawBBox(const CoreBBox& v, const Color& color) { - // TODO + const u8 stripsCount = 6; + const u8 vertCount = 4; + const s8 thickness = 2; + s16 packetSize = 150 * thickness; + prim.type = PRIM_LINE; + auto gsColor = getGSColor(color); + + auto* packet = + packet2_create(packetSize, P2_TYPE_NORMAL, P2_MODE_CHAIN, false); + + std::array, stripsCount> inputVerts; + fillBBoxVertices(inputVerts, v); + + packet2_chain_open_end(packet, 0, 0); + + bool drawedSomething = false; + + for (s8 i = 0; i < thickness; i++) { + for (s8 j = 0; j < stripsCount; j++) { + for (s8 k = 0; k < vertCount; k++) { + auto index1 = k; + auto index2 = (k + 1) % vertCount; + + std::array outputVerts; + auto draw = calcLineVertices(outputVerts.data(), inputVerts[j][index1], + inputVerts[j][index2], i); + + if (!draw) { + continue; + } + + drawedSomething = true; + + packet2_update(packet, + draw_prim_start(packet->next, 0, &prim, &gsColor)); + + packet2_add_u64(packet, outputVerts[0].xyz); + packet2_add_u64(packet, outputVerts[1].xyz); + + packet2_update(packet, + draw_prim_end(packet->next, 2, TYRA_UTILS_LINE_REGLIST)); + + packet2_pad128(packet, 0); + } + } + } + + if (!drawedSomething) { + packet2_free(packet); + return; + } + + packet2_update(packet, draw_finish(packet->next)); + + packet2_chain_close_tag(packet); + + dma_channel_wait(DMA_CHANNEL_GIF, 0); + dma_channel_send_packet2(packet, DMA_CHANNEL_GIF, true); + dma_channel_wait(DMA_CHANNEL_GIF, 0); + + packet2_free(packet); +} + +void Renderer3DUtility::fillBBoxVertices(std::array, 6>& v, + const CoreBBox& bbox) { + // Up + /** + * 2 - lowX, hiY, lowZ + * 3 - lowX, hiY, hiZ + * 7 - hiX, hiY, hiZ + * 6 - hiX, hiY, lowZ + */ + v[1][0] = bbox.vertices[2]; + v[1][1] = bbox.vertices[3]; + v[1][2] = bbox.vertices[7]; + v[1][3] = bbox.vertices[6]; + + // Down + /** + * 0 - lowX, lowY, lowZ + * 1 - lowX, lowY, hiZ + * 5 - hiX, lowY, hiZ + * 4 - hiX, lowY, lowZ + */ + v[0][0] = bbox.vertices[0]; + v[0][1] = bbox.vertices[1]; + v[0][2] = bbox.vertices[5]; + v[0][3] = bbox.vertices[4]; + + // Near + /** + * 0 - lowX, lowY, lowZ + * 2 - lowX, hiY, lowZ + * 6 - hiX, hiY, lowZ + * 4 - hiX, lowY, lowZ + */ + v[2][0] = bbox.vertices[0]; + v[2][1] = bbox.vertices[2]; + v[2][2] = bbox.vertices[6]; + v[2][3] = bbox.vertices[4]; + + // Far + /** + * 1 - lowX, lowY, hiZ + * 3 - lowX, hiY, hiZ + * 7 - hiX, hiY, hiZ + * 5 - hiX, lowY, hiZ + */ + v[3][0] = bbox.vertices[1]; + v[3][1] = bbox.vertices[3]; + v[3][2] = bbox.vertices[7]; + v[3][3] = bbox.vertices[5]; + + // Left + /** + * 0 - lowX, lowY, lowZ + * 1 - lowX, lowY, hiZ + * 3 - lowX, hiY, hiZ + * 2 - lowX, hiY, lowZ + */ + v[4][0] = bbox.vertices[0]; + v[4][1] = bbox.vertices[1]; + v[4][2] = bbox.vertices[3]; + v[4][3] = bbox.vertices[2]; + + // Right + /** + * 4 - hiX, lowY, lowZ + * 5 - hiX, lowY, hiZ + * 7 - hiX, hiY, hiZ + * 6 - hiX, hiY, lowZ + */ + v[5][0] = bbox.vertices[4]; + v[5][1] = bbox.vertices[5]; + v[5][2] = bbox.vertices[7]; + v[5][3] = bbox.vertices[6]; +} + +color_t Renderer3DUtility::getGSColor(const Color& color) { + color_t gsColor; + gsColor.r = static_cast(color.r); + gsColor.g = static_cast(color.g); + gsColor.b = static_cast(color.b); + gsColor.a = static_cast(color.a); + return gsColor; +} + +bool Renderer3DUtility::calcLineVertices(xyz_t* outputArray, const Vec4& a, + const Vec4& b, + const u8& displayOffset) { + const auto& mvp = core->renderer3D.getViewProj(); + Vec4 tmpA = mvp * a; + Vec4 tmpB = mvp * b; + + clipInput[0].position = &tmpA; + clipInput[1].position = &tmpB; + clipInput[2].position = &tmpA; + + auto clippedSize = planesClipAlgorithm.clip( + clippedVerts.data(), clipInput.data(), {false, false, false}); + + if (clippedSize == 0) { + return false; + } + + // Perspective divide + clippedVerts[0].position /= clippedVerts[0].position.w; + clippedVerts[1].position /= clippedVerts[1].position.w; + + // To screen space + s32 centerX = ftoi4(2048 + displayOffset); + s32 centerY = ftoi4(2048 + displayOffset); + const u32 maxZ = ftoi4(((float)0xFFFFFF) / 32.0F); + + outputArray[0].x = (clippedVerts[0].position.x + 1.0F) * centerX; + outputArray[0].y = (clippedVerts[0].position.y + 1.0F) * centerY; + outputArray[0].z = (clippedVerts[0].position.z + 1.0F) * maxZ; + + outputArray[1].x = (clippedVerts[1].position.x + 1.0F) * centerX; + outputArray[1].y = (clippedVerts[1].position.y + 1.0F) * centerY; + outputArray[1].z = (clippedVerts[1].position.z + 1.0F) * maxZ; + + return true; } } // namespace Tyra diff --git a/engine/src/renderer/core/2d/renderer_core_2d.cpp b/engine/src/renderer/core/2d/renderer_core_2d.cpp index 2b861a9..985c0f0 100644 --- a/engine/src/renderer/core/2d/renderer_core_2d.cpp +++ b/engine/src/renderer/core/2d/renderer_core_2d.cpp @@ -32,7 +32,7 @@ RendererCore2D::~RendererCore2D() { delete rects[1]; } -const float RendererCore2D::GS_CENTER = 4096.0F; +const float RendererCore2D::GS_DRAW_AREA = 4096.0F; const float RendererCore2D::SCREEN_CENTER = 4096.0F / 2.0F; void RendererCore2D::setPrim() { diff --git a/engine/src/renderer/core/3d/bbox/core_bbox.cpp b/engine/src/renderer/core/3d/bbox/core_bbox.cpp index 2559a71..126189d 100644 --- a/engine/src/renderer/core/3d/bbox/core_bbox.cpp +++ b/engine/src/renderer/core/3d/bbox/core_bbox.cpp @@ -143,6 +143,10 @@ CoreBBox::CoreBBox(const CoreBBox& t_bbox) { Vec4::copy(&vertices[i], t_bbox.vertices[i].xyzw); } +void CoreBBox::operator=(const CoreBBox& v) { + for (auto i = 0; i < 8; i++) Vec4::copy(&vertices[i], v.vertices[i].xyzw); +} + CoreBBox::CoreBBox(Vec4* t_vertices) { for (auto i = 0; i < 8; i++) Vec4::copy(&vertices[i], t_vertices[i].xyzw); } @@ -178,6 +182,30 @@ std::string CoreBBox::getPrint(const char* name) const { return res.str(); } +CoreBBox CoreBBox::create(const Vec4& center, const float& size) { + CoreBBox bbox; + + float lowX = center.x - size; + float lowY = center.y - size; + float lowZ = center.z - size; + + float hiX = center.x + size; + float hiY = center.y + size; + float hiZ = center.z + size; + + bbox.vertices[0].set(lowX, lowY, lowZ); + bbox.vertices[1].set(lowX, lowY, hiZ); + bbox.vertices[2].set(lowX, hiY, lowZ); + bbox.vertices[3].set(lowX, hiY, hiZ); + + bbox.vertices[4].set(hiX, lowY, lowZ); + bbox.vertices[5].set(hiX, lowY, hiZ); + bbox.vertices[6].set(hiX, hiY, lowZ); + bbox.vertices[7].set(hiX, hiY, hiZ); + + return bbox; +} + CoreBBoxFrustum CoreBBox::isInFrustum(const Plane* frustumPlanes, const M4x4& model, const float* margins) const { diff --git a/engine/src/renderer/core/3d/clipper/ee_clip_algorithm.cpp b/engine/src/renderer/core/3d/clipper/planes_clip_algorithm.cpp similarity index 75% rename from engine/src/renderer/core/3d/clipper/ee_clip_algorithm.cpp rename to engine/src/renderer/core/3d/clipper/planes_clip_algorithm.cpp index 9252b93..6adbd6d 100644 --- a/engine/src/renderer/core/3d/clipper/ee_clip_algorithm.cpp +++ b/engine/src/renderer/core/3d/clipper/planes_clip_algorithm.cpp @@ -8,25 +8,28 @@ # Sandro Sobczyński */ -#include "renderer/core/3d/clipper/ee_clip_algorithm.hpp" +#include "renderer/core/3d/clipper/planes_clip_algorithm.hpp" namespace Tyra { -EEClipAlgorithm::EEClipAlgorithm() { tempVertices = new EEClipVertex[9]; } +PlanesClipAlgorithm::PlanesClipAlgorithm() { + tempVertices = new PlanesClipVertex[9]; +} -EEClipAlgorithm::~EEClipAlgorithm() { delete[] tempVertices; } +PlanesClipAlgorithm::~PlanesClipAlgorithm() { delete[] tempVertices; } -float EEClipAlgorithm::clipMargin = -10.0F; +float PlanesClipAlgorithm::clipMargin = -10.0F; -void EEClipAlgorithm::init(const RendererSettings& settings) { +void PlanesClipAlgorithm::init(const RendererSettings& settings) { halfWidth = 0.5F; halfHeight = 0.5F; near = settings.getNear() - (-clipMargin); far = -settings.getFar(); } -u8 EEClipAlgorithm::clip(EEClipVertex* o_vertices, EEClipVertexPtrs* i_vertices, - const EEClipAlgorithmSettings& settings) { +u8 PlanesClipAlgorithm::clip(PlanesClipVertex* o_vertices, + PlanesClipVertexPtrs* i_vertices, + const EEClipAlgorithmSettings& settings) { for (int i = 0; i < 3; i++) { o_vertices[i].position = *i_vertices[i].position; if (settings.lerpColors) o_vertices[i].color = *i_vertices[i].color; @@ -58,8 +61,8 @@ u8 EEClipAlgorithm::clip(EEClipVertex* o_vertices, EEClipVertexPtrs* i_vertices, return outputSize; } -float EEClipAlgorithm::getValueByPlane(const EEClipVertex& v, - const int& plane) { +float PlanesClipAlgorithm::getValueByPlane(const PlanesClipVertex& v, + const int& plane) { switch (plane) { case 1: return v.position.x; // x plane @@ -73,8 +76,9 @@ float EEClipAlgorithm::getValueByPlane(const EEClipVertex& v, } } -bool EEClipAlgorithm::isInside(const int& plane, const float& v, const float& w, - const float& planeLimitValue) { +bool PlanesClipAlgorithm::isInside(const int& plane, const float& v, + const float& w, + const float& planeLimitValue) { switch (plane) { case 3: return v <= planeLimitValue; // near z plane @@ -86,11 +90,10 @@ bool EEClipAlgorithm::isInside(const int& plane, const float& v, const float& w, } } -u8 EEClipAlgorithm::clipAgainstPlane(EEClipVertex* original, - const u8& originalSize, - EEClipVertex* clipped, const int& plane, - const float& planeLimitValue, - const EEClipAlgorithmSettings& settings) { +u8 PlanesClipAlgorithm::clipAgainstPlane( + PlanesClipVertex* original, const u8& originalSize, + PlanesClipVertex* clipped, const int& plane, const float& planeLimitValue, + const EEClipAlgorithmSettings& settings) { int clippedSize = 0; for (u32 i = 0; i < originalSize; i++) {