When I run the following basic LWJGL program, all I get is a red screen due to glClearColor(1, 0, 0, 1). Nothing renders in the screen except the red background. I'm using Ubuntu as my operating system.
How do I fix this? Here is the complete source code.
Main.java:
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.ContextAttribs;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.PixelFormat;
public class Main {
public static void main(String[] args) {
createDisplay(1280, 720);
//Initializations...
float[] vertex = {
-1.5f, 1.5f, 0f, //V0
-1.5f, -1.5f, 0f, //V1
1.5f, -1.5f, 0f, //V2
1.5f, 1.5f, 0f //V3
};
int[] index = {
0, 1, 3,
3, 1, 2
};
Render render = new Render(vertex, index);
Shader shader = new Shader("vertexShader", "fragmentShader"); //initialize shader
shader.bindAttribute(0, "positions");
shader.link();
GL11.glClearColor(1, 0, 0, 1);
while(!Display.isCloseRequested()) {
Display.sync(60);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
render.draw(shader);
Display.update();
}
render.cleanUp();
shader.cleanUp();
Display.destroy();
}
private static void createDisplay(int Width, int Height) {
ContextAttribs attribs = new ContextAttribs(3, 2);
attribs.withForwardCompatible(true).withProfileCore(true);
try {
Display.setDisplayMode(new DisplayMode(Width, Height));
Display.create(new PixelFormat(), attribs);
} catch (LWJGLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.err.println("Cannot Create Display");
}
GL11.glViewport(0, 0, Width, Height);
}
}
Render.java:
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
public class Render {
int vaoID;
int vertexCount;
List<Integer> vbos = new ArrayList<Integer>();
public Render(float[] vertex, int[] indices) {
vaoID = createVAO();
addIndices(indices);
addVertex(vertex);
unbindVAO();
vertexCount = indices.length;
}
public void draw() {
GL30.glBindVertexArray(vaoID);
GL20.glEnableVertexAttribArray(0);
GL11.glDrawElements(GL11.GL_TRIANGLES, vertexCount, GL11.GL_UNSIGNED_INT, 0);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
}
public void draw(Shader shader) {
shader.bind();
GL30.glBindVertexArray(vaoID);
GL20.glEnableVertexAttribArray(0);
GL11.glDrawElements(GL11.GL_TRIANGLES, vertexCount, GL11.GL_UNSIGNED_INT, 0);
GL20.glDisableVertexAttribArray(0);
GL30.glBindVertexArray(0);
shader.unbind();
}
public void cleanUp() {
for(int vbo: vbos) {
GL15.glDeleteBuffers(vbo);
}
GL30.glDeleteVertexArrays(vaoID);
}
public int getvaoID() {
return vaoID;
}
private int createVAO() {
int id = GL30.glGenVertexArrays();
GL30.glBindVertexArray(id);
return id;
}
private void addVertex(float[] vertex) {
addToAttribList(0, vertex);
}
private void addToAttribList(int slot, float[] buffer) {
int vboID = GL15.glGenBuffers();
vbos.add(vboID);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID);
FloatBuffer float_buffer = toFloatBuffer(buffer);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, float_buffer, GL15.GL_STATIC_DRAW);
GL30.glVertexAttribIPointer(slot, 3, GL11.GL_FLOAT, 0, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
private void addIndices(int[] indices) {
int vboID = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboID);
IntBuffer int_buffer = toIntBuffer(indices);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, int_buffer, GL15.GL_STATIC_DRAW);
}
private FloatBuffer toFloatBuffer(float[] buffer) {
FloatBuffer floatBuffer = BufferUtils.createFloatBuffer(buffer.length);
floatBuffer.put(buffer);
floatBuffer.flip();
return floatBuffer;
}
private IntBuffer toIntBuffer(int[] buffer) {
IntBuffer intBuffer = BufferUtils.createIntBuffer(buffer.length);
intBuffer.put(buffer);
intBuffer.flip();
return intBuffer;
}
private void unbindVAO() {
GL30.glBindVertexArray(0);
}
}
Shader.java:
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.lwjgl.opengl.GL20;
public class Shader {
private final int programID;
private int vertexID;
private int fragmentID;
public Shader(String keyVertex, String keyFragment) {
programID = createProgram();
vertexID = createVertexShader(keyVertex);
fragmentID = createFragmentShader(keyFragment);
}
public int createProgram() {
int id = createProgramShader();
if(id==0) {
System.err.println("Cannot create shader");
}
return id;
}
public int createVertexShader(String key) {
int id = createShader("shaders/" + key + ".vs", GL20.GL_VERTEX_SHADER);
if(id == 0) {
System.err.println("Error creating Vertex Shader");
}
return id;
}
public int createFragmentShader(String key) {
int id = createShader("shaders/" + key + ".fs", GL20.GL_FRAGMENT_SHADER);
if(id == 0) {
System.err.println("Error creating Fragment Shader");
}
return id;
}
public void link() {
GL20.glLinkProgram(programID);
GL20.glValidateProgram(programID);
}
public void bind() {
GL20.glUseProgram(programID);
}
public void unbind() {
GL20.glUseProgram(0);
}
public void cleanUp() {
GL20.glDetachShader(programID, vertexID);
GL20.glDetachShader(programID, fragmentID);
GL20.glDeleteShader(vertexID);
GL20.glDeleteShader(fragmentID);
GL20.glDeleteProgram(programID);
}
public void bindAttribute(int attribute, String variableName) {
GL20.glBindAttribLocation(programID, attribute, variableName);
}
private int createProgramShader() {
return GL20.glCreateProgram();
}
private int createShader(String key, int type) {
StringBuilder shaderSource = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(key));
} catch (FileNotFoundException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}
String line;
try {
while((line = reader.readLine())!=null) {
shaderSource.append(line).append("\n");
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int id = GL20.glCreateShader(type);
GL20.glShaderSource(id, shaderSource);
GL20.glCompileShader(id);
if(GL20.glGetShaderi(id, GL20.GL_COMPILE_STATUS) == 0) {
System.err.println(key + ": Shader compilation error: " + GL20.glGetShaderInfoLog(id, 1080));
}
GL20.glAttachShader(id, programID);
return id;
}
}
And here are the shaders..
vertexShader.vs:
#version 400 core
in vec3 positions;
out vec3 pass_pos;
void main(void) {
gl_Position = vec4(positions, 1.0);
pass_pos = vec3(positions.x, 1.0, positions.z+0.05);
}
fragmentShader.fs:
#version 400 core
in vec3 pass_pos;
out vec4 out_Color;
void main(void) {
out_Color = vec4(pass_pos, 1.0);
}