Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shared Context Between Multiple Windows? #845

Open
robin-read opened this issue Mar 14, 2023 · 2 comments
Open

Shared Context Between Multiple Windows? #845

robin-read opened this issue Mar 14, 2023 · 2 comments

Comments

@robin-read
Copy link

Hi Folks,

I need a bit of help. I'd like to be able to open two windows and have them share the same GLContext so that I can load some Textures and render these in both windows.

I'm not sure how to go about doing this. Any help welcome!

Thanks!

@stevenlovegrove
Copy link
Owner

OpenGL can actually share resources like textures across contexts - you just have to construct the context that way. I'd recommend this based on your description. Pangolin actually does this automatically with X11, but it hasn't been implemented for other platforms.

See https://github.com/stevenlovegrove/Pangolin/blob/master/components/pango_windowing/src/display_x11.cpp#L492 where global_gl_context is the first context created and the one shared when creating other contexts. If you need it for other platforms, it should be possible on Windows, but MacOS can be trickier due to some GUI thread restrictions it enforces.

@robin-read
Copy link
Author

robin-read commented Apr 12, 2023

Thanks for the reply. I've continued to tinker around but am still struggling. I've put together a bare-bones example of what I'm trying to do. Clearly I'm going wrong but can't really tell.

#include <pangolin/display/display.h>
#include <pangolin/display/view.h>
#include <pangolin/handler/handler.h>
#include <pangolin/gl/gldraw.h>

void render(const std::string &contextName,
            pangolin::WindowInterface &window,
            pangolin::View &view,
            pangolin::GlTexture &texture)
{
    window.MakeCurrent();
    pangolin::BindToContext(contextName);
    view.Activate();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);

    if (!texture.IsValid())
    {
        throw std::runtime_error("Texture is not valid!");
    }

    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
    texture.RenderToViewport();

    pangolin::FinishFrame();
    window.RemoveCurrent();
}

int main(int argc, char *argv[])
{
    // Setup the first Window
    pangolin::WindowInterface &window1 = pangolin::CreateWindowAndBind("First", 640, 480);
    pangolin::OpenGlRenderState s_cam1(pangolin::ProjectionMatrix(640, 480, 420, 420, 320, 240, 0.2, 100),
                                       pangolin::ModelViewLookAt(-2, 2, -2, 0, 0, 0, pangolin::AxisY));
    pangolin::View &d_cam1 = pangolin::CreateDisplay().SetBounds(0.0, 1.0, 0.0, 1.0, -640.0f / 480.0f);

    // Setup the second Window
    pangolin::WindowInterface &window2 = pangolin::CreateWindowAndBind("Second", 640, 480);
    pangolin::OpenGlRenderState s_cam2(pangolin::ProjectionMatrix(640, 480, 420, 420, 320, 240, 0.2, 100),
                                       pangolin::ModelViewLookAt(-2, 2, -2, 0, 0, 0, pangolin::AxisY));
    pangolin::View &d_cam2 = pangolin::CreateDisplay().SetBounds(0.0, 1.0, 0.0, 1.0, -640.0f / 480.0f);

    // Load the texture, this is sensitive to which window it is created after.
    pangolin::GlTexture texture;
    texture.LoadFromFile("/home/host_user/Desktop/arrow.png");

    while (!pangolin::ShouldQuit())
    {
        render("First", window1, d_cam1, texture);
        render("Second", window2, d_cam2, texture);
    }

    return 0;
}

The result I get is below:

Texture Screenshot

What I've noticed is that if I move where I load the Texture (e.g. before or after creating window2) the result of the rendering flips (e.g. "First" has the correct texture and "Second" shows a white texture). Moreover, if I create a texture for each window and pass the respective texture to the render() function all works well. However I'd like to load the texture only once and use to render the texture in each window.

// Create window1...
 pangolin::GlTexture texture1;
 texture1.LoadFromFile("/home/host_user/Desktop/arrow.png");

// Create window2...
 pangolin::GlTexture texture2;
 texture2.LoadFromFile("/home/host_user/Desktop/arrow.png");

while (!pangolin::ShouldQuit())
{
    render("First", window1, d_cam1, texture1);
    render("Second", window2, d_cam2, texture2);
}

Am I trying to do something that's not possible or am I missing something? Also, I'm on v0.8 on Ubuntu 22.04.

Thanks!

P.S. I'm very new to OpenGL, so probably missing some core knowledge too!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants