StandardGame woes

Hello again



I've had a miserable day with StandardGame. As a professional java developer I was instantly attracted by the programming elegance of the StandardGame class. And the opportunity to avoid all the unnecesary code of BaseSimpleGame and it's cohorts was too tempting to pass up on.



So, I finally get myself a working app with some terrain and I turn my attention to the water level that I need to put into my scene. Now, the projected water seen in the TestProjectedWater app is beautiful, but I don't want to jump in too deep and have no idea what projected actually means :wink: So, I figure TestSimpleQuadWater has got my name written all over it. It's nice to look at and I think I can get it into my GameState to display in my StandardGame's OpenGL.



Yeah, right !



I had all sorts of problems, but the one I'm currently facing has got me stumped. TestSimpleQuadWater extends SimplePassGame which sets up everything it needs. Looking through the source for SimplePassGame and all it's parent classes I took out everything I thought I needed and put it into my active GameState. I'll confess right now that I have no idea what a pass is, but figured I'd look that up later (what a cowboy!).



Drilling down through the class heirarchy I have found that my issue is in a call to the GLSLShaderObjectsState's isSupported() method. It throws a NullPointer. The null it is complaining about is from the call to GLContext.getCapabilities() which returns null.



I figure that one of the SimplePassGame support classes is doing something behind the scenes that I haven't found, but I can't find it for the life of me.



So, two questions really:


  1. What am I missing ?
  2. Am I creating a rod for my own back by trying to use StandardGame ? I'd really like to, but if it's just not what people are doing, then I won't.



    Thanks in anticipation guys.







    Mak

I think adamgp is on the right track.  The only big down-side to StandardGame is that you often have to take the mentality, "When in doubt, stick it in GameTaskQueue and see if that fixes it". :wink:



There's not been a whole lot of work done with passes in StandardGame that I know of.  There is a DebugGameState which replicates the functionality of SimpleGame, but I never got around to replicating a similar GameState for SimplePassGame.  If through this experience you aren't cursing StandardGame (which I would be offended at because I originally wrote it) you might consider releasing a PassGameState to the community to help others trying to get started with it.



There is definitely a certain level of frustration getting going with StandardGame when you're doing a lot of stuff that needs to be done in the OpenGL thread, but I can tell you from my own experience (and believe many others would echo the sentiment) that once you've successfully converted you'll never go back. :wink:

Excellent info guys. Thanks very much. I'll check it out right now.



I wonder if you could suggest a source of information for which operations are required to be executed within the OpenGL thread ? Looking at your StandardGame Awesomeness examples darkfrog, it is not clear why box.lock() would be required to be executed in the OpenGL thread, whilst box.updateRenderState() is not. Is this just something you pick up as you go along, or is there something to this end documented in OpenGL docs somewhere ?



Thanks again you two … very helpful and prompt.







Mak

If you understand the internals of the engine and what aspects make direct calls to OpenGL it's pretty straight-forward.  However, since I don't understand all the internals and expect very few people do except some of the other weird developers (shhh…they might be listening), it's sort of hit and miss.  You can generally take an educated guess as to logical nature of certain aspects actually doing something in OpenGL.  This really hasn't been documented, but about the time it actually gets documented we will have the information necessary to fix it so they are not directly calling OpenGL anymore. :wink:

Hmm, im currently realising that you need to immerse yourself deep into opengl stuff to acheive good results, the engine alone doesnt cut it - its the frills you add that makes the difference

Well, I believe eventually this won't necessarily be the case, but we're sort of stuck in a transition phase where portions of jME are thread-safe and others are not.  We will ideally move to complete thread-safety where instructions will be queued up and handled in the OpenGL thread during an update or render call, but until that's done it's going to still be a little frustrating if you don't have some OpenGL knowledge to go with it.

Not sure if you see the bigger picture. Mr Coder has demostrated some seriously good effects. These are not simple ConcurrentLinkedQueues's or Futertask's.



Simply put, what you think you see is not actually what you see. its not trying to recreate the world, but giving the illusion that you see the world






I understand that, but instead of having the general purpose GameTaskQueue that anything can be passed into and called in OpenGL, rather, when you make a call to do anything that needs to be done in OpenGL it would create an instruction object that would be stuck into the OpenGL queue that would then be invoked on the next update or render (depending on the type of instruction).  From the jME programmer's perspective they would still be doing everything exactly the same.  Internally though, instead of that method they call now that calls directly off to LWJGL it would enqueue an LWJGL instruction and would be picked up on the next update/render and would then be called there instead.  This way you never have to worry about the OpenGL, you simply are passing instructions from jME.

look up ConcurrentLinkedQueue. It is FIFO based and gets round most of that synchronisation .



You just need an action framework where by the queue holds the actions and remove is called on each update method if it is not empty.



You may need to allow one to throttle it, so that it draws a little at a time in the case of a huge scene creation










Can open … worms everywhere !



I seem to have sparked off something here. Sorry about that :slight_smile:



Anyway, it was totally what you guys have been talking about. I extended SimplePassManager to make sure that the OpenGL calls where queued and that solved most of my issues. The only other things were individual calls to the OpenGL queue that had to be queued also.



That said, I've actually switched back to working off of SimpleGame :slight_smile: Sorry darkfrog. I love the StandardGame concept and will return to it in the future, but I just want to get a handle on the OpenGL principles first, without the hassle of having to think about the OpenGL threading.



Thanks for you help on this one







Mak

theprism said:

look up ConcurrentLinkedQueue. It is FIFO based and gets round most of that synchronisation .

You just need an action framework where by the queue holds the actions and remove is called on each update method if it is not empty.

You may need to allow one to throttle it, so that it draws a little at a time in the case of a huge scene creation


That is not the problem...essentially that's what I wrote for GameTaskQueueManager in the first place. :-p  The problem is going through all of jME and creating instruction objects and then changing the whole framework to utilize it.  If you're up to the task I would be happy to help get it into the repository. ;)

Ahh, as in all of the examples ??



Not sure if it all that complex if you keep teh feature as a plug in



Here is what i use, just need a sceneAction interface with one method on it called doAction()



Also - to remove the normal singleton synchronized woes, be sure to call getInstance very early in the game initialisation, as there is a small chance that 2 instances could be created if 2 threads called it before a single instance is created.



Then plug it in with inheritance, just override update() or whatever to make sure that invokeActions is called on each cycle.



private static final ConcurrentLinkedQueue<SceneAction> actionsQueue = new ConcurrentLinkedQueue<SceneAction>();
   

   private static SceneActionStore instance;
       
   
   public static SceneActionStore getInstance() {   
      if(instance == null) instance = new SceneActionStore();
      return instance;
   }
   
   public void addAction(SceneAction action) {
      actionsQueue.add(action);
   }
   
   public void invokeActions() {
      
      while(!actionsQueue.isEmpty()) {         
         actionsQueue.remove().doAction();         
      }
      

   }



Did you also see the work LLama has been doing on the Terra project for tasks ??