#include "d3d9.h"
#include "d3dx9.h"
#include "windowsx.h"
#include "tchar.h"
HWND g_hwnd;
LPDIRECT3D9 g_d3d9=NULL;
LPDIRECT3DDEVICE9 g_d3d9device=NULL;
LPDIRECT3DVERTEXBUFFER9 g_d3d9vb=NULL;
LPDIRECT3DINDEXBUFFER9 g_d3d9ib=NULL;
ID3DXFont* Font = 0;
struct CustomVertex
{
float x,y,z;
float nx,ny,nz;
};
#define CustomFVF (D3DFVF_XYZ|D3DFVF_NORMAL)
LRESULT initVertex()
{
CustomVertex cv[]=
{
{ -1.0f, 0.0f, -1.0f, 0.0f, 0.707f, -0.707f},
{ 0.0f, 1.0f, 0.0f, 0.0f, 0.707f, -0.707f},
{ 1.0f, 0.0f, -1.0f, 0.0f, 0.707f, -0.707f},
{ -1.0f, 0.0f, 1.0f, -0.707f, 0.707f, 0.0f},
{ 0.0f, 1.0f, 0.0f, -0.707f, 0.707f, 0.0f},
{ -1.0f, 0.0f, -1.0f, -0.707f, 0.707f, 0.0f},
{ 1.0f, 0.0f, -1.0f, 0.707f, 0.707f, 0.0f},
{ 0.0f, 1.0f, 0.0f, 0.707f, 0.707f, 0.0f},
{ 1.0f, 0.0f, 1.0f, 0.707f, 0.707f, 0.0f},
{ 1.0f, 0.0f, 1.0f, 0.0f, 0.707f, 0.707f},
{ 0.0f, 1.0f, 0.0f, 0.0f, 0.707f, 0.707f},
{ -1.0f, 0.0f, 1.0f, 0.0f, 0.707f, 0.707f},
};
if FAILED(g_d3d9device->CreateVertexBuffer(sizeof(cv),NULL,CustomFVF,D3DPOOL_MANAGED,&g_d3d9vb,NULL))
return E_FAIL;
void *p;
g_d3d9vb->Lock(0,sizeof(cv),&p,0);
memcpy(p,cv,sizeof(cv));
g_d3d9vb->Unlock();
//定义材质
D3DMATERIAL9 ml;
ZeroMemory(&ml,sizeof(ml));
ml.Ambient=D3DXCOLOR(0.0f,0.0f,0.0f,0.0f);
ml.Diffuse=D3DXCOLOR(1.0f,1.f,0.f,0.f);
g_d3d9device->SetMaterial(&ml);
return S_OK;
}
LRESULT initLight()
{
D3DLIGHT9 l1;
ZeroMemory(&l1,sizeof(l1));
l1.Type=D3DLIGHT_DIRECTIONAL;
l1.Direction=D3DXVECTOR3(1.f,0.f,0.f);
l1.Ambient=D3DXCOLOR(1.f,1.f,1.f,0.f);
l1.Diffuse=D3DXCOLOR(2.f,0.f,0.f,0.f);
g_d3d9device->SetLight(0,&l1);
g_d3d9device->LightEnable(0,true);
D3DLIGHT9 l2;
ZeroMemory(&l2,sizeof(l2));
l2.Type=D3DLIGHT_POINT;
l2.Position=D3DXVECTOR3(2.f,1.f,-1.f);
l2.Ambient=D3DXCOLOR(1.f,1.f,1.f,0.f);
l2.Diffuse=D3DXCOLOR(1.f,0.f,0.f,0.f);
l2.Range=2.f;
g_d3d9device->SetLight(1,&l2);
g_d3d9device->LightEnable(1,true);
D3DLIGHT9 l3;
ZeroMemory(&l3,sizeof(l3));
l3.Type=D3DLIGHT_SPOT;
l3.Position=D3DXVECTOR3(0.f,0.7f,-6.f);
D3DXVec3Normalize((D3DXVECTOR3*)&l3.Direction,&D3DXVECTOR3(0.f,0.f,1.f));
l3.Falloff=1.f;
l3.Attenuation0=1.f;
l3.Ambient=l3.Diffuse=D3DXCOLOR(0.f,1.f,0.f,0.f);
l3.Theta=0.2f;
l3.Phi=0.4f;
l3.Range=500.f;
g_d3d9device->SetLight(2,&l3);
g_d3d9device->LightEnable(2,true);
return S_OK;
}
LRESULT initText()
{
D3DXFONT_DESC d3dFont;
memset(&d3dFont,0,sizeof(d3dFont));
d3dFont.Height=14;
d3dFont.Width=8;
d3dFont.Weight=400;
d3dFont.Italic=FALSE;
d3dFont.CharSet=DEFAULT_CHARSET;
wcscpy_s(d3dFont.FaceName,_T("宋体"));
if(FAILED(D3DXCreateFontIndirect(g_d3d9device, &d3dFont, &Font)))
{
::MessageBox(0, _T("D3DXCreateFontIndirect() - FAILED"), 0, 0);
::PostQuitMessage(0);
}
return S_OK;
}
LRESULT initgame()
{
D3DCAPS9 dcaps;
D3DPRESENT_PARAMETERS para;
ZeroMemory(¶,sizeof(para));
int devtype;
ZeroMemory(&dcaps,sizeof(dcaps));
g_d3d9=Direct3DCreate9(D3D_SDK_VERSION);
g_d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,&dcaps);
if (dcaps.DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT)
devtype=D3DCREATE_HARDWARE_VERTEXPROCESSING;
else
devtype=D3DCREATE_SOFTWARE_VERTEXPROCESSING;
para.AutoDepthStencilFormat=D3DFMT_D16;
para.EnableAutoDepthStencil=true;
para.BackBufferFormat=D3DFMT_A8R8G8B8;
para.hDeviceWindow=g_hwnd;
para.SwapEffect=D3DSWAPEFFECT_DISCARD;
para.Windowed=true;
if FAILED(g_d3d9->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,g_hwnd,devtype,¶,&g_d3d9device))
return E_FAIL;
g_d3d9device->SetRenderState(D3DRS_ZENABLE,true);
g_d3d9device->SetRenderState(D3DRS_LIGHTING,true);
g_d3d9device->SetRenderState(D3DRS_NORMALIZENORMALS,true);
g_d3d9device->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE,D3DMCS_MATERIAL);
// g_d3d9device->SetRenderState(D3DRS_AMBIENT,D3DCOLOR_COLORVALUE(0.7,0.7,0.7,0));
initVertex();
initLight();
initText();
return S_OK;
}
LRESULT setmatrix()
{
static float i=0.f;
D3DXMATRIX world;
D3DXMATRIX view;
D3DXMATRIX proj;
D3DXMatrixRotationY(&world,i++*D3DX_PI/180);
g_d3d9device->SetTransform(D3DTS_WORLD,&world);
D3DXVECTOR3 eye(0.0f,2.0f,-4.0f);
D3DXVECTOR3 lookat(0.0f,0.0f,0.0f);
D3DXVECTOR3 up(0.0f,1.0f,0.0f);
D3DXMatrixLookAtLH(&view,&eye,&lookat,&up);
g_d3d9device->SetTransform(D3DTS_VIEW,&view);
D3DXMatrixPerspectiveFovLH(&proj,D3DX_PI/4,1.0f,1.0f,100.f);
g_d3d9device->SetTransform(D3DTS_PROJECTION,&proj);
return S_OK;
}
LRESULT render()
{
setmatrix();
g_d3d9device->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_COLORVALUE(0.0,0,0,0),1.0f,0);
g_d3d9device->BeginScene();
g_d3d9device->SetStreamSource(0,g_d3d9vb,0,sizeof(CustomVertex));
g_d3d9device->SetFVF(CustomFVF);
g_d3d9device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 4);
RECT rect = {4, 4, 300, 50};
Font->DrawTextW(
NULL,
_T("数字1:关闭/打开平行光 \n\r数字2:关闭/打开点光 \n\r上下左右键:移动聚光灯"),
-1,
&rect,
DT_TOP | DT_LEFT,
0xffffffff);
g_d3d9device->EndScene();
g_d3d9device->Present(NULL,NULL,NULL,NULL);
return S_OK;
}
LRESULT CALLBACK wndproc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
D3DLIGHT9 l;
BOOL t;
ZeroMemory(&l,sizeof(l));
g_d3d9device->GetLight(2,&l);
switch (wparam)
{
case 49: //数字1 打开或关闭平行光
{
g_d3d9device->GetLightEnable(0,&t);
g_d3d9device->LightEnable(0,!t);
}
break;
case 50: //数字2 打开或关闭点灯
{
g_d3d9device->GetLightEnable(1,&t);
g_d3d9device->LightEnable(1,!t);
}
break;
case 37: //左 移动聚光灯
{
l.Direction.x-=0.03f;
}
break;
case 38: //上
{
l.Direction.y+=0.03f;
}
break;
case 39: //右
{
l.Direction.x+=0.03f;
}
break;
case 40: //下
{
l.Direction.y-=0.03f;
}
break;
}
D3DXVec3Normalize((D3DXVECTOR3*)&l.Direction,(D3DXVECTOR3*)&l.Direction);
g_d3d9device->SetLight(2,&l);
g_d3d9device->LightEnable(2,true);
break;
default :
break;
}
return DefWindowProc(hwnd,message,wparam,lparam);
}
int WINAPI WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd )
{
WNDCLASSEX wndclassex;
ZeroMemory(&wndclassex,sizeof(wndclassex));
wndclassex.cbSize=sizeof(wndclassex);
wndclassex.hCursor=LoadCursor(hInstance,IDC_ARROW);
wndclassex.hInstance=hInstance;
wndclassex.lpszClassName=_T("game");
wndclassex.style=CS_HREDRAW|CS_VREDRAW;
wndclassex.lpfnWndProc=wndproc;
RegisterClassEx(&wndclassex);
g_hwnd=CreateWindow(_T("game"),_T("direct"),WS_OVERLAPPEDWINDOW,100,100,400,600,NULL,NULL,hInstance,NULL);
ShowWindow(g_hwnd,SW_SHOW);
UpdateWindow(g_hwnd);
initgame();
MSG msg;
ZeroMemory(&msg,sizeof(msg));
while(msg.message!=WM_QUIT)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
render();
}
}