OpenGL - 加载纹理数据之前的 glGenerateMipmap
OpenGL - glGenerateMipmap before loading texture data
在我的代码中,我在实际加载纹理数据之前调用了 glGenerateMipmap
(使用 glTexImage2D
),但我注意到它似乎仍然有效...
这是为什么?调用 glGenerateMipmap
是否会导致未来 glTexImage2D
调用也创建 mipmap 数据?
代码(我使用 C# 和 OpenTK):
int id = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, id);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.LinearMipmapLinear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
// if I comment this line it results in triangles being black - suggesting mipmaps are being used
// (otherwise it works just fine)
GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmpData.Width, bmpData.Height, 0,
OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmpData.Scan0);
bitmap.UnlockBits(bmpData);
glGenerateMipmap()
取base level图片的current content(其中base level是设置为GL_TEXTURE_BASE_LEVEL
的level,默认为0),并生成从基本级别 + 1 到最大级别的所有 mipmap 级别。
这意味着 glGenerateMipmap()
对以后调用 glTexImage2D()
没有影响。如果您希望在使用 glTexImage2D()
或 glTexSubImage2D()
等调用修改纹理数据后更新 mipmap,您必须再次调用 glGenerateMipmap()
。
如果您的 mipmap 看起来是自动更新的,我可以想到两种可能的解释:
- 您的 OpenGL 实现做了一些规范没有要求的事情。事实上,我认为它已损坏,因为它不应该更改未被您的
glTex[Sub]Image2D()
调用明确修改的纹理级别。之前生成的 mipmap 应该保持不变。
- 您并没有真正使用 mipmapping。您的
GL_TEXTURE_MIN_FILTER
未设置为使用 mipmap,或者 GL_TEXTURE_MAX_LEVEL
/GL_TEXTURE_MAX_LOD
设置为不使用 mipmap。或者更有可能的是,您的纹理并没有根据它们的尺寸和绘制尺寸进行缩小。
兼容性配置文件中有一个 GL_GENERATE_MIPMAP
纹理参数。这会导致在纹理内容发生变化时自动生成 mipmap。
在我的代码中,我在实际加载纹理数据之前调用了 glGenerateMipmap
(使用 glTexImage2D
),但我注意到它似乎仍然有效...
这是为什么?调用 glGenerateMipmap
是否会导致未来 glTexImage2D
调用也创建 mipmap 数据?
代码(我使用 C# 和 OpenTK):
int id = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, id);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) TextureWrapMode.ClampToEdge);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.LinearMipmapLinear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
// if I comment this line it results in triangles being black - suggesting mipmaps are being used
// (otherwise it works just fine)
GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
BitmapData bmpData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmpData.Width, bmpData.Height, 0,
OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, bmpData.Scan0);
bitmap.UnlockBits(bmpData);
glGenerateMipmap()
取base level图片的current content(其中base level是设置为GL_TEXTURE_BASE_LEVEL
的level,默认为0),并生成从基本级别 + 1 到最大级别的所有 mipmap 级别。
这意味着 glGenerateMipmap()
对以后调用 glTexImage2D()
没有影响。如果您希望在使用 glTexImage2D()
或 glTexSubImage2D()
等调用修改纹理数据后更新 mipmap,您必须再次调用 glGenerateMipmap()
。
如果您的 mipmap 看起来是自动更新的,我可以想到两种可能的解释:
- 您的 OpenGL 实现做了一些规范没有要求的事情。事实上,我认为它已损坏,因为它不应该更改未被您的
glTex[Sub]Image2D()
调用明确修改的纹理级别。之前生成的 mipmap 应该保持不变。 - 您并没有真正使用 mipmapping。您的
GL_TEXTURE_MIN_FILTER
未设置为使用 mipmap,或者GL_TEXTURE_MAX_LEVEL
/GL_TEXTURE_MAX_LOD
设置为不使用 mipmap。或者更有可能的是,您的纹理并没有根据它们的尺寸和绘制尺寸进行缩小。
兼容性配置文件中有一个 GL_GENERATE_MIPMAP
纹理参数。这会导致在纹理内容发生变化时自动生成 mipmap。