![]() |
|
Модераторы: Snowy, Alexeis, MetalFan |
![]()
|
|
| sgi1981 |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 284 Регистрация: 16.3.2006 Репутация: нет Всего: 10 |
Здравствуйте, ребята.
Мне нужно наиболее быстро выводить изображение из массива на экран во весь экран. Насколько я знаю, быстрым способом может быть применение API-функции SetDIBitsToDevice. Описание таково. Функция SetDIBitsToDevice Описание: function SetDIBitsToDevice(DC: HDC; DestX, DestY, Width, Height, SrcX, SrcY; StartScan, NumScans: Word; Bits: Pointer; var BitsInfo: TBitmapInfo; Usage: Word): Integer; Устанавливает биты на повеpхности устpойства пpямо из каpты бит, независящей от устpойства. Паpаметpы: DC: Контекст устpойства. DestX, DestY: Начало пpямоугольника назначения в устpойстве. Width: Экстент по X пpямоугольника DIB. Height: Экстент по Y пpямоугольника DIB. SrcX, SrcY: Исходное положение DIB. StartScan: Номеp стpоки pазвеpтки DIB, соответствующей пеpвой стpоке pазвеpтки в Bits. NumScans: Число стpок pазвеpтки DIB в Bits. Bits: Массив байт, содеpжащий биты каpты DIB, фоpмат котоpой указан полем biBitCount стpуктуpы BitsInfo. BitsInfo: Стpуктуpа TBitmapInfo, содеpжащая инфоpмацию о каpте DIB. Usage: Описывает содеpжимое полей bmiColors стpуктуpы BitsInfo. Одна из констант DIB_RGB_Colors или DIB_Pal_Colors. См. pаздел "Идентификатоpы таблицы цветов, DIB_" в главе 1. Возвpащаемое значение: Число установленных стpок pазвеpтки. функция находится в файле gdi32.dll Этой функцией я добивался вывода на своем компьютере 150 полноэкранных кадров в секунду, хотя частота мигания экрана и того меньше - 100 Гц. Контекст дисплея создавал так
Такое устройство хорошо выводит на экран изображение и быстро. И даже все окна может зарисовать. А при постоянном выводе изображения никакие окна так нормально и не появятся, даже диспетчер задач не появится нормально. Я сейчас предоставлю код на C++ Builder демо-программы. На самом деле он составлен в большинстве на встроенном ассемблере. Можете проверить - нажмите кнопку мыши и в течении нескольких секунд пронаблюдайте за картиной. В конце нажмите Alt-F4.
Проблема заключается в следующем. Перед тем как вывести массив на экран в виде растрового изображения - нужно этот массив оформить, то есть рассчитать цвет каждого пиксела, что означает рассчитать значение каждого элемента массива. Рассчитанные значения само собой нужно сохранять в самом массиве. Но размер массива при разрешении экрана 1024*768 точек и цвета TrueColor равен приблизительно 3 МБ и в кэш-память второго уровня не помещается при записи всех элементов. Процессору приходится сохранять массив в оперативную память. Но скорость записи в оперативную память всего 640 МБ / секунда. Это в 30 раз меньше чем скорость записи в кэш-память. Значит при этом теряется время. Избежать лишней записи массива в кэш-память можно поэтапным выводом изображения порциями. В таком случае организуется массив, который бы полностью поместился в кэш-памяти и хранил только 24 строки развертки (прикиньте, у меня на Celeron 4 всего то 128 кб кэша). Этот массив выводится через определенное время на разные учатки экрана той же функцией SetDIBitsToDevice. И тогда эта API-функция не обращается к оперативной памяти за массивом а читает его прямо из кэша. И процессор не будет лишний раз гонять данные в модули памяти и назад. Но в таком случае получается резание изображения. И это хорошо видно при работе демо-программы. Если сразу за один вызов функции выводить все полноэкранное изображение, то резания изображения не происходит. Почему в данном случае изображение режется я в принципе знаю. Но мне нужно избежать этого вредного эффекта и в то же время экономно использовать время ЦП. Я знаю, что есть такой прием. В видеоадаптере организуется как минимум 2 области видеопамяти. А вывод информации происходин на экран только из одной из них, в то время как запись со стороны центрального процессора идет в другую область видеопамяти. Затем, когда процессор запишет в эту другую область памяти изображение, видеоадаптер переключается программно на отображение вновь записанной области видеопамяти, а ЦП теперь начинает писать в первую область видеопамяти. И так повторяется от кадра до кадра. Но я работаю через функцию API. И если созданное для дисплея устройство обрабатывает только одноэкранную матрицу бит, то никак я не могу записать в теневую область данные, поскольку её просто нет в таком случае. Если бы БИТМАП устройства дисплея созданного (устройства) функцией CreateDC("DISPLAY", 0, 0, 0) был больше размера пиксельной матрицы, можно было бы прокручивать изображение функцией ScrollDC. Я пробовал так делать, но результат прокручивания показал, что за границами дисплея битмапа уже не существует. Теперь я не нахожу выхода. -------------------- Тело в нашем пространстве - есть часть пространства, в которой пространство обладает дисторсией относительно внешнего пространства. |
||||
|
|||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 55 Всего: 459 |
sgi1981, Если нужна такая большая скорость, может воспользоваться OpenGl?
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| Snowy |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 11363 Регистрация: 13.10.2004 Где: Питер Репутация: 18 Всего: 484 |
DirectDraw.
Загоняем изображение, как текстуру в видеопамять. Никакой кэш и оперативка нам более не интересны. Даем комманду - рисуй и все. |
|||
|
||||
| sgi1981 |
|
||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 284 Регистрация: 16.3.2006 Репутация: нет Всего: 10 |
Покажи пример вывода массива двойных слов в видеопамять на OpenGl. Добавлено @ 17:43
Нет, мысли об использовании кэш-памяти я оставить в любом случае не могу. По той причине, что я все равно в любом случае задумываюсь о быстродействии. И если я пойму, что этот прием не дает лучшего быстродействия, то я его отброшу. P. S. Никогда не бери пример с дураков, которыми легче управлять.
Мне нужно загонять сформированные участки изображения из небольшого массива в видеопамять. Этот массив формируется в самой программе. Изображение не должно обновляться до тех пор, пока не будут записаны все его части. КАК МНЕ ЭТО СДЕЛАТЬ. Это сообщение отредактировал(а) sgi1981 - 3.4.2006, 17:44 -------------------- Тело в нашем пространстве - есть часть пространства, в которой пространство обладает дисторсией относительно внешнего пространства. |
||||||
|
|||||||
| bems |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3400 Регистрация: 5.1.2006 Репутация: 1 Всего: 88 |
100 кадров в секунду - это (для большинства) предел восприятия. И ни кеш, ни оперативка, ни замена селерона на пентиум не смогут застваить твоего юзера заметить разницу. Зачем тебе 150?
-------------------- Обижено школьников: 8 |
|||
|
||||
| sgi1981 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 284 Регистрация: 16.3.2006 Репутация: нет Всего: 10 |
Ребят, я понимаю что вы читаете и хотите понять... Но FPS=150 мне вовсе не нужно. А про FPS=150 я писал потому, что учитывал скорость вывода уже сформированного массива в видеопамять. В действительности кроме процедуры вывода готового массива должно выполняться формирование массива. Само формирование массива заключается в вычислении значений цвета пикселов. Я должен оценить общее быстродействие. Но общее быстродействие зависит не только от скорости вычисления цветов пикселов, но и от скорости вывода готового массива в видеопамять ! А скорость записи в видеопамять я как раз и оцениваю по скорости копирования кадров без их формирования. Ещё раз поясну другим путем. Я хочу добиться максимальной скорости вывода кадров (максимального FPS) изменяющегося изображения виртуального пространства. Эта скорость зависит от двух составляющих 1) Скорость вычисления элементов массива изображения 2) Скорость вывода этого массива на экран Значит я стремлюсь добиться максимума обеих скоростей. В первом сообщении, где я писал про FPS=150 я оценивал быстродействие второй составляющей общей задачи. То бишь чтобы оценить то насколько быстро копируется готовое изображение на экран, нужно отбросить первую составляющую задачи, чтобы формирование массива не влияло на оценку общей скорости и тогда мы можем принять, что общая скорость равна скорости копирования в видеопамять. Для этого просто многократно копируем один и тот же массив на экран. Тогда мы можем сделать вывод по быстродействию второй составляющей задачи. Теперь понятно ? А теперь кто-нибудь объясните мне, пожалуйста, какие есть функции OpenGL или DirectX для вывода изображения по частям из массива так, чтобы все полноэкранное изображение обновлялось только по моей команде после того как все части его будут выведены, чтобы не происходило "разрезание" изображения. То есть чтобы не было так, что в то время как луч ЭЛТ монитора выводит старый кадр копируется в видеопамять новый, и таким образом часть изображения получится от старого кадра, а остальная часть - от нового. -------------------- Тело в нашем пространстве - есть часть пространства, в которой пространство обладает дисторсией относительно внешнего пространства. |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 55 Всего: 459 |
Ну я думаю без учебника здесь точно не разобраться. А последовательность действй примрно такая.
1)Получение контекста окна. 2)инициализация формата пиксела со свойствами двойной буферизации и режимом - полный экран 3)Установка параметров экрана 3)Подготовка битовой карты - просто перечисляются цвета пикселов слева напаво, сверху вниз. 4)Загрузка текстуры LoadTexture2D (размеры соотв размерам экрана) 5)Рисоватие квадрата с координатами левой нижней и правой верхней (-1,-1), (1,1) с выводом текстуры. SwapBuffers(dc); перересует весь экран p.s. способ Snowy может быть быстрее(я не знаком с DirectDraw) -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: нет Всего: 250 |
Определи что у твоего контекста два буффера и меняй их. (посмотри описание: SetPixelFormat , PIXELFORMATDESCRIPTOR, SwapBuffers) |
|||
|
||||
| p0s0l |
|
|||
![]() Г-н Посол ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 3668 Регистрация: 13.7.2003 Где: 58°38' с.ш. 4 9°41' в.д. Репутация: 16 Всего: 112 |
Если я правильно понял - у тебя каждый пиксел вычисляется по какой-то формуле. Если сможешь это оформить в виде шейдеров, то вычислениями будет заниматься уже видяха, а не проц + не надо перекидывать данные:
http://forum.vingrad.ru/index.php?showtopic=73464 Если же все вычисления сводятся лишь к тому, что надо просто вывести определенный кусок сгенерированной статичной текстуры, то проще их заранее сгенерить и выводить, как сказал Snowy... -------------------- С уважением, г-н Посол. |
|||
|
||||
![]()
|
| Правила форума "Delphi: Звук, графика и видео" | |
|
|
Запрещено: 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делится вскрытыми компонентами
FAQ раздела лежит здесь! Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Girder, Snowy. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |