OpenGl 游戏编程笔记 第三章: OpenGL 状态和图元 (二)
OpenGl 游戏编程笔记 第四章: 变换和矩阵(一)

OpenGl 游戏编程笔记 第三章: OpenGL 状态和图元 (三)

皮贝贝 posted @ 2010年3月31日 06:13 in opengl with tags 游戏 OpenGL game , 6002 阅读

OpenGl 游戏编程笔记 第三章: OpenGL 状态和图元 (三)

1 3D 绘制多边形

通过在 3D 空间绘制几个顶点, 会围成一个多边形, OpenGL 默认的行为是用颜色来填充这个多边形. 你可以自由的来控制多个多边形绘制的行为, 通过函数:


void glPolygonMode(GLenum face, GLenum mode);

在 OpenGL 中多边形是分成两面来处理的. 参数 face 可以是 GL_FRONT(前面), 也可以是 GL_BACK(后面), 还可以是 GL_FRONT_AND_BACK (两面).

参数 mode 的取值如下:


描述
GL_POINT 指定的多个多边形顶点会只渲染为一个点. 效果如同 glBegin(GL_POINTS)
GL_LINE 会渲染为多条线(闭合的). 效果如同 glBegin(GL_LINE_LOOP)
GL_FILL 默认状态.被填充

例如, 我们希望前面填充效果, 后面一面只绘制一个线框:

 

glPolygonMode(GL_FRONG, GL_FILL);
glPolygonMode(GL_BACK, GL_LINE);

 

同样的, 你可以通过 glGet() 的 GL_POLYGON_MODE 来获知当前的绘制模式.

1.1 面剔除

有时候我们只想显示一面, 另一面始终不显示, 我们需要要求 OpenGL 对另一面停止渲染, 这样才 节省OpenGL 的渲染开支. 要想启用剔除功能, 需要通过 glCullFace() 来开启:


void glCullFace(GLenum mode)

mode 指定了要剔除的面, 可以使 GL_FRONG, GL_BACK, GL_FRONG_AND_BACK 中的任意一个. 默认设置是 GL_BACK(后面).

接下来就是告诉 OpenGL 那个面是正面, 那个是反面. OpenGL 是通过你指定多边形点的顺序来知道的. 你可以在正面选择一个点来作为开始的点, 然后, 你选择通过顺时针或是逆时针方向来处理这些点. 如果你觉得 指定顺序很繁琐, OpenGL 也会根据你得顺序自动判断正方面. 默认地, OpenGL 认为逆时针方向的点集是 正面, 而顺时针方向的则为反面. 你可以通过 glFrontFace() 来改变默认的行为:


void glFrontFace(GLenum mode);

参数 mode 可以是 GL_CCW( 逆时针为正面), 或是 GL_CW (顺时针为正面).

1.2 隐藏多边形的边

你可以通过下面的函数在绘制时通知 OpenGL 边不予显示:


void glEdgeFlag(GLboolean isEdge);
void glEdgeFlagv(const GLboolean *isEdge);

两个版本的区别在于第二个参数取值为数组. 参数可以取值为 GL_TRUE (默认如此), 或是 GL_FALSE (不被绘制).

1.3 反走样

大似点线的反走样, 可以通过 glEnable()  glDisable() 的 GL_POLYGON_SMOOTH 来开启或关闭, 通过 glGet()  glIsEnabled() 来获知当前的状态. 默认是关闭的. 例程如下:

 

if (!glIsEnabled(GL_POLYGON_SMOOTH))
        glEnable(GL_POLYGON_SMOOTH);


 

1.4 指定点画模式

默认是关闭的, 可以通过 glEnable() 的 GL_POLYGON_STIPPLE 开启. 开启之后, 就可以用 下面的函数来设置点画模式了:


void glPolygonStipple(const GLubyte *mask);

参数 mask 是一个指针, 指向一个包含 32 * 32 位模式的数组. 这个数组决定了多边形中那些点绘制,那些 不被绘制. 不像线的点画模式中的反序, 多边形的点画模式是正序的. 注意的是, 多边形的点画模式用于 2D 的屏幕坐标系中, 所以旋转一个多边形可能不会正常旋转.

来看几个特殊的多边形.

1.5 三角形

任何多边形都可以分解成一个个的三角形, 所以三角形是预提供的一种多边形.

绘制三角形很简单, glBegin() / glEnd() 中指定三个顶点即可:

 

glBegin(GL_TRIANGLES);
glVertex3f(-2.0, -1.0, 0.0);
glVertex3f(3.0,  1.0, 0.0);
glVertex3f(0.0, 3.0, 0.0);
glEnd();


 

如同点线, 可以在代码块中绘制多个三角形, 多余的点将被忽略.

glBegin() 的 GL_TRIANGLE_STRIP 下, 每两个连续的点和接下来的一个顶点组成一个三角形.

glBegin() 的 GL_TRIANGLE_FAN 下, 会绘制一系列围绕着一个顶点的三角形. 指定的第一个 顶点就是中性顶点, 与后来的每连续两个顶点组成一个三角形.

1.6 四边形

四边形的 glBegin() 参数是 GL_QUADS , 可以绘制一个或多个四边形. OpenGL 也提供了 GL_QUAD_STRIP 来绘制连续的四边形.

1.7 多边形

因为多边形的顶点数不固定, 所以 glBegin() 的参数 GL_POLYGON 是一个单数形式. 并且顶点 必须最少三个, 否则不予绘制.

1 属性

前面已经讲了如何从 OpenGL 中获知和设定状态. 接下来看看如何存储和恢复这些状态值.

状态群指的是 OpenGL 中一系列相关联的状态. 如线相关的有线宽, 点画模式, 线的平滑等. 通过 使用 glPushAttrib()  glPopAttrib() 函数可以保存和恢复一个状态群中的所有状态值.


void glPushAttrib(GLbitfield mask);
void glPopAttrib(void)

glPushAttrib() 会把参数 mode 指定的状态群的所有状态保存到状态栈上. mask 可以是多个 状态群的并集. glPopAttrib() 从状态栈上恢复上次 glPushAttrib() 保存的状态. mode 可以取值:


Mask 状态群
GL_ALL_ATTRIBBITS 所有状态群  
GL_ENABLE BIT 开启的状态
GL_FOG_BIT
GL_LIGNTING_BIT 光照
GL_LINE_BIT 线
GL_POINT_BIT
GL_POLYGON_BIT 多边形
GL_TEXTURE_BIT 纹理

 

Date: 2010-03-30 22:01:51

HTML generated by org-mode 6.30c in emacs 23

 

Avatar_small
Tanky Woo 说:
2010年5月30日 18:11

嗯,学习了。
我的博客:www.wutianqi.com
论坛:www.cppleyuan.com

Avatar_small
caobeixingqiu 说:
2010年6月24日 17:46

@Tanky Woo: 无聊的时候干的事情 呵呵


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter