基于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 三维曲面数据场动态显示仿真系统展示图
查看本文来源