我的Direct3D之路2:学习第一个三角形绘制程序以及一些注意点
来源:互联网 发布:mac上类似美图秀秀 编辑:程序博客网 时间:2024/04/30 02:03
打开\Samples\C++\Direct3D\Tutorials\Tut02_Vertices路径下的工程,这就是微软给的官方绘图教程。
一、窗口主程序
程序有点乱,先看窗口主程序INT WINAPI wWinMain( HINSTANCE hInst, HINSTANCE, LPWSTR, INT ){ UNREFERENCED_PARAMETER( hInst ); //注册一个窗口类 WNDCLASSEX wc = { sizeof( WNDCLASSEX ), CS_CLASSDC, MsgProc, 0L, 0L, GetModuleHandle( NULL ), NULL, NULL, NULL, NULL, L"D3D Tutorial", NULL }; RegisterClassEx( &wc ); // 创建一个应用程序窗口 HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 02: Vertices", WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, wc.hInstance, NULL ); // 初始化Direct3D if( SUCCEEDED( InitD3D( hWnd ) ) ) { // 创建顶点缓冲 if( SUCCEEDED( InitVB() ) ) { // 显示窗口 ShowWindow( hWnd, SW_SHOWDEFAULT ); UpdateWindow( hWnd ); // 进入Message循环 MSG msg; ZeroMemory( &msg, sizeof( msg ) ); while( msg.message != WM_QUIT ) { if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else Render(); } } } UnregisterClass( L"D3D Tutorial", wc.hInstance ); return 0;}
参数多的眼花缭乱,但都不是重要的,跟着注释走知道在干嘛就行了
大概分为五步:
1.窗口创建
2.初始化D3D设备
3.创建顶点缓存
4.显示窗口
5.进入Message循环(在Message循环里面执行渲染)
其中我觉得比较重要需要注意的是
HWND hWnd = CreateWindow( L"D3D Tutorial", L"D3D Tutorial 02: Vertices",WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,NULL, NULL, wc.hInstance, NULL );
这个函数里的100,100,300,300的意思是指从屏幕坐标的100,100开始创建一个300,300大小的窗口
如果改成CreateWindow( L"D3D Tutorial", L"D3D Tutorial 02: Vertices",WS_OVERLAPPEDWINDOW,200, 200, 600, 600,NULL, NULL, wc.hInstance, NULL );
窗口就会这样显示
还有消息循环,windows通过这种循环让窗口能随时被缩放移动等,我们的渲染函数写在这里
二、D3D的初始化
HRESULT InitD3D( HWND hWnd ){ // 创建D3D物体 if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) ) return E_FAIL; // 建立一个结构体用于D3D设备的创建 D3DPRESENT_PARAMETERS d3dpp; ZeroMemory( &d3dpp, sizeof( d3dpp ) ); d3dpp.Windowed = TRUE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; // 创建D3D设备 if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice ) ) ) { return E_FAIL; } return S_OK;}
需要注意的是d3dpp.Windowed属性决定了是否是窗口模式,d3dpp.SwapEffect属性上一章详细介绍过,不说了,具体链接如下:
Direct3D补充篇:表面缓冲区技术实现动画的流畅显示
d3dpp.BackBufferFormat属性是后缓冲区的格式,一般窗口模式可用D3DFMT_UNKNOWN,全屏模式是CheckDeviceType的返回值
创建D3D设备的函数HRESULT CreateDevice(
UINT Adapter, //显卡序列号
D3DDEVTYPE DeviceType, //D3D设备类型
HWND hFocusWindow, //所属窗口句柄
DWORD BehaviorFlags, //设备进行3D运算方式
D3DPRESENT_PARAMETERS *pPresentationParameters, //用于存储D3D设备相关信息的指针
IDirect3DDevice9 ** ppReturnedDeviceInterface //返回D3D设备接口指针的地址
);
而我们创建CreateDevice( D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice )
其中D3DADAPTER_DEFAULT是指默认的显卡(如果你的是双显卡的电脑,就要看一看这个属性了)
D3DDEVTYPE_HAL和D3DCREATE_SOFTWARE_VERTEXPROCESSING组合可以实现不同的处理方式:
D3DDEVTYPE_HAL和D3DCREATE_HARDWARE_VERTEXPROCESSING组合:完全交由GPU处理
D3DDEVTYPE_HAL和D3DCREATE_MIXED_VERTEXPROCESSING组合:顶点处理可由CPU或者GPU来做,其他是GPU
D3DDEVTYPE_HAL和D3DCREATE_SOFTWARE_VERTEXPROCESSING组合:顶点处理由CPU,其他由GPU来处理
D3DDEVTYPE_REF和D3DCREATE_SOFTWARE_VERTEXPROCESSING组合:完全由CPU来做,这个很慢
三、创建顶点缓存
在执行这个函数之前,我们在全局变量里面定义了一个结构体// 自定义顶点类型的结构体struct CUSTOMVERTEX{ FLOAT x, y, z, rhw; // 顶点的位置 DWORD color; // 顶点的颜色};可是D3D不知道这个结构体中的这些数据记录了什么,我们要指定一种格式让D3D能识别这个结构体
// 自定义的FVF#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)这是一种灵活顶点格式 ( Flexible Vertex Format )FVF
FVF的格式可以是以下类型的组合
D3DFVF_XYZ包含未经转换的顶点坐标
D3DFVF_XYZRHW包含经过转换的顶点坐标
D3DFVF_XYZW包含经过转换和裁剪的顶点坐标
D3DFVF_XYZB1………D3DFVF_XYZB5包含用于骨骼动画的顶点和顶点对骨骼的权重信息
D3DFVF_NORMAL包含法线信息
D3DFVF_PSIZE顶点信息指明绘制点的大小
D3DFVF_DIFFUSE包含漫反射的信息
D3DFVF_SPECULAR包含镜面反射的信息
D3DFVF_TEX0………D3DFVF_TEX8包含0-8个纹理坐标信息
所以现在我们指定位置1为D3DFVF_XYZRHW包含经过转换的顶点坐标,位置2为D3DFVF_DIFFUSE包含漫反射的信息(这个在这里就是颜色)
HRESULT InitVB()//初始化顶点缓存{ //为了渲染一个三角形,我们需要初始化三个顶点 CUSTOMVERTEX vertices[] = { { 150.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, }, // x,y,z为坐标,rhw为,后面表示颜色 { 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, }, { 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, }, };//创建顶点缓冲,我们从默认缓冲池中分配足够的内存,存储3个顶点,指定了FVF格式,所以顶点缓冲知道包含的数据 if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3 * sizeof( CUSTOMVERTEX ), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL ) ) ) { return E_FAIL; } // Now we fill the vertex buffer. To do this, we need to Lock() the VB to // gain access to the vertices. This mechanism is required becuase vertex // buffers may be in device memory.//填充缓冲区,先Lock,在填充最后Unlock(这个过程是必需的) VOID* pVertices; if( FAILED( g_pVB->Lock( 0, sizeof( vertices ), ( void** )&pVertices, 0 ) ) ) return E_FAIL; memcpy( pVertices, vertices, sizeof( vertices ) ); g_pVB->Unlock(); return S_OK;}D3DFVF_XYZRHW和D3DFVF_XYZ的区别我们要搞懂
在顶点结构体中没有RHW时,Direct3D将执行视、投影、世界等变换以及进行光线计算,之后你才能在窗口中得到你所绘制的物体。当顶点结构体中有RHW时,告知Direct3D使用的顶点已经在屏幕坐标系中了,不再执行视图、投影、世界等变换和光线计算,因为D3DFVF_XYZRHW标志告诉它顶点已经经过了这些处理,并直接将顶点进行光栅操作,任何用SetTransform进行的转换都对其无效。不过这时的原点就在客户区的左上角了,其中x向右为正,y向下为正,而z的意义已经变为z-buffer的象素深度。
为D3DFVF_XYZ时,没有经过变换,原点在窗口中心,为D3DFVF_XYZRHW时,经过了变换,左上角的屏幕坐标为原点
然后我们再用这个结构体创建三个顶点。
四、渲染函数
VOID Render(){ //清除背景的缓冲 g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 255 ), 1.0f, 0 ); // 开始绘制场景 if( SUCCEEDED( g_pd3dDevice->BeginScene() ) ) {//用顶点缓冲来绘制三角形。这分为几个步骤。我们需要把顶点数据传给一个流,所以一开始我们需要确定流的来源,就是我们的顶点缓冲。//然后我们需要让D3D知道顶点的格式//最后用DrawPrimitive来做绘制 g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) ); g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 ); // 结束绘制场景 g_pd3dDevice->EndScene(); } // 交换后台缓存和前台缓存,并提交到渲染管道,将后台缓存内容渲染出来 g_pd3dDevice->Present( NULL, NULL, NULL, NULL );}
1.刷新背景缓存
2.开始绘制
3.交换后台缓存和前台缓存
在我们刷新背景的时候可以定义背景的颜色D3DCOLOR_XRGB( 0, 0, 255 ),目前是0,0,225为蓝色
DrawPrimitive函数绘制的时候,需要指定图元类型
D3D图元类型是分六种:
点列集合 D3DPT_POINTLIST 一组点的集合
线列集合 D3DPT_LINELIST 一组线段的集合
线带集合 D3DPT_LINESTRIP 首尾相连的线段的集合
三角形列 D3DPT_TRIANGLELIST 一组三角形的集合
三角形带 D3DPT_TRIANGLESTRIP 首尾相连的三角形,有两个顶点重合
三角形扇 D3DPT_TRIANGLEFAN 组成扇形的一组三角形
这里使用了D3DPT_TRIANGLELIST
五、参考文献:
- 我的Direct3D之路2:学习第一个三角形绘制程序以及一些注意点
- 我的Direct3D学习之路3:第一个3D绘图程序
- 我的第一个Direct3D程序——第一个三角形
- 我的第一个DirectX程序界面及三角形的绘制
- 我的java学习路之编写第一个程序
- 异常的学习以及一些注意点
- 我的第一个VTK程序--绘制球体
- Java学习之路之“我的第一个Java程序“HelloWorld””
- OpenGL(二)第一个OpenGL程序绘制三角形
- 我的嵌入式学习之路(一) linux 跑的第一个程序 LED灯
- Android之我的第一个程序
- Direct3D 11教程2:绘制一个三角形
- 我的SSH之旅 (2) : 第一个SpringMVC程序
- JAVA的第一个程序以及一些名词
- JavaEE学习之路|我的第一个servlet
- Direct3D编程第一个程序框架
- 微信小程序发现的一些小问题以及解决方案集合以及注意点
- DP的一些注意点以及题目
- 关键字-分节2(static)
- webview系列:Html5页面和Native App怎么进行交互
- 关键字分节3(基本数据类型-short、int、long、char、float、double)
- reset css
- unity ToolTip
- 我的Direct3D之路2:学习第一个三角形绘制程序以及一些注意点
- 关键字-分节4(sizeof)
- 第三周项目3——求集合并集
- react-native笔记
- 考思科认证NA过程的学习笔记
- Remove Invalid Parentheses
- 关于ThreadLocal的一道面试题(酷我公司)
- spark 处理遇到的问题解决方法
- 关键字-分节5(signed、unsigned)