Pohled pod kapotu JVM – zpracování událostí v knihovně SDLJava

Pavel Tišnovský 4. 3. 2014

Knihovna SDLJava obsahuje i mechanismus umožňující zpracování různých typů událostí, které mohou vzniknout například při stisku klávesy či při pohybu myši popř. joysticku. Celý mechanismus práce s událostmi je navržen takovým způsobem, aby byl paměťově nenáročný, tj. aby zbytečně nevznikaly nové objekty.

Obsah

1. Dokončení tématu z předchozí části seriálu: obrázky typu BufferedImage a texturování

2. Parametry metody TextureFactory.loadTexture()

3. Demonstrační příklad SDLTest26 – použití obrázku typu BufferedImage při texturování

4. Demonstrační příklad SDLTest27 – BufferedImage, texturování a alfa blending

5. Zpracování událostí v knihovně SDLJava

6. Demonstrační příklad SDLTest28 – čtení událostí ve smyčce

7. Demonstrační příklad SDLTest29 – reakce na událost typu SDLQuitEvent

8. Demonstrační příklad SDLTest30 – čtení informací o stisknutých a puštěných klávesách

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

10. Odkazy na Internetu

1. Dokončení tématu z předchozí části seriálu: obrázky typu BufferedImage a texturování

V dnešní části seriálu o programovacím jazyce Java i o virtuálním stroji tohoto jazyka se budeme zabývat především popisem zpracování událostí v knihovně SDLJava. Ještě předtím však musíme dokončit téma, kterému jsme se věnovali v poslednípředposlední části tohoto seriálu – texturování. Na několika demonstračních příkladech jsme si již ukázali, jakým způsobem je možné načíst texturu z externího souboru a jak se následně tato textura naváže na kontext OpenGL. Ovšem v knihovně SDLJava je možné texturu, přesněji řečeno instanci třídy Texture vytvořit i z rastrového obrázku typu BufferedImage. Tato funkcionalita se může hodit zejména ve chvílích, kdy je obrázek nějakým způsobem programově generován, tj. když je například vytvářena procedurální textura. Základem pro vytváření či načítání textur je třída org.gljava.opengl.TextureFactory, která mj. nabízí i následující metody určené pro získání instance této třídy a následně pro načtení textury:

# 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

2. Parametry metody TextureFactory.loadTexture()

Nás nyní bude zajímat především poslední zmíněná metoda TextureFactory.loadTexture(GL gl, java.awt.image.BufferedImage bufferedImage, int target, int dstPixelFormat, int minFilter, int magFilter), které je možné předat obrázek typu BufferedImage a na základě dalších informací se z tohoto obrázku vytvoří běžná textura, tj. objekt typu Texture. Význam parametrů této metody je následující:

# Parametr Význam
1 GL gl aktuální kontext OpenGL
2 BufferedImage bufferedImage obrázek, který má být konvertován na texturu
3 int target buď GL.GL_TEXTURE_1D nebo GL.GL_TEXTURE_2D
4 int dstPixelFormat formát textury, typicky GL.GL_RGBA (viz též předchozí části tohoto seriálu)
5 int minFilter filtr použitý při zmenšování obrázku, typicky GL.GL_LINEAR
6 int magFilter filtr použitý při zvětšování obrázku, typicky GL.GL_LINEAR

Parametr target může podle typu textury nabývat hodnot:

# Hodnota Význam
1 GL.GL_TEXTURE_1D jednorozměrná textura
2 GL.GL_TEXTURE_2D dvourozměrná textura (mnohem častější)

Parametr dstPixelFormat určuje interní formát výsledné textury:

# Rozšířený formát Základní formát
1 GL_ALPHA4 GL_ALPHA
2 GL_ALPHA8 GL_ALPHA
3 GL_ALPHA12 GL_ALPHA
4 GL_ALPHA16 GL_ALPHA
5 GL_LUMINANCE4 GL_LUMINANCE
6 GL_LUMINANCE8 GL_LUMINANCE
7 GL_LUMINANCE12 GL_LUMINANCE
8 GL_LUMINANCE16 GL_LUMINANCE
9 GL_LUMINANCE4_ALPHA4 GL_LUMINANCE_ALPHA
10 GL_LUMINANCE6_ALPHA2 GL_LUMINANCE_ALPHA
11 GL_LUMINANCE8_ALPHA8 GL_LUMINANCE_ALPHA
12 GL_LUMINANCE12_ALPHA4 GL_LUMINANCE_ALPHA
13 GL_LUMINANCE12_ALPHA12 GL_LUMINANCE_ALPHA
14 GL_LUMINANCE16_ALPHA16 GL_LUMINANCE_ALPHA
15 GL_INTENSITY4 GL_INTENSITY
16 GL_INTENSITY8 GL_INTENSITY
17 GL_INTENSITY12 GL_INTENSITY
18 GL_INTENSITY16 GL_INTENSITY
19 GL_R3_G3_B2 GL_RGB
20 GL_RGB4 GL_RGB
21 GL_RGB5 GL_RGB
22 GL_RGB8 GL_RGB
23 GL_RGB10 GL_RGB
24 GL_RGB12 GL_RGB
25 GL_RGB16 GL_RGB
26 GL_RGBA2 GL_RGBA
27 GL_RGBA4 GL_RGBA
28 GL_RGB5_A1 GL_RGBA
29 GL_RGBA8 GL_RGBA
30 GL_RGB10_A2 GL_RGBA
31 GL_RGBA12 GL_RGBA
32 GL_RGBA16 GL_RGBA

Hodnoty předávané v posledních dvou parametrech minFiltermagFilter jsou specifikovány těmito konstantami:

# Hodnota Význam
1 GL.GL_NEAREST při změně velikosti se použije nejbližší texel
2 GL.GL_LINEAR při změně velikosti se použije (bi)lineární interpolace

3. Demonstrační příklad SDLTest26 – použití obrázku typu BufferedImage při texturování

V dnešním prvním demonstračním příkladu, který se jmenuje SDLTest26, je ukázáno, jak je možné vytvořit texturu, tj. instanci třídy org.gljava.opengl.Texture z rastrového obrázku (bitmapy) reprezentovaného objektem typu java.awt.image.BufferedImage. Vlastní bitmapa je vytvořena v metodě createTexture(), přičemž si všimněte, že formát uložení pixelů v bitmapě může, ale nemusí přesně korespondovat s formátem uložení pixelů ve výsledné textuře. Následně je bitmapa v metodě renderImage() vyplněna jednoduchým vzorkem a poté je provedeno její převedení na texturu. Rozměry textury samozřejmě nemusí korespondovat s rozměry reálného objektu, který je touto texturou pokryt:

/**
 * Vytvoreni textury z obrazku typu BufferedImage.
 */
private static Texture createTexture(GL gl) throws IOException {
    // rozmery textury
    final int width = 256;
    final int height = 256;
 
    // vytvoreni rastroveho obrazku
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
    renderImage(image);
 
    // ziskani instance typu TextureFactory
    TextureFactory textureFactory = TextureFactory.getFactory();
 
    // vytvoreni textury z obrazku typu BufferedImage
    return textureFactory.loadTexture(gl, image, GL.GL_TEXTURE_2D, GL.GL_RGBA, GL.GL_LINEAR, GL.GL_LINEAR);
}

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

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.awt.image.DataBuffer;
import java.io.IOException;
 
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 sesty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Vytvoreni textury z obrazku typu BufferedImage.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest26 {
 
    /**
     * 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);
 
        // zakaz opakovani textury
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP);
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP);
 
        // 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);
 
        // navazani textury na kontext OpenGL
        texture.bind(gl);
 
        // vykresleni ctyruhelniku pokryteho texturou
        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
    }
 
    /**
     * Vytvoreni textury z obrazku typu BufferedImage.
     */
    private static Texture createTexture(GL gl) throws IOException {
        // rozmery textury
        final int width = 256;
        final int height = 256;
 
        // vytvoreni rastroveho obrazku
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
        renderImage(image);
 
        // ziskani instance typu TextureFactory
        TextureFactory textureFactory = TextureFactory.getFactory();
 
        // vytvoreni textury z obrazku typu BufferedImage
        return textureFactory.loadTexture(gl, image, GL.GL_TEXTURE_2D, GL.GL_RGBA, GL.GL_LINEAR, GL.GL_LINEAR);
    }
 
    /**
     * Vytvoreni vzorku.
     */
    private static void renderImage(BufferedImage image) {
        // rozmery bitmapy
        final int width = image.getWidth();
        final int height = image.getHeight();
 
        // ziskani objektu obsahujiciho hodnoty vsech pixelu bitmapy
        DataBuffer dataBuffer = image.getRaster().getDataBuffer();
 
        // provest vypocet barev pixelu a jejich vykresleni
        int i = 0;
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                dataBuffer.setElem(i++, 0xff);
                dataBuffer.setElem(i++, 0xff);
                dataBuffer.setElem(i++, y);
                dataBuffer.setElem(i++, x);
            }
        }
        System.out.println("Written " + i + " bytes into DataBuffer");
    }
 
    /**
     * 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);
 
            // vytvoreni textury z obrazku typu BufferedImage
            Texture texture = createTexture(gl);
 
            // 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 SDLTest26.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 SDLTest26.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 SDLTest26

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

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

4. Demonstrační příklad SDLTest27 – BufferedImage, texturování a alfa blending

V předchozí části tohoto seriálu jsme si ukázali, že v případě použití rastrového obrázku uloženého v souboru typu PNG je možné pro vytvoření textury v plné míře využít informace o průhlednosti jednotlivých pixelů uložených v alfa kanále (jedná se o volitelný kanál). Stejným způsobem je však možné pracovat s průhledností ve chvíli, kdy se textura vytváří z bitmapy typu BufferedImage, což je ukázáno v dnešním druhém demonstračním příkladu. Nejzajímavější je zde metoda drawScene(), z níž je patrné, že se nejdříve vykreslí pozadí složené z mřížky (alfa blending je vypnutý) a posléze se přes toho pozadí vykreslí poloprůhledná textura (nyní již se zapnutým alfa blendingem):

/**
 * Vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL.
 */
private static void drawScene(GL gl, Texture texture) {
    // vymazani framebufferu (bile pozadi)
    gl.glClear(GL.GL_COLOR_BUFFER_BIT);
 
    // zakaz prace s texturami
    gl.glDisable(gl.GL_TEXTURE_2D);
 
    // 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 prace s texturami
    gl.glEnable(GL.GL_TEXTURE_2D);
 
    // povoleni a nastaveni blendingu
    gl.glEnable(GL.GL_BLEND);
    gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
 
    // navazani textury na kontext OpenGL
    texture.bind(gl);
 
    // vykresleni ctyruhelniku pokryteho texturou
    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
}

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

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;
import java.awt.image.DataBuffer;
import java.io.IOException;
 
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 sedmy demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Vytvoreni textury z obrazku typu BufferedImage.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest27 {
 
    /**
     * 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);
 
        // zakaz opakovani textury
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP);
        gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP);
 
        // 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 (1.0f, 1.0f, 1.0f, 0.0f);
    }
 
    /**
     * Vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL.
     */
    private static void drawScene(GL gl, Texture texture) {
        // vymazani framebufferu (bile pozadi)
        gl.glClear(GL.GL_COLOR_BUFFER_BIT);
 
        // zakaz prace s texturami
        gl.glDisable(gl.GL_TEXTURE_2D);
 
        // 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 prace s texturami
        gl.glEnable(GL.GL_TEXTURE_2D);
 
        // povoleni a nastaveni blendingu
        gl.glEnable(GL.GL_BLEND);
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
 
        // navazani textury na kontext OpenGL
        texture.bind(gl);
 
        // vykresleni ctyruhelniku pokryteho texturou
        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
    }
 
    /**
     * Vytvoreni textury z obrazku typu BufferedImage.
     */
    private static Texture createTexture(GL gl) throws IOException {
        // rozmery textury
        final int width = 256;
        final int height = 256;
 
        // vytvoreni rastroveho obrazku
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
        renderImage(image);
 
        // ziskani instance typu TextureFactory
        TextureFactory textureFactory = TextureFactory.getFactory();
 
        // vytvoreni textury z obrazku typu BufferedImage
        return textureFactory.loadTexture(gl, image, GL.GL_TEXTURE_2D, GL.GL_RGBA, GL.GL_LINEAR, GL.GL_LINEAR);
    }
 
    /**
     * Vytvoreni vzorku.
     */
    private static void renderImage(BufferedImage image) {
        // rozmery bitmapy
        final int width = image.getWidth();
        final int height = image.getHeight();
 
        // ziskani objektu obsahujiciho hodnoty vsech pixelu bitmapy
        DataBuffer dataBuffer = image.getRaster().getDataBuffer();
 
        // provest vypocet barev pixelu a jejich vykresleni
        int i = 0;
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                dataBuffer.setElem(i++, x+y);
                dataBuffer.setElem(i++, x-y);
                dataBuffer.setElem(i++, y);
                dataBuffer.setElem(i++, y);
            }
        }
        System.out.println("Written " + i + " bytes into DataBuffer");
    }
 
    /**
     * 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);
 
            // vytvoreni textury z obrazku typu BufferedImage
            Texture texture = createTexture(gl);
 
            // 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 SDLTest27.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 SDLTest27.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 SDLTest27

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

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

5. Zpracování událostí v knihovně SDLJava

Knihovna SDLJava obsahuje i vlastní systém pro práci s událostmi, který je možné využít například při práci s klávesnicí, myší či joystickem. Systém událostí implementovaný v SDLJava se v několika ohledech odlišuje například od způsobu reakce na události, který známe z knihovny AWT a přeneseně i z knihovny Swing. Zatímco v případě AWT/Swing bylo možné naprogramovat reakci na nějaký typ události pro každou komponentu (okno, widget) zvlášť, a to formou anonymních tříd s „callback metodami“, je v SDLJava implementována jediná fronta událostí, z níž je možné jednotlivé události vybírat a/nebo číst s využitím následujících čtyř statických metod implementovaných ve třídě SDLEvent:

# Metoda Význam
1 SDLEvent pollEvent() přečtení události z fronty
2 SDLEvent pollEvent(boolean returnEvent) přečtení události z fronty
3 SDLEvent waitEvent() čekání na další událost a přečtení této události
4 SDLEvent waitEvent(boolean returnEvent) čekání na další událost a případné přečtení této události

To, zda se použije metoda pollEvent() či metoda waitEvent() závisí na povaze aplikace. Například ve chvíli, kdy aplikace zobrazuje nějaké menu či dialog, může být vhodné čekat na další událost v metodě waitEvent(), zatímco ve hře, v níž se pohybují protivníci nezávisle na akcích uživatele, se typicky používá metoda pollEvent(), která může vrátit null v případě, že žádná událost nebyla do fronty uložena.

V knihovně SDLJava je fronta událostí řešena takovým způsobem, aby se nemusely vytvářet nové objekty při vzniku události – ty by jen zbytečně zaplňovaly haldu (heap) a její plnění by vedlo i k pozastavování aplikace ve chvílích, kdy by se spouštěl správce paměti (garbage collector). Proto bývá obvykle hra naprogramovaná s využitím SDLJava plynulejší, než podobná aplikace naprogramovaná s využitím AWT či Swingu (nemluvě již o obecně vyšším výkonu SDLJava při provádění grafických operací).

Současná verze knihovny SDLJava pracuje s následujícími typy událostí:

# Událost
1 sdljava.event.SDLActiveEvent
2 sdljava.event.SDLExposeEvent
3 sdljava.event.SDLJoyAxisEvent
4 sdljava.event.SDLJoyBallEvent
5 sdljava.event.SDLJoyButtonEvent
6 sdljava.event.SDLJoyHatEvent
7 sdljava.event.SDLKeyboardEvent
8 sdljava.event.SDLMouseButtonEvent
9 sdljava.event.SDLMouseMotionEvent
10 sdljava.event.SDLQuitEvent
11 sdljava.event.SDLResizeEvent
12 sdljava.event.SDLSysWMEvent

Princip zpracování jednotlivých typů událostí si postupně ukážeme na několika demonstračních příkladech.

6. Demonstrační příklad SDLTest28 – čtení událostí ve smyčce

V demonstračním příkladu pojmenovaném SDLTest28 je ukázán nejjednodušší typ smyčky pro zpracování událostí. Tato (nekonečná) smyčka je implementována v metodě eventLoop() a provádí pouze tři činnosti – čekání na příchod nové události, přečtení této události a následně výpis jména třídy, jejíž objekt reprezentuje právě zachycenou událost. Povšimněte si, že demonstrační příklad nelze jednoduše ukončit uzavřením jeho okna, protože v tomto případě se „pouze“ vytvoří událost typu SDLQuitEvent, na níž se však nijak nereaguje. Příklad tedy ukončíte například přes CTRL+C, zasláním signálu atd. Samotná smyčka pro zpracování událostí vypadá následovně:

/**
 * Smycka pro zpracovani udalosti.
 */
private static void eventLoop() throws SDLException {
    while (true) {
        // precist udalost z fronty
        SDLEvent event = SDLEvent.waitEvent();
        System.out.println(event.getClass().getName());
    }
}

Obrázek 3: Ukázka výstupu demonstračního příkladu SDLTest28.

Úplný zdrojový kód demonstračního příkladu SDLTest28:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.event.SDLEvent;
import sdljava.video.SDLVideo;
 
 
 
/**
 * Dvacaty osmy demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Cteni udalosti.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest28 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 320;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 240;
 
    /**
     * 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 void initVideo() throws SDLException {
        final long flags = SDLVideo.SDL_DOUBLEBUF;
        SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags);
    }
 
    /**
     * Smycka pro zpracovani udalosti.
     */
    private static void eventLoop() throws SDLException {
        while (true) {
            // precist udalost z fronty
            SDLEvent event = SDLEvent.waitEvent();
            System.out.println(event.getClass().getName());
        }
    }
 
    /**
     * Spusteni osmeho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace knihovny SDLJava
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
 
            // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani
            initVideo();
 
            // smycka pro zpracovani udalosti
            eventLoop();
        }
        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 SDLTest28.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 SDLTest28.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 SDLTest28

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

7. Demonstrační příklad SDLTest29 – reakce na událost typu SDLQuitEvent

Chování předchozího demonstračního příkladu SDLTest28 bylo – politicky korektně řečeno – poněkud „nestandardní“ ;-), protože uživatelé očekávají, že se po zavření okna příslušná aplikace skutečně ukončí. Toho lze velmi snadno dosáhnout i při použití knihovny SDLJava, a to konkrétně takovým způsobem, že se správně zareaguje na událost typu SDLQuitEvent. Tato událost typicky vzniká právě při pokusu o uzavření okna aplikace, a to nezávisle na tom, na jakém operačním systému je aplikace spuštěna. Jeden z nejjednodušších způsobů reakce na událost typu SDLQuitEvent je ukončení běhu smyčky událostí:

/**
 * Smycka pro zpracovani udalosti.
 */
private static void eventLoop() throws SDLException {
    while (true) {
        // precist udalost z fronty
        SDLEvent event = SDLEvent.waitEvent();
        System.out.println(event.getClass().getName());
 
        // vyskok ze smycky pro zpracovani udalosti pri vyskytu
        // udalosti typu SDLQuitEvent
        if (event instanceof SDLQuitEvent) {
            return;
        }
    }
}

Opět následuje výpis celého zdrojového kódu demonstračního příkladu SDLTest29:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.event.SDLEvent;
import sdljava.event.SDLQuitEvent;
import sdljava.video.SDLVideo;
 
 
 
/**
 * Dvacaty devaty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Cteni udalosti a reakce na udalost typu SDLQuitEvent.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest29 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 320;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 240;
 
    /**
     * 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 void initVideo() throws SDLException {
        final long flags = SDLVideo.SDL_DOUBLEBUF;
        SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags);
    }
 
    /**
     * Smycka pro zpracovani udalosti.
     */
    private static void eventLoop() throws SDLException {
        while (true) {
            // precist udalost z fronty
            SDLEvent event = SDLEvent.waitEvent();
            System.out.println(event.getClass().getName());
 
            // vyskok ze smycky pro zpracovani udalosti pri vyskytu
            // udalosti typu SDLQuitEvent
            if (event instanceof SDLQuitEvent) {
                return;
            }
        }
    }
 
    /**
     * Spusteni osmeho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace knihovny SDLJava
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
 
            // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani
            initVideo();
 
            // smycka pro zpracovani udalosti
            eventLoop();
        }
        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 SDLTest29.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 SDLTest29.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 SDLTest29

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

8. Demonstrační příklad SDLTest30 – čtení informací o stisknutých a puštěných klávesách

Kromě události typu SDLQuitEvent lze samozřejmě reagovat i na další typy událostí. V dnešním posledním demonstračním příkladu nazvaném SDLTest30 je ukázán základní způsob zpracování události typu SDLKeyboardEvent. Tato událost vznikne ve chvíli stlačení či naopak puštění nějaké klávesy – důležitý je zde právě fakt, že dokážeme snadno detekovat i okamžik puštění nějaké klávesy, což se hodí při programování her. Objekt typu SDLKeyboardEvent nese několik důležitých informací, především pak kód stisknuté/puštěné klávesy a stav této klávesy. Kódy kláves lze porovnávat s konstantami uloženými ve třídě SDLKey. V demonstračním příkladu je tímto způsobem reagováno na stisk klávesy ESC, která běh demonstračního příkladu ukončí:

/**
 * Smycka pro zpracovani udalosti.
 */
private static void eventLoop() throws SDLException {
    while (true) {
        // precist udalost z fronty
        SDLEvent event = SDLEvent.waitEvent();
 
        // vyskok ze smycky pro zpracovani udalosti pri vyskytu
        // udalosti typu SDLQuitEvent
        if (event instanceof SDLQuitEvent) {
            return;
        }
 
        // stisk ci pusteni klavesy
        if (event instanceof SDLKeyboardEvent) {
            final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event;
            final int symbol = keyEvent.getSym();
            final String state = keyEvent.getState() == SDLPressedState.PRESSED ? "pressed" : "release";
            System.out.println("Keyboard event: symbol=" + symbol +" state=" + state);
 
            // ESC ukonci program
            if (symbol == SDLKey.SDLK_ESCAPE) {
                return;
            }
        }
    }
}

Úplný zdrojový kód demonstračního příkladu SDLTest30 vypadá následovně:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.event.SDLEvent;
import sdljava.event.SDLKeyboardEvent;
import sdljava.event.SDLKey;
import sdljava.event.SDLQuitEvent;
import sdljava.video.SDLVideo;
 
import sdljava.x.swig.SDLPressedState;
 
 
 
/**
 * Dvacaty devaty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Cteni udalosti a reakce na stisk klaves.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest30 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 320;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 240;
 
    /**
     * 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 void initVideo() throws SDLException {
        final long flags = SDLVideo.SDL_DOUBLEBUF;
        SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags);
    }
 
    /**
     * Smycka pro zpracovani udalosti.
     */
    private static void eventLoop() throws SDLException {
        while (true) {
            // precist udalost z fronty
            SDLEvent event = SDLEvent.waitEvent();
 
            // vyskok ze smycky pro zpracovani udalosti pri vyskytu
            // udalosti typu SDLQuitEvent
            if (event instanceof SDLQuitEvent) {
                return;
            }
 
            // stisk ci pusteni klavesy
            if (event instanceof SDLKeyboardEvent) {
                final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event;
                final int symbol = keyEvent.getSym();
                final String state = keyEvent.getState() == SDLPressedState.PRESSED ? "pressed" : "release";
                System.out.println("Keyboard event: symbol=" + symbol +" state=" + state);
 
                // ESC ukonci program
                if (symbol == SDLKey.SDLK_ESCAPE) {
                    return;
                }
            }
        }
    }
 
    /**
     * Spusteni osmeho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace knihovny SDLJava
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
 
            // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani
            initVideo();
 
            // smycka pro zpracovani udalosti
            eventLoop();
        }
        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 SDLTest30.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 SDLTest30.java

Skript pro spuštění na Linuxu:

widgety

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

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

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

Všech pět dnes popsaných demonstračních příkladů bylo společně s podpůrnými skripty určenými pro jejich překlad a následné spuštění uloženo 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 sedmi 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 SDLTest26.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest26/SDLTest26.ja­va
2 SDLTest26_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest26/SDLTest26_com­pile.sh
3 SDLTest26_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest26/SDLTest26_com­pile_sys.sh
4 SDLTest26_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest26/SDLTest26_run­.sh
5 SDLTest26_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest26/SDLTest26_run_sys­.sh
6 SDLTest26_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest26/SDLTest26_com­pile.bat
7 SDLTest26_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest26/SDLTest26_run­.bat
     
8 SDLTest27.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest27/SDLTest27.ja­va
9 SDLTest27_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest27/SDLTest27_com­pile.sh
10 SDLTest27_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest27/SDLTest27_com­pile_sys.sh
11 SDLTest27_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest27/SDLTest27_run­.sh
12 SDLTest27_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest27/SDLTest27_run_sys­.sh
13 SDLTest27_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest27/SDLTest27_com­pile.bat
14 SDLTest27_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest27/SDLTest27_run­.bat
     
15 SDLTest28.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest28/SDLTest28.ja­va
16 SDLTest28_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest28/SDLTest28_com­pile.sh
17 SDLTest28_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest28/SDLTest28_com­pile_sys.sh
18 SDLTest28_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest28/SDLTest28_run­.sh
19 SDLTest28_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest28/SDLTest28_run_sys­.sh
20 SDLTest28_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest28/SDLTest28_com­pile.bat
21 SDLTest28_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest28/SDLTest28_run­.bat
     
22 SDLTest29.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest29/SDLTest29.ja­va
23 SDLTest29_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest29/SDLTest29_com­pile.sh
24 SDLTest29_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest29/SDLTest29_com­pile_sys.sh
25 SDLTest29_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest29/SDLTest29_run­.sh
26 SDLTest29_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest29/SDLTest29_run_sys­.sh
27 SDLTest29_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest29/SDLTest29_com­pile.bat
28 SDLTest29_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest29/SDLTest29_run­.bat
     
29 SDLTest30.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest30/SDLTest30.ja­va
30 SDLTest30_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest30/SDLTest30_com­pile.sh
31 SDLTest30_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest30/SDLTest30_com­pile_sys.sh
32 SDLTest30_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest30/SDLTest30_run­.sh
33 SDLTest30_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest30/SDLTest30_run_sys­.sh
34 SDLTest30_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest30/SDLTest30_com­pile.bat
35 SDLTest30_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ff8f5102c62a/sdlja­va/SDLTest30/SDLTest30_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
Našli jste v článku chybu?
Lupa.cz: Jak se prodává firma za miliardu?

Jak se prodává firma za miliardu?

Vitalia.cz: 5 chyb, které děláme při skladování potravin

5 chyb, které děláme při skladování potravin

Podnikatel.cz: V říjnu se rozšíří režim reverse-charge

V říjnu se rozšíří režim reverse-charge

Podnikatel.cz: Byla finanční manažerka, teď cvičí jógu

Byla finanční manažerka, teď cvičí jógu

Vitalia.cz: dTest odhalil ten nejlepší kečup

dTest odhalil ten nejlepší kečup

Podnikatel.cz: Tyto pojmy k #EET byste měli znát

Tyto pojmy k #EET byste měli znát

Podnikatel.cz: Takhle se prodávají mražené potraviny

Takhle se prodávají mražené potraviny

Vitalia.cz: Tohle jsou nejlepší česká piva podle odborníků

Tohle jsou nejlepší česká piva podle odborníků

Vitalia.cz: Jak Ondra o astma přišel

Jak Ondra o astma přišel

Podnikatel.cz: Znáte už 5 novinek k #EET

Znáte už 5 novinek k #EET

Podnikatel.cz: Babišovi se nedá věřit, stěžovali si hospodští

Babišovi se nedá věřit, stěžovali si hospodští

DigiZone.cz: Samsung EVO-S: novinka pro Skylink

Samsung EVO-S: novinka pro Skylink

Vitalia.cz: Pryč se zastaralým stravováním ve školách

Pryč se zastaralým stravováním ve školách

DigiZone.cz: Wimbledon na Nova Sport až do 2019

Wimbledon na Nova Sport až do 2019

DigiZone.cz: Funbox 4K v DVB-T2 má ostrý provoz

Funbox 4K v DVB-T2 má ostrý provoz

DigiZone.cz: Nova opět stahuje „milionáře“

Nova opět stahuje „milionáře“

DigiZone.cz: Technisat připravuje trojici DAB

Technisat připravuje trojici DAB

Lupa.cz: Cimrman má hry na YouTube i vlastní doodle

Cimrman má hry na YouTube i vlastní doodle

Měšec.cz: TEST: Vyzkoušeli jsme pražské taxikáře

TEST: Vyzkoušeli jsme pražské taxikáře

DigiZone.cz: Mordparta: trochu podchlazený 87. revír

Mordparta: trochu podchlazený 87. revír