/* Sketch to show how a Sprite can use a four-bit image with a palette to change the appearance of an image while rendering it only once. Example for library: https://github.com/Bodmer/TFT_eSPI A Sprite is notionally an invisible graphics screen that is kept in the processors RAM. Graphics can be drawn into the Sprite just as it can be drawn directly to the screen. Once the Sprite is completed it can be plotted onto the screen in any position. If there is sufficient RAM then the Sprite can be the same size as the screen and used as a frame buffer. A 16 bit Sprite occupies (2 * width * height) bytes in RAM. On a ESP8266 Sprite sizes up to 126 x 160 can be accommodated, this size requires 40kBytes of RAM for a 16 bit color depth. When 8 bit color depth sprites are created they occupy (width * height) bytes in RAM, so larger sprites can be created, or the RAM required is halved. */ // Set delay after plotting the sprite #define DELAY 30 // Width and height of sprite #define WIDTH 164 #define HEIGHT 164 #include "sample_images.h" TFT_eSPI tft = TFT_eSPI(); // Declare object "tft" TFT_eSprite spr = TFT_eSprite(&tft); // Declare Sprite object "spr" with pointer to "tft" object byte red = 31; // Red is the top 5 bits of a 16 bit colour value byte green = 0;// Green is the middle 6 bits byte blue = 0; // Blue is the bottom 5 bits byte state = 0; int rloop = 0; int incr = 1; uint16_t cmap[16]; void setup() { Serial.begin(9600); Serial.println(); delay(50); // Initialise the TFT registers tft.init(); spr.setColorDepth(4); // Create a sprite of defined size spr.createSprite(WIDTH, HEIGHT); // Clear the TFT screen to black tft.fillScreen(TFT_BLACK); // push the image - only need to do this once. spr.pushImage(2, 2, 160, 160, (uint16_t *)stars); for (int i = 0; i < 16; i++) cmap[i] = rainbow(); } void loop(void) { // create a palette with the defined colors and push it. spr.createPalette(cmap, 16); spr.pushSprite(tft.width() / 2 - WIDTH / 2, tft.height() / 2 - HEIGHT / 2); // update the colors for (int i = 0; i < 15; i++) { cmap[i] = cmap[i + 1]; } if (incr == 2) { (void)rainbow(); // skip alternate steps to go faster } cmap[15] = rainbow(); rloop += incr; if (rloop > 0xc0) { incr = incr == 2 ? 1 : 2; rloop = 0; } delay(DELAY); } // ######################################################################### // Return a 16 bit rainbow colour // ######################################################################### unsigned int rainbow() { switch (state) { case 0: green ++; if (green == 64) { green = 63; state = 1; } break; case 1: red--; if (red == 255) { red = 0; state = 2; } break; case 2: blue ++; if (blue == 32) { blue = 31; state = 3; } break; case 3: green --; if (green == 255) { green = 0; state = 4; } break; case 4: red ++; if (red == 32) { red = 31; state = 5; } break; case 5: blue --; if (blue == 255) { blue = 0; state = 0; } break; } return red << 11 | green << 5 | blue; }