dx11学习笔记-2.用DX画一个三角形

上一篇所介绍的流程是每个DX程序初始化的必需代码,运行代码可以得到一个空窗口。下面我们就开始在这个窗口上画点东西。正如学编程语言都是从hello world开始,学图形学一般都是从画三角形开始,之前学OPENGL是这样。而MS的官方教程中,Tutorial02就渲染了一个三角形。
这里写图片描述

基本流程

新增变量
ID3D11VertexShader* g_pVertexShader = NULL;
ID3D11PixelShader* g_pPixelShader = NULL;
ID3D11InputLayout* g_pVertexLayout = NULL;
ID3D11Buffer* g_pVertexBuffer = NULL;

从DX10开始,固定管线被完全移除,取而代之的是各种着色器。最基本的两种着色器,顶点着色器和像素着色器,是渲染一个图形所必备的。
顶点着色器,顾名思义,是对于用户定义的顶点进行变换操作,是渲染管线的入口;像素着色器则是对顶点所划出的区域,进行逐像素操作。
如果程序中只包含这两种着色器,那么像素着色器的输入,将直接来自于顶点着色器的输出。

顶点:vertex,不同于点point。它包含了更多信息,其中最基本的,也是必需的信息,就是顶点位置。所以我们定义一个顶点结构体,先把最基本的位置信息作为其内部成员。
struct Vertex
{ XMFLOAT3 pos;};

XM-XNA Math库,DX11中应用的数学库。在dx之前的版本中,用的是D3DXVECTOR3,和XMFLOAT3所代表的结构相同。

1、创建并设置顶点缓存

输入顶点着色器的,需要是一块顶点缓存。dx11中若要创建顶点缓存,需要告知缓存的描述信息(D3D11_BUFFER_DESC),缓存的填充数据(D3D11_SUBRESOURCE_DATA)。
缓存描述信息中描述了该缓存的用途(BIND VERTEX),该缓存的大小(sizeof(Vertex)*顶点数量);
缓存的填充数据,就是将我们定义的顶点数组赋给其pSysMem成员完成数据绑定。
最后调用device的CreateBuffer方法,将以上二者和我们想得到的g_pVertexBuffer 地址传入。
创建成功后,context调用IASetVertexBuffers方法来设置顶点缓存。
此外,还需要设置顶点的拓扑结构,context调用IASetPrimitiveTopology方法。
所谓拓扑结构就是几何物体与其自身相连接的固有属性。

代码示例:

    //InitDevice函数
    //新增代码
    //缓存信息描述
    D3D11_BUFFER_DESC bd;
    ZeroMemory( &bd, sizeof(bd) );
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.ByteWidth = sizeof( Vertex ) * 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 );

    // 设置顶点缓存
    UINT stride = sizeof( SimpleVertex );
    UINT offset = 0;
    g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );

    // 设置顶点的拓扑组织结构(三角形列表、三角形扇、三角形条带…)
    g_pImmediateContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
2、创建着色器,完成输入装配

一般着色器的创建流程就两步:1、编译着色器代码片;2、根据编译得到的缓存数据创建着色器并保存。
而顶点着色器作为渲染管线的入口,还承担着接收原始输入信息的任务。所以在创建完着色器之后,我们还需要完成输入装配(Input layout)。也就是告诉顶点着色器我们输入数据的组织形式,这样着色器才知道该怎样调用输入的一堆数据。
编译步骤,需要指明着色器文件路径,着色器的入口函数名称,着色器解释模型。

代码示例:

    //CompileShaderFromFile函数
HRESULT CompileShaderFromFile( WCHAR* szFileName, LPCSTR szEntryPoint, LPCSTR szShaderModel, ID3DBlob** ppBlobOut )
{
    HRESULT hr = S_OK;
    //D3DCOMPILE_ENABLE_STRICTNESS:禁止过时的语法
    DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS;
#if defined( DEBUG ) || defined( _DEBUG )
    dwShaderFlags |= D3DCOMPILE_DEBUG;//编译着色器时加入调试信息
#endif

    ID3DBlob* pErrorBlob;
    hr = D3DX11CompileFromFile( szFileName, NULL, NULL, szEntryPoint, szShaderModel, 
        dwShaderFlags, 0, NULL, ppBlobOut, &pErrorBlob, NULL );
    if( FAILED(hr) )
    {
        if( pErrorBlob != NULL )
            OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() );
        if( pErrorBlob ) pErrorBlob->Release();
        return hr;
    }
    if( pErrorBlob ) pErrorBlob->Release();

    return S_OK;
}


    // InitDevice函数
    // 新增代码
    ID3DBlob* pVSBlob = NULL;
    // 编译vertex shader代码文件
    hr = CompileShaderFromFile( L"Tutorial02.fx", "VS", "vs_4_0", &pVSBlob );
    if( FAILED( hr ) )
    {
        // 处理错误...
        return hr;
    }

    // 创建 vertex shader
    hr = g_pd3dDevice->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &g_pVertexShader );
    if( FAILED( hr ) )
    {   
        pVSBlob->Release();
        return hr;
    }   

    // 编译 pixel shader代码文件
    ID3DBlob* pPSBlob = NULL;
    hr = CompileShaderFromFile( L"Tutorial02.fx", "PS", "ps_4_0", &pPSBlob );
    if( FAILED( hr ) )
    {
        // 处理错误...
        return hr;
    }

    // 创建 pixel shader
    hr = g_pd3dDevice->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &g_pPixelShader );
    pPSBlob->Release();
    if( FAILED( hr ) )
        return hr;

    // 定义input layout
    D3D11_INPUT_ELEMENT_DESC layout[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };
    // 此处numElements=1
    UINT numElements = ARRAYSIZE( layout );

    // 创建 input layout
    hr = g_pd3dDevice->CreateInputLayout( layout, numElements, pVSBl
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值