Browse Source

allow more general selection of texture filter type for DynamicTextFont

David Rose 24 years ago
parent
commit
de6a97f1c0

+ 48 - 0
panda/src/gobj/texture.cxx

@@ -28,6 +28,7 @@
 #include "datagramIterator.h"
 #include "bamReader.h"
 #include "bamWriter.h"
+#include "string_utils.h"
 
 #include <stddef.h>
 
@@ -538,6 +539,53 @@ mark_dirty(int flags_to_set) {
   _all_dirty_flags |= flags_to_set;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::string_wrap_mode
+//       Access: Public
+//  Description: Returns the WrapMode value associated with the given
+//               string representation, or WM_invalid if the string
+//               does not match any known WrapMode value.
+////////////////////////////////////////////////////////////////////
+Texture::WrapMode Texture::
+string_wrap_mode(const string &string) {
+  if (cmp_nocase_uh(string, "repeat") == 0) {
+    return WM_repeat;
+  } else if (cmp_nocase_uh(string, "clamp") == 0) {
+    return WM_clamp;
+  } else {
+    return WM_invalid;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::string_filter_type
+//       Access: Public
+//  Description: Returns the FilterType value associated with the given
+//               string representation, or FT_invalid if the string
+//               does not match any known FilterType value.
+////////////////////////////////////////////////////////////////////
+Texture::FilterType Texture::
+string_filter_type(const string &string) {
+  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 if (cmp_nocase_uh(string, "mipmap") == 0) {
+    return FT_linear_mipmap_linear;
+
+  } else {
+    return FT_invalid;
+  }
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::register_with_read_factory
 //       Access: Public, Static

+ 9 - 0
panda/src/gobj/texture.h

@@ -64,11 +64,17 @@ PUBLISHED:
     // A.k.a. trilinear filtering: Bilinear filter the pixel from
     // two mipmap levels, and linearly blend the results.
     FT_linear_mipmap_linear,
+
+    // Returned by string_filter_type() for an invalid match.
+    FT_invalid
   };
 
   enum WrapMode {
     WM_clamp,
     WM_repeat,
+
+    // Returned by string_wrap_mode() for an invalid match.
+    WM_invalid
   };
 
 PUBLISHED:
@@ -130,6 +136,9 @@ public:
 
   void mark_dirty(int flags_to_set);
 
+  static WrapMode string_wrap_mode(const string &string);
+  static FilterType string_filter_type(const string &string);
+
 private:
   WrapMode _wrapu;
   WrapMode _wrapv;

+ 59 - 14
panda/src/text/config_text.cxx

@@ -24,12 +24,47 @@
 #include "dynamicTextPage.h"
 #include "geomTextGlyph.h"
 
-#include <dconfig.h>
+#include "dconfig.h"
 
 Configure(config_text);
 NotifyCategoryDef(text, "");
 
 ConfigureFn(config_text) {
+  init_libtext();
+}
+
+const bool text_flatten = config_text.GetBool("text-flatten", true);
+const bool text_update_cleared_glyphs = config_text.GetBool("text-update-cleared-glyphs", false);
+const int text_anisotropic_degree = config_text.GetInt("text-anisotropic-degree", 1);
+const int text_texture_margin = config_text.GetInt("text-texture-margin", 2);
+const float text_poly_margin = config_text.GetFloat("text-poly-margin", 1.0f);
+const int text_page_x_size = config_text.GetInt("text-page-x-size", 256);
+const int text_page_y_size = config_text.GetInt("text-page-y-size", 256);
+const float text_point_size = config_text.GetFloat("text-point-size", 10.0f);
+const float text_pixels_per_unit = config_text.GetFloat("text-pixels-per-unit", 30.0f);
+const bool text_small_caps = config_text.GetBool("text-small-caps", false);
+const float text_small_caps_scale = config_text.GetFloat("text-small-caps-scale", 0.8f);
+
+Texture::FilterType text_minfilter = Texture::FT_invalid;
+Texture::FilterType text_magfilter = Texture::FT_invalid;
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: init_libtext
+//  Description: Initializes the library.  This must be called at
+//               least once before any of the functions or classes in
+//               this library can be used.  Normally it will be
+//               called by the static initializers and need not be
+//               called explicitly, but special cases exist.
+////////////////////////////////////////////////////////////////////
+void
+init_libtext() {
+  static bool initialized = false;
+  if (initialized) {
+    return;
+  }
+  initialized = true;
+
   StaticTextFont::init_type();
   TextFont::init_type();
   TextNode::init_type();
@@ -52,17 +87,27 @@ ConfigureFn(config_text) {
     text_cat.error()
       << "Invalid text-encoding: " << text_encoding << "\n";
   }
-}
 
-const bool text_flatten = config_text.GetBool("text-flatten", true);
-const bool text_update_cleared_glyphs = config_text.GetBool("text-update-cleared-glyphs", false);
-const bool text_mipmap = config_text.GetBool("text-mipmap", false);
-const int text_anisotropic_degree = config_text.GetInt("text-anisotropic-degree", 1);
-const int text_texture_margin = config_text.GetInt("text-texture-margin", 2);
-const float text_poly_margin = config_text.GetFloat("text-poly-margin", 1.0f);
-const int text_page_x_size = config_text.GetInt("text-page-x-size", 256);
-const int text_page_y_size = config_text.GetInt("text-page-y-size", 256);
-const float text_point_size = config_text.GetFloat("text-point-size", 10.0f);
-const float text_pixels_per_unit = config_text.GetFloat("text-pixels-per-unit", 30.0f);
-const bool text_small_caps = config_text.GetBool("text-small-caps", false);
-const float text_small_caps_scale = config_text.GetFloat("text-small-caps-scale", 0.8f);
+  // FT_linear_mipmap_nearest (that is, choose the nearest mipmap
+  // level and bilinear filter the pixels from there) gives us some
+  // mipmapping to avoid dropping pixels, but avoids the hideous
+  // artifacts that we get from some cards (notably TNT2) from
+  // filtering between two different mipmap levels.
+  string text_minfilter_str = config_text.GetString("text-minfilter", "linear_mipmap_nearest");
+  string text_magfilter_str = config_text.GetString("text-magfilter", "linear");
+
+  text_minfilter = Texture::string_filter_type(text_minfilter_str);
+  if (text_minfilter == Texture::FT_invalid) {
+    text_cat.error()
+      << "Invalid text-minfilter: " << text_minfilter_str << "\n";
+    text_minfilter = Texture::FT_linear;
+  }
+
+  text_magfilter = Texture::string_filter_type(text_magfilter_str);
+  if (text_magfilter == Texture::FT_invalid) {
+    text_cat.error()
+      << "Invalid text-magfilter: " << text_magfilter_str << "\n";
+    text_magfilter = Texture::FT_linear;
+  }
+  
+}

+ 8 - 3
panda/src/text/config_text.h

@@ -19,8 +19,9 @@
 #ifndef CONFIG_TEXT_H
 #define CONFIG_TEXT_H
 
-#include <pandabase.h>
-#include <notifyCategoryProxy.h>
+#include "pandabase.h"
+#include "notifyCategoryProxy.h"
+#include "texture.h"
 
 class DSearchPath;
 
@@ -28,7 +29,6 @@ NotifyCategoryDecl(text, EXPCL_PANDA, EXPTP_PANDA);
 
 extern const bool text_flatten;
 extern const bool text_update_cleared_glyphs;
-extern const bool text_mipmap;
 extern const int text_anisotropic_degree;
 extern const int text_texture_margin;
 extern const float text_poly_margin;
@@ -39,4 +39,9 @@ extern const float text_pixels_per_unit;
 extern const bool text_small_caps;
 extern const float text_small_caps_scale;
 
+extern Texture::FilterType text_minfilter;
+extern Texture::FilterType text_magfilter;
+
+extern EXPCL_PANDA void init_libtext();
+
 #endif

+ 5 - 8
panda/src/text/dynamicTextPage.cxx

@@ -47,14 +47,11 @@ DynamicTextPage(DynamicTextFont *font) :
   set_keep_ram_image(true);
 
   // We don't necessarily want to use mipmaps, since we don't want to
-  // regenerate those every time the texture changes, but we do want
-  // at least linear filtering.
-  set_magfilter(FT_linear);
-  if (text_mipmap) {
-    set_minfilter(FT_linear_mipmap_linear);
-  } else {
-    set_minfilter(FT_linear);
-  }
+  // regenerate those every time the texture changes, but we probably
+  // do want at least linear filtering.  Use whatever the Configrc
+  // file suggests.
+  set_minfilter(text_minfilter);
+  set_magfilter(text_magfilter);
 
   // Anisotropic filtering can help the look of the text, and doesn't
   // require generating mipmaps, but does require hardware support.