一个旋转的三角形,主要练习坐标变换。
#pragma once
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#include <d3d9.h>
#include <d3dx9.h>
#include <strsafe.h>
#pragma warning(disable:4996)
//global variables.
LPDIRECT3D9 g_pD3D=NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice9=NULL;
LPDIRECT3DVERTEXBUFFER9 g_pD3DVB=NULL;
//custom vertex struct.
struct CUSTOMVERTEX
{
FLOAT x,y,z;
DWORD color;
};
//define custom vertex format.
#define D3DFVF_CUSTOMVETEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
//init D3D variables
HRESULT InitD3D(HWND hWnd)
{
//init D3D
g_pD3D=Direct3DCreate9(D3D_SDK_VERSION);
if(FAILED(g_pD3D))
{
return E_FAIL;
}
//init D3D present parameter.
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed=TRUE;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;
//create d3d device.
if(FAILED(g_pD3D->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&g_pD3DDevice9)))
{
return E_FAIL;
}
//turn off culling.
g_pD3DDevice9->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE);
//turn off light.
g_pD3DDevice9->SetRenderState(D3DRS_LIGHTING,FALSE);
return S_OK;
}
//init geometry
HRESULT InitGeometry()
{
//initialize three custom vertex.
CUSTOMVERTEX g_vertices[3]=
{
{-1.0f,-1.0f, 0.0f, D3DCOLOR_XRGB(0,255,0)},
{0.0f, 1.0f, 0.0f, D3DCOLOR_XRGB(255,0,0)},
{1.0f,-1.0f, 0.0f, D3DCOLOR_XRGB(0,0,255)}
};
//create vertex buffer.
if(FAILED(g_pD3DDevice9->CreateVertexBuffer(
sizeof(g_vertices),
0,
D3DFVF_CUSTOMVETEX,
D3DPOOL_DEFAULT,
&g_pD3DVB,
NULL)))
{
return E_FAIL;
}
//fill vertex buffer.
void* pVertices=NULL;
if(FAILED(g_pD3DVB->Lock(0,sizeof(g_vertices),&pVertices,0)))
{
return E_FAIL;
}
memcpy(pVertices,g_vertices,sizeof(g_vertices));
g_pD3DVB->Unlock();
return S_OK;
}
//clean up d3d variables.
void CleanUp()
{
if(g_pD3DVB!=NULL)
{
g_pD3DVB->Release();
}
if(g_pD3DDevice9!=NULL)
{
g_pD3DDevice9->Release();
}
if(g_pD3D!=NULL)
{
g_pD3D->Release();
}
}
//setup matrix
void SetupMatrix()
{
//world matrix.
D3DXMATRIXA16 matWorld;
//rotation matrix.
UINT itimes=timeGetTime()%1000;
FLOAT fAngle=itimes * ( 2.0f * D3DX_PI ) / 1000.0f;
D3DXMatrixRotationY(&matWorld,fAngle);
//set world matrix.
g_pD3DDevice9->SetTransform(D3DTS_WORLD,&matWorld);
//set view point.
D3DXVECTOR3 vEyePt(0.0f,3.0f,-5.0f);
D3DXVECTOR3 vLookAt(0.0f,0.0f,0.0f);
D3DXVECTOR3 vUp(0.0f,1.0f,0.0f);
//view matrix.
D3DXMATRIXA16 matView;
//set view matrix.
D3DXMatrixLookAtLH(&matView,&vEyePt,&vLookAt,&vUp);
g_pD3DDevice9->SetTransform(D3DTS_VIEW,&matView);
//set projection matrix.
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,1.0f,100.0f);
g_pD3DDevice9->SetTransform(D3DTS_PROJECTION,&matProj);
}
//render the scene.
void Render()
{
//clear target device.
g_pD3DDevice9->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
//draw primitive.
if(SUCCEEDED(g_pD3DDevice9->BeginScene()))
{
SetupMatrix();
g_pD3DDevice9->SetStreamSource(0,g_pD3DVB,0,sizeof(CUSTOMVERTEX));
g_pD3DDevice9->SetFVF(D3DFVF_CUSTOMVETEX);
g_pD3DDevice9->DrawPrimitive(D3DPT_TRIANGLELIST,0,1);
g_pD3DDevice9->EndScene();
}
//present back buffer to display.
g_pD3DDevice9->Present(NULL,NULL,NULL,NULL);
}
//message loop handler.
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);
}
//the application entry point.
INT WINAPI wWinMain(HINSTANCE,HINSTANCE,LPWSTR,INT)
{
//windclass structure.
WNDCLASSEX wcex;
wcex.cbClsExtra=0;
wcex.cbSize=sizeof(WNDCLASSEX);
wcex.cbWndExtra=0;
wcex.hbrBackground=NULL;
wcex.hCursor=NULL;
wcex.hIcon=NULL;
wcex.hIconSm=NULL;
wcex.hInstance=GetModuleHandle(NULL);
wcex.lpfnWndProc=MsgProc;
wcex.lpszClassName=L"D3D Toturial";
wcex.lpszMenuName=NULL;
wcex.style=CS_CLASSDC;
//register window class.
RegisterClassEx(&wcex);
//create window.
HWND hWnd=CreateWindow(
L"D3D Toturial",
L"D3D Toturial 003",
WS_OVERLAPPEDWINDOW,
100,
100,
300,
300,
NULL,
NULL,
wcex.hInstance,
NULL);
//init d3d.
if(SUCCEEDED(InitD3D(hWnd)))
{
if(SUCCEEDED(InitGeometry()))
{
//show window.
ShowWindow(hWnd,SW_SHOWDEFAULT);
UpdateWindow(hWnd);
// Enter the message loop
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();
}
}
}
//unregister window class.
UnregisterClass( L"D3D Tutorial", wcex.hInstance );
return 0;
}
运行结果
1.声明顶点数据
2.初始化顶点数据
3.设置坐标变化
4.渲染显示