⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainfrm.cpp

📁 CEGUI是用来做3D游戏UI界面开发的底层接口库
💻 CPP
字号:
// MainFrm.cpp : CMainFrame 类的实现
//

#include "stdafx.h"
#include "MFCD3D.h"
#include "MainFrm.h"
#include <CEGUI.h>
#include <CEGUIDefaultResourceProvider.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CMainFrame

IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	ON_WM_CREATE()
	ON_WM_SETFOCUS()
	ON_WM_DESTROY()
	ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()


// CMainFrame 构造/析构

CMainFrame::CMainFrame()
: m_d3dDevice(NULL) , 
  m_pCEGUIRender(NULL) ,
  m_pMesh(NULL) , 
  m_pMeshMaterials(NULL) ,
  m_pText(NULL)
{
	m_rotateY = 0.0f;
}

CMainFrame::~CMainFrame()
{
}


int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	// 创建一个视图以占用框架的工作区
	if (!m_wndView.Create(NULL, NULL, AFX_WS_DEFAULT_VIEW,
		CRect(0, 0, 0, 0), this, AFX_IDW_PANE_FIRST, NULL))
	{
		TRACE0("未能创建视图窗口\n");
		return -1;
	}
	
	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
		!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
	{
		TRACE0("未能创建工具栏\n");
		return -1;      // 未能创建
	}
	// TODO: 如果不需要工具栏可停靠,则删除这三行
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);

	return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	// TODO: 在此处通过修改 CREATESTRUCT cs 来修改窗口类或
	// 样式

	cs.style = WS_OVERLAPPED | WS_CAPTION | FWS_ADDTOTITLE
		 | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX;

	cs.dwExStyle &= ~WS_EX_CLIENTEDGE;
	cs.lpszClass = AfxRegisterWndClass(0);
	return TRUE;
}


// CMainFrame 诊断

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CFrameWnd::Dump(dc);
}

#endif //_DEBUG


// CMainFrame 消息处理程序

void CMainFrame::OnSetFocus(CWnd* /*pOldWnd*/)
{
	// 将焦点前移到视图窗口
	m_wndView.SetFocus();
}

BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
	// 让视图第一次尝试该命令
	if (m_wndView.OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
		return TRUE;

	// 否则,执行默认处理
	return CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
}

// 渲染
void CMainFrame::Render(float timeDelta)
{
	if(m_d3dDevice) // Only use Device methods if we have a valid device.
	{
		//
		// Draw the Scene:
		//
		m_d3dDevice->BeginScene();
		m_d3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(50 , 0 , 50) , 1.0f, 0);
            /// Render Meshs
            DrawMesh();
			/// Render CEGUI
			CEGUI::System::getSingleton().renderGUI();

		m_d3dDevice->EndScene();
		m_d3dDevice->Present(0, 0, 0, 0);
	}
}

void CMainFrame::DrawMesh()
{
	D3DXMATRIX objMat , matRotate , finalMat;
	
	D3DXMatrixIdentity(&objMat);
	D3DXMatrixRotationY(&matRotate , m_rotateY);
	D3DXMatrixMultiply(&finalMat , &objMat , &matRotate);


	m_d3dDevice->SetTransform(D3DTS_WORLD , &finalMat);
    m_d3dDevice->SetTexture(0 , m_pText);
	m_d3dDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
	m_d3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
	m_d3dDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);


    for(DWORD i = 0; i < m_dwNumMaterials;++i)
    {
        m_d3dDevice->SetMaterial(&m_pMeshMaterials[i]);
        m_pMesh->DrawSubset(i);
    }
}

// 初始化D3D
BOOL CMainFrame::InitD3D(void)
{
	ASSERT(IsWindow(m_wndView.m_hWnd));
	// 初始化Direct3D9
	// Step1.获得IDirect3D9接口
	IDirect3D9* _d3d9;
	_d3d9 = Direct3DCreate9(D3D_SDK_VERSION);
	if(!_d3d9)
	{
		::AfxMessageBox(_T("Get Interface of Direct3D Failed!") , MB_ICONSTOP);
		return FALSE;
	}
	// Step2.检查显卡能力
	D3DCAPS9 caps;
	_d3d9->GetDeviceCaps(D3DADAPTER_DEFAULT ,
		D3DDEVTYPE_HAL ,
		&caps);
	int vp = 0;
	if(caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
		vp = D3DCREATE_HARDWARE_VERTEXPROCESSING;
	else
		vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
	// Step3.填充D3DPRESENT_PARAMETERS
	D3DPRESENT_PARAMETERS d3dpp;
	CRect rect;
	GetClientRect(&rect);
	ZeroMemory(&d3dpp,sizeof(D3DPRESENT_PARAMETERS));
	d3dpp.BackBufferWidth            = rect.Width();
	d3dpp.BackBufferHeight           = rect.Height();
	d3dpp.BackBufferFormat           = D3DFMT_A8R8G8B8;
	d3dpp.BackBufferCount            = 1;
	d3dpp.MultiSampleType            = D3DMULTISAMPLE_NONE;
	d3dpp.MultiSampleQuality         = 0;
	d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD; 
	d3dpp.hDeviceWindow              = m_wndView.m_hWnd;
	d3dpp.Windowed                   = true;		// 一定要为true
	d3dpp.EnableAutoDepthStencil     = true; 
	d3dpp.AutoDepthStencilFormat     = D3DFMT_D24S8;
	d3dpp.Flags                      = 0;
	d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
	d3dpp.PresentationInterval       = D3DPRESENT_INTERVAL_IMMEDIATE;

	// Step4.创建Direct3D设备
	HRESULT hr;
	hr = _d3d9->CreateDevice(D3DADAPTER_DEFAULT ,
		D3DDEVTYPE_HAL ,
		m_wndView.m_hWnd ,
		vp ,
		&d3dpp ,
		&m_d3dDevice);
	if(FAILED(hr))
	{
		switch(hr)
		{
		case D3DERR_DEVICELOST:
			AfxMessageBox(_T("Create D3D Device Failed!<Error:D3DERR_DEVICELOST>") , MB_ICONSTOP);
			break;
		case D3DERR_INVALIDCALL:
			AfxMessageBox(_T("Create D3D Device Failed!<Error:D3DERR_INVALIDCALL>") , MB_ICONSTOP);
			break;
		case D3DERR_NOTAVAILABLE:
			AfxMessageBox(_T("Create D3D Device Failed!<Error:D3DERR_NOTAVAILABLE>") , MB_ICONSTOP);
			break;
		case D3DERR_OUTOFVIDEOMEMORY:
			AfxMessageBox(_T("Create D3D Device Failed!<Error:D3DERR_OUTOFVIDEOMEMORY>") , MB_ICONSTOP);
			break;
		}
		_d3d9->Release();
		return FALSE;
	}
	_d3d9->Release();
	// Direct3D9初始化完成
	// 装载资源
	Setup();
	return TRUE;
}
// 清除资源
void CMainFrame::CleanUp(void)
{
    SAFE_DELETE_ARRAY(m_pMeshMaterials)
}

// 装载资源
BOOL CMainFrame::Setup(void)
{
    if(!SetupModel())
        return FALSE;
    if(!SetupGUI())
        return FALSE;

	return TRUE;
}

BOOL CMainFrame::SetupModel()
{
    LPD3DXBUFFER ppAdjacencyBuffer;
    LPD3DXBUFFER pD3DXMtrlBuffer;
    HRESULT hr;
    
    /// 加载Mesh
    hr = D3DXLoadMeshFromX("../meshs/EvilDrone.x" , 
        D3DXMESH_SYSTEMMEM , 
        m_d3dDevice , 
        &ppAdjacencyBuffer , 
        &pD3DXMtrlBuffer , 
        NULL , 
        &m_dwNumMaterials , 
        &m_pMesh);
    if(FAILED(hr))
        return FALSE;
    /// 设置材质
    D3DXMATERIAL* matMaterials = static_cast<D3DXMATERIAL*>(pD3DXMtrlBuffer->GetBufferPointer());
    m_pMeshMaterials = new D3DMATERIAL9[m_dwNumMaterials];
    for(DWORD i = 0;i < m_dwNumMaterials;++i)
    {
        m_pMeshMaterials[i] = matMaterials[i].MatD3D;
        m_pMeshMaterials[i].Ambient = m_pMeshMaterials[i].Diffuse;
    }
	// 设置摄像机参数
	D3DXVECTOR3 pos(0.0f , 0.0f , -5.0f);
	D3DXVECTOR3 tag(0.0f , 0.0f , 20.0f);
	D3DXVECTOR3 up(0.0f , 1.0f , 0.0f);
	D3DXMATRIX v;
	D3DXMatrixLookAtLH(&v , &pos , &tag , &up);
	m_d3dDevice->SetTransform(D3DTS_VIEW , &v);
	// 设置(平行)投影矩阵
	D3DXMATRIX proj;
	CRect rect;
	m_wndView.GetClientRect(&rect);
	D3DXMatrixPerspectiveFovLH(
			&proj,
			D3DX_PI * 0.25f, // 45 - degree
			(float)rect.Width() / (float)rect.Height(),
			1.0f,
			1000.0f);

	m_d3dDevice->SetTransform(D3DTS_PROJECTION , &proj);
    m_d3dDevice->SetRenderState(D3DRS_AMBIENT , D3DCOLOR_XRGB(0 , 0 , 0));
	m_d3dDevice->SetRenderState(D3DRS_CULLMODE , D3DCULL_CCW);

    m_d3dDevice->SetRenderState(D3DRS_LIGHTING, TRUE);	// 把光照打开
    /// 设置光照
    D3DLIGHT9 light;
    light.Type = D3DLIGHT_DIRECTIONAL;
    D3DXVECTOR3 dir(0.0f , 0.0f , 0.0f);
    D3DXVec3Normalize((D3DXVECTOR3*)&light.Direction , &dir);
    light.Diffuse.r = 0.0f;
    light.Diffuse.g = 0.5f;
    light.Diffuse.b = 0.5f;
    light.Ambient.r = 0.0f;
    light.Ambient.g = 0.3f;
    light.Ambient.b = 0.3f;
    light.Range = sqrtf(FLT_MAX);
    m_d3dDevice->SetLight(0 , &light);
    m_d3dDevice->LightEnable(0 , TRUE);
    /// 载入纹理
    if(FAILED(D3DXCreateTextureFromFile(m_d3dDevice , "../meshs/EvilDrone_Diff.jpg" , &m_pText)))
    {
        AfxMessageBox(_T("纹理文件载入失败!"));
        return FALSE;
    }
	m_d3dDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
	m_d3dDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);

    return TRUE;
}

BOOL CMainFrame::SetupGUI()
{
	m_pCEGUIRender = new CEGUI::DirectX9Renderer(m_d3dDevice , 0);	
	new CEGUI::System(m_pCEGUIRender);
	/// 初始化GUI资源的缺省路径
	CEGUI::DefaultResourceProvider* rp = static_cast<CEGUI::DefaultResourceProvider*>
		(CEGUI::System::getSingleton().getResourceProvider());
	rp->setResourceGroupDirectory("schemes", "../datafiles/schemes/");
	rp->setResourceGroupDirectory("imagesets", "../datafiles/imagesets/");
	rp->setResourceGroupDirectory("fonts", "../datafiles/fonts/");
	rp->setResourceGroupDirectory("layouts", "../datafiles/layouts/");
	rp->setResourceGroupDirectory("looknfeels", "../datafiles/looknfeel/");
	//rp->setResourceGroupDirectory("lua_scripts", "../datafiles/lua_scripts/");
	/// 设置使用的缺省资源
	CEGUI::Imageset::setDefaultResourceGroup("imagesets");
	CEGUI::Font::setDefaultResourceGroup("fonts");
	CEGUI::Scheme::setDefaultResourceGroup("schemes");
	CEGUI::WidgetLookManager::setDefaultResourceGroup("looknfeels");
	CEGUI::WindowManager::setDefaultResourceGroup("layouts");
	//CEGUI::ScriptModule::setDefaultResourceGroup("lua_scripts");
	/// 设置GUI
	using namespace CEGUI;


	/// 得到GUI样式的图片集
	Imageset* taharezlookImage;
	try{
		taharezlookImage = ImagesetManager::getSingleton().createImageset("TaharezLook.imageset");
	}catch (CEGUI::Exception& exc)
	{
		AfxMessageBox(exc.getMessage().c_str());
	}
	/// 设置鼠标图标
	System::getSingleton().setDefaultMouseCursor(&taharezlookImage->getImage("MouseArrow"));

	/// 设置字体
	FontManager::getSingleton().createFont("Commonwealth-10.font");

	/// 设置GUI皮肤
	WidgetLookManager::getSingleton().parseLookNFeelSpecification("TaharezLook.looknfeel");

	/// 载入GUI规划
	SchemeManager::getSingleton().loadScheme("TaharezLook.scheme");
	/// 得到窗口管理单件
	WindowManager& winMgr = WindowManager::getSingleton();

	/// 从layout文件中载入布局
	Window* gameGUI = winMgr.loadWindowLayout("GameGUI.layout"); 

	/// 设置GUI的Sheet(Sheet是CEGUI中窗口的容器)
	System::getSingleton().setGUISheet(gameGUI);

    /// 设置两个旋转按钮文本
	winMgr.getWindow("GameGUI/Left")->setText("TurnLeft");
	winMgr.getWindow("GameGUI/Right")->setText("TurnRight");
	/// 设置鼠标事件自动重复
	winMgr.getWindow("GameGUI/Left")->setWantsMultiClickEvents(false);
	winMgr.getWindow("GameGUI/Left")->setMouseAutoRepeatEnabled(true);
//	winMgr.getWindow("GameGUI/Left")->setAutoRepeatDelay(1.0f);
	winMgr.getWindow("GameGUI/Right")->setWantsMultiClickEvents(false);
	winMgr.getWindow("GameGUI/Right")->setMouseAutoRepeatEnabled(true);
//	winMgr.getWindow("GameGUI/Right")->setAutoRepeatDelay(1.0f);
	/// 添加两个按钮的事件处理函数
	winMgr.getWindow("GameGUI/Left")->subscribeEvent(
		CEGUI::Window::EventMouseButtonDown, 
		CEGUI::Event::Subscriber(&CMainFrame::TurnLeft, this));
	winMgr.getWindow("GameGUI/Right")->subscribeEvent(
		CEGUI::Window::EventMouseButtonDown, 
		CEGUI::Event::Subscriber(&CMainFrame::TurnRight, this));

	return TRUE;
}

void CMainFrame::OnDestroy()
{
	CFrameWnd::OnDestroy();

	CleanUp();

	m_d3dDevice->Release();
}
void CMainFrame::OnMouseMove(UINT nFlags, CPoint point)
{
	::ShowCursor(TRUE);

	CFrameWnd::OnMouseMove(nFlags, point);
}

bool CMainFrame::TurnLeft(const CEGUI::EventArgs& e)
{
	m_rotateY += 0.1f;
	
	return true;
}

bool CMainFrame::TurnRight(const CEGUI::EventArgs& e)
{
	m_rotateY -= 0.1f;

	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -