实验七广告板的技术.docx
《实验七广告板的技术.docx》由会员分享,可在线阅读,更多相关《实验七广告板的技术.docx(16页珍藏版)》请在冰豆网上搜索。
实验七广告板的技术
实验七:
广告板技术
一、实验目的
掌握广告板技术的原理,熟悉广告板技术使用方法.
二、实验仪器
Pc,vs2010
三、实验原理及过程
//利用广告板技术实现一个某种特效,如树木,并描述程序实现时的思路包括对每个调用的API以及脚本
进行详细说明
1、广告板技术原理:
采用一个带有纹理的四边形,其纹理图像为该广告板所代表的物体的图像,即用带有该物体图像的长方形,代替该物体生成该物体的图形画面。
广告版放置于所代表物体的位置中心,并随相机的运动而变化,始终面对用户。
2、主要调用的API函数说明:
//创建广告板矩形和纹理对象
HRESULTCALLBACKOnCreateDevice(IDirect3DDevice9*pd3dDevice,
constD3DSURFACE_DESC*pBackBufferSurfaceDesc,
void*pUserContext);
//渲染场景
pd3dDevice->SetTransform(D3DTS_WORLD,&g_matGround);
pd3dDevice->SetTexture(0,g_pGroundTex);//设置纹理
pd3dDevice->SetStreamSource(0,g_pGroundVB,0,sizeof(CUSTOMVERTEX));
pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
//渲染树木
pd3dDevice->SetTransform(D3DTS_WORLD,&g_matTree);
pd3dDevice->SetTexture(0,g_pTreeTex);
pd3dDevice->SetStreamSource(0,g_pTreeVB,0,sizeof(CUSTOMVERTEX));
pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
四、实验结果
五、实验心得
通过本次实验掌握广告板技术的原理,熟悉广告板技术使用方法,了解广告板技术的使用流程,对Direct3D渲染设备的渲染技术有了更多的了解;广告板不能独立存在,必须依赖于某个广告板集,广告板集内所有的广告板的尺寸、材质均相同。
六、主要代码
//BillBoard.cpp
//-----------------------------------------------------------------------------
//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"BillBoard");
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);
g_HUD.AddCheckBox(IDC_USEBILLBOARD,L"使用BillBoard矩阵",40,iY+=32,160,24,g_bUseBillBoard);
}
//-----------------------------------------------------------------------------
//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;
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(pd3dDevice->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX),
0,D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED,&g_pGroundVB,NULL));
CUSTOMVERTEXvertices1[]=
{
{-32.0f,0.0f,-32.0f,0.0f,16.0f,},
{-32.0f,0.0f,32.0f,0.0f,0.0f,},
{32.0f,0.0f,-32.0f,16.0f,16.0f,},
{32.0f,0.0f,32.0f,16.0f,0.0f,}
};
VOID*pVertices1;
if(FAILED(g_pGroundVB->Lock(0,sizeof(vertices1),(void**)&pVertices1,0)))
returnE_FAIL;
memcpy(pVertices1,vertices1,sizeof(vertices1));
g_pGroundVB->Unlock();
//创建树木顶点缓冲区
V_RETURN(pd3dDevice->CreateVertexBuffer(4*sizeof(CUSTOMVERTEX),
0,D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED,&g_pTreeVB,NULL));
CUSTOMVERTEXvertices2[]=
{
{-1.0f,0.0f,0.0f,0.0f,1.0f,},
{-1.0f,2.5f,0.0f,0.0f,0.0f,},
{1.0f,0.0f,0.0f,1.0f,1.0f,},
{1.0f,2.5f,0.0f,1.0f,0.0f,}
};
VOID*pVertices2;
if(FAILED(g_pTreeVB->Lock(0,sizeof(vertices2),(void**)&pVertices2,0)))
returnE_FAIL;
memcpy(pVertices2,vertices2,sizeof(vertices2));
g_pTreeVB->Unlock();
//创建地面纹理和树木纹理
V_RETURN(D3DXCreateTextureFromFile(pd3dDevice,L"ground.jpg",&g_pGroundTex));
V_RETURN(D3DXCreateTextureFromFile(pd3dDevice,L"tree.dds",&g_pTreeTex));
returnS_OK;
}
//-----------------------------------------------------------------------------
//Desc:
在此创建默认内存类型资源对象,设置纹理操作启用alpha混合,alpha混合系数
//-----------------------------------------------------------------------------
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));
//初始化地面世界矩阵
D3DXMatrixIdentity(&g_matGround);
//初始化树木世界矩阵
D3DXMatrixIdentity(&g_matTree);
//设置投影矩阵
D3DXMATRIXA16matProj;
floatfAspectRatio=(float)pBackBufferSurfaceDesc->Width/pBackBufferSurfaceDesc->Height;
D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,fAspectRatio,1.0f,100.0f);
pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);
//设置纹理状态
pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
pd3dDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
pd3dDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
//Alpha混合设置,设置混合系数
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,true);
pd3dDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
pd3dDevice->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
//禁用照明效果
pd3dDevice->SetRenderState(D3DRS_LIGHTING,false);
returnS_OK;
}
//-----------------------------------------------------------------------------
//Desc:
更新场景,根据观察方向,构造广告板矩阵,通过广告板矩阵旋转矩形对象,使其面向观察者
//-----------------------------------------------------------------------------
voidCALLBACKOnFrameMove(IDirect3DDevice9*pd3dDevice,doublefTime,
floatfElapsedTime,void*pUserContext)
{
//设置观察矩阵
staticD3DXMATRIXA16matView;
floatangle=(float)fTime/2.0f;
D3DXVECTOR3vEyePt(8*sin(angle),1.5f,8*cos(angle));
D3DXVECTOR3vLookatPt(0.0f,0.0f,0.0f);
D3DXVECTOR3vUpVec(0.0f,1.0f,0.0f);
D3DXMatrixLookAtLH(&matView,&vEyePt,&vLookatPt,&vUpVec);
pd3dDevice->SetTransform(D3DTS_VIEW,&matView);
//初始化树木世界矩阵
D3DXMatrixIdentity(&g_matTree);
//使用广告板矩阵
staticD3DXMATRIXmatBillBoard;
if(g_bUseBillBoard==true)
{
//根据当前观察方向构造广告板矩阵
D3DXVECTOR3vDir=vLookatPt-vEyePt;
if(vDir.x>0.0f)
D3DXMatrixRotationY(&matBillBoard,-atanf(vDir.z/vDir.x)+D3DX_PI/2);
else
D3DXMatrixRotationY(&matBillBoard,-atanf(vDir.z/vDir.x)-D3DX_PI/2);
//为树木矩阵乘以广告板矩阵
g_matTree=matBillBoard*g_matTree;
}
}
//-----------------------------------------------------------------------------
//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