diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index d68ad57e0..47ac94427 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -821,13 +821,21 @@ static void OGLRender() if(hasShaders) { + //NOTE: this toon invalidation logic is hopelessly buggy. + //it may sometimes fail. it would be better to always recreate this data. + //but, that may be slow. since the cost of uploading that texture is huge in opengl (relative to rasterizer). + //someone please study it. + //here is a suggestion: it may make sense to memcmp the toon tables and upload only when it actually changes if (gfx3d.renderState.invalidateToon) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_1D, oglToonTableTextureID); - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, &gfx3d.renderState.rgbToonTable[0]); - gfx3d.renderState.invalidateToon = false; + u32 rgbToonTable[32]; + for(int i=0;i<32;i++) + rgbToonTable[i] = RGB15TO32_NOALPHA(gfx3d.renderState.u16ToonTable[i]); + glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, &rgbToonTable[0]); + gfx3d.state.invalidateToon = false; } } diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index b68022314..e85254ad0 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -578,8 +578,6 @@ void gfx3d_reset() GFX_PIPEclear(); GFX_FIFOclear(); - - gfx3d.state.invalidateToon = true; } @@ -1611,16 +1609,16 @@ int gfx3d_GetNumVertex() void gfx3d_UpdateToonTable(u8 offset, u16 val) { - gfx3d.state.rgbToonTable[offset] = RGB15TO32(val, 255); gfx3d.state.invalidateToon = true; + gfx3d.state.u16ToonTable[offset] = val; } void gfx3d_UpdateToonTable(u8 offset, u32 val) { //C.O.P. sets toon table via this method - gfx3d.state.rgbToonTable[offset] = RGB15TO32(val & 0xFFFF, 255); - gfx3d.state.rgbToonTable[offset+1] = RGB15TO32(val >> 16, 255); gfx3d.state.invalidateToon = true; + gfx3d.state.u16ToonTable[offset] = val & 0xFFFF; + gfx3d.state.u16ToonTable[offset+1] = val >> 16; } s32 gfx3d_GetClipMatrix (unsigned int index) @@ -2329,7 +2327,7 @@ SFORMAT SF_GFX3D[]={ { "GSCD", 4, 1, &gfx3d.state.clearDepth}, { "GSFC", 4, 4, &gfx3d.state.fogColor}, { "GSFO", 4, 1, &gfx3d.state.fogOffset}, - { "GST3", 4, 32, gfx3d.state.rgbToonTable}, + { "GST4", 2, 32, gfx3d.state.u16ToonTable}, { "GSST", 4, 128, &gfx3d.state.shininessTable[0]}, { "GSSI", 4, 1, &shininessInd}, { "GSAF", 4, 1, &gfx3d.state.activeFlushCommand}, diff --git a/desmume/src/gfx3d.h b/desmume/src/gfx3d.h index 90cc19c6e..044ca2ee0 100644 --- a/desmume/src/gfx3d.h +++ b/desmume/src/gfx3d.h @@ -103,6 +103,7 @@ inline u32 RGB15TO6665(u16 col, u8 alpha5) //produce a 15bpp color from individual 5bit components #define R5G5B5TORGB15(r,g,b) ((r)|((g)<<5)|((b)<<10)) +#define RGB15TO32_NOALPHA(col) ( color_15bit_to_24bit[col&0x7FFF] ) //produce a 16bpp color from individual 5bit components #define R6G6B6TORGB15(r,g,b) ((r>>1)|((g&0x3E)<<4)|((b&0x3E)<<9)) @@ -317,8 +318,8 @@ struct GFX3D_State for(u32 i=0;i> 2) & 0x3F; - toonTable[i].g = (gfx3d.renderState.rgbToonTable[i] >> 10) & 0x3F; - toonTable[i].b = (gfx3d.renderState.rgbToonTable[i] >> 18) & 0x3F; + #ifdef WORDS_BIGENDIAN + u32 u32temp = RGB15TO32(gfx3d.renderState.u16ToonTable[i]); + toonTable[i].r = (u32temp >> 2) & 0x3F; + toonTable[i].g = (u32temp >> 10) & 0x3F; + toonTable[i].b = (u32temp >> 18) & 0x3F; + #else + toonTable[i].color = (RGB15TO32_NOALPHA(gfx3d.renderState.u16ToonTable[i])>>2)&0x3F3F3F3F; + #endif } - gfx3d.renderState.invalidateToon = false; } void SoftRasterizerEngine::updateFogTable()