Grafické aplikace ve Visual C++ (6.) V této lekci se posuneme o velký krok kupředu, protože vám ukážu zdrojové kódy, které vám velmi usnadní práci s Direct Draw objekty. Veškerý kód je součástí SDK. Dále se blíže podíváme na funkci Blt(). 6.1.Třídy CDisplay a CSurfaceBylo napsáno pár jednoduchých funkcí, které vám však velmi usnadní život s DirectDraw. Zdrojové kódy těchto funkcí jsou součástí SDK, které jste instalovali na začátku našeho povídání. Konkrétně byste je měli najít v adresáři SDK na disku. Pokud je tedy chcete používat, je asi nejlepší si do projektu zkopírovat soubory ddutil.h, ddutil.cpp a dxutil.h. Jako celé DD i tyto soubory prošly celkem radikálním vývojem. Na počátku obsahovaly pouze globální funkce, nyní obsahují dvě třídy, které se kompletně starají o grafický interface a povrchy. Vložte tedy oba soubory do vašeho projektu, nejlépe ve FileView přes popup menu, kde vyberte položku Add files to project. V ClassView by se měli objevit dvě nové třídy: CDisplay a CSurface. Aby šel projekt zkompilovat, musíte vypnout pro soubor ddutil.cpp předkompilované hlavičky, nebo do souboru vložit stdafx.h vašeho projektu. Doporučuji udělat to první. To uděláte v menu Project Settings..., kde v levém okénku najdete požadovaný soubor a vpravo vyberete druhou kartu, kde zvolíte Precompiled header, kde zvolíte první volbu Not using precompiled header. Pro snazší orientaci jsem vám stáhl tento obrázek:
Nyní si zkuste, zdali vám půjde projekt zkompilovat.
Celý systém je velice jednoduchý. Stačí do souboru control.h
vložit hlavičkový soubor ddutil.h a můžete
začít. Vložte tedy následující řádek někam na začátek souboru
control.h: A nyní již budete jen mazat kód, který jsme vytvořili v minulých lekcích, protože vše obstará třída CDisplay a CSurface. 1. Vytvořte objekt m_theDisplay (typu CDisplay) ve třídě CControl. Poté vložte do funkce DDInit() volání funkce CreateFullScreenDisplay(), jenž je členská funkce třídy CDisplay. Funkce přijímá celkem 4 parametry. za prvé je to HANDLE našeho okna, který přijímá i naše funkce DDInit(), dále jsou to rozměry obrazovky v pixelech, vy můžete zadat konstanty definované výše. Jsou to RES_X, RES_Y a RES_BITDEPTH. To je vše, zbytek funkce až na poslední řádek vymažte. 2. Vytvoříme pozadí. Ve třídě CControl deklarujte proměnnou typu ukazatel CSurface m_surBackground. Ve funkce DDInit() vytvořte dynamicky objekt CSurface a zavolejte funkci CreateSurfaceFromFile() objektu m_theDisplay. Funkce má opět 4 parametry. První je ukazatel na ukazatel na objekt povrchu, druhý je řetězec bitmapy, která se nahraje do povrchu a poslední dva parametry jsou požadované rozměry povrchu, pokud zde zadáte 0, vytvoří se povrch o velikosti bitmapy. Dejte pozor aby na konci funkce DDInit() zůstal řádek, který aktivuje smyčku zpráv! Funkce DDInit() vypadá po úpravě takto:
void CControl::UpdateFrame() 6.2 Další možnosti třídy CDisplay6.2.1 PaletaNyní si povíme něco o paletách. Třídy CDisplay samozřejmě podporuje i palety. Nejprve musíte deklarovat objekt LPDIRECTDRAWPALETTE, který může být lokální. Poté zavoláte funkci CreatePaletteFromBitmap(), která má pouze dva parametry. První je objekt LPDIRECTDRAWPALETTE, který jsme již deklarovali a druhý je řetězec bitmapy, ze které se paleta vytvoří. Důležité je, že funkce vytvoří objekt palety podle palety bitmapy a ne podle barev bitmapy! Často se totiž stává, že si vytvoříme bitmapu, která obsahuje všechny barvy, které potřebujeme, ale paleta této bitmapy zůstane standardní tzn. paleta základních 256 barev (jako ve Windows). Takže musíte vytvořit bitmapu v nějakém externím rastrovém editoru (např. Malování, Photoshop) a uložit s 256 barevnou paletou. Tento externí editor pak vytvoří adaptivní paletu, která přesně odpovídá vaší bitmapě. Když ho pak importujete do Visual C++, můžete klidně bitmapu palety zmenšit na 1x1 pixel s libovolnou barvou, aby nezabíral cenné kB v .exe souboru. Taková bitmapa si ovšem uchová svojí paletu (vytvořenou externím editorem) a ta se také použije v naší funkci. Dále musíte zavolat členskou funkci rozhraní Následuje jednoduchý příklad nastavení bitmapy:
Pokud pracujete v 16-bitech (65 tis. barev), je nastavení palety zbytečné. To
znamená, že paletu má smysl nastavovat jen v 8-bitech (256 barev) - nižší
barevnou hloubku ani neuvádím, kdo by chtěl pracovat s 16 barvami. Naopak pokud
pracujete v 8-bitech je paleta nutná, protože jinak se použijí základní
barvy Windows a bitmapa se dost znehodnotí (pokud se zrovna netrefíte). 6.2.2. Nastavení průhledné barvy neboli nastavení Color KeyNastavení průhledné barvy je velmi důležitá vlastnost povrchů DirectDraw.
Color key neboli barevný klíč, označí barvu v povrchu, kterou nechceme
vykreslovat to znamená, že výsledný obrázek bude v tomto místě průhledný.
Color key nastavujete pro každý vytvořený povrch zvlášť. My zatím nemáme
žádný obrázek, který bychom potřebovali vykreslovat transparentně. Princip
color key spočívá v označení průhledné barvy pomocí makra RGB. Ve
třídě CSurface objevíte funkci
SetColorKey(), která přijímá jeden parametr právě
jako barvu.
6.3. Funkce Blt()Jistě jste si všimli, že funkce Blt() je i
ve třídě CDisplay, to je ale funkce, která je
zjednodušená a jen málo využívá možnosti pravé funkce Blt(). O této funkci jsem
se již několikrát zmiňoval, ale nikdy jsem pořádně neřekl,
co všechno vlastně umí. Už je vám asi jasné, že slouží ke kopírování - blittování - dat (bitů) mezi povrchy. V souboru
Jak vidíte má spoustu parametrů a my si je teď konečně všechny probereme.
Funkci vám osvětlí následující obrázek: Tak už je vám to aspoň trošku jasné? Doufám, že ano. Nyní si podrobně vysvětlíme poslední dva záhadné parametry. 1. dwFlagsTento parametr může nabývat mnoha hodnot, které se navíc dají kombinovat.
Následující tabulka vysvětlí, co která hodnota dělá:
Hodnot je samozřejmě ještě víc, ale nám budou tyto bohatě stačit. Hodnoty se
mohou mezi sebou kombinovat pomocí operátoru | (např. DDBLT_WAIT | DDBLT_COLORFILL).
Na konci této části bude několik příkladů, jak je možno použít uvedené hodnoty.
Druhá struktura již není tak důležitá, ale přesto s její pomocí můžeme nastavit
zajímavé efekty. 2. lpDDBltFxPrincip použití je trošku odlišný, protože musíte nejdříve vytvořit strukturu
typu DDBLTFX, kterou pak předáte funkci
Pokud používáme parametr dwDDFX, musíme funkci Použití ostatních efektů je analogické, přesto pokud byste měli nějaké
speciální požadavky, napište mi. Poznámka: Pokud nenastavíte color key pro povrch, který pak kopírujete s
parametrem DDBLT_KEYSRC, funkce Poznámka: Abyste mohli použít přímo tuto funkci s použitím třídy CSurface a CDisplay musíte využít funkcí CSurface::GetDDrawSurface() a CDisplay::GetBackSurface(), které obě vrací ukazatele na pravé povrchy DirectDraw. 6.3. ZávěrA je tu zase konec. Doufám, že se vám dnešní lekce líbila a že vám přinesla
zase něco nového. Už jsme se určitě dostali za půlku celé teorie DirectDraw.
Příště si vytvoříme třídy CSprite, která bude
představovat jakýkoliv kreslený obrázek. © 2001
| ||||||||||||||||||||
| ||||||||||||||||||||
|