4

So when I got to grips with the java

paint(Graphics g){}

method I moved on to creating my own render methods but I had to learn about buffer strategies and how to 'get' Graphics

So now I am learning openGL, I have got to grips with the method:

@Override
public void display(GLAutoDrawable arg0){}

and now I would like to create my own render methods, so far I have constantly run up against one exception:

Exception in thread "main" javax.media.opengl.GLException: No OpenGL context current on this thread

EDIT: Question: If I want to make glDraw calls outside of the

@Override
public void display(GLAutoDrawable arg0){}

method, how do I ensure the glContext of my GLCanvas is "current"

Preferably as a code example, as I Have looked through the api's and used google extensivly, many links you guys have already been so kind as to put here I have already found before and I am still drawing a blank... literally! Closest I've got was when it didn't throw a "no current context" exception but the screen just went black permenantly!

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Troyseph
  • 4,960
  • 3
  • 38
  • 61
  • You don't GET a current context, you MAKE a existing context current. – datenwolf Sep 14 '11 at 18:49
  • @datenwolf Ok so thats great, but how? I assume its a single liner, but I can't find anything useful with google, could you possibly show me a link to a tutorial or send me the code on here? That would be a great help thanks – Troyseph Sep 14 '11 at 22:03
  • I never used JOGL so far, but with just 3 minutes of browsing its API docs I found that there is a function `GLContext.makeCurrent` and that `GLCanvas.getContext` returns a `GLContext` instance. http://jogamp.org/deployment/jogamp-next/javadoc/jogl/javadoc/javax/media/opengl/GLContext.html#makeCurrent() – datenwolf Sep 14 '11 at 22:29
  • 1
    Not sure if this is an answer myself yet, but I'm looking into NEWT from JOGL 2, among other things, that should let us do just that... And we can even use it with AWT apparently: http://jausoft.com/blog/2010/11/28/newt-threading-overview/ – Samuel Audet Sep 17 '11 at 09:44

3 Answers3

3

Duplicating my answer to your other question:

Odd as it may seem, this is the way it is supposed to work.

Behind the scenes what is going on is that when the GLCanvas you have created comes to be drawn, behind the scenes JOGL is doing a whole pile of work. It is creating a GLContext, and making it current for the GLCanvas for the current thread. Only when that is done can you make rendering calls. A GLContext that has not been made current, or a GL object that derives from it, is no use to you.

Almost all JOGL applications work that way. You create a GLEventListener, and implement display() in it, extract a GL from the GLAutoDrawable and use it to make rendering calls. You don't want to make rendering calls in any other place, any more than you want to make Graphics2D calls outside of the paint() method. (You can of course write submethods that are called from the display() method, and which take the GL or GLAutoDrawable as an argument).

There are ways for you to specifically create a GLContext and make it current yourself, but they are rarely necessary. It is almost always better to use the approach here.

If you are using low-level buffers, like BufferStrategy, your best bet is to do your JOGL rendering to a GLPBuffer, which is an offscreen JOGL drawable. Create the GLPBuffer, render to it, and then copy the rendered bitmap into your buffer. Some implementations of GLDrawable allow for explicit creation of offscreen drawables with "createOffscreenDrawable(...). This article will give you some pointers.

You can also call GLDrawable.display() explicitly, provided you are on the rendering thread.

If you are looking to do initialization, such as creating a display list, you can use the GLDrawable.init(...) method, which is called before the first call to display(...), although it can be called more than once.

DJClayworth
  • 26,349
  • 9
  • 53
  • 79
  • What??? I never use the paint method, or repaint method, I always create my own render method like so 'private void render() { BufferStrategy bs = getBufferStrategy(); if (bs == null) { createBufferStrategy(2); bs = getBufferStrategy(); } if (bs != null) { Graphics g = bs.getDrawGraphics(); }' Then I pass the Graphics onto whichever class is currently rendering, e.g. my mainMenu class or helpScreen class, I can't do that with the display() method in OpenGL, well I don't know how to at any rate, not in the same way I'd do it with Graphics – Troyseph Sep 15 '11 at 22:12
  • Ok I don't think we are on the same page here I'm being really unclear my bad, Here's what I'm trying to do: Before my loop starts I want to create a display List, then start the loop and call the display() method each loop to display it, However I cannot create my display list unless it is inside the display() method, in which case it would then get called every loop when I call display() again, which is bad! So I would like to create another method in which I can create my display list, but it doesn't work because my best attempts to make the context 'current' have failed. – Troyseph Sep 16 '11 at 15:55
  • My comment before was just me being surprised that you used java's own paint method, and considered creating your own render method to be silly/pointless! I don't want to use low level buffers, just make the context of my GLCanvas current so I can draw to it with GL – Troyseph Sep 16 '11 at 15:57
  • @Sebastian Troy: If your worries are about display list creation and the like: At the beginning of your display function add a "if(initialiazed == false){one_time_initialization(); initialized = true;}" and do display list creation and the rest in one_time_initialization(). – datenwolf Sep 16 '11 at 17:19
  • @Sebastian I've edited the answer to reflect this. You might want to edit the question to be more explicit about what you are looking for. – DJClayworth Sep 16 '11 at 17:51
  • @datenwolf I may want to make a bunch of display lists and be able to re calculate a specific one, so I would be checking about 20 or 30 different booleans each tick, which would be a waste of processing power, hence if I could create a method createDisplayList(int listToReDraw){} it would save on processing power – Troyseph Sep 16 '11 at 19:02
  • 2
    Checking 20 to 30 booleans really isn't so much of a problem, trust me. – datenwolf Sep 17 '11 at 19:49
3

I found documentation discussing this issue here:

http://fivedots.coe.psu.ac.th/~ad/jg2/ch15/index.html

The GLContext.makeCurrent()/release() hack seems to work for me under Linux/OpenJDK 6/JOGL 2, but we will see... in particular, making the OpenGL context switch thread all the time like that will incur (too much?) overhead.

Then there is NEWT of JOGL 2 and LWJGL's toolkit, but they seem to be a whole new ball of wax to handle, bye bye Swing. :(

Samuel Audet
  • 4,964
  • 1
  • 26
  • 33
  • Great Link, thank you, I know I'll be able to get my teeth into this :D but it could take a long while! So my apologies if I don't except an answer or finalise answering this question for a the time being! – Troyseph Sep 17 '11 at 23:41
  • BTW, I dug a bit more into the subject, and it appears the safe way to do what we want would be to call Threading.invokeOnOpenGLThread(), which does something similar to EventQueue.invokeAndWait()/invokeLater(), but on the thread used for OpenGL rendering. This however does not solve my problem, since I need something with very low overhead. I suppose creating a PBuffer with shared context would be the best portable way of doing that... – Samuel Audet Sep 18 '11 at 04:23
0

Dont ask me why, but for me (after so many attempts) this is working like a charm

I declared as variable

private GLCanvas gLCanvas;

and then just a

gLCanvas.repaint();

Did the job ;)

elect
  • 6,765
  • 10
  • 53
  • 119