OpenGL ES texture fonts

http://www.allegro.cc/forums/thread/599388

I would like to implement texture fonts in OpenGL ES. Is it possible to use GL_ALPHA textures? They are more space efficient than GL_RGBA. Is it possible to color the text when using GL_ALPHA textures? How? Could you send a sample code?


OpenGL ES support GL_ALPHA. It's then up to the OpenGL ES driver whether the texture you've supplied in GL_ALPHA form remains so, which will depend on whether your GPU supports GL_ALPHA. I believe that the PowerVR in the iPhone does (and can confirm that the example texture class provided by Apple uploads as GL_ALPHA when you load a suitable PNG or supply data tagged as being of that format), otherwise I'm not very certain.

Colour text using GL_ALPHA in OpenGL ES almost exactly as you would with normal OpenGL. So, for example, set the texture environment mode to 'modulate':

  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

Then subsequently use calls to glColor4f (the number of combinations and permutations of glColor is reduced in OpenGL ES) to set the colour of the next string. Alternatively, supply something to glColorPointer (either directly supply data, or use the connected vertex buffer object (VBO) measures) if you want to specify colour per-vertex.

Just on the off chance that you are targetting the iPhone (my guess is that it is currently the most targetted OpenGL ES platform, but I'm fully aware that there are several other OpenGL ES platforms that are viable), note that the implementation of VBOs means that using them doesn't provide anything even close to the speed boost you'd get for switching on a conventional desktop target. There are some minor throughput increases, but definitely if you're starting out then don't worry about them now. The speed difference isn't very great, and you can worry about them later in the day — they're an extension that is easy to patch on to existing code.

EDIT:
Oh! Sample code! If you'll excuse the higgledy-piggledy blend of C++ and Objective-C:

1#include "Text.h"
2 
3CRotoText *TextWriter;
4Texture2D *TextSheet;
5 
6#define NUM_GLYPHS 44
7 
8struct Glyph
9{
10CVertexArray *Vertices;
11CTexCoordArray *TexCoords;
12float Width;
13} Glyphs[NUM_GLYPHS];
14 
15CRotoText::CRotoText()
16{
17TextSheet = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"font.png"]];
18[TextSheet Activate];
19glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
20glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
21 
22int Coords[NUM_GLYPHS][4] =
23{
24/* numbers 0 - 9 */
25{1, 14, 4, 18},
26{6, 14, 8, 18},
27{10, 14, 13, 18},
28{15, 14, 18, 18},
29{20, 14, 23, 18},
30{25, 14, 28, 18},
31{30, 14, 33, 18},
32{35, 14, 38, 18},
33{40, 14, 43, 18},
34{45, 14, 48, 18},
35 
36/* letters a - m */
37{1, 1, 4, 5},
38{6, 1, 9, 5},
39{11, 1, 14, 5},
40{16, 1, 19, 5},
41{21, 1, 23, 5},
42{25, 1, 27, 5},
43{29, 1, 32, 5},
44{34, 1, 37, 5},
45{40, 1, 40, 5},
46{43, 1, 46, 5},
47{48, 1, 51, 5},
48{53, 1, 55, 5},
49{57, 1, 61, 5},
50 
51/* letters n - z */
52{1, 7, 5, 11},
53{7, 7, 10, 11},
54{12, 7, 15, 11},
55{17, 7, 20, 12},
56{22, 7, 25, 11},
57{27, 7, 30, 11},
58{32, 7, 34, 11},
59{36, 7, 39, 11},
60{41, 7, 45, 11},
61{50, 14, 54, 18},
62{47, 7, 51, 11},
63{53, 7, 57, 11},
64{59, 7, 61, 11},
65 
66/* dot, semi-colon, space, exclamation mark, question mark, apostrophe */
67{56, 14, 56, 18},
68{58, 14, 58, 18},
69{1, 20, 3, 24},
70{60, 14, 60, 18},
71{58, 20, 60, 24},
72{54, 20, 54, 21},
73{50, 20, 52, 22},
74{46, 20, 47, 25},
75};
76int c = NUM_GLYPHS;
77while(c--)
78{
79GLfloat Positions[8] = {0, 0}, TexCoords[8];
80 
81Positions[0] =
82Positions[2] = (GLfloat)(1+Coords[c][2] - Coords[c][0]) / 64.0;
83Positions[3] =
84Positions[7] = 0;
85 
86Positions[4] =
87Positions[6] = 0;
88Positions[1] =
89Positions[5] = -(GLfloat)(1+Coords[c][3] - Coords[c][1]) / 32.0;
90 
91TexCoords[4] =
92TexCoords[6] = ((GLfloat)Coords[c][0] ) / 64.0;
93TexCoords[3] =
94TexCoords[7] = ((GLfloat)Coords[c][1] ) / 32.0;
95 
96TexCoords[0] =
97TexCoords[2] = ((GLfloat)Coords[c][2] + 1) / 64.0;
98TexCoords[1] =
99TexCoords[5] = ((GLfloat)Coords[c][3] + 1) / 32.0;
100 
101Glyphs[c].Vertices = new CVertexArray(2, GL_FLOAT, Positions, 4);
102Glyphs[c].TexCoords = new CTexCoordArray(2, GL_FLOAT, TexCoords, 4);
103Glyphs[c].Width = Positions[0] + 1.0/64.0;
104}
105}
106 
107CRotoText::~CRotoText()
108{
109[TextSheet release];
110}
111 
112int CRotoText::GetGlyph(char t)
113{
114if(t >= 48 && t < 58) return t - 48;
115t = toupper(t);
116if(t >= 65 && t < 91) return t - 55;
117 
118switch(t)
119{
120default: return -1;
121case '.': return 36;
122case ':': return 37;
123case ' ': return 38;
124case '!': return 39;
125case '?': return 40;
126case '/'': return 41;
127case '-': return 42;
128case ',': return 43;
129}
130}
131 
132 
133void CRotoText::WriteString(char *fmt, ...)
134{
135char Buffer[2048];
136va_list varg;
137 
138va_start(varg, fmt);
139vsnprintf(Buffer, 2048, fmt, varg);
140va_end(varg);
141 
142char *P = Buffer;
143[TextSheet Activate];
144glPushMatrix();
145glScalef(1, 0.5, 1);
146while(*P)
147{
148int ToPrint = GetGlyph(*P);
149 
150if(ToPrint >= 0)
151{
152Glyphs[ToPrint].Vertices->Enable();
153Glyphs[ToPrint].TexCoords->Enable();
154glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
155glTranslatef(Glyphs[ToPrint].Width, 0, 0);
156}
157P++;
158}
159glPopMatrix();
160}
161 
162float CRotoText::StringWidth(char *fmt, ...)
163{
164char Buffer[2048];
165float Width = 0;
166va_list varg;
167 
168va_start(varg, fmt);
169vsnprintf(Buffer, 2048, fmt, varg);
170va_end(varg);
171 
172char *P = Buffer;
173while(*P)
174{
175int ToPrint = GetGlyph(*P);
176 
177if(ToPrint >= 0)
178Width += Glyphs[ToPrint].Width;
179P++;
180}
181return Width;
182}
183 
184void CRotoText::SetScale(float scale)
185{
186glScalef((float)scale * (128.0/480.0), (float)scale * (128.0/480.0), 1);
187}

That code is hardcoded to the particular font bitmap I was using, as shown by the way that it doesn't even use ASCII for its internal table. CVertexArray and CTexCoordArray are my own little classes for storing stuff that will later be passed to glVertexArray and glTexCoordArray (via a VBO, but whatever), these two lines:

  TextSheet = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"font.png"]];
  [TextSheet Activate];

Just load and then activate a texture from the file 'font.png' using Apple's example texture class. They're Objective-C, which is why they might look slightly odd.

The text ends up being output in whatever colour was last set with glColor4f. The SetScale function is specific to the projection matrix I have set up elsewhere and the size of the font. You'll notice that each glyph is a very small number of pixels indeed (typically three or four across by five high), so I needed to be very specific about ensuring that texels map exactly to pixels, or things would look really blurry.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值