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

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

下面是运行的一个截图

时间: 2024-08-07 06:38:28

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

Swift学习笔记十二:下标脚本(subscript)

下标脚本就是对一个东西通过索引,快速取值的一种语法,例如数组的a[0].这就是一个下标脚本.通过索引0来快速取值.在Swift中,我们可以对类(Class).结构体(structure)和枚举(enumeration)中自己定义下标脚本的语法 一.常规定义 class Student{ var scores:Int[] = Array(count:5,repeatedValue:0) subscript(index:Int) -> Int{ get{ return scores[index];

《Hibernate学习笔记十二》学生、课程、分数关系的设计与实现

<Hibernate学习笔记十二>学生.课程.分数关系的设计与实现 这个马士兵老师的Hibernate视频学习的一个题目,这里面要用到多对多.多对一的关联关系以及联合主键,因此觉得挺好的,自己写篇博文来记录下. 先考虑数据库表 1.学生表:为简单起见,只考虑了学生id和学生姓名,其中id为主键 2.课程表:为简单起见,只考虑了课程id和课程名称,其中id为主键 3.分数表 分数表有两种解决方案 3.1 第一种为:使用联合主键:student_id 和 course_id 3.2 第二种:不使用

虚拟机VMWare学习笔记十二 - 将物理机抓取成虚拟机

1. 安装VMware vCenter Converter Standalone Client 运行虚拟机,File -- Virtualize a Physical Machine 这时如果电脑中没有VMware vCenter Converter Standalone Client ,则会进行安装. 安装过程 之后图标会出现在桌面上,双击运行 选择连接到本地服务器,登陆 点击转换计算机 这个,可以将本地计算机抓取成虚拟机,也可以将其他可以访问的计算机(需知道管理员用户名及密码)抓取成虚拟机.

laravel3学习笔记(十二)

原作者博客:ieqi.net ==================================================================================================== 请求反射 HTTP 协议本身是无状态性的,但是在应用中处理各种业务逻辑时我们必须要有状态的把控,这样,折中的办法就是将状态进行标记然后嵌入到 HTTP 协议的请求中,然后应用根据这些标记来进行状态的串联以及处理.所以我们就要对请求进行反射处理以获取请求信息, Lara

Directx11学习笔记【二十二】 用高度图实现地形

本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5827714.html 在前面我们曾经实现过简单的地形(Directx11学习笔记[十三] 实现一个简单地形),只不过原来使用一个固定的函数获得地形高度,这样跟真实的地形差距比较大.接下来让我们学习使用高度图来进行三维地形模拟. 1.高度图 高度图其实就是一组连续的数组,这个数组中的元素与地形网格中的顶点一一对应,且每一个元素都指定了地形网格的某个顶点的高度值.高度

Directx11学习笔记【二】 将HelloWin封装成类

我们把上一个教程的代码封装到一个类中来方便以后的使用. 首先新建一个空工程叫做MyHelloWin,添加一个main.cpp文件,然后新建一个类叫做MyWindow,将于窗体有关的操作封装到里面 MyWindow.h文件 1 /************************************************************************ 2 Directx11学习笔记[2] 将HelloWin封装成类 3 2016.01 by zhangbaochong 4 /

java jvm学习笔记十二(访问控制器的栈校验机制)

欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 本节源码:http://download.csdn.net/detail/yfqnihao/4863854 这一节,我们会简单的描述一下jvm访问控制器的栈校验机制. 这节课,我们还是以实践为主,什么是栈校验机制,讲一百遍不如你自己实际的代码一下然后验证一下,下面我们下把环境搭起来. 第一步,配置系统环境.(copy吧,少年) path=%JAVA_HOME%/bin JAVA_HOME=C:/Java/jdk1.6

Directx11学习笔记【二十】 使用DirectX Tool Kit加载mesh

本文由zhangbaochong原创,转载请注明出处: 现在directx已经不再支持.x文件了,意味着D3DXLoadMeshFromX加载mesh的方法已经不能用了.要加载mesh除了自己解析文件外,最简单的方法是利用微软开源的工具DirectXTK中的Model类或者DXUT中的CDXUTSDKMesh类.这里以DirectXTK为例,看看如何加载的吧! 1.格式转化 DirectXTK中的Model类支持.sdkmesh和.cmo格式,所以下载的.obj..fbx等格式的文件必须转化成支

JavaScript权威设计--JavaScript函数(简要学习笔记十二)

1.作为命名空间的函数 有时候我们需要声明很多变量.这样的变量会污染全局变量并且可能与别人声明的变量产生冲突. 这时.解决办法是将代码放入一个函数中,然后调用这个函数.这样全局变量就变成了 局部变量. 如: function my(){ } my(); //别忘记调用 这段代码定义了一个单独的全局变量:名叫"my"的函数. 我们还可以这么写,定义一个匿名函数: (function(){ //这里第一个左括号是必须的,如果不写,JavaScript解析器会将 //function解析成函