绘图工具箱

  • 设置当前清除颜色,用于清除RGBA模式下的颜色缓冲区, red、green、blue、alpha值会根据需要进行截取,值范围限定在[0,1]之内,默认清除的颜色是(0,0,0,0),也就是黑色。
WINGDIAPI void APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
  • 用当前的缓冲区清除值清除指定的缓冲区。mask参数的值如下所示进行位逻辑或者组合。
缓冲区 名称
颜色缓冲区 GL_COLOR_BUFFER_BIT
深度缓冲区 GL_DEPTH_BUFFER_BIT
累积缓冲区(兼容性扩展) GL_ACCUM_BUFFER_BIT
模板缓冲区 GL_STENCIL_BUFFER_BIT
WINGDIAPI void APIENTRY glClear (GLbitfield mask)

注意:除了使用glClearColor()和glCrearDepth()函数之外,还可以使用glClearIndex()、glClearAccum() 和 glClearStencil()函数设置用于清除相应的颜色索引、累计颜色、模板索引值。

指定颜色

WINGDIAPI void APIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue);

强制完成绘图操作

  • 强制以前发出的OpenGL命令开始执行,因此保证他们能够在有限的时间内完成

    WINGDIAPI void APIENTRY glFlush (void);
    
  • 强制以前发出的OpenGL命令完成执行,在以前命令完成执行之前,这个函数并不会返回

    WINGDIAPI void APIENTRY glFinish (void);
    

坐标系统工具

  • glViewport() 函数调整用于绘图的像素矩阵,他占据整个新窗口。后面3个函数调整用于绘图坐标系统,是左下角的坐标是(0, 0),左上角是(w, h)
WINGDIAPI void APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
WINGDIAPI void APIENTRY glLoadIdentity (void);
void APIENTRY gluOrtho2D (
    GLdouble left, 
    GLdouble right, 
    GLdouble bottom, 
    GLdouble top);

描述点、执行和多边形

  • 绘制由角顶点(x1, y1) 和 (x2, y2) 定义矩形,这个矩形位于 z = 0 的平面上,并且他的边与 x 和 y 轴 平行,如果使用了这个函数的向量形式,角顶点是由两个数组指针指定的,他们分别包含一对(x, y) 坐标值。
WINGDIAPI void APIENTRY glRect{sifd} (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2);
WINGDIAPI void APIENTRY glRect{sifd}v (const GLdouble *v1, const GLdouble *v2);
  • 指定了一个用于描述几何物体的顶点,可以选择这个函数适合的版本,既可以图为一个顶点提供多达4个的坐标(x, y, z, w), 也可以只提供2个坐标(x, y)。如果选择的函数版本并没有显示地指定z 和 w, z 就会当作 0, w则默认位1。 glVertex*()函数只有当他位于glBegin 和 glEnd 之间时才会有效。
WINGDIAPI void APIENTRY glVertex[234]{sifd} (GLdouble x, GLdouble y, GLdouble z);
WINGDIAPI void APIENTRY glVertex[234]{sifd}v (const GLdouble *v);

OpenGL几何图元

  • 标志着一个顶点数据列表的开始,他描述了一个几何图元, mode参数指定图元类型。
    WINGDIAPI void APIENTRY glBegin (GLenum mode);
    
含义
GL_POINTS 单个点
GL_TRIANGLES 3个顶点被解释为三角形
GL_TRIANGLE_STRIP 三角形连接成串
GL_TRIANGLE_FAN 连接扇形的三角形系列
GL_LINE 一对顶点被解释成直线
GL_LINE_STRIP 一系列连接直线
GL_LINE_LOOP 一系列连接直线,第一个点和最后一个点彼此相连
GL_QUADS 4个顶点被解释为四边形
GL_QUAD_STRIP 四边形的连接串
GL_POLYGON 简单的凸多边形的边界
  • 标志着一个顶点数据列表的结束
WINGDIAPI void APIENTRY glEnd (void);
  • 使用 glBegin() 和 glEnd() 的限制
函数 作用
glVertex*() 设置顶点坐标
glColor*() 设置RGBA 颜色
glIndex*() 设置颜色的索引
glSecondaryColor*() 设置纹理应用
glNormal*() 设置法线向量坐标
glMaterial*() 设置材料属性
glFog*() 设置雾坐标
glTexCoord*() 设置纹理坐标
glMultiTexCoord*() 为多重纹理设置纹理坐标
glVertexAttrib*() 设置通用的顶点属性
glEdgeFlag*() 控制边界绘制
glArrayElement() 提取顶点数组数据
glEvalCoord() glEvalPoint() 生成坐标
glCallLists() glCallList() 执行显示列表

基本状态管理

  • glEnable() 启用一个功能, glDisable()用于关闭一个功能。
WINGDIAPI void APIENTRY glEnable (GLenum cap);
WINGDIAPI void APIENTRY glDisable (GLenum cap);
  • 根据当前的状态查询处于禁用还是启用状态
    WINGDIAPI GLboolean APIENTRY glIsEnabled (GLenum cap);
    WINGDIAPI void APIENTRY glGetBooleanv (GLenum pname, GLboolean *params);
    WINGDIAPI void APIENTRY glGetIntegerv (GLenum pname, GLint *params);
    WINGDIAPI void APIENTRY glGetFloatv (GLenum pname, GLfloat *params);
    WINGDIAPI void APIENTRY glGetDoublev (GLenum pname, GLdouble *params);
    WINGDIAPI void APIENTRY glGetPointerv (GLenum pname, GLvoid* *params);
    

显示点、直线和多边形

  • 设置被渲染点的宽度,以像素为单位,size 必须大于0,在默认情况下是1.0
WINGDIAPI void APIENTRY glPointSize (GLfloat size);
  • 以像素位单位设置宽度,用于直线渲染。width参数必须大于0.0,在默认情况下为1.0,OpenGL3.1不支持大于1.0的值,否则将会产生一个GL_INVALID_VALUE的错误。
WINGDIAPI void APIENTRY glLineWidth (GLfloat width);
  • 设置直线的当前点画模式。pattern参数是由1和0组成的16为序列。他们根据需要进行重复,对一条特定的直线进行点画处理。从这个模式的低位开始,一个像素一个像素进行处理,如果模型中对应的位是1,就绘制这个像素,否则就不绘制这个像素。模式可以使用factor参数(表示重复因子)进行扩展,他与1和0的连续序列相乘,因此,如果模式中出现了连续3个1,并且factor是2,那么他们就扩展6个连续的1,必须以GL_LINE_STIPPLE为参数调用glEnable()才能启用点画直线功能。
WINGDIAPI void APIENTRY glLineStipple (GLint factor, GLushort pattern);
  • 控制一个多边形的正面和背面的绘图模式face参数可以是GL_FRONT_AND_BACK,GL_FRONT,GL_BACK,mode参数可以是GL_POINT,GL_LINE,GL_FILL,表示多边形应该被画成点,轮廓,还是填充模式,默认情况下都是填充模式。 OpenGL3.1只接受控制一个多边形的正面和背面的绘图模式face参数可以是GL_FRONT_AND_BACK作为face的值,并且不管是多边形的正面还是背面都以相同的方式渲染。
WINGDIAPI void APIENTRY glPolygonMode (GLenum face, GLenum mode);
  • 控制多边形正面如何决定,默认情况下mode是GL_CCW,他表示窗口坐标上投影多边形顶点顺序位逆时针表面为正面。如果mode是GL_CW,顶点顺序为顺时针的表面认为是正面。
WINGDIAPI void APIENTRY glFrontFace (GLenum mode);

注意:顶点的方向(顺时针和逆时针)又称为环绕

  • 表示那些多边形在转换到屏幕坐标之前应该丢弃(剔除),mode参数可以是GL_FRONT,GL_BACK,GL_FRONT_AND_BACK,分别表示正面多边形。背面多边形和所有多边形,为了是剔除生效,必须以GL_CULL_FACE为参数调用glEnable()来启动剔除功能,相反就调用glDisable()函数来关闭
WINGDIAPI void APIENTRY glCullFace (GLenum mode);
  • 定义填充多边形当前点画模式mask参数是一个指向 32 32 的位图指针后者被解释为0和1的掩码,如果是1就绘制对应的像素,否在就不绘制。可以使用 GL_POLYGON_STIPPLE 为参数调用函数 glEnable() 和 glDisable() 函数来启动和关闭多边形点画功能。mask数据的解释受到glPixelStore() GL_UNPACK*模式的影响。
WINGDIAPI void APIENTRY glPolygonStipple (const GLubyte *mask);
  • 表示一个顶点是否应该被认为是多边形的一条边界的起点,如果flag是GL_TRUE,边界标之就设置为GL_TRUE(默认)。在此之后创建所有顶点都认为是边界边的起点,直到用GL_FLASE为flag 参数的值再次调用这个函数。
WINGDIAPI void APIENTRY glEdgeFlag (GLboolean flag);
WINGDIAPI void APIENTRY glEdgeFlagv (const GLboolean *flag);

法线向量

  • 根据参数设置当前的法线向量,这个函数非向量版本(没有v)接收3个参数,把一个(nx,ny,nz)向量指定为法线向量,此外,还可以使用带向量的版本(带v),并提供一个包含3个元素的数组来指定所需要的法线向量。b、i和s版本的函数会对他们的参数进行线性缩放,是他们位于范围[-1.0, 1.0]之间。
glNormal3{bsidf}(GLfloat nx, GLfloat ny, GLfloat nz);
glNormal3{bsidf}v(const GLfloat *v);

注意:法线向量只表示方向,因此和他的长度无关。法线可以指定任意长度,但是在执行光照计算之前,他的长度会转为1(长度为1的向量称为单位向量或者规范化的向量)。一般而言,为了使一条法线具有单位长度,只要把他的每个 x,y,z 分别除以法线的长度就可以了。

L = sqrt{X^2 + Y^2 + Z^2}

OpenGL会自动对法线向量进行规范化,为了使用这个功能可以调用glEnable(GL_NORMALIZE)。如果提供了单位长度的法线。并且只能均匀的缩放(x,y,z使用相同的缩放因子)。

注意:自动规范化和重新缩放一般需要额外的计算,因此可能降低应用程序的性能。用GL_RESCALE_NORMAL对法线均匀的缩放通常要比使用GL_NORMALIZE进行完整的规范化开销更少,在默认的情况下,法线的自动化规范和重新操作都是禁用的。

顶点数组

  • 使用顶点数组对几何图形进行渲染需要3个步骤:
  1. 激活(启用)最多可达8个数组,每个数组用于存储不同类型的数据:顶点坐标,表面法线,RGBA颜色,辅助颜色,颜色索引,雾坐标,纹理坐标以及多边形的边界标志。
  2. 把数组存放在数组中,这些数组是通过他们的内存地址(即指针)进行访问。在客户机-服务器模型中,这些数组存放在客户机的地址空间中。
  3. 用这些数据绘制几何图形,OpenGL通过指针从所有的被激活的数组中获取数据,在客户机-服务器模型中,数据被传输到服务器的地址空间中,由3中方式可以完成这个任务
    1) 访问单独的数组元素(随机存取)
    2) 创建一个单独的数组元素的列表(系统存取)
  • 启用数组
  1. 指定需要启用的数组,array参数可以使用下面这些符号常量:GL_VERTEX_ARRAY GL_COLOR_ARRAY GL_SECONDARY_COLOR_ARRAY GL_INDEX_ARRAY GL_NORMAL_ARRAY GL_FOG_COORDINATE_ARRAY GL_TEXTURE_COORD_ARRAY GL_EDGE_FLAG_ARRAY
WINGDIAPI void APIENTRY glEnableClientState (GLenum array);
  1. 指定了需要禁用的数组,接受参数和glEnableClientState相同
WINGDIAPI void APIENTRY glDisableClientState (GLenum array);
  • 指定数组的数据
  1. 指定了需要访问的空间坐标数据,pointer是数组包含的第一个顶点的第一个坐标的内存地址,type制定了数组中每个坐标的数据类型。
WINGDIAPI void APIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
WINGDIAPI void APIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
WINGDIAPI void APIENTRY glSecondColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
WINGDIAPI void APIENTRY glIndexPointer (GLenum type, GLsizei stride, const GLvoid *pointer);
WINGDIAPI void APIENTRY glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer);
WINGDIAPI void APIENTRY glFogCloordPointer (GLenum type, GLsizei stride, const GLvoid *pointer);
WINGDIAPI void APIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
WINGDIAPI void APIENTRY glEdgeFlagPointer (GLsizei stride, const GLvoid *pointer);
函数 大小 参数的值
glVertexPointer 2,3,4 GL_SHORT、GL_INT、GL_FLOAT、GL_DOUBL
glColorPointer 3,4 GL_BYTE、GL_UNSIGNED_BYTE、GL_SHORT、GL_UNSIGNED_SHORT、GL_INT、GL_UNSIGNED_INT、GL_FLOAT、GL_DOUBLE
glSecondColorPointer 3 GL_BYTE、GL_UNSIGNED_BYTE、GL_SHORT、GLUNSIGNED_SHORT、GL_INT、GL_UNSIGNED_INT、GL_FLOAT、GL_DOUBLE
glIndexPointer 1 GL_UNSIGNED_BYTE、GL_SHORT、GL_INT、GL_FLOAT、GL_DOUBLE
glNormalPointer 3 GL_BYTE、GL_SHORT、GL_INT、GL_FLOAT、GL_DOUBLE
glFogCloordPointer 1 GL_FLOAT、GL_DOUBLE
glTexCoordPointer 1,2,3,4 GL_SHORT、GL_INT、GL_FLOAT、GL_DOUBLE
glEdgeFlagPointer 1 没有type参数(数据类型必须是GL布尔类型)
  1. 跨距(Stride)

gl*Pointer() 函数的stride参数告诉OpenGL如何访问指针数组中的数据。他的值应该是两个连续的指针元素之间的字节数量(或者是0,这是一种特殊情况)

  • 解引用和渲染
  1. 获取当前所有已启用输的的一个顶点(第ith个)的数据,对于顶点坐标数组,对应的函数是glVertex[size][type]v(),其中size是[2,3,4]之一,type是[s,i,f,d]之一,分别表示GLshort、GLint、GLfloat 和 GLdouble。 size和type都是由glVertexPointer()函数定义的,对于其他启用数组,glArrayElement(),glInde[type]v(),glNormal3[type]v()和glFogCoord[type]v(),如果启用了顶点坐标数组,那么其他几个数组(如果启用)相对应的函数(与数组相对应,最多可达七个)被执行后,glVertex*v()函数在最后执行。
WINGDIAPI void APIENTRY glArrayElement (GLint i);
  1. 使用count个元素定义一个几何图元序列,这些元素的索引值保存在indices数组中,type必须是GL_UNSIGNED_BYTE、GL_UNSIGNED_SHORT或GL_UNSIGNED_INT,表示indices数组的数据类型,mode参数指定了被创建的是那种类型的图元。他的值和glBegin()函数所接受的参数值相同。
WINGDIAPI void APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
  1. 调用一系列的glDrawElements()函数 (数量为primcount个),indices是一个指针数组,包含了数组元素的类别,count是一个数组,包含了每个相应的数组元素列表中能够找到顶点的数量,mode(图元类型)和type(数据类型) 与他们在glDrawElements()函数中的含义相同。
void glMultiDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
  1. 创建一个几何图元序列,类似于glDrawElements()创建的序列,但是具有更强的限制。glDrawRangeElements()的有些参数与类似于glDrawElements()相同,包括mode(图元类型),count(元素的数量),type(数据类型)和indices可以姐搜的范围,indices数组中的值必须位于start和end之间才是合法的(包含start和end)。

    void glDrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
    
  2. 创建一个几何吐艳序列,每个被启用的数组中从first开始,到(first + count - 1) 结束的数组元素。mode指定了创建的图元类型,他的值和glBegin函数所接受的的参数值相同。

WINGDIAPI void APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
WINGDIAPI void APIENTRY glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount);