diff --git a/src/main/java/org/xfe/engine/files/Obj.java b/src/main/java/org/xfe/engine/files/Obj.java index a5d065f..4ffffbc 100644 --- a/src/main/java/org/xfe/engine/files/Obj.java +++ b/src/main/java/org/xfe/engine/files/Obj.java @@ -10,9 +10,8 @@ import java.util.Scanner; public class Obj { int vertex_count; - float[] vertices; - float[] normals; - int[] vertex_indices; + float[] vbo; + int[] indices; String file_path; @@ -24,14 +23,13 @@ public class Obj { void loadObj(File file) { - ArrayList temp_vertices = new ArrayList<>(); - ArrayList temp_normals = new ArrayList<>(); - ArrayList temp_vertex_indices = new ArrayList<>(); - ArrayList temp_real_normals = new ArrayList<>(); + ArrayList v = new ArrayList<>(); + ArrayList vn = new ArrayList<>(); + ArrayList i = new ArrayList<>(); + ArrayList temp_vbo = new ArrayList<>(); String line; String[] face_data_temp; - int i; Scanner scanner; @@ -50,50 +48,89 @@ public class Obj { switch (data[0]) { case "v": - temp_vertices.add(Float.valueOf(data[1])); - temp_vertices.add(Float.valueOf(data[2])); - temp_vertices.add(Float.valueOf(data[3])); + v.add(Float.valueOf(data[1])); + v.add(Float.valueOf(data[2])); + v.add(Float.valueOf(data[3])); break; case "vn": - temp_normals.add(Float.valueOf(data[1])); - temp_normals.add(Float.valueOf(data[2])); - temp_normals.add(Float.valueOf(data[3])); + vn.add(Float.valueOf(data[1])); + vn.add(Float.valueOf(data[2])); + vn.add(Float.valueOf(data[3])); break; case "f": // Sample face data : "f 5//1 3//1 1//1" where each thing is v//normal_v - for (i = 1; i < 4; i++) { - face_data_temp = data[i].split("//"); - temp_vertex_indices.add(Integer.parseInt(face_data_temp[0]) - 1); + for (int index = 1; index < 4; index++) { - if (face_data_temp.length > 1) + // "//" means "vertex index//normal index" + if (line.contains("//")) { + face_data_temp = data[index].split("//"); + + int vertex_index = (Integer.parseInt(face_data_temp[0]) - 1) * 3; int normal_index = (Integer.parseInt(face_data_temp[1]) - 1) * 3; - for (int c = 0; c < 3; c++) - temp_real_normals.add(temp_normals.get(normal_index + c)); + boolean vbo_el_found = false; + + // We must look for the vertex//normal pair in the existing VBO buffer + for (int a = 0; a < temp_vbo.size(); a += 6) + { + boolean vertex_found = true; + boolean normal_found = true; + + // look for vertex + for (int b = 0; b < 3; b++) + if (temp_vbo.get(a + b) != v.get(vertex_index + b)) { + vertex_found = false; + break; + } + + // look for normal + for (int b = 3; b < 6; b++) + if (temp_vbo.get(a + b) != vn.get(normal_index + b - 3)) { + normal_found = false; + break; + } + + if (vertex_found && normal_found) + { + i.add(a / 6); + vbo_el_found = true; + } + } + + // If we didn't find a match vertex//normal pair it must be added to the VBO + if (!vbo_el_found) + { + // Add vertex + for (int a = 0; a < 3; a++) + temp_vbo.add(v.get(vertex_index + a)); + + // Add normal + for (int a = 0; a < 3; a++) + temp_vbo.add(vn.get(normal_index + a)); + + // Add new index to indices + i.add((temp_vbo.size() / 6) - 1); + } } + } break; } } - this.vertices = ArrayUtils.toPrimitive(temp_vertices.toArray(Float[]::new)); - this.normals = ArrayUtils.toPrimitive(temp_real_normals.toArray(Float[]::new)); - this.vertex_indices = ArrayUtils.toPrimitive(temp_vertex_indices.toArray(Integer[]::new)); - this.vertex_count = this.vertices.length / 3; + this.indices = ArrayUtils.toPrimitive(i.toArray(Integer[]::new)); + this.vbo = ArrayUtils.toPrimitive(temp_vbo.toArray(Float[]::new)); + this.vertex_count = this.vbo.length / 6; } - public float[] getVertices() { - return vertices; - } - - public float[] getNormals() { - return normals; + public float[] getVbo() { + return vbo; } public int[] getIndices() { - return vertex_indices; + return indices; } public int getVertexCount() { diff --git a/src/main/java/org/xfe/engine/world/Mesh.java b/src/main/java/org/xfe/engine/world/Mesh.java index 56f1427..b11f104 100644 --- a/src/main/java/org/xfe/engine/world/Mesh.java +++ b/src/main/java/org/xfe/engine/world/Mesh.java @@ -1,6 +1,5 @@ package org.xfe.engine.world; -import org.apache.commons.lang3.ArrayUtils; import org.lwjgl.opengl.GL30; import org.lwjgl.system.MemoryStack; import org.xfe.engine.files.Obj; @@ -22,15 +21,14 @@ public class Mesh { public int vao_id; public List vbo_id_list; - public float[] vertices; - public float[] normals; - public int[] vertex_indices; + public float[] vbo_buffer; + public int[] indices; - public Mesh(float[] v, int[] i) { + public Mesh(float[] vbo_buffer, int[] i) { this.vbo_id_list = new ArrayList<>(); - this.vertices = v; - this.vertex_indices = i; + this.vbo_buffer = vbo_buffer; + this.indices = i; this.init(); } @@ -40,13 +38,11 @@ public class Mesh { this.vbo_id_list = new ArrayList<>(); Obj obj = new Obj(obj_file_path); - this.vertices = obj.getVertices(); - this.normals = obj.getNormals(); - this.vertex_indices = obj.getIndices(); + this.vbo_buffer = obj.getVbo(); + this.indices = obj.getIndices(); this.vertex_count = obj.getVertexCount(); - System.out.println(Arrays.toString(this.vertices)); - System.out.println(Arrays.toString(this.normals)); + this.init(); } @@ -58,11 +54,10 @@ public class Mesh { MemoryStack stack = MemoryStack.stackPush(); // Bind our vertices into the VBO - vertices_buffer = stack.callocFloat(this.vertices.length); - vertex_count = this.vertices.length / 3; + vertices_buffer = stack.callocFloat(this.vbo_buffer.length); // Convert from our object list to the primitive float array - vertices_buffer.put(0, this.vertices); + vertices_buffer.put(0, this.vbo_buffer); this.vao_id = glGenVertexArrays(); glBindVertexArray(this.vao_id); @@ -73,26 +68,28 @@ public class Mesh { glBufferData(GL_ARRAY_BUFFER, vertices_buffer, GL_STATIC_DRAW); glEnableVertexAttribArray(0); glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0); + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, 3, GL_FLOAT, false, 0, 0); - if (normals.length > 0) { - vbo_id = glGenBuffers(); - vbo_id_list.add(vbo_id); - - FloatBuffer normals_buffer = stack.callocFloat(normals.length); - normals_buffer.put(0, this.normals); - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBufferData(GL_ARRAY_BUFFER, normals_buffer, vbo_id); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_FLOAT, false, 0, 0); - } +// if (normals.length > 0) { +// vbo_id = glGenBuffers(); +// vbo_id_list.add(vbo_id); +// +// FloatBuffer normals_buffer = stack.callocFloat(normals.length); +// normals_buffer.put(0, this.normals); +// glBindBuffer(GL_ARRAY_BUFFER, vbo_id); +// glBufferData(GL_ARRAY_BUFFER, normals_buffer, vbo_id); +// glEnableVertexAttribArray(1); +// glVertexAttribPointer(1, 3, GL_FLOAT, false, 0, 0); +// } // Bind indices in EBO - if (this.vertex_indices.length > 0) { + if (this.indices.length > 0) { vbo_id = glGenBuffers(); vbo_id_list.add(vbo_id); - IntBuffer indice_buffer = stack.callocInt(vertex_indices.length); - indice_buffer.put(0, this.vertex_indices); + IntBuffer indice_buffer = stack.callocInt(indices.length); + indice_buffer.put(0, this.indices); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_id); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indice_buffer, GL_STATIC_DRAW); @@ -111,7 +108,7 @@ public class Mesh { glBindVertexArray(this.vao_id); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); - glDrawElements(GL_TRIANGLES, this.vertex_indices.length, GL_UNSIGNED_INT, 0); + glDrawElements(GL_TRIANGLES, this.indices.length, GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1);