DirectX 游戏 LPD3DX9Sprite 渲染缓慢
Posted
技术标签:
【中文标题】DirectX 游戏 LPD3DX9Sprite 渲染缓慢【英文标题】:DirectX Game LPD3DX9Sprite Rendering Slow 【发布时间】:2015-10-27 16:17:32 【问题描述】:嘿,我正在尝试用 C++ 构建一个 2D 引擎,它可以同时使用 DirectX 和 SDL 处理数千个精灵。我听说 LPD3DX9Sprite 非常高效,来自 XNA 的风格对我来说非常熟悉。我正在做一些性能测试,一次批处理多个精灵(相同的纹理和设置)。但是,性能和原因似乎存在一些问题。
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。垂直同步已启用,但无论如何都会出现减速。对此我能做些什么吗?
我觉得奇怪的是,与一个完整的 C# 游戏引擎相比,这个没有真正逻辑的简单 C++ 测试游戏是在爬行。
【问题讨论】:
Test.draw();
的内容是什么?
Graphics::SpriteBatch->Draw(Texture, &SourceRect, &OriginPos, &D3DXVECTOR3(Position.x,Position.y,0), Color);我什至还没有为旋转和缩放添加任何变换。就是这个。
【参考方案1】:
可以说这是罪魁祸首:
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 功能。
【讨论】:
谢谢,我会寻找更好的方法。我想真的没有一个简单的出路。SpriteBatch
在 Direct3D 11 中使用 DirectX Tool Kit 是最简单的方法。【参考方案2】:
注意,ID3DXSprite::Draw
方法不会将精灵绘制/渲染到屏幕上。它只是将精灵添加到批处理精灵列表中。有关接口ID3DXSprite
中可用方法的信息,请参阅@987654321 @。
您必须使用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);
基本上,您需要在for
循环之后添加Graphics::SpriteBatch->Flush();
这段代码。然后Flush()
方法将绘制所有批处理的精灵。
【讨论】:
我查看了描述,似乎 Flush();无论 End() 何时调用方法;方法被调用。我也尝试了您的建议,但游戏仍然运行缓慢。以上是关于DirectX 游戏 LPD3DX9Sprite 渲染缓慢的主要内容,如果未能解决你的问题,请参考以下文章