Android 在OpenGL ES 2.0中使用单独的缓冲区和索引信息

Android 在OpenGL ES 2.0中使用单独的缓冲区和索引信息,android,opengl-es,Android,Opengl Es,目前,我正在编写一个小型的OpenGLES2.0应用程序,以了解其工作原理。我制作了一个简单的.obj加载程序,将模型拉入并渲染到手机屏幕上。到目前为止,我已经在完全基于顶点将对象渲染到屏幕上方面取得了一些相对成功 我所困惑的是,如何考虑像正常情况一样的附加信息 //Get handle to vertex shader's vPosition member. int mPositionHandle = GLES20.glGetAttribLocation(_sProgram,

目前,我正在编写一个小型的OpenGLES2.0应用程序,以了解其工作原理。我制作了一个简单的.obj加载程序,将模型拉入并渲染到手机屏幕上。到目前为止,我已经在完全基于顶点将对象渲染到屏幕上方面取得了一些相对成功

我所困惑的是,如何考虑像正常情况一样的附加信息

//Get handle to vertex shader's vPosition member.
        int mPositionHandle = GLES20.glGetAttribLocation(_sProgram, "vPosition");

        //Get handle to vertex shader's vNormal member.
        int mNormalHandle = GLES20.glGetAttribLocation(_sProgram, "vNormal");

        // Enable generic vertex attribute array
        GLES20.glEnableVertexAttribArray(mPositionHandle);

        // Pass in the position information
        GLES20.glEnableVertexAttribArray(mNormalHandle);

        GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, modelLoader.getVertBuffer());

        GLES20.glVertexAttribPointer(mNormalHandle, 3, GLES20.GL_FLOAT, false, 0, modelLoader.getNormalBuffer());

        // Get handle to shape's transformation matrix
        int mtrxhandle = GLES20.glGetUniformLocation(_sProgram, "uMVPMatrix");

        // Apply the projection and view transformation
        GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, projViewMat, 0);

        GLES20.glDrawElements(GLES20.GL_TRIANGLES, modelLoader.getIndices().length, GLES20.GL_UNSIGNED_SHORT, modelLoader.getIndBuffer());
我在这里有顶点,在索引缓冲区中,我基本上保存每个面的顶点位置,以便:

v[0] = x y z
v[1] = x y z
v[2] = x y z

Indices for face 1 = 0 1 2
我不确定的是如何定义法线与顶点之间的关系。我是否应该将这些信息与索引一起包含,并具有类似的内容

Indices for face 1 = 0 1 2 n1 n1 n1

有人能解释一下这是如何设置的吗?

你不能这样做,至少在OpenGL ES中不能

在桌面GL中,AMD有一个扩展,可以将多个离散属性索引塞进单个索引数组中。但是,通常每个索引都表示:从索引中拉出位置和所有其他顶点属性。您必须具有与位置顶点属性相同的法线顶点属性


有一种替代方法涉及顶点纹理提取,但速度较慢且不受很好的支持(在ES 2.0中,顶点纹理提取是可选的)。您最好的选择是复制法线属性,以便在位置和法线之间具有1:1的关系。它需要更多的内存,但它是性能最好、最兼容的解决方案。

所以我要做的是将缓冲区构建为一个紧凑的缓冲区,并使其能够读取x、y、z、nx、ny、nz?我仍然感到困惑,因为如果这样做的话,我是否会得到相同法线的倍数,这将是低效的?是的,这就是你必须要做的。是的,从存储的角度来看,它是低效的。然而,当硬件能够获取三角形所需的所有顶点数据而不在顶点数组周围跳跃时,它的工作效果最佳。顶点阶段中的大量缓存专用于后期T&L(即,存储顶点着色器运行后计算的值),以便具有共享顶点的三角形不会反复变换同一顶点,因为这最终比存储重复的顶点属性效率要低得多。GDDR的延迟相当高,所以您希望在一次操作中获取尽可能多的有用信息。它也是高带宽的,因此如果数据结构正确,这两件事往往会相互抵消。交错顶点数据是为此目的正确构造数据的一种方法。你不必这样做,你可以有单独的缓冲区,但你仍然需要有一个正常的每个位置。嵌入式设备上的各种各样的内存结构使这一点变得复杂,但通常交错阵列即使复制数据也很好。谢谢,这是一种非常草率的方法,但我想这是我无法控制的。