c++ - OpenGL glGeneratemipmap 和帧缓冲区

标签 c++ opengl mipmaps

我全神贯注于动态生成 mipmap,并使用以下代码读取此位:http://www.g-truc.net/post-0256.html

//Create the mipmapped texture
glGenTextures(1, &ColorbufferName);
glBindTexture(ColorbufferName);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_UNSIGNED_BYTE, NULL);
glGenerateMipmap(GL_TEXTURE_2D); // /!\ Allocate the mipmaps /!\
...
//Create the framebuffer object and attach the mipmapped texture
glBindFramebuffer(GL_FRAMEBUFFER, FramebufferName);
glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ColorbufferName, 0);
...
//Commands to actually draw something
render();
...
//Generate the mipmaps of ColorbufferName
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, ColorbufferName);
glGenerateMipmap(GL_TEXTURE_2D);

我的问题:

  1. 为什么glGenerateMipmap在渲染到纹理的情况下需要调用两次?
  2. 是不是每一帧都要这样调用?

例如,如果我导入一个漫反射 2d 纹理,我只需要在将它加载到 OpenGL 后调用它一次,如下所示:

    GLCALL(glGenTextures(1, &mTexture));
    GLCALL(glBindTexture(GL_TEXTURE_2D, mTexture));

    GLint format = (colorFormat == ColorFormat::COLOR_FORMAT_RGB ? GL_RGB : colorFormat == ColorFormat::COLOR_FORMAT_RGBA ? GL_RGBA : GL_RED);
    GLCALL(glTexImage2D(GL_TEXTURE_2D, 0, format, textureWidth, textureHeight, 0, format, GL_UNSIGNED_BYTE, &textureData[0]));

    GLCALL(glGenerateMipmap(GL_TEXTURE_2D));
    GLCALL(glBindTexture(GL_TEXTURE_2D, 0));

我怀疑这是因为纹理在每一帧都被重新绘制,并且 mipmap 生成在这个过程中使用了它的内容,但我想确认这一点。

3 - 此外,如果我渲染到我的 gbuffer,然后立即将其 glBlitFramebuffer 渲染到默认 FBO,我是否需要像这样绑定(bind)和 glGenerateMipmap

GLCALL(glBindTexture(GL_TEXTURE_2D, mGBufferTextures[GBuffer::GBUFFER_TEXTURE_DIFFUSE]));
GLCALL(glGenerateMipmap(GL_TEXTURE_2D));
GLCALL(glReadBuffer(GL_COLOR_ATTACHMENT0 + GBuffer::GBUFFER_TEXTURE_DIFFUSE));
GLCALL(glBlitFramebuffer(0, 0, mWindowWidth, mWindowHeight, 0, 0, mWindowWidth, mWindowHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR));

最佳答案

  1. 正如您链接到的帖子中所解释的,“[glGenerateMipmap] 实际上做了两件事,这可能是它唯一的问题:它分配 mipmap 内存并生成 mipmap。”

    请注意,在第一个 glGenerateMipmap 调用之前是一个带有 NULL 数据指针的 glTexImage2D 调用。这两个调用结合起来将为所有纹理级别简单地分配内存。此时它们包含的数据是垃圾。

    将图像加载到纹理的第一层后,您将必须再次调用 glGenerateMipmap 以使用缩减采样图像实际填充较小的层。

  2. 您的猜测是正确的,glGenerateMipmap 每帧都会被调用,因为渲染到纹理第一层的图像每帧都会发生变化(因为它正在被渲染到)。如果您不调用该函数,则永远不会修改较小的 mipmap(如果您要映射这样的纹理,当距离足够远时,您会看到未初始化的较小 mipmap 级别)。

  3. 没有。仅当您打算通过使用纹理贴图的纹理过滤模式将纹理映射到三角形时才需要纹理贴图。如果您只处理第一层纹理,则不需要生成 mipmap。事实上,如果您从不映射纹理,则可以使用渲染缓冲区而不是帧缓冲区中的纹理。

关于c++ - OpenGL glGeneratemipmap 和帧缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20359352/

相关文章:

c++ - 无法在 OpenGL 上使用不同的 VAO 渲染不同的网格

在 Code::Blocks Ubuntu 中找不到 -l<library>

android - 将 Mipmap 文件夹用于启动器图标是否需要最低 SDK?

opengl - GLSL 采样器如何确定纹理的缩小程度以及 mipmap 级别?

以::开头的 C++ 嵌套命名空间定义

c++ - 使用 SWIG 将 Python 数组传递给 c++ 函数

c++ - c++ 的最佳 instanceof 解决方法

c++ - C++98 中的 std::remove_if 用法

c++ - 动态链接库(dll/so)中char*类型的函数参数