CZ NeHe OpenGL
Lekce 8

Lekce 8 - Blending

Další typ speciálního efektu v OpenGL je blending, neboli průhlednost. Kombinace pixelů je určena alfa hodnotou barvy a použitou funkcí. Nabývá-li alfa 0.0f, materiál zprůhlední, hodnota 1.0f přináší pravý opak.

Rovnice blendingu

Nemáte rádi matematiku a chcete vidět, jak se používá průhlednost prakticky, pak přeskočte tuto část. Pro někoho může být nepochopitelná.

(Rs Sr + Rd Dr, Gs Sg + Gd Dg, Bs Sb + Bd Db, As Sa + Ad Da)

OpenGL vypočítá výsledek blendingu dvou pixelů z předchozí rovnice. 's' a 'r' představují zdrojový a cílový pixel. 'S' a 'D' jsou činitelé blendingu. Tyto hodnoty určují jak moc budou pixely průhledné. Většina obyčejných hodnot pro S a D jsou (As, As, As, As) (AKA zdrojová alfa) pro S a (1, 1, 1, 1) - (As, As, As, As) (AKA jedna minus zdrojová alfa) pro D. Rovnice bude vypadat takto:

(Rs As + Rd (1 - As), Gs As + Gd (1 - As), Bs As + Bs (1 - As), As As + Ad (1 - As))

Nyní už se budeme věnovat praktickému kódu. Použijeme kód z lekce 7.

#include <windows.h>// Hlavičkový soubor pro Windows

#include <stdio.h>// Hlavičkový soubor pro standardní vstup/výstup

#include <gl\gl.h>// Hlavičkový soubor pro OpenGL32 knihovnu

#include <gl\glu.h>// Hlavičkový soubor pro Glu32 knihovnu

#include <gl\glaux.h>// Hlavičkový soubor pro Glaux knihovnu

HDC hDC = NULL;// Privátní GDI Device Context

HGLRC hRC = NULL;// Trvalý Rendering Context

HWND hWnd = NULL;// Obsahuje Handle našeho okna

HINSTANCE hInstance;// Obsahuje instanci aplikace

bool keys[256];// Pole pro ukládání vstupu z klávesnice

bool active = TRUE;// Ponese informaci o tom, zda je okno aktivní

bool fullscreen = TRUE;// Ponese informaci o tom, zda je program ve fullscreenu

Blending se v OpenGL zapíná stejně, jako všechno ostatní. Nastavíme jeho parametry a vypneme depth buffer, jinak by se objekty za průhlednými polygony nevykreslily. To sice není správná cesta k blendingu, ale ve většině jednoduchých projektů bude fungovat. Správná cesta k vykreslení průhledných (alfa < 1.0) polygonů je obrácení depth bufferu (nejvzdálenější objekty se vykreslují první). Např.: uvažujme polygon 1 jako vzdálenější od pozorovatele. Správně by měl být tedy vykreslen polygon 2 a až po něm polygon 1. Když se na to podíváte, jako ve skutečnosti, všechno světlo se mísí za těmito dvěma polygony (jsou-li průhledné), musí se vykreslit polygon 2 první a potom polygon 1. Raději řaďte průhledné objekty podle hloubky a kreslete je až po vykreslení celé scény se zapnutým depth bufferem, jinak můžete dostat špatné výsledky. Vím že je to těžké, ale je to jediná správná cesta.

bool light;// Světlo ON/OFF

bool blend;// Blending OFF/ON

bool lp;// Stisknuto L?

bool fp;// Stisknuto F?

bool bp;// Stisknuto B?

GLfloat xrot;// X Rotace

GLfloat yrot;// Y Rotace

GLfloat xspeed;// Rychlost x rotace

GLfloat yspeed;// Rychlost y rotace

GLfloat z=-5.0f;// Hloubka v obrazovce

GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f };// Okolní světlo

GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f };// Přímé světlo

GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f };// Pozice světla

GLuint filter;// Použitý texturový filtr

GLuint texture[3];// Ukládá 3 textury

Posuneme se dolů na LoadGLTextures() a změníme jméno textury.

// Funkce LoadGLTextures()

if(TextureImage[0]=LoadBMP("Data/Glass.bmp"))// Loading bitmapy

Další řádky přidáme do InitGL(). Nastavení jimi objekty na plný jas a 50% alfu (průhlednost). To znamená, že když bude blending zapnut, objekt bude z 50% průhledný. Alfa hodnota 0.0 je úplná průhlednost, 1.0 je opak. Druhý řádek nastaví typ blendingu.

// Funkce InitGL()

glColor4f(1.0f,1.0f,1.0f,0.5f);// Plný jas, 50% alfa

glBlendFunc(GL_SRC_ALPHA,GL_ONE);// Funkce blendingu pro průsvitnost založená na hodnotě alfa

Podívejte se na následující kód, je umístěn na konci lekce ve funkci WinMain().

// Funkce WinMain()

if (keys['B'] && !bp)// Klávesa B - zapne blending

{

bp=TRUE;

blend = !blend;

if(blend)

{

glEnable(GL_BLEND);// Zapne blending

glDisable(GL_DEPTH_TEST);// Vypne hloubkové testování

}

else

{

glDisable(GL_BLEND);// Vypne blending

glEnable(GL_DEPTH_TEST);// Zapne hloubkové testování

}

}

if (!keys['B'])// Uvolnění B

{

bp=FALSE;

}

Není to jednoduché? Stačí zapnout blending, vypnout hloubkové testování a zavolat funkci glColor4f(r,g,b,a) - vše, co nakreslíme bude průhledné.

Jak ale nastavíme barvu použitou v textuře? Jednoduše, v modulated texture modu, každý pixel mapovaný texturou je násobkem aktuální barvy. Když je kreslená barva (0.5, 0.6, 0.4), násobíme barvou a předáme (0.5, 0.6, 0.4, 0.2) (alfa se rovná 1.0, není-li určena).

Alfa z textury

Alfa hodnota použitá pro průhlednost může být přečtena z textury pouze jako barva. To se dělá tak, že se předá alfa do obrázku při nahrávání a poté se ve funkci glTexImage2D() použije pro barevný formát GL_RGBA.

napsal: Tom Stanis <stanis (zavináč) cs.wisc.edu>
přeložil: Jiří Rajský - RAJSOFT junior <predator.jr (zavináč) seznam.cz>

Zdrojové kódy

Lekce 8

<<< Lekce 7 | Lekce 9 >>>


Tento offline překladů NeHe OpenGL Tutoriálů lze volně šířit podle Obecné veřejné licence GNU Nové okno, jeho nejnovější verze je dostupná na domovském webu projektu CZ NeHe OpenGL Nové okno.

Michal Turek - Woq <WOQ (zavináč) email.cz> (24.02.2004).