Форум программистов, компьютерный форум, киберфорум
DirectX
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/18: Рейтинг темы: голосов - 18, средняя оценка - 4.56
13 / 13 / 0
Регистрация: 09.03.2012
Сообщений: 112

Как ускорить вывод изображения?

03.07.2012, 19:28. Показов 3555. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте уважаемые программисты! Вот я пишу игровой 2D движок на C++ directx9 и то, что у меня получилось сравниваю с американским 2D движком, который тоже написан на C++ directx9. Я просто загружаю из файла png картинку размером 32 на 32 пикселя и много раз вывожу ее на экране. С помощью методов интерфейса ID3DXSprite уменьшаю ее в два раза и каждый кадр вращаю на определенный угол. Также измеряю время вывода картинок на экран. В игре смена кадров происходит 60 раз в секунду. Вся беда в том, что в американском двиге спокойно можно вращать и выводить на экран более 4000 спрайтов, а в моем - только 200, при выводе 300 спрайтов количество смены кадров в секунду падает до 45. Подскажите как мне ускорить вывод изображения и добиться соответствующего результата. Может кто-то уже писал 2D движок и занимался подобным вопросом? Может есть какие-то статьи или книги по этому вопросу?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
03.07.2012, 19:28
Ответы с готовыми решениями:

Ускорить вывод изображения в JLabel
Подскажите, пожалуйста, можно ли каким-то образом ускорить вывод изображения в JLabel. Использую двойную буферизацию, как off-screen буфер...

Как ускорить прорисовку изображения?
Добрый день! Решил написать небольшой просмотрщик изображений на WPF, и столкнулся с такой проблемой, когда загружаю достаточно большое...

Как ускорить отрисовку изображения?
Доброго времени суток. Столкнулся с такой проблемой: Необходимо загрузить инвертированное изображение, обратить цвета (сделать...

15
13 / 13 / 0
Регистрация: 09.03.2012
Сообщений: 112
04.07.2012, 21:18  [ТС]
Вот начал потихоньку разбираться в чем дело. Вывожу определенное количество спрайтов на экран и смотрю сколько это занимает времени. 1 спрайт рисуется за 33 мкс. 10 спрайтов рисуется за 70 мкс. 48 спрайтов рисуется за 220 мкс. Такая скорость меня вполне устраивает, но если я добавляю еще один спрайт и рисую 49, то это уже занимает 2500 мкс. 200 спрайтов выводится за 7200 мкс. Возникает вопрос, почему процедура рисования 49 спрайтов занимает по времени в 10 раз больше, чем прорисовка 48?
0
49 / 49 / 2
Регистрация: 17.07.2011
Сообщений: 318
07.07.2012, 18:27
Как выводите картинки?
Весь секрет в частоте вызова функций рисования и оптимизации изображения.
Если можете сформировать кадр вне функций рисования собрав всё в буфер и за один вызов DrawIndexedPrimitives или хотя бы DrawPrimitives, вот вам и будет максимальная производительность.
А массивы для буфера можно в нескольких потоках формировать, думаю будет летать круче чем у оригинала.
Используйте не особо расточительный формат вершин.
Если хотите спрайтами выводить, собирайте всё в один спрайт и выводите.
1
13 / 13 / 0
Регистрация: 09.03.2012
Сообщений: 112
08.07.2012, 00:23  [ТС]
Цитата Сообщение от danrusm Посмотреть сообщение
Как выводите картинки?
Вот функция, которая создает спрайт с нужными характеристиками
C++
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
//--------------------------------------------------------------------------------------
//  Функция
//  DrawSprite()
//  Выводит спрайт на экран
VOID DrawSprite(LPDIRECT3DTEXTURE9 textura, float X, float Y, float ugol)
{
    sprite->Begin(D3DXSPRITE_ALPHABLEND);
    float scX = 0.5f;//Длина спрайта к1
    float scY = 0.5f;//Ширина спрайта к1
    // Texture being used is 64 by 64:
    float cenX = 16;
    float cenY = 16;
    D3DXVECTOR2 spriteCentre=D3DXVECTOR2(cenX * scX, cenY * scY);
    // Screen position of the sprite
    D3DXVECTOR2 trans=D3DXVECTOR2(X - spriteCentre.x,Y - spriteCentre.y);
    // Rotate based on the time passed
    float rotation=ugol*D3DX_PI/180.0f;
    // Build our matrix to rotate, scale and position our sprite
    D3DXMATRIX mat;
    D3DXVECTOR2 scaling(scX,scY);
    // out, scaling centre, scaling rotation, scaling, rotation centre, rotation, translation
    D3DXMatrixTransformation2D(&mat,NULL,0.0,&scaling,&spriteCentre,rotation,&trans);
    // Tell the sprite about the matrix
    sprite->SetTransform(&mat);
    // Draw the sprite 
    sprite->Draw(textura,NULL,NULL,NULL,0xFFFFFFFF);
    // Thats it
    sprite->End();
}
Потом вывожу определенное количество спрайтов на экран и засекаю время.
C++
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
30
31
32
33
34
35
36
37
38
//-----------------------------------------------------------------------------------
//  Функция
//  RenderingDirect3D()
//  Рисуем в приложении
//-----------------------------------------------------------------------------------
VOID RenderingDirect3D()
{
    
    if(pDirect3DDevice == NULL)     // Проверяем ошибки
     return;
    //Очищаем задний буфер
    pDirect3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );//цвет фона
    
    // Здесь происходит прорисовка сцены
    pDirect3DDevice->BeginScene();// Начало сцены
    //-----------------------------------------------------------------------------------------------
    // Вывод спрайта на экран
    //-----------------------------------------------------------------------------------------------
    start_2 = GetCycleCount();//Засекаем время
    
    for(int i=1; i<=8; i++)
    { 
        
        for(int j=1; j<=6; j++)
        {
            DrawSprite(pTex_k1, 100 + (i*15), 100 + (j*15), ug2);
        }
        
    }
    
    raznost = GetCycleCount() - start_2;//Количество тактов
    microSec = (double)raznost/2310; //Время в микросекундах
    
    pDirect3DDevice->EndScene();//Конец сцены       
    
    pDirect3DDevice->Present( NULL, NULL, NULL, NULL );//Копируем задний буфер в передний
     
}
Но это работает очень медленно.
Цитата Сообщение от danrusm Посмотреть сообщение
Если хотите спрайтами выводить, собирайте всё в один спрайт и выводите.
Я так понимаю мне нужно взять спрайт размеры которого равны размерам окна, потом скопировать в этот спрайт все остальные спрайты и выводить только один спрайт. Я правильно понял?
0
49 / 49 / 2
Регистрация: 17.07.2011
Сообщений: 318
08.07.2012, 09:29
Ваш вывод тормозят вызовы begin end, уберите их в отдельные функции
C++
1
2
3
4
5
6
Sprite->Begin();
for(.....)
{
   //LoadAllSprite
}
Sprite-End();
Так же можно передавать параметры очистки и сёрфэйс спрайта, чтоб не перерисовывать весь кадр, а только изменившуюся часть.
В общем порядок такой, открыл рендер --- запихнул всё в память --- нарисовал.
Если хочешь ещё быстрее, создай условия в которых между бегин и енд нет цикла, как варриант это объединение спрайтов и использование многопоточной обработки, пока один поток рисует, второй уже готовит очередной кадр и т.д. или компоновку одного спрайта из нескольких сделать в несколько потоков, в общем поле деятельности большое.
1
13 / 13 / 0
Регистрация: 09.03.2012
Сообщений: 112
08.07.2012, 22:17  [ТС]
Цитата Сообщение от danrusm Посмотреть сообщение
Ваш вывод тормозят вызовы begin end, уберите их в отдельные функции
C++
1
2
3
4
5
6
Sprite->Begin();
for(.....)
{
* *//LoadAllSprite
}
Sprite-End();
Спасибо друг, это как раз то решение, которое мне нужно, теперь у меня спокойно выводится более 4000 спрайтов как в игровом двиге, проблема решена.
0
49 / 49 / 2
Регистрация: 17.07.2011
Сообщений: 318
09.07.2012, 18:16
Цитата Сообщение от The special one Посмотреть сообщение
Спасибо друг, это как раз то решение, которое мне нужно, теперь у меня спокойно выводится более 4000 спрайтов как в игровом двиге, проблема решена.
Всегда пожалуйста.
Кстати есть настройки по выводу, можно рисовать чаще чем обновляется экран, только незачем, у тебя затык был потому что по дефаулту между вызовами begin 60 миллисек.
1
13 / 13 / 0
Регистрация: 09.03.2012
Сообщений: 112
09.07.2012, 22:27  [ТС]
Цитата Сообщение от danrusm Посмотреть сообщение
у тебя затык был потому что по дефаулту между вызовами begin 60 миллисек.
Теперь ясно. Может 60 микросекунд?
0
49 / 49 / 2
Регистрация: 17.07.2011
Сообщений: 318
10.07.2012, 07:38
Точно, перепутал, 60 кадров в секунду.
1
13 / 13 / 0
Регистрация: 09.03.2012
Сообщений: 112
10.07.2012, 13:39  [ТС]
60 кадров в секунду - 16.7 миллисекунд. А как изменить время обновления экрана?
0
49 / 49 / 2
Регистрация: 17.07.2011
Сообщений: 318
10.07.2012, 19:08
Это имеет смысл только если обновление моника выше, скажем 100 герц.
А сама настройка PresentParameters.PresentInterval.
1
13 / 13 / 0
Регистрация: 09.03.2012
Сообщений: 112
11.07.2012, 15:02  [ТС]
Вот отх...л (отработал) 12 часов на смене, пришел домой уставший, начал искать и ничего найти не могу. Подскажите что нужно написать и куда вставить, чтоб установить частоту обновления экрана, например, 20, 100, 387, 1015 кадров в секунду. Можно ли? Не спрашивайте зачем, просто надо и все.
0
49 / 49 / 2
Регистрация: 17.07.2011
Сообщений: 318
11.07.2012, 18:06
При заполнении структуры D3DPRESENT_PARAMETERS укажи параметр PresentationInterval.
Знаю default - 60 кадров в секунду и immediate - максимально возможное количество кадров(зависит от нагрузки, то есть максимальная производительность).

Добавлено через 19 минут
Ты можешь варировать между максимумом и 1 кадром через таймер, других вариантов нет.
1
13 / 13 / 0
Регистрация: 09.03.2012
Сообщений: 112
11.07.2012, 18:26  [ТС]
Спасибо, с этим вопросом я полностью разобрался.
0
117 / 75 / 5
Регистрация: 15.03.2012
Сообщений: 259
12.07.2012, 16:22
Хочу напомнить, что система Windows 7 (как впрочем все виндусы серии Windows 1...2....3...3.11...95...98...и тд), в отличии от Windows CE, QNX и пр, не является операционной системой реального времени. Что это это значит? А то, что в данной операционной системе таймер не может работать чаще 50..60 МИЛИСЕКУНД, тоесть практический точнее одной двадцатой секунды Вам замерить не удастся. Откуда цифры? Оттуда, что в своё время занимался программированием серво контроллеров в робототехнике, там всё управлялось TTL сигналами с длинной импульса 5 МИКРОСЕКУНД и управлялось всё при помощи ШИМ (широтно импульсной модуляции). Так вот, пытался сварганить на Windows управляемый генератор импульсов, варганил варганил и долго не мог понять, почему роботы дёргаются не понятно и всё время по разному, хотя в функции SetTimer я вводил интервал в 5 микросекунд....Ну что я могу сказать, оценил ситуацию на осциллографе и вот как раз оттуда после не хитрых измерений и вышли эти пределы точности Windows в 50...60 миллисекунд. Так что ребята, все ваши измерения FPS в 4000 на Windows 7 - это всё бутафория, а точнее не более чем набор примерно случайных чисел. Думаю, что в зависимости от таймеров в самих чипах на материнской плате цифра может варьироваться в пределах 10 миллисекунд но не более. Лично мне пришлось покупать в комп доп плату широтно импульсной модуляции со счётчиками таймерами и уже оперировать ими. Ладно....долго рассказывать......вот так.
0
49 / 49 / 2
Регистрация: 17.07.2011
Сообщений: 318
12.07.2012, 18:56
Цитата Сообщение от -=MASTER=- Посмотреть сообщение
Хочу напомнить, что система Windows 7 (как впрочем все виндусы серии Windows 1...2....3...3.11...95...98...и тд), в отличии от Windows CE, QNX и пр, не является операционной системой реального времени. Что это это значит? А то, что в данной операционной системе таймер не может работать чаще 50..60 МИЛИСЕКУНД, тоесть практический точнее одной двадцатой секунды Вам замерить не удастся. Откуда цифры? Оттуда, что в своё время занимался программированием серво контроллеров в робототехнике, там всё управлялось TTL сигналами с длинной импульса 5 МИКРОСЕКУНД и управлялось всё при помощи ШИМ (широтно импульсной модуляции). Так вот, пытался сварганить на Windows управляемый генератор импульсов, варганил варганил и долго не мог понять, почему роботы дёргаются не понятно и всё время по разному, хотя в функции SetTimer я вводил интервал в 5 микросекунд....Ну что я могу сказать, оценил ситуацию на осциллографе и вот как раз оттуда после не хитрых измерений и вышли эти пределы точности Windows в 50...60 миллисекунд. Так что ребята, все ваши измерения FPS в 4000 на Windows 7 - это всё бутафория, а точнее не более чем набор примерно случайных чисел. Думаю, что в зависимости от таймеров в самих чипах на материнской плате цифра может варьироваться в пределах 10 миллисекунд но не более. Лично мне пришлось покупать в комп доп плату широтно импульсной модуляции со счётчиками таймерами и уже оперировать ими. Ладно....долго рассказывать......вот так.
Да какие проблемы, тиками мерить будем.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
12.07.2012, 18:56
Помогаю со студенческими работами здесь

Как ускорить отрисовку изображения на PictureBox
Может кто знает как можно ускорить отрисовку загруженного изображения в PictureBox, (изображение довольно таки большое 1500х1500 и выше)...

Построение иерарх. дерева на основе существующей БД. Как ускорить вывод данных.
Есть БД в которой заложен вывод данных в иерархическом виде (1С) т.е. там есть ID и ParentID (вхождение в ветвь). Мне нужно вывести...

Преобразование изображения: ускорить работу кода
Добрый. Как можно ускорить следующий код? Мне необходимо конвертировать определенный цвет в пространстве RGB в пространство LAB. Я хочу...

Как сделать эту программы ввод/вывод через sys.stdin? Хочу ускорить. В C++ это очень хорошо ускоряет?
h = {} i = 0 for _ in range(int(input())): # считывает количества списков s = input() # удаляет первое число в строке s =...

Ускорить вывод в RichEdit
Я генерирую миллион значений Все значения вывожу в поток: osftream p(&quot;text.txt&quot;); for(i=0; i &lt; 1000000; i++) { p &lt;&lt;...


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

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru