Changes in 0.9 from 0.7

Started by llewmason, April 17, 2004, 05:37:57

Previous topic - Next topic

llewmason

I've been using 0.7 for a long while.

I just downloaded 0.9, and some of the changes make me scratch my head..

On first inspection the class structure seems pretty odd now.

No more GL?  I have to use GL11 if I want a 1.1 method, and GL13 if I want a 1.3 method.  Slightly odd, but GL13 doesn't inherit from GL11, which makes the whole thing downright wierd.  Now I need to know which OpenGL revision the gl function was added in order to find it.  That's going to get annoying fast.

If I was using 1.5, then I can see that static imports might make my life easier, since I could can just static import all the GL versions I need and the extensions I need.  For those of us that currently aren't running 1.5 (since my IDE doesn't support it right now), this new system is pretty inconvenient.

The lack of multiple inheritance, combined with the fact that the GLxx classes aren't interfaces, means I can't even create an equivalent GL class that handles all the versions up to the version that I care about.

Am I missing something (as I'm in need of sleep, so may easily have missed something)?  Did you guys have a good reason for this change that is escaping me?

llewmason

Let me add a few more while I think of them:

1)  The fact that the GLU functions take native arrays, and the GL functions take NIO buffers.  Calling glGetDouble() to get my projection matrix gives me an NIO buffer, which I then have to convert to a 2d native array before I can pass it to gluProject.

2) Why do functions exist in multiple classes in the glu package.  For example, gluLookAt is in Project and in GLU.

3) GLU classes like Project and Registry inherit from Util.  Why?

4) In fact, why are there multiple classes in the glu package at all?  If you want to make glu available, then all functions in one GLU class makes sense.  If you want to write a new utility library for GL, then that's fine, but it isn't a port of GLU, and it probably shouldn't be in a package/class called glu.

5) The set of function name changes for GLxx seems inconsistent.  glRotatef still exists, even though there isn't anything you can do except for floats, but glLightfv becomes glLight.  You still have glLightf, since you support float versus vector, but it seems like the case you care about is vector vs not, in which case you should have glLight and glLightv, and glRotate.  The inconsistency is wierd, but instead of resolving that, I'd rather you went back to the original OpenGL API names.  There are two reasons why.  Firstly, you are making it harder to get existing OpenGL users to switch if you start renaming all the APIs (and now you either need your own documentation, or a guide explaining the differences).  Secondly, porting code becomes more painful, as you have to go in and fix all the differing API names.

btw. Don't get me wrong.  I love LWJGL.  I'm just trying to understand why you made some rather odd (in my opinion) design choices as you move towards 1.0.

cfmdobbie

Hi there.  I'm not a dev, but I can answer a few of these until someone more relevant comes along! ;)

Quote from: "llewmason"I have to use GL11 if I want a 1.1 method [...]
If I was using 1.5, [...] static imports [...]
Yes, you need to use the correct GL* object for your call.  Yes, it will be wonderful when static import arrives.  Yes, it's going to be a bit of a pain until that happens. :)  The decision was made that LWJGL will be best used in a 1.5 environment, so the API is oriented towards making things easier for such developers.  It's a bit of a pain for 1.4 users, but you should get used to it pretty quick.  Also there is another choice available to you:

QuoteThe lack of multiple inheritance, [...] means I can't even create an equivalent GL class that handles all the versions up to the version that I care about.
You don't need inheritance to do that.  Create your own GL class with whatever calls you want to use, and make those calls invoke the appropiate method on the appropiate GL* class.

If you prefer a single class holding all OpenGL methods, it shouldn't be hard to set up.  In fact, then you get a lot more visibility over which methods you're using.

Quote1)  The fact that the GLU functions take native arrays, and the GL functions take NIO buffers.  Calling glGetDouble() to get my projection matrix gives me an NIO buffer, which I then have to convert to a 2d native array before I can pass it to gluProject.
It was decided that the GLU will most often be called from Java code using arrays.  So yes, unfortunately you'll need to perform an extra conversion step if you want to pass the GLU data from the GL.

Quote[...] 5) The set of function name changes for GLxx seems inconsistent.  glRotatef still exists, even though there isn't anything you can do except for floats, but glLightfv becomes glLight.[...]  Secondly, porting code becomes more painful, as you have to go in and fix all the differing API names.
It seems a bit odd, but there's method to the (perceived) madness. ;)

All methods whose arguments leave you in no doubt as to which method is being asked for have had the suffices removed.  In general, this means that only methods that take NIO buffers have been stripped.  The problem is that of automatic widening conversions - the devs found that they caused enough hassle that it was worthwhile making the argument type explicit in the method name.

Whether or not this is a good decision comes down to personal opinion.  However, note that if you decide to create your own GL proxy class, you can name the methods however you like, including stripping or returning all method suffices.

Hope you find some of this useful!
ellomynameis Charlie Dobbie.

llewmason

Thanks for the answers.

Quote from: "cfmdobbie"
QuoteThe lack of multiple inheritance, [...] means I can't even create an equivalent GL class that handles all the versions up to the version that I care about.
You don't need inheritance to do that.  Create your own GL class with whatever calls you want to use, and make those calls invoke the appropiate method on the appropiate GL* class.

If you prefer a single class holding all OpenGL methods, it shouldn't be hard to set up.  In fact, then you get a lot more visibility over which methods you're using.

I meant 'easily create an equivalent GL class' when I said 'create an equivalent GL class'.   :)

I don't consider copying all the method declarations and members by hand easy.

I still don't understand why each GLxx class doesn't inherit from earlier versions.  I thought the OpenGL API was defined such that (for example) 1.4 includes everything from 1.3 along with the new stuff in 1.4.  If that's the case, inheritance seems to be the most natural way to implement it.

elias

In fact, we had inheritance for a while, then suddenly it disappeared because of static imports. We discussed it a while and I don't think we ever got to the final conclusion that inheritance should be removed. So it might get back in again soon.

I think the reason it doesn't bother us much is that either we like the separation and being forced to know what part of GL you use (that includes at least me), or simply because people are beginning to use the jdk 1.5 beta.

Other than that, I think inheritance should go back in for the core classes, so you could simply use GL15 all over if you really wanted. For extensions, you still have to know the exact class, which I think is reasonable. Thoughts?

- elias

elias

If you still want to port your stuff to 0.9, a safe bet is to replace all instances of "GL." with "GL11.". Very little was added to 1.2 (mostly stuff is in the ARB_imaging extensions) and 1.3 (mostly multitexturing and 3d texture targets) and most people never use 1.4 and certainly not 1.5. If you're using extensions, you'll have to convert their use to the exact classes regardless of how the inheritance issue is solved.

- elias

llewmason

All working.

For others who may go through similar issues, here's the things I had to fix.

1) All GL. calls to GLxx, ARBxx, NVxx, etc.

This was annoying but mostly search replace.
I was only using one thing in GL12 (GL_CLAMP_TO_EDGE for skyboxes).  Everything else was GL11 or an extension (for me NVProgram, NVVertexProgram, NVDepthClamp, ARBMultitexture).

2) Keyboard read() now merged into poll().

3) GLU now pushed into Java classes.

I only used a few functions (gluProject, gluPerspective, gluLookAt).

4) Functions like glLightfv() renamed to glLight()

Again, search and replace exercise.

5) GLU functions now take native arrays instead of NIO arrays.

Since I was passing GL results into GLU functions, I had to add manual conversions to construct the native arrays on demand.

6) Memory bounds checks require extra memory on end of array.

There have already been threads about this.
The GL functions require 4 units of memory (e.g., 4 floats meaning 16 bytes) even if you are only fetching one unit (e.g., 1 float meaning 4 bytes).
So, if you call
GL11.glGetInteger(ARBMultitexture.GL_MAX_TEXTURE_UNITS_ARB, nativeint);

then you need 4 integers allocated in nativeint, not 1 (even though it's only going to fill 1).  IMO, this sucks, because I like to use limit() sometimes to determine my loop condition on NIO buffers, and now I can't.  That said, most of these cases you know what's in the buffer exactly anyway.

Luckily, I did the right thing, and used a memory creation class for all my NIO buffers.  So I made one set of changes in one class, and none of my code noticed the new requirement.

7) MacOS X support is broken due to a missing function.  I fixed it locally myself, and hopefully someone will fix that in the codebase soon.  v0.91 anyone?

One thing that helped me a lot was that I had wrapper GraphicsService and SoundService classes.  None of my code called LWJGL directly, so the only changes were to that codebase.  I did that on purpose given how much LWJGL seemed to change between versions (and because I wasn't sure whether LWJGL was going to survive, and wanted to be able to move to JOGL or something if I had to).  This isolated all my real code from my LWJGL interface.  From 0.7 to 0.9 I didn't change a single line outside of my service classes.[/code]

Matzon

Quote from: "llewmason"
7) MacOS X support is broken due to a missing function.  I fixed it locally myself, and hopefully someone will fix that in the codebase soon.  v0.91 anyone?
How... good are you on os x? - you talked about helping out - and that would be really awesome, as the os x port is a bit limited, due to lack of dedicated developer. We're planning some major work on os x - could you help out?

Quote from: "llewmason"
One thing that helped me a lot was that I had wrapper GraphicsService and SoundService classes.
FWIW, you should always try to abstract most of the code, so yes - abstracting out lwjgl is a good thing, however not because  we wont "survive" ;) - we definately will survive, IMO we've got a *much* better implementation than jogl - but I am ofcourse biased :)

llewmason

Quote from: "Matzon"
How... good are you on os x? - you talked about helping out - and that would be really awesome, as the os x port is a bit limited, due to lack of dedicated developer. We're planning some major work on os x - could you help out?

I haven't done any commercial OS X development.  That said, I've screwed around with it, and would be happy to learn more as needed.  OS X is my primary system at home.

My day job involves enterprise application development in Java (and C++ - whenever we can't avoid it) on Windows, Solaris, AIX and Linux.

I'd be happy to help out.  Perhaps we can followup over email as to what your 'major plans' for OS X are.  Send something to llewmason {at} yahoo.com.

Quote from: "Matzon"
FWIW, you should always try to abstract most of the code, so yes - abstracting out lwjgl is a good thing, however not because  we wont "survive" ;) - we definately will survive, IMO we've got a *much* better implementation than jogl - but I am ofcourse biased :)

Oh, don't get me wrong. I'm not a big fan of JOGL.  I have no need for Swing for the sort of things I want to use OpenGL for.  For example, I ended up writing my own PNG loader to avoid having to bring in all of AWT just so I could use the image io stuff from the JDK.

Low level access to the hardware through Java is what I want.  That said, my biggest concern wasn't the project surviving, it was the way you guys rewrote the API every release.  Now I'm shielded from that (mostly).  Also, I actually started playing with OpenGL under Java before LWJGL even existed, and the transition from GL4Java to LWJGL was pretty painless because of the time I spent writing my abstraction layer.

llewmason

6) Memory bounds checks require extra memory on end of array.

Just to avoid further confusion, everywhere I said 4 units I meant 16 units.  So getting 1 integer actually requires a buffer of 16 integers (64 bytes).

Matzon

Quote from: "llewmason"I'd be happy to help out. Perhaps we can followup over email as to what your 'major plans' for OS X are. Send something to llewmason {at} yahoo.com.
Cool, I'll just contact Elias & Cas (mostly elias) for the info on OS X, since he has something lined out already.

princec

We're listening :)

Basically our plans for OSX are along the lines of: use AWT and HID somehow, along with a small GL context creator adapter. We figured that seeing as AWT is guaranteed supported on OSX we may as well use it to display dialog boxes and also possibly we might as well use it to create the Window for MacOS. The GL context adapter is something gregorypierce wrote (which he said we could take a look at) but all it does is create an OpenGL context on an AWT window as far as I can tell - which means it works with LWJGL.

The HID code is the real bastard - but we might be able to avoid it as the existing code might work OK with AWT.

Cas :)

elias

Note that HID should only be used for Controller. Mouse and Keyboard are best taken care of by the standard event method (awt events in the case of awt).

- elias

cfmdobbie

ellomynameis Charlie Dobbie.

princec

on another related note: I shall add all the extension methods too.

Cas :)