2015-10-27 3 views
0

Привет, Я пытаюсь создать 2D-движок на C++, который может обрабатывать тысячи спрайтов одновременно с использованием DirectX, а также SDL. Я слышал, что LPD3DX9Sprite очень эффективен и выходит из XNA, стиль мне очень хорошо знаком. Я выполнял некоторые тесты производительности, одновременно добавляя несколько спрайтов (одинаковые текстуры и настройки). Однако, похоже, некоторые проблемы с производительностью и idk почему.DirectX Game LPD3DX9Sprite Rendering Slow

void Draw() 
{ 

Graphics::direct3D_device->Clear(1, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 0, 0, 0), 0, 0); 
Graphics::direct3D_device->BeginScene(); 

Graphics::SpriteBatch->Begin(D3DXSPRITE_ALPHABLEND); 

string fs = std::to_string(fps); 


for (int i = 0; i < 1000; i++) 
    Test.Draw(); 

DrawTextString(32, 64, fs.c_str()); 

Graphics::SpriteBatch->End(); 

Graphics::direct3D_device->EndScene(); 
Graphics::direct3D_device->Present(NULL, NULL, NULL, NULL); 
} 

Это мой Жеребьевка код это вызывает функцию, которая в основном вызывает DrawMethod объекта LPD3DX9Sprite. В игре больше ничего не происходит, только этот код чертежа.

Согласно счетчику fps, я получаю 4 кадра в секунду. Vsync включен, но замедление происходит независимо. Есть ли что-нибудь, что я могу сделать по этому поводу?

Мне показалось странным, что эта простая тестовая игра на C++ без реальной логики сканирует по сравнению с полным движком игры на C#, который безупречно работает со многими рендерингами спрайтов.

+0

Каково содержимое 'Test.draw();'? – Xirema

+0

Графика :: SpriteBatch-> Draw (Текстура, & SourceRect, & OriginPos, & D3DXVECTOR3 (Position.x, Position.y, 0), Цвет); Я даже не добавляю никаких преобразований для вращения и масштабирования. Просто это. –

ответ

0

Это, вероятно, справедливо сказать, что это преступник:

for (int i = 0; i < 1000; i++) 
    Test.Draw(); 

Наряду с содержанием Test.draw();, которые вы утверждаете, что:

Graphics::SpriteBatch->Draw(Texture, &SourceRect, &OriginPos, &D3DXVECTOR3(Position.x,Position.y,0), Color); 

Несмотря на то, что это относительно простой команды, это довольно дорогостоящая команда, которая должна подталкивать к графической карте сверх-и-over-and-over. Я не знаю основную технику библиотеки, которую вы используете, но когда команды написаны так, она сильно напоминает стиль кодирования в OpenGL1.x, где вершины и текстуры передаются на графическую карту, так как они необходимо, а не предварительно загружать их и просто вызывать команды для рисования предварительно загруженных вершин. Вам нужно выяснить, может ли библиотека загружать эти данные на графическую карту раньше, используя объекты буфера Vertex и другие подобные конструкции.

Если это не так, вам нужно будет самостоятельно изучить и реализовать эти концепции.

также:

Я слышал, что LPD3DX9Sprite очень эффективен ...

Вообще говоря, любая ситуация, когда вы используете DirectX9, по определению, не будет быстрым. Нет, если вы не используете набор функций DX10 и DX11, но в этом случае нет оснований использовать функции DX9 в первую очередь.

+0

Спасибо, я изучу поиск лучшего метода. Я думаю, что на самом деле нелегкий выход. –

+0

'' SpriteBatch'', используя [DirectX Tool Kit] (https://github.com/Microsoft/DirectXTK) для Direct3D 11 - это простой выход. –

0

Обратите внимание, метод ID3DXSprite::Draw не рисует/рендеринга спрайта в screen.It только добавляет спрайт к списку информации sprites.For дозируемой о методах, доступных в интерфейсе ID3DXSprite см это link. Вы должны использовать HRESULT Flush(), чтобы нарисовать все обработанные спрайты.

Так что ваш код должны быть изменены так,

void Draw() 
{ 

Graphics::direct3D_device->Clear(1, NULL, D3DCLEAR_TARGET,D3DCOLOR_ARGB(255, 0, 0, 0), 0, 0); 
Graphics::direct3D_device->BeginScene(); 

Graphics::SpriteBatch->Begin(D3DXSPRITE_ALPHABLEND); 

string fs = std::to_string(fps); 


for (int i = 0; i < 1000; i++) 
{ 
    Test.Draw(); 
} 
Graphics::SpriteBatch->Flush();//Basically call the Flush Method here 
DrawTextString(32, 64, fs.c_str()); 

Graphics::SpriteBatch->End(); 

Graphics::direct3D_device->EndScene(); 
Graphics::direct3D_device->Present(NULL, NULL, NULL, NULL); 
} 

В принципе, вам нужно добавить Graphics::SpriteBatch->Flush(); этот код после for loop.The Flush() метода будет рисовать все пакетные спрайты.

+0

Я рассмотрел описание, и кажется, что Flush(); метод вызывается независимо от того, когда End(); метод. Я также попробовал ваше предложение, но игра все еще работает медленно. –