顶点缓存

一个顶点缓存是一块连续的存储了顶点数据的内存。

 

Length 分配给缓存的字节大小。假如想得到一个能存储3个顶点的顶点缓存,那么我们就要在顶点结构中设置这个参数为3 * sizeof ( Vertex ) 

Usage 指定关于怎样使用缓存的额外信息,可以为0,也可为一下几个参数的一个或多个组合:

D3DUSAGE_DYNAMIC——设置这个参数可以使缓存是动态的。在下一页说明静态和动态缓存。

D3DUSAGE_POINTS——这个参数指定缓存存储原始点。原始点将在第14章粒子系统中介绍。这个参数仅仅用在顶点缓冲中。

D3DUSAGE_SOFTWAREPROCESSING——使用软件顶点处理

D3DUSAGE_WRITEONLY——指定应用程序只能写缓存。它允许驱动程序分配最适合的内存地址作为写缓存。注意如果从创建好的这种缓存中读数据,将会返回错误信息。

FVF 存储在缓存中的顶点格式

Pool 缓存放置在哪一个内存池中

ppVertexBuffer 返回创建好的顶点缓存的指针。

pShareHandle  目前没有使用,一般传NULL。

访问顶点缓存

为了访问顶点缓存,我们需要得到一个指针,因此我们需要使用IDirect3DVertexBuffer9::LockIDirect3DVertexBuffer9 :: Unlock

 

OffsetToLock 偏移量,以字节为单位,从缓存开始位置到锁定开始位置的距离。

SizeToLock 锁定的字节数。

Flags 标记描述怎样锁定内存。它可能是或者是下面参数中的个或多个的组合

D3DLOCK_DISCARD——这个参数仅仅会在动态缓存时被使用。它指示硬件丢弃缓存并返回一个指向新分配的缓存的指针。这是很有用,因为当我们存取一个新分配的缓存时它允许硬件继续从丢弃的缓存渲染。这防止了硬件延迟。

D3DLOCK_NOO VERWRITE——这个参数仅仅会在动态缓存时被使用。它声明你将向缓存中添加数据。即,你不能向已经渲染的内存中写数据。这是有好处的因为他允许你在添加新数据到缓存的同时让硬件继续渲染。

D3DLOCK_READONLY——这个参数声明你锁定的缓存只能从中读取数据而不能写数据。这允许一些内在的优化。

投影(Projection)

视图坐标系的主要任务就是将3D 场景转化为2D 图像表示。这种从维转换成n-1 维的过程就叫做投影

投影变换的实质就是定义可视体(视景体),并将可视体内的几何图形投影到投影窗口上去。

 

pOut 返回投影矩阵。

fovy 用弧度表示视野角度。 

Aspect 宽高比,Width/Height

zn 前裁剪面距离。

zf 后裁剪面距离。

渲染管线

3D场景转换成2D图像显示在显示器上,这一系列必须完成的操作就叫做渲染管线。

其过程如下:

 Local Space->World Space->View Space->Backface Culling->Lighting->Clipping->Projection 

 ->Viewport Space->Rasterization

渲染管线中的许多级变换都是从一个坐标系到另一个坐标系的变换,可用IDirect3DDevice9::SetTranform来实现。

 

State 坐标系变换类型

pMatrix 变换矩阵

对于一个物体,通常在可视范围内背面是不可见的,那么背面拣选达到的效果则是拣选(删除)在可视范围内看不见的背面。

Direct3D 中默认顶点以顺时针方向(在观察坐标系中)形成的三角形为正面,以逆时针方向形成的三角形为背面,如果不想使用默认拣选状态可以通过IDirect3DDevice9::SetRenderState来实现

 

State 当为D3DRS_FILLMODE时可以改变填充模型

Value 填充模型

D3DFILL_POINT

D3DFILL_WIREFRAME 

D3DFILL_SOLID 

D3DFILL_FORCE_DWORD 

绘制准备

以下准备皆为IDirect3DDevice9的函数

1.设置资源流

 

StreamNumber 确定我们的顶点缓存与哪一个资源流挂钩。由于此处不适用多重流,所以默认使用0号流。

pStreamData 一个指向我们想与流挂钩的那个顶点缓存的指针

OffsetInBytes 相对流开始处的偏移量。以字节为单位,它指定被填入渲染管线的顶点数据

的开始位置。

Stride 我们在顶点缓存中操作的每个部分(每个顶点)的流的字节大小

2.设置顶点格式

 

FVF 指定后面用来绘图调用的顶点的顶点格式

3.设置索引缓存

假如我们使用了索引缓存,我们必须设置后面要用于绘制操作的索引缓存。

 

pIndexData 传递一个索引缓存指针的拷贝。

绘制图元(不使用索引信息)

 

PrimitiveType 图元类型,详情查看SDK手册。

StartVertex 索引到在顶点流中的一个元素。设置渲染顶点中的开始点。这个参数给予我

们一定的机动性,可以绘制一个顶点缓存中的某部分。

PrimitiveCount 绘制图元个数。

所有绘制方法都必须在IDirect3DDevice9::BeginSceneIDirect3DDevice9::EndScene

方法之间被调用

 

 
   
  1. #include <d3dx9.h> 
  2. #include <string.h> 
  3. #include <Windows.h> 
  4.  
  5.  
  6. #define WINDOWNAME TEXT("D3DGameFrame") 
  7. #define WINDOWCLASS TEXT("The GameFrame of Dull") 
  8.   
  9.  
  10.  
  11. #define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) 
  12. #define KEYUP(vk_code)   ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1) 
  13.  
  14. const int Width  = 640; 
  15. const int Height = 480; 
  16.  
  17. HWND      mainWindowHandle = NULL;  
  18. HINSTANCE hinstanceApp     = NULL;  
  19. bool      ESC              = true
  20.  
  21. IDirect3DDevice9* Device = NULL;  
  22. IDirect3D9* d3d9 = NULL; 
  23. HRESULT hr = NULL; 
  24.  
  25. IDirect3DVertexBuffer9* Triangle = NULL; 
  26.  
  27.  
  28. struct Vertex 
  29.     float x,y,z; 
  30. }; 
  31.  
  32. #define D3DFVF (D3DFVF_XYZ) 
  33.  
  34. LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) 
  35.     PAINTSTRUCT     ps;  
  36.     HDC             hdc;     
  37.  
  38.     switch( msg ) 
  39.     { 
  40.         case WM_PAINT:  
  41.             { 
  42.                 hdc = BeginPaint(hWnd,&ps);   
  43.  
  44.                 EndPaint(hWnd,&ps); 
  45.             }  
  46.             break
  47.         case WM_DESTROY: 
  48.             { 
  49.                 ::PostQuitMessage(0); 
  50.             }            
  51.             break;       
  52.     } 
  53.     return ::DefWindowProc(hWnd, msg, wParam, lParam); 
  54.  
  55.  
  56.  
  57. int GameInit(void *parms = NULL, int num_parms = 0) 
  58.     ESC = false
  59.  
  60.     Device->CreateVertexBuffer(3*sizeof(Vertex),D3DUSAGE_WRITEONLY,D3DFVF,D3DPOOL_MANAGED,&Triangle,NULL); 
  61.      
  62.     Vertex vertices[] = 
  63.     { 
  64.         {-1.0f, 0.0f, 2.0f}, 
  65.         {0.0f, 1.0f, 2.0f}, 
  66.         {1.0f, 0.0f, 2.0f} 
  67.     }; 
  68.      
  69.     void* pVertices; 
  70.     Triangle->Lock(0,0,(void **)&pVertices,0); 
  71.     memcpy(pVertices,vertices,sizeof(vertices)); 
  72.     Triangle->Unlock(); 
  73.  
  74.     D3DXMATRIX proj; 
  75.     D3DXMatrixPerspectiveFovLH(&proj,D3DX_PI * 0.5f,(float)Width/(float)Height,1.0f,1000.0f); 
  76.  
  77.     Device->SetTransform(D3DTS_PROJECTION,&proj); 
  78.     Device->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); 
  79.  
  80.     return 1; 
  81. }  
  82.  
  83.  
  84. int GameMain(void *parms = NULL, int num_parms = 0) 
  85.     if(ESC) return 0; 
  86.      
  87.     Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0); 
  88.  
  89.     Device->BeginScene(); 
  90.  
  91.     Device->SetStreamSource(0, Triangle, 0, sizeof(Vertex)); 
  92.     Device->SetFVF(D3DFVF); 
  93.  
  94.     // Draw one triangle. 
  95.     Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1); 
  96.  
  97.     Device->EndScene(); 
  98.     Device->Present(NULL, NULL, NULL, NULL); 
  99.      
  100.     if (KEYDOWN(VK_ESCAPE)) 
  101.     { 
  102.         ESC = true
  103.         SendMessage(mainWindowHandle,WM_CLOSE,0,0); 
  104.     } 
  105.          
  106.     return 1; 
  107.  
  108. }  
  109.  
  110.  
  111. int GameShutdown(void *parms = NULL, int num_parms = 0) 
  112.     if(NULL != Triangle) 
  113.     { 
  114.         Triangle->Release(); 
  115.         Triangle = NULL; 
  116.     } 
  117.  
  118.     if( NULL != d3d9) 
  119.     { 
  120.         d3d9->Release(); 
  121.         d3d9 = NULL; 
  122.     } 
  123.  
  124.  
  125.     if( NULL != Device) 
  126.     { 
  127.         Device->Release(); 
  128.         Device = NULL; 
  129.     } 
  130.     return 1; 
  131. }    
  132.  
  133.  
  134.  
  135.  
  136. int WINAPI WinMain(HINSTANCE hInstance, 
  137.                    HINSTANCE prevInstance,  
  138.                    PSTR cmdLine, 
  139.                    int showCmd) 
  140.     HWND hWnd; 
  141.     MSG msg; 
  142.     WNDCLASS wndClass; 
  143.  
  144.     wndClass.style         = CS_HREDRAW | CS_VREDRAW; 
  145.     wndClass.lpfnWndProc   = (WNDPROC)WndProc;  
  146.     wndClass.cbClsExtra    = NULL; 
  147.     wndClass.cbWndExtra    = NULL; 
  148.     wndClass.hInstance     = hInstance; 
  149.     wndClass.hIcon         = LoadIcon(0, IDI_APPLICATION); 
  150.     wndClass.hCursor       = LoadCursor(0, IDC_ARROW); 
  151.     wndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); 
  152.     wndClass.lpszMenuName  = NULL; 
  153.     wndClass.lpszClassName = WINDOWCLASS; 
  154.  
  155.     if( !RegisterClass(&wndClass) )  
  156.     { 
  157.         ::MessageBox(NULL, TEXT("RegisterClass() - FAILED"), NULL, NULL); 
  158.         return false
  159.     } 
  160.  
  161.     hWnd = CreateWindow(WINDOWCLASS, 
  162.                         WINDOWNAME,  
  163.                         WS_OVERLAPPEDWINDOW | WS_VISIBLE, 
  164.                         0, 0,  
  165.                         Width,  
  166.                         Height, 
  167.                         NULL, 
  168.                         NULL, 
  169.                         hInstance, 
  170.                         NULL);  
  171.  
  172.     if( !hWnd ) 
  173.     { 
  174.         ::MessageBox(NULL,TEXT( "CreateWindow() - FAILED"), NULL, NULL); 
  175.         return false
  176.     } 
  177.  
  178.  
  179.     hinstanceApp = hInstance; 
  180.     mainWindowHandle = hWnd; 
  181.  
  182.     ::ShowWindow(hWnd, SW_SHOW); 
  183.     ::UpdateWindow(hWnd); 
  184.  
  185.     //1: 获得一个IDirect3D9接口指针。 
  186.  
  187.      
  188.     d3d9 = Direct3DCreate9(D3D_SDK_VERSION); 
  189.     /*Direct3DCreate9 的唯一一个参数总是D3D_SDK_VERSION, 
  190.     这可以保证应用程序通过正确的头文件被生成。如果函数调用失败, 
  191.     那么它将返回一个空指针。*/ 
  192.  
  193.     if( !d3d9 ) 
  194.     { 
  195.         ::MessageBox(NULL, TEXT("Direct3DCreate9() - FAILED"), NULL, NULL); 
  196.         return false
  197.     } 
  198.  
  199.     //2:检查设备能力(D3DCAPS9),搞清楚主显卡是否支持硬件顶点处理。. 
  200.     //当我们创建一个IDirect3DDevice9对象来表示主显示设备时,必须要设定其顶点处理的类型。 
  201.      
  202.     D3DCAPS9 caps; 
  203.  
  204.     d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);// 填充主显示设备的能力(D3DCAPS9结构) 
  205.  
  206.     int vp = 0; 
  207.     if( caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ) 
  208.         vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; 
  209.     else 
  210.         vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; 
  211.  
  212.     //3: 初始化一个D3DPRESENT _PARAMETERS结构实例。 
  213.   
  214.     D3DPRESENT_PARAMETERS d3dpp; 
  215.     d3dpp.BackBufferWidth            = Width; 
  216.     d3dpp.BackBufferHeight           = Height; 
  217.     d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8; 
  218.     d3dpp.BackBufferCount            = 1; 
  219.     d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE; 
  220.     d3dpp.MultiSampleQuality         = 0; 
  221.     d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD;  
  222.     d3dpp.hDeviceWindow              = hWnd; 
  223.     d3dpp.Windowed                   = true;  
  224.     d3dpp.EnableAutoDepthStencil     = true;  
  225.     d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8; 
  226.     d3dpp.Flags                      = 0; 
  227.     d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; 
  228.     d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE; 
  229.  
  230.     //4:创建一个基于已经初始化好的D3DPRESENT _PARAMETERS结构的IDirect3DDevice9对象。 
  231.      
  232.     hr = d3d9->CreateDevice(//Creates a device to represent the display adapter. 
  233.         D3DADAPTER_DEFAULT, // primary adapter 
  234.         D3DDEVTYPE_HAL,     // device type 
  235.         hWnd,               // window associated with device 
  236.         vp,                 // vertex processing 
  237.         &d3dpp,             // present parameters 
  238.         &Device);           // return created device 
  239.  
  240.     if( FAILED(hr) ) 
  241.     { 
  242.         d3dpp.AutoDepthStencilFormat = D3DFMT_D16; 
  243.          
  244.         hr = d3d9->CreateDevice( 
  245.             D3DADAPTER_DEFAULT, 
  246.             D3DDEVTYPE_HAL, 
  247.             hWnd, 
  248.             vp, 
  249.             &d3dpp, 
  250.             &Device); 
  251.  
  252.         if( FAILED(hr) ) 
  253.         { 
  254.             d3d9->Release(); //释放d3d9 
  255.             ::MessageBox(NULL, TEXT("CreateDevice() - FAILED"), NULL, NULL); 
  256.             return false
  257.         } 
  258.     } 
  259.  
  260.     GameInit(); 
  261.  
  262.     while(TRUE) 
  263.     { 
  264.      
  265.         if(PeekMessage(&msg,NULL,0,0,PM_REMOVE)) 
  266.         {  
  267.             if (msg.message == WM_QUIT) 
  268.                 break;   
  269.             TranslateMessage(&msg); 
  270.             DispatchMessage(&msg); 
  271.         } 
  272.  
  273.         GameMain(); 
  274.          
  275.     }  
  276.  
  277.     GameShutdown(); 
  278.     return 0;