From 0287c81e94ef0a871b8fad598d98be7f33ef1788 Mon Sep 17 00:00:00 2001 From: David Rose Date: Tue, 28 Nov 2000 18:29:47 +0000 Subject: [PATCH] *** empty log message *** --- panda/src/egg/eggTexture.I | 51 +++++++++++++++++++++++++++ panda/src/egg/eggTexture.cxx | 63 ++++++++++++++++++++++------------ panda/src/egg/eggTexture.h | 29 +++++++++++++--- panda/src/egg/parser.yxx | 3 ++ panda/src/egg2sg/eggLoader.cxx | 54 +++++++++++++++++++++-------- panda/src/gobj/texture.I | 15 ++++++++ panda/src/gobj/texture.cxx | 28 +++++++++++++-- panda/src/gobj/texture.h | 16 +++++++++ panda/src/putil/bam.h | 3 +- 9 files changed, 219 insertions(+), 43 deletions(-) diff --git a/panda/src/egg/eggTexture.I b/panda/src/egg/eggTexture.I index b4fef438ea..67110721ac 100644 --- a/panda/src/egg/eggTexture.I +++ b/panda/src/egg/eggTexture.I @@ -192,6 +192,57 @@ get_magfiltercolor() const { return _magfiltercolor; } +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::set_anisotropic_degree +// Access: Public +// Description: Sets the degree of anisotropic filtering for this +// texture. 1 is off; higher levels indicate filtering +// in effect. +//////////////////////////////////////////////////////////////////// +INLINE void EggTexture:: +set_anisotropic_degree(int anisotropic_degree) { + _anisotropic_degree = anisotropic_degree; + _flags |= F_has_anisotropic_degree; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::clear_anisotropic_degree +// Access: Public +// Description: Removes the specification of anisotropic filtering +// from the texture. +//////////////////////////////////////////////////////////////////// +INLINE void EggTexture:: +clear_anisotropic_degree() { + _anisotropic_degree = 0; + _flags &= ~F_has_anisotropic_degree; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::has_anisotropic_degree +// Access: Public +// Description: Returns true if a value for the anisotropic filtering +// degree has been specified for this texture, false +// otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool EggTexture:: +has_anisotropic_degree() const { + return (_flags & F_has_anisotropic_degree) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::get_anisotropic_degree +// Access: Public +// Description: Returns the anisotropic filtering degree that has +// been specified for this texture. It is an error to +// call this unless has_anisotropic_degree() returns +// true. +//////////////////////////////////////////////////////////////////// +INLINE int EggTexture:: +get_anisotropic_degree() const { + nassertr(has_anisotropic_degree(), 1); + return _anisotropic_degree; +} + //////////////////////////////////////////////////////////////////// // Function: EggTexture::set_env_type // Access: Public diff --git a/panda/src/egg/eggTexture.cxx b/panda/src/egg/eggTexture.cxx index 331b833510..07e98f267c 100644 --- a/panda/src/egg/eggTexture.cxx +++ b/panda/src/egg/eggTexture.cxx @@ -29,6 +29,7 @@ EggTexture(const string &tref_name, const string &filename) _magfilter = FT_unspecified; _magfilteralpha = FT_unspecified; _magfiltercolor = FT_unspecified; + _anisotropic_degree = 0; _env_type = ET_unspecified; _flags = 0; _transform = LMatrix3d::ident_mat(); @@ -62,6 +63,7 @@ operator = (const EggTexture ©) { _magfilter = copy._magfilter; _magfilteralpha = copy._magfilteralpha; _magfiltercolor = copy._magfiltercolor; + _anisotropic_degree = copy._anisotropic_degree; _env_type = copy._env_type; _flags = copy._flags; _transform = copy._transform; @@ -120,6 +122,11 @@ write(ostream &out, int indent_level) const { << " magfiltercolor { " << get_magfiltercolor() << " }\n"; } + if (has_anisotropic_degree()) { + indent(out, indent_level + 2) + << " anisotropic-degree { " << get_anisotropic_degree() << " }\n"; + } + if (get_env_type() != ET_unspecified) { indent(out, indent_level + 2) << " envtype { " << get_env_type() << " }\n"; @@ -426,22 +433,38 @@ string_wrap_mode(const string &string) { //////////////////////////////////////////////////////////////////// EggTexture::FilterType EggTexture:: string_filter_type(const string &string) { + // Old egg filter types. if (cmp_nocase_uh(string, "point") == 0) { - return FT_point; + return FT_nearest; } else if (cmp_nocase_uh(string, "linear") == 0) { return FT_linear; } else if (cmp_nocase_uh(string, "bilinear") == 0) { - return FT_bilinear; + return FT_linear; } else if (cmp_nocase_uh(string, "trilinear") == 0) { - return FT_trilinear; + return FT_linear; } else if (cmp_nocase_uh(string, "mipmap_point") == 0) { - return FT_mipmap_point; + return FT_nearest_mipmap_nearest; } else if (cmp_nocase_uh(string, "mipmap_linear") == 0) { - return FT_mipmap_linear; + return FT_nearest_mipmap_linear; } else if (cmp_nocase_uh(string, "mipmap_bilinear") == 0) { - return FT_mipmap_bilinear; + return FT_linear_mipmap_nearest; } else if (cmp_nocase_uh(string, "mipmap_trilinear") == 0) { - return FT_mipmap_trilinear; + return FT_linear_mipmap_linear; + + // Current egg filter types, that match those in Texture. + } else if (cmp_nocase_uh(string, "nearest") == 0) { + return FT_nearest; + } else if (cmp_nocase_uh(string, "linear") == 0) { + return FT_linear; + } else if (cmp_nocase_uh(string, "nearest_mipmap_nearest") == 0) { + return FT_nearest_mipmap_nearest; + } else if (cmp_nocase_uh(string, "linear_mipmap_nearest") == 0) { + return FT_linear_mipmap_nearest; + } else if (cmp_nocase_uh(string, "nearest_mipmap_linear") == 0) { + return FT_nearest_mipmap_linear; + } else if (cmp_nocase_uh(string, "linear_mipmap_linear") == 0) { + return FT_linear_mipmap_linear; + } else { return FT_unspecified; } @@ -541,22 +564,20 @@ ostream &operator << (ostream &out, EggTexture::FilterType type) { switch (type) { case EggTexture::FT_unspecified: return out << "unspecified"; - case EggTexture::FT_point: - return out << "point"; + + case EggTexture::FT_nearest: + return out << "nearest"; case EggTexture::FT_linear: return out << "linear"; - case EggTexture::FT_bilinear: - return out << "bilinear"; - case EggTexture::FT_trilinear: - return out << "trilinear"; - case EggTexture::FT_mipmap_point: - return out << "mipmap_point"; - case EggTexture::FT_mipmap_linear: - return out << "mipmap_linear"; - case EggTexture::FT_mipmap_bilinear: - return out << "mipmap_bilinear"; - case EggTexture::FT_mipmap_trilinear: - return out << "mipmap_trilinear"; + + case EggTexture::FT_nearest_mipmap_nearest: + return out << "nearest_mipmap_nearest"; + case EggTexture::FT_linear_mipmap_nearest: + return out << "linear_mipmap_nearest"; + case EggTexture::FT_nearest_mipmap_linear: + return out << "nearest_mipmap_linear"; + case EggTexture::FT_linear_mipmap_linear: + return out << "linear_mipmap_linear"; } nassertr(false, out); diff --git a/panda/src/egg/eggTexture.h b/panda/src/egg/eggTexture.h index 0f501dfe6e..412e50b776 100644 --- a/panda/src/egg/eggTexture.h +++ b/panda/src/egg/eggTexture.h @@ -53,9 +53,21 @@ public: WM_unspecified, WM_repeat, WM_clamp }; enum FilterType { - FT_unspecified, FT_point, FT_linear, FT_bilinear, FT_trilinear, - FT_mipmap_point, FT_mipmap_linear, FT_mipmap_bilinear, - FT_mipmap_trilinear + // Note that these type values match up, name-for-name, with a + // similar enumerated type in Panda's Texture object. However, + // they do *not* match up numerically. You must convert between + // them using a switch statement. + FT_unspecified, + + // Mag Filter and Min Filter + FT_nearest, + FT_linear, + + // Min Filter Only + FT_nearest_mipmap_nearest, + FT_linear_mipmap_nearest, + FT_nearest_mipmap_linear, + FT_linear_mipmap_linear, }; enum EnvType { ET_unspecified, ET_modulate, ET_decal @@ -87,6 +99,11 @@ public: INLINE void set_magfiltercolor(FilterType type); INLINE FilterType get_magfiltercolor() const; + INLINE void set_anisotropic_degree(int anisotropic_degree); + INLINE void clear_anisotropic_degree(); + INLINE bool has_anisotropic_degree() const; + INLINE int get_anisotropic_degree() const; + INLINE void set_env_type(EnvType type); INLINE EnvType get_env_type() const; @@ -109,13 +126,15 @@ public: private: enum Flags { - F_has_transform = 0x0001, - F_has_alpha_file = 0x0002 + F_has_transform = 0x0001, + F_has_alpha_file = 0x0002, + F_has_anisotropic_degree = 0x0004, }; Format _format; WrapMode _wrap_mode, _wrap_u, _wrap_v; FilterType _minfilter, _magfilter, _magfilteralpha, _magfiltercolor; + int _anisotropic_degree; EnvType _env_type; int _flags; LMatrix3d _transform; diff --git a/panda/src/egg/parser.yxx b/panda/src/egg/parser.yxx index 646073b88c..e6d86e4e95 100644 --- a/panda/src/egg/parser.yxx +++ b/panda/src/egg/parser.yxx @@ -364,6 +364,9 @@ texture_body: texture->set_magfiltercolor(f); } + } else if (cmp_nocase_uh(name, "anisotropic_degree") == 0) { + texture->set_anisotropic_degree(value); + } else if (cmp_nocase_uh(name, "envtype") == 0) { EggTexture::EnvType e = EggTexture::string_env_type(strval); if (e == EggTexture::ET_unspecified) { diff --git a/panda/src/egg2sg/eggLoader.cxx b/panda/src/egg2sg/eggLoader.cxx index 9c08fd5f79..94bf0f4ccd 100644 --- a/panda/src/egg2sg/eggLoader.cxx +++ b/panda/src/egg2sg/eggLoader.cxx @@ -596,13 +596,11 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { } switch (egg_tex->get_minfilter()) { - case EggTexture::FT_point: + case EggTexture::FT_nearest: tex->set_minfilter(Texture::FT_nearest); break; case EggTexture::FT_linear: - case EggTexture::FT_bilinear: - case EggTexture::FT_trilinear: if (egg_ignore_filters) { egg2sg_cat.warning() << "Ignoring minfilter request\n"; @@ -612,7 +610,7 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { } break; - case EggTexture::FT_mipmap_point: + case EggTexture::FT_nearest_mipmap_nearest: if (egg_ignore_filters) { egg2sg_cat.warning() << "Ignoring minfilter request\n"; @@ -626,9 +624,35 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { } break; - case EggTexture::FT_mipmap_linear: - case EggTexture::FT_mipmap_bilinear: - case EggTexture::FT_mipmap_trilinear: + case EggTexture::FT_linear_mipmap_nearest: + if (egg_ignore_filters) { + egg2sg_cat.warning() + << "Ignoring minfilter request\n"; + tex->set_minfilter(Texture::FT_nearest); + } else if (egg_ignore_mipmaps) { + egg2sg_cat.warning() + << "Ignoring mipmap request\n"; + tex->set_minfilter(Texture::FT_linear); + } else { + tex->set_minfilter(Texture::FT_linear_mipmap_nearest); + } + break; + + case EggTexture::FT_nearest_mipmap_linear: + if (egg_ignore_filters) { + egg2sg_cat.warning() + << "Ignoring minfilter request\n"; + tex->set_minfilter(Texture::FT_nearest); + } else if (egg_ignore_mipmaps) { + egg2sg_cat.warning() + << "Ignoring mipmap request\n"; + tex->set_minfilter(Texture::FT_nearest); + } else { + tex->set_minfilter(Texture::FT_nearest_mipmap_linear); + } + break; + + case EggTexture::FT_linear_mipmap_linear: if (egg_ignore_filters) { egg2sg_cat.warning() << "Ignoring minfilter request\n"; @@ -652,17 +676,15 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { } switch (egg_tex->get_magfilter()) { - case EggTexture::FT_point: - case EggTexture::FT_mipmap_point: + case EggTexture::FT_nearest: + case EggTexture::FT_nearest_mipmap_nearest: + case EggTexture::FT_nearest_mipmap_linear: tex->set_magfilter(Texture::FT_nearest); break; case EggTexture::FT_linear: - case EggTexture::FT_bilinear: - case EggTexture::FT_trilinear: - case EggTexture::FT_mipmap_linear: - case EggTexture::FT_mipmap_bilinear: - case EggTexture::FT_mipmap_trilinear: + case EggTexture::FT_linear_mipmap_nearest: + case EggTexture::FT_linear_mipmap_linear: if (egg_ignore_filters) { egg2sg_cat.warning() << "Ignoring magfilter request\n"; @@ -681,6 +703,10 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { } } + if (egg_tex->has_anisotropic_degree()) { + tex->set_anisotropic_degree(egg_tex->get_anisotropic_degree()); + } + if (tex->_pbuffer->get_num_components() == 1) { switch (egg_tex->get_format()) { case EggTexture::F_red: diff --git a/panda/src/gobj/texture.I b/panda/src/gobj/texture.I index f746bb5cc1..513e5b7d9c 100644 --- a/panda/src/gobj/texture.I +++ b/panda/src/gobj/texture.I @@ -64,3 +64,18 @@ INLINE Texture::FilterType Texture:: get_magfilter() const { return _magfilter; } + +//////////////////////////////////////////////////////////////////// +// Function: Texture::get_anisotropic_degree +// Access: Public +// Description: Returns the degree of anisotropic filtering that +// should be applied to the texture. Normally, this is +// 1, to indicate that anisotropic filtering should be +// disabled. If this is a number higher than 1, +// anisotropic filtering should be enabled (if the +// rendering backend supports it). +//////////////////////////////////////////////////////////////////// +INLINE int Texture:: +get_anisotropic_degree() const { + return _anisotropic_degree; +} diff --git a/panda/src/gobj/texture.cxx b/panda/src/gobj/texture.cxx index c93016cd6f..a73d6f252f 100644 --- a/panda/src/gobj/texture.cxx +++ b/panda/src/gobj/texture.cxx @@ -36,6 +36,7 @@ Texture() : ImageBuffer() { _minfilter = FT_nearest; _wrapu = WM_repeat; _wrapv = WM_repeat; + _anisotropic_degree = 1; _pbuffer = new PixelBuffer; _has_requested_size = false; } @@ -360,6 +361,23 @@ void Texture::set_magfilter(FilterType filter) } } +//////////////////////////////////////////////////////////////////// +// Function: set_anisotropic_degree +// Access: Public +// Description: Specifies the level of anisotropic filtering to apply +// to the texture. Normally, this is 1, to indicate +// anisotropic filtering is disabled. This may be set +// to a number higher than one to enable anisotropic +// filtering, if the rendering backend supports this. +//////////////////////////////////////////////////////////////////// +void Texture:: +set_anisotropic_degree(int anisotropic_degree) { + if (_anisotropic_degree != anisotropic_degree) { + unprepare(); + _anisotropic_degree = anisotropic_degree; + } +} + //////////////////////////////////////////////////////////////////// // Function: Texture::write_datagram // Access: Public @@ -377,6 +395,7 @@ write_datagram(BamWriter *manager, Datagram &me) me.add_uint8(_magfilter); me.add_uint8(_magfiltercolor); me.add_uint8(_magfilteralpha); + me.add_int16(_anisotropic_degree); } //////////////////////////////////////////////////////////////////// @@ -388,8 +407,7 @@ write_datagram(BamWriter *manager, Datagram &me) // place //////////////////////////////////////////////////////////////////// void Texture:: -fillin(DatagramIterator& scan, BamReader*) -{ +fillin(DatagramIterator &scan, BamReader *manager) { //We don't want to call ImageBuffer::fillin, like we //would normally, since due to needing to know the name //of the Texture before creating it, we have already read @@ -404,6 +422,12 @@ fillin(DatagramIterator& scan, BamReader*) _magfilter = (enum FilterType) scan.get_uint8(); _magfiltercolor = (enum FilterType) scan.get_uint8(); _magfilteralpha = (enum FilterType) scan.get_uint8(); + + if (manager->get_file_minor_ver() >= 4) { + _anisotropic_degree = scan.get_int16(); + } else { + _anisotropic_degree = 1; + } } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/texture.h b/panda/src/gobj/texture.h index 39dad83b78..92b07326c4 100644 --- a/panda/src/gobj/texture.h +++ b/panda/src/gobj/texture.h @@ -30,13 +30,26 @@ class EXPCL_PANDA Texture : public ImageBuffer { public: enum FilterType { // Mag Filter and Min Filter + + // Point sample the pixel FT_nearest, + + // Bilinear filtering of four neighboring pixels FT_linear, // Min Filter Only + + // Point sample the pixel from the nearest mipmap level FT_nearest_mipmap_nearest, + + // Bilinear filter the pixel from the nearest mipmap level FT_linear_mipmap_nearest, + + // Point sample the pixel from two mipmap levels, and linearly blend FT_nearest_mipmap_linear, + + // A.k.a. trilinear filtering: Bilinear filter the pixel from + // two mipmap levels, and linearly blend the results. FT_linear_mipmap_linear, }; @@ -78,12 +91,14 @@ public: void set_wrapv( WrapMode wrap ); void set_minfilter( FilterType filter ); void set_magfilter( FilterType filter ); + void set_anisotropic_degree(int anisotropic_degree); INLINE int get_level() const; INLINE WrapMode get_wrapu() const; INLINE WrapMode get_wrapv() const; INLINE FilterType get_minfilter() const; INLINE FilterType get_magfilter() const; + INLINE int get_anisotropic_degree() const; public: static void register_with_read_factory(void); @@ -124,6 +139,7 @@ protected: FilterType _magfilter; FilterType _magfiltercolor; FilterType _magfilteralpha; + int _anisotropic_degree; // A Texture keeps a list (actually, a map) of all the GSG's that it // has been prepared into. Each GSG conversely keeps a list (a set) diff --git a/panda/src/putil/bam.h b/panda/src/putil/bam.h index c7c63c662e..c99e80715b 100644 --- a/panda/src/putil/bam.h +++ b/panda/src/putil/bam.h @@ -17,10 +17,11 @@ static const string _bam_header = string("pbj\0\n\r", 6); static const unsigned short _bam_major_ver = 2; // Bumped to major version 2 on 7/6/00 due to major changes in Character. -static const unsigned short _bam_minor_ver = 3; +static const unsigned short _bam_minor_ver = 4; // Bumped to minor version 1 on 7/19/00 to quantize channel files. // Bumped to minor version 2 on 8/21/00 for CollisionNode::_collide_geom. // Bumped to minor version 3 on 11/21/00 for dual-image textures. +// Bumped to minor version 4 on 11/28/00 for anisotropic texture filtering. #endif