diff --git a/hs_err_pid18718.log b/hs_err_pid18718.log index 35a2c63..9555c52 100644 --- a/hs_err_pid18718.log +++ b/hs_err_pid18718.log @@ -36,8 +36,8 @@ j org.lwjgl.system.jemalloc.JEmalloc.nje_free(J)V+6 j org.lwjgl.system.jemalloc.JEmallocAllocator.free(J)V+1 j org.lwjgl.system.MemoryUtil.nmemFree(J)V+4 j org.lwjgl.system.MemoryUtil.memFree(Ljava/nio/Buffer;)V+14 -j org.xfe.engine.Mesh.init()V+170 -j org.xfe.engine.Mesh.([Ljava/lang/Float;[Ljava/lang/Integer;)V+15 +j org.xfe.engine.world.Mesh.init()V+170 +j org.xfe.engine.world.Mesh.([Ljava/lang/Float;[Ljava/lang/Integer;)V+15 j org.xfe.game.Main.init(Lorg/xfe/engine/Window;Lorg/xfe/engine/World;Lorg/xfe/engine/Render;)V+177 j org.xfe.engine.Engine.(Ljava/lang/String;Lorg/xfe/engine/Window$WindowOptions;Lorg/xfe/engine/GameLogic;)V+79 j org.xfe.game.Main.main([Ljava/lang/String;)V+22 diff --git a/hs_err_pid19012.log b/hs_err_pid19012.log index 14383fa..bf24ef0 100644 --- a/hs_err_pid19012.log +++ b/hs_err_pid19012.log @@ -36,8 +36,8 @@ j org.lwjgl.system.jemalloc.JEmalloc.nje_free(J)V+6 j org.lwjgl.system.jemalloc.JEmallocAllocator.free(J)V+1 j org.lwjgl.system.MemoryUtil.nmemFree(J)V+4 j org.lwjgl.system.MemoryUtil.memFree(Ljava/nio/Buffer;)V+14 -j org.xfe.engine.Mesh.init()V+170 -j org.xfe.engine.Mesh.([Ljava/lang/Float;[Ljava/lang/Integer;)V+15 +j org.xfe.engine.world.Mesh.init()V+170 +j org.xfe.engine.world.Mesh.([Ljava/lang/Float;[Ljava/lang/Integer;)V+15 j org.xfe.game.Main.init(Lorg/xfe/engine/Window;Lorg/xfe/engine/World;Lorg/xfe/engine/Render;)V+177 j org.xfe.engine.Engine.(Ljava/lang/String;Lorg/xfe/engine/Window$WindowOptions;Lorg/xfe/engine/GameLogic;)V+79 j org.xfe.game.Main.main([Ljava/lang/String;)V+22 diff --git a/hs_err_pid19126.log b/hs_err_pid19126.log index 6a02958..f5655e5 100644 --- a/hs_err_pid19126.log +++ b/hs_err_pid19126.log @@ -36,8 +36,8 @@ j org.lwjgl.system.jemalloc.JEmalloc.nje_free(J)V+6 j org.lwjgl.system.jemalloc.JEmallocAllocator.free(J)V+1 j org.lwjgl.system.MemoryUtil.nmemFree(J)V+4 j org.lwjgl.system.MemoryUtil.memFree(Ljava/nio/Buffer;)V+14 -j org.xfe.engine.Mesh.init()V+170 -j org.xfe.engine.Mesh.([Ljava/lang/Float;[Ljava/lang/Integer;)V+15 +j org.xfe.engine.world.Mesh.init()V+170 +j org.xfe.engine.world.Mesh.([Ljava/lang/Float;[Ljava/lang/Integer;)V+15 j org.xfe.game.Main.init(Lorg/xfe/engine/Window;Lorg/xfe/engine/World;Lorg/xfe/engine/Render;)V+177 j org.xfe.engine.Engine.(Ljava/lang/String;Lorg/xfe/engine/Window$WindowOptions;Lorg/xfe/engine/GameLogic;)V+79 j org.xfe.game.Main.main([Ljava/lang/String;)V+22 diff --git a/src/main/java/org/xfe/engine/Engine.java b/src/main/java/org/xfe/engine/Engine.java index 5d8fdfc..ca546d1 100644 --- a/src/main/java/org/xfe/engine/Engine.java +++ b/src/main/java/org/xfe/engine/Engine.java @@ -1,6 +1,6 @@ package org.xfe.engine; -import org.joml.*; +import org.xfe.engine.world.World; import java.lang.Math; diff --git a/src/main/java/org/xfe/engine/GameLogic.java b/src/main/java/org/xfe/engine/GameLogic.java index 7172da7..0c3a4ae 100644 --- a/src/main/java/org/xfe/engine/GameLogic.java +++ b/src/main/java/org/xfe/engine/GameLogic.java @@ -1,5 +1,7 @@ package org.xfe.engine; +import org.xfe.engine.world.World; + public interface GameLogic { void cleanup(); diff --git a/src/main/java/org/xfe/engine/Mesh.java b/src/main/java/org/xfe/engine/Mesh.java deleted file mode 100644 index f794286..0000000 --- a/src/main/java/org/xfe/engine/Mesh.java +++ /dev/null @@ -1,183 +0,0 @@ -package org.xfe.engine; - -import org.apache.commons.lang3.ArrayUtils; -import org.lwjgl.opengl.GL30; -import org.lwjgl.system.MemoryStack; -import org.lwjgl.system.MemoryUtil; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Scanner; - -import static org.lwjgl.opengl.GL11.*; -import static org.lwjgl.opengl.GL15.*; -import static org.lwjgl.opengl.GL20.*; -import static org.lwjgl.opengl.GL30.*; - -public class Mesh { - - public int vertex_count; - public int vao_id; - public List vbo_id_list; - - public Float[] vertices; - public Float[] normals; - public Integer[] vertice_indices; - public Integer[] normal_indices; - - public Mesh(Float[] v, Integer[] i) { - this.vertices = v; - this.vertice_indices = i; - init(); - } - - // Creates a new Mesh object from an wavefront .obj file - public Mesh(String obj_file_path) { - this.vbo_id_list = new ArrayList<>(); - this.loadObj(obj_file_path); - } - - public void loadObj(String file_path) { - - ArrayList temp_vertices = new ArrayList<>(); - ArrayList temp_normals = new ArrayList<>(); - ArrayList temp_vertice_indices = new ArrayList<>(); - ArrayList temp_normal_indices = new ArrayList<>(); - - Scanner scanner; - File obj; - - String line; - String[] face_data_temp; - int[] face_data = new int[3]; - int i; - - // Try to open the file - try { - obj = new File(file_path); - scanner = new Scanner(obj); - } catch (Exception e) { - System.out.println("ERROR: OBJ File \"" + file_path + "\" not found."); - e.printStackTrace(); - return; - } - - while (scanner.hasNextLine()) { - line = scanner.nextLine(); - - String[] data = line.split(" "); - - 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])); - break; - case "vn": - temp_normals.add(Float.valueOf(data[1])); - temp_normals.add(Float.valueOf(data[2])); - temp_normals.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_vertice_indices.add(Integer.parseInt(face_data_temp[0]) - 1); - - if (face_data_temp.length > 1) - temp_normal_indices.add(Integer.parseInt(face_data_temp[1])); - } - break; - } - } - - this.vertices = temp_vertices.toArray(Float[]::new); - this.normals = temp_normals.toArray(Float[]::new); - this.vertice_indices = temp_vertice_indices.toArray(Integer[]::new); - this.normal_indices = temp_normal_indices.toArray(Integer[]::new); - - // OBJ File has been read, setup openGL buffers - init(); - - System.out.println(Arrays.toString(this.vertices)); - System.out.println(Arrays.toString(this.vertice_indices)); - } - - private void init() { - FloatBuffer vertices_buffer = null; - - try { - MemoryStack stack = MemoryStack.stackPush(); - - // Bind our vertices into the VBO - vertices_buffer = stack.callocFloat(this.vertices.length); - vertex_count = this.vertices.length / 3; - - // Convert from our object list to the primitive float array - vertices_buffer.put(0, ArrayUtils.toPrimitive(this.vertices)); - - this.vao_id = glGenVertexArrays(); - glBindVertexArray(this.vao_id); - - int vbo_id = glGenBuffers(); - vbo_id_list.add(vbo_id); - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glBufferData(GL_ARRAY_BUFFER, vertices_buffer, GL_STATIC_DRAW); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0); - - // Bind indices in EBO - if (this.vertice_indices.length > 0) { - vbo_id = glGenBuffers(); - vbo_id_list.add(vbo_id); - - IntBuffer indice_buffer = stack.callocInt(vertice_indices.length); - indice_buffer.put(0, ArrayUtils.toPrimitive(vertice_indices)); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_id); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indice_buffer, GL_STATIC_DRAW); - } - - if (normals.length > 0) { - vbo_id = glGenBuffers(); - vbo_id_list.add(vbo_id); - - FloatBuffer normals_buffer = stack.callocFloat(normals.length); - normals_buffer.put(0, ArrayUtils.toPrimitive(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); - } - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); - } finally { -// if (vertices_buffer != null) { -// MemoryUtil.memFree(vertices_buffer); -// } - } - } - - public void render() { - glBindVertexArray(this.vao_id); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glDrawElements(GL_TRIANGLES, this.vertice_indices.length, GL_UNSIGNED_INT, 0); - - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - glBindVertexArray(0); - } - public void cleanUp() { - vbo_id_list.forEach(GL30::glDeleteBuffers); - glDeleteVertexArrays(this.vao_id); - } -} diff --git a/src/main/java/org/xfe/engine/Render.java b/src/main/java/org/xfe/engine/Render.java index 4ebf939..87d205d 100644 --- a/src/main/java/org/xfe/engine/Render.java +++ b/src/main/java/org/xfe/engine/Render.java @@ -3,14 +3,10 @@ package org.xfe.engine; import org.joml.Matrix4f; import org.joml.Vector3f; import org.lwjgl.opengl.GL; +import org.xfe.engine.world.Entity; +import org.xfe.engine.world.World; -import java.util.Arrays; - -import static org.lwjgl.glfw.GLFW.*; import static org.lwjgl.opengl.GL11.*; -import static org.lwjgl.opengl.GL15.*; -import static org.lwjgl.opengl.GL20.*; -import static org.lwjgl.opengl.GL30.*; public class Render { diff --git a/src/main/java/org/xfe/engine/files/Obj.java b/src/main/java/org/xfe/engine/files/Obj.java new file mode 100644 index 0000000..a5d065f --- /dev/null +++ b/src/main/java/org/xfe/engine/files/Obj.java @@ -0,0 +1,102 @@ +package org.xfe.engine.files; + +import org.apache.commons.lang3.ArrayUtils; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Scanner; + +public class Obj { + int vertex_count; + + float[] vertices; + float[] normals; + int[] vertex_indices; + + String file_path; + + public Obj(String file_path) { + this.file_path = file_path; + this.loadObj(new File(file_path)); + } + + + 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<>(); + + String line; + String[] face_data_temp; + int i; + + Scanner scanner; + + try { + scanner = new Scanner(file); + } catch (FileNotFoundException e) { + System.out.println("ERROR: OBJ File \"" + file_path + "\" not found."); + e.printStackTrace(); + return; + } + + while (scanner.hasNextLine()) { + line = scanner.nextLine(); + + String[] data = line.split(" "); + + 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])); + break; + case "vn": + temp_normals.add(Float.valueOf(data[1])); + temp_normals.add(Float.valueOf(data[2])); + temp_normals.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); + + if (face_data_temp.length > 1) + { + 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)); + } + } + 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; + } + + public float[] getVertices() { + return vertices; + } + + public float[] getNormals() { + return normals; + } + + public int[] getIndices() { + return vertex_indices; + } + + public int getVertexCount() { + return vertex_count; + } +} diff --git a/src/main/java/org/xfe/engine/Entity.java b/src/main/java/org/xfe/engine/world/Entity.java similarity index 96% rename from src/main/java/org/xfe/engine/Entity.java rename to src/main/java/org/xfe/engine/world/Entity.java index cd2ce82..8c945e0 100644 --- a/src/main/java/org/xfe/engine/Entity.java +++ b/src/main/java/org/xfe/engine/world/Entity.java @@ -1,9 +1,9 @@ -package org.xfe.engine; +package org.xfe.engine.world; import org.joml.Matrix4f; +import org.xfe.engine.ShaderProgram; import java.io.File; -import java.util.Scanner; import static org.lwjgl.opengl.GL20.GL_FRAGMENT_SHADER; import static org.lwjgl.opengl.GL20.GL_VERTEX_SHADER; diff --git a/src/main/java/org/xfe/engine/Light.java b/src/main/java/org/xfe/engine/world/Light.java similarity index 90% rename from src/main/java/org/xfe/engine/Light.java rename to src/main/java/org/xfe/engine/world/Light.java index 20c5655..72c206e 100644 --- a/src/main/java/org/xfe/engine/Light.java +++ b/src/main/java/org/xfe/engine/world/Light.java @@ -1,4 +1,4 @@ -package org.xfe.engine; +package org.xfe.engine.world; import org.joml.Vector3f; diff --git a/src/main/java/org/xfe/engine/world/Mesh.java b/src/main/java/org/xfe/engine/world/Mesh.java new file mode 100644 index 0000000..56f1427 --- /dev/null +++ b/src/main/java/org/xfe/engine/world/Mesh.java @@ -0,0 +1,124 @@ +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; + +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.opengl.GL15.*; +import static org.lwjgl.opengl.GL20.*; +import static org.lwjgl.opengl.GL30.*; + +public class Mesh { + + public int vertex_count; + public int vao_id; + public List vbo_id_list; + + public float[] vertices; + public float[] normals; + public int[] vertex_indices; + + public Mesh(float[] v, int[] i) { + this.vbo_id_list = new ArrayList<>(); + + this.vertices = v; + this.vertex_indices = i; + + this.init(); + } + + // Creates a new Mesh object from an wavefront .obj file + public Mesh(String obj_file_path) { + 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.vertex_count = obj.getVertexCount(); + + System.out.println(Arrays.toString(this.vertices)); + System.out.println(Arrays.toString(this.normals)); + + this.init(); + } + + private void init() { + FloatBuffer vertices_buffer = null; + + try { + MemoryStack stack = MemoryStack.stackPush(); + + // Bind our vertices into the VBO + vertices_buffer = stack.callocFloat(this.vertices.length); + vertex_count = this.vertices.length / 3; + + // Convert from our object list to the primitive float array + vertices_buffer.put(0, this.vertices); + + this.vao_id = glGenVertexArrays(); + glBindVertexArray(this.vao_id); + + int vbo_id = glGenBuffers(); + vbo_id_list.add(vbo_id); + glBindBuffer(GL_ARRAY_BUFFER, vbo_id); + glBufferData(GL_ARRAY_BUFFER, vertices_buffer, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 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) { + vbo_id = glGenBuffers(); + vbo_id_list.add(vbo_id); + + IntBuffer indice_buffer = stack.callocInt(vertex_indices.length); + indice_buffer.put(0, this.vertex_indices); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_id); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indice_buffer, GL_STATIC_DRAW); + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + } finally { +// if (vertices_buffer != null) { +// MemoryUtil.memFree(vertices_buffer); +// } + } + } + + public void render() { + glBindVertexArray(this.vao_id); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glDrawElements(GL_TRIANGLES, this.vertex_indices.length, GL_UNSIGNED_INT, 0); + + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glBindVertexArray(0); + } + public void cleanUp() { + vbo_id_list.forEach(GL30::glDeleteBuffers); + glDeleteVertexArrays(this.vao_id); + } +} diff --git a/src/main/java/org/xfe/engine/World.java b/src/main/java/org/xfe/engine/world/World.java similarity index 89% rename from src/main/java/org/xfe/engine/World.java rename to src/main/java/org/xfe/engine/world/World.java index 3c7a345..aabd540 100644 --- a/src/main/java/org/xfe/engine/World.java +++ b/src/main/java/org/xfe/engine/world/World.java @@ -1,6 +1,4 @@ -package org.xfe.engine; - -import org.joml.Vector3f; +package org.xfe.engine.world; import java.util.ArrayList; diff --git a/src/main/java/org/xfe/game/Main.java b/src/main/java/org/xfe/game/Main.java index 7ce504a..030db93 100644 --- a/src/main/java/org/xfe/game/Main.java +++ b/src/main/java/org/xfe/game/Main.java @@ -2,6 +2,8 @@ package org.xfe.game; import org.joml.Matrix4f; import org.xfe.engine.*; +import org.xfe.engine.world.Entity; +import org.xfe.engine.world.World; public class Main implements GameLogic { @@ -36,7 +38,7 @@ public class Main implements GameLogic { public void update(Window window, World world, long diffTimeMillis) { world.entities.get(0).model = new Matrix4f() .identity() - .translate(0, 0, -10) + .translate(0, 0, -5) .rotate(ang, 0,1, 0); ang += 1.0f/100.0f; }