diff --git a/WorldWindAndroid/library.iml b/WorldWindAndroid/library.iml
index 03de696..507ce46 100644
--- a/WorldWindAndroid/library.iml
+++ b/WorldWindAndroid/library.iml
@@ -27,6 +27,7 @@
+
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/SceneController.java b/WorldWindAndroid/src/gov/nasa/worldwind/SceneController.java
index a5ba5aa..4b2c585 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/SceneController.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/SceneController.java
@@ -52,7 +52,6 @@ public class SceneController extends WWObjectImpl {
protected Set perFrameStatisticsKeys = new HashSet();
protected final Map perFrameStatistics = Collections.synchronizedMap(new ConcurrentHashMap());
- protected GLRuntimeCapabilities glRuntimeCaps = new GLRuntimeCapabilities();
/** Support class used to build the composite representation of surface objects as a list of SurfaceTiles. */
protected SurfaceObjectTileBuilder surfaceObjectTileBuilder;
@@ -270,7 +269,6 @@ public void drawFrame(double deltaTime, int viewportWidth, int viewportHeight) {
// perFrameStatistics.clear();
this.surfaceObjectTiles.clear(); // Clear the surface object tiles generated during the last frame.
- this.glRuntimeCaps.initialize();
// Prepare the drawing context for a new frame then cause this scene controller to draw its content. There is no
// need to explicitly swap the front and back buffers here, as the owner WorldWindow does this for us. In the
// case of WorldWindowGLSurfaceView, the GLSurfaceView automatically swaps the front and back buffers for us.
@@ -325,7 +323,6 @@ protected void doDrawFrame(DrawContext dc) {
protected void initializeDrawContext(DrawContext dc, int viewportWidth, int viewportHeight) {
dc.initialize(viewportWidth, viewportHeight);
dc.setFrameTimeStamp(SystemClock.elapsedRealtime());
- dc.setGLRuntimeCapabilities(glRuntimeCaps);
dc.setModel(this.model);
dc.setView(this.view);
dc.setVerticalExaggeration(this.verticalExaggeration);
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/geom/Matrix.java b/WorldWindAndroid/src/gov/nasa/worldwind/geom/Matrix.java
index 80d4fdc..0c3448d 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/geom/Matrix.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/geom/Matrix.java
@@ -5,8 +5,7 @@
*/
package gov.nasa.worldwind.geom;
-import gov.nasa.worldwind.avlist.AVList;
-import gov.nasa.worldwind.avlist.AVListImpl;
+import android.graphics.PointF;
import gov.nasa.worldwind.terrain.Terrain;
import gov.nasa.worldwind.util.Logging;
@@ -572,7 +571,7 @@ public static Matrix fromImageToGeographic(int imageWidth, int imageHeight, Sect
* @throws IllegalArgumentException if either imagePoints
or geoPoints
is null or have
* length less than 3.
*/
- public static Matrix fromImageToGeographic(java.awt.geom.Point2D[] imagePoints, LatLon[] geoPoints)
+ public static Matrix fromImageToGeographic(PointF[] imagePoints, LatLon[] geoPoints)
{
if (imagePoints == null)
{
@@ -635,12 +634,12 @@ public static Matrix fromImageToGeographic(java.awt.geom.Point2D[] imagePoints,
double lon2 = geoPoints[1].getLongitude().degrees;
double lon3 = geoPoints[2].getLongitude().degrees;
- double x1 = imagePoints[0].getX();
- double x2 = imagePoints[1].getX();
- double x3 = imagePoints[2].getX();
- double y1 = imagePoints[0].getY();
- double y2 = imagePoints[1].getY();
- double y3 = imagePoints[2].getY();
+ double x1 = imagePoints[0].x;
+ double x2 = imagePoints[1].x;
+ double x3 = imagePoints[2].x;
+ double y1 = imagePoints[0].y;
+ double y2 = imagePoints[1].y;
+ double y3 = imagePoints[2].y;
double a0 = (x3 - x1) - (x2 - x1) * (y3 - y1) / (y2 - y1);
double a = (1 / a0) * ((lon3 - lon1) - (lon2 - lon1) * (y3 - y1) / (y2 - y1));
@@ -659,7 +658,7 @@ public static Matrix fromImageToGeographic(java.awt.geom.Point2D[] imagePoints,
0.0, 0.0, 0.0, 0.0);
}
- public static Matrix fromGeographicToImage(java.awt.geom.Point2D[] imagePoints, LatLon[] geoPoints)
+ public static Matrix fromGeographicToImage(PointF[] imagePoints, LatLon[] geoPoints)
{
if (imagePoints == null)
{
@@ -722,12 +721,12 @@ public static Matrix fromGeographicToImage(java.awt.geom.Point2D[] imagePoints,
double lon2 = geoPoints[1].getLongitude().degrees;
double lon3 = geoPoints[2].getLongitude().degrees;
- double x1 = imagePoints[0].getX();
- double x2 = imagePoints[1].getX();
- double x3 = imagePoints[2].getX();
- double y1 = imagePoints[0].getY();
- double y2 = imagePoints[1].getY();
- double y3 = imagePoints[2].getY();
+ double x1 = imagePoints[0].x;
+ double x2 = imagePoints[1].x;
+ double x3 = imagePoints[2].x;
+ double y1 = imagePoints[0].y;
+ double y2 = imagePoints[1].y;
+ double y3 = imagePoints[2].y;
double a0 = (lon3 - lon1) - (lon2 - lon1) * (lat3 - lat1) / (lat2 - lat1);
double a = (1 / a0) * ((x3 - x1) - (x2 - x1) * (lat3 - lat1) / (lat2 - lat1));
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/geom/PickPointFrustum.java b/WorldWindAndroid/src/gov/nasa/worldwind/geom/PickPointFrustum.java
index 5c435f5..18f38e8 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/geom/PickPointFrustum.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/geom/PickPointFrustum.java
@@ -44,7 +44,7 @@ public PickPointFrustum(Frustum frustum, android.graphics.Rect rect)
// ============== Intersection Functions ======================= //
/**
- * Returns true if the specified 2D screen {@link java.awt.Rectangle} intersects the space enclosed by this view
+ * Returns true if the specified 2D screen {@link android.graphics.Rect} intersects the space enclosed by this view
* aligned frustums screen rectangle.
*
* @param rect the rectangle to test
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/geom/Sector.java b/WorldWindAndroid/src/gov/nasa/worldwind/geom/Sector.java
index e338a8b..34547d6 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/geom/Sector.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/geom/Sector.java
@@ -776,6 +776,9 @@ public double distanceTo(DrawContext dc, Vec4 point)
throw new IllegalArgumentException(message);
}
Vec4[] corners = new Vec4[4];
+ for(int i=0; i 0)
+ if (this.getActiveAttributes(). isEnableInterior() && this.getActiveAttributes().getInteriorOpacity() > 0)
this.drawInterior(dc, sdc);
- if (this.getActiveAttributes().isEnableOutline() && this.getActiveAttributes().getOutlineColor().a > 0)
+ if (this.getActiveAttributes().isEnableOutline() && this.getActiveAttributes().getOutlineOpacity() > 0)
this.drawOutline(dc, sdc);
}
@@ -670,7 +665,7 @@ protected void applyModelviewTransform(DrawContext dc, SurfaceTileDrawContext sd
}
Matrix mvp = Matrix.fromIdentity();
mvp.multiplyAndSet(sdc.getProjectionMatrix(), modelview);
- dc.getCurrentProgram().loadUniformMatrix("mvp", mvp);
+ dc.getCurrentProgram().loadUniformMatrix("mvpMatrix", mvp);
}
/** Determines which attributes -- normal, highlight or default -- to use each frame. */
@@ -1071,8 +1066,8 @@ protected Object createGeometryKey(DrawContext dc, SurfaceTileDrawContext sdc)
protected double computeEdgeIntervalsPerDegree(SurfaceTileDrawContext sdc)
{
double texelsPerDegree = Math.max(
- sdc.getViewport().width / sdc.getSector().getDeltaLonDegrees(),
- sdc.getViewport().getHeight() / sdc.getSector().getDeltaLatDegrees());
+ sdc.getViewport().width() / sdc.getSector().getDeltaLonDegrees(),
+ sdc.getViewport().height() / sdc.getSector().getDeltaLatDegrees());
double intervalsPerTexel = 1.0 / this.getTexelsPerEdgeInterval();
return intervalsPerTexel * texelsPerDegree;
@@ -1155,7 +1150,7 @@ protected void applyInteriorTextureState(DrawContext dc, SurfaceTileDrawContext
transform = Matrix.fromScale(cosLat / scale, 1d / scale, 1d).multiply(transform);
// To maintain the pattern apparent size, we scale it so that one texture pixel match one draw tile pixel.
double regionPixelSize = dc.getGlobe().getRadius() * sdc.getSector().getDeltaLatRadians()
- / sdc.getViewport().height;
+ / sdc.getViewport().height();
double texturePixelSize = dc.getGlobe().getRadius() * Angle.fromDegrees(1).radians / texture.getHeight();
double drawScale = texturePixelSize / regionPixelSize;
transform = Matrix.fromScale(drawScale, drawScale, 1d).multiply(transform); // Pre multiply
@@ -1272,8 +1267,7 @@ protected Integer tessellateInterior(DrawContext dc)
try
{
- return null;
-// return this.doTessellateInterior(dc);
+ return this.doTessellateInterior(dc);
}
catch (OutOfMemoryError e)
{
@@ -1283,12 +1277,51 @@ protected Integer tessellateInterior(DrawContext dc)
//noinspection ThrowableInstanceNeverThrown
// throw new WWRuntimeException(message, e);
this.handleUnsuccessfulInteriorTessellation(dc);
-
-
return null;
}
}
+ protected Integer doTessellateInterior(DrawContext dc) {
+ int numBytes = 0;
+
+ Position referencePos = this.getReferencePosition();
+ if (referencePos == null)
+ return null;
+
+ for (List drawLocations : this.getActiveGeometry())
+ {
+ if (vertexBuffer == null || vertexBuffer.capacity() < 2 * drawLocations.size())
+ vertexBuffer = BufferUtil.newFloatBuffer(2 * (drawLocations.size()+2));
+ vertexBuffer.clear();
+
+ LatLon firstPoint = drawLocations.get(0);
+
+ //calculate center and draw triangle fan all around it
+ LatLon centerPoint = LatLon.interpolate(.5f, firstPoint, drawLocations.get(drawLocations.size()/2));
+
+ vertexBuffer.put((float) (centerPoint.getLongitude().degrees - referencePos.getLongitude().degrees));
+ vertexBuffer.put((float) (centerPoint.getLatitude().degrees - referencePos.getLatitude().degrees));
+ numBytes += 2 * 8; // 3 coords of 8 bytes each
+
+ for (LatLon ll : drawLocations)
+ {
+ vertexBuffer.put((float) (ll.getLongitude().degrees - referencePos.getLongitude().degrees));
+ vertexBuffer.put((float) (ll.getLatitude().degrees - referencePos.getLatitude().degrees));
+ numBytes += 2 * 8; // 3 coords of 8 bytes each
+ }
+ //Add first point again
+ vertexBuffer.put((float) (firstPoint.getLongitude().degrees - referencePos.getLongitude().degrees));
+ vertexBuffer.put((float) (firstPoint.getLatitude().degrees - referencePos.getLatitude().degrees));
+ numBytes += 2 * 8; // 3 coords of 8 bytes each
+ vertexBuffer.flip();
+
+ dc.getCurrentProgram().vertexAttribPointer("vertexPoint", 2, GL_FLOAT, false, 0, vertexBuffer);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, drawLocations.size());
+ }
+
+ return numBytes;
+ }
+
// protected Integer doTessellateInterior(DrawContext dc)
// {
//
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/render/DrawContext.java b/WorldWindAndroid/src/gov/nasa/worldwind/render/DrawContext.java
index 535f442..52c94ec 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/render/DrawContext.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/render/DrawContext.java
@@ -92,24 +92,6 @@ public int compareTo(OrderedRenderableEntry that) {
protected Set perFrameStatisticsKeys;
protected Map perFrameStatistics;
- protected GLRuntimeCapabilities glRuntimeCaps;
-
- public GLRuntimeCapabilities getGLRuntimeCapabilities()
- {
- return this.glRuntimeCaps;
- }
-
- public void setGLRuntimeCapabilities(GLRuntimeCapabilities capabilities)
- {
- if (capabilities == null)
- {
- String message = Logging.getMessage("nullValue.GLRuntimeCapabilitiesIsNull");
- Logging.error(message);
- throw new IllegalArgumentException(message);
- }
-
- this.glRuntimeCaps = capabilities;
- }
/**
* Initializes this DrawContext
. This method should be called at the beginning of each frame to prepare
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/render/Path.java b/WorldWindAndroid/src/gov/nasa/worldwind/render/Path.java
index b89a73c..ee9629a 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/render/Path.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/render/Path.java
@@ -1168,7 +1168,12 @@ protected void beginDrawing(DrawContext dc) {
// each shape.
program.enableVertexAttribute("vertexPoint");
- program.loadUniform1f("uOpacity", dc.isPickingMode() ? 1f : this.layer.getOpacity());
+ double opacity = 1d;
+ if(this.layer!=null)
+ opacity = layer.getOpacity();
+ else if(dc.getCurrentLayer()!=null)
+ opacity = dc.getCurrentLayer().getOpacity();
+ program.loadUniform1f("uOpacity", dc.isPickingMode() ? 1f : opacity);
// Set the OpenGL state that this shape depends on.
GLES20.glDisable(GLES20.GL_CULL_FACE);
@@ -1268,7 +1273,7 @@ protected void doDrawOutlineVBO(DrawContext dc, int[] vboIds, PathData pathData)
if (this.isShowPositions())
{
this.drawPointsVBO(dc, vboIds, pathData);
- drawPointLabels(dc, pathData, false);
+ drawPointLabels(dc, pathData, true);
}
}
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/render/SurfaceObjectTileBuilder.java b/WorldWindAndroid/src/gov/nasa/worldwind/render/SurfaceObjectTileBuilder.java
index 261b6b9..4d27066 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/render/SurfaceObjectTileBuilder.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/render/SurfaceObjectTileBuilder.java
@@ -6,19 +6,16 @@
package gov.nasa.worldwind.render;
import android.graphics.Point;
+import android.opengl.GLES20;
import gov.nasa.worldwind.WorldWindowImpl;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.avlist.AVList;
import gov.nasa.worldwind.avlist.AVListImpl;
import gov.nasa.worldwind.cache.Cacheable;
import gov.nasa.worldwind.geom.*;
-import gov.nasa.worldwind.render.GpuTextureTile;
import gov.nasa.worldwind.util.*;
import java.util.*;
-import java.util.List;
-
-import android.opengl.GLES20;
import static android.opengl.GLES20.*;
@@ -533,6 +530,7 @@ protected void updateTile(DrawContext dc, SurfaceObjectTile tile, Matrix project
if (texture == null) // Create the tile's texture if it doesn't already have one.
{
+ Logging.verbose("Creating tile texture");
texture = this.createTileTexture(dc, tile.getWidth(), tile.getHeight());
tile.setTexture(dc.getTextureCache(), texture);
}
@@ -595,11 +593,14 @@ protected void updateTile(DrawContext dc, SurfaceObjectTile tile, Matrix project
*/
protected GpuTexture createTileTexture(DrawContext dc, int width, int height)
{
+ Logging.verbose(String.format("createTileTexture(%d, %d)", width, height));
int internalFormat = this.tileTextureFormat == 0 ? DEFAULT_TEXTURE_INTERNAL_FORMAT : tileTextureFormat;
int [] textureId = new int[1];
glGenTextures(1, textureId, 0);
+ glBindTexture(GL_TEXTURE_2D, textureId[0]);
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, this.isUseLinearFilter() ?
(this.isUseMipmaps() ? GL_LINEAR_MIPMAP_LINEAR : GL_LINEAR) : GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, this.isUseLinearFilter() ?
@@ -607,15 +608,17 @@ protected GpuTexture createTileTexture(DrawContext dc, int width, int height)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- GpuTexture t = new GpuTexture(GL_TEXTURE_2D, textureId, width, height,
- OGLUtil.estimateMemorySize(internalFormat, GL_UNSIGNED_BYTE, width, height, isUseMipmaps()), Matrix.fromIdentity());
-
- t.bind();
+ glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null);
if(isUseMipmaps()) {
glGenerateMipmap(textureId[0]);
}
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ GpuTexture t = new GpuTexture(GL_TEXTURE_2D, textureId, width, height,
+ OGLUtil.estimateMemorySize(internalFormat, GL_UNSIGNED_BYTE, width, height, isUseMipmaps()), Matrix.fromIdentity());
+
return t;
}
@@ -787,6 +790,8 @@ protected void assembleTiles(DrawContext dc)
if (sectors == null)
continue;
+ if(WorldWindowImpl.DEBUG)
+ Logging.verbose(String.format("Surface object sectors: %s", sectors));
for (Sector s : sectors)
{
// Use the LevelSets tiling scheme to index the surface object's sector into the top level tiles. This
@@ -863,42 +868,53 @@ protected void assembleTiles(DrawContext dc)
protected void addTileOrDescendants(DrawContext dc, LevelSet levelSet, SurfaceObjectTile parent,
SurfaceObjectTile tile)
{
+// if(WorldWindowImpl.DEBUG) Logging.verbose(String.format("Checking tile %s @%s", tile, tile.getSector()));
+
+ // Ignore this tile if it falls completely outside the DrawContext's visible sector.
+ if (!this.intersectsVisibleSector(dc, tile))
+ {
+// if(WorldWindowImpl.DEBUG) Logging.verbose(String.format("!intersect visible sector throwing away"));
+ // This tile is not added to the current tile list, so we clear it's object list to prepare it for use
+ // during the next frame.
+ tile.clearObjectList();
+ return;
+ }
+
// Ignore this tile if it falls completely outside the DrawContext's visible sector.
- if (!this.intersectsVisibleSector(dc, tile))
- {
- // This tile is not added to the current tile list, so we clear it's object list to prepare it for use
- // during the next frame.
- tile.clearObjectList();
- return;
- }
+// if (!this.intersectsFrustum(dc, tile))
+// {
+// if(WorldWindowImpl.DEBUG) Logging.verbose(String.format("!Intersect frustrum throwing away"));
+// // This tile is not added to the current tile list, so we clear it's object list to prepare it for use
+// // during the next frame.
+// tile.clearObjectList();
+// return;
+// }
- // Ignore this tile if it falls completely outside the frustum. This may be the viewing frustum or the pick
- // frustum, depending on the implementation.
- if (!this.intersectsFrustum(dc, tile))
- {
- // This tile is not added to the current tile list, so we clear it's object list to prepare it for use
- // during the next frame.
- tile.clearObjectList();
- return;
- }
+// if(WorldWindowImpl.DEBUG) Logging.verbose(String.format("Visible checking for objects"));
// If the parent tile is not null, add any parent surface objects that intersect this tile.
if (parent != null)
this.addIntersectingObjects(dc, parent, tile);
// Ignore tiles that do not intersect any surface objects.
- if (!tile.hasObjects())
- return;
+ if (!tile.hasObjects()) {
+// if(WorldWindowImpl.DEBUG) Logging.verbose("!tile.hasObjects()");
+ return;
+ }
+// if(WorldWindowImpl.DEBUG) Logging.verbose(String.format("Tile has objects: %s", tile.getObjectList()));
// If this tile meets the current rendering criteria, add it to the current tile list. This tile's object list
// is cleared after the tile update operation.
if (this.meetsRenderCriteria(dc, levelSet, tile))
{
- this.addTile(tile);
+ if(WorldWindowImpl.DEBUG) Logging.verbose(String.format("Meets render criteria so adding this tile"));
+
+ this.addTile(tile);
return;
}
Level nextLevel = levelSet.getLevel(tile.getLevelNumber() + 1);
+// if(WorldWindowImpl.DEBUG) Logging.verbose(String.format("Splitting tile to next level: %d", nextLevel.getLevelNumber()));
for (GpuTextureTile subTile : tile.createSubTiles(nextLevel))
{
this.addTileOrDescendants(dc, levelSet, tile, (SurfaceObjectTile) subTile);
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/render/SurfaceQuad.java b/WorldWindAndroid/src/gov/nasa/worldwind/render/SurfaceQuad.java
index 811a706..96dea97 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/render/SurfaceQuad.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/render/SurfaceQuad.java
@@ -5,27 +5,23 @@
*/
package gov.nasa.worldwind.render;
-import gov.nasa.worldwind.Configuration;
-import gov.nasa.worldwind.WorldWind;
-import gov.nasa.worldwind.avlist.AVKey;
+import android.opengl.GLES20;
import gov.nasa.worldwind.geom.Angle;
import gov.nasa.worldwind.geom.LatLon;
import gov.nasa.worldwind.geom.Position;
import gov.nasa.worldwind.globes.Globe;
+import gov.nasa.worldwind.util.BufferUtil;
import gov.nasa.worldwind.util.Logging;
import gov.nasa.worldwind.util.SurfaceTileDrawContext;
-import javax.xml.stream.XMLOutputFactory;
-import javax.xml.stream.XMLStreamException;
-import javax.xml.stream.XMLStreamWriter;
-import java.awt.*;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.Writer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import static android.opengl.GLES20.GL_FLOAT;
+import static android.opengl.GLES20.GL_LINE_STRIP;
+import static android.opengl.GLES20.glDrawArrays;
+
/**
* @author dcollins
* @version $Id: SurfaceQuad.java 1171 2013-02-11 21:45:02Z dcollins $
@@ -370,7 +366,32 @@ protected List> createGeometry(Globe globe, SurfaceTileDrawContext
return geom;
}
- //**************************************************************//
+ @Override
+ protected Integer doTessellateInterior(DrawContext dc) {
+ Position refPos = this.getReferencePosition();
+ if (refPos == null)
+ return null;
+
+ for (List drawLocations : this.activeGeometry)
+ {
+ if (vertexBuffer == null || vertexBuffer.capacity() < 2 * drawLocations.size())
+ vertexBuffer = BufferUtil.newFloatBuffer(2 * drawLocations.size());
+ vertexBuffer.clear();
+
+ for (LatLon ll : drawLocations)
+ {
+ vertexBuffer.put((float) (ll.getLongitude().degrees - refPos.getLongitude().degrees));
+ vertexBuffer.put((float) (ll.getLatitude().degrees - refPos.getLatitude().degrees));
+ }
+ vertexBuffer.flip();
+
+ dc.getCurrentProgram().vertexAttribPointer("vertexPoint", 2, GL_FLOAT, false, 0, vertexBuffer);
+ glDrawArrays(GLES20.GL_TRIANGLE_FAN, 0, drawLocations.size());
+ }
+ return 4*8;
+ }
+
+//**************************************************************//
//******************** Restorable State ***********************//
//**************************************************************//
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/terrain/TiledTessellator.java b/WorldWindAndroid/src/gov/nasa/worldwind/terrain/TiledTessellator.java
index d119fda..529c862 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/terrain/TiledTessellator.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/terrain/TiledTessellator.java
@@ -1006,8 +1006,8 @@ protected void markSectorExpired(Sector sector) {
protected boolean isExpired(DrawContext dc, TerrainTile tile) {
TerrainGeometry geom = tile.getGeometry(getTerrainGeometryCache());
if(geom==null) {
- if(WorldWindowImpl.DEBUG)
- Logging.verbose("Generating tile geometry for first time: " + tile);
+// if(WorldWindowImpl.DEBUG)
+// Logging.verbose("Generating tile geometry for first time: " + tile);
return true;
}
if(geom.verticalExaggeration != dc.getVerticalExaggeration()) {
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/util/GLRuntimeCapabilities.java b/WorldWindAndroid/src/gov/nasa/worldwind/util/GLRuntimeCapabilities.java
index f267fd2..e0a1e50 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/util/GLRuntimeCapabilities.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/util/GLRuntimeCapabilities.java
@@ -5,15 +5,11 @@
*/
package gov.nasa.worldwind.util;
-import gov.nasa.worldwind.Configuration;
-import gov.nasa.worldwind.avlist.AVKey;
-import java.util.Scanner;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.Arrays;
+import java.util.List;
import static android.opengl.GLES20.*;
-import static gov.nasa.worldwind.WorldWindowImpl.*;
/**
* GLRuntimeCapabilities describes the GL capabilities supported by the current GL runtime. It provides the caller with
@@ -37,443 +33,410 @@
*/
public class GLRuntimeCapabilities
{
- protected static final String GL_EXT_FRAMEBUFFER_OBJECT_STRING = "GL_EXT_framebuffer_object";
- protected static final String GL_EXT_TEXTURE_FILTER_ANISOTROPIC_STRING = "GL_EXT_texture_filter_anisotropic";
-
- protected double glVersion;
- protected boolean isVMwareSVGA3D;
- protected boolean isAnisotropicTextureFilterAvailable;
- protected boolean isAnisotropicTextureFilterEnabled;
- protected boolean isFramebufferObjectAvailable;
- protected boolean isFramebufferObjectEnabled;
- protected boolean isVertexBufferObjectAvailable;
- protected boolean isVertexBufferObjectEnabled;
- protected int depthBits;
- protected double maxTextureAnisotropy;
- protected int maxTextureSize;
- protected int numTextureUnits;
- protected String extensions;
-
- /**
- * Constructs a new GLAtttributes, enabling framebuffer objects, anisotropic texture filtering, and vertex buffer
- * objects. Note that these properties are marked as enabled, but they are not known to be available yet. All other
- * properties are set to default values which may be set explicitly by the caller, or implicitly by calling {@link
- * #initialize()}.
- *
- * Note: The default vertex-buffer usage flag can be set via {@link gov.nasa.worldwind.Configuration} using the key
- * "gov.nasa.worldwind.avkey.VBOUsage". If that key is not specified in the configuration then vertex-buffer usage
- * defaults to true
.
- */
- public GLRuntimeCapabilities()
- {
- this.isAnisotropicTextureFilterEnabled = true;
- this.isFramebufferObjectEnabled = true;
- this.isVertexBufferObjectEnabled = true;
- this.maxTextureAnisotropy = -1d;
- }
-
- /**
- * Initialize this GLRuntimeCapabilities. The context's
- * runtime GL capabilities are examined, and the properties of this GLRuntimeCapabilities are modified accordingly.
- * Invoking initialize() may change any property of this GLRuntimeCapabilities, except the caller specified enable
- * flags: is[Feature]Enabled.
- *
- * @throws IllegalArgumentException if the glContext is null.
- */
- public void initialize()
- {
- if (this.glVersion < 1.0)
- {
- String s = glGetString(GL_VERSION);
- Pattern p = Pattern.compile(".*?(\\d+).(\\d+)");
- Matcher m = p.matcher(s);
- Logging.info("Version: " + s);
- try {
- for(int i=0; i mExtensions;
+
+ private static GLRuntimeCapabilities instance;
+
+ public static GLRuntimeCapabilities getInstance() {
+ if (instance == null) {
+ synchronized (GLRuntimeCapabilities.class) {
+ if(instance==null) {
+ instance = new GLRuntimeCapabilities();
+ }
+ }
+ }
+ return instance;
+ }
+ /**
+ * Constructs a new GLAtttributes, enabling framebuffer objects, anisotropic texture filtering, and vertex buffer
+ * objects. Note that these properties are marked as enabled, but they are not known to be available yet. All other
+ * properties are set to default values which may be set explicitly by the caller.
+ *
+ * Note: The default vertex-buffer usage flag can be set via {@link gov.nasa.worldwind.Configuration} using the key
+ * "gov.nasa.worldwind.avkey.VBOUsage". If that key is not specified in the configuration then vertex-buffer usage
+ * defaults to true
.
+ */
+ private GLRuntimeCapabilities() {
+ mParam = new int[1];
+
+ String[] versionString = (glGetString(GL_VERSION)).split(" ");
+ if (versionString.length >= 3) {
+ String[] versionParts = versionString[2].split("\\.");
+ if (versionParts.length >= 2) {
+ mGLES_Major_Version = Integer.parseInt(versionParts[0]);
+ if (versionParts[1].endsWith(":") || versionParts[1].endsWith("-")) {
+ versionParts[1] = versionParts[1].substring(0, versionParts[1].length() - 1);
+ }
+ mGLES_Minor_Version = Integer.parseInt(versionParts[1]);
+ glVersion = Double.parseDouble(mGLES_Major_Version + "." + mGLES_Minor_Version);
+ }
+ }
+ versionString = (glGetString(GL_SHADING_LANGUAGE_VERSION)).split(" ");
+ if (versionString.length >= 3) {
+ String[] versionParts = versionString[2].split("\\.");
+ if (versionParts.length >= 2) {
+ mGLSL_Major_Version = Integer.parseInt(versionParts[0]);
+ if (versionParts[1].endsWith(":") || versionParts[1].endsWith("-")) {
+ versionParts[1] = versionParts[1].substring(0, versionParts[1].length() - 1);
+ }
+ mGLSL_Minor_Version = Integer.parseInt(versionParts[1]);
+ glslVersion = Double.parseDouble(mGLSL_Major_Version + "." + mGLSL_Minor_Version);
}
-// if (s != null)
-// {
-// s = s.substring(0, 3);
-// Double d = WWUtil.convertStringToDouble(s);
-// if (d != null)
-// this.glVersion = d;
-// }
- }
-
- // Determine whether or not the OpenGL implementation is provided by the VMware SVGA 3D driver. This flag is
- // used to work around bugs and unusual behavior in the VMware SVGA 3D driver. The VMware drivers tested on
- // 7 August 2013 report the following strings for GL_VENDOR and GL_RENDERER:
- // - GL_VENDOR: "VMware, Inc."
- // - GL_RENDERER: "Gallium 0.4 on SVGA3D; build: RELEASE;"
- String glVendor = glGetString(GL_VENDOR);
- String glRenderer = glGetString(GL_RENDERER);
- if (glVendor != null && glVendor.toLowerCase().contains("vmware")
- && glRenderer != null && glRenderer.toLowerCase().contains("svga3d"))
- {
- this.isVMwareSVGA3D = true;
- }
- if(this.extensions==null) {
- this.extensions = glGetString(GL_EXTENSIONS);
- if(DEBUG)
- Logging.info("GL Extensions:\n"+extensions);
}
- this.isAnisotropicTextureFilterAvailable = isExtensionAvailable(GL_EXT_TEXTURE_FILTER_ANISOTROPIC_STRING);
- this.isFramebufferObjectAvailable = isExtensionAvailable(GL_EXT_FRAMEBUFFER_OBJECT_STRING);
- // Vertex Buffer Objects are supported in version 1.5 or greater only.
- this.isVertexBufferObjectAvailable = this.glVersion >= 1.5;
-
- if (this.depthBits == 0)
- {
- int[] params = new int[1];
- glGetIntegerv(GL_DEPTH_BITS, params, 0);
- this.depthBits = params[0];
- }
-
- // Texture max anisotropy defaults to -1. A value less than 2.0 indicates that this graphics context does not
- // support texture anisotropy.
- if (this.maxTextureAnisotropy < 0)
- {
- // Documentation on the anisotropic texture filter is available at
- // http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt
- if (this.isAnisotropicTextureFilterAvailable)
- {
- // The maxAnisotropy value can be any real value. A value less than 2.0 indicates that the graphics
- // context does not support texture anisotropy.
+
+ // Determine whether or not the OpenGL implementation is provided by the VMware SVGA 3D driver. This flag is
+ // used to work around bugs and unusual behavior in the VMware SVGA 3D driver. The VMware drivers tested on
+ // 7 August 2013 report the following strings for GL_VENDOR and GL_RENDERER:
+ // - GL_VENDOR: "VMware, Inc."
+ // - GL_RENDERER: "Gallium 0.4 on SVGA3D; build: RELEASE;"
+ glVendor = glGetString(GL_VENDOR);
+ glRenderer = glGetString(GL_RENDERER);
+
+ mExtensions = Arrays.asList(glGetString(GL_EXTENSIONS).split(" "));
+
+ isAnisotropicTextureFilterAvailable = isExtensionAvailable("GL_EXT_texture_filter_anisotropic");
+ isFramebufferObjectAvailable = true;//isExtensionAvailable(GL_EXT_framebuffer_object) || isExtensionAvailable("OES_fbo_render_mipmap");
+ // Vertex Buffer Objects are supported in version 1.5 or greater only. we are using 2.0
+ isVertexBufferObjectAvailable = true;
+
+ // Documentation on the anisotropic texture filter is available at
+ // http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt
+ if (isAnisotropicTextureFilterAvailable)
+ {
+ // The maxAnisotropy value can be any real value. A value less than 2.0 indicates that the graphics
+ // context does not support texture anisotropy.
// float[] params = new float[1];
// glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, params, 0);
// this.maxTextureAnisotropy = params[0];
- }
- }
-
- if (this.numTextureUnits == 0)
- {
- int[] params = new int[1];
- glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, params, 0);
- this.numTextureUnits = params[0];
- }
-
- if (this.maxTextureSize == 0)
- {
- int[] params = new int[1];
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, params, 0);
- this.maxTextureSize = params[0];
- }
- }
+ }
+ mDepthBits = getInt(GL_DEPTH_BITS);
+ mMaxCombinedTextureImageUnits = getInt(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
+ mMaxCubeMapTextureSize = getInt(GL_MAX_CUBE_MAP_TEXTURE_SIZE);
+ mMaxFragmentUniformVectors = getInt(GL_MAX_FRAGMENT_UNIFORM_VECTORS);
+ mMaxRenderbufferSize = getInt(GL_MAX_RENDERBUFFER_SIZE);
+ mMaxTextureImageUnits = getInt(GL_MAX_TEXTURE_IMAGE_UNITS);
+ mMaxTextureSize = getInt(GL_MAX_TEXTURE_SIZE);
+ mMaxVaryingVectors = getInt(GL_MAX_VARYING_VECTORS);
+ mMaxVertexAttribs = getInt(GL_MAX_VERTEX_ATTRIBS);
+ mMaxVertexTextureImageUnits = getInt(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
+ mMaxVertexUniformVectors = getInt(GL_MAX_VERTEX_UNIFORM_VECTORS);
+ mMaxViewportWidth = getInt(GL_MAX_VIEWPORT_DIMS, 2, 0);
+ mMaxViewportHeight = getInt(GL_MAX_VIEWPORT_DIMS, 2, 1);
+ mMinAliasedLineWidth = getInt(GL_ALIASED_LINE_WIDTH_RANGE, 2, 0);
+ mMaxAliasedLineWidth = getInt(GL_ALIASED_LINE_WIDTH_RANGE, 2, 1);
+ mMinAliasedPointSize = getInt(GL_ALIASED_POINT_SIZE_RANGE, 2, 0);
+ mMaxAliasedPointSize = getInt(GL_ALIASED_POINT_SIZE_RANGE, 2, 1);
+ }
+
+ private int getInt(int pname)
+ {
+ glGetIntegerv(pname, mParam, 0);
+ return mParam[0];
+ }
+
+ private int getInt(int pname, int length, int index)
+ {
+ int[] params = new int[length];
+ glGetIntegerv(pname, params, 0);
+ return params[index];
+ }
public boolean isExtensionAvailable(CharSequence extension) {
- return this.extensions.contains(extension);
+ return this.mExtensions.contains(extension);
+ }
+
+ /**
+ * Returns the current GL runtime version as a real number. For example, if the GL version is 1.5, this returns the
+ * floating point number equivalent to 1.5.
+ *
+ * @return GL version as a number.
+ */
+ public double getGLVersion()
+ {
+ return this.glVersion;
+ }
+
+ public double getGLSLVersion()
+ {
+ return this.glslVersion;
}
- /**
- * Returns the current GL runtime version as a real number. For example, if the GL version is 1.5, this returns the
- * floating point number equivalent to 1.5.
- *
- * @return GL version as a number.
- */
- public double getGLVersion()
- {
- return this.glVersion;
- }
-
- /**
- * Sets the current GL runtime version as a real number. For example, to set a GL version of 1.5, specify the
- * floating point number 1.5.
- *
- * @param version the GL version as a number.
- */
- public void setGLVersion(double version)
- {
- this.glVersion = version;
- }
-
- /**
- * Returns true if the OpenGL implementation is provided by the VMware SVGA 3D driver. Otherwise this returns
- * false.
- *
- * This flag is used to work around bugs and unusual behavior in the VMware SVGA 3D driver. For details on VMware
- * graphics drivers, see http://www.vmware.com/files/pdf/techpaper/vmware-horizon-view-graphics-acceleration-deployment.pdf.
- *
- * @return true if the OpenGL implementation is VMware SVGA 3D, and false otherwise.
- */
- public boolean isVMwareSVGA3D()
- {
- return this.isVMwareSVGA3D;
- }
-
- /**
- * Returns true if anisotropic texture filtering is available in the current GL runtime, and is enabled. Otherwise
- * this returns false. For details on GL anisotropic texture filtering, see http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt.
- *
- * @return true if anisotropic texture filtering is available and enabled, and false otherwise.
- */
- public boolean isUseAnisotropicTextureFilter()
- {
- return this.isAnisotropicTextureFilterAvailable && this.isAnisotropicTextureFilterEnabled;
- }
-
- /**
- * Returns true if framebuffer objects are available in the current GL runtime, and are enabled. Otherwise this
- * returns false. For details on GL framebuffer objects, see http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt.
- *
- * @return true if framebuffer objects are available and enabled, and false otherwise.
- */
- public boolean isUseFramebufferObject()
- {
- return this.isFramebufferObjectAvailable && this.isFramebufferObjectEnabled;
- }
-
- /**
- * Returns true if vertex buffer objects are available in the current GL runtime, and are enabled. Otherwise this
- * returns false. For details on GL vertex buffer objects, see http://www.opengl.org/registry/specs/ARB/vertex_buffer_object.txt.
- *
- * @return true if vertex buffer objects are available and enabled, and false otherwise.
- */
- public boolean isUseVertexBufferObject()
- {
- return this.isVertexBufferObjectAvailable && this.isVertexBufferObjectEnabled;
- }
-
- /**
- * Returns true if anisotropic filtering is available in the current GL runtime.
- *
- * @return true if anisotropic texture filtering is available, and false otherwise.
- */
- public boolean isAnisotropicTextureFilterAvailable()
- {
- return this.isAnisotropicTextureFilterAvailable;
- }
-
- /**
- * Sets whether or not anisotropic filtering is available in the current GL runtime.
- *
- * @param available true to flag anisotropic texture filtering as available, and false otherwise.
- */
- public void setAnisotropicTextureFilterAvailable(boolean available)
- {
- this.isAnisotropicTextureFilterAvailable = available;
- }
-
- /**
- * Returns true if anisotropic texture filtering is enabled for use (only applicable if the feature is available in
- * the current GL runtime)
- *
- * @return true if anisotropic texture filtering is enabled, and false otherwise.
- */
- public boolean isAnisotropicTextureFilterEnabled()
- {
- return this.isAnisotropicTextureFilterEnabled;
- }
-
- /**
- * Sets whether or not anisotropic texture filtering should be used if it is available in the current GL runtime.
- *
- * @param enable true to enable anisotropic texture filtering, false to disable it.
- */
- public void setAnisotropicTextureFilterEnabled(boolean enable)
- {
- this.isAnisotropicTextureFilterEnabled = enable;
- }
-
- /**
- * Returns true if framebuffer objects are available in the current GL runtime.
- *
- * @return true if framebuffer objects are available, and false otherwise.
- */
- public boolean isFramebufferObjectAvailable()
- {
- return this.isFramebufferObjectAvailable;
- }
-
- /**
- * Sets whether or not framebuffer objects are available in the current GL runtime.
- *
- * @param available true to flag framebuffer objects as available, and false otherwise.
- */
- public void setFramebufferObjectAvailable(boolean available)
- {
- this.isFramebufferObjectAvailable = available;
- }
-
- /**
- * Returns true if framebuffer objects are enabled for use (only applicable if the feature is available in the
- * current GL runtime)
- *
- * @return true if framebuffer objects are enabled, and false otherwise.
- */
- public boolean isFramebufferObjectEnabled()
- {
- return this.isFramebufferObjectEnabled;
- }
-
- /**
- * Sets whether or not framebuffer objects should be used if they are available in the current GL runtime.
- *
- * @param enable true to enable framebuffer objects, false to disable them.
- */
- public void setFramebufferObjectEnabled(boolean enable)
- {
- this.isFramebufferObjectEnabled = enable;
- }
-
- /**
- * Returns true if vertex buffer objects are available in the current GL runtime.
- *
- * @return true if vertex buffer objects are available, and false otherwise.
- */
- public boolean isVertexBufferObjectAvailable()
- {
- return this.isVertexBufferObjectAvailable;
- }
-
- /**
- * Sets whether or not vertext buffer objects are available in the current GL runtime.
- *
- * @param available true to flag vertex buffer objects as available, and false otherwise.
- */
- public void setVertexBufferObjectAvailable(boolean available)
- {
- this.isVertexBufferObjectAvailable = available;
- }
-
- /**
- * Returns true if anisotropic vertex buffer objects are enabled for use (only applicable if the feature is
- * available in the current GL runtime).
- *
- * @return true if anisotropic vertex buffer objects are, and false otherwise.
- */
- public boolean isVertexBufferObjectEnabled()
- {
- return this.isVertexBufferObjectEnabled;
- }
-
- /**
- * Sets whether or not vertex buffer objects should be used if they are available in the current GL runtime.
- *
- * @param enable true to enable vertex buffer objects, false to disable them.
- */
- public void setVertexBufferObjectEnabled(boolean enable)
- {
- this.isVertexBufferObjectEnabled = enable;
- }
-
- /**
- * Returns the number of bitplanes in the current GL depth buffer. The number of bitplanes is directly proportional
- * to the accuracy of the GL renderer's hidden surface removal. The returned value is typically 16, 24 or 32. For
- * more information on OpenGL depth buffering, see http://www.opengl.org/archives/resources/faq/technical/depthbuffer.htm.
- *
- * @return the number of bitplanes in the current GL depth buffer.
- */
- public int getDepthBits()
- {
- return this.depthBits;
- }
-
- /**
- * Sets the number of bitplanes in the current GL depth buffer. The specified value is typically 16, 24 or 32.
- *
- * @param depthBits the number of bitplanes in the current GL depth buffer.
- *
- * @throws IllegalArgumentException if depthBits is less than one.
- */
- public void setDepthBits(int depthBits)
- {
- if (maxTextureSize < 1)
- {
- String message = Logging.getMessage("generic.DepthBitsLessThanOne");
- Logging.error(message);
- throw new IllegalArgumentException(message);
- }
-
- this.depthBits = depthBits;
- }
-
- /**
- * Returns a real number defining the maximum degree of texture anisotropy supported by the current GL runtime. This
- * defines the maximum ratio of the anisotropic texture filter. So 2.0 would define a maximum ratio of 2:1. If the
- * degree is less than 2, then the anisotropic texture filter is not supported by the current GL runtime.
- *
- * @return the maximum degree of texture anisotropy supported.
- */
- public double getMaxTextureAnisotropy()
- {
- return this.maxTextureAnisotropy;
- }
-
- /**
- * Sets the maximum degree of texture anisotropy supported by the current GL runtime. This value defines the
- * maximum ratio of the an anisotropic texture filter. So 2.0 would define a maximum ratio of 2:1. A valueless than
- * 2 denotes that the anisotropic texture filter is not supported by the current GL runtime.
- *
- * @param maxAnisotropy the maximum degree of texture anisotropy supported.
- */
- public void setMaxTextureAnisotropy(double maxAnisotropy)
- {
- this.maxTextureAnisotropy = maxAnisotropy;
- }
-
- /**
- * Returns the maximum texture size in texels supported by the current GL runtime. For a 1D texture, this defines
- * the maximum texture width, for a 2D texture, this defines the maximum texture width and height, and for a 3D
- * texture, this defines the maximum width, height, and depth.
- *
- * @return the maximum texture size supported, in texels.
- */
- public int getMaxTextureSize()
- {
- return this.maxTextureSize;
- }
-
- /**
- * Sets the maximum texture size in texels supported by the current GL runtime. For a 1D texture, this defines the
- * maximum texture width, for a 2D texture, this defines the maximum texture width and height, and for a 3D texture,
- * this defines the maximum width, height, and depth.
- *
- * @param maxTextureSize the maximum texture size supported, in texels.
- *
- * @throws IllegalArgumentException if the size is less than one.
- */
- public void setMaxTextureSize(int maxTextureSize)
- {
- if (maxTextureSize < 1)
- {
- String message = Logging.getMessage("generic.MaxTextureSizeLessThanOne");
- Logging.error(message);
- throw new IllegalArgumentException(message);
- }
-
- this.maxTextureSize = maxTextureSize;
- }
-
- /**
- * Returns the number of texture units supported by the current GL runtime.
- *
- * @return the number of texture units supported.
- */
- public int getNumTextureUnits()
- {
- return this.numTextureUnits;
- }
-
- /**
- * Sets the number of texture units supported by the current GL runtime.
- *
- * @param numTextureUnits the number texture units supported.
- *
- * @throws IllegalArgumentException if the number of texture units is less than one.
- */
- public void setNumTextureUnits(int numTextureUnits)
- {
- if (numTextureUnits < 1)
- {
- String message = Logging.getMessage("generic.NumTextureUnitsLessThanOne");
- Logging.error(message);
- throw new IllegalArgumentException(message);
- }
-
- this.numTextureUnits = numTextureUnits;
- }
+ /**
+ * Returns true if anisotropic texture filtering is available in the current GL runtime, and is enabled. Otherwise
+ * this returns false. For details on GL anisotropic texture filtering, see http://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt.
+ *
+ * @return true if anisotropic texture filtering is available and enabled, and false otherwise.
+ */
+ public boolean isUseAnisotropicTextureFilter()
+ {
+ return this.isAnisotropicTextureFilterAvailable && this.isAnisotropicTextureFilterEnabled;
+ }
+
+ /**
+ * Returns true if framebuffer objects are available in the current GL runtime, and are enabled. Otherwise this
+ * returns false. For details on GL framebuffer objects, see http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt.
+ *
+ * @return true if framebuffer objects are available and enabled, and false otherwise.
+ */
+ public boolean isUseFramebufferObject()
+ {
+ return this.isFramebufferObjectAvailable && this.isFramebufferObjectEnabled;
+ }
+
+ public void setAnisotropicTextureFilterEnabled(boolean enable)
+ {
+ this.isAnisotropicTextureFilterEnabled = enable;
+ }
+
+ /**
+ * Sets whether or not framebuffer objects should be used if they are available in the current GL runtime.
+ *
+ * @param enable true to enable framebuffer objects, false to disable them.
+ */
+ public void setFramebufferObjectEnabled(boolean enable)
+ {
+ this.isFramebufferObjectEnabled = enable;
+ }
+
+ /**
+ * Returns the number of bitplanes in the current GL depth buffer. The number of bitplanes is directly proportional
+ * to the accuracy of the GL renderer's hidden surface removal. The returned value is typically 16, 24 or 32. For
+ * more information on OpenGL depth buffering, see http://www.opengl.org/archives/resources/faq/technical/depthbuffer.htm.
+ *
+ * @return the number of bitplanes in the current GL depth buffer.
+ */
+ public int getDepthBits()
+ {
+ return mDepthBits;
+ }
+
+ /**
+ * Returns a real number defining the maximum degree of texture anisotropy supported by the current GL runtime. This
+ * defines the maximum ratio of the anisotropic texture filter. So 2.0 would define a maximum ratio of 2:1. If the
+ * degree is less than 2, then the anisotropic texture filter is not supported by the current GL runtime.
+ *
+ * @return the maximum degree of texture anisotropy supported.
+ */
+ public double getMaxTextureAnisotropy() {
+ return mMaxTextureAnisotropy;
+ }
+
+ /**
+ * A rough estimate of the largest texture that OpenGL can handle.
+ * @return
+ */
+ public int getMaxTextureSize()
+ {
+ return mMaxTextureSize;
+ }
+
+ /**
+ * The maximum supported texture image units that can be used to access texture maps from the vertex shader
+ * and the fragment processor combined. If both the vertex shader and the fragment processing stage access
+ * the same texture image unit, then that counts as using two texture image units against this limit.
+ * @return
+ */
+ public int getMaxCombinedTextureUnits()
+ {
+ return mMaxCombinedTextureImageUnits;
+ }
+
+ /**
+ * The value gives a rough estimate of the largest cube-map texture that the GL can handle.
+ * The value must be at least 1024.
+ * @return
+ */
+ public int getMaxCubeMapTextureSize()
+ {
+ return mMaxCubeMapTextureSize;
+ }
+
+ /**
+ * The maximum number of individual 4-vectors of floating-point, integer, or boolean values that can be held
+ * in uniform variable storage for a fragment shader.
+ * @return
+ */
+ public int getMaxFragmentUniformVectors()
+ {
+ return mMaxFragmentUniformVectors;
+ }
+
+ /**
+ * Indicates the maximum supported size for renderbuffers.
+ * @return
+ */
+ public int getMaxRenderbufferSize()
+ {
+ return mMaxRenderbufferSize;
+ }
+
+ /**
+ * The maximum supported texture image units that can be used to access texture maps from the fragment shader.
+ * @return
+ */
+ public int getMaxTextureImageUnits()
+ {
+ return mMaxTextureImageUnits;
+ }
+
+ /**
+ * The maximum number of 4-vectors for varying variables.
+ * @return
+ */
+ public int getMaxVaryingVectors()
+ {
+ return mMaxVaryingVectors;
+ }
+
+ /**
+ * The maximum number of 4-component generic vertex attributes accessible to a vertex shader.
+ * @return
+ */
+ public int getMaxVertexAttribs()
+ {
+ return mMaxVertexAttribs;
+ }
+
+ /**
+ * The maximum supported texture image units that can be used to access texture maps from the vertex shader.
+ * @return
+ */
+ public int getMaxVertexTextureImageUnits()
+ {
+ return mMaxVertexTextureImageUnits;
+ }
+
+ /**
+ * The maximum number of 4-vectors that may be held in uniform variable storage for the vertex shader.
+ * @return
+ */
+ public int getMaxVertexUniformVectors()
+ {
+ return mMaxVertexUniformVectors;
+ }
+
+ /**
+ * The maximum supported viewport width
+ * @return
+ */
+ public int getMaxViewportWidth()
+ {
+ return mMaxViewportWidth;
+ }
+
+ /**
+ * The maximum supported viewport height
+ * @return
+ */
+ public int getMaxViewportHeight()
+ {
+ return mMaxViewportHeight;
+ }
+
+ /**
+ * Indicates the minimum width supported for aliased lines
+ * @return
+ */
+ public int getMinAliasedLineWidth()
+ {
+ return mMinAliasedLineWidth;
+ }
+
+ /**
+ * Indicates the maximum width supported for aliased lines
+ * @return
+ */
+ public int getMaxAliasedLineWidth()
+ {
+ return mMaxAliasedLineWidth;
+ }
+
+ /**
+ * Indicates the minimum size supported for aliased points
+ * @return
+ */
+ public int getMinAliasedPointSize()
+ {
+ return mMinAliasedPointSize;
+ }
+
+ /**
+ * Indicates the maximum size supported for aliased points
+ * @return
+ */
+ public int getMaxAliasedPointSize()
+ {
+ return mMaxAliasedPointSize;
+ }
+
+ public String toString()
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append("GL v%d.%d", mGLES_Major_Version, mGLES_Minor_Version);
+ sb.append("GLSL v%d.%d", mGLSL_Major_Version, mGLSL_Minor_Version);
+ sb.append("-=-=-=- OpenGL Capabilities -=-=-=-\n");
+ sb.append("Max Cube Map Texture Size : ").append(mMaxCubeMapTextureSize).append("\n");
+ sb.append("Max Fragment Uniform Vectors : ").append(mMaxFragmentUniformVectors).append("\n");
+ sb.append("Max Renderbuffer Size : ").append(mMaxRenderbufferSize).append("\n");
+ sb.append("Max Texture Image Units : ").append(mMaxTextureImageUnits).append("\n");
+ sb.append("Max Texture Size : ").append(mMaxTextureSize).append("\n");
+ sb.append("Max Varying Vectors : ").append(mMaxVaryingVectors).append("\n");
+ sb.append("Max Vertex Attribs : ").append(mMaxVertexAttribs).append("\n");
+ sb.append("Max Vertex Texture Image Units : ").append(mMaxVertexTextureImageUnits).append("\n");
+ sb.append("Max Vertex Uniform Vectors : ").append(mMaxVertexUniformVectors).append("\n");
+ sb.append("Max Viewport Width : ").append(mMaxViewportWidth).append("\n");
+ sb.append("Max Viewport Height : ").append(mMaxViewportHeight).append("\n");
+ sb.append("Min Aliased Line Width : ").append(mMinAliasedLineWidth).append("\n");
+ sb.append("Max Aliased Line Width : ").append(mMaxAliasedLineWidth).append("\n");
+ sb.append("Min Aliased Point Size : ").append(mMinAliasedPointSize).append("\n");
+ sb.append("Max Aliased Point Width : ").append(mMaxAliasedPointSize).append("\n");
+ sb.append("Depth Bits : ").append(mDepthBits).append("\n");
+ sb.append("Is Anisotropic Texture Filter Avail: ").append(isAnisotropicTextureFilterAvailable).append("\n");
+ sb.append("Max Texture Anisotropy : ").append(mMaxTextureAnisotropy).append("\n");
+ sb.append("-=-=-=- /OpenGL Capabilities -=-=-=-\n");
+ sb.append("-=-=-=- OpenGL Extensions -=-=-=-\n");
+ for(String extension : mExtensions)
+ sb.append(extension).append("\n");
+ sb.append("-=-=-=- /OpenGL Extensions -=-=-=-\n");
+ return sb.toString();
+ }
}
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/util/MessageStrings.properties b/WorldWindAndroid/src/gov/nasa/worldwind/util/MessageStrings.properties
index 11b5029..2267a67 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/util/MessageStrings.properties
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/util/MessageStrings.properties
@@ -241,6 +241,7 @@ nullValue.ShapeIsNull=Shape is null
nullValue.SourceIsNull=Source is null
nullValue.StringIsNull=String is null
nullValue.SuffixIsNull=Suffix is null
+nullValue.SurfaceTileDrawContextIsNull=Surface tile draw context is null
nullValue.TaskIsNull=Task is null
nullValue.TerrainIsNull=Terrain is null
nullValue.TextureIsNull=Texture is null
@@ -297,6 +298,7 @@ BasicRetrievalService.RunningThreadNamePrefix=Running World Wind Retriever:\u002
BasicRetrievalService.UncaughtExceptionDuringRetrieval=Uncaught exception during retrieval on thread {0}
BasicSceneController.ExceptionDuringPick=Exception occurred during picking
+BasicSceneController.ExceptionDuringPreRendering=Exception encountered while pre-rendering
Configuration.AppConfigNotFound=Application configuration {0} not found
Configuration.ConversionError=Error parsing configuration value {0}
@@ -378,6 +380,17 @@ Matrix.MatrixIsNotSymmetric=Matrix {0} is not symmetric
MemoryCache.SizeIsLessThanOne=Size {0} is less than one
MemoryCache.SizeIsLargerThanCapacity=Size {0} is larger than cache capacity {1}
+OGL.CannotDeleteVBO=Cannot delete VBO because there's no current OpenGL context
+OGL.FramebufferComplete=Framebuffer complete
+OGL.FramebufferIncompleteAttachment=Framebuffer incomplete: attachment no longer exists, has a dimension of zero, or is a non-renderable buffer
+OGL.FramebufferIncompleteDimensions=Framebuffer incomplete: attachments have different dimensions
+OGL.FramebufferIncompleteDrawBuffer=Framebuffer incomplete: no draw buffer attachment
+OGL.FramebufferIncompleteFormats=Framebuffer incomplete: attachments have different internal formats
+OGL.FramebufferIncompleteMissingAttachment=Framebuffer incomplete: no attachments
+OGL.FramebufferIncompleteMultisample=Framebuffer incomplete: attachment have different renderbuffer samples
+OGL.FramebufferIncompleteReadBuffer=Framebuffer incomplete: no read buffer attachment
+OGL.FramebufferUnsupported=Framebuffer unsupported: attachments violate implementation defined restrictions
+
TaskService.CancellingDuplicateTask=Task service: cancelling duplicate task {0}
TaskService.IdleThreadNamePrefix=World Wind Task (Idle)
TaskService.RunningThreadNamePrefix=World Wind Task
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/util/OGLRenderToTextureSupport.java b/WorldWindAndroid/src/gov/nasa/worldwind/util/OGLRenderToTextureSupport.java
index 58a0a0b..ba3cfd0 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/util/OGLRenderToTextureSupport.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/util/OGLRenderToTextureSupport.java
@@ -6,6 +6,7 @@
package gov.nasa.worldwind.util;
import android.graphics.Rect;
+import gov.nasa.worldwind.WorldWindowImpl;
import gov.nasa.worldwind.geom.Matrix;
import gov.nasa.worldwind.render.Color;
import gov.nasa.worldwind.render.DrawContext;
@@ -79,6 +80,8 @@ public boolean isEnableFramebufferObject()
*/
public void setEnableFramebufferObject(boolean enable)
{
+ if(WorldWindowImpl.DEBUG)
+ Logging.verbose(String.format("setEnableFramebufferObject(%b)", enable));
this.isFramebufferObjectEnabled = enable;
}
@@ -221,7 +224,6 @@ public Matrix beginRendering(DrawContext dc, int x, int y, int width, int height
Logging.error(message);
throw new IllegalArgumentException(message);
}
-
this.drawRegion.set(x, y, width, height);
projection.setOrthographic(x, x+width, y, y+height, -1, 1);
@@ -286,7 +288,6 @@ public void endRendering(DrawContext dc)
}
this.stackHandler.popAttrib();
- this.drawRegion = null;
this.colorTarget = null;
}
@@ -348,11 +349,13 @@ protected void copyScreenPixelsToTexture(DrawContext dc, int x, int y, int width
protected boolean useFramebufferObject(DrawContext dc)
{
- return this.isEnableFramebufferObject() && dc.getGLRuntimeCapabilities().isUseFramebufferObject();
+ return isEnableFramebufferObject() && GLRuntimeCapabilities.getInstance().isUseFramebufferObject();
}
protected void beginFramebufferObjectRendering(DrawContext dc)
{
+ if(WorldWindowImpl.DEBUG)
+ Logging.verbose("binding FrameBuffer Object");
// Binding a framebuffer object causes all GL operations to operate on the attached textures and renderbuffers
// (if any).
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/util/OGLStackHandler.java b/WorldWindAndroid/src/gov/nasa/worldwind/util/OGLStackHandler.java
index f075f36..2c11aa9 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/util/OGLStackHandler.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/util/OGLStackHandler.java
@@ -40,14 +40,14 @@ void restore() {
private static class ColorState {
boolean blendEnabled;
- int []iState = new int[5];
+ int []iState = new int[6];
float []fState = new float[4];
ColorState save() {
blendEnabled = glIsEnabled(GL_BLEND);
glGetIntegerv(GL_BLEND_SRC_RGB, iState, 0);
- glGetIntegerv(GL_BLEND_SRC_ALPHA, iState, 1);
- glGetIntegerv(GL_BLEND_DST_RGB, iState, 2);
+ glGetIntegerv(GL_BLEND_DST_RGB, iState, 1);
+ glGetIntegerv(GL_BLEND_SRC_ALPHA, iState, 2);
glGetIntegerv(GL_BLEND_DST_ALPHA, iState, 3);
glGetIntegerv(GL_BLEND_EQUATION_RGB, iState, 4);
glGetIntegerv(GL_BLEND_EQUATION_ALPHA, iState, 5);
@@ -98,7 +98,7 @@ void restore() {
private static class ScissorState {
boolean enabled;
- int[] box;
+ int[] box = new int[4];
ScissorState save() {
enabled = glIsEnabled(GL_SCISSOR_TEST);
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/util/PickPointFrustumList.java b/WorldWindAndroid/src/gov/nasa/worldwind/util/PickPointFrustumList.java
index 5729c2b..d2acdfb 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/util/PickPointFrustumList.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/util/PickPointFrustumList.java
@@ -5,12 +5,12 @@
*/
package gov.nasa.worldwind.util;
+import android.graphics.Point;
import android.graphics.Rect;
import gov.nasa.worldwind.geom.Extent;
import gov.nasa.worldwind.geom.PickPointFrustum;
import gov.nasa.worldwind.geom.Vec4;
-import java.awt.*;
import java.util.ArrayList;
/**
@@ -248,7 +248,7 @@ public final boolean intersectsAny(Vec4 pa, Vec4 pb)
}
/**
- * Returns true if the specified {@link java.awt.Rectangle} intersects the 2D screen space enclosed by ALL the
+ * Returns true if the specified {@link android.graphics,Rect} intersects the 2D screen space enclosed by ALL the
* Frustums. NOTE: Cannot be true if all frustums do not intersect.
*
* @param rect the Rectangle to test.
@@ -279,7 +279,7 @@ public final boolean intersectsAll(Rect rect)
}
/**
- * Returns true if the specified {@link java.awt.Rectangle} intersects the 2D screen space enclosed by ANY of the
+ * Returns true if the specified {@link android.graphics.Rect} intersects the 2D screen space enclosed by ANY of the
* Frustums.
*
* @param rect the Rectangle to test.
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/util/SurfaceTileDrawContext.java b/WorldWindAndroid/src/gov/nasa/worldwind/util/SurfaceTileDrawContext.java
index c64bc06..73d131e 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/util/SurfaceTileDrawContext.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/util/SurfaceTileDrawContext.java
@@ -5,12 +5,11 @@
*/
package gov.nasa.worldwind.util;
+import android.graphics.Rect;
import gov.nasa.worldwind.geom.LatLon;
import gov.nasa.worldwind.geom.Matrix;
import gov.nasa.worldwind.geom.Sector;
-import java.awt.*;
-
/**
* SurfaceTileDrawContext contains the context needed to render to an off-screen surface tile. SurfaceTileDrawContext is
* defined by a geographic Sector and a corresponding tile viewport. The Sector maps geographic coordinates to pixels in
@@ -22,7 +21,7 @@
public class SurfaceTileDrawContext
{
protected Sector sector;
- protected Rectangle viewport;
+ protected Rect viewport;
protected Matrix projection;
protected Matrix modelview;
@@ -36,7 +35,7 @@ public class SurfaceTileDrawContext
* @throws IllegalArgumentException if either the sector or viewport are null, or if the viewport width or height is
* less than or equal to zero.
*/
- public SurfaceTileDrawContext(Sector sector, Rectangle viewport, Matrix projectionMatrix)
+ public SurfaceTileDrawContext(Sector sector, Rect viewport, Matrix projectionMatrix)
{
if (sector == null)
{
@@ -52,14 +51,14 @@ public SurfaceTileDrawContext(Sector sector, Rectangle viewport, Matrix projecti
throw new IllegalArgumentException(message);
}
- if (viewport.width <= 0)
+ if (viewport.width() <= 0)
{
String message = Logging.getMessage("Geom.WidthInvalid");
Logging.error(message);
throw new IllegalArgumentException(message);
}
- if (viewport.height <= 0)
+ if (viewport.height() <= 0)
{
String message = Logging.getMessage("Geom.HeightInvalid");
Logging.error(message);
@@ -68,8 +67,8 @@ public SurfaceTileDrawContext(Sector sector, Rectangle viewport, Matrix projecti
this.sector = sector;
this.viewport = viewport;
- this.modelview = Matrix.fromGeographicToViewport(sector, viewport.x, viewport.y,
- viewport.width, viewport.height);
+ this.modelview = Matrix.fromGeographicToViewport(sector, viewport.left, viewport.top,
+ viewport.width(), viewport.height());
this.projection = projectionMatrix;
}
@@ -88,7 +87,7 @@ public SurfaceTileDrawContext(Sector sector, Rectangle viewport, Matrix projecti
*/
public SurfaceTileDrawContext(Sector sector, int viewportWidth, int viewportHeight, Matrix projectionMatrix)
{
- this(sector, new Rectangle(viewportWidth, viewportHeight), projectionMatrix);
+ this(sector, new Rect(0, 0, viewportWidth, viewportHeight), projectionMatrix);
}
/**
@@ -106,7 +105,7 @@ public Sector getSector()
*
* @return the context's viewport.
*/
- public Rectangle getViewport()
+ public Rect getViewport()
{
return this.viewport;
}
diff --git a/WorldWindAndroid/src/gov/nasa/worldwind/util/WWIO.java b/WorldWindAndroid/src/gov/nasa/worldwind/util/WWIO.java
index 1950195..0c4ee65 100644
--- a/WorldWindAndroid/src/gov/nasa/worldwind/util/WWIO.java
+++ b/WorldWindAndroid/src/gov/nasa/worldwind/util/WWIO.java
@@ -12,7 +12,6 @@
import gov.nasa.worldwind.exception.WWRuntimeException;
import gov.nasa.worldwind.render.GpuProgram;
-import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.ref.WeakReference;
import java.net.InetSocketAddress;
diff --git a/WorldWindowApplicationSample/AndroidManifest.xml b/WorldWindowApplicationSample/AndroidManifest.xml
index e10e764..8a4421d 100644
--- a/WorldWindowApplicationSample/AndroidManifest.xml
+++ b/WorldWindowApplicationSample/AndroidManifest.xml
@@ -5,21 +5,15 @@
All Rights Reserved.
$Id: AndroidManifest.xml 59 2011-09-20 18:41:08Z dcollins $
--->
-
+-->
-
+
-
+
-
-
-
+
+
+
-
+
-
-
+
+
diff --git a/WorldWindowApplicationSample/pom.xml b/WorldWindowApplicationSample/pom.xml
index a13c8bd..33f3020 100644
--- a/WorldWindowApplicationSample/pom.xml
+++ b/WorldWindowApplicationSample/pom.xml
@@ -36,7 +36,7 @@
android
android
- 4.4_r1
+ 4.4.2_r3
provided
@@ -45,6 +45,11 @@
+
+ android.support
+ compatibility-v4
+ 19.0.1
+
com.github.trilogisit.worldwindandroid
library
@@ -67,4 +72,11 @@
+
+
+
+ third.party.closed.source.repo
+ file://${basedir}/../maven_repo_3rd_party
+
+
diff --git a/WorldWindowApplicationSample/res/drawable-hdpi/drawer_shadow.9.png b/WorldWindowApplicationSample/res/drawable-hdpi/drawer_shadow.9.png
new file mode 100644
index 0000000..236bff5
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-hdpi/drawer_shadow.9.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-hdpi/ic_action_new.png b/WorldWindowApplicationSample/res/drawable-hdpi/ic_action_new.png
new file mode 100644
index 0000000..3a525cd
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-hdpi/ic_action_new.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-hdpi/ic_action_settings.png b/WorldWindowApplicationSample/res/drawable-hdpi/ic_action_settings.png
new file mode 100644
index 0000000..0eb78f7
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-hdpi/ic_action_settings.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-hdpi/ic_drawer.png b/WorldWindowApplicationSample/res/drawable-hdpi/ic_drawer.png
new file mode 100644
index 0000000..c59f601
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-hdpi/ic_drawer.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-mdpi/drawer_shadow.9.png b/WorldWindowApplicationSample/res/drawable-mdpi/drawer_shadow.9.png
new file mode 100644
index 0000000..ffe3a28
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-mdpi/drawer_shadow.9.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-mdpi/ic_action_new.png b/WorldWindowApplicationSample/res/drawable-mdpi/ic_action_new.png
new file mode 100644
index 0000000..da506ca
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-mdpi/ic_action_new.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-mdpi/ic_action_settings.png b/WorldWindowApplicationSample/res/drawable-mdpi/ic_action_settings.png
new file mode 100644
index 0000000..c290e59
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-mdpi/ic_action_settings.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-mdpi/ic_drawer.png b/WorldWindowApplicationSample/res/drawable-mdpi/ic_drawer.png
new file mode 100644
index 0000000..1ed2c56
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-mdpi/ic_drawer.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-xhdpi/drawer_shadow.9.png b/WorldWindowApplicationSample/res/drawable-xhdpi/drawer_shadow.9.png
new file mode 100644
index 0000000..fabe9d9
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-xhdpi/drawer_shadow.9.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-xhdpi/ic_action_new.png b/WorldWindowApplicationSample/res/drawable-xhdpi/ic_action_new.png
new file mode 100644
index 0000000..6038bee
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-xhdpi/ic_action_new.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-xhdpi/ic_action_settings.png b/WorldWindowApplicationSample/res/drawable-xhdpi/ic_action_settings.png
new file mode 100644
index 0000000..999d0f0
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-xhdpi/ic_action_settings.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-xhdpi/ic_drawer.png b/WorldWindowApplicationSample/res/drawable-xhdpi/ic_drawer.png
new file mode 100644
index 0000000..a5fa74d
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-xhdpi/ic_drawer.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-xxhdpi/drawer_shadow.9.png b/WorldWindowApplicationSample/res/drawable-xxhdpi/drawer_shadow.9.png
new file mode 100644
index 0000000..b91e9d7
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-xxhdpi/drawer_shadow.9.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-xxhdpi/ic_action_new.png b/WorldWindowApplicationSample/res/drawable-xxhdpi/ic_action_new.png
new file mode 100644
index 0000000..c0cd3d9
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-xxhdpi/ic_action_new.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-xxhdpi/ic_action_settings.png b/WorldWindowApplicationSample/res/drawable-xxhdpi/ic_action_settings.png
new file mode 100644
index 0000000..530227e
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-xxhdpi/ic_action_settings.png differ
diff --git a/WorldWindowApplicationSample/res/drawable-xxhdpi/ic_drawer.png b/WorldWindowApplicationSample/res/drawable-xxhdpi/ic_drawer.png
new file mode 100644
index 0000000..9c4685d
Binary files /dev/null and b/WorldWindowApplicationSample/res/drawable-xxhdpi/ic_drawer.png differ
diff --git a/WorldWindowApplicationSample/res/layout/main.xml b/WorldWindowApplicationSample/res/layout/main.xml
index 2b07347..bede6bc 100644
--- a/WorldWindowApplicationSample/res/layout/main.xml
+++ b/WorldWindowApplicationSample/res/layout/main.xml
@@ -1,70 +1,52 @@
-
+
-
-
-
-
+ android:layout_height="match_parent">
-
-
-
-
-
+ android:layout_height="24dp"
+ android:layout_alignParentBottom="true"
+ android:background="@android:color/background_light"/>
-
-
-
+
+
+
+
+
+
+
-
+
-
+
-
-
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/WorldWindowApplicationSample/res/layout/toc_view_dialog.xml b/WorldWindowApplicationSample/res/layout/toc_view_dialog.xml
index 5558ce8..8639706 100644
--- a/WorldWindowApplicationSample/res/layout/toc_view_dialog.xml
+++ b/WorldWindowApplicationSample/res/layout/toc_view_dialog.xml
@@ -1,15 +1,15 @@
-
+ android:layout_height="match_parent"
+ android:orientation="vertical">
-
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/WorldWindowApplicationSample/res/menu/options.xml b/WorldWindowApplicationSample/res/menu/options.xml
index ad74eaf..d33b11b 100644
--- a/WorldWindowApplicationSample/res/menu/options.xml
+++ b/WorldWindowApplicationSample/res/menu/options.xml
@@ -6,14 +6,24 @@
-->
\ No newline at end of file
diff --git a/WorldWindowApplicationSample/res/values/strings.xml b/WorldWindowApplicationSample/res/values/strings.xml
index 2440a7b..f6cbe31 100644
--- a/WorldWindowApplicationSample/res/values/strings.xml
+++ b/WorldWindowApplicationSample/res/values/strings.xml
@@ -7,8 +7,8 @@
$Id: strings.xml 83 2011-10-06 15:37:57Z ccrick $
-->
- WorldDroid³
- WorldDroid³
+ WorldWind Sample
+ WorldWind Sample
Dashboard
Latitude:
Longitude:
@@ -23,4 +23,7 @@
…
Drag Item
Delete Layer
+
+ Open TOC Drawer
+ Close TOC Drawer
diff --git a/WorldWindowApplicationSample/res/xml/debug_preferences.xml b/WorldWindowApplicationSample/res/xml/debug_preferences.xml
new file mode 100644
index 0000000..bef416d
--- /dev/null
+++ b/WorldWindowApplicationSample/res/xml/debug_preferences.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/WorldWindowApplicationSample/res/xml/performance_preferences.xml b/WorldWindowApplicationSample/res/xml/performance_preferences.xml
new file mode 100644
index 0000000..29b5881
--- /dev/null
+++ b/WorldWindowApplicationSample/res/xml/performance_preferences.xml
@@ -0,0 +1,36 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/WorldWindowApplicationSample/res/xml/preference_headers.xml b/WorldWindowApplicationSample/res/xml/preference_headers.xml
new file mode 100644
index 0000000..e91dc0e
--- /dev/null
+++ b/WorldWindowApplicationSample/res/xml/preference_headers.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/WorldWindowApplicationSample/sample.iml b/WorldWindowApplicationSample/sample.iml
index 8ba7991..b8ca09f 100644
--- a/WorldWindowApplicationSample/sample.iml
+++ b/WorldWindowApplicationSample/sample.iml
@@ -26,10 +26,14 @@
+
+
+
+
diff --git a/WorldWindowApplicationSample/src/config/Earth/Compound.xml b/WorldWindowApplicationSample/src/config/Earth/Compound.xml
new file mode 100644
index 0000000..0c108db
--- /dev/null
+++ b/WorldWindowApplicationSample/src/config/Earth/Compound.xml
@@ -0,0 +1,142 @@
+
+
+
+
+
+ Earth Elevation Model (USA 10m, WordWide 30m, Ocean 900m)
+
+ http://data.worldwind.arc.nasa.gov/elev
+ http://data.worldwind.arc.nasa.gov/elev
+ mergedAsterElevations
+
+ true
+
+ 17 12 2009 01:01:01 GMT
+ Earth/EarthElevationModel.bil16
+ application/bil16
+
+ 0.20
+ .bil
+
+ config/SRTM30Plus_ExtremeElevations_5.bil
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Scankort Denmark DSM
+
+ http://data.worldwind.arc.nasa.gov/elev
+ http://data.worldwind.arc.nasa.gov/elev
+ ScankortElevationsDenmarkDSM
+
+
+ 25 06 2009 22:45:32 GMT
+ Earth/ScankortElevationsDenmarkDSM
+ application/bil32
+
+ .bil
+
+ 0.30
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/WorldWindowApplicationSample/src/config/etc1/BMNGWMSLayer.xml b/WorldWindowApplicationSample/src/config/etc1/BMNGWMSLayer.xml
new file mode 100644
index 0000000..a4ed1d4
--- /dev/null
+++ b/WorldWindowApplicationSample/src/config/etc1/BMNGWMSLayer.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+ Blue Marble (WMS) 2004
+
+ http://data.worldwind.arc.nasa.gov/wms
+ http://data.worldwind.arc.nasa.gov/wms
+ bmng200405
+
+
+ 26 03 2009 00:00:00 GMT
+ Earth/BMNGWMS/BMNG(Shaded + Bathymetry) Tiled - Version 1.1 - 5.2004
+ image/png
+
+ image/png
+
+
+ image/pkm
+ .pkm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2
+ 1000
+
diff --git a/WorldWindowApplicationSample/src/config/etc1/LandsatI3WMSLayer.xml b/WorldWindowApplicationSample/src/config/etc1/LandsatI3WMSLayer.xml
new file mode 100644
index 0000000..150d4c8
--- /dev/null
+++ b/WorldWindowApplicationSample/src/config/etc1/LandsatI3WMSLayer.xml
@@ -0,0 +1,53 @@
+
+
+
+
+
+ i-cubed Landsat
+
+ http://data.worldwind.arc.nasa.gov/wms
+ http://data.worldwind.arc.nasa.gov/wms
+ esat
+
+
+ 26 03 2009 00:00:00 GMT
+ Earth/NASA LandSat I3 WMS
+ image/png
+
+ image/png
+
+
+ image/pkm
+ .pkm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/WorldWindowApplicationSample/src/config/etc1/ScankortDenmarkImageLayer.xml b/WorldWindowApplicationSample/src/config/etc1/ScankortDenmarkImageLayer.xml
new file mode 100644
index 0000000..b317079
--- /dev/null
+++ b/WorldWindowApplicationSample/src/config/etc1/ScankortDenmarkImageLayer.xml
@@ -0,0 +1,52 @@
+
+
+
+
+
+ Scankort Denmark
+
+ http://data.worldwind.arc.nasa.gov/wms
+ http://data.worldwind.arc.nasa.gov/wms
+ Scankort
+
+
+ 25 06 2009 22:45:32 GMT
+ Earth/Scankort Denmark
+ image/png
+
+ image/png
+ image/dds
+
+ image/pkm
+ .pkm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+ false
+ false
+
+
+
+
+
+
\ No newline at end of file
diff --git a/WorldWindowApplicationSample/src/config/sample.xml b/WorldWindowApplicationSample/src/config/sample.xml
new file mode 100644
index 0000000..c929e11
--- /dev/null
+++ b/WorldWindowApplicationSample/src/config/sample.xml
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WorldWindowApplicationSample/src/config/worldwind.layers2.xml b/WorldWindowApplicationSample/src/config/worldwind.layers2.xml
index 9f86812..eb63e17 100644
--- a/WorldWindowApplicationSample/src/config/worldwind.layers2.xml
+++ b/WorldWindowApplicationSample/src/config/worldwind.layers2.xml
@@ -7,30 +7,32 @@
-
+ title="Sky"/>
+
+ value="3e5"/>
+ actuate="onRequest"
+ href="config/etc1/BMNGWMSLayer.xml"/>
-
+ actuate="onRequest"
+ href="config/etc1/LandsatI3WMSLayer.xml"/>
+
+
+
+ title="World Map"/>
+ title="Compass"/>
+ title="Scale Bar"/>
\ No newline at end of file
diff --git a/WorldWindowApplicationSample/src/it/trilogis/android/ww/CustomBox.java b/WorldWindowApplicationSample/src/it/trilogis/android/ww/CustomBox.java
deleted file mode 100644
index adabae0..0000000
--- a/WorldWindowApplicationSample/src/it/trilogis/android/ww/CustomBox.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * Copyright (C) 2014 United States Government as represented by the Administrator of the
- * National Aeronautics and Space Administration.
- * All Rights Reserved.
- */
-
-package it.trilogis.android.ww;
-
-import android.graphics.Point;
-import android.opengl.GLES20;
-import gov.nasa.worldwind.cache.GpuResourceCache;
-import gov.nasa.worldwind.geom.*;
-import gov.nasa.worldwind.layers.Layer;
-import gov.nasa.worldwind.pick.PickSupport;
-import gov.nasa.worldwind.render.Color;
-import gov.nasa.worldwind.render.DrawContext;
-import gov.nasa.worldwind.render.GpuProgram;
-import gov.nasa.worldwind.render.OrderedRenderable;
-import gov.nasa.worldwind.util.Logging;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-
-/**
- * Created by kedzie on 3/20/14.
- */
-public class CustomBox implements OrderedRenderable {
- protected Position position;
- protected float size;
- protected long frameTimestamp;
- protected Vec4 placePoint;
- protected double eyeDistance;
- protected Extent extent;
- protected PickSupport pickSupport = new PickSupport();
-
- protected FloatBuffer vertexBuffer;
- protected FloatBuffer textureBuffer;
- protected FloatBuffer normalBuffer;
- protected FloatBuffer colorBuffer;
- protected IntBuffer indexBuffer;
- Matrix currentMatrix = Matrix.fromIdentity();
- protected final Object programKey = new Object();
- protected boolean programCreationFailed;
- protected Layer pickLayer;
- protected Color currentColor = new Color(1, 0, 0);
-
- public CustomBox(Position position, float sizeInMeters)
- {
- this.position = position;
- this.size = sizeInMeters;
-
- float halfSize = size * .5f;
- float[] vertices = {
- // -- back
- halfSize, halfSize, halfSize, -halfSize, halfSize, halfSize,
- -halfSize, -halfSize, halfSize, halfSize, -halfSize, halfSize, // 0-1-halfSize-3 front
-
- halfSize, halfSize, halfSize, halfSize, -halfSize, halfSize,
- halfSize, -halfSize, -halfSize, halfSize, halfSize, -halfSize,// 0-3-4-5 right
- // -- front
- halfSize, -halfSize, -halfSize, -halfSize, -halfSize, -halfSize,
- -halfSize, halfSize, -halfSize, halfSize, halfSize, -halfSize,// 4-7-6-5 back
-
- -halfSize, halfSize, halfSize, -halfSize, halfSize, -halfSize,
- -halfSize, -halfSize, -halfSize, -halfSize, -halfSize, halfSize,// 1-6-7-halfSize left
-
- halfSize, halfSize, halfSize, halfSize, halfSize, -halfSize,
- -halfSize, halfSize, -halfSize, -halfSize, halfSize, halfSize, // top
-
- halfSize, -halfSize, halfSize, -halfSize, -halfSize, halfSize,
- -halfSize, -halfSize, -halfSize, halfSize, -halfSize, -halfSize,// bottom
- };
-
- float[] textureCoords = new float[]
- {
- 0, 1, 1, 1, 1, 0, 0, 0, // front
- 0, 1, 1, 1, 1, 0, 0, 0, // up
- 0, 1, 1, 1, 1, 0, 0, 0, // back
- 0, 1, 1, 1, 1, 0, 0, 0, // down
- 0, 1, 1, 1, 1, 0, 0, 0, // right
- 0, 1, 1, 1, 1, 0, 0, 0, // left
- };
-
- float[] colors = new float[] {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
- };
-
- float n = 1;
-
- float[] normals = {
- 0, 0, n, 0, 0, n, 0, 0, n, 0, 0, n, // front
- n, 0, 0, n, 0, 0, n, 0, 0, n, 0, 0, // right
- 0, 0, -n, 0, 0, -n, 0, 0, -n, 0, 0, -n, // back
- -n, 0, 0, -n, 0, 0, -n, 0, 0, -n, 0, 0, // left
- 0, n, 0, 0, n, 0, 0, n, 0, 0, n, 0, // top
- 0, -n, 0, 0, -n, 0, 0, -n, 0, 0, -n, 0, // bottom
- };
-
- int[] indices = {
- 0, 1, 2, 0, 2, 3,
- 4, 5, 6, 4, 6, 7,
- 8, 9, 10, 8, 10, 11,
- 12, 13, 14, 12, 14, 15,
- 16, 17, 18, 16, 18, 19,
- 20, 21, 22, 20, 22, 23,
- };
-
- vertexBuffer = ByteBuffer.allocateDirect(vertices.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
- vertexBuffer.put(vertices).position(0);
- normalBuffer = ByteBuffer.allocateDirect(normals.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
- normalBuffer.put(normals).position(0);
- textureBuffer = ByteBuffer.allocateDirect(textureCoords.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
- textureBuffer.put(textureCoords).position(0);
- colorBuffer = ByteBuffer.allocateDirect(colors.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
- colorBuffer.put(colors).position(0);
- indexBuffer = ByteBuffer.allocateDirect(indices.length*4).order(ByteOrder.nativeOrder()).asIntBuffer();
- indexBuffer.put(indices).position(0);
- }
-
- protected void beginDrawing(DrawContext dc)
- {
- GpuProgram program = this.getDefaultGpuProgram(dc.getGpuResourceCache());
- if (program == null) return; // Message already logged in getDefaultGpuProgram.
-
- // Bind this shape's gpu program as the current OpenGL program.
- dc.setCurrentProgram(program);
- program.bind();
-
- // Enable the gpu program's vertexPoint attribute, if one exists. The data for this attribute is specified by
- // each shape.
- int attribLocation = program.getAttribLocation("vertexPoint");
- if (attribLocation >= 0) GLES20.glEnableVertexAttribArray(attribLocation);
-
- // Set the OpenGL state that this shape depends on.
- GLES20.glDisable(GLES20.GL_CULL_FACE);
-
- Matrix transform = Matrix.fromTranslation(dc.getGlobe().computePointFromPosition(
- position.latitude, position.longitude, position.elevation*dc.getVerticalExaggeration()));
- transform = transform.multiply(Matrix.fromRotationY(position.longitude));
- // Rotate the coordinate system to match the latitude.
- // Latitude is treated clockwise as rotation about the X-axis. We flip the latitude value so that a positive
- // rotation produces a clockwise rotation (when facing the axis).
- transform = transform.multiply(Matrix.fromRotationX(position.latitude.multiply(-1.0)));
- currentMatrix.multiplyAndSet(dc.getView().getModelviewProjectionMatrix(), transform);
- dc.getCurrentProgram().loadUniformMatrix("mvpMatrix", this.currentMatrix);
- }
-
- protected void endDrawing(DrawContext dc)
- {
- GpuProgram program = dc.getCurrentProgram();
- if (program == null) return; // Message already logged in getDefaultGpuProgram via beginDrawing.
-
- // Disable the program's vertexPoint attribute, if one exists. This restores the program state modified in
- // beginRendering. This must be done while the program is still bound, because getAttribLocation depends on
- // the current OpenGL program state.
- int location = program.getAttribLocation("vertexPoint");
- if (location >= 0) GLES20.glDisableVertexAttribArray(location);
-
- // Restore the previous OpenGL program state.
- dc.setCurrentProgram(null);
- GLES20.glUseProgram(0);
-
- // Restore the OpenGL array and element array buffer bindings to 0.
- GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
- GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
-
- // Restore the remaining OpenGL state values to their defaults.
- GLES20.glEnable(GLES20.GL_CULL_FACE);
- GLES20.glDepthMask(true);
- GLES20.glLineWidth(1f);
- }
-
- protected void drawUnitCube(DrawContext dc)
- {
- int maPositionHandle = dc.getCurrentProgram().getAttribLocation("vertexPoint");
- GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false,
- 4*3, vertexBuffer.rewind());
- GLES20.glDrawElements(GLES20.GL_TRIANGLES, indexBuffer.capacity(), GLES20.GL_UNSIGNED_INT, indexBuffer.rewind());
- }
-
- // From OrderedRenderable
- public void pick(DrawContext dc, Point pickPoint)
- {
- try {
- this.render(dc);
- } finally {
- this.pickSupport.resolvePick(dc, pickPoint, this.pickLayer);
- }
- }
-
- // From OrderedRenderable
- public double getDistanceFromEye()
- {
- return this.eyeDistance;
- }
-
- protected boolean intersectsFrustum(DrawContext dc)
- {
- if (this.extent == null)
- return true; // don't know the visibility, shape hasn't been computed yet
-
-// if (dc.isPickingMode())
-// return dc.getPickFrustums().intersectsAny(this.extent);
-
- return dc.getView().getFrustumInModelCoordinates().intersects(this.extent);
- }
-
- // From Renderable
- public void render(DrawContext dc)
- {
- if (this.extent != null)
- {
- if (!this.intersectsFrustum(dc)) {
- Logging.warning("!intersectFrustum");
- return;
- }
-
- // If the shape is less that a pixel in size, don't render it.
- if (dc.isSmall(this.extent, 1))
- return;
- }
-
- if (dc.isOrderedRenderingMode())
- this.drawOrderedRenderable(dc, this.pickSupport);
- else
- this.makeOrderedRenderable(dc);
- }
-
- protected void makeOrderedRenderable(DrawContext dc)
- {
- // This method is called twice each frame: once during picking and once during
- // rendering. We only need to compute the placePoint and eyedistance once per
- // frame, so check the frame timestamp to see if this is new frame.
- if (dc.getFrameTimeStamp() != this.frameTimestamp)
- {
- this.placePoint = dc.getGlobe().computePointFromPosition(this.position);
- Box box = Box.computeBoundingBox((FloatBuffer) vertexBuffer.rewind(), 3);
- this.extent = box.translate(placePoint);
- this.eyeDistance = dc.getView().getEyePoint().distanceTo3(this.placePoint);
-
- this.frameTimestamp = dc.getFrameTimeStamp();
- }
- if (dc.isPickingMode()) this.pickLayer = dc.getCurrentLayer();
- // Add the cube to the ordered renderable list.
- dc.addOrderedRenderable(this);
- }
-
- protected void drawOrderedRenderable(DrawContext dc, PickSupport pickCandidates)
- {
- this.beginDrawing(dc);
- try
- {
- if (dc.isPickingMode())
- {
- int pickColor = dc.getUniquePickColor();
- pickCandidates.addPickableObject(pickColor, this, this.position);
- dc.getCurrentProgram().loadUniformColor("color", currentColor.set(pickColor, false));
- } else {
- dc.getCurrentProgram().loadUniformColor("color", this.currentColor.set(1, 0, 0));
- }
-
- this.drawUnitCube(dc);
- }
- finally
- {
- this.endDrawing(dc);
- }
- }
-
- protected GpuProgram getDefaultGpuProgram(GpuResourceCache cache) {
- if (this.programCreationFailed) return null;
-
- GpuProgram program = cache.getProgram(this.programKey);
-
- if (program == null) {
- try {
- GpuProgram.GpuProgramSource source = GpuProgram.readProgramSource(R.raw.abstractshapevert, R.raw.abstractshapefrag);
- program = new GpuProgram(source);
- cache.put(this.programKey, program);
- } catch (Exception e) {
- String msg = Logging.getMessage("GL.ExceptionLoadingProgram", R.raw.abstractshapevert, R.raw.abstractshapefrag);
- Logging.error(msg);
- this.programCreationFailed = true;
- }
- }
-
- return program;
- }
-
-}
\ No newline at end of file
diff --git a/WorldWindowApplicationSample/src/it/trilogis/android/ww/WorldWindowActivity.java b/WorldWindowApplicationSample/src/it/trilogis/android/ww/WorldWindowActivity.java
index 010c131..5ea4dd0 100644
--- a/WorldWindowApplicationSample/src/it/trilogis/android/ww/WorldWindowActivity.java
+++ b/WorldWindowApplicationSample/src/it/trilogis/android/ww/WorldWindowActivity.java
@@ -1,279 +1,387 @@
/*
- * Copyright (C) 2013 Trilogis S.r.l.
- *
- * 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.
+ * Copyright (C) 2014 United States Government as represented by the Administrator of the
+ * National Aeronautics and Space Administration.
+ * All Rights Reserved.
*/
+
package it.trilogis.android.ww;
-import android.opengl.GLSurfaceView;
+import android.animation.AnimatorSet;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.preference.PreferenceManager;
+import android.support.v4.app.ActionBarDrawerToggle;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.widget.DrawerLayout;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.widget.TextView;
+import android.widget.Toast;
import gov.nasa.worldwind.*;
import gov.nasa.worldwind.avlist.AVKey;
import gov.nasa.worldwind.geom.Angle;
+import gov.nasa.worldwind.geom.LatLon;
import gov.nasa.worldwind.geom.Position;
-import gov.nasa.worldwind.globes.Globe;
-import gov.nasa.worldwind.layers.CompassLayer;
-import gov.nasa.worldwind.layers.Layer;
-import gov.nasa.worldwind.layers.LayerList;
-import gov.nasa.worldwind.layers.RenderableLayer;
-import gov.nasa.worldwind.render.Path;
+import gov.nasa.worldwind.layers.*;
+import gov.nasa.worldwind.render.*;
+import gov.nasa.worldwind.terrain.ElevationModel;
+import gov.nasa.worldwind.terrain.ZeroElevationModel;
import gov.nasa.worldwind.util.Logging;
+import gov.nasa.worldwind.util.PerformanceStatistic;
+import gov.nasa.worldwind.util.StatusBar;
import gov.nasa.worldwind.util.WWIO;
import it.trilogis.android.ww.dialogs.AddWMSDialog;
import it.trilogis.android.ww.dialogs.AddWMSDialog.OnAddWMSLayersListener;
-import it.trilogis.android.ww.dialogs.TocDialog;
+import it.trilogis.android.ww.dialogs.TocFragment;
+import it.trilogis.android.ww.view.SettingsActivity;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.*;
-import android.app.Activity;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.widget.TextView;
+import static it.trilogis.android.ww.view.SettingsActivity.*;
/**
* @author Nicola Dorigatti
*/
public class WorldWindowActivity extends Activity {
- static {
- System.setProperty("gov.nasa.worldwind.app.config.document", "config/wwandroiddemo.xml");
- }
-
- private static final String TAG = "TrilogisWWExample";
-
- // This parameters are useful for WMS Addition and view.
- // Thanks to the Autonomous Province of Bolzano (Italy) for the Open WMS Server.
- // The Use of their WMS Services for commercial and/or support to companies is allowed.
- public final static String DEFAULT_WMS_URL = "http://sdi.provinz.bz.it/geoserver/wms";
- private final static double BOLZANO_LATITUDE = 46.4995d;
- private final static double BOLZANO_LONGITUDE = 11.3254d;
- private final static double BOLZANO_VIEW_HEADING = 60d;
- private final static double BOLZANO_VIEW_TILT = 60d;
- private final static double BOLZANO_VIEW_DISTANCE_KM = 13000d;
-
- public static final int INITIAL_LATITUDE = 40;
- public static final int INITIAL_LONGITUDE = -120;
-
- protected WorldWindowGLSurfaceView wwd;
-
- // private CompassLayer cl;
- // private WorldMapLayer wml;
- // private SkyGradientLayer sgl;
- // private ScalebarLayer sbl;
-
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // Setting the location of the file store on Android as cache directory. Doing this, when user has no space left
- // on the device, if he asks to the system to free Cache of apps, all the MB/GB of WorldWindApplication will be cleared!
- File fileDir = getCacheDir();// getFilesDir();
+ static {
+ System.setProperty("gov.nasa.worldwind.app.config.document", "config/sample.xml");
+ }
+
+ private static final String TAG = "WorldWindowActivity";
+
+ public final static String DEFAULT_WMS_URL = "http://data.worldwind.arc.nasa.gov/wms";
+
+ public static final int INITIAL_LATITUDE = 56;
+ public static final int INITIAL_LONGITUDE = 9;
+
+ protected WorldWindowGLTextureView wwd;
+ private ElevationModel mElevationModel;
+ private BasicView mView;
+ private RenderableLayer layer;
+
+ private TextView mFrameRateText;
+ private DrawerLayout mDrawerLayout;
+ private ActionBarDrawerToggle mDrawerToggle;
+ private TocFragment mTocFragment;
+
+ private boolean mUseElevation;
+
+ private Handler statHandler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ StringBuffer sb = new StringBuffer();
+ Map stats = wwd.getPerFrameStatistics();
+ if(stats!=null) {
+ sb.append(stats.get(PerformanceStatistic.FRAME_RATE));
+ for (PerformanceStatistic stat : stats.values()) {
+ if (stat != null && !stat.getKey().equals(PerformanceStatistic.FRAME_RATE))
+ sb.append('\n').append(stat);
+ }
+ }
+ sb.append(String.format("\nVertical Exaggeration: %.2f", wwd.getSceneController().getVerticalExaggeration()));
+ mFrameRateText.setText(sb.toString());
+ }
+ };
+
+ /**
+ * Called when the activity is first created.
+ */
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ PreferenceManager.setDefaultValues(this, R.xml.debug_preferences, false);
+ PreferenceManager.setDefaultValues(this, R.xml.performance_preferences, false);
+
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+ getActionBar().setDisplayShowHomeEnabled(true);
+ getActionBar().setHomeButtonEnabled(true);
+
+ // Setting the location of the file store on Android as cache directory. Doing this, when user has no space left
+ // on the device, if he asks to the system to free Cache of apps, all the MB/GB of WorldWindApplication will be cleared!
+ File fileDir = getCacheDir();// getFilesDir();
Logging.info("Application cache directory: " + fileDir);
if (null != fileDir && fileDir.exists() && fileDir.canWrite()) {
- File output = new File(fileDir, ".nomedia");
- if (!output.exists()) {
- try {
- output.createNewFile();
- } catch (IOException e) {
- Log.e(TAG, "IOException while creating .nomedia: " + e.getMessage());
- }
- }
- }
- System.setProperty("gov.nasa.worldwind.platform.user.store", fileDir.getAbsolutePath());
+ File output = new File(fileDir, ".nomedia");
+ if (!output.exists()) {
+ try {
+ output.createNewFile();
+ } catch (IOException e) {
+ Log.e(TAG, "IOException while creating .nomedia: " + e.getMessage());
+ }
+ }
+ }
+ System.setProperty("gov.nasa.worldwind.platform.user.store", fileDir.getAbsolutePath());
- WWIO.setContext(this);
+ WWIO.setContext(this);
- setContentView(R.layout.main);
+ setContentView(R.layout.main);
- wwd = (WorldWindowGLSurfaceView) findViewById(R.id.wwd);
- wwd.setDebugFlags(GLSurfaceView.DEBUG_CHECK_GL_ERROR);
+ mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
+ mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
+ mDrawerToggle = new ActionBarDrawerToggle( this, mDrawerLayout, R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close );
+
+ wwd = (WorldWindowGLTextureView) findViewById(R.id.wwd);
+ wwd.setFrameRate(60);
+ Set keys = new HashSet();
+ keys.add(PerformanceStatistic.ALL);
+ wwd.setPerFrameStatisticsKeys(keys);
+
+ mTocFragment = (TocFragment) getFragmentManager().findFragmentById(R.id.tocFragment);
+
+ wwd.addPropertyChangeListener(PerformanceStatistic.FRAME_RATE, new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ statHandler.obtainMessage(0, event.getNewValue()).sendToTarget();
+ }
+ });
wwd.setModel((Model) WorldWind.createConfigurationComponent(AVKey.MODEL_CLASS_NAME));
- wwd.setLatitudeText((TextView) findViewById(R.id.latvalue));
- wwd.setLongitudeText((TextView) findViewById(R.id.lonvalue));
+ mElevationModel = wwd.getModel().getGlobe().getElevationModel();
+
+ StatusBar statusBar = (StatusBar) findViewById(R.id.statusBar);
+ statusBar.setEventSource(wwd);
+
+ mFrameRateText = (TextView) findViewById(R.id.perframeStatText);
+ mFrameRateText.bringToFront();
- BasicView view = (BasicView) wwd.getView();
- Globe globe = wwd.getModel().getGlobe();
+ mView = (BasicView) wwd.getView();
- view.setLookAtPosition(Position.fromDegrees(INITIAL_LATITUDE, INITIAL_LONGITUDE,
- globe.getElevation(Angle.fromDegrees(INITIAL_LATITUDE), Angle.fromDegrees(INITIAL_LONGITUDE))));
-// view.setHeading(Angle.fromDegrees(BOLZANO_VIEW_HEADING));
- view.setTilt(Angle.fromDegrees(45));
- view.setRange(7000);
+ mView.setLookAtPosition(Position.fromDegrees(INITIAL_LATITUDE, INITIAL_LONGITUDE, 0));
+ mView.setRange(100);
- RenderableLayer layer = new RenderableLayer();
+ layer = new RenderableLayer();
layer.setName("Renderable");
- CustomBox box = new CustomBox(Position.fromDegrees(INITIAL_LATITUDE, INITIAL_LONGITUDE,
- globe.getElevation(Angle.fromDegrees(INITIAL_LATITUDE), Angle.fromDegrees(INITIAL_LONGITUDE))), 2000);
- layer.addRenderable(box);
+
+ SurfaceQuad quad = new SurfaceQuad(LatLon.fromDegrees(INITIAL_LATITUDE, INITIAL_LONGITUDE), 20, 20);
+ BasicShapeAttributes quadAttrs = new BasicShapeAttributes();
+ quadAttrs.setEnableInterior(true);
+ quadAttrs.setEnableOutline(true);
+ quadAttrs.setInteriorMaterial(new Material(Color.randomColor()));
+ quadAttrs.setOutlineMaterial(new Material(Color.randomColor()));
+ quadAttrs.setOutlineOpacity(.8f);
+ quadAttrs.setInteriorOpacity(.5f);
+ quadAttrs.setOutlineWidth(12f);
+ quad.setAttributes(quadAttrs);
+ layer.addRenderable(quad);
+
+ SurfaceQuad quad2 = new SurfaceQuad(LatLon.fromDegrees(INITIAL_LATITUDE+.0004, INITIAL_LONGITUDE+.0004), 25, 30);
+ BasicShapeAttributes quad2Attrs = new BasicShapeAttributes();
+ quad2Attrs.setEnableInterior(true);
+ quad2Attrs.setEnableOutline(true);
+ quad2Attrs.setInteriorMaterial(new Material(Color.randomColor()));
+ quad2Attrs.setOutlineMaterial(new Material(Color.randomColor()));
+ quad2Attrs.setOutlineOpacity(.8f);
+ quad2Attrs.setInteriorOpacity(.4f);
+ quad2Attrs.setOutlineWidth(12f);
+ quad2.setAttributes(quad2Attrs);
+ layer.addRenderable(quad2);
+
+ ArrayList positions = new ArrayList(5);
+ final float radius = .001f;
+ final int pathHeight = 5;
+ positions.add(Position.fromDegrees(INITIAL_LATITUDE + radius, INITIAL_LONGITUDE + radius, pathHeight));
+ positions.add(Position.fromDegrees(INITIAL_LATITUDE + radius, INITIAL_LONGITUDE - radius, pathHeight));
+ positions.add(Position.fromDegrees(INITIAL_LATITUDE - radius, INITIAL_LONGITUDE - radius, pathHeight));
+ positions.add(Position.fromDegrees(INITIAL_LATITUDE - radius, INITIAL_LONGITUDE + radius, pathHeight));
+ positions.add(Position.fromDegrees(INITIAL_LATITUDE + radius, INITIAL_LONGITUDE + radius, pathHeight));
Path field = new Path();
- ArrayList positions = new ArrayList();
- positions.add(Position.fromDegrees(INITIAL_LATITUDE+1, INITIAL_LONGITUDE+1));
- positions.add(Position.fromDegrees(INITIAL_LATITUDE+1, INITIAL_LONGITUDE-1));
- positions.add(Position.fromDegrees(INITIAL_LATITUDE-1, INITIAL_LONGITUDE-1));
- positions.add(Position.fromDegrees(INITIAL_LATITUDE-1, INITIAL_LONGITUDE+1));
- field.setPositions(positions);
- field.setExtrude(true);
+ field.setTerrainConformance(10f);
+ field.setAltitudeMode(AVKey.CLAMP_TO_GROUND);
field.setFollowTerrain(true);
- field.setDrawVerticals(true);
- field.setShowPositions(true);
+ field.setPathType(AVKey.GREAT_CIRCLE);
+ field.setPositions(positions);
+ field.setExtrude(false);
+ field.setDrawVerticals(false);
+ field.setShowPositions(false);
+ field.setShowPositionsScale(4d);
+ field.setPositionColors(new Path.PositionColors() {
+ @Override
+ public Color getColor(Position position, int ordinal) {
+ return Color.randomColor();
+ }
+ });
+
+ BasicShapeAttributes attrs = new BasicShapeAttributes();
+ attrs.setEnableInterior(false);
+ attrs.setEnableOutline(true);
+ attrs.setOutlineWidth(6f);
+ field.setAttributes(attrs);
layer.addRenderable(field);
- insertBeforeCompass(wwd, layer);
- }
+ layer.addRenderable(field);
+
+ insertBeforeLayer(CompassLayer.class, layer);
+
+ wwd.getSceneController().addPropertyChangeListener(AVKey.VERTICAL_EXAGGERATION, new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ Logging.info(String.format("Vertical Exaggeration: %.2f->%.2f", event.getOldValue(), event.getNewValue()));
+ statHandler.sendEmptyMessage(0);
+ if(mUseElevation && event.getNewValue().equals(Double.valueOf(0))) {
+ Logging.info("Using Zero elevation model");
+ wwd.getModel().getGlobe().setElevationModel(new ZeroElevationModel());
+ } else if(mUseElevation && event.getOldValue().equals(Double.valueOf(0))) {
+ Logging.info("Using normal elevation model");
+ wwd.getModel().getGlobe().setElevationModel(mElevationModel);
+ }
+ }
+ });
- public static void insertBeforeCompass(WorldWindow wwd, Layer layer)
- {
+ updatePreferences();
+ mTocFragment.setWorldWindData(wwd);
+ }
+
+ public void insertBeforeLayer(Class extends Layer> target, Layer layer) {
// Insert the layer into the layer list just before the compass.
- int compassPosition = 0;
LayerList layers = wwd.getModel().getLayers();
- for (Layer l : layers)
- {
- if (l instanceof CompassLayer)
- compassPosition = layers.indexOf(l);
+ int targetPosition = layers.indexOf(searchSpecificLayer(target));
+ layers.add(targetPosition, layer);
+ }
+
+ private T searchSpecificLayer(Class classToSearch) {
+ for (Layer lyr : wwd.getModel().getLayers()) {
+ if (classToSearch.isInstance(lyr))
+ return classToSearch.cast(lyr);
}
- layers.add(compassPosition, layer);
+ return null;
+ }
+
+ @Override
+ protected void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+ // Sync the toggle state after onRestoreInstanceState has occurred.
+ mDrawerToggle.syncState();
+ }
+
+ @Override
+ public void onConfigurationChanged(android.content.res.Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ // Pass any configuration change to the drawer toggls
+ mDrawerToggle.onConfigurationChanged(newConfig);
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ wwd.onPause();
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ wwd.onResume();
+ }
+
+ @Override
+ protected void onDestroy() {
+ wwd.onSurfaceDestroyed();
+ super.onDestroy();
}
- @Override
- protected void onPause() {
- super.onPause();
- wwd.onPause();
- }
-
- @Override
- protected void onResume() {
- super.onResume();
- wwd.onResume();
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.options, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- // case R.id.menu_toggle_compass:
- // if (null == cl) {
- // cl = searchSpecificLayer(CompassLayer.class);
- // }
- // if (null == cl) {
- // cl = new CompassLayer();
- // cl.setName("Compass");
- // if (this.wwd.getModel().getLayers().add(cl)) Log.d(TAG, "CompassLayer created from scratch and added!!");
- // } else {
- // if (this.wwd.getModel().getLayers().contains(cl)) {
- // cl.setEnabled(!cl.isEnabled());
- // // this.wwd.getModel().getLayers().remove(cl);
- // Log.d(TAG, "CompassLayer Removed!!");
- // } else {
- // this.wwd.getModel().getLayers().addIfAbsent(cl);
- // cl.setEnabled(true);
- // Log.d(TAG, "CompassLayer not created but added!!");
- // }
- // }
- // break;
- // case R.id.menu_toggle_worldmap:
- // if (null == wml) {
- // wml = searchSpecificLayer(WorldMapLayer.class);
- // }
- // if (null == wml) {
- // wml = new WorldMapLayer();
- // wml.setName("WorldMap");
- // if (this.wwd.getModel().getLayers().add(wml)) Log.d(TAG, "WorldMapLayer created from scratch and added!");
- // } else {
- // if (this.wwd.getModel().getLayers().contains(wml)) {
- // wml.setEnabled(!wml.isEnabled());
- // Log.d(TAG, "WorldMapLayer Removed!!");
- // } else {
- // this.wwd.getModel().getLayers().addIfAbsent(wml);
- // wml.setEnabled(true);
- // Log.d(TAG, "WorldMapLayer not created but added!!");
- // }
- // }
- // break;
- // case R.id.menu_toggle_sky:
- // if (null == sgl) {
- // sgl = searchSpecificLayer(SkyGradientLayer.class);
- // }
- // if (null == sgl) {
- // sgl = new SkyGradientLayer();
- // sgl.setName("Sky");
- // if (this.wwd.getModel().getLayers().add(sgl)) Log.d(TAG, "SkyGradientLayer created from scratch and added!");
- // } else {
- // if (this.wwd.getModel().getLayers().contains(sgl)) {
- // sgl.setEnabled(!sgl.isEnabled());
- // Log.d(TAG, "SkyGradientLayer Removed!!");
- // } else {
- // this.wwd.getModel().getLayers().addIfAbsent(sgl);
- // sgl.setEnabled(true);
- // Log.d(TAG, "SkyGradientLayer not created but added!!");
- // }
- // }
- // break;
- // case R.id.menu_toggle_scalebar:
- // if (null == sbl) {
- // sbl = searchSpecificLayer(ScalebarLayer.class);
- // }
- // if (null == sbl) {
- // sbl = new ScalebarLayer();
- // sbl.setName("Scale Bar");
- // if (this.wwd.getModel().getLayers().add(sbl)) Log.d(TAG, "ScalebarLayer created from scratch and added!");
- // } else {
- // if (this.wwd.getModel().getLayers().contains(sbl)) {
- // sbl.setEnabled(!sbl.isEnabled());
- // Log.d(TAG, "ScaleBarLayer Removed!!");
- // } else {
- // this.wwd.getModel().getLayers().addIfAbsent(sbl);
- // sbl.setEnabled(true);
- // Log.d(TAG, "ScaleBarLayer not created but added!!");
- // }
- // }
- // break;
- case R.id.menu_add_wms:
- AddWMSDialog wmsLayersDialog = new AddWMSDialog();
- wmsLayersDialog.setOnAddWMSLayersListener(new OnAddWMSLayersListener() {
-
- public void onAddWMSLayers(List layersToAdd) {
- for (Layer lyr : layersToAdd) {
- boolean added = WorldWindowActivity.this.wwd.getModel().getLayers().addIfAbsent(lyr);
- Log.d(TAG, "Layer '" + lyr.getName() + "' " + (added ? "correctly" : "not") + " added to WorldWind!");
- }
- }
- });
- wmsLayersDialog.show(getFragmentManager(), "addWmsLayers");
- return true;
- case R.id.show_layers_toc:
- TocDialog tocDialog = new TocDialog();
- tocDialog.setWorldWindData(wwd);
- tocDialog.show(getFragmentManager(), "tocDialog");
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- @SuppressWarnings({ "unchecked", "unused" })
- private T searchSpecificLayer(Class classToSearch) {
- for (Layer lyr : wwd.getModel().getLayers()) {
- if (classToSearch.isInstance(lyr))
- return (T) lyr;
- }
- return null;
- }
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.options, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (mDrawerToggle.onOptionsItemSelected(item)) {
+ return true;
+ }
+
+ switch (item.getItemId()) {
+ case R.id.menu_add_wms:
+ AddWMSDialog wmsLayersDialog = new AddWMSDialog();
+ wmsLayersDialog.setOnAddWMSLayersListener(new OnAddWMSLayersListener() {
+
+ public void onAddWMSLayers(List layersToAdd) {
+ for (Layer lyr : layersToAdd) {
+ boolean added = WorldWindowActivity.this.wwd.getModel().getLayers().addIfAbsent(lyr);
+ Toast.makeText(WorldWindowActivity.this, "Layer '" + lyr.getName() + "' " + (added ? "correctly" : "not") + " added to WorldWind!", Toast.LENGTH_LONG).show();
+ }
+ }
+ });
+ wmsLayersDialog.show(getFragmentManager(), "addWmsLayers");
+ return true;
+ case R.id.menu_zoom_in:
+ AnimatorSet zoomIn = new AnimatorSet();
+ zoomIn.setDuration(3000);
+ zoomIn.setInterpolator(new AccelerateDecelerateInterpolator());
+ zoomIn.play(mView.createRangeAnimator(wwd, 40d))
+ .before(mView.createTiltAnimator(wwd, Angle.fromDegrees(45)));
+ mView.animate(zoomIn);
+
+ return true;
+ case R.id.menu_zoom_out:
+ AnimatorSet zoomOut = new AnimatorSet().setDuration(3000);
+ zoomOut.setInterpolator(new AccelerateDecelerateInterpolator());
+ zoomOut.play(mView.createRangeAnimator(wwd, 100d))
+ .with(mView.createTiltAnimator(wwd, Angle.fromDegrees(0)));
+ mView.animate(zoomOut);
+
+ return true;
+ case R.id.menu_preferences:
+ startActivityForResult(new Intent(this, SettingsActivity.class), 0);
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ updatePreferences();
+ }
+
+ /**
+ * Update parameters to reflect preferences
+ */
+ private void updatePreferences() {
+ SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
+ WorldWindowImpl.DEBUG = mPrefs.getBoolean(PREF_DEBUG_LOGGING, true);
+ mFrameRateText.setVisibility(mPrefs.getBoolean(PREF_STATS, false) ? android.view.View.VISIBLE : android.view.View.GONE);
+
+ wwd.invokeInRenderingThread(new Runnable() {
+ @Override
+ public void run() {
+ SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(WorldWindowActivity.this);
+ for(Layer l : wwd.getModel().getLayers()) {
+ if(l instanceof TiledImageLayer) {
+ ((TiledImageLayer)l).setDrawTileIDs(mPrefs.getBoolean(PREF_TILE_ID, false));
+ ((TiledImageLayer)l).setDrawBoundingVolumes(mPrefs.getBoolean(PREF_TILE_BOUNDRIES, false));
+ }
+ }
+ wwd.getModel().setShowTessellationBoundingVolumes(mPrefs.getBoolean(PREF_ELEV_TILE_BOUNDRIES, false));
+ wwd.getModel().setShowTessellationTileIds(mPrefs.getBoolean(PREF_ELEV_TILE_ID, false));
+
+ final double verticalExaggeration = Double.valueOf(mPrefs.getString(PREF_VERTICAL_EXAGGERATION, "1"));
+
+ mUseElevation = mPrefs.getBoolean(PREF_ENABLE_ELEVATION, true);
+
+ wwd.getSceneController().setVerticalExaggeration(verticalExaggeration);
+
+ if(!mUseElevation) {
+ wwd.getModel().getGlobe().setElevationModel(new ZeroElevationModel());
+ } else {
+ wwd.getModel().getGlobe().setElevationModel(mElevationModel);
+ }
+ mView.setFarDistanceMultiplier(Float.valueOf(mPrefs.getString(PREF_HORIZON_MULTIPLIER, "1")));
+ mView.setDetectCollisions(mPrefs.getBoolean(PREF_COLLISION_DETECTION, false));
+ }
+ });
+ wwd.requestRender();
+ }
}
diff --git a/WorldWindowApplicationSample/src/it/trilogis/android/ww/dialogs/AddWMSDialog.java b/WorldWindowApplicationSample/src/it/trilogis/android/ww/dialogs/AddWMSDialog.java
index 695c776..c99d5d8 100644
--- a/WorldWindowApplicationSample/src/it/trilogis/android/ww/dialogs/AddWMSDialog.java
+++ b/WorldWindowApplicationSample/src/it/trilogis/android/ww/dialogs/AddWMSDialog.java
@@ -1,336 +1,336 @@
-/*
- * Copyright (C) 2013 Trilogis S.r.l.
- *
- * 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 it.trilogis.android.ww.dialogs;
-
-import gov.nasa.worldwind.Factory;
-import gov.nasa.worldwind.WorldWind;
-import gov.nasa.worldwind.avlist.AVKey;
-import gov.nasa.worldwind.avlist.AVList;
-import gov.nasa.worldwind.avlist.AVListImpl;
-import gov.nasa.worldwind.layers.Layer;
-import gov.nasa.worldwind.ogc.wms.WMSCapabilities;
-import gov.nasa.worldwind.ogc.wms.WMSLayerCapabilities;
-import gov.nasa.worldwind.ogc.wms.WMSLayerStyle;
-import gov.nasa.worldwind.util.WWUtil;
-import it.trilogis.android.ww.R;
-import it.trilogis.android.ww.WorldWindowActivity;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.WindowManager;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.EditText;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.Toast;
-
-/**
- * @author Nicola Dorigatti
- */
-public class AddWMSDialog extends DialogFragment {
- private static final String TAG = "AddWMSDialog";
- private Thread downloadThread;
- LayerInfoAdapter mListViewAdapter = null;
- private ListView mListView;
-
- private OnAddWMSLayersListener mListener;
-
- public interface OnAddWMSLayersListener {
- public void onAddWMSLayers(List layersToAdd);
- }
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- Bundle arguments = getArguments();
-
- String defaultWMSURL = WorldWindowActivity.DEFAULT_WMS_URL;
-
- if (null != arguments) {
- defaultWMSURL = arguments.getString("WMSURL");
- if (null == defaultWMSURL || defaultWMSURL.trim().isEmpty())
- defaultWMSURL = WorldWindowActivity.DEFAULT_WMS_URL;
- }
-
- // Use the Builder class for convenient dialog construction
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
- LayoutInflater inflater = getActivity().getLayoutInflater();
- View view = inflater.inflate(R.layout.dialog_wms_add, null);
-
- // Lookup views
- mListView = (ListView) view.findViewById(R.id.wms_layerslistview);
- mListViewAdapter = new LayerInfoAdapter(getActivity(), layerInfos.toArray(new LayerInfo[layerInfos.size()]));
- mListView.setAdapter(mListViewAdapter);
-
- final LinearLayout mainLayout = (LinearLayout) view.findViewById(R.id.main_add_wms_layout);
- mainLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
- final EditText urlEditText = (EditText) view.findViewById(R.id.wms_url_et);
- urlEditText.setText(defaultWMSURL);
- final Button getCapabilitiesButton = (Button) view.findViewById(R.id.get_capabilities_btn);
- getCapabilitiesButton.setOnClickListener(new View.OnClickListener() {
-
- public void onClick(View v) {
- InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
- imm.hideSoftInputFromWindow(urlEditText.getWindowToken(), 0);
- final String WMSURLtoUSE = urlEditText.getText().toString();
- // TODO Should Check url validity before starting to download WMS capabilities
- if (downloadThread == null) {
- getCapabilitiesButton.setEnabled(false);
- downloadThread = new Thread(new Runnable() {
-
- public void run() {
- downloadCapabilities(WMSURLtoUSE);
- downloadThread = null;
- AddWMSDialog.this.getActivity().runOnUiThread(new Runnable() {
-
- public void run() {
- // update listVIew
- updateLayerInfoList(getActivity());
- getCapabilitiesButton.setEnabled(true);
- }
- });
- }
- });
- downloadThread.start();
- }
-
- }
- });
-
- builder.setView(view);
- builder.setPositiveButton(getString(android.R.string.ok), new OnClickListener() {
-
- public void onClick(DialogInterface dialog, int which) {
- ArrayList retval = new ArrayList();
- LayerInfo[] infos = mListViewAdapter.getLayerInfos();
- for (LayerInfo info : infos) {
- if (info.selected) {
- Layer layer = createLayer(info.caps, info.params);
- if (null != layer) {
- retval.add(layer);
- }
- }
- }
- Toast.makeText(getActivity(), "Created layers that will be added to worldWind: " + retval.size(), Toast.LENGTH_LONG).show();
- if (null != mListener) {
- mListener.onAddWMSLayers(retval);
- }
- }
- });
- // Create the AlertDialog object and return it
- return builder.create();
- }
-
- /*
- * (non-Javadoc)
- * @see android.app.Fragment#onViewCreated(android.view.View, android.os.Bundle)
- */
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- this.getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
- }
-
- public void setOnAddWMSLayersListener(OnAddWMSLayersListener listener) {
- mListener = listener;
- }
-
- private void downloadCapabilities(String wmsURL) {
- try {
- layerInfos.clear();
- URI serverURI = new URI(wmsURL.trim());
- WMSCapabilities caps = WMSCapabilities.retrieve(serverURI);
- caps.parse();
- final List namedLayerCaps = caps.getNamedLayers();
- if (namedLayerCaps == null)
- return;
- for (WMSLayerCapabilities lc : namedLayerCaps) {
- Set styles = lc.getStyles();
-
- if (styles == null || styles.size() == 0) {
- // Log.d(TAG, "Null or empty styles!");
- LayerInfo layerInfo = createLayerInfo(caps, lc, null);
- layerInfos.add(layerInfo);
- } else {
- // Log.d(TAG, "Styles is not null and not empty");
- for (WMSLayerStyle style : styles) {
- LayerInfo layerInfo = createLayerInfo(caps, lc, style);
- layerInfos.add(layerInfo);
- }
- }
- }
-
- } catch (Throwable t) {
- t.printStackTrace();
- }
- }
-
- private void updateLayerInfoList(Context context) {
- mListViewAdapter = new LayerInfoAdapter(getActivity(), layerInfos.toArray(new LayerInfo[layerInfos.size()]));
- mListView.setAdapter(mListViewAdapter);
- // mListViewAdapter.setLayerInfos(layerInfos.toArray(new LayerInfo[layerInfos.size()]));
- mListViewAdapter.notifyDataSetChanged();
- Log.i(TAG, "Updated listview");
- }
-
- private Layer createLayer(WMSCapabilities caps, AVListImpl params) {
- AVList configParams = params.copy(); // Copy to insulate changes from the caller.
-
- // Some wms servers are slow, so increase the timeouts and limits used by world wind's retrievers.
- configParams.setValue(AVKey.URL_CONNECT_TIMEOUT, 30000);
- configParams.setValue(AVKey.URL_READ_TIMEOUT, 30000);
- configParams.setValue(AVKey.RETRIEVAL_QUEUE_STALE_REQUEST_LIMIT, 60000);
-
- try {
- String factoryKey = AVKey.LAYER_FACTORY;
- Factory factory = (Factory) WorldWind.createConfigurationComponent(factoryKey);
- return (Layer) factory.createFromConfigSource(caps, params);
- } catch (Exception e) {
- Log.e(TAG, "Exception creating layer WMS: " + e.getMessage());
- // Ignore the exception, and just return null.
- }
-
- return null;
- }
-
- // ------------LAYER INFO UTILS
- protected final TreeSet layerInfos = new TreeSet(new Comparator() {
- public int compare(LayerInfo infoA, LayerInfo infoB) {
- String nameA = infoA.getName();
- String nameB = infoB.getName();
- return nameA.compareTo(nameB);
- }
- });
-
- protected LayerInfo createLayerInfo(WMSCapabilities caps, WMSLayerCapabilities layerCaps, WMSLayerStyle style) {
- // Create the layer info specified by the layer's capabilities entry and
- // the selected style.
-
- LayerInfo linfo = new LayerInfo();
- linfo.caps = caps;
- linfo.params = new AVListImpl();
- linfo.params.setValue(AVKey.LAYER_NAMES, layerCaps.getName());
- if (style != null)
- linfo.params.setValue(AVKey.STYLE_NAMES, style.getName());
- String abs = layerCaps.getLayerAbstract();
- if (!WWUtil.isEmpty(abs))
- linfo.params.setValue(AVKey.LAYER_ABSTRACT, abs);
-
- linfo.params.setValue(AVKey.DISPLAY_NAME, makeTitle(caps, linfo));
-
- return linfo;
- }
-
- protected static String makeTitle(WMSCapabilities caps, LayerInfo layerInfo) {
- String layerNames = layerInfo.params.getStringValue(AVKey.LAYER_NAMES);
- String styleNames = layerInfo.params.getStringValue(AVKey.STYLE_NAMES);
- String[] lNames = layerNames.split(",");
- String[] sNames = styleNames != null ? styleNames.split(",") : null;
-
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < lNames.length; i++) {
- if (sb.length() > 0)
- sb.append(", ");
-
- String layerName = lNames[i];
- WMSLayerCapabilities lc = caps.getLayerByName(layerName);
- String layerTitle = lc.getTitle();
- sb.append(layerTitle != null ? layerTitle : layerName);
-
- if (sNames == null || sNames.length <= i)
- continue;
-
- String styleName = sNames[i];
- WMSLayerStyle style = lc.getStyleByName(styleName);
- if (style == null)
- continue;
-
- sb.append(" : ");
- String styleTitle = style.getTitle();
- sb.append(styleTitle != null ? styleTitle : styleName);
- }
-
- return sb.toString();
- }
-
- protected static class LayerInfo {
- protected WMSCapabilities caps;
- protected AVListImpl params = new AVListImpl();
- protected boolean selected = false;
-
- protected String getTitle() {
- return params.getStringValue(AVKey.DISPLAY_NAME);
- }
-
- protected String getName() {
- return params.getStringValue(AVKey.LAYER_NAMES);
- }
-
- protected String getAbstract() {
- return params.getStringValue(AVKey.LAYER_ABSTRACT);
- }
- }
-
- private class LayerInfoAdapter extends ArrayAdapter {
-
- private LayerInfo[] types;
-
- public LayerInfoAdapter(Activity context, LayerInfo[] types) {
- super(context, android.R.layout.simple_list_item_1, types);
- this.types = types;
- }
-
- public LayerInfo[] getLayerInfos() {
- return types;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- final LayerInfo layerType = types[position];
- View retval = convertView;
- if (retval == null) {
- retval = new CheckBox(getContext());
- }
- ((CheckBox) retval).setText(layerType.getTitle());
- ((CheckBox) retval).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
-
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- layerType.selected = buttonView.isChecked();
- }
- });
- ((CheckBox) retval).setChecked(layerType.selected);
- return retval;
- }
- }
-}
+/*
+ * Copyright (C) 2013 Trilogis S.r.l.
+ *
+ * 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 it.trilogis.android.ww.dialogs;
+
+import gov.nasa.worldwind.Factory;
+import gov.nasa.worldwind.WorldWind;
+import gov.nasa.worldwind.avlist.AVKey;
+import gov.nasa.worldwind.avlist.AVList;
+import gov.nasa.worldwind.avlist.AVListImpl;
+import gov.nasa.worldwind.layers.Layer;
+import gov.nasa.worldwind.ogc.wms.WMSCapabilities;
+import gov.nasa.worldwind.ogc.wms.WMSLayerCapabilities;
+import gov.nasa.worldwind.ogc.wms.WMSLayerStyle;
+import gov.nasa.worldwind.util.WWUtil;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.app.DialogFragment;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.ListView;
+import android.widget.Toast;
+import it.trilogis.android.ww.R;
+import it.trilogis.android.ww.WorldWindowActivity;
+
+/**
+ * @author Nicola Dorigatti
+ */
+public class AddWMSDialog extends DialogFragment {
+ private static final String TAG = "AddWMSDialog";
+ private Thread downloadThread;
+ LayerInfoAdapter mListViewAdapter = null;
+ private ListView mListView;
+
+ private OnAddWMSLayersListener mListener;
+
+ public interface OnAddWMSLayersListener {
+ public void onAddWMSLayers(List layersToAdd);
+ }
+
+ @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Bundle arguments = getArguments();
+
+ String defaultWMSURL = WorldWindowActivity.DEFAULT_WMS_URL;
+
+ if (null != arguments) {
+ defaultWMSURL = arguments.getString("WMSURL");
+ if (null == defaultWMSURL || defaultWMSURL.trim().isEmpty())
+ defaultWMSURL = WorldWindowActivity.DEFAULT_WMS_URL;
+ }
+
+ // Use the Builder class for convenient dialog construction
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+ View view = inflater.inflate(R.layout.dialog_wms_add, null);
+
+ // Lookup views
+ mListView = (ListView) view.findViewById(R.id.wms_layerslistview);
+ mListViewAdapter = new LayerInfoAdapter(getActivity(), layerInfos.toArray(new LayerInfo[layerInfos.size()]));
+ mListView.setAdapter(mListViewAdapter);
+
+ final LinearLayout mainLayout = (LinearLayout) view.findViewById(R.id.main_add_wms_layout);
+ mainLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
+ final EditText urlEditText = (EditText) view.findViewById(R.id.wms_url_et);
+ urlEditText.setText(defaultWMSURL);
+ final Button getCapabilitiesButton = (Button) view.findViewById(R.id.get_capabilities_btn);
+ getCapabilitiesButton.setOnClickListener(new View.OnClickListener() {
+
+ public void onClick(View v) {
+ InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
+ imm.hideSoftInputFromWindow(urlEditText.getWindowToken(), 0);
+ final String WMSURLtoUSE = urlEditText.getText().toString();
+ // TODO Should Check url validity before starting to download WMS capabilities
+ if (downloadThread == null) {
+ getCapabilitiesButton.setEnabled(false);
+ downloadThread = new Thread(new Runnable() {
+
+ public void run() {
+ downloadCapabilities(WMSURLtoUSE);
+ downloadThread = null;
+ AddWMSDialog.this.getActivity().runOnUiThread(new Runnable() {
+
+ public void run() {
+ // update listVIew
+ updateLayerInfoList(getActivity());
+ getCapabilitiesButton.setEnabled(true);
+ }
+ });
+ }
+ });
+ downloadThread.start();
+ }
+
+ }
+ });
+
+ builder.setView(view);
+ builder.setPositiveButton(getString(android.R.string.ok), new OnClickListener() {
+
+ public void onClick(DialogInterface dialog, int which) {
+ ArrayList retval = new ArrayList();
+ LayerInfo[] infos = mListViewAdapter.getLayerInfos();
+ for (LayerInfo info : infos) {
+ if (info.selected) {
+ Layer layer = createLayer(info.caps, info.params);
+ if (null != layer) {
+ retval.add(layer);
+ }
+ }
+ }
+ Toast.makeText(getActivity(), "Created layers that will be added to worldWind: " + retval.size(), Toast.LENGTH_LONG).show();
+ if (null != mListener) {
+ mListener.onAddWMSLayers(retval);
+ }
+ }
+ });
+ // Create the AlertDialog object and return it
+ return builder.create();
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see android.app.Fragment#onViewCreated(android.view.View, android.os.Bundle)
+ */
+ @Override
+ public void onViewCreated(View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ this.getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
+ }
+
+ public void setOnAddWMSLayersListener(OnAddWMSLayersListener listener) {
+ mListener = listener;
+ }
+
+ private void downloadCapabilities(String wmsURL) {
+ try {
+ layerInfos.clear();
+ URI serverURI = new URI(wmsURL.trim());
+ WMSCapabilities caps = WMSCapabilities.retrieve(serverURI);
+ caps.parse();
+ final List namedLayerCaps = caps.getNamedLayers();
+ if (namedLayerCaps == null)
+ return;
+ for (WMSLayerCapabilities lc : namedLayerCaps) {
+ Set styles = lc.getStyles();
+
+ if (styles == null || styles.size() == 0) {
+ // Log.d(TAG, "Null or empty styles!");
+ LayerInfo layerInfo = createLayerInfo(caps, lc, null);
+ layerInfos.add(layerInfo);
+ } else {
+ // Log.d(TAG, "Styles is not null and not empty");
+ for (WMSLayerStyle style : styles) {
+ LayerInfo layerInfo = createLayerInfo(caps, lc, style);
+ layerInfos.add(layerInfo);
+ }
+ }
+ }
+
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ }
+
+ private void updateLayerInfoList(Context context) {
+ mListViewAdapter = new LayerInfoAdapter(getActivity(), layerInfos.toArray(new LayerInfo[layerInfos.size()]));
+ mListView.setAdapter(mListViewAdapter);
+ // mListViewAdapter.setLayerInfos(layerInfos.toArray(new LayerInfo[layerInfos.size()]));
+ mListViewAdapter.notifyDataSetChanged();
+ Log.i(TAG, "Updated listview");
+ }
+
+ private Layer createLayer(WMSCapabilities caps, AVListImpl params) {
+ AVList configParams = params.copy(); // Copy to insulate changes from the caller.
+
+ // Some wms servers are slow, so increase the timeouts and limits used by world wind's retrievers.
+ configParams.setValue(AVKey.URL_CONNECT_TIMEOUT, 30000);
+ configParams.setValue(AVKey.URL_READ_TIMEOUT, 30000);
+ configParams.setValue(AVKey.RETRIEVAL_QUEUE_STALE_REQUEST_LIMIT, 60000);
+
+ try {
+ String factoryKey = AVKey.LAYER_FACTORY;
+ Factory factory = (Factory) WorldWind.createConfigurationComponent(factoryKey);
+ return (Layer) factory.createFromConfigSource(caps, params);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception creating layer WMS: " + e.getMessage());
+ // Ignore the exception, and just return null.
+ }
+
+ return null;
+ }
+
+ // ------------LAYER INFO UTILS
+ protected final TreeSet layerInfos = new TreeSet(new Comparator() {
+ public int compare(LayerInfo infoA, LayerInfo infoB) {
+ String nameA = infoA.getName();
+ String nameB = infoB.getName();
+ return nameA.compareTo(nameB);
+ }
+ });
+
+ protected LayerInfo createLayerInfo(WMSCapabilities caps, WMSLayerCapabilities layerCaps, WMSLayerStyle style) {
+ // Create the layer info specified by the layer's capabilities entry and
+ // the selected style.
+
+ LayerInfo linfo = new LayerInfo();
+ linfo.caps = caps;
+ linfo.params = new AVListImpl();
+ linfo.params.setValue(AVKey.LAYER_NAMES, layerCaps.getName());
+ if (style != null)
+ linfo.params.setValue(AVKey.STYLE_NAMES, style.getName());
+ String abs = layerCaps.getLayerAbstract();
+ if (!WWUtil.isEmpty(abs))
+ linfo.params.setValue(AVKey.LAYER_ABSTRACT, abs);
+
+ linfo.params.setValue(AVKey.DISPLAY_NAME, makeTitle(caps, linfo));
+
+ return linfo;
+ }
+
+ protected static String makeTitle(WMSCapabilities caps, LayerInfo layerInfo) {
+ String layerNames = layerInfo.params.getStringValue(AVKey.LAYER_NAMES);
+ String styleNames = layerInfo.params.getStringValue(AVKey.STYLE_NAMES);
+ String[] lNames = layerNames.split(",");
+ String[] sNames = styleNames != null ? styleNames.split(",") : null;
+
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < lNames.length; i++) {
+ if (sb.length() > 0)
+ sb.append(", ");
+
+ String layerName = lNames[i];
+ WMSLayerCapabilities lc = caps.getLayerByName(layerName);
+ String layerTitle = lc.getTitle();
+ sb.append(layerTitle != null ? layerTitle : layerName);
+
+ if (sNames == null || sNames.length <= i)
+ continue;
+
+ String styleName = sNames[i];
+ WMSLayerStyle style = lc.getStyleByName(styleName);
+ if (style == null)
+ continue;
+
+ sb.append(" : ");
+ String styleTitle = style.getTitle();
+ sb.append(styleTitle != null ? styleTitle : styleName);
+ }
+
+ return sb.toString();
+ }
+
+ protected static class LayerInfo {
+ protected WMSCapabilities caps;
+ protected AVListImpl params = new AVListImpl();
+ protected boolean selected = false;
+
+ protected String getTitle() {
+ return params.getStringValue(AVKey.DISPLAY_NAME);
+ }
+
+ protected String getName() {
+ return params.getStringValue(AVKey.LAYER_NAMES);
+ }
+
+ protected String getAbstract() {
+ return params.getStringValue(AVKey.LAYER_ABSTRACT);
+ }
+ }
+
+ private class LayerInfoAdapter extends ArrayAdapter {
+
+ private LayerInfo[] types;
+
+ public LayerInfoAdapter(Activity context, LayerInfo[] types) {
+ super(context, android.R.layout.simple_list_item_1, types);
+ this.types = types;
+ }
+
+ public LayerInfo[] getLayerInfos() {
+ return types;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final LayerInfo layerType = types[position];
+ View retval = convertView;
+ if (retval == null) {
+ retval = new CheckBox(getContext());
+ }
+ ((CheckBox) retval).setText(layerType.getTitle()+"-"+layerType.caps.getImageFormats());
+ ((CheckBox) retval).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ layerType.selected = buttonView.isChecked();
+ }
+ });
+ ((CheckBox) retval).setChecked(layerType.selected);
+ return retval;
+ }
+ }
+}
diff --git a/WorldWindowApplicationSample/src/it/trilogis/android/ww/dialogs/TocDialog.java b/WorldWindowApplicationSample/src/it/trilogis/android/ww/dialogs/TocFragment.java
similarity index 63%
rename from WorldWindowApplicationSample/src/it/trilogis/android/ww/dialogs/TocDialog.java
rename to WorldWindowApplicationSample/src/it/trilogis/android/ww/dialogs/TocFragment.java
index a9f04f0..bc2c893 100644
--- a/WorldWindowApplicationSample/src/it/trilogis/android/ww/dialogs/TocDialog.java
+++ b/WorldWindowApplicationSample/src/it/trilogis/android/ww/dialogs/TocFragment.java
@@ -1,219 +1,206 @@
-/*
- * Copyright (C) 2013 Trilogis S.r.l.
- *
- * 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 it.trilogis.android.ww.dialogs;
-
-import gov.nasa.worldwind.WorldWindowGLSurfaceView;
-import gov.nasa.worldwind.layers.Layer;
-import gov.nasa.worldwind.layers.LayerList;
-import it.trilogis.android.ww.R;
-import it.trilogis.android.ww.dialogs.AddWMSDialog.OnAddWMSLayersListener;
-import it.trilogis.android.ww.view.DragListView;
-import java.util.List;
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnClickListener;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-/**
- * @author Nicola Dorigatti
- */
-public class TocDialog extends DialogFragment {
- private static final String TAG = "TocDialog";
- private LayerArrayAdapter mListViewAdapter = null;
- private DragListView mListView;
- WorldWindowGLSurfaceView wwd = null;
-
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- // Use the Builder class for convenient dialog construction
- AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
-
- LayoutInflater inflater = getActivity().getLayoutInflater();
- View view = inflater.inflate(R.layout.toc_view_dialog, null);
- mListView = (DragListView) view.findViewById(android.R.id.list);
-
- View removerow = view.findViewById(R.id.removeView);
- mListView.setTrashcan((ImageView) removerow);
- mListView.setDropListener(onDrop);
- mListView.setRemoveListener(onRemove);
- // Init WorldWind Data
- initWorldWindLayerAdapter();
- // Set view
- builder.setView(view);
- builder.setPositiveButton(getString(android.R.string.ok), new OnClickListener() {
-
- public void onClick(DialogInterface dialog, int which) {
- Toast.makeText(getActivity(), "Created layers that will be added to worldWind: ", Toast.LENGTH_LONG).show();
- }
- });
- builder.setNeutralButton(getString(R.string.menu_action_text_wms), new OnClickListener() {
-
- public void onClick(DialogInterface dialog, int which) {
- // Add dialog for wms
- openAddWMSDialog();
- }
- });
- // Create the AlertDialog object and return it
- return builder.create();
- }
-
- /*
- * (non-Javadoc)
- * @see android.app.DialogFragment#onStart()
- */
- @Override
- public void onStart() {
- super.onStart();
- AlertDialog d = (AlertDialog) getDialog();
- if (d != null) {
- Button neutralButton = d.getButton(Dialog.BUTTON_NEUTRAL);
- neutralButton.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- openAddWMSDialog();
- }
- });
- }
- }
-
- /*
- * (non-Javadoc)
- * @see android.app.Fragment#onResume()
- */
- @Override
- public void onResume() {
- super.onResume();
- if (mListViewAdapter != null) {
- mListViewAdapter.notifyDataSetChanged();
- }
- }
-
- /**
- * Set the class parameter that will be used to fill adapter and perform operations.
- *
- * @param wwd
- * The WorldWind context to be used.
- */
- public void setWorldWindData(WorldWindowGLSurfaceView wwd) {
- if (null == wwd) {
- Log.e(TAG, "Setting null world wind data!!!");
- return;
- }
- this.wwd = wwd;
- // Initialize list view, adapters and so on...
- initWorldWindLayerAdapter();
- }
-
- /**
- *
- */
- private void initWorldWindLayerAdapter() {
- if (null == wwd) {
- Log.e(TAG, "Trying to initialize layer adapter with not valid WorldWind context!!");
- return;
- }
- if (null == mListView) {
- Log.e(TAG, "Trying to initialize layer list view, but list view is null!!");
- return;
- }
- LayerList layers = wwd.getModel().getLayers();
- mListViewAdapter = new LayerArrayAdapter(getActivity(), layers);
- mListView.setAdapter(mListViewAdapter);
- }
-
- private DragListView.DropListener onDrop = new DragListView.DropListener() {
- public void drop(int from, int to) {
- Layer item = mListViewAdapter.getItem(from);
- mListViewAdapter.remove(item);
- mListViewAdapter.insert(item, to);
- }
- };
-
- private DragListView.RemoveListener onRemove = new DragListView.RemoveListener() {
- public void remove(int which) {
- mListViewAdapter.remove(mListViewAdapter.getItem(which));
- }
- };
-
- private class LayerArrayAdapter extends ArrayAdapter {
-
- private final List list;
-
- public LayerArrayAdapter(Activity context, List list) {
- super(context, R.layout.toc_list_view_item, list);
- this.list = list;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- final Layer layer = list.get(position);
- View retval = convertView;
- if (retval == null) {
- LayoutInflater inflator = getActivity().getLayoutInflater();
- retval = inflator.inflate(R.layout.toc_list_view_item, null);
- }
- CheckBox checkbox = (CheckBox) retval.findViewById(R.id.toc_item_checkbox);
- checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
-
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- layer.setEnabled(buttonView.isChecked());
- }
- });
- checkbox.setChecked(layer.isEnabled());
- checkbox.setText(layer.getName());
- return retval;
- }
- }
-
- // ===================== ADD WMS ================================0
- private void openAddWMSDialog() {
- AddWMSDialog wmsLayersDialog = new AddWMSDialog();
- wmsLayersDialog.setOnAddWMSLayersListener(mListener);
- wmsLayersDialog.show(getFragmentManager(), "addWmsLayers");
- }
-
- private OnAddWMSLayersListener mListener = new OnAddWMSLayersListener() {
-
- public void onAddWMSLayers(List layersToAdd) {
-
- if (null == layersToAdd || layersToAdd.isEmpty() || null == wwd) {
- Log.w(TAG, "Null or empty layers/WorldWindContext to add!");
- return;
- }
- for (Layer lyr : layersToAdd) {
- boolean added = wwd.getModel().getLayers().addIfAbsent(lyr);
- Log.d(TAG, "Layer '" + lyr.getName() + "' " + (added ? "correctly" : "not") + " added to WorldWind!");
-
- }
- if (mListViewAdapter != null) {
- mListViewAdapter.notifyDataSetChanged();
- }
-
- }
- };
-}
+/*
+ * Copyright (C) 2013 Trilogis S.r.l.
+ *
+ * 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 it.trilogis.android.ww.dialogs;
+
+import android.app.*;
+import android.widget.*;
+import gov.nasa.worldwind.SceneController;
+import gov.nasa.worldwind.WorldWindow;
+import gov.nasa.worldwind.layers.Layer;
+import gov.nasa.worldwind.layers.LayerList;
+import it.trilogis.android.ww.R;
+import it.trilogis.android.ww.dialogs.AddWMSDialog.OnAddWMSLayersListener;
+import it.trilogis.android.ww.view.DragListView;
+import java.util.List;
+
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import gov.nasa.worldwind.terrain.ElevationModel;
+
+/**
+ * @author Marek Kedzierski
+ */
+public class TocFragment extends Fragment {
+ private static final String TAG = "TocFragment";
+ private LayerArrayAdapter mListViewAdapter;
+ private DragListView mListView;
+ WorldWindow wwd;
+ private SceneController sceneController;
+ private ElevationModel elevationModel;
+
+ private static final double VERT_EXAGG_INCREMENT = 0.1;
+ private Button lowerButton;
+ private Button raiseButton;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.toc_view_dialog, null);
+ mListView = (DragListView) view.findViewById(android.R.id.list);
+
+ View removerow = view.findViewById(R.id.removeView);
+ mListView.setTrashcan((ImageView) removerow);
+ mListView.setDropListener(onDrop);
+ mListView.setRemoveListener(onRemove);
+
+ lowerButton = (Button) view.findViewById(R.id.lowerButton);
+ lowerButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ sceneController.setVerticalExaggeration(
+ Math.max(0, sceneController.getVerticalExaggeration()-VERT_EXAGG_INCREMENT));
+ updateVerticalExaggerationButtonState();
+ }
+ });
+ raiseButton = (Button) view.findViewById(R.id.raiseButton);
+ raiseButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ sceneController.setVerticalExaggeration(
+ sceneController.getVerticalExaggeration() + VERT_EXAGG_INCREMENT);
+ updateVerticalExaggerationButtonState();
+ }
+ });
+
+ // Init WorldWind Data
+ if(wwd!=null)
+ initWorldWindLayerAdapter();
+ return view;
+ }
+
+ private void updateVerticalExaggerationButtonState() {
+ lowerButton.setEnabled(sceneController.getVerticalExaggeration()!=0);
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see android.app.Fragment#onResume()
+ */
+ @Override
+ public void onResume() {
+ super.onResume();
+ if (mListViewAdapter != null) {
+ mListViewAdapter.notifyDataSetChanged();
+ }
+ }
+
+ /**
+ * Set the class parameter that will be used to fill adapter and perform operations.
+ *
+ * @param wwd
+ * The WorldWind context to be used.
+ */
+ public void setWorldWindData(WorldWindow wwd) {
+ if (null == wwd) {
+ Log.e(TAG, "Setting null world wind data!!!");
+ return;
+ }
+ this.wwd = wwd;
+ sceneController = wwd.getSceneController();
+ // Initialize list view, adapters and so on...
+ initWorldWindLayerAdapter();
+ }
+
+ /**
+ *
+ */
+ private void initWorldWindLayerAdapter() {
+ if (null == wwd) {
+ Log.e(TAG, "Trying to initialize layer adapter with not valid WorldWind context!!");
+ return;
+ }
+ if (null == mListView) {
+ Log.e(TAG, "Trying to initialize layer list view, but list view is null!!");
+ return;
+ }
+ LayerList layers = wwd.getModel().getLayers();
+ mListViewAdapter = new LayerArrayAdapter(getActivity(), layers);
+ mListView.setAdapter(mListViewAdapter);
+ }
+
+ private DragListView.DropListener onDrop = new DragListView.DropListener() {
+ public void drop(int from, int to) {
+ Layer item = mListViewAdapter.getItem(from);
+ mListViewAdapter.remove(item);
+ mListViewAdapter.insert(item, to);
+ }
+ };
+
+ private DragListView.RemoveListener onRemove = new DragListView.RemoveListener() {
+ public void remove(int which) {
+ mListViewAdapter.remove(mListViewAdapter.getItem(which));
+ }
+ };
+
+ private class LayerArrayAdapter extends ArrayAdapter {
+
+ private final List list;
+
+ public LayerArrayAdapter(Activity context, List list) {
+ super(context, R.layout.toc_list_view_item, list);
+ this.list = list;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final Layer layer = list.get(position);
+ View retval = convertView;
+ if (retval == null) {
+ LayoutInflater inflator = getActivity().getLayoutInflater();
+ retval = inflator.inflate(R.layout.toc_list_view_item, null);
+ }
+ CheckBox checkbox = (CheckBox) retval.findViewById(R.id.toc_item_checkbox);
+ checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ layer.setEnabled(buttonView.isChecked());
+ }
+ });
+ checkbox.setChecked(layer.isEnabled());
+ checkbox.setText(layer.getName());
+ return retval;
+ }
+ }
+
+ // ===================== ADD WMS ================================0
+ private void openAddWMSDialog() {
+ AddWMSDialog wmsLayersDialog = new AddWMSDialog();
+ wmsLayersDialog.setOnAddWMSLayersListener(mListener);
+ wmsLayersDialog.show(getFragmentManager(), "addWmsLayers");
+ }
+
+ private OnAddWMSLayersListener mListener = new OnAddWMSLayersListener() {
+
+ public void onAddWMSLayers(List layersToAdd) {
+
+ if (null == layersToAdd || layersToAdd.isEmpty() || null == wwd) {
+ Log.w(TAG, "Null or empty layers/WorldWindContext to add!");
+ return;
+ }
+ for (Layer lyr : layersToAdd) {
+ boolean added = wwd.getModel().getLayers().addIfAbsent(lyr);
+ Log.d(TAG, "Layer '" + lyr.getName() + "' " + (added ? "correctly" : "not") + " added to WorldWind!");
+
+ }
+ if (mListViewAdapter != null) {
+ mListViewAdapter.notifyDataSetChanged();
+ }
+
+ }
+ };
+}
diff --git a/WorldWindowApplicationSample/src/it/trilogis/android/ww/view/DragListView.java b/WorldWindowApplicationSample/src/it/trilogis/android/ww/view/DragListView.java
index bf1fd7d..7a89370 100644
--- a/WorldWindowApplicationSample/src/it/trilogis/android/ww/view/DragListView.java
+++ b/WorldWindowApplicationSample/src/it/trilogis/android/ww/view/DragListView.java
@@ -15,24 +15,18 @@
*/
package it.trilogis.android.ww.view;
-import it.trilogis.android.ww.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.util.AttributeSet;
-import android.view.GestureDetector;
+import android.view.*;
import android.view.GestureDetector.SimpleOnGestureListener;
-import android.view.Gravity;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.ListView;
+import it.trilogis.android.ww.R;
public class DragListView extends ListView {
private ImageView mDragView;
@@ -170,7 +164,7 @@ public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float ve
private int myPointToPosition(int x, int y) {
if (y < 0) {
- // when dragging off the top of the screen, calculate position
+ // when dragging off the top of the screen, calculate mPosition
// by going back from a visible item
int pos = myPointToPosition(x, y + mItemHeightNormal);
if (pos > 0) {
diff --git a/WorldWindowApplicationSample/src/it/trilogis/android/ww/view/SettingsActivity.java b/WorldWindowApplicationSample/src/it/trilogis/android/ww/view/SettingsActivity.java
new file mode 100644
index 0000000..1c79b7d
--- /dev/null
+++ b/WorldWindowApplicationSample/src/it/trilogis/android/ww/view/SettingsActivity.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 United States Government as represented by the Administrator of the
+ * National Aeronautics and Space Administration.
+ * All Rights Reserved.
+ */
+
+package it.trilogis.android.ww.view;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
+import android.view.MenuItem;
+import gov.nasa.worldwind.util.Logging;
+import it.trilogis.android.ww.R;
+
+import java.util.List;
+
+/**
+ * Preference headers
+ *
+ * Created by kedzie on 4/16/14.
+ */
+public class SettingsActivity extends PreferenceActivity {
+
+ public static final String PREF_ENABLE_ELEVATION="elevation";
+ public static final String PREF_VERTICAL_EXAGGERATION="verticalExaggeration";
+ public static final String PREF_HORIZON_MULTIPLIER = "farDistance";
+ public static final String PREF_COLLISION_DETECTION = "detectCollisions";
+ public static final String PREF_DEBUG_LOGGING="logging";
+ public static final String PREF_STATS="showStats";
+ public static final String PREF_TILE_ID = "drawTileIds";
+ public static final String PREF_TILE_BOUNDRIES = "drawTileBoundries";
+ public static final String PREF_ELEV_TILE_ID = "drawElevationTileIds";
+ public static final String PREF_ELEV_TILE_BOUNDRIES = "drawElevationTileBoundries";
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+ getActionBar().setDisplayShowHomeEnabled(true);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch(item.getItemId()) {
+ case android.R.id.home:
+ finish();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ protected boolean isValidFragment(String fragmentName) {
+ Logging.verbose("isValidFragment " + fragmentName);
+ return true;
+ }
+
+ @Override
+ public void onBuildHeaders(List target) {
+ loadHeadersFromResource(R.xml.preference_headers, target);
+ }
+
+ public static class PerformancePreferenceFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener{
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.performance_preferences);
+ }
+
+ @Override
+ public void onPause() {
+ getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
+ super.onPause();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ final SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();
+ onSharedPreferenceChanged(sharedPreferences, PREF_HORIZON_MULTIPLIER);
+ onSharedPreferenceChanged(sharedPreferences, PREF_VERTICAL_EXAGGERATION);
+ sharedPreferences.registerOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ if(key.equals(PREF_HORIZON_MULTIPLIER))
+ findPreference(key).setSummary("Horizon Distance Multiplier: " + sharedPreferences.getString(key, ""));
+ else if(key.equals(PREF_VERTICAL_EXAGGERATION))
+ findPreference(key).setSummary("Vertical Exaggeration: " + sharedPreferences.getString(key, ""));
+ }
+ }
+
+ public static class DebugPreferenceFragment extends PreferenceFragment {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.debug_preferences);
+ }
+
+
+ }
+}
+
diff --git a/maven_repo_3rd_party/android/android/4.4.2_r3/_remote.repositories b/maven_repo_3rd_party/android/android/4.4.2_r3/_remote.repositories
new file mode 100644
index 0000000..ad6b8f4
--- /dev/null
+++ b/maven_repo_3rd_party/android/android/4.4.2_r3/_remote.repositories
@@ -0,0 +1,6 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu May 08 16:49:28 CDT 2014
+android-4.4.2_r3-sources.jar>=
+android-4.4.2_r3.pom>=
+android-4.4.2_r3-javadoc.jar>=
+android-4.4.2_r3.jar>=
diff --git a/maven_repo_3rd_party/android/android/4.4.2_r3/android-4.4.2_r3-javadoc.jar b/maven_repo_3rd_party/android/android/4.4.2_r3/android-4.4.2_r3-javadoc.jar
new file mode 100644
index 0000000..62863ed
Binary files /dev/null and b/maven_repo_3rd_party/android/android/4.4.2_r3/android-4.4.2_r3-javadoc.jar differ
diff --git a/maven_repo_3rd_party/android/android/4.4.2_r3/android-4.4.2_r3-sources.jar b/maven_repo_3rd_party/android/android/4.4.2_r3/android-4.4.2_r3-sources.jar
new file mode 100644
index 0000000..9c0c613
Binary files /dev/null and b/maven_repo_3rd_party/android/android/4.4.2_r3/android-4.4.2_r3-sources.jar differ
diff --git a/maven_repo_3rd_party/android/android/4.4.2_r3/android-4.4.2_r3.jar b/maven_repo_3rd_party/android/android/4.4.2_r3/android-4.4.2_r3.jar
new file mode 100644
index 0000000..b94c815
Binary files /dev/null and b/maven_repo_3rd_party/android/android/4.4.2_r3/android-4.4.2_r3.jar differ
diff --git a/maven_repo_3rd_party/android/android/4.4.2_r3/android-4.4.2_r3.pom b/maven_repo_3rd_party/android/android/4.4.2_r3/android-4.4.2_r3.pom
new file mode 100644
index 0000000..7412797
--- /dev/null
+++ b/maven_repo_3rd_party/android/android/4.4.2_r3/android-4.4.2_r3.pom
@@ -0,0 +1,9 @@
+
+
+ 4.0.0
+ android
+ android
+ 4.4.2_r3
+ POM was created from install:install-file
+
diff --git a/maven_repo_3rd_party/android/support/compatibility-v4/19.0.1/_remote.repositories b/maven_repo_3rd_party/android/support/compatibility-v4/19.0.1/_remote.repositories
new file mode 100644
index 0000000..1d37040
--- /dev/null
+++ b/maven_repo_3rd_party/android/support/compatibility-v4/19.0.1/_remote.repositories
@@ -0,0 +1,5 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Sun Jan 19 15:06:44 CST 2014
+compatibility-v4-19.0.1.pom>=
+compatibility-v4-19.0.1-sources.jar>=
+compatibility-v4-19.0.1.jar>=
diff --git a/maven_repo_3rd_party/android/support/compatibility-v4/19.0.1/compatibility-v4-19.0.1-sources.jar b/maven_repo_3rd_party/android/support/compatibility-v4/19.0.1/compatibility-v4-19.0.1-sources.jar
new file mode 100644
index 0000000..5a73403
Binary files /dev/null and b/maven_repo_3rd_party/android/support/compatibility-v4/19.0.1/compatibility-v4-19.0.1-sources.jar differ
diff --git a/maven_repo_3rd_party/android/support/compatibility-v4/19.0.1/compatibility-v4-19.0.1.jar b/maven_repo_3rd_party/android/support/compatibility-v4/19.0.1/compatibility-v4-19.0.1.jar
new file mode 100644
index 0000000..96644ed
Binary files /dev/null and b/maven_repo_3rd_party/android/support/compatibility-v4/19.0.1/compatibility-v4-19.0.1.jar differ
diff --git a/maven_repo_3rd_party/android/support/compatibility-v4/19.0.1/compatibility-v4-19.0.1.pom b/maven_repo_3rd_party/android/support/compatibility-v4/19.0.1/compatibility-v4-19.0.1.pom
new file mode 100644
index 0000000..af346c4
--- /dev/null
+++ b/maven_repo_3rd_party/android/support/compatibility-v4/19.0.1/compatibility-v4-19.0.1.pom
@@ -0,0 +1,9 @@
+
+
+ 4.0.0
+ android.support
+ compatibility-v4
+ 19.0.1
+ POM was created from install:install-file
+
diff --git a/maven_repo_3rd_party/android/support/compatibility-v4/maven-metadata-local.xml b/maven_repo_3rd_party/android/support/compatibility-v4/maven-metadata-local.xml
new file mode 100644
index 0000000..ccae2d6
--- /dev/null
+++ b/maven_repo_3rd_party/android/support/compatibility-v4/maven-metadata-local.xml
@@ -0,0 +1,15 @@
+
+
+ android.support
+ compatibility-v4
+
+ 19.0.1
+
+ 13
+ 18
+ 19
+ 19.0.1
+
+ 20140119210644
+
+
diff --git a/maven_repo_3rd_party/com/github/masdennis/rajawali/rajawali/1.0.0/_remote.repositories b/maven_repo_3rd_party/com/github/masdennis/rajawali/rajawali/1.0.0/_remote.repositories
new file mode 100644
index 0000000..fa6833d
--- /dev/null
+++ b/maven_repo_3rd_party/com/github/masdennis/rajawali/rajawali/1.0.0/_remote.repositories
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu Jul 03 19:05:19 CDT 2014
+rajawali-1.0.0.pom>=
+rajawali-1.0.0.aar>=
diff --git a/maven_repo_3rd_party/com/github/masdennis/rajawali/rajawali/1.0.0/rajawali-1.0.0.aar b/maven_repo_3rd_party/com/github/masdennis/rajawali/rajawali/1.0.0/rajawali-1.0.0.aar
new file mode 100644
index 0000000..c1ff502
Binary files /dev/null and b/maven_repo_3rd_party/com/github/masdennis/rajawali/rajawali/1.0.0/rajawali-1.0.0.aar differ
diff --git a/maven_repo_3rd_party/com/github/masdennis/rajawali/rajawali/1.0.0/rajawali-1.0.0.pom b/maven_repo_3rd_party/com/github/masdennis/rajawali/rajawali/1.0.0/rajawali-1.0.0.pom
new file mode 100644
index 0000000..9d6272c
--- /dev/null
+++ b/maven_repo_3rd_party/com/github/masdennis/rajawali/rajawali/1.0.0/rajawali-1.0.0.pom
@@ -0,0 +1,74 @@
+
+
+
+ 4.0.0
+
+ com.github.masdennis.rajawali
+ rajawali
+ 1.0.0
+ aar
+
+ Rajawali
+
+
+ https://github.com/MasDennis/Rajawali
+ scm:git:git://github.com/MasDennis/Rajawali.git
+ scm:git:git://github.com/MasDennis/Rajawali.git
+
+
+
+ https://www.github.com/MasDennis/Rajawali/issues
+ GitHub Issues
+
+
+
+
+ android
+ android
+ 4.4_r1
+ provided
+
+
+ commons-logging
+ commons-logging
+
+
+
+
+
+
+ ${basedir}/src
+ ${basedir}/bin
+ ${basedir}/bin/classes
+ ${project.artifactId}
+
+
+ maven-compiler-plugin
+ 2.3.2
+ 1.61.6
+
+
+ com.jayway.maven.plugins.android.generation2
+ android-maven-plugin
+ 3.8.2
+ true
+
+ 19
+
+ true
+
+ true
+
+ true
+
+
+
+ manifest
+ process-resources
+ manifest-update
+
+
+
+
+
+
diff --git a/maven_repo_3rd_party/com/github/masdennis/rajawali/rajawali/maven-metadata-local.xml b/maven_repo_3rd_party/com/github/masdennis/rajawali/rajawali/maven-metadata-local.xml
new file mode 100644
index 0000000..ebd6e16
--- /dev/null
+++ b/maven_repo_3rd_party/com/github/masdennis/rajawali/rajawali/maven-metadata-local.xml
@@ -0,0 +1,12 @@
+
+
+ com.github.masdennis.rajawali
+ rajawali
+
+ 1.0.0
+
+ 1.0.0
+
+ 20140704000519
+
+
diff --git a/maven_repo_3rd_party/org/slf4j/slf4j-android/1.5.8/_remote.repositories b/maven_repo_3rd_party/org/slf4j/slf4j-android/1.5.8/_remote.repositories
new file mode 100644
index 0000000..f9fa72a
--- /dev/null
+++ b/maven_repo_3rd_party/org/slf4j/slf4j-android/1.5.8/_remote.repositories
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu Jun 12 15:15:29 CDT 2014
+slf4j-android-1.5.8.jar>=
+slf4j-android-1.5.8.pom>=
diff --git a/maven_repo_3rd_party/org/slf4j/slf4j-android/1.5.8/slf4j-android-1.5.8.jar b/maven_repo_3rd_party/org/slf4j/slf4j-android/1.5.8/slf4j-android-1.5.8.jar
new file mode 100644
index 0000000..e0128bc
Binary files /dev/null and b/maven_repo_3rd_party/org/slf4j/slf4j-android/1.5.8/slf4j-android-1.5.8.jar differ
diff --git a/maven_repo_3rd_party/org/slf4j/slf4j-android/1.5.8/slf4j-android-1.5.8.pom b/maven_repo_3rd_party/org/slf4j/slf4j-android/1.5.8/slf4j-android-1.5.8.pom
new file mode 100644
index 0000000..50c875f
--- /dev/null
+++ b/maven_repo_3rd_party/org/slf4j/slf4j-android/1.5.8/slf4j-android-1.5.8.pom
@@ -0,0 +1,9 @@
+
+
+ 4.0.0
+ org.slf4j
+ slf4j-android
+ 1.5.8
+ POM was created from install:install-file
+
diff --git a/maven_repo_3rd_party/org/slf4j/slf4j-android/1.6.1-RC1/_remote.repositories b/maven_repo_3rd_party/org/slf4j/slf4j-android/1.6.1-RC1/_remote.repositories
new file mode 100644
index 0000000..b076ec5
--- /dev/null
+++ b/maven_repo_3rd_party/org/slf4j/slf4j-android/1.6.1-RC1/_remote.repositories
@@ -0,0 +1,4 @@
+#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice.
+#Thu Jun 12 15:15:52 CDT 2014
+slf4j-android-1.6.1-RC1.jar>=
+slf4j-android-1.6.1-RC1.pom>=
diff --git a/maven_repo_3rd_party/org/slf4j/slf4j-android/1.6.1-RC1/slf4j-android-1.6.1-RC1.jar b/maven_repo_3rd_party/org/slf4j/slf4j-android/1.6.1-RC1/slf4j-android-1.6.1-RC1.jar
new file mode 100644
index 0000000..480348f
Binary files /dev/null and b/maven_repo_3rd_party/org/slf4j/slf4j-android/1.6.1-RC1/slf4j-android-1.6.1-RC1.jar differ
diff --git a/maven_repo_3rd_party/org/slf4j/slf4j-android/1.6.1-RC1/slf4j-android-1.6.1-RC1.pom b/maven_repo_3rd_party/org/slf4j/slf4j-android/1.6.1-RC1/slf4j-android-1.6.1-RC1.pom
new file mode 100644
index 0000000..02f4713
--- /dev/null
+++ b/maven_repo_3rd_party/org/slf4j/slf4j-android/1.6.1-RC1/slf4j-android-1.6.1-RC1.pom
@@ -0,0 +1,9 @@
+
+
+ 4.0.0
+ org.slf4j
+ slf4j-android
+ 1.6.1-RC1
+ POM was created from install:install-file
+
diff --git a/maven_repo_3rd_party/org/slf4j/slf4j-android/maven-metadata-local.xml b/maven_repo_3rd_party/org/slf4j/slf4j-android/maven-metadata-local.xml
new file mode 100644
index 0000000..e2f5e0a
--- /dev/null
+++ b/maven_repo_3rd_party/org/slf4j/slf4j-android/maven-metadata-local.xml
@@ -0,0 +1,13 @@
+
+
+ org.slf4j
+ slf4j-android
+
+ 1.6.1-RC1
+
+ 1.5.8
+ 1.6.1-RC1
+
+ 20140612201552
+
+