【问题标题】:How to properly use GLES20.glVertexAttribPointer() on android with VBOs?如何在带有 VBO 的 android 上正确使用 GLES20.glVertexAttribPointer()?
【发布时间】:2016-06-23 05:09:08
【问题描述】:

我试图让一个简单的 2D 正方形出现在屏幕上,但我遇到了 GLES20.glVertexAttribPointer() 方法中的最后一个参数的问题。

这是我的代码(draw() 方法):

public void draw(float[] matrix){
        int shaderHandle = shader.getShaderHandle();
        int mMVPMatrixHandle;

        GLES20.glUseProgram(shaderHandle);
        mPositionHandle = GLES20.glGetAttribLocation(shaderHandle, "vPosition");

        mMVPMatrixHandle = GLES20.glGetUniformLocation(shaderHandle, "uMVPMatrix");
        MyGLRenderer.checkGlError("glGetUniformLocation");

        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, matrix, 0);
        MyGLRenderer.checkGlError("glUniformMatrix4fv");

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER,vbo);
        GLES20.glEnableVertexAttribArray(mPositionHandle);
        GLES20.glVertexAttribPointer(mPositionHandle,COORDS_PER_VERTEX,GLES20.GL_FLOAT,false,0,0);

        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER,ibo);
        GLES20.glDrawElements(GLES20.GL_TRIANGLES,DRAW_ORDER.length,GLES20.GL_UNSIGNED_SHORT,null);

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER,0);
        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER,0);
    }

问题出在这一行:

GLES20.glVertexAttribPointer(mPositionHandle,COORDS_PER_VERTEX,GLES20.GL_FLOAT,false,0,0);

我正在使用 Android Studio,它告诉我不能将 0 作为此方法的最后一个参数传递,它需要一个 Buffer 对象。

为了使用我的 VBO,我被告知我必须将零作为最后一个参数。我该怎么做?

我收到的logcat条目如下:

06-23 22:27:23.098 2709-2709/? I/art: Not late-enabling -Xcheck:jni (already on)
06-23 22:27:23.222 2709-2709/com.example.android.opengl W/System: ClassLoader referenced unknown path: /data/app/com.example.android.opengl-2/lib/x86
06-23 22:27:23.362 2709-2709/com.example.android.opengl W/System: ClassLoader referenced unknown path: /data/app/com.example.android.opengl-2/lib/x86
06-23 22:27:23.432 2709-2730/com.example.android.opengl D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true

                                                                          [ 06-23 22:27:23.439  2709: 2709 D/         ]
                                                                          HostConnection::get() New Host Connection established 0xab9e4670, tid 2709


                                                                          [ 06-23 22:27:23.472  2709: 2730 D/         ]
                                                                          HostConnection::get() New Host Connection established 0xaf4471b0, tid 2730
06-23 22:27:23.474 2709-2730/com.example.android.opengl I/OpenGLRenderer: Initialized EGL, version 1.4

                                                                          [ 06-23 22:27:23.506  2709: 2729 D/         ]
                                                                          HostConnection::get() New Host Connection established 0xab9e4ac0, tid 2729
06-23 22:27:23.557 2709-2729/com.example.android.opengl I/System.out: DEBUG
06-23 22:27:23.562 2709-2729/com.example.android.opengl E/Surface: getSlotFromBufferLocked: unknown buffer: 0xb4093c00
06-23 22:27:23.565 2709-2729/com.example.android.opengl E/AndroidRuntime: FATAL EXCEPTION: GLThread 129
                                                                          Process: com.example.android.opengl, PID: 2709
                                                                          java.lang.NullPointerException: Attempt to invoke virtual method 'int java.nio.Buffer.remaining()' on a null object reference
                                                                              at android.opengl.GLES20.glVertexAttribPointer(GLES20.java:1913)
                                                                              at com.example.android.opengl.Sprite.draw(Sprite.java:105)
                                                                              at com.example.android.opengl.MyGLRenderer.onDrawFrame(MyGLRenderer.java:76)
                                                                              at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1535)
                                                                              at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)
06-23 22:27:23.607 2709-2730/com.example.android.opengl E/Surface: getSlotFromBufferLocked: unknown buffer: 0xa3b11230

【问题讨论】:

  • 你能给我们你得到的 logcat 错误声明吗?
  • 我已经在上面添加了logcat
  • 我仍然坚持我的回答,你试过了吗?
  • 其实我只是想通了我的问题。不过感谢您的帮助!

标签: android opengl-es opengl-es-2.0 vbo


【解决方案1】:

我想通了!

问题根本不在于我的代码,而在于我使用的 Android SDK 版本。有一个非常简单的解决方法。

您只需将项目的 SDK 设置(compileSdkVersion、minSdkVersion、targetSdkVersion)更改为适当的版本。我将 minSdkVersion 和 compileSdkVersion 的版本更改为 14,因为这个版本包含对 OpenGL ES 2.0 的完全(足够)支持来做我想做的事情,而且几乎没有人使用低于 14 的 SDK 版本的设备了。

【讨论】:

  • 是的,在 API 级别 8 中引入的原始 ES20 绑定中缺少此入口点,并在 API 级别 9 中添加。您可以在 API 文档中看到这一点,其中每个入口点的 API 级别已列出。至少他们在一个版本中修复了它。他们花了 6 个版本来修复 ES30 绑定中缺少的一些条目,而其他的似乎在 24 版中仍然丢失。
【解决方案2】:

我没有看到你的 logcat 输出,所以我不知道究竟是什么错误。但是,我有一个猜测;去掉最后两行 glBindBuffer 。

public void draw(float[] matrix){
    int shaderHandle = shader.getShaderHandle();
    int mMVPMatrixHandle;

    GLES20.glUseProgram(shaderHandle);
    mPositionHandle = GLES20.glGetAttribLocation(shaderHandle, "vPosition");

    mMVPMatrixHandle = GLES20.glGetUniformLocation(shaderHandle, "uMVPMatrix");
    MyGLRenderer.checkGlError("glGetUniformLocation");

    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, matrix, 0);
    MyGLRenderer.checkGlError("glUniformMatrix4fv");

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER,vbo);
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    GLES20.glVertexAttribPointer(mPositionHandle,COORDS_PER_VERTEX,GLES20.GL_FLOAT,false,0,0);

    GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER,ibo);
    GLES20.glDrawElements(GLES20.GL_TRIANGLES,DRAW_ORDER.length,GLES20.GL_UNSIGNED_SHORT,null);

}

【讨论】:

    猜你喜欢
    • 2012-01-23
    • 2021-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-10
    • 2023-03-20
    相关资源
    最近更新 更多