Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

1

02.10.2012, 13:32

Textured Font Drawing

Hallo zusammen,

ich habe bisher immer nur mit Bitmap Font in OpenGL gearbeitet (wglUseFontBitmaps, glBitmap etc.) und nun möchte ich mich endlich mal mit Textured Font auseinander setzen.
Die Irrlicht Engine bietet da die Möglichkeit, eine zuvor generierte Texture mit allen Gylphen zu laden und als Text zu zeichnen. Ich möchte das in meiner Engine noch etwas erweitert haben,
und zwar erstelle ich (zur Zeit nur unter Windows) den Font mit der GDI (CreateFont), zeichne das in eine Bitmap, extrahiere die Pixel und erstelle daraus eine Texture.
Das klappt soweit auch schon ganz gut, nur leider habe ich nach wie vor Probleme, die korrekte Breite der Glyphen zu ermitteln, die er einnimmt. Damit meine ich nicht die Breite die der Glyph (btw. das Symbol) visuell einnimmt, sondern um wie viel Pixel erst der nächste Glyph kommen soll.
Ein Leerzeichen soll schließlich mehr als 0 Pixel an Platz einnehmen. Die WinAPI bzw. die GDI ist da alles andere als Benutzerfreundlich.

So mache ich das bisher:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    struct SGlyph
    {
        SGlyph(HDC dc, u32 GlyphChar) :
            Offset(0)
        {
            char Char = static_cast<c8>(GlyphChar);
            
            /* Query glyph metrics */
            GLYPHMETRICS Metrics;
            MAT2 Mat2 = { { 0, 1 }, { 0, 0 }, { 0, 0 }, { 0, 1 } }; 
            
            GetGlyphOutlineA(dc, GlyphChar, GGO_METRICS, &Metrics, 0, 0, &Mat2);
            
            SIZE sz;
            GetTextExtentPoint32A(dc, &Char, 1, &sz);
            
            ABC abc;
            GetCharABCWidths(dc, GlyphChar, GlyphChar, &abc);
            
            /* Setup glyph metrics */
            Offset      = Metrics.gmCellIncX; // HIER ENTNEHME ICH ZURZEIT DIE INFORMATION VON DER ICH SPRACH
            
            Origin.X    = abc.abcA;
            Origin.Y    = abc.abcC;
            
            Size.Width  = abc.abcB + 2;
            Size.Height = sz.cy;
        }
        ~SGlyph()
        {
        }
        
        /* Members */
        size2di Size;
        rect2di Rect;      //!< Rectangular area of the glyph in the texture (in pixels).
        point2di Origin;
        int Offset;             //!< The space which occupies the glyph (in pixels).
    };


Der Wert "gmCellIncX" klang für mich nach dem, wonach ich suche, aber wenn ihr euch folgendes Bild anschaut, seht ihr, dass das nicht stimmen kann.
Oben mein Textured-Font und unten der Bitmap Font.
Danke schon mal im Voraus für eure Hilfe :)

PS: Schriftart ist "Brush Script MT" (Italic & Underlined)
»LukasBanana« hat folgendes Bild angehängt:
  • DemoBildText.png

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

2

02.10.2012, 14:21

Also ich habe jetzt herausgefunden, dass man für TrueType Font die Funktion GetCharABCWidths verwenden muss.
Aber dümmere Namen als "abcA", "abcB" und "abcC" konnten sich die Microsoft Programmierer auch nicht ausdenken. So ganz klappt das mit der Zusammensetzung bei mir immer noch nicht.
Hab das jetzt mal wie folgt geändert:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
    struct SGlyph
    {
        SGlyph(HDC dc, u32 GlyphChar) :
            StartOffset(0),
            DrawnWidth(0),
            WhiteSpace(0)
        {
            c8 Char = static_cast<c8>(GlyphChar);
            
            /* Query glyph metrics */
            SIZE sz;
            GetTextExtentPoint32A(dc, &Char, 1, &sz);
            
            ABC abc;
            GetCharABCWidths(dc, GlyphChar, GlyphChar, &abc);
            
            /* Setup glyph metrics */
            StartOffset = abc.abcA;
            DrawnWidth  = abc.abcB;
            WhiteSpace  = abc.abcC;
            
            Size.Width  = DrawnWidth + 2;
            Size.Height = sz.cy;
        }
        ~SGlyph()
        {
        }
        
        /* Members */
        dim::size2di Size; // Das ist der Platz, den der Glyph in der Texture einnimmt.
        s32 StartOffset;
        s32 DrawnWidth;
        s32 WhiteSpace;
    };

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

3

02.10.2012, 14:37

Ok, hab's jetzt auch selbst gelöst. Ist etwas kompliziert mit den komischen Variablennamen zurecht zu kommen, aber jetzt sieht's top aus :-)
Hier noch mal Bild zum Vergleich. Underlined klappt zwar nicht perfekt, aber ansich sieht der Text deutlich besser aus, als mit Bitmap-Font :D
»LukasBanana« hat folgendes Bild angehängt:
  • DemoBildText.png

Werbeanzeige