Product in C -> Header file (no actual implementation) -> OpenGL
Product in Java -> Java code (which has the native method) -> JNI (Fat code, doing all sorts of magic) -> Header file -> OpenGL
product in statically compiled language - by definition file, or by hand, or by kernel call mapped to some library - library calling implementation - OpenGL do hard work - buggy driver call - GFX do work
product in Java - batch of data - JNI call - by hand call mapped to some library - library calling implementation - OpenGL do hard work - buggy driver call - GFX do work
Not too much different. If someone does too much work in native code force him to use assembly.
Of course there are alternatives
product in assembly sometimes compiled language - batch of data, or so - ruber hose analisis of driver, or dissasembly analisis of driver - translation into GFX card data - moving into driver part of memory - direct call GFX do work
halfscript - preparation of calls - one time accepting by guard a certified multithreaded splitable driver - translation by driver - exclusive mode of card - GFX do work
Of course halfcript doesn't have a compiler.
The direct GFX microcode functions call by assambly is unatractive too. Too much work to do a window, and of course that ruber hose analisis.
So we are ending with inperfect solutions, for "perfect" games.
Just a few days ago I had a little proble with one demo program, it used a funny optimalizations and SSE functions. It compiled and worked well for my old CPU, but I was forced to disable all optimalizations to force it work on my new CPU. The most beautiful thing was when I used O2 G6 switch compiler returned optimalizations back in safer way. The point is the original compiled binary would refuse to work with my computer and many others, just becouse it did a work that could be JITed.
So if someone would try to be oversmart and use "crossplatform" portability of C to do a work that could be done by same amount of line of code, or less in Java at the simillar speed, he should carefully provide alternative and test his library (that would fail unpredicably)
So if you are doing batching in Java, you are faster than in C (if library connection wasn't done in a baka way). If you are trying to do batching in C, you are ending with unreadable code and possible library inter operability problems.
As a sidenote, you could be fast in both languages, but your performance could be killed by a buggy driver. That happens most often, when there is game like Doom 3 and both main GFX manufacturers are trying to be baka.
copyright Raghar 2005 permision to cite, use as part of your article, repair grammar, and add a half page of nasty words about both NVIDIA and ATI granted. (If that halfpage wouldn't be just insults you could add more.)