【问题标题】:How to determine the width and height of a GL framebuffer object given only the corresponding id如何确定仅给定相应 id 的 GL 帧缓冲区对象的宽度和高度
【发布时间】:2023-03-19 04:36:01
【问题描述】:

我想确定帧缓冲区对象的大小(宽度、高度)。

我通过

创建了一个帧缓冲对象
// create the FBO. 
glGenFramebuffers(1, &fboId);

如何仅在给定帧缓冲区对象 ID (fboId) 的情况下获取第一个颜色附件的大小? 这是可能的还是我必须将颜色附件的大小存储在外部变量中以便以后知道 FBO 的大小?

【问题讨论】:

  • 仅供参考:为了获得更好的服务,请使用 OpenGL 标记来解决 OpenGL 问题,即使是更高版本。大多数 OpenGL 专家关注的是 OpenGL 标记,而不是 OpenGL-3 标记。

标签: c++ opengl opengl-3


【解决方案1】:

您的问题有些混乱,因为您要求的是两种不同的东西。

这是一个简单的问题:

如果仅给定帧缓冲区对象 ID (fboId),如何获取第一个颜色附件的大小?

这很简单:获取附加到该附件的纹理/渲染缓冲区,获取附加的 mipmap 级别和数组层,然后查询纹理/渲染缓冲区的大小。

前两个步骤已完成with glGetFramebufferAttachmentParameter(注意关键字“附件”),用于GL_COLOR_ATTACHMENT0。您查询GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 以获取它是渲染缓冲区还是纹理。您可以使用GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 获取渲染缓冲区/纹理名称。

如果对象是渲染缓冲区,则可以绑定渲染缓冲区并使用glGetRenderbufferParameter 获取渲染缓冲区的GL_RENDERBUFFER_WIDTHGL_RENDERBUFFER_HEIGHT

如果对象是纹理,则需要做更多的工作。需要查询附件参数GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL获取mipmap等级。

当然,现在你需要知道如何绑定它。如果您使用的是 4.4 之前的 OpenGL 版本或没有某些扩展,那么这很复杂。看,你需要知道使用哪个texture target type。尽管这看起来很愚蠢和烦人,但仅从纹理对象名称来确定目标的唯一方法是……尝试一切。遍历每个目标并检查glGetErrorGL_INVALID_OPERATION 没有返回的那个是正确的。

如果您有可用的 GL 4.4 或 ARB_multi_bind,您可以只使用 use glBindTextures(注意“s”),这不需要您指定目标。如果你有 4.5 或ARB_direct_state_access,你根本不需要绑定纹理。 DSA 风格的函数不需要纹理目标,它还提供glBindTextureUnit,将纹理绑定到其自然内部目标。

一旦您绑定了纹理并且它是 mipmap 级别,您就可以通过 use glGetTexLevelParameter 查询该级别的 GL_TEXTURE_WIDTHGL_TEXTURE_HEIGHT

现在,这就是简单的问题。难题是你的标题要求什么:

我想确定帧缓冲区对象的大小(宽度、高度)。

FBO 的可渲染区域的大小与GL_COLOR_ATTACHMENT0 的大小不同。 FBO 的可渲染区域是附加到 FBO 的所有图像的所有尺寸的交集。

除非您对此 FBO 有专门的了解,否则您不能假设该 FBO 仅包含一张图片或所有图片的大小相同(如果您对 FBO 有专门的了解,那么坦率地说,您应该知道它有多大)。因此,您需要对每个 附件重复上述过程(如果类型为GL_NONE,则不附加任何内容)。然后取返回值的交集(即:最小宽度和高度)。

一般来说,您不必询问您创建的 FBO 有多大。就像你不必问纹理它们有多大一样。你创造了它们;根据定义,您知道它们有多大。您将它们放在 FBO 中,所以您再次知道它有多大。

【讨论】:

  • 感谢您的回答(顺便说一句,每次我问 OpenGL 问题时,我都会找到您的答案之一:我不知道您在 SO 上花了多少时间,但您确实值得每一次代表点你有:))
  • 我如何知道将帧缓冲区的附加纹理绑定到哪个目标? (例如 GL_TEXTURE_2D?GL_TEXTURE_CUBE_MAP?等)OBJECT_TYPE 只返回“GL_TEXTURE”,我看不到任何查询实际纹理目标的方法。
  • @namey: 把它绑定为每一个可能的纹理目标; 不会导致错误的那个是正确的。你可能认为我在讽刺,但实际上我是认真的。如果您只有纹理对象,这是了解纹理类型的唯一方法。或者,使用 ARB_direct_state_access,您不必在意。
猜你喜欢
  • 1970-01-01
  • 2020-07-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多