opengl 如何使用glReadPixels()从FBO返回调整大小后的图像?

xpcnnkqh  于 2022-11-04  发布在  其他
关注(0)|答案(2)|浏览(385)

简短:我需要一个快速的方法来调整缓冲区图像,然后返回像素给我保存到文件等。
目前,我首先使用glReadPixels(),然后使用自己的resize函数亲自检查像素大小。
有没有什么方法可以加快调整大小的速度,例如让OpenGL为我做这项工作?我想我可以使用glGetTexImage()并启用miplevel和mipmapping,但正如我之前注意到的,这个功能在我的GFX卡上有bug,所以我不能使用它。
我只需要一个miplevel,它可以是1到4之间的任何值,但不是全部,以节省一些GPU内存。那么,是否可以只生成一个所需大小的miplevel呢?

**注:**我不认为我可以使用多采样,因为我需要像素精确渲染的模板测试,所以如果我渲染它与多采样,它会使模糊像素,他们会失败的模板测试和遮罩和结果将是不正确的(AFAIK)。**编辑:**我只想缩放颜色(RGBA)缓冲区!

ctrmrzij

ctrmrzij1#

如果你有OpenGL 3.0或者EXT_framebuffer_blit(很有可能--大约2005年以来的所有nVidia卡,大约2008年以来的所有ATI卡都有它,甚至英特尔高清显卡也声称支持它),那么你可以将glBlitFramebuffer[EXT]转换为一个较小的帧缓冲区(具有相应较小的矩形),并让显卡来完成这项工作。
请注意,即使您说“我不需要原始的”,您也不能在同一个帧缓冲区内安全地重新缩放,因为重叠的位块是未定义的(* 允许 *,但未定义)。
或者,您当然可以使用简单的缩小像素着色器(如果需要,可以使用aniso decimation)绘制一个全屏四边形。
事实上,既然你在最后一段提到了模板...如果它是 * 模板 *(或深度),那么你肯定会想用着色器绘制一个全屏四边形,因为它很可能不会给予想要的结果。通常,在这种情况下,人们会选择max过滤器而不是插值(例如,对模板值0和值10进行插值可以得到什么合理的、有意义的结果--需要其他的东西,诸如“任何非零”或“样本区域中的最大值”)。

eivgtgni

eivgtgni2#

创建所需目标大小的帧缓冲区,并使用完全调整大小的缓冲区大小的纹理四边形绘制源图像。然后使用glReadPixels读取调整大小的帧缓冲区内容。
伪代码:

unbind_texture(OriginalSizeFBOattachmentColorTex);

glBindFramebuffer(OriginalSizeFBO);
render_picture();

glBindFramebuffer(TargetSizeFBO); // TargetSizeFBO used a Renderbuffer color attachment
glBindTexture(OriginalSizeFBOattachmentColorTex);
glViewport(TargetSize);
render_full_viewport_quad_with_texture();

glReadPixels(...);

相关问题