我全神贯注于动态生成 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);
我的问题:
- 为什么
glGenerateMipmap
在渲染到纹理的情况下需要调用两次? - 是不是每一帧都要这样调用?
例如,如果我导入一个漫反射 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));
最佳答案
正如您链接到的帖子中所解释的,“[
glGenerateMipmap
] 实际上做了两件事,这可能是它唯一的问题:它分配 mipmap 内存并生成 mipmap。”请注意,在第一个
glGenerateMipmap
调用之前是一个带有 NULL 数据指针的glTexImage2D
调用。这两个调用结合起来将为所有纹理级别简单地分配内存。此时它们包含的数据是垃圾。将图像加载到纹理的第一层后,您将必须再次调用
glGenerateMipmap
以使用缩减采样图像实际填充较小的层。您的猜测是正确的,
glGenerateMipmap
每帧都会被调用,因为渲染到纹理第一层的图像每帧都会发生变化(因为它正在被渲染到)。如果您不调用该函数,则永远不会修改较小的 mipmap(如果您要映射这样的纹理,当距离足够远时,您会看到未初始化的较小 mipmap 级别)。没有。仅当您打算通过使用纹理贴图的纹理过滤模式将纹理映射到三角形时才需要纹理贴图。如果您只处理第一层纹理,则不需要生成 mipmap。事实上,如果您从不映射纹理,则可以使用渲染缓冲区而不是帧缓冲区中的纹理。
关于c++ - OpenGL glGeneratemipmap 和帧缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20359352/