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 ------------
- [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
-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 "./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<GlobalStateType> {
Terrain* terrain;
Skybox* skybox;
Ship* ship;
DebugObject* dbgObj;
};
} // namespace Demo
+2
View File
@@ -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;
@@ -32,6 +32,7 @@ class GameRenderer {
void clear();
void renderSkybox(const RendererStaticPair& pair);
void render();
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();
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!");
+1 -1
View File
@@ -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;
+15 -16
View File
@@ -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);
engine->renderer.beginFrame(cameraInfo);
{
renderer.clear();
{
renderer.add(skybox->pair); // First, because of ALLPASS
// Render other stuff
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();
}
+7
View File
@@ -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;
}
@@ -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);
+5 -1
View File
@@ -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; }
@@ -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<EEClipVertex>* vertices, McpipBlock* block);
void moveDataToBuffer(std::vector<EEClipVertex>* vertices, const u8& context);
void addCorrections(std::vector<PlanesClipVertex>* vertices,
McpipBlock* block);
void moveDataToBuffer(std::vector<PlanesClipVertex>* vertices,
const u8& context);
void addDataToPacket(packet2_t* packet, const u8& context, McpipBlock* block,
const int& count,
RendererCoreTextureBuffers* texBuffers);
@@ -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"
@@ -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<EEClipVertex>* vertices);
void moveDataToBuffer(const std::vector<EEClipVertex>& vertices,
void perspectiveDivide(std::vector<PlanesClipVertex>* vertices);
void moveDataToBuffer(const std::vector<PlanesClipVertex>& vertices,
StaPipQBuffer* buffer);
};
+27 -5
View File
@@ -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<PlanesClipVertex, 9> clippedVerts;
std::array<PlanesClipVertexPtrs, 3> clipInput;
RendererCore* core;
prim_t basePrim;
color_t baseColor;
prim_t prim;
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
@@ -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;
+18 -3
View File
@@ -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<CoreBBox>& 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; }
@@ -44,7 +58,8 @@ class CoreBBox {
/**
* @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 margins Optional margins
*/
@@ -11,7 +11,7 @@
#pragma once
#include <vector>
#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);
};
@@ -14,11 +14,11 @@
namespace Tyra {
struct EEClipVertex {
struct PlanesClipVertex {
Vec4 position, normal, st, color;
};
struct EEClipVertexPtrs {
struct PlanesClipVertexPtrs {
Vec4 *position, *normal, *st, *color;
};
+10
View File
@@ -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();
@@ -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<EEClipVertex> clippedVertices;
std::vector<PlanesClipVertex> 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<EEClipVertex>* vertices,
void McpipClip::addCorrections(std::vector<PlanesClipVertex>* 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<EEClipVertex>* vertices,
}
}
void McpipClip::moveDataToBuffer(std::vector<EEClipVertex>* vertices,
void McpipClip::moveDataToBuffer(std::vector<PlanesClipVertex>* vertices,
const u8& context) {
for (u32 i = 0; i < vertices->size(); i++) {
vertexBuffers[context][i].set(vertices->at(i).position);
@@ -31,7 +31,7 @@ void StaPipClipper::clip(StaPipQBuffer* buffer) {
buffer->bag->texture != nullptr,
buffer->bag->color->many != nullptr};
std::vector<EEClipVertex> clippedVertices;
std::vector<PlanesClipVertex> 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<EEClipVertex>* vertices) {
void StaPipClipper::perspectiveDivide(std::vector<PlanesClipVertex>* vertices) {
for (u32 i = 0; i < vertices->size(); i++) {
(*vertices)[i].position /= (*vertices)[i].position.w;
}
}
void StaPipClipper::moveDataToBuffer(const std::vector<EEClipVertex>& vertices,
StaPipQBuffer* buffer) {
void StaPipClipper::moveDataToBuffer(
const std::vector<PlanesClipVertex>& vertices, StaPipQBuffer* buffer) {
buffer->reallocateManually(vertices.size());
for (u32 i = 0; i < vertices.size(); i++) {
+231 -47
View File
@@ -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<Vec4, 2> inputVerts;
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};
auto* packet =
packet2_create(packetSize, P2_TYPE_NORMAL, P2_MODE_CHAIN, false);
std::array<xyz_t, 2> outputVerts;
std::array<color_t, 2> outputColors;
std::array<Vec4, vertCount> inputVerts;
inputVerts[0] = from;
inputVerts[1] = to;
draw_convert_xyz(outputVerts.data(), 2048, 2048,
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);
std::array<xyz_t, vertCount> 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<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
@@ -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() {
@@ -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 {
@@ -8,24 +8,27 @@
# 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 {
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,
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;
@@ -58,7 +61,7 @@ u8 EEClipAlgorithm::clip(EEClipVertex* o_vertices, EEClipVertexPtrs* i_vertices,
return outputSize;
}
float EEClipAlgorithm::getValueByPlane(const EEClipVertex& v,
float PlanesClipAlgorithm::getValueByPlane(const PlanesClipVertex& v,
const int& plane) {
switch (plane) {
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) {
switch (plane) {
case 3:
@@ -86,10 +90,9 @@ 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,
u8 PlanesClipAlgorithm::clipAgainstPlane(
PlanesClipVertex* original, const u8& originalSize,
PlanesClipVertex* clipped, const int& plane, const float& planeLimitValue,
const EEClipAlgorithmSettings& settings) {
int clippedSize = 0;