Help Updating GLArrayDataServer

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Help Updating GLArrayDataServer

glangho
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.
Reply | Threaded
Open this post in threaded view
|

Re: Help Updating GLArrayDataServer

gouessej
Administrator
Hi

glMultiDrawArrays() is broken on some platforms, it's not worth it.

You use GL_STATIC_DRAW, it's not a good idea if you'd like to modify the content of GLArrayDataServer.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Help Updating GLArrayDataServer

glangho
gouessej wrote
Hi

glMultiDrawArrays() is broken on some platforms, it's not worth it.

You use GL_STATIC_DRAW, it's not a good idea if you'd like to modify the content of GLArrayDataServer.
I was going to change that to DYNAMIC_DRAW, but from what I'm reading in 2D it's probably easier to just use STREAM_DRAW and replace the entire buffer whenever anything changes on screen.  Is it OK to continuously replace my GLArrayDataServer object or should I reuse the same GLArrayDataServer and only replace its buffer?

Thanks for the glMultiDrawArrays() tip.  I'll be switching to glDrawArrays() once I get down to a single VBO of all my onscreen objects.
Reply | Threaded
Open this post in threaded view
|

Re: Help Updating GLArrayDataServer

gouessej
Administrator
You should only update the content of the buffer.
Julien Gouesse | Personal blog | Website