utility functions

This commit is contained in:
h4570
2022-08-17 00:19:16 +02:00
parent 4fb0ab3b6c
commit fea2398699
27 changed files with 419 additions and 247 deletions
+4 -4
View File
@@ -1,10 +1,9 @@
------------ Tyra's v2.0 roadmap to publish on GitHub ------------ ------------ Tyra's v2.0 roadmap to publish on GitHub ------------
- [Renderer] utility functions
- [Demo] Red screen on hit - [Demo] Red screen on hit
- [Demo] Count of killed zombies - [HUD] Count of killed zombies
- [Demo] Crosshair - [HUD] Crosshair
- [Demo] 2D Health bar - [HUD] 2D Health bar
- [Demo] Game over screen - [Demo] Game over screen
- [Demo] Game fadein with audio information about island - [Demo] Game fadein with audio information about island
- [General] USB test - [General] USB test
@@ -36,6 +35,7 @@ because Mesh rendering uses only core.render()
------------ Github issues for Tyra v2 ------------ ------------ Github issues for Tyra v2 ------------
- [renderer] fog - [renderer] fog
- [renderer] bbox parts optimization - [renderer] bbox parts optimization
- [General] smart pointers and std::array instead of raw pointers
- [md2] refactor - [md2] refactor
- [2D] Fixed font support - [2D] Fixed font support
- [File] Async file loading - [File] Async file loading
-40
View File
@@ -1,40 +0,0 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#pragma once
#include <tyra>
#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
-2
View File
@@ -17,7 +17,6 @@
#include "./terrain/terrain.hpp" #include "./terrain/terrain.hpp"
#include "./skybox/skybox.hpp" #include "./skybox/skybox.hpp"
#include "./ship/ship.hpp" #include "./ship/ship.hpp"
#include "./debug_object.hpp"
#include "./enemy/enemy_manager.hpp" #include "./enemy/enemy_manager.hpp"
namespace Demo { namespace Demo {
@@ -50,7 +49,6 @@ class GameState : public State<GlobalStateType> {
Terrain* terrain; Terrain* terrain;
Skybox* skybox; Skybox* skybox;
Ship* ship; Ship* ship;
DebugObject* dbgObj;
}; };
} // namespace Demo } // namespace Demo
+2
View File
@@ -20,6 +20,7 @@
using Tyra::Engine; using Tyra::Engine;
using Tyra::Pad; using Tyra::Pad;
using Tyra::Renderer3DUtility;
using Tyra::Vec4; using Tyra::Vec4;
namespace Demo { namespace Demo {
@@ -41,6 +42,7 @@ class Player {
private: private:
void handlePlayerPosition(const Heightmap& heightmap, void handlePlayerPosition(const Heightmap& heightmap,
const float& terrainHeight); const float& terrainHeight);
Renderer3DUtility* utility;
float speed; float speed;
Pad* pad; Pad* pad;
@@ -32,6 +32,7 @@ class GameRenderer {
void clear(); void clear();
void renderSkybox(const RendererStaticPair& pair);
void render(); void render();
private: private:
-65
View File
@@ -1,65 +0,0 @@
/*
# _____ ____ ___
# | \/ ____| |___|
# | | | \ | |
#-----------------------------------------------------------------------
# Copyright 2022, tyra - https://github.com/h4570/tyra
# Licensed under Apache License 2.0
# Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/
#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
+1 -4
View File
@@ -92,15 +92,12 @@ void Enemy::handlePlayerShoot(const PlayerShootAction& shootAction) {
} }
const auto& ray = shootAction.ray.value(); const auto& ray = shootAction.ray.value();
auto bbox = auto bbox =
mesh->getCurrentBoundingBox().getTransformed(mesh->getModelMatrix()); mesh->getCurrentBoundingBox().getTransformed(mesh->getModelMatrix());
auto isOnEnemy = ray.intersectBox(bbox.min(), bbox.max()); auto isOnEnemy = ray.intersectBox(bbox.min(), bbox.max());
utility->drawBBox(bbox);
utility->drawLine(ray.origin, ray.direction);
utility->drawPoint(*mesh->getPosition());
if (isOnEnemy) { if (isOnEnemy) {
mesh->setPosition(spawnPoint); mesh->setPosition(spawnPoint);
TYRA_LOG("Enemy hit!"); TYRA_LOG("Enemy hit!");
+1 -1
View File
@@ -43,7 +43,7 @@ EnemyManager::EnemyManager(Engine* engine, const Heightmap& heightmap) {
auto* sample = engine->audio.adpcm.load( auto* sample = engine->audio.adpcm.load(
FileUtils::fromCwd("game/models/zombie/punch.adpcm")); FileUtils::fromCwd("game/models/zombie/punch.adpcm"));
const int enemyCount = 2; const int enemyCount = 10;
for (int i = 0; i < enemyCount; i++) { for (int i = 0; i < enemyCount; i++) {
EnemyInfo info; EnemyInfo info;
info.adpcmChannel = 9 + i; info.adpcmChannel = 9 + i;
+15 -16
View File
@@ -39,7 +39,6 @@ void GameState::onStart() {
enemyManager = new EnemyManager(engine, terrain->heightmap); enemyManager = new EnemyManager(engine, terrain->heightmap);
ship = new Ship(repository); ship = new Ship(repository);
skybox = new Skybox(repository); skybox = new Skybox(repository);
dbgObj = new DebugObject(repository);
initialized = true; initialized = true;
} }
@@ -52,41 +51,41 @@ GlobalStateType GameState::onFinish() {
delete terrain; delete terrain;
delete ship; delete ship;
delete skybox; delete skybox;
delete dbgObj;
initialized = false; initialized = false;
return STATE_EXIT; return STATE_EXIT;
} }
void GameState::update() { 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) { if (fpsChecker++ > 50) {
TYRA_LOG("FPS: ", engine->info.getFps(), TYRA_LOG("FPS: ", engine->info.getFps(),
" RAM: ", engine->info.getAvailableRAM()); " RAM: ", engine->info.getAvailableRAM());
fpsChecker = 0; fpsChecker = 0;
} }
player->update(terrain->heightmap); // Game logic
skybox->update(player->getPosition());
auto shootAction = player->getShootAction(); auto shootAction = player->getShootAction();
enemyManager->update(terrain->heightmap, player->getPosition(), shootAction); enemyManager->update(terrain->heightmap, player->getPosition(), shootAction);
auto cameraInfo = player->getCameraInfo(); // Render other stuff
dbgObj->setPosition(*cameraInfo.looksAt);
engine->renderer.beginFrame(cameraInfo);
{
renderer.clear();
{
renderer.add(skybox->pair); // First, because of ALLPASS
renderer.add(ship->pair); renderer.add(ship->pair);
renderer.add(dbgObj->pair);
renderer.add(player->pair); renderer.add(player->pair);
renderer.add(enemyManager->getPairs()); renderer.add(enemyManager->getPairs());
renderer.add(terrain->pair); renderer.add(terrain->pair);
}
renderer.render(); renderer.render();
}
// End frame
engine->renderer.endFrame(); engine->renderer.endFrame();
} }
+7
View File
@@ -19,6 +19,8 @@ Player::Player(Engine* engine)
position = Vec4(3.0F, 50.0F, 0.0F); position = Vec4(3.0F, 50.0F, 0.0F);
camera.lookAt = Vec4(0.0F, 0.0F, -30.0F); camera.lookAt = Vec4(0.0F, 0.0F, -30.0F);
speed = 5.0F; speed = 5.0F;
utility = &engine->renderer.renderer3D.utility;
} }
Player::~Player() { delete pair; } Player::~Player() { delete pair; }
@@ -39,6 +41,11 @@ PlayerShootAction Player::getShootAction() const {
action.ray = Ray(camera.position, camera.lookAt.getNormalized()); 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; return action;
} }
@@ -46,6 +46,11 @@ void GameRenderer::clear() {
dynamicPairs.clear(); dynamicPairs.clear();
} }
void GameRenderer::renderSkybox(const RendererStaticPair& pair) {
renderer->renderer3D.usePipeline(&stpip);
stpip.render(pair.mesh, pair.options);
}
void GameRenderer::render() { void GameRenderer::render() {
if (staticPairs.size()) { if (staticPairs.size()) {
renderer->renderer3D.usePipeline(&stpip); renderer->renderer3D.usePipeline(&stpip);
+5 -1
View File
@@ -19,13 +19,17 @@ namespace Tyra {
/** Bounding box with more features */ /** Bounding box with more features */
class BBox : public CoreBBox { class BBox : public CoreBBox {
public: public:
BBox(const BBox& t_bbox);
explicit BBox(CoreBBox** t_bboxes, const u32& count); explicit BBox(CoreBBox** t_bboxes, const u32& count);
explicit BBox(Vec4* t_vertices, u32* faces, u32 t_count); explicit BBox(Vec4* t_vertices, u32* faces, u32 t_count);
explicit BBox(Vec4* t_vertices, 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, const M4x4& t_matrix);
explicit BBox(const BBox& t_bbox);
explicit BBox(Vec4* t_vertices); 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& getHeight() const { return _height; }
const float& getDepth() const { return _depth; } const float& getDepth() const { return _depth; }
const float& getWidth() const { return _width; } const float& getWidth() const { return _width; }
@@ -18,7 +18,7 @@
#include "../../mcpip_block.hpp" #include "../../mcpip_block.hpp"
#include "../../data/mcpip_block_data.hpp" #include "../../data/mcpip_block_data.hpp"
#include "./mcpip_vu1_as_is_shared_defines.h" #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 { namespace Tyra {
@@ -27,7 +27,7 @@ class McpipClip {
McpipClip(); McpipClip();
~McpipClip(); ~McpipClip();
EEClipAlgorithm algorithm; PlanesClipAlgorithm algorithm;
EEClipAlgorithmSettings algoSettings; EEClipAlgorithmSettings algoSettings;
void init(RendererCore* core, McpipBlockData* t_singleBlockData, void init(RendererCore* core, McpipBlockData* t_singleBlockData,
@@ -52,14 +52,16 @@ class McpipClip {
u16 vu1DBufferSize; u16 vu1DBufferSize;
Vec4 inputVerts[3]; Vec4 inputVerts[3];
EEClipVertexPtrs inputTriangle[3]; PlanesClipVertexPtrs inputTriangle[3];
EEClipVertex clippedTriangle[9]; PlanesClipVertex clippedTriangle[9];
Vec4 vertexBuffers[2][108]; Vec4 vertexBuffers[2][108];
Vec4 texCoordBuffers[2][108]; Vec4 texCoordBuffers[2][108];
void addCorrections(std::vector<EEClipVertex>* vertices, McpipBlock* block); void addCorrections(std::vector<PlanesClipVertex>* vertices,
void moveDataToBuffer(std::vector<EEClipVertex>* vertices, const u8& context); McpipBlock* block);
void moveDataToBuffer(std::vector<PlanesClipVertex>* vertices,
const u8& context);
void addDataToPacket(packet2_t* packet, const u8& context, McpipBlock* block, void addDataToPacket(packet2_t* packet, const u8& context, McpipBlock* block,
const int& count, const int& count,
RendererCoreTextureBuffers* texBuffers); RendererCoreTextureBuffers* texBuffers);
@@ -12,7 +12,7 @@
#include "renderer/core/3d/bbox/core_bbox.hpp" #include "renderer/core/3d/bbox/core_bbox.hpp"
#include "renderer/core/3d/renderer_3d_frustum_planes.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_packages_bbox.hpp"
#include "./stapip_bag_package.hpp" #include "./stapip_bag_package.hpp"
#include "../stapip_bag.hpp" #include "../stapip_bag.hpp"
@@ -14,7 +14,7 @@
#include "debug/debug.hpp" #include "debug/debug.hpp"
#include "./stapip_qbuffer.hpp" #include "./stapip_qbuffer.hpp"
#include "renderer/renderer_settings.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 { namespace Tyra {
@@ -36,15 +36,15 @@ class StaPipClipper {
private: private:
u32 maxVertCount; u32 maxVertCount;
EEClipAlgorithm algorithm; PlanesClipAlgorithm algorithm;
M4x4* mvp; M4x4* mvp;
Vec4 inputVerts[3]; Vec4 inputVerts[3];
EEClipVertexPtrs inputTriangle[3]; PlanesClipVertexPtrs inputTriangle[3];
EEClipVertex clippedTriangle[9]; PlanesClipVertex clippedTriangle[9];
void perspectiveDivide(std::vector<EEClipVertex>* vertices); void perspectiveDivide(std::vector<PlanesClipVertex>* vertices);
void moveDataToBuffer(const std::vector<EEClipVertex>& vertices, void moveDataToBuffer(const std::vector<PlanesClipVertex>& vertices,
StaPipQBuffer* buffer); StaPipQBuffer* buffer);
}; };
+27 -5
View File
@@ -14,10 +14,16 @@
#include "renderer/models/color.hpp" #include "renderer/models/color.hpp"
#include "renderer/core/3d/bbox/core_bbox.hpp" #include "renderer/core/3d/bbox/core_bbox.hpp"
#include "../core/renderer_core.hpp" #include "../core/renderer_core.hpp"
#include "renderer/core/3d/clipper/planes_clip_algorithm.hpp"
namespace Tyra { 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 { class Renderer3DUtility {
public: public:
Renderer3DUtility(); Renderer3DUtility();
@@ -25,8 +31,8 @@ class Renderer3DUtility {
void init(RendererCore* core); void init(RendererCore* core);
void drawPoint(const Vec4& v); void drawBox(const Vec4& v, const float& size);
void drawPoint(const Vec4& v, const Color& color); 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);
void drawLine(const Vec4& from, const Vec4& to, const Color& color); 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); void drawBBox(const CoreBBox& v, const Color& color);
private: private:
std::array<PlanesClipVertex, 9> clippedVerts;
std::array<PlanesClipVertexPtrs, 3> clipInput;
RendererCore* core; RendererCore* core;
prim_t basePrim; prim_t prim;
color_t baseColor;
void fillBBoxVertices(std::array<std::array<Vec4, 4>, 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 } // namespace Tyra
@@ -37,7 +37,7 @@ class RendererCore2D {
prim_t prim; prim_t prim;
lod_t lod; lod_t lod;
static const float GS_CENTER; static const float GS_DRAW_AREA;
static const float SCREEN_CENTER; static const float SCREEN_CENTER;
u8 context; u8 context;
+18 -3
View File
@@ -21,17 +21,31 @@ namespace Tyra {
/** Bounding box */ /** Bounding box */
class CoreBBox { class CoreBBox {
public: 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* faces, u32 t_count);
explicit CoreBBox(Vec4* t_vertices, u32 t_count); explicit CoreBBox(Vec4* t_vertices, u32 t_count);
explicit CoreBBox(Vec4* t_vertices); explicit CoreBBox(Vec4* t_vertices);
explicit CoreBBox(const CoreBBox& t_bbox);
explicit CoreBBox(CoreBBox** t_bboxes, const u32& count); explicit CoreBBox(CoreBBox** t_bboxes, const u32& count);
explicit CoreBBox(const std::vector<CoreBBox>& t_bboxes, explicit CoreBBox(const std::vector<CoreBBox>& t_bboxes,
const u32& startIndex, const u32& stopIndex); 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]; Vec4 vertices[8];
void operator=(const CoreBBox& v);
const Vec4& operator[](const u8& i) const { return vertices[i]; } const Vec4& operator[](const u8& i) const { return vertices[i]; }
const u8 getVertexCount() const { return 8; } const u8 getVertexCount() const { return 8; }
@@ -44,7 +58,8 @@ class CoreBBox {
/** /**
* @brief Check if bbox is in view frustum * @brief Check if bbox is in view frustum
* *
* @param frustumPlanes Available in engine.renderer.core.renderer3D.frustumPlanes * @param frustumPlanes Available in
* engine.renderer.core.renderer3D.frustumPlanes
* @param model Model matrix * @param model Model matrix
* @param margins Optional margins * @param margins Optional margins
*/ */
@@ -11,7 +11,7 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include "./ee_clip_vertex.hpp" #include "./planes_clip_vertex.hpp"
#include "debug/debug.hpp" #include "debug/debug.hpp"
#include "renderer/renderer_settings.hpp" #include "renderer/renderer_settings.hpp"
@@ -21,30 +21,30 @@ struct EEClipAlgorithmSettings {
bool lerpNormals, lerpTexCoords, lerpColors; bool lerpNormals, lerpTexCoords, lerpColors;
}; };
class EEClipAlgorithm { class PlanesClipAlgorithm {
public: public:
EEClipAlgorithm(); PlanesClipAlgorithm();
~EEClipAlgorithm(); ~PlanesClipAlgorithm();
void init(const RendererSettings& settings); void init(const RendererSettings& settings);
u8 clip(EEClipVertex* o_vertices, EEClipVertexPtrs* i_vertices, u8 clip(PlanesClipVertex* o_vertices, PlanesClipVertexPtrs* i_vertices,
const EEClipAlgorithmSettings& settings); const EEClipAlgorithmSettings& settings);
static float clipMargin; static float clipMargin;
private: private:
float halfWidth, halfHeight, near, far; 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, bool isInside(const int& plane, const float& v, const float& w,
const float& planeLimitValue); const float& planeLimitValue);
/** @return clipped size */ /** @return clipped size */
u8 clipAgainstPlane(EEClipVertex* original, const u8& originalSize, u8 clipAgainstPlane(PlanesClipVertex* original, const u8& originalSize,
EEClipVertex* clipped, const int& plane, PlanesClipVertex* clipped, const int& plane,
const float& planeLimitValue, const float& planeLimitValue,
const EEClipAlgorithmSettings& settings); const EEClipAlgorithmSettings& settings);
}; };
@@ -14,11 +14,11 @@
namespace Tyra { namespace Tyra {
struct EEClipVertex { struct PlanesClipVertex {
Vec4 position, normal, st, color; Vec4 position, normal, st, color;
}; };
struct EEClipVertexPtrs { struct PlanesClipVertexPtrs {
Vec4 *position, *normal, *st, *color; Vec4 *position, *normal, *st, *color;
}; };
+10
View File
@@ -102,6 +102,16 @@ Vec4 BBox::max() const {
return _max; 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 { void BBox::getMinMax(Vec4* res_min, Vec4* res_max) const {
Vec4 temp = Vec4(); Vec4 temp = Vec4();
@@ -60,7 +60,7 @@ void McpipClip::initStaticPacket() {
void McpipClip::addData(McpipBlock* block, const bool& isMulti, void McpipClip::addData(McpipBlock* block, const bool& isMulti,
RendererCoreTextureBuffers* texBuffers, RendererCoreTextureBuffers* texBuffers,
packet2_t* packet, const u8& context) { packet2_t* packet, const u8& context) {
std::vector<EEClipVertex> clippedVertices; std::vector<PlanesClipVertex> clippedVertices;
auto mvp = rendererCore->renderer3D.getViewProj() * (*block->model); auto mvp = rendererCore->renderer3D.getViewProj() * (*block->model);
const auto* blockData = isMulti ? multiBlockData : singleBlockData; 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); addDataToPacket(packet, context, block, clippedVertices.size(), texBuffers);
} }
void McpipClip::addCorrections(std::vector<EEClipVertex>* vertices, void McpipClip::addCorrections(std::vector<PlanesClipVertex>* vertices,
McpipBlock* block) { McpipBlock* block) {
for (u32 i = 0; i < vertices->size(); i++) { for (u32 i = 0; i < vertices->size(); i++) {
(*vertices)[i].position /= (*vertices)[i].position.w; // Perspective divide (*vertices)[i].position /= (*vertices)[i].position.w; // Perspective divide
@@ -100,7 +100,7 @@ void McpipClip::addCorrections(std::vector<EEClipVertex>* vertices,
} }
} }
void McpipClip::moveDataToBuffer(std::vector<EEClipVertex>* vertices, void McpipClip::moveDataToBuffer(std::vector<PlanesClipVertex>* vertices,
const u8& context) { const u8& context) {
for (u32 i = 0; i < vertices->size(); i++) { for (u32 i = 0; i < vertices->size(); i++) {
vertexBuffers[context][i].set(vertices->at(i).position); vertexBuffers[context][i].set(vertices->at(i).position);
@@ -31,7 +31,7 @@ void StaPipClipper::clip(StaPipQBuffer* buffer) {
buffer->bag->texture != nullptr, buffer->bag->texture != nullptr,
buffer->bag->color->many != nullptr}; buffer->bag->color->many != nullptr};
std::vector<EEClipVertex> clippedVertices; std::vector<PlanesClipVertex> clippedVertices;
for (u32 i = 0; i < buffer->size / 3; i++) { for (u32 i = 0; i < buffer->size / 3; i++) {
for (u8 j = 0; j < 3; j++) { for (u8 j = 0; j < 3; j++) {
@@ -63,14 +63,14 @@ void StaPipClipper::clip(StaPipQBuffer* buffer) {
moveDataToBuffer(clippedVertices, buffer); moveDataToBuffer(clippedVertices, buffer);
} }
void StaPipClipper::perspectiveDivide(std::vector<EEClipVertex>* vertices) { void StaPipClipper::perspectiveDivide(std::vector<PlanesClipVertex>* vertices) {
for (u32 i = 0; i < vertices->size(); i++) { for (u32 i = 0; i < vertices->size(); i++) {
(*vertices)[i].position /= (*vertices)[i].position.w; (*vertices)[i].position /= (*vertices)[i].position.w;
} }
} }
void StaPipClipper::moveDataToBuffer(const std::vector<EEClipVertex>& vertices, void StaPipClipper::moveDataToBuffer(
StaPipQBuffer* buffer) { const std::vector<PlanesClipVertex>& vertices, StaPipQBuffer* buffer) {
buffer->reallocateManually(vertices.size()); buffer->reallocateManually(vertices.size());
for (u32 i = 0; i < vertices.size(); i++) { for (u32 i = 0; i < vertices.size(); i++) {
+231 -47
View File
@@ -23,83 +23,85 @@ Renderer3DUtility::Renderer3DUtility() {}
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) { void Renderer3DUtility::init(RendererCore* t_core) {
core = t_core; core = t_core;
basePrim.type = PRIM_LINE; prim.type = PRIM_LINE;
basePrim.shading = PRIM_SHADE_FLAT; prim.shading = PRIM_SHADE_FLAT;
basePrim.mapping = DRAW_DISABLE; prim.mapping = DRAW_DISABLE;
basePrim.fogging = DRAW_DISABLE; prim.fogging = DRAW_DISABLE;
basePrim.blending = DRAW_DISABLE; prim.blending = DRAW_DISABLE;
basePrim.antialiasing = DRAW_DISABLE; prim.antialiasing = DRAW_ENABLE;
basePrim.mapping_type = PRIM_MAP_ST; prim.mapping_type = PRIM_MAP_ST;
basePrim.colorfix = PRIM_UNFIXED; prim.colorfix = PRIM_UNFIXED;
baseColor.r = 0x80; const auto& settings = core->getSettings();
baseColor.g = 0x80; planesClipAlgorithm.init(settings);
baseColor.b = 0x80;
baseColor.a = 0x80;
baseColor.q = 1.0F;
} }
void Renderer3DUtility::drawPoint(const Vec4& v) { void Renderer3DUtility::drawBox(const Vec4& v, const float& size) {
drawPoint(v, Color(128.0F, 0.0F, 0.0F, 128.0F)); drawBox(v, size, Color(192.0F, 32.0F, 32.0F, 128.0F));
} }
void Renderer3DUtility::drawLine(const Vec4& from, const Vec4& to) { 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) { 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) { void Renderer3DUtility::drawBox(const Vec4& v, const float& size,
// TODO const Color& color) {
auto bbox = CoreBBox::create(v, size);
drawBBox(bbox, color);
} }
void Renderer3DUtility::drawLine(const Vec4& from, const Vec4& to, void Renderer3DUtility::drawLine(const Vec4& from, const Vec4& to,
const Color& color) { const Color& color) {
const u16 packetSize = 20; const u8 vertCount = 2;
auto* packet = packet2_create(20, P2_TYPE_NORMAL, P2_MODE_CHAIN, false); const s8 thickness = 2;
s16 packetSize = 8 * thickness;
prim.type = PRIM_LINE;
auto gsColor = getGSColor(color);
auto mvp = core->renderer3D.getViewProj(); auto* packet =
std::array<Vec4, 2> inputVerts; packet2_create(packetSize, P2_TYPE_NORMAL, P2_MODE_CHAIN, false);
std::array<color_f_t, 2> 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};
std::array<xyz_t, 2> outputVerts; std::array<Vec4, vertCount> inputVerts;
std::array<color_t, 2> outputColors; inputVerts[0] = from;
inputVerts[1] = to;
draw_convert_xyz(outputVerts.data(), 2048, 2048, std::array<xyz_t, vertCount> outputVerts;
static_cast<int>(0xFFFFFF / 32.0F), 2,
reinterpret_cast<vertex_f_t*>(inputVerts.data()));
draw_convert_rgbq(outputColors.data(), 2,
reinterpret_cast<vertex_f_t*>(inputVerts.data()),
inputColors.data(), 0x80);
packet2_chain_open_end(packet, 0, 0); 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, packet2_update(packet,
draw_prim_start(packet->next, 0, &basePrim, &baseColor)); draw_prim_end(packet->next, 2, TYRA_UTILS_LINE_REGLIST));
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));
packet2_update(packet, draw_finish(packet->next)); packet2_update(packet, draw_finish(packet->next));
packet2_chain_close_tag(packet); 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_wait(DMA_CHANNEL_GIF, 0);
dma_channel_send_packet2(packet, DMA_CHANNEL_GIF, true); dma_channel_send_packet2(packet, DMA_CHANNEL_GIF, true);
dma_channel_wait(DMA_CHANNEL_GIF, 0); 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) { 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<std::array<Vec4, vertCount>, 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<xyz_t, 2> 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<std::array<Vec4, 4>, 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<u8>(color.r);
gsColor.g = static_cast<u8>(color.g);
gsColor.b = static_cast<u8>(color.b);
gsColor.a = static_cast<u8>(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 } // namespace Tyra
@@ -32,7 +32,7 @@ RendererCore2D::~RendererCore2D() {
delete rects[1]; 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; const float RendererCore2D::SCREEN_CENTER = 4096.0F / 2.0F;
void RendererCore2D::setPrim() { void RendererCore2D::setPrim() {
@@ -143,6 +143,10 @@ CoreBBox::CoreBBox(const CoreBBox& t_bbox) {
Vec4::copy(&vertices[i], t_bbox.vertices[i].xyzw); 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) { CoreBBox::CoreBBox(Vec4* t_vertices) {
for (auto i = 0; i < 8; i++) Vec4::copy(&vertices[i], t_vertices[i].xyzw); 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(); 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, CoreBBoxFrustum CoreBBox::isInFrustum(const Plane* frustumPlanes,
const M4x4& model, const M4x4& model,
const float* margins) const { const float* margins) const {
@@ -8,24 +8,27 @@
# Sandro Sobczyński <sandro.sobczynski@gmail.com> # Sandro Sobczyński <sandro.sobczynski@gmail.com>
*/ */
#include "renderer/core/3d/clipper/ee_clip_algorithm.hpp" #include "renderer/core/3d/clipper/planes_clip_algorithm.hpp"
namespace Tyra { 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; halfWidth = 0.5F;
halfHeight = 0.5F; halfHeight = 0.5F;
near = settings.getNear() - (-clipMargin); near = settings.getNear() - (-clipMargin);
far = -settings.getFar(); far = -settings.getFar();
} }
u8 EEClipAlgorithm::clip(EEClipVertex* o_vertices, EEClipVertexPtrs* i_vertices, u8 PlanesClipAlgorithm::clip(PlanesClipVertex* o_vertices,
PlanesClipVertexPtrs* i_vertices,
const EEClipAlgorithmSettings& settings) { const EEClipAlgorithmSettings& settings) {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
o_vertices[i].position = *i_vertices[i].position; o_vertices[i].position = *i_vertices[i].position;
@@ -58,7 +61,7 @@ u8 EEClipAlgorithm::clip(EEClipVertex* o_vertices, EEClipVertexPtrs* i_vertices,
return outputSize; return outputSize;
} }
float EEClipAlgorithm::getValueByPlane(const EEClipVertex& v, float PlanesClipAlgorithm::getValueByPlane(const PlanesClipVertex& v,
const int& plane) { const int& plane) {
switch (plane) { switch (plane) {
case 1: case 1:
@@ -73,7 +76,8 @@ float EEClipAlgorithm::getValueByPlane(const EEClipVertex& v,
} }
} }
bool EEClipAlgorithm::isInside(const int& plane, const float& v, const float& w, bool PlanesClipAlgorithm::isInside(const int& plane, const float& v,
const float& w,
const float& planeLimitValue) { const float& planeLimitValue) {
switch (plane) { switch (plane) {
case 3: case 3:
@@ -86,10 +90,9 @@ bool EEClipAlgorithm::isInside(const int& plane, const float& v, const float& w,
} }
} }
u8 EEClipAlgorithm::clipAgainstPlane(EEClipVertex* original, u8 PlanesClipAlgorithm::clipAgainstPlane(
const u8& originalSize, PlanesClipVertex* original, const u8& originalSize,
EEClipVertex* clipped, const int& plane, PlanesClipVertex* clipped, const int& plane, const float& planeLimitValue,
const float& planeLimitValue,
const EEClipAlgorithmSettings& settings) { const EEClipAlgorithmSettings& settings) {
int clippedSize = 0; int clippedSize = 0;