From 6efa03112e8828f11f2b831df00cc17c9c6c1e2b Mon Sep 17 00:00:00 2001 From: Ian Curtis Date: Mon, 8 Jan 2018 18:35:42 +0000 Subject: [PATCH] Rewrite projection maths based upon previously unknown viewport values. The previous values used roughly worked as the normals for frustum planes. Perhaps they were only used for culling and not actually rendering, as sometimes the values don't work correctly. --- Src/Graphics/New3D/New3D.cpp | 36 ++++++++++++++++++++---------------- VS2008/Supermodel.vcxproj | 4 ++-- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/Src/Graphics/New3D/New3D.cpp b/Src/Graphics/New3D/New3D.cpp index 9df0960..332fbc2 100644 --- a/Src/Graphics/New3D/New3D.cpp +++ b/Src/Graphics/New3D/New3D.cpp @@ -757,26 +757,30 @@ void CNew3D::RenderViewport(UINT32 addr) m_LODBlendTable = (LODBlendTable*)TranslateCullingAddress(vpnode[0x17] & 0xFFFFFF); - vp->angle_left = -atan2(*(float *)&vpnode[12], *(float *)&vpnode[13]); - vp->angle_right = atan2(*(float *)&vpnode[16], -*(float *)&vpnode[17]); - vp->angle_top = atan2(*(float *)&vpnode[14], *(float *)&vpnode[15]); - vp->angle_bottom = -atan2(*(float *)&vpnode[18], -*(float *)&vpnode[19]); + /* + vp->angle_left = -atan2(*(float *)&vpnode[12], *(float *)&vpnode[13]); // These values work out as the normals for the clipping planes. + vp->angle_right = atan2(*(float *)&vpnode[16], -*(float *)&vpnode[17]); // Sometimes these values (dirt devils,lost world) are totally wrong + vp->angle_top = atan2(*(float *)&vpnode[14], *(float *)&vpnode[15]); // and don't work for the frustum values exactly. + vp->angle_bottom = -atan2(*(float *)&vpnode[18], -*(float *)&vpnode[19]); // Perhaps they are just used for culling and not rendering. + */ - // I don't really know what these paramaters are for. They are derived from the view angles somehow. - // In the sdk it's they are someting like (1/tan(left)-tan(right)) * tan(left) - // But we know when left=right the value is always 0.5. Any other value and we have off-axis projection - // My theory is, the h/w is using these values to actually set the frustum planes angles - // The above vpnode[12], vpnode[13] actually work as a normal vector for the clipping planes (used for culling) - // I think in lost world and dirt devils, there is a missmatch between the computed plane normals, and the view angles - if (*(float *)&vpnode[0xa] == 0.5f) { - vp->angle_bottom = -vp->angle_top; - } + float cv = *(float *)&vpnode[0x8]; // 1/tan(left-right) + float cw = *(float *)&vpnode[0x9]; // 1/tan(top-bottom) + float io = *(float *)&vpnode[0xa]; // top / bottom (ratio) - ish + float jo = *(float *)&vpnode[0xb]; // left / right (ratio) - if (*(float *)&vpnode[0xb] == 0.5f) { - vp->angle_right = -vp->angle_left; - } + float left = (1.0f / cv) * (0.0f - jo); + float right = (1.0f / cv) * (1.0f - jo); + float bottom = (1.0f / cw) * (0.0f - io); + float top = (1.0f / cw) * (1.0f - io); + + vp->angle_left = std::atan(left); // probably could skip atan + vp->angle_right = std::atan(right); + vp->angle_bottom = std::atan(bottom); + vp->angle_top = std::atan(top); // calculate the frustum shape, near/far pair are dummy values + CalcViewport(vp, 1, 1000); // calculate frustum planes diff --git a/VS2008/Supermodel.vcxproj b/VS2008/Supermodel.vcxproj index 60347aa..09c9c34 100644 --- a/VS2008/Supermodel.vcxproj +++ b/VS2008/Supermodel.vcxproj @@ -93,7 +93,7 @@ Disabled ..\Src;..\Src\OSD;..\Src\OSD\SDL;..\Src\OSD\Windows;..\Libraries\zlib-1.2.4;..\Libraries\SDL-1.2.14\include;$(DXSDK_DIR)\Include;%(AdditionalIncludeDirectories) - SUPERMODEL_WIN32;INLINE=static __inline;_MBCS;_CRT_SECURE_NO_WARNINGS;GLEW_STATIC;NET_BOARD + SUPERMODEL_WIN32;INLINE=static __inline;_MBCS;_CRT_SECURE_NO_WARNINGS;GLEW_STATIC true EnableFastChecks MultiThreadedDebug @@ -157,7 +157,7 @@ xcopy /D /Y "$(ProjectDir)\SDL\$(Platform)\$(Configuration)\SDL.dll" "$(TargetDi Full false ..\Src;..\Src\OSD;..\Src\OSD\SDL;..\Src\OSD\Windows;..\Libraries\zlib-1.2.4;..\Libraries\SDL-1.2.14\include;$(DXSDK_DIR)\Include;%(AdditionalIncludeDirectories) - SUPERMODEL_WIN32;INLINE=static __inline;_MBCS;_CRT_SECURE_NO_WARNINGS;GLEW_STATIC;NET_BOARD + SUPERMODEL_WIN32;INLINE=static __inline;_MBCS;_CRT_SECURE_NO_WARNINGS;GLEW_STATIC MultiThreaded true