More fixes for 3D rendering

This commit is contained in:
UnknownShadow200 2023-05-28 12:18:52 +10:00
parent 52f11d2679
commit 37e22a6ab2

View File

@ -41,6 +41,8 @@ static void InitGX(void) {
GX_SetDispCopyGamma(GX_GM_1_0); GX_SetDispCopyGamma(GX_GM_1_0);
GX_InvVtxCache(); GX_InvVtxCache();
GX_SetNumChans(1);
xfbs[0] = Window_XFB; xfbs[0] = Window_XFB;
xfbs[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(mode)); xfbs[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(mode));
} }
@ -61,6 +63,7 @@ cc_bool Gfx_TryRestoreContext(void) { return true; }
void Gfx_RestoreState(void) { void Gfx_RestoreState(void) {
InitDefaultResources(); InitDefaultResources();
// 4x4 dummy white texture (textures must be at least 1 4x4 tile) // 4x4 dummy white texture (textures must be at least 1 4x4 tile)
struct Bitmap bmp; struct Bitmap bmp;
BitmapCol pixels[4 * 4]; BitmapCol pixels[4 * 4];
@ -81,6 +84,7 @@ typedef struct CCTexture_ {
GXTexObj obj; GXTexObj obj;
cc_uint32 pixels[]; cc_uint32 pixels[];
} CCTexture; } CCTexture;
// ClassiCube RGBA8 bitmaps // ClassiCube RGBA8 bitmaps
// - store pixels in simple linear order // - store pixels in simple linear order
// i.e. pixels are ordered as (x=0,y=0), (x=1,y=0), (x=2,y=0) ... (x=0,y=1) ... // i.e. pixels are ordered as (x=0,y=0), (x=1,y=0), (x=2,y=0) ... (x=0,y=1) ...
@ -89,7 +93,8 @@ typedef struct CCTexture_ {
// GX RGBA8 textures // GX RGBA8 textures
// - store pixels in 4x4 tiles // - store pixels in 4x4 tiles
// - store all of the AR values of the tile's pixels, then store all of the GB values // - store all of the AR values of the tile's pixels, then store all of the GB values
static void ReorderPixels(cc_uint32* pixels, struct Bitmap* bmp) { static void ReorderPixels(cc_uint32* pixels, struct Bitmap* bmp,
int originX, int originY, int rowWidth) {
int size = bmp->width * bmp->height * 4; int size = bmp->width * bmp->height * 4;
// http://hitmen.c02.at/files/yagcd/yagcd/chap15.html // http://hitmen.c02.at/files/yagcd/yagcd/chap15.html
@ -97,14 +102,15 @@ static void ReorderPixels(cc_uint32* pixels, struct Bitmap* bmp) {
// "RGBA8 (4x4 tiles in two cache lines - first is AR and second is GB" // "RGBA8 (4x4 tiles in two cache lines - first is AR and second is GB"
uint8_t *src = (uint8_t*)bmp->scan0; uint8_t *src = (uint8_t*)bmp->scan0;
uint8_t *dst = (uint8_t*)pixels; uint8_t *dst = (uint8_t*)pixels;
int bmpWidth = bmp->width, bmpHeight = bmp->height; int srcWidth = bmp->width, srcHeight = bmp->height;
for (int blockY = 0; blockY < bmpHeight; blockY += 4) for (int tileY = originY; tileY < originY + srcHeight; tileY += 4)
for (int blockX = 0; blockX < bmpWidth; blockX += 4) for (int tileX = originX; tileX < originX + srcWidth; tileX += 4)
{ {
for (int y = 0; y < 4; y++) { for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) { for (int x = 0; x < 4; x++) {
uint32_t idx = (((blockY + y) * bmpWidth) + blockX + x) << 2; uint32_t idx = (((tileY + y) * rowWidth) + tileX + x) << 2;
*dst++ = src[idx + 0]; // A *dst++ = src[idx + 0]; // A
*dst++ = src[idx + 1]; // R *dst++ = src[idx + 1]; // R
} }
@ -112,7 +118,8 @@ static void ReorderPixels(cc_uint32* pixels, struct Bitmap* bmp) {
for (int y = 0; y < 4; y++) { for (int y = 0; y < 4; y++) {
for (int x = 0; x < 4; x++) { for (int x = 0; x < 4; x++) {
uint32_t idx = (((blockY + y) * bmpWidth) + blockX + x) << 2; uint32_t idx = (((tileY + y) * rowWidth) + tileX + x) << 2;
*dst++ = src[idx + 2]; // G *dst++ = src[idx + 2]; // G
*dst++ = src[idx + 3]; // B *dst++ = src[idx + 3]; // B
} }
@ -133,15 +140,20 @@ GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipm
GX_TF_RGBA8, GX_REPEAT, GX_REPEAT, GX_FALSE); GX_TF_RGBA8, GX_REPEAT, GX_REPEAT, GX_FALSE);
GX_InitTexObjFilterMode(&tex->obj, GX_NEAR, GX_NEAR); GX_InitTexObjFilterMode(&tex->obj, GX_NEAR, GX_NEAR);
ReorderPixels(tex->pixels, bmp); ReorderPixels(tex->pixels, bmp, 0, 0, bmp->width);
DCFlushRange(tex->pixels, size); DCFlushRange(tex->pixels, size);
return tex; return tex;
} }
void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, int rowWidth, cc_bool mipmaps) { void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, int rowWidth, cc_bool mipmaps) {
CCTexture* tex = (CCTexture*)texId;
// TODO: wrong behaviour if x/y/part isn't multiple of 4 pixels
//ReorderPixels(tex->pixels, part, x, y, rowWidth);
GX_InvalidateTexAll();
} }
void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, struct Bitmap* part, cc_bool mipmaps) { void Gfx_UpdateTexturePart(GfxResourceID texId, int x, int y, struct Bitmap* part, cc_bool mipmaps) {
Gfx_UpdateTexture(texId, x, y, part, part->width, mipmaps);
} }
void Gfx_DeleteTexture(GfxResourceID* texId) { void Gfx_DeleteTexture(GfxResourceID* texId) {
@ -156,6 +168,7 @@ void Gfx_DisableMipmaps(void) { }
void Gfx_BindTexture(GfxResourceID texId) { void Gfx_BindTexture(GfxResourceID texId) {
CCTexture* tex = (CCTexture*)texId; CCTexture* tex = (CCTexture*)texId;
if (!tex) tex = white_square; if (!tex) tex = white_square;
GX_LoadTexObj(&tex->obj, GX_TEXMAP0); GX_LoadTexObj(&tex->obj, GX_TEXMAP0);
} }
@ -189,6 +202,7 @@ void Gfx_ClearCol(PackedCol color) {
void Gfx_SetColWriteMask(cc_bool r, cc_bool g, cc_bool b, cc_bool a) { void Gfx_SetColWriteMask(cc_bool r, cc_bool g, cc_bool b, cc_bool a) {
} }
static cc_bool depth_write = true, depth_test = true; static cc_bool depth_write = true, depth_test = true;
static void UpdateDepthState(void) { static void UpdateDepthState(void) {
// match Desktop behaviour, where disabling depth testing also disables depth writing // match Desktop behaviour, where disabling depth testing also disables depth writing
@ -256,6 +270,7 @@ static cc_uint16* gfx_indices;
GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) { GfxResourceID Gfx_CreateIb(void* indices, int indicesCount) {
void* data = memalign(16, indicesCount * 2); void* data = memalign(16, indicesCount * 2);
if (!data) Logger_Abort("Failed to allocate memory for GFX VB"); if (!data) Logger_Abort("Failed to allocate memory for GFX VB");
Mem_Copy(data, indices, indicesCount * 2); Mem_Copy(data, indices, indicesCount * 2);
return data; return data;
} }
@ -270,6 +285,7 @@ void Gfx_DeleteIb(GfxResourceID* ib) {
*ib = 0; *ib = 0;
} }
/*########################################################################################################################* /*########################################################################################################################*
*------------------------------------------------------Vertex Buffers-----------------------------------------------------* *------------------------------------------------------Vertex Buffers-----------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
@ -361,7 +377,8 @@ void Gfx_SetAlphaTest(cc_bool enabled) {
} }
void Gfx_DepthOnlyRendering(cc_bool depthOnly) { void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
//GX_SetColorUpdate(!depthOnly); GX_SetColorUpdate(!depthOnly);
GX_SetAlphaUpdate(!depthOnly);
} }
@ -404,8 +421,9 @@ void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, f
void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float zNear, float zFar) { void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float zNear, float zFar) {
guOrtho(matrix, 0, height, 0, width, zNear, zFar); guOrtho(matrix, 0, height, 0, width, zNear, zFar);
} }
void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) {
guPerspective(matrix, fov,aspect, 0.1f, zFar); guPerspective(matrix, fov * MATH_RAD2DEG, aspect, 0.1f, zFar);
} }
void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix) { void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix) {
@ -432,9 +450,11 @@ void Gfx_LoadIdentityMatrix(MatrixType type) {
} }
void Gfx_EnableTextureOffset(float x, float y) { void Gfx_EnableTextureOffset(float x, float y) {
// TODO
} }
void Gfx_DisableTextureOffset(void) { void Gfx_DisableTextureOffset(void) {
//TODO
} }
@ -449,16 +469,17 @@ void Gfx_SetVertexFormat(VertexFormat fmt) {
if (fmt == gfx_format) return; if (fmt == gfx_format) return;
gfx_format = fmt; gfx_format = fmt;
gfx_stride = strideSizes[fmt]; gfx_stride = strideSizes[fmt];
GX_ClearVtxDesc(); GX_ClearVtxDesc();
if (fmt == VERTEX_FORMAT_TEXTURED) { if (fmt == VERTEX_FORMAT_TEXTURED) {
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
GX_SetNumChans(1);
GX_SetNumTexGens(1); GX_SetNumTexGens(1);
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
@ -466,11 +487,10 @@ void Gfx_SetVertexFormat(VertexFormat fmt) {
} else { } else {
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GX_SetNumChans(1);
GX_SetNumTexGens(0); GX_SetNumTexGens(0);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0);
GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR); GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
@ -480,9 +500,10 @@ void Gfx_SetVertexFormat(VertexFormat fmt) {
void Gfx_DrawVb_Lines(int verticesCount) { void Gfx_DrawVb_Lines(int verticesCount) {
} }
// TODO GX_QUADS instead maybe.. ?
static void Draw_ColouredTriangles(int verticesCount, int startVertex) { static void Draw_ColouredTriangles(int verticesCount, int startVertex) {
GX_Begin(GX_TRIANGLES, GX_VTXFMT0, ICOUNT(verticesCount)); GX_Begin(GX_TRIANGLES, GX_VTXFMT0, ICOUNT(verticesCount));
// TODO: Ditch indexed rendering and use GX_QUADS instead ??
for (int i = 0; i < ICOUNT(verticesCount); i++) for (int i = 0; i < ICOUNT(verticesCount); i++)
{ {
struct VertexColoured* v = (struct VertexColoured*)gfx_vertices + startVertex + gfx_indices[i]; struct VertexColoured* v = (struct VertexColoured*)gfx_vertices + startVertex + gfx_indices[i];
@ -492,6 +513,7 @@ static void Draw_ColouredTriangles(int verticesCount, int startVertex) {
} }
GX_End(); GX_End();
} }
static void Draw_TexturedTriangles(int verticesCount, int startVertex) { static void Draw_TexturedTriangles(int verticesCount, int startVertex) {
GX_Begin(GX_TRIANGLES, GX_VTXFMT0, ICOUNT(verticesCount)); GX_Begin(GX_TRIANGLES, GX_VTXFMT0, ICOUNT(verticesCount));
for (int i = 0; i < ICOUNT(verticesCount); i++) for (int i = 0; i < ICOUNT(verticesCount); i++)