| 470 | //============================================================================================================= |
| 471 | |
| 472 | TextCache* Font::buildTextCache(const std::string& text, float offsetX, float offsetY, unsigned int color) |
| 473 | { |
| 474 | if(!textureID) |
| 475 | { |
| 476 | LOG(LogError) << "Error - tried to build TextCache with Font that has no texture loaded!"; |
| 477 | return NULL; |
| 478 | } |
| 479 | |
| 480 | const int triCount = text.length() * 2; |
| 481 | const int vertCount = triCount * 3; |
| 482 | TextCache::Vertex* vert = new TextCache::Vertex[vertCount]; |
| 483 | GLubyte* colors = new GLubyte[vertCount * 4]; |
| 484 | |
| 485 | //texture atlas width/height |
| 486 | float tw = (float)textureWidth; |
| 487 | float th = (float)textureHeight; |
| 488 | |
| 489 | float x = offsetX; |
| 490 | float y = offsetY + mMaxGlyphHeight * 1.1f * fontScale; //padding (another 0.5% is added to the bottom through the sizeText function) |
| 491 | |
| 492 | int charNum = 0; |
| 493 | for(int i = 0; i < vertCount; i += 6, charNum++) |
| 494 | { |
| 495 | unsigned char letter = text[charNum]; |
| 496 | |
| 497 | if(letter < 32 || letter >= 128) |
| 498 | letter = 127; //print [X] if character is not standard ASCII |
| 499 | |
| 500 | //the glyph might not start at the cursor position, but needs to be shifted a bit |
| 501 | const float glyphStartX = x + charData[letter].bearingX * fontScale; |
| 502 | //order is bottom left, top right, top left |
| 503 | vert[i + 0].pos << glyphStartX, y + (charData[letter].texH - charData[letter].bearingY) * fontScale; |
| 504 | vert[i + 1].pos << glyphStartX + charData[letter].texW * fontScale, y - charData[letter].bearingY * fontScale; |
| 505 | vert[i + 2].pos << glyphStartX, vert[i + 1].pos.y(); |
| 506 | |
| 507 | Eigen::Vector2i charTexCoord(charData[letter].texX, charData[letter].texY); |
| 508 | Eigen::Vector2i charTexSize(charData[letter].texW, charData[letter].texH); |
| 509 | |
| 510 | vert[i + 0].tex << charTexCoord.x() / tw, (charTexCoord.y() + charTexSize.y()) / th; |
| 511 | vert[i + 1].tex << (charTexCoord.x() + charTexSize.x()) / tw, charTexCoord.y() / th; |
| 512 | vert[i + 2].tex << vert[i + 0].tex.x(), vert[i + 1].tex.y(); |
| 513 | |
| 514 | //next triangle (second half of the quad) |
| 515 | vert[i + 3].pos = vert[i + 0].pos; |
| 516 | vert[i + 4].pos = vert[i + 1].pos; |
| 517 | vert[i + 5].pos[0] = vert[i + 1].pos.x(); |
| 518 | vert[i + 5].pos[1] = vert[i + 0].pos.y(); |
| 519 | |
| 520 | vert[i + 3].tex = vert[i + 0].tex; |
| 521 | vert[i + 4].tex = vert[i + 1].tex; |
| 522 | vert[i + 5].tex[0] = vert[i + 1].tex.x(); |
| 523 | vert[i + 5].tex[1] = vert[i + 0].tex.y(); |
| 524 | |
| 525 | x += charData[letter].advX * fontScale; |
| 526 | } |
| 527 | |
| 528 | TextCache* cache = new TextCache(vertCount, vert, colors, this); |
| 529 | if(color != 0x00000000) |