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