假如设置这样的顶点格式:
- #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ)//灵活顶点格式
- struct CUSTOMVERTEX
- {
- D3DXVECTOR3 position;
- };
他告诉我们,顶点是未进行坐标转换和光照处理的,须我没手动处理,如果我们未处理会是怎样呢?
1 什么都不做:
- /******************************************************
- FileName: CTDUIMessage.h - TDOnline/UISystem
- Author: lsm Version: Date: 08/10/28
- Description: Manage message,include accept/post message etc.
- History:
- <author> <time> <version> <note>
- ******************************************************/
- /*-------------Head------------*/
- #include "assert.h"
- #include "d3dx9.h"
- #pragma warning(disable : 4996)
- #include "strsafe.h"
- #pragma warning(disable : 4996)
- LPDIRECT3D9 g_pD3DObj = NULL; //D3D 对象
- LPDIRECT3DDEVICE9 g_pD3DDev = NULL; //D3D 设备
- LPDIRECT3DVERTEXBUFFER9 g_pVerBuf = NULL; //顶点缓冲区
- TCHAR g_AppName[] = TEXT("D3D");//类名
- #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ)//灵活顶点格式
- struct CUSTOMVERTEX
- {
- D3DXVECTOR3 position;
- };
- /*---------------End------------*/
- /*==========================================
- Function name: InitD3D
- Description: 初始化D3D对象
- ==========================================*/
- HRESULT InitD3D(HWND hWnd)
- {
- if((g_pD3DObj = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)//创建3D对象
- {
- assert(false);
- return E_FAIL;
- }
- D3DDISPLAYMODE devMode;
- if (FAILED(g_pD3DObj->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &devMode)))//获得显卡信息
- {
- assert(false);
- return E_FAIL;
- }
- D3DPRESENT_PARAMETERS d3dpp;
- ZeroMemory(&d3dpp, sizeof(d3dpp));
- d3dpp.Windowed = true;
- d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
- d3dpp.EnableAutoDepthStencil = true;
- d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
- d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
- if(FAILED(g_pD3DObj->CreateDevice(
- D3DADAPTER_DEFAULT,
- D3DDEVTYPE_HAL,
- hWnd,
- D3DCREATE_SOFTWARE_VERTEXPROCESSING,
- &d3dpp,
- &g_pD3DDev
- )))
- {
- assert(false);
- return E_FAIL;
- }
- g_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
- g_pD3DDev->SetRenderState(D3DRS_ZENABLE, true);
- g_pD3DDev->SetRenderState(D3DRS_LIGHTING, true);
- //g_pD3DDev->SetRenderState(D3DRS_AMBIENT, 0x00202020);
- return S_OK;
- }
- /*==========================================
- Function name: InitVBuf
- Description: 填充顶点缓冲区
- ==========================================*/
- HRESULT InitVBuf()
- {
- if (FAILED(g_pD3DDev->CreateVertexBuffer(
- 3*sizeof(CUSTOMVERTEX),
- 0,
- D3DFVF_CUSTOMVERTEX,
- D3DPOOL_DEFAULT,
- &g_pVerBuf,
- NULL
- )))
- {
- return E_FAIL;
- }
- CUSTOMVERTEX *vertices;
- if (FAILED(g_pVerBuf->Lock(0, 0, (void**)&vertices, 0)))//锁住内存
- {
- return E_FAIL;
- }
- vertices[0].position = D3DXVECTOR3(-1.0f,-1.0f, 0.0f);//四个点
- vertices[2].position = D3DXVECTOR3( 1.0f,-1.0f, 0.0f);
- vertices[1].position = D3DXVECTOR3( 1.0f, 1.0f, 0.0f);
- g_pVerBuf->Unlock();
- return S_OK;
- }
- /*==========================================
- Function name: ChangeWorld
- Description: 坐标变换和设置摄像机
- ==========================================*/
- HRESULT ChangeWorld()
- {
- D3DXMATRIXA16 matWorld;
- D3DXMatrixIdentity(&matWorld);
- g_pD3DDev->SetTransform(D3DTS_WORLD, &matWorld);
- D3DXMATRIXA16 matView;
- D3DXMatrixIdentity(&matView);
- D3DXVECTOR3 eyeVec (0.0f, 0.0f, -4.0f);
- D3DXVECTOR3 lookVec(0.0f, 0.0f, 0.0f);
- D3DXVECTOR3 upVec (0.0f, 1.0f, 0.0f);
- D3DXMatrixLookAtLH(&matView, &eyeVec, &lookVec, &upVec);
- g_pD3DDev->SetTransform(D3DTS_VIEW, &matView);
- D3DXMATRIXA16 matProj;
- D3DXMatrixIdentity(&matProj);
- D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
- g_pD3DDev->SetTransform(D3DTS_PROJECTION, &matProj);
- return S_OK;
- }
- /*==========================================
- Function name: ChangeWorld
- Description: 设置
- ==========================================*/
- HRESULT SetUpLightAndMatrial()
- {
- D3DMATERIAL9 d3dMat;
- ZeroMemory(&d3dMat, sizeof(D3DMATERIAL9));
- d3dMat.Ambient.a = d3dMat.Diffuse.a =1.0f;
- d3dMat.Ambient.r = d3dMat.Diffuse.r =0.0f;
- d3dMat.Ambient.g = d3dMat.Diffuse.g =1.0f;
- d3dMat.Ambient.b = d3dMat.Diffuse.b =1.0f;
- g_pD3DDev->SetMaterial(&d3dMat);
- return S_OK;
- }
- /*==========================================
- Function name: Cleanup
- Description: 释放对象
- ==========================================*/
- VOID Cleanup()
- {
- if (g_pVerBuf != NULL)
- {
- g_pVerBuf->Release();
- }
- if (g_pD3DDev != NULL)
- {
- g_pD3DDev->Release();
- }
- if (g_pD3DObj != NULL)
- {
- g_pD3DObj->Release();
- }
- }
- /*==========================================
- Function name: Render
- Description: 负责渲染
- ==========================================*/
- VOID Render()
- {
- if (g_pD3DDev == NULL)
- {
- return ;
- }
- g_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 255),1.0f, 0);
- if (SUCCEEDED(g_pD3DDev->BeginScene()))
- {
- //SetUpLightAndMatrial();//注意没使用
- //ChangeWorld();
- g_pD3DDev->SetStreamSource(0, g_pVerBuf, 0, sizeof(CUSTOMVERTEX));
- g_pD3DDev->SetFVF(D3DFVF_CUSTOMVERTEX);
- g_pD3DDev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
- g_pD3DDev->EndScene();
- }
- g_pD3DDev->Present(NULL, NULL, NULL, NULL);
- }
- /*==========================================
- Function name: MsgProc
- Description: 负责消息循环
- ==========================================*/
- 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);
- }
- /*==========================================
- Function name: WinMain
- Description: 程序启动函数
- ==========================================*/
- INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
- {
- WNDCLASSEX wc = {
- sizeof(WNDCLASSEX),
- CS_CLASSDC,
- MsgProc,
- 0L,
- 0L,
- GetModuleHandle(NULL),
- NULL,
- NULL,
- NULL,
- NULL,
- g_AppName,
- NULL
- };
- RegisterClassEx(&wc);
- HWND hWnd = CreateWindow(
- g_AppName,
- TEXT("D3D Tutorial 1"),
- WS_OVERLAPPEDWINDOW,
- 100,
- 100,
- 300,
- 300,
- NULL,
- NULL,
- wc.hInstance,
- NULL
- );
- if (hWnd == NULL)
- {
- return -1;
- }
- if(SUCCEEDED(InitD3D(hWnd)))
- {
- if(SUCCEEDED(InitVBuf()))
- {
- ShowWindow(hWnd, SW_SHOWDEFAULT);
- UpdateWindow(hWnd);
- MSG msg;
- ZeroMemory(&msg, sizeof(msg));
- while (msg.message != WM_QUIT)
- {
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- else
- {
- Render();
- }
- }
- }
- }
- UnregisterClass(g_AppName, wc.hInstance);
- return 0;
- }
上面即不进行坐标变换也不进行光照处理,结果屏幕右下角部分显示一个黑色的三角形
2 添加坐标变换:
- /*==========================================
- Function name: ChangeWorld
- Description: 坐标变换和设置摄像机
- ==========================================*/
- HRESULT ChangeWorld()
- {
- D3DXMATRIXA16 matWorld;
- D3DXMatrixIdentity(&matWorld);
- g_pD3DDev->SetTransform(D3DTS_WORLD, &matWorld);
- D3DXMATRIXA16 matView;
- D3DXMatrixIdentity(&matView);
- D3DXVECTOR3 eyeVec (0.0f, 0.0f, -4.0f);
- D3DXVECTOR3 lookVec(0.0f, 0.0f, 0.0f);
- D3DXVECTOR3 upVec (0.0f, 1.0f, 0.0f);
- D3DXMatrixLookAtLH(&matView, &eyeVec, &lookVec, &upVec);
- g_pD3DDev->SetTransform(D3DTS_VIEW, &matView);
- D3DXMATRIXA16 matProj;
- D3DXMatrixIdentity(&matProj);
- D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
- g_pD3DDev->SetTransform(D3DTS_PROJECTION, &matProj);
- return S_OK;
- }
结果三角形变小了,显然是经过了坐标变换,然后投影到屏幕上来。
3 添加材质:
- /*==========================================
- Function name: SetUpLightAndMatrial
- Description: 设置
- ==========================================*/
- HRESULT SetUpLightAndMatrial()
- {
- D3DMATERIAL9 d3dMat;
- ZeroMemory(&d3dMat, sizeof(D3DMATERIAL9));
- d3dMat.Ambient.a = d3dMat.Diffuse.a =1.0f;
- d3dMat.Ambient.r = d3dMat.Diffuse.r =0.0f;
- d3dMat.Ambient.g = d3dMat.Diffuse.g =1.0f;
- d3dMat.Ambient.b = d3dMat.Diffuse.b =1.0f;
- g_pD3DDev->SetMaterial(&d3dMat);
- return S_OK;
- }
设置环境光颜色
- g_pD3DDev->SetRenderState(D3DRS_AMBIENT, 0x00202020);
现在我们的三角形有颜色了
4 添加光照:
添加光照比较麻烦些,须在以下几点改改
(1)修改顶点格式:
- #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL)//灵活顶点格式
- struct CUSTOMVERTEX
- {
- D3DXVECTOR3 position;
- D3DXVECTOR3 normal;//添加法线
- };
(2)修改顶点数据:
- vertices[0].position = D3DXVECTOR3(-1.0f,-1.0f, 0.0f);//四个点
- vertices[0].normal = D3DXVECTOR3(-1.0f,-1.0f, -2.0f);
- vertices[2].position = D3DXVECTOR3( 1.0f,-1.0f, 0.0f);
- vertices[0].normal = D3DXVECTOR3(-1.0f,-1.0f, -2.0f);
- vertices[1].position = D3DXVECTOR3( 1.0f, 1.0f, 0.0f);
- vertices[0].normal = D3DXVECTOR3(-1.0f,-1.0f, -2.0f);
(3)添加灯光
- D3DLIGHT9 d3dlight;
- ZeroMemory(&d3dlight, sizeof(D3DLIGHT9));
- d3dlight.Type = D3DLIGHT_DIRECTIONAL;//平行光
- d3dlight.Direction = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
- d3dlight.Diffuse.r = 1.0f;
- d3dlight.Diffuse.g = 1.0f;
- d3dlight.Diffuse.b = 0.0f;
- d3dlight.Range = 1000.0f;
- g_pD3DDev->SetLight(0, &d3dlight);
- g_pD3DDev->LightEnable(0, true);
现在三角形又是另外一种颜色了
附整个代码:
- /******************************************************
- FileName: CTDUIMessage.h - TDOnline/UISystem
- Author: lsm Version: Date: 08/10/28
- Description: Manage message,include accept/post message etc.
- History:
- <author> <time> <version> <note>
- ******************************************************/
- /*-------------Head------------*/
- #include "assert.h"
- #include "d3dx9.h"
- #pragma warning(disable : 4996)
- #include "strsafe.h"
- #pragma warning(disable : 4996)
- LPDIRECT3D9 g_pD3DObj = NULL; //D3D 对象
- LPDIRECT3DDEVICE9 g_pD3DDev = NULL; //D3D 设备
- LPDIRECT3DVERTEXBUFFER9 g_pVerBuf = NULL; //顶点缓冲区
- TCHAR g_AppName[] = TEXT("D3D");//类名
- #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL)//灵活顶点格式
- struct CUSTOMVERTEX
- {
- D3DXVECTOR3 position;
- D3DXVECTOR3 normal;//添加法线
- };
- /*---------------End------------*/
- /*==========================================
- Function name: InitD3D
- Description: 初始化D3D对象
- ==========================================*/
- HRESULT InitD3D(HWND hWnd)
- {
- if((g_pD3DObj = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)//创建3D对象
- {
- assert(false);
- return E_FAIL;
- }
- D3DDISPLAYMODE devMode;
- if (FAILED(g_pD3DObj->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &devMode)))//获得显卡信息
- {
- assert(false);
- return E_FAIL;
- }
- D3DPRESENT_PARAMETERS d3dpp;
- ZeroMemory(&d3dpp, sizeof(d3dpp));
- d3dpp.Windowed = true;
- d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
- d3dpp.EnableAutoDepthStencil = true;
- d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
- d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
- if(FAILED(g_pD3DObj->CreateDevice(
- D3DADAPTER_DEFAULT,
- D3DDEVTYPE_HAL,
- hWnd,
- D3DCREATE_SOFTWARE_VERTEXPROCESSING,
- &d3dpp,
- &g_pD3DDev
- )))
- {
- assert(false);
- return E_FAIL;
- }
- g_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
- g_pD3DDev->SetRenderState(D3DRS_ZENABLE, true);
- g_pD3DDev->SetRenderState(D3DRS_LIGHTING, true);
- //g_pD3DDev->SetRenderState(D3DRS_AMBIENT, 0x00202020);
- return S_OK;
- }
- /*==========================================
- Function name: InitVBuf
- Description: 填充顶点缓冲区
- ==========================================*/
- HRESULT InitVBuf()
- {
- if (FAILED(g_pD3DDev->CreateVertexBuffer(
- 3*sizeof(CUSTOMVERTEX),
- 0,
- D3DFVF_CUSTOMVERTEX,
- D3DPOOL_DEFAULT,
- &g_pVerBuf,
- NULL
- )))
- {
- return E_FAIL;
- }
- CUSTOMVERTEX *vertices;
- if (FAILED(g_pVerBuf->Lock(0, 0, (void**)&vertices, 0)))//锁住内存
- {
- return E_FAIL;
- }
- vertices[0].position = D3DXVECTOR3(-1.0f,-1.0f, 0.0f);//四个点
- vertices[0].normal = D3DXVECTOR3(-1.0f,-1.0f, -2.0f);
- vertices[2].position = D3DXVECTOR3( 1.0f,-1.0f, 0.0f);
- vertices[0].normal = D3DXVECTOR3(-1.0f,-1.0f, -2.0f);
- vertices[1].position = D3DXVECTOR3( 1.0f, 1.0f, 0.0f);
- vertices[0].normal = D3DXVECTOR3(-1.0f,-1.0f, -2.0f);
- g_pVerBuf->Unlock();
- return S_OK;
- }
- /*==========================================
- Function name: ChangeWorld
- Description: 坐标变换和设置摄像机
- ==========================================*/
- HRESULT ChangeWorld()
- {
- D3DXMATRIXA16 matWorld;
- D3DXMatrixIdentity(&matWorld);
- g_pD3DDev->SetTransform(D3DTS_WORLD, &matWorld);
- D3DXMATRIXA16 matView;
- D3DXMatrixIdentity(&matView);
- D3DXVECTOR3 eyeVec (0.0f, 0.0f, -4.0f);
- D3DXVECTOR3 lookVec(0.0f, 0.0f, 0.0f);
- D3DXVECTOR3 upVec (0.0f, 1.0f, 0.0f);
- D3DXMatrixLookAtLH(&matView, &eyeVec, &lookVec, &upVec);
- g_pD3DDev->SetTransform(D3DTS_VIEW, &matView);
- D3DXMATRIXA16 matProj;
- D3DXMatrixIdentity(&matProj);
- D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f );
- g_pD3DDev->SetTransform(D3DTS_PROJECTION, &matProj);
- return S_OK;
- }
- /*==========================================
- Function name: SetUpLightAndMatrial
- Description: 设置
- ==========================================*/
- HRESULT SetUpLightAndMatrial()
- {
- D3DMATERIAL9 d3dMat;
- ZeroMemory(&d3dMat, sizeof(D3DMATERIAL9));
- d3dMat.Ambient.a = d3dMat.Diffuse.a =1.0f;
- d3dMat.Ambient.r = d3dMat.Diffuse.r =0.0f;
- d3dMat.Ambient.g = d3dMat.Diffuse.g =1.0f;
- d3dMat.Ambient.b = d3dMat.Diffuse.b =1.0f;
- g_pD3DDev->SetMaterial(&d3dMat);
- D3DLIGHT9 d3dlight;
- ZeroMemory(&d3dlight, sizeof(D3DLIGHT9));
- d3dlight.Type = D3DLIGHT_DIRECTIONAL;//平行光
- d3dlight.Direction = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
- d3dlight.Diffuse.r = 1.0f;
- d3dlight.Diffuse.g = 1.0f;
- d3dlight.Diffuse.b = 0.0f;
- d3dlight.Range = 1000.0f;
- g_pD3DDev->SetLight(0, &d3dlight);
- g_pD3DDev->LightEnable(0, true);
- return S_OK;
- }
- /*==========================================
- Function name: Cleanup
- Description: 释放对象
- ==========================================*/
- VOID Cleanup()
- {
- if (g_pVerBuf != NULL)
- {
- g_pVerBuf->Release();
- }
- if (g_pD3DDev != NULL)
- {
- g_pD3DDev->Release();
- }
- if (g_pD3DObj != NULL)
- {
- g_pD3DObj->Release();
- }
- }
- /*==========================================
- Function name: Render
- Description: 负责渲染
- ==========================================*/
- VOID Render()
- {
- if (g_pD3DDev == NULL)
- {
- return ;
- }
- g_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 255),1.0f, 0);
- if (SUCCEEDED(g_pD3DDev->BeginScene()))
- {
- SetUpLightAndMatrial();//注意没使用
- ChangeWorld();
- g_pD3DDev->SetStreamSource(0, g_pVerBuf, 0, sizeof(CUSTOMVERTEX));
- g_pD3DDev->SetFVF(D3DFVF_CUSTOMVERTEX);
- g_pD3DDev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
- g_pD3DDev->EndScene();
- }
- g_pD3DDev->Present(NULL, NULL, NULL, NULL);
- }
- /*==========================================
- Function name: MsgProc
- Description: 负责消息循环
- ==========================================*/
- 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);
- }
- /*==========================================
- Function name: WinMain
- Description: 程序启动函数
- ==========================================*/
- INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
- {
- WNDCLASSEX wc = {
- sizeof(WNDCLASSEX),
- CS_CLASSDC,
- MsgProc,
- 0L,
- 0L,
- GetModuleHandle(NULL),
- NULL,
- NULL,
- NULL,
- NULL,
- g_AppName,
- NULL
- };
- RegisterClassEx(&wc);
- HWND hWnd = CreateWindow(
- g_AppName,
- TEXT("D3D Tutorial 1"),
- WS_OVERLAPPEDWINDOW,
- 100,
- 100,
- 300,
- 300,
- NULL,
- NULL,
- wc.hInstance,
- NULL
- );
- if (hWnd == NULL)
- {
- return -1;
- }
- if(SUCCEEDED(InitD3D(hWnd)))
- {
- if(SUCCEEDED(InitVBuf()))
- {
- ShowWindow(hWnd, SW_SHOWDEFAULT);
- UpdateWindow(hWnd);
- MSG msg;
- ZeroMemory(&msg, sizeof(msg));
- while (msg.message != WM_QUIT)
- {
- if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- else
- {
- Render();
- }
- }
- }
- }
- UnregisterClass(g_AppName, wc.hInstance);
- return 0;
- }