一、DXUT框架
为了方便我们使用D3D,在这里DXUT框架(基于DX9).我们只需要设置一系列的回调函数就可以很好的使用D3D,节省了很多代码。使用这个框架,我们只需要知道每个回调函数的作用,在回调函数中写上处理代码即可。
#include "DXUT.h"
#include "DXUTgui.h"
/*-----------------------------------------------------------
*************************************************************
*D3D相关回调函数
*************************************************************
------------------------------------------------------------*/
//1.D3d设备创建成功后回调
HRESULT CALLBACK OnD3D9CreateDevice(IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext);
//2.重置D3d设备成功后回调
HRESULT CALLBACK OnD3D9ResetDevice(IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext);
//3.主消息处理和传递函数
LRESULT CALLBACK MsgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext);
//4.主渲染函数,主要是显示部分
void CALLBACK OnD3D9FrameRender(IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext);
//5.D3d设备丢失后回调,如显卡突然损坏了
void CALLBACK OnD3D9LostDevice(void* pUserContext);
//6.D3d设备销毁(释放)后回调,如关闭程序
void CALLBACK OnD3D9DestroyDevice(void* pUserContext);
//7.键盘事件回调
void CALLBACK OnKeyboard(UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext);
//8.Dialog上的按钮等响应(这个是CDXUTDialog部分的,不属于框架)
void CALLBACK OnGUIEvent(UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext);
//9.鼠标事件
void CALLBACK OnMouse(bool bLeftButtonDown, bool bRightButtonDown, bool bMiddleButtonDown, bool bSideButton1Down, bool bSideButton2Down, int nMouseWheelDelta, int xPos, int yPos, void* pUserContext);
//Main 入口函数
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
{
// Enable run-time memory check for debug builds.
// TODO: 在此放置代码。
// Set DXUT callbacks
DXUTSetCallbackMsgProc(MsgProc);
DXUTSetCallbackKeyboard(OnKeyboard);
DXUTSetCallbackMouse(OnMouse);
DXUTSetCallbackD3D9DeviceCreated(OnD3D9CreateDevice);
DXUTSetCallbackD3D9DeviceReset(OnD3D9ResetDevice);
DXUTSetCallbackD3D9DeviceLost(OnD3D9LostDevice);
DXUTSetCallbackD3D9DeviceDestroyed(OnD3D9DestroyDevice);
DXUTSetCallbackD3D9FrameRender(OnD3D9FrameRender);
InitAppUI();
DXUTInit(true, true, NULL); // Parse the command line, show msgboxes on error, no extra command line params
DXUTSetCursorSettings(true, true);
DXUTCreateWindow(L"拼接程序(DX9)");
DXUTCreateDevice(true, 440, 280);
DXUTMainLoop(); // Enter into the DXUT render loop
return DXUTGetExitCode();
}
对于ID3D开头的类,大多数情况下是以指针的形式使用,在使用完成后一定要记得Safe Release,否则容易内存泄漏。
#define SAFE_RELEASE(p) { if (p) { (p)->Release(); (p)=NULL; } }
二、基本的设置窗口和程序全屏
拼接程序需要设置很多参数,就需要一个设置界面,在全屏状态下通过点击按钮和改变参数来调整拼接的效果,我使用的是CDXUTDialog,例如程序在启动之前需要设置屏幕(投影机)的排列方式
//CDXUTDialogResourceManager g_DlgResManager; //对话框管理器(针对所有的)
//CDXUTDialog g_BasicSetDlg; //设置对话框
void InitAppUI()
{
g_BasicSetDlg.Init(&g_DlgResManager);
g_BasicSetDlg.SetCallback(OnGUIEvent);
//
g_BasicSetDlg.AddStatic(IDC_STATIC_SCREENWIDTH, L"单个屏幕宽(像素):", 80, 30, 125, 22);
g_BasicSetDlg.AddStatic(IDC_STATIC_SCREENHEIGHT, L"单个屏幕高(像素):", 80, 70, 125, 22);
g_BasicSetDlg.AddEditBox(IDC_EDIT_SCREENWIDTH, L"1920", 230, 25, 125, 35);
g_BasicSetDlg.AddEditBox(IDC_EDIT_SCREENHEIGHT, L"1080", 230, 65, 125, 35);
//
g_BasicSetDlg.AddStatic(IDC_STATIC_SCREENROWS, L"屏幕排列-行:", 80, 110, 125, 22);
g_BasicSetDlg.AddStatic(IDC_STATIC_SCREENCOLS, L"屏幕排列-列:", 80, 150, 125, 22);
g_BasicSetDlg.AddEditBox(IDC_EDIT_SCREENROWS, L"1", 230, 105, 125, 35);
g_BasicSetDlg.AddEditBox(IDC_EDIT_SCREENCOLS, L"1", 230, 145, 125, 35);
//BTN
g_BasicSetDlg.AddButton(IDC_BTN_CONFIRM, L"确认", 80, 220, 80, 30);
g_BasicSetDlg.AddButton(IDC_BTN_CANCEL, L"取消", 280, 220, 80, 30);
}
全屏状态
//移动界面
::SetWindowLong(DXUTGetHWND(), GWL_STYLE, WS_EX_TOPMOST | WS_POPUP); //设置样式
::SetWindowPos(DXUTGetHWND(), HWND_NOTOPMOST, 0, 0, g_BasicSet.Width*g_BasicSet.Cols, g_BasicSet.Height*g_BasicSet.Rows, SWP_SHOWWINDOW);//移动位置
设置观察点
void SetTransformAndState()
{
LPDIRECT3DDEVICE9 pd3dDevice = DXUTGetD3D9Device();
//初始化位置
D3DXMATRIX Ortho2D;
D3DXMATRIX Identity;
//设置观看方式永远位于屏幕中心
D3DXMatrixIdentity(&Identity);
D3DXMatrixOrthoLH(&Ortho2D, AllScreenWidth, AllScreenHeight, 1.0f, 1000.0f);
pd3dDevice->SetTransform(D3DTS_PROJECTION, &Ortho2D);
pd3dDevice->SetTransform(D3DTS_VIEW, &Identity);
//D3DXMatrixRotationY(&Identity, 1);
pd3dDevice->SetTransform(D3DTS_WORLD, &Identity);
//设置材质?不知道干啥
D3DMATERIAL9 mtrl;
::ZeroMemory(&mtrl, sizeof(mtrl));
mtrl.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
mtrl.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
mtrl.Specular = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
pd3dDevice->SetMaterial(&mtrl);
// Set the ambient light
pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
pd3dDevice->SetRenderState(D3DRS_AMBIENT, D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f));
}