基于OpenGL的三维曲面数据场动态显示

2007-08-20 08:53 作者: 白婷 赵军 朱双华等 出处: 计算机与信息技术 责任编辑:方舟
摘 要 在大数据量条件下,实时动态显示三维曲面较困难,其关键在于提高三维图形数据处理和图形绘制速度。通过对基于图形工业标准OpenGL实现三维曲面动态显示的原理和方法的讨论,提出采用OpenGL的双缓存、显示列表技术,大幅度提高了图形数据处理和刷新速度,保证了每帧数据图形绘制的连续性和完整性,成功实现了三维曲面数据场实时动态显示。

  关键词 OpenGL 三维曲面 动态显示

  引言

  在某三维数据场中,数据随时间的变化而发生变化,为直观观察数据随时间变化的态势,需对数据场的变化实时动态显示。利用网格曲面显示三维数据场是一种直观的方法,但需经过数据插值、投影、曲面拼接、消隐等处理后方可绘制图形,计算量较大。在数据量较大的情况下,实时动态显示三维曲面图形较困难,其关键在于提高每帧图形处理和绘制刷新速度,以保证每帧三维曲面显示时的连贯性和完整性。

  OpenGL是性能卓越的图形处理工具,采用OpenGL双缓存和绘图操作予编译技术,较好解决了三维图形数据处理和绘图刷新速度问题。利用Visual C++调用OpenGL的三维图形编程接口成功实现了大数据量的三维曲面图形的实时动态显示。

基于OpenGL的三维曲面动态显示实现

  在使用Visual C++的MFC AppWizard建立应用程序框架后,生成了多个类,与OpenGL编程相关的类是视图类,主要的显示任务都在其中完成。

  1、基于OpenGL绘图的基本设置

  1.1 设置必要的编译链接环境

  OpenGL的图形编程接口包括的主要函数和库函数被封装在动态链接库中,因此在项目中要添加 OpenGL32.dll、glu32.dll和glaux.dll三个库。同时在应用程序的视类头文件中加入OpenGL头文件说明:

  #include "gl/gl.h"

  #include "gl/glu.h"

  #include "gl/glaux.h"

  1.2 设置像素格式

  该部分设置绘图所需的像素格式,Windows下采用PIXELFORMATDESCRIPTOR结构设置像素格式,该结构包含26个属性信息,包含了颜色位数、颜色模式、缓存的位数和操作方式,以及是否采用双缓存机制等。

  1.3 创建着色描述表

  OpenGL应用程序的设备描述表(DC)称为着色描述表,由它通知Windows在窗口中绘制图形。应用程序必须在绘图之前调用专用函数wglCreateContext()创建自己的着色描述表,调用wglMakeCurrent()使其当前化,退出OpenGL时使着色表非当前化。

  1.4 创建三维曲面的观察场景

  OpenGL一般用函数glFrustrum()和glViewport()实现投影变换和视口变换。glFrustrum()定义了一个容纳绘制对象的最大空间区域,即视景体,位于视景体以外的部分都会被剪切掉;glViewport()则定义了一个绘制场景的矩形区域,即视口,用来把场景中的点映射到绘图区。

  glFrustrum(-1.0,1.0,-2.0,2.0,0.0,7.0);

  //视景体上、下、左、右、前、后的坐标分别为-1.0,1.0,-2.0,2.0,0.0,7.0;

  glViewport(0,0,200,300);

  //视口区上、下、左、右坐标分别为0,0,200,300;

  1.5 视类中OnDraw()成员函数的设置

  在Windows的VC++编程中,所有窗口中的图形绘制代码都在视类的OnDraw成员函数中实现,采用OpenGL绘制三维曲面之前需要进行必要的环境设置。

  glClearColor(1.0f,1.0f,1.0f,1.0f);//设置背景颜色为白色

  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//清除颜色缓存和深度缓存

  glColor3f(1.0f,1.0f,1.0f);//设置绘图颜色为红色

  2、创建绘制三维曲面的显示列表

  在显示列表中定义用户绘制三维曲面图形所需数据以及数据之间显示连接方式。文中实例中显示列表包括三维曲面图形的数据点的显示列表;坐标轴的显示列表;显示坐标数据的显示列表。显示列表采用线段连接的方式。

  3、三维曲面图形动态显示程序主框架

  在视类中产生Onhuitu()作为绘图的主程序。三维曲面图形动态显示子程序drawsurbs()包括初始化,读数据文件,数据插值,投影变换,消隐,绘图显示列表设置(坐标轴绘制显示列表、三维曲面绘制显示列表),强制绘图操作,缓存拷贝,切换前后缓冲区等几个主要部分。初始化程序myinit()中设置双缓存模式,是实现动态显示的前提。drawsurbs()中缓存拷贝auxSwapBuffers()、切换缓存SwapBuffers (wglGetCurrentDC())、缓冲区的清除glClear(GL_COLOR_ BUFFER_BIT|GL_DEPTH_BUFFER_BIT)是实现动态显示的必不可少的操作。

void CNurbsView::Onhuitu()
{
 HWND hWnd=GetSafeHwnd();
 HDC hDC=::GetDC(hWnd);
 wglMakeCurrent(hDC,hglrc); //设置当前着色表
 drawsurbs(); //动态显示三维曲面子程序
 wglMakeCurrent(NULL,NULL);//着色表非当前化
 SwapBuffers(hDC); //交换缓存
}
void CNurbsView::drawsurbs()
{
 ……
 myinit(); //初始化子程序
 jixu=20; //动态显示帧数
 While(jixu)
 {
  readdata(); //读数据文件子程序
  interplator(); //数据插值子程序
  orthoprojection(); //投影变换子程序
  xiaoying(); //消隐子程序
  glPushMatrix();
  glColor3f(0.0f,1.0f,1.0f); //颜色设置
  glLineWidth(2.0); //线宽设置
  glNewList(axis_list,GL_COMPILE);//坐标轴显示列表
  ……
  glEndList();
  glNewList(sufer_list,GL_COMPILE); //三维曲面绘制显示列表
  ……
  glEndList();
  glCallList(axis_list);
  glCallList(sufer_list)
  glFlush(); //强制绘图
  glPopMatrix();
  auxSwapBuffers(); //缓存拷贝
  SwapBuffers(wglGetCurrentDC()); //切换缓存
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //为绘下帧曲面清除缓冲区
  jixu--
  deley(); //延时子程序
 }
}

void CNurbsView::myinit()
{
 glClearColor(0.03,0.4,0.4,0.4);
 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 auxInitDisplayMode(AUX_DOUBLE|AUX_RGBA);//设置成双缓存模式
}

  某数据场三维曲面动态显示仿真系统实例

  根据以上思想,利用OpenGL双缓存及显示列表技术,基于某数据场数据,开发了三维曲面图形动态显示仿真系统,该实例中视窗中三维曲面图形随数据场的数据的改变而动态显示,图2为程序运行中某一时刻的显示结果。

  结束语

  在微机平台上,利用VC6.0的OpenGL根据数据场的分布进行三维曲面的动态显示是切实可行的,尤其采用双缓存及显示列表技术可以得到很好的三维曲面生成速度,这种动态显示技术可以推广应用在需要进行实时动态显示的数据处理方面。

  
  图2 三维曲面数据场动态显示仿真系统展示图

  在使用Visual C++的MFC AppWizard建立应用程序框架后,生成了多个类,与OpenGL编程相关的类是视图类,主要的显示任务都在其中完成。

  1、基于OpenGL绘图的基本设置

  1.1 设置必要的编译链接环境

  OpenGL的图形编程接口包括的主要函数和库函数被封装在动态链接库中,因此在项目中要添加 OpenGL32.dll、glu32.dll和glaux.dll三个库。同时在应用程序的视类头文件中加入OpenGL头文件说明:

  #include "gl/gl.h"

  #include "gl/glu.h"

  #include "gl/glaux.h"

  1.2 设置像素格式

  该部分设置绘图所需的像素格式,Windows下采用PIXELFORMATDESCRIPTOR结构设置像素格式,该结构包含26个属性信息,包含了颜色位数、颜色模式、缓存的位数和操作方式,以及是否采用双缓存机制等。

  1.3 创建着色描述表

  OpenGL应用程序的设备描述表(DC)称为着色描述表,由它通知Windows在窗口中绘制图形。应用程序必须在绘图之前调用专用函数wglCreateContext()创建自己的着色描述表,调用wglMakeCurrent()使其当前化,退出OpenGL时使着色表非当前化。

  1.4 创建三维曲面的观察场景

  OpenGL一般用函数glFrustrum()和glViewport()实现投影变换和视口变换。glFrustrum()定义了一个容纳绘制对象的最大空间区域,即视景体,位于视景体以外的部分都会被剪切掉;glViewport()则定义了一个绘制场景的矩形区域,即视口,用来把场景中的点映射到绘图区。

  glFrustrum(-1.0,1.0,-2.0,2.0,0.0,7.0);

  //视景体上、下、左、右、前、后的坐标分别为-1.0,1.0,-2.0,2.0,0.0,7.0;

  glViewport(0,0,200,300);

  //视口区上、下、左、右坐标分别为0,0,200,300;

  1.5 视类中OnDraw()成员函数的设置

  在Windows的VC++编程中,所有窗口中的图形绘制代码都在视类的OnDraw成员函数中实现,采用OpenGL绘制三维曲面之前需要进行必要的环境设置。

  glClearColor(1.0f,1.0f,1.0f,1.0f);//设置背景颜色为白色

  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//清除颜色缓存和深度缓存

  glColor3f(1.0f,1.0f,1.0f);//设置绘图颜色为红色

  2、创建绘制三维曲面的显示列表

  在显示列表中定义用户绘制三维曲面图形所需数据以及数据之间显示连接方式。文中实例中显示列表包括三维曲面图形的数据点的显示列表;坐标轴的显示列表;显示坐标数据的显示列表。显示列表采用线段连接的方式。

  3、三维曲面图形动态显示程序主框架

  在视类中产生Onhuitu()作为绘图的主程序。三维曲面图形动态显示子程序drawsurbs()包括初始化,读数据文件,数据插值,投影变换,消隐,绘图显示列表设置(坐标轴绘制显示列表、三维曲面绘制显示列表),强制绘图操作,缓存拷贝,切换前后缓冲区等几个主要部分。初始化程序myinit()中设置双缓存模式,是实现动态显示的前提。drawsurbs()中缓存拷贝auxSwapBuffers()、切换缓存SwapBuffers (wglGetCurrentDC())、缓冲区的清除glClear(GL_COLOR_ BUFFER_BIT|GL_DEPTH_BUFFER_BIT)是实现动态显示的必不可少的操作。

void CNurbsView::Onhuitu()
{
 HWND hWnd=GetSafeHwnd();
 HDC hDC=::GetDC(hWnd);
 wglMakeCurrent(hDC,hglrc); //设置当前着色表
 drawsurbs(); //动态显示三维曲面子程序
 wglMakeCurrent(NULL,NULL);//着色表非当前化
 SwapBuffers(hDC); //交换缓存
}
void CNurbsView::drawsurbs()
{
 ……
 myinit(); //初始化子程序
 jixu=20; //动态显示帧数
 While(jixu)
 {
  readdata(); //读数据文件子程序
  interplator(); //数据插值子程序
  orthoprojection(); //投影变换子程序
  xiaoying(); //消隐子程序
  glPushMatrix();
  glColor3f(0.0f,1.0f,1.0f); //颜色设置
  glLineWidth(2.0); //线宽设置
  glNewList(axis_list,GL_COMPILE);//坐标轴显示列表
  ……
  glEndList();
  glNewList(sufer_list,GL_COMPILE); //三维曲面绘制显示列表
  ……
  glEndList();
  glCallList(axis_list);
  glCallList(sufer_list)
  glFlush(); //强制绘图
  glPopMatrix();
  auxSwapBuffers(); //缓存拷贝
  SwapBuffers(wglGetCurrentDC()); //切换缓存
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //为绘下帧曲面清除缓冲区
  jixu--
  deley(); //延时子程序
 }
}

void CNurbsView::myinit()
{
 glClearColor(0.03,0.4,0.4,0.4);
 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 auxInitDisplayMode(AUX_DOUBLE|AUX_RGBA);//设置成双缓存模式
}

  某数据场三维曲面动态显示仿真系统实例

  根据以上思想,利用OpenGL双缓存及显示列表技术,基于某数据场数据,开发了三维曲面图形动态显示仿真系统,该实例中视窗中三维曲面图形随数据场的数据的改变而动态显示,图2为程序运行中某一时刻的显示结果。

  结束语

  在微机平台上,利用VC6.0的OpenGL根据数据场的分布进行三维曲面的动态显示是切实可行的,尤其采用双缓存及显示列表技术可以得到很好的三维曲面生成速度,这种动态显示技术可以推广应用在需要进行实时动态显示的数据处理方面。

  
  图2 三维曲面数据场动态显示仿真系统展示图

  基于OpenGL的三维曲面动态显示原理

  1、基于OpenGL三维曲面图形显示原理

  OpenGL是独立于操作系统的开放式三维图形软件接口。其主要功能是将三维曲面通过顶点序列或像素点进行描述,并进行相应的透视、光照、纹理操作,最终转换成帧缓存中的图像数据,利用该图像数据进行三维曲面图形的着色。三维曲面图形显示归纳为以下几个步骤:

  (1)在三维场景中建立曲面绘制的模型。选用插值方法、参数曲面函数,计算曲面控制点,进行曲面重构;

  (2)设置视点和透视方式;

  (3)进行消隐、光照、纹理、明暗处理;

  (4)绘制场景,输出到屏幕窗口。

  
  图1 三维曲面图形显示基本流程

  2、利用双缓存实现动态显示原理

  三维曲面动态显示需要连续地绘制三维曲面并显示场景,用不同的曲面数据刷新屏幕视窗。

  在OpenGL中利用双缓存技术,分配两个帧缓存区,在连续显示三维曲面时,一个帧缓冲区中的数据执行绘制曲面命令的同时,另一个帧缓存区中的数据进行图形显示。当前可见视频缓存称为前台视频缓存,不可见的正在绘图的视频缓存称为后台视频缓存。当后台视频缓存中的数据要求显示时,OpenGL就将它拷贝至前台视频缓存,显示硬件不断地读可见视频缓存中的内容,并把结果显示在屏幕上。

  应用双缓存,每一帧三维曲面只在绘制完成之后才显示出来,所以观察者可以看到每一帧完整三维曲面,而不是曲面的绘制过程。

  使用双缓存实现三维曲面动态显示的步骤如下:

  (1)设置OpenGL窗口显示属性为双缓存机制:auxInitDisplayMode(AUX_DOUBLE|AUX_RGBA);

  (2)利用OpenGL基本绘图命令绘制三维曲面;

  (3)一帧曲面绘图结束后缓存拷贝,切换缓存:auxSwapBuffers();

  SwapBuffers(wglGetCurrentDC());

  3、利用显示列表提高程序运行效率

  显示列表是一组预先存储起来留待以后调用的函数语句。调用显示列表时就按次序执行其中的函数。显示列表将反复执行的绘图操作以编译好的命令方式进行存储,设计成命令的高速缓存,而不是动态的数据库缓存,所以可以优化程序运行性能。

  实现和调用显示列表的方法:

  (1)创建列表:

  void glNewList(Gluint list,Glenm mode);

  void glBegin(Glenum mode);

  void glEnd(void);

  void glEndList();

  (2)调用列表:

  void glCallList(Gluint list);

基于OpenGL的三维曲面数据场动态显示 (转)相关推荐

  1. OpenGL 基于OpenGL的三维机器人仿真

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 基于Op ...

  2. 计算机可视化仿真技术opengl,基于OpenGL的三维场景可视化仿真

    摘要: 随着计算机可视化技术的发展,计算机可视化应用的领域不断地拓宽,广泛地应用在科学计算.人工智能仿真.三维图形的制作方面等领域.可视化是计算机技术应用的热门领域,而这个热门领域的核心都集中在三维真 ...

  3. 基于FME实现点云数据的过滤去噪和生成表面模型

    作者:LLT 近年来随着三维激光扫描技术的不断发展与更新,点云数据也越来越多地应用于各个领域.FME作为一款数据转换和变换软件,在点云处理方面也有许多独到之处.下面就给大家分享一些点云数据的处理技巧. ...

  4. 基于三维GIS的场数据模型研究与实践

    地理信息系统(geographic information  sys-tem , GIS)的灵魂是空间分析,而空间分析的基础是空间数据模型.空间数据模型是人们对现实世界地理空间实体.现象以及它们之间相 ...

  5. 人脸扫描建模_一种基于三维扫描数据的人脸建模方法

    一种基于三维扫描数据的人脸建模方法 黄炎辉 1 , 樊养余 1 , 董卫军 2 [摘 要] 三维扫描仪可以准确获取人脸的几何形状与纹理,但原始的人脸扫描 数据仅为一张连续曲面,不符合实际的人脸结构,无 ...

  6. matlab 光度 三维重构 code,基于matlab的三维点云数据三维重建

    基于matlab的三维点云数据三维重建,通过快速构建三角网,实现三维模型的建立,并提供实例数据用于实验. 三维重建的英文术语名称是3D Reconstruction. 三维重建是指对三维物体建立适合计 ...

  7. html5三维空间效果,基于HTML5的空间环境数据三维成像研究与应用

    摘要: 自上世纪五,六十年代载人航天技术发展以来,研究人员对空间环境开始进行系统化及规模化的研究.他们根据对地球轨道参数及地磁参数等的研究,确定了多种粒子或剂量,并开始对初级粒子及剂量进行测量和分析. ...

  8. 基于图像的三维物体重建:在深度学习时代的最新技术和趋势综述之三维曲面解码...

    点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 1.三维曲面解码 基于体积表示的方法在计算上非常浪费,因为信息只在三维形状的表面或其附近丰富.直接处理 ...

  9. 如何使用MATLAB对任意三维数据绘制三维曲面

    这段时间写论文,用到MATLAB绘制三维曲面,而由于三组数据是同样维度,不能直接使用mesh或者surf等绘图命令进行绘图,这时候怎么办呢? 方法:将两组数据运用拟合的方法得到关于第三组数据的回归方程 ...

最新文章

  1. 虚拟机下Linux安装图解之二:虚拟机的创建
  2. 阿里云云市场全新升级 瞄准需求拓生态
  3. spring -boot定时任务 quartz 基于 MethodInvokingJobDetailFactoryBean 实现
  4. 使用wcstok_s函数分割路径, 创建多级目录
  5. iphone桌面上的圆圈怎么设置_苹果手机桌面上找不到便签记事本怎么办?有办法添加吗...
  6. alibaba实习生代码大赛
  7. glassfish 4配置_自己构建GlassFish 4.0快照
  8. 能让中年人放下面子赚到钱的副业
  9. 计算机械功的公式,机械功率计算公式
  10. 1991年首批全国500位名老中医
  11. Linux线程性能分析和CPU亲和力
  12. 软件测试工程师简历项目经验怎么写(含真实简历)
  13. Dev GridControl 单元格输入数据的验证方法
  14. MicroLib微库和ARM标准C库:usart使用中printf重定向引起的问题
  15. Windows中,ping无法解析域名,nslookup却可解析。此故障的排除思路
  16. Java 判断一个点是否在一个三角形内
  17. 关于快消产品的一点小小认识
  18. 鼠标光标变成了一个点
  19. OMRON NB7触摸屏添加.h头文件
  20. Mopria Print Service现在可用于统一端点管理解决方案

热门文章

  1. 华为鸿蒙手机发布,宣布!魅族携照明类产品加入华为鸿蒙生态
  2. 复旦计算机系本硕连读几年,总算晓得比较好的本硕连读的大学及专业
  3. aslr oracle,Linux (x86) Exploit 开发系列教程之八 绕过 ASLR -- 第三部分
  4. python中的divmod函数_Python中的divmod函数和map函数
  5. 关于Redis事务的介绍
  6. 【CSS】圣杯、双飞翼布局
  7. 12.1 剪贴板的简单用法
  8. mysql 查阻塞_mysql检查阻塞进程
  9. 计算机多了一个用户21cfr,计算机系统验证与 21CFR Part11之间的关系
  10. ssh 错误 ssh: connect to host 192.168.1.106 port 22: Connection refused