From 4599527921be131edba2c484171a431db89a1beb Mon Sep 17 00:00:00 2001 From: Sergey Lipskiy Date: Thu, 18 Dec 2014 19:38:43 +0600 Subject: [PATCH] Implement flat shading. --- OpenGL.cpp | 36 +++++++++++++++++++++++++++++++++++- OpenGL.h | 3 ++- gSP.h | 2 ++ 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/OpenGL.cpp b/OpenGL.cpp index 59ccf0c8..848d655b 100644 --- a/OpenGL.cpp +++ b/OpenGL.cpp @@ -267,6 +267,27 @@ void OGLRender::addTriangle(int _v0, int _v1, int _v2) triangles.elements[triangles.num++] = _v0; triangles.elements[triangles.num++] = _v1; triangles.elements[triangles.num++] = _v2; + + if ((gSP.geometryMode & G_SHADE) == 0) { + // Prim shading + for (u32 i = triangles.num - 3; i < triangles.num; ++i) { + SPVertex & vtx = triangles.vertices[triangles.elements[i]]; + vtx.flat_r = gDP.primColor.r; + vtx.flat_g = gDP.primColor.g; + vtx.flat_b = gDP.primColor.b; + vtx.flat_a = vtx.a; + } + } else if ((gSP.geometryMode & G_SHADING_SMOOTH) == 0) { + // Flat shading + SPVertex & vtx0 = triangles.vertices[_v0]; + for (u32 i = triangles.num - 3; i < triangles.num; ++i) { + SPVertex & vtx = triangles.vertices[triangles.elements[i]]; + vtx.flat_r = vtx0.r; + vtx.flat_g = vtx0.g; + vtx.flat_b = vtx0.b; + vtx.flat_a = vtx.a; + } + } } #define ORKIN_BLENDMODE @@ -687,10 +708,17 @@ void OGLRender::_prepareDrawTriangle(bool _dma) _setTexCoordArrays(); } + const bool updateColorArrays = m_bFlatColors != (!RSP.bLLE && (gSP.geometryMode & G_SHADING_SMOOTH) == 0); + if (updateColorArrays) + m_bFlatColors = !m_bFlatColors; + if (updateArrays) { SPVertex * pVtx = _dma ? triangles.dmaVertices.data() : &triangles.vertices[0]; glVertexAttribPointer(SC_POSITION, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->x); - glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->r); + if (m_bFlatColors) + glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->flat_r); + else + glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->r); glVertexAttribPointer(SC_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->s); if (config.enableHWLighting) { glEnableVertexAttribArray(SC_NUMLIGHTS); @@ -701,6 +729,12 @@ void OGLRender::_prepareDrawTriangle(bool _dma) _updateViewport(); glEnable(GL_SCISSOR_TEST); currentCombiner()->updateRenderState(); + } else if (updateColorArrays) { + SPVertex * pVtx = _dma ? triangles.dmaVertices.data() : &triangles.vertices[0]; + if (m_bFlatColors) + glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->flat_r); + else + glVertexAttribPointer(SC_COLOR, 4, GL_FLOAT, GL_FALSE, sizeof(SPVertex), &pVtx->r); } currentCombiner()->updateColors(); diff --git a/OpenGL.h b/OpenGL.h index 3a686a21..7e948dca 100644 --- a/OpenGL.h +++ b/OpenGL.h @@ -87,7 +87,7 @@ public: #endif // __TRIBUFFER_OPT private: - OGLRender() : m_bImageTexture(false) {} + OGLRender() : m_bImageTexture(false), m_bFlatColors(false) {} OGLRender(const OGLRender &); friend class OGLVideo; @@ -133,6 +133,7 @@ private: RENDER_STATE m_renderState; GLVertex m_rect[4]; bool m_bImageTexture; + bool m_bFlatColors; }; class OGLVideo diff --git a/gSP.h b/gSP.h index 90ab7f30..39b1805c 100644 --- a/gSP.h +++ b/gSP.h @@ -21,6 +21,7 @@ if \ ( \ ( \ (video().getRender().getTrianglesCount() > 1000) || \ + ((gSP.geometryMode & G_SHADING_SMOOTH) == 0) || \ ( \ (RSP.nextCmd != G_NOOP) && \ (RSP.nextCmd != G_RDPNOOP) && \ @@ -73,6 +74,7 @@ struct SPVertex f32 x, y, z, w; f32 nx, ny, nz, __pad0; f32 r, g, b, a; + f32 flat_r, flat_g, flat_b, flat_a; f32 s, t; u8 HWLight; s16 flag;