📄 mainfrm.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 + -