openFrameworks openGL context

This is a followup to my post in this thread

I am trying to work with openCL with its option to interop with OpenGL. In projects where I have my own abstraction classes for OpenGL (with GLFW), get the OpenGL context this way

cl_context_properties properties[] = {
        CL_GL_CONTEXT_KHR, (cl_context_properties)glXGetCurrentContext(),
        CL_GLX_DISPLAY_KHR, (cl_context_properties)glXGetCurrentDisplay(),
        CL_CONTEXT_PLATFORM, (cl_context_properties)m_Platform(), 0
    };

But this does not work in OpenFrameworks. I dont know the best way to get the context.

So far instead of glXGetCurrentContext() I have tried ofGetGLXContext() and ofGetWindowPtr()->getGLXContext() and they both dont seem to work.

Could someone please help me with the correct function to access the GL context created by OF?

are you using more than a single window?

No just the one regular window. Which is why its confusing, does ofGetWindowPtr() not point to the current AppRunner’s window?

Hey @DarkSalmon apologies for the forceful tagging, But I see you have given excellent advice in this topic regarding sharing oF Glfw context.

Would you please share any thoughts on this issue?

Hey @hypermodernist,

That’s fine, what kind of issues / errors do you see ?

For sharing OpenGL contexts with another thread using glfw the infs provided in the aforementioned post - as well as the linked github issue - should suffice :

/* Custom method to create GL context for graphics processing free from OF. */
shared_ptr<ofAppBaseWindow> createContext(const ofWindowSettings & _settings) {
  ofGLFWWindowSettings settings(_settings);

  // When used for graphics only we can discard presenting parameters.
  settings.title = "";
  settings.numSamples = 0;  
  settings.doubleBuffering = false;
  settings.visible = false;
  settings.setSize(1, 1);

  shared_ptr<ofAppGLFWWindow> context = std::make_shared<ofAppGLFWWindow>();

  context->setup(settings); // <- this will also make the context current.
  context->setVerticalSync(false);

  return context;
}

void main() {
  ofGLFWWindowSettings settings;
  settings.setGLVersion(3, 3);

  // First create a shareable context free of OpenFrameworks' system.
  std::shared_ptr<ofAppGLFWWindow> shared_ctx = createContext(settings);

  // Then create your OF glfw window context as you usually do.
  settings.shareContextWith = shared_ctx;
  settings.title            = "Custom App";
  settings.numSamples       = 4;
  settings.doubleBuffering  = true;
  settings.visible          = true;
  settings.setSize(960, 540);

  // This will also make its context current.
  std::shared_ptr<ofAppGLFWWindow> render_ctx = ofCreateWindow(settings);
  render_ctx->setVerticalSync(true);

  // Give the shared context to your app.
  std::shared_ptr<ofApp> app(new ofApp(shared_ctx));

  // The app should take the first window context created through ofCreateWindow
  // but let's be explicit.
  ofRunApp(render_ctx, app);
  ofRunMainLoop(); 
}

The trick is that openframeworks will makeCurrent its windows’ context every loop’s frame
so you want to disable (makeCurrent(nulltpr)) other contexts used in the thread beforehand.

As a quick reminder shared contexts can be used to share objects but not states (like
vertex arrays), so if you’re using OpenCL for buffer / texture processing that will be okay.

Hopes that help.

Cheers !

1 Like

Thank you for your response! This is really helpful. I am still trying to wrap my head around this as I am very new to the oF internal workflow. Dont yet know the exact steps with which oF creates its GL abstractions.

//Off topic, would you know of a guide/starting point where I can see how oF ‘engine’ works? Maybe I create a separate topic when i have done a bit more of my own investigation

As to what went wrong with my code above, it was correct code, it just had problems with device sharing. I run an optimus laptop on Linux (intel iGPU + nvidia dGPU) so i had not configured the “source” and “sink” devices for ‘offload to dGPU’ to work correctly. With the correct flags, my code works properly

Mmh not as such no, but if your comfortable with it I suggest you check the code directly, especially the AppRunner and ofCreateWindow from here.

The somewhat convoluted way to context creation I described is only useful for context sharing with other threads though, as if you use ofCreateWindow directly its context will be preempted by the mainloop every other frames.

Also when you use :

settingsB.shareContextWith = contextA;
auto contextB = ofCreateWindow(settingsB);

What you actually do is giving access to contextA to contextB (and not the other way around as the name might suggest), this is why the processing / graphics context is created first and the graphics / presentation context (with the window display) is created second. In some way it is akin to write :

class contextB : public contextA {};