195 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			195 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|   This tests the alpha blending function that is used with the antialiased
 | |
|   fonts:
 | |
| 
 | |
|   Alpha = 0 = 100% background, alpha = 255 = 100% foreground colour
 | |
| 
 | |
|   blendedColor = tft.alphaBlend(alpha, fg_color, bg_color);
 | |
| 
 | |
|   The alphaBlend() function operates on 16 bit colours only
 | |
|   A test is included where the colours are mapped to 8 bits after blending
 | |
| 
 | |
|   Information on alpha blending is here
 | |
|   https://en.wikipedia.org/wiki/Alpha_compositing
 | |
|   
 | |
|   Example for library:
 | |
|   https://github.com/Bodmer/TFT_eSPI
 | |
| 
 | |
|   The sketch has been tested on a 320x240 ILI9341 based TFT, it
 | |
|   could be adapted for other screen sizes.
 | |
| 
 | |
|   Created by Bodmer 10/2/18
 | |
| 
 | |
|   #########################################################################
 | |
|   ###### DON'T FORGET TO UPDATE THE User_Setup.h FILE IN THE LIBRARY ######
 | |
|   #########################################################################
 | |
| */
 | |
| 
 | |
| #include <TFT_eSPI.h>       // Include the graphics library
 | |
| 
 | |
| TFT_eSPI tft = TFT_eSPI();  // Create object "tft"
 | |
| 
 | |
| // -------------------------------------------------------------------------
 | |
| // Setup
 | |
| // -------------------------------------------------------------------------
 | |
| void setup(void) {
 | |
|   tft.init();
 | |
|   tft.setRotation(0);
 | |
|   tft.fillScreen(TFT_DARKGREY);
 | |
| }
 | |
| 
 | |
| // -------------------------------------------------------------------------
 | |
| // Main loop
 | |
| // -------------------------------------------------------------------------
 | |
| void loop()
 | |
| {
 | |
|   // 16 bit colours  (5 bits red, 6 bits green, 5 bits blue)
 | |
|   // Blend from white to full spectrum
 | |
|   for (int a = 0; a < 256; a+=2) // Alpha 0 = 100% background, alpha 255 = 100% foreground
 | |
|   {
 | |
|     for (int c = 0; c < 192; c++) tft.drawPixel(c, a/2, tft.alphaBlend(a, rainbow(c), TFT_WHITE));
 | |
|   }
 | |
| 
 | |
|   // Blend from full spectrum to black
 | |
|   for (int a = 255; a > 2; a-=2)
 | |
|   {
 | |
|     for (int c = 0; c < 192; c++) tft.drawPixel(c, 128 + (255-a)/2, tft.alphaBlend(a, rainbow(c), TFT_BLACK));
 | |
|   }
 | |
| 
 | |
|   // Blend from white to black (32 grey levels)
 | |
|   for (uint16_t a = 0; a < 255; a++) // Alpha 0 = 100% background, alpha 255 = 100% foreground
 | |
|   {
 | |
|     tft.drawFastHLine(192, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_WHITE));
 | |
|     tft.drawFastHLine(204, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_RED));
 | |
|     tft.drawFastHLine(216, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_GREEN));
 | |
|     tft.drawFastHLine(228, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_BLUE));
 | |
|   }
 | |
| 
 | |
|   delay(4000);
 | |
| 
 | |
|   // Blend from white to colour (32 grey levels)
 | |
|   for (uint16_t a = 0; a < 255; a++) // Alpha 0 = 100% background, alpha 255 = 100% foreground
 | |
|   {
 | |
|     //tft.drawFastHLine(192, a, 12, tft.alphaBlend(a, TFT_BLACK, TFT_WHITE));
 | |
|     tft.drawFastHLine(204, a, 12, tft.alphaBlend(a, TFT_RED,   TFT_WHITE));
 | |
|     tft.drawFastHLine(216, a, 12, tft.alphaBlend(a, TFT_GREEN, TFT_WHITE));
 | |
|     tft.drawFastHLine(228, a, 12, tft.alphaBlend(a, TFT_BLUE,  TFT_WHITE));
 | |
|   }
 | |
| 
 | |
|   delay(4000);
 | |
| 
 | |
|   //*
 | |
|   // Decrease to 8 bit colour (3 bits red, 3 bits green, 2 bits blue)
 | |
|   // Blend from white to full spectrum
 | |
|   for (int a = 0; a < 256; a+=2) // Alpha 0 = 100% background, alpha 255 = 100% foreground
 | |
|   {
 | |
|     // Convert blended 16 bit colour to 8 bits to reduce colour resolution, then map back to 16 bits for displaying
 | |
|     for (int c = 0; c < 192; c++) tft.drawPixel(c, a/2, tft.color8to16(tft.color16to8(tft.alphaBlend(a, rainbow(c), 0xFFFF))));
 | |
|   }
 | |
| 
 | |
|   // Blend from full spectrum to black
 | |
|   for (int a = 255; a > 2; a-=2)
 | |
|   {
 | |
|     // Convert blended 16 bit colour to 8 bits to reduce colour resolution, then map back to 16 bits for displaying
 | |
|     for (int c = 0; c < 192; c++) tft.drawPixel(c, 128 + (255-a)/2, tft.color8to16(tft.color16to8(tft.alphaBlend(a, rainbow(c), 0))));
 | |
|   }
 | |
| 
 | |
|   // Blend from white to black (4 grey levels - it will draw 4 more with a blue tinge due to lower blue bit count)
 | |
|   // Blend from black to a primary colour
 | |
|   for (uint16_t a = 0; a < 255; a++) // Alpha 0 = 100% background, alpha 255 = 100% foreground
 | |
|   {
 | |
|     tft.drawFastHLine(192, a, 12, tft.color8to16(tft.color16to8(tft.alphaBlend(a, TFT_BLACK, TFT_WHITE))));
 | |
|     tft.drawFastHLine(204, a, 12, tft.color8to16(tft.color16to8(tft.alphaBlend(a, TFT_BLACK, TFT_RED))));
 | |
|     tft.drawFastHLine(216, a, 12, tft.color8to16(tft.color16to8(tft.alphaBlend(a, TFT_BLACK, TFT_GREEN))));
 | |
|     tft.drawFastHLine(228, a, 12, tft.color8to16(tft.color16to8(tft.alphaBlend(a, TFT_BLACK, TFT_BLUE))));
 | |
|   }
 | |
| 
 | |
|   delay(4000);
 | |
|   //*/
 | |
| 
 | |
|   /*
 | |
|   // 16 bit colours  (5 bits red, 6 bits green, 5 bits blue)
 | |
|   for (int a = 0; a < 256; a+=2) // Alpha 0 = 100% background, alpha 255 = 100% foreground
 | |
|   {
 | |
|     for (int c = 0; c < 192; c++) tft.drawPixel(c, a/2, tft.alphaBlend(a, rainbow(c), TFT_CYAN));
 | |
|   }
 | |
| 
 | |
|   // Blend from full spectrum to cyan
 | |
|   for (int a = 255; a > 2; a-=2)
 | |
|   {
 | |
|     for (int c = 0; c < 192; c++) tft.drawPixel(c, 128 + (255-a)/2, tft.alphaBlend(a, rainbow(c), TFT_YELLOW));
 | |
|   }
 | |
|   //*/
 | |
| 
 | |
|   /*
 | |
|   // Blend other colour transitions for test purposes
 | |
|   for (uint16_t a = 0; a < 255; a++) // Alpha 0 = 100% background, alpha 255 = 100% foreground
 | |
|   {
 | |
|     tft.drawFastHLine(192, a, 12, tft.alphaBlend(a, TFT_WHITE,  TFT_WHITE));  // Should show as solid white
 | |
|     tft.drawFastHLine(204, a, 12, tft.alphaBlend(a, TFT_BLACK,  TFT_BLACK));  // Should show as solid black
 | |
|     tft.drawFastHLine(216, a, 12, tft.alphaBlend(a, TFT_YELLOW, TFT_CYAN));   // Brightness should be fairly even
 | |
|     tft.drawFastHLine(228, a, 12, tft.alphaBlend(a, TFT_CYAN,   TFT_MAGENTA));// Brightness should be fairly even
 | |
|   }
 | |
| 
 | |
|   delay(4000);
 | |
|   //*/
 | |
| }
 | |
| 
 | |
| 
 | |
| // #########################################################################
 | |
| // Return a 16 bit rainbow colour
 | |
| // #########################################################################
 | |
| unsigned int rainbow(byte value)
 | |
| {
 | |
|   // If 'value' is in the range 0-159 it is converted to a spectrum colour
 | |
|   // from 0 = red through to 127 = blue to 159 = violet
 | |
|   // Extending the range to 0-191 adds a further violet to red band
 | |
|  
 | |
|   value = value%192;
 | |
|   
 | |
|   byte red   = 0; // Red is the top 5 bits of a 16 bit colour value
 | |
|   byte green = 0; // Green is the middle 6 bits, but only top 5 bits used here
 | |
|   byte blue  = 0; // Blue is the bottom 5 bits
 | |
| 
 | |
|   byte sector = value >> 5;
 | |
|   byte amplit = value & 0x1F;
 | |
| 
 | |
|   switch (sector)
 | |
|   {
 | |
|     case 0:
 | |
|       red   = 0x1F;
 | |
|       green = amplit; // Green ramps up
 | |
|       blue  = 0;
 | |
|       break;
 | |
|     case 1:
 | |
|       red   = 0x1F - amplit; // Red ramps down
 | |
|       green = 0x1F;
 | |
|       blue  = 0;
 | |
|       break;
 | |
|     case 2:
 | |
|       red   = 0;
 | |
|       green = 0x1F;
 | |
|       blue  = amplit; // Blue ramps up
 | |
|       break;
 | |
|     case 3:
 | |
|       red   = 0;
 | |
|       green = 0x1F - amplit; // Green ramps down
 | |
|       blue  = 0x1F;
 | |
|       break;
 | |
|     case 4:
 | |
|       red   = amplit; // Red ramps up
 | |
|       green = 0;
 | |
|       blue  = 0x1F;
 | |
|       break;
 | |
|     case 5:
 | |
|       red   = 0x1F;
 | |
|       green = 0;
 | |
|       blue  = 0x1F - amplit; // Blue ramps down
 | |
|       break;
 | |
|   }
 | |
| 
 | |
|   return red << 11 | green << 6 | blue;
 | |
| }
 | |
| 
 | |
| 
 |