External context ?

Started by jpgygax68, June 20, 2008, 16:34:28

Previous topic - Next topic

jpgygax68

Hi!

I'm desperately trying to find a way to do OpenGL in Java. I've looked at both JOGL, gl4java, and now LWJGL, but I can't find a way to do the following, very simple thing: use an external context.

You see, I'm developing DLLs for an OpenGL-based simulator application. These DLLs make the application modular (it has started out being pretty monolithic). One of my DLLs is responsible for creating OpenGL windows (full-screen and otherwise). Because I've started to use Java to create test programs for my DLLs, I now need to be able to draw a few things in the contexts that my DLL is creating, just to see if they behave.

Unfortunately, LWJGL refuses to draw anything before I've called Display.create(), which creates a context I do not want or need.

How can I use LWJGL as a direct OpenGL binding ? In other words, how can make it use a context that it has not created itself ?

Thanks for any help on this one!

wolf_m

I would guess you'd have to call GLContext.useContext(Object).

The context has to implement at least the basic GL11 functions, apparently.

dronus

I think that would be hard..  as lwjgl hides away the contexts pointer. If you create an external context, you have to pass it to lwjgls world, which is currently not possible i think. If you load your dll by JNA or JNI you can obtain some Pointer object wrapping the c pointer, which then could be passed to a modified lwjgl to a function you have to implement.. which takes the Pointer and just take it als lwjgl's context pointer.

jpgygax68

Quote from: wolf_m on June 20, 2008, 16:43:54
I would guess you'd have to call GLContext.useContext(Object).

The context has to implement at least the basic GL11 functions, apparently.
Thanks! I use JNA to bind my DLL. Do you think I could just cast Windows' HGLRC to Pointer, then to Object, and pass that to GLContext.useContext() ?

wolf_m

I think you should get on the #lwjgl IRC channel on freenode to get some real help.

dronus

Quote from: jpgygax68 on June 20, 2008, 22:25:15Thanks! I use JNA to bind my DLL. Do you think I could just cast Windows' HGLRC to Pointer, then to Object, and pass that to GLContext.useContext() ?
No, i don't think so. the Object in use by useContext() is merely a kind of "token" that is used to identify one context uiniquely. It has nothing to do with a pointer (a java object in the virtual machine has no address in the c sense).
What you need is an lwjgl function that sets the context by a real memory address. Such one doesn't exist as far as i know. So i think you need to get the lwgjl sources, add one function that set lwjgls internat context pointer, and build it. pretty hard work.

wolf_m

I think he's solved it already, but doesn't post the solution here for some reason... IRC log:
[15:37:15] <gygax> perhaps I should just try to feed it a HGLRC
[15:37:28] <elias_naur> nah
[15:37:43] <wolf_m> as I said, my guess is you should write a wrapper around your native code and feed that into it
[15:37:52] <elias_naur> the parameter is only used to cache function pointers
[15:38:01] <gygax> thanks Elias
[15:38:19] <gygax> that doesn't make my job easier :-)
[15:38:27] <elias_naur> lwjgl has a map of handle->function_pointers
[15:38:41] <elias_naur> so if you pass an existing handle to useContext, a lot of work will be saved
[15:38:56] <elias_naur> what's important is that the relevant context is current when useContext is called
[15:39:26] <gygax> so is there a way to get a "blank" map and initialize it with my externally-created GL context ?
[15:40:52] <elias_naur> sure, just make the external context current and call GLContext.useContext(object_representing_the_context)
[15:41:11] <elias_naur> make sure you hold on to the object, since the map is weak
[15:41:46] <gygax> hold on - I'm not quite following yet
[15:41:59] <gygax> where do I get object_representing_the_context from ?
[15:42:10] <elias_naur> anywhere, a "new Object()" will do fine
[15:42:11] <Evil[1]> just make an: Object context = new Object();
[15:42:14] <Evil[1]> hahaha
[15:42:22] <gygax> that was evil
[15:42:23] <elias_naur> as long as it isn't garbage collected before you're done with the context
[15:43:08] <Evil[1]> it's just a "marker" for your context if you want to see it this way.
[15:43:16] <gygax> ahaaa
[15:43:24] <gygax> hey, that would be real easy
[15:43:43] <Evil[1]> if you want to use it, just make your context current and call useContext...
[15:43:47] <elias_naur> the reason that new Object() is enough is because OpenGL state is global to the current thread
[15:43:52] <Evil[1]> .oO(hopefully this is right)
[15:44:15] <gygax> let me try this and come back in, like, 15 minutes
[15:44:18] <elias_naur> the HGLRC is only used with wgl
[15:44:19] <gygax> thanks!
[15:44:35] <wolf_m> so I was wrong all along.. Good thing you came here gygax
[15:44:41] <gygax> :-)

[...]

[15:58:55] <gygax> well I'll be
[15:59:06] <gygax> it worked!
[15:59:12] <wolf_m> congrats :)
[15:59:19] <gygax> no, congrats to you guys
[15:59:19] <Evil[1]> hehehe.
[15:59:44] <wolf_m> post your findings on the forums to provide a shortcut for others

That's where he left yesterday  :-\

jpgygax68

Thank you wolf_m! I'm ashamed of myself, I just realized I was being a bad netizen to leave this question hanging out there unanswered...

For anyone interested, here's the solution, provided by most helpful member Evil. Every time before using a context created outside of lwjgl, you must insert a call like this one:

GLContext.useContext(myTrackingObject);

, where myTrackingObject is simply an instance of Object, created by your own code. As Evil explained, that Object serves as a kind of "mark" for the GL context, a place for lwjgl where to put status information that needs to be associated with that context.

So, if you are using several contexts (as I do), you will of course need several of these tracking objects. useContext() must be called right after whatever code you use to actually switch to a new GL context.

A suggestion for the lwjgl makers: wouldn't it be more intuitive to define a dedicated class for this task, or maybe create a factory method ?

dronus

But this doesn't is a solution to your questinon? I thought you like to use a externally created context only the pointer is known.

jpgygax68

Quote from: dronus on June 25, 2008, 23:37:25
But this doesn't is a solution to your questinon? I thought you like to use a externally created context only the pointer is known.

Yes, it does solve the problem, because my external DLL not only creates the GL contexts, it can also make them current (through a call to wglMakeCurrent()). All I needed was a way to make lwjgl accept my contexts.