mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-13 01:26:50 -04:00
Merge pull request #1328 from rmn20/DS-fixes
[NDS/DSi] Rendering impovements
This commit is contained in:
commit
69f0cda9c7
@ -438,8 +438,9 @@ typedef cc_uint8 cc_bool;
|
|||||||
#define CC_BUILD_NOFPU
|
#define CC_BUILD_NOFPU
|
||||||
#define DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN
|
#define DEFAULT_NET_BACKEND CC_NET_BACKEND_BUILTIN
|
||||||
#define CC_DISABLE_ANIMATIONS /* Very costly in FPU less system */
|
#define CC_DISABLE_ANIMATIONS /* Very costly in FPU less system */
|
||||||
#define CC_BUILD_LOW_VRAM /* Only ~640 kb of VRAM */
|
#ifndef BUILD_DSI
|
||||||
#undef CC_BUILD_ADVLIGHTING
|
#undef CC_BUILD_ADVLIGHTING
|
||||||
|
#endif
|
||||||
#elif defined __WIIU__
|
#elif defined __WIIU__
|
||||||
#define CC_BUILD_WIIU
|
#define CC_BUILD_WIIU
|
||||||
#define CC_BUILD_CONSOLE
|
#define CC_BUILD_CONSOLE
|
||||||
|
@ -916,12 +916,10 @@ static void OnInit(void) {
|
|||||||
EnvRenderer_Legacy = flags & ENV_LEGACY;
|
EnvRenderer_Legacy = flags & ENV_LEGACY;
|
||||||
EnvRenderer_Minimal = flags & ENV_MINIMAL;
|
EnvRenderer_Minimal = flags & ENV_MINIMAL;
|
||||||
|
|
||||||
#ifndef CC_BUILD_LOW_VRAM
|
|
||||||
TextureEntry_Register(&clouds_entry);
|
TextureEntry_Register(&clouds_entry);
|
||||||
TextureEntry_Register(&skybox_entry);
|
TextureEntry_Register(&skybox_entry);
|
||||||
TextureEntry_Register(&snow_entry);
|
TextureEntry_Register(&snow_entry);
|
||||||
TextureEntry_Register(&rain_entry);
|
TextureEntry_Register(&rain_entry);
|
||||||
#endif
|
|
||||||
|
|
||||||
Event_Register_(&TextureEvents.PackChanged, NULL, OnTexturePackChanged);
|
Event_Register_(&TextureEvents.PackChanged, NULL, OnTexturePackChanged);
|
||||||
Event_Register_(&TextureEvents.AtlasChanged, NULL, OnTerrainAtlasChanged);
|
Event_Register_(&TextureEvents.AtlasChanged, NULL, OnTerrainAtlasChanged);
|
||||||
|
@ -16,23 +16,33 @@ void Gfx_Create(void) {
|
|||||||
Gfx.MinTexHeight = 8;
|
Gfx.MinTexHeight = 8;
|
||||||
Gfx.MaxTexWidth = 256;
|
Gfx.MaxTexWidth = 256;
|
||||||
Gfx.MaxTexHeight = 256;
|
Gfx.MaxTexHeight = 256;
|
||||||
//Gfx.MaxTexSize = 256 * 256;
|
//Gfx.MaxTexSize = 256 * 256;
|
||||||
Gfx.Created = true;
|
Gfx.Created = true;
|
||||||
glInit();
|
glInit();
|
||||||
|
|
||||||
glClearColor(0, 15, 10, 31);
|
glClearColor(0, 15, 10, 31);
|
||||||
glClearPolyID(63);
|
glClearPolyID(63);
|
||||||
glAlphaFunc(7);
|
glAlphaFunc(7);
|
||||||
|
|
||||||
|
glEnable(GL_ANTIALIAS);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glEnable(GL_FOG);
|
||||||
|
|
||||||
glClearDepth(GL_MAX_DEPTH);
|
glClearDepth(GL_MAX_DEPTH);
|
||||||
Gfx_SetViewport(0, 0, 256, 192);
|
Gfx_SetViewport(0, 0, 256, 192);
|
||||||
|
|
||||||
vramSetBankA(VRAM_A_TEXTURE);
|
vramSetBankA(VRAM_A_TEXTURE);
|
||||||
vramSetBankB(VRAM_B_TEXTURE);
|
vramSetBankB(VRAM_B_TEXTURE);
|
||||||
vramSetBankC(VRAM_C_TEXTURE);
|
vramSetBankC(VRAM_C_TEXTURE);
|
||||||
vramSetBankD(VRAM_D_TEXTURE);
|
vramSetBankD(VRAM_D_TEXTURE);
|
||||||
|
vramSetBankE(VRAM_E_TEX_PALETTE);
|
||||||
Gfx_SetFaceCulling(false);
|
|
||||||
|
Gfx_SetFaceCulling(false);
|
||||||
|
|
||||||
|
// Set texture matrix to identity
|
||||||
|
MATRIX_CONTROL = 3;
|
||||||
|
MATRIX_IDENTITY = 0;
|
||||||
|
MATRIX_CONTROL = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cc_bool Gfx_TryRestoreContext(void) {
|
cc_bool Gfx_TryRestoreContext(void) {
|
||||||
@ -42,9 +52,10 @@ cc_bool Gfx_TryRestoreContext(void) {
|
|||||||
void Gfx_Free(void) {
|
void Gfx_Free(void) {
|
||||||
Gfx_FreeState();
|
Gfx_FreeState();
|
||||||
vramSetBankA(VRAM_A_LCD);
|
vramSetBankA(VRAM_A_LCD);
|
||||||
vramSetBankB(VRAM_B_LCD);
|
vramSetBankB(VRAM_B_LCD);
|
||||||
vramSetBankC(VRAM_C_LCD);
|
vramSetBankC(VRAM_C_LCD);
|
||||||
vramSetBankD(VRAM_D_LCD);
|
vramSetBankD(VRAM_D_LCD);
|
||||||
|
vramSetBankE(VRAM_E_LCD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -90,7 +101,8 @@ void Gfx_ClearColor(PackedCol color) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_EndFrame(void) {
|
void Gfx_EndFrame(void) {
|
||||||
glFlush(0);
|
// W buffering is used for fog
|
||||||
|
glFlush(GL_WBUFFERING);
|
||||||
// TODO not needed?
|
// TODO not needed?
|
||||||
swiWaitForVBlank();
|
swiWaitForVBlank();
|
||||||
}
|
}
|
||||||
@ -101,39 +113,102 @@ void Gfx_EndFrame(void) {
|
|||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static int tex_width, tex_height;
|
static int tex_width, tex_height;
|
||||||
|
|
||||||
GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
|
static int FindColorInPalette(cc_uint16* pal, int pal_size, cc_uint16 col) {
|
||||||
vramSetBankA(VRAM_A_TEXTURE);
|
if ((col >> 15) == 0) return 0;
|
||||||
|
|
||||||
|
for (int i = 1; i < pal_size; i++) {
|
||||||
|
if(pal[i] == col) return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
cc_uint16* tmp = Mem_TryAlloc(bmp->width * bmp->height, 2);
|
GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
|
||||||
if (!tmp) return 0;
|
cc_uint16* tmp = Mem_TryAlloc(bmp->width * bmp->height, 2);
|
||||||
|
if (!tmp) return 0;
|
||||||
|
|
||||||
// TODO: Only copy when rowWidth != bmp->width
|
// TODO: Only copy when rowWidth != bmp->width
|
||||||
for (int y = 0; y < bmp->height; y++)
|
for (int y = 0; y < bmp->height; y++) {
|
||||||
{
|
|
||||||
cc_uint16* src = bmp->scan0 + y * rowWidth;
|
cc_uint16* src = bmp->scan0 + y * rowWidth;
|
||||||
cc_uint16* dst = tmp + y * bmp->width;
|
cc_uint16* dst = tmp + y * bmp->width;
|
||||||
|
|
||||||
for (int x = 0; x < bmp->width; x++)
|
swiCopy(src, dst, bmp->width | COPY_MODE_HWORD);
|
||||||
{
|
}
|
||||||
dst[x] = src[x];
|
|
||||||
|
// Palettize texture if possible
|
||||||
|
int pal_size = 1;
|
||||||
|
cc_uint16* tmp_palette = Mem_TryAlloc(256, 2);
|
||||||
|
if (!tmp_palette) return 0;
|
||||||
|
tmp_palette[0] = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < bmp->width * bmp->height; i++) {
|
||||||
|
cc_uint16 col = tmp[i];
|
||||||
|
|
||||||
|
int idx = FindColorInPalette(tmp_palette, pal_size, col);
|
||||||
|
|
||||||
|
if (idx == -1) {
|
||||||
|
pal_size++;
|
||||||
|
if (pal_size > 256) break;
|
||||||
|
tmp_palette[pal_size - 1] = col;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int texFormat = GL_RGBA;
|
||||||
|
if(pal_size <= 4) texFormat = GL_RGB4;
|
||||||
|
else if(pal_size <= 16) texFormat = GL_RGB16;
|
||||||
|
else if(pal_size <= 256) texFormat = GL_RGB256;
|
||||||
|
|
||||||
|
if(texFormat != GL_RGBA) {
|
||||||
|
char* tmp_chr = (char*) tmp;
|
||||||
|
|
||||||
|
for (int i = 0; i < bmp->width * bmp->height; i++) {
|
||||||
|
cc_uint16 col = tmp[i];
|
||||||
|
int idx = FindColorInPalette(tmp_palette, pal_size, col);
|
||||||
|
|
||||||
|
if(texFormat == GL_RGB256) {
|
||||||
|
tmp_chr[i] = idx;
|
||||||
|
} else if(texFormat == GL_RGB16) {
|
||||||
|
if((i & 1) == 0) {
|
||||||
|
tmp_chr[i >> 1] = idx;
|
||||||
|
} else {
|
||||||
|
tmp_chr[i >> 1] |= idx << 4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if((i & 3) == 0) {
|
||||||
|
tmp_chr[i >> 2] = idx;
|
||||||
|
} else {
|
||||||
|
tmp_chr[i >> 2] |= idx << (2 * (i & 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load texture in vram
|
||||||
|
int textureID;
|
||||||
|
glGenTextures(1, &textureID);
|
||||||
|
glBindTexture(0, textureID);
|
||||||
|
glTexImage2D(0, 0, texFormat, bmp->width, bmp->height, 0, 0, tmp);
|
||||||
|
if (texFormat != GL_RGBA) {
|
||||||
|
int glPalSize;
|
||||||
|
if(texFormat == GL_RGB4) glPalSize = 4;
|
||||||
|
else if(texFormat == GL_RGB16) glPalSize = 16;
|
||||||
|
else glPalSize = 256;
|
||||||
|
|
||||||
|
glColorTableEXT(0, 0, glPalSize, 0, 0, tmp_palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexParameter(0, GL_TEXTURE_WRAP_S | GL_TEXTURE_WRAP_T | TEXGEN_TEXCOORD | GL_TEXTURE_COLOR0_TRANSPARENT);
|
||||||
|
|
||||||
int textureID;
|
cc_uint16* vram_ptr = glGetTexturePointer(textureID);
|
||||||
glGenTextures(1, &textureID);
|
if (!vram_ptr) Platform_Log2("No VRAM for %i x %i texture", &bmp->width, &bmp->height);
|
||||||
glBindTexture(0, textureID);
|
|
||||||
glTexImage2D(0, 0, GL_RGBA, bmp->width, bmp->height, 0, TEXGEN_TEXCOORD, tmp);
|
|
||||||
glTexParameter(0, GL_TEXTURE_WRAP_S | GL_TEXTURE_WRAP_T);
|
|
||||||
|
|
||||||
cc_uint16* vram_ptr = glGetTexturePointer(textureID);
|
Mem_Free(tmp);
|
||||||
if (!vram_ptr) Platform_Log2("No VRAM for %i x %i texture", &bmp->width, &bmp->height);
|
Mem_Free(tmp_palette);
|
||||||
|
|
||||||
Mem_Free(tmp);
|
|
||||||
return (void*)textureID;
|
return (void*)textureID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_BindTexture(GfxResourceID texId) {
|
void Gfx_BindTexture(GfxResourceID texId) {
|
||||||
glBindTexture(0, (int)texId);
|
glBindTexture(0, (int)texId);
|
||||||
|
|
||||||
tex_width = 0;
|
tex_width = 0;
|
||||||
tex_height = 0;
|
tex_height = 0;
|
||||||
@ -142,17 +217,17 @@ void Gfx_BindTexture(GfxResourceID texId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
int texture = (int)texId;
|
int texture = (int)texId;
|
||||||
glBindTexture(0, texture);
|
glBindTexture(0, texture);
|
||||||
|
|
||||||
int width = 0;
|
int width = 0;
|
||||||
glGetInt(GL_GET_TEXTURE_WIDTH, &width);
|
glGetInt(GL_GET_TEXTURE_WIDTH, &width);
|
||||||
cc_uint16* vram_ptr = glGetTexturePointer(texture);
|
cc_uint16* vram_ptr = glGetTexturePointer(texture);
|
||||||
return;
|
return;
|
||||||
// TODO doesn't work without VRAM bank changing to LCD and back maybe??
|
// TODO doesn't work without VRAM bank changing to LCD and back maybe??
|
||||||
// (see what glTeximage2D does ??)
|
// (see what glTeximage2D does ??)
|
||||||
|
|
||||||
for (int yy = 0; yy < part->height; yy++)
|
for (int yy = 0; yy < part->height; yy++)
|
||||||
{
|
{
|
||||||
cc_uint16* dst = vram_ptr + width * (y + yy) + x;
|
cc_uint16* dst = vram_ptr + width * (y + yy) + x;
|
||||||
cc_uint16* src = part->scan0 + rowWidth * yy;
|
cc_uint16* src = part->scan0 + rowWidth * yy;
|
||||||
@ -165,9 +240,9 @@ void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DeleteTexture(GfxResourceID* texId) {
|
void Gfx_DeleteTexture(GfxResourceID* texId) {
|
||||||
int texture = (int)(*texId);
|
int texture = (int)(*texId);
|
||||||
if (texture) glDeleteTextures(1, &texture);
|
if (texture) glDeleteTextures(1, &texture);
|
||||||
*texId = 0;
|
*texId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_EnableMipmaps(void) { }
|
void Gfx_EnableMipmaps(void) { }
|
||||||
@ -177,23 +252,6 @@ void Gfx_DisableMipmaps(void) { }
|
|||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
*-----------------------------------------------------State management----------------------------------------------------*
|
*-----------------------------------------------------State management----------------------------------------------------*
|
||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
void Gfx_SetFaceCulling(cc_bool enabled) {
|
|
||||||
glPolyFmt(POLY_ALPHA(31) | (enabled ? POLY_CULL_BACK : POLY_CULL_NONE));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void SetAlphaBlend(cc_bool enabled) {
|
|
||||||
/*if (enabled) {
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
} else {
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
|
||||||
|
|
||||||
static void SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a) {
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
void Gfx_SetDepthWrite(cc_bool enabled) { }
|
void Gfx_SetDepthWrite(cc_bool enabled) { }
|
||||||
void Gfx_SetDepthTest(cc_bool enabled) { }
|
void Gfx_SetDepthTest(cc_bool enabled) { }
|
||||||
@ -256,65 +314,86 @@ static int buf_count;
|
|||||||
static void* gfx_vertices;
|
static void* gfx_vertices;
|
||||||
|
|
||||||
struct DSTexturedVertex {
|
struct DSTexturedVertex {
|
||||||
vu32 xy; v16 z;
|
vu32 command;
|
||||||
vu32 rgb;
|
vu32 rgb;
|
||||||
int u, v;
|
vu32 uv;
|
||||||
|
vu32 xy; vu32 z;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DSColouredVertex {
|
struct DSColouredVertex {
|
||||||
vu32 xy; v16 z;
|
vu32 command;
|
||||||
vu32 rgb;
|
vu32 rgb;
|
||||||
|
vu32 xy; vu32 z;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Precalculate all the expensive vertex data conversion,
|
// Precalculate all the expensive vertex data conversion,
|
||||||
// so that actual drawing of them is as fast as possible
|
// so that actual drawing of them is as fast as possible
|
||||||
static void PreprocessTexturedVertices(void) {
|
static void PreprocessTexturedVertices(void) {
|
||||||
struct VertexTextured* src = gfx_vertices;
|
struct VertexTextured* src = gfx_vertices;
|
||||||
struct DSTexturedVertex* dst = gfx_vertices;
|
struct DSTexturedVertex* dst = gfx_vertices;
|
||||||
|
|
||||||
for (int i = 0; i < buf_count; i++, src++, dst++)
|
for (int i = 0; i < buf_count; i++, src++, dst++)
|
||||||
{
|
{
|
||||||
struct VertexTextured v = *src;
|
struct VertexTextured v = *src;
|
||||||
v16 x = floattov16(v.x / 64.0f);
|
|
||||||
v16 y = floattov16(v.y / 64.0f);
|
v16 x = floattov16(v.x / 64.0f);
|
||||||
v16 z = floattov16(v.z / 64.0f);
|
v16 y = floattov16(v.y / 64.0f);
|
||||||
dst->xy = (y << 16) | (x & 0xFFFF);
|
v16 z = floattov16(v.z / 64.0f);
|
||||||
dst->z = z;
|
|
||||||
|
/*int uvX = (v.U * 256.0f + 0.5f); // 0.5f for rounding
|
||||||
dst->u = floattof32(v.U);
|
int uvY = (v.V * 256.0f + 0.5f);*/
|
||||||
dst->v = floattof32(v.V);
|
int uvX = ((int) (v.U * 4096.0f)) - 32768;
|
||||||
|
int uvY = ((int) (v.V * 4096.0f)) - 32768;
|
||||||
|
|
||||||
int r = PackedCol_R(v.Col);
|
int r = PackedCol_R(v.Col);
|
||||||
int g = PackedCol_G(v.Col);
|
int g = PackedCol_G(v.Col);
|
||||||
int b = PackedCol_B(v.Col);
|
int b = PackedCol_B(v.Col);
|
||||||
dst->rgb = RGB15(r >> 3, g >> 3, b >> 3);
|
|
||||||
}
|
dst->command = FIFO_COMMAND_PACK(FIFO_NOP, FIFO_COLOR, FIFO_TEX_COORD, FIFO_VERTEX16);
|
||||||
|
|
||||||
|
dst->rgb = ARGB16(1, r >> 3, g >> 3, b >> 3);
|
||||||
|
|
||||||
|
dst->uv = TEXTURE_PACK(uvX, uvY);
|
||||||
|
|
||||||
|
dst->xy = (y << 16) | (x & 0xFFFF);
|
||||||
|
dst->z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
DC_FlushRange(gfx_vertices, buf_count * sizeof(struct DSTexturedVertex));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PreprocessColouredVertices(void) {
|
static void PreprocessColouredVertices(void) {
|
||||||
struct VertexColoured* src = gfx_vertices;
|
struct VertexColoured* src = gfx_vertices;
|
||||||
struct DSColouredVertex* dst = gfx_vertices;
|
struct DSColouredVertex* dst = gfx_vertices;
|
||||||
|
|
||||||
for (int i = 0; i < buf_count; i++, src++, dst++)
|
for (int i = 0; i < buf_count; i++, src++, dst++)
|
||||||
{
|
{
|
||||||
struct VertexColoured v = *src;
|
struct VertexColoured v = *src;
|
||||||
v16 x = floattov16(v.x / 64.0f);
|
|
||||||
v16 y = floattov16(v.y / 64.0f);
|
v16 x = floattov16(v.x / 64.0f);
|
||||||
v16 z = floattov16(v.z / 64.0f);
|
v16 y = floattov16(v.y / 64.0f);
|
||||||
dst->xy = (y << 16) | (x & 0xFFFF);
|
v16 z = floattov16(v.z / 64.0f);
|
||||||
dst->z = z;
|
|
||||||
|
|
||||||
int r = PackedCol_R(v.Col);
|
int r = PackedCol_R(v.Col);
|
||||||
int g = PackedCol_G(v.Col);
|
int g = PackedCol_G(v.Col);
|
||||||
int b = PackedCol_B(v.Col);
|
int b = PackedCol_B(v.Col);
|
||||||
dst->rgb = RGB15(r >> 3, g >> 3, b >> 3);
|
|
||||||
}
|
dst->command = FIFO_COMMAND_PACK(FIFO_NOP, FIFO_NOP, FIFO_COLOR, FIFO_VERTEX16);
|
||||||
|
|
||||||
|
dst->rgb = ARGB16(1, r >> 3, g >> 3, b >> 3);
|
||||||
|
|
||||||
|
dst->xy = (y << 16) | (x & 0xFFFF);
|
||||||
|
dst->z = z;
|
||||||
|
}
|
||||||
|
|
||||||
|
DC_FlushRange(gfx_vertices, buf_count * sizeof(struct DSColouredVertex));
|
||||||
}
|
}
|
||||||
|
|
||||||
GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) {
|
GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) {
|
||||||
return (void*)1;
|
return (void*)1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_BindIb(GfxResourceID ib) { }
|
void Gfx_BindIb(GfxResourceID ib) { }
|
||||||
void Gfx_DeleteIb(GfxResourceID* ib) { }
|
void Gfx_DeleteIb(GfxResourceID* ib) { }
|
||||||
|
|
||||||
|
|
||||||
@ -331,19 +410,19 @@ void Gfx_DeleteVb(GfxResourceID* vb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
void* Gfx_LockVb(GfxResourceID vb, VertexFormat fmt, int count) {
|
||||||
buf_fmt = fmt;
|
buf_fmt = fmt;
|
||||||
buf_count = count;
|
buf_count = count;
|
||||||
return vb;
|
return vb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_UnlockVb(GfxResourceID vb) {
|
void Gfx_UnlockVb(GfxResourceID vb) {
|
||||||
gfx_vertices = vb;
|
gfx_vertices = vb;
|
||||||
|
|
||||||
if (buf_fmt == VERTEX_FORMAT_TEXTURED) {
|
if (buf_fmt == VERTEX_FORMAT_TEXTURED) {
|
||||||
PreprocessTexturedVertices();
|
PreprocessTexturedVertices();
|
||||||
} else {
|
} else {
|
||||||
PreprocessColouredVertices();
|
PreprocessColouredVertices();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -367,27 +446,105 @@ void Gfx_DeleteDynamicVb(GfxResourceID* vb) { Gfx_DeleteVb(vb); }
|
|||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
static cc_bool skipRendering;
|
static cc_bool skipRendering;
|
||||||
|
|
||||||
|
static cc_bool backfaceCullEnabled;
|
||||||
|
|
||||||
|
static cc_bool fogEnabled;
|
||||||
|
static FogFunc fogMode;
|
||||||
|
static float fogDensityEnd;
|
||||||
|
|
||||||
|
static void SetPolygonMode() {
|
||||||
|
glPolyFmt(
|
||||||
|
POLY_ALPHA(31) |
|
||||||
|
(backfaceCullEnabled ? POLY_CULL_BACK : POLY_CULL_NONE) |
|
||||||
|
(fogEnabled ? POLY_FOG : 0) |
|
||||||
|
POLY_RENDER_FAR_POLYS |
|
||||||
|
POLY_RENDER_1DOT_POLYS
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_SetFaceCulling(cc_bool enabled) {
|
||||||
|
backfaceCullEnabled = enabled;
|
||||||
|
SetPolygonMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetAlphaBlend(cc_bool enabled) {
|
||||||
|
/*if (enabled) {
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void Gfx_SetAlphaArgBlend(cc_bool enabled) { }
|
||||||
|
|
||||||
|
static void SetColorWrite(cc_bool r, cc_bool g, cc_bool b, cc_bool a) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RecalculateFog() {
|
||||||
|
if (fogMode == FOG_LINEAR) {
|
||||||
|
int fogEnd = floattof32(fogDensityEnd);
|
||||||
|
|
||||||
|
// Find shift value so that our fog end is
|
||||||
|
// inside maximum distance covered by fog table
|
||||||
|
int shift = 10;
|
||||||
|
while (shift > 0) {
|
||||||
|
// why * 512? I dont know
|
||||||
|
if (32 * (0x400 >> shift) * 512 >= fogEnd) break;
|
||||||
|
shift--;
|
||||||
|
}
|
||||||
|
|
||||||
|
glFogShift(shift);
|
||||||
|
glFogOffset(0);
|
||||||
|
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
int distance = (i * 512 + 256) * (0x400 >> shift);
|
||||||
|
int intensity = distance * 127 / fogEnd;
|
||||||
|
if(intensity > 127) intensity = 127;
|
||||||
|
|
||||||
|
glFogDensity(i, intensity);
|
||||||
|
}
|
||||||
|
|
||||||
|
glFogDensity(31, 127);
|
||||||
|
} else {
|
||||||
|
// TODO?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Gfx_SetFog(cc_bool enabled) {
|
void Gfx_SetFog(cc_bool enabled) {
|
||||||
|
fogEnabled = enabled;
|
||||||
|
SetPolygonMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetFogCol(PackedCol color) {
|
void Gfx_SetFogCol(PackedCol color) {
|
||||||
|
int r = PackedCol_R(color);
|
||||||
|
int g = PackedCol_G(color);
|
||||||
|
int b = PackedCol_B(color);
|
||||||
|
|
||||||
|
glFogColor(r >> 3, g >> 3, b >> 3, 31);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetFogDensity(float value) {
|
void Gfx_SetFogDensity(float value) {
|
||||||
|
fogDensityEnd = value;
|
||||||
|
RecalculateFog();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetFogEnd(float value) {
|
void Gfx_SetFogEnd(float value) {
|
||||||
|
fogDensityEnd = value;
|
||||||
|
RecalculateFog();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_SetFogMode(FogFunc func) {
|
void Gfx_SetFogMode(FogFunc func) {
|
||||||
|
fogMode = func;
|
||||||
|
RecalculateFog();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetAlphaTest(cc_bool enabled) {
|
static void SetAlphaTest(cc_bool enabled) {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
//glEnable(GL_ALPHA_TEST);
|
//glEnable(GL_ALPHA_TEST);
|
||||||
} else {
|
} else {
|
||||||
//glDisable(GL_ALPHA_TEST);
|
//glDisable(GL_ALPHA_TEST);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
|
||||||
@ -403,7 +560,7 @@ static int lastMatrix;
|
|||||||
|
|
||||||
void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix) {
|
void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix) {
|
||||||
if (type != lastMatrix) {
|
if (type != lastMatrix) {
|
||||||
lastMatrix = type;
|
lastMatrix = type;
|
||||||
MATRIX_CONTROL = matrix_modes[type];
|
MATRIX_CONTROL = matrix_modes[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -421,12 +578,12 @@ void Gfx_LoadMatrix(MatrixType type, const struct Matrix* matrix) {
|
|||||||
MATRIX_LOAD4x4 = floattof32(src[i]);
|
MATRIX_LOAD4x4 = floattof32(src[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vertex commands are signed 16 bit values, with 12 bits fractional
|
// Vertex commands are signed 16 bit values, with 12 bits fractional
|
||||||
// aka only from -8.0 to 8.0
|
// aka only from -8.0 to 8.0
|
||||||
// That's way too small to be useful, so counteract that by scaling down
|
// That's way too small to be useful, so counteract that by scaling down
|
||||||
// vertices and then scaling up the matrix multiplication
|
// vertices and then scaling up the matrix multiplication
|
||||||
if (type == MATRIX_VIEW)
|
if (type == MATRIX_VIEW)
|
||||||
glScalef32(floattof32(64.0f), floattof32(64.0f), floattof32(64.0f));
|
glScalef32(floattof32(64.0f), floattof32(64.0f), floattof32(64.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_LoadMVP(const struct Matrix* view, const struct Matrix* proj, struct Matrix* mvp) {
|
void Gfx_LoadMVP(const struct Matrix* view, const struct Matrix* proj, struct Matrix* mvp) {
|
||||||
@ -435,18 +592,17 @@ void Gfx_LoadMVP(const struct Matrix* view, const struct Matrix* proj, struct Ma
|
|||||||
Matrix_Mul(mvp, view, proj);
|
Matrix_Mul(mvp, view, proj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct Matrix texMatrix;
|
static struct Matrix texMatrix = Matrix_IdentityValue;
|
||||||
void Gfx_EnableTextureOffset(float x, float y) {
|
|
||||||
texMatrix.row1.x = x; texMatrix.row2.y = y;
|
|
||||||
Gfx_LoadMatrix(2, &texMatrix);
|
|
||||||
//glTexParameter(0, TEXGEN_NORMAL | GL_TEXTURE_WRAP_S | GL_TEXTURE_WRAP_T);
|
|
||||||
|
|
||||||
|
void Gfx_EnableTextureOffset(float x, float y) {
|
||||||
|
// Looks bad due to low uvm precision
|
||||||
|
/*texMatrix.row4.x = x * 4096; texMatrix.row4.y = y * 4096;
|
||||||
|
Gfx_LoadMatrix(2, &texMatrix);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DisableTextureOffset(void) {
|
void Gfx_DisableTextureOffset(void) {
|
||||||
texMatrix.row1.x = 0; texMatrix.row1.y = 0;
|
/*texMatrix.row4.x = 0; texMatrix.row4.y = 0;
|
||||||
Gfx_LoadMatrix(2, &texMatrix);
|
Gfx_LoadMatrix(2, &texMatrix);*/
|
||||||
//glTexParameter(0, TEXGEN_TEXCOORD | GL_TEXTURE_WRAP_S | GL_TEXTURE_WRAP_T);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -456,55 +612,39 @@ void Gfx_DisableTextureOffset(void) {
|
|||||||
void Gfx_SetVertexFormat(VertexFormat fmt) {
|
void Gfx_SetVertexFormat(VertexFormat fmt) {
|
||||||
gfx_format = fmt;
|
gfx_format = fmt;
|
||||||
gfx_stride = strideSizes[fmt];
|
gfx_stride = strideSizes[fmt];
|
||||||
|
|
||||||
if (fmt == VERTEX_FORMAT_TEXTURED) {
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
} else {
|
|
||||||
glDisable(GL_TEXTURE_2D);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DrawVb_Lines(int verticesCount) {
|
void Gfx_DrawVb_Lines(int verticesCount) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void CallDrawList(void* list, u32 listSize) {
|
||||||
|
// Based on libnds glCallList
|
||||||
|
while (dmaBusy(0) || dmaBusy(1) || dmaBusy(2) || dmaBusy(3));
|
||||||
|
dmaSetParams(0, list, (void*) &GFX_FIFO, DMA_FIFO | listSize);
|
||||||
|
while (dmaBusy(0));
|
||||||
|
}
|
||||||
|
|
||||||
static void Draw_ColouredTriangles(int verticesCount, int startVertex) {
|
static void Draw_ColouredTriangles(int verticesCount, int startVertex) {
|
||||||
|
glBindTexture(0, 0); // Disable texture
|
||||||
GFX_BEGIN = GL_QUADS;
|
GFX_BEGIN = GL_QUADS;
|
||||||
for (int i = 0; i < verticesCount; i++)
|
CallDrawList(&((struct DSColouredVertex*) gfx_vertices)[startVertex], verticesCount * 4);
|
||||||
{
|
|
||||||
struct DSColouredVertex* v = (struct DSColouredVertex*)gfx_vertices + startVertex + i;
|
|
||||||
|
|
||||||
GFX_COLOR = v->rgb;
|
|
||||||
GFX_VERTEX16 = v->xy;
|
|
||||||
GFX_VERTEX16 = v->z;
|
|
||||||
}
|
|
||||||
GFX_END = 0;
|
GFX_END = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Draw_TexturedTriangles(int verticesCount, int startVertex) {
|
static void Draw_TexturedTriangles(int verticesCount, int startVertex) {
|
||||||
GFX_BEGIN = GL_QUADS;
|
|
||||||
int width = tex_width, height = tex_height;
|
int width = tex_width, height = tex_height;
|
||||||
|
|
||||||
// Original code used was
|
// Scale uvm to fit into texture size
|
||||||
// U = mulf32(v->u, inttof32(width))
|
MATRIX_CONTROL = 3;
|
||||||
// which behind the scenes expands to
|
MATRIX_PUSH = 0;
|
||||||
// W = width << 12
|
glScalef32(width << 4, height << 4, 0);
|
||||||
// U = ((int64)v->u * W) >> 12;
|
|
||||||
// and in this case, the bit shifts can be cancelled out
|
GFX_BEGIN = GL_QUADS;
|
||||||
// to avoid calling __aeabi_lmul to perform the 64 bit multiplication
|
CallDrawList(&((struct DSTexturedVertex*) gfx_vertices)[startVertex], verticesCount * 5);
|
||||||
// therefore the code can be simplified to
|
|
||||||
// U = v->u * width
|
|
||||||
|
|
||||||
for (int i = 0; i < verticesCount; i++)
|
|
||||||
{
|
|
||||||
struct DSTexturedVertex* v = (struct DSTexturedVertex*)gfx_vertices + startVertex + i;
|
|
||||||
|
|
||||||
GFX_COLOR = v->rgb;
|
|
||||||
GFX_TEX_COORD = TEXTURE_PACK(f32tot16(v->u * width), f32tot16(v->v * height));
|
|
||||||
GFX_VERTEX16 = v->xy;
|
|
||||||
GFX_VERTEX16 = v->z;
|
|
||||||
}
|
|
||||||
GFX_END = 0;
|
GFX_END = 0;
|
||||||
|
|
||||||
|
MATRIX_POP = 1;
|
||||||
|
MATRIX_CONTROL = matrix_modes[lastMatrix];
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
|
void Gfx_DrawVb_IndexedTris_Range(int verticesCount, int startVertex) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user