9

我正在忙于动态生成 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,我是否需要绑定并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));
4

1 回答 1

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

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

    将图像加载到纹理的第一层后,您将不得不glGenerateMipmap第二次调用以实际用下采样图像填充较小的层。

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

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

于 2013-12-03T19:28:14.450 回答