Search code examples
c++unity-game-engineopengltextures

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!


Solution

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