Hlavní navigace

Pohled pod kapotu JVM – blending a textury s alfa kanálem v knihovně SDLJava

25. 2. 2014
Doba čtení: 31 minut

Sdílet

Při práci s texturami je v mnoha aplikacích, ať již se jedná o 3D aplikace či o hry s 2D grafikou, nutné využívat textury, jejichž některé texely jsou poloprůhledné či zcela průhledné. V dnešním článku o jazyku Java si ukážeme, jak lze (nejenom) při texturování využívat takzvaný blending nabízený knihovnou SDLJava.

Obsah

1. Pohled pod kapotu JVM – blending a textury s alfa kanálem v knihovně SDLJava

2. Průhlednost a poloprůhlednost fragmentů, alfa kanál a alfa blending

3. Tvar míchací funkce (blending function) využívané při vykreslování

4. Význam konstant předávaných do metody GL.glBlendFunc()

5. Alfa blending prováděný při vykreslování trojrozměrných scén

6. Demonstrační příklad SDLTest23 – alfa blending u textury načtené ze souboru

7. Demonstrační příklad SDLTest24 – nastavení poloprůhlednosti při vykreslování

8. Demonstrační příklad SDLTest25 – ukázka dalších možností blendingu

9. Repositář se zdrojovými kódy všech čtyř dnešních demonstračních příkladů

10. Odkazy na Internetu

1. Pohled pod kapotu JVM – blending a textury s alfa kanálem v knihovně SDLJava

Texturování popsané v předchozí části tohoto seriálu lze využít pro pokrytí stěn trojrozměrných těles nějakým (bitmapovým) vzorkem, ovšem stejná technologie se v současnosti používá například i u stále populárních 2D her, zejména pro vyobrazení scrollujícího pozadí hry nebo pro vykreslení pohybujících se spritů. V těchto oblastech však již nevystačíme se zcela neprůhlednými texturami, ale je nutné nějakým způsobem umět pracovat s texturami, v nichž jsou některé texely průhledné či dokonce poloprůhledné. Samotné grafické akcelerátory, grafická knihovna OpenGL a zprostředkovaně i javovská knihovna SDLJava samozřejmě práci s texturami majícími (polo)průhledné texely podporuje; celá tato funkcionalita je součástí obecnější technologie – blendingu – při němž dochází k míchání barev pixelů již uložených do framebufferu s právě vykreslovanými fragmenty. Podrobnosti o blendingu a především pak o blendingu využívajícího alfa kanál si popíšeme v navazujících kapitolách.

V předchozích částech tohoto seriálu jsme se již několikrát zmínili o barvovém prostoru používaném při práci s barvami v knihovně OpenGL. Barvy jsou v tomto barvovém prostoru popsány pomocí tří barvových složek R (Red), G (Green) a B (Blue). K těmto třem složkám se často přidává ještě složka čtvrtá, nazývaná A (Alfa). Výsledný barvový prostor se proto označuje zkratkou RGBA. Pomocí alfa složky (někdy také nazývané alfa-kanál) lze specifikovat míru průhlednosti, resp. naopak neprůhlednosti vybraných objektů nebo jejich plošek. Alfa složku lze také nastavit samostatně pro každý texel ve vykreslované textuře, čehož se poměrně často využívá při programování mnoha grafických efektů, například výbuchů. A právě tuto vlastnost OpenGL využijeme v dnešních demonstračních příkladech. Při spuštění programu, který používá pro vykreslování grafickou knihovnu OpenGL, je vliv alfa složky na vykreslovanou plošku zakázán. Proto, pokud chceme programovat některé grafické efekty, musíme před vykreslením vhodně nastavit režim míchání již nakreslené části scény s nově vykreslovanými tělesy.

2. Průhlednost a poloprůhlednost fragmentů, alfa kanál a alfa blending

Nejprve si připomeňme, že takzvaný fragment je velmi jednoduchá datová struktura (popisující diskrétní část plochy) složená z barvy pixelu, jeho průhlednosti, vzdálenosti od pozorovatele (popř. převrácené hodnoty vzdálenosti od pozorovatele) a případných dalších podpůrných informací. Framebuffer je v podstatě pravidelně uspořádaná matice (rastr) fragmentů, i když většinou o framebufferu přemýšlíme spíše jako o množině několika specializovaných bufferů (color-buffer, paměť hloubky neboli Z-buffer, stencil buffer, accumulation buffer jakožto zobecněná forma color-bufferu atd.). Barvy fragmentů tvoří ve framebufferu samostatný color-buffer, který se posléze – po vykreslení celé scény – zobrazuje na obrazovce. Rasterizace je proces, kterým se matematický model plošky (polygonu) převádí na jednotlivé fragmenty. Při použití blendingu (tj. míchání barev) musíme nejdříve specifikovat, jakým způsobem se budou kombinovat právě vykreslované fragmenty s hodnotami uloženými ve framebufferu. Způsob míchání barvy uložené ve framebufferu a barvy aktuálně vykreslovaného fragmentu se řídí uživatelem definovanou míchací funkci (blending function). V této (velmi jednoduché) funkci vystupují následující členy:

  • Zdroj (source) je fragment vzniklý rasterizací v právě běžícím rasterizačním procesu (můžeme si představit například vykreslení trojúhelníku postupnou rasterizací/diskretizací plochy trojúhelníku na jednotlivé fragmenty).
  • Cíl (destination) je hodnota již dříve zapsaná do framebufferu, tj. barva fragmentu, který již byl do framebufferu vykreslen dříve. Tato hodnota bude v závislosti na aktuálně nastavené blending funkci přepsána nebo jinak ovlivněna.

V knihovně OpenGL lze stanovit koeficienty míchání pro každou barvovou složku zvlášť. Tak lze jednoduše dosáhnout na první pohled složitých efektů, například maskování jedné barvy apod.

3. Tvar míchací funkce (blending function) využívané při vykreslování

Míchací rovnici (původně ve vektorovém tvaru), která se při blendingu používá pro výpočet nové barvy fragmentu, je možné rozepsat do čtyř rovnic odpovídajících barvovému modelu RGBA:

Rn=RsSr+RdDr
Gn=GsSg+GdDg
Bn=BsSb+BdDb
An=AsSa+AdDa

Význam jednotlivých členů použitých v rovnicích je následující:

# Člen Význam
1 Rn nově vypočtená červená barvová složka
2 Gn nově vypočtená zelená barvová složka
3 Bn nově vypočtená modrá barvová složka
4 An nová hodnota alfa složky
5 Rs červená barvová složka zdrojového fragmentu
6 Gs zelená barvová složka zdrojového fragmentu
7 Bs modrá barvová složka zdrojového fragmentu
8 As alfa složka zdrojového fragmentu
9 Rd červená barvová složka cílového fragmentu
10 Gd zelená barvová složka cílového fragmentu
11 Bd modrá barvová složka cílového fragmentu
12 Ad alfa složka cílového fragmentu
13 Sr míchací faktor pro červenou barvu zdrojového fragmentu
14 Sg míchací faktor pro zelenou barvu zdrojového fragmentu
15 Sb míchací faktor pro modrou barvu zdrojového fragmentu
16 Sa míchací faktor pro alfa složku zdrojového fragmentu
17 Dr míchací faktor pro červenou barvu cílového fragmentu
18 Dg míchací faktor pro zelenou barvu cílového fragmentu
19 Db míchací faktor pro modrou barvu cílového fragmentu
20 Da míchací faktor pro alfa složku cílového fragmentu

Pro praktické použití si však stačí zapamatovat význam jednotlivých písmen: R-red, G-green, B-blue, A-alpha, n-new fragment, s-source fragment, d-destination fragment.

Ve výše uvedených rovnicích je nutné specifikovat míchací faktory (koeficienty) Sr, Sg, Sb, Sa, Dr, Dg, Db a Da, ostatní hodnoty odpovídají barvám a alfa-složkám zdrojových a cílových fragmentů. Koeficienty S a D se nezadávají přímo číselnou hodnotou, protože se mohou měnit v závislosti na barvách zdrojových a cílových fragmentů. Místo toho se používají symboly (symbolické konstanty), jejichž konkrétní hodnota se vypočte automaticky při rasterizaci.

4. Význam konstant předávaných do metody GL.glBlendFunc()

Pro zadání míchacích koeficientů se používá metoda:

org.gljava.opengl.GL.glBlendFunc(long sFactor, long dFactor);

První parametr sFactor určuje způsob výpočtu míchacích faktorů Sr, Sg, Sb a Sa, druhý parametr dFactor pak způsob výpočtu faktorů Dr, Dg, Db a Da.

Pro hodnoty, které lze do těchto parametrů dosadit, platí základní pravidla:

  1. Za sFactor popř. dFactor lze dosadit některou z konstant, které jsou předdefinovány v hlavičkovém souboru gl.h (nativní rozhraní OpenGL) či jako konstanty v rozhraní org.gljava.opengl.GL (knihovna SDLJava).
  2. Některé z těchto konstant lze zadat do obou parametrů. Jedná se například o konstanty GL_ZERO, GL_ONE apod. Význam těchto konstant se samozřejmě liší podle toho, do kterého parametru jsou dosazeny.
  3. Některé konstanty lze použít pouze pro parametr sFactor. Jedná se například o konstanty GL_DST_COLOR nebo GL_ONE_MINUS_DST_COLOR.
  4. Některé konstanty lze naopak použít pouze pro parametrdFactor. Jde o konstanty GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR apod.

V následující tabulce je vypsán význam míchacích faktorů, které můžeme použít pro specifikaci koeficientů míchací rovnice. Ve sloupci Název je jméno faktoru, tj. konstanta definovaná v rozhraní GL. Ve sloupci Použití je označeno, zda se může symbolická konstanta použít pro dosazení do parametru sFactor (S), dFactor (D) nebo do obou parametrů. Ve sloupci Význam jsou ve vektorovém tvaru naznačeny hodnoty zdrojových či cílových koeficientů.

# Název Použití Význam
1 GL_ZERO S nebo D (0, 0, 0, 0)
2 GL_ONE S nebo D (1, 1, 1, 1)
3 GL_DST_COLOR S (Rd, Gd, Bd, Ad)
4 GL_SRC_COLOR D (Rs, Gs, Bs, As)
5 GL_ONE_MINUS_DST_COLOR S (1, 1, 1, 1)-(Rd, Gd, Bd, Ad)
6 GL_ONE_MINUS_SRC_COLOR D (1, 1, 1, 1)-(Rs, Gs, Bs, As)
7 GL_SRC_ALPHA S nebo D (As, As, As, As)
8 GL_ONE_MINUS_SRC_ALPHA S nebo D (1, 1, 1, 1)-(As, As, As, As)
9 GL_DST_ALPHA S nebo D (Ad, Ad, Ad, Ad)
10 GL_ONE_MINUS_DST_ALPHA S nebo D (1, 1, 1, 1)-(Ad, Ad, Ad, Ad)
11 GL_SRC_ALPHA_SATURATE S (f, f, f, 1)   f=min(As, 1-Ad)

5. Alfa blending prováděný při vykreslování trojrozměrných scén

Při vykreslování průhledných či poloprůhledných trojrozměrných těles záleží vizuální vzhled výsledné scény na zvoleném pořadí renderovaných objektů, na rozdíl od neprůhledných těles, kde jsou neviditelné (plně či částečně překryté) stěny automaticky odstraněny díky testu na hloubku fragmentů prováděnou při renderingu s využitím paměti hloubky (nezávisle na pořadí vykreslování). Jako první by se proto při práci s průhlednými tělesy měly vykreslit nejvzdálenější objekty (resp. přesněji řečeno jejich stěny). Zejména proto, že řazení stěn podle vzdálenosti od pozorovatele je časově náročné a nejednoznačné, je nutno metodu pro praktické využití nepatrně vylepšit. Doporučuje se dodržovat následující postup:

  • Nejprve je zapotřebí při startu aplikace alokovat společně s barvovými buffery i paměť hloubky (Z-buffer). V případě použití knihovnySDLJava se tato inicializace může provést automaticky při nastavování grafického režimu.
  • Paměť hloubky (Z-buffer) se musí nastavit do režimu čtení i zápisu (read-write) hloubek fragmentů. Toho dosáhneme zavoláním příkazuGL.glDepthMask(true).
  • Po nastavení a povolení paměti hloubky se vykreslí všechny neprůhledné objekty, resp. přesněji řečeno všechny neprůhledné stěny. Tyto objekty se vzhledem k testu hloubky každého vykreslovaného fragmentu vykreslí korektně, tj. vzdálenější stěny budou korektně překryty bližšími stěnami. To je zapříčiněno funkcí paměti hloubky a komparátoru, který pro každý vykreslovaný fragment testuje, zda je umístěn před nebo za již vykresleným fragmentem, jehož hloubka je v hloubkovém bufferu uložena. Po vykreslení všech neprůhledných objektů je tedy v paměti hloubky zapsána „výšková mapa“ nejbližších vykreslených fragmentů v každé buňce framebufferu (formát zde uložených vzdáleností je většinou reprezentován číslem 1/z, takže by bylo přesnější mluvit o tzn. W-bufferu a ne o Z-bufferu, to je však pouze implementační detail).
  • Před vykreslením průhledných objektů se musí funkce paměti hloubky nastavit do režimu read-only, tj. hloubky fragmentů jsou z hloubkového bufferu pouze čteny při komparaci (a tyto fragmenty jsou popř. odstraněny z dalšího vykreslování). Zápis hodnot do hloubkového bufferu je zakázán, protože průhledné objekty se musí vykreslit i tehdy, pokud jsou schovány za dalším průhledným objektem a neprůhledné objekty se za objekty průhlednými nesmí vymazat. Nastavení hloubkového bufferu do režimu read-only provedeme příkazem/metodou GL.glDepthMask(false).
  • Dalším krokem je programové seřazení průhledných objektů podle jejich hloubky (vzdálenosti) od pozorovatele. Objekty se poté vykreslí v tomto pořadí, nejdříve samozřejmě objekt nejvzdálenější.
  • Složité objekty, tj. objekty, jejichž plošky jsou složeny z mnohoúhelníků, je někdy nutné takzvanou tesselací rozdělit na jednotlivé trojúhelníky, jinak by mohly nastat vizuální chyby při překrývání objektů. K tesselaci je možné použít již existující knihovny (v případě céčka například knihovnu GLU).
  • Po vykreslení všech průhledných objektů se hloubkový buffer nastaví opět do režimu read-write (GL.glDepthMask(true)), aby se v příštím průchodu (snímku) neprůhledné objekty vykreslily korektně.

6. Demonstrační příklad SDLTest23 – alfa blending u textury načtené ze souboru

V dnešním prvním demonstračním příkladu nazvaném SDLTest23 je ukázáno, jakým způsobem je možné použít externí rastrový obrázek s (polo)průhlednými pixely jako texturu použitou při vykreslení vyplněného čtyřúhelníku. Obrázek, který je zde použitý, byl získán z Wikipedie a obsahuje jak zcela neprůhledné pixely, tak i částečně či zcela průhledné pixely. Aby bylo možné korektně uložit celý alfa kanál s osmibitovou hloubkou, byl vybrán formát PNG. Originální obrázek použitý ve funkci textury vypadá takto:

Alfa kanál lze zobrazit následujícím způsobem (průhlednost určuje úroveň šedé, šachovnice značí zcela průhledné pixely):

Na detailu hrany písmena C je patrné, že obrázek skutečně obsahuje i poloprůhledné pixely:

Povšimněte si, že i přesto, že načtená textura obsahuje alfa kanál, je nutné při texturování povolit blending, jinak by se výpočet průhlednosti neprovedl korektně (ostatně sami si můžete vyzkoušet, co se stane, když se následující příkazy zakomentují):

// nastaveni blendingu
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);

Následuje výpis zdrojového kódu demonstračního příkladu SDLTest23:

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
 
import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.video.SDLPixelFormat;
import sdljava.video.SDLSurface;
import sdljava.video.SDLVideo;
 
import org.gljava.opengl.GL;
import org.gljava.opengl.Texture;
import org.gljava.opengl.TextureFactory;
 
 
 
/**
 * Dvacaty treti demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Texturovani, objekt typu Texture a alfa blending.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest23 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 600;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 600;
 
    /**
     * Bitova hloubka vybraneho grafickeho rezimu.
     * (0 znamena automaticky vyber, ovsem lze samozrejme pouzit
     * i hodnoty 8, 16, 24 ci 32, podle vlastnosti graficke karty)
     */
    private static final int GFX_BPP = 0;
 
    /**
     * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani.
     */
    private static SDLSurface initVideo() throws SDLException {
        final long flags = SDLVideo.SDL_OPENGL | SDLVideo.SDL_DOUBLEBUF;
        return SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags);
    }
 
    /**
     * Nastaveni transformacnich matic a barvy pozadi framebufferu.
     */
    private static void initScene(GL gl, int width, int height) {
        // nastaveni projekcni matice
        gl.glMatrixMode(gl.GL_PROJECTION);
 
        // jednotkova matice
        gl.glLoadIdentity();
 
        // mapovani abstraktnich souradnic do souradnic okna ci cele obrazovky
        gl.glOrtho(0, width, height, 0, -1, 1);
 
        // nastaveni modelview matice
        gl.glMatrixMode(gl.GL_MODELVIEW);
        gl.glLoadIdentity();
 
        // viditelna oblast
        gl.glViewport(0, 0, width, height);
 
        // vypnuti pameti hloubky pri vykreslovani
        gl.glDisable(gl.GL_DEPTH_TEST);
 
        // opakovani textury
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_REPEAT);
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_REPEAT);
 
        // volba filtru
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST);
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST);
 
        // vylepseni zobrazovani v pripade pouziti perspektivni projekce
        gl.glHint(gl.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_NICEST);
 
        // barva pozadi framebufferu pro volani glClear()
        gl.glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
    }
 
    /**
     * Vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL.
     */
    private static void drawScene(GL gl, Texture texture) {
 
        // vymazani framebufferu
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
 
        // zakaz prace s texturami
        gl.glDisable(gl.GL_TEXTURE_2D);
 
        gl.glBegin(GL.GL_LINES);
            gl.glColor3f(1.0f, 0.0f, 0.0f);
            gl.glVertex2i(0, 0);
            gl.glColor3f(1.0f, 0.0f, 1.0f);
            gl.glVertex2i(600, 600);
            gl.glColor3f(0.0f, 1.0f, 0.0f);
            gl.glVertex2i(600, 0);
            gl.glColor3f(1.0f, 1.0f, 0.0f);
            gl.glVertex2i(0, 600);
        gl.glEnd();
 
        // povoleni prace s texturami
        gl.glEnable(GL.GL_TEXTURE_2D);
 
        // nastaveni blendingu
        gl.glEnable(GL.GL_BLEND);
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
 
        texture.bind(gl);
 
        // vykresleni ctyruhelniku
        gl.glBegin(GL.GL_QUADS);
            gl.glTexCoord2f(0.0f, 0.0f);
            gl.glVertex2i(100, 100);
            gl.glTexCoord2f(1.0f, 0.0f);
            gl.glVertex2i(500, 100);
            gl.glTexCoord2f(1.0f, 1.0f);
            gl.glVertex2i(500, 500);
            gl.glTexCoord2f(0.0f, 1.0f);
            gl.glVertex2i(100, 500);
        gl.glEnd();
 
        gl.glFlush();                                        // provedeni a vykresleni vsech zmen
    }
 
    /**
     * Spusteni osmeho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace video subsystemu knihovny SDL
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
 
            // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani
            SDLSurface screen = initVideo();
 
            // inicializace celoobrazovkoveho grafickeho rezimu
            GL gl = screen.getGL();
 
            // nastaveni transformacnich matic a barvy pozadi framebufferu
            initScene(gl, GFX_WIDTH, GFX_HEIGHT);
 
            // nacteni textury
            Texture texture = TextureFactory.getFactory().loadTexture(gl, "c.png");
 
            // vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL
            drawScene(gl, texture);
 
            // prepnuti predniho a zadniho bufferu
            screen.glSwapBuffers();
 
            // ukonceni cele aplikace po peti sekundach
            Thread.sleep(5000);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
        // zobrazit ziskane informace
    }
 
}

Skript pro překlad na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest23.java

Dávkový soubor pro překlad na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest23.java

Skript pro spuštění na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
java -cp .:$SDL_JAVA_LIBS/sdljava.jar -Djava.library.path=$SDL_JAVA_LIBS SDLTest23

Dávkový soubor pro spuštění na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
java -cp .;%SDL_JAVA_LIBS%\sdljava.jar -Djava.library.path=%SDL_JAVA_LIBS% SDLTest23

Obrázek 1: Scéna vykreslená po spuštění demonstračního příkladu SDLTest23.

7. Demonstrační příklad SDLTest24 – nastavení poloprůhlednosti při vykreslování

Jak jsme si již řekli v úvodních kapitolách, netýká se nastavení průhlednosti pouze texelů, z nichž se skládají textury, ale průhlednost je možné nastavit i při vykreslování různých geometrických primitiv podporovaných knihovnou SDLJava. V dnešním druhém demonstračním příkladu je ukázáno využití metody GL.glColor4f() pro specifikaci barvy a současně i průhlednosti při vykreslování čtverců. V programové smyčce umístěné do uživatelské metody drawScene() je postupně vykreslen čtverec vyplněný různými barvami, jehož neprůhlednost je postupně nastavována na hodnoty 0%, 20%, 40%, 60%, 80% a 100%:

// nastaveni blendingu
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
 
float[][] colors = {
    {1.0f, 1.0f, 1.0f},
    {0.0f, 0.0f, 1.0f},
    {1.0f, 0.0f, 0.0f},
    {0.0f, 1.0f, 0.0f},
    {0.0f, 1.0f, 1.0f},
    {0.0f, 0.0f, 0.0f},
};
 
// vykresleni serie nekolika ctvercu ruznou barvou
// s ruznou pruhlednosti
float alpha;
int x, y;
for (y = 0; y < colors.length; y++) {
    for (x = 0, alpha = 0.0f; x <= 500; x += 100, alpha += 0.2f) {
        drawSquare(gl, x, y*100, colors[y][0], colors[y][1], colors[y][2], alpha);
    }
}

Následuje výpis zdrojového kódu příkladu SDLTest24:

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
 
import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.video.SDLPixelFormat;
import sdljava.video.SDLSurface;
import sdljava.video.SDLVideo;
 
import org.gljava.opengl.GL;
import org.gljava.opengl.Texture;
import org.gljava.opengl.TextureFactory;
 
 
 
/**
 * Dvacaty ctvrty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Alfa blending pri vykreslovani.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest24 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 600;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 600;
 
    /**
     * Bitova hloubka vybraneho grafickeho rezimu.
     * (0 znamena automaticky vyber, ovsem lze samozrejme pouzit
     * i hodnoty 8, 16, 24 ci 32, podle vlastnosti graficke karty)
     */
    private static final int GFX_BPP = 0;
 
    /**
     * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani.
     */
    private static SDLSurface initVideo() throws SDLException {
        final long flags = SDLVideo.SDL_OPENGL | SDLVideo.SDL_DOUBLEBUF;
        return SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags);
    }
 
    /**
     * Nastaveni transformacnich matic a barvy pozadi framebufferu.
     */
    private static void initScene(GL gl, int width, int height) {
        // nastaveni projekcni matice
        gl.glMatrixMode(gl.GL_PROJECTION);
 
        // jednotkova matice
        gl.glLoadIdentity();
 
        // mapovani abstraktnich souradnic do souradnic okna ci cele obrazovky
        gl.glOrtho(0, width, height, 0, -1, 1);
 
        // nastaveni modelview matice
        gl.glMatrixMode(gl.GL_MODELVIEW);
        gl.glLoadIdentity();
 
        // viditelna oblast
        gl.glViewport(0, 0, width, height);
 
        // vypnuti pameti hloubky pri vykreslovani
        gl.glDisable(gl.GL_DEPTH_TEST);
 
        // barva pozadi framebufferu pro volani glClear()
        gl.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
    }
 
    /**
     * Vykresleni ctverce.
     */
    private static void drawSquare(GL gl, int x, int y, float r, float g, float b, float a) {
        // vykresleni ctyruhelniku
        gl.glColor4f(r, g, b, a);
        gl.glBegin(GL.GL_QUADS);
            gl.glVertex2i(x+10, y+10);
            gl.glVertex2i(x+90, y+10);
            gl.glVertex2i(x+90, y+90);
            gl.glVertex2i(x+10, y+90);
        gl.glEnd();
    }
 
    /**
     * Vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL.
     */
    private static void drawScene(GL gl) {
        // vymazani framebufferu (bile pozadi)
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
 
        // zakaz blendingu
        gl.glDisable(GL.GL_BLEND);
 
        // vykresleni mrizky
        gl.glColor3f(0.0f, 0.0f, 0.0f);
        gl.glBegin(GL.GL_LINES);
        for (int i=0; i < GFX_WIDTH; i+=20) {
            gl.glVertex2i(i, 0);
            gl.glVertex2i(i, GFX_HEIGHT);
        }
        for (int i=0; i < GFX_HEIGHT; i+=20) {
            gl.glVertex2i(0, i);
            gl.glVertex2i(GFX_WIDTH, i);
        }
        gl.glEnd();
 
        // nastaveni blendingu
        gl.glEnable(GL.GL_BLEND);
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
 
        float[][] colors = {
            {1.0f, 1.0f, 1.0f},
            {0.0f, 0.0f, 1.0f},
            {1.0f, 0.0f, 0.0f},
            {0.0f, 1.0f, 0.0f},
            {0.0f, 1.0f, 1.0f},
            {0.0f, 0.0f, 0.0f},
        };
 
        // vykresleni serie nekolika ctvercu ruznou barvou
        // s ruznou pruhlednosti
        float alpha;
        int x, y;
        for (y = 0; y < colors.length; y++) {
            for (x = 0, alpha = 0.0f; x <= 500; x += 100, alpha += 0.2f) {
                drawSquare(gl, x, y*100, colors[y][0], colors[y][1], colors[y][2], alpha);
            }
        }
 
        gl.glFlush();      // provedeni a vykresleni vsech zmen
    }
 
    /**
     * Spusteni demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace video subsystemu knihovny SDL
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
 
            // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani
            SDLSurface screen = initVideo();
 
            // inicializace celoobrazovkoveho grafickeho rezimu
            GL gl = screen.getGL();
 
            // nastaveni transformacnich matic a barvy pozadi framebufferu
            initScene(gl, GFX_WIDTH, GFX_HEIGHT);
 
            // vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL
            drawScene(gl);
 
            // prepnuti predniho a zadniho bufferu
            screen.glSwapBuffers();
 
            // ukonceni cele aplikace po peti sekundach
            Thread.sleep(5000);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
        // zobrazit ziskane informace
    }
 
}

Skript pro překlad na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest24.java

Dávkový soubor pro překlad na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest24.java

Skript pro spuštění na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
java -cp .:$SDL_JAVA_LIBS/sdljava.jar -Djava.library.path=$SDL_JAVA_LIBS SDLTest24

Dávkový soubor pro spuštění na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
java -cp .;%SDL_JAVA_LIBS%\sdljava.jar -Djava.library.path=%SDL_JAVA_LIBS% SDLTest24

Obrázek 1: Scéna vykreslená po spuštění demonstračního příkladu SDLTest24.

8. Demonstrační příklad SDLTest25 – ukázka dalších možností blendingu

Dnešní třetí a současně i poslední demonstrační příklad je implementován ve třídě s názvem SDLTest25. V tomto příkladu je ukázán efekt většiny kombinací operátorů předávaných do metody GL.glBlendFunc(). Celočíselné konstanty odpovídající operátorům zdrojových fragmentů i fragmentů cílových jsou uloženy ve dvojici polí nazvaných sourceOperatorsdestOperators:

long[] sourceOperators = {
    GL.GL_ZERO,
    GL.GL_ONE,
    GL.GL_DST_COLOR,
    GL.GL_ONE_MINUS_DST_COLOR,
    GL.GL_SRC_ALPHA,
    GL.GL_ONE_MINUS_SRC_ALPHA,
    GL.GL_DST_ALPHA,
    GL.GL_ONE_MINUS_DST_ALPHA
};
long[] destOperators = {
    GL.GL_ZERO,
    GL.GL_ONE,
    GL.GL_SRC_COLOR,
    GL.GL_ONE_MINUS_SRC_COLOR,
    GL.GL_SRC_ALPHA,
    GL.GL_ONE_MINUS_SRC_ALPHA,
    GL.GL_DST_ALPHA,
    GL.GL_ONE_MINUS_DST_ALPHA
};

Vzájemné kombinace těchto operátorů jsou nastavovány ve vnořené programové smyčce:

// vykresleni serie nekolika ctvercu ruznou barvou
// s ruznou pruhlednosti
float alpha;
int x, y;
for (y = 0; y < destOperators.length; y++) {
    for (x = 0; x < sourceOperators.length; x++) {
        // nastaveni blendingu
        gl.glBlendFunc(sourceOperators[x], destOperators[y]);
        drawSquare(gl, x*100, y*100, 0.0f, 0.0f, 1.0f, 0.5f);
    }
}

Za povšimnutí stojí i způsob nastavení barvy pozadí framebufferu:

// barva pozadi framebufferu pro volani glClear()
gl.glClearColor(1.0f, 1.0f, 1.0f, 0.5f);

Úplný zdrojový kód demonstračního příkladu SDLTest25 má tvar:

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
 
import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.video.SDLPixelFormat;
import sdljava.video.SDLSurface;
import sdljava.video.SDLVideo;
 
import org.gljava.opengl.GL;
import org.gljava.opengl.Texture;
import org.gljava.opengl.TextureFactory;
 
 
 
/**
 * Dvacaty paty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Alfa blending pri vykreslovani.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest25 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 800;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 800;
 
    /**
     * Bitova hloubka vybraneho grafickeho rezimu.
     * (0 znamena automaticky vyber, ovsem lze samozrejme pouzit
     * i hodnoty 8, 16, 24 ci 32, podle vlastnosti graficke karty)
     */
    private static final int GFX_BPP = 0;
 
    /**
     * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani.
     */
    private static SDLSurface initVideo() throws SDLException {
        final long flags = SDLVideo.SDL_OPENGL | SDLVideo.SDL_DOUBLEBUF;
        return SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags);
    }
 
    /**
     * Nastaveni transformacnich matic a barvy pozadi framebufferu.
     */
    private static void initScene(GL gl, int width, int height) {
        // nastaveni projekcni matice
        gl.glMatrixMode(gl.GL_PROJECTION);
 
        // jednotkova matice
        gl.glLoadIdentity();
 
        // mapovani abstraktnich souradnic do souradnic okna ci cele obrazovky
        gl.glOrtho(0, width, height, 0, -1, 1);
 
        // nastaveni modelview matice
        gl.glMatrixMode(gl.GL_MODELVIEW);
        gl.glLoadIdentity();
 
        // viditelna oblast
        gl.glViewport(0, 0, width, height);
 
        // vypnuti pameti hloubky pri vykreslovani
        gl.glDisable(gl.GL_DEPTH_TEST);
 
        // barva pozadi framebufferu pro volani glClear()
        gl.glClearColor(1.0f, 1.0f, 1.0f, 0.5f);
    }
 
    /**
     * Vykresleni ctverce.
     */
    private static void drawSquare(GL gl, int x, int y, float r, float g, float b, float a) {
        // vykresleni ctyruhelniku
        gl.glColor4f(r, g, b, a);
        gl.glBegin(GL.GL_QUADS);
            gl.glVertex2i(x+10, y+10);
            gl.glVertex2i(x+90, y+10);
            gl.glVertex2i(x+90, y+90);
            gl.glVertex2i(x+10, y+90);
        gl.glEnd();
    }
 
    /**
     * Vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL.
     */
    private static void drawScene(GL gl) {
        // vymazani framebufferu (bile pozadi)
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
 
        // zakaz blendingu
        gl.glDisable(GL.GL_BLEND);
 
        // vykresleni mrizky
        gl.glColor3f(0.0f, 0.0f, 0.0f);
        gl.glBegin(GL.GL_LINES);
        for (int i=0; i < GFX_WIDTH; i+=20) {
            gl.glVertex2i(i, 0);
            gl.glVertex2i(i, GFX_HEIGHT);
        }
        for (int i=0; i < GFX_HEIGHT; i+=20) {
            gl.glVertex2i(0, i);
            gl.glVertex2i(GFX_WIDTH, i);
        }
        gl.glEnd();
 
        // povoleni blendingu
        gl.glEnable(GL.GL_BLEND);
 
        long[] sourceOperators = {
            GL.GL_ZERO,
            GL.GL_ONE,
            GL.GL_DST_COLOR,
            GL.GL_ONE_MINUS_DST_COLOR,
            GL.GL_SRC_ALPHA,
            GL.GL_ONE_MINUS_SRC_ALPHA,
            GL.GL_DST_ALPHA,
            GL.GL_ONE_MINUS_DST_ALPHA
        };
        long[] destOperators = {
            GL.GL_ZERO,
            GL.GL_ONE,
            GL.GL_SRC_COLOR,
            GL.GL_ONE_MINUS_SRC_COLOR,
            GL.GL_SRC_ALPHA,
            GL.GL_ONE_MINUS_SRC_ALPHA,
            GL.GL_DST_ALPHA,
            GL.GL_ONE_MINUS_DST_ALPHA
        };
 
        // vykresleni serie nekolika ctvercu ruznou barvou
        // s ruznou pruhlednosti
        float alpha;
        int x, y;
        for (y = 0; y < destOperators.length; y++) {
            for (x = 0; x < sourceOperators.length; x++) {
                // nastaveni blendingu
                gl.glBlendFunc(sourceOperators[x], destOperators[y]);
                drawSquare(gl, x*100, y*100, 0.0f, 0.0f, 1.0f, 0.5f);
            }
        }
 
        gl.glFlush();      // provedeni a vykresleni vsech zmen
    }
 
    /**
     * Spusteni demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace video subsystemu knihovny SDL
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
 
            // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani
            SDLSurface screen = initVideo();
 
            // inicializace celoobrazovkoveho grafickeho rezimu
            GL gl = screen.getGL();
 
            // nastaveni transformacnich matic a barvy pozadi framebufferu
            initScene(gl, GFX_WIDTH, GFX_HEIGHT);
 
            // vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL
            drawScene(gl);
 
            // prepnuti predniho a zadniho bufferu
            screen.glSwapBuffers();
 
            // ukonceni cele aplikace po peti sekundach
            Thread.sleep(5000);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
        // zobrazit ziskane informace
    }
 
}

Skript pro překlad na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest25.java

Dávkový soubor pro překlad na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest25.java

Skript pro spuštění na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
java -cp .:$SDL_JAVA_LIBS/sdljava.jar -Djava.library.path=$SDL_JAVA_LIBS SDLTest25

Dávkový soubor pro spuštění na Windows:

UX DAy - tip 2

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
java -cp .;%SDL_JAVA_LIBS%\sdljava.jar -Djava.library.path=%SDL_JAVA_LIBS% SDLTest25

Obrázek 1: Scéna vykreslená po spuštění demonstračního příkladu SDLTest25.

9. Repositář se zdrojovými kódy všech čtyř dnešních demonstračních příkladů

Všechny čtyři dnes popsané demonstrační příklady byly společně s podpůrnými skripty určenými pro jejich překlad a následné spuštění uloženy do Mercurial repositáře dostupného na adrese http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/. Podobně jako tomu bylo i v předchozích šesti dílech tohoto seriálu, i ke dnešním příkladům jsou přiloženy skripty využitelné pro jejich překlad a spuštění. Navíc byly přidány i skripty využitelné ve Windows:

# Zdrojový soubor/skript Umístění souboru v repositáři
1 SDLTest23.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest23/SDLTest23.ja­va
2 SDLTest23_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest23/SDLTest23_com­pile.sh
3 SDLTest23_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest23/SDLTest23_com­pile_sys.sh
4 SDLTest23_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest23/SDLTest23_run­.sh
5 SDLTest23_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest23/SDLTest23_run_sys­.sh
6 SDLTest23_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest23/SDLTest23_com­pile.bat
7 SDLTest23_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest23/SDLTest23_run­.bat
     
8 SDLTest24.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest24/SDLTest24.ja­va
9 SDLTest24_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest24/SDLTest24_com­pile.sh
10 SDLTest24_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest24/SDLTest24_com­pile_sys.sh
11 SDLTest24_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest24/SDLTest24_run­.sh
12 SDLTest24_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest24/SDLTest24_run_sys­.sh
13 SDLTest24_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest24/SDLTest24_com­pile.bat
14 SDLTest24_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest24/SDLTest24_run­.bat
     
15 SDLTest25.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest25/SDLTest25.ja­va
16 SDLTest25_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest25/SDLTest25_com­pile.sh
17 SDLTest25_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest25/SDLTest25_com­pile_sys.sh
18 SDLTest25_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest25/SDLTest25_run­.sh
19 SDLTest25_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest25/SDLTest25_run_sys­.sh
20 SDLTest25_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest25/SDLTest25_com­pile.bat
21 SDLTest25_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/c0a962ff72e6/sdlja­va/SDLTest25/SDLTest25_run­.bat

10. Odkazy na Internetu

  1. glDrawArrays
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawArrays­.xml
  2. glDrawElements
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawElemen­ts.xml
  3. glDrawArraysInstanced
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawArraysIn­stanced.xml
  4. glDrawElementsInstanced
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawElemen­tsInstanced.xml
  5. Root.cz: Seriál Grafická knihovna OpenGL
    http://www.root.cz/serialy/graficka-knihovna-opengl/
  6. Root.cz: Seriál Tvorba přenositelných grafických aplikací využívajících knihovnu GLUT
    http://www.root.cz/serialy/tvorba-prenositelnych-grafickych-aplikaci-vyuzivajicich-knihovnu-glut/
  7. Best Practices for Working with Vertex Data
    https://developer.apple.com/li­brary/ios/documentation/3ddra­wing/conceptual/opengles_pro­grammingguide/Techniquesfor­WorkingwithVertexData/Techni­quesforWorkingwithVertexDa­ta.html
  8. SDL 1.2 Documentation: SDL_Surface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlsurface.html
  9. SDL 1.2 Documentation: SDL_PixelFormat
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlpixelformat.html
  10. SDL 1.2 Documentation: SDL_LockSurface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdllocksurface.html
  11. SDL 1.2 Documentation: SDL_UnlockSurface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlunlocksurface.html
  12. SDL 1.2 Documentation: SDL_LoadBMP
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlloadbmp.html
  13. SDL 1.2 Documentation: SDL_SaveBMP
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlsavebmp.html
  14. SDL 1.2 Documentation: SDL_BlitSurface
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlblitsurface.html
  15. SDL 1.2 Documentation: SDL_VideoInfo
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlvideoinfo.html
  16. SDL 1.2 Documentation: SDL_GetVideoInfo
    http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlgetvideoinfo.html
  17. Class BufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/i­mage/BufferStrategy.html
  18. Class Graphics
    http://docs.oracle.com/ja­vase/1.5.0/docs/api/java/aw­t/Graphics.html
  19. Double Buffering and Page Flipping
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/doublebuf.html
  20. BufferStrategy and BufferCapabilities
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/bufferstrategy.html
  21. Java:Tutorials:Double Buffering
    http://content.gpwiki.org/in­dex.php/Java:Tutorials:Dou­ble_Buffering
  22. Double buffer in standard Java AWT
    http://www.codeproject.com/Ar­ticles/2136/Double-buffer-in-standard-Java-AWT
  23. Java 2D: Hardware Accelerating – Part 1 – Volatile Images
    http://www.javalobby.org/fo­rums/thread.jspa?threadID=16840&tstar­t=0
  24. Java 2D: Hardware Accelerating – Part 2 – Buffer Strategies
    http://www.javalobby.org/ja­va/forums/t16867.html
  25. How does paintComponent work?
    http://stackoverflow.com/qu­estions/15544549/how-does-paintcomponent-work
  26. A Swing Architecture Overview
    http://www.oracle.com/technet­work/java/architecture-142923.html
  27. Class javax.swing.JComponent
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html
  28. Class java.awt.Component
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.html
  29. Class java.awt.Component.BltBufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.BltBufferStrategy.html
  30. Class java.awt.Component.FlipBufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.FlipBufferStrategy­.html
  31. Metoda java.awt.Component.isDoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.html#isDoubleBuffe­red()
  32. Metoda javax.swing.JComponent.is­DoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html#isDouble­Buffered()
  33. Metoda javax.swing.JComponent.set­DoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html#setDouble­Buffered(boolean)
  34. Javadoc – třída GraphicsDevice
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsDevice.html
  35. Javadoc – třída GraphicsEnvironment
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsEnvironment.html
  36. Javadoc – třída GraphicsConfiguration
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsConfiguration.html
  37. Javadoc – třída DisplayMode
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Dis­playMode.html
  38. Lesson: Full-Screen Exclusive Mode API
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/
  39. Full-Screen Exclusive Mode
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/exclusivemode.html
  40. Display Mode
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/displaymode.html
  41. Using the Full-Screen Exclusive Mode API in Java
    http://www.developer.com/ja­va/other/article.php/3609776/U­sing-the-Full-Screen-Exclusive-Mode-API-in-Java.htm
  42. Java quick guide: JVM Instruction Set (tabulka všech instrukcí JVM)
    http://www.mobilefish.com/tu­torials/java/java_quickgu­ide_jvm_instruction_set.html
  43. The JVM Instruction Set
    http://mpdeboer.home.xs4a­ll.nl/scriptie/node14.html
  44. MultiMedia eXtensions
    http://softpixel.com/~cwrig­ht/programming/simd/mmx.phpi
  45. SSE (Streaming SIMD Extentions)
    http://www.songho.ca/misc/sse/sse­.html
  46. Timothy A. Chagnon: SSE and SSE2
    http://www.cs.drexel.edu/~tc365/mpi-wht/sse.pdf
  47. Intel corporation: Extending the Worldr's Most Popular Processor Architecture
    http://download.intel.com/techno­logy/architecture/new-instructions-paper.pdf
  48. SIMD architectures:
    http://arstechnica.com/ol­d/content/2000/03/simd.ar­s/
  49. GC safe-point (or safepoint) and safe-region
    http://xiao-feng.blogspot.cz/2008/01/gc-safe-point-and-safe-region.html
  50. Safepoints in HotSpot JVM
    http://blog.ragozin.info/2012/10/sa­fepoints-in-hotspot-jvm.html
  51. Java theory and practice: Synchronization optimizations in Mustang
    http://www.ibm.com/develo­perworks/java/library/j-jtp10185/
  52. How to build hsdis
    http://hg.openjdk.java.net/jdk7/hot­spot/hotspot/file/tip/src/sha­re/tools/hsdis/README
  53. Java SE 6 Performance White Paper
    http://www.oracle.com/technet­work/java/6-performance-137236.html
  54. Lukas Stadler's Blog
    http://classparser.blogspot­.cz/2010/03/hsdis-i386dll.html
  55. How to build hsdis-amd64.dll and hsdis-i386.dll on Windows
    http://dropzone.nfshost.com/hsdis.htm
  56. PrintAssembly
    https://wikis.oracle.com/dis­play/HotSpotInternals/Prin­tAssembly
  57. The Java Virtual Machine Specification: 3.14. Synchronization
    http://docs.oracle.com/ja­vase/specs/jvms/se7/html/jvms-3.html#jvms-3.14
  58. The Java Virtual Machine Specification: 8.3.1.4. volatile Fields
    http://docs.oracle.com/ja­vase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4
  59. The Java Virtual Machine Specification: 17.4. Memory Model
    http://docs.oracle.com/ja­vase/specs/jls/se7/html/jls-17.html#jls-17.4
  60. The Java Virtual Machine Specification: 17.7. Non-atomic Treatment of double and long
    http://docs.oracle.com/ja­vase/specs/jls/se7/html/jls-17.html#jls-17.7
  61. Open Source ByteCode Libraries in Java
    http://java-source.net/open-source/bytecode-libraries
  62. ASM Home page
    http://asm.ow2.org/
  63. Seznam nástrojů využívajících projekt ASM
    http://asm.ow2.org/users.html
  64. ObjectWeb ASM (Wikipedia)
    http://en.wikipedia.org/wi­ki/ObjectWeb_ASM
  65. Java Bytecode BCEL vs ASM
    http://james.onegoodcooki­e.com/2005/10/26/java-bytecode-bcel-vs-asm/
  66. BCEL Home page
    http://commons.apache.org/bcel/
  67. Byte Code Engineering Library (před verzí 5.0)
    http://bcel.sourceforge.net/
  68. Byte Code Engineering Library (verze >= 5.0)
    http://commons.apache.org/pro­per/commons-bcel/
  69. BCEL Manual
    http://commons.apache.org/bcel/ma­nual.html
  70. Byte Code Engineering Library (Wikipedia)
    http://en.wikipedia.org/wiki/BCEL
  71. BCEL Tutorial
    http://www.smfsupport.com/sup­port/java/bcel-tutorial!/
  72. Bytecode Engineering
    http://book.chinaunix.net/spe­cial/ebook/Core_Java2_Volu­me2AF/0131118269/ch13lev1sec6­.html
  73. Bytecode Outline plugin for Eclipse (screenshoty + info)
    http://asm.ow2.org/eclipse/index.html
  74. Javassist
    http://www.jboss.org/javassist/
  75. Byteman
    http://www.jboss.org/byteman
  76. Java programming dynamics, Part 7: Bytecode engineering with BCEL
    http://www.ibm.com/develo­perworks/java/library/j-dyn0414/
  77. The JavaTM Virtual Machine Specification, Second Edition
    http://java.sun.com/docs/bo­oks/jvms/second_edition/html/VMSpec­TOC.doc.html
  78. The class File Format
    http://java.sun.com/docs/bo­oks/jvms/second_edition/html/Clas­sFile.doc.html
  79. javap – The Java Class File Disassembler
    http://docs.oracle.com/ja­vase/1.4.2/docs/tooldocs/win­dows/javap.html
  80. javap-java-1.6.0-openjdk(1) – Linux man page
    http://linux.die.net/man/1/javap-java-1.6.0-openjdk
  81. Using javap
    http://www.idevelopment.in­fo/data/Programming/java/mis­cellaneous_java/Using_javap­.html
  82. Examine class files with the javap command
    http://www.techrepublic.com/ar­ticle/examine-class-files-with-the-javap-command/5815354
  83. aspectj (Eclipse)
    http://www.eclipse.org/aspectj/
  84. Aspect-oriented programming (Wikipedia)
    http://en.wikipedia.org/wi­ki/Aspect_oriented_program­ming
  85. AspectJ (Wikipedia)
    http://en.wikipedia.org/wiki/AspectJ
  86. EMMA: a free Java code coverage tool
    http://emma.sourceforge.net/
  87. Cobertura
    http://cobertura.sourceforge.net/
  88. jclasslib bytecode viewer
    http://www.ej-technologies.com/products/jclas­slib/overview.html

Byl pro vás článek přínosný?