views:

288

answers:

3
+5  Q: 

Windowless OpenGL

Hi, I would like to have a windowless OpenGL context (on both GNU/linux with Xorg and Windows). I'm not going to render anything but only call functions like glGetString, glCompileShader and similar.

I've done some goggling but not come up with anything useful, except creating a hidden window; which seems like a hack to me.

So does anyone have a better idea (for any platform)?

EDIT: With Xorg I was able to create and attach an OpenGL context to the root-window:

#include<stdio.h>
#include<stdlib.h>
#include<X11/X.h>
#include<X11/Xlib.h>
#include<GL/gl.h>
#include<GL/glx.h>

int main(int argc, const char* argv[]){
  Display *dpy;
  Window root;
  GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
  XVisualInfo *vi;
  GLXContext glc;

  dpy = XOpenDisplay(NULL);

  if ( !dpy ) {
    printf("\n\tcannot connect to X server\n\n");
    exit(0);
  }

  root = DefaultRootWindow(dpy);
  vi = glXChooseVisual(dpy, 0, att);

  if (!vi) {
    printf("\n\tno appropriate visual found\n\n");
    exit(0);
  }

  glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
  glXMakeCurrent(dpy, root, glc);

  printf("vendor: %s\n", (const char*)glGetString(GL_VENDOR));

  return 0;
}
+1  A: 

You need a window to host the context and you need a context to be able to do anything.

Source

If you don't want to display anything make the window invisible.

If there was another way to do this, it would be documented somewhere and easily found as it's not an uncommon problem.

ChrisF
http://www.opengl.org/wiki/Creating_an_OpenGL_Context
Luca
@Luca - thanks for the link, most informative. I'll add it into the answer
ChrisF
+4  A: 

Until you create a window, OpenGL has no idea what implementation you use. For example, there's a very different driver (and different hardware acceleration) for OpenGL in a remote X-Windows session vs OpenGL in an DRI X-Windows session. Shader language support might be different between these cases, and the output of the shader compiler is definitely going to be implementation-dependent, as well as any errors generated based on resource exhaustion.

So while actually creating a window may not be 100% necessary, you have to associate your context with the graphics hardware (or lack thereof) somehow, and since this can be done with a window no one bothered implementing an alternate method.

Ben Voigt
What about creating a context and associating it with the root-window?
ext
@ext: Sounds like a reasonable approach. Note that no extra code had to be written for OpenGL to handle that case, it's still "associate a new context with some window", as opposed to "associate a new context with this graphics card and no I don't have a window".Just be careful not to actually render on the root window.
Ben Voigt
+3  A: 

Actually, it is necessary to have a window handle to create a "traditional" rendering context (the root window on X11 or the desktop window on Windows are good for this). It is used to fetch OpenGL information and extentions availability.

Once you got that information, you can destroy the render context and release the "dummy" window!

You should test for the extensions *ARB_extensions_string* and *ARB_create_context_profile*, (described in these page: ARB_create_context). Then, you can create a render context by calling CreateContextAttribs, in a platform independent way, without having a system window associated and requiring only the system device context:

        int[] mContextAttrib = new int[] {
            Wgl.CONTEXT_MAJOR_VERSION, REQUIRED_OGL_VERSION_MAJOR,
            Wgl.CONTEXT_MINOR_VERSION, REQUIRED_OGL_VERSION_MINOR,
            Wgl.CONTEXT_PROFILE_MASK, (int)(Wgl.CONTEXT_CORE_PROFILE_BIT),
            Wgl.CONTEXT_FLAGS, (int)(Wgl.CONTEXT_FORWARD_COMPATIBLE_BIT),
            0
        };


        if ((mRenderContext = Wgl.CreateContextAttribs(mDeviceContext, pSharedContext, mContextAttrib)) == IntPtr.Zero)
            throw new Exception("unable to create context");

Then, you could associate a frame buffer object or a system window to the created render context, if you wish to render (but as I understand, you want to compile only shaders).

Using CreateContextAttribs has many advantages:

  • It is platform independent
  • It's possible to request specific OpenGL implementation
  • It's possible to request a > 3.2 OpenGL implementation
  • It's possible to force the forward compatibility option (shader only rendering, that's the future way)
  • It's possible to select (in a forward compatible context only) a specific OpenGL implementation profile (actually there is only the CORE profile, but there could be more in the future.
  • It's possible to enable a debugging option, even if it isn't defined how this option could be used by the actual driver implementation

However, older hardware/drivers could not implements this extension, indeed I suggest to write a fallback code in order to create a backward compatible context.

Luca
This seems like what I am looking for, I will try it out.
ext