Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
C/C++
OpenGL v C++ Builderu (6.díl)
open gl
4. prosince 2001, 00.00 | 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.
|
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)
|
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á.
|
Ř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:
Obsah seriálu (více o seriálu):
- OpenGL - 1.díl Nastavení a jednoduché kreslení
- OpenGL - 2 díl Rotace objektů
- OpenGL v C++ Builderu (3.díl)
- OpenGL v C++ Builderu (4.díl)
- OpenGL v C++ Builderu (5.díl)
- OpenGL v C++ Builderu (6.díl)
- OpenGL -Jednoduché efekty 1
- OpenGL - 8. díl - 3D Font, JPEG textury
- OpenGL 9. díl - Bitmap Font
- OpenGL -10.díl Náčítání modelů ze souborů
Diskuse k článku
-
25. listopadu 2012
-
30. srpna 2002
-
10. října 2002
-
4. listopadu 2002
-
12. září 2002
-
25. listopadu 2012
-
28. července 1998
-
31. července 1998
-
28. srpna 1998
-
6. prosince 2000
-
27. prosince 2007
-
4. května 2007