* gg: pure-V sgl renderer (gg/render) with CPU rasterizer backend * gg: add per-corner rounded rect, 9-slice, CPU output equality test * gg: add multiply/screen blend modes to renderer and CPU rasterizer * gg: add multiply/screen to ImageEffect enum * gg: fix review defects in V renderer (font crash, api break, leaks) - text_rendering: add FonsRenderTarget allocated before fonsCreateInternal, since fontstash calls renderCreate synchronously; fixes invalid memory access crash on startup. renderUpdate now copies only the dirty atlas region. - draw: rewrite draw_rounded_rect_filled_4 as a single convex triangle strip (removes nonexistent begin_triangle_fan calls that broke compilation of any user of the new API, removes double-blend overlaps); add clamp_radius/clamp_slice helpers. - draw_9slice: remove dead slices array/loop, clamp dest slices proportionally, use clamped UVs. - render: do not create pipeline object 5 (quads reuse triangles pipeline, matching sgl); push_pipeline uses max_stack_depth-1; add is_image_registered/update_image_region/destroy. - image: register textures once per image; streaming updates refresh the CPU copy via update_image_region. - gg: call ctx.r.destroy() before gfx.shutdown(); drop unused gg.render imports; add .vv compile samples for the new APIs. - flush: pass [4]int dirty rect to validate_texture (was &int, heap overwrite causing delayed crash in begin()). * gg: migrate examples off sokol.sgl to ctx.r gg no longer submits an sgl context after the pure-V renderer migration, so direct sgl calls in gg examples either failed to typecheck (rotating_textured_quad passed render.Pipeline to sgl.load_pipeline) or silently recorded nothing. Route matrix, pipeline, texture and primitive calls through ctx.r instead. * x.ttf.render_sokol: draw through ctx.r instead of sgl draw_text_bmp took ctx &gg.Context but issued its matrix, pipeline, texture and quad calls to sokol.sgl. After the pure-V renderer migration gg no longer submits an sgl context, and the mixed types made the function (and every ttf_font example) fail to compile: cannot use render.Pipeline as sgl.Pipeline in argument 1 to sgl.load_pipeline. * gg: add a compile-test for all gg based examples Compiles every examples/gg program, plus breakout, viewer and both ttf_font examples, so examples that keep referencing sokol.sgl directly fail the suite instead of the renderer migration (render.Pipeline is not sgl.Pipeline) going unnoticed. The samples are compiled in parallel with VJOBS-style workers into a private vcache directory.
vviewer
Image viewer for V, built with gg/sokol and the pure-V decoders from
vlib/image/decoders. No
stbi/stb_image is involved: JPEG, PNG, BMP, WEBP, TIFF, and GIF bytes
are decoded by our own V code.
Build and run
From this directory:
v run . # run
v -prod . # optimized build
A C compiler is required (the sokol backend is C). The viewer renders through the standard sokol backend (OpenGL on Linux, D3D11 on Windows, Metal on macOS); no custom shader compilation is needed.
Usage
Command line — mix files, folders, and zip archives:
viewer img1.jpg img2.bmp folder1 folder2.zip
All folders and zips are scanned for images. You can also start the viewer with no arguments and drag and drop files, folders, or zips onto the window.
Accepted extensions: .jpg, .jpeg, .png, .bmp, .gif, .webp,
.tiff, and .zip archives containing them.
Controls
| Input | Action |
|---|---|
ESC / q |
Quit |
right / left |
Next / previous image |
up / down |
Next / previous folder |
F |
Toggle full screen |
R |
Rotate 90 degrees |
I |
Toggle info text |
P |
Pause / play animation |
H |
Toggle help |
1 / 2 / 3 |
Sort by name / date / as loaded |
| Mouse wheel | Next / previous image |
| Left mouse button (hold) | Pan |
| Right mouse button (hold) | Zoom |
| Middle mouse button | Reset view / fill window |
Animation players and their encoded input are released when switching images,
including builds with -gc none.
Limitations
- Animated GIF and animated WEBP are played back frame by frame. APNG files decode, but the viewer shows the static (first) frame only.
- Multi-page TIFF files show the first page only.
- 16-bit PNG and 12-bit JPEG are scaled down to 8-bit RGBA for display.
- Zip archives opened through the bundled miniz library cannot be opened directly from paths with non-ASCII characters on Windows; the viewer works around this by copying the archive to an ASCII-only temp file.
- The viewer displays images; it does not write or convert them. Use the decoder packages directly for that.