Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (107)
games submitted by our members
Games in WIP (535)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Using the same Display/Keyboard/etc. in multiple threads  (Read 1624 times)
0 Members and 1 Guest are viewing this topic.
Offline cd

Junior Newbie





« Posted 2005-06-30 12:54:20 »

Hi.

First of all, thank you for putting together LWJGL; it's just what I've been looking for and works perfectly. It's really saved my project.

However, I'm having a little trouble getting to grips with something. Basically my situation is this: I want to create the Display and Keyboard (and probably other LWJGL objects in the future) in one thread, but I wish to have access to the same objects in other threads. For example, one thread will be making heavy use of Display and one will be making heavy use of Keyboard.

Last night I became very confused by all of this; if I jumped straight into the 'run' method of my Display-using Thread object, it would work perfectly, however using the 'start' method to begin a new thread caused a severe Null Pointer Exception when using Display.update. I decided to download the LWJGL code and dig around to find out exactly what happens at Display.update -- eventually I discovered that there has been quite a bit of effort put in so that different threads can own different rendering contexts; exactly what I didn't want to happen! Cheesy

In an attempt to amend this, as soon as the Display object was created, I stored the Context (through Display.getContext()) into a static object. On entering a different thread, I then used GLContext.useContext(), passing the stored Context object. This seemed to get rid of the Null Pointer Exception, which was nice, but now introduced a different error. On calling Display.update(), it now causes an "Invalid Operation 1282" error in glGetError(). After searching around on Google, I took some advice on this message board of placing Util.checkGLError() around the place. Even putting it immediately before the call to Display.update() didn't find any errors though, so this has left me even more puzzled.

At the end of it, I decided that this method that I was using to evade the thread-local GLContext wasn't the right way to go. So could anybody recommend a sensible method of acheiving what I want to acheive? In short, I want to be able to access exactly the same Display/Keyboard/etc. object from any of the threads in my program.
Offline cd

Junior Newbie





« Reply #1 - Posted 2005-06-30 14:01:49 »

I've just run some more tests and there is a slight inaccuracy in my previous post; the OpenGL "Invalid operation (1282)" error occurs any time after I try to switch the context in the new thread.

Here is the code where I save the current context in the main thread:

1  
OpenGL.setContext(Display.getContext());


Where this 'OpenGL' context just basically holds an Object and returns it when it's asked; this is the object that grabs hold of the context and passes it between threads.

When the new thread begins, here is the code that restores the context:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
   public void run()
   {
      // First thing to do is to tell OpenGL to use the same
     // rendering context as the main thread.
     try
      {
         GLContext.useContext(OpenGL.getContext());
      }
      catch(LWJGLException ex)
      {
         finished = true;
         return;
      }
     
      Util.checkGLError();


Calling Util.checkGLError() immediately before starting the new thread produces no OpenGL errors. After the thread is created, no OpenGL or Display-modifying functions are called in the main thread, so this is not the source of the errors (I've checked thoroughly with Util.checkGLError()). However, as soon as I set the OpenGL context with the above code, this is where the OpenGL error starts appearing.

[EDIT]
I'm very sorry to keep messing around like this, but I seem to be more awake than I was at 4:30 last night when I came up with the idea of what was going wrong. I have just been experimenting even more and discovered this:

1) The Display -is- accessible through all Threads, so sorry about the subject of this thread. I hadn't tested it correctly.
2) I've discovered exactly which part of the program is going wrong: here is more info...

From the stack trace, the origin of the null pointer exception is in GL11.java on line 1839:

1  
long function_pointer = GLContext.getCapabilities().GL11_glGetError_pointer;


So to test out the exception and get things clear, I have changed my thread entry point code to this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
   public void run()
   {
      try { Keyboard.create(); }
      catch(LWJGLException ex) { ex.printStackTrace(); }
           
      if(GLContext.getCapabilities() == null)
         System.out.println("it was null.");
     
      Util.checkGLError();


Display.create() was called in a different thread (the Display -has- been created upon entering the thread with the code shown above). Inside the thread where Display.create() was called, GLContext.getCapabilities() is not null.

Now, I think I have discovered exactly what I am trying to do (so sorry once again for changing my mind about the problem so many times): I need to be able to access the same GL context throughout all of my threads, rather than each Thread keeping its own copy. If my understanding is correct, the GLContext object is thread local, so each time a new Thread accesses the GLContext.getCapabilities() method, the capabilities created inside that thread are returned. In my case, I'm calling GLContext.getCapabilities (implicitly through Util.checkGLError()) inside a thread which has -not- (and cannot) call Display.create().

So, now I believe the clear question that I am asking is this: how can I maintain the same GLContext throughout all Threads? I have a feeling that doing something similar to this is an incorrect way of going about it:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
   public void run()
   {
      try
      {
         GLContext.useContext(Display.getContext());
      }
      catch(LWJGLException ex)
      {
         ex.printStackTrace();
      }
           
      if(GLContext.getCapabilities() == null)
         System.out.println("it was null.");
     
      Util.checkGLError();


While using this line of code, it does stop the null pointer exceptions (and the test for GLContext.getCapabilities() is now -not- null), I end up receiving this error when calling Util.checkGLError(): "Exception in thread "Thread-0" org.lwjgl.opengl.OpenGLException: Invalid operation (1282) at org.lwjgl.opengl.Util.checkGLError(Util.java:56)".

Hopefully I've now got my question clear; once again, sorry for the lack of clarity in my previous posts.

[/EDIT]
Offline Matzon

JGO Knight


Medals: 19
Projects: 1


I'm gonna wring your pants!


« Reply #2 - Posted 2005-06-30 14:25:14 »

LWJGL is intended to be used in single threaded mode - the may or may not be issues related to multithread access.
That said, you might want to call Display.makeCurrent();

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline cd

Junior Newbie





« Reply #3 - Posted 2005-06-30 14:38:34 »

Hi Matzon.

I tried modifying my new thread to this:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
   public void run()
   {
      try
      {
         Display.makeCurrent();
      }
      catch(LWJGLException ex)
      {
         ex.printStackTrace();
      }
           
      if(GLContext.getCapabilities() == null)
         System.out.println("it was null.");
     
      Util.checkGLError();


The stack trace produced by the makeCurrent() call is this:

Quote
Exception in thread "Thread-0" java.lang.IllegalStateException: From thread Thread[Thread-0,5,main]: Thread[main,5,main] already has the context current
   at org.lwjgl.opengl.Context.checkAccess(Context.java:169)
   at org.lwjgl.opengl.Context.makeCurrent(Context.java:176)
   at org.lwjgl.opengl.Display.makeCurrent(Display.java:576)

Note: My previous post has been edited; I didn't see your response until I applied the changes to it. Maybe the changes in that previous post can help shed some more light on this?
Offline tom
« Reply #4 - Posted 2005-06-30 16:55:23 »

Why do you need to access the context from different threads? It's usually better to let only one thread interact with OpenGL. Other threads can queue up their commands that is proccessed in the worker thread.

Offline cd

Junior Newbie





« Reply #5 - Posted 2005-06-30 18:21:40 »

Originally, we had different subsystems in different threads - for example, the input subsystem would be in one thread, rendering subsystem in another, etc.

I looked through the code relevant to what I was trying to acheive and decided that maybe it would just be best to go with the one-thread approach. I'm currently in the middle of converting  the engine components to work in a single-threaded environment and it's coming along very well. Now I will be able to continue moving completely from Java2D to LWJGL.

Cheers for the suggestions and help. Keep up the excellent work on LWJGL.


Regards,
Chris.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

pw (36 views)
2014-07-24 01:59:36

Riven (37 views)
2014-07-23 21:16:32

Riven (24 views)
2014-07-23 21:07:15

Riven (27 views)
2014-07-23 20:56:16

ctomni231 (56 views)
2014-07-18 06:55:21

Zero Volt (49 views)
2014-07-17 23:47:54

danieldean (39 views)
2014-07-17 23:41:23

MustardPeter (43 views)
2014-07-16 23:30:00

Cero (59 views)
2014-07-16 00:42:17

Riven (56 views)
2014-07-14 18:02:53
HotSpot Options
by dleskov
2014-07-08 03:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 00:47:22

How do I start Java Game Development?
by ra4king
2014-05-17 11:13:37

HotSpot Options
by Roquen
2014-05-15 09:59:54

HotSpot Options
by Roquen
2014-05-06 15:03:10

Escape Analysis
by Roquen
2014-04-29 22:16:43

Experimental Toys
by Roquen
2014-04-28 13:24:22
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!