简体   繁体   English

Direct3D11(C ++):渲染(基本)问题

[英]Direct3D11(C++): Rendering (basic) question

I've been following a book about basics for game programming with D3D11. 我一直在跟随一本关于D3D11游戏编程基础知识的书。 I now understand the absolute basics of Direct3D :) 我现在明白了Direct3D的绝对基础知识:)

but... I have a question. 但是......我有一个问题。 In the book, I always had to make one demo at a time. 在书中,我总是不得不一次制作一个演示。 Now, I'm trying to make a 2D game with it. 现在,我正在尝试用它制作2D游戏。 Since I don't want to get used to bad habits so I need your advice. 因为我不想习惯坏习惯,所以我需要你的建议。

In the book, I always had to define a (struct VertexPos with texcoord and position members) OR (struct VertexPos with only a XMFLOAT3 position member). 在本书中,我总是要定义一个(带有texcoord和位置成员的结构VertexPos)或者(只有一个XMFLOAT3位置成员的结构VertexPos)。 In the game I'm making, I want to be able to draw both solid surfaces without textures and surfaces with textures. 在我正在制作的游戏中,我希望能够绘制没有纹理的固体表面和具有纹理的表面。 I'm not sure how to do this, let alone do this efficiently. 我不确定如何做到这一点,更不用说有效地做到这一点。

Here is my rendering function: 这是我的渲染功能:

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);
}

So, how should I handle this efficiently with multiple vertex buffers, input layouts, Shaders, Blenders, etc? 那么,我应该如何有效地处理多个顶点缓冲区,输入布局,着色器,搅拌器等?

Should I just create multiple versions of those, and then set reset the input assembly, shaders and such after the Draw call? 我应该只创建那些版本的多个版本,然后在Draw调用之后设置重置输入程序集,着色器等吗? Or does this not work/ is this not efficient? 或者这不起作用/这效率不高?

Thanks :) 谢谢 :)

The simple answer is yes, you should create multiple vertex buffers, input layouts, shaders, etc. and set the appropriate ones before each corresponding draw call. 简单的答案是肯定的,您应该创建多个顶点缓冲区,输入布局,着色器等,并在每个相应的绘制调用之前设置适当的顶点缓冲区。 This will work and is reasonably efficient (should be efficient enough for a 2D game on modern hardware). 这将起作用并且相当有效(对于现代硬件上的2D游戏应该足够有效)。

Things tend to get a bit more complicated in a full 3D game engine. 在完整的3D游戏引擎中,事情往往变得复杂一些。 Typically the rendering engine will have some additional internal levels of abstraction layered on top of primitive objects like vertex and index buffers, input layouts, shaders etc. 通常,渲染引擎将在原始对象(如顶点和索引缓冲区,输入布局,着色器等)之上分层设置一些额外的内部抽象级别。

A reasonably common simple way of structuring things is to have a Mesh class which knows about all of the vertex buffers, index buffers, input layouts, shaders, textures, etc. which make up a bit of a 3D model that can be drawn in a single draw call and is responsible for setting them all (often along with other bits of render state like blend modes, culling modes, etc.) and issuing the corresponding draw call. 构造事物的一种相当常见的简单方法是使用一个Mesh类来了解所有顶点缓冲区,索引缓冲区,输入布局,着色器,纹理等等,它们构成了一个可以在单个绘制调用并负责将它们全部设置(通常与渲染状态的其他位一样,如混合模式,剔除模式等)并发出相应的绘制调用。

There is a cost associated with changing any device state and so rendering engines are often designed to try and sort all the objects that need drawing in a particular frame so as to minimize the number of state changes required. 与更改任何设备状态相关联的成本因此,渲染引擎通常被设计为尝试对需要在特定帧中绘制的所有对象进行排序,以便最小化所需的状态改变的数量。 In the Dawn of War 2 renderer for example we sorted all of the mesh geometry so that we could draw eg all of the space marine helmets with minimal state changes required before drawing all of the space marine bodies with different vertex and index buffers, textures, etc. 例如,在战争黎明2渲染器中,我们对所有网格几何体进行了排序,以便在绘制具有不同顶点和索引缓冲区,纹理的所有空间海洋体之前,我们可以绘制所有需要最小状态变化的所有空间海洋头盔。等等

Modern 3D hardware and APIs have somewhat less overhead for changing state than in the past so sorting to minimize state changes is a bit less important than it once was but it is still common practice for games that need to get maximum performance on the PC. 与过去相比,现代3D硬件和API在改变状态方面的开销要小一些,因此排序以最小化状态变化的重要性不如以前那么重要,但对于需要在PC上获得最佳性能的游戏来说,它仍然是常见做法。

In a data driven rendering engine that supports a flexible lighting and material model along with skinned animation, terrain, particle systems, full screen effects, 2D UI, etc. a suitable design for managing all of the state required to draw the game objects and for sorting it so it can be drawn with maximum efficiency can get quite complex and there are many different approaches to structuring things. 在数据驱动的渲染引擎中,支持灵活的照明和材质模型以及蒙皮动画,地形,粒子系统,全屏效果,2D UI等,这是一种合适的设计,用于管理绘制游戏对象所需的所有状态。对它进行排序以便以最高效率绘制可能会变得非常复杂,并且有许多不同的方法来构建事物。 The code for everything that could be classed as 'renderer state management' often makes up a significant portion of the code in a typical rendering engine. 可归类为“渲染器状态管理”的所有内容的代码通常构成典型渲染引擎中代码的重要部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM