//=============================================================================
//Desc:主程序源文件
//=============================================================================
#include"dxstdafx.h"
#include"resource.h"

//-----------------------------------------------------------------------------
//全局变量
//-----------------------------------------------------------------------------
ID3DXFont*g_pFont=NULL;//ID3DXFont字体对象
ID3DXSprite*g_pTextSprite=NULL;//ID3DXSprite文本精灵对象
boolg_bShowHelp=true;//标识是否显示简单说明文本
CDXUTDialogResourceManagerg_DialogResourceManager;//对话框资源管理器
CD3DSettingsDlgg_SettingsDlg;//Direct3D设备设置对话框
CDXUTDialogg_HUD;//
CDXUTDialogg_SampleUI;//
LPDIRECT3DVERTEXBUFFER9g_pVB=NULL;//顶点缓冲区
LPDIRECT3DTEXTURE9g_pTexture1=NULL;//第一层纹理
LPDIRECT3DTEXTURE9g_pTexture2=NULL;//第二层纹理

//定义顶点结构和灵活顶点格式
structCUSTOMVERTEX

{
FLOATx,y,z;//未经过坐标转换的顶点坐标
DWORDcolor;//顶点漫反射颜色值
FLOATu,v;//顶点纹理坐标
FLOATu1,v1;//顶点纹理坐标
};
#defineD3DFVF_CUSTOMVERTEX(D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX2)

//-----------------------------------------------------------------------------
//控件ID
//-----------------------------------------------------------------------------
#defineIDC_TOGGLEFULLSCREEN1
#defineIDC_TOGGLEREF2
#defineIDC_CHANGEDEVICE3

//-----------------------------------------------------------------------------
//Desc:函数声明
//------------------------------------------------------------------------------
boolCALLBACKIsDeviceAcceptable(D3DCAPS9*pCaps,D3DFORMATAdapterFormat,D3DFORMATBackBufferFormat,boolbWindowed,void*pUserContext);
boolCALLBACKModifyDeviceSettings(DXUTDeviceSettings*pDeviceSettings,constD3DCAPS9*pCaps,void*pUserContext);
HRESULTCALLBACKOnCreateDevice(IDirect3DDevice9*pd3dDevice,constD3DSURFACE_DESC*pBackBufferSurfaceDesc,void*pUserContext);
HRESULTCALLBACKOnResetDevice(IDirect3DDevice9*pd3dDevice,constD3DSURFACE_DESC*pBackBufferSurfaceDesc,void*pUserContext);
voidCALLBACKOnFrameMove(IDirect3DDevice9*pd3dDevice,doublefTime,floatfElapsedTime,void*pUserContext);
voidCALLBACKOnFrameRender(IDirect3DDevice9*pd3dDevice,doublefTime,floatfElapsedTime,void*pUserContext);
LRESULTCALLBACKMsgProc(HWNDhWnd,UINTuMsg,WPARAMwParam,LPARAMlParam,bool*pbNoFurtherProcessing,void*pUserContext);
voidCALLBACKKeyboardProc(UINTnChar,boolbKeyDown,boolbAltDown,void*pUserContext);
voidCALLBACKOnGUIEvent(UINTnEvent,intnControlID,CDXUTControl*pControl,void*pUserContext);
voidCALLBACKOnLostDevice(void*pUserContext);
voidCALLBACKOnDestroyDevice(void*pUserContext);
voidInitApp();
voidRenderText();

//-----------------------------------------------------------------------------
//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:应用程序相关初始化
//-----------------------------------------------------------------------------
voidInitApp()

{
//初始化对话框
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:设备能力检查
//-----------------------------------------------------------------------------
boolCALLBACKIsDeviceAcceptable(D3DCAPS9*pCaps,D3DFORMATAdapterFormat,
D3DFORMATBackBufferFormat,boolbWindowed,
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渲染设备设置
//-----------------------------------------------------------------------------
boolCALLBACKModifyDeviceSettings(DXUTDeviceSettings*pDeviceSettings,
constD3DCAPS9*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,
constD3DSURFACE_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,
constD3DSURFACE_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:更新场景
//-----------------------------------------------------------------------------
voidCALLBACKOnFrameMove(IDirect3DDevice9*pd3dDevice,doublefTime,
floatfElapsedTime,void*pUserContext)

{
}

//-----------------------------------------------------------------------------
//Desc:渲染场景
//-----------------------------------------------------------------------------
voidCALLBACKOnFrameRender(IDirect3DDevice9*pd3dDevice,doublefTime,
floatfElapsedTime,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:渲染文本
//-----------------------------------------------------------------------------
voidRenderText()

{
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:键盘消息处理
//-----------------------------------------------------------------------------
voidCALLBACKKeyboardProc(UINTnChar,boolbKeyDown,boolbAltDown,void*pUserContext)

{
if(bKeyDown)

{
switch(nChar)

{
caseVK_F1:g_bShowHelp=!g_bShowHelp;break;
}
}
}

//-----------------------------------------------------------------------------
//Desc:处理各种控件消息
//-----------------------------------------------------------------------------
voidCALLBACKOnGUIEvent(UINTnEvent,intnControlID,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()中创建的资源
//-----------------------------------------------------------------------------
voidCALLBACKOnLostDevice(void*pUserContext)

{
g_DialogResourceManager.OnLostDevice();
g_SettingsDlg.OnLostDevice();
if(g_pFont)
g_pFont->OnLostDevice();
SAFE_RELEASE(g_pTextSprite);
}

//------------------------------------------------------------------------------
//Desc:释放在OnCreateDevice()中创建的资源
//------------------------------------------------------------------------------
voidCALLBACKOnDestroyDevice(void*pUserContext)

{
g_DialogResourceManager.OnDestroyDevice();
g_SettingsDlg.OnDestroyDevice();
SAFE_RELEASE(g_pFont);
SAFE_RELEASE(g_pVB);
SAFE_RELEASE(g_pTexture1);
SAFE_RELEASE(g_pTexture2);
}
本文介绍在Direct3D中实现多层纹理混合的技术细节,包括设备能力检查、修改Direct3D渲染设备设置、创建管理内存资源对象、更新场景、渲染场景以及消息处理等功能。
1932

被折叠的 条评论
为什么被折叠?



