Hlavní navigace

Pohled pod kapotu JVM – základní koncepty, na nichž je postavena knihovna SDLJava

21. 1. 2014
Doba čtení: 29 minut

Sdílet

V dnešní části seriálu o programovacím jazyce Java i o virtuálním stroji Javy si popíšeme základní koncepty používané při vykreslování s využitím knihovny SDLJava. Popíšeme si především možnosti třídy sdljava.video.SDLSurface, včetně metod využívaných při operacích typu BitBLT.

Obsah

1. Pohled pod kapotu JVM – základní koncepty, na nichž je postavena knihovna SDLJava

2. Třída sdljava.video.SDLRect

3. Třída sdljava.video.SDLSurface

4. Načtení bitmapy s využitím metody sdljava.video.SDLVideo.loadBMP()

5. Podpora dalších grafických formátů

6. Operace typu BitBLT realizovaná mezi dvěma objekty typu sdljava.video.SDLSurface

7. Demonstrační příklad SDLTest4 – načtení bitmapy typu BMP a provedení operace BitBLT

8. Demonstrační příklad SDLTest5 – určení pozice, kde se má bitmapa vykreslit

9. Demonstrační příklad SDLTest6 – ořez bitmapy při provádění operace typu BitBLT

10. Demonstrační příklad SDLTest7 – načtení bitmapy uložené ve formátu PNG

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

12. Odkazy na Internetu

1. Pohled pod kapotu JVM – základní koncepty, na nichž je postavena knihovna SDLJava

V dnešní části seriálu o programovacím jazyce Java i o virtuálním stroji tohoto jazyka budeme pokračovat v popisu možností knihovny SDLJava. V předchozím díle jsme si řekli základní informace o této knihovně; víme tedy, že se jedná o „objektové“ rozhraní ke známé nativní knihovně SDL. Taktéž jsme si na trojici demonstračních příkladů ukázali, jak lze knihovnu SDLJava využít ve vlastních aplikacích. Dnes se podrobněji seznámíme se základy vykreslování grafických scén s využitím SDLJava a tím pádem i SDL. Demonstrační příklady, s nimiž se seznámíme, budou využívat šestici tříd vypsaných v následující tabulce, ovšem popis bude zaměřen především na třídy sdljava.video.SDLRect, sdljava.video.SDLVideosdljava.video.SDLSurface, které tvoří základ grafického subsystému knihovny SDL a v posledním demonstračním příkladu bude využita i třída sdljava.image.SDLImage:

# Třída Stručný popis
1 sdljava.SDLMain tato třída obsahuje především metody pro inicializaci knihovny SDL a pro korektní ukončení činnosti aplikace
2 sdljava.SDLException výjimka vyhazovaná při provedení některé neplatné operace v knihovně SDLJava či SDL
3 sdljava.video.SDLRect jednoduchá třída obalující strukturu SDL_rect z knihovny SDL
4 sdljava.video.SDLVideo třída se statickými metodami používanými při práci s grafikou
5 sdljava.video.SDLSurface reprezentuje bitmapu či framebuffer, do něhož je možné provádět vykreslování
6 sdljava.image.SDLImage třída obsahující jedinou přetíženou metodu load určenou pro načtení bitmap z různých zdrojů (souborů, bufferu, URL atd.)

2. Třída sdljava.video.SDLRect

První třída z knihovny SDLJava, s níž se dnes podrobněji seznámíme, má plný název sdljava.video.SDLRect . Instance této třídy reprezentují obdélník se specifikovanými souřadnicemi jeho levého horního rohu i se zadanými rozměry (šířka, výška). Obdélníky jsou v knihovně SDLJava využity na několika místech; my se s nimi konkrétně setkáme v souvislosti s operací typu BitBLT, v níž mohou být obdélníky použity jak pro specifikaci umístění kopírované bitmapy, tak i pro nastavení ořezávání při kopiích bitmap. Jak jednotlivé souřadnice, tak i šířka a výška každého obdélníku jsou reprezentovány celými čísly typu int, zatímco v nativní knihovně SDL vypadá datový typ SDL_Rect následovně:

typedef struct SDL_Rect {
        Sint16 x, y;
        Uint16 w, h;
} SDL_Rect;

Ve třídě sdljava.video.SDLRect mohou programátoři přímo přistupovat k atributům x, y, widthheight, popř. mohou alternativně použít příslušné gettery a settery, které jsou navíc rozšířeny o metody setLocation()setSize():

# Metoda Popis
1 int getX() getter pro atribut x
2 int getY() getter pro atribut y
3 int getWidth() getter pro atribut width
4 int getHeight() getter pro atribut height
5 void setX(int x) setter pro atribut x
6 void setY(int y) setter pro atribut y
7 void setWidth(int width) setter pro atribut width
8 void setHeight(int height) setter pro atribut height
9 void setLocation(int x, int y) nastavuje atributy xy
10 void setSize(int width, int height) nastavuje atributy widthheight

Velmi často se taktéž používá konstruktor public SDLRect(int x, int y, int width, int height).

3. Třída sdljava.video.SDLSurface

Zatímco třída sdljava.video.SDLRect popsaná v předchozí kapitole je velmi jednoduchá a jedná se vlastně jen o přímočaře navrženou obalovou třídu nad céčkovou datovou strukturou, je třída sdljava.video.SDLSurface již mnohem složitější, a to jak svojí vnitřní strukturou, tak i metodami, které tato třída nabízí. Objekty typu SDLSurface představují v knihovně SDLJava bitmapu, do níž je možné provádět vykreslování, popř. kterou lze s využitím operace typu BitBLT přenést do jiné bitmapy. SDLSurface však v SDL taktéž představuje i vlastní framebuffer, což znamená, že většinu operací, kterou lze provádět s bitmapami uloženými v operační paměti, je možné provádět i s framebufferem. Třída SDLSurface obaluje nativní datovou strukturu SDL_Surface, jejíž deklarace vypadá následovně:

typedef struct SDL_Surface {
        Uint32 flags;                           /** Read-only */
        SDL_PixelFormat *format;                /** Read-only */
        int w, h;                               /** Read-only */
        Uint16 pitch;                           /** Read-only */
        void *pixels;                           /** Read-write */
        int offset;                             /** Private */
 
        /** Hardware-specific surface info */
        struct private_hwdata *hwdata;
 
        /** clipping information */
        SDL_Rect clip_rect;                     /** Read-only */
        Uint32 unused1;                         /** for binary compatibility */
 
        /** Allow recursive locks */
        Uint32 locked;                          /** Private */
 
        /** info for fast blit mapping to other surfaces */
        struct SDL_BlitMap *map;                /** Private */
 
        /** format version, bumped at every change to invalidate blit maps */
        unsigned int format_version;            /** Private */
 
        /** Reference count -- used when freeing surface */
        int refcount;                           /** Read-mostly */
} SDL_Surface;

Programátory využívající knihovnu SDLJava však budou velmi pravděpodobně zajímat především metody, které jim třída SDLSurface nabízí. Stručně je možné říci, že se nabízené metody rozdělují do několika kategorií: vytvoření či načtení bitmapy/plochy, vyplnění plochy či její části barvou, přístup k jednotlivým pixelům a konečně přenos celé plochy či její části na jinou plochu či obrazovku. Důležitou metodou je SDLSurface.loadBMP() popsaná v navazující kapitole. Dále zde můžeme nalézt metodu SDLSurface.fillRect() sloužící buď pro vyplnění celé plochy/bitmapy jednou barvou, nebo pro vyplnění obdélníka specifikovaného pomocí SDLRect. Ukázku použití těchto metod jsme mohli vidět v předchozí části tohoto seriálu. Samostatnou kategorií je přetížená metoda SDLSurface.blitSurface() sloužící pro vykonání operace typu BitBLT.

4. Načtení bitmapy s využitím metody sdljava.video.SDLVideo.loadBMP()

Většina her, v nichž je použita knihovna SDL (resp. přeneseně i SDLJava) pro práci s 2D grafikou, musí nějakým způsobem načítat rastrové obrázky z externích souborů. Samotná základní varianta knihovny SDL se nesnaží pokrýt všechny dostupné grafické formáty ani suplovat další knihovny (giflib, libpng, libjpeg…) a z tohoto důvodu podporuje pouze načítání rastrových obrázků uložených v souborech typu BMP neboli (Windows) Bitmap. Tento formát byl navržen firmami IBM a Microsoft (každá firma navrhla jinou variantu) jako základní rastrový obrazový formát pro jejich operační systémy OS/2 a Microsoft Windows. Tím pádem je načítání i ukládání obrázků v tomto formátu podporováno přímo v aplikačním rozhraní daného operačního systému a tvůrci programů mohou toto rozhraní využít bez toho, aby daný formát detailně znali.

Zajímavý je také způsob ukládání obrazových řádků do souborů. Ty se totiž v původních verzích neukládaly směrem shora dolů, jak je to přirozené pro programátory, mikroprocesory, operační paměti i pro použité zobrazovací prostředky (grafické karty, tiskárny), ale přesně naopak – zespoda nahoru. Vzhledem k tomu, že i vykreslování obrázků pomocí WinAPI se provádí od spodního okraje, se vše výrazně komplikuje. Důvod, proč je směr vykreslování a ukládání u bitmap (přesněji řečeno obrázků typu BMP) opačný, spočívá v tom, že tuto orientaci původně používal operační systém OS/2, který je však v tomto ohledu alespoň konzistentní – souřadnice rostou směrem od levého spodního rohu směrem doprava a nahoru. Ve WinAPI se však používá „klasické“ a přirozenější orientace souřadnic, které rostou od levého horního rohu směrem doprava a dolů, a tak se opačný smysl vykreslování bitmap do tohoto systému vůbec nehodí a u několika API funkcí způsobuje zmatky v chápání směru.

Nicméně tyto implementační detaily nemusí programátory využívající SDL/SDLJava příliš zajímat. Praktičtější je informace, že pro načtení bitmapy se používá statická metoda static SDLSurface. loadBMP(java.lang.String path), které se předá cesta k bitmapě a výsledkem je přímo objekt typu SDLSurface, jenž lze buď zkonvertovat nebo přímo vykreslit na obrazovku. Povšimněte si, že se této metodě předává řetězec s cestou a nikoli objekt typu File, takže záleží jen na programátorovi, zda správně ošetří jména souborů s bitmapami takovým způsobem, aby byl program přenositelný (týká se to zejména oddělovačů adresářů). Příklad použití této metody si ukážeme v demonstračním příkladu SDLTest4, který je popsán v sedmé kapitole, nicméně základní idiom je jednoduchý:

// nacteni bitmapy z externiho souboru
SDLSurface bitmap = SDLVideo.loadBMP("test.bmp");

5. Podpora dalších grafických formátů

Podpora grafického formátu BMP v jádru knihovny SDL nemusí být pro mnoho aplikací dostačující, zejména ve chvíli, kdy je například vyvíjena hra s velkým množstvím obrázků. V takovém případě by byly nároky na potřebnou kapacitu disku zbytečně velké; navíc má formát BMP jen omezené možnosti definice průhlednosti pixelů. Alternativním řešením je využití jednoho z přídavných modulů knihovny SDL, který se jmenuje SDL_image. I tento modul je v knihovně SDLJava dostupný a to konkrétně přes třídu sdljava.image.SDLImage. Tato třída obsahuje jen jedinou přetíženou statickou metodu load(), která vrací, podobně jako výše popsaná metoda SDLSurface.loadBMP(), objekt typu SDLSurface. Přes sdljava.image.SDLImage.load() je možné načíst bitmapy uložené do různých formátů, ovšem pro většinu programátorů budou pravděpodobně nejdůležitější formáty PNGJPEG:

# Metoda Popis
1 static SDLSurface load(java.nio.Buffer buf) načtení bitmapy, která je uložena v bufferu
2 static SDLSurface load(byte[] data) načtení bitmapy uložené v poli
3 static SDLSurface load(java.io.InputStream in) načtení bitmapy ze vstupního proudu
4 static SDLSurface load(java.lang.String file) načtení bitmapy ze souboru specifikovaného jménem
5 static SDLSurface load(java.net.URL url) načtení bitmapy z místa specifikovaného pomocí URL

V mnoha aplikacích se programátoři pravděpodobně spokojí s načtením každé bitmapy ze samostatného souboru, ovšem někdy může být výhodnější všechny bitmapy uložit do souboru jediného a pro jejich načtení následně využít vstupní proud popř. buffer. Knihovna SDLJava sama rozpozná hlavičku grafického formátu i ukončení obrázku.

6. Operace typu BitBLT realizovaná mezi dvěma objekty typu sdljava.video.SDLSurface

Jakmile jsou bitmapy načteny z externích souborů, je nutné je nějakým způsobem vykreslit. V knihovně SDLJava se tato operace provádí pomocí přetížené metody SDLSurface.blitSurface(). Tato metoda existuje ve třech variantách, které se od sebe liší počtem a významem parametrů. Základní operace však zůstává stejná – zdrojová bitmapa (tj. objekt typu SDLSurface) je přenesena do bitmapy cílové, která je vždy předána v prvním parametru metody SDLSurface.blitSurface(). V případě, že je zdrojová bitmapa menší než bitmapa cílová, je zdrojová bitmapa přenesena do levého horního rohu cílové bitmapy. Pokud je naopak zdrojová bitmapa větší, je při jejím přenosu provedeno její ořezání.

Pokud je nutné explicitně specifikovat pozici zdrojové bitmapy v bitmapě cílové, používá se druhá varianta metody SDLSurface.blitSurface(), kde se kýžená pozice specifikuje pomocí objektu typu SDLRect (význam má jen pozice jeho levého horního rohu). Ovšem při přenosu bitmapy je možné provést i její ořezání na základě informací uložených ve druhém objektu typu SDLRect. Souřadnice představované tímto objektem se vztahují vždy ke zdrojové bitmapě (k jejímu lokálnímu souřadnému systému):

# Metoda Popis
1 int blitSurface(SDLSurface dstSurface) přenos bitmapy do levého horního rohu cílové bitmapy
2 int blitSurface(SDLSurface dstSurface, SDLRect dst) předchozí operace + možnost specifikace místa, na nějž bude bitmapa přenesena
3 int blitSurface(SDLRect src, SDLSurface dstSurface, SDLRect dst) předchozí operace + možnost specifikace ořezového obdélníka

Všechny tři varianty budou použity v demonstračních příkladech.

7. Demonstrační příklad SDLTest4 – načtení bitmapy typu BMP a provedení operace BitBLT

V prvním demonstračním příkladu si ukážeme způsob načtení bitmapy s jejím následným vykreslením na obrazovku. Nejprve je provedena inicializace knihovny SDL s využitím statické metody SDLMain.init(), které se pomocí konstanty SDLMain.SDL_INIT_VIDEO předá informace o tom, že se bude využívat pouze grafický subsystém SDL. Následně je s využitím taktéž statické metody SDLVideo.setVideoMode() provedeno přepnutí do celoobrazovkového grafického režimu s rozlišením 800×600 pixelů a s bitovou hloubkou 16 bitů na pixel. Všechny tyto operace jsme si již popsali v předchozí části tohoto seriálu. Následně se s využitím metody SDLVideo.loadBMP() načte bitmapa uložená ve formátu Microsoft Bitmap. Návratovou hodnotou této metody je instance třídy SDLSurface, v níž jsou uloženy jak hodnoty (barvy) jednotlivých pixelů, tak i rozměry bitmapy, její formát apod. Bitmapa je na obrazovku vykreslena pomocí metody SDLSurface.blitSurface(SDLSurface), přičemž plochou/bitmapou, do níž má být vykreslení provedeno, je samotný framebuffer.

Příklad má pořadové číslo 4, protože navazuje na demonstrační příklady vysvětlené minule:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.video.SDLVideo;
import sdljava.video.SDLSurface;
 
 
 
/**
 * Ctvrty demonstracni priklad vyuzivajici knihovnu SDLjava.
 * Po spusteni se provede prepnuti do grafickeho rezimu 800x600x16
 * Po inicializaci grafickeho rezimu se nacte bitmapa "xscorch.bmp",
 * ktera se nasledne vykresli na obrazovku operaci typu BitBLT.
 */
public class SDLTest4 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu.
     */
    private static final int GFX_WIDTH = 800;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu.
     */
    private static final int GFX_HEIGHT = 600;
 
    /**
     * Bitova hloubka vybraneho grafickeho rezimu.
     */
    private static final int GFX_BPP = 16;
 
    /**
     * Nazev bitmapy, ktera se ma nacist a nasledne zobrazit.
     */
    private static final String IMAGE_NAME = "xscorch.bmp";
 
    /**
     * Vykresleni bitmapy na obrazovku.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktery se ma na obrazovku vykreslit
     */
    private static void drawOnScreen(SDLSurface screen, SDLSurface bitmap) throws SDLException {
        // provest operaci typu BitBLT
        bitmap.blitSurface(screen);
        // nutno volat i v pripade, ze neni pouzit double buffering
        screen.updateRect();
        screen.flip();
    }
 
    /**
     * Spusteni demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace video subsystemu knihovny SDL.
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
            // inicializace celoobrazovkoveho grafickeho rezimu
            final SDLSurface screen = SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, SDLVideo.SDL_FULLSCREEN);
            // nacteni bitmapy z externiho souboru
            final SDLSurface bitmap = SDLVideo.loadBMP(IMAGE_NAME);
            // vykresleni bitmapy na obrazovku
            drawOnScreen(screen, bitmap);
            Thread.sleep(5000);
        }
        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 (Linux):

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

Skript pro překlad (Windows):

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

Skript pro spuštění (Linux):

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

Skript pro spuštění (Windows):

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

8. Demonstrační příklad SDLTest5 – určení pozice, kde se má bitmapa vykreslit

V dnešním druhém demonstračním příkladu pojmenovaném SDLTest5 si ukážeme další možnosti nabízené metodou SDLSurface.blitSurface. V předchozím příkladu se bitmapa načtená z externího souboru zobrazila v levém horním rohu obrazovky nastavené na grafický režim 800×600×16 bpp. V naprosté většině případů (snad až na vykreslení pozadí celé scény) však budeme potřebovat vykreslit bitmapu na jinou pozici na obrazovce. K tomuto účelu se musí namísto metody SDLSurface.blitSurface(SDLSurface dstSurface) použít její rozšířená varianta blitSurface(SDLSurface dstSurface, SDLRect dst). Této metodě se navíc předává obdélník, jehož počáteční souřadnice (x,y) určují, ve kterém místě na obrazovce (či na jiné bitmapě) se má zdrojová bitmapa začít vykreslovat, tj. kde bude ležet její horní levý roh. Šířka a výška obdélníku zde nemá prakticky žádný význam, v demonstračním příkladu se však pro úplnost nastaví i tyto dva atributy, a to konkrétně v metodě computePositionOnScreen.

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

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.video.SDLRect;
import sdljava.video.SDLVideo;
import sdljava.video.SDLSurface;
 
 
 
/**
 * Paty demonstracni priklad vyuzivajici knihovnu SDLjava.
 * Po spusteni se provede prepnuti do grafickeho rezimu 800x600x16
 * Po inicializaci grafickeho rezimu se nacte bitmapa "xscorch.bmp",
 * ktera se nasledne vykresli na obrazovku operaci typu BitBLT, ovsem
 * se specifikaci presneho umisteni bitmapy na obrazovce.
 */
public class SDLTest5 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu.
     */
    private static final int GFX_WIDTH = 800;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu.
     */
    private static final int GFX_HEIGHT = 600;
 
    /**
     * Bitova hloubka vybraneho grafickeho rezimu.
     */
    private static final int GFX_BPP = 16;
 
    /**
     * Nazev bitmapy, ktera se ma nacist a nasledne zobrazit.
     */
    private static final String IMAGE_NAME = "xscorch.bmp";
 
    /**
     * Vykresleni bitmapy na obrazovku.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktery se ma na obrazovku vykreslit
     */
    private static void drawOnScreen(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);
        // nutno volat i v pripade, ze neni pouzit double buffering
        screen.updateRect();
        screen.flip();
    }
 
    /**
     * Vypocitat umisteni bitmapy na obrazovce.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktery 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 demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace video subsystemu knihovny SDL.
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
            // inicializace celoobrazovkoveho grafickeho rezimu
            final SDLSurface screen = SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, SDLVideo.SDL_FULLSCREEN);
            // nacteni bitmapy z externiho souboru
            final SDLSurface bitmap = SDLVideo.loadBMP(IMAGE_NAME);
            // vykresleni bitmapy na obrazovku
            drawOnScreen(screen, bitmap);
            Thread.sleep(5000);
        }
        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 (Linux):

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

Skript pro překlad (Windows):

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

Skript pro spuštění (Linux):

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

Skript pro spuštění (Windows):

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

9. Demonstrační příklad SDLTest6 – ořez bitmapy při provádění operace typu BitBLT

V dalším demonstračním příkladu nazvaném SDLTest6 se taktéž vykresluje bitmapa načtená z externího souboru typu BMP (Windows Bitmap), ovšem souběžně s vykreslováním této bitmapy s využitím operace BitBLT se aplikuje i ořezávání rastrového obrázku na základě údajů předaných ve výše popsané datové struktuře typu SDLRect. Aby byl efekt ořezávání lépe viditelný, není bitmapa do framebufferu vykreslena pouze jedenkrát; namísto toho je na displeji zobrazena jednoduchá animace spočívající v plynulém posunování ořezového obdélníku přes vykreslovanou („blitovanou“) bitmapu. Celkem je zobrazeno tisíc snímků animace, přičemž minimální doba jednoho snímku je nastavena na deset milisekund. Způsobem přesnějšího časování se budeme zabývat později, v dnešním jednoduchém příkladu nám však bude dostačovat použití Thread.sleep(10). Zdrojový kód demonstračního příkladu vypadá následovně:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.video.SDLRect;
import sdljava.video.SDLVideo;
import sdljava.video.SDLSurface;
 
 
 
/**
 * Sesty demonstracni priklad vyuzivajici knihovnu SDLjava.
 * Po spusteni se provede prepnuti do grafickeho rezimu 800x600x16
 * Po inicializaci grafickeho rezimu se nacte bitmapa "xscorch.bmp".
 * Nasledne se provede demonstrace moznosti metody
 * blitSurface(SDLRect src, SDLSurface dstSurface, SDLRect dst)
 */
public class SDLTest6 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu.
     */
    private static final int GFX_WIDTH = 800;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu.
     */
    private static final int GFX_HEIGHT = 600;
 
    /**
     * Bitova hloubka vybraneho grafickeho rezimu.
     */
    private static final int GFX_BPP = 16;
 
    /**
     * Nazev bitmapy, ktera se ma nacist a nasledne zobrazit.
     */
    private static final String IMAGE_NAME = "xscorch.bmp";
 
    /**
     * Rozmery obdelniku pouziteho pri animaci.
     */
    private static final int SOURCE_RECTANGLE_SIZE = 100;
 
    /**
     * Vykresleni jednoduche animace na obrazovku.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktery se ma na obrazovku vykreslit
     * @throws InterruptedException
     */
    private static void drawOnScreen(SDLSurface screen, SDLSurface bitmap) throws SDLException, InterruptedException {
        // vypocitat umisteni bitmapy na obrazovce.
        final SDLRect dstrect = computePositionOnScreen(screen, bitmap);
        // obdelnik urcujici orezani obrazku
        SDLRect srcrect = new SDLRect(0, 0, SOURCE_RECTANGLE_SIZE, SOURCE_RECTANGLE_SIZE);
        int x = 0, y = 0;
        int dx = 1, dy = 1;
        // jednoducha animace spocivajici v plynule zmene
        // pocatecniho bodu zdrojoveho obdelniku
        for (int i = 0; i < 1000; i++) {
            x += dx;
            y += dy;
            if (x >= bitmap.getWidth() - SOURCE_RECTANGLE_SIZE) {
                dx = -dx;
            }
            if (y >= bitmap.getHeight() - SOURCE_RECTANGLE_SIZE) {
                dy = -dy;
            }
            if (x <= 0) {
                dx = -dx;
            }
            if (y <= 0) {
                dy = -dy;
            }
            // vypocitat pocatecni bod zdrojoveho obdelniku
            srcrect.x = x;
            srcrect.y = y;
            // provest operaci typu BitBLT
            bitmap.blitSurface(srcrect, screen, dstrect);
            // nutno volat i v pripade, ze neni pouzit double buffering
            screen.updateRect();
            screen.flip();
            Thread.sleep(10);
        }
    }
 
    /**
     * Vypocitat umisteni bitmapy na obrazovce.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktery 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 demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace video subsystemu knihovny SDL.
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
            // inicializace celoobrazovkoveho grafickeho rezimu
            final SDLSurface screen = SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, SDLVideo.SDL_FULLSCREEN);
            // nacteni bitmapy z externiho souboru
            final SDLSurface bitmap = SDLVideo.loadBMP(IMAGE_NAME);
            // vykresleni bitmapy na obrazovku
            drawOnScreen(screen, bitmap);
            Thread.sleep(1000);
        }
        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 (Linux):

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

Skript pro překlad (Windows):

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

Skript pro spuštění (Linux):

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

Skript pro spuštění (Windows):

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

10. Demonstrační příklad SDLTest7 – načtení bitmapy uložené ve formátu PNG

V dnešním posledním demonstračním příkladu pojmenovaném SDLTest7 si ukážeme jeden z možných způsobů načtení bitmapy uložené ve formátu odlišném od poměrně primitivního a neúsporného formátu Microsoft Bitmap. Zde již není možné využít metodu sdljava.video.SDLVideo.loadBMP(), ale je nutné zavolat mnohem obecnější metodu sdljava.image.SDLImage.load(), která volá nativní funkce z libSDLJava_image.so popř. SDLJava_image.dll (ve skutečnosti jsou tyto nativní metody jen mezivrstvou ke knihovně libSDL_image.so/SDL_image.so). Důležité je, že je podporován například formát PNG, což je velmi užitečné, protože kromě (poměrně dobré) bezztrátové komprimace podporuje tento formát i různé metody uložení průhlednosti pixelů, takže do PNG je možné ukládat například sprity. S touto v oblasti 2D grafiky známou a již velmi dlouho využívanou technikou se seznámíme v následující části tohoto seriálu. Nyní se již podívejme na zdrojový kód demonstračního příkladu:

import sdljava.SDLMain;
import sdljava.SDLException;
import sdljava.video.SDLVideo;
import sdljava.video.SDLSurface;
import sdljava.image.SDLImage;
 
 
 
/**
 * Sedmy demonstracni priklad vyuzivajici knihovnu SDLjava.
 * Po spusteni se provede prepnuti do grafickeho rezimu 800x600x16
 * Po inicializaci grafickeho rezimu se nacte bitmapa "xscorch.png",
 * ktera se nasledne vykresli na obrazovku operaci typu BitBLT.
*/
public class SDLTest7 {
 
    /**
     * Horizontalni rozliseni vybraneho grafickeho rezimu.
     */
    private static final int GFX_WIDTH = 800;
 
    /**
     * Vertikalni rozliseni vybraneho grafickeho rezimu.
     */
    private static final int GFX_HEIGHT = 600;
 
    /**
     * Bitova hloubka vybraneho grafickeho rezimu.
     */
    private static final int GFX_BPP = 16;
 
    /**
     * Nazev bitmapy, ktera se ma nacist a nasledne zobrazit.
     */
    private static final String IMAGE_NAME = "xscorch.png";
 
    /**
     * Vykresleni bitmapy na obrazovku.
     * 
     * @param screen
     *            framebuffer
     * @param bitmap
     *            bitmapa, ktery se ma na obrazovku vykreslit
     */
    private static void drawOnScreen(SDLSurface screen, SDLSurface bitmap) throws SDLException {
        // provest operaci typu BitBLT
        bitmap.blitSurface(screen);
        // nutno volat i v pripade, ze neni pouzit double buffering
        screen.updateRect();
        screen.flip();
    }
 
    /**
     * Spusteni demonstracniho prikladu.
     */
    public static void main(String[] args) {
        try {
            // inicializace video subsystemu knihovny SDL.
            SDLMain.init(SDLMain.SDL_INIT_VIDEO);
            // inicializace celoobrazovkoveho grafickeho rezimu
            final SDLSurface screen = SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, SDLVideo.SDL_FULLSCREEN);
            // nacteni bitmapy z externiho souboru
            final SDLSurface bitmap = SDLImage.load(IMAGE_NAME);
            // vykresleni bitmapy na obrazovku
            drawOnScreen(screen, bitmap);
            Thread.sleep(5000);
        }
        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 (Linux):

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

Skript pro překlad (Windows):

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

Skript pro spuštění (Linux):

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

Skript pro spuštění (Windows):

root_podpora

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

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

Všechny čtyři dnešní demonstrační příklady byly společně s podpůrnými skripty určenými pro jejich překlad a následné spuštění uloženy do Mercurial repositáře dostupného na adrese http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/. Podobně jako tomu bylo i v předchozím dí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 SDLTest4.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest4/SDLTest4.java 
2 SDLTest4_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest4/SDLTest4_compi­le.sh 
3 SDLTest4_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest4/SDLTest4_compi­le_sys.sh
4 SDLTest4_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest4/SDLTest4_run.sh 
5 SDLTest4_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest4/SDLTest4_run_sys­.sh 
6 SDLTest4_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest4/SDLTest4_compi­le.bat 
7 SDLTest4_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest4/SDLTest4_run.bat 
     
8 SDLTest5.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest5/SDLTest5.java 
9 SDLTest5_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest5/SDLTest5_compi­le.sh 
10 SDLTest5_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest5/SDLTest5_compi­le_sys.sh
11 SDLTest5_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest5/SDLTest5_run.sh 
12 SDLTest5_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest5/SDLTest5_run_sys­.sh 
13 SDLTest5_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest5/SDLTest5_compi­le.bat 
14 SDLTest5_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest5/SDLTest5_run.bat 
     
15 SDLTest6.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest6/SDLTest6.java 
16 SDLTest6_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest6/SDLTest6_compi­le.sh 
17 SDLTest6_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest6/SDLTest6_compi­le_sys.sh
18 SDLTest6_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest6/SDLTest6_run.sh 
19 SDLTest6_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest6/SDLTest6_run_sys­.sh 
20 SDLTest6_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest6/SDLTest6_compi­le.bat 
21 SDLTest6_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest6/SDLTest6_run.bat 
     
22 SDLTest7.java http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest7/SDLTest7.java 
23 SDLTest7_compile.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest7/SDLTest7_compi­le.sh 
24 SDLTest7_compile_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest7/SDLTest7_compi­le_sys.sh
25 SDLTest7_run.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest7/SDLTest7_run.sh 
26 SDLTest7_run_sys.sh http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest7/SDLTest7_run_sys­.sh 
27 SDLTest7_compile.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest7/SDLTest7_compi­le.bat 
28 SDLTest7_run.bat http://icedtea.classpath.or­g/people/ptisnovs/jvm-tools/file/6fe0d3a6edeb/sdlja­va/SDLTest7/SDLTest7_run.bat 
     

Pro správnou činnost demonstračních příkladů je nutné mít v pracovním adresáři uloženu i dvojici obrázků xscorch.bmpxscorch.png:

12. Odkazy na Internetu

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

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