mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2024-11-30 01:25:49 +00:00
Split face colour from per vertex poly colour. Fixes colour bleeding between connected polys in harley.
This commit is contained in:
parent
595e24ad60
commit
ded3168060
|
@ -30,6 +30,7 @@ struct R3DPoly
|
||||||
{
|
{
|
||||||
Vertex v[4]; // just easier to have them as an array
|
Vertex v[4]; // just easier to have them as an array
|
||||||
float faceNormal[3]; // we need this to help work out poly winding, i assume the h/w uses this instead of calculating normals itself
|
float faceNormal[3]; // we need this to help work out poly winding, i assume the h/w uses this instead of calculating normals itself
|
||||||
|
float faceColour[4]; // per face colour
|
||||||
int number = 4;
|
int number = 4;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -732,7 +732,7 @@ void CNew3D::RenderViewport(UINT32 addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNew3D::CopyVertexData(R3DPoly& r3dPoly, std::vector<Poly>& polyArray)
|
void CNew3D::CopyVertexData(const R3DPoly& r3dPoly, std::vector<Poly>& polyArray)
|
||||||
{
|
{
|
||||||
//====================
|
//====================
|
||||||
Poly p;
|
Poly p;
|
||||||
|
@ -757,6 +757,13 @@ void CNew3D::CopyVertexData(R3DPoly& r3dPoly, std::vector<Poly>& polyArray)
|
||||||
p.p3 = r3dPoly.v[0];
|
p.p3 = r3dPoly.v[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//multiply face attributes with vertex attributes if required
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
p.p1.color[i] = (UINT8)(p.p1.color[i] * r3dPoly.faceColour[i]);
|
||||||
|
p.p2.color[i] = (UINT8)(p.p2.color[i] * r3dPoly.faceColour[i]);
|
||||||
|
p.p3.color[i] = (UINT8)(p.p3.color[i] * r3dPoly.faceColour[i]);
|
||||||
|
}
|
||||||
|
|
||||||
polyArray.emplace_back(p);
|
polyArray.emplace_back(p);
|
||||||
|
|
||||||
if (r3dPoly.number == 4) {
|
if (r3dPoly.number == 4) {
|
||||||
|
@ -772,6 +779,13 @@ void CNew3D::CopyVertexData(R3DPoly& r3dPoly, std::vector<Poly>& polyArray)
|
||||||
p.p3 = r3dPoly.v[2];
|
p.p3 = r3dPoly.v[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//multiply face attributes with vertex attributes if required
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
p.p1.color[i] = (UINT8)(p.p1.color[i] * r3dPoly.faceColour[i]);
|
||||||
|
p.p2.color[i] = (UINT8)(p.p2.color[i] * r3dPoly.faceColour[i]);
|
||||||
|
p.p3.color[i] = (UINT8)(p.p3.color[i] * r3dPoly.faceColour[i]);
|
||||||
|
}
|
||||||
|
|
||||||
polyArray.emplace_back(p);
|
polyArray.emplace_back(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -887,6 +901,37 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy face attributes
|
||||||
|
|
||||||
|
for (i = 0; i < p.number; i++) {
|
||||||
|
|
||||||
|
if ((ph.header[1] & 2) == 0) {
|
||||||
|
UINT32 colorIdx = (ph.header[4] >> 8) & 0x7FF;
|
||||||
|
p.faceColour[2] = (m_polyRAM[0x400 + colorIdx] & 0xFF) / 255.f;
|
||||||
|
p.faceColour[1] = ((m_polyRAM[0x400 + colorIdx] >> 8) & 0xFF) / 255.f;
|
||||||
|
p.faceColour[0] = ((m_polyRAM[0x400 + colorIdx] >> 16) & 0xFF) / 255.f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (ph.ColorDisabled()) { // no colours were set
|
||||||
|
p.faceColour[0] = 1.0f;
|
||||||
|
p.faceColour[1] = 1.0f;
|
||||||
|
p.faceColour[2] = 1.0f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p.faceColour[0] = ((ph.header[4] >> 24)) / 255.f;
|
||||||
|
p.faceColour[1] = ((ph.header[4] >> 16) & 0xFF) / 255.f;
|
||||||
|
p.faceColour[2] = ((ph.header[4] >> 8) & 0xFF) / 255.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((ph.header[6] & 0x00800000)) { // if set, polygon is opaque
|
||||||
|
p.faceColour[3] = 1.0f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p.faceColour[3] = ph.Transparency() / 255.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if we have flat shading, we can't re-use normals from shared vertices
|
// if we have flat shading, we can't re-use normals from shared vertices
|
||||||
for (i = 0; i < p.number && !ph.SmoothShading(); i++) {
|
for (i = 0; i < p.number && !ph.SmoothShading(); i++) {
|
||||||
p.v[i].normal[0] = p.faceNormal[0];
|
p.v[i].normal[0] = p.faceNormal[0];
|
||||||
|
@ -894,7 +939,8 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
p.v[i].normal[2] = p.faceNormal[2];
|
p.v[i].normal[2] = p.faceNormal[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; j < p.number; j++) // remaining vertices are new and defined here
|
// remaining vertices are new and defined here
|
||||||
|
for (; j < p.number; j++)
|
||||||
{
|
{
|
||||||
// Fetch vertices
|
// Fetch vertices
|
||||||
UINT32 ix = data[0];
|
UINT32 ix = data[0];
|
||||||
|
@ -914,37 +960,18 @@ void CNew3D::CacheModel(Model *m, const UINT32 *data)
|
||||||
p.v[j].normal[2] = (INT8)(iz & 0xFF) / 128.f;
|
p.v[j].normal[2] = (INT8)(iz & 0xFF) / 128.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ph.header[1] & 2) == 0) {
|
|
||||||
UINT32 colorIdx = ((ph.header[4] >> 8) & 0x7FF);
|
|
||||||
p.v[j].color[2] = (m_polyRAM[0x400 + colorIdx] & 0xFF);
|
|
||||||
p.v[j].color[1] = (m_polyRAM[0x400 + colorIdx] >> 8) & 0xFF;
|
|
||||||
p.v[j].color[0] = (m_polyRAM[0x400 + colorIdx] >> 16) & 0xFF;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (ph.ColorDisabled()) { // no colours were set
|
|
||||||
p.v[j].color[0] = 255;
|
|
||||||
p.v[j].color[1] = 255;
|
|
||||||
p.v[j].color[2] = 255;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
p.v[j].color[0] = (ph.header[4] >> 24);
|
|
||||||
p.v[j].color[1] = (ph.header[4] >> 16) & 0xFF;
|
|
||||||
p.v[j].color[2] = (ph.header[4] >> 8) & 0xFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ph.FixedShading() && ph.LightEnabled()) {
|
if (ph.FixedShading() && ph.LightEnabled()) {
|
||||||
float shade = ((ix+128) & 0xFF) / 255.f;
|
UINT8 shade = (UINT8)((ix + 128) & 0xFF);
|
||||||
p.v[j].color[0] = (UINT8)(p.v[j].color[0] * shade);
|
p.v[j].color[0] = shade; // hardware doesn't really have per vertex colours, only per poly
|
||||||
p.v[j].color[1] = (UINT8)(p.v[j].color[1] * shade);
|
p.v[j].color[1] = shade;
|
||||||
p.v[j].color[2] = (UINT8)(p.v[j].color[2] * shade);
|
p.v[j].color[2] = shade;
|
||||||
}
|
|
||||||
|
|
||||||
if ((ph.header[6] & 0x00800000)) { // if set, polygon is opaque
|
|
||||||
p.v[j].color[3] = 255;
|
p.v[j].color[3] = 255;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p.v[j].color[3] = ph.Transparency();
|
p.v[j].color[0] = 255;
|
||||||
|
p.v[j].color[1] = 255;
|
||||||
|
p.v[j].color[2] = 255;
|
||||||
|
p.v[j].color[3] = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
float texU, texV = 0;
|
float texU, texV = 0;
|
||||||
|
|
|
@ -168,7 +168,7 @@ private:
|
||||||
|
|
||||||
// building the scene
|
// building the scene
|
||||||
void CacheModel(Model *m, const UINT32 *data);
|
void CacheModel(Model *m, const UINT32 *data);
|
||||||
void CopyVertexData(R3DPoly& r3dPoly, std::vector<Poly>& polyArray);
|
void CopyVertexData(const R3DPoly& r3dPoly, std::vector<Poly>& polyArray);
|
||||||
|
|
||||||
void RenderScene(int priority, bool alpha);
|
void RenderScene(int priority, bool alpha);
|
||||||
float Determinant3x3(const float m[16]);
|
float Determinant3x3(const float m[16]);
|
||||||
|
|
Loading…
Reference in a new issue