Merge "Issue #2333 Merging gl refactor from GOES-R work. Preparing GL for data units in image." into development
Former-commit-id: 41462b804bf079368bead7c1271b1abdb7d4bf63
This commit is contained in:
commit
50bf735240
30 changed files with 1335 additions and 636 deletions
|
@ -27,12 +27,16 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.measure.unit.Unit;
|
||||
import javax.measure.unit.UnitFormat;
|
||||
|
||||
import org.geotools.coverage.grid.GridEnvelope2D;
|
||||
import org.geotools.coverage.grid.GridGeometry2D;
|
||||
import org.geotools.geometry.Envelope2D;
|
||||
import org.opengis.coverage.grid.GridEnvelope;
|
||||
|
||||
import com.raytheon.uf.common.colormap.image.ColorMapData;
|
||||
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
||||
import com.raytheon.uf.common.dataplugin.PluginDataObject;
|
||||
import com.raytheon.uf.common.datastorage.DataStoreFactory;
|
||||
import com.raytheon.uf.common.geospatial.ISpatialObject;
|
||||
|
@ -55,6 +59,7 @@ import com.raytheon.uf.viz.core.map.IMapMeshExtension;
|
|||
import com.raytheon.uf.viz.core.rsc.AbstractVizResource;
|
||||
import com.raytheon.uf.viz.core.rsc.capabilities.ColorMapCapability;
|
||||
import com.raytheon.uf.viz.core.rsc.capabilities.ImagingCapability;
|
||||
import com.vividsolutions.jts.geom.Coordinate;
|
||||
|
||||
/**
|
||||
* {@link TileSetRenderable} for 2D {@link PluginDataObject}s. Groups adjacent
|
||||
|
@ -68,7 +73,9 @@ import com.raytheon.uf.viz.core.rsc.capabilities.ImagingCapability;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 19, 2013 2122 mschenke Initial creation.
|
||||
* Jun 19, 2013 2122 mschenke Initial creation.
|
||||
* Oct 16, 2013 2333 mschenke Added method for auto-unit conversion
|
||||
* interrogating
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -199,7 +206,7 @@ public class RecordTileSetRenderable extends TileSetRenderable {
|
|||
BufferSlicer.slice(data.getBuffer(),
|
||||
tileRect, bigTileRect), new int[] {
|
||||
tileRect.width, tileRect.height },
|
||||
data.getDataType());
|
||||
data.getDataType(), data.getDataUnit());
|
||||
|
||||
callbacks.get(i).setRetrievedData(subData);
|
||||
try {
|
||||
|
@ -353,6 +360,69 @@ public class RecordTileSetRenderable extends TileSetRenderable {
|
|||
tile.getRectangle()).getColorMapData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double interrogate(Coordinate coordinate) throws VizException {
|
||||
ColorMapParameters parameters = colormapping.getColorMapParameters();
|
||||
return interrogate(coordinate, parameters.getNoDataValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw image value from tile image that contains the lat/lon
|
||||
* coordinate in units of desiredUnit
|
||||
*
|
||||
* @param coordinate
|
||||
* in lat/lon space
|
||||
* @param desiredUnit
|
||||
* unit to convert data value to if not nanValue
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
public double interrogate(Coordinate coordinate, Unit<?> desiredUnit)
|
||||
throws VizException {
|
||||
ColorMapParameters parameters = colormapping.getColorMapParameters();
|
||||
return interrogate(coordinate, parameters.getNoDataValue(), desiredUnit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw image value from tile image that contains the lat/lon
|
||||
* coordinate in units of desiredUnit
|
||||
*
|
||||
* @param coordinate
|
||||
* in lat/lon space
|
||||
* @param nanValue
|
||||
* if interrogated value is equal to nanValue, {@link Double#NaN}
|
||||
* will be returned
|
||||
* @param desiredUnit
|
||||
* unit to convert data value to if not nanValue
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
public double interrogate(Coordinate coordinate, double nanValue,
|
||||
Unit<?> desiredUnit) throws VizException {
|
||||
double dataValue = super.interrogate(coordinate, nanValue);
|
||||
if (Double.isNaN(dataValue) == false) {
|
||||
ColorMapParameters params = colormapping.getColorMapParameters();
|
||||
Unit<?> dataUnit = params.getDataUnit();
|
||||
if (dataUnit != null && desiredUnit != null
|
||||
&& dataUnit != desiredUnit) {
|
||||
if (dataUnit.isCompatible(desiredUnit)) {
|
||||
dataValue = dataUnit.getConverterTo(desiredUnit).convert(
|
||||
dataValue);
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to interrogate tile set. "
|
||||
+ String.format(
|
||||
"Desired unit (%s) is not compatible with data unit (%s).",
|
||||
UnitFormat.getUCUMInstance()
|
||||
.format(desiredUnit),
|
||||
UnitFormat.getUCUMInstance()
|
||||
.format(dataUnit)));
|
||||
}
|
||||
}
|
||||
}
|
||||
return dataValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param target
|
||||
*/
|
||||
|
|
|
@ -62,11 +62,12 @@ import com.vividsolutions.jts.geom.Coordinate;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 8, 2012 mschenke Initial creation
|
||||
* May 28, 2013 2037 njensen Made imageMap concurrent to fix leak
|
||||
* Jun 20, 2013 2122 mschenke Fixed null pointer in interrogate and made
|
||||
* canceling jobs safer
|
||||
*
|
||||
* Aug 8, 2012 mschenke Initial creation
|
||||
* May 28, 2013 2037 njensen Made imageMap concurrent to fix leak
|
||||
* Jun 20, 2013 2122 mschenke Fixed null pointer in interrogate and made
|
||||
* canceling jobs safer
|
||||
* Oct 16, 2013 2333 mschenke Added auto NaN checking for interrogation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
|
@ -474,6 +475,24 @@ public class TileSetRenderable implements IRenderable {
|
|||
* @throws VizException
|
||||
*/
|
||||
public double interrogate(Coordinate coordinate) throws VizException {
|
||||
return interrogate(coordinate, Double.NaN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the raw image value from tile image that contains the lat/lon
|
||||
* coordinate. Any values matching nanValue will return {@link Double#NaN}
|
||||
*
|
||||
* @param coordinate
|
||||
* in lat/lon space
|
||||
* @param nanValue
|
||||
* if interrogated value is equal to nanValue, {@link Double#NaN}
|
||||
* will be returned
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
public double interrogate(Coordinate coordinate, double nanValue)
|
||||
throws VizException {
|
||||
double dataValue = Double.NaN;
|
||||
try {
|
||||
double[] local = new double[2];
|
||||
llToLocalProj
|
||||
|
@ -490,15 +509,20 @@ public class TileSetRenderable implements IRenderable {
|
|||
if (di != null) {
|
||||
IImage image = di.getImage();
|
||||
if (image instanceof IColormappedImage) {
|
||||
return ((IColormappedImage) image).getValue(
|
||||
IColormappedImage cmapImage = (IColormappedImage) image;
|
||||
dataValue = cmapImage.getValue(
|
||||
(int) grid[0] % tileSize, (int) grid[1]
|
||||
% tileSize);
|
||||
if (dataValue == nanValue) {
|
||||
dataValue = Double.NaN;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (TransformException e) {
|
||||
throw new VizException("Error interrogating ", e);
|
||||
}
|
||||
return Double.NaN;
|
||||
return dataValue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ public class GLTrueColorImagingExtension extends AbstractGLSLImagingExtension
|
|||
GLOffscreenRenderingExtension extension = target
|
||||
.getExtension(GLOffscreenRenderingExtension.class);
|
||||
try {
|
||||
extension.renderOffscreen(trueColorImage,
|
||||
extension.beginOffscreenRendering(trueColorImage,
|
||||
trueColorImage.getImageExtent());
|
||||
boolean allPainted = true;
|
||||
for (Channel channel : Channel.values()) {
|
||||
|
@ -145,7 +145,8 @@ public class GLTrueColorImagingExtension extends AbstractGLSLImagingExtension
|
|||
}
|
||||
}
|
||||
} catch (VizException e) {
|
||||
extension.renderOnscreen();
|
||||
// Exception: end rendering now instead of postImageRender
|
||||
extension.endOffscreenRendering();
|
||||
throw e;
|
||||
}
|
||||
renderingChannel = null;
|
||||
|
@ -180,7 +181,7 @@ public class GLTrueColorImagingExtension extends AbstractGLSLImagingExtension
|
|||
AbstractGLImage image, Object data) throws VizException {
|
||||
if (image instanceof GLTrueColorImage) {
|
||||
target.getExtension(GLOffscreenRenderingExtension.class)
|
||||
.renderOnscreen();
|
||||
.endOffscreenRendering();
|
||||
target.drawRasters(paintProps, new DrawableImage(
|
||||
((GLTrueColorImage) image).getWrappedImage(),
|
||||
(PixelCoverage) data));
|
||||
|
|
|
@ -32,7 +32,8 @@ import javax.media.opengl.GL;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Nov 21, 2011 mschenke Initial creation
|
||||
* Nov 21, 2011 mschenke Initial creation
|
||||
* Oct 16, 2013 2333 mschenke Removed Buffer from GLColorMapData
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -83,6 +84,16 @@ public abstract class AbstractGLColorMapDataFormat {
|
|||
*/
|
||||
public abstract double getDataFormatMax();
|
||||
|
||||
/**
|
||||
* Returns true if the data format is a signed data format (values in format
|
||||
* can be less than 0), false otherwise
|
||||
*
|
||||
* @return true if signed format
|
||||
*/
|
||||
public boolean isSignedFormat() {
|
||||
return getDataFormatMin() < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a buffer object for specified data for copying data from out of GL
|
||||
*
|
||||
|
@ -93,8 +104,7 @@ public abstract class AbstractGLColorMapDataFormat {
|
|||
|
||||
/**
|
||||
* Specifies if the data format type's values are scaled when copied to GL
|
||||
* and referenced in shader. True means the values will by default be scaled
|
||||
* to -1 to 1, false indicates shader will receive values as is
|
||||
* and referenced in shader.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
@ -108,9 +118,11 @@ public abstract class AbstractGLColorMapDataFormat {
|
|||
* @param x
|
||||
* @param y
|
||||
* @param data
|
||||
* @param dataBuffer
|
||||
* @return
|
||||
*/
|
||||
public abstract Number getValue(int x, int y, GLColorMapData data);
|
||||
public abstract Number getValue(int x, int y, GLColorMapData data,
|
||||
Buffer dataBuffer);
|
||||
|
||||
/**
|
||||
* Get the number of bytes each pixel takes up
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.viz.core.gl.dataformat;
|
||||
|
||||
import java.nio.Buffer;
|
||||
|
||||
import javax.measure.unit.Unit;
|
||||
|
||||
import com.raytheon.uf.common.colormap.image.ColorMapData;
|
||||
|
||||
/**
|
||||
* GLColorMapData backed by a java Buffer
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 16, 2013 2333 mschenke Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class GLBufferColorMapData extends GLColorMapData {
|
||||
|
||||
private Buffer data;
|
||||
|
||||
private int textureType;
|
||||
|
||||
private Unit<?> dataUnit;
|
||||
|
||||
public GLBufferColorMapData(ColorMapData cmData,
|
||||
AbstractGLColorMapDataFormat dataFormat) {
|
||||
super(dataFormat, cmData.getDataType(), cmData.getDimensions());
|
||||
this.textureType = dataFormat.getTextureType();
|
||||
this.data = dataFormat.formatForGL(cmData.getBuffer(), this);
|
||||
this.dataUnit = cmData.getDataUnit();
|
||||
}
|
||||
|
||||
public Buffer getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Buffer data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Buffer getCopybackBuffer() {
|
||||
return dataFormat.getCopybackBuffer(this);
|
||||
}
|
||||
|
||||
public int getCopyBackTextureType() {
|
||||
return dataFormat.getCopyBackTextureType();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.dataformat.GLColorMapData#getTextureType()
|
||||
*/
|
||||
@Override
|
||||
public int getTextureType() {
|
||||
return textureType;
|
||||
}
|
||||
|
||||
public void setTextureType(int textureType) {
|
||||
this.textureType = textureType;
|
||||
}
|
||||
|
||||
public Number getValue(int x, int y) {
|
||||
return dataFormat.getValue(x, y, this, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public Unit<?> getDataUnit() {
|
||||
return dataUnit;
|
||||
}
|
||||
|
||||
}
|
|
@ -110,8 +110,7 @@ public class GLByteDataFormat extends AbstractGLColorMapDataFormat {
|
|||
* (int, int, java.nio.Buffer)
|
||||
*/
|
||||
@Override
|
||||
public Short getValue(int x, int y, GLColorMapData data) {
|
||||
Buffer dataBuffer = data.getData();
|
||||
public Short getValue(int x, int y, GLColorMapData data, Buffer dataBuffer) {
|
||||
if (data.getTextureType() != GL.GL_UNSIGNED_BYTE) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot process texture of type " + data.getTextureType());
|
||||
|
|
|
@ -19,10 +19,7 @@
|
|||
**/
|
||||
package com.raytheon.viz.core.gl.dataformat;
|
||||
|
||||
import java.nio.Buffer;
|
||||
|
||||
import com.raytheon.uf.common.colormap.image.ColorMapData;
|
||||
import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -34,7 +31,8 @@ import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 10, 2011 bsteffen Initial creation
|
||||
* Aug 10, 2011 bsteffen Initial creation
|
||||
* Oct 16, 2013 2333 mschenke Removed Buffer from this object
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -43,31 +41,17 @@ import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
|
|||
*/
|
||||
public class GLColorMapData {
|
||||
|
||||
private final AbstractGLColorMapDataFormat dataFormat;
|
||||
protected final AbstractGLColorMapDataFormat dataFormat;
|
||||
|
||||
private Buffer data;
|
||||
private final int[] dimensions;
|
||||
|
||||
private int[] dimensions;
|
||||
private final ColorMapData.ColorMapDataType dataType;
|
||||
|
||||
private ColorMapData.ColorMapDataType dataType;
|
||||
|
||||
private int textureType;
|
||||
|
||||
public GLColorMapData(ColorMapData cmData,
|
||||
AbstractGLColorMapDataFormat dataFormat) {
|
||||
public GLColorMapData(AbstractGLColorMapDataFormat dataFormat,
|
||||
ColorMapData.ColorMapDataType dataType, int[] dimensions) {
|
||||
this.dataFormat = dataFormat;
|
||||
this.dimensions = cmData.getDimensions();
|
||||
this.dataType = cmData.getDataType();
|
||||
this.textureType = dataFormat.getTextureType();
|
||||
this.data = dataFormat.formatForGL(cmData.getBuffer(), this);
|
||||
}
|
||||
|
||||
public Buffer getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(Buffer data) {
|
||||
this.data = data;
|
||||
this.dataType = dataType;
|
||||
this.dimensions = dimensions;
|
||||
}
|
||||
|
||||
public int getTextureFormat() {
|
||||
|
@ -79,21 +63,13 @@ public class GLColorMapData {
|
|||
}
|
||||
|
||||
public int getTextureType() {
|
||||
return textureType;
|
||||
}
|
||||
|
||||
public void setTextureType(int textureType) {
|
||||
this.textureType = textureType;
|
||||
return dataFormat.getTextureType();
|
||||
}
|
||||
|
||||
public ColorMapData.ColorMapDataType getDataType() {
|
||||
return dataType;
|
||||
}
|
||||
|
||||
public int getCopyBackTextureType() {
|
||||
return dataFormat.getCopyBackTextureType();
|
||||
}
|
||||
|
||||
public double getDataFormatMin() {
|
||||
return dataFormat.getDataFormatMin();
|
||||
}
|
||||
|
@ -106,12 +82,8 @@ public class GLColorMapData {
|
|||
return dataFormat.isScaled();
|
||||
}
|
||||
|
||||
public Buffer getCopybackBuffer() {
|
||||
return dataFormat.getCopybackBuffer(this);
|
||||
}
|
||||
|
||||
public Number getValue(int x, int y) {
|
||||
return dataFormat.getValue(x, y, this);
|
||||
public boolean isDataFormatSigned() {
|
||||
return dataFormat.isSignedFormat();
|
||||
}
|
||||
|
||||
public int getDimensionSize(int index) {
|
||||
|
|
|
@ -107,18 +107,18 @@ public class GLFloatDataFormat extends AbstractGLColorMapDataFormat {
|
|||
* (int, int, com.raytheon.viz.core.gl.dataprep.GLColorMapData)
|
||||
*/
|
||||
@Override
|
||||
public Float getValue(int x, int y, GLColorMapData data) {
|
||||
public Float getValue(int x, int y, GLColorMapData data, Buffer dataBuffer) {
|
||||
if (data.getTextureType() != GL.GL_FLOAT) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot process texture of type " + data.getTextureType());
|
||||
} else if (!(data.getData() instanceof FloatBuffer)) {
|
||||
} else if (!(dataBuffer instanceof FloatBuffer)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Expecting data to contain a FloatBuffer but instead it is a "
|
||||
+ data.getData().getClass().getSimpleName());
|
||||
+ dataBuffer.getClass().getSimpleName());
|
||||
}
|
||||
int width = data.getDimensionSize(0);
|
||||
int index = y * width + x;
|
||||
FloatBuffer buffer = (FloatBuffer) data.getData();
|
||||
FloatBuffer buffer = (FloatBuffer) dataBuffer;
|
||||
return buffer.get(index);
|
||||
}
|
||||
|
||||
|
|
|
@ -121,18 +121,18 @@ public class GLHalfFloatDataFormat extends AbstractGLColorMapDataFormat {
|
|||
* (int, int, com.raytheon.viz.core.gl.dataprep.GLColorMapData)
|
||||
*/
|
||||
@Override
|
||||
public Float getValue(int x, int y, GLColorMapData data) {
|
||||
public Float getValue(int x, int y, GLColorMapData data, Buffer dataBuffer) {
|
||||
if (data.getTextureType() != GL.GL_HALF_FLOAT_ARB) {
|
||||
throw new IllegalArgumentException(
|
||||
"Cannot process texture of type " + data.getTextureType());
|
||||
} else if (!(data.getData() instanceof ShortBuffer)) {
|
||||
} else if (!(dataBuffer instanceof ShortBuffer)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Expecting data to contain a ShortBuffer but instead it is a "
|
||||
+ data.getData().getClass().getSimpleName());
|
||||
+ dataBuffer.getClass().getSimpleName());
|
||||
}
|
||||
int width = getAlignedWidth(data.getDimensionSize(0));
|
||||
int index = y * width + x;
|
||||
ShortBuffer buffer = (ShortBuffer) data.getData();
|
||||
ShortBuffer buffer = (ShortBuffer) dataBuffer;
|
||||
return convertFromFloat16(buffer.get(index));
|
||||
}
|
||||
|
||||
|
|
|
@ -100,15 +100,15 @@ public class GLIntDataFormat extends AbstractGLColorMapDataFormat {
|
|||
* (int, int, com.raytheon.viz.core.gl.dataprep.GLColorMapData)
|
||||
*/
|
||||
@Override
|
||||
public Integer getValue(int x, int y, GLColorMapData data) {
|
||||
if (!(data.getData() instanceof IntBuffer)) {
|
||||
public Integer getValue(int x, int y, GLColorMapData data, Buffer dataBuffer) {
|
||||
if (!(dataBuffer instanceof IntBuffer)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Expecting data to contain a IntBuffer but instead it is a "
|
||||
+ data.getData().getClass().getSimpleName());
|
||||
+ dataBuffer.getClass().getSimpleName());
|
||||
}
|
||||
int width = data.getDimensionSize(0);
|
||||
int index = y * width + x;
|
||||
IntBuffer buffer = (IntBuffer) data.getData();
|
||||
IntBuffer buffer = (IntBuffer) dataBuffer;
|
||||
int value = buffer.get(index);
|
||||
switch (data.getTextureType()) {
|
||||
case GL.GL_INT:
|
||||
|
|
|
@ -105,15 +105,15 @@ public class GLShortDataFormat extends AbstractGLColorMapDataFormat {
|
|||
* (int, int, com.raytheon.viz.core.gl.dataprep.GLColorMapData)
|
||||
*/
|
||||
@Override
|
||||
public Number getValue(int x, int y, GLColorMapData data) {
|
||||
if (!(data.getData() instanceof ShortBuffer)) {
|
||||
public Number getValue(int x, int y, GLColorMapData data, Buffer dataBuffer) {
|
||||
if (!(dataBuffer instanceof ShortBuffer)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Expecting data to contain a ShortBuffer but instead it is a "
|
||||
+ data.getData().getClass().getSimpleName());
|
||||
+ dataBuffer.getClass().getSimpleName());
|
||||
}
|
||||
int width = getAlignedWidth(data.getDimensionSize(0));
|
||||
int index = y * width + x;
|
||||
ShortBuffer buffer = (ShortBuffer) data.getData();
|
||||
ShortBuffer buffer = (ShortBuffer) dataBuffer;
|
||||
short value = buffer.get(index);
|
||||
switch (data.getTextureType()) {
|
||||
case GL.GL_SHORT:
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
**/
|
||||
package com.raytheon.viz.core.gl.dataformat;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import javax.media.opengl.GL;
|
||||
|
@ -49,15 +50,15 @@ public class GLSignedByteDataFormat extends GLByteDataFormat {
|
|||
* int, com.raytheon.viz.core.gl.dataprep.GLColorMapData)
|
||||
*/
|
||||
@Override
|
||||
public Short getValue(int x, int y, GLColorMapData data) {
|
||||
if (!(data.getData() instanceof ByteBuffer)) {
|
||||
public Short getValue(int x, int y, GLColorMapData data, Buffer dataBuffer) {
|
||||
if (!(dataBuffer instanceof ByteBuffer)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Expecting data to contain a ByteBuffer but instead it is a "
|
||||
+ data.getData().getClass().getSimpleName());
|
||||
+ dataBuffer.getClass().getSimpleName());
|
||||
}
|
||||
int width = getAlignedWidth(data.getDimensionSize(0));
|
||||
int index = y * width + x;
|
||||
ByteBuffer buffer = (ByteBuffer) data.getData();
|
||||
ByteBuffer buffer = (ByteBuffer) dataBuffer;
|
||||
byte value = buffer.get(index);
|
||||
switch (data.getTextureType()) {
|
||||
case GL.GL_BYTE:
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
**/
|
||||
package com.raytheon.viz.core.gl.dataformat;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import javax.media.opengl.GL;
|
||||
|
@ -82,15 +83,15 @@ public class GLUnsignedShortDataFormat extends GLShortDataFormat {
|
|||
* int, com.raytheon.viz.core.gl.dataformat.GLColorMapData)
|
||||
*/
|
||||
@Override
|
||||
public Number getValue(int x, int y, GLColorMapData data) {
|
||||
if (!(data.getData() instanceof ShortBuffer)) {
|
||||
public Number getValue(int x, int y, GLColorMapData data, Buffer dataBuffer) {
|
||||
if (!(dataBuffer instanceof ShortBuffer)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Expecting data to contain a ShortBuffer but instead it is a "
|
||||
+ data.getData().getClass().getSimpleName());
|
||||
+ dataBuffer.getClass().getSimpleName());
|
||||
}
|
||||
int width = getAlignedWidth(data.getDimensionSize(0));
|
||||
int index = y * width + x;
|
||||
ShortBuffer buffer = (ShortBuffer) data.getData();
|
||||
ShortBuffer buffer = (ShortBuffer) dataBuffer;
|
||||
return (buffer.get(index) & 0xFFFF);
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ public interface IGLColorMapDataFormatProvider {
|
|||
public AbstractGLColorMapDataFormat getGLColorMapDataFormat(
|
||||
ColorMapData colorMapData) {
|
||||
return GLColorMapDataFormatFactory
|
||||
.getGLColorMapDataFormat(colorMapData);
|
||||
.getGLColorMapDataFormat(colorMapData.getDataType());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -22,18 +22,14 @@ 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 com.raytheon.uf.common.colormap.image.ColorMapData;
|
||||
import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
|
||||
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
||||
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.IImage;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.GraphicsExtension;
|
||||
|
@ -42,11 +38,13 @@ import com.raytheon.uf.viz.core.exception.VizException;
|
|||
import com.raytheon.viz.core.gl.IGLTarget;
|
||||
import com.raytheon.viz.core.gl.dataformat.AbstractGLColorMapDataFormat;
|
||||
import com.raytheon.viz.core.gl.dataformat.GLByteDataFormat;
|
||||
import com.raytheon.viz.core.gl.dataformat.GLColorMapData;
|
||||
import com.raytheon.viz.core.gl.dataformat.GLColorMapDataFormatFactory;
|
||||
import com.raytheon.viz.core.gl.dataformat.IGLColorMapDataFormatProvider;
|
||||
import com.raytheon.viz.core.gl.ext.imaging.GLColormappedImageExtension;
|
||||
import com.raytheon.viz.core.gl.ext.imaging.GLDefaultImagingExtension;
|
||||
import com.raytheon.viz.core.gl.images.AbstractGLImage;
|
||||
import com.raytheon.viz.core.gl.images.GLColormappedImage;
|
||||
import com.raytheon.viz.core.gl.images.GLImage;
|
||||
import com.raytheon.viz.core.gl.images.GLOffscreenColormappedImage;
|
||||
import com.raytheon.viz.core.gl.internal.GLView2D;
|
||||
|
||||
/**
|
||||
|
@ -97,17 +95,29 @@ public class GLOffscreenRenderingExtension extends GraphicsExtension<IGLTarget>
|
|||
|
||||
private ViewInfo currentInfo = null;
|
||||
|
||||
public void renderOffscreen(IImage offscreenImage) throws VizException {
|
||||
renderOffscreen(offscreenImage, target.getView().getExtent());
|
||||
/**
|
||||
* Begins offscreen rendering to the glImage. All rendering after this call
|
||||
* will occur on the image until {@link #endOffscreenRendering()} is called.
|
||||
* Render area will be set to the current view's extent
|
||||
*
|
||||
* @param glImage
|
||||
* @throws VizException
|
||||
*/
|
||||
public void beginOffscreenRendering(AbstractGLImage glImage)
|
||||
throws VizException {
|
||||
beginOffscreenRendering(glImage, target.getView().getExtent());
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
AbstractGLImage glImage = (AbstractGLImage) offscreenImage;
|
||||
/**
|
||||
* Begins offscreen rendering to the glImage. All rendering after this call
|
||||
* will occur on the image until {@link #endOffscreenRendering()} is called.
|
||||
* Render area will be set to the offscreenExtent provided
|
||||
*
|
||||
* @param glImage
|
||||
* @throws VizException
|
||||
*/
|
||||
public void beginOffscreenRendering(AbstractGLImage glImage,
|
||||
IExtent offscreenExtent) throws VizException {
|
||||
if (glImage.getStatus() == IImage.Status.UNLOADED
|
||||
|| glImage.getStatus() == IImage.Status.LOADING) {
|
||||
glImage.setStatus(IImage.Status.LOADING);
|
||||
|
@ -129,8 +139,16 @@ public class GLOffscreenRenderingExtension extends GraphicsExtension<IGLTarget>
|
|||
setCurrentView(new ViewInfo(view, glImage));
|
||||
}
|
||||
|
||||
public void renderOnscreen() throws VizException {
|
||||
if (viewStack.size() > 0) {
|
||||
/**
|
||||
* Ends offscreen rendering. Should only be called if a call to
|
||||
* {@link #beginOffscreenRendering(AbstractGLImage)} or
|
||||
* {@link #beginOffscreenRendering(AbstractGLImage, IExtent)} was
|
||||
* successfully called first first
|
||||
*
|
||||
* @throws VizException
|
||||
*/
|
||||
public void endOffscreenRendering() throws VizException {
|
||||
if (viewStack.isEmpty() == false) {
|
||||
setCurrentView(viewStack.pop());
|
||||
}
|
||||
}
|
||||
|
@ -167,60 +185,84 @@ public class GLOffscreenRenderingExtension extends GraphicsExtension<IGLTarget>
|
|||
return Compatibilty.TARGET_COMPATIBLE;
|
||||
}
|
||||
|
||||
public IImage constructOffscreenImage(final int[] dimensions)
|
||||
/**
|
||||
* Creates an RGB based image for use in offscreen rendering
|
||||
*
|
||||
* @param dimensions
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
public AbstractGLImage constructOffscreenImage(final int[] dimensions)
|
||||
throws VizException {
|
||||
return target.initializeRaster(new IRenderedImageCallback() {
|
||||
return new GLImage(new IRenderedImageCallback() {
|
||||
@Override
|
||||
public RenderedImage getImage() throws VizException {
|
||||
return new BufferedImage(dimensions[0], dimensions[1],
|
||||
BufferedImage.TYPE_INT_RGB);
|
||||
}
|
||||
});
|
||||
}, GLDefaultImagingExtension.class);
|
||||
}
|
||||
|
||||
public GLColormappedImage constructOffscreenImage(
|
||||
/**
|
||||
* Creates a colormapped offscreen image with the specified dataType and
|
||||
* dimensions
|
||||
*
|
||||
* @param dataType
|
||||
* @param dimensions
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
public GLOffscreenColormappedImage constructOffscreenImage(
|
||||
ColorMapDataType dataType, int[] dimensions) throws VizException {
|
||||
return constructOffscreenImage(dataType, dimensions, null);
|
||||
}
|
||||
|
||||
public GLColormappedImage constructOffscreenImage(
|
||||
/**
|
||||
* Creates a colormapped offscreen image with the specified dataType and
|
||||
* dimensions and default colormap parameters
|
||||
*
|
||||
* @param dataType
|
||||
* @param dimensions
|
||||
* @param parameters
|
||||
* @return
|
||||
* @throws VizException
|
||||
*/
|
||||
public GLOffscreenColormappedImage constructOffscreenImage(
|
||||
final ColorMapDataType dataType, final int[] dimensions,
|
||||
ColorMapParameters parameters) throws VizException {
|
||||
GLColormappedImageExtension cmapExt = target
|
||||
.getExtension(GLColormappedImageExtension.class);
|
||||
if (!supportsLuminance) {
|
||||
return cmapExt.initializeRaster(new NoLuminanceDataCallback(
|
||||
dimensions, dataType), parameters);
|
||||
} else {
|
||||
GLColormappedImage image = cmapExt.initializeRaster(
|
||||
new IColorMapDataRetrievalCallback() {
|
||||
AbstractGLColorMapDataFormat format = null;
|
||||
|
||||
@Override
|
||||
public ColorMapData getColorMapData()
|
||||
throws VizException {
|
||||
return new ColorMapData(dataType, dimensions);
|
||||
}
|
||||
}, parameters);
|
||||
if (!checkedLuminance) {
|
||||
checkedLuminance = true;
|
||||
try {
|
||||
renderOffscreen(image);
|
||||
} catch (VizException e) {
|
||||
// Log this so it is easy to see in the console logs.
|
||||
new VizException(
|
||||
"Graphics card does not support luminance textures.",
|
||||
e).printStackTrace(System.out);
|
||||
// assume we don't support luminance
|
||||
supportsLuminance = false;
|
||||
// Reconstruct image
|
||||
image = constructOffscreenImage(dataType, dimensions,
|
||||
parameters);
|
||||
} finally {
|
||||
renderOnscreen();
|
||||
}
|
||||
}
|
||||
return image;
|
||||
if (supportsLuminance) {
|
||||
format = GLColorMapDataFormatFactory
|
||||
.getGLColorMapDataFormat(dataType);
|
||||
} else {
|
||||
format = new NoLuminanceDataFormat(dataType);
|
||||
}
|
||||
|
||||
GLOffscreenColormappedImage image = new GLOffscreenColormappedImage(
|
||||
new GLColorMapData(format, dataType, dimensions), parameters,
|
||||
GLColormappedImageExtension.class);
|
||||
|
||||
if (!checkedLuminance) {
|
||||
checkedLuminance = true;
|
||||
try {
|
||||
beginOffscreenRendering(image);
|
||||
} catch (VizException e) {
|
||||
// Log this so it is easy to see in the console logs.
|
||||
new VizException(
|
||||
"Graphics card does not support luminance textures.", e)
|
||||
.printStackTrace(System.out);
|
||||
// assume we don't support luminance
|
||||
supportsLuminance = false;
|
||||
// Reconstruct image
|
||||
image = constructOffscreenImage(dataType, dimensions,
|
||||
parameters);
|
||||
} finally {
|
||||
endOffscreenRendering();
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
private static final class NoLuminanceDataFormat extends GLByteDataFormat {
|
||||
|
@ -228,10 +270,11 @@ public class GLOffscreenRenderingExtension extends GraphicsExtension<IGLTarget>
|
|||
// Used to get the original min/max which makes signed bytes work and
|
||||
// theoretically will give better looking results for other integer data
|
||||
// types.
|
||||
private final ColorMapDataType originalType;
|
||||
private final AbstractGLColorMapDataFormat originalFormat;
|
||||
|
||||
private NoLuminanceDataFormat(ColorMapDataType originalType) {
|
||||
this.originalType = originalType;
|
||||
this.originalFormat = GLColorMapDataFormatFactory
|
||||
.getGLColorMapDataFormat(originalType);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -251,46 +294,14 @@ public class GLOffscreenRenderingExtension extends GraphicsExtension<IGLTarget>
|
|||
|
||||
@Override
|
||||
public double getDataFormatMin() {
|
||||
return getOriginalGLColorMapDataFormat().getDataFormatMin();
|
||||
return originalFormat.getDataFormatMin();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getDataFormatMax() {
|
||||
return getOriginalGLColorMapDataFormat().getDataFormatMax();
|
||||
return originalFormat.getDataFormatMax();
|
||||
}
|
||||
|
||||
private AbstractGLColorMapDataFormat getOriginalGLColorMapDataFormat() {
|
||||
return GLColorMapDataFormatFactory
|
||||
.getGLColorMapDataFormat(originalType);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final class NoLuminanceDataCallback implements
|
||||
IColorMapDataRetrievalCallback, IGLColorMapDataFormatProvider {
|
||||
|
||||
private int[] dimensions;
|
||||
|
||||
private final ColorMapDataType originalType;
|
||||
|
||||
private NoLuminanceDataCallback(int[] dimensions,
|
||||
ColorMapDataType type) {
|
||||
this.dimensions = dimensions;
|
||||
this.originalType = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractGLColorMapDataFormat getGLColorMapDataFormat(
|
||||
ColorMapData colorMapData) {
|
||||
return new NoLuminanceDataFormat(originalType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ColorMapData getColorMapData() throws VizException {
|
||||
Buffer buffer = ByteBuffer.allocate(dimensions[0] * dimensions[1]
|
||||
* 3);
|
||||
return new ColorMapData(buffer, dimensions, originalType);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormappedImageExtensio
|
|||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.viz.core.gl.glsl.AbstractGLSLImagingExtension;
|
||||
import com.raytheon.viz.core.gl.glsl.GLShaderProgram;
|
||||
import com.raytheon.viz.core.gl.images.AbstractGLColormappedImage;
|
||||
import com.raytheon.viz.core.gl.images.AbstractGLImage;
|
||||
import com.raytheon.viz.core.gl.images.GLColormappedImage;
|
||||
import com.raytheon.viz.core.gl.objects.GLTextureObject;
|
||||
|
@ -48,10 +49,11 @@ import com.raytheon.viz.core.gl.objects.GLTextureObject;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Nov 18, 2011 mschenke Initial creation
|
||||
* Nov 18, 2011 mschenke Initial creation
|
||||
* Feb 14, 2013 1616 bsteffen Add option for interpolation of colormap
|
||||
* parameters, disable colormap interpolation
|
||||
* by default.
|
||||
* Oct 16, 2013 2333 mschenke Cleaned up load shader method, used isScaled
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -94,10 +96,10 @@ public class GLColormappedImageExtension extends AbstractGLSLImagingExtension
|
|||
public Object preImageRender(PaintProperties paintProps,
|
||||
AbstractGLImage image, PixelCoverage coverage) throws VizException {
|
||||
GLColormappedImageExtensionData data = null;
|
||||
if (image instanceof GLColormappedImage) {
|
||||
if (image instanceof AbstractGLColormappedImage) {
|
||||
data = new GLColormappedImageExtensionData();
|
||||
GL gl = target.getGl();
|
||||
GLColormappedImage glImage = (GLColormappedImage) image;
|
||||
AbstractGLColormappedImage glImage = (AbstractGLColormappedImage) image;
|
||||
// First see if the colormap has been loaded
|
||||
ColorMapParameters usedColorMapParameters = ((IColormappedImage) glImage)
|
||||
.getColorMapParameters();
|
||||
|
@ -199,31 +201,30 @@ public class GLColormappedImageExtension extends AbstractGLSLImagingExtension
|
|||
public void loadShaderData(GLShaderProgram program, IImage iimage,
|
||||
PaintProperties paintProps) throws VizException {
|
||||
// Get image as AbstractGLImage
|
||||
GLColormappedImage image = null;
|
||||
if (iimage instanceof GLColormappedImage == false) {
|
||||
AbstractGLColormappedImage image = null;
|
||||
if (iimage instanceof AbstractGLColormappedImage == false) {
|
||||
throw new VizException(
|
||||
"Cannot apply glsl colormap raster shader to non gl colormap image");
|
||||
}
|
||||
image = (GLColormappedImage) iimage;
|
||||
image = (AbstractGLColormappedImage) iimage;
|
||||
|
||||
GLColormappedImage colormappedImg = (GLColormappedImage) image;
|
||||
ColorMapParameters colorMapParameters = colormappedImg
|
||||
.getColorMapParameters();
|
||||
ColorMapParameters colorMapParameters = image.getColorMapParameters();
|
||||
|
||||
program.setUniform("colorMapSz", colorMapParameters.getColorMap()
|
||||
.getSize());
|
||||
int textureType = image.getTextureType();
|
||||
boolean isFloat = textureType == GL.GL_FLOAT
|
||||
|| textureType == GL.GL_HALF_FLOAT_ARB;
|
||||
boolean isScaled = image.isImageFormatScaled();
|
||||
double dataMin = colorMapParameters.getDataMin();
|
||||
double dataMax = colorMapParameters.getDataMax();
|
||||
if (isFloat == false) {
|
||||
if (isScaled) {
|
||||
// get format from image and get data min/max from it
|
||||
dataMin = image.getDataMin();
|
||||
dataMax = image.getDataMax();
|
||||
}
|
||||
|
||||
program.setUniform("isFloat", isFloat);
|
||||
double cmapMin = colorMapParameters.getColorMapMin();
|
||||
double cmapMax = colorMapParameters.getColorMapMax();
|
||||
|
||||
program.setUniform("isFloat", !isScaled);
|
||||
program.setUniform("logarithmic",
|
||||
colorMapParameters.isLogarithmic() ? 1 : 0);
|
||||
program.setUniform("logFactor", colorMapParameters.getLogFactor());
|
||||
|
@ -233,8 +234,8 @@ public class GLColormappedImageExtension extends AbstractGLSLImagingExtension
|
|||
|
||||
program.setUniform("naturalMin", dataMin);
|
||||
program.setUniform("naturalMax", dataMax);
|
||||
program.setUniform("cmapMin", colorMapParameters.getColorMapMin());
|
||||
program.setUniform("cmapMax", colorMapParameters.getColorMapMax());
|
||||
program.setUniform("cmapMin", cmapMin);
|
||||
program.setUniform("cmapMax", cmapMax);
|
||||
|
||||
program.setUniform("alphaMask", 2);
|
||||
program.setUniform("colorMap", 1);
|
||||
|
|
|
@ -0,0 +1,280 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.viz.core.gl.images;
|
||||
|
||||
import javax.media.opengl.GL;
|
||||
|
||||
import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
|
||||
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
||||
import com.raytheon.uf.viz.core.drawables.IColormappedImage;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.sun.opengl.util.texture.TextureCoords;
|
||||
|
||||
/**
|
||||
* Base implementation of a gl colormapped image.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 16, 2013 2333 mschenke Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public abstract class AbstractGLColormappedImage extends AbstractGLImage
|
||||
implements IColormappedImage {
|
||||
|
||||
protected ColorMapParameters colorMapParameters;
|
||||
|
||||
protected GLCMTextureData data;
|
||||
|
||||
public AbstractGLColormappedImage(GLCMTextureData data,
|
||||
ColorMapParameters params,
|
||||
Class<? extends IImagingExtension> extensionClass) {
|
||||
super(extensionClass);
|
||||
this.data = data;
|
||||
this.colorMapParameters = params;
|
||||
if (data.isLoaded()) {
|
||||
setStatus(Status.LOADED);
|
||||
} else if (data.isStaged()) {
|
||||
setStatus(Status.STAGED);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.images.AbstractGLImage#stageTexture()
|
||||
*/
|
||||
@Override
|
||||
public boolean stageTexture() throws VizException {
|
||||
if (data == null) {
|
||||
throw new VizException(
|
||||
"Cannot stage texture, image has been disposed");
|
||||
}
|
||||
return data.stageTexture();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.viz.core.gl.internal.GLImage#loadTexture(javax.media.opengl
|
||||
* .GLContext)
|
||||
*/
|
||||
@Override
|
||||
public void loadTexture(GL gl) throws VizException {
|
||||
if (data.loadTexture(gl)) {
|
||||
// Add to texture cache
|
||||
setStatus(Status.LOADED);
|
||||
} else {
|
||||
setStatus(Status.FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the texture's data type
|
||||
*
|
||||
* Example: GL.GL_FLOAT
|
||||
*
|
||||
* @return the data type of the texture
|
||||
*
|
||||
*/
|
||||
public int getTextureType() {
|
||||
return data.getTextureType();
|
||||
}
|
||||
|
||||
public ColorMapDataType getColorMapDataType() {
|
||||
return data.getColorMapDataType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the texture's format
|
||||
*
|
||||
* Example: GL.GL_LUMINANCE
|
||||
*
|
||||
* @return the texture format
|
||||
*/
|
||||
public int getTextureFormat() {
|
||||
return data.getTextureFormat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the texture's internal format
|
||||
*
|
||||
* This is the format of the texture after driver manipulation
|
||||
*
|
||||
* Example: GL.GL_LUMINANCE8
|
||||
*
|
||||
* @return the texture internal format
|
||||
*/
|
||||
public int getTextureInternalFormat() {
|
||||
return data.getTextureInternalFormat();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the textureid
|
||||
*/
|
||||
public int getTextureid() {
|
||||
return data.getTexId();
|
||||
}
|
||||
|
||||
/**
|
||||
* the absolute minimum value of a pixel in this image. {@link Double#NaN}
|
||||
* if no absolute minimum exists
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public double getDataMin() {
|
||||
return data.getDataMin();
|
||||
}
|
||||
|
||||
/**
|
||||
* the absolute maximum value of a pixel in this image. {@link Double#NaN}
|
||||
* if no absolute maximum exists
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public double getDataMax() {
|
||||
return data.getDataMax();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the image values will be scaled when loaded into GL
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isImageFormatScaled() {
|
||||
return data.isDataFormatScaled();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.viz.core.drawables.IColormappedImage#getColorMapParameters()
|
||||
*/
|
||||
@Override
|
||||
public ColorMapParameters getColorMapParameters() {
|
||||
return this.colorMapParameters;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.viz.core.drawables.IColormappedImage#setColorMapParameters
|
||||
* (com.raytheon.viz.core.drawables.ColorMapParameters)
|
||||
*/
|
||||
@Override
|
||||
public void setColorMapParameters(ColorMapParameters params) {
|
||||
this.colorMapParameters = params;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.viz.core.gl.internal.images.GLImage#getTextureStorageType()
|
||||
*/
|
||||
@Override
|
||||
public int getTextureStorageType() {
|
||||
return data.getTextureStorageType();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.internal.images.GLImage#getHeight()
|
||||
*/
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return data.getDimensionSize(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.internal.images.GLImage#getWidth()
|
||||
*/
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return data.getDimensionSize(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
if (data != null) {
|
||||
data.dispose();
|
||||
data = null;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.images.AbstractGLImage#getStatus()
|
||||
*/
|
||||
@Override
|
||||
public Status getStatus() {
|
||||
Status status = super.getStatus();
|
||||
if (data == null) {
|
||||
if (status != Status.UNLOADED) {
|
||||
setStatus(Status.UNLOADED);
|
||||
}
|
||||
} else if (data.isLoaded()) {
|
||||
if (status != Status.LOADED) {
|
||||
setStatus(Status.LOADED);
|
||||
}
|
||||
} else if (data.isStaged()) {
|
||||
if (status != Status.STAGED) {
|
||||
setStatus(Status.STAGED);
|
||||
}
|
||||
} else if (data.isLoaded() == false && status == Status.LOADED) {
|
||||
if (data.isStaged()) {
|
||||
setStatus(Status.STAGED);
|
||||
} else {
|
||||
setStatus(Status.UNLOADED);
|
||||
}
|
||||
} else if (data.isStaged() == false && status == Status.STAGED) {
|
||||
setStatus(Status.UNLOADED);
|
||||
}
|
||||
return super.getStatus();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.images.AbstractGLImage#getTextureCoords()
|
||||
*/
|
||||
@Override
|
||||
public TextureCoords getTextureCoords() {
|
||||
return new TextureCoords(0, 1, 1, 0);
|
||||
}
|
||||
|
||||
}
|
|
@ -41,7 +41,8 @@ import com.sun.opengl.util.texture.TextureCoords;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 2, 2011 bsteffen Initial creation
|
||||
* Aug 2, 2011 bsteffen Initial creation
|
||||
* Oct 16, 2013 2333 mschenke Cleaned up usaAsFrameBuffer for clearer logic
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -171,55 +172,61 @@ public abstract class AbstractGLImage implements IImage {
|
|||
|
||||
public void usaAsFrameBuffer() throws VizException {
|
||||
GL gl = GLU.getCurrentGL();
|
||||
if (fbo != null && fbo.isValid()) {
|
||||
fbo.bind(gl);
|
||||
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
if (rbuf != null && rbuf.isValid()) {
|
||||
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
|
||||
if (fbo == null || fbo.isValid() == false) {
|
||||
gl.glBindTexture(getTextureStorageType(), 0);
|
||||
|
||||
fbo = new GLFrameBufferObject(this);
|
||||
if (fbo.isValid()) {
|
||||
fbo.bind(gl);
|
||||
if ((rbuf == null || rbuf.isValid() == false)
|
||||
&& gl.glIsEnabled(GL.GL_DEPTH_TEST)) {
|
||||
// Generate and bind a render buffer for the depth component
|
||||
rbuf = new GLRenderBuffer(this);
|
||||
rbuf.bind(gl);
|
||||
rbuf.createStorage(gl, GL.GL_DEPTH_COMPONENT, getWidth(),
|
||||
getHeight());
|
||||
gl.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, 0);
|
||||
|
||||
// Attach render buffer to depth of fbo
|
||||
gl.glFramebufferRenderbufferEXT(GL.GL_FRAMEBUFFER_EXT,
|
||||
GL.GL_DEPTH_ATTACHMENT_EXT, GL.GL_RENDERBUFFER_EXT,
|
||||
rbuf.getId());
|
||||
}
|
||||
|
||||
// Attach texture to color attachement on fbo
|
||||
gl.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT,
|
||||
GL.GL_COLOR_ATTACHMENT0_EXT, getTextureStorageType(),
|
||||
getTextureid(), 0);
|
||||
String errorMessage = fbo.checkStatus(gl);
|
||||
|
||||
// use the window buffer
|
||||
if (errorMessage != null) {
|
||||
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);
|
||||
if (fbo != null) {
|
||||
fbo.dispose();
|
||||
fbo = null;
|
||||
}
|
||||
if (rbuf != null) {
|
||||
rbuf.dispose();
|
||||
rbuf = null;
|
||||
}
|
||||
throw new VizException(errorMessage);
|
||||
}
|
||||
} else {
|
||||
gl.glClear(GL.GL_COLOR_BUFFER_BIT);
|
||||
throw new VizException("Error generating Frame Buffer Object");
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
// Bind the fbo for use
|
||||
fbo.bind(gl);
|
||||
}
|
||||
gl = GLU.getCurrentGL();
|
||||
|
||||
gl.glBindTexture(getTextureStorageType(), 0);
|
||||
|
||||
fbo = new GLFrameBufferObject(this);
|
||||
fbo.bind(gl);
|
||||
|
||||
if (gl.glIsEnabled(GL.GL_DEPTH_TEST)) {
|
||||
// Generate and bind a render buffer for the depth component
|
||||
rbuf = new GLRenderBuffer(this);
|
||||
rbuf.bind(gl);
|
||||
rbuf.createStorage(gl, GL.GL_DEPTH_COMPONENT, getWidth(),
|
||||
getHeight());
|
||||
gl.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, 0);
|
||||
|
||||
// Attach render buffer to depth of fbo
|
||||
gl.glFramebufferRenderbufferEXT(GL.GL_FRAMEBUFFER_EXT,
|
||||
GL.GL_DEPTH_ATTACHMENT_EXT, GL.GL_RENDERBUFFER_EXT,
|
||||
rbuf.getId());
|
||||
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
if (rbuf != null && rbuf.isValid()) {
|
||||
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
|
||||
} else {
|
||||
gl.glClear(GL.GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
// Attach texture to color attachement on fbo
|
||||
gl.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT,
|
||||
GL.GL_COLOR_ATTACHMENT0_EXT, getTextureStorageType(),
|
||||
getTextureid(), 0);
|
||||
String errorMessage = fbo.checkStatus(gl);
|
||||
|
||||
// use the window buffer
|
||||
if (errorMessage != null) {
|
||||
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);
|
||||
if (fbo != null) {
|
||||
fbo.dispose();
|
||||
fbo = null;
|
||||
}
|
||||
if (rbuf != null) {
|
||||
rbuf.dispose();
|
||||
rbuf = null;
|
||||
}
|
||||
throw new VizException(errorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -265,7 +272,7 @@ public abstract class AbstractGLImage implements IImage {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
|
|
|
@ -19,29 +19,15 @@
|
|||
**/
|
||||
package com.raytheon.viz.core.gl.images;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.media.opengl.GL;
|
||||
import javax.media.opengl.glu.GLU;
|
||||
|
||||
import com.raytheon.uf.common.colormap.image.ColorMapData;
|
||||
import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
|
||||
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.viz.core.gl.GLContextBridge;
|
||||
import com.raytheon.viz.core.gl.dataformat.GLColorMapData;
|
||||
import com.raytheon.viz.core.gl.dataformat.IGLColorMapDataFormatProvider;
|
||||
import com.raytheon.viz.core.gl.internal.cache.IImageCacheable;
|
||||
import com.raytheon.viz.core.gl.internal.cache.ImageCache;
|
||||
import com.raytheon.viz.core.gl.internal.cache.ImageCache.CacheType;
|
||||
import com.raytheon.viz.core.gl.objects.GLTextureObject;
|
||||
|
||||
/**
|
||||
*
|
||||
* TODO Make use new ColorMapData retrieval callback stuff.... Keep old
|
||||
* CMDataPreparer stuff working
|
||||
* Colormappable texture data object. Does not provide source of data
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
|
@ -49,87 +35,77 @@ import com.raytheon.viz.core.gl.objects.GLTextureObject;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Aug 2, 2011 bsteffen Initial creation
|
||||
* Aug 2, 2011 bsteffen Initial creation
|
||||
* Mar 21, 2013 1806 bsteffen Update GL mosaicing to use dynamic data
|
||||
* format for offscreen textures.
|
||||
* Oct 16, 2013 2333 mschenke Moved retrievable/Buffer parts out and
|
||||
* into separate class.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author bsteffen
|
||||
* @version 1.0
|
||||
*/
|
||||
public class GLCMTextureData implements IImageCacheable {
|
||||
public class GLCMTextureData {
|
||||
|
||||
private GLTextureObject tex;
|
||||
protected GLTextureObject tex;
|
||||
|
||||
private final IColorMapDataRetrievalCallback callback;
|
||||
protected GLColorMapData data;
|
||||
|
||||
private int refCount = 0;
|
||||
|
||||
private GLColorMapData data = null;
|
||||
|
||||
private GLCMTextureData(IColorMapDataRetrievalCallback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void use() {
|
||||
refCount += 1;
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
synchronized (texMap) {
|
||||
refCount -= 1;
|
||||
if (refCount == 0) {
|
||||
texMap.remove(callback);
|
||||
ImageCache.getInstance(CacheType.MEMORY).remove(this);
|
||||
ImageCache.getInstance(CacheType.TEXTURE).remove(this);
|
||||
}
|
||||
/**
|
||||
* Constructs a GLCMTextureData with the specified GLColorMapData.
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
public GLCMTextureData(GLColorMapData data) {
|
||||
this.data = data;
|
||||
if (data == null && getClass().equals(GLCMTextureData.class)) {
|
||||
// If null data and class is not overridden, throw exception
|
||||
throw new IllegalArgumentException(
|
||||
"null GLColorMapData is not allowed for GLCMTextureData");
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void disposeTexture(GL gl) {
|
||||
protected GLColorMapData getDataObject() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes the texture data object
|
||||
*/
|
||||
public void dispose() {
|
||||
// Dispose the texture
|
||||
disposeTexture();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes the underlying texture in the texture data
|
||||
*/
|
||||
public synchronized void disposeTexture() {
|
||||
if (isLoaded()) {
|
||||
tex.dispose();
|
||||
tex = null;
|
||||
}
|
||||
ImageCache.getInstance(CacheType.TEXTURE).remove(this);
|
||||
}
|
||||
|
||||
public synchronized void disposeTextureData() {
|
||||
if (isStaged()) {
|
||||
data.setData(null);
|
||||
}
|
||||
ImageCache.getInstance(CacheType.MEMORY).remove(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stages the texture data for use.
|
||||
*
|
||||
* @return true if successfully staged, false otherwise
|
||||
* @throws VizException
|
||||
*/
|
||||
public synchronized boolean stageTexture() throws VizException {
|
||||
// Don't need to stage if we are already in gpu
|
||||
if (isLoaded()) {
|
||||
return true;
|
||||
}
|
||||
// Don't need to stage if we already have data
|
||||
if (isStaged()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// OK, Fetch the data
|
||||
ColorMapData cmData = callback.getColorMapData();
|
||||
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;
|
||||
// There is no data to stage
|
||||
return isStaged();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the texture object into GL
|
||||
*
|
||||
* @param gl
|
||||
* @return true if texture is loaded, false otherwise
|
||||
* @throws VizException
|
||||
*/
|
||||
public synchronized boolean loadTexture(GL gl) throws VizException {
|
||||
// Don't need to load if we are already loaded
|
||||
if (isLoaded()) {
|
||||
|
@ -149,8 +125,7 @@ public class GLCMTextureData implements IImageCacheable {
|
|||
gl.glTexParameteri(type, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
|
||||
gl.glTexParameteri(type, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
|
||||
|
||||
if (getTextureType() == GL.GL_SHORT || getTextureType() == GL.GL_INT
|
||||
|| getTextureType() == GL.GL_BYTE) {
|
||||
if (isDataFormatScaled() && isDataFormatSigned()) {
|
||||
// GL maps signed data into the range -1 to 1, but gl trims
|
||||
// this to a valid range of 0 to 1, essentially removing
|
||||
// negative values. Adding a scale and bias remaps this from
|
||||
|
@ -160,120 +135,156 @@ public class GLCMTextureData implements IImageCacheable {
|
|||
gl.glPixelTransferf(GL.GL_RED_BIAS, 0.5f);
|
||||
}
|
||||
|
||||
int w = data.getDimensionSize(0);
|
||||
int h = data.getDimensionSize(1);
|
||||
int w = getDimensionSize(0);
|
||||
int h = getDimensionSize(1);
|
||||
|
||||
createTexture2D(gl, type, w, h);
|
||||
|
||||
gl.glTexImage2D(type, 0, getTextureInternalFormat(), w, h, 0,
|
||||
getTextureFormat(), getTextureType(), data.getData().rewind());
|
||||
gl.glPixelTransferf(GL.GL_RED_SCALE, 1.0f);
|
||||
gl.glPixelTransferf(GL.GL_RED_BIAS, 0.0f);
|
||||
ImageCache.getInstance(CacheType.TEXTURE).put(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isStaged() {
|
||||
return data != null && data.getData() != null;
|
||||
/**
|
||||
* Creates a 2D texture for type, with width/height w/h. Texture object must
|
||||
* be bound for this call to work using
|
||||
* {@link GLTextureObject#bind(GL, int)}
|
||||
*
|
||||
* @param gl
|
||||
* @param type
|
||||
* @param w
|
||||
* @param h
|
||||
*/
|
||||
protected void createTexture2D(GL gl, int type, int w, int h) {
|
||||
// Allocate our space on the graphics card, no buffer to upload so it
|
||||
// will be filled with default values initially (0s)
|
||||
gl.glTexImage2D(type, 0, getTextureInternalFormat(), w, h, 0,
|
||||
getTextureFormat(), getTextureType(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if texture data is staged. If false, a call to
|
||||
* {@link #stageTexture()} is needed before texture can be loaded
|
||||
*
|
||||
* @return true if staged
|
||||
*/
|
||||
public boolean isStaged() {
|
||||
// There is nothing to stage, so we are good if data != null
|
||||
return getDataObject() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if texture data is loaded. If false, a call to
|
||||
* {@link #loadTexture(GL)} is needed before the texture can be used in GL
|
||||
*
|
||||
* @return true if staged
|
||||
*/
|
||||
public boolean isLoaded() {
|
||||
return tex != null && tex.isValid();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the dimension index passed in (0=width,1=height)
|
||||
*
|
||||
* @param dimension
|
||||
* @return
|
||||
*/
|
||||
public int getDimensionSize(int dimension) {
|
||||
return data.getDimensionSize(dimension);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the texture type of the data (FLOAT,INT,SHORT,etc).
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getTextureType() {
|
||||
return data.getTextureType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns texture format (LUMINANCE,RGB)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getTextureFormat() {
|
||||
return data.getTextureFormat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns texture gl internal format (number of bits: LUMINANCE8/16/32)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getTextureInternalFormat() {
|
||||
return data.getTextureInternalFormat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the minimum valid data value for the texture format. (0 for
|
||||
* unsigned byte, -128 for signed byte, etc)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public double getDataMin() {
|
||||
return data.getDataFormatMin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximium valid data value for the texture format. ( 255 for
|
||||
* usnigned byte, 127 for signed byte, etc)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public double getDataMax() {
|
||||
return data.getDataFormatMax();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the data values when uploaded to GL are in a scaled
|
||||
* format and need to be converted to get actual data value
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isDataFormatScaled() {
|
||||
return data.isDataFormatScaled();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the data format is a signed data format (values in format
|
||||
* can be less than 0), false otherwise
|
||||
*
|
||||
* @return true if signed format
|
||||
*/
|
||||
public boolean isDataFormatSigned() {
|
||||
return data.isDataFormatSigned();
|
||||
}
|
||||
|
||||
/**
|
||||
* The id of the texture in GL. Will not work if {@link #isLoaded()} returns
|
||||
* false
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getTexId() {
|
||||
if (isLoaded()) {
|
||||
ImageCache.getInstance(CacheType.TEXTURE).put(this);
|
||||
}
|
||||
return tex.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* The texture storage type of the data (TEXTURE_2D)
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int getTextureStorageType() {
|
||||
return GL.GL_TEXTURE_2D;
|
||||
}
|
||||
|
||||
public double getValue(int x, int y) {
|
||||
double value = Double.NaN;
|
||||
if (!isStaged() && isLoaded()) {
|
||||
GLContextBridge.makeMasterContextCurrent();
|
||||
GL gl = GLU.getCurrentGL();
|
||||
int textureStorageType = getTextureStorageType();
|
||||
int copybackTextureType = data.getCopyBackTextureType();
|
||||
Buffer copybackBuffer = data.getCopybackBuffer();
|
||||
gl.glEnable(textureStorageType);
|
||||
gl.glActiveTexture(GL.GL_TEXTURE0);
|
||||
tex.bind(gl, textureStorageType);
|
||||
gl.glGetTexImage(textureStorageType, 0, getTextureFormat(),
|
||||
copybackTextureType, copybackBuffer.rewind());
|
||||
gl.glActiveTexture(GL.GL_TEXTURE0);
|
||||
gl.glBindTexture(textureStorageType, 0);
|
||||
gl.glDisable(textureStorageType);
|
||||
|
||||
data.setTextureType(copybackTextureType);
|
||||
data.setData(copybackBuffer);
|
||||
GLContextBridge.releaseMasterContext();
|
||||
}
|
||||
if (data != null) {
|
||||
ImageCache.getInstance(CacheType.MEMORY).put(this);
|
||||
value = data.getValue(x, y).doubleValue();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private static Map<IColorMapDataRetrievalCallback, GLCMTextureData> texMap = new HashMap<IColorMapDataRetrievalCallback, GLCMTextureData>();
|
||||
|
||||
public static GLCMTextureData getGlTextureId(
|
||||
IColorMapDataRetrievalCallback callback) {
|
||||
synchronized (texMap) {
|
||||
GLCMTextureData data = texMap.get(callback);
|
||||
if (data == null) {
|
||||
data = new GLCMTextureData(callback);
|
||||
texMap.put(callback, data);
|
||||
}
|
||||
data.use();
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
if (data != null) {
|
||||
int[] dimensions = data.getDimensions();
|
||||
int totalSize = data.getBytesPerPixel();
|
||||
for (int i = 0; i < dimensions.length; ++i) {
|
||||
totalSize *= dimensions[i];
|
||||
}
|
||||
return totalSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ColorMapDataType} for the texture
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public ColorMapDataType getColorMapDataType() {
|
||||
return data.getDataType();
|
||||
}
|
||||
|
|
|
@ -24,10 +24,8 @@ import javax.media.opengl.GL;
|
|||
import com.raytheon.uf.common.colormap.image.ColorMapData.ColorMapDataType;
|
||||
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
||||
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
|
||||
import com.raytheon.uf.viz.core.drawables.IColormappedImage;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.sun.opengl.util.texture.TextureCoords;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -39,46 +37,25 @@ import com.sun.opengl.util.texture.TextureCoords;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jul 27, 2009 mschenke Initial creation
|
||||
* Jul 27, 2009 mschenke Initial creation
|
||||
* Mar 21, 2013 1806 bsteffen Update GL mosaicing to use dynamic data
|
||||
* format for offscreen textures.
|
||||
* Oct 16, 2013 2333 mschenke Moved shared logic into base class
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
*/
|
||||
public class GLColormappedImage extends AbstractGLImage implements
|
||||
IColormappedImage {
|
||||
public class GLColormappedImage extends AbstractGLColormappedImage {
|
||||
|
||||
protected ColorMapParameters colorMapParameters;
|
||||
|
||||
protected GLCMTextureData data;
|
||||
protected GLRetrievableCMTextureData data;
|
||||
|
||||
public GLColormappedImage(IColorMapDataRetrievalCallback dataCallback,
|
||||
ColorMapParameters params,
|
||||
Class<? extends IImagingExtension> extensionClass) {
|
||||
super(extensionClass);
|
||||
this.data = GLCMTextureData.getGlTextureId(dataCallback);
|
||||
this.colorMapParameters = params;
|
||||
if (data.isLoaded()) {
|
||||
setStatus(Status.LOADED);
|
||||
} else if (data.isStaged()) {
|
||||
setStatus(Status.STAGED);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.images.AbstractGLImage#stageTexture()
|
||||
*/
|
||||
@Override
|
||||
public boolean stageTexture() throws VizException {
|
||||
if (data == null) {
|
||||
throw new VizException(
|
||||
"Cannot stage texture, image has been disposed");
|
||||
}
|
||||
return data.stageTexture();
|
||||
super(GLRetrievableCMTextureData.getGlTextureId(dataCallback), params,
|
||||
extensionClass);
|
||||
this.data = (GLRetrievableCMTextureData) super.data;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -90,117 +67,15 @@ public class GLColormappedImage extends AbstractGLImage implements
|
|||
*/
|
||||
@Override
|
||||
public void loadTexture(GL gl) throws VizException {
|
||||
if (data.loadTexture(gl)) {
|
||||
// Add to texture cache
|
||||
setStatus(Status.LOADED);
|
||||
data.disposeTextureData();
|
||||
} else {
|
||||
setStatus(Status.FAILED);
|
||||
data.disposeTextureData();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the texture's data type
|
||||
*
|
||||
* Example: GL.GL_FLOAT
|
||||
*
|
||||
* @return the data type of the texture
|
||||
*
|
||||
*/
|
||||
public int getTextureType() {
|
||||
return data.getTextureType();
|
||||
super.loadTexture(gl);
|
||||
// No need to keep around texture data after loading
|
||||
data.disposeTextureData();
|
||||
}
|
||||
|
||||
public ColorMapDataType getColorMapDataType() {
|
||||
return data.getColorMapDataType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the texture's format
|
||||
*
|
||||
* Example: GL.GL_LUMINANCE
|
||||
*
|
||||
* @return the texture format
|
||||
*/
|
||||
public int getTextureFormat() {
|
||||
return data.getTextureFormat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the texture's internal format
|
||||
*
|
||||
* This is the format of the texture after driver manipulation
|
||||
*
|
||||
* Example: GL.GL_LUMINANCE8
|
||||
*
|
||||
* @return the texture internal format
|
||||
*/
|
||||
public int getTextureInternalFormat() {
|
||||
return data.getTextureInternalFormat();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the textureid
|
||||
*/
|
||||
public int getTextureid() {
|
||||
return data.getTexId();
|
||||
}
|
||||
|
||||
/**
|
||||
* the absolute minimum value of a pixel in this image. {@link Double#NaN}
|
||||
* if no absolute minimum exists
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public double getDataMin() {
|
||||
return data.getDataMin();
|
||||
}
|
||||
|
||||
/**
|
||||
* the absolute maximum value of a pixel in this image. {@link Double#NaN}
|
||||
* if no absolute maximum exists
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public double getDataMax() {
|
||||
return data.getDataMax();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.viz.core.drawables.IColormappedImage#getColorMapParameters()
|
||||
*/
|
||||
@Override
|
||||
public ColorMapParameters getColorMapParameters() {
|
||||
return this.colorMapParameters;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.viz.core.drawables.IColormappedImage#setColorMapParameters
|
||||
* (com.raytheon.viz.core.drawables.ColorMapParameters)
|
||||
*/
|
||||
@Override
|
||||
public void setColorMapParameters(ColorMapParameters params) {
|
||||
this.colorMapParameters = params;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.viz.core.gl.internal.images.GLImage#getTextureStorageType()
|
||||
*/
|
||||
@Override
|
||||
public int getTextureStorageType() {
|
||||
return data.getTextureStorageType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getValue(int x, int y) {
|
||||
double val = Double.NaN;
|
||||
|
@ -210,33 +85,10 @@ public class GLColormappedImage extends AbstractGLImage implements
|
|||
return val;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.internal.images.GLImage#getHeight()
|
||||
*/
|
||||
@Override
|
||||
public int getHeight() {
|
||||
return data.getDimensionSize(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.internal.images.GLImage#getWidth()
|
||||
*/
|
||||
@Override
|
||||
public int getWidth() {
|
||||
return data.getDimensionSize(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
super.dispose();
|
||||
if (data != null) {
|
||||
data.dispose();
|
||||
data = null;
|
||||
}
|
||||
data = null;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -250,46 +102,4 @@ public class GLColormappedImage extends AbstractGLImage implements
|
|||
super.usaAsFrameBuffer();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.images.AbstractGLImage#getStatus()
|
||||
*/
|
||||
@Override
|
||||
public Status getStatus() {
|
||||
Status status = super.getStatus();
|
||||
if (data == null) {
|
||||
if (status != Status.UNLOADED) {
|
||||
setStatus(Status.UNLOADED);
|
||||
}
|
||||
} else if (data.isLoaded()) {
|
||||
if (status != Status.LOADED) {
|
||||
setStatus(Status.LOADED);
|
||||
}
|
||||
} else if (data.isStaged()) {
|
||||
if (status != Status.STAGED) {
|
||||
setStatus(Status.STAGED);
|
||||
}
|
||||
} else if (data.isLoaded() == false && status == Status.LOADED) {
|
||||
if (data.isStaged()) {
|
||||
setStatus(Status.STAGED);
|
||||
} else {
|
||||
setStatus(Status.UNLOADED);
|
||||
}
|
||||
} else if (data.isStaged() == false && status == Status.STAGED) {
|
||||
setStatus(Status.UNLOADED);
|
||||
}
|
||||
return super.getStatus();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.images.AbstractGLImage#getTextureCoords()
|
||||
*/
|
||||
@Override
|
||||
public TextureCoords getTextureCoords() {
|
||||
return new TextureCoords(0, 1, 1, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ public class GLImage extends AbstractGLImage implements IImageCacheable {
|
|||
ImageCache.getInstance(CacheType.TEXTURE).remove(this);
|
||||
}
|
||||
|
||||
public void disposeTexture(GL gl) {
|
||||
public void disposeTexture() {
|
||||
synchronized (this) {
|
||||
if (theTexture == null) {
|
||||
return;
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.viz.core.gl.images;
|
||||
|
||||
import com.raytheon.uf.common.colormap.prefs.ColorMapParameters;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IImagingExtension;
|
||||
import com.raytheon.viz.core.gl.dataformat.GLColorMapData;
|
||||
|
||||
/**
|
||||
* Colormappable image that is writeable to in GL/GLSL but is not back by a
|
||||
* Buffer and therefore not preinitialized or inspectable
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Oct 16, 2013 2333 mschenke Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class GLOffscreenColormappedImage extends AbstractGLColormappedImage {
|
||||
|
||||
/**
|
||||
* @param data
|
||||
* @param params
|
||||
* @param extensionClass
|
||||
*/
|
||||
public GLOffscreenColormappedImage(GLColorMapData data,
|
||||
ColorMapParameters params,
|
||||
Class<? extends IImagingExtension> extensionClass) {
|
||||
super(new GLCMTextureData(data), params, extensionClass);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.viz.core.drawables.IColormappedImage#getValue(int,
|
||||
* int)
|
||||
*/
|
||||
@Override
|
||||
public double getValue(int x, int y) {
|
||||
// TODO: Read value off of graphics card?
|
||||
return Double.NaN;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,291 @@
|
|||
/**
|
||||
* This software was developed and / or modified by Raytheon Company,
|
||||
* pursuant to Contract DG133W-05-CQ-1067 with the US Government.
|
||||
*
|
||||
* U.S. EXPORT CONTROLLED TECHNICAL DATA
|
||||
* This software product contains export-restricted data whose
|
||||
* export/transfer/disclosure is restricted by U.S. law. Dissemination
|
||||
* to non-U.S. persons whether in the United States or abroad requires
|
||||
* an export license or other authorization.
|
||||
*
|
||||
* Contractor Name: Raytheon Company
|
||||
* Contractor Address: 6825 Pine Street, Suite 340
|
||||
* Mail Stop B8
|
||||
* Omaha, NE 68106
|
||||
* 402.291.0100
|
||||
*
|
||||
* See the AWIPS II Master Rights File ("Master Rights File.pdf") for
|
||||
* further licensing information.
|
||||
**/
|
||||
package com.raytheon.viz.core.gl.images;
|
||||
|
||||
import java.nio.Buffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.measure.unit.Unit;
|
||||
import javax.media.opengl.GL;
|
||||
import javax.media.opengl.glu.GLU;
|
||||
|
||||
import com.raytheon.uf.common.colormap.image.ColorMapData;
|
||||
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
|
||||
import com.raytheon.uf.viz.core.exception.VizException;
|
||||
import com.raytheon.viz.core.gl.GLContextBridge;
|
||||
import com.raytheon.viz.core.gl.dataformat.GLBufferColorMapData;
|
||||
import com.raytheon.viz.core.gl.dataformat.IGLColorMapDataFormatProvider;
|
||||
import com.raytheon.viz.core.gl.internal.cache.IImageCacheable;
|
||||
import com.raytheon.viz.core.gl.internal.cache.ImageCache;
|
||||
import com.raytheon.viz.core.gl.internal.cache.ImageCache.CacheType;
|
||||
|
||||
/**
|
||||
* Object that represents a colormapped texture that can be unloaded and
|
||||
* reloaded from main/graphics memory using a retrieval callback
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* SOFTWARE HISTORY
|
||||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Jun 24, 2013 mschenke Initial creation
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @author mschenke
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class GLRetrievableCMTextureData extends GLCMTextureData implements
|
||||
IImageCacheable {
|
||||
|
||||
private static Map<IColorMapDataRetrievalCallback, GLRetrievableCMTextureData> texMap = new HashMap<IColorMapDataRetrievalCallback, GLRetrievableCMTextureData>();
|
||||
|
||||
/**
|
||||
* Gets a {@link GLRetrievableCMTextureData} for the callback. These
|
||||
* TextureData objects can be shared among callbacks
|
||||
*
|
||||
* @param callback
|
||||
* @return
|
||||
*/
|
||||
public static GLRetrievableCMTextureData getGlTextureId(
|
||||
IColorMapDataRetrievalCallback callback) {
|
||||
synchronized (texMap) {
|
||||
GLRetrievableCMTextureData data = texMap.get(callback);
|
||||
if (data == null) {
|
||||
data = new GLRetrievableCMTextureData(callback);
|
||||
texMap.put(callback, data);
|
||||
}
|
||||
data.use();
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
private final IColorMapDataRetrievalCallback callback;
|
||||
|
||||
private int refCount = 0;
|
||||
|
||||
/**
|
||||
* Private constructor, access only allowed through
|
||||
* {@link #getGlTextureId(IColorMapDataRetrievalCallback)}
|
||||
*
|
||||
* @param callback
|
||||
*/
|
||||
private GLRetrievableCMTextureData(IColorMapDataRetrievalCallback callback) {
|
||||
super(null);
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GLBufferColorMapData getDataObject() {
|
||||
return (GLBufferColorMapData) super.getDataObject();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.images.GLCMTextureData#stageTexture()
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean stageTexture() throws VizException {
|
||||
// Don't need to stage if we are already in GL
|
||||
if (isLoaded()) {
|
||||
return true;
|
||||
}
|
||||
// Don't need to stage if we already have data locally
|
||||
if (isStaged()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// OK, Fetch the data
|
||||
ColorMapData cmData = callback.getColorMapData();
|
||||
if (cmData != null) {
|
||||
IGLColorMapDataFormatProvider glDataFormatCallback = IGLColorMapDataFormatProvider.defaultCallback;
|
||||
if (callback instanceof IGLColorMapDataFormatProvider) {
|
||||
glDataFormatCallback = (IGLColorMapDataFormatProvider) callback;
|
||||
}
|
||||
this.data = new GLBufferColorMapData(cmData,
|
||||
glDataFormatCallback.getGLColorMapDataFormat(cmData));
|
||||
if (isStaged()) {
|
||||
ImageCache.getInstance(CacheType.MEMORY).put(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// The data fetch didn't go well
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.viz.core.gl.images.GLCMTextureData#loadTexture(javax.media
|
||||
* .opengl.GL)
|
||||
*/
|
||||
@Override
|
||||
public synchronized boolean loadTexture(GL gl) throws VizException {
|
||||
if (super.loadTexture(gl)) {
|
||||
ImageCache.getInstance(CacheType.TEXTURE).put(this);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void disposeTexture() {
|
||||
super.disposeTexture();
|
||||
ImageCache.getInstance(CacheType.TEXTURE).remove(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.viz.core.gl.internal.cache.IImageCacheable#disposeTextureData
|
||||
* ()
|
||||
*/
|
||||
@Override
|
||||
public void disposeTextureData() {
|
||||
if (isStaged()) {
|
||||
getDataObject().setData(null);
|
||||
}
|
||||
ImageCache.getInstance(CacheType.MEMORY).remove(this);
|
||||
}
|
||||
|
||||
public void use() {
|
||||
refCount += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.images.GLCMTextureData#dispose()
|
||||
*/
|
||||
@Override
|
||||
public void dispose() {
|
||||
synchronized (texMap) {
|
||||
refCount -= 1;
|
||||
if (refCount == 0) {
|
||||
texMap.remove(callback);
|
||||
ImageCache.getInstance(CacheType.TEXTURE).remove(this);
|
||||
ImageCache.getInstance(CacheType.MEMORY).remove(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.images.GLCMTextureData#getTexId()
|
||||
*/
|
||||
@Override
|
||||
public int getTexId() {
|
||||
if (isLoaded()) {
|
||||
ImageCache.getInstance(CacheType.TEXTURE).put(this);
|
||||
}
|
||||
return super.getTexId();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.uf.common.util.cache.ICacheObject#getSize()
|
||||
*/
|
||||
@Override
|
||||
public int getSize() {
|
||||
GLBufferColorMapData data = getDataObject();
|
||||
if (data != null) {
|
||||
int[] dimensions = data.getDimensions();
|
||||
int totalSize = data.getBytesPerPixel();
|
||||
for (int i = 0; i < dimensions.length; ++i) {
|
||||
totalSize *= dimensions[i];
|
||||
}
|
||||
return totalSize;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see com.raytheon.viz.core.gl.images.GLCMTextureData#isStaged()
|
||||
*/
|
||||
@Override
|
||||
public boolean isStaged() {
|
||||
GLBufferColorMapData data = getDataObject();
|
||||
// Override since we have our required data
|
||||
return data != null && data.getData() != null;
|
||||
}
|
||||
|
||||
public double getValue(int x, int y) {
|
||||
GLBufferColorMapData data = getDataObject();
|
||||
double value = Double.NaN;
|
||||
if (!isStaged() && isLoaded()) {
|
||||
GLContextBridge.makeMasterContextCurrent();
|
||||
GL gl = GLU.getCurrentGL();
|
||||
int textureStorageType = getTextureStorageType();
|
||||
int copybackTextureType = data.getCopyBackTextureType();
|
||||
Buffer copybackBuffer = data.getCopybackBuffer();
|
||||
gl.glEnable(textureStorageType);
|
||||
gl.glActiveTexture(GL.GL_TEXTURE0);
|
||||
tex.bind(gl, textureStorageType);
|
||||
gl.glGetTexImage(textureStorageType, 0, getTextureFormat(),
|
||||
copybackTextureType, copybackBuffer.rewind());
|
||||
gl.glActiveTexture(GL.GL_TEXTURE0);
|
||||
gl.glBindTexture(textureStorageType, 0);
|
||||
gl.glDisable(textureStorageType);
|
||||
|
||||
data.setTextureType(copybackTextureType);
|
||||
data.setData(copybackBuffer);
|
||||
GLContextBridge.releaseMasterContext();
|
||||
}
|
||||
if (data != null) {
|
||||
ImageCache.getInstance(CacheType.MEMORY).put(this);
|
||||
value = data.getValue(x, y).doubleValue();
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see
|
||||
* com.raytheon.viz.core.gl.images.GLCMTextureData#uploadTexture2D(javax
|
||||
* .media.opengl.GL, int, int, int)
|
||||
*/
|
||||
@Override
|
||||
protected void createTexture2D(GL gl, int type, int w, int h) {
|
||||
gl.glTexImage2D(type, 0, getTextureInternalFormat(), w, h, 0,
|
||||
getTextureFormat(), getTextureType(), getDataObject().getData()
|
||||
.rewind());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Unit} associated with the data
|
||||
*
|
||||
* @return the dataUnit
|
||||
*/
|
||||
public Unit<?> getDataUnit() {
|
||||
GLBufferColorMapData data = getDataObject();
|
||||
return data != null ? data.getDataUnit() : null;
|
||||
}
|
||||
}
|
|
@ -19,8 +19,6 @@
|
|||
**/
|
||||
package com.raytheon.viz.core.gl.internal.cache;
|
||||
|
||||
import javax.media.opengl.GL;
|
||||
|
||||
import com.raytheon.uf.common.util.cache.ICacheObject;
|
||||
|
||||
/**
|
||||
|
@ -44,6 +42,6 @@ public interface IImageCacheable extends ICacheObject {
|
|||
|
||||
public abstract void disposeTextureData();
|
||||
|
||||
public abstract void disposeTexture(GL gl);
|
||||
public abstract void disposeTexture();
|
||||
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ public class ImageCache extends LRUCache<Object, IImageCacheable> implements
|
|||
new GLDisposer() {
|
||||
@Override
|
||||
protected void dispose(GL gl) {
|
||||
i.disposeTexture(gl);
|
||||
i.disposeTexture();
|
||||
}
|
||||
}.dispose();
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ import com.raytheon.uf.viz.core.DrawableImage;
|
|||
import com.raytheon.uf.viz.core.IExtent;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IMosaicImageExtension;
|
||||
import com.raytheon.uf.viz.core.drawables.ext.IMosaicImageExtension.IMosaicImage;
|
||||
import com.raytheon.viz.core.gl.images.GLColormappedImage;
|
||||
import com.raytheon.viz.core.gl.images.GLDelegateImage;
|
||||
import com.raytheon.viz.core.gl.images.GLOffscreenColormappedImage;
|
||||
|
||||
/**
|
||||
* GL implementation of IMosaicImage, wraps an offscreen image and contains
|
||||
|
@ -47,7 +47,7 @@ import com.raytheon.viz.core.gl.images.GLDelegateImage;
|
|||
* @version 1.0
|
||||
*/
|
||||
|
||||
public class GLMosaicImage extends GLDelegateImage<GLColormappedImage>
|
||||
public class GLMosaicImage extends GLDelegateImage<GLOffscreenColormappedImage>
|
||||
implements IMosaicImage {
|
||||
|
||||
private DrawableImage[] images;
|
||||
|
@ -63,7 +63,7 @@ public class GLMosaicImage extends GLDelegateImage<GLColormappedImage>
|
|||
* @param image
|
||||
* @param extensionClass
|
||||
*/
|
||||
public GLMosaicImage(GLColormappedImage image, int[] bounds,
|
||||
public GLMosaicImage(GLOffscreenColormappedImage image, int[] bounds,
|
||||
IExtent imageExtent,
|
||||
Class<? extends IMosaicImageExtension> extensionClass) {
|
||||
super(image, extensionClass);
|
||||
|
@ -167,7 +167,7 @@ public class GLMosaicImage extends GLDelegateImage<GLColormappedImage>
|
|||
return image.getValue(x, y);
|
||||
}
|
||||
|
||||
public void setWrappedImage(GLColormappedImage wrappedImage) {
|
||||
public void setWrappedImage(GLOffscreenColormappedImage wrappedImage) {
|
||||
this.image.dispose();
|
||||
this.image = wrappedImage;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import com.raytheon.viz.core.gl.glsl.AbstractGLSLImagingExtension;
|
|||
import com.raytheon.viz.core.gl.glsl.GLShaderProgram;
|
||||
import com.raytheon.viz.core.gl.images.AbstractGLImage;
|
||||
import com.raytheon.viz.core.gl.images.GLColormappedImage;
|
||||
import com.raytheon.viz.core.gl.images.GLOffscreenColormappedImage;
|
||||
|
||||
/**
|
||||
* Extension used for rendering radar mosaic images
|
||||
|
@ -47,9 +48,11 @@ import com.raytheon.viz.core.gl.images.GLColormappedImage;
|
|||
*
|
||||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Dec 16, 2011 mschenke Initial creation
|
||||
* Dec 16, 2011 mschenke Initial creation
|
||||
* Mar 21, 2013 1806 bsteffen Update GL mosaicing to use dynamic data
|
||||
* format for offscreen textures.
|
||||
* Oct 16, 2013 2333 mschenke Cleaned up render logic, switched to
|
||||
* use GLOffscreenColormappedImage
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -60,11 +63,12 @@ import com.raytheon.viz.core.gl.images.GLColormappedImage;
|
|||
public class GLMosaicImageExtension extends AbstractGLSLImagingExtension
|
||||
implements IMosaicImageExtension {
|
||||
|
||||
private GLColormappedImage writeToImage;
|
||||
private GLOffscreenColormappedImage writeToImage;
|
||||
|
||||
public GLMosaicImage initializeRaster(int[] imageBounds,
|
||||
IExtent imageExtent, ColorMapParameters params) throws VizException {
|
||||
// Since byte is the most common type of mosaic start with a byte image. It might switch later if needed.
|
||||
// Since byte is the most common type of mosaic start with a byte image.
|
||||
// It might switch later if needed when images to mosaic are set
|
||||
return new GLMosaicImage(target.getExtension(
|
||||
GLOffscreenRenderingExtension.class).constructOffscreenImage(
|
||||
ColorMapDataType.BYTE, imageBounds, params), imageBounds,
|
||||
|
@ -80,6 +84,7 @@ public class GLMosaicImageExtension extends AbstractGLSLImagingExtension
|
|||
*/
|
||||
@Override
|
||||
public String getShaderProgramName() {
|
||||
// Default mosaicing algorithm glsl program
|
||||
return "mosaicOrdered";
|
||||
}
|
||||
|
||||
|
@ -96,36 +101,47 @@ public class GLMosaicImageExtension extends AbstractGLSLImagingExtension
|
|||
AbstractGLImage image, PixelCoverage coverage) throws VizException {
|
||||
if (image instanceof GLMosaicImage) {
|
||||
GLMosaicImage mosaicImage = (GLMosaicImage) image;
|
||||
boolean drawMosaic = true;
|
||||
if (mosaicImage.isRepaint()) {
|
||||
writeToImage = getWriteToImage(mosaicImage);
|
||||
GLOffscreenRenderingExtension extension = target
|
||||
.getExtension(GLOffscreenRenderingExtension.class);
|
||||
try {
|
||||
extension.renderOffscreen(mosaicImage,
|
||||
mosaicImage.getImageExtent());
|
||||
DrawableImage[] imagesToMosaic = mosaicImage
|
||||
.getImagesToMosaic();
|
||||
// Make sure images are staged before we mosaic them
|
||||
ImagingSupport.prepareImages(target, imagesToMosaic);
|
||||
DrawableImage[] imagesToMosaic = mosaicImage
|
||||
.getImagesToMosaic();
|
||||
// Make sure images are staged before we mosaic them
|
||||
ImagingSupport.prepareImages(target, imagesToMosaic);
|
||||
|
||||
boolean allPainted = true;
|
||||
// Each image needs to draw separately due to gl issues when
|
||||
// zoomed in very far, rendered parts near the corners don't
|
||||
// show all the pixels for each image. Pushing and popping
|
||||
// GL_TEXTURE_BIT before/after each render fixes this issue
|
||||
for (DrawableImage di : imagesToMosaic) {
|
||||
allPainted &= drawRasters(paintProps, di);
|
||||
writeToImage = getWriteToImage(mosaicImage);
|
||||
if (writeToImage != null) {
|
||||
GLOffscreenRenderingExtension extension = target
|
||||
.getExtension(GLOffscreenRenderingExtension.class);
|
||||
try {
|
||||
extension.beginOffscreenRendering(mosaicImage,
|
||||
mosaicImage.getImageExtent());
|
||||
|
||||
boolean allPainted = true;
|
||||
// Each image needs to draw separately due to gl issues
|
||||
// when zoomed in very far, rendered parts near the
|
||||
// corners don't show all the pixels for each image.
|
||||
// Pushing and popping GL_TEXTURE_BIT before/after each
|
||||
// render fixes this issue
|
||||
for (DrawableImage di : imagesToMosaic) {
|
||||
allPainted &= drawRasters(paintProps, di);
|
||||
}
|
||||
// Need to set repaint based on if drawing completed.
|
||||
mosaicImage.setRepaint(allPainted == false);
|
||||
} finally {
|
||||
extension.endOffscreenRendering();
|
||||
}
|
||||
// Need to set repaint based on if drawing completed.
|
||||
mosaicImage.setRepaint(allPainted == false);
|
||||
} finally {
|
||||
extension.renderOnscreen();
|
||||
writeToImage = null;
|
||||
} else {
|
||||
drawMosaic = false;
|
||||
mosaicImage.setRepaint(true);
|
||||
}
|
||||
writeToImage = null;
|
||||
}
|
||||
|
||||
target.drawRasters(paintProps,
|
||||
new DrawableImage(mosaicImage.getWrappedImage(), coverage));
|
||||
if (drawMosaic) {
|
||||
target.drawRasters(paintProps,
|
||||
new DrawableImage(mosaicImage.getWrappedImage(),
|
||||
coverage));
|
||||
}
|
||||
// Don't actually render this image now since we just did it
|
||||
return null;
|
||||
} else {
|
||||
|
@ -138,12 +154,13 @@ public class GLMosaicImageExtension extends AbstractGLSLImagingExtension
|
|||
}
|
||||
}
|
||||
|
||||
private GLColormappedImage getWriteToImage(GLMosaicImage mosaicImage)
|
||||
throws VizException {
|
||||
private GLOffscreenColormappedImage getWriteToImage(
|
||||
GLMosaicImage mosaicImage) throws VizException {
|
||||
ColorMapDataType neededType = null;
|
||||
for (DrawableImage di : mosaicImage.getImagesToMosaic()) {
|
||||
IImage image = di.getImage();
|
||||
if (image.getStatus() != Status.LOADED) {
|
||||
if (image.getStatus() != Status.LOADED
|
||||
&& image.getStatus() != Status.STAGED) {
|
||||
continue;
|
||||
}
|
||||
if (image instanceof GLColormappedImage) {
|
||||
|
@ -158,11 +175,17 @@ public class GLMosaicImageExtension extends AbstractGLSLImagingExtension
|
|||
}
|
||||
}
|
||||
}
|
||||
GLColormappedImage writeTo = mosaicImage.getWrappedImage();
|
||||
|
||||
if (neededType == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
GLOffscreenColormappedImage writeTo = mosaicImage.getWrappedImage();
|
||||
if (neededType != null && neededType != writeTo.getColorMapDataType()) {
|
||||
GLOffscreenRenderingExtension offscreenExt = target
|
||||
.getExtension(GLOffscreenRenderingExtension.class);
|
||||
int[] dimensions = { writeTo.getWidth(), writeTo.getHeight() };
|
||||
writeTo.dispose();
|
||||
writeTo = offscreenExt.constructOffscreenImage(neededType,
|
||||
dimensions, writeTo.getColorMapParameters());
|
||||
mosaicImage.setWrappedImage(writeTo);
|
||||
|
|
|
@ -220,8 +220,8 @@ public class SatResource extends
|
|||
InterrogationResult result = null;
|
||||
synchronized (tileMap) {
|
||||
for (SatTileSetRenderable renderable : tileMap.values()) {
|
||||
double rValue = renderable.interrogate(latLon);
|
||||
if (Double.isNaN(rValue) == false && rValue != fillValue) {
|
||||
double rValue = renderable.interrogate(latLon, fillValue);
|
||||
if (Double.isNaN(rValue) == false) {
|
||||
result = new InterrogationResult(
|
||||
renderable.getSatelliteRecord(), rValue);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,8 @@ import java.nio.FloatBuffer;
|
|||
import java.nio.IntBuffer;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
import javax.measure.unit.Unit;
|
||||
|
||||
/**
|
||||
*
|
||||
* Container for colormap data.
|
||||
|
@ -36,6 +38,7 @@ import java.nio.ShortBuffer;
|
|||
* Date Ticket# Engineer Description
|
||||
* ------------ ---------- ----------- --------------------------
|
||||
* Feb 28, 2013 bsteffen Seperate from IColorMapDataRetrievalCallback
|
||||
* Oct 16, 2013 2333 mschenke Added field for specifying the unit of the data
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -48,11 +51,13 @@ public class ColorMapData {
|
|||
BYTE, SIGNED_BYTE, UNSIGNED_SHORT, SHORT, INT, FLOAT;
|
||||
}
|
||||
|
||||
private Buffer buffer;
|
||||
private final Buffer buffer;
|
||||
|
||||
private int[] dimensions;
|
||||
private final int[] dimensions;
|
||||
|
||||
private ColorMapData.ColorMapDataType dataType;
|
||||
private final ColorMapData.ColorMapDataType dataType;
|
||||
|
||||
private final Unit<?> dataUnit;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -63,6 +68,14 @@ public class ColorMapData {
|
|||
this(buffer, dimensions, getDataType(buffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dataType
|
||||
* @param dataBounds
|
||||
*/
|
||||
public ColorMapData(ColorMapDataType dataType, int[] dimensions) {
|
||||
this(getBuffer(dataType, dimensions), dimensions, dataType);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param buffer
|
||||
* @param dataBounds
|
||||
|
@ -70,19 +83,20 @@ public class ColorMapData {
|
|||
*/
|
||||
public ColorMapData(Buffer buffer, int[] dimensions,
|
||||
ColorMapData.ColorMapDataType dataType) {
|
||||
this.buffer = buffer;
|
||||
this.dimensions = dimensions;
|
||||
this.dataType = dataType;
|
||||
this(buffer, dimensions, dataType, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dataType
|
||||
* @param buffer
|
||||
* @param dataBounds
|
||||
* @param dataType
|
||||
*/
|
||||
public ColorMapData(ColorMapDataType dataType, int[] dimensions) {
|
||||
this.buffer = getBuffer(dataType, dimensions);
|
||||
public ColorMapData(Buffer buffer, int[] dimensions,
|
||||
ColorMapData.ColorMapDataType dataType, Unit<?> dataUnit) {
|
||||
this.buffer = buffer;
|
||||
this.dimensions = dimensions;
|
||||
this.dataType = dataType;
|
||||
this.dataUnit = dataUnit;
|
||||
}
|
||||
|
||||
public Buffer getBuffer() {
|
||||
|
@ -97,6 +111,10 @@ public class ColorMapData {
|
|||
return dataType;
|
||||
}
|
||||
|
||||
public Unit<?> getDataUnit() {
|
||||
return dataUnit;
|
||||
}
|
||||
|
||||
public static ColorMapData.ColorMapDataType getDataType(Buffer buffer) {
|
||||
if (buffer instanceof FloatBuffer) {
|
||||
return ColorMapData.ColorMapDataType.FLOAT;
|
||||
|
|
|
@ -80,6 +80,8 @@ import com.raytheon.uf.common.datastorage.records.AbstractStorageRecord;
|
|||
import com.raytheon.uf.common.datastorage.records.ByteDataRecord;
|
||||
import com.raytheon.uf.common.datastorage.records.IDataRecord;
|
||||
import com.raytheon.uf.common.geospatial.ISpatialEnabled;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.ByteBufferWrapper;
|
||||
import com.raytheon.uf.common.geospatial.interpolation.data.UnsignedByteBufferWrapper;
|
||||
//import com.raytheon.viz.core.gl.dataprep.ByteDataPreparer;
|
||||
//import com.raytheon.viz.core.gl.dataprep.GlNumericImageData;
|
||||
import com.raytheon.viz.core.gl.dataformat.GLByteDataFormat;
|
||||
|
@ -845,15 +847,11 @@ SoundingModelReader sndingMdlRdr = new SoundingModelReader(
|
|||
double tempDbl = Double.NaN;
|
||||
if (retriever != null ){
|
||||
|
||||
/* Wrap the raw data of bytes into a GLByteDataFormat object */
|
||||
//TODO? GLColorMapDataFormatFactory bdff = new GLColorMapDataFormatFactory();
|
||||
//TODO? GLByteDataFormat bdf = bdff.getGLColorMapDataFormat(byteBuffer, retriever, rectangle, new int[] {maxX,maxY});
|
||||
GLByteDataFormat bdf = new GLByteDataFormat();
|
||||
ColorMapData cmd = new ColorMapData(byteBuffer, new int[] {maxX,maxY});
|
||||
GLColorMapData glColorMapData = new GLColorMapData(cmd, bdf);
|
||||
/* Wrap the raw data of bytes into a ByteBufferWrapper object */
|
||||
UnsignedByteBufferWrapper bdf = new UnsignedByteBufferWrapper(byteBuffer, maxX, maxY);
|
||||
|
||||
/*Get the actual pixel value information from the byte array */
|
||||
tempDbl = bdf.getValue( ( int )( outCoord[ 0 ] ), ( int ) ( outCoord[ 1 ] ), glColorMapData );
|
||||
tempDbl = bdf.getDataValue( ( int )( outCoord[ 0 ] ), ( int ) ( outCoord[ 1 ] ));
|
||||
|
||||
if ( isSinglePixelNeeded ){
|
||||
pixVal = new Double( (tempDbl) );
|
||||
|
@ -880,7 +878,7 @@ SoundingModelReader sndingMdlRdr = new SoundingModelReader(
|
|||
/*Generate the NxN array of pixel values*/
|
||||
for ( int i = 0 ; i < newArrDimensions ; i++){
|
||||
for ( int j = 0 ; j < newArrDimensions ; j++){
|
||||
arrayOfPixVal[i][j] = bdf.getValue( ( int )( squarePixelArea[i][j].xCoord ), ( int ) ( squarePixelArea[i][j].yCoord ), glColorMapData );
|
||||
arrayOfPixVal[i][j] = bdf.getDataValue( ( int )( squarePixelArea[i][j].xCoord ), ( int ) ( squarePixelArea[i][j].yCoord ));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue