gov.nasa.worldwind.awt.WorldWindowGLJPanel Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2012 United States Government as represented by the Administrator of the
* National Aeronautics and Space Administration.
* All Rights Reserved.
*/
package gov.nasa.worldwind.awt;
import gov.nasa.worldwind.*;
import gov.nasa.worldwind.avlist.*;
import gov.nasa.worldwind.cache.GpuResourceCache;
import gov.nasa.worldwind.event.*;
import gov.nasa.worldwind.exception.WWRuntimeException;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.pick.PickedObjectList;
import gov.nasa.worldwind.util.*;
import com.jogamp.opengl.*;
import com.jogamp.opengl.awt.GLJPanel;
import java.beans.*;
import java.util.*;
/**
* WorldWindowGLCanvas
is a lightweight Swing component for displaying World Wind {@link Model}s (globe and
* layers). It's a self-contained component intended to serve as an application's WorldWindow
. Construction
* options exist to specify a specific graphics device and to share graphics resources with another graphics device.
*
* Note: The Java SDK for OpenGL (JOGL) support for the underlying {@link GLJPanel} that this class uses has
* historically been problematic. It works well on some devices but not on others, and its performance varies much more
* among devices than that of its heavyweight counterpart, {@link WorldWindowGLCanvas}. It's therefore best to use the
* heavyweight component if possible. You can find detailed information on this issue in the Heavyweight and
* Lightweight Issues section of the "JOGL User's
* Guide"
*
* This class is capable of supporting stereo devices. To cause a stereo device to be selected and used, specify the
* Java VM property "gov.nasa.worldwind.stereo.mode=device" prior to creating an instance of this class. A stereo
* capable {@link SceneController} such as {@link gov.nasa.worldwind.StereoSceneController} must also be specified in
* the World Wind {@link Configuration}. The default configuration specifies a stereo-capable controller. To prevent
* stereo from being used by subsequently opened {@code WorldWindowGLCanvas}es, set the property to a an empty string,
* "". If a stereo device cannot be selected and used, this falls back to a non-stereo device that supports World Wind's
* minimum requirements.
*
* Under certain conditions, JOGL replaces the GLContext
associated with instances of this class. This then
* necessitates that all resources such as textures that have been stored on the graphic devices must be regenerated for
* the new context. World Wind does this automatically by clearing the associated {@link GpuResourceCache}. Objects
* subsequently rendered automatically re-create those resources. If an application creates its own graphics resources,
* including textures, vertex buffer objects and display lists, it must store them in the GpuResourceCache
* associated with the current {@link gov.nasa.worldwind.render.DrawContext} so that they are automatically cleared, and
* be prepared to re-create them if they do not exist in the DrawContext
's current
* GpuResourceCache
when needed. Examples of doing this can be found by searching for usages of the method
* {@link GpuResourceCache#get(Object)} and {@link GpuResourceCache#getTexture(Object)}.
*
* @author Tom Gaskins
* @version $Id: WorldWindowGLJPanel.java 2047 2014-06-06 22:48:33Z tgaskins $
*/
public class WorldWindowGLJPanel extends GLJPanel implements WorldWindow, PropertyChangeListener
{
/** The drawable to which {@link WorldWindow} methods are delegated. */
protected final WorldWindowGLDrawable wwd; // WorldWindow interface delegates to wwd
/** Constructs a new WorldWindowGLCanvas
window on the default graphics device. */
public WorldWindowGLJPanel()
{
super(Configuration.getRequiredGLCapabilities(), new BasicGLCapabilitiesChooser());
try
{
this.wwd = ((WorldWindowGLDrawable) WorldWind.createConfigurationComponent(AVKey.WORLD_WINDOW_CLASS_NAME));
this.wwd.initDrawable(this);
this.wwd.addPropertyChangeListener(this);
this.wwd.initGpuResourceCache(WorldWindowImpl.createGpuResourceCache());
this.createView();
this.createDefaultInputHandler();
WorldWind.addPropertyChangeListener(WorldWind.SHUTDOWN_EVENT, this);
this.wwd.endInitialization();
}
catch (Exception e)
{
String message = Logging.getMessage("Awt.WorldWindowGLSurface.UnabletoCreateWindow");
Logging.logger().severe(message);
throw new WWRuntimeException(message, e);
}
}
/**
* Constructs a new WorldWindowGLJPanel
on the default graphics device and shares graphics resources
* with another WorldWindow
.
*
* @param shareWith a WorldWindow
with which to share graphics resources.
*
* @see GLJPanel#GLJPanel(com.jogamp.opengl.GLCapabilitiesImmutable, com.jogamp.opengl.GLCapabilitiesChooser,
* com.jogamp.opengl.GLContext)
*/
public WorldWindowGLJPanel(WorldWindow shareWith)
{
super(Configuration.getRequiredGLCapabilities(), new BasicGLCapabilitiesChooser());
if (shareWith != null)
this.setSharedContext(shareWith.getContext());
try
{
this.wwd = ((WorldWindowGLDrawable) WorldWind.createConfigurationComponent(AVKey.WORLD_WINDOW_CLASS_NAME));
this.wwd.initDrawable(this);
this.wwd.addPropertyChangeListener(this);
if (shareWith != null)
this.wwd.initGpuResourceCache(shareWith.getGpuResourceCache());
else
this.wwd.initGpuResourceCache(WorldWindowImpl.createGpuResourceCache());
this.createView();
this.createDefaultInputHandler();
WorldWind.addPropertyChangeListener(WorldWind.SHUTDOWN_EVENT, this);
this.wwd.endInitialization();
}
catch (Exception e)
{
String message = Logging.getMessage("Awt.WorldWindowGLSurface.UnabletoCreateWindow");
Logging.logger().severe(message);
throw new WWRuntimeException(message, e);
}
}
/**
* Constructs a new WorldWindowGLJPanel
that shares graphics resources with another
* WorldWindow
and whose capabilities are chosen via a specified {@link GLCapabilities} object and a
* {@link GLCapabilitiesChooser}.
*
* @param shareWith a WorldWindow
with which to share graphics resources.
* @param capabilities a capabilities object indicating the OpenGL rendering context's capabilities. May be null, in
* which case a default set of capabilities is used.
* @param chooser a chooser object that customizes the specified capabilities. May be null, in which case a
* default chooser is used.
*
* @see GLJPanel#GLJPanel(com.jogamp.opengl.GLCapabilitiesImmutable, com.jogamp.opengl.GLCapabilitiesChooser,
* com.jogamp.opengl.GLContext)
*/
public WorldWindowGLJPanel(WorldWindow shareWith, GLCapabilities capabilities,
GLCapabilitiesChooser chooser)
{
super(capabilities, chooser);
if (shareWith != null)
this.setSharedContext(shareWith.getContext());
try
{
this.wwd = ((WorldWindowGLDrawable) WorldWind.createConfigurationComponent(AVKey.WORLD_WINDOW_CLASS_NAME));
this.wwd.initDrawable(this);
this.wwd.addPropertyChangeListener(this);
if (shareWith != null)
this.wwd.initGpuResourceCache(shareWith.getGpuResourceCache());
else
this.wwd.initGpuResourceCache(WorldWindowImpl.createGpuResourceCache());
this.createView();
this.createDefaultInputHandler();
WorldWind.addPropertyChangeListener(WorldWind.SHUTDOWN_EVENT, this);
this.wwd.endInitialization();
}
catch (Exception e)
{
String message = Logging.getMessage("Awt.WorldWindowGLSurface.UnabletoCreateWindow");
Logging.logger().severe(message);
throw new WWRuntimeException(message, e);
}
}
public void propertyChange(PropertyChangeEvent evt)
{
if(this.wwd == evt.getSource())
this.firePropertyChange(evt);
//noinspection StringEquality
if (evt.getPropertyName() == WorldWind.SHUTDOWN_EVENT)
this.shutdown();
}
public void shutdown()
{
WorldWind.removePropertyChangeListener(WorldWind.SHUTDOWN_EVENT, this);
this.wwd.shutdown();
}
@Override
public boolean isEnableGpuCacheReinitialization()
{
return this.wwd.isEnableGpuCacheReinitialization();
}
@Override
public void setEnableGpuCacheReinitialization(boolean enableGpuCacheReinitialization)
{
this.wwd.setEnableGpuCacheReinitialization(enableGpuCacheReinitialization);
}
/** Constructs and attaches the {@link View} for this WorldWindow
. */
protected void createView()
{
this.setView((View) WorldWind.createConfigurationComponent(AVKey.VIEW_CLASS_NAME));
}
/** Constructs and attaches the {@link InputHandler} for this WorldWindow
. */
protected void createDefaultInputHandler()
{
this.setInputHandler((InputHandler) WorldWind.createConfigurationComponent(AVKey.INPUT_HANDLER_CLASS_NAME));
}
public InputHandler getInputHandler()
{
return this.wwd.getInputHandler();
}
public void setInputHandler(InputHandler inputHandler)
{
if (this.wwd.getInputHandler() != null)
this.wwd.getInputHandler().setEventSource(null); // remove this window as a source of events
this.wwd.setInputHandler(inputHandler != null ? inputHandler : new NoOpInputHandler());
if (inputHandler != null)
inputHandler.setEventSource(this);
}
public SceneController getSceneController()
{
return this.wwd.getSceneController();
}
public void setSceneController(SceneController sceneController)
{
this.wwd.setSceneController(sceneController);
}
public GpuResourceCache getGpuResourceCache()
{
return this.wwd.getGpuResourceCache();
}
public void redraw()
{
this.repaint();
}
public void redrawNow()
{
this.wwd.redrawNow();
}
public void setModel(Model model)
{
// null models are permissible
this.wwd.setModel(model);
}
public Model getModel()
{
return this.wwd.getModel();
}
public void setView(View view)
{
// null views are permissible
if (view != null)
this.wwd.setView(view);
}
public View getView()
{
return this.wwd.getView();
}
public void setModelAndView(Model model, View view)
{ // null models/views are permissible
this.setModel(model);
this.setView(view);
}
public void addRenderingListener(RenderingListener listener)
{
this.wwd.addRenderingListener(listener);
}
public void removeRenderingListener(RenderingListener listener)
{
this.wwd.removeRenderingListener(listener);
}
public void addSelectListener(SelectListener listener)
{
this.wwd.getInputHandler().addSelectListener(listener);
this.wwd.addSelectListener(listener);
}
public void removeSelectListener(SelectListener listener)
{
this.wwd.getInputHandler().removeSelectListener(listener);
this.wwd.removeSelectListener(listener);
}
public void addPositionListener(PositionListener listener)
{
this.wwd.addPositionListener(listener);
}
public void removePositionListener(PositionListener listener)
{
this.wwd.removePositionListener(listener);
}
public void addRenderingExceptionListener(RenderingExceptionListener listener)
{
this.wwd.addRenderingExceptionListener(listener);
}
public void removeRenderingExceptionListener(RenderingExceptionListener listener)
{
this.wwd.removeRenderingExceptionListener(listener);
}
public Position getCurrentPosition()
{
return this.wwd.getCurrentPosition();
}
public PickedObjectList getObjectsAtCurrentPosition()
{
return this.wwd.getSceneController() != null ? this.wwd.getSceneController().getPickedObjectList() : null;
}
public PickedObjectList getObjectsInSelectionBox()
{
return this.wwd.getSceneController() != null ? this.wwd.getSceneController().getObjectsInPickRectangle() : null;
}
public Object setValue(String key, Object value)
{
return this.wwd.setValue(key, value);
}
public AVList setValues(AVList avList)
{
return this.wwd.setValues(avList);
}
public Object getValue(String key)
{
return this.wwd.getValue(key);
}
public Collection
© 2015 - 2024 Weber Informatics LLC | Privacy Policy