Teamworkguy2
09-06-2012, 06:40 PM
Using Windows 7 (x64) with Nvidia GTS 450
Open GL 4.2.0 (lwjgl 2.8.4)
Shaders are compiled with #version 130
I'm *trying* to use buffer objects in GL and the result is a black screen (immediate mode works fine).
I've tried checking glGetError()'s output, but did not get any errors.
In the below code, I can render the VBO vertices using immediate mode and it displays just fine using the same vertex, normal, and color data as the VBO.
The vertex and fragment shaders seem to be working(?) since the test triangles render correctly (correct me if immediate mode triangles do not use the same vertex and fragment shaders as VBOs).
Here's some of the relevant code, I made a test project to work on the code that is having the problem.
So hopefully it highlights the problem and does not waste anyone's time.
Here's the main method that creates the Open GL context and loads the shaders (I did not include the actual code for those functions) and runs a loop to render a VBO and a test triangle.
public static void main(String[] args) {
initGL();
GLShader shader = null;
try {
File vertexShaderFile = new File("shaders/shader.vert");
File fragmentShaderFile = new File("shaders/shader.frag");
// The next 3 lines just create the 3 Open GL integers for the program, vert, and frag shaders and store them in an object that has fields for each integer
shader = ShaderLoader.loadShaders(vertexShaderFile, fragmentShaderFile);
int programId = ShaderLoader.createProgram(shader.getVertexShader( ), shader.getFragmentShader())
shader.setProgram(programId);
// Generic Vertex Attributes to use when drawing the VBO
GL20.glBindAttribLocation(shader.getProgram(), 0, "position_in");
GL20.glBindAttribLocation(shader.getProgram(), 1, "normal_in");
GL20.glBindAttribLocation(shader.getProgram(), 2, "color_in");
ShaderLoader.linkAndUseShader(shader.getProgram()) ;
} catch (IOException e) {
System.err.println("Error loading shader files");
e.printStackTrace();
}
ByteBuffer data = GLVBO.getDataTestBuffer();
ByteBuffer element = GLVBO.getIndexTestBuffer();
// Hard coded 32 bytes for Vertexf[x,y,z]Normalf[x,y,z]Colorb[r,g,b,a]Paddingf[0] as well as exactly 3 elements
GLVBO vbo = new GLVBO(data, element, GL15.GL_STATIC_DRAW, GL11.GL_TRIANGLES, 32, 3);
while(!Display.isCloseRequested()) {
gameLoop(vbo, data);
}
destroy();
}
private static void gameLoop(GLVBO vbo, ByteBuffer vertexNormalColor) {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
vbo.render();
GL11.glBegin(GL11.GL_TRIANGLES);
for( ; vertexNormalColor.position() < vertexNormalColor.limit(); ) {
// Sorry, a lot of variables, I decided to displayed the actual vertex data of the VBO to ensure that the data is correct
float vx = vertexNormalColor.getFloat();
float vy = vertexNormalColor.getFloat();
float vz = vertexNormalColor.getFloat();
float nx = vertexNormalColor.getFloat();
float ny = vertexNormalColor.getFloat();
float nz = vertexNormalColor.getFloat();
byte r = vertexNormalColor.get(); // Get's a single byte
byte g = vertexNormalColor.get();
byte b = vertexNormalColor.get();
byte a = vertexNormalColor.get();
int padding = vertexNormalColor.getInt(); // Padding because [stride=32] = [Vertex=3*4 + Normal=3*4 + Color=1*4 + Padding=1*4]
GL11.glColor4f(r, g, b, a);
GL11.glNormal3f(nx, ny, nz);
GL11.glVertex3f(vx+1, vy+1, vz+1); // Shift the test vertices so that I can see when I get the VBO working
}
GL11.glEnd();
vertexNormalColor.flip();
Display.update();
Display.sync(maxFps);
}
Here is the class that creates and renders the VBO (it basically acts like a VAO for my program)
public class GLVBO {
private int dataId, elementId, elementCount, elementSize, drawType;
/** GLVBO, create Open GL Buffer Object
* @param data - the buffer data
* @param element - list of indices to buffer data
* @param usage - the buffer's usage (e.g. GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW,
* GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY)
* @param drawType - such as GL_TRIANGLES, GL_LINES, etc...
* @param elementSize - the number of bytes in each element
* @param elementCount - the number of elements in the data and element buffers
*/
public GLVBO(ByteBuffer data, ByteBuffer element, int usage, int drawType, int elementSize, int elementCount) {
// Create the Vertex BO and Element BO
dataId = createBO(data, GL15.GL_ARRAY_BUFFER, usage);
elementId = createBO(element, GL15.GL_ELEMENT_ARRAY_BUFFER, usage);
this.drawType = drawType;
this.elementSize = elementSize;
this.elementCount = elementCount;
}
public void render() {
// Bind buffers
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, this.dataId);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, this.elementId);
// Bind attribute types
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, this.elementSize, 0); // Vertex (x,y,z)
GL20.glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, this.elementSize, 12); // Normal (x,y,z)
GL20.glVertexAttribPointer(2, 4, GL11.GL_BYTE, false, this.elementSize, 24); // Color (r,g,b,a)
// Enable attribute types
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL20.glEnableVertexAttribArray(2);
// Draw attributes from GL_ARRAY_BUFFER using indices from GL_ELEMENT_ARRAY_BUFFER
GL11.glDrawElements(this.drawType, this.elementCount, GL11.GL_INT, 0);
// Disable attribute types
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL20.glDisableVertexAttribArray(2);
// Unbind buffers
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
public static int createBO(ByteBuffer vertexData, int targetType, int usage) {
int id = GL15.glGenBuffers();
GL15.glBindBuffer(targetType, id); // Bind the new buffer
GL15.glBufferData(targetType, vertexData, usage); // Upload the buffer data
GL15.glBindBuffer(targetType, 0); // Unbind the buffer once data uploading is done
return id;
}
}
Hopefully the code did not scare anyone away.
I am guessing that I'm doing something wrong with generic vertex attributes, but I'm not sure since I don't fully understand how attributes are supposed to work.
Also, I'd be happy to post the vertex and fragment shaders if anyone wants to see them, their very short.
Open GL 4.2.0 (lwjgl 2.8.4)
Shaders are compiled with #version 130
I'm *trying* to use buffer objects in GL and the result is a black screen (immediate mode works fine).
I've tried checking glGetError()'s output, but did not get any errors.
In the below code, I can render the VBO vertices using immediate mode and it displays just fine using the same vertex, normal, and color data as the VBO.
The vertex and fragment shaders seem to be working(?) since the test triangles render correctly (correct me if immediate mode triangles do not use the same vertex and fragment shaders as VBOs).
Here's some of the relevant code, I made a test project to work on the code that is having the problem.
So hopefully it highlights the problem and does not waste anyone's time.
Here's the main method that creates the Open GL context and loads the shaders (I did not include the actual code for those functions) and runs a loop to render a VBO and a test triangle.
public static void main(String[] args) {
initGL();
GLShader shader = null;
try {
File vertexShaderFile = new File("shaders/shader.vert");
File fragmentShaderFile = new File("shaders/shader.frag");
// The next 3 lines just create the 3 Open GL integers for the program, vert, and frag shaders and store them in an object that has fields for each integer
shader = ShaderLoader.loadShaders(vertexShaderFile, fragmentShaderFile);
int programId = ShaderLoader.createProgram(shader.getVertexShader( ), shader.getFragmentShader())
shader.setProgram(programId);
// Generic Vertex Attributes to use when drawing the VBO
GL20.glBindAttribLocation(shader.getProgram(), 0, "position_in");
GL20.glBindAttribLocation(shader.getProgram(), 1, "normal_in");
GL20.glBindAttribLocation(shader.getProgram(), 2, "color_in");
ShaderLoader.linkAndUseShader(shader.getProgram()) ;
} catch (IOException e) {
System.err.println("Error loading shader files");
e.printStackTrace();
}
ByteBuffer data = GLVBO.getDataTestBuffer();
ByteBuffer element = GLVBO.getIndexTestBuffer();
// Hard coded 32 bytes for Vertexf[x,y,z]Normalf[x,y,z]Colorb[r,g,b,a]Paddingf[0] as well as exactly 3 elements
GLVBO vbo = new GLVBO(data, element, GL15.GL_STATIC_DRAW, GL11.GL_TRIANGLES, 32, 3);
while(!Display.isCloseRequested()) {
gameLoop(vbo, data);
}
destroy();
}
private static void gameLoop(GLVBO vbo, ByteBuffer vertexNormalColor) {
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
vbo.render();
GL11.glBegin(GL11.GL_TRIANGLES);
for( ; vertexNormalColor.position() < vertexNormalColor.limit(); ) {
// Sorry, a lot of variables, I decided to displayed the actual vertex data of the VBO to ensure that the data is correct
float vx = vertexNormalColor.getFloat();
float vy = vertexNormalColor.getFloat();
float vz = vertexNormalColor.getFloat();
float nx = vertexNormalColor.getFloat();
float ny = vertexNormalColor.getFloat();
float nz = vertexNormalColor.getFloat();
byte r = vertexNormalColor.get(); // Get's a single byte
byte g = vertexNormalColor.get();
byte b = vertexNormalColor.get();
byte a = vertexNormalColor.get();
int padding = vertexNormalColor.getInt(); // Padding because [stride=32] = [Vertex=3*4 + Normal=3*4 + Color=1*4 + Padding=1*4]
GL11.glColor4f(r, g, b, a);
GL11.glNormal3f(nx, ny, nz);
GL11.glVertex3f(vx+1, vy+1, vz+1); // Shift the test vertices so that I can see when I get the VBO working
}
GL11.glEnd();
vertexNormalColor.flip();
Display.update();
Display.sync(maxFps);
}
Here is the class that creates and renders the VBO (it basically acts like a VAO for my program)
public class GLVBO {
private int dataId, elementId, elementCount, elementSize, drawType;
/** GLVBO, create Open GL Buffer Object
* @param data - the buffer data
* @param element - list of indices to buffer data
* @param usage - the buffer's usage (e.g. GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW,
* GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW, GL_DYNAMIC_READ, or GL_DYNAMIC_COPY)
* @param drawType - such as GL_TRIANGLES, GL_LINES, etc...
* @param elementSize - the number of bytes in each element
* @param elementCount - the number of elements in the data and element buffers
*/
public GLVBO(ByteBuffer data, ByteBuffer element, int usage, int drawType, int elementSize, int elementCount) {
// Create the Vertex BO and Element BO
dataId = createBO(data, GL15.GL_ARRAY_BUFFER, usage);
elementId = createBO(element, GL15.GL_ELEMENT_ARRAY_BUFFER, usage);
this.drawType = drawType;
this.elementSize = elementSize;
this.elementCount = elementCount;
}
public void render() {
// Bind buffers
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, this.dataId);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, this.elementId);
// Bind attribute types
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, this.elementSize, 0); // Vertex (x,y,z)
GL20.glVertexAttribPointer(1, 3, GL11.GL_FLOAT, false, this.elementSize, 12); // Normal (x,y,z)
GL20.glVertexAttribPointer(2, 4, GL11.GL_BYTE, false, this.elementSize, 24); // Color (r,g,b,a)
// Enable attribute types
GL20.glEnableVertexAttribArray(0);
GL20.glEnableVertexAttribArray(1);
GL20.glEnableVertexAttribArray(2);
// Draw attributes from GL_ARRAY_BUFFER using indices from GL_ELEMENT_ARRAY_BUFFER
GL11.glDrawElements(this.drawType, this.elementCount, GL11.GL_INT, 0);
// Disable attribute types
GL20.glDisableVertexAttribArray(0);
GL20.glDisableVertexAttribArray(1);
GL20.glDisableVertexAttribArray(2);
// Unbind buffers
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}
public static int createBO(ByteBuffer vertexData, int targetType, int usage) {
int id = GL15.glGenBuffers();
GL15.glBindBuffer(targetType, id); // Bind the new buffer
GL15.glBufferData(targetType, vertexData, usage); // Upload the buffer data
GL15.glBindBuffer(targetType, 0); // Unbind the buffer once data uploading is done
return id;
}
}
Hopefully the code did not scare anyone away.
I am guessing that I'm doing something wrong with generic vertex attributes, but I'm not sure since I don't fully understand how attributes are supposed to work.
Also, I'd be happy to post the vertex and fragment shaders if anyone wants to see them, their very short.