mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2025-04-10 19:15:14 +00:00
Support high priority polygons. They are treated as a separate overlay plane by the h/w. Fixes some missing fx in harley.
This commit is contained in:
parent
2ae2010ee4
commit
5b9741bd5d
Src/Graphics/New3D
|
@ -47,6 +47,23 @@ struct R3DPoly
|
||||||
|
|
||||||
struct Mesh
|
struct Mesh
|
||||||
{
|
{
|
||||||
|
//helper funcs
|
||||||
|
bool Render(bool alpha)
|
||||||
|
{
|
||||||
|
if (alpha) {
|
||||||
|
if (!textureAlpha && !polyAlpha) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (textureAlpha || polyAlpha) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// texture
|
// texture
|
||||||
int format, x, y, width, height = 0;
|
int format, x, y, width, height = 0;
|
||||||
bool mirrorU = false;
|
bool mirrorU = false;
|
||||||
|
@ -65,6 +82,7 @@ struct Mesh
|
||||||
bool alphaTest = false; // discard fragment based on alpha (ogl does this with fixed function)
|
bool alphaTest = false; // discard fragment based on alpha (ogl does this with fixed function)
|
||||||
bool clockWise = true; // we need to check if the matrix will change the winding
|
bool clockWise = true; // we need to check if the matrix will change the winding
|
||||||
bool layered = false; // stencil poly
|
bool layered = false; // stencil poly
|
||||||
|
bool highPriority = false; // rendered over the top
|
||||||
|
|
||||||
// lighting
|
// lighting
|
||||||
bool lighting = false;
|
bool lighting = false;
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <string.h>
|
||||||
#include "R3DFloat.h"
|
#include "R3DFloat.h"
|
||||||
|
|
||||||
#define MAX_RAM_POLYS 100000
|
#define MAX_RAM_POLYS 100000
|
||||||
|
@ -103,8 +104,10 @@ void CNew3D::DrawScrollFog()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNew3D::RenderScene(int priority, bool alpha)
|
bool CNew3D::RenderScene(int priority, bool renderOverlay, bool alpha)
|
||||||
{
|
{
|
||||||
|
bool hasOverlay = false; // (high priority polys)
|
||||||
|
|
||||||
if (alpha) {
|
if (alpha) {
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
@ -138,17 +141,13 @@ void CNew3D::RenderScene(int priority, bool alpha)
|
||||||
|
|
||||||
for (auto &mesh : *m.meshes) {
|
for (auto &mesh : *m.meshes) {
|
||||||
|
|
||||||
if (alpha) {
|
if (mesh.highPriority) {
|
||||||
if (!mesh.textureAlpha && !mesh.polyAlpha) {
|
hasOverlay = true;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (mesh.textureAlpha || mesh.polyAlpha) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mesh.Render(alpha)) continue;
|
||||||
|
if (mesh.highPriority != renderOverlay) continue;
|
||||||
|
|
||||||
if (!matrixLoaded) {
|
if (!matrixLoaded) {
|
||||||
glLoadMatrixf(m.modelMat);
|
glLoadMatrixf(m.modelMat);
|
||||||
matrixLoaded = true; // do this here to stop loading matrices we don't need. Ie when rendering non transparent etc
|
matrixLoaded = true; // do this here to stop loading matrices we don't need. Ie when rendering non transparent etc
|
||||||
|
@ -192,6 +191,8 @@ void CNew3D::RenderScene(int priority, bool alpha)
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
|
||||||
|
return hasOverlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CNew3D::RenderFrame(void)
|
void CNew3D::RenderFrame(void)
|
||||||
|
@ -259,9 +260,24 @@ void CNew3D::RenderFrame(void)
|
||||||
m_r3dShader.SetShader(true);
|
m_r3dShader.SetShader(true);
|
||||||
|
|
||||||
for (int pri = 0; pri <= 3; pri++) {
|
for (int pri = 0; pri <= 3; pri++) {
|
||||||
|
|
||||||
|
//==============
|
||||||
|
bool hasOverlay;
|
||||||
|
//==============
|
||||||
|
|
||||||
|
glViewport (0, 0, m_totalXRes, m_totalYRes); // clear whole viewport
|
||||||
glClear (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
|
glClear (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
|
||||||
RenderScene (pri, false);
|
|
||||||
RenderScene (pri, true);
|
hasOverlay = RenderScene(pri, false, false);
|
||||||
|
hasOverlay = RenderScene(pri, false, true);
|
||||||
|
|
||||||
|
if (hasOverlay) {
|
||||||
|
//clear depth buffer and render high priority polys
|
||||||
|
glViewport(0, 0, m_totalXRes, m_totalYRes); // clear whole viewport
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
|
RenderScene(pri, true, false);
|
||||||
|
RenderScene(pri, true, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_r3dShader.SetShader(false); // unbind shader
|
m_r3dShader.SetShader(false); // unbind shader
|
||||||
|
@ -828,7 +844,7 @@ void CNew3D::CopyVertexData(const R3DPoly& r3dPoly, std::vector<Poly>& polyArray
|
||||||
V3::createNormal(r3dPoly.v[0].pos, r3dPoly.v[1].pos, r3dPoly.v[2].pos, normal);
|
V3::createNormal(r3dPoly.v[0].pos, r3dPoly.v[1].pos, r3dPoly.v[2].pos, normal);
|
||||||
|
|
||||||
dotProd = V3::dotProduct(normal, r3dPoly.faceNormal);
|
dotProd = V3::dotProduct(normal, r3dPoly.faceNormal);
|
||||||
clockWise = dotProd >= 0.0;
|
clockWise = dotProd >= 0;
|
||||||
|
|
||||||
if (clockWise) {
|
if (clockWise) {
|
||||||
p.p1 = r3dPoly.v[0];
|
p.p1 = r3dPoly.v[0];
|
||||||
|
@ -930,6 +946,7 @@ void CNew3D::SetMeshValues(SortingMesh *currentMesh, PolyHeader &ph)
|
||||||
currentMesh->textureAlpha = ph.TextureAlpha();
|
currentMesh->textureAlpha = ph.TextureAlpha();
|
||||||
currentMesh->polyAlpha = ph.PolyAlpha();
|
currentMesh->polyAlpha = ph.PolyAlpha();
|
||||||
currentMesh->lighting = ph.LightEnabled() && !ph.FixedShading();
|
currentMesh->lighting = ph.LightEnabled() && !ph.FixedShading();
|
||||||
|
currentMesh->highPriority = ph.HighPriority();
|
||||||
|
|
||||||
if (ph.Layered() || (!ph.TexEnabled() && ph.PolyAlpha())) {
|
if (ph.Layered() || (!ph.TexEnabled() && ph.PolyAlpha())) {
|
||||||
currentMesh->layered = true;
|
currentMesh->layered = true;
|
||||||
|
|
|
@ -176,9 +176,9 @@ private:
|
||||||
void CopyVertexData(const R3DPoly& r3dPoly, std::vector<Poly>& polyArray);
|
void CopyVertexData(const R3DPoly& r3dPoly, std::vector<Poly>& polyArray);
|
||||||
void OffsetTexCoords(R3DPoly& r3dPoly, float offset[2]);
|
void OffsetTexCoords(R3DPoly& r3dPoly, float offset[2]);
|
||||||
|
|
||||||
void RenderScene(int priority, bool alpha);
|
bool RenderScene(int priority, bool renderOverlay, bool alpha); // returns if has overlay plane
|
||||||
float Determinant3x3(const float m[16]);
|
float Determinant3x3(const float m[16]);
|
||||||
bool IsDynamicModel(UINT32 *data); // check if the model has a colour palette
|
bool IsDynamicModel(UINT32 *data); // check if the model has a colour palette
|
||||||
bool IsVROMModel(UINT32 modelAddr);
|
bool IsVROMModel(UINT32 modelAddr);
|
||||||
void DrawScrollFog();
|
void DrawScrollFog();
|
||||||
|
|
||||||
|
|
|
@ -381,8 +381,9 @@ UINT64 PolyHeader::Hash()
|
||||||
hash |= (UINT64)DoubleSided() << 33; // bits 33 double sided
|
hash |= (UINT64)DoubleSided() << 33; // bits 33 double sided
|
||||||
hash |= (UINT64)AlphaTest() << 34; // bits 34 contour processing
|
hash |= (UINT64)AlphaTest() << 34; // bits 34 contour processing
|
||||||
hash |= (UINT64)PolyAlpha() << 35; // bits 35 poly alpha processing
|
hash |= (UINT64)PolyAlpha() << 35; // bits 35 poly alpha processing
|
||||||
hash |= (UINT64)TextureAlpha() << 36; // bits 35 texture alpha processing
|
hash |= (UINT64)TextureAlpha() << 36; // bits 36 texture alpha processing
|
||||||
hash |= (UINT64)MicroTexture() << 37; // bits 36 microtexture enable
|
hash |= (UINT64)MicroTexture() << 37; // bits 37 microtexture enable
|
||||||
|
hash |= (UINT64)HighPriority() << 38; // bits 38 high priority enable
|
||||||
|
|
||||||
//to do add the rest of the states
|
//to do add the rest of the states
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue