- November 2, 2010 at 7:45 pm #30336
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?
Deep 2010-11-02 21:35:15November 3, 2010 at 10:22 am #34478
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.November 12, 2010 at 2:04 pm #34480
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 4×4, 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?November 17, 2010 at 1:24 pm #34481
Any insight anyone can provide here would be greatly appreciated. I’m kind of stuck on this one at the moment.November 17, 2010 at 10:50 pm #34482
I’m curious: what do you mean by code “that assumes the block size for compressed textures is 4×4”? (As far as I understand the PowerVR compression, it uses 4(!) blocks of 4×4 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 4×4 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?November 18, 2010 at 3:50 pm #34483
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 4×4 pixels in the case of
PVRTC4bpp, and 8×4 pixels in the case of PVRTC2bpp”. My application was written for S3TC compression, which uses 4×4 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.November 18, 2010 at 5:21 pm #34484
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?November 18, 2010 at 8:02 pm #34485
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 4×4 block of RGBA colors with 8 bits per channel requires 4x4x4x8 bits = 512 bits; however, the compressed 4×4 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.November 18, 2010 at 9:05 pm #34486
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.November 18, 2010 at 9:07 pm #34487
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.November 23, 2010 at 6:29 pm #34488
If the PVRTC4bpp corresponds to blocks that are 4×4 pixels in size, why does the pvrtc_compress() function only support sizes down to 8×8? For S3TC textures we always just set the 1×1 and 2×2 mipmaps equal to the 4×4 one. For PVRTC4bpp is the recommendation to set the 1×1, 2×2, and 4×4 mipmaps equal to the 8×8?November 23, 2010 at 7:39 pm #34489
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.November 25, 2010 at 3:07 pm #34490
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 8×8 (or 8×16) images are acceptable due to the format requiring 4 data blocks in order to reconstruct any given pixel. Repeating smaller textures across 8×8 images (e.g. four 4×4 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.