• Directx11学习笔记【十二】 画一个旋转的彩色立方体


    上一次我们学习了如何画一个2D三角形,现在让我们进一步学习如何画一个旋转的彩色立方体吧。

    具体流程同画三角形类似,因此不再给出完整代码了,不同的部分会再说明。

    由于我们要画彩色的立方体,所以顶点结构体中加入颜色变量

    struct Vertex
    {
        XMFLOAT3 pos;
        XMFLOAT4 color;
    };

    着色器代码 

     1 cbuffer cbPerObject
     2 {
     3     float4x4 gWorldViewProj; 
     4 };
     5 
     6 struct VertexIn
     7 {
     8     float3 PosL  : POSITION;
     9         float4 Color : COLOR;
    10 };
    11 
    12 struct VertexOut
    13 {
    14     float4 PosH  : SV_POSITION;
    15         float4 Color : COLOR;
    16 };
    17 
    18 VertexOut VS(VertexIn vin)
    19 {
    20     VertexOut vout;
    21     
    22     // Transform to homogeneous clip space.
    23     vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);
    24     
    25     // Just pass vertex color into the pixel shader.
    26         vout.Color = vin.Color;
    27     
    28         return vout;
    29 }
    30 
    31 float4 PS(VertexOut pin) : SV_Target
    32 {
    33     return pin.Color;
    34 }
    35 
    36 technique11 ColorTech
    37 {
    38     pass P0
    39     {
    40         SetVertexShader( CompileShader( vs_5_0, VS() ) );
    41         SetGeometryShader( NULL );
    42         SetPixelShader( CompileShader( ps_5_0, PS() ) );
    43     }
    44 }

    定义了一个矩阵gWorldViewProj,后面我们会利用它进行旋转立方体

    BoxDemo.h

     1 #pragma once
     2 
     3 #include "Dx11DemoBase.h"
     4 #include "d3dx11effect.h"
     5 
     6 class BoxDemo : public Dx11DemoBase
     7 {
     8 public:
     9     BoxDemo();
    10     ~BoxDemo();
    11 
    12     bool LoadContent() override;
    13     void UnLoadContent() override;
    14 
    15     void Update(float dt) override;
    16     void Render() override;
    17 
    18 private:
    19     ID3D11Buffer *m_pVertexBuffer;
    20     ID3D11Buffer *m_pIndexBuffer;//新增
    21     ID3D11InputLayout *m_pInputLayout;
    22 
    23     ID3DX11Effect *m_pFx;
    24     ID3DX11EffectTechnique *m_pTechnique;
    25     ID3DX11EffectMatrixVariable *m_pFxWorldViewProj;
    26     XMFLOAT4X4 m_world;
    27     XMFLOAT4X4 m_view;
    28     XMFLOAT4X4 m_proj;
    29 
    30 };

    LoadContent()函数

    顶点信息及缓冲的创建

     1 Vertex vertices[] =
     2     {        
     3         { XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT4(255, 255, 255, 1) },//white
     4         { XMFLOAT3(-0.5f, +0.5f, -0.5f), XMFLOAT4(0, 0, 0, 1) },//black
     5         { XMFLOAT3(+0.5f, +0.5f, -0.5f), XMFLOAT4(255, 0, 0, 1) },//red
     6         { XMFLOAT3(+0.5f, -0.5f, -0.5f), XMFLOAT4(0, 255, 0, 1) },//green
     7         { XMFLOAT3(-0.5f, -0.5f, +0.5f), XMFLOAT4(0, 0, 255, 1) },//blue
     8         { XMFLOAT3(-0.5f, +0.5f, +0.5f), XMFLOAT4(255, 255, 0, 1) },//yellow
     9         { XMFLOAT3(+0.5f, +0.5f, +0.5f), XMFLOAT4(0, 255, 255, 1) },//cyan
    10         { XMFLOAT3(+0.5f, -0.5f, +0.5f), XMFLOAT4(255, 0, 255, 1) }//magenta
    11     };
    12 
    13 
    14     D3D11_BUFFER_DESC vertexDesc;
    15     ZeroMemory(&vertexDesc, sizeof(vertexDesc));
    16     vertexDesc.Usage = D3D11_USAGE_DEFAULT;
    17     vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    18     vertexDesc.ByteWidth = sizeof(Vertex)* 8;
    19 
    20     D3D11_SUBRESOURCE_DATA resourceData;
    21     ZeroMemory(&resourceData, sizeof(resourceData));
    22     resourceData.pSysMem = vertices;
    23     result = m_pd3dDevice->CreateBuffer(&vertexDesc, &resourceData, &m_pVertexBuffer);
    24     if (FAILED(result))
    25     {
    26         return false;
    27     }

    相比三角形,立方体还要定义Index信息,来确定立方体的六个面

     1 UINT indices[] = {
     2         // front face
     3         0, 1, 2,
     4         0, 2, 3,
     5 
     6         // back face
     7         4, 6, 5,
     8         4, 7, 6,
     9 
    10         // left face
    11         4, 5, 1,
    12         4, 1, 0,
    13 
    14         // right face
    15         3, 2, 6,
    16         3, 6, 7,
    17 
    18         // top face
    19         1, 5, 6,
    20         1, 6, 2,
    21 
    22         // bottom face
    23         4, 0, 3,
    24         4, 3, 7
    25     };
    26 
    27     D3D11_BUFFER_DESC indexDesc;
    28     ZeroMemory(&indexDesc, sizeof(indexDesc));
    29     indexDesc.Usage = D3D11_USAGE_IMMUTABLE;
    30     indexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
    31     indexDesc.ByteWidth = sizeof(UINT)* 36;
    32 
    33     D3D11_SUBRESOURCE_DATA indexData;
    34     ZeroMemory(&indexData, sizeof(indexData));
    35     indexData.pSysMem = indices;
    36     result = m_pd3dDevice->CreateBuffer(&indexDesc, &indexData, &m_pIndexBuffer);
    37     if (FAILED(result))
    38     {
    39         return false;
    40     }

    定义输入布局

     1 D3D11_INPUT_ELEMENT_DESC solidColorLayout[] =
     2     {
     3         { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
     4         { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }
     5     };
     6     UINT numLayoutElements = ARRAYSIZE(solidColorLayout);
     7     D3DX11_PASS_DESC passDesc;
     8     m_pTechnique->GetPassByIndex(0)->GetDesc(&passDesc);
     9 
    10     result = m_pd3dDevice->CreateInputLayout(solidColorLayout, numLayoutElements, passDesc.pIAInputSignature,
    11         passDesc.IAInputSignatureSize, &m_pInputLayout);

    Update()函数----实现旋转

    怎么实现立方体的旋转呢?我们之前不是给出了 world,view,proj三个矩阵吗,实现旋转的一种方式就是根据游戏时间旋转相应矩阵(例如world矩阵)。

    可以定义一个静态变量表示游戏时间,每一帧运行时更新t值,同时对矩阵作相应旋转即可。

     1 static float t = 0.0f;
     2     t += (float)XM_PI * 0.0125f;
     3     static DWORD dwTimeStart = 0;
     4     DWORD dwTimeCur = GetTickCount();
     5     if (dwTimeStart == 0)
     6         dwTimeStart = dwTimeCur;
     7     t = (dwTimeCur - dwTimeStart) / 1000.0f;
     8 
     9     XMVECTOR pos = XMVectorSet(2.0f, 0.0f, 0.0f, 1.0f);
    10     XMVECTOR target = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
    11     XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
    12 
    13     XMMATRIX V = XMMatrixLookAtLH(pos, target, up);
    14     XMStoreFloat4x4(&m_view, V);
    15     XMMATRIX T = XMMatrixPerspectiveFovLH(XM_PIDIV2, m_width / static_cast<float>(m_height),
    16         0.01f, 100.0f);
    17     XMStoreFloat4x4(&m_proj, T);
    18     //根据时间旋转world矩阵
    19     XMMATRIX P = XMMatrixRotationY(t);
    20     XMStoreFloat4x4(&m_world, P);

    Render()函数

    和之前的代码大部分一样,不同的是要设置IndexBuffer,绘制的时候要用DrawIndexed()而不是Draw().

     1 if (m_pImmediateContext == 0)
     2         return;
     3     //清除渲染目标视图
     4     float clearColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };//背景颜色
     5     m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, clearColor);
     6 
     7     UINT stride = sizeof(Vertex);
     8     UINT offset = 0;
     9     //设置数据信息格式控制信息
    10     m_pImmediateContext->IASetInputLayout(m_pInputLayout);
    11     //设置要绘制的几何体信息
    12     m_pImmediateContext->IASetVertexBuffers(0,1,&m_pVertexBuffer,&stride,&offset);
    13     m_pImmediateContext->IASetIndexBuffer(m_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
    14     //指明如何绘制
    15     m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
    16 
    17     //设置常量 
    18     XMMATRIX world = XMLoadFloat4x4(&m_world);
    19     XMMATRIX view = XMLoadFloat4x4(&m_view);
    20     XMMATRIX proj = XMLoadFloat4x4(&m_proj);
    21     XMMATRIX worldViewProj = world*view*proj;
    22     m_pFxWorldViewProj->SetMatrix(reinterpret_cast<float*>(&worldViewProj));
    23 
    24     D3DX11_TECHNIQUE_DESC techDesc;
    25     m_pTechnique->GetDesc(&techDesc);
    26     for (UINT i = 0; i < techDesc.Passes; ++i)
    27     {
    28         m_pTechnique->GetPassByIndex(i)->Apply(0, m_pImmediateContext);
    29         m_pImmediateContext->DrawIndexed(36, 0, 0);
    30     }
    31     //马上输出
    32     m_pSwapChain->Present(0, 0);

    这样我们的工作都完成了,运行便可以得到一个旋转的彩色立方体了.

    下面是运行的一个截图

  • 相关阅读:
    IO复用(较详细)
    关于CGI 和 PHP-FPM需要弄清的
    php内核一些常识
    python搭建web服务
    瓶颈分析
    分布式系统
    vmdk多文件合成单文件并导入
    用户登录自动调用修改网络信息脚本
    strace命令用法
    使用Nginx反向代理Docker的Asp.Net Core项目的请求
  • 原文地址:https://www.cnblogs.com/zhangbaochong/p/5483876.html
Copyright © 2020-2023  润新知