为什么glReadPixels似乎返回垃圾?

时间:2016-07-08 09:46:44

标签: linux opengl egl

我试图用OpenGL绘制屏幕。为此我使用EGL初始化pbuffer表面,然后绘制到它,用glReadPixels读取结果。但是下面的程序让我在不同的(基于Mesa的Intel on Linux)GPU上使用了垃圾。也就是说,在Atom N550上我得到零,而在Xeon E3-1200 v3上我有70 00 07 44而不是预期的40 80 bf ff

设置LIBGL_ALWAYS_SOFTWARE=1环境变量后,我得到了预期的结果。另外,如果我用eglBindAPI注释掉这一行,我会在Xeon上获得好结果,但在Atom上仍然为零。

这是我的计划:

#include <EGL/egl.h>
#include <GL/gl.h>
#include <iostream>
#include <iomanip>
#include <cstring>

int eglPrintError(std::string const& context)
{
    const GLint error=eglGetError();
    std::cerr << context << ": error 0x" << std::hex << int(error) << "\n";
    return 1;
}
bool checkError(std::string const& funcName)
{
    const GLenum error=glGetError();
    if(error!=GL_NO_ERROR)
    {
        std::cerr << funcName << ": error 0x" << std::hex << int(error) << "\n";
        return true;
    }
    return false;
}

constexpr int fbW=1, fbH=1;

bool initGL()
{
    if(!eglBindAPI(EGL_OPENGL_API)) return !eglPrintError("eglBindAPI");

    const EGLDisplay dpy=eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if(!dpy) return !eglPrintError("eglGetDisplay");

    if(!eglInitialize(dpy,nullptr,nullptr)) return !eglPrintError("eglInitialize");

    static const EGLint cfgAttribs[]={EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT,
                                      EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
                                      EGL_RED_SIZE, 8,
                                      EGL_GREEN_SIZE, 8,
                                      EGL_BLUE_SIZE, 8,
                                      EGL_ALPHA_SIZE, 8,
                                      EGL_NONE};
    EGLConfig cfg;
    EGLint cfgCount;
    if(!eglChooseConfig(dpy,cfgAttribs,&cfg,1,&cfgCount))
        return !eglPrintError("eglChooseConfig");
    if(cfgCount==0)
    {
        std::cerr << "Failed to get any usable EGL configs\n";
        return false;
    }

    const EGLContext context=eglCreateContext(dpy,cfg,EGL_NO_CONTEXT,NULL);
    if(!context) return !eglPrintError("eglCreateContext");

    const EGLint surfaceAttribs[]={EGL_WIDTH, fbW, EGL_HEIGHT, fbH, EGL_NONE};
    const EGLSurface surface=eglCreatePbufferSurface(dpy,cfg,surfaceAttribs);
    if(!surface) return eglPrintError("eglCreatePbufferSurface");

    if(!eglMakeCurrent(dpy,surface,surface,context))
        return !eglPrintError("eglMakeCurrent");

    return true;
}

int main(int argc, char** argv)
{
    if(!initGL()) return 1;

    glViewport(0,0,fbW,fbH);
    glClearColor(0.25,0.5,0.75,1.);
    glClear(GL_COLOR_BUFFER_BIT);

    glFinish();
    unsigned char data[4*fbW*fbH];
    std::memset(data,0xb7,sizeof data); // to see unchanged values
    glReadPixels(0,0,fbW,fbH,GL_RGBA,GL_UNSIGNED_BYTE,data);
    if(checkError("glReadPixels")) return 1;
    std::cout << "Data read: " << std::hex << std::setfill('0');
    for(auto datum : data)
        std::cout << std::setw(2) << +datum << " ";
    std::cout << "\n";
    return 0;
}

我的问题是,上述代码中是否有任何可能导致此类行为的错误,或者我的驱动程序是否仅仅是错误的?

0 个答案:

没有答案