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.
Related
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
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.
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.
My program creates many vertex buffer just after startup as soon as vertex data is loaded over a network, and then occasionally deletes or create vertex buffers during hot loop. It works as expected almost always, but sometimes on some machines buffer creation in hot loop produces zero names.
It doesn't look like an invalid state, because it would fire much earlier. Also, documentation and spec is not clear enough about such type of errors. Does it mean that implementation run out of buffer names?
I also found this thread. Topicstarter says that initializing names before passing them to glGenBuffers fixed his problem. Is it necessary to initialize those values?
Since it seems to work on some machines, glGenBuffer returning 0 could be because of an improperly set up context. Here
davek20 had the same problem with glGenBuffers. He solved it by fixing his incorrect context setup.
As stated on here on GLFW 'Getting started' page, under 'Creating a window and context' they state
"If the required minimum version is not supported on the machine, context (and window) creation fails."
and these machines of yours might have correct drivers but probably doesn't support all or some versions of OpenGL, as the documentation states.
If you are using GLFW_CONTEXT_VERSION_MAJOR and GLFW_CONTEXT_VERSION_MINOR consider changing these. I also recommend checking the context creation for returning NULL (0).
Example from GLFW's documentation page:
GLFWwindow* window;
if (!glfwInit())
return -1;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(960, 540, "OpenGL", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
I'm following a tutorial which uses glfwWindowHint() to set the version of GLFW that he is using. He's on OSX and I'm on Windows. I have the exact same code as his. When I do this:
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
And then this:
GLFWwindow* window = glfwCreateWindow(640, 360, "Modern OpenGL", NULL, NULL);
It always returns NULL. But in the tutorial he said that setting the window hints was necessary to use the code that the program uses. When I take out the window hints the window is created sucessfully, but then it crashes (because of the other code that probably required the window hint changes).
I'm on Windows XP. How do I fix this?
Interestingly, this code should always return NULL on OSX, as OSX supports OpenGL >=3 only in core profiles, while this code requests a compatibility profile.
On Windows, a compatibility profile of that version might be supported. But this will depend on the GPU and the drivers you have installed. It might very well be the case that your system does simply not support GL3.2. Make sure you are using recent drivers. And check what GL version your GPU actually supports. One thing you could try though is setting the GLFW_OPENGL_FORWARD_COMPAT hint to GL_FALSE.