From 4817c5765528976b92189e9e183370daecd97288 Mon Sep 17 00:00:00 2001 From: codeanticode Date: Mon, 12 Jan 2015 01:58:45 -0500 Subject: [PATCH] lwjgl renderer uses new arch --- .../src/processing/lwjgl/PGraphics2D.java | 5 + .../src/processing/lwjgl/PGraphics3D.java | 5 + .../src/processing/lwjgl/PGraphicsLWJGL.java | 7 + .../lwjgl/src/processing/lwjgl/PLWJGL.java | 530 +----------- .../src/processing/lwjgl/PSurfaceLWJGL.java | 798 ++++++++++++++++++ 5 files changed, 854 insertions(+), 491 deletions(-) create mode 100644 java/libraries/lwjgl/src/processing/lwjgl/PSurfaceLWJGL.java diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PGraphics2D.java b/java/libraries/lwjgl/src/processing/lwjgl/PGraphics2D.java index 501de2ba0..3fce79e14 100644 --- a/java/libraries/lwjgl/src/processing/lwjgl/PGraphics2D.java +++ b/java/libraries/lwjgl/src/processing/lwjgl/PGraphics2D.java @@ -1,5 +1,6 @@ package processing.lwjgl; +import processing.core.PSurface; import processing.opengl.PGL; import processing.opengl.PGraphicsOpenGL; @@ -7,4 +8,8 @@ public class PGraphics2D extends processing.opengl.PGraphics2D { protected PGL createPGL(PGraphicsOpenGL pg) { return new PLWJGL(pg); } + @Override + public PSurface createSurface() { // ignore + return new PSurfaceLWJGL(this); + } } diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PGraphics3D.java b/java/libraries/lwjgl/src/processing/lwjgl/PGraphics3D.java index 14bbc5c31..d85da6938 100644 --- a/java/libraries/lwjgl/src/processing/lwjgl/PGraphics3D.java +++ b/java/libraries/lwjgl/src/processing/lwjgl/PGraphics3D.java @@ -1,5 +1,6 @@ package processing.lwjgl; +import processing.core.PSurface; import processing.opengl.PGL; import processing.opengl.PGraphicsOpenGL; @@ -7,4 +8,8 @@ public class PGraphics3D extends processing.opengl.PGraphics3D { protected PGL createPGL(PGraphicsOpenGL pg) { return new PLWJGL(pg); } + @Override + public PSurface createSurface() { // ignore + return new PSurfaceLWJGL(this); + } } diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PGraphicsLWJGL.java b/java/libraries/lwjgl/src/processing/lwjgl/PGraphicsLWJGL.java index b34d4d2a3..60cda24ac 100644 --- a/java/libraries/lwjgl/src/processing/lwjgl/PGraphicsLWJGL.java +++ b/java/libraries/lwjgl/src/processing/lwjgl/PGraphicsLWJGL.java @@ -22,9 +22,11 @@ package processing.lwjgl; +import processing.core.PSurface; import processing.opengl.PGL; import processing.opengl.PGraphicsOpenGL; + /** * LWJGL renderer. * @@ -33,4 +35,9 @@ public class PGraphicsLWJGL extends PGraphicsOpenGL { protected PGL createPGL(PGraphicsOpenGL pg) { return new PLWJGL(pg); } + + @Override + public PSurface createSurface() { // ignore + return new PSurfaceLWJGL(this); + } } diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PLWJGL.java b/java/libraries/lwjgl/src/processing/lwjgl/PLWJGL.java index d37dd203a..4e0cc69bc 100644 --- a/java/libraries/lwjgl/src/processing/lwjgl/PLWJGL.java +++ b/java/libraries/lwjgl/src/processing/lwjgl/PLWJGL.java @@ -34,7 +34,6 @@ import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.geom.PathIterator; import java.nio.Buffer; - import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; @@ -88,14 +87,6 @@ public class PLWJGL extends PGL { /** The canvas where OpenGL rendering takes place */ public static Canvas canvas; - - // ........................................................ - - // Event handling - - /** Poller threads to get the keyboard/mouse events from LWJGL */ - protected static KeyPoller keyPoller; - protected static MousePoller mousePoller; // ........................................................ @@ -145,7 +136,7 @@ public class PLWJGL extends PGL { } } - +/* protected void initSurface(int antialias) { if (canvas != null) { keyPoller.requestStop(); @@ -219,18 +210,18 @@ public class PLWJGL extends PGL { firstFrame = true; setFps = false; } - +*/ - protected void reinitSurface() { } +// protected void reinitSurface() { } - protected void registerListeners() { - keyPoller = new KeyPoller(pg.parent); - keyPoller.start(); - - mousePoller = new MousePoller(pg.parent); - mousePoller.start(); - } +// protected void registerListeners() { +// keyPoller = new KeyPoller(pg.parent); +// keyPoller.start(); +// +// mousePoller = new MousePoller(pg.parent); +// mousePoller.start(); +// } /////////////////////////////////////////////////////////// @@ -238,30 +229,30 @@ public class PLWJGL extends PGL { // Frame rendering - protected boolean canDraw() { - return pg.initialized && pg.parent.isDisplayable(); - } +// protected boolean canDraw() { +// return pg.initialized && pg.parent.isDisplayable(); +// } +// - - protected void requestFocus() { } +// protected void requestFocus() { } - protected void requestDraw() { - if (pg.initialized) { - glThread = Thread.currentThread(); - pg.parent.handleDraw(); - Display.update(); - } - } - - - protected void swapBuffers() { - try { - Display.swapBuffers(); - } catch (LWJGLException e) { - e.printStackTrace(); - } - } +// protected void requestDraw() { +// if (pg.initialized) { +// glThread = Thread.currentThread(); +// pg.parent.handleDraw(); +// Display.update(); +// } +// } +// +// +// protected void swapBuffers() { +// try { +// Display.swapBuffers(); +// } catch (LWJGLException e) { +// e.printStackTrace(); +// } +// } @Override @@ -343,15 +334,13 @@ public class PLWJGL extends PGL { @Override protected int getFontAscent(Object font) { - FontMetrics metrics = pg.parent.getFontMetrics((Font)font); - return metrics.getAscent(); + return pg.getFontMetrics((Font) font).getAscent(); } @Override protected int getFontDescent(Object font) { - FontMetrics metrics = pg.parent.getFontMetrics((Font)font); - return metrics.getDescent(); + return pg.getFontMetrics((Font) font).getDescent(); } @@ -359,455 +348,15 @@ public class PLWJGL extends PGL { protected int getTextWidth(Object font, char buffer[], int start, int stop) { // maybe should use one of the newer/fancier functions for this? int length = stop - start; - FontMetrics metrics = pg.parent.getFontMetrics((Font)font); + FontMetrics metrics = pg.getFontMetrics((Font) font); return metrics.charsWidth(buffer, start, length); } @Override protected Object getDerivedFont(Object font, float size) { - return ((Font)font).deriveFont(size); + return ((Font) font).deriveFont(size); } - - - /////////////////////////////////////////////////////////// - - // LWJGL event handling - - - protected class KeyPoller extends Thread { - protected PApplet parent; - protected boolean stopRequested; - protected boolean[] pressedKeys; - protected char[] charCheys; - - KeyPoller(PApplet parent) { - this.parent = parent; - stopRequested = false; - } - - @Override - public void run() { - pressedKeys = new boolean[256]; - charCheys = new char[256]; - Keyboard.enableRepeatEvents(true); - while (true) { - if (stopRequested) break; - - Keyboard.poll(); - while (Keyboard.next()) { - if (stopRequested) break; - - long millis = Keyboard.getEventNanoseconds() / 1000000L; - char keyChar = Keyboard.getEventCharacter(); - int keyCode = Keyboard.getEventKey(); - - if (keyCode >= pressedKeys.length) continue; - - int modifiers = 0; - if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || - Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) { - modifiers |= Event.SHIFT; - } - if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || - Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)) { - modifiers |= Event.CTRL; - } - if (Keyboard.isKeyDown(Keyboard.KEY_LMETA) || - Keyboard.isKeyDown(Keyboard.KEY_RMETA)) { - modifiers |= Event.META; - } - if (Keyboard.isKeyDown(Keyboard.KEY_LMENU) || - Keyboard.isKeyDown(Keyboard.KEY_RMENU)) { - // LWJGL maps the menu key and the alt key to the same value. - modifiers |= Event.ALT; - } - - int keyPCode = LWJGLtoAWTCode(keyCode); - if (keyChar == 0) { - keyChar = PConstants.CODED; - } - - int action = 0; - if (Keyboard.getEventKeyState()) { - action = KeyEvent.PRESS; - KeyEvent ke = new KeyEvent(null, millis, - action, modifiers, - keyChar, keyPCode); - parent.postEvent(ke); - pressedKeys[keyCode] = true; - charCheys[keyCode] = keyChar; - keyPCode = 0; - action = KeyEvent.TYPE; - } else if (pressedKeys[keyCode]) { - keyChar = charCheys[keyCode]; - pressedKeys[keyCode] = false; - action = KeyEvent.RELEASE; - } - - KeyEvent ke = new KeyEvent(null, millis, - action, modifiers, - keyChar, keyPCode); - parent.postEvent(ke); - } - try { - Thread.sleep(10); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - - public void requestStop() { - stopRequested = true; - } - } - - - protected class MousePoller extends Thread { - protected PApplet parent; - protected boolean stopRequested; - protected boolean pressed; - protected boolean inside; - protected long startedClickTime; - protected int startedClickButton; - - MousePoller(PApplet parent) { - this.parent = parent; - stopRequested = false; - } - - @Override - public void run() { - while (true) { - if (stopRequested) break; - - Mouse.poll(); - while (Mouse.next()) { - if (stopRequested) break; - - long millis = Mouse.getEventNanoseconds() / 1000000L; - - int modifiers = 0; - if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || - Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) { - modifiers |= Event.SHIFT; - } - if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || - Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)) { - modifiers |= Event.CTRL; - } - if (Keyboard.isKeyDown(Keyboard.KEY_LMETA) || - Keyboard.isKeyDown(Keyboard.KEY_RMETA)) { - modifiers |= Event.META; - } - if (Keyboard.isKeyDown(Keyboard.KEY_LMENU) || - Keyboard.isKeyDown(Keyboard.KEY_RMENU)) { - // LWJGL maps the menu key and the alt key to the same value. - modifiers |= Event.ALT; - } - - int x = Mouse.getX(); - int y = parent.height - Mouse.getY(); - int button = 0; - if (Mouse.isButtonDown(0)) { - button = PConstants.LEFT; - } else if (Mouse.isButtonDown(1)) { - button = PConstants.RIGHT; - } else if (Mouse.isButtonDown(2)) { - button = PConstants.CENTER; - } - - int action = 0; - if (button != 0) { - if (pressed) { - action = MouseEvent.DRAG; - } else { - action = MouseEvent.PRESS; - pressed = true; - } - } else if (pressed) { - action = MouseEvent.RELEASE; - pressed = false; - } else { - action = MouseEvent.MOVE; - } - - if (inside) { - if (!Mouse.isInsideWindow()) { - inside = false; - action = MouseEvent.EXIT; - } - } else { - if (Mouse.isInsideWindow()) { - inside = true; - action = MouseEvent.ENTER; - } - } - - int count = 0; - if (Mouse.getEventButtonState()) { - startedClickTime = millis; - startedClickButton = button; - } else { - if (action == MouseEvent.RELEASE) { - boolean clickDetected = millis - startedClickTime < 500; - if (clickDetected) { - // post a RELEASE event, in addition to the CLICK event. - MouseEvent me = new MouseEvent(null, millis, action, modifiers, - x, y, button, count); - parent.postEvent(me); - action = MouseEvent.CLICK; - count = 1; - } - } - } - - MouseEvent me = new MouseEvent(null, millis, action, modifiers, - x, y, button, count); - parent.postEvent(me); - } - try { - Thread.sleep(10); - } catch (InterruptedException e) { - e.printStackTrace(); - } - } - } - - public void requestStop() { - stopRequested = true; - } - } - - // To complete later... - // http://docs.oracle.com/javase/6/docs/api/java/awt/event/KeyEvent.html - // http://processing.org/reference/keyCode.html - protected int LWJGLtoAWTCode(int code) { - switch (code) { - case Keyboard.KEY_0: - return java.awt.event.KeyEvent.VK_0; - case Keyboard.KEY_1: - return java.awt.event.KeyEvent.VK_1; - case Keyboard.KEY_2: - return java.awt.event.KeyEvent.VK_2; - case Keyboard.KEY_3: - return java.awt.event.KeyEvent.VK_3; - case Keyboard.KEY_4: - return java.awt.event.KeyEvent.VK_4; - case Keyboard.KEY_5: - return java.awt.event.KeyEvent.VK_5; - case Keyboard.KEY_6: - return java.awt.event.KeyEvent.VK_6; - case Keyboard.KEY_7: - return java.awt.event.KeyEvent.VK_7; - case Keyboard.KEY_8: - return java.awt.event.KeyEvent.VK_8; - case Keyboard.KEY_9: - return java.awt.event.KeyEvent.VK_9; - case Keyboard.KEY_A: - return java.awt.event.KeyEvent.VK_A; - case Keyboard.KEY_B: - return java.awt.event.KeyEvent.VK_B; - case Keyboard.KEY_C: - return java.awt.event.KeyEvent.VK_C; - case Keyboard.KEY_D: - return java.awt.event.KeyEvent.VK_D; - case Keyboard.KEY_E: - return java.awt.event.KeyEvent.VK_E; - case Keyboard.KEY_F: - return java.awt.event.KeyEvent.VK_F; - case Keyboard.KEY_G: - return java.awt.event.KeyEvent.VK_G; - case Keyboard.KEY_H: - return java.awt.event.KeyEvent.VK_H; - case Keyboard.KEY_I: - return java.awt.event.KeyEvent.VK_I; - case Keyboard.KEY_J: - return java.awt.event.KeyEvent.VK_J; - case Keyboard.KEY_K: - return java.awt.event.KeyEvent.VK_K; - case Keyboard.KEY_L: - return java.awt.event.KeyEvent.VK_L; - case Keyboard.KEY_M: - return java.awt.event.KeyEvent.VK_M; - case Keyboard.KEY_N: - return java.awt.event.KeyEvent.VK_N; - case Keyboard.KEY_O: - return java.awt.event.KeyEvent.VK_O; - case Keyboard.KEY_P: - return java.awt.event.KeyEvent.VK_P; - case Keyboard.KEY_Q: - return java.awt.event.KeyEvent.VK_Q; - case Keyboard.KEY_R: - return java.awt.event.KeyEvent.VK_R; - case Keyboard.KEY_S: - return java.awt.event.KeyEvent.VK_S; - case Keyboard.KEY_T: - return java.awt.event.KeyEvent.VK_T; - case Keyboard.KEY_U: - return java.awt.event.KeyEvent.VK_U; - case Keyboard.KEY_V: - return java.awt.event.KeyEvent.VK_V; - case Keyboard.KEY_W: - return java.awt.event.KeyEvent.VK_W; - case Keyboard.KEY_X: - return java.awt.event.KeyEvent.VK_X; - case Keyboard.KEY_Y: - return java.awt.event.KeyEvent.VK_Y; - case Keyboard.KEY_Z: - return java.awt.event.KeyEvent.VK_Z; - case Keyboard.KEY_ADD: - return java.awt.event.KeyEvent.VK_ADD; - case Keyboard.KEY_APOSTROPHE: - return java.awt.event.KeyEvent.VK_ASTERISK; - case Keyboard.KEY_AT: - return java.awt.event.KeyEvent.VK_AT; - case Keyboard.KEY_BACK: - return java.awt.event.KeyEvent.VK_BACK_SPACE; - case Keyboard.KEY_BACKSLASH: - return java.awt.event.KeyEvent.VK_BACK_SLASH; - case Keyboard.KEY_CAPITAL: - return java.awt.event.KeyEvent.VK_CAPS_LOCK; - case Keyboard.KEY_CIRCUMFLEX: - return java.awt.event.KeyEvent.VK_CIRCUMFLEX; - case Keyboard.KEY_COLON: - return java.awt.event.KeyEvent.VK_COLON; - case Keyboard.KEY_COMMA: - return java.awt.event.KeyEvent.VK_COMMA; - case Keyboard.KEY_CONVERT: - return java.awt.event.KeyEvent.VK_CONVERT; - case Keyboard.KEY_DECIMAL: - return java.awt.event.KeyEvent.VK_DECIMAL; - case Keyboard.KEY_DELETE: - return java.awt.event.KeyEvent.VK_DELETE; - case Keyboard.KEY_DIVIDE: - return java.awt.event.KeyEvent.VK_DIVIDE; - case Keyboard.KEY_DOWN: - return java.awt.event.KeyEvent.VK_DOWN; - case Keyboard.KEY_END: - return java.awt.event.KeyEvent.VK_END; - case Keyboard.KEY_EQUALS: - return java.awt.event.KeyEvent.VK_EQUALS; - case Keyboard.KEY_ESCAPE: - return java.awt.event.KeyEvent.VK_ESCAPE; - case Keyboard.KEY_F1: - return java.awt.event.KeyEvent.VK_F1; - case Keyboard.KEY_F10: - return java.awt.event.KeyEvent.VK_F10; - case Keyboard.KEY_F11: - return java.awt.event.KeyEvent.VK_F11; - case Keyboard.KEY_F12: - return java.awt.event.KeyEvent.VK_F12; - case Keyboard.KEY_F13: - return java.awt.event.KeyEvent.VK_F13; - case Keyboard.KEY_F14: - return java.awt.event.KeyEvent.VK_F14; - case Keyboard.KEY_F15: - return java.awt.event.KeyEvent.VK_F15; - case Keyboard.KEY_F2: - return java.awt.event.KeyEvent.VK_F2; - case Keyboard.KEY_F3: - return java.awt.event.KeyEvent.VK_F3; - case Keyboard.KEY_F4: - return java.awt.event.KeyEvent.VK_F4; - case Keyboard.KEY_F5: - return java.awt.event.KeyEvent.VK_F5; - case Keyboard.KEY_F6: - return java.awt.event.KeyEvent.VK_F6; - case Keyboard.KEY_F7: - return java.awt.event.KeyEvent.VK_F7; - case Keyboard.KEY_F8: - return java.awt.event.KeyEvent.VK_F8; - case Keyboard.KEY_F9: - return java.awt.event.KeyEvent.VK_F9; -// case Keyboard.KEY_GRAVE: - case Keyboard.KEY_HOME: - return java.awt.event.KeyEvent.VK_HOME; - case Keyboard.KEY_INSERT: - return java.awt.event.KeyEvent.VK_INSERT; - case Keyboard.KEY_LBRACKET: - return java.awt.event.KeyEvent.VK_BRACELEFT; - case Keyboard.KEY_LCONTROL: - return java.awt.event.KeyEvent.VK_CONTROL; - case Keyboard.KEY_LEFT: - return java.awt.event.KeyEvent.VK_LEFT; - case Keyboard.KEY_LMENU: - return java.awt.event.KeyEvent.VK_ALT; - case Keyboard.KEY_LMETA: - return java.awt.event.KeyEvent.VK_META; - case Keyboard.KEY_LSHIFT: - return java.awt.event.KeyEvent.VK_SHIFT; - case Keyboard.KEY_MINUS: - return java.awt.event.KeyEvent.VK_MINUS; - case Keyboard.KEY_MULTIPLY: - return java.awt.event.KeyEvent.VK_MULTIPLY; -// case Keyboard.KEY_NEXT: - case Keyboard.KEY_NUMLOCK: - return java.awt.event.KeyEvent.VK_NUM_LOCK; - case Keyboard.KEY_NUMPAD0: - return java.awt.event.KeyEvent.VK_NUMPAD0; - case Keyboard.KEY_NUMPAD1: - return java.awt.event.KeyEvent.VK_NUMPAD1; - case Keyboard.KEY_NUMPAD2: - return java.awt.event.KeyEvent.VK_NUMPAD2; - case Keyboard.KEY_NUMPAD3: - return java.awt.event.KeyEvent.VK_NUMPAD3; - case Keyboard.KEY_NUMPAD4: - return java.awt.event.KeyEvent.VK_NUMPAD4; - case Keyboard.KEY_NUMPAD5: - return java.awt.event.KeyEvent.VK_NUMPAD5; - case Keyboard.KEY_NUMPAD6: - return java.awt.event.KeyEvent.VK_NUMPAD6; - case Keyboard.KEY_NUMPAD7: - return java.awt.event.KeyEvent.VK_NUMPAD7; - case Keyboard.KEY_NUMPAD8: - return java.awt.event.KeyEvent.VK_NUMPAD8; - case Keyboard.KEY_NUMPAD9: - return java.awt.event.KeyEvent.VK_NUMPAD9; -// case Keyboard.KEY_NUMPADCOMMA: -// case Keyboard.KEY_NUMPADENTER: -// case Keyboard.KEY_NUMPADEQUALS: - case Keyboard.KEY_PAUSE: - return java.awt.event.KeyEvent.VK_PAUSE; - case Keyboard.KEY_PERIOD: - return java.awt.event.KeyEvent.VK_PERIOD; -// case Keyboard.KEY_POWER: -// case Keyboard.KEY_PRIOR: - case Keyboard.KEY_RBRACKET: - return java.awt.event.KeyEvent.VK_BRACERIGHT; - case Keyboard.KEY_RCONTROL: - return java.awt.event.KeyEvent.VK_CONTROL; - case Keyboard.KEY_RETURN: - return java.awt.event.KeyEvent.VK_ENTER; - case Keyboard.KEY_RIGHT: - return java.awt.event.KeyEvent.VK_RIGHT; -// case Keyboard.KEY_RMENU: - case Keyboard.KEY_RMETA: - return java.awt.event.KeyEvent.VK_META; - case Keyboard.KEY_RSHIFT: - return java.awt.event.KeyEvent.VK_SHIFT; -// case Keyboard.KEY_SCROLL: - case Keyboard.KEY_SEMICOLON: - return java.awt.event.KeyEvent.VK_SEMICOLON; - case Keyboard.KEY_SLASH: - return java.awt.event.KeyEvent.VK_SLASH; -// case Keyboard.KEY_SLEEP: - case Keyboard.KEY_SPACE: - return java.awt.event.KeyEvent.VK_SPACE; - case Keyboard.KEY_STOP: - return java.awt.event.KeyEvent.VK_STOP; - case Keyboard.KEY_SUBTRACT: - return java.awt.event.KeyEvent.VK_SUBTRACT; - case Keyboard.KEY_TAB: - return java.awt.event.KeyEvent.VK_TAB; -// case Keyboard.KEY_UNDERLINE: - case Keyboard.KEY_UP: - return java.awt.event.KeyEvent.VK_UP; - default: - return 0; - } - } /////////////////////////////////////////////////////////// @@ -912,18 +461,17 @@ public class PLWJGL extends PGL { protected FontOutline createFontOutline(char ch, Object font) { - return new FontOutline(ch, font); + return new FontOutline(ch, (Font) font); } protected class FontOutline implements PGL.FontOutline { PathIterator iter; - public FontOutline(char ch, Object font) { + public FontOutline(char ch, Font font) { char textArray[] = new char[] { ch }; - Graphics2D graphics = (Graphics2D) pg.parent.getGraphics(); - FontRenderContext frc = graphics.getFontRenderContext(); - GlyphVector gv = ((Font)font).createGlyphVector(frc, textArray); + FontRenderContext frc = pg.getFontRenderContext(font); + GlyphVector gv = font.createGlyphVector(frc, textArray); Shape shp = gv.getOutline(); iter = shp.getPathIterator(null); } diff --git a/java/libraries/lwjgl/src/processing/lwjgl/PSurfaceLWJGL.java b/java/libraries/lwjgl/src/processing/lwjgl/PSurfaceLWJGL.java new file mode 100644 index 000000000..67236938e --- /dev/null +++ b/java/libraries/lwjgl/src/processing/lwjgl/PSurfaceLWJGL.java @@ -0,0 +1,798 @@ +package processing.lwjgl; + +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Frame; + +import org.lwjgl.LWJGLException; +import org.lwjgl.input.Keyboard; +import org.lwjgl.input.Mouse; +import org.lwjgl.opengl.Display; +import org.lwjgl.opengl.DisplayMode; + +import processing.core.PApplet; +import processing.core.PConstants; +import processing.core.PGraphics; +import processing.core.PImage; +import processing.core.PSurface; +import processing.event.Event; +import processing.event.KeyEvent; +import processing.event.MouseEvent; +import processing.opengl.PGraphicsOpenGL; + +public class PSurfaceLWJGL implements PSurface { + PApplet sketch; + PGraphics graphics; + + int sketchWidth; + int sketchHeight; + + Frame frame; + + PLWJGL pgl; + + // ........................................................ + + // Event handling + + /** Poller threads to get the keyboard/mouse events from LWJGL */ + protected static KeyPoller keyPoller; + protected static MousePoller mousePoller; + + Thread thread; + boolean paused; + Object pauseObject = new Object(); + + /** As of release 0116, frameRate(60) is called as a default */ + protected float frameRateTarget = 60; + protected long frameRatePeriod = 1000000000L / 60L; + + PSurfaceLWJGL(PGraphics graphics) { + this.graphics = graphics; + this.pgl = (PLWJGL) ((PGraphicsOpenGL)graphics).pgl; + } + + @Override + public void initOffscreen() { + } + + @Override + public Canvas initCanvas(PApplet sketch) { + return null; + } + + @Override + public Frame initFrame(PApplet sketch, Color backgroundColor, + int deviceIndex, boolean fullScreen, boolean spanDisplays) { + this.sketch = sketch; + + sketchWidth = sketch.sketchWidth(); + sketchHeight = sketch.sketchHeight(); + try { + Display.setDisplayMode(new DisplayMode(sketchWidth, sketchHeight)); + Display.create(); + } catch (LWJGLException e) { + e.printStackTrace(); + System.exit(0); + } + + keyPoller = new KeyPoller(sketch); + keyPoller.start(); + + mousePoller = new MousePoller(sketch); + mousePoller.start(); + + frame = new DummyFrame(); + return frame; + } + + @Override + public void setTitle(String title) { + Display.setTitle(title); + + } + + @Override + public void setVisible(boolean visible) { + } + + @Override + public void setResizable(boolean resizable) { + Display.setResizable(resizable); + } + + @Override + public void placeWindow(int[] location) { + Display.setLocation(location[0], location[1]); + + } + + @Override + public void placeWindow(int[] location, int[] editorLocation) { + // TODO Auto-generated method stub + + } + + @Override + public void placePresent(Color stopColor) { + // TODO Auto-generated method stub + + } + + @Override + public void setupExternalMessages() { + // TODO Auto-generated method stub + + } + + @Override + public void startThread() { + if (thread == null) { + thread = new AnimationThread(); + thread.start(); + } else { + throw new IllegalStateException("Thread already started in PSurfaceAWT"); + } + } + + + @Override + public void pauseThread() { + PApplet.debug("PApplet.run() paused, calling object wait..."); + paused = true; + } + + // halts the animation thread if the pause flag is set + protected void checkPause() { + if (paused) { + synchronized (pauseObject) { + try { + pauseObject.wait(); +// PApplet.debug("out of wait"); + } catch (InterruptedException e) { + // waiting for this interrupt on a start() (resume) call + } + } + } +// PApplet.debug("done with pause"); + } + + + @Override + public void resumeThread() { + paused = false; + synchronized (pauseObject) { + pauseObject.notifyAll(); // wake up the animation thread + } + } + + + @Override + public boolean stopThread() { + if (thread == null) { + return false; + } + thread = null; + return true; + + } + + + @Override + public boolean isStopped() { + return thread == null; + } + + + @Override + public void setSize(int width, int height) { + // TODO Auto-generated method stub + + } + + @Override + public void setSmooth(int level) { + // TODO Auto-generated method stub + + } + + + @Override + public void setFrameRate(float fps) { + frameRateTarget = fps; + frameRatePeriod = (long) (1000000000.0 / frameRateTarget); + } + + + @Override + public void requestFocus() { + // TODO Auto-generated method stub + + } + + + @Override + public void blit() { + // TODO Auto-generated method stub + + } + + @Override + public void setCursor(int kind) { + // TODO Auto-generated method stub + + } + + @Override + public void setCursor(PImage image, int hotspotX, int hotspotY) { + // TODO Auto-generated method stub + + } + + @Override + public void showCursor() { + // TODO Auto-generated method stub + + } + + @Override + public void hideCursor() { + // TODO Auto-generated method stub + } + + class AnimationThread extends Thread { + + public AnimationThread() { + super("Animation Thread"); + } + + /** + * Main method for the primary animation thread. + * Painting in AWT and Swing + */ + @Override + public void run() { // not good to make this synchronized, locks things up + long beforeTime = System.nanoTime(); + long overSleepTime = 0L; + + int noDelays = 0; + // Number of frames with a delay of 0 ms before the + // animation thread yields to other running threads. + final int NO_DELAYS_PER_YIELD = 15; + + // If size un-initialized, might be a Canvas. Call setSize() here since + // we now have a parent object that this Canvas can use as a peer. + if (graphics.image == null) { +// System.out.format("it's null, sketchW/H already set to %d %d%n", sketchWidth, sketchHeight); + setSize(sketchWidth, sketchHeight); +// System.out.format(" but now, sketchW/H changed to %d %d%n", sketchWidth, sketchHeight); + } + + // un-pause the sketch and get rolling + sketch.start(); + + while ((Thread.currentThread() == thread) && !sketch.finished) { + checkPause(); + + // Don't resize the renderer from the EDT (i.e. from a ComponentEvent), + // otherwise it may attempt a resize mid-render. +// Dimension currentSize = canvas.getSize(); +// if (currentSize.width != sketchWidth || currentSize.height != sketchHeight) { +// System.err.format("need to resize from %s to %d, %d%n", currentSize, sketchWidth, sketchHeight); +// } + + // render a single frame +// if (g != null) { + sketch.handleDraw(); + Display.update(); +// } + + if (sketch.frameCount == 1) { + requestFocus(); + } + + // wait for update & paint to happen before drawing next frame + // this is necessary since the drawing is sometimes in a + // separate thread, meaning that the next frame will start + // before the update/paint is completed + + long afterTime = System.nanoTime(); + long timeDiff = afterTime - beforeTime; + //System.out.println("time diff is " + timeDiff); + long sleepTime = (frameRatePeriod - timeDiff) - overSleepTime; + + if (sleepTime > 0) { // some time left in this cycle + try { + Thread.sleep(sleepTime / 1000000L, (int) (sleepTime % 1000000L)); + noDelays = 0; // Got some sleep, not delaying anymore + } catch (InterruptedException ex) { } + + overSleepTime = (System.nanoTime() - afterTime) - sleepTime; + + } else { // sleepTime <= 0; the frame took longer than the period + overSleepTime = 0L; + noDelays++; + + if (noDelays > NO_DELAYS_PER_YIELD) { + Thread.yield(); // give another thread a chance to run + noDelays = 0; + } + } + + beforeTime = System.nanoTime(); + } + + sketch.dispose(); // call to shutdown libs? + Display.destroy(); + + // If the user called the exit() function, the window should close, + // rather than the sketch just halting. + // TODO: these methods need to be public... +// if (sketch.exitCalled) { +// sketch.exitActual(); +// } + } + } + + @SuppressWarnings("serial") + class DummyFrame extends Frame { + + public DummyFrame() { + super(); + } + + @Override + public void setResizable(boolean resizable) { +// super.setResizable(resizable); + } + + @Override + public void setVisible(boolean visible) { +// window.setVisible(visible); + } + + @Override + public void setTitle(String title) { +// window.setTitle(title); + } + } + + /////////////////////////////////////////////////////////// + + // LWJGL event handling + + + protected class KeyPoller extends Thread { + protected PApplet parent; + protected boolean stopRequested; + protected boolean[] pressedKeys; + protected char[] charCheys; + + KeyPoller(PApplet parent) { + this.parent = parent; + stopRequested = false; + } + + @Override + public void run() { + pressedKeys = new boolean[256]; + charCheys = new char[256]; + Keyboard.enableRepeatEvents(true); + while (true) { + if (stopRequested) break; + + Keyboard.poll(); + while (Keyboard.next()) { + if (stopRequested) break; + + long millis = Keyboard.getEventNanoseconds() / 1000000L; + char keyChar = Keyboard.getEventCharacter(); + int keyCode = Keyboard.getEventKey(); + + if (keyCode >= pressedKeys.length) continue; + + int modifiers = 0; + if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || + Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) { + modifiers |= Event.SHIFT; + } + if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || + Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)) { + modifiers |= Event.CTRL; + } + if (Keyboard.isKeyDown(Keyboard.KEY_LMETA) || + Keyboard.isKeyDown(Keyboard.KEY_RMETA)) { + modifiers |= Event.META; + } + if (Keyboard.isKeyDown(Keyboard.KEY_LMENU) || + Keyboard.isKeyDown(Keyboard.KEY_RMENU)) { + // LWJGL maps the menu key and the alt key to the same value. + modifiers |= Event.ALT; + } + + int keyPCode = LWJGLtoAWTCode(keyCode); + if (keyChar == 0) { + keyChar = PConstants.CODED; + } + + int action = 0; + if (Keyboard.getEventKeyState()) { + action = KeyEvent.PRESS; + KeyEvent ke = new KeyEvent(null, millis, + action, modifiers, + keyChar, keyPCode); + parent.postEvent(ke); + pressedKeys[keyCode] = true; + charCheys[keyCode] = keyChar; + keyPCode = 0; + action = KeyEvent.TYPE; + } else if (pressedKeys[keyCode]) { + keyChar = charCheys[keyCode]; + pressedKeys[keyCode] = false; + action = KeyEvent.RELEASE; + } + + KeyEvent ke = new KeyEvent(null, millis, + action, modifiers, + keyChar, keyPCode); + parent.postEvent(ke); + } + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public void requestStop() { + stopRequested = true; + } + } + + + protected class MousePoller extends Thread { + protected PApplet parent; + protected boolean stopRequested; + protected boolean pressed; + protected boolean inside; + protected long startedClickTime; + protected int startedClickButton; + + MousePoller(PApplet parent) { + this.parent = parent; + stopRequested = false; + } + + @Override + public void run() { + while (true) { + if (stopRequested) break; + + Mouse.poll(); + while (Mouse.next()) { + if (stopRequested) break; + + long millis = Mouse.getEventNanoseconds() / 1000000L; + + int modifiers = 0; + if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || + Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) { + modifiers |= Event.SHIFT; + } + if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || + Keyboard.isKeyDown(Keyboard.KEY_RCONTROL)) { + modifiers |= Event.CTRL; + } + if (Keyboard.isKeyDown(Keyboard.KEY_LMETA) || + Keyboard.isKeyDown(Keyboard.KEY_RMETA)) { + modifiers |= Event.META; + } + if (Keyboard.isKeyDown(Keyboard.KEY_LMENU) || + Keyboard.isKeyDown(Keyboard.KEY_RMENU)) { + // LWJGL maps the menu key and the alt key to the same value. + modifiers |= Event.ALT; + } + + int x = Mouse.getX(); + int y = parent.height - Mouse.getY(); + int button = 0; + if (Mouse.isButtonDown(0)) { + button = PConstants.LEFT; + } else if (Mouse.isButtonDown(1)) { + button = PConstants.RIGHT; + } else if (Mouse.isButtonDown(2)) { + button = PConstants.CENTER; + } + + int action = 0; + if (button != 0) { + if (pressed) { + action = MouseEvent.DRAG; + } else { + action = MouseEvent.PRESS; + pressed = true; + } + } else if (pressed) { + action = MouseEvent.RELEASE; + pressed = false; + } else { + action = MouseEvent.MOVE; + } + + if (inside) { + if (!Mouse.isInsideWindow()) { + inside = false; + action = MouseEvent.EXIT; + } + } else { + if (Mouse.isInsideWindow()) { + inside = true; + action = MouseEvent.ENTER; + } + } + + int count = 0; + if (Mouse.getEventButtonState()) { + startedClickTime = millis; + startedClickButton = button; + } else { + if (action == MouseEvent.RELEASE) { + boolean clickDetected = millis - startedClickTime < 500; + if (clickDetected) { + // post a RELEASE event, in addition to the CLICK event. + MouseEvent me = new MouseEvent(null, millis, action, modifiers, + x, y, button, count); + parent.postEvent(me); + action = MouseEvent.CLICK; + count = 1; + } + } + } + + MouseEvent me = new MouseEvent(null, millis, action, modifiers, + x, y, button, count); + parent.postEvent(me); + } + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public void requestStop() { + stopRequested = true; + } + } + + // To complete later... + // http://docs.oracle.com/javase/6/docs/api/java/awt/event/KeyEvent.html + // http://processing.org/reference/keyCode.html + protected int LWJGLtoAWTCode(int code) { + switch (code) { + case Keyboard.KEY_0: + return java.awt.event.KeyEvent.VK_0; + case Keyboard.KEY_1: + return java.awt.event.KeyEvent.VK_1; + case Keyboard.KEY_2: + return java.awt.event.KeyEvent.VK_2; + case Keyboard.KEY_3: + return java.awt.event.KeyEvent.VK_3; + case Keyboard.KEY_4: + return java.awt.event.KeyEvent.VK_4; + case Keyboard.KEY_5: + return java.awt.event.KeyEvent.VK_5; + case Keyboard.KEY_6: + return java.awt.event.KeyEvent.VK_6; + case Keyboard.KEY_7: + return java.awt.event.KeyEvent.VK_7; + case Keyboard.KEY_8: + return java.awt.event.KeyEvent.VK_8; + case Keyboard.KEY_9: + return java.awt.event.KeyEvent.VK_9; + case Keyboard.KEY_A: + return java.awt.event.KeyEvent.VK_A; + case Keyboard.KEY_B: + return java.awt.event.KeyEvent.VK_B; + case Keyboard.KEY_C: + return java.awt.event.KeyEvent.VK_C; + case Keyboard.KEY_D: + return java.awt.event.KeyEvent.VK_D; + case Keyboard.KEY_E: + return java.awt.event.KeyEvent.VK_E; + case Keyboard.KEY_F: + return java.awt.event.KeyEvent.VK_F; + case Keyboard.KEY_G: + return java.awt.event.KeyEvent.VK_G; + case Keyboard.KEY_H: + return java.awt.event.KeyEvent.VK_H; + case Keyboard.KEY_I: + return java.awt.event.KeyEvent.VK_I; + case Keyboard.KEY_J: + return java.awt.event.KeyEvent.VK_J; + case Keyboard.KEY_K: + return java.awt.event.KeyEvent.VK_K; + case Keyboard.KEY_L: + return java.awt.event.KeyEvent.VK_L; + case Keyboard.KEY_M: + return java.awt.event.KeyEvent.VK_M; + case Keyboard.KEY_N: + return java.awt.event.KeyEvent.VK_N; + case Keyboard.KEY_O: + return java.awt.event.KeyEvent.VK_O; + case Keyboard.KEY_P: + return java.awt.event.KeyEvent.VK_P; + case Keyboard.KEY_Q: + return java.awt.event.KeyEvent.VK_Q; + case Keyboard.KEY_R: + return java.awt.event.KeyEvent.VK_R; + case Keyboard.KEY_S: + return java.awt.event.KeyEvent.VK_S; + case Keyboard.KEY_T: + return java.awt.event.KeyEvent.VK_T; + case Keyboard.KEY_U: + return java.awt.event.KeyEvent.VK_U; + case Keyboard.KEY_V: + return java.awt.event.KeyEvent.VK_V; + case Keyboard.KEY_W: + return java.awt.event.KeyEvent.VK_W; + case Keyboard.KEY_X: + return java.awt.event.KeyEvent.VK_X; + case Keyboard.KEY_Y: + return java.awt.event.KeyEvent.VK_Y; + case Keyboard.KEY_Z: + return java.awt.event.KeyEvent.VK_Z; + case Keyboard.KEY_ADD: + return java.awt.event.KeyEvent.VK_ADD; + case Keyboard.KEY_APOSTROPHE: + return java.awt.event.KeyEvent.VK_ASTERISK; + case Keyboard.KEY_AT: + return java.awt.event.KeyEvent.VK_AT; + case Keyboard.KEY_BACK: + return java.awt.event.KeyEvent.VK_BACK_SPACE; + case Keyboard.KEY_BACKSLASH: + return java.awt.event.KeyEvent.VK_BACK_SLASH; + case Keyboard.KEY_CAPITAL: + return java.awt.event.KeyEvent.VK_CAPS_LOCK; + case Keyboard.KEY_CIRCUMFLEX: + return java.awt.event.KeyEvent.VK_CIRCUMFLEX; + case Keyboard.KEY_COLON: + return java.awt.event.KeyEvent.VK_COLON; + case Keyboard.KEY_COMMA: + return java.awt.event.KeyEvent.VK_COMMA; + case Keyboard.KEY_CONVERT: + return java.awt.event.KeyEvent.VK_CONVERT; + case Keyboard.KEY_DECIMAL: + return java.awt.event.KeyEvent.VK_DECIMAL; + case Keyboard.KEY_DELETE: + return java.awt.event.KeyEvent.VK_DELETE; + case Keyboard.KEY_DIVIDE: + return java.awt.event.KeyEvent.VK_DIVIDE; + case Keyboard.KEY_DOWN: + return java.awt.event.KeyEvent.VK_DOWN; + case Keyboard.KEY_END: + return java.awt.event.KeyEvent.VK_END; + case Keyboard.KEY_EQUALS: + return java.awt.event.KeyEvent.VK_EQUALS; + case Keyboard.KEY_ESCAPE: + return java.awt.event.KeyEvent.VK_ESCAPE; + case Keyboard.KEY_F1: + return java.awt.event.KeyEvent.VK_F1; + case Keyboard.KEY_F10: + return java.awt.event.KeyEvent.VK_F10; + case Keyboard.KEY_F11: + return java.awt.event.KeyEvent.VK_F11; + case Keyboard.KEY_F12: + return java.awt.event.KeyEvent.VK_F12; + case Keyboard.KEY_F13: + return java.awt.event.KeyEvent.VK_F13; + case Keyboard.KEY_F14: + return java.awt.event.KeyEvent.VK_F14; + case Keyboard.KEY_F15: + return java.awt.event.KeyEvent.VK_F15; + case Keyboard.KEY_F2: + return java.awt.event.KeyEvent.VK_F2; + case Keyboard.KEY_F3: + return java.awt.event.KeyEvent.VK_F3; + case Keyboard.KEY_F4: + return java.awt.event.KeyEvent.VK_F4; + case Keyboard.KEY_F5: + return java.awt.event.KeyEvent.VK_F5; + case Keyboard.KEY_F6: + return java.awt.event.KeyEvent.VK_F6; + case Keyboard.KEY_F7: + return java.awt.event.KeyEvent.VK_F7; + case Keyboard.KEY_F8: + return java.awt.event.KeyEvent.VK_F8; + case Keyboard.KEY_F9: + return java.awt.event.KeyEvent.VK_F9; +// case Keyboard.KEY_GRAVE: + case Keyboard.KEY_HOME: + return java.awt.event.KeyEvent.VK_HOME; + case Keyboard.KEY_INSERT: + return java.awt.event.KeyEvent.VK_INSERT; + case Keyboard.KEY_LBRACKET: + return java.awt.event.KeyEvent.VK_BRACELEFT; + case Keyboard.KEY_LCONTROL: + return java.awt.event.KeyEvent.VK_CONTROL; + case Keyboard.KEY_LEFT: + return java.awt.event.KeyEvent.VK_LEFT; + case Keyboard.KEY_LMENU: + return java.awt.event.KeyEvent.VK_ALT; + case Keyboard.KEY_LMETA: + return java.awt.event.KeyEvent.VK_META; + case Keyboard.KEY_LSHIFT: + return java.awt.event.KeyEvent.VK_SHIFT; + case Keyboard.KEY_MINUS: + return java.awt.event.KeyEvent.VK_MINUS; + case Keyboard.KEY_MULTIPLY: + return java.awt.event.KeyEvent.VK_MULTIPLY; +// case Keyboard.KEY_NEXT: + case Keyboard.KEY_NUMLOCK: + return java.awt.event.KeyEvent.VK_NUM_LOCK; + case Keyboard.KEY_NUMPAD0: + return java.awt.event.KeyEvent.VK_NUMPAD0; + case Keyboard.KEY_NUMPAD1: + return java.awt.event.KeyEvent.VK_NUMPAD1; + case Keyboard.KEY_NUMPAD2: + return java.awt.event.KeyEvent.VK_NUMPAD2; + case Keyboard.KEY_NUMPAD3: + return java.awt.event.KeyEvent.VK_NUMPAD3; + case Keyboard.KEY_NUMPAD4: + return java.awt.event.KeyEvent.VK_NUMPAD4; + case Keyboard.KEY_NUMPAD5: + return java.awt.event.KeyEvent.VK_NUMPAD5; + case Keyboard.KEY_NUMPAD6: + return java.awt.event.KeyEvent.VK_NUMPAD6; + case Keyboard.KEY_NUMPAD7: + return java.awt.event.KeyEvent.VK_NUMPAD7; + case Keyboard.KEY_NUMPAD8: + return java.awt.event.KeyEvent.VK_NUMPAD8; + case Keyboard.KEY_NUMPAD9: + return java.awt.event.KeyEvent.VK_NUMPAD9; +// case Keyboard.KEY_NUMPADCOMMA: +// case Keyboard.KEY_NUMPADENTER: +// case Keyboard.KEY_NUMPADEQUALS: + case Keyboard.KEY_PAUSE: + return java.awt.event.KeyEvent.VK_PAUSE; + case Keyboard.KEY_PERIOD: + return java.awt.event.KeyEvent.VK_PERIOD; +// case Keyboard.KEY_POWER: +// case Keyboard.KEY_PRIOR: + case Keyboard.KEY_RBRACKET: + return java.awt.event.KeyEvent.VK_BRACERIGHT; + case Keyboard.KEY_RCONTROL: + return java.awt.event.KeyEvent.VK_CONTROL; + case Keyboard.KEY_RETURN: + return java.awt.event.KeyEvent.VK_ENTER; + case Keyboard.KEY_RIGHT: + return java.awt.event.KeyEvent.VK_RIGHT; +// case Keyboard.KEY_RMENU: + case Keyboard.KEY_RMETA: + return java.awt.event.KeyEvent.VK_META; + case Keyboard.KEY_RSHIFT: + return java.awt.event.KeyEvent.VK_SHIFT; +// case Keyboard.KEY_SCROLL: + case Keyboard.KEY_SEMICOLON: + return java.awt.event.KeyEvent.VK_SEMICOLON; + case Keyboard.KEY_SLASH: + return java.awt.event.KeyEvent.VK_SLASH; +// case Keyboard.KEY_SLEEP: + case Keyboard.KEY_SPACE: + return java.awt.event.KeyEvent.VK_SPACE; + case Keyboard.KEY_STOP: + return java.awt.event.KeyEvent.VK_STOP; + case Keyboard.KEY_SUBTRACT: + return java.awt.event.KeyEvent.VK_SUBTRACT; + case Keyboard.KEY_TAB: + return java.awt.event.KeyEvent.VK_TAB; +// case Keyboard.KEY_UNDERLINE: + case Keyboard.KEY_UP: + return java.awt.event.KeyEvent.VK_UP; + default: + return 0; + } + } +}