OpenTK从dds纹理手动上传Mipmaps不起作用

时间:2019-05-04 19:16:40

标签: c# opengl opentk mipmaps

我有一些dds纹理将完全生成mipmap(通常为10个级别)。据我所知,我只是在加载第一个基本级别,并且正在使用GL.GenerateMipmap(GenerateMipmapTarget.Texture2D)生成mipmap,效果很好。

由于我已经保存了mipmap数据,因此我想将它们手动加载到其余级别,而不是调用-非常昂贵的回调。

这是对应的代码

//Upload to GPU
bufferID = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, bufferID);

//Temp Variables
int w = width;
int h = height;
int mm_count = ddsImage.header.dwMipMapCount;
int temp_size = ddsImage.header.dwPitchOrLinearSize;
int offset = 0;

for (int i=0; i < ddsImage.header.dwMipMapCount; i++)
{
     if (w == 0 || h == 0)
        continue;
     byte[] tex_data = new byte[temp_size];
     Array.Copy(ddsImage.bdata, offset, tex_data, 0, temp_size);
     GL.CompressedTexImage2D(TextureTarget.Texture2D, i, this.pif, w, h, 0, temp_size, tex_data);
     //Console.WriteLine(GL.GetError());
     offset += temp_size;
     temp_size /= 4;
     w = w >> 1;
     h = h >> 1;
}

Console.WriteLine(GL.GetError());
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureLodBias, -0.2f);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) TextureWrapMode.Repeat);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) TextureWrapMode.Repeat);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) TextureMinFilter.LinearMipmapLinear);
//GL.GenerateMipmap(GenerateMipmapTarget.Texture2D); //Generate Mipmaps from the base level
//Console.WriteLine(GL.GetError());

int max_level = 0;
GL.GetTexParameter(TextureTarget.Texture2D, GetTextureParameter.TextureMaxLevel, out max_level);
int base_level = 0;
GL.GetTexParameter(TextureTarget.Texture2D, GetTextureParameter.TextureBaseLevel, out base_level);

int maxsize = Math.Max(height, width);
int p = (int) Math.Floor(Math.Log(maxsize, 2)) + base_level;
int q = Math.Min(p, max_level);

#if(DEBUG)
      //Get all mipmaps
      temp_size = ddsImage.header.dwPitchOrLinearSize;
      for (int i = 0; i < q; i++)
      {
          //Get lowest calculated mipmap
          byte[] pixels = new byte[temp_size];

          //Save to disk
          GL.GetCompressedTexImage(TextureTarget.Texture2D, i, pixels);
          File.WriteAllBytes("Temp\\level" + i.ToString(), pixels);
          temp_size = Math.Max(temp_size / 4, 16);
      }
#endif


ddsImage = null;

ddsImage是保存dds图像信息和所有像素数据的对象。

这些纹理被完全渲染为黑色。如果我取消对mipmap生成这一行的评论,那么一切都将像一个魅力。另外,当我转储mipmap关卡数据时,它们没有损坏。我有一种感觉,我需要以某种方式告诉opengl我定义了多少个mipmap,但是这里的主要问题是,为什么连基本级别都不起作用。至少这一项应该有效。

1 个答案:

答案 0 :(得分:0)

好吧,事实证明,根据https://www.khronos.org/opengl/wiki/Common_Mistakes#Legacy_Generation

,我创建的纹理确实不完整

我按照步骤进行操作,发现在上传纹理数据之前需要设置MAX_LEVEL和BASE_LEVEL参数,这样就可以像魅力一样工作了。

GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBaseLevel, 0);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, 8);

最大级别的值应该为mips - 1。但是由于某种原因,当我尝试使用图像的所有mipmap时,纹理再次变为黑色。我仍然没有对其进行全面的测试,但是我认为我应该完全省略2x2和1x1 mipmap的上传。如果我对此进行测试,我将更新答案。

相关问题