diff --git a/GPU3D.cpp b/GPU3D.cpp index 7f8cabc0..4f20d074 100644 --- a/GPU3D.cpp +++ b/GPU3D.cpp @@ -776,6 +776,10 @@ void SubmitPolygon() poly->FacingView = facingview; + u32 texfmt = (TexParam >> 26) & 0x7; + u32 polyalpha = (CurPolygonAttr >> 16) & 0x1F; + poly->Translucent = (texfmt == 1 || texfmt == 6 || (polyalpha > 0 && polyalpha < 31)); + if (LastStripPolygon && clipstart > 0) { if (c == lastpolyverts) @@ -830,8 +834,8 @@ void SubmitVertex() if ((TexParam >> 30) == 3) { - vertextrans->TexCoords[0] = (CurVertex[0]*TexMatrix[0] + CurVertex[1]*TexMatrix[4] + CurVertex[2]*TexMatrix[8] + 0x1000*TexCoords[0]) >> 20; - vertextrans->TexCoords[1] = (CurVertex[0]*TexMatrix[1] + CurVertex[1]*TexMatrix[5] + CurVertex[2]*TexMatrix[9] + 0x1000*TexCoords[1]) >> 20; + vertextrans->TexCoords[0] = (vertex[0]*TexMatrix[0] + vertex[1]*TexMatrix[4] + vertex[2]*TexMatrix[8] + vertex[3]*(TexCoords[0]<<8)) >> 20; + vertextrans->TexCoords[1] = (vertex[0]*TexMatrix[1] + vertex[1]*TexMatrix[5] + vertex[2]*TexMatrix[9] + vertex[3]*(TexCoords[1]<<8)) >> 20; } else { @@ -911,8 +915,8 @@ s32 CalculateLighting() { if ((TexParam >> 30) == 2) { - TexCoords[0] = (Normal[0]*TexMatrix[0] + Normal[1]*TexMatrix[4] + Normal[2]*TexMatrix[8] + 0x200*TexCoords[0]) >> 17; - TexCoords[1] = (Normal[0]*TexMatrix[1] + Normal[1]*TexMatrix[5] + Normal[2]*TexMatrix[9] + 0x200*TexCoords[1]) >> 17; + TexCoords[0] += (((s64)Normal[0]*TexMatrix[0] + (s64)Normal[1]*TexMatrix[4] + (s64)Normal[2]*TexMatrix[8]) >> 17); + TexCoords[1] += (((s64)Normal[0]*TexMatrix[1] + (s64)Normal[1]*TexMatrix[5] + (s64)Normal[2]*TexMatrix[9]) >> 17); } s32 normaltrans[3]; diff --git a/GPU3D.h b/GPU3D.h index d17cbf58..e2948bfb 100644 --- a/GPU3D.h +++ b/GPU3D.h @@ -50,6 +50,7 @@ typedef struct u32 TexPalette; bool FacingView; + bool Translucent; } Polygon; diff --git a/GPU3D_Soft.cpp b/GPU3D_Soft.cpp index 5c9e7ff4..d29573cf 100644 --- a/GPU3D_Soft.cpp +++ b/GPU3D_Soft.cpp @@ -761,6 +761,7 @@ void RenderPolygon(Polygon* polygon, u32 wbuffer) u32 color = RenderPixel(polygon, x, y, z, vr>>3, vg>>3, vb>>3, s, t); u32 attr = 0; + u32 pixeladdr = (y*256) + x; u8 alpha = color >> 24; @@ -769,14 +770,23 @@ void RenderPolygon(Polygon* polygon, u32 wbuffer) { if (alpha <= AlphaRef) continue; } + else + { + if (alpha == 0) continue; + } // alpha blending disable // TODO: check alpha test when blending is disabled if (!(DispCnt & (1<<3))) alpha = 31; + u32 dstcolor = ColorBuffer[pixeladdr]; + u32 dstalpha = dstcolor >> 24; + if (alpha == 31) { + // edge fill rules for opaque pixels + // TODO, eventually: antialiasing if (!wireframe) { if ((edge & 0x1) && slope_start > 0x1000) @@ -785,18 +795,39 @@ void RenderPolygon(Polygon* polygon, u32 wbuffer) continue; } - DepthBuffer[(y*256) + x] = z; + DepthBuffer[pixeladdr] = z; } - else if (alpha > 0) + else if (dstalpha == 0) { - // + // TODO: conditional Z-buffer update + DepthBuffer[pixeladdr] = z; + } + else + { + u32 srcR = color & 0x3F; + u32 srcG = (color >> 8) & 0x3F; + u32 srcB = (color >> 16) & 0x3F; + + u32 dstR = dstcolor & 0x3F; + u32 dstG = (dstcolor >> 8) & 0x3F; + u32 dstB = (dstcolor >> 16) & 0x3F; + + alpha++; + dstR = ((srcR * alpha) + (dstR * (32-alpha))) >> 5; + dstG = ((srcG * alpha) + (dstG * (32-alpha))) >> 5; + dstB = ((srcB * alpha) + (dstB * (32-alpha))) >> 5; + + alpha--; + if (alpha > dstalpha) dstalpha = alpha; + + color = dstR | (dstG << 8) | (dstB << 16) | (dstalpha << 24); // TODO: conditional Z-buffer update - DepthBuffer[(y*256) + x] = z; + DepthBuffer[pixeladdr] = z; } - ColorBuffer[(y*256) + x] = color; - AttrBuffer[(y*256) + x] = attr; + ColorBuffer[pixeladdr] = color; + AttrBuffer[pixeladdr] = attr; } if (lslope > 0) dxl += lslope; @@ -808,8 +839,6 @@ void RenderPolygon(Polygon* polygon, u32 wbuffer) void RenderFrame(u32 attr, Vertex* vertices, Polygon* polygons, int npolys) { - // TODO: render translucent polygons last - u32 polyid = (ClearAttr1 >> 24) & 0x3F; if (DispCnt & (1<<14)) @@ -866,9 +895,17 @@ void RenderFrame(u32 attr, Vertex* vertices, Polygon* polygons, int npolys) } } + // TODO: Y-sorting of translucent polygons + for (int i = 0; i < npolys; i++) - {//if (i