 |
|
 |
 |
 |
| 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.
|
|
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
|
Hodnocení článku |
1 |
2 |
3 |
4 |
5 Aktuální známka: 2.64 (Počet známek: 3544)
|
|
|
 |
 |
 |