Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/lib/graphics/font/glfont.cc @ 3715

Last change on this file since 3715 was 3478, checked in by patrick, 20 years ago

orxonox/trunk: fixed font leak and removed sfont again

File size: 11.8 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#include "glfont.h"
47
48
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#include "../debug.h"
59
60
61#define DEFAULT_PTSIZE  18
62#define DEFAULT_TEXT    "orxonox 1234567890"
63#define NUM_COLORS      256
64
65
66
67GLFont::GLFont()
68{
69  this->init("");
70
71}
72GLFont::GLFont(const char* fontFile)
73{
74  this->init(fontFile);
75}
76GLFont::~GLFont()
77{
78 
79}
80
81bool GLFont::init(const char* fontFile)
82{
83  // setting default values.
84  renderStyle = TTF_STYLE_NORMAL;
85
86
87  // Initializing lib-TTF if necesary.
88  if (TTF_WasInit() && TTF_Init() < 0 ) 
89    {
90      PRINTF(1)("Couldn't initialize TTF: %s\n", SDL_GetError());
91      return false;
92    }
93}
94
95bool GLFont::ttfInitialized = false;
96
97bool GLFont::setFont(const char* fonFile)
98{
99
100}
101void GLFont::setText(const char* text)
102{
103
104}
105
106void GLFont::setStyle(char* style)
107{
108  renderStyle = TTF_STYLE_NORMAL;
109 
110  for (int i = 0; i < strlen(style); i++)
111    if (strncmp(style+i, "b", 1) == 0) 
112      this->renderStyle |= TTF_STYLE_BOLD;
113    else if (strncmp(style+i, "i", 1) == 0)
114      this->renderStyle |= TTF_STYLE_ITALIC;
115    else if (strncmp(style+i, "u", 1) == 0) 
116      this->renderStyle |= TTF_STYLE_UNDERLINE;
117
118  // TTF_SetFontStyle(font, renderstyle);
119
120}
121void GLFont::setSize(void)
122{
123
124}
125void GLFont::setPosition(int x, int y)
126{
127
128}
129
130void GLFont::renderText(void)
131{
132
133}
134void GLFont::renderText(const char* text, int x, int y)
135{
136  // enter the 2D-Mode
137
138  SDL_Surface *screen = SDL_GetVideoSurface();
139 
140  /* Note, there may be other things you need to change,
141     depending on how you have your OpenGL state set up.
142  */
143  glPushAttrib(GL_ENABLE_BIT);
144  glDisable(GL_DEPTH_TEST);
145  glDisable(GL_CULL_FACE);
146  glEnable(GL_TEXTURE_2D);
147 
148  /* This allows alpha blending of 2D textures with the scene */
149  glEnable(GL_BLEND);
150  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
151 
152  glViewport(0, 0, screen->w, screen->h);
153 
154  glMatrixMode(GL_PROJECTION);
155  glPushMatrix();
156  glLoadIdentity();
157 
158  glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
159 
160  glMatrixMode(GL_MODELVIEW);
161  glPushMatrix();
162  glLoadIdentity();
163 
164  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
165
166
167
168
169
170  // Leave the 2D-Mode
171  glMatrixMode(GL_MODELVIEW);
172  glPopMatrix();
173 
174  glMatrixMode(GL_PROJECTION);
175  glPopMatrix();
176 
177  glPopAttrib();
178}
179
180
181bool GLFont::loadTexture()
182{
183  int w, h;
184  SDL_Surface *image;
185  SDL_Rect area;
186  Uint32 saved_flags;
187  Uint8  saved_alpha;
188 
189  /* Use the surface width and height expanded to powers of 2 */
190  w = powerOfTwo(surface->w);
191  h = powerOfTwo(surface->h);
192  texcoord[0] = 0.0f;                   /* Min X */
193  texcoord[1] = 0.0f;                   /* Min Y */
194  texcoord[2] = (GLfloat)surface->w / w;        /* Max X */
195  texcoord[3] = (GLfloat)surface->h / h;        /* Max Y */
196 
197  image = SDL_CreateRGBSurface(
198                               SDL_SWSURFACE,
199                               w, h,
200                               32,
201#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
202                               0x000000FF, 
203                               0x0000FF00, 
204                               0x00FF0000, 
205                               0xFF000000
206#else
207                               0xFF000000,
208                               0x00FF0000, 
209                               0x0000FF00, 
210                               0x000000FF
211#endif
212                               );
213  if ( image == NULL ) {
214    return 0;
215  }
216 
217  /* Save the alpha blending attributes */
218  saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
219  saved_alpha = surface->format->alpha;
220  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
221    SDL_SetAlpha(surface, 0, 0);
222  }
223 
224  /* Copy the surface into the GL texture image */
225  area.x = 0;
226  area.y = 0;
227  area.w = surface->w;
228  area.h = surface->h;
229  SDL_BlitSurface(surface, &area, image, &area);
230 
231  /* Restore the alpha blending attributes */
232  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
233    SDL_SetAlpha(surface, saved_flags, saved_alpha);
234  }
235 
236  /* Create an OpenGL texture for the image */
237  glGenTextures(1, &texture);
238  glBindTexture(GL_TEXTURE_2D, texture);
239  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
240  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
241  glTexImage2D(GL_TEXTURE_2D,
242               0,
243               GL_RGBA,
244               w, h,
245               0,
246               GL_RGBA,
247               GL_UNSIGNED_BYTE,
248               image->pixels);
249  SDL_FreeSurface(image); /* No longer needed */
250 
251  //  return texture;
252}
253
254/* Quick utility function for texture creation */
255int GLFont::powerOfTwo(int input)
256{
257  int value = 1;
258 
259  while ( value < input ) {
260    value <<= 1;
261  }
262  return value;
263}
264
265
266/*
267private:
268char* fontFile;
269char* text;
270int positionX;
271int positionY;
272*/
273
274
275
276
277char Usage[100] = "orxonox test" ;
278void SDL_GL_Enter2DMode()
279{
280}
281
282void SDL_GL_Leave2DMode()
283{
284}
285
286/* Quick utility function for texture creation */
287static int power_of_two(int input)
288{
289}
290
291
292
293GLuint SDL_GL_LoadTexture(SDL_Surface *surface, GLfloat *texcoord)
294{
295
296}
297
298int setup(int argc, char *argv[])
299{
300        char *argv0 = argv[0];
301        SDL_Surface *screen;
302        TTF_Font *font;
303        SDL_Surface *text;
304        int ptsize;
305        int i, done;
306        SDL_Color white = { 0xFF, 0xFF, 0xFF, 0 };
307        SDL_Color black = { 0x00, 0x00, 0x00, 0 };
308        SDL_Color *forecol;
309        SDL_Color *backcol;
310        GLenum gl_error;
311        GLuint texture;
312        int x, y, w, h;
313        GLfloat texcoord[4];
314        GLfloat texMinX, texMinY;
315        GLfloat texMaxX, texMaxY;
316
317        int renderstyle;
318        int dump;
319        enum {
320                RENDER_LATIN1,
321                RENDER_UTF8,
322                RENDER_UNICODE
323        } rendertype;
324        char *message;
325
326        /* Look for special execution mode */
327        dump = 0;
328        /* Look for special rendering types */
329        rendertype = RENDER_LATIN1;
330        /* Default is black and white */
331        forecol = &black;
332        backcol = &white;
333        for ( i=1; argv[i] && argv[i][0] == '-'; ++i ) {
334                if ( strcmp(argv[i], "-utf8") == 0 ) {
335                        rendertype = RENDER_UTF8;
336                } else
337                if ( strcmp(argv[i], "-unicode") == 0 ) {
338                        rendertype = RENDER_UNICODE;
339                } else
340                if ( strcmp(argv[i], "-b") == 0 ) {
341                        renderstyle |= TTF_STYLE_BOLD;
342                } else
343                if ( strcmp(argv[i], "-i") == 0 ) {
344                        renderstyle |= TTF_STYLE_ITALIC;
345                } else
346                if ( strcmp(argv[i], "-u") == 0 ) {
347                        renderstyle |= TTF_STYLE_UNDERLINE;
348                } else
349                if ( strcmp(argv[i], "-dump") == 0 ) {
350                        dump = 1;
351                } else
352                if ( strcmp(argv[i], "-fgcol") == 0 ) {
353                        int r, g, b;
354                        if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) {
355                                fprintf(stderr, Usage, argv0);
356                                return(1);
357                        }
358                        forecol->r = (Uint8)r;
359                        forecol->g = (Uint8)g;
360                        forecol->b = (Uint8)b;
361                } else
362                if ( strcmp(argv[i], "-bgcol") == 0 ) {
363                        int r, g, b;
364                        if ( sscanf (argv[++i], "%d,%d,%d", &r, &g, &b) != 3 ) {
365                                fprintf(stderr, Usage, argv0);
366                                return(1);
367                        }
368                        backcol->r = (Uint8)r;
369                        backcol->g = (Uint8)g;
370                        backcol->b = (Uint8)b;
371                } else {
372                        fprintf(stderr, Usage, argv0);
373                        return(1);
374                }
375        }
376        argv += i;
377        argc -= i;
378
379        /* Check usage */
380        if ( ! argv[0] ) {
381                fprintf(stderr, Usage, argv0);
382                return(1);
383        }
384
385        /* Initialize SDL */
386        if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
387                fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
388                return(2);
389        }
390        atexit(SDL_Quit);
391
392        /* Initialize the TTF library */
393        if ( TTF_Init() < 0 ) {
394                fprintf(stderr, "Couldn't initialize TTF: %s\n",SDL_GetError());
395                return(2);
396        }
397        atexit(TTF_Quit);
398
399        /* Open the font file with the requested point size */
400        ptsize = 0;
401        if ( argc > 1 ) {
402                ptsize = atoi(argv[1]);
403        }
404        if ( ptsize == 0 ) {
405                i = 2;
406                ptsize = DEFAULT_PTSIZE;
407        } else {
408                i = 3;
409        }
410        font = TTF_OpenFont(argv[0], ptsize);
411        if ( font == NULL ) {
412                fprintf(stderr, "Couldn't load %d pt font from %s: %s\n",
413                                        ptsize, argv[0], SDL_GetError());
414                return(2);
415        }
416
417        if( dump ) {
418
419                for( i = 48; i < 123; i++ ) {
420                        SDL_Surface* glyph = NULL;
421
422                        glyph = TTF_RenderGlyph_Shaded( font, i, *forecol, *backcol );
423
424                        if( glyph ) {
425                                char outname[64];
426                                sprintf( outname, "glyph-%d.bmp", i );
427                                SDL_SaveBMP( glyph, outname );
428                        }
429
430                }
431
432                return( 0 );
433        }
434
435        /* Set a 640x480 video mode */
436        screen = SDL_SetVideoMode(640, 480, 0, SDL_OPENGL);
437        if ( screen == NULL ) {
438                fprintf(stderr, "Couldn't set 640x480 OpenGL mode: %s\n",
439                                                        SDL_GetError());
440                return(2);
441        }
442
443        /* Render and center the message */
444        if ( argc > 2 ) {
445                message = argv[2];
446        } else {
447                message = DEFAULT_TEXT;
448        }
449        switch (rendertype) {
450            case RENDER_LATIN1:
451                text = TTF_RenderText_Blended(font, message, *forecol);
452                break;
453
454            case RENDER_UTF8:
455                text = TTF_RenderUTF8_Blended(font, message, *forecol);
456                break;
457
458            case RENDER_UNICODE:
459                {
460                        /* This doesn't actually work because you can't pass
461                           UNICODE text in via command line, AFAIK, but...
462                         */
463                        Uint16 unicode_text[BUFSIZ];
464                        int index;
465                        for ( index = 0; (message[0] || message[1]); ++index ) {
466                                unicode_text[index]  = ((Uint8 *)message)[0];
467                                unicode_text[index] <<= 8;
468                                unicode_text[index] |= ((Uint8 *)message)[1];
469                                message += 2;
470                        }
471                        text = TTF_RenderUNICODE_Blended(font,
472                                        unicode_text, *forecol);
473                }
474                break;
475            default:
476                text = NULL; /* This shouldn't happen */
477                break;
478        }
479        if ( text == NULL ) {
480                fprintf(stderr, "Couldn't render text: %s\n", SDL_GetError());
481                TTF_CloseFont(font);
482                return(2);
483        }
484        x = (screen->w - text->w)/2;
485        y = (screen->h - text->h)/2;
486        w = text->w;
487        h = text->h;
488        printf("Font is generally %d big, and string is %hd big\n",
489                                                TTF_FontHeight(font), text->h);
490
491        /* Convert the text into an OpenGL texture */
492        glGetError();
493        texture = SDL_GL_LoadTexture(text, texcoord);
494        if ( (gl_error = glGetError()) != GL_NO_ERROR ) {
495                /* If this failed, the text may exceed texture size limits */
496                printf("Warning: Couldn't create texture: 0x%x\n", gl_error);
497        }
498
499        /* Make texture coordinates easy to understand */
500        texMinX = texcoord[0];
501        texMinY = texcoord[1];
502        texMaxX = texcoord[2];
503        texMaxY = texcoord[3];
504
505        /* We don't need the original text surface anymore */
506        SDL_FreeSurface(text);
507
508        /* Initialize the GL state */
509        glViewport( 0, 0, screen->w, screen->h );
510        glMatrixMode( GL_PROJECTION );
511        glLoadIdentity( );
512
513        glOrtho( -2.0, 2.0, -2.0, 2.0, -20.0, 20.0 );
514
515        glMatrixMode( GL_MODELVIEW );
516        glLoadIdentity( );
517
518        glEnable(GL_DEPTH_TEST);
519
520        glDepthFunc(GL_LESS);
521
522        glShadeModel(GL_SMOOTH);
523
524        /* Wait for a keystroke, and blit text on mouse press */
525        done = 0;
526        while ( ! done ) {
527
528          /* Show the text on the screen */
529          SDL_GL_Enter2DMode();
530          glBindTexture(GL_TEXTURE_2D, texture);
531          glBegin(GL_QUADS);
532          glTexCoord2f(texMinX, texMinY); glVertex2i(x,   y  );
533          glTexCoord2f(texMaxX, texMinY); glVertex2i(x+w, y  );
534          glTexCoord2f(texMinX, texMaxY); glVertex2i(x,   y+h);
535          glTexCoord2f(texMaxX, texMaxY); glVertex2i(x+w, y+h);
536          glEnd();
537          SDL_GL_Leave2DMode();
538         
539          /* Swap the buffers so everything is visible */
540          SDL_GL_SwapBuffers( );
541        }
542        TTF_CloseFont(font);
543        return(0);
544}
545
Note: See TracBrowser for help on using the repository browser.