C++ glUnproject和重画场景后的奇怪结果

C++ glUnproject和重画场景后的奇怪结果,c++,opengl,graphics,3d,C++,Opengl,Graphics,3d,对于我正在编写的算法,我需要取消屏幕坐标的投影,并将它们重新投影到光空间中。这是这样的:我从我的视点(使用glLookAt)填充深度缓冲区,然后将所有可见像素取消投影到世界空间。然后我将它们重新投射到光的空间中 我检查了所有的东西以确保我没有犯错误(之后我必须做一些其他的事情),所以我画了我从光空间看到的新投影像素。为了确保我得到了正确的结果,我假设我的光线和我的眼睛在同一个点上 这是原景。然后我取消投影并重新绘制它们,我得到以下结果: void getObjectCoords(){ s

对于我正在编写的算法,我需要取消屏幕坐标的投影,并将它们重新投影到光空间中。这是这样的:我从我的视点(使用glLookAt)填充深度缓冲区,然后将所有可见像素取消投影到世界空间。然后我将它们重新投射到光的空间中

我检查了所有的东西以确保我没有犯错误(之后我必须做一些其他的事情),所以我画了我从光空间看到的新投影像素。为了确保我得到了正确的结果,我假设我的光线和我的眼睛在同一个点上

这是原景。然后我取消投影并重新绘制它们,我得到以下结果:

void getObjectCoords(){
std::向量z(800*600,0);
标准::矢量<顶点>光点;
闪烁视口[4];
GLdouble modelview[16];
gl双投影[16];
GLdouble-posX,posY,posZ;
//为取消投影设置原始视点
gluLookAt(4.0,4.0,15.0,0.0,0.0,0.0,1.0,0.0);
//获取Modelviewx、投影和视口矩阵
glGetDoublev(GL_模型视图_矩阵,模型视图);
glGetDoublev(GL_投影矩阵,投影);
glGetIntegerv(GL_视口,视口);
//重置模型视图
glLoadIdentity();
//获取原始点的深度坐标
glReadPixels(0,0800,600,GL_深度分量,GL_浮点,&z[0]);
//未投影的X和Y。
整数计数=0;
顶点温度;
对于(int X=0;X<800;++X){
对于(int Y=0;Y<600;++Y){
glunproject(X,Y,z[X*600+Y],modelview,projection,viewport,&posX,&posY,&posZ);
如果(z[X*600+Y]<1){
++计数;
温度x=posX;
温度y=posY;
温度z=位置z;
光点。推回(温度);
}
}
}
std::cout z、modelview、投影、视口、&winX、&winY、&winZ);
温度x=winX;
温度y=winY;
温度z=winZ;
样本点。推回(温度);
}
//标准:coutz);
}
格伦德();
}
在我看来,情况似乎是这样的,尽管我不知道为什么。您还可以在不同高度看到部分场景,如果这些都在同一高度,则我的图像已完成(并且我有正确的结果)

那么,是什么原因使它站在它的一边并且如此分散?(有人告诉我这两件事可能有关联)

编辑: 根据下面给出的建议,我开始尝试不同的pixelstore选项: GL_-PACK_对齐似乎没有任何效果,我尝试了1、2、4和8。 GL_PACK_ROW_LENGTH为0时正确,它采用readpixels中指定的宽度。
鉴于我不想跳过任何内容,跳过选项也应保持为零。

这似乎是因为您没有正确设置像素存储参数(步幅、对齐等),尤其是块参数。查看完整的选项集。在您的情况下,您要设置

glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
就在调用glReadPixels之前


编辑/更新:

代码中还有另一个问题:处理像素阵列的方式。你写的

gluUnProject( …, z[X*600 + Y], …)
这是错误的。每一行(在您的例子中)都有800像素宽,所以要前进一行,必须偏移800个元素。因此,要寻址(宽度、高度)线性阵列中的像素(x,y),必须写入

data[y*width + x]
还是你的情况

z[Y*800 + X]

顺便说一下,不要硬编码800×600,而应该使用变量或命名常量;保持代码的可维护性。

这看起来您没有正确设置像素存储参数(步幅、对齐等),尤其是块参数。查看完整的选项集。在您的情况下,您要设置

glPixelStorei(GL_PACK_ALIGNMENT, 1);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
就在调用glReadPixels之前


编辑/更新:

代码中还有另一个问题:处理像素阵列的方式。你写的

gluUnProject( …, z[X*600 + Y], …)
这是错误的。每一行(在您的例子中)都有800像素宽,所以要前进一行,必须偏移800个元素。因此,要寻址(宽度、高度)线性阵列中的像素(x,y),必须写入

data[y*width + x]
还是你的情况

z[Y*800 + X]

顺便说一下,不要硬编码800×600,而应该使用变量或命名常量;保持代码的可维护性。

Hmm,恐怕这不会改变第二幅图像中的任何内容。仔细想想,看看我的代码,你是对的,它可能是像素存储。我将对这些选项进行更多的实验。如果你有任何建议,为什么你的不工作,我很高兴听到他们@弗里斯蒂:问题在于数据对齐,但不是在OpenGL部分,而是在您的访问上。看我的编辑(待编写)。是的,我知道,我有变量,但通过测试我把它们改成了数字。我知道这是不好的练习,但动作要快,而且全部..好了,最后开始:这确实是一个非常愚蠢的错误。即使我使用了变量,我也会成功的。我真傻,竟然像你说的那样换了x和y。谢谢!嗯,恐怕这不会改变第二张图片中的任何内容。当你仔细思考并查看我的代码时,你是对的,它可能是像素存储。我将对这些选项进行更多的实验。如果你有任何建议,为什么你的不工作,我很高兴听到他们@弗里斯蒂:问题在于数据对齐,但不是在OpenGL部分,而是在您的访问上。看我的编辑(待编写)。是的,我知道,我有变量,但通过测试我把它们改成了数字。我知道这是不好的练习,但动作要快,而且全部..好了,最后开始:这确实是一个非常愚蠢的错误。即使我使用了变量,我也会成功的。我真傻,竟然像你说的那样换了x和y。谢谢!