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;
 | 
						|
}
 | 
						|
 | 
						|
 |