Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
177 views
in Technique[技术] by (71.8m points)

c++ - Windowless OpenGL

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("
cannot connect to X server

");
    exit(0);
  }

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

  if (!vi) {
    printf("
no appropriate visual found

");
    exit(0);
  }

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

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

  return 0;
}

EDIT2: I've written a short article about windowless opengl (with sample code) based on the accepted answer.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...