首页 > 代码库 > 第二章 状态管理和绘制几何物体 总结

第二章 状态管理和绘制几何物体 总结

目标 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表示元素的内存索引位置。