Interleaved vertex arrays

Started by Qudus, January 25, 2008, 02:55:42

Previous topic - Next topic

Qudus

hi

I would like to setup a code path for interleaved vertex arrays. If VBOs are not supported (or not wanted) by the running hardware (the user), I want it to fall back to regular vertex arrays. This worked perfectly as long as I didn't use interleaved vertex data.

I found the glInterleavedArrays() method. But it looks kinda strange and doesn't seem to support custom vertex arrays, which is a must. Is this even the correct function for this intention.

Is there a tutorial about interleaved vertex data? Or can anyone point me to good documentation or give me hints?

Thanks.

Marvin

ndhb

You're right the http://www.opengl.org/sdk/docs/man/xhtml/glInterleavedArrays.xml doesn't provide patterns for custom vertex attributes. You have to use the pre-defined (color/normal/texture coordinates) for your custom data. This limitation makes interleaved arrays less general than regular arrays. Also, interleaved arrays does not consistently provide better performance on all implementations and sort of complicates the geometry handling.

There's a tutorial on interleaved arrays on the LWJGL Wiki.

darkprophet

I have never used glInterleavedArrays to be honest; I have just set the stride and offset to buffers and did interleavage that way. It was always more performant than regular vertex arrays for me, especially on a regular vertex, normal, textures interleaving buffer.

DP :)

Qudus

Quote from: darkprophet on January 25, 2008, 20:31:51
I have never used glInterleavedArrays to be honest; I have just set the stride and offset to buffers and did interleavage that way. It was always more performant than regular vertex arrays for me, especially on a regular vertex, normal, textures interleaving buffer.

This sounds like a good solution. But I don't know, how to do this. Do you mean an operation on the FloatBuffer itself? I can't find any methods for setting the stride and offset on a FloatBuffer object. And there is only one glVertexPointer(), glNormalPointer(), etc. method, that takes an offset, but it doesn't take the buffer. so there must be another method to pass the buffer before and then use glVertexPointer(), etc. to set the offset. All of the glVertexPointer() methods do take a stride value, but as I said only one takes the offset.

Marvin

Qudus

Quote from: ndhb on January 25, 2008, 11:54:31
There's a tutorial on interleaved arrays on the LWJGL Wiki.

Where would that be? I only know the one about VBOs, which deals with interleaved data.

Marvin

ndhb

Yes then it's probably the one you found already: http://lwjgl.org/wiki/doku.php/lwjgl/tutorials/opengl/speedyvbo

However, there's nothing that prevents you from using interleaved arrays without VBO extension, if you insist :)

Qudus

Quote from: ndhb on January 26, 2008, 13:53:15
Yes then it's probably the one you found already: http://lwjgl.org/wiki/doku.php/lwjgl/tutorials/opengl/speedyvbo

Yes :).

Quote from: ndhb on January 26, 2008, 13:53:15
However, there's nothing that prevents you from using interleaved arrays without VBO extension, if you insist :)

*confused*
This was exactly the point. How can I do this with (optional) custom vertex attributes?

Marvin

darkprophet

So you have one big buffer that has vertices, normals, and texture coordinates:

int stride = array.getStride() * SIZE[type];
array.getBuffer().position(array.getOffset());
			switch (array.getType()) {
				case Float:
					GL11.glVertexPointer(array.getChunkSize(), stride, (FloatBuffer) array.getBuffer());
					break;
				case Int:
					GL11.glVertexPointer(array.getChunkSize(), stride, (IntBuffer) array.getBuffer());
					break;
				default:
					throw new IllegalArgumentException("Unsupported array type");
			}


Easy huh? :)

DP

Qudus

Ah! So I only need to set the buffer's position and the values will be read in stride intervals offsetted by the initial position. This is indeed easy :). Thanks a lot.

Marvin

Qudus

I tried it. And it works half the way. Vertex coordinates are correct, but the texture coordinates are not (visually).

My vertices have coordinates and two 2-sized texture units.
So stride is (3 + 2 + 2) * 4 = 28 and offsets are 0, 12 and 20.

The stride and offsets are exactly the same as I use in VBO mode and it works in VBO mode. So these values should be correct. Do I have to adjust the buffer's limit or any other setting?

Marvin

darkprophet

what the 3 + 2 + 2 ?

3 for vertices, 2 for ?

DP :)

Qudus

Quote from: darkprophet on January 26, 2008, 16:50:02
what the 3 + 2 + 2 ?

3 for vertices, 2 for ?

The vertex coordinates have three components and are placed at offset 0. The two texture units have two components each and are placed at offsets 3 (*4) and 5 (*4). So stride is 3 (for the vertex coordinate) and 2 for the first texture unit's texture coordinates) and 2 again for the second unit (times 4 for all).

But I got an idea, which I will test right now. Is it maybe important if vertex coordinates are at the beginning or at the end of the stride? As I said, I put them at the beginning (offset 0), but maybe they have to be placed at the end. Could this be?

Marvin

Matthias

Why do you think the stride is different for each part of interleaved data ?

It's the size of the vertex structure (coords + texture + ....) - in your case 3+2+2 => 7 floats. You mix up offset and stride.

Ciao Matthias

Qudus

Quote from: Matthias on January 26, 2008, 17:58:37
Why do you think the stride is different for each part of interleaved data ?

It's the size of the vertex structure (coords + texture + ....) - in your case 3+2+2 => 7 floats. You mix up offset and stride.

Oops. I just didn'T complete my sentense ;). It shouldn't be 3 and 2 and 2, but 3 + 2 + 2 = 7 (times 4 for all). That's what I wanted to say :). But thanks for clearing me up.

Marvin

Qudus

Ha! I got it. I forgot to divide the offset by 4 to use it as a nio buffer position. Stupid me!

Thanks for your patience. It works now.

Marvin