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

来源:互联网 发布:sketch 46 破解版 mac 编辑:程序博客网 时间:2024/04/30 06:35

本文介绍编写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****************************************************************/BOOLInitDirect3D(HINSTANCE hInstance,int nWidth,int nHeight,BOOL bWindowed);/*****************************************************************函数名:Setup*功能:创建与初始化资源、缓存、变换等*输入:hWnd:窗口句柄*输出:无*返回值:成功:TRUE失败:FALSE****************************************************************/BOOLSetup(HWND hWnd);/*****************************************************************函数名:GameLoop*功能:游戏循环(消息循环)*输入:无*输出:无*返回值:无****************************************************************/voidGameLoop();/*****************************************************************函数名:Render*功能:场景绘制*输入:无*输出:无*返回值:无****************************************************************/voidRender();/*****************************************************************函数名:Cleanup*功能:程序退出时释放申请的资源*输入:无*输出:无*返回值:无****************************************************************/voidCleanup();



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

/*****************************************************************函数名:InitDirect3D*功能:注册窗口类,创建程序窗口,创建IDirect3DDevice9接口对象*输入:hInstance:程序实例句柄,*nWidth:窗口宽度,nHeight:窗口高度,*bWindowed:窗口模式还是全屏模式*输出:无*返回值:成功:TRUE失败:FALSE****************************************************************/BOOLInitDirect3D(HINSTANCE hInstance,int nWidth,int nHeight,BOOL bWindowed){HINSTANCE hInst=hInstance;if(NULL==hInst)hInst=GetModuleHandle(NULL);//如果hInstance为NULL,则得到当前程序的实例句柄/********** Step 1:注册窗口类**************/WNDCLASSwndcls;//窗口类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;//注册窗口类,失败返回FALSEif(!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 接口对象LPDIRECT3D9pD3D=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;//硬件处理elsevp=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****************************************************************/BOOLSetup(HWND hWnd){if(NULL==hWnd)return FALSE;//显示窗口ShowWindow(hWnd,SW_SHOW);UpdateWindow(hWnd);return TRUE;}/*****************************************************************函数名:GameLoop*功能:游戏循环(消息循环)*输入:无*输出:无*返回值:无****************************************************************/voidGameLoop(){MSGmsg;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*功能:场景绘制*输入:无*输出:无*返回值:无****************************************************************/voidRender(){//清屏,颜色设为灰色,深度缓存置为1.0,模板缓存置为0g_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*功能:程序退出时释放申请的资源*输入:无*输出:无*返回值:无****************************************************************/voidCleanup(){SAFE_RELEASE(g_pd3dDevice);}


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

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


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

//全局变量HWNDg_hWnd=NULL;//窗口句柄LPTSTRg_pszClassName=TEXT("Demo_01");//类名LPTSTRg_pszWindowName=TEXT("Demo_01:实现Direct3D程序的主框架");//窗口标题const intg_nWidth=800;//窗口宽度const intg_nHeight=600;//窗口高度LPDIRECT3DDEVICE9g_pd3dDevice=NULL;//IDirect3DDevice9接口对象,用它绘制场景及其他操作//窗口过程LRESULTCALLBACKWndProc(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 WINAPIWinMain(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;}


最后是程序运行的截图



以下是工程文件下载地址

百度网盘

0 0