索引缓存,再一次复习

  1. //【Visual C++】游戏开发笔记系列配套源码 三十七 浅墨DirectX提高班之五 顶点缓存的红颜知己:索引缓存的故事   
  2. //       VS2010版   
  3. // 2012年 12月16日  Create by 浅墨    
  4. //图标素材: Dota2 黑暗游侠的大招 射手天赋   
  5. //此刻心情:耿耿于怀着过去和忐忑不安着未来的人,也常常挥霍无度着现在。希望我们都做那个把握好现在的人。   
  6. //   
  7. //*****************************************************************************************    
  8.   
  9.   
  10.   
  11.   
  12. //*****************************************************************************************   
  13. // Desc: 头文件定义部分     
  14. //*****************************************************************************************                                                                                          
  15. #include <d3d9.h>   
  16. #include <d3dx9.h>   
  17. #include <tchar.h>   
  18. #include   <time.h>    
  19.   
  20.   
  21.   
  22.   
  23. //*****************************************************************************************   
  24. // Desc: 库文件定义部分     
  25. //*****************************************************************************************    
  26. #pragma comment(lib,"d3d9.lib")   
  27. #pragma comment(lib,"d3dx9.lib")   
  28. #pragma comment(lib, "winmm.lib ")   
  29.   
  30.   
  31. //*****************************************************************************************   
  32. // Desc: 宏定义部分      
  33. //*****************************************************************************************   
  34. #define SCREEN_WIDTH    800                     //为窗口宽度定义的宏,以方便在此处修改窗口宽度   
  35. #define SCREEN_HEIGHT   600                         //为窗口高度定义的宏,以方便在此处修改窗口高度   
  36. #define WINDOW_TITLE    _T("【Visual C++游戏开发笔记】博文配套demo之三十七 浅墨DirectX提高班之五 顶点缓存的红颜知己:索引缓存的故事") //为窗口标题定义的宏   
  37. #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }      //自定义一个SAFE_RELEASE()宏,便于资源的释放   
  38.   
  39.   
  40.   
  41. //*****************************************************************************************   
  42. // 【顶点缓存、索引缓存绘图四步曲之一】:设计顶点格式   
  43. //*****************************************************************************************   
  44. struct CUSTOMVERTEX  
  45. {  
  46.     FLOAT x, y, z,rhw;  
  47.     DWORD color;  
  48. };  
  49. #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)  //FVF灵活顶点格式   
  50.   
  51.   
  52. //*****************************************************************************************   
  53. // Desc: 全局变量声明部分     
  54. //*****************************************************************************************   
  55. LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; //Direct3D设备对象   
  56. ID3DXFont*              g_pFont=NULL;    //字体COM接口   
  57. float                   g_FPS = 0.0f;       //一个浮点型的变量,代表帧速率   
  58. wchar_t                 g_strFPS[50];    //包含帧速率的字符数组   
  59. LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer = NULL;    //顶点缓存对象   
  60. LPDIRECT3DINDEXBUFFER9  g_pIndexBuffer  = NULL;    // 索引缓存对象   
  61.   
  62. //*****************************************************************************************   
  63. // Desc: 全局函数声明部分    
  64. //*****************************************************************************************    
  65. LRESULT CALLBACK    WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam );  
  66. HRESULT             Direct3D_Init(HWND hwnd);  
  67. HRESULT             Objects_Init();  
  68. void                Direct3D_Render( HWND hwnd);  
  69. void                Direct3D_CleanUp( );  
  70. float               Get_FPS();  
  71.   
  72.   
  73. //*****************************************************************************************   
  74. // Name: WinMain( )   
  75. // Desc: Windows应用程序入口函数   
  76. //*****************************************************************************************   
  77. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nShowCmd)  
  78. {  
  79.   
  80.     //开始设计一个完整的窗口类   
  81.     WNDCLASSEX wndClass = { 0 };                //用WINDCLASSEX定义了一个窗口类,即用wndClass实例化了WINDCLASSEX,用于之后窗口的各项初始化       
  82.     wndClass.cbSize = sizeof( WNDCLASSEX ) ;    //设置结构体的字节数大小   
  83.     wndClass.style = CS_HREDRAW | CS_VREDRAW;   //设置窗口的样式   
  84.     wndClass.lpfnWndProc = WndProc;             //设置指向窗口过程函数的指针   
  85.     wndClass.cbClsExtra     = 0;  
  86.     wndClass.cbWndExtra     = 0;  
  87.     wndClass.hInstance = hInstance;             //指定包含窗口过程的程序的实例句柄。   
  88.     wndClass.hIcon=(HICON)::LoadImage(NULL,_T("icon.ico"),IMAGE_ICON,0,0,LR_DEFAULTSIZE|LR_LOADFROMFILE); //从全局的::LoadImage函数从本地加载自定义ico图标   
  89.     wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );    //指定窗口类的光标句柄。   
  90.     wndClass.hbrBackground=(HBRUSH)GetStockObject(GRAY_BRUSH);  //为hbrBackground成员指定一个灰色画刷句柄   
  91.     wndClass.lpszMenuName = NULL;                       //用一个以空终止的字符串,指定菜单资源的名字。   
  92.     wndClass.lpszClassName = _T("ForTheDreamOfGameDevelop");        //用一个以空终止的字符串,指定窗口类的名字。   
  93.   
  94.     if( !RegisterClassEx( &wndClass ) )             //设计完窗口后,需要对窗口类进行注册,这样才能创建该类型的窗口   
  95.         return -1;        
  96.   
  97.     HWND hwnd = CreateWindow( _T("ForTheDreamOfGameDevelop"),WINDOW_TITLE,          //喜闻乐见的创建窗口函数CreateWindow   
  98.         WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, SCREEN_WIDTH,  
  99.         SCREEN_HEIGHT, NULL, NULL, hInstance, NULL );  
  100.   
  101.   
  102.     //Direct3D资源的初始化,调用失败用messagebox予以显示   
  103.     if (!(S_OK==Direct3D_Init (hwnd)))  
  104.     {  
  105.         MessageBox(hwnd, _T("Direct3D初始化失败~!"), _T("浅墨的消息窗口"), 0); //使用MessageBox函数,创建一个消息窗口    
  106.     }  
  107.   
  108.   
  109.   
  110.     MoveWindow(hwnd,200,50,SCREEN_WIDTH,SCREEN_HEIGHT,true);   //调整窗口显示时的位置,窗口左上角位于屏幕坐标(200,50)处   
  111.     ShowWindow( hwnd, nShowCmd );    //调用Win32函数ShowWindow来显示窗口   
  112.     UpdateWindow(hwnd);  //对窗口进行更新,就像我们买了新房子要装修一样   
  113.   
  114.       
  115.   
  116.       
  117.   
  118.     //消息循环过程   
  119.     MSG msg = { 0 };  //初始化msg   
  120.     while( msg.message != WM_QUIT )         //使用while循环   
  121.     {  
  122.         if( PeekMessage( &msg, 0, 0, 0, PM_REMOVE ) )   //查看应用程序消息队列,有消息时将队列中的消息派发出去。   
  123.         {  
  124.             TranslateMessage( &msg );       //将虚拟键消息转换为字符消息   
  125.             DispatchMessage( &msg );        //该函数分发一个消息给窗口程序。   
  126.         }  
  127.         else  
  128.         {  
  129.             Direct3D_Render(hwnd);          //调用渲染函数,进行画面的渲染   
  130.         }  
  131.     }  
  132.   
  133.     UnregisterClass(_T("ForTheDreamOfGameDevelop"), wndClass.hInstance);  
  134.     return 0;    
  135. }  
  136.   
  137.   
  138.   
  139. //*****************************************************************************************   
  140. // Name: WndProc()   
  141. // Desc: 对窗口消息进行处理   
  142. //*****************************************************************************************   
  143. LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )   //窗口过程函数WndProc   
  144. {  
  145.     switch( message )               //switch语句开始   
  146.     {  
  147.     case WM_PAINT:                   // 客户区重绘消息   
  148.         Direct3D_Render(hwnd);          //调用Direct3D_Render函数,进行画面的绘制   
  149.         ValidateRect(hwnd, NULL);   // 更新客户区的显示   
  150.         break;                                  //跳出该switch语句   
  151.   
  152.     case WM_KEYDOWN:                // 键盘按下消息   
  153.         if (wParam == VK_ESCAPE)    // ESC键   
  154.             DestroyWindow(hwnd);    // 销毁窗口, 并发送一条WM_DESTROY消息   
  155.         break;  
  156.     case WM_DESTROY:                //窗口销毁消息   
  157.         Direct3D_CleanUp();     //调用Direct3D_CleanUp函数,清理COM接口对象   
  158.         PostQuitMessage( 0 );       //向系统表明有个线程有终止请求。用来响应WM_DESTROY消息   
  159.         break;                      //跳出该switch语句   
  160.   
  161.     default:                        //若上述case条件都不符合,则执行该default语句   
  162.         return DefWindowProc( hwnd, message, wParam, lParam );      //调用缺省的窗口过程来为应用程序没有处理的窗口消息提供缺省的处理。   
  163.     }  
  164.   
  165.     return 0;                   //正常退出   
  166. }  
  167.   
  168.   
  169. //*****************************************************************************************   
  170. // Name: Direct3D_Init( )   
  171. // Desc: 初始化Direct3D   
  172. // Point:【Direct3D初始化四步曲】   
  173. //      1.初始化四步曲之一,创建Direct3D接口对象   
  174. //      2.初始化四步曲之二,获取硬件设备信息   
  175. //      3.初始化四步曲之三,填充结构体   
  176. //      4.初始化四步曲之四,创建Direct3D设备接口   
  177. //*****************************************************************************************   
  178.   
  179. HRESULT Direct3D_Init(HWND hwnd)  
  180. {  
  181.   
  182.     //--------------------------------------------------------------------------------------   
  183.     // 【Direct3D初始化四步曲之一,创接口】:创建Direct3D接口对象, 以便用该Direct3D对象创建Direct3D设备对象   
  184.     //--------------------------------------------------------------------------------------   
  185.     LPDIRECT3D9  pD3D = NULL; //Direct3D接口对象的创建   
  186.     if( NULL == ( pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) //初始化Direct3D接口对象,并进行DirectX版本协商   
  187.             return E_FAIL;  
  188.   
  189.     //--------------------------------------------------------------------------------------   
  190.     // 【Direct3D初始化四步曲之二,取信息】:获取硬件设备信息   
  191.     //--------------------------------------------------------------------------------------   
  192.     D3DCAPS9 caps; int vp = 0;  
  193.     if( FAILED( pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps ) ) )  
  194.         {  
  195.             return E_FAIL;  
  196.         }  
  197.     if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )  
  198.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;   //支持硬件顶点运算,我们就采用硬件顶点运算,妥妥的   
  199.     else  
  200.         vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; //不支持硬件顶点运算,无奈只好采用软件顶点运算   
  201.   
  202.     //--------------------------------------------------------------------------------------   
  203.     // 【Direct3D初始化四步曲之三,填内容】:填充D3DPRESENT_PARAMETERS结构体   
  204.     //--------------------------------------------------------------------------------------   
  205.     D3DPRESENT_PARAMETERS d3dpp;   
  206.     ZeroMemory(&d3dpp, sizeof(d3dpp));  
  207.     d3dpp.BackBufferWidth            = SCREEN_WIDTH;  
  208.     d3dpp.BackBufferHeight           = SCREEN_HEIGHT;  
  209.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;  
  210.     d3dpp.BackBufferCount            = 2;  
  211.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;  
  212.     d3dpp.MultiSampleQuality         = 0;  
  213.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD;   
  214.     d3dpp.hDeviceWindow              = hwnd;  
  215.     d3dpp.Windowed                   = true;  
  216.     d3dpp.EnableAutoDepthStencil     = true;   
  217.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;  
  218.     d3dpp.Flags                      = 0;  
  219.     d3dpp.FullScreen_RefreshRateInHz = 0;  
  220.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;  
  221.   
  222.     //--------------------------------------------------------------------------------------   
  223.     // 【Direct3D初始化四步曲之四,创设备】:创建Direct3D设备接口   
  224.     //--------------------------------------------------------------------------------------   
  225.     if(FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,   
  226.         hwnd, vp, &d3dpp, &g_pd3dDevice)))  
  227.         return E_FAIL;  
  228.   
  229.   
  230.     if(!(S_OK==Objects_Init())) return E_FAIL;  
  231.   
  232.   
  233.   
  234.     SAFE_RELEASE(pD3D) //LPDIRECT3D9接口对象的使命完成,我们将其释放掉   
  235.   
  236.     return S_OK;  
  237. }  
  238.   
  239. HRESULT Objects_Init()  
  240. {  
  241.     //创建字体   
  242.     if(FAILED(D3DXCreateFont(g_pd3dDevice, 30, 0, 0, 1, FALSE, DEFAULT_CHARSET,   
  243.         OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, 0, _T("宋体"), &g_pFont)))  
  244.         return E_FAIL;  
  245.   
  246.   
  247.   
  248.     srand((unsigned)time(NULL));      //初始化时间种子   
  249.   
  250.   
  251.   
  252.       
  253.   
  254.   
  255.     //--------------------------------------------------------------------------------------   
  256.     // 【顶点缓存、索引缓存绘图四步曲之二】:创建顶点缓存和索引缓存   
  257.     //--------------------------------------------------------------------------------------   
  258.         //创建顶点缓存   
  259.         if( FAILED( g_pd3dDevice->CreateVertexBuffer( 18*sizeof(CUSTOMVERTEX),  
  260.             0, D3DFVF_CUSTOMVERTEX,  
  261.             D3DPOOL_DEFAULT, &g_pVertexBuffer, NULL ) ) )  
  262.         {  
  263.             return E_FAIL;  
  264.         }  
  265.         // 创建索引缓存   
  266.     if( FAILED(     g_pd3dDevice->CreateIndexBuffer(48 * sizeof(WORD), 0,   
  267.         D3DFMT_INDEX16, D3DPOOL_DEFAULT, &g_pIndexBuffer, NULL)) )  
  268.         {  
  269.         return E_FAIL;  
  270.   
  271.         }  
  272.         //--------------------------------------------------------------------------------------   
  273.         // 【顶点缓存、索引缓存绘图四步曲之三】:访问顶点缓存和索引缓存   
  274.         //--------------------------------------------------------------------------------------   
  275.         //顶点数据的设置,   
  276.         CUSTOMVERTEX Vertices[17];  
  277.         Vertices[0].x = 400;  
  278.         Vertices[0].y = 300;  
  279.         Vertices[0].z = 0.5f;  
  280.         Vertices[0].rhw = 1.0f;  
  281.         Vertices[0].color = D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256);  
  282.         for(int i=0; i<16; i++)  
  283.         {  
  284.             Vertices[i+1].x =  (float)(250*sin(i*3.14159/8.0)) + 400;  
  285.             Vertices[i+1].y = -(float)(250*cos(i*3.14159/8.0)) + 300;  
  286.             Vertices[i+1].z = 0.5f;  
  287.             Vertices[i+1].rhw = 1.0f;  
  288.             Vertices[i+1].color =  D3DCOLOR_XRGB(rand() % 256, rand() % 256, rand() % 256);  
  289.         }  
  290.   
  291.         //填充顶点缓冲区   
  292.         VOID* pVertices;  
  293.         if( FAILED( g_pVertexBuffer->Lock( 0, sizeof(Vertices), (void**)&pVertices, 0 ) ) )  
  294.             return E_FAIL;  
  295.         memcpy( pVertices, Vertices, sizeof(Vertices) );  
  296.         g_pVertexBuffer->Unlock();  
  297.   
  298.         //索引数组的设置   
  299.         WORD Indices[] ={ 0,1,2, 0,2,3, 0,3,4, 0,4,5, 0,5,6, 0,6,7, 0,7,8, 0,8,9, 0,9,10, 0,10,11 ,0,11,12, 0,12,13 ,0,13,14 ,0,14,15 ,0,15,16, 0, 16,1 };  
  300.   
  301.         // 填充索引数据   
  302.         WORD *pIndices = NULL;  
  303.         g_pIndexBuffer->Lock(0, 0, (void**)&pIndices, 0);  
  304.         memcpy( pIndices, Indices, sizeof(Indices) );  
  305.         g_pIndexBuffer->Unlock();  
  306.   
  307.     return S_OK;  
  308. }  
  309.   
  310. //*****************************************************************************************   
  311. // Name: Direct3D_Render()   
  312. // Desc: 进行图形的渲染操作   
  313. // Point:【Direct3D渲染五步曲】   
  314. //      1.渲染五步曲之一,清屏操作   
  315. //      2.渲染五步曲之二,开始绘制   
  316. //      3.渲染五步曲之三,正式绘制   
  317. //      4.渲染五步曲之四,结束绘制   
  318. //      5.渲染五步曲之五,翻转显示   
  319. //*****************************************************************************************   
  320.   
  321. void Direct3D_Render(HWND hwnd)  
  322. {  
  323.   
  324.     //--------------------------------------------------------------------------------------   
  325.     // 【Direct3D渲染五步曲之一】:清屏操作   
  326.     //--------------------------------------------------------------------------------------   
  327.     g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);  
  328.   
  329.     //定义一个矩形,用于获取主窗口矩形   
  330.     RECT formatRect;  
  331.     GetClientRect(hwnd, &formatRect);  
  332.   
  333.     //--------------------------------------------------------------------------------------   
  334.     // 【Direct3D渲染五步曲之二】:开始绘制   
  335.     //--------------------------------------------------------------------------------------   
  336.     g_pd3dDevice->BeginScene();                     // 开始绘制   
  337.     //--------------------------------------------------------------------------------------   
  338.     // 【Direct3D渲染五步曲之三】:正式绘制,利用顶点缓存绘制图形   
  339.     //--------------------------------------------------------------------------------------   
  340.   
  341.     //--------------------------------------------------------------------------------------   
  342.     // 【顶点缓存、索引缓存绘图四步曲之四】:绘制图形   
  343.     //--------------------------------------------------------------------------------------   
  344.     // 设置渲染状态   
  345.     g_pd3dDevice->SetRenderState(D3DRS_SHADEMODE,D3DSHADE_GOURAUD);  //这句代码可省略,因为高洛德着色模式胃D3D默认的着色模式   
  346.   
  347.     g_pd3dDevice->SetStreamSource( 0, g_pVertexBuffer, 0, sizeof(CUSTOMVERTEX) );//把包含的几何体信息的顶点缓存和渲染流水线相关联   
  348.     g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );//指定我们使用的灵活顶点格式的宏名称   
  349.     g_pd3dDevice->SetIndices(g_pIndexBuffer);//设置索引缓存   
  350.     g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 17, 0, 16);//利用索引缓存配合顶点缓存绘制图形   
  351.   
  352.   
  353.     //在窗口右上角处,显示每秒帧数   
  354.     int charCount = swprintf_s(g_strFPS, 20, _T("FPS:%0.3f"), Get_FPS() );  
  355.     g_pFont->DrawText(NULL, g_strFPS, charCount , &formatRect, DT_TOP | DT_RIGHT, D3DCOLOR_XRGB(255,239,136));  
  356.   
  357.     //--------------------------------------------------------------------------------------   
  358.     // 【Direct3D渲染五步曲之四】:结束绘制   
  359.     //--------------------------------------------------------------------------------------   
  360.     g_pd3dDevice->EndScene();                       // 结束绘制   
  361.     //--------------------------------------------------------------------------------------   
  362.     // 【Direct3D渲染五步曲之五】:显示翻转   
  363.     //--------------------------------------------------------------------------------------   
  364.     g_pd3dDevice->Present(NULL, NULL, NULL, NULL);  // 翻转与显示   
  365.        
  366. }  
  367.   
  368.   
  369. //*****************************************************************************************   
  370. // Name:Get_FPS()函数   
  371. // Desc: 用于计算帧速率   
  372. //*****************************************************************************************   
  373. float Get_FPS()  
  374. {  
  375.   
  376.     //定义四个静态变量   
  377.     static float  fps = 0; //我们需要计算的FPS值   
  378.     static int    frameCount = 0;//帧数   
  379.     static float  currentTime =0.0f;//当前时间   
  380.     static float  lastTime = 0.0f;//持续时间   
  381.   
  382.     frameCount++;//每调用一次Get_FPS()函数,帧数自增1   
  383.     currentTime = timeGetTime()*0.001f;//获取系统时间,其中timeGetTime函数返回的是以毫秒为单位的系统时间,所以需要乘以0.001,得到单位为秒的时间   
  384.   
  385.     //如果当前时间减去持续时间大于了1秒钟,就进行一次FPS的计算和持续时间的更新,并将帧数值清零   
  386.     if(currentTime - lastTime > 1.0f) //将时间控制在1秒钟   
  387.     {  
  388.         fps = (float)frameCount /(currentTime - lastTime);//计算这1秒钟的FPS值   
  389.         lastTime = currentTime; //将当前时间currentTime赋给持续时间lastTime,作为下一秒的基准时间   
  390.         frameCount    = 0;//将本次帧数frameCount值清零   
  391.     }  
  392.   
  393.     return fps;  
  394. }  
  395.   
  396.   
  397. //*****************************************************************************************   
  398. // Name: Direct3D_CleanUp()   
  399. // Desc: 对Direct3D的资源进行清理,释放COM接口对象   
  400. //*****************************************************************************************   
  401. void Direct3D_CleanUp()  
  402. {  
  403.     //释放COM接口对象   
  404.     SAFE_RELEASE(g_pIndexBuffer)  
  405.     SAFE_RELEASE(g_pVertexBuffer)  
  406.     SAFE_RELEASE(g_pFont)  
  407.     SAFE_RELEASE(g_pd3dDevice)    
  408. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值