📄 tiledsurfaceobjectrenderer.java
字号:
/* Copyright (C) 2001, 2009 United States Government as represented bythe Administrator of the National Aeronautics and Space Administration.All Rights Reserved.*/package gov.nasa.worldwind.render;import com.sun.opengl.util.texture.*;import gov.nasa.worldwind.View;import gov.nasa.worldwind.avlist.*;import gov.nasa.worldwind.geom.*;import gov.nasa.worldwind.globes.Globe;import gov.nasa.worldwind.layers.*;import gov.nasa.worldwind.pick.*;import gov.nasa.worldwind.terrain.SectorGeometryList;import gov.nasa.worldwind.util.*;import javax.media.opengl.GL;/** * @author dcollins * @version $Id: TiledSurfaceShapeRenderer.java 9992 2009-04-08 04:38:54Z dcollins $ */public class TiledSurfaceObjectRenderer{ // Default attribute values. protected static final LatLon DEFAULT_TILE_DELTA = LatLon.fromDegrees(36, 36); protected static final Sector DEFAULT_SECTOR = Sector.FULL_SPHERE; protected static final int DEFAULT_NUM_LEVELS = 17; protected static final int DEFAULT_NUM_EMPTY_LEVELS = 0; protected static final int DEFAULT_TILE_WIDTH = 512; protected static final int DEFAULT_TILE_HEIGHT = 512; protected static final boolean DEFAULT_PICK_ENABLED = false; protected static final boolean DEFAULT_USE_MIPMAPS = false; // Default with a ratio of 1.5 surface tile texels to 1 screen pixel. This has been emperically determined to // produce good looking results with the standard class of SurfaceShapes such as SurfacePolygon. protected static final double DEFAULT_TEXEL_TO_PIXEL_RATIO = 1.5; protected static final java.awt.Color DEFAULT_TILE_BACKGROUND_COLOR = new java.awt.Color(0, 0, 0, 0); protected static final boolean DEFAULT_SHOW_TILE_OUTLINES = false; protected static final String DEFAULT_TILE_COUNT_NAME = "Surface Object Tiles"; protected static long uniqueId = 1; protected Iterable<? extends SurfaceObject> surfaceObjectIterable; protected LevelSet levelSet; protected boolean pickEnabled; protected boolean useMipmaps; protected double texelToPixelRatio; protected java.awt.Color tileBackgroundColor; // State computed in each rendering pass. protected java.util.List<SurfaceObjectInfo> currentSurfaceObjects; protected java.util.List<TextureTile> currentTiles; protected java.util.Map<TileKey, SurfaceObjectState> tileStateMap; protected Sector currentBoundingSector; protected java.awt.Rectangle currentTileViewport; protected PickTile pickTile; protected boolean havePickTile; // Rendering support components. protected PickSupport pickSupport = new PickSupport(); protected OGLOrtho2DSupport renderToTextureSupport = new OGLOrtho2DSupport(); // Rendering diagnostic attrbiutes protected boolean showTileOutlines; protected String tileCountName; public TiledSurfaceObjectRenderer(LevelSet levelSet) { if (levelSet == null) { String message = Logging.getMessage("nullValue.LevelSetIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } this.levelSet = levelSet; this.useMipmaps = DEFAULT_USE_MIPMAPS; this.tileBackgroundColor = DEFAULT_TILE_BACKGROUND_COLOR; this.texelToPixelRatio = DEFAULT_TEXEL_TO_PIXEL_RATIO; this.currentSurfaceObjects = new java.util.ArrayList<SurfaceObjectInfo>(); this.currentTiles = new java.util.ArrayList<TextureTile>(); this.tileStateMap = new java.util.HashMap<TileKey, SurfaceObjectState>(); this.pickTile = new PickTile(Sector.EMPTY_SECTOR); this.showTileOutlines = DEFAULT_SHOW_TILE_OUTLINES; this.tileCountName = DEFAULT_TILE_COUNT_NAME; } public TiledSurfaceObjectRenderer(AVList params) { this(new LevelSet(initParams(params))); } public TiledSurfaceObjectRenderer() { this(new AVListImpl()); } protected static AVList initParams(AVList params) { if (params == null) { String message = Logging.getMessage("nullValue.ParamsIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } Object o; Object cacheId = null; o = params.getValue(AVKey.LEVEL_ZERO_TILE_DELTA); if (o == null || !(o instanceof LatLon)) params.setValue(AVKey.LEVEL_ZERO_TILE_DELTA, DEFAULT_TILE_DELTA); o = params.getValue(AVKey.SECTOR); if (o == null || !(o instanceof LatLon)) params.setValue(AVKey.SECTOR, DEFAULT_SECTOR); o = params.getValue(AVKey.NUM_LEVELS); if (o == null || !(o instanceof Integer)) params.setValue(AVKey.NUM_LEVELS, DEFAULT_NUM_LEVELS); o = params.getValue(AVKey.NUM_EMPTY_LEVELS); if (o == null || !(o instanceof Integer)) params.setValue(AVKey.NUM_EMPTY_LEVELS, DEFAULT_NUM_EMPTY_LEVELS); o = params.getValue(AVKey.TILE_WIDTH); if (o == null || !(o instanceof Integer)) params.setValue(AVKey.TILE_WIDTH, DEFAULT_TILE_WIDTH); o = params.getValue(AVKey.TILE_HEIGHT); if (o == null || !(o instanceof Integer)) params.setValue(AVKey.TILE_HEIGHT, DEFAULT_TILE_HEIGHT); o = params.getValue(AVKey.DATA_CACHE_NAME); if (o == null) { //noinspection ConstantConditions if (cacheId == null) { cacheId = createUniqueCacheId(); } params.setValue(AVKey.DATA_CACHE_NAME, cacheId); } o = params.getValue(AVKey.DATASET_NAME); if (o == null) { if (cacheId == null) { cacheId = createUniqueCacheId(); } params.setValue(AVKey.DATASET_NAME, cacheId); } // We won't use any tile resource paths, so just supply a dummy format suffix. o = params.getValue(AVKey.FORMAT_SUFFIX); if (o == null) params.setValue(AVKey.FORMAT_SUFFIX, ".xyz"); return params; } protected static String createUniqueCacheId() { StringBuilder sb = new StringBuilder(); sb.append(TiledSurfaceObjectRenderer.class.getName()); sb.append("/"); sb.append(nextUniqueId()); return sb.toString(); } protected static long nextUniqueId() { return uniqueId++; } public boolean isPickEnabled() { return this.pickEnabled; } public void setPickEnabled(boolean enabled) { this.pickEnabled = enabled; } public boolean isUseMipmaps() { return this.useMipmaps; } public void setUseMipmaps(boolean useMipmaps) { this.useMipmaps = useMipmaps; } /** * Returns the surface object texel to screen pixel ratio. See {#link蕇etPixelToTexelRatio(double} for a description * of this value's meaning. * * @return surface object texel to screen pixel ratio. */ public double getTexelToPixelRatio() { return this.texelToPixelRatio; } /** * Sets the surface object texel to screen pixel ratio. * <ul> * <li> * If <code>ratio</code> is 1, the renderer will attempt to create tiles whose texels have approximately the same * size as a screen pixel. * </li> * <li> * If <code>ratio</code> is less than 1, the renderer will attempt to create tiles whose texels are smaller than * a screen pixel. For example, specifying ratio=0.5 indicates that a surface object texel should be half the size * of a screen pixel. * </li> * <li> * If <code>ratio</code> is greater than 1, the renderer will attempt to create tiles whose texels are larger than * a screen pixel. For example, specifying ratio=2 indicates that a surface object texel should be twice the size of * a screen pixel. * * @param ratio surface object texel to screen pixel ratio. * * @throws IllegalArgumentException if <code>ratio</code> is less than or equal to zero. */ public void setTexelToPixelRatio(double ratio) { if (ratio <= 0) { String message = Logging.getMessage("generic.ArgumentOutOfRange", "ratio <= 0"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } this.texelToPixelRatio = ratio; } public java.awt.Color getTileBackgroundColor() { return this.tileBackgroundColor; } public void setTileBackgroundColor(java.awt.Color color) { if (color == null) { String message = Logging.getMessage("nullValue.ColorIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } this.tileBackgroundColor = color; } public boolean isShowTileOutlines() { return this.showTileOutlines; } public void setShowTileOutlines(boolean show) { this.showTileOutlines = show; } public Iterable<? extends SurfaceObject> getSurfaceObjects() { return this.surfaceObjectIterable; } public void setSurfaceObjects(Iterable<? extends SurfaceObject> objects) { this.surfaceObjectIterable = objects; } public void preRender(DrawContext dc) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (this.surfaceObjectIterable == null) return; java.awt.Rectangle lastTileViewport = this.currentTileViewport; this.currentTileViewport = this.computeTileViewport(dc); // If the last viewport used to update the tiles is not equal to the current viewport, then invalidate the // current tile state, which will force all tiles to update regardless of whether their content has changed. if (lastTileViewport != null && !lastTileViewport.equals(this.currentTileViewport)) { this.clearAllTileState(); } this.clearSurfaceObjects(dc); this.clearTiles(dc); this.assembleSurfaceObjects(dc); this.assembleTiles(dc); this.updateTiles(dc); } public void render(DrawContext dc) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (this.surfaceObjectIterable == null) return; this.draw(dc, false); } public void pick(DrawContext dc, java.awt.Point pickPoint, Layer layer) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (this.surfaceObjectIterable == null) return; if (!this.pickEnabled) return; this.pickSupport.beginPicking(dc); try { this.draw(dc, true); } finally { this.pickSupport.endPicking(dc); } this.resolvePick(dc, pickPoint, layer); this.pickSupport.clearPickList(); } protected java.awt.Rectangle computeTileViewport(DrawContext dc) { // Compute the smallest dimension of level set tile or pick tile. int minSize = Integer.MAX_VALUE; for (Level level : this.levelSet.getLevels()) { if (minSize > level.getTileWidth()) minSize = level.getTileWidth(); if (minSize > level.getTileHeight()) minSize = level.getTileHeight(); } if (this.pickEnabled && this.havePickTile) { if (minSize > this.pickTile.getPreferredWidth()) minSize = this.pickTile.getPreferredWidth(); if (minSize > this.pickTile.getPreferredHeight()) minSize = this.pickTile.getPreferredHeight(); } // The viewport may be smaller than the desired dimensions. For that reason, we constrain the desired // dimensions by the viewport. java.awt.Rectangle viewport = dc.getView().getViewport(); if (minSize > viewport.width) minSize = viewport.width; if (minSize > viewport.height) minSize = viewport.height; // The final dimension used to render all surface tiles will be the smallest square dimension which fits into // the viewport. int size = WWMath.powerOfTwoFloor(minSize); return new java.awt.Rectangle(viewport.x, viewport.y, size, size); } //**************************************************************// //******************** Tile Rendering ************************// //**************************************************************// protected void draw(DrawContext dc, boolean isPickCall) { if (this.currentTiles.isEmpty()) return; OGLStackHandler stackHandler = new OGLStackHandler(); this.beginRendering(dc, stackHandler); try { this.drawTiles(dc, isPickCall); } finally { this.endRendering(dc, stackHandler); } } protected void drawTiles(DrawContext dc, boolean isPickCall) { if (isPickCall) { this.drawPickTiles(dc); } else { this.drawRenderTiles(dc); } } protected void drawRenderTiles(DrawContext dc) { dc.getGeographicSurfaceTileRenderer().setShowImageTileOutlines(this.showTileOutlines); dc.getGeographicSurfaceTileRenderer().renderTiles(dc, this.currentTiles); } protected void drawPickTiles(DrawContext dc) { // The surface object pick colors are rendered into the pickTile's texture during the preRender stage. We must // therefore render the pickTile's texture as though it was a typical RGBA texture, although the colors are // all pick colors or transparent black. Note that blending must be enabled to keep the transparent regions // from obscuring other pick colors. if (!this.havePickTile) return; boolean isPickingMode = dc.isPickingMode(); if (isPickingMode) { dc.disablePickingMode(); } dc.getGeographicSurfaceTileRenderer().setShowImageTileOutlines(false); dc.getGeographicSurfaceTileRenderer().renderTile(dc, this.pickTile); if (isPickingMode) { dc.enablePickingMode(); } } protected void beginRendering(DrawContext dc, OGLStackHandler stackHandler) { GL gl = dc.getGL();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -