QuoteMain.java
public class Main {
public static long WINDOW;
ShaderProgram shader;
Mesh mesh;
public static void main(String[] args) {
new Main().run();
}
private void run() {
init();
loop();
terminate();
}
private void init() {
if(!glfwInit()) throw new RuntimeException("Could not initialize GLFW (ERROR CODE : 0x0001)");
WINDOW = glfwCreateWindow(800, 600, "Skylift FS", NULL, NULL);
glfwSwapInterval(1);
glfwSetFramebufferSizeCallback(WINDOW, (win, width, height) -> {
glViewport(0, 0, width, height);
});
glfwMakeContextCurrent(WINDOW);
createCapabilities();
try {
shader = new ShaderProgram();
shader.setVertexShader("/com/masterpiece/shaders/vertexshader.glsl");
shader.setFragmentShader("/com/masterpiece/shaders/fragmentshader.glsl");
shader.link();
}
catch (Exception e) {
e.printStackTrace();
}
float[] positions = new float[] {
-0.5f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.5f, 0.5f, 0.0f,
};
int[] indices = new int[] {
0, 1, 3, 3, 1, 2,
};
float[] colors = new float[] {
0.5f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f,
0.0f, 0.0f, 0.5f,
0.0f, 0.5f, 0.5f,
};
mesh = new Mesh(positions, indices, colors);
glfwShowWindow(WINDOW);
}
private void loop() {
Renderer renderer = new Renderer(shader);
glClearColor(0.0f, 1.0f, 1.0f, 1.0f);
while(!glfwWindowShouldClose(WINDOW)) {
glClear(GL_COLOR_BUFFER_BIT);
shader.bind();
renderer.render(mesh);
shader.unbind();
glfwSwapBuffers(WINDOW);
glfwPollEvents();
}
}
private void terminate() {
if (shader != null) shader.cleanup();
if (mesh != null) mesh.cleanup();
glfwDestroyWindow(WINDOW);
glfwTerminate();
}
}
QuoteShaderProgram.java
package com.masterpiece.shaders;
import static org.lwjgl.opengl.GL20.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.FloatBuffer;
import java.util.HashMap;
import java.util.Map;
import org.joml.Matrix4f;
import org.lwjgl.system.MemoryStack;
public class ShaderProgram {
int program_id;
int vertex_shader_id;
int fragment_shader_id;
private final Map<String, Integer> uniforms;
public ShaderProgram() throws Exception {
this.uniforms = new HashMap<>();
if((program_id=glCreateProgram())==0) throw new Exception("Failed to create shader program");
}
public void setVertexShader(String path) throws Exception {
vertex_shader_id=createShader(read(path), GL_VERTEX_SHADER);
}
public void setFragmentShader(String path) throws Exception {
fragment_shader_id=createShader(read(path), GL_FRAGMENT_SHADER);
}
public void link() throws Exception {
glLinkProgram(program_id);
if (glGetProgrami(program_id, GL_LINK_STATUS) == 0) {
throw new Exception("Error linking Shader code: " + glGetProgramInfoLog(program_id, 1024));
}
glDetachShader(program_id, vertex_shader_id);
glDetachShader(program_id, fragment_shader_id);
glValidateProgram(program_id);
if (glGetProgrami(program_id, GL_VALIDATE_STATUS) == 0) {
System.err.println("Warning validating Shader code: " + glGetProgramInfoLog(program_id, 1024));
}
}
public void bind() {
glUseProgram(program_id);
}
public void unbind() {
glUseProgram(0);
}
public void cleanup() {
unbind();
glDeleteShader(vertex_shader_id);
glDeleteShader(fragment_shader_id);
glDeleteProgram(program_id);
}
private int createShader(String code, int type) throws Exception {
int id = glCreateShader(type);
glShaderSource(id, code);
glCompileShader(id);
if (glGetShaderi(id, GL_COMPILE_STATUS) == 0)
throw new Exception(type+"- "+ glGetShaderInfoLog(id, 1024));
glAttachShader(program_id, id);
return id;
}
public void createUniform(String uniformName) throws Exception {
int uniformLocation = glGetUniformLocation(program_id, 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()) {
FloatBuffer fb = stack.mallocFloat(16);
value.get(fb);
glUniformMatrix4fv(uniforms.get(uniformName), false, fb);
}
}
private String read(String path) {
String read = "";
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(path)));
String input;
while((input = reader.readLine()) != null) read += input += "\n";
}
catch (IOException e) {
e.printStackTrace();
}
return read;
}
}
QuoteMesh.java
package com.masterpiece.mesh;
import static org.lwjgl.opengl.GL11.GL_FLOAT;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL30.*;
public class Mesh {
int vaoID;
int coordinatesVboID;
int indiciesVboID;
int colorsVboID;
int dataLength;
public Mesh(float[] data, int[] indicies, float[] colors) {
vaoID = glGenVertexArrays();
coordinatesVboID = glGenBuffers();
indiciesVboID = glGenBuffers();
colorsVboID = glGenBuffers();
dataLength = indicies.length;
glBindVertexArray(vaoID);
glBindBuffer(GL_ARRAY_BUFFER, coordinatesVboID);
glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indiciesVboID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicies, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, colorsVboID);
glBufferData(GL_ARRAY_BUFFER, colors, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, false, 0, 0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindVertexArray(0);
}
public int getVaoID() {
return vaoID;
}
public int getVboID() {
return coordinatesVboID;
}
public int getVertexCount() {
return dataLength;
}
public void cleanup() {
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glBindVertexArray(vaoID);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteVertexArrays(vaoID);
glDeleteBuffers(coordinatesVboID);
}
}
QuoteRenderer.java
package com.masterpiece.main;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT;
import static org.lwjgl.opengl.GL11.glDrawElements;
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
import static org.lwjgl.opengl.GL30.glBindVertexArray;
import java.nio.IntBuffer;
import org.joml.Matrix4f;
import org.lwjgl.BufferUtils;
import com.masterpiece.mesh.Mesh;
import com.masterpiece.shaders.ShaderProgram;
public class Renderer {
public static float FOV = (float) Math.toRadians(60.0f);
public static final float Z_NEAR = 0.01f, Z_FAR = 1000.0f;
private Matrix4f projectionMatrix;
private final ShaderProgram shader;
public Renderer(ShaderProgram shader) {
IntBuffer width = BufferUtils.createIntBuffer(1), height = BufferUtils.createIntBuffer(1);
glfwGetWindowSize(Main.WINDOW, width, height);
float aspectRatio = (float) width.get() / height.get();
projectionMatrix = new Matrix4f().perspective(FOV, aspectRatio, Z_NEAR, Z_FAR);
try {
shader.createUniform("projectionMatrix");
}
catch (Exception e) {
e.printStackTrace();
}
this.shader = shader;
}
public void render(Mesh mesh) {
shader.setUniform("projectionMatrix", projectionMatrix);
glBindVertexArray(mesh.getVaoID());
glEnableVertexAttribArray(0); //Positional Data
glEnableVertexAttribArray(1); //Color Data
glDrawElements(GL_TRIANGLES, mesh.getVertexCount(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}
}
Here's my code, it used to work fine and draw a colorful rectangle, but I do not remember what I had changed that broke this program. I'm following the "3D game development to LWJGL". Since I am fairly new to LWJGL I do not know many ways to debug the code, everything works fine I don't face any errors that would cause the code to break :(.
The shader's are fairly simple too, if you would like them I will include it