4

我一直在关注一本关于使用 D3D11 进行游戏编程的基础知识的书。我现在了解 Direct3D 的绝对基础 :)

但是...我有一个问题。在书中,我总是不得不一次做一个演示。现在,我正在尝试用它制作一个 2D 游戏。因为我不想习惯坏习惯,所以我需要你的建议。

在本书中,我总是必须定义一个(带有 texcoord 和位置成员的结构 VertexPos)或(只有一个 XMFLOAT3 位置成员的结构 VertexPos)。在我正在制作的游戏中,我希望能够绘制没有纹理的实体表面和有纹理的表面。我不确定如何做到这一点,更不用说有效地做到这一点了。

这是我的渲染功能:

void GameSpriteDemo::Render()
{
    if (m_pD3DContext == 0)
    {return;}

    float ClearColor[4] = {0.0f, 0.0f, 0.25f, 1.0f};
    m_pD3DContext->ClearRenderTargetView(m_pBackBufferTarget,ClearColor);

    UINT stride = sizeof(VertexPos);
    UINT offset = 0;

    m_pD3DContext->IASetInputLayout(m_pInputLayout);
    m_pD3DContext->IASetVertexBuffers(0,1,&m_pVertexBuffer, &stride, &offset);
    m_pD3DContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    m_pD3DContext->VSSetShader(m_pSolidColorVS,0,0);
    m_pD3DContext->PSSetShader(m_pSolidColorPS,0,0);
    m_pD3DContext->PSSetShaderResources(0,1,&m_pColorMap);
    m_pD3DContext->PSSetSamplers(0,1,&m_pColorMapSampler);

    for(int i=0; i < 2; ++i)
    {
        XMMATRIX world = m_Sprites[i].GetWorldMatrix();
        XMMATRIX mvp = XMMatrixMultiply( world, m_VpMatrix );
        mvp = XMMatrixTranspose(mvp);

        m_pD3DContext->UpdateSubresource(m_pMvpCB,0,0,&mvp,0,0);
        m_pD3DContext->VSSetConstantBuffers(0,1,&m_pMvpCB);

        m_pD3DContext->Draw(6,0);
    }

    m_pSwapChain->Present(0,0);
}

那么,我应该如何使用多个顶点缓冲区、输入布局、着色器、Blender 等有效地处理这个问题?

我应该只创建多个版本,然后在 Draw 调用之后设置重置输入程序集、着色器等吗?或者这不起作用/这不是有效的吗?

谢谢 :)

4

1 回答 1

4

简单的答案是肯定的,您应该创建多个顶点缓冲区、输入布局、着色器等,并在每个相应的绘图调用之前设置适当的。这将起作用并且相当有效(对于现代硬件上的 2D 游戏应该足够有效)。

在完整的 3D 游戏引擎中,事情往往会变得更加复杂。通常,渲染引擎会在原始对象(如顶点和索引缓冲区、输入布局、着色器等)之上有一些额外的内部抽象级别。

构造事物的一种相当常见的简单方法是有一个 Mesh 类,它知道所有的顶点缓冲区、索引缓冲区、输入布局、着色器、纹理等,它们构成了一个可以绘制在一个 3D 模型中的位单个绘图调用并负责设置它们(通常与其他渲染状态位,如混合模式、剔除模式等)并发出相应的绘图调用。

更改任何设备状态都会产生成本,因此渲染引擎通常被设计为尝试对需要在特定帧中绘制的所有对象进行排序,以最大限度地减少所需的状态更改次数。例如,在《战争黎明 2》渲染器中,我们对所有网格几何体进行了排序,以便我们可以在绘制具有不同顶点和索引缓冲区、纹理、等等

与过去相比,现代 3D 硬件和 API 更改状态的开销要少一些,因此排序以最小化状态更改的重要性不如以前,但对于需要在 PC 上获得最大性能的游戏来说,这仍然是常见做法。

在支持灵活光照和材质模型以及蒙皮动画、地形、粒子系统、全屏效果、2D UI 等的数据驱动渲染引擎中,适合管理绘制游戏对象所需的所有状态以及对其进行排序以便以最高效率绘制它可能会变得非常复杂,并且有许多不同的方法来构建事物。可以归类为“渲染器状态管理”的所有内容的代码通常构成典型渲染引擎中代码的重要部分。

于 2011-09-06T23:11:48.320 回答