Direct3D绘制旋转立方体例程

本文介绍了如何使用Direct3D9在Windows环境下初始化设备,创建顶点和索引缓冲区,以及实现一个旋转立方体的简单图形渲染过程。作者展示了如何设置世界和视图投影变换,并利用时间差更新旋转角度以实现动态效果。
摘要由CSDN通过智能技术生成

初始化文件见Direct3D的初始化_direct3dcreate9_寂寂寂寂寂蝶丶的博客-CSDN博客

D3DPractice.cpp

#include <windows.h>
#include "d3dUtility.h"
#include <d3dx9math.h>

IDirect3DDevice9* Device = NULL;
IDirect3DVertexBuffer9* VB = NULL;
IDirect3DIndexBuffer9* IB = NULL;
const int Width = 1024;
const int Height = 768;

struct Vertex
{
	Vertex(){}
	Vertex(float x, float y, float z)
		:_x(x), _y(y), _z(z)
	{
	}
	float _x, _y, _z;
	static const DWORD FVF;
};
const DWORD Vertex::FVF = D3DFVF_XYZ;

#if 0
Display方法有两项任务,更新场景和绘制场景,我们想让立方体旋转起来,必须在程序生成的每帧图像中给旋转角一定的增量,
从而指定立方体的旋转方式,通过更新每帧图像中立方体的角度,立方体在每帧图像中就被微微地旋转,从而产生转动的视觉效果
本例中我们是用世界变换来指定立方体的方向
#endif

bool DisPlay(float timeDelta)
{
	if (Device)
	{
		D3DXMATRIX Rx, Ry;
		
		//x轴旋转矩阵
		D3DXMatrixRotationX(&Rx, 3.14f / 4.0f);

		static float y = 0.0f;
		//y轴旋转矩阵
		D3DXMatrixRotationY(&Ry, y);
		y += timeDelta;

		//重置
		if (y >= 6.28f)
			y = 0.0f;

		D3DXMATRIX p = Rx * Ry;
		Device->SetTransform(D3DTS_WORLD, &p);

/*
	STDMETHOD(Clear)(THIS_ DWORD Count, CONST D3DRECT* pRects, DWORD Flags, D3DCOLOR Color, float Z, DWORD Stencil) PURE;
	Count: pRects数组中矩形的数目
	pRects:要执行清除操作的屏幕矩形数组,该参数允许我们只对表面的部分区域进行清除操作
	Flags:指定所要清除的表面
	D3DCLEAR_TARGET 绘制目标表面,通常指后台缓存
	D3DCLEAR_ZBUFFER 深度缓存
	D3DCLEAR_STENCIL 模板缓存
	Color:指定将绘制目标体设置为何种颜色
	Z:深度缓存所需要设定的值
	Stencil:模板缓存所需要设定的值
*/
		Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);

		if (SUCCEEDED(Device->BeginScene()))
		{
			//指定数据流输入源
			Device->SetStreamSource(0, VB, 0, sizeof(Vertex));
			//设置索引缓存
			Device->SetIndices(IB);
			//设置顶点格式
			Device->SetFVF(Vertex::FVF);

			//通过索引缓存来绘制绘制
			Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
			//Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
			Device->EndScene();
		}
		Device->Present(0, 0, 0, 0);  //提交后台缓存
	}
	return true;
}



bool InitVertexBuffer()
{
	Device->CreateVertexBuffer(8 * sizeof(Vertex), D3DUSAGE_WRITEONLY, Vertex::FVF, D3DPOOL_MANAGED, &VB, 0);
	Device->CreateIndexBuffer(36 * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &IB, 0);
	
	//顶点缓存
	Vertex* vertices;
	VB->Lock(0, 0, (void**)&vertices, 0);
	vertices[0] = Vertex(-1.0f, -1.0f, -1.0f);
	vertices[1] = Vertex(-1.0f, 1.0f, -1.0f);
	vertices[2] = Vertex(1.0f, 1.0f, -1.0f);
	vertices[3] = Vertex(1.0f, -1.0f, -1.0f);
	vertices[4] = Vertex(-1.0f, -1.0f, 1.0f);
	vertices[5] = Vertex(-1.0f, 1.0f, 1.0f);
	vertices[6] = Vertex(1.0f, 1.0f, 1.0f);
	vertices[7] = Vertex(1.0f, -1.0f, 1.0f);
	VB->Unlock();

	//索引缓存
	WORD* indices = 0;
	IB->Lock(0, 0, (void**)&indices, 0);
	//front side
	indices[0] = 0;indices[1] = 1;indices[2] = 2;
	indices[3] = 0;indices[4] = 2;indices[5] = 3;

	//back side
	indices[6] = 4;indices[7] = 6;indices[8] = 5;
	indices[9] = 4;indices[10] = 7;indices[11] = 6;

	//left side
	indices[12] = 4;indices[13] = 5;indices[14] = 1;
	indices[15] = 4;indices[16] = 1;indices[17] = 0;

	//right side
	indices[18] = 3;indices[19] = 2;indices[20] = 6;
	indices[21] = 3;indices[22] = 6;indices[23] = 7;

	//top
	indices[24] = 1;indices[25] = 5;indices[26] = 6;
	indices[27] = 1;indices[28] = 6;indices[29] = 2;

	//bottom
	indices[30] = 4;indices[31] = 0;indices[32] = 3;
	indices[33] = 4;indices[34] = 3;indices[35] = 7;
	IB->Unlock();

	//取景变换(观察者坐标系)
	D3DXVECTOR3 position(0.0f, 0.0f, -5.0f);
	D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
	D3DXMATRIX V;
	D3DXMatrixLookAtLH(&V, &position, &target, &up);
	Device->SetTransform(D3DTS_VIEW, &V);

	//投影变换
	D3DXMATRIX proj;
	D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI*0.5f, (float)Width / (float)Height, 1.0f, 1000.0f);
	Device->SetTransform(D3DTS_PROJECTION, &proj);

	Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);

	return true;
}

#if 0
创建顶点缓存和索引缓存,对缓存进行锁定,将构成立方体的顶点数据以及构成立方体的三角形单元的索引数据分别写入顶点缓存和索引缓存。然后将摄像
机沿Z轴负方向平移几个单位,以使绘制在世界坐标系原点的立方体处于摄像机的视场内。然后再实施投影变换,最终,将填充模式的绘制状态设为线框模式
#endif
bool SetUp()
{
	return InitVertexBuffer();
}

void CleanUp()
{
	d3d::Release<IDirect3DVertexBuffer9*>(VB);
	d3d::Release<IDirect3DIndexBuffer9*>(IB);
}

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd)
{
	
	if (!d3d::InitD3D(hInstance, 800, 600, true, D3DDEVTYPE_HAL, &Device))
	{
		::MessageBox(0, L"InitD3D() - FAILED", 0, 0);
		return 0;
	}

	if (!SetUp())
	{
		::MessageBox(0, L"SetUp() - FAILED", 0, 0);
		return 0;
	}
	d3d::EnterMsgLoop(DisPlay);
	CleanUp();
	Device->Release();

	return 0;
}

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值