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 + + + + +