[Grafika] [WebTip] [Fotografování] [Galerie] [MujMac] [Printing]
  Redakce: info (at) builder.cz   Inzerce: reklama (at) grafika.cz
Diskuzní fóra
.Net (68468)
ASP (1591)
ActiveX (168)
Allegro (136)
Assembler (3926)
C++ Builder (23160)
C/C++ (44499)
Databáze (30680)
Delphi (78806)
DelphiX (1655)
DirectX (1464)
Java (39508)
JavaScript (12598)
Matematické programy (2178)
OOP a UML (732)
OpenGL (6920)
Php (65224)
PowerBuilder (464)
Problémy a algoritmy (10473)
Programování v Linuxu (2000)
Právo a programování (3384)
Python (1353)
Ruby (136)
Visual Basic (12078)
Visual C++ (12956)
Wap (56)
Web (10895)
Web servery (5549)
Win32 (13553)
Windows CE (865)
XML/XSL (1860)
Textová inzerce
Služby Builder.cz
  • Bazar - koupím(0)
  • Bazar - prodám(0)
  • Hledám práci(0)
  • Nabízíme práci(0)
  • Projekty(0)
  • OpenGL v C++ Builderu (6.díl)
    Vítejte u dalšího dílu seriálu věnovanému OpenGL. V dnešním již šestém díle si povíme něco o tom, jak využívat fonty a tisknout řetězců do OpenGL okna.
    OpenGL
    Předchozí díl: OpenGL v C++ Builderu (5.díl)

    Následující díl: OpenGL -Jednoduché efekty 1
    Autor: Michal Svoboda
    Rubrika: C/C++
    Publikováno: 04.12. 2001
     Tisk článku
    Poslat odkaz emailem
     

    Používání fontů

    Vítejte u dalšího dílu seriálu věnovanému OpenGL. V dnešním šestém díle si povíme něco o tom, jak využívat fonty a tisknout řetězců do OpenGL okna. Myslím, že je pravý čas naučit se psát a využívat systémové fonty (Arial, Courier atd..).

    O co půjde? Napadají mě dvě možnosti, jak pracovat s textem v OpenGL. Jedna možnost je mít připravený obrázek s písmem, všechny v řadě za sebou (nebo do řádků). Načíst tento obrázek do paměti a pak při tisku řetězce vybírat jednotlivé písmenka z obrázku a kreslit je do okna na správnou pozici. Druhý způsob je podobný, vytvoříme si tabulku znaků (0-255, ale může to být i jinak 32-128). Každý znak uložíme do listu (tabulky). A obdobně při tisku řetězce vyvoláváme jednotlivé znaky z listu (jako objekty). Princip je stejný v obou případech, rozdílem jsou zpracovávaná data, v prvém případě se jedná o obrázek BMP a v druhém jde o objekty z listu. My se budeme zabývat druhým způsobem.

    Uvidíte, jak vám pěkně za chvíli do sebe zapadne to, co jsem vám napsal. Náš dnešní příklad bude opět jednoduchý. Vidíte jej na obrázku, ale navíc se text bude pohybovat v okně a měnit barvu. Tak se pusťme do díla.

    Budeme k našemu programu potřebovat několik pomocných proměnných.

    GLuint	base; // Display List pro první písmeno
    GLfloat cnt1; // čítač pro posun textu
    GLfloat cnt2; // čítač pro posun textu

    Všechny znaky budou uložené v display listech od a až po ž v pořadí za sebou. Proměnná base nás bude informovat o indexu prvního znaku v display listu a za ním jsou naskládané ostatní písmenka. Tak například znak 'A' má v tabulce znaků pořadové číslo 65 a znak 'B' má pořadové číslo 66. Tak to pokračuje dál. No a my máme všechna písmenka uložené v display listu a písmeno 'A' budeme mít uloženo v display listu na pozici base + 65.

    A teď si ukážeme, že proměnná base je opravdu potřeba. Vytvoříme si vlastní funkci, která zavede font do paměti a aktivuje ho.
    Pro to nám poslouží naše vlastní funkce TForm1::BuildFont(GLvoid)

    HFONT	font; // Windows Font ID
    base = glGenLists(223); // 223 políček pro 223 znaku
     font = CreateFont(-20, // výška fontu
                   0, // šířka fontu
                   0, // úhel
                   0, // úhel
                   FW_BOLD, // typ písma (normální ,tučné)
                   FALSE, // kurzíva
                   FALSE, // podtržené
                   FALSE, // přeškrtnuté
                   DEFAULT_CHARSET, // kódování znaků
                   OUT_TT_PRECIS,
                   CLIP_DEFAULT_PRECIS,
                   ANTIALIASED_QUALITY, // kvalita tisku
                   FF_DONTCARE|DEFAULT_PITCH,
                   "Arial"); // jméno fontu
     SelectObject(hDC, font); // označení používaného fontu
     wglUseFontBitmaps(hDC, 32, 223, base); // uložíme znaky od 32 do 255
                 

    Funkce glGenLists má za úkol vytvořit spojité pole display listů, a vrací nám index prvního display listu (uložíme do base). My potřebujeme 223 display listů a funkce glGenLists zajistí, aby šli po sobě.

    Font vytvoříme pomocí funkce CreateFont. Komentář je v rámečku myslím výstižný, ale řekněme si některé další možné nastavení. V helpu je tato funkce popsána takto:
    CreateFont(int Height,int Width,int Escapement, int Orientation, int Weight, DWORD Italic, DWORD Underline, DWORD StrikeOut, DWORD CharSet, DWORD OutputPrecision, DWORD ClipPrecision, DWORD Quality, DWORD PitchAndFamily, LPCTSTR Face);

    Height - určuje výšku textu, pokud je hodnota 0, velikost písma bude implicitní. Pokud je hodnota kladná, zadáváme výšku buňky písma. Když je hodnota záporná, určujeme absolutní velikost písma (doporučuji vyzkoušet).
    Width - šířka textu
    Escapement - velmi zajímavý parametr, nastaví úhel natočení textu, zadáváme ho v desetinách stupně. Můžeme zadávat kladné a záporné hodnoty. Uspokojivých výsledků dosáhneme do hodnoty +250. Záporné hodnoty nedávají dobré výsledky.
    CharSet - určí kódování písma, pokud si vystačíte pouze s anglickými znaky zadejte ANSI_CHARSET, k českým znakům se doberete přes DEFAULT_CHARSET a je zde i spoustu jiných možností (EASTEUROPE_CHARSET,RUSSIAN_CHARSET atd.)
    OutputPrecision - je také užitečné nastavení, pokud je v systému nainstalovaných více fontů stejného jména, více verzí (true typové, rastrové). nejlepší je použít vždy true typovou verzi písma, takže nastavení OUT_TT_ONLY_PRECIS.
    ClipPrecision - určí typ ořezání písma - CLIP_DEFAULT_PRECIS
    Quality - definuje výstupní kvalitu. Pokud mohu mluvit za sebe, mám rád nejvyšší kvalitu a ta nese označení ANTIALIASED_QUALITY (vyhlazené písmo)
    Face - jméno fontu, jak je známe například z WORDu a jiných aplikací (Arial, Courier . . .)

    Další velice důležitou věcí je udělat si nějakou funkci, která se nám postará o výpis celého řetězce naráz. Uděláme funkci glPrint a není nikterak složitá.

    char	text[256];	
    va_list ap; // seznam argumentů
    if (fmt == NULL)  // test na prázdný řetězec
     return;
    va_start(ap, fmt); 
    vsprintf(text, fmt, ap); // obdoba sprintf ale s proměnným počtem parametrů va_end(ap);
    glPushAttrib(GL_LIST_BIT);
    glListBase(base-32); // nastaví aktuální DisplayList na první písmeno
    glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); // zpracuje celý řetězec
    glPopAttrib();

    Řetězec do funkce vstupuje jako parametr fmt, a my ho potřebujeme trochu upravit. Připíšeme navíc ještě čítač (číslo, které se bude v průběhu měnit), k tomu nám poslouží výborně funkce vsprintf, která nám znovu řetězec přeformátuje a připíše číslo. Potom pomocí glListBase musíme nastavit základní (bázový) display list, protože potom funkce glCallLists vykresluje jednotlivé písmenka z pole text (řetězce), kde jsou číselně uložené kódy těchto písmen. A funkce glCallLists vyvolává postupně display listy od hodnoty, kterou nastavíme do glListBase. No to ale ještě nevysvětluje, proč je tam jako parametr
    glListBase(base-32);
    To je proto, že jsme při tvorbě naší tabulky znaků zanedbali 32 prvních znaků. Takže abychom se dostali vždy ke správnému písmenku, musíme tuto hodnotu báze ještě o 32 snížit.

    No a to je už skoro celé, nyní akorát zaměříme svoji pozornost na funkci DrawScene a nastavíme pozici, kde chceme řetězec v okně zobrazit a pak zavoláme náš výtvor glPrint:
    glRasterPos2f(-2.0f+2*cos(cnt1), sin(2*cnt2));
    glPrint("Miškyn TEST Font - %7.2f", cnt1);

    Čítače cnt1 a cnt2 zajistí pohyb v okně.

    Celý program si můžete stáhnout ZDE (320KB).

    Užitečné informace:

    nehe.gamedev.net





    Zpět na začátek stránky

    Autor: Michal Svoboda
    Klikni pro další články autora

    Hodnocení článku
    1 | 2 | 3 | 4 | 5
    Aktuální známka: 2.64
    (Počet známek: 3544)

    Komentáře k článku
    llook25.04.8:5132 zanedbanych znaku
    Michal Svoboda25.04.12:05RE: 32 zanedbanych znaku
         





    info@builder.cz
    Vydává Grafika Publishing, s.r.o.
    Copyright (c) 1997-2002 Všechna práva vyhrazena