I attempting to render an exported model in .obj form (exported from blender). It is a sphere and my app crashes only on Nexus 5 phone. It is working on Andy emulator and other Android devices.
While debugging, I tried changing the value of the 'count' parameter, to see what would happen. My sphere has 960 faces (so I should draw 2880 to see the full model). However, if I put 1785 or more, it will crash. Using 1784 or less, it doesn't crash (but I only see a part of the model).
It crash on GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 1784);
private void draw()
{
mCubePositions.position(0);
GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 0, mCubePositions);
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Pass in the normal information
mCubeNormals.position(0);
GLES20.glVertexAttribPointer(mNormalHandle, 3, GLES20.GL_FLOAT, false, 0, mCubeNormals);
GLES20.glEnableVertexAttribArray(mNormalHandle);
// This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
// (which currently contains model * view).
Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
// Pass in the modelview matrix.
GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0);
// This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
// (which now contains model * view * projection).
Matrix.multiplyMM(mTemporaryMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
System.arraycopy(mTemporaryMatrix, 0, mMVPMatrix, 0, 16);
// Pass in the combined matrix.
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
// Pass in the light position in eye space.
GLES20.glUniform3f(mLightPosHandle, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1], mLightPosInEyeSpace[2]);
// Draw the cube.
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 1784);
}
My OBJ reader
public static void readModel(Context context, int resId) {
// read in all the lines and put in their respective arraylists of strings
// reason I do this is to get a count of the faces to be used to initialize the
// float arrays
ArrayList<String> vertexes = new ArrayList<String>();
ArrayList<String> vertexNormals = new ArrayList<String>();
ArrayList<String> textures = new ArrayList<String>();
ArrayList<String> faces = new ArrayList<String>();
InputStream iStream = context.getResources().openRawResource(resId);
InputStreamReader isr = new InputStreamReader(iStream);
BufferedReader bReader = new BufferedReader(isr);
String line;
try {
while ((line = bReader.readLine()) != null) {
// do not read in the leading v, vt or f
if (line.startsWith("v ")) vertexes.add(line.substring(2));
if (line.startsWith("vn ")) vertexNormals.add(line.substring(3));
if (line.startsWith("vt ")) textures.add(line.substring(3));
if (line.startsWith("f ")) faces.add(line.substring(2));
}
} catch (IOException e) {
e.printStackTrace();
}
// holding arrays for the vertices, texture coords and indexes
float[] vCoords = new float[faces.size() *3*3];
float[] vNCoords = new float[faces.size()*3*3];
float[] vtCoords = new float[faces.size()*3*2];
totalCaras = faces.size();
int vertexIndex = 0;
int faceIndex = 0;
int textureIndex = 0;
// for each face
for (String i : faces) {
// for each face component
for (String j : i.split(" ")) {
String[] faceComponent = j.split("//");
String vertex = vertexes.get(Integer.parseInt(faceComponent[0]) - 1);
String normal = vertexNormals.get(Integer.parseInt(faceComponent[1]) - 1);
String vertexComp[] = vertex.split(" ");
String normalComp[] = normal.split(" ");
for (String v : vertexComp) {
vCoords[vertexIndex++] = Float.parseFloat(v);
}
for (String n : normalComp) {
vNCoords[faceIndex++] = Float.parseFloat(n);
}
}
}
mCubePositions = ByteBuffer.allocateDirect(vCoords.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
mCubePositions.put(vCoords).position(0);
mCubeNormals = ByteBuffer.allocateDirect(vNCoords.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
mCubeNormals.put(vNCoords).position(0);
}
The only trace that logcat shows:
06-10 09:08:32.016: D/OpenGLRenderer(6041): Use EGL_SWAP_BEHAVIOR_PRESERVED: true
06-10 09:08:32.027: D/Atlas(6041): Validating map...
06-10 09:08:32.074: I/Adreno-EGL(6041): <qeglDrvAPI_eglInitialize:379>: QUALCOMM Build: 01/14/15, ab0075f, Id3510ff6dc
06-10 09:08:32.075: I/OpenGLRenderer(6041): Initialized EGL, version 1.4
06-10 09:05:05.724: D/OpenGLRenderer(5242): Enabling debug mode 0
06-10 09:05:05.878: A/libc(5242): Fatal signal 11 (SIGSEGV), code 2, fault addr 0x74615000 in tid 5279 (GLThread 13643)