Direct3D学习手记一:实现Direct3D程序框架

本文介绍编写Direct3D程序的一般步骤和框架函数:

一般步骤:

1.注册窗口类

2.创建窗口

3.创建设备

4.初始化程序要用的资源如顶点或索引缓存

5.游戏循环即消息循环,在没有消息时进行场景的绘制

6.程序退出前的清理操作,释放申请的资源


框架函数:

1.InitDirect3D函数完成步骤1、2、3

2.Setup函数完成步骤4

3.GameLoop函数完成步骤5

4.Render函数进行场景绘制

5.Cleanup函数完成步骤6


以下是框架函数的声明头文件

/***************************************************************
*	Direct3D程序框架的函数声明文件
***************************************************************
*	FileName	:	Common.h
*	Author		:	Anonymous
*	Time			:	2013/12/22
***************************************************************/
#pragma once
#include<d3d9.h>

/****************************************************************
*函数名	:	InitDirect3D
*功能		:	注册窗口类,创建程序窗口,创建IDirect3DDevice9接口对象
*输入		:	hInstance:程序实例句柄,
*					nWidth:窗口宽度,nHeight:窗口高度,
*					bWindowed:窗口模式还是全屏模式
*输出		:	无
*返回值	:	成功:TRUE		失败:FALSE
****************************************************************/
BOOL			InitDirect3D(HINSTANCE hInstance,int nWidth,int nHeight,BOOL bWindowed);

/****************************************************************
*函数名	:	Setup
*功能		:	创建与初始化资源、缓存、变换等
*输入		:	hWnd:窗口句柄
*输出		:	无
*返回值	:	成功:TRUE		失败:FALSE
****************************************************************/
BOOL			Setup(HWND hWnd);

/****************************************************************
*函数名	:	GameLoop
*功能		:	游戏循环(消息循环)
*输入		:	无
*输出		:	无
*返回值	:	无
****************************************************************/
void			GameLoop();

/****************************************************************
*函数名	:	Render
*功能		:	场景绘制
*输入		:	无
*输出		:	无
*返回值	:	无
****************************************************************/
void			Render();

/****************************************************************
*函数名	:	Cleanup
*功能		:	程序退出时释放申请的资源
*输入		:	无
*输出		:	无
*返回值	:	无
****************************************************************/
void			Cleanup();



以下是框架函数的实现(注释非常清楚):

/****************************************************************
*函数名	:	InitDirect3D
*功能		:	注册窗口类,创建程序窗口,创建IDirect3DDevice9接口对象
*输入		:	hInstance:程序实例句柄,
*					nWidth:窗口宽度,nHeight:窗口高度,
*					bWindowed:窗口模式还是全屏模式
*输出		:	无
*返回值	:	成功:TRUE		失败:FALSE
****************************************************************/
BOOL			InitDirect3D(HINSTANCE hInstance,int nWidth,int nHeight,BOOL bWindowed)
{
	HINSTANCE hInst=hInstance;
	if(NULL==hInst)
		hInst=GetModuleHandle(NULL);//如果hInstance为NULL,则得到当前程序的实例句柄

	/********** 	Step 1	:	注册窗口类	**************/
	WNDCLASS	wndcls;//窗口类
	wndcls.cbClsExtra=0;
	wndcls.cbWndExtra=0;
	wndcls.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);//使用系统自带的灰色画刷
	wndcls.hCursor=LoadCursor(hInst,MAKEINTRESOURCE(IDC_MAIN_CURSOR));//设置光标
	wndcls.hIcon=LoadIcon(hInst,MAKEINTRESOURCE(IDI_MAIN_ICON));//设置图标
	wndcls.hInstance=hInst;
	wndcls.lpfnWndProc=WndProc;//设置窗口过程,用于处理各种消息
	wndcls.lpszClassName=g_pszClassName;//窗口类名
	wndcls.lpszMenuName=NULL;
	wndcls.style=CS_VREDRAW|CS_HREDRAW;

	//注册窗口类,失败返回FALSE
	if(!RegisterClass(&wndcls))
		return FALSE;

	/********** 	Step 2	:	创建窗口	**************/
	g_hWnd=CreateWindow(g_pszClassName,//类名
													g_pszWindowName,//窗口标题
													WS_OVERLAPPEDWINDOW,//风格
													300,//左上角点的横坐标
													80,//左上角点的纵坐标
													nWidth,//窗口宽度
													nHeight,//窗口高度
													NULL,//父窗口实例句柄
													NULL,//菜单句柄
													hInst,//实例句柄
													NULL);
	//判断窗口是否创建成功
	if(NULL==g_hWnd)
	{
		UnregisterClass(g_pszClassName,hInst);
		return FALSE;
	}

	/********** 	Step 3	:	创建IDirect3DDevice9接口对象		**************/
	//Step 3.1 : 创建IDirect3D9 接口对象
	LPDIRECT3D9	pD3D=NULL;
	pD3D=Direct3DCreate9(D3D_SDK_VERSION);
	if(NULL==pD3D)//创建失败
	{
		UnregisterClass(g_pszClassName,hInst);
		return FALSE;
	}

	//Step 3.2 : 获取设备性能信息,设置顶点处理方式:软件or硬件
	D3DCAPS9 caps;
	int vp=0;//顶点处理方式
	if(FAILED(pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&caps)))
	{
		SAFE_RELEASE(pD3D);
		return FALSE;
	}
	if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)//判断设备是否支持硬件顶点处理(转换和光照)
		vp=D3DCREATE_HARDWARE_VERTEXPROCESSING;//硬件处理
	else
		vp=D3DCREATE_SOFTWARE_VERTEXPROCESSING;//软件处理

	//Step 3.3 : 初始化创建设备的参数
	D3DPRESENT_PARAMETERS d3dpp;
	d3dpp.AutoDepthStencilFormat=D3DFMT_D24S8;//24位深度缓存,8位模板缓存
	d3dpp.BackBufferCount=1;//后台缓存数
	d3dpp.BackBufferFormat=D3DFMT_A8R8G8B8;//后台缓存像素点格式
	d3dpp.BackBufferHeight=nHeight;//后台缓存高度(像素)
	d3dpp.BackBufferWidth=nWidth;//宽度
	d3dpp.EnableAutoDepthStencil=true;//自动管理深度缓存和模板缓存
	d3dpp.Flags=0;//其他标识
	d3dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT;//刷新频率
	d3dpp.hDeviceWindow=g_hWnd;//要绘制的窗口句柄
	d3dpp.MultiSampleQuality=0;//多重采样质量
	d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE;//多重采样设为无
	d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE;//立即提交/交换
	d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;//交换时销毁缓存
	d3dpp.Windowed=bWindowed;//窗口模式还是全屏模式

	//Step 3.4 : 创建设备
	if(FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,g_hWnd,vp,&d3dpp,&g_pd3dDevice)))
	{
		SAFE_RELEASE(pD3D);
		return FALSE;
	}

	SAFE_RELEASE(pD3D);
	return TRUE;
}

/****************************************************************
*函数名	:	Setup
*功能		:	创建与初始化资源、缓存、变换等
*输入		:	hWnd:窗口句柄
*输出		:	无
*返回值	:	成功:TRUE		失败:FALSE
****************************************************************/
BOOL			Setup(HWND hWnd)
{
	if(NULL==hWnd)
		return FALSE;

	//显示窗口
	ShowWindow(hWnd,SW_SHOW);
	UpdateWindow(hWnd);
	return TRUE;
}

/****************************************************************
*函数名	:	GameLoop
*功能		:	游戏循环(消息循环)
*输入		:	无
*输出		:	无
*返回值	:	无
****************************************************************/
void			GameLoop()
{
	MSG	msg;
	ZeroMemory(&msg,sizeof(MSG));

	//消息循环,收到WM_QUIT时退出程序
	while(WM_QUIT != msg.message)
	{
		if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
		{
			//有消息产生,转发消息
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			//没有消息,利用空余时间绘制场景
			Render();
		}
	}
}

/****************************************************************
*函数名	:	Render
*功能		:	场景绘制
*输入		:	无
*输出		:	无
*返回值	:	无
****************************************************************/
void			Render()
{
	//清屏,颜色设为灰色,深度缓存置为1.0,模板缓存置为0
	g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(150,150,150),1.0,0);

	if(SUCCEEDED(g_pd3dDevice->BeginScene()))//开始绘制
	{
		/*在此绘制其他*/

		g_pd3dDevice->EndScene();//结束绘制
	}
	g_pd3dDevice->Present(NULL,NULL,NULL,NULL);//翻转,显示
}

/****************************************************************
*函数名	:	Cleanup
*功能		:	程序退出时释放申请的资源
*输入		:	无
*输出		:	无
*返回值	:	无
****************************************************************/
void			Cleanup()
{
	SAFE_RELEASE(g_pd3dDevice);
}


在Cleanup函数中SAFE_RELEASE为宏定义,以便释放COM接口对象,其定义如下:

//释放COM接口对象的宏
#define		SAFE_RELEASE(p)	\
do												\
{													\
	if(p)											\
	{												\
		(p)->Release();						\
		(p)=NULL;							\
	}												\
}while(0);


下面就是程序的主函数与窗口过程函数以及一些全局变量的定义以方便后期的修改:

//全局变量
HWND									g_hWnd=NULL;//窗口句柄
LPTSTR									g_pszClassName=TEXT("Demo_01");//类名
LPTSTR									g_pszWindowName=TEXT("Demo_01	:	实现Direct3D程序的主框架");//窗口标题
const int									g_nWidth=800;//窗口宽度
const int									g_nHeight=600;//窗口高度


LPDIRECT3DDEVICE9			g_pd3dDevice=NULL;//IDirect3DDevice9接口对象,用它绘制场景及其他操作

//窗口过程
LRESULT	CALLBACK	WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
	switch(msg)
	{
	case WM_PAINT:
		Render();
		ValidateRect(hWnd,NULL);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_KEYDOWN:
		if(VK_ESCAPE==wParam)
			DestroyWindow(hWnd);
		break;
	}
	return DefWindowProc(hWnd,msg,wParam,lParam);
}
//程序主函数,入口点
int WINAPI	WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,LPSTR pszCmdLine,int nCmdShow)
{
	//Step 1	:	注册窗口类,创建窗口,创建设备
	if(!InitDirect3D(hInstance,g_nWidth,g_nHeight,TRUE))
		return 0;

	//Step 2	:	创建与初始化资源、缓存、变换等
	if(!Setup(g_hWnd))
		return 0;

	//Step 3	:	游戏循环
	GameLoop();

	//Step 4	:	游戏退出,清理
	Cleanup();
	UnregisterClass(g_pszClassName,hInstance);
	return 0;
}


最后是程序运行的截图



以下是工程文件下载地址

百度网盘

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值