游戏开发实验7.doc_第1页
游戏开发实验7.doc_第2页
游戏开发实验7.doc_第3页
游戏开发实验7.doc_第4页
游戏开发实验7.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验七:广告板技术一、实验目的掌握广告板技术的原理,熟悉广告板技术使用方法.二、实验仪器Visual Studio 2005三、实验原理及过程/网上检索广告板技术相关知识Billboard 理解与实现Billboard是一项使用非常普遍的技术,很多一些绚丽的特效可以使用它来实现,当然公告板、姓名板等是它较早的用途。Billboard 的主要思想是在 XY 平面上建立一个绘图区域,在此区域上渲染一张贴图的一个区域,并且此平面要一直面向摄像机。Billboard的主要实现:1.Billboard的绘制区域是建立在自身坐标系的XY平面上,绘制区域的正面朝向为自身坐标系的Z轴的方向。由于Billboard需要朝向摄像机,所以Billboard在构造渲染顶点数据的时候需要将原始的Billboard绘制区域的左右对调后再填充定点数据(即原来的区域left与 right)。2.Billboard朝向问题:Billboard需要一直朝向摄像机,即通过YawPicthroll(由于旋转是相对于Billboard自身坐标系,所以YawPicthroll分别对应YXZ)三次旋转后达到billboard永远朝向摄像机的目的。一般程序实现分两种,固定Yaw轴(Billboard的上方向不变)与不固定Yaw轴。固定Yaw轴的Billboard旋转的时候要使Yaw轴保持固定所以不能进行Picth和Roll旋转,只需要沿Yaw轴旋转。固定Yaw轴的Billboard需要三次旋转Billboard旋转D3D代码: /由于Billboard的旋转是按自身坐标系旋转,所以up/right/foward分别对应Y/X/Z轴 /首先得到billboard应该被设置成的朝向向量即摄像机的朝向向量的反方向 D3DXVECTOR3 lookAt(0.0f, 0.0f, 1.0f); lookAt = -pCam-GetDirection(); /再得到lookAt投影到XZ平面上的向量,用于计算Pitch值(相当于沿X方向旋转的角度) D3DXVECTOR3 adjustLookAt = lookAt; adjustLookAt.y = 0.0f; /必须要将向量变为单位向量 D3DXVec3Normalize(&lookAt, &lookAt); D3DXVec3Normalize(&adjustLookAt, &adjustLookAt); D3DXMATRIX rm_x;/沿X轴的旋转矩阵 D3DXMATRIX rm_z;/沿Y轴的旋转矩阵 D3DXMatrixIdentity(&rm_z); /如果摄像机的上方向的Y值小于0则需要将Billboard的up方向向反方向调换一下 if (pCam & pCam-GetUp().y 0.0f) D3DXMatrixRotationAxis(&rm_z, &D3DXVECTOR3(0.0f, 0.0f, 1.0f), D3DX_PI); /Billboard朝向与XZ平面的夹角 dot = D3DXVec3Dot(&adjustLookAt, &lookAt); /如果Billboard朝向是沿Y轴向下则绕X轴正向旋转,否则沿X轴反向旋转, /左手坐标系下的旋转符合左手定则,比划一下就能知道为什么 if (lookAt.y = 0) D3DXMatrixRotationAxis(&rm_x, &D3DXVECTOR3(1.0f, 0.0f, 0.0f), acos(dot); else D3DXMatrixRotationAxis(&rm_x, &D3DXVECTOR3(-1.0f, 0.0f, 0.0f), acos(dot); rm_x = rm_z * rm_x; D3DXMATRIX rm_y;/绕Y轴旋转的矩阵 /旋转的角度为Billboard朝向与Billboard原始朝向的夹角 dot = D3DXVec3Dot(&D3DXVECTOR3(0.0f, 0.0f, 1.0f), &adjustLookAt); /根据Billboard朝向方向是偏X轴的正方向还是反方向决定绕Y轴的正方向或反方向 /同样用左手比划一下就知道为什么 if (adjustLookAt.x SetTransform( D3DTS_VIEW, &matView );创建字体 V_RETURN( D3DXCreateFont( pd3dDevice, 15, 0, FW_BOLD, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, LArial, &g_pFont ) );创建地面纹理和树木纹理V_RETURN( D3DXCreateTextureFromFile( pd3dDevice, Lground.jpg, &g_pGroundTex );V_RETURN( D3DXCreateTextureFromFile( pd3dDevice, Ltree.dds, &g_pTreeTex );创建广告板矩形和纹理对象HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_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 );4、 实验结果Toggle REF选择: 改变设备:(转动速度变慢)使用广告板矩阵:五、实验心得本次实验与上次的实验步骤比较一致,主要难点也是在于读懂代码,理解代码的具体含义。一开始找不到相应的代码,后来由老师提供。但由于对广告板技术的不熟悉,对于一些函数还是不明白,只能先通过网络搜索广告版技术的相关知识,了解与之相关的一些函数及用法,之后慢慢开始尝试读相关代码,虽然能读懂一些,但也只是小部分,通过细节部分的检索和同学的指导,使得能够大部分读懂本次实验的代码。通过本次实验,基本掌握了广告板技术的原理,熟悉了广告板技术使用方法,了解了广告版技术实现的步骤,知道广告板与其依赖的广告板集内的各个广告板的尺寸材质等参数都需相等,进一步加深了对OGRE相关知识理解。在理论课的基础上,通过实践,不但巩固了上课所学的理论知识,也学到了一些上课所未详细讲的内容,但自身还有很多的不足,后期仍需要更加努力深入的学习游戏开发这门课程。六、主要代码BillBoard.cpp/=/ Desc: 主程序源代码/BillBoard.cpp/=#include dxstdafx.h#include resource.h/-/ 全局变量/-ID3DXFont* g_pFont = NULL; /ID3DXFont字体对象ID3DXSprite* g_pTextSprite = NULL; /ID3DXSprite文本精灵对象bool g_bShowHelp = true; /标识是否显示简单说明文本CDXUTDialogResourceManager g_DialogResourceManager; /对话框资源管理器CD3DSettingsDlg g_SettingsDlg; /Direct3D设备设置对话框CDXUTDialog g_HUD; /对话框CDXUTDialog g_SampleUI; /对话框LPDIRECT3DVERTEXBUFFER9 g_pGroundVB; /地面顶点缓冲区LPDIRECT3DVERTEXBUFFER9 g_pTreeVB; /树木顶点缓冲区LPDIRECT3DTEXTURE9 g_pGroundTex; /地面纹理LPDIRECT3DTEXTURE9 g_pTreeTex; /树木纹理D3DXMATRIX g_matGround; /地面世界矩阵D3DXMATRIX g_matTree; /树木世界矩阵bool g_bUseBillBoard = true; /标志是否使用广告板技术/-/ Desc: 定义广告板矩形顶点结构和顶点格式/-struct CUSTOMVERTEXfloat x, y, z; /顶点位置float u,v ; /顶点纹理坐标;#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_TEX1)/-/ 控件ID/-#define IDC_TOGGLEFULLSCREEN 1#define IDC_TOGGLEREF 2#define IDC_CHANGEDEVICE 3#define IDC_USEBILLBOARD 4/-/ Desc: 函数声明/-bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext );bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext );HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext );void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext );LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, bool* pbNoFurtherProcessing, void* pUserContext );void CALLBACK KeyboardProc( UINT nChar, bool bKeyDown, bool bAltDown, void* pUserContext );void CALLBACK OnGUIEvent( UINT nEvent, int nControlID, CDXUTControl* pControl, void* pUserContext );void CALLBACK OnLostDevice( void* pUserContext );void CALLBACK OnDestroyDevice( void* pUserContext );void InitApp();void RenderText();/-/ Desc: 入口函数/-INT WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) /为Debug配置启用运行时内存检查功能#if defined(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( LBillBoard );DXUTCreateDevice( D3DADAPTER_DEFAULT, true, 640, 480, IsDeviceAcceptable, ModifyDeviceSettings );/进入消息循环和场景渲染DXUTMainLoop();/在此进行应用程序相关的清除工作return DXUTGetExitCode();/-/ Desc: 应用程序相关初始化/-void InitApp() /初始化对话框 g_SettingsDlg.Init( &g_DialogResourceManager ); g_HUD.Init( &g_DialogResourceManager ); g_SampleUI.Init( &g_DialogResourceManager );/为g_HUD对话框设置消息处理函数,添加控件 g_HUD.SetCallback( OnGUIEvent ); int iY = 10; g_HUD.AddButton( IDC_TOGGLEFULLSCREEN, LToggle full screen, 35, iY, 125, 22 ); g_HUD.AddButton( IDC_TOGGLEREF, LToggle REF (F3), 35, iY += 24, 125, 22 ); g_HUD.AddButton( IDC_CHANGEDEVICE, LChange device (F2), 35, iY += 24, 125, 22, VK_F2 );g_HUD.AddCheckBox(IDC_USEBILLBOARD, L使用BillBoard矩阵, 40, iY += 32, 160, 24, g_bUseBillBoard );/-/ Desc: 设备能力检查/-bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )/检查后台缓冲区格式是否支持Alpha混合等操作(post pixel blending operations) IDirect3D9* pD3D = DXUTGetD3DObject(); if( FAILED( pD3D-CheckDeviceFormat( pCaps-AdapterOrdinal, pCaps-DeviceType, AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, D3DRTYPE_TEXTURE, BackBufferFormat ) ) ) return false; return true;/-/ Desc: 修改Direct3D渲染设备设置/-bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext ) /如果不支持硬件顶点处理则使用软件顶点处理 if( (pCaps-DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) = 0) pDeviceSettings-BehaviorFlags = D3DCREATE_SOFTWARE_VERTEXPROCESSING; /如果使用参考设备,则弹出警告对话框 static bool s_bFirstTime = true; if( s_bFirstTime ) s_bFirstTime = false; if( pDeviceSettings-DeviceType = D3DDEVTYPE_REF ) DXUTDisplaySwitchingToREFWarning(); return true;/-/ Desc: 在此创建管理内存资源对象,创建广告板矩形和纹理对象/-HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) HRESULT hr; 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, LArial, &g_pFont ) );/创建地面顶点缓冲区 V_RETURN( pd3dDevice-CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &g_pGroundVB, NULL ); CUSTOMVERTEX vertices1 = -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 ) ) ) return E_FAIL; memcpy( pVertices1, vertices1, sizeof(vertices1) );g_pGroundVB-Unlock();/创建树木顶点缓冲区 V_RETURN( pd3dDevice-CreateVertexBuffer( 4*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, &g_pTreeVB, NULL ); CUSTOMVERTEX vertices2 = -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 ) ) ) return E_FAIL; memcpy( pVertices2, vertices2, sizeof(vertices2) );g_pTreeVB-Unlock();/创建地面纹理和树木纹理V_RETURN( D3DXCreateTextureFromFile( pd3dDevice, Lground.jpg, &g_pGroundTex );V_RETURN( D3DXCreateTextureFromFile( pd3dDevice, Ltree.dds, &g_pTreeTex ); return S_OK;/-/ Desc: 在此创建默认内存类型资源对象,设置纹理操作启用alpha混合,alpha混合系数/-HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext ) HRESULT hr; 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);/设置投影矩阵D3DXMATRIXA16 matProj;float fAspectRatio = (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 ); return S_OK;/-/ Desc: 更新场景,根据观察方向,构造广告板矩阵,通过广告板矩阵旋转矩形对象,使其面向观察者/-void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )/设置观察矩阵static D3DXMATRIXA16 matView;float angle = (float)fTime/2.0f;D3DXVECTOR3 vEyePt( 8*sin(angle), 1.5f, 8*cos(angle) ); D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f ); D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f ); D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec ); pd3dDevice-SetTransform( D3DTS_VIEW, &matView );/初始化树木世界矩阵D3DXMatrixIdentity(&g_matTree);/使用广告板矩阵static D3DXMATRIX matBillBoard;if(g_bUseBillBoard = true)/根据当前观察方向构造广告板矩阵D3DXVECTOR3 vDir = vLookatPt - vEyePt;if( vDir.x 0.0f )D3DXMatrixRotationY( &matBillBoard, -atanf(vDir.z/vDir.x)+D3DX_PI/2 );elseD3DXMatrixRotationY( &matBillBoard, -atanf(vDir.z/vDir.x)-D3DX_PI/2 );/为树木矩阵乘以广告板矩阵g_matTree = matBillBoard*g_matTree;/-/ Desc: 渲染场景/-void CALLBACK OnFrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext ) HRESULT hr;/如果正在利用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-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 );/渲

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论