From ca67b65703e8a7c6436869132c1d042ad97b46fe Mon Sep 17 00:00:00 2001 From: Luo Jinghua Date: Mon, 13 Jun 2011 14:54:40 +0800 Subject: opengles: save & restore gl states --- src/sdl-freetype-opengles.c | 294 +++++++++++++++++++++++++------------------- 1 file changed, 165 insertions(+), 129 deletions(-) diff --git a/src/sdl-freetype-opengles.c b/src/sdl-freetype-opengles.c index e81dc4d..1b27849 100644 --- a/src/sdl-freetype-opengles.c +++ b/src/sdl-freetype-opengles.c @@ -299,6 +299,14 @@ sdl_freetype_opengles_glyphs_render (sdl_freetype_font_t * font, int i, start, num_cached; sdl_freetype_bool_t dirty = SDL_FREETYPE_FALSE; GLboolean blend_enabled; + GLboolean color_array_enabled; + GLboolean vertex_array_enabled; + GLboolean texcoord_array_enabled; + GLboolean normal_array_enabled; + GLboolean tex2d_enabled; + GLboolean lighting_enabled; + GLfloat color[4]; + GLenum blenddst, blendsrc; if (!render->valid) { for (i = 0; i < num_glyphs && !render->valid; i++) @@ -320,148 +328,176 @@ sdl_freetype_opengles_glyphs_render (sdl_freetype_font_t * font, if (!cached) return SDL_FREETYPE_ERR_OUT_OF_MEMORY; - blend_enabled = glIsEnabled(GL_BLEND); + blend_enabled = glIsEnabled (GL_BLEND); + color_array_enabled = glIsEnabled (GL_COLOR_ARRAY); + vertex_array_enabled = glIsEnabled (GL_VERTEX_ARRAY); + texcoord_array_enabled = glIsEnabled (GL_TEXTURE_COORD_ARRAY); + normal_array_enabled = glIsEnabled (GL_NORMAL_ARRAY); + tex2d_enabled = glIsEnabled (GL_TEXTURE_2D); + lighting_enabled = glIsEnabled (GL_LIGHTING); + glGetFloatv (GL_CURRENT_COLOR, color); + glGetIntegerv (GL_BLEND_SRC, &blendsrc); + glGetIntegerv (GL_BLEND_DST, &blenddst); start = 0; while (start < num_glyphs) { - int end; - - num_cached = 0; - for (i = start; i < num_glyphs; i++) { - info = sdl_freetype_font_glyph_info_lookup (font, glyphs[i].index, - SDL_FREETYPE_GLYPH_SURFACE | - SDL_FREETYPE_GLYPH_USER_DATA); - if (!info || info->flags & SDL_FREETYPE_GLYPH_EMPTY) - continue; - - user_data = info->data; - if (!user_data) { - if (num_cached) - i--; - break; - } - if (!user_data->area) - continue; - user_data->locked++; - cached[num_cached].index = i; - cached[num_cached++].info = info; - } - end = i + 1; - - if (num_cached) { - GLfloat *vertex_buffer = render->vertex_buffer; - GLfloat *texcoord_buffer = render->texcoord_buffer; - int left = num_cached; - - if (!dirty) { - dirty = SDL_FREETYPE_TRUE; - - glMatrixMode (GL_TEXTURE); - glPushMatrix (); - glLoadIdentity (); - - glMatrixMode (GL_MODELVIEW); - glPushMatrix (); - - glEnable (GL_BLEND); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glEnable (GL_TEXTURE_2D); - glBindTexture (GL_TEXTURE_2D, render->texture); - - glTranslatef (x * render->usx, y * render->usy, 0.0f); - - glColor4ub (r, g, b, a); - - glEnableClientState (GL_VERTEX_ARRAY); - glEnableClientState (GL_TEXTURE_COORD_ARRAY); - - glVertexPointer (2, GL_FLOAT, 0, vertex_buffer); - glTexCoordPointer (2, GL_FLOAT, 0, texcoord_buffer); - } - - i = 0; - while (left) { - int num_quads = VERTEX_BUFFER_SIZE; - int max_index; - int j; - - if (left < num_quads) - num_quads = left; - - max_index = i + num_quads; - - for (j = 0; i < max_index; i++, j += 12) { - user_data = cached[i].info->data; - - assert (user_data->locked != 0); - - x1 = FIXEDTOD (glyphs[cached[i].index].x) + cached[i].info->x_offset; - y1 = FIXEDTOD (glyphs[cached[i].index].y) + cached[i].info->y_offset; - x2 = x1 + cached[i].info->bitmap.width; - y2 = y1 + cached[i].info->bitmap.rows; - - x1 *= render->usx; - y1 *= render->usy; - x2 *= render->usx; - y2 *= render->usy; - - texcoord_buffer[j + 0] = user_data->uv[0].x; - texcoord_buffer[j + 1] = user_data->uv[0].y; - vertex_buffer[j + 0] = x1; - vertex_buffer[j + 1] = y1; - - texcoord_buffer[j + 2] = user_data->uv[0].x; - texcoord_buffer[j + 3] = user_data->uv[1].y; - vertex_buffer[j + 2] = x1; - vertex_buffer[j + 3] = y2; - - texcoord_buffer[j + 4] = user_data->uv[1].x; - texcoord_buffer[j + 5] = user_data->uv[1].y; - vertex_buffer[j + 4] = x2; - vertex_buffer[j + 5] = y2; - - texcoord_buffer[j + 6] = user_data->uv[1].x; - texcoord_buffer[j + 7] = user_data->uv[1].y; - vertex_buffer[j + 6] = x2; - vertex_buffer[j + 7] = y2; - - texcoord_buffer[j + 8] = user_data->uv[1].x; - texcoord_buffer[j + 9] = user_data->uv[0].y; - vertex_buffer[j + 8] = x2; - vertex_buffer[j + 9] = y1; - - texcoord_buffer[j + 10] = user_data->uv[0].x; - texcoord_buffer[j + 11] = user_data->uv[0].y; - vertex_buffer[j + 10] = x1; - vertex_buffer[j + 11] = y1; - - user_data->locked--; - } + int end; + + num_cached = 0; + for (i = start; i < num_glyphs; i++) { + info = sdl_freetype_font_glyph_info_lookup (font, glyphs[i].index, + SDL_FREETYPE_GLYPH_SURFACE | + SDL_FREETYPE_GLYPH_USER_DATA); + if (!info || info->flags & SDL_FREETYPE_GLYPH_EMPTY) + continue; + + user_data = info->data; + if (!user_data) { + if (num_cached) + i--; + break; + } + if (!user_data->area) + continue; + user_data->locked++; + cached[num_cached].index = i; + cached[num_cached++].info = info; + } + end = i + 1; + + if (num_cached) { + GLfloat *vertex_buffer = render->vertex_buffer; + GLfloat *texcoord_buffer = render->texcoord_buffer; + int left = num_cached; + + if (!dirty) { + dirty = SDL_FREETYPE_TRUE; + + glMatrixMode (GL_TEXTURE); + glPushMatrix (); + glLoadIdentity (); + + glMatrixMode (GL_MODELVIEW); + glPushMatrix (); + + glEnable (GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glDisable (GL_LIGHTING); + glDisable (GL_DEPTH_TEST); + glDisable (GL_FOG); + + glEnable (GL_TEXTURE_2D); + glBindTexture (GL_TEXTURE_2D, render->texture); + + glTranslatef (x * render->usx, y * render->usy, 0.0f); + + glColor4ub (r, g, b, a); + + glEnableClientState (GL_VERTEX_ARRAY); + glEnableClientState (GL_TEXTURE_COORD_ARRAY); + glDisableClientState (GL_COLOR_ARRAY); + glDisableClientState (GL_NORMAL_ARRAY); + + glVertexPointer (2, GL_FLOAT, 0, vertex_buffer); + glTexCoordPointer (2, GL_FLOAT, 0, texcoord_buffer); + } + + i = 0; + while (left) { + int num_quads = VERTEX_BUFFER_SIZE; + int max_index; + int j; + + if (left < num_quads) + num_quads = left; - glDrawArrays (GL_TRIANGLES, 0, num_quads * 6); + max_index = i + num_quads; - left -= num_quads; - } - } - start = end; + for (j = 0; i < max_index; i++, j += 12) { + user_data = cached[i].info->data; + + assert (user_data->locked != 0); + + x1 = FIXEDTOD (glyphs[cached[i].index].x) + cached[i].info->x_offset; + y1 = FIXEDTOD (glyphs[cached[i].index].y) + cached[i].info->y_offset; + x2 = x1 + cached[i].info->bitmap.width; + y2 = y1 + cached[i].info->bitmap.rows; + + x1 *= render->usx; + y1 *= render->usy; + x2 *= render->usx; + y2 *= render->usy; + + texcoord_buffer[j + 0] = user_data->uv[0].x; + texcoord_buffer[j + 1] = user_data->uv[0].y; + vertex_buffer[j + 0] = x1; + vertex_buffer[j + 1] = y1; + + texcoord_buffer[j + 2] = user_data->uv[0].x; + texcoord_buffer[j + 3] = user_data->uv[1].y; + vertex_buffer[j + 2] = x1; + vertex_buffer[j + 3] = y2; + + texcoord_buffer[j + 4] = user_data->uv[1].x; + texcoord_buffer[j + 5] = user_data->uv[1].y; + vertex_buffer[j + 4] = x2; + vertex_buffer[j + 5] = y2; + + texcoord_buffer[j + 6] = user_data->uv[1].x; + texcoord_buffer[j + 7] = user_data->uv[1].y; + vertex_buffer[j + 6] = x2; + vertex_buffer[j + 7] = y2; + + texcoord_buffer[j + 8] = user_data->uv[1].x; + texcoord_buffer[j + 9] = user_data->uv[0].y; + vertex_buffer[j + 8] = x2; + vertex_buffer[j + 9] = y1; + + texcoord_buffer[j + 10] = user_data->uv[0].x; + texcoord_buffer[j + 11] = user_data->uv[0].y; + vertex_buffer[j + 10] = x1; + vertex_buffer[j + 11] = y1; + + user_data->locked--; + } + + glDrawArrays (GL_TRIANGLES, 0, num_quads * 6); + + left -= num_quads; + } + } + start = end; } if (dirty) { - glDisableClientState (GL_VERTEX_ARRAY); - glDisableClientState (GL_TEXTURE_COORD_ARRAY); + if (!vertex_array_enabled) + glDisableClientState (GL_VERTEX_ARRAY); + if (!texcoord_array_enabled) + glDisableClientState (GL_TEXTURE_COORD_ARRAY); + if (color_array_enabled) + glEnableClientState (GL_COLOR_ARRAY); + if (normal_array_enabled) + glEnableClientState (GL_NORMAL_ARRAY); + + glMatrixMode (GL_TEXTURE); + glPopMatrix (); - glPopMatrix (); + if (!blend_enabled) + glDisable (GL_BLEND); + glBlendFunc (blendsrc, blenddst); - glMatrixMode (GL_TEXTURE); - glPopMatrix (); + if (lighting_enabled) + glEnable (GL_LIGHTING); - if (!blend_enabled) - glDisable (GL_BLEND); + if (!tex2d_enabled) + glDisable (GL_TEXTURE_2D); + glBindTexture (GL_TEXTURE_2D, 0); - glBindTexture (GL_TEXTURE_2D, 0); + glMatrixMode (GL_MODELVIEW); + glPopMatrix (); - glMatrixMode (GL_MODELVIEW); + glColor4f (color[0], color[1], color[2], color[3]); } if (cached != stack_cached) -- cgit v1.2.3