nopnop2002 / esp-idf-st7789

ST7789 Driver for esp-idf
MIT License
234 stars 56 forks source link

Preventing black screen while refreshing text #20

Open unre4l opened 3 years ago

unre4l commented 3 years ago

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!

nopnop2002 commented 3 years ago

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.
unre4l commented 3 years ago

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.

nopnop2002 commented 3 years ago

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().

unre4l commented 3 years ago

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! 👍

nopnop2002 commented 3 years ago

This is done if _font_fill is valid:

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