close

第一個DirectX專案,可以描繪出一個白色正方形的程式。只有兩個檔案的專案main.cpp & main.h,附有詳細註解。

 

1. main.cpp

 

#include "main.h"

//視窗程式的主要入口
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
//設定視窗
WNDCLASSEX wndclass = {sizeof(wndclass), //視窗類別執行
CS_HREDRAW|CS_VREDRAW, //處理水平與垂直重繪
WndProc, //視窗行程 
0, 0, hInstance, //處理實體 
LoadIcon(NULL, IDI_APPLICATION), 
LoadCursor(NULL,IDC_ARROW), //游標的形狀設定成箭頭
(HBRUSH)(COLOR_WINDOW+1), //hbrBackground
NULL, //hMenu
_T("window"),
LoadIcon(NULL, IDI_APPLICATION)}; //處理圖示

RegisterClassEx(&wndclass); //登入視窗類別

//產生視窗
HWND hWnd = CreateWindowEx(
0, //dwExStyle
_T("window"), _T("window"), //視窗標題
WS_OVERLAPPEDWINDOW, //重疊視窗
CW_USEDEFAULT, CW_USEDEFAULT,
640, 480,
NULL, NULL, hInstance, NULL);

ShowWindow(hWnd, nCmdShow); //顯示視窗
UpdateWindow(hWnd);

//DirectX 初始化
DirectXCreate(hWnd);

MSG msg;
while(TRUE)
{
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
if(msg.message==WM_QUIT) break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
//DirectX 繪圖
DirectXRender();
}
}

//DirectX 資源釋放
DirectXDestroy();
return (int)msg.wParam;
}

//訊息迴圈
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) //結果叫回行程(視窗處理、無符號整數、W參數、L參數)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam); //傳回定義視窗行程
}

//DirectX 初始化
void DirectXCreate(HWND hWnd)
{
//初始化directX
D3DDISPLAYMODE d3ddm;

if((g_pD3D = ::Direct3DCreate9(D3D_SDK_VERSION)) == 0) //初始化directXGraphics,即取得本身指向Direct3D9物件的指標
return;
if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) //
return;

//裝置表現參數(presentation parameter)的初始化
ZeroMemory(&g_D3DPP, sizeof(D3DPRESENT_PARAMETERS)); //D3D表現參數的所有成員的值都清除為零
g_D3DPP.BackBufferCount = 1; 
g_D3DPP.Windowed = TRUE; //視窗模式 
g_D3DPP.BackBufferFormat = d3ddm.Format; //先將圖像描繪在背景緩衝區 
g_D3DPP.SwapEffect = D3DSWAPEFFECT_DISCARD; //指定DirectXGraphics所產生的圖像送到顯示器畫面,設定值是:自動最佳傳送方式
g_D3DPP.EnableAutoDepthStencil = TRUE; //錯誤對策:啟用自動深度模板 
g_D3DPP.AutoDepthStencilFormat = D3DFMT_D16; //錯誤對策:自動深度模板的色彩模式

//產生物件裝置
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, //使用硬體(GPU)來進行描繪和頂點處理
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&g_D3DPP, &g_pD3DDevice))) {
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, //若上述的設定失敗,則使用硬體(GPU)來描繪,在CPU進行頂點處理(將資料從顯卡記憶體載入到主記憶體讓CPU代替GPU的工作)
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&g_D3DPP, &g_pD3DDevice))) {
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd, //若上述的設定失敗,則繪圖和頂點處理都在CPU進行
D3DCREATE_SOFTWARE_VERTEXPROCESSING, //使用軟體來進行頂點處理
&g_D3DPP, &g_pD3DDevice))) {
return;
}}}

//初始化頂點資料
if(FAILED(g_pD3DDevice->CreateVertexBuffer(4*sizeof(MY_VERTEX),D3DUSAGE_WRITEONLY,
MY_VERTEX_FVF,D3DPOOL_MANAGED,
&g_pVB, NULL ))) return;

//將頂點緩衝器的內容填滿
MY_VERTEX* v;
g_pVB->Lock( 0, 0, (void**)&v, 0 );
//各頂點的位置
v[0].p = D3DXVECTOR3(-1.5f, 1.5f, 0.0f );
v[1].p = D3DXVECTOR3( 1.5f, 1.5f, 0.0f );
v[2].p = D3DXVECTOR3(-1.5f, -1.5f, 0.0f );
v[3].p = D3DXVECTOR3( 1.5f, -1.5f, 0.0f );
//各頂點的顏色
v[0].color = v[1].color = v[2].color = v[3].color =
D3DXCOLOR( 1.0f, 1.0f, 1.0f, 1.0f);
g_pVB->Unlock();
//繪圖狀態參數的設定
g_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE);
g_pD3DDevice->SetRenderState( D3DRS_ZENABLE, TRUE);
g_pD3DDevice->SetRenderState( D3DRS_DITHERENABLE,TRUE);
g_pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE);

//設定場景view矩陣初始化
D3DXMatrixIdentity( &g_view);
D3DXMatrixLookAtLH( &g_view, &D3DXVECTOR3(0.0f, 0.0f, -10.0f),
&D3DXVECTOR3(0.0f, 0.0f, 0.0f),
&D3DXVECTOR3(0.0f, 1.0f, 0.0f));
g_pD3DDevice->SetTransform(D3DTS_VIEW, &g_view);
//視埠的初始化
D3DVIEWPORT9 vp;
if(FAILED(g_pD3DDevice->GetViewport(&vp))) return;
float aspect;
aspect = (float)vp.Width / (float)vp.Height;

//陣列初始化
D3DXMatrixIdentity(&g_proj);
D3DXMatrixPerspectiveFovLH(&g_proj, D3DXToRadian(45.0f), aspect, 5.0f, 1000.0f);

g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &g_proj); //設定攝影機參數
D3DXMatrixIdentity(&g_world);
g_pD3DDevice->SetTransform(D3DTS_WORLD, &g_world); 
}

//初始化DirectX 繪圖
void DirectXRender()
{
g_pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(0,0,0),1.0f,0); //把整個畫面清掉,包括view board視圖板、depth buffer深度緩衝區、stencil buffer模板緩衝區等
g_pD3DDevice->BeginScene(); //開始描繪新場景

//正方形的描繪
g_pD3DDevice->SetStreamSource( 0, g_pVB, 0, sizeof(MY_VERTEX) ); //設定頂點緩衝區
g_pD3DDevice->SetFVF( MY_VERTEX_FVF ); //頂點緩衝器的格式設定
g_pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 ); //描繪頂點緩衝器

g_pD3DDevice->EndScene(); //結束描繪
g_pD3DDevice->Present(0,0,0,0); //從背景畫面送到前景畫面
}

//DirectX 資源釋放
void DirectXDestroy()
{
SAFE_RELEASE(g_pVB); //釋放頂點緩衝器
SAFE_RELEASE(g_pD3DDevice); //釋放裝置物件
SAFE_RELEASE(g_pD3D); //釋放DirectXGraphics
}

 

2. main.h

 

#ifndef __MAIN_H
#define __MAIN_H

//windows 相關標頭檔
#include <stdio.h>
#include <windows.h>
#include <tchar.h>

//directX 相關標頭檔與程式庫
#include <d3d9.h>
#include <d3dx9.h>
#pragma comment(lib,"dsound.lib")
#pragma comment(lib,"dinput8.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dxof.lib")
#pragma comment(lib,"dxguid.lib")

// 釋放記憶體
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }

//可以在視窗後面顯示一個 console 方便除錯
#pragma comment(linker, "/subsystem:console /entry:WinMainCRTStartup")

//處理系統訊息的視窗行程(處理目前視窗、無正負符號整數、訊息參數、訊息參數)
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

//directX 頂點與向量圖形
class MY_VERTEX
{
public:
D3DXVECTOR3 p;
DWORD color;
};

//Flexible Vertex Format
const DWORD MY_VERTEX_FVF=(D3DFVF_XYZ | D3DFVF_DIFFUSE);

LPDIRECT3D9 g_pD3D; 
LPDIRECT3DDEVICE9 g_pD3DDevice; 
D3DPRESENT_PARAMETERS g_D3DPP;

D3DXMATRIX g_proj;
D3DXMATRIX g_view;
D3DXMATRIX g_world;

LPDIRECT3DVERTEXBUFFER9 g_pVB;
LPDIRECT3DTEXTURE9 g_pTexture;

void DirectXCreate(HWND hWnd);
void DirectXRender();
void DirectXDestroy();

#endif

 

 

Hello World.png

 

arrow
arrow
    全站熱搜

    丹尼爾 發表在 痞客邦 留言(0) 人氣()