Mercurial > projects > mde
changeset 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 | f9f5e04f20b2 |
children | d43523ed4b62 |
files | codeDoc/jobs.txt codeDoc/mergetag/file-format-binary.txt data/conf/fonts.mtt data/conf/gui.mtt mde/gl/basic.d mde/gui/widget/miscWidgets.d mde/resource/FontTexture.d mde/resource/font.d mde/types/basic.d |
diffstat | 9 files changed, 145 insertions(+), 22 deletions(-) [+] |
line wrap: on
line diff
--- a/codeDoc/jobs.txt Sat Jun 14 12:04:25 2008 +0100 +++ b/codeDoc/jobs.txt Sat Jun 14 13:09:03 2008 +0100 @@ -51,6 +51,6 @@ 1 Mergetag binary support -Done (for git log message): -Implemented gl.texture module to load textures from file (untested). -Fixed log level/option setting in Init. \ No newline at end of file +Done (for mercurial log message): +Coloured and alpha-blended text is now supported. +TextWidgets get text colour from argument. \ No newline at end of file
--- a/codeDoc/mergetag/file-format-binary.txt Sat Jun 14 12:04:25 2008 +0100 +++ b/codeDoc/mergetag/file-format-binary.txt Sat Jun 14 13:09:03 2008 +0100 @@ -2,6 +2,9 @@ License: GNU General Public License version 2 or later (see COPYING) +No file format is set yet; this basically includes possibilities. The file format may or may not be compatible across platforms; if not it may just be used as a cache (i.e. open .mtt/.mtb, whichever is newest, and if it's .mtt then save a .mtb version). + + This is the file format for mergetag binary files. The unit size is a byte. Most numbers to do with the layout (i.e. not stored data) should be stored as a 32-bit uint.
--- a/data/conf/fonts.mtt Sat Jun 14 12:04:25 2008 +0100 +++ b/data/conf/fonts.mtt Sat Jun 14 13:09:03 2008 +0100 @@ -1,5 +1,6 @@ {MT01} <char[]|fallback="default"> +!{Lists available fonts. This data may be moved to options for more generic handling.} {default} <char[]|path="/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf"> <int|size=16>
--- a/data/conf/gui.mtt Sat Jun 14 12:04:25 2008 +0100 +++ b/data/conf/gui.mtt Sat Jun 14 13:09:03 2008 +0100 @@ -7,7 +7,7 @@ {W2} <int|x=150> <int|y=200> -<int[][int]|widgetData=[0:[0xB004,5,5,2,1,2,1,2,1,1,1,1,1,2,1,2,1,2,1,1,1,1,1,2,1,2,1,2],1:[0x3001],2:[0x2]]> +<int[][int]|widgetData=[0:[0xB004,5,5,2,1,2,1,2,1,1,1,1,1,2,1,2,1,2,1,1,1,1,1,2,1,2,1,2],1:[0x3001],2:[0x2,0xFFFF00]]> {WEmbedded} <int|x=20> <int|y=100>
--- a/mde/gl/basic.d Sat Jun 14 12:04:25 2008 +0100 +++ b/mde/gl/basic.d Sat Jun 14 13:09:03 2008 +0100 @@ -24,14 +24,14 @@ //BEGIN GL & window setup void glSetup () { + glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glEnable(GL_TEXTURE_2D); - glShadeModel(GL_FLAT); + glShadeModel(GL_SMOOTH); glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
--- a/mde/gui/widget/miscWidgets.d Sat Jun 14 12:04:25 2008 +0100 +++ b/mde/gui/widget/miscWidgets.d Sat Jun 14 13:09:03 2008 +0100 @@ -106,21 +106,25 @@ class TextWidget : Widget { this (IWindow wind, int[] data) { - if (data.length != 1) throw new WidgetDataException; + if (data.length != 2) throw new WidgetDataException; if (font is null) font = FontStyle.get("default"); font.updateBlock (str, textCache); mw = textCache.w; mh = textCache.h; + colour = Colour (cast(ubyte) (data[1] >> 16u), + cast(ubyte) (data[1] >> 8u), + cast(ubyte) data[1] ); super (wind,data); } void draw () { super.draw(); - font.textBlock (x,y, str, textCache); // test new-lines and unicode characters + font.textBlock (x,y, str, textCache, colour); // test new-lines and unicode characters } protected: const str = "Text Widget\nαβγ − ΑΒΓ"; TextBlock textCache; + Colour colour; static FontStyle font; }
--- a/mde/resource/FontTexture.d Sat Jun 14 12:04:25 2008 +0100 +++ b/mde/resource/FontTexture.d Sat Jun 14 13:09:03 2008 +0100 @@ -24,6 +24,7 @@ * matter. However, for the model/world coords, y increases downwards. */ module mde.resource.FontTexture; +import mde.types.basic; // Colour import mde.Options; import mde.resource.exception; @@ -160,15 +161,59 @@ } } - /** Render a block of text using a cache. Updates the cache if necessary. */ - void drawTextCache (FT_Face face, char[] str, ref TextBlock cache, int x, int y) { + /** Render a block of text using a cache. Updates the cache if necessary. + * + * Params: + * face = Current typeface pointer; must be passed from font.d (only needed if the cache is + * invalid) + * str = Text to render (only needed if the cache is invalid) + * cache = Cache used to speed up CPU-side rendering code + * x = Smaller x-coordinate of position + * y = Smaller y-coordinate of position + * col = Text colour (note: currently limited to black or white) */ + void drawCache (FT_Face face, char[] str, ref TextBlock cache, int x, int y, Colour col ) { updateCache (face, str, cache); // update if necessary debug scope (failure) logger.error ("drawTextCache failed"); + // opaque (GL_DECAL would be equivalent) + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + drawCacheImpl (cache, x, y, col); + } + /** A variation of drawCache, for transparent text. + * + * Instead of passing the alpha value(s) as arguments, set the openGL colour prior to calling: + * --- + * glColor3f (.5f, .5f, .5f); // set alpha to half + * drawCacheA (face, ...); + * + * glColor3ub (0, 255, 127); // alpha 0 for red, 1 for green, half for blue + * drawCacheA (face, ...); + * --- + * + * The overhead of the transparency is minimal. */ + void drawCacheA (FT_Face face, char[] str, ref TextBlock cache, int x, int y, Colour col/+ = Colour.WHITE+/) { + updateCache (face, str, cache); // update if necessary + debug scope (failure) + logger.error ("drawTextCache failed"); + + // transparency alpha + // alpha is current colour, per component + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + drawCacheImpl (cache, x, y, col); + } + + private void drawCacheImpl (ref TextBlock cache, int x, int y, Colour col) { + if (DerelictGL.availableVersion() >= GLVersion.Version14) { + glBlendFunc (GL_CONSTANT_COLOR, GL_ONE_MINUS_SRC_COLOR); + glBlendColor(col.r, col.g, col.b, 1f); // text colour + } else + glBlendFunc (col.nearestGLConst, GL_ONE_MINUS_SRC_COLOR); + glEnable (GL_TEXTURE_2D); glEnable(GL_BLEND); - glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_COLOR); foreach (chr; cache.chars) { GlyphAttribs* ga = chr.ga; @@ -281,10 +326,13 @@ void drawTexture () { // temp func if (tex.length == 0) return; + glEnable (GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, tex[0].texID); - glEnable (GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_COLOR); + float[4] Cc = [ 1.0f, 1f, 1f, 1f ]; + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, Cc.ptr); + glColor3f (1f, 0f, 0f); glBegin (GL_QUADS); glTexCoord2f (0f, 0f); glVertex2i (0, 0); @@ -312,14 +360,12 @@ // create a new texture static LinePacker create () { LinePacker p; - //FIXME: check for error? + //FIXME: why do I get a blank texture when binding to non-0? //glGenTextures (1, &(p.texID)); p.texID = 0; - //FIXME: why do I get a blank texture when using bind? - glBindTexture(GL_TEXTURE_2D, p.texID); // add a pretty background to the texture - static if (false) { + static if (true) { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); ubyte[3][dimH][dimW] testTex; @@ -335,7 +381,8 @@ const void* ptr = null; // Create a texture without initialising values. - glTexImage2D(GL_TEXTURE_2D, 0, 3, + glBindTexture(GL_TEXTURE_2D, p.texID); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, dimW, dimH, 0, GL_RGB, GL_UNSIGNED_BYTE, ptr); return p;
--- a/mde/resource/font.d Sat Jun 14 12:04:25 2008 +0100 +++ b/mde/resource/font.d Sat Jun 14 13:09:03 2008 +0100 @@ -16,6 +16,7 @@ /// Sets up freetype (in a basic way). module mde.resource.font; +public import mde.types.basic; // Colour import mde.Options; import mde.resource.FontTexture; import mde.resource.exception; @@ -228,7 +229,10 @@ * * The text block is drawn with top-left corner at x,y. To put the text's baseline at a given * y coordinate would require some changes. Line height is currently variable, depending on the - * highest glyph in the line. + * highest glyph in the line (should probably be fixed: FIXME). + * + * Specify the text's colour with col; currently this is only Colour.WHITE or Colour.BLACK + * (FIXME). FIXME: add alpha support. * * As a CPU-side code optimisation, store a TextBlock (unique to str) and pass a reference as * the cache argument. This is the recommended method, although for one-time calls when you @@ -246,26 +250,37 @@ * than this cache only serves as a small optimisation. However, the only way to get the size * of a text block is to use a TextBlock cache and update it, either with this function or with * the updateBlock function. */ - void textBlock (int x, int y, char[] str, ref TextBlock cache) { + void textBlock (int x, int y, char[] str, ref TextBlock cache, Colour col) { try { - fontTex.drawTextCache (face, str, cache, x, y); + fontTex.drawCache (face, str, cache, x, y, col); } catch (Exception e) { logger.warn ("Exception while drawing text: "~e.msg); } } /** ditto */ - void textBlock (int x, int y, char[] str) { + void textBlock (int x, int y, char[] str, Colour col) { try { // Using the cache method for one-time use is slightly less than optimal, but doing so // isn't really recommended anyway (and maintaining two versions of fontTex.drawText // would be horrible). TextBlock cache; - fontTex.drawTextCache (face, str, cache, x, y); + fontTex.drawCache (face, str, cache, x, y, col); } catch (Exception e) { logger.warn ("Exception while drawing text: "~e.msg); } } + /** A variation of textBlock for transparency. + * + * Set the alpha by calling glColor*() first. See FontTexture.drawCacheA()'s documentation for + * details. */ + void textBlockA (int x, int y, char[] str, ref TextBlock cache, Colour col) { + try { + fontTex.drawCacheA (face, str, cache, x, y, col); + } catch (Exception e) { + logger.warn ("Exception while drawing text: "~e.msg); + } + } /** The font-specified vertical distance between the baseline of consecutive lines. */ int getLineSeparation () {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mde/types/basic.d Sat Jun 14 13:09:03 2008 +0100 @@ -0,0 +1,53 @@ +/* LICENSE BLOCK +Part of mde: a Modular D game-oriented Engine +Copyright © 2007-2008 Diggory Hardy + +This program is free software: you can redistribute it and/or modify it under the terms +of the GNU General Public License as published by the Free Software Foundation, either +version 2 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/** Contains basic types used by mde. Some may be moved to other modules. */ +module mde.types.basic; + +//FIXME: remove import and change types or not? +import derelict.opengl.gltypes; + +/// Represent a colour using clamped floats +struct Colour { + /// Returns GL_ONE if total value is nearer white than black, else GL_ZERO. + GLenum nearestGLConst () { + return r+g+b >= 1.5f ? GL_ONE : GL_ZERO; + } + + GLclampf r,g,b; /// values + + static { + /// Predefined colours + const Colour WHITE = { r:1f, g:1f, b:1f }; + const Colour BLACK = { r:0f, g:0f, b:0f }; /// ditto + + /// Construct from floats (doesn't clamp, but GL does when values are passed) + Colour opCall (float r, float g, float b) { + Colour c; + c.r = r; + c.g = g; + c.b = b; + return c; + } + /// Construct from ubytes + Colour opCall (ubyte r, ubyte g, ubyte b) { + Colour c; + c.r = cast(float) r / 255f; + c.g = cast(float) g / 255f; + c.b = cast(float) b / 255f; + return c; + } + } +}