All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jogamp.newt.opengl.GLWindow Maven / Gradle / Ivy

There is a newer version: 2.3.2
Show newest version
/*
 * Copyright (c) 2008 Sun Microsystems, Inc. All Rights Reserved.
 * Copyright (c) 2010 JogAmp Community. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * - Redistribution of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistribution in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * Neither the name of Sun Microsystems, Inc. or the names of
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
 * MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR
 * ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR
 * DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
 * DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
 * ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
 * SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *
 */

package com.jogamp.newt.opengl;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.List;

import javax.media.nativewindow.AbstractGraphicsConfiguration;
import javax.media.nativewindow.CapabilitiesChooser;
import javax.media.nativewindow.CapabilitiesImmutable;
import javax.media.nativewindow.NativeSurface;
import javax.media.nativewindow.NativeWindow;
import javax.media.nativewindow.NativeWindowException;
import javax.media.nativewindow.SurfaceUpdatedListener;
import javax.media.nativewindow.util.InsetsImmutable;
import javax.media.nativewindow.util.Point;
import javax.media.opengl.FPSCounter;
import javax.media.opengl.GL;
import javax.media.opengl.GL3;
import javax.media.opengl.GL4ES3;
import javax.media.opengl.GLAnimatorControl;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawable;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLES2;
import javax.media.opengl.GLES3;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLException;
import javax.media.opengl.GLProfile;

import jogamp.newt.WindowImpl;
import jogamp.opengl.GLAutoDrawableBase;
import jogamp.opengl.GLContextImpl;
import jogamp.opengl.GLDrawableImpl;

import com.jogamp.common.GlueGenVersion;
import com.jogamp.common.util.VersionUtil;
import com.jogamp.common.util.locks.RecursiveLock;
import com.jogamp.newt.MonitorDevice;
import com.jogamp.newt.NewtFactory;
import com.jogamp.newt.Screen;
import com.jogamp.newt.Window;
import com.jogamp.newt.event.KeyListener;
import com.jogamp.newt.event.MouseListener;
import com.jogamp.newt.event.NEWTEvent;
import com.jogamp.newt.event.NEWTEventConsumer;
import com.jogamp.newt.event.WindowAdapter;
import com.jogamp.newt.event.WindowEvent;
import com.jogamp.newt.event.WindowListener;
import com.jogamp.newt.event.WindowUpdateEvent;
import com.jogamp.opengl.JoglVersion;
import com.jogamp.opengl.GLStateKeeper;

/**
 * An implementation of {@link GLAutoDrawable} and {@link Window} interface,
 * using a delegated {@link Window} instance, which may be an aggregation (lifecycle: created and destroyed).
 * 

* This implementation supports {@link GLStateKeeper GL state preservation}, * hence {@link #isGLStatePreservationSupported()} returns true. *

*

* This implementation does not make the OpenGL context current
* before calling the various input EventListener callbacks, ie {@link com.jogamp.newt.event.MouseListener} etc.
* This design decision is made in favor of a more performant and simplified * implementation. Also the event dispatcher shall be implemented OpenGL agnostic.
* To be able to use OpenGL commands from within such input {@link com.jogamp.newt.event.NEWTEventListener},
* you can inject {@link javax.media.opengl.GLRunnable} objects * via {@link #invoke(boolean, javax.media.opengl.GLRunnable)} to the OpenGL command stream.
*

*/ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Window, NEWTEventConsumer, FPSCounter { private final WindowImpl window; /** * Constructor. Do not call this directly -- use {@link #create()} instead. */ protected GLWindow(Window window) { super(null, null, false /* always handle device lifecycle ourselves */); this.window = (WindowImpl) window; this.window.setWindowDestroyNotifyAction( new Runnable() { public void run() { defaultWindowDestroyNotifyOp(); } } ); window.addWindowListener(new WindowAdapter() { @Override public void windowRepaint(WindowUpdateEvent e) { defaultWindowRepaintOp(); } @Override public void windowResized(WindowEvent e) { defaultWindowResizedOp(getWidth(), getHeight()); } }); this.window.setLifecycleHook(new GLLifecycleHook()); } @Override public final Object getUpstreamWidget() { return window; } /** * Creates a new GLWindow attaching a new Window referencing a * new default Screen and default Display with the given GLCapabilities. *

* The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()} * and {@link Screen#removeReference()}. *

* The default Display will be reused if already instantiated. */ public static GLWindow create(GLCapabilitiesImmutable caps) { return new GLWindow(NewtFactory.createWindow(caps)); } /** * Creates a new GLWindow attaching a new Window referencing the given Screen * with the given GLCapabilities. *

* The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()} * and {@link Screen#removeReference()}. *

*/ public static GLWindow create(Screen screen, GLCapabilitiesImmutable caps) { return new GLWindow(NewtFactory.createWindow(screen, caps)); } /** * Creates a new GLWindow attaching the given window. *

* The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()} * and {@link Screen#removeReference()}. *

*/ public static GLWindow create(Window window) { return new GLWindow(window); } /** * Creates a new GLWindow attaching a new child Window * of the given parentNativeWindow with the given GLCapabilities. *

* The Display/Screen will be compatible with the parentNativeWindow, * or even identical in case it's a Newt Window. * An already instantiated compatible Display will be reused. *

*

* The lifecycle of this Window's Screen and Display is handled via {@link Screen#addReference()} * and {@link Screen#removeReference()}. *

*/ public static GLWindow create(NativeWindow parentNativeWindow, GLCapabilitiesImmutable caps) { return new GLWindow(NewtFactory.createWindow(parentNativeWindow, caps)); } //---------------------------------------------------------------------- // WindowClosingProtocol implementation // @Override public WindowClosingMode getDefaultCloseOperation() { return window.getDefaultCloseOperation(); } @Override public WindowClosingMode setDefaultCloseOperation(WindowClosingMode op) { return window.setDefaultCloseOperation(op); } //---------------------------------------------------------------------- // Window Access // @Override public CapabilitiesChooser setCapabilitiesChooser(CapabilitiesChooser chooser) { return window.setCapabilitiesChooser(chooser); } @Override public final CapabilitiesImmutable getChosenCapabilities() { final GLDrawable _drawable = drawable; return null != _drawable ? _drawable.getChosenGLCapabilities() : window.getChosenCapabilities(); } @Override public final CapabilitiesImmutable getRequestedCapabilities() { return window.getRequestedCapabilities(); } @Override public final Window getDelegatedWindow() { return window.getDelegatedWindow(); } @Override public final NativeWindow getParent() { return window.getParent(); } @Override public final Screen getScreen() { return window.getScreen(); } @Override public final MonitorDevice getMainMonitor() { return window.getMainMonitor(); } @Override public final void setTitle(String title) { window.setTitle(title); } @Override public final String getTitle() { return window.getTitle(); } @Override public final boolean isPointerVisible() { return window.isPointerVisible(); } @Override public final void setPointerVisible(boolean mouseVisible) { window.setPointerVisible(mouseVisible); } @Override public final boolean isPointerConfined() { return window.isPointerConfined(); } @Override public final void confinePointer(boolean grab) { window.confinePointer(grab); } @Override public final void setUndecorated(boolean value) { window.setUndecorated(value); } @Override public final void warpPointer(int x, int y) { window.warpPointer(x, y); } @Override public final boolean isUndecorated() { return window.isUndecorated(); } @Override public final void setAlwaysOnTop(boolean value) { window.setAlwaysOnTop(value); } @Override public final boolean isAlwaysOnTop() { return window.isAlwaysOnTop(); } @Override public final void setFocusAction(FocusRunnable focusAction) { window.setFocusAction(focusAction); } @Override public void setKeyboardFocusHandler(KeyListener l) { window.setKeyboardFocusHandler(l); } @Override public final void requestFocus() { window.requestFocus(); } @Override public final void requestFocus(boolean wait) { window.requestFocus(wait); } @Override public boolean hasFocus() { return window.hasFocus(); } @Override public final InsetsImmutable getInsets() { return window.getInsets(); } @Override public final int getX() { return window.getX(); } @Override public final int getY() { return window.getY(); } @Override public final int getWidth() { return window.getWidth(); } @Override public final int getHeight() { return window.getHeight(); } @Override public final void setPosition(int x, int y) { window.setPosition(x, y); } @Override public void setTopLevelPosition(int x, int y) { window.setTopLevelPosition(x, y); } @Override public final boolean setFullscreen(boolean fullscreen) { return window.setFullscreen(fullscreen); } @Override public boolean setFullscreen(List monitors) { return window.setFullscreen(monitors); } @Override public final boolean isFullscreen() { return window.isFullscreen(); } @Override public final boolean isVisible() { return window.isVisible(); } @Override public final String toString() { return "NEWT-GLWindow[ \n\tHelper: " + helper + ", \n\tDrawable: " + drawable + ", \n\tContext: " + context + ", \n\tWindow: "+window+ /** ", \n\tFactory: "+factory+ */ "]"; } @Override public final ReparentOperation reparentWindow(NativeWindow newParent) { return window.reparentWindow(newParent); } @Override public final ReparentOperation reparentWindow(NativeWindow newParent, boolean forceDestroyCreate) { return window.reparentWindow(newParent, forceDestroyCreate); } @Override public final boolean removeChild(NativeWindow win) { return window.removeChild(win); } @Override public final boolean addChild(NativeWindow win) { return window.addChild(win); } //---------------------------------------------------------------------- // Window.LifecycleHook Implementation // @Override public final void destroy() { window.destroy(); } @Override public void setWindowDestroyNotifyAction(Runnable r) { window.setWindowDestroyNotifyAction(r); } @Override public final void setVisible(boolean visible) { window.setVisible(visible); } @Override public final void setSize(int width, int height) { window.setSize(width, height); } @Override public void setTopLevelSize(int width, int height) { window.setTopLevelSize(width, height); } @Override public final boolean isNativeValid() { return window.isNativeValid(); } @Override public Point getLocationOnScreen(Point storage) { return window.getLocationOnScreen(storage); } // Hide methods here .. protected class GLLifecycleHook implements WindowImpl.LifecycleHook { @Override public void preserveGLStateAtDestroy(boolean value) { GLWindow.this.preserveGLStateAtDestroy(value); } @Override public synchronized void destroyActionPreLock() { // nop } @Override public synchronized void destroyActionInLock() { if(Window.DEBUG_IMPLEMENTATION) { String msg = "GLWindow.destroy() "+WindowImpl.getThreadName()+", start"; System.err.println(msg); //Exception e1 = new Exception(msg); //e1.printStackTrace(); } destroyImplInLock(); if(Window.DEBUG_IMPLEMENTATION) { System.err.println("GLWindow.destroy() "+WindowImpl.getThreadName()+", fin"); } } @Override public synchronized void resetCounter() { if(Window.DEBUG_IMPLEMENTATION) { System.err.println("GLWindow.resetCounter() "+WindowImpl.getThreadName()); } GLWindow.this.resetFPSCounter(); final GLAnimatorControl animator = GLWindow.this.getAnimator(); if( null != animator ) { animator.resetFPSCounter(); } } @Override public synchronized void setVisibleActionPost(boolean visible, boolean nativeWindowCreated) { long t0; if(Window.DEBUG_IMPLEMENTATION) { t0 = System.nanoTime(); System.err.println("GLWindow.setVisibleActionPost("+visible+", "+nativeWindowCreated+") "+WindowImpl.getThreadName()+", start"); } else { t0 = 0; } if (null == drawable && visible && 0 != window.getWindowHandle() && 0() { public Object run() { if( anim.isAnimating() && null != animThread ) { try { animThread.stop(); } catch(Throwable t) { } } return null; } } ); } } } } //---------------------------------------------------------------------- // OpenGL-related methods and state // private GLContext sharedContext = null; @Override protected final RecursiveLock getLock() { return window.getLock(); } /** * Specifies an {@link javax.media.opengl.GLContext OpenGL context} to share with.
* At native creation, {@link #setVisible(boolean) setVisible(true)}, * a {@link javax.media.opengl.GLDrawable drawable} and {@link javax.media.opengl.GLContext context} is created besides the native Window itself,
* hence you shall set the shared context before. * * @param sharedContext The OpenGL context shared by this GLWindow's one */ public void setSharedContext(GLContext sharedContext) { this.sharedContext = sharedContext; } @Override public void display() { if( !isNativeValid() || !isVisible() ) { return; } if(sendDestroy || ( window.hasDeviceChanged() && GLAutoDrawable.SCREEN_CHANGE_ACTION_ENABLED ) ) { sendDestroy=false; destroy(); return; } final boolean done; final RecursiveLock lock = window.getLock(); lock.lock(); // sync: context/drawable could have been recreated/destroyed while animating try { if( null != context ) { // surface is locked/unlocked implicit by context's makeCurrent/release helper.invokeGL(drawable, context, defaultDisplayAction, defaultInitAction); done = true; } else { done = false; } } finally { lock.unlock(); } if( !done && ( 0 < getWidth() && 0 < getHeight() ) ) { // retry drawable and context creation, will itself issue resize -> display setVisible(true); } } /** * {@inheritDoc} *

* GLWindow supports GL state preservation, hence returns true. *

*/ @Override public final boolean isGLStatePreservationSupported() { return true; } //---------------------------------------------------------------------- // GLDrawable methods // private GLDrawableFactory factory; @Override public final GLDrawableFactory getFactory() { return factory; } @Override public final void swapBuffers() throws GLException { defaultSwapBuffers(); } //---------------------------------------------------------------------- // NEWTEventConsumer // @Override public boolean consumeEvent(NEWTEvent event) { return window.consumeEvent(event); } //---------------------------------------------------------------------- // Window completion // @Override public final void windowRepaint(int x, int y, int width, int height) { window.windowRepaint(x, y, width, height); } @Override public final void enqueueEvent(boolean wait, com.jogamp.newt.event.NEWTEvent event) { window.enqueueEvent(wait, event); } @Override public final void runOnEDTIfAvail(boolean wait, final Runnable task) { window.runOnEDTIfAvail(wait, task); } @Override public final void removeSurfaceUpdatedListener(SurfaceUpdatedListener l) { window.removeSurfaceUpdatedListener(l); } @Override public final void addSurfaceUpdatedListener(SurfaceUpdatedListener l) { window.addSurfaceUpdatedListener(l); } @Override public final void addSurfaceUpdatedListener(int index, SurfaceUpdatedListener l) throws IndexOutOfBoundsException { window.addSurfaceUpdatedListener(index, l); } @Override public void sendWindowEvent(int eventType) { window.sendWindowEvent(eventType); } @Override public final WindowListener getWindowListener(int index) { return window.getWindowListener(index); } @Override public final WindowListener[] getWindowListeners() { return window.getWindowListeners(); } @Override public final void removeWindowListener(WindowListener l) { window.removeWindowListener(l); } @Override public final void addWindowListener(WindowListener l) { window.addWindowListener(l); } @Override public final void addWindowListener(int index, WindowListener l) throws IndexOutOfBoundsException { window.addWindowListener(index, l); } @Override public final void setKeyboardVisible(boolean visible) { window.setKeyboardVisible(visible); } @Override public final boolean isKeyboardVisible() { return window.isKeyboardVisible(); } @Override public final void addKeyListener(KeyListener l) { window.addKeyListener(l); } @Override public final void addKeyListener(int index, KeyListener l) { window.addKeyListener(index, l); } @Override public final void removeKeyListener(KeyListener l) { window.removeKeyListener(l); } @Override public final KeyListener getKeyListener(int index) { return window.getKeyListener(index); } @Override public final KeyListener[] getKeyListeners() { return window.getKeyListeners(); } @Override public final void addMouseListener(MouseListener l) { window.addMouseListener(l); } @Override public final void addMouseListener(int index, MouseListener l) { window.addMouseListener(index, l); } @Override public final void removeMouseListener(MouseListener l) { window.removeMouseListener(l); } @Override public final MouseListener getMouseListener(int index) { return window.getMouseListener(index); } @Override public final MouseListener[] getMouseListeners() { return window.getMouseListeners(); } //---------------------------------------------------------------------- // NativeWindow completion // @Override public final int lockSurface() throws NativeWindowException, RuntimeException { return window.lockSurface(); } @Override public final void unlockSurface() { window.unlockSurface(); } @Override public final boolean isSurfaceLockedByOtherThread() { return window.isSurfaceLockedByOtherThread(); } @Override public final Thread getSurfaceLockOwner() { return window.getSurfaceLockOwner(); } @Override public final boolean surfaceSwap() { return window.surfaceSwap(); } @Override public final long getWindowHandle() { return window.getWindowHandle(); } @Override public final long getSurfaceHandle() { return window.getSurfaceHandle(); } @Override public final AbstractGraphicsConfiguration getGraphicsConfiguration() { return window.getGraphicsConfiguration(); } @Override public final long getDisplayHandle() { return window.getDisplayHandle(); } @Override public final int getScreenIndex() { return window.getScreenIndex(); } @Override public final void surfaceUpdated(Object updater, NativeSurface ns, long when) { window.surfaceUpdated(updater, ns, when); } /** * A most simple JOGL AWT test entry */ public static void main(String args[]) { final boolean forceES2; final boolean forceES3; final boolean forceGL3; final boolean forceGL4ES3; { boolean _forceES2 = false; boolean _forceES3 = false; boolean _forceGL3 = false; boolean _forceGL4ES3 = false; if( null != args ) { for(int i=0; i




© 2015 - 2024 Weber Informatics LLC | Privacy Policy