Direct3D learning (4)

Direct3D learning (4)

学习D3d的教程,里面第6章以后就不提供代码了,自己按照他说的,进行了一些封装。还是比较肤浅的。目前至少能运行了。

使用异常处理,纯虚类接口,继承,模板template等C++方法。

GameObjectAction是接口类,主要定义了一些基本的虚函数接口。

GameObject是基本类,包含了Direct3DDevice的指针,一个世界矩阵用于表示物体的移动和翻转,angleX表示相对于x轴的角度,x表示中心相对于x的偏移,其他类似。继承了GameObjectAction。

class GameApp是运行游戏的一个类。它里面定义了一个vector的GameObject,表示画面中所有物体的集合。

class D3dCube是一个立方体类,(事实上也可以处理长方体),支持基本的移动旋转等操作。

目前的实现很是简单。但这毕竟是一个开始。以后一点点修改。

下载地址http://blog.blogchina.com/upload/2005-04-08/20050408152549160215.rar, 解压后,记得修改工程的directX9的路径。

下面是源代码:

 

/*  用于异常处理。 暂时简单处理了一下。
 * filename: gy_exception.h
 */

#ifndef _GY_EXCEPTION_H
#define _GY_EXCEPTION_H

namespace gy {

	const int ER_CODE = 2000;

	class Exception
	{
	public:
		Exception(int code = 0) : errno(code) { }
		~Exception() { }

		int errno;
	};

}

#endif

/*
 * filename: GameObject.h
 */
#ifndef _GY_GAMEOBJECT_H
#define _GY_GAMEOBJECT_H

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

namespace gy {

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

	inline void Matrix_Initialize(D3DXMATRIX& mat)
	{
		mat = D3DXMATRIX(
			1.0f, 0.0f, 0.0f, 0.0f,
			0.0f, 1.0f, 0.0f, 0.0f,
			0.0f, 0.0f, 1.0f, 0.0f,
			0.0f, 0.0f, 0.0f, 1.0f);
	}

	class GameObjectAction
	{
	public:
		virtual void Render() = 0;
		virtual void MoveTo(float _x, float _y, float _z) = 0;
		virtual void RotateTo(float _anglex, float _angley, float _anglez) = 0;
		virtual void Translate(float _x, float _y, float _z) = 0;
		virtual void Rotate(float _anglex, float _angley, float _anglez) = 0;
	};

	class GameObject : public GameObjectAction
	{
	public:
		GameObject(LPDIRECT3DDEVICE9 p) {
			pD9 = p;
			//position = D3DXVECTOR3(0, 0, 0);
			Matrix_Initialize(worldmatrix);
			x = y = z = anglex = angley = anglez = 0;
		}
		virtual ~GameObject() {}

		// data
	protected:
		LPDIRECT3DDEVICE9 pD9;
		//D3DXVECTOR3 position;
		D3DXMATRIX worldmatrix;
		float anglex, angley, anglez;
		float x, y, z;
	};

}

#endif

/*
 * filename: D3dCube.h
 */


#ifndef _GY_D3DCUBE_H
#define _GY_D3DCUBE_H

#include "GameObject.h"
#include "gy_exception.h"

namespace gy {

	template < class CustomVertex >
	class D3dCube : public GameObject
	{
	public:
		D3dCube(LPDIRECT3DDEVICE9 pD3dDevice9, CustomVertex *array, size_t count, DWORD fvfflag);
		~D3dCube();
		void Render();
		void MoveTo(float _x, float _y, float _z);
		void Translate(float _x, float _y, float _z);
		void Rotate(float _anglex, float _angley, float _anglez);
		void RotateTo(float _anglex, float _angley, float _anglez);

	private:
		void DoTranslate();
		void DoRotate();
		
		LPDIRECT3DVERTEXBUFFER9 vertex;
		DWORD fvf;
		
	};

	template < class CustomVertex >
		D3dCube< CustomVertex >::D3dCube(LPDIRECT3DDEVICE9 p, CustomVertex* array, 
		size_t count, DWORD fvfflag) : GameObject(p)
	{
		void *pVertex;
		size_t length;

		vertex = NULL;

		length = sizeof(CustomVertex) * count;
		if (FAILED(pD9->CreateVertexBuffer(length, 0, fvfflag,D3DPOOL_DEFAULT, &vertex, NULL))) {
			throw(Exception(ER_CODE));
			return;
		}
		if (FAILED(vertex->Lock(0, length, (void**)&pVertex, 0))) {
			throw(Exception(ER_CODE));
			return;
		}
		memcpy(pVertex, array, length);
		vertex->Unlock();
		fvf = fvfflag;
	}

	template < class CustomVertex >
		D3dCube< CustomVertex >::~D3dCube()
	{
		SafeRelease(vertex);
	}

	template < class CustomVertex >
		void D3dCube< CustomVertex > :: DoRotate()
	{
		D3DXMATRIX mat, matX, matY, matZ;
		D3DXMatrixRotationX(&matX, anglex);
		D3DXMatrixRotationX(&matY, angley);
		D3DXMatrixRotationX(&matZ, anglez);
		D3DXMatrixMultiply(&mat, &matX, &matY);
		D3DXMatrixMultiply(&mat, &mat, &matZ);

		D3DXMatrixMultiply(&worldmatrix, &worldmatrix, &mat);
	}

	template < class CustomVertex >
		void D3dCube< CustomVertex >::DoTranslate()
	{
		D3DXMATRIX mat;
		D3DXMatrixTranslation(&mat, x, y, z);

		D3DXMatrixMultiply(&worldmatrix, &worldmatrix, &mat);
	}

	template < class CustomVertex >
		void D3dCube< CustomVertex >::Render()
	{
		DoTranslate();
		DoRotate();
		pD9->SetTransform(D3DTS_WORLD, &worldmatrix);
		pD9->SetStreamSource(0, vertex, 0, sizeof(CustomVertex));
		pD9->SetFVF(fvf);
		pD9->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2);
		pD9->DrawPrimitive(D3DPT_TRIANGLESTRIP, 4, 8);
		pD9->DrawPrimitive(D3DPT_TRIANGLESTRIP, 14, 2);

		Matrix_Initialize(worldmatrix);
	}

	template < class CustomVertex >
		void D3dCube< CustomVertex >::MoveTo(float _x, float _y, float _z)
	{
		x = _x;
		y = _y;
		z = _z;
	}

	template < class CustomVertex >
		void D3dCube< CustomVertex >::Translate(float _x, float _y, float _z)
	{
		x += _x;
		y += _y;
		z += _z;
	}

	template < class CustomVertex >
		void D3dCube< CustomVertex >::Rotate(float _anglex, float _angley, float _anglez)
	{
		anglex += _anglex;
		angley += _angley;
		anglez += _anglez;
	}

	template < class CustomVertex >
		void D3dCube< CustomVertex >::RotateTo(float _anglex, float _angley, float _anglez)
	{
		anglex = _anglex;
		angley = _angley;
		anglez = _anglez;
	}

}

#endif

/*
 * filename: GameApp.h
 */

#ifndef _GY_GAMEAPP_H
#define _GY_GAMEAPP_H

#include "GameObject.h"
#include "gy_exception.h"
#include < vector >

using namespace std;

namespace gy {

class GameApp
{
public:
	GameApp(HWND hWnd);
	~GameApp();
	void Loop();
	void AddObject(GameObject* pObject) {
		objects.push_back(pObject);
	}

	LPDIRECT3DDEVICE9 GetDevice() { return pD9; }
	LPDIRECT3D9 GetD3D() { return pD3D; }

private:
	void Render();
	void SetupCamera();
	void SetupPerspective();
	void Init(HWND hWnd);
	void End();

	// data
public:
	LPDIRECT3D9 pD3D;
	LPDIRECT3DDEVICE9 pD9;
	vector< GameObject* > objects;

};

}

#endif

/*
 * filename: GameApp.cpp
 */

#include "stdafx.h"

#include "GameApp.h"
#include < Mmsystem.h >

namespace gy {

	GameApp::GameApp(HWND hWnd)
	{
		Init(hWnd);
	}

	GameApp::~GameApp()
	{
		End();
	}

	void GameApp::Init(HWND hWnd)
	{
		pD3D = Direct3DCreate9(D3D_SDK_VERSION);
		if (pD3D == NULL) {
			throw(Exception(ER_CODE));
			return;  // use throw in future
		}
		D3DDISPLAYMODE d3ddm;
		if (FAILED( pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))) {
			throw(Exception(ER_CODE));
			return;
		}
		D3DPRESENT_PARAMETERS d3dpp;
		ZeroMemory(&d3dpp, sizeof(d3dpp));
		d3dpp.Windowed = TRUE;

		d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
		d3dpp.BackBufferFormat = d3ddm.Format;
		if (FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
			D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pD9))) {
			throw(Exception(ER_CODE));
			return;
		}
		// remove in future
		// set cullmode use anti-circle-way
		pD9->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
		pD9->SetRenderState(D3DRS_LIGHTING, FALSE);
		return;
	}

	void GameApp::End()
	{
		for (size_t i = 0; i < objects.size(); ++i) {
			if (objects[i] != NULL) {
				delete objects[i];
				objects[i] = NULL;
			}
		}
		SafeRelease(pD9);
		SafeRelease(pD3D);
	}

	void GameApp::SetupCamera()
	{
		//Here we will setup the camera.
		//The camera has three settings: "Camera Position", "Look at Position" and
		//"Up Direction"
		//We have set the following:
		//Camera Position: (0, 0, -30)
		//Look at Position: (0, 0, 0)
		//Up direction: Y-Axis.
		D3DXMATRIX matView;
		D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0.0f, 0.0f,-100.0f), //Camera Position
			&D3DXVECTOR3(0.0f, 0.0f, 0.0f), //Look At Position
			&D3DXVECTOR3(0.0f, 1.0f, 0.0f)); //Up Direction
		pD9->SetTransform(D3DTS_VIEW, &matView);
	}

	void GameApp::SetupPerspective()
	{
		//Here we specify the field of view, aspect ration and near and
		//far clipping planes.
		D3DXMATRIX matProj;
		D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 500.0f);
		pD9->SetTransform(D3DTS_PROJECTION, &matProj);
	}

	void GameApp::Render()
	{
		if (pD9 == NULL) {
			return;
		}
		pD9->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
		pD9->BeginScene();

		SetupCamera();
		SetupPerspective();

		for (size_t i = 0; i < objects.size(); ++i) {
			if (objects[i] != NULL) {
				objects[i]->RotateTo(timeGetTime()/400.0f, 0.0f, 0.0f);
				objects[i]->Render();
			}
		}

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

	void GameApp::Loop()
	{
		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();
			}
			//Sleep(33);  // 30fps = 1000/33 fps
		}
	}
}

/*
 * filename: d3d.cpp
 */

#include "stdafx.h"

#include "GameApp.h"
#include "D3dCube.h"

using namespace gy;

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

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)

CUSTOMVERTEX cvVertex[] = {
	//Top Face
	{-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 0 - Blue 
	{-5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 1 - Red 
	{5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 2 - Red 
	{5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 3 - Green 

	//Face 1
	{-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 4 - Red 
	{-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 5 - Blue 
	{5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 6 - Green 
	{5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 7 - Red 

	//Face 2
	{5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 8 - Blue 
	{5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 9 - Green

	//Face 3
	{-5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 10 - Green 
	{-5.0f, 5.0f, 5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 11 - Red 

	//Face 4
	{-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 12 - Red 
	{-5.0f, 5.0f, -5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 13 - Blue

	//Bottom Face
	{5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 14 - Green 
	{5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0, 0, 255),}, //Vertex 15 - Blue 
	{-5.0f, -5.0f, -5.0f, D3DCOLOR_XRGB(255, 0, 0),}, //Vertex 16 - Red 
	{-5.0f, -5.0f, 5.0f, D3DCOLOR_XRGB(0, 255, 0),}, //Vertex 17 - Green

};

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);

	try {
		GameApp theGameApp(hWnd);

		ShowWindow(hWnd, SW_SHOWDEFAULT);
		UpdateWindow(hWnd);

		D3dCube< CUSTOMVERTEX > *cube = new D3dCube< CUSTOMVERTEX >(theGameApp.GetDevice(), cvVertex, 
			sizeof(cvVertex)/sizeof(CUSTOMVERTEX), D3DFVF_CUSTOMVERTEX);

		theGameApp.AddObject(cube);

		cube = new D3dCube< CUSTOMVERTEX >(theGameApp.GetDevice(), cvVertex, 
			sizeof(cvVertex)/sizeof(CUSTOMVERTEX), D3DFVF_CUSTOMVERTEX);
		cube->MoveTo(20.0f, 0.0f, 0.0f);

		theGameApp.AddObject(cube);


		theGameApp.Loop();
	}catch(Exception e) {
		cout << "Catch Error: " << e.errno << endl;
	}

    UnregisterClass("DX Project 1", wc.hInstance);
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值