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:
Ian Curtis 2017-02-20 17:22:32 +00:00
parent 2ae2010ee4
commit 5b9741bd5d
4 changed files with 53 additions and 17 deletions

View file

@ -47,6 +47,23 @@ struct R3DPoly
struct Mesh
{
//helper funcs
bool Render(bool alpha)
{
if (alpha) {
if (!textureAlpha && !polyAlpha) {
return false;
}
}
else {
if (textureAlpha || polyAlpha) {
return false;
}
}
return true;
}
// texture
int format, x, y, width, height = 0;
bool mirrorU = false;
@ -65,6 +82,7 @@ struct Mesh
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 layered = false; // stencil poly
bool highPriority = false; // rendered over the top
// lighting
bool lighting = false;

View file

@ -4,6 +4,7 @@
#include <cmath>
#include <algorithm>
#include <limits>
#include <string.h>
#include "R3DFloat.h"
#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) {
glEnable(GL_BLEND);
}
@ -138,17 +141,13 @@ void CNew3D::RenderScene(int priority, bool alpha)
for (auto &mesh : *m.meshes) {
if (alpha) {
if (!mesh.textureAlpha && !mesh.polyAlpha) {
continue;
}
}
else {
if (mesh.textureAlpha || mesh.polyAlpha) {
continue;
}
if (mesh.highPriority) {
hasOverlay = true;
}
if (!mesh.Render(alpha)) continue;
if (mesh.highPriority != renderOverlay) continue;
if (!matrixLoaded) {
glLoadMatrixf(m.modelMat);
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);
glDepthMask(GL_TRUE);
glDisable(GL_STENCIL_TEST);
return hasOverlay;
}
void CNew3D::RenderFrame(void)
@ -259,9 +260,24 @@ void CNew3D::RenderFrame(void)
m_r3dShader.SetShader(true);
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);
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
@ -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);
dotProd = V3::dotProduct(normal, r3dPoly.faceNormal);
clockWise = dotProd >= 0.0;
clockWise = dotProd >= 0;
if (clockWise) {
p.p1 = r3dPoly.v[0];
@ -930,6 +946,7 @@ void CNew3D::SetMeshValues(SortingMesh *currentMesh, PolyHeader &ph)
currentMesh->textureAlpha = ph.TextureAlpha();
currentMesh->polyAlpha = ph.PolyAlpha();
currentMesh->lighting = ph.LightEnabled() && !ph.FixedShading();
currentMesh->highPriority = ph.HighPriority();
if (ph.Layered() || (!ph.TexEnabled() && ph.PolyAlpha())) {
currentMesh->layered = true;

View file

@ -176,9 +176,9 @@ private:
void CopyVertexData(const R3DPoly& r3dPoly, std::vector<Poly>& polyArray);
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]);
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);
void DrawScrollFog();

View file

@ -381,8 +381,9 @@ UINT64 PolyHeader::Hash()
hash |= (UINT64)DoubleSided() << 33; // bits 33 double sided
hash |= (UINT64)AlphaTest() << 34; // bits 34 contour processing
hash |= (UINT64)PolyAlpha() << 35; // bits 35 poly alpha processing
hash |= (UINT64)TextureAlpha() << 36; // bits 35 texture alpha processing
hash |= (UINT64)MicroTexture() << 37; // bits 36 microtexture enable
hash |= (UINT64)TextureAlpha() << 36; // bits 36 texture alpha processing
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