From 1226363d5d085775c3be6334b6f1c881eb3f3174 Mon Sep 17 00:00:00 2001 From: zeromus Date: Wed, 11 Feb 2009 08:58:26 +0000 Subject: [PATCH] rasterize: perspective correct material colors--not doing this was a bug. optionally interpolate material colors when clipping. the hardware doesnt do this, but it looks ugly on the hardware and unless I am debugging I want it done. --- desmume/src/NDSSystem.cpp | 2 ++ desmume/src/NDSSystem.h | 8 ++++++ desmume/src/OGLRender.cpp | 8 +++--- desmume/src/gfx3d.h | 17 +++++++------ desmume/src/rasterize.cpp | 42 ++++++++++++++++++++++++++------ desmume/src/windows/main.cpp | 5 ++++ desmume/src/windows/main.h | 2 ++ desmume/src/windows/resource.h | 2 +- desmume/src/windows/resources.rc | 30 ++++++++++++++--------- 9 files changed, 84 insertions(+), 32 deletions(-) diff --git a/desmume/src/NDSSystem.cpp b/desmume/src/NDSSystem.cpp index e9121ba37..915f93b29 100644 --- a/desmume/src/NDSSystem.cpp +++ b/desmume/src/NDSSystem.cpp @@ -45,6 +45,8 @@ //#define USE_REAL_BIOS +TCommonSettings CommonSettings; + static BOOL LidClosed = FALSE; static u8 countLid = 0; char pathToROM[MAX_PATH]; diff --git a/desmume/src/NDSSystem.h b/desmume/src/NDSSystem.h index 892f9d63c..166249ad9 100644 --- a/desmume/src/NDSSystem.h +++ b/desmume/src/NDSSystem.h @@ -274,6 +274,14 @@ inline u32 NDS_exec(s32 nb) { return NDS_exec(nb); } int NDS_WriteBMP_32bppBuffer(int width, int height, const void* buf, const char *filename); +extern struct TCommonSettings { + TCommonSettings() + : HighResolutionInterpolateColor(true) + {} + bool HighResolutionInterpolateColor; +} CommonSettings; + + #endif diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index c62b0cbe1..0e3d8d967 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -774,23 +774,25 @@ static void OGLRender() VERT *vert1 = &gfx3d.vertlist->list[poly->vertIndexes[j]]; VERT *vert2 = &gfx3d.vertlist->list[poly->vertIndexes[j+1]]; + u8 alpha = material_5bit_to_8bit[poly->getAlpha()]; + u8 color0[4] = { material_5bit_to_8bit[vert0->color[0]], material_5bit_to_8bit[vert0->color[1]], material_5bit_to_8bit[vert0->color[2]], - material_5bit_to_8bit[vert0->color[3]] + alpha }; u8 color1[4] = { material_5bit_to_8bit[vert1->color[0]], material_5bit_to_8bit[vert1->color[1]], material_5bit_to_8bit[vert1->color[2]], - material_5bit_to_8bit[vert1->color[3]] + alpha }; u8 color2[4] = { material_5bit_to_8bit[vert2->color[0]], material_5bit_to_8bit[vert2->color[1]], material_5bit_to_8bit[vert2->color[2]], - material_5bit_to_8bit[vert2->color[3]] + alpha }; glTexCoord2fv(vert0->texcoord); diff --git a/desmume/src/gfx3d.h b/desmume/src/gfx3d.h index aa2702e66..a8d71d212 100644 --- a/desmume/src/gfx3d.h +++ b/desmume/src/gfx3d.h @@ -75,6 +75,8 @@ struct POLY { return false; } + + int getAlpha() { return (polyAttr>>16)&0x1F; } }; #define POLYLIST_SIZE 100000 @@ -84,16 +86,16 @@ struct POLYLIST { int count; }; -/*#define PROJLIST_SIZE 1000 -struct PROJLIST { - float projMatrix[PROJLIST_SIZE][16]; - int count; -};*/ - struct VERT { float coord[4]; float texcoord[2]; - u8 color[4]; + u8 color[3]; + float fcolor[3]; + void color_to_float() { + fcolor[0] = color[0]; + fcolor[1] = color[1]; + fcolor[2] = color[2]; + } }; #define VERTLIST_SIZE 400000 @@ -130,7 +132,6 @@ struct GFX3D POLYLIST* polylist; VERTLIST* vertlist; - //PROJLIST* projlist; int indexlist[POLYLIST_SIZE]; BOOL wbuffer, sortmode; diff --git a/desmume/src/rasterize.cpp b/desmume/src/rasterize.cpp index 59853fb2d..2bc021792 100644 --- a/desmume/src/rasterize.cpp +++ b/desmume/src/rasterize.cpp @@ -36,6 +36,7 @@ #include "render3D.h" #include "gfx3d.h" #include "texcache.h" +#include "NDSSystem.h" using std::min; using std::max; @@ -288,6 +289,7 @@ struct Shader dst.color.components.g = modulate_table[texColor.components.g][materialColor.components.g]; dst.color.components.b = modulate_table[texColor.components.b][materialColor.components.b]; dst.color.components.a = modulate_table[texColor.components.a][materialColor.components.a]; + //debugging tricks //dst.color = materialColor; //dst.color.color = polynum*8+8; //dst.color.components.a = 31; @@ -462,9 +464,9 @@ static void triangle_from_devmaster() float fx1 = verts[0]->coord[0], fy1 = verts[0]->coord[1], fz1 = verts[0]->coord[2]; float fx2 = verts[1]->coord[0], fy2 = verts[1]->coord[1], fz2 = verts[1]->coord[2]; float fx3 = verts[2]->coord[0], fy3 = verts[2]->coord[1], fz3 = verts[2]->coord[2]; - u8 r1 = verts[0]->color[0], g1 = verts[0]->color[1], b1 = verts[0]->color[2], a1 = verts[0]->color[3]; - u8 r2 = verts[1]->color[0], g2 = verts[1]->color[1], b2 = verts[1]->color[2], a2 = verts[1]->color[3]; - u8 r3 = verts[2]->color[0], g3 = verts[2]->color[1], b3 = verts[2]->color[2], a3 = verts[2]->color[3]; + float r1 = verts[0]->fcolor[0], g1 = verts[0]->fcolor[1], b1 = verts[0]->fcolor[2]; + float r2 = verts[1]->fcolor[0], g2 = verts[1]->fcolor[1], b2 = verts[1]->fcolor[2]; + float r3 = verts[2]->fcolor[0], g3 = verts[2]->fcolor[1], b3 = verts[2]->fcolor[2]; float u1 = verts[0]->texcoord[0], v1 = verts[0]->texcoord[1]; float u2 = verts[1]->texcoord[0], v2 = verts[1]->texcoord[1]; float u3 = verts[2]->texcoord[0], v3 = verts[2]->texcoord[1]; @@ -555,13 +557,20 @@ static void triangle_from_devmaster() shader.invw = i_invw.Z; shader.invu = i_tex_invu.Z; shader.invv = i_tex_invv.Z; + + //perspective-correct the colors + float r = (i_color_r.Z / i_invw.Z) + 0.5f; + float g = (i_color_g.Z / i_invw.Z) + 0.5f; + float b = (i_color_b.Z / i_invw.Z) + 0.5f; + //this is a HACK: //we are being very sloppy with our interpolation precision right now //and rather than fix it, i just want to clamp it + shader.materialColor.components.r = max(0,min(31,(int)r)); + shader.materialColor.components.g = max(0,min(31,(int)g)); + shader.materialColor.components.b = max(0,min(31,(int)b)); + shader.materialColor.components.a = polyAttr.alpha; - shader.materialColor.components.r = max(0,min(31,i_color_r.cur())); - shader.materialColor.components.g = max(0,min(31,i_color_g.cur())); - shader.materialColor.components.b = max(0,min(31,i_color_b.cur())); //pixel shader Fragment shaderOutput; @@ -761,10 +770,20 @@ static VERT clipPoint(VERT* inside, VERT* outside, int coord, int which) #define INTERP(X) ret . X = interpolate(t, inside-> X ,outside-> X ) - INTERP(color[0]); INTERP(color[1]); INTERP(color[2]); + INTERP(coord[0]); INTERP(coord[1]); INTERP(coord[2]); INTERP(coord[3]); INTERP(texcoord[0]); INTERP(texcoord[1]); + if(CommonSettings.HighResolutionInterpolateColor) + { + INTERP(fcolor[0]); INTERP(fcolor[1]); INTERP(fcolor[2]); + } + else + { + INTERP(color[0]); INTERP(color[1]); INTERP(color[2]); + ret.color_to_float(); + } + //this seems like a prudent measure to make sure that math doesnt make a point pop back out //of the clip volume through interpolation if(which==-1) @@ -901,7 +920,9 @@ static void SoftRastRender() for(int i=0;i<256*192;i++) screen[i] = clearFragment; - //printf("%d\n",gfx3d.wbuffer?1:0); + //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(); //submit all polys to clipper clippedPolyCounter = 0; @@ -930,6 +951,11 @@ static void SoftRastRender() //vert.coord[1] = max(0.0f,min(1.0f,vert.coord[1])); //vert.coord[2] = max(0.0f,min(1.0f,vert.coord[2])); + //perspective-correct the colors + vert.fcolor[0] /= vert.coord[3]; + vert.fcolor[1] /= vert.coord[3]; + vert.fcolor[2] /= vert.coord[3]; + //viewport transformation vert.coord[0] *= 256; vert.coord[1] *= 192; diff --git a/desmume/src/windows/main.cpp b/desmume/src/windows/main.cpp index 15e6581ee..e8209e006 100644 --- a/desmume/src/windows/main.cpp +++ b/desmume/src/windows/main.cpp @@ -1347,6 +1347,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance, } cur3DCore = GetPrivateProfileInt("3D", "Renderer", GPU3D_OPENGL, IniName); + CommonSettings.HighResolutionInterpolateColor = GetPrivateProfileInt("3D", "HighResolutionInterpolateColor", 1, IniName); NDS_3D_ChangeCore(cur3DCore); #ifdef BETA_VERSION @@ -2651,6 +2652,8 @@ LRESULT CALLBACK GFX3DSettingsDlgProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp) { int i; + CheckDlgButton(hw,IDC_INTERPOLATECOLOR,CommonSettings.HighResolutionInterpolateColor?1:0); + for(i = 0; core3DList[i] != NULL; i++) { ComboBox_AddString(GetDlgItem(hw, IDC_3DCORE), core3DList[i]->name); @@ -2665,8 +2668,10 @@ LRESULT CALLBACK GFX3DSettingsDlgProc(HWND hw, UINT msg, WPARAM wp, LPARAM lp) { case IDOK: { + CommonSettings.HighResolutionInterpolateColor = IsDlgButtonChecked(hw,IDC_INTERPOLATECOLOR); NDS_3D_ChangeCore(ComboBox_GetCurSel(GetDlgItem(hw, IDC_3DCORE))); WritePrivateProfileInt("3D", "Renderer", cur3DCore, IniName); + WritePrivateProfileInt("3D", "HighResolutionInterpolateColor", CommonSettings.HighResolutionInterpolateColor?1:0, IniName); } case IDCANCEL: { diff --git a/desmume/src/windows/main.h b/desmume/src/windows/main.h index ec960ff97..f679e306d 100644 --- a/desmume/src/windows/main.h +++ b/desmume/src/windows/main.h @@ -13,4 +13,6 @@ void Display(); void Pause(); void FrameAdvance(); + + #endif diff --git a/desmume/src/windows/resource.h b/desmume/src/windows/resource.h index 4882fdabd..1a44d77a4 100644 --- a/desmume/src/windows/resource.h +++ b/desmume/src/windows/resource.h @@ -493,4 +493,4 @@ #define IDC_HKCOMBO 60077 #define IDD_KEYCUSTOM 60078 #define IDM_HOTKEY_CONFIG 60079 - +#define IDC_INTERPOLATECOLOR 70000 diff --git a/desmume/src/windows/resources.rc b/desmume/src/windows/resources.rc index b966d3a67..cc094bda2 100644 --- a/desmume/src/windows/resources.rc +++ b/desmume/src/windows/resources.rc @@ -532,46 +532,52 @@ END // Dialog resources // LANGUAGE LANG_DANISH, SUBLANG_DANISH_DENMARK -IDD_3DSETTINGS DIALOG 0, 0, 174, 73 +IDD_3DSETTINGS DIALOG 0, 0, 174, 120 STYLE DS_MODALFRAME | DS_SETFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "3D settings" FONT 8, "MS Sans Serif" BEGIN - DEFPUSHBUTTON "OK", IDOK, 62, 52, 50, 14, BS_DEFPUSHBUTTON - PUSHBUTTON "Cancel", IDCANCEL, 117, 52, 50, 14, BS_PUSHBUTTON - PUSHBUTTON "Default", IDC_DEFAULT, 7, 52, 50, 14, BS_PUSHBUTTON + DEFPUSHBUTTON "OK", IDOK, 62, 92, 50, 14, BS_DEFPUSHBUTTON + PUSHBUTTON "Cancel", IDCANCEL, 117, 92, 50, 14, BS_PUSHBUTTON + PUSHBUTTON "Default", IDC_DEFAULT, 7, 92, 50, 14, BS_PUSHBUTTON GROUPBOX "Renderer:", IDC_STATIC, 7, 7, 160, 39 COMBOBOX IDC_3DCORE, 15, 23, 146, 138, WS_TABSTOP | WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWNLIST + AUTOCHECKBOX "Unrealistically High-Precision Color Interpolation", IDC_INTERPOLATECOLOR, 9, 55, 165, 10, BS_AUTOCHECKBOX + LTEXT "(Presently only effective for SoftRasterizer)", IDC_STATIC, 21, 65, 134, 8, SS_LEFT END LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -IDD_3DSETTINGS DIALOGEX 0, 0, 174, 73 +IDD_3DSETTINGS DIALOGEX 0, 0, 174, 120 STYLE DS_MODALFRAME | DS_SETFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "3D settings" FONT 8, "MS Sans Serif", 0, 0, 0 BEGIN - DEFPUSHBUTTON "OK", IDOK, 62, 52, 50, 14, BS_DEFPUSHBUTTON - PUSHBUTTON "Cancel", IDCANCEL, 117, 52, 50, 14, BS_PUSHBUTTON - PUSHBUTTON "Default", IDC_DEFAULT, 7, 52, 50, 14, BS_PUSHBUTTON + DEFPUSHBUTTON "OK", IDOK, 62, 92, 50, 14, BS_DEFPUSHBUTTON + PUSHBUTTON "Cancel", IDCANCEL, 117, 92, 50, 14, BS_PUSHBUTTON + PUSHBUTTON "Default", IDC_DEFAULT, 7, 92, 50, 14, BS_PUSHBUTTON GROUPBOX "Renderer:", IDC_STATIC, 7, 7, 160, 39 COMBOBOX IDC_3DCORE, 15, 23, 146, 138, WS_TABSTOP | WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWNLIST + AUTOCHECKBOX "Unrealistically High-Precision Color Interpolation", IDC_INTERPOLATECOLOR, 9, 55, 165, 10, BS_AUTOCHECKBOX + LTEXT "(Presently only effective for SoftRasterizer)", IDC_STATIC, 21, 65, 134, 8, SS_LEFT END LANGUAGE LANG_FRENCH, SUBLANG_FRENCH -IDD_3DSETTINGS DIALOG 0, 0, 174, 73 +IDD_3DSETTINGS DIALOG 0, 0, 174, 120 STYLE DS_MODALFRAME | DS_SETFONT | WS_BORDER | WS_CAPTION | WS_DLGFRAME | WS_POPUP | WS_SYSMENU CAPTION "Configuration 3D" FONT 8, "MS Sans Serif" BEGIN - DEFPUSHBUTTON "OK", IDOK, 62, 52, 50, 14, BS_DEFPUSHBUTTON - PUSHBUTTON "Annuler", IDCANCEL, 117, 52, 50, 14, BS_PUSHBUTTON - PUSHBUTTON "Par défaut", IDC_DEFAULT, 7, 52, 50, 14, BS_PUSHBUTTON + DEFPUSHBUTTON "OK", IDOK, 62, 92, 50, 14, BS_DEFPUSHBUTTON + PUSHBUTTON "Annuler", IDCANCEL, 117, 92, 50, 14, BS_PUSHBUTTON + PUSHBUTTON "Par défaut", IDC_DEFAULT, 7, 92, 50, 14, BS_PUSHBUTTON GROUPBOX "Moteur de rendu :", IDC_STATIC, 7, 7, 160, 39 COMBOBOX IDC_3DCORE, 15, 23, 146, 138, WS_TABSTOP | WS_VSCROLL | WS_TABSTOP | CBS_DROPDOWNLIST + AUTOCHECKBOX "Unrealistically High-Precision Color Interpolation", IDC_INTERPOLATECOLOR, 9, 55, 165, 10, BS_AUTOCHECKBOX + LTEXT "(Presently only effective for SoftRasterizer)", IDC_STATIC, 21, 65, 134, 8, SS_LEFT END