Allegro - Bitmapy do hloubky a page flipping(16. díl) - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

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:

Soutěž

Sponzorem soutěže je:

IDIF

 

Kde se koná výstava fotografií Luďka Vojtěchovského?

V dnešní soutěži hrajeme o:



C/C++

Allegro - Bitmapy do hloubky a page flipping(16. díl)

allegro

29. listopadu 2002, 00.00 | Dnes se podíváme na BITMAPy o něco více do hloubky. Také si vysvětlíme jak funguje page flipping. Všechno si samozřejmě ukážeme na dvou příkladech.

Co je to Sub-Bitmapa?

Dalo by se to přeložit jako pod-bitmapa, to znamená, že je podřazena nějaké jiné BITMAPě. A to také je. Než si vysvětlíme co a jak, podívejme se jak se vytváří. Funkční prototyp vypadá následovně:

BITMAP *create_sub_bitmap(BITMAP *parent, int x, y, width, height);

Funkce vrací pointer na BITMAPu, jako stará známá funkce create_bitmap. Pokud je vše v pořádku tak vrací pointer na nově alokovanou paměť, při chybě vrací jako obvykle NULL. První parametr je rodičovské okno. Tudíž naše nová Sub-Bitmapa je vlastně potomek. rodičovské okno může být například screen, tedy obrazovka. My vlastně jakoby do našeho okna vyřízneme nové okno, které bude s tím rodičovským sdílet paměť (neboli body). To znamená, že když něco zapíšeme do naší bitmapy, objeví se rovnou i na obrazovce v našem případě. Pokud tedy rodičovské okno je screen. x, y jsou souřadnice, odkud se bude začínat s vyříznutím toho obdélníku do rodičovského okna. width a height jsou šířka a výška obdélníku.

Nejlepší bude si uvést, pro jistotu, jako vždy, malý ukázkový příklad:

#include "allegro.h" // netreba predstavovat

int main()
{
	BITMAP *SB;
	
	allegro_init();
    install_keyboard();

    set_color_depth(32);
    if (set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0) != 0) {
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
        allegro_message("Nejde grafika: \n%s\n", allegro_error);
        return 1;
    }

    SB = create_sub_bitmap(screen, 160, 100, 640-160, 480-100);
	
	// nasi SUB_BITMAPU si oramujeme
	rect(SB, 0,0,SB->w-1,SB->h-1, makecol(0,255,0));

	// pokusime se vypsat text na souradnice 0,0
	textout(SB, font, "NA POZICI 0,0 ale ve skutecnosti 160, 100", 0, 0, 
                           makecol(255,0,0)); 
	readkey();

	return 0;
}
END_OF_MAIN();

Na začátku programu si definujeme proměnnou SB typu BITMAP. Tu později využijeme pro naší Sub-bitmapu. Po inicializaci grafiky se konečně vrhneme na vytvoření naší dceřiné bitmapy. Jako rodičovské okno používáme screen, to znamená, tudíž bude hned všechno vidět nebo taky ne (při chybě nebo zápisu mimo oblast). Náš vyříznutý obdélník začíná na souřadnicích 160, 100. A právě pokud budeme zapisovat do SB na souřadnice 0, 0 tak se nám to co vykreslujeme zobrazí na obrazovce právě na pozici 160, 100. Šířku a výšku jsme si ponechali až do levého spodního rohu bitmapy screen. Tedy 640-160 a 480-100. Pro úplnou správnost programu, by bylo ještě třeba zkontrolovat zda se naše bitmapa vytvořila. Nyní přejdeme na vykreslení obdélníku, který naší celou sub-bitmapu orámuje.

Pokud zadáte číslo např. 100 znamená to, že se začne vykreslovat od hodnoty 100 ne tedy 99. Proto je v našem orámování hodnota SB->w-1, jinak by spodní a pravý okraje nabyli vidět. Stejně tak to je i pro druhou souřadnici.

Obrázek z programu vypadá takto:

Okraj jsem 3x zesílil aby byl aspoň trochu vidět.

Video paměť

Video paměť je, že si vlastně vytvoříte jakoby více hlavních obrazovek screen. A pak mezi nimi pouze přepínáte. Prototyp na funkce, která vytváří bitmapy tohoto druhu je podobný jako funkce create_bitmap. Viz zde:

BITMAP *create_video_bitmap(int width, int height);

Vrací stejné hodnoty jako create_bitmap. Tj. chybu nebo pointer na nově alokovanou bitmapu.

Přepínání mezi jednotlivými bitmapami demonstruje následující příklad, který je upravený z příkladu z Allegra (soubor exflip.c):

#include "allegro.h" // netreba predstavovat

int main()
{
	BITMAP *page1, *page2;
	BITMAP *active_page;
	int c;

	allegro_init();
	install_timer();

	if (set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0) != 0) {
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("Unable to set any graphic mode\n%s\n", 
                                                         allegro_error);
		return 1;
	}

	set_palette(desktop_palette);
	text_mode(-1);

	/* now create two video memory bitmaps for the page flipping */
	page1 = create_video_bitmap(SCREEN_W, SCREEN_H);
	page2 = create_video_bitmap(SCREEN_W, SCREEN_H);

	if ((!page1) || (!page2)) {
		set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
		allegro_message("Unable to create two video memory pages\n");
		return 1;
	}

	active_page = page2;

	/* do the animation using page flips... */
	for (c=-32; c<=SCREEN_W+32; c++) {
		clear_to_color(active_page, makecol(255, 255, 255));
		circlefill(active_page, c, SCREEN_H/2, 32, makecol(0, 0, 0));
		textprintf(active_page, font, 0, 0, makecol(0, 0, 0),
			"Page flipping (%s)", gfx_driver->name);
		show_video_bitmap(active_page);

		if (active_page == page1)
			active_page = page2;
		else
			active_page = page1;
	}

	destroy_bitmap(page1);
	destroy_bitmap(page2);

	return 0;
}
END_OF_MAIN();

Tak pěkně po pořádku. Na začátku si deklarujeme 3 bitmapy. Dvě z toho později alokujeme a přidělíme jim paměť. Tu třetí budeme používat jako zástupný pointer. Věřím, že už nemusím po 10 měsících (zhruba) vysvětlovat, co dělá inicializace a pak následné přidělení paměti při vytváření bitmap. Přejdeme tudíž rovnou k věci.

Princip page flippingu

Po obrazovce se prožene vyplněné kolečko pomocí circlefill. Zleva doprava. Je to obdoba Bouble Bufferingu, ale k tomu až na konci článku. Princip spočívá v tom, že pokaždé kreslíme na právě aktivní stránku. To je naše pomocná proměnná active_page. My například kreslíme na stránku č. 2 a mezitím je na obrazovce stránka č. 1. Tudíž, není vidět překreslování, protože kreslíme do paměti, která není právě aktivní. Po-té pomocí funkce show_video_bitmap, přehodíme neaktivní stránku na aktivní. Prakticky ta stránka, která je aktivní je právě neaktivní. Nebo naopak je aktivní, protože do ní právě kreslíme, ale není na obrazovce. Doufám, že to chápete. Je potřeba se aspoň trošku zamyslet jak to funguje (nebo aspoň já jsem musel). Funkce na přehození stránek vypadá takto:

int show_video_bitmap(BITMAP *bitmap);

Při správném přehození vrací nulu a jako parametr si bere tu bitmapu, kterou má přehodit jako aktuální.

Shrnutí

Funkce na vytváření sub-bitmap se hodí např., když byste třeba programovali nějaký náhled a nekontrolovali vstupy, tak aby se vám nestalo, že se vám přepíše něco co nemá. Jinak page flipping co se týče IMHO (mého skromného názoru) tak není špatný. Nicméně radši používám double buffering. Co budeme používat Vy, nechám na Vás.

Zdrojové kódy si můžete, jako obvykle, stáhnout zde.

PS: Mám na Vás milí čtenáři otázku: to byste nejvíce uvítali jako další díl Allegra? Odpovědi můžete posílat prosím na mail nebo psát jako komentáře ke článku. Předem moc děkuji.

Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » C/C++  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: