С Новым годом! Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/41: Рейтинг темы: голосов - 41, средняя оценка - 4.56
0 / 0 / 0
Регистрация: 11.12.2011
Сообщений: 789

Графические дисплеи - приемы и алгоритмы.

04.09.2016, 21:49. Показов 7686. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Создаю тему, потому что собственных вычислительных мощностей уже не хватает.
Есть некоторые вопросы по работе с LCD и TFT экранами. Пропустим "железные" вопросы подключения и согласования экрана с МК, оставим за кадром процедуры сброса и инициализации конкретного экрана. Допустим, мы уже умеем выводить пиксель, символ, рисовать линию и прямоугольник, выводить заранее заданные строки из ROM и flash. Что с этим делать дальше? Итак, вопросы:
1. Есть дисплей ili9341, есть адаптированная под AVR GCC библиотека TFTv2.cpp. В библиотеке есть функция вывода символа
TFT::drawChar
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void TFT::drawChar( INT8U ascii, INT16U poX, INT16U poY,INT16U size, INT16U fgcolor)
{
if((ascii>=32)&&(ascii<=127))
{
;
}
else
{
ascii = ?-32;
}
for (int i =0; i<FONT_X; i++ ) {
INT8U temp = pgm_read_byte(&sympleFont[ascii-0x20][i]);
for(INT8U f=0;f<8;f++)
{
if((temp>>f)&0x01)
{
fillRectangle(poX+i*size, poY+f*size, size, size, fgcolor);
}
}
}
}
которая была приведена к таком виду:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void TFT_drawChar( unsykned char ascii, unsykned int poX, unsykned int poY,unsykned int size, unsykned int fgcolor)
{
if((ascii>=32)&&(ascii<=127))                  // если параметр ascii входит в множество символов
{
;
}
else
{
ascii = ?-32;
}
 
for (unsykned char i = 0; i<FONT_X; i++)               // сканируем строки, длина строки  FONT_X = 8
{
unsykned char temp = pgm_read_byte(&sympleFont[ascii-0x20][i]);         // читаем байт столбца
for(unsykned char f=0;f<FONT_Y;f++)                                 // проверяем биты в байте, высота символа FONT_Y = 8
{
if((temp>>f)&0x01)                                       // начиная с младшего бита
{
TFT_fillRectangle(poX+i*size, poY+f*size, size, size, fgcolor);         // рисуем "пиксель" размером size
}
else
{
TFT_fillRectangle(poX+i*size, poY+f*size, size, size, back_color);  // и вот тут и начинается мерцание
}
}
}
}
Добавлена строка, затирающая "пиксель", если он отсутствует в битмаске. При выводе символа или строки при помощи этой функции на экране наблюдается подергивание символа по оси Х во время перерисовки строки (символа).
Видео раз, видео два.
Если закомментировать строку TFT_fillRectangle(poX+i*size, poY+f*size, size, size, back_color);, то символ выводится четко, но если выводить изменяющиеся данные, то новые пиксели будут накладываться на старые, и в конце концов получится залитое одним цветом знакоместо. Смотрел на ютубе разные видео, ни у кого на подобном экране не заметил такого глюка. Почему получается мерцание? Ведь если выводится одна и та же строка (символ) в одно и то же место, то и данные, идущие в GROM не должны изменяться. Перекопал функцию TFT_fillRectangle, ничего подозрительного не обнаружил. Пробовал снижать частоту обмена, игрался с инициализацией стекляшки - все не то. Не пойму, в чем прикол, хоть убейся об стену. Кто пользовал эту библиотеку, покажите как правильно рисовать символы, чтобы не перерисовывать весь экран... Или поделитесь кодом и шрифтом для экрана 320*240.

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

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

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

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

приветствуется любая помощь в освоении графических экранов - можно псевдокодом, можно русским по белому, можно примерами кода. Всем заранее спасибо!
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
04.09.2016, 21:49
Ответы с готовыми решениями:

Как распознать каптчу: приемы и алгоритмы
Доброго всем времени суток,недавно стал вопрос ребром,стало весьма и весьма интересно как распознать каптчу,сразу оговорюсь, исключительно...

Дисплеи
Люди, пожалуйста подскажите... нужет дисплей, цветной 3.2&quot; - 3.5&quot; такой что б достать было не сложно (возможно от мобильного) под который...

Дисплеи
Так как дисплеи набирают большую популярность в радиолюбительских конструкциях, а цены на них высоковаты, особенно на графические,...

18
1 / 1 / 0
Регистрация: 19.07.2013
Сообщений: 423
04.09.2016, 23:07
Не сказать что я прямо специалист. Напишу немного
Почему получается мерцание?
Сбиваются координаты вывода.
Попробуйте построчно вывести одинаковые строки по одному разу, типа такого:
TESTING
TESTING
TESTING

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

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

Накидаю книг. Вообще по алгоритмам смотреть компьютерную графику
1. Порев В. Н. Компьютерная графика. - СПб: БХВ.- Петербург, 2012. – 432с
2. Основы разработки компьютерных моделей сложных систем. Учебное пособие. Маликов Р.Ф. Уфа, 2013. - 256 с.
3. Корриган Д. Компьютерная графика: секреты и решения. Учебник. М.: Энтроп, 2007
4. Котов Ю.В., Павлова А.А. Основы машинной графики. Учебник. М: Просвещение, 2013.
5. Фоли Дж., Вэн Дэм А. Основы интерактивной машинной графики. Учебник. М: Мир, 2011.
6. Миронов Б.Г., Миронова Р.С. Инженерная и компьютерная графика. Учебник для вузов. Гриф УМО.- М.: Высшая школа, 2012.- 365с.
0
0 / 0 / 0
Регистрация: 11.12.2011
Сообщений: 789
08.09.2016, 10:43
Разобрался с мерцанием сиволов.
В функции вывода строки правый край предыдущего символа затирал левый край следующего символа. FONT_SPACE был менее чем FONT_X, вот и накладывались символы друг на друга.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void TFT_drawString(char *string,unsykned int poX, unsykned int poY, unsykned int size,unsykned 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;
}
}
}
Кроме того, чуть поправил вывод символа.
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void TFT_drawChar( unsykned char ascii, unsykned int poX, unsykned int poY,unsykned int size, unsykned int fgcolor)
{
unsykned int pix_color;
//if((ascii>=32)&&(ascii<=127))                  // если параметр ascii входит в множество символов
//{
//;
//}
//else
//{
//ascii = ?-32;
//}
 
for (unsykned char i = 0; i<FONT_X; i++)               // сканируем строки, ширина символа  FONT_X
{
unsykned char temp = pgm_read_byte(&sympleFont[ascii-0x20][i]);         // читаем байт столбца
for(unsykned 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
}
}
}
0
0 / 0 / 0
Регистрация: 15.03.2014
Сообщений: 258
08.09.2016, 11:35
Цитата Сообщение от Финский
3. Вывод строк разной длины в одни и те же координаты - как стирать остаток старой, более длинной строки? (С семисегментными индикаторами такой проблемы принципиально не существовало :)) В отдельном месте хранить длину предыдущей выведенной строки, и если новая короче - затереть старую?
А всю старую строку хранить и выводить ее фоновым цветом (если новая != старая) памяти жалко ? При медленном spi так может быть быстрее чем тереть знакоместа полностью.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 1,864
08.09.2016, 13:01
Финский, совет (из опыта): лучше поправьте функцию TFT_fillRectangle, а не её вызов.
(основная идея: она должна закрашивать прямоугольник ровно того размера, который ей передан)

Вообще типовой подход к координатам в аргументах функций:
1. Для функций рисования заполненных фигур (и любых других, где обозначаются области - например, проверка, куда ткнули пальцем) - целые координаты находятся "между пикселями" (на листке буниги в клеточку клетки - пикселы, координаты - по линиям). Соответственно, заливка прямоугольника (x,y,size,size) - это закрашивание пикселей ("клеточек") в промежутке от x до x+size и от y до y+size
2. Для функций рисования линий целые координаты - в серединах пикселей (клеточек).
(но главное - раз создать какую-то конвенцию и всегда её придерживаться)
0
0 / 0 / 0
Регистрация: 25.04.2016
Сообщений: 334
08.09.2016, 14:36
Цитата Сообщение от oomomstir
Финский, совет (из опыта): лучше поправьте функцию TFT_fillRectangle, а не её вызов.
Учитывая скорость TFT_fillRectangle ее лучше просто выкинуть, а не править. В начале отрисовки символа задается область вывода, потом идут одни данные без никаких установок координат и т.п....
0
0 / 0 / 0
Регистрация: 11.12.2011
Сообщений: 789
08.09.2016, 18:32
Riftistor, вот и отрисуйте мне три символа разных размеров - 1x, 3x и 10x, например.
Или подскажите другой алгоритм масштабирования шрифтов.
0
0 / 0 / 0
Регистрация: 25.04.2016
Сообщений: 334
08.09.2016, 19:20
Цитата Сообщение от Финский
Riftistor, вот и отрисуйте мне три символа разных размеров - 1x, 3x и 10x, например.
Какие с этим проблемы? Задал в 3 раза большее окно, каждую точку в линии выводишь 3 раза, вместо одного, затем 3 раза выводишь каждую линию.
0
0 / 0 / 0
Регистрация: 06.12.2016
Сообщений: 322
11.09.2016, 20:57
А какие у вас шрифты? Я пробовал на дисплее как раз 320*240 масштабировать растровый шрифт - это выглядит очень некрасиво. В итоге остановился на том, что надо иметь несколько шрифтов разного размера.
0
0 / 0 / 0
Регистрация: 11.12.2011
Сообщений: 789
12.09.2016, 21:04
Шрифт в оригинале был 8*8, но я ужал его до стандартных 5*8.
Несколько шрифтов - вариант заманчивый, но опять же - расход флеша. Вот разберусь, как хранить графику и шрифты на внешней флешке - так и заведу несколько шрифтов.
0
0 / 0 / 0
Регистрация: 05.10.2007
Сообщений: 498
14.09.2016, 09:37
Применив минимальную упаковку RLE, размер драйвера + шрифт Arial 20 (заглавные буквы) ... 3 килобайта.
0
0 / 0 / 0
Регистрация: 15.02.2015
Сообщений: 444
20.09.2016, 21:08
А подскажите по блендингу двух bmp картинок с альфа-каналом на одном дисплее? Нужно просто вывести одно изображение поверх другого, но при этом нужно сохранить прозрачность фона. МК STM32F746. Как я понял из даташита, в драйвере дисплея для этого предусмотрено два слоя, на один (нижний) выводится фоновое изображение, на верхний слой значок с прозрачным фоном (оба изображения в формате ARGB c 32-битным значением), и далее аппаратным способом оба изображения подмешиваются с помощью графического ускорителя DMA2D с различными пропорциями и выводятся на экран. Проблема в том, что, как я понимаю, верхний слой должен быть полностью прозрачным, но в библиотеках для этого чипа TRANSPORENT цвет указан как 0xFF000000. Ровно такой же цвет используется в bmp файле для прозрачного фона значка. Вроде бы все правильно, но это же ЧЕРНЫЙ (0x000000)! И значение цвета BLACK в этой же библиотеке равно тому же TRANSPORENT.

Code
1
2
3
4
#define LCD_COLOR_BLACK         ((uint32_t)0xFF000000)
#define LCD_COLOR_BROWN         ((uint32_t)0xFFA52A2A)
#define LCD_COLOR_ORANGE        ((uint32_t)0xFFFFA500)
#define LCD_COLOR_TRANSPORENT   ((uint32_t)0xFF000000)
В итоге общая картинка тускнеет (черный цвет затемняет фон), а, так как сам дисплей не ахти, результат, который я вижу, весьма далек от идеала. Очевидно, правильное решение заключается в чем-то другом. Вопрос, что это за способ?
0
0 / 0 / 0
Регистрация: 25.04.2016
Сообщений: 334
21.09.2016, 14:39
Цитата Сообщение от El1te
Проблема в том, что, как я понимаю, верхний слой должен быть полностью прозрачным, но в библиотеках для этого чипа TRANSPORENT цвет указан как 0xFF000000. Ровно такой же цвет используется в bmp файле для прозрачного фона значка. Вроде бы все правильно, но это же ЧЕРНЫЙ (0x000000)! И значение цвета BLACK в этой же библиотеке равно тому же TRANSPORENT.
С LTDC не работал, но раз у тебя изображения хранятся в ARGB8888, то для чего нужен Color Keying? Он для форматов без альфы, если у тебя, например, RGB565, то можно сделать прозрачным один из цветов который нигде не используется, для этого есть по регистру на каждый слой. Для ARGB прозрачным пикселям просто делаешь А = 0.
0
0 / 0 / 0
Регистрация: 26.03.2015
Сообщений: 316
21.09.2016, 15:35
При выхлопе в режиме argb - альфа канал может меняться в двух вариантах: сумма двух альф - без контроля переполнения и умножение двух альф без контроля переполнения. По этому полная прозрачность "00" - всегда остаётся прозрачностью, а вот частичная прозрачность после сложения или умножения может стать полной прозрачностью. Это не баг - а фишка, и её можно использовать с выгодой.
Нужно заметить, что альфаканал не используется в умножении яркости rgb на выхлопе, argb передаётся в память как есть, для дальнейшего пользования.
0
0 / 0 / 0
Регистрация: 15.02.2015
Сообщений: 444
22.09.2016, 11:50
Цитата Сообщение от Riftistor
Цитата Сообщение от El1te
Проблема в том, что, как я понимаю, верхний слой должен быть полностью прозрачным, но в библиотеках для этого чипа TRANSPORENT цвет указан как 0xFF000000. Ровно такой же цвет используется в bmp файле для прозрачного фона значка. Вроде бы все правильно, но это же ЧЕРНЫЙ (0x000000)! И значение цвета BLACK в этой же библиотеке равно тому же TRANSPORENT.
С LTDC не работал, но раз у тебя изображения хранятся в ARGB8888, то для чего нужен Color Keying? Он для форматов без альфы, если у тебя, например, RGB565, то можно сделать прозрачным один из цветов который нигде не используется, для этого есть по регистру на каждый слой. Для ARGB прозрачным пикселям просто делаешь А = 0.

То есть получается, если тот же черный цвет присутствует где-то в самой иконке, то черный этот "прозрачно-черный" цвет я использовать не могу, потому что альфа = 0 должна устанавливаться при условии (color == black), так? А если на экране несколько иконок, то я должен заранее определять, какой цвет в новом наборе будет прозрачным? Или я неправильно понял? Вопросы может быть наивные, но я просто раньше работал только с примитивной графикой.
0
0 / 0 / 0
Регистрация: 25.04.2016
Сообщений: 334
22.09.2016, 12:13
Цитата Сообщение от El1te
То есть получается, если тот же черный цвет присутствует где-то в самой иконке, то черный этот "прозрачно-черный" цвет я использовать не могу, потому что альфа = 0 должна устанавливаться при условии (color == black), так? А если на экране несколько иконок, то я должен заранее определять, какой цвет в новом наборе будет прозрачным? Или я неправильно понял? Вопросы может быть наивные, но я просто раньше работал только с примитивной графикой.
Да, один из цветов резервируется под прозрачный. Можно выбрать такой, который точно не будет использоваться, можно при загрузке картинок чуть подкорректировать цвета, например, все непрозрачные черные пиксели превратить в 1, тогда они будут непрозрачные и почти черные. Но если у тебя в памяти изображения хранятся как ARGB, то лучше отключить Color Keying и непрозрачные пиксели хранить как FFxxxxxx, а прозрачные как 00xxxxxx.
0
0 / 0 / 0
Регистрация: 15.02.2015
Сообщений: 444
22.09.2016, 12:39
Но это же получается вообще как-то нивелирует всю полезность Chrome ART ускорителя для 2D графики, которым так гордятся микроэлектронщики. В чем смысл тогда, я не понимаю?
0
0 / 0 / 0
Регистрация: 25.04.2016
Сообщений: 334
22.09.2016, 19:03
Цитата Сообщение от El1te
Но это же получается вообще как-то нивелирует всю полезность Chrome ART ускорителя для 2D графики, которым так гордятся микроэлектронщики. В чем смысл тогда, я не понимаю?
Я точно так же не понимаю, чем именно нивелируется вся полезность Chrome ART... Конечно в простых случаях можно самому копировать с проверкой альфы, но если изображение будет полупрозрачным, то придется рассчитывать отдельно каждый цвет и это может быть раз в 10+ медленнее. DMA2D сам блендит и конвертирует форматы, а проц в это время занимается чем-то другим.
0
0 / 0 / 0
Регистрация: 26.03.2015
Сообщений: 316
25.09.2016, 16:04
Чёрный цвет является мнимой подложкой, а так-же прозрачным цветом в случае rgb - альфа как константа в одном регистре.
В случае argb - чёрный цвет уже не является прозрачным по умолчанию, есть возможность затемнить графику чёрным цветом по маске альфа_канала.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
25.09.2016, 16:04
Помогаю со студенческими работами здесь

eInk дисплеи
Как у меня Kindle появился, сразу невероятно захотелось попробовать eYmk дисплеи. Сразу появился вопрос, где их взять? Производит только...

Дисплеи(монитор)
Привет, ето Я опять.. Как программно возможно поставить параметры монитора (ну те которые через кнопочки монитора управляется)?...

Нестандартные дисплеи
Добрый день. Как начинающий AVR программист решил начать с часов. В них будет радио, 2 будильника, аналоговый вход и термометр....

Широкие дисплеи
Абсолютно не понимаю, зачем такие нужны. Всё равно, ведь на дополнительной площади показывать обычно нечего. Вот если бы выпускались...

Помогите использовать дисплеи.
Первый 16 символов 2 строки, выдран из принтера самсунг. Имеет 14 проводов соединения с платой. Производитель YES optoitistronics их...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Новые блоги и статьи
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru