OpenGL glGeneratemipmap和Framebuffers

时间:2013-12-03 18:56:02

标签: 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. 每帧都必须这样调用吗?
  3. 如果我例如导入漫反射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));
    

1 个答案:

答案 0 :(得分:9)

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

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

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

  2. 您的猜测是正确的,每个帧都会调用glGenerateMipmap,因为渲染到纹理的第一个级别的图像每帧都会更改(因为它正在渲染到)。如果你没有调用这个函数,那么永远不会修改较小的mipmap(如果你要映射这样的纹理,你会在足够远的时候看到未初始化的较小的mipmap级别。)

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