Posted by
glangho on
May 25, 2016; 8:34pm
URL: https://forum.jogamp.org/Help-Updating-GLArrayDataServer-tp4036745.html
Hello,
I've been using the shader utilities and GLArrayDataServer to draw 2D objects for a bit now. I've been handling animation by storing all frames in my vbo and making multiple draw calls with different values passed to glMultiDrawArrays() to get the correct animation for a given entity. I hear it's a better practice to instead make a single draw call and update your vbo each frame with what's on the screen. I want to test this out with my tile maps since it will be easy to manage where a tile is in my vbo.
Here's a basic example of how I build a GLArrayDataServer interleaved vbo.
public void buildVbo(ShaderState st) {
int elementCount = 1;
int vertexCount = 6 * elementCount;
vbo = GLArrayDataServer.createGLSLInterleaved(2 + 4 + 2, GL2.GL_FLOAT, false, vertexCount,
GL2.GL_STATIC_DRAW);
{
vbo.addGLSLSubArray("vVertex2f", 2, GL2.GL_ARRAY_BUFFER);
vbo.addGLSLSubArray("vColor4f", 4, GL2.GL_ARRAY_BUFFER);
vbo.addGLSLSubArray("vTexture2f", 2, GL2.GL_ARRAY_BUFFER);
}
final FloatBuffer fb = (FloatBuffer) vbo.getBuffer();
final float[] vertexArray = new float[vertexCount * 2];
final float[] colorArray = new float[vertexCount * 4];
final float[] textureVertexArray = new float[vertexCount * 2];
int vboCounter = 0;
vertexArray[vboCounter + 0] = (-w / 2);
vertexArray[vboCounter + 1] = (h / 2);
// vertexArray[vboCounter...
vertexArray[vboCounter + 11] = (h / 2);
colorArray[(vboCounter * 2) + 0] = 1.0f;
colorArray[(vboCounter * 2) + 1] = 1.0f;
// colorArray[(vboCounter...
colorArray[(vboCounter * 2) + 23] = 1.0f;
textureVertexArray[vboCounter + 0] = 0.0f;
textureVertexArray[vboCounter + 1] = 0.0f;
// textureVertexArray[vboCounter...
textureVertexArray[vboCounter + 11] = 0.0f;
vboCounter += 12;
try {
for (int j = 0; j < vertexCount; j++) {
fb.put(vertexArray, j * 2, 2);
fb.put(colorArray, j * 4, 4);
fb.put(textureVertexArray, j * 2, 2);
}
} catch (BufferOverflowException | IndexOutOfBoundsException | ReadOnlyBufferException ex) {
Logger.getLogger(TileSelector.class.getName()).log(Level.SEVERE, null, ex);
}
vbo.seal(true);
st.ownAttribute(vbo, true);
first = new int[elementCount];
count = new int[elementCount];
for (int k = 0; k < elementCount; k++) {
first[k] = k * 6;
count[k] = 6;
}
draw = elementCount;
}
I draw the VBO with something like:
public void draw() {
GL2 gl = GLContext.getCurrentGL().getGL2();
vbo.enableBuffer(gl, true);
gl.glMultiDrawArrays(GL2.GL_TRIANGLES, first, 0, count, 0, draw);
vbo.enableBuffer(gl, false);
}
So with my tilemap example, say I want to change a color of a single tile to green. I figure I need to call getBuffer() and update the correct position. That should be fairly easy because I know would know which tiles are stored in the buffer and in which position (i.e., first tile would be first 48 bytes). Do I need to do anything else on the GLArrayDataServer side or do I just call seal(true) again?
Thanks for your time.