[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)
  • Allegro - Knihovna pro programování her IV.
    Další z řady dílů o Allegru nás seznámí s Double Bufferingem a blíže s funkcí blit. Také se naučíme vytvářet svoje vlastní virtuální obrazovky a samozřejmostí je i příklad na kterém si vše předvedeme.
    Allegro - Knihovna pro programování her
    Předchozí díl: Allegro - Knihovna pro programování her III.

    Následující díl: Allegro - Myš a klávesnice (5. díl)
    Autor: Matoušek Pavel
    Rubrika: C/C++
    Publikováno: 11.01. 2002
     Tisk článku
    Poslat odkaz emailem
     

    V minulém díle jsem slíbil, že si povíme o funkci blit a o Double Bufferingu, ale ještě před tím bych Vám rád řekl něco, na co jsem byl upozorněn v komentáři.

    Funkce allegro_exit(); může být vynechána a allegro se o uvolnění "postará". A pokud používáte C++ tak by Vám mohla nadělat tato funkce pěknou paseku. Například kdyby jste ji zavolali v destruktoru. Dokonce, i když se podíváte na zdrojové soubory, které jsou ke stažení na internetu tak se i tam čas od času vynechává. Ale hodně se vyskytuje ve starších zdrojových souborech. Já tuto funkci prozatím používat budu, abych nepletl začátečníky.

    Funkce blit a kouzla s ní


    O samotné funkci blit si povídat nebudeme, ale seznámíme se s jejími odvozeninami a to s funkcemi masked_blit, stretch_blit a kombinací obojího masked_stretch_blit (přičemž tato funkce není ve verzi 3.12, ale objevila se až později ).

    Jako první si povíme o masked_blit, ale ještě před tím si řekneme o tom co je to mód transparent nebo transparent color.

    Pokud programujete webové stránky a chcete vykreslit na nějaký vzorek např. červené kolečko tak použijete formát .gif a červené kolečko namalujete např. na bílý povrch a bílou barvu nastavíte jako transparentní což je právě transparent color.
    Nebo taky existuje to, že například se zapne v programu mód transparent a ten třeba nevykresluje černou barvu. Možností je více, ale většinou jsou podobné těmto.
    Dalo by se říci, že je to jedno a totéž.

    Ale teď k tomu jak funguje funkce masked_blit, jejíž prototyp vypadá naprosto stejně jako u funkce blit až na název:

    void masked_blit(BITMAP *source, BITMAP *dest, int source_x, int source_y, int dest_x, int dest_y, int width, int height);

    Tato funkce používá obě dvě výše jmenované metody, ale pro kterou se rozhodne to záleží na barevné hloubce jestli je 8bpp nebo větší.

    Pokud používáte 8bpp tak máte paletu o 256 prvcích typu RGB jak jsme si ukázali minule. A právě tady se používá první verze a to transparent color. A barva transparentní bude taková jakou navolíte do palety s indexem 0. To znamená, že pokud chcete mít jako transparentní barvu černou nastavíte si to např. tímto způsobem:

    pal[0].r = 0;
    pal[0].g = 0;
    pal[0].b = 0;

    kde pal je typu PALETTE samozřejmě.

    Ale když používáte 15, 16, 24 nebo 32 bpp tak je zde použit druhý způsob. Vykreslujete obrázek pomocí funkce masked_blit a tím jakoby zapnete mód transparent, který nevykresluje světlou/jasnou růžovou barvu, kde položky RED a BLUE mají hodnotu 255 a GREEN má hodnotu 0. Barvu dostanete například pomocí makecol(255, 0, 255);. Další zajímavá funkce je stretch_blit:

    void stretch_blit(BITMAP *source, BITMAP *dest, int source_x, source_y, source_width, source_height, int dest_x, dest_y, dest_width, dest_height);

    Tato funkce má deset parametrů, ale není to tolik jak by se mohlo na první pohled zdát. První dva parametry jsou zdrojová a cílová BITMAPa. Další 4 parametry určují zdrojový obdélník a poslední 4 parametry určují cílový obdélník. To znamená, že pomocí této funkce můžete tzv. ZOOMovat. Například máte obrázek o rozměrech 100 * 100 pixelů v proměnné bmp a potřebuje ho překreslit na obrazovku aby měl 200*200 pixelů volala by se funkce s následujícími parametry:

    stretch_blit(bmp, screen, 0, 0, 100, 100, 0, 0, 200, 200);

    nebo obecněji:

    stretch_blit(bmp, screen, 0, 0, bmp->w, bmp->h, 0, 0, bmp->w * 2, bmp->h * 2);

    Jestli potřebujete naprogramovat preview obrázků tak se nemusíte s tím programovat "ručně", ale tato funkce Vám ulehčí spoustu práce.

    Další funkce je kombinací těchto dvou zmiňovaných a to funkce:

    void masked_stretch_blit(BITMAP *source, BITMAP *dest, int source_x, source_y, source_w, source_h, int dest_x, dest_y, dest_w, dest_h);

    Parametry stejné jako u funkce stretch_blit akorát používá mód transparent nebo transparent color.

    Virtuální obrazovky


    S tím jsme se nepřímo setkali už minule při ukládání obrázků, ale dneska si o tom povíme více.

    Jako první bych představil asi nejpoužívanější funkci pro práci s virtuálními obrazovkami a to:

    BITMAP *create_bitmap(int width, int height);

    Příklad:
    BITMAP *backbuffer;

    backbuffer = create_bitmap(SCREEN_W, SCREEN_H);


    První řádek inicializuje proměnnou backbuffer, což je pointer na typ BITMAP a druhý řádek nám vytvoří virtuální obrazovku o rozměrech obrazovky a o stejné barevné hloubce jako je screen.

    Další podobná funkce je:

    BITMAP *create_bitmap_ex(int color_depth, int width, int height);

    Jediný rozdíl spočívá v tom, že si můžeme sami určit barevnou hloubku. Jinak jsou si tyto dvě funkce naprosto rovnocenné.

    A nakonec ještě pár zajímavých funkcí, které nám leccos vypoví o našich BITMAPách:

    int bitmap_color_depth(BITMAP *bmp);

    Tato fce vrátí barevnou hloubku.

    int bitmap_mask_color(BITMAP *bmp);

    A tato funkce nám pro změnu vrátí transparentní barvu. Tedy pro mód 8bpp vrací pal[0] (podle toho co jsme si jako transparentni barvu nadefinovali) a pro zbytek bpp nám vrací číslo kde leží transparentní barva. Tedy makecol(255, 0, 255);. Samozřejmě se to liší podle toho jaký používáme mód jestli 15 bpp nebo 32 bpp apod.

    Double Buffering


    Se používá poměrně často i v dnešních hrách. Proč taky ne, když je jednoduchý a i rychlý. Samozřejmě existují i jiné metody jako je Page Flipping, Triple Buffering atd., ale pro naše příklady je bohatě dostačující, alespoň prozatím. Tyto metody si ale vysvětlíme až někdy příště.

    Double Buffering funguje na principu dvou virtuálních obrazovek typu BITMAP v Allegru. Dodávám v Allegru z toho důvodu, že např. v DDraw ver. 7.0 to je typu LPDIRECTDRAWSURFACE7 a říká se tomu obecně surface, což je rozhraní nebo spíše pointer na rozhraní IDirectDrawSurface7, protože celé DirectX je založeno na COM (Component Object Model). Ale o tom až v seriálu o DirectX.

    První virtuální obrazovka je vlastně ( už v našem případě ) proměnná screen, tedy to co vidíme na obrazovce. Druhá proměnná může být např. backbuffer opět typu BITMAP.
    Znamená to, že všechno vykreslujete do backbufferu ( dále jen BB ) a pak to funkcí blit zkopírujete na obrazovku tedy do proměnné screen nebo si proto můžete vytvořit funkci např.:

    void flip_to_screen(void)
    {
      blit(backbuffer, screen, 0, 0, 0, 0, backbuffer->w, backbuffer->h);
    }


    a pak v programu po vykreslení všeho do BB akorát zavoláte tuto funkci ( flip_to_screen(); ) a je to na obrazovce. Obě dvě proměnné budou globální samozřejmě.
    A k čemu vlastně slouží? Double Buffering Vám totiž odstraní tzv. blikání.

    Příklad
    Tradice je tradice a my si vše ukážeme na příkladu, který demonstruje to, co jsme se dnes naučili :). Pro ukázku uvádím jen jeden. Zbytek příkladů je ke stažení na konci.
    #include <dos.h>
    #include <stdlib.h>
    #include <time.h>
    #include "allegro.h" // hlav. soubor. allegra
    
    // virt. obr. pro DB - DOUBLE BUFFERING
    BITMAP *backbuffer;
    char ss[20];
    
    // zapne allegro a grafiku vcetne backbufferu
    // kdyz chyba - konec programu
    int init(void)
    {
      int result;
    
      if ( (result = allegro_init() ) != 0 )  // inicializuje allegro
      {
    
        printf("Nejde Allegro! - %s\n\nZmackni cokoliv.",allegro_error);
        getch();
        return 0;
      }
      // nahodi mod 640 * 480 * 8
    
      set_color_depth(8);
      if ( (result = set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0) ) < 0) {
        set_gfx_mode(GFX_TEXT, 80, 25, 0, 0);
        printf("Nejde grafika! - %s\n\nZmackni cokoliv.",allegro_error);
        getch();
        allegro_exit();
        return 0;
      }
      set_palette(desktop_palette);
    
      backbuffer = create_bitmap(SCREEN_W, SCREEN_H);
    }
    
    // zkopiruje backbuffer na obrazovku
    void flip_to_screen(void)
    {
      blit(backbuffer, screen, 0, 0, 0, 0, backbuffer->w, backbuffer->h);
    }
    
    int main(void)
    {
      int i;
      PALETTE pal;
    
      init();
    
      // kresli kolecko bez DB
      for (i = 0; i < 640; i+=5) {
    
        clear(screen);
        circlefill(screen, i, SCREEN_H / 2, 50, makecol(255, 0, 0));
        textout(screen,font,"BEZ DOUBLE BUFFERINGU",i,0,makecol(0, 0, 255));
    
        delay(40);
      }
    
      clear(screen);
    
      // kresli kolecko s DB
      for (i = 0; i < 640; i+=5) {
        clear(backbuffer);
        circlefill(backbuffer, i, SCREEN_H / 2, 50, makecol(255, 0, 0));
        textout(backbuffer,font,"S DOUBLE BUFFERINGEM",i,0,makecol(0, 0, 255));
    
        flip_to_screen();
        delay(40);
      }
    
    
      sprintf(ss, "%d", bitmap_mask_color(backbuffer));
    
      textout(screen, font, ss , 20, 20, makecol(0, 0, 255));
    
    
      getch();
      // uvolni pamet
      destroy_bitmap(backbuffer);
    
      // mozne i vynechat
      allegro_exit();
    
      return 0;
    }


    Příště se seznámíme s klávesnicí a myší. Nakonec zakončíme vše příkladem, který bude obsahovat Double Buffering, načítání a ukládání obrázků a to vše budeme ovládat pomocí klávesnice či myši.

    Zdrojové soubory (jsou 2) si můžete stáhnou zde.

    Nezapomeňte (tedy pokud ji už nemáte) si taky pořídit novou verzi Allegra 4.0. Od příště pracujeme s ní.

    Zpět na začátek stránky

    Pavel Matoušek
    Osobní stránky autora naleznete na www.pmatousek.com

    Hodnocení článku
    1 | 2 | 3 | 4 | 5
    Aktuální známka: 2.53
    (Počet známek: 3271)

    Komentáře k článku
    Pavel Matoušek - Autor04.02.15:41Instalace a konfigurace již příští díl č. 7!!!
    Radek Chalupa12.01.8:30Hodnocení
    Pavel Matoušek12.01.10:12RE: Hodnocení
    Pavel Matoušek12.01.0:41Nove jmeno...
    mol12.01.10:31RE: Nove jmeno...
    Pavel Matoušek12.01.11:12RE: RE: Nove jmeno...
    mol12.01.12:36RE: RE: RE: Nove jmeno...
    Pavel Matoušek12.01.13:09RE: RE: RE: RE: Nove jmeno...
    mol12.01.14:15RE: RE: RE: RE: RE: Nove jmeno...
    Pavel Matoušek12.01.14:41RE: RE: RE: RE: RE: RE: Nove jmeno...
    mol12.01.16:10RE: RE: RE: RE: RE: RE: RE: Nove jmeno...
    Pavel Matoušek12.01.16:22RE: RE: RE: RE: RE: RE: RE: RE: Nove jmeno...
    mol11.01.20:35jeste takova drobnustka
    mol11.01.19:25k druhemu odstavci
    Pavel Matoušek11.01.19:53RE: k druhemu odstavci
    mol11.01.20:25RE: RE: k druhemu odstavci
         





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