Issue #345 fix issues with gl contexts and creation and deletion of gl objects!

Change-Id: Ied6c7a814478e21f3cd0eccabfecb00a92e698db

Former-commit-id: 73d24fad2f [formerly e0f697c492eecff4bb8d83d05efbcaf2876125c9]
Former-commit-id: 69e8cde115
This commit is contained in:
Ben Steffensmeier 2012-02-20 15:25:28 -06:00
parent d4b76c1057
commit 27973ec694
31 changed files with 1006 additions and 687 deletions

View file

@ -106,12 +106,11 @@ public abstract class AbstractGLMesh implements IMesh {
}
if (!compiled) {
vertexCoords.setTarget(glTarget);
vertexCoords.compile();
vertexCoords.compile(glTarget.getGl());
compiled = true;
}
GLGeometryPainter.paintGeometries(glTarget, vertexCoords,
GLGeometryPainter.paintGeometries(glTarget.getGl(), vertexCoords,
sharedTextureCoords.getTextureCoords());
}

View file

@ -1,73 +0,0 @@
/**
* 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;
import org.eclipse.swt.opengl.GLCanvas;
/**
*
* Caches the initial GLCanvas
*
* This is not ideal, since the SWT resources for the first canvas are always
* left open after the map is disposed, but due to limitations in JOGL and
* Eclipse, it is necessary.
*
* <pre>
* SOFTWARE HISTORY
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jul 10, 2007 chammack Initial Creation.
*
* </pre>
*
* @author chammack
* @version 1.0
*/
public class GLCanvasCache {
private static GLCanvasCache instance;
private GLCanvas canvas;
public static synchronized GLCanvasCache getInstance() {
if (instance == null) {
instance = new GLCanvasCache();
}
return instance;
}
/**
* @return the canvas
*/
public GLCanvas getCanvas() {
return canvas;
}
/**
* @param canvas
* the canvas to set
*/
public void setCanvas(GLCanvas canvas) {
this.canvas = canvas;
}
}

View file

@ -0,0 +1,203 @@
/**
* 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;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLPbuffer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.opengl.GLCanvas;
import org.eclipse.swt.opengl.GLData;
import org.eclipse.swt.widgets.Shell;
import com.raytheon.uf.viz.core.exception.VizException;
/**
*
* Provide a mechanism for keeping JOGL GLContext in sync with the SWT GLCanvas
* context. The JOGL GLContext has most of the logic needed to manage contexts,
* except for when the context is external. Since our context is created by the
* SWT GLCanvas the JOGL GLContext does not actually control the active context
* in GL. This class contains a GLCanvas and a GLContext and keeps the active
* context in sync between the two.
*
* This class also provides static access to the "Master Context" which is a
* context with which all other contexts are sharing data. Ideally we would not
* need to use the master context however there is a bug in some Windows/Intel
* drivers which causes crashes if a texture is created on a context, then the
* context is deleted, then the texture is deleted on a different context. To
* resolve this all textures should be created and deleted on the master
* context. This is done by calling makeMasterContextCurrent before calling
* glGenTexture or glDeleteTexture and then calling releaseMasterContext
* immediately after to restore the previous context.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 17, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class GLContextBridge {
private static GLContextBridge activeContext;
private static GLContextBridge masterContext;
private static GLContextBridge previousContext;
private final GLCanvas canvas;
private final GLContext context;
public GLContextBridge(int width, int height) throws VizException {
GLCapabilities glCap = new GLCapabilities();
if (!GLDrawableFactory.getFactory().canCreateGLPbuffer()) {
throw new VizException(
"Graphics card does not support GLPbuffer and "
+ "therefore does not support offscreen rendering.");
}
GLPbuffer buf = GLDrawableFactory.getFactory().createGLPbuffer(glCap,
null, width, height, null);
this.context = buf.createContext(null);
this.canvas = null;
activeContext = this;
releaseContext();
}
public GLContextBridge(GLCanvas canvas) {
this.canvas = canvas;
this.canvas.setCurrent();
this.context = GLDrawableFactory.getFactory().createExternalGLContext();
activeContext = this;
releaseContext();
}
/**
* Make this context current for any GL Operations and release any
* previously active context.
*
* @return true if this context was not previously active and should
* therefore be released when you are done performing gl operations
*/
public boolean makeContextCurrent() {
if (canvas != null && !canvas.isDisposed()) {
canvas.setCurrent();
} else if (canvas != null) {
throw new RuntimeException(
"Cannot make gl context current, GLCanvas is disposed");
}
GLContext oldContext = GLContext.getCurrent();
if (context != oldContext) {
if (oldContext != null) {
oldContext.release();
}
if (context.makeCurrent() == GLContext.CONTEXT_NOT_CURRENT) {
throw new RuntimeException(
"Cannot make gl context current, Unknown error occured.");
}
}
boolean retVal = (activeContext != this);
activeContext = this;
return retVal;
}
public void releaseContext() {
if (context == GLContext.getCurrent()) {
context.release();
}
if (activeContext == this) {
activeContext = null;
}
}
public void destroyContext() {
releaseContext();
context.destroy();
}
/**
* get the GLData to use when creating a new GLCanvas, data.shareContext
* will contain the canvas for the "Master Context"
*
* @return
*/
public static GLData getGLData() {
return getGLData(true);
}
private static GLData getGLData(boolean setContext) {
GLData data = new GLData();
data.stencilSize = 1;
data.depthSize = 1;
data.doubleBuffer = true;
if (setContext) {
data.shareContext = getMasterContext().canvas;
}
return data;
}
private static GLContextBridge getMasterContext() {
if (masterContext == null) {
GLCanvas canvas = new GLCanvas(new Shell(), SWT.NONE,
getGLData(false));
masterContext = new GLContextBridge(canvas);
}
return masterContext;
}
/**
* This method makes the shared master context the active contexts, it also
* stores the current active context to be restored on release.
*
*/
public static void makeMasterContextCurrent() {
if (masterContext != null) {
if (activeContext != null) {
previousContext = activeContext;
activeContext.releaseContext();
}
masterContext.makeContextCurrent();
}
}
/**
* Releases the master context and restores the context that was active
* before makeMasterContextCurrent was called.
*/
public static void releaseMasterContext() {
if (masterContext != null) {
masterContext.releaseContext();
if (previousContext != null) {
previousContext.makeContextCurrent();
previousContext = null;
}
}
}
}

View file

@ -0,0 +1,127 @@
/**
* 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;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
import javax.media.opengl.GL;
/**
*
* This class provides a convenient way of disposing of GL resources on an
* active GLContext.
*
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 17, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class GLDisposalManager {
private static ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
private static List<GLAutoDisposer> autoDisposers = new LinkedList<GLAutoDisposer>();
private static Queue<GLDisposer> disposeQueue = new LinkedBlockingQueue<GLDisposer>();
/**
* This method should be used to dispose of a GL resource, at the end of a
* frame the target will make the context current and dispose of all
* resources.
*
* @param disposer
* a disposer object that is ready to dispose of a gl resource.
*/
private static void dispose(GLDisposer disposer) {
disposeQueue.add(disposer);
}
/**
* Provide a backup mechanism to dispose. This uses WeakReference objects to
* call the disposer after the object is garbage collected. For this to work
* the disposer must have no references to object. Object should be the only
* thing using these GL resources, this will not work for anything which
* might be shared by multiple objects. This will also result in the dispose
* method of the disposer being called more than once so it should clear any
*
* @param disposer
* - a disposer that will be called when object is garbage
* collected
* @param object
* - an object which uses a gl resource.
*/
public static void autoDispose(GLDisposer disposer, Object object) {
autoDisposers.add(new GLAutoDisposer(object, disposer));
}
/**
* For use by the target only, the target should call this to dispose all
* unneeded resources
*
* @param gl
*/
public static void performDispose(GL gl) {
GLDisposer disposer = disposeQueue.poll();
while (disposer != null) {
disposer.dispose(gl);
disposer = disposeQueue.poll();
}
GLAutoDisposer autoDisposer = (GLAutoDisposer) refQueue.poll();
while (autoDisposer != null) {
autoDisposers.remove(autoDisposer);
autoDisposer.disposer.dispose();
autoDisposer = (GLAutoDisposer) refQueue.poll();
}
}
public static abstract class GLDisposer {
protected abstract void dispose(GL gl);
final public void dispose() {
GLDisposalManager.dispose(this);
}
}
private static class GLAutoDisposer extends WeakReference<Object> {
private final GLDisposer disposer;
public GLAutoDisposer(Object referent, GLDisposer disposer) {
super(referent, refQueue);
this.disposer = disposer;
}
}
}

View file

@ -26,7 +26,6 @@ import org.eclipse.swt.opengl.GLCanvas;
import org.eclipse.swt.opengl.GLData;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;
import org.opengis.coverage.grid.GridEnvelope;
import com.raytheon.uf.viz.core.AbstractGraphicsFactoryAdapter;
@ -145,19 +144,7 @@ public class GLFactoryAdapter extends AbstractGraphicsFactoryAdapter {
@Override
public Canvas constrcutCanvas(Composite canvasComp) throws VizException {
GLCanvas canvas;
GLData data = new GLData();
data.stencilSize = 1;
data.depthSize = 1;
data.doubleBuffer = true;
GLCanvas cachedCanvas = GLCanvasCache.getInstance().getCanvas();
if (cachedCanvas == null) {
Shell invisibleShell = new Shell();
cachedCanvas = new GLCanvas(invisibleShell, SWT.NONE, data);
GLCanvasCache.getInstance().setCanvas(cachedCanvas);
cachedCanvas.setCurrent();
}
data.shareContext = cachedCanvas;
GLData data = GLContextBridge.getGLData();
canvas = new GLCanvas(canvasComp, SWT.NONE, data);
canvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
@ -173,8 +160,7 @@ public class GLFactoryAdapter extends AbstractGraphicsFactoryAdapter {
*/
@Override
public void disposeCanvas(Canvas canvas) {
GLCanvas cachedCanvas = GLCanvasCache.getInstance().getCanvas();
if (cachedCanvas != canvas && !canvas.isDisposed()) {
if (!canvas.isDisposed()) {
canvas.getParent().dispose();
}
}

View file

@ -29,8 +29,8 @@ import java.util.List;
import javax.media.opengl.GL;
import com.raytheon.uf.viz.core.IExtent;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.viz.core.gl.objects.GLVertexBufferObject;
/**
* GL Geometry object, supports compiling into VBOs. Coordinates passed in will
@ -53,9 +53,6 @@ import com.raytheon.uf.viz.core.exception.VizException;
public class GLGeometryObject2D {
public static class GLGeometryObjectData {
private IGLTarget target;
private GL gl;
public IExtent worldExtent;
@ -72,12 +69,6 @@ public class GLGeometryObject2D {
this.coordType = coordType;
}
public void setTarget(IGLTarget target) {
this.target = target;
if (target != null) {
gl = target.getGl();
}
}
}
protected static enum State {
@ -96,7 +87,7 @@ public class GLGeometryObject2D {
protected int points;
protected int vboId;
protected GLVertexBufferObject vbo;
protected State state;
@ -104,8 +95,6 @@ public class GLGeometryObject2D {
public GLGeometryObject2D(GLGeometryObjectData data) {
this.data = new GLGeometryObjectData(data.geometryType, data.coordType);
this.data.gl = data.gl;
this.data.target = data.target;
this.data.manageIndicies = data.manageIndicies;
this.data.mutable = data.mutable;
this.data.worldExtent = data.worldExtent;
@ -119,16 +108,16 @@ public class GLGeometryObject2D {
}
compiledIndicies = null;
points = 0;
vboId = -1;
vbo = null;
state = State.MUTABLE;
}
public void compile() throws VizException {
public void compile(GL gl) throws VizException {
// We will use glMultiDrawArrays if the cardSupportsHighEndFeatures, so
// we will keep track of a lenghts buffer
state = State.COMPILED;
int add = 1;
if (GLCapabilities.getInstance(data.gl).cardSupportsHighEndFeatures) {
if (GLCapabilities.getInstance(gl).cardSupportsHighEndFeatures) {
state = State.COMPILED_HIGH_END;
add = 0;
}
@ -169,24 +158,21 @@ public class GLGeometryObject2D {
copy.put(data.get());
}
GL gl = this.data.gl;
// clear the error bit.
this.data.target.makeContextCurrent();
gl.glGetError();
// generate vbo
vboId = GLVBOCleaner.allocateVBO(this, this.data.target);
vbo = new GLVertexBufferObject(this);
// verify successful
if (vboId <= 0) {
vboId = -1;
if (!vbo.isValid()) {
vbo = null;
throw new VizException("Error compiling wireframe shape, "
+ "could not generate vertex buffer object");
}
// bind and load
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, vboId);
vbo.bind(gl, GL.GL_ARRAY_BUFFER);
gl.glBufferData(GL.GL_ARRAY_BUFFER, copy.capacity() * 4,
copy.rewind(), GL.GL_STATIC_DRAW);
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, 0);
@ -223,16 +209,8 @@ public class GLGeometryObject2D {
compiledLengths = null;
state = State.INVALID;
if (vboId > -1) {
final int vbo = vboId;
vboId = -1;
VizApp.runAsync(new Runnable() {
@Override
public void run() {
GLVBOCleaner.unallocateVBO(GLGeometryObject2D.this, vbo,
data.target);
}
});
if (vbo != null && vbo.isValid()) {
vbo.dispose();
}
}
@ -368,15 +346,8 @@ public class GLGeometryObject2D {
}
}
public synchronized void paint() throws VizException {
GLGeometryPainter.paintGeometries(data.target, this);
}
public void setTarget(IGLTarget target) {
data.target = target;
if (data.target != null) {
data.gl = target.getGl();
}
public synchronized void paint(GL gl) throws VizException {
GLGeometryPainter.paintGeometries(gl, this);
}
// 2D specific functions, override for 3D support

View file

@ -50,9 +50,8 @@ public class GLGeometryPainter {
private static int maxVertices = -1;
public static void paintGeometries(IGLTarget target,
GLGeometryObject2D... geoms) throws VizException {
GL gl = target.getGl();
public static void paintGeometries(GL gl, GLGeometryObject2D... geoms)
throws VizException {
State state = State.INVALID;
Set<State> states = new HashSet<State>();
for (GLGeometryObject2D geom : geoms) {
@ -131,11 +130,11 @@ public class GLGeometryPainter {
case COMPILED:
case COMPILED_HIGH_END: {
for (GLGeometryObject2D geom : geoms) {
if (geom.vboId <= 0) {
if (!geom.vbo.isValid()) {
throw new VizException(
"Could not paint geometry, VBO not set!");
}
gl.glBindBuffer(GL.GL_ARRAY_BUFFER, geom.vboId);
geom.vbo.bind(gl, GL.GL_ARRAY_BUFFER);
switch (geom.data.coordType) {
case GL.GL_VERTEX_ARRAY: {
gl.glVertexPointer(geom.pointsPerCoordinate(), GL.GL_FLOAT,

View file

@ -1,138 +0,0 @@
/**
* 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;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.media.opengl.GL;
/**
*
* This class uses WeakReference to guarantee that all vbos are deallocated even
* if dispose is never called. It is still better to call dispose to avoid
* having "dead" vbos on the graphics card, which can slow down rendering.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jun 9, 2011 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class GLVBOCleaner extends WeakReference<Object> {
/**
* This is needed so when unallocate is called we can set the vboId to -1
* and stop it from being redeleted
*/
private static List<GLVBOCleaner> cleaners = new LinkedList<GLVBOCleaner>();
/**
* THis queue will contain all garbage collected vbo objects, if everyone
* deallocates all vboIds will be -1.
*/
private static ReferenceQueue<Object> queue = new ReferenceQueue<Object>();
/**
* get a new vboId from gl which will be linked to object, if object is
* garbage collected then the vbo will still be freed. This should only be
* called on the main thread.
*
* @param object
* @param target
* @return
*/
public static int allocateVBO(Object object, IGLTarget target) {
target.makeContextCurrent();
clean(target.getGl());
GLVBOCleaner cleaner = new GLVBOCleaner(object, target.getGl());
target.handleError(target.getGl().glGetError());
// verify successful
if (cleaner.vboId > 0) {
cleaners.add(cleaner);
}
return cleaner.vboId;
}
/**
* Immediately free a vbo which has been allocated, any method that uses
* allocate should also use deallocate. object must be the same as the
* object passed to allocate.
*
* @param object
* @param vboId
* @param target
*/
public static void unallocateVBO(Object object, int vboId, IGLTarget target) {
target.makeContextCurrent();
clean(target.getGl());
if (vboId <= 0) {
return;
}
Iterator<GLVBOCleaner> iter = cleaners.iterator();
while (iter.hasNext()) {
GLVBOCleaner cleaner = iter.next();
if (cleaner.get() == object && cleaner.vboId == vboId) {
cleaner.freeVbo(target.getGl());
iter.remove();
}
}
}
private static void clean(GL gl) {
GLVBOCleaner cleaner = (GLVBOCleaner) queue.poll();
while (cleaner != null) {
if (cleaner.vboId > 0) {
System.err
.println("An object with a gl vertex buffer object has been garbage collected without being disposed. This can cause a delay in freeing vbos which can cause severe performance problems.");
cleaner.freeVbo(gl);
}
cleaners.remove(cleaner);
cleaner = (GLVBOCleaner) queue.poll();
}
}
private int vboId;
private GLVBOCleaner(Object referent, GL gl) {
super(referent, queue);
int[] vbos = new int[1];
gl.glGenBuffers(1, vbos, 0);
this.vboId = vbos[0];
}
private void freeVbo(GL gl) {
gl.glDeleteBuffers(1, new int[] { this.vboId }, 0);
this.vboId = -1;
}
}

View file

@ -20,7 +20,6 @@
package com.raytheon.viz.core.gl;
import com.raytheon.uf.viz.core.drawables.IFont;
import com.raytheon.viz.core.gl.internal.GLTarget;
import com.sun.opengl.util.j2d.TextRenderer;
/**
@ -49,13 +48,6 @@ public interface IGLFont extends IFont {
*/
public TextRenderer getTextRenderer();
/**
* Get the target for the font
*
* @return
*/
public GLTarget getTarget();
/**
* Force a dispose
*/

View file

@ -20,7 +20,6 @@
package com.raytheon.viz.core.gl;
import javax.media.opengl.GL;
import javax.media.opengl.GLContext;
import javax.media.opengl.glu.GLU;
import org.eclipse.swt.graphics.Rectangle;
@ -54,6 +53,12 @@ public interface IGLTarget extends IGraphicsTarget {
*/
public abstract boolean makeContextCurrent();
/**
*
* @return
*/
public abstract void releaseContext();
/**
* Get the modle view matrix settings
*
@ -101,21 +106,6 @@ public interface IGLTarget extends IGraphicsTarget {
*/
public abstract Rectangle getBounds();
/**
* Get the gl context
*
* @return
*/
public abstract GLContext getContext();
/**
* Dispose luminance texture
*
* @param id
* @param pboID
*/
public abstract void disposeLuminanceTexture(int id, int pboID);
/**
* Dispose a vbo
*
@ -186,4 +176,5 @@ public interface IGLTarget extends IGraphicsTarget {
* Checks the glError state and does a UFStatus message
*/
public abstract void handleError(int errorid);
}

View file

@ -98,9 +98,8 @@ public class SharedCoordMap {
GL.GL_TRIANGLE_STRIP, GL.GL_TEXTURE_COORD_ARRAY);
data.manageIndicies = false;
textureCoords = new GLGeometryObject2D(data);
textureCoords.setTarget(glTarget);
populateTextureGeom(key, textureCoords);
textureCoords.compile();
textureCoords.compile(glTarget.getGl());
}
private void incRef() {

View file

@ -20,14 +20,14 @@
package com.raytheon.viz.core.gl.images;
import javax.media.opengl.GL;
import javax.media.opengl.GLContext;
import javax.media.opengl.glu.GLU;
import com.raytheon.uf.viz.core.IGraphicsTarget;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.drawables.IImage;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.viz.core.gl.IGLTarget;
import com.raytheon.viz.core.gl.internal.GLTarget;
import com.raytheon.viz.core.gl.GLContextBridge;
import com.raytheon.viz.core.gl.objects.GLFrameBufferObject;
import com.raytheon.viz.core.gl.objects.GLRenderBuffer;
/**
*
@ -48,9 +48,6 @@ import com.raytheon.viz.core.gl.internal.GLTarget;
*/
public abstract class AbstractGLImage implements IImage {
/** The GL graphics target */
protected IGLTarget theTarget;
/** The brightness of the image */
private float brightness = 1.0f;
@ -67,13 +64,12 @@ public abstract class AbstractGLImage implements IImage {
protected Throwable throwable;
// Used for offscreen rendering
private int fbo = -1;
private GLFrameBufferObject fbo;
// Used for offscreen rendering
private int rbuf = -1;
private GLRenderBuffer rbuf;
protected AbstractGLImage(IGLTarget target) {
this.theTarget = target;
protected AbstractGLImage() {
}
/**
@ -113,10 +109,10 @@ public abstract class AbstractGLImage implements IImage {
* IGraphicsTarget)
*/
public void target(IGraphicsTarget target) throws VizException {
theTarget = (GLTarget) target;
GLContext ctx = theTarget.getContext();
// TextureLoaderJob.getInstance().requestLoadIntoTexture(this, ctx);
this.loadTexture(ctx);
GLContextBridge.makeMasterContextCurrent();
this.loadTexture(GLU.getCurrentGL());
GLContextBridge.releaseMasterContext();
}
/*
@ -158,117 +154,64 @@ public abstract class AbstractGLImage implements IImage {
}
public void dispose() {
if (fbo > 0 || rbuf > 0) {
final int[] bufs = new int[] { -1, -1 };
if (fbo > 0) {
bufs[0] = fbo;
fbo = -1;
if (fbo != null) {
fbo.dispose();
fbo = null;
}
if (rbuf > 0) {
bufs[1] = rbuf;
rbuf = -1;
}
VizApp.runAsync(new Runnable() {
@Override
public void run() {
theTarget.makeContextCurrent();
if (bufs[0] > 0) {
theTarget.getGl().glDeleteFramebuffersEXT(1,
new int[] { bufs[0] }, 0);
}
if (bufs[1] > 0) {
theTarget.getGl().glDeleteRenderbuffersEXT(1,
new int[] { bufs[1] }, 0);
}
}
});
if (rbuf != null) {
rbuf.dispose();
rbuf = null;
}
}
public void usaAsFrameBuffer() throws VizException {
GL gl = theTarget.getGl();
if (fbo != -1) {
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, fbo);
GL gl = GLU.getCurrentGL();
if (fbo != null && fbo.isValid()) {
fbo.bind(gl);
gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
if (rbuf != -1) {
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);
}
return;
}
gl = GLU.getCurrentGL();
gl.glBindTexture(getTextureStorageType(), 0);
int[] ids = new int[1];
gl.glGenFramebuffersEXT(1, ids, 0);
fbo = ids[0];
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, fbo);
fbo = new GLFrameBufferObject(this);
fbo.bind(gl);
if (gl.glIsEnabled(GL.GL_DEPTH_TEST)) {
// Generate and bind a render buffer for the depth component
gl.glGenRenderbuffersEXT(1, ids, 0);
rbuf = ids[0];
gl.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, rbuf);
gl.glRenderbufferStorageEXT(GL.GL_RENDERBUFFER_EXT,
GL.GL_DEPTH_COMPONENT, getWidth(), getHeight());
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);
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 = null;
switch (gl.glCheckFramebufferStatusEXT(GL.GL_FRAMEBUFFER_EXT)) {
case GL.GL_FRAMEBUFFER_COMPLETE_EXT: {
// Everything is ok.
break;
}
case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: {
errorMessage = "Error: Framebuffer incomplete, fbo attachement is NOT complete";
break;
}
case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: {
errorMessage = "Error: Framebuffer incomplete, no image is attached to FBO";
break;
}
case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: {
errorMessage = "Error: Framebuffer incomplete, attached images have different dimensions";
break;
}
case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: {
errorMessage = "Error: Framebuffer incomplete, color attached images have different internal formats";
break;
}
case GL.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: {
errorMessage = "Error: Framebuffer incomplete, draw buffer";
break;
}
case GL.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: {
errorMessage = "Error: Framebuffer incomplete, read buffer";
break;
}
case GL.GL_FRAMEBUFFER_UNSUPPORTED_EXT: {
errorMessage = "Error: Framebuffer not supported by hardware/drivers";
break;
}
}
String errorMessage = fbo.checkStatus(gl);
// use the window buffer
if (errorMessage != null) {
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);
if (fbo != -1) {
gl.glDeleteFramebuffersEXT(1, new int[] { fbo }, 0);
fbo = -1;
if (fbo != null) {
fbo.dispose();
fbo = null;
}
if (rbuf != -1) {
gl.glDeleteRenderbuffersEXT(1, new int[] { rbuf }, 0);
rbuf = -1;
if (rbuf != null) {
rbuf.dispose();
rbuf = null;
}
throw new VizException(errorMessage);
}
@ -280,6 +223,6 @@ public abstract class AbstractGLImage implements IImage {
public abstract void stageTexture() throws VizException;
public abstract void loadTexture(GLContext ctx) throws VizException;
public abstract void loadTexture(GL gl) throws VizException;
}

View file

@ -24,6 +24,7 @@ import java.util.HashMap;
import java.util.Map;
import javax.media.opengl.GL;
import javax.media.opengl.glu.GLU;
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback.ColorMapData;
@ -33,6 +34,7 @@ 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;
/**
*
@ -54,7 +56,7 @@ import com.raytheon.viz.core.gl.internal.cache.ImageCache.CacheType;
*/
public class GLCMTextureData implements IImageCacheable {
private int texId = -1;
private GLTextureObject tex;
private final IColorMapDataRetrievalCallback callback;
@ -83,8 +85,8 @@ public class GLCMTextureData implements IImageCacheable {
public synchronized void disposeTexture(GL gl) {
if (isLoaded()) {
gl.glDeleteTextures(1, new int[] { texId }, 0);
texId = -1;
tex.dispose();
tex = null;
}
ImageCache.getInstance(CacheType.TEXTURE).remove(this);
}
@ -131,13 +133,10 @@ public class GLCMTextureData implements IImageCacheable {
if (!stageTexture()) {
return false;
}
int type = getTextureStorageType();
int[] t = null;
t = new int[1];
gl.glGenTextures(1, t, 0);
gl.glBindTexture(type, t[0]);
tex = new GLTextureObject(this);
tex.bind(gl, type);
gl.glTexParameteri(type, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
gl.glTexParameteri(type, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
@ -162,9 +161,7 @@ public class GLCMTextureData implements IImageCacheable {
getTextureFormat(), getTextureType(), data.getData().rewind());
gl.glPixelTransferf(GL.GL_RED_SCALE, 1.0f);
gl.glPixelTransferf(GL.GL_RED_BIAS, 0.0f);
texId = t[0];
ImageCache.getInstance(CacheType.TEXTURE).put(this);
return true;
}
@ -173,7 +170,7 @@ public class GLCMTextureData implements IImageCacheable {
}
public boolean isLoaded() {
return texId > 0;
return tex != null && tex.isValid();
}
public int getDimensionSize(int dimension) {
@ -196,21 +193,25 @@ public class GLCMTextureData implements IImageCacheable {
if (isLoaded()) {
ImageCache.getInstance(CacheType.TEXTURE).put(this);
}
return texId;
return tex.getId();
}
public int getTextureStorageType() {
return GL.GL_TEXTURE_2D;
}
public double getValue(GL gl, int x, int y, float dataMin, float dataMax) {
public double getValue(int x, int y, float dataMin, float dataMax) {
if (!isStaged() && isLoaded()) {
GL gl = GLU.getCurrentGL();
if (gl == null || data == null) {
return Double.NaN;
}
int textureStorageType = getTextureStorageType();
int copybackTextureType = data.getCopyBackTextureType();
Buffer copybackBuffer = data.getCopybackBuffer();
gl.glEnable(textureStorageType);
gl.glActiveTexture(GL.GL_TEXTURE0);
gl.glBindTexture(textureStorageType, texId);
tex.bind(gl, textureStorageType);
gl.glGetTexImage(textureStorageType, 0, getTextureFormat(),
copybackTextureType, copybackBuffer.rewind());
gl.glActiveTexture(GL.GL_TEXTURE0);

View file

@ -19,7 +19,7 @@
**/
package com.raytheon.viz.core.gl.images;
import javax.media.opengl.GLContext;
import javax.media.opengl.GL;
import com.raytheon.uf.viz.core.data.IColorMapDataRetrievalCallback;
import com.raytheon.uf.viz.core.drawables.ColorMapParameters;
@ -52,7 +52,7 @@ public class GLColormappedImage extends AbstractGLImage implements
public GLColormappedImage(IColorMapDataRetrievalCallback dataCallback,
ColorMapParameters params, IGLTarget target) {
super(target);
super();
this.data = GLCMTextureData.getGlTextureId(dataCallback);
this.colorMapParameters = params;
}
@ -79,8 +79,8 @@ public class GLColormappedImage extends AbstractGLImage implements
* .GLContext)
*/
@Override
public void loadTexture(GLContext ctx) throws VizException {
if (data.loadTexture(ctx.getGL())) {
public void loadTexture(GL gl) throws VizException {
if (data.loadTexture(gl)) {
// Add to texture cache
setStatus(Status.LOADED);
data.disposeTextureData();
@ -169,12 +169,7 @@ public class GLColormappedImage extends AbstractGLImage implements
@Override
public double getValue(int x, int y) {
double val = 0;
if (theTarget == null || data == null) {
return Double.NaN;
}
val = data.getValue(theTarget.getGl(), x, y,
colorMapParameters.getDataMin(),
double val = data.getValue(x, y, colorMapParameters.getDataMin(),
colorMapParameters.getDataMax());
return val;
}

View file

@ -28,9 +28,7 @@ import java.util.Hashtable;
import javax.media.jai.PlanarImage;
import javax.media.opengl.GL;
import javax.media.opengl.GLContext;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.data.IRenderedImageCallback;
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.viz.core.gl.IGLTarget;
@ -73,7 +71,7 @@ public class GLImage extends AbstractGLImage implements IImageCacheable {
protected int size;
public GLImage(IRenderedImageCallback preparer, IGLTarget target) {
super(target);
super();
theTexture = null;
this.imagePreparer = preparer;
}
@ -113,15 +111,8 @@ public class GLImage extends AbstractGLImage implements IImageCacheable {
if (getStatus() == Status.LOADED) {
if (theTexture != null) {
final Texture tex = theTexture;
theTexture.dispose();
theTexture = null;
VizApp.runAsync(new Runnable() {
@Override
public void run() {
theTarget.makeContextCurrent();
tex.dispose();
}
});
}
if (theStagedData != null) {
setStatus(Status.STAGED);
@ -154,7 +145,7 @@ public class GLImage extends AbstractGLImage implements IImageCacheable {
* the OpenGL context
* @throws VizException
*/
public void loadTexture(GLContext ctx) throws VizException {
public void loadTexture(GL gl) throws VizException {
synchronized (this) {
Texture tex = TextureIO.newTexture(theStagedData);

View file

@ -54,7 +54,8 @@ import com.raytheon.viz.core.gl.IGLFont;
*/
public class FontFactory {
private static final transient IUFStatusHandler statusHandler = UFStatus.getHandler(FontFactory.class);
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(FontFactory.class);
public static final String DEFAULT_FONT_ID = "com.raytheon.uf.viz.core.defaultFont";
@ -85,7 +86,7 @@ public class FontFactory {
* @param target
* @return The font to use, never null
*/
public IGLFont getFont(String fontId, GLTarget target) {
public IGLFont getFont(String fontId) {
if (!registry.hasValueFor(fontId)) {
statusHandler.handle(Priority.PROBLEM,
"No font registered with id: " + fontId);
@ -108,7 +109,7 @@ public class FontFactory {
styles.add(IFont.Style.ITALIC);
}
IGLFont font = new GLFont(target, name, size,
IGLFont font = new GLFont(name, size,
styles.toArray(new IFont.Style[styles.size()]));
if (fontId.equals(DEFAULT_FONT_ID)) {
font = new UnmodifiableGLFont(font);

View file

@ -112,7 +112,7 @@ public abstract class GLAbstractView implements IView, Cloneable {
public void setupView(IGraphicsTarget target) {
IGLTarget glTarget = asIGLTarget(target);
glTarget.makeContextCurrent();
boolean release = glTarget.makeContextCurrent();
glTarget.getGl().glMatrixMode(GL.GL_PROJECTION);
glTarget.getGl().glLoadIdentity();
setProjectionMatrix(glTarget);
@ -126,6 +126,9 @@ public abstract class GLAbstractView implements IView, Cloneable {
setViewArea(glTarget);
// glTarget.setupClippingPlane(getClippingPlanes());
if (release) {
glTarget.releaseContext();
}
}
protected IGLTarget asIGLTarget(IGraphicsTarget target) {

View file

@ -67,14 +67,11 @@ public class GLFont implements IGLFont {
private boolean scaleFont = true;
private GLTarget target;
public GLFont() {
;
}
public GLFont(GLTarget target, File font, float fontSize, Style[] styles) {
this.target = target;
public GLFont(File font, float fontSize, Style[] styles) {
try {
this.font = Font.createFont(Font.TRUETYPE_FONT, font).deriveFont(
fontSize);
@ -98,9 +95,7 @@ public class GLFont implements IGLFont {
this.textRenderer = TextRendererCache.getRenderer(this.font);
}
public GLFont(GLTarget target, String fontName, float fontSize,
Style[] styles) {
this.target = target;
public GLFont(String fontName, float fontSize, Style[] styles) {
this.fontName = fontName;
this.currentFontSize = this.fontSize = fontSize;
this.styles = styles;
@ -172,9 +167,9 @@ public class GLFont implements IGLFont {
GLFont newFont = null;
if (this.fontFile != null) {
// File based construction
newFont = new GLFont(this.target, this.fontFile, size, styles);
newFont = new GLFont(this.fontFile, size, styles);
} else {
newFont = new GLFont(this.target, this.fontName, size, styles);
newFont = new GLFont(this.fontName, size, styles);
}
return newFont;
@ -259,16 +254,6 @@ public class GLFont implements IGLFont {
this.scaleFont = scaleFont;
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.core.gl.IGLFont#getTarget()
*/
@Override
public GLTarget getTarget() {
return target;
}
/*
* (non-Javadoc)
*
@ -278,15 +263,11 @@ public class GLFont implements IGLFont {
public void disposeInternal() {
if (!disposed) {
if (this.textRenderer != null) {
boolean release = target.makeContextCurrent();
TextRendererCache.releaseRenderer(this.font);
this.textRenderer = null;
disposed = true;
if (release) {
target.releaseContext();
}
}
}
}

View file

@ -40,10 +40,6 @@ import java.util.Map.Entry;
import java.util.Set;
import javax.media.opengl.GL;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLContext;
import javax.media.opengl.GLDrawableFactory;
import javax.media.opengl.GLPbuffer;
import javax.media.opengl.glu.GLU;
import javax.media.opengl.glu.GLUquadric;
import javax.vecmath.Vector3d;
@ -102,6 +98,8 @@ import com.raytheon.uf.viz.core.drawables.ext.colormap.IColormappedImageExtensio
import com.raytheon.uf.viz.core.exception.VizException;
import com.raytheon.uf.viz.core.geom.PixelCoordinate;
import com.raytheon.uf.viz.core.preferences.PreferenceConstants;
import com.raytheon.viz.core.gl.GLContextBridge;
import com.raytheon.viz.core.gl.GLDisposalManager;
import com.raytheon.viz.core.gl.IGLFont;
import com.raytheon.viz.core.gl.IGLTarget;
import com.raytheon.viz.core.gl.TextureLoaderJob;
@ -111,9 +109,7 @@ 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.GLImage;
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;
import com.sun.opengl.util.Screenshot;
import com.sun.opengl.util.j2d.TextRenderer;
import com.sun.opengl.util.texture.Texture;
@ -182,7 +178,7 @@ public class GLTarget implements IGLTarget {
protected final GLCanvas theCanvas;
/** the GLContext */
protected final GLContext theContext;
protected final GLContextBridge theContext;
/** Has a texure load occurred during a draw operation */
protected boolean hasLoadedTextureOnLoop = false;
@ -216,12 +212,13 @@ public class GLTarget implements IGLTarget {
/** The GLU object */
protected final GLU glu = new GLU();
protected static final Map<String, Integer> loadedColorMaps = new LinkedHashMap<String, Integer>() {
protected static final Map<String, GLTextureObject> loadedColorMaps = new LinkedHashMap<String, GLTextureObject>() {
private static final long serialVersionUID = 1L;
@Override
protected boolean removeEldestEntry(Entry<String, Integer> eldest) {
protected boolean removeEldestEntry(
Entry<String, GLTextureObject> eldest) {
if (size() > maxColorMapCacheSize) {
handleRemove(eldest.getValue());
return true;
@ -231,15 +228,15 @@ public class GLTarget implements IGLTarget {
}
@Override
public Integer remove(Object key) {
Integer id = super.remove(key);
public GLTextureObject remove(Object key) {
GLTextureObject id = super.remove(key);
handleRemove(id);
return id;
}
private void handleRemove(Integer value) {
if (value != null) {
currentGl.disposeLuminanceTexture(value, 0);
private void handleRemove(GLTextureObject value) {
if (value != null && value.isValid()) {
value.dispose();
}
}
@ -257,8 +254,6 @@ public class GLTarget implements IGLTarget {
protected final float textMagnification;
protected final GLContext sharedContext;
protected ColorMapParameters lastColormapUsed;
protected double lastAlphaUsed = 1.0f;
@ -311,14 +306,11 @@ public class GLTarget implements IGLTarget {
theCanvas = (GLCanvas) canvas;
theCanvas.setCurrent();
theContext = GLDrawableFactory.getFactory().createExternalGLContext();
theContext = new GLContextBridge(theCanvas);
sharedContext = theContext; // extDrawable.createContext(theContext);
// sharedContext.makeCurrent();
theContext.makeContextCurrent();
makeContextCurrent();
gl = theContext.getGL();
gl = GLU.getCurrentGL();
theWidth = width;
theHeight = width;
@ -359,22 +351,12 @@ public class GLTarget implements IGLTarget {
public GLTarget(float width, float height) throws VizException {
theCanvas = null;
canvasSize = new Rectangle(0, 0, (int) width, (int) height);
GLCapabilities glCap = new GLCapabilities();
if (!GLDrawableFactory.getFactory().canCreateGLPbuffer()) {
throw new VizException(
"Graphics card does not support GLPbuffer and "
+ "therefore does not support offscreen rendering.");
}
GLPbuffer buf = GLDrawableFactory.getFactory().createGLPbuffer(glCap,
null, (int) width, (int) height, null);
theContext = buf.createContext(null);
sharedContext = theContext;
theContext = new GLContextBridge((int) width, (int) height);
makeContextCurrent();
gl = theContext.getGL();
theContext.makeContextCurrent();
gl = GLU.getCurrentGL();
theWidth = width;
theHeight = width;
@ -473,7 +455,6 @@ public class GLTarget implements IGLTarget {
*/
@Override
public void clearClippingPlane() {
this.makeContextCurrent();
gl.glDisable(GL.GL_CLIP_PLANE0);
gl.glDisable(GL.GL_CLIP_PLANE1);
gl.glDisable(GL.GL_CLIP_PLANE2);
@ -501,7 +482,7 @@ public class GLTarget implements IGLTarget {
@Override
public IWireframeShape createWireframeShape(boolean mutableFlag,
GeneralGridGeometry geom) {
return new GLWireframeShape2D(this, geom, mutableFlag);
return new GLWireframeShape2D(geom, mutableFlag);
}
/*
@ -519,7 +500,7 @@ public class GLTarget implements IGLTarget {
return new GLWireframeShape(null, geom, mutable,
simplificationLevel, spatialChopFlag, extent);
} else {
return new GLWireframeShape2D(this, geom, mutable);
return new GLWireframeShape2D(geom, mutable);
}
}
@ -532,7 +513,7 @@ public class GLTarget implements IGLTarget {
@Override
public IWireframeShape createWireframeShape(boolean mutable,
IDescriptor descriptor) {
return new GLWireframeShape2D(this, descriptor, mutable);
return new GLWireframeShape2D(descriptor, mutable);
}
/*
@ -548,7 +529,7 @@ public class GLTarget implements IGLTarget {
return new GLWireframeShape(descriptor, mutable,
simplificationLevel);
} else {
return new GLWireframeShape2D(this, descriptor, mutable);
return new GLWireframeShape2D(descriptor, mutable);
}
}
@ -567,7 +548,7 @@ public class GLTarget implements IGLTarget {
return new GLWireframeShape(descriptor, null, mutable,
simplificationLevel, spatialChopFlag, extent);
} else {
return new GLWireframeShape2D(this, descriptor, mutable);
return new GLWireframeShape2D(descriptor, mutable);
}
}
@ -578,7 +559,7 @@ public class GLTarget implements IGLTarget {
*/
@Override
public void dispose() {
makeContextCurrent();
theContext.makeContextCurrent();
if (defaultFont != null) {
defaultFont.disposeInternal();
}
@ -586,8 +567,8 @@ public class GLTarget implements IGLTarget {
colorbarFont.disposeInternal();
}
theContext.release();
theContext.destroy();
theContext.releaseContext();
theContext.destroyContext();
if (theCanvas != null && theCanvas.isDisposed() == false) {
theCanvas.removeListener(SWT.Resize, this.canvasResizeListener);
}
@ -595,15 +576,6 @@ public class GLTarget implements IGLTarget {
extensionManager.dispose();
}
public void disposeLuminanceTexture(int id, int pboID) {
makeContextCurrent();
gl.glDeleteTextures(1, new int[] { id }, 0);
if (pboID > 0) {
gl.glDeleteBuffers(1, new int[] { pboID }, 0);
}
}
/**
* Dispose a vbo
*
@ -668,7 +640,6 @@ public class GLTarget implements IGLTarget {
}
this.clearClippingPlane();
this.makeContextCurrent();
this.pushGLState();
try {
@ -726,7 +697,6 @@ public class GLTarget implements IGLTarget {
@Override
public void drawColorRamp(DrawableColorMap drawableColorMap)
throws VizException {
this.makeContextCurrent();
this.pushGLState();
try {
final ColorMapParameters colorMapParams = drawableColorMap
@ -743,7 +713,7 @@ public class GLTarget implements IGLTarget {
double y1 = pixelExtent.getMinY();
double y2 = pixelExtent.getMaxY();
Integer i = getColorMapTexture(colorMapParams);
GLTextureObject i = getColorMapTexture(colorMapParams);
GLColormappedImage alphaMaskTexture = null;
if (colorMapParams.isUseMask() && capabilities.cardSupportsShaders) {
@ -767,7 +737,7 @@ public class GLTarget implements IGLTarget {
gl.glEnable(GL.GL_TEXTURE_1D);
gl.glActiveTexture(GL.GL_TEXTURE0);
gl.glBindTexture(GL.GL_TEXTURE_1D, i);
i.bind(gl, GL.GL_TEXTURE_1D);
if (drawableColorMap.interpolate) {
gl.glTexParameteri(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_MIN_FILTER,
@ -1040,7 +1010,6 @@ public class GLTarget implements IGLTarget {
*/
@Override
public void drawLine(DrawableLine... lines) throws VizException {
this.makeContextCurrent();
this.pushGLState();
try {
RGB prevColor = null;
@ -1191,7 +1160,6 @@ public class GLTarget implements IGLTarget {
Set<String> errorMsgs = new HashSet<String>();
List<DrawableImage> notDrawn = new ArrayList<DrawableImage>();
this.makeContextCurrent();
this.pushGLState();
try {
gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
@ -1293,7 +1261,7 @@ public class GLTarget implements IGLTarget {
}
// Get and stage colormap texture
Integer cmapTexture = getColorMapTexture(usedColorMapParameters);
GLTextureObject cmapTexture = getColorMapTexture(usedColorMapParameters);
if (alphaMaskTexture != null) {
gl.glActiveTexture(GL.GL_TEXTURE2);
@ -1303,7 +1271,7 @@ public class GLTarget implements IGLTarget {
}
gl.glActiveTexture(GL.GL_TEXTURE1);
gl.glBindTexture(GL.GL_TEXTURE_1D, cmapTexture);
cmapTexture.bind(gl, GL.GL_TEXTURE_1D);
if (glImage.isInterpolated()) {
gl.glTexParameteri(GL.GL_TEXTURE_1D,
@ -1461,25 +1429,6 @@ public class GLTarget implements IGLTarget {
handleError(gl.glGetError());
IImageCacheable[] pending = ImageCache.getInstance(CacheType.TEXTURE)
.getImagesWaitingToDispose();
if (pending != null) {
for (IImageCacheable glI : pending) {
glI.disposeTexture(getGl());
}
}
// Delete any pending resources
pending = ImageCache.getInstance(CacheType.MEMORY)
.getImagesWaitingToDispose();
if (pending != null) {
for (IImageCacheable glI : pending) {
glI.disposeTextureData();
}
}
if (errorMsgs.size() > 0) {
throw new VizException("Error rendering " + errorMsgs.size()
+ " images: " + errorMsgs);
@ -1572,7 +1521,6 @@ public class GLTarget implements IGLTarget {
@Override
public void drawRect(IExtent extent, RGB color, float lineWidth,
double alpha) {
this.makeContextCurrent();
this.pushGLState();
try {
gl.glPolygonMode(GL.GL_BACK, GL.GL_LINE);
@ -1605,7 +1553,6 @@ public class GLTarget implements IGLTarget {
@Override
public void drawShadedRect(IExtent pe, RGB color, double alpha,
byte[] stipple) throws VizException {
this.makeContextCurrent();
this.pushGLState();
try {
@ -1644,7 +1591,6 @@ public class GLTarget implements IGLTarget {
*/
public void drawRect(PixelCoverage coverage, RGB color, float lineWidth,
double alpha) {
this.makeContextCurrent();
this.pushGLState();
try {
gl.glPolygonMode(GL.GL_FRONT, GL.GL_LINE);
@ -1718,7 +1664,6 @@ public class GLTarget implements IGLTarget {
brightness = Math.max(brightness, 0.0f);
brightness = Math.min(brightness, 1.0f);
this.makeContextCurrent();
pushGLState();
try {
gl.glPolygonMode(GL.GL_BACK, GL.GL_FILL);
@ -1916,11 +1861,10 @@ public class GLTarget implements IGLTarget {
float lineWidth, IGraphicsTarget.LineStyle lineStyle, IFont font,
float alpha) throws VizException {
if (shape instanceof GLWireframeShape2D) {
makeContextCurrent();
pushGLState();
try {
((GLWireframeShape2D) shape).paint(viewExtent, canvasSize,
aColor, lineWidth, lineStyle, font, alpha);
((GLWireframeShape2D) shape).paint(this, viewExtent,
canvasSize, aColor, lineWidth, lineStyle, font, alpha);
} finally {
popGLState();
}
@ -1934,7 +1878,6 @@ public class GLTarget implements IGLTarget {
float lineWidth, LineStyle lineStyle, IGLFont font, float alpha)
throws VizException {
this.makeContextCurrent();
this.pushGLState();
try {
@ -2085,7 +2028,7 @@ public class GLTarget implements IGLTarget {
*/
@Override
public void endFrame() {
makeContextCurrent();
try {
if (this.lastColormapUsed != null && this.useBuiltinColorbar) {
this.drawColorbar(this.lastColormapUsed);
@ -2098,27 +2041,6 @@ public class GLTarget implements IGLTarget {
return;
}
makeContextCurrent();
// Delete any pending resources
IImageCacheable[] pending = ImageCache.getInstance(CacheType.MEMORY)
.getImagesWaitingToDispose();
if (pending != null) {
for (IImageCacheable glI : pending) {
glI.disposeTextureData();
}
}
pending = ImageCache.getInstance(CacheType.TEXTURE)
.getImagesWaitingToDispose();
if (pending != null) {
for (IImageCacheable glI : pending) {
glI.disposeTexture(getGl());
}
}
gl.glFinish();
if (theCanvas != null) {
@ -2129,13 +2051,12 @@ public class GLTarget implements IGLTarget {
// redrawRetries++;
// }
}
if (GLContext.getCurrent() == theContext) {
theContext.release();
}
}
GLContextBridge.makeMasterContextCurrent();
public GLContext getContext() {
return this.theContext;
GLDisposalManager.performDispose(GLU.getCurrentGL());
GLContextBridge.releaseMasterContext();
releaseContext();
}
/*
@ -2184,10 +2105,6 @@ public class GLTarget implements IGLTarget {
}
public GLContext getSharedContext() {
return this.sharedContext;
}
/*
* (non-Javadoc)
*
@ -2328,16 +2245,16 @@ public class GLTarget implements IGLTarget {
gl.glLoadIdentity();
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
this.colorbarFont = new UnmodifiableGLFont(new GLFont(this,
DEFAULT_FONT, (10 * textMagnification), null));
this.colorbarFont = new UnmodifiableGLFont(new GLFont(DEFAULT_FONT,
(10 * textMagnification), null));
if (PlatformUI.isWorkbenchRunning()) {
fontFactory = FontFactory.getInstance();
this.defaultFont = new UnmodifiableGLFont(fontFactory.getFont(
FontFactory.DEFAULT_FONT_ID, this));
this.defaultFont = new UnmodifiableGLFont(
fontFactory.getFont(FontFactory.DEFAULT_FONT_ID));
} else {
this.defaultFont = new UnmodifiableGLFont(
new GLFont(this, java.awt.Font.MONOSPACED, 14.0f,
new GLFont(java.awt.Font.MONOSPACED, 14.0f,
new Style[] { Style.BOLD }));
}
releaseContext();
@ -2418,7 +2335,7 @@ public class GLTarget implements IGLTarget {
*/
@Override
public IFont initializeFont(File fontFile, float size, Style[] styles) {
return new GLFont(this, fontFile, size, styles);
return new GLFont(fontFile, size, styles);
}
/*
@ -2430,7 +2347,7 @@ public class GLTarget implements IGLTarget {
*/
@Override
public IFont initializeFont(String fontName, float size, Style[] styles) {
return new GLFont(this, fontName, size, styles);
return new GLFont(fontName, size, styles);
}
/*
@ -2442,7 +2359,7 @@ public class GLTarget implements IGLTarget {
@Override
public IFont initializeFont(String font) {
if (fontFactory != null && fontFactory.hasId(font)) {
return fontFactory.getFont(font, this);
return fontFactory.getFont(font);
}
return defaultFont.deriveWithSize(defaultFont.getFontSize());
}
@ -2457,16 +2374,16 @@ public class GLTarget implements IGLTarget {
return needsRefresh;
}
protected int loadColormapIntoTexture(ColorMap glColorMap) {
protected GLTextureObject loadColormapIntoTexture(ColorMap glColorMap) {
Buffer bb = glColorMap.getColorMap();
int[] t = new int[2];
gl.glGenTextures(1, t, 0);
GLContextBridge.makeMasterContextCurrent();
GLTextureObject t = new GLTextureObject();
GLContextBridge.releaseMasterContext();
if (gl.isFunctionAvailable("glActiveTexture")) {
gl.glActiveTexture(GL.GL_TEXTURE1);
}
gl.glEnable(GL.GL_TEXTURE_1D);
gl.glBindTexture(GL.GL_TEXTURE_1D, t[0]);
t.bind(gl, GL.GL_TEXTURE_1D);
bb.rewind();
gl.glTexParameteri(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_WRAP_S,
GL.GL_CLAMP_TO_EDGE);
@ -2487,7 +2404,7 @@ public class GLTarget implements IGLTarget {
0, GL.GL_RGBA, GL.GL_FLOAT, bb);
gl.glDisable(GL.GL_TEXTURE_1D);
return t[0];
return t;
}
/*
@ -2496,22 +2413,7 @@ public class GLTarget implements IGLTarget {
* @see com.raytheon.viz.core.gl.IGLTarget#makeContextCurrent()
*/
public boolean makeContextCurrent() {
boolean releaseContext = false;
if (theContext != (GLContext.getCurrent())) {
GLContext oldContext = GLContext.getCurrent();
if (oldContext != null) {
oldContext.release();
}
if (theCanvas != null && !theCanvas.isDisposed()) {
theCanvas.setCurrent();
}
theContext.makeCurrent();
currentGl = this;
releaseContext = true;
}
return releaseContext;
return theContext.makeContextCurrent();
}
/**
@ -2521,7 +2423,7 @@ public class GLTarget implements IGLTarget {
*
*/
public void releaseContext() {
theContext.release();
theContext.releaseContext();
}
/*
@ -2537,7 +2439,7 @@ public class GLTarget implements IGLTarget {
Rectangle bounds = theCanvas.getClientArea();
boolean needsDispose = makeContextCurrent();
makeContextCurrent();
gl.glViewport(0, 0, bounds.width, bounds.height);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glLoadIdentity();
@ -2545,9 +2447,7 @@ public class GLTarget implements IGLTarget {
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glLoadIdentity();
if (needsDispose) {
releaseContext();
}
}
@ -2559,7 +2459,7 @@ public class GLTarget implements IGLTarget {
@Override
public BufferedImage screenshot() {
boolean grabbedContext = makeContextCurrent();
makeContextCurrent();
if (theCanvas != null) {
theCanvas.swapBuffers();
}
@ -2570,9 +2470,7 @@ public class GLTarget implements IGLTarget {
theCanvas.swapBuffers();
}
if (grabbedContext) {
releaseContext();
}
return bi;
}
@ -2621,7 +2519,6 @@ public class GLTarget implements IGLTarget {
if (extent == null) {
return;
}
this.makeContextCurrent();
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glPushMatrix();
@ -2917,7 +2814,6 @@ public class GLTarget implements IGLTarget {
@Override
public void drawShadedPolygon(LinearRing poly, RGB color, double alpha,
byte[] stipple) throws VizException {
this.makeContextCurrent();
this.pushGLState();
try {
// set the shading and alpha
@ -2966,7 +2862,7 @@ public class GLTarget implements IGLTarget {
this.updatedExtent = updatedExtent;
}
private Integer getColorMapTexture(ColorMapParameters cmapParams) {
private GLTextureObject getColorMapTexture(ColorMapParameters cmapParams) {
IColorMap cmap = cmapParams.getColorMap();
String name = cmap.getName();
if (name == null) {
@ -2974,7 +2870,7 @@ public class GLTarget implements IGLTarget {
+ cmapParams.hashCode();
}
Integer i = loadedColorMaps.get(name);
GLTextureObject i = loadedColorMaps.get(name);
if (i == null || cmap.isChanged()) {
if (i != null) {
loadedColorMaps.remove(name);
@ -3220,7 +3116,6 @@ public class GLTarget implements IGLTarget {
// function ends up calling begin/end rendering lots which slows it down
// to the speed of a not bulk operation
TextRenderer textRenderer = null;
makeContextCurrent();
pushGLState();
gl.glMatrixMode(GL.GL_MODELVIEW);
@ -3558,7 +3453,6 @@ public class GLTarget implements IGLTarget {
return;
}
this.makeContextCurrent();
this.pushGLState();
try {
int pointsPerLocation = 1;

View file

@ -73,26 +73,20 @@ public class GLWireframeShape2D implements IWireframeShape {
private boolean compiled = false;
private IGLTarget target;
private GLGeometryObject2D geometry;
private GLGeometryObjectData geomData;
public GLWireframeShape2D(IGLTarget target,
GeneralGridGeometry gridGeometry, boolean mutable) {
this.target = target;
public GLWireframeShape2D(GeneralGridGeometry gridGeometry, boolean mutable) {
geomData = new GLGeometryObjectData(GL.GL_LINE_STRIP,
GL.GL_VERTEX_ARRAY);
geomData.setTarget(target);
geomData.mutable = mutable;
geomData.worldExtent = new PixelExtent(gridGeometry.getGridRange());
initialize();
}
public GLWireframeShape2D(IGLTarget target, IDescriptor descriptor,
boolean mutable) {
this(target, descriptor.getGridGeometry(), mutable);
public GLWireframeShape2D(IDescriptor descriptor, boolean mutable) {
this(descriptor.getGridGeometry(), mutable);
this.descriptor = descriptor;
}
@ -230,16 +224,16 @@ public class GLWireframeShape2D implements IWireframeShape {
geometry.allocate(points);
}
public synchronized void paint(IExtent viewExtent, Rectangle canvasSize,
RGB color, float lineWidth, LineStyle lineStyle, IFont font,
float alpha) throws VizException {
public synchronized void paint(IGLTarget target, IExtent viewExtent,
Rectangle canvasSize, RGB color, float lineWidth,
LineStyle lineStyle, IFont font, float alpha) throws VizException {
if (isDrawable() == false) {
return;
}
if (!geomData.mutable && !compiled) {
compiled = true;
geometry.compile();
geometry.compile(target.getGl());
}
GL gl = target.getGl();
@ -321,7 +315,7 @@ public class GLWireframeShape2D implements IWireframeShape {
gl.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_KEEP);
}
geometry.paint();
geometry.paint(target.getGl());
gl.glDisable(GL.GL_BLEND);

View file

@ -135,22 +135,10 @@ public class PreferenceBasedGLFont implements IGLFont, IPropertyChangeListener {
public void propertyChange(PropertyChangeEvent event) {
if (propertyName.equals(event.getProperty())) {
preferenceFont.disposeInternal();
preferenceFont = FontFactory.getInstance().getFont(propertyName,
preferenceFont.getTarget());
preferenceFont.getTarget().setNeedsRefresh(true);
preferenceFont = FontFactory.getInstance().getFont(propertyName);
}
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.core.gl.IGLFont#getTarget()
*/
@Override
public GLTarget getTarget() {
return preferenceFont.getTarget();
}
/*
* (non-Javadoc)
*

View file

@ -25,6 +25,9 @@ import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.media.opengl.GL;
import com.raytheon.viz.core.gl.GLDisposalManager.GLDisposer;
import com.sun.opengl.util.j2d.TextRenderer;
/**
@ -60,7 +63,14 @@ public class TextRendererCache {
@Override
protected boolean removeEldestEntry(Entry<Font, TextRenderer> eldest) {
if (size() > UNUSED_RENDERER_SIZE) {
eldest.getValue().dispose();
final TextRenderer renderer = eldest.getValue();
new GLDisposer() {
@Override
protected void dispose(GL gl) {
renderer.dispose();
}
}.dispose();
return true;
}
return false;

View file

@ -23,8 +23,6 @@ import com.raytheon.uf.common.status.IUFStatusHandler;
import com.raytheon.uf.common.status.UFStatus;
import com.raytheon.uf.common.status.UFStatus.Priority;
import com.raytheon.uf.viz.core.drawables.IFont;
import com.raytheon.uf.viz.core.status.StatusConstants;
import com.raytheon.viz.core.gl.Activator;
import com.raytheon.viz.core.gl.IGLFont;
import com.sun.opengl.util.j2d.TextRenderer;
@ -47,7 +45,8 @@ import com.sun.opengl.util.j2d.TextRenderer;
*/
public class UnmodifiableGLFont implements IGLFont {
private static final transient IUFStatusHandler statusHandler = UFStatus.getHandler(UnmodifiableGLFont.class);
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(UnmodifiableGLFont.class);
private IGLFont unmodifiableFont;
@ -146,14 +145,4 @@ public class UnmodifiableGLFont implements IGLFont {
return unmodifiableFont.toString();
}
/*
* (non-Javadoc)
*
* @see com.raytheon.viz.core.gl.IGLFont#getTarget()
*/
@Override
public GLTarget getTarget() {
return unmodifiableFont.getTarget();
}
}

View file

@ -20,12 +20,12 @@
package com.raytheon.viz.core.gl.internal.cache;
import java.util.ArrayList;
import java.util.List;
import javax.media.opengl.GL;
import com.raytheon.uf.common.util.cache.LRUCache;
import com.raytheon.uf.viz.core.Activator;
import com.raytheon.uf.viz.core.preferences.PreferenceConstants;
import com.raytheon.viz.core.gl.GLDisposalManager.GLDisposer;
/**
* Cache for GLImages, one for memory and one fore texture
@ -77,8 +77,6 @@ public class ImageCache extends LRUCache<Object, IImageCacheable> implements
/** The instance of the memory cache */
private static ImageCache memoryCache;
private List<IImageCacheable> waitingToDispose;
/**
* Get Singletons
*
@ -116,7 +114,6 @@ public class ImageCache extends LRUCache<Object, IImageCacheable> implements
*/
private ImageCache(long maxSz) {
super(maxSz);
this.waitingToDispose = new ArrayList<IImageCacheable>();
}
public void put(IImageCacheable image) {
@ -126,13 +123,16 @@ public class ImageCache extends LRUCache<Object, IImageCacheable> implements
@Override
protected void removeItem(Item item) {
super.removeItem(item);
waitingToDispose.add(item.value);
final IImageCacheable i = item.value;
if (this == memoryCache) {
i.disposeTextureData();
} else if (this == textureCache) {
new GLDisposer() {
@Override
protected void dispose(GL gl) {
i.disposeTexture(gl);
}
}.dispose();
}
public IImageCacheable[] getImagesWaitingToDispose() {
IImageCacheable[] arr = this.waitingToDispose
.toArray(new IImageCacheable[waitingToDispose.size()]);
this.waitingToDispose.clear();
return arr;
}
}

View file

@ -97,7 +97,6 @@ public class GLColormapShadedShapeExtension extends
throws VizException {
if (shape instanceof GLColormapShadedShape) {
GLColormapShadedShape glBaseShape = (GLColormapShadedShape) shape;
target.makeContextCurrent();
GL gl = target.getGl();
gl.glPolygonMode(GL.GL_BACK, GL.GL_FILL);
gl.glEnableClientState(GL.GL_VERTEX_ARRAY);

View file

@ -17,7 +17,6 @@ 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.IGLColorMapDataFormatProvider;
import com.raytheon.viz.core.gl.images.AbstractGLImage;
@ -34,7 +33,6 @@ public class GLOffscreenRenderingExtension extends GraphicsExtension<IGLTarget>
throw new VizException(
"Can only use GLImages as offscreen frameBuffer on GLTarget");
}
target.makeContextCurrent();
AbstractGLImage glImage = (AbstractGLImage) offscreenImage;
if (glImage.getStatus() == IImage.Status.UNLOADED
|| glImage.getStatus() == IImage.Status.LOADING) {
@ -52,7 +50,6 @@ public class GLOffscreenRenderingExtension extends GraphicsExtension<IGLTarget>
@Override
public void renderOnscreen() throws VizException {
target.makeContextCurrent();
Rectangle canvasSize = target.getBounds();
target.getGl().glViewport(0, 0, canvasSize.width, canvasSize.height);
target.getGl().glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);
@ -132,7 +129,8 @@ public class GLOffscreenRenderingExtension extends GraphicsExtension<IGLTarget>
// assume we don't support luminance
supportsLuminance = false;
// Reconstruct image
image = constructOffscreenImage(dataType, dimensions, parameters);
image = constructOffscreenImage(dataType, dimensions,
parameters);
}
}
return image;

View file

@ -0,0 +1,120 @@
/**
* 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.objects;
import javax.media.opengl.GL;
/**
*
* A simple wrapper around a GL frameBuffer id that manages creation and
* disposal of frameBuffer ids.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 17, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class GLFrameBufferObject extends GLIdWrapper {
/**
* Create a new frameBuffer id in gl and register this frameBuffer to be
* disposed when parent is garbage collected.
*
* @param parent
* - the object that will be using the texture.
* @param gl
*/
public GLFrameBufferObject(Object parent) {
super(parent);
}
/**
* Create a new frameBuffer id in gl
*
* @param gl
*/
public GLFrameBufferObject() {
super();
}
@Override
protected void genId(GL gl, int[] arr) {
gl.glGenFramebuffersEXT(1, arr, 0);
}
@Override
protected void deleteId(GL gl, int[] arr) {
gl.glDeleteFramebuffersEXT(1, arr, 0);
}
public void bind(GL gl) {
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, id);
}
public String checkStatus(GL gl) {
String errorMessage = null;
switch (gl.glCheckFramebufferStatusEXT(GL.GL_FRAMEBUFFER_EXT)) {
case GL.GL_FRAMEBUFFER_COMPLETE_EXT: {
// Everything is ok.
break;
}
case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: {
errorMessage = "Error: Framebuffer incomplete, fbo attachement is NOT complete";
break;
}
case GL.GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: {
errorMessage = "Error: Framebuffer incomplete, no image is attached to FBO";
break;
}
case GL.GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: {
errorMessage = "Error: Framebuffer incomplete, attached images have different dimensions";
break;
}
case GL.GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: {
errorMessage = "Error: Framebuffer incomplete, color attached images have different internal formats";
break;
}
case GL.GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: {
errorMessage = "Error: Framebuffer incomplete, draw buffer";
break;
}
case GL.GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: {
errorMessage = "Error: Framebuffer incomplete, read buffer";
break;
}
case GL.GL_FRAMEBUFFER_UNSUPPORTED_EXT: {
errorMessage = "Error: Framebuffer not supported by hardware/drivers";
break;
}
}
return errorMessage;
}
}

View file

@ -0,0 +1,96 @@
/**
* 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.objects;
import javax.media.opengl.GL;
import javax.media.opengl.glu.GLU;
import com.raytheon.viz.core.gl.GLDisposalManager;
import com.raytheon.viz.core.gl.GLDisposalManager.GLDisposer;
/**
*
* Most objects in GL are represented in Java as an integer id. This class
* provides some of the generic code needed to manage these and dispose of these
* GL Objects
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 17, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public abstract class GLIdWrapper extends GLDisposer {
protected int id;
public GLIdWrapper(Object parent) {
this();
GLDisposalManager.autoDispose(this, parent);
}
public GLIdWrapper() {
int[] arr = new int[1];
genId(GLU.getCurrentGL(), arr);
this.id = arr[0];
}
public boolean isValid() {
return id != -1;
}
public int getId() {
return id;
}
@Override
protected void dispose(GL gl) {
if (id != -1) {
deleteId(gl, new int[] { id });
}
this.id = -1;
}
/**
* Generate an id for this object, arr is an array of length 1 and id should
* be set to the only element in the array
*
* @param gl
* @param arr
*/
protected abstract void genId(GL gl, int[] arr);
/**
* Delete an id for this object, arr is an array of length 1 and will
* contain the id
*
* @param gl
* @param arr
*/
protected abstract void deleteId(GL gl, int[] arr);
}

View file

@ -0,0 +1,84 @@
/**
* 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.objects;
import javax.media.opengl.GL;
/**
*
* A simple wrapper around a GL renderBuffer id that manages creation and
* disposal of renderBuffer ids.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 17, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class GLRenderBuffer extends GLIdWrapper {
/**
* Create a new renderBuffer id in gl and register this renderBuffer to be
* disposed when parent is garbage collected.
*
* @param parent
* - the object that will be using the texture.
* @param gl
*/
public GLRenderBuffer(Object parent) {
super(parent);
}
/**
* Create a new renderBuffer id in gl
*
* @param gl
*/
public GLRenderBuffer() {
super();
}
@Override
protected void genId(GL gl, int[] arr) {
gl.glGenRenderbuffersEXT(1, arr, 0);
}
@Override
protected void deleteId(GL gl, int[] arr) {
gl.glDeleteRenderbuffersEXT(1, arr, 0);
}
public void bind(GL gl) {
gl.glBindRenderbufferEXT(GL.GL_RENDERBUFFER_EXT, id);
}
public void createStorage(GL gl, int internalFormat, int width, int height) {
gl.glRenderbufferStorageEXT(GL.GL_RENDERBUFFER_EXT, internalFormat,
width, height);
}
}

View file

@ -0,0 +1,88 @@
/**
* 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.objects;
import javax.media.opengl.GL;
/**
*
* A simple wrapper around a GLTextureId that manages creation and disposal of
* texture ids.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 17, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class GLTextureObject extends GLIdWrapper {
/**
* Create a new texture id in gl and register this texture to be disposed
* when parent is garbage collected.
*
* @param parent
* - the object that will be using the texture.
* @param gl
*/
public GLTextureObject(Object parent) {
super(parent);
}
/**
* Create a new texture id in gl
*
* @param gl
*/
public GLTextureObject() {
super();
}
@Override
protected void genId(GL gl, int[] arr) {
gl.glGenTextures(1, arr, 0);
}
@Override
protected void deleteId(GL gl, int[] arr) {
gl.glDeleteTextures(1, arr, 0);
}
/**
*
* @param gl
* @param target
* Specifies the target to which the texture is bound. Must be
* either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, or
* GL_TEXTURE_CUBE_MAP.
*/
public void bind(GL gl, int target) {
gl.glBindTexture(target, id);
}
}

View file

@ -0,0 +1,88 @@
/**
* 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.objects;
import javax.media.opengl.GL;
/**
*
* A wrapper around a vbo id from gl. This object contains the logic to create
* and dispose vbo ids.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Feb 17, 2012 bsteffen Initial creation
*
* </pre>
*
* @author bsteffen
* @version 1.0
*/
public class GLVertexBufferObject extends GLIdWrapper {
/**
* Create a new vboId in gl and register this vbo to be disposed when parent
* is garbage collected.
*
* @param parent
* - the object that will be using the vbo.
* @param gl
*/
public GLVertexBufferObject(Object parent) {
super();
}
/**
* Create a new vboId in gl
*
* @param gl
*/
public GLVertexBufferObject() {
super();
}
@Override
protected void genId(GL gl, int[] arr) {
gl.glGenBuffers(1, arr, 0);
}
@Override
protected void deleteId(GL gl, int[] arr) {
gl.glDeleteBuffers(1, arr, 0);
}
/**
*
* @param gl
* @param target
* Specifies the target to which the buffer object is bound. The
* symbolic constant must be GL_ARRAY_BUFFER,
* GL_ELEMENT_ARRAY_BUFFER, GL_PIXEL_PACK_BUFFER, or
* GL_PIXEL_UNPACK_BUFFER
*/
public void bind(GL gl, int target) {
gl.glBindBuffer(target, id);
}
}