Information on gl*Pointer

Started by Cornix, December 19, 2013, 12:05:34

Previous topic - Next topic

Cornix

Hi there,

I have a little question about gl*Pointer functions with lwjgl.
Lets say I have a float buffer like this:
float[] vertices = new float[] {
		// x, y, z, 1
		// u, v, 0, 1
		// r, g, b, a
		x, 		y, 		z, 1,
		0, 		0, 		0, 1,
		1, 		0, 		0, 1,
		
		x, 		y + h, 	z, 1,
		0, 		1, 		0, 1,
		0, 		1, 		0, 1,
		
		x + w, 	y + h, 	z, 1,
		1, 		1, 		0, 1,
		0, 		0, 		1, 1,
		
		x + w, 	y, 		z, 1,
		1, 		0, 		0, 1,
		1, 		1, 		1, 1
};


And I dont want to use a VBO. I would like to do something like this:
glVertexPointer(size == 4, stride == 12, from == 0, buffer);
glTexcoordPointer(size == 4, stride == 12, from == 4, buffer);
glColorPointer(size == 4, stride == 12, from == 8, buffer);

(I know this is not correct java syntax)

However, this does not seem to be possible with the way lwjgl does it.
The only way to specify an offset is, when a buffer is bound as ARRAY_BUFFER.
But in C this would be possible.

Is there some kind of function which I am just overlooking right now?
Or, if there is no way to do this, is this planned to be implemented in lwjgl 3.0?
Or, if it is not going to be implemented in lwjgl, is there any downside of splitting the buffer up in several smaller buffers, one for position, one for texcoords and one for colors?

Thanks in advance.

spasi

It is of course possible to do in LWJGL: by changing the current FloatBuffer.position() you're effectively changing the "from" parameter in your pseudo-code.

In C terms, when you pass a NIO buffer to an LWJGL method, you're basically passing a pointer with an address equal to the buffer's (base address + current position * element type scale). Where "element type scale" is 1 for ByteBuffer, 2 for ShortBuffer, 4 for Int/FloatBuffer, etc.

Cornix

Thanks for the reply!
This sounds great, however, I am having some difficulties in using it.

Heres some code:
This works!
float[] vertex_data = new float[] {
				x, 	y, 	z, 1,
				x, 	y + h, 	z, 1,
				x + w, 	y + h, 	z, 1,
				x + w, 	y, 	z, 1
		};
		float[] texcoord_data = new float[] {
				0, 0, 0, 1,
				0, 1, 0, 1,
				1, 1, 0, 1,
				1, 0, 0, 1
		};
		float[] color_data = new float[] {
				1, 0, 0, 1,
				0, 1, 0, 1,
				0, 0, 1, 1,
				1, 1, 1, 1
		};
		
		GL11.glEnable(GL11.GL_VERTEX_ARRAY);
		GL11.glEnable(GL11.GL_TEXTURE_COORD_ARRAY);
		GL11.glEnable(GL11.GL_COLOR_ARRAY);
		
		GL11.glVertexPointer(4, 0, BufferMagic.make(vertex_data));
		GL11.glTexCoordPointer(4, 0, BufferMagic.make(texcoord_data));
		GL11.glColorPointer(4, 0, BufferMagic.make(color_data));



This does not work -.-
float[] vertices = new float[] {
				// x, 		y, 		z, 1
				// u, 		v, 		0, 1
				// r, 		g, 		b, a

				x, 		y, 		z, 1,
				0, 		0, 		0, 1,
				1, 		0, 		0, 1,
				
				x, 		y + h, 	z, 1,
				0, 		1, 		0, 1,
				0, 		1, 		0, 1,
				
				x + w, 	y + h, 	z, 1,
				1, 		1, 		0, 1,
				0, 		0, 		1, 1,
				
				x + w, 	y, 		z, 1,
				1, 		0, 		0, 1,
				1, 		1, 		1, 1
		};
		FloatBuffer buf = Buffer_Generator.make_buffer(vertices);
		buf.clear();
		
		int floatSize = 4;
		int stride = 12 * floatSize;
		
		GL11.glEnable(GL11.GL_VERTEX_ARRAY);
		GL11.glEnable(GL11.GL_TEXTURE_COORD_ARRAY);
		GL11.glEnable(GL11.GL_COLOR_ARRAY);
		
		buf.position(0 * floatSize);
		buf.limit(buf.capacity());
		GL11.glVertexPointer(4, stride, buf);
		buf.clear();
		
		buf.position(4 * floatSize);
		buf.limit(buf.capacity());
		GL11.glTexCoordPointer(4, stride, buf);
		buf.clear();
		
		buf.position(8 * floatSize);
		buf.limit(buf.capacity());
		GL11.glColorPointer(4, stride, buf);
		buf.clear();


My guess would be that either "stride" or the offsets are calculated incorrectly.
But when I have 4 elements for position, texcoords and color, and each element is a float, then my stride should be 4 * 12, isnt that correct?

spasi

The stride is correct, it is correctly calculated in bytes. The offsets are wrong though, because buf is a FloatBuffer, not a ByteBuffer. As I said in my previous reply, the current position is scaled by the number of bytes per element in the buffer (i.e. 4). So, change:

buf.position(0 * floatSize);
buf.position(4 * floatSize);
buf.position(8 * floatSize);


to:

buf.position(0);
buf.position(4);
buf.position(8);


and it will work.

Cornix

Well, that makes sense and it works now.

Thank you very much.