esp-idf-st7789 icon indicating copy to clipboard operation
esp-idf-st7789 copied to clipboard

Preventing black screen while refreshing text

Open unre4l opened this issue 3 years ago • 5 comments

Hi, i measure values every second an print them onto the screen. To clear old values i first fill the screen black and then draw the text. That results in a visible "refresh" effect, everything is black and the text slowly appears again line per line.
Is it possible to draw everything in a frame buffer and then paint the screen at once? So that there isn't a completly black screen for one frame. Thanks and cool library!

unre4l avatar Mar 29 '21 02:03 unre4l

Is it possible to draw everything in a frame buffer and then paint the screen at once?

What is a frame buffer? Do you mean all Pixel data?

If you want to partially rewrite the text on the screen, write the same text in the same color as the background and it will disappear.

uint16_t color;
lcdFillScreen(dev, BLACK);
uint8_t ascii[20];

color = RED;
strcpy((char *)ascii, "Direction=0");
lcdDrawString(dev, fx, 0, 60, ascii, color);

.
.
.
.

color = BLACK;
strcpy((char *)ascii, "Direction=0");
lcdDrawString(dev, fx, 0, 60, ascii, color); // text is disappear.

nopnop2002 avatar Mar 29 '21 09:03 nopnop2002

Do you mean all Pixel data?

Kind of. My goal is to have:

Frame 1     ->   Frame 2
| text A |       | text B  |  

But what is possible is:

(draw text)      (draw clearing rect)       (draw text)
Frame 1     ->   Frame 2               ->   Frame 3
| text A |       |        |                 | text B  |  

If you want to partially rewrite the text on the screen, write the same text in the same color as the background and it will disappear.

Thanks for the example, but unfortunately it wont solve the problem. The frame inbetween the text draw calls has to be a black rectangle (or black text) to clear the previous text. So there is always one frame before new text can appear. If one could write all pixel data in a buffer[screen_x][screen_y] and swap all pixel in one draw call, a refresh frame to clear old data wont be necessary, because one can clear and draw on the buffer and flush at once to the screen so no intermediate frame would be visible.

unre4l avatar Mar 29 '21 14:03 unre4l

If one could write all pixel data in a buffer[screen_x][screen_y] and swap all pixel in one draw call,

There is lcdDrawMultiPixels(). You will draw RED square.

uint16_t PixelData[16][16];

for (int x=0;x<16;x++);
  for (int y=0;y<16;y++);
    PixelData[x][y] = RED;
  }
}

for (int y=0;y<16,y++) {
  lcdDrawMultiPixels(&dev, 0, y, 16, PixelData[[0][y]);
}

The generator for text bitmaps is GetFontx().

nopnop2002 avatar Mar 29 '21 22:03 nopnop2002

The lcdDrawMultiPixels solves my problem. Thanks! I scrolled through your code and found an even simpler solution.

https://github.com/nopnop2002/esp-idf-st7789/blob/42705cd3a0c99f917f37920db310e5d22303b0e1/main/st7789.c#L772 This line does exactly what i was looking for. Although refreshing is slower, there is no flickering! 👍

unre4l avatar Mar 30 '21 12:03 unre4l

This is done if _font_fill is valid:

https://github.com/nopnop2002/esp-idf-st7789/blob/42705cd3a0c99f917f37920db310e5d22303b0e1/main/st7789.c#L751

nopnop2002 avatar Mar 31 '21 01:03 nopnop2002