
游戏开发实验7.doc
14页实验七:广告板技术一、实验目的掌握广告板技术的原理,熟悉广告板技术使用方法.二、实验仪器Visual Studio 2005三、实验原理及过程//网上检索广告板技术相关知识Billboard 理解与实现Billboard是一项使用非常普遍的技术,很多一些绚丽的特效可以使用它来实现,当然公告板、姓名板等是它较早的用途Billboard 的主要思想是在 XY 平面上建立一个绘图区域,在此区域上渲染一张贴图的一个区域,并且此平面要一直面向摄像机Billboard的主要实现:1.Billboard的绘制区域是建立在自身坐标系的XY平面上,绘制区域的正面朝向为自身坐标系的Z轴的方向由于Billboard需要朝向摄像机,所以Billboard在构造渲染顶点数据的时候需要将原始的Billboard绘制区域的左右对调后再填充定点数据(即原来的区域left与 right)2.Billboard朝向问题:Billboard需要一直朝向摄像机,即通过Yaw\Picth\roll(由于旋转是相对于Billboard自身坐标系,所以Yaw\Picth\roll分别对应Y\X\Z)三次旋转后达到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 <= 0) D3DXMatrixRotationAxis(&rm_y, &D3DXVECTOR3(0.0f, -1.0f, 0.0f), acos(dot)); else D3DXMatrixRotationAxis(&rm_y, &D3DXVECTOR3(0.0f, 1.0f, 0.0f), acos(dot));3.Billboard渲染时需要根据使用情况决定是否需要开启灯光渲染。
Billboard的实现步骤:一:定义广告版矩形顶点结构和顶点格式二:创建广告版矩形和纹理对象三: 接下来就是设置一些Alpha混合系数四: 根据观察的方向来广告版矩阵,通过旋转矩阵对象使它面向观察者//利用广告板技术实现一个某种特效,如树木,并描述程序实现时的思路包括对每个调用的API以及脚本进行详细说明设置观察矩阵 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 );创建字体 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"ground.jpg", &g_pGroundTex )); V_RETURN( D3DXCreateTextureFromFile( pd3dDevice, L"tree.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 );四、 实验结果Toggle REF选择: 改变设备:(转动速度变慢)使用广告板矩阵:五、实验心得本次实验与上次的实验步骤比较一致,主要难点也是在于读懂代码,理解代码的具体含义。
一开始找不到相应的代码,后来由老师提供但由于对广告板技术的不熟悉,对于一些函数还是不明白,只能先通过网络搜索广告版技术的相关知识,了解与之相关的一些函数及用法,之后慢慢开始尝试读相关代码,虽然能读懂一些,但也只是小部分,通过细节部分的检索和同学的指导,使得能够大部分读懂本次实验的代码通过本次实验,基本掌握了广告板技术的原理,熟悉了广告板技术使用方法,了解了广告版技术实现的步骤,知道广告板与其依赖的广告板集内的各个广告板的尺寸材质等参数都需相等,进一步加深了对OGRE相关知识理解在理论课的基础上,通过实践,不但巩固了上课所学的理论知识,也学到了一些上课所未详细讲的内容,但自身还有很多的不足,后期仍需要更加努力深入的学习游戏开发这门课程六、主要代码BillBoard.cpp//=============================================================================// Desc: 主程序源代码//BillBoard.cpp//=============================================================================#include "dxstdafx.h"#include "resource.h"//-----------------------------------------------------------------------------// 全局变量//-----------------------------------------------------------------------------ID3DXFont* g_pFont = NULL; //ID3DXFont字体对象ID3DXSprite* g_pTextSprite = NULL; //ID3DXSprite文本。












