DX9 空间坐标变换示例代码
// @time 2012.3.25
// @author jadeshu
#include <Windows.h>
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"winmm.lib")
wchar_t *g_pClassName=L"Transform";
wchar_t *g_pWindowName=L"空间坐标变换示例";
//定义设备接口
IDirect3DDevice9 * g_pd3dDevice=NULL;
IDirect3DVertexBuffer9 * g_pVertexBuf=NULL;
IDirect3DIndexBuffer9 * g_pIndexBuf=NULL;
struct CUSTOMVERTEX
{
FLOAT _x,_y,_z;
DWORD _color;
CUSTOMVERTEX(FLOAT x,FLOAT y,FLOAT z,DWORD color)
:_x(x),_y(y),_z(z),_color(color){}
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
//回调函数声明
LRESULT CALLBACK WinProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
);
//初始化Direct3D函数声明
HRESULT Init3D(HWND hwnd);
//渲染声明
VOID Render();
//清除对象声明
VOID Cleanup();
//主函数
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
//定义窗口类结构
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
ZeroMemory(&msg,sizeof(msg));
wc.cbClsExtra=0;
wc.cbSize=sizeof(WNDCLASSEX);
wc.cbWndExtra=0;
wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wc.hCursor=LoadCursor(hInstance,IDC_ARROW);
wc.hIcon=LoadIcon(hInstance,IDI_APPLICATION);
wc.hIconSm=NULL;
wc.hInstance=hInstance;
wc.lpfnWndProc=WinProc;
wc.lpszClassName=g_pClassName;
wc.lpszMenuName=NULL;
wc.style=CS_HREDRAW|CS_VREDRAW;
//注册窗口
RegisterClassEx(&wc);
//创建窗口
hwnd=CreateWindow(g_pClassName,g_pWindowName,WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,0);
//加载3D初始化
if (FAILED(Init3D(hwnd)))
{
return FALSE;
}
//显示和更新窗口
ShowWindow(hwnd,nCmdShow);
UpdateWindow(hwnd);
//消息循环
while (WM_QUIT!=msg.message)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
//转换消息
TranslateMessage(&msg);
//投递消息
DispatchMessage(&msg);
}
else
{
//渲染
Render();
}
}
//删除注册窗口
UnregisterClass(g_pClassName,hInstance);
return msg.wParam;
}
//回调函数
LRESULT CALLBACK WinProc(HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch (uMsg)
{
case WM_PAINT:
Render(); //渲染
ValidateRect(hwnd,NULL); //更新窗口
return 0;
case WM_DESTROY:
Cleanup(); //清除对象
PostQuitMessage(0); //退出消息循环
return 0;
}
return DefWindowProc(hwnd,uMsg,wParam,lParam); //返回默认消息
}
//Direct3D初始化
HRESULT Init3D(HWND hwnd)
{
IDirect3D9 *pD3D=NULL; //定义对象接口
pD3D=Direct3DCreate9(D3D_SDK_VERSION); //创建对象接口
if (NULL==pD3D)
{
return E_FAIL;
}
D3DCAPS9 caps; //获取硬件设备信息
int vp=0;
pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&caps);
if (caps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT)
{
vp=D3DCREATE_HARDWARE_VERTEXPROCESSING;
}
else
{
vp=D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}
//创建Direct3D设备接口
D3DPRESENT_PARAMETERS d3dpp;
//d3dpp.AutoDepthStencilFormat=D3DFMT_D24S8;
d3dpp.BackBufferCount=1;
d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;
d3dpp.BackBufferHeight=640;
d3dpp.BackBufferWidth=480;
d3dpp.EnableAutoDepthStencil=FALSE;
d3dpp.Flags=0;
d3dpp.FullScreen_RefreshRateInHz=D3DPRESENT_RATE_DEFAULT;
d3dpp.hDeviceWindow=hwnd;
d3dpp.MultiSampleQuality=0;
d3dpp.MultiSampleType=D3DMULTISAMPLE_NONE;
d3dpp.PresentationInterval=D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.Windowed=TRUE;
//ZeroMemory( &d3dpp, sizeof(d3dpp) );
//d3dpp.Windowed = TRUE;
//d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
//d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,D3DCREATE_HARDWARE_VERTEXPROCESSING/*D3DCREATE_SOFTWARE_VERTEXPROCESSING*/,&d3dpp,&g_pd3dDevice)))
{
return E_FAIL;
}
//创建顶点缓冲区
g_pd3dDevice->CreateVertexBuffer(8*sizeof(CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&g_pVertexBuf,NULL);
//填充顶点缓冲区
CUSTOMVERTEX *pVertices=NULL;
g_pVertexBuf->Lock(0,0,(void **)&pVertices,0);
pVertices[0]=CUSTOMVERTEX(-5.0f,5.0f,-5.0f,D3DCOLOR_XRGB(255,0,0));
pVertices[1]=CUSTOMVERTEX(-5.0f,5.0f,5.0f,D3DCOLOR_XRGB(0,255,0));
pVertices[2]=CUSTOMVERTEX(5.0f,5.0f,5.0f,D3DCOLOR_XRGB(0,0,255));
pVertices[3]=CUSTOMVERTEX(5.0f,5.0f,-5.0f,D3DCOLOR_XRGB(255,255,0));
pVertices[4]=CUSTOMVERTEX(-5.0f,-5.0f,-5.0f,D3DCOLOR_XRGB(0,0,255));
pVertices[5]=CUSTOMVERTEX(-5.0f,-5.0f,5.0f,D3DCOLOR_XRGB(255,255,0));
pVertices[6]=CUSTOMVERTEX(5.0f,-5.0f,5.0f,D3DCOLOR_XRGB(255,0,0));
pVertices[7]=CUSTOMVERTEX(5.0f,-5.0f,-5.0f,D3DCOLOR_XRGB(0,255,0));
g_pVertexBuf->Unlock();
//创建索引缓冲区
g_pd3dDevice->CreateIndexBuffer(36*sizeof(WORD),0,D3DFMT_INDEX16,D3DPOOL_DEFAULT,&g_pIndexBuf,0);
//填充索引缓冲区
WORD *pIndices=NULL;
g_pIndexBuf->Lock(0,0,(void **)&pIndices,0);
pIndices[0]=0,pIndices[1]=1,pIndices[2]=2;
pIndices[3]=0,pIndices[4]=2,pIndices[5]=3;
pIndices[6]=0,pIndices[7]=3,pIndices[8]=7;
pIndices[9]=0,pIndices[10]=7,pIndices[11]=4;
pIndices[12]=0,pIndices[13]=4,pIndices[14]=5;
pIndices[15]=0,pIndices[16]=5,pIndices[17]=1;
pIndices[18]=2,pIndices[19]=6,pIndices[20]=7;
pIndices[21]=2,pIndices[22]=7,pIndices[23]=3;
pIndices[24]=2,pIndices[25]=5,pIndices[26]=6;
pIndices[27]=2,pIndices[28]=1,pIndices[29]=5;
pIndices[30]=4,pIndices[31]=6,pIndices[32]=5;
pIndices[33]=4,pIndices[34]=7,pIndices[35]=6;
g_pIndexBuf->Unlock();
return S_OK;
}
//渲染图形
VOID Render()
{
g_pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(150,120,255),1.0f,0); //清除后台缓冲区
g_pd3dDevice->BeginScene(); //开始绘制
//世界变换矩阵
D3DXMATRIX matWorld,Rx,Ry,Rz;
D3DXMatrixIdentity(&matWorld);
D3DXMatrixRotationX(&Rx,/*::timeGetTime()/1000*/1.0f);
D3DXMatrixRotationY(&Ry,/*::timeGetTime()/1000*//*1.0f*/::timeGetTime()/1000.0f);
D3DXMatrixRotationZ(&Rz,/*::timeGetTime()/1000.0f*//*::timeGetTime()/1000*/1.0f);
matWorld=Rx*Ry*Rz*matWorld;
g_pd3dDevice->SetTransform(D3DTS_WORLD,&matWorld);
//取景变换矩阵
D3DXMATRIX matView;
D3DXVECTOR3 vEye(0.0f,0.0f,-30.0f);
D3DXVECTOR3 vAt(0.0f,0.0f,0.0f);
D3DXVECTOR3 vUp(0.0f,1.0f,0.0f);
D3DXMatrixLookAtLH(&matView,&vEye,&vAt,&vUp);
g_pd3dDevice->SetTransform(D3DTS_VIEW,&matView);
//投影变换矩阵
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4.0f,1.0f,1.0f,1000.0f);
g_pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);
//设置渲染
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING,FALSE);
g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
//渲染三角形
g_pd3dDevice->SetStreamSource(0,g_pVertexBuf,0,sizeof(CUSTOMVERTEX));
g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
g_pd3dDevice->SetRenderState(D3DRS_AMBIENT,D3DCOLOR_XRGB(222,222,222));
g_pd3dDevice->SetIndices(g_pIndexBuf);
g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,0,12);
g_pd3dDevice->EndScene(); //结束绘制
g_pd3dDevice->Present(NULL,NULL,NULL,NULL); //从后台缓冲区复制到前台----翻转
}
//清除对象,内存
VOID Cleanup()
{
if (g_pIndexBuf!=NULL)
{
g_pIndexBuf->Release();
g_pIndexBuf=NULL;
}
if (g_pVertexBuf!=NULL)
{
g_pVertexBuf->Release();
g_pVertexBuf=NULL;
}
if (g_pd3dDevice!=NULL)
{
g_pd3dDevice->Release();
g_pd3dDevice=NULL;
}
}