Creating Cross-Platform OpenGL Context Out of Screen

I have a task to implement offscreen rendering of OpenGL for both Window and Linux in C ++. I have a version already written in Java using the LWJGL lib.There I used a PBuffer object, which under the hood creates Pbuffers based on the OS used. At first I thought about re-implementing the full logic for creating PBuffer, as was done in LWJGL's own source. Then I read this on StackOverflow.com, which suggests using standard context creation, say using GLFW (this is a cross-platform), but not to create the actual window. Is it correct? What are the pros and cons of using Pbuffer in this case?

Update: I just want to emphasize that I use FBOs to render frames, so my problem here is not how to render in off-screen mode, but how to create a windowless context in both Windows and Linux.

+6
source share
3 answers

I highly recommend not using PBuffers , but using Frame Buffer Objects (FBOs) . FBOs offer much better performance, since using them does not require a context switch, and they have several other advantages .

LWJGL supports FBOs , but GLFW is โ€œsimpleโ€ for cross-platform tuning of OpenGL and not for rendering . For convenient cross-platform use of FBO, I would recommend using a library such as OGLplus on top of GLFW. See here for an example of rendering to a texture.

+5
source

The simple DirectMedia Layer (SDL) library is worth a try. This simplifies cross-platform OpenGL context creation with the ability to use memory surfaces for off-screen rendering.

The only thing you need to do is enable your OpenGL and SDL headers from different places, depending on your platform. This can be done using simple preprocessor directives.

+2
source

As far as I know, there is no cross-platform way to create contexts, you will need to create your own abstraction and then implement it for each platform.

In the windows, I used the following code to create a second context for loading content in the background thread (this program used GLFW, but it did not matter):

void Program::someFunction() { HDC hdc = wglGetCurrentDC(); HGLRC hglrc = wglGetCurrentContext(); HGLRC hglrc_new = wglCreateContext(hdc); wglShareLists(hglrc, hglrc_new); loadThread = boost::thread(&Program::loadFunc, this, hdc, hglrc_new); } /** * Imports all our assets. Supposed to run in its own thread with its own OpenGL context. * @param hdc The current device context. * @param hglrc A OpenGL context thats shares its display list with the main rendering context. */ void Program::loadFunc(HDC hdc, HGLRC hglrc) { wglMakeCurrent(hdc, hglrc); //Do stuff... wglMakeCurrent(NULL, NULL); wglDeleteContext(hglrc); } 
0
source

All Articles