zoukankan      html  css  js  c++  java
  • OpenGL顶点数组

    OpenGL顶点数组

      在OpenGL中,所有的几何图元都是由顶点定义的,而每个顶点又有很多属性,如:坐标,颜色,法向量等。如果对每个顶点逐个的调用函数来描述,那么,开销是非常大的。而且不方便对复杂几何体顶点的管理。这里采用了顶点数组的方法,不但便于数据的管理,而且大大减少了函数的调用。

        使用顶点数组,需要三个步骤:启用数组,指定数组数据、解引用并渲染。下面分别进行介绍。

    1、启用数组

       OpenGL共有八个顶点数组可供使用,在使用之前,应该先启用要使用的数组,函数如下:

       void glEnableClientState(GLenum array);

       其中参数array对应8个顶点数组,分别为:

       GL_VERTEX_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

    其中最常用的是前两个,本文就以前两个为例。使用结束后,要关闭数组以释放资源,函数如下:

       void glDisableClientState(GLenum array),参数与前面相同。

        这里面需要注意的是,每个顶点都对应着这8个数组所对应的属性,也就是说地i个顶点,对应的坐标,颜色等信息,由相对应的数组的第i个元素所描述。

    2、指定数组的数据

       void glVertexPointer(GLint size,GLenum type,GLsizei stride,const GLvoid* pointer);

    其中:

       size——每个顶点坐标的数量,必须是2,3或4;

       type——指定了数组中坐标的数据类型(GL_SHORT,GL_INT,GL_FLOAT,或GL_DOUBLE);

       stride——连续的顶点之间的字节偏移量。如果是0,则顶点是紧密相邻的;

       pointer——数组的首地址。

    其他数组使用发发与上述函数类似。

    举例如下:

    static GLint vertices[]={25,25,

                             100,325,

                             175,25,

                             175,325};

    static GLfloat colors[]={1.0,0.0,0.0,

                             0.0,1.0,0.0,

                             0.0,0.0,1.0,

                             0.0,1.0,1.0};

    glEnableClientState(GL_VERTEX_ARRAY);//启用顶点坐标数组

    glEnableClientState(GL_COLOR_ARRAY); //启用顶点颜色数组

    glVertexPointer(2,GL_INT,0,vertices);//指定坐标数据

    glColorPointer(3,GL_FLOAT,0,colors); //指定颜色数据

    通过上述的操作,就定义了四个顶点的坐标和颜色,如:第一个顶点的坐标为[25,25],颜色为红色,依次类推。

    也可以将不同类型数组的数据放在同一个数组中,如:

    static GLfloat interwind[]={25,25,1.0,0.0,0.0,

                                100,325,0.0,1.0,0.0,

                                175,25,0.0,0.0,1.0,

                                175,325,0.0,1.0,1.0};

    glVertexPointer(2,GL_FLOAT,5*sizeof(GLfloat),&interwind[0]);

    glColorPointer(3,GL_FLOAT,5*sizeof(GLfloat),&interwind[2]);

    这里与上面唯一不同的就是第三个参数,这里面,第三个参数是指本数组中(如坐标数组),两个顶点同类坐标之间的距离(如,两个顶点第一个坐标的距离)。当然,它的值若不是0,那么所乘的系数,一定是大于第一个参数的(如,5大于2)。

    3、解引用与渲染

       void glArrayElement(GLint ith);

      获取第ith个顶点的信息,至于能获得哪些信息,取决于开启了哪些顶点数组。如(接上诉代码):

       glBegin(GL_TRIANGLES);

       glArrayElement(1);

       glArrayElement(2);

       glArrayElement(3);

       glEnd();

      则按照上述定义的第2,3,4(第一个顶点是0)个顶点画三角形,这里需要注意的事,glArrayElement函数只是单纯的引用顶点,必须放在glBegin()和glEnd()之间才有意义。

      上述方法适合灵活的调用较少数量的顶点,对于顶点较多的几何元素,可以用下列方法: 

        void glDrawElements(GLenum mode,GLsizei count,GLenum type,void *indices);

    其中:

        mode——指定是那种图元,和glBegin()中的参数一样;

        count——构建一个图元所需要的顶点个数;

        type——indices数组的数据类型,必须是GL_UNSIGNED_BYTE,GL_UNSIGNED_SHORT和GL_UNSIGNED_INT中的一个;

        indices——图元顶点序列的数组。

    效果类似于:

        glBegin(mode);

         for(i=0;i<count;i++)

            glArrayElement(indices[i]);

        glEnd();

    例如,要用以上定义好的数据画两个三角形:

    static GLubyte triangleone[]={0,1,2}; 

    static GLubyte triangletwo[]={1,2,3};

    glDrawElements(GL_TRIANGLE,3,GL_UNSIGNED_BYTE,triangleone);

    glDrawElements(GL_TRIANGLE,3,GL_UNSIGNED_BYTE,triangletwo);

    注意,glDrawElements函数不需要也不能放在glBegin()和glEnd()之间。

    void glMultiDrawElements(GLenum mode,GLsizei *count,GLenum type,void **indices,GLsizei primcount);

    效果相当于:

    for(i=0;i<primcount;i++){

        if(count[i]>0)

           glDrawElements(mode,count[i],type,indices[i]);

    }

    其中,indeces定义为GLvoid *indeces[primcount]={描述顶点序列的primcount个数组名};

    还有其他的一些函数,在这里不再一一分析,可以参考“红宝书”第二章的内容。

    顶点数组为构建复杂图元提供了灵活而有效的解决方案,同时提高了OpenGL程序的执行效率,在以后的变成中,应尽量用顶点数组的方式定义图元,以便熟悉并灵活运用!

    参考:http://blog.sina.com.cn/s/blog_505b7d470100rjvo.html

  • 相关阅读:
    征战蓝桥 —— 2017年第八届 —— C/C++A组第7题——正则问题
    征战蓝桥 —— 2017年第八届 —— C/C++A组第7题——正则问题
    征战蓝桥 —— 2017年第八届 —— C/C++A组第7题——正则问题
    征战蓝桥 —— 2017年第八届 —— C/C++A组第8题——包子凑数
    征战蓝桥 —— 2017年第八届 —— C/C++A组第8题——包子凑数
    征战蓝桥 —— 2017年第八届 —— C/C++A组第8题——包子凑数
    征战蓝桥 —— 2017年第八届 —— C/C++A组第9题——分巧克力
    征战蓝桥 —— 2017年第八届 —— C/C++A组第9题——分巧克力
    征战蓝桥 —— 2017年第八届 —— C/C++A组第9题——分巧克力
    征战蓝桥 —— 2017年第八届 —— C/C++A组第10题——油漆面积
  • 原文地址:https://www.cnblogs.com/tekkaman/p/3760637.html
Copyright © 2011-2022 走看看