#include "stdafx.h"
#include "d3d9.h"
#include "d3dx9.h"
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#define WINDOW_CLASS "UGPDX" //視窗類名稱
#define WINDOW_NAME "Template" //視窗類標題
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
bool InitializeD3D(HWND hWnd,bool fullscreen);//用於在程式中設定和建立Direct3D
bool InitializeObjects(); //用於建立顯示程式中要繪製在螢幕上的物體
void RenderScene();//用於在螢幕上渲染已經繪製好的圖形
void Shutdown(); //用於在程式退出時進行一些銷燬工作
//direct3D object and device
LPDIRECT3D9 g_D3D=NULL;
LPDIRECT3DDEVICE9 g_D3DDevice=NULL;
//Matrices
D3DXMATRIX g_projection;
D3DXMATRIX g_ViewMatrix;
D3DXMATRIX g_WorldMatrix;
//vertex buffer to hold the geometry
LPDIRECT3DVERTEXBUFFER9 g_VertexBuffer=NULL;//定義了一個頂點快取物件
//A structure for our custom vertex type
//定義場景中單個3D點的結構
struct stD3Dvertex
{
float x,y,z,rhw;//點的x,y,z座標值
unsigned long color;//點的顏色
};
//our custom FVF,which describes our custom vertex structure
//定義頂點格式標示符,即靈活頂點格式
#define D3DFVF_VERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)
//視窗過程函式(系統自動呼叫,即回撥函式)
LRESULT WINAPI MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;
case WM_KEYUP:
if(wParam==VK_ESCAPE)
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd,msg,wParam,lParam);
}
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE prevhInst,LPSTR cmdLine,int
show)
{
//Register the window class
WNDCLASSEX wc={sizeof(WNDCLASSEX),CS_CLASSDC,MsgProc,0L,0L,
GetModuleHandle(NULL),NULL,NULL,NULL,NULL,
WINDOW_CLASS,NULL};
RegisterClassEx(&wc);
//create the application's window
HWND hWnd=CreateWindow(WINDOW_CLASS,WINDOW_NAME,WS_OVERLAPPEDWINDOW,
100,100,640,480,GetDesktopWindow(),NULL,
wc.hInstance,NULL);
//initialize Direct3D
if (InitializeD3D(hWnd,false))
{
ShowWindow(hWnd,SW_SHOWDEFAULT);
UpdateWindow(hWnd);
//enter the message loop
MSG msg;
ZeroMemory(&msg,sizeof(msg));//巨集用0來填充一塊記憶體區域
while(msg.message!=WM_QUIT)
{
if (PeekMessage(&msg,NULL,0U,0U,PM_REMOVE))//從訊息佇列中獲取下一條訊息
{
TranslateMessage(&msg);//對相關訊息進行一些轉換
DispatchMessage(&msg);//將轉換後的訊息傳送給訊息過程函式
}
else
//處理向螢幕繪製影象的程式碼部分
RenderScene();
}
}
//release any and all resources
Shutdown();
UnregisterClass("AppClass",wc.hInstance);//取消對視窗類的註冊
return 0;
}
//設定寫入要繪製的場景資料
bool InitializeObjects()
{
unsigned long col=D3DCOLOR_XRGB(255,255,255);//紅,綠,藍
//Fill in our structure to draw an object
//x,y,z,rhw,color
//objData結構體陣列:設定所有點的資料
stD3Dvertex objData[]=
{
{420.0f,150.0f,0.5f,1.0f,col,},//第一個點的座標及顏色
{420.0f,350.0f,0.5f,1.0f,col,},//第二個點的座標及顏色
{220.0f,150.0f,0.5f,1.0f,col,},//第三個點的座標及顏色
{220.0f,350.0f,0.5f,1.0f,col,},//第四個點的座標及顏色
};
//create the vertex buffer
//建立頂點快取
if (FAILED(g_D3DDevice->CreateVertexBuffer(sizeof(objData),0,
D3DFVF_VERTEX,D3DPOOL_DEFAULT,&g_VertexBuffer,
NULL)))
return false;
//fill the vertex buffer
void *ptr;
//鎖定頂點快取,以進行讀寫操作
if(FAILED(g_VertexBuffer->Lock(0,sizeof(objData),
(void**)&ptr,0)))
return false;
//將資料複製到該快取中
memcpy(ptr,objData,sizeof(objData));
//對頂點快取進行解鎖
g_VertexBuffer->Unlock();
return true;
}
//繪製場景
void RenderScene()
{
//clear the back buffer
g_D3DDevice->Clear(0,NULL,D3DCLEAR_TARGET,
D3DCOLOR_XRGB(0,0,0),1.0f,0);
//begin the scene start rendering
g_D3DDevice->BeginScene();
//render object
//設定頂點資料流的輸入源
g_D3DDevice->SetStreamSource(0,g_VertexBuffer,0,
sizeof(stD3Dvertex));
g_D3DDevice->SetFVF(D3DFVF_VERTEX);//設定頂點格式
g_D3DDevice->DrawPrimitive(D3DPT_LINELIST,0,2);//進行繪製
//end the scene.stop rendering
g_D3DDevice->EndScene();
//display the scene
//向顯示器顯示繪製的結果
g_D3DDevice->Present(NULL,NULL,NULL,NULL);
}
void Shutdown()
{
if(g_D3DDevice!=NULL) g_D3DDevice->Release();
if(g_D3D!=NULL) g_D3D->Release();
if(g_VertexBuffer!=NULL) g_VertexBuffer->Release();
g_D3DDevice=NULL;
g_D3D=NULL;
g_VertexBuffer=NULL;
}
bool InitializeD3D(HWND hWnd,bool fullscreen)
{
D3DDISPLAYMODE displayMode;
//create the D3D object
g_D3D=Direct3DCreate9(D3D_SDK_VERSION);
if(g_D3D==NULL) return false;
//get the desktop display mode
if(FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,
&displayMode)))
return false;
//set up the structure used to create the d3ddevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
if (fullscreen)
{
d3dpp.Windowed=FALSE;
d3dpp.BackBufferWidth=640;
d3dpp.BackBufferHeight=480;
}
else
d3dpp.Windowed=TRUE;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat=displayMode.Format;
//create the D3Device
if(FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp,&g_D3DDevice)))
return false;
//initialize any objects we will be displaying
if(!InitializeObjects()) return false;
return true;
}