我试图写一个OpenGL的包装,让我用我所有的现有的图形代码(OpenGL的书面)和将路由OpenGL调用到Direct3D的等价物。 这工作得非常好,到目前为止,除了性能转向了相当的问题。
现在,我承认我是最有可能使用D3D在某种程度上,它从未被设计。 我更新一个顶点缓冲数千每循环渲染时间。 每次我画一个“雪碧”我送4个顶点到GPU纹理坐标等,并在“精灵”的屏幕上一次的数量就会达到接近1K到1.5K,那么我的应用程序的FPS下降到下面10fps的。
使用VS2012性能分析(这是真棒,顺便说一句),我可以看到ID3D11DeviceContext->绘制方法占用了大量的时间: 截图这里
有没有我不使用正确,而Draw方法中设置自己的顶点缓冲,或一些设置? 是不是真的,真不好可以用我所有的精灵相同顶点缓冲? 如果是这样,还有什么其他可以怎么做,不会彻底改变我现有的图形代码库的架构(其围绕的OpenGL模式建...发送一切交给GPU每帧!)
在我的游戏最大的FPS凶手是当我展示了很多在屏幕上的文字。 每个字符是有纹理的四通道,并且每一个都需要单独的更新到顶点缓冲器和一个单独的呼叫绘制。 如果D3D或硬件不喜欢多次调用绘制,然后还能怎么你一次绘制大量的文字在屏幕上的?
让我知道如果有任何你想看到帮我诊断此问题的详细代码。
谢谢!
下面是我在其上运行的硬件:
- 酷睿i7 3.5GHz的@
- 的RAM 16场演唱会
- 的GeForce GTX 560钛
这里就是我中运行的软件:
- Windows 8的发布预览
- VS 2012
- DirectX 11的
下面是绘制方法:
void OpenGL::Draw(const std::vector<OpenGLVertex>& vertices)
{
auto matrix = *_matrices.top();
_constantBufferData.view = DirectX::XMMatrixTranspose(matrix);
_context->UpdateSubresource(_constantBuffer, 0, NULL, &_constantBufferData, 0, 0);
_context->IASetInputLayout(_inputLayout);
_context->VSSetShader(_vertexShader, nullptr, 0);
_context->VSSetConstantBuffers(0, 1, &_constantBuffer);
D3D11_PRIMITIVE_TOPOLOGY topology = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
ID3D11ShaderResourceView* texture = _textures[_currentTextureId];
// Set shader texture resource in the pixel shader.
_context->PSSetShader(_pixelShaderTexture, nullptr, 0);
_context->PSSetShaderResources(0, 1, &texture);
D3D11_MAPPED_SUBRESOURCE mappedResource;
D3D11_MAP mapType = D3D11_MAP::D3D11_MAP_WRITE_DISCARD;
auto hr = _context->Map(_vertexBuffer, 0, mapType, 0, &mappedResource);
if (SUCCEEDED(hr))
{
OpenGLVertex *pData = reinterpret_cast<OpenGLVertex *>(mappedResource.pData);
memcpy(&(pData[_currentVertex]), &vertices[0], sizeof(OpenGLVertex) * vertices.size());
_context->Unmap(_vertexBuffer, 0);
}
UINT stride = sizeof(OpenGLVertex);
UINT offset = 0;
_context->IASetVertexBuffers(0, 1, &_vertexBuffer, &stride, &offset);
_context->IASetPrimitiveTopology(topology);
_context->Draw(vertices.size(), _currentVertex);
_currentVertex += (int)vertices.size();
}
这里是创建顶点缓冲的方法:
void OpenGL::CreateVertexBuffer()
{
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.ByteWidth = _maxVertices * sizeof(OpenGLVertex);
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_FLAG::D3D11_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
bd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA initData;
ZeroMemory(&initData, sizeof(initData));
_device->CreateBuffer(&bd, NULL, &_vertexBuffer);
}
这里是我的顶点着色器的代码:
cbuffer ModelViewProjectionConstantBuffer : register(b0)
{
matrix model;
matrix view;
matrix projection;
};
struct VertexShaderInput
{
float3 pos : POSITION;
float4 color : COLOR0;
float2 tex : TEXCOORD0;
};
struct VertexShaderOutput
{
float4 pos : SV_POSITION;
float4 color : COLOR0;
float2 tex : TEXCOORD0;
};
VertexShaderOutput main(VertexShaderInput input)
{
VertexShaderOutput output;
float4 pos = float4(input.pos, 1.0f);
// Transform the vertex position into projected space.
pos = mul(pos, model);
pos = mul(pos, view);
pos = mul(pos, projection);
output.pos = pos;
// Pass through the color without modification.
output.color = input.color;
output.tex = input.tex;
return output;
}