www.pudn.com > Win32DirectX9.rar > Win32DirectX9.cpp
// Win32DirectX9.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "Win32DirectX9.h"
#define MAX_LOADSTRING 100
// 全局变量:
HINSTANCE hInst; // 当前实例
TCHAR szTitle[MAX_LOADSTRING]; // 标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING]; // 主窗口类名
// g_全局变量
HINSTANCE g_hInst;
HWND g_hWnd;
IDirect3D9 *g_pD3D;
IDirect3DDevice9 *g_pd3dDevice;
IDirect3DVertexBuffer9 *g_pVB;
struct CUSTOMVERTEX
{
D3DVECTOR pos;
D3DVECTOR normal;
};
//TCHAR szTitle[MAX_LOADSTRING];
//TCHAR szWindowClass[MAX_LOADSTRING];
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
void OnIdle( void );
void OnCreate( HWND hWnd );
HRESULT InitD3D( void );
HRESULT CreateObject( void );
void ReleaseD3D( void );
HRESULT SetModalMatrix( void );
HRESULT SetProjMatrix( WORD wWidth, WORD wHeight );
void BeforePaint( void );
// 此代码模块中包含的函数的前向声明:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
void CalcNormal( const D3DVECTOR *pVertices, D3DVECTOR *pNormal )
{
D3DVECTOR v1, v2;
v1.x = pVertices[0].x - pVertices[1].x;
v1.y = pVertices[0].y - pVertices[1].y;
v1.z = pVertices[0].z - pVertices[1].z;
v2.x = pVertices[1].x - pVertices[2].x;
v2.y = pVertices[1].y - pVertices[2].y;
v2.z = pVertices[1].z - pVertices[2].z;
D3DXVECTOR3 Temp( v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z,v1.x * v2.y - v1.y * v2.x );
D3DXVec3Normalize( (D3DXVECTOR3*)pNormal, &Temp );
}
class CTimer
{
private:
LARGE_INTEGER m_Frequency;
LARGE_INTEGER m_StartCount;
public:
CTimer()
{
QueryPerformanceFrequency(&m_Frequency);
Start();
}
void Start()
{
QueryPerformanceCounter(&m_StartCount);
}
double End()
{
LARGE_INTEGER CurrentCount;QueryPerformanceCounter(&CurrentCount);
return double(CurrentCount.LowPart - m_StartCount.LowPart)/(double)m_Frequency.LowPart;
}
};
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// TODO: 在此放置代码。
MSG msg;
HACCEL hAccelTable;
// 初始化全局字符串
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_WIN32DIRECTX9, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// 执行应用程序初始化:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WIN32DIRECTX9);
// 主消息循环:(原始)
//while (GetMessage(&msg, NULL, 0, 0))
//{
// if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
// {
// TranslateMessage(&msg);
// DispatchMessage(&msg);
// }
//}
// 主消息循环:(修改后)
while(true)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if(!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
continue;
}
if(WM_QUIT == msg.message)
{
break;
}
OnIdle();
}
UnregisterClass(szWindowClass, g_hInst);
return (int) msg.wParam;
}
//
// 函数: MyRegisterClass()
//
// 目的: 注册窗口类。
//
// 注释:
//
// 仅当希望在已添加到 Windows 95 的
// “RegisterClassEx”函数之前此代码与 Win32 系统兼容时,
// 才需要此函数及其用法。调用此函数
// 十分重要,这样应用程序就可以获得关联的
// “格式正确的”小图标。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_WIN32DIRECTX9);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCTSTR)IDC_WIN32DIRECTX9;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// 函数: InitInstance(HANDLE, int)
//
// 目的: 保存实例句柄并创建主窗口
//
// 注释:
//
// 在此函数中,我们在全局变量中保存实例句柄并
// 创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // 将实例句柄存储在全局变量中
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
//
// 函数: WndProc(HWND, unsigned, WORD, LONG)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_CREATE: // 建立时 执行
//MessageBox(NULL, "Hello , Gavin", "WM_CREATE", MB_OK);
OnCreate(hWnd);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 分析菜单选择:
switch (wmId)
{
case ID_D3D_BEGIN:
break;
case ID_D3D_END:
break;
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
ReleaseD3D();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// “关于”框的消息处理程序。
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
void OnCreate( HWND hWnd )
{
g_hWnd = hWnd;
InitD3D();
CreateObject();
}
void ReleaseD3D( void )
{
if(g_pVB != NULL) g_pVB->Release();
if(g_pd3dDevice != NULL) g_pd3dDevice->Release();
if(g_pD3D != NULL) g_pD3D->Release();
}
HRESULT InitD3D( void )
{
g_pD3D = Direct3DCreate9( D3D_SDK_VERSION );
if(g_pD3D == NULL) return E_FAIL;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_PUREDEVICE,
&d3dpp, &g_pd3dDevice);
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_COLORVALUE( 0.3f, 0.3f, 0.3f, 1.0 ));
g_pd3dDevice->LightEnable(0, TRUE);
D3DMATERIAL9 mtrl;
ZeroMemory( &mtrl, sizeof(mtrl));
mtrl.Diffuse.r = mtrl.Ambient.r = 140.0f/255.0f ;
mtrl.Diffuse.g = mtrl.Ambient.g = 200.0f/255.0f ;
mtrl.Diffuse.b = mtrl.Ambient.b = 255.0f/255.0f ;
mtrl.Diffuse.a = mtrl.Ambient.a = 1.0f;
g_pd3dDevice->SetMaterial(&mtrl);
return S_OK;
}
void BeforePaint( void )
{
D3DLIGHT9 light;
ZeroMemory(&light, sizeof(light));
light.Position = D3DXVECTOR3(30.0f, 30.0f, 30.0f);
light.Attenuation1 = 0.05f;
light.Diffuse.r = 1.0f;
light.Diffuse.g = 1.0f;
light.Diffuse.b = 1.0f;
light.Range = 1000.0f;
light.Type = D3DLIGHT_POINT;
g_pd3dDevice->SetLight(0, &light);
g_pd3dDevice->LightEnable(0, TRUE);
}
HRESULT CreateObject( void )
{
D3DVECTOR SrcBox[] = {
{ 5.0f, 5.0f, 0.0f },{ 5.0f, 5.0f, 10.0f },
{ 5.0f,-5.0f, 0.0f },{ 5.0f,-5.0f, 10.0f },
{-5.0f,-5.0f, 0.0f },{-5.0f,-5.0f, 10.0f },
{-5.0f, 5.0f, 0.0f },{-5.0f, 5.0f, 10.0f }
};
WORD wIndex[] = {
0, 4, 6, 0, 2, 4,
0, 6, 7, 0, 7, 1,
0, 3, 2, 0, 1, 3,
5, 2, 3, 5, 4, 2,
5, 6, 4, 5, 7, 6,
5, 1, 7, 5, 3, 1
};
CUSTOMVERTEX ExpandBox[sizeof(wIndex)/sizeof(WORD)];
for(int i = 0; i < 36; i++) ExpandBox[i].pos = SrcBox[ wIndex[i] ];
for(i = 0; i < 12; i++)
{
D3DVECTOR Tri[3];
Tri[0] = ExpandBox[i * 3 + 0].pos ;
Tri[1] = ExpandBox[i * 3 + 1].pos ;
Tri[2] = ExpandBox[i * 3 + 2].pos ;
ExpandBox[i * 3 + 0].normal.x = 0.0f ;
ExpandBox[i * 3 + 0].normal.y = 0.0f ;
ExpandBox[i * 3 + 0].normal.z = 1.0f ;
CalcNormal(Tri, &(ExpandBox[i * 3 + 0].normal ));
ExpandBox[i * 3 + 1].normal = ExpandBox[i * 3 + 0].normal ;
ExpandBox[i * 3 + 2].normal = ExpandBox[i * 3 + 0].normal ;
}
g_pd3dDevice->CreateVertexBuffer(sizeof(ExpandBox), 0, /*D3DFVF_CUSTOMVERTEX*/ 0, D3DPOOL_DEFAULT, &g_pVB, NULL);
VOID* pVertices;
g_pVB->Lock( 0, sizeof(ExpandBox), (void**)&pVertices, 0) ;
MoveMemory(pVertices, ExpandBox, sizeof(ExpandBox)) ;
g_pVB->Unlock() ;
return S_OK;
}
void OnIdle( void )
{
static CTimer t;
static double dt = t.End();
double temp = t.End();
double szValue[256];
double ZhenLv = 1 / (temp - dt); // 当前帧率
//sprintf(szValue,"%f", ZhenLv);
//sprintf(szValue , "当前帧率 : %f ", ZhenLv);
SetWindowText(g_hWnd, "当前帧率:");
dt = temp;
if(g_pd3dDevice != NULL)
{
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 200), 1.0f, 0);
if(SUCCEEDED(g_pd3dDevice->BeginScene()))
{
BeforePaint();
if(FAILED(SetModalMatrix())) return;
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX));
g_pd3dDevice->SetFVF(/*D3DFVF_CUSTOMVERTEX*/0);
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 12);
g_pd3dDevice->EndScene();
g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}
}
}
HRESULT SetModalMatrix( void )
{
static float fRadius = 0.5f;
fRadius -= 0.003f;
if(fRadius < 0) fRadius = D3DX_PI * 2;
D3DXMATRIX matWorld;
D3DXMatrixRotationZ( &matWorld, 0.0f);
if(FAILED(g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld))) return E_FAIL;
D3DXMATRIX matView;
D3DXMatrixLookAtLH( &matView, &D3DXVECTOR3(cosf(fRadius) * 40.0f,
sinf(fRadius) * 40.0f, 30.0), &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &D3DXVECTOR3(0.0f, 0.0f, 1.0f));
g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
return S_OK;
}
HRESULT SetProjMatrix( WORD wWidth, WORD wHeight )
{
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, (float)wWidth/(float)wHeight, 1.0f,100.0f);
return g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}