]> git.mxchange.org Git - flightgear.git/commitdiff
Fix GUI and HUD text rendering problems.
authortimoore <timoore>
Fri, 6 Jun 2008 19:02:17 +0000 (19:02 +0000)
committertimoore <timoore>
Fri, 6 Jun 2008 19:02:17 +0000 (19:02 +0000)
After the changes that moved the GUI and HUD to a slave camera, the
texture-based fonts wouldn't display. The main fixes here are making
sure that the TXF textures are all loaded into the font cache early,
and explicitly setting the active texture unit in the GUI / HUD
drawImplementation.

src/Cockpit/hud.cxx
src/GUI/gui.cxx
src/GUI/new_gui.cxx
src/GUI/new_gui.hxx
src/Main/renderer.cxx

index 606a29efb5ba7878720547cb2382aeb8a51a5431..564b536dc90a09cd2a794feb8bfbac9784fa7b1f 100644 (file)
@@ -542,6 +542,7 @@ void fgTextList::draw()
     vector<fgText>::iterator lastString = List.end();
 
     glPushAttrib(GL_COLOR_BUFFER_BIT);
+    glEnable(GL_TEXTURE_2D);
     glEnable(GL_BLEND);
     if (HUDprop->isTransparent())
         glBlendFunc(GL_SRC_ALPHA, GL_ONE);
index b730270f51d042ca7a771e1ae03778a376fcdb35..69b172d1b77f7b8e844e858723ea7f32190ec47f 100644 (file)
@@ -80,6 +80,7 @@ public:
         puSetDefaultColourScheme  (0.8, 0.8, 0.9, 1);
 
         FGFontCache *fc = globals->get_fontcache();
+        fc->initializeFonts();
         puFont *GuiFont
             = fc->get(globals->get_locale()->getStringValue("font",
                                                             "typewriter.txf"),
index 9f67a41d3b9a9e8de2f1df9335aac14099968335..c6057b771dc7e18ff0bed62ed888d7902a402c21 100644 (file)
@@ -1,5 +1,9 @@
 // new_gui.cxx: implementation of XML-configurable GUI support.
+#include <algorithm>
 #include <iostream>
+#include <cstring>
+#include <sys/types.h>
+#include <dirent.h>
 
 #include "new_gui.hxx"
 
@@ -13,7 +17,6 @@
 
 #include "menubar.hxx"
 #include "dialog.hxx"
-#include "SafeTexFont.hxx"
 
 extern puFont FONT_HELVETICA_14;
 extern puFont FONT_SANS_12B;
@@ -400,10 +403,25 @@ FGColor::merge(const FGColor *color)
 // FGFontCache class.
 ////////////////////////////////////////////////////////////////////////
 
-static const struct {
+namespace
+{
+struct GuiFont
+{
     const char *name;
     puFont *font;
-} guifonts[] = {
+    struct Predicate
+        : public std::unary_function<const GuiFont, bool>
+    {
+        Predicate(const char* name_) : name(name_) {}
+        bool operator() (const GuiFont& f1) const
+        {
+            return std::strcmp(f1.name, name) == 0;
+        }
+        const char* name;
+    };
+};
+
+const GuiFont guifonts[] = {
     { "default",      &FONT_HELVETICA_14 },
     { "FIXED_8x13",   &PUFONT_8_BY_13 },
     { "FIXED_9x15",   &PUFONT_9_BY_15 },
@@ -413,10 +431,11 @@ static const struct {
     { "HELVETICA_12", &PUFONT_HELVETICA_12 },
     { "HELVETICA_14", &FONT_HELVETICA_14 },
     { "HELVETICA_18", &PUFONT_HELVETICA_18 },
-    { "SANS_12B",     &FONT_SANS_12B },
-    { 0, 0 }
+    { "SANS_12B",     &FONT_SANS_12B }
 };
 
+const GuiFont* guifontsEnd = &guifonts[sizeof(guifonts)/ sizeof(guifonts[0])];
+}
 
 FGFontCache::FGFontCache() :
     _initialized(false)
@@ -425,31 +444,59 @@ FGFontCache::FGFontCache() :
 
 FGFontCache::~FGFontCache()
 {
-   map<const string, fnt *>::iterator it, end = _fonts.end();
-   for (it = _fonts.begin(); it != end; ++it)
+   PuFontMap::iterator it, end = _puFonts.end();
+   for (it = _puFonts.begin(); it != end; ++it)
        delete it->second;
 }
 
+inline bool FGFontCache::FntParamsLess::operator()(const FntParams& f1,
+                                                   const FntParams& f2) const
+{
+    int comp = f1.name.compare(f2.name);
+    if (comp < 0)
+        return true;
+    else if (comp > 0)
+        return false;
+    if (f1.size < f2.size)
+        return true;
+    else if (f1.size > f2.size)
+        return false;
+    return f1.slant < f2.slant;
+}
+
 struct FGFontCache::fnt *
 FGFontCache::getfnt(const char *name, float size, float slant)
 {
-    _itt_t it;
-    if ((it = _fonts.find(name)) != _fonts.end())
-        return it->second;
-
-    SGPath path = getfntpath(name);
-
-    fnt *f = new fnt();
-    f->texfont = new flightgear::SafeTexFont;
-
-    if (f->texfont->load((char *)path.c_str())) {
+    string fontName(name);
+    FntParams fntParams(fontName, size, slant);
+    PuFontMap::iterator i = _puFonts.find(fntParams);
+    if (i != _puFonts.end())
+        return i->second;
+    // fntTexFont s are all preloaded into the _texFonts map
+    TexFontMap::iterator texi = _texFonts.find(fontName);
+    fntTexFont* texfont = 0;
+    puFont* pufont = 0;
+    if (texi != _texFonts.end()) {
+        texfont = texi->second;
+    } else {
+        const GuiFont* guifont = std::find_if(&guifonts[0], guifontsEnd,
+                                              GuiFont::Predicate(name));
+        if (guifont != guifontsEnd) {
+            pufont = guifont->font;
+        }
+    }
+    fnt* f = new fnt;
+    if (pufont) {
+        f->pufont = pufont;
+    } else if (texfont) {
+        f->texfont = texfont;
         f->pufont = new puFont;
         f->pufont->initialize(static_cast<fntFont *>(f->texfont), size, slant);
-        return _fonts[name] = f;
+    } else {
+        f->pufont = guifonts[0].font;
     }
-
-    delete f;
-    return _fonts["default"];
+    _puFonts[fntParams] = f;
+    return f;
 }
 
 puFont *
@@ -477,8 +524,7 @@ FGFontCache::get(SGPropertyNode *node)
     return get(name, size, slant);
 }
 
-SGPath
-FGFontCache::getfntpath(const char *name)
+void FGFontCache::init()
 {
     if (!_initialized) {
         char *envp = ::getenv("FG_FONTS");
@@ -488,13 +534,14 @@ FGFontCache::getfntpath(const char *name)
             _path.set(globals->get_fg_root());
             _path.append("Fonts");
         }
-
-        for (int i = 0; guifonts[i].name; i++)
-            _fonts[guifonts[i].name] = new fnt(guifonts[i].font);
-
         _initialized = true;
     }
+}
 
+SGPath
+FGFontCache::getfntpath(const char *name)
+{
+    init();
     SGPath path(_path);
     if (name && std::string(name) != "") {
         path.append(name);
@@ -508,4 +555,27 @@ FGFontCache::getfntpath(const char *name)
     return path;
 }
 
+bool FGFontCache::initializeFonts()
+{
+    static string fontext("txf");
+    init();
+    DIR* fontdir = opendir(_path.c_str());
+    if (!fontdir)
+        return false;
+    const dirent *dirEntry;
+    while ((dirEntry = readdir(fontdir)) != 0) {
+        SGPath path(_path);
+        path.append(dirEntry->d_name);
+        if (path.extension() == fontext) {
+            fntTexFont* f = new fntTexFont;
+            if (f->load((char *)path.c_str()))
+                _texFonts[string(dirEntry->d_name)] = f;
+            else
+                delete f;
+        }
+    }
+    closedir(fontdir);
+    return true;
+}
+
 // end of new_gui.cxx
index 674bd73e2d99a7ddade14181bb2f3b455041a9bc..3fb1703d2d2a30211a8fe9a42b246f448bf50d13 100644 (file)
@@ -18,6 +18,7 @@
 #include <simgear/structure/subsystem_mgr.hxx>
 #include <simgear/misc/sg_path.hxx>
 
+#include <functional>
 #include <vector>
 #include <map>
 
@@ -286,23 +287,51 @@ private:
 
 
 /**
- * A small class to keep all fonts available for future use.
+ * A class to keep all fonts available for future use.
  * This also assures a font isn't resident more than once.
  */
 class FGFontCache {
 private:
+    // The parameters of a request to the cache.
+    struct FntParams
+    {
+        const std::string name;
+        const float size;
+        const float slant;
+        FntParams() : size(0.0f), slant(0.0f) {}
+        FntParams(const FntParams& rhs)
+            : name(rhs.name), size(rhs.size), slant(rhs.slant)
+        {
+        }
+        FntParams(const std::string& name_, float size_, float slant_)
+            : name(name_), size(size_), slant(slant_)
+        {
+        }
+    };
+    struct FntParamsLess
+        : public std::binary_function<const FntParams, const FntParams, bool>
+    {
+        bool operator() (const FntParams& f1, const FntParams& f2) const;
+    };
     struct fnt {
         fnt(puFont *pu = 0) : pufont(pu), texfont(0) {}
         ~fnt() { if (texfont) { delete pufont; delete texfont; } }
+        // Font used by plib GUI code
         puFont *pufont;
+        // TXF font
         fntTexFont *texfont;
     };
+    // Path to the font directory
     SGPath _path;
 
-    map<const string,fnt *> _fonts;
-    typedef map<const string,fnt *>::const_iterator _itt_t;
+    typedef map<const string, fntTexFont*> TexFontMap;
+    typedef map<const FntParams, fnt*, FntParamsLess> PuFontMap;
+    TexFontMap _texFonts;
+    PuFontMap _puFonts;
+
     bool _initialized;
     struct fnt *getfnt(const char *name, float size, float slant);
+    void init();
 
 public:
     FGFontCache();
@@ -314,6 +343,14 @@ public:
     fntTexFont *getTexFont(const char *name, float size=15.0, float slant=0.0);
 
     SGPath getfntpath(const char *name);
+    /**
+     * Preload all the fonts in the FlightGear font directory. It is
+     * important to load the font textures early, with the proper
+     * graphics context current, so that no plib (or our own) code
+     * tries to load a font from disk when there's no current graphics
+     * context.
+     */
+    bool initializeFonts();
 };
 
 
index 8840ca5bb99418f95ef35432a87f38487a77c033..56b68cc083c70e8c8161a1f8a19352bf56ae8a15 100644 (file)
@@ -159,6 +159,9 @@ public:
   {
     if (!fgOSIsMainContext(state.getGraphicsContext()))
       return;
+    state.setActiveTextureUnit(0);
+    state.setClientActiveTextureUnit(0);
+
     state.disableAllVertexArrays();
 
     glPushAttrib(GL_ALL_ATTRIB_BITS);
@@ -201,7 +204,8 @@ public:
   {
     if (!fgOSIsMainContext(state.getGraphicsContext()))
       return;
-
+    state.setActiveTextureUnit(0);
+    state.setClientActiveTextureUnit(0);
     state.disableAllVertexArrays();
 
     glPushAttrib(GL_ALL_ATTRIB_BITS);
@@ -222,6 +226,7 @@ public:
 
     glPopClientAttrib();
     glPopAttrib();
+
   }
 
   virtual osg::Object* cloneType() const { return new SGHUDAndPanelDrawable; }