第二章 状态管理和绘制几何物体 总结
目标 1. 清除窗口
2.强制完成所有尚未执行的绘图操作
3.在2d或3d空间绘制图元
4.打开、关闭、查询状态
5.控制图元显示
6.在实心物体表面适当位置指定法线向量
7.用顶点数组和缓冲区对象存储和访问几何数据。
8.同时保存和恢复几个状态变量。
1.1 3种基本操作:清除窗口、绘制几何图形、绘制光栅对象。
2. 绘图工具箱:
2.1 清除RGBA模式的窗口
glClearColor(R, G, B, A); //将当前清除颜色设置成为一个状态变量 glClearDepth(1.0); //指定深度缓冲区中每个像素要设置的值 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // 表示要清除的缓冲区为颜色缓冲区和深度缓冲区
2.2 指定颜色
glColor3f(R,G,B);
2.3 强制完成绘图操作
void glFlush(void); void glFinish(void);
2.4 坐标系统工具箱
当窗口发生改变的时候,会发送一个时间作为通知。在glutReshapeFunc()中注册的那个函数会被调用。并且必须注册一个回调函数完成下面任务:
1)重新建立一个矩形区域,把它作为新的渲染画布。
2)定义一个用于绘制物体的坐标系统。
//一个2d的glutReshapeFunc(reshape)回调函数 void reshape(int w, int h) { glViewport(0, 0, (GLsizei)w, (GLsizei) h);//调整用于绘图的像素矩形,使它占据整个窗口 glMatrixMode(GL_PROJECTION); //接下来的三行代码表示让坐标系的左下角为原点(0,0) glLoadIdentity(); gluOrtho2D(0.0, (GLdouble)w, 0.0, (GLdouble)h); }
3 描述图元:点、直线、多边形
3.1 矩形:
void glRect{sifd}(x1, y1, x2, y2);
3.2 指定顶点:
void glVertex[234]{sifd}(); //注意只有在glBegin 和glEnd之间时才有效
void glVertex[234]{sifd}v();
3.3 几何图元:
将一组顶点放在glBegin 和glEnd之间, 传递给glBegin的参数决定了利用这些顶点所构成的几何图元的类型;
有GL_POINT\GL_LINES\GL_LINE_STRIP\GL_LINE_LOOP\GL_TRIANGLES\GL_TRIANGLES_STRIP\GL_TRIANGLE_FAN\GL_QUADS\GL_QUAD_STRIP\GL_POLYGON
glBegin(GL_POLYGON); glVertex2f(0, 0); glVertex2f(0, 3); glVertex2f(3, 4); glEnd();
在glBegin和glEnd之间还可以用另外的一些函数来指定顶点的额外的属性数据, 例如:颜色glColor*(); 法线向量glNormal*(); 纹理坐标glTexCoord*();等
4. 基本状态管理
物体在渲染的时候可能会用到光照、纹理、隐藏表面消除、雾或者其他的状态
这都是由函数 void glEnable(); 和 void glDisalbe();来控制 , 例如有GL_BLEND, GL_DEPTH_TEST, GL_FOG, GL_LINE_STIPPE, GL_LIGHTING等。
查询GLboolean glIsEnable(GLenum capability); 它返回GL_TRUE\GL_FALSE, 还可以查询其他类型的。
5. 显示点、直线和多边形
5.1 点
void glPointSize();
5.2 直线
线宽: void glLineWidth(GLfloat width);
点画线: void glLineStipple(GLint factor, GLushort pattern) ; 必须掉用glEnable(GL_LINE_STIPPLE)来启用点画线功能。
5.3 多边形细节
点、轮廓、实心:void glPolygonMode(GLenum face, GLenum mode); 参数face可以是GL_FRONT_AND_BACK, GL_FRONT, GL_BACK. 参数mode可以是GL_POINT, GL_LINE,GL_FILL
反转和剔除多边形表面:void glFrontFace(GLenum mode), mode表示哪面为正面 GL_CCW表示逆时针方向为正面, GL_CW表示顺时针方向为正面。
剔除:glEnable(GL_CULL_FACE); void glCullFace(GLenum mode);
点画多边形:glEnable(GL_POLYGON_STIPPLE); void glPolygonStipple();
5.4 法线
void glNormal*()
5.5 标记多边形的边界边
void glEdgeFlag(GL_TRUE) 表示其后的顶点为边界边的起点。
6. 顶点数组
使用顶点数组对几何图形进行渲染需要三个步骤:
1)激活顶点数组:顶点坐标(数组)、表面法线、RGBA颜色,辅助颜色、颜色索引、雾坐标、纹理坐标、多边形边界标志
void glEnableClientState(GLenum array);//GL_VERTEX_ARRAY, etc.
void glDisableClientState();
2)把数据放入数组中。
void glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid* pointer);//size是每个顶点的坐标数量2/3/4,stride是连续顶点之间的字节偏移量。type为GL_INT等,pointer是第一个顶点的内存位置
void glColorPointer()\void glSecondaryColorPointer\glIndexPointer\glNormalPointer\glFogCoordPointer\glTexCoordPointer\glEdgeFlagPointer
static GLint vertics[] = { 25, 25, 100, 325, 175,25 } static GLfloat colors[] = { 1.0, 0.2, 0.2, 0.2, 0.2, 1.0, 0.8, 1.0, 0.2 } glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glColorPointer(3, GL_FLOAT, 0, colors); glVertexPointer(2, GL_INT, 0, vertices);
3)用这些数据绘制几何图形:解引用和渲染。
解引用:客户端的数组中数据被提取发送到服务器,然后发送到图形处理管线进行渲染。
a. void glArrayElement(GLint ith); 获取当前已启用数组(可以是多个)的第ith个顶点数据。
glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRYA); glColorPointer(3, GL_FLOAT, 0, colors); glVertexPointer(2, GL_INT, 0, vertices); glBegin(GL_TRIANGLES) glArrayElement(2); glArrayElement(3); glArrayElement(5); glEnd();
b. void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); // mode表示要创建那种图元GL_POLYGON/GL_LINE_LOOP/GL_LINES/GL_POINTS, count表示解引用数组元素的个数,type表示类型为GL_UNSIGNED_BYTE等, indices表示元素的内存索引位置。