Interleaved Arrays in LWJGL???

Started by elias4444, November 02, 2007, 18:29:07

Previous topic - Next topic

elias4444

Ok, I'm finally biting the bullet on this one and moving to interleaved arrays to try and squeeze out some performance improvements. I've run into some issues though between how it's done in C++ type openGL and LWJGL. Here's what I have so far for building the big interleaved array:
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
			GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
			GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
			///////////////////////////////
			//// Big Interleaved Array ////
			///////////////////////////////
			float[] floatCoords = new float[vertexsetstexs.size()*2 + vertexsetsnorms.size()*3 + vertexsetscoords.size()*3];
			float[] coords = new float[3];
			float[] norms = new float[3];
			float[] texes = new float[2];
			for (int i = 0;i<vertexsetscoords.size();i += 8) {
				coords = vertexsetscoords.get(i);
				norms = vertexsetsnorms.get(i);
				texes = vertexsetstexs.get(i);
				floatCoords[i] = coords[0];
				floatCoords[i+1] = coords[1];
				floatCoords[i+2] = coords[2];
				floatCoords[i+3] = norms[0];
				floatCoords[i+4] = norms[1];
				floatCoords[i+5] = norms[2];
				floatCoords[i+6] = texes[0];
				floatCoords[i+7] = texes[1];
			}
			bigInterleavedArray = BufferUtils.createFloatBuffer(vertexsetstexs.size()*2 + vertexsetsnorms.size()*3 + vertexsetscoords.size()*3);
			bigInterleavedArray.put(floatCoords);
			bigInterleavedArray.flip();

                        .... Pointers?!?!?!?

My problem is the pointers at the end. In C, you use glVertexPointer(size, type, stride, pointer to start in array), glTexCoordPointer, and glNormalPointer... issue is though, how do you specify the needed "pointer to start in array" part for each one? Anyone know of an lwjgl tutorial for how to handle these differences? I wasn't able to find anything in the javadoc or wiki.

=-=-=-=-=-======-=-=-=-=-=-
http://www.tommytwisters.com

elias4444

Ugh... after posting, I finally found it: http://lwjgl.org/wiki/doku.php/lwjgl/tutorials/opengl/speedyvbo

It has an example in there which I think answers my question.

Isn't it amazing how you can look forever for something, and then, right after finally asking for help, you find it on your own anyway?  ::)

=-=-=-=-=-======-=-=-=-=-=-
http://www.tommytwisters.com

elias4444

I might as well hijack my own thread to keep asking questions about Interleaved Arrays...

Does an interleaved array have to have the same number of vertices, normals, colors, etc.? I'm realizing now as I try to interleave my data, that I simply don't have as many colors as I do vertices, since I attach colors to faces rather than vertices and also since many faces share common vertices (even though the faces may be different colors). How do you get around this?

Also, do you have to break apart and make new interleaved arrays for each different texture that might be used in a single object? I don't see how you can use multiple textures in a single array.
=-=-=-=-=-======-=-=-=-=-=-
http://www.tommytwisters.com

ndhb

Hi Elias.

Yes, you do need the same number of vertex attributes (colours, normals, etc) as vertices. When a vertex is indexed, all the enabled vertex attributes are indexed as well. If you do colours or normals, per edges you have to repeat the values.

You do not have to break your interleaved array apart, if you can get away with drawing a subset of the array for each texture - eg. you can specify a start index and count (primitives) for the function calls; drawArrays, drawElements, drawRangeElements. Then bind the texture and draw the relevant subsets from each array that uses that texture. If that is not possible, then yes, you need to split up the arrays on a per texture basis. An alternative idea is to supply different texture coordinates and use multitexturing (omit texture coordinates for texture n and include texture coordinates for texture m), but there's a limit to the number of texture units (the limit is small, NVIDIA 7800GT the number is 4). Whether this actually works, I have not verified but you can test the idea and post your results.

kind regards,
Nicolai de Haan Brøgger

elias4444

ndhb, thanks! I'm trying to do what you mentioned, but I can't seem to get the right command going.

So, let's say I have an interleaved array of just vertex and texture coordinates (3 + 2 for stride). I have a face smack dab in the middle of the array that requires a texture. How do I tell openGL to just draw the sets that make up that face? I've been trying to use glDrawRangeElements, but can't seem to figure out the options correctly (I keep getting garbage if I try to do anything other than render the whole set).

edit: I've been fiddling with glDrawRangeElements and it seems that it doesn't matter what I put in the start and end options, it still draws everything up until the count (as if count was actually the end). Any help with this would be appreciated, as I can't seem to find a good tutorial to explain this at all.

edit: once again, got it shortly after posting.  :P
For those who search here though and have the same issue.... start and end will always be 0 and the max-number-of-items in the buffer. count is how many items to grab. And then the last option for the buffer offset is "whichever item to start at multiplied by 4" (I was forgetting the multiplied by 4 part in my experiments).


=-=-=-=-=-======-=-=-=-=-=-
http://www.tommytwisters.com