Browse Source

add sRGB support to egg-palettize, sluminance to egg

Brian Lach 2 years ago
parent
commit
52d59b2df7

+ 10 - 0
panda/src/egg/eggTexture.cxx

@@ -504,6 +504,7 @@ has_alpha_channel(int num_components) const {
   case F_green:
   case F_blue:
   case F_luminance:
+  case F_sluminance:
   case F_rgb:
   case F_rgb12:
   case F_rgb8:
@@ -520,6 +521,7 @@ has_alpha_channel(int num_components) const {
 
   case F_luminance_alpha:
   case F_luminance_alphamask:
+  case F_sluminance_alpha:
   case F_rgba:
   case F_rgbm:
   case F_rgba12:
@@ -732,6 +734,10 @@ string_format(const string &string) {
     return F_luminance_alpha;
   } else if (cmp_nocase_uh(string, "luminance_alphamask") == 0) {
     return F_luminance_alphamask;
+  } else if (cmp_nocase_uh(string, "sluminance") == 0) {
+    return F_sluminance;
+  } else if (cmp_nocase_uh(string, "sluminance_alpha") == 0) {
+    return F_sluminance_alpha;
   } else {
     return F_unspecified;
   }
@@ -1179,6 +1185,10 @@ ostream &operator << (ostream &out, EggTexture::Format format) {
     return out << "luminance_alpha";
   case EggTexture::F_luminance_alphamask:
     return out << "luminance_alphamask";
+  case EggTexture::F_sluminance:
+    return out << "sluminance";
+  case EggTexture::F_sluminance_alpha:
+    return out << "sluminance_alpha";
   }
 
   nassertr(false, out);

+ 2 - 1
panda/src/egg/eggTexture.h

@@ -63,7 +63,8 @@ PUBLISHED:
     F_luminance_alpha, F_luminance_alphamask,
 
     // Only for compatibility with .bam, use is discouraged!
-    F_srgb, F_srgb_alpha
+    F_srgb, F_srgb_alpha,
+    F_sluminance, F_sluminance_alpha
   };
   enum CompressionMode {
     CM_default, CM_off, CM_on,

+ 10 - 0
panda/src/egg2pg/eggLoader.cxx

@@ -887,12 +887,14 @@ load_texture(TextureDef &def, EggTexture *egg_tex) {
   case EggTexture::F_blue:
   case EggTexture::F_alpha:
   case EggTexture::F_luminance:
+  case EggTexture::F_sluminance:
     wanted_channels = 1;
     wanted_alpha = false;
     break;
 
   case EggTexture::F_luminance_alpha:
   case EggTexture::F_luminance_alphamask:
+  case EggTexture::F_sluminance_alpha:
     wanted_channels = 2;
     wanted_alpha = true;
     break;
@@ -1225,6 +1227,7 @@ check_texture_attributes(Texture *tex, SamplerState sampler, const EggTexture *e
     case EggTexture::F_blue:
     case EggTexture::F_alpha:
     case EggTexture::F_luminance:
+    case EggTexture::F_sluminance:
       break;
     default:
       egg2pg_cat.warning()
@@ -1238,6 +1241,7 @@ check_texture_attributes(Texture *tex, SamplerState sampler, const EggTexture *e
     case EggTexture::F_unspecified:
     case EggTexture::F_luminance_alpha:
     case EggTexture::F_luminance_alphamask:
+    case EggTexture::F_sluminance:
       break;
     default:
       egg2pg_cat.error()
@@ -1389,6 +1393,12 @@ convert_format(EggTexture::Format format, EggTexture::EnvType env) {
 
   case EggTexture::F_srgb_alpha:
     return Texture::F_srgb_alpha;
+
+  case EggTexture::F_sluminance:
+    return Texture::F_sluminance;
+
+  case EggTexture::F_sluminance_alpha:
+    return Texture::F_sluminance_alpha;
   }
 
   egg2pg_cat.warning()

+ 6 - 0
panda/src/egg2pg/eggSaver.cxx

@@ -1462,6 +1462,12 @@ get_egg_texture(Texture *tex) {
       case Texture::F_srgb_alpha:
         temp.set_format(EggTexture::F_srgb_alpha);
         break;
+      case Texture::F_sluminance:
+        temp.set_format(EggTexture::F_sluminance);
+        break;
+      case Texture::F_sluminance_alpha:
+        temp.set_format(EggTexture::F_sluminance_alpha);
+        break;
       default:
         break;
       }

+ 6 - 0
pandatool/src/egg-palettize/eggPalettize.cxx

@@ -321,6 +321,12 @@ describe_input_file() {
             "match the number of channels.  As above, any valid egg texture "
             "format may be used, e.g. force-rgba12, force-rgb5, etc.\n\n");
 
+  show_text("  srgb", 10,
+            "This specifies that this texture is in sRGB space and the format "
+            "should be changed to reflect that.  The texture format will be "
+            "changed to the appropriate sRGB equivalent based on the number "
+            "of image channels.\n\n");
+
   show_text("  keep-format", 10,
             "This specifies that the image format requested by an egg file "
             "should be exactly preserved, without attempting to optimize "

+ 2 - 1
pandatool/src/palettizer/palettizer.cxx

@@ -39,7 +39,7 @@ Palettizer *pal = nullptr;
 // update egg-palettize to write out additional information to its pi file,
 // without having it increment the bam version number for all bam and boo
 // files anywhere in the world.
-int Palettizer::_pi_version = 20;
+int Palettizer::_pi_version = 21;
 /*
  * Updated to version 8 on 32003 to remove extensions from texture key names.
  * Updated to version 9 on 41303 to add a few properties in various places.
@@ -54,6 +54,7 @@ int Palettizer::_pi_version = 20;
  * TextureProperties::_quality_level.  Updated to version 19 on 71609 to add
  * PaletteGroup::_override_margin Updated to version 20 on 72709 to add
  * TexturePlacement::_swapTextures
+ * Updated to version 21 on 110120 to add sRGB support.
  */
 
 int Palettizer::_min_pi_version = 8;

+ 2 - 0
pandatool/src/palettizer/textureImage.cxx

@@ -360,6 +360,8 @@ post_txa_file() {
 
   _properties._anisotropic_degree = _request._anisotropic_degree;
 
+  _properties._srgb = _request._srgb;
+
   if (_properties._color_type == nullptr) {
     _properties._color_type = _request._properties._color_type;
     _properties._alpha_type = _request._properties._alpha_type;

+ 80 - 4
pandatool/src/palettizer/textureProperties.cxx

@@ -42,6 +42,7 @@ TextureProperties() {
   _anisotropic_degree = 0;
   _color_type = nullptr;
   _alpha_type = nullptr;
+  _srgb = false;
 }
 
 /**
@@ -59,6 +60,7 @@ TextureProperties(const TextureProperties &copy) :
   _anisotropic_degree(copy._anisotropic_degree),
   _color_type(copy._color_type),
   _alpha_type(copy._alpha_type),
+  _srgb(copy._srgb),
   _got_num_channels(copy._got_num_channels),
   _num_channels(copy._num_channels),
   _effective_num_channels(copy._effective_num_channels)
@@ -83,6 +85,7 @@ operator = (const TextureProperties &copy) {
   _num_channels = copy._num_channels;
   _effective_num_channels = copy._effective_num_channels;
   _format = copy._format;
+  _srgb = copy._srgb;
 }
 
 /**
@@ -168,6 +171,8 @@ uses_alpha() const {
   case EggTexture::F_alpha:
   case EggTexture::F_luminance_alpha:
   case EggTexture::F_luminance_alphamask:
+  case EggTexture::F_srgb_alpha:
+  case EggTexture::F_sluminance_alpha:
     return true;
 
   default:
@@ -210,6 +215,9 @@ update_properties(const TextureProperties &other) {
     _num_channels = other._num_channels;
     _effective_num_channels = _num_channels;
   }
+
+  _srgb = other._srgb;
+
   if (_force_format) {
     // If we've forced our own format, it doesn't change.
   } else if (other._force_format) {
@@ -260,6 +268,7 @@ fully_define() {
 
     case EggTexture::F_luminance_alpha:
     case EggTexture::F_luminance_alphamask:
+    case EggTexture::F_sluminance_alpha:
       _num_channels = 2;
       break;
 
@@ -268,6 +277,7 @@ fully_define() {
     case EggTexture::F_blue:
     case EggTexture::F_alpha:
     case EggTexture::F_luminance:
+    case EggTexture::F_sluminance:
       _num_channels = 1;
       break;
     }
@@ -294,6 +304,8 @@ fully_define() {
     case EggTexture::F_luminance_alphamask:
     case EggTexture::F_srgb:
     case EggTexture::F_srgb_alpha:
+    case EggTexture::F_sluminance:
+    case EggTexture::F_sluminance_alpha:
       break;
 
     case EggTexture::F_rgba12:
@@ -323,6 +335,7 @@ fully_define() {
       case EggTexture::F_blue:
       case EggTexture::F_alpha:
       case EggTexture::F_luminance:
+      case EggTexture::F_sluminance:
         break;
 
         // These formats suggest an alpha channel; they are quietly replaced
@@ -332,8 +345,16 @@ fully_define() {
         _format = EggTexture::F_luminance;
         break;
 
+      case EggTexture::F_sluminance_alpha:
+        _format = EggTexture::F_sluminance;
+        break;
+
       default:
-        _format = EggTexture::F_luminance;
+        if (_srgb) {
+          _format = EggTexture::F_sluminance;
+        } else {
+          _format = EggTexture::F_luminance;
+        }
       }
       break;
 
@@ -341,6 +362,7 @@ fully_define() {
       switch (_format) {
       case EggTexture::F_luminance_alpha:
       case EggTexture::F_luminance_alphamask:
+      case EggTexture::F_sluminance_alpha:
         break;
 
         // These formats implicitly reduce the number of channels to 1.
@@ -349,10 +371,15 @@ fully_define() {
       case EggTexture::F_blue:
       case EggTexture::F_alpha:
       case EggTexture::F_luminance:
+      case EggTexture::F_sluminance:
         break;
 
       default:
-        _format = EggTexture::F_luminance_alpha;
+        if (_srgb) {
+          _format = EggTexture::F_sluminance_alpha;
+        } else {
+          _format = EggTexture::F_luminance_alpha;
+        }
       }
       break;
 
@@ -363,6 +390,7 @@ fully_define() {
       case EggTexture::F_rgb8:
       case EggTexture::F_rgb5:
       case EggTexture::F_rgb332:
+      case EggTexture::F_srgb:
         break;
 
         // These formats suggest an alpha channel; they are quietly replaced
@@ -382,10 +410,15 @@ fully_define() {
       case EggTexture::F_blue:
       case EggTexture::F_alpha:
       case EggTexture::F_luminance:
+      case EggTexture::F_sluminance:
         break;
 
       default:
-        _format = EggTexture::F_rgb;
+        if (_srgb) {
+          _format = EggTexture::F_srgb;
+        } else {
+          _format = EggTexture::F_rgb;
+        }
       }
       break;
 
@@ -397,6 +430,7 @@ fully_define() {
       case EggTexture::F_rgba8:
       case EggTexture::F_rgba4:
       case EggTexture::F_rgba5:
+      case EggTexture::F_srgb_alpha:
         break;
 
         // These formats implicitly reduce the number of channels to 3.
@@ -405,12 +439,14 @@ fully_define() {
       case EggTexture::F_rgb8:
       case EggTexture::F_rgb5:
       case EggTexture::F_rgb332:
+      case EggTexture::F_srgb:
         _effective_num_channels = 3;
         break;
 
         // These formats implicitly reduce the number of channels to 2.
       case EggTexture::F_luminance_alpha:
       case EggTexture::F_luminance_alphamask:
+      case EggTexture::F_sluminance_alpha:
         _effective_num_channels = 2;
         break;
 
@@ -420,15 +456,40 @@ fully_define() {
       case EggTexture::F_blue:
       case EggTexture::F_alpha:
       case EggTexture::F_luminance:
+      case EggTexture::F_sluminance:
         _effective_num_channels = 1;
         break;
 
       default:
-        _format = EggTexture::F_rgba;
+        if (_srgb) {
+          _format = EggTexture::F_srgb_alpha;
+        } else {
+          _format = EggTexture::F_rgba;
+        }
       }
     }
   }
 
+  // Respect the _srgb flag.  If this is set, it means the texture is in sRGB
+  // space and the format should be changed to reflect that.
+  if (_srgb) {
+    switch (_num_channels) {
+    case 1:
+      _format = EggTexture::F_sluminance;
+      break;
+    case 2:
+      _format = EggTexture::F_sluminance_alpha;
+      break;
+    case 3:
+      _format = EggTexture::F_srgb;
+      break;
+    case 4:
+    default:
+      _format = EggTexture::F_srgb_alpha;
+      break;
+    }
+  }
+
   switch (_minfilter) {
   case EggTexture::FT_unspecified:
     _minfilter = EggTexture::FT_linear;
@@ -504,6 +565,9 @@ operator < (const TextureProperties &other) const {
   if (_anisotropic_degree != other._anisotropic_degree) {
     return _anisotropic_degree < other._anisotropic_degree;
   }
+  if (_srgb != other._srgb) {
+    return _srgb < other._srgb;
+  }
   if (_color_type != other._color_type) {
     return _color_type < other._color_type;
   }
@@ -525,6 +589,7 @@ operator == (const TextureProperties &other) const {
           _magfilter == other._magfilter &&
           _quality_level == other._quality_level &&
           _anisotropic_degree == other._anisotropic_degree &&
+          _srgb == other._srgb &&
           _color_type == other._color_type &&
           (_color_type == nullptr ||
            _alpha_type == other._alpha_type));
@@ -606,6 +671,12 @@ get_format_string(EggTexture::Format format) {
 
   case EggTexture::F_srgb_alpha:
     return "sa";
+
+  case EggTexture::F_sluminance:
+    return "sl";
+
+  case EggTexture::F_sluminance_alpha:
+    return "st";
   }
 
   return "x";
@@ -779,6 +850,7 @@ write_datagram(BamWriter *writer, Datagram &datagram) {
   datagram.add_int32((int)_magfilter);
   datagram.add_int32((int)_quality_level);
   datagram.add_int32(_anisotropic_degree);
+  datagram.add_bool(_srgb);
   writer->write_pointer(datagram, _color_type);
   writer->write_pointer(datagram, _alpha_type);
 }
@@ -852,6 +924,10 @@ fillin(DatagramIterator &scan, BamReader *manager) {
   }
   _anisotropic_degree = scan.get_int32();
 
+  if (Palettizer::_read_pi_version >= 21) {
+    _srgb = scan.get_bool();
+  }
+
   manager->read_pointer(scan);  // _color_type
   manager->read_pointer(scan);  // _alpha_type
 }

+ 1 - 0
pandatool/src/palettizer/textureProperties.h

@@ -62,6 +62,7 @@ public:
   int _anisotropic_degree;
   PNMFileType *_color_type;
   PNMFileType *_alpha_type;
+  bool _srgb;
 
 private:
   static std::string get_format_string(EggTexture::Format format);

+ 1 - 0
pandatool/src/palettizer/textureRequest.cxx

@@ -21,6 +21,7 @@ TextureRequest::
 TextureRequest() {
   _got_size = false;
   _got_num_channels = false;
+  _srgb = false;
   _x_size = 0;
   _y_size = 0;
   _num_channels = 0;

+ 1 - 0
pandatool/src/palettizer/textureRequest.h

@@ -41,6 +41,7 @@ public:
   bool _force_format;
   bool _generic_format;
   bool _keep_format;
+  bool _srgb;
   EggTexture::FilterType _minfilter;
   EggTexture::FilterType _magfilter;
   int _anisotropic_degree;

+ 10 - 0
pandatool/src/palettizer/txaLine.cxx

@@ -179,6 +179,9 @@ parse(const string &line) {
       } else if (word == "cont") {
         _keywords.push_back(KW_cont);
 
+      } else if (word == "srgb") {
+        _keywords.push_back(KW_srgb);
+
       } else if (word == "margin") {
         ++wi;
         if (wi == words.end()) {
@@ -502,6 +505,9 @@ match_texture(TextureImage *texture) const {
     case KW_cont:
       got_cont = true;
       break;
+
+    case KW_srgb:
+      request._srgb = true;
     }
   }
 
@@ -586,6 +592,10 @@ output(std::ostream &out) const {
     case KW_anisotropic:
       out << " aniso " << _aniso_degree;
       break;
+
+    case KW_srgb:
+      out << " srgb";
+      break;
     }
   }
 

+ 2 - 1
pandatool/src/palettizer/txaLine.h

@@ -81,7 +81,8 @@ private:
     KW_linear,
     KW_mipmap,
     KW_cont,
-    KW_anisotropic
+    KW_anisotropic,
+    KW_srgb,
   };
 
   typedef pvector<Keyword> Keywords;