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

标签 c++ directx rendering direct3d direct3d11

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

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

在书中,我总是必须定义一个(结构 VertexPos 与 texcoord 和位置成员)或(结构 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);
}

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

我是否应该只创建这些版本的多个版本,然后在 Draw 调用之后设置重置输入程序集、着色器等?还是这行不通/效率不高?

谢谢:)

最佳答案

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

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

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

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

与过去相比,现代 3D 硬件和 API 更改状态的开销略有减少,因此排序以最小化状态更改不再像以前那么重要,但对于需要在电脑。

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

关于c++ - Direct3D11(C++) : Rendering (basic) question,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7324471/

相关文章:

c++ - vgasave 中的 D3D 设备

javascript - WebGL 更新动态网格

c++ - 调用 SDL_RenderCopy 时出现异常

c++ - 在 Ubuntu 11.10 中安装所有用于开发的 OpenGL 库

c++ - DirectX11 如何从常量缓冲区中剥离未使用的变量?

c++ - vector 删除无需设置 iter 返回值即可工作

c++ - gametutorials.com 问题和评论 DirectX 教程

java - 绘制缓冲图像时 Java 2D 的性能问题

c++ - 给定一个矩形区域和一组矩形,检查整个区域是否被它们覆盖

C++ 编译器错误 "was not declared in this scope"