I have looked at a lot of posts, and cannot find what is wrong with my code. I have bound my VBO however it doesn't work and gives me this error:
Exception in thread "main" org.lwjgl.opengl.OpenGLException: Cannot use
offsets when Array Buffer Object is disabled
at org.lwjgl.opengl.GLChecks.ensureArrayVBOenabled(GLChecks.java:77)
at org.lwjgl.opengl.GL20.glVertexAttribPointer(GL20.java:892)
at glsl.Main.main(Main.java:117)
I don't understand what is wrong here. I have looked everywhere and can't work out what is wrong with this. I have tried it with and without glEnable(GL_ARRAY_BUFFER_BINDING);
package glsl;
import java.nio.FloatBuffer;
import java.util.Scanner;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.*;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
public class Main
{
private static int initShaderProgram()
{
int shaderProgram = glCreateProgram();
int vertexShader = getShader(GL_VERTEX_SHADER, "/shader.vert");
glAttachShader(shaderProgram, vertexShader);
int fragmentShader = getShader(GL_FRAGMENT_SHADER, "/shader.frag");
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
checkError(shaderProgram, GL_LINK_STATUS, true);
glValidateProgram(shaderProgram);
checkError(shaderProgram, GL_VALIDATE_STATUS, true);
return shaderProgram;
}
private static int getShader(int shaderType, String shaderName)
{
int shader = glCreateShader(shaderType);
String shaderText = "";
Scanner scan = new Scanner(Main.class.getResourceAsStream(shaderName));
while(scan.hasNextLine())
shaderText = shaderText.concat(scan.nextLine().concat("\n"));
scan.close();
System.out.println("\n");
System.out.println(shaderName+" source: --------------------------------------------");
System.out.println("\n"+shaderText);
System.out.println("\n");
glShaderSource(shader, shaderText);
glCompileShader(shader);
checkError(shader, GL_COMPILE_STATUS, false);
return shader;
}
private static void checkError(int shader, int status, boolean isProgram)
{
if(!isProgram)
{
if(glGetShaderi(shader, status) == org.lwjgl.opengl.GL11.GL_FALSE)
{
System.err.println("Shader broken: " + glGetShaderInfoLog(shader, GL_INFO_LOG_LENGTH));
System.exit(1);
}
}else
{
if(glGetProgrami(shader, status) == org.lwjgl.opengl.GL11.GL_FALSE)
{
System.err.println("Shader broken: " + glGetProgramInfoLog(shader, GL_INFO_LOG_LENGTH));
System.exit(1);
}
}
}
public static void main(String[] args)
{
try
{
Display.setDisplayMode(new DisplayMode(800, 600));
Display.create();
}catch(org.lwjgl.LWJGLException e)
{
System.exit(1);
}
glEnable(GL_ARRAY_BUFFER_BINDING);
int shaderProgram = initShaderProgram();
String attribute_name = "coord2d";
int attribute_coord2d = glGetAttribLocation(shaderProgram, attribute_name);
int vboTriangle;
float[] triangleVerticesArray =
{
-1, -1,
0, 1f,
1, -1
};
FloatBuffer triangleVertices = (FloatBuffer) BufferUtils.createFloatBuffer(triangleVerticesArray.length).put(triangleVerticesArray).flip();
vboTriangle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboTriangle);
glBufferData(GL_ARRAY_BUFFER, triangleVertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
while(!Display.isCloseRequested())
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glEnableVertexAttribArray(attribute_coord2d);
glBindBuffer(GL_VERTEX_ARRAY, vboTriangle);
glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, false, 0, 0l);
glBindBuffer(GL_VERTEX_ARRAY, 0);
glDisableVertexAttribArray(attribute_coord2d);
glUseProgram(0);
Display.update();
Display.sync(60);
}
cleanup(shaderProgram, new int[]{vboTriangle});
}
private static void cleanup(int shaderProgram, int[] vbos)
{
for(int i = 0; i < vbos.length; i++)
glDeleteBuffers(vbos[i]);
glDeleteProgram(shaderProgram);
Display.destroy();
}
}
You need to set up the pointers with a VAO, a Vertex Array Object.
int vaoID = glGenVertexArrays();
Then you need to bind it, and set up the pointers with the VBOs, Vertex Array Objects.
glBindVertexArray(vaoID);
glEnableVertexAttribArray(indexLocation);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glVertexAttribPointer(indexLocation, 2, GL_FLOAT, false, 0, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
Then everytime you render, bind the VAO, and issue a draw command.
glBindVertexArray(vaoID);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
Then finally, you need to dispose the VAO object.
glBindVertexArray(0);
glDeleteVertexArrays(vaoID);
Hope this helps.