Imagination PowerVR SDK Blog

PVRTexLib GenerateMIPMaps / Resize returns false




I’ve been trying to Resize / GenerateMipmaps for quite a while now without success, the function always returns false.
At a high level, I load my images using the freeimage library, convert them to 32 bit and pass the data pointer my compression routines. There, I create a new CPVRTexture, passing the data pointer and taking great care at setting the PixelFormat / ChannelType correctly.
I can then Transcode the texture correctly to a PVRTCI4Bpp format for example and save the texture without problem.
When I open the pvr with PVRTexToolGUI, the texture is as expected. Perfect.

But as soon as I try to GenerateMipmaps, wether it is before or after the Transcode operation, the function returns false.
I know about the limitations: The texture has to have square power of two dimensions but it never worked.
So I thought my configuration was maybe a bit tricky (it’s a bit more complex than described here) so I decided to start a new project from scratch and test it on a pvr file starting with the sample code from the documentation. The calls to Resize and GenerateMipmaps still return false. This is where I would love some error reporting for instance.

Any ideas ?



#include "stdafx.h"

#include "PVRTexture.h"

#include "PVRTextureUtilities.h"

using namespace pvrtexture;

int _tmain(int argc, _TCHAR* argv[])


  bool result;

  const char* filePath = "C:\Sparks\AssetsBuild\Froggle\iPhone4\MultiplierJump3X.pvr";

  // Open and reads a pvr texture from the file location specified by filePath

  CPVRTexture cTexture(filePath);

  PixelType PVRTC4BPP( PVRStandard8PixelType ); // Compress to PVRTC 4bpp.

  result = Resize(cTexture, 16, 16, 1, eResizeLinear);

  // Convert the image to a Normal Map with a scale of 5.0, and y/z/x channel order

  result = GenerateNormalMap(cTexture, 5.0, "yzx");

  // Generate MIP-map chain

  result = GenerateMIPMaps(cTexture, eResizeLinear);

  // False colour the MIP-map levels

  result = ColourMIPMaps(cTexture);

  // Compress to PVRTC 4bpp.

  result = Transcode(cTexture, PVRTC4BPP, ePVRTVarTypeUnsignedInteger, ePVRTCSpacelRGB);

  // Save the file

  result = cTexture.saveFile("C:\Sparks\AssetsBuild\Froggle\iPhone4\MultiplierJump3XM.pvr");

  return 0;



Figured it out thanks to this post as Tobias says:

Most importantly, how are you specifying the texture’s format? The pre-processor functions will only work on uncompressed images in the format that PVRTexLib expects (RGBA 8 8 8 8, RGBA 16 16 16 16 or RGBA 32 32 32 32 - with pixel types of unsigned byte norm, unsigned short norm or unsigned integer norm respectively. 32 bit float is also valid.



My pixel channel type was of the correct unsigned byte norm but I forgot that I was forging my PixelType on the fly to follow my source buffer BGRA8888 format.
Question though:

What really happens during a Transcode from BGRA8888 to PVRStandard8PixelType ?
Are the bytes swapped ? or is the buffer re-allocated ?
I also might want to control the downscaling of my mipmaps using freeimage’s powerful scaling functions.
Is there a way to provide the data for all my mipmap levels manually and not use GenerateMIPMaps ?




Hi Micha,

Glad you figured out how to make this work - using any non-compressed formats at all is something that we plan to add to PVRTexLib at some point, but currently the code base we have to do this is too slow so hasn't yet been integrated.

Currently the transcode function does a simple reallocation of a new buffer and transcodes data into that via a generic encoding method. You could use the CopyChannels function to do it faster as a straight swap instead, and just manually set the pixel format.

You can use the getDataPtr() function to return a pointer to the correct MIP-Map level and simply overwrite the data there to add custom MIP levels.



Tobias2012-06-07 09:39:06