Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/sfont/glfont.c @ 3457

Last change on this file since 3457 was 3457, checked in by bensch, 19 years ago

orxonox/trunk: added new File glfont.c that will be modified, so it can display any ttf font

also included libSDL_ttf into configure. this enables the use of any ttf font as mentioned by konfuzzius in orxonox-dev mail 266.

File size: 10.5 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14
15   ***
16   * This file is extended to the needs of the orxonox-project.         *
17   * the Copyright of the original file is below this copyright         *
18   *                                                                  ***
19
20*/
21
22/*
23    glfont:  An example of using the SDL_ttf library with OpenGL.
24    Copyright (C) 1997-2004 Sam Lantinga
25
26    This library is free software; you can redistribute it and/or
27    modify it under the terms of the GNU Library General Public
28    License as published by the Free Software Foundation; either
29    version 2 of the License, or (at your option) any later version.
30
31    This library is distributed in the hope that it will be useful,
32    but WITHOUT ANY WARRANTY; without even the implied warranty of
33    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
34    Library General Public License for more details.
35
36    You should have received a copy of the GNU Library General Public
37    License along with this library; if not, write to the Free
38    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
39
40    The SDL_GL_* functions in this file are available in the public domain.
41
42    Sam Lantinga
43    slouken@libsdl.org
44*/
45
46/* $Id: glfont.c,v 1.6 2004/01/04 17:41:55 slouken Exp $ */
47
48/* A simple program to test the text rendering feature of the TTF library */
49
50#include <stdlib.h>
51#include <stdio.h>
52#include <string.h>
53
54#include <SDL/SDL.h>
55#include <SDL/SDL_ttf.h>
56
57#include "../glincl.h"
58
59#define DEFAULT_PTSIZE  18
60#define DEFAULT_TEXT    "orxonox 1234567890"
61#define NUM_COLORS      256
62
63static char *Usage =
64"Usage: %s [-utf8|-unicode] [-b] [-i] [-u] [-fgcol r,g,b] [-bgcol r,g,b] \
65<font>.ttf [ptsize] [text]\n";
66
67void SDL_GL_Enter2DMode()
68{
69        SDL_Surface *screen = SDL_GetVideoSurface();
70
71        /* Note, there may be other things you need to change,
72           depending on how you have your OpenGL state set up.
73        */
74        glPushAttrib(GL_ENABLE_BIT);
75        glDisable(GL_DEPTH_TEST);
76        glDisable(GL_CULL_FACE);
77        glEnable(GL_TEXTURE_2D);
78
79        /* This allows alpha blending of 2D textures with the scene */
80        glEnable(GL_BLEND);
81        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
82
83        glViewport(0, 0, screen->w, screen->h);
84
85        glMatrixMode(GL_PROJECTION);
86        glPushMatrix();
87        glLoadIdentity();
88
89        glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
90
91        glMatrixMode(GL_MODELVIEW);
92        glPushMatrix();
93        glLoadIdentity();
94
95        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
96}
97
98void SDL_GL_Leave2DMode()
99{
100        glMatrixMode(GL_MODELVIEW);
101        glPopMatrix();
102
103        glMatrixMode(GL_PROJECTION);
104        glPopMatrix();
105
106        glPopAttrib();
107}
108
109/* Quick utility function for texture creation */
110static int power_of_two(int input)
111{
112        int value = 1;
113
114        while ( value < input ) {
115                value <<= 1;
116        }
117        return value;
118}
119
120GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord)
121{
122        GLuint texture;
123        int w, h;
124        SDL_Surface *image;
125        SDL_Rect area;
126        Uint32 saved_flags;
127        Uint8  saved_alpha;
128
129        /* Use the surface width and height expanded to powers of 2 */
130        w = power_of_two(surface->w);
131        h = power_of_two(surface->h);
132        texcoord[0] = 0.0f;                     /* Min X */
133        texcoord[1] = 0.0f;                     /* Min Y */
134        texcoord[2] = (GLfloat)surface->w / w;  /* Max X */
135        texcoord[3] = (GLfloat)surface->h / h;  /* Max Y */
136
137        image = SDL_CreateRGBSurface(
138                        SDL_SWSURFACE,
139                        w, h,
140                        32,
141#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
142                        0x000000FF, 
143                        0x0000FF00, 
144                        0x00FF0000, 
145                        0xFF000000
146#else
147                        0xFF000000,
148                        0x00FF0000, 
149                        0x0000FF00, 
150                        0x000000FF
151#endif
152                       );
153        if ( image == NULL ) {
154                return 0;
155        }
156
157        /* Save the alpha blending attributes */
158        saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
159        saved_alpha = surface->format->alpha;
160        if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
161                SDL_SetAlpha(surface, 0, 0);
162        }
163
164        /* Copy the surface into the GL texture image */
165        area.x = 0;
166        area.y = 0;
167        area.w = surface->w;
168        area.h = surface->h;
169        SDL_BlitSurface(surface, &area, image, &area);
170
171        /* Restore the alpha blending attributes */
172        if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
173                SDL_SetAlpha(surface, saved_flags, saved_alpha);
174        }
175
176        /* Create an OpenGL texture for the image */
177        glGenTextures(1, &texture);
178        glBindTexture(GL_TEXTURE_2D, texture);
179        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
180        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
181        glTexImage2D(GL_TEXTURE_2D,
182                     0,
183                     GL_RGBA,
184                     w, h,
185                     0,
186                     GL_RGBA,
187                     GL_UNSIGNED_BYTE,
188                     image->pixels);
189        SDL_FreeSurface(image); /* No longer needed */
190
191        return texture;
192}
193
194int setup(int argc, char *argv[])
195{
196        char *argv0 = argv[0];
197        SDL_Surface *screen;
198        TTF_Font *font;
199        SDL_Surface *text;
200        int ptsize;
201        int i, done;
202        SDL_Color white = { 0xFF, 0xFF, 0xFF, 0 };
203        SDL_Color black = { 0x00, 0x00, 0x00, 0 };
204        SDL_Color *forecol;
205        SDL_Color *backcol;
206        GLenum gl_error;
207        GLuint texture;
208        int x, y, w, h;
209        GLfloat texcoord[4];
210        GLfloat texMinX, texMinY;
211        GLfloat texMaxX, texMaxY;
212
213        int renderstyle;
214        int dump;
215        enum {
216                RENDER_LATIN1,
217                RENDER_UTF8,
218                RENDER_UNICODE
219        } rendertype;
220        char *message;
221
222        /* Look for special execution mode */
223        dump = 0;
224        /* Look for special rendering types */
225        renderstyle = TTF_STYLE_NORMAL;
226        rendertype = RENDER_LATIN1;
227        /* Default is black and white */
228        forecol = &black;
229        backcol = &white;
230        for ( i=1; argv[i] && argv[i][0] == '-'; ++i ) {
231                if ( strcmp(argv[i], "-utf8") == 0 ) {
232                        rendertype = RENDER_UTF8;
233                } else
234                if ( strcmp(argv[i], "-unicode") == 0 ) {
235                        rendertype = RENDER_UNICODE;
236                } else
237                if ( strcmp(argv[i], "-b") == 0 ) {
238                        renderstyle |= TTF_STYLE_BOLD;
239                } else
240                if ( strcmp(argv[i], "-i") == 0 ) {
241                        renderstyle |= TTF_STYLE_ITALIC;
242                } else
243                if ( strcmp(argv[i], "-u") == 0 ) {
244                        renderstyle |= TTF_STYLE_UNDERLINE;
245                } else
246                if ( strcmp(argv[i], "-dump") == 0 ) {
247                        dump = 1;
248                } else
249                if ( strcmp(argv[i], "-fgcol") == 0 ) {
250                        int r, g, b;
251                        if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) {
252                                fprintf(stderr, Usage, argv0);
253                                return(1);
254                        }
255                        forecol->r = (Uint8)r;
256                        forecol->g = (Uint8)g;
257                        forecol->b = (Uint8)b;
258                } else
259                if ( strcmp(argv[i], "-bgcol") == 0 ) {
260                        int r, g, b;
261                        if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) {
262                                fprintf(stderr, Usage, argv0);
263                                return(1);
264                        }
265                        backcol->r = (Uint8)r;
266                        backcol->g = (Uint8)g;
267                        backcol->b = (Uint8)b;
268                } else {
269                        fprintf(stderr, Usage, argv0);
270                        return(1);
271                }
272        }
273        argv += i;
274        argc -= i;
275
276        /* Check usage */
277        if ( ! argv[0] ) {
278                fprintf(stderr, Usage, argv0);
279                return(1);
280        }
281
282        /* Initialize SDL */
283        if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
284                fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
285                return(2);
286        }
287        atexit(SDL_Quit);
288
289        /* Initialize the TTF library */
290        if ( TTF_Init() < 0 ) {
291                fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());
292                return(2);
293        }
294        atexit(TTF_Quit);
295
296        /* Open the font file with the requested point size */
297        ptsize = 0;
298        if ( argc > 1 ) {
299                ptsize = atoi(argv[1]);
300        }
301        if ( ptsize == 0 ) {
302                i = 2;
303                ptsize = DEFAULT_PTSIZE;
304        } else {
305                i = 3;
306        }
307        font = TTF_OpenFont(argv[0], ptsize);
308        if ( font == NULL ) {
309                fprintf(stderr, "Couldn't load %d pt font from %s: %s\n",
310                                        ptsize, argv[0], SDL_GetError());
311                return(2);
312        }
313        TTF_SetFontStyle(font, renderstyle);
314
315        if( dump ) {
316
317                for( i = 48; i < 123; i++ ) {
318                        SDL_Surface* glyph = NULL;
319
320                        glyph = TTF_RenderGlyph_Shaded( font, i, *forecol, *backcol );
321
322                        if( glyph ) {
323                                char outname[64];
324                                sprintf( outname, "glyph-%d.bmp", i );
325                                SDL_SaveBMP( glyph, outname );
326                        }
327
328                }
329
330                return( 0 );
331        }
332
333        /* Set a 640x480 video mode */
334        screen = SDL_SetVideoMode(640, 480, 0, SDL_OPENGL);
335        if ( screen == NULL ) {
336                fprintf(stderr, "Couldn't set 640x480 OpenGL mode: %s\n",
337                                                        SDL_GetError());
338                return(2);
339        }
340
341        /* Render and center the message */
342        if ( argc > 2 ) {
343                message = argv[2];
344        } else {
345                message = DEFAULT_TEXT;
346        }
347        switch (rendertype) {
348            case RENDER_LATIN1:
349                text = TTF_RenderText_Blended(font, message, *forecol);
350                break;
351
352            case RENDER_UTF8:
353                text = TTF_RenderUTF8_Blended(font, message, *forecol);
354                break;
355
356            case RENDER_UNICODE:
357                {
358                        /* This doesn't actually work because you can't pass
359                           UNICODE text in via command line, AFAIK, but...
360                         */
361                        Uint16 unicode_text[BUFSIZ];
362                        int index;
363                        for ( index = 0; (message[0] || message[1]); ++index ) {
364                                unicode_text[index]  = ((Uint8 *)message)[0];
365                                unicode_text[index] <<= 8;
366                                unicode_text[index] |= ((Uint8 *)message)[1];
367                                message += 2;
368                        }
369                        text = TTF_RenderUNICODE_Blended(font,
370                                        unicode_text, *forecol);
371                }
372                break;
373            default:
374                text = NULL; /* This shouldn't happen */
375                break;
376        }
377        if ( text == NULL ) {
378                fprintf(stderr, "Couldn't render text: %s\n", SDL_GetError());
379                TTF_CloseFont(font);
380                return(2);
381        }
382        x = (screen->w - text->w)/2;
383        y = (screen->h - text->h)/2;
384        w = text->w;
385        h = text->h;
386        printf("Font is generally %d big, and string is %hd big\n",
387                                                TTF_FontHeight(font), text->h);
388
389        /* Convert the text into an OpenGL texture */
390        glGetError();
391        texture = SDL_GL_LoadTexture(text, texcoord);
392        if ( (gl_error = glGetError()) != GL_NO_ERROR ) {
393                /* If this failed, the text may exceed texture size limits */
394                printf("Warning: Couldn't create texture: 0x%x\n", gl_error);
395        }
396
397        /* Make texture coordinates easy to understand */
398        texMinX = texcoord[0];
399        texMinY = texcoord[1];
400        texMaxX = texcoord[2];
401        texMaxY = texcoord[3];
402
403        /* We don't need the original text surface anymore */
404        SDL_FreeSurface(text);
405
406        /* Initialize the GL state */
407        glViewport( 0, 0, screen->w, screen->h );
408        glMatrixMode( GL_PROJECTION );
409        glLoadIdentity( );
410
411        glOrtho( -2.0, 2.0, -2.0, 2.0, -20.0, 20.0 );
412
413        glMatrixMode( GL_MODELVIEW );
414        glLoadIdentity( );
415
416        glEnable(GL_DEPTH_TEST);
417
418        glDepthFunc(GL_LESS);
419
420        glShadeModel(GL_SMOOTH);
421
422        /* Wait for a keystroke, and blit text on mouse press */
423        done = 0;
424        while ( ! done ) {
425
426          /* Show the text on the screen */
427          SDL_GL_Enter2DMode();
428          glBindTexture(GL_TEXTURE_2D, texture);
429          glBegin(GL_QUADS);
430          glTexCoord2f(texMinX, texMinY); glVertex2i(x,   y  );
431          glTexCoord2f(texMaxX, texMinY); glVertex2i(x+w, y  );
432          glTexCoord2f(texMinX, texMaxY); glVertex2i(x,   y+h);
433          glTexCoord2f(texMaxX, texMaxY); glVertex2i(x+w, y+h);
434          glEnd();
435          SDL_GL_Leave2DMode();
436         
437          /* Swap the buffers so everything is visible */
438          SDL_GL_SwapBuffers( );
439        }
440        TTF_CloseFont(font);
441        return(0);
442}
443
Note: See TracBrowser for help on using the repository browser.