zoukankan      html  css  js  c++  java
  • 基于OpenGL的三维曲面动态显示实现

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

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

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

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

    #include"glgl.h"  #include "glglu.h"  #include "glglaux.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

  • 相关阅读:
    《Programming WPF》翻译 第8章 1.动画基础
    一些被遗忘的设计模式
    《Programming WPF》翻译 第4章 数据绑定
    《Programming WPF》翻译 第3章 控件
    《Programming WPF》翻译 第5章 样式和控件模板
    《Programming WPF》翻译 第7章 绘图
    《Programming WPF》翻译 第9章 自定义控件
    《Programming WPF》翻译 第7章 绘图 (2)
    《Programming WPF》翻译 第8章 前言
    关于Debug和Release之本质区别
  • 原文地址:https://www.cnblogs.com/arxive/p/11748228.html
Copyright © 2011-2022 走看看