fix(graphics): y-flip render-target composite + skip depth load/store
David flagged the cinder integration showed the scene upside-down. sokol_gfx writes to offscreen render-target memory in OpenGL native bottom-up convention, so the texture, when sampled with default top-down UV, appears vertically mirrored on the swap chain.
draw-render-target now sources from src=(0, height, width, -height) so the texcoord V range is inverted on sample — scene is upright when composited. Inside with-render-target, user coordinates remain top-left-origin (matching the swap-chain convention), so user code isn't affected.
Also drops the per-frame depth-stencil clear: loadaction and storeaction both DONTCARE. The depth attachment exists only because sgp's pipeline validation requires the pass and pipeline depth formats to match; 2D rendering never reads or writes it, so loading and storing it is wasted work.
Note: render-target->texture (Phase 2 consumer path) returns a borrowed wrapper whose memory is still in GL bottom-up layout — custom shaders that sample it directly should flip V themselves (or use draw-render-target which handles the flip). Will be documented + smoke-tested in Phase 2.
src/c/graphics.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)src/c/graphics.cmodified
sgp_viewport(0, 0, rt->width, rt->height); sgp_project(0, (float)rt->width, 0, (float)rt->height); /* Color: clear to transparent black on entry, keep contents on exit * (the swap-chain composite reads it). Depth: don't load, don't * store — the depth attachment exists only to satisfy sgp's * pipeline-validation requirement that pass and pipeline depth * formats match; 2D rendering never reads or writes it. */ sg_pass_action act = { .colors[0] = { .load_action = SG_LOADACTION_CLEAR, .clear_value = {0.0f, 0.0f, 0.0f, 0.0f}, }, .depth = { .load_action = SG_LOADACTION_CLEAR, .load_action = SG_LOADACTION_DONTCARE, .store_action = SG_STOREACTION_DONTCARE, .clear_value = 1.0f, }, }; sg_pass pass = { sgp_set_view(0, rt->tex_view); sgp_set_sampler(0, rt->sampler); /* Flip V on sample: sokol_gfx framebuffers write to texture memory in * GL bottom-up convention even on top-down backends, so a render * target sampled with the default top-down UV looks vertically * mirrored on the swap chain. Sourcing from y=height with h=-height * inverts the texcoord range so the composite is upright. */ sgp_rect dest = {x, y, w, h}; sgp_rect src = {0, 0, (float)rt->width, (float)rt->height}; sgp_rect src = {0, (float)rt->height, (float)rt->width, -(float)rt->height}; sgp_draw_textured_rect(0, dest, src); sgp_reset_view(0);