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.
Related
I want to create opengl 2d library, where textures as well as windows are encapsulated as objects. Is it possible to create dummy static DC and make it current when loading textures? All of the windows would have same PIXELFORMATDESCRIPTOR as the static one. This way, users of the library would not have to create window prior to loading textures or passing windows as parameters to textures.
Is it possible to create dummy static DC and make it current when loading textures?
Sort of. As long as the visual formats of the device contexts are compatible with each other, you can bind a OpenGL render context created for this visual format to any of these device contexts.
So you can perfectly fine create a window, with a DC that's never shown on the screen (always kept hidden, size of 0×0) and use that for background OpenGL operations. You can also create a secondary OpenGL context, have it share its namespace with the primary context, make it current on the hidden window on a separate worker thread, so that you can asynchronously perform OpenGL operations (like loading textures) while the main context is used for other things.
I need to develop an app using Java wrapper for OpenGL LWJGL.The app will run on remote server in a headless mode.I am trying to understand if and how is it possible taking into consideration the fact that GL context in LWJGL (and in other APis) is created via Java UI elements like Canvas etc.In my case I need to be able to init GL context without creating a window as the drawing targets will be FBOs from which the pixel buffers will render to texture. There is one possible solution though already called PBuffer (I guess pixel buffer) object in LWJGL.It indeed doesn't need GL context created via window as it creates it internally.I don't want to use this method both because it is older concept (and weaker ) than Frame buffer object and because I am using OGL 3.3 -> .So I really don't want to mix with any old pipeline legacy.
I have basically 2 questions:
1.Can I create a context without setting up a window to use for FBO based rendering(headless mode) ?
2.If the answer to the first question is negative ,then can I run on the remote server such an app where the windows is still initialized for the sake of context access ?
UPDATE:
The question can be closed.I tested it via first initialization done with PBuffers to set a context.Then FBO rendering works as supposed.
I found the answer on my own. One should set PBuffer first to create headless GL context. Once it is created we can use FBOs to render frames into images.
We have an OpenGL Application (using Ogre3d and SDL, not directly calling OpenGL) and we are trying to change the Resolution at runtime. It seems that we need to re-initialize our OpenGL context with the new Resolution but a number of items are breaking along the way. On Linux it seems to work for a while, then we get graphical corruption on screen. On Windows it simply crashes the next time we try to render a frame. We have forced the reloading of textures in Ogre, and if we rendering nothing but textures (no 3d models) then this works fine, but any 3d models cause a crash and reloading before rendering them has no effect.
Here is a link to an in depth explanation of Ogre3d calls we are doing: http://www.ogre3d.org/forums/viewtopic.php?f=2&t=62825
All we really need to know is, When re-initializing an Opengl context what resources need to be restored?
Why does adjusting an OpenGL context affect other resources? Is it the way OpenGL works, or did one of the libraries we use introduce this issue? Could we have added this issue without knowing it?
Did you have a look at this forum thread ?
SDL seems to destroy the OpenGL when changing resolution. In this case, all you GL resources are destroyed with the context.
One possible solution would be to create another 'dummy' GL context, sharing resources with you 'real' GL context, and to keep it alive with SDL destroys the 'main' context. This way most of your resources should survive.
Note that some resources can't be shared, textures and VBO are fine, but VAO can't.
OpenGL support was added SDL after its surface code had been established. That's why changing the size of a SDL window is destructive. You were pointed to OpenGL context sharing and its caveats. However I'd avoid the problem alltogether by not using SDL for creating an OpenGL window. You can use all the other facilities SDL provides without a window managed by SDL, so the only thing that would change is input event processing and how the window's created. Instead of SDL I'd use GLFW, which like SDL requires you to implement your own event processing loop, so using GLFW as a drop-in replacement for OpenGL window and context creation is straightforward.
I have built an OpenGL Viewer control that can simply be dropped onto a windows form (at design time) and assigned an OpenGL display list (at run time).
The viewer control handles navigation, display options (e.g. background color), etc. It is also responsible for creating and destroying rendering and device contexts as necessary.
Obviously, each viewer control instance has its own device context, the 'window' where the image is drawn.
Questions:
How should each viewer control instance manage rendering contexts?
Should each instance have it's own context or share a global rendering context?
I'm particularly concerned with how this affects WGL font creation (wglUseFontBitmaps and wglUseFontOutlines), which requires a rendering context (whatever the current context is) and a device context.
Do I need to create each WGL font for each rendering/device context combination?
Perhaps my approach is flawed.
I would go with the context per control approach. You do have to remember that extensions are context based so you'll have to bind them for each one you make (I use glew_MX to handle this).
Also, you can share display lists across contexts (as long as they are on the same gpu) and the wgl font creation creates display lists so you should be fine.
Occassionally I hit places where I'd want to get an OpenGL framebuffer object, but where I'm not interested about opening a window of any kind.
Is it possible to create an opengl context without attaching it to a window of any kind?
Yes! you can use the desktop window as the window passed to OpenGL- as long as you don't try to display anything on it ;)
Just Call GetDesktopWindow and pass the result as an argument when creating new OpenGL window.
http://www.opengl.org/wiki/Creating_an_OpenGL_Context
According to this Web page, WGL_ARB_create_context can be used to create a context without a window. I have not actually tried it myself. I used freeGLUT to create the context and then rendered off-screen to a framebuffer+renderbuffer. I exit the program without ever calling glutMainLoop. It is klugy, but it works for my purposes.
Yes, you can perform off-screen rendering with OpenGL, but the exact way to set it up is dependent on the operating system.
The closest you get to an OS independent way would be to use Mesa 3D, but then your off-screen rendering would not be hw accelerated.