0

PyGamer Arduino 888 RGB to 565 color conversion
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

PyGamer Arduino 888 RGB to 565 color conversion

by quarterturn on Sun Jun 13, 2021 4:42 pm

I'm trying to come up with a simple face shading method for some 3D graphics experiements I'm doing on the PyGamer board. I use a face normal projection to give me a value 0-255, so for testing I'd like to just give that to R,G, and B to get a greyscale shading. I am using a 16-bit canvas, so I'll need 565 RGB. This site describes a method of turning RGB888 into RGB565: https://www.lucasgaland.com/24-bit-16-b ... -lcd-guis/

Here's the relevant code in my program:
Code: Select all | TOGGLE FULL SIZE
            unsigned int red5 = (face_colors[i] * 249 + 1014) >> 11;
            unsigned int green6 = (face_colors[i] * 253 + 505) >> 10;
            unsigned int blue5 = (face_colors[i] * 249 + 1014) >> 11;
            if (face_colors != NULL)
                color = (red5 << 11) | (green6 << 5) | blue5;


However this does not produce the intended result. I get greys with green and purple mixed in. Adafruit_Arcada_Def.h color definitions appear to show that colorss are packed in RGB order, so I don't think I have the color order wrong. Is there something I'm overlooking in Adafruit_GFX.h which would allow me to specify color in 888 RGB?

If nothing stands out from my code snippet I'll be glad to put the whole thing up on github so it can be compiled and run. It's basically a tear-apart of the Uno9341TFT library, moving all the functions out of the class and removing all the hacky stuff needed to make things work without a framebuffer.

BTW, using a canvas and blitting at the conclusion of each render gives very nice results. It has no problem at all with the Stamford Bunny. I did have to set blocking to 'true' like so arcada.blitFrameBuffer(0, 0, true, true); otherwise I had an area on the screen which stayed blank.
Attachments
bunny.jpg
bunny.jpg (105.55 KiB) Viewed 118 times

quarterturn
 
Posts: 76
Joined: Mon Mar 23, 2015 11:05 pm

Re: PyGamer Arduino 888 RGB to 565 color conversion

by quarterturn on Sun Jun 13, 2021 7:45 pm

Despite not seeing any value above 255 in face_colors[] I've no doubt missed something as the following code does produce a nice greyscale gradient:

Code: Select all | TOGGLE FULL SIZE
#include "Adafruit_Arcada.h"
Adafruit_Arcada arcada;


void setup(void) {
  arcada.displayBegin();
 
  // Turn on backlight
  arcada.setBacklight(255);

 
  testlines(ARCADA_YELLOW);
  delay(500);

}

void loop() {
}

void testlines(uint16_t color) {
  arcada.display->fillScreen(ARCADA_BLACK);
  for (int16_t x=0; x < arcada.display->width(); x++) {
    unsigned int red5 = (x * 249 + 1014) >> 11;
    unsigned int green6 = (x * 253 + 505) >> 10;
    unsigned int blue5 = (x * 249 + 1014) >> 11;
    color = (red5 << 11) | (green6 << 5) | blue5;
    arcada.display->drawLine(x, 0, x, arcada.display->height()-1, color);
  }
}

quarterturn
 
Posts: 76
Joined: Mon Mar 23, 2015 11:05 pm

Re: PyGamer Arduino 888 RGB to 565 color conversion

by quarterturn on Sun Jun 13, 2021 8:27 pm

The same color code does not work when using a canvas!

Code: Select all | TOGGLE FULL SIZE
#include "Adafruit_Arcada.h"
Adafruit_Arcada arcada;

uint16_t *framebuffer;

void setup(void) {
  arcada.arcadaBegin();
  arcada.displayBegin();
 
  // Turn on backlight
  arcada.setBacklight(255);

  if (! arcada.createFrameBuffer(ARCADA_TFT_WIDTH, ARCADA_TFT_HEIGHT)) {
    arcada.haltBox("Could not allocate framebuffer");
  }
  framebuffer = arcada.getFrameBuffer();
 
  testlines(arcada.getCanvas(), ARCADA_YELLOW);
  arcada.blitFrameBuffer(0, 0, false, true);
  delay(500);

}

void loop() {
}

void testlines(GFXcanvas16 *_canvas, uint16_t color) {
  _canvas->fillScreen(ARCADA_BLACK);
  for (int16_t x=0; x < arcada.display->width(); x++) {
    unsigned int red5 = (x * 249 + 1014) >> 11;
    unsigned int green6 = (x * 253 + 505) >> 10;
    unsigned int blue5 = (x * 249 + 1014) >> 11;
    color = (red5 << 11) | (green6 << 5) | blue5;
    _canvas->drawLine(x, 0, x, arcada.display->height()-1, color);
  }
}


Instead of a greyscale gradient you get pinks and greens!

quarterturn
 
Posts: 76
Joined: Mon Mar 23, 2015 11:05 pm

Re: PyGamer Arduino 888 RGB to 565 color conversion

by quarterturn on Sun Jun 13, 2021 8:44 pm

Looking at one of the pixeldust examples I see __builtin_bswap16(color)) being used. The following now produces a correct gradient:

Code: Select all | TOGGLE FULL SIZE
#include "Adafruit_Arcada.h"
Adafruit_Arcada arcada;

uint16_t *framebuffer;

void setup(void) {
  arcada.arcadaBegin();
  arcada.displayBegin();
 
  // Turn on backlight
  arcada.setBacklight(255);

  if (! arcada.createFrameBuffer(ARCADA_TFT_WIDTH, ARCADA_TFT_HEIGHT)) {
    arcada.haltBox("Could not allocate framebuffer");
  }
  framebuffer = arcada.getFrameBuffer();
 
  testlines(arcada.getCanvas(), ARCADA_YELLOW);
  arcada.blitFrameBuffer(0, 0, false, true);
  delay(500);

}

void loop() {
}

void testlines(GFXcanvas16 *_canvas, uint16_t color) {
  _canvas->fillScreen(ARCADA_BLACK);
  for (int16_t x=0; x < arcada.display->width(); x++) {
    color = arcada.display->color565(x, x, x);
    _canvas->drawLine(x, 0, x, arcada.display->height()-1, __builtin_bswap16(color));
  }
}


I had no idea there was a 'color565' method until I saw it in one of the pixeldust demos. It's hard to tell where stuff comes from in Arcada.

quarterturn
 
Posts: 76
Joined: Mon Mar 23, 2015 11:05 pm

Please be positive and constructive with your questions and comments.