Skip to content

Commit

Permalink
Correct color of line vertices.
Browse files Browse the repository at this point in the history
  • Loading branch information
gonetz committed Jul 5, 2024
1 parent 2be0355 commit fb645bf
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 31 deletions.
71 changes: 43 additions & 28 deletions src/GraphicsDrawer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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++;
Expand All @@ -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;
}

Expand All @@ -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();
}
Expand Down
4 changes: 2 additions & 2 deletions src/GraphicsDrawer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion src/gSP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit fb645bf

Please sign in to comment.