C# 加载纹理数据前的OpenGL-GLGenerateEMIPMAP

C# 加载纹理数据前的OpenGL-GLGenerateEMIPMAP,c#,opengl,mipmaps,C#,Opengl,Mipmaps,在我的代码中,在实际加载纹理数据之前(使用glTexImage2D),我调用了glGenerateMipmap,但我注意到它似乎仍然有效 为什么呢?调用glGenerateMipmap是否也会导致将来的glTexImage2D调用创建mipmap数据 代码(我使用C#和OpenTK): glGenerateMipmap()获取基本级别图像的当前内容(其中基本级别是设置为GL_纹理_基本级别,默认为0的级别),并生成从基本级别+1到最大级别的所有mipmap级别 这意味着glGenerateMip

在我的代码中,在实际加载纹理数据之前(使用
glTexImage2D
),我调用了
glGenerateMipmap
,但我注意到它似乎仍然有效

为什么呢?调用
glGenerateMipmap
是否也会导致将来的
glTexImage2D
调用创建mipmap数据

代码(我使用C#和OpenTK):

glGenerateMipmap()
获取基本级别图像的当前内容(其中基本级别是设置为
GL_纹理_基本级别
,默认为0的级别),并生成从基本级别+1到最大级别的所有mipmap级别

这意味着
glGenerateMipmap()
对以后调用
glTexImage2D()
没有影响。如果希望在使用调用(如
glTexImage2D()
glTexSubImage2D()
)修改纹理数据后更新mipmap,则必须再次调用
glGenerateMipmap()

如果您的mipmap看起来是自动更新的,我可以想出两种可能的解释:

  • 您的OpenGL实现做了一些规范不要求的事情。事实上,我认为它是坏的,因为它不应该更改未被
    glTex[Sub]Image2D()调用显式修改的纹理级别。以前生成的mipmap应保持不变
  • 你没有真正使用mipmapping。您的
    GL\u纹理\u最小\u过滤器
    未设置为使用mipmap,或者
    GL\u纹理\u最大\u级别
    /
    GL\u纹理\u最大\u LOD
    已设置为不使用mipmap。或者更可能的是,您的纹理只是没有根据其尺寸和绘制时的大小进行缩小
  • 兼容性配置文件中有一个
    GL\u GENERATE\u MIPMAP
    纹理参数。这会导致在纹理内容更改时自动生成mipmap。

    glGenerateMipmap()
    获取基本级别图像的当前内容(其中基本级别是设置为
    GL_texture_base_level
    ,默认为0),并生成从基本级别+1到最大级别的所有mipmap级别

    这意味着
    glGenerateMipmap()
    对以后调用
    glTexImage2D()
    没有影响。如果希望在使用调用(如
    glTexImage2D()
    glTexSubImage2D()
    )修改纹理数据后更新mipmap,则必须再次调用
    glGenerateMipmap()

    如果您的mipmap看起来是自动更新的,我可以想出两种可能的解释:

  • 您的OpenGL实现做了一些规范不要求的事情。事实上,我认为它是坏的,因为它不应该更改未被
    glTex[Sub]Image2D()调用显式修改的纹理级别。以前生成的mipmap应保持不变
  • 你没有真正使用mipmapping。您的
    GL\u纹理\u最小\u过滤器
    未设置为使用mipmap,或者
    GL\u纹理\u最大\u级别
    /
    GL\u纹理\u最大\u LOD
    已设置为不使用mipmap。或者更可能的是,您的纹理只是没有根据其尺寸和绘制时的大小进行缩小

  • 兼容性配置文件中有一个
    GL\u GENERATE\u MIPMAP
    纹理参数。这会导致在纹理内容发生变化时自动生成mipmap。

    它不应该以这种方式工作,但当您调用未定义的行为时,一切都是可能的
    glGenerateMipmaps(…)
    获取图像LOD 0,并通过对所有剩余LOD向下采样到1x1来生成mipchain。当然,这只有在分配图像LOD 0时才有意义,直到您调用
    glTexImage2D
    。它不应该以这种方式工作,但当您调用未定义的行为时,一切都是可能的
    glGenerateMipmaps(…)
    获取图像LOD 0,并通过对所有剩余LOD向下采样到1x1来生成mipchain。当然,这只有在分配图像LOD 0时才有意义,直到调用
    glTexImage2D
    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);