android - 取消绑定(bind) VBO 后,glDrawElements 上的 OpenGL ES 2.0 崩溃

标签 android opengl-es crash segmentation-fault

首先,我应该说我正在使用 Android API 27 在像素模拟器上运行它,但我在 Android API 26 上也遇到了同样的崩溃。

我只是想绘制一个二维 Sprite 并为其设置动画。我有一个线程同时运行到渲染循环(在 GLSurfaceView 和 GLSurfaceView.Renderer 中),在 Sprite 表中更新具有不同纹理坐标的 VBO。但是,据我所知,问题出在哪里。

基本上我能说的就是绑定(bind)和取消绑定(bind)我的 VBO 后 glDrawElements 崩溃,特别是取消绑定(bind)。具体来说,它是一个空指针取消引用错误。当我取消绑定(bind)我的元素缓冲区对象时,这个问题不会发生。

编辑:我刚刚发布了这个,我意识到我忘了提到在快速阅读 glBindBuffer 之后我发现:

The value zero is reserved, but there is no default buffer object for each buffer object target. Instead, buffer set to zero effectively unbinds any buffer object previously bound, and restores client memory usage for that buffer object target (if supported for that target).



关于恢复内存的部分可能是造成这种情况的原因吗?如果是这样,我将如何解绑它。

这是 Sprite.java 的代码:
package com.matthew.beatclimber;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLUtils;
import android.opengl.Matrix;

import android.content.Context;

import java.util.Timer;
import java.util.TimerTask;

/**
 * Created by matthew on 10/28/17.
 */
/*
Note to self:
This can be done to bind a attribute location to a literal
GLES20.glBindAttribLocation(program, 0, "vPosition");
 */
public class Sprite
{
    private FloatBuffer vertexBuffer;
    private ShortBuffer indexBuffer;
    private Timer animateTimer;
    private SpriteSheet spriteSheet;
    private int[] vbo = {0}, ebo = {0}, texture = {0};
    private int vertexShader, fragmentShader, program;
    static float[] vertices = {
            -16.0f, 16.0f, 0.0f, 1.0f, /*Tex Coords*/ -1.0f, 1.0f, //Top Left
            -16.0f, -16.0f, 0.0f, 1.0f,               -1.0f, -1.0f, //Bot Left
            16.0f, -16.0f, 0.0f, 1.0f,                1.0f, -1.0f, //Bot Right
            //-1.0f, 1.0f, 3.0f, 1.0f, /*Tex Coords*/ -1.0f, 1.0f, //Top Left
            //1.0f, -1.0f, 3.0f, 1.0f,                1.0f, -1.0f, //Bot Right
            16.0f, 16.0f, 0.0f, 1.0f,                 1.0f, 1.0f //Top Right
    };
    private static final short[] order = { 0, 1, 2, 0, 2, 3};
    private float[] model = new float[16];
    static float[] ortho = new float[16];
    char[] infoLog = new char[512];
    private static final String vertexShaderCode =
            "attribute vec4 vPosition;" +
                    "attribute vec2 TexCoords;" +
                    "varying vec2 texCoords;" +
                    "uniform mat4 ortho;" +
                    "uniform mat4 model;"+
                    "void main() {" +
                    "   gl_Position = ortho * model * vPosition;" +
                    "   texCoords = TexCoords;" +
                    "}";
    private static final String fragmentShaderCode =
            "precision mediump float;" +
                    "uniform sampler2D tex1;" +
                    "varying vec2 texCoords;" +
                    "void main() {" +
                    "   gl_FragColor = mix(texture2D(tex1, texCoords), vec4(texCoords, 0.0, 1.0), 0.2);" +
                    "}";
    public Sprite(int screenWidth, int screenHeight)
    {
        //Set model equal to a identity matrix
        Matrix.setIdentityM(model, 0);
        Matrix.translateM(model, 0, screenWidth / 2, screenHeight / 2, 0);
        Matrix.scaleM(model, 0, 32, 32, 0);




        ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);

        ByteBuffer dlb = ByteBuffer.allocateDirect(order.length * 2);
        dlb.order(ByteOrder.nativeOrder());
        indexBuffer = dlb.asShortBuffer();
        indexBuffer.put(order);
        indexBuffer.position(0);

        //Create shader program
        vertexShader = OpenGLES31Activity.loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
        fragmentShader = OpenGLES31Activity.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
        program = GLES20.glCreateProgram();
        int[] success = new int[2];
        GLES20.glGetShaderiv(vertexShader, GLES20.GL_COMPILE_STATUS, success, 0);
        GLES20.glGetShaderiv(fragmentShader, GLES20.GL_COMPILE_STATUS, success, 1);

        GLES20.glAttachShader(program, vertexShader);
        GLES20.glAttachShader(program, fragmentShader);

        GLES20.glBindAttribLocation(program, 0, "vPosition");
        GLES20.glBindAttribLocation(program, 1, "TexCoords");

        GLES20.glLinkProgram(program);
        if((success[0] == GLES20.GL_FALSE))
        {
            GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
            String info = GLES20.glGetShaderInfoLog(vertexShader);
            System.out.println("ERROR: VERTEX: " + info);
        }
        if ((success[1]  == GLES20.GL_FALSE))
        {
            GLES20.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
            String info = GLES20.glGetShaderInfoLog(fragmentShader);
            System.out.println("ERROR: FRAG: " + info);
        }
        //Create Buffer Objects (Vertex and Element Buffer Objects)
        GLES20.glGenBuffers(1, vbo, 0);
        GLES20.glGenBuffers(1, ebo, 0);

        //Bind Objects
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo[0]);
        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ebo[0]);

        //Write Data
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexBuffer.capacity() * 4, vertexBuffer, GLES20.GL_DYNAMIC_DRAW);
        GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBuffer.capacity() * 2, indexBuffer, GLES20.GL_STATIC_DRAW);

        //Unbind objects
        //GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
        //GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);

        animateTimer = new Timer();
    }
    public synchronized void draw()
    {
        //Use Shader Program
        GLES20.glUseProgram(program);
        //////////////////////Configure Attribute (Core OpenGL ie: in)//////////////////////////
        //Get Attribute Locations
        //int attribLocationPos = GLES20.glGetAttribLocation(program, "vPosition");
        //int attribLocationTex = GLES20.glGetAttribLocation(program, "TexCoords");

        //Enable Vertex Attribute Array
        GLES20.glEnableVertexAttribArray(0);
        GLES20.glVertexAttribPointer(0, 4, GLES20.GL_FLOAT, false, 24, 0);

        //Tex Coord Attribute
        GLES20.glEnableVertexAttribArray(1);
        GLES20.glVertexAttribPointer(1, 2, GLES20.GL_FLOAT, false, 24, 16);

        //Bind Objects
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo[0]);
        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ebo[0]);

        //int[] i = new int[1];
        //int[] j = new int[1];

        //GLES20.glGetIntegerv(GLES20.GL_ARRAY_BUFFER_BINDING, i, 0);
        //GLES20.glGetIntegerv(GLES20.GL_ELEMENT_ARRAY_BUFFER_BINDING, j, 0);
        //System.out.println(i + " " + j);

        //Set model matrix uniform to model
        GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(program, "model"), 1, false, model, 0);

        GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(program, "ortho"), 1, false, ortho, 0);

        //Texture Stuff
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture[0]);

        //Draw Square
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, order.length, GLES20.GL_UNSIGNED_SHORT, 0);
        //GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 6);

        //Disable Vertex Attribute Array
        GLES20.glDisableVertexAttribArray(0);
        GLES20.glDisableVertexAttribArray(1);

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

        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);

        //Stop using program
        //GLES20.glUseProgram(0);
    }
    public void createTextureSpriteSheet(Context context, int resourceID, int spriteWidth, int spriteHeight, int sheetWidth, int sheetHeight, int frame)
    {
        InputStream is = context.getResources().openRawResource(resourceID);
        Bitmap bitmap;
        try {
            bitmap = BitmapFactory.decodeStream(is);
        } finally {
            try {
                is.close();
            } catch(IOException e) {
                // Ignore.
            }
        }
        //bitmap = BitmapFactory.decodeFile("R.raw.blobbosheet.png      \
        ByteBuffer data = ByteBuffer.allocateDirect(bitmap.getByteCount());
        data.order(ByteOrder.nativeOrder());
        bitmap.copyPixelsToBuffer(data);
        System.out.println("Bitmap: " + bitmap.getWidth() + " " + bitmap.getHeight());
        data.position(0);
        GLES20.glGenTextures(1, texture, 0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture[0]);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
        GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap.getWidth(), bitmap.getHeight(), 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, data);
        //GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);

        spriteSheet = new SpriteSheet(sheetWidth, sheetHeight, spriteWidth, spriteHeight, 8);

        float[] texCoords = spriteSheet.getSpriteCoords(frame);
        for(int i = 0; i < 8; i++)
        {
            System.out.println("TexCoord: " + i + " is : " + texCoords[i]);
        }
        spriteSheet.setFrame(frame);

        //Update Tex Coords
        vertices[4] = texCoords[0];
        vertices[5] = texCoords[1];
        vertices[10] = texCoords[2];
        vertices[11] = texCoords[3];
        vertices[16] = texCoords[4];
        vertices[17] = texCoords[5];
        vertices[22] = texCoords[6];
        vertices[23] = texCoords[7];

        updateVBO();
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
    }
    public void switchSprite(int frame)
    {
        float[] texCoords = spriteSheet.getSpriteCoords(frame);
        spriteSheet.setFrame(frame);

        //Update Tex Coords
        vertices[4] = texCoords[0];
        vertices[5] = texCoords[1];
        vertices[10] = texCoords[2];
        vertices[11] = texCoords[3];
        vertices[16] = texCoords[4];
        vertices[17] = texCoords[5];
        vertices[22] = texCoords[6];
        vertices[23] = texCoords[7];

        updateVBO();
    }
    public void nextFrame()
    {
        float[] texCoords = spriteSheet.nextFrame();

        for(int i = 0; i < 8; i++)
        {
            System.out.println("TexCoord: " + i + " is : " + texCoords[i]);
        }
        //Update Tex Coords
        vertices[4] = texCoords[0];
        vertices[5] = texCoords[1];
        vertices[10] = texCoords[2];
        vertices[11] = texCoords[3];
        vertices[16] = texCoords[4];
        vertices[17] = texCoords[5];
        vertices[22] = texCoords[6];
        vertices[23] = texCoords[7];

        updateVBO();
    }
    public void animate(int startFrame, int framesPerSec, final int numbOfFrames)
    {
        switchSprite(startFrame);
        TimerTask task = new TimerTask()
        {
            int count = 0;
            public void run()
            {
               nextFrame();
               count++;
               System.out.println("Animate Thread Going!");
               if(count == numbOfFrames)
               {
                   System.out.println("Animate Thread Canceled");
                   cancel();
               }
            }
        };
        animateTimer.scheduleAtFixedRate(task, 0, 1000 / framesPerSec);
    }
    public synchronized void updateVBO()
    {
        System.out.println("In updateVBO()");
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo[0]);
        vertexBuffer.clear();
        vertexBuffer.put(vertices).flip();
        float[] test = new float[vertexBuffer.capacity()];
        vertexBuffer.get(test);
        for(float i : test)
        {
            System.out.println(i + ", ");
        }
        vertexBuffer.clear();
        vertexBuffer.put(vertices).flip();
        for(int i = 4; i < 23; i += 6)
        {
            System.out.println("TexCoord: " + i + " is : " + vertices[i]);
            System.out.println("TexCoord: " + i + " is : " + vertices[i + 1]);
        }
        System.out.println(vertexBuffer.capacity() * 4 + " " + vertexBuffer.remaining());
        GLES20.glBufferSubData(GLES20.GL_ARRAY_BUFFER, 0, vertexBuffer.capacity() * 4, vertexBuffer);
        //GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexBuffer.capacity() * 4, )
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
    }
}

和我的渲染器的代码:
package com.matthew.beatclimber;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.Matrix;
import android.content.Context;
import android.util.DisplayMetrics;
import android.view.Display;

import android.app.Activity;
/**
 * Created by matthew on 10/28/17.
 */

public class MyGLRenderer implements GLSurfaceView.Renderer
{
    Sprite sprite;
    float[] orthoProjection = new float[16];
    Context context;
    public MyGLRenderer(Context context)
    {
        this.context = context;
    }
    @Override
    public void onSurfaceCreated(GL10 gl10, EGLConfig config) {
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        sprite = new Sprite(1080, 1704);
        sprite.createTextureSpriteSheet(context, R.drawable.blobbosheet, 32, 32, 256, 32, 0);

        sprite.animate(0, 2, -1);
    }

    @Override
    public void onSurfaceChanged(GL10 gl10, int width, int height) {
        GLES20.glViewport(0, 0, width, height);

        Matrix.orthoM(orthoProjection, 0, 0, width, 0, height, -1, 100);
        Sprite.ortho = orthoProjection;
    }

    @Override
    public void onDrawFrame(GL10 gl10)
    {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
        System.out.println("Drawing");
        sprite.draw();
    }
}

这也是它转储到日志中的内容:
11-04 17:50:41.569 13651-13670/com.matthew.beatclimber A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x10 in tid 13670 (GLThread 490), pid 13651 (hew.beatclimber)
11-04 17:50:41.606 13678-13678/? A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
11-04 17:50:41.606 13678-13678/? A/DEBUG: Build fingerprint: 'google/sdk_gphone_x86/generic_x86:8.1.0/OPM1.171004.001/4376136:userdebug/dev-keys'
11-04 17:50:41.606 13678-13678/? A/DEBUG: Revision: '0'
11-04 17:50:41.606 13678-13678/? A/DEBUG: ABI: 'x86'
11-04 17:50:41.606 13678-13678/? A/DEBUG: pid: 13651, tid: 13670, name: GLThread 490  >>> com.matthew.beatclimber <<<
11-04 17:50:41.606 13678-13678/? A/DEBUG: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x10
11-04 17:50:41.606 13678-13678/? A/DEBUG: Cause: null pointer dereference
11-04 17:50:41.606 13678-13678/? A/DEBUG:     eax 00000010  ebx 9eaf3be4  ecx 00000008  edx 8f4000ea
11-04 17:50:41.606 13678-13678/? A/DEBUG:     esi 00000010  edi 00000000
11-04 17:50:41.606 13678-13678/? A/DEBUG:     xcs 00000073  xds 0000007b  xes 0000007b  xfs 0000003b  xss 0000007b
11-04 17:50:41.606 13678-13678/? A/DEBUG:     eip ab72b33c  ebp 8ff7c5c8  esp 8ff7c588  flags 00010202
11-04 17:50:41.907 13678-13678/? A/DEBUG: backtrace:
11-04 17:50:41.907 13678-13678/? A/DEBUG:     #00 pc 0001a33c  /system/lib/libc.so (memcpy+732)
11-04 17:50:41.907 13678-13678/? A/DEBUG:     #01 pc 00021cd0  /vendor/lib/egl/libEGL_emulation.so (glUtilsPackPointerData+480)
11-04 17:50:41.907 13678-13678/? A/DEBUG:     #02 pc 0003bb98  /vendor/lib/libGLESv2_enc.so ((anonymous namespace)::glVertexAttribPointerData_enc(void*, unsigned int, int, unsigned int, unsigned char, int, void*, unsigned int)+184)
11-04 17:50:41.907 13678-13678/? A/DEBUG:     #03 pc 000286c4  /vendor/lib/libGLESv2_enc.so (GL2Encoder::sendVertexAttributes(int, int, bool, int)+1124)
11-04 17:50:41.907 13678-13678/? A/DEBUG:     #04 pc 000167ce  /vendor/lib/libGLESv2_enc.so (GL2Encoder::s_glDrawElements(void*, unsigned int, int, unsigned int, void const*)+958)
11-04 17:50:41.907 13678-13678/? A/DEBUG:     #05 pc 00009c3f  /vendor/lib/egl/libGLESv2_emulation.so (glDrawElements+79)
11-04 17:50:41.907 13678-13678/? A/DEBUG:     #06 pc 00099c16  /system/lib/libandroid_runtime.so (android_glDrawElements__IIII(_JNIEnv*, _jobject*, int, int, int, int)+38)
11-04 17:50:41.907 13678-13678/? A/DEBUG:     #07 pc 00e82a36  /system/framework/x86/boot-framework.oat (offset 0x5fc000) (android.opengl.GLES10.glClearColorx [DEDUPED]+182)
11-04 17:50:41.907 13678-13678/? A/DEBUG:     #08 pc 00642032  /system/lib/libart.so (art_quick_invoke_static_stub+418)
11-04 17:50:41.907 13678-13678/? A/DEBUG:     #09 pc 00116009  /system/lib/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+265)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #10 pc 0032143f  /system/lib/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+335)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #11 pc 0031a6a4  /system/lib/libart.so (_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE+836)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #12 pc 0062927a  /system/lib/libart.so (MterpInvokeStatic+282)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #13 pc 00633021  /system/lib/libart.so (artMterpAsmInstructionStart+14497)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #14 pc 002f392b  /system/lib/libart.so (art::interpreter::Execute(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue, bool)+539)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #15 pc 002fa1e7  /system/lib/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame*, art::JValue*)+231)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #16 pc 0031a68a  /system/lib/libart.so (_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE+810)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #17 pc 00627a44  /system/lib/libart.so (MterpInvokeVirtual+756)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #18 pc 00632ea1  /system/lib/libart.so (artMterpAsmInstructionStart+14113)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #19 pc 002f392b  /system/lib/libart.so (art::interpreter::Execute(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue, bool)+539)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #20 pc 002fa1e7  /system/lib/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame*, art::JValue*)+231)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #21 pc 0031a68a  /system/lib/libart.so (_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE+810)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #22 pc 00628c0f  /system/lib/libart.so (MterpInvokeInterface+1647)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #23 pc 006330a1  /system/lib/libart.so (artMterpAsmInstructionStart+14625)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #24 pc 002f392b  /system/lib/libart.so (art::interpreter::Execute(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue, bool)+539)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #25 pc 002fa1e7  /system/lib/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame*, art::JValue*)+231)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #26 pc 0031a68a  /system/lib/libart.so (_ZN3art11interpreter6DoCallILb0ELb0EEEbPNS_9ArtMethodEPNS_6ThreadERNS_11ShadowFrameEPKNS_11InstructionEtPNS_6JValueE+810)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #27 pc 0062905c  /system/lib/libart.so (MterpInvokeDirect+428)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #28 pc 00632fa1  /system/lib/libart.so (artMterpAsmInstructionStart+14369)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #29 pc 002f392b  /system/lib/libart.so (art::interpreter::Execute(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue, bool)+539)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #30 pc 002fa0cb  /system/lib/libart.so (art::interpreter::EnterInterpreterFromEntryPoint(art::Thread*, art::DexFile::CodeItem const*, art::ShadowFrame*)+139)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #31 pc 006175ef  /system/lib/libart.so (artQuickToInterpreterBridge+1311)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #32 pc 00647f2d  /system/lib/libart.so (art_quick_to_interpreter_bridge+77)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #33 pc 00641e62  /system/lib/libart.so (art_quick_invoke_stub+338)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #34 pc 00115fdf  /system/lib/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+223)
11-04 17:50:41.908 13678-13678/? A/DEBUG:     #35 pc 00544aeb  /system/lib/libart.so (art::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::ArgArray*, art::JValue*, char const*)+91)
11-04 17:50:41.909 13678-13678/? A/DEBUG:     #36 pc 00545fb8  /system/lib/libart.so (art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue*)+744)
11-04 17:50:41.909 13678-13678/? A/DEBUG:     #37 pc 0057512f  /system/lib/libart.so (art::Thread::CreateCallback(void*)+1487)
11-04 17:50:41.909 13678-13678/? A/DEBUG:     #38 pc 00071445  /system/lib/libc.so (__pthread_start(void*)+53)
11-04 17:50:41.909 13678-13678/? A/DEBUG:     #39 pc 000205db  /system/lib/libc.so (__start_thread+75)
11-04 17:50:41.909 13678-13678/? A/DEBUG:     #40 pc 0001ec16  /system/lib/libc.so (__bionic_clone+70)
11-04 17:50:42.190 1484-1484/? E//system/bin/tombstoned: Tombstone written to: /data/tombstones/tombstone_04

最佳答案

操作顺序有点困惑。设置顶点属性指针时,必须先绑定(bind)缓冲区,然后设置指针。

public synchronized void draw()
{
    //Use Shader Program
    GLES20.glUseProgram(program);

    //Enable Vertex Attribute Array
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo[0]);

    GLES20.glEnableVertexAttribArray(0);
    GLES20.glVertexAttribPointer(0, 4, GLES20.GL_FLOAT, false, 24, 0);

    //Tex Coord Attribute
    GLES20.glEnableVertexAttribArray(1);
    GLES20.glVertexAttribPointer(1, 2, GLES20.GL_FLOAT, false, 24, 16);

    //Bind Index Buffer
    GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, ebo[0]);
    ...
}

添加缓冲区解除绑定(bind)代码时会出现错误,因为否则仍然会从构造函数绑定(bind)正确的缓冲区。

关于android - 取消绑定(bind) VBO 后,glDrawElements 上的 OpenGL ES 2.0 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47116154/

相关文章:

android - 从我的 Activity 中启动后,如何在正常操作中打开系统摄像头?

android - firebase 函数触发通知

android - 三个activity down后如何回到main activity?

安卓导航 View : Scroll the menu items only issue

swift - glVertexAttribPointer() last at OpenGL 中的属性值可以是一个数组吗?

android - 使用 Sceneform 实时下载 3D 模型

ios - 哪种环境适合 iOS 中的 Tic Tac Toe 等游戏?

ios - tableview 为零并且应用程序崩溃 ios xcode

windows - 远程执行时短 LdrLoadDll stub 崩溃

iphone - iPhone应用程序崩溃日志