www.pudn.com > d3d_mesh.rar > D3DWnd.cpp


// D3DWnd.cpp : 实现文件 
// 
 
#include "stdafx.h" 
#include "Third3D.h" 
#include "D3DWnd.h" 
#include ".\d3dwnd.h" 
 
 
// CD3DWnd 
 
IMPLEMENT_DYNAMIC(CD3DWnd, CWnd) 
CD3DWnd::CD3DWnd() 
: m_nRotateY(0) 
, m_nRotationX(0) 
{ 
	m_ObjectNums=0; 
} 
 
CD3DWnd::~CD3DWnd() 
{ 
} 
 
 
BEGIN_MESSAGE_MAP(CD3DWnd, CWnd) 
	ON_WM_CREATE() 
	ON_WM_DESTROY() 
	ON_WM_TIMER() 
	ON_WM_KEYDOWN() 
END_MESSAGE_MAP() 
 
 
 
// CD3DWnd 消息处理程序 
 
 
void CD3DWnd::InitD3D(void) 
{ 
    m_pD3D=::Direct3DCreate9(D3D_SDK_VERSION); 
	 
	D3DPRESENT_PARAMETERS d3dpp; 
     ::ZeroMemory(&d3dpp, sizeof(d3dpp)); 
	d3dpp.SwapEffect= D3DSWAPEFFECT_DISCARD; 
	d3dpp.Windowed =TRUE; 
	d3dpp.BackBufferFormat =D3DFMT_UNKNOWN; 
	d3dpp.AutoDepthStencilFormat=D3DFMT_D16; 
	d3dpp.EnableAutoDepthStencil =TRUE; 
	m_pD3D->CreateDevice( 
						D3DADAPTER_DEFAULT, //使用缺省的显卡 
						D3DDEVTYPE_HAL, //指定设备类型为HAL 
						m_hWnd, //Direct3D窗口的句柄 
						D3DCREATE_SOFTWARE_VERTEXPROCESSING,//软件顶点处理 
						&d3dpp, &m_pDevice); 
 
    m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE); 
    m_pDevice->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE); 
	m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); } 
 
void CD3DWnd::InitGeometry(void) 
{ 
	LPD3DXBUFFER pD3DXMtrlBuffer; 
	::D3DXLoadMeshFromX( 
		"d:\\3dsmax7\\meshes\\fighter.x", D3DXMESH_SYSTEMMEM, m_pDevice, 
			NULL, &pD3DXMtrlBuffer, NULL, 
			&m_ObjectNums, //返回模型中子集的数目 
			&m_pMesh ); 
	m_pMaterials = new D3DMATERIAL9[m_ObjectNums]; 
	m_pTexture=new LPDIRECT3DTEXTURE9[m_ObjectNums]; 
    D3DXMATERIAL* d3dxMaterials =(D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer(); 
	for( DWORD i=0; i < m_ObjectNums; i++ ) 
	{ 
		//复制子集的材质 
		m_pMaterials[i] = d3dxMaterials[i].MatD3D; 
		//Direct3D在调入Mesh模型时,没有设置材质的环境光颜色, 
		//这里把它设置成和漫反射一样的颜色。 
		m_pMaterials[i].Ambient = m_pMaterials[i].Diffuse; 
		//调入纹理图片 
		::D3DXCreateTextureFromFile( 
					m_pDevice, 
					d3dxMaterials[i].pTextureFilename, //纹理图片的文件名 
					&m_pTexture[i] ); 
	} 
	pD3DXMtrlBuffer->Release(); // 
 
} 
 
void CD3DWnd::Release3D(void) 
{ 
	for(int i=0;iRelease();  
	} 
	delete[]m_pMaterials; 
	delete[] m_pTexture; 
	m_pDevice->Release(); 
	m_pD3D->Release();  
} 
 
void CD3DWnd::SetLight(void) 
{ 
	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.Direction = D3DXVECTOR3( -1.0f, -1.0f,0.0f ); 
	light.Range = 1000.0f; //灯光的作用范围 
	m_pDevice->SetLight( 0, &light ); //设置灯光,参数1为灯光的索引号 
	m_pDevice->LightEnable( 0, TRUE );//打开灯光,参数1为灯光的索引号 
	//设置环境光 
	m_pDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_RGBA(32,32,32,0) ); 
} 
 
void CD3DWnd::SetMatrics(void) 
{  
  
	D3DXMATRIX matWorld; 
	D3DXMATRIX matRotate; 
	D3DXMATRIX matZoom; 
	D3DXMATRIX matTrans; 
	D3DXMATRIX matRX; 
 
	//计算旋转变换矩阵 
	if(GetAsyncKeyState(VK_UP))m_nRotationX+=2; 
	if(GetAsyncKeyState(VK_DOWN))m_nRotationX-=2; 
	if(GetAsyncKeyState(VK_LEFT))m_nRotateY+=2; 
	if(GetAsyncKeyState(VK_RIGHT))m_nRotateY-=2; 
	 
	float angle = m_nRotateY * D3DX_PI / 180; 
	::D3DXMatrixRotationY( &matRotate, angle ); 
	 
 
      angle = m_nRotationX * D3DX_PI / 180; 
	::D3DXMatrixRotationX(&matRX,angle); 
 
	//::D3DXMatrixMultiply( &matRotate, &matRotate, &matRX ); 
	 
	::D3DXMatrixTranslation(&matTrans,0.0,-5.0,0.0); 
	 
 
	//计算缩放变换矩阵:缩小5倍 
	::D3DXMatrixScaling( &matZoom, 1.0f, 1.0f, 1.0f ); 
	//世界变换矩阵=缩放矩阵×旋转矩阵 
 
	::D3DXMatrixMultiply(&matWorld,&matZoom,&matRX); 
 
	::D3DXMatrixMultiply( &matWorld, &matWorld, &matRotate ); 
	::D3DXMatrixMultiply( &matWorld, &matWorld, &matTrans ); 
	//把世界变换矩阵设置到渲染环境 
	m_pDevice->SetTransform( D3DTS_WORLD, &matWorld ); 
 
	 
	 
	 
  D3DXVECTOR3 eye(0.0,3.0f,-25.0f); 
  D3DXVECTOR3 lookat(0.0f,0.0f,0.0f); 
  D3DXVECTOR3 up(0.0f,1.0f,0.0f); 
  D3DXMATRIX matView; 
  ::D3DXMatrixLookAtLH(&matView,&eye,&lookat,&up); 
  m_pDevice->SetTransform(D3DTS_VIEW,&matView);  
 
  D3DXMATRIXA16 matProj; 
//计算透视投影变换矩阵 
  ::D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f ); 
//把投影变换矩阵设置到渲染环境 
  m_pDevice->SetTransform( D3DTS_PROJECTION, &matProj ); 
} 
 
void CD3DWnd::Render(void) 
{ 
   m_pDevice->Clear( 
	  0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 
    D3DCOLOR_XRGB(0,0,0), //指定使用蓝色 
    1.0f, 0); 
 
 
    m_pDevice->BeginScene(); 
	SetLight(); 
	SetMatrics(); 
	for( DWORD i=0; i < m_ObjectNums; i++ ) 
	{ 
		//设置子集的材质 
		m_pDevice->SetMaterial( &m_pMaterials[i] ); 
		//设置子集的纹理,混合方式使用缺省值:纹理 × 材质的漫反射 
		m_pDevice->SetTexture( 0, m_pTexture[i] ); 
		//绘制子集 
    	m_pMesh->DrawSubset( i ); 
		m_pDevice->SetTexture( 0, NULL); 
	} 
	m_pDevice->EndScene(); 
  m_pDevice->Present(NULL,NULL,NULL,NULL);  
} 
 
int CD3DWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{ 
	if (CWnd::OnCreate(lpCreateStruct) == -1) 
		return -1; 
 
    InitD3D(); 
    InitGeometry(); 
	SetTimer(1,40,NULL); 
	return 0; 
} 
 
void CD3DWnd::OnDestroy() 
{ 
	CWnd::OnDestroy(); 
	Release3D(); 
 
} 
 
void CD3DWnd::OnTimer(UINT nIDEvent) 
{ 
    m_nRotateY+=2; 
	Render(); 
	CWnd::OnTimer(nIDEvent); 
} 
 
void CD3DWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{ 
	switch(nChar){ 
		case VK_UP: 
			m_nRotationX+=2; 
			break; 
		case VK_DOWN: 
			m_nRotationX-=2; 
			break; 
	} 
	CWnd::OnKeyDown(nChar, nRepCnt, nFlags); 
}