Tiny3D
Loading...
Searching...
No Matches
t3d.h
Go to the documentation of this file.
1
6#ifndef TINY3D_T3D_H
7#define TINY3D_T3D_H
8
9#include <t3d/t3dmath.h>
10#include <libdragon.h>
11
12#ifdef __cplusplus
13extern "C"
14{
15#endif
16
17#define T3D_VERTEX_CACHE_SIZE 70
18
19extern uint32_t T3D_RSP_ID;
20
21// RSP commands, must match with the commands defined in `rsp/rsp_tiny3d.rspl`
22enum T3DCmd {
23 T3D_CMD_TRI_DRAW = 0x0,
24 T3D_CMD_SCREEN_SIZE = 0x1,
25 T3D_CMD_MATRIX_STACK = 0x2,
26 T3D_CMD_SET_WORD = 0x3,
27 T3D_CMD_VERT_LOAD = 0x4,
28 T3D_CMD_LIGHT_SET = 0x5,
29 T3D_CMD_DRAWFLAGS = 0x6,
30 T3D_CMD_PROJ_SET = 0x7,
31 T3D_CMD_PATCH = 0x8,
32 T3D_CMD_FOG_STATE = 0x9,
33 T3D_CMD_TRI_SYNC = 0xA,
34 T3D_CMD_TRI_STRIP = 0xB,
35 T3D_CMD_TRI_SEQ = 0xC,
36 // = 0xD,
37 // = 0xE,
38 // = 0xF,
39};
40
41// Internal vertex format, interleaves two vertices
42typedef struct {
43 /* 0x00 */ int16_t posA[3]; // s16 (used in the ucode as the int. part of a s16.16)
44 /* 0x06 */ uint16_t normA; // 5,6,5 packed normal
45 /* 0x08 */ int16_t posB[3]; // s16 (used in the ucode as the int. part of a s16.16)
46 /* 0x0E */ uint16_t normB; // 5,6,5 packed normal
47 /* 0x10 */ uint32_t rgbaA; // RGBA8 color
48 /* 0x14 */ uint32_t rgbaB; // RGBA8 color
49 /* 0x18 */ int16_t stA[2]; // UV fixed point 10.5 (pixel coords)
50 /* 0x1C */ int16_t stB[2]; // UV fixed point 10.5 (pixel coords)
51} __attribute__((aligned(8))) T3DVertPacked;
52
53static_assert(sizeof(T3DVertPacked) == 0x20, "T3DVertPacked has wrong size");
54
55enum T3DDrawFlags {
56 T3D_FLAG_DEPTH = 1 << 0,
57 T3D_FLAG_TEXTURED = 1 << 1,
58 T3D_FLAG_SHADED = 1 << 2,
59 T3D_FLAG_CULL_FRONT = 1 << 3,
60 T3D_FLAG_CULL_BACK = 1 << 4,
61 T3D_FLAG_NO_LIGHT = 1 << 16,
62};
63
64// Segment addresses, some are used internally but can be set by the user too
65enum T3DSegment {
66 T3D_SEGMENT_1 = 1,
67 T3D_SEGMENT_2 = 2,
68 T3D_SEGMENT_3 = 3,
69 T3D_SEGMENT_4 = 4,
70 T3D_SEGMENT_5 = 5,
71 T3D_SEGMENT_6 = 6,
72 T3D_SEGMENT_SKELETON = 7,
73};
74
75// Vertex effect functions
76enum T3DVertexFX {
77 T3D_VERTEX_FX_NONE = 0,
78 T3D_VERTEX_FX_SPHERICAL_UV = 1,
79 T3D_VERTEX_FX_CELSHADE_COLOR = 2,
80 T3D_VERTEX_FX_CELSHADE_ALPHA = 3,
81 T3D_VERTEX_FX_OUTLINE = 4,
82 T3D_VERTEX_FX_UV_OFFSET = 5,
83};
84
85// computation to use to combine lighting and vertex color
86enum T3DLightingMode
87{
88 T3D_LIGHTING_MODE_MUL = 0,
89 T3D_LIGHTING_MODE_ADD = 1,
90 T3D_LIGHTING_MODE_REPLACE = 2,
91};
92
99typedef struct {
100 T3DMat4FP _matCameraFP [[deprecated("Use t3d_viewport_set_view_matrix()")]];
101 T3DMat4FP _matProjFP [[deprecated("Use t3d_viewport_set_projection_matrix()")]];
102
103 T3DMat4 matCamera; // view matrix, can be set via `t3d_viewport_look_at`
104 T3DMat4 matProj; // projection matrix, can be set via `t3d_viewport_set_projection`
105
106 T3DMat4 matCamProj; // combined view-projection matrix, calculated automatically on demand
107 T3DFrustum viewFrustum; // frustum, calculated from the combined matrix
108 bool _isCamProjDirty; // flag to indicate if the combined matrix needs to be recalculated
109
110 int32_t offset[2]; // screen offset in pixel, [0,0] by default
111 int32_t size[2]; // screen size in pixel, same as the allocated framebuffer size by default
112 int guardBandScale; // guard band for clipping, 2 by default
113 int useRejection; // use rejection instead of clipping, false by default
114
115 float _normScaleW; // factor to normalize W in the ucode, set automatically
116
117 uint16_t _bufferCount; // amount of matrices / framebuffers
118 uint16_t _bufferIdx; // current buffer index
119 T3DMat4FP *_matFP; // stores both camera and projection matrices
121
125typedef struct {
126 // Internal matrix stack size, must be at least 2.
127 // If set two zero, 8 will be used by default.
128 int matrixStackSize;
130
135typedef struct {
136 uint32_t trisPreCull;
137 uint32_t trisPostCull;
138} T3DMetrics;
139
144void t3d_init(T3DInitParams params);
145
149void t3d_destroy(void);
150
154void t3d_frame_start(void);
155
156
158void t3d_screen_clear_color(color_t color);
159
162
170void t3d_metrics_fetch(T3DMetrics* data);
171
183 return (T3DViewport){
184 ._isCamProjDirty = true,
185 .offset = {0, 0},
186 .size = {(int32_t)display_get_width(), (int32_t)display_get_height()},
187 .guardBandScale = 2,
188 .useRejection = false,
189 ._bufferCount = 0,
190 ._matFP = NULL,
191 };
192}
193
204inline static T3DViewport t3d_viewport_create_buffered(uint16_t count) {
206 vp._bufferCount = count;
207 vp._bufferIdx = 0;
208 vp._matFP = (T3DMat4FP*)malloc_uncached(sizeof(T3DMat4FP) * 2 * count);
209 return vp;
210}
211
220inline static void t3d_viewport_destroy(T3DViewport *viewport) {
221 if(viewport->_matFP) {
222 free_uncached(viewport->_matFP);
223 viewport->_matFP = NULL;
224 viewport->_bufferCount = 0;
225 viewport->_bufferIdx = 0;
226 }
227}
228
238void t3d_viewport_attach(T3DViewport *viewport);
239
245
254inline static void t3d_viewport_set_area(T3DViewport *viewport, int32_t x, int32_t y, int32_t width, int32_t height) {
255 viewport->offset[0] = x;
256 viewport->offset[1] = y;
257 viewport->size[0] = width;
258 viewport->size[1] = height;
259}
260
271void t3d_viewport_set_perspective(T3DViewport *viewport, float fov, float aspectRatio, float near, float far);
272
284void t3d_viewport_set_projection(T3DViewport *viewport, float fov, float near, float far);
285
297void t3d_viewport_set_ortho(T3DViewport *viewport, float left, float right, float bottom, float top, float near, float far);
298
308inline static void t3d_viewport_set_w_normalize(T3DViewport *viewport, float near, float far) {
309 viewport->_normScaleW = 2.0f / (far + near);
310}
311
320void t3d_viewport_look_at(T3DViewport *viewport, const T3DVec3 *eye, const T3DVec3 *target, const T3DVec3 *up);
321
329void t3d_viewport_set_view_matrix(T3DViewport *viewport, const T3DMat4 *mat);
330
339void t3d_viewport_set_projection_matrix(T3DViewport *viewport, const T3DMat4 *mat);
340
349void t3d_viewport_calc_viewspace_pos(T3DViewport *viewport, T3DVec3 *out, const T3DVec3 *pos);
350
357void t3d_tri_draw(uint32_t v0, uint32_t v1, uint32_t v2);
358
370void t3d_tri_draw_unindexed(uint32_t baseIndex, uint32_t triCount);
371
383void t3d_quad_draw_unindexed(uint32_t baseIndex, uint32_t quadCount);
384
385
404void t3d_tri_draw_strip(int16_t* indexBuff, int count);
405
413void t3d_tri_draw_strip_and_sync(int16_t* indexBuff, int count);
414
420inline static void t3d_tri_sync() {
421 rspq_write(T3D_RSP_ID, T3D_CMD_TRI_SYNC, 0);
422}
423
433void t3d_matrix_set(const T3DMat4FP *mat, bool doMultiply);
434
439void t3d_matrix_push(const T3DMat4FP *mat);
440
445void t3d_matrix_pop(int count);
446
459void t3d_matrix_push_pos(int count);
460
465void t3d_matrix_set_proj(const T3DMat4FP *mat);
466
474void t3d_vert_load(const T3DVertPacked *vertices, uint32_t offset, uint32_t count);
475
482void t3d_light_set_ambient(const uint8_t *color);
483
493void t3d_light_set_directional(int index, const uint8_t *color, const T3DVec3 *dir);
494
512void t3d_light_set_point(int index, const uint8_t *color, const T3DVec3 *pos, float size, bool ignoreNormals);
513
519void t3d_light_set_count(int count);
520
531void t3d_light_set_exposure(float exposure);
532
541void t3d_fog_set_range(float near, float far);
542
547static inline void t3d_fog_set_enabled(bool isEnabled) {
548 // 0xB/0xC are the offsets of attributes (color/UV) in a vertex on the RSP side
549 // this allows the code to do a branch-less save.
550 // 0xB points to alpha of the current vertex, 0xC to the UV which get overwritten later
551 rspq_write(T3D_RSP_ID, T3D_CMD_FOG_STATE, isEnabled ? 0x0B : 0x0C);
552}
553
559uint16_t t3d_vert_pack_normal(const T3DVec3 *normal);
560
565void t3d_state_set_drawflags(enum T3DDrawFlags drawFlags);
566
574void t3d_state_set_depth_offset(int16_t offset);
575
593void t3d_state_set_alpha_to_tile(bool enable);
594
612void t3d_state_set_vertex_fx(enum T3DVertexFX func, int16_t arg0, int16_t arg1);
613
622void t3d_state_set_vertex_fx_scale(uint16_t scale);
623
645void t3d_state_set_lighting_mode(enum T3DLightingMode mode);
646
655void t3d_segment_set(uint8_t segmentId, void* address);
656
664static inline void* t3d_segment_placeholder(uint8_t segmentId) {
665 return (void*)(uint32_t)(segmentId << (8*3 + 2));
666}
667
677static inline void* t3d_segment_address(uint8_t segmentId, void* ptr) {
678 return (void*)(PhysicalAddr(ptr) | (segmentId << (8*3 + 2)));
679}
680
681// Index-buffer helpers:
682
705void t3d_indexbuffer_convert(int16_t indices[], int count);
706
707// Vertex-buffer helpers:
708
714static inline int16_t* t3d_vertbuffer_get_pos(T3DVertPacked vert[], int idx) {
715 return (idx & 1) ? vert[idx/2].posB : vert[idx/2].posA;
716}
717
723static inline int16_t* t3d_vertbuffer_get_uv(T3DVertPacked vert[], int idx) {
724 return (idx & 1) ? vert[idx/2].stB : vert[idx/2].stA;
725}
726
732static inline uint32_t* t3d_vertbuffer_get_color(T3DVertPacked vert[], int idx) {
733 return (idx & 1) ? &vert[idx/2].rgbaB : &vert[idx/2].rgbaA;
734}
735
741static inline uint8_t* t3d_vertbuffer_get_rgba(T3DVertPacked vert[], int idx) {
742 return (idx & 1) ? (uint8_t*)&vert[idx/2].rgbaB : (uint8_t*)&vert[idx/2].rgbaA;
743}
744
750static inline uint16_t* t3d_vertbuffer_get_norm(T3DVertPacked vert[], int idx) {
751 return (idx & 1) ? &vert[idx/2].normB : &vert[idx/2].normA;
752}
753
754#ifdef __cplusplus
755}
756#endif
757
758// C++ wrappers that allow (const-)references to be passed instead of pointers
759#ifdef __cplusplus
760
761inline void t3d_viewport_attach(T3DViewport &viewport) { t3d_viewport_attach(&viewport); }
762inline void t3d_viewport_set_area(T3DViewport &viewport, int32_t x, int32_t y, int32_t width, int32_t height) { t3d_viewport_set_area(&viewport, x, y, width, height); }
763inline void t3d_viewport_set_projection(T3DViewport &viewport, float fov, float near, float far) { t3d_viewport_set_projection(&viewport, fov, near, far); }
764inline void t3d_viewport_set_ortho(T3DViewport &viewport, float left, float right, float bottom, float top, float near, float far) { t3d_viewport_set_ortho(&viewport, left, right, bottom, top, near, far); }
765inline void t3d_viewport_set_w_normalize(T3DViewport &viewport, float near, float far) { t3d_viewport_set_w_normalize(&viewport, near, far); }
766inline void t3d_viewport_look_at(T3DViewport &viewport, const T3DVec3 &eye, const T3DVec3 &target, const T3DVec3 &up = T3DVec3{{0,1,0}}) { t3d_viewport_look_at(&viewport, &eye, &target, &up); }
767inline void t3d_viewport_calc_viewspace_pos(T3DViewport &viewport, T3DVec3 &out, const T3DVec3 &pos) { t3d_viewport_calc_viewspace_pos(&viewport, &out, &pos); }
768
769inline void t3d_light_set_directional(int index, const uint8_t *color, const T3DVec3 &dir) { t3d_light_set_directional(index, color, &dir); }
770inline void t3d_light_set_point(int index, const uint8_t *color, const T3DVec3 &pos, float size, bool ignoreNormals = false) { t3d_light_set_point(index, color, &pos, size, ignoreNormals); }
771
772inline void t3d_light_set_ambient(const color_t &color) { t3d_light_set_ambient((const uint8_t*)&color); }
773inline void t3d_light_set_directional(int index, const color_t &color, const T3DVec3 &dir) { t3d_light_set_directional(index, (const uint8_t*)&color, &dir); }
774inline void t3d_light_set_point(int index, const color_t &color, const T3DVec3 &pos, float size, bool ignoreNormals = false) { t3d_light_set_point(index, (const uint8_t*)&color, &pos, size, ignoreNormals); }
775
776#endif
777
778#endif //TINY3D_T3D_H
Definition t3dmath.h:38
Definition t3d.h:125
Definition t3d.h:135
Definition t3d.h:99
static void t3d_viewport_destroy(T3DViewport *viewport)
Definition t3d.h:220
void t3d_state_set_vertex_fx(enum T3DVertexFX func, int16_t arg0, int16_t arg1)
Definition t3d.c:343
void t3d_destroy(void)
Destroys the tiny3d library.
Definition t3d.c:83
void t3d_vert_load(const T3DVertPacked *vertices, uint32_t offset, uint32_t count)
Definition t3d.c:155
void t3d_viewport_attach(T3DViewport *viewport)
Definition t3d.c:531
static uint32_t * t3d_vertbuffer_get_color(T3DVertPacked vert[], int idx)
Definition t3d.h:732
void t3d_indexbuffer_convert(int16_t indices[], int count)
Definition t3d.c:694
void t3d_light_set_count(int count)
Definition t3d.c:192
static uint16_t * t3d_vertbuffer_get_norm(T3DVertPacked vert[], int idx)
Definition t3d.h:750
void t3d_viewport_calc_viewspace_pos(T3DViewport *viewport, T3DVec3 *out, const T3DVec3 *pos)
Definition t3d.c:664
void t3d_tri_draw_strip_and_sync(int16_t *indexBuff, int count)
Definition t3d.c:498
void t3d_state_set_alpha_to_tile(bool enable)
Definition t3d.c:336
void t3d_state_set_lighting_mode(enum T3DLightingMode mode)
Definition t3d.c:390
void t3d_light_set_ambient(const uint8_t *color)
Definition t3d.c:206
static int16_t * t3d_vertbuffer_get_uv(T3DVertPacked vert[], int idx)
Definition t3d.h:723
static void * t3d_segment_address(uint8_t segmentId, void *ptr)
Definition t3d.h:677
void t3d_viewport_set_view_matrix(T3DViewport *viewport, const T3DMat4 *mat)
Definition t3d.c:648
static T3DViewport t3d_viewport_create_buffered(uint16_t count)
Definition t3d.h:204
static uint8_t * t3d_vertbuffer_get_rgba(T3DVertPacked vert[], int idx)
Definition t3d.h:741
uint16_t t3d_vert_pack_normal(const T3DVec3 *normal)
Definition t3d.c:283
void t3d_matrix_pop(int count)
Definition t3d.c:141
void t3d_viewport_set_perspective(T3DViewport *viewport, float fov, float aspectRatio, float near, float far)
Definition t3d.c:623
void t3d_viewport_set_ortho(T3DViewport *viewport, float left, float right, float bottom, float top, float near, float far)
Definition t3d.c:634
void t3d_segment_set(uint8_t segmentId, void *address)
Definition t3d.c:424
void t3d_tri_draw(uint32_t v0, uint32_t v1, uint32_t v2)
Draws a single triangle, referencing loaded vertices.
Definition t3d.c:432
void t3d_tri_draw_strip(int16_t *indexBuff, int count)
Definition t3d.c:493
void t3d_init(T3DInitParams params)
Initializes the tiny3d library.
Definition t3d.c:51
void t3d_matrix_push(const T3DMat4FP *mat)
Definition t3d.c:137
static void t3d_viewport_set_w_normalize(T3DViewport *viewport, float near, float far)
Definition t3d.h:308
void t3d_screen_clear_color(color_t color)
Clears the entire screen with a given color.
Definition t3d.c:97
void t3d_state_set_depth_offset(int16_t offset)
Definition t3d.c:332
void t3d_state_set_drawflags(enum T3DDrawFlags drawFlags)
Definition t3d.c:300
void t3d_matrix_push_pos(int count)
Definition t3d.c:146
static void t3d_tri_sync()
Definition t3d.h:420
void t3d_frame_start(void)
Starts a new frame, this will setup some default states.
Definition t3d.c:176
void t3d_screen_clear_depth()
Clears the entire depth buffer with a fixed value (0xFFFC)
Definition t3d.c:101
void t3d_fog_set_range(float near, float far)
Definition t3d.c:503
void t3d_light_set_exposure(float exposure)
Definition t3d.c:200
void t3d_viewport_look_at(T3DViewport *viewport, const T3DVec3 *eye, const T3DVec3 *target, const T3DVec3 *up)
Definition t3d.c:640
void t3d_state_set_vertex_fx_scale(uint16_t scale)
Definition t3d.c:385
void t3d_viewport_set_projection(T3DViewport *viewport, float fov, float near, float far)
Definition t3d.c:629
static void t3d_viewport_set_area(T3DViewport *viewport, int32_t x, int32_t y, int32_t width, int32_t height)
Definition t3d.h:254
void t3d_quad_draw_unindexed(uint32_t baseIndex, uint32_t quadCount)
Definition t3d.c:473
void t3d_matrix_set_proj(const T3DMat4FP *mat)
Definition t3d.c:151
static void * t3d_segment_placeholder(uint8_t segmentId)
Definition t3d.h:664
void t3d_light_set_directional(int index, const uint8_t *color, const T3DVec3 *dir)
Definition t3d.c:215
void t3d_matrix_set(const T3DMat4FP *mat, bool doMultiply)
Definition t3d.c:133
static T3DViewport t3d_viewport_create()
Definition t3d.h:182
static int16_t * t3d_vertbuffer_get_pos(T3DVertPacked vert[], int idx)
Definition t3d.h:714
static void t3d_fog_set_enabled(bool isEnabled)
Definition t3d.h:547
void t3d_light_set_point(int index, const uint8_t *color, const T3DVec3 *pos, float size, bool ignoreNormals)
Definition t3d.c:243
void t3d_viewport_set_projection_matrix(T3DViewport *viewport, const T3DMat4 *mat)
Definition t3d.c:656
void t3d_metrics_fetch(T3DMetrics *data)
Definition t3d.c:125
T3DViewport * t3d_viewport_get()
Definition t3d.c:619
void t3d_tri_draw_unindexed(uint32_t baseIndex, uint32_t triCount)
Definition t3d.c:469
__attribute__((deprecated)) void t3d_debug_print_init()
Initializes the debug print system, make sure to have 'font.ia4.png' in your FS.