diff --git a/pom.xml b/pom.xml
index abd2ac8..213bdd9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,6 +13,7 @@
22
UTF-8
3.3.4
+ 1.9.6
@@ -72,6 +73,23 @@
+
+
+
+ org.apache.commons
+ commons-lang3
+ 3.14.0
+
+
+
+
+ org.joml
+ joml
+ ${joml.version}
+
+
+
+
org.lwjgl
lwjgl
diff --git a/src/main/java/org/example/Entity.java b/src/main/java/org/example/Entity.java
index 46653ba..7e8eb78 100644
--- a/src/main/java/org/example/Entity.java
+++ b/src/main/java/org/example/Entity.java
@@ -12,36 +12,13 @@ import java.util.Scanner;
public class Entity
{
- OBJModel model;
+ Mesh mesh;
public ShaderProgram shader;
- private final int vaoId;
- private final int vboId;
-
public Entity(String object_file_path, String fragment_shader_path, String vertex_shader_path)
{
- // Load Object
- try (InputStream in = this.getClass().getResourceAsStream(object_file_path)) {
- // Create an OBJParser and parse the resource
- final IOBJParser parser = new OBJParser();
- this.model = parser.parse(in);
-
- // Use the model representation to get some basic info
- System.out.println(MessageFormat.format(
- "OBJ model has {0} vertices, {1} normals, {2} texture coordinates, and {3} objects.",
- model.getVertices().size(),
- model.getNormals().size(),
- model.getTexCoords().size(),
- model.getObjects().size()));
- } catch (Exception e) {
- System.out.println("ERROR Parsing obj");
- e.printStackTrace();
- System.exit(1);
- }
-
- vaoId = 0;
- vboId = 0;
+ this.mesh = new Mesh(object_file_path);
// Load Shaders
try {
@@ -68,12 +45,4 @@ public class Entity
e.printStackTrace();
}
}
-
- public int getVaoId() {
- return vaoId;
- }
-
- public int getVboId() {
- return vboId;
- }
}
diff --git a/src/main/java/org/example/Game.java b/src/main/java/org/example/Game.java
index 9311836..42d13bf 100644
--- a/src/main/java/org/example/Game.java
+++ b/src/main/java/org/example/Game.java
@@ -1,11 +1,13 @@
package org.example;
+import org.joml.*;
import org.lwjgl.*;
import org.lwjgl.Version;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.*;
import org.lwjgl.system.*;
+import java.lang.Math;
import java.nio.*;
import java.io.*;
import java.text.MessageFormat;
@@ -13,6 +15,9 @@ import java.text.MessageFormat;
import static org.lwjgl.glfw.Callbacks.*;
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.*;
import static org.lwjgl.system.MemoryStack.*;
import static org.lwjgl.system.MemoryUtil.*;
@@ -21,7 +26,11 @@ import org.lwjgl.system.MemoryStack;
public class Game
{
+ public static final float Z_FAR = 1000.0f;
+ public static final float Z_NEAR = 0.1f;
+ public static final float FOV = (float) Math.toRadians(90.0f);
private long window;
+ private Matrix4f projection_matrix;
public void run()
{
@@ -102,6 +111,12 @@ public class Game
// Add stuff to world
world.addEntity(new Entity("/objs/cube.obj", "/shaders/shader.frag", "/shaders/shader.vert"));
+ // Calculate Perspective Matrix
+ int w, h;
+ glfwGetWindowSize(window, w, h);
+ float aspect_ratio = (float) ;
+ this.projection_matrix = new Matrix4f().perspective(FOV, )
+
// Main loop or something
while ( !glfwWindowShouldClose(window) )
{
@@ -109,10 +124,22 @@ public class Game
glfwSwapBuffers(window);
+ for (Entity entity : world.entities)
+ render(entity);
+
glfwPollEvents();
}
}
+ public void render(Entity entity) {
+ entity.shader.bind();
+
+ glBindVertexArray(entity.mesh.vao_id);
+ glEnableVertexAttribArray(0);
+ glEnableVertexAttribArray(1);
+ glDrawElements(GL_TRIANGLES, entity.mesh.vertex_count, GL_UNSIGNED_INT, 0);
+ }
+
public static void main(String[] args)
{
new Game().run();
diff --git a/src/main/java/org/example/Mesh.java b/src/main/java/org/example/Mesh.java
index e68596e..ee8a89e 100644
--- a/src/main/java/org/example/Mesh.java
+++ b/src/main/java/org/example/Mesh.java
@@ -1,24 +1,44 @@
package org.example;
+import org.apache.commons.lang3.ArrayUtils;
+import org.lwjgl.system.MemoryUtil;
+
import java.io.File;
import java.io.FileNotFoundException;
+import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.Scanner;
-public class Mesh {
- private final int vaoId;
- private final int vboId;
+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 Mesh() {
- this.vaoId = 0;
- this.vboId = 0;
+public class Mesh {
+
+ public int vertex_count;
+ public int vao_id;
+ public int vbo_id;
+
+ Float[] vertices;
+ Float[] normals;
+ Integer[] vertice_indices;
+ Integer[] normal_indices;
+
+ // Creates a new Mesh object from an wavefront .obj file
+ public Mesh(String obj_file_path) {
+ 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;
- ArrayList vertices = new ArrayList<>();
- ArrayList normals = new ArrayList<>();
String line;
String[] face_data_temp;
@@ -42,9 +62,73 @@ public class Mesh {
switch (data[0]) {
case "v":
- vertices.add(Float.valueOf(data[1]));
+ 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]));
+
+ 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();
+ }
+
+ private void init() {
+ FloatBuffer vertices_buffer = null;
+
+ try {
+ vertices_buffer = MemoryUtil.memAllocFloat(this.vertices.length);
+ vertex_count = this.vertices.length / 3;
+
+ // Convert from our object list to the primitive float array
+ vertices_buffer.put(ArrayUtils.toPrimitive(this.vertices)).flip();
+
+ this.vao_id = glGenVertexArrays();
+ glBindVertexArray(this.vao_id);
+
+ this.vbo_id = glGenBuffers();
+ glBindBuffer(GL_ARRAY_BUFFER, this.vbo_id);
+ glBufferData(GL_ARRAY_BUFFER, vertices_buffer, GL_STATIC_DRAW);
+ glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ } finally {
+ if (vertices_buffer != null) {
+ MemoryUtil.memFree(vertices_buffer);
+ }
+ }
+ }
+
+ public void cleanUp() {
+ glDisableVertexAttribArray(0);
+
+ // Delete the VBO
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glDeleteBuffers(this.vbo_id);
+
+ // Delete the VAO
+ glBindVertexArray(0);
+ glDeleteVertexArrays(this.vao_id);
}
}
diff --git a/src/main/java/org/example/Window.java b/src/main/java/org/example/Window.java
new file mode 100644
index 0000000..e113259
--- /dev/null
+++ b/src/main/java/org/example/Window.java
@@ -0,0 +1,24 @@
+package org.example;
+
+
+import org.lwjgl.glfw.*;
+import org.lwjgl.system.MemoryUtil;
+
+import java.util.concurrent.Callable;
+
+import static org.lwjgl.glfw.Callbacks.glfwFreeCallbacks;
+import static org.lwjgl.glfw.GLFW.*;
+import static org.lwjgl.opengl.GL11.*;
+import static org.lwjgl.system.MemoryUtil.NULL;
+
+public class Window {
+ public long window_handle;
+
+ public int height;
+ public int width;
+ private Callable resize_func;
+
+ public Window(String title, Callable resize_func) {
+
+ }
+}