Hello guys, first post here hopefully I can find some help.
I am fairly new to opengl but I like it so far. I wrote a .obj parser and it works great if I use gl_drawArrays() which works great but if I use gl_drawElements() its all funky… I get the feeling I am doing something incorrectly but I hope that someone here can help me figure out what i’m doing.
Here is my parser and vbo setup code so far.
private void parseData(String data){
String[] lines = data.split("
");
for (int i = 0; i < lines.length; i++) {
String l = lines[i];
if(l.startsWith("#")){
continue;
}
if(l.startsWith("v ")){
String[] verts = l.split("[ ]");
parseVertex(l, verts);
numberOfVertexAttributes++;
continue;
}
if(l.startsWith("vn ")){
String[] normals = l.split("[ ]");
parseNormals(l, normals);
numberOfNormalAttributes++;
continue;
}
if(l.startsWith("vt ")){
//String[] texture = l.split("[ ]+");
//nothing for now
continue;
}
if(l.startsWith("f ")){
String[] faces = l.split("[ ]+");
parseFaces(l, faces);
faceIndex++;
if(faceIndex % 2 == 0)
numberOfFaces++;
continue;
}
}
}
private String load(int id){
String data = "";
try {
InputStream is = context.getResources().openRawResource(id);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuffer b = new StringBuffer();
String l = reader.readLine();
while(l != null){
b.append(l);
b.append("
");
l = reader.readLine();
}
data = b.toString();
reader.close();
}catch(Exception ex){
Log.d("model loader load data", "exception "+ex);
}
return data;
}
private void parseVertex(String l, String[] vert){
String[] v = l.split("[ ]");
vertices.add(new vec3(Float.parseFloat(v[1]), Float.parseFloat(v[2]), Float.parseFloat(v[3])));
}
private void parseNormals(String l, String[] normal){
String[] n = l.split("[ ]");
normals.add(new vec3(Float.parseFloat(n[1]), Float.parseFloat(n[2]), Float.parseFloat(n[3])));
}
private void parseFaces(String s, String[] index){
String[] fi = s.split("[ ]");
String[] a = fi[1].split("[/]");
String[] b = fi[2].split("[/]");
String[] c = fi[3].split("[/]");
indices.add(new vec3(Integer.parseInt(a[0]), Integer.parseInt(b[0]), Integer.parseInt(c[0])));
faces.add(new face(Integer.parseInt(a[0]), Integer.parseInt(b[0]), Integer.parseInt(c[0]), Integer.parseInt(a[2])));
numberOfVertices+=3;
numberOfFacesAttributes++;
}
private class vec3{
float x, y, z;
public vec3(float x, float y, float z){
this.x = x;
this.y = y;
this.z = z;
}
@SuppressWarnings("unused")
public String printout(){
return "x "+this.x+" y "+this.y+" z "+this.z;
}
}
private class face{
int[] data;
public face(int v1, int v2, int v3, int n1){
data = new int[6];
data[0] = v1;
data[1] = v2;
data[2] = v3;
data[3] = n1;
}
}
here is how i setup my vbo
vertexArray = new float[numberOfFacesAttributes*9];
normalArray = new float[numberOfFacesAttributes*9];
indexArray = new short[numberOfFacesAttributes*3];
int va = 0;
int ia = 0;
int na = 0;
//System.out.println(numberOfFacesAttributes);
for(int i = 0; i < numberOfFacesAttributes; i++){
vertexArray[va++] = vertices.get((faces.get(i).data[0]-1)).x;
vertexArray[va++] = vertices.get((faces.get(i).data[0]-1)).y;
vertexArray[va++] = vertices.get((faces.get(i).data[0]-1)).z;
vertexArray[va++] = vertices.get((faces.get(i).data[1]-1)).x;
vertexArray[va++] = vertices.get((faces.get(i).data[1]-1)).y;
vertexArray[va++] = vertices.get((faces.get(i).data[1]-1)).z;
vertexArray[va++] = vertices.get((faces.get(i).data[2]-1)).x;
vertexArray[va++] = vertices.get((faces.get(i).data[2]-1)).y;
vertexArray[va++] = vertices.get((faces.get(i).data[2]-1)).z;
normalArray[na++] = normals.get((faces.get(i).data[3]-1)).x;
normalArray[na++] = normals.get((faces.get(i).data[3]-1)).y;
normalArray[na++] = normals.get((faces.get(i).data[3]-1)).z;
normalArray[na++] = normals.get((faces.get(i).data[3]-1)).x;
normalArray[na++] = normals.get((faces.get(i).data[3]-1)).y;
normalArray[na++] = normals.get((faces.get(i).data[3]-1)).z;
normalArray[na++] = normals.get((faces.get(i).data[3]-1)).x;
normalArray[na++] = normals.get((faces.get(i).data[3]-1)).y;
normalArray[na++] = normals.get((faces.get(i).data[3]-1)).z;
indexArray[ia++] = (short) (faces.get(i).data[0]);
indexArray[ia++] = (short) (faces.get(i).data[1]);
indexArray[ia++] = (short) (faces.get(i).data[2]);
}
if I use gl_drawArrays() and use the vertex arrays I get a nice drawing, if i use gl_drawElements i get really terrible rendering.
See videos below, i really appreciate you guys help.
cube rendered with gl_drawarrays() : obj model loader0 - YouTube
same model drawn gl_drawelements() : obj model loader a0 - YouTube
monkey with per fragment lighting gl_drawarrays() : monkey - YouTube
same monkey no lighting gl_drawelements() : obj model loader a1 - YouTube