I recently embarked on my first major OpenGL project: converting Art of Illusion (www.artofillusion.org) to use Jogl for interactive rendering in place of the software renderer it was using before. Following the principle of, “first make it work, then worry about speed,” I initially implemented it in a very straightforward way, doing all the rendering in immediate mode. The result was about twice as fast as the pure software renderer - not terrible, but I knew it could do a lot better.
I did some reading about OpenGL optimization, and decided that vertex arrays looked like a good first thing to try. So I converted it to use arrays for the vertices and normals, and that sped it up by about 30%. That’s something, but I was hoping for a lot more.
I profiled the code, and immediately saw the problem. By far the biggest chunk of time was taken up filling the FloatBuffers that hold the arrays. In fact, building the arrays took more than twice as much time as the calls to glDrawArrays() that actually rendered them! The problem is that calling put() on a direct buffer is a very expensive operation, involving a native method call. So the actual rendering is much faster, but preparing the arrays takes so much time that the overall speed improvement is very small.
There’s also a form of put() that takes an array, so I tried using that instead. The result was much worse. In fact, this was even slower than just rendering in immediate mode! Filling in the array takes negligible time, but passing it to put() is incredibly slow.
Is this just a case where Java is inherently slower than a lower level language like C? Or is there some better way of building the arrays that I’m missing?
This is using the latest Jogl build, running under Java 1.4.2 on Mac OS X 10.3.8.
Thanks!
Peter