[英]Windowless OpenGL
我想有一个没有窗口的OpenGL上下文(在带有Xorg和Windows的GNU / linux上)。 除了只调用glGetString
, glCompileShader
等类似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_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不知道您使用的是什么实现。 例如,在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.