effects.cpp

Go to the documentation of this file.
00001 /*
00002  * effects.cpp
00003  *
00004  * Copyright (C) 2010  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  * Program to test the glut-font library -- particularly FontEffect objects.
00008  */
00009 
00010 // includes --------------------------------------------------------------------
00011 #include <iostream>
00012 
00013 #include "glut-demo/glut-demo.h"
00014 #include "glut-font/glut-font-effects.h"
00015 #include "perf/perf.h"
00016 #include "util/file.h"
00017 
00018 
00019 
00020 static const int s_border                       = 32;
00021 
00022 static const int s_desiredHeight                = 24;   // pixel height of line
00023 
00024 static const char * s_lines                     =
00025         "This is a test. "
00026         "This is line 2. "
00027         "This is line 3. "
00028         "This is a really, really long line.  Really.  It's quite long. "
00029         "Short. "
00030         "You have found +3 dollars and +8 Euros!  Spend them wisely. "
00031         "0123456789 "
00032         "abcdefghijklmnopqrstuvwxyz That isn't really a word. "
00033         "Today: cloudy with showers.  High 59F.  Winds SSE at 5 to 10 mph.  Chance of rain 60%. "
00034         "Good bye! "
00035         "End of line.";
00036 
00037 static const int s_msPerChar                    = 50;
00038 
00039 static const glut_color_t s_color(0.5, 1.0, 0.5);
00040 
00041 
00042 ////////////////////////////////////////////////////////////////////////////////
00043 //
00044 //      static helper methods
00045 //
00046 ////////////////////////////////////////////////////////////////////////////////
00047 
00048 class Drawer : public glut::DemoHost {
00049 public:
00050         Drawer(IN const char * dir) {
00051                         ASSERT(dir, "null");
00052                         m_fontDir = dir;
00053                         m_index = -2;
00054                 }
00055         ~Drawer(void) throw() { }
00056 
00057         // glut::Host class interface methods ----------------------------------
00058         void onInit(void) {
00059                         // first, find all true type files...
00060                         this->addFiles("ttf");
00061 
00062                         // create font manager
00063                         m_fontMgr = glut::FontManager::create();
00064                         ASSERT_THROW(m_fontMgr,
00065                             "failed to create font manager");
00066 
00067                         m_width = 800;          // start with this
00068                         this->updateFont(-1);   // start with default
00069 
00070                         // time
00071                         m_time = perf::getNow();
00072                 }
00073 
00074         bool displayAxes(void) { return false; }
00075 
00076         void onKey(IN int key, IN int mods) {
00077                         int deltaIndex = 0;
00078                         switch (key) {
00079                         case 'n':       deltaIndex = +1;        break;
00080                         case 'N':       deltaIndex = -1;        break;
00081                         case ' ':       m_effect->reset();      break;
00082                         case 'a':       m_effect->advance();    break;
00083                         case 'c':       m_effect->complete();   break;
00084                         default:
00085                                 // ignore!
00086                                 break;
00087                         }
00088 
00089                         int nMax = m_paths.size();
00090                         int newIndex = m_index + deltaIndex;
00091                         if (newIndex < -1) {
00092                                 newIndex = nMax - 1;
00093                         } else if (newIndex >= nMax) {
00094                                 newIndex = -1;
00095                         }
00096                         this->updateFont(newIndex);
00097                 }
00098 
00099         void display2D(IN int width, IN int height) {
00100                         ASSERT(m_currFont, "null");
00101                         ASSERT(m_effect, "null");
00102 
00103                         m_width = width;
00104 
00105                         int nMax = m_paths.size();
00106                         const int bufsize = 1024;
00107                         char buffer[bufsize];
00108                         snprintf(buffer, bufsize, "font: %s",
00109                             m_currFont->getName());
00110                         glut::Font * defFont = glut::getDefaultFont();
00111                         defFont->display(1, 47, 0, buffer);
00112                         snprintf(buffer, bufsize, "font %d of %d",
00113                             m_index + 1, nMax);
00114                         defFont->display(1, 62, 0, buffer);
00115                         snprintf(buffer, bufsize, "font size: %4.1f point",
00116                             m_currFont->getFaceSize());
00117                         defFont->display(1, 77, 0, buffer);
00118                         defFont->display(1, 92, 0, "(n)ext font");
00119                         defFont->display(width - 300, 62, 0, "(space): reset");
00120                         defFont->display(width - 300, 77, 0, "(a)dvance");
00121                         defFont->display(width - 300, 92, 0, "(c)omplete");
00122                         int yStart = 92 + s_border + m_currFont->getLineHeight();
00123 
00124                         perf::time_t now = perf::getNow();
00125                         perf::time_t delta = now;
00126                         delta.decrement(m_time);
00127                         m_time = now;
00128                         m_effect->tick(delta.getSeconds());
00129 
00130                         glBegin(GL_LINES);
00131                                 glVertex3f(s_border, 0, 0);
00132                                 glVertex3f(s_border, height, 0);
00133                                 glVertex3f(width - s_border, 0, 0);
00134                                 glVertex3f(width - s_border, height, 0);
00135                         glEnd();
00136 
00137                         glMatrixMode(GL_MODELVIEW);
00138                         glPushMatrix();
00139                         glTranslatef(s_border, yStart, 0);
00140 
00141                         m_effect->render();
00142 
00143                         glPopMatrix();
00144                 }
00145         
00146 private:
00147         // private typedefs ----------------------------------------------------
00148 
00149         // private helper methods ----------------------------------------------
00150         void addFiles(IN const char * ext) {
00151                         ASSERT(ext, "null extension");
00152                         VecString files;
00153                         walkDirectoryTree(m_fontDir.c_str(), ext, files);
00154                         int nFiles = files.size();
00155                         for (int i = 0; i < nFiles; ++i) {
00156                                 const char * path = files[i].c_str();
00157                                 std::string full_path;
00158                                 appendPath(m_fontDir.c_str(), path, full_path);
00159                                 DPRINTF("Font file: '%s'", full_path.c_str());
00160 
00161                                 m_paths.push_back(full_path);
00162                         }
00163                 }
00164 
00165         void updateFont(IN int newIndex) {
00166                         if (m_currFont && m_index == newIndex)
00167                                 return;         // nothing to do!
00168                         m_index = newIndex;
00169 
00170                         int nMax = m_paths.size();
00171                         const char * path = NULL;
00172                         if (m_index >= 0 && m_index < nMax) {
00173                                 path = m_paths[m_index].c_str();
00174                         }
00175                         m_currFont = m_fontMgr->getFont(path);
00176                         ASSERT(m_currFont, "null font?");
00177 
00178                         // resize
00179                         scaleFontToPixelHeight(m_currFont, "M", s_desiredHeight);
00180 
00181                         // parse into lines
00182                         std::string lines;
00183                         glut::breakLongString(s_lines, m_currFont,
00184                             m_width - 2 * s_border, lines);
00185                         DPRINTF("Lines:\n%s", lines.c_str());
00186 
00187                         // create font effect
00188                         m_effect = glut::getCharacterAdvanceEffect(m_currFont,
00189                                         lines.c_str(), s_msPerChar, s_color);
00190                 }
00191 
00192         // private member data -------------------------------------------------
00193         std::string                     m_fontDir;
00194         VecString                       m_paths;
00195         smart_ptr<glut::FontManager>    m_fontMgr;
00196         smart_ptr<glut::Font>           m_currFont;
00197         smart_ptr<glut::FontEffect>     m_effect;
00198         int                             m_index;
00199         perf::time_t                    m_time;
00200         int                             m_width;
00201 };
00202 
00203 
00204 
00205 ////////////////////////////////////////////////////////////////////////////////
00206 //
00207 //      entry point
00208 //
00209 ////////////////////////////////////////////////////////////////////////////////
00210 
00211 int
00212 main
00213 (
00214 IN int argc,
00215 IN const char * argv[]
00216 )
00217 {
00218         ASSERT(2 == argc, "Usage: glut-font-effects <font-dir>");
00219         const char * font_dir = argv[1];
00220         DPRINTF("Using font directory: '%s'", font_dir);
00221 
00222         try {
00223                 // title
00224                 std::string title = "glut-font FontEffect test: ";
00225                 title += font_dir;
00226 
00227                 // main loop
00228                 smart_ptr<glut::DemoHost> host = new Drawer(font_dir);
00229                 ASSERT(host, "out of memory");
00230                 glut::startDemo(argc, argv, title.c_str(), host);
00231 
00232         } catch (std::exception& e) {
00233                 DPRINTF("Exception: %s", e.what());
00234         }
00235 
00236         // only reach here on error
00237         return -1;
00238 }
00239