I’m making a system to dynamically render text using lwjgl. I have a system set up to automatically generate a texture to use in rendering, and the image does work. Here’s where the problem is.
I have this code to initialize 2 VBOs and a VAO, both are set up to be able to handle 1024 text characters worth of data.
vbo = GL15.glGenBuffers(); //Main VBO to hold data
vao = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
GL15.glBufferData(vbo, dataBuffer, GL15.GL_DYNAMIC_DRAW);
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 36, 0); //Position
GL20.glVertexAttribPointer(1, 4, GL11.GL_FLOAT, false, 36, 12); //Color
GL20.glVertexAttribPointer(3, 2, GL11.GL_FLOAT, false, 36, 28); //Texture Coordinates
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
indvbo = GL15.glGenBuffers(); //VBO to hold indices
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indvbo);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_DYNAMIC_DRAW);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
And I try to update the data in vbo using this code
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
dataBuffer.clear();
for(Vertex vert : vertices) { //Vertex is a custom class to hold vertex data.
dataBuffer.put(new float[] { //Put position, color, and texture coordinates in buffer
vert.x,
vert.y,
vert.z,
vert.r,
vert.g,
vert.b,
vert.a,
vert.u,
vert.v
});
}
dataBuffer.flip();
GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, dataBuffer);
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indvbo);
indices.clear();
indices.put(indArray.getIndices());
indices.flip();
GL15.glBufferSubData(GL15.GL_ELEMENT_ARRAY_BUFFER, 0, indices);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
But it nothing appears on the screen. If I use glGetBufferSubData to retrieve the data from either vbo, I get a buffer filled with zeros. However, if I change
GL15.glBufferSubData(GL15.GL_ARRAY_BUFFER, 0, dataBuffer);
to be
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, dataBuffer, GL15.GL_DYNAMIC_DRAW);
and I change
GL15.glBufferSubData(GL15.GL_ELEMENT_ARRAY_BUFFER, 0, indices);
to be
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indices, GL15.GL_DYNAMIC_DRAW);
Everything will appear on the screen and glGetBufferSubData will return what I had originally put in. I don’t want to use glBufferData because I’m doing this each frame and I don’t want to re allocate memory each frame. What am I doing that causes glBufferSubData to not work?
First, you don’t pass the buffer object as the first parameter; you pass the target you bound the buffer object to. You bound it to
GL15.GL_ARRAY_BUFFER, so you pass that.Second, if
dataBufferis empty at this point, thisglBufferDatawill effectively have a size of 0.glBufferSubDatacannot reallocate the size of the buffer. I would suggest using the properglBufferDatato allocate a specific size of buffer storage, rather than passingdataBuffer.And make sure that your later
glBufferSubDatacalls don’t try to set memory outside of that storage. So allocate a bunch of memory.Lastly, investigate some buffer object streaming techniques if you’re serious about this.