Direct3D学习手记一:实现Direct3D程序框架
2013-12-22 14:48
344 查看
本文介绍编写Direct3D程序的一般步骤和框架函数:
一般步骤:
1.注册窗口类2.创建窗口
3.创建设备
4.初始化程序要用的资源如顶点或索引缓存
5.游戏循环即消息循环,在没有消息时进行场景的绘制
6.程序退出前的清理操作,释放申请的资源
框架函数:
1.InitDirect3D函数完成步骤1、2、32.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; }
最后是程序运行的截图:
以下是工程文件下载地址:
百度网盘相关文章推荐
- PHP CI框架学习笔记-分页实现程序
- 框架学习系列 mybatis 第四篇 mybatis入门程序之需求开发1
- 菜鸟学习c++—map使用练习 实现词频统计程序
- NPAPI插件开发学习:实现非IE浏览器的类似ActiveX的本地程序(插件)调用
- 微信小程序学习笔记--20170425--登录验证实现
- 第二部分 程序框架实现的线程分析
- spring4学习记录05-spring mvc实战之框架构建测试jpa借助spring-data实现自动化jpa
- MFC框架程序中全屏显示特性的实现
- 机器学习入门学习笔记:(一)BP神经网络原理推导及程序实现
- Introduction to 3D Game Programming with DirectX 11学习笔记 4.4 演示程序框架
- Android 实现图片缓存异步加载框架学习笔记
- Android开发学习笔记-实现联网检测程序版本
- java程序——用集合框架实现学生类的排序输出
- 开心网辅助程序开发手记(三):实现停车功能
- 微信小程序,学习笔记(一)框架,视图层
- SpringMvc[学习手记]-框架搭建
- Jimoshi_Spring 框架学习(一)--Spring实现IOC思想、javabean对象、Spring对象和对象之间关系
- prism4学习笔记二:应用框架完成你的第一个prisam程序
- 【学习ios之路:C语言】小程序:实现类似ATM取款机功能.
- 【框架-MFC】MFC 实现单例进程,只允许一个程序运行