几个月前,在我将Nexus 4更新为Android 5.1(现在是5.1.1 - 来自Google的库存工厂图像)之后,我的一款游戏在使用带有GL_POINTS的glDrawArrays绘制粒子时开始崩溃。我已经简化了,用Java重新实现了代码,并复制了崩溃。
崩溃始终是致命信号7(SIGBUS),代码2似乎是OpenGL驱动程序代码。
在这个测试中,对于我来说,在for循环中有118个drawPoint()调用,一切似乎运行正常,但如果我尝试119个drawPoint()调用则崩溃(下一帧)。对drawPoint()的任意数量的调用,超过119,也会崩溃。
此Java代码在Nexus 4虚拟设备上运行正常。最初的C代码可以在PC,iOS和其他Android设备上运行,没有任何问题。
这似乎可能是Nexus 4驱动程序问题。有什么想法吗?
logcat的:
--------- beginning of crash
A/libc﹕ Fatal signal 7 (SIGBUS), code 2, fault addr 0xa2876000 in tid 17998 (GLThread 14477)
I/DEBUG﹕ *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG﹕ Build fingerprint: 'google/occam/mako:5.1.1/LMY47V/1836172:user/release-keys'
I/DEBUG﹕ Revision: '11'
I/DEBUG﹕ ABI: 'arm'
I/DEBUG﹕ pid: 17822, tid: 17998, name: GLThread 14477 >>> com.joeco.pointsprites <<<
I/DEBUG﹕ signal 7 (SIGBUS), code 2 (BUS_ADRERR), fault addr 0xa2876000
I/DEBUG﹕ r0 c0004600 r1 a2876000 r2 04000000 r3 a2876000
I/DEBUG﹕ r4 b7755818 r5 00000000 r6 b776d550 r7 00000018
I/DEBUG﹕ r8 b776d550 r9 04000000 sl 00008000 fp 00000000
I/DEBUG﹕ ip fc000000 sp a4601850 lr abad3c91 pc abac38e6 cpsr 60030030
I/DEBUG﹕ backtrace:
I/DEBUG﹕ #00 pc 000ab8e6 /system/vendor/lib/egl/libGLESv2_adreno.so (oxili_write_event_write+41)
I/DEBUG﹕ #01 pc 000bbc8d /system/vendor/lib/egl/libGLESv2_adreno.so (oxili_wa_predraw+234)
I/DEBUG﹕ #02 pc 000bbef1 /system/vendor/lib/egl/libGLESv2_adreno.so (oxili_wa_point_sprite_dummy_draw+204)
I/DEBUG﹕ #03 pc 000ba47b /system/vendor/lib/egl/libGLESv2_adreno.so (oxili_primitive_drawarrays+318)
I/DEBUG﹕ #04 pc 000825cf /system/vendor/lib/egl/libGLESv2_adreno.so (rb_primitive_drawarrays+298)
I/DEBUG﹕ #05 pc 0005a4f7 /system/vendor/lib/egl/libGLESv2_adreno.so (core_glDrawArraysInstancedXXX+294)
I/DEBUG﹕ #06 pc 0005a877 /system/vendor/lib/egl/libGLESv2_adreno.so (core_glDrawArrays+6)
I/DEBUG﹕ #07 pc 00049acb /system/vendor/lib/egl/libGLESv2_adreno.so (glDrawArrays+24)
I/DEBUG﹕ #08 pc 00a5befb /data/dalvik-cache/arm/system@framework@boot.oat
MainActivity.java的代码:
// MainActivity.java -- pointsprite crash -- Joe Linhoff 6/15/2015
package com.joeco.pointsprites;
import android.app.Activity;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.os.Bundle;
import android.os.SystemClock;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ByteBuffer;
import javax.microedition.khronos.opengles.GL10;
// starting point: http://developer.android.com/training/graphics/opengl/index.html
public class MainActivity extends Activity {
public GLSurfaceView mGLView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLView = new MyGLSurfaceView(this);
setContentView(mGLView);
} // onCreate()
class MyGLSurfaceView extends GLSurfaceView {
private final MyGLRenderer mRenderer;
public MyGLSurfaceView(Context context) {
super(context);
setEGLContextClientVersion(2); // create OpenGL ES 2.0 context
mRenderer = new MyGLRenderer();
setRenderer(mRenderer);
setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
} // MyGLSurfaceView()
} // class MyGLSurvaceView
public class PointGeo {
FloatBuffer vertexBuffer;
static final int floatsPerVertex = 3;
float pointCoords[] = { 0.1f, 0.0f, 0.0f }; // xyz
final int vertexCount = pointCoords.length / floatsPerVertex;
final int vertexStride = floatsPerVertex * 4; // 4 bytes per float
public PointGeo() {
ByteBuffer bb = ByteBuffer.allocateDirect(pointCoords.length * 4); // each is 4 bytes
bb.order(ByteOrder.nativeOrder()); // device's native byte order
vertexBuffer = bb.asFloatBuffer(); // create floating point buffer
vertexBuffer.put(pointCoords); // copy coordinates into buffer
vertexBuffer.position(0); // set to first item
} // PointGeo()
} // class PointGeo
public class MyGLRenderer implements GLSurfaceView.Renderer {
private boolean mSetup = false;
private PointGeo mPoint;
private int mTriangleShaderProgram;
private int mTriangleShaderLoc_uMVPMat;
private int mTriangleShaderLoc_vPos;
private float[] mViewMat = new float[16];
private float[] mModelMat = new float[16];
private float[] mProjMat = new float[16];
private float[] mMVPMat = new float[16];
public void onDrawFrame(GL10 unused) {
if(!mSetup)
lazySetup();
GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
// build model matrix -- rotate
int time = (int)SystemClock.uptimeMillis() & 8191;
float angleInDegrees = (360.0f / 8191.0f) * time;
Matrix.setIdentityM(mModelMat, 0);
Matrix.rotateM(mModelMat, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);
// draw -- 118:ok 119:crash on next frame
for(int i=0;i<119;i++)
drawPoint();
} // onDrawFrame()
void drawPoint()
{
// setup
GLES20.glUseProgram(mTriangleShaderProgram);
GLES20.glEnableVertexAttribArray(mTriangleShaderLoc_vPos);
GLES20.glVertexAttribPointer(mTriangleShaderLoc_vPos, mPoint.floatsPerVertex,
GLES20.GL_FLOAT, false, mPoint.vertexStride, mPoint.vertexBuffer);
// build mvp matrix
Matrix.multiplyMM(mMVPMat,0,mViewMat,0,mModelMat,0);
Matrix.multiplyMM(mMVPMat, 0, mProjMat, 0, mMVPMat, 0);
GLES20.glUniformMatrix4fv(mTriangleShaderLoc_uMVPMat, 1, false, mMVPMat, 0);
// draw
GLES20.glDrawArrays(GLES20.GL_POINTS, 0, mPoint.vertexCount);
// finish
GLES20.glDisableVertexAttribArray(mTriangleShaderLoc_vPos);
GLES20.glUseProgram(0);
} // drawPoint()
@Override
public void onSurfaceCreated(GL10 gl10, javax.microedition.khronos.egl.EGLConfig eglConfig) {
} // onSurfaceCreated()
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
// create projection matrix
final float ratio = (float) width / height;
final float left = -ratio;
final float right = ratio;
final float bottom = -1.0f;
final float top = 1.0f;
final float near = 1.0f;
final float far = 10.0f;
Matrix.frustumM(mProjMat, 0, left, right, bottom, top, near, far);
} // onSurfaceChanged()
public int loadShader(int type, String shaderCode) {
int shader = GLES20.glCreateShader(type); // create shader
GLES20.glShaderSource(shader, shaderCode); // add source
GLES20.glCompileShader(shader); // compile
return shader;
} // loadShader()
private final String vertexShaderCode =
"attribute vec4 vPos;" +
"uniform mat4 uMVPMat;" +
"void main() {" +
" gl_Position = vPos*uMVPMat;" +
" gl_PointSize = 40.0f; " +
"}";
private final String fragmentShaderCode =
"void main() {" +
" gl_FragColor = vec4(0.5f,0.7f,0.5f,1.f);" +
"}";
void lazySetup()
{
mSetup=true;
mPoint = new PointGeo();
int vshader = loadShader(GLES20.GL_VERTEX_SHADER,vertexShaderCode);
int fshader = loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShaderCode);
mTriangleShaderProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(mTriangleShaderProgram, vshader);
GLES20.glAttachShader(mTriangleShaderProgram, fshader);
GLES20.glLinkProgram(mTriangleShaderProgram);
int err = GLES20.glGetError();
mTriangleShaderLoc_uMVPMat = GLES20.glGetUniformLocation(mTriangleShaderProgram, "uMVPMat");
mTriangleShaderLoc_vPos = GLES20.glGetAttribLocation(mTriangleShaderProgram, "vPos");
setViewMat();
Matrix.setIdentityM(mModelMat,0);
} // lazySetup()
void setViewMat()
{
final float eyeX = 0.0f;
final float eyeY = 0.0f;
final float eyeZ = 5.0f;
final float lookX = 0.0f;
final float lookY = 0.0f;
final float lookZ = -1.0f;
final float upX = 0.0f;
final float upY = 1.0f;
final float upZ = 0.0f;
Matrix.setLookAtM(mViewMat, 0, eyeX, eyeY, eyeZ,
lookX, lookY, lookZ, upX, upY, upZ);
} // setViewMat()
} // class MyGLRenderer
} // class MainActivity
答案 0 :(得分:0)
你的VS中有attribute vec4 vPos;
,这是4个浮点数,但你每个顶点只上传3个浮点数......改变你的顶点着色器:
attribute vec4 vPos;
- &gt; attribute vec3 vPos;
另外
gl_Position = vPos * uMVPMat;
- &gt; gl_Position = vec4(vPos, 1.0) * uMVPMat;