现在的位置: 首页 > 综合 > 正文

Directx11 HelloWorld之简单三角形绘制

2019年04月18日 ⁄ 综合 ⁄ 共 5530字 ⁄ 字号 评论关闭

  学习SDK,在d3d11中进行简单的三角形绘制,以此熟悉Direct11的绘制流程。此文参考上一篇的Directx11的基本Demo。

  相对Directx11的basic demo,在Directx11中绘制一个三角形,初始化的工作主要是在InitDevice()中1:创建一个顶点着色器Vertex Shader;2:描述我们自己的顶点格式D3D11_INPUT_ELEMENT_DESC;3:创建像素着色器Pixel Shader;4:描述,创建存储我们要绘制的顶点的buffer并绑定其到pipeline。

  然后在Render部分1:指定我们要调用的像素着色器和顶点着色器;2:调用Draw()。

  下面来详细描述其在InitDevice()中的初始化工作。

HRESULT InitDevice()

{

 //======================

//之前讨论的InitDevice的基本初始化工作,主要利用D3D11CreateDeviceAndSwapChain()创建IDXGISwapChain,ID3D11Device,ID3D11DeviceContext;

……………………………………………………

//=======================

    //下面开始初始化基本顶点绘制的工作。/

    //(1)创建一个顶点着色器 

    //(1.1)先通过函数D3DX11CompileFromFile()编译fx文件中的vertex shader代码,将编译好的二进制代码存在ID3DBlob*中。

    ID3DBlob* vErrorBlob;

    ID3DBlob* pVSBlob = NULL;

    hr = D3DX11CompileFromFile( L"Basic.fx", NULL, NULL, "VS", "vs_4_0", 

    dwShaderFlags, 0, NULL, &pVSBlob, &vErrorBlob, NULL );

 

    //(1.2)通过ID3D11Device::CreateVertexShader(),利用编译好的shader代码创建vertex shader

    hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL,          &g_pVertexShader );

 

 

    //2利用D3D11_INPUT_ELEMENT_DESC来描述我们自己的顶点格式(非常类似于D3d9的D3DVERTEXELEMENT9)。接着将顶点格式绑定到pipeline和激活这个顶点格式等初始化工作。参考D3d的SDK:D3D11_INPUT_ELEMENT_DESC就是:A description of a single element for the input-assembler stage。下面来详细看下代码。

    //(2.1) 定义输入的顶点格式D3D11_INPUT_ELEMENT_DESC 

    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
 UINT numElements = ARRAYSIZE( layout );

    //(2.2) 然后创建一个描述上面顶点格式的接口interface:ID3D11InputLayout 。(ps:不知道这样解释对不对,SDK上的解释是D3D11InputLayout:An input-layout interface accesses the input data for the input-assembler stage)

   hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(),
                                          pVSBlob->GetBufferSize(), &g_pVertexLayout );

   //顶点着色器的代码已经完成它的功能,释放它。

    pVSBlob->Release();

    //(2.3) 调用IASetInputLayout将上面创建好的ID3DInputLayout绑定到input-assembler阶段。(不理解input-assembler阶段可以查阅SDK的解释,或者看我最后面的附录)

    g_pImmediateContext->IASetInputLayout( g_pVertexLayout );

   //3:创建一个像素着色器

   //(3.1)和顶点着色器类似,先通过函数D3DX11CompileFromFile()编译fx文件中的pixel shader代码,将编译好的二进制代码存在ID3DBlob*中。

 

    ID3DBlob* pErrorBlob;

    ID3DBlob* PSBlob = NULL;

    hr = D3DX11CompileFromFile( L"Basic.fx", NULL, NULL, "PS", "ps_4_0", 

    dwShaderFlags, 0, NULL, &PSBlob, &pErrorBlob, NULL );

 

 

   //(3.2)通过ID3D11Device::CreatePixelShader(),利用编译好的pixel shader代码创建pixel shader

   hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader );

   //释放shader代码的存储空间
   pPSBlob->Release();

 

  //4:创建用来储存我们要绘制的顶点的buffer

 //(4.1)定义我们所理解(C++所理解)的顶点结构,这里主要position。并创建一个数组具体描述几个顶点。

struct SimpleVertex
{
    XMFLOAT3 Pos;
};
     SimpleVertex vertices[] =
    {
        XMFLOAT3( 0.0f, 0.5f, 0.5f ),
        XMFLOAT3( 0.5f, -0.5f, 0.5f ),
        XMFLOAT3( -0.5f, -0.5f, 0.5f ),
    };

   //(4.2)描述并创建缓存ID3D11Buffer,来存储我们的顶点。我们要用D3D11_BUFFER_DESC和D3D11_SUBRESOURCE_DATA分别描述我们要创建的ID3D11Buffer。
    D3D11_BUFFER_DESC bd;
   ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( SimpleVertex ) * 3;
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    D3D11_SUBRESOURCE_DATA InitData;
    ZeroMemory( &InitData, sizeof(InitData) );
    InitData.pSysMem = vertices;
    hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );

 

  //(4.3)用ID3D11DeviceContext::IASetVertexBuffers()设定我们上面定义的顶点缓存不知道这样说对不对,SDK上的说法:Bind an array of vertex buffers to the input-assembler stage)。

    UINT stride = sizeof( SimpleVertex );
    UINT offset = 0;
    g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );

 

    // 5:设置我们顶点间的拓扑结构。

    g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );

}

 

剩下的步骤到了周期性调用的Render()函数中了。

void Render()
{
    // Clear the back buffer
    float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; // red,green,blue,alpha
    g_pImmediateContext->ClearRenderTargetView( g_pRenderTargetView, ClearColor );

    // 给device指定顶点着色器

 g_pImmediateContext->VSSetShader( g_pVertexShader, NULL, 0 );

   //给device指定像素着色器
 g_pImmediateContext->PSSetShader( g_pPixelShader, NULL, 0 );
    g_pImmediateContext->Draw( 3, 0 );

    // Present the information rendered to the back buffer to the front buffer (the screen)
    g_pSwapChain->Present( 0, 0 );
}

 

  上面就是我对在D3d11中简单绘制的流程总结了。最后附带下Input-Assembler Stage的官方解释,虽然是D3d10的但是11的也差不多。

  Input-Assembler Stage (Direct3D 10)

  The Direct3D 10 API separates functional areas of the pipeline into stages; the first stage in the pipeline is the input-assembler (IA) stage.

  The purpose of the input-assembler stage is to read primitive data (points, lines and/or triangles) from user-filled buffers and assemble the data into primitives that will be used by the other pipeline stages. The IA stage can assemble vertices into several different primitive types (such as line lists, triangle strips, or primitives with adjacency). New primitive types (such as a line list with adjacency or a triangle list with adjacency) have been added to support the geometry shader.

  There are a few steps necessary to initialize the input-assembler (IA) stage. For example, you need to create buffer resources with the vertex data that the pipeline needs, tell the IA stage where the buffers are and what type of data they contain, and specify the type of primitives to assemble from the data.

The basic steps involved in setting up the IA stage, shown in the following table, are covered in this topic.

Step Description
Create Input Buffers Create and initialize input buffers with input vertex data.
Create the Input-Layout Object Define how the vertex buffer data will be streamed into the IA stage by using an input-layout object.
Bind Objects to the Input-Assembler Stage Bind the created objects (input buffers and the input-layout object) to the IA stage.
Specify the Primitive Type Identify how the vertices will be assembled into primitives.
Call Draw Methods Send the data bound to the IA stage through the pipeline.

 

抱歉!评论已关闭.