OpenGL开发 空间绘图:几何图元和缓冲区

 

GL_POINTS //选择点作为图元

void glPointSize(GLfloat size); //函数接受1个参数,它用于指定被绘点的近似直径。但是,点的大小设置还是存在限制。

GLfloat sizes[2] //存储受支持的点大小范围

GLfloat step; //存储受支持的点大小增量

 

//获得受支持的点大小范围以及增量大小

glGetFloatv(GL_POINT_SIZE_RANGE,sizes);

glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);

这里,sizes数组将包含两个元素,分别表示glPointSize的最小有效值和最大有效值。另外,变量step表示点大小范围之内最小允许步进值。指定一个位于范围之外的值并不会产生错误,如果指定的值比最大有效值大,系统会取最大有效值;如果指定的值比最小有效值小,系统会取最小有效值。

 

glEnable/glDisable所启用或禁止的任何特性或功能,以及glSet所设置的任何数值设置,都可以用glGet函数的众多变形之一进行查询。

—————————————————————————————————————————————————————————————————————————————

GL_LINES //选择直线作为图元

每两个指定的顶点用于绘制一条直线,如果为GL_LINES 指定奇数个顶点,最后一个顶点会被忽略。

GL_LINE_STRIP //选择线带作为图元

绘制一条经过所有这些顶点的连续的线。

GL_LINE_LOOP //选择线环作为图元

这种图元与GL_LINE_STRIP 非常相似,只是最后一个顶点和第一个顶点之间也会绘制一条直线。

 

void glLineWidth(GLfloat width); //函数接受1个参数,它用于指定被绘直线的近似宽度。但是,直线宽度的大小设置也存在限制。

GLfloat sizes[2] //存储受支持的直线宽度范围

GLfloat step; //存储受支持的直线宽度点大小增量

 

//获得受支持的直线宽度范围以及增量

glGetFloatv(GL_LINE_WIDTH_RANGE,sizes);

glGetFloatv(GL_LINE_WIDTH_GRANULARITY,&step);

这里,sizes数组将包含两个元素,分别表示glLineWidth的最小有效值和最大有效值。另外,变量step表示直线宽度范围之内最小允许步进值。指定一个位于范围之外的值并不会产生错误,如果指定的值比最大有效值大,系统会取最大有效值;如果指定的值比最小有效值小,系统会取最小有效值。

 

除了修改直线的宽度以外,我们还可以用点线或虚线模式来创建直线,这称为点画(stippling)。为了实现直线点画,首先必须利用下面这行代码启用点画功能:

glEnable(GL_LINE_STIPPLE);

然后,可以用glLineStipple函数创建这种模式:

void glLineStipple(GLint factor, GLushort pattern);

NOTE:glEnable函数所启用的任何特性或功能都可以用一个对应的glDisable调用来取消。

pattern参数是一个16位的值,它指定了一个模式,供绘直线所用。他的每个位都表示线段的一部分或者处于打开状态,或者处于关闭状态。在默认情况下,每个位对应一个像素,但factor参数可以作为乘法因子增加模式的宽度。

—————————————————————————————————————————————————————————————————————————————

GL_TRIANGLES //三角形图元

顶点的指定次序以及方向的组合称为环绕(winding)。

在默认情况下,OpenGL认为逆时针方向环绕的一面是多边形的正面。如果想要改变OpenGL的这个默认行为,可以调用下面这个函数:

glFrontFace(GL_CW);

GL_CW参数告诉OpenGL顺时针环绕的多边形将被认为是正面的。为了把多边形的正面重新恢复为逆时针环绕,可以在这个函数中使用GL_CCW参数。

 

GL_TRIANGLE_STRIP //三角形带图元

可以绘制一串相连的三角形,从而节省大量的时间。

使用三角形带而不是分别指定每个三角形具有两个优点:

首先,用前三个顶点指定第一个三角形之后,对于接下来的每个三角形,只需要再指定一个顶点。需要绘制大量的三角形时,采用这种方法可以节省大量的程序代码和数据存储空间。第二个优点是运算性能的提供和带宽的节省。更少的顶点意味着数据从内存传输到图形卡的速度更快,并且顶点变换的次数也可以更少一些。

GL_TRIANGLE_FAN //三角形扇图元

创建一组围绕一个中心点的相连三角形。

用前三个顶点组成第一个三角形之后,后续的每个顶点(Vi)和原点(V0)以及前驱的那个顶点(Vi-1)形成了接下来的那个三角形。

——————————————————————————————————————————————————

glShadeModel(GL_FLAT);

告诉OpenGL用当前的颜色(也就是这个多边形的最后一个顶点的颜色)填充这个多边形。

glShadeMode(GL_SMOOTH);

告诉OpenGL根据每一个顶点的颜色对多边形就行渐变着色,对相邻的顶点的颜色进行匀和。

 

启动深度测试:

glEnable(GL_DEPTH_TEST);

 

启用或禁用背面消除:

glEnable(GL_CULL_FACE);

glDisable(GL_CULL_FACE);

 

多边形模式:

glPolygonMode(GL_BACK,GL_LINE);

glPolygonMode(GL_BACK,GL_FILL);

具体什么作用还不是很清楚,有待进一步研究。

————————————————————————————————

GL_QUADS //四边形图元

这些多边形具有顺时针方向的环绕。

GL_QUADS_STRIP //四边形带图元

GL_POLYGON //多边形图元

为了启动多边形点画,我们可以调用:

glEnable(GL_POLYGON_STIPPLE);

然后调用:

glPolygonStipple(pBitmap);

pBitmap是一个指定了一块区域的指针,这个数据区域包含了点画模式。随后,所有的多边形就是用pBitmap(GLubyte *)所指定的模式进行填充。

 

glEdgeFlag(); //接受一个参数,来吧edge标志设置为true或false。当这个函数设置为true时,接下来的所有顶点都将作为多边形边界的起点。

 

——————————————————————————————————

void glDrawBuffer(Glenum mode);

如果mode参数指定为GL_FRONT,OpenGL就会在前缓冲区进行渲染;如果指定为GL_BACK,那么渲染将在后缓冲区进行。

使用GLUT,我们可以通过下面的代码对显示模式进行初始化,以使用RGB颜色和双缓冲渲染:

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

为了进行单缓冲渲染,可以简单地忽略位标志GLUT_DOUBLE:

glutInitDisplayMode(GLUT_RGB);

进行单缓冲渲染时,如果希望把渲染结果实际绘制到屏幕上,需要调用glFlush或glFinish。

 

操作深度缓冲区:

在GLUT中请求一个深度缓冲区非常简单,只需在初始化显示模式时添加GLUT_DEPTH位标志:

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);

我们知道,为了启用深度缓冲区进行深度测试,只需简单地进行下面这个调用:

glEnable(GL_DEPTH_TEST);

即使深度测试未被启用,如果深度缓冲区被创建,OpenGL也将把所有写入到颜色缓冲区的颜色片段对应的深度值写入到深度缓冲区。

但是,有时候我们可能希望在进行深度测试时禁止把值写入到深度缓冲区。我们可以调用glDepthMash函数来完成这个任务:

void glDepthMask(GLboolean mask);

我们可以使用下面这个glEnable调用来打开裁剪测试:

glEnable(GL_SCISSOR_TEST);

当然,我们也可以用对应的glDisable调用来关闭裁剪测试。窗口内部执行渲染的那个区域称为裁剪框(scissor box),它是用下面这个函数以窗口坐标(像素)的形式指定的。

void glScissor(GLint x,GLint y,GLint z,GLsizei width,GLsizei height);

x和y参数指定了裁剪框的左下角, width和 height参数则分别指定了裁剪框的宽度和高度。

 

使用模板缓冲区

当我们使用GLUT时,我们在初始化显示模式时请求一个模板缓冲区:

glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_STENCIL);

我们也可以使用glEnable/glDisable来打开或关闭这个功能:

glEnable(GL_STENCIL_TEST);

打开了模板测试之后,绘图就只在那些通过了模板测试的位置进行。我们可以使用下面的这个函数设置模板测试:

void glStencilFunc(GLenum func,GLint ref ,GLuint mash);

模板参数func可以取下面任意一个值:GL_NEVER、GL_ALWAYS、GL_LESS、GL_LEQUAL、GL_EQUAL、GL_GEQUAL、GL_GREATER和GL_NOTEQUAL。这些值告诉了OpenGL如何把已经存储在模板缓冲区中的值与ref参数所指定的值进行比较。假设参考值为A,存储在模板缓冲区中的值为B,则上面这些值分别代表“从不通过”、“总是通过”、“当A小于B时通过”、“当A小于等于B时通过”、“当A等于B时通过”、“当A大于等于B时通过”、“当A大于B时通过”、“当A不等于B时通过”。另外我们可以指定一个掩码,在进行比较前,将这个掩码与参考值和模板缓冲区中的值进行AND操作。

 

创建模板图案

使用下面的代码清除颜色、深度和模板缓冲区:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

在清除操作中所使用的值是在之前调用下面这个函数时设置的:

glClearStencil(GLint s);

进入模板缓冲区的值取决于glStencilOp函数是如何被调用的:

void glStencilOp(GLenum fail,GLenum zfail,GLenum zpass);

这些值告诉OpenGL,如果模板测试失败,他应该如何修改模板缓冲区的值。而且,即使模板测试通过,也可以根据深度测试是失败(zfail)还是通过(zpass)来修改模板缓冲区的值。这些参数的合法值包括:GL_KEEP、GL_ZERO、GL_REPLACE、GL_INCR、GL_DECR、GL_INVERT、GL_INCR_WRAP和GL_DECR_WRAP。这些值分别对应于“保持当前值”、“把它设置为0”、“用参考值(取自glStencilFunc)代替”、“增加或减少这个值”、“反转这个值”以及“循环增加或减少这个值”。

我们可以使用glStencilMask函数对模板缓冲区的写入设置掩码:

void glStencilMask(GLboolean mask);

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值