Parcourir la source

Support for 16-bit textures

Üstün Ergenoglu il y a 10 ans
Parent
commit
3bc43223e9
2 fichiers modifiés avec 108 ajouts et 48 suppressions
  1. 92 44
      gameplay/src/Texture.cpp
  2. 16 4
      gameplay/src/Texture.h

+ 92 - 44
gameplay/src/Texture.cpp

@@ -161,12 +161,86 @@ Texture* Texture::create(Image* image, bool generateMipmaps)
     }
 }
 
+GLint Texture::getFormatInternal(Format format)
+{
+    switch (format)
+    {
+        case Texture::RGB888:
+        case Texture::RGB565:
+            return GL_RGB;
+        case Texture::RGBA8888:
+        case Texture::RGBA4444:
+        case Texture::RGBA5551:
+            return GL_RGBA;
+        case Texture::ALPHA:
+            return GL_ALPHA;
+        case Texture::DEPTH:
+#if !defined(OPENGL_ES) || defined(GL_ES_VERSION_3_0)
+            return GL_DEPTH_COMPONENT32F;
+#else
+            return GL_DEPTH_COMPONENT;
+#endif
+        default:
+            return 0;
+    }
+}
+
+GLenum Texture::getFormatTexel(Format format)
+{
+    switch (format)
+    {
+        case Texture::RGB888:
+        case Texture::RGBA8888:
+        case Texture::ALPHA:
+            return GL_UNSIGNED_BYTE;
+        case Texture::RGB565:
+            return GL_UNSIGNED_SHORT_5_6_5;
+        case Texture::RGBA4444:
+            return GL_UNSIGNED_SHORT_4_4_4_4;
+        case Texture::RGBA5551:
+            return GL_UNSIGNED_SHORT_5_5_5_1;
+        case Texture::DEPTH:
+#if !defined(OPENGL_ES) || defined(GL_ES_VERSION_3_0)
+            return GL_FLOAT;
+#else
+            return GL_UNSIGNED_INT;
+#endif
+        default:
+            return 0;
+    }
+}
+
+size_t Texture::getFormatBPP(Format format)
+{
+        switch (format)
+        {
+            case Texture::RGB565:
+            case Texture::RGBA4444:
+            case Texture::RGBA5551:
+                return 2;
+            case Texture::RGB888:
+                return 3;
+            case Texture::RGBA8888:
+                return 4;
+            case Texture::ALPHA:
+                return 1;
+            default:
+                return 0;
+        }
+}
+
 Texture* Texture::create(Format format, unsigned int width, unsigned int height, const unsigned char* data, bool generateMipmaps, Texture::Type type)
 {
     GP_ASSERT( type == Texture::TEXTURE_2D || type == Texture::TEXTURE_CUBE );
 
     GLenum target = (GLenum)type;
 
+    GLint internalFormat = getFormatInternal(format);
+    GP_ASSERT( internalFormat != 0 );
+
+    GLenum texelType = getFormatTexel(format);
+    GP_ASSERT( texelType != 0 );
+
     // Create the texture.
     GLuint textureId;
     GL_ASSERT( glGenTextures(1, &textureId) );
@@ -180,50 +254,28 @@ Texture* Texture::create(Format format, unsigned int width, unsigned int height,
 #endif
 
     // Load the texture
+    size_t bpp = getFormatBPP(format);
     if (type == Texture::TEXTURE_2D)
     {
-        // Texture 2D
-        if (format == Texture::DEPTH)
-        {
-#if !defined(OPENGL_ES) || defined(GL_ES_VERSION_3_0) && GL_ES_VERSION_3_0
-    		GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, data) );
-#else
-    		GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, data) );
-#endif    		
-        }
-        else
-        {
-    		GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, (GLenum)format, width, height, 0, (GLenum)format, GL_UNSIGNED_BYTE, data) );
-    	}
+        GLenum f = (format == Texture::DEPTH) ? GL_DEPTH_COMPONENT : internalFormat;
+        GL_ASSERT( glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, f, texelType, data) );
     }
     else
     {
         // Get texture size
         unsigned int textureSize = width * height;
-        switch (format)
+        if (bpp == 0)
         {
-            case Texture::RGB:
-                textureSize *= 3;
-                break;
-            case Texture::RGBA:
-                textureSize *= 4;
-                break;
-            case Texture::ALPHA:
-                break;
-            case Texture::UNKNOWN:
-                if (data)
-                {
-                    glDeleteTextures(1, &textureId);
-                    GP_ERROR("Failed to determine texture size because format is UNKNOWN.");
-                    return NULL;
-                }
-                break;
+            glDeleteTextures(1, &textureId);
+            GP_ERROR("Failed to determine texture size because format is UNKNOWN.");
+            return NULL;
         }
+        textureSize *= bpp;
         // Texture Cube
         for (unsigned int i = 0; i < 6; i++)
         {
             const unsigned char* texturePtr = (data == NULL) ? NULL : &data[i * textureSize];
-            GL_ASSERT( glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, (GLenum)format, width, height, 0, (GLenum)format, GL_UNSIGNED_BYTE, texturePtr) );
+            GL_ASSERT( glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalFormat, width, height, 0, internalFormat, texelType, texturePtr) );
         }
     }
 
@@ -253,6 +305,9 @@ Texture* Texture::create(Format format, unsigned int width, unsigned int height,
     texture->_width = width;
     texture->_height = height;
     texture->_minFilter = minFilter;
+    texture->_internalFormat = internalFormat;
+    texture->_texelType = texelType;
+    texture->_bpp = bpp;
     if (generateMipmaps)
         texture->generateMipmaps();
 
@@ -289,6 +344,9 @@ Texture* Texture::create(TextureHandle handle, int width, int height, Format for
     texture->_format = format;
     texture->_width = width;
     texture->_height = height;
+    texture->_internalFormat = getFormatInternal(format);
+    texture->_texelType = getFormatTexel(format);
+    texture->_bpp = getFormatBPP(format);
 
     return texture;
 }
@@ -304,27 +362,17 @@ void Texture::setData(const unsigned char* data)
 
     if (_type == Texture::TEXTURE_2D)
     {
-        GL_ASSERT( glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _width, _height, (GLenum)_format, GL_UNSIGNED_BYTE, data) );
+        GL_ASSERT( glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _width, _height, _internalFormat, _texelType, data) );
     }
     else
     {
         // Get texture size
         unsigned int textureSize = _width * _height;
-        switch (_format)
-        {
-            case Texture::RGB:
-                textureSize *= 3;
-                break;
-            case Texture::RGBA:
-                textureSize *= 4;
-                break;
-            case Texture::ALPHA:
-                break;
-        }
+        textureSize *= _bpp;
         // Texture Cube
         for (unsigned int i = 0; i < 6; i++)
         {
-            GL_ASSERT( glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _width, _height, (GLenum)_format, GL_UNSIGNED_BYTE, &data[i * textureSize]) );
+            GL_ASSERT( glTexSubImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, _width, _height, _internalFormat, _texelType, &data[i * textureSize]) );
         }
     }
 

+ 16 - 4
gameplay/src/Texture.h

@@ -24,10 +24,15 @@ public:
     enum Format
     {
         UNKNOWN = 0,
-        RGB     = GL_RGB,
-        RGBA    = GL_RGBA,
-        ALPHA   = GL_ALPHA,
-        DEPTH	= GL_DEPTH_COMPONENT,
+        RGB,
+        RGB888 = RGB,
+        RGB565,
+        RGBA,
+        RGBA8888 = RGBA,
+        RGBA4444,
+        RGBA5551,
+        ALPHA,
+        DEPTH,
     };
 
     /**
@@ -326,6 +331,9 @@ private:
     static GLubyte* readCompressedPVRTCLegacy(const char* path, Stream* stream, GLsizei* width, GLsizei* height, GLenum* format, unsigned int* mipMapCount, unsigned int* faceCount, GLenum faces[6]);
 
     static int getMaskByteIndex(unsigned int mask);
+    static GLint getFormatInternal(Format format);
+    static GLenum getFormatTexel(Format format);
+    static size_t getFormatBPP(Format format);
 
     std::string _path;
     TextureHandle _handle;
@@ -341,6 +349,10 @@ private:
     Wrap _wrapR;
     Filter _minFilter;
     Filter _magFilter;
+
+    GLint _internalFormat;
+    GLenum _texelType;
+    size_t _bpp;
 };
 
 }