Issue #239 got offscreen rendering working for clients

Former-commit-id: f41733465eb0ee048fb76a0d5467ce456d1cf7c9
This commit is contained in:
Max Schenkelberg 2012-04-12 10:45:50 -05:00
parent a6c6695e5b
commit 2de39bb487
26 changed files with 634 additions and 60 deletions

View file

@ -17,13 +17,16 @@
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
* further licensing information.
**/
package com.raytheon.uf.viz.remote.graphics.events.mesh;
package com.raytheon.uf.viz.collaboration.ui.rsc;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
import com.google.common.eventbus.Subscribe;
import com.raytheon.uf.viz.collaboration.ui.rsc.CollaborationRenderingHandler.ColorMapDataCallback;
import com.raytheon.uf.viz.core.IMesh;
import com.raytheon.uf.viz.core.drawables.IImage;
import com.raytheon.uf.viz.core.drawables.IWireframeShape;
/**
* TODO Add Description
* Collaboration class responsible for disposing renderable objects
*
* <pre>
*
@ -31,14 +34,33 @@ import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Mar 26, 2012 mschenke Initial creation
* Apr 11, 2012 mschenke Initial creation
*
* </pre>
*
* @author mschenke
* @version 1.0
*/
@DynamicSerialize
public class DisposeMeshEvent extends AbstractDispatchingObjectEvent {
public class CollaborationDisposingHandler {
@Subscribe
public void disposeImage(IImage image) {
image.dispose();
}
@Subscribe
public void disposeMesh(IMesh mesh) {
mesh.dispose();
}
@Subscribe
public void disposed(ColorMapDataCallback callback) {
callback.setData(null);
}
@Subscribe
public void disposeWireframeShape(IWireframeShape shape) {
shape.dispose();
}
}

View file

@ -19,11 +19,41 @@
**/
package com.raytheon.uf.viz.collaboration.ui.rsc;
import java.nio.Buffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import com.raytheon.uf.viz.core.DrawableImage;
import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.IMesh;
import com.raytheon.uf.viz.core.PixelCoverage;
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
import com.raytheon.uf.viz.core.drawables.IColormappedImage;
import com.raytheon.uf.viz.core.drawables.IImage;
import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.drawables.ext.IOffscreenRenderingExtension;
import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormappedImageExtension;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.map.IMapMeshExtension;
import com.raytheon.uf.viz.remote.graphics.events.BeginFrameEvent;
import com.raytheon.uf.viz.remote.graphics.events.DisposeObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.colormap.ColorMapDataEvent;
import com.raytheon.uf.viz.remote.graphics.events.colormap.CreateColormappedImageEvent;
import com.raytheon.uf.viz.remote.graphics.events.colormap.UpdateColorMapParametersEvent;
import com.raytheon.uf.viz.remote.graphics.events.imagery.PaintImageEvent;
import com.raytheon.uf.viz.remote.graphics.events.imagery.PaintImagesEvent;
import com.raytheon.uf.viz.remote.graphics.events.imagery.UpdateImageDataEvent;
import com.raytheon.uf.viz.remote.graphics.events.mesh.CreateMeshEvent;
import com.raytheon.uf.viz.remote.graphics.events.mesh.ReprojectMeshEvent;
import com.raytheon.uf.viz.remote.graphics.events.offscreen.CreateOffscreenImageEvent;
import com.raytheon.uf.viz.remote.graphics.events.offscreen.RenderOffscreenEvent;
import com.raytheon.uf.viz.remote.graphics.events.offscreen.RenderOnscreenEvent;
/**
* Class that handles rendering events for collaboration resource
@ -44,10 +74,19 @@ import com.raytheon.uf.viz.remote.graphics.events.BeginFrameEvent;
public class CollaborationRenderingHandler {
private Map<Integer, Object[]> renderableObjectMap = new HashMap<Integer, Object[]>();
private IGraphicsTarget target;
private PaintProperties paintProps;
private EventBus disposerRouter;
public CollaborationRenderingHandler() {
this.disposerRouter = new EventBus();
this.disposerRouter.register(new CollaborationDisposingHandler());
}
/**
* @param target
* @param paintProps
@ -57,10 +96,93 @@ public class CollaborationRenderingHandler {
this.paintProps = paintProps;
}
public void dispose() {
/**
* Put a renderable object in the object map. If an object already exists
* for that id, it will be sent to the disposer
*
* @param objectId
* @param obj
*/
private void putRenderableObject(int objectId, Object obj) {
if (obj != null) {
Object[] objects = null;
if (obj.getClass().isArray()) {
objects = (Object[]) obj;
} else {
objects = new Object[] { obj };
}
Object[] oldValue = renderableObjectMap.put(objectId, objects);
if (oldValue != null) {
dispose(oldValue);
}
}
}
/**
* Get a renderable object out of the object map as the objectType, if no
* object exists or the object is not of type objectType, null is returned.
* If the Object in the map is an Object[], the first object in the array
* that is of type objectType will be returned
*
* @param <T>
* @param objectId
* @param objectType
* @return
*/
private <T> T getRenderableObject(int objectId, Class<T> objectType) {
T obj = null;
Object[] toCheck = renderableObjectMap.get(objectId);
if (toCheck != null) {
for (Object check : toCheck) {
if (objectType.isInstance(check)) {
obj = objectType.cast(check);
break;
}
}
}
return obj;
}
/**
* Dispose all renderable object data
*/
public void dispose() {
for (Object[] obj : renderableObjectMap.values()) {
dispose(obj);
}
renderableObjectMap.clear();
}
/**
* Disposes a single renderable object by sending it to the disposer
* EventBus
*
* @param obj
*/
private void dispose(Object[] objects) {
for (Object toDispose : objects) {
disposerRouter.post(toDispose);
}
}
/**
* General dispose of a renderable object event
*
* @param event
*/
@Subscribe
public void disposeRenderable(DisposeObjectEvent event) {
Object[] toDispose = renderableObjectMap.remove(event);
if (toDispose != null) {
dispose(toDispose);
}
}
/**
* Begin frame event, modifies the target extent
*
* @param event
*/
@Subscribe
public void handleBeginFrame(BeginFrameEvent event) {
double[] center = event.getExtentCenter();
@ -76,4 +198,171 @@ public class CollaborationRenderingHandler {
}
}
// ================== Common IImage events ==================
@Subscribe
public void renderImages(PaintImagesEvent event) throws VizException {
PaintImageEvent[] events = event.getImageEvents();
List<DrawableImage> images = new ArrayList<DrawableImage>(events.length);
for (PaintImageEvent pie : events) {
IImage image = getRenderableObject(pie.getObjectId(), IImage.class);
if (image != null) {
PixelCoverage coverage = new PixelCoverage(pie.getUl(),
pie.getUr(), pie.getLr(), pie.getLl());
IMesh mesh = getRenderableObject(pie.getMeshId(), IMesh.class);
if (mesh != null) {
coverage.setMesh(mesh);
}
images.add(new DrawableImage(image, coverage));
} else {
// TODO: Log?
}
}
if (images.size() > 0) {
PaintProperties imageProps = new PaintProperties(paintProps);
imageProps.setAlpha(event.getAlpha());
target.drawRasters(imageProps,
images.toArray(new DrawableImage[images.size()]));
}
}
@Subscribe
public void updateImageData(UpdateImageDataEvent event) {
IImage image = getRenderableObject(event.getObjectId(), IImage.class);
if (image != null) {
image.setBrightness(event.getBrightness());
image.setContrast(event.getContrast());
image.setInterpolated(event.isInterpolated());
}
}
// ================== IColormappedImage events ==================
/**
* TODO: Manage ColorMaps better! (sharing and updating)
*
* Creates an IColormappedImage object from the event
*
* @param event
* @throws VizException
*/
@Subscribe
public void createColormappedImage(CreateColormappedImageEvent event)
throws VizException {
int imageId = event.getObjectId();
IColorMapDataRetrievalCallback callback = new ColorMapDataCallback();
UpdateColorMapParametersEvent cmapEvent = event.getColorMapParameters();
ColorMapParameters params = null;
if (cmapEvent != null) {
params = cmapEvent.asColorMapParameters();
}
IColormappedImage image = target.getExtension(
IColormappedImageExtension.class).initializeRaster(callback,
params);
putRenderableObject(imageId, new Object[] { image, callback });
}
@Subscribe
public void dataArrived(ColorMapDataEvent event) {
ColorMapDataCallback callback = getRenderableObject(
event.getObjectId(), ColorMapDataCallback.class);
if (callback != null) {
callback.setData(event.getColorMapData());
}
}
// TODO: Put utility classes in same package
public class ColorMapDataCallback implements IColorMapDataRetrievalCallback {
private ColorMapData data;
@Override
public ColorMapData getColorMapData() throws VizException {
ColorMapData rval = data;
if (data != null) {
data = null;
}
return rval;
}
public void setData(ColorMapData data) {
this.data = data;
}
}
// ================== IMesh events ==================
@Subscribe
public void createMesh(CreateMeshEvent event) throws VizException {
// TODO: Should we cache or should we expect data provider or even
// internal to the target?
int meshId = event.getObjectId();
IMesh mesh = target.getExtension(IMapMeshExtension.class)
.constructMesh(event.getImageGeometry(),
event.getTargetGeometry());
putRenderableObject(meshId, mesh);
}
@Subscribe
public void reprojectMesh(ReprojectMeshEvent event) throws VizException {
IMesh mesh = getRenderableObject(event.getObjectId(), IMesh.class);
if (mesh != null) {
mesh.reproject(event.getTargetGeometry());
}
}
// ================== Offscreen image events ==================
@Subscribe
public void createOffscreenImage(CreateOffscreenImageEvent event)
throws VizException {
try {
IImage offscreenImage = null;
IOffscreenRenderingExtension ext = target
.getExtension(IOffscreenRenderingExtension.class);
int[] dims = event.getDimensions();
if (event.getBufferType() != null) {
Class<? extends Buffer> bufferType = Class.forName(
event.getBufferType()).asSubclass(Buffer.class);
if (event.getColorMapParamters() != null) {
offscreenImage = ext.constructOffscreenImage(bufferType,
dims, event.getColorMapParamters()
.asColorMapParameters());
} else {
offscreenImage = ext.constructOffscreenImage(bufferType,
dims);
}
} else {
offscreenImage = ext.constructOffscreenImage(dims);
}
if (offscreenImage != null) {
putRenderableObject(event.getObjectId(), offscreenImage);
}
} catch (ClassNotFoundException e) {
throw new VizException("Could not find class for buffer type: "
+ event.getBufferType(), e);
}
}
@Subscribe
public void renderOffscreen(RenderOffscreenEvent event) throws VizException {
IImage offscreenImage = getRenderableObject(event.getObjectId(),
IImage.class);
if (offscreenImage != null) {
if (event.getExtent() != null) {
target.getExtension(IOffscreenRenderingExtension.class)
.renderOffscreen(offscreenImage, event.getIExtent());
} else {
target.getExtension(IOffscreenRenderingExtension.class)
.renderOffscreen(offscreenImage);
}
}
}
@Subscribe
public void renderOnscreen(RenderOnscreenEvent event) throws VizException {
target.getExtension(IOffscreenRenderingExtension.class)
.renderOnscreen();
}
}

View file

@ -33,6 +33,7 @@ import com.raytheon.uf.viz.core.drawables.PaintProperties;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
import com.raytheon.uf.viz.core.rsc.LoadProperties;
import com.raytheon.uf.viz.core.rsc.RenderingOrderFactory.ResourceOrder;
import com.raytheon.uf.viz.remote.graphics.AbstractRemoteGraphicsEvent;
import com.raytheon.uf.viz.remote.graphics.events.BeginFrameEvent;
import com.raytheon.uf.viz.remote.graphics.events.EndFrameEvent;
@ -91,6 +92,7 @@ public class CollaborationResource extends
@Override
protected void disposeInternal() {
renderingHandler.dispose();
renderingRouter.unregister(renderingHandler);
}
@Override
@ -161,6 +163,16 @@ public class CollaborationResource extends
}
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.rsc.AbstractVizResource#getResourceOrder()
*/
@Override
public ResourceOrder getResourceOrder() {
return ResourceOrder.LOWEST;
}
/*
* (non-Javadoc)
*

View file

@ -754,6 +754,13 @@ public interface IGraphicsTarget extends IImagingExtension {
public void drawPoint(double x, double y, double z, RGB color,
PointStyle pointStyle, float magnification) throws VizException;
/**
* Gets the targets current view
*
* @return
*/
public IView getView();
/**
* Notify the Graphics Target that there are updated extents that need to be
* set.

View file

@ -2,6 +2,7 @@ package com.raytheon.uf.viz.core.drawables.ext;
import java.nio.Buffer;
import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
import com.raytheon.uf.viz.core.drawables.IImage;
import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension.IGraphicsExtensionInterface;
@ -12,6 +13,8 @@ public interface IOffscreenRenderingExtension extends
/**
* All drawing between a call to renderOffscreen and the next call to
* renderOnscreen will be drawn to offscreenImage rather than to the screen.
* Will use the current screen's world as the coverage area for the
* offscreen image
*
* @param offscreenImage
* image to render to
@ -19,6 +22,19 @@ public interface IOffscreenRenderingExtension extends
*/
public void renderOffscreen(IImage offscreenImage) throws VizException;
/**
* All drawing between a call to renderOffscreen and the next call to
* renderOnscreen will be drawn to offscreenImage rather than to the screen.
* Will use the extent passed in as the world coverage area for the
* offscreen image
*
* @param offscreenImage
* @param offscreenExtent
* @throws VizException
*/
public void renderOffscreen(IImage offscreenImage, IExtent offscreenExtent)
throws VizException;
/**
* Reset rendering to the screen. This only needs to be called if
* renderOffscreen has been called.

View file

@ -28,5 +28,11 @@
<graphicsExtension
class="com.raytheon.uf.viz.remote.graphics.extensions.DispatchingMapMeshExtension">
</graphicsExtension>
<graphicsExtension
class="com.raytheon.uf.viz.remote.graphics.extensions.DispatchingOffscreenRenderingExtension">
</graphicsExtension>
<graphicsExtension
class="com.raytheon.uf.viz.remote.graphics.extensions.DispatchingImagingExtension">
</graphicsExtension>
</extension>
</plugin>

View file

@ -39,6 +39,7 @@ import com.raytheon.uf.viz.core.DrawableLine;
import com.raytheon.uf.viz.core.DrawableString;
import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.IView;
import com.raytheon.uf.viz.core.PixelCoverage;
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
import com.raytheon.uf.viz.core.data.IColormappedDataPreparer;
@ -662,7 +663,7 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
}
private void sendCreateWireframeShapeEvent(DispatchingWireframeShape shape,
Boolean mutable, GeneralGridGeometry geom,
boolean mutable, GeneralGridGeometry geom,
Float simplificationLevel, Boolean spatialChopFlag, IExtent extent) {
CreateWireframeShapeEvent event = RemoteGraphicsEventFactory
.createEvent(CreateWireframeShapeEvent.class, shape);
@ -839,6 +840,15 @@ public class DispatchGraphicsTarget extends DispatchingObject<IGraphicsTarget>
topRadius, sideCount, sliceCount, rotation, lean);
}
/**
* @return
* @see com.raytheon.uf.viz.core.IGraphicsTarget#getView()
*/
@Override
public IView getView() {
return wrappedObject.getView();
}
/**
* @return
* @see com.raytheon.uf.viz.core.IGraphicsTarget#getViewType()

View file

@ -22,7 +22,7 @@ package com.raytheon.uf.viz.remote.graphics.events;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
/**
* Event object for disposing of an image
* TODO Add Description
*
* <pre>
*
@ -38,6 +38,6 @@ import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
* @version 1.0
*/
@DynamicSerialize
public class DisposeImageEvent extends AbstractDispatchingObjectEvent {
public class DisposeObjectEvent extends AbstractDispatchingObjectEvent {
}

View file

@ -132,6 +132,8 @@ public class ColorMapDataEvent extends AbstractDispatchingObjectEvent {
ByteBuffer buffer = direct ? ByteBuffer
.allocateDirect(bytes.length) : ByteBuffer
.allocate(bytes.length);
buffer.put(bytes);
buffer.rewind();
Buffer dataBuffer = null;
switch (dataType) {
case BYTE:

View file

@ -19,6 +19,7 @@
**/
package com.raytheon.uf.viz.remote.graphics.events.colormap;
import com.raytheon.uf.common.colormap.ColorMap;
import com.raytheon.uf.common.colormap.IColorMap;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
@ -281,6 +282,29 @@ public class UpdateColorMapParametersEvent extends
this.useMask = useMask;
}
/**
* Get the update colormap parameters event as ColorMapParameters object
*
* @return
*/
public ColorMapParameters asColorMapParameters() {
ColorMapParameters params = new ColorMapParameters();
params.setAlphaMask(getAlphaMask());
params.setColorMapMin(getColorMapMin());
params.setColorMapMax(getColorMapMax());
params.setDataMin(getDataMin());
params.setDataMax(getDataMax());
params.setLogarithmic(isLogarithmic());
params.setLogFactor(getLogFactor());
params.setMirror(isMirror());
params.setUseMask(isUseMask());
if (red != null && green != null && blue != null && alpha != null) {
params.setColorMap(new ColorMap("" + getObjectId(), red, green,
blue, alpha));
}
return params;
}
public static UpdateColorMapParametersEvent createEvent(
DispatchingObject<?> creator, ColorMapParameters parameters) {
UpdateColorMapParametersEvent event = RemoteGraphicsEventFactory

View file

@ -44,6 +44,9 @@ import com.raytheon.uf.viz.remote.graphics.events.IRenderEvent;
public class PaintImagesEvent extends AbstractRemoteGraphicsEvent implements
IRenderEvent {
@DynamicSerializeElement
private float alpha;
@DynamicSerializeElement
private PaintImageEvent[] imageEvents;
@ -62,4 +65,19 @@ public class PaintImagesEvent extends AbstractRemoteGraphicsEvent implements
this.imageEvents = imageEvents;
}
/**
* @return the alpha
*/
public float getAlpha() {
return alpha;
}
/**
* @param alpha
* the alpha to set
*/
public void setAlpha(float alpha) {
this.alpha = alpha;
}
}

View file

@ -20,6 +20,7 @@
package com.raytheon.uf.viz.remote.graphics.events.imagery;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
/**
@ -41,11 +42,14 @@ import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent
@DynamicSerialize
public class UpdateImageDataEvent extends AbstractDispatchingObjectEvent {
private boolean interpolated;
@DynamicSerializeElement
private boolean interpolated = false;
private float brightness;
@DynamicSerializeElement
private float brightness = 1.0f;
private float contrast;
@DynamicSerializeElement
private float contrast = 1.0f;
/**
* @return the interpolated

View file

@ -20,6 +20,9 @@
package com.raytheon.uf.viz.remote.graphics.events.offscreen;
import com.raytheon.uf.common.serialization.annotations.DynamicSerialize;
import com.raytheon.uf.common.serialization.annotations.DynamicSerializeElement;
import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.PixelExtent;
import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.IRenderEvent;
@ -44,4 +47,43 @@ import com.raytheon.uf.viz.remote.graphics.events.IRenderEvent;
public class RenderOffscreenEvent extends AbstractDispatchingObjectEvent
implements IRenderEvent {
@DynamicSerializeElement
private double[] extent;
/**
* @return the extent
*/
public double[] getExtent() {
return extent;
}
/**
* @param extent
* the extent to set
*/
public void setExtent(double[] extent) {
this.extent = extent;
}
/**
* @return the iextent
*/
public IExtent getIExtent() {
if (extent != null) {
return new PixelExtent(extent[0], extent[1], extent[2], extent[3]);
}
return null;
}
/**
* @param iextent
* the iextent to set
*/
public void setIExtent(IExtent extent) {
if (extent != null) {
this.extent = new double[] { extent.getMinX(), extent.getMaxX(),
extent.getMinY(), extent.getMaxY() };
}
}
}

View file

@ -43,7 +43,7 @@ import com.raytheon.uf.viz.remote.graphics.events.AbstractDispatchingObjectEvent
public class SimpleWireframeShapeEvent extends AbstractDispatchingObjectEvent {
public static enum EventAction {
DISPOSE, RESET, CLEAR_LABELS, COMPILE;
RESET, CLEAR_LABELS, COMPILE;
}
@DynamicSerializeElement

View file

@ -119,9 +119,10 @@ public abstract class AbstractDispatchingImageExtension extends
PaintImagesEvent bulkRender = RemoteGraphicsEventFactory.createEvent(
PaintImagesEvent.class, target);
bulkRender.setImageEvents(imageEvents);
target.dispatch(bulkRender);
return target.getWrappedObject().drawRasters(paintProps,
bulkRender.setAlpha(paintProps.getAlpha());
boolean rval = target.getWrappedObject().drawRasters(paintProps,
targeted.toArray(new DrawableImage[targeted.size()]));
target.dispatch(bulkRender);
return rval;
}
}

View file

@ -77,7 +77,8 @@ public class DispatchingMapMeshExtension extends
@Override
public IMesh constructMesh(GridGeometry2D imageGeometry,
GeneralGridGeometry targetGeometry) throws VizException {
IMesh targetMesh = target.getExtension(IMapMeshExtension.class)
IMesh targetMesh = target.getWrappedObject()
.getExtension(IMapMeshExtension.class)
.constructMesh(imageGeometry, targetGeometry);
DispatchingMesh mesh = new DispatchingMesh(targetMesh,
target.getDispatcher());

View file

@ -21,6 +21,7 @@ package com.raytheon.uf.viz.remote.graphics.extensions;
import java.nio.Buffer;
import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
import com.raytheon.uf.viz.core.drawables.IImage;
import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension;
@ -65,14 +66,28 @@ public class DispatchingOffscreenRenderingExtension extends
*/
@Override
public void renderOffscreen(IImage offscreenImage) throws VizException {
renderOffscreen(offscreenImage, target.getView().getExtent());
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.drawables.ext.IOffscreenRenderingExtension#
* renderOffscreen(com.raytheon.uf.viz.core.drawables.IImage)
*/
@Override
public void renderOffscreen(IImage offscreenImage, IExtent extent)
throws VizException {
AbstractDispatchingImage<?> image = (AbstractDispatchingImage<?>) offscreenImage;
// Render off screen for target image
target.getWrappedObject()
.getExtension(IOffscreenRenderingExtension.class)
.renderOffscreen(image.getWrappedObject());
.renderOffscreen(image.getWrappedObject(), extent);
// Send event for offscreen rendering
image.dispatch(RemoteGraphicsEventFactory.createEvent(
RenderOffscreenEvent.class, image));
RenderOffscreenEvent event = RemoteGraphicsEventFactory.createEvent(
RenderOffscreenEvent.class, image);
event.setIExtent(extent);
image.dispatch(event);
}
/*
@ -99,7 +114,7 @@ public class DispatchingOffscreenRenderingExtension extends
*/
@Override
public IImage constructOffscreenImage(int[] dimensions) throws VizException {
IImage wrapped = target
IImage wrapped = target.getWrappedObject()
.getExtension(IOffscreenRenderingExtension.class)
.constructOffscreenImage(dimensions);
return createOffscreenImage(wrapped, null, dimensions, null);

View file

@ -60,7 +60,6 @@ public abstract class AbstractDispatchingColormappedImage<T extends IImage>
Dispatcher dispatcher, ColorMapParameters parameters) {
super(targetObject, extensionClass, dispatcher);
if (parameters != null) {
this.colorMap = parameters.getColorMap();
parameters.addListener(this);
}
}
@ -85,7 +84,7 @@ public abstract class AbstractDispatchingColormappedImage<T extends IImage>
ColorMapParameters parameters) {
UpdateColorMapParametersEvent event = UpdateColorMapParametersEvent
.createEvent(this, parameters);
if (parameters.getColorMap() == colorMap) {
if (parameters.getColorMap() == colorMap && colorMap != null) {
// Same colormap, discard cm data
event.setRed(null);
event.setBlue(null);

View file

@ -24,7 +24,7 @@ import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.remote.graphics.Dispatcher;
import com.raytheon.uf.viz.remote.graphics.DispatchingObject;
import com.raytheon.uf.viz.remote.graphics.events.DisposeImageEvent;
import com.raytheon.uf.viz.remote.graphics.events.DisposeObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.RemoteGraphicsEventFactory;
import com.raytheon.uf.viz.remote.graphics.events.imagery.UpdateImageDataEvent;
@ -49,7 +49,7 @@ import com.raytheon.uf.viz.remote.graphics.events.imagery.UpdateImageDataEvent;
public abstract class AbstractDispatchingImage<T extends IImage> extends
DispatchingObject<T> implements IImage {
protected boolean dirty = true;
protected boolean dirty = false;
protected UpdateImageDataEvent imageData;
@ -102,7 +102,7 @@ public abstract class AbstractDispatchingImage<T extends IImage> extends
wrappedObject.dispose();
// Dispatch the dispose
dispatch(RemoteGraphicsEventFactory.createEvent(
DisposeImageEvent.class, this));
DisposeObjectEvent.class, this));
}
/*

View file

@ -26,8 +26,8 @@ import com.raytheon.uf.viz.core.IMesh;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.remote.graphics.Dispatcher;
import com.raytheon.uf.viz.remote.graphics.DispatchingObject;
import com.raytheon.uf.viz.remote.graphics.events.DisposeObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.RemoteGraphicsEventFactory;
import com.raytheon.uf.viz.remote.graphics.events.mesh.DisposeMeshEvent;
import com.raytheon.uf.viz.remote.graphics.events.mesh.ReprojectMeshEvent;
/**
@ -67,7 +67,7 @@ public class DispatchingMesh extends DispatchingObject<IMesh> implements IMesh {
public void dispose() {
wrappedObject.dispose();
// Send event to dispose mesh
dispatch(RemoteGraphicsEventFactory.createEvent(DisposeMeshEvent.class,
dispatch(RemoteGraphicsEventFactory.createEvent(DisposeObjectEvent.class,
this));
}

View file

@ -30,6 +30,7 @@ import com.raytheon.uf.viz.core.drawables.IWireframeShape;
import com.raytheon.uf.viz.remote.graphics.Activator;
import com.raytheon.uf.viz.remote.graphics.Dispatcher;
import com.raytheon.uf.viz.remote.graphics.DispatchingObject;
import com.raytheon.uf.viz.remote.graphics.events.DisposeObjectEvent;
import com.raytheon.uf.viz.remote.graphics.events.RemoteGraphicsEventFactory;
import com.raytheon.uf.viz.remote.graphics.events.wireframe.AllocatePointsEvent;
import com.raytheon.uf.viz.remote.graphics.events.wireframe.SimpleWireframeShapeEvent;
@ -197,7 +198,8 @@ public class DispatchingWireframeShape extends
public void dispose() {
wrappedObject.dispose();
// Send dispose event
sendSimpleEvent(EventAction.DISPOSE);
dispatch(RemoteGraphicsEventFactory.createEvent(
DisposeObjectEvent.class, this));
shapeData = null;
}

View file

@ -25,6 +25,7 @@ import javax.media.opengl.glu.GLU;
import org.eclipse.swt.graphics.Rectangle;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.IView;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
import com.raytheon.viz.core.gl.objects.GLTextureObject;
@ -111,4 +112,10 @@ public interface IGLTarget extends IGraphicsTarget {
*/
public abstract void handleError(int errorid);
/**
* Set the targets current view
*
* @param view
*/
public void setView(IView view);
}

View file

@ -1,14 +1,16 @@
package com.raytheon.viz.core.gl.ext;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import java.util.Stack;
import javax.media.opengl.GL;
import org.eclipse.swt.graphics.Rectangle;
import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.IView;
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
import com.raytheon.uf.viz.core.data.IRenderedImageCallback;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
@ -21,17 +23,56 @@ import com.raytheon.viz.core.gl.dataformat.AbstractGLColorMapDataFormat;
import com.raytheon.viz.core.gl.dataformat.GLByteDataFormat;
import com.raytheon.viz.core.gl.dataformat.IGLColorMapDataFormatProvider;
import com.raytheon.viz.core.gl.images.AbstractGLImage;
import com.raytheon.viz.core.gl.internal.GLView2D;
import com.raytheon.viz.core.gl.internal.ext.GLColormappedImageExtension;
public class GLOffscreenRenderingExtension extends GraphicsExtension<IGLTarget>
implements IOffscreenRenderingExtension {
private static class ViewInfo {
private IView view;
private AbstractGLImage image;
/**
* @param extent
* @param bounds
*/
public ViewInfo(IView view, AbstractGLImage image) {
this.view = view;
this.image = image;
}
}
private static boolean checkedLuminance = false;
private static boolean supportsLuminance = true;
private Stack<ViewInfo> viewStack = new Stack<ViewInfo>();
private ViewInfo currentInfo = null;
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.drawables.ext.IOffscreenRenderingExtension#
* renderOffscreen(com.raytheon.uf.viz.core.drawables.IImage)
*/
@Override
public void renderOffscreen(IImage offscreenImage) throws VizException {
renderOffscreen(offscreenImage, target.getView().getExtent());
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.drawables.ext.IOffscreenRenderingExtension#
* renderOffscreen(com.raytheon.uf.viz.core.drawables.IImage,
* com.raytheon.uf.viz.core.IExtent)
*/
@Override
public void renderOffscreen(IImage offscreenImage, IExtent offscreenExtent)
throws VizException {
if (!(offscreenImage instanceof AbstractGLImage)) {
throw new VizException(
"Can only use GLImages as offscreen frameBuffer on GLTarget");
@ -46,16 +87,44 @@ public class GLOffscreenRenderingExtension extends GraphicsExtension<IGLTarget>
if (glImage.getStatus() == IImage.Status.STAGED) {
glImage.target(target);
}
target.getGl()
.glViewport(0, 0, glImage.getWidth(), glImage.getHeight());
glImage.usaAsFrameBuffer();
IView view = new GLView2D(offscreenExtent);
if (currentInfo == null) {
// Use null for image so we use canvas when we pop
viewStack.push(new ViewInfo(target.getView(), null));
} else {
viewStack.push(currentInfo);
}
setCurrentView(new ViewInfo(view, glImage));
}
@Override
public void renderOnscreen() throws VizException {
Rectangle canvasSize = target.getBounds();
target.getGl().glViewport(0, 0, canvasSize.width, canvasSize.height);
target.getGl().glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);
if (viewStack.size() > 0) {
setCurrentView(viewStack.pop());
}
}
private void setCurrentView(ViewInfo current) throws VizException {
currentInfo = current;
Rectangle bounds = null;
if (currentInfo.image == null) {
// Null bounds means use current targets bounds
bounds = new Rectangle(target.getBounds().width,
target.getBounds().height);
// Set currentInfo to null since we are using screen/display info
// and we don't want to cache old info
currentInfo = null;
target.getGl().glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);
} else {
bounds = new Rectangle(currentInfo.image.getWidth(),
currentInfo.image.getHeight());
currentInfo.image.usaAsFrameBuffer();
}
target.setView(current.view);
target.getGl().glViewport(0, 0, bounds.width, bounds.height);
}
/*

View file

@ -110,15 +110,17 @@ public class GLCMTextureData implements IImageCacheable {
// OK, Fetch the data
ColorMapData cmData = callback.getColorMapData();
IGLColorMapDataFormatProvider glDataFormatCallback = IGLColorMapDataFormatProvider.defaultCallback;
if (callback instanceof IGLColorMapDataFormatProvider) {
glDataFormatCallback = (IGLColorMapDataFormatProvider) callback;
}
data = new GLColorMapData(cmData,
glDataFormatCallback.getGLColorMapDataFormat(cmData));
if (isStaged()) {
ImageCache.getInstance(CacheType.MEMORY).put(this);
return true;
if (cmData != null) {
IGLColorMapDataFormatProvider glDataFormatCallback = IGLColorMapDataFormatProvider.defaultCallback;
if (callback instanceof IGLColorMapDataFormatProvider) {
glDataFormatCallback = (IGLColorMapDataFormatProvider) callback;
}
data = new GLColorMapData(cmData,
glDataFormatCallback.getGLColorMapDataFormat(cmData));
if (isStaged()) {
ImageCache.getInstance(CacheType.MEMORY).put(this);
return true;
}
}
// The data fetch didn't go well
return false;

View file

@ -67,6 +67,7 @@ import com.raytheon.uf.viz.core.DrawableLine;
import com.raytheon.uf.viz.core.DrawableString;
import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.IView;
import com.raytheon.uf.viz.core.PixelCoverage;
import com.raytheon.uf.viz.core.VizConstants;
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
@ -184,7 +185,7 @@ public class GLTarget implements IGLTarget {
.getInstance().getBoolean("-no_shader");
/** The current visible extent */
protected IExtent viewExtent;
protected IView targetView;
protected IExtent updatedExtent;
@ -392,7 +393,7 @@ public class GLTarget implements IGLTarget {
this.updatedExtent = null;
}
viewExtent = display.getExtent().clone();
this.targetView = display.getView();
makeContextCurrent();
@ -400,6 +401,7 @@ public class GLTarget implements IGLTarget {
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
}
IExtent viewExtent = targetView.getExtent();
theCurrentZoom = (viewExtent.getMaxY() - viewExtent.getMinY())
/ theHeight;
@ -1399,8 +1401,9 @@ public class GLTarget implements IGLTarget {
if (shape instanceof GLWireframeShape2D) {
pushGLState();
try {
((GLWireframeShape2D) shape).paint(this, viewExtent,
canvasSize, aColor, lineWidth, lineStyle, font, alpha);
((GLWireframeShape2D) shape).paint(this,
targetView.getExtent(), canvasSize, aColor, lineWidth,
lineStyle, font, alpha);
} finally {
popGLState();
}
@ -1415,7 +1418,7 @@ public class GLTarget implements IGLTarget {
throws VizException {
this.pushGLState();
try {
IExtent viewExtent = targetView.getExtent();
boolean usedStencilBuffer = false;
Map<double[], String> labels = shape.getLabelMap();
@ -1439,7 +1442,7 @@ public class GLTarget implements IGLTarget {
Rectangle2D bounds = null;
for (Entry<double[], String> entry : entrySet) {
double[] pos = entry.getKey();
if (this.viewExtent.contains(pos)) {
if (viewExtent.contains(pos)) {
bounds = this.getStringBounds(font, entry.getValue());
gl.glPolygonMode(GL.GL_BACK, GL.GL_FILL);
@ -1478,7 +1481,7 @@ public class GLTarget implements IGLTarget {
int[] spatialZones = new int[] { 0 };
if (level != 0) {
spatialZones = shape.getSpatialIndices(this.viewExtent);
spatialZones = shape.getSpatialIndices(viewExtent);
}
gl.glEnable(GL.GL_BLEND);
@ -1536,7 +1539,7 @@ public class GLTarget implements IGLTarget {
entrySet.size());
for (Entry<double[], String> entry : entrySet) {
double[] pos = entry.getKey();
if (this.viewExtent.contains(pos)) {
if (viewExtent.contains(pos)) {
DrawableString string = new DrawableString(
entry.getValue(), color);
string.font = font;
@ -1614,12 +1617,12 @@ public class GLTarget implements IGLTarget {
}
private double getScaleX() {
return viewExtent.getWidth() / this.canvasSize.width;
return targetView.getExtent().getWidth() / this.canvasSize.width;
}
private double getScaleY() {
return viewExtent.getHeight() / this.canvasSize.height;
return targetView.getExtent().getHeight() / this.canvasSize.height;
}
@ -2299,6 +2302,29 @@ public class GLTarget implements IGLTarget {
this.updatedExtent = updatedExtent;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.uf.viz.core.IGraphicsTarget#getView()
*/
@Override
public IView getView() {
return targetView;
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.core.gl.IGLTarget#setView(com.raytheon.uf.viz.core.IView
* )
*/
@Override
public void setView(IView view) {
this.targetView = view;
this.targetView.setupView(this);
}
/*
* (non-Javadoc)
*

View file

@ -75,7 +75,7 @@ public class GLView2D implements IView {
this(rect.x, rect.x + rect.width, rect.y, rect.y + rect.height);
}
public GLView2D(PixelExtent pe) {
public GLView2D(IExtent pe) {
this.extent = pe;
}