From fb645bfcc8df959666543cf1f54ab3147c8f08b9 Mon Sep 17 00:00:00 2001 From: Sergey Lipskiy Date: Thu, 4 Jul 2024 23:58:28 +0700 Subject: [PATCH] Correct color of line vertices. --- src/GraphicsDrawer.cpp | 71 +++++++++++++++++++++++++----------------- src/GraphicsDrawer.h | 4 +-- src/gSP.cpp | 2 +- 3 files changed, 46 insertions(+), 31 deletions(-) diff --git a/src/GraphicsDrawer.cpp b/src/GraphicsDrawer.cpp index b5963eb7a..7be62d97e 100644 --- a/src/GraphicsDrawer.cpp +++ b/src/GraphicsDrawer.cpp @@ -984,47 +984,59 @@ void GraphicsDrawer::drawDMATriangles(u32 _numVtx) dropRenderState(); } -void GraphicsDrawer::_drawThickLine(u32 _v0, u32 _v1, float _width) +static void correctLineVerticesColor(SPVertex _vertexBuf[2], SPVertex& _v0) { + auto copyColors = [](f32 const* src, f32* dst1, f32* dst2) + { + for (u32 i = 0; i < 4; ++i) + dst1[i] = dst2[i] = src[i]; + }; + + auto convertNormalsToColors = [](f32 const* normals, f32* dst) + { + // Line3D* microcodes have no lighting code + // Original colors are stored in vertex normals, which need to be converted back to colors. + for (u32 i = 0; i < 3; ++i) { + f32 color = normals[i] * 0.5f; + if (color < 0.0f) + color += 1.0f; + dst[i] = color; + } + }; + + SPVertex & vtx1 = _vertexBuf[0]; + SPVertex & vtx2 = _vertexBuf[1]; if ((gSP.geometryMode & G_LIGHTING) == 0) { if ((gSP.geometryMode & G_SHADE) == 0) { - SPVertex & vtx1 = triangles.vertices[_v0]; - vtx1.flat_r = gDP.primColor.r; - vtx1.flat_g = gDP.primColor.g; - vtx1.flat_b = gDP.primColor.b; - vtx1.flat_a = gDP.primColor.a; - SPVertex & vtx2 = triangles.vertices[_v1]; - vtx2.flat_r = gDP.primColor.r; - vtx2.flat_g = gDP.primColor.g; - vtx2.flat_b = gDP.primColor.b; - vtx2.flat_a = gDP.primColor.a; - } - else if ((gSP.geometryMode & G_SHADING_SMOOTH) == 0) { + copyColors(&gDP.primColor.r, &vtx1.r, &vtx1.flat_r); + copyColors(&gDP.primColor.r, &vtx2.r, &vtx2.flat_r); + } else if ((gSP.geometryMode & G_SHADING_SMOOTH) == 0) { // Flat shading - SPVertex & vtx0 = triangles.vertices[_v0 + ((RSP.w1 >> 24) & 3)]; - SPVertex & vtx1 = triangles.vertices[_v0]; - vtx1.r = vtx1.flat_r = vtx0.r; - vtx1.g = vtx1.flat_g = vtx0.g; - vtx1.b = vtx1.flat_b = vtx0.b; - vtx1.a = vtx1.flat_a = vtx0.a; - SPVertex & vtx2 = triangles.vertices[_v1]; - vtx2.r = vtx2.flat_r = vtx0.r; - vtx2.g = vtx2.flat_g = vtx0.g; - vtx2.b = vtx2.flat_b = vtx0.b; - vtx2.a = vtx2.flat_a = vtx0.a; + copyColors(&_v0.r, &vtx1.r, &vtx1.flat_r); + copyColors(&_v0.r, &vtx2.r, &vtx2.flat_r); } } + else { + convertNormalsToColors(&vtx1.nx, &vtx1.r); + convertNormalsToColors(&vtx2.nx, &vtx2.r); + } +} + +void GraphicsDrawer::_drawThickLine(u32 _v0, u32 _v1, float _width, u32 _flag) +{ + SPVertex vertexBuf[2] = { triangles.vertices[_v0], triangles.vertices[_v1] }; + correctLineVerticesColor(vertexBuf, triangles.vertices[_flag]); setDMAVerticesSize(4); SPVertex * pVtx = getDMAVerticesData(); const f32 ySign = GBI.isNegativeY() ? -1.0f : 1.0f; - pVtx[0] = triangles.vertices[_v0]; + pVtx[0] = vertexBuf[0]; pVtx[0].x = pVtx[0].x / pVtx[0].w * gSP.viewport.vscale[0] + gSP.viewport.vtrans[0]; pVtx[0].y = ySign * pVtx[0].y / pVtx[0].w * gSP.viewport.vscale[1] + gSP.viewport.vtrans[1]; pVtx[0].z = pVtx[0].z / pVtx[0].w; pVtx[1] = pVtx[0]; - pVtx[2] = triangles.vertices[_v1]; + pVtx[2] = vertexBuf[1]; pVtx[2].x = pVtx[2].x / pVtx[2].w * gSP.viewport.vscale[0] + gSP.viewport.vtrans[0]; pVtx[2].y = ySign * pVtx[2].y / pVtx[2].w * gSP.viewport.vscale[1] + gSP.viewport.vtrans[1]; pVtx[2].z = pVtx[2].z / pVtx[2].w; @@ -1060,7 +1072,7 @@ void GraphicsDrawer::_drawThickLine(u32 _v0, u32 _v1, float _width) drawScreenSpaceTriangle(4); } -void GraphicsDrawer::drawLine(u32 _v0, u32 _v1, float _width) +void GraphicsDrawer::drawLine(u32 _v0, u32 _v1, float _width, u32 _flag) { m_texrectDrawer.draw(); m_statistics.lines++; @@ -1073,8 +1085,9 @@ void GraphicsDrawer::drawLine(u32 _v0, u32 _v1, float _width) lineWidth *= dwnd().getScaleX(); else lineWidth *= config.frameBufferEmulation.nativeResFactor; + if (lineWidth > m_maxLineWidth) { - _drawThickLine(_v0, _v1, _width * 0.5f); + _drawThickLine(_v0, _v1, _width * 0.5f, _flag); return; } @@ -1089,6 +1102,8 @@ void GraphicsDrawer::drawLine(u32 _v0, u32 _v1, float _width) _updateViewport(); SPVertex vertexBuf[2] = { triangles.vertices[_v0], triangles.vertices[_v1] }; + correctLineVerticesColor(vertexBuf, triangles.vertices[_flag]); + gfxContext.drawLine(lineWidth, vertexBuf); dropRenderState(); } diff --git a/src/GraphicsDrawer.h b/src/GraphicsDrawer.h index 5f0c307c5..466620da4 100644 --- a/src/GraphicsDrawer.h +++ b/src/GraphicsDrawer.h @@ -53,7 +53,7 @@ class GraphicsDrawer void drawDMATriangles(u32 _numVtx); - void drawLine(u32 _v0, u32 _v1, float _width); + void drawLine(u32 _v0, u32 _v1, float _width, u32 _flag); void drawRect(int _ulx, int _uly, int _lrx, int _lry); @@ -210,7 +210,7 @@ class GraphicsDrawer void _updateStates(DrawingState _drawingState) const; void _prepareDrawTriangle(DrawingState _drawingState); bool _canDraw() const; - void _drawThickLine(u32 _v0, u32 _v1, float _width); + void _drawThickLine(u32 _v0, u32 _v1, float _width, u32 _flag); void _drawOSD(const char *_pText, float _x, float & _y); diff --git a/src/gSP.cpp b/src/gSP.cpp index 641d367b0..b22c49577 100644 --- a/src/gSP.cpp +++ b/src/gSP.cpp @@ -1974,7 +1974,7 @@ void gSPSetOtherMode_L(u32 _length, u32 _shift, u32 _data) void gSPLine3D(u32 v0, u32 v1, s32 wd, u32 flag ) { - dwnd().getDrawer().drawLine(v0, v1, 1.5f + wd * 0.5f); + dwnd().getDrawer().drawLine(v0, v1, 1.5f + wd * 0.5f, flag); DebugMsg(DEBUG_NORMAL, "gSPLine3D( %i, %i, %i, %i )\n", v0, v1, wd, flag); }