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.
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 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>