赞
踩
这是个令人十分激动的时刻,用Directx3D去渲染出一些形状,还有会动的形状。感觉就跟中了彩票一样的心情。
好了,以上都是废话。在上一次的文章中学会了如何初始化Directx3D环境,now!开始真正的干事情了,首先要渲染一个三维三角形。在前面的代码的基础上其实添加小量代码就可以实现渲染了,不过还是要了解几个东西。
1.可变定点格式FVF(Flexible Vertex Format),Directx3D用这种方法来定义顶点结构,以满足各种不同情况的需求。用户可以根据自己程序的不同需要来定义相应的顶点对象,忽略某些对象,这样实现了在渲染模型是节省内存和最小化流水线宽度的目的。在此并不打算详细的说明FVF,因为其实我也不懂。。。简单来说FVF是Directx3D提供给用户灵活的定义自己的顶点结构的方式,你的顶点结构可以很复杂也可以很简单,只有x, y, z三个坐标,这完全看你的需要。在此我们要渲染一个彩色的三角形,所以我们为我们的顶点结构添加了除坐标之外的一个属性color。
- struct CUSTOMVERTEX
- {
- FLOAT x, y, z, rhw;
- DWORD color;
- };
- HRESULT IDirect3Ddevice9::CreateVetexBuffer(
- UINT Length, //分配给缓冲区的字节数
- DWORD Usage, //标识缓冲区将会被怎样使用,设为0,标识没有附加属性
- DWORD FVF, //缓冲区存储的顶点的可变顶点格式FVF
- D3DPOOL pool, //缓冲区的内存池类型
- IDirect3DVertexBuffer9** ppVertexBuffer, //返回被创建的顶点缓冲区指针
- HANDLE* pShareHandle //暂时未使用,扩展部分,设为0
- );
在创建顶点缓冲区后,需要用我们预先定义好的顶点数据去填充这个缓冲区,由于缓冲区有可能在显存或系统内存中,首先调用Lock()方法锁定获取缓冲区的首地址:
- HRESULT IDirect3DVertexBuffer9::Lock(
- UNIT offsetToLock, //以字节计算的偏移地址,从缓冲区首部开始偏移地质处开始锁定
- UNIT sizeToLock, //锁定的字节数
- BYTE** ppData, //返回被锁定的缓冲区区域的头指针
- DWORD Flags, //描述缓冲区锁定方式的标识
- );
最后还要调用Unlock()解除锁定。
索引缓冲区的创建:和定点缓冲区类似
- HRESULT IDirect3DDevice9::CreateIndexBuffer(
- //参数含义基本和CreateVertexBuffer一样,只有Format不同
- UINT Length,
- DWORD Usage,
- D3DFORMAT Format, //确定哪种索引格式,有16位,和32位,它们可以容纳的最大索引不同
- D3DPOOL Pool,
- IDirect3DIndexBuffer** ppIndexBuffer,
- HANDLE* pShareHandle
- );
同样要用类似的Lock()方法锁定索引缓冲区:- HRESULT IDirect3DIndexBuffer9::Lock(
- UNIT offsetToLock, //以字节计算的偏移地址,从缓冲区首部开始偏移地质处开始锁定
- UNIT sizeToLock, //锁定的字节数
- BYTE** ppData, //返回被锁定的缓冲区区域的头指针
- DWORD Flags, //描述缓冲区锁定方式的标识
- );
同样的Unlock()方法
到此渲染的数据已经准备完毕,在渲染之前还需要做几件事情:
1、设定数据源,也就是顶点缓冲区,把数据挂接到渲染流水线上等待渲染。
- HRESULT IDirect3DDevice9::SetStreamSource(
- UINT StreamNumber, //根据显卡能力不同,可以支持多条流水线同时工作
- IDirect3DVertexBuffer9* pStreamData, //顶点缓冲区数据指针
- UINT offsetInBytes, //设置从缓冲区第几个字节开始挂接
- UINT Stride, //顶点缓冲区的顶点大小,以字节计算
- );
2、设置顶点格式:
SetFVF();
3、设置索引缓冲区:
SetIndices(IndexBuffer);
- //----------------------------------------------------------------------------
- //---------渲染一个一个基本的三维三角形
- //---------by coderLing 2013.3.29
- //----------------------------------------------------------------------------
-
- #include <d3d9.h>
-
- //------Some gobal variables---------------------------------------------------
- LPDIRECT3D9 g_pD3D = NULL; //用于创建D3DDevice 对象
- LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
- LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; //指向顶点缓冲区
-
- //------自定义顶点类型---------------------------------------------------------
- struct CUSTOMVERTEX
- {
- FLOAT x, y, z, rhw;
- DWORD color;
- };
-
- //------自定义的FVF------------------------------------------------------------
- #define D3DFVF_CUSTOMVERTEX ( D3DFVF_XYZRHW | D3DFVF_DIFFUSE)
-
- //------常量-------------------------------------------------------------------
- #define WND_NAME L"vertexBuffer"
- #define WND_TITLE L"Directx3D深入详解之——创建使用定点缓冲区"
-
- //------初始化Directx3D--------------------------------------------------------
- HRESULT InitD3D( HWND hWnd )
- {
- //创建 D3D 对象
- if( NULL == ( g_pD3D = Direct3DCreate9 ( D3D_SDK_VERSION) ) )
- return E_FAIL;
-
- //设置D3DPRESENT_PRAMETERS参数
- D3DPRESENT_PARAMETERS d3dpp;
- SecureZeroMemory( &d3dpp, sizeof(d3dpp) );
- d3dpp.Windowed = TRUE;
- d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
- d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
-
- //创建 D3DDevice
- if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
- D3DCREATE_SOFTWARE_VERTEXPROCESSING,
- &d3dpp, &g_pd3dDevice ) ) )
- {
- return E_FAIL;
- }
-
- return S_OK;
- }
-
-
- //------初始化顶点缓冲区--------------------------------------------------------
- HRESULT InitVB()
- {
- CUSTOMVERTEX vertices[] =
- {
- { 150.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, }, //x, y, z, rhw, color
- { 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
- { 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, },
- };
-
- //创建顶点缓冲区,要申请足够的内存空间
- if( FAILED( g_pd3dDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),
- 0, D3DFVF_CUSTOMVERTEX,
- D3DPOOL_DEFAULT, &g_pVB, NULL) ) )
- return E_FAIL;
-
- //把顶点数据填充到缓冲区中
- 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;
- }
-
- //------释放资源----------------------------------------------------------------------
- VOID Cleanup()
- {
- if( g_pVB != NULL)
- g_pVB->Release();
-
- if( g_pd3dDevice != NULL)
- g_pd3dDevice->Release();
-
- if( g_pD3D != NULL)
- g_pD3D->Release();
- }
-
-
- //--------渲染过程---------------------------------------------------------------------
- VOID Render()
- {
- //把背景缓冲区变为蓝色
- g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);
-
- //开始渲染
- if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
- {
- //绘制三角形
- 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);
- }
-
-
- //---------消息过程---------------------------------------------------------------------
- LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch( msg )
- {
- case WM_DESTROY:
- Cleanup();
- PostQuitMessage( 0 );
- return 0;
- }
-
- return DefWindowProc( hWnd, msg, wParam, lParam );
- }
-
- //---------WinMain()函数----------------------------------------------------------------
- INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT)
- {
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
- GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
- WND_NAME, NULL};
- RegisterClassEx( &wc );
-
- HWND hWnd = CreateWindow( WND_NAME, WND_TITLE, WS_OVERLAPPEDWINDOW,
- 100, 100, 300, 300, GetDesktopWindow(),
- NULL, wc.hInstance, NULL );
-
- if( SUCCEEDED( InitD3D(hWnd) ) )
- {
- if( SUCCEEDED( InitVB() ) )
- {
- ShowWindow( hWnd, SW_SHOWDEFAULT );
- UpdateWindow( hWnd );
-
- //消息循环
- MSG msg;
- SecureZeroMemory( &msg, sizeof(MSG) );
- while( msg.message != WM_QUIT )
- {
- if( PeekMessage( &msg, NULL,0U, 0U, PM_REMOVE ) )
- {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
- else
- Render();
- }
- }
- }
-
- UnregisterClass( WND_NAME, wc.hInstance );
- return 0;
- }
旋转立方体:
- //--------ColorfulCube----------------------------------------------------------------
- //--------by coderLing 2013.3.30
- //------------------------------------------------------------------------------------
-
- #include <d3d9.h>
- #include <d3dx9.h> //如果要使用D3DX库就必须加入这个头文件
-
- //定义使用到的顶点结构
- struct CUSTOMVERTEX
- {
- FLOAT x,y,z; //顶点坐标信息
- DWORD color; //顶点颜色信息
- };
-
- //定义顶点的FVF结构
- #define D3DFVF_CUSTOMVERTEX ( D3DFVF_XYZ | D3DFVF_DIFFUSE)
- #define WND_NAME L"ColorfulCube"
- #define WND_TITLE L"Directx3D游戏开发之-ColorfulCube"
-
- //some gobal variables
- LPDIRECT3D9 g_pD3D = NULL; //Direct3D对象指针,LP开头便是指针
- LPDIRECT3DDEVICE9 g_pD3DDevice = NULL; //Direct3D 设备
- LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; //顶点缓冲区指针
- LPDIRECT3DINDEXBUFFER9 g_pIB = NULL; //索引缓冲区指针
-
- //初始化Direct3D设备
- HRESULT InitD3D( HWND hWnd)
- {
- //创建Directx3D对象
- if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
- return E_FAIL;
-
- //填写创建Direct3D设备的结构体
- D3DPRESENT_PARAMETERS d3dpp;
- SecureZeroMemory( &d3dpp, sizeof( d3dpp ));
- d3dpp.Windowed = TRUE;
- d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
- d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
-
- //创建Direct3D设备
- if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
- D3DCREATE_SOFTWARE_VERTEXPROCESSING,
- &d3dpp, &g_pD3DDevice) ) )
- {
- return E_FAIL;
- }
-
- return S_OK;
- }
-
- //初始化绘图相关数据,顶点缓冲区,索引缓冲区
- HRESULT InitDraw()
- {
- //创建顶点缓冲区
- g_pD3DDevice->CreateVertexBuffer(
- 8 * sizeof(CUSTOMVERTEX),
- D3DUSAGE_WRITEONLY,
- D3DFVF_CUSTOMVERTEX,
- D3DPOOL_MANAGED,
- &g_pVB,
- 0);
-
- //创建索引缓冲区
- g_pD3DDevice->CreateIndexBuffer(
- 36 * sizeof(WORD),
- D3DUSAGE_WRITEONLY,
- D3DFMT_INDEX16,
- D3DPOOL_MANAGED,
- &g_pIB,
- 0);
-
- //创建立方体的8个顶点,每个顶点的颜色都不同
- //在绘制是,Direct3D会根据顶点的颜色对三角形内部像素进行插值,所以立方体看起来是彩色的
- CUSTOMVERTEX source_vertices[] ={
- { -1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB(255,0,0) },
- { -1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB(0,255,0) },
- { 1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB(0,0,255) },
- { 1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB(255,255,0) },
- { -1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB(255,0,255) },
- { -1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0,255,255) },
- { 1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0,0,0) },
- { 1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB(255,255,255) }
- };
-
- //把上面的顶点数据复制到所创建的缓冲区中
- CUSTOMVERTEX* pVertices;
- if( FAILED( g_pVB->Lock(0, 8*sizeof(CUSTOMVERTEX), (VOID**)&pVertices, 0) ) )
- return E_FAIL;
- memcpy( pVertices, source_vertices, 8*sizeof(CUSTOMVERTEX) );
- g_pVB->Unlock();
-
- //定义索引缓冲区的内容
- WORD* indices = 0;
- g_pIB->Lock(0, 0, (VOID**)&indices, 0);
- //正面
- indices[0] = 0; indices[1] = 1; indices[2] = 2;
- indices[3] = 0; indices[4] = 2; indices[5] = 3;
- //背面
- indices[6] = 4; indices[7] = 6; indices[8] = 5;
- indices[9] = 4; indices[10] = 7; indices[11] = 6;
- //左面
- indices[12] = 4; indices[13] = 5; indices[14] = 1;
- indices[15] = 4; indices[16] = 1; indices[17] = 0;
- //右面
- indices[18] = 3; indices[19] = 2; indices[20] = 6;
- indices[21] = 3; indices[22] = 6; indices[23] = 7;
- //顶面
- indices[24] = 1; indices[25] = 5; indices[26] = 6;
- indices[27] = 1; indices[28] = 6; indices[29] = 2;
- //顶面
- indices[30] = 4; indices[31] = 0; indices[32] = 3;
- indices[33] = 4; indices[34] = 3; indices[35] = 7;
-
- g_pIB->Unlock();
-
- //设置摄像机
- D3DXVECTOR3 position(0.0f, 0.0f, -5.0f);
- D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
- D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
- D3DXMATRIX V;
- D3DXMatrixLookAtLH(&V, &position, &target, &up);
- g_pD3DDevice->SetTransform(D3DTS_VIEW, &V);
-
- //设置投影矩阵
- D3DXMATRIX proj;
- D3DXMatrixPerspectiveFovLH(
- &proj,
- D3DX_PI * 0.5f,
- (float)800 / (float)600,
- 1.0f,
- 1000.0f
- );
- g_pD3DDevice->SetTransform( D3DTS_PROJECTION, &proj);
- //没有材质,纹理信息,关闭灯光显示出本身颜色
- g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
-
- return S_OK;
- }
-
- //------释放资源------------------------------------------------------------------------------
- VOID Cleanup()
- {
- if( g_pVB != NULL )
- g_pVB->Release();
-
- if( g_pIB != NULL )
- g_pIB->Release();
-
- if( g_pD3DDevice != NULL )
- g_pD3DDevice->Release();
-
- if( g_pD3D != NULL)
- g_pD3D->Release();
- }
-
- //--------渲染函数------------------------------------------------------------------
- VOID Render()
- {
- //清除屏幕缓冲区到蓝色屏幕
- g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 255),1.0f, 0);
-
- //开始绘制
- if( SUCCEEDED( g_pD3DDevice->BeginScene() ) )
- {
- //创建沿3个轴的矩阵
- D3DXMATRIXA16 matWorld_X;
- D3DXMatrixIdentity( &matWorld_X);
- D3DXMatrixRotationX( &matWorld_X, timeGetTime()/500.0f);
-
- D3DXMATRIXA16 matWorld_Y;
- D3DXMatrixIdentity( &matWorld_Y);
- D3DXMatrixRotationY( &matWorld_Y, timeGetTime()/500.0f);
-
- D3DXMATRIXA16 matWorld_Z;
- D3DXMatrixIdentity( &matWorld_Z);
- D3DXMatrixRotationZ( &matWorld_Z, timeGetTime()/500.0f);
-
- //设置物体的世界矩阵
- g_pD3DDevice->SetTransform( D3DTS_WORLD,
- &(matWorld_X*matWorld_Y*matWorld_Z) );
-
- g_pD3DDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
- g_pD3DDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
- g_pD3DDevice->SetIndices( g_pIB );
- g_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 8, 0,12);
-
- //结束绘制
- g_pD3DDevice->EndScene();
- }
-
- //显示
- g_pD3DDevice->Present( NULL, NULL, NULL, NULL);
- }
-
-
- //消息回调函数
- LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch( msg )
- {
- case WM_DESTROY:
- Cleanup();
- PostQuitMessage( 0 );
- return 0;
- }
-
- return DefWindowProc( hWnd, msg, wParam, lParam );
- }
-
- //Main函数
- INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT)
- {
- //创建及注册窗口类
- WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
- GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
- WND_NAME, NULL};
- RegisterClassEx( &wc );
-
- //创建窗口
- HWND hWnd = CreateWindow( WND_NAME, WND_TITLE, WS_OVERLAPPEDWINDOW,
- 100, 100, 800, 600, GetDesktopWindow(),
- NULL, wc.hInstance, NULL );
-
- if( SUCCEEDED( InitD3D(hWnd) ) )
- {
- if( SUCCEEDED( InitDraw() ) )
- {
- //显示窗口
- ShowWindow( hWnd, SW_SHOWDEFAULT );
- UpdateWindow( hWnd );
-
- //消息循环
- MSG msg;
- SecureZeroMemory( &msg, sizeof(msg) );
- while( msg.message != WM_QUIT )
- {
- if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
- {
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
- else
- Render();
- }
- }
- }
-
- UnregisterClass( WND_NAME, wc.hInstance );
- return 0;
- }
The End ~~~~~~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。