Exemple #1
0
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;
}