Effect Basics - AlbertGBarber/PixelSpork GitHub Wiki

Jump To:

Creating Effects:

In Pixel Spork, every effect is contained in its own class. To create an instance of an effect, you call its constructor.

For example, to create an instance of the Rainbow Cycle effect you would write:

RainbowCyclePS rainbowCycle(mainSegments, 30, true, 80); 

The first part of this statement, RainbowCyclePS, is the effect class name/type, while the second, rainbowCycle, is the name of your instance of the effect. The instance name can be anything you like. The arguments in brackets, (mainSegments, 30, true, 80), specify the constructor settings for the effect, including what Segment Set it will be drawn on (more on that below), how quickly the effect updates, and many others. The number and types of arguments correspond to one of the effect's constructors (effects can have multiple constructors with different sets of options for different situations).

Note that effects often have additional settings that are not included in the constructors, generally because they are not super important for creating the effect. These settings will always have default values (you don't need to set them for the effect to run!), but if you want to change them you'll have to do it after construction (see "Changing Effect Settings" below).

You can have as many instances of an effect as you like (as long as you have enough memory). They would all be unique from one another, having their own settings, and being updated and drawn independently. For example, you could have two RainbowCyclePS effects, called rainbow1 and rainbow2, that draw on different segment sets. Both effects operate independently, having no attachment to one another.

In the example above, we were using this constructor from Rainbow Cycle:

RainbowCyclePS(SegmentSetPS &SegSet, uint16_t Length, bool Direct, uint16_t Rate);

You can match up the arguments with those in the example above, so our rainbowCycle will be drawn on mainSegments, the rainbows will be length 30, move in the "true" (positive) direction (direct), with an update rate of 80ms.

Each effect has its own dedicated wiki page that explains the effect and its settings in detail. It also include pre-filled constructor examples to help get you started.

Note that there is an alternative way to create effects involving pointers, which is handy when managing multiple or temporary effects. This method is best explained in the Effects Advanced.

Segment Sets and Effects:

Before going further, it's important to understand that every effect is drawn on a specific Segment Set. The segment set is always supplied as an argument in the effect constructor (usually as the first argument), and provides the led configuration that tells the effect where to draw. Think of the segment set as a blank canvas, and the effect, the paint. You need both paint and a canvas to make a painting, and both contribute to how the end painting looks.

The effect's segment set will be bound to the effect's segSet pointer. Should you need to, you can access or change the effect's segment set like:

//Set a hypothetical variable "aVar" equal to a property of you effect's Segment Set 
aVar =  yourEffect.segSet->someSegmentSetProperty;

//Change the Segment Set your effect is using
//(note that you may need to reset() an effect if you change its segment set, check the effect's wiki page!)
yourEffect.segSet = &newSegmentSet;

Updating and Drawing Effects:

All effects have an update() function, that updates and draws the effect.

Using the above example, to update our rainbowCycle, we would call:

rainbowCycle.update();

Note that the effect updates at it's update rate (80ms in our example). This means that whenever we call update() the effect checks if 80ms have passed since the previous update. If so, then the effect updates and re-draws itself, if not, then the update is skipped.

There are some additional tricks when working with multiple effects, read about them on the Effects Advanced page.

Changing Effect Settings:

Changing effect variables is similar to calling the update() above. Using rainbowCycle as an example again. To change the effect's direction, we would do:

rainbowCycle.direct = false;

Note that not all effect settings can be changed directly, some may require a function call, such as changing the length of our rainbowCycle:

rainbowCycle.setLength(50);

This changes the length of the rainbows to 50. Functions are usually needed when multiple variables need to be changed at once, often behind the scenes. These functions and settings are specified on the effect's wiki page.

Finally, some settings are stored as pointers. This is a more advanced subject, which is best explained on the pointers page.

Common Variables:

While each effect's wiki page specifies all its settings, there are some variables that are common to most effects. Rather than explain them on every wiki page, I have grouped them together here. Familiarizing yourself with these variables may help you understand effects more quickly.

Effect Naming Conventions:

Effects will be tagged with either Seg Line, Seg, or nothing at all in the wiki right-sidebar. These tags tell you a glance how if the effect is "2D" and how it will be drawn:

  • No Tag -- Means the effect is 1D only, operating on each pixel individually. In code, these effects will have a "PS" at the end of their name, ie FireworksPS.

  • Seg Line -- Means that the effect is "2D" and will be drawn on whole segment lines, treating each line as an individual pixel or independent line (for effects like Fire2012 (Seg Line). In code, effects using segment lines will have "SL" at the end of their name, ie TwinkleSL.

  • Seg -- Like Seg Line, but treating each entire segment as a single pixel or independent line (for effects like Rain (Seg) or Fire2012 (Seg)). In code, effects using segments will have "Seg" at the end, ie RainSeg.

  • Multiple Tags -- Means the effect can be configured to use Segments, Segment Lines, or (possibly) be 1D, usually via a segMode setting. In code, these effects will have multiple tags at the end, ie RainbowCycleSLSeg.

See Segment Sets of info on segment lines, etc.

Note that it's possible to have a segment line based effect draw on whole segments by creating "single" segments, as explained in Advanced Segment Usage.

For most effects, it's safe to change the segment set after the effect has been created, although in a few cases it may require calling one of the effect's functions (this will be noted on the effect's wiki page).

"Fast" Effects:

There are a number of effects that have "fast" included in their name. These effects will always be paired with a non-fast version. ie, Gradient Cycle and Gradient Cycle Fast. The "fast" version of the effect is designed to run faster and/or use less memory that the non-fast version, but has more restraints or fewer options than the non-fast version. Major differences should be called out on the effect's wiki page.