当前位置: 华文问答 > 数码

为什么非要基于窗口来创建OpenGL上下文?窗口和Opengl和操作系统和GPU之间的关系是啥?

2022-09-18数码

不是非要的。

只不过OpenGL是古老的东西, 一开始只为了渲染,而渲染总要有个画布 吧,于是让人直觉地和窗口联系了起来。常见的教程也就保留了基于窗口创建的做法。

但是后来也出现了离屏渲染的做法;再后来FBO出现以后,其实也算是跟实际窗口解耦了一半;再往后还有API是不需要「画布」的(Compute)。

从现代API视角来看,创建完context能用一堆API,但如果要绘制到屏幕的话需要手动创建swapchain(you don't pay for what you don't use?)。

OpenGL这种 老API是把这部分内容隐含进context的 无法摆脱(为了兼容性,可能也因为懒得改)。当然具体实现可以「虚构」一个实际上不做事情的swapchain……

OpenGL本身是平台无关的,但事实上做不到真的无关,所以需要一个「loader」或者说中间层。

一个系统可能有不同设备,有不同的OpenGL支持,于是要靠这个中间层去定位/选择设备,以及做一些基础工作(比如前面提到的)。

常见的就是Windows下WGL,Linux下GLX或者EGL,iOS下EAGL。

WGL不但古老,还是被Windows所打压的,所以最惨,绕不过一个HDC。HDC是GDI的概念,最常见的就是通过HWND拿,系统也会根据窗口来选择绑定的设备。

当然GDI是能用CreateCompatibleDC(NULL)来创建「和当前屏幕兼容」的内存DC的,不过事实上虽然用这个DC能看到加载了显卡的驱动,但CreateContext是不成功的。

GLX虽然也很古老,但不知是开源界愿意接受新事物,还是x11的C/S设计,导致创建glcontext是要指定drawable的——这就使得你可以脱离窗口,用CreateGLXPixmap(或者pbuffer?)去创建这个画布。

EGL是后来搭配OpenGL ES出现的,一开始还雄心勃勃想成为跨平台的接口,后来随着转向vulkan这事也偃旗息鼓了。

但EGL的确足够开放,加了一堆扩展,不但能像GLX一样用Pixmap/Pbuffer(好像后者更合适,至少安卓没提供前者),后来因为被wayland选中,逐渐往底层扩展,甚至还能直接对接gbm了 [1]

参考

  1. ^ EGL_MESA_platform_gbm https://registry.khronos.org/EGL/extensions/MESA/EGL_MESA_platform_gbm.txt