summaryrefslogtreecommitdiff
path: root/src/modules
AgeCommit message (Collapse)Author
2021-02-08modules/swarm: implement a particles swarm moduleVito Caputo
Just a fun little swarm based loosely on 80s-era boids It would be interesting to make stuff like the # of particles and the weights runtime configurable, or exposed as knobs. Using a Z-buffer for occlusions and perhaps shading by depth might make a significant improvement on the visual quality. It might also be interesting to draw the particles as lines connecting their current position with their previous, instead as pixels. Or fat pixels like stars...
2021-02-07modules/plasma: normalize plasma dimensionsVito Caputo
This is a quick and dirty jab at normalizing the plasma size to be independent of the frame size. I kind of hate this module as-is, it's tempting to discard all the fixed point stuff and just redo it using floats.. the plasma itself isn't that attractive as-is either. But I have other things to work on currently, just wanted to make it so the plasma doesn't look like a solid color in the montage tile.
2021-02-07modules/plasma: trivial cleanupsVito Caputo
- move LUT initialization to context create - minor syntactic changes
2021-01-18modules/drizzle: low-hanging fruit optimizationsVito Caputo
- switch puddle_sample() to 0..1 coordinates to avoid some pointless extra arithmetic on every pixel - avoid redundant ->w multiplies in puddle_sample() - avoid multiplies in inner loops of drizzle_render_fragment() by accumulating coordinates w/addition instead I noticed full-screen 'compose' was struggling to keep a full frame rate on my laptop when testing with the new 'plato' layer. valgrind profiles showed drizzle as the big hog, mostly the puddle_sample() function. These changes help but it's still not great, getting much better will likely become invasive and crufty. It would be nice to cache the vertical lerp results and reuse them across puddle_sample() calls when valid, that might be a useful TODO. The runner-up is spiro, prolly some low-hanging fruit there as well, I haven't looked yet.
2021-01-17compose: add plato to default layersVito Caputo
now: "drizzle:stars:spiro:plato"
2021-01-17plato: regular convex polyhedrons in 3DVito Caputo
plato implements very simple software-rendered 3D models of the five convex regular polyhedra / Platonic solids Some TODO items: - procedurally generate vertices at runtime - add hidden surface removal setting (Z-buffer?) - add flat shaded rendering setting - add gouraud shading, maybe phong too? - show dual polyhedra This was more about slapping together a minimal 3D wireframe software renderer than anything to do with polyhedra, convex regular polyhedra just seemed like an excellent substrate since they're so simple to model.
2020-09-26modules/compose: set default layersVito Caputo
In case some code path creates module contexts and renders without applying settings, it's important to ensure there are defaults. As-is this would have crashed compose because compose_layers would have been NULL, and compose_create_context() assumed compose_layers always contained something useful. Montage would have been an example of this, though for other reasons montage has had compose disabled so I don't think anything currently would have triggered this.
2020-09-26modules/montage: skip compose moduleVito Caputo
The threaded rendering backend isn't reentrant and compose could hypothetically have montage as a layer triggering infinite recursion. For now use a big hammer and block compose module from montage.
2020-09-26modules/montage: cleanup vestigial stars/pixbounce lookupsVito Caputo
Once upon a time montage had to skip stars and pixbouce because they crashed. That has since been corrected, but the commit which removed the skips didn't remove the lookups. This removes the leftover lookups.
2020-09-26modules/montage: pass 1 for num_cpus when creating contextsVito Caputo
This module needs some love, but it already always supplies 1 to the open-coded rendering for the tiles. It never should have been supplying the real num_cpus to module.create_context(), then only supplying 1 for rendering.
2020-09-25modules/compose: add a rudimentary compositing moduleVito Caputo
--module=compose,layers=first:second:third:... this draws the named modules in the order listed, overdrawing the output of the previous layers in a cumulative fashion.
2020-09-25fb: track zeroed state in fb_fragment_tVito Caputo
This adds a bit flag for tracking if the fragment has been zeroed since its last flip/present. When a fresh frame comes back from flipping, its zeroed state is reset to false. When fb_fragment_zero() is called, it checks if zeroed is true, and skips the zeroing if so. If zeroed is false, fb_fragment_zero() will zero the fragment and set the zeroed flag to 1. This change is preparatory for layering the output of modules in a compositing fashion. Not all modules are amenable to being used as upper layers, since they inherently fill the screen with new pixels every frame. Those modules make good bottom or bg layers. Other modules perform fb_fragment_zero() every frame and add relatively few pixels atop a clean slate. These modules make good candidates for upper layers where this change becomes relevant.
2020-09-13modules/rtv: implement snow_module settingVito Caputo
This takes a module name or "none", to use the specified module or do nothing during the channel switching snow_duration. The default is "snow" like before.
2020-09-12modules/rtv: implement context_duration settingVito Caputo
This renames rtv_channel_t to rtv_module_t and modules to channels in various places, which arguably should have been in a separate commit but I'm not up for separating that out at the moment. Fundamentally what's happening is every channel is getting its own context which may persist across channel switches, this allows watching a variety of channels in a stateful manner before they get their contexts recreated with re-randomized settings. For modules without settings it's not terribly interesting, and I'm thinking modules should probably start deriving some of their state more directly from the global ticks rather than their own per-context counters and timers. That way even when their contexts get recreated with re-randomized settings, there can be some continuity for ticks-derived state. Deriving position for instance mathematically from ticks would allow things to be located continuously despite having their contexts and even settings changed, which may be interesting. Anyhow, if you want the previous behavior where contexts are always recreated on channel switch, just set the value to be contxt_duration equal to duration.
2020-09-12modules/rtv: s/ticket/order/Vito Caputo
Ticket is unnecessarily abstract/opaque of a name for this, it's simply the sort order. No point making the reader grok whatever model I was thinking when I wrote it at the time, i.e. tickets at a butcher counter.
2020-09-12modules/spiro: use ticks instead of time() w/srandVito Caputo
time() only changes every second, so this had the effect of freezing the seed a second at a time, affecting all rand() users, when spiro's create_context() was called more frequently than 1HZ. When using rtv with channels=spiro,duration=0 the create_context() gets called every other frame, and the visual results were very broken with the spiro only actually reseeding every second and the snow between each frame being static since it too uses rand() for seeding itself. This whole situation suggests no module should be calling srand(), and instead rototiller should probably call srand() once at startup and any modules that wish to use rand with a different seed should use rand_r(), and maybe rand() just for acquiring the seed like modules/snow does.
2020-09-12modules/rtv: rename rtv_skip_module()Vito Caputo
Purely cosmetic change renaming to rtv_should_skip_module() since the function doesn't actually skip anything, it just determines the skip.
2020-09-11modules/rtv: make channels set configurableVito Caputo
This adds a colon-separated channels setting, with a setting of "all" for the existing all-modules behavior. Colon was used since comma is already taken by the settings separator, maybe in the future comma escaping can be added everywhere relevant but for now just keep it simple. The immediate value of this setting is telling rtv to limit itself to a single module, and using its setting randomizer to automatically observe a variety of the available settings in action on a specific module, especially during development. If knobs ever get added in the future I expect this will become even more interesting for watching specific modules under their various settings permutations in combination with their knobs being twisted - especially if rtv reconstructs random signal generator chains for the "knob-twisters" on every channel switch. An immediately interesting TODO complementing this particular change would be optionally preserving module contexts across channel switches, so when the same module is revisited it resumes where it was last seen. But this conflicts with settings changes on channel switching, since contexts should probably always be recreated when settings change - but that's probably a module-specific detail that modules should just be robust enough to tolerate as in they'd safely ignore settings changes without a context recreate, or apply them if they safely can without a context recreate... TODO.
2020-09-11modules/rtv: make durations configurableVito Caputo
This adds three rtv settings: duration, caption_duration, snow_duration
2020-09-11module/sparkler: implement some BSP drawing settingsVito Caputo
This commit adds a few settings for visualizing the octree BSP: show_bsp_leafs (on/off): Draw wireframe cubes around octree leaf nodes show_bsp_leafs_min_depth (0,4,6,8,10): Set minimum octree depth for leaf nodes displayed show_bsp_matches (on/off): Draw lines connecting BSP search matches show_bsp_matches_affected_only (on/off): Limit drawn BSP search matches to only matches actually affected by the simulation The code implementing this stuff is a bit crufty, fb_fragment_t had to be pulled down to the sim ops for example and whether that actually results in drawing occurring during the sim phase depends on the config used and how the particle implementations react to the config... it's just gross. This matters because the caller used to know only the draw phase touched fb_fragment_t, and because of that the fragment was zeroed after sim and before draw in parallel. But now the caller needs to know if the config would make sim do some drawing, and do the fragment zeroing before sim instead, and skip the zero before draw to not lose what sim drew. It's icky, but I'll leave it for now, at least it's isolated to the sparkler.
2020-09-11modules/sparkler: wire up particles_conf_t settingsVito Caputo
These don't actually do anything yet
2020-09-11modules/sparkler: add particles conf parameterVito Caputo
Just stubbed out for now, wanting to restore some octree overlays like the old standalone sparkler had. Those can be wired up to settings so rtv can occasionally show the spatial partition and matched particles.
2020-02-21modules/snow: use rand() on WIN32Vito Caputo
My current version of mingw in debian 9.11 doesn't seem to have rand_r(), so let's just use plain rand() and lose the improved parallelization on win builds.
2020-01-25modules/flui2d: derive r from ticksVito Caputo
Modulo ticks by 2*M_PI to preserve precision by constraining the float to 2*M_PI radians.
2020-01-25rototiller: introduce ticks and wire up to modulesVito Caputo
Most modules find themselves wanting some kind of "t" value increasing with time or frames rendered. It's common for them to create and maintain this variable locally, incrementing it with every frame rendered. It may be interesting to introduce a global notion of ticks since rototiller started, and have all modules derive their "t" value from this instead of having their own private versions of it. In future modules and general innovations it seems likely that playing with time, like jumping it forwards and backwards to achieve some visual effects, will be desirable. This isn't applicable to all modules, but for many their entire visible state is derived from their "t" value, making them entirely reversible. This commit doesn't change any modules functionally, it only adds the plumbing to pull a ticks value down to the modules from the core. A ticks offset has also been introduced in preparation for supporting dynamic shifting of the ticks value, though no API is added for doing so yet. It also seems likely an API will be needed for disabling the time-based ticks advancement, with functions for explicitly setting its value. If modules are created for incorporating external sequencers and music coordination, they will almost certainly need to manage the ticks value explicitly. When a sequencer jumps forwards/backwards in the creative process, the module glue responsible will need to keep ticks synchronized with the sequencer/editor tool. Before any of this can happen, we need ticks as a first-class core thing shared by all modules. Future commits will have to modify existing modules to use the ticks appropriately, replacing their bespoke variants.
2020-01-23stars: mess with the starfieldPhilip J Freeman
This commit adds some fun features to the starfield: - normalize aspect ratio to fragment size - rolling viewport - rotating viewport (with rate option)
2020-01-12libs/ray: decouple film and frame dimensionsVito Caputo
The existing code conflated the rendered frame dimensions with what's essentially the virtual camera's film dimensions. That resulted in a viewing frustum depending on the rendered frame dimensions. Smaller frames (like in the montage module) would show a smaller viewport into the same scene. Now the view into the scene always shows the same viewport in terms of the frustum dimensions for a given combination of focal_length and film_{width,height}. The rendered frame is essentially a sampling of the 2D plane (the virtual film) intersecting the frustum. Nothing is done to try enforce a specific aspect ratio or any such magic. The caller is expected to manage this for now, or just ignore it and let the output be stretched when the aspect ratio of the output doesn't match the virtual film's aspect ratio. In the future it might be interesting to support letter boxing or such things for preserving the film's aspect ratio. For now the ray module just lets things be stretched, with hard-coded film dimensions of something approximately consistent with the past viewport. The ray module could make some effort to fit the hard-coded film dimensions to the runtime aspect ratio for the frame to be rendered, tweaking things as needed but generally preserving the general hard-coded dimensions. Allowing the frustum to be minimally adjusted to fit the circumstances... that might also be worth shoving into libray. Something of a automatic fitting mode for the camera.
2020-01-08modules/flui2d: static-ify flui2d_setup()Vito Caputo
2020-01-08modules/drizzle: add a classic 2D raindrops visVito Caputo
Using the new puddle lib throw some raindrops on the framebuffer
2020-01-06rtv: rework randomized module selectionVito Caputo
Switch to working through the set of modules in a random order, randomizing the order once per cycle. This way no modules get starved for display, which was pretty common in the old method.
2020-01-06stars: fat starsPhilip J Freeman
draw stars as circles that get larger as the approach the camera
2020-01-06spiro: spirograph emulatorPhilip J Freeman
This commit adds a module that emulates a spirograph
2020-01-03montage: bump Y tiles when root has large fractionVito Caputo
Ideally the number of modules can tile without leaving gaps, but as rototiller evolves over time modules are added piecemeal so try accomodate those awkward layouts.
2019-12-30montage: re-enable stars and pixbouncePhilip J Freeman
2019-12-30pixbounce: fix bugs, refactor for resizingPhilip J Freeman
- fix bug for square fragments - use create and destroy context hooks instead of globals - refactor to allow fragment resizing - handle extremely small fragments gracefully
2019-12-30stars: fix bugs, big refactor for resizingPhilip J Freeman
- use a context not globals - use floats and a "unit cube" to simulate the starfield
2019-12-18modules/rtv: remove stale random settings commentVito Caputo
Since 7a77cc1a landed this is no longer true, the .random member will be used to support randomizing non multiple-choice settings.
2019-11-26montage: add (threaded) to descriptionVito Caputo
While the montage doesn't deeply thread the per-tile/module rendering, the per-frame rendering is threaded with a work unit granularity of every module's tile. Meaning every module renders its tile in a single thread, but the tiles are all rendered in parallel. For the most part this works, and will only work better as more modules are added to rototiller increasing the granularity. In the mean time it's a bit coarse and some modules can be a lot more costly to render than others, and there can be a shortage of modules to schedule on idle CPUs. It would be an interesting task to try make each module's tile get subfragmented elastically. I didn't make any attempt to do that, but it might even be worthwhile on hidpi screens where even those small tiles may have a whole lot of pixels, especially on manycore CPUs.
2019-11-25meta2d: add a classic 2D metaballs moduleVito Caputo
2019-11-25din: don't include v3f.h in din.hVito Caputo
This requires a forward declaration of v3f_t and changing din() to take a v3f_t *. The swab module needed updating to supply a pointer type and a v3f_t definition. This is being done so din.h users can have their own v3f implementations. I might consolidate all the duplicated vector code scattered throughout the libs and modules, but for now I'm carrying on with the original intention of having modules be largely self-contained. Though the introduction of libs like ray and din has certainly violated that a bit already.
2019-11-24snow: only create n_cpus fragmentsVito Caputo
Since snow_context_t needs another member anyways, stick n_cpus in there to inform the fragmenter of precisely how many fragments to make. This renderer doesn't benefit from tiling or any such locality, so it uses the slice fragmenter and really only benefits from as many fragments as there are CPUs. Any additional fragments is just wasted fragmenting overhead.
2019-11-24snow: per-cpu rand_r() seed stateVito Caputo
Snow was already threaded, but used a global seed with rand_r() meaning the CPUs were hammering on the same address. There wasn't any locking or atomics, as it isn't terribly critical when generating white noise if the seed access is racy. But the writes still caused cache lines to ping-pong. This commit gives a ~15.5% speedup in my measurements on an i7-2640M. Note without the padded union, using just an array of ints, zero gain is realized. I used a padding of 256 just to have some headroom, x86 is 64 but other CPUs vary, POWER9 is 128 for example.
2019-11-24montage: rework fragmenterVito Caputo
This repurposes the generic fb_fragment_tile_single() to better fit the montage use case. Partially covered areas are simply skipped, and tiles no longer need to be square. In determining the tile width and height, I'm just using the sqrt of the number of modules and dividing the frame width and height. But when the sqrt has a fraction, it's rounded up on the width divide and rounded down on the height divide. So the width gets the extra column of tiles, and the height just throws away the fraction. I think it's OK for now, until someone gets a bug up their ass and wants to avoid having vacant tiles in the bottom right corner when the number of modules doesn't cooperate. One problem with the just skipping partially covered areas is they don't get zeroed out - no fragment is ever generated for them. To fix that there will prolly have to be a fb_fragment_zero() of the frame @ prepare :(. I guess it wouldn't be the end of the world if the fragmenter itself zeroed out skipped regions. It's kind of an ugly layering violation but this is a private montage- specific fragmenter.
2019-11-24montage: rework module skippingVito Caputo
The old approach was just to get things working, it's preferable to not have empty tiles on-screen where modules were skipped and have all tiles be smaller to accomodate vacancies. Now the modules list gets pruned @ context create, so the skipping only happens once and everywhere else is looking at a modules list and count of only the keepers. I also added stars to the skipped modules, for now, since both stars and pixbounce malfunction when the fragment size changes.
2019-11-24montage: zero skipped fragmentsVito Caputo
Not doing this produces especially visible artifacts when shown by rtv.
2019-11-24montage: skip pixbounceVito Caputo
Segfaults were observed when montage came up in rtv, since pixbounce doesn't seem to be rendering properly at all just skip it for now. I suspect what's happening is rtv ran pixbounce before running montage, and pixbounce caches fragment knowledge @ initialization. So when montage ran pixbounce in a tile, that stale fragment knowledge was used and caused scribbling. Stars probably has similar problems actually.
2019-11-24montage: add montage moduleVito Caputo
This is somewhat unfinished as it uses the generic tiled fragmenter that's not interested in appearances but prioritizes total coverage and simplicity. Montage should have its own tiler that can produce non-square and even non-uniform tile dimensions, prioritizing filling the screen with mostly-uniform tiles. But that's a TODO item, this is good enough for now and exercises some fragment details previously irrelevant and often ignored/broken in modules. The pixbounce module in particular seems completely broken with small fragment sizes.
2019-11-24rototiller: rototiller_fragmenter_t s/num/number/Vito Caputo
Mechanical change removing abbreviation for consistency
2019-11-23rototiller: pass cpu to .render_fragment()Vito Caputo
Mostly mechanical change, though threads.c needed some jiggering to make the logical cpu id available to the worker threads. Now render_fragment() can easily addresss per-cpu data created by create_context().
2019-11-23rototiller: pass num_cpus to .create_context()Vito Caputo
Back in the day, there was no {create,destroy}_context(), so passing num_cpus to just prepare_frame made sense. Modules then would implicitly initialize themselves on the first prepare_frame() call using a static initialized variable. Since then things have been decomposed a bit for more sophisticated (and cleaner) modules. It can be necessary to allocate per-cpu data structures and the natural place to do that is @ create_context(). So this commit wires that up. A later commit will probably have to plumb a "current cpu" identifier into the render_fragment() function. Because a per-cpu data structure isn't particularly useful if you can't easily address it from within your execution context.
© All Rights Reserved