Directx11学习笔记【十二】 画一个旋转的彩色立方体
2016-05-11 22:38
363 查看
上一次我们学习了如何画一个2D三角形,现在让我们进一步学习如何画一个旋转的彩色立方体吧。
具体流程同画三角形类似,因此不再给出完整代码了,不同的部分会再说明。
由于我们要画彩色的立方体,所以顶点结构体中加入颜色变量
定义了一个矩阵gWorldViewProj,后面我们会利用它进行旋转立方体
相比三角形,立方体还要定义Index信息,来确定立方体的六个面
定义输入布局
可以定义一个静态变量表示游戏时间,每一帧运行时更新t值,同时对矩阵作相应旋转即可。
这样我们的工作都完成了,运行便可以得到一个旋转的彩色立方体了.
下面是运行的一个截图
具体流程同画三角形类似,因此不再给出完整代码了,不同的部分会再说明。
由于我们要画彩色的立方体,所以顶点结构体中加入颜色变量
struct Vertex { XMFLOAT3 pos; XMFLOAT4 color; };
着色器代码
cbuffer cbPerObject { float4x4 gWorldViewProj; }; struct VertexIn { float3 PosL : POSITION; float4 Color : COLOR; }; struct VertexOut { float4 PosH : SV_POSITION; float4 Color : COLOR; }; VertexOut VS(VertexIn vin) { VertexOut vout; // Transform to homogeneous clip space. vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj); // Just pass vertex color into the pixel shader. vout.Color = vin.Color; return vout; } float4 PS(VertexOut pin) : SV_Target { return pin.Color; } technique11 ColorTech { pass P0 { SetVertexShader( CompileShader( vs_5_0, VS() ) ); SetGeometryShader( NULL ); SetPixelShader( CompileShader( ps_5_0, PS() ) ); } }
定义了一个矩阵gWorldViewProj,后面我们会利用它进行旋转立方体
BoxDemo.h
#pragma once #include "Dx11DemoBase.h" #include "d3dx11effect.h" class BoxDemo : public Dx11DemoBase { public: BoxDemo(); ~BoxDemo(); bool LoadContent() override; void UnLoadContent() override; void Update(float dt) override; void Render() override; private: ID3D11Buffer *m_pVertexBuffer; ID3D11Buffer *m_pIndexBuffer;//新增 ID3D11InputLayout *m_pInputLayout; ID3DX11Effect *m_pFx; ID3DX11EffectTechnique *m_pTechnique; ID3DX11EffectMatrixVariable *m_pFxWorldViewProj; XMFLOAT4X4 m_world; XMFLOAT4X4 m_view; XMFLOAT4X4 m_proj; };
LoadContent()函数
顶点信息及缓冲的创建Vertex vertices[] = { { XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT4(255, 255, 255, 1) },//white { XMFLOAT3(-0.5f, +0.5f, -0.5f), XMFLOAT4(0, 0, 0, 1) },//black { XMFLOAT3(+0.5f, +0.5f, -0.5f), XMFLOAT4(255, 0, 0, 1) },//red { XMFLOAT3(+0.5f, -0.5f, -0.5f), XMFLOAT4(0, 255, 0, 1) },//green { XMFLOAT3(-0.5f, -0.5f, +0.5f), XMFLOAT4(0, 0, 255, 1) },//blue { XMFLOAT3(-0.5f, +0.5f, +0.5f), XMFLOAT4(255, 255, 0, 1) },//yellow { XMFLOAT3(+0.5f, +0.5f, +0.5f), XMFLOAT4(0, 255, 255, 1) },//cyan { XMFLOAT3(+0.5f, -0.5f, +0.5f), XMFLOAT4(255, 0, 255, 1) }//magenta }; D3D11_BUFFER_DESC vertexDesc; ZeroMemory(&vertexDesc, sizeof(vertexDesc)); vertexDesc.Usage = D3D11_USAGE_DEFAULT; vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vertexDesc.ByteWidth = sizeof(Vertex)* 8; D3D11_SUBRESOURCE_DATA resourceData; ZeroMemory(&resourceData, sizeof(resourceData)); resourceData.pSysMem = vertices; result = m_pd3dDevice->CreateBuffer(&vertexDesc, &resourceData, &m_pVertexBuffer); if (FAILED(result)) { return false; }
相比三角形,立方体还要定义Index信息,来确定立方体的六个面
UINT indices[] = { // front face 0, 1, 2, 0, 2, 3, // back face 4, 6, 5, 4, 7, 6, // left face 4, 5, 1, 4, 1, 0, // right face 3, 2, 6, 3, 6, 7, // top face 1, 5, 6, 1, 6, 2, // bottom face 4, 0, 3, 4, 3, 7 }; D3D11_BUFFER_DESC indexDesc; ZeroMemory(&indexDesc, sizeof(indexDesc)); indexDesc.Usage = D3D11_USAGE_IMMUTABLE; indexDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; indexDesc.ByteWidth = sizeof(UINT)* 36; D3D11_SUBRESOURCE_DATA indexData; ZeroMemory(&indexData, sizeof(indexData)); indexData.pSysMem = indices; result = m_pd3dDevice->CreateBuffer(&indexDesc, &indexData, &m_pIndexBuffer); if (FAILED(result)) { return false; }
定义输入布局
D3D11_INPUT_ELEMENT_DESC solidColorLayout[] = { { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; UINT numLayoutElements = ARRAYSIZE(solidColorLayout); D3DX11_PASS_DESC passDesc; m_pTechnique->GetPassByIndex(0)->GetDesc(&passDesc); result = m_pd3dDevice->CreateInputLayout(solidColorLayout, numLayoutElements, passDesc.pIAInputSignature, passDesc.IAInputSignatureSize, &m_pInputLayout);
Update()函数----实现旋转
怎么实现立方体的旋转呢?我们之前不是给出了 world,view,proj三个矩阵吗,实现旋转的一种方式就是根据游戏时间旋转相应矩阵(例如world矩阵)。可以定义一个静态变量表示游戏时间,每一帧运行时更新t值,同时对矩阵作相应旋转即可。
static float t = 0.0f; t += (float)XM_PI * 0.0125f; static DWORD dwTimeStart = 0; DWORD dwTimeCur = GetTickCount(); if (dwTimeStart == 0) dwTimeStart = dwTimeCur; t = (dwTimeCur - dwTimeStart) / 1000.0f; XMVECTOR pos = XMVectorSet(2.0f, 0.0f, 0.0f, 1.0f); XMVECTOR target = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f); XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f); XMMATRIX V = XMMatrixLookAtLH(pos, target, up); XMStoreFloat4x4(&m_view, V); XMMATRIX T = XMMatrixPerspectiveFovLH(XM_PIDIV2, m_width / static_cast<float>(m_height), 0.01f, 100.0f); XMStoreFloat4x4(&m_proj, T); //根据时间旋转world矩阵 XMMATRIX P = XMMatrixRotationY(t); XMStoreFloat4x4(&m_world, P);
Render()函数
和之前的代码大部分一样,不同的是要设置IndexBuffer,绘制的时候要用DrawIndexed()而不是Draw().if (m_pImmediateContext == 0) return; //清除渲染目标视图 float clearColor[4] = { 1.0f, 1.0f, 1.0f, 1.0f };//背景颜色 m_pImmediateContext->ClearRenderTargetView(m_pRenderTargetView, clearColor); UINT stride = sizeof(Vertex); UINT offset = 0; //设置数据信息格式控制信息 m_pImmediateContext->IASetInputLayout(m_pInputLayout); //设置要绘制的几何体信息 m_pImmediateContext->IASetVertexBuffers(0,1,&m_pVertexBuffer,&stride,&offset); m_pImmediateContext->IASetIndexBuffer(m_pIndexBuffer, DXGI_FORMAT_R32_UINT, 0); //指明如何绘制 m_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); //设置常量 XMMATRIX world = XMLoadFloat4x4(&m_world); XMMATRIX view = XMLoadFloat4x4(&m_view); XMMATRIX proj = XMLoadFloat4x4(&m_proj); XMMATRIX worldViewProj = world*view*proj; m_pFxWorldViewProj->SetMatrix(reinterpret_cast<float*>(&worldViewProj)); D3DX11_TECHNIQUE_DESC techDesc; m_pTechnique->GetDesc(&techDesc); for (UINT i = 0; i < techDesc.Passes; ++i) { m_pTechnique->GetPassByIndex(i)->Apply(0, m_pImmediateContext); m_pImmediateContext->DrawIndexed(36, 0, 0); } //马上输出 m_pSwapChain->Present(0, 0);
这样我们的工作都完成了,运行便可以得到一个旋转的彩色立方体了.
下面是运行的一个截图
相关文章推荐
- new和malloc的区别&delete和free的区别
- Apriori算法
- Tomasulo算法
- iOS开发 -关于使用iOS沙盒路径遇到的问题
- Apriori算法
- spring mvc Cannot locate BeanDefinitionParser for element spring-servlet.xml
- 第五届山东省ACM Full Binary Tree
- zabbix_proxy 代理的实现
- Eclipse 中 CVS show histoy 显示空白
- Java基础-OOP特性之封装、继承、多态、抽象
- HTTP的一些状态消息参考
- JVM调优总结(一)-- 一些概念
- 第五届山东省ACM Factorial
- 毕设系列—服务端:Java-SSH框架(一)
- D. Number of Parallelograms
- 调用 Android系统资源的方法
- ACM-2013 蟠桃记
- 3-28高项作业
- 第五届山东省ACM Devour Magic
- Java 接口和抽象类区别