D3D矩阵Matrices

来源:互联网 发布:zip文件修复软件 编辑:程序博客网 时间:2024/06/09 13:44
  1. //使用矩阵  
  2. //熟悉创建设备和顶点的方法  
  3. //想要自由创建三维顶点,必须使用4*4大小的矩阵。基本的矩阵变换包括移动(transition)、  
  4. //旋转(rotation)和缩放(scaling)三种。几何信息为模型坐标系,必须变换为三维世界坐标系。  
  5. //这时使用世界矩阵,再次将世界坐标系的集合信息变换为摄像机坐标系。这时使用的是视图  
  6. //矩阵。只有将视图矩阵的集合信息投影到二维平面,才能绘制到窗口。也就是说:经过世界  
  7. //坐标->视图矩阵->投影矩阵的变换才能进行绘图(当然,还需要进行裁剪等处理工作)  
  8.   
  9. #include <Windows.h>  
  10. #include <mmsystem.h>         //使用TimeGetTime()函数包含的首部  
  11. #include <d3dx9.h>  
  12.   
  13. //全局参数  
  14. LPDIRECT3D9         g_pD3D  = NULL;  //创建D3D设备的D3D对象参数  
  15. LPDIRECT3DDEVICE9       g_pd3dDevice = NULL; //渲染使用中的D3D设备  
  16. LPDIRECT3DVERTEXBUFFER9     g_pVB   = NULL; //存储顶点的顶点缓冲  
  17.   
  18. //定义用户顶点的结构体  
  19. struct CUSTOMVERTEX  
  20. {  
  21.     FLOAT x, y, z;      //顶点的三维坐标  
  22.     DWORD color;        //顶点的颜色  
  23. };  
  24.   
  25. //表现用户顶点结构体信息的FVF  
  26. //结构体由X, Y, Z, RHW值和Diffuse颜色组成  
  27. #define D3DFVF_CUSTOMVERTEX  (D3DFVF_XYZ | D3DFVF_DIFFUSE)  
  28.   
  29.   
  30. //Direct3D初始化  
  31. HRESULT InitD3D(HWND hWnd)  
  32. {  
  33.     //创建一个用来创建设备的D3D对象  
  34.     if(NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))  
  35.         return E_FAIL;  
  36.   
  37.     //创建设备的结构体  
  38.     D3DPRESENT_PARAMETERS d3dpp;  
  39.     ZeroMemory(&d3dpp, sizeof(d3dpp));  
  40.     d3dpp.Windowed = TRUE;  
  41.     d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;  
  42.     d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;  
  43.   
  44.     //创建设备  
  45.     if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,  
  46.                 D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice)))  
  47.     {  
  48.         return E_FAIL;  
  49.     }  
  50.   
  51.     //起到卷起功能,对三角形的前面、后面进行渲染  
  52.     g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);  
  53.   
  54.     //顶点具有颜色值,能起到光源功能  
  55.     g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);  
  56.   
  57.     //这里对设备状态信息进行处理  
  58.     return S_OK;  
  59. }  
  60.   
  61. //几何信息初始化  
  62. HRESULT InitGeometry()  
  63. {  
  64.     //渲染三角形的三个顶点  
  65.     CUSTOMVERTEX g_Vertices[] =   
  66.     {  
  67.         { -1.0f, -1.0f, 0.0f, 0xffff0000, },  
  68.         {  1.0f, -1.0f, 0.0f, 0xff0000ff, },  
  69.         {  0.0f,  1.0f, 0.0f, 0xffffffff, },  
  70.     };  
  71.   
  72.     //创建顶点缓冲  
  73.     //分配存储三个用户顶点的存储器  
  74.     //指定存储FVF的数据格式  
  75.     if(FAILED(g_pd3dDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX,   
  76.                         D3DPOOL_DEFAULT, &g_pVB, NULL)))  
  77.     {  
  78.         return E_FAIL;  
  79.     }  
  80.   
  81.     //将数据写入顶点缓冲  
  82.     //调用顶点缓冲的Lock()函数,定义指针  
  83.     VOID* pVertices;  
  84.     if(FAILED(g_pVB->Lock(0, sizeof(g_Vertices), (void**)&pVertices, 0)))  
  85.         return E_FAIL;  
  86.     memcpy(pVertices, g_Vertices, sizeof(g_Vertices));  
  87.     g_pVB->Unlock();  
  88.   
  89.     return S_OK;  
  90. }  
  91.   
  92. //删除初始化对象  
  93. VOID Cleanup()  
  94. {  
  95.     if(g_pVB != NULL)  
  96.         g_pVB->Release();  
  97.   
  98.     if(g_pd3dDevice != NULL)  
  99.         g_pd3dDevice->Release();  
  100.   
  101.     if(g_pD3D != NULL)  
  102.         g_pD3D->Release();  
  103. }  
  104.   
  105. //创建矩阵:矩阵分为世界矩阵、视图矩阵、投影矩阵  
  106. VOID SetupMatrices()  
  107. {  
  108.     //世界矩阵  
  109.     D3DXMATRIXA16 matWorld;  
  110.   
  111.     UINT iTime = timeGetTime() % 1000;     //运行1000的余数运算,以保证Float运算的精确度  
  112.     FLOAT fAngle = iTime * (2.0f * D3DX_PI) / 1000.0f;    //创建每1000毫秒旋转一圈(2 * pi)的旋转矩阵  
  113.     D3DXMatrixRotationY(&matWorld, fAngle);              //创建以Y轴为旋转轴的旋转矩阵  
  114.     g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);      //在设备中将创建的矩阵设定为世界矩阵  
  115.   
  116.     //视图矩阵  
  117.     //定义视图矩阵需要3个值  
  118.     D3DXVECTOR3 vEyePt(0.0f, 3.0f, -5.0f);          //1.眼睛的位置(0,3.0,-5)  
  119.     D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f);        //2.眼睛观察的位置(0,0,0)  
  120.     D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f);           //3.表现顶点方向的上方向量(0,1,0)  
  121.     D3DXMATRIXA16 matView;  
  122.     D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec); //由1,2,3的值创建视图矩阵  
  123.     g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);        //在设备中设定创建的视图矩阵  
  124.   
  125.     //投影矩阵  
  126.     //定义投影矩阵需要视角(FOV = Field of view)、长宽比(aspect ratio)和裁剪平面的值  
  127.     D3DXMATRIXA16 matProj;  
  128.     //matProj       : 设定值的矩阵  
  129.     //D3DX_PI/4  : FOV (D3DX_PI/4 = 45°)  
  130.     //1.0f              : 长宽比  
  131.     //1.0f              : 近裁剪面(near clipping plane)  
  132.     //100.0f            : 远裁剪面(far clipping plane)  
  133.     D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f);  
  134.     g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);          //在设备中设定创建的投影矩阵  
  135. }  
  136.   
  137. //绘图  
  138. VOID Render()  
  139. {  
  140.     //将后置缓冲清除,同时设置为蓝色(0,0,255)  
  141.     g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);  
  142.   
  143.     //开始渲染  
  144.     if(SUCCEEDED(g_pd3dDevice->BeginScene()))  
  145.     {  
  146.         //创建世界矩阵、视图矩阵、投影矩阵  
  147.         SetupMatrices();  
  148.   
  149.         //绘制顶点缓冲的三角形  
  150.         //1.使包含顶点的缓冲绑定一个设备数据流  
  151.         g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));  
  152.         //2.想D3D指定顶点着色信息,大多数情况下只指定FVF格式  
  153.         g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);  
  154.         //3.调用输出几何的DrawPrimitive()函数  
  155.         g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);  
  156.   
  157.         //结束渲染  
  158.         g_pd3dDevice->EndScene();  
  159.     }  
  160.   
  161.     //显示后置缓冲的动画  
  162.     g_pd3dDevice->Present(NULL, NULL, NULL, NULL);  
  163.   
  164. }  
  165.   
  166. //窗口过程  
  167. LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)  
  168. {  
  169.     switch(msg)  
  170.     {  
  171.     case WM_DESTROY:  
  172.             Cleanup();  
  173.             PostQuitMessage(0);  
  174.             return 0;  
  175.     }  
  176.   
  177.     return DefWindowProc(hWnd, msg, wParam, lParam);  
  178. }  
  179.   
  180. //程序的起始地址  
  181. INT WINAPI WinMain(HINSTANCE hInst, HINSTANCELPSTRINT)  
  182. {  
  183.     //注册窗口类  
  184.     WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,  
  185.             GetModuleHandle(NULL), NULL, NULL, NULL, NULL,  
  186.             TEXT("D3D Tutorial"), NULL };  
  187.     RegisterClassEx(&wc);  
  188.   
  189.     //创建窗口 GetDesktopWindow()  
  190.     HWND hWnd = CreateWindow(TEXT("D3D Tutorial"), TEXT("D3D Tutorial 03:Matrices"),  
  191.                 WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,  
  192.                 GetDesktopWindow(), NULL, wc.hInstance, NULL);  
  193.   
  194.     //Direct3D初始化  
  195.     if(SUCCEEDED(InitD3D(hWnd)))  
  196.     {  
  197.         //顶点缓冲  
  198.         if(SUCCEEDED(InitGeometry()))  
  199.         {  
  200.             //显示窗口  
  201.             ShowWindow(hWnd,SW_SHOWDEFAULT);  
  202.             UpdateWindow(hWnd);  
  203.   
  204.             //消息循环  
  205.             MSG msg;  
  206.             ZeroMemory(&msg, sizeof(msg));  
  207.             while(msg.message != WM_QUIT)  
  208.             {  
  209.                 //消息队列中友消息时,调用相应的处理过程  
  210.                 if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))  
  211.                 {  
  212.                     TranslateMessage(&msg);  
  213.                     DispatchMessage(&msg);  
  214.                 }  
  215.                 else  
  216.                     //如果没有需要处理的消息,调用Reader()函数  
  217.                     Render();  
  218.             }  
  219.         }  
  220.     }  
  221.   
  222.     //删除注册的类  
  223.     UnregisterClass(TEXT("D3D Tutorial"), wc.hInstance);  
  224.     return 0;  
  225. }  
原创粉丝点击