Browse Source

[rl_gputex] Correctly load mipmaps from DDS files (#4399)

Nikolas 10 months ago
parent
commit
902d3c92e3
1 changed files with 10 additions and 3 deletions
  1. 10 3
      src/external/rl_gputex.h

+ 10 - 3
src/external/rl_gputex.h

@@ -185,6 +185,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
                 if (header->ddspf.flags == 0x40)        // No alpha channel
                 {
                     int data_size = image_pixel_size*sizeof(unsigned short);
+                    if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
                     image_data = RL_MALLOC(data_size);
 
                     memcpy(image_data, file_data_ptr, data_size);
@@ -196,6 +197,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
                     if (header->ddspf.a_bit_mask == 0x8000)     // 1bit alpha
                     {
                         int data_size = image_pixel_size*sizeof(unsigned short);
+                        if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
                         image_data = RL_MALLOC(data_size);
 
                         memcpy(image_data, file_data_ptr, data_size);
@@ -215,6 +217,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
                     else if (header->ddspf.a_bit_mask == 0xf000)   // 4bit alpha
                     {
                         int data_size = image_pixel_size*sizeof(unsigned short);
+                        if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
                         image_data = RL_MALLOC(data_size);
 
                         memcpy(image_data, file_data_ptr, data_size);
@@ -236,6 +239,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
             else if ((header->ddspf.flags == 0x40) && (header->ddspf.rgb_bit_count == 24))   // DDS_RGB, no compressed
             {
                 int data_size = image_pixel_size*3*sizeof(unsigned char);
+                if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
                 image_data = RL_MALLOC(data_size);
 
                 memcpy(image_data, file_data_ptr, data_size);
@@ -245,6 +249,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
             else if ((header->ddspf.flags == 0x41) && (header->ddspf.rgb_bit_count == 32)) // DDS_RGBA, no compressed
             {
                 int data_size = image_pixel_size*4*sizeof(unsigned char);
+                if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
                 image_data = RL_MALLOC(data_size);
 
                 memcpy(image_data, file_data_ptr, data_size);
@@ -265,9 +270,11 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
             }
             else if (((header->ddspf.flags == 0x04) || (header->ddspf.flags == 0x05)) && (header->ddspf.fourcc > 0)) // Compressed
             {
-                // NOTE: This forces only 1 mipmap to be loaded which is not really correct but it works
-                int data_size = (header->pitch_or_linear_size < file_size - 0x80) ? header->pitch_or_linear_size : file_size - 0x80;
-                *mips = 1;
+                int data_size = 0;
+
+                // Calculate data size, including all mipmaps
+                if (header->mipmap_count > 1) data_size = header->pitch_or_linear_size + header->pitch_or_linear_size / 3;
+                else data_size = header->pitch_or_linear_size;
 
                 image_data = RL_MALLOC(data_size*sizeof(unsigned char));