Panda3D

eggTexture.cxx

00001 // Filename: eggTexture.cxx
00002 // Created by:  drose (18Jan99)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "eggTexture.h"
00016 #include "eggMiscFuncs.h"
00017 #include "lexerDefs.h"
00018 
00019 #include "indent.h"
00020 #include "string_utils.h"
00021 
00022 TypeHandle EggTexture::_type_handle;
00023 
00024 
00025 ////////////////////////////////////////////////////////////////////
00026 //     Function: EggTexture::Constructor
00027 //       Access: Published
00028 //  Description:
00029 ////////////////////////////////////////////////////////////////////
00030 EggTexture::
00031 EggTexture(const string &tref_name, const Filename &filename)
00032   : EggFilenameNode(tref_name, filename)
00033 {
00034   _texture_type = TT_unspecified;
00035   _format = F_unspecified;
00036   _compression_mode = CM_default;
00037   _wrap_mode = WM_unspecified;
00038   _wrap_u = WM_unspecified;
00039   _wrap_v = WM_unspecified;
00040   _wrap_w = WM_unspecified;
00041   _minfilter = FT_unspecified;
00042   _magfilter = FT_unspecified;
00043   _anisotropic_degree = 0;
00044   _env_type = ET_unspecified;
00045   _saved_result = false;
00046   _tex_gen = TG_unspecified;
00047   _quality_level = QL_unspecified;
00048   _priority = 0;
00049   _color.set(0.0f, 0.0f, 0.0f, 1.0f);
00050   _border_color.set(0.0f, 0.0f, 0.0f, 1.0f);
00051   _flags = 0;
00052   _alpha_file_channel = 0;
00053   _read_mipmaps = false;
00054   _multitexture_sort = 0;
00055 }
00056 
00057 ////////////////////////////////////////////////////////////////////
00058 //     Function: EggTexture::Copy constructor
00059 //       Access: Published
00060 //  Description:
00061 ////////////////////////////////////////////////////////////////////
00062 EggTexture::
00063 EggTexture(const EggTexture &copy) {
00064   (*this) = copy;
00065 }
00066 
00067 ////////////////////////////////////////////////////////////////////
00068 //     Function: EggTexture::Copy assignment operator
00069 //       Access: Published
00070 //  Description:
00071 ////////////////////////////////////////////////////////////////////
00072 EggTexture &EggTexture::
00073 operator = (const EggTexture &copy) {
00074   clear_multitexture();
00075 
00076   EggFilenameNode::operator = (copy);
00077   EggRenderMode::operator = (copy);
00078   EggTransform::operator = (copy);
00079 
00080   _texture_type = copy._texture_type;
00081   _format = copy._format;
00082   _compression_mode = copy._compression_mode;
00083   _wrap_mode = copy._wrap_mode;
00084   _wrap_u = copy._wrap_u;
00085   _wrap_v = copy._wrap_v;
00086   _wrap_w = copy._wrap_w;
00087   _minfilter = copy._minfilter;
00088   _magfilter = copy._magfilter;
00089   _anisotropic_degree = copy._anisotropic_degree;
00090   _env_type = copy._env_type;
00091   _saved_result = copy._saved_result;
00092   _tex_gen = copy._tex_gen;
00093   _quality_level = copy._quality_level;
00094   _stage_name = copy._stage_name;
00095   _priority = copy._priority;
00096   _color = copy._color;
00097   _border_color = copy._border_color;
00098   _uv_name = copy._uv_name;
00099   _rgb_scale = 1;
00100   _alpha_scale = 1;
00101   _flags = copy._flags;
00102   _alpha_filename = copy._alpha_filename;
00103   _alpha_fullpath = copy._alpha_fullpath;
00104   _alpha_file_channel = copy._alpha_file_channel;
00105   _read_mipmaps = copy._read_mipmaps;
00106   _multitexture_sort = 0;
00107   _combiner[0] = copy._combiner[0];
00108   _combiner[1] = copy._combiner[1];
00109 
00110   return *this;
00111 }
00112 
00113 ////////////////////////////////////////////////////////////////////
00114 //     Function: EggTexture::Destructor
00115 //       Access: Published, Virtual
00116 //  Description:
00117 ////////////////////////////////////////////////////////////////////
00118 EggTexture::
00119 ~EggTexture() {
00120   clear_multitexture();
00121 }
00122 
00123 ////////////////////////////////////////////////////////////////////
00124 //     Function: EggTexture::write
00125 //       Access: Public, Virtual
00126 //  Description: Writes the texture definition to the indicated output
00127 //               stream in Egg format.
00128 ////////////////////////////////////////////////////////////////////
00129 void EggTexture::
00130 write(ostream &out, int indent_level) const {
00131   write_header(out, indent_level, "<Texture>");
00132   enquote_string(out, get_filename(), indent_level + 2) << "\n";
00133 
00134   if (has_alpha_filename()) {
00135     indent(out, indent_level + 2)
00136       << "<Scalar> alpha-file { ";
00137     enquote_string(out, get_alpha_filename());
00138     out << " }\n";
00139   }
00140 
00141   if (has_alpha_file_channel()) {
00142     indent(out, indent_level + 2)
00143       << "<Scalar> alpha-file-channel { " 
00144       << get_alpha_file_channel() << " }\n";
00145   }
00146 
00147   if (get_read_mipmaps()) {
00148     indent(out, indent_level + 2)
00149       << "<Scalar> read-mipmaps { 1 }\n";
00150   }
00151 
00152   if (get_texture_type() != TT_unspecified) {
00153     indent(out, indent_level + 2)
00154       << "<Scalar> type { " << get_texture_type() << " }\n";
00155   }
00156 
00157   if (get_format() != F_unspecified) {
00158     indent(out, indent_level + 2)
00159       << "<Scalar> format { " << get_format() << " }\n";
00160   }
00161 
00162   if (get_compression_mode() != CM_default) {
00163     indent(out, indent_level + 2)
00164       << "<Scalar> compression { " << get_compression_mode() << " }\n";
00165   }
00166 
00167   if (get_wrap_mode() != WM_unspecified) {
00168     indent(out, indent_level + 2)
00169       << "<Scalar> wrap { " << get_wrap_mode() << " }\n";
00170   }
00171 
00172   if (get_wrap_u() != WM_unspecified) {
00173     indent(out, indent_level + 2)
00174       << "<Scalar> wrapu { " << get_wrap_u() << " }\n";
00175   }
00176 
00177   if (get_wrap_v() != WM_unspecified) {
00178     indent(out, indent_level + 2)
00179       << "<Scalar> wrapv { " << get_wrap_v() << " }\n";
00180   }
00181 
00182   if (get_wrap_w() != WM_unspecified) {
00183     indent(out, indent_level + 2)
00184       << "<Scalar> wrapw { " << get_wrap_w() << " }\n";
00185   }
00186 
00187   if (get_minfilter() != FT_unspecified) {
00188     indent(out, indent_level + 2)
00189       << "<Scalar> minfilter { " << get_minfilter() << " }\n";
00190   }
00191 
00192   if (get_magfilter() != FT_unspecified) {
00193     indent(out, indent_level + 2)
00194       << "<Scalar> magfilter { " << get_magfilter() << " }\n";
00195   }
00196 
00197   if (has_anisotropic_degree()) {
00198     indent(out, indent_level + 2)
00199       << "<Scalar> anisotropic-degree { " << get_anisotropic_degree() << " }\n";
00200   }
00201 
00202   if (get_env_type() != ET_unspecified) {
00203     indent(out, indent_level + 2)
00204       << "<Scalar> envtype { " << get_env_type() << " }\n";
00205   }
00206 
00207   for (int ci = 0; ci < (int)CC_num_channels; ci++) {
00208     CombineChannel channel = (CombineChannel)ci;
00209     if (get_combine_mode(channel) != CM_unspecified) {
00210       indent(out, indent_level + 2)
00211         << "<Scalar> combine-" << channel 
00212         << " { " << get_combine_mode(channel) << " }\n";
00213     }
00214     for (int i = 0; i < (int)CI_num_indices; i++) {
00215       if (get_combine_source(channel, i) != CS_unspecified) {
00216         indent(out, indent_level + 2)
00217           << "<Scalar> combine-" << channel << "-source" << i
00218           << " { " << get_combine_source(channel, i) << " }\n";
00219       }
00220       if (get_combine_operand(channel, i) != CO_unspecified) {
00221         indent(out, indent_level + 2)
00222           << "<Scalar> combine-" << channel << "-operand" << i
00223           << " { " << get_combine_operand(channel, i) << " }\n";
00224       }
00225     }
00226   }
00227 
00228   if (get_saved_result()) {
00229     indent(out, indent_level + 2)
00230       << "<Scalar> saved-result { 1 }\n";
00231   }
00232 
00233   if (get_tex_gen() != TG_unspecified) {
00234     indent(out, indent_level + 2)
00235       << "<Scalar> tex-gen { " << get_tex_gen() << " }\n";
00236   }
00237 
00238   if (get_quality_level() != QL_unspecified) {
00239     indent(out, indent_level + 2)
00240       << "<Scalar> quality-level { " << get_quality_level() << " }\n";
00241   }
00242 
00243   if (has_stage_name()) {
00244     indent(out, indent_level + 2)
00245       << "<Scalar> stage-name { " << get_stage_name() << " }\n";
00246   }
00247 
00248   if (has_priority()) {
00249     indent(out, indent_level + 2)
00250       << "<Scalar> priority { " << get_priority() << " }\n";
00251   }
00252 
00253   if (has_color()) {
00254     indent(out, indent_level + 2)
00255       << "<Scalar> blendr { " << _color[0] << " }\n";
00256     indent(out, indent_level + 2)
00257       << "<Scalar> blendg { " << _color[1] << " }\n";
00258     indent(out, indent_level + 2)
00259       << "<Scalar> blendb { " << _color[2] << " }\n";
00260     indent(out, indent_level + 2)
00261       << "<Scalar> blenda { " << _color[3] << " }\n";
00262   }
00263 
00264   if (has_border_color()) {
00265     indent(out, indent_level + 2)
00266       << "<Scalar> borderr { " << _border_color[0] << " }\n";
00267     indent(out, indent_level + 2)
00268       << "<Scalar> borderg { " << _border_color[1] << " }\n";
00269     indent(out, indent_level + 2)
00270       << "<Scalar> borderb { " << _border_color[2] << " }\n";
00271     indent(out, indent_level + 2)
00272       << "<Scalar> bordera { " << _border_color[3] << " }\n";
00273   }
00274 
00275   if (has_uv_name()) {
00276     indent(out, indent_level + 2)
00277       << "<Scalar> uv-name { " << get_uv_name() << " }\n";
00278   }
00279 
00280   if (has_rgb_scale()) {
00281     indent(out, indent_level + 2)
00282       << "<Scalar> rgb-scale { " << get_rgb_scale() << " }\n";
00283   }
00284 
00285   if (has_alpha_scale()) {
00286     indent(out, indent_level + 2)
00287       << "<Scalar> alpha-scale { " << get_alpha_scale() << " }\n";
00288   }
00289 
00290   EggRenderMode::write(out, indent_level + 2);
00291 
00292   if (has_transform()) {
00293     EggTransform::write(out, indent_level + 2, "<Transform>");
00294   }
00295 
00296   indent(out, indent_level) << "}\n";
00297 }
00298 
00299 ////////////////////////////////////////////////////////////////////
00300 //     Function: EggTexture::is_equivalent_to
00301 //       Access: Published
00302 //  Description: Returns true if the two textures are equivalent in
00303 //               all relevant properties (according to eq), false
00304 //               otherwise.
00305 //
00306 //               The Equivalence parameter, eq, should be set to the
00307 //               bitwise OR of the following properties, according to
00308 //               what you consider relevant:
00309 //
00310 //               EggTexture::E_basename:
00311 //                 The basename part of the texture filename, without
00312 //                 the directory prefix *or* the filename extension.
00313 //
00314 //               EggTexture::E_extension:
00315 //                 The extension part of the texture filename.
00316 //
00317 //               EggTexture::E_dirname:
00318 //                 The directory prefix of the texture filename.
00319 //
00320 //               EggTexture::E_complete_filename:
00321 //                 The union of the above three; that is, the complete
00322 //                 filename, with directory, basename, and extension.
00323 //
00324 //               EggTexture::E_transform:
00325 //                 The texture matrix.
00326 //
00327 //               EggTexture::E_attributes:
00328 //                 All remaining texture attributes (mode, mipmap,
00329 //                 etc.) except TRef name.
00330 //
00331 //               EggTexture::E_tref_name:
00332 //                 The TRef name.
00333 ////////////////////////////////////////////////////////////////////
00334 bool EggTexture::
00335 is_equivalent_to(const EggTexture &other, int eq) const {
00336   if ((eq & E_complete_filename) == E_complete_filename) {
00337     //cout << "compared by filename" << endl;
00338     if (get_filename() != other.get_filename()) {
00339       return false;
00340     }
00341   } else {
00342     //cout << "compared by not complete filename" << endl;
00343     const Filename &a = get_filename();
00344     const Filename &b = other.get_filename();
00345 
00346     if (eq & E_basename) {
00347       if (a.get_basename_wo_extension() != b.get_basename_wo_extension()) {
00348         return false;
00349       }
00350     }
00351     if (eq & E_extension) {
00352       if (a.get_extension() != b.get_extension()) {
00353         return false;
00354       }
00355     }
00356     if (eq & E_dirname) {
00357       if (a.get_dirname() != b.get_dirname()) {
00358         return false;
00359       }
00360     }
00361   }
00362 
00363   if (eq & E_transform) {
00364     //cout << "compared by transform" << endl;
00365     if (transform_is_identity() != other.transform_is_identity()) {
00366       return false;
00367     }
00368 
00369     if (has_transform() && other.has_transform()) {
00370       if (!get_transform3d().almost_equal(other.get_transform3d(), 0.0001)) {
00371         return false;
00372       }
00373     }
00374   }
00375 
00376   if (eq & E_attributes) {
00377     //cout << "compared by attributes" << endl;
00378     if (_texture_type != other._texture_type ||
00379         _format != other._format ||
00380         _compression_mode != other._compression_mode ||
00381         _wrap_mode != other._wrap_mode ||
00382         _wrap_u != other._wrap_u ||
00383         _wrap_v != other._wrap_v ||
00384         _wrap_w != other._wrap_w ||
00385         _minfilter != other._minfilter ||
00386         _magfilter != other._magfilter ||
00387         _env_type != other._env_type) {
00388       return false;
00389     }
00390     if (EggRenderMode::operator != (other)) {
00391       return false;
00392     }
00393   }
00394 
00395   if (eq & E_tref_name) {
00396     //cout << "compared by tref_name" << endl;
00397     if (get_name() != other.get_name()) {
00398       return false;
00399     }
00400   }
00401 
00402   return true;
00403 }
00404 
00405 ////////////////////////////////////////////////////////////////////
00406 //     Function: EggTexture::sorts_less_than
00407 //       Access: Published
00408 //  Description: An ordering operator to compare two textures for
00409 //               sorting order.  This imposes an arbitrary ordering
00410 //               useful to identify unique textures, according to the
00411 //               indicated Equivalence factor.  See
00412 //               is_equivalent_to().
00413 ////////////////////////////////////////////////////////////////////
00414 bool EggTexture::
00415 sorts_less_than(const EggTexture &other, int eq) const {
00416   if ((eq & E_complete_filename) == E_complete_filename) {
00417     if (get_filename() != other.get_filename()) {
00418       return get_filename() < other.get_filename();
00419     }
00420   } else {
00421     const Filename &a = get_filename();
00422     const Filename &b = other.get_filename();
00423 
00424     if (eq & E_basename) {
00425       if (a.get_basename_wo_extension() != b.get_basename_wo_extension()) {
00426         return a.get_basename_wo_extension() < b.get_basename_wo_extension();
00427       }
00428     }
00429     if (eq & E_extension) {
00430       if (a.get_extension() != b.get_extension()) {
00431         return a.get_extension() < b.get_extension();
00432       }
00433     }
00434     if (eq & E_dirname) {
00435       if (a.get_dirname() != b.get_dirname()) {
00436         return a.get_dirname() < b.get_dirname();
00437       }
00438     }
00439   }
00440 
00441   if (eq & E_transform) {
00442     bool is_identity = transform_is_identity();
00443     bool other_is_identity = other.transform_is_identity();
00444     if (is_identity != other_is_identity) {
00445       return (int)is_identity < (int)other_is_identity;
00446     }
00447 
00448     if (has_transform() && other.has_transform()) {
00449       int compare = get_transform3d().compare_to(other.get_transform3d());
00450       if (compare != 0) {
00451         return compare < 0;
00452       }
00453     }
00454   }
00455 
00456   if (eq & E_attributes) {
00457     if (_texture_type != other._texture_type) {
00458       return (int)_texture_type < (int)other._texture_type;
00459     }
00460     if (_format != other._format) {
00461       return (int)_format < (int)other._format;
00462     }
00463     if (_compression_mode != other._compression_mode) {
00464       return (int)_compression_mode < (int)other._compression_mode;
00465     }
00466     if (_wrap_mode != other._wrap_mode) {
00467       return (int)_wrap_mode < (int)other._wrap_mode;
00468     }
00469     if (_wrap_u != other._wrap_u) {
00470       return (int)_wrap_u < (int)other._wrap_u;
00471     }
00472     if (_wrap_v != other._wrap_v) {
00473       return (int)_wrap_v < (int)other._wrap_v;
00474     }
00475     if (_wrap_w != other._wrap_w) {
00476       return (int)_wrap_w < (int)other._wrap_w;
00477     }
00478     if (_minfilter != other._minfilter) {
00479       return (int)_minfilter < (int)other._minfilter;
00480     }
00481     if (_magfilter != other._magfilter) {
00482       return (int)_magfilter < (int)other._magfilter;
00483     }
00484     if (_anisotropic_degree != other._anisotropic_degree) {
00485       return _anisotropic_degree < other._anisotropic_degree;
00486     }
00487     if (_env_type != other._env_type) {
00488       return (int)_env_type < (int)other._env_type;
00489     }
00490     if (EggRenderMode::operator != (other)) {
00491       return EggRenderMode::operator < (other);
00492     }
00493   }
00494 
00495   if (eq & E_tref_name) {
00496     if (get_name() != other.get_name()) {
00497       return get_name() < other.get_name();
00498     }
00499   }
00500 
00501   return false;
00502 }
00503 
00504 ////////////////////////////////////////////////////////////////////
00505 //     Function: EggTexture::has_alpha_channel
00506 //       Access: Published
00507 //  Description: Given the number of color components (channels) in
00508 //               the image file as actually read from the disk, return
00509 //               true if this texture seems to have an alpha channel
00510 //               or not.  This depends on the EggTexture's format as
00511 //               well as the number of channels.
00512 ////////////////////////////////////////////////////////////////////
00513 bool EggTexture::
00514 has_alpha_channel(int num_components) const {
00515   switch (_format) {
00516   case F_red:
00517   case F_green:
00518   case F_blue:
00519   case F_luminance:
00520   case F_rgb:
00521   case F_rgb12:
00522   case F_rgb8:
00523   case F_rgb5:
00524   case F_rgb332:
00525     // These formats never use alpha, regardless of the number of
00526     // components we have.
00527     return false;
00528 
00529   case F_alpha:
00530     // This format always uses alpha.
00531     return true;
00532 
00533   case F_luminance_alpha:
00534   case F_luminance_alphamask:
00535   case F_rgba:
00536   case F_rgbm:
00537   case F_rgba12:
00538   case F_rgba8:
00539   case F_rgba4:
00540   case F_rgba5:
00541   case F_unspecified:
00542     // These formats use alpha if the image had alpha.
00543     return (num_components == 2 || num_components == 4);
00544   }
00545 
00546   return false;
00547 }
00548 
00549 ////////////////////////////////////////////////////////////////////
00550 //     Function: EggTexture::affects_polygon_alpha
00551 //       Access: Published
00552 //  Description: Returns true if this texture's environment type or
00553 //               combine mode allows the texture to have an affect on
00554 //               the polygon's alpha values, false otherwise.
00555 ////////////////////////////////////////////////////////////////////
00556 bool EggTexture::
00557 affects_polygon_alpha() const {
00558   switch (_env_type) {
00559   case ET_modulate:
00560   case ET_replace:
00561     return true;
00562 
00563   case ET_decal:
00564   case ET_blend:
00565   case ET_add:
00566   case ET_blend_color_scale:
00567     return false;
00568   case ET_modulate_glow:
00569   case ET_modulate_gloss:
00570   case ET_normal:
00571   case ET_normal_height:
00572   case ET_glow:
00573   case ET_gloss:
00574     return false;
00575 
00576   case ET_selector:
00577     return true;
00578 
00579   case ET_unspecified:
00580     break;
00581   }
00582 
00583   switch (_combiner[CC_alpha]._mode) {
00584   case CM_replace:
00585   case CM_modulate:
00586   case CM_add_signed:
00587   case CM_subtract:
00588     return true;
00589 
00590   case CM_interpolate:
00591   case CM_add:
00592   case CM_dot3_rgb:
00593   case CM_dot3_rgba:
00594     return false;
00595 
00596   case CM_unspecified:
00597     break;
00598   }
00599 
00600   // A completely unspecified texture environment implies "modulate",
00601   // which does affect alpha.
00602   return true;
00603 }
00604 
00605 
00606 ////////////////////////////////////////////////////////////////////
00607 //     Function: EggTexture::clear_multitexture
00608 //       Access: Published
00609 //  Description: Resets the multitexture flags set by
00610 //               multitexture_over().  After this call,
00611 //               get_multitexture() will return false, and
00612 //               get_multitexture_sort() will return 0.
00613 ////////////////////////////////////////////////////////////////////
00614 void EggTexture::
00615 clear_multitexture() {
00616   _multitexture_sort = 0;
00617 
00618   // Now empty out the _over_textures and _under_textures sets.  This
00619   // requires a bit of care so we don't end up in mutual recursion or
00620   // iterating through self-modifying structures.  To avoid this, we
00621   // empty the sets first, and then walk through their original
00622   // contents.
00623   MultiTextures orig_over_textures, orig_under_textures;
00624   orig_over_textures.swap(_over_textures);
00625   orig_under_textures.swap(_under_textures);
00626 
00627   MultiTextures::iterator mti;
00628   for (mti = orig_over_textures.begin(); 
00629        mti != orig_over_textures.end(); 
00630        ++mti) {
00631     EggTexture *other = (*mti);
00632     other->_under_textures.erase(this);
00633   }
00634   for (mti = orig_under_textures.begin(); 
00635        mti != orig_under_textures.end(); 
00636        ++mti) {
00637     EggTexture *other = (*mti);
00638     other->_over_textures.erase(this);
00639   }
00640 }
00641 
00642 ////////////////////////////////////////////////////////////////////
00643 //     Function: EggTexture::multitexture_over
00644 //       Access: Published
00645 //  Description: Indicates that this texture should be layered on top
00646 //               of the other texture.  This will guarantee that
00647 //               this->get_multitexture_sort() >
00648 //               other->get_multitexture_sort(), at least until
00649 //               clear_multitexture() is called on either one.
00650 //
00651 //               The return value is true if successful, or false if
00652 //               there is a failure because the other texture was
00653 //               already layered on top of this one (or there is a
00654 //               three- or more-way cycle).
00655 ////////////////////////////////////////////////////////////////////
00656 bool EggTexture::
00657 multitexture_over(EggTexture *other) {
00658   if (get_multitexture_sort() <= other->get_multitexture_sort()) {
00659     MultiTextures cycle_detector;
00660     if (!r_min_multitexture_sort(other->get_multitexture_sort() + 1,
00661                                  cycle_detector)) {
00662       // Found a cycle right off the bat!
00663       return false;
00664     }
00665   }
00666 
00667   if (_over_textures.insert(other).second) {
00668     bool inserted_under = other->_under_textures.insert(this).second;
00669     nassertr(inserted_under, false);
00670   }
00671   nassertr(get_multitexture_sort() > other->get_multitexture_sort(), false);
00672 
00673   return true;
00674 }
00675 
00676 ////////////////////////////////////////////////////////////////////
00677 //     Function: EggTexture::string_texture_type
00678 //       Access: Published, Static
00679 //  Description: Returns the Texture_ype value associated with the given
00680 //               string representation, or TT_unspecified if the string
00681 //               does not match any known TextureType value.
00682 ////////////////////////////////////////////////////////////////////
00683 EggTexture::TextureType EggTexture::
00684 string_texture_type(const string &string) {
00685   if (cmp_nocase_uh(string, "1d") == 0 ||
00686       cmp_nocase_uh(string, "1dtexture") == 0 ||
00687       cmp_nocase_uh(string, "1d_texture") == 0) {
00688     return TT_1d_texture;
00689 
00690   } else if (cmp_nocase_uh(string, "2d") == 0 ||
00691              cmp_nocase_uh(string, "2dtexture") == 0 ||
00692              cmp_nocase_uh(string, "2d_texture") == 0) {
00693     return TT_2d_texture;
00694 
00695   } else if (cmp_nocase_uh(string, "3d") == 0 ||
00696              cmp_nocase_uh(string, "3dtexture") == 0 ||
00697              cmp_nocase_uh(string, "3d_texture") == 0) {
00698     return TT_3d_texture;
00699 
00700   } else if (cmp_nocase_uh(string, "cube") == 0 ||
00701              cmp_nocase_uh(string, "cubemap") == 0 ||
00702              cmp_nocase_uh(string, "cube_map") == 0) {
00703     return TT_cube_map;
00704 
00705   } else {
00706     return TT_unspecified;
00707   }
00708 }
00709 
00710 ////////////////////////////////////////////////////////////////////
00711 //     Function: EggTexture::string_format
00712 //       Access: Published, Static
00713 //  Description: Returns the Format value associated with the given
00714 //               string representation, or F_unspecified if the string
00715 //               does not match any known Format value.
00716 ////////////////////////////////////////////////////////////////////
00717 EggTexture::Format EggTexture::
00718 string_format(const string &string) {
00719   if (cmp_nocase_uh(string, "rgba") == 0) {
00720     return F_rgba;
00721   } else if (cmp_nocase_uh(string, "rgbm") == 0) {
00722     return F_rgbm;
00723   } else if (cmp_nocase_uh(string, "rgba12") == 0) {
00724     return F_rgba12;
00725   } else if (cmp_nocase_uh(string, "rgba8") == 0) {
00726     return F_rgba8;
00727   } else if (cmp_nocase_uh(string, "rgba4") == 0) {
00728     return F_rgba4;
00729 
00730   } else if (cmp_nocase_uh(string, "rgb") == 0) {
00731     return F_rgb;
00732   } else if (cmp_nocase_uh(string, "rgb12") == 0) {
00733     return F_rgb12;
00734   } else if (cmp_nocase_uh(string, "rgb8") == 0) {
00735     return F_rgb8;
00736   } else if (cmp_nocase_uh(string, "rgb5") == 0) {
00737     return F_rgb5;
00738   } else if (cmp_nocase_uh(string, "rgba5") == 0) {
00739     return F_rgba5;
00740   } else if (cmp_nocase_uh(string, "rgb332") == 0) {
00741     return F_rgb332;
00742   } else if (cmp_nocase_uh(string, "red") == 0) {
00743     return F_red;
00744   } else if (cmp_nocase_uh(string, "green") == 0) {
00745     return F_green;
00746   } else if (cmp_nocase_uh(string, "blue") == 0) {
00747     return F_blue;
00748   } else if (cmp_nocase_uh(string, "alpha") == 0) {
00749     return F_alpha;
00750   } else if (cmp_nocase_uh(string, "luminance") == 0) {
00751     return F_luminance;
00752   } else if (cmp_nocase_uh(string, "luminance_alpha") == 0) {
00753     return F_luminance_alpha;
00754   } else if (cmp_nocase_uh(string, "luminance_alphamask") == 0) {
00755     return F_luminance_alphamask;
00756   } else {
00757     return F_unspecified;
00758   }
00759 }
00760 
00761 ////////////////////////////////////////////////////////////////////
00762 //     Function: EggTexture::string_compression_mode
00763 //       Access: Published, Static
00764 //  Description: Returns the CompressionMode value associated with the given
00765 //               string representation, or CM_default if the string
00766 //               does not match any known CompressionMode value.
00767 ////////////////////////////////////////////////////////////////////
00768 EggTexture::CompressionMode EggTexture::
00769 string_compression_mode(const string &string) {
00770   if (cmp_nocase_uh(string, "off") == 0) {
00771     return CM_off;
00772   } else if (cmp_nocase_uh(string, "on") == 0) {
00773     return CM_on;
00774   } else if (cmp_nocase_uh(string, "fxt1") == 0) {
00775     return CM_fxt1;
00776   } else if (cmp_nocase_uh(string, "dxt1") == 0) {
00777     return CM_dxt1;
00778   } else if (cmp_nocase_uh(string, "dxt2") == 0) {
00779     return CM_dxt2;
00780   } else if (cmp_nocase_uh(string, "dxt3") == 0) {
00781     return CM_dxt3;
00782   } else if (cmp_nocase_uh(string, "dxt4") == 0) {
00783     return CM_dxt4;
00784   } else if (cmp_nocase_uh(string, "dxt5") == 0) {
00785     return CM_dxt5;
00786   } else {
00787     return CM_default;
00788   }
00789 }
00790 
00791 ////////////////////////////////////////////////////////////////////
00792 //     Function: EggTexture::string_wrap_mode
00793 //       Access: Published, Static
00794 //  Description: Returns the WrapMode value associated with the given
00795 //               string representation, or WM_unspecified if the string
00796 //               does not match any known WrapMode value.
00797 ////////////////////////////////////////////////////////////////////
00798 EggTexture::WrapMode EggTexture::
00799 string_wrap_mode(const string &string) {
00800   if (cmp_nocase_uh(string, "repeat") == 0) {
00801     return WM_repeat;
00802   } else if (cmp_nocase_uh(string, "clamp") == 0) {
00803     return WM_clamp;
00804   } else if (cmp_nocase_uh(string, "mirror") == 0) {
00805     return WM_mirror;
00806   } else if (cmp_nocase_uh(string, "mirror_once") == 0) {
00807     return WM_mirror_once;
00808   } else if (cmp_nocase_uh(string, "border_color") == 0) {
00809     return WM_border_color;
00810   } else {
00811     return WM_unspecified;
00812   }
00813 }
00814 
00815 ////////////////////////////////////////////////////////////////////
00816 //     Function: EggTexture::string_filter_type
00817 //       Access: Published, Static
00818 //  Description: Returns the FilterType value associated with the given
00819 //               string representation, or FT_unspecified if the string
00820 //               does not match any known FilterType value.
00821 ////////////////////////////////////////////////////////////////////
00822 EggTexture::FilterType EggTexture::
00823 string_filter_type(const string &string) {
00824   // Old egg filter types.
00825   if (cmp_nocase_uh(string, "point") == 0) {
00826     return FT_nearest;
00827   } else if (cmp_nocase_uh(string, "linear") == 0) {
00828     return FT_linear;
00829   } else if (cmp_nocase_uh(string, "bilinear") == 0) {
00830     return FT_linear;
00831   } else if (cmp_nocase_uh(string, "trilinear") == 0) {
00832     return FT_linear_mipmap_linear;
00833   } else if (cmp_nocase_uh(string, "mipmap") == 0) {
00834     return FT_linear_mipmap_linear;
00835   } else if (cmp_nocase_uh(string, "mipmap_point") == 0) {
00836     return FT_nearest_mipmap_nearest;
00837   } else if (cmp_nocase_uh(string, "mipmap_linear") == 0) {
00838     return FT_nearest_mipmap_linear;
00839   } else if (cmp_nocase_uh(string, "mipmap_bilinear") == 0) {
00840     return FT_linear_mipmap_nearest;
00841   } else if (cmp_nocase_uh(string, "mipmap_trilinear") == 0) {
00842     return FT_linear_mipmap_linear;
00843 
00844     // Current egg filter types, that match those in Texture.
00845   } else if (cmp_nocase_uh(string, "nearest") == 0) {
00846     return FT_nearest;
00847   } else if (cmp_nocase_uh(string, "linear") == 0) {
00848     return FT_linear;
00849   } else if (cmp_nocase_uh(string, "nearest_mipmap_nearest") == 0) {
00850     return FT_nearest_mipmap_nearest;
00851   } else if (cmp_nocase_uh(string, "linear_mipmap_nearest") == 0) {
00852     return FT_linear_mipmap_nearest;
00853   } else if (cmp_nocase_uh(string, "nearest_mipmap_linear") == 0) {
00854     return FT_nearest_mipmap_linear;
00855   } else if (cmp_nocase_uh(string, "linear_mipmap_linear") == 0) {
00856     return FT_linear_mipmap_linear;
00857 
00858   } else {
00859     return FT_unspecified;
00860   }
00861 }
00862 
00863 ////////////////////////////////////////////////////////////////////
00864 //     Function: EggTexture::string_env_type
00865 //       Access: Published, Static
00866 //  Description: Returns the EnvType value associated with the given
00867 //               string representation, or ET_unspecified if the string
00868 //               does not match any known EnvType value.
00869 ////////////////////////////////////////////////////////////////////
00870 EggTexture::EnvType EggTexture::
00871 string_env_type(const string &string) {
00872   if (cmp_nocase_uh(string, "modulate") == 0) {
00873     return ET_modulate;
00874 
00875   } else if (cmp_nocase_uh(string, "decal") == 0) {
00876     return ET_decal;
00877 
00878   } else if (cmp_nocase_uh(string, "blend") == 0) {
00879     return ET_blend;
00880 
00881   } else if (cmp_nocase_uh(string, "replace") == 0) {
00882     return ET_replace;
00883 
00884   } else if (cmp_nocase_uh(string, "add") == 0) {
00885     return ET_add;
00886 
00887   } else if (cmp_nocase_uh(string, "blend_color_scale") == 0) {
00888     return ET_blend_color_scale;
00889 
00890   } else if (cmp_nocase_uh(string, "modulate_glow") == 0) {
00891     return ET_modulate_glow;
00892 
00893   } else if (cmp_nocase_uh(string, "modulate_gloss") == 0) {
00894     return ET_modulate_gloss;
00895 
00896   } else if (cmp_nocase_uh(string, "normal") == 0) {
00897     return ET_normal;
00898 
00899   } else if (cmp_nocase_uh(string, "normal_height") == 0) {
00900     return ET_normal_height;
00901 
00902   } else if (cmp_nocase_uh(string, "glow") == 0) {
00903     return ET_glow;
00904 
00905   } else if (cmp_nocase_uh(string, "gloss") == 0) {
00906     return ET_gloss;
00907 
00908   } else if (cmp_nocase_uh(string, "height") == 0) {
00909     return ET_height;
00910 
00911   } else if (cmp_nocase_uh(string, "selector") == 0) {
00912     return ET_selector;
00913 
00914   } else {
00915     return ET_unspecified;
00916   }
00917 }
00918 
00919 ////////////////////////////////////////////////////////////////////
00920 //     Function: EggTexture::string_combine_mode
00921 //       Access: Published, Static
00922 //  Description: Returns the CombineMode value associated with the given
00923 //               string representation, or CM_unspecified if the string
00924 //               does not match any known CombineMode value.
00925 ////////////////////////////////////////////////////////////////////
00926 EggTexture::CombineMode EggTexture::
00927 string_combine_mode(const string &string) {
00928   if (cmp_nocase_uh(string, "replace") == 0) {
00929     return CM_replace;
00930 
00931   } else if (cmp_nocase_uh(string, "modulate") == 0) {
00932     return CM_modulate;
00933 
00934   } else if (cmp_nocase_uh(string, "add") == 0) {
00935     return CM_add;
00936 
00937   } else if (cmp_nocase_uh(string, "add_signed") == 0) {
00938     return CM_add_signed;
00939 
00940   } else if (cmp_nocase_uh(string, "interpolate") == 0) {
00941     return CM_interpolate;
00942 
00943   } else if (cmp_nocase_uh(string, "subtract") == 0) {
00944     return CM_subtract;
00945 
00946   } else if (cmp_nocase_uh(string, "dot3_rgb") == 0) {
00947     return CM_dot3_rgb;
00948 
00949   } else if (cmp_nocase_uh(string, "dot3_rgba") == 0) {
00950     return CM_dot3_rgba;
00951 
00952   } else {
00953     return CM_unspecified;
00954   }
00955 }
00956 
00957 ////////////////////////////////////////////////////////////////////
00958 //     Function: EggTexture::string_combine_source
00959 //       Access: Published, Static
00960 //  Description: Returns the CombineSource value associated with the given
00961 //               string representation, or CS_unspecified if the string
00962 //               does not match any known CombineSource value.
00963 ////////////////////////////////////////////////////////////////////
00964 EggTexture::CombineSource EggTexture::
00965 string_combine_source(const string &string) {
00966   if (cmp_nocase_uh(string, "texture") == 0) {
00967     return CS_texture;
00968 
00969   } else if (cmp_nocase_uh(string, "constant") == 0) {
00970     return CS_constant;
00971 
00972   } else if (cmp_nocase_uh(string, "primary_color") == 0) {
00973     return CS_primary_color;
00974 
00975   } else if (cmp_nocase_uh(string, "previous") == 0) {
00976     return CS_previous;
00977 
00978   } else if (cmp_nocase_uh(string, "constant_color_scale") == 0) {
00979     return CS_constant_color_scale;
00980 
00981   } else if (cmp_nocase_uh(string, "last_saved_result") == 0) {
00982     return CS_last_saved_result;
00983 
00984   } else {
00985     return CS_unspecified;
00986   }
00987 }
00988 
00989 ////////////////////////////////////////////////////////////////////
00990 //     Function: EggTexture::string_combine_operand
00991 //       Access: Published, Static
00992 //  Description: Returns the CombineOperand value associated with the given
00993 //               string representation, or CO_unspecified if the string
00994 //               does not match any known CombineOperand value.
00995 ////////////////////////////////////////////////////////////////////
00996 EggTexture::CombineOperand EggTexture::
00997 string_combine_operand(const string &string) {
00998   if (cmp_nocase_uh(string, "src_color") == 0) {
00999     return CO_src_color;
01000 
01001   } else if (cmp_nocase_uh(string, "one_minus_src_color") == 0) {
01002     return CO_one_minus_src_color;
01003 
01004   } else if (cmp_nocase_uh(string, "src_alpha") == 0) {
01005     return CO_src_alpha;
01006 
01007   } else if (cmp_nocase_uh(string, "one_minus_src_alpha") == 0) {
01008     return CO_one_minus_src_alpha;
01009 
01010   } else {
01011     return CO_unspecified;
01012   }
01013 }
01014 
01015 ////////////////////////////////////////////////////////////////////
01016 //     Function: EggTexture::string_tex_gen
01017 //       Access: Published, Static
01018 //  Description: Returns the TexGen value associated with the given
01019 //               string representation, or ET_unspecified if the string
01020 //               does not match any known TexGen value.
01021 ////////////////////////////////////////////////////////////////////
01022 EggTexture::TexGen EggTexture::
01023 string_tex_gen(const string &string) {
01024   if (cmp_nocase_uh(string, "unspecified") == 0) {
01025     return TG_unspecified;
01026 
01027   } else if (cmp_nocase_uh(string, "sphere_map") == 0 ||
01028              cmp_nocase_uh(string, "eye_sphere_map") == 0) {
01029     return TG_eye_sphere_map;
01030 
01031   } else if (cmp_nocase_uh(string, "world_cube_map") == 0) {
01032     return TG_world_cube_map;
01033 
01034   } else if (cmp_nocase_uh(string, "cube_map") == 0 ||
01035              cmp_nocase_uh(string, "eye_cube_map") == 0) {
01036     return TG_eye_cube_map;
01037 
01038   } else if (cmp_nocase_uh(string, "world_normal") == 0) {
01039     return TG_world_normal;
01040 
01041   } else if (cmp_nocase_uh(string, "eye_normal") == 0) {
01042     return TG_eye_normal;
01043 
01044   } else if (cmp_nocase_uh(string, "world_position") == 0) {
01045     return TG_world_position;
01046 
01047   } else if (cmp_nocase_uh(string, "eye_position") == 0) {
01048     return TG_eye_position;
01049 
01050   } else if (cmp_nocase_uh(string, "point_sprite") == 0) {
01051     return TG_point_sprite;
01052 
01053   } else {
01054     return TG_unspecified;
01055   }
01056 }
01057 
01058 ////////////////////////////////////////////////////////////////////
01059 //     Function: EggTexture::string_quality_level
01060 //       Access: Published, Static
01061 //  Description: Returns the TexGen value associated with the given
01062 //               string representation, or ET_unspecified if the string
01063 //               does not match any known TexGen value.
01064 ////////////////////////////////////////////////////////////////////
01065 EggTexture::QualityLevel EggTexture::
01066 string_quality_level(const string &string) {
01067   if (cmp_nocase_uh(string, "unspecified") == 0) {
01068     return QL_unspecified;
01069 
01070   } else if (cmp_nocase_uh(string, "default") == 0) {
01071     return QL_default;
01072 
01073   } else if (cmp_nocase_uh(string, "fastest") == 0) {
01074     return QL_fastest;
01075 
01076   } else if (cmp_nocase_uh(string, "normal") == 0) {
01077     return QL_normal;
01078 
01079   } else if (cmp_nocase_uh(string, "best") == 0) {
01080     return QL_best;
01081 
01082   } else {
01083     return QL_unspecified;
01084   }
01085 }
01086 
01087 ////////////////////////////////////////////////////////////////////
01088 //     Function: EggTexture::as_transform
01089 //       Access: Public, Virtual
01090 //  Description: Returns this object cross-cast to an EggTransform
01091 //               pointer, if it inherits from EggTransform, or NULL if
01092 //               it does not.
01093 ////////////////////////////////////////////////////////////////////
01094 EggTransform *EggTexture::
01095 as_transform() {
01096   return this;
01097 }
01098 
01099 ////////////////////////////////////////////////////////////////////
01100 //     Function: EggTexture::egg_start_parse_body
01101 //       Access: Protected, Virtual
01102 //  Description: This function is called within parse_egg().  It
01103 //               should call the appropriate function on the lexer to
01104 //               initialize the parser into the state associated with
01105 //               this object.  If the object cannot be parsed into
01106 //               directly, it should return false.
01107 ////////////////////////////////////////////////////////////////////
01108 bool EggTexture::
01109 egg_start_parse_body() {
01110   egg_start_texture_body();
01111   return true;
01112 }
01113 
01114 ////////////////////////////////////////////////////////////////////
01115 //     Function: EggTexture::r_min_multitexture_sort
01116 //       Access: Private
01117 //  Description: Ensures that our multitexture_sort is at least the
01118 //               indicated value.
01119 ////////////////////////////////////////////////////////////////////
01120 bool EggTexture::
01121 r_min_multitexture_sort(int sort, EggTexture::MultiTextures &cycle_detector) {
01122   if (_multitexture_sort >= sort) {
01123     // No problem.
01124     return true;
01125   }
01126 
01127   if (!cycle_detector.insert(this).second) {
01128     // Oops, we just hit a cycle!
01129     return false;
01130   }
01131 
01132   _multitexture_sort = sort;
01133 
01134   // Now we also have to increment all of the textures that we are
01135   // under.
01136   bool no_cycles = true;
01137 
01138   MultiTextures::iterator mti;
01139   for (mti = _under_textures.begin();
01140        mti != _under_textures.end();
01141        ++mti) {
01142     EggTexture *other = (*mti);
01143     if (!other->r_min_multitexture_sort(sort + 1, cycle_detector)) {
01144       // Oops, found a cycle!
01145       no_cycles = false;
01146     }
01147   }
01148 
01149   return no_cycles;
01150 }
01151 
01152 
01153 ////////////////////////////////////////////////////////////////////
01154 //     Function: TextureType output operator
01155 //  Description:
01156 ////////////////////////////////////////////////////////////////////
01157 ostream &operator << (ostream &out, EggTexture::TextureType texture_type) {
01158   switch (texture_type) {
01159   case EggTexture::TT_unspecified:
01160     return out << "unspecified";
01161 
01162   case EggTexture::TT_1d_texture:
01163     return out << "1d";
01164 
01165   case EggTexture::TT_2d_texture:
01166     return out << "2d";
01167 
01168   case EggTexture::TT_3d_texture:
01169     return out << "3d";
01170 
01171   case EggTexture::TT_cube_map:
01172     return out << "cube-map";
01173   }
01174 
01175   nassertr(false, out);
01176   return out << "(**invalid**)";
01177 }
01178 
01179 
01180 ////////////////////////////////////////////////////////////////////
01181 //     Function: Format output operator
01182 //  Description:
01183 ////////////////////////////////////////////////////////////////////
01184 ostream &operator << (ostream &out, EggTexture::Format format) {
01185   switch (format) {
01186   case EggTexture::F_unspecified:
01187     return out << "unspecified";
01188 
01189   case EggTexture::F_rgba:
01190     return out << "rgba";
01191   case EggTexture::F_rgbm:
01192     return out << "rgbm";
01193   case EggTexture::F_rgba12:
01194     return out << "rgba12";
01195   case EggTexture::F_rgba8:
01196     return out << "rgba8";
01197   case EggTexture::F_rgba4:
01198     return out << "rgba4";
01199 
01200   case EggTexture::F_rgb:
01201     return out << "rgb";
01202   case EggTexture::F_rgb12:
01203     return out << "rgb12";
01204   case EggTexture::F_rgb8:
01205     return out << "rgb8";
01206   case EggTexture::F_rgb5:
01207     return out << "rgb5";
01208   case EggTexture::F_rgba5:
01209     return out << "rgba5";
01210   case EggTexture::F_rgb332:
01211     return out << "rgb332";
01212 
01213   case EggTexture::F_red:
01214     return out << "red";
01215   case EggTexture::F_green:
01216     return out << "green";
01217   case EggTexture::F_blue:
01218     return out << "blue";
01219   case EggTexture::F_alpha:
01220     return out << "alpha";
01221   case EggTexture::F_luminance:
01222     return out << "luminance";
01223   case EggTexture::F_luminance_alpha:
01224     return out << "luminance_alpha";
01225   case EggTexture::F_luminance_alphamask:
01226     return out << "luminance_alphamask";
01227   }
01228 
01229   nassertr(false, out);
01230   return out << "(**invalid**)";
01231 }
01232 
01233 ////////////////////////////////////////////////////////////////////
01234 //     Function: CompressionMode output operator
01235 //  Description:
01236 ////////////////////////////////////////////////////////////////////
01237 ostream &operator << (ostream &out, EggTexture::CompressionMode mode) {
01238   switch (mode) {
01239   case EggTexture::CM_default:
01240     return out << "default";
01241   case EggTexture::CM_off:
01242     return out << "off";
01243   case EggTexture::CM_on:
01244     return out << "on";
01245   case EggTexture::CM_fxt1:
01246     return out << "fxt1";
01247   case EggTexture::CM_dxt1:
01248     return out << "dxt1";
01249   case EggTexture::CM_dxt2:
01250     return out << "dxt2";
01251   case EggTexture::CM_dxt3:
01252     return out << "dxt3";
01253   case EggTexture::CM_dxt4:
01254     return out << "dxt4";
01255   case EggTexture::CM_dxt5:
01256     return out << "dxt5";
01257   }
01258 
01259   nassertr(false, out);
01260   return out << "(**invalid**)";
01261 }
01262 
01263 ////////////////////////////////////////////////////////////////////
01264 //     Function: WrapMode output operator
01265 //  Description:
01266 ////////////////////////////////////////////////////////////////////
01267 ostream &operator << (ostream &out, EggTexture::WrapMode mode) {
01268   switch (mode) {
01269   case EggTexture::WM_unspecified:
01270     return out << "unspecified";
01271   case EggTexture::WM_repeat:
01272     return out << "repeat";
01273   case EggTexture::WM_clamp:
01274     return out << "clamp";
01275   case EggTexture::WM_mirror:
01276     return out << "mirror";
01277   case EggTexture::WM_mirror_once:
01278     return out << "mirror_once";
01279   case EggTexture::WM_border_color:
01280     return out << "border_color";
01281   }
01282 
01283   nassertr(false, out);
01284   return out << "(**invalid**)";
01285 }
01286 
01287 ////////////////////////////////////////////////////////////////////
01288 //     Function: FilterType output operator
01289 //  Description:
01290 ////////////////////////////////////////////////////////////////////
01291 ostream &operator << (ostream &out, EggTexture::FilterType type) {
01292   switch (type) {
01293   case EggTexture::FT_unspecified:
01294     return out << "unspecified";
01295 
01296   case EggTexture::FT_nearest:
01297     return out << "nearest";
01298   case EggTexture::FT_linear:
01299     return out << "linear";
01300 
01301   case EggTexture::FT_nearest_mipmap_nearest:
01302     return out << "nearest_mipmap_nearest";
01303   case EggTexture::FT_linear_mipmap_nearest:
01304     return out << "linear_mipmap_nearest";
01305   case EggTexture::FT_nearest_mipmap_linear:
01306     return out << "nearest_mipmap_linear";
01307   case EggTexture::FT_linear_mipmap_linear:
01308     return out << "linear_mipmap_linear";
01309   }
01310 
01311   nassertr(false, out);
01312   return out << "(**invalid**)";
01313 }
01314 
01315 ////////////////////////////////////////////////////////////////////
01316 //     Function: EnvType output operator
01317 //  Description:
01318 ////////////////////////////////////////////////////////////////////
01319 ostream &operator << (ostream &out, EggTexture::EnvType type) {
01320   switch (type) {
01321   case EggTexture::ET_unspecified:
01322     return out << "unspecified";
01323 
01324   case EggTexture::ET_modulate:
01325     return out << "modulate";
01326 
01327   case EggTexture::ET_decal:
01328     return out << "decal";
01329 
01330   case EggTexture::ET_blend:
01331     return out << "blend";
01332 
01333   case EggTexture::ET_replace:
01334     return out << "replace";
01335 
01336   case EggTexture::ET_add:
01337     return out << "add";
01338 
01339   case EggTexture::ET_blend_color_scale:
01340     return out << "blend_color_scale";
01341 
01342   case EggTexture::ET_modulate_glow:
01343     return out << "modulate_glow";
01344 
01345   case EggTexture::ET_modulate_gloss:
01346     return out << "modulate_gloss";
01347 
01348   case EggTexture::ET_normal:
01349     return out << "normal";
01350 
01351   case EggTexture::ET_normal_height:
01352     return out << "normal_height";
01353 
01354   case EggTexture::ET_glow:
01355     return out << "glow";
01356     
01357   case EggTexture::ET_gloss:
01358     return out << "gloss";
01359     
01360   case EggTexture::ET_height:
01361     return out << "height";
01362     
01363   case EggTexture::ET_selector:
01364     return out << "selector";
01365   }
01366 
01367   nassertr(false, out);
01368   return out << "(**invalid**)";
01369 }
01370 
01371 ostream &
01372 operator << (ostream &out, EggTexture::CombineMode cm) {
01373   switch (cm) {
01374   case EggTexture::CM_unspecified:
01375     return out << "unspecified";
01376 
01377   case EggTexture::CM_replace:
01378     return out << "replace";
01379 
01380   case EggTexture::CM_modulate:
01381     return out << "modulate";
01382 
01383   case EggTexture::CM_add:
01384     return out << "add";
01385 
01386   case EggTexture::CM_add_signed:
01387     return out << "add_signed";
01388 
01389   case EggTexture::CM_interpolate:
01390     return out << "interpolate";
01391 
01392   case EggTexture::CM_subtract:
01393     return out << "subtract";
01394 
01395   case EggTexture::CM_dot3_rgb:
01396     return out << "dot3_rgb";
01397 
01398   case EggTexture::CM_dot3_rgba:
01399     return out << "dot3_rgba";
01400   }
01401 
01402   return out << "**invalid CombineMode(" << (int)cm << ")**";
01403 }
01404 
01405 ostream &
01406 operator << (ostream &out, EggTexture::CombineChannel cm) {
01407   switch (cm) {
01408   case EggTexture::CC_rgb:
01409     return out << "rgb";
01410 
01411   case EggTexture::CC_alpha:
01412     return out << "alpha";
01413 
01414   case EggTexture::CC_num_channels:
01415     // This case is here just to prevent a compiler warning.  Fall out
01416     // of the switch and return the error message.
01417     break;
01418   }
01419 
01420   return out << "**invalid CombineChannel(" << (int)cm << ")**";
01421 }
01422 
01423 ostream &
01424 operator << (ostream &out, EggTexture::CombineSource cs) {
01425   switch (cs) {
01426   case EggTexture::CS_unspecified:
01427     return out << "unspecified";
01428 
01429   case EggTexture::CS_texture:
01430     return out << "texture";
01431 
01432   case EggTexture::CS_constant:
01433     return out << "constant";
01434 
01435   case EggTexture::CS_primary_color:
01436     return out << "primary_color";
01437 
01438   case EggTexture::CS_previous:
01439     return out << "previous";
01440 
01441   case EggTexture::CS_constant_color_scale:
01442     return out << "constant_color_scale";
01443 
01444   case EggTexture::CS_last_saved_result:
01445     return out << "last_saved_result";
01446   }
01447 
01448   return out << "**invalid CombineSource(" << (int)cs << ")**";
01449 }
01450 
01451 ostream &
01452 operator << (ostream &out, EggTexture::CombineOperand co) {
01453   switch (co) {
01454   case EggTexture::CO_unspecified:
01455     return out << "unspecified";
01456 
01457   case EggTexture::CO_src_color:
01458     return out << "src_color";
01459 
01460   case EggTexture::CO_one_minus_src_color:
01461     return out << "one_minus_src_color";
01462 
01463   case EggTexture::CO_src_alpha:
01464     return out << "src_alpha";
01465 
01466   case EggTexture::CO_one_minus_src_alpha:
01467     return out << "one_minus_src_alpha";
01468   }
01469 
01470   return out << "**invalid CombineOperand(" << (int)co << ")**";
01471 }
01472 
01473 ostream &
01474 operator << (ostream &out, EggTexture::TexGen tex_gen) {
01475   switch (tex_gen) {
01476   case EggTexture::TG_unspecified:
01477     return out << "unspecified";
01478 
01479   case EggTexture::TG_eye_sphere_map:
01480     return out << "eye_sphere_map";
01481 
01482   case EggTexture::TG_world_cube_map:
01483     return out << "world_cube_map";
01484 
01485   case EggTexture::TG_eye_cube_map:
01486     return out << "eye_cube_map";
01487 
01488   case EggTexture::TG_world_normal:
01489     return out << "world_normal";
01490 
01491   case EggTexture::TG_eye_normal:
01492     return out << "eye_normal";
01493 
01494   case EggTexture::TG_world_position:
01495     return out << "world_position";
01496 
01497   case EggTexture::TG_eye_position:
01498     return out << "eye_position";
01499 
01500   case EggTexture::TG_point_sprite:
01501     return out << "point_sprite";
01502   }
01503 
01504   return out << "**invalid TexGen(" << (int)tex_gen << ")**";
01505 }
01506 
01507 ostream &
01508 operator << (ostream &out, EggTexture::QualityLevel quality_level) {
01509   switch (quality_level) {
01510   case EggTexture::QL_unspecified:
01511     return out << "unspecified";
01512   case EggTexture::QL_default:
01513     return out << "default";
01514   case EggTexture::QL_fastest:
01515     return out << "fastest";
01516   case EggTexture::QL_normal:
01517     return out << "normal";
01518   case EggTexture::QL_best:
01519     return out << "best";
01520   }
01521 
01522   return out << "**invalid QualityLevel(" << (int)quality_level << ")**";
01523 }
 All Classes Functions Variables Enumerations