GL.createCapabilities() & the Hello World program

Started by Gojira, February 23, 2017, 21:52:35

Previous topic - Next topic

Gojira

GL.createCapabilities() is throwing me for a loop.

According to the documentation, GL.createCapabilities() must be called before any GL functions.  But the Hello World program on the main page doesn't do that.  It calls quite a few GLFW functions before it calls GL.createCapabilities().

https://www.lwjgl.org/guide

And if I move the call to GL.createCapabilities() from loop() to init(), where the program actually starts, the Hello World program throws an error at me.  I don't understand why making the context earlier would create an error.



Kai

The documentation is correct, and so is the HelloWorld example on the Getting Started page.

Your assumption that calling GLFW functions means "calling GL functions" is not correct.

Methods on the GLFW class, such as glfwWindowHint() and glfwCreateWindow() and even glfwMakeContextCurrent() are neither OpenGL functions nor do they at any point call OpenGL functions internally.
They are used to create a window and with it an OpenGL context.
(Btw. whenever you see "GL functions" in the context of OpenGL/GLFW/LWJGL, that "GL" usually means "OpenGL")
That means, the OpenGL context is actually being created by the glfwCreateWindow() method internally. In order to use OpenGL functions for this context, that context must be made "current" in the executing thread by calling glfwMakeContextCurrent().
The OpenGL context is now both created and current in the executing thread.

In order for LWJGL to actually know about the OpenGL context and initialize itself using that context, we have to call GL.createCapabilities().
It is only after that call that we can call OpenGL functions via methods on those GLxx and extension classes living in the org.lwjgl.opengl package.

Gojira

So let me see if I have this straight.

glfwMakeContextCurrent() makes the "context" current, and then GL.createCapabilities() binds that context to the LWJGL and the OpenGL library?  I can call GL.createCapabilities() anytime after glfwMakeContextCurrent() and it will work?

Just curious: how is this context passed since the GL.createCapabilities() method doesn't take any parameters?

spasi

Quote from: Gojira on February 23, 2017, 22:52:23glfwMakeContextCurrent() makes the "context" current, and then GL.createCapabilities() binds that context to the LWJGL and the OpenGL library?

There is no context handle stored somewhere in LWJGL. The call to GL.createCapabilities() retrieves the OpenGL function pointers that correspond to the context that is current in the current thread and also populates the capability flags (which core versions and extensions are supported). This information is stored in a GLCapabilities object, which is then stored in thread-local storage. If there are multiple contexts made current in the same thread, the GL.setCapabilities() method can be called to reuse an existing GLCapabilities instance.

When and how the context is actually made current, is managed externally. GLFW does it own context management and so do other libraries. You can do your own context creation and management in LWJGL, but you have to use OS-specific APIs (i.e. CGL, GLX, WGL, EGL).

Quote from: Gojira on February 23, 2017, 22:52:23I can call GL.createCapabilities() anytime after glfwMakeContextCurrent() and it will work?

Yes. You can call GL.createCapabilities() anytime you know there is an OpenGL context current in the current thread.

Quote from: Gojira on February 23, 2017, 22:52:23Just curious: how is this context passed since the GL.createCapabilities() method doesn't take any parameters?

LWJGL uses the OS-specific APIs mentioned above to retrieve the current context from the current thread and query its capabilities.

Gojira

OK, this is similar to what I was thinking (I think), but it uses "thread local" instead of global variables.  Thanks for taking the time to explain this.

Can I ask what those OS-specific call are that you referred to?  Let's say for example Windows 64 bit w/ OpenGL and GLFW, since that's what I'm using at the moment.  I would have thought that LWJGL was making OpenGL calls or maybe GLFW calls to get the context, so I'm wondering what is OS specific that needs to be accessed.

spasi

Quote from: Gojira on March 02, 2017, 23:44:47Can I ask what those OS-specific call are that you referred to?  Let's say for example Windows 64 bit w/ OpenGL and GLFW, since that's what I'm using at the moment.

WGL is the API that manages OpenGL contexts on Windows. Look for functions with the "wgl" prefix in the GL class (e.g. wglGetProcAddress and wglGetCurrentDC).

Note that this is bootstrapping code so some functions are called manually (using the function addresses and org.lwjgl.system.JNI) instead of via the generated bindings.

Gojira

Awesome.  That will give me something to poke at and learn.  I'm mostly a Java programmer, I don't know much Microsoft API.  Thanks again for the info.