diff options
author | Luo Jinghua <sunmoon1997@gmail.com> | 2011-06-13 11:03:42 +0800 |
---|---|---|
committer | Luo Jinghua <sunmoon1997@gmail.com> | 2011-06-13 11:19:50 +0800 |
commit | 2668d45c63d5e17501e5f9ff145d609a87c44945 (patch) | |
tree | 9074f061f2a5850f21c45f558a08b3f7a995afc7 | |
parent | 40555bf99d5ccfa1bebe4e4231ab3d9a86a77cd4 (diff) |
test: added a gles variant of wrap-test
-rw-r--r-- | src/Makefile.am | 14 | ||||
-rw-r--r-- | src/gles-wrap-test.cpp | 493 | ||||
-rw-r--r-- | src/wrap-test.cpp | 8 |
3 files changed, 511 insertions, 4 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index a731ad2..53dcf3d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -81,9 +81,11 @@ endif if HAVE_OPENGLES gles_test = gles-test +gles_wrap_test = gles-wrap-test endif -noinst_PROGRAMS = hash-test cache-test font-test $(sdl_test) $(sdl_opengl_test) $(gles_test) $(wrap_test) +noinst_PROGRAMS = hash-test cache-test font-test $(sdl_test) $(sdl_opengl_test) \ + $(gles_test) $(wrap_test) $(gles_wrap_test) hash_test_SOURCES = hash-test.c hash_test_LDADD = libsdl-freetype.la @@ -129,6 +131,16 @@ endif endif endif +if HAVE_OPENGLES +gles_wrap_test_SOURCES = gles-wrap-test.cpp +gles_wrap_test_LDADD = libsdl-freetype-opengles.la $(EGL_LIBS) +if HAVE_FONTCONFIG +gles_wrap_test_LDADD += libsdl-ft.la +else +gles_wrap_test_LDADD += libsdl-freetype.la +endif +endif + lib_LTLIBRARIES = \ libsdl-freetype.la \ $(libsdl_ft) \ diff --git a/src/gles-wrap-test.cpp b/src/gles-wrap-test.cpp new file mode 100644 index 0000000..f1a2001 --- /dev/null +++ b/src/gles-wrap-test.cpp @@ -0,0 +1,493 @@ +/* Copyright (C) <2011> Luo Jinghua<sunmoon1997@gmail.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <EGL/egl.h> +#include <GLES/gl.h> + +#include <sdl-freetype.h> +#include <sdl-freetype-opengles.h> + +#ifdef HAVE_FONTCONFIG +#include <sdl-ft.h> +#endif + +#include <stdio.h> + +static EGLDisplay eglDisplay = 0; +static EGLConfig eglConfig = 0; +static EGLContext eglContext = 0; +static EGLSurface eglSurface = 0; + +#ifdef HAVE_X +static Display *x11Display = NULL; +static Window x11Window = None; +#endif + +// consts +#define COLOURDEPTH_RED_SIZE 8 +#define COLOURDEPTH_GREEN_SIZE 8 +#define COLOURDEPTH_BLUE_SIZE 8 +#define COLOURDEPTH_DEPTH_SIZE 16 + +static const EGLint configAttribs[] ={ + EGL_RED_SIZE, COLOURDEPTH_RED_SIZE, + EGL_GREEN_SIZE, COLOURDEPTH_GREEN_SIZE, + EGL_BLUE_SIZE, COLOURDEPTH_BLUE_SIZE, + EGL_DEPTH_SIZE, COLOURDEPTH_DEPTH_SIZE, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, + EGL_NONE +}; + +static int InitOpenGL(int width, int height) +{ + EGLint numConfigsOut = 0; + /* EGLint contextParams[] = {EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE}; // Use GLES version 1.x */ + +#ifdef HAVE_X + // use EGL to initialise GLES + x11Display = XOpenDisplay(NULL); + + if (!x11Display) + { + fprintf(stderr, "ERROR: unable to get display!n"); + return 0; + } + + x11Window = XCreateSimpleWindow(x11Display, + RootWindow(x11Display, DefaultScreen(x11Display)), + 1, 1, width, height, 0, + BlackPixel(x11Display, DefaultScreen(x11Display)), + BlackPixel(x11Display, DefaultScreen(x11Display))); + if (x11Window == None) + { + fprintf(stderr, "ERROR: unable to create a window!n"); + return 0; + } + + XMapWindow(x11Display, x11Window); + XFlush(x11Display); + + eglDisplay = eglGetDisplay((EGLNativeDisplayType)x11Display); +#else + eglDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY); +#endif + if (eglDisplay == EGL_NO_DISPLAY) + { + printf("Unable to initialise EGL display."); + return 0; + } + + // Initialise egl + if (!eglInitialize(eglDisplay, NULL, NULL)) + { + printf("Unable to initialise EGL display."); + return 0; + } + + // Find a matching config + if (eglChooseConfig(eglDisplay, configAttribs, &eglConfig, 1, &numConfigsOut) != EGL_TRUE || numConfigsOut == 0) + { + fprintf(stderr, "Unable to find appropriate EGL config."); + return 0; + } + +#ifdef HAVE_X + eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType)x11Window, 0); +#else + eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType)0, 0); +#endif + if ( eglSurface == EGL_NO_SURFACE) + { + printf("Unable to create EGL surface!"); + return 0; + } + + // Bind GLES and create the context + eglBindAPI(EGL_OPENGL_ES_API); + eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, NULL); + if (eglContext == EGL_NO_CONTEXT) + { + printf("Unable to create GLES context!"); + return 0; + } + + if (eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext) == EGL_FALSE) + { + printf("Unable to make GLES context current"); + return 0; + } + + return 1; +} + +/*====================================================== + * Kill off any opengl specific details + ====================================================*/ +static void TerminateOpenGL(void) +{ + eglMakeCurrent(eglDisplay, NULL, NULL, EGL_NO_CONTEXT); + eglDestroySurface(eglDisplay, eglSurface); + eglDestroyContext(eglDisplay, eglContext); + eglSurface = 0; + eglContext = 0; + eglConfig = 0; + + eglTerminate(eglDisplay); + eglDisplay = 0; + +#ifdef HAVE_X + XDestroyWindow(x11Display, x11Window); + XCloseDisplay(x11Display); + x11Display = NULL; +#endif +} + +static int SwapBuffers(void) +{ + eglSwapBuffers(eglDisplay, eglSurface); + return 0; +} + +#include <vector> + +enum TextFormat { + TF_NONE = 0, + TF_CALCRECT = 1 << 0, + TF_CENTER = 1 << 1, + TF_LEFT = 1 << 2, + TF_RIGHT = 1 << 3, + TF_SINGLELINE = 1 << 4, + TF_NOCLIP = 1 << 5 +}; + +struct TextRect { + int x; + int y; + int width; + int height; +}; + +struct TextColor { + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; +}; + +typedef std::vector<sdl_freetype_glyph_t> GlyphVector; +struct TextLine { + GlyphVector glyphs; + sdl_freetype_text_fixed_extents_t exts; +}; +typedef std::vector<TextLine> TextLineVector; + +static int +DrawText(sdl_freetype_font_t * font, + const FT_Int32 *text, int len, + TextRect *rect, + TextFormat format, + TextColor color) +{ + if (!font || !text) + return 0; + + if (len < 0) { + const FT_Int32 *s = text; + + len = 0; + while (*s++) + len++; + } + + TextLineVector lines; + + sdl_freetype_font_fixed_extents_t exts; + sdl_freetype_font_fixed_extents(font, &exts); + + sdl_freetype_fixed_t x = 0; + sdl_freetype_fixed_t y = 0; + sdl_freetype_fixed_t adv_x = 0; + sdl_freetype_fixed_t adv_y = 0; + sdl_freetype_fixed_t width = rect->width << 16; + sdl_freetype_fixed_t maxwidth = 0; + bool clip = (format & TF_NOCLIP) == 0; + + lines.push_back(TextLine()); + TextLine *line = &lines.back(); + memset(&line->exts, 0, sizeof(line->exts)); + + for (int i = 0; i < len; i++) { + sdl_freetype_glyph_t g; + sdl_freetype_text_fixed_extents_t metrics; + + if (text[i] == '\r') + continue; + + if (clip && (y + exts.height) >> 16 > rect->height) + break; + + if (text[i] == '\n') { + if (format & TF_SINGLELINE) + continue; + y += exts.height; + + sdl_freetype_font_glyphs_fixed_extents(font, &line->exts, + &line->glyphs[0], line->glyphs.size()); + if (line->exts.width > maxwidth) + maxwidth = line->exts.width; + + lines.push_back(TextLine()); + line = &lines.back(); + memset(&line->exts, 0, sizeof(line->exts)); + adv_x = 0; + adv_y = 0; + x = 0; + } + + x += adv_x; + y += adv_y; + g.x = x; + g.y = y; + g.index = sdl_freetype_font_glyph_index(font, text[i]); + if (!g.index || sdl_freetype_font_glyph_fixed_metrics(font, g.index, &metrics)) { + adv_x = 0; + adv_y = 0; + continue; + } else { + adv_x = metrics.x_advance; + adv_y = metrics.y_advance; + } + if (format & TF_SINGLELINE) { + if (!clip || x + metrics.width <= width) + line->glyphs.push_back(g); + else + break; + } else { + if (clip && x + metrics.width > width) { + sdl_freetype_font_glyphs_fixed_extents(font, &line->exts, + &line->glyphs[0], line->glyphs.size()); + if (line->exts.width > maxwidth) + maxwidth = line->exts.width; + + lines.push_back(TextLine()); + line = &lines.back(); + memset(&line->exts, 0, sizeof(line->exts)); + + x = 0; + y += exts.height; + g.y = y; + g.x = x; + } + line->glyphs.push_back(g); + } + } + if (line->glyphs.size() && !line->exts.width) + sdl_freetype_font_glyphs_fixed_extents(font, &line->exts, + &line->glyphs[0], line->glyphs.size()); + if (!(format & TF_CALCRECT)) { + int xoffset; + int yoffset; + + if (lines.size()) + yoffset = (exts.height - exts.descent) >> 16; + for (size_t i = 0; i < lines.size(); i++) { + TextLine &line = lines[i]; + + xoffset = -line.exts.x_bearing >> 16; + if (format & TF_RIGHT) + xoffset += rect->width - (line.exts.width >> 16); + else if (format & TF_CENTER) + xoffset += (rect->width - (line.exts.width >> 16)) / 2; + + sdl_freetype_font_show_glyphs(font, 0, + color.r, color.g, color.b, color.a, + rect->x + xoffset, rect->y + yoffset, + &line.glyphs[0], line.glyphs.size()); + } + } + + if (!lines[0].glyphs.size()) + return 0; + + rect->width = maxwidth >> 16; + return (lines.size() * exts.height) >> 16; +} + +static void DrawLine(float x0, float y0, float x1, float y1) +{ + GLfloat verts[4]; + + verts[0] = x0; + verts[1] = y0; + verts[2] = x1; + verts[3] = y1; + + glEnableClientState (GL_VERTEX_ARRAY); + + glVertexPointer (2, GL_FLOAT, 0, verts); + glDrawArrays (GL_LINES, 0, 2); + + glDisableClientState (GL_VERTEX_ARRAY); +} + +static void DrawRect(float x, float y, float w, float h) +{ + DrawLine(x, y, x + w, y); + DrawLine(x + w, y, x + w, y + h); + DrawLine(x + w, y + h, x, y + h); + DrawLine(x, y + h, x, y); +} + +#define WIDTH 640 +#define HEIGHT 480 +int +main(int argc, char *argv[]) +{ + int done; + sdl_freetype_font_t * font; + sdl_freetype_glyph_render_t * render; + sdl_freetype_text_extents_t extents; + float alpha, step; + FT_Int32 text[] = { 'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '.', ' ', + 0x4f60, 0x597d, ',', ' ', 0x5927, 0x4e16, 0x754c, 0xff01, 0x0000 }; + +#ifdef HAVE_FONTCONFIG + font = sdl_ft_create_font ("sans", 16, + SDL_FT_WEIGHT_NORMAL, SDL_FT_SLANT_NORMAL, 96); +#else + if (argc < 2) { + printf("usage: %s /path/to/font.ttf\n", argv[0]); + return -1; + } + font = sdl_freetype_font_create(argv[1], 16 * 96 / 72.0); +#endif + if (!font) + goto errquit0; + + if (!InitOpenGL(WIDTH, HEIGHT)) + return -1; + + render = sdl_freetype_opengles_render_create (); + if (!render) + goto errquit1; + sdl_freetype_font_set_render (font, render); + + glMatrixMode (GL_PROJECTION) ; + glLoadIdentity (); + glOrthof (0, WIDTH, HEIGHT, 0, -1.0, 1.0); + + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + + alpha = 1.0f; + step = -0.002; + done = 0; + while (!done) { + float x, y; + +#ifdef HAVE_X + XEvent xevent; + + while (XPending(x11Display)) { + XNextEvent(x11Display, &xevent); + if (xevent.type == KeyPress) + done = 1; + } +#endif + + glClearColor (0.8f, 0.8f, 0.8f, 1.0f); + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glMatrixMode (GL_MODELVIEW); + glLoadIdentity (); + + glScalef (alpha + 1.0, alpha + 1.0, 1.0); + + TextColor color; + color.r = 255; + color.g = 0; + color.b = 0; + color.a = 64 + alpha * (255 - 64); + + TextRect rect; + rect.x = 400; + rect.y = 100; + rect.width = 200; + rect.height = 100; + + int h; + + // draw a single line and left aligned text + h = DrawText(font, text, -1, &rect, TextFormat(TF_SINGLELINE | TF_LEFT), color); + DrawRect(400, 100, 200, 100); + DrawLine(400, 100 + h, 400 + 200, 100 + h); + + // draw a multiple lines and left aligned text + rect.x = 100; + rect.y = 100; + rect.width = 100; + rect.height = 100; + h = DrawText(font, text, -1, &rect, TF_LEFT, color); + DrawRect(100, 100, 200, 100); + DrawLine(100, 100 + h, 100 + 200, 100 + h); + + // draw a multiple lines and right aligned text + rect.x = 100; + rect.y = 200; + rect.width = 200; + rect.height = 100; + h = DrawText(font, text, -1, &rect, TF_RIGHT, color); + DrawRect(100, 200, 200, 100); + DrawLine(100, 200 + h, 100 + 200, 200 + h); + + // draw a multiple lines and center aligned text + rect.x = 100; + rect.y = 300; + rect.width = 200; + rect.height = 100; + h = DrawText(font, text, -1, &rect, TF_CENTER, color); + DrawRect(100, 300, 200, 100); + DrawLine(100, 300 + h, 100 + 200, 300 + h); + + SwapBuffers(); + + alpha += step; + if (alpha < 0.0f) { + alpha = 0.0f; + step = -step; + } else if (alpha > 1.0f) { + alpha = 1.0f; + step = -step; + } + } + + errquit1: + sdl_freetype_font_destroy (font); + sdl_freetype_fini (); + + errquit0: + TerminateOpenGL(); + return 0; +} diff --git a/src/wrap-test.cpp b/src/wrap-test.cpp index 7dca6d0..68cec7a 100644 --- a/src/wrap-test.cpp +++ b/src/wrap-test.cpp @@ -74,8 +74,6 @@ DrawText(sdl_freetype_font_t * font, if (!font || !text) return 0; - TextLineVector lines; - if (len < 0) { FT_Int32 *s = text; @@ -84,6 +82,8 @@ DrawText(sdl_freetype_font_t * font, len++; } + TextLineVector lines; + sdl_freetype_font_fixed_extents_t exts; sdl_freetype_font_fixed_extents(font, &exts); @@ -176,7 +176,7 @@ DrawText(sdl_freetype_font_t * font, for (size_t i = 0; i < lines.size(); i++) { TextLine &line = lines[i]; - xoffset = line.exts.x_bearing >> 16; + xoffset = -line.exts.x_bearing >> 16; if (format & TF_RIGHT) xoffset += rect->width - (line.exts.width >> 16); else if (format & TF_CENTER) @@ -304,6 +304,8 @@ main(int argc, char *argv[]) glMatrixMode (GL_MODELVIEW); glLoadIdentity (); + glScalef (alpha + 1.0, alpha + 1.0, 1.0); + TextColor color; color.r = 255; color.g = 0; |