OpenGL (16.) - Fading
Ve starých dobách DOSu bylo ztmavení obrazovky relativně snadné - stačilo jen při každém snímku dekrementovat paletu. Nyní v době 16ti nebo 32ti bitů vzniká problém s tím, že paletu nemáme. Pokud chcete tak můžete ztmavit pixel po pixelu odečtením jedničky od každé RGB hodnoty, já jsem na to šel trochu jinak...
Základní myšlenka je vhodně umístit černý obdelník tak, aby zakrýval celou plochu obrazovky. Jemu budeme měnit průhlednost podle toho, jestli chceme zesvětlení nebo ztmavení scény. Proměnné FadeOut a FadeIn nám budou při vykreslování říkat, jestli máme průhlednost pro snímek zvýšit nebo snížit. Alpha je pak samotná průhlednost.
type KFadeC = class
private
public
FadeOut: boolean; //setmeni
FadeIn: boolean; //zesvetleni
alpha: single;
DisplayWidth, DisplayHeight: integer;
procedure SetFadeOut;
procedure SetFadeIn;
function Draw(ElapsedTime: single): boolean;
constructor Create;
end;
V proměnných DisplayWidth a DisplayHeight si uchováváme rozlišení obrazovky. Pro ztmavení bude sloužit procedura SetFadeOut, pro zesvětlení SetFadeIn.
//Setmeni procedure KFadeC.SetFadeOut; begin FadeIn := false; FadeOut := true; Alpha := 0; end; //Zesvetleni procedure KFadeC.SetFadeIn; begin FadeOut := false; FadeIn := true; Alpha := 1; end;
A hlavní část dnešního kódu je zde. Po každém vyrenderování scény zavoláme funkci Draw s parametrem kolik času trvala poslední smyčka renderování. Tato hodnota je velmi důležitá pro plynulost jak setmívání ale i jiných událostí ve hře (hlavně pohyb).
function KFadeC.Draw(ElapsedTime: single): boolean;
begin
if FadeOut or FadeIn then begin
glMatrixMode (GL_PROJECTION);
glPushMatrix;
glLoadIdentity;
glOrtho (0,DisplayWidth,DisplayHeight,0,-1000,1000);
glMatrixMode (GL_MODELVIEW);
glPushMatrix;
glLoadIdentity;
glPushAttrib (GL_DEPTH_BUFFER_BIT or GL_ENABLE_BIT or GL_COLOR_BUFFER_BIT);
glDisable (GL_DEPTH_TEST);
if Alpha < 0 then begin
FadeIn := false;
end else
if (Alpha >= 0) AND (Alpha <= 1 ) then begin
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
EnableBlending;
if FadeOut then
Alpha := Alpha + ElapsedTime / 5 //5 udává počet sekund
else
Alpha := Alpha - ElapsedTime / 5;
glColor4f(0, 0, 0, Alpha);
glRectd(0, 0 , DisplayWidth, DisplayHeight);
DisableBlending;
end else
if Alpha >= 1 then begin
glColor3f(0, 0, 0);
glRectd(0, 0 , DisplayWidth, DisplayHeight);
end;
glEnable(GL_DEPTH_TEST);
glPopAttrib;
glPopMatrix;
glMatrixMode (GL_PROJECTION);
glPopMatrix;
glMatrixMode (GL_MODELVIEW);
result := true;
end else result := false;
end;
Teď bych měl zdroják trošku vysvětlit. Pokud je aktivní buď zesvětlování nebo setmění scény, pak voláním glOrtho změníme pohled. Nový rozsah v okně OpenGL je v ose X 0 až 640, v ose Y 0 až 480 a v ose Z -100 až 100. To uděláme proto, aby se nám lépe umisťoval text na obrazovku. Je li alpha menší než jedna, pak ukončíme zesvětlování. Je-li větší jak jedna, pak zobrazíme přes celou obrazovku černý čtverec a ukončíme ztmavování. Je-li Alpha v rozsahu od 0 do 1, pak povolíme a nastavíme průhlednost a také vykreslíme poloprůhledný obdelník přes celou obrazovku. Pak načteme zpět uložené matice.
V samotném programu pak stačí volat:
var Fade: KFadeC; begin Fade := KFadeC.Create; Fade.DisplayWidth := Width; Fade.DisplayHeight := Height; Fade.SetFadeIn;
Pak v renderovací smyčce voláme(ElapsedTime je v sekundách):
Fade.Draw(ElapsedTime);
Tímto jsme docílili vlastnosti, že po zavolání SetFadeIn se obrazovka začne pomalu zesvětlovat (asi 5 sekund) až do normálu, pak už se nic neděje. Zavoláme-li SetFadeOut, obrazovka se začne stmívat až do černé, kde zůstane - GAME OVER.
Tento efekt (ale asi jiným algoritmem) je využit snad ve všech hrách a teď si ho můžete jednoduše vytvořit i vy. Co se týče rychlost, pak klesne zhruba o 10 fps - Při startu nebo ukončení hry nám to moc nevadí a navíc to vypadá pěkně...
Pro zajímavost jsem tento kus zdrojáku vyšťoural ze hry quake2. Je vidět, že na stmavení obrazovky šli podobně - přes obdelník vykreslený přes celou obrazovku. Nejedná se o plynulý fading, ale stmavení v menu ap.
void Draw_FadeScreen (void)
{
qglEnable (GL_BLEND);
qglDisable (GL_TEXTURE_2D);
qglColor4f (0, 0, 0, 0.8);
qglBegin (GL_QUADS);
qglVertex2f (0,0);
qglVertex2f (vid.width, 0);
qglVertex2f (vid.width, vid.height);
qglVertex2f (0, vid.height);
qglEnd();
qglColor4f (1,1,1,1);
qglEnable (GL_TEXTURE_2D);
qglDisable (GL_BLEND);
}
Vyšlo 30.10.2002, v blogu: 0 1 2 3 4 5 6 7 8
Děkuji, že jste se rozhodl(a) přečíst tento článek. Budu rád i za komentář. Pokud Vás tento článek zaujal a rádi byste jej doporučili ostatním, podpořte mně prosím tím, že věnujete minutku svého času a uděláte mi reklamu na linkuj.cz, vybrali.sme.sk či jagg.cz. Přeji příjemné čtení
Poslední články
- CZ,cracky a cd keygen
- Tenisti v akci...
- První příspěvek v blogu
- Zobrazení terénu ve 3D grafice
- Engine (2.) - Timing
- Engine (1.) - Logování
- OpenGL (17.) - Light mapping - úvod
- OpenGL (16.) - Fading
- Herní grafické enginy (3.) - GLScene
- Herní grafické enginy (2.) - Pythian Project
- OpenGL (15.) - Ucelený částicový systém - pokračování
- OpenGL (14.) - Ucelený částicový systém
- OpenGL (13.) - Nastavení OpenGL v jazyce C/C++
- 3D Studio MAX (13.) - Popis modifikačních funkcí ve 3D Studiu MAX
- OpenGL (12.) - visualizační plugin pro WinAMP