direct3d MeshFromObj(win32)

#pragma once
#include "stdafx.h"
#include "template.h"
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
LPDIRECT3D9                g_pD3D       = NULL; //Direct3D对象
LPDIRECT3DDEVICE9          g_pd3dDevice = NULL; //Direct3D设备对象
CMeshLoader             g_MeshLoader;        // Loads a mesh from an .obj file
//-----------------------------------------------------------------------------
// 显示帧率
//-----------------------------------------------------------------------------
ID3DXFont* Font   = 0;
DWORD FrameCnt    = 0;
float TimeElapsed = 0;
float timeDelta   =0;
float FPS         = 0;
TCHAR TFPSString[100];
//-----------------------------------------------------------------------------
// Desc: 顶点结构
//-----------------------------------------------------------------------------

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)  //顶点格式

float g_fSpinX = 0.0f;
float g_fSpinY = 0.0f;
float g_fDisZ = 0.0f;
HRESULT InitGeometry(HWND hWnd )
{
	g_MeshLoader.Create( g_pd3dDevice, L"media\\cup.obj" );
	for( UINT i = 0; i < g_MeshLoader.GetNumMaterials(); i++ )
	{
		Material* pMaterial = g_MeshLoader.GetMaterial( i );
		//pComboBox->AddItem( pMaterial->strName, ( void* )( INT_PTR )i );
	}
	return S_OK;
}
//-----------------------------------------------------------------------------
// Desc: 设置观察矩阵和投影矩阵
//-----------------------------------------------------------------------------
VOID SetWorldMatrix()
{
	static long curTime=0;
	static float elapsetime=0;
	elapsetime = (timeGetTime()-curTime)/1000.0f;
	curTime = timeGetTime();

	D3DXMATRIX matWorld;
	D3DXMATRIX matRotation;
	D3DXMATRIX matTranslation;
	D3DXMatrixRotationYawPitchRoll( &matRotation, D3DXToRadian(g_fSpinX), D3DXToRadian(g_fSpinY), 0.0f );
	D3DXMatrixTranslation( &matTranslation, 0.0f, 0.0f, g_fDisZ );
	/*D3DXMatrixRotationYawPitchRoll( &matRotation, 0.0f, 0.0f, 0.0f );
	D3DXMatrixTranslation( &matTranslation, -g_fSpinX*0.01, g_fSpinY*0.01, g_fDisZ );*/
	matWorld = matRotation * matTranslation;
	g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );


}
VOID SetupViewandProjMatrices()
{
	//创建并设置观察矩阵
	D3DXVECTOR3 vEyePt( 0.0f, 0.0f, -2 );
	D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
	D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
	D3DXMATRIXA16 matView;
	D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
	g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

	//创建并设置投影矩阵
	D3DXMATRIXA16 matProj;
	D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/2, 1.0f, 0.1f, 100.0f );
	g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}


void SetLight()
{
	D3DXVECTOR3 vecDir;
	D3DLIGHT9 light;
	ZeroMemory( &light, sizeof(D3DLIGHT9) );
	light.Type       = D3DLIGHT_DIRECTIONAL;
	light.Diffuse.r   = 1.0f;
	light.Diffuse.g   = 1.0f;
	light.Diffuse.b   = 1.0f;
	light.Diffuse.a   = 1.0f;
	light.Specular.r  = 1.0f;
	light.Specular.g  = 1.0f;
	light.Specular.b  = 1.0f;
	light.Specular.a  = 1.0f;
	vecDir = D3DXVECTOR3(-1.0f, 0.0f, 1.0f);
	D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction, &vecDir );
	light.Range       = 1000.0f;
	g_pd3dDevice->SetLight( 0, &light );
	g_pd3dDevice->LightEnable( 0, true );
	g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );

	//设置环境光
	g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00808080);
}
bool SetFont()
{
	D3DXFONT_DESC df;
	ZeroMemory(&df, sizeof(D3DXFONT_DESC));
	df.Height         = 12;    // in logical units
	df.Width          = 12;    // in logical units 
	df.Weight         = 500;   // boldness, range 0(light) - 1000(bold)
	df.Italic         = false;      
	df.CharSet        = GB2312_CHARSET;
	df.OutputPrecision   = 0;                    
	df.Quality        = 0;           
	df.PitchAndFamily = 0;           
	wcscpy(df.FaceName, L"Times New Roman"); // font style

	if(FAILED(D3DXCreateFontIndirect(g_pd3dDevice, &df, &Font)))
	{
		::MessageBox(0, L"D3DXCreateFontIndirect() - FAILED", 0, 0);
		::PostQuitMessage(0);
	}
	return true;
}
//-----------------------------------------------------------------------------
// Desc: 初始化Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
	if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
		return E_FAIL;

	D3DDISPLAYMODE d3ddm;

	if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
	{
		// TO DO: Respond to failure of GetAdapterDisplayMode
		return E_FAIL;
	}

	HRESULT hr;

	if( FAILED( hr = g_pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
		d3ddm.Format, D3DUSAGE_DEPTHSTENCIL,
		D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
	{
		if( hr == D3DERR_NOTAVAILABLE )
			// POTENTIAL PROBLEM: We need at least a 16-bit z-buffer!
			return E_FAIL;
	}

	//
	// Do we support hardware vertex processing? if so, use it. 
	// If not, downgrade to software.
	//

	D3DCAPS9 d3dCaps;

	if( FAILED( g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, 
		D3DDEVTYPE_HAL, &d3dCaps ) ) )
	{
		// TO DO: Respond to failure of GetDeviceCaps
		return E_FAIL;
	}

	DWORD dwBehaviorFlags = 0;

	if( d3dCaps.VertexProcessingCaps != 0 )
		dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
	else
		dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;

	//
	// Everything checks out - create a simple, windowed device.
	//

	D3DPRESENT_PARAMETERS d3dpp;
	memset(&d3dpp, 0, sizeof(d3dpp));

	d3dpp.BackBufferFormat       = d3ddm.Format;
	d3dpp.SwapEffect             = D3DSWAPEFFECT_DISCARD;
	d3dpp.Windowed               = TRUE;
	d3dpp.EnableAutoDepthStencil = TRUE;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
	d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_IMMEDIATE;

	if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
		dwBehaviorFlags, &d3dpp, &g_pd3dDevice ) ) )
	{
		// TO DO: Respond to failure of CreateDevice
		return E_FAIL;
	}

	//禁用照明效果
	//g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); 

	//设置剔出模式为不剔出任何面
	g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,  D3DCULL_NONE);

	

	//g_pd3dDevice->SetRenderState ( D3DRS_FILLMODE, D3DFILL_WIREFRAME );
	//设置变换矩阵
	SetupViewandProjMatrices();


	SetLight();
	SetFont();
	return S_OK;
}
//-----------------------------------------------------------------------------
// Desc: 释放创建对象
//-----------------------------------------------------------------------------
VOID Cleanup()
{



	//释放Direct3D设备对象
	if( g_pd3dDevice != NULL) 
		g_pd3dDevice->Release();

	//释放Direct3D对象
	if( g_pD3D != NULL)
		g_pD3D->Release();
}


void RenderSubset( UINT iSubset )
{
	//获取当前子网格模型的材质和纹理
	ID3DXMesh* pMesh = g_MeshLoader.GetMesh();
	Material* pMaterial = g_MeshLoader.GetMaterial( iSubset );

	//为当前子网格模型设置材质
	static D3DMATERIAL9 mtrl;
	ZeroMemory( &mtrl, sizeof(D3DMATERIAL9) );
	mtrl.Ambient.r = pMaterial->vAmbient.x;
	mtrl.Ambient.g = pMaterial->vAmbient.x;
	mtrl.Ambient.b = pMaterial->vAmbient.x;
	mtrl.Ambient.a = pMaterial->fAlpha;
	mtrl.Diffuse.r = pMaterial->vDiffuse.x;
	mtrl.Diffuse.g = pMaterial->vDiffuse.y;
	mtrl.Diffuse.b = pMaterial->vDiffuse.z;
	mtrl.Diffuse.a = pMaterial->fAlpha;
	mtrl.Specular.r = pMaterial->vSpecular.x;
	mtrl.Specular.g = pMaterial->vSpecular.y;
	mtrl.Specular.b = pMaterial->vSpecular.z;
	mtrl.Specular.a = pMaterial->fAlpha;
	g_pd3dDevice->SetMaterial( &mtrl );

	//为当前子网格模型设置纹理
	g_pd3dDevice->SetTexture( 0, pMaterial->pTexture );

	//渲染当前子网格模型
	pMesh->DrawSubset( iSubset );
}
//-----------------------------------------------------------------------------
// Desc: 渲染图形
//-----------------------------------------------------------------------------
VOID Render(float timeDelta)
{
	FrameCnt++;

	TimeElapsed += timeDelta;

	if(TimeElapsed >= 1.0f)
	{
		char FPSString[100];
		FPS = (float)FrameCnt / TimeElapsed;
		D3DCAPS9 d3dCaps;
		g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, &d3dCaps );
		if( d3dCaps.VertexProcessingCaps != 0 )
			sprintf(FPSString, "D3D9 %.2ffps HAL(hw vp)", FPS);
		else
			sprintf(FPSString, "D3D9 %.2ffps REF(simulate hw vp) ", FPS);

		int nLen = strlen(FPSString) + 1;  
		FPSString[nLen] = '\0'; // mark end of string
		int nwLen = MultiByteToWideChar(CP_ACP, 0, FPSString, nLen, NULL, 0);   
		MultiByteToWideChar(CP_ACP, 0, FPSString, nLen, TFPSString, nwLen); 
		TimeElapsed = 0.0f;
		FrameCnt    = 0;
	}
	//清空后台缓冲区
	g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(45, 50, 170), 1.0f, 0 );

	
	//开始在后台缓冲区绘制图形
	if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
	{
		RECT rect = {0, 0, 600, 500};
		Font->DrawText(0,TFPSString,-1,&rect,DT_TOP | DT_LEFT, 0xffffff00);

		
		SetWorldMatrix();

		for( UINT iSubset = 0; iSubset < g_MeshLoader.GetNumMaterials(); iSubset++ )
		{
			RenderSubset( iSubset );
		}

		g_pd3dDevice->EndScene();
	}
	//将在后台缓冲区绘制的图形提交到前台缓冲区显示
	g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

//-----------------------------------------------------------------------------
// Desc: 消息处理
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	static POINT ptLastMousePosit;
	static POINT ptCurrentMousePosit;
	static bool bMousing;


	switch( msg )
	{
	
	case WM_LBUTTONDOWN:
		{
			ptLastMousePosit.x = ptCurrentMousePosit.x = LOWORD (lParam);
			ptLastMousePosit.y = ptCurrentMousePosit.y = HIWORD (lParam);
			bMousing = true;
		}
		break;

	case WM_LBUTTONUP:
		{
			bMousing = false;
		}
		break;
	
	case WM_MOUSEMOVE:
		{
			ptCurrentMousePosit.x = LOWORD (lParam);
			ptCurrentMousePosit.y = HIWORD (lParam);

			if( bMousing )
			{
				g_fSpinX -= (ptCurrentMousePosit.x - ptLastMousePosit.x);
				g_fSpinY -= (ptCurrentMousePosit.y - ptLastMousePosit.y);
			}

			ptLastMousePosit.x = ptCurrentMousePosit.x;
			ptLastMousePosit.y = ptCurrentMousePosit.y;
		}
		break;
	
	case WM_MOUSEWHEEL:
		{
			g_fDisZ +=(short)HIWORD (wParam)*0.00005;
		}
		break;
	case WM_DESTROY:
		Cleanup();
		PostQuitMessage( 0 );
		return 0;
	case WM_PAINT:
		Render(timeDelta);
		ValidateRect( hWnd, NULL );
		return 0;
	}

	return DefWindowProc( hWnd, msg, wParam, lParam );
}


//-----------------------------------------------------------------------------
// Desc: 程序入口
//-----------------------------------------------------------------------------
int APIENTRY _tWinMain(HINSTANCE hInstance,
					   HINSTANCE hPrevInstance,
					   LPTSTR    lpCmdLine,
					   int       nCmdShow)
{
	WNDCLASSEX winClass;
	MSG        uMsg;

	memset(&uMsg,0,sizeof(uMsg));

	winClass.lpszClassName = L"MY_WINDOWS_CLASS";
	winClass.cbSize        = sizeof(WNDCLASSEX);
	winClass.style         = CS_HREDRAW | CS_VREDRAW;
	winClass.lpfnWndProc   = MsgProc;
	winClass.hInstance     = hInstance;
	winClass.hIcon	       = LoadIcon(hInstance, (LPCTSTR)IDI_DIRECTX_ICON);
	winClass.hIconSm	   = LoadIcon(hInstance, (LPCTSTR)IDI_DIRECTX_ICON);
	winClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	winClass.lpszMenuName  = NULL;
	winClass.cbClsExtra    = 0;
	winClass.cbWndExtra    = 0;

	if( !RegisterClassEx(&winClass) )
		return E_FAIL;

	HWND hWnd = CreateWindowEx( NULL, L"MY_WINDOWS_CLASS", 
		L"Direct3D (DX9) - Initialization",
		WS_OVERLAPPEDWINDOW | WS_VISIBLE,
		CW_USEDEFAULT, CW_USEDEFAULT, 640, 460, NULL, NULL, hInstance, NULL );

	//初始化Direct3D
	if( SUCCEEDED( InitD3D( hWnd ) ) )
	{ 
		if( SUCCEEDED(InitGeometry(hWnd)))
		{
			//显示主窗口
			ShowWindow( hWnd, SW_SHOWDEFAULT );
			UpdateWindow( hWnd );

			static float lastTime = (float)timeGetTime(); 
			//进入消息循环
			MSG msg;
			ZeroMemory( &msg, sizeof(msg) );
			while( msg.message!=WM_QUIT )
			{
				if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
				{
					TranslateMessage( &msg );
					DispatchMessage( &msg );
				}
				else
				{
					float currTime  = (float)timeGetTime();
					float timeDelta = (currTime - lastTime)*0.001f;
					Render(timeDelta);  //渲染图形
					lastTime = currTime;
				}
			}
		}
	}

	UnregisterClass( L"ClassName", hInstance);
	return 0;
}

MeshLoader.h, MeshLoader.cpp和dxut中的文件在direct3d sample中都有就不贴了,direct3d sample中是基于DXUT框架的,在这里以自己写的win32程序实现
1、刚开始实现时加入DXUT文件夹出现很多未定义的函数,主要是在工程中不要把所有的文件都加载进来,比如DXUTguiIME等文件,需要添加的文件见实现图


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值