基于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)是实现动态显示的必不可少的操作。
voidCNurbsView::Onhuitu()
{
HWND hWnd=GetSafeHwnd();
HDChDC=::GetDC(hWnd);
wglMakeCurrent(hDC,hglrc);//设置当前着色表
drawsurbs();//动态显示三维曲面子程序
wglMakeCurrent(NULL,NULL);//着色表非当前化
SwapBuffers(hDC);//交换缓存
}
{
……
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根据数据场的分布进行三维曲面的动态显示是切实可行的,尤其采用双缓存及显示列表技术可以得到很好的三维曲面生成速度,这种动态显示技术可以推广应用在需要进行实时动态显示的数据处理方面。
基于OpenGL的三维曲面动态显示原理
1、基于OpenGL三维曲面图形显示原理
OpenGL是独立于操作系统的开放式三维图形软件接口。其主要功能是将三维曲面通过顶点序列或像素点进行描述,并进行相应的透视、光照、纹理操作,最终转换成帧缓存中的图像数据,利用该图像数据进行三维曲面图形的着色。三维曲面图形显示归纳为以下几个步骤:
(1)在三维场景中建立曲面绘制的模型。选用插值方法、参数曲面函数,计算曲面控制点,进行曲面重构;
(2)设置视点和透视方式;
(3)进行消隐、光照、纹理、明暗处理;
(4)绘制场景,输出到屏幕窗口。

图2 三维曲面图形显示基本流程
2、利用双缓存实现动态显示原理
三维曲面动态显示需要连续地绘制三维曲面并显示场景,用不同的曲面数据刷新屏幕视窗。
在OpenGL中利用双缓存技术,分配两个帧缓存区,在连续显示三维曲面时,一个帧缓冲区中的数据执行绘制曲面命令的同时,另一个帧缓存区中的数据进行图形显示。当前可见视频缓存称为前台视频缓存,不可见的正在绘图的视频缓存称为后台视频缓存。当后台视频缓存中的数据要求显示时,OpenGL就将它拷贝至前台视频缓存,显示硬件不断地读可见视频缓存中的内容,并把结果显示在屏幕上。
应用双缓存,每一帧三维曲面只在绘制完成之后才显示出来,所以观察者可以看到每一帧完整三维曲面,而不是曲面的绘制过程。
使用双缓存实现三维曲面动态显示的步骤如下:
(1)设置OpenGL窗口显示属性为双缓存机制:auxInitDisplayMode(AUX_DOUBLE|AUX_RGBA);
(2)利用OpenGL基本绘图命令绘制三维曲面;
(3)一帧曲面绘图结束后缓存拷贝,切换缓存:auxSwapBuffers();
SwapBuffers(wglGetCurrentDC());
3、利用显示列表提高程序运行效率
显示列表是一组预先存储起来留待以后调用的函数语句。调用显示列表时就按次序执行其中的函数。显示列表将反复执行的绘图操作以编译好的命令方式进行存储,设计成命令的高速缓存,而不是动态的数据库缓存,所以可以优化程序运行性能。
实现和调用显示列表的方法:
(1)创建列表:
voidglNewList(Gluint list,Glenm mode);
voidglBegin(Glenum mode);
voidglEnd(void);
voidglEndList();
(2)调用列表:
voidglCallList(Gluint list);
CSDN 2015-05
基于OpenGL的三维曲面动态显示实现的更多相关文章
- 基于OpenGL三维软件开发
		实验原理: OpenGL在MFC下编程原理---- Windows操作系统对OpenGL的支持 在Windows下用GDI作图必须通过设备上下文(DeviceContext简写DC)调用相应的函数:用 ... 
- 学习基于OpenGL的CAD程序的开发计划(一)
		本人目前从事的工作面对的客户中很多来自高端制造业,他们对CAD/CAE/CAM软件的应用比较多.公司现有的软件产品主要是用于渲染展示及交互,但面对诸如CAD方面的应用(比如基于约束的装配.制造工艺的流 ... 
- MATLAB三维曲面
		今天终于测试了,发下来第一张试卷中只会做一小题.我蒙了!!! 所以呢,我现在再做一下,总结总结! 作函数 f(x)=2(x1-1)4+2x22 的三维图. 这道题要用到的知识点有函数meshgrid. ... 
- Matlab绘图基础——一些标准三维曲面
		标准三维曲面 t=0:pi/20:2*pi; [x,y,z]= cylinder(2+sin(t),30); %[x,y,z]= cylinder(R,n),其中R为圆周半径,n为组成圆周的点 ... 
- Matlab绘制三维曲面(以二维高斯函数为例)
		原文地址为:Matlab绘制三维曲面(以二维高斯函数为例) 寒假学习了一下Python下的NumPy和pymatlab,感觉不是很容易上手.来学校之后,决定继续看完数字图像处理一书.还是想按照上学期的 ... 
- 基于WebGL的三维的物联网平台技术
		参加工作三年了,从一个搞调试的民工进阶为程序员,收获还是有那么一点的.慢慢讲一些. 去年在网上发现了https://hightopo.com/cn-index.html图扑软件的基于WebGL的三维j ... 
- 基于OpenGL编写一个简易的2D渲染框架-05 渲染文本
		阅读文章前需要了解的知识:文本渲染 https://learnopengl-cn.github.io/06%20In%20Practice/02%20Text%20Rendering/ 简要步骤: 获 ... 
- 基于SceneControl的三维GIS开发
		在ArcGIS体系中,三维开发包括两种:基于Scene的三维开发和基于Globe的三维开发. 由上图可以看出,两种开发的接口都很相似,掌握了Scene开发会相对容易的过渡到Globe开发中. 正如上图 ... 
- 基于Opengl的太阳系动画实现
		#include <GL\glut.h> float fEarth = 2.0f;//地球绕太阳的旋转角度float fMoon = 24.0f;//月球绕地球的旋转角度 void Ini ... 
随机推荐
- django bms
			1. 创建模型 一对多: 需要在""多""的表创建一个""关键字段"" 关联 就像在mysql的哪项少的比如(书与出版 ... 
- python基础之一:input、if、while
- Windows server 2003 粘滞键后门+提权
			Windows server 2003中可以建立粘滞键与cmd的连接来绕过已经设置好的安全机制做一些事情,比如新建用户.提权 粘滞键介绍 网上查了一些资料,也没怎么说明白,不如自己试一下,大概意思就是 ... 
- zzulioj - 2624: 小H的奇怪加法
			题目链接:http://acm.zzuli.edu.cn/problem.php?id=2624 题目描述 小H非常喜欢研究算法,尤其是各种加法.没错加法包含很多种,例如二进制中的全加,半加等.全加: ... 
- Java实现递归阶乘
			public class Factorial{ public static void main(String[] args){ for (int i = -5; i <= 5; i++) { S ... 
- CF1174E Ehab and the Expected GCD Problem(DP,数论)
			题目大意:对于一个序列,定义它的价值是它的所有前缀的 $\gcd$ 中互不相同的数的个数.给定整数 $n$,问在 $1$ 到 $n$ 的排列中,有多少个排列的价值达到最大值.答案对 $10^9+7$ ... 
- 第02组 团队Git现场编程实战
			目录 1. 组员职责分工(2分) 2. github 的提交日志截图(1分) 3. 程序运行截图(3分) 4. 程序运行环境(1分) 5. GUI界面(5分) 6. 基础功能实现(10分) 7. 鼓励 ... 
- centos gcc编译
			centos上面的gcc是4.x的,因为我们使用了c++17,所以想升级成最新的gcc 1. 下载源码 https://gcc.gnu.org/index.html 2. 下载下来是.tar.xz,因 ... 
- 在ensp上通过FTP进行文件操作
			接下来的实验,我们使PC-1为用户端,需要访问FTP Server,不允许用户端上传到server. 在R1上员工不能上传文件到server,但是可以下载文件.同时R1也需要作为用户端从server下 ... 
- Lua table的remove函数
			[1]remove函数简介 table.remove(table, pos): 返回table数组中位于pos位置的元素,其后的元素会被前移. pos参数可选, 默认为table长度, 即从最后一个元 ... 
