Commits

aradeski  committed 2ae7652

Reworked PVR Texture loader to support many more options in PVR file.

  • Participants
  • Parent commits cdab608

Comments (0)

Files changed (1)

File OgreMain/src/OgrePVRTCCodec.cpp

 #include "OgreStringConverter.h"
 
 #define FOURCC(c0, c1, c2, c3) (c0 | (c1 << 8) | (c2 << 16) | (c3 << 24))
-#define PVR_TEXTURE_FLAG_TYPE_MASK	0xff
 
 namespace Ogre {
 	
 
     const uint32 PVR_MAGIC = FOURCC('P', 'V', 'R', '!');
 
-    enum
-    {
-        kPVRTextureFlagTypePVRTC_2 = 24,
-        kPVRTextureFlagTypePVRTC_4
+    enum  PixelType {
+        OGL_RGBA_4444= 0x10,
+        OGL_RGBA_5551,
+        OGL_RGBA_8888,
+        OGL_RGB_565,
+        OGL_RGB_555,
+        OGL_RGB_888,
+        OGL_I_8,
+        OGL_AI_88,
+        OGL_PVRTC2,
+        OGL_PVRTC4,
+    };
+
+    enum Flags {
+        PVR_HAS_MIPMAPS = 0x100,
+        PVR_TWIDDLED = 0x200,
+        PVR_NORMAL_MAP = 0x400,
+        PVR_ADDED_BORDER = 0x800,
+        PVR_IS_CUBE_MAP = 0x1000,
+        PVR_MIPMAP_IN_FALSE_COLOUR = 0x2000,
+        PVR_IS_VOLUME_TEXTURE = 0x4000,
+        PVR_APLHA_APPLIED = 0x8000,
+        PVR_IS_VFLIPPED = 0x10000,
+        PVR_PIXEL_TYPE_MASK = 0xFF
     };
     
     typedef struct _PVRTCTexHeader
     {
         PVRTCTexHeader header;
         uint32 flags = 0, pvrTag = 0, formatFlags = 0;
-        size_t numFaces = 1; // Assume one face until we know otherwise
 
         ImageData *imgData = OGRE_NEW ImageData();
 		MemoryDataStreamPtr output;
         // Get format flags
         flags = header.flags;
         flipEndian((void *)flags, sizeof(uint32));
-        formatFlags = flags & PVR_TEXTURE_FLAG_TYPE_MASK;
 
         uint32 bitmaskAlpha = header.bitmaskAlpha;
         flipEndian((void *)bitmaskAlpha, sizeof(uint32));
 
-        if (formatFlags == kPVRTextureFlagTypePVRTC_4 || formatFlags == kPVRTextureFlagTypePVRTC_2)
-        {
-            if (formatFlags == kPVRTextureFlagTypePVRTC_4)
-            {
-                imgData->format = bitmaskAlpha ? PF_PVRTC_RGBA4 : PF_PVRTC_RGB4;
-            }
-            else if (formatFlags == kPVRTextureFlagTypePVRTC_2)
-            {
-                imgData->format = bitmaskAlpha ? PF_PVRTC_RGBA2 : PF_PVRTC_RGB2;
-            }
-
-            imgData->depth = 1;
-            imgData->width = header.width;
-            imgData->height = header.height;
-            imgData->num_mipmaps = static_cast<ushort>(header.numMipmaps);
-
+        uint32 pt = flags & PVR_PIXEL_TYPE_MASK;
+        switch (pt) {
+        case OGL_RGBA_4444:
+            imgData->format = PF_A4R4G4B4;
+            break;
+        case OGL_RGBA_5551:
+            imgData->format = PF_A1R5G5B5;
+            break;
+        case OGL_RGBA_8888:
+            imgData->format = PF_R8G8B8A8;
+            break;
+        case OGL_RGB_565:
+            imgData->format = PF_R5G6B5;
+            break;
+        case OGL_RGB_888:
+            imgData->format = PF_R8G8B8;
+            break;
+        case OGL_I_8:
+            imgData->format = PF_L8;
+            break;
+        case OGL_PVRTC4:
+            // check for alpha component
+            imgData->format = bitmaskAlpha ? PF_PVRTC_RGBA4 : PF_PVRTC_RGB4;
             // PVRTC is a compressed format
             imgData->flags |= IF_COMPRESSED;
+            break;
+        case OGL_PVRTC2:
+            //check for alpha component
+            imgData->format = bitmaskAlpha ? PF_PVRTC_RGBA2 : PF_PVRTC_RGB2;
+            // PVRTC is a compressed format
+            imgData->flags |= IF_COMPRESSED;
+            break;
+        default:
+            StringStream ss;
+            ss << "Unsupported PVR pixel type: " << pt;
+            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, ss.str(), "PVRTCCodec::decode");
+
+        };
+
+        size_t numFaces = 1; // Assume one face until we know otherwise
+        imgData->depth = 1;
+
+        if (flags & PVR_IS_CUBE_MAP) {
+            numFaces = 6;
+            imgData->flags |= IF_CUBEMAP;
+        } else if (flags & PVR_IS_VOLUME_TEXTURE) {
+            OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
+                        "PVR Volume Surface not supported!", "PVRTCCodec::decode");
+            //TODO volume texture support
+            //imgData->flags |= IF_3D_TEXTURE;
+            //imgData->depth = header.numSurfs;
         }
 
+        imgData->num_mipmaps = static_cast<ushort>(header.numMipmaps);
+        imgData->width = header.width;
+        imgData->height = header.height;
+
         // Calculate total size from number of mipmaps, faces and size
 		imgData->size = Image::calculateSize(imgData->num_mipmaps, numFaces, 
                                              imgData->width, imgData->height, imgData->depth, imgData->format);