This commit is contained in:
Sir_Leon 2013-07-02 17:01:28 +02:00
commit be86423712
3 changed files with 124 additions and 54 deletions

View file

@ -5,7 +5,6 @@
#include "Renderer.h" #include "Renderer.h"
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include "Log.h" #include "Log.h"
#include "Vector2.h"
FT_Library Font::sLibrary; FT_Library Font::sLibrary;
bool Font::libraryInitialized = false; bool Font::libraryInitialized = false;
@ -220,13 +219,14 @@ Font::~Font()
} }
struct Vertex
{
Vector2<GLfloat> pos;
Vector2<GLfloat> tex;
};
void Font::drawText(std::string text, int startx, int starty, int color) void Font::drawText(std::string text, int startx, int starty, int color)
{
TextCache* cache = buildTextCache(text, startx, starty, color);
renderTextCache(cache);
delete cache;
}
void Font::renderTextCache(TextCache* cache)
{ {
if(!textureID) if(!textureID)
{ {
@ -234,24 +234,92 @@ void Font::drawText(std::string text, int startx, int starty, int color)
return; return;
} }
const int triCount = text.length() * 2; if(cache == NULL)
Vertex* vert = new Vertex[triCount * 3]; {
GLubyte* colors = new GLubyte[triCount * 3 * 4]; LOG(LogError) << "Attempted to draw NULL TextCache!";
return;
}
if(cache->sourceFont != this)
{
LOG(LogError) << "Attempted to draw TextCache with font other than its source!";
return;
}
glBindTexture(GL_TEXTURE_2D, textureID); glBindTexture(GL_TEXTURE_2D, textureID);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(2, GL_FLOAT, sizeof(TextCache::Vertex), &cache->verts[0].pos);
glTexCoordPointer(2, GL_FLOAT, sizeof(TextCache::Vertex), &cache->verts[0].tex);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, cache->colors);
glDrawArrays(GL_TRIANGLES, 0, cache->vertCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
}
void Font::sizeText(std::string text, int* w, int* h)
{
float cwidth = 0.0f;
for(unsigned int i = 0; i < text.length(); i++)
{
unsigned char letter = text[i];
if(letter < 32 || letter >= 128)
letter = 127;
cwidth += charData[letter].advX * fontScale;
}
if(w != NULL)
*w = (int)cwidth;
if(h != NULL)
*h = getHeight();
}
int Font::getHeight()
{
return (int)(mMaxGlyphHeight * 1.5f * fontScale);
}
//=============================================================================================================
//TextCache
//=============================================================================================================
TextCache* Font::buildTextCache(const std::string& text, int offsetX, int 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 //texture atlas width/height
float tw = (float)textureWidth; float tw = (float)textureWidth;
float th = (float)textureHeight; float th = (float)textureHeight;
float x = (float)startx; float x = (float)offsetX;
float y = starty + mMaxGlyphHeight * 1.1f * fontScale; //padding (another 0.5% is added to the bottom through the sizeText function) float y = offsetY + mMaxGlyphHeight * 1.1f * fontScale; //padding (another 0.5% is added to the bottom through the sizeText function)
int charNum = 0; int charNum = 0;
for(int i = 0; i < triCount * 3; i += 6, charNum++) for(int i = 0; i < vertCount; i += 6, charNum++)
{ {
unsigned char letter = text[charNum]; unsigned char letter = text[charNum];
@ -286,49 +354,24 @@ void Font::drawText(std::string text, int startx, int starty, int color)
x += charData[letter].advX * fontScale; x += charData[letter].advX * fontScale;
} }
Renderer::buildGLColorArray(colors, color, triCount * 3); TextCache* cache = new TextCache(vertCount, vert, colors, this);
if(color != 0x00000000)
cache->setColor(color);
glEnableClientState(GL_VERTEX_ARRAY); return cache;
glEnableClientState(GL_TEXTURE_COORD_ARRAY); }
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(2, GL_FLOAT, sizeof(Vertex), &vert[0].pos); TextCache::TextCache(int verts, Vertex* v, GLubyte* c, Font* f) : vertCount(verts), verts(v), colors(c), sourceFont(f)
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &vert[0].tex); {
glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors); }
glDrawArrays(GL_TRIANGLES, 0, triCount * 3); TextCache::~TextCache()
{
glDisableClientState(GL_VERTEX_ARRAY); delete[] verts;
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisable(GL_TEXTURE_2D);
glDisable(GL_BLEND);
delete[] vert;
delete[] colors; delete[] colors;
} }
void Font::sizeText(std::string text, int* w, int* h) void TextCache::setColor(unsigned int color)
{ {
float cwidth = 0.0f; Renderer::buildGLColorArray(const_cast<GLubyte*>(colors), color, vertCount);
for(unsigned int i = 0; i < text.length(); i++)
{
unsigned char letter = text[i];
if(letter < 32 || letter >= 128)
letter = 127;
cwidth += charData[letter].advX * fontScale;
}
if(w != NULL)
*w = (int)cwidth;
if(h != NULL)
*h = getHeight();
}
int Font::getHeight()
{
return (int)(mMaxGlyphHeight * 1.5f * fontScale);
} }

View file

@ -6,6 +6,9 @@
#include GLHEADER #include GLHEADER
#include <ft2build.h> #include <ft2build.h>
#include FT_FREETYPE_H #include FT_FREETYPE_H
#include "Vector2.h"
class TextCache;
//A TrueType Font renderer that uses FreeType and OpenGL. //A TrueType Font renderer that uses FreeType and OpenGL.
//The library is automatically initialized when it's needed. //The library is automatically initialized when it's needed.
@ -37,8 +40,12 @@ public:
GLuint textureID; GLuint textureID;
void drawText(std::string text, int startx, int starty, int color); //Render some text using this font. TextCache* buildTextCache(const std::string& text, int offsetX, int offsetY, unsigned int color);
void sizeText(std::string text, int* w, int* h); //Sets the width and height of a given string to given pointers. Skipped if pointer is NULL. void renderTextCache(TextCache* cache);
//Create a TextCache, render with it, then delete it. Best used for short text or text that changes frequently.
void drawText(std::string text, int startx, int starty, int color);
void sizeText(std::string text, int* w, int* h); //Sets the width and height of a given string to supplied pointers. A dimension is skipped if its pointer is NULL.
int getHeight(); int getHeight();
void init(); void init();
@ -65,4 +72,24 @@ private:
int mSize; int mSize;
}; };
class TextCache
{
public:
struct Vertex
{
Vector2<GLfloat> pos;
Vector2<GLfloat> tex;
};
void setColor(unsigned int color);
TextCache(int verts, Vertex* v, GLubyte* c, Font* f);
~TextCache();
const int vertCount;
const Vertex* verts;
const GLubyte* colors;
const Font* sourceFont;
};
#endif #endif

View file

@ -30,7 +30,7 @@ GuiGameList::GuiGameList(Window* window) : GuiComponent(window),
mImageAnimation.addChild(&mScreenshot); mImageAnimation.addChild(&mScreenshot);
//scale delay with screen width (higher width = more text per line) //scale delay with screen width (higher width = more text per line)
//the scroll speed is automatically scrolled by component size //the scroll speed is automatically scaled by component size
mDescription.setAutoScroll((int)(1500 + (Renderer::getScreenWidth() * 0.5)), 0.025f); mDescription.setAutoScroll((int)(1500 + (Renderer::getScreenWidth() * 0.5)), 0.025f);
mTransitionImage.setOffset(Renderer::getScreenWidth(), 0); mTransitionImage.setOffset(Renderer::getScreenWidth(), 0);