Changeset 4597 in orxonox.OLD for orxonox/trunk/src/lib/graphics/text_engine.cc
- Timestamp:
- Jun 11, 2005, 12:55:48 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
orxonox/trunk/src/lib/graphics/text_engine.cc
r4537 r4597 1 /* 1 /* 2 2 orxonox - the future of 3D-vertical-scrollers 3 3 … … 16 16 17 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 18 adding them to orxonox. This is really important, because we do not 19 19 want to offend anyone. 20 20 */ … … 46 46 \param type The renderType to display this font in 47 47 48 this constructor is private, because the user should initialize 48 this constructor is private, because the user should initialize 49 49 a text with the TextEngine. 50 50 */ … … 68 68 /** 69 69 \brief deletes a Text out of memory 70 70 71 71 This also ereases the text from the textList of the TextEngine 72 72 */ … … 117 117 char* tmpText = this->text; 118 118 while (*tmpText != '\0') 119 120 121 122 123 124 125 119 { 120 if(glyphArray[*tmpText]) 121 { 122 width += glyphArray[*tmpText]->width; 123 } 124 tmpText++; 125 } 126 126 this->posSize.w = width; 127 127 } … … 174 174 if (likely(this->font != NULL)) 175 175 tmpSurf = TTF_RenderText_Blended(this->font->font, 176 177 176 this->text, 177 this->color); 178 178 if (tmpSurf) 179 179 this->texture = loadTexture(tmpSurf, &this->texCoord); … … 208 208 pos.z = tmp[2]; 209 209 } 210 else 210 else 211 211 { 212 212 pos.x = this->posSize.x; … … 232 232 glEnable(GL_TEXTURE_2D); 233 233 glBegin(GL_QUADS); 234 234 235 235 glTexCoord2f(this->texCoord.minU, this->texCoord.minV); 236 236 glVertex2f(pos.x, pos.y ); 237 237 238 238 glTexCoord2f(this->texCoord.maxU, this->texCoord.minV); 239 239 glVertex2f(pos.x + this->posSize.w, pos.y ); 240 240 241 241 glTexCoord2f(this->texCoord.maxU, this->texCoord.maxV); 242 242 glVertex2f(pos.x + this->posSize.w, pos.y + this->posSize.h); 243 243 244 244 glTexCoord2f(this->texCoord.minU, this->texCoord.maxV); 245 245 glVertex2f(pos.x, pos.y + this->posSize.h); 246 246 247 247 glEnd(); 248 248 } … … 257 257 char* tmpText = this->text; 258 258 while (*tmpText != '\0') 259 260 261 262 263 264 265 266 259 { 260 if(glyphArray[*tmpText]) 261 { 262 glCallList(glyphArray[*tmpText]->displayList); 263 glTranslatef(glyphArray[*tmpText]->width, 0, 0); 264 } 265 tmpText++; 266 } 267 267 } 268 268 glPopMatrix(); … … 299 299 Uint32 saved_flags; 300 300 Uint8 saved_alpha; 301 301 302 302 /* Use the surface width and height expanded to powers of 2 */ 303 303 w = powerOfTwo(surface->w); … … 311 311 } 312 312 image = SDL_CreateRGBSurface(SDL_SWSURFACE, 313 314 313 w, h, 314 32, 315 315 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ 316 0x000000FF, 317 0x0000FF00, 318 0x00FF0000, 319 316 0x000000FF, 317 0x0000FF00, 318 0x00FF0000, 319 0xFF000000 320 320 #else 321 322 0x00FF0000, 323 0x0000FF00, 324 321 0xFF000000, 322 0x00FF0000, 323 0x0000FF00, 324 0x000000FF 325 325 #endif 326 326 ); 327 327 if ( image == NULL ) { 328 328 return 0; 329 329 } 330 330 331 331 /* Save the alpha blending attributes */ 332 332 saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK); … … 335 335 SDL_SetAlpha(surface, 0, 0); 336 336 } 337 337 338 338 /* Copy the surface into the GL texture image */ 339 339 area.x = 0; … … 342 342 area.h = surface->h; 343 343 SDL_BlitSurface(surface, &area, image, &area); 344 344 345 345 /* Restore the alpha blending attributes */ 346 346 if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { 347 347 SDL_SetAlpha(surface, saved_flags, saved_alpha); 348 348 } 349 349 350 350 /* Create an OpenGL texture for the image */ 351 351 glGenTextures(1, &texture); … … 354 354 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 355 355 glTexImage2D(GL_TEXTURE_2D, 356 357 358 359 360 361 362 356 0, 357 GL_RGBA, 358 w, h, 359 0, 360 GL_RGBA, 361 GL_UNSIGNED_BYTE, 362 image->pixels); 363 363 SDL_FreeSurface(image); /* No longer needed */ 364 364 365 365 return texture; 366 366 } 367 367 368 368 /** 369 \brief Quick utility function for texture creation 369 \brief Quick utility function for texture creation 370 370 \param input an integer 371 371 \returns the next bigger 2^n-integer than input … … 374 374 { 375 375 int value = 1; 376 376 377 377 while ( value < input ) { 378 378 value <<= 1; … … 395 395 Font::Font(const char* fontFile, unsigned int fontSize, Uint8 r, Uint8 g, Uint8 b) 396 396 { 397 this->setClassID(CL_FONT, "Font"); 397 398 // setting default values. 398 399 this->font = NULL; 399 400 this->fontFile = NULL; 400 401 this->glyphArray = NULL; 401 this->fastTextureID = 0; 402 402 this->fastTextureID = 0; 403 403 404 this->setSize(fontSize); 404 405 … … 423 424 { 424 425 for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++) 425 426 delete this->glyphArray[i]; 426 427 delete []this->glyphArray; 427 428 } … … 441 442 if (!this->fontFile) 442 443 { 444 this->setName(fontFile); 443 445 this->fontFile = new char[strlen(fontFile)+1]; 444 446 strcpy(this->fontFile, fontFile); 445 447 446 448 this->font = TTF_OpenFont(this->fontFile, this->fontSize); 447 449 if(!this->font) 448 449 450 451 450 { 451 PRINTF(1)("TTF_OpenFont: %s\n", TTF_GetError()); 452 return false; 453 } 452 454 else 453 455 return true; 454 456 } 455 457 else … … 468 470 { 469 471 this->renderStyle = TTF_STYLE_NORMAL; 470 472 471 473 for (int i = 0; i < strlen(renderStyle); i++) 472 if (strncmp(renderStyle+i, "b", 1) == 0) 474 if (strncmp(renderStyle+i, "b", 1) == 0) 473 475 this->renderStyle |= TTF_STYLE_BOLD; 474 476 else if (strncmp(renderStyle+i, "i", 1) == 0) 475 477 this->renderStyle |= TTF_STYLE_ITALIC; 476 else if (strncmp(renderStyle+i, "u", 1) == 0) 478 else if (strncmp(renderStyle+i, "u", 1) == 0) 477 479 this->renderStyle |= TTF_STYLE_UNDERLINE; 478 480 … … 547 549 and MUST be deleted by the user.. 548 550 549 This only works for horizontal fonts. see 551 This only works for horizontal fonts. see 550 552 http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html 551 553 for more info about vertical Fonts … … 557 559 if (likely (this->font!= NULL)) 558 560 TTF_GlyphMetrics(this->font, rg->character, 559 560 561 561 &rg->minX, &rg->maxX, 562 &rg->minY, &rg->maxY, 563 &rg->advance); 562 564 rg->height = rg->maxY - rg->minY; 563 565 rg->width = rg->maxX - rg->minX; … … 569 571 GLuint Font::createFastTexture(void) 570 572 { 571 /* interesting GLYPHS: 573 /* interesting GLYPHS: 572 574 * 32: space 573 575 * 33-47: Special Characters. … … 589 591 SDL_Rect tmpRect; // this represents a Rectangle for blitting. 590 592 SDL_Surface* tmpSurf = SDL_CreateRGBSurface(SDL_SWSURFACE, 591 592 593 rectSize, rectSize, 594 32, 593 595 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ 594 0x000000FF, 595 0x0000FF00, 596 0x00FF0000, 597 596 0x000000FF, 597 0x0000FF00, 598 0x00FF0000, 599 0xFF000000 598 600 #else 599 600 0x00FF0000, 601 0x0000FF00, 602 601 0xFF000000, 602 0x00FF0000, 603 0x0000FF00, 604 0x000000FF 603 605 #endif 604 606 ); 605 607 tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h; 606 608 SDL_SetClipRect(tmpSurf, &tmpRect); … … 614 616 615 617 if (tmpGlyph = this->glyphArray[i]) 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 618 { 619 if (tmpGlyph->height > maxLineHeight) 620 maxLineHeight = tmpGlyph->height; 621 622 if (tmpRect.x+tmpGlyph->width > tmpSurf->w) 623 { 624 tmpRect.x = 0; 625 tmpRect.y = tmpRect.y + maxLineHeight + 1; 626 maxLineHeight = 0; 627 } 628 if (tmpRect.y + maxLineHeight > tmpSurf->h) 629 { 630 PRINTF(1)("Protection, so font cannot write over the boundraries error (this should not heappen\n"); 631 break; 632 } 633 // reading in the new Glyph 634 if (likely(this->font != NULL)) 635 glyphSurf = TTF_RenderGlyph_Blended(this->font, i, this->fastColor); 636 if( glyphSurf != NULL ) 637 { 638 639 SDL_SetAlpha(glyphSurf, 0, 0); 640 641 SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect); 642 TexCoord tmpTexCoord; 643 tmpTexCoord.minU = (float)tmpRect.x/(float)tmpSurf->w; 644 tmpTexCoord.maxU = (float)(tmpRect.x+tmpGlyph->width)/(float)tmpSurf->w; 645 tmpTexCoord.minV = (float)tmpRect.y/(float)tmpSurf->w; 646 tmpTexCoord.maxV = (float)(tmpRect.y+tmpGlyph->height)/(float)tmpSurf->w; 647 tmpGlyph->displayList = glGenLists(1); 648 649 glNewList(tmpGlyph->displayList, GL_COMPILE); 650 glBegin(GL_QUADS); 651 glTexCoord2f(tmpTexCoord.minU, tmpTexCoord.minV); 652 glVertex2d(0, 0); 653 glTexCoord2f(tmpTexCoord.minU, tmpTexCoord.maxV); 654 glVertex2d(0, tmpGlyph->height); 655 glTexCoord2f(tmpTexCoord.maxU, tmpTexCoord.maxV); 656 glVertex2d(tmpGlyph->width, tmpGlyph->height); 657 glTexCoord2f(tmpTexCoord.maxU, tmpTexCoord.minV); 658 glVertex2d(tmpGlyph->width, 0); 659 glEnd(); 660 glEndList(); 661 SDL_FreeSurface(glyphSurf); 662 663 tmpRect.x += tmpGlyph->width + 1; 664 665 // Outputting Glyphs to BMP-files. 666 /* 667 char outname[64]; 668 if (i < 10) 669 sprintf( outname, "glyph-00%d.bmp", i ); 670 else if (i <100) 671 sprintf( outname, "glyph-0%d.bmp", i ); 672 else 673 sprintf( outname, "glyph-%d.bmp", i ); 674 SDL_SaveBMP(tmpSurf, outname); 675 */ 676 } 677 } 676 678 } 677 679 … … 682 684 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 683 685 glTexImage2D(GL_TEXTURE_2D, 684 685 686 687 688 689 690 686 0, 687 GL_RGBA, 688 tmpSurf->w, tmpSurf->h, 689 0, 690 GL_RGBA, 691 GL_UNSIGNED_BYTE, 692 tmpSurf->pixels); 691 693 SDL_FreeSurface(tmpSurf); 692 694 return texture; … … 707 709 this->glyphArray = new Glyph*[FONT_HIGHEST_KNOWN_CHAR]; 708 710 for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++) 709 710 } 711 711 this->glyphArray[i] = NULL; 712 } 713 712 714 Uint16 lastGlyph = from + count; 713 715 714 716 for (int i = from; i <= lastGlyph; i++) 715 717 { … … 723 725 \returns the optimal size to use as the texture size 724 726 725 \todo: this algorithm can be a lot more faster, althought it does 727 \todo: this algorithm can be a lot more faster, althought it does 726 728 not really matter within the init-context, and 128 glyphs. 727 729 728 This function searches for a 2^n sizes texture-size, this is for 730 This function searches for a 2^n sizes texture-size, this is for 729 731 openGL-version < 1.2 compatibility ( and because it is realy easy like this :)) 730 732 */ … … 743 745 maxLineHeight = 0; 744 746 for (i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++) 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 747 { 748 if(tmpGlyph = this->glyphArray[i]) 749 { 750 // getting the height of the highest Glyph in the Line. 751 if (tmpGlyph->height > maxLineHeight) 752 maxLineHeight = tmpGlyph->height; 753 754 if (x + tmpGlyph->width > size) 755 { 756 x = 0; 757 y = y + maxLineHeight; 758 maxLineHeight = 0; 759 } 760 if (y + maxLineHeight + 1 > size) 761 break; 762 x += tmpGlyph->width + 1; 763 764 } 765 } 764 766 if (i == FONT_HIGHEST_KNOWN_CHAR) 765 767 sizeOK = true; 766 768 else 767 769 size *= 2; 768 770 } 769 771 return size; … … 801 803 \brief standard constructor 802 804 */ 803 TextEngine::TextEngine () 805 TextEngine::TextEngine () 804 806 { 805 807 this->setClassID(CL_TEXT_ENGINE, "TextEngine"); 808 this->setName("TextEngine"); 806 809 this->enableFonts(); 807 810 … … 818 821 819 822 */ 820 TextEngine::~TextEngine () 823 TextEngine::~TextEngine () 821 824 { 822 825 this->disableFonts(); 823 826 824 827 delete this->textList; 825 828 … … 835 838 { 836 839 if(TTF_Init()==-1) 837 840 PRINTF(1)("TTF_Init: %s\n", TTF_GetError()); 838 841 839 842 TextEngine::checkVersion(); … … 932 935 /** 933 936 \brief outputs some nice Debug information 934 937 935 938 \todo there should also be something outputted about Font 936 939 */ … … 941 944 PRINT(0)("+-------------------------------+\n"); 942 945 PRINT(0)("Reference: %p; Text Counts: %d\n", this, this->textList->getSize()); 943 946 944 947 tIterator<Text>* textIterator = textList->getIterator(); 945 948 Text* text = textIterator->nextElement(); … … 973 976 else 974 977 { 975 PRINTF(2)("compiled with SDL_ttf version: %d.%d.%d\n", 976 977 978 979 980 PRINTF(2)("running with SDL_ttf version: %d.%d.%d\n", 981 982 983 978 PRINTF(2)("compiled with SDL_ttf version: %d.%d.%d\n", 979 compile_version.major, 980 compile_version.minor, 981 compile_version.patch); 982 983 PRINTF(2)("running with SDL_ttf version: %d.%d.%d\n", 984 link_version.major, 985 link_version.minor, 986 link_version.patch); 984 987 return false; 985 988 }
Note: See TracChangeset
for help on using the changeset viewer.