summaryrefslogtreecommitdiff
path: root/src/sdl-freetype-opengles.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sdl-freetype-opengles.c')
-rw-r--r--src/sdl-freetype-opengles.c119
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;