glReadPixel(One Pass vs循环点)

时间:2015-06-02 23:12:02

标签: c++ opengl

我对OpenGL和C ++很陌生,并且最近一直试图从我已经渲染的窗口中提取深度值。我发现了一些有趣的东西,我似乎无法弄清楚为什么会这样。

如果我用"宽度"来调用glReadPixel和"身高"与我的窗口大小匹配的值,我得到一个特定的深度图。

但是,如果我单独遍历像素,在每个点调用glReadPixel,我会得到一个不同的深度图。我这样做的就是"正确的"一个,或至少我期望的深度图。通过抓住" one-pass,"中的所有深度值得到的那个。可以这么说,是第二个版本的横向延伸版本。

这是我用于" one-pass"的基本代码。方法,窗口的一个小子样本(10x5块)

int size = window_height * window_width;
depth_ = new GLfloat[size];
glReadBuffer(GL_FRONT);
glReadPixels(0, 0, 10, 5, GL_DEPTH_COMPONENT, GL_FLOAT, depth_);
// left to right, bottom to top
int count = 0;
    for (int j = 0; j < 5; j++){
        for(int i = 0; i < 10; i++){
            myfile << i << " " << j << " " << depth_[count] << std::endl;
            count++;
        }
    }

这是我通过遍历每个点使用的代码,并为每个像素单独调用glReadPixel:

glReadBuffer(GL_FRONT);
float depthPixel;
for (int j = 0; j < 5; j++){
    for(int i = 0; i < 10; i++){
        glReadPixels(i, j, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depthPixel);
        myfile << i << " " << j << " " << depthPixel << std::endl;
    }
}

我从&#34; one-pass&#34;中保存的文本文件的前几个值。方法如下所示:

0 0 0.462552  (1)
1 0 0.463212  
2 0 0.463831  (2)
3 0 0.464458  
4 0 0.46518   (3)
5 0 0.465858  
6 0 0.466519  (4)

第二种循环方法如下所示:

0 0 0.462552  (1)
1 0 0.463831  (2)
2 0 0.46518   (3)
3 0 0.466519  (4)
4 0 0.467764
5 0 0.469067
6 0 0.47047

如您所见,在第一个示例中的每个点之间插入了一个额外的深度值,几乎就像我以两倍的速率采样。

再一次,我是OpenGL的新手以及很多这样的东西,所以我可能犯了一个非常愚蠢的初学者错误。尽管如此,我还没有能够自己解决这个问题。

任何人都可以帮我一把吗?

2 个答案:

答案 0 :(得分:0)

我认为您的问题可能存在于此处:

int size = window_height * window_width;
…
glReadPixels(0, 0, 10, 5, GL_DEPTH_COMPONENT, GL_FLOAT, depth_);
                    ^^^^^
                         \--- ?!?!

你有一些宽度= 10,高度= 5的硬编码值,这当然不会让OpenGL正确填充你的缓冲区。

答案 1 :(得分:0)

感谢大家的帮助,我发现在看到我的Retina显示屏是否导致问题后,我发现了什么问题。

当我初始化窗口时,我打开了多次采样,如下所示:

    glfwWindowHint(GLFW_SAMPLES, 4);

我将其设置回默认值,然后添加一些代码以说明我的Retina显示(缩小以匹配我想要的实际窗口宽度/高度。)

    glfwWindowHint(GLFW_SAMPLES, 0);

这解决了我的问题。我还不完全确定在水平方向上进行双重采样的情况,但是我猜测它与我在网上的一些示例代码中继承的多次采样有关,并且也许它与Retina显示屏相互作用。

无论如何,你的评论帮助我找到了正确的方向,一切都按照我的预期运作。