Age | Commit message (Collapse) | Author |
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
--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.
|
|
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.
|
|
I was using SDL_CreateRGBSurfaceWithFormat() without considering the
minimum SDL2 version implications. Switch to SDL_CreateRGBSurface()
as there's no relevant difference, so I can lower the minimum SDL2
version in configure.ac.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
Purely cosmetic change renaming to
rtv_should_skip_module() since the function doesn't actually
skip anything, it just determines the skip.
|
|
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.
|
|
This adds three rtv settings:
duration, caption_duration, snow_duration
|
|
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.
|
|
These don't actually do anything yet
|
|
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.
|
|
This seems unnecessary and doesn't always read well in combination
with a given setting name string.
Just get rid of it for now.
|
|
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.
|
|
Using strlen on the input string isn't safe; it may be unterminated
|
|
Added a triangle wave
|
|
This builds minimally upon the existing sine wave code,
just use the sign to drive the signal high or low.
Wikipedia shows a third state for 0 values, but that's for a -1..+1
signal. I'm producing all 0-1 signals as it's more convenient for
this application, but it seems like it would be awkward to return
.5f for the 0 case. So 0 is being treated as just another positive
value; high.
|
|
Provides improved ergonomics when using the bulitin ops, and much
appreciated arity and type checking.
|
|
Added some rudimentary refcounting so sig_t's can be readily shared
by multiple sig_t's.
|
|
Seems broken, fix it correctly later.
|
|
off by one order of magnitude
|
|
map 0-1 inputs to their inverse 1-0
|
|
Rename inv->neg, preparation for a new sig_ops_inv for inverting
0..1 to 1..0
|
|
Included a little hack to defend against divide by zero, seems
reasonable given the intended use cases.
|
|
|
|
This is a specialized version of sig_ops_scale which assumes a
min..max range of -1..+1
nvidia register combiners docs describe this operation as "expand
normal", and they have several variants, but I don't want to go
too crazy here right now. Plain expand it is.
|
|
This assumes the input value is always 0-1, but may be used to produce
values in any signed range, mapped linearly to the input.
|
|
aka negation
|
|
The whole idea was to produce values 0-1, except of course
sig_ops_{mult,const} where one could deliberately get out of
these bounds.
Everything else should stay within 0-1 as it makes everything
much more composable.
|
|
Supply two sig_t *'s: a, b
|
|
Supply three sig_t *'s: value, min, max
|
|
Added a simple test exercising pow and round
|
|
The flexible array of void *'s would just align to a pointer,
which may not be safe for all members of whatever gets shoved in
here.
In an effort to make it more robust, make it an array of a junk
drawer union of types.
|
|
Comment was vestigial from ops_mult.c which ops_lerp.c was derived
from.
|
|
(Ab)uses rand_r by feeding ticks_ms as seedp for pseudo-random
numbers deterministically derived from ticks_ms.
|
|
|
|
Make sig_ops_t.destroy functions consistently after init, no
functional changes.
|
|
This takes three signals; a, b, and t
t controls the weight interpolating between a and b, they all key
off the same time ticks_ms.
|
|
Now hz can vary with time as well...
|
|
The simplest of signals: a constant value.
The immediate need for this is to convert ops_sin_ctxt_t.hz to
another sig_t enabling varying hz with time, while still being
able to have a fixed hz as well.
|
|
This adds a small framework of sorts for creating and composing signal
generators.
Two generators are implemented at this time; sig_ops_sin and sig_ops_mult
sig_ops_sin accepts a hz variable and will produce a sine wave of that
frequency.
sig_ops_mult accepts two sig_t generators and multiplies their outputs
Callers may construct their own sig_ops_t ops structs and supply them to
sig_new(), but it's expected that libs/sig will grow a collection of
commonly used generators which can then be used by simply passing their
sig_ops_$foo to sig_new().
See the test code at the bottom of libs/sig/sig.c for some contrived
sample usage. Note by composing multiple sig_ops_sin generators with
a sig_ops_mult generator, one can already easily construct a synth-like
LFO generator.
Some obvious todos are to add triangle/sawtooth/square wave generators.
More compositional generators may be interesting as well, like additive
and subtractive for example. Those will need to implement clipping, as
it's expected that the generators *always* stay within unity (0-1).
No modules use this yet, but I expect to wire this up to rtv for driving
knobs.
|
|
This is intended for modules to expose bindings for floats affecting
rendering output that may be varied at runtime frame-to-frame.
See the comment in knobs.h for more information.
This commit only introduces the concept, no modules utilize it yet.
|
|
Cosmetic change, put setup with the other function pointers.
|
|
Modulo ticks by 2*M_PI to preserve precision by constraining the float
to 2*M_PI radians.
|
|
Missed this!
|