基于OpenGL的三维场景多视角实时漫游与观察

更新时间:2023-04-13 11:56:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

Computer Era No.112008

0引言

三维场景的实时观察与漫游技术广泛应用于三维游戏、虚拟现实、科学计算可视化等领域。用户通过键盘和鼠标操作摄影机,可对场景进行实时漫游,或者对对象进行多角度细致入微的观察,似乎有一种身临其境的感觉。OpenGL 是目前国际上公认的3D 图形工业标准,在Unix 与PC 平台上得到广泛的应用,并占据了领导地位。但是OpenGL 无窗口系统,包括场景观察在内的API 都是低级的C 函数,缺乏交互功能[1]。鉴于这种情况,本文在VC 环境下,采用面向对象技术,建立了一个摄影机类CCamera ,以响应键盘和鼠标消息实现三维场景的多视角实时观察与漫游。在CCamera 中通过OpenGL 提供的矩阵堆栈,实现视角的变换,在简化计算的同时,提高了程序的运行效率。

1Camera 类的定义

Camera 类变量和主要函数定义如下:

CCamera {public:

CVector3m_vPosition;//视点位置CVector3m_vView;//观察点位置

CVector3m_vUpVector;//摄影机向上方位向量Cvector3m_vStrafe;//摄影机侧向向量float m_fSpeed;//摄影机步速大小//下列变量用作第三人称视角

float m_fElevation;//摄影机的仰角(YZ 平面),范围0-180float m_fAzimuth;//摄影机的方位角

(XZ 平面),范围0-360float m_fDistance;//视点到观察点距离void SetViewByKeyDown();

//第一人称视角时,通过键盘平移摄像机void SetViewByMouseMove(UINT nFlags);//通过鼠标旋转摄像机private:

void RotateView(float a,CVector3vAxis);//将视线绕vAxis 旋转a 角度

void Vector3DRotateMatrix(float a,CVector3vAxis,GLmatrix16f M);

}

2景中人视角下的场景观察

2.1全局固定坐标系下的场景观察

全局固定坐标系下对场景的观察,主要通过改变摄影机空间位置及参数,然后用OpenGL 的gluLookAt 函数实现[2]。摄影机控制包括平移和旋转。例如,以视点为中心通过鼠标旋转摄影机的代码如下:

void CCamera::SetViewByMouseMove (UINT nFlags){RECT rect;

POINT mousePos;//存放鼠标移动过程中的坐标GetWindowRect(m_hWnd,&rect);int middleX=(rect.right+rect.left)>>1;int middleY=(rect.top+rect.bottom)>>1;

GetCursorPos(&mousePos);//得到鼠标当前的x,y 坐标if((mousePos.x==middleX)&&(mousePos.y==middleY))return;SetCursorPos(middleX,middleY);//将鼠标位置置窗口中央float angleY=(float)((middleX-mousePos.x));//方位角float angleZ=(float)((middleY-mousePos.y));//仰角RotateView(angleZ,m_vStrafe);//以vStrafe 为轴旋转RotateView(angleY,CVector3(0.0,1.0,0.0));//绕y 轴旋转}

typedef float GLmatrix16f[16];

void CCamera::RotateView(float a,CVector3vAxis){GLmatrix16f MR;

Vector3DRotateMatrix(a,vAxis,MR);CVector3vD=m_vView-m_vPosition;

CVector3vVector=Transform(MR,vD);//将vD 转换为齐次向量后乘矩阵MR ,并将结果转换成3维向量

m_vView=vPosition+vVector;

m_vUpVector=Normalize(Cross(m_vStrafe,vDirection));

}

我们用OpenGL 提供的矩阵堆栈获得绕某向量旋转的旋转矩阵M ,代码如下:

void CCamera::Vector3DRotateMatrix(float a,CVector3vAxis,GLmatrix16f M){glPushMatrix();glLoadIdentity();

基于OpenGL 的三维场景多视角实时漫游与观察

傅由甲

(重庆工学院计算机科学与工程学院,重庆400050)

要:主要介绍三维场景中景内和景外摄影机控制的原理和实现方法。该方法克服了OpenGL 场景观察缺乏交互功能的缺点,在VC 环境下采用面向对象技术,建立一个摄影机类,通过键盘和鼠标进行三维场景的多视角实时观察和漫游。在摄影机类的实现中通过OpenGL 提供的矩阵堆栈,直接获得变换矩阵,避免了大量矩阵运算代码的编写,并在简化计算的同时,提高了程序的运行效率。

关键词:OpenGL ;摄影机控制;三维场景漫游;三维场景观察

60··

计算机时代2008年第11期

glRotatef(a,vAxis.x,vAxis.y,vAxis.z);glGetFloatv(GL_MODELVIEW_MATRIX,M);glPopMatrix();}

2.2移动局部坐标系下的场景观察[3]

这种方法多用于建模软件中,其主要原理是假想一个与所绘制场景固定在一起的可移动的局部坐标系,所有变换操作都相对该局部坐标系进行,由于绘制场景相对局部坐标系固定,所以通过平移和旋转局部坐标系,可以很方便地实现对场景全方位的观察。

以场景中点C(x,y,z)为观察点,用OpenGL 实现任意角度观察,其代码如下:

glPushMatrix();glLoadIdentity();glTranslatef(x,y,z);

//局部坐标系平移到C 点

(1)glRotatef(angleY,0.0,1.0,0.0);

//局部坐标系绕(0.0,1.0,0.0)轴旋转的角度(2)glRotatef(angleX,1.0,0.0,0.0);

//局部坐标系绕(1.0,0.0,0.0)轴旋转的角度(3)glRotatef(angleZ,0.0,0.0,1.0);

//局部坐标系绕(0.0,0.0,1.0)轴旋转的角度(4)glTranslatef(-x,-y,-z);//局部坐标系平移到原位置(5)

draw_the_scene();//绘制场景

glPopMatrix();

2.3全局固定坐标系与移动局部坐标系的转换

场景位于局部坐标系中,而摄影机处于全局固定坐标系中,在一些需要判定摄影机和场景相互位置关系的计算中,如视体裁剪、摄影机碰撞检测等,必须将两者统一到同一个坐标系下。为便于计算,我们将摄影机的全局坐标转换到场景的局部坐标系中。

设步骤⑴~⑸的4×4齐次变换矩阵为M4,摄影机在移动局部坐标系中的齐次坐标为vPosition',vView',vUp',则:

vPosition'=M 4-1

×CVector4

(m_vPosition.x,m_vPosition.y,m_vPosition.z,1)

vView'=M 4-1

×CVector4

(m_vView.x,m_vView.y,m_vView.z,1)vUp'=M 4-1

×CVector4

(m_vUp.x,m_vUp.y,m_vUp.z,1)3景外人视角下的场景观察

景外人视角包括观察对象(或跟踪对象)和摄影机两部分组成。在这种视角下需要得到摄影机绕观察对象进行多角度观察的效果,常采用极坐标来描述摄影机位置和方向。其位置关系如图1所示,用三个参数描述,分别为摄影机与观察点O 的距离d ,摄影机绕观察对象的局部坐标Y 轴的方位角α,以及与Y 轴的夹角β

(仰角)[4]。设与观察对象固定的局部坐标系三个轴向量为!X ,!Y ,!

Z ,则摄影机采用如下步骤定位:

⑴将!Z 绕!Y

旋转α角度得到向量!

Z α;⑵计算β的转轴:!Y β=!Y ×!Z α

;⑶将!Y 绕!Y β

旋转β角度并单位化得到摄影机视线方向!V ;

⑷计算m_vUp=!V ×!Y β;

⑸m_vView=O ,m_vPosition=O+!V ·d

从上面可知,只要d ,α,β保持不变,无论观察对象怎样运动,摄影机和观察对象间的相对位置将不变,从而实现对观察对象的跟踪;反之,通过调整以上参数,可以实现摄影机对对象任意角度的观察。

图1角色与其摄影机的位置关系

4结束语

本文就OpenGL 下如何使用面向对象技术实现摄影机的多角度实时观察与漫游进行了探讨,给出了景中人视角摄影机控制的关键代码,并论述了景外人视角摄影机控制的原理,比较好地解决了OpenGL 低级API 场景观察缺乏交互功能的缺点。由于对摄像机进行了封装,相关代码也便于其移植和重用。图2是本文摄影机在作者参与的多个项目中的应用,其中(a)为景中人视角下对三维场景的漫游镜头;(b)为景外人视角下对三维重建的数字猪进行全方位的观察镜头。

(a)景中人漫游

(b)景外人观察

图2摄影机漫游与观察实例

参考文献:

[1]王玉华,杨克俭,曾梅兰.面向对象技术在三维虚拟场景建模中的应

用研究[J].武汉理工大学学报(交通科学与工程版),2003.27(1):37~40

[2]Edward Angel.Interactive Computer Graphics:A Top-Down

Approach with OpenGL,3e[M].Person Eduction,Inc.247~248[3]Dave Shreiner,Mason Woo,Jackie Neider 等.OpenGL 编程指南

(原书第5版)[M].机械工业出版社,2006.

[4]傅由甲.基于物理、特征行为仿真的三维空间碰撞检测及响应研究[D].

武汉理工大学,2005.

C E 61··

本文来源:https://www.bwwdw.com/article/hu3l.html

Top