您的位置:首页 > 其它

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

2016-05-11 22:38 363 查看
上一次我们学习了如何画一个2D三角形,现在让我们进一步学习如何画一个旋转的彩色立方体吧。

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

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

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


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

下面是运行的一个截图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: