opengl学习(四)-----绘制简单图形(二)_C/C++_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > C/C++ > opengl学习(四)-----绘制简单图形(二)

opengl学习(四)-----绘制简单图形(二)

 2012/4/5 13:26:30  如沐春风的小妮  程序员俱乐部  我要评论(0)
  • 摘要:上一周简简单单的讲了一下简单图形的绘制。按照所讲内容绘制一个20条边的多边形,那需要调用多少函数呢?至少22个。首先调用glBegin(),然后是20个顶点函数,最后调用一个glEnd()函数。再如果,要绘制一个立方体。一个立方体有6个面,一个面有四个顶点,也就是至少要定义26个函数。可是一个立方体按照数学里面的算法是只有8个顶点,如果按照我们绘制多边形的这种方式,每个顶点都指定了3次,才可以将所有的平面绘制完成形成一个立方体。好吧,我承认,我是要说,这显然,太~浪~费~了
  • 标签:学习
  上一周简简单单的讲了一下简单图形的绘制。按照所讲内容绘制一个20条边的多边形,那需要调用多少函数呢?至少22个。首先调用glBegin(),然后是20个顶点函数,最后调用一个glEnd()函数。再如果,要绘制一个立方体。一个立方体有6个面,一个面有四个顶点,也就是至少要定义26个函数。
    可是一个立方体按照数学里面的算法是只有8个顶点,如果按照我们绘制多边形的这种方式,每个顶点都指定了3次,才可以将所有的平面绘制完成形成一个立方体。
    好吧,我承认,我是要说,这显然,太~浪~费~了。OpenGL是不会这么无耻的允许这样浪费的事情存在的,所以大家不用纠结,继续往下看吧。
    OpenGL提供了顶点数组函数,允许只用少数几个数组指定大量的与顶点相关的数据,并用少量函数调用访问这些数据。
    使用顶点数组对几何图形进行渲染需要三个步骤:
   第一,启用数组。
   引用void glEnableClientState(GLenum array)
    指定了需要启用的数组。array参数可以使用下面这些符号常量:GL_VERTEY_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
    第一个步骤是使用上面这个函数,激活选择的数组。例如激活顶点坐标数组就是glEnableClientState(GL_VERTEY_ARRAY)。
    有启用就用禁用,下面这个函数即为禁用函数。
   引用void glDisableClientState(GLenum array)
指定了需要禁用的数组。它接受的参数与glEnableClientState()函数相同。
    第二,指定数组的数据。
    共用8个不同的函数指定数组,每个函数用于指定一个不同类型的数组。
   引用void glVertexPointer(GLint size, GLenum type, GLsizei stride,const GLvoid *pointer);
    指定了需要访问的空间坐标数据。
    pointer:顶点坐标的内存地址;
    type:数组数据的类型(GL_SHORT、GL_INT、GL_FLOAT或GL+DOUBLE)。
    size:顶点的坐标数量,必须为2、3、4.
    stride:连续顶点之间的字节偏移量。如果为0,则表示顶点是相邻的。
    其它7个函数如下:
glColorPointer(GLint size, GLenum type, GLsizei stride,const GLvoid *pointer);
glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride,const GLvoid *pointer);
glIndexPointer(GLint size, GLenum type, GLsizei stride,const GLvoid *pointer);
glNormalPointer(GLint size, GLenum type, GLsizei stride,const GLvoid *pointer);
glFogCoordPointer(GLint size, GLenum type, GLsizei stride,const GLvoid *pointer);
glTexCoordPointer(GLint size, GLenum type, GLsizei stride,const GLvoid *pointer);
glEdgeFlagPointer(GLint size, GLenum type, GLsizei stride,const GLvoid *pointer);

    附上一个小的例子
static GLint vertices[] = {25, 25, 
                           100, 325, 
                           175, 25, 
                           175, 325, 
                           250, 25, 
                           325, 325};
static GLfloat colors[] = {1.0, 0.2, 0.2, 
                           0.2, 0.2, 1.0, 
                           0.8, 1.0, 2.0, 
                           0.75, 0.75, 0.75, 
                           0.35, 0.35, 0.35, 
                           0.5, 0.5, 0.5};
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(3, GL_FLOAT, 0, color);
glVertexPointer(2, GL_INT, 0, vertices);

   第三,解引用和渲染。
   解引用单个数组元素:
   引用void glArrayElement(GLint ith)
    获取当前所有已启用数组的一个顶点(第ith个)的数据。对于顶点坐标数组,对应的函数是glVertex[size][type]v(),其中size是【2,3,4】之一。type是[s,i,f,d]之一,size和type都是glVertexPointer()函数定义的。对于其他启动的数组,glArrayElement()分别调用那个glEndgFlagv()、glTexCoord[size[[type]v()、glColor[size][type]v()、glSecondaryColor3[type]v()、glInde[type]v()、glNoramal3[type]v()和glFogCoord[type]v()。如果启用了顶点坐标数组,在其他几个数组(如果启用)相对应的函数被执行之后,glVertex*v()函数在最后执行。
     举例说明:使用第二步骤时启用的顶点数组的第1,2,3顶点绘制一个三角形:
glBegin(GL_TRIANGLES);
glArrayElement(0);
glArrayElement(1);
glArrayElement(2);
glEnd();

    上面这段代码与下面的效果相同:
glBegin(GL_TRIANGLES);
glColor3fv(color);
glVertex2iv(vertices);
glColor3fv(color + (1*3));
glVertex2iv(vertices + (1*2));
glColor3fv(color + (2*3));
glVertex2iv(vertices + (2*2));
glEnd();

glArrayElement每个顶点还是调用一次,恩,不够简洁么。。再来看一个更简洁点儿的。
引用
void glDrawElements(GLenum mode, GLsize count, GLenum type, const GLvoid *indices);
    使用count个元素定义一个几何图元序列,这些元素的索引值保存在indices数组中。type是indices数组中数据的类型。mode参数指定了被创建的是哪种类型的图元。
还是以刚刚的例子继续替换吧,它的效果与刚刚的效果是一样的,还需要重复?需要,好吧。。自己copy去~~:
static GLubyte indices = {0, 1, 2};
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, indices);
发表评论
用户名: 匿名