Add texture loading.

This commit is contained in:
Sebastian Cabrera 2023-05-31 13:47:13 -04:00
parent 34b9ac0d05
commit c5972b9dd2
10 changed files with 122 additions and 11 deletions

View file

@ -6,7 +6,10 @@ import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.stb.STBImage;
import org.lwjgl.system.MemoryStack;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
@ -15,14 +18,45 @@ import java.util.List;
public class ObjectLoader {
private List<Integer> vaos = new ArrayList<>();
private List<Integer> vbos = new ArrayList<>();
private List<Integer> textures = new ArrayList<>();
public Model loadModel(float[] vertices, int[] indices) {
public Model loadModel(float[] vertices, float[] textureCoordinates, int[] indices) {
int id = createVAO();
storeIndicesBuffer(indices);
storeDataInAttributeList(0, 3, vertices);
storeDataInAttributeList(1, 2, textureCoordinates);
unbind();
return new Model(id, vertices.length / 3);
return new Model(id, indices.length);
}
public int loadTexture(String filename) throws Exception {
int width, height;
ByteBuffer buffer;
try (MemoryStack stack = MemoryStack.stackPush()) {
IntBuffer w = stack.mallocInt(1);
IntBuffer h = stack.mallocInt(1);
IntBuffer c = stack.mallocInt(1);
buffer = STBImage.stbi_load(filename, w, h, c, 4);
if (buffer == null)
throw new Exception("Image File " + filename + " not loaded " + STBImage.stbi_failure_reason());
width = w.get();
height = h.get();
}
int id = GL11.glGenTextures();
textures.add(id);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, id);
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, buffer);
GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
STBImage.stbi_image_free(buffer);
return id;
}
private int createVAO() {
@ -67,5 +101,7 @@ public class ObjectLoader {
GL30.glDeleteVertexArrays(vao);
for (int vbo : vbos)
GL30.glDeleteBuffers(vbo);
for (int texture : textures)
GL11.glDeleteTextures(texture);
}
}

View file

@ -3,6 +3,7 @@ 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.GL13;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
@ -21,18 +22,25 @@ public class RenderManager {
shader.createFragmentShader(Utils.loadResource("/shaders/fragment.fs"));
shader.link();
shader.createUniform("textureSampler");
}
public void render(Model model) {
clear();
shader.bind();
shader.setUniform("textureSampler", 0);
GL30.glBindVertexArray(model.getId());
GL20.glEnableVertexAttribArray(0);
GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, model.getVertexCount());
GL20.glEnableVertexAttribArray(1);
GL13.glActiveTexture(GL13.GL_TEXTURE0);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, model.getTexture().getId());
GL11.glDrawElements(GL11.GL_TRIANGLES, model.getVertexCount(), GL11.GL_UNSIGNED_INT, 0);
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL30.glBindVertexArray(0);
shader.unbind();

View file

@ -1,15 +1,42 @@
package com.okseby.core;
import org.joml.Matrix4f;
import org.lwjgl.opengl.GL20;
import org.lwjgl.system.MemoryStack;
import java.util.HashMap;
import java.util.Map;
public class ShaderManager {
private final int programID;
private int vertexShaderID, fragmentShaderID;
private final Map<String, Integer> uniforms;
public ShaderManager() throws Exception {
programID = GL20.glCreateProgram();
if (programID == 0)
throw new Exception("Could not create shader");
uniforms = new HashMap<>();
}
public void createUniform(String uniformName) throws Exception {
int uniformLocation = GL20.glGetUniformLocation(programID, uniformName);
if (uniformLocation < 0)
throw new Exception("Could not find uniform " + uniformName);
uniforms.put(uniformName, uniformLocation);
}
public void setUniform(String uniformName, Matrix4f value) {
try (MemoryStack stack = MemoryStack.stackPush()) {
GL20.glUniformMatrix4fv(uniforms.get(uniformName), false, value.get(stack.mallocFloat(16)));
}
}
public void setUniform(String uniformName, int value) {
GL20.glUniform1i(uniforms.get(uniformName), value);
}
public void createVertexShader(String shaderCode) throws Exception {

View file

@ -17,9 +17,10 @@ public class WindowManager {
@Getter private long window;
@Getter private int width, height;
@Getter private final Matrix4f projectionMatrix;
@Getter @Setter private String title;
@Getter @Setter private boolean resizeable, vsync;
@Getter private final Matrix4f projectionMatrix;
public WindowManager(String title, int width, int height, boolean vsync) {
this.title = title;

View file

@ -1,13 +1,28 @@
package com.okseby.core.entity;
import lombok.Getter;
import lombok.Setter;
public class Model {
@Getter private int id;
@Getter private int vertexCount;
@Getter @Setter private Texture texture;
public Model(int id, int vertexCount) {
this.id = id;
this.vertexCount = vertexCount;
}
public Model(int id, int vertexCount, Texture texture) {
this.id = id;
this.vertexCount = vertexCount;
this.texture = texture;
}
public Model(Model model, Texture texture) {
this.id = model.getId();
this.vertexCount = model.getVertexCount();
this.texture = texture;
}
}

View file

@ -0,0 +1,14 @@
package com.okseby.core.entity;
import lombok.Getter;
public class Texture {
@Getter private final int id;
public Texture(int id) {
this.id = id;
}
}

View file

@ -2,6 +2,7 @@ package com.okseby.core.test;
import com.okseby.core.*;
import com.okseby.core.entity.Model;
import com.okseby.core.entity.Texture;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL11;
@ -29,9 +30,7 @@ public class TestGame implements ILogic {
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f,
-0.5f, 0.5f, 0f
};
int[] indices = {
@ -39,7 +38,15 @@ public class TestGame implements ILogic {
3, 1, 2
};
model = loader.loadModel(vertices, indices);
float[] textureCoordinates = {
0, 0,
0, 1,
1, 1,
1, 0
};
model = loader.loadModel(vertices, textureCoordinates, indices);
model.setTexture(new Texture(loader.loadTexture("textures/grassblock.png")));
}
@Override

View file

@ -1,9 +1,11 @@
#version 400 core
in vec3 color;
in vec2 fragmentTextureCoordinates;
out vec4 fragmentColor;
uniform sampler2D textureSampler;
void main() {
fragmentColor = vec4(color, 1.0);
fragmentColor = texture(textureSampler, fragmentTextureCoordinates);
}

View file

@ -1,10 +1,11 @@
#version 400 core
in vec3 position;
in vec2 textureCoordinates;
out vec3 color;
out vec2 fragmentTextureCoordinates;
void main() {
gl_Position = vec4(position, 1.0);
color = vec3(position.x + 0.25, 0.17, position.y + 0.25);
fragmentTextureCoordinates = textureCoordinates;
}

BIN
textures/grassblock.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB