void Font::drawText(std::string text, int startx, int starty, int color) { if(!textureID) { LOG(LogError) << "Error - tried to draw with Font that has no texture loaded!"; return; } const int triCount = text.length() * 2; Vertex* vert = new Vertex[triCount * 3]; GLubyte* colors = new GLubyte[triCount * 3 * 4]; glBindTexture(GL_TEXTURE_2D, textureID); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //texture atlas width/height float tw = (float)textureWidth; float th = (float)textureHeight; float x = (float)startx; float y = starty + mMaxGlyphHeight * 1.1f * fontScale; //padding (another 0.5% is added to the bottom through the sizeText function) int charNum = 0; for(int i = 0; i < triCount * 3; i += 6, charNum++) { unsigned char letter = text[charNum]; if(letter < 32 || letter >= 128) letter = 127; //print [X] if character is not standard ASCII //order is bottom left, top right, top left vert[i + 0].pos = Vector2<GLfloat>(x, y + (charData[letter].texH - charData[letter].bearingY) * fontScale); vert[i + 1].pos = Vector2<GLfloat>(x + charData[letter].texW * fontScale, y - charData[letter].bearingY * fontScale); vert[i + 2].pos = Vector2<GLfloat>(x, vert[i + 1].pos.y); Vector2<int> charTexCoord(charData[letter].texX, charData[letter].texY); Vector2<int> charTexSize(charData[letter].texW, charData[letter].texH); vert[i + 0].tex = Vector2<GLfloat>(charTexCoord.x / tw, (charTexCoord.y + charTexSize.y) / th); vert[i + 1].tex = Vector2<GLfloat>((charTexCoord.x + charTexSize.x) / tw, charTexCoord.y / th); vert[i + 2].tex = Vector2<GLfloat>(vert[i + 0].tex.x, vert[i + 1].tex.y); //next triangle (second half of the quad) vert[i + 3].pos = vert[i + 0].pos; vert[i + 4].pos = vert[i + 1].pos; vert[i + 5].pos.x = vert[i + 1].pos.x; vert[i + 5].pos.y = vert[i + 0].pos.y; vert[i + 3].tex = vert[i + 0].tex; vert[i + 4].tex = vert[i + 1].tex; vert[i + 5].tex.x = vert[i + 1].tex.x; vert[i + 5].tex.y = vert[i + 0].tex.y; x += charData[letter].advX * fontScale; } Renderer::buildGLColorArray(colors, color, triCount * 3); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &vert[0].pos); glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &vert[0].tex); glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors); glDrawArrays(GL_TRIANGLES, 0, triCount * 3); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisable(GL_TEXTURE_2D); glDisable(GL_BLEND); delete[] vert; delete[] colors; }
TextCache* Font::buildTextCache(const std::string& text, float offsetX, float offsetY, unsigned int color) { if(!textureID) { LOG(LogError) << "Error - tried to build TextCache with Font that has no texture loaded!"; return NULL; } const int triCount = text.length() * 2; const int vertCount = triCount * 3; TextCache::Vertex* vert = new TextCache::Vertex[vertCount]; GLubyte* colors = new GLubyte[vertCount * 4]; //texture atlas width/height float tw = (float)textureWidth; float th = (float)textureHeight; float x = offsetX; float y = offsetY + mMaxGlyphHeight * 1.1f * fontScale; //padding (another 0.5% is added to the bottom through the sizeText function) int charNum = 0; for(int i = 0; i < vertCount; i += 6, charNum++) { unsigned char letter = text[charNum]; if(letter < 32 || letter >= 128) letter = 127; //print [X] if character is not standard ASCII //the glyph might not start at the cursor position, but needs to be shifted a bit const float glyphStartX = x + charData[letter].bearingX * fontScale; //order is bottom left, top right, top left vert[i + 0].pos << glyphStartX, y + (charData[letter].texH - charData[letter].bearingY) * fontScale; vert[i + 1].pos << glyphStartX + charData[letter].texW * fontScale, y - charData[letter].bearingY * fontScale; vert[i + 2].pos << glyphStartX, vert[i + 1].pos.y(); Eigen::Vector2i charTexCoord(charData[letter].texX, charData[letter].texY); Eigen::Vector2i charTexSize(charData[letter].texW, charData[letter].texH); vert[i + 0].tex << charTexCoord.x() / tw, (charTexCoord.y() + charTexSize.y()) / th; vert[i + 1].tex << (charTexCoord.x() + charTexSize.x()) / tw, charTexCoord.y() / th; vert[i + 2].tex << vert[i + 0].tex.x(), vert[i + 1].tex.y(); //next triangle (second half of the quad) vert[i + 3].pos = vert[i + 0].pos; vert[i + 4].pos = vert[i + 1].pos; vert[i + 5].pos[0] = vert[i + 1].pos.x(); vert[i + 5].pos[1] = vert[i + 0].pos.y(); vert[i + 3].tex = vert[i + 0].tex; vert[i + 4].tex = vert[i + 1].tex; vert[i + 5].tex[0] = vert[i + 1].tex.x(); vert[i + 5].tex[1] = vert[i + 0].tex.y(); x += charData[letter].advX * fontScale; } TextCache* cache = new TextCache(vertCount, vert, colors, this); if(color != 0x00000000) cache->setColor(color); return cache; }