diff options
Diffstat (limited to 'src/sdl-freetype-opengles.c')
-rw-r--r-- | src/sdl-freetype-opengles.c | 119 |
1 files changed, 84 insertions, 35 deletions
diff --git a/src/sdl-freetype-opengles.c b/src/sdl-freetype-opengles.c index 2ce3898..b1425b5 100644 --- a/src/sdl-freetype-opengles.c +++ b/src/sdl-freetype-opengles.c @@ -39,12 +39,14 @@ #include <stdlib.h> #include <stdio.h> -#include <GL/gl.h> + +#include <GLES/gl.h> #define FIXEDTOD(f) (sdl_freetype_fixed_to_double (f)) #define GLYPH_CACHE_SIZE 512 #define GLYPH_CACHE_LEVEL 64 +#define VERTEX_BUFFER_SIZE 128 typedef struct sdl_freetype_opengles_render_s { sdl_freetype_glyph_render_t base; @@ -56,6 +58,8 @@ typedef struct sdl_freetype_opengles_render_s { int width, height; float usx, usy; GLuint texture; + GLfloat vertex_buffer[VERTEX_BUFFER_SIZE * 6 * 2]; + GLfloat texcoord_buffer[VERTEX_BUFFER_SIZE * 6 * 2]; } sdl_freetype_opengles_render_t; typedef struct { @@ -115,8 +119,8 @@ sdl_freetype_opengles_glyph_user_data_init (sdl_freetype_font_t * font, glGenTextures (1, &opengles_render->texture); glBindTexture (GL_TEXTURE_2D, opengles_render->texture); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); @@ -238,15 +242,14 @@ sdl_freetype_opengles_glyph_user_data_init (sdl_freetype_font_t * font, break; } - glPopClientAttrib (); if (data) free (data); user_data->uv[0].x = (float)area->x; user_data->uv[0].y = (float)area->y; - user_data->uv[1].x = (float)(area->x + bitmap->width); - user_data->uv[1].y = (float)(area->y + bitmap->rows); + user_data->uv[1].x = (float)(area->x + bitmap->width) / opengles_render->width; + user_data->uv[1].y = (float)(area->y + bitmap->rows) / opengles_render->height; info->data = user_data; return SDL_FREETYPE_ERR_OK; } @@ -289,6 +292,7 @@ sdl_freetype_opengles_glyphs_render (sdl_freetype_font_t * font, sdl_freetype_glyph_info_t * info; double x1, y1, x2, y2; int i, num_cached; + GLboolean blend_enabled; if (!render->valid) { for (i = 0; i < num_glyphs && !render->valid; i++) @@ -310,7 +314,7 @@ sdl_freetype_opengles_glyphs_render (sdl_freetype_font_t * font, if (!cached) return SDL_FREETYPE_ERR_OUT_OF_MEMORY; - glPushAttrib (GL_CURRENT_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT); + blend_enabled = glIsEnabled(GL_BLEND); num_cached = 0; for (i = 0; i < num_glyphs; i++) { @@ -328,10 +332,13 @@ sdl_freetype_opengles_glyphs_render (sdl_freetype_font_t * font, } if (num_cached) { + GLfloat *vertex_buffer = render->vertex_buffer; + GLfloat *texcoord_buffer = render->texcoord_buffer; + int left = num_cached; + glMatrixMode (GL_TEXTURE); glPushMatrix (); glLoadIdentity (); - glScalef (1.0f / render->width, 1.0f / render->height, 1.0f); glMatrixMode (GL_MODELVIEW); glPushMatrix (); @@ -346,37 +353,75 @@ sdl_freetype_opengles_glyphs_render (sdl_freetype_font_t * font, glColor4ub (r, g, b, a); - glBegin (GL_QUADS); + glEnableClientState (GL_VERTEX_ARRAY); + glEnableClientState (GL_TEXTURE_COORD_ARRAY); - for (i = 0; i < num_cached; i++) { - user_data = cached[i].info->data; + glVertexPointer (2, GL_FLOAT, 0, vertex_buffer); + glTexCoordPointer (2, GL_FLOAT, 0, texcoord_buffer); - x1 = FIXEDTOD (glyphs[cached[i].index].x) + cached[i].info->x_offset; - y2 = -FIXEDTOD (glyphs[cached[i].index].y) - cached[i].info->y_offset; - x2 = x1 + cached[i].info->bitmap.width; - y1 = y2 - cached[i].info->bitmap.rows; + i = 0; + while (left) { + int num_quads = VERTEX_BUFFER_SIZE; + int max_index; + int j = 0; - x1 *= render->usx; - y1 *= render->usy; - x2 *= render->usx; - y2 *= render->usy; + if (left < num_quads) + num_quads = left; - glTexCoord2f (user_data->uv[0].x, user_data->uv[1].y); - glVertex2f (x1, y1); + max_index = i + num_quads; + for (j = 0; i < max_index; i++, j += 12) { + user_data = cached[i].info->data; - glTexCoord2f (user_data->uv[0].x, user_data->uv[0].y); - glVertex2f (x1, y2); + x1 = FIXEDTOD (glyphs[cached[i].index].x) + cached[i].info->x_offset; + y2 = -FIXEDTOD (glyphs[cached[i].index].y) - cached[i].info->y_offset; + x2 = x1 + cached[i].info->bitmap.width; + y1 = y2 - cached[i].info->bitmap.rows; - glTexCoord2f (user_data->uv[1].x, user_data->uv[0].y); - glVertex2f (x2, y2); + x1 *= render->usx; + y1 *= render->usy; + x2 *= render->usx; + y2 *= render->usy; - glTexCoord2f (user_data->uv[1].x, user_data->uv[1].y); - glVertex2f (x2, y1); + 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; - user_data->locked = SDL_FREETYPE_FALSE; - } + 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; - glEnd (); + 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 = SDL_FREETYPE_FALSE; + } + + glDrawArrays (GL_TRIANGLES, 0, num_quads * 6); + + left -= num_quads; + } + + glDisableClientState (GL_VERTEX_ARRAY); + glDisableClientState (GL_TEXTURE_COORD_ARRAY); glPopMatrix (); @@ -384,7 +429,10 @@ sdl_freetype_opengles_glyphs_render (sdl_freetype_font_t * font, glPopMatrix (); } - glPopAttrib (); + if (!blend_enabled) + glDisable (GL_BLEND); + + glBindTexture (GL_TEXTURE_2D, 0); if (cached != stack_cached) free (cached); @@ -462,10 +510,11 @@ sdl_freetype_opengles_render_create (void) render->subpixel = SDL_FREETYPE_FALSE; render->usx = render->usy = 1.0; render->width = render->height = GLYPH_CACHE_SIZE; - render->manager = sdl_freetype_area_manager_create (render->width, - render->height, - GLYPH_CACHE_LEVEL, - &sdl_freetype_opengles_glyph_ops); + render->manager = + sdl_freetype_area_manager_create (render->width, + render->height, + GLYPH_CACHE_LEVEL, + &sdl_freetype_opengles_glyph_ops); if (!render->manager) goto errquit1; |