Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: Font is PERFECT :)

File size: 7.8 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 "util/loading/resource_manager.h"
22#include "debug.h"
23
24using namespace std;
25
26/**
27 * @brief creates a new Text Element
28 * @param fontFile the Font to render this text in
29 * @param type The renderType to display this font in
30 */
31Text::Text(const std::string& fontFile, unsigned int textSize)
32{
33  this->setClassID(CL_TEXT, "Text");
34
35  // initialize this Text
36  this->font = NULL;
37  this->text = "";
38  this->setAlignment(TEXT_DEFAULT_ALIGNMENT);
39  this->blending = TEXT_DEFAULT_BLENDING;
40  this->color = TEXT_DEFAULT_COLOR;
41  this->setSize(TEXT_DEFAULT_SIZE);
42  this->setText("");
43
44
45  if (!fontFile.empty())
46    this->setFont(fontFile, FONT_DEFAULT_RENDER_SIZE);
47  this->setSizeY2D(textSize);
48}
49
50/**
51 * @brief deletes a Text out of memory
52 */
53Text::~Text()
54{
55  if (this->font != NULL && this->font != Font::getDefaultFont())
56    ResourceManager::getInstance()->unload(this->font);
57}
58
59
60/**
61 * @brief sets the Font of this Text to font from fontFile
62 * @param fontFile the File to load the Font from.
63 * @param fontSize the Size of the Font
64 */
65void Text::setFont(const std::string& fontFile, unsigned int fontSize)
66{
67  Font* newFont;
68  Font* oldFont = this->font;
69
70  // load a new Font
71  if (!fontFile.empty())
72  {
73    newFont = (Font*)ResourceManager::getInstance()->load(fontFile, TTF, RP_GAME, (int)fontSize);
74    if (newFont == NULL)
75    {
76      newFont = Font::getDefaultFont();
77      PRINTF(2)("Font %s could not be loaded, probably file not found\n", fontFile.c_str());
78    }
79  }
80  else
81    newFont = Font::getDefaultFont();
82
83  // unloading the Font if we alrady have one loaded.
84  this->font = newFont;
85  if (oldFont != NULL && oldFont != Font::getDefaultFont())
86    ResourceManager::getInstance()->unload(oldFont);
87}
88
89/**
90 * @brief Sets a new Text to the font
91 * @param text the new text to set
92 */
93void Text::setText(const std::string& text)
94{
95  this->text = text;
96
97  // setting up the Text-Width if DYNAMIC
98//  if (this->type & TEXT_RENDER_DYNAMIC && this->getAlignment() != TEXT_ALIGN_LEFT && this->font != NULL)
99  const Font* calcSizeFont = this->font;
100  if (calcSizeFont != NULL || (calcSizeFont = Font::getDefaultFont()) != NULL)
101  {
102    Glyph** glyphArray = calcSizeFont->getGlyphArray();
103
104    float width = 0;
105    if (!this->text.empty())
106    {
107      for (unsigned int i = 0; i < this->text.size(); i++)
108      {
109        if(glyphArray[this->text[i]] != NULL)
110        {
111          width += glyphArray[this->text[i]]->advance;
112        }
113      }
114      this->setSizeX2D(width *this->getSizeY2D());
115    }
116  }
117}
118
119/**
120 * @brief draws the Text
121 */
122void Text::draw() const
123{
124  glPushMatrix();
125  // transform for alignment.
126  if (this->getAlignment() == TEXT_ALIGN_RIGHT)
127    glTranslatef(-this->getSizeX2D(), 0, 0);
128  else if (this->getAlignment() == TEXT_ALIGN_CENTER || this->getAlignment() == TEXT_ALIGN_SCREEN_CENTER)
129    glTranslatef(-this->getSizeX2D()/2, 0, 0);
130
131  // drawing this Text.
132  // setting the Blending effects
133  glColor4f(this->color.x, this->color.y, this->color.z, this->blending);
134  glEnable(GL_BLEND);
135  glEnable(GL_TEXTURE_2D);
136  glBlendFunc(GL_SRC_ALPHA, GL_ONE);
137
138  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, GL_MODULATE );
139
140  Glyph** glyphArray;
141  if (likely (this->font != NULL))
142  {
143    glyphArray = this->font->getGlyphArray();
144    glBindTexture(GL_TEXTURE_2D, font->getTexture());
145  }
146  else
147  {
148    if (unlikely(Font::getDefaultFont() == NULL))
149      Font::initDefaultFont();
150    glyphArray = Font::getDefaultFont()->getGlyphArray();
151    glBindTexture(GL_TEXTURE_2D, Font::getDefaultFont()->getTexture());
152  }
153  if (likely(!this->text.empty()))
154  {
155    glTranslatef(getAbsCoor2D().x, getAbsCoor2D().y, 0);
156    glRotatef(this->getAbsDir2D(), 0, 0, 1);
157    Glyph* tmpGlyph;
158    float posX = 0.0f;
159
160    glBegin(GL_QUADS);
161    for (unsigned int i = 0; i < this->text.size(); i++)
162    {
163      if(likely((tmpGlyph = glyphArray[this->text[i]]) != NULL))
164      {
165        glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[2]);
166        glVertex2d(posX+tmpGlyph->maxX*this->getSizeY2D(), 0);
167
168        glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[3]);
169        glVertex2d(posX+tmpGlyph->maxX*this->getSizeY2D(), this->getSizeY2D());
170
171        glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[3]);
172        glVertex2d(posX+tmpGlyph->minX*this->getSizeY2D(), this->getSizeY2D());
173
174        glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[2]);
175        glVertex2d(posX+tmpGlyph->minX*this->getSizeY2D(), 0);
176
177        posX += tmpGlyph->advance * this->getSizeY2D();
178      }
179    }
180    glEnd();
181  }
182
183  glPopMatrix();
184}
185
186/**
187 * @brief prints out some nice debug information about this text
188 */
189void Text::debug() const
190{
191  PRINT(0)("=== TEXT: %s ===\n", this->text.c_str());
192  PRINT(0)("Color: %0.2f %0.2f %0.2f\n", this->color.x, this->color.y, this->color.z);
193}
194
195
196////////////
197/// UTIL ///
198////////////
199/**
200 * @brief Loads a Font from an SDL_surface into a texture.
201 * @param surface The surface to make the texture of
202 * @param texCoord The texture coordinates of the 4 corners of the texture
203 * @returns the ID of the texture
204 */
205GLuint Text::loadTexture(SDL_Surface *surface, TexCoord* texCoord)
206{
207  GLuint texture;
208  int w, h;
209  SDL_Surface *image;
210  SDL_Rect area;
211  Uint32 saved_flags;
212  Uint8  saved_alpha;
213
214  /* Use the surface width and height expanded to powers of 2 */
215  w = powerOfTwo(surface->w);
216  h = powerOfTwo(surface->h);
217  if (texCoord != NULL)
218  {
219    texCoord->minU = 0.0f;
220    texCoord->minV = 0.0f;
221    texCoord->maxU = (GLfloat)surface->w / w;
222    texCoord->maxV = (GLfloat)surface->h / h;
223  }
224  image = SDL_CreateRGBSurface(SDL_SWSURFACE,
225                               w, h,
226                               32,
227#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
228                               0x000000FF,
229                               0x0000FF00,
230                               0x00FF0000,
231                               0xFF000000
232#else
233                                   0xFF000000,
234                               0x00FF0000,
235                               0x0000FF00,
236                               0x000000FF
237#endif
238                              );
239  if ( image == NULL ) {
240    return 0;
241  }
242
243  /* Save the alpha blending attributes */
244  saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
245  saved_alpha = surface->format->alpha;
246  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
247    SDL_SetAlpha(surface, 0, 0);
248  }
249
250  /* Copy the surface into the GL texture image */
251  area.x = 0;
252  area.y = 0;
253  area.w = surface->w;
254  area.h = surface->h;
255  SDL_BlitSurface(surface, &area, image, &area);
256
257  /* Restore the alpha blending attributes */
258  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
259    SDL_SetAlpha(surface, saved_flags, saved_alpha);
260  }
261
262  /* Create an OpenGL texture for the image */
263  glGenTextures(1, &texture);
264  glBindTexture(GL_TEXTURE_2D, texture);
265  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
266  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
267  glTexImage2D(GL_TEXTURE_2D,
268               0,
269               GL_RGBA,
270               w, h,
271               0,
272               GL_RGBA,
273               GL_UNSIGNED_BYTE,
274               image->pixels);
275  SDL_FreeSurface(image); /* No longer needed the data */
276
277  return texture;
278}
279
280/**
281 * @brief Quick utility function for texture creation
282 * @param input an integer
283 * @returns the next bigger 2^n-integer than input
284 */
285int Text::powerOfTwo(int input)
286{
287  int value = 1;
288
289  while ( value < input )
290    value <<= 1;
291  return value;
292}
Note: See TracBrowser for help on using the repository browser.