c++ - GL_32F 和 glReadPixels

标签 c++ opengl glsl

在 OpenGL 中,我试图将未缩放的 float 从我的片段着色器输出到 FBO 颜色附件,以便鼠标悬停在值上进行拾取。但是我无法让我的片段着色器代码正确写入值。

我添加了一个颜色附件,用于将拾取值存储到我绘制的帧缓冲区中,如下所示:

// ... Bind FBO .etc.
glTexImage2D(
    GL_TEXTURE_2D,
    0,
    GL_R32F,
    DrawTextureDims.width(),
    DrawTextureDims.height(),
    0,
    GL_RED,
    GL_FLOAT,
    0);
glFramebufferTexture2D(
    GL_FRAMEBUFFER,
    GL_COLOR_ATTACHMENT2,
    GL_TEXTURE_2D,
    pointsMeshData->magnitudeTexture,
    0);

并在绘制之前设置绘制缓冲区,如下所示:

    // ...
    GLenum drawBufs[2] {
        GL_COLOR_ATTACHMENT0,
        GL_COLOR_ATTACHMENT2
    };
    glDrawBuffers(2,drawBufs);

    GLfloat clearMagnitude[4] { 0,0,0,0 };
    glClearBufferfv(GL_COLOR,1,clearMagnitude);

    // Bind VAO and shader. Setup uniforms and call glDrawElements()

最后回读如下:

...
glBindFramebuffer(GL_READ_FRAMEBUFFER,drawData->renderFBO.handle());
glReadBuffer(GL_COLOR_ATTACHMENT2);
glBindBuffer(GL_PIXEL_PACK_BUFFER,0);

*magnitude = 0.f;
glReadPixels(x,y,1,1,GL_RED,GL_FLOAT,magnitude);
...

但是,当我使用以下片段着色器输出到第二个颜色附件时,没有绘制任何内容。我从 glReadPixels() 取回了用 (clearMagnitude) 清除的颜色

#version 330

in float scale;
uniform sampler1D uPalette;
layout(location=0) out vec4 color;
layout(location=1) out float oScale;

void main(void)
{
    color = texture(uPalette,scale);
    oScale = scale;
}

另一方面,当我使用以下(显然错误)片段着色器进行输出时,我在 glReadPixels() 中得到一个缩放的 (0-1) 值:

#version 330

in float scale;
uniform sampler1D uPalette;
layout(location=0) out vec4 color;
layout(location=1) out vec4 oScale;

void main(void)
{
    color = texture(uPalette,scale);
    oScale = vec4(scale,scale,scale,1);
}

我做错了什么?我如何在 GLSL 中输出和读回单个未缩放的 float ?

最佳答案

I output using the following (clearly wrong) fragment shader

那个片段着色器没有任何问题。就像顶点属性一样,片段着色器输出组件计数不必与实际目标图像的组件计数相匹配。如果您的输出图像的组件少于相应的片段着色器变量,那么它将只获取与图像匹配的组件并忽略其余组件。

但是,您没有输出 vec4 只是为了写入单 channel 图像。您的 float 示例应该可以正常工作,因此可能存在驱动程序错误。

至于缩放问题,那是另一回事的错:read color clamping .您必须使用 glClampColor 告诉 OpenGL 不要限制浮点读取。像这样:

glClampColor(GL_CLAMP_READ_COLOR, GL_FIXED_ONLY);

这可以防止在读取具有定点格式的 FBO 附加图像时发生夹紧。

这不是 FBO 状态的一部分;这只是一个上下文值。因此,您只需设置一次即可忘记它。

关于c++ - GL_32F 和 glReadPixels,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42325388/

相关文章:

c++ - ISO C++ 禁止声明没有类型的 ...

javascript - glGetHistogram WebGL/C++

c++ - 在 CodeBlocks 中设置 OpenGL

opengl - 用于数组大小的专门化常量

optimization - GLSL 着色器中 cos() 和 sin() 函数的速度?

java - C++ 或 Java 中的类型转换和类型转换有什么区别?

c++ - 是否可以将对指针的引用从 Excel VBA 传递到 C++?

c++ - 在 C++ 中为继承的嵌套类提供单独的数据类型

java - OpenGL 帧缓冲区深度不起作用

glsl - WebGL 是否支持 1D 纹理?