Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/graphics/text_engine/text.cc @ 5768

Last change on this file since 5768 was 5768, checked in by bensch, 18 years ago

orxonox/trunk: font is a Texture now (this is a procedural texture)

File size: 8.7 KB
RevLine 
[4744]1/*
[1853]2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
[1855]10
11   ### File Specific:
[5343]12   main-programmer: Benjamin Grauer
[1855]13   co-programmer: ...
[1853]14*/
15
[5357]16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
[1853]17
[5343]18#include "text.h"
19#include "font.h"
[1853]20
[5343]21#include "graphics_engine.h"
22#include "resource_manager.h"
23#include "class_list.h"
24#include "debug.h"
25#include "p_node.h"
26
[1856]27using namespace std;
[1853]28
[5343]29/**
30 *  creates a new Text Element
31 * @param fontFile the Font to render this text in
32 * @param type The renderType to display this font in
33 */
[5767]34Text::Text(const char* fontFile, unsigned int textSize)
[5343]35{
36  this->init();
[1856]37
[5343]38  if (fontFile != NULL)
[5369]39    this->setFont(fontFile, FONT_DEFAULT_RENDER_SIZE);
[5768]40  this->setSizeY2D(textSize);
[5343]41}
42
[3245]43/**
[5343]44 *  deletes a Text out of memory
45 *
46 * This also ereases the text from the textList of the TextEngine
47 */
48Text::~Text()
49{
[5767]50  if (this->font != NULL && this->font != Font::getDefaultFont())
[5343]51    ResourceManager::getInstance()->unload(this->font);
52
53  if (this->text)
54    delete[] this->text;
[3365]55}
[1853]56
[5362]57/**
58 * initializes Text
59 */
[5343]60void Text::init()
61{
62  this->setClassID(CL_TEXT, "Text");
[1853]63
[5343]64  // initialize this Text
65  this->font = NULL;
66  this->text = NULL;
67  this->externText = NULL;
68  this->setAlignment(TEXT_DEFAULT_ALIGNMENT);
69  this->blending = TEXT_DEFAULT_BLENDING;
70  this->color = TEXT_DEFAULT_COLOR;
[5768]71  this->setSize(TEXT_DEFAULT_SIZE);
[5343]72  this->setText(NULL);
73}
74
[3245]75/**
[5343]76 * sets the Font of this Text to font from fontFile
77 * @param fontFile the File to load the Font from.
78 * @param fontSize the Size of the Font
79 */
80void Text::setFont(const char* fontFile, unsigned int fontSize)
81{
82  Font* tmpFont;
83  Text* newText;
84  Vector tmpVec;
85
[5345]86  // unloading the Font if we alrady have one loaded.
[5767]87  if (this->font != NULL && this->font != Font::getDefaultFont())
[5345]88    ResourceManager::getInstance()->unload(this->font);
89  this->font = NULL;
[5344]90
[5345]91  // load a new Font
92  if (fontFile != NULL)
[5344]93  {
[5345]94    tmpFont = (Font*)ResourceManager::getInstance()->load(fontFile, TTF, RP_GAME, &fontSize);
95    if (tmpFont != NULL)
96      this->font = tmpFont;
97    else
98      PRINTF(2)("Font %s could not be loaded, probably file not found\n", fontFile);
[5343]99  }
100}
101
102/**
[5362]103 * Sets a new Text to the font
[5343]104 * @param text the new text to set
105 */
106void Text::setText(const char* text, bool isExtern)
107{
108  if (isExtern)
109  {
110    this->externText = text;
111
112    if (unlikely(this->text != NULL))
113    {
114      delete[] this->text;
115      this->text = NULL;
116    }
117  }
118  else
119  {
120    this->externText = NULL;
121    if (this->text)
122      delete[] this->text;
123    if (text != NULL)
124    {
125      this->text = new char[strlen(text)+1];
126      strcpy(this->text, text);
127    }
128    else
129      this->text = NULL;
130  }
131
132  // setting up the Text-Width if DYNAMIC
[5418]133//  if (this->type & TEXT_RENDER_DYNAMIC && this->getAlignment() != TEXT_ALIGN_LEFT && this->font != NULL)
134  const Font* calcSizeFont = this->font;
135  if (calcSizeFont != NULL || (calcSizeFont = Font::getDefaultFont()) != NULL)
[5343]136  {
[5418]137    Glyph** glyphArray = calcSizeFont->getGlyphArray();
[5343]138
[5368]139    float width = 0;
[5343]140    const char* tmpText = this->externText;
141    if (this->externText == NULL)
142      tmpText = this->text;
143    if (tmpText != NULL)
144    {
145      while (*tmpText != '\0')
146      {
[5418]147        if(glyphArray[*tmpText] != NULL)
[5343]148        {
[5418]149          width += glyphArray[*tmpText]->advance;
[5343]150        }
151        tmpText++;
152      }
[5767]153      this->setSizeX2D(width *this->getSizeY2D());
[5343]154    }
155  }
156}
157
158/**
159 *  draws the Text
160 */
161void Text::draw() const
162{
163  glPushMatrix();
164  // transform for alignment.
165  if (this->getAlignment() == TEXT_ALIGN_RIGHT)
[5767]166    glTranslatef(-this->getSizeX2D(), 0, 0);
[5343]167  else if (this->getAlignment() == TEXT_ALIGN_CENTER || this->getAlignment() == TEXT_ALIGN_SCREEN_CENTER)
[5767]168    glTranslatef(-this->getSizeX2D()/2, 0, 0);
[5343]169
170  // drawing this Text.
171  // setting the Blending effects
172  glColor4f(this->color.x, this->color.y, this->color.z, this->blending);
173  glEnable(GL_BLEND);
174  glEnable(GL_TEXTURE_2D);
175  glBlendFunc(GL_SRC_ALPHA, GL_ONE);
176
177  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, GL_MODULATE );
178
[5767]179  Glyph** glyphArray;
180  if (likely (this->font != NULL))
[5343]181  {
[5767]182    glyphArray = this->font->getGlyphArray();
[5768]183    glBindTexture(GL_TEXTURE_2D, font->getTexture());
[5767]184  }
185  else
186  {
187    if (unlikely(Font::getDefaultFont() == NULL))
188      Font::initDefaultFont();
189    glyphArray = Font::getDefaultFont()->getGlyphArray();
[5768]190    glBindTexture(GL_TEXTURE_2D, Font::getDefaultFont()->getTexture());
[5767]191  }
192  const char* tmpText = this->externText;
193  if (this->externText == NULL)
194    tmpText = this->text;
195  if (likely(tmpText != NULL))
196  {
197    glTranslatef(getAbsCoor2D().x, getAbsCoor2D().y, 0);
198    glRotatef(this->getAbsDir2D(), 0, 0, 1);
199    Glyph* tmpGlyph;
200    float posX = 0.0f;
201    while (likely(*tmpText != '\0'))
[5343]202    {
[5767]203      if(likely((tmpGlyph = glyphArray[*tmpText]) != NULL))
[5343]204      {
[5767]205        glBegin(GL_QUADS);
[5419]206
[5767]207        glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[2]);
208        glVertex2d(posX, 0);
[5419]209
[5767]210        glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[3]);
[5768]211        glVertex2d(posX, this->getSizeY2D());
[5419]212
[5767]213        glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[3]);
[5768]214        glVertex2d(posX+tmpGlyph->width*this->getSizeY2D(), this->getSizeY2D());
[5419]215
[5767]216        glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[2]);
[5768]217        glVertex2d(posX+tmpGlyph->width*this->getSizeY2D(), 0);
[5419]218
[5767]219        glEnd();
220        glEndList();
[5768]221        posX += tmpGlyph->advance * this->getSizeY2D();
[5343]222      }
[5767]223      ++tmpText;
[5343]224    }
225  }
226
227  glPopMatrix();
228}
229
230/**
231 *  prints out some nice debug information about this text
232 */
233void Text::debug() const
234{
235  if (this->externText == NULL)
236    PRINT(0)("=== TEXT: %s ===\n", this->text);
237  else
238    PRINT(0)("=== TEXT: %s ===\n", this->externText);
239
240  if (this->getBindNode())
241    PRINT(0)("is bind to %s; ref=%p\n", this->getBindNode()->getName(), this->getBindNode());
242  PRINT(0)("Color: %0.2f %0.2f %0.2f\n", this->color.x, this->color.y, this->color.z);
243}
244
245
246////////////
247/// UTIL ///
248////////////
249/**
[5345]250 * Loads a Font from an SDL_surface into a texture.
[5343]251 * @param surface The surface to make the texture of
252 * @param texCoord The texture coordinates of the 4 corners of the texture
253 * @returns the ID of the texture
254 */
255GLuint Text::loadTexture(SDL_Surface *surface, TexCoord* texCoord)
256{
257  GLuint texture;
258  int w, h;
259  SDL_Surface *image;
260  SDL_Rect area;
261  Uint32 saved_flags;
262  Uint8  saved_alpha;
263
264  /* Use the surface width and height expanded to powers of 2 */
265  w = powerOfTwo(surface->w);
266  h = powerOfTwo(surface->h);
267  if (texCoord != NULL)
268  {
269    texCoord->minU = 0.0f;
270    texCoord->minV = 0.0f;
271    texCoord->maxU = (GLfloat)surface->w / w;
272    texCoord->maxV = (GLfloat)surface->h / h;
273  }
274  image = SDL_CreateRGBSurface(SDL_SWSURFACE,
275                               w, h,
276                               32,
277#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
278                               0x000000FF,
279                               0x0000FF00,
280                               0x00FF0000,
281                               0xFF000000
282#else
283                                   0xFF000000,
284                               0x00FF0000,
285                               0x0000FF00,
286                               0x000000FF
287#endif
288                              );
289  if ( image == NULL ) {
290    return 0;
291  }
292
293  /* Save the alpha blending attributes */
294  saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
295  saved_alpha = surface->format->alpha;
296  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
297    SDL_SetAlpha(surface, 0, 0);
298  }
299
300  /* Copy the surface into the GL texture image */
301  area.x = 0;
302  area.y = 0;
303  area.w = surface->w;
304  area.h = surface->h;
305  SDL_BlitSurface(surface, &area, image, &area);
306
307  /* Restore the alpha blending attributes */
308  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
309    SDL_SetAlpha(surface, saved_flags, saved_alpha);
310  }
311
312  /* Create an OpenGL texture for the image */
313  glGenTextures(1, &texture);
314  glBindTexture(GL_TEXTURE_2D, texture);
[5368]315  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
[5343]316  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
317  glTexImage2D(GL_TEXTURE_2D,
318               0,
319               GL_RGBA,
320               w, h,
321               0,
322               GL_RGBA,
323               GL_UNSIGNED_BYTE,
324               image->pixels);
325  SDL_FreeSurface(image); /* No longer needed the data */
326
327  return texture;
328}
329
330/**
331 *  Quick utility function for texture creation
332 * @param input an integer
333 * @returns the next bigger 2^n-integer than input
334 */
335int Text::powerOfTwo(int input)
336{
337  int value = 1;
338
339  while ( value < input )
340    value <<= 1;
341  return value;
342}
Note: See TracBrowser for help on using the repository browser.