comparison mde/resource/FontTexture.d @ 57:9e1f05fbbcef

Coloured and alpha-blended text is now supported. TextWidgets get text colour from argument.
author Diggory Hardy <diggory.hardy@gmail.com>
date Sat, 14 Jun 2008 13:09:03 +0100
parents f000d6cd0f74
children 7cab2af4ba21
comparison
equal deleted inserted replaced
56:f9f5e04f20b2 57:9e1f05fbbcef
22 * coordinates, and OpenGL's model/world coordinates (for rendering). The freetype and texture 22 * coordinates, and OpenGL's model/world coordinates (for rendering). The freetype and texture
23 * coords are cartesian (i.e. y increases upwards), although largely this is too abstract to 23 * coords are cartesian (i.e. y increases upwards), although largely this is too abstract to
24 * matter. However, for the model/world coords, y increases downwards. */ 24 * matter. However, for the model/world coords, y increases downwards. */
25 module mde.resource.FontTexture; 25 module mde.resource.FontTexture;
26 26
27 import mde.types.basic; // Colour
27 import mde.Options; 28 import mde.Options;
28 import mde.resource.exception; 29 import mde.resource.exception;
29 30
30 import derelict.freetype.ft; 31 import derelict.freetype.ft;
31 import derelict.opengl.gl; 32 import derelict.opengl.gl;
158 // Now increment i and continue with the next line if there is one. 159 // Now increment i and continue with the next line if there is one.
159 y += lineSep - yMax; 160 y += lineSep - yMax;
160 } 161 }
161 } 162 }
162 163
163 /** Render a block of text using a cache. Updates the cache if necessary. */ 164 /** Render a block of text using a cache. Updates the cache if necessary.
164 void drawTextCache (FT_Face face, char[] str, ref TextBlock cache, int x, int y) { 165 *
166 * Params:
167 * face = Current typeface pointer; must be passed from font.d (only needed if the cache is
168 * invalid)
169 * str = Text to render (only needed if the cache is invalid)
170 * cache = Cache used to speed up CPU-side rendering code
171 * x = Smaller x-coordinate of position
172 * y = Smaller y-coordinate of position
173 * col = Text colour (note: currently limited to black or white) */
174 void drawCache (FT_Face face, char[] str, ref TextBlock cache, int x, int y, Colour col ) {
165 updateCache (face, str, cache); // update if necessary 175 updateCache (face, str, cache); // update if necessary
166 debug scope (failure) 176 debug scope (failure)
167 logger.error ("drawTextCache failed"); 177 logger.error ("drawTextCache failed");
168 178
179 // opaque (GL_DECAL would be equivalent)
180 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
181
182 drawCacheImpl (cache, x, y, col);
183 }
184 /** A variation of drawCache, for transparent text.
185 *
186 * Instead of passing the alpha value(s) as arguments, set the openGL colour prior to calling:
187 * ---
188 * glColor3f (.5f, .5f, .5f); // set alpha to half
189 * drawCacheA (face, ...);
190 *
191 * glColor3ub (0, 255, 127); // alpha 0 for red, 1 for green, half for blue
192 * drawCacheA (face, ...);
193 * ---
194 *
195 * The overhead of the transparency is minimal. */
196 void drawCacheA (FT_Face face, char[] str, ref TextBlock cache, int x, int y, Colour col/+ = Colour.WHITE+/) {
197 updateCache (face, str, cache); // update if necessary
198 debug scope (failure)
199 logger.error ("drawTextCache failed");
200
201 // transparency alpha
202 // alpha is current colour, per component
203 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
204
205 drawCacheImpl (cache, x, y, col);
206 }
207
208 private void drawCacheImpl (ref TextBlock cache, int x, int y, Colour col) {
209 if (DerelictGL.availableVersion() >= GLVersion.Version14) {
210 glBlendFunc (GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR);
211 glBlendColor(col.r, col.g, col.b, 1f); // text colour
212 } else
213 glBlendFunc (col.nearestGLConst, GL_ONE_MINUS_SRC_COLOR);
214
169 glEnable (GL_TEXTURE_2D); 215 glEnable (GL_TEXTURE_2D);
170 glEnable(GL_BLEND); 216 glEnable(GL_BLEND);
171 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_COLOR);
172 217
173 foreach (chr; cache.chars) { 218 foreach (chr; cache.chars) {
174 GlyphAttribs* ga = chr.ga; 219 GlyphAttribs* ga = chr.ga;
175 220
176 glBindTexture(GL_TEXTURE_2D, ga.texID); 221 glBindTexture(GL_TEXTURE_2D, ga.texID);
279 cachedGlyphs[chr] = ga; 324 cachedGlyphs[chr] = ga;
280 } 325 }
281 326
282 void drawTexture () { // temp func 327 void drawTexture () { // temp func
283 if (tex.length == 0) return; 328 if (tex.length == 0) return;
329 glEnable (GL_TEXTURE_2D);
284 glBindTexture(GL_TEXTURE_2D, tex[0].texID); 330 glBindTexture(GL_TEXTURE_2D, tex[0].texID);
285 glEnable (GL_TEXTURE_2D);
286 glEnable(GL_BLEND); 331 glEnable(GL_BLEND);
287 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_COLOR); 332 glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_COLOR);
333 float[4] Cc = [ 1.0f, 1f, 1f, 1f ];
334 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, Cc.ptr);
335 glColor3f (1f, 0f, 0f);
288 336
289 glBegin (GL_QUADS); 337 glBegin (GL_QUADS);
290 glTexCoord2f (0f, 0f); glVertex2i (0, 0); 338 glTexCoord2f (0f, 0f); glVertex2i (0, 0);
291 glTexCoord2f (1f, 0f); glVertex2i (dimW, 0); 339 glTexCoord2f (1f, 0f); glVertex2i (dimW, 0);
292 glTexCoord2f (1f, 1f); glVertex2i (dimW, dimH); 340 glTexCoord2f (1f, 1f); glVertex2i (dimW, dimH);
310 struct LinePacker 358 struct LinePacker
311 { 359 {
312 // create a new texture 360 // create a new texture
313 static LinePacker create () { 361 static LinePacker create () {
314 LinePacker p; 362 LinePacker p;
315 //FIXME: check for error? 363 //FIXME: why do I get a blank texture when binding to non-0?
316 //glGenTextures (1, &(p.texID)); 364 //glGenTextures (1, &(p.texID));
317 p.texID = 0; 365 p.texID = 0;
318 //FIXME: why do I get a blank texture when using bind?
319 glBindTexture(GL_TEXTURE_2D, p.texID);
320 366
321 // add a pretty background to the texture 367 // add a pretty background to the texture
322 static if (false) { 368 static if (true) {
323 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 369 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
324 glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); 370 glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
325 ubyte[3][dimH][dimW] testTex; 371 ubyte[3][dimH][dimW] testTex;
326 for (size_t i = 0; i < dimW; ++i) 372 for (size_t i = 0; i < dimW; ++i)
327 for (size_t j = 0; j < dimH; ++j) 373 for (size_t j = 0; j < dimH; ++j)
333 void* ptr = testTex.ptr; 379 void* ptr = testTex.ptr;
334 } else 380 } else
335 const void* ptr = null; 381 const void* ptr = null;
336 382
337 // Create a texture without initialising values. 383 // Create a texture without initialising values.
338 glTexImage2D(GL_TEXTURE_2D, 0, 3, 384 glBindTexture(GL_TEXTURE_2D, p.texID);
385 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
339 dimW, dimH, 0, 386 dimW, dimH, 0,
340 GL_RGB, GL_UNSIGNED_BYTE, ptr); 387 GL_RGB, GL_UNSIGNED_BYTE, ptr);
341 return p; 388 return p;
342 } 389 }
343 390