矩阵

     对于XMMATRIX的初始化,可以有多种方法,一种方法是传4个XMVECTOR参数,每个XMVECTOR对应矩阵的一行;第二种方法是直接传递16个浮点数,代表整个矩阵的内容;第三种方法是用一个FLOAT型的数组,代表整个矩阵的内容。当然,这三种方法都有点麻烦,不过在实际中,自己来手动初始化矩阵的地方也不多,了解下其初始化方法即可。其次,XMMATRIX重载了()操作符,用来访问矩阵中的成员,用法跟正常矩阵访问完全一样,即传递两个参数(row, col)即可。 XMMATRIX也重载了*和*=操作符,用途很明显,用来进行矩阵的乘积。

    在函数定义中,类型为XMMATRIX的形参必须用CXMMATRIX类型代替。

 

1、 矩阵相关函数

 

  1. XMMATRIX XMMatrixIdentity();                //返回单位矩阵,即对角线全1,其他全0  
  2. BOOL     XMMatrixIsIdentity(CXMMATRIX M);       //判断一个矩阵是否为单位矩阵  
  3. XMMATRIX XMMatrixMultiply(CXMMATRIX A, CXMMATRIX B);    //两矩阵相乘  
  4. XMMATRIX XMMatrixTranspose(CXMMATRIX M);        //矩阵转置  
  5. XMVECTOR XMMatrixDeterminant(CXMMATRIX M);      //求矩阵对应行列式的值det  
  6. XMMATRIX XMMatrixInverse(XMVECTOR *pDet, CXMMATRIX M);  //求矩阵M的逆,*pDet为该矩阵的det  

 

 2、 3D中矩阵变换相关函数

 

  1. XMMATRIX XMMatrixScaling(FLOAT scaleX, FLOAT scaleY, FLOAT scaleZ); //伸缩变化,指定三个方向上的伸缩比  
  2. XMMATRIX XMMatrixScalingFromVector(FXMVECTOR scale);            //通过向量指定三个方向伸缩比,求伸缩变换  
  3. XMMATRIX XMMatrixRotationX(FLOAT angle);                //围绕x轴的旋转变换  
  4. XMMATRIX XMMatrixRotationY(FLOAT angle);                //围绕y轴的旋转变换  
  5. XMMATRIX XMMatrixRotationZ(FLOAT angle);                //围绕z轴的旋转变换  
  6. XMMATRIX XMMatrixRotationAxis(FXMVECTOR axis, FLOAT angle);     //围绕任意轴axis的旋转变换  
  7. XMMATRIX XMMatrixTranslation(FLOAT x, FLOAT y, FLOAT z);        //*移变换,指定三个方向的*移量  
  8. XMMATRIX XMMatrixTranslationFromVector(FXMVECTOR offset);       //通过向量指定三个方向的*移量,求*移变换  
  9. XMVECTOR XMVector3Transform(FXMVECTOR v, CXMMATRIX m);          //向量、矩阵相乘  
  10. XMVECTOR XMVector3TransformCoord(FXMVECTOR v, CXMMATRIX m);         //向量、矩阵相乘,但向量w=1,因此为点的变换  
  11. XMVECTOR XMVector3TransformNormal(FXMVECTOR v, CXMMATRIX m);        //向量、矩阵相乘,但向量w=0,因此为向量的变换  

 

数据格式

       D3D应用程序中,无论是纹理图片,还是创建的缓冲区,都有着特定的数据格式。D3D11支持有限的数据格式,以枚举变量形式存在,如下几种:

       DXGI_FORMAT_R32G32B32_FLOAT: 3个32位单精度符点数组成,比如用于代表三维空间坐标,以及24位颜色;

       DXGI_FORMAT_R16G16B16A16_UNORM: 4个16位数组成,每个成员位于[0,1.0f]之间,UNORM意指:unsigned normalized,即无符号,且归一化的;

       DXGI_FORMAT_R32G32_UINT:2个32位数组成,每个成员为无符号整型(unsigned int);

       DXGI_FORMAT_R8G8B8A8_UNORM:4个8位数组成,每个成员为[0,1.f]之间;

       DXGI_FORMAT_R8G8B8A8_SNORM:4个8位数组成,每个成员为[-1.0f, 1.0f]之间,SNORM意指:signed normalized;

       DXGI_FORMAT_R8G8B8A8_SINT:4个8位数组成,每个成员为有符号整型;

       此外还有很多其他类型的数据格式,熟悉各部分的意义后对任何类型可以很快从名字中得知其意思,也很容易写出指定意义的数据格式对应的枚举变量。数据格式在程序中使用相当频繁,因此很有必要提前熟悉该枚举类型变量的特点。

多重采样抗锯齿  Multisampling Atialiasing

 

[cpp] view plaincopy
 
  1. typedef struct DXGI_SAMPLE_DESC {  
  2.   UINT Count;  
  3.   UINT Quality;  
  4. } DXGI_SAMPLE_DESC, *LPDXGI_SAMPLE_DESC;  

Count为我们设置的采样的个数,Quality为机器支持的不同的等级,初始化过程中我们会对Quality进行检测。

注意Multisampling区别于super sampling的关键点:不同采样点是分别计算颜色值(super sampling)还是共享同一颜色值(Multisampling)。详细情况有很多参考书介绍。

 

Direct3D 初始化

 

Direct3D 初始化
初始化Direct3D,我们需要完成以下四个步骤:
1.定义我们需要检查的设备类型(device types)和特征级别(feature levels)
2.创建Direct3D设备,渲染设备(context)和交换链(swap chain)。
3.创建渲染目标(render target)。
4.设置视口(viewport)

交换链是设备和上下文将要绘制的渲染目标。

DXGI  即DirectX图形学基础,用于Direct3D交换链swap chains和枚举设备适配器
enumeration of deviceadapters的创建。
XInput 是之前版本DirectInput的一个补充,但XInput不支持键盘和鼠标等PC最常见的输入设备,所以涉及到键盘及鼠标消息的处理,还是需要使用DirectInput。

REFERENCED_PARAMETER用于避免变量定义后没在函数体中使用的编译警告

 ————————————————————————————————————————————————————————————

 D3D11的初始化主要有以下几个步骤:

       1. 创建设备ID3D11Device和设备上下文ID3D11DeviceContext;

       2. 检测多重采样支持的等级:CheckMultisampleQualityLevels

       3. 创建交换链

       4. 创建RenderTargetView

       5. 创建DepthStencilView

       6. 把上述两个视图绑定到渲染管线相应的阶段

       7. 设置Viewport

********************************************************************************

  1 #include <Windows.h>
  2 #include <string>
  3 #include <D3D11.h>
  4 #include <xnamath.h>
  5 
  6 using namespace std;
  7 
  8 //重要的全局变量
  9 //在后面学习过程中,这些全局将作为框架类的成员变量存在
 10 HINSTANCE    g_hInstance(NULL);
 11 HWND        g_hWnd(NULL);
 12 
 13 wstring        g_clsName(L"d3d11");
 14 wstring        g_wndTitle(L"D3D11初始化");
 15 
 16 UINT        g_winWidth(640);
 17 UINT        g_winHeight(480);
 18 
 19 //D3D相关全局变量
 20 ID3D11Device        *g_device(NULL);
 21 ID3D11DeviceContext    *g_deviceContext(NULL);
 22 IDXGISwapChain        *g_swapChain(NULL);
 23 
 24 ID3D11DepthStencilView    *g_depthStencilView(NULL);
 25 ID3D11RenderTargetView    *g_renderTargetView(NULL);
 26 
 27 //初始化
 28 BOOL InitWin32();
 29 //初始化D3D
 30 BOOL InitD3D();
 31 void Render();
 32 //主循环
 33 int     Run();
 34 //回收资源
 35 void Release();
 36 
 37 LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
 38 
 39 //程序入口
 40 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR cmdLine, int cmdShow)
 41 {
 42     g_hInstance = hInstance;
 43 
 44     if(!InitWin32())
 45         return -1;
 46     if(!InitD3D())
 47         return -1;
 48 
 49     return Run();
 50 }
 51 
 52 BOOL InitWin32()
 53 {
 54     //创建窗口类
 55     WNDCLASS wndcls;
 56     wndcls.cbClsExtra = 0;
 57     wndcls.cbWndExtra = 0;
 58     wndcls.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
 59     wndcls.hCursor = LoadCursor(NULL,IDC_ARROW);
 60     wndcls.hIcon = LoadIcon(NULL,IDI_APPLICATION);
 61     wndcls.hInstance = g_hInstance;
 62     wndcls.lpfnWndProc = WinProc;
 63     wndcls.lpszClassName = g_clsName.c_str();
 64     wndcls.lpszMenuName = NULL;
 65     wndcls.style = CS_HREDRAW | CS_VREDRAW;
 66 
 67     //注册窗口类
 68     if(!RegisterClass(&wndcls))
 69     {
 70         MessageBox(NULL,L"窗口注册失败!",L"错误",MB_OK);
 71         return FALSE;
 72     }
 73 
 74     //创建窗口
 75     g_hWnd = CreateWindow(g_clsName.c_str(),
 76                         g_wndTitle.c_str(),
 77                         WS_OVERLAPPEDWINDOW,
 78                          CW_USEDEFAULT,CW_USEDEFAULT,
 79                         g_winWidth,g_winHeight,
 80                         NULL,
 81                         NULL,
 82                         g_hInstance,
 83                         NULL);
 84     if(!g_hWnd)
 85     {
 86         MessageBox(NULL,L"窗口创建失败!",L"错误",MB_OK);
 87         return FALSE;
 88     }
 89 
 90     //显示、更新窗口
 91     ShowWindow(g_hWnd,SW_SHOW);
 92     UpdateWindow(g_hWnd);
 93 
 94     //Win32初始化完毕
 95     return TRUE;
 96 }
 97 
 98 BOOL InitD3D()
 99 {
100     //创建设备及上下文
101     D3D_FEATURE_LEVEL features[3] = {D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, D3D_FEATURE_LEVEL_9_3};
102     D3D_FEATURE_LEVEL myFeatureLevel;
103     HRESULT hr = D3D11CreateDevice(NULL,D3D_DRIVER_TYPE_HARDWARE,0,0,features,3,D3D11_SDK_VERSION,&g_device,&myFeatureLevel,&g_deviceContext);
104     if(FAILED(hr))
105     {
106         MessageBox(NULL,L"创建d3d11设备失败!",L"错误",MB_OK);
107         return FALSE;
108     }
109 
110     //检测4x采样等级
111     UINT msaa4xQuality(0);
112     g_device->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM,4,&msaa4xQuality);
113 
114     //创建交换链
115     //先描述其属性
116     DXGI_SWAP_CHAIN_DESC swapChainDesc = {0};
117     swapChainDesc.BufferDesc.Width = g_winWidth;                    //宽、高
118     swapChainDesc.BufferDesc.Height = g_winHeight;
119     swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;            //刷新率
120     swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
121     swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;                    //恒定参数,按照这样指明即可
122     swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;    //同上
123     swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;                        //数据格式,一个为RGBA四元色格式
124     swapChainDesc.BufferCount = 1;                                                        //后缓冲区个数,1个足够
125     swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;                        //Usage,很好理解
126     swapChainDesc.Flags = 0;    
127     swapChainDesc.OutputWindow = g_hWnd;                            //主窗口句柄
128     swapChainDesc.SampleDesc.Count = 4;                                //多重采样
129     swapChainDesc.SampleDesc.Quality = msaa4xQuality-1;
130     swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;            //交换:绝大多数情况用DISCARD
131     swapChainDesc.Windowed = true;                                    //窗口模式
132 
133     //获取IDXGIFactory以创建交换链
134     IDXGIDevice *dxgiDevice(NULL);
135     g_device->QueryInterface(__uuidof(IDXGIDevice),reinterpret_cast<void**>(&dxgiDevice));
136     IDXGIAdapter *dxgiAdapter(NULL);
137     dxgiDevice->GetParent(__uuidof(IDXGIAdapter),reinterpret_cast<void**>(&dxgiAdapter));
138     IDXGIFactory *dxgiFactory(NULL);
139     dxgiAdapter->GetParent(__uuidof(IDXGIFactory),reinterpret_cast<void**>(&dxgiFactory));
140     hr = dxgiFactory->CreateSwapChain(g_device,&swapChainDesc,&g_swapChain);
141     if(FAILED(hr))
142     {
143         MessageBox(NULL,L"创建d3d11交换链失败!",L"错误",MB_OK);
144         return FALSE;
145     }
146     dxgiFactory->Release();
147     dxgiAdapter->Release();
148     dxgiDevice->Release();
149 
150     //创建视图
151     //需要先获得资源
152     ID3D11Texture2D *backBuffer(NULL);
153     g_swapChain->GetBuffer(0,__uuidof(ID3D11Texture2D),reinterpret_cast<void**>(&backBuffer));
154     hr = g_device->CreateRenderTargetView(backBuffer,NULL,&g_renderTargetView);
155     if(FAILED(hr))
156     {
157         MessageBox(NULL,L"创建RenderTargetView失败!",L"错误",MB_OK);
158         return FALSE;
159     }
160     backBuffer->Release();
161 
162     //创建深度缓冲区视图
163     //要先创建对应缓冲区
164     //创建缓冲区Texture2D,要先给出描述
165     D3D11_TEXTURE2D_DESC desc = {0};
166     desc.Width = g_winWidth;
167     desc.Height = g_winHeight;
168     desc.MipLevels = 1;
169     desc.ArraySize = 1;
170     desc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
171     desc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
172     desc.MiscFlags = 0;
173     desc.SampleDesc.Count = 4;
174     desc.SampleDesc.Quality = msaa4xQuality-1;
175     desc.Usage = D3D11_USAGE_DEFAULT;
176     desc.CPUAccessFlags = 0;
177     ID3D11Texture2D *depthStencilBuffer(NULL);
178     hr = g_device->CreateTexture2D(&desc,NULL,&depthStencilBuffer);
179     if(FAILED(hr))
180     {
181         MessageBox(NULL,L"创建d3d11深度缓冲区失败!",L"错误",MB_OK);
182         return FALSE;
183     }
184     hr = g_device->CreateDepthStencilView(depthStencilBuffer,NULL,&g_depthStencilView);
185     if(FAILED(hr))
186     {
187         MessageBox(NULL,L"创建DepthStencilView失败!",L"错误",MB_OK);
188         return FALSE;
189     }
190 
191     //有了视图要绑定到管线相应阶段
192     g_deviceContext->OMSetRenderTargets(1,&g_renderTargetView,g_depthStencilView);
193     depthStencilBuffer->Release();
194 
195     //最后设置视口
196     D3D11_VIEWPORT viewPort = {0};
197     viewPort.Width = static_cast<FLOAT>(g_winWidth);
198     viewPort.Height = static_cast<FLOAT>(g_winHeight);
199     viewPort.MinDepth = 0.f;
200     viewPort.MaxDepth = 1.f;
201     viewPort.TopLeftX = 0.f;
202     viewPort.TopLeftY = 0.f;
203     g_deviceContext->RSSetViewports(1,&viewPort);
204 
205     return TRUE;
206 }
207 
208 void Render()
209 {
210     //渲染一个绿色的窗口
211     XMVECTORF32 color = {0.f, 1.f, 0.f, 1.6f};
212     g_deviceContext->ClearRenderTargetView(g_renderTargetView,reinterpret_cast<float*>(&color));
213     g_deviceContext->ClearDepthStencilView(g_depthStencilView,D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL,1.f,0);
214 
215     //全部的场景绘制工作在这里面进行.....
216 
217     //最后显示
218     g_swapChain->Present(0,0);
219 }
220 
221 int Run()
222 {
223     MSG msg = {0};
224     //主消息循环,也是游戏当中的主循环
225     while(msg.message != WM_QUIT)
226     {
227         if(PeekMessage(&msg,NULL,NULL,NULL,PM_REMOVE))
228         {
229             TranslateMessage(&msg);
230             DispatchMessage(&msg);
231         }
232         else
233         {
234             //在这里做该做的事:渲染
235             Render();
236         }
237     }
238 
239     Release();
240 
241     return msg.wParam;
242 }
243 
244 void Release()
245 {
246     g_depthStencilView->Release();
247     g_renderTargetView->Release();
248     g_swapChain->Release();
249     g_deviceContext->Release();
250     g_device->Release();
251 }
252 
253 LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
254 {
255     switch(msg)
256     {
257     case WM_DESTROY:
258         PostQuitMessage(0);
259         return 0;
260     }
261 
262     return DefWindowProc(hwnd,msg,wParam,lParam);
263 }
View Code

相关文章: