2

I recently updated my loading code for textures and also added some new features like mipmap loading ( the last application has been only 2D so i didn't need them ). But the loaded PVRTC textures stay black when using mipmaps, without mipmaps everything works like expected and also mipmaps are working when using textures like RGBA8888 textures.

Loading of the compressed data:

for (int i = 0; i < source.MipmapCount; i++)
{
    data = source.GetData(i);
    GLTextures.CompressedTexImage2D(TextureType.TEXTURE_2D, i, Format.CompressedFormat.Value, Width >> i, Height >> i, data.Length, data);
    Debug.WriteGLError("Texture2D->CompressedTexImage2D", "MipmapLevel={0}", i);
}

Setup of the filtering:

if (source.MipmapCount == 0)
{
    switch (filterQuality)
    {
        case FilterQuality.Nearest:
            GLTextures.TexParameteri(TextureType.TEXTURE_2D, TexParameter.TEXTURE_MIN_FILTER, (Int32)TextureMinFilterParams.NEAREST);
            GLTextures.TexParameteri(TextureType.TEXTURE_2D, TexParameter.TEXTURE_MAG_FILTER, (Int32)TextureMagFilterParams.NEAREST);
            break;
        case FilterQuality.Linear:
            GLTextures.TexParameteri(TextureType.TEXTURE_2D, TexParameter.TEXTURE_MIN_FILTER, (Int32)TextureMinFilterParams.LINEAR);
            GLTextures.TexParameteri(TextureType.TEXTURE_2D, TexParameter.TEXTURE_MAG_FILTER, (Int32)TextureMagFilterParams.LINEAR);
            break;
    }
    Debug.WriteGLError("Texture2D->TexParameteri without mipmaps");
}
else
{
    switch (filterQuality)
    {
        case FilterQuality.Nearest:
            GLTextures.TexParameteri(TextureType.TEXTURE_2D, TexParameter.TEXTURE_MIN_FILTER, (Int32)TextureMinFilterParams.NEAREST_MIPMAP_LINEAR);
            GLTextures.TexParameteri(TextureType.TEXTURE_2D, TexParameter.TEXTURE_MAG_FILTER, (Int32)TextureMagFilterParams.NEAREST);
            break;
        case FilterQuality.Linear:
            GLTextures.TexParameteri(TextureType.TEXTURE_2D, TexParameter.TEXTURE_MIN_FILTER, (Int32)TextureMinFilterParams.LINEAR_MIPMAP_LINEAR);
            GLTextures.TexParameteri(TextureType.TEXTURE_2D, TexParameter.TEXTURE_MAG_FILTER, (Int32)TextureMagFilterParams.LINEAR);
            break;
    }

    Debug.WriteGLError("Texture2D->TexParameteri with mipmaps");

    if (anisotropicQuality > 1f && GL.IsExtensionSupported(Extension.GL_EXT_texture_filter_anisotropic))
    {
        // GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 
        GLTextures.TexParameter(TextureType.TEXTURE_2D, 0x84FF, Mathf.Clamp(anisotropicQuality, 1f, GL.GetFloat(GetFloatName.TEXTURE_MAX_ANISOTROPY)));
        Debug.WriteGLError("Texture2D->Anisotropy");
    }
}

Loading of the texture The loading is done with a modified reference-loader for PVR files. I checked the length of the bytes of each mipmap and the last few arrays have the size of 32 bytes ( minimum size of PVRTC ). What could cause the issue?

Edit

The method "GLTextures.CompressedTexImage2D".

public static void CompressedTexImage2D(TextureType target, Int32 level, CompressedFormats internalFormat, Int32 width, Int32 height, Int32 imageSize, Byte[] pixels)
{
    /* Used for mobile apps for debugging purposes */
    Debug.CheckMethodLoaded(glCompressedTexImage2D);
    Profiler.IncreaseCallCount("glCompressedTexImage2D");
    glCompressedTexImage2D(target, level, internalFormat, width, height, 0, imageSize, pixels);
}

Image formats definition:

PVRTC2RGB = new ImageFormat("PVRTC2RGB", CompressedFormats.COMPRESSED_RGB_PVRTC_2BPPV1_IMG, 16, 8, bitsPerPixel: 2, requiredExtension:Extension.GL_IMG_texture_compression_pvrtc);
PVRTC2RGBA = new ImageFormat("PVRTC2RGBA", CompressedFormats.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG, 16, 8, bitsPerPixel: 2, requiredExtension: Extension.GL_IMG_texture_compression_pvrtc);
PVRTC4RGB = new ImageFormat("PVRTC4RGB", CompressedFormats.COMPRESSED_RGB_PVRTC_4BPPV1_IMG, 8, 8, bitsPerPixel: 4, requiredExtension: Extension.GL_IMG_texture_compression_pvrtc);
PVRTC4RGBA = new ImageFormat("PVRTC4RGBA", CompressedFormats.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG, 8, 8, bitsPerPixel: 4, requiredExtension: Extension.GL_IMG_texture_compression_pvrtc);
Community
  • 1
  • 1
Felix K.
  • 6,201
  • 2
  • 38
  • 71
  • Are you sure `source.GetData(i)` returns correct data? You should check not only length of input but values too. If you are extracting textures from .PVR file please ensure that you are reading correct data - IIRC, there are 2 types of headers. Also, it is unclear what is inside of `GLTextures.CompressedTexImage2D()` method. – keaukraine Jan 29 '13 at 08:57
  • Can I suggest you try asking the question on the Imagination technologies (i.e. PowerVR) dev forum (http://forum.imgtec.com/categories/powervr-graphics). I'd love to help directly but my OpenGL ES is too rusty. – Simon F Jan 29 '13 at 10:04
  • @keaukraine Yes it should, the loader only supports the newer file header right now and throws a exception when using the old one. Which is not used by my graphic guy anyway. I could post the code which loads the PVR but its really a lot of code. `GLTextures.CompressedTexImage2D()` is just a wrapper to the native method. I will add it to the question. If you think you need the PVR code i will post it. – Felix K. Jan 29 '13 at 10:30
  • May be you've messed PVRTC format, there are 4 of them: 2 or 4 bits with or without alpha. Do you use any blending? If alpha channel gets messed up it may lead to black color. If you use OpenGL ES 2.0, you can try to alter fragment shader to see if all RGB (A if needed) channels are OK. – keaukraine Jan 29 '13 at 10:54
  • @keaukraine Yes i know, i added the format definition above which shows the constants i used ( packed in enums to make life easier 9. Also it's working when only using one mipmap image ( Don't load the others ). – Felix K. Jan 29 '13 at 11:06

4 Answers4

2

I just came across a similar issue using cocos2d-x. After a lot of debugging I finally figured it out : make sure you are supplying a complete mipmap chain (down to 1x1) or set Apple's GL_TEXTURE_MAX_LEVEL_APPLE texture parameter to the correct number of mipmaps. Unfortunately, Apple's own TextureTool output only down to 8x8 (with was supposed to be the lower limit but it's not anymore). Even PVRTextureLoader sample code from Apple doesn't works out of the box.

1

edit: correction.

I believe your texture min/mag filters must be:

  • GL_LINEAR_MIPMAP_NEAREST for the min filter
  • GL_LINEAR for the mag filter

when using mipmaps with PVRTC. See the header file at: http://ne3d.googlecode.com/svn-history/r3/trunk/Lib/SRC/Tools/OGLES/PVRTTextureAPI.h

sheu
  • 5,653
  • 17
  • 32
  • You are right, in my code for loading ETC1 mip-mapped textures I use the same min/mag filters. This seems to be correct setup. – keaukraine Jan 29 '13 at 11:29
  • Just checked it on the simulator and it does not solve the problem, they are still black when using mipmaps ( Checked the mipmaps again and saw that all levels have data ). But this doesn't mean that it is not part of the problem. I going to test it on the iPad later, maybe there is a simulator issue too. – Felix K. Jan 29 '13 at 12:26
0

Be sure your "imageSize" in glCompressedTexImage2D is bigger than 32 at any mipmap level.

wpp
  • 1
  • Bigger or Bigger or Equal? Because as i said all mipmaps have the minimum size of 32 bytes. – Felix K. Mar 01 '13 at 12:41
  • sorry, I don't see that. it seem is the same problem. good luck. this is some pvrt rule * Height and width must be at least 8. * Height and width must be a power of 2. * Must be square (height==width)。 – wpp Mar 02 '13 at 06:35
0

To achieve mipmap "effect" on PVRTC texture, you should use:

  • use filter GL_LINEAR.
  • fetch texture color using texture2DLod(EXT) with lod value calculated by yourself.
Felix K.
  • 6,201
  • 2
  • 38
  • 71
  • 2
    (This post does not seem to provide a [quality answer](https://stackoverflow.com/help/how-to-answer) to the question. Please either edit your answer, or just post it as a comment to the question). – sɐunıɔןɐqɐp Aug 05 '18 at 15:22
  • @sɐunıɔןɐqɐp I agree, it's also answered. Also texture2DLod is used fo fetch a single LOD level, something you usually don't want to do manually. – Felix K. Aug 05 '18 at 18:11