diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index bab425440..8b0ae5b94 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -734,9 +734,15 @@ static void OGLRender() if(hasShaders) { + //TODO - maybe this should only happen if the toon table is stale (for a slight speedup) + glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_1D, oglToonTableTextureID); - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, gfx3d.rgbToonTable); + + //generate a 8888 toon table from the ds format one and store it in a texture + u32 rgbToonTable[32]; + for(int i=0;i<32;i++) rgbToonTable[i] = RGB15TO32(gfx3d.u16ToonTable[i], 255); + glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, rgbToonTable); } xglDepthMask(GL_TRUE); diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index e7521a57e..8208ce38c 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -909,13 +909,13 @@ BOOL gfx3d_glShininess (u32 val) void gfx3d_UpdateToonTable(u8 offset, u16 val) { - gfx3d.rgbToonTable[offset] = RGB15TO32(val, 255); + gfx3d.u16ToonTable[offset] = val; } void gfx3d_UpdateToonTable(u8 offset, u32 val) { - gfx3d.rgbToonTable[offset] = RGB15TO32(val & 0xFFFF, 255); - gfx3d.rgbToonTable[offset+1] = RGB15TO32(val >> 8, 255); + gfx3d.u16ToonTable[offset] = val & 0xFFFF; + gfx3d.u16ToonTable[offset+1] = val >> 8; } static void gfx3d_glTexImage_cache() @@ -2335,7 +2335,7 @@ SFORMAT SF_GFX3D[]={ { "GSCD", 4, 1, &gfx3d.clearDepth}, { "GSFC", 4, 4, gfx3d.fogColor}, { "GSFO", 4, 1, &gfx3d.fogOffset}, - { "GSTT", 4, 32, gfx3d.rgbToonTable}, + { "GST2", 2, 32, gfx3d.u16ToonTable}, { "GSST", 4, 128, shininessTable}, { "GSSI", 4, 1, &shininessInd}, //------------------------ diff --git a/desmume/src/gfx3d.h b/desmume/src/gfx3d.h index 3df6c281a..164e96a5c 100644 --- a/desmume/src/gfx3d.h +++ b/desmume/src/gfx3d.h @@ -222,7 +222,7 @@ struct GFX3D //you can use this to track how many real frames passed, for comparing to frameCtr; int frameCtrRaw; - u32 rgbToonTable[32]; + u16 u16ToonTable[32]; }; extern GFX3D gfx3d; diff --git a/desmume/src/rasterize.cpp b/desmume/src/rasterize.cpp index 4ec005e30..3795b99b7 100644 --- a/desmume/src/rasterize.cpp +++ b/desmume/src/rasterize.cpp @@ -248,6 +248,7 @@ INLINE static void SubmitVertex(int vert_index, VERT& rawvert) static Fragment screen[256*192]; static FragmentColor screenColor[256*192]; +static FragmentColor toonTable[32]; FORCEINLINE int iround(float f) { @@ -386,34 +387,42 @@ struct Shader dst.a = materialColor.a; break; case 2: //toon/highlight shading - u = invu*w; - v = invv*w; - texColor = sampler.sample(u,v); - u32 toonColorVal; - toonColorVal = gfx3d.rgbToonTable[materialColor.r]; - FragmentColor toonColor; - toonColor.r = ((toonColorVal & 0x0000FF) >> 3); - toonColor.g = ((toonColorVal & 0x00FF00) >> 11); - toonColor.b = ((toonColorVal & 0xFF0000) >> 19); - if(sampler.texFormat == 0) { - //if no texture is set then we dont need to modulate texture with toon - //but rather just use toon directly - dst = toonColor; - dst.a = materialColor.a; - } - else - { - dst.r = modulate_table[texColor.r][toonColor.r]; - dst.g = modulate_table[texColor.g][toonColor.g]; - dst.b = modulate_table[texColor.b][toonColor.b]; - dst.a = modulate_table[texColor.a][materialColor.a]; - } - if(gfx3d.shading == GFX3D::HIGHLIGHT) - { - dst.r = min(31, (dst.r + toonColor.r)); - dst.g = min(31, (dst.g + toonColor.g)); - dst.b = min(31, (dst.b + toonColor.b)); + u = invu*w; + v = invv*w; + texColor = sampler.sample(u,v); + if(texColor.r != 0x1f || texColor.g != 0x1f || texColor.b != 0x1f) { + int zzz=9; + } + FragmentColor toonColor = toonTable[materialColor.r]; + if(sampler.texFormat == 0) + { + //if no texture is set then we dont need to modulate texture with toon + //but rather just use toon directly + dst = toonColor; + dst.a = materialColor.a; + } + else + { + if(gfx3d.shading == GFX3D::HIGHLIGHT) + { + dst.r = modulate_table[texColor.r][materialColor.r]; + dst.g = modulate_table[texColor.g][materialColor.r]; + dst.b = modulate_table[texColor.b][materialColor.r]; + dst.a = modulate_table[texColor.a][materialColor.a]; + + dst.r = min(31, (dst.r + toonColor.r)); + dst.g = min(31, (dst.g + toonColor.g)); + dst.b = min(31, (dst.b + toonColor.b)); + } + else + { + dst.r = modulate_table[texColor.r][toonColor.r]; + dst.g = modulate_table[texColor.g][toonColor.g]; + dst.b = modulate_table[texColor.b][toonColor.b]; + dst.a = modulate_table[texColor.a][materialColor.a]; + } + } } break; case 3: //shadows @@ -1234,6 +1243,14 @@ static void SoftRastRender() for(int i=0;i<256*192;i++) screenColor[i] = clearFragmentColor; + //convert the toon colors + //TODO for a slight speedup this could be cached in gfx3d (oglrenderer could benefit as well) + for(int i=0;i<32;i++) { + toonTable[i].r = gfx3d.u16ToonTable[i]&0x1F; + toonTable[i].g = (gfx3d.u16ToonTable[i]>>5)&0x1F; + toonTable[i].b = (gfx3d.u16ToonTable[i]>>10)&0x1F; + } + //convert colors to float to get more precision in case we need it for(int i=0;icount;i++) gfx3d.vertlist->list[i].color_to_float();