[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 - 8. díl - 3D Font, JPEG textury
    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.
    OpenGL
    Předchozí díl: OpenGL -Jednoduché efekty 1

    Následující díl: OpenGL 9. díl - Bitmap Font
    Autor: Michal Svoboda
    Rubrika: C/C++
    Publikováno: 05.03. 2002
     Tisk článku
    Poslat odkaz emailem
     

    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.

    gldAspect = (double) (ClientWidth)/ (double) (ClientHeight-Panel1->Height);

    . . . . .
    - při výpočtu poměru výšky a šířky OpenGL okna musíme uvažovat navíc i výšku panelu. Ale to není všechno, gl Viewport je rovněž menší než celé okno.
    . . . . .

    glViewport(0, 0, ClientWidth, ClientHeight-Panel1->Height);

    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.

    TColor Barva;
    TJPEGImage *Obr;
    Obr = new TJPEGImage();
    Obr->LoadFromFile("lights.jpg");
    sirka = Obr->Bitmap->Width;
    vyska = Obr->Bitmap->Height;
    textura1 = new BYTE[3*Obr->Bitmap->Width*Obr->Bitmap->Height];
    for (int y = 0; y < Obr->Bitmap->Height; y++) {
     for (int x = 0; x < Obr->Bitmap->Width; x++) {
     Barva = Obr->Bitmap->Canvas->Pixels[x][y];
      // z vlastnosti Pixels přečteme všechny barvy bodů a rozložíme na složky
     *(textura1+3*(Obr->Bitmap->Height-y-1)*Obr->Bitmap->Height+3*x) = 
            GetRValue(Barva);
     *(textura1+3*(Obr->Bitmap->Height-y-1)*Obr->Bitmap->Height+3*x+1) = 
            GetGValue(Barva);
     *(textura1+3*(Obr->Bitmap->Height-y-1)*Obr->Bitmap->Height+3*x+2) = 
            GetBValue(Barva);
     }
    }

    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í:

    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
    glEnable(GL_TEXTURE_GEN_S);
    glEnable(GL_TEXTURE_GEN_T);

    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.


    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.67
    (Počet známek: 3888)

    Komentáře k článku
    -- Žádné příspěvky --
    Přidat příspěvek




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