From dcd1307a717d43541fd5f19b68d41b54742c5fd0 Mon Sep 17 00:00:00 2001 From: okseby Date: Sat, 27 May 2023 00:35:01 -0400 Subject: [PATCH] Attempt adding GLSL shaders for basic color. Not working atm. --- README.md | 2 +- .../java/com/okseby/core/ObjectLoader.java | 12 +++- .../java/com/okseby/core/RenderManager.java | 24 ++++++- .../java/com/okseby/core/ShaderManager.java | 68 +++++++++++++++++++ .../java/com/okseby/core/test/TestGame.java | 7 +- .../java/com/okseby/core/utils/Utils.java | 20 ++++++ src/main/resources/shaders/fragment.fs | 9 +++ src/main/resources/shaders/vertex.vs | 10 +++ 8 files changed, 147 insertions(+), 5 deletions(-) create mode 100644 src/main/java/com/okseby/core/ShaderManager.java create mode 100644 src/main/resources/shaders/fragment.fs create mode 100644 src/main/resources/shaders/vertex.vs 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