嘿我正在尝试用C ++构建一个2D引擎,它可以使用DirectX和SDL一次处理数千个精灵。我听说LPD3DX9Sprite非常高效,来自XNA的风格对我来说非常熟悉。我正在做一些性能测试,一次批处理多个精灵(相同的纹理和设置)。但是,似乎存在性能问题和idk原因。
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);
}
这是我的绘图代码,它调用一个基本上调用LPD3DX9Sprite对象的DrawMethod的函数。除了这个绘图代码,游戏中没有其他任何东西真正发生。
根据fps计数器,我得到4fps。 Vsync已启用但无论如何都会发生减速。我能做些什么吗?
我觉得奇怪的是,与C#中的完整游戏引擎相比,这个C ++中没有真正逻辑的简单测试游戏是爬行的,它可以完美地运行许多精灵渲染。
答案 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);
尽管这是一个相对简单的命令,但是必须一遍又一遍地推送到显卡才是一个非常昂贵的命令。我不知道你正在使用的库的底层机制,但是当命令是这样写的时,它强烈地唤起了OpenGL1.x中的编码风格,其中顶点和纹理被流式传输到显卡,因为它们是需要,而不是预加载它们,只需调用命令来绘制预加载的顶点。您需要研究库是否有能力使用Vertex Buffer Objects和其他类似结构提前将此数据加载到图形卡上。
如果没有,那么您需要自己学习并实施这些概念。
此外:
我听说LPD3DX9Sprite非常有效......
一般来说,根据定义,任何使用DirectX9的情况都不会很快。除非您使用的是DX10和DX11的功能集,否则在这种情况下,首先没有理由使用DX9功能。
答案 1 :(得分:0)
注意,方法ID3DXSprite::Draw
不会将精灵绘制/渲染到屏幕上。它只是将精灵添加到批量精灵列表中。有关界面中可用方法的信息{{1看到这个link。
您必须使用ID3DXSprite
绘制所有已批处理的精灵。
所以你的代码应该像这样修改,
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
方法将绘制所有已批处理的精灵。