代码改变世界

第一个Directx程序

2011-07-14 07:57  李龙江  阅读(407)  评论(0编辑  收藏  举报
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"winmm.lib")

#include "windows.h"
#include <d3d9.h>
#include <d3dx9math.h>

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW|D3DFVF_DIFFUSE)

//顶点结构
struct CUSTOMVERTEX
{
	FLOAT x,y,z,rhw;
	DWORD colour;
};

//全局变量
HWND hWnd;
HINSTANCE hInst;
IDirect3D9* g_pD3D;
IDirect3DDevice9* g_pD3DDevice;
IDirect3DVertexBuffer9* g_pVertexBuffer;

//窗口函数
ATOM     MyRegisterClass(HINSTANCE hInstance);
BOOL     InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);


//D3D函数
HRESULT InitialiseD3D(HWND hWnd);       //初始化D3D
HRESULT InitialiseVertexBuffer();       //初始化顶点缓存
void Render();                          //渲染
void CleanUp();                         //程序结束,清理内存


int APIENTRY WinMain(HINSTANCE hInstance,
				 HINSTANCE hPrevInstance,
				 LPSTR     lpCmdLine,
				 int       nCmdShow)
{
	// TODO: Place code here.
	MSG msg;

	MyRegisterClass(hInstance);

	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	while (GetMessage(&msg, NULL, 0, 0))
	{ 
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return msg.wParam;
}


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    = NULL;
	wcex.hCursor   = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = L"3D";
	wcex.hIconSm   = NULL;

	return RegisterClassEx(&wcex);
}


BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	HWND hWnd;

	hInst = hInstance; // Store instance handle in our global variable

	hWnd = CreateWindow(L"3D", L"3D窗口", WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

	if (!hWnd)
	{
		return FALSE;
	}

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	PAINTSTRUCT ps;
	HDC hdc;
	switch (message)
	{
	case WM_CREATE:          //初始化
		InitialiseD3D(hWnd);
		InitialiseVertexBuffer();
	case WM_PAINT:          //渲染
		hdc = BeginPaint(hWnd, &ps);
		Render();
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		CleanUp();          //清理资源
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}


HRESULT InitialiseD3D(HWND hWnd)
{
	g_pD3D=Direct3DCreate9(D3D_SDK_VERSION);
	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;
	d3dpp.SwapEffect=D3DSWAPEFFECT_COPY;
	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* pVertices;
	CUSTOMVERTEX cvVertices[] =
	{
		{300.0f,50.0f,0.5f,1.0f,D3DCOLOR_XRGB(255,0,0)},
		{500.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)},

		{500.0f,50.0f,0.5f,1.0f,D3DCOLOR_XRGB(255,0,0)},
		{700.0f,350.0f,0.5f,1.0f,D3DCOLOR_XRGB(0,255,0)},
		{300.0f,350.0f,0.5f,1.0f,D3DCOLOR_XRGB(0,0,255)}
	};
	if(FAILED(g_pD3DDevice->CreateVertexBuffer(6 * sizeof(CUSTOMVERTEX),0,
		D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&g_pVertexBuffer,NULL))){
			return E_FAIL;
	}
	if(FAILED(g_pVertexBuffer->Lock(0,sizeof(cvVertices),(VOID**)& pVertices,0))){
		return E_FAIL;
	}
	memcpy(pVertices,cvVertices,sizeof(cvVertices));
	g_pVertexBuffer->Unlock();
	return S_OK;
}

void Render()
{
	if(g_pD3DDevice==NULL){
		return;
	}

	g_pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);

	g_pD3DDevice->BeginScene();

	g_pD3DDevice->SetStreamSource(0,g_pVertexBuffer,0,sizeof(CUSTOMVERTEX));
	g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
	g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST,0,2);

	g_pD3DDevice->EndScene();

	g_pD3DDevice->Present(0,0,0,0);
}
void CleanUp()
{
	g_pVertexBuffer->Release();
	g_pD3DDevice->Release();
	g_pD3D->Release();
}