Pohled pod kapotu JVM – volání funkcí OpenGL s využitím knihovny SDLJava

Pavel Tišnovský 4. 2. 2014

V dnešní části našeho předlouhého seriálu o programovacím jazyce Java i o virtuálním stroji Javy si ukážeme, jakým způsobem je možné využít knihovnu SDLJava pro získání takzvaného vykreslovacího kontextu OpenGL a jaké rozhraní nám SDLJava nabízí pro volání funkcí grafické knihovny OpenGL.

1. Pohled pod kapotu JVM – volání funkcí OpenGL s využitím knihovny SDLJava

2. Inicializace knihovny SDLJava a získání kontextu OpenGL

3. Inicializace stavového stroje OpenGL a vykreslení jednoduché scény

4. Demonstrační příklad SDLTest12 – použití OpenGL pro vykreslování

5. Geometrické entity v OpenGL 1.x a OpenGL 2.x

6. Demonstrační příklad SDLTest13 – vykreslení geometrických primitiv

7. Nastavení základních vlastností vykreslovaných objektů

8. Demonstrační příklad SDLTest14 – nastavení základních vlastností vykreslovaných bodů

9. Demonstrační příklad SDLTest15 – nastavení základních vlastností vykreslovaných úseček

10. Demonstrační příklad SDLTest16 – nastavení vlastností uzavřených plošných objektů

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

12. Odkazy na Internetu

1. Pohled pod kapotu JVM – volání funkcí OpenGL s využitím knihovny SDLJava

V předchozích částech seriálu o programovacím jazyku Java i o virtuálním stroji Javy jsme si ukázali využití metod nabízených knihovnou SDLJava při vykreslování bitmap do framebufferu i způsoby, jakými je možné číst či zapisovat hodnoty jednotlivých pixelů v libovolném objektu typu SDLSurface. Tyto možnosti nabízené třídami z balíčků SDLJava přesně odpovídají grafickým schopnostem nativní knihovny SDL 1.x, která kromě práce s bitmapami, vyplnění obdélníku a blokového přenosu jedné bitmapy do bitmapy jiné žádné další specializovanější funkce nepodporuje. To znamená, že například algoritmus pro vykreslení úsečky či vyplněného polygonu si buď musí vývojář sám naprogramovat, popř. může alternativně využít některé rozšiřující moduly, které byly ke knihovně SDL vyvinuty. Ovšem existuje ještě jedna možnost, která může být pro mnoho aplikací velmi užitečná – využití možností knihovny OpenGL a tím pádem i schopností nabízených staršími i moderními grafickými akcelerátory.

Vzhledem k tomu, že knihovna OpenGL byla navržena takovým způsobem, že její API je kompatibilní s jazyky C a Fortran, je nutné pro použití této knihovny z jiných programovacích jazyků vytvořit nějaké vhodné rozhraní. Týká se to i Javy, kde je toto rozhraní komplikováno mj. i nutností volat všechny funkce OpenGL přes JNI (Java Native Interface). V současnosti existuje hned několik podpůrných knihoven i celých enginů pro Javu, které javovským programátorům možnosti grafické knihovny OpenGL více či méně přímočarým způsobem zpřístupňují; my se v tomto článku budeme věnovat rozhraní, které je nabízené přímo v knihovně SDLJava. Toto rozhraní se nesnaží žádným způsobem možnosti OpenGL „obalovat“ další funkcionalitou, takže zde například nenalezneme třídy ani metody pro vytvoření grafu scény, načítání 3D formátů, tvorbu obalových těles atd. Namísto toho se při využití SDLJava setkáme s metodami, které jsou pojmenovány stejně jako funkce v nativní knihovně OpenGL a případné změny jsou provedeny jen kvůli rozdílům mezi C a Javou (bezznaménkové datové typy atd.).

2. Inicializace knihovny SDLJava a získání kontextu OpenGL

Funkce, které jsou nabízeny API grafické knihovny OpenGL, slouží pro nastavení parametrů vykreslovací pipeline a pro zahájení vykreslování těles složených z jednoduchých geometrických prvků typu bod, úsečka, trojúhelník, pruh trojúhelníků atd. V tomto API však nenajdeme žádné funkce pro vytvoření okna, nastavení grafického režimu, konfiguraci framebufferu či pro prohození funkcí předního a zadního bufferu. Tvůrci OpenGL rozumně předpokládali, že tyto funkce jsou zcela závislé na konkrétním operačním systému a tudíž je žádným způsobem do standardu(ů) OpenGL nezařadili. Z tohoto důvodu je nutné, aby se vytvoření okna pro vykreslování popř. nastavení celoobrazovkového grafického režimu řešilo s využitím jiných knihoven (SDL, GLUT/freeglut, GLFW, EGL apod.), popř. s využitím API podporovaného operačním systémem (příkladem může být WGL). Podobnou funkcionalitu nám samozřejmě nabízí i knihovna SDLJava.

Inicializace a získání takzvaného grafického kontextu OpenGL se skládá ze dvou kroků. Nejprve je nutné inicializovat celoobrazovkový grafický režim či otevřít okno pro vykreslování s uvedením bitového příznaku SDLVideo.SDL_OPENGL:

    /**
     * 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);
    }

Následně je nutné nad získaným objektem typu SDLSurface, který představuje framebuffer, zavolat metodu getGL() vracející instanci třídy implementující rozhraní org.gljava.opengl.GL:

    // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani
    SDLSurface screen = initVideo();
 
    // inicializace celoobrazovkoveho grafickeho rezimu
    GL gl = screen.getGL();

Přes metody předepsané rozhraním org.gljava.opengl.GL je již možné volat všechny funkce OpenGL, což si ukážeme v navazujících kapitolách na pětici demonstračních příkladů.

3. Inicializace stavového stroje OpenGL a vykreslení jednoduché scény

Jakmile máme k dispozici instanci třídy implementující rozhraní org.gljava.opengl.GL, je již možné přes tuto instanci volat nativní funkce knihovny OpenGL. Nejprve se podívejme, jak se nastavují transformační matice (projekční matice a modelview matice). Nejprve se přes Gl.glMatrixMode() určí, obsah jaké matice se má nastavit a posléze se přes Gl.glLoadIdentity() načte jednotková matice, což pro naše účely (jednoduchá 2D scéna) plně postačuje. Následně se přes Gl.glOrtho() nastaví ortogonální promítání (bez perspektivy). Metoda Gl.glDisable(gl.GL_DEPTH_TEST) zakáže provádění testů na hloubku (vzdálenost) jednotlivých fragmentů vytvářených v procesu rasterizace objektů a metoda Gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f) specifikuje barvu, kterou se vymaže pozadí okna, přesněji řečeno zadní buffer uložený ve framebufferu. Při jejím volání se zadávají čtyři barvové složky (Red, Green, Blue a Alpha), z nichž každá je v rozsahu 0.0–1.0 (0.0 znamená nepřítomnost příslušné barvové složky ve výsledné barvě, 1.0 maximální vysvícení):

    /**
     * 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, 0, height, -1, 1);
 
        // nastaveni modelview matice
        gl.glMatrixMode(gl.GL_MODELVIEW);
        gl.glLoadIdentity();
        // viditelna oblast
        gl.glViewport(0, 0, width, height);
 
        // vypnuti pameti hloubky pri vykreslovani
        gl.glDisable(gl.GL_DEPTH_TEST);
 
        // barva pozadi framebufferu pro volani glClear()
        gl.glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
    }

Při vykreslování budeme používat takzvaný přímý režim (direct mode), který byl specifikován již v OpenGL verze 1.x a dodnes je dodržována zpětná kompatibilita s tímto režimem. Teoreticky se sice přímý režim stal v OpenGL 3.1 oficiálně nepodporovaným, ovšem například ovladače karet nVidia ho stále podporují a podle tvrzení firmy i podporovat budou (nový a obecně i rychlejší způsob vykreslování si přiblížíme v některé navazující části tohoto seriálu).

Metoda Gl.glBegin(Gl.GL_QUADS) zahájí vykreslování čtyřúhelníků, z nichž každý je specifikován čtyřmi vrcholy. Tyto vrcholy se zadávají například příkazem Gl.glVertex2i(), kterému předáme 2D souřadnice vrcholu čtyřúhelníku. Ukončení zadávání vrcholů zajistí příkaz Gl.glEnd(), který tvoří takzvané „příkazové závorky“ společně s voláním Gl.glBegin(). Tyto příkazy tedy vždy musí tvořit pár. Posledním příkazem je Gl.glFlush(), jenž zajistí provedení všech operací na grafické kartě. Bez uvedení tohoto příkazu by se mohlo stát, že některé objekty by nebyly zobrazeny, protože by zůstaly v nedokončeném stavu v grafické pipeline akcelerátoru:

    /**
     * Vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL.
     */
    private static void drawScene(GL gl) {
        // vymazani framebufferu
        gl.glClear(gl.GL_COLOR_BUFFER_BIT);
        // vykresleni ctverce
        gl.glBegin(gl.GL_QUADS);
            gl.glColor3f(1.0f, 0.0f, 0.0f);
            gl.glVertex2i(200, 100);
            gl.glColor3f(0.0f, 1.0f, 0.0f);
            gl.glVertex2i(600, 100);
            gl.glColor3f(1.0f, 0.0f, 1.0f);
            gl.glVertex2i(600, 500);
            gl.glColor3f(0.0f, 0.0f, 1.0f);
            gl.glVertex2i(200, 500);
        gl.glEnd();
    }

4. Demonstrační příklad SDLTest12 – použití OpenGL pro vykreslování

V dnešním prvním demonstračním příkladu si ukážeme jak inicializaci knihovny SDLJava, tak i způsob získání kontextu OpenGL. Ve chvíli, kdy je tento kontext získán, je již možné provést inicializaci stavového stroje OpenGL a následně vykreslit jednoduchou scénu způsobem, který jsme si popsali v předchozích dvou kapitolách:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.video.SDLPixelFormat;
import sdljava.video.SDLSurface;
import sdljava.video.SDLVideo;
 
import org.gljava.opengl.GL;
 
 
 
/**
 * Dvanacty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Ukazka vyuziti zakladnich moznosti graficke knihovny OpenGL -
 * vykresleni ctyruhelniku a vypocet barvy s vyuzitim
 * Gouraudova stinovani.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest12 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 800;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 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, 0, height, -1, 1);
 
        // nastaveni modelview matice
        gl.glMatrixMode(gl.GL_MODELVIEW);
        gl.glLoadIdentity();
        // viditelna oblast
        gl.glViewport(0, 0, width, height);
 
        // vypnuti pameti hloubky pri vykreslovani
        gl.glDisable(gl.GL_DEPTH_TEST);
 
        // barva pozadi framebufferu pro volani glClear()
        gl.glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
    }
 
    /**
     * Vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL.
     */
    private static void drawScene(GL gl) {
        // vymazani framebufferu
        gl.glClear(gl.GL_COLOR_BUFFER_BIT);
        // vykresleni ctverce
        gl.glBegin(gl.GL_QUADS);
            gl.glColor3f(1.0f, 0.0f, 0.0f);
            gl.glVertex2i(200, 100);
            gl.glColor3f(0.0f, 1.0f, 0.0f);
            gl.glVertex2i(600, 100);
            gl.glColor3f(1.0f, 0.0f, 1.0f);
            gl.glVertex2i(600, 500);
            gl.glColor3f(0.0f, 0.0f, 1.0f);
            gl.glVertex2i(200, 500);
        gl.glEnd();
    }
 
    /**
     * 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);
 
            // vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL
            drawScene(gl);
 
            // prepnuti predniho a zadniho bufferu
            screen.glSwapBuffers();
 
            // ukonceni 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 SDLTest12.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 SDLTest12.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 SDLTest12

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

Obrázek 1: Screenshot demonstračního příkladu SDLTest12.java.

5. Geometrické entity v OpenGL 1.x a OpenGL 2.x

Pomocí příkazů OpenGL lze při použití přímého režimu vykreslovat pouze základní geometrické prvky, které nazýváme primitiva. Z těchto primitiv se potom skládají složitější tělesa a celé rozsáhlé 3D scény. Existuje celkem deset typů primitiv, mezi než patří: izolovaný bod, úsečka zadaná dvěma koncovými body, řetězec úseček (polyčára), uzavřená smyčka vytvořená z úseček (uzavřená polyčára), trojúhelník, trs trojúhelníků, pás trojúhelníků, rovinný čtyřúhelník, pás rovinných čtyřúhelníků a rovinný konvexní polygon.

Při vykreslování každého primitiva musíme nejdříve zadat příkaz Gl.glBegin(typ primitiva), kterým knihovně OpenGL sdělujeme, že se začínají zadávat jednotlivé vrcholy primitiva popř. i vlastnosti těchto vrcholů. Vykreslování se ukončí párovým příkazem Gl.glEnd(), který nemá žádné parametry. Mezi příkazy Gl.glBegin()Gl.glEnd() lze zadat libovolný počet vrcholů primitiva příkazem Gl.glVertex*(). Vrcholy jsou zadané svými souřadnicemi, a to buď dvěma (x, y), třemi (x, y, z) nebo čtyřmi (x, y, z, w).

Pro dvourozměrné scény zadáváme pouze souřadnice (x, y) a vrcholy se zadávají příkazem Gl.glVertex2*(), kde se za znak * dosadí příznak udávající datový typ (i-int, f-float apod.) parametrů. Souřadnice (z) se automaticky nastaví na nulu a souřadnice (w) na jedničku.

Pro 3D scény zadáváme buď souřadnice (x, y, z) nebo celou čtveřici (x, y, z, w). Pro trojici souřadnic se pro zadání vrcholů používá příkaz Gl.glVertex3*(), pro čtveřici souřadnic potom Gl.glVertex4*(). Pokud je zadána pouze trojice souřadnic, dosadí se za souřadnici w automaticky jednička. Souřadnice w je použita při perspektivní projekci, a udává váhu vrcholu (weight). Pro běžné použití vždy tuto souřadnici nastavujeme na jedničku, protože touto souřadnicí se dělí zbylé tři souřadnice, tedy x'=x/w, y'=y/wz'=z/w.

6. Demonstrační příklad SDLTest13 – vykreslení geometrických primitiv

Po překladu a spuštění dnešního druhého demonstračního příkladu se do okna vykreslí všechna grafická primitiva podporovaná knihovnou OpenGL v případě, že se pro vykreslování využívá přímý režim (direct mode). Ve spodní části okna jsou postupně vykresleny body, jednotlivé úsečky, polyčára a uzavřená polyčára, ve druhé řadě pak trojúhelník, pruh trojúhelníků a trs trojúhelníků. V horní řadě je zobrazen čtyřúhelník, pruh sestavený ze čtyřúhelníků a obecný konvexní mnohostěn:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.video.SDLPixelFormat;
import sdljava.video.SDLSurface;
import sdljava.video.SDLVideo;
 
import org.gljava.opengl.GL;
 
 
 
/**
 * Trinacty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Ukazka vyuziti zakladnich moznosti graficke knihovny OpenGL -
 * vykresleni nekolika bodu a linearnich geometrickych tvaru.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest13 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 800;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 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*2/3, 0, height*2/3, -1, 1);
 
        // nastaveni modelview matice
        gl.glMatrixMode(gl.GL_MODELVIEW);
        gl.glLoadIdentity();
 
        // viditelna oblast
        gl.glViewport(0, 0, width, height);
 
        // vypnuti pameti hloubky pri vykreslovani
        gl.glDisable(gl.GL_DEPTH_TEST);
 
        // barva pozadi framebufferu pro volani glClear()
        gl.glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
    }
 
    /**
     * Vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL.
     */
    private static void drawScene(GL gl) {
        // vymazani framebufferu
        gl.glClear(gl.GL_COLOR_BUFFER_BIT);
 
        // nastaveni barvy pro vykreslovani
        gl.glColor3f(1.0f, 1.0f, 1.0f);
        gl.glBegin(gl.GL_POINTS);                         // nyni zacneme vykreslovat body
            gl.glVertex2i( 50,  50);
            gl.glVertex2i(100,  50);
            gl.glVertex2i(100, 100);
            gl.glVertex2i( 50, 100);
        gl.glEnd();
 
        gl.glColor3f(1.0f, 0.0f, 1.0f);
        gl.glBegin(gl.GL_LINES);                          // nyni zacneme vykreslovat usecky
            gl.glVertex2i(150,  50);
            gl.glVertex2i(200,  50);
            gl.glVertex2i(200, 100);
            gl.glVertex2i(150, 100);
        gl.glEnd();
 
        gl.glColor3f(0.0f, 1.0f, 1.0f);
        gl.glBegin(gl.GL_LINE_STRIP);                     // nyni vykreslime polycaru
            gl.glVertex2i(250,  50);
            gl.glVertex2i(300,  50);
            gl.glVertex2i(300, 100);
            gl.glVertex2i(250, 100);
        gl.glEnd();
 
        gl.glColor3f(1.0f, 1.0f, 0.0f);
        gl.glBegin(gl.GL_LINE_LOOP);                      // nyni vykreslime uzavrenou polycaru
            gl.glVertex2i(350,  50);
            gl.glVertex2i(400,  50);
            gl.glVertex2i(400, 100);
            gl.glVertex2i(350, 100);
        gl.glEnd();
 
        gl.glColor3f(0.0f, 0.0f, 1.0f);
        gl.glBegin(gl.GL_TRIANGLES);                      // vykresleni trojuhelniku
            gl.glVertex2i( 50, 150);
            gl.glVertex2i(100, 150);
            gl.glVertex2i(100, 200);
            gl.glVertex2i( 50, 200);
        gl.glEnd();
 
        gl.glColor3f(0.0f, 1.0f, 0.0f);
        gl.glBegin(gl.GL_TRIANGLE_STRIP);                 // vykresleni pruhu trojuhelniku
            gl.glVertex2i(150, 150);
            gl.glVertex2i(150, 200);
            gl.glVertex2i(200, 200);
            gl.glVertex2i(200, 150);
        gl.glEnd();
 
        gl.glColor3f(1.0f, 0.0f, 0.0f);
        gl.glBegin(gl.GL_TRIANGLE_FAN);                   // vykresleni trsu trojuhelniku
            gl.glVertex2i(300, 150);
            gl.glVertex2i(250, 160);
            gl.glVertex2i(270, 190);
            gl.glVertex2i(290, 200);
            gl.glVertex2i(310, 200);
            gl.glVertex2i(330, 190);
            gl.glVertex2i(350, 160);
        gl.glEnd();
 
        gl.glColor3f(1.0f, 0.5f, 0.5f);
        gl.glBegin(gl.GL_QUADS);                          // vykresleni ctyruhelniku
            gl.glVertex2i( 50, 250);
            gl.glVertex2i(100, 250);
            gl.glVertex2i(100, 300);
            gl.glVertex2i( 50, 300);
        gl.glEnd();
 
        gl.glColor3f(0.5f, 0.5f, 1.0f);
        gl.glBegin(gl.GL_QUAD_STRIP);                     // vykresleni pruhu ctyruhleniku
            gl.glVertex2i(150, 250);
            gl.glVertex2i(150, 300);
            gl.glVertex2i(200, 240);
            gl.glVertex2i(200, 310);
            gl.glVertex2i(250, 260);
            gl.glVertex2i(250, 290);
            gl.glVertex2i(300, 250);
            gl.glVertex2i(300, 300);
        gl.glEnd();
 
        gl.glColor3f(0.5f, 1.0f, 0.5f);
        gl.glBegin(gl.GL_POLYGON);                        // vykresleni konvexniho polygonu
            gl.glVertex2i(350, 260);
            gl.glVertex2i(370, 240);
            gl.glVertex2i(390, 240);
            gl.glVertex2i(410, 260);
            gl.glVertex2i(410, 280);
            gl.glVertex2i(390, 300);
            gl.glVertex2i(370, 300);
            gl.glVertex2i(350, 280);
        gl.glEnd();
    }
 
    /**
     * 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);
 
            // vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL
            drawScene(gl);
 
            // prepnuti predniho a zadniho bufferu
            screen.glSwapBuffers();
 
            // ukonceni cele aplikace po peti sekundach
            Thread.sleep(5000);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
        // zobrazit ziskane informace
    }
 
}

Skript pro překlad na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest13.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 SDLTest13.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 SDLTest13

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

Obrázek 2: Screenshot demonstračního příkladu SDLTest13.java.

7. Nastavení základních vlastností vykreslovaných objektů

Při vykreslování lze velmi jednoduše měnit mnoho vlastností primitiv/objektů. První vlastností, kterou lze měnit u všech typů primitiv, je barva vrcholu. Jelikož je bod zadán pouze jedním vrcholem (příkazem Gl.glVertex*()), je zadaná barva pro celý bod konstantní, pro úsečky a plošné útvary je tomu však jinak. Barva se zadává příkazem Gl.glColor*(). Formát barvy je definován v barvovém modelu RGB (Red, Green, Blue – tedy tři barevné složky) nebo RGBA (Red, Green, Blue, Alpha – tři barevné složky a průhlednost). Jako typ dat lze pro specifikaci jednotlivých barevných složek zadat libovolný datový typ OpenGL; my se budeme v demonstračních příkladech držet typu float.

Druhou vlastností je velikost bodu. Velikost se zadává příkazem Gl.glPointSize(float size), kde parametr size musí být větší než nula. Implicitní velikost bodu je nastavena na 1.0 což odpovídá jednomu pixelu na obrazovce. Velikost bodu nelze měnit uvnitř „závorkových příkazů“ glBegin()glEnd().

Třetí vlastností, kterou lze vypnout nebo zapnout je antialiasing bodů. Antialiasing se zapíná příkazem Gl.glEnable(Gl.GL_POINT_SMOOTH) a vypíná příkazem Gl.glDisable(Gl.GL_POINT_SMOOTH). Pokud je antialiasing vypnutý, body se zobrazují jako čtverce, pokud je zapnutý, tak by se body měly zobrazit jako kruhy s rozmazanými okraji. Zde je zapotřebí zdůraznit, že ne všechny grafické akcelerátory podporují kruhové body. Antialiasing nelze zapnout a vypnout uvnitř závorkových příkazů glBegin()glEnd(). Při vypnutém antialiasingu se velikost bodů zaokrouhluje na celé pixely, pokud je však antialiasing zapnutý, velikost může být neceločíselná.

Podobně jako u bodů, i u úseček lze měnit jejich barvu. Pokud se barva specifikuje před „závorkovým příkazem“ Gl.glBegin(), je celá úsečka vykreslena konstantní barvou. Pokud se barva specifikuje mezi příkazy Gl.glBegin()Gl.glEnd(), může se měnit barva jednotlivých vrcholů. Na grafické kartě se potom automaticky provede lineární interpolace barev mezi vrcholy. Druhou vlastností je tloušťka úsečky. Ta se nastavuje příkazem Gl.glLineWidth(float width), kde width musí být větší než nula. Implicitní tloušťka úseček je nastavena na hodnotu 1.0 což odpovídá jednomu pixelu na obrazovce.

Při vykreslování úseček lze, podobně jako u bodů, povolit nebo zakázat antialiasing. Pro tento účel se používají příkazy Gl.glEnable(Gl.GL_LINE_SMOOTH)Gl.glDisable(Gl.GL_LINE_SMOOTH). Pokud je antialiasing úseček vypnutý, úsečka se vykreslí s ostrými hranami a konce úseček budou zarovnány s nejbližší souřadnou osou (konce jsou tedy horizontální nebo vertikální). Pokud je antialiasing úseček zapnutý, úsečka se vykreslí s rozmazanými hranami a konce úseček budou vždy kolmé na směrnici úsečky.

Poslední vlastností úseček je maska, která se používá při vykreslování jednotlivých pixelů úsečky. Maska je šestnáctibitová hodnota, kde jednotlivé bity určují, zda se má některá část úsečky vykreslit. Maska tedy specifikuje vzorek, kterým je úsečka vykreslena. Pokud je například maska nastavena na hodnotu 0×fff0 (binárně 1111111111110000), bude vždy dvanáct pixelů vykresleno a čtyři pixely nevykresleny. Maska se zadává příkazem Gl.glLineStipple(factor, pastrongern), kde factor je faktor zvětšení masky ve směru úsečky (vzorek lze tedy na úsečce „natahovat“) a pastrongern je bitová maska. Pro povolení maskování se musí zavolat příkaz Gl.glEnable(Gl.GL_LINE_STIPPLE), pro zakázání Gl.glDisable(Gl.GL_LINE_STIPPLE). Implicitně je maskování zakázáno.

U plošných útvarů lze, podobně jako u bodů a úseček, měnit jejich barvu. Pokud se barva specifikuje před příkazem Gl.glBegin(), je celý útvar vykreslen jednou konstantní barvou (pokud nepoužijeme texturování a osvětlení – viz další díly). Pokud barvu specifikujeme mezi „závorkovými příkazy“ Gl.glBegin()Gl.glEnd(), lze měnit barvu jednotlivých vrcholů. Grafická karta nebo softwarová implementace OpenGL potom provede interpolaci barvy. Tímto jednoduchým způsobem lze v OpenGL dosáhnout Gouraudova stínování.

Každý plošný útvar má dvě strany (faces) – rub a líc (backfront). Tyto strany (orientace se zjistí z normálového vektoru) mohou být vykresleny odlišně. Toho se dá využít například při řezu objektů, kdy je jasné, která strana leží uvnitř a která vně tělesa. Odvrácené strany úplně uzavřených těles lze ořezat (operace culling).

Pro rub a/nebo líc lze zadat mód vykreslování. Jsou možné tři varianty:

  • vykreslí se pouze vrcholy polygonu (plošného útvaru)
  • vykreslí se hrany polygonu
  • vykreslí se vyplněný polygon

Mód vykreslování plošných útvarů se změní příkazem Gl.glPolygonMode(face, mode), kde parametr face může nabývat hodnot Gl.GL_FRONT_AND_BACK (obě strany), Gl.GL_FRONT (přední strana) a Gl.GL_BACK (zadní strana). Parametr mode může nabývat hodnot Gl.GL_POINT (vykreslují se vrcholy), Gl.GL_LINE (vykreslují se hrany) a Gl.GL_FILL (vyplněný polygon).

8. Demonstrační příklad SDLTest14 – nastavení základních vlastností vykreslovaných bodů

V demonstračním příkladu SDLTest14 je ukázáno, jakým způsobem lze nastavit základní vlastnosti vykreslovaných bodů. Na obrazovce (resp. ve vytvořeném okně) se ve spodní části vykreslí několik bodů s různou barvou (tyto body mají velikost jednoho pixelu), nad nimi jsou nakresleny čtvercové body o různé velikosti (antialiasing je zakázaný) a v horní řadě pak kulaté body, opět s různou velikostí (zde je naopak antialiasing povolený):

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.video.SDLPixelFormat;
import sdljava.video.SDLSurface;
import sdljava.video.SDLVideo;
 
import org.gljava.opengl.GL;
 
 
 
/**
 * Ctrnacty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Nastaveni vlastnosti zakladnich geometrickych tvaru (zde konkretne bodu)
 * vykreslovanych pres OpenGL.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest14 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 800;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 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/2, 0, height/2, -1, 1);
 
        // nastaveni modelview matice
        gl.glMatrixMode(gl.GL_MODELVIEW);
        gl.glLoadIdentity();
 
        // viditelna oblast
        gl.glViewport(0, 0, width, height);
 
        // vypnuti pameti hloubky pri vykreslovani
        gl.glDisable(gl.GL_DEPTH_TEST);
 
        // barva pozadi framebufferu pro volani glClear()
        gl.glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
    }
 
    /**
     * Vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL.
     */
    private static void drawScene(GL gl) {
        // vymazani framebufferu
        gl.glClear(gl.GL_COLOR_BUFFER_BIT);
 
        gl.glDisable(gl.GL_POINT_SMOOTH);              // zakazani antialiasingu bodu
        gl.glPointSize(1.0f);                          // velikost vykreslovanych bodu je jeden pixel
        gl.glBegin(gl.GL_POINTS);
        for (float loop=0.0f; loop<=1.0f; loop+=0.1f) {// vykresleni prvni rady bodu ruzne barvy
            gl.glColor3f(loop, 0.5f, 1.0f-loop);       // zmena barvy uvnitr prikazovych "zavorek" glBegin()/glEnd()
            gl.glVertex2f(50.0f+300.0f*loop, 50.0f);
        }
        gl.glEnd();
 
        for (float loop=0.0f; loop<=1.0f; loop+=0.1f) {// vykresleni druhe rady bodu ruzne velikosti a barvy
            gl.glColor3f(loop, 0.5f, 1.0f-loop);       // zmena barvy vne prikazovych "zavorek" glBegin()/glEnd()
            gl.glPointSize(loop*20.0f+1.0f);           // zmena velikosti vykreslovanych bodu
            gl.glBegin(gl.GL_POINTS);
                gl.glVertex2f(50.0f+300.0f*loop, 100.0f);
            gl.glEnd();
        }
 
        gl.glEnable(gl.GL_POINT_SMOOTH);               // povoleni antialiasingu bodu
        for (float loop=0.0f; loop<=1.0f; loop+=0.1f) {// vykresleni treti rady bodu ruzne velikosti a barvy
            gl.glColor3f(loop, 0.5f, 1.0f-loop);       // zmena barvy vne prikazovych "zavorek" glBegin()/glEnd()
            gl.glPointSize(loop*20.0f+1.0f);           // zmena velikosti vykreslovanych bodu
            gl.glBegin(gl.GL_POINTS);
                gl.glVertex2f(50.0f+300.0f*loop, 150.0f);
            gl.glEnd();
        }
        gl.glFlush();                                  // provedeni a vykresleni vsech zmen
    }
 
    /**
     * Spusteni osmeho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace video subsystemu knihovny SDL
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
 
            // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani
            SDLSurface screen = initVideo();
 
            // inicializace celoobrazovkoveho grafickeho rezimu
            GL gl = screen.getGL();
 
            // nastaveni transformacnich matic a barvy pozadi framebufferu
            initScene(gl, GFX_WIDTH, GFX_HEIGHT);
 
            // vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL
            drawScene(gl);
 
            // prepnuti predniho a zadniho bufferu
            screen.glSwapBuffers();
 
            // ukonceni cele aplikace po peti sekundach
            Thread.sleep(5000);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
        // zobrazit ziskane informace
    }
 
}

Skript pro překlad na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest14.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 SDLTest14.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 SDLTest14

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

Obrázek 3: Screenshot demonstračního příkladu SDLTest14.java.

9. Demonstrační příklad SDLTest15 – nastavení základních vlastností vykreslovaných úseček

Dnešní předposlední příklad, jehož název je SDLTest15, slouží pro ukázku, jak je možné nastavit vlastnosti vykreslovaných úseček. Do vytvořeného okna jsou vykresleny úsečky, u nichž je barva počátečního a koncového vrcholu odlišná, což znamená, že grafický akcelerátor musí použít lineární stínování. Dále je u úseček nastavena rozdílná tloušťka, antialiasing (zapnutý/vypnutý) a v horní části okna můžeme vidět několik úseček, u nichž se postupně mění jejich vzorek:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.video.SDLPixelFormat;
import sdljava.video.SDLSurface;
import sdljava.video.SDLVideo;
 
import org.gljava.opengl.GL;
 
 
 
/**
 * Patnacty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Nastaveni vlastnosti zakladnich geometrickych tvaru vykreslovanych
 * pres OpenGL.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest15 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 800;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 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/2, 0, height/2, -1, 1);
 
        // nastaveni modelview matice
        gl.glMatrixMode(gl.GL_MODELVIEW);
        gl.glLoadIdentity();
 
        // viditelna oblast
        gl.glViewport(0, 0, width, height);
 
        // vypnuti pameti hloubky pri vykreslovani
        gl.glDisable(gl.GL_DEPTH_TEST);
 
        // barva pozadi framebufferu pro volani glClear()
        gl.glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
    }
 
    /**
     * Vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL.
     */
    private static void drawScene(GL gl) {
        int patterns[]={0xff00, 0xf0f0, 0xcccc, 0x5555, 0xfe10, 0x5e32};
 
        // vymazani framebufferu
        gl.glClear(gl.GL_COLOR_BUFFER_BIT);
 
        gl.glDisable(gl.GL_LINE_SMOOTH);               // zakazani antialiasingu usecek
        gl.glDisable(gl.GL_LINE_STIPPLE);              // zakazani maskovani pixelu na care
        gl.glLineWidth(1.0f);                          // tloustka usecky je jeden pixel
        gl.glBegin(gl.GL_LINES);
 
        for (float loop=0.0f; loop<=1.0f; loop+=0.1f) {   // vykresleni prvni rady usecek ruzne barvy
            gl.glColor3f(loop, 0.0f, 1.0f-loop);       // zmena barvy uvnitr prikazovych "zavorek" glBegin()/glEnd()
            gl.glVertex2f(50.0f+300.0f*loop, 20.0f);
            gl.glColor3f(loop, 1.0f, 1.0f-loop);
            gl.glVertex2f(100.0f+300.0f*loop, 70.0f);
        }
        gl.glEnd();
        for (float loop=0.0f; loop<=1.0f; loop+=0.1f) {// vykresleni druhe rady usecek ruzne tloustky
            gl.glLineWidth(loop*10.0f+0.1f);           // zmena tloustky usecky
            gl.glBegin(gl.GL_LINES);
                gl.glColor3f(loop, 0.0f, 1.0f-loop);   // zmena barvy uvnitr prikazovych "zavorek" glBegin()/glEnd()
                gl.glVertex2f(50.0f+300.0f*loop, 90.0f);
                gl.glColor3f(loop, 1.0f, 1.0f-loop);
                gl.glVertex2f(100.0f+300.0f*loop, 140.0f);
            gl.glEnd();
        }
        gl.glEnable(gl.GL_LINE_SMOOTH);                // povoleni antialiasingu usecek
        for (float loop=0.0f; loop<=1.0f; loop+=0.1f) {// vykresleni treti rady usecek ruzne tloustky
            gl.glLineWidth(loop*10.0f+0.1f);           // zmena tloustky usecky
            gl.glBegin(gl.GL_LINES);
                gl.glColor3f(loop, 0.0f, 1.0f-loop);   // zmena barvy uvnitr prikazovych "zavorek" glBegin()/glEnd()
                gl.glVertex2f(50.0f+300.0f*loop, 160.0f);
                gl.glColor3f(loop, 1.0f, 1.0f-loop);
                gl.glVertex2f(100.0f+300.0f*loop, 210.0f);
            gl.glEnd();
        }
        gl.glDisable(gl.GL_LINE_SMOOTH);               // zakazani antialiasingu usecek
        gl.glEnable(gl.GL_LINE_STIPPLE);               // povoleni maskovani pixelu na care
        gl.glLineWidth(1.0f);                          // tloustka usecky je jeden pixel
        gl.glColor3f(1.0f, 1.0f, 1.0f);                // zmena barvy vne prikazovych "zavorek" glBegin()/glEnd()
        for (int i=0; i<6; i++) {
            gl.glLineStipple(2, patterns[i]);          // nastaveni masky pri kresleni usecek
            gl.glBegin(gl.GL_LINES);
                gl.glVertex2i(50, 230+i*15);           // vykresleni usecky
                gl.glVertex2i(350, 230+i*15);
            gl.glEnd();
        }
        gl.glFlush();                                  // provedeni a vykresleni vsech zmen
    }
 
    /**
     * Spusteni osmeho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace video subsystemu knihovny SDL
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
 
            // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani
            SDLSurface screen = initVideo();
 
            // inicializace celoobrazovkoveho grafickeho rezimu
            GL gl = screen.getGL();
 
            // nastaveni transformacnich matic a barvy pozadi framebufferu
            initScene(gl, GFX_WIDTH, GFX_HEIGHT);
 
            // vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL
            drawScene(gl);
 
            // prepnuti predniho a zadniho bufferu
            screen.glSwapBuffers();
 
            // ukonceni cele aplikace po peti sekundach
            Thread.sleep(5000);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
        // zobrazit ziskane informace
    }
 
}

Skript pro překlad na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest15.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 SDLTest15.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 SDLTest15

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

Obrázek 4: Screenshot demonstračního příkladu SDLTest15.java.

10. Demonstrační příklad SDLTest16 – nastavení vlastností uzavřených plošných objektů

V posledním demonstračním příkladu s názvem SDLTest16 je ukázán způsob nastavení vlastností uzavřených plošných objektů, v tomto konkrétním případě trojúhelníků. Trojúhelníky jsou vykresleny různým způsobem: s výplní (Gouraudovo stínování), pouze hrany a pouze vrcholy:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.video.SDLPixelFormat;
import sdljava.video.SDLSurface;
import sdljava.video.SDLVideo;
 
import org.gljava.opengl.GL;
 
 
 
/**
 * Sestnacty demonstracni priklad vyuzivajici knihovnu SDLjava.
 *
 * Nastaveni vlastnosti zakladnich geometrickych tvaru vykreslovanych
 * pres OpenGL.
 *
 * @author Pavel Tisnovsky
 */
public class SDLTest16 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_WIDTH = 800;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna.
     */
    private static final int GFX_HEIGHT = 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*2/3, 0, height*2/3, -1, 1);
 
        // nastaveni modelview matice
        gl.glMatrixMode(gl.GL_MODELVIEW);
        gl.glLoadIdentity();
 
        // viditelna oblast
        gl.glViewport(0, 0, width, height);
 
        // vypnuti pameti hloubky pri vykreslovani
        gl.glDisable(gl.GL_DEPTH_TEST);
 
        // barva pozadi framebufferu pro volani glClear()
        gl.glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
    }
 
    /**
     * Vykresleni trojuhelniku na urcenou pozici.
     */
    private static void drawTriangle(GL gl, int x, int y)
    {
        gl.glBegin(gl.GL_TRIANGLES);
            gl.glColor3f(1.0f, 0.0f, 0.0f);   // kazdy vertex bude vykresleny jinou barvou
            gl.glVertex2i(x, y);
            gl.glColor3f(0.0f, 1.0f, 0.0f);
            gl.glVertex2i(x+100, y);
            gl.glColor3f(0.0f, 0.0f, 1.0f);
            gl.glVertex2i(x+50, y+80);
        gl.glEnd();
    }
 
    /**
     * Vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL.
     */
    private static void drawScene(GL gl) {
        // vymazani framebufferu
        gl.glClear(gl.GL_COLOR_BUFFER_BIT);
 
        gl.glPointSize(5.0f);                          // velikost bodu je rovna peti pixelum
        gl.glLineWidth(2.0f);                          // tloustka usecek je rovna dvema pixelum
        gl.glEnable(gl.GL_POINT_SMOOTH);               // povoleni antialiasingu bodu
        gl.glEnable(gl.GL_LINE_SMOOTH);                // povoleni antialiasingu usecek
        gl.glDisable(gl.GL_POLYGON_STIPPLE);           // zakazat vzorek
        gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL);  // vykreslovani vyplnenych trojuhelniku
        drawTriangle(gl, 50, 50);
        gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_LINE);  // vykreslovani pouze hran trojuhelniku
        drawTriangle(gl, 180, 50);
        gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_POINT); // vykreslovani pouze vrcholu trojuhelniku
        drawTriangle(gl, 310, 50);
        gl.glPolygonMode(gl.GL_FRONT_AND_BACK, gl.GL_FILL);  // vykreslovani vyplnenych trojuhelniku
        gl.glFlush();                                  // provedeni a vykresleni vsech zmen
    }
 
    /**
     * Spusteni osmeho demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace video subsystemu knihovny SDL
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
 
            // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani
            SDLSurface screen = initVideo();
 
            // inicializace celoobrazovkoveho grafickeho rezimu
            GL gl = screen.getGL();
 
            // nastaveni transformacnich matic a barvy pozadi framebufferu
            initScene(gl, GFX_WIDTH, GFX_HEIGHT);
 
            // vykresleni velmi jednoduche sceny s vyuzitim funkci OpenGL
            drawScene(gl);
 
            // prepnuti predniho a zadniho bufferu
            screen.glSwapBuffers();
 
            // ukonceni cele aplikace po peti sekundach
            Thread.sleep(5000);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            // musime obnovit puvodni graficky rezim
            // i v tom pripade, ze nastane nejaka vyjimka
            SDLMain.quit();
        }
        // zobrazit ziskane informace
    }
 
}

Skript pro překlad na Linuxu:

#!/bin/sh
 
SDL_JAVA_LIBS=./sdljava-0.9.1/lib
 
javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest16.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 SDLTest16.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 SDLTest16

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

widgety

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

Obrázek 5: Screenshot demonstračního příkladu SDLTest16.java.

11. 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 třech 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 SDLTest12.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest12/SDLTest12.ja­va
2 SDLTest12_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest12/SDLTest12_com­pile.sh
3 SDLTest12_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest12/SDLTest12_com­pile_sys.sh
4 SDLTest12_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest12/SDLTest12_run­.sh
5 SDLTest12_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest12/SDLTest12_run_sys­.sh
6 SDLTest12_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest12/SDLTest12_com­pile.bat
7 SDLTest12_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest12/SDLTest12_run­.bat
     
8 SDLTest13.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest13/SDLTest13.ja­va
9 SDLTest13_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest13/SDLTest13_com­pile.sh
10 SDLTest13_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest13/SDLTest13_com­pile_sys.sh
11 SDLTest13_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest13/SDLTest13_run­.sh
12 SDLTest13_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest13/SDLTest13_run_sys­.sh
13 SDLTest13_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest13/SDLTest13_com­pile.bat
14 SDLTest13_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest13/SDLTest13_run­.bat
     
15 SDLTest14.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest14/SDLTest14.ja­va
16 SDLTest14_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest14/SDLTest14_com­pile.sh
17 SDLTest14_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest14/SDLTest14_com­pile_sys.sh
18 SDLTest14_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest14/SDLTest14_run­.sh
19 SDLTest14_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest14/SDLTest14_run_sys­.sh
20 SDLTest14_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest14/SDLTest14_com­pile.bat
21 SDLTest14_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest14/SDLTest14_run­.bat
     
22 SDLTest15.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest15/SDLTest15.ja­va
23 SDLTest15_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest15/SDLTest15_com­pile.sh
24 SDLTest15_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest15/SDLTest15_com­pile_sys.sh
25 SDLTest15_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest15/SDLTest15_run­.sh
26 SDLTest15_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest15/SDLTest15_run_sys­.sh
27 SDLTest15_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest15/SDLTest15_com­pile.bat
28 SDLTest15_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest15/SDLTest15_run­.bat
     
29 SDLTest16.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest16/SDLTest16.ja­va
30 SDLTest16_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest16/SDLTest16_com­pile.sh
31 SDLTest16_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest16/SDLTest16_com­pile_sys.sh
32 SDLTest16_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest16/SDLTest16_run­.sh
33 SDLTest16_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest16/SDLTest16_run_sys­.sh
34 SDLTest16_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest16/SDLTest16_com­pile.bat
35 SDLTest16_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/70d370f78ee0/sdlja­va/SDLTest16/SDLTest16_run­.bat

12. Odkazy na Internetu

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

5 pravidel proti infekci močových cest

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

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

Lupa.cz: Patička e-mailu závazná jako vlastnoruční podpis?

Patička e-mailu závazná jako vlastnoruční podpis?

120na80.cz: Galerie: Čínští policisté testují českou minerálku

Galerie: Čínští policisté testují českou minerálku

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

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

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

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

DigiZone.cz: Regionální tele­vize CZ vysílá "Mapu úspěchu"

Regionální tele­vize CZ vysílá "Mapu úspěchu"

Vitalia.cz: Tradiční čínská medicína a rakovina

Tradiční čínská medicína a rakovina

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

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

Vitalia.cz: Tesco nabízí desítky tun jídla zdarma

Tesco nabízí desítky tun jídla zdarma

Podnikatel.cz: Rohlik.cz testoval roboty pro rozvážku

Rohlik.cz testoval roboty pro rozvážku

Podnikatel.cz: Nemá dluhy? Zjistíte to na poště

Nemá dluhy? Zjistíte to na poště

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

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

Lupa.cz: Jak se prodává firma za miliardu?

Jak se prodává firma za miliardu?

Podnikatel.cz: Udělali jsme velkou chybu, napsal Čupr

Udělali jsme velkou chybu, napsal Čupr

DigiZone.cz: Technisat připravuje trojici DAB

Technisat připravuje trojici DAB

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

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

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

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

120na80.cz: Pálení žáhy: která jídla ne a co nás uzdraví?

Pálení žáhy: která jídla ne a co nás uzdraví?

Lupa.cz: Blíží se konec Wi-Fi sítí bez hesla?

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