Obsah
1. Pohled pod kapotu JVM – zpracování událostí v knihovně SDLJava (klávesnice a myš)
2. Nejdůležitější metody třídy sdljava.event.SDLEvent
3. Čtení informací o stisknutých klávesách: sdljava.event.SDLKeyboardEvent
4. Symbolická jména jednotlivých kláves
5. Demonstrační příklad SDLTest31: čtení stavu klávesnice a výpis názvu jednotlivých kláves
6. Stav modifikátorů: Shift, Alt, Ctrl apod.
7. Demonstrační příklad SDLTest32: čtení stavu klávesnice včetně základních modifikátorů
8. Čtení informací o stavu tlačítek myši
9. Demonstrační příklad SDLTest33: přečtení stavu tlačítek myši
10. Jakým způsobem lze zaregistrovat otočení kolečka myši?
11. Demonstrační příklad SDLTest34: jednoduchý výpočet otočení kolečka myši
12. Čtení absolutních i relativních souřadnic kurzoru myši
13. Demonstrační příklad SDLTest35: výpis informací o kurzoru myši
14. Repositář se zdrojovými kódy všech pěti dnešních demonstračních příkladů
1. Pohled pod kapotu JVM – zpracování událostí v knihovně SDLJava (klávesnice a myš)
V dnešní části seriálu o programovacím jazyce Java i o virtuálním stroji tohoto jazyka si na pětici demonstračních příkladů ukážeme, jakým způsobem je možné v knihovně SDLJava reagovat na stisk či puštění kláves, stisk či puštění tlačítek myši, otočení kolečka myši a popř. i na pohyb kurzoru myši v okně běžící aplikace. Popíšeme si tedy především práci se třídami sdljava.event.SDLEvent, sdljava.event.SDLKeyboardEvent, sdljava.event.SDLMouseButtonEvent a sdljava.event.SDLMouseMotionEvent i s pomocnými třídami sdljava.event.SDLMod a v neposlední řadě i sdljava.x.swig.SDLPressedState. Připomeňme si nejprve, že získání informací o klávesnici i myši se provádí postupným čtením a popř. i čekáním na vznik událostí, které jsou systémem automaticky ukládány do takzvané fronty událostí. Typická smyčka pro čtení událostí tedy může vypadat následovně:
while (true) { // precist udalost z fronty SDLEvent event = SDLEvent.waitEvent(); // vyskok ze smycky pro zpracovani udalosti pri vyskytu // udalosti typu SDLQuitEvent if (event instanceof SDLQuitEvent) { return; } // stisk ci pusteni klavesy if (event instanceof SDLKeyboardEvent) { ... } // stisk ci pusteni tlacitka mysi if (event instanceof SDLMouseButtonEvent) { ... } // pohyb kurzoru mysi if (event instanceof SDLMouseMotionEvent) { ... } // reakce na další typy událostí ...
2. Nejdůležitější metody třídy sdljava.event.SDLEvent
Základní třídou při práci s událostmi je v knihovně SDLJava třída nazvaná sdljava.event.SDLEvent, od níž jsou odvozeny všechny další třídy, jejichž objekty již reprezentují konkrétní typy událostí. První čtyři metody, o nichž jsme se zmiňovali již v předchozí části tohoto seriálu, slouží pro přečtení události z fronty událostí, popř. pro čekání na vznik další události. Všechny tyto metody jsou statické, tj. volají se stylem SDLEvent.pollEvent() atd:
# | Metoda | Význam |
---|---|---|
1 | static SDLEvent pollEvent() | přečtení události z fronty |
2 | static SDLEvent pollEvent(boolean returnEvent) | přečtení události z fronty |
3 | static SDLEvent waitEvent() | čekání na další událost a přečtení této události |
4 | static SDLEvent waitEvent(boolean returnEvent) | čekání na další událost a případné přečtení této události |
I další tři metody jsou statické. Tyto metody slouží pro nastavení způsobu práce s klávesnicí a joystickem:
# | Metoda | Význam |
---|---|---|
1 | static void enableKeyRepeat(int delay, int interval) | nastavení automatického opakování generování události při držení stisknuté klávesy |
2 | static int enableUNICODE(int mode) | povoluje výpočet Unicode hodnoty klávesy (většinou jen zbytečně zdržující :-) |
3 | static int joystickEventState(SDLEventState state) | nastavení práce s joystickem |
Využitelná je i (abstraktní) metoda getType() vracející konstantu určující typ události. V praxi se však většinou setkáme spíše s využitím operátoru instanceof pro rozlišení, jaká událost byla z fronty událostí přečtena.
3. Čtení informací o stisknutých klávesách: sdljava.event.SDLKeyboardEvent
Při stisku či naopak při puštění libovolné klávesy vznikne událost, která je zachycena v objektu typu sdljava.event.SDLKeyboardEvent. Tento objekt obsahuje hned několik metod, s jejichž pomocí lze zjistit jak kód klávesy, tak i případné modifikátory (Shift, Ctrl, Alt atd.), které byly stisknuty společně s inkriminovanou klávesou (přesněji řečeno musí být modifikátory stlačeny PŘED stiskem inkriminované klávesy a stále drženy – viz též informace uvedené v šesté kapitole). Ve třídě sdljava.event.SDLKeyboardEvent nalezneme především pětici metod vypsaných v následující tabulce:
# | Metoda | Význam |
---|---|---|
1 | int getSym() | vrátí hodnotu jednoznačně identifikující stisknutou/puštěnou klávesu |
2 | int getUnicode() | obsahuje kód stisknuté/puštěné klávesy v Unikódu (musí být nejdříve povoleno) |
3 | short getScancode() | systémově závislý kód stisknuté/puštěné klávesy |
4 | SDLPressedState getState() | tato hodnota umožňuje rozlišit, zda byla klávesa stisknuta či naopak puštěna |
5 | SDLMod getMod() | stav jednotlivých modifikátorů popsaný v šesté kapitole |
4. Symbolická jména jednotlivých kláves
Nativní knihovna SDL, nad níž je obalová knihovna SDLJava postavena, je navržena takovým způsobem, aby byla multiplatformní a aby ji dokonce bylo možné provozovat i na starších osobních počítačích a/nebo herních konzolích. Z tohoto důvodu můžeme jak v SDL tak i v SDLJava najít množství symbolických jmen kláves, přičemž zdaleka ne všechny klávesy existují i na běžné klávesnici PC. V následujících několika tabulkách jsou tato symbolická jména vypsána (v případě SDLJava je najdeme ve třídě sdljava.event.SDLKey). Povšimněte si, že SDLJava dokáže bez problémů rozeznat rozdíl mezi numerickými klávesami a numerickým blokem atd. – to je samozřejmě při programování her velmi důležité.
Numerické klávesy umístěné v hlavním alfanumerickém bloku mají přiřazeny následující symboly:
# | Symbolické jméno klávesy |
---|---|
1 | SDLK0 |
2 | SDLK1 |
3 | SDLK2 |
4 | SDLK3 |
5 | SDLK4 |
6 | SDLK5 |
7 | SDLK6 |
8 | SDLK7 |
9 | SDLK8 |
10 | SDLK9 |
V hlavním alfanumerickém bloku jsou i klávesy „a“ až „z“. Symboly pro kapitálky zde nenajdeme, protože takové klávesy vlastně na klávesnici neexistují (modifikátor Shift a zámek Caps Lock lze rozlišit jiným způsobem):
# | Symbolické jméno klávesy |
---|---|
1 | SDLK_a |
2 | SDLK_b |
3 | SDLK_c |
4 | SDLK_d |
5 | SDLK_e |
6 | SDLK_f |
7 | SDLK_g |
8 | SDLK_h |
9 | SDLK_i |
10 | SDLK_j |
11 | SDLK_k |
12 | SDLK_l |
13 | SDLK_m |
14 | SDLKn |
15 | SDLK_o |
16 | SDLK_p |
17 | SDLK_q |
18 | SDLK_r |
19 | SDLK_s |
20 | SDLK_t |
21 | SDLK_u |
22 | SDLK_v |
23 | SDLK_w |
24 | SDLK_x |
25 | SDLK_y |
26 | SDLK_z |
Následují symboly pro další klávesy umístěné většinou v hlavním alfanumerickém bloku (ne všechny klávesy však najdeme na PC):
# | Symbolické jméno klávesy |
---|---|
1 | SDLK_BACKSPACE |
2 | SDLK_DELETE |
3 | SDLK_TAB |
4 | SDLK_CLEAR |
5 | SDLK_RETURN |
6 | SDLK_PAUSE |
7 | SDLK_ESCAPE |
8 | SDLK_SPACE |
9 | SDLK_EXCLAIM |
10 | SDLK_QUOTEDBL |
11 | SDLK_HASH |
12 | SDLK_DOLLAR |
13 | SDLK_AMPERSAND |
14 | SDLK_QUOTE |
15 | SDLK_LEFTPAREN |
16 | SDLK_RIGHTPAREN |
17 | SDLK_ASTERISK |
18 | SDLK_PLUS |
19 | SDLK_COMMA |
20 | SDLK_MINUS |
21 | SDLK_PERIOD |
22 | SDLK_SLASH |
23 | SDLK_COLON |
24 | SDLK_SEMICOLON |
25 | SDLK_LESS |
26 | SDLK_EQUALS |
27 | SDLK_GREATER |
28 | SDLK_QUESTION |
29 | SDLK_AT |
30 | SDLK_LEFTBRACKET |
31 | SDLK_BACKSLASH |
32 | SDLK_RIGHTBRACKET |
33 | SDLK_CARET |
34 | SDLK_UNDERSCORE |
35 | SDLK_BACKQUOTE |
Pro sedmnáct kláves umístěných v odděleném numerickém bloku je definováno následujících sedmnáct symbolů (na mnoha klávesnicích však klávesu = nenajdeme):
# | Symbolické jméno klávesy |
---|---|
1 | SDLK_KP0 |
2 | SDLK_KP1 |
3 | SDLK_KP2 |
4 | SDLK_KP3 |
5 | SDLK_KP4 |
6 | SDLK_KP5 |
7 | SDLK_KP6 |
8 | SDLK_KP7 |
9 | SDLK_KP8 |
10 | SDLK_KP9 |
11 | SDLK_KP_PERIOD |
12 | SDLK_KP_DIVIDE |
13 | SDLK_KP_MULTIPLY |
14 | SDLK_KP_MINUS |
15 | SDLK_KP_PLUS |
16 | SDLK_KP_ENTER |
17 | SDLK_KP_EQUALS |
Samostatný blok je na běžné PC klávesnici vyhrazen pro kurzorové šipky a další podobné klávesy, jimž jsou v SDLJava přiřazeny symboly:
# | Symbolické jméno klávesy |
---|---|
1 | SDLK_UP |
2 | SDLK_DOWN |
3 | SDLK_RIGHT |
4 | SDLK_LEFT |
5 | SDLK_INSERT |
6 | SDLK_HOME |
7 | SDLK_END |
8 | SDLK_PAGEUP |
9 | SDLK_PAGEDOWN |
Symboly pro klávesy F1 až F15 (opět platí, že klávesy označené F13 až F15 budete na běžném PC pravděpodobně hledat marně :-):
# | Symbolické jméno klávesy |
---|---|
1 | SDLK_F1 |
2 | SDLK_F2 |
3 | SDLK_F3 |
4 | SDLK_F4 |
5 | SDLK_F5 |
6 | SDLK_F6 |
7 | SDLK_F7 |
9 | SDLK_F8 |
9 | SDLK_F9 |
10 | SDLK_F10 |
11 | SDLK_F11 |
12 | SDLK_F12 |
13 | SDLK_F13 |
14 | SDLK_F14 |
15 | SDLK_F15 |
Následující symboly jsou vyhrazeny pro všechny možné zámky a přeřaďovače:
# | Symbolické jméno klávesy |
---|---|
1 | SDLK_CAPSLOCK |
2 | SDLK_SCROLLOCK |
3 | SDLK_RSHIFT |
4 | SDLK_LSHIFT |
5 | SDLK_RCTRL |
6 | SDLK_LCTRL |
7 | SDLK_RALT |
8 | SDLK_LALT |
9 | SDLK_RMETA |
10 | SDLK_LMETA |
11 | SDLK_LSUPER |
12 | SDLK_RSUPER |
13 | SDLK_MODE |
14 | SDLK_COMPOSE |
Různé speciální klávesy:
# | Symbolické jméno klávesy |
---|---|
1 | SDLK_HELP |
2 | SDLK_PRINT |
3 | SDLK_SYSREQ |
4 | SDLK_BREAK |
5 | SDLK_MENU |
6 | SDLK_POWER |
7 | SDLK_EURO |
8 | SDLK_UNDO |
Pokud bude přepnut layout klávesnice, například na CZ, budou klávesy přiřazené národním znakům generovat jeden z následujících kódů, na což je zapotřebí dávat při vývoji pozor:
# | Symbolické jméno klávesy |
---|---|
1 | SDLK_WORLD0 |
2 | SDLK_WORLD1 |
3 | SDLK_WORLD2 |
4 | SDLK_WORLD3 |
5 | SDLK_WORLD4 |
6 | SDLK_WORLD5 |
7 | SDLK_WORLD6 |
8 | SDLK_WORLD7 |
9 | SDLK_WORLD8 |
10 | SDLK_WORLD9 |
11 | SDLK_WORLD10 |
12 | SDLK_WORLD11 |
13 | SDLK_WORLD12 |
14 | SDLK_WORLD13 |
15 | SDLK_WORLD14 |
16 | SDLK_WORLD15 |
17 | SDLK_WORLD16 |
18 | SDLK_WORLD17 |
19 | SDLK_WORLD18 |
20 | SDLK_WORLD19 |
21 | SDLK_WORLD20 |
22 | SDLK_WORLD21 |
23 | SDLK_WORLD22 |
24 | SDLK_WORLD23 |
25 | SDLK_WORLD24 |
26 | SDLK_WORLD25 |
27 | SDLK_WORLD26 |
28 | SDLK_WORLD27 |
29 | SDLK_WORLD28 |
30 | SDLK_WORLD29 |
31 | SDLK_WORLD30 |
32 | SDLK_WORLD31 |
33 | SDLK_WORLD32 |
34 | SDLK_WORLD33 |
35 | SDLK_WORLD34 |
36 | SDLK_WORLD35 |
37 | SDLK_WORLD36 |
38 | SDLK_WORLD37 |
39 | SDLK_WORLD38 |
40 | SDLK_WORLD39 |
41 | SDLK_WORLD40 |
42 | SDLK_WORLD41 |
43 | SDLK_WORLD42 |
44 | SDLK_WORLD43 |
45 | SDLK_WORLD44 |
46 | SDLK_WORLD45 |
47 | SDLK_WORLD46 |
48 | SDLK_WORLD47 |
49 | SDLK_WORLD48 |
50 | SDLK_WORLD49 |
51 | SDLK_WORLD50 |
52 | SDLK_WORLD51 |
53 | SDLK_WORLD52 |
54 | SDLK_WORLD53 |
55 | SDLK_WORLD54 |
56 | SDLK_WORLD55 |
57 | SDLK_WORLD56 |
58 | SDLK_WORLD57 |
59 | SDLK_WORLD58 |
60 | SDLK_WORLD59 |
61 | SDLK_WORLD60 |
62 | SDLK_WORLD61 |
63 | SDLK_WORLD62 |
64 | SDLK_WORLD63 |
65 | SDLK_WORLD64 |
66 | SDLK_WORLD65 |
67 | SDLK_WORLD66 |
68 | SDLK_WORLD67 |
69 | SDLK_WORLD68 |
70 | SDLK_WORLD69 |
71 | SDLK_WORLD70 |
72 | SDLK_WORLD71 |
73 | SDLK_WORLD72 |
74 | SDLK_WORLD73 |
75 | SDLK_WORLD74 |
76 | SDLK_WORLD75 |
77 | SDLK_WORLD76 |
78 | SDLK_WORLD77 |
79 | SDLK_WORLD78 |
80 | SDLK_WORLD79 |
81 | SDLK_WORLD80 |
82 | SDLK_WORLD81 |
83 | SDLK_WORLD82 |
84 | SDLK_WORLD83 |
85 | SDLK_WORLD84 |
86 | SDLK_WORLD85 |
87 | SDLK_WORLD86 |
88 | SDLK_WORLD87 |
89 | SDLK_WORLD88 |
90 | SDLK_WORLD89 |
91 | SDLK_WORLD90 |
92 | SDLK_WORLD91 |
93 | SDLK_WORLD92 |
94 | SDLK_WORLD93 |
95 | SDLK_WORLD94 |
96 | SDLK_WORLD95 |
5. Demonstrační příklad SDLTest31: čtení stavu klávesnice a výpis názvu jednotlivých kláves
V dnešním prvním demonstračním příkladu nazvaném SDLTest31 je ukázán princip čtení základních informací o stlačených i puštěných klávesách. Ve chvíli, kdy je zjištěno, že je ve frontě událostí uložena událost typu SDLKeyboardEvent, lze provést přetypování na tento typ události a následně použít metodu SDLKeyboardEvent.getSym() pro přečtení symbolu klávesy, metodu SDLKeyboardEvent.getState() pro zjištění, zda byla klávesa stlačena či naopak puštěna a konečně je možné s využitím metody SDLEvent.getKeyName(symbol) převést kód klávesy na její jméno reprezentované řetězcem. Naznačený postup je implementován v následujících čtyřech programových řádcích:
final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event; // symbol/kod klavesy final int symbol = keyEvent.getSym(); // stav klavesy: stisknuta/pustena final String state = keyEvent.getState() == SDLPressedState.PRESSED ? "pressed" : "release"; // jmeno klavesy v citelne podobe final String keyname = SDLEvent.getKeyName(symbol);
Následuje výpis celého zdrojového kódu demonstračního příkladu SDLTest31:
import sdljava.SDLMain; import sdljava.SDLException; import sdljava.event.SDLEvent; import sdljava.event.SDLKeyboardEvent; import sdljava.event.SDLKey; import sdljava.event.SDLQuitEvent; import sdljava.video.SDLVideo; import sdljava.x.swig.SDLPressedState; /** * Tricaty prvni demonstracni priklad vyuzivajici knihovnu SDLjava. * * Cteni stavu klavesnice a vypis nazvu jednotlivych klaves. * * @author Pavel Tisnovsky */ public class SDLTest31 { /** * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna. */ private static final int GFX_WIDTH = 320; /** * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna. */ private static final int GFX_HEIGHT = 240; /** * Bitova hloubka vybraneho grafickeho rezimu. * (0 znamena automaticky vyber, ovsem lze samozrejme pouzit * i hodnoty 8, 16, 24 ci 32, podle vlastnosti graficke karty) */ private static final int GFX_BPP = 0; /** * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani. */ private static void initVideo() throws SDLException { final long flags = SDLVideo.SDL_DOUBLEBUF; SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags); } /** * Smycka pro zpracovani udalosti. */ private static void eventLoop() throws SDLException { while (true) { // precist udalost z fronty SDLEvent event = SDLEvent.waitEvent(); // vyskok ze smycky pro zpracovani udalosti pri vyskytu // udalosti typu SDLQuitEvent if (event instanceof SDLQuitEvent) { return; } // stisk ci pusteni klavesy if (event instanceof SDLKeyboardEvent) { final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event; // symbol/kod klavesy final int symbol = keyEvent.getSym(); // stav klavesy: stisknuta/pustena final String state = keyEvent.getState() == SDLPressedState.PRESSED ? "pressed" : "release"; // jmeno klavesy v citelne podobe final String keyname = SDLEvent.getKeyName(symbol); // vypis ziskanych informaci System.out.format("Keyboard event: symbol=%3d keyname=%-15s state=%s\n", symbol, keyname, state); // ESC ukonci program if (symbol == SDLKey.SDLK_ESCAPE && keyEvent.getState() == SDLPressedState.PRESSED) { return; } } } } /** * Spusteni demonstracniho prikladu. */ public static void main(String[] args) { try { // inicializace knihovny SDLJava SDLMain.init(SDLMain.SDL_INIT_VIDEO); // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani initVideo(); // smycka pro zpracovani udalosti eventLoop(); } catch (Exception e) { e.printStackTrace(); } finally { // musime obnovit puvodni graficky rezim // i v tom pripade, ze nastane nejaka vyjimka SDLMain.quit(); } // zobrazit ziskane informace } }
Skript pro překlad na Linuxu:
#!/bin/sh SDL_JAVA_LIBS=./sdljava-0.9.1/lib javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest31.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 SDLTest31.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 SDLTest31
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% SDLTest31
6. Stav modifikátorů: Shift, Alt, Ctrl apod.
V mnoha aplikacích je nutné kromě informace o stlačené či naopak puštěné klávese přečíst i stav modifikátorů, tj. kláves typu Shift, Ctrl a Alt (popř. Meta). Pro mnohé typy her je navíc nutné rozlišit například levý Shift od pravého Shiftu apod. (příkladem jsou některé varianty Pinballu využívající právě tyto klávesy pro ovládání pálek). Stav modifikátorů je uložen v objektu typu sdljava.event.SDLMod, který lze získat z události typu SDLKeyboardEvent s využitím metody SDLKeyboardEvent.getMod(). Ve třídě SDLMod nalezneme následující metody vracející pravdivostní hodnotu true/false v závislosti na okamžitém stavu vybraného modifikátoru; s tím, že například SDLMod.shift() nerozlišuje, zda byla stlačena první, druhá či dokonce obě klávesy Shift:
# | Metoda | Význam |
---|---|---|
1 | boolean alt() | stav libovolného modifikátoru Alt (většinou jen levý) |
2 | boolean caps() | stav zámku CapsLock |
3 | boolean ctrl() | stav modifikátoru Ctrl (oba) |
4 | boolean leftAlt() | stav levého modifikátoru Alt |
5 | boolean leftCtrl() | stav levého modifikátoru Ctrl |
6 | boolean leftMeta() | stav levého modifikátoru Meta (Sun keyboard?) |
7 | boolean leftShift() | stav levého modifikátoru Shift |
8 | boolean meta() | stav modifikátoru Meta |
9 | boolean num() | stav zámku NumberLock |
10 | boolean rightAlt() | stav pravého modifikátoru Alt |
11 | boolean rightCtrl() | stav pravého modifikátoru Ctrl |
12 | boolean rightMeta() | stav pravého modifikátoru Meta |
13 | boolean rightShift() | stav pravého modifikátoru Shift |
14 | boolean shift() | stav libovolného modifikátoru Shift |
7. Demonstrační příklad SDLTest32: čtení stavu klávesnice včetně základních modifikátorů
Dnešní druhý demonstrační příklad se jmenuje SDLTest32 a je v něm ukázáno, jakým způsobem je možné přečíst základní modifikátory, tj. stav stisku či puštění kláves Shift, Ctrl a Alt. Postup je velmi jednoduchý – ve chvíli, kdy se ve frontě událostí nachází událost typu SDLKeyboardEvent, provedeme přetypování na tento typ události, stejně jako v předchozím demonstračním příkladu a následně se s využitím metody SDLKeyboardEvent.getMod() získá objekt reprezentující stav všech modifikátorů. Tento objekt nabízí mj. i metody SDLMod.shift(), SDLMod.ctrl() a SDLMod.alt() popsané v předchozí kapitole:
final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event; // symbol/kod klavesy final int symbol = keyEvent.getSym(); // stav modifikatoru final SDLMod modifiers = keyEvent.getMod(); // ziskani hodnoty zakladnich preradovacu final boolean shift = modifiers.shift(); final boolean ctrl = modifiers.ctrl(); final boolean alt = modifiers.alt();
Opět následuje výpis celého zdrojového kódu demonstračního příkladu SDLTest32:
import sdljava.SDLMain; import sdljava.SDLException; import sdljava.event.SDLEvent; import sdljava.event.SDLKeyboardEvent; import sdljava.event.SDLKey; import sdljava.event.SDLMod; import sdljava.event.SDLQuitEvent; import sdljava.video.SDLVideo; import sdljava.x.swig.SDLPressedState; /** * Tricaty druhy demonstracni priklad vyuzivajici knihovnu SDLjava. * * Cteni stavu klavesnice, vcetne vsech modifikatoru. * * @author Pavel Tisnovsky */ public class SDLTest32 { /** * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna. */ private static final int GFX_WIDTH = 320; /** * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna. */ private static final int GFX_HEIGHT = 240; /** * Bitova hloubka vybraneho grafickeho rezimu. * (0 znamena automaticky vyber, ovsem lze samozrejme pouzit * i hodnoty 8, 16, 24 ci 32, podle vlastnosti graficke karty) */ private static final int GFX_BPP = 0; /** * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani. */ private static void initVideo() throws SDLException { final long flags = SDLVideo.SDL_DOUBLEBUF; SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags); } /** * Smycka pro zpracovani udalosti. */ private static void eventLoop() throws SDLException { while (true) { // precist udalost z fronty SDLEvent event = SDLEvent.waitEvent(); // vyskok ze smycky pro zpracovani udalosti pri vyskytu // udalosti typu SDLQuitEvent if (event instanceof SDLQuitEvent) { return; } // stisk ci pusteni klavesy if (event instanceof SDLKeyboardEvent) { final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event; // symbol/kod klavesy final int symbol = keyEvent.getSym(); // stav modifikatoru final SDLMod modifiers = keyEvent.getMod(); // ziskani hodnoty zakladnich preradovacu final boolean shift = modifiers.shift(); final boolean ctrl = modifiers.ctrl(); final boolean alt = modifiers.alt(); // vypis ziskanych informaci System.out.format("Keyboard event: symbol=%3d shift=%b ctrl=%b alt=%b\n", symbol, shift, ctrl, alt); // ESC ukonci program if (symbol == SDLKey.SDLK_ESCAPE && keyEvent.getState() == SDLPressedState.PRESSED) { return; } } } } /** * Spusteni demonstracniho prikladu. */ public static void main(String[] args) { try { // inicializace knihovny SDLJava SDLMain.init(SDLMain.SDL_INIT_VIDEO); // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani initVideo(); // smycka pro zpracovani udalosti eventLoop(); } catch (Exception e) { e.printStackTrace(); } finally { // musime obnovit puvodni graficky rezim // i v tom pripade, ze nastane nejaka vyjimka SDLMain.quit(); } // zobrazit ziskane informace } }
Skript pro překlad na Linuxu:
#!/bin/sh SDL_JAVA_LIBS=./sdljava-0.9.1/lib javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest32.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 SDLTest32.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 SDLTest32
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% SDLTest32
8. Čtení informací o stavu tlačítek myši
Informace o stavu tlačítek myši se čte prakticky stejným způsobem jako informace o stisku či naopak o puštění kláves; pouze s tím rozdílem, že knihovna SDLJava sice umožňuje rozeznat až 255 teoreticky nainstalovaných tlačítek myši, ale symbolická jména existují pouze pro levé tlačítko, pravé tlačítko a tlačítko prostřední. Při stisku či puštění některého tlačítka myši vznikne událost reprezentovaná objektem typu sdljava.event.SDLMouseButtonEvent, která mj. obsahuje i metodu SDLMouseButtonEvent.getButton() pro přečtení indexu stisknutého/puštěného tlačítka, metodu SDLMouseButtonEvent.getState pro zjištění aktuálního stavu tlačítka a taktéž dvojici metod SDLMouseButtonEvent.getX() a SDLMouseButtonEvent.getY() s jejichž pomocí lze přečíst souřadnice kurzoru myši v momentě, kdy byla událost stisku/puštění tlačítka zaregistrována.
9. Demonstrační příklad SDLTest33: přečtení stavu tlačítek myši
Nejjednodušší způsob přečtení stavu tlačítek myši je implementován v dnešním třetím demonstračním příkladu nazvaném SDLTest33. V okamžiku, kdy je z fronty událostí přečtena událost typu SDLMouseButtonEvent, provedeme přetypování na tento typ objektu a následně je možné využít metodu SDLMouseButtonEvent.getButton() pro přečtení kódu stlačeného či puštěného tlačítka myši. Přečtenou hodnotu je možné porovnat s konstantami SDLEvent.SDL_BUTTON_LEFT, SDLEvent.SDL_BUTTON_MIDDLE a SDLEvent.SDL_BUTTON_RIGHT a současně je možné s využitím metod SDLMouseButtonEvent.getX() a SDLMouseButtonEvent.getY() získat souřadnice kurzoru myši v okamžiku, kdy byla událost zaregistrována:
// pretypovani final SDLMouseButtonEvent mouseButtonEvent = (SDLMouseButtonEvent)event; // ktere tlacitko zpusobilo vznik udalosti? final int button = mouseButtonEvent.getButton(); String buttonName = "unknown"; // prevod na retezec switch (button) { case SDLEvent.SDL_BUTTON_LEFT: buttonName = "left"; break; case SDLEvent.SDL_BUTTON_MIDDLE: buttonName = "middle"; break; case SDLEvent.SDL_BUTTON_RIGHT: buttonName = "right"; break; } // stisknuto/pusteno final SDLPressedState state = mouseButtonEvent.getState(); final String buttonStateStr = state == SDLPressedState.PRESSED ? "pressed " : "released"; // souradnice kurzoru mysi ve chvili vzniku udalosti final int x = mouseButtonEvent.getX(); final int y = mouseButtonEvent.getY();
Úplný zdrojový kód demonstračního příkladu SDLTest33 je vypsán pod tímto odstavcem:
import sdljava.SDLMain; import sdljava.SDLException; import sdljava.event.SDLEvent; import sdljava.event.SDLKeyboardEvent; import sdljava.event.SDLMouseButtonEvent; import sdljava.event.SDLKey; import sdljava.event.SDLQuitEvent; import sdljava.video.SDLVideo; import sdljava.x.swig.SDLPressedState; /** * Tricaty treti demonstracni priklad vyuzivajici knihovnu SDLjava. * * Cteni stavu tlacitek mysi. * * @author Pavel Tisnovsky */ public class SDLTest33 { /** * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna. */ private static final int GFX_WIDTH = 320; /** * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna. */ private static final int GFX_HEIGHT = 240; /** * Bitova hloubka vybraneho grafickeho rezimu. * (0 znamena automaticky vyber, ovsem lze samozrejme pouzit * i hodnoty 8, 16, 24 ci 32, podle vlastnosti graficke karty) */ private static final int GFX_BPP = 0; /** * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani. */ private static void initVideo() throws SDLException { final long flags = SDLVideo.SDL_DOUBLEBUF; SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags); } /** * Smycka pro zpracovani udalosti. */ private static void eventLoop() throws SDLException { while (true) { // precist udalost z fronty SDLEvent event = SDLEvent.waitEvent(); // vyskok ze smycky pro zpracovani udalosti pri vyskytu // udalosti typu SDLQuitEvent if (event instanceof SDLQuitEvent) { return; } // stisk ci pusteni tlacitka mysi if (event instanceof SDLMouseButtonEvent) { // pretypovani final SDLMouseButtonEvent mouseButtonEvent = (SDLMouseButtonEvent)event; // ktere tlacitko zpusobilo vznik udalosti? final int button = mouseButtonEvent.getButton(); String buttonName = "unknown"; // prevod na retezec switch (button) { case SDLEvent.SDL_BUTTON_LEFT: buttonName = "left"; break; case SDLEvent.SDL_BUTTON_MIDDLE: buttonName = "middle"; break; case SDLEvent.SDL_BUTTON_RIGHT: buttonName = "right"; break; } // stisknuto/pusteno final SDLPressedState state = mouseButtonEvent.getState(); final String buttonStateStr = state == SDLPressedState.PRESSED ? "pressed " : "released"; // souradnice kurzoru mysi ve chvili vzniku udalosti final int x = mouseButtonEvent.getX(); final int y = mouseButtonEvent.getY(); // vypis informaci o udalosti System.out.format("Button %s %s at coordinates (%d, %s)\n", buttonName, buttonStateStr, x, y); } // stisk ci pusteni klavesy if (event instanceof SDLKeyboardEvent) { // pretypovani final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event; // symbol/kod klavesy final int symbol = keyEvent.getSym(); // ESC ukonci program if (symbol == SDLKey.SDLK_ESCAPE && keyEvent.getState() == SDLPressedState.PRESSED) { return; } } } } /** * Spusteni demonstracniho prikladu. */ public static void main(String[] args) { try { // inicializace knihovny SDLJava SDLMain.init(SDLMain.SDL_INIT_VIDEO); // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani initVideo(); // smycka pro zpracovani udalosti eventLoop(); } catch (Exception e) { e.printStackTrace(); } finally { // musime obnovit puvodni graficky rezim // i v tom pripade, ze nastane nejaka vyjimka SDLMain.quit(); } // zobrazit ziskane informace } }
Skript pro překlad na Linuxu:
#!/bin/sh SDL_JAVA_LIBS=./sdljava-0.9.1/lib javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest33.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 SDLTest33.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 SDLTest33
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% SDLTest33
10. Jakým způsobem lze zaregistrovat otočení kolečka myši?
V mnoha aplikacích a samozřejmě i v počítačových hrách je nutné nějakým způsobem pracovat i s kolečkem myši. Knihovna SDLJava nám sice neumožňuje přímo získat informaci o (relativním) natočení kolečka myši, ale namísto toho nabízí jednodušší, ale stále ještě dostatečnou podporu – otáčení kolečka je detekováno jako „stisk“ virtuálního čtvrtého a pátého tlačítka myši, což znamená, že se stále používá metoda SDLMouseButtonEvent.getButton(), jejíž návratová hodnota se porovnává s konstantou SDLEvent.SDL_BUTTON_WHEELUP a SDLEvent.SDL_BUTTON_WHEELDOWN. Záleží čistě jen na programátorovi, jakým způsobem tyto informace využije; my si v navazující kapitole ukážeme využití pomocné proměnné, která bude obsahovat natočení kolečka myši počítaného nikoli ve stupních, ale v počtu příchodu událostí o pootočení kolečka nahoru popř. dolů.
11. Demonstrační příklad SDLTest34: jednoduchý výpočet otočení kolečka myši
Detekce stisku virtuálních tlačítek myši SDLEvent.SDL_BUTTON_WHEELUP a SDLEvent.SDL_BUTTON_WHEELDOWN je využita v dnešním čtvrtém demonstračním příkladu nazvaném SDLTest34. Při příchodu jedné z těchto událostí se zvýší popř. naopak sníží hodnota atributu angleOfRotation. Následuje výpis celého zdrojového kódu tohoto demonstračního příkladu:
import sdljava.SDLMain; import sdljava.SDLException; import sdljava.event.SDLEvent; import sdljava.event.SDLKeyboardEvent; import sdljava.event.SDLMouseButtonEvent; import sdljava.event.SDLKey; import sdljava.event.SDLQuitEvent; import sdljava.video.SDLVideo; import sdljava.x.swig.SDLPressedState; /** * Tricaty ctvrty demonstracni priklad vyuzivajici knihovnu SDLjava. * * Prace s koleckem mysi. * * @author Pavel Tisnovsky */ public class SDLTest34 { /** * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna. */ private static final int GFX_WIDTH = 320; /** * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna. */ private static final int GFX_HEIGHT = 240; /** * Bitova hloubka vybraneho grafickeho rezimu. * (0 znamena automaticky vyber, ovsem lze samozrejme pouzit * i hodnoty 8, 16, 24 ci 32, podle vlastnosti graficke karty) */ private static final int GFX_BPP = 0; /** * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani. */ private static void initVideo() throws SDLException { final long flags = SDLVideo.SDL_DOUBLEBUF; SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags); } /** * Rotace kolecka mysi. */ private static int angleOfRotation = 0; /** * Smycka pro zpracovani udalosti. */ private static void eventLoop() throws SDLException { while (true) { // precist udalost z fronty SDLEvent event = SDLEvent.waitEvent(); // vyskok ze smycky pro zpracovani udalosti pri vyskytu // udalosti typu SDLQuitEvent if (event instanceof SDLQuitEvent) { return; } // stisk ci pusteni tlacitka mysi if (event instanceof SDLMouseButtonEvent) { // pretypovani final SDLMouseButtonEvent mouseButtonEvent = (SDLMouseButtonEvent)event; // ktere tlacitko zpusobilo vznik udalosti? final int button = mouseButtonEvent.getButton(); // stisknuto/pusteno final SDLPressedState state = mouseButtonEvent.getState(); // pri "stisku" kolecka se zjisti smer otaceni if (state == SDLPressedState.PRESSED) { boolean rotationChanged = false; if (button == SDLEvent.SDL_BUTTON_WHEELUP) { angleOfRotation--; rotationChanged = true; } else if (button == SDLEvent.SDL_BUTTON_WHEELDOWN) { angleOfRotation++; rotationChanged = true; } // vypis informaci o rotaci kolecka mysi, ovsem pouze pri zmene if (rotationChanged) { System.out.format("Mouse wheel angle of rotation: %d\n", angleOfRotation); } } } // stisk ci pusteni klavesy if (event instanceof SDLKeyboardEvent) { // pretypovani final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event; // symbol/kod klavesy final int symbol = keyEvent.getSym(); // ESC ukonci program if (symbol == SDLKey.SDLK_ESCAPE && keyEvent.getState() == SDLPressedState.PRESSED) { return; } } } } /** * Spusteni demonstracniho prikladu. */ public static void main(String[] args) { try { // inicializace knihovny SDLJava SDLMain.init(SDLMain.SDL_INIT_VIDEO); // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani initVideo(); // smycka pro zpracovani udalosti eventLoop(); } catch (Exception e) { e.printStackTrace(); } finally { // musime obnovit puvodni graficky rezim // i v tom pripade, ze nastane nejaka vyjimka SDLMain.quit(); } // zobrazit ziskane informace } }
Skript pro překlad na Linuxu:
#!/bin/sh SDL_JAVA_LIBS=./sdljava-0.9.1/lib javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest34.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 SDLTest34.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 SDLTest34
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% SDLTest34
12. Čtení absolutních i relativních souřadnic kurzoru myši
Ve chvíli, kdy je nutné registrovat nejenom stisk tlačítek myši, ale i samotný pohyb kurzoru myši, používá se namísto události typu SDLMouseButtonEvent událost SDLMouseMotionEvent. Instance této třídy obsahují několik metod pro zjištění absolutních souřadnic kurzoru (v rámci okna aplikace!) i pro přečtení relativních souřadnic, tj. souřadnic vztažených k předchozí události typu SDLMouseMotionEvent. Reakce na pohyb kurzoru myši je ve skutečnosti velmi jednoduchá:
// pohyb kurzoru mysi if (event instanceof SDLMouseMotionEvent) { // pretypovani final SDLMouseMotionEvent mouseMotionEvent = (SDLMouseMotionEvent)event; // precist absolutni souradnice kurzoru mysi final int absX = mouseMotionEvent.getX(); final int absY = mouseMotionEvent.getY(); // precist relativni souradnice kurzoru mysi final int relX = mouseMotionEvent.getXrel(); final int relY = mouseMotionEvent.getYrel(); }
13. Demonstrační příklad SDLTest35: výpis informací o kurzoru myši
Výše ukázaná část programového kódu pro přečtení absolutních i relativních souřadnic kurzoru myši je použita v dnešním pátém a současně i posledním demonstračním příkladu SDLTest35, jenž po svém spuštění bude po každém pohybu myši vypisovat zjištěné souřadnice na standardní výstup. Kurzor se však musí pohybovat v rámci okna otevřeného aplikací:
import sdljava.SDLMain; import sdljava.SDLException; import sdljava.event.SDLEvent; import sdljava.event.SDLKeyboardEvent; import sdljava.event.SDLMouseMotionEvent; import sdljava.event.SDLKey; import sdljava.event.SDLQuitEvent; import sdljava.video.SDLVideo; import sdljava.x.swig.SDLPressedState; /** * Tricaty paty demonstracni priklad vyuzivajici knihovnu SDLjava. * * Cteni absolutni a relativni pozice kurzoru mysi. * * @author Pavel Tisnovsky */ public class SDLTest35 { /** * Horizontalni rozliseni vybraneho grafickeho rezimu ci okna. */ private static final int GFX_WIDTH = 320; /** * Vertikalni rozliseni vybraneho grafickeho rezimu ci okna. */ private static final int GFX_HEIGHT = 240; /** * Bitova hloubka vybraneho grafickeho rezimu. * (0 znamena automaticky vyber, ovsem lze samozrejme pouzit * i hodnoty 8, 16, 24 ci 32, podle vlastnosti graficke karty) */ private static final int GFX_BPP = 0; /** * Inicializace grafickeho rezimu ci otevreni okna pro vykreslovani. */ private static void initVideo() throws SDLException { final long flags = SDLVideo.SDL_DOUBLEBUF; SDLVideo.setVideoMode(GFX_WIDTH, GFX_HEIGHT, GFX_BPP, flags); } /** * Smycka pro zpracovani udalosti. */ private static void eventLoop() throws SDLException { while (true) { // precist udalost z fronty SDLEvent event = SDLEvent.waitEvent(); // vyskok ze smycky pro zpracovani udalosti pri vyskytu // udalosti typu SDLQuitEvent if (event instanceof SDLQuitEvent) { return; } // pohyb kurzoru mysi if (event instanceof SDLMouseMotionEvent) { // pretypovani final SDLMouseMotionEvent mouseMotionEvent = (SDLMouseMotionEvent)event; // precist absolutni souradnice kurzoru mysi final int absX = mouseMotionEvent.getX(); final int absY = mouseMotionEvent.getY(); // precist relativni souradnice kurzoru mysi final int relX = mouseMotionEvent.getXrel(); final int relY = mouseMotionEvent.getYrel(); // vypis ziskanych informaci System.out.format("Mouse motion: absolute (%d, %d), relative (%d, %d)\n", absX, absY, relX, relY); } // stisk ci pusteni klavesy if (event instanceof SDLKeyboardEvent) { // pretypovani final SDLKeyboardEvent keyEvent = (SDLKeyboardEvent)event; // symbol/kod klavesy final int symbol = keyEvent.getSym(); // ESC ukonci program if (symbol == SDLKey.SDLK_ESCAPE && keyEvent.getState() == SDLPressedState.PRESSED) { return; } } } } /** * Spusteni demonstracniho prikladu. */ public static void main(String[] args) { try { // inicializace knihovny SDLJava SDLMain.init(SDLMain.SDL_INIT_VIDEO); // inicializace grafickeho rezimu ci otevreni okna pro vykreslovani initVideo(); // smycka pro zpracovani udalosti eventLoop(); } catch (Exception e) { e.printStackTrace(); } finally { // musime obnovit puvodni graficky rezim // i v tom pripade, ze nastane nejaka vyjimka SDLMain.quit(); } // zobrazit ziskane informace } }
Skript pro překlad na Linuxu:
#!/bin/sh SDL_JAVA_LIBS=./sdljava-0.9.1/lib javac -cp $SDL_JAVA_LIBS/sdljava.jar SDLTest35.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 SDLTest35.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 SDLTest35
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% SDLTest35
14. 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.org/people/ptisnovs/jvm-tools/. Podobně jako tomu bylo i v předchozích sedmi dílech tohoto seriálu, i ke dnešním příkladům jsou přiloženy skripty využitelné pro jejich překlad a spuštění. Navíc byly přidány i skripty využitelné ve Windows:
15. Odkazy na Internetu
- glDrawArrays
http://www.opengl.org/sdk/docs/man4/xhtml/glDrawArrays.xml - glDrawElements
http://www.opengl.org/sdk/docs/man4/xhtml/glDrawElements.xml - glDrawArraysInstanced
http://www.opengl.org/sdk/docs/man4/xhtml/glDrawArraysInstanced.xml - glDrawElementsInstanced
http://www.opengl.org/sdk/docs/man4/xhtml/glDrawElementsInstanced.xml - Root.cz: Seriál Grafická knihovna OpenGL
http://www.root.cz/serialy/graficka-knihovna-opengl/ - 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/ - Best Practices for Working with Vertex Data
https://developer.apple.com/library/ios/documentation/3ddrawing/conceptual/opengles_programmingguide/TechniquesforWorkingwithVertexData/TechniquesforWorkingwithVertexData.html - SDL 1.2 Documentation: SDL_Surface
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlsurface.html - SDL 1.2 Documentation: SDL_PixelFormat
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlpixelformat.html - SDL 1.2 Documentation: SDL_LockSurface
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdllocksurface.html - SDL 1.2 Documentation: SDL_UnlockSurface
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlunlocksurface.html - SDL 1.2 Documentation: SDL_LoadBMP
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlloadbmp.html - SDL 1.2 Documentation: SDL_SaveBMP
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlsavebmp.html - SDL 1.2 Documentation: SDL_BlitSurface
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlblitsurface.html - SDL 1.2 Documentation: SDL_VideoInfo
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlvideoinfo.html - SDL 1.2 Documentation: SDL_GetVideoInfo
http://www.libsdl.org/release/SDL-1.2.15/docs/html/sdlgetvideoinfo.html - Class BufferStrategy
http://docs.oracle.com/javase/6/docs/api/java/awt/image/BufferStrategy.html - Class Graphics
http://docs.oracle.com/javase/1.5.0/docs/api/java/awt/Graphics.html - Double Buffering and Page Flipping
http://docs.oracle.com/javase/tutorial/extra/fullscreen/doublebuf.html - BufferStrategy and BufferCapabilities
http://docs.oracle.com/javase/tutorial/extra/fullscreen/bufferstrategy.html - Java:Tutorials:Double Buffering
http://content.gpwiki.org/index.php/Java:Tutorials:Double_Buffering - Double buffer in standard Java AWT
http://www.codeproject.com/Articles/2136/Double-buffer-in-standard-Java-AWT - Java 2D: Hardware Accelerating – Part 1 – Volatile Images
http://www.javalobby.org/forums/thread.jspa?threadID=16840&tstart=0 - Java 2D: Hardware Accelerating – Part 2 – Buffer Strategies
http://www.javalobby.org/java/forums/t16867.html - How does paintComponent work?
http://stackoverflow.com/questions/15544549/how-does-paintcomponent-work - A Swing Architecture Overview
http://www.oracle.com/technetwork/java/architecture-142923.html - Class javax.swing.JComponent
http://docs.oracle.com/javase/6/docs/api/javax/swing/JComponent.html - Class java.awt.Component
http://docs.oracle.com/javase/6/docs/api/java/awt/Component.html - Class java.awt.Component.BltBufferStrategy
http://docs.oracle.com/javase/6/docs/api/java/awt/Component.BltBufferStrategy.html - Class java.awt.Component.FlipBufferStrategy
http://docs.oracle.com/javase/6/docs/api/java/awt/Component.FlipBufferStrategy.html - Metoda java.awt.Component.isDoubleBuffered()
http://docs.oracle.com/javase/6/docs/api/java/awt/Component.html#isDoubleBuffered() - Metoda javax.swing.JComponent.isDoubleBuffered()
http://docs.oracle.com/javase/6/docs/api/javax/swing/JComponent.html#isDoubleBuffered() - Metoda javax.swing.JComponent.setDoubleBuffered()
http://docs.oracle.com/javase/6/docs/api/javax/swing/JComponent.html#setDoubleBuffered(boolean) - Javadoc – třída GraphicsDevice
http://docs.oracle.com/javase/7/docs/api/java/awt/GraphicsDevice.html - Javadoc – třída GraphicsEnvironment
http://docs.oracle.com/javase/7/docs/api/java/awt/GraphicsEnvironment.html - Javadoc – třída GraphicsConfiguration
http://docs.oracle.com/javase/7/docs/api/java/awt/GraphicsConfiguration.html - Javadoc – třída DisplayMode
http://docs.oracle.com/javase/7/docs/api/java/awt/DisplayMode.html - Lesson: Full-Screen Exclusive Mode API
http://docs.oracle.com/javase/tutorial/extra/fullscreen/ - Full-Screen Exclusive Mode
http://docs.oracle.com/javase/tutorial/extra/fullscreen/exclusivemode.html - Display Mode
http://docs.oracle.com/javase/tutorial/extra/fullscreen/displaymode.html - Using the Full-Screen Exclusive Mode API in Java
http://www.developer.com/java/other/article.php/3609776/Using-the-Full-Screen-Exclusive-Mode-API-in-Java.htm - Java quick guide: JVM Instruction Set (tabulka všech instrukcí JVM)
http://www.mobilefish.com/tutorials/java/java_quickguide_jvm_instruction_set.html - The JVM Instruction Set
http://mpdeboer.home.xs4all.nl/scriptie/node14.html - MultiMedia eXtensions
http://softpixel.com/~cwright/programming/simd/mmx.phpi - SSE (Streaming SIMD Extentions)
http://www.songho.ca/misc/sse/sse.html - Timothy A. Chagnon: SSE and SSE2
http://www.cs.drexel.edu/~tc365/mpi-wht/sse.pdf - Intel corporation: Extending the Worldr's Most Popular Processor Architecture
http://download.intel.com/technology/architecture/new-instructions-paper.pdf - SIMD architectures:
http://arstechnica.com/old/content/2000/03/simd.ars/ - GC safe-point (or safepoint) and safe-region
http://xiao-feng.blogspot.cz/2008/01/gc-safe-point-and-safe-region.html - Safepoints in HotSpot JVM
http://blog.ragozin.info/2012/10/safepoints-in-hotspot-jvm.html - Java theory and practice: Synchronization optimizations in Mustang
http://www.ibm.com/developerworks/java/library/j-jtp10185/ - How to build hsdis
http://hg.openjdk.java.net/jdk7/hotspot/hotspot/file/tip/src/share/tools/hsdis/README - Java SE 6 Performance White Paper
http://www.oracle.com/technetwork/java/6-performance-137236.html - Lukas Stadler's Blog
http://classparser.blogspot.cz/2010/03/hsdis-i386dll.html - How to build hsdis-amd64.dll and hsdis-i386.dll on Windows
http://dropzone.nfshost.com/hsdis.htm - PrintAssembly
https://wikis.oracle.com/display/HotSpotInternals/PrintAssembly - The Java Virtual Machine Specification: 3.14. Synchronization
http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-3.html#jvms-3.14 - The Java Virtual Machine Specification: 8.3.1.4. volatile Fields
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.3.1.4 - The Java Virtual Machine Specification: 17.4. Memory Model
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4 - The Java Virtual Machine Specification: 17.7. Non-atomic Treatment of double and long
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.7 - Open Source ByteCode Libraries in Java
http://java-source.net/open-source/bytecode-libraries - ASM Home page
http://asm.ow2.org/ - Seznam nástrojů využívajících projekt ASM
http://asm.ow2.org/users.html - ObjectWeb ASM (Wikipedia)
http://en.wikipedia.org/wiki/ObjectWeb_ASM - Java Bytecode BCEL vs ASM
http://james.onegoodcookie.com/2005/10/26/java-bytecode-bcel-vs-asm/ - BCEL Home page
http://commons.apache.org/bcel/ - Byte Code Engineering Library (před verzí 5.0)
http://bcel.sourceforge.net/ - Byte Code Engineering Library (verze >= 5.0)
http://commons.apache.org/proper/commons-bcel/ - BCEL Manual
http://commons.apache.org/bcel/manual.html - Byte Code Engineering Library (Wikipedia)
http://en.wikipedia.org/wiki/BCEL - BCEL Tutorial
http://www.smfsupport.com/support/java/bcel-tutorial!/ - Bytecode Engineering
http://book.chinaunix.net/special/ebook/Core_Java2_Volume2AF/0131118269/ch13lev1sec6.html - Bytecode Outline plugin for Eclipse (screenshoty + info)
http://asm.ow2.org/eclipse/index.html - Javassist
http://www.jboss.org/javassist/ - Byteman
http://www.jboss.org/byteman - Java programming dynamics, Part 7: Bytecode engineering with BCEL
http://www.ibm.com/developerworks/java/library/j-dyn0414/ - The JavaTM Virtual Machine Specification, Second Edition
http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html - The class File Format
http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html - javap – The Java Class File Disassembler
http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/javap.html - javap-java-1.6.0-openjdk(1) – Linux man page
http://linux.die.net/man/1/javap-java-1.6.0-openjdk - Using javap
http://www.idevelopment.info/data/Programming/java/miscellaneous_java/Using_javap.html - Examine class files with the javap command
http://www.techrepublic.com/article/examine-class-files-with-the-javap-command/5815354 - aspectj (Eclipse)
http://www.eclipse.org/aspectj/ - Aspect-oriented programming (Wikipedia)
http://en.wikipedia.org/wiki/Aspect_oriented_programming - AspectJ (Wikipedia)
http://en.wikipedia.org/wiki/AspectJ - EMMA: a free Java code coverage tool
http://emma.sourceforge.net/ - Cobertura
http://cobertura.sourceforge.net/ - jclasslib bytecode viewer
http://www.ej-technologies.com/products/jclasslib/overview.html