Сводный список записей блога

--->>>> Сводный список записей блога <<<<---

22 октября 2022

Графическая библиотека

На данный момент я написал и начал использовать уже третью версию своей графической библиотеки.

В соответствии с ранее описанной парадигмой - это абстрактная библиотека верхнего уровня, которая оперирует с графическими примитивами и ничего не знает о дисплее.

Библиотека оперирует 16-битным цветом (RGB565) вне зависимости от применяемого дисплея.

Библиотека позволяет рисовать на дисплее линии, окружности и прямоугольники (с заливкой и без), выводить описанные ранее растровые спрайты, рисовать "черепашью" графику, работать с оверлеем в ОЗУ.

Перечень функций библиотеки:

Управление цветом

void setColor(uint16_t color);
void setColorBg(uint16_t color);
uint16_t convertRgbTo565color(uint8_t r, uint8_t g, uint8_t b);

Оверлей

Оверлей - область в ОЗУ контроллера. Использование оверлея позволяет в выделенной области ОЗУ отрисовать необходимую графическую информацию - такую как текст, графические примитивы и т.д.
После чего "выплюнуть" содержимое буфера в дисплей.
Вариант использования оверлея - отрисовка графической информации в буфере с использованием прозрачности при использовании дисплеев с поддержкой оконного режима вывода, когда нет возможности напрямую нарисовать перекрывающиеся объекты.

void enableOverlay(uint8_t width, uint8_t height, uint16_t* overlayBuffer);
void disableOverlay(void);
void drawOverlay(coordType x, coordType y, uint8_t doDisableOverlay);

Спрайтовая графика

void drawSprite   (coordType x, coordType y, const spriteType sprite,
uint8_t isTransparent, uint16_t* overridePalette);

void drawRleSprite(coordType x, coordType y, const spriteType sprite,
uint8_t isTransparent, uint16_t* overridePalette);

Вывод текста

void setFont(const uint8_t* fontPtr);
void setTextPos(coordType x, coordType y);
void setCursorPos(coordType x, coordType y);
void setTextSymbolsInterval(uint8_t symbolsInterval);
void setTextIntervalFillType(textIntervalFillType textIntervalFillMode);
void setTextTransparency(textTranparencyType textTransparency);
void putSymbol ( char symbol );
void printS (char* str);
void printS_P(const char* str); // AVR only

Функционал отрисовки шрифтов заточен на описанный ранее формат шрифтов.
Чуть позже я опишу и выложу еще одну утилитку - редактор шрифтов.

Графические примитивы

void lineH  (coordType x1, coordType x2, coordType y );
void lineV  (coordType x,  coordType y1, coordType y2);
void line   (coordType x1, coordType y1, coordType x2, coordType y2);
void lineTo (coordType x2, coordType y2);
void rectangle (coordType x1, coordType y1, coordType x2, coordType y2, fillModeType fill);
void circle (coordType x0, coordType y0, coordType R, fillModeType fill);

Черепашья графика

Рисование примитивов по принципу "черепашьей" графики, где каждый элемент примитива определяется начальной точкой, одним из восьми направлений и числом шагов.
Конец последовательности определяется элементом с числом шагов 0.
Рисование примитива может выполняться как полностью всего за одну итерацию, так и с задержками. Задержки могут быть как между рисованием элементов примитива, так и для процесса рисования каждого элемента. 

void turtleDrawInit(coordType x, coordType y, turtleDrawItemType* firstItem, 
uint8_t itemPause, uint8_t stepPause);

turtleDrawResultType turtleDrawExecute(uint8_t timeTicks);

Подключение библиотеки

Что бы библиотека могла что то нарисовать - ей, как минимум, нужно сообщить процедуру отрисовки пикселя на экране.
А так же передать некоторые дополнительные параметры.

Это все делается посредством файлика GGraphicsInterface.h, индивидуального для каждого проекта.

/*** LCD driver ***/
#include "LCD ST7789/ST7789.h" 

/*** variable size for coordinates ***/
#define DISPLAY_SHORT_COORDINATES

/*** mandatory routines ***/
#define displayPutPixel(x, y, c) putPixelST7789( (x), (y), (c) )
#define displayClear() clearDisplayST7789()

/*** use overlay ? ***/
#define DISPLAY_USE_OVERLAY

/*** use display window ? ***/
#define DISPLAY_USE_WINDOW
/*** area routines ***/
#ifdef DISPLAY_USE_WINDOW
#define fillDisplay(color) fillDisplayST7789((color))
#define displayFillArea(x1,y1,x2,y2, c) fillAreaST7789( (x1), (y1), (x2), (y2),  (c) )
#define displaySetArea(x1,y1,x2,y2) setOutputAreaST7789( (x1), (y1), (x2), (y2) )
#define displaySendColor(c) sendColorDataST7789( (c) )
#endif //DISPLAY_USE_WINDOW

/*** Fonts ***/
#include "FONTS/5x7_Nokia.h"

Из обязательного - необходимо подключение драйвера дисплея и определение одной-единственной функции отрисовки пикселя displayPutPixel.
Эта функция может быть подключена через define или полноценно описана как функция-прокладка.

Переопределение функции очистки дисплея - displayClear - исключительно для удобства написания программы.

Определение DISPLAY_SHORT_COORDINATES указывает библиотеке, что все координатные аргументы - 8-битные (uint8_t), если определение не задано - используются 16-битные координаты. Для дисплеев с разрешением менее 256х256 пикселей и меньше это позволяет на 8-битных контроллерах оптимизировать производительность.

Определение DISPLAY_USE_OVERLAY, если задано, разблокирует функции работы с оверлеем.

Определение DISPLAY_USE_WINDOW разблокирует оконные функции библиотеки для работы с дисплеями, поддерживающими оконный вывод. При этом библиотеке дополнительно нужно предоставить следующие функции драйвера:

fillDisplay(color) - заливка дисплея заданным цветом
displayFillArea(x1,y1,x2,y2, c) - заливка заданным цветом области дисплея
displaySetArea(x1,y1,x2,y2) - определение окна дисплея и включение режима записи цветовых данных
displaySendColor(color) - отправка цвета одного пикселя, для вывода в окно

Подключение шрифтов. 
Поскольку в файле шрифта, кроме самих данных о символах, есть еще и различные определения, необходимые для библиотеки, здесь необходимо подключить файлы всех используемых шрифтов.

А в самой программе уже определить сами шрифты, как массивы.

const fontType nokia_font = FONT_5X7_NOKIA;


Где это всё взять?

Графическая библиотека и несколько шрифтов "по мотивам" - тут







3 комментария:

  1. Это нужная, но теория. Давно не было ваших интересных поделок.Терпеливо жду.

    ОтветитьУдалить
    Ответы
    1. Теория тоже нужна и важна. А поделок нету. Последний был недельный таймер. Больше я ничего не делал пока. Может со-автор придумает что то, у неё интересные мысли есть.

      Удалить
  2. Хорошие новости.
    Соавтору интересных мыслей и удачи в воплощении.

    ОтветитьУдалить

======= !!! ВНИМАНИЕ !!! ======================================================================
Гугл умный и боится спама. Поэтому иногда ваши комментарии Гугл отправляет мне на премодерацию. Отправлять или нет - решаю не я, а алгоритмы Гугла. Если ваш комментарий не появился сразу, значит я получу уведомление и опубликую ваш комментарий через некоторое время. Я стараюсь это делать достаточно оперативно.