无窗口OpenGL

时间:2010-05-24 12:16:34

标签: c++ c opengl

我想要一个没有窗口的OpenGL上下文(在带有Xorg和Windows的GNU / linux上)。除了只调用glGetStringglCompileShader之类的函数之外,我不会渲染任何东西。

除了创建一个隐藏的窗口之外,我已经完成了一些有用的但没有任何有用的东西。这对我来说似乎是个黑客。

那么有没有人有更好的想法(对于任何平台)?

编辑:使用Xorg,我能够在根窗口创建并附加OpenGL上下文:

#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;
}

EDIT2:我根据接受的答案写了一篇关于windowless opengl的简短文章(带有示例代码)。

5 个答案:

答案 0 :(得分:21)

实际上,有必要使用窗口句柄来创建“传统”渲染上下文(X11上的根窗口或Windows上的桌面窗口都适用于此)。它用于获取OpenGL信息和扩展可用性。

获得该信息后,您可以销毁渲染上下文并释放“虚拟”窗口!

您应该测试扩展 ARB_extensions_string ARB_create_context_profile ,(在这些页面中描述:ARB_create_context)。然后,您可以通过以独立于平台的方式调用 CreateContextAttribs 来创建渲染上下文,而无需关联系统窗口并且只需要系统设备上下文

        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");

然后,如果您希望渲染,可以将帧缓冲区对象或系统窗口与创建的渲染上下文相关联(但据我所知,您只想编译着色器)。

使用 CreateContextAttribs 有许多优点:

  • 平台无关
  • 可以请求特定的OpenGL实施
  • 可以请求&gt; 3.2 OpenGL实施
  • 可以强制使用向前兼容性选项(仅使用着色器渲染,这是未来的方式)
  • 可以选择(仅在前向兼容的上下文中)特定的OpenGL实施配置文件(实际上只有CORE配置文件,但可能会有更多内容未来。
  • 可以启用调试选项,即使未定义实际驱动程序实现如何使用此选项

但是,较旧的硬件/驱动程序无法实现此扩展,实际上我建议编写一个回退代码以创建向后兼容的上下文。

答案 1 :(得分:7)

在创建窗口之前,OpenGL不知道您使用的是什么实现。例如,在DRI X-Windows会话中,远程X-Windows会话中的OpenGL与OpenGL的驱动程序(以及不同的硬件加速)非常不同。在这些情况下,着色器语言支持可能会有所不同,并且着色器编译器的输出肯定会依赖于实现,以及基于资源耗尽而产生的任何错误。

因此,虽然实际创建窗口可能不是100%必需的,但您必须以某种方式将您的上下文与图形硬件(或缺少图形硬件)相关联,并且由于这可以通过窗口完成,因此没有人打扰实现替代方法。

答案 2 :(得分:2)

您需要一个窗口来托管上下文,并且您需要一个上下文才能执行任何操作。

Source

如果您不想显示任何内容,请使窗口不可见。

如果有另一种方法可以做到这一点,那么它会被记录在某处并且很容易找到,因为这不是一个不寻常的问题。

答案 3 :(得分:1)

我所做的其中一件事 - 无可否认,这是为了避免创建我自己的GL窗口的开销 - 是利用开放的流程窗口。

理解OpenGL的关键是:通过调用wglCreateContext创建GL上下文所需要的只是一个有效的DC。

文档中没有任何内容表明它必须是您拥有的。

为了测试这一点,我弹出了魔兽世界,并利用SPY ++获取窗口句柄,然后我手动将该句柄插入到GetDC的调用中,GetDC返回一个有效的设备上下文,然后从那里运行我的GL代码的其余部分正常。

我自己没有创建GL窗口。

这是我用魔兽世界和星际迷航在线https://universalbri.wordpress.com/2015/06/05/experiment-results

时发生的事情

所以要回答你的问题,是的,你需要一个窗口,但文档中没有任何内容表明窗口需要由你拥有。

现在建议:我无法使用桌面窗口提供此方法来提供有效的可视输出,但我能够使用针对HWND的getDeskTopWindow API成功创建DC,然后调用GetDC。因此,如果你想要使用OpenGL进行非可视化处理 - 让我知道你正在做什么,我很好奇,如果你碰巧让GetDesktopWindow方法使用视觉效果 - 请在这个帖子上重新发布你所做的。

祝你好运。

不要让任何人告诉你它无法完成。

当有遗嘱时,有办法。

答案 4 :(得分:1)

使用GLFW,您可以setting a single <VISIBLE: FALSE> window hint

执行此操作