Changeset 5343 in orxonox.OLD for trunk/src/lib/graphics/text_engine/text.cc
- Timestamp:
- Oct 10, 2005, 12:16:19 AM (19 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/graphics/text_engine/text.cc
r5330 r5343 10 10 11 11 ### File Specific: 12 main-programmer: ...12 main-programmer: Benjamin Grauer 13 13 co-programmer: ... 14 14 */ 15 15 16 //#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ 17 18 #include "proto_class.h" 16 #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_FONT 17 18 #include "text.h" 19 #include "font.h" 20 21 #include "graphics_engine.h" 22 #include "resource_manager.h" 23 #include "class_list.h" 24 #include "debug.h" 25 #include "p_node.h" 19 26 20 27 using namespace std; 21 28 22 23 /** 24 * standard constructor 25 * @todo this constructor is not jet implemented - do it 26 */ 27 ProtoClass::ProtoClass () 28 { 29 this->setClassID(CL_PROTO_ID, "ProtoClass"); 30 31 /* If you make a new class, what is most probably the case when you write this file 32 don't forget to: 33 1. Add the new file new_class.cc to the ./src/Makefile.am 34 2. Add the class identifier to ./src/class_id.h eg. CL_NEW_CLASS 35 36 Advanced Topics: 37 - if you want to let your object be managed via the ObjectManager make sure to read 38 the object_manager.h header comments. You will use this most certanly only if you 39 make many objects of your class, like a weapon bullet. 40 */ 41 } 42 43 44 /** 45 * standard deconstructor 46 */ 47 ProtoClass::~ProtoClass () 48 { 49 // delete what has to be deleted here 50 } 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 */ 34 Text::Text(const char* fontFile, unsigned int fontSize, TEXT_RENDER_TYPE type) 35 { 36 this->init(); 37 38 if (fontFile != NULL) 39 this->setFont(fontFile, fontSize); 40 this->setType(type); 41 } 42 43 /** 44 * creates a new Text Element 45 * @param font the Font to render this text in 46 * @param type The renderType to display this font in 47 * 48 * this constructor is private, because the user should initialize 49 * a text with the TextEngine. 50 */ 51 Text::Text(Font* font, TEXT_RENDER_TYPE type) 52 { 53 this->init(); 54 55 this->font = font; 56 this->setType(type); 57 } 58 59 /** 60 * deletes a Text out of memory 61 * 62 * This also ereases the text from the textList of the TextEngine 63 */ 64 Text::~Text() 65 { 66 if (this->font != NULL) 67 ResourceManager::getInstance()->unload(this->font); 68 69 if (this->text) 70 delete[] this->text; 71 } 72 73 void Text::init() 74 { 75 this->setClassID(CL_TEXT, "Text"); 76 77 // initialize this Text 78 this->font = NULL; 79 this->text = NULL; 80 this->externText = NULL; 81 this->setAlignment(TEXT_DEFAULT_ALIGNMENT); 82 this->texture = 0; 83 this->blending = TEXT_DEFAULT_BLENDING; 84 this->color = TEXT_DEFAULT_COLOR; 85 this->setType(TEXT_RENDER_DYNAMIC); 86 87 this->setText(NULL); 88 } 89 90 /** 91 * sets the Font of this Text to font 92 * @param font the Font (normaly from the ResourceManager) to allocate to this Text 93 */ 94 void Text::setFont(Font* font) 95 { 96 if (this->font != NULL) 97 ResourceManager::getInstance()->unload(this->font); 98 this->font = font; 99 } 100 101 /** 102 * sets the Font of this Text to font from fontFile 103 * @param fontFile the File to load the Font from. 104 * @param fontSize the Size of the Font 105 */ 106 void Text::setFont(const char* fontFile, unsigned int fontSize) 107 { 108 Font* tmpFont; 109 Text* newText; 110 Vector tmpVec; 111 112 tmpFont = (Font*)ResourceManager::getInstance()->load(fontFile, TTF, RP_GAME, &fontSize); 113 if (tmpFont == NULL) 114 { 115 PRINTF(2)("Font %s could not be loaded, probably file not found\n", fontFile); 116 this->setFont(NULL); 117 } 118 else 119 this->setFont(tmpFont); 120 } 121 122 /** 123 * sets the Type of this Text 124 * @param type the type to set. 125 */ 126 void Text::setType(TEXT_RENDER_TYPE type) 127 { 128 if (this->font != NULL && this->font->font) 129 this->type = type; 130 else 131 this->type = TEXT_RENDER_DYNAMIC; 132 } 133 134 /** 135 * Sets a new Text to the font 136 * @param text the new text to set 137 */ 138 void Text::setText(const char* text, bool isExtern) 139 { 140 if (isExtern) 141 { 142 this->externText = text; 143 144 if (unlikely(this->text != NULL)) 145 { 146 delete[] this->text; 147 this->text = NULL; 148 } 149 } 150 else 151 { 152 this->externText = NULL; 153 if (this->text) 154 delete[] this->text; 155 if (text != NULL) 156 { 157 this->text = new char[strlen(text)+1]; 158 strcpy(this->text, text); 159 } 160 else 161 this->text = NULL; 162 } 163 164 // setting up the Text-Width if DYNAMIC 165 if (this->type & TEXT_RENDER_DYNAMIC && this->getAlignment() != TEXT_ALIGN_LEFT && this->font != NULL) 166 { 167 Glyph** glyphArray = this->font->getGlyphArray(); 168 169 int width = 0; 170 const char* tmpText = this->externText; 171 if (this->externText == NULL) 172 tmpText = this->text; 173 if (tmpText != NULL) 174 { 175 while (*tmpText != '\0') 176 { 177 if(glyphArray[*tmpText]) 178 { 179 width += glyphArray[*tmpText]->width; 180 } 181 tmpText++; 182 } 183 this->width = width; 184 } 185 } 186 } 187 188 /** 189 * creates a texture out of the given parameters 190 191 this has to be called every time by the user, to if changes were made. 192 this is only for TEXT_STATIC-mode 193 */ 194 void Text::createTexture() 195 { 196 SDL_Surface* tmpSurf; 197 if (this->texture) 198 glDeleteTextures(1, &this->texture); 199 if (likely(this->font != NULL)) 200 { 201 SDL_Color theColor = { (int)(this->color.x*255), (int)(this->color.y*255), (int)(this->color.z*255) }; 202 tmpSurf = TTF_RenderText_Blended(this->font->font, 203 this->text, 204 theColor); 205 } 206 if (tmpSurf) 207 this->texture = loadTexture(tmpSurf, &this->texCoord); 208 209 this->width = tmpSurf->w; 210 this->height = tmpSurf->h; 211 SDL_FreeSurface(tmpSurf); 212 } 213 214 /** 215 * draws the Text 216 */ 217 void Text::draw() const 218 { 219 glPushMatrix(); 220 // transform for alignment. 221 if (this->getAlignment() == TEXT_ALIGN_RIGHT) 222 glTranslatef(-this->width, 0, 0); 223 else if (this->getAlignment() == TEXT_ALIGN_CENTER || this->getAlignment() == TEXT_ALIGN_SCREEN_CENTER) 224 glTranslatef(-this->width/2, 0, 0); 225 226 // drawing this Text. 227 // setting the Blending effects 228 glColor4f(this->color.x, this->color.y, this->color.z, this->blending); 229 glEnable(GL_BLEND); 230 glEnable(GL_TEXTURE_2D); 231 glBlendFunc(GL_SRC_ALPHA, GL_ONE); 232 233 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, GL_MODULATE ); 234 235 if(likely(type & TEXT_RENDER_DYNAMIC )) 236 { 237 Glyph** glyphArray; 238 if (likely (this->font != NULL)) 239 { 240 glyphArray = this->font->getGlyphArray(); 241 glBindTexture(GL_TEXTURE_2D, font->getFastTextureID()); 242 } 243 else 244 { 245 if (unlikely(Font::getDefaultFont() == NULL)) 246 Font::initDefaultFont(); 247 glyphArray = Font::getDefaultFont()->getGlyphArray(); 248 glBindTexture(GL_TEXTURE_2D, Font::getDefaultFont()->getFastTextureID()); 249 } 250 glTranslatef(getAbsCoor2D().x, getAbsCoor2D().y, 0); 251 // glRotatef(this->getAbsDir2D(), 0,0,1); 252 const char* tmpText = this->externText; 253 if (this->externText == NULL) 254 tmpText = this->text; 255 if (likely(tmpText != NULL)) 256 { 257 while (likely(*tmpText != '\0')) 258 { 259 if(likely(glyphArray[*tmpText] != NULL)) 260 { 261 glCallList(glyphArray[*tmpText]->displayList); 262 glTranslatef(glyphArray[*tmpText]->width, 0, 0); 263 } 264 tmpText++; 265 } 266 } 267 } 268 else //(if type & TEXT_RENDER_STATIC) 269 { 270 glBindTexture(GL_TEXTURE_2D, this->texture); 271 glBegin(GL_QUADS); 272 273 glTexCoord2f(this->texCoord.minU, this->texCoord.minV); 274 glVertex2f(this->getAbsCoor2D().x, this->getAbsCoor2D().y ); 275 276 glTexCoord2f(this->texCoord.maxU, this->texCoord.minV); 277 glVertex2f(this->getAbsCoor2D().x + this->width, this->getAbsCoor2D().y ); 278 279 glTexCoord2f(this->texCoord.maxU, this->texCoord.maxV); 280 glVertex2f(this->getAbsCoor2D().x + this->width, getAbsCoor2D().y + this->height); 281 282 glTexCoord2f(this->texCoord.minU, this->texCoord.maxV); 283 glVertex2f(getAbsCoor2D().x, getAbsCoor2D().y + this->height); 284 285 glEnd(); 286 287 } 288 glPopMatrix(); 289 } 290 291 /** 292 * prints out some nice debug information about this text 293 */ 294 void Text::debug() const 295 { 296 if (this->externText == NULL) 297 PRINT(0)("=== TEXT: %s ===\n", this->text); 298 else 299 PRINT(0)("=== TEXT: %s ===\n", this->externText); 300 301 if (this->getBindNode()) 302 PRINT(0)("is bind to %s; ref=%p\n", this->getBindNode()->getName(), this->getBindNode()); 303 PRINT(0)("Color: %0.2f %0.2f %0.2f\n", this->color.x, this->color.y, this->color.z); 304 } 305 306 307 //////////// 308 /// UTIL /// 309 //////////// 310 /** 311 * Loads a Font from an SDL_surface into a texture. 312 * @param surface The surface to make the texture of 313 * @param texCoord The texture coordinates of the 4 corners of the texture 314 * @returns the ID of the texture 315 */ 316 GLuint Text::loadTexture(SDL_Surface *surface, TexCoord* texCoord) 317 { 318 GLuint texture; 319 int w, h; 320 SDL_Surface *image; 321 SDL_Rect area; 322 Uint32 saved_flags; 323 Uint8 saved_alpha; 324 325 /* Use the surface width and height expanded to powers of 2 */ 326 w = powerOfTwo(surface->w); 327 h = powerOfTwo(surface->h); 328 if (texCoord != NULL) 329 { 330 texCoord->minU = 0.0f; 331 texCoord->minV = 0.0f; 332 texCoord->maxU = (GLfloat)surface->w / w; 333 texCoord->maxV = (GLfloat)surface->h / h; 334 } 335 image = SDL_CreateRGBSurface(SDL_SWSURFACE, 336 w, h, 337 32, 338 #if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */ 339 0x000000FF, 340 0x0000FF00, 341 0x00FF0000, 342 0xFF000000 343 #else 344 0xFF000000, 345 0x00FF0000, 346 0x0000FF00, 347 0x000000FF 348 #endif 349 ); 350 if ( image == NULL ) { 351 return 0; 352 } 353 354 /* Save the alpha blending attributes */ 355 saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK); 356 saved_alpha = surface->format->alpha; 357 if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { 358 SDL_SetAlpha(surface, 0, 0); 359 } 360 361 /* Copy the surface into the GL texture image */ 362 area.x = 0; 363 area.y = 0; 364 area.w = surface->w; 365 area.h = surface->h; 366 SDL_BlitSurface(surface, &area, image, &area); 367 368 /* Restore the alpha blending attributes */ 369 if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { 370 SDL_SetAlpha(surface, saved_flags, saved_alpha); 371 } 372 373 /* Create an OpenGL texture for the image */ 374 glGenTextures(1, &texture); 375 glBindTexture(GL_TEXTURE_2D, texture); 376 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 377 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 378 glTexImage2D(GL_TEXTURE_2D, 379 0, 380 GL_RGBA, 381 w, h, 382 0, 383 GL_RGBA, 384 GL_UNSIGNED_BYTE, 385 image->pixels); 386 SDL_FreeSurface(image); /* No longer needed the data */ 387 388 return texture; 389 } 390 391 /** 392 * Quick utility function for texture creation 393 * @param input an integer 394 * @returns the next bigger 2^n-integer than input 395 */ 396 int Text::powerOfTwo(int input) 397 { 398 int value = 1; 399 400 while ( value < input ) 401 value <<= 1; 402 return value; 403 }
Note: See TracChangeset
for help on using the changeset viewer.