1、OpenGL简介

1、OpenGL概览

  OpenGL (英文:Open Graphics Library,译名:开放式图形库)是个专业的图形程序接口,是用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口(API)。这个接口由近350个不同的函数调用组成,用来从简单的图形比特绘制复杂的三维景象。1

在这里插入图片描述

图1-1 OpenGL logo

  OpenGL规范描述了绘制2D和3D图形的抽象API。尽管这些API可以完全通过软件实现,但它是为大部分或者全部使用硬件加速而设计的。

  OpenGL的程序编程接口(API)定义了若干个可被客户端程序调用的函数(例如:WINGDIAPI void APIENTRY glBegin(GLenum mode);),以及一些具名整型常量(例如,常量GL_LINES对应的十六进制数为0x0001)。虽然这些函数的定义表面上类似于C编程语言,但它们是语言独立的。即OpenGL可以与很多编程语言进行绑定,例如:C语言绑定的WGL、GLX和CGL;JavaScript绑定的WebGL(基于OpenGL ES 2.0在Web浏览器中的进行3D渲染的API)等。

WebGL

图1-2 WebGL logo

  OpenGL也是一个不断进化的API。新版的OpenGL规范会定期由Khronos Group发布,新版本通过扩展API来支持各种新功能。每个版本的细节由Khronos Group的成员一致决定,包括一些GPU厂商、显卡厂商、操作系统设计人员以及类似Mozilla和谷歌的一般性技术公司。


2、相关网站


3、相关开发库

OpenGL函数库中的函数一般命名方式如下:

<库前缀><根命令><可选的参数个数><可选的参数类型>

  其中库前缀主要描述所属函数属于那个开发库,根命令主要描述函数的主要功能,可选的参数个数即函数的形参有几个,可选的参数类型描述形参的参数属于float、double或int等类型。

表 3-1 OpenGL函数后缀和参数数据类型
后缀数据类型C语言类型OpenGL类型定义
b8位整数singned charGLbyte
s16位整数shortGLshort
i32位整数int 或 longGLint,GLsizei
f32位浮点数floatGLfloat,GLclampf2
d64位浮点数doubleGLdouble,GLclampd3
ub8位无符号整数unsigned charGLubyte,GLboolean4
us16位无符号整数unsigned shortGLushort
ui32位无符号整数unsigned int 或 unsigned longGLuint,GLenum,GLbitfield

在OpenGL的日常开发中一般会使用到以下几个库:

1、核心库(gl):

  核心库包含的函数名前缀为 gl ,这部分函数用于常规的、核心的图形处理。根据处理对象、处理方式的不同派生出来的函数原形多达 300 多个。gl.h 核心库中的函数主要可以分为以下几类:

  • 基本图元绘制类函数:
    主要完成基本图元(点、线、三角形、四边形等)的绘制,包括:glBegain() 、 glEnd() 、 glNormal*() 、 glVertex* ()2 等 ;
  • 矩阵操作、几何变换和投影变换类函数:
    主要完成一些矩阵计算、压栈、出栈、几何变换、投影变换等,包括的函数有:glMatrixMode()、glLoadIdentity()、glLoadMatrix()、glPushMatrix()、glPopMatrix()、glMultMatrix()、glTranslate*()、glRotate*() 、glScale*() 、 glOrtho() 、 glFrustum() 、 glViewport() 等;

  • 光照材质及颜色设置类函数:
    主要完成光照效果和材质效果及颜色设置,包括的函数有:glLight*() 、 glLightModel*()、glMaterial() 、glColor*() 、 glIndex*()等;

  • 显示列表类函数:
    主要完成显示列表的创建、调用、结束、生成和删除,包括的函数有:glNewList()、 glCallList() 、glEndList() 、 glGenLists() 和 glDeleteLists() ;

  • 纹理类函数:
    主要有一维纹理函数: glTexImage1D() 、二维纹理函数 :glTexImage2D() 、设置纹理参数:glTexParameter*() 、纹理环境:glTexEnv*() 和纹理坐标的函数 : glTetCoord*() 等;

  • 光栅化、像素操作类函数:
    主要包括的函数有像素位置设置 glRasterPos*() 、线型宽度设置 glLineWidth() 、多边形绘制模式设置 glPolygonMode() ,读取像素 glReadPixel() 、复制像素 glCopyPixel() 等;

  • 状态设置与查询函数:
    glEnable() 、glDisable()、 glGetError()、glGet*() 等;

  • 特殊效果函数:
    混合函数效果 glBlendFunc() 、反走样函数 glHint() 和雾化效果 glFog*() 等;

2、实用库(glu):
  实用库顾名思义,提供一些非常实用的 API 接口供用户调用。由于使用 OpenGL 绘制场景时都必须从最基本的图元(点、线、三角形)开始绘制,在开发过程中难免会浪费时间,glu 实用库为了减轻编程工作者的工作量,将 OpenGL 的一些接口进行了封装,用户可以通过调用 glu 中的函数接口来完成相对复杂的处理或变换,glu 库中还提供了许多建模的功能,例如二次曲面以及NURBS曲面和表面等,实用库中的函数使用 glu 为前缀,便于和核心库进行区分。

  glu 库中的函数接口大致可以分为以下几个部分:

  • 坐标转换和投影变换函数:
    定义投影方式函数 gluPerspective() 、 gluOrtho2D() 、 gluLookAt() ,拾取投影视景体函数 gluPickMatrix() ,投影矩阵计算 gluProject() 和 gluUnProject() ;

  • 多边形镶嵌及网格化工具:
    主要完成镶嵌多边形的一些操作,包括建立、删除多边形、定义顶点、法向量等操作,gluNewTess() 、 gluDeleteTess() 、 gluTessCallback() 、 gluBeginPolygon() 、 gluTessVertex() 、 gluNextContour() 、 gluEndPolygon() 、gluTessBeginContour 、gluDeleteTess、gluTessNormal;

  • 二次曲面绘制工具:
    主要有绘制球面、锥面、柱面、圆环面 gluNewQuadric() 、 gluSphere() 、 gluCylinder() 、 gluDisk() 、 gluPartialDisk() 、 gluDeleteQuadric() ;

  • 绘制二次几何物体工具:
    主要用来定义和绘制 Nurbs 曲线和曲面,包括 gluNewNurbsRenderer() 、 gluNurbsCurve() 、 gluBeginSurface() 、 gluEndSurface() 、 gluBeginCurve() 、 gluNurbsProperty() ;

  • 错误反馈及查询工具:
    获取出错信息的字符串 gluErrorString()、得到一个NURBS属性:gluGetNurbsProperty(),得到一个描述GLU版本号或支持GLU扩展调用的字符串:gluGetString(),得到一个镶嵌对象:gluGetTessProperty() 。

  • 多重映射工具
    建立一维多重映射:gluBuild1DMipmaps,建立二维多重映射:gluBuild2DMipmaps等

3、实用工具库(glut):
  实用工具库包含大约 30 多个函数,包含的函数以 glut 为前缀,由 Mark KLilgrad 在 SGI 编写(现在在Nvidia)。glut 工具包的使用是不依赖于窗口平台的 OpenGL 工具包,它提供更为复杂的绘制功能,目在于隐藏不同窗口平台 API 的复杂度。由于 glut 中的窗口管理函数是不依赖于运行环境的,因此OpenGL中的工具库可以在 Windows、MacOS 等系统下运行,特别适合于开发不需要复杂界面的 OpenGL 示例程序。

  glut 库中的函数接口大致可以分为以下几个部分:

  • 初始化和启动事件处理类函数:

  • 窗口管理类函数:

  • 重叠层管理类函数:

  • 菜单管理类函数:

  • 注册回调函数类函数:

  • 颜色索引、状态检索和映射表管理类函数:

  • 绘制类函数:

4、辅助库(glaux):

  辅助库函数名前缀为 aux ,这部分函数提供对 OpenGL 基本的窗口管理、输入输出处理以及绘制一些简单三维物体。 由于aux 库在 Windows 上的兼容性问题实现有很多错误,因此很容易导致程序频繁的崩溃。aux 库在很大程度上已经被 glut 库取代。

5、轻量级工具程序库(GLFW):

  GLFW 是配合 OpenGL 使用的轻量级工具程序库,缩写自 Graphics Library Framework(图形库框架)。GLFW 的主要功能是创建并管理窗口和 OpenGL 上下文,同时还提供了处理手柄、键盘、鼠标输入的功能。GLFW 库具有很好的兼容性,可以在 Windows、Linux、MacOS 等系统上完美运行。

6、扩展库(GLEW):
  OpenGL Extension Wrangler Library(GLEW)是跨平台的开源 C/C ++ 扩展加载库。 GLEW提供了有效的运行时机制,它能自动识别当前平台所支持的全部 OpenGL 高级扩展函数。只要包含 glew.h 头文件,就能使用 gl、glu、glext、wgl、glx 的全部函数。 GLEW 已在各种操作系统上进行了测试,包括Windows,Linux,MacOS X等。

7、其他扩展库:

  由于 OpenGL 扩展需要针对不同平台和不同驱动都适用, 不可能将所有的 API 接口程序全部放到标准库中,所以就诞生了其他一些扩展库,当然硬件厂商还需要根据自己的需要开发支持特定系统的 OpenGL 扩展库。


4、状态机

  OpenGL是一个状态机。在使用OpenGL的过程中,可以根据当前程序绘图的需要来设置绘图的不同状态(或模式),之后可以一直保持这个模式,直到被修改。例如:颜色的修改,当前的颜色是一个状态变量,它可以被修改为白色、红色、黑色等其他任何颜色,在设置成功之后,所绘制的所有图形都会是这个颜色,直到被修改为其他颜色。
  当然不止颜色这一种状态变量,另外还包括当前视图和投影变换、多边形绘图模式、光照位置、绘制的图形的材质等等。通常会使用glEnable()和glDisable()来对当前的一些状态变量进行修改,确定状态是否开启和关闭。


5、OpenGL渲染管线

  下图 5-1 是美国福特公司采用的渲染方式,当然这也是OpenGL进行数据处理的方法。OpenGL最初的数据包括两部分,第一部分是几何数据(顶点、线、多边形),它经过的处理阶段有求值器和基于顶点的操作与基本装配,之后通过光栅化以及片段操作写入到帧缓冲区。第二部分是像素数据(像素、纹理图像、位图等),它的处理方式是先经过像素操作,之后经过光栅化、片段操作后写入到缓冲区(若存在纹理图片,在光栅化之前会进行纹理装配)。

渲染管线

图5-1 OpenGL渲染管线

5.1、显示列表

  在OpenGL中,不管是像素数据还是顶点数据都可以保存在显示列表(display list)中,它相当于将一部分绘图通过OpenGL的函数调用,转换成绘图数据保存下来,之后在需要它的地方,只用调用这个显示列表就行,例如:想要绘制一片森林,就可以使用显示列表。森林是由一棵棵的树组成,可以将一棵树的绘图数据用OpenGL的显示列表保存起来,再通过调用显示列表来绘制着一片森林。虽然看着这一绘制过程比较繁琐,不如一次性直接绘制,但是显示列表最初已经将绘图函数转换成OpenGL的绘图数据了,这里省下了从OpenGL函数到绘图数据转换的过程,虽然这个时间也很短,但是当绘制相同的图形,并且数量很多时,使用显示列表绘制和直接绘制之间的时间差距还是很大的。显示列表最初就是用来降低绘制时间,提高绘图性能的。

5.2、求值器

  在图形绘制的最底层硬件往往是通过简单的点、线、多边形来绘制复杂的图形,一个平滑的曲线或表面往往也是通过使用大量的微小线段或多边形来模拟的。OpenGL求值器简单来说,它提供一种方式,可以通过少数的控制点来指定曲线或表面(或其中的一部分)上的点,然后就可以使用控制点按照任意精度来渲染曲线或表面。当然求值器还提供自动计算法向量。可以按照多种方式使用求值器返回的点,例如绘制点状表面、线框表面等。

5.3、像素操作

  OpenGL的渲染管线中,像素数据和单路径的几何数据相比,处理过程略有不同。像素数据首先会从内存中提取出来进行解包,从一种格式解包为适当的数据类型,接着会根据一副像素图对接报后的数据进行缩放、偏移等操作。处理的结果会写入到纹理内存或者直接发送到光栅化阶段。

5.4、基于顶点的操作

  顶点数据通过求值器后会进入基于顶点的处理阶段,会将顶点变换为图元。实际的绘图中往往会很复杂,当开启顶点的雾、光照、法线、材质属性等信息,这个阶段将会变得非常“忙碌”,这个阶段会将这些信息进行一一计算之后再进行下一步操作。如果绘图中还开启了纹理,这个阶段还将生成并变换纹理坐标。

5.5、图元装配

  在图元装配阶段主要完成裁剪操作,它会将半空间之外的那部分几何图元进行消除,这个半空间是有一个平面所指定。其中点裁剪是简单地接受或者拒绝绘制顶点,直线或多边形裁剪则有可能会添加一些额外顶点,具体会取决于直线或多边形是如何裁剪的。
  当然还有一些特殊情况下会进行透视除法的步骤。透视除法会将远处的物体绘制的比近处的物体小。图元装配阶段产生的结果就是根据之前设置的颜色、深度(或者纹理坐标以及光栅化等指导信息)进行了变换、裁剪之后的图元顶点。

5.6、光栅化

  OpenGL中的光栅化是将几何数据和像素数据转换为片段(fragment)的过程,帧缓冲区中的每一个像素都会对应有一个片段方块。

5.7、纹理装配

  OpenGL绘图可以将纹理图片应用在几何物体上,这样会使几何物体看上去更加的逼真,纹理贴图能够保证当这个多边形进行变换或者渲染时,映射到多边形表面的图像表现正确。纹理贴图可以应用到所有的图元,当然在进行纹理贴图的过程中必然会有一定的复杂性。

5.8、片段操作

  在绘图数据存储至帧缓冲区之前,会执行一系列的操作,这些操作会产生或丢弃一部分片段。在片段操作之前的操作完成并产生对应的颜色和深度之后,将会进行一系列开启的测试(例如:裁剪测试、Alpha测试、模板测试、深度测试等),若某种测试失败,将会直接丢弃这部分片段。在完成这一系列测试工作之后,经过完整测试操作的片段就会被绘制到适当的缓冲区,最终形成像素。


🍤
💿
🔥


  1. 摘自维基百科 ↩︎

  2. 这里的 “ * ” 指的是存在相同作用的函数,只是适用的场合不同,例如 glVertex3f() 和 glVertex2f(),前者使用在三维坐标系中,后者使用在二维坐标系中,效果都是绘制一个点; ↩︎ ↩︎

  3. 用于将多个布尔值(最多32个)打包到单个使用位操作变量的四字节整型。 ↩︎

  4. 用于布尔值 ↩︎

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值