/*******************************************************************************
* Copyright 2014 Geoscience Australia
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package au.gov.ga.earthsci.worldwind.common.layers.atmosphere;
import gov.nasa.worldwind.geom.LatLon;
import gov.nasa.worldwind.geom.Sector;
import gov.nasa.worldwind.render.DrawContext;
import gov.nasa.worldwind.render.SurfaceImage;
import gov.nasa.worldwind.util.Logging;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
/**
* {@link SurfaceImage} that allows customisation of the blending function used
* (via values passed to glBlendFunc).
*
* @author Michael de Hoog (michael.dehoog@ga.gov.au)
*/
public class BlendSurfaceImage extends SurfaceImage
{
private int srcBlend = GL2.GL_ONE;
private int dstBlend = GL2.GL_ONE_MINUS_SRC_ALPHA;
public BlendSurfaceImage()
{
super();
}
public BlendSurfaceImage(Object imageSource, Iterable<? extends LatLon> corners)
{
super(imageSource, corners);
}
public BlendSurfaceImage(Object imageSource, Sector sector)
{
super(imageSource, sector);
}
public void resetBlendFunc()
{
srcBlend = GL2.GL_ONE;
dstBlend = GL2.GL_ONE_MINUS_SRC_ALPHA;
}
public void setBlendFunc(int srcBlend, int dstBlend)
{
this.srcBlend = srcBlend;
this.dstBlend = dstBlend;
}
@Override
public void render(DrawContext dc)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull"); //$NON-NLS-1$
Logging.logger().severe(message);
throw new IllegalStateException(message);
}
if (dc.isPickingMode() && !this.isPickEnabled())
{
return;
}
if (this.getSector() == null || !this.getSector().intersects(dc.getVisibleSector()))
{
return;
}
if (this.sourceTexture == null)
{
return;
}
GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.
try
{
if (!dc.isPickingMode())
{
double opacity = dc.getCurrentLayer() != null
? this.getOpacity() * dc.getCurrentLayer().getOpacity() : this.getOpacity();
if (opacity < 1)
{
gl.glPushAttrib(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_POLYGON_BIT | GL2.GL_CURRENT_BIT);
// Enable blending using white premultiplied by the current opacity.
gl.glColor4d(opacity, opacity, opacity, opacity);
}
else
{
gl.glPushAttrib(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_POLYGON_BIT);
}
gl.glEnable(GL.GL_BLEND);
gl.glBlendFunc(srcBlend, dstBlend);
}
else
{
gl.glPushAttrib(GL2.GL_POLYGON_BIT);
}
gl.glPolygonMode(GL2.GL_FRONT, GL2.GL_FILL);
gl.glEnable(GL.GL_CULL_FACE);
gl.glCullFace(GL.GL_BACK);
dc.getGeographicSurfaceTileRenderer().renderTiles(dc, this.thisList);
}
finally
{
gl.glPopAttrib();
}
}
}