Hello,
is there any speed difference using ‘normal’ int arrays to store buffers pointers or using IntBuffers? glDrawRangeElements for exaple…
Thanks…
Hello,
is there any speed difference using ‘normal’ int arrays to store buffers pointers or using IntBuffers? glDrawRangeElements for exaple…
Thanks…
The inly difference is that for direct IntBuffers there is no data-copy involved when it gets sent through JNI.
heap IntBuffers are basicly just int[]s with a fancy wrapper.
So for small buffers the difference is tiny, but the larger your data-set, the more time the data-copy takes.
One of the differences is that if you pass in an int[] the JOGL internals has to go wrap it in an NIOBuffer. That’s memory allocation and garbage collection overhead, and potentially copying into the platform-specific byte order. Both of these cost you some performance. You’re always better off using NIO Buffers directly if given the choice.
There’s a fair amount of misinformation floating around in this thread. For any routine accepting for example both an int[] and an IntBuffer there is no performance difference between the two. Some routines like glVertexPointer accept only direct NIO Buffers (this is mentioned in the javadoc) and in this case the decision has basically been made for you – this is necessary due to the semantics of these C routines. Some routines like glTexImage2D accept either a direct or non-direct Buffer – it is up to you whether you want to wrap an int[] in an IntBuffer or allocate a direct IntBuffer. Both are basically the same speed.
What is the misinformation then?
Do int[]s not involve a data-copy when sent through JNI?
Could you clear this up please?
Please Ken,
clear it up to me too. I’m very confused.
for example: i want to load a model,
a read it’s data to a normal Java structures, then i create vbos from them (int[]) and in the rendering circle
using gl.glBindBuffer( GL.GL_ARRAY_BUFFER , vertexVBO[0] ); and then
gl.glVertexPointer( 3, GL.GL_FLOAT, 0, 0 );
if i’m using NIOBuffers, i haven’t to use glBindBuffer, just
gl.glVertexPointer( 3, GL.GL_FLOAT, vertexBuffer );
this statement.
is it correct?
Why should i use NIOBuffers, if it doesn’t result better performance?
by the way, if i create buffers like this:
FloatBuffer buff = BufferUtil.newFloatBuffer( data.length );
buff.put( data );
buff.rewind();
is it correct? when should i use direct or indirect options? or byteorder?
Thanks for your patience
No, they don’t. JOGL’s autogenerated native code uses GetPrimitiveArrayCritical which incurs no data copy. They also aren’t automatically wrapped in a Buffer. In situations where a Buffer is mandatory this is up to the end user.
The performance difference in this case isn’t between using NIO Buffers or not, but between using vertex arrays and VBOs. The drivers have more information about what (if anything) has changed from frame to frame when using VBOs so they can usually be more efficient than using vertex arrays.
If you are sending the resulting data to one of the OpenGL routines that requires a direct buffer (any of the “pointer” routines like glVertexPointer, for example) then you must use a direct buffer. Otherwise it’s basically up to the application. Generally we do not recommend mixing direct and non-direct Buffers in the same application, but this is becoming less of an issue with recent optimizations added to HotSpot such as bimorphic call inlining where the JVM can generate efficient code for both cases simultaneously.
If you’re using direct Buffers you should always allocate them either using the BufferUtil class or make 100% sure you set the byte order to the native order. Using anything except the native order with OpenGL or basically any C library is going to be wrong because the notion of “byte order” for Buffers is purely a Java concept.
Thanks…
one off-topic question, if you don’t mind…
if i’m rendering a lot of geometry (400 tree and terrainpieces), and the JProfiler found the bottleneck: the calls of glDrawRangeElements (96% of cpu usage).
I’m using indexed VBO-s (no nio buffers), triangle_strip models (using nvtristrip).
How can i specify the exact speed problem? How can i interpret this bottleneck? i have a lot of data transfering between cpu and gpu?
If i rewrite the renderer code in my engine, to nio buffers, i receive no performance speed-up?
i read all performance-papers from ati and nvidia and opengl.org, but i don’t know what to do with glDrawRangeElements problems…
I think you should sign up for NVidia’s developer program and try their NVPerfKit including the instrumented drivers. Hopefully the performance counters should show you what’s taking all of the time. If you’re using static draw VBOs I would expect that there should be no transfer of geometry between the CPU and GPU each frame unless you have so much geometry that it can’t all fit on the card.
So from what you’ve said, Ken, there’s no performance difference on the OpenGL/JOGL side between using arrays and nio buffers, but what about adding elements to the array or buffer before its passed into OpenGL (granted, this is more a Java question than a JOGL question, but its still relevent). Is it faster to put elements into direct nio buffers, assign array elements, or is it about the same?
It should be about the same. If it isn’t it’s effectively a HotSpot bug. Some work is still ongoing to smooth out some performance issues with Buffers but I wouldn’t let that stop you from using them.