15 #include "textureProperties.h"
16 #include "palettizer.h"
17 #include "pnmFileType.h"
19 #include "datagramIterator.h"
20 #include "bamReader.h"
21 #include "bamWriter.h"
22 #include "string_utils.h"
33 _got_num_channels =
false;
35 _effective_num_channels = 0;
36 _format = EggTexture::F_unspecified;
37 _force_format =
false;
38 _generic_format =
false;
40 _minfilter = EggTexture::FT_unspecified;
41 _magfilter = EggTexture::FT_unspecified;
42 _quality_level = EggTexture::QL_unspecified;
43 _anisotropic_degree = 0;
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)
76 void TextureProperties::
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;
101 if (!_force_format) {
102 _format = EggTexture::F_unspecified;
105 _minfilter = EggTexture::FT_unspecified;
106 _magfilter = EggTexture::FT_unspecified;
107 _quality_level = EggTexture::QL_unspecified;
108 _anisotropic_degree = 0;
118 return _got_num_channels;
130 nassertr(_got_num_channels, 0);
131 return _effective_num_channels;
143 _num_channels = num_channels;
144 _effective_num_channels = num_channels;
145 _got_num_channels =
true;
157 nassertv(_got_num_channels && _num_channels >= 3);
159 _effective_num_channels = _num_channels;
172 nassertv(_got_num_channels && (_num_channels == 2 || _num_channels == 4));
174 _effective_num_channels = _num_channels;
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:
215 if (_got_num_channels) {
217 num << _effective_num_channels;
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);
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;
245 }
else if (other._force_format) {
246 _format = other._format;
248 _format = union_format(_format, other._format);
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);
255 _anisotropic_degree = other._anisotropic_degree;
258 _color_type = other._color_type;
259 _alpha_type = other._alpha_type;
271 if (!_got_num_channels || _force_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:
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:
291 case EggTexture::F_luminance_alpha:
292 case EggTexture::F_luminance_alphamask:
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:
304 _got_num_channels =
true;
307 _effective_num_channels = _num_channels;
312 if (_generic_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:
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;
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;
345 if (!_force_format && !_keep_format) {
346 switch (_num_channels) {
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:
358 case EggTexture::F_luminance_alpha:
359 case EggTexture::F_luminance_alphamask:
360 _format = EggTexture::F_luminance;
364 _format = EggTexture::F_luminance;
370 case EggTexture::F_luminance_alpha:
371 case EggTexture::F_luminance_alphamask:
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:
383 _format = EggTexture::F_luminance_alpha;
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:
398 case EggTexture::F_rgba8:
399 _format = EggTexture::F_rgb8;
402 case EggTexture::F_rgba5:
403 case EggTexture::F_rgba4:
404 _format = EggTexture::F_rgb5;
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:
416 _format = EggTexture::F_rgb;
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:
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;
440 case EggTexture::F_luminance_alpha:
441 case EggTexture::F_luminance_alphamask:
442 _effective_num_channels = 2;
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;
455 _format = EggTexture::F_rgba;
460 switch (_minfilter) {
461 case EggTexture::FT_unspecified:
462 _minfilter = EggTexture::FT_linear;
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;
483 _color_type = pal->_color_type;
484 _alpha_type = pal->_alpha_type;
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);
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);
525 bool TextureProperties::
527 if (_format != other._format) {
528 return (
int)_format < (int)other._format;
530 if (_minfilter != other._minfilter) {
531 return (
int)_minfilter < (int)other._minfilter;
533 if (_magfilter != other._magfilter) {
534 return (
int)_magfilter < (int)other._magfilter;
536 if (_quality_level != other._quality_level) {
537 return (
int)_quality_level < (int)other._quality_level;
539 if (_anisotropic_degree != other._anisotropic_degree) {
540 return _anisotropic_degree < other._anisotropic_degree;
542 if (_color_type != other._color_type) {
543 return _color_type < other._color_type;
546 if (_alpha_type != other._alpha_type) {
547 return _alpha_type < other._alpha_type;
558 bool TextureProperties::
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 &&
567 _alpha_type == other._alpha_type));
575 bool TextureProperties::
577 return !operator == (other);
586 string TextureProperties::
587 get_format_string(EggTexture::Format format) {
589 case EggTexture::F_unspecified:
592 case EggTexture::F_rgba:
595 case EggTexture::F_rgbm:
598 case EggTexture::F_rgba12:
601 case EggTexture::F_rgba8:
604 case EggTexture::F_rgba4:
607 case EggTexture::F_rgba5:
610 case EggTexture::F_rgb:
613 case EggTexture::F_rgb12:
616 case EggTexture::F_rgb8:
619 case EggTexture::F_rgb5:
622 case EggTexture::F_rgb332:
625 case EggTexture::F_luminance_alpha:
628 case EggTexture::F_luminance_alphamask:
631 case EggTexture::F_red:
634 case EggTexture::F_green:
637 case EggTexture::F_blue:
640 case EggTexture::F_alpha:
643 case EggTexture::F_luminance:
656 string TextureProperties::
657 get_filter_string(EggTexture::FilterType filter_type) {
658 switch (filter_type) {
659 case EggTexture::FT_unspecified:
662 case EggTexture::FT_nearest:
665 case EggTexture::FT_linear:
668 case EggTexture::FT_nearest_mipmap_nearest:
671 case EggTexture::FT_linear_mipmap_nearest:
674 case EggTexture::FT_nearest_mipmap_linear:
677 case EggTexture::FT_linear_mipmap_linear:
689 string TextureProperties::
690 get_anisotropic_degree_string(
int aniso_degree) {
691 if (aniso_degree <= 1) {
694 return string(
"an") + format_string(aniso_degree);
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:
710 case EggTexture::QL_fastest:
713 case EggTexture::QL_normal:
716 case EggTexture::QL_best:
728 string TextureProperties::
745 EggTexture::Format TextureProperties::
746 union_format(EggTexture::Format a, EggTexture::Format b) {
748 case EggTexture::F_unspecified:
751 case EggTexture::F_rgba:
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:
768 case EggTexture::F_rgb:
769 if (b != EggTexture::F_unspecified) {
785 EggTexture::FilterType TextureProperties::
786 union_filter(EggTexture::FilterType a, EggTexture::FilterType b) {
787 if ((
int)a < (
int)b) {
800 EggTexture::QualityLevel TextureProperties::
801 union_quality_level(EggTexture::QualityLevel a, EggTexture::QualityLevel b) {
802 if ((
int)a < (
int)b) {
818 register_factory(get_class_type(), make_TextureProperties);
831 datagram.
add_bool(_got_num_channels);
833 datagram.
add_int32(_effective_num_channels);
860 DCAST_INTO_R(_color_type, p_list[index], index);
865 DCAST_INTO_R(_alpha_type, p_list[index], index);
886 parse_params(params, scan, manager);
887 me->
fillin(scan, manager);
901 _got_num_channels = scan.
get_bool();
903 _effective_num_channels = _num_channels;
904 if (Palettizer::_read_pi_version >= 9) {
905 _effective_num_channels = scan.
get_int32();
907 _format = (EggTexture::Format)scan.
get_int32();
909 _generic_format =
false;
910 if (Palettizer::_read_pi_version >= 9) {
913 _keep_format =
false;
914 if (Palettizer::_read_pi_version >= 13) {
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();
void set_num_channels(int num_channels)
Sets the number of channels (1 through 4) associated with the image, presumably after reading this in...
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...
Defines a texture map that may be applied to geometry.
Base class for objects that can be written to and read from Bam files.
This is the base class of a family of classes that represent particular image file types that PNMImag...
virtual int complete_pointers(TypedWritable **p_list, BamReader *manager)
Called after the object is otherwise completely read from a Bam file, this function'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 ...
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'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.
int get_num_channels() const
Returns the number of channels (1 through 4) associated with the image.
void set_anisotropic_degree(int anisotropic_degree)
Sets the degree of anisotropic filtering for this texture.
void add_bool(bool value)
Adds a boolean value to the datagram.
void update_egg_tex(EggTexture *egg_tex) const
Adjusts the texture properties of the indicated egg reference to match these properties.
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()...
bool uses_alpha() const
Returns true if the texture uses an alpha channel, false otherwise.
An instance of this class is passed to the Factory when requesting it to do its business and construc...
void force_nonalpha()
Sets the actual number of channels to indicate an image with no alpha channel, presumably after disco...
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...
void fillin(DatagramIterator &scan, BamReader *manager)
Reads the binary data from the given datagram iterator, which was written by a previous call to write...
bool has_num_channels() const
Returns true if the number of channels is known.
string get_string() const
Returns a string corresponding to the TextureProperties object.
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.
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.
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.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
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.
void read_pointer(DatagramIterator &scan)
The interface for reading a pointer to another object from a Bam file.
This is the set of characteristics of a texture that, if different from another texture, prevent the two textures from sharing a PaletteImage.