Panda3D
textureProperties.cxx
1 // Filename: textureProperties.cxx
2 // Created by: drose (29Nov00)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "textureProperties.h"
16 #include "palettizer.h"
17 #include "pnmFileType.h"
18 #include "datagram.h"
19 #include "datagramIterator.h"
20 #include "bamReader.h"
21 #include "bamWriter.h"
22 #include "string_utils.h"
23 
24 TypeHandle TextureProperties::_type_handle;
25 
26 ////////////////////////////////////////////////////////////////////
27 // Function: TextureProperties::Constructor
28 // Access: Public
29 // Description:
30 ////////////////////////////////////////////////////////////////////
31 TextureProperties::
32 TextureProperties() {
33  _got_num_channels = false;
34  _num_channels = 0;
35  _effective_num_channels = 0;
36  _format = EggTexture::F_unspecified;
37  _force_format = false;
38  _generic_format = false;
39  _keep_format = false;
40  _minfilter = EggTexture::FT_unspecified;
41  _magfilter = EggTexture::FT_unspecified;
42  _quality_level = EggTexture::QL_unspecified;
43  _anisotropic_degree = 0;
44  _color_type = (PNMFileType *)NULL;
45  _alpha_type = (PNMFileType *)NULL;
46 }
47 
48 ////////////////////////////////////////////////////////////////////
49 // Function: TextureProperties::Copy Constructor
50 // Access: Public
51 // Description:
52 ////////////////////////////////////////////////////////////////////
53 TextureProperties::
54 TextureProperties(const TextureProperties &copy) :
55  _format(copy._format),
56  _force_format(copy._force_format),
57  _generic_format(copy._generic_format),
58  _keep_format(copy._keep_format),
59  _minfilter(copy._minfilter),
60  _magfilter(copy._magfilter),
61  _quality_level(copy._quality_level),
62  _anisotropic_degree(copy._anisotropic_degree),
63  _color_type(copy._color_type),
64  _alpha_type(copy._alpha_type),
65  _got_num_channels(copy._got_num_channels),
66  _num_channels(copy._num_channels),
67  _effective_num_channels(copy._effective_num_channels)
68 {
69 }
70 
71 ////////////////////////////////////////////////////////////////////
72 // Function: TextureProperties::Copy Assignment Operator
73 // Access: Public
74 // Description:
75 ////////////////////////////////////////////////////////////////////
76 void TextureProperties::
77 operator = (const TextureProperties &copy) {
78  _force_format = copy._force_format;
79  _generic_format = copy._generic_format;
80  _keep_format = copy._keep_format;
81  _minfilter = copy._minfilter;
82  _magfilter = copy._magfilter;
83  _quality_level = copy._quality_level;
84  _anisotropic_degree = copy._anisotropic_degree;
85  _color_type = copy._color_type;
86  _alpha_type = copy._alpha_type;
87  _got_num_channels = copy._got_num_channels;
88  _num_channels = copy._num_channels;
89  _effective_num_channels = copy._effective_num_channels;
90  _format = copy._format;
91 }
92 
93 ////////////////////////////////////////////////////////////////////
94 // Function: TextureProperties::clear_basic
95 // Access: Public
96 // Description: Resets only the properties that might be changed by
97 // update_properties() to a neutral state.
98 ////////////////////////////////////////////////////////////////////
101  if (!_force_format) {
102  _format = EggTexture::F_unspecified;
103  }
104 
105  _minfilter = EggTexture::FT_unspecified;
106  _magfilter = EggTexture::FT_unspecified;
107  _quality_level = EggTexture::QL_unspecified;
108  _anisotropic_degree = 0;
109 }
110 
111 ////////////////////////////////////////////////////////////////////
112 // Function: TextureProperties::has_num_channels
113 // Access: Public
114 // Description: Returns true if the number of channels is known.
115 ////////////////////////////////////////////////////////////////////
118  return _got_num_channels;
119 }
120 
121 ////////////////////////////////////////////////////////////////////
122 // Function: TextureProperties::get_num_channels
123 // Access: Public
124 // Description: Returns the number of channels (1 through 4)
125 // associated with the image. It is an error to call
126 // this unless has_num_channels() returns true.
127 ////////////////////////////////////////////////////////////////////
130  nassertr(_got_num_channels, 0);
131  return _effective_num_channels;
132 }
133 
134 ////////////////////////////////////////////////////////////////////
135 // Function: TextureProperties::set_num_channels
136 // Access: Public
137 // Description: Sets the number of channels (1 through 4)
138 // associated with the image, presumably after reading
139 // this information from the image header.
140 ////////////////////////////////////////////////////////////////////
142 set_num_channels(int num_channels) {
143  _num_channels = num_channels;
144  _effective_num_channels = num_channels;
145  _got_num_channels = true;
146 }
147 
148 ////////////////////////////////////////////////////////////////////
149 // Function: TextureProperties::force_grayscale
150 // Access: Public
151 // Description: Sets the actual number of channels to indicate a
152 // grayscale image, presumably after discovering that
153 // the image contains no colored pixels.
154 ////////////////////////////////////////////////////////////////////
157  nassertv(_got_num_channels && _num_channels >= 3);
158  _num_channels -= 2;
159  _effective_num_channels = _num_channels;
160 }
161 
162 ////////////////////////////////////////////////////////////////////
163 // Function: TextureProperties::force_nonalpha
164 // Access: Public
165 // Description: Sets the actual number of channels to indicate an
166 // image with no alpha channel, presumably after
167 // discovering that the alpha channel contains no
168 // meaningful pixels.
169 ////////////////////////////////////////////////////////////////////
172  nassertv(_got_num_channels && (_num_channels == 2 || _num_channels == 4));
173  _num_channels--;
174  _effective_num_channels = _num_channels;
175 }
176 
177 ////////////////////////////////////////////////////////////////////
178 // Function: TextureProperties::uses_alpha
179 // Access: Public
180 // Description: Returns true if the texture uses an alpha channel,
181 // false otherwise.
182 ////////////////////////////////////////////////////////////////////
184 uses_alpha() const {
185  switch (_format) {
186  case EggTexture::F_rgba:
187  case EggTexture::F_rgbm:
188  case EggTexture::F_rgba12:
189  case EggTexture::F_rgba8:
190  case EggTexture::F_rgba4:
191  case EggTexture::F_rgba5:
192  case EggTexture::F_alpha:
193  case EggTexture::F_luminance_alpha:
194  case EggTexture::F_luminance_alphamask:
195  return true;
196 
197  default:
198  return false;
199  }
200 }
201 
202 ////////////////////////////////////////////////////////////////////
203 // Function: TextureProperties::get_string
204 // Access: Public
205 // Description: Returns a string corresponding to the
206 // TextureProperties object. Each unique set of
207 // TextureProperties will generate a unique string.
208 // This is used to generate unique palette image
209 // filenames.
210 ////////////////////////////////////////////////////////////////////
211 string TextureProperties::
212 get_string() const {
213  string result;
214 
215  if (_got_num_channels) {
216  ostringstream num;
217  num << _effective_num_channels;
218  result += num.str();
219  }
220 
221  result += get_format_string(_format);
222  result += get_filter_string(_minfilter);
223  result += get_filter_string(_magfilter);
224  result += get_anisotropic_degree_string(_anisotropic_degree);
225  result += get_type_string(_color_type, _alpha_type);
226  result += get_quality_level_string(_quality_level);
227  return result;
228 }
229 
230 ////////////////////////////////////////////////////////////////////
231 // Function: TextureProperties::update_properties
232 // Access: Public
233 // Description: If the indicate TextureProperties structure is more
234 // specific than this one, updates this one.
235 ////////////////////////////////////////////////////////////////////
238  if (!_got_num_channels) {
239  _got_num_channels = other._got_num_channels;
240  _num_channels = other._num_channels;
241  _effective_num_channels = _num_channels;
242  }
243  if (_force_format) {
244  // If we've forced our own format, it doesn't change.
245  } else if (other._force_format) {
246  _format = other._format;
247  } else {
248  _format = union_format(_format, other._format);
249  }
250 
251  _minfilter = union_filter(_minfilter, other._minfilter);
252  _magfilter = union_filter(_magfilter, other._magfilter);
253  _quality_level = union_quality_level(_quality_level, other._quality_level);
254 
255  _anisotropic_degree = other._anisotropic_degree;
256 
257  if (_color_type == (PNMFileType *)NULL) {
258  _color_type = other._color_type;
259  _alpha_type = other._alpha_type;
260  }
261 }
262 
263 ////////////////////////////////////////////////////////////////////
264 // Function: TextureProperties::fully_define
265 // Access: Public
266 // Description: If any properties remain unspecified, specify them
267 // now. Also reconcile conflicting information.
268 ////////////////////////////////////////////////////////////////////
271  if (!_got_num_channels || _force_format) {
272  switch (_format) {
273  case EggTexture::F_rgba:
274  case EggTexture::F_rgbm:
275  case EggTexture::F_rgba12:
276  case EggTexture::F_rgba8:
277  case EggTexture::F_rgba4:
278  case EggTexture::F_rgba5:
279  _num_channels = 4;
280  break;
281 
282  case EggTexture::F_unspecified:
283  case EggTexture::F_rgb:
284  case EggTexture::F_rgb12:
285  case EggTexture::F_rgb8:
286  case EggTexture::F_rgb5:
287  case EggTexture::F_rgb332:
288  _num_channels = 3;
289  break;
290 
291  case EggTexture::F_luminance_alpha:
292  case EggTexture::F_luminance_alphamask:
293  _num_channels = 2;
294  break;
295 
296  case EggTexture::F_red:
297  case EggTexture::F_green:
298  case EggTexture::F_blue:
299  case EggTexture::F_alpha:
300  case EggTexture::F_luminance:
301  _num_channels = 1;
302  break;
303  }
304  _got_num_channels = true;
305  }
306 
307  _effective_num_channels = _num_channels;
308 
309  // Respect the _generic_format flag. If this is set, it means the
310  // user has indicated that we should strip off any bitcount-specific
311  // formats and replace them with the more generic equivalents.
312  if (_generic_format) {
313  switch (_format) {
314  case EggTexture::F_unspecified:
315  case EggTexture::F_rgba:
316  case EggTexture::F_rgbm:
317  case EggTexture::F_rgb:
318  case EggTexture::F_red:
319  case EggTexture::F_green:
320  case EggTexture::F_blue:
321  case EggTexture::F_alpha:
322  case EggTexture::F_luminance:
323  case EggTexture::F_luminance_alpha:
324  case EggTexture::F_luminance_alphamask:
325  break;
326 
327  case EggTexture::F_rgba12:
328  case EggTexture::F_rgba8:
329  case EggTexture::F_rgba4:
330  case EggTexture::F_rgba5:
331  _format = EggTexture::F_rgba;
332  break;
333 
334  case EggTexture::F_rgb12:
335  case EggTexture::F_rgb8:
336  case EggTexture::F_rgb5:
337  case EggTexture::F_rgb332:
338  _format = EggTexture::F_rgb;
339  break;
340  }
341  }
342 
343  // Make sure the format reflects the number of channels, although we
344  // accept a format that ignores an alpha channel.
345  if (!_force_format && !_keep_format) {
346  switch (_num_channels) {
347  case 1:
348  switch (_format) {
349  case EggTexture::F_red:
350  case EggTexture::F_green:
351  case EggTexture::F_blue:
352  case EggTexture::F_alpha:
353  case EggTexture::F_luminance:
354  break;
355 
356  // These formats suggest an alpha channel; they are quietly
357  // replaced with non-alpha equivalents.
358  case EggTexture::F_luminance_alpha:
359  case EggTexture::F_luminance_alphamask:
360  _format = EggTexture::F_luminance;
361  break;
362 
363  default:
364  _format = EggTexture::F_luminance;
365  }
366  break;
367 
368  case 2:
369  switch (_format) {
370  case EggTexture::F_luminance_alpha:
371  case EggTexture::F_luminance_alphamask:
372  break;
373 
374  // These formats implicitly reduce the number of channels to 1.
375  case EggTexture::F_red:
376  case EggTexture::F_green:
377  case EggTexture::F_blue:
378  case EggTexture::F_alpha:
379  case EggTexture::F_luminance:
380  break;
381 
382  default:
383  _format = EggTexture::F_luminance_alpha;
384  }
385  break;
386 
387  case 3:
388  switch (_format) {
389  case EggTexture::F_rgb:
390  case EggTexture::F_rgb12:
391  case EggTexture::F_rgb8:
392  case EggTexture::F_rgb5:
393  case EggTexture::F_rgb332:
394  break;
395 
396  // These formats suggest an alpha channel; they are quietly
397  // replaced with non-alpha equivalents.
398  case EggTexture::F_rgba8:
399  _format = EggTexture::F_rgb8;
400  break;
401 
402  case EggTexture::F_rgba5:
403  case EggTexture::F_rgba4:
404  _format = EggTexture::F_rgb5;
405  break;
406 
407  // These formats implicitly reduce the number of channels to 1.
408  case EggTexture::F_red:
409  case EggTexture::F_green:
410  case EggTexture::F_blue:
411  case EggTexture::F_alpha:
412  case EggTexture::F_luminance:
413  break;
414 
415  default:
416  _format = EggTexture::F_rgb;
417  }
418  break;
419 
420  case 4:
421  switch (_format) {
422  case EggTexture::F_rgba:
423  case EggTexture::F_rgbm:
424  case EggTexture::F_rgba12:
425  case EggTexture::F_rgba8:
426  case EggTexture::F_rgba4:
427  case EggTexture::F_rgba5:
428  break;
429 
430  // These formats implicitly reduce the number of channels to 3.
431  case EggTexture::F_rgb:
432  case EggTexture::F_rgb12:
433  case EggTexture::F_rgb8:
434  case EggTexture::F_rgb5:
435  case EggTexture::F_rgb332:
436  _effective_num_channels = 3;
437  break;
438 
439  // These formats implicitly reduce the number of channels to 2.
440  case EggTexture::F_luminance_alpha:
441  case EggTexture::F_luminance_alphamask:
442  _effective_num_channels = 2;
443  break;
444 
445  // These formats implicitly reduce the number of channels to 1.
446  case EggTexture::F_red:
447  case EggTexture::F_green:
448  case EggTexture::F_blue:
449  case EggTexture::F_alpha:
450  case EggTexture::F_luminance:
451  _effective_num_channels = 1;
452  break;
453 
454  default:
455  _format = EggTexture::F_rgba;
456  }
457  }
458  }
459 
460  switch (_minfilter) {
461  case EggTexture::FT_unspecified:
462  _minfilter = EggTexture::FT_linear;
463  break;
464 
465  default:
466  break;
467  }
468 
469  switch (_magfilter) {
470  case EggTexture::FT_unspecified:
471  case EggTexture::FT_nearest_mipmap_nearest:
472  case EggTexture::FT_linear_mipmap_nearest:
473  case EggTexture::FT_nearest_mipmap_linear:
474  case EggTexture::FT_linear_mipmap_linear:
475  _magfilter = EggTexture::FT_linear;
476  break;
477 
478  default:
479  break;
480  }
481 
482  if (_color_type == (PNMFileType *)NULL) {
483  _color_type = pal->_color_type;
484  _alpha_type = pal->_alpha_type;
485  }
486 }
487 
488 ////////////////////////////////////////////////////////////////////
489 // Function: TextureProperties::update_egg_tex
490 // Access: Public
491 // Description: Adjusts the texture properties of the indicated egg
492 // reference to match these properties.
493 ////////////////////////////////////////////////////////////////////
495 update_egg_tex(EggTexture *egg_tex) const {
496  egg_tex->set_format(_format);
497  egg_tex->set_minfilter(_minfilter);
498  egg_tex->set_magfilter(_minfilter);
499  egg_tex->set_quality_level(_quality_level);
500  egg_tex->set_anisotropic_degree(_anisotropic_degree);
501 }
502 
503 ////////////////////////////////////////////////////////////////////
504 // Function: TextureProperties::egg_properties_match
505 // Access: Public
506 // Description: Returns true if all of the properties that are
507 // reflected directly in an egg file match between this
508 // TextureProperties object and the other, or false if
509 // any of them differ.
510 ////////////////////////////////////////////////////////////////////
513  return (_format == other._format &&
514  _minfilter == other._minfilter &&
515  _magfilter == other._magfilter &&
516  _quality_level == other._quality_level &&
517  _anisotropic_degree == other._anisotropic_degree);
518 }
519 
520 ////////////////////////////////////////////////////////////////////
521 // Function: TextureProperties::Ordering Operator
522 // Access: Public
523 // Description:
524 ////////////////////////////////////////////////////////////////////
525 bool TextureProperties::
526 operator < (const TextureProperties &other) const {
527  if (_format != other._format) {
528  return (int)_format < (int)other._format;
529  }
530  if (_minfilter != other._minfilter) {
531  return (int)_minfilter < (int)other._minfilter;
532  }
533  if (_magfilter != other._magfilter) {
534  return (int)_magfilter < (int)other._magfilter;
535  }
536  if (_quality_level != other._quality_level) {
537  return (int)_quality_level < (int)other._quality_level;
538  }
539  if (_anisotropic_degree != other._anisotropic_degree) {
540  return _anisotropic_degree < other._anisotropic_degree;
541  }
542  if (_color_type != other._color_type) {
543  return _color_type < other._color_type;
544  }
545  if (_color_type != (PNMFileType *)NULL) {
546  if (_alpha_type != other._alpha_type) {
547  return _alpha_type < other._alpha_type;
548  }
549  }
550  return false;
551 }
552 
553 ////////////////////////////////////////////////////////////////////
554 // Function: TextureProperties::Equality Operator
555 // Access: Public
556 // Description:
557 ////////////////////////////////////////////////////////////////////
558 bool TextureProperties::
559 operator == (const TextureProperties &other) const {
560  return (_format == other._format &&
561  _minfilter == other._minfilter &&
562  _magfilter == other._magfilter &&
563  _quality_level == other._quality_level &&
564  _anisotropic_degree == other._anisotropic_degree &&
565  _color_type == other._color_type &&
566  (_color_type == (PNMFileType *)NULL ||
567  _alpha_type == other._alpha_type));
568 }
569 
570 ////////////////////////////////////////////////////////////////////
571 // Function: TextureProperties::Nonequality Operator
572 // Access: Public
573 // Description:
574 ////////////////////////////////////////////////////////////////////
575 bool TextureProperties::
576 operator != (const TextureProperties &other) const {
577  return !operator == (other);
578 }
579 
580 ////////////////////////////////////////////////////////////////////
581 // Function: TextureProperties::get_format_string
582 // Access: Private, Static
583 // Description: Returns a short string representing the given
584 // EggTexture format.
585 ////////////////////////////////////////////////////////////////////
586 string TextureProperties::
587 get_format_string(EggTexture::Format format) {
588  switch (format) {
589  case EggTexture::F_unspecified:
590  return "u";
591 
592  case EggTexture::F_rgba:
593  return "a";
594 
595  case EggTexture::F_rgbm:
596  return "m";
597 
598  case EggTexture::F_rgba12:
599  return "a12";
600 
601  case EggTexture::F_rgba8:
602  return "a8";
603 
604  case EggTexture::F_rgba4:
605  return "a4";
606 
607  case EggTexture::F_rgba5:
608  return "a5";
609 
610  case EggTexture::F_rgb:
611  return "c";
612 
613  case EggTexture::F_rgb12:
614  return "c12";
615 
616  case EggTexture::F_rgb8:
617  return "c8";
618 
619  case EggTexture::F_rgb5:
620  return "c5";
621 
622  case EggTexture::F_rgb332:
623  return "c3";
624 
625  case EggTexture::F_luminance_alpha:
626  return "t"; // t for two-channel
627 
628  case EggTexture::F_luminance_alphamask:
629  return "t1";
630 
631  case EggTexture::F_red:
632  return "r";
633 
634  case EggTexture::F_green:
635  return "g";
636 
637  case EggTexture::F_blue:
638  return "b";
639 
640  case EggTexture::F_alpha:
641  return "a";
642 
643  case EggTexture::F_luminance:
644  return "l";
645  }
646 
647  return "x";
648 }
649 
650 ////////////////////////////////////////////////////////////////////
651 // Function: TextureProperties::get_filter_string
652 // Access: Private, Static
653 // Description: Returns a short string representing the given
654 // EggTexture filter type.
655 ////////////////////////////////////////////////////////////////////
656 string TextureProperties::
657 get_filter_string(EggTexture::FilterType filter_type) {
658  switch (filter_type) {
659  case EggTexture::FT_unspecified:
660  return "u";
661 
662  case EggTexture::FT_nearest:
663  return "n";
664 
665  case EggTexture::FT_linear:
666  return "l";
667 
668  case EggTexture::FT_nearest_mipmap_nearest:
669  return "m1";
670 
671  case EggTexture::FT_linear_mipmap_nearest:
672  return "m2";
673 
674  case EggTexture::FT_nearest_mipmap_linear:
675  return "m3";
676 
677  case EggTexture::FT_linear_mipmap_linear:
678  return "m";
679  }
680 
681  return "x";
682 }
683 
684 ////////////////////////////////////////////////////////////////////
685 // Function: TextureProperties::get_anisotropic_degree_string
686 // Access: Private, Static
687 // Description: Returns a short string describing the anisotropic degree.
688 ////////////////////////////////////////////////////////////////////
689 string TextureProperties::
690 get_anisotropic_degree_string(int aniso_degree) {
691  if (aniso_degree <= 1) {
692  return "";
693  } else {
694  return string("an") + format_string(aniso_degree);
695  }
696 }
697 
698 ////////////////////////////////////////////////////////////////////
699 // Function: TextureProperties::get_quality_level_string
700 // Access: Private, Static
701 // Description: Returns a short string describing the quality level.
702 ////////////////////////////////////////////////////////////////////
703 string TextureProperties::
704 get_quality_level_string(EggTexture::QualityLevel quality_level) {
705  switch (quality_level) {
706  case EggTexture::QL_unspecified:
707  case EggTexture::QL_default:
708  return "";
709 
710  case EggTexture::QL_fastest:
711  return "f";
712 
713  case EggTexture::QL_normal:
714  return "n";
715 
716  case EggTexture::QL_best:
717  return "b";
718  }
719  return "";
720 }
721 
722 ////////////////////////////////////////////////////////////////////
723 // Function: TextureProperties::get_type_string
724 // Access: Private, Static
725 // Description: Returns a short string representing whether the color
726 // and/or alpha type has been specified or not.
727 ////////////////////////////////////////////////////////////////////
728 string TextureProperties::
729 get_type_string(PNMFileType *color_type, PNMFileType *alpha_type) {
730  if (color_type == (PNMFileType *)NULL) {
731  return "";
732  }
733  if (alpha_type == (PNMFileType *)NULL) {
734  return "c";
735  }
736  return "a";
737 }
738 
739 ////////////////////////////////////////////////////////////////////
740 // Function: TextureProperties::union_format
741 // Access: Private, Static
742 // Description: Returns the EggTexture format which is the more
743 // specific of the two.
744 ////////////////////////////////////////////////////////////////////
745 EggTexture::Format TextureProperties::
746 union_format(EggTexture::Format a, EggTexture::Format b) {
747  switch (a) {
748  case EggTexture::F_unspecified:
749  return b;
750 
751  case EggTexture::F_rgba:
752  switch (b) {
753  case EggTexture::F_rgbm:
754  case EggTexture::F_rgba12:
755  case EggTexture::F_rgba8:
756  case EggTexture::F_rgba4:
757  case EggTexture::F_rgba5:
758  case EggTexture::F_red:
759  case EggTexture::F_green:
760  case EggTexture::F_blue:
761  case EggTexture::F_alpha:
762  return b;
763 
764  default:
765  return a;
766  };
767 
768  case EggTexture::F_rgb:
769  if (b != EggTexture::F_unspecified) {
770  return b;
771  }
772  return a;
773 
774  default:
775  return a;
776  }
777 }
778 
779 ////////////////////////////////////////////////////////////////////
780 // Function: TextureProperties::union_filter
781 // Access: Private, Static
782 // Description: Returns the EggTexture filter type which is the more
783 // specific of the two.
784 ////////////////////////////////////////////////////////////////////
785 EggTexture::FilterType TextureProperties::
786 union_filter(EggTexture::FilterType a, EggTexture::FilterType b) {
787  if ((int)a < (int)b) {
788  return b;
789  } else {
790  return a;
791  }
792 }
793 
794 ////////////////////////////////////////////////////////////////////
795 // Function: TextureProperties::union_quality_level
796 // Access: Private, Static
797 // Description: Returns the EggTexture quality level which is the
798 // more specific of the two.
799 ////////////////////////////////////////////////////////////////////
800 EggTexture::QualityLevel TextureProperties::
801 union_quality_level(EggTexture::QualityLevel a, EggTexture::QualityLevel b) {
802  if ((int)a < (int)b) {
803  return b;
804  } else {
805  return a;
806  }
807 }
808 
809 ////////////////////////////////////////////////////////////////////
810 // Function: TextureProperties::register_with_read_factory
811 // Access: Public, Static
812 // Description: Registers the current object as something that can be
813 // read from a Bam file.
814 ////////////////////////////////////////////////////////////////////
818  register_factory(get_class_type(), make_TextureProperties);
819 }
820 
821 ////////////////////////////////////////////////////////////////////
822 // Function: TextureProperties::write_datagram
823 // Access: Public, Virtual
824 // Description: Fills the indicated datagram up with a binary
825 // representation of the current object, in preparation
826 // for writing to a Bam file.
827 ////////////////////////////////////////////////////////////////////
829 write_datagram(BamWriter *writer, Datagram &datagram) {
830  TypedWritable::write_datagram(writer, datagram);
831  datagram.add_bool(_got_num_channels);
832  datagram.add_int32(_num_channels);
833  datagram.add_int32(_effective_num_channels);
834  datagram.add_int32((int)_format);
835  datagram.add_bool(_force_format);
836  datagram.add_bool(_generic_format);
837  datagram.add_bool(_keep_format);
838  datagram.add_int32((int)_minfilter);
839  datagram.add_int32((int)_magfilter);
840  datagram.add_int32((int)_quality_level);
841  datagram.add_int32(_anisotropic_degree);
842  writer->write_pointer(datagram, _color_type);
843  writer->write_pointer(datagram, _alpha_type);
844 }
845 
846 ////////////////////////////////////////////////////////////////////
847 // Function: TextureProperties::complete_pointers
848 // Access: Public, Virtual
849 // Description: Called after the object is otherwise completely read
850 // from a Bam file, this function's job is to store the
851 // pointers that were retrieved from the Bam file for
852 // each pointer object written. The return value is the
853 // number of pointers processed from the list.
854 ////////////////////////////////////////////////////////////////////
857  int index = TypedWritable::complete_pointers(p_list, manager);
858 
859  if (p_list[index] != (TypedWritable *)NULL) {
860  DCAST_INTO_R(_color_type, p_list[index], index);
861  }
862  index++;
863 
864  if (p_list[index] != (TypedWritable *)NULL) {
865  DCAST_INTO_R(_alpha_type, p_list[index], index);
866  }
867  index++;
868 
869  return index;
870 }
871 
872 ////////////////////////////////////////////////////////////////////
873 // Function: TextureProperties::make_TextureProperties
874 // Access: Protected
875 // Description: This method is called by the BamReader when an object
876 // of this type is encountered in a Bam file; it should
877 // allocate and return a new object with all the data
878 // read.
879 ////////////////////////////////////////////////////////////////////
880 TypedWritable* TextureProperties::
881 make_TextureProperties(const FactoryParams &params) {
883  DatagramIterator scan;
884  BamReader *manager;
885 
886  parse_params(params, scan, manager);
887  me->fillin(scan, manager);
888  return me;
889 }
890 
891 ////////////////////////////////////////////////////////////////////
892 // Function: TextureProperties::fillin
893 // Access: Protected
894 // Description: Reads the binary data from the given datagram
895 // iterator, which was written by a previous call to
896 // write_datagram().
897 ////////////////////////////////////////////////////////////////////
900  TypedWritable::fillin(scan, manager);
901  _got_num_channels = scan.get_bool();
902  _num_channels = scan.get_int32();
903  _effective_num_channels = _num_channels;
904  if (Palettizer::_read_pi_version >= 9) {
905  _effective_num_channels = scan.get_int32();
906  }
907  _format = (EggTexture::Format)scan.get_int32();
908  _force_format = scan.get_bool();
909  _generic_format = false;
910  if (Palettizer::_read_pi_version >= 9) {
911  _generic_format = scan.get_bool();
912  }
913  _keep_format = false;
914  if (Palettizer::_read_pi_version >= 13) {
915  _keep_format = scan.get_bool();
916  }
917  _minfilter = (EggTexture::FilterType)scan.get_int32();
918  _magfilter = (EggTexture::FilterType)scan.get_int32();
919  if (Palettizer::_read_pi_version >= 18) {
920  _quality_level = (EggTexture::QualityLevel)scan.get_int32();
921  }
922  _anisotropic_degree = scan.get_int32();
923 
924  manager->read_pointer(scan); // _color_type
925  manager->read_pointer(scan); // _alpha_type
926 }
void set_num_channels(int num_channels)
Sets the number of channels (1 through 4) associated with the image, presumably after reading this in...
int get_num_channels() const
Returns the number of channels (1 through 4) associated with the image.
bool get_bool()
Extracts a boolean value.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:122
Defines a texture map that may be applied to geometry.
Definition: eggTexture.h:33
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:37
This is the base class of a family of classes that represent particular image file types that PNMImag...
Definition: pnmFileType.h:35
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Called after the object is otherwise completely read from a Bam file, this function&#39;s job is to store...
virtual void write_datagram(BamWriter *writer, Datagram &datagram)
Fills the indicated datagram up with a binary representation of the current object, in preparation for writing to a Bam file.
This is the fundamental interface for writing binary objects to a Bam file, to be extracted later by ...
Definition: bamWriter.h:73
PN_int32 get_int32()
Extracts a signed 32-bit integer.
virtual void fillin(DatagramIterator &scan, BamReader *manager)
This internal function is intended to be called by each class&#39;s make_from_bam() method to read in all...
virtual void write_datagram(BamWriter *manager, Datagram &dg)
Writes the contents of this object to the datagram for shipping out to a Bam file.
void update_egg_tex(EggTexture *egg_tex) const
Adjusts the texture properties of the indicated egg reference to match these properties.
string get_string() const
Returns a string corresponding to the TextureProperties object.
void set_anisotropic_degree(int anisotropic_degree)
Sets the degree of anisotropic filtering for this texture.
Definition: eggTexture.I:252
void add_bool(bool value)
Adds a boolean value to the datagram.
Definition: datagram.I:118
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Receives an array of pointers, one for each time manager->read_pointer() was called in fillin()...
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:40
void force_nonalpha()
Sets the actual number of channels to indicate an image with no alpha channel, presumably after disco...
bool uses_alpha() const
Returns true if the texture uses an alpha channel, false otherwise.
bool has_num_channels() const
Returns true if the number of channels is known.
void fillin(DatagramIterator &scan, BamReader *manager)
Reads the binary data from the given datagram iterator, which was written by a previous call to write...
void force_grayscale()
Sets the actual number of channels to indicate a grayscale image, presumably after discovering that t...
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:213
bool egg_properties_match(const TextureProperties &other) const
Returns true if all of the properties that are reflected directly in an egg file match between this T...
static void register_with_read_factory()
Registers the current object as something that can be read from a Bam file.
void clear_basic()
Resets only the properties that might be changed by update_properties() to a neutral state...
void add_int32(PN_int32 value)
Adds a signed 32-bit integer to the datagram.
Definition: datagram.I:159
A class to retrieve the individual data elements previously stored in a Datagram. ...
void update_properties(const TextureProperties &other)
If the indicate TextureProperties structure is more specific than this one, updates this one...
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:43
void fully_define()
If any properties remain unspecified, specify them now.
void write_pointer(Datagram &packet, const TypedWritable *dest)
The interface for writing a pointer to another object to a Bam file.
Definition: bamWriter.cxx:279
void read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
Definition: bamReader.cxx:658
This is the set of characteristics of a texture that, if different from another texture, prevent the two textures from sharing a PaletteImage.