DirectX9.0例程:网格的创建与绘制

本例程演示了如何创建一个简单的立方体网格并进行绘制

主要的流程如下:

  • 创建空网格对象
  • 将立方体的面片数据写入网格缓存
  • 指定网格中每个面片所属的子集
  • 生成该网格的邻接信息
  • 优化网格
  • 绘制网格

总结红龙书中的例程代码如下:

 

d3dUtility.h

#ifndef __d3dUtilityH__  
#define __d3dUtilityH__  

#include    

namespace d3d
{
	//初始化DirectX3D
	bool InitD3D(                     
		HINSTANCE hInstance,       // [in] Application instance.  
		int width, int height,     // [in] Backbuffer dimensions.  
		bool windowed,             // [in] Windowed (true)or full screen (false).  
		D3DDEVTYPE deviceType,     // [in] HAL or REF  
		IDirect3DDevice9** device);// [out]The created device.  

    //消息循环
	int EnterMsgLoop(   
		bool(*ptr_display)(float timeDelta));

	LRESULT CALLBACK Wnd_Proc(
		HWND hwnd,
		UINT msg,
		WPARAM wParam,
		LPARAM lParam);

	template void Release(T t)
	{
		if (t)
		{
			t->Release();
			t = 0;
		}
	}

	template void Delete(T t)
	{
		if (t)
		{
			delete t;
			t = 0;
		}
	}


	const D3DXCOLOR      WHITE(D3DCOLOR_XRGB(255, 255, 255));
	const D3DXCOLOR      BLACK(D3DCOLOR_XRGB(0, 0, 0));
	const D3DXCOLOR        RED(D3DCOLOR_XRGB(255, 0, 0));
	const D3DXCOLOR      GREEN(D3DCOLOR_XRGB(0, 255, 0));
	const D3DXCOLOR       BLUE(D3DCOLOR_XRGB(0, 0, 255));
	const D3DXCOLOR     YELLOW(D3DCOLOR_XRGB(255, 255, 0));
	const D3DXCOLOR       CYAN(D3DCOLOR_XRGB(0, 255, 255));
	const D3DXCOLOR    MAGENTA(D3DCOLOR_XRGB(255, 0, 255));


	D3DMATERIAL9 InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p);

	const D3DMATERIAL9 WHITE_MTRL = InitMtrl(WHITE, WHITE, WHITE, BLACK, 2.0f);
	const D3DMATERIAL9 RED_MTRL = InitMtrl(RED, RED, RED, BLACK, 2.0f);
	const D3DMATERIAL9 GREEN_MTRL = InitMtrl(GREEN, GREEN, GREEN, BLACK, 2.0f);
	const D3DMATERIAL9 BLUE_MTRL = InitMtrl(BLUE, BLUE, BLUE, BLACK, 2.0f);
	const D3DMATERIAL9 YELLOW_MTRL = InitMtrl(YELLOW, YELLOW, YELLOW, BLACK, 2.0f);

	D3DLIGHT9 InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color);
	D3DLIGHT9 InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color);
	D3DLIGHT9 InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color);

}


#endif 

d3dUtility.cpp

#include "d3dUtility.h"
//#pragma comment(lib,"d3d9.lib")  
//#pragma comment(lib,"d3dx9.lib")  
//#pragma comment(lib,"winmm.lib")  

bool d3d::InitD3D(
	HINSTANCE hInstance,
	int width, int height,
	bool windowed,
	D3DDEVTYPE deviceType,
	IDirect3DDevice9** device)
{
	//  
	// Create the main application window.  
	//  

	WNDCLASS wc;

	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = (WNDPROC)d3d::Wnd_Proc;
	wc.cbClsExtra = 0;
	wc.cbWndExtra = 0;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon(0, IDI_APPLICATION);
	wc.hCursor = LoadCursor(0, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wc.lpszMenuName = 0;
	wc.lpszClassName = "Direct3D9App";

	if (!RegisterClass(&wc))
	{
		::MessageBox(0, "RegisterClass() - FAILED", 0, 0);
		return false;
	}
	     
	HWND hwnd = 0;
	hwnd = ::CreateWindow(
		"Direct3D9App", 
		"Direct3D9App",
		WS_EX_APPWINDOW,
		0, 0, width, height,
		0 /*parent hwnd*/, 0 /* menu */, hInstance, 0 /*extra*/);

	//HWND CreateWindow(            
	//  LPCTSTR lpWindowName,      // 窗口标题
	//  DWORD dwStyle,             // 窗口风格
	//  int x,                     // 初始 x 坐标
	//  int y,                     // 初始 y 坐标
	//  int nWidth,                // 初始 x 方向尺寸
	//  int nHeight,               // 初始 y 方向尺寸
	//  HWND hWndParent,           // 父窗口句柄
	//  HMENU hMenu,               // 窗口菜单句柄
	//  HINSTANCE hInstance,       // 程序实例句柄
	//  LPVOID lpParam             // 创建参数
	//); 

	if (!hwnd)
	{
		::MessageBox(0, "CreateWindow() - FAILED", 0, 0);
		return false;
	}

	::ShowWindow(hwnd, SW_SHOW);
	::UpdateWindow(hwnd);


	// Init D3D:    

	HRESULT hr = 0;
 
	//要初始化IDirect3D,首先必须获取指向接口IDrect3D9的指针。使得一个专门的Direct3D函数可以很容易做到  
	IDirect3D9* d3d9 = 0;
	d3d9 = Direct3DCreate9(D3D_SDK_VERSION);

	if (!d3d9)
	{
		::MessageBox(0, "Direct3DCreate9() - FAILED", 0, 0);
		return false;
	}
 
	//检验图形卡是否支持该硬件顶点运算  
	D3DCAPS9 caps;
	d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, deviceType, &caps);

	int vp = 0;
	if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
		//硬件顶点运算
		vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;  
	else
		//软件顶点运算
		vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;  
	 
	//填充D3DPRESENT_PARAMETERS结构体
	D3DPRESENT_PARAMETERS d3dpp;
	d3dpp.BackBufferWidth = width;                 //后台缓存中表面的宽度,单位为像素  
	d3dpp.BackBufferHeight = height;               //后台缓存中表面的高度,单位为像素  
	d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;      //后台缓存的像素格式(如32位像素格式:D3DFMT_A8R8G8B8)  
	d3dpp.BackBufferCount = 1;                     //所需使用的后台缓存的个数,通常是1,需要一个后台缓存  
	d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;   //多重采样类型  
	d3dpp.MultiSampleQuality = 0;                  //多重采样的质量水平  
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;      //枚举类型指定交换链中的缓存的页面设置方式。  
	d3dpp.hDeviceWindow = hwnd;                    //与设备相关的窗口句柄。指定了所有进行绘制的应用程序窗口  
	d3dpp.Windowed = windowed;                     //窗口模式,为false时表示全屏模式
	d3dpp.EnableAutoDepthStencil = true;           //为true时,自动创建并维护深度缓存或模板缓存  
	d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;   //深度缓存或模板缓存的像素格式  
	d3dpp.Flags = 0;                               //附加特性 
	d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;   //刷新频率
	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;   //一般为立即提交或由Direct3D来选择提交
 
	// 创建IDrect3Device9接口
	hr = d3d9->CreateDevice(
		D3DADAPTER_DEFAULT,  
		deviceType,           
		hwnd,                
		vp,                
		&d3dpp,              
		device);             

	//HRESULT CreateDevice(
    //    UINT Adapter,                                    // 希望代表的物理显卡
    //    D3DDEVTYPE DeviceType,                           // 设备类型
	//    HWND hFocusWindow,                               // 窗口句柄,指设备要绘制的目标窗口 
	//    DWORD BehaviorFlags,                             // 顶点运算类型
	//    D3DPRESENT_PARAMETERS *pPresentationParameters,  // 完成初始化的D3DPRESENT_PARAMETERS结构体
	//    IDirect3DDevice9 **ppReturnedDeviceInterface     // 返回所创建的设备
	//);

	if (FAILED(hr))
	{
		// 再次使用16位深度缓存尝试 
		d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

		hr = d3d9->CreateDevice(
			D3DADAPTER_DEFAULT,
			deviceType,
			hwnd,
			vp,
			&d3dpp,
			device); 

		if (FAILED(hr))
		{
			d3d9->Release();  
			::MessageBox(0, "CreateDevice() - FAILED", 0, 0);
			return false;
		}
	}

	d3d9->Release();  

	return true;
}

//消息循环  
int d3d::EnterMsgLoop(bool(*ptr_display)(float timeDelta))
{
	MSG msg;
	::ZeroMemory(&msg, sizeof(MSG));

	static float lastTime = (float)timeGetTime();

	while (msg.message != WM_QUIT)
	{
		if (::PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
		{
			::TranslateMessage(&msg);
			::DispatchMessage(&msg);
		}
		else
		{
			float currTime = (float)timeGetTime();
			//计算相邻两次调用ptr_display的时间间隔 
			float timeDelta = (currTime - lastTime)*0.001f;
			//调用指定display函数
			ptr_display(timeDelta);

			lastTime = currTime;
		}
	}
	return msg.wParam;
}


D3DMATERIAL9 d3d::InitMtrl(D3DXCOLOR a, D3DXCOLOR d, D3DXCOLOR s, D3DXCOLOR e, float p)
{
	D3DMATERIAL9 mtrl;
	mtrl.Ambient = a;
	mtrl.Diffuse = d;
	mtrl.Specular = s;
	mtrl.Emissive = e;
	mtrl.Power = p;
	return mtrl;
}

D3DLIGHT9 d3d::InitDirectionalLight(D3DXVECTOR3* direction, D3DXCOLOR* color)
{
	D3DLIGHT9 light;
	::ZeroMemory(&light, sizeof(light));

	light.Type = D3DLIGHT_DIRECTIONAL;
	light.Ambient = *color*0.4f;
	light.Diffuse = *color;
	light.Specular = *color*0.6f;
	light.Direction = *direction;

	return light;
}

D3DLIGHT9 d3d::InitPointLight(D3DXVECTOR3* position, D3DXCOLOR* color)
{
	D3DLIGHT9 light;
	::ZeroMemory(&light, sizeof(light));

	light.Type = D3DLIGHT_POINT;
	light.Ambient = *color * 0.4f;
	light.Diffuse = *color;
	light.Specular = *color * 0.6f;
	light.Position = *position;
	light.Range = 1000.0f;
	light.Falloff = 1.0f;
	light.Attenuation0 = 1.0f;
	light.Attenuation1 = 0.0f;
	light.Attenuation2 = 0.0f;

	return light;
}


D3DLIGHT9 d3d::InitSpotLight(D3DXVECTOR3* position, D3DXVECTOR3* direction, D3DXCOLOR* color)
{
	D3DLIGHT9 light;
	::ZeroMemory(&light, sizeof(light));

	light.Type = D3DLIGHT_SPOT;
	light.Ambient = *color * 0.4f;
	light.Diffuse = *color;
	light.Specular = *color * 0.6f;
	light.Position = *position;
	light.Direction = *direction;
	light.Range = 1000.0f;
	light.Falloff = 1.0f;
	light.Attenuation0 = 1.0f;
	light.Attenuation1 = 0.0f;
	light.Attenuation2 = 0.0f;
	light.Theta = 0.5f;
	light.Phi = 0.7f;

	return light;
}

WinMain.cpp

#include "d3dUtility.h"
#include 
#include 

using namespace d3d;

IDirect3DDevice9* device = 0;
int width = 640;
int height = 480;

ID3DXMesh* mesh = 0;
const DWORD NumSubsets = 3;
IDirect3DTexture9* tex[3] = {0,0,0};

std::ofstream OutFile;


void dumpVertices(std::ofstream& OutFile, ID3DXMesh* mesh);

//其他四个将网格数据输出到文件中的函数都和dumpVertices相似,
//因为代码中心不在此类函数,所以不再做实现、说明和使用
//void dumpIndices(std::ofstream& outFile, ID3DXMesh* mesh);
//void dumpAttributeBuffer(std::ofstream& outFile, ID3DXMesh* mesh);
//void dumpAdjacencyBuffer(std::ofstream& outFile, ID3DXMesh* mesh);
//void dumpAtrributeTable(std::ofstream& outFile, ID3DXMesh* mesh);

typedef struct Vertex {
	Vertex() {};
	Vertex(float x, float y, float z, float nx, float ny, float nz, float u, float v) 
		:_x(x),_y(y),_z(z),_nx(nx),_ny(ny),_nz(nz),_u(u),_v(v) 
    {}

	float _x, _y, _z;
	float _nx, _ny, _nz;
	float _u, _v;

	static const DWORD FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;
}vertex;

bool Setup() {
	//创建空网格
	HRESULT hr=0;

	hr=D3DXCreateMeshFVF(
		12,
		24,
		D3DPOOL_MANAGED,
		vertex::FVF,
		device,
		&mesh
	);

//	HRESULT WINAPI D3DXCreateMeshFVF(    //也可用D3DXCreateMesh函数创建
//		DWORD NumFaces,                  //网格具有的面片总数
//		DWORD NumVertices,               //网格具有的顶点总数
//		DWORD options,                   //创建标记
//		DWORD FVF,                       //灵活顶点格式
//		LPDIRECT3DDEVICE9 pDevices,      //设备指针
//		[out]LPD3DXMESH* ppMesh               //创建的网格对象指针
//	)

	//填充网格顶点信息
	vertex* v=0;
	mesh->LockVertexBuffer(0, (void**)&v);

	//front face
	v[0] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
	v[1] = Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
	v[2] = Vertex(1.0f, 1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);
	v[3] = Vertex(1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);


	//back face
	v[4] = Vertex(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
	v[5] = Vertex(1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f);
	v[6] = Vertex(1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
	v[7] = Vertex(-1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f);

	//left face
	v[8] = Vertex(-1.0f, -1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
	v[9] = Vertex(-1.0f, 1.0f, 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
	v[10] = Vertex(-1.0f, 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f);
	v[11] = Vertex(-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f);

	//right face
	v[12] = Vertex(1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
	v[13] = Vertex(1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
	v[14] = Vertex(1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f);
	v[15] = Vertex(1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f);

	//top face
	v[16] = Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
	v[17] = Vertex(-1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f);
	v[18] = Vertex(1.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f);
	v[19] = Vertex(1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);

	//bottom face
	v[20] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f);
	v[21] = Vertex(1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f);
	v[22] = Vertex(1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f);
	v[23] = Vertex(-1.0f, -1.0f, 1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);

	mesh->UnlockVertexBuffer();

	//填充网格索引信息
	DWORD* i = 0;
	mesh->LockIndexBuffer(0, (void**)&i);

	//front face
	i[0] = 0; i[1] = 1; i[2] = 2;
	i[3] = 0; i[4] = 2; i[5] = 3;

	//back face
	i[6] = 4; i[7] = 5; i[8] = 6;
	i[9] = 4; i[10] = 6; i[11] = 7;

	//left face
	i[12] = 8; i[13] = 9; i[14] = 10;
	i[15] = 8; i[16] = 10; i[17] = 11;

	//right face
	i[18] = 12; i[19] = 13; i[20] = 14;
	i[21] = 12; i[22] = 14; i[23] = 15;


	//top face
	i[24] = 16; i[25] = 17; i[26] = 18;
	i[27] = 16; i[28] = 18; i[29] = 19;

	//bottom face
	i[30] = 20; i[31] = 21; i[32] = 22;
	i[33] = 20; i[34] = 22; i[35] = 23;

	mesh->UnlockIndexBuffer();

	//指定属性缓存的值,即面片所属的子集
	DWORD* attributeBuffer = 0;
	mesh->LockAttributeBuffer(0, &attributeBuffer);

	for (int a = 0; a < 4 ; a++)
	{
		attributeBuffer[a] = 0;
	}

	for (int b = 4; b < 8; b++)
	{
		attributeBuffer[b] = 1;
	}

	for (int c = 8; c < 12; c++)
	{
		attributeBuffer[c] = 2;
	}

	mesh->UnlockAttributeBuffer();

	//计算邻接信息
	std::vector adjacencyBuffer(mesh->GetNumFaces()*3);
	mesh->GenerateAdjacency(0.0f, &adjacencyBuffer[0]);

	//网格优化
	hr = mesh->OptimizeInplace(
		D3DXMESHOPT_ATTRSORT | D3DXMESHOPT_COMPACT | D3DXMESHOPT_VERTEXCACHE,
		&adjacencyBuffer[0],
		0, 0, 0
	);

//	HRESULT OptimizeInplace(
//      DWORD Flags,                    //优化方案
//	    const DWORD *pAdjacencyIn,      //未经优化的邻接数组指针
//		DWORD *pAdjacencyOut,           //优化后的邻接信息
//		DWORD *pFaceRemap,              //网格面片的重绘信息
//	    LPD3DXBUFFER *ppVertexRemap     //顶点的重绘信息
//	);

	//输出网格数据到文件中
	OutFile.open("Mesh Dump.txt");

	dumpVertices(OutFile, mesh);
	/*dumpIndices(OutFile, mesh);
	dumpAttributeTable(OutFile, mesh);
	dumpAttributeBuffer(OutFile, mesh);
	dumpAdjacencyBuffer(OutFile, mesh);*/

	OutFile.close();

	//创建三个纹理
	D3DXCreateTextureFromFile(    //读入图像文件,加载到IDirect3DTexture9对象中
		                          //可以加载的图像格式:BMP、DDS、DIB、JPG、PNG、TGA
		device,                   //创建纹理的device
		"tex1.jpg",               //加载的图像文件名
		&tex[0]);                 //创建的纹理

	D3DXCreateTextureFromFile(
		device,
		"tex2.jpg",
		&tex[1]);

	D3DXCreateTextureFromFile(
		device,
		"tex3.jpg",
		&tex[2]);
	
	//设置纹理过滤和多级渐进纹理过滤
	device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
	device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
	device->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);

	device->SetRenderState(D3DRS_LIGHTING, false);

	//取景变换
	D3DXVECTOR3 pos(0.0f, 0.f, -4.0f);
	D3DXVECTOR3 target(0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);

	D3DXMATRIX V;
	D3DXMatrixLookAtLH(
		&V,
		&pos,
		&target,
		&up);

	device->SetTransform(D3DTS_VIEW, &V);

	//投影变换
	D3DXMATRIX proj;
	D3DXMatrixPerspectiveLH(
		&proj,
		D3DX_PI*0.5f,
		(float)width / (float)height,
		1.0f,
		1000.f
	);
	device->SetTransform(D3DTS_PROJECTION, &proj);


	return true;
}

//cleanup
void cleanup() {                              //释放网格和所有纹理
	d3d::Release(mesh);
	for (int i = 0; i < NumSubsets; i++)
	{
		d3d::Release(tex[i]);
	}
}

//display
bool display(float deltaTime) {
	if (device) {
		//设置旋转变换
		D3DXMATRIX xRot;
		D3DXMatrixRotationX(&xRot, D3DX_PI * 0.2f);

		static float y = 0.0f;
		D3DXMATRIX yRot;
		D3DXMatrixRotationY(&yRot, y);
		y += deltaTime;

		if (y >= 6.28f)
			y = 0.0f;

		D3DXMATRIX World = xRot * yRot;

		device->SetTransform(D3DTS_WORLD, &World);

		//清屏
		device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
		//HRESULT Clear(
		//	  DWORD Count,                 //pRects数组中矩形的数目
		//	  const D3DRECT *pRects,       //所要执行清除操作的屏幕矩形数组
		//	  DWORD Flags,                 //所要清除的表面,包括D3DCLEAR_TARGET(后台缓存), D3DCLEAR_ZBUFFER(Z深度缓存), D3DCLEAR_STENCIL(模板平面缓存)
		//	  D3DCOLOR Color,              //指定将绘制目标体设置为何种颜色
		//	  float Z,                     //设定深度缓存,[0,1]
		//	  DWORD Stencil                //模板缓存所要设定的值
		//);

		//开始绘制
		device->BeginScene();

		for (int i = 0; i < NumSubsets; i++)
		{
			device->SetTexture(0, tex[i]);
			mesh->DrawSubset(i);
		}

		device->EndScene();

		//提交后台缓存
		device->Present(0, 0, 0, 0);
	}
	return true;
}

//Wnd_Proc
LRESULT CALLBACK d3d::Wnd_Proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
	switch (msg) {
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_KEYDOWN:             //按下esc退出
		if (wparam == VK_ESCAPE)
			DestroyWindow(hwnd);
	}
	return ::DefWindowProc(hwnd, msg, wparam, lparam);
}

//WinMain
int WINAPI WinMain(HINSTANCE inst, HINSTANCE, PSTR cmd_line, int cmd_show) {
	if (!InitD3D(inst, width, height, true, D3DDEVTYPE_HAL, &device)) {
		MessageBox(NULL, "init_d3d()-fail.", 0, MB_OK);
		return 0;
	}
	if (!Setup()) {
		MessageBox(NULL, "setup_d3d()-fail.", 0, MB_OK);
		return 0;
	}
	d3d::EnterMsgLoop(display);

	cleanup();
	device->Release();

	return 0;
}

//dumpVertices
void dumpVertices(std::ofstream& OutFile, ID3DXMesh* mesh)
{
	OutFile << "vertices:";

	vertex* v = 0;
	mesh->LockVertexBuffer(0, (void**)&v);

	OutFile << "---------" << std::endl;

	for (int i = 0; i < mesh->GetNumVertices(); i++)           //输出顶点信息
	{
		OutFile << "vertice [" << i << "] : (";
		OutFile << v[i]._x << "," << v[i]._y << "," << v[i]._z << ",";
		OutFile << v[i]._nx << "," << v[i]._ny << "," << v[i]._nz << ",";
		OutFile << v[i]._u << "," << v[i]._v << "," << std::endl;
	}

	mesh->UnlockVertexBuffer();

	OutFile << std::endl << std::endl;
}


//void dumpIndices(std::ofstream& OutFile, ID3DXMesh* mesh){}
//void dumpAttributeBuffer(std::ofstream& OutFile, ID3DXMesh* mesh){}
//void dumpAdjacencyBuffer(std::ofstream& OutFile, ID3DXMesh* mesh){}
//void dumpAttributeTable(std::ofstream& OutFile, ID3DXMesh* mesh){}

输出的MeshDump.txt如下:

vertices:
---------
vertice [0] : (-1,-1,1,0,0,1,0,0)
vertice [1] : (1,1,1,0,0,1,1,1)
vertice [2] : (-1,1,1,0,0,1,1,0)
vertice [3] : (1,-1,1,0,0,1,0,1)
vertice [4] : (-1,-1,-1,0,0,-1,0,0)
vertice [5] : (1,1,-1,0,0,-1,1,1)
vertice [6] : (1,-1,-1,0,0,-1,1,0)
vertice [7] : (-1,1,-1,0,0,-1,0,1)
vertice [8] : (1,-1,-1,1,0,0,0,0)
vertice [9] : (1,1,1,1,0,0,1,1)
vertice [10] : (1,-1,1,1,0,0,1,0)
vertice [11] : (1,1,-1,1,0,0,0,1)
vertice [12] : (-1,-1,1,-1,0,0,0,0)
vertice [13] : (-1,1,-1,-1,0,0,1,1)
vertice [14] : (-1,-1,-1,-1,0,0,1,0)
vertice [15] : (-1,1,1,-1,0,0,0,1)
vertice [16] : (-1,-1,-1,0,-1,0,0,0)
vertice [17] : (1,-1,1,0,-1,0,1,1)
vertice [18] : (-1,-1,1,0,-1,0,1,0)
vertice [19] : (1,-1,-1,0,-1,0,0,1)
vertice [20] : (-1,1,-1,0,1,0,0,0)
vertice [21] : (1,1,1,0,1,0,1,1)
vertice [22] : (1,1,-1,0,1,0,1,0)
vertice [23] : (-1,1,1,0,1,0,0,1)

运行结果如下:

DirectX9.0例程:网格的创建与绘制_第1张图片

 

你可能感兴趣的:(DirectX)