Direct3D learning (1)

學習DirectX9中Direct3D的用法。

一。初始化

1. 創建Direct3D的藉口指針。
IDirect3D9* g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);

2. 獲得顯示模式後,創建device。
D3DDISPLAYMODE d3ddm;
g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
D3DPRESENT_PARAMETERS d3dpp;  // Direct3D的參數
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;    // 設置爲window模式
d3dpp.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;  //設置切換效果
d3dpp.BackBufferFormat = d3ddm.Format;  // 根據取得的顯示模式,設置格式
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;  // 定義Device指針
g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice)

二。 描畫

1. 清空畫面。
g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);  //清空整個畫面,背景顏色爲黑色

HRESULT Clear(      

    DWORD Count, // pRects指向的RECT數目     const D3DRECT *pRects, // 指向RECT列表,表示要清除的各個矩形。     DWORD Flags, // 定義清除方法。     D3DCOLOR Color, // 清除後的顏色     float Z, // 清除後的Z座標[0,1]     DWORD Stencil // 清除後的模板值。 ); // 返回D3D_OK表示成功,else 失敗
2. 開始描畫
g_pD3DDevice->BeginScene(); // 開始
// 中間的描畫





g_pD3DDevice->EndScene(); // 結束
g_pD3DDevice->Present(NULL, NULL, NULL, NULL); //顯示下一個緩存的畫面
HRESULT Present(      

    CONST RECT *pSourceRect, // 指明源矩形     CONST RECT *pDestRect, // 指明目的矩形     HWND hDestWindowOverride, // 指明目的窗口     CONST RGNDATA *pDirtyRegion // 指明需要刷新的區域 );
三。結束
if (g_pD3DDevice!=NULL) { g_pD3DDevice->Release(); g_pD3DDevice = NULL; }
if (g_pD3D!= NULL) { g_pD3D->Release();  g_pD3D = NULL; }
下面是一個簡單的畫一個三角形的程序,我區分了directx8和9的代碼,用宏_GY_D3D8。代碼主要是從一本書上copy來的。
#include "stdafx.h"

#ifdef _GY_D3D8
#include < d3d8.h >
#else
#include < d3d9.h >
#endif

#ifdef _GY_D3D8
LPDIRECT3D8 g_pD3D = NULL;
LPDIRECT3DDEVICE8 g_pD3DDevice = NULL;
LPDIRECT3DVERTEXBUFFER8 g_pVertexBuffer = NULL;
#else
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVertexBuffer = NULL;
#endif

struct CUSTOMVERTEX
{
	FLOAT x, y, z, rhw;
	DWORD color;
};

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)

#define SafeRelease(pObject) /
	if (pObject != NULL) {/
		pObject->Release(); /
		pObject = NULL; /
	}

HRESULT InitializeD3D(HWND hWnd)
{
#ifdef _GY_D3D8
	g_pD3D = Direct3DCreate8(D3D_SDK_VERSION);
#else
	g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
#endif
	if (g_pD3D == NULL) {
		return E_FAIL;
	}
	D3DDISPLAYMODE d3ddm;
	if (FAILED( g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) {
		return E_FAIL;
	}
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.Windowed = TRUE;
#ifdef _GY_D3D8
	d3dpp.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC;
#else
	d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
#endif
	d3dpp.BackBufferFormat = d3ddm.Format;
	if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
				D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pD3DDevice))) {
		return E_FAIL;
	}
	return S_OK;
}

HRESULT InitialiseVertexBuffer()
{
	VOID* pVertex;
	CUSTOMVERTEX cvVertex[] = {
		{250.0f, 100.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(255,0,0) },
		{400.0f, 350.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0,255,0) },
		{100.0f, 350.0f, 0.5f, 1.0f, D3DCOLOR_XRGB(0,0,255) }
	};
#ifdef _GY_D3D8
	if (FAILED(g_pD3DDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX,
		D3DPOOL_DEFAULT, &g_pVertexBuffer))) {
		return E_FAIL;
	}
	if (FAILED(g_pVertexBuffer->Lock(0, sizeof(cvVertex), (BYTE**)&pVertex, 0))) {
		return E_FAIL;
	}
#else
	if (FAILED(g_pD3DDevice->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX,
		D3DPOOL_DEFAULT, &g_pVertexBuffer, NULL))) {
		return E_FAIL;
	}
	if (FAILED(g_pVertexBuffer->Lock(0, sizeof(cvVertex), (void**)&pVertex, 0))) {
		return E_FAIL;
	}
#endif
	
	memcpy(pVertex, cvVertex, sizeof(cvVertex));
	g_pVertexBuffer->Unlock();
	return S_OK;
}

void Render()
{
	if (g_pD3DDevice == NULL) {
		return;
	}
	// background color
	g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
	g_pD3DDevice->BeginScene();
#ifdef _GY_D3D8
	g_pD3DDevice->SetStreamSource(0, g_pVertexBuffer, sizeof(CUSTOMVERTEX));
	g_pD3DDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX);
#else
	g_pD3DDevice->SetStreamSource(0, g_pVertexBuffer, 0, sizeof(CUSTOMVERTEX));
	g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
#endif
	
	g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

	g_pD3DDevice->EndScene();
	g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}

void CleanUp()
{
	SafeRelease(g_pVertexBuffer);
	SafeRelease(g_pD3DDevice);
	SafeRelease(g_pD3D);
}

void GameLoop()
{
	MSG msg;
	BOOL fMessage;
	PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
	while(msg.message != WM_QUIT) {
		fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
		if (fMessage) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}else {
			Render();
		}
	}
}

LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch(msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
		break;
	case WM_KEYUP:
		switch(wParam) {
		case VK_ESCAPE:
			DestroyWindow(hWnd);
			return 0;
			break;
		}
		break;
	default:
		break;
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}

INT WINAPI WinMain(HINSTANCE hInst, HINSTANCE , LPSTR , int )
{
	WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_CLASSDC, WinProc, 0L, 0L, 
		GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
		"DX Project 1", NULL};
	RegisterClassEx(&wc);
	HWND hWnd = CreateWindow("DX Project 1", "www.andypike.com: Tutorial 1", 
		WS_OVERLAPPEDWINDOW, 50, 50, 500, 500,
		GetDesktopWindow(), NULL, wc.hInstance, NULL);

	if(SUCCEEDED(InitializeD3D(hWnd)))
	{
		//Show our window
		ShowWindow(hWnd, SW_SHOWDEFAULT);
		UpdateWindow(hWnd);
		
		//Start game running: Enter the game loop
		if (SUCCEEDED(InitialiseVertexBuffer())) {
			GameLoop();
		}
	}
	
	CleanUp();
	
    UnregisterClass("DX Project 1", wc.hInstance);
    
    return 0;
}
發佈了19 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章