From bb24efb8567561053f4ec7bc31e9a9ba6058ab16 Mon Sep 17 00:00:00 2001 From: Ross W Date: Sat, 1 Nov 2025 08:45:36 +0000 Subject: [PATCH] Texture implementation --- assets/shaders/texture.frag.glsl | 12 ++++ assets/shaders/texture.vert.glsl | 15 ++++ assets/textures/plink.jpg | Bin 0 -> 5214 bytes assets/textures/plink.png | Bin 0 -> 49804 bytes src/main/java/org/hirw/game/Mesh.java | 32 ++++++--- src/main/java/org/hirw/game/Shader.java | 4 ++ src/main/java/org/hirw/game/SplashScene.java | 33 +++++++-- src/main/java/org/hirw/game/Texture.java | 66 ++++++++++++++++++ src/main/java/org/hirw/game/TexturedMesh.java | 41 +++++++++++ src/main/java/org/hirw/game/Window.java | 6 +- 10 files changed, 191 insertions(+), 18 deletions(-) create mode 100644 assets/shaders/texture.frag.glsl create mode 100644 assets/shaders/texture.vert.glsl create mode 100644 assets/textures/plink.jpg create mode 100644 assets/textures/plink.png create mode 100644 src/main/java/org/hirw/game/Texture.java create mode 100644 src/main/java/org/hirw/game/TexturedMesh.java diff --git a/assets/shaders/texture.frag.glsl b/assets/shaders/texture.frag.glsl new file mode 100644 index 0000000..74e5d39 --- /dev/null +++ b/assets/shaders/texture.frag.glsl @@ -0,0 +1,12 @@ +#version 330 core +out vec4 FragColour; + +in vec4 ourColour; +in vec2 TexCoord; + +uniform sampler2D ourTexture; + +void main() +{ + FragColour = texture(ourTexture, TexCoord); +} diff --git a/assets/shaders/texture.vert.glsl b/assets/shaders/texture.vert.glsl new file mode 100644 index 0000000..d5749a3 --- /dev/null +++ b/assets/shaders/texture.vert.glsl @@ -0,0 +1,15 @@ +#version 330 core + +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec4 aColour; +layout (location = 2) in vec2 aTexCoord; + +out vec4 ourColour; +out vec2 TexCoord; + +void main() +{ + gl_Position = vec4(aPos, 1.0); + ourColour = aColour; + TexCoord = aTexCoord; +} diff --git a/assets/textures/plink.jpg b/assets/textures/plink.jpg new file mode 100644 index 0000000000000000000000000000000000000000..184ea8c450441190f66a27a6fa286077735fbc89 GIT binary patch literal 5214 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 N002ovPDHLkV1j^d_TB&h literal 0 HcmV?d00001 diff --git a/src/main/java/org/hirw/game/Mesh.java b/src/main/java/org/hirw/game/Mesh.java index 0cb361a..d5e429c 100644 --- a/src/main/java/org/hirw/game/Mesh.java +++ b/src/main/java/org/hirw/game/Mesh.java @@ -16,14 +16,18 @@ public class Mesh { @Getter float[] vertices; @Getter int[] elements; - private static final float[] defaultVertexArray = { + protected final int POSITION_SIZE = 3; + protected final int RGBA_SIZE = 4; + protected final int FLOAT_SIZE_IN_BYTES = Float.SIZE / Byte.SIZE; + + protected static final float[] DEFAULT_VERTEX_ARRAY = { 0.5f, -0.5f, 0.0f, /* */ 1.0f, 0.0f, 0.0f, 1.0f, -0.5f, 0.5f, 0.0f, /* */ 0.0f, 1.0f, 0.0f, 1.0f, 0.5f, 0.5f, 0.0f, /* */ 0.0f, 0.0f, 1.0f, 1.0f, -0.5f, -0.5f, 0.0f, /* */ 1.0f, 1.0f, 0.0f, 1.0f, }; - private static final int[] defaultElementArray = { + protected static final int[] DEFAULT_ELEMENT_ARRAY = { 2, 1, 0, 0, 1, 3 }; @@ -38,7 +42,7 @@ public class Mesh { } public Mesh(Shader shader) { - this(shader, defaultVertexArray, defaultElementArray); + this(shader, DEFAULT_VERTEX_ARRAY, DEFAULT_ELEMENT_ARRAY); } public void init() { @@ -61,7 +65,7 @@ public class Mesh { getEboID(), getVboID(), getEboID(), getShader().getShaderProgramID()); } - private void glDraw() { + protected void glDraw() { glBindVertexArray(this.vaoID); glDrawElements(GL_TRIANGLES, getElements().length, GL_UNSIGNED_INT, 0); glBindVertexArray(0); @@ -74,16 +78,24 @@ public class Mesh { initialiseVertexBufferObject(); initialiseElementBufferObject(); - int positionsSize = 3; - int colourSize = 4; - int floatSizeBytes = 4; - int vertexSizeBytes = (positionsSize + colourSize) * floatSizeBytes; - glVertexAttribPointer(0, positionsSize, GL_FLOAT, false, vertexSizeBytes, 0); + initialiseAttribPointers(); + } + + protected int initialiseAttribPointers() { + int vertexSizeInBytes = calculateVertexSizeInBytes(); + + glVertexAttribPointer(0, POSITION_SIZE, GL_FLOAT, false, vertexSizeInBytes, 0); glEnableVertexAttribArray(0); glVertexAttribPointer( - 1, colourSize, GL_FLOAT, false, vertexSizeBytes, positionsSize * floatSizeBytes); + 1, RGBA_SIZE, GL_FLOAT, false, vertexSizeInBytes, POSITION_SIZE * FLOAT_SIZE_IN_BYTES); glEnableVertexAttribArray(1); + + return vertexSizeInBytes; + } + + protected int calculateVertexSizeInBytes() { + return (POSITION_SIZE + RGBA_SIZE) * FLOAT_SIZE_IN_BYTES; } private void initialiseVertexBufferObject() { diff --git a/src/main/java/org/hirw/game/Shader.java b/src/main/java/org/hirw/game/Shader.java index 6f1bca6..90603a5 100644 --- a/src/main/java/org/hirw/game/Shader.java +++ b/src/main/java/org/hirw/game/Shader.java @@ -40,6 +40,10 @@ public class Shader { this.vertexSource = readFromFile(vertPath); } + public Shader(String path) { + this(path + ".frag.glsl", path + ".vert.glsl"); + } + public Shader() { this(DEFAULT_FRAG_PATH, DEFAULT_VERT_PATH); } diff --git a/src/main/java/org/hirw/game/SplashScene.java b/src/main/java/org/hirw/game/SplashScene.java index e8d52b2..b583e02 100644 --- a/src/main/java/org/hirw/game/SplashScene.java +++ b/src/main/java/org/hirw/game/SplashScene.java @@ -8,6 +8,7 @@ public class SplashScene extends Scene { @Getter @Setter private Mesh screenCover; @Getter @Setter private FaderShader screenCoverFaderShader; + @Getter @Setter private Mesh logo; public SplashScene() { super(SceneType.SPLASH); @@ -15,9 +16,11 @@ public class SplashScene extends Scene { public void init() { createScreenCover(); + createLogo(); } public void update() { + getLogo().draw(); getScreenCoverFaderShader().update(); getScreenCover().draw(); } @@ -31,15 +34,33 @@ public class SplashScene extends Scene { setScreenCover(screenCover); } + private void createLogo() { + Shader texturedShader = new Shader("assets/shaders/texture"); + texturedShader.init(); + Texture logoTexture = new Texture(225, 225, "assets/textures/plink.jpg", 3); + logoTexture.init(); + Mesh logoMesh = + new TexturedMesh(texturedShader, logoTexture, logoRectVertices, screenCoverRectElements); + logoMesh.init(); + setLogo(logoMesh); + } + private static final float[] screenCoverRectVertices = { - 1.0f, -1.0f, 0.0f, /* */ 0.0f, 0.0f, 0.0f, 1.0f, - -1.0f, 1.0f, 0.0f, /* */ 0.0f, 0.0f, 0.0f, 0.0f, - 1.0f, 1.0f, 0.0f, /* */ 0.0f, 0.0f, 0.0f, 0.0f, - -1.0f, -1.0f, 0.0f, /* */ 0.0f, 0.0f, 0.0f, 0.0f, + 1.0f, 1.0f, 0.0f, /* */ 0.0f, 0.0f, 0.0f, 0.0f, // 0 Top Right + 1.0f, -1.0f, 0.0f, /* */ 0.0f, 0.0f, 0.0f, 0.0f, // 1 Bottom Right + -1.0f, -1.0f, 0.0f, /* */ 0.0f, 0.0f, 0.0f, 0.0f, // 2 Bottom Left + -1.0f, 1.0f, 0.0f, /* */ 0.0f, 0.0f, 0.0f, 0.0f, // 3 Top Left }; private static final int[] screenCoverRectElements = { - 2, 1, 0, - 0, 1, 3 + 0, 1, 3, + 1, 2, 3 + }; + + private static final float[] logoRectVertices = { + 0.1f, 0.1f, 0.0f, /* */ 0.0f, 0.0f, 0.0f, 0.0f, /* */ 1.0f, 1.0f, // 0 Top Right + 0.1f, -0.1f, 0.0f, /* */ 0.0f, 0.0f, 0.0f, 0.0f, /* */ 1.0f, 0.0f, // 1 Bottom Right + -0.1f, -0.1f, 0.0f, /* */ 0.0f, 0.0f, 0.0f, 0.0f, /* */ 0.0f, 0.0f, // 2 Bottom Left + -0.1f, 0.1f, 0.0f, /* */ 0.0f, 0.0f, 0.0f, 0.0f, /* */ 0.0f, 1.0f, // 3 Top Left }; } diff --git a/src/main/java/org/hirw/game/Texture.java b/src/main/java/org/hirw/game/Texture.java new file mode 100644 index 0000000..05e8158 --- /dev/null +++ b/src/main/java/org/hirw/game/Texture.java @@ -0,0 +1,66 @@ +package org.hirw.game; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.opengl.GL12.*; +import static org.lwjgl.stb.STBImage.stbi_image_free; +import static org.lwjgl.stb.STBImage.stbi_load; +import static org.lwjgl.stb.STBImage.stbi_set_flip_vertically_on_load; + +import java.nio.ByteBuffer; +import lombok.Getter; +import lombok.Setter; + +public class Texture { + @Getter private int width; + @Getter private int height; + @Getter private int channelCount; + @Getter private String texturePath; + @Getter @Setter private int textureID; + + public Texture(int width, int height, String texturePath, int channelCount) { + this.width = width; + this.height = height; + this.texturePath = texturePath; + this.channelCount = channelCount; + } + + public void init() { + ByteBuffer imageBytes = loadImageBytes(); + createTexture(imageBytes); + stbi_image_free(imageBytes); + } + + private ByteBuffer loadImageBytes() { + stbi_set_flip_vertically_on_load(true); + return stbi_load( + getTexturePath(), new int[getWidth()], new int[getHeight()], new int[getChannelCount()], 0); + } + + private void createTexture(ByteBuffer imageBytes) { + setTextureID(glGenTextures()); + glBindTexture(GL_TEXTURE_2D, getTextureID()); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + + setupFilterParameters(); + setupWrapParameters(); + + glTexImage2D( + GL_TEXTURE_2D, 0, GL_RGB, getWidth(), getHeight(), 0, GL_RGB, GL_UNSIGNED_BYTE, imageBytes); + // glGenerateMipmap(GL_TEXTURE_2D); + } + + private void setupFilterParameters() { + // https://github.com/mattdesl/lwjgl-basics/wiki/textures#texture-parameters + // Set the minification and Magnifiation filters: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + + private void setupWrapParameters() { + // https://github.com/mattdesl/lwjgl-basics/wiki/textures#texture-parameters + // Each Vertex has many attributes, including Position (x, y) and Texture Coordinates (s, t). + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } +} diff --git a/src/main/java/org/hirw/game/TexturedMesh.java b/src/main/java/org/hirw/game/TexturedMesh.java new file mode 100644 index 0000000..4a7ea5c --- /dev/null +++ b/src/main/java/org/hirw/game/TexturedMesh.java @@ -0,0 +1,41 @@ +package org.hirw.game; + +import static org.lwjgl.opengl.GL11.*; +import static org.lwjgl.opengl.GL20.*; + +import lombok.Getter; + +public class TexturedMesh extends Mesh { + @Getter private Texture texture; + + private final int TEXTURE_COORDS_SIZE = 2; + + public TexturedMesh(Shader shader, Texture texture, float[] vertexArray, int[] elementArray) { + super(shader, vertexArray, elementArray); + this.texture = texture; + } + + public TexturedMesh(Shader shader, Texture texture) { + this(shader, texture, DEFAULT_VERTEX_ARRAY, DEFAULT_ELEMENT_ARRAY); + } + + protected int initialiseAttribPointers() { + int vertexSizeInBytes = super.initialiseAttribPointers(); + + int offset = (POSITION_SIZE + RGBA_SIZE) * FLOAT_SIZE_IN_BYTES; + glVertexAttribPointer(2, TEXTURE_COORDS_SIZE, GL_FLOAT, false, vertexSizeInBytes, offset); + glEnableVertexAttribArray(2); + + return vertexSizeInBytes; + } + + protected int calculateVertexSizeInBytes() { + return (POSITION_SIZE + RGBA_SIZE + TEXTURE_COORDS_SIZE) * FLOAT_SIZE_IN_BYTES; + } + + protected void glDraw() { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, getTexture().getTextureID()); + super.glDraw(); + } +} diff --git a/src/main/java/org/hirw/game/Window.java b/src/main/java/org/hirw/game/Window.java index f49d40e..1324819 100644 --- a/src/main/java/org/hirw/game/Window.java +++ b/src/main/java/org/hirw/game/Window.java @@ -14,7 +14,7 @@ import org.lwjgl.opengl.*; public class Window { private int width, height; - private final String title; + @Getter private String title; @Getter private long glfwWindow; private static Window window = null; @@ -61,7 +61,7 @@ public class Window { glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); - glfwWindow = glfwCreateWindow(this.width, this.height, "Hello World!", NULL, NULL); + glfwWindow = glfwCreateWindow(this.width, this.height, getTitle(), NULL, NULL); if (glfwWindow == NULL) throw new RuntimeException("Failed to create the GLFW window"); glfwSetCursorPosCallback(glfwWindow, Mouse::cursorPositionCallback); @@ -76,6 +76,8 @@ public class Window { GL.createCapabilities(); glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glClearColor(1.0f, 1.0f, 1.0f, 0.0f);