Creating OpenGL context without window
Asked Answered
S

1

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.

Seadon answered 18/9, 2012 at 17:37 Comment(11)
There's that portable thing called EGL, but I'm not really sure if it's usable on Windows as of nowTnt
Where does the "off-screen" part come from? GetDC(0) returns a device context for the entire screen, not for an off-screen entityCollide
possible duplicate of Can you create OpenGL context without opening a window?Collide
Also you must never set the pixelformat of the root window, and creating a OpenGL context isn't such a good idea either.Depicture
@datenwolf, did i set the root window pixelformat? o.O oh well... any suggestions how it should be done then?Seadon
@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.Depicture
@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.Seadon
@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.Depicture
@datenwolf, how does this client-server system work exactly? do i need to send the data with sockets or something?Seadon
@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.Depicture
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.Loosetongued
D
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.

Depicture answered 18/9, 2012 at 17:45 Comment(3)
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?Seadon
@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.Psychoneurotic
@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...?Seadon

© 2022 - 2024 — McMap. All rights reserved.