// ============================================================================= // Desc:主程序源文件 // ============================================================================= #include " dxstdafx.h " #include " resource.h " // ----------------------------------------------------------------------------- // 全局变量 // ----------------------------------------------------------------------------- ID3DXFont * g_pFont = NULL; // ID3DXFont字体对象 ID3DXSprite * g_pTextSprite = NULL; // ID3DXSprite文本精灵对象 bool g_bShowHelp = true ; // 标识是否显示简单说明文本 CDXUTDialogResourceManagerg_DialogResourceManager; // 对话框资源管理器 CD3DSettingsDlgg_SettingsDlg; // Direct3D设备设置对话框 CDXUTDialogg_HUD; // CDXUTDialogg_SampleUI; // LPDIRECT3DVERTEXBUFFER9g_pVB = NULL; // 顶点缓冲区 LPDIRECT3DTEXTURE9g_pTexture1 = NULL; // 第一层纹理 LPDIRECT3DTEXTURE9g_pTexture2 = NULL; // 第二层纹理 // 定义顶点结构和灵活顶点格式 struct CUSTOMVERTEX {FLOATx,y,z;//未经过坐标转换的顶点坐标DWORDcolor;//顶点漫反射颜色值FLOATu,v;//顶点纹理坐标FLOATu1,v1;//顶点纹理坐标} ; #define D3DFVF_CUSTOMVERTEX(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX2) // ----------------------------------------------------------------------------- // 控件ID // ----------------------------------------------------------------------------- #define IDC_TOGGLEFULLSCREEN1 #define IDC_TOGGLEREF2 #define IDC_CHANGEDEVICE3 // ----------------------------------------------------------------------------- // Desc:函数声明 // ------------------------------------------------------------------------------ bool CALLBACKIsDeviceAcceptable(D3DCAPS9 * pCaps,D3DFORMATAdapterFormat,D3DFORMATBackBufferFormat, bool bWindowed, void * pUserContext); bool CALLBACKModifyDeviceSettings(DXUTDeviceSettings * pDeviceSettings, const D3DCAPS9 * pCaps, void * pUserContext);HRESULTCALLBACKOnCreateDevice(IDirect3DDevice9 * pd3dDevice, const D3DSURFACE_DESC * pBackBufferSurfaceDesc, void * pUserContext);HRESULTCALLBACKOnResetDevice(IDirect3DDevice9 * pd3dDevice, const D3DSURFACE_DESC * pBackBufferSurfaceDesc, void * pUserContext); void CALLBACKOnFrameMove(IDirect3DDevice9 * pd3dDevice, double fTime, float fElapsedTime, void * pUserContext); void CALLBACKOnFrameRender(IDirect3DDevice9 * pd3dDevice, double fTime, float fElapsedTime, void * pUserContext);LRESULTCALLBACKMsgProc(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam, bool * pbNoFurtherProcessing, void * pUserContext); void CALLBACKKeyboardProc(UINTnChar, bool bKeyDown, bool bAltDown, void * pUserContext); void CALLBACKOnGUIEvent(UINTnEvent, int nControlID,CDXUTControl * pControl, void * pUserContext); void CALLBACKOnLostDevice( void * pUserContext); void CALLBACKOnDestroyDevice( void * pUserContext); void InitApp(); void RenderText(); // ----------------------------------------------------------------------------- // Desc:入口函数 // ----------------------------------------------------------------------------- INTWINAPIWinMain(HINSTANCE,HINSTANCE,LPSTR, int ) {//为Debug配置启用运行时内存检查功能#ifdefined(DEBUG)|defined(_DEBUG)_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_LEAK_CHECK_DF);#endif//设置回调函数DXUTSetCallbackDeviceCreated(OnCreateDevice);DXUTSetCallbackDeviceReset(OnResetDevice);DXUTSetCallbackDeviceLost(OnLostDevice);DXUTSetCallbackDeviceDestroyed(OnDestroyDevice);DXUTSetCallbackMsgProc(MsgProc);DXUTSetCallbackKeyboard(KeyboardProc);DXUTSetCallbackFrameRender(OnFrameRender);DXUTSetCallbackFrameMove(OnFrameMove);//应用程序相关的初始化InitApp();//初始化DXUT,创建窗口,创建Direct3D设备对象DXUTInit(true,true,true);DXUTSetCursorSettings(true,true);DXUTCreateWindow(L"MultiTexture");DXUTCreateDevice(D3DADAPTER_DEFAULT,true,640,480,IsDeviceAcceptable,ModifyDeviceSettings);//进入消息循环和场景渲染DXUTMainLoop();//在此进行应用程序相关的清除工作returnDXUTGetExitCode();} // ----------------------------------------------------------------------------- // Desc:应用程序相关初始化 // ----------------------------------------------------------------------------- void InitApp() {//初始化对话框g_SettingsDlg.Init(&g_DialogResourceManager);g_HUD.Init(&g_DialogResourceManager);g_SampleUI.Init(&g_DialogResourceManager);//为g_HUD对话框设置消息处理函数,添加控件g_HUD.SetCallback(OnGUIEvent);intiY=10;g_HUD.AddButton(IDC_TOGGLEFULLSCREEN,L"Togglefullscreen",35,iY,125,22);g_HUD.AddButton(IDC_TOGGLEREF,L"ToggleREF(F3)",35,iY+=24,125,22);g_HUD.AddButton(IDC_CHANGEDEVICE,L"Changedevice(F2)",35,iY+=24,125,22,VK_F2);} // ----------------------------------------------------------------------------- // Desc:设备能力检查 // ----------------------------------------------------------------------------- bool CALLBACKIsDeviceAcceptable(D3DCAPS9 * pCaps,D3DFORMATAdapterFormat,D3DFORMATBackBufferFormat, bool bWindowed, void * pUserContext) {//检查后台缓冲区格式是否支持Alpha混合等操作(postpixelblendingoperations)IDirect3D9*pD3D=DXUTGetD3DObject();if(FAILED(pD3D->CheckDeviceFormat(pCaps->AdapterOrdinal,pCaps->DeviceType,AdapterFormat,D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,D3DRTYPE_TEXTURE,BackBufferFormat)))returnfalse;//检查当前渲染设备是否支持多层纹理混合if(pCaps->MaxTextureBlendStages<=1)returnfalse;returntrue;} // ----------------------------------------------------------------------------- // Desc:修改Direct3D渲染设备设置 // ----------------------------------------------------------------------------- bool CALLBACKModifyDeviceSettings(DXUTDeviceSettings * pDeviceSettings, const D3DCAPS9 * pCaps, void * pUserContext) {//如果不支持硬件顶点处理则使用软件顶点处理if((pCaps->DevCaps&D3DDEVCAPS_HWTRANSFORMANDLIGHT)==0){pDeviceSettings->BehaviorFlags=D3DCREATE_SOFTWARE_VERTEXPROCESSING;}//如果使用参考设备,则弹出警告对话框staticbools_bFirstTime=true;if(s_bFirstTime){s_bFirstTime=false;if(pDeviceSettings->DeviceType==D3DDEVTYPE_REF)DXUTDisplaySwitchingToREFWarning();}returntrue;} // ----------------------------------------------------------------------------- // Desc:在此创建管理内存资源对象 // ----------------------------------------------------------------------------- HRESULTCALLBACKOnCreateDevice(IDirect3DDevice9 * pd3dDevice, const D3DSURFACE_DESC * pBackBufferSurfaceDesc, void * pUserContext) {HRESULThr;V_RETURN(g_DialogResourceManager.OnCreateDevice(pd3dDevice));V_RETURN(g_SettingsDlg.OnCreateDevice(pd3dDevice));//创建字体V_RETURN(D3DXCreateFont(pd3dDevice,15,0,FW_BOLD,1,FALSE,DEFAULT_CHARSET,OUT_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH|FF_DONTCARE,L"Arial",&g_pFont));//创建第一层纹理对象V_RETURN(D3DXCreateTextureFromFile(pd3dDevice,L"Wall.bmp",&g_pTexture1));//创建第二层纹理对象V_RETURN(D3DXCreateTextureFromFile(pd3dDevice,L"light.jpg",&g_pTexture2));//设置顶点数据CUSTOMVERTEXg_Vertices[]={{-3.0f,-3.0f,0.0f,0xffffffff,0.0f,1.0f,0.0f,1.0f},{-3.0f,3.0f,0.0f,0xffffffff,0.0f,0.0f,0.0f,0.0f},{3.0f,-3.0f,0.0f,0xffffffff,1.0f,1.0f,1.0f,1.0f},{3.0f,3.0f,0.0f,0xffffffff,1.0f,0.0f,1.0f,0.0f}};//创建顶点缓冲区V_RETURN(pd3dDevice->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_MANAGED,&g_pVB,NULL));//填充顶点数据VOID*pVertices;V_RETURN(g_pVB->Lock(0,sizeof(g_Vertices),(void**)&pVertices,0));memcpy(pVertices,g_Vertices,sizeof(g_Vertices));g_pVB->Unlock();returnS_OK;} // ----------------------------------------------------------------------------- // Desc:在此创建默认内存类型资源对象 // ----------------------------------------------------------------------------- HRESULTCALLBACKOnResetDevice(IDirect3DDevice9 * pd3dDevice, const D3DSURFACE_DESC * pBackBufferSurfaceDesc, void * pUserContext) {HRESULThr;V_RETURN(g_DialogResourceManager.OnResetDevice());V_RETURN(g_SettingsDlg.OnResetDevice());//设置对话框位置和尺寸g_HUD.SetLocation(pBackBufferSurfaceDesc->Width-170,0);g_HUD.SetSize(170,170);g_SampleUI.SetLocation(pBackBufferSurfaceDesc->Width-170,pBackBufferSurfaceDesc->Height-350);g_SampleUI.SetSize(170,300);//恢复字体if(g_pFont)V_RETURN(g_pFont->OnResetDevice());//创建ID3DXSprite接口对象V_RETURN(D3DXCreateSprite(pd3dDevice,&g_pTextSprite));//设置观察矩阵D3DXMATRIXA16matView;D3DXVECTOR3vEyePt(0.0f,0.0f,-8);D3DXVECTOR3vLookatPt(0.0f,0.0f,0.0f);D3DXVECTOR3vUpVec(0.0f,1.0f,0.0f);D3DXMatrixLookAtLH(&matView,&vEyePt,&vLookatPt,&vUpVec);pd3dDevice->SetTransform(D3DTS_VIEW,&matView);//设置投影矩阵D3DXMATRIXA16matProj;floatfAspectRatio=(float)pBackBufferSurfaceDesc->Width/pBackBufferSurfaceDesc->Height;D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,fAspectRatio,1.0f,100.0f);pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);//设置第层纹理、纹理阶段状态和纹理坐标索引pd3dDevice->SetTexture(0,g_pTexture1);pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_MODULATE);pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE);pd3dDevice->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_DISABLE);pd3dDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,0);pd3dDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);pd3dDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);//设置第层纹理、纹理阶段状态和纹理坐标索引pd3dDevice->SetTexture(1,g_pTexture2);pd3dDevice->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_ADD);pd3dDevice->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE);pd3dDevice->SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_CURRENT);pd3dDevice->SetTextureStageState(1,D3DTSS_ALPHAOP,D3DTOP_DISABLE);pd3dDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,1);pd3dDevice->SetSamplerState(1,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);pd3dDevice->SetSamplerState(1,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);//关闭光照计算pd3dDevice->SetRenderState(D3DRS_LIGHTING,false);returnS_OK;} // ----------------------------------------------------------------------------- // Desc:更新场景 // ----------------------------------------------------------------------------- void CALLBACKOnFrameMove(IDirect3DDevice9 * pd3dDevice, double fTime, float fElapsedTime, void * pUserContext) {} // ----------------------------------------------------------------------------- // Desc:渲染场景 // ----------------------------------------------------------------------------- void CALLBACKOnFrameRender(IDirect3DDevice9 * pd3dDevice, double fTime, float fElapsedTime, void * pUserContext) {HRESULThr;//如果正在利用Direct3D设备设置对话框进行设置,则不渲染场景if(g_SettingsDlg.IsActive()){g_SettingsDlg.OnRender(fElapsedTime);return;}//清除后台颜色缓冲区和深度缓冲区V(pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,D3DCOLOR_ARGB(0,45,50,170),1.0f,0));//渲染场景if(SUCCEEDED(pd3dDevice->BeginScene())){pd3dDevice->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX));pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);//渲染文本和控件DXUT_BeginPerfEvent(DXUT_PERFEVENTCOLOR,L"HUD/Stats");RenderText();V(g_HUD.OnRender(fElapsedTime));V(g_SampleUI.OnRender(fElapsedTime));DXUT_EndPerfEvent();V(pd3dDevice->EndScene());}} // ----------------------------------------------------------------------------- // Desc:渲染文本 // ----------------------------------------------------------------------------- void RenderText() {CDXUTTextHelpertxtHelper(g_pFont,g_pTextSprite,15);//显示当前Direct3D设备状态和渲染帧速率txtHelper.Begin();txtHelper.SetInsertionPos(5,5);txtHelper.SetForegroundColor(D3DXCOLOR(1.0f,1.0f,0.0f,1.0f));txtHelper.DrawTextLine(DXUTGetFrameStats(true));txtHelper.DrawTextLine(DXUTGetDeviceStats());//显示其他简要信息txtHelper.SetForegroundColor(D3DXCOLOR(1.0f,1.0f,1.0f,1.0f));txtHelper.DrawTextLine(L"多层纹理混合");//显示简单帮助文本constD3DSURFACE_DESC*pd3dsdBackBuffer=DXUTGetBackBufferSurfaceDesc();if(g_bShowHelp){txtHelper.SetInsertionPos(10,pd3dsdBackBuffer->Height-15*6);txtHelper.SetForegroundColor(D3DXCOLOR(1.0f,0.75f,0.0f,1.0f));txtHelper.DrawTextLine(L"Controls(F1tohide):");txtHelper.SetInsertionPos(40,pd3dsdBackBuffer->Height-15*5);txtHelper.DrawTextLine(L"Quit:ESC");}else{txtHelper.SetInsertionPos(10,pd3dsdBackBuffer->Height-15*2);txtHelper.SetForegroundColor(D3DXCOLOR(1.0f,1.0f,1.0f,1.0f));txtHelper.DrawTextLine(L"PressF1forhelp");}txtHelper.End();} // ----------------------------------------------------------------------------- // Desc:消息处理 // ----------------------------------------------------------------------------- LRESULTCALLBACKMsgProc(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam, bool * pbNoFurtherProcessing, void * pUserContext) {*pbNoFurtherProcessing=g_DialogResourceManager.MsgProc(hWnd,uMsg,wParam,lParam);if(*pbNoFurtherProcessing)return0;if(g_SettingsDlg.IsActive()){g_SettingsDlg.MsgProc(hWnd,uMsg,wParam,lParam);return0;}*pbNoFurtherProcessing=g_HUD.MsgProc(hWnd,uMsg,wParam,lParam);if(*pbNoFurtherProcessing)return0;*pbNoFurtherProcessing=g_SampleUI.MsgProc(hWnd,uMsg,wParam,lParam);if(*pbNoFurtherProcessing)return0;return0;} // ----------------------------------------------------------------------------- // Desc:键盘消息处理 // ----------------------------------------------------------------------------- void CALLBACKKeyboardProc(UINTnChar, bool bKeyDown, bool bAltDown, void * pUserContext) {if(bKeyDown){switch(nChar){caseVK_F1:g_bShowHelp=!g_bShowHelp;break;}}} // ----------------------------------------------------------------------------- // Desc:处理各种控件消息 // ----------------------------------------------------------------------------- void CALLBACKOnGUIEvent(UINTnEvent, int nControlID,CDXUTControl * pControl, void * pUserContext) {switch(nControlID){caseIDC_TOGGLEFULLSCREEN:DXUTToggleFullScreen();break;caseIDC_TOGGLEREF:DXUTToggleREF();break;caseIDC_CHANGEDEVICE:g_SettingsDlg.SetActive(!g_SettingsDlg.IsActive());break;}} // ----------------------------------------------------------------------------- // Desc:释放在OnResetDevice()中创建的资源 // ----------------------------------------------------------------------------- void CALLBACKOnLostDevice( void * pUserContext) {g_DialogResourceManager.OnLostDevice();g_SettingsDlg.OnLostDevice();if(g_pFont)g_pFont->OnLostDevice();SAFE_RELEASE(g_pTextSprite);} // ------------------------------------------------------------------------------ // Desc:释放在OnCreateDevice()中创建的资源 // ------------------------------------------------------------------------------ void CALLBACKOnDestroyDevice( void * pUserContext) {g_DialogResourceManager.OnDestroyDevice();g_SettingsDlg.OnDestroyDevice();SAFE_RELEASE(g_pFont);SAFE_RELEASE(g_pVB);SAFE_RELEASE(g_pTexture1);SAFE_RELEASE(g_pTexture2);}