错误剩余()<计数<在GLSurfaceView.Renderer中需要

时间:2016-02-20 10:36:47

标签: android opengl-es

我正在尝试在OpenGL ES中创建一个三角形。但是,gl.glDrawElements(GL10.GL_TRIANGLES, pIndex.length, GL10.GL_UNSIGNED_SHORT, pBuff);方法中的代码中的draw行崩溃了。

public class GLTriangleEx {

    private float vertices[] = {
        0f, 1f, // point 0
        1f, -1f, // point 1
        -1f, -1f // point 2
    };

    private  FloatBuffer vertBuff;

    private short[] pIndex = {0, 1, 2};

    private ShortBuffer pBuff;

    public GLTriangleEx() {
        ByteBuffer bBuff = ByteBuffer.allocateDirect(vertices.length * 4);
        bBuff.order(ByteOrder.nativeOrder());
        vertBuff = bBuff.asFloatBuffer();
        vertBuff.put(vertices);
        vertBuff.position(0);

        ByteBuffer pbBuff = ByteBuffer.allocateDirect(pIndex.length * 2);
        pbBuff.order(ByteOrder.nativeOrder());
        pBuff = pbBuff.asShortBuffer();
        pBuff.put(pIndex);
        pbBuff.position(0);
    }

    public void draw(GL10 gl){
        gl.glFrontFace(GL10.GL_CW);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertBuff);

        // app crashes here.
        gl.glDrawElements(GL10.GL_TRIANGLES, pIndex.length, GL10.GL_UNSIGNED_SHORT, pBuff);
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    }

崩溃日志猫是

            java.lang.ArrayIndexOutOfBoundsException: remaining() < count < needed
            at com.google.android.gles_jni.GLImpl.glDrawElements(Native Method)
            at com.mobility.opengleslearning.GLTriangleEx.draw(GLTriangleEx.java:45)
            at com.mobility.opengleslearning.GLRenderer.onDrawFrame(GLRenderer.java:38)
            at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1522)
            at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1239)

我已查看以下链接以获取帮助但对我的案例没用:

  1. Android OpenGL error: "remaining() < needed" and Android 4.4

  2. Beginning to learn OpenGL ES. Drawing quad

1 个答案:

答案 0 :(得分:3)

您需要回放用于索引的ShortBuffer。在这段代码中:

ByteBuffer pbBuff = ByteBuffer.allocateDirect(pIndex.length * 2);
pbBuff.order(ByteOrder.nativeOrder());
pBuff = pbBuff.asShortBuffer();
pBuff.put(pIndex);
pbBuff.position(0);

您正在倒退pbBuff,这是潜在的ByteBuffer

asShortBuffer()返回与原始缓冲区共享基础数据的视图缓冲区。从documentation(我强调):

  

视图缓冲区只是另一个缓冲区,其内容由字节缓冲区支持。字节缓冲区内容的更改将在视图缓冲区中可见,反之亦然; 两个缓冲区&#39;位置,限制和标记值是独立的

所以pBuff,你的视图缓冲区,有自己的位置。您需要回放视图缓冲区,这是您稍后使用的缓冲区:

pBuff.position(0);