Easyelectronics.ru

Электроника для всех
Текущее время: 01 окт 2020, 18:49

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 19 ] 
Автор Сообщение
 Заголовок сообщения: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 05 сен 2016, 22:36 
Старожил
Аватара пользователя

Зарегистрирован: 18 июн 2011, 16:29
Сообщения: 1893
Откуда: Докучаевск-Волноваха
Создаю тему, потому что собственных вычислительных мощностей уже не хватает.
Есть некоторые вопросы по работе с LCD и TFT экранами. Пропустим "железные" вопросы подключения и согласования экрана с МК, оставим за кадром процедуры сброса и инициализации конкретного экрана. Допустим, мы уже умеем выводить пиксель, символ, рисовать линию и прямоугольник, выводить заранее заданные строки из RAM и flash. Что с этим делать дальше? Итак, вопросы:
1. Есть дисплей ili9341, есть адаптированная под AVR GCC библиотека TFTv2.cpp. В библиотеке есть функция вывода символа
Show TFT::drawChar
которая была приведена к таком виду:
Show void TFT_drawChar
Добавлена строка, затирающая "пиксель", если он отсутствует в битмаске. При выводе символа или строки при помощи этой функции на экране наблюдается подергивание символа по оси Х во время перерисовки строки (символа).
Видео раз, видео два.
Если закомментировать строку TFT_fillRectangle(poX+i*size, poY+f*size, size, size, back_color);, то символ выводится четко, но если выводить изменяющиеся данные, то новые пиксели будут накладываться на старые, и в конце концов получится залитое одним цветом знакоместо. Смотрел на ютубе разные видео, ни у кого на подобном экране не заметил такого глюка. Почему получается мерцание? Ведь если выводится одна и та же строка (символ) в одно и то же место, то и данные, идущие в GRAM не должны изменяться. Перекопал функцию TFT_fillRectangle, ничего подозрительного не обнаружил. Пробовал снижать частоту обмена, игрался с инициализацией стекляшки - все не то. Не пойму, в чем прикол, хоть убейся об стену. Кто пользовал эту библиотеку, покажите как правильно рисовать символы, чтобы не перерисовывать весь экран... Или поделитесь кодом и шрифтом для экрана 320*240.

2. Допустим, делаем очередные часы бла-бла-бла на крутом экране. Как сформировать вывод строки вида "ЧЧ:ММ:СС" из трех отдельных переменных?(про sprintf знаю, дорогоинтим не предлагать). Сделать массив buffer на 9 элементов, и через серию itoa и strcat натрамбовать туда символы и вывести через условную print_string_from_RAM? Выводить переменные отдельно, через разбивку на разряды? (пропустим пока вопросы переноса строк)

3. Вывод строк разной длины в одни и те же координаты - как стирать остаток старой, более длинной строки? (С семисегментными индикаторами такой проблемы принципиально не существовало :)) В отдельном месте хранить длину предыдущей выведенной строки, и если новая короче - затереть старую?

4. Движущиеся объекты - я умом-то теорию понимаю - новые координаты, куда перемещаемся, и старые, где затираем объект, при этом следить, чтобы не вышли за пределы экранной области. При всем этом, обходиться без кадрового буфера (оперативки мало, я все еще на АВРках сижу :( ) Кто как делает? Правильно понимаю принцип? Не хочется тратить время на изобретение велосипедов, хочется компактно, понятно, и быстро, не надо портировать DirectX 11 на МК.

5. Хранение картинок, шрифтов и пр. графики на внешней SPI flash. В теории оно выглядело просто идеально - потоком читаем из флешки, льем в экран. Реальность немного потыкала фейсом об тэйбл - аппаратный SPI всего один. Читать в буфер по 512 байт, и сливать в экран по 256 слов - херня, медленно и печально(и заморочки с адресацией окна вывода Set_XY). Городить софтовый SPI? Читать из флешки с паузами, есть такая возможность вроде по сигналу #HOLD (даташит)/ Как по-простому организовать?

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

_________________
Хранитель форума


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 05 сен 2016, 23:54 
Старожил
Аватара пользователя

Зарегистрирован: 14 дек 2011, 01:53
Сообщения: 528
Не сказать что я прямо специалист. Напишу немного
Цитата:
Почему получается мерцание?

Сбиваются координаты вывода.
Попробуйте построчно вывести одинаковые строки по одному разу, типа такого:
TESTING
TESTING
TESTING

еще на этапе тестирования помогает затирать не фоновым цветом, а контрастирующим с заполняющим.

Цитата:
Вывод строк разной длины в одни и те же координаты

Да, как вариант, запоминать координату границы вывода и затирать остаток
Цитата:
Движущиеся объекты

Как вариант перерисовывать по одному столбцу в сторону движения или
читать столбец из дисплея и писать в следующий

Накидаю книг. Вообще по алгоритмам смотреть компьютерную графику
Show


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 09 сен 2016, 11:30 
Старожил
Аватара пользователя

Зарегистрирован: 18 июн 2011, 16:29
Сообщения: 1893
Откуда: Докучаевск-Волноваха
Разобрался с мерцанием сиволов.
В функции вывода строки правый край предыдущего символа затирал левый край следующего символа. FONT_SPACE был менее чем FONT_X, вот и накладывались символы друг на друга.
Код:
void TFT_drawString(char *string,unsigned int poX, unsigned int poY, unsigned int size,unsigned int fgcolor)
{
   while(*string)
   {
      TFT_drawChar(*string, poX, poY, size, fgcolor);
      *string++;
      if((poX+FONT_X) < (MAX_X - FONT_X*size))
      {
         poX += FONT_SPACE*size;                                     /* Move cursor right            */
      }
      else
      {
         poX=0;
         poY+=size*FONT_Y+FONT_SPACE;
      }
   }
}

Кроме того, чуть поправил вывод символа.
Код:
void TFT_drawChar( unsigned char ascii, unsigned int poX, unsigned int poY,unsigned int size, unsigned int fgcolor)
{
   unsigned int pix_color;
   //if((ascii>=32)&&(ascii<=127))                  // если параметр ascii входит в множество символов
   //{
      //;
   //}
   //else
   //{
      //ascii = '?'-32;
   //}
   
   for (unsigned char i = 0; i<FONT_X; i++)               // сканируем строки, ширина символа  FONT_X
   {
      unsigned char temp = pgm_read_byte(&simpleFont[ascii-0x20][i]);         // читаем байт столбца
      for(unsigned char f=0;f<FONT_Y;f++)                                 // проверяем биты в байте
      {
         if((temp>>f) & 0x01)                                       // начиная с младшего бита
         {
            pix_color = fgcolor;
         }
         else
         {
            pix_color = back_color;
         }
         TFT_fillRectangle(poX+i*size, poY+f*size, size-1, size-1, pix_color);         // рисуем "пиксель" размером size, цветом pix_color
      }
   }
}

_________________
Хранитель форума


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 09 сен 2016, 12:22 
Старожил

Зарегистрирован: 19 мар 2014, 19:33
Сообщения: 291
Финский писал(а):
3. Вывод строк разной длины в одни и те же координаты - как стирать остаток старой, более длинной строки? (С семисегментными индикаторами такой проблемы принципиально не существовало :)) В отдельном месте хранить длину предыдущей выведенной строки, и если новая короче - затереть старую?

А всю старую строку хранить и выводить ее фоновым цветом (если новая != старая) памяти жалко ? При медленном spi так может быть быстрее чем тереть знакоместа полностью.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 09 сен 2016, 13:48 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2795
Откуда: Санкт-Петербург
Финский, совет (из опыта): лучше поправьте функцию TFT_fillRectangle, а не её вызов.
(основная идея: она должна закрашивать прямоугольник ровно того размера, который ей передан)

Вообще типовой подход к координатам в аргументах функций:
1. Для функций рисования заполненных фигур (и любых других, где обозначаются области - например, проверка, куда ткнули пальцем) - целые координаты находятся "между пикселями" (на листке бумаги в клеточку клетки - пикселы, координаты - по линиям). Соответственно, заливка прямоугольника (x,y,size,size) - это закрашивание пикселей ("клеточек") в промежутке от x до x+size и от y до y+size
2. Для функций рисования линий целые координаты - в серединах пикселей (клеточек).
(но главное - раз создать какую-то конвенцию и всегда её придерживаться)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 09 сен 2016, 15:23 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1279
aamonster писал(а):
Финский, совет (из опыта): лучше поправьте функцию TFT_fillRectangle, а не её вызов.

Учитывая скорость TFT_fillRectangle ее лучше просто выкинуть, а не править. В начале отрисовки символа задается область вывода, потом идут одни данные без никаких установок координат и т.п....


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 09 сен 2016, 19:19 
Старожил
Аватара пользователя

Зарегистрирован: 18 июн 2011, 16:29
Сообщения: 1893
Откуда: Докучаевск-Волноваха
Reflector, вот и отрисуйте мне три символа разных размеров - 1x, 3x и 10x, например.
Или подскажите другой алгоритм масштабирования шрифтов.

_________________
Хранитель форума


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 09 сен 2016, 20:07 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1279
Финский писал(а):
Reflector, вот и отрисуйте мне три символа разных размеров - 1x, 3x и 10x, например.

Какие с этим проблемы? Задал в 3 раза большее окно, каждую точку в линии выводишь 3 раза, вместо одного, затем 3 раза выводишь каждую линию.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 12 сен 2016, 21:44 
Старожил

Зарегистрирован: 18 июл 2016, 21:17
Сообщения: 746
А какие у вас шрифты? Я пробовал на дисплее как раз 320*240 масштабировать растровый шрифт - это выглядит очень некрасиво. В итоге остановился на том, что надо иметь несколько шрифтов разного размера.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 13 сен 2016, 21:51 
Старожил
Аватара пользователя

Зарегистрирован: 18 июн 2011, 16:29
Сообщения: 1893
Откуда: Докучаевск-Волноваха
Шрифт в оригинале был 8*8, но я ужал его до стандартных 5*8.
Несколько шрифтов - вариант заманчивый, но опять же - расход флеша. Вот разберусь, как хранить графику и шрифты на внешней флешке - так и заведу несколько шрифтов.

_________________
Хранитель форума


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 15 сен 2016, 10:24 
Старожил
Аватара пользователя

Зарегистрирован: 30 янв 2014, 18:09
Сообщения: 647
Откуда: Киев
Применив минимальную упаковку RLE, размер драйвера + шрифт Arial 20 (заглавные буквы) ... 3 килобайта.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 21 сен 2016, 21:55 
Старожил
Аватара пользователя

Зарегистрирован: 19 фев 2015, 17:37
Сообщения: 1604
Откуда: void
А подскажите по блендингу двух bmp картинок с альфа-каналом на одном дисплее? Нужно просто вывести одно изображение поверх другого, но при этом нужно сохранить прозрачность фона. МК STM32F746. Как я понял из даташита, в драйвере дисплея для этого предусмотрено два слоя, на один (нижний) выводится фоновое изображение, на верхний слой значок с прозрачным фоном (оба изображения в формате ARGB c 32-битным значением), и далее аппаратным способом оба изображения подмешиваются с помощью графического ускорителя DMA2D с различными пропорциями и выводятся на экран. Проблема в том, что, как я понимаю, верхний слой должен быть полностью прозрачным, но в библиотеках для этого чипа TRANSPARENT цвет указан как 0xFF000000. Ровно такой же цвет используется в bmp файле для прозрачного фона значка. Вроде бы все правильно, но это же ЧЕРНЫЙ (0x000000)! И значение цвета BLACK в этой же библиотеке равно тому же TRANSPARENT.

Код:
#define LCD_COLOR_BLACK         ((uint32_t)0xFF000000)
#define LCD_COLOR_BROWN         ((uint32_t)0xFFA52A2A)
#define LCD_COLOR_ORANGE        ((uint32_t)0xFFFFA500)
#define LCD_COLOR_TRANSPARENT   ((uint32_t)0xFF000000)


В итоге общая картинка тускнеет (черный цвет затемняет фон), а, так как сам дисплей не ахти, результат, который я вижу, весьма далек от идеала. Очевидно, правильное решение заключается в чем-то другом. Вопрос, что это за способ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 22 сен 2016, 15:26 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1279
El1te писал(а):
Проблема в том, что, как я понимаю, верхний слой должен быть полностью прозрачным, но в библиотеках для этого чипа TRANSPARENT цвет указан как 0xFF000000. Ровно такой же цвет используется в bmp файле для прозрачного фона значка. Вроде бы все правильно, но это же ЧЕРНЫЙ (0x000000)! И значение цвета BLACK в этой же библиотеке равно тому же TRANSPARENT.

С LTDC не работал, но раз у тебя изображения хранятся в ARGB8888, то для чего нужен Color Keying? Он для форматов без альфы, если у тебя, например, RGB565, то можно сделать прозрачным один из цветов который нигде не используется, для этого есть по регистру на каждый слой. Для ARGB прозрачным пикселям просто делаешь А = 0.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 22 сен 2016, 16:22 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 835
При выхлопе в режиме argb - альфа канал может меняться в двух вариантах: сумма двух альф - без контроля переполнения и умножение двух альф без контроля переполнения. По этому полная прозрачность "00" - всегда остаётся прозрачностью, а вот частичная прозрачность после сложения или умножения может стать полной прозрачностью. Это не баг - а фишка, и её можно использовать с выгодой.
Нужно заметить, что альфаканал не используется в умножении яркости rgb на выхлопе, argb передаётся в память как есть, для дальнейшего пользования.

_________________
Потоковая OS


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 23 сен 2016, 12:37 
Старожил
Аватара пользователя

Зарегистрирован: 19 фев 2015, 17:37
Сообщения: 1604
Откуда: void
Reflector писал(а):
El1te писал(а):
Проблема в том, что, как я понимаю, верхний слой должен быть полностью прозрачным, но в библиотеках для этого чипа TRANSPARENT цвет указан как 0xFF000000. Ровно такой же цвет используется в bmp файле для прозрачного фона значка. Вроде бы все правильно, но это же ЧЕРНЫЙ (0x000000)! И значение цвета BLACK в этой же библиотеке равно тому же TRANSPARENT.

С LTDC не работал, но раз у тебя изображения хранятся в ARGB8888, то для чего нужен Color Keying? Он для форматов без альфы, если у тебя, например, RGB565, то можно сделать прозрачным один из цветов который нигде не используется, для этого есть по регистру на каждый слой. Для ARGB прозрачным пикселям просто делаешь А = 0.


То есть получается, если тот же черный цвет присутствует где-то в самой иконке, то черный этот "прозрачно-черный" цвет я использовать не могу, потому что альфа = 0 должна устанавливаться при условии (color == black), так? А если на экране несколько иконок, то я должен заранее определять, какой цвет в новом наборе будет прозрачным? Или я неправильно понял? Вопросы может быть наивные, но я просто раньше работал только с примитивной графикой.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 23 сен 2016, 13:00 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1279
El1te писал(а):
То есть получается, если тот же черный цвет присутствует где-то в самой иконке, то черный этот "прозрачно-черный" цвет я использовать не могу, потому что альфа = 0 должна устанавливаться при условии (color == black), так? А если на экране несколько иконок, то я должен заранее определять, какой цвет в новом наборе будет прозрачным? Или я неправильно понял? Вопросы может быть наивные, но я просто раньше работал только с примитивной графикой.

Да, один из цветов резервируется под прозрачный. Можно выбрать такой, который точно не будет использоваться, можно при загрузке картинок чуть подкорректировать цвета, например, все непрозрачные черные пиксели превратить в 1, тогда они будут непрозрачные и почти черные. Но если у тебя в памяти изображения хранятся как ARGB, то лучше отключить Color Keying и непрозрачные пиксели хранить как FFxxxxxx, а прозрачные как 00xxxxxx.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 23 сен 2016, 13:26 
Старожил
Аватара пользователя

Зарегистрирован: 19 фев 2015, 17:37
Сообщения: 1604
Откуда: void
Но это же получается вообще как-то нивелирует всю полезность Chrome ART ускорителя для 2D графики, которым так гордятся микроэлектронщики. В чем смысл тогда, я не понимаю?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 23 сен 2016, 19:50 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1279
El1te писал(а):
Но это же получается вообще как-то нивелирует всю полезность Chrome ART ускорителя для 2D графики, которым так гордятся микроэлектронщики. В чем смысл тогда, я не понимаю?

Я точно так же не понимаю, чем именно нивелируется вся полезность Chrome ART... Конечно в простых случаях можно самому копировать с проверкой альфы, но если изображение будет полупрозрачным, то придется рассчитывать отдельно каждый цвет и это может быть раз в 10+ медленнее. DMA2D сам блендит и конвертирует форматы, а проц в это время занимается чем-то другим.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Графические дисплеи - приемы и алгоритмы.
СообщениеДобавлено: 26 сен 2016, 16:51 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 835
Чёрный цвет является мнимой подложкой, а так-же прозрачным цветом в случае rgb - альфа как константа в одном регистре.
В случае argb - чёрный цвет уже не является прозрачным по умолчанию, есть возможность затемнить графику чёрным цветом по маске альфа_канала.

_________________
Потоковая OS


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 19 ] 


Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB