Advertisement

Opengl freetype text alignment

Started by December 31, 2014 03:19 PM
1 comment, last by Jan2go 10 years ago

I'm trying to make text writing function. Here:


struct character
{
	float advancex, advancey, bitmapw, bitmaph, bitmapl, bitmapt, texx;
};

character* c;

struct point {
	GLfloat x;
	GLfloat y;
	GLfloat z;
	GLfloat s;
	GLfloat t;
};

point coords[255*6];

void renderText(const char*text,float x,float y,float sizex,float sizey)
{
	// ScreenWidth = 640;
	// ScreenHeight = 480;
	auto l = -ScreenWidth / 2 + x;
	auto t = ScreenHeight / 2  + y;

	int n = 0;

	for (const char *p = text; *p; p++) 
	{
		if (!w || !h)continue;

		auto r = l + c[*p].bitmapw*sizex;
		auto b = t - c[*p].bitmaph*sizey;

		coords[n++] = { l, t, 0, c[*p].texx, c[*p].bitmaph / atlas_height };
		coords[n++] = { r, b, 0, c[*p].texx + c[*p].bitmapw / atlas_width, 0 };
		coords[n++] = { l, b, 0, c[*p].texx, 0 };

		coords[n++] = { l, t, 0, c[*p].texx, c[*p].bitmaph / atlas_height };
		coords[n++] = { r, t, 0, c[*p].texx + c[*p].bitmapw / atlas_width, c[*p].bitmaph / atlas_height };
		coords[n++] = { r, b, 0, c[*p].texx + c[*p].bitmapw / atlas_width, 0 };

		l += c[*p].advancex*sizex;
		t += c[*p].advancey*sizey;

	}
	glBindTexture(GL_TEXTURE_2D, texture2D_ID0);
	glBindVertexArray(vertex_array_ID);
	glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_ID);

	glBufferSubData(GL_ARRAY_BUFFER,0,n*sizeof(point),coords);
	glDrawArrays(GL_TRIANGLES, 0, n);
}

How can I get aligned text? I use orthographic projection given as glm::ortho(-320.0f, +320.0f, 240.0f, -240.0f, 0.1f, 100.f);

and I get this result:

Sorry for my English.

The alignment of the text has nothing to do with the projection matrix really, you need to do some debugging and analyze the different glyphs values that pertain to each individual character. I see that you already have most of the work done, but you have to remember, given a common baseline ( pen horizontal location ), each glyph will have a different origin in reference to the baseline. Consider, the characters like 'y' and 'p' vs 'a' and 'w', you will notice that these are going to have a different origin in relation to the baseline. If you are using Freetype ( which it seems like you are ), you need to offset each character by the origin to get them to a common baseline.

Advertisement
Like cgrant said you need to take the height diffences of the characters into account. Using the data that you get from FreeType you can calculate the ascent and descent of each character. Then you use these values to adjust the Y-coordinate of your vertices.
In my code I calcualte ascent and descent like this (slot is the FT_GlyphSlot of a character):
float descent = static_cast<float>(slot->bitmap.rows - slot->bitmap_top);
float ascent = static_cast<float>(slot->bitmap_top) - descent;

This topic is closed to new replies.

Advertisement