微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在不需要任何窗口系统库的情况下使用 OpenGL 渲染到内存?

如何解决如何在不需要任何窗口系统库的情况下使用 OpenGL 渲染到内存?

我想使用 OpenGL(1.5 版)将图像渲染到内存,而不在屏幕上显示它们(例如,我可以将它们保存为图像文件或在终端中将它们渲染为 ASCII)。我不想要任何 I/O。我在 SO 上发现了类似的问题,但没有一个解决我接下来的具体要求。

现在我想我可以使用像 glx 这样的库并告诉它不要打开任何窗口,但是我也不希望我的代码依赖于任何像 X11 这样的窗口系统库,因为我的程序根本不做任何事情对于任何窗口或 I/O,我不明白为什么我的程序会受到对 X 窗口的依赖(因为有些系统根本没有 X 窗口,它们甚至可能根本没有图形界面)。我的程序应该只依赖于 OpenGL 驱动程序。

我明白我需要创建一个 OpenGL 上下文,它不是 OpenGL 的一部分,它是依赖于平台的东西,所以实际上我可能需要一些库来理想地创建一个 OpenGL 渲染到内存上下文多平台方式(即抽象掉平台相关的东西)。这样的东西存在吗? (我对任何专有的、特定于 GPU 或特定于驱动程序的软件不感兴趣,该程序应该在支持给定 OpenGL 版本的任何 GPU 上运行。)还有什么我应该考虑的吗?

基本上我希望我的程序非常小并且不会被它不需要的东西所累,因为它所需要的只是使用通用的 OpenGL 驱动程序将图像渲染到内存中,并且应该在任何具有这样的系统上工作OpenGL 驱动程序。

谢谢。

解决方法

根据您使用的操作系统和驱动程序的可用性,您可以使用 EGL 进行纯粹的、无头的、GPU 加速的 OpenGL 渲染。 Nvidia 在 https://developer.nvidia.com/blog/egl-eye-opengl-visualization-without-x-server/

上有一个很好的开发者博客,介绍了如何做到这一点

其要点是,在显示设备上创建 EGL 上下文而不将其与输出相关联。来源(直接从链接的文章中复制):

#include <EGL/egl.h>
static const EGLint configAttribs[] = {
          EGL_SURFACE_TYPE,EGL_PBUFFER_BIT,EGL_BLUE_SIZE,8,EGL_GREEN_SIZE,EGL_RED_SIZE,EGL_DEPTH_SIZE,EGL_RENDERABLE_TYPE,EGL_OPENGL_BIT,EGL_NONE
};    

static const int pbufferWidth = …;
static const int pbufferHeight = …;

static const EGLint pbattr[] = {
        EGL_WIDTH,pbufferWidth,EGL_HEIGHT,pbufferHeight,EGL_NONE,};

int main(int argc,char *argv[])
{
  EGLDisplay eglDpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  EGLint major,minor;
  eglInitialize(eglDpy,&major,&minor);
  EGLint numConfigs;
  EGLConfig eglCfg;

  eglChooseConfig(eglDpy,configAttribs,&eglCfg,1,&numConfigs);
  EGLSurface eglSurf = eglCreatePbufferSurface(eglDpy,eglCfg,pbattr);
  eglBindAPI(EGL_OPENGL_API);
  EGLContext eglCtx = eglCreateContext(eglDpy,EGL_NO_CONTEXT,NULL);    
  eglMakeCurrent(eglDpy,eglSurf,eglCtx);

  do_opengl_stuff();

  eglTerminate(eglDpy);
  return 0;
}

如果您无权访问 EGL,但您的操作系统和 GPU 受 Linux DRM/DRI 支持,您可以选择 KMS/GBM 路线,并且值得使用通过扩展机制获得的帧缓冲对象(好吧,使用 Mesa您可以像使用非扩展一样使用它们,即使使用 OpenGL-1.x)。 kmscube 演示有一个“无表面”模式,它演示了正是这样做的。

简而言之:EGL 是处理它的“干净”方式。 KMS 是一种“hacky”方式。

另一个选项,现在可能完全超出您的范围,是使用 Vulkan,严格来说,无头渲染是“默认”,在屏幕上获取内容的方法是规范的实际扩展:>

    VK_KHR_wayland_surface
    VK_KHR_xcb_surface
    VK_KHR_xlib_surface
    VK_KHR_win32_surface

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。