diff --git a/README.md b/README.md
index 55af60e..53d0ba9 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# Warabi
-This is a game engine, that doesn't make games.... or engines.
+This is a game engine, that doesn't make games.....
......and its written in Java, sorry.
diff --git a/src/main/java/com/okseby/core/ObjectLoader.java b/src/main/java/com/okseby/core/ObjectLoader.java
index f8f3d7d..7eb0db1 100644
--- a/src/main/java/com/okseby/core/ObjectLoader.java
+++ b/src/main/java/com/okseby/core/ObjectLoader.java
@@ -8,6 +8,7 @@ import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
@@ -15,8 +16,9 @@ public class ObjectLoader {
private List vaos = new ArrayList<>();
private List vbos = new ArrayList<>();
- public Model loadModel(float[] vertices) {
+ public Model loadModel(float[] vertices, int[] indices) {
int id = createVAO();
+ storeIndicesBuffer(indices);
storeDataInAttributeList(0, 3, vertices);
unbind();
@@ -31,6 +33,14 @@ public class ObjectLoader {
return id;
}
+ private void storeIndicesBuffer(int[] indices) {
+ int vbo = GL15.glGenBuffers();
+ vbos.add(vbo);
+ GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vbo);
+ IntBuffer buffer = Utils.storeDataInIntBuffer(indices);
+ GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW);
+ }
+
private void storeDataInAttributeList(int attributeNumber, int vertexCount, float[] data) {
int vbo = GL15.glGenBuffers();
vbos.add(vbo);
diff --git a/src/main/java/com/okseby/core/RenderManager.java b/src/main/java/com/okseby/core/RenderManager.java
index 3c267e4..910f6d8 100644
--- a/src/main/java/com/okseby/core/RenderManager.java
+++ b/src/main/java/com/okseby/core/RenderManager.java
@@ -1,20 +1,40 @@
package com.okseby.core;
+import com.okseby.core.entity.Model;
+import com.okseby.core.utils.Utils;
import org.lwjgl.opengl.GL11;
+import org.lwjgl.opengl.GL20;
+import org.lwjgl.opengl.GL30;
public class RenderManager {
private final WindowManager window;
+ private ShaderManager shader;
public RenderManager() {
window = Launcher.getWindow();
}
public void init() throws Exception {
+ shader = new ShaderManager();
+ shader.createVertexShader(Utils.loadResource("/shaders/vertex.vs"));
+ shader.createFragmentShader(Utils.loadResource("/shaders/fragment.fs"));
+
+ shader.link();
}
- public void render() {
+ public void render(Model model) {
+ clear();
+ shader.bind();
+
+ GL30.glBindVertexArray(model.getId());
+ GL20.glEnableVertexAttribArray(0);
+ GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, model.getVertexCount());
+ GL20.glDisableVertexAttribArray(0);
+ GL30.glBindVertexArray(0);
+
+ shader.unbind();
}
public void clear() {
@@ -22,6 +42,6 @@ public class RenderManager {
}
public void cleanup() {
-
+ shader.cleanup();
}
}
diff --git a/src/main/java/com/okseby/core/ShaderManager.java b/src/main/java/com/okseby/core/ShaderManager.java
new file mode 100644
index 0000000..5a4a4cc
--- /dev/null
+++ b/src/main/java/com/okseby/core/ShaderManager.java
@@ -0,0 +1,68 @@
+package com.okseby.core;
+
+import org.lwjgl.opengl.GL20;
+
+public class ShaderManager {
+ private final int programID;
+ private int vertexShaderID, fragmentShaderID;
+
+ public ShaderManager() throws Exception {
+ programID = GL20.glCreateProgram();
+ if (programID == 0)
+ throw new Exception("Could not create shader");
+ }
+
+ public void createVertexShader(String shaderCode) throws Exception {
+ vertexShaderID = createShader(shaderCode, GL20.GL_VERTEX_SHADER);
+ }
+
+ public void createFragmentShader(String shaderCode) throws Exception {
+ fragmentShaderID = createShader(shaderCode, GL20.GL_FRAGMENT_SHADER);
+ }
+
+ public int createShader(String shaderCode, int shaderType) throws Exception {
+ int shaderID = GL20.glCreateShader(shaderType);
+ if (shaderID == 0)
+ throw new Exception("Error creating shader. Type: " + shaderType);
+
+ GL20.glShaderSource(shaderID, shaderCode);
+ GL20.glCompileShader(shaderID);
+
+ if (GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS) == 0)
+ throw new Exception("Error compiling shader code. Type: " + shaderType + " Info: " + GL20.glGetShaderInfoLog(shaderID, 1024));
+
+ GL20.glAttachShader(programID, shaderID);
+
+ return shaderID;
+ }
+
+ public void link() throws Exception {
+ GL20.glLinkProgram(programID);
+ if (GL20.glGetProgrami(programID, GL20.GL_LINK_STATUS) == 0)
+ throw new Exception("Error linking shader code. Info: " + GL20.glGetProgramInfoLog(programID, 1024));
+
+ if (vertexShaderID != 0)
+ GL20.glDetachShader(programID, vertexShaderID);
+
+ if (fragmentShaderID != 0)
+ GL20.glDetachShader(programID, fragmentShaderID);
+
+ GL20.glValidateProgram(programID);
+ if (GL20.glGetProgrami(programID, GL20.GL_VALIDATE_STATUS) == 0)
+ throw new Exception("Unable to validate shader code: " + GL20.glGetProgramInfoLog(programID, 1024));
+ }
+
+ public void bind() {
+ GL20.glUseProgram(programID);
+ }
+
+ public void unbind() {
+ GL20.glUseProgram(0);
+ }
+
+ public void cleanup() {
+ unbind();
+ if (programID != 0)
+ GL20.glDeleteProgram(programID);
+ }
+}
diff --git a/src/main/java/com/okseby/core/test/TestGame.java b/src/main/java/com/okseby/core/test/TestGame.java
index 45d0d61..a01c465 100644
--- a/src/main/java/com/okseby/core/test/TestGame.java
+++ b/src/main/java/com/okseby/core/test/TestGame.java
@@ -34,7 +34,12 @@ public class TestGame implements ILogic {
-0.5f, 0.5f, 0f
};
- model = loader.loadModel(vertices);
+ int[] indices = {
+ 0, 1, 3,
+ 3, 1, 2
+ };
+
+ model = loader.loadModel(vertices, indices);
}
@Override
diff --git a/src/main/java/com/okseby/core/utils/Utils.java b/src/main/java/com/okseby/core/utils/Utils.java
index 98a56fa..ae8b1ea 100644
--- a/src/main/java/com/okseby/core/utils/Utils.java
+++ b/src/main/java/com/okseby/core/utils/Utils.java
@@ -2,7 +2,11 @@ package com.okseby.core.utils;
import org.lwjgl.system.MemoryUtil;
+import java.io.InputStream;
import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.Scanner;
public class Utils {
public static FloatBuffer storeDataInFloatBuffer(float[] data) {
@@ -11,4 +15,20 @@ public class Utils {
return buffer;
}
+
+ public static IntBuffer storeDataInIntBuffer(int[] data) {
+ IntBuffer buffer = MemoryUtil.memAllocInt(data.length);
+ buffer.put(data).flip();
+
+ return buffer;
+ }
+
+ public static String loadResource(String filename) throws Exception {
+ String result;
+ try (InputStream in = Utils.class.getResourceAsStream(filename);
+ Scanner scanner = new Scanner(in, StandardCharsets.UTF_8.name())) {
+ result = scanner.useDelimiter("\\A").next();
+ }
+ return result;
+ }
}
diff --git a/src/main/resources/shaders/fragment.fs b/src/main/resources/shaders/fragment.fs
new file mode 100644
index 0000000..9cd2af0
--- /dev/null
+++ b/src/main/resources/shaders/fragment.fs
@@ -0,0 +1,9 @@
+#version 400 core
+
+in vec3 color;
+
+out vec4 fragmentColor;
+
+void main() {
+ fragmentColor = vec4(color, 1.0);
+}
\ No newline at end of file
diff --git a/src/main/resources/shaders/vertex.vs b/src/main/resources/shaders/vertex.vs
new file mode 100644
index 0000000..748fa9c
--- /dev/null
+++ b/src/main/resources/shaders/vertex.vs
@@ -0,0 +1,10 @@
+#version 400 core
+
+in vec3 position;
+
+out vec3 color;
+
+void main() {
+ gl_Position = vec4(position, 1.0);
+ color = vec3(position.x + 0.25, 0.17, position.y + 0.25);
+}
\ No newline at end of file