GLFW multiple windows multiple threads OpenGL and Vulkan mix - glfw

Qustion about GLFW
I have a program that has windows in OpenGL and one window with Vulkan.
When creating the Vulkan window I set
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
when I create OpenGL
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
My problem is after I create the Vulkan window I cannot create any other new windows. If I call glfwCreateWindow it does not work.
Glfw Error 65546: The specified window has no context
(I found this as a problem when working with ImGUI and multiple Viewports. that creates new window when dragging out of main window)
The creation on windows are on different threads.
How come one effects the others, and how to restore functionality to get the OpenGL Context back. so I can create more windows?
I am missing something here.
Thanks.

Before creating the OpenGL window, you must set the client API to OpenGL again via:
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API);
so that GLFW also creates an OpenGL context (and not only the window).
The default of this setting is GLFW_OPENGL_API, but when you explicitly disable OpenGL context creation for Vulkan via glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); you must reenable OpenGL context creation back for the OpenGL window.
See: https://www.glfw.org/docs/3.3/window_guide.html#GLFW_CLIENT_API_hint

Related

Using multiple threads in OpenGL and SDL

I am trying to move some of my rendering in OpenGL and some other calculations to a second thread. The problems start when I do anything related to OpenGL.
I have read that one OpenGL context can only be used by one thread.
I'm creating my context using this command from OpenGL:
SDL_GLContext context = SDL_GL_CreateContext(window);
How can I generate a second context for the same window? And can I use multiple contexts on one window?

Is there a way to change the number of MSAA samples of an existing GLFW window?

I am currently writing a game using C++, OpenGL and GLFW. I would like to allow users to change the number of samples the game uses for antialiasing, since users with old systems might want to disable antialising altogether for performance reasons.
The problem is that GLFW_SAMPLES is a window-creation hint, which means that it's applied when a window is created:
// Use 4 samples for antialiasing
glfwWindowHint(GLFW_SAMPLES, 4);
// The hint above is applied to the window that's created below
GLFWwindow* myWindow = glfwCreateWindow(widthInPix, heightInPix, title.c_str(), glfwGetPrimaryMonitor(), nullptr);
// Disable antialiasing
// This hint is not applied to the previously created window
glfwWindowHint(GLFW_SAMPLES, 4);
The GLFW documentation doesn't contain any information about how to change the number of samples of an existing window. Has anyone faced this problem in the past?
No, you must create a new window and destroy the old one. Preferably sharing the two contexts, so that non-container objects won't be lost in the shuffle.
Alternatively, you can create multisampled textures or renderbuffers, render to an FBO, and then blit the rendered data to a non-multisampled window. That way, you have complete control over the number of samples, and you can easily destroy and recreate such images at your leisure.

GLFW | What is a context?

I am trying to understand what's GLFW_CONTEXT_VERSION_MAJOR and GLFW_CONTEXT_VERSION_MINOR. And what exactly those functions do:
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
And it seems to me that first of all I must find out what is context. Documentation explanation looks too complicated and doesn't even give its definition, so I can't understand what it is and what's its purpose.
It states in the first sentence with the headline Context objects: "A window object encapsulates both a top-level window and an OpenGL or OpenGL ES context."
So it will be an OpenGL/OpenGL ES context. The functions set the OpenGL/OpenGL ES version requirement for that context the window will create when you create the window.
In your example above GLFW will try to create an OpenGL 3.3 context for that window.

How to Get Unity Context into OpenGL Window

I want to get the unity context into opengl so I can display a unity render texture in an opengl glfw window. I tried using
oldContext = glfwGetCurrentContext(); but the value of oldContext is just null.
I am trying to use the low-level native unity plugin and Texture.GetNativeTexturePtr
Any help would be greatly appreciated!
OpenGL context cannot be queried like OpenGL state related objects via some glGet* API.Context is not part of OpenGL API,it is a part of the system you're running on and it exists to allow you maintaining of OpenGL state and issue command to the driver. You must access a system specific handle that points to the context via system specific API.On Windows (WinGDI)that's would be
HGLRC wglGetCurrentContext();
On linux see related GLX API. You need to find functions to access GLXContext
I did it once in Unity3D (framebuffer readout plugin). But it used Unity's OpenGL or DirectX context to issue API commands only.
Also,I am not sure you can 'inject' or share a context for a window that doesn't own that context. You see, when you (or Unity) init display it creates context and related GL resources,like the default FBO with all required attachments on its own,and that FBO is mapped to some system resource(device) which takes actually care of presenting those pixels on the screen. Therefore, I am not sure display context can be moved from Window to Window in the same manner that a context can be shared between threads.(But I can be wrong on this one)
You can create your plugin Window on some thread,with its own GL context. Then create and share a texture object between those two. Remember, GL textures are shareable. If you copy contents from Unity's screen FBO into that texture,then you can copy it into your plugin's screen FBO from that texture as well.
Btw,look at this SO question .You can see there vendor specific GL extensions which allow copying data into texture from different contexts without requiring shared context,share lists setup.
Regarding why GLFW returns you nullptr. In your example you use GLFW library.
glfwGetCurrentContext()
But if you look at the source code,you see this:
GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return _glfwPlatformGetTls(&_glfw.contextSlot);
}
Which probably means that it retrieves a pointer to GLFWWindow from its own cache and not from the system.And if you didn't create that context via GLFW,you won't get any valid pointer. So try working directly with your system related API as explained above.

How to make an existing X11 window OpenGL ready?

I can't seem to find an example of creating an OpenGL context off of an existing X11 Window. Every example I find creates a window that is already OpenGL ready by providing the necessary visual attributes (via glXChooseVisual or glXChooseFBConfig). What if I already have an existing window (referenced via Display* and Window) and want to change the Colormap and XVisualInfo for the Window for OpenGL rendering? Think ChoosePixelFormat and SetPixelFormat on Windows when creating an OpenGL context. Is this even possible in X11? Do I have to create a Window that's already ready for OpenGL?