From c28ec45f8c21107324446373be0e1308dee1321c Mon Sep 17 00:00:00 2001 From: Ross W Date: Tue, 19 Aug 2025 19:56:37 +0100 Subject: [PATCH] Added Shader class, default shaders --- assets/shaders/default.frag.glsl | 8 ++ assets/shaders/default.vert.glsl | 11 +++ src/main/java/org/hirw/game/Shader.java | 115 ++++++++++++++++++++++++ src/main/java/org/hirw/game/Window.java | 2 + 4 files changed, 136 insertions(+) create mode 100644 assets/shaders/default.frag.glsl create mode 100644 assets/shaders/default.vert.glsl create mode 100644 src/main/java/org/hirw/game/Shader.java diff --git a/assets/shaders/default.frag.glsl b/assets/shaders/default.frag.glsl new file mode 100644 index 0000000..b69a2fb --- /dev/null +++ b/assets/shaders/default.frag.glsl @@ -0,0 +1,8 @@ +#version 330 core + +in vec4 fColour; +out vec4 colour; + +void main() { + colour = fColour; +} diff --git a/assets/shaders/default.vert.glsl b/assets/shaders/default.vert.glsl new file mode 100644 index 0000000..a0b5cc4 --- /dev/null +++ b/assets/shaders/default.vert.glsl @@ -0,0 +1,11 @@ +#version 330 core + +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec4 aColour; + +out vec4 fColour; + +void main() { + fColour = aColour; + gl_Position = vec4(aPos, 1.0); +} diff --git a/src/main/java/org/hirw/game/Shader.java b/src/main/java/org/hirw/game/Shader.java new file mode 100644 index 0000000..4229ccc --- /dev/null +++ b/src/main/java/org/hirw/game/Shader.java @@ -0,0 +1,115 @@ +package org.hirw.game; + +import static org.lwjgl.opengl.GL20.*; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.InvalidPathException; +import java.nio.file.NoSuchFileException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.EnumMap; +import java.util.Map; +import lombok.Getter; +import lombok.Setter; +import org.hirw.game.util.Log; + +public class Shader { + private enum ShaderType { + FRAG, + VERT + } + + private static final EnumMap SHADERS = + new EnumMap<>( + Map.of( + ShaderType.FRAG, GL_FRAGMENT_SHADER, + ShaderType.VERT, GL_VERTEX_SHADER)); + + private static final String DEFAULT_FRAG_PATH = "assets/shaders/default.frag.glsl"; + private static final String DEFAULT_VERT_PATH = "assets/shaders/default.vert.glsl"; + + @Getter private String vertexSource; + @Getter private String fragmentSource; + @Getter @Setter private int vertexID; + @Getter @Setter private int fragmentID; + @Getter @Setter private int shaderProgramID; + + public Shader(String fragPath, String vertPath) { + this.fragmentSource = readFromFile(fragPath); + this.vertexSource = readFromFile(vertPath); + } + + public Shader() { + this(DEFAULT_FRAG_PATH, DEFAULT_VERT_PATH); + } + + public void init() { + compileShader(ShaderType.FRAG); + compileShader(ShaderType.VERT); + createProgram(); + } + + private void compileShader(ShaderType shaderType) { + int shaderID = glCreateShader(SHADERS.get(shaderType)); + + switch (shaderType) { + case ShaderType.FRAG -> { + setFragmentID(shaderID); + glShaderSource(shaderID, getFragmentSource()); + } + case ShaderType.VERT -> { + setVertexID(shaderID); + glShaderSource(shaderID, getVertexSource()); + } + } + + glCompileShader(shaderID); + + if (glGetShaderi(shaderID, GL_COMPILE_STATUS) == GL_FALSE) { + int len = glGetShaderi(shaderID, GL_INFO_LOG_LENGTH); + Log.error( + "Shader initialisation", + String.format( + "Failed to compile %s shader: %s", + shaderType.toString(), glGetShaderInfoLog(shaderID, len))); + } + } + + private void createProgram() { + setShaderProgramID(glCreateProgram()); + glAttachShader(shaderProgramID, getVertexID()); + glAttachShader(shaderProgramID, getFragmentID()); + glLinkProgram(shaderProgramID); + + int success = glGetProgrami(getShaderProgramID(), GL_LINK_STATUS); + if (success == GL_FALSE) { + int len = glGetProgrami(getShaderProgramID(), GL_INFO_LOG_LENGTH); + + Log.error( + "Shader initialisation", + String.format( + "Failed to create Shader Program: %s", + glGetShaderInfoLog(getShaderProgramID(), len))); + } + } + + private String readFromFile(String stringFilePath) { + String source = ""; + + try { + Path filePath = Paths.get(stringFilePath); + source = Files.readString(filePath); + + } catch (NoSuchFileException | InvalidPathException e) { + Log.error( + "Shader initialisation", "Couldn't open file (probably a bad path): " + stringFilePath); + } catch (IOException e) { + Log.error( + "Shader initialisation", + "An IO Exception occured while reading from file: " + stringFilePath); + } + + return source; + } +} diff --git a/src/main/java/org/hirw/game/Window.java b/src/main/java/org/hirw/game/Window.java index 4dd4068..3dd52ff 100644 --- a/src/main/java/org/hirw/game/Window.java +++ b/src/main/java/org/hirw/game/Window.java @@ -80,6 +80,8 @@ public class Window { GL.createCapabilities(); glClearColor(0.0f, 0.0f, 2.0f, 0.0f); + Shader someShader = new Shader(); + someShader.init(); } private void loop() {