《OpenGL ES 3.x游戏开发(下卷)》一1.2 顶点数组对象

1.2 顶点数组对象

使用了顶点缓冲技术后,绘制效率有了较大的提升。但是还有一点不尽如人意,那就是顶点的位置坐标、法向量、纹理坐标等不同方面的数据每次使用时需要单独指定,重复了一些不必要的工作。OpenGL ES 3.0考虑到了这一点,提供了一种专门用于解决此问题的对象——顶点数组对象(VAO)。本节将介绍顶点数组对象。

1.2.1 基本知识与案例效果

顶点数组对象的主要功能就是将绘制一个物体时所需的对应于不同方面(如顶点坐标、法向量、纹理坐标)的顶点缓冲及相关设置包装成一个整体,绘制时直接使用顶点数组对象即可,不必分别使用每个顶点缓冲,这可以进一步提高绘制效率。

了解了顶点数组对象的主要功能后,下面介绍两个与使用顶点数组对象相关的方法(这两个方法也是通过GLES30类进行调用),具体内容如下。

  • glGenVertexArrays方法

glGenVertexArrays方法主要用于创建新的顶点数组对象,该方法的具体签名如下。

1    public static void glGenVertexArrays (int n, int[] arrays, int offset)

说明

参数n为需要创建的顶点数组对象的数量,参数arrays用来存放创建的n个顶点数组对象的编号,参数offset为arrays数组的偏移量。

  • glBindVertexArray方法

创建顶点数组对象之后,就可以用glBindVertexArray方法绑定指定的顶点数组对象,以便对指定的顶点数组对象进行设置或使用,其方法签名如下。

1    public static void glBindVertexArray (int array)

说明

参数array为需要绑定的顶点数组对象的编号。用glBindVertexArray方法绑定顶点数组对象之后,更改顶点数组状态的后续调用(如glBindBuffer、glVertexAttribPointer、glEnableVertexAttribArray和glDisableVertexAttribArray等)将影响绑定的顶点数组对象。通过绑定不同的顶点数组对象,绘制时应用程序可以快速在不同顶点数组配置之间进行切换(只需一句代码即可),大大提高了开发效率。

了解了顶点数组对象的一些基本知识以后,下面来了解一下本节案例Sample1_2的运行效果,具体情况如图1-2所示。

提示

运行本案例时,当手指在屏幕上上下左右滑动时,相应的物体也会绕x轴和y轴旋转。

1.2.2 案例开发步骤

了解了顶点数组对象的基本知识以及本节案例的运行效果后,就可以进行案例的开发了。由于案例Sample1_2是在案例Sample1_1的基础上修改而来的,所以这里仅给出相关的修改部分,具体步骤如下。

(1)首先介绍的是用于初始化顶点数组对象的方法initVAO,此方法用于在绘制之前一次性对顶点数组对象进行初始化,其具体代码如下。

1     public void initVAO(){
2         int[] vaoIds=new int[1];                   //用于存放顶点数组对象编号的数组
3         GLES30.glGenVertexArrays(1, vaoIds, 0);    //创建一个顶点数组对象
4         vaoId=vaoIds[0];                           //获取将创建的顶点数组对象编号
5         GLES30.glBindVertexArray(vaoId);           //绑定顶点数组对象
6         GLES30.glEnableVertexAttribArray(maPositionHandle);  //启用顶点位置数据数组
7         GLES30.glEnableVertexAttribArray(maNormalHandle);    //启用法向量数据数组
8         GLES30.glEnableVertexAttribArray(maTexCoorHandle);   //启用纹理坐标数据数组
9         //绑定到顶点坐标数据缓冲
10        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,mVertexBufferId);
11        //指定顶点位置数据使用对应缓冲
12        GLES30.glVertexAttribPointer(maPositionHandle, 3, GLES30.GL_FLOAT,false,3*4,0);
13        //绑定到顶点法向量数据缓冲
14        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,mNormalBufferId);
15        //指定顶点法向量数据使用对应缓冲
16        GLES30.glVertexAttribPointer (maNormalHandle, 3,GLES30.GL_FLOAT, false,3*4,0);
17        //绑定到顶点纹理坐标数据缓冲
18        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,mTexCoorBufferId);
19        //指定顶点纹理坐标数据使用对应缓冲
20        GLES30.glVertexAttribPointer(maTexCoorHandle,2,GLES30.GL_FLOAT,false,2*4,0);
21        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,0);  //绑定到系统默认缓冲
22        GLES30.glBindVertexArray(0);                    //绑定到系统默认顶点数组对象
23    }

提示

上述initVAO方法主要用于创建并初始化顶点数组对象,包括生成VAO,绑定VAO,启用顶点位置、法向量、纹理坐标数据数组,然后依次将顶点坐标数据、顶点法向量数据以及顶点纹理坐标数据指定到相应的缓冲,最后绑定到系统默认的缓冲以及系统默认的顶点数组对象,此方法在初始化顶点数据时调用一次。

(2)接下来将要介绍的是用于绘制物体的方法drawSelf,该方法与案例Sample1_1中对应的方法有所不同。此处的绘制方法功能更为简单,省略了在绘制时一一绑定所需的顶点缓冲,并为不同数据(顶点坐标、法向量、纹理坐标)一一指定缓冲的代码,其具体代码如下。

1    public void drawSelf(int texId){
2         GLES30.glUseProgram(mProgram);                     //指定使用某套着色器程序
3         //将最终变换矩阵传入渲染管线
4         GLES30.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, MatrixState.getFinalMatrix(), 0);
5         //将基本变换矩阵传入渲染管线
6         GLES30.glUniformMatrix4fv(muMMatrixHandle, 1, false, MatrixState.getMMatrix(), 0);
7         //将光源位置传入渲染管线
8         GLES30.glUniform3fv(maLightLocationHandle, 1, MatrixState.lightPositionFB);
9         //将摄像机位置传入渲染管线
10        GLES30.glUniform3fv(maCameraHandle, 1, MatrixState.cameraFB);
11        GLES30.glBindVertexArray(vaoId);                     //绑定顶点数组对象
12        GLES30.glActiveTexture(GLES30.GL_TEXTURE0);          //激活纹理
13        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D, texId);   //绑定纹理
14        GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, vCount); //绘制加载的物体
15        GLES30.glBindVertexArray(0);     //绑定到系统默认的顶点数组对象
16    }

说明

该绘制方法的功能主要为指定使用某套着色器程序,将最终变换矩阵、基本变换矩阵、光源位置及摄像机位置等数据送入渲染管线,并绑定顶点数组对象,激活和绑定纹理,绘制物体之后绑定到系统默认的顶点数组对象。从与案例Sample1_1中的drawSelf方法进行对比可以看出,其代码更短,开发成本更低,读者在实际开发中应该尽量选用。

时间: 2024-10-30 05:28:20

《OpenGL ES 3.x游戏开发(下卷)》一1.2 顶点数组对象的相关文章

《OpenGL ES 3.x游戏开发(下卷)》一导读

前 言 OpenGL ES 3.x游戏开发(下卷) 为什么要写这样一套书 随着智能手机硬件性能的不断提升,如"水果忍者""极品飞车""狂野飙车8:极速凌云"等一批优秀的3D游戏娱乐应用在广大智能机用户间流行开来.与此同时,也带动了手机游戏产业逐渐从2D走向3D.但目前国内专门介绍3D游戏开发的书籍与资料都非常少,同时3D应用开发的门槛又比较高,使得很多初学者无从下手.根据这种情况,笔者结合多年从事3D游戏应用开发的经验编写了这样一套书. 了解一些

《OpenGL ES 3.x游戏开发(下卷)》一1.1 顶点缓冲区

1.1 顶点缓冲区 将绘制物体的顶点数据保存在内存中,在调用glDrawArrays或者glDrawElements等绘制方法前需要调用相应的方法将数据送入显存,I/O开销大,性能不够好. 若采用顶点缓冲区对象存放顶点数据,则不需要在每次绘制前都将顶点数据复制进显存,而是在初始化顶点缓冲区对象时一次性将顶点数据送入显存,每次绘制时直接使用显存中的数据,可以大大提高渲染性能. 1.1.1 基本知识 OpenGL ES 3.0中支持两种类型的顶点缓冲区对象,分别为数组缓冲区对象(Array Buff

《OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例》——6.4节点法向量和面法向量

6.4 点法向量和面法向量 OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例 本章前面几节的案例都是基于球面开发的,球面属于连续.平滑的曲面,因此面上的每个顶点都有确定的法向量.但现实世界中的物体表面并不都是连续.平滑的,此时对于面上的某些点的法向量计算就不那么直观了,图6-18说明了这个问题. 从图6-18中可以看出,顶点A位于长方体左.上.前3个面的交界处,此处是不光滑的.这种情况下顶点A的法向量有两种处理策略,具体如下所列. 在顶点A的位置放置3个不同的顶点,每个顶点看作是仅

《OpenGL ES 3.x游戏开发(上卷)》一第1章 Android概述

第1章 Android概述 OpenGL ES 3.x游戏开发(上卷)随着移动互联网时代的到来,智能手机逐渐走进了人们的生活, Google公司于2007年11月5日发布了基于Linux平台的开源手机操作系统--Android.由于Android系统的开源性以及其他各个方面的因素,其受到了广大手机厂商的青睐,因此需要大量的Android开发人员来满足日益增长的海量软件开发需求. 提示 有些读者可能会有一点奇怪,不是介绍OpenGL ES 3.0的知识吗,怎么一开始就介绍Android呢?这是因为

《OpenGL ES 3.x游戏开发(上卷)》一第2章 游戏开发相关的 Android基础知识

第2章 游戏开发相关的 Android基础知识 OpenGL ES 3.x游戏开发(上卷)虽然本书主要是介绍OpenGL ES 3.0 3D应用及游戏开发的,但由于很多3D游戏应用中还需要用到目标平台的一些其他应用开发方面的知识,而本书3D基础知识部分主要是借助于Android平台来介绍OpenGL ES 3.0 3D应用及游戏开发的.故本章将向读者简要介绍一些在Android游戏开发中必备的一些基础知识,如音效.文件的读取.游戏信息的存储.Socket网络.蓝牙网络等. 提示 由于介绍Andr

OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例》一6.3 定位光与定向光

6.3 定位光与定向光 OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例上一节中介绍的光照效果都是基于定位光光源的,定位光光源类似于现实生活中的白炽灯灯泡,其在某个固定的位置,发出的光向四周发散.定位光照射的一个明显特点就是,在给定光源位置的情况下,对不同位置的物体产生的光照效果不同. 现实世界中并不都是定位光,例如照射到地面上的阳光,光线之间是平行的,这种光称为定向光.定向光照射的明显特点是,在给定光线方向的情况下,场景中不同位置的物体反映出的光照效果完全一致.图6-16中对定位

《OpenGL ES 3.x游戏开发(下卷)》一1.5 其他缓冲区对象操作

1.5 其他缓冲区对象操作 前面已经介绍了顶点缓冲区对象.顶点数组对象.一致缓冲区对象以及映射缓冲区对象,本节将介绍两个其他的缓冲区对象操作,包括复制缓冲区对象(Copying Buffer Objects)以及从颜色缓冲区复制纹理数据(Copying Texture Data from the Color Buffer). 1.5.1 复制缓冲区对象 到目前为止,已经介绍了如何使用glBufferData.glBufferSubData以及 glMapBufferRange方法将数据加载到缓冲

《OpenGL ES 3.x游戏开发(下卷)》一1.8 小结

1.8 小结 本章主要介绍了顶点缓冲区对象.顶点数组对象.一致缓冲区对象.映射缓冲区对象.复制缓冲区对象.从颜色缓冲区复制纹理数据.帧缓冲与渲染缓冲以及多重渲染目标等关于缓冲的基本知识与技术,并给出了一些典型的小案例. 通过本章的学习,读者可以初步领会缓冲区对象所起的重要作用,为以后开发更加复杂.更高性能的3D应用或游戏奠定了良好的基础.

《OpenGL ES 3.x游戏开发(下卷)》一1.4 映射缓冲区对象

1.4 映射缓冲区对象 前面几节已经介绍了顶点缓冲区对象.顶点数组对象以及一致缓冲区对象,通过使用这些技术可以在很大程度上提高绘制效率.本节将介绍在某些情况下可以进一步提高效率的映射缓冲区对象(Mapping Buffer Objects). 1.4.1 基本知识与案例效果 本章前面的几个案例中,都是通过调用glBufferData方法或者glBufferSubData方法向缓冲区中送入数据或者更新数据的.采用这种策略时需要首先将数据在内存中准备好,然后再通过glBufferData方法或glB