Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7263 was 7221, checked in by bensch, 19 years ago

orxonox/trunk: merged the std-branche back, it runs on windows and Linux

svn merge https://svn.orxonox.net/orxonox/branches/std . -r7202:HEAD

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