zoukankan      html  css  js  c++  java
  • [Direct3D 9.0] 第一个程序 旋转立方体

      1 #include <Windows.h>
      2 #include <d3d9.h>
      3 #include <D3DX10math.h>
      4 #include <strsafe.h>
      5 //全局变量 
      6 
      7 LPDIRECT3D9 d3D9 = NULL;                                         // IDirect3D9接口指针,用于获得物理设备信息和创建IDirect3DDeivce9接口。
      8 LPDIRECT3DDEVICE9 d3dDevice = NULL;                    // 代表显示3d图形的物理设备的C++对象。
      9 LPDIRECT3DVERTEXBUFFER9 vertexBuffer = NULL;   // 顶点缓存,用于存储顶点坐标。
     10 LPDIRECT3DINDEXBUFFER9 indexBuffer = NULL;     // 索引缓存,用于存储组成各个三角形的顶点的索引
     11 
     12 struct Vertex  // 三维中顶点结构
     13 {
     14     float x, y, z;
     15 };
     16 
     17 //初始化 Direct3D
     18 BOOL InitD3D(HWND hwnd)
     19 {
     20     if( NULL == (d3D9 = Direct3DCreate9(D3D_SDK_VERSION))) //  该初始化函数保证应用程序通过正确的头文件被生成。
     21         return E_FAIL;  
     22 
     23 
     24 
     25     D3DCAPS9 caps;                            //device capabilitites
     26     d3D9->GetDeviceCaps(                 // 获取设备信息
     27         D3DADAPTER_DEFAULT,            //Adapter 指定获取哪个显示适配器的特性
     28         D3DDEVTYPE_HAL,                   // 设备类型 硬件设备:D3DDEVTYPE_HAL 软件设备:D3DDEVTYPE_REF
     29         &caps);                                    //返回填充后的D3DCAPS9结构。
     30 
     31     int vp = 0;                               //代表是否支持硬件顶点处理
     32     if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)  //显卡是否支持硬件几何转换和光源计算
     33     {
     34         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; //支持,硬件方式处理顶点
     35     }
     36     else
     37     {
     38         vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;  //软件方式处理顶点
     39     }
     40 
     41     D3DPRESENT_PARAMETERS d3dparam;   // 这个结构用于设定我们将要创建的IDirect3DDevice9对象的一些特性
     42     ZeroMemory(&d3dparam, sizeof(d3dparam));
     43     d3dparam.BackBufferWidth = 800;                   //后备缓冲表面的宽度
     44     d3dparam.BackBufferHeight = 600;                    //后备缓冲表面的高度
     45     d3dparam.BackBufferFormat = D3DFMT_A8R8G8B8;  //后备缓冲表面的像素格式
     46     d3dparam.BackBufferCount = 1;                                 // 后备表面的个数
     47     d3dparam.MultiSampleType = D3DMULTISAMPLE_NONE;  //全屏抗锯齿的类型
     48     d3dparam.MultiSampleQuality = 0;                                   //全屏抗锯齿的质量等级
     49     d3dparam.SwapEffect = D3DSWAPEFFECT_DISCARD;            // 指定表面在交换链中是如何被交换的
     50     d3dparam.hDeviceWindow = hwnd;                          // 窗口句柄
     51     d3dparam.Windowed = true;                      //是否窗口模式
     52     d3dparam.EnableAutoDepthStencil = true;                // 深度/模板缓冲
     53     d3dparam.AutoDepthStencilFormat = D3DFMT_D24S8;            //深度/模板缓冲的等级
     54     d3dparam.Flags = 0;    // 一些附加特性
     55     d3dparam.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;    //刷新率
     56     d3dparam.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;  //属于D3DPRESENT 成员,又有两个常用标志,其余请查SDK:
     57     
     58     //创建IDirect3DDevcie9对象
     59     if(FAILED(d3D9->CreateDevice(        
     60         D3DADAPTER_DEFAULT,            //adapter
     61         D3DDEVTYPE_HAL,             //设备类型
     62         hwnd,                             //窗口句柄
     63         vp,                                 //顶点处理方式
     64         &d3dparam, &d3dDevice)))
     65     {
     66         return E_FAIL;
     67     }
     68     return true;
     69 }
     70  
     71 // 创建顶点缓存
     72 bool InitVertexBuffer()
     73 {
     74 
     75     // 初始化正方体的8顶点
     76     Vertex vertex[] = 
     77     {
     78         {-1.0f, -1.0f, -1.0f},
     79         {-1.0f,  1.0f, -1.0f},
     80         {1.0f, 1.0f, -1.0f},
     81         {1.0f, -1.0f, -1.0f},
     82         {-1.0f, -1.0f, 1.0f},
     83         {-1.0f, 1.0f, 1.0f},
     84         {1.0f, 1.0f, 1.0f},
     85         {1.0f, -1.0f, 1.0f}
     86     };
     87     if(FAILED(d3dDevice->CreateVertexBuffer(          //创建顶点缓存
     88         8*sizeof(Vertex),           // 分配给缓存的字节大小         
     89         0,                                 //指定关于怎样使用缓存的额外信息
     90         D3DFVF_XYZ,               // 存储杂牌缓存中的顶点格式
     91         D3DPOOL_DEFAULT,      //缓存放置在哪一个内存池中
     92         &vertexBuffer,                //返回创建好的顶点缓存的指针
     93         NULL)))                          // 没有使用
     94     {
     95         return false;
     96     }
     97     Vertex *vetices;
     98     vertexBuffer->Lock(0, 0, (void**)&vetices, 0);          //锁存整个缓存
     99     memcpy(vetices, vertex, sizeof(vertex));                   //想缓存里写顶点
    100     vertexBuffer->Unlock();                                         //解锁缓存
    101     return true;
    102 }
    103 
    104 //设置照相机和投影
    105 void SetupMatrices()
    106 {
    107 
    108     D3DXMATRIXA16 matWorld;
    109     UINT iTime = timeGetTime() % 1000;           //旋转
    110     FLOAT fAngle = iTime * ( 2.0f * D3DX_PI ) / 1000.0f;
    111     D3DXMatrixRotationY( &matWorld, fAngle );  //绕Y坐标旋转matWorord矩阵
    112     d3dDevice->SetTransform( D3DTS_WORLD, &matWorld );  //切换到世界坐标系中
    113 
    114     D3DXVECTOR3 position(5.0f, 5.0f, -5.0f);            //虚拟照相机坐标
    115     D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);                 // 目标物体坐标
    116     D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);                        //正上方坐标
    117     D3DXMATRIX v;                                                          
    118     D3DXMatrixLookAtLH(&v, &position, &target, &up);      //计算视图坐标系的变换矩阵   
    119 
    120     d3dDevice->SetTransform(D3DTS_VIEW, &v);    //视图坐标系变换
    121 
    122 
    123     D3DXMATRIX proj;                 //投影矩阵
    124     //计算投影矩阵
    125     D3DXMatrixPerspectiveFovLH(&proj,               
    126         D3DX_PI*0.5f,         //视野角度
    127         800.0/600.0,            //宽高比
    128         1.0f,                       //前裁剪面距离
    129         1000.0f);                   //后裁剪面距离
    130     d3dDevice->SetTransform(D3DTS_PROJECTION, &proj);        //设置投影变换
    131     d3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);         //以线框模式渲染物体
    132 }
    133 
    134 //初始化索引缓存
    135 bool InitIntextBuffer()
    136 {
    137     d3dDevice->CreateIndexBuffer(36*sizeof(WORD),        
    138         D3DUSAGE_WRITEONLY, 
    139         D3DFMT_INDEX16,                     //指定索引的大小
    140         D3DPOOL_MANAGED, 
    141         &indexBuffer, 
    142         0);
    143     WORD* indices = 0;
    144     indexBuffer->Lock(0, 0, (void**)&indices, 0);
    145 
    146     //前面
    147     indices[0] = 0; indices[1] = 1; indices[2] = 2;
    148     indices[3] = 0; indices[4] = 2; indices[5] = 3;
    149     // 背面
    150     indices[6] = 4; indices[7] = 6; indices[8] = 5;
    151     indices[9] = 4; indices[10] = 7; indices[11] = 6;
    152 
    153     // 左面
    154     indices[12] =4; indices[13] =5; indices[14] = 1;
    155     indices[15] = 4; indices[16] = 1; indices[17] = 0;
    156 
    157     // 右面
    158     indices[18] = 3; indices[19] = 2; indices[20] =6;
    159     indices[21] = 3; indices[22] = 6; indices[23] =7;
    160     //顶面
    161     indices[24] = 1; indices[25] = 5; indices[26] =6;
    162     indices[27] = 1; indices[28] = 6; indices[29] = 2;
    163     //底面
    164     indices[30] =4; indices[31] = 0; indices[32] =3;
    165     indices[33] = 4; indices[34] = 3; indices[35] = 7;
    166 
    167     indexBuffer->Unlock();
    168 
    169     
    170 
    171     return true;
    172 }
    173 
    174 //释放COM资源
    175 bool CleanUp()
    176 {
    177     if(indexBuffer != NULL)
    178         indexBuffer->Release();
    179     if(vertexBuffer != NULL)
    180         vertexBuffer->Release();
    181     if(d3dDevice != NULL)
    182         d3dDevice->Release();
    183     if(d3D9 != NULL)
    184         d3D9->Release();
    185     return true;
    186 }
    187 
    188 //渲染
    189 bool Render()         
    190 {
    191 
    192 
    193     d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
    194     if(SUCCEEDED(d3dDevice->BeginScene()))        //开始场景绘制
    195     {
    196         SetupMatrices();    //设置照相机和投影
    197 
    198         // 设置资源流与一个顶点缓存挂钩
    199         d3dDevice->SetStreamSource(0, vertexBuffer, 0, sizeof(Vertex));
    200         d3dDevice->SetIndices(indexBuffer);           //设置索引缓存
    201         d3dDevice->SetFVF(D3DFVF_XYZ);               //设置顶点格式
    202 
    203          //使用索引来绘制图元
    204         d3dDevice->DrawIndexedPrimitive(
    205             D3DPT_TRIANGLELIST,         //图元类型 
    206             0,                                         //一个基本数字,在调用中用它去加上索引
    207             0,                                         //将被引用的最小索引值
    208             8,                                         //顶点数
    209             0,                                         //开始渲染的开始索引点 
    210             12);                                       //绘制图元的个数
    211         d3dDevice->EndScene();             //结束场景绘制
    212     }
    213     d3dDevice->Present(NULL, NULL, NULL, NULL);        //翻转表面
    214     return true;
    215 }
    216 
    217 
    218 //消息处理函数
    219 LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
    220 {
    221     switch( msg )
    222     {
    223     case WM_DESTROY:
    224         CleanUp();
    225         PostQuitMessage( 0 );
    226         return 0;
    227     }
    228 
    229     return DefWindowProc( hwnd, msg, wParam, lParam );
    230 }
    231 
    232 //main函数
    233 INT WINAPI wWinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in LPWSTR lpCmdLine, __in int nShowCmd )
    234 {
    235     UNREFERENCED_PARAMETER(hInstance);
    236     WNDCLASSEX wc = {
    237         sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, 
    238         GetModuleHandle(NULL), NULL, NULL, NULL, NULL, 
    239         L"Cubedemo", NULL
    240     };
    241     RegisterClassEx(&wc);
    242     
    243     HWND hwnd = CreateWindow(L"CubeDemo", L"CubeDemo", 
    244         WS_OVERLAPPEDWINDOW, 100, 100, 800, 600, NULL, NULL, hInstance, NULL);
    245 
    246     if(InitD3D(hwnd))
    247     {
    248         if(InitVertexBuffer() && InitIntextBuffer())
    249         {
    250             ShowWindow(hwnd, SW_SHOWDEFAULT);
    251             UpdateWindow(hwnd);
    252             MSG msg;
    253             ZeroMemory(&msg, sizeof(msg));
    254             while(msg.message != WM_QUIT)
    255             {
    256                 if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
    257                 {
    258                     TranslateMessage(&msg);
    259                     DispatchMessage(&msg);
    260                 }
    261                 else
    262                 {
    263                     Render();
    264                 }    
    265             }
    266 
    267         }
    268     }
    269     UnregisterClass(L"CubeDemo", wc.hInstance);
    270     return 0;
    271 
    272 }
  • 相关阅读:
    kudu 存储引擎简析
    Kudu vs HBase
    HBase原理–所有Region切分的细节都在这里了
    4月第3周业务风控关注 | 文化部再次审查直播和游戏产品,已下架4939款直播应用
    知物由学 | 如何应对日益强大的零日攻击
    Apache 流框架 Flink,Spark Streaming,Storm对比分析(二)
    Apache 流框架 Flink,Spark Streaming,Storm对比分析(一)
    poj1637Sightseeing tour(混合图欧拉回路)
    计算机网络_学习笔记 第一章 概述
    [Codecademy] HTML&CSS 第三课:HTML Basic II
  • 原文地址:https://www.cnblogs.com/wangke1020/p/3672165.html
Copyright © 2011-2022 走看看