Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7264 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
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"
[7193]22#include "util/loading/resource_manager.h"
[5343]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 */
[7221]34Text::Text(const std::string& fontFile, unsigned int textSize)
[5343]35{
36  this->init();
[1856]37
[7221]38  if (!fontFile.empty())
[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);
[3365]52}
[1853]53
[5362]54/**
55 * initializes Text
56 */
[5343]57void Text::init()
58{
59  this->setClassID(CL_TEXT, "Text");
[1853]60
[5343]61  // initialize this Text
62  this->font = NULL;
[7221]63  this->text = "";
[5343]64  this->setAlignment(TEXT_DEFAULT_ALIGNMENT);
65  this->blending = TEXT_DEFAULT_BLENDING;
66  this->color = TEXT_DEFAULT_COLOR;
[5768]67  this->setSize(TEXT_DEFAULT_SIZE);
[7221]68  this->setText("");
[5343]69}
70
[3245]71/**
[5343]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 */
[7221]76void Text::setFont(const std::string& fontFile, unsigned int fontSize)
[5343]77{
78  Font* tmpFont;
79  Text* newText;
80  Vector tmpVec;
81
[5345]82  // unloading the Font if we alrady have one loaded.
[5767]83  if (this->font != NULL && this->font != Font::getDefaultFont())
[5345]84    ResourceManager::getInstance()->unload(this->font);
85  this->font = NULL;
[5344]86
[5345]87  // load a new Font
[7221]88  if (!fontFile.empty())
[5344]89  {
[6645]90    tmpFont = (Font*)ResourceManager::getInstance()->load(fontFile, TTF, RP_GAME, (int)fontSize);
[5345]91    if (tmpFont != NULL)
92      this->font = tmpFont;
93    else
[7221]94      PRINTF(2)("Font %s could not be loaded, probably file not found\n", fontFile.c_str());
[5343]95  }
96}
97
98/**
[5362]99 * Sets a new Text to the font
[5343]100 * @param text the new text to set
101 */
[7221]102void Text::setText(const std::string& text)
[5343]103{
[7221]104  this->text = text;
[5343]105
106  // setting up the Text-Width if DYNAMIC
[5418]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)
[5343]110  {
[5418]111    Glyph** glyphArray = calcSizeFont->getGlyphArray();
[5343]112
[5368]113    float width = 0;
[7221]114    if (!this->text.empty())
[5343]115    {
[7221]116      for (unsigned int i = 0; i < this->text.size(); i++)
[5343]117      {
[7221]118        if(glyphArray[this->text[i]] != NULL)
[5343]119        {
[7221]120          width += glyphArray[this->text[i]]->advance;
[5343]121        }
122      }
[5767]123      this->setSizeX2D(width *this->getSizeY2D());
[5343]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)
[5767]136    glTranslatef(-this->getSizeX2D(), 0, 0);
[5343]137  else if (this->getAlignment() == TEXT_ALIGN_CENTER || this->getAlignment() == TEXT_ALIGN_SCREEN_CENTER)
[5767]138    glTranslatef(-this->getSizeX2D()/2, 0, 0);
[5343]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
[5767]149  Glyph** glyphArray;
150  if (likely (this->font != NULL))
[5343]151  {
[5767]152    glyphArray = this->font->getGlyphArray();
[5768]153    glBindTexture(GL_TEXTURE_2D, font->getTexture());
[5767]154  }
155  else
156  {
157    if (unlikely(Font::getDefaultFont() == NULL))
158      Font::initDefaultFont();
159    glyphArray = Font::getDefaultFont()->getGlyphArray();
[5768]160    glBindTexture(GL_TEXTURE_2D, Font::getDefaultFont()->getTexture());
[5767]161  }
[7221]162  if (likely(!this->text.empty()))
[5767]163  {
164    glTranslatef(getAbsCoor2D().x, getAbsCoor2D().y, 0);
165    glRotatef(this->getAbsDir2D(), 0, 0, 1);
166    Glyph* tmpGlyph;
167    float posX = 0.0f;
[6349]168
169    glBegin(GL_QUADS);
[7221]170    for (unsigned int i = 0; i < this->text.size(); i++)
[5343]171    {
[7221]172      if(likely((tmpGlyph = glyphArray[this->text[i]]) != NULL))
[5343]173      {
[6349]174        glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[2]);
175        glVertex2d(posX+tmpGlyph->width*this->getSizeY2D(), 0);
[5419]176
[6349]177        glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[3]);
178        glVertex2d(posX+tmpGlyph->width*this->getSizeY2D(), this->getSizeY2D());
[5419]179
[5767]180        glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[3]);
[5768]181        glVertex2d(posX, this->getSizeY2D());
[5419]182
[6349]183        glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[2]);
184        glVertex2d(posX, 0);
[5419]185
[5768]186        posX += tmpGlyph->advance * this->getSizeY2D();
[5343]187      }
188    }
[6349]189    glEnd();
[5343]190  }
191
192  glPopMatrix();
193}
194
195/**
196 *  prints out some nice debug information about this text
197 */
198void Text::debug() const
199{
[7221]200  PRINT(0)("=== TEXT: %s ===\n", this->text.c_str());
[5343]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/**
[5345]212 * Loads a Font from an SDL_surface into a texture.
[5343]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);
[5368]277  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
[5343]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.