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

使用 GLX 时,OpenGL glReadPixels 不适用于 EGL

如何解决使用 GLX 时,OpenGL glReadPixels 不适用于 EGL

我想将 OpenGL 与 EGL 上下文一起用于屏幕外渲染到内存中。我设法获得了一个运行代码,而没有 OGL 或 EGL 报告的错误,但是当我尝试在渲染后使用 glreadPixels 读取像素时,我在内存中看不到任何渲染图像。我还尝试了使用 GLX 上下文而不是 EGL 的相同代码,并且该代码按预期工作。我想看看错误在哪里,因为我想使用 EGL 而不是拖着不必要的窗口系统库的负担。我还想避免 OGL 版本 > 1.5,即没有帧缓冲对象。

这里是完整的代码,你可以通过在 1 和 0 之间改变 USE_EGL 的值来在 EGL 和 GLX 之间切换。(我编译为 gcc -lGL -lEGL -lGLX -lX11 test.c

#include <stdint.h>
#include <stdio.h>

#include <GL/gl.h>
#include <EGL/egl.h>

#include <GL/glx.h>

#define USE_EGL 1

#define IMG_W 16
#define IMG_H 16

uint8_t image[4 * IMG_W * IMG_H];

int main()
{

#if USE_EGL
  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 EGLint pbufferAttribs[] =
  {
    EGL_WIDTH,IMG_W,EGL_HEIGHT,IMG_H,EGL_NONE
  };

  EGLdisplay eglDpy = eglGetdisplay(EGL_DEFAULT_disPLAY);

  EGLint major,minor;

  printf("%d",eglInitialize(eglDpy,&major,&minor) == EGL_TRUE);

  EGLint numConfigs;
  EGLConfig eglCfg;

  printf("%d",eglChooseConfig(eglDpy,configAttribs,&eglCfg,1,&numConfigs) == EGL_TRUE);

  EGLSurface eglSurf = eglCreatePbufferSurface(eglDpy,eglCfg,pbufferAttribs);

  printf("%d",eglSurf != EGL_NO_SURFACE);

  printf("%d",eglBindAPI(EGL_OPENGL_API) == EGL_TRUE);

  EGLContext eglCtx = eglCreateContext(eglDpy,EGL_NO_CONTEXT,NULL);

  printf("%d",eglMakeCurrent(eglDpy,eglSurf,eglCtx) == EGL_TRUE);
#else
  // glx

  display *glxDpy = XOpendisplay(0);

  int attributeList[] = {
    GLX_RGBA,GLX_DOUBLEBUFFER,GLX_RED_SIZE,GLX_GREEN_SIZE,GLX_BLUE_SIZE,None };

  int nelements;
  GLXFBConfig *fbc = glXChooseFBConfig(glxDpy,DefaultScreen(glxDpy),&nelements);

  XVisualInfo *vi = glXChooseVisual(glxDpy,attributeList);

  XSetwindowAttributes swa;
  swa.colormap = XCreateColormap(glxDpy,Rootwindow(glxDpy,vi->screen),vi->visual,AllocNone);
  swa.border_pixel = 0;
  swa.event_mask = StructureNotifyMask;
  Window win = XCreateWindow(glxDpy,vi->depth,InputOutput,CWBorderPixel|CWColormap|CWEventMask,&swa);

  XMapWindow (glxDpy,win);

  GLXContext ctx = glXCreateContext(glxDpy,vi,GL_TRUE);
  glXMakeCurrent (glxDpy,win,ctx);
#endif

  glClearColor(0.0,0.0,0.0);
  glClear(GL_COLOR_BUFFER_BIT);
  glColor3f(1.0,0.7,1.0);
  glOrtho(0.0,1.0,-1.0,1.0);

  printf("%d",glGetError() == GL_NO_ERROR);

  glBegin(GL_polyGON);
    glVertex3f(0.2,0.2,0.0);
    glVertex3f(0.2,0.0);
    glVertex3f(0.7,0.0);
  glEnd();

  glFlush();

  glFinish();

  glreadPixels(0,GL_RGB,GL_UNSIGNED_BYTE,image);

  printf("%d",glGetError() == GL_NO_ERROR);

  glFinish();

  printf("\n");

  for (int i = 0; i < IMG_W; ++i) // draw to terminal
  {
    for (int j = 0; j < IMG_H; ++j)
      printf("%c ",image[3 * (j * IMG_W + i)] != 0 ? '#' : '.');

    printf("\n");
  }

  #if USE_EGL
    eglTerminate(eglDpy);
  #else
    ctx = glXGetCurrentContext(); 
    glXDestroyContext(glxDpy,ctx); 
  #endif

  return 0;
}

使用 USE_EGL 0(glx 版本)我得到了预期的结果:

11
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . # # # # # # # # . . . . .
. . . # # # # # # # . . . . . .
. . . # # # # # # . . . . . . .
. . . # # # # # . . . . . . . .
. . . # # # # . . . . . . . . .
. . . # # # . . . . . . . . . .
. . . # # . . . . . . . . . . .
. . . # . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .

同时使用 USE_EGL 1 我得到:

1111111
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .

我的系统是 Devuan GNU/Linux,带有 OpenGL version string: 2.1 Mesa 18.3.6,Intel GPU。是我做错了什么还是可能是驱动程序错误

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