Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/branches/textEngine/src/lib/graphics/font/text_engine.cc @ 3769

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

orxonox/branches/textEngine: compiling again, many movements… still working

File size: 21.1 KB
RevLine 
[3655]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:
[3766]12   main-programmer: Benjamin Grauer
[3655]13   co-programmer: ...
[3766]14
15   for some fonts and licenses visit: =http://www.dafont.com/en/font.php=
16
17   !! IMPORTANT !! When using ttf fonts clear the license issues prior to
18   adding them to orxonox. This is really important, because we do not
[3767]19   want to offend anyone.
[3655]20*/
21
[3766]22#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_FONT
[3655]23
[3766]24#include "text_engine.h"
[3655]25
26using namespace std;
27
[3766]28#include <stdlib.h>
29#include <stdio.h>
30#include <string.h>
[3655]31
[3766]32#include "graphics_engine.h"
[3769]33#include "resource_manager.h"
34
[3766]35#include "p_node.h"
36#include "vector.h"
37#include "debug.h"
38
39
40////////////
[3768]41/// TEXT ///
[3766]42////////////
[3769]43Text::Text(Font* font, int type)
[3768]44{
[3769]45  // initialize this Text
46  this->bindNode = NULL;
47  this->text = NULL;
48  this->texture = 0;
49  this->setType(TEXT_DYNAMIC);
50  this->setPosition(0, 0);
[3768]51
[3769]52  this->setText(FONT_DEFAULT_TEXT);
[3768]53}
54
[3769]55
[3768]56Text::~Text(void)
57{
58
59}
60
61
62void Text::setBindNode(PNode* bindNode)
63{
64  this->bindNode = bindNode;
65}
66
[3655]67/**
[3768]68   \brief sets the Type of this Text
69   \param type the type to set.
70*/
71void Text::setType(int type)
72{
73  this->type = type;
74}
75
76
77/**
78   \brief Sets a new Text to the font
79   \param text the new text to set
80*/
81void Text::setText(const char* text)
82{
83  if (this->text)
84    delete []this->text;
85  this->text = new char[strlen(text)+1];
86  strcpy(this->text, text);
87}
88
89/**
90   \brief sets a Position.
91   \param x the x-position in pixels from the left border
92   \param y the y-position in pixels from the top border
93*/
94void Text::setPosition(int x, int y)
95{
96  this->posSize.x = x;
97  this->posSize.y = y;
98}
99
[3769]100/**
101   \brief sets a new color to the font
102   \param r Red
103   \param g Green
104   \param b Blue
105*/
106void Text::setColor(Uint8 r, Uint8 g, Uint8 b)
107{
108  this->color.r = r;
109  this->color.g = g;
110  this->color.b = b;
111}
[3768]112
113/**
[3769]114   \brief creates a texture out of the given parameters
115
116   this has to be called every time by the user, to if changes were made.
117*/
118void Text::createTexture(void)
119{
120  SDL_Surface* tmpSurf;
121  if (this->texture)
122    glDeleteTextures(1, &this->texture);
123  tmpSurf = TTF_RenderText_Blended(this->font->font,
124                                   this->text,
125                                   this->color);
126  if (tmpSurf)
127    this->texture = loadTexture(tmpSurf, &this->texCoord);
128
129  this->posSize.w = tmpSurf->w;
130  this->posSize.h = tmpSurf->h;
131  SDL_FreeSurface(tmpSurf);
132}
133
134/**
[3768]135   \brief draws the Font
136   \todo FIX this is to slow/static
137*/
138void Text::draw(void)
139{
140  // storing all the Transformation Matrices.
141  GLdouble modMat[16];
142  GLdouble projMat[16];
143  GLint viewPort[4];
144  glGetDoublev(GL_PROJECTION_MATRIX, projMat);
145  glGetDoublev(GL_MODELVIEW_MATRIX, modMat);
146  glGetIntegerv(GL_VIEWPORT, viewPort);
147
[3769]148  printf("rendering some Text\n");
149  //enter2DMode();
[3768]150
[3769]151
[3768]152  // setting the Position of this Text.
153  Vector pos;
154  if (this->bindNode)
155    {
156      GLdouble x = this->bindNode->getAbsCoor().x;
157      GLdouble y = this->bindNode->getAbsCoor().y;
158      GLdouble z = this->bindNode->getAbsCoor().z;
159      GLdouble tmp[3];
160      gluProject(x, y, z, modMat, projMat, viewPort, tmp, tmp+1, tmp+2);
161      printf("test %f %f %f,\n", tmp[0], tmp[1], tmp[2]);
162      pos.x = tmp[0] + this->posSize.x;
163      pos.y = GraphicsEngine::getInstance()->getResolutionY() - tmp[1] + this->posSize.y;
164      pos.z = tmp[2];
165    }
166  else 
167    {
168      pos.x = this->posSize.x;
169      pos.y = this->posSize.y;
170      pos.z = 0;
171    }
172
173  // drawing this Text.
174  if(type == TEXT_STATIC)
175    {
176      glBindTexture(GL_TEXTURE_2D, this->texture);
177      glEnable(GL_TEXTURE_2D);
178      glBegin(GL_QUADS);
179     
180      glTexCoord2f(this->texCoord.minU, this->texCoord.minV);
181      glVertex2i(pos.x,   pos.);
182     
183      glTexCoord2f(this->texCoord.maxU, this->texCoord.minV);
184      glVertex2i(pos.x + this->posSize.w, pos.);
185     
186      glTexCoord2f(this->texCoord.maxU, this->texCoord.maxV);
187      glVertex2i(pos.x + this->posSize.w, pos.y + this->posSize.h);
188     
189      glTexCoord2f(this->texCoord.minU, this->texCoord.maxV);
190      glVertex2i(pos.x, pos.y + this->posSize.h);
191     
192      glEnd();
193    }
194  else //(if type & TEXT_DYNAMIC)
195    {
196      Glyph** glyphArray = this->font->getGlyphArray();
197      glBindTexture(GL_TEXTURE_2D, this->font->getFastTextureID());
198      //      glEnable(GL_TEXTURE_2D);
199      glTranslatef(pos.x, pos.y, 0);
200
201      printf("%d, %d\n", this->font->getFastTextureID(), glyphArray[65]->displayList);
202      char* tmpText = this->text;
203      while (*tmpText != '\0')
204        {
205          if(glyphArray[*tmpText])
206            {
207              glCallList(glyphArray[*tmpText]->displayList);
208              glTranslatef(glyphArray[*tmpText]->width, 0, 0);
209            }
210          tmpText++;
211        }
212    }
[3769]213  //leave2DMode();
[3768]214}
215
216
217
218////////////
219/// FONT ///
220////////////
221/**
[3766]222   \brief constructs a Font
223   \param fontFile the File to load the font from
[3767]224   \param fontSize the Size of the Font in Pixels
225   \param r Red value of the Font.
226   \param g Green value of the Font.
227   \param b Blue value of the Font.
[3766]228*/
[3767]229Font::Font(const char* fontFile, unsigned int fontSize, Uint8 r, Uint8 g, Uint8 b)
[3766]230{
231  // setting default values.
232  this->font = NULL;
233  this->fontFile = NULL;
234  this->glyphArray = NULL;
[3769]235  this->fastTextureID = 0; 
[3766]236 
237  this->setSize(fontSize);
[3769]238  this->setStyle("c");//TTF_STYLE_NORMAL);
239
[3766]240  this->setFont(fontFile);
241
242
[3769]243  this->setFastColor(r, g, b);
[3768]244
[3766]245  this->fastTextureID = this->createFastTexture();
246}
247
248/**
[3767]249   \brief destructs a font
250*/
251Font::~Font(void)
252{
[3769]253  // deleting the List of all Texts
[3767]254
[3769]255  // deleting all Glyphs
[3767]256  if (this->glyphArray)
257    {
258      for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
259        delete this->glyphArray[i];
260      delete []this->glyphArray;
261    }
262
[3769]263  // erease this font out of the memory.
[3767]264  if (this->font)
265    TTF_CloseFont(this->font);
266}
267
268/**
[3766]269   \brief sets The Font.
270   \param fontFile The file containing the font.
271   \returns true if loaded, false if something went wrong, or if a font was loaded before.
272*/
273bool Font::setFont(const char* fontFile)
274{
275  if (!this->fontFile)
276    {
277      this->fontFile = new char[strlen(fontFile)+1];
278      strcpy(this->fontFile, fontFile);
279     
280      this->font = TTF_OpenFont(this->fontFile, this->fontSize);
281      if(!this->font) 
282        {
283          PRINTF(1)("TTF_OpenFont: %s\n", TTF_GetError());
284          return false;
285      }
286      return true;
287    }
288  else
289    {
290      PRINTF(2)("Font already initialized, unable to change it now.\n");
291      return false;
292    }
293}
294
295/**
296   \brief sets a specific renderStyle
297   \param renderStyle the Style to render: a char-array containing:
298   i: italic, b: bold, u, underline
299*/
300void Font::setStyle(char* renderStyle)
301{
[3768]302  this->renderStyle = TTF_STYLE_NORMAL;
[3766]303 
304  for (int i = 0; i < strlen(renderStyle); i++)
305    if (strncmp(renderStyle+i, "b", 1) == 0) 
[3768]306      this->renderStyle |= TTF_STYLE_BOLD;
[3766]307    else if (strncmp(renderStyle+i, "i", 1) == 0)
[3768]308      this->renderStyle |= TTF_STYLE_ITALIC;
[3766]309    else if (strncmp(renderStyle+i, "u", 1) == 0) 
[3768]310      this->renderStyle |= TTF_STYLE_UNDERLINE;
[3766]311
312  if (this->font)
[3768]313    TTF_SetFontStyle(this->font, this->renderStyle);
[3766]314  else
315    PRINTF(2)("Font was not initialized, please do so before setting the Font-Style.\n");
316}
317
[3768]318
319
[3766]320/**
321   \brief Sets a new Size to the font
322   \param fontSize The new Size in pixels.
323*/
324void Font::setSize(unsigned int fontSize)
325{
326  this->fontSize = fontSize;
327}
328
329/**
330   \brief sets a new color to the font
331   \param r Red
332   \param g Green
333   \param b Blue
334*/
[3769]335void Font::setFastColor(Uint8 r, Uint8 g, Uint8 b)
[3766]336{
[3769]337  this->fastColor.r = r;
338  this->fastColor.g = g;
339  this->fastColor.b = b;
[3766]340}
341
342/**
343   \returns the maximum height of the Font, if the font was initialized, 0 otherwise
344*/
345int Font::getMaxHeight(void)
346{
347  if (this->font)
348    return TTF_FontHeight(this->font);
349  else
350    return 0;
351}
352
353/**
354   \returns the maximum ascent of the Font, if the font was initialized, 0 otherwise
355
356   the ascent is the pixels of the font above the baseline
357*/
358int Font::getMaxAscent(void)
359{
360  if (this->font)
361    return TTF_FontAscent(this->font);
362  else
363    return 0;
364}
365
366/**
367   \returns the maximum descent of the Font, if the font was initialized, 0 otherwise
368
369   the descent is the pixels of the font below the baseline
370*/
371int Font::getMaxDescent(void)
372{
373  if (this->font)
374    return TTF_FontDescent(this->font);
375  else
376    return 0;
377}
378
379/**
380   \param character The character to get info about.
381   \returns a Glyph struct of a character. This Glyph is a pointer,
382   and MUST be deleted by the user..
383
384   This only works for horizontal fonts. see
385   http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html
386   for more info about vertical Fonts
387*/
388Glyph* Font::getGlyphMetrics(Uint16 character)
389{
390  Glyph* rg = new Glyph;
391  rg->character = character;
392  TTF_GlyphMetrics(this->font, rg->character,
393                   &rg->minX, &rg->maxX,
394                   &rg->minY, &rg->maxY,
395                   &rg->advance);
396  rg->height = rg->maxY - rg->minY;
397  rg->width = rg->maxX - rg->minX;
398  rg->bearingX = (rg->advance - rg->width) / 2;
399  rg->bearingY = rg->maxY;
400  return rg;
401}
402
403/**
404   \brief entering 2D Mode
405   
406   this is a GL-Projection-mode, that is orthogonal, for placing the font in fron of everything else
407*/
408void Font::enter2DMode(void)
409{
410  SDL_Surface *screen = SDL_GetVideoSurface();
411 
412  /* Note, there may be other things you need to change,
413     depending on how you have your OpenGL state set up.
414  */
415  glPushAttrib(GL_ENABLE_BIT);
416  glDisable(GL_DEPTH_TEST);
417  glDisable(GL_CULL_FACE);
418  glDisable(GL_LIGHTING);  // will be set back when leaving 2D-mode
419  glEnable(GL_TEXTURE_2D);
420
421  /* This allows alpha blending of 2D textures with the scene */
422  glEnable(GL_BLEND);
423  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
424 
425  glViewport(0, 0, screen->w, screen->h);
426 
427  glMatrixMode(GL_PROJECTION);
428  glPushMatrix();
429  glLoadIdentity();
430 
431  glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
432 
433  glMatrixMode(GL_MODELVIEW);
434  glPushMatrix();
435  glLoadIdentity();
436 
437  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
438}
439
440/**
441   \brief leaves the 2DMode again also \see Font::enter2DMode(void)
442*/
443void Font::leave2DMode(void)
444{
445        glMatrixMode(GL_MODELVIEW);
446        glPopMatrix();
447
448        glMatrixMode(GL_PROJECTION);
449        glPopMatrix();
450
451        glPopAttrib();
452}
453
454
455GLuint Font::createFastTexture(void)
456{
457  /* interesting GLYPHS:
458   *  33-47: Special Characters.
459   *  48-57: 0-9
460   *  58-63: some more special chars (minor)
461   *  65-90: A-Z
462   *  97-122: a-z
463   */
464  int numberOfGlyphs = 90;
465
466  this->initGlyphs(33, numberOfGlyphs);
467
468  int rectSize = this->findOptimalFastTextureSize();
469
470  // setting default values. (maybe not needed afterwards)
471  SDL_Color tmpColor;  tmpColor.r = tmpColor.g = tmpColor.b = 0;
472  // Surface definition.
473  SDL_Rect tmpRect; // this represents a Rectangle for blitting.
474  SDL_Surface* tmpSurf =  SDL_CreateRGBSurface(SDL_SWSURFACE,
475                                               rectSize, rectSize,
476                                               32,
477#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
478                                               0x000000FF, 
479                                               0x0000FF00, 
480                                               0x00FF0000, 
481                                               0xFF000000
482#else
483                                               0xFF000000,
484                                               0x00FF0000, 
485                                               0x0000FF00, 
486                                               0x000000FF
487#endif
488                                               );
489  tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h;
490  SDL_SetClipRect(tmpSurf, &tmpRect);
491  int maxLineHeight = 0;
492
493  // all the interessting Glyphs
494  for (int i = 33; i <= 122; i++)
495    {
496      SDL_Surface* glyphSurf = NULL;
497      Glyph* tmpGlyph;
498
499      if (tmpGlyph = this->glyphArray[i])
500        {
501          if (tmpGlyph->height > maxLineHeight)
502            maxLineHeight = tmpGlyph->height;
503         
504          if (tmpRect.x+tmpGlyph->width > tmpSurf->w)
505            {
506              tmpRect.x = 0;
507              tmpRect.y = tmpRect.y + maxLineHeight + 1;
508              maxLineHeight = 0;
509            }
510          if (tmpRect.y + maxLineHeight > tmpSurf->h)
511            {
512              PRINTF(1)("Protection, so font cannot write over the boundraries error (this should not heappen\n");
513              break;
514            }
515          // reading in the new Glyph
[3769]516          glyphSurf = TTF_RenderGlyph_Blended(this->font, i, this->fastColor);
[3766]517          if( glyphSurf ) 
518            {
519
520              SDL_SetAlpha(glyphSurf, 0, 0);
521
522              SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect);
523              TexCoord tmpTexCoord;
524              tmpTexCoord.minU = (float)tmpRect.x/(float)tmpSurf->w;
525              tmpTexCoord.maxU = (float)(tmpRect.x+tmpGlyph->width)/(float)tmpSurf->w;
526              tmpTexCoord.minV = (float)tmpRect.y/(float)tmpSurf->w;
527              tmpTexCoord.maxV = (float)(tmpRect.y+tmpGlyph->height)/(float)tmpSurf->w;
528              tmpGlyph->displayList = glGenLists(1);
529
530              glNewList(tmpGlyph->displayList, GL_COMPILE);
531              glBegin(GL_QUADS);
532              glTexCoord2f(tmpTexCoord.minU, tmpTexCoord.minV);
533              glVertex2d(0, 0);
534              glTexCoord2f(tmpTexCoord.minU, tmpTexCoord.maxV);
535              glVertex2d(0, tmpGlyph->height);
536              glTexCoord2f(tmpTexCoord.maxU, tmpTexCoord.maxV);
537              glVertex2d(tmpGlyph->width, tmpGlyph->height);
538              glTexCoord2f(tmpTexCoord.maxU, tmpTexCoord.minV);
539              glVertex2d(tmpGlyph->width, 0);
540              glEnd();
541              glEndList();
542              SDL_FreeSurface(glyphSurf);
543
544              tmpRect.x += tmpGlyph->width + 1;
545
546              // Outputting Glyphs to BMP-files.
547              /*
548                char outname[64];
549                if (i < 10)
550                sprintf( outname, "glyph-00%d.bmp", i );
551                else if (i <100)
552                sprintf( outname, "glyph-0%d.bmp", i );
553                else
554                sprintf( outname, "glyph-%d.bmp", i );
555                SDL_SaveBMP(tmpSurf, outname);
556              */
557            }
558        }
559    }
560  GLuint texture;
561  glGenTextures(1, &texture);
562  glBindTexture(GL_TEXTURE_2D, texture);
563  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
564  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
565  glTexImage2D(GL_TEXTURE_2D,
566               0,
567               GL_RGBA,
568               tmpSurf->w, tmpSurf->h,
569               0,
570               GL_RGBA,
571               GL_UNSIGNED_BYTE,
572               tmpSurf->pixels);
573  SDL_FreeSurface(tmpSurf);
574  return texture;
575}
576
577/**
578   \brief stores Glyph Metrics in an Array.
579   \param from The Glyph to start from.
580   \param count The number of Glyphs to start From.
581*/
582void Font::initGlyphs(Uint16 from, Uint16 count)
583{
584  /* initialize the Array, and set all its entries to NULL
585   *  only if the Glyph-array has not been initialized
586   */
587  if (!this->glyphArray)
588    {
589      this->glyphArray = new Glyph*[FONT_HIGHEST_KNOWN_CHAR];
590      for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
591        this->glyphArray[i] = NULL;
592    }
593 
594  Uint16 lastGlyph = from + count;
595 
596  for (int i = from; i <= lastGlyph; i++)
597    {
598      // setting up all the Glyphs we like.
599      glyphArray[i] = getGlyphMetrics(i);
600    }
601  return;
602}
603
604/**
605   \returns the optimal size to use as the texture size
606
607   \todo: this algorithm can be a lot more faster, althought it does
608   not really matter within the init-context, and 128 glyphs.
609
610   This function searches for a 2^n sizes texture-size, this is for
611   openGL-version < 1.2 compatibility. and because it is realy easy like this.
612*/
613int Font::findOptimalFastTextureSize(void)
614{
615  int i;
616  int x,y; // the counters
617  int maxLineHeight;
618  int size = 32;      // starting Value, we have to start somewhere 32 seems reasonable.
619  bool sizeOK = false;
620  Glyph* tmpGlyph;
621
622  while (!sizeOK)
623    {
624      x = 0; y = 0;
625      maxLineHeight = 0;
626      for (i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
627        {
628          if(tmpGlyph = this->glyphArray[i])
629            {
630              // getting the height of the highest Glyph in the Line.
631              if (tmpGlyph->height > maxLineHeight)
632                maxLineHeight = tmpGlyph->height;
633
634              if (x + tmpGlyph->width > size)
635                {
636                  x = 0;
637                  y = y + maxLineHeight;
638                  maxLineHeight = 0;
639                }
640              if (y + maxLineHeight + 1 > size)
641                break;
642              x += tmpGlyph->width + 1;
643
644            }
645        }
646      if (i == FONT_HIGHEST_KNOWN_CHAR)
647        sizeOK = true;
648      else
649        size *= 2;
650    }
651  return size;
652 
653}
654
655
656/**
657   \brief a simple function to get some interesting information about this class
658*/
659void Font::debug(void)
660{
661
662  // print the loaded font's style
663  int style;
664  style=TTF_GetFontStyle(this->font);
665  PRINTF(0)("The font style is:");
666  if(style==TTF_STYLE_NORMAL)
667    PRINTF(0)(" normal");
668  else {
669    if(style&TTF_STYLE_BOLD)
670      PRINTF(0)(" bold");
671    if(style&TTF_STYLE_ITALIC)
672      PRINTF(0)(" italic");
673    if(style&TTF_STYLE_UNDERLINE)
674      PRINTF(0)(" underline");
675  }
676  PRINTF(0)("\n");
677
678
679}
680
[3769]681////////////
682/// UTIL ///
683////////////
684/**
685   \brief Loads a Font from an SDL_surface into a texture.
686   \param surface The surface to make the texture of
687   \param texCoord The texture coordinates of the 4 corners of the texture
688   \returns the ID of the texture
689*/
690GLuint loadTexture(SDL_Surface *surface, TexCoord* texCoord)
691{
692  GLuint texture;
693  int w, h;
694  SDL_Surface *image;
695  SDL_Rect area;
696  Uint32 saved_flags;
697  Uint8  saved_alpha;
698 
699  /* Use the surface width and height expanded to powers of 2 */
700  w = powerOfTwo(surface->w);
701  h = powerOfTwo(surface->h);
702  if (texCoord)
703    {
704      texCoord->minU = 0.0f;
705      texCoord->minV = 0.0f;
706      texCoord->maxU = (GLfloat)surface->w / w;
707      texCoord->maxV = (GLfloat)surface->h / h;
708    }
709  image = SDL_CreateRGBSurface(SDL_SWSURFACE,
710                               w, h,
711                               32,
712#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
713                               0x000000FF, 
714                               0x0000FF00, 
715                               0x00FF0000, 
716                               0xFF000000
717#else
718                               0xFF000000,
719                               0x00FF0000, 
720                               0x0000FF00, 
721                               0x000000FF
722#endif
723                               );
724  if ( image == NULL ) {
725    return 0;
726  }
727 
728  /* Save the alpha blending attributes */
729  saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
730  saved_alpha = surface->format->alpha;
731  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
732    SDL_SetAlpha(surface, 0, 0);
733  }
734 
735  /* Copy the surface into the GL texture image */
736  area.x = 0;
737  area.y = 0;
738  area.w = surface->w;
739  area.h = surface->h;
740  SDL_BlitSurface(surface, &area, image, &area);
741 
742  /* Restore the alpha blending attributes */
743  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
744    SDL_SetAlpha(surface, saved_flags, saved_alpha);
745  }
746 
747  /* Create an OpenGL texture for the image */
748  glGenTextures(1, &texture);
749  glBindTexture(GL_TEXTURE_2D, texture);
750  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
751  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
752  glTexImage2D(GL_TEXTURE_2D,
753               0,
754               GL_RGBA,
755               w, h,
756               0,
757               GL_RGBA,
758               GL_UNSIGNED_BYTE,
759               image->pixels);
760  SDL_FreeSurface(image); /* No longer needed */
761 
762  return texture;
763}
[3766]764
[3769]765/**
766   \brief Quick utility function for texture creation
767   \param input an integer
768   \returns the next bigger 2^n-integer than input
769*/
770int powerOfTwo(int input)
771{
772  int value = 1;
773 
774  while ( value < input ) {
775    value <<= 1;
776  }
777  return value;
778}
[3766]779
780
781
782
783
784
[3768]785///////////////////
786/// TEXT-ENGINE ///
787///////////////////
[3766]788/**
[3655]789   \brief standard constructor
790*/
[3766]791TextEngine::TextEngine () 
[3655]792{
[3766]793   this->setClassName ("TextEngine");
[3769]794   this->enableFonts();
[3655]795
[3769]796   this->textList = new tList<Text>;
[3655]797}
798
799/**
800   \brief the singleton reference to this class
801*/
[3766]802TextEngine* TextEngine::singletonRef = NULL;
[3655]803
804/**
805   \returns a Pointer to this Class
806*/
[3766]807TextEngine* TextEngine::getInstance(void)
[3655]808{
[3766]809  if (!TextEngine::singletonRef)
810    TextEngine::singletonRef = new TextEngine();
811  return TextEngine::singletonRef;
[3655]812}
813
814/**
815   \brief standard deconstructor
816
817*/
[3766]818TextEngine::~TextEngine () 
[3655]819{
[3769]820  this->disableFonts();
821 
822  delete this->textList;
823
[3766]824  TextEngine::singletonRef = NULL;
[3655]825
826}
[3766]827
828/**
829   \brief function to enable TTF_Fonts
830*/
831void TextEngine::enableFonts(void)
832{
833  if (!TTF_WasInit())
834    {
835      if(TTF_Init()==-1)
836        PRINTF(1)("TTF_Init: %s\n", TTF_GetError());
837
838      TextEngine::checkVersion();
839    }
840  else
841    PRINTF(4)("Fonts already initialized\n");
842     
843}
844
845/**
846   \brief function to disable TTF_fonts
847*/
848void TextEngine::disableFonts(void)
849{
850  if (TTF_WasInit())
851    {
852      TTF_Quit();
853    }
854  else
855    PRINTF(4)("Fonts were not initialized.\n");
856}
857
858/**
[3769]859   \brief creates a new Text with a certain font.
860   \see Font::Font
861   \see Text::Text
862*/
863Text* TextEngine::createText(const char* fontFile, unsigned int fontSize, Uint8 r, Uint8 g, Uint8 b)
864{
865  Font* tmpFont;
866  Text* newText;
867
868  tmpFont = (Font*)ResourceManager::getInstance()->load(fontFile, TTF, RP_GAME);
869  if (!tmpFont)
870    {
871      PRINTF(2)("Font %s could not be loaded, probably file not found\n", fontFile);
872      return NULL;
873    }
874
875  newText = new Text(tmpFont, TEXT_DYNAMIC);
876}
877
878void TextEngine::draw(void)
879{
880  tIterator<Text>* textIterator = textList->getIterator();
881  Text* text = textIterator->nextElement();
882  while( text != NULL)
883    {
884      text->draw();
885      text = textIterator->nextElement();
886    }
887  delete textIterator;
888}
889
890/**
[3766]891   \brief checks if the compiled version and the local version of SDL_ttf match.
892   \returns true if match, false otherwise
893*/
894bool TextEngine::checkVersion(void)
895{
896  SDL_version compile_version;
897  SDL_version link_version;
898  TTF_VERSION(&compile_version);
899  link_version = *TTF_Linked_Version();
900
901  if (compile_version.major == link_version.major &&
902      compile_version.minor == link_version.minor &&
903      compile_version.patch == link_version.patch)
904    {
905      return true;
906    }
907  else
908    {
909      PRINTF(2)("compiled with SDL_ttf version: %d.%d.%d\n", 
910                compile_version.major,
911                compile_version.minor,
912                compile_version.patch);
913     
914      PRINTF(2)("running with SDL_ttf version: %d.%d.%d\n", 
915                link_version.major,
916                link_version.minor,
917                link_version.patch);
918      return false;
919    }
920}
Note: See TracBrowser for help on using the repository browser.