基于OpenGL的虚拟漫游技术研究(1)
- 格式:pdf
- 大小:430.67 KB
- 文档页数:3
基于WebGL的虚拟场景漫游系统设计与实现随着计算机技术的不断发展,虚拟现实技术已经在很多领域得到应用,例如游戏、教育、医疗等。
其中,虚拟场景漫游系统是比较受欢迎的一种应用。
本文将介绍一种基于WebGL的虚拟场景漫游系统的设计与实现。
一、WebGL的基本概念WebGL是一种在浏览器中实现3D图形的技术。
它可以让开发者使用JavaScript语言来创建复杂的3D图形,实现虚拟现实等应用。
WebGL的核心技术是OpenGL,它是一种跨平台的3D图形API。
WebGL利用JavaScript代码与OpenGL交互,可以在浏览器中实现3D图形渲染。
二、虚拟场景漫游系统的设计思路虚拟场景漫游系统的实现主要分为三个部分:场景设计、场景渲染和用户交互。
1. 场景设计场景设计是虚拟场景漫游系统的基础,它需要实现以下功能:(1)场景建模:使用3D建模软件(例如Blender、Maya等)进行场景建模,将场景中的物体建模成3D模型。
(2)场景导入:将3D模型导入到WebGL中,通过JavaScript 控制场景中的模型运动和交互。
(3)贴图处理:将场景中的贴图进行处理,使得在WebGL中呈现质量较高的视觉效果。
2. 场景渲染场景渲染是虚拟场景漫游系统的核心,它需要实现以下功能:(1)渲染引擎:使用WebGL的渲染引擎,将场景中的3D模型渲染成2D图像。
(2)光照处理:通过光照处理,使得场景中的物体呈现逼真的光影效果。
(3)特效处理:为场景添加特效(如雾化、镜面反射等),增强场景的视觉效果。
3. 用户交互用户交互是虚拟场景漫游系统的重要部分,它需要实现以下功能:(1)摄像头控制:通过键盘或鼠标控制摄像头的位置和方向,实现场景的漫游。
(2)交互元素:在场景中添加交互元素,例如按钮、触发器等,实现特定功能(如打开门、触发动画等)。
(3)界面设计:为用户提供一个友好的交互界面,让用户能够方便地控制场景。
三、系统实现本文采用THREE.js作为WebGL框架,实现了一个简单的虚拟场景漫游系统。
基于OpenG L技术的实时漫游系统研究及实现僧德文1,2,王红霞1(1.浙江水利水电专科学校,浙江杭州 310018;2.北京科技大学土木与环境工程学院,北京 100083)摘 要:结合水利行业的需求和当前可行的技术,讨论了基于桌面系统及通用平台开发实时漫游系统的技术关键和难点,给出了模型建立、转换及调用方法,并利用OpenG L技术基于Visual C++6.0集成开发环境开发了一个实用的实时漫游系统.关键词:水利工程;漫游;数据模型;开放的图形程序接口中图分类号:TP391 文献标识码:A 文章编号:1008-536X(2007)022*******Study and Implementation of Real T ime Navigation System Ba sed on Open G LS ENG De2wen1,2,WANG Hong2xia1(1.Zhejiang Water C onservancy and Hydropower C ollege,Hangzhou310018,China;2.Civil and Environmental Engineering School,Beijing University of Science and T echnology,Beijing100083,China)Abstract:C ombined with the needs of water conservancy and feasible technology,this paper discusses the techniques and the difficulties in the development of a real time desktop navigation system based on comm on developing platform.The methods of construction,transi2 tion and usage of the visualized3D m odels are provided.A practical system is implemented by OpenG L on the Visual C++6.0inte2 grated development environment.K ey w ords:water conservancy w orks;navigation;data m odel;OpenG L0 引 言现实世界是在三维空间延伸的,过去人们由于受认知能力、技术手段和硬件水平的限制,对现实世界的仿真基本上是二维形式.然而,二维仿真是一种抽象和简化,很多情况下不能有效地表达现实世界中的物体和现象,在某种程度上给人们的思维带来了一定的局限.近年来,可视化仿真技术的发展和硬件能力的提高,为人们更好地模拟和描述现实世界提供了方便[1].OpenG L是SGI公司开发的一套高性能图形处理系统,它以高性能的交互式三维图形建模能力和易于编程开发,得到了Micros oft、I BM、DEC、S UN、HP等大公司的认同.目前它已经成为开放的国际图形标准[2].本研究结合水利工程特点,探讨基于PC机平台,在Visu2收稿日期:2006212205基金项目:浙江省教育厅科研立项项目(21205);浙江省水利厅科技项目(RC0605);浙江省高校青年教师资助计划项目(21223);浙江省教育厅科研立项项目(20060001)作者简介:僧德文(1977-),男,福建漳州人,博士/博士后研究人员,主要研究方向为地学可视化、系统建模与仿真.al C++6.0集成开发环境下利用OpenG L技术开发三维实时漫游系统的实现方法.1 三维仿真场景的构造场景(Scene)是系统所有可视化对象的集合.一般来讲这些对象的形状可以通过点、线、面(多边形)进行拟合,对象的真实感则通过对三维物体进行裁剪、反走样、消隐并赋予阴影、光照、纹理和材质等属性来表现.三维空间虚拟场景的构造一般要经过以下步骤[3]:(1)几何构模 就是对整个场景模型进行几何重建,主要运用数学方法建立所需场景的几何描述,并将它们输入计算机.这部分工作可由三维立体造型或曲面造型系统来完成.(2)物理构模 所谓物理构模就是进行颜色、光照、材质和纹理等的处理,最终将几何图素及其视觉特征转换为可供显示的图形或图像.(3)场景设置 在对三维场景进行渲染前,需要设置相关的场景参数值.这些参数一般包括光源性质(镜射光、漫射光和环境光)、光源方位(距离和方向)、明暗处理方式(平滑处理或平面处理)、纹理映射方式 第19卷 第2期浙江水利水电专科学校学报V ol.19 N o.2 2007年6月J.Zhejiang Wat.C ons&Hydr.C ollege Jun.2007等.除此之外还需设定视点位置和视线方向.(4)模型渲染 主要通过投影变换将三维空间场景转换为二维计算机屏幕上的图像.虚拟场景中一般都采用透视投影,以更好地模拟真实世界的情况.2 虚拟漫游系统框架通过可视化技术构造出三维虚拟场景后,系统必须提供一定的人机交互功能,使用户能够更好的理解和认识场景中的对象以及对象间的关系.在所有人机交互手段中,交互式漫游是最重要的一种虚拟观测手段[4].本研究设计了的虚拟漫游系统框架(见图1).图1 三维场景虚拟漫游系统框架整个系统由用户的交互输入控制场景的绘制与显示.用户的输入主要指键盘、鼠标等输入设备的输入,经输入解释后将变成一系列的控制命令,进行场景数据的管理、几何模型的加载、物体光照、材质属性、不透明度以及视点方向、位置的设置等.之后,模型渲染模块能够根据用户的输入进行场景的实时绘制与动态显示.在这个过程中,还能够根据视点与物体之间的距离进行碰撞检测.3 漫游功能的实现三维场景漫游中,观察者可以通过鼠标或键盘来控制视点的位置、视向和参考方向.当视点的位置、视向和参考方向发生改变时,场景中的物体相对于观察者的方位也发生了改变,从而产生了“动感”.系统中,视点即为人眼的“化身”,其功能与现实世界的照相机类似,视线方向可由参考点位置确定(参考点位置减去视点位置即可得到视线方向的向量).漫游过程的实质就是通过不断移动视点或改变视线方向而产生三维动画的过程.3.1 键盘漫游命令的处理键盘漫游就是通过操纵键盘实现用户在三维场景中的任意漫游.通过键盘漫游用户可以灵活、准确地对场景进行全方位的观察.键盘漫游的过程就是一个根据键盘命令连续不断地改变视点位置或视线方向并渲染场景的过程.通常,键盘漫游命令包括左转、右转、前进、后退、上升、下降、仰视、俯视、左移、右移等.本系统中使用的是Z 轴朝上的左手坐标系,Z 值代表场景的高度,响应左转、右转、仰视、俯视命令时视点均保持不变,只改变视线方向.对左转、右转视线分别绕Z 轴逆、顺时针旋转一定角度,对仰视、俯视则增、减视线与XY 平面的夹角(仰角);前进、后退时将视点分别沿视线方向、视线反方向移动一定距离(视行进速度而定);上升、下降时则只增、减视点高度值(Z 坐标值);左移、右移时只将视点进行平移,视线方向则保持不变.按照这种响应方法,通过空间向量分解运算,即可计算出新的视点和参考点坐标.例如当响应前进(后退)命令时视点与参考点坐标的计算公式为:(1)视点坐标(speed 表示行进速度,anglez 表示视线绕Z 轴旋转的角度)vEyePt.x =vEyePt.x +(-)speed ×sin (anglez );vEyePt.y =vEyePt.y +(-)speed ×cos (anglez );vEyePt.z =vEyePt.z ;(2)参考点坐标(updown -angle 表示视线与XY 平面的夹角即仰角)v LookPt.x =vEyePt.x +150×sin (anglez );v LookPt.y =vEyePt.y +150×cos (anglez );v LookPt.z =vEyePt.z +150×sin (updown -angle );上式中常数150是为了使视点和参考点之间保持一定距离而设置的.3.2 记录漫游路径通过键盘操作实现对三维场景实时漫游虽然灵活、方便,但用户不断地按下键盘显得有些烦琐.特别是当需要重复前一漫游过程时更是如此.为此,系统可设计一种对键盘漫游过程进行记录的功能(记录漫游路径).所记录的键盘漫游过程称为历史记录,通过重新播放历史记录便可实现对键盘漫游过程的再现[5].记录键盘漫游过程的处理如下:首先记录下初始的视点、观察点、视线绕Z 轴旋转的角度、仰角等,然后对每种连续的键盘操作命令按“动作类型,执行次数”的格式进行记录,其中动作类型为上述的10种键盘漫游命令之一,目的就是将键盘漫游的整个过程解释为漫游命令序列.最后以一个相反的过程播放历史记录,即从文件中读取上述初始化参数并按照这些参 64 浙江水利水电专科学校学报第19卷数对系统进行设置,而后读取键盘操作命令的序列并调用相应的命令处理函数进行处理.4 系统优化要达到真实模拟环境系统,对各类复杂的自然以及人造工程的真实模拟,需要借助于计算机真实感图形绘制技术才能完成,主要包括反走样、消隐、光照、阴影、材质纹理、融合、雾化等技术.图形真实感绘制直接影响到场景的真实性及其可视化效果,然而,真实感与实时性是相互对立的两个问题,很多情况下要在两者之间取得一个平衡[5].本系统的优化着重于降低场景的复杂度在编程时采取了以下措施:(1)对象的重复引用 场景中经常需要多个相同的虚拟物体,如相同的树木等,对于这类需重复出现的物体,采用了重复引用的方法,再通过几何变换得到其他位置的物体,该方法大大节省了内存,提高了动态显示的速度.(2)可见消隐 由于屏幕只显示观察者的视野,即使系统的整个仿真场景都被绘制,落在观察者视野之外的物体也是不可见的.因此,只要绘制观察者当前所能看见的场景便能达到要求.当观察者仅能看到场景的很少一部分时,由于系统只显示相应部分的场景,从而大大减少了所需显示的物体的数目.5 结 论作者在最近开发的水利工程三维可视化仿真系统中,运用前面介绍的方法方便而高效地实现了水利工程三维场景的交互虚拟漫游.系统漫游速度快、画面流畅、真实感强,实践效果良好.图2体现了用户在交互漫游过程中,从不同视点位置和视线方向观察的仿真场景三维效果.进一步的研究工作正在进行之中,目标是将各种人造工程实体集成显示到仿真场景中,并提供其它方式的交互漫游功能.图2 三维仿真场景虚拟漫游系统参考文献:[1] 汪成为,高 文,王行仁.灵境(虚拟现实)技术的理论、实现及应用[M].北京:清华大学出版社,1997.[2] 僧德文,李仲学,李春民.基于OpenG L 的真实感图形绘制技术研究与实现[J ].计算机应用研究,2005,22(3):173-175.[3] 僧德文,李仲学,李春民,等.地矿三维场景虚拟漫游技术及其应用[J ].东北大学学报,2004,25(S2):35-37.[4] 尚建嘎,刘修国,郑 坤.三维场景交互漫游的研究与实现[J ].计算机工程,2003,29(2):61-63.[5] 彭群生,鲍虎军,金小刚.计算机真实感图形的算法基础[M].北京:科学出版社,1999. 第2期僧德文等.基于OpenG L 技术的实时漫游系统研究及实现65 。
主要参考了NEHE的Opengl教程所有物体都是直接用代码画的,没有经过建模。
主要部分有详细注释。
适合刚接触图形学或OpenGL的新手。
老鸟勿来。
部分效果图:全部代码,VC6.0环境:/*主要实现简单的3D空间搭建,添加物体旋转效果,光照,纹理映射,3D漫游,雾化效果*/#include <windows.h>// Header File For Windows#include <math.h>// Math Library Header File#include <stdio.h>// Header File For Standard Input/Output#include <gl\gl.h>// Header File For The OpenGL32 Library#include <gl\glu.h>// Header File For The GLu32 Library#include <gl\glaux.h>// Header File For The Glaux LibraryHDC hDC=NULL;// Private GDI Device ContextHGLRC hRC=NULL;// Permanent Rendering ContextHWND hWnd=NULL;// Holds Our Window HandleHINSTANCE hInstance;// Holds The Instance Of The Applicationbool keys[256];// Array Used For The Keyboard Routinebool active=TRUE;// Window Active Flag Set To TRUE By Defaultbool fullscreen=TRUE;// Fullscreen Flag Set To Fullscreen Mode By Defaultbool blend;// Blending ON/OFFbool bp;// B Pressed?bool fp;// F Pressed?bool gp;// G Pressed?bool light;bool lp;GLuint fogMode[]= { GL_EXP, GL_EXP2, GL_LINEAR };// 雾气的三种模式GLuint fogfilter = 0;// Which Fog Mode To UseGLfloat fogColor[4] = {0.5f,0.5f,0.5f,1.0f};// Fog ColorGLfloat walkbias = 0;GLfloat walkbiasangle = 0;GLfloat lookupdown = 0.0f;float x;float z;GLfloat eye[]={0.0f,0.0f,0.0f};GLfloat lookat[]={0.0f,0.0f,0.0f};GLfloat angle=-90.0;GLfloat speed=0.5;float PI=3.14159f;GLuint filter;// Which Filter To UseGLuint texture[7];// 储存7个纹理LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);// Declaration For WndProcAUX_RGBImageRec *LoadBMP(char *Filename) // 加载一个位图{FILE *File=NULL; // File Handleif (!Filename) // Make Sure A Filename Was Given{return NULL; // If Not Return NULL }File=fopen(Filename,"r"); // Check To See If The File Existsif (File) // Does The File Exist?{fclose(File); // Close The Handlereturn auxDIBImageLoad(Filename); // Load The Bitmap And Return A Pointer}return NULL; // If Load Failed Return NULL }int LoadGLTextures() // 加载位图并将其转化为纹理{int Status=FALSE; // Status IndicatorAUX_RGBImageRec *TextureImage[1]; // Create Storage Space For The Texturememset(TextureImage,0,sizeof(void *)*1); // Set The Pointer To NULLif (TextureImage[0]=LoadBMP("Data/zhou.bmp")) //指定风扇轴的纹理{Status=TRUE; // Set The Status To TRUEglGenTextures(1, &texture[0]);glBindTexture(GL_TEXTURE_2D,texture[0]);glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,0,GL_RGB,GL_ UNSIGNED_BYTE,TextureImage[0]->data);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);}if(TextureImage[0]=LoadBMP("Data/yepian.bmp")) //指定风扇叶的纹理{Status=TRUE;glGenTextures(1,&texture[1]);glBindTexture(GL_TEXTURE_2D,texture[1]);glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,0,GL_RGB,GL_ UNSIGNED_BYTE,TextureImage[0]->data);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);}if(TextureImage[0]=LoadBMP("Data/qiang.bmp")) //指定左右墙壁的纹理{Status=TRUE;glGenTextures(1,&texture[2]);glBindTexture(GL_TEXTURE_2D,texture[2]);glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,0,GL_RGB,GL_ UNSIGNED_BYTE,TextureImage[0]->data);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);}if(TextureImage[0]=LoadBMP("Data/diban.bmp")) //指定地板的纹理{Status=TRUE;glGenTextures(1,&texture[3]);glBindTexture(GL_TEXTURE_2D,texture[3]);glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,0,GL_RGB,GL_ UNSIGNED_BYTE,TextureImage[0]->data);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);}if(TextureImage[0]=LoadBMP("Data/tianhuaban.bmp")) //指定天花板的纹理{Status=TRUE;glGenTextures(1,&texture[4]);glBindTexture(GL_TEXTURE_2D,texture[4]);glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,0,GL_RGB,GL_ UNSIGNED_BYTE,TextureImage[0]->data);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);}if(TextureImage[0]=LoadBMP("Data/qiang2.bmp")) //指定对面墙的纹理{Status=TRUE;glGenTextures(1,&texture[5]);glBindTexture(GL_TEXTURE_2D,texture[5]);glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,0,GL_RGB,GL_ UNSIGNED_BYTE,TextureImage[0]->data);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);}if(TextureImage[0]=LoadBMP("Data/shafa.bmp")) //指定沙发的纹理{Status=TRUE;glGenTextures(1,&texture[6]);glBindTexture(GL_TEXTURE_2D,texture[6]);glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,0,GL_RGB,GL_ UNSIGNED_BYTE,TextureImage[0]->data);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);}if (TextureImage[0]) // If Texture Exists{if (TextureImage[0]->data) // If Texture Image Exists{free(TextureImage[0]->data); // Free The Texture Image Memory}free(TextureImage[0]); // Free The Image Structure }return Status; // Return The Status}GLvoid ReSizeGLScene(GLsizei width, GLsizei height)// Resize And Initialize The GLWindow{if (height==0)// Prevent A Divide By Zero By {height=1;// Making Height Equal One }glViewport(0,0,width,height);// Reset The Current ViewportglMatrixMode(GL_PROJECTION);// Select The Projection Matrix glLoadIdentity();// Reset The Projection Matrix// Calculate The Aspect Ratio Of The WindowgluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,120.0f);glMatrixMode(GL_MODELVIEW);// Select The Modelview MatrixglLoadIdentity();// Reset The Modelview Matrix }//设置0—6号光源位置GLfloat sun_light_position0[] = {0.0f, -5.0f, 2.0f, 1.0f};GLfloat sun_light_position1[] = {0.0f, 7.0f, 2.0f, 1.0f};GLfloat sun_light_position2[] = {-10.0f, -5.0f, -30.0f, 1.0f};GLfloat sun_light_position3[] = {10.0f, 7.0f, -30.0f, 1.0f};GLfloat sun_light_position4[] = {10.0f, 5.0f, -50.0f, 1.0f};GLfloat sun_light_position5[] = {-10.0f, -5.0f, -50.0f, 1.0f};GLfloat sun_light_ambient[] = {0.5f, 0.5f, 0.5f, 1.0f}; //环境光GLfloat sun_light_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; //漫射光GLfloat sun_light_specular[] = {1.0f, 1.0f, 1.0f, 1.0f}; //反射光int InitGL(GLvoid)// 开始对OpenGL进行所有的设置{if (!LoadGLTextures())// Jump To Texture Loading Routine{return FALSE;// If Texture Didn't Load Return FALSE}glEnable(GL_TEXTURE_2D);// 开启纹理映射glBlendFunc(GL_SRC_ALPHA,GL_ONE);// Set The Blending Function For TranslucencyglClearColor(0.0f, 0.0f, 0.0f, 0.0f);// 清理背景颜色为黑色glClearDepth(1.0);// 开启清理深度缓存glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); //透视修正glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position0); //0号光源glLightfv(GL_LIGHT0, GL_AMBIENT, sun_light_ambient);glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse);glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);glLightfv(GL_LIGHT1, GL_POSITION, sun_light_position1); //1号光源glLightfv(GL_LIGHT1, GL_AMBIENT, sun_light_ambient);glLightfv(GL_LIGHT1, GL_DIFFUSE, sun_light_diffuse);glLightfv(GL_LIGHT1, GL_SPECULAR, sun_light_specular);glLightfv(GL_LIGHT2, GL_POSITION, sun_light_position2); //2号光源glLightfv(GL_LIGHT2, GL_AMBIENT, sun_light_ambient);glLightfv(GL_LIGHT2, GL_DIFFUSE, sun_light_diffuse);glLightfv(GL_LIGHT2, GL_SPECULAR, sun_light_specular);glLightfv(GL_LIGHT3, GL_POSITION, sun_light_position3); //3号光源glLightfv(GL_LIGHT3, GL_AMBIENT, sun_light_ambient);glLightfv(GL_LIGHT3, GL_DIFFUSE, sun_light_diffuse);glLightfv(GL_LIGHT3, GL_SPECULAR, sun_light_specular);glLightfv(GL_LIGHT4, GL_POSITION, sun_light_position4); //4号光源glLightfv(GL_LIGHT4, GL_AMBIENT, sun_light_ambient);glLightfv(GL_LIGHT4, GL_DIFFUSE, sun_light_diffuse);glLightfv(GL_LIGHT4, GL_SPECULAR, sun_light_specular);glLightfv(GL_LIGHT5, GL_POSITION, sun_light_position5); //5号光源glLightfv(GL_LIGHT5, GL_AMBIENT, sun_light_ambient);glLightfv(GL_LIGHT5, GL_DIFFUSE, sun_light_diffuse);glLightfv(GL_LIGHT5, GL_SPECULAR, sun_light_specular);glEnable(GL_LIGHTING); //启用光源glEnable(GL_LIGHT0); //启用0号光源glEnable(GL_LIGHT1); //启用1号光源glEnable(GL_LIGHT2);glEnable(GL_LIGHT3);glEnable(GL_LIGHT4);glEnable(GL_LIGHT5);glFogi(GL_FOG_MODE, fogMode[fogfilter]);// Fog ModeglFogfv(GL_FOG_COLOR, fogColor);// Set Fog ColorglFogf(GL_FOG_DENSITY, 0.1f);// 雾气的浓度glHint(GL_FOG_HINT, GL_DONT_CARE);// 系统如何计算雾气glFogf(GL_FOG_START, -10.0f);// 雾气的开始位置glFogf(GL_FOG_END, -58.0f);// 雾气的结束位置glEnable(GL_FOG);return TRUE;// Initialization Went OK}void DrawGLfengshanzhou() //画一个四边形作为风扇轴{glBindTexture(GL_TEXTURE_2D, texture[0]); //绑定0号纹理,即风扇轴的纹理glBegin(GL_QUADS); //画四边形glNormal3f( 0.0f, 0.0f, 1.0f); //设置法向量glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.1f, -2.5f, 0.0f); //纹理和四边形左下坐标glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.1f, -2.5f, 0.0f); //纹理和四边形右下坐标glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.1f, 2.5f, 0.0f); //纹理和四边形右上坐标glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.1f, 2.5f, 0.0f); //纹理和四边形左上坐标glEnd();}void DrawGLfengshanye() //画一个四边形作为风扇叶片{glBindTexture(GL_TEXTURE_2D, texture[1]); //绑定1号纹理,即叶片的纹理glBegin(GL_QUADS);glNormal3f(0.0f,1.0f,0.0f);glTexCoord2f(0.0f, 0.0f);glVertex3f( 4.0f, 0.0f, 1.0f);glTexCoord2f(1.0f, 0.0f);glVertex3f(-4.0f, 0.0f, 1.0f);glTexCoord2f(1.0f, 1.0f);glVertex3f(-4.0f, 0.0f, -1.0f);glTexCoord2f(0.0f, 1.0f);glVertex3f( 4.0f, 0.0f, -1.0f);glEnd();}void DrawGLfengshan(GLfloat x) //画风扇,由柱和叶片组合而成,有一个浮点型参数,代表旋转增量{glPushMatrix();glTranslatef(0.0,2.5f,0.0); //轴长5.0,开始在中心原点,所以先向上平移2.5DrawGLfengshanzhou(); //画风扇轴glPopMatrix();glPushMatrix();glRotatef(x,0.0f,1.0f,0.0f); //使风扇叶片绕Y轴旋转,x表示旋转增量glPushMatrix();glTranslatef(4.0f,0.0f,0.0f); //风扇叶长8.0,开始在中心原点,所以先向右平移4.0DrawGLfengshanye(); //画第一个叶片glPopMatrix();glPushMatrix();glRotatef(120,0.0f,1.0f,0.0f); //旋转120度glTranslatef(4.0f,0.0f,0.0f); //注意:编码时变换的顺序和实际变换的顺序刚好相反。
基于OpenGL的虚拟漫游系统实现技术530021 广西电化教育馆(广西南宁) 祝英俊 530003 广西财经学院国际教育学院(广西南宁) 李国祥【摘 要】通过介绍一个基于OpenGL的虚拟漫游系统,紧紧围绕虚拟场景的真实性和系统的实时性,着重讨论了一些关键技术以及这些技术的实现方法和实现过程。
【关键词】虚拟漫游;OpenGL;碰撞检测;层次细节引言虚拟漫游系统的主要功能是实现客户与虚拟场景的交互,它是虚拟现实应用的基本功能之一。
构造一个虚拟环境漫游系统,就是利用高性能的计算机软硬件创建参与者具有身临其境的人机交互能力、有助于启发构思的信息环境,进而达到参与者在虚拟环境中获取知识、形成概念的最终目标。
本文主要使用3D Max进行三维建模,以Visual C++ 6.0为开发平台,通过导入已建好的三位场景,应用碰撞检测、相机控制、场景调度等手段来增强系统的真实感。
1、OpenGL在VC++ 6.0的环境配置首先需要下载到OpenGL库,然后按以下步骤进行设置[1]:(1)把glut32.dll复制到Windows操作系统目录下。
(2)把连接库g lut.l ib复制到开发环境的库目录中:(..\\Microsoft Visual Studio\VC98\Lib)。
(3)把glut.h放到开发环境中保存gl.h和glu.h的同一目录下(Microsoft Visual Studio\VC98\Include\GL目录下)。
(4)在VC下把菜单Project/setting打开其对话框,选择Link页,在其Object/library Modules编辑框中加上opengl32.lib、glu32.lib、glut32.lib。
由于OpenGL是独立于窗口系统的,它可以在其他窗口系统中进行渲染操作,但要进行窗口的基础设置,以支持OpenGL渲染。
本系统采用单文档视图结构,文档类主要进行数据处理工作,而视图类负责图形的显示工作。
国防科学技术人学研究生院学位论文然后他用泛函求导方法导出高斯函数的一阶导数,此即为该最佳函数的最好近似,且有简便的计算方法。
在进行处理前,Canny算法先用高斯平滑滤波器来平滑图像用来除去噪声,即用高斯平滑滤波器与图像作卷积。
滤波的目的是为了消除噪声,因为图像中的噪声在图像傅旱叶变换中对应着高频部分,所以要在频域中削弱噪声的影响,就要设法减弱这部分的频率分量。
实际工作中,人们常常采用低通滤波器来实现。
然而大多数滤波器在降低噪声的同时也导致了边缘强度的损失(边缘也对应着高频部分)。
因此,需要在边缘与噪声之间作一个折衷,采用高斯平滑滤波器是一个较好的折衷方案。
增强边缘是将邻域(或局部)强度值有显著变化的点突出来,它一般通过计算梯度幅值来完成的,Canny分割算法采用一阶偏导的有限差分来计算梯度的幅值和方向。
对一个边缘来说,其一阶导数在边界处存在一个向上的阶跃或者其二阶导数过零点。
导数的计算对噪声很敏感,而一般的边缘检测也正是利用求导数来实现的。
在处理过程中,Canny算法还将经过一个非极大值抑制(NonmaximalSuppression)的过程。
最后,Canny算法将采用两个阈值来连接边缘。
非极大值抑制是为了保证边缘线被细化为一个象素的宽度,Canny算子采用边缘梯度方向的非极大抑制方法。
如果在45度和135度边缘方向的每边区域的狄度值是相同的,这种方法容易产生厚边缘。
如图2.1所示,其原因是这些边界象素点在边缘方向上没有邻接边界点。
我们可以用这种方法消除这种厚边缘,对边缘方向为45度和135度的象素点与它的水平或垂直方向的邻接边界点作比较,如果它的水平或垂直方向的邻接边界点也有同样的边缘方向,则删除它的邻接边界点,显然这种方法可以消除这种厚边缘。
鼬2.1135度厚边缘示意l璺I2.2.2边界线断点填充用Canny算子来提取图像的边界一个最大的优点就是很容易把边缘细化为单象素宽度,而且效果也较好,但是在边缘细化过程中在边界上容易产生断点,而且随高斯函数的口系数的不同及两个阈值参数的不同,产生的断点的个数与断点间隔长度也不同,因此我们必须对断点进行填充,国防科学技术入学研究生院学位论文圈2.4新算法实验结_聚图l(b)SUSAN酗2.5新算法实验结果幽2(a)Harris(b)SUSAN(c)newalgorithm图26新算法实验结果倒3(b)SUSAN(c)newalgorithm幽27新算法实验结果幽4国防科学技术人学研究生院学佟论文其中k为一个尺度因子系数。
基于OpenGL的三维校园漫游系统可视化研究刘萍萍;陆兆攀;高武奇【摘要】As a distributed information center easy to use with no limit of time and space,the digital campus is a new type of organization and management,which has become the trend of the construction and development of digital campus information.In order to provide an important campus information platform for the construction of digital university,based on the technology of virtual reality,the design and implementation of virtual campus roaming system based onVC++platform and OpenGL are discussed,and the basic algorithm of develo-ping virtual campus roaming system is further studied.Taking Xi'an Technological University Weiyang Campus as a model,it is simula-ted by the technology of virtual reality,3D Max modeling,SQL database,three-dimensional panoramic and computer network,to achieve a virtual campus roaming system with good realistic effect and real-time ers can use the mouse and keyboard and other ex-ternal devices roaming in the three-dimensional virtual campus scene,so that the campus realistic interaction is achieved to meet the re-quirements of digital educating and training.%数字校园作为一个分布式的、无时空限制、便于使用的信息中心,具有一种全新的组织和管理方式,已成为当今数字化校园信息建设和发展的趋势.为了给数字化大学的建设提供一个重要的校园信息化平台,以虚拟现实技术为基础,讨论了基于VC++平台和OpenGL的虚拟校园漫游系统的设计和实现,对开发虚拟校园漫游系统的基本算法进行进一步研究.以西安工业大学未央校区作为模型,利用虚拟现实技术、3D Max建模技术、SQL数据库技术、三维全景技术和计算机网络技术,对其进行仿真建设,实现一个具有良好的真实感效果和实时交互性的虚拟校园的漫游系统.用户可以借助鼠标和键盘等外部设备在三维虚拟校园场景中漫游,使校园真实感的交互操作得以实现,满足了数字化教育训练的要求.【期刊名称】《计算机技术与发展》【年(卷),期】2018(028)004【总页数】6页(P174-178,182)【关键词】OpenGL;虚拟校园;虚拟现实技术;3DMax;SQL数据库【作者】刘萍萍;陆兆攀;高武奇【作者单位】西安工业大学计算机科学与工程学院,陕西西安710021;西安工业大学计算机科学与工程学院,陕西西安710021;西安工业大学计算机科学与工程学院,陕西西安710021【正文语种】中文【中图分类】TP3990 引言随着虚拟现实及相关技术的不断进步与发展,人们之间的交流也将采用新的方式、进入新的领域,实现由文字图像到三维VR(虚拟现实)的转变[1]。
虚拟环境的演示和漫游摘要本文主要介绍了利用OpenGL来实现对虚拟环境的演示及漫游,介绍了设计所用的相关软件,如3DMAX、OpenGL、等,重点说明了OpenGL对于图形的重要性以及调用方法。
本设计主要以VC为开发平台,通过OpenGL函数对虚拟环境进行了构建,使人们可以在其构建的虚拟环境中漫游,使其了解虚拟环境所参考的现实环境。
用户可通过键盘等外设来对构建的虚拟环境进行浏览,以第一人称视角给其留下深刻的印象。
本软件将有助于在用户亲自到达某个区域前对其有个基本的了解,这将大大减少用户了解某地区付出的代价,使其可以提高生活与工作的效率。
本设计还可将构建的3D模型创建到虚拟的场景中,这将有助于用户了解某地的建筑以及功能。
虚拟环境的演示和漫游将有助于扩展人们的视野,同时还不用付出很多的时间和精力,就能感受与实地相似的真实感。
关键词:3DMAX OpenGL 目录第一章虚拟环境的演示和漫游(任务目标和解决方案) (4)1.1 目标 (4)1.2 实现 (4)一、校园虚拟环境的实现 (4)二、在程序中调用建立好的模型 (4)三、在程序中实现对虚拟环境的漫游 (4)第二章虚拟环境的演示和漫游中应用的软件 (4)2.1 使用的软件简介 (4)2.2 简介 (5)2.3 Visual C++简介 (5)2.4 3D Studio MAX简介 (5)2.5 OpenGL简介 (5)一、简介 (5)二、特点 (5)三、OpenGL的基本操作 (6)四、OpenGL图形处理系统的结构及基本框架 (7)五、OpenGL的基本工作流程 (9)六、OpenGL图形操作步骤 (11)第三章利用3DMAX建立虚拟环境所需的模型 (13)3.1 虚拟环境中场景的模型建立 (13)3.2 将模型转换为主程序可以调用的文件 (15)第四章程序源代码 (16)4.1 程序主框架代码 (16)4.2 OpenGL程序框架代码 (18)4.3 虚拟环境效果渲染代码 (21)4.4 调用3D模型及场景贴图代码 (33)第5章运行结果 (42)5.1 程序运行结果 (42)5.2 程序运行结果截图 (42)结论 (44)鸣谢 (44)参考文献 (45)第一章虚拟环境的演示和漫游(任务目标和解决方案)1.1目标:对现实的环境进行模拟建立一个虚拟的世界,可以让人们在虚拟的环境中漫游,使其对现实的环境有个大概的了解。
现代计算机(总第二五七期)MODERNCOMPUTER2007.40引言把3DSMax建模后的模型转换成OpenGL程序,再对其进行控制则是一种比较理想的方法,再通过VC++编程调用OpenGL可以对整个三维图形轻松进行渲染,设计交互动作设计和系统整合,从而创建良好的虚拟漫游程序。
1三维模型的创建与读取虚拟现实模型的生成需要兼顾实时性与真实感,建模的基本思路是以3DS模型为基础构建整个室内环境,并在模型上添加相应的纹理贴图以增强真实感,通过提取模型数据并加以优化,供OpenGL调用,以提高模型显示速度。
3DS是一种非常普遍的数据格式,以3DS格式保存的三维图形文件非常丰富,因此对3DS数据模型的读取和操作具有非常重要的实际意义[2]。
读取3DS文件的步骤是:(1)在程序中建立自定义的数据结构存储数据模型;(2)从3DS文件中读取数据,并将这些数据存放在建立的模型信息结构体中。
1.1定义数据结构3DS模型数据是在结构体中定义的,包括点、面、材质信息、对象信息和模型信息结构体,主要用于将3DS文件中读出的数据保存在模型中。
结构体定义如下:classCVector3{public:floatx,y,z;};//定义3D点类,用于保存模型中的顶点classCVector2{public:floatx,y;};//定义2D点类,用于保存模型的UV纹理坐标structtFace{intvertIndex[3];//顶点索引intcoordIndex[3];//纹理坐标索引};//面信息结构体1.23DS文件的导入为了实现3DS格式文件的导入,在VC++中定义了CLoad3DS类,主要用于处理3DS文件中的各种块。
在导入过程中,通过CLoad3DS类中递归函数的组合,将3DS文件中的数据全部读出并存储在自定义的数据格式中。
这三个递归函数包括:voidProcessNextChunk(t3DModel*pModel,tChunk*);//读下一个块voidProcessNextObjectChunk(t3DModel*pModel,t3DObject*pObject,tChunk*);//读下一个对象块voidProcessNextMaterialChunk(t3DModel*pModel,tChunk*);//读下一个材质块其流程图如图1所示。
图1导入函数流程图2OpenGL应用程序的创建在3DS文件导入之后,漫游场景中模型的所有信息都保存在了自定义的数据结构中,通过OpenGL直接使用这些数据,可将三维模型重新绘制出来[3]。
2.1OpenGL程序框架在Windows下,构建OpenGL程序框架主要包括四项内容:(1)添加函数库;(2)设置像素格式;(3)创基于OpenGL的虚拟漫游技术研究侯守明,朱雅莉{河南理工大学计算机科学与技术学院,焦作454100)摘要:以室内漫游系统开发为例,描述了基于OpenGL的虚拟漫游系统的构建过程,探讨了构建过程中3DS文件导入、OpenGL绘制、漫游控制和碰撞检测等一些技术问题。
实验结果表明,该系统基本实现了三维场景的实时漫游,效果良好。
关键词:虚拟漫游;OpenGL;3DSMax;VC++;碰撞检测!"现代计算机(总第二五七期)建渲染场景;(4)视口和投影变换。
如图2所示:图2OpenGL程序的基本框架2.2OpenGL重绘三维场景(1)计算法向量法向量在用多边形构造三维造型时是至关重要的,它与实体的光照模型密切相关。
光线从不同入射角照射到模型表面时,显示结果有差别,如果忽略了法向量的计算,将不能重现模型的三维效果[3]。
通过自定义函数voidCLoad3DS::ComputeNor-mals(t3DModel*pModel)计算对象的法向量,函数中遍历了对象的所有面和所有顶点,计算出它们的法向量,并通过规范化后将法向量添加到法向量列表中。
在OpenGL绘制模型时,将法向量列表中的每一个元素作为参数传递给函数voidglNormal3{bsid}(GLfloatnx,GLfloatny,GLfloatnz),设置当前顶点的法向量。
(2)绘制场景之前导入3DS文件时,已经把场景中模型的各种信息都存储在了自定义的数据结构中,OpenGL从这些数据结构中获取信息,以一定的绘制模式将模型一一绘制出。
伪代码如下:遍历模型中所有的对象{获得当前显示的对象if(该对象有纹理映射)为对象绑定纹理else取消二维纹理映射模式开始以多个三角形模式绘制}3漫游控制技术图3为整个漫游系统的组成框架:图3虚拟漫游系统的组成框架用户对视角的控制主要通过定义摄像机类CCamera的方法实现,在摄像机类中有几个关键的数据变量,它们分别是摄像机的位置(m_vPosition),摄像机的视野(m_vView),摄像机的向上的位置(m_vUpVector),摄像机左右方向(m_vStrafe),它们决定摄像机状态,并且只被摄像机类内的函数调用。
根据摄像机的位置、左右方向和上下方向,利用OpenGL实用库函数gluLookAt()设置投影变换:glu-LookAt(m_vPosition.x,m_vPosition.y,m_vPosition.z,m_vView.x,m_vView.y,m_vView.z,m_vUpVector.x,m_vUpVector.y,m_vUpVector.z);。
3.1控制方法(1)鼠标控制通过鼠标的移动来设置视点,并改变视线方向,实现仰视和俯视。
主要代码如下:GetCursorPos(&mousePos);//获得鼠标的当前位置angleY=(float)((middleX-mousePos.x))/500.0f;//计算角度angleZ=(float)((middleY-mousePos.y))/500.0f;currentRotX-=angleZ;//旋转观察方向CVector3vAxis=Cross(m_vView-m_vPosition,m_vUpVector);vAxis=Normalize(vAxis);RotateView(angleZ,vAxis.x,vAxis.y,vAxis.z);RotateView(angleY,0,1,0);(2)键盘控制键盘的方向键和W、S、A、D可以实现前进、后退,左转和右转。
左转、右转时视点均保持不变,只改变视线方向;前进、后退时将视点分别沿视线方向和视线反方向移动一定距离。
主要代码如下:floatspeed=kSpeed*g_FrameInterval;//获得当前帧率if(GetKeyState(VK_UP)&0x80||GetKeyState(‘W’)&0x80)//是否按下UP箭头键或‘W’键{MoveCamera(speed);//向前移动摄像机}if(GetKeyState(VK_DOWN)&0x80||GetKeyState('S')&0x80)//是否按下DOWN键或'S'键{MoveCamera(-speed);//向后移动摄像机}if(GetKeyState(VK_LEFT)&0x80||GetKeyState('A')&0x80)//是否按下LEFT箭头键或'A'键{StrafeCamera(-speed);//向左移动摄像机}if(GetKeyState(VK_RIGHT)&0x80||GetKeyState('A')&0x80)//是否按下RIGHT箭头键或'A'键!"MODERNCOMPUTER2007.4现代计算机(总第二五七期)MODERNCOMPUTER2007.4{StrafeCamera(speed);//向右移动摄像机}3.2碰撞检测技术进行碰撞检测常采用包围盒技术,包围盒的各线段与坐标轴平行,最大好处是可以实现快速碰撞检测,但是很多实际应用的可视化系统中,要想做到自然交互光靠包围盒进行检测是不够的。
由于任何物体的表面都可以被剖分成三角形,所以要进行比较精确的碰撞检测就必须转化为三角形之间的碰撞检测。
在虚拟漫游中,控制摄像机(视点)使其在相对静止的场景中运动,每当接收到用户漫游场景的输入,系统都要进行检测,判断根据用户的输入而得到的新的视点是否会与场景中的物体发生碰撞或进入物体的内部。
把视点转化为一个点,把场景中的物体的表面剖分成三角形,这样,碰撞检测便转化为判断一个点是否与三角形相交的问题[1]。
判断视点是否与三角形发生了碰撞,只要判断前后两视点的连线与平面的交点是否在三角形内部[5]。
代码如下:for(inti=0;i<3;i++){vA=Triangle[i]-vCutpoint;//得到当前顶点与交点之间的向量vB=Triangle[(i+1)%3]-vCutpoint;//得到下一个顶点与交点之间的向量Angle+=AngleBetween(vectorvA,vectorvS);//交点与三角形三个顶点夹角之和}如果夹角之和大于等于360°,交点在三角形内部,说明视点与三角形发生了碰撞;如果夹角小于360o,交点不在三角形内部,说明视点并未与三角形发生碰撞。
4结论在VC++6.0下,通过读取3DS构建的场景模型信息,基于OpenGL三维图形库实现了一个学生宿舍室内虚拟漫游程序,用户可以使用键盘和鼠标实现场景任意方向的浏览。
运行结果见图4。
使用这种方法可以快速构建复杂三维场景的虚拟模型,系统设计简单方便,开发成本低,场景的真实感和实时性能够满足用户需求。
该研究可进一步推广应用于矿井的三维建模、工业产品的虚拟展示等领域。
图4宿舍室内漫游系统运行效果参考文献[1]王长波,殷红.VC++6.0中用OpenGL实现建筑物虚拟漫游,电脑编程技巧与维护(2002.3):73~77[2]和平鸽工作室.OpenGL三维图形系统开发与实用技术.实用技术篇.重庆:重庆大学出版社,2003[3]郭景,雷鸣.3DSMAX模型在OpenGL中的读取与重现,自动化与仪表(2002.5):46~49[4]王清辉,王彪.VisualC++CAD应用程序开发技术.北京:机械工业出版社,2003[5]熊伟,毛善君,马蔼乃.基于观察者的碰撞检测技术在虚拟环境漫游中的应用,计算机应用(2002.11):7 ̄10(收稿日期:2007-01-12)ResearchonTechnologyofVirtualWalkthroughBasedonOpenGLHOUShou-ming,ZHUYa-li(CollegeofComputerScienceandTechnology,HenanPolytechnicUniversity,Jiaozuo451000China)Abstract:Keywords:VirtualWalkthrough;OpenGL;3DSMax;VC++;CollideDetectionTakesvirtualwalkthroughsysteminthedormitoryasanexample,describestheconstructingprocessinvirtualwalkthroughsystembasedonOpenGL,discussessometechnologiessuchas3DSfilesimport,OpenGLdrawing,walkthroughcontrolandcollidedetection.Theexperimentalresultindicatesthat,thissystemhasbetterachievedthe3Dscenereal-timewalkthrough.!"。