Pohled pod kapotu JVM – kreslicí funkce ve třídě sdljavax.gfx.SDLGfx (3.část) a zvukový subsystém SDLJava

Pavel Tišnovský 22. 4. 2014

V dnešní části seriálu o programovacím jazyku Java i o virtuálním stroji tohoto jazyka nejprve dokončíme popis „kreslicích“ funkcí, které jsou dostupné ve třídě sdljavax.gfx.SDLGfx. Následně se zaměříme na popis zvukového subsystému knihovny SDLJava, zejména třídy SDLMixer.

Obsah

1. Změna velikosti bitmap a rotace bitmap

2. Demonstrační příklad SDLTest57 – načtení a vykreslení originální bitmapy

3. Demonstrační příklad SDLTest58 – změna měřítka bitmapy

4. Demonstrační příklad SDLTest59 – rotace bitmapy

5. Zvukový subsystém knihovny SDLJava

6. Základ přehrávání zvuků a hudby s využitím třídy SDLMixer

7. Demonstrační příklad SDLTest60 – přehrání zvuku načteného ze souboru .wav

8. Demonstrační příklad SDLTest61 – přehrání hudby načtené ze souboru .mod

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

10. Odkazy na Internetu

1. Změna velikosti bitmap a rotace bitmap

V první polovině dnešního článku o knihovně SDLJava dokončíme popis „kreslicích“ funkcí nabízených třídou sdljavax.gfx.SDLGfx. Řekneme si, jakým způsobem je možné měnit velikost bitmap, popř. jak lze bitmapami rotovat o libovolný úhel. Druhá polovina článku bude věnována zvukovému subsystému SDLJava; zaměříme se především na popis základních možností třídy SDLMixer, s jejímž využitím je možné velmi jednoduše přehrávat zvuky ale i hudbu, která může být uložena v různých formátech, včetně Ogg Vorbis či stále populárních formátů založených na amigáckých MODulech.

Ve třídě sdljavax.gfx.SDLGfx nalezneme kromě běžných „kreslicích“ funkcí i dvojici funkcí zoomSurfacerotozoomSurface se zvláštním významem. Tyto funkce slouží ke změně velikosti bitmapy, popř. k rotaci bitmapy společně se změnou velikosti. Bitmapa je reprezentována instancí typu SDLSurface a vzhledem k tomu, že rozměry SDLSurface jsou po jejím vytvoření neměnitelné, vrací obě popisované funkce novou bitmapu, tj. novou instanci typu SDLSurface. Kromě obou zmíněných funkcí zoomSurfacerotozoomSurface nalezneme ve třídě sdljavax.gfx.SDLGfx i funkce pojmenované zoomSurfaceSizerotozoomSurfaceSize sloužící pro zjištění rozměrů bitmapy po změně měřítka či po její rotaci:

# Jméno funkce Návratová hodnota Parametry Popis
zoomSurface SDLSurface SDLSurface src, double zoomx, double zoomy, boolean smooth změna měřítka bitmapy (vytvoří se nová bitmapa)
zoomSurfaceSize java.awt.Dimension int width, int height, double zoomx, double zoomy výpočet rozměrů nové bitmapy po změně měřítka
         
rotozoomSurface SDLSurface SDLSurface src, double angle, double zoom, boolean smooth rotace a změna měřítka bitmapy (vytvoří se nová bitmapa)
rotozoomSurfaceSize java.awt.Dimension int width, int height, double angle, double zoom výpočet rozměrů nové bitmapy po rotaci a změně měřítka

Způsob použití funkcí zoomSurfacerotozoomSurface si ukážeme na dvojici demonstračních příkladů popsaných ve třetíve čtvrté kapitole.

2. Demonstrační příklad SDLTest57 – načtení a vykreslení originální bitmapy

V dnešním prvním demonstračním příkladu pojmenovaném SDLTest58 není ve skutečnosti použita žádná nová funkce. Tento příklad totiž bude sloužit jako základ pro následující dva demonstrační příklady se jmény SDLTest59SDLTest60. Implementovaný algoritmus je velmi jednoduchý – po spuštění tohoto demonstračního příkladu se nahraje rastrový obrázek „xscorch.bmp“, jenž můžete nalézt na této adrese: http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/raw-file/ce9cbc53b31c/sdljava/im­g/xscorch.bmp. Následně je tato bitmapa pomocí operace typu BitBLT/BLIT přenesena do framebufferu a zobrazena. Program poté čeká na stisk klávesy ESC, která jeho běh ukončí.

Obrázek 1: Obrazovka demonstračního příkladu SDLTest57.

Zdrojový kód demonstračního příkladu SDLTest57:

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.SDLSurface;
import sdljava.video.SDLVideo;
import sdljava.video.SDLRect;
 
import sdljava.x.swig.SDLPressedState;
import static sdljavax.gfx.SDLGfx.*;
 
 
 
/**
 * Padesaty sedmy demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Vykresleni bitmapy na obrazovku.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest57 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 480;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 480;
 
    /**
     * 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;
 
    /**
     * Nazev bitmapy, ktera se ma nacist a nasledne zobrazit.
     */
    private static final String INPUT_IMAGE_NAME = "xscorch.bmp";
 
    /**
     * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani.
     */
    private static SDLSurface initVideo() throws SDLException {
        final long flags = SDLVideo.SDL_DOUBLEBUF;
        return 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) {
                // pretypovani
                final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event;
 
                // symbol/kod klavesy
                final int symbol = keyEvent.getSym();
 
                // ESC ukonci program
                if (symbol == SDLKey.SDLK_ESCAPE && keyEvent.getState() == SDLPressedState.PRESSED) {
                    return;
                }
            }
        }
    }
 
    /**
     * Vykresleni sceny na obrazovku ci do okna aplikace.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktera se ma vykreslit
     */
    private static void drawOnScreen(SDLSurface screen, SDLSurface bitmap) throws SDLException {
        // vykresleni bitmapy s obrazkem
        drawBitmap(screen, bitmap);
 
        // nutno volat i v pripade, ze neni pouzit double buffering
        screen.updateRect();
        screen.flip();
    }
 
    /**
     * Vykresleni bitmapy na obrazovku.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktery se ma na obrazovku vykreslit
     */
    private static void drawBitmap(SDLSurface screen, SDLSurface bitmap) throws SDLException {
        // vypocitat umisteni bitmapy na obrazovce.
        final SDLRect rect = computePositionOnScreen(screen, bitmap);
 
        // provest operaci typu BitBLT
        bitmap.blitSurface(screen, rect);
 
    }
 
    /**
     * Vypocitat umisteni bitmapy na obrazovce.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa s pismem, ktera se ma na obrazovku vykreslit
     * @return obdelnik predstavujici pozici bitmapy na obrazovce
     */
    private static SDLRect computePositionOnScreen(SDLSurface screen, SDLSurface bitmap) {
        // ziskat rozmery obrazovky i bitmapy
        final int screenWidth = screen.getWidth();
        final int screenHeight = screen.getHeight();
        final int bitmapWidth = bitmap.getWidth();
        final int bitmapHeight = bitmap.getHeight();
 
        // vypocitat umisteni bitmapy na obrazovce
        final int x = (screenWidth - bitmapWidth)>>1;
        final int y = (screenHeight - bitmapHeight)>>1;
        return new SDLRect(x, y, bitmapWidth, bitmapHeight);
    }
 
    /**
     * Spusteni padesateho sedmeho 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
            final SDLSurface screen = initVideo();
 
            // nacteni bitmapy z externiho souboru
            final SDLSurface bitmap = SDLVideo.loadBMP(INPUT_IMAGE_NAME);
 
            // vykresleni sceny na obrazovku
            drawOnScreen(screen, bitmap);
 
            // 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();
        }
    }
 
}

Skript pro překlad tohoto demonstračního příkladu na Linuxu:

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

Dávkový soubor pro překlad tohoto demonstračního příkladu na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest57.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 SDLTest57

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

3. Demonstrační příklad SDLTest58 – změna měřítka bitmapy

V dnešním druhém demonstračním příkladu pojmenovaném SDLTest58 je ukázán způsob použití funkce sdljavax.gfx.SDLGfx.zoomSurface(). Této funkci se předává čtveřice parametrů – zdrojová bitmapa představovaná instancí třídy SDLSurface, měřítko v ose X, měřítko v ose Y a čtvrtým parametrem je pravdivostní příznak určující, zda se má při zvětšování či zmenšování bitmapy použít rychlý algoritmus pro výběr nejbližších pixelů (hodnota false) či poněkud pomalejší algoritmus implementující bilineární interpolaci (hodnota true). Návratovou hodnotou funkce zoomSurface() je nová bitmapa, tj. nová instance třídy SDLSurface. Povšimněte si, že měřítka v ose X i ose Y jsou na sobě nezávislá: při zadání hodnoty menší než jedna dojde ke zmenšení bitmapy v daném směru, při zadání hodnoty větší než jedna naopak ke zvětšení:

/**
 * Vykresleni sceny na obrazovku ci do okna aplikace.
 * 
 * @param screen
 *            framebuffer
 * @param bitmap
 *            bitmapa, ktera se ma zpracovat
 */
private static void drawOnScreen(SDLSurface screen, SDLSurface bitmap) throws SDLException {
    // vytvoreni nove bitmapy se zmenou meritka
    SDLSurface zoomedBitmap = zoomSurface(bitmap, 1.5, 2.3, false);
 
    // vykresleni nove bitmapy s obrazkem
    drawBitmap(screen, zoomedBitmap);
 
    // nutno volat i v pripade, ze neni pouzit double buffering
    screen.updateRect();
    screen.flip();
}

Obrázek 2: Obrazovka demonstračního příkladu SDLTest58 ve chvíli, kdy se při zvětšování/zmenšování bitmapy použije algoritmus výběru nejbližšího pixelu.

Obrázek 3: Obrazovka demonstračního příkladu SDLTest58 ve chvíli, kdy se při zvětšování/zmenšování bitmapy použije vylepšený algoritmus založený na bilineární transformaci.

Úplný zdrojový kód demonstračního příkladu SDLTest58 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.SDLSurface;
import sdljava.video.SDLVideo;
import sdljava.video.SDLRect;
 
import sdljava.x.swig.SDLPressedState;
import static sdljavax.gfx.SDLGfx.*;
 
 
 
/**
 * Padesaty osmy demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Vytvoreni nove bitmapy se zmenou meritka.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest58 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 480;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 480;
 
    /**
     * 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;
 
    /**
     * Nazev bitmapy, ktera se ma nacist a nasledne zobrazit.
     */
    private static final String INPUT_IMAGE_NAME = "xscorch.bmp";
 
    /**
     * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani.
     */
    private static SDLSurface initVideo() throws SDLException {
        final long flags = SDLVideo.SDL_DOUBLEBUF;
        return 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) {
                // pretypovani
                final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event;
 
                // symbol/kod klavesy
                final int symbol = keyEvent.getSym();
 
                // ESC ukonci program
                if (symbol == SDLKey.SDLK_ESCAPE && keyEvent.getState() == SDLPressedState.PRESSED) {
                    return;
                }
            }
        }
    }
 
    /**
     * Vykresleni sceny na obrazovku ci do okna aplikace.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktera se ma zpracovat
     */
    private static void drawOnScreen(SDLSurface screen, SDLSurface bitmap) throws SDLException {
        // vytvoreni nove bitmapy se zmenou meritka
        SDLSurface zoomedBitmap = zoomSurface(bitmap, 1.5, 2.3, false);
 
        // vykresleni nove bitmapy s obrazkem
        drawBitmap(screen, zoomedBitmap);
 
        // nutno volat i v pripade, ze neni pouzit double buffering
        screen.updateRect();
        screen.flip();
    }
 
    /**
     * Vykresleni bitmapy na obrazovku.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktery se ma na obrazovku vykreslit
     */
    private static void drawBitmap(SDLSurface screen, SDLSurface bitmap) throws SDLException {
        // vypocitat umisteni bitmapy na obrazovce.
        final SDLRect rect = computePositionOnScreen(screen, bitmap);
 
        // provest operaci typu BitBLT
        bitmap.blitSurface(screen, rect);
 
    }
 
    /**
     * Vypocitat umisteni bitmapy na obrazovce.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa s pismem, ktera se ma na obrazovku vykreslit
     * @return obdelnik predstavujici pozici bitmapy na obrazovce
     */
    private static SDLRect computePositionOnScreen(SDLSurface screen, SDLSurface bitmap) {
        // ziskat rozmery obrazovky i bitmapy
        final int screenWidth = screen.getWidth();
        final int screenHeight = screen.getHeight();
        final int bitmapWidth = bitmap.getWidth();
        final int bitmapHeight = bitmap.getHeight();
 
        // vypocitat umisteni bitmapy na obrazovce
        final int x = (screenWidth - bitmapWidth)>>1;
        final int y = (screenHeight - bitmapHeight)>>1;
        return new SDLRect(x, y, bitmapWidth, bitmapHeight);
    }
 
    /**
     * Spusteni padesateho 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
            final SDLSurface screen = initVideo();
 
            // nacteni bitmapy z externiho souboru
            final SDLSurface bitmap = SDLVideo.loadBMP(INPUT_IMAGE_NAME);
 
            // vykresleni sceny na obrazovku
            drawOnScreen(screen, bitmap);
 
            // 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();
        }
    }
 
}

Skript pro překlad tohoto demonstračního příkladu na Linuxu:

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

Dávkový soubor pro překlad tohoto demonstračního příkladu na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest58.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 SDLTest58

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

4. Demonstrační příklad SDLTest59 – rotace bitmapy

Zatímco v předchozím demonstračním příkladu byla použita funkce sdljavax.gfx.SDLGfx.zoomSurface() pro vytvoření nové zvětšené nebo zmenšené bitmapy, je v dnešním třetím demonstračním příkladu nazvaném SDLTest59 využita funkce sdljavax.gfx.SDLGfx.rotozo­omSurface(), kterou je možné použít pro současnou rotaci bitmapy i změnu jejího měřítka. I této funkci se předávají čtyři parametry – zdrojová bitmapa představovaná objektem typu SDLSurface, úhel otočení specifikovaný ve stupních, třetím parametrem lze specifikovat zvětšení či zmenšení bitmapy (ve všech směrech stejné) a ve čtvrtém parametru se opět s využitím pravdivostní hodnoty určuje buď rychlý algoritmus vybírající při otáčení nejbližší pixely, popř. pomalejší algoritmus s antialiasingem, který produkuje kvalitnější výsledky. Úhel otočení je reprezentován hodnotou typu double, což znamená, že otočení je možné specifikovat s větší přesností než jeden stupeň. Míra zvětšení či zmenšení bitmapy je taktéž reprezentována hodnotou typu double: hodnotami většími než 1 se zadává zvětšení, hodnotami menšími než 1 naopak zmenšení bitmapy:

/**
 * Vykresleni sceny na obrazovku ci do okna aplikace.
 * 
 * @param screen
 *            framebuffer
 * @param bitmap
 *            bitmapa, ktera se ma zpracovat
 */
private static void drawOnScreen(SDLSurface screen, SDLSurface bitmap) throws SDLException {
    // vytvoreni nove bitmapy s jeji rotaci
    SDLSurface rotatedBitmap = rotozoomSurface(bitmap, 45, 1.0, false);
 
    // vykresleni nove bitmapy s obrazkem
    drawBitmap(screen, rotatedBitmap);
 
    // nutno volat i v pripade, ze neni pouzit double buffering
    screen.updateRect();
    screen.flip();
}

Obrázek 4: Obrazovka demonstračního příkladu SDLTest59 ve chvíli, kdy se při zvětšování/zmenšování bitmapy použije algoritmus výběru nejbližšího pixelu.

Obrázek 5: Obrazovka demonstračního příkladu SDLTest59 ve chvíli, kdy se při zvětšování/zmenšování bitmapy použije vylepšený algoritmus založený na bilineární transformaci.

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

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.SDLSurface;
import sdljava.video.SDLVideo;
import sdljava.video.SDLRect;
 
import sdljava.x.swig.SDLPressedState;
import static sdljavax.gfx.SDLGfx.*;
 
 
 
/**
 * Padesaty devaty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Vytvoreni nove bitmapy s jeji rotaci.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest59 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 480;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 480;
 
    /**
     * 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;
 
    /**
     * Nazev bitmapy, ktera se ma nacist a nasledne zobrazit.
     */
    private static final String INPUT_IMAGE_NAME = "xscorch.bmp";
 
    /**
     * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani.
     */
    private static SDLSurface initVideo() throws SDLException {
        final long flags = SDLVideo.SDL_DOUBLEBUF;
        return 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) {
                // pretypovani
                final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event;
 
                // symbol/kod klavesy
                final int symbol = keyEvent.getSym();
 
                // ESC ukonci program
                if (symbol == SDLKey.SDLK_ESCAPE && keyEvent.getState() == SDLPressedState.PRESSED) {
                    return;
                }
            }
        }
    }
 
    /**
     * Vykresleni sceny na obrazovku ci do okna aplikace.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktera se ma zpracovat
     */
    private static void drawOnScreen(SDLSurface screen, SDLSurface bitmap) throws SDLException {
        // vytvoreni nove bitmapy s jeji rotaci
        SDLSurface rotatedBitmap = rotozoomSurface(bitmap, 45, 1.0, false);
 
        // vykresleni nove bitmapy s obrazkem
        drawBitmap(screen, rotatedBitmap);
 
        // nutno volat i v pripade, ze neni pouzit double buffering
        screen.updateRect();
        screen.flip();
    }
 
    /**
     * Vykresleni bitmapy na obrazovku.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktery se ma na obrazovku vykreslit
     */
    private static void drawBitmap(SDLSurface screen, SDLSurface bitmap) throws SDLException {
        // vypocitat umisteni bitmapy na obrazovce.
        final SDLRect rect = computePositionOnScreen(screen, bitmap);
 
        // provest operaci typu BitBLT
        bitmap.blitSurface(screen, rect);
 
    }
 
    /**
     * Vypocitat umisteni bitmapy na obrazovce.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa s pismem, ktera se ma na obrazovku vykreslit
     * @return obdelnik predstavujici pozici bitmapy na obrazovce
     */
    private static SDLRect computePositionOnScreen(SDLSurface screen, SDLSurface bitmap) {
        // ziskat rozmery obrazovky i bitmapy
        final int screenWidth = screen.getWidth();
        final int screenHeight = screen.getHeight();
        final int bitmapWidth = bitmap.getWidth();
        final int bitmapHeight = bitmap.getHeight();
 
        // vypocitat umisteni bitmapy na obrazovce
        final int x = (screenWidth - bitmapWidth)>>1;
        final int y = (screenHeight - bitmapHeight)>>1;
        return new SDLRect(x, y, bitmapWidth, bitmapHeight);
    }
 
    /**
     * Spusteni padesateho devateho 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
            final SDLSurface screen = initVideo();
 
            // nacteni bitmapy z externiho souboru
            final SDLSurface bitmap = SDLVideo.loadBMP(INPUT_IMAGE_NAME);
 
            // vykresleni sceny na obrazovku
            drawOnScreen(screen, bitmap);
 
            // 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();
        }
    }
 
}

Skript pro překlad tohoto demonstračního příkladu na Linuxu:

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

Dávkový soubor pro překlad tohoto demonstračního příkladu na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest59.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 SDLTest59

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

5. Zvukový subsystém knihovny SDLJava

Při popisu knihovny SDLJava jsme se prozatím soustředili zejména na vykreslování do framebufferu a na systém práce s událostmi. Ovšem tato knihovna v sobě integruje i další – mnohdy neméně významný – zvukový subsystém. Ten je z hlediska programátora implementován v balíčcích sdljava.audiosdljava.mixer, přičemž se v současné verzi knihovny SDLJava naprostá většina použitelných metod a funkcí nachází ve třídách dostupných v balíčku sdljava.mixer, zejména ve třídě sdljava.mixer.SDLMixer. S využitím této třídy je možné jednoduše přehrávat hudbu či zvuky, nastavovat hlasitost jednotlivých zvukových kanálů, automaticky zajistit postupné snížení hlasitosti, aplikovat další zvukové filtry na přehrávaný zvuk atd. Dnes se seznámíme pouze se základy využití zvukového subsystému, podrobnější informace o problematice nastavení bufferů apod. budou uvedeny v navazující části tohoto seriálu.

6. Základ přehrávání zvuků a hudby s využitím třídy SDLMixer

Podívejme se nyní, jakým způsobem lze zvukový subsystém knihovny SDLJava využít v praxi. Nejprve je nutné provést inicializaci zvukového subsystému, a to podobným způsobem, který již známe z inicializace subsystému grafického:

// inicializace knihovny SDLJava
SDLMain.init(SDLMain.SDL_INIT_AUDIO);

Následně je nutné přes metodu SDLMixer.openAudio() nastavit vzorkovací frekvenci přehrávaných samplů, formát zvuku (zde šestnáctibitové samply se stereo kanály), celkový počet zvukových kanálů vstupujících do mixéru a konečně velikost zvukových bufferů. My zde prozatím použijeme osvědčenou hodnotu 1024, ovšem příště si řekneme, za jakých okolností se vyplatí velikost bufferů změnit:

SDLMixer.openAudio(44100, SDLMixer.AUDIO_S16, 1, 1024);

Dále je nutné nastavit hlasitost pro přehrávání zvuků a/nebo hudby, a to jednou z těchto metod:

SDLMixer.volume(-1, 100);
SDLMixer.volumeMusic(100);

Při přehrávání zvuků se musí zvuková data buď vytvořit či načíst ze souboru a následně spustit přehrávání v určeném zvukovém kanálu:

// nacteni samplu z externiho souboru
MixChunk effect = SDLMixer.loadWAV("Kitten.wav");
 
// prehrani samplu
SDLMixer.playChannel(-1, effect, 0);

Podobně se postupuje při přehrávání hudby, která je typicky uložena v souborech MIDI, Ogg Vorbis či Amiga MOD:

// nacteni hudby z externiho souboru
MixMusic music = SDLMixer.loadMUS("Beast1_2.mod");
 
// prehrani hudby
SDLMixer.playMusic(music, -1);

Aplikace může jednoduše testovat, zda již došlo k ukončení přehrávání zvuku/zvuků (to je nutné pro znovunaplnění bufferu či bufferů):

// musime pockat na ukonceni prehravani
while (SDLMixer.playing(ALL_SOUND_CHANNELS) > 0) {
    SDLTimer.delay(100);
}

Taktéž lze testovat, zda se již přehrála celá hudební skladba:

// musime pockat na ukonceni prehravani
while (SDLMixer.playingMusic()) {
    SDLTimer.delay(100);
}

Celý postup bude ukázán na dvojici demonstračních příkladů popsaných v navazujících dvou kapitolách.

7. Demonstrační příklad SDLTest60 – přehrání zvuku načteného ze souboru .wav

Dnešní předposlední demonstrační příklad po svém spuštění načte zvukový soubor nazvaný „Kitten.wav“ (tento je konkrétně součástí programu Scratch) a přehraje ho v prvním zvukovém kanálu. Po inicializaci zvukového subsystému a nastavení hlasitosti se načte již zmíněný zvukový soubor pomocí metody SDLMixer.loadWAV(„Kitten.wav“). Následně se spustí přehrávání zvuku s využitím metody SDLMixer.playChannel(ALL_SO­UND_CHANNELS, effect, 0), kde je konstantou ALL_SOUND_CHANNELS=-1 určeno, že se má zahájit přehrávání ve všech vytvořených zvukových kanálech a hodnota 0 v posledním parametru udává počet přehrání (jedenkrát). Následně je nutné v programové smyčce počkat na přehrání zvuku; pokud by tato smyčka nebyla v programu použita, byla by aplikace ukončena ještě před inicializací přehrávání. Podívejme se nyní na zdrojový kód tohoto demonstračního příkladu, který není příliš dlouhý, a to díky využití relativně vysokoúrovňové třídy sdljava.mixer.SDLMixer:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.SDLTimer;
 
import sdljava.mixer.SDLMixer;
import sdljava.mixer.MixChunk;
 
 
 
/**
 * Sedesaty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * SDLJava a audio.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest60 {
 
    /**
     * Konstanta zastupujici vsechny zvukove kanaly.
     */
    static final int ALL_SOUND_CHANNELS = -1;
 
    /**
     * Prehrani zvukoveho vzorku.
     */
    public static void playSample() throws SDLException, InterruptedException {
        // nastaveni vlastnosti zvukoveho subsystemu i vybranych zvukovych kanalu
        SDLMixer.openAudio(44100, SDLMixer.AUDIO_S16, 1, 1024);
        SDLMixer.volume(ALL_SOUND_CHANNELS, 100);
 
        // nacteni samplu z externiho souboru
        MixChunk effect = SDLMixer.loadWAV("Kitten.wav");
 
        // prehrani samplu
        SDLMixer.playChannel(ALL_SOUND_CHANNELS, effect, 0);
 
        // musime pockat na ukonceni prehravani
        while (SDLMixer.playing(ALL_SOUND_CHANNELS) > 0) {
            SDLTimer.delay(100);
        }
    }
 
    /**
     * Spusteni sedesateho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace knihovny SDLJava
            SDLMain.init(SDLMain.SDL_INIT_AUDIO);
 
            // prehrani zvukoveho vzorku
            playSample();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            SDLMain.quit();
        }
    }
 
}

Skript pro překlad tohoto demonstračního příkladu na Linuxu:

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

Dávkový soubor pro překlad tohoto demonstračního příkladu na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest60.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 SDLTest60

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

8. Demonstrační příklad SDLTest61 – přehrání hudby načtené ze souboru .mod

V dnešním posledním demonstračním příkladu je ukázáno, jakým způsobem lze využít knihovnu SDLJava pro přehrávání hudby. Povšimněte si, že zdrojový kód tohoto příkladu je velmi krátký, protože díky použití třídy sdljava.mixer.SDLMixer je přehrávání hudby skutečně jednoduché. Nejprve je provedena inicializace zvukového subsystému (což již známe) a posléze se metodou SDLMixer.loadMUS(„Beast1_2.mod“) načte soubor obsahující hudbu – v tomto případě znělku ze známé hry Shadow of the Beast uloženou ve formátu amigáckých modulů, které jsou stále ještě dosti populární. Následně je přes metodu SDLMixer.playMusic(music, –1) spuštěno přehrávání hudby, přičemž hodnota –1 značí, že se má melodie přehrávat neustále dokola a kladná hodnota značí počet přehrání melodie. Následuje programová smyčka, v níž se metodou SDLMixer.playingMusic() zjišťuje, zda již nedošlo k ukončení melodie (což však při loop=-1 nikdy nenastane, takže se program musí ukončit přímo z terminálu:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.SDLTimer;
 
import sdljava.mixer.SDLMixer;
import sdljava.mixer.MixMusic;
 
 
 
/**
 * Sedesaty prvni demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * SDLJava a audio.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest61 {
 
    /**
     * Prehrani hudby.
     */
    public static void playMusic() throws SDLException, InterruptedException {
        // nastaveni vlastnosti zvukoveho subsystemu i vybranych zvukovych kanalu
        SDLMixer.openAudio(44100, SDLMixer.AUDIO_S16, 1, 1024);
        SDLMixer.volumeMusic(100);
 
        // nacteni hudby z externiho souboru
        MixMusic music = SDLMixer.loadMUS("Beast1_2.mod");
 
        // prehrani hudby
        SDLMixer.playMusic(music, -1);
 
        // musime pockat na ukonceni prehravani
        while (SDLMixer.playingMusic()) {
            SDLTimer.delay(100);
        }
    }
 
    /**
     * Spusteni sedesateho prvniho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace knihovny SDLJava
            SDLMain.init(SDLMain.SDL_INIT_AUDIO);
 
            // prehrani hudby
            playMusic();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            SDLMain.quit();
        }
    }
 
}

Skript pro překlad tohoto demonstračního příkladu na Linuxu:

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

Dávkový soubor pro překlad tohoto demonstračního příkladu na Windows:

set SDL_JAVA_LIBS=.\sdljava-0.9.1\lib
 
javac -cp %SDL_JAVA_LIBS%\sdljava.jar SDLTest61.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 SDLTest61

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

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 několika 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 SDLTest57.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest57/SDLTest57.ja­va
2 SDLTest57_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest57/SDLTest57_com­pile.sh
3 SDLTest57_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest57/SDLTest57_com­pile_sys.sh
4 SDLTest57_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest57/SDLTest57_run­.sh
5 SDLTest57_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest57/SDLTest57_run_sys­.sh
6 SDLTest57_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest57/SDLTest57_com­pile.bat
7 SDLTest57_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest57/SDLTest57_run­.bat
     
8 SDLTest58.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest58/SDLTest58.ja­va
9 SDLTest58_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest58/SDLTest58_com­pile.sh
10 SDLTest58_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest58/SDLTest58_com­pile_sys.sh
11 SDLTest58_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest58/SDLTest58_run­.sh
12 SDLTest58_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest58/SDLTest58_run_sys­.sh
13 SDLTest58_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest58/SDLTest58_com­pile.bat
14 SDLTest58_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest58/SDLTest58_run­.bat
     
15 SDLTest59.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest59/SDLTest59.ja­va
16 SDLTest59_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest59/SDLTest59_com­pile.sh
17 SDLTest59_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest59/SDLTest59_com­pile_sys.sh
18 SDLTest59_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest59/SDLTest59_run­.sh
19 SDLTest59_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest59/SDLTest59_run_sys­.sh
20 SDLTest59_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest59/SDLTest59_com­pile.bat
21 SDLTest59_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest59/SDLTest59_run­.bat
     
22 SDLTest60.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest60/SDLTest60.ja­va
23 SDLTest60_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest60/SDLTest60_com­pile.sh
24 SDLTest60_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest60/SDLTest60_com­pile_sys.sh
25 SDLTest60_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest60/SDLTest60_run­.sh
26 SDLTest60_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest60/SDLTest60_run_sys­.sh
27 SDLTest60_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest60/SDLTest60_com­pile.bat
28 SDLTest60_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest60/SDLTest60_run­.bat
     
29 SDLTest61.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest61/SDLTest61.ja­va
30 SDLTest61_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest61/SDLTest61_com­pile.sh
31 SDLTest61_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest61/SDLTest61_com­pile_sys.sh
32 SDLTest61_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest61/SDLTest61_run­.sh
33 SDLTest61_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest61/SDLTest61_run_sys­.sh
34 SDLTest61_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest61/SDLTest61_com­pile.bat
35 SDLTest61_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/ce9cbc53b31c/sdlja­va/SDLTest61/SDLTest61_run­.bat

10. Odkazy na Internetu

  1. SDL_mixer 2.0
    http://www.libsdl.org/pro­jects/SDL_mixer/
  2. SDLJava: package sdljava.ttf
    http://sdljava.sourceforge­.net/docs/api/sdljava/ttf/pac­kage-summary.html#package_description
  3. SDLJava: class sdljava.ttf.SDLTTF
    http://sdljava.sourceforge­.net/docs/api/sdljava/ttf/SDLTTF­.html
  4. SDLJava: class sdljava.ttf.SDLTrueTypeFont
    http://sdljava.sourceforge­.net/docs/api/sdljava/ttf/SDLTru­eTypeFont.html
  5. SDL_ttf Documentation
    http://www.libsdl.org/pro­jects/SDL_ttf/docs/
  6. SDL_ttf 2.0 (není prozatím součástí SDLJava)
    http://www.libsdl.org/pro­jects/SDL_ttf/
  7. SDL_ttf doc
    http://www.libsdl.org/pro­jects/SDL_ttf/docs/SDL_ttf_fra­me.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. glDrawArrays
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawArrays­.xml
  18. glDrawElements
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawElemen­ts.xml
  19. glDrawArraysInstanced
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawArraysIn­stanced.xml
  20. glDrawElementsInstanced
    http://www.opengl.org/sdk/doc­s/man4/xhtml/glDrawElemen­tsInstanced.xml
  21. Root.cz: Seriál Grafická knihovna OpenGL
    http://www.root.cz/serialy/graficka-knihovna-opengl/
  22. 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/
  23. 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
  24. Class BufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/i­mage/BufferStrategy.html
  25. Class Graphics
    http://docs.oracle.com/ja­vase/1.5.0/docs/api/java/aw­t/Graphics.html
  26. Double Buffering and Page Flipping
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/doublebuf.html
  27. BufferStrategy and BufferCapabilities
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/bufferstrategy.html
  28. Java:Tutorials:Double Buffering
    http://content.gpwiki.org/in­dex.php/Java:Tutorials:Dou­ble_Buffering
  29. Double buffer in standard Java AWT
    http://www.codeproject.com/Ar­ticles/2136/Double-buffer-in-standard-Java-AWT
  30. Java 2D: Hardware Accelerating – Part 1 – Volatile Images
    http://www.javalobby.org/fo­rums/thread.jspa?threadID=16840&tstar­t=0
  31. Java 2D: Hardware Accelerating – Part 2 – Buffer Strategies
    http://www.javalobby.org/ja­va/forums/t16867.html
  32. How does paintComponent work?
    http://stackoverflow.com/qu­estions/15544549/how-does-paintcomponent-work
  33. A Swing Architecture Overview
    http://www.oracle.com/technet­work/java/architecture-142923.html
  34. Class javax.swing.JComponent
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html
  35. Class java.awt.Component
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.html
  36. Class java.awt.Component.BltBufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.BltBufferStrategy.html
  37. Class java.awt.Component.FlipBufferStrategy
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.FlipBufferStrategy­.html
  38. Metoda java.awt.Component.isDoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/java/awt/Com­ponent.html#isDoubleBuffe­red()
  39. Metoda javax.swing.JComponent.is­DoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html#isDouble­Buffered()
  40. Metoda javax.swing.JComponent.set­DoubleBuffered()
    http://docs.oracle.com/ja­vase/6/docs/api/javax/swin­g/JComponent.html#setDouble­Buffered(boolean)
  41. Javadoc – třída GraphicsDevice
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsDevice.html
  42. Javadoc – třída GraphicsEnvironment
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsEnvironment.html
  43. Javadoc – třída GraphicsConfiguration
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Grap­hicsConfiguration.html
  44. Javadoc – třída DisplayMode
    http://docs.oracle.com/ja­vase/7/docs/api/java/awt/Dis­playMode.html
  45. Lesson: Full-Screen Exclusive Mode API
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/
  46. Full-Screen Exclusive Mode
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/exclusivemode.html
  47. Display Mode
    http://docs.oracle.com/ja­vase/tutorial/extra/fullscre­en/displaymode.html
  48. 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
  49. 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
  50. The JVM Instruction Set
    http://mpdeboer.home.xs4a­ll.nl/scriptie/node14.html
  51. MultiMedia eXtensions
    http://softpixel.com/~cwrig­ht/programming/simd/mmx.phpi
  52. SSE (Streaming SIMD Extentions)
    http://www.songho.ca/misc/sse/sse­.html
  53. Timothy A. Chagnon: SSE and SSE2
    http://www.cs.drexel.edu/~tc365/mpi-wht/sse.pdf
  54. Intel corporation: Extending the Worldr's Most Popular Processor Architecture
    http://download.intel.com/techno­logy/architecture/new-instructions-paper.pdf
  55. SIMD architectures:
    http://arstechnica.com/ol­d/content/2000/03/simd.ar­s/
  56. GC safe-point (or safepoint) and safe-region
    http://xiao-feng.blogspot.cz/2008/01/gc-safe-point-and-safe-region.html
  57. Safepoints in HotSpot JVM
    http://blog.ragozin.info/2012/10/sa­fepoints-in-hotspot-jvm.html
  58. Java theory and practice: Synchronization optimizations in Mustang
    http://www.ibm.com/develo­perworks/java/library/j-jtp10185/
  59. How to build hsdis
    http://hg.openjdk.java.net/jdk7/hot­spot/hotspot/file/tip/src/sha­re/tools/hsdis/README
  60. Java SE 6 Performance White Paper
    http://www.oracle.com/technet­work/java/6-performance-137236.html
  61. Lukas Stadler's Blog
    http://classparser.blogspot­.cz/2010/03/hsdis-i386dll.html
  62. How to build hsdis-amd64.dll and hsdis-i386.dll on Windows
    http://dropzone.nfshost.com/hsdis.htm
  63. PrintAssembly
    https://wikis.oracle.com/dis­play/HotSpotInternals/Prin­tAssembly
  64. The Java Virtual Machine Specification: 3.14. Synchronization
    http://docs.oracle.com/ja­vase/specs/jvms/se7/html/jvms-3.html#jvms-3.14
  65. 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
  66. 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
  67. 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
  68. Open Source ByteCode Libraries in Java
    http://java-source.net/open-source/bytecode-libraries
  69. ASM Home page
    http://asm.ow2.org/
  70. Seznam nástrojů využívajících projekt ASM
    http://asm.ow2.org/users.html
  71. ObjectWeb ASM (Wikipedia)
    http://en.wikipedia.org/wi­ki/ObjectWeb_ASM
  72. Java Bytecode BCEL vs ASM
    http://james.onegoodcooki­e.com/2005/10/26/java-bytecode-bcel-vs-asm/
  73. BCEL Home page
    http://commons.apache.org/bcel/
  74. Byte Code Engineering Library (před verzí 5.0)
    http://bcel.sourceforge.net/
  75. Byte Code Engineering Library (verze >= 5.0)
    http://commons.apache.org/pro­per/commons-bcel/
  76. BCEL Manual
    http://commons.apache.org/bcel/ma­nual.html
  77. Byte Code Engineering Library (Wikipedia)
    http://en.wikipedia.org/wiki/BCEL
  78. BCEL Tutorial
    http://www.smfsupport.com/sup­port/java/bcel-tutorial!/
  79. Bytecode Engineering
    http://book.chinaunix.net/spe­cial/ebook/Core_Java2_Volu­me2AF/0131118269/ch13lev1sec6­.html
  80. Bytecode Outline plugin for Eclipse (screenshoty + info)
    http://asm.ow2.org/eclipse/index.html
  81. Javassist
    http://www.jboss.org/javassist/
  82. Byteman
    http://www.jboss.org/byteman
  83. Java programming dynamics, Part 7: Bytecode engineering with BCEL
    http://www.ibm.com/develo­perworks/java/library/j-dyn0414/
  84. The JavaTM Virtual Machine Specification, Second Edition
    http://java.sun.com/docs/bo­oks/jvms/second_edition/html/VMSpec­TOC.doc.html
  85. The class File Format
    http://java.sun.com/docs/bo­oks/jvms/second_edition/html/Clas­sFile.doc.html
  86. javap – The Java Class File Disassembler
    http://docs.oracle.com/ja­vase/1.4.2/docs/tooldocs/win­dows/javap.html
  87. javap-java-1.6.0-openjdk(1) – Linux man page
    http://linux.die.net/man/1/javap-java-1.6.0-openjdk
  88. Using javap
    http://www.idevelopment.in­fo/data/Programming/java/mis­cellaneous_java/Using_javap­.html
  89. Examine class files with the javap command
    http://www.techrepublic.com/ar­ticle/examine-class-files-with-the-javap-command/5815354
  90. aspectj (Eclipse)
    http://www.eclipse.org/aspectj/
  91. Aspect-oriented programming (Wikipedia)
    http://en.wikipedia.org/wi­ki/Aspect_oriented_program­ming
  92. AspectJ (Wikipedia)
    http://en.wikipedia.org/wiki/AspectJ
  93. EMMA: a free Java code coverage tool
    http://emma.sourceforge.net/
  94. Cobertura
    http://cobertura.sourceforge.net/
  95. jclasslib bytecode viewer
    http://www.ej-technologies.com/products/jclas­slib/overview.html
Našli jste v článku chybu?
Lupa.cz: Blíží se konec Wi-Fi sítí bez hesla?

Blíží se konec Wi-Fi sítí bez hesla?

Vitalia.cz: Antibakteriální mýdla nepomáhají, spíš škodí

Antibakteriální mýdla nepomáhají, spíš škodí

Vitalia.cz: Voda z Vltavy před a po úpravě na pitnou

Voda z Vltavy před a po úpravě na pitnou

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

Cimrman má hry na YouTube i vlastní doodle

Podnikatel.cz: ČOI zamířila na e-shopy. Zaplatí 1,5 milionu

ČOI zamířila na e-shopy. Zaplatí 1,5 milionu

DigiZone.cz: DVB-T2 ověřeno: seznam TV zveřejněn

DVB-T2 ověřeno: seznam TV zveřejněn

Vitalia.cz: Nová vakcína proti chřipce se aplikuje nosem

Nová vakcína proti chřipce se aplikuje nosem

Podnikatel.cz: ČSSZ posílá přehled o důchodovém kontě

ČSSZ posílá přehled o důchodovém kontě

Vitalia.cz: Jsou vegani a vyrábějí nemléko

Jsou vegani a vyrábějí nemléko

DigiZone.cz: Digi Slovakia zařazuje stanice SPI

Digi Slovakia zařazuje stanice SPI

Root.cz: Hořící telefon Samsung Note 7 zapálil auto

Hořící telefon Samsung Note 7 zapálil auto

DigiZone.cz: Budoucnost TV vysílání ve Visegrádu

Budoucnost TV vysílání ve Visegrádu

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

Nova opět stahuje „milionáře“

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

Jak Ondra o astma přišel

Vitalia.cz: Muž, který miluje příliš. Ženám neimponuje

Muž, který miluje příliš. Ženám neimponuje

Vitalia.cz: Tahák, jak vyzrát nad zápachem z úst

Tahák, jak vyzrát nad zápachem z úst

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

dTest odhalil ten nejlepší kečup

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

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

DigiZone.cz: Technisat připravuje trojici DAB

Technisat připravuje trojici DAB

DigiZone.cz: Parlamentní listy: kde končí PR...

Parlamentní listy: kde končí PR...