Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用stbi_write_PNG从OpenGL帧缓冲区保存的PNG向右移动_C++_Opengl_Png_Fbo_Stb Image - Fatal编程技术网

C++ 使用stbi_write_PNG从OpenGL帧缓冲区保存的PNG向右移动

C++ 使用stbi_write_PNG从OpenGL帧缓冲区保存的PNG向右移动,c++,opengl,png,fbo,stb-image,C++,Opengl,Png,Fbo,Stb Image,几天来,我一直在试图解决这个视觉缺陷,但都没有成功,所以我问这个问题是想看看是否有人能帮助我理解正在发生的事情 首先,我将描述没有任何代码的问题,然后我将介绍一些代码。情况如下: 我的OpenGL应用程序将此图像渲染到多样本帧缓冲区: 然后,我将该多采样帧缓冲区blit到常规帧缓冲区(而不是多采样帧缓冲区)中 然后,我使用glReadPixels将RGB数据从常规帧缓冲区读取到一个无符号字节数组中 最后,我使用无符号字节数组调用stbi\u write\u png。结果是: 在我看来,字

几天来,我一直在试图解决这个视觉缺陷,但都没有成功,所以我问这个问题是想看看是否有人能帮助我理解正在发生的事情

首先,我将描述没有任何代码的问题,然后我将介绍一些代码。情况如下:

  • 我的OpenGL应用程序将此图像渲染到多样本帧缓冲区:

  • 然后,我将该多采样帧缓冲区blit到常规帧缓冲区(而不是多采样帧缓冲区)中

  • 然后,我使用
    glReadPixels
    将RGB数据从常规帧缓冲区读取到一个无符号字节数组中

  • 最后,我使用无符号字节数组调用
    stbi\u write\u png
    。结果是:

在我看来,字节的第一行似乎向右移动,这会导致所有其他行移动,从而形成对角线形状

这是我的密码:

  • 要创建多采样帧缓冲区,请执行以下操作:
int-width=450;
内部高度=450;
int numOfSamples=1;
//创建多采样帧缓冲区
glGenFramebuffers(1,&mMultisampleFBO);
glBindFramebuffer(GL_FRAMEBUFFER,mMultisampleFBO);
//创建多采样纹理并将其用作颜色附件
glGenTextures(1,&mm多采样纹理);
glBindTexture(GL_纹理_2D_多采样,mMultisampleTexture);
glTexImage2DMultisample(GL_纹理2D_MULTISAMPLE、numOfSamples、GL_RGB、宽度、高度、GL_TRUE);
glBindTexture(GL_纹理_2D_多样本,0);
glFramebufferTexture2D(GL_帧缓冲区,GL_颜色,GL_附件0,GL_纹理,GL_2D,mMultisampleTexture,0);
//创建多示例renderbuffer对象并将其用作深度附着
glGenRenderbuffers(1,&mmbo);
glBindRenderbuffer(GL_RENDERBUFFER,mmbo);
glRenderbufferStorageMultisample(GL_RENDERBUFFER,numOfSamples,GL_DEPTH_分量,宽度,高度);
glBindRenderbuffer(GL_RENDERBUFFER,0);
glFramebufferRenderbuffer(GL_帧缓冲区、GL_深度_附件、GL_RENDERBUFFER、MMBO);
  • 要创建常规帧缓冲区,请执行以下操作:
//创建常规帧缓冲区
glGenFramebuffers(1,&mRegularFBO);
glBindFramebuffer(GL_FRAMEBUFFER,mRegularFBO);
//创建纹理并将其用作颜色附件
glGenTextures(1和mRegularTexture);
glBindTexture(GLU纹理2D,mRegularTexture);
GLTEXAGE2D(GL_纹理_2D,0,GL_RGB,宽度,高度,0,GL_RGB,GL_无符号_字节,NULL);
glBindTexture(GL_TEXTURE_2D,0);
glFramebufferTexture2D(GL_帧缓冲区,GL_颜色,GL_附件0,GL_纹理,mRegularTexture,0);
  • 请注意,两个帧缓冲区都报告为已完成

  • 要将多样本帧缓冲区blit到常规帧缓冲区中,请从常规帧缓冲区读取并写入PNG图像:

int-width=450;
内部高度=450;
静态GLubyte*数据=新GLubyte[3*450*450];
memset(数据,0,3*宽度*高度);
//将多采样帧缓冲区插入常规帧缓冲区
glBindFramebuffer(GL_READ_FRAMEBUFFER,mMultisampleFBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,mRegularFBO);
glBlitFramebuffer(0,0,宽度,高度,0,0,宽度,高度,GL\u颜色\u缓冲区\u位,GL\u最近);
//从常规帧缓冲区读入数据数组
glBindFramebuffer(GL_FRAMEBUFFER,mRegularFBO);
glReadPixels(0,0,宽度,高度,GL_RGB,GL_无符号字节,数据);
//编写PNG图像
int numOfComponents=3;//RGB
int-stridinbytes=宽度*3;
stbi_write_png(imgName.c_str(),宽度,高度,3,数据,宽度*3);
  • 请注意,glGetError不报告任何错误

我还没能弄清楚到底是怎么回事。谢谢你的帮助

当读取图像时,问题是行的对齐。默认情况下,假定图像每行的起始对齐为4。
由于图像的宽度为450,不能被4整除(450/4=112.5),且格式为RGB(3字节),因此必须更改对齐方式

在读取图像数据之前,更改
GL\u PACK\u对齐方式
():

glPixelStorei(GL\u-PACK\u对齐,1);
glReadPixels(0,0,宽度,高度,GL_RGB,GL_无符号字节,数据);

看起来每行末尾都有填充。因为一行是450*3=1250字节,所以在编写PNG时,有两个填充字节是不需要考虑的。将跨距更改为
width*3+2
(尽管应该计算
2
,而不是硬编码)。默认情况下,行按4字节对齐。您的
write\u png
调用需要一个连续块。根据以下问题将GL_PACK_ALIGNMENT设置为1:在每个阶段转储一个原始图像,并找出步幅的方向wrong@1201ProgramAlarm你的解决方案也解决了我的问题。谢谢大家!@拉比是的,我就是这么说的。我链接的问题正好谈到解包*:)我的应用程序现在运行得很好,谢谢!:-)