Skip to content

Camera: draw the letterbox bars again, through the 2D batch - #29

Merged
ivan-ushakov merged 1 commit into
crossplatformfrom
feature/letterbox-black-bars
Jul 27, 2026
Merged

Camera: draw the letterbox bars again, through the 2D batch#29
ivan-ushakov merged 1 commit into
crossplatformfrom
feature/letterbox-black-bars

Conversation

@ivan-ushakov

Copy link
Copy Markdown
Collaborator

No description provided.

CameraManager::drawBlackBars opened with

	if(!gb_RenderDevice3D) // world 3D render not ported to SDL backend yet (slice 3)
		return;

and nothing has assigned gb_RenderDevice3D since the D3D9 retirement, so the bars
have been dead on every platform, Windows included. The comment was stale twice
over: the world 3D render has long since landed, and what actually held this back
was the dynamic vertex buffer family (Render-PORTING.md #15) -- GetBufferXYZWD()
returns nullptr on cSDLRenderDevice, and cVertexBufferInternal::Lock/Unlock/
DrawPrimitive are empty bodies in RenderStub.cpp. Dropping the guard on its own
would have turned a silent no-op into a null dereference.

But the bars never needed a dynamic buffer of their own. The original hand-rolled
SetNoMaterial + GetBufferXYZWD() + PT_TRIANGLELIST is exactly what
cD3DRender::DrawRectangle queued into `rectangles` and FlushFilledRect emptied at
EndScene -- same buffer, same primitive, same vertex format. So the port is four
DrawRectangle calls, which cSDLRenderDevice already forwards to the UI batch.
This is the third time #15 has looked like a blocker and turned out not to be;
the register's own warning applies.

Going through DrawRectangle drops the state dance with it. The six
Get/SetRenderState calls existed to turn off depth test, alpha test and blending
and put them back; the 2D pipeline has none of them to turn off. SetNoMaterial
goes too -- DrawRectangle passes a null texture, and the UI renderer binds its 1x1
white, so the vertex colour comes through unmodulated. That leaves this file with
no D3D names at all, so the Render/D3D/D3DRender.h include goes as well.

Two deliberate divergences, both commented at the call site:

Opacity now works. D3D drew the bars with D3DRS_ALPHABLENDENABLE FALSE, so the
alpha in Color4c(0,0,0, opacity*255) never reached the blender and the bars were
solid black whatever was passed. The 2D pipeline blends. The only caller
(GameShell.cpp) takes the default 1.0f, so shipped content is unchanged; the
parameter just stops being a lie.

DrawRectangle is integer and the rects are not, so they expand to the enclosing
integer rect rather than truncating. The four rects are laid out such that this
pushes every inner edge outward. A bar can now overshoot the work area by a pixel,
which is invisible; truncating could leave a 1px lit seam of scene along the inner
edge, which is not.

Only visible below 4:3 -- drawBlackBars returns early above it, and there the bars
are zero-sized anyway. Of the shipped resolutions, 1280x1024, 1024x800 and 720x576
qualify; at 1280x1024 the work area is 1280x960 centred, giving a 32px bar top and
bottom. Not visually verified: invisible at any widescreen setting.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ivan-ushakov
ivan-ushakov merged commit ca5efc2 into crossplatform Jul 27, 2026
4 checks passed
@ivan-ushakov
ivan-ushakov deleted the feature/letterbox-black-bars branch July 27, 2026 17:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant