diff --git a/core/src/processing/opengl/PGL.java b/core/src/processing/opengl/PGL.java index 00c464525..dedaeb5b6 100644 --- a/core/src/processing/opengl/PGL.java +++ b/core/src/processing/opengl/PGL.java @@ -630,7 +630,8 @@ public abstract class PGL { private boolean needFBOLayer(boolean clear0) { // TODO: need to revise this, on windows we might not want to use FBO layer // even with anti-aliasing enabled... - return !clear0 || fboLayerRequested || 1 < numSamples; +// return !clear0 || fboLayerRequested || 1 < numSamples; + return false; } diff --git a/core/src/processing/opengl/PGraphicsOpenGL.java b/core/src/processing/opengl/PGraphicsOpenGL.java index 5977ec53d..3034fd6ef 100644 --- a/core/src/processing/opengl/PGraphicsOpenGL.java +++ b/core/src/processing/opengl/PGraphicsOpenGL.java @@ -560,10 +560,10 @@ public class PGraphicsOpenGL extends PGraphics { //public void setAntiAlias(int samples) // PGraphics - @Override - public void setFrameRate(float frameRate) { - pgl.setFps(frameRate); - } +// @Override +// public void setFrameRate(float frameRate) { +// pgl.setFps(frameRate); +// } @Override @@ -686,6 +686,12 @@ public class PGraphicsOpenGL extends PGraphics { } + @Override + public PSurface createSurface() { // ignore + return new PSurfaceNEWT(this); + } + + ////////////////////////////////////////////////////////////// // IMAGE METADATA FOR THIS RENDERER @@ -1633,10 +1639,10 @@ public class PGraphicsOpenGL extends PGraphics { } - @Override - public void requestFocus() { // ignore - pgl.requestFocus(); - } +// @Override +// public void requestFocus() { +// pgl.requestFocus(); +// } /** @@ -1649,8 +1655,21 @@ public class PGraphicsOpenGL extends PGraphics { } +// @Override +// public void requestDraw() { +// if (primarySurface) { +// if (initialized) { +// if (sized) pgl.reinitSurface(); +// if (parent.canDraw()) pgl.requestDraw(); +// } else { +// initPrimary(); +// } +// } +// } + + @Override - public void requestDraw() { + public void beginDraw() { if (primarySurface) { if (initialized) { if (sized) pgl.reinitSurface(); @@ -1658,13 +1677,7 @@ public class PGraphicsOpenGL extends PGraphics { } else { initPrimary(); } - } - } - - @Override - public void beginDraw() { - if (primarySurface) { setCurrentPG(this); } else { pgl.getGL(getPrimaryPGL()); diff --git a/core/src/processing/opengl/PJOGL.java b/core/src/processing/opengl/PJOGL.java index 4845d5fdd..ec34fb876 100644 --- a/core/src/processing/opengl/PJOGL.java +++ b/core/src/processing/opengl/PJOGL.java @@ -98,6 +98,7 @@ public class PJOGL extends PGL { // OS-specific configuration + /* protected static int WINDOW_TOOLKIT; protected static int EVENTS_TOOLKIT; protected static boolean USE_JOGL_FBOLAYER; @@ -131,6 +132,10 @@ public class PJOGL extends PGL { USE_JOGL_FBOLAYER = false; } } +*/ + + protected static boolean USE_FBOLAYER_BY_DEFAULT = false; + protected static boolean USE_JOGL_FBOLAYER = false; // ........................................................ @@ -252,6 +257,7 @@ public class PJOGL extends PGL { @Override protected void initSurface(int antialias) { + /* if (profile == null) { if (PROFILE == 2) { try { @@ -382,6 +388,7 @@ public class PJOGL extends PGL { pg.parent.defaultSize = false; registerListeners(); + */ fboLayerCreated = false; fboLayerInUse = false; @@ -402,43 +409,43 @@ public class PJOGL extends PGL { @Override protected void registerListeners() { - if (WINDOW_TOOLKIT == AWT) { - pg.parent.addListeners(canvasAWT); - - listener = new PGLListener(); - canvasAWT.addGLEventListener(listener); - } else if (WINDOW_TOOLKIT == NEWT) { - if (EVENTS_TOOLKIT == NEWT) { - NEWTMouseListener mouseListener = new NEWTMouseListener(); - windowNEWT.addMouseListener(mouseListener); - NEWTKeyListener keyListener = new NEWTKeyListener(); - windowNEWT.addKeyListener(keyListener); - NEWTWindowListener winListener = new NEWTWindowListener(); - windowNEWT.addWindowListener(winListener); - } else if (EVENTS_TOOLKIT == AWT) { - pg.parent.addListeners(canvasNEWT); - } - - listener = new PGLListener(); - windowNEWT.addGLEventListener(listener); - } - - if (canvas != null) { - canvas.setFocusTraversalKeysEnabled(false); - } +// if (WINDOW_TOOLKIT == AWT) { +// pg.parent.addListeners(canvasAWT); +// +// listener = new PGLListener(); +// canvasAWT.addGLEventListener(listener); +// } else if (WINDOW_TOOLKIT == NEWT) { +// if (EVENTS_TOOLKIT == NEWT) { +// NEWTMouseListener mouseListener = new NEWTMouseListener(); +// windowNEWT.addMouseListener(mouseListener); +// NEWTKeyListener keyListener = new NEWTKeyListener(); +// windowNEWT.addKeyListener(keyListener); +// NEWTWindowListener winListener = new NEWTWindowListener(); +// windowNEWT.addWindowListener(winListener); +// } else if (EVENTS_TOOLKIT == AWT) { +// pg.parent.addListeners(canvasNEWT); +// } +// +// listener = new PGLListener(); +// windowNEWT.addGLEventListener(listener); +// } +// +// if (canvas != null) { +// canvas.setFocusTraversalKeysEnabled(false); +// } } @Override protected void deleteSurface() { - super.deleteSurface(); - - if (canvasAWT != null) { - canvasAWT.removeGLEventListener(listener); - pg.parent.removeListeners(canvasAWT); - } else if (canvasNEWT != null) { - windowNEWT.removeGLEventListener(listener); - } +// super.deleteSurface(); +// +// if (canvasAWT != null) { +// canvasAWT.removeGLEventListener(listener); +// pg.parent.removeListeners(canvasAWT); +// } else if (canvasNEWT != null) { +// windowNEWT.removeGLEventListener(listener); +// } } @@ -681,7 +688,9 @@ public class PJOGL extends PGL { @Override protected boolean canDraw() { - return pg.initialized && pg.parent.isDisplayable(); + return true; +// return pg.initialized; +// && pg.parent.isDisplayable(); } @@ -691,6 +700,7 @@ public class PJOGL extends PGL { @Override protected void requestDraw() { + /* drawException = null; boolean canDraw = pg.parent.canDraw(); if (pg.initialized && (canDraw || prevCanDraw)) { @@ -719,16 +729,17 @@ public class PJOGL extends PGL { throw new RuntimeException(drawException); } } + */ } @Override protected void swapBuffers() { - if (WINDOW_TOOLKIT == AWT) { - canvasAWT.swapBuffers(); - } else if (WINDOW_TOOLKIT == NEWT) { - windowNEWT.swapBuffers(); - } +// if (WINDOW_TOOLKIT == AWT) { +// canvasAWT.swapBuffers(); +// } else if (WINDOW_TOOLKIT == NEWT) { +// windowNEWT.swapBuffers(); +// } } @@ -801,11 +812,70 @@ public class PJOGL extends PGL { // JOGL event listeners + protected void getBuffers(GLWindow glWindow) { + if (USE_JOGL_FBOLAYER && capabilities.isFBO()) { + // The onscreen drawing surface is backed by an FBO layer. + GLFBODrawable fboDrawable = null; + fboDrawable = (GLFBODrawable)glWindow.getDelegatedDrawable(); + + if (fboDrawable != null) { + backFBO = fboDrawable.getFBObject(GL.GL_BACK); + if (1 < numSamples) { + if (needSepFrontTex) { + // When using multisampled FBO, the back buffer is the MSAA + // surface so it cannot be read from. The sink buffer contains + // the readable 2D texture. + // In this case, we create an auxiliary "front" buffer that it is + // swapped with the sink buffer at the beginning of each frame. + // In this way, we always have a readable copy of the previous + // frame in the front texture, while the back is synchronized + // with the contents of the MSAA back buffer when requested. + if (frontFBO == null) { + // init + frontFBO = new FBObject(); + frontFBO.reset(gl, pg.width, pg.height, numSamples); + frontFBO.attachTexture2D(gl, 0, true); + sinkFBO = backFBO.getSamplingSinkFBO(); + changedFrontTex = changedBackTex = true; + } else { + // swap + FBObject temp = sinkFBO; + sinkFBO = frontFBO; + frontFBO = temp; + backFBO.setSamplingSink(sinkFBO); + changedFrontTex = changedBackTex = false; + } + backTexAttach = (FBObject.TextureAttachment) sinkFBO. + getColorbuffer(0); + frontTexAttach = (FBObject.TextureAttachment)frontFBO. + getColorbuffer(0); + } else { + changedFrontTex = changedBackTex = sinkFBO == null; + + // Default setting (to save resources): the front and back + // textures are the same. + sinkFBO = backFBO.getSamplingSinkFBO(); + backTexAttach = (FBObject.TextureAttachment) sinkFBO. + getColorbuffer(0); + frontTexAttach = backTexAttach; + } + } else { + // w/out multisampling, rendering is done on the back buffer. + frontFBO = fboDrawable.getFBObject(GL.GL_FRONT); + backTexAttach = (FBObject.TextureAttachment) backFBO.getColorbuffer(0); + frontTexAttach = (FBObject.TextureAttachment) frontFBO.getColorbuffer(0); + } + } + + } + } + protected class PGLListener implements GLEventListener { public PGLListener() {} @Override public void display(GLAutoDrawable glDrawable) { + /* getGL(glDrawable); if (USE_JOGL_FBOLAYER && capabilities.isFBO()) { @@ -876,6 +946,7 @@ public class PJOGL extends PGL { drawException = ex; } drawLatch.countDown(); + */ } @Override @@ -925,6 +996,7 @@ public class PJOGL extends PGL { // } } + /* protected void nativeMouseEvent(com.jogamp.newt.event.MouseEvent nativeEvent, int peAction) { int modifiers = nativeEvent.getModifiers(); @@ -1080,7 +1152,7 @@ public class PJOGL extends PGL { nativeKeyEvent(e, KeyEvent.TYPE); } } - +*/ /////////////////////////////////////////////////////////// @@ -1119,25 +1191,25 @@ public class PJOGL extends PGL { } - @Override protected int getFontDescent(Object font) { - FontMetrics metrics = pg.parent.getFontMetrics((Font)font); - return metrics.getDescent(); +// FontMetrics metrics = pg.parent.getFontMetrics((Font)font); +// return metrics.getDescent(); + return 0; } - @Override 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); - return metrics.charsWidth(buffer, start, length); +// int length = stop - start; +// FontMetrics metrics = pg.parent.getFontMetrics((Font)font); +// return metrics.charsWidth(buffer, start, length); + return 0; } - @Override protected Object getDerivedFont(Object font, float size) { return ((Font)font).deriveFont(size); + } @@ -1315,7 +1387,9 @@ public class PJOGL extends PGL { public FontOutline(char ch, Object font) { char textArray[] = new char[] { ch }; - Graphics2D graphics = (Graphics2D) pg.parent.getGraphics(); + // ??????????????? +// Graphics2D graphics = (Graphics2D) pg.parent.getGraphics(); + Graphics2D graphics = null; FontRenderContext frc = graphics.getFontRenderContext(); GlyphVector gv = ((Font)font).createGlyphVector(frc, textArray); Shape shp = gv.getOutline(); diff --git a/core/src/processing/opengl/PSurfaceNEWT.java b/core/src/processing/opengl/PSurfaceNEWT.java new file mode 100644 index 000000000..f08515b99 --- /dev/null +++ b/core/src/processing/opengl/PSurfaceNEWT.java @@ -0,0 +1,460 @@ +package processing.opengl; + +import java.awt.Color; +import java.awt.Frame; +import java.net.URL; +import java.util.ArrayList; + +import javax.media.opengl.GLAutoDrawable; +import javax.media.opengl.GLCapabilities; +import javax.media.opengl.GLEventListener; +import javax.media.opengl.GLException; +import javax.media.opengl.GLProfile; + +import com.jogamp.newt.Display; +import com.jogamp.newt.MonitorDevice; +import com.jogamp.newt.NewtFactory; +import com.jogamp.newt.Screen; +import com.jogamp.newt.event.InputEvent; +import com.jogamp.newt.event.WindowAdapter; +import com.jogamp.newt.event.WindowEvent; +import com.jogamp.newt.opengl.GLWindow; +import com.jogamp.opengl.util.FPSAnimator; + +import processing.core.PApplet; +import processing.core.PConstants; +import processing.core.PGraphics; +import processing.core.PImage; +import processing.core.PSurface; +import processing.event.KeyEvent; +import processing.event.MouseEvent; + +public class PSurfaceNEWT implements PSurface { + /** Selected GL profile */ + public static GLProfile profile; + + PJOGL pgl; + + GLWindow window; + Frame frame; + FPSAnimator animator; + + PApplet sketch; + PGraphics graphics; + + int sketchWidth; + int sketchHeight; + + public PSurfaceNEWT(PGraphics graphics) { + this.graphics = graphics; + this.pgl = (PJOGL) ((PGraphicsOpenGL)graphics).pgl; + } + + public void initOffscreen() { + // TODO Auto-generated method stub + + } + + public Frame initFrame(PApplet sketch, Color backgroundColor, + int deviceIndex, boolean fullScreen, + boolean spanDisplays) { + this.sketch = sketch; + + Display display = NewtFactory.createDisplay(null); + display.addReference(); // trigger creation + Screen screen = NewtFactory.createScreen(display, 0); + screen.addReference(); + int screenWidth = screen.getWidth(); + int screenHeight = screen.getHeight(); + System.out.println("Screen res " + screenWidth + "x" + screenHeight); + + ArrayList monitors = new ArrayList(); + for (int i = 0; i < screen.getMonitorDevices().size(); i++) { + MonitorDevice monitor = screen.getMonitorDevices().get(i); + System.out.println("Monitor " + monitor.getId() + " ************"); + System.out.println(monitor.toString()); + System.out.println(monitor.getViewportInWindowUnits()); + System.out.println(monitor.getViewport()); + + monitors.add(monitor); + } + System.out.println("*******************************"); + + if (profile == null) { + if (PJOGL.PROFILE == 2) { + try { + profile = GLProfile.getGL2ES1(); + } catch (GLException ex) { + profile = GLProfile.getMaxFixedFunc(true); + } + } else if (PJOGL.PROFILE == 3) { + try { + profile = GLProfile.getGL2GL3(); + } catch (GLException ex) { + profile = GLProfile.getMaxProgrammable(true); + } + if (!profile.isGL3()) { + PGraphics.showWarning("Requested profile GL3 but is not available, got: " + profile); + } + } else if (PJOGL.PROFILE == 4) { + try { + profile = GLProfile.getGL4ES3(); + } catch (GLException ex) { + profile = GLProfile.getMaxProgrammable(true); + } + if (!profile.isGL4()) { + PGraphics.showWarning("Requested profile GL4 but is not available, got: " + profile); + } + } else throw new RuntimeException(PGL.UNSUPPORTED_GLPROF_ERROR); + } + + // Setting up the desired capabilities; + GLCapabilities caps = new GLCapabilities(profile); + caps.setAlphaBits(PGL.REQUESTED_ALPHA_BITS); + caps.setDepthBits(PGL.REQUESTED_DEPTH_BITS); + caps.setStencilBits(PGL.REQUESTED_STENCIL_BITS); + caps.setBackgroundOpaque(true); + caps.setOnscreen(true); + pgl.capabilities = caps; + + sketchWidth = sketch.sketchWidth(); + sketchHeight = sketch.sketchHeight(); + + window = GLWindow.create(screen, caps); + window.setPosition(0, 0); + window.setSize(sketchWidth, sketchHeight); + window.setVisible(true); + + + NEWTMouseListener mouseListener = new NEWTMouseListener(); + window.addMouseListener(mouseListener); + NEWTKeyListener keyListener = new NEWTKeyListener(); + window.addKeyListener(keyListener); +// NEWTWindowListener winListener = new NEWTWindowListener(); +// window.addWindowListener(winListener); + + DrawListener drawlistener = new DrawListener(); + window.addGLEventListener(drawlistener); + + animator = new FPSAnimator(window, 60); + + + window.addWindowListener(new WindowAdapter() { + @Override + public void windowDestroyNotify(final WindowEvent e) { + animator.stop(); + } + }); + + frame = new DummyFrame(); + return frame; + } + + class DummyFrame extends Frame { + + public DummyFrame() { + super(); +// setVisible(false); + } + + @Override + public void setResizable(boolean resizable) { + super.setResizable(resizable); + + // call NEWT function to make the window resizable + } + + @Override + public void setVisible(boolean visible) { + // don't call super.setVisible() + // make the NEWT window visible/invisible + window.setVisible(visible); + } + + @Override + public void setTitle(String title) { + window.setTitle(title); + } + } + + + public void setTitle(String title) { + window.setTitle(title); + } + + public void setVisible(boolean visible) { + window.setVisible(visible); + } + + public void setResizable(boolean resizable) { + // TODO Auto-generated method stub + + } + + public void placeWindow(int[] location) { + // TODO Auto-generated method stub + + } + + public void placeWindow(int[] location, int[] editorLocation) { + // TODO Auto-generated method stub + + } + + public void placePresent(Color stopColor) { + // TODO Auto-generated method stub + + } + + public void setupExternalMessages() { + // TODO Auto-generated method stub + + } + + public void startThread() { + animator.start(); + } + + public void pauseThread() { + animator.pause(); + } + + public void resumeThread() { + animator.resume(); + } + + public boolean stopThread() { + return animator.stop(); + } + + public boolean isStopped() { + return !animator.isAnimating(); + } + + public void setSize(int width, int height) { + // TODO Auto-generated method stub + + } + + public void setFrameRate(float fps) { + // TODO Auto-generated method stub + + } + + public void requestFocus() { + // TODO Auto-generated method stub + + } + + public void blit() { + // TODO Auto-generated method stub + + } + + + + + + class DrawListener implements GLEventListener { + public void display(GLAutoDrawable drawable) { + System.out.println("yea"); + pgl.getGL(drawable); + pgl.getBuffers(window); + sketch.handleDraw(); + if (sketch.frameCount == 1) { + requestFocus(); + } + } + public void dispose(GLAutoDrawable drawable) { + pgl.getGL(drawable); + sketch.dispose(); +// if (sketch.exitCalled) { +// sketch.exitActual(); +// } + } + public void init(GLAutoDrawable drawable) { + pgl.getGL(drawable); + sketch.start(); + } + public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) { + pgl.getGL(drawable); + + } + } + + protected class NEWTWindowListener implements com.jogamp.newt.event.WindowListener { + public NEWTWindowListener() { + super(); + } + @Override + public void windowGainedFocus(com.jogamp.newt.event.WindowEvent arg0) { +// pg.parent.focusGained(null); + } + + @Override + public void windowLostFocus(com.jogamp.newt.event.WindowEvent arg0) { +// pg.parent.focusLost(null); + } + + @Override + public void windowDestroyNotify(com.jogamp.newt.event.WindowEvent arg0) { + } + + @Override + public void windowDestroyed(com.jogamp.newt.event.WindowEvent arg0) { + } + + @Override + public void windowMoved(com.jogamp.newt.event.WindowEvent arg0) { + } + + @Override + public void windowRepaint(com.jogamp.newt.event.WindowUpdateEvent arg0) { + } + + @Override + public void windowResized(com.jogamp.newt.event.WindowEvent arg0) { } + } + + // NEWT mouse listener + protected class NEWTMouseListener extends com.jogamp.newt.event.MouseAdapter { + public NEWTMouseListener() { + super(); + } + @Override + public void mousePressed(com.jogamp.newt.event.MouseEvent e) { + nativeMouseEvent(e, MouseEvent.PRESS); + } + @Override + public void mouseReleased(com.jogamp.newt.event.MouseEvent e) { + nativeMouseEvent(e, MouseEvent.RELEASE); + } + @Override + public void mouseClicked(com.jogamp.newt.event.MouseEvent e) { + nativeMouseEvent(e, MouseEvent.CLICK); + } + @Override + public void mouseDragged(com.jogamp.newt.event.MouseEvent e) { + nativeMouseEvent(e, MouseEvent.DRAG); + } + @Override + public void mouseMoved(com.jogamp.newt.event.MouseEvent e) { + nativeMouseEvent(e, MouseEvent.MOVE); + } + @Override + public void mouseWheelMoved(com.jogamp.newt.event.MouseEvent e) { + nativeMouseEvent(e, MouseEvent.WHEEL); + } + @Override + public void mouseEntered(com.jogamp.newt.event.MouseEvent e) { + nativeMouseEvent(e, MouseEvent.ENTER); + } + @Override + public void mouseExited(com.jogamp.newt.event.MouseEvent e) { + nativeMouseEvent(e, MouseEvent.EXIT); + } + } + + // NEWT key listener + protected class NEWTKeyListener extends com.jogamp.newt.event.KeyAdapter { + public NEWTKeyListener() { + super(); + } + @Override + public void keyPressed(com.jogamp.newt.event.KeyEvent e) { + nativeKeyEvent(e, KeyEvent.PRESS); + } + @Override + public void keyReleased(com.jogamp.newt.event.KeyEvent e) { + nativeKeyEvent(e, KeyEvent.RELEASE); + } + public void keyTyped(com.jogamp.newt.event.KeyEvent e) { + nativeKeyEvent(e, KeyEvent.TYPE); + } + } + + protected void nativeMouseEvent(com.jogamp.newt.event.MouseEvent nativeEvent, + int peAction) { + int modifiers = nativeEvent.getModifiers(); + int peModifiers = modifiers & + (InputEvent.SHIFT_MASK | + InputEvent.CTRL_MASK | + InputEvent.META_MASK | + InputEvent.ALT_MASK); + + int peButton = 0; + if ((modifiers & InputEvent.BUTTON1_MASK) != 0) { + peButton = PConstants.LEFT; + } else if ((modifiers & InputEvent.BUTTON2_MASK) != 0) { + peButton = PConstants.CENTER; + } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) { + peButton = PConstants.RIGHT; + } + + if (PApplet.platform == PConstants.MACOSX) { + //if (nativeEvent.isPopupTrigger()) { + if ((modifiers & InputEvent.CTRL_MASK) != 0) { + peButton = PConstants.RIGHT; + } + } + + int peCount = 0; + if (peAction == MouseEvent.WHEEL) { + peCount = nativeEvent.isShiftDown() ? (int)nativeEvent.getRotation()[0] : + (int)nativeEvent.getRotation()[1]; + } else { + peCount = nativeEvent.getClickCount(); + } + + MouseEvent me = new MouseEvent(nativeEvent, nativeEvent.getWhen(), + peAction, peModifiers, + nativeEvent.getX(), nativeEvent.getY(), + peButton, + peCount); + + sketch.postEvent(me); + } + + protected void nativeKeyEvent(com.jogamp.newt.event.KeyEvent nativeEvent, + int peAction) { + int peModifiers = nativeEvent.getModifiers() & + (InputEvent.SHIFT_MASK | + InputEvent.CTRL_MASK | + InputEvent.META_MASK | + InputEvent.ALT_MASK); + + char keyChar; + if (nativeEvent.getKeyChar() == 0) { + keyChar = PConstants.CODED; + } else { + keyChar = nativeEvent.getKeyChar(); + } + + KeyEvent ke = new KeyEvent(nativeEvent, nativeEvent.getWhen(), + peAction, peModifiers, + keyChar, + nativeEvent.getKeyCode()); + + sketch.postEvent(ke); + } + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + public void setCursor(int kind) { + // TODO Auto-generated method stub + + } + + public void setCursor(PImage image, int hotspotX, int hotspotY) { + // TODO Auto-generated method stub + + } + + public void showCursor() { + window.setPointerVisible(true); + } + + public void hideCursor() { + window.setPointerVisible(false); + } +}