source: trunk/src/font.cpp @ 269

Last change on this file since 269 was 269, checked in by sam, 10 years ago

Convert NPOT textures in code.

  • Property svn:keywords set to Id
File size: 4.1 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://sam.zoy.org/projects/COPYING.WTFPL for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#ifdef WIN32
16#   define WIN32_LEAN_AND_MEAN
17#   include <windows.h>
18#endif
19#if defined __APPLE__ && defined __MACH__
20#   include <OpenGL/gl.h>
21#else
22#   define GL_GLEXT_PROTOTYPES
23#   include <GL/gl.h>
24#endif
25
26#include <SDL.h>
27#include <SDL_image.h>
28
29#include "core.h"
30
31/*
32 * Font implementation class
33 */
34
35class FontData
36{
37    friend class Font;
38
39private:
40    char *name;
41
42    SDL_Surface *img;
43    int width, height;
44    GLuint texture;
45};
46
47/*
48 * Public Font class
49 */
50
51Font::Font(char const *path)
52  : data(new FontData())
53{
54    data->name = strdup(path);
55    data->img = NULL;
56
57    for (char const *name = path; *name; name++)
58        if ((data->img = IMG_Load(name)))
59            break;
60
61    if (!data->img)
62    {
63        SDL_Quit();
64        exit(1);
65    }
66
67    drawgroup = DRAWGROUP_BEFORE;
68}
69
70Font::~Font()
71{
72    delete data;
73}
74
75void Font::TickDraw(float deltams)
76{
77    Entity::TickDraw(deltams);
78
79    if (destroy)
80    {
81        if (data->img)
82            SDL_FreeSurface(data->img);
83        else
84            glDeleteTextures(1, &data->texture);
85    }
86    else if (data->img)
87    {
88        data->width = data->img->w / 16;
89        data->height = data->img->h / 16;
90
91        GLuint format = data->img->format->Amask ? GL_RGBA : GL_RGB;
92        int planes = data->img->format->Amask ? 4 : 3;
93
94        int w = PotUp(data->img->w);
95        int h = PotUp(data->img->h);
96
97        uint8_t *pixels = (uint8_t *)data->img->pixels;
98        if (w != data->img->w || h != data->img->h)
99        {
100            uint8_t *tmp = (uint8_t *)malloc(planes * w * h);
101            for (int line = 0; line < data->img->h; line++)
102                memcpy(tmp + planes * w * line,
103                       pixels + planes * data->img->w * line,
104                       planes * data->img->w);
105            pixels = tmp;
106        }
107
108        glGenTextures(1, &data->texture);
109        glBindTexture(GL_TEXTURE_2D, data->texture);
110
111        glTexImage2D(GL_TEXTURE_2D, 0, planes, w, h, 0,
112                     format, GL_UNSIGNED_BYTE, pixels);
113
114        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
115        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
116
117        if (pixels != data->img->pixels)
118            free(pixels);
119        SDL_FreeSurface(data->img);
120        data->img = NULL;
121    }
122}
123
124char const *Font::GetName()
125{
126    return data->name;
127}
128
129void Font::Print(int x, int y, char const *str)
130{
131    if (data->img)
132        return;
133
134    glBindTexture(GL_TEXTURE_2D, data->texture);
135    glBegin(GL_QUADS);
136    while (*str)
137    {
138        uint32_t ch = (uint8_t)*str++;
139        float tx = .0625f * (ch & 0xf);
140        float ty = .0625f * ((ch >> 4) & 0xf);
141
142        if (ch != ' ')
143        {
144            glTexCoord2f(tx, ty + .0625f);
145            glVertex2f(x, y);
146            glTexCoord2f(tx + .0625f, ty + .0625f);
147            glVertex2f(x + data->width, y);
148            glTexCoord2f(tx + .0625f, ty);
149            glVertex2f(x + data->width, y + data->height);
150            glTexCoord2f(tx, ty);
151            glVertex2f(x, y + data->height);
152        }
153
154        x += data->width;
155    }
156    glEnd();
157}
158
159void Font::PrintBold(int x, int y, char const *str)
160{
161    static struct { int dx, dy; float r, g, b; } tab[] =
162    {
163        { -1,  0, 0.0, 0.0, 0.0 },
164        {  0, -1, 0.0, 0.0, 0.0 },
165        {  0,  1, 0.0, 0.0, 0.0 },
166        {  1, -1, 0.0, 0.0, 0.0 },
167        {  1,  1, 0.0, 0.0, 0.0 },
168        {  2,  0, 0.0, 0.0, 0.0 },
169        {  1,  0, 0.5, 0.5, 0.5 },
170        {  0,  0, 1.0, 1.0, 1.0 },
171    };
172
173    if (data->img)
174        return;
175
176    glPushAttrib(GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT);
177    for (unsigned int i = 0; i < sizeof(tab) / sizeof(*tab); i++)
178    {
179        glColor3f(tab[i].r, tab[i].g, tab[i].b);
180        Print(x + tab[i].dx, y + tab[i].dy, str);
181    }
182    glPopAttrib();
183}
184
Note: See TracBrowser for help on using the repository browser.