我想要一个没有窗口的OpenGL上下文(在带有Xorg和Windows的GNU / linux上)。除了只调用glGetString
,glCompileShader
之类的函数之外,我不会渲染任何东西。
除了创建一个隐藏的窗口之外,我已经完成了一些有用的但没有任何有用的东西。这对我来说似乎是个黑客。
那么有没有人有更好的想法(对于任何平台)?
编辑:使用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的简短文章(带有示例代码)。
答案 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 有许多优点:
但是,较旧的硬件/驱动程序无法实现此扩展,实际上我建议编写一个回退代码以创建向后兼容的上下文。
答案 1 :(得分:7)
在创建窗口之前,OpenGL不知道您使用的是什么实现。例如,在DRI X-Windows会话中,远程X-Windows会话中的OpenGL与OpenGL的驱动程序(以及不同的硬件加速)非常不同。在这些情况下,着色器语言支持可能会有所不同,并且着色器编译器的输出肯定会依赖于实现,以及基于资源耗尽而产生的任何错误。
因此,虽然实际创建窗口可能不是100%必需的,但您必须以某种方式将您的上下文与图形硬件(或缺少图形硬件)相关联,并且由于这可以通过窗口完成,因此没有人打扰实现替代方法。
答案 2 :(得分:2)
您需要一个窗口来托管上下文,并且您需要一个上下文才能执行任何操作。
如果您不想显示任何内容,请使窗口不可见。
如果有另一种方法可以做到这一点,那么它会被记录在某处并且很容易找到,因为这不是一个不寻常的问题。
答案 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)