DirectX11(三)

渲染流水线的各个阶段

这里写图片描述

必须初始化的3个组件

ID3D11Device(设备):该设备包含创建资源的方法
ID3D11DeviceContext(上下文):主要用于在缓冲区执行渲染
IDXGISwapChain(交换链):将后台缓存与前台缓存交换,在显示器上显示

创建目标视图和深度模板视图

    assert(m_pImmediateContext);
    assert(m_pd3dDevice);
    assert(m_pSwapChain);

    ReleaseCOM(m_pRenderTargetView);
    ReleaseCOM(m_pDepthStencilView);
    ReleaseCOM(m_pDepthStencil);

    //创建渲染目标视图
    HR(m_pSwapChain->ResizeBuffers(1, m_Width, m_Height, DXGI_FORMAT_R8G8B8A8_UNORM, 0));
    ID3D11Texture2D* backBuffer;
    HR(m_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&backBuffer)));
    HR(m_pd3dDevice->CreateRenderTargetView(backBuffer, 0, &m_pRenderTargetView));
    ReleaseCOM(backBuffer);

    //深度模板视图
    D3D11_TEXTURE2D_DESC depthStencilDesc;

    depthStencilDesc.Width = m_Width;
    depthStencilDesc.Height = m_Height;
    depthStencilDesc.MipLevels = 1;
    depthStencilDesc.ArraySize = 1;
    depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    depthStencilDesc.SampleDesc.Count = 1;
    depthStencilDesc.SampleDesc.Quality = 0;
    depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
    depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    depthStencilDesc.CPUAccessFlags = 0;
    depthStencilDesc.MiscFlags = 0;

    HR(m_pd3dDevice->CreateTexture2D(&depthStencilDesc, 0, &m_pDepthStencil));
    HR(m_pd3dDevice->CreateDepthStencilView(m_pDepthStencil, 0, &m_pDepthStencilView));

    m_pImmediateContext->OMSetRenderTargets(1, &m_pRenderTargetView, m_pDepthStencilView);

    //设置视口
    m_ScreenViewport.TopLeftX = 0;
    m_ScreenViewport.TopLeftY = 0;
    m_ScreenViewport.Width = static_cast<float>(m_Width);
    m_ScreenViewport.Height = static_cast<float>(m_Height);
    m_ScreenViewport.MinDepth = 0.0f;
    m_ScreenViewport.MaxDepth = 1.0f;

    m_pImmediateContext->RSSetViewports(1, &m_ScreenViewport);

创建顶点布局

const D3D11_INPUT_ELEMENT_DESC InputLayoutDesc::Basic32[3] =
{
    { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};

ID3D11InputLayout* InputLayouts::Basic32 = 0;

void InputLayouts::InitAll(ID3D11Device* device)
{
    D3DX11_PASS_DESC passDesc;
    Effects::FX->Light1TexTech->GetPassByIndex(0)->GetDesc(&passDesc);
    HR(device->CreateInputLayout(InputLayoutDesc::Basic32, 3, passDesc.pIAInputSignature,
        passDesc.IAInputSignatureSize, &Basic32));
}

创建顶点和索引

Vertex::Basic32 v[24];

    float w2 = 1.0f*1;
    float h2 = 1.0f*1;
    float d2 = 1.0f*1;

    v[0] = { { -w2, -h2, -d2 }, { 0.0f, 0.0f, -1.0f }, { 0.0f, 1.0f } };
    v[1] = { { -w2, +h2, -d2 }, { 0.0f, 0.0f, -1.0f }, { 0.0f, 0.0f } };
    v[2] = { { +w2, +h2, -d2 }, { 0.0f, 0.0f, -1.0f }, { 1.0f, 0.0f } };
    v[3] = { { +w2, -h2, -d2 }, { 0.0f, 0.0f, -1.0f }, { 1.0f, 1.0f } };

    // Fill in the back face vertex data.
    v[4] = { { -w2, -h2, +d2 }, { 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f } };
    v[5] = { { +w2, -h2, +d2 }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f } };
    v[6] = { { +w2, +h2, +d2 }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 0.0f } };
    v[7] = { { -w2, +h2, +d2 }, { 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f } };

    // Fill in the top face vertex data.
    v[8] = { { -w2, +h2, -d2 }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 1.0f } };
    v[9] = { { -w2, +h2, +d2 }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f } };
    v[10] = { { +w2, +h2, +d2 }, { 0.0f, 1.0f, 0.0f }, { 1.0f, 0.0f } };
    v[11] = { { +w2, +h2, -d2 }, { 0.0f, 1.0f, 0.0f }, { 1.0f, 1.0f } };

    // Fill in the bottom face vertex data.
    v[12] = { { -w2, -h2, -d2 }, { 0.0f, -1.0f, 0.0f }, { 1.0f, 1.0f } };
    v[13] = { { +w2, -h2, -d2 }, { 0.0f, -1.0f, 0.0f }, { 0.0f, 1.0f } };
    v[14] = { { +w2, -h2, +d2 }, { 0.0f, -1.0f, 0.0f }, { 0.0f, 0.0f } };
    v[15] = { { -w2, -h2, +d2 }, { 0.0f, -1.0f, 0.0f }, { 1.0f, 0.0f } };

    // Fill in the left face vertex data.
    v[16] = { { -w2, -h2, +d2 }, { -1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f } };
    v[17] = { { -w2, +h2, +d2 }, { -1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f } };
    v[18] = { { -w2, +h2, -d2 }, { -1.0f, 0.0f, 0.0f }, { 1.0f, 0.0f } };
    v[19] = { { -w2, -h2, -d2 }, { -1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f } };

    // Fill in the right face vertex data.
    v[20] = { { +w2, -h2, -d2 }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f } };
    v[21] = { { +w2, +h2, -d2 }, { 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f } };
    v[22] = { { +w2, +h2, +d2 }, { 1.0f, 0.0f, 0.0f }, { 1.0f, 0.0f } };
    v[23] = { { +w2, -h2, +d2 }, { 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f } };


    D3D11_BUFFER_DESC vbd;
    vbd.Usage = D3D11_USAGE_IMMUTABLE;
    vbd.ByteWidth = sizeof(Vertex::Basic32)* 24;
    vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vbd.CPUAccessFlags = 0;
    vbd.MiscFlags = 0;
    D3D11_SUBRESOURCE_DATA vinitData;
    vinitData.pSysMem = &v[0];
    HR(m_pd3dDevice->CreateBuffer(&vbd, &vinitData, &m_VB));


    UINT i[36];

    // Fill in the front face index data
    i[0] = 0; i[1] = 1; i[2] = 2;
    i[3] = 0; i[4] = 2; i[5] = 3;

    // Fill in the back face index data
    i[6] = 4; i[7] = 5; i[8] = 6;
    i[9] = 4; i[10] = 6; i[11] = 7;

    // Fill in the top face index data
    i[12] = 8; i[13] = 9; i[14] = 10;
    i[15] = 8; i[16] = 10; i[17] = 11;

    // Fill in the bottom face index data
    i[18] = 12; i[19] = 13; i[20] = 14;
    i[21] = 12; i[22] = 14; i[23] = 15;

    // Fill in the left face index data
    i[24] = 16; i[25] = 17; i[26] = 18;
    i[27] = 16; i[28] = 18; i[29] = 19;

    // Fill in the right face index data
    i[30] = 20; i[31] = 21; i[32] = 22;
    i[33] = 20; i[34] = 22; i[35] = 23;

    D3D11_BUFFER_DESC ibd;
    ibd.Usage = D3D11_USAGE_IMMUTABLE;
    ibd.ByteWidth = sizeof(UINT)* 36;
    ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
    ibd.CPUAccessFlags = 0;
    ibd.MiscFlags = 0;
    D3D11_SUBRESOURCE_DATA iinitData;
    iinitData.pSysMem = &i[0];
    HR(m_pd3dDevice->CreateBuffer(&ibd, &iinitData, &m_IB));

在Render函数中

    //先请屏
    float color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
    m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, color);
    m_pImmediateContext->ClearDepthStencilView(m_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

    //设置输入布局和拓扑结构
    m_pImmediateContext->IASetInputLayout(InputLayouts::Basic32);
    m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    //设置顶点和索引
    UINT stride = sizeof(Vertex::Basic32);
    UINT offset = 0;
    m_pImmediateContext->IASetVertexBuffers(0, 1, &m_VB, &stride, &offset);
    m_pImmediateContext->IASetIndexBuffer(m_IB, DXGI_FORMAT_R32_UINT, 0);

    //设置变换矩阵
    XMMATRIX view = XMLoadFloat4x4(&m_View);
    XMMATRIX proj = XMLoadFloat4x4(&m_Proj);
    XMMATRIX world = XMLoadFloat4x4(&m_BoxWorld);
    XMMATRIX worldViewProj = world*view*proj;

    //设置材质
    Material Mat;
    Mat.Ambient = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
    Mat.Diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
    Mat.Specular = XMFLOAT4(0.6f, 0.6f, 0.6f, 16.0f);

    //设置观察的位置,用于计算镜面高光
    XMFLOAT3 mEyePosW = XMFLOAT3(-2.3f, 5.06f, -19.0f);

    //方向光源
    DirectionalLight mDirLights[3];
    mDirLights[0].Ambient = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f);
    mDirLights[0].Diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
    mDirLights[0].Specular = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
    mDirLights[0].Direction = XMFLOAT3(0.57735f, -0.57735f, 0.57735f);

    mDirLights[1].Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
    mDirLights[1].Diffuse = XMFLOAT4(0.20f, 0.20f, 0.20f, 1.0f);
    mDirLights[1].Specular = XMFLOAT4(0.25f, 0.25f, 0.25f, 1.0f);
    mDirLights[1].Direction = XMFLOAT3(-0.57735f, -0.57735f, 0.57735f);

    mDirLights[2].Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
    mDirLights[2].Diffuse = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f);
    mDirLights[2].Specular = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
    mDirLights[2].Direction = XMFLOAT3(0.0f, -0.707f, -0.707f);

    //设置GPU的常量缓冲
    Effects::FX->SetDirLights(mDirLights);
    Effects::FX->SetEyePosW(mEyePosW);

    XMFLOAT4X4 mTexTransform;
    XMMATRIX I = XMMatrixIdentity();
    XMStoreFloat4x4(&mTexTransform, I);

    D3DX11_TECHNIQUE_DESC techDesc;
    Effects::FX->Light3TexTech->GetDesc(&techDesc);
    for (UINT p = 0; p < techDesc.Passes; ++p)
    {
        world = XMLoadFloat4x4(&m_BoxWorld);
        XMMATRIX worldInvTranspose = MathHelper::InverseTranspose(world);
        worldViewProj = world*view*proj;
        Effects::FX->SetWorld(world);
        Effects::FX->SetWorldInvTranspose(worldInvTranspose);
        Effects::FX->SetWorldViewProj(worldViewProj);
        Effects::FX->SetTexTransform(XMLoadFloat4x4(&mTexTransform));
        Effects::FX->SetMaterial(Mat);
        Effects::FX->SetDiffuseMap(m_DiffuseMapSRV);
        //将设置的常量缓冲和纹理贴图传送给GPU
        Effects::FX->Light3TexTech->GetPassByIndex(p)->Apply(0, m_pImmediateContext);
        //绘制
        m_pImmediateContext->DrawIndexed(36, 0, 0);
    }
    //将前台缓冲和后台缓冲交换,显示图像
    HR(m_pSwapChain->Present(0, 0));

初始化和创建各种D3D11资源后。1
每帧基本上就是清屏和清除深度模板缓存。2
设置输入布局和拓扑结构 3
设置输入顶点 4
设置光栅化状态设置Shader,将相应的常量缓冲或纹理贴图输送给GPU 5
GPU完成绘制 6

3 - 6的步骤应该就是所谓的一次draw call(个人理解)

一些设置方法如果当前draw call没有设置(如光栅化状态, 输入布局, 拓扑结构等)应该使用的是上一次的设置。
这里写图片描述
以上是Introdution to 3D programming with DirectX 11里的一个例子
可以去这里下载完整例子
上图就是光照和纹理映射,主要实现都在Shader里完成。光照和纹理映射的软件实现在之前的软件光栅化 五
十张里有差不多的实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值