Direct3D11(c++):渲染(基础)问题

Direct3D11(C++): Rendering (basic) question

本文关键字:基础 问题 渲染 Direct3D11 c++      更新时间:2023-10-16

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

但是…我有一个问题。在书中,我每次只能制作一个demo。现在,我正尝试着用它制作一款2D游戏。因为我不想习惯坏习惯,所以我需要你的建议。

在本书中,我总是必须定义一个(结构体VertexPos具有texcoord和position成员)或(结构体VertexPos仅具有XMFLOAT3位置成员)。在我所创造的游戏中,我希望能够同时绘制没有纹理的实体表面和带有纹理的表面。我不知道该怎么做,更不用说有效率地做了。

这是我的渲染函数:
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);
}

那么,我应该如何有效地处理这个与多个顶点缓冲区,输入布局,着色器,混合器等?

我应该只是创建这些的多个版本,然后设置重置输入程序集,着色器等绘图调用后?或者这行不通/效率不高?

谢谢:)

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

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

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

改变任何设备状态都是有成本的,所以渲染引擎通常被设计成尝试在特定帧中对所有需要绘制的对象进行排序,以尽量减少所需的状态改变次数。例如,在《战争黎明2》的渲染器中,我们对所有的网格几何结构进行了排序,这样我们就可以在绘制所有具有不同顶点和索引缓冲区、纹理等的空间海洋物体之前,以最小的状态变化绘制所有的空间海洋头盔。

与过去相比,现代3D硬件和api在改变状态方面的开销有所减少,因此排序以最小化状态变化的重要性有所降低,但对于需要在PC上获得最大性能的游戏来说,这仍然是一种常见的做法。

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