SWE
/import/home/rettenbs/src/SWE/src/opengl/text.h
00001 // =====================================================================
00002 // This file is part of SWE_CUDA (see file SWE_Block.cu for details).
00003 //
00004 // Copyright (C) 2012 Sebastian Rettenberger
00005 //
00006 // SWE_CUDA is free software: you can redristribute it and/or modify
00007 // it under the terms of the GNU General Public License as published by
00008 // the Free Software Foundation, either version 3 of the License, or
00009 // (at your option) any later version.
00010 //
00011 // SWE_CUDA is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU General Public License
00017 // along with SWE_CUDA.  If not, see <http://www.gnu.org/licenses/>.
00018 // =====================================================================
00019 
00020 #ifndef TEXT_H
00021 #define TEXT_H
00022 
00023 #include <cmath>
00024 #include <string>
00025 #include <vector>
00026 #include <SDL/SDL_ttf.h>
00027 #include <SDL/SDL_opengl.h>
00028 
00029 class Text
00030 {
00031 private:
00033         std::vector<GLuint> textures;
00035         std::vector<int> width;
00037         std::vector<int> height;
00038 
00040         unsigned int nextText;
00041 
00042 public:
00043         Text()
00044         {
00045                 // Initialize TTF if not done yet
00046                 if (instances == 0) {
00047                         if (TTF_Init() < 0) {
00048                         fprintf(stderr, "\nCould not initialize SDL_ttf\n" );
00049                         exit(-1);
00050                         }
00051 
00052                         openFont();
00053                 }
00054 
00055                 instances++;
00056         }
00057 
00058         ~Text()
00059         {
00060                 // We assume that std::vector is just an array ...
00061                 glDeleteTextures(textures.size(), &textures[0]);
00062 
00063                 instances--;
00064 
00065                 if (instances == 0) {
00066                         TTF_CloseFont(font);
00067                         TTF_Quit();
00068                 }
00069         }
00070 
00071         void addText(const char* text)
00072         {
00073                 if (!font)
00074                         return;
00075 
00076                 // Draw string
00077                 SDL_Color black = {0, 0, 0, 255};
00078                 SDL_Surface* surf = TTF_RenderText_Blended(font, text, black);
00079 
00080                 if (surf) {
00081                         GLuint texture;
00082 
00083                         /* Tell GL about our new texture */
00084                         glGenTextures(1, &texture);
00085                         glBindTexture(GL_TEXTURE_2D, texture);
00086                         glTexImage2D(GL_TEXTURE_2D, 0, 4, surf->w, surf->h, 0, GL_BGRA,
00087                                         GL_UNSIGNED_BYTE, surf->pixels);
00088 
00089                         width.push_back(surf->w);
00090                         height.push_back(surf->h);
00091 
00092                         textures.push_back(texture);
00093 
00094                         /* Clean up */
00095                         SDL_FreeSurface(surf);
00096                 }
00097         }
00098 
00099         void startTextMode()
00100         {
00101                 // Enable 2D mode
00102                 int vPort[4];
00103 
00104                 glGetIntegerv(GL_VIEWPORT, vPort);
00105 
00106                 glMatrixMode(GL_PROJECTION);
00107                 glPushMatrix();
00108                 glLoadIdentity();
00109 
00110                 glOrtho(0, vPort[2], 0, vPort[3], -1, 1);
00111                 glMatrixMode(GL_MODELVIEW);
00112                 glPushMatrix();
00113                 glLoadIdentity();
00114                 glDisable(GL_DEPTH_TEST);
00115             glEnable(GL_BLEND);
00116                 glEnable(GL_TEXTURE_2D);
00117             glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
00118 
00119             nextText = 0;
00120         }
00121 
00125         bool showNextText(SDL_Rect &location)
00126         {
00127                 if (!font)
00128                         return false;
00129 
00130                 if (nextText >= textures.size())
00131                         // No more textures to show
00132                         return false;
00133 
00134                 /* GL_NEAREST looks horrible, if scaled... */
00135                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00136                 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00137 
00138                 /* prepare to render our texture */
00139                 glBindTexture(GL_TEXTURE_2D, textures[nextText]);
00140 
00141                 /* Draw a quad at location */
00142                 glBegin(GL_QUADS);
00143                         /* Recall that the origin is in the lower-left corner
00144                            That is why the TexCoords specify different corners
00145                            than the Vertex coords seem to. */
00146                         glTexCoord2f(0.0f, 1.0f);
00147                                 glVertex2f(location.x, location.y - height[nextText]);
00148                         glTexCoord2f(1.0f, 1.0f);
00149                                 glVertex2f(location.x + width[nextText], location.y - height[nextText]);
00150                         glTexCoord2f(1.0f, 0.0f);
00151                                 glVertex2f(location.x + width[nextText], location.y);
00152                         glTexCoord2f(0.0f, 0.0f);
00153                                 glVertex2f(location.x, location.y);
00154                 glEnd();
00155 
00156                 /* return the deltas in the unused w,h part of the rect */
00157                 location.w = width[nextText];
00158                 location.h = height[nextText];
00159 
00160                 nextText++;
00161 
00162                 return nextText < textures.size();
00163         }
00164 
00165         void endTextMode()
00166         {
00167                 // Disable 2D mode
00168                 glDisable(GL_BLEND);
00169                 glDisable(GL_TEXTURE_2D);
00170                 glEnable(GL_DEPTH_TEST);
00171                 glMatrixMode(GL_PROJECTION);
00172                 glPopMatrix();
00173                 glMatrixMode(GL_MODELVIEW);
00174                 glPopMatrix();
00175         }
00176 
00177 private:
00178         static void openFont()
00179         {
00180                 std::string fullFileName = "";
00181 
00182                 // On unix: determine directory of exec
00183 #ifdef __unix__
00184                 // Code taken from:
00185                 // http://www.gamedev.net/community/forums/topic.asp?topic_id=459511
00186                 std::string path = "";
00187                 pid_t pid = getpid();
00188                 char buf[20] = {0};
00189                 sprintf(buf,"%d",pid);
00190                 std::string _link = "/proc/";
00191                 _link.append( buf );
00192                 _link.append( "/exe");
00193                 char proc[512];
00194                 int ch = readlink(_link.c_str(),proc,512);
00195                 if (ch != -1) {
00196                         proc[ch] = 0;
00197                         path = proc;
00198                         std::string::size_type t = path.find_last_of("/");
00199                         path = path.substr(0, t);
00200                 }
00201 
00202                 fullFileName = path + std::string("/");
00203 #endif
00204                 fullFileName.append("FreeSans.ttf");
00205 
00206                 font = TTF_OpenFont(fullFileName.c_str(), 16);
00207 
00208                 if (!font) {
00209                         fprintf(stderr, "TTF_OpenFont: %s\n", TTF_GetError());
00210                         fprintf(stderr, "All text will be ignored\n");
00211                 }
00212         }
00213 
00215         static unsigned int instances;
00216 
00218         static TTF_Font* font;
00219 };
00220 
00221 #endif // TEXT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends