21

I'm trying to figure out what is the simplest way to create a windowless OpenGL program for offscreen rendering.

Currently I use this, and it works fine so far: (error checks removed here for clarity)

BOOL create_opengl_context(){
    GLuint PixelFormat;
    static PIXELFORMATDESCRIPTOR pfd;
    hDC = GetDC(NULL);
    PixelFormat = ChoosePixelFormat(hDC, &pfd);
    SetPixelFormat(hDC, PixelFormat, &pfd);
    hRC = wglCreateContext(hDC);
    wglMakeCurrent(hDC, hRC);
}

Is this safe to use? What is the "standard" way to create a windowless OpenGL program?

Edit: I'm using FBO for the offscreen rendering.

Rookie
  • 4,064
  • 6
  • 54
  • 86
  • There's that portable thing called [EGL](http://en.wikipedia.org/wiki/EGL_(OpenGL)), but I'm not really sure if it's usable on Windows as of now – Kos Sep 18 '12 at 17:40
  • 2
    Where does the "off-screen" part come from? `GetDC(0)` returns a device context for the entire screen, not for an off-screen entity – jalf Sep 18 '12 at 17:42
  • 2
    possible duplicate of [Can you create OpenGL context without opening a window?](http://stackoverflow.com/questions/576896/can-you-create-opengl-context-without-opening-a-window) – jalf Sep 18 '12 at 17:45
  • 2
    Also you must *never* set the pixelformat of the root window, and creating a OpenGL context isn't such a good idea either. – datenwolf Sep 18 '12 at 17:46
  • @datenwolf, did i set the root window pixelformat? o.O oh well... any suggestions how it should be done then? – Rookie Sep 18 '12 at 17:50
  • 2
    @Rookie: Create a regular window, but don't show it to the user, i.e. omit the WS_VISIBLE flag when creating the window. Create the OpenGL context on that window. – datenwolf Sep 18 '12 at 18:22
  • @datenwolf, okay, but is that the only way? my aim is to optimize the window/context creation, because currently it takes (in worst case) 3/4 of the time of my program running time, which is kinda silly. Is it possible to create the "window" once, and then somehow remember it for all the programs that are executed? edit: i dont even use WS_VISIBLE currently (yet my window is visible), where is that supposed to go? i used `ShowWindow(hWnd, SW_SHOW);` though. – Rookie Sep 19 '12 at 14:43
  • @Rookie: Creating a window is a rather fast process. Context creation however can be quite costly, and that's independent from if it uses a window or not. If your problem is the program startup and initialization phase, then you clearly should implement this as a client-server system. You'd have one server process (that started one time and keeps running) that does all the GPU operations for the clients, which are lightweight programs that just pass tasks to the server and return the result to their caller. – datenwolf Sep 19 '12 at 16:09
  • @datenwolf, how does this client-server system work exactly? do i need to send the data with sockets or something? – Rookie Sep 20 '12 at 10:29
  • @Rookie: You can use what ever IPC (Inter Process Communication) scheme suits you best. If I were to design such a system I'd use a segment of SHM (SHared Memory) for data exchange and some RPC (remote procedure call) mechanism to call functions in the server, that internally reference data in the SHM. You're on Windows, so I cannot recommend anything in particular (I'm a Unix/Linux guy). On Unix/Linux a viable RPC system would be D-Bus; although I personally don't like a number of aspects in its design, but D-Bus is the de-facto standard RPC mechanism on Linux. – datenwolf Sep 20 '12 at 10:51
  • After latest AMD driver update for RX6500 XT, my whole screen flickers for a brief moment and my program crashes. Perhaps a dummy window would be better. – IOviSpot Aug 14 '22 at 13:40

1 Answers1

15

The old method for purely windowless OpenGL is using a PBuffer. On Windows this requires the creation of a intermediate OpenGL context using a regular window to obtain the required extension function pointers. On X11/GLX it works without further ado.

The modern way to implement off-screen rendering is using a regular, but hidden window with the usual OpenGL context and a FBO as render target.

The bleeding edge, and yet not very well supported method (except on certain embedded devices) is using EGL for drawable creation.

datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • Im using FBO. Currently the context creation takes 3/4 of the time my program runs... is it anywhow possible to reduce this context creation time? – Rookie Sep 18 '12 at 17:48
  • @Rookie: If you are running the same program many times, maybe you can change it to a client/server model, in which the client does the computations but the server does the actual render. That way the context is created only once in the server initialization. – rodrigo Sep 18 '12 at 17:57
  • @rodrigo, i cant let client do any computations or i would run into other compatibility problems. i dont understand how that makes the context creation only once though... im not sure how can i make it "keep alive" the program but still be possible to run multiple processes from that program at once...? – Rookie Sep 19 '12 at 14:36