【问题标题】:Different OpenGL Framebuffer RGBA values on NVIDIA cardsNVIDIA 卡上不同的 OpenGL 帧缓冲区 RGBA 值
【发布时间】:2021-06-16 10:57:38
【问题描述】:

我正在尝试实现一种颜色选择算法,因此我在不同的帧缓冲区上用唯一颜色渲染我的实体,因此我可以查询鼠标所在像素上的帧缓冲区(使用 glReadPixels)并选择下面的实体鼠标光标。 这在我的集成 Intel HD Graphics 4600 上运行良好。我能够读回我在 GPU 上发送的确切值。 但是使用我的 Nvidia GTX 860M 运行应用程序,结果并不一致。一些随机像素具有原始颜色,但大多数像素的颜色略有改变。 同样的事情发生在另一台配备 Geforce 8600 GT 的计算机上。 我尝试使用 NSight Graphics 运行它,它允许我查看纹理的内存。 箭头指向正确的像素颜色。我希望每个像素都具有相同的颜色。

我用这个联合来创造一种独特的颜色......

union u_picking_color {
    struct s_entity *ep;
    glm::vec3 color;
};

然后我像这样查询帧缓冲区:

struct s_entity *Renderer::GetEntity(int x, int y) {
    union u_picking_color picking_color = { 0 };
    m_picking_fbo.SetReadTarget();
    glReadPixels(x, y, 1, 1, GL_RGB, GL_FLOAT, &picking_color.color);
    return picking_color.ep;
}

以下是用于创建帧缓冲区的 API 调用:


glGenFramebuffers(1, &m_frameBufferId);
glBindFramebuffer(GL_FRAMEBUFFER, m_frameBufferId);
glGenTextures(1, &m_colorTextureId);
glBindTexture(GL_TEXTURE_2D, m_colorTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorTextureId, 0);
glGenTextures(1, &m_depthTextureId);
glBindTexture(GL_TEXTURE_2D, m_depthTextureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthTextureId, 0);

此外,这里是用于在帧缓冲区上绘制的着色器。它们不会改变颜色。他们只通过管道传递它。

顶点:

#version 330 core

layout(location = 0) in vec3 v_Position;
//layout(location = 1) in vec3 v_Normal;
//layout(location = 2) in vec4 v_Color;
layout(location = 3) in vec3 v_PickingColor;

out vec4 color;
uniform mat4 u_ViewProjection;

void main()
{
    color = vec4(v_PickingColor, 1);
    gl_Position = u_ViewProjection * vec4(v_Position.x, v_Position.y, v_Position.z, 1.0f);
}

片段:

#version 330 core

out vec4 fragColor;

in vec4 color;

void main()
{   
    fragColor = color;
}

我尝试禁用 GL_BLEND 和 GL_DITHER,但没有成功。

【问题讨论】:

    标签: c++ opengl graphics textures nvidia


    【解决方案1】:

    事实证明,即使我对每个顶点使用相同的颜色,我也应该在着色器上使用“flat”关键字来防止插值并避免精度错误。

    顶点着色器:

    flat out vec4 color;
    

    片段着色器:

    flat in vec4 color;
    

    【讨论】:

      猜你喜欢
      • 2014-06-26
      • 1970-01-01
      • 1970-01-01
      • 2013-12-19
      • 2013-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多