繁体   English   中英

无窗口OpenGL

[英]Windowless OpenGL

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

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

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

编辑:使用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;
}

编辑2:我根据接受的答案写了一篇关于无窗口opengl (带有示例代码)的简短文章。

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

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

您应该测试扩展ARB_extensions_stringARB_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实现
  • 可以请求> 3.2 OpenGL实现
  • 可以强制向前兼容性选项 (仅着色器渲染,这是未来的方式)
  • 可以选择 (仅在前向兼容的上下文中) 特定的OpenGL实现配置文件 (实际上只有CORE配置文件,但将来可能会有更多。
  • 即使未定义实际驱动程序实现如何使用此选项,也可以启用调试选项

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

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

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

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

资源

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

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

我所做的其中一件事 - 无可否认是为了避免创建我自己的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方法使用视觉效果 - 请在这个帖子上重新发布你所做的。

祝好运。

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

当有遗嘱时,就有办法。

使用GLFW ,您可以通过设置单个<VISIBLE: FALSE>窗口提示来完成此操作

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM