glReadPixels 不适用于 GL_FLOAT

Posted

技术标签:

【中文标题】glReadPixels 不适用于 GL_FLOAT【英文标题】:glReadPixels is not working with GL_FLOAT 【发布时间】:2018-05-25 10:58:56 【问题描述】:

我正在使用 OpenGL 着色器并尝试打印颜色值。

所以,我使用了glReadPixels 函数。它适用于GL_UNSIGNED_BYTE,但不适用于GL_FLOAT

我还有什么需要做的吗?

这是我的代码。

void settingFrameBuffers()

    glGenFramebuffers(NUM_FBO, fbo);
    glGenTextures(NUM_FBO, tex);

    for (int i = 0; i < NUM_FBO; i++)
    
        glBindFramebuffer(GL_FRAMEBUFFER, fbo[i]);
        glBindTexture(GL_TEXTURE_2D, tex[i]);

        if (i == 0) glActiveTexture(GL_TEXTURE0);
        else if (i == 1) glActiveTexture(GL_TEXTURE1);
        else if (i == 2) glActiveTexture(GL_TEXTURE2);
        else if (i == 3) glActiveTexture(GL_TEXTURE3);
        else if (i == 4) glActiveTexture(GL_TEXTURE4);
        else if (i == 5) glActiveTexture(GL_TEXTURE5);

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, NULL);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex[i], 0);

        GLuint dbo;
        glGenRenderbuffers(1, &dbo);
        glBindRenderbuffer(GL_RENDERBUFFER, dbo);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height);

        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, dbo);

        glDrawBuffer(GL_COLOR_ATTACHMENT0);
    


void printWholeMassToConsole()

    GLfloat* data =new GLfloat[4 * width*height];

    glBindFramebuffer(GL_FRAMEBUFFER, fbo[otFb]);
    //glReadPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, data);
    glReadnPixels(0, 0, width, height, GL_RGBA, GL_FLOAT, sizeof(data), data);

    float sumR = 0;
    float sumG = 0;
    float sumB = 0;

    for (int i = 0; i < 4 * width*height; i += 4)
    
        if (i > 0) break;
        sumR += data[i];
        sumG += data[i + 1];
        sumB += data[i + 2];
    

    float sum = sumR + sumG + sumB;

    float possibleDiff = 3.0*width*height*0.5;
    //if (abs(wholeMass - sum) <= possibleDiff) cout << "O - ";
    //else cout << "X - ";
    printf("mass : %d\t %d\t %d\t %d\n", sum, sumR, sumG, sumB);

    free(data);

这是第一个着色器。

// vertex shader
#version 450

in vec4 position;
in vec2 texCoord;

out vec2 fragTexCoord;

void main()

    gl_Position = position;
    fragTexCoord = texCoord;


// fragment shader
#version 450

in vec2 fragTexCoord;

out vec4 FragColor;

void main()

    FragColor = vec4(0.5, 0.0, 0.0, 1.0);

这是第二个着色器。

// vertex shader
#version 450

in vec4 position;
in vec2 texCoord;

out vec2 fragTexCoord;

void main()

    gl_Position = position;
    fragTexCoord = texCoord;


// fragment shader
#version 450

in vec2 fragTexCoord;

uniform sampler2D tex;

out vec4 FragColor;

void main()

    FragColor = texture(tex, fragTexCoord);

它通过第一个 shaderotFb framebuffer 上绘制一些东西,然后将otFb 纹理映射到主framebuffer

当我使用glReadPixelsGL_FLOAT 时,程序会自行终止,当glReadnPixelsGL_FLOAT 时,程序会打印垃圾值。

我用了很多次搜索,但我找不到解决方案。

或者我有什么不同的方法可以尝试?

【问题讨论】:

旁注:当你使用 new[] 分配内存时,你必须使用 delete[] 而不是 free() 来释放它。 谢谢,忘记把分配方法alloc改成new[]了。 sizeof(data) 不是动态分配内存的大小。它的大小为GLfloat*。分配的内存大小(以字节为单位)为sizeof(GLfloat)*4*widht*height 哦...有一个错误。我用 %d 而不是 %f 来打印 printf.... 【参考方案1】:

尝试更改帧缓冲区绑定函数调用的第一个参数(printWholeMassToConsole 函数中的第二行代码),即:

glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo[otFb]);

希望它有效。

【讨论】:

这不会改变任何事情。调用 glBindFramebuffer 并将目标设置为 GL_FRAMEBUFFER 将帧缓冲区绑定到读取和绘制帧缓冲区目标

以上是关于glReadPixels 不适用于 GL_FLOAT的主要内容,如果未能解决你的问题,请参考以下文章

glReadPixels 的 OpenGL DSA 等效项

如何在不同的线程上调用 glReadPixels?

glReadPixels 不更新值

glReadPixels 移动坐标与缩放

为啥 glreadpixels 仅在某些情况下有效?

从 glReadPixels 创建 HBITMAP