How to use vertex arrays?

I’m trying to convert some rendering code that uses plain glVertex() calls and the like into code that uses vertex arrays but without luck so far.

Hopefully there’s someone willing to take a look at what’s wrong with the following code? Old a new code are mixed using a boolean to determine which to use for rendering, but they should do exactly the same. The “old” code works so you can assume that basic setup and such works correctly. But ofcourse I can post the complete source if necessary.

Any help would be much appreciated.

Cheers,
-Tako

init():


            if (useArrays) {
                  vertBuf = ByteBuffer.allocateDirect(12 * 4).asFloatBuffer();
                  texBuf = ByteBuffer.allocateDirect(8 * 4).asFloatBuffer();
                  
                  texBuf.put(0.0f).put(0.0f);
                  vertBuf.put(-1.0f).put(-1.0f).put(1.0f);
                  texBuf.put(1.0f).put(0.0f);
                  vertBuf.put(1.0f).put(-1.0f).put(1.0f);
                  texBuf.put(1.0f).put(1.0f);
                  vertBuf.put(1.0f).put(1.0f).put(1.0f);
                  texBuf.put(0.0f).put(1.0f);
                  vertBuf.put(-1.0f).put(1.0f).put(1.0f);
            } else {
                  list = gl.glGenLists(1);
                  gl.glNewList(list, GL.GL_COMPILE);
                  gl.glTexCoord2f(0.0f, 0.0f);
                  gl.glVertex3f(-1.0f, -1.0f, 1.0f);
                  gl.glTexCoord2f(1.0f, 0.0f);
                  gl.glVertex3f(1.0f, -1.0f, 1.0f);
                  gl.glTexCoord2f(1.0f, 1.0f);
                  gl.glVertex3f(1.0f, 1.0f, 1.0f);
                  gl.glTexCoord2f(0.0f, 1.0f);
                  gl.glVertex3f(-1.0f, 1.0f, 1.0f);
                  gl.glEndList();
            }

display():


            if (useArrays) {
                  gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
                  gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
                  
                  gl.glVertexPointer(3, GL.GL_FLOAT, 3 * 4, vertBuf);
                  gl.glTexCoordPointer(2, GL.GL_FLOAT, 2 * 4, texBuf);
                  
                  gl.glDrawArrays(GL.GL_QUADS, 0, 4);
                  
                  gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
                  gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
            } else {
                  gl.glBegin(GL.GL_QUADS);
                  gl.glCallList(list);
                  gl.glEnd();
            }

rewind vertBuf and texBuf befor calling glVertexPointer and glTexCoordPointer.

Nope, doesn’t help :-/

In fact, I have those rewinds in there but took them out for the example above because they didn’t make any difference anyway.

Jogl calls ignore buffer position/mark/limit etc. with buffer data, so rewinding or fliping shouldn’t make any difference.

From the docs:

[quote]stride
The byte offset between consecutive vertices. When stride is zero, the vertices are tightly packed in the array.
[/quote]
In this case you’ve got separate vertex and texture coord buffers, and no gaps between the actual data elements, so stride should be 0.

sigh That’s what you get for being lazy, using Eclipse I depend a lot on the info the IDE gives me but of course a big part of JOGL is generated and so has very unhelpful argument names and I just didn’t check the docs. I had tried a 0 stride before though and it didn’t work either. The display code now looks like this:


            if (useArrays) {
                  gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
                  gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
                  
                  gl.glVertexPointer(3, GL.GL_FLOAT, 0, vertBuf);
                  gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, texBuf);
                  
                  gl.glDrawArrays(GL.GL_QUADS, 0, 4);
                  
                  gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
                  gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
            } else {
                  gl.glBegin(GL.GL_QUADS);
                  gl.glCallList(list);
                  gl.glEnd();
            }

Would posting a download URL to the code be more helpful?

edit: removed the calls to rewind()

I’m out of ideas, perhaps some generous use of glGetError might be an idea.

Ok, I put in a bunch of glGetError() statements and everything seems to be okay.

Any chance you or somebody else might take a look at the code?

It can be downloaded here: www.palacio-cristal.com/textest.jar

I would be most grateful :smiley:

Hate to chime in without being sure, but shouldn’t you have to order your buffers with the native order?

I can assure you that you do need native order to ge vertex arrays to work. Just recently rediscovered that issue in my own code - I’ve done VAs a couple of times and both times I forgot to set native order on the buffer :o)

Learn from experience? Me?? :o)

Chime in all you want, maxcaleb, because you were absolutely right as was kaffiene. Thanks both of you.

Somehow I had gotten it in my head that an allocateDirect() already returned a buffer in native byte order. I still have the feeling that I read about a method somewhere that did this but as I can’t find any proof of its existence anymore I must have been dreaming it.

Thanks for the help guys.

BTW: It didn’t make one bit of difference in the framerate, so now on to the next test with vertex objects :wink:

Quintesse,

I have been trying to get some info on how to do VBO’s
for a while now. If you happen to get a small example up and running I would greatly appreciate it if you would e-mail me the source code at kmyers@bardstowncable.net . If it’s too much trouble, or you forget, it’s no big deal.

On another note, I would have thought that Veretex Arrays would make a big difference by avoiding all those method calls, but I have no experience to go on. Are potentially thousands of method calls per frame really that cheap? Is all the fiddling with vertex arrays not worth it? Life would be easier, at least for this newbie :slight_smile:

I vaguely remember someone stating (reliable resource, isn’t it :wink: ) that you should stay in range of 2000 opengl calls per frame if you want to keep it realtime. Idea was that while triangle/pixel throughput increased very fast, amount of work which needs to be done to send command to GPU (involving context switches between user space and driver, etc) tends to be the same.