LWJGL Forum

Please login or register.

Login with username, password and session length

Author Topic: GL.createCapabilities() & the Hello World program  (Read 823 times)

Gojira

  • Newbie
  • *
  • Offline Offline
  • Posts: 22
GL.createCapabilities() & the Hello World program
« on: February 23, 2017, 21:52:35 »

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.


Logged

Kai

  • Nerdus Imperius
  • *****
  • Offline Offline
  • Posts: 925
Re: GL.createCapabilities() & the Hello World program
« Reply #1 on: February 23, 2017, 22:08:55 »

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.
Logged

Gojira

  • Newbie
  • *
  • Offline Offline
  • Posts: 22
Re: GL.createCapabilities() & the Hello World program
« Reply #2 on: February 23, 2017, 22:52:23 »

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?
Logged

spasi

  • Administrator
  • Nerdus Imperius
  • *****
  • Offline Offline
  • Posts: 1835
Re: GL.createCapabilities() & the Hello World program
« Reply #3 on: February 24, 2017, 07:45:05 »

glfwMakeContextCurrent() 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).

I 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.

Just 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.
Logged

Gojira

  • Newbie
  • *
  • Offline Offline
  • Posts: 22
Re: GL.createCapabilities() & the Hello World program
« Reply #4 on: March 02, 2017, 23:44:47 »

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.
Logged

spasi

  • Administrator
  • Nerdus Imperius
  • *****
  • Offline Offline
  • Posts: 1835
Re: GL.createCapabilities() & the Hello World program
« Reply #5 on: March 03, 2017, 08:08:37 »

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.

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.
Logged

Gojira

  • Newbie
  • *
  • Offline Offline
  • Posts: 22
Re: GL.createCapabilities() & the Hello World program
« Reply #6 on: March 03, 2017, 17:07:27 »

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.
Logged