The OpenGL just supports capability to draw primitive, not text. In order to draw text on screen we need support of other package such as Cairo or Pango. The following topic describe how to use Cairo with OpenGL.
1 First we need to create a Cairo surface for drawing (text)
2 Then we will load the surface into GL texture using glTextureXXX function
3 After all, we will apply texture mapping into our primitive (for example a rectangle for displaying text)
Create Cairo Context
inline cairo_t*
create_cairo_context (int width,
int height,
int channels,
cairo_surface_t** surf,
unsigned char** buffer)
{
cairo_t* cr;
/* create cairo-surface/context to act as OpenGL-texture source */
*buffer = (unsigned char*)calloc (channels * width * height, sizeof (unsigned char));
if (!*buffer)
{
printf ("create_cairo_context() - Couldn't allocate surface-buffer\n");
return NULL;
}
*surf = cairo_image_surface_create_for_data (*buffer,
CAIRO_FORMAT_ARGB32,
width,
height,
channels * width);
if (cairo_surface_status (*surf) != CAIRO_STATUS_SUCCESS)
{
free (*buffer);
printf ("create_cairo_context() - Couldn't create surface\n");
return NULL;
}
cr = cairo_create (*surf);
if (cairo_status (cr) != CAIRO_STATUS_SUCCESS)
{
free (*buffer);
printf ("create_cairo_context() - Couldn't create context\n");
return NULL;
}
return cr;
}
Draw text into the Cairo surface and then load it into GL Texture
inline int DrawText(int x, int y, int width, int height, char *string, COLOR &textColor, COLOR &background)
{
cairo_surface_t* surface = NULL;
cairo_t* cr;
unsigned char* surfData;
GLuint textureId;
/* create cairo-surface/context to act as OpenGL-texture source */
cr = create_cairo_context (256,
256,
4,
&surface,
&surfData);
/* clear background */
cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
cairo_set_source_rgb(cr, background.red, background.green, background.blue);
cairo_paint (cr);
cairo_move_to(cr, 256/10, 256/2);
cairo_set_font_size(cr, 30);
cairo_select_font_face(cr, "sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
cairo_set_source_rgb(cr, textColor.red, textColor.green, textColor.blue);
cairo_show_text(cr, string);
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D,
0,
GL_RGBA,
256,
256,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
surfData);
TestEGLError("glTexImage2D");
free (surfData);
cairo_destroy (cr);
return textureId;
}
Texture Mapping
The texture mapping is so simple, we need to provide them the UV coordinate. The UV coordinate is range from 0 to 1 which 0 is the start point, and 1 is the end point. The following is an example usage
GLfloat textureCoord[] = {
f2vt(0.0f), f2vt(0.35f),
f2vt(1.0f), f2vt(0.35f),
f2vt(0.0f), f2vt(0.55f),
f2vt(1.0f), f2vt(0.55f)
};
COLOR clrText = {255,255,255};
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
GLuint textureId = DrawText(clipRect[0], clipRect[1], clipRect[2], clipRect[3], data, clrText, this->m_clrBackground);
glVertexPointer(2, VERTTYPEENUM, 0, rect);
glTexCoordPointer(2, VERTTYPEENUM, 0, textureCoord);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDeleteTextures(1, &textureId);
Showing posts with label opengl. Show all posts
Showing posts with label opengl. Show all posts
Aug 16, 2009
Aug 15, 2009
Enable 2D Over OpenGL
In OpenGL, if we want to 2D only, we can use the Ortho matrix to set ignore the z-list. The following code snippet demo how to do that
void glEnable2D()
{
int vPort[4];
glGetIntegerv(GL_VIEWPORT, vPort);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, vPort[2], 0, vPort[3], -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
}
void glDisable2D()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
void glEnable2D()
{
int vPort[4];
glGetIntegerv(GL_VIEWPORT, vPort);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, vPort[2], 0, vPort[3], -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
}
void glDisable2D()
{
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
Subscribe to:
Posts (Atom)