Hlavní navigace

Pohled pod kapotu JVM – práce s texturami v knihovně SDLJava

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

Sdílet

V dnešní části seriálu o programovacím jazyce Java i o virtuálním stroji Javy si popíšeme princip texturování implementovaný v knihovně OpenGL i způsob práce s texturami (načtení, použití, specifikace vlastností) v SDLJava s využitím tříd org.gljava.opengl.Texture a org.gljava.opengl.TextureFactory.

Obsah

1. Pohled pod kapotu JVM – práce s texturami v knihovně SDLJava

2. Nastavení parametrů textur v OpenGL

3. Rozšířená podpora formátů textur

4. Třída TextureFactory a objekt typu Texture

5. Demonstrační příklad SDLTest20 – texturování a objekt typu Texture

6. Demonstrační příklad SDLTest21 – opakování textury

7. Demonstrační příklad SDLTest22 – volba filtru použitého při zvětšování a zmenšování textury

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

9. Odkazy na Internetu

1. Pohled pod kapotu JVM – práce s texturami v knihovně SDLJava

V dnešní části tohoto seriálu si ukážeme, jak je možné s využitím knihovny SDLJava a s ní propojené knihovny OpenGL používat texturování. Texturováním (resp. poněkud přesněji řečeno nanášením textur) je označen princip obarvení povrchu zobrazovacích těles různými obrazci. Důležité přitom je, že se nijak nemění geometrické vlastnosti těles, pouze se jiným způsobem zobrazuje jejich povrch. Obrazce, které se na povrch těles nanášejí, se nazývají textury (textures). Tyto textury jsou většinou představovány plošnými obrázky (dvoudimenzionální textury), některé grafické systémy však podporují i vykreslování jednorozměrných a dokonce trojrozměrných (objemových) textur.

Obrazce pro textury se mohou vytvářet několika způsoby. Buď je možné použít klasické rastrové obrázky (vzniklé například namalováním, vyfocením nebo naskenováním) nebo se textura může vytvářet pomocí různých algoritmů založených většinou na procedurálních a fraktálních technikách – tímto způsobem vznikají takzvané procedurální textury. Procedurální textury lze použít buď pro výpočet rastrových obrázků před vlastním vykreslováním (po výpočtu obrázku se tato textura chová jako každý jiný rastrový obrázek se všemi výhodami i nevýhodami) nebo se může výpočet textur provádět v reálném čase až při vykreslování, přičemž se parametry výpočtu textury nastaví podle aktuální velikosti a orientace plošky, na kterou se textura nanáší. Tuto druhou možnost však OpenGL přímo nepodporuje, výpočet procedurálních textur je tedy nutné provádět „ručně“, popř. lze použít shadery, tj. programy vykonávané přímo na GPU.

V dalším textu se budeme téměř výhradně zabývat texturami reprezentovanými rastrovými obrázky, nezávisle na tom, jakým způsobem vznikly. I když řeč bude převážně o dvoudimenzionálních texturách (tedy bitmapáchpixmapách), většina zde popisovaných vlastností se vztahuje i na jednorozměrné a trojrozměrné textury. Podobně jako je bitmapa či pixmapa složená ze základních rastrových elementů (pixelů), tak je textura složena z texelů. Pixel a texel mají stejné vlastnosti a podobný či dokonce ekvivalentní způsob uložení v paměti. V dalším textu však budeme oba pojmy navzájem oddělovat, tj. pixel je element vykreslovaný na obrazovce, kdežto texel je rastrový element (většinou) dvourozměrné textury. Texturování potom spočívá v nanášení texelů na vykreslovaný povrch.

Použití rastrových textur s sebou přináší samozřejmě své výhody i nevýhody. Jak jsme si již řekli, používá se technika texturování jako určitá náhrada při zobrazování složitých povrchů těles (zeď, omítka, dřevo, kámen), kdy se tento obecně nehomogenní povrch nahradí ploškou s nanesenou texturou. Záleží na vhodné volbě textury, velikosti objektu a nasvícení celé scény, zda tato náhrada bude dostatečná, či zda uživatel uvidí vizuální chyby ve scéně. Další předností texturování je, že pokud u textur použijeme průhlednost (nazývanou také alfa kanál), je možné vizuálně změnit geometrii předmětů, protože se předmět může na některých místech jevit jako děravý. Poznamenejme, že při použití průhlednosti je nutné programově setřídit průhledné nebo poloprůhledné plošky, jelikož by v tomto případě Z-buffer (paměť hloubky) nepracoval korektně – i průhledné texely by se „vykreslily“ a poškodily tak informaci o hloubce fragmentu uloženou v Z-bufferu.

2. Nastavení parametrů textur v OpenGL

V OpenGL lze také zvolit různé filtrace textur, režimy mapování textur na plošky, multitexturování a další grafické efekty, které si dále probereme. Musíme si však uvědomit, že pokud použijeme některý grafický efekt, který není grafickým akcelerátorem podporován, dojde k výpočtům pomocí hlavního procesoru počítače, což značně zpomaluje celý systém. Proto je nejprve vhodné zjistit, které efekty jsou na grafickém akcelerátoru podporovány a případně dát uživateli naší aplikace na výběr mezi kvalitou a rychlostí zobrazení (s těmito omezeními se dnes už prakticky nesetkáme).

Parametry textury (tj. například způsob, jakým je textura mapována na povrch vykreslovaného tělesa) lze nastavit voláním metody:

org.gljava.opengl.GL:
void glTexParameterf(
    long target,
    long pname,
    float param
);

nebo metody:

org.gljava.opengl.GL:
void glTexParameteri(
    long target,
    long pname,
    int param
);

Alternativně lze také zavolat metody, které jako svůj poslední parametr akceptují místo skalární hodnoty pole hodnot, které je však v případě SDLJava reprezentováno bufferem:

org.gljava.opengl.GL:
void glTexParameterfv(
    long target,
    long pname,
    java.nio.FloatBuffer params
);
void glTexParameteriv(
    long target,
    long pname,
    java.nio.IntBuffer params
);

První parametr (target) může podle zvolené dimenze textury nabývat hodnot GL.GL_TEXTURE_1D (jednodimenzionální texura, tj. barevný přechod) nebo GL.GL_TEXTURE_2D (nejběžnější, rastrová textura). Hodnoty parametrů dalších dvou parametrů pnamevalue jsou uvedeny v následujícím seznamu:

  • Parametr GL.GL_TEXTURE_WRAP_S:
    tímto parametrem specifikujeme, zda se má při překročení rozsahu texturovací souřadnice ve směru osy s provést opakování motivu na textuře (value=GL.GL_REPEAT) nebo protažení první či poslední hodnoty (value=GL.GL_CLAMP). Opakování motivu na textuře je vhodné použít v případech, že zobrazujeme různé na sebe navazující motivy, například cihlové zdi, podlahy apod. Protažením textury lze v některých případech zamezit vizuálním artefaktům, které by se mohly objevit při napojování textur. Překročení rozsahu není tedy v žádném případě chybou, vyvoláme ho například příkazem GL.glTexCoord2f(2.0, 0.5).
  • Parametr GL.GL_TEXTURE_WRAP_T:
    tento parametr má podobný význam jako parametr předchozí s tím rozdílem, že se místo na souřadnici ve směru osy s vztahuje na souřadnici ve směru osy t. U 1D textur nemá hodnota tohoto parametru vliv na zobrazení textury, použitelný je pouze u 2D textur. Opakování resp. protažení textury lze pro souřadnice ve všech směrech nastavovat nezávisle.
  • Parametr GL.GL_TEXTURE_MIN_FILTER:
    tímto parametrem je možné zvolit filtr použitý při zmenšování textury, tj. tehdy, jestliže na plochu jednoho vykreslovaného pixelu musíme použít barvy několika sousedních texelů. Nejjednodušší a nejrychlejší filtr se volí hodnotou GL.GL_NEAREST. U tohoto filtru se barva vykreslovaného pixelu vypočte z barvy texelu, jehož souřadnice nejpřesněji odpovídají zadaným souřadnicím do textury. Poněkud sofistikovanější filtr se zadává hodnotou GL.GL_LINEAR, kdy se barva vykreslovaného pixelu spočítá pomocí bilineární interpolace z barev sousedních texelů. Další čtyři filtry (GL.GL_NEAREST_MIPMAP_NEAREST, GL.GL_NEAREST_MIPMAP_LINEAR, GL.GL_LINEAR_MIPMAP_NEARESTGL.GL_LINEAR_MIPMAP_LINEAR) využívají takzvané mipmapy, jejichž význam si vysvětlíme příště.
  • Parametr GL.GL_TEXTURE_MAX_FILTER:
    tímto parametrem se volí filtr použitý při zvětšování textury, tj. v případě, že vykreslovaný pixel obsahuje pouze malou plochu texelu. Možné hodnoty jsou GL.GL_NEAREST (použije se nejbližší texel) nebo GL.GL_LINEAR (použije se lineární interpolace mezi barvami sousedních texelů).
  • Parametr GL.GL_TEXTURE_BORDER_COLOR:
    tímto parametrem lze zvolit barvu rámečku okolo textury (pokud je rámeček použit, tj. pokud má nenulovou šířku). V případě zadávání barvy je nutné použít příkazy GL.glTexParameteriv() resp. GL.glTexParameterfv(), protože barva se zadává jako vektor (pole, buffer) čtyř složek R, G, B a A. Implicitní barva rámečku je (0, 0, 0, 0), tedy černá.

3. Rozšířená podpora formátů textur

Kromě základních formátů textur je možné používat v OpenGL verze 1.2 a vyšších i další rozšířené formáty. Jaká výhoda plyne z použití takových formátů? Především jde o to, že použitím některých formátů s malou nebo dostatečnou bitovou hloubkou můžeme ušetřit paměť alokovanou pro textury. Druhou výhodou je možnost použít textury načtené z různých externích souborů, které mají mnohdy exotický formát. V následující tabulce budou ukázány rozšířené formáty textur spolu se základním formátem a typem dat pro každou barvovou složku:

Rozšířený formát Základní formát Počet bitů R Počet bitů G Počet bitů B Počet bitů A Luminance (úroveň bílé) Intenzita (úroveň bílé=alpha)
GL_ALPHA4 GL_ALPHA       4    
GL_ALPHA8 GL_ALPHA       8    
GL_ALPHA12 GL_ALPHA       12    
GL_ALPHA16 GL_ALPHA       16    
GL_LUMINANCE4 GL_LUMINANCE         4  
GL_LUMINANCE8 GL_LUMINANCE         8  
GL_LUMINANCE12 GL_LUMINANCE         12  
GL_LUMINANCE16 GL_LUMINANCE         16  
GL_LUMINANCE4_ALPHA4 GL_LUMINANCE_ALPHA       4 4  
GL_LUMINANCE6_ALPHA2 GL_LUMINANCE_ALPHA       2 6  
GL_LUMINANCE8_ALPHA8 GL_LUMINANCE_ALPHA       8 8  
GL_LUMINANCE12_ALPHA4 GL_LUMINANCE_ALPHA       4 12  
GL_LUMINANCE12_ALPHA12 GL_LUMINANCE_ALPHA       12 12  
GL_LUMINANCE16_ALPHA16 GL_LUMINANCE_ALPHA       16 16  
GL_INTENSITY4 GL_INTENSITY           4
GL_INTENSITY8 GL_INTENSITY           8
GL_INTENSITY12 GL_INTENSITY           12
GL_INTENSITY16 GL_INTENSITY           16
GL_R3_G3_B2 GL_RGB 3 3 2      
GL_RGB4 GL_RGB 4 4 4      
GL_RGB5 GL_RGB 5 5 5      
GL_RGB8 GL_RGB 8 8 8      
GL_RGB10 GL_RGB 10 10 10      
GL_RGB12 GL_RGB 12 12 12      
GL_RGB16 GL_RGB 16 16 16      
GL_RGBA2 GL_RGBA 2 2 2 2    
GL_RGBA4 GL_RGBA 4 4 4 4    
GL_RGB5_A1 GL_RGBA 5 5 5 1    
GL_RGBA8 GL_RGBA 8 8 8 8    
GL_RGB10_A2 GL_RGBA 10 10 10 2    
GL_RGBA12 GL_RGBA 12 12 12 12    
GL_RGBA16 GL_RGBA 16 16 16 16    

Pro šetření pamětí jsou zajímavé například formáty GL_R3_G3_B2, kdy paměť pro jeden texel zabírá pouze jeden byte, nebo GL_RGB5_A1, kde každá barvová složka zabírá 5 bitů (celkem je tedy pro barvu vyhrazeno 15 bitů) a alfa složka jeden bit (rozlišujeme tedy pouze průhlednost či neprůhlednost texelu).

4. Třída TextureFactory a objekt typu Texture

Grafická knihovna OpenGL neobsahuje žádné funkce pro načtení textury ze souboru či ke konverzím mezi různými formáty pixelů/texelů. Programátoři využívající pouze OpenGL tedy musí příslušný programový kód napsat ručně, ovšem vzhledem k tomu, že se jedná stále o stejné operace, existuje v knihovně SDLJava dvojice tříd, které dokážou texturu načíst a posléze s ní jednoduše pracovat. První z těchto tříd se jmenuje org.gljava.opengl.TextureFactory a najdeme v ní jak statickou metodu getFactory() vracející instanci této třídy (konstruktor není viditelný), tak i trojici metod loadTexture() pro načtení textury z externího souboru, popř. z obrázku typu BufferedImage (což se může hodit v případě, že je textura například vytvořena procedurálně):

# Návratový typ Metoda Popis
1 TextureFactory getFactory() získání instance třídy TextureFactory
2 Texture loadTexture(GL gl, java.lang.String path) načtení textury ze souboru specifikovaného jménem
3 Texture loadTexture(GL gl, java.net.URL url) načtení textury ze souboru/zdroje specifikovaného URL
4 Texture loadTexture(GL gl, java.awt.image.BufferedImage bufferedImage, int target, int dstPixelFormat, int minFilter, int magFilter) načtení textury z obrázku typu BufferedImage

Návratovou hodnotou metod TextureFactory.loadTexture() je instance třídy typu org.gljava.opengl.Texture, která představuje texturu použitelnou při vykreslování objektů. Velmi důležitou metodou, kterou musíme při vykreslování použít, je Texture.bind() sloužící pro navázání textury na kontext OpenGL. Dále tato třída obsahuje metody pro zjištění rozměrů textury, popř. pro nastavení těchto rozměrů:

# Návratový typ Metoda Popis
1 void bind(GL gl) nejdůležitější metoda, navázání textury na kontext OpenGL
2 float getWidth() zjištění skutečné šířky textury
3 float getHeight() zjištění skutečné výšky textury
4 int getImageWidth() zjištění šířky pixmapy (v pixelech)
5 int getImageHeight() zjištění výšky pixmapy (v pixelech)

5. Demonstrační příklad SDLTest20 – texturování a objekt typu Texture

V dnešním prvním demonstračním příkladu nazvaném SDLTest20 je ukázána základní práce s texturami. Ihned po inicializaci knihovny SDLJava, nastavení grafického režimu a získání kontextu OpenGL je načten rastrový obrázek „xscorch.bmp“, který si můžete stáhnout z této adresy. Tento obrázek je reprezentován instancí třídy Texture, která bude následně použita při vykreslování:

// nacteni textury
Texture texture = TextureFactory.getFactory().loadTexture(gl, "xscorch.bmp");

Následně je nutné nastavit základní parametry texturování, což jsou operace prováděné přes knihovnu OpenGL. Texturování je nejprve potřeba povolit a poté nastavit režim opakování textury, filtry použité při zvětšování či zmenšování textury a režim vykreslování při použití perspektivní projekce (resp. při určení čtvrté souřadnice vrcholů):

// povoleni prace s texturami
gl.glEnable(gl.GL_TEXTURE_2D);
 
// 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);

Při vykreslování je zapotřebí nejdříve určit, která textura se má použít, což se provede navázáním textury na kontext OpenGL (změní se tím vnitřní stav OpenGL):

texture.bind(gl);

Při vykreslování objektu je nutné u každého vertexu určit i souřadnice v prostoru textury (u-v souřadnice):

// vykresleni ctyruhelniku
gl.glBegin(gl.GL_QUADS);
    gl.glTexCoord2f(0.0f, 0.0f);
    gl.glVertex2i(200, 100);
    gl.glTexCoord2f(1.0f, 0.0f);
    gl.glVertex2i(600, 100);
    gl.glTexCoord2f(1.0f, 1.0f);
    gl.glVertex2i(600, 300);
    gl.glTexCoord2f(0.0f, 1.0f);
    gl.glVertex2i(200, 600);
gl.glEnd();

Následuje úplný výpis programového kódu tohoto demonstračního příkladu:

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 demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Texturovani a objekt typu Texture.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest20 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 200;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 200;
 
    /**
     * 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);
 
        // povoleni prace s texturami
        gl.glEnable(gl.GL_TEXTURE_2D);
 
        // 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);
 
        texture.bind(gl);
 
        // vykresleni ctyruhelniku
        gl.glBegin(gl.GL_QUADS);
            gl.glTexCoord2f(0.0f, 0.0f);
            gl.glVertex2i(200, 100);
            gl.glTexCoord2f(1.0f, 0.0f);
            gl.glVertex2i(600, 100);
            gl.glTexCoord2f(1.0f, 1.0f);
            gl.glVertex2i(600, 300);
            gl.glTexCoord2f(0.0f, 1.0f);
            gl.glVertex2i(200, 600);
        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, "xscorch.bmp");
 
            // 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 SDLTest20.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 SDLTest20.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 SDLTest20

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% SDLTest20

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

6. Demonstrační příklad SDLTest21 – opakování textury

Dnešní druhý demonstrační příklad má název SDLTest21 a je na něm ukázán efekt opakování textury v případě, že souřadnice v prostoru textury překračují interval 0.0 až 1.0. Nastavení grafického režimu, inicializace OpenGL se získáním kontextu OpenGL i načtení textury probíhá zcela stejným způsobem, jako tomu bylo v předchozím příkladu. Stejné je i nastavení parametrů texturování:

// povoleni prace s texturami
gl.glEnable(gl.GL_TEXTURE_2D);
 
// 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);

Při vlastním vykreslování jsou však zadány souřadnice v prostoru textury, které v některých případech leží mimo rozsah 0.0 až 1.0, což znamená, že grafický akcelerátor bude texturu nanášet na objekt opakovaně (jakoby se jednalo o dlaždice). V následujícím úryvku kódu si všimněte parametrů předávaných do metody gl.glTexCoord2f():

// vykresleni ctyruhelniku
gl.glBegin(gl.GL_QUADS);
    gl.glTexCoord2f(0.0f, 0.0f);
    gl.glVertex2i(200, 100);
    gl.glTexCoord2f(3.0f, 0.0f);
    gl.glVertex2i(600, 100);
    gl.glTexCoord2f(1.0f, 3.0f);
    gl.glVertex2i(600, 300);
    gl.glTexCoord2f(-1.0f, 1.0f);
    gl.glVertex2i(100, 600);
gl.glEnd();

Úplný výpis demonstračního příkladu SDLTest21 je zobrazen pod tímto odstavcem:

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 prvni demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Texturovani a objekt typu Texture - opakovani textury.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest21 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 200;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 200;
 
    /**
     * 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);
 
        // povoleni prace s texturami
        gl.glEnable(gl.GL_TEXTURE_2D);
 
        // 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);
 
        texture.bind(gl);
 
        // vykresleni ctyruhelniku
        gl.glBegin(gl.GL_QUADS);
            gl.glTexCoord2f(0.0f, 0.0f);
            gl.glVertex2i(200, 100);
            gl.glTexCoord2f(3.0f, 0.0f);
            gl.glVertex2i(600, 100);
            gl.glTexCoord2f(1.0f, 3.0f);
            gl.glVertex2i(600, 300);
            gl.glTexCoord2f(-1.0f, 1.0f);
            gl.glVertex2i(100, 600);
        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, "xscorch.bmp");
 
            // 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 SDLTest21.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 SDLTest21.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 SDLTest21

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% SDLTest21

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

7. Demonstrační příklad SDLTest22 – protažení textury

Při zvětšení či naopak zmenšení textury se začínají uplatňovat filtry prováděné grafickým akcelerátorem. Filtry se nepoužijí pouze v jednom případě – když je velikost pixelů a texelů zcela shodná a současně se plochy pixelů a texelů přesně překrývají (objekt není natočen ani posunut oproti souřadnému systému obrazovky). Prozatím jsme si neřekli bližší informace o takzvaném mipmappingu, ovšem i bez využití této technologie lze zvolit minimálně mezi dvěma typy filtrů: velmi rychlý filtr typu „nearest“, který vždy vybere barvu nejbližšího texelu a poněkud pomalejší (více přístupů do texturovací paměti) filtr provádějící (bili)neární interpolaci na základě barev přečtených z nejbližších texelů. V dnešním posledním demonstračním příkladu je ukázán rozdíl mezi těmito filtry.

Objekt, v našem případě jednoduchý obdélník, je vykreslen dvakrát. Jednou s využitím filtru typu „nearest“:

// 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);
 
// vykresleni ctyruhelniku
gl.glBegin(gl.GL_QUADS);
    gl.glTexCoord2f(0.0f, 0.3f);
    gl.glVertex2i(0, 0);
    gl.glTexCoord2f(0.5f, 0.3f);
    gl.glVertex2i(300, 0);
    gl.glTexCoord2f(0.5f, 0.8f);
    gl.glVertex2i(300, 200);
    gl.glTexCoord2f(0.0f, 0.8f);
    gl.glVertex2i(0, 200);
gl.glEnd();

A podruhé s využitím filtru provádějícího bilineární interpolaci:

// volba filtru
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR);
gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR);
 
texture.bind(gl);
 
// vykresleni ctyruhelniku
gl.glBegin(gl.GL_QUADS);
    gl.glTexCoord2f(0.0f, 0.3f);
    gl.glVertex2i(0, 200);
    gl.glTexCoord2f(0.5f, 0.3f);
    gl.glVertex2i(300, 200);
    gl.glTexCoord2f(0.5f, 0.8f);
    gl.glVertex2i(300, 400);
    gl.glTexCoord2f(0.0f, 0.8f);
    gl.glVertex2i(0, 400);
gl.glEnd();

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

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 druhy demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Texturovani a objekt typu Texture - volba ruznych filtru pouzitych pri texturovani.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest22 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 300;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 400;
 
    /**
     * 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);
 
        // povoleni prace s texturami
        gl.glEnable(gl.GL_TEXTURE_2D);
 
        // 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);
 
        // 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);
 
        texture.bind(gl);
 
        // 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);
 
        // vykresleni ctyruhelniku
        gl.glBegin(gl.GL_QUADS);
            gl.glTexCoord2f(0.0f, 0.3f);
            gl.glVertex2i(0, 0);
            gl.glTexCoord2f(0.5f, 0.3f);
            gl.glVertex2i(300, 0);
            gl.glTexCoord2f(0.5f, 0.8f);
            gl.glVertex2i(300, 200);
            gl.glTexCoord2f(0.0f, 0.8f);
            gl.glVertex2i(0, 200);
        gl.glEnd();
 
        // volba filtru
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR);
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR);
 
        texture.bind(gl);
 
        // vykresleni ctyruhelniku
        gl.glBegin(gl.GL_QUADS);
            gl.glTexCoord2f(0.0f, 0.3f);
            gl.glVertex2i(0, 200);
            gl.glTexCoord2f(0.5f, 0.3f);
            gl.glVertex2i(300, 200);
            gl.glTexCoord2f(0.5f, 0.8f);
            gl.glVertex2i(300, 400);
            gl.glTexCoord2f(0.0f, 0.8f);
            gl.glVertex2i(0, 400);
        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, "xscorch.bmp");
 
            // 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 SDLTest22.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 SDLTest22.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 SDLTest22

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% SDLTest22

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

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

Všechny tř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 pěti 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 SDLTest20.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/02880fee963a/sdlja­va/SDLTest20/SDLTest20.ja­va
2 SDLTest20_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d9d2ef329fbd/sdlja­va/SDLTest20/SDLTest20_com­pile.sh
3 SDLTest20_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d9d2ef329fbd/sdlja­va/SDLTest20/SDLTest20_com­pile_sys.sh
4 SDLTest20_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d9d2ef329fbd/sdlja­va/SDLTest20/SDLTest20_run­.sh
5 SDLTest20_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d9d2ef329fbd/sdlja­va/SDLTest20/SDLTest20_run_sys­.sh
6 SDLTest20_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d9d2ef329fbd/sdlja­va/SDLTest20/SDLTest20_com­pile.bat
7 SDLTest20_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d9d2ef329fbd/sdlja­va/SDLTest20/SDLTest20_run­.bat
     
8 SDLTest21.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/02880fee963a/sdlja­va/SDLTest21/SDLTest21.ja­va
9 SDLTest21_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d9d2ef329fbd/sdlja­va/SDLTest21/SDLTest21_com­pile.sh
10 SDLTest21_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d9d2ef329fbd/sdlja­va/SDLTest21/SDLTest21_com­pile_sys.sh
11 SDLTest21_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d9d2ef329fbd/sdlja­va/SDLTest21/SDLTest21_run­.sh
12 SDLTest21_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d9d2ef329fbd/sdlja­va/SDLTest21/SDLTest21_run_sys­.sh
13 SDLTest21_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d9d2ef329fbd/sdlja­va/SDLTest21/SDLTest21_com­pile.bat
14 SDLTest21_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/d9d2ef329fbd/sdlja­va/SDLTest21/SDLTest21_run­.bat
     
15 SDLTest22.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/02880fee963a/sdlja­va/SDLTest22/SDLTest22.ja­va
16 SDLTest22_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/02880fee963a/sdlja­va/SDLTest22/SDLTest22_com­pile.sh
17 SDLTest22_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/02880fee963a/sdlja­va/SDLTest22/SDLTest22_com­pile_sys.sh
18 SDLTest22_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/02880fee963a/sdlja­va/SDLTest22/SDLTest22_run­.sh
19 SDLTest22_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/02880fee963a/sdlja­va/SDLTest22/SDLTest22_run_sys­.sh
20 SDLTest22_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/02880fee963a/sdlja­va/SDLTest22/SDLTest22_com­pile.bat
21 SDLTest22_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/02880fee963a/sdlja­va/SDLTest22/SDLTest22_run­.bat

9. 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ý?