Frame the Winners Circle for the shape it was built for
The stand was composed to be looked at from a 4:3 pod monitor. On a 16:9 canvas its platform runs out at the sides and the shot fills up with sky and void, so the podium is now pillarboxed: the scene renders into a centred 4:3 viewport with the surround left black. The projection has to use the cropped shape too, or the scene comes out squashed into the narrower viewport instead of cropped by it. RP412PODIUMASPECT overrides the ratio, 0 turns it off. The camera also came in closer, from 33 units rather than 45, and now aims slightly below the group rather than above it. That tilt is what buys back the sky above the grandstand - aiming above the group tips the camera up instead and walks the winner's spot off the bottom of the frame, which is the one position that has to be in shot. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+66
-1
@@ -1802,6 +1802,7 @@ DPLRenderer::DPLRenderer(
|
||||
// the next race re-reads viewangle from RPDPL.INI.
|
||||
mPresentationCamera = False;
|
||||
mPresentationFog = False;
|
||||
mPresentationAspect = 0.0f;
|
||||
D3DXMatrixIdentity(&mPresentationView);
|
||||
dplMainView = NULL;
|
||||
dplDeathZone = NULL;
|
||||
@@ -2374,6 +2375,20 @@ void
|
||||
// tells the end-of-mission fade to stand down
|
||||
mPresentationFog = True;
|
||||
|
||||
//
|
||||
// Crop to the shape the stand was composed for. 4:3 unless
|
||||
// RP412PODIUMASPECT says otherwise; 0 turns it off and lets
|
||||
// the podium run full width.
|
||||
//
|
||||
mPresentationAspect = 4.0f / 3.0f;
|
||||
{
|
||||
const char *aspect = getenv("RP412PODIUMASPECT");
|
||||
if (aspect != NULL)
|
||||
{
|
||||
mPresentationAspect = (float) atof(aspect);
|
||||
}
|
||||
}
|
||||
|
||||
// unconditional: fogUpdating is off while a vehicle drives its own
|
||||
// headlight fog, and the podium overrides all of that
|
||||
if (mDevice != NULL)
|
||||
@@ -6094,6 +6109,36 @@ void DPLRenderer::ExecuteImplementation(RendererComplexity, RendererOrigin::Inte
|
||||
lastFrameTime = mTargetRenderTime;
|
||||
currentFrameTime = Now();
|
||||
|
||||
//
|
||||
// Pillarbox: black the whole target first, then narrow the viewport so
|
||||
// everything after this - clear, scene, reticle - lands inside the crop
|
||||
// and the surround stays black. Restored after Present.
|
||||
//
|
||||
if (mPresentationAspect > 0.0f)
|
||||
{
|
||||
D3DVIEWPORT9 full;
|
||||
full.X = 0;
|
||||
full.Y = 0;
|
||||
full.Width = mPresentParams.BackBufferWidth;
|
||||
full.Height = mPresentParams.BackBufferHeight;
|
||||
full.MinZ = 0.0f;
|
||||
full.MaxZ = 1.0f;
|
||||
mDevice->SetViewport(&full);
|
||||
mDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
|
||||
|
||||
DWORD cropped = (DWORD)
|
||||
(mPresentParams.BackBufferHeight * mPresentationAspect);
|
||||
if (cropped > mPresentParams.BackBufferWidth)
|
||||
{
|
||||
cropped = mPresentParams.BackBufferWidth;
|
||||
}
|
||||
|
||||
D3DVIEWPORT9 crop = full;
|
||||
crop.Width = cropped;
|
||||
crop.X = (mPresentParams.BackBufferWidth - cropped) / 2;
|
||||
mDevice->SetViewport(&crop);
|
||||
}
|
||||
|
||||
DWORD currentFog;
|
||||
mDevice->GetRenderState(D3DRS_FOGCOLOR, ¤tFog);
|
||||
hr = mDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, currentFog, 1.0f, 0);
|
||||
@@ -6253,6 +6298,19 @@ void DPLRenderer::ExecuteImplementation(RendererComplexity, RendererOrigin::Inte
|
||||
|
||||
hr = mDevice->Present(NULL, NULL, gMainPresentWindow, NULL);
|
||||
|
||||
// hand the whole target back
|
||||
if (mPresentationAspect > 0.0f)
|
||||
{
|
||||
D3DVIEWPORT9 full;
|
||||
full.X = 0;
|
||||
full.Y = 0;
|
||||
full.Width = mPresentParams.BackBufferWidth;
|
||||
full.Height = mPresentParams.BackBufferHeight;
|
||||
full.MinZ = 0.0f;
|
||||
full.MaxZ = 1.0f;
|
||||
mDevice->SetViewport(&full);
|
||||
}
|
||||
|
||||
//
|
||||
// RP412RENDERDIAG=1: did the ending frame actually reach the window, and
|
||||
// what colour did it clear to? A black clear with a blue-violet fog set
|
||||
@@ -6889,11 +6947,18 @@ void DPLRenderer::SetViewAngle(Degree new_angle)
|
||||
viewRatio = (float) tan(view_angle / 2.0f);
|
||||
aspectRatio = (float) y_size / (float) x_size;
|
||||
|
||||
// pillarboxed shots render into a narrower viewport, so the projection
|
||||
// has to use that shape or the scene comes out squashed rather than
|
||||
// cropped
|
||||
float projection_aspect = (mPresentationAspect > 0.0f)
|
||||
? mPresentationAspect
|
||||
: ((float) x_size / (float) y_size);
|
||||
|
||||
D3DXMatrixIdentity(&mProjectionMatrix);
|
||||
D3DXMatrixPerspectiveFovLH(
|
||||
&mProjectionMatrix,
|
||||
viewAngle * (PI / 180.0f),
|
||||
(float) x_size / (float) y_size,
|
||||
projection_aspect,
|
||||
clipNear,
|
||||
clipFar);
|
||||
mProjectionMatrix(0, 0) *= -1; // handedness flip - the view is RH
|
||||
|
||||
Reference in New Issue
Block a user