Ejemplo n.º 1
0
  protected void initializeTexture(DrawContext dc) {
    Texture iconTexture = dc.getTextureCache().getTexture(this.getIconFilePath());
    if (iconTexture != null) return;

    try {
      InputStream iconStream = this.getClass().getResourceAsStream("/" + this.getIconFilePath());
      if (iconStream == null) {
        File iconFile = new File(this.iconFilePath);
        if (iconFile.exists()) {
          iconStream = new FileInputStream(iconFile);
        }
      }

      iconTexture = TextureIO.newTexture(iconStream, false, null);
      iconTexture.bind();
      this.iconWidth = iconTexture.getWidth();
      this.iconHeight = iconTexture.getHeight();
      dc.getTextureCache().put(this.getIconFilePath(), iconTexture);
    } catch (IOException e) {
      String msg = Logging.getMessage("layers.IOExceptionDuringInitialization");
      Logging.logger().severe(msg);
      throw new WWRuntimeException(msg, e);
    }

    GL gl = dc.getGL();
    gl.glTexParameteri(
        GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); // _MIPMAP_LINEAR);
    gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
    gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
    gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
    // Enable texture anisotropy, improves "tilted" world map quality.
    int[] maxAnisotropy = new int[1];
    gl.glGetIntegerv(GL.GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy, 0);
    gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy[0]);
  }
  private void loadAllTopLevelTextures(DrawContext dc) {
    for (MercatorTextureTile tile : this.topLevels) {
      if (!tile.isTextureInMemory(dc.getTextureCache())) this.forceTextureLoad(tile);
    }

    this.levelZeroLoaded = true;
  }
  private void addTile(DrawContext dc, MercatorTextureTile tile) {
    tile.setFallbackTile(null);

    if (tile.isTextureInMemory(dc.getTextureCache())) {
      //            System.out.printf("Sector %s, min = %f, max = %f\n", tile.getSector(),
      //                dc.getGlobe().getMinElevation(tile.getSector()),
      // dc.getGlobe().getMaxElevation(tile.getSector()));
      this.addTileToCurrent(tile);
      return;
    }

    // Level 0 loads may be forced
    if (tile.getLevelNumber() == 0
        && this.forceLevelZeroLoads
        && !tile.isTextureInMemory(dc.getTextureCache())) {
      this.forceTextureLoad(tile);
      if (tile.isTextureInMemory(dc.getTextureCache())) {
        this.addTileToCurrent(tile);
        return;
      }
    }

    // Tile's texture isn't available, so request it
    if (tile.getLevelNumber() < this.levels.getNumLevels()) {
      // Request only tiles with data associated at this level
      if (!this.levels.isResourceAbsent(tile)) this.requestTexture(dc, tile);
    }

    // Set up to use the currentResource tile's texture
    if (this.currentResourceTile != null) {
      if (this.currentResourceTile.getLevelNumber() == 0
          && this.forceLevelZeroLoads
          && !this.currentResourceTile.isTextureInMemory(dc.getTextureCache())
          && !this.currentResourceTile.isTextureInMemory(dc.getTextureCache()))
        this.forceTextureLoad(this.currentResourceTile);

      if (this.currentResourceTile.isTextureInMemory(dc.getTextureCache())) {
        tile.setFallbackTile(currentResourceTile);
        this.addTileToCurrent(tile);
      }
    }
  }
  private void addTileOrDescendants(DrawContext dc, MercatorTextureTile tile) {
    if (this.meetsRenderCriteria(dc, tile)) {
      this.addTile(dc, tile);
      return;
    }

    // The incoming tile does not meet the rendering criteria, so it must be subdivided and those
    // subdivisions tested against the criteria.

    // All tiles that meet the selection criteria are drawn, but some of those tiles will not have
    // textures associated with them either because their texture isn't loaded yet or because they
    // are finer grain than the layer has textures for. In these cases the tiles use the texture of
    // the closest ancestor that has a texture loaded. This ancestor is called the
    // currentResourceTile.
    // A texture transform is applied during rendering to align the sector's texture coordinates
    // with the
    // appropriate region of the ancestor's texture.

    MercatorTextureTile ancestorResource = null;

    try {
      // TODO: Revise this to reflect that the parent layer is only requested while the algorithm
      // continues
      // to search for the layer matching the criteria.
      // At this point the tile does not meet the render criteria but it may have its texture in
      // memory.
      // If so, register this tile as the resource tile. If not, then this tile will be the next
      // level
      // below a tile with texture in memory. So to provide progressive resolution increase, add
      // this tile
      // to the draw list. That will cause the tile to be drawn using its parent tile's texture, and
      // it will
      // cause it's texture to be requested. At some future call to this method the tile's texture
      // will be in
      // memory, it will not meet the render criteria, but will serve as the parent to a tile that
      // goes
      // through this same process as this method recurses. The result of all this is that a tile
      // isn't rendered
      // with its own texture unless all its parents have their textures loaded. In addition to
      // causing
      // progressive resolution increase, this ensures that the parents are available as the user
      // zooms out, and
      // therefore the layer remains visible until the user is zoomed out to the point the layer is
      // no longer
      // active.
      if (tile.isTextureInMemory(dc.getTextureCache()) || tile.getLevelNumber() == 0) {
        ancestorResource = this.currentResourceTile;
        this.currentResourceTile = tile;
      } else if (!tile.getLevel().isEmpty()) {
        //                this.addTile(dc, tile);
        //                return;

        // Issue a request for the parent before descending to the children.
        if (tile.getLevelNumber() < this.levels.getNumLevels()) {
          // Request only tiles with data associated at this level
          if (!this.levels.isResourceAbsent(tile)) this.requestTexture(dc, tile);
        }
      }

      MercatorTextureTile[] subTiles =
          tile.createSubTiles(this.levels.getLevel(tile.getLevelNumber() + 1));
      for (MercatorTextureTile child : subTiles) {
        if (this.isTileVisible(dc, child)) this.addTileOrDescendants(dc, child);
      }
    } finally {
      if (ancestorResource != null) // Pop this tile as the currentResource ancestor
      this.currentResourceTile = ancestorResource;
    }
  }
Ejemplo n.º 5
0
  protected void drawIcon(DrawContext dc) {
    if (this.getIconFilePath() == null) return;

    GL gl = dc.getGL();
    OGLStackHandler ogsh = new OGLStackHandler();

    try {
      // Initialize texture if necessary
      Texture iconTexture = dc.getTextureCache().getTexture(this.getIconFilePath());
      if (iconTexture == null) {
        this.initializeTexture(dc);
        iconTexture = dc.getTextureCache().getTexture(this.getIconFilePath());
        if (iconTexture == null) {
          String msg = Logging.getMessage("generic.ImageReadFailed");
          Logging.logger().finer(msg);
          return;
        }
      }
      gl.glDisable(GL.GL_DEPTH_TEST);

      double width = this.getScaledIconWidth();
      double height = this.getScaledIconHeight();

      // Load a parallel projection with xy dimensions (viewportWidth, viewportHeight)
      // into the GL projection matrix.
      java.awt.Rectangle viewport = dc.getView().getViewport();
      ogsh.pushProjectionIdentity(gl);
      double maxwh = width > height ? width : height;
      gl.glOrtho(0d, viewport.width, 0d, viewport.height, -0.6 * maxwh, 0.6 * maxwh);

      // Translate and scale
      ogsh.pushModelviewIdentity(gl);
      double scale = this.computeScale(viewport);
      Vec4 locationSW = this.computeLocation(viewport, scale);
      gl.glTranslated(locationSW.x(), locationSW.y(), locationSW.z());
      // Scale to 0..1 space
      gl.glScaled(scale, scale, 1);
      gl.glScaled(width, height, 1d);

      if (!dc.isPickingMode()) {
        gl.glEnable(GL.GL_BLEND);
        gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);

        // Draw background color behind the map
        gl.glColor4ub(
            (byte) this.backColor.getRed(),
            (byte) this.backColor.getGreen(),
            (byte) this.backColor.getBlue(),
            (byte) (this.backColor.getAlpha() * this.getOpacity()));
        dc.drawUnitQuad();

        // Draw world map icon
        gl.glColor4d(1d, 1d, 1d, this.getOpacity());
        gl.glEnable(GL.GL_TEXTURE_2D);
        iconTexture.bind();

        TextureCoords texCoords = iconTexture.getImageTexCoords();
        dc.drawUnitQuad(texCoords);
        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
        gl.glDisable(GL.GL_TEXTURE_2D);

        // Draw crosshair for current location
        gl.glLoadIdentity();
        gl.glTranslated(locationSW.x(), locationSW.y(), locationSW.z());
        // Scale to width x height space
        gl.glScaled(scale, scale, 1);
        // Set color
        float[] colorRGB = this.color.getRGBColorComponents(null);
        gl.glColor4d(colorRGB[0], colorRGB[1], colorRGB[2], this.getOpacity());

        // Draw crosshair
        Position groundPos = this.computeGroundPosition(dc, dc.getView());
        if (groundPos != null) {
          int x = (int) (width * (groundPos.getLongitude().degrees + 180) / 360);
          int y = (int) (height * (groundPos.getLatitude().degrees + 90) / 180);
          int w = 10; // cross branch length
          // Draw
          gl.glBegin(GL.GL_LINE_STRIP);
          gl.glVertex3d(x - w, y, 0);
          gl.glVertex3d(x + w + 1, y, 0);
          gl.glEnd();
          gl.glBegin(GL.GL_LINE_STRIP);
          gl.glVertex3d(x, y - w, 0);
          gl.glVertex3d(x, y + w + 1, 0);
          gl.glEnd();
        }

        // Draw view footprint in map icon space
        if (this.showFootprint) {
          this.footPrintPositions = this.computeViewFootPrint(dc, 32);
          if (this.footPrintPositions != null) {
            gl.glBegin(GL.GL_LINE_STRIP);
            LatLon p1 = this.footPrintPositions.get(0);
            for (LatLon p2 : this.footPrintPositions) {
              int x = (int) (width * (p2.getLongitude().degrees + 180) / 360);
              int y = (int) (height * (p2.getLatitude().degrees + 90) / 180);
              // Draw
              if (LatLon.locationsCrossDateline(p1, p2)) {
                int y1 = (int) (height * (p1.getLatitude().degrees + 90) / 180);
                gl.glVertex3d(x < width / 2 ? width : 0, (y1 + y) / 2, 0);
                gl.glEnd();
                gl.glBegin(GL.GL_LINE_STRIP);
                gl.glVertex3d(x < width / 2 ? 0 : width, (y1 + y) / 2, 0);
              }
              gl.glVertex3d(x, y, 0);
              p1 = p2;
            }
            gl.glEnd();
          }
        }
        // Draw 1px border around and inside the map
        gl.glBegin(GL.GL_LINE_STRIP);
        gl.glVertex3d(0, 0, 0);
        gl.glVertex3d(width, 0, 0);
        gl.glVertex3d(width, height - 1, 0);
        gl.glVertex3d(0, height - 1, 0);
        gl.glVertex3d(0, 0, 0);
        gl.glEnd();
      } else {
        // Picking
        this.pickSupport.clearPickList();
        this.pickSupport.beginPicking(dc);
        // Where in the world are we picking ?
        Position pickPosition =
            computePickPosition(
                dc, locationSW, new Dimension((int) (width * scale), (int) (height * scale)));
        Color color = dc.getUniquePickColor();
        int colorCode = color.getRGB();
        this.pickSupport.addPickableObject(colorCode, this, pickPosition, false);
        gl.glColor3ub((byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue());
        dc.drawUnitQuad();
        this.pickSupport.endPicking(dc);
        this.pickSupport.resolvePick(dc, dc.getPickPoint(), this);
      }
    } finally {
      dc.restoreDefaultDepthTesting();
      dc.restoreDefaultCurrentColor();
      if (dc.isPickingMode()) dc.restoreDefaultBlending();
      ogsh.pop(gl);
    }
  }