My OpenGL application currently supports the following DDS compressed formats:
Now I'm porting to OpenGL ES 2.0 using the PowerVR SDK. As best I can tell from the documentation and headers, my only options for compression formats are:
I don't suppose it's possible that I can use my existing DDS loader to load data into one of these formats is it (i.e. these are actually different storage formats and not just different tokens)?
If I do need to regenerate all of my data, is the PVR format the recommended approach? I'm looking for the solution that would be the most portable across different devices.
If PVR is the recommendation, I assume the pvrtc utility is the way to generate compressed textures of this format?
You’re correct: the PVRTC and ETC formats are very different from the S3TC ones and you won’t be able to use these textures without some kind of conversion (unless you’re on a platform that exposes S3TC texture use - it might be worth checking in the extension string, but I’m pretty certain this won’t be exposed on your target platform).
The most universally supported texture format is ETC, howver there is no support for an alpha channel with this format.
PVRTC does support alpha and is present in all POWERVR devices that make up the majority of mobile 3D platforms at this time. It also offers as good or better compression (4bpp and 2bpp).
The utility you should use to generate these textures is PVRTexTool - if you have a lot of textures then I suggest you make a script that utilises the command line version of this tool to compress your data. PVRTexTool is in the Utilities folder of the SDKs and also available from here:
PVRTexTool can save to DDS although the loading code that we provide uses the .PVR format.
Good information. Thank you.
Using GL_COMPRESSED_TEXTURE_FORMATS to query the available compressed formats on my system (NVIDIA GeForce 6800 Ultra), I get GL_ETC1_RGB8_OES and GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG. Since Imagination provides the OpenGL ES SDK and wrote the texture compression format, I guess I’m surprised that all 4 versions of the PVR format (RGB 2BPP, RGB 4BPP, RGBA 2BPP, RGBA 4BPP) are not available.
I’ve got a fair bit of code in my application that assumes the block size for compressed textures is 4x4, so I’d like to use the 4BPP version.
I also require compressed textures to support alpha, which is one of the reasons I’d like to use the PVR format in the first place.
Is it just a bug that these other formats are not returned by this function? Is there some other version of the SDK that would provide me access to other versions?
Any insight anyone can provide here would be greatly appreciated. I’m kind of stuck on this one at the moment.
I’m curious: what do you mean by code “that assumes the block size for compressed textures is 4x4”? (As far as I understand the PowerVR compression, it uses 4(!) blocks of 4x4 pixels to decode any pixel. I guess there is no block of any size that can be decoded independently of other pixels (apart from the whole image). Therefore, your assumption of a 4x4 block size might not work with the PowerVR compression.)
When you refer to “my system”, is that the PowerVR OpenGL ES 2.0 PC emulation on a PC with an NVIDIA GeForce 6800 Ultra? Wouldn’t it work to have a fallback for the PC emulation to uncompressed textures and only use compressed textures on an actual device?
I’m referring to the comment in the PVRTC Texture Compression Usage Guide “PVRTC is block-based; each block is 64 bit in size and corresponds to 4x4 pixels in the case of
PVRTC4bpp, and 8x4 pixels in the case of PVRTC2bpp”. My application was written for S3TC compression, which uses 4x4 pixels per block. Our code for texture subloading, for example, is written assuming that compressed textures are 1/4 the size of the corresponding uncompressed texture, and I’d like to avoid having to change this if possible.
Yes, when I refer to my system I mean the PC running the emulator. I have things working w/ uncompressed now. I’m just looking to implement and test the compressed textures on the emulator while I’m waiting for the actual target hardware. Also, some parts of our application only used compressed textures, so I will be unable to test them w/o implementing this feature.
This may be a problem in PVRVFrame. I’ve filed an issue BRN31863 in our system and the engineer responsible for PVRVFrame will look at it.
You should be able to use PVRTC textures under PVRVFrame without decompressing them first. If you ignore the results of the glGet do compressed textures upload successfully? Which version of PVRVFrame are you using?
I’m confused by the arithmetics: you say your assumption is that the compressed textures are 1/4 of the size of the corresponding uncompressed texture (as for DXT2, DXT3, DXT4, DXT5). But PVRTC4bpp compresses to 1/8. (An uncompressed 4x4 block of RGBA colors with 8 bits per channel requires 4x4x4x8 bits = 512 bits; however, the compressed 4x4 block in PVRTC4bpp only requires 64 bits, i.e. 1/8.)
As far as I see there is no PowerVR compression scheme with a 4:1 compression; thus, unfortunately, you might have to rewrite your code in any case.
Thanks Gordon. I haven’t tried to ignore glGet and use the tokens anyway yet. I had some other tasks come up and had put this on the back burner while I waited to get a response back from the forum.
I’m using version 2.07.27.0484 of the SDK.
Sorry Martin, I misspoke. I meant per side. You can compute the width of the compressed texture by dividing the width of it non-compressed by 4. This results in the overall size being 1/8 as you said.
If the PVRTC4bpp corresponds to blocks that are 4x4 pixels in size, why does the pvrtc_compress() function only support sizes down to 8x8? For S3TC textures we always just set the 1x1 and 2x2 mipmaps equal to the 4x4 one. For PVRTC4bpp is the recommendation to set the 1x1, 2x2, and 4x4 mipmaps equal to the 8x8?
I implemented the texture compression by ignoring the glGet as you suggested and it worked… well almost.
In pvrtc.h it says that the input array should be in the form (8A 8R 8G 8B). When I put my data in that form, I’m able to render w/ a compressed texture using either GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG or GL_COMPRESSES_RGBA_PVRTC_4BPPV1_IMG, but the colors are off. Doing some trial and error, I see that the color looks correct when I put the input data in the form (8B 8G 8R 8A). Can you confirm that the input format should be BGRA?
In any case, it would appear that there is a bug in glGet() for GL_COMPRESSED_TEXTURE_FORMATS. The about box on PVRFrame says SDK build 2.07.27.0297.
Also, I assume that a return value of ‘1’ for pvrtc_compress() means success? I don’t see anything in the header that indicates what return value I should be checking for an error.
The comment does seem to need review. The RGBA vs RBGA may be a mistake - I’ll double check this and update it if so (BRN31914). The return value is correct for success - I’ll see about adding mention of this too. The issue with GL_COMPRESSED_TEXTURE_FORMATS has been filed and we’ll look into this.
Only 8x8 (or 8x16) images are acceptable due to the format requiring 4 data blocks in order to reconstruct any given pixel. Repeating smaller textures across 8x8 images (e.g. four 4x4 images) allows them to be represented in PVRTC.
The PVRTC library is a raw compressor so this is not done for you. The PVRTexLib library does this automatically for you if you specify a MIP-map chain that is complete and then compress to PVRTC.
Hi all, just to say that this issue has now been resolved. User input is now required in ARGB format as described, and this fix will be applied to the 2.8 release.