glMultiDrawElements and GL_ELEMENT_ARRAY_BUFFER

All,

I am attempting to render VBOs with glMultiDrawElements() and buffering the vertex indices. My application crashes on the glMultiDrawElements() call with the following:

# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x05041d2f, pid=5808, tid=3152

The following psuedo code represenets how I might set up the vertex indices to render two triangles, and illustrates where my mistake most likely exists.

FloatBuffer vertices = {0.0, 0.0, 1.0, 0.0, 0.0, 1.0,   1.0, 1.0, 2.0, 1.0, 1.0, 2.0}
IntBuffer indices= {0, 1, 2,   3, 4, 5};
IntBuffer groupLengths = {3, 3};
int count = 2;
IntBuffer[] offsets = {{0}, {12}}; //byte offsets of primitives in indices

//more code here

glBindBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.capacity() * 4, indices, GL_STATIC_DRAW);

//more code here

glMultiDrawElements(GL_LINE_LOOP, groupLengths, GL2.GL_UNSIGNED_INT, offsets, count);

I hope this is clear enough for everyone. Please let me know if you see anything wrong with this structuring. Or if anyone can post how they rendered VBOs usings glMultiDrawElements() and buffering the indices it would be very much appreciated. From what I have found googling, this appears to be something that many others have trouble with.

Thank you,
Robert

Try doing the glDrawElements yourself first: simulate glMultiDrawElements (which is all it does under the hood anyway). If that works… leave it that way :slight_smile:

Cas :slight_smile:

All,

There is no performance gain for using glMultiDrawElements()?

Thank you,
Robert

Well, there is a slight difference (less JNI calls), but I guess that’s not really what the suggestions is about.

glDrawElements is ‘known to work’ – there is a (slim) chance your current code won’t work with glDrawElements either. That’d mean that there is a bug in your code, which will probably be easy to fix. If all of the above happened to be the case, you can take the fix and use it to fix the original bug in your code using glMultiDrawElements.

There is no really measurable gain of performance when using glMultiDrawElements() as far as I know.

What if you have a 1000 array of triangle strips? That means 1 call vs. 1000 calls… but in most cases its better to use degenerate tris to stitch the strips.

May as well just use GL_TRIANGLES. Any card with even a 3-vertex post transform cache will be roughly the same speed as GL_TRIANGLE_STRIP for rather less headaches.

Cas :slight_smile:

Some graphic cards will only perform a loop like you were not using this function… Do you think strips can still really improve the performance on recent graphic cards?

with vertex-caches >=24 (on ancient DX9 cards like ATi Radeon 9700 Pro) I can hardly imagine that GL_TRIANGLE_STRIP will be any faster. Having said that, I haven’t tested it. With strips you need these no-fragment triangles to connect the batches, which will have to pass through the rasterizer, which might even slow it down a tiny bit.

[quote]Some graphic cards will only perform a loop like you were not using this function… Do you think strips can still really improve the performance on recent graphic cards?
[/quote]
I was thinking android/iphone, where it is recommended to use strips.

In that case, maybe you could do some benchmarks and enlighten us with the results?

No I can’t. I don’t have an android phone, only the emulator which doesn’t represent actual device performance.
If you want to send me an android phone, please contact me at shadowislord@gmail.com, thanks.

;D

Kev’s got one, we could ask him to try it out :slight_smile:

Though I honestly can’t imagine any phone hardware having either a GPU or a post-transform cache. But you never know.

Cas :slight_smile:

Smartphones have had GPUs for quite a few years now…

For the latest/greatest: http://www.slashgear.com/htc-to-use-nvidia-tegra-for-1080p-capable-smartphones-1630752/

For iPhone (which has similar graphics chip to the motorola droid) it says on this site:
http://developer.apple.com/iphone/library/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html

[quote]Using triangle strips significantly reduces the number of vertex calculations that OpenGL ES must perform on your geometry. Your performance is best if an object (or even a group of objects) can be submitted in a single unindexed triangle strip using glDrawArrays. This may involve adding degenerate triangles to merge multiple smaller triangle strips into a single large strip.

If your geometry duplicates a large number of vertices (because vertices are shared by many triangles or because a large number of duplicate vertices were added to merge multiple triangle strips), you may obtain better performance by submitting an indexed triangle strip using glDrawElements. For performance, your application should sort the drawing order so that triangles that share the same vertex are drawn reasonably close to one another in the strip. Graphics hardware often caches recent vertex calculations, so submitting all the triangles that use the same vertex can allow the hardware to used the cached calculations, rather than repeating vertex calculations.

For best results, you should test your geometry using both indexed and unindexed triangle strips, and use the one that performs the fastest.
[/quote]