Allow asymmetric projection matrices. Fixes a bunch of missing effects and bad camera angles in harley.

This commit is contained in:
Ian Curtis 2016-03-31 09:27:42 +00:00
parent c398cab1b1
commit 7e7847bc83

View file

@ -604,7 +604,6 @@ void CNew3D::RenderViewport(UINT32 addr, int pri)
int curPri; int curPri;
int vpX, vpY, vpWidth, vpHeight; int vpX, vpY, vpWidth, vpHeight;
int spotColorIdx; int spotColorIdx;
GLfloat vpTopAngle, vpBotAngle, fovYDegrees;
GLfloat scrollFog, scrollAtt; GLfloat scrollFog, scrollAtt;
Viewport* vp; Viewport* vp;
@ -642,32 +641,41 @@ void CNew3D::RenderViewport(UINT32 addr, int pri)
vp->priority = pri; vp->priority = pri;
// Fetch viewport parameters (TO-DO: would rounding make a difference?) // Fetch viewport parameters (TO-DO: would rounding make a difference?)
vpX = (vpnode[0x1A] & 0xFFFF) >> 4; // viewport X (12.4 fixed point) vpX = (int)(((vpnode[0x1A] & 0xFFFF) / 16.0f) + 0.5f); // viewport X (12.4 fixed point)
vpY = (vpnode[0x1A] >> 20) & 0xFFF; // viewport Y (12.4) vpY = (int)(((vpnode[0x1A] >> 16) / 16.0f) + 0.5f); // viewport Y (12.4)
vpWidth = (vpnode[0x14] & 0xFFFF) >> 2; // width (14.2) vpWidth = (int)(((vpnode[0x14] & 0xFFFF) / 4.0f) + 0.5f); // width (14.2)
vpHeight = (vpnode[0x14] >> 18) & 0x3FFF; // height (14.2) vpHeight = (int)(((vpnode[0x14] >> 16) / 4.0f) + 0.5f); // height (14.2)
matrixBase = vpnode[0x16] & 0xFFFFFF; // matrix base address matrixBase = vpnode[0x16] & 0xFFFFFF; // matrix base address
LODBlendTable* tableTest = (LODBlendTable*)TranslateCullingAddress(vpnode[0x17]); LODBlendTable* tableTest = (LODBlendTable*)TranslateCullingAddress(vpnode[0x17]);
// Field of view and clipping float angle_left = -atan2(*(float *)&vpnode[12], *(float *)&vpnode[13]);
vpTopAngle = (float)asin(*(float *)&vpnode[0x0E]); // FOV Y upper half-angle (radians) float angle_right = atan2(*(float *)&vpnode[16], -*(float *)&vpnode[17]);
vpBotAngle = (float)asin(*(float *)&vpnode[0x12]); // FOV Y lower half-angle float angle_top = atan2(*(float *)&vpnode[14], *(float *)&vpnode[15]);
fovYDegrees = (vpTopAngle + vpBotAngle)*(float)(180.0 / 3.14159265358979323846); float angle_bottom = -atan2(*(float *)&vpnode[18], -*(float *)&vpnode[19]);
// TO-DO: investigate clipping planes float near = 0.1f;
float far = 1e5;
float l = near * tanf(angle_left);
float r = near * tanf(angle_right);
float t = near * tanf(angle_top);
float b = near * tanf(angle_bottom);
// TO-DO: investigate clipping near/far planes
//if (g_Config.wideScreen && (vpX == 0) && (vpWidth >= 495) && (vpY == 0) && (vpHeight >= 383)) // only expand viewports that occupy whole screen
//if (0)
if ((vpX == 0) && (vpWidth >= 495) && (vpY == 0) && (vpHeight >= 383)) if ((vpX == 0) && (vpWidth >= 495) && (vpY == 0) && (vpHeight >= 383))
{ {
// Wide screen hack only modifies X axis and not the Y FOV float windowAR = (float)m_totalXRes / (float)m_totalYRes;
float originalAR = 496 / 384.f;
float correction = windowAR / originalAR; // expand horizontal frustum planes
vp->x = 0; vp->x = 0;
vp->y = m_yOffs + (GLint)((float)(384 - (vpY + vpHeight))*m_yRatio); vp->y = m_yOffs + (GLint)((float)(384 - (vpY + vpHeight))*m_yRatio);
vp->width = m_totalXRes; vp->width = m_totalXRes;
vp->height = (GLint)((float)vpHeight*m_yRatio); vp->height = (GLint)((float)vpHeight*m_yRatio);
vp->projectionMatrix.Perspective(fovYDegrees, (GLfloat)vp->width / (GLfloat)vp->height, 0.1f, 1e5); // use actual full screen ratio to get proper X FOV vp->projectionMatrix.Frustum(l*correction, r*correction, b, t, near, far);
} }
else else
{ {
@ -676,7 +684,7 @@ void CNew3D::RenderViewport(UINT32 addr, int pri)
vp->width = (GLint)((float)vpWidth*m_xRatio); vp->width = (GLint)((float)vpWidth*m_xRatio);
vp->height = (GLint)((float)vpHeight*m_yRatio); vp->height = (GLint)((float)vpHeight*m_yRatio);
vp->projectionMatrix.Perspective(fovYDegrees, (GLfloat)vpWidth / (GLfloat)vpHeight, 0.1f, 1e5); // use Model 3 viewport ratio vp->projectionMatrix.Frustum(l, r, b, t, near, far);
} }
// Lighting (note that sun vector points toward sun -- away from vertex) // Lighting (note that sun vector points toward sun -- away from vertex)