Fix the default 2d projection halving draws on 2x displays after a resize - #607
Conversation
… a resize cf_make_draw builds the default projection from the window size in points, but the canvas-recreation hook rebuilt it from the canvas's pixel size (window * pixel_scale). On a Retina-class display the first resize doubled the projection extent and every 2d draw rendered at half size from then on. 1x machines never saw it. The hook now reads app->w/h (points) like startup does, refreshes the mvp under the current camera the way cf_draw_projection does so a mid-frame cf_app_set_size takes effect immediately, and re-derives the AA factor since pixel_scale may be what changed. A test forces pixel_scale to 2 on an owned app so 1x CI exercises the 2x path, and checks cf_screen_to_world / cf_world_to_screen against the point-space extents. Docs: cf_make_app and cf_app_set_size sizes are points (a pixel unless the OS clusters pixels); cf_app_get_display_scale is the OS UI-scale hint CF reports but never applies.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 146e4c7e1b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| s_draw->projection = ortho_2d(0, 0, (float)app->w, (float)app->h); | ||
| CF_MUL_M32_M32(s_draw->mvp, s_draw->projection, s_draw->cam_stack.last()); |
There was a problem hiding this comment.
Refresh saved default projections when resizing
When cf_app_set_size recreates the canvas inside a cf_draw_push scope, this updates only the active projection while projection_stack still contains the pre-resize projection. The newly added test validates the transform before cf_draw_pop, but that pop immediately restores the old dimensions; subsequent drawing, including later frames because reset_cam() preserves the projection, is scaled using the stale window size until another recreation. Update the saved default projection state as part of the resize, or otherwise prevent the pop from undoing this refresh.
Useful? React with 👍 / 👎.
…a resize cf_app_set_canvas_size(w, h) now rebuilds the default projection to span w by h: a retro 320x180 target draws in its own pixels with no cf_draw_projection call, which is what such apps already relied on when the hook was built from the canvas. The automatic recreation path keeps passing the window size in points. Codex's catch on #607: a resize from inside a cf_draw_push scope updated only the active projection, and the pop restored the stale pre-resize one for every later frame. The hook now tracks the default projection it last set and swaps the new one into any saved copies of it, leaving a user's own saved projection alone. Tests cover both.
The startup projection spans the window in points, but the canvas-recreation hook rebuilt it from the canvas's pixel size (
window * pixel_scale). On a 2x display the first resize doubled the projection extent and every 2d draw rendered at half size from then on. This is the regression #575 and #579 set out to fix.The fix is the hook reading
app->w/h(points), plus refreshing the mvp under the current camera (mirroringcf_draw_projection) so a mid-framecf_app_set_sizelands immediately, and re-deriving the AA factor sincepixel_scalemay be what changed.No API changes. The model stays: window sizes in points, canvas auto-recreated at
points * pixel_scale, projection automatic,cf_app_get_pixel_scaleread-only. Docs updated to say so, and to state thatcf_app_get_display_scaleis the OS UI-scale hint CF reports but never applies.Test: forces
pixel_scale = 2on an owned app so 1x CI walks the 2x path, and checkscf_screen_to_world/cf_world_to_screenagainst point-space extents. Verified it fails with the old hook and passes with the new one. Full suite: 362/362 on Windows.