From b49289a4f6257e0c35e39c60595f13bc96bcee1c Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 21 May 2015 11:16:46 +0200 Subject: [PATCH] Allow setting min-lod, max-lod, lod-bias in egg file --- panda/src/egg/eggTexture.I | 136 +++++++++++++++++++++++++++++++++ panda/src/egg/eggTexture.h | 20 +++++ panda/src/egg/parser.yxx | 9 +++ panda/src/egg2pg/eggLoader.cxx | 62 +++++++++------ panda/src/gobj/texture.I | 22 ++++++ panda/src/gobj/texture.h | 1 + 6 files changed, 227 insertions(+), 23 deletions(-) diff --git a/panda/src/egg/eggTexture.I b/panda/src/egg/eggTexture.I index 25f1bcfab4..a6b49f7bd2 100644 --- a/panda/src/egg/eggTexture.I +++ b/panda/src/egg/eggTexture.I @@ -1057,6 +1057,142 @@ get_read_mipmaps() const { return _read_mipmaps; } +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::set_min_lod +// Access: Published +// Description: Sets the minimum mipmap level that may be sampled. +//////////////////////////////////////////////////////////////////// +INLINE void EggTexture:: +set_min_lod(double min_lod) { + _min_lod = min_lod; + _flags |= F_has_min_lod; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::clear_min_lod +// Access: Published +// Description: Removes the specification of a minimum mipmap level +// from the texture. +//////////////////////////////////////////////////////////////////// +INLINE void EggTexture:: +clear_min_lod() { + _min_lod = -1000; + _flags &= ~F_has_min_lod; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::has_min_lod +// Access: Published +// Description: Returns true if a value for the minimum mipmap level +// has been specified for this texture, false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool EggTexture:: +has_min_lod() const { + return (_flags & F_has_min_lod) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::get_min_lod +// Access: Published +// Description: Returns the minimum mipmap level that has been +// specified for this texture. +//////////////////////////////////////////////////////////////////// +INLINE double EggTexture:: +get_min_lod() const { + return _min_lod; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::set_max_lod +// Access: Published +// Description: Sets the maximum mipmap level that may be sampled. +//////////////////////////////////////////////////////////////////// +INLINE void EggTexture:: +set_max_lod(double max_lod) { + _max_lod = max_lod; + _flags |= F_has_max_lod; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::clear_max_lod +// Access: Published +// Description: Removes the specification of a maximum mipmap level +// from the texture. +//////////////////////////////////////////////////////////////////// +INLINE void EggTexture:: +clear_max_lod() { + _max_lod = 1000; + _flags &= ~F_has_max_lod; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::has_max_lod +// Access: Published +// Description: Returns true if a value for the maximum mipmap level +// has been specified for this texture, false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool EggTexture:: +has_max_lod() const { + return (_flags & F_has_max_lod) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::get_max_lod +// Access: Published +// Description: Returns the maximum mipmap level that has been +// specified for this texture. +//////////////////////////////////////////////////////////////////// +INLINE double EggTexture:: +get_max_lod() const { + return _max_lod; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::set_lod_bias +// Access: Published +// Description: Sets the mipmap level bias that is added to the +// mipmap level to be sampled. +//////////////////////////////////////////////////////////////////// +INLINE void EggTexture:: +set_lod_bias(double lod_bias) { + _lod_bias = lod_bias; + _flags |= F_has_lod_bias; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::clear_lod_bias +// Access: Published +// Description: Removes the specification of a maximum mipmap level +// from the texture. +//////////////////////////////////////////////////////////////////// +INLINE void EggTexture:: +clear_lod_bias() { + _lod_bias = 1000; + _flags &= ~F_has_lod_bias; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::has_lod_bias +// Access: Published +// Description: Returns true if a value for the maximum mipmap level +// has been specified for this texture, false otherwise. +//////////////////////////////////////////////////////////////////// +INLINE bool EggTexture:: +has_lod_bias() const { + return (_flags & F_has_lod_bias) != 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: EggTexture::get_lod_bias +// Access: Published +// Description: Returns the maximum mipmap level that has been +// specified for this texture. +//////////////////////////////////////////////////////////////////// +INLINE double EggTexture:: +get_lod_bias() const { + return _lod_bias; +} + //////////////////////////////////////////////////////////////////// // Function: EggTexture::get_multitexture_sort // Access: Published diff --git a/panda/src/egg/eggTexture.h b/panda/src/egg/eggTexture.h index 3b68b640a7..575e243471 100644 --- a/panda/src/egg/eggTexture.h +++ b/panda/src/egg/eggTexture.h @@ -281,6 +281,20 @@ PUBLISHED: INLINE void set_read_mipmaps(bool read_mipmaps); INLINE bool get_read_mipmaps() const; + INLINE void set_min_lod(double min_lod); + INLINE void clear_min_lod(); + INLINE bool has_min_lod() const; + INLINE double get_min_lod() const; + + INLINE void set_max_lod(double max_lod); + INLINE void clear_max_lod(); + INLINE bool has_max_lod() const; + INLINE double get_max_lod() const; + + INLINE void set_lod_bias(double lod_bias); + INLINE void clear_lod_bias(); + INLINE bool has_lod_bias() const; + INLINE double get_lod_bias() const; void clear_multitexture(); bool multitexture_over(EggTexture *other); @@ -320,6 +334,9 @@ private: F_has_alpha_scale = 0x0200, F_has_border_color = 0x0400, F_has_num_views = 0x0800, + F_has_min_lod = 0x1000, + F_has_max_lod = 0x2000, + F_has_lod_bias = 0x4000, }; TextureType _texture_type; @@ -347,6 +364,9 @@ private: int _alpha_file_channel; bool _read_mipmaps; int _multitexture_sort; + double _min_lod; + double _max_lod; + double _lod_bias; class SourceAndOperand { public: diff --git a/panda/src/egg/parser.yxx b/panda/src/egg/parser.yxx index 9c828fec9e..57f9488ef9 100644 --- a/panda/src/egg/parser.yxx +++ b/panda/src/egg/parser.yxx @@ -699,6 +699,15 @@ texture_body: } else if (cmp_nocase_uh(name, "read_mipmaps") == 0) { texture->set_read_mipmaps(((int)value) != 0); + } else if (cmp_nocase_uh(name, "min_lod") == 0) { + texture->set_min_lod(value); + + } else if (cmp_nocase_uh(name, "max_lod") == 0) { + texture->set_max_lod(value); + + } else if (cmp_nocase_uh(name, "lod_bias") == 0) { + texture->set_lod_bias(value); + } else { eggyywarning("Unsupported texture scalar: " + name); } diff --git a/panda/src/egg2pg/eggLoader.cxx b/panda/src/egg2pg/eggLoader.cxx index b472a104b6..f764d6e8f1 100644 --- a/panda/src/egg2pg/eggLoader.cxx +++ b/panda/src/egg2pg/eggLoader.cxx @@ -1088,36 +1088,38 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { tex->set_compression(convert_compression_mode(egg_tex->get_compression_mode())); } + SamplerState sampler; + EggTexture::WrapMode wrap_u = egg_tex->determine_wrap_u(); EggTexture::WrapMode wrap_v = egg_tex->determine_wrap_v(); EggTexture::WrapMode wrap_w = egg_tex->determine_wrap_w(); if (wrap_u != EggTexture::WM_unspecified) { - tex->set_wrap_u(convert_wrap_mode(wrap_u)); + sampler.set_wrap_u(convert_wrap_mode(wrap_u)); } if (wrap_v != EggTexture::WM_unspecified) { - tex->set_wrap_v(convert_wrap_mode(wrap_v)); + sampler.set_wrap_v(convert_wrap_mode(wrap_v)); } if (wrap_w != EggTexture::WM_unspecified) { - tex->set_wrap_w(convert_wrap_mode(wrap_w)); + sampler.set_wrap_w(convert_wrap_mode(wrap_w)); } if (egg_tex->has_border_color()) { - tex->set_border_color(egg_tex->get_border_color()); + sampler.set_border_color(egg_tex->get_border_color()); } switch (egg_tex->get_minfilter()) { case EggTexture::FT_nearest: - tex->set_minfilter(SamplerState::FT_nearest); + sampler.set_minfilter(SamplerState::FT_nearest); break; case EggTexture::FT_linear: if (egg_ignore_filters) { egg2pg_cat.warning() << "Ignoring minfilter request\n"; - tex->set_minfilter(SamplerState::FT_nearest); + sampler.set_minfilter(SamplerState::FT_nearest); } else { - tex->set_minfilter(SamplerState::FT_linear); + sampler.set_minfilter(SamplerState::FT_linear); } break; @@ -1125,13 +1127,13 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { if (egg_ignore_filters) { egg2pg_cat.warning() << "Ignoring minfilter request\n"; - tex->set_minfilter(SamplerState::FT_nearest); + sampler.set_minfilter(SamplerState::FT_nearest); } else if (egg_ignore_mipmaps) { egg2pg_cat.warning() << "Ignoring mipmap request\n"; - tex->set_minfilter(SamplerState::FT_nearest); + sampler.set_minfilter(SamplerState::FT_nearest); } else { - tex->set_minfilter(SamplerState::FT_nearest_mipmap_nearest); + sampler.set_minfilter(SamplerState::FT_nearest_mipmap_nearest); } break; @@ -1139,13 +1141,13 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { if (egg_ignore_filters) { egg2pg_cat.warning() << "Ignoring minfilter request\n"; - tex->set_minfilter(SamplerState::FT_nearest); + sampler.set_minfilter(SamplerState::FT_nearest); } else if (egg_ignore_mipmaps) { egg2pg_cat.warning() << "Ignoring mipmap request\n"; - tex->set_minfilter(SamplerState::FT_linear); + sampler.set_minfilter(SamplerState::FT_linear); } else { - tex->set_minfilter(SamplerState::FT_linear_mipmap_nearest); + sampler.set_minfilter(SamplerState::FT_linear_mipmap_nearest); } break; @@ -1153,13 +1155,13 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { if (egg_ignore_filters) { egg2pg_cat.warning() << "Ignoring minfilter request\n"; - tex->set_minfilter(SamplerState::FT_nearest); + sampler.set_minfilter(SamplerState::FT_nearest); } else if (egg_ignore_mipmaps) { egg2pg_cat.warning() << "Ignoring mipmap request\n"; - tex->set_minfilter(SamplerState::FT_nearest); + sampler.set_minfilter(SamplerState::FT_nearest); } else { - tex->set_minfilter(SamplerState::FT_nearest_mipmap_linear); + sampler.set_minfilter(SamplerState::FT_nearest_mipmap_linear); } break; @@ -1167,13 +1169,13 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { if (egg_ignore_filters) { egg2pg_cat.warning() << "Ignoring minfilter request\n"; - tex->set_minfilter(SamplerState::FT_nearest); + sampler.set_minfilter(SamplerState::FT_nearest); } else if (egg_ignore_mipmaps) { egg2pg_cat.warning() << "Ignoring mipmap request\n"; - tex->set_minfilter(SamplerState::FT_linear); + sampler.set_minfilter(SamplerState::FT_linear); } else { - tex->set_minfilter(SamplerState::FT_linear_mipmap_linear); + sampler.set_minfilter(SamplerState::FT_linear_mipmap_linear); } break; @@ -1185,7 +1187,7 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { case EggTexture::FT_nearest: case EggTexture::FT_nearest_mipmap_nearest: case EggTexture::FT_nearest_mipmap_linear: - tex->set_magfilter(SamplerState::FT_nearest); + sampler.set_magfilter(SamplerState::FT_nearest); break; case EggTexture::FT_linear: @@ -1194,9 +1196,9 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { if (egg_ignore_filters) { egg2pg_cat.warning() << "Ignoring magfilter request\n"; - tex->set_magfilter(SamplerState::FT_nearest); + sampler.set_magfilter(SamplerState::FT_nearest); } else { - tex->set_magfilter(SamplerState::FT_linear); + sampler.set_magfilter(SamplerState::FT_linear); } break; @@ -1205,9 +1207,23 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) { } if (egg_tex->has_anisotropic_degree()) { - tex->set_anisotropic_degree(egg_tex->get_anisotropic_degree()); + sampler.set_anisotropic_degree(egg_tex->get_anisotropic_degree()); } + if (egg_tex->has_min_lod()) { + sampler.set_min_lod(egg_tex->get_min_lod()); + } + + if (egg_tex->has_max_lod()) { + sampler.set_max_lod(egg_tex->get_max_lod()); + } + + if (egg_tex->has_lod_bias()) { + sampler.set_lod_bias(egg_tex->get_lod_bias()); + } + + tex->set_default_sampler(sampler); + if (tex->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 4aeaf4b259..6c6b945d2f 100644 --- a/panda/src/gobj/texture.I +++ b/panda/src/gobj/texture.I @@ -1105,6 +1105,28 @@ get_default_sampler() const { return cdata->_default_sampler; } +//////////////////////////////////////////////////////////////////// +// Function: Texture::set_default_sampler +// Access: Published +// Description: This sets the default sampler state for this +// texture, containing the wrap and filter properties +// specified on the texture level; it may still be +// overridden by a sampler state specified at a higher +// level. This encompasses the settings for get_wrap_u, +// get_minfilter, get_anisotropic_degree, etc. +// +// This makes a copy of the SamplerState object, so +// future modifications of the same SamplerState will +// have no effect on this texture unless you call +// set_default_sampler again. +//////////////////////////////////////////////////////////////////// +INLINE void Texture:: +set_default_sampler(const SamplerState &sampler) { + CDWriter cdata(_cycler, true); + cdata->_default_sampler = sampler; + cdata->inc_properties_modified(); +} + //////////////////////////////////////////////////////////////////// // Function: Texture::get_wrap_u // Access: Published diff --git a/panda/src/gobj/texture.h b/panda/src/gobj/texture.h index f19b1ef8fa..5381e5af26 100644 --- a/panda/src/gobj/texture.h +++ b/panda/src/gobj/texture.h @@ -321,6 +321,7 @@ PUBLISHED: INLINE void set_render_to_texture(bool render_to_texture); INLINE const SamplerState &get_default_sampler() const; + INLINE void set_default_sampler(const SamplerState &sampler); INLINE SamplerState::WrapMode get_wrap_u() const; INLINE SamplerState::WrapMode get_wrap_v() const; INLINE SamplerState::WrapMode get_wrap_w() const;