当前位置:文档之家› OpenGL应用编程接口文档

OpenGL应用编程接口文档

OpenGL1 OpenGL 特点1.建模:OpenGL图形库除了提供基本的点、线、多边形的绘制函数外,还提供了复杂的三维物体(球、锥、多面体、茶壶等)以及复杂曲线和曲面绘制函数。

2.变换:OpenGL图形库的变换包括基本变换和投影变换。

基本变换有平移、旋转、变比镜像四种变换,投影变换有平行投影(又称正射投影)和透视投影两种变换。

其变换方法有利于减少算法的运行时间,提高三维图形的显示速度。

3.颜色模式设置:OpenGL颜色模式有两种,即RGBA模式和颜色索引(Color Inde x)。

4.光照和材质设置:OpenGL光有辐射光(Emitted Light)、环境光(Ambient Ligh t)、漫反射光(Diffuse Light)和镜面光(Specular Light)。

材质是用光反射率来表示。

场景(Scene)中物体最终反映到人眼的颜色是光的红绿蓝分量与材质红绿蓝分量的反射率相乘后形成的颜色。

5.纹理映射(Texture Mapping)。

利用OpenGL纹理映射功能可以十分逼真地表达物体表面细节。

6.位图显示和图象增强图象功能除了基本的拷贝和像素读写外,还提供融合(Blendi ng)、反走样(Antialiasing)和雾(fog)的特殊图象效果处理。

以上三条可使被仿真物更具真实感,增强图形显示的效果。

7.双缓存动画(Double Buffering)双缓存即前台缓存和后台缓存,简言之,后台缓存计算场景、生成画面,前台缓存显示后台缓存已画好的画面。

此外,利用OpenGL还能实现深度暗示(Depth Cue)、运动模糊(Motion Blur)等特殊效果。

从而实现了消隐算法。

2 OpenGL 工作机制∙如何在OpenGL中表示3D物体∙OpenGL 的渲染流水线∙OpenGL中函数的命名规则2.1 OpenGL中3D物体的表示在3D空间中,场景是物体或模型的集合。

在3D图形渲染中,所有的物体都是由三角形构成的。

这是因为一个三角形可以表示一个平面,而3D物体就是由一个或多个平面构成的。

比如下图表示了一个非常复杂的3D地形,它们也不过是由许许多多三角形表示的。

渲染后的地形面貌复杂的地形也是由三角形构成的因此,在OpenGL中,我们只要指定一个或多个三角形,就可以表示任意3D物体。

那么如何指定三角形呢?OpenGL提供三种指定三角形的方法:即单个三角形、三角条形和三角扇形。

指定单个三角形。

这是最简单,最直接的方法。

即调用特定的OpenGL函数,传入三个顶点坐标,指定一个三角形。

如下图:三角条形。

这种方式适合于同时绘制多个三角形,且这些三角形之间至少存在一条公共边。

一个三角条形是在单个三角形的基础上,再指定一个或多个顶点。

这些顶点按照次序同上一顶点一起构成一个新的三角形。

下图演示了这种推进过程。

三角扇形。

三角扇形中,所有顶点按照一个中心点成扇形排列。

如下图,是一个以V1为中心点的三角扇形。

既然使用三角形就可以表示任何图形,为什么还要使用三角条形和三角扇形呢?这是因为在OpenGL渲染流水线中,对于每个顶点都要进行变换运算。

而对于一些连接在一起的三角形组来说,使用三角条形或三角扇形就减少了顶点的数目,这意味着减少了对顶点的运算,因此提高了渲染速度。

例如,上图中第三个三角扇形,该扇形描述了4个三角形。

如果把这四个三角形都一一作为单个三角形传给OpenGL的话,我们需要3*4=12个顶点,而使用了三角扇形之后,我们只使用了6个顶点。

这节约了一半的运算量!2.2 OpenGL 的渲染流水线当我们把要绘制的三角形传给OpenGL之后,OpenGL还要做许多工作以完成3D空间到屏幕的投影。

这一系列的过程被称为OpenGL的渲染流水线。

一般地,OpenGL的渲染流程如下:2.2.1 视图变换当一个场景确定之后,如果我们想移动某个物体,或者要实现场景内的漫游,就必须进行模型视图的变换。

模型视图变换可以根据需要,移动或旋转一个或多个物体。

例如,如果我们想在3D空间中沿着Z轴向前走的话,只需要把所有物体向-Z方向移动n个单位即可。

如果我们要向左看,就应该把所有物体沿着Y轴渲染向右旋转N个角度。

下图演示了这个过程。

2.2.2 背面隐藏在一些封闭的3D物体中,朝着物体内部的面总是不可见的。

对于这些永远不可见的平面,我们可以使用背面隐藏忽略对它的绘制以提高渲染速度。

为了实现背面隐藏,我们在绘制三角形的时候必须注意三角形的绕法。

一般的,OpenGL默认为逆时针缠绕的面是正面。

如下图所示的三角形中,如果把顶点按照V1->V3->V2的顺序传给OpenGL,那么OpenGL就会认为这个三角形朝着屏幕的面是正面。

使用背面隐藏,就要求我们在把图形传给OpenGL的时候要始终遵守正面使用逆时针绕法的规定。

要开启背面隐藏的功能,只需调用函数:glEnable(GL_CULL_FACE);当然,我们也可以改变OpenGL的设置,决定是对物体的正面还是背面进行隐藏。

调用如下函数:glCullFace(GL_FRONT);来隐藏正面,也可调用glCullFace(GL_BACK);来隐藏背面。

2.2.3 光照渲染如果你开启了光照渲染,并且为每个顶点指定了它的法线,在此过程中,OpenGL将根据顶点的法线和光源的位置及性质重新计算顶点的颜色。

使用光照效果可以大大提高画面的真实性。

2.2.4 剪裁剪裁就是把那些不在视见空间,或者一半在可视空间中的物体剔除或剪裁,以保证不该出现在屏幕上的图形就不出现。

2.2.5 投影要把一个3D空间中的物体显示在屏幕上,就要进行投影。

投影又有两种方式:平行投影和透视投影。

在平行投影中,远处的物体和近处的物体是一样大的,这种投影主要运用在计算机辅助设计(CAD)上,由于这种投影没有立体感,所以一般情况下使用透视投影。

在透视投影中,远处的物体会变得较小,因此在透视投影中,可视空间是一个平头截体(或台体)。

下图表明了投影变换的原理。

2.2.6 视见空间变换当3D空间中的图形经过投影成为2D图形之后,我们还要把图形缩放到窗口或屏幕上。

这个过程被称为视见空间变换。

对于一般的游戏来说,视见空间应该是整个屏幕或窗体。

但是视见空间也可以是它的子集。

2.2.7 光栅化当2D图形的所有变换都完成之后,就要把它们栅格化以显示在屏幕上,或保存为BMP 图片。

栅格化其实是把变换得到的2D矢量图转化为位图的过程。

2.2.8 绘制在这一步中,将由Windows GDI把光栅化的图形显示在屏幕上。

2.3 OpenGL的命名规则在OpenGL1.1库中,包含了大约300多个API函数。

为了方便程序员记忆和使用,这些函数都按照一定的规则进行命名。

例如,函数glVertex用于传入顶点数据,而glVertex又有glVertex2i, glVertex3f, glVertex2f, glVertex2d,glVertex3d等变种。

它们各自有什么意义呢?在函数glVertex3i中,"gl"表示当前函数属于OpenGL库。

当然,此前缀如果是"glu",则表示是GLU库(OpenGL辅助库)。

2.4 OpenGL与特定的平台OpenGL被设计为只有输出的,所以它只提供渲染功能。

核心API没有窗口系统、音频、打印、键盘/鼠标或其它输入设备的概念。

虽然这一开始看起来像是一种限制,但它允许进行渲染的代码完全独立于他运行的操作系统,允许跨平台开发。

然而,有些整合于原生窗口系统的东西需要允许和宿主系统交互。

这通过下列附加API实现:* GLX - X11(包括透明的网络)* WGL - Microsoft Windows* AGL - Apple MacOS另外,GLUT库能够以可移植的方式提供基本的窗口功能。

2.5 Window NT系统中的OpenGL使用1.NT系统Windows/System32/opengl32.dll存在2.在头文件内加上:#include <GL/gl.h>#include <GL/glu.h>#include <GL/glaux.h>3.在集成环境中Project | Settings | Link | Object/library module | "opengl32.lib glu32.lib glaux.lib" | OK4.小例子(旋转的正方形)建立win32的普通工程,添入源代码如下:#include"stdafx.h"#include<stdio.h>#include<gl/gl.h>#include<gl/glu.h>#include<gl/glaux.h>static GLfloat spin = 0.0;static GLfloat cx,cy;void CALLBACK renderScene(){glClear(GL_COLOR_BUFFER_BIT); // 清除缓存glPushMatrix(); // 当前矩阵压栈glTranslated(cx,cy,0); // 移动视点glRotatef(spin, 0.0, 0.0, 1.0); // 旋转视点glColor3f(1.0, 0.0, 0.0); // 设置颜色glRectf(-25.0, -25.0, 25.0, 25.0); // 绘制矩形glPopMatrix(); // 还原当前矩阵glFlush(); // 强制命令执行auxSwapBuffers(); // 交换缓存,输出显示void CALLBACK changeSize(GLsizei w, GLsizei h){if (h == 0){h = 1;}if (w == 0){w = 1;}glViewport(0, 0, w, h); // 设置视图尺寸cx = w/2;cy = h/2;glLoadIdentity();if (w <= h){glOrtho(0.0, 250.0, 0.0, 250.0*h/w, 1.0, -1.0); // 设置投影矩阵 cx = 125.0;cy = 125.0*h/w;}else{glOrtho(0.0, 250.0*w/h, 0.0, 250.0, 1.0, -1.0); // 设置投影矩阵 cx = 125.0*w/h;cy = 125.0;}}void CALLBACK spinDisplay(){spin += 2.0;if (spin > 360.0){spin -= 360.0;}renderScene(); // 渲染输出void CALLBACK leftBtnClick(AUX_EVENTREC *event){auxIdleFunc(spinDisplay); // 左键动画}void CALLBACK rightBtnClick(AUX_EVENTREC *event){auxIdleFunc(NULL); // 右键停止动画}int _tmain(int argc, _TCHAR* argv[]){auxInitDisplayMode(AUX_SINGLE|AUX_DOUBLE); // 初始化显示模式auxInitPosition(100,100,250,250); // 初始化显示位置auxInitWindow(_T("My first OpenGL program")); // 初始输出化窗口cx = 125;cy = 125;glClearColor(0.0, 0.0, 0.0, 0.0);glShadeModel(GL_FLAT); // 明暗处理设置auxReshapeFunc(changeSize); // 设置尺寸变化处理函数auxMouseFunc(AUX_LEFTBUTTON, AUX_MOUSEDOWN, leftBtnClick); // 设置鼠标左键处理函数 auxMouseFunc(AUX_RIGHTBUTTON, AUX_MOUSEDOWN, rightBtnClick); // 设置鼠标右键处理函数 auxMainLoop(renderScene); // 进入主循环printf("Press anykey to return!");getchar();return 0;}OpenGL ES1 OpenGL 特点和桌面Windows的3D应用一样,移动设备也需要API的支持。

相关主题