Re: [sdljava-users] Usage example for glGetDoublev
Status: Beta
Brought to you by:
ivan_ganza
From: Robert S. <the...@gm...> - 2005-09-13 00:26:44
|
Hi, I just want to jump into the discussion because I was one of the persons who suggested Ivan to use NIO buffers instead of Java arrays (and I have some small background about the topic from JNI and GNU Classpath coding). > The biggest buffer I use that way is there to store a matrix of > 4x4 doubles, that is, 128 bytes. Perfect. This is really the point where you can use NIO buffers. It may be look odd to you but a regular Java array is more troublesome than a NIO buffer. The buffer is an object denoting a certain memory region. Therefore you can think of it as a thin wrapper around a normal C array (or memory region that allocated with malloc/calloc). A Java array is something that lifes inside the JVM and can be implemented very differently. NIO buffers and Java arrays have very similar JNI functions to interact with them. Both have a function which returns a pointer so that you can modify the data in C-style. However the array access function explicitly states that you *may* receive the pointer to a copy of the original data (remember that Java arrays life in the JVMs heap and may be moved around because of garbage collection and memory compaction). This won't happen with NIO buffers. If you have a feeling that frequent bytebuffer instantiations would harm the performance of your application then please have a look whether you may not solve this problem in a different way (e.g. pooling buffers or the like). > Using byte buffers may be a valid approach when working on large, uniform > amounts of data like framebuffers. But that is not the case with geometry > data for OpenGL. Using vertex arrays is almost out of question for me since > the geometry data I have is very dynamic in every way. Definitely not. NIO buffers can be used wherever interaction with native machinery is involved. I once wrote a jinput plugin which uses the Linux kernel's input system to access mouse/keyboard/joypad etc (You can find the sources in the respective forums at javagaming.org). It makes heavy use of NIO buffers even for such small amounts of data (key/button/axes states) and I think it is a big win that the system's kernel can write into the memory which it shares with my Java application. > Well, this is not trying to be a rant. I'm just not yet convinced that this is > the right approach. It looks like far too much overhead to me, making all the > OpenGL functions taking (small) arrays practically useless. Well, in which way could they be implemented otherwise? At one point you will forced to create a buffer in memory (probably C). If you hand over the data in Java arrays and copy it over into a malloc'ed memory region then this would hit performance seriously (You need one copy operation and one time malloc/free in GLJava's code.) With NIO buffers the JNI implementation would simply return the buffer's pointer and call the OpenGL function. The handling of the buffer (recreate it every time or do some pooling) is up to you - the application programmer. > Maybe some > benchmarking is in order to get some definitive answers, but I don't have > enough time for that. Well I try to prove it with a bit of pseudo code. (I use pseudo code because I dont know the JNI function names by heart. They are very tedious ...) 1. With Java arrays GL.java public class GL { public native setSomethingv(int[] foo); } net_sf_GL.c: setSomethingv(jvm, jobject java_array){ jint* thevalues = JVM_get_pointer_to_java_array(java_array); // may copy int size = JVM_get_size_of_java_array(java_array); int* buffer = malloc(sizeof(int) * size); memcopy(thevalues -> buffer, size * sizeof(int)); GLsetSomething(buffer); JVM_release_access_to_java_array(java_array); } 2. With NIO buffers public class GL { public native setSomethingv(IntBuffer foo); } net_sf_GL.c: setSomethingv(jvm, jobject nio_buffer){ jint* thevalues = JVM_get_pointer_of_nio_buffer(nio_buffer); GLsetSomething(thevalues); JVM_release_access_to_java_array(java_array); } (I am broadly ignoring any type conversion oddities here.) Btw: There is a utility class in GLJava that creates direct Integer, Long, Short, Double and Float buffers in one method call (In fact every newer OpenGL binding* has these methods ...) cu Robert * JOGL, LwJGL |