Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: removed support for text-render-static

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