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 - 8. díl - 3D Font, JPEG textury
open gl
5. března 2002, 00.00 | V dnešním díle seriálu se opět vrátíme k písmu. Tentokrát budeme psát trojrozměrným písmem, a aby toho nebylo málo, potáhneme si jej texturou z JPEG obrázku. Článek navazuje na 6. díl, kde jsme se zabývali 2D písmem.
V dnešním díle seriálu se opět vrátíme k písmu. Tentokrát budeme psát trojrozměrným písmem, a aby toho nebylo málo, potáhneme si jej texturou z JPEG obrázku. Článek navazuje na 6. díl, kde jsme se zabývali 2D písmem.
Dříve než začnu popisovat 3D psaní, musím si vám trochu postěžovat na svůj C++ Builder a také na svou nepozornost. Když se vrátím k předchozím dílům tohoto seriálu vloudilo se mi do příkladů pár drobných chybek, kterých je těžké si na první problém všimnout. První chybka se mi povedla, když jsem jako časovač použil komponentu DelphiX - DXTimer a po té co jsem ji smazal z formuláře, zůstal v kódu nepříjemný řádek
#pragma link "DXClass"
který samozřejmě vyvolá chybu u překladače, kde nejsou komponenty DelphiX nainstalovány.
Druhý problém zavinil sám C++ Builder, který do každého projektu (makefile) vkládá informace o použitých knihovnách (lib a packages). A poměrně hojně se mi do projektu v poslední době přimíchávají packages (nepoužité, navíc ještě doinstalované). A při překladu na překladači, kde tyto komponenty nejsou, Builder ohlásí chybu. Řešení jsou dvě. To méně příjemné řešení je chirurgickou cestou odstranit nepotřebné knihovny a packages z projektu (souboru bpr) pomocí poznámkového bloku a to tak, že editujete řádky LIBRARIES, SPARELIBS, PACKAGES. Druhá možnost je, že v menu Project/Options... zaškrtnete volbu Packages / Build with runtime packages. Odstraníte nevhodné balíčky a znovu toto poličko vyrušíte. Nevhodné balíčky zmizí z projektu a vše je v pořádku.
V OpenGL máme možnost kromě obyčejného dvojrozměrného písma využívat trojrozměrné písmo. Princip je velmi podobný tomu, který jsme si popisovali v 6 díle.
Nejprve si musíme vytvořit celou znakovou sadu 3D fontu, k tomu nám podobně jako minule poslouží funkce BuildFont, kterou si sami napíšeme. Tato funkce nám vytvoří 256 znaků a každý bude uložen do display listu. Funkce glGenLists(256) nám najde 256 volných display listů jdoucích po sobě. API Funkce CreateFont vytvoří font a vrátí jeho ID (typu HFONT). A mi z tohoto vytvořeného fontu uděláme tzv. Outline font - 3D znaky. K tomu nám výborně poslouží funkce
BOOL wglUseFontOutlines(HDC hdc, DWORD first, DWORD count,
DWORD listBase, FLOAT deviation, FLOAT extrusion, int format,
LPGLYPHMETRICSFLOAT lpgmf );
hdc - zařízení, kde budeme 3D font používat (Form1->hDC)
first - index prvního znaku
count - délka tabulky znaků
listbase - index prvního displaylistu ..... viz proměnná base (popsáno
v 6.díle)
extrusion - zanoření písma do 3d (do osy z)
format - dvě možnosti WGL_FONT_LINES a WGL_FONT_POLYGONS; první znamená
,že modely písma budou z čar, druhá znamená - modely písmen budou z ploch (polygonů)
lpgmf - odkaz na strukturu GLYPHMETRICSFLOAT,
zde se uloží informace o jednotlivých znacích - umístění a orientace znaků
Další změnou oproti 2D psaní písma je právě využití GLYPHMETRICSFLOAT
pro výpočet šířky jednotlivých znaků a jejich správné umístění. Pozmění námi
napsanou funkci glPrint (opět víz 6. díl). Algoritmus se liší pouze ve výpočtu
šířky textu, zde je to
length+=gmf[text[loop]].gmfCellIncX;
Do programu jsem přidal pro příznivce VCL komponenty Panel, Edit a 2x UpDown, aby bylo jasně, jak jde poměrně dobře VCL kombinovat s OpneGL. Výřez OpenGL je menší než je velikost formuláře.
|
Všechno ostatní je stejné jako v díle 6.
Příklad je ke stažení ZDE (240KB).
3D Font s JPEG texturou
Aby tento článek nebyl tak suchý, pokusím se vám popsat jiný způsob načítání textur. Bude více orientovaný na možnosti VCL. A jelikož ve VCL máme i třídu TJPEGImage, vyzkoušíme, jak se používají JPG textury.
Pro načtení textury potřebujeme znát jeho velikost. Já si ji uložím do proměnných vyska a sirka (ale není to nezbytně nutné, jde to i jinak). Dále budeme potřebovat ukazatel na bitmapu, kterou vycucneme z JPEG obrázku. Ukazatel bude typu BYTE, protože potřebujeme pouze surové obrazové data.
|
Uznávám, že uvedený algoritmus nepatří zrovna k nejrychlejším, protože vlastnost Pixels[][] je pomalá (ale takové už je VCL). Nicméně uvedený algoritmus je velmi jednoduchý a nějaké nepatrné zpoždění při načítání textur nám nevadí, protože jej provádíme při startu programu. Algoritmus načte JPG obrázek do objektu Obr (TJPEGImage), ukazatel textura1 bude ukazovat na obrazové data, a proto dynamicky alokujeme potřebné množství bajtů. Informaci o barvě daného bodu čteme z vlastnosti Pixels[][], vrací se hodnota TColor. A jelikož potřebujeme u každého bodu jednotlivé složky R,G,B s chutí využijeme makra GetRValue(), GetGValue(), GetBValue().
Navíc, aby OpenGL otexturoval napsaný text, musíme učinit potřebné nastavení pro texturování:
|
Toto nastavení vám musím interpretovat vlastními slovy, protože nápovědě jsem příliš neporozuměl. Nastavení glTexGeni na GL_S koordinuje namapování textury na členitý objekt svisle a nastavení glTexGeni na GL_T koordinuje namapování textury na členitý objekt vodorovně. Kombinací obou dvou nastavení dosáhneme kvalitního pokrytí písmen texturami. To je celé.
Výsledek lze stáhnout ZDE (300 KB).
Pro tentokrát je toho dost, nicméně, problematiku fontů a písma jsme ještě nevyčerpali. V některém z příštích dílů se podíváme na tzv. bitmapové písmo.
Podobné příklady, jako v tomto článku najdete na Nehe. Z velké časti jsem se jimi inspiroval.
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ů
-
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