Optimized version with C++. Runs much faster.

This commit is contained in:
The Dust Council 2026-06-04 01:11:46 -07:00
parent 3fa044013a
commit 47730936de
6 changed files with 479 additions and 17 deletions

View file

@ -194,6 +194,9 @@ out over a few seconds. Press any key to bring it back.
| Mirror-ball count | `3` / `4` | How many reflecting mirror spheres are on screen (01000) |
| Shapes | `N` | Toggle random ⇄ cycling shape spawns |
| Fullscreen | `F` or `F11` | Toggle fullscreen |
| Perf HUD | `F1` | FPS / frame ms / body & draw-batch counts |
| VSync | `F2` | Toggle VSync (uncap the frame rate) |
| Glow mode | `F3` | Post-process bloom vs. legacy per-vector glow |
| Pause | `Space` | |
| Quit | `Esc` | |
@ -241,11 +244,36 @@ out over a few seconds. Press any key to bring it back.
(`spin = 4^(seed · variance)`), so changing it re-spreads every solid's
rotation rate instantly — `0` makes them all tumble alike, `100` gives a
very wide range.
- **CRT glow** wraps each sharp vector in a soft phosphor mist: many faint
additive width layers fade outward into a halo, and a few faint enlarged
ghost copies bloom that glow into a larger volume than the hardware line-width
cap (~10px) could reach on its own. The crisp core is drawn last so the vector
stays sharp; the glow setting scales the mist's spread and brightness.
- **CRT glow** wraps each sharp vector in a soft phosphor mist. Two
implementations, switchable live with `F3`:
- **Bloom (default, when framebuffer objects are available):** the field's
sharp cores are rendered once, then a dual-filter pyramid (downsample, then
tent-filter upsample accumulating each scale into the next finer one) builds
a smooth, ever-widening, fading halo around the vectors. A fold factor
attenuates the wider scales so the halo fades out and the blacks stay clean.
This is **one draw per body instead of nine**, dramatically faster at high
body counts.
- **Legacy:** each vector is redrawn as many faint additive width layers plus
a few enlarged ghost copies. Kept as a fallback for GPUs without FBOs.
- **Performance / retained mode.** Geometry is uploaded to vertex/index buffer
objects once and drawn with `glDrawElements` instead of per-vertex immediate
mode, so the CPU isn't re-submitting millions of vertices per frame. Rigid
shapes use static buffers; morphing 4/5/6-D polytopes stream positions into a
shared buffer with a static index buffer; clocks and animated objects (whose
topology is rebuilt each frame) stay on the immediate path. GL 1.5/3.0 entry
points are resolved at run time via `glfwGetProcAddress`, so the same code
works on the Linux, Windows, and screensaver builds; both retained mode and
bloom fall back gracefully if unavailable.
- **Frustum culling.** The field is a full sphere around the camera, so most
bodies are behind or beside the view. Six view-frustum planes are extracted
from the modelview·projection matrix each frame and each body's bounding
sphere is tested before the (relatively costly) projection and draw; the cull
margin includes the glow spread so edge halos don't pop. Off-screen bodies
still advance and recycle — only their drawing is skipped. At a full field
(~7200 bodies) this typically draws under ~1000 of them.
- The `F1` HUD shows FPS, frame time, and live body / drawn / draw-batch /
vertex counts; `F2` toggles VSync; `F3` switches bloom vs. legacy glow.
- **Magnifying glasses** are real lenses. After the field is drawn, the back
buffer is grabbed into a texture (`glCopyTexSubImage2D`); each lens body is
then projected to its screen position and drawn as a disc that samples that