Texture implementation
This commit is contained in:
12
assets/shaders/texture.frag.glsl
Normal file
12
assets/shaders/texture.frag.glsl
Normal file
@@ -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);
|
||||
}
|
||||
15
assets/shaders/texture.vert.glsl
Normal file
15
assets/shaders/texture.vert.glsl
Normal file
@@ -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;
|
||||
}
|
||||
BIN
assets/textures/plink.jpg
Normal file
BIN
assets/textures/plink.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
BIN
assets/textures/plink.png
Normal file
BIN
assets/textures/plink.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
|
||||
66
src/main/java/org/hirw/game/Texture.java
Normal file
66
src/main/java/org/hirw/game/Texture.java
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
41
src/main/java/org/hirw/game/TexturedMesh.java
Normal file
41
src/main/java/org/hirw/game/TexturedMesh.java
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user