OpenGL ES 2.0在解开VBO后在glDrawElements上崩溃



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

我只是试图绘制一个二维精灵并设置它的动画。我有一个线程与渲染循环同时运行(在GLSurfaceView和GLSurfaceView.render中),用不同的纹理坐标更新精灵表中的VBO。但据我所知,问题并不是从哪里来的。

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

编辑:我刚刚发布了这篇文章,我意识到我忘了提到,在glBindBuffer上快速阅读后,我发现:

保留值零,但没有默认的缓冲区对象每个缓冲对象目标。相反,缓冲区有效地设置为零解除绑定以前绑定的任何缓冲区对象,并恢复客户端内存该缓冲区对象目标的使用情况(如果该目标支持)。

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

以下是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

操作顺序有点混乱。设置顶点属性指针时,必须先绑定缓冲区,然后设置指针。

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]);
...
}

添加缓冲区解除绑定代码时会出现错误,因为在其他情况下,正确的缓冲区仍然从构造函数绑定。

相关内容

  • 没有找到相关文章

最新更新