2016-07-12 23 views
0

Ich erstelle ein VBO mit GLES20 in Android und bin derzeit in einem JNI-Fehler läuft. Ich überprüfe Kapazität und Wert counts. Ich habe auch überprüft, ob der Puffer (STANDARD_QUAD in meinem Code) und ID bekommt. Ich weiß wirklich nicht weiter. Ich habe auf zwei verschiedenen physischen Geräten und einem Emulator getestet, so dass der Fehler irgendwo im Code sein muss.Android GLES20 - kann VBO nicht erstellen - JNI ERROR

Code:

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); 

Ausgang:

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) 

EDIT:

den Code der folgenden ändern, den Fehler ändert.

Der Fehler ändert sich in JNI DETECTED ERROR IN APPLICATION: jarray was null. Aber definitiv Puffer! = Null. Es ist wirklich komisch.

+0

Ist diese Zeile 'GLES20.glBufferData (GLES20.GL_ARRAY_BUFFER, puffer.capacity(), Puffer, GLES20.GL_STATIC_DRAW)' 'vielleicht in einen Mutex verpackt? – Shark

+0

@Shark, wenn Sie meinen, ob es synchronisiert ist, dann ist no, außer 'android.opengl.GLSurfaceView $ GLThread.guardedRun (GLSurfaceView.java:1561)' synchronisiert. –

+0

Lesen Sie den StackTrace erneut, die angegebene Zeile ist problematisch, da sie 'ReleasePrimitiveArrayCritical' aufruft, was den' 'zu viele kritische Releases'-Fehler verursacht, der mit einem Mutex verbunden sein kann oder nicht (siehe Mutator 'held mutexes =') Sperre "(geteilte gehalten)" Teil?) – Shark

Antwort

1

Ich löste es schließlich mit buffer.position(0) anstelle von buffer.flip().

Nach der docs buffer.flip() sollte korrekt funktionieren, da es auch die Position auf 0. Der einzige Unterschied Einstellung ist, dass flip() wird auch die limit auf die letzte Position einstellen (siehe the docs für weitere Informationen). Also ist es möglich, dass das Limit das seltsame Verhalten verursacht.