opengl es 2.0 - Android GLES20 - 无法创建 VBO - JNI 错误



我正在Android中使用GLES20创建一个VBO,目前遇到了JNI错误。我仔细检查了容量和值计数。我还检查了缓冲区(STANDARD_QUAD在我的代码中)是否得到和 ID。我真的不知道该如何继续。我在 2 个不同的物理设备和一个模拟器上进行了测试,因此故障一定在代码的某个地方。

法典:

    ByteBuffer buffer = ByteBuffer.allocate(30 * 4);
    buffer.order(ByteOrder.nativeOrder());
    buffer.asFloatBuffer().put(new float[]{
            0, 0, 0,    0,0,
            0,  1, 0,   0,1,
             1, 0, 0,   1,0,
             1,  1, 0,  1,1,
            1, 0, 0,    1,0,
             0, 1, 0,   0,1
    });
    buffer.flip();
    int[] vboids = new int[1];
    GLES20.glGenBuffers(1, vboids, 0);
    STANDARD_QUAD = vboids[0];
    System.out.println("init vbo (std quad): " + STANDARD_QUAD + ", buffer.capacity: " + buffer.capacity());
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, STANDARD_QUAD);
    GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, buffer.capacity(), buffer, GLES20.GL_STATIC_DRAW);
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);

输出:

init vbo (std quad): 1, buffer.capacity: 120
JNI DETECTED ERROR IN APPLICATION: thread Thread[13,tid=19730,Runnable,Thread*=0xb4e08800,peer=0x12c07060,"GLThread 13050"] called too many critical releases
     in call to ReleasePrimitiveArrayCritical
     from void android.opengl.GLES20.glBufferData(int, int, java.nio.Buffer, int)
 "GLThread 13050" prio=5 tid=13 Runnable
   | group="main" sCount=0 dsCount=0 obj=0x12c07060 self=0xb4e08800
   | sysTid=19730 nice=-11 cgrp=apps sched=0/0 handle=0xaf854300
   | state=R schedstat=( 73594541 5530250 17 ) utm=6 stm=1 core=5 HZ=100
   | stack=0xa10fe000-0xa1100000 stackSize=1036KB
   | held mutexes= "mutator lock"(shared held)
   native: #00 pc 00004c58  /system/lib/libbacktrace_libc++.so (UnwindCurrent::Unwind(unsigned int, ucontext*)+23)
   native: #01 pc 000034c1  /system/lib/libbacktrace_libc++.so (Backtrace::Unwind(unsigned int, ucontext*)+8)
   native: #02 pc 0025c5ad  /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::mirror::ArtMethod*)+84)
   native: #03 pc 0023f8cb  /system/lib/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+162)
   native: #04 pc 000b313d  /system/lib/libart.so (art::JniAbort(char const*, char const*)+620)
   native: #05 pc 000b386d  /system/lib/libart.so (art::JniAbortF(char const*, char const*, ...)+68)
   native: #06 pc 000b6b65  /system/lib/libart.so (art::ScopedCheck::ScopedCheck(_JNIEnv*, int, char const*)+1436)
   native: #07 pc 000c1de7  /system/lib/libart.so (art::CheckJNI::ReleasePrimitiveArrayCritical(_JNIEnv*, _jarray*, void*, int)+42)
   native: #08 pc 000684d1  /system/lib/libandroid_runtime.so (???)
   native: #09 pc 000736e3  /system/lib/libandroid_runtime.so (???)
   native: #10 pc 01574071  /system/framework/arm/boot.oat (Java_android_opengl_GLES20_glBufferData__IILjava_nio_Buffer_2I+128)
   at android.opengl.GLES20.glBufferData(Native method)
   at my.package.glsl.GuiProgram.initQuad(GuiProgram.java:66)
   at my.package.glsl.GuiProgram.onCreated(GuiProgram.java:111)
   at my.package.glsl.Program.create(Program.java:67)
   at my.package.glsl.Shaders.initialize(Shaders.java:26)
   at my.package.myapplication.FullscreenActivity.renderGL(FullscreenActivity.java:66)
   at my.package.myapplication.FullscreenActivity.access$000(FullscreenActivity.java:22)
   at my.package.myapplication.FullscreenActivity$1.render(FullscreenActivity.java:42)
   at my.package.opengl.OpenglRenderer.onDrawFrame(OpenglRenderer.java:38)
   at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1561)
   at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1278)

编辑:

代码更改为以下内容,错误将更改。

    FloatBuffer buffer = ByteBuffer.allocate(30 * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
    buffer.put(new float[]{
            //...
    });
    buffer.flip();
    //...
    GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, buffer.capacity() * 4, buffer, GLES20.GL_STATIC_DRAW);

错误将更改为 JNI DETECTED ERROR IN APPLICATION: jarray was null 。但绝对是缓冲区 != 空。这真的很奇怪。

我终于通过使用buffer.position(0)而不是buffer.flip()解决了它。

根据文档buffer.flip()应该正常工作,因为它也将位置设置为 0。唯一的区别是flip()还将limit设置为最后一个位置(有关更多信息,请参阅文档)。因此,限制可能会导致奇怪的行为。

最新更新