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 + Bd (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 >>>