Example #1
0
  protected void setDepthFunc(DrawContext dc, OrderedIcon uIcon, Vec4 screenPoint) {
    GL gl = dc.getGL();

    if (uIcon.icon.isAlwaysOnTop()) {
      gl.glDepthFunc(GL.GL_ALWAYS);
      return;
    }

    Position eyePos = dc.getView().getEyePosition();
    if (eyePos == null) {
      gl.glDepthFunc(GL.GL_ALWAYS);
      return;
    }

    double altitude = eyePos.getElevation();
    if (altitude < (dc.getGlobe().getMaxElevation() * dc.getVerticalExaggeration())) {
      double depth = screenPoint.z - (8d * 0.00048875809d);
      depth = depth < 0d ? 0d : (depth > 1d ? 1d : depth);
      gl.glDepthFunc(GL.GL_LESS);
      gl.glDepthRange(depth, depth);
    } else if (uIcon.eyeDistance > uIcon.horizonDistance) {
      gl.glDepthFunc(GL.GL_EQUAL);
      gl.glDepthRange(1d, 1d);
    } else {
      gl.glDepthFunc(GL.GL_ALWAYS);
    }
  }
  /**
   * Draw labels for picking.
   *
   * @param dc Current draw context.
   * @param pickSupport the PickSupport instance to be used.
   */
  protected void doPick(DrawContext dc, PickSupport pickSupport) {
    GL gl = dc.getGL();

    Angle heading = this.rotation;

    double headingDegrees;
    if (heading != null) headingDegrees = heading.degrees;
    else headingDegrees = 0;

    int x = this.screenPoint.x;
    int y = this.screenPoint.y;

    boolean matrixPushed = false;
    try {
      if (headingDegrees != 0) {
        gl.glPushMatrix();
        matrixPushed = true;

        gl.glTranslated(x, y, 0);
        gl.glRotated(headingDegrees, 0, 0, 1);
        gl.glTranslated(-x, -y, 0);
      }

      for (int i = 0; i < this.lines.length; i++) {
        Rectangle2D bounds = this.lineBounds[i];
        double width = bounds.getWidth();
        double height = bounds.getHeight();

        x = this.screenPoint.x;
        if (this.textAlign.equals(AVKey.CENTER)) x = x - (int) (width / 2.0);
        else if (this.textAlign.equals(AVKey.RIGHT)) x = x - (int) width;
        y -= this.lineHeight;

        Color color = dc.getUniquePickColor();
        int colorCode = color.getRGB();
        PickedObject po = new PickedObject(colorCode, this.getPickedObject(), this.position, false);
        pickSupport.addPickableObject(po);

        // Draw line rectangle
        gl.glColor3ub((byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue());

        try {
          gl.glBegin(GL.GL_POLYGON);
          gl.glVertex3d(x, y, 0);
          gl.glVertex3d(x + width - 1, y, 0);
          gl.glVertex3d(x + width - 1, y + height - 1, 0);
          gl.glVertex3d(x, y + height - 1, 0);
          gl.glVertex3d(x, y, 0);
        } finally {
          gl.glEnd();
        }

        y -= this.lineSpacing;
      }
    } finally {
      if (matrixPushed) {
        gl.glPopMatrix();
      }
    }
  }
  /**
   * Establish the OpenGL state needed to draw text.
   *
   * @param dc the current draw context.
   */
  protected void beginDrawing(DrawContext dc) {
    GL gl = dc.getGL();

    int attrMask =
        GL.GL_DEPTH_BUFFER_BIT // for depth test, depth mask and depth func
            | GL.GL_TRANSFORM_BIT // for modelview and perspective
            | GL.GL_VIEWPORT_BIT // for depth range
            | GL.GL_CURRENT_BIT // for current color
            | GL.GL_COLOR_BUFFER_BIT // for alpha test func and ref, and blend
            | GL.GL_DEPTH_BUFFER_BIT // for depth func
            | GL.GL_ENABLE_BIT; // for enable/disable changes

    this.BEogsh.pushAttrib(gl, attrMask);

    if (!dc.isPickingMode()) {
      gl.glEnable(GL.GL_BLEND);
      OGLUtil.applyBlending(gl, false);
    }

    // Do not depth buffer the label. (Labels beyond the horizon are culled above.)
    gl.glDisable(GL.GL_DEPTH_TEST);
    gl.glDepthMask(false);

    // The image is drawn using a parallel projection.
    this.BEogsh.pushProjectionIdentity(gl);
    gl.glOrtho(
        0d, dc.getView().getViewport().width, 0d, dc.getView().getViewport().height, -1d, 1d);

    this.BEogsh.pushModelviewIdentity(gl);
  }
Example #4
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]);
  }
Example #5
0
 // Draw scale rectangle
 private void drawRectangle(DrawContext dc, double width, double height) {
   GL gl = dc.getGL();
   gl.glBegin(GL.GL_POLYGON);
   gl.glVertex3d(0, height, 0);
   gl.glVertex3d(0, 0, 0);
   gl.glVertex3d(width, 0, 0);
   gl.glVertex3d(width, height, 0);
   gl.glVertex3d(0, height, 0);
   gl.glEnd();
 }
  protected void doPick(
      DrawContext dc, Iterable<? extends Renderable> renderables, java.awt.Point pickPoint) {
    this.pickSupport.clearPickList();
    this.pickSupport.beginPicking(dc);

    try {
      for (Renderable renderable : renderables) {
        // If the caller has specified their own Iterable,
        // then we cannot make any guarantees about its contents.
        if (renderable != null) {
          float[] inColor = new float[4];
          dc.getGL().glGetFloatv(GL.GL_CURRENT_COLOR, inColor, 0);
          java.awt.Color color = dc.getUniquePickColor();
          dc.getGL()
              .glColor3ub((byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue());

          try {
            renderable.render(dc);
          } catch (Exception e) {
            String msg = Logging.getMessage("generic.ExceptionWhilePickingRenderable");
            Logging.logger().severe(msg);
            continue; // go on to next renderable
          }

          dc.getGL().glColor4fv(inColor, 0);

          if (renderable instanceof Locatable) {
            this.pickSupport.addPickableObject(
                color.getRGB(), renderable, ((Locatable) renderable).getPosition(), false);
          } else {
            this.pickSupport.addPickableObject(color.getRGB(), renderable);
          }
        }
      }

      this.pickSupport.resolvePick(dc, pickPoint, this);
    } finally {
      this.pickSupport.endPicking(dc);
    }
  }
Example #7
0
 // Draw scale graphic
 private void drawScale(DrawContext dc, double width, double height) {
   GL gl = dc.getGL();
   gl.glBegin(GL.GL_LINE_STRIP);
   gl.glVertex3d(0, height, 0);
   gl.glVertex3d(0, 0, 0);
   gl.glVertex3d(width, 0, 0);
   gl.glVertex3d(width, height, 0);
   gl.glEnd();
   gl.glBegin(GL.GL_LINE_STRIP);
   gl.glVertex3d(width / 2, 0, 0);
   gl.glVertex3d(width / 2, height / 2, 0);
   gl.glEnd();
 }
Example #8
0
  protected void endDrawIcons(DrawContext dc) {
    if (dc.isPickingMode()) this.pickSupport.endPicking(dc);

    GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.

    if (dc.isPickingMode()) {
      gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, OGLUtil.DEFAULT_TEX_ENV_MODE);
      gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_SRC0_RGB, OGLUtil.DEFAULT_SRC0_RGB);
      gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_COMBINE_RGB, OGLUtil.DEFAULT_COMBINE_RGB);
    }

    gl.glBindTexture(GL.GL_TEXTURE_2D, 0);

    this.oglStackHandler.pop(gl);
  }
Example #9
0
  protected void beginDrawIcons(DrawContext dc) {
    GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.

    this.oglStackHandler.clear();

    int attributeMask =
        GL2.GL_DEPTH_BUFFER_BIT // for depth test, depth mask and depth func
            | GL2.GL_TRANSFORM_BIT // for modelview and perspective
            | GL2.GL_VIEWPORT_BIT // for depth range
            | GL2.GL_CURRENT_BIT // for current color
            | GL2.GL_COLOR_BUFFER_BIT // for alpha test func and ref, and blend
            | GL2.GL_DEPTH_BUFFER_BIT // for depth func
            | GL2.GL_ENABLE_BIT; // for enable/disable changes
    this.oglStackHandler.pushAttrib(gl, attributeMask);

    // Apply the depth buffer but don't change it.
    if ((!dc.isDeepPickingEnabled())) gl.glEnable(GL.GL_DEPTH_TEST);
    gl.glDepthMask(false);

    // Suppress any fully transparent image pixels
    gl.glEnable(GL2.GL_ALPHA_TEST);
    gl.glAlphaFunc(GL2.GL_GREATER, 0.001f);

    // Load a parallel projection with dimensions (viewportWidth, viewportHeight)
    this.oglStackHandler.pushProjectionIdentity(gl);
    gl.glOrtho(
        0d, dc.getView().getViewport().width, 0d, dc.getView().getViewport().height, -1d, 1d);

    this.oglStackHandler.pushModelview(gl);
    this.oglStackHandler.pushTexture(gl);

    if (dc.isPickingMode()) {
      this.pickSupport.beginPicking(dc);

      // Set up to replace the non-transparent texture colors with the single pick color.
      gl.glEnable(GL.GL_TEXTURE_2D);
      gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_COMBINE);
      gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_SRC0_RGB, GL2.GL_PREVIOUS);
      gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_COMBINE_RGB, GL2.GL_REPLACE);
    } else {
      gl.glEnable(GL.GL_TEXTURE_2D);
      gl.glEnable(GL.GL_BLEND);
      gl.glBlendFunc(GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA);
    }
  }
  /**
   * Render the label interior as a filled rectangle.
   *
   * @param dc Current draw context.
   */
  protected void drawInterior(DrawContext dc) {
    GL gl = dc.getGL();

    double width = this.bounds.getWidth();
    double height = this.bounds.getHeight();

    int x = this.screenPoint.x;
    int y = this.screenPoint.y;

    // Adjust x to account for text alignment
    int xAligned = x;
    if (AVKey.CENTER.equals(textAlign)) xAligned = x - (int) (width / 2);
    else if (AVKey.RIGHT.equals(textAlign)) xAligned = x - (int) width;

    // We draw text top-down, so adjust y to compensate.
    int yAligned = (int) (y - height);

    // Apply insets
    Insets insets = this.getInsets();
    xAligned -= insets.left;
    width = width + insets.left + insets.right;
    yAligned -= insets.bottom;
    height = height + insets.bottom + insets.top;

    if (!dc.isPickingMode()) {
      // Apply the frame background color and opacity if we're in normal rendering mode.
      Color color = this.computeBackgroundColor(this.getMaterial().getDiffuse());
      gl.glColor4ub(
          (byte) color.getRed(),
          (byte) color.getGreen(),
          (byte) color.getBlue(),
          (byte) (this.interiorOpacity < 1 ? (int) (this.interiorOpacity * 255 + 0.5) : 255));
    }

    try {
      // Draw a quad
      gl.glPushMatrix();
      gl.glTranslated(xAligned, yAligned, 0);
      gl.glScaled(width, height, 1.0);
      dc.drawUnitQuad();
    } finally {
      gl.glPopMatrix();
    }
  }
  /**
   * Draw the label's text. This method sets up the text renderer, and then calls {@link
   * #doDrawText(TextRenderer) doDrawText} to actually draw the text.
   *
   * @param dc Current draw context.
   * @param textRenderer Text renderer.
   */
  protected void drawText(DrawContext dc, TextRenderer textRenderer) {
    GL gl = dc.getGL();

    Angle heading = this.rotation;

    double headingDegrees;
    if (heading != null) headingDegrees = heading.degrees;
    else headingDegrees = 0;

    boolean matrixPushed = false;
    try {
      int x = this.screenPoint.x;
      int y = this.screenPoint.y;

      if (headingDegrees != 0) {
        gl.glPushMatrix();
        matrixPushed = true;

        gl.glTranslated(x, y, 0);
        gl.glRotated(headingDegrees, 0, 0, 1);
        gl.glTranslated(-x, -y, 0);
      }

      if (this.isDrawInterior()) this.drawInterior(dc);

      textRenderer.begin3DRendering();
      try {
        this.doDrawText(textRenderer);

        // Draw other labels that share the same text renderer configuration, if possible.
        if (this.isEnableBatchRendering()) this.drawBatchedText(dc, textRenderer);
      } finally {
        textRenderer.end3DRendering();
      }
    } finally {
      if (matrixPushed) {
        gl.glPopMatrix();
      }
    }
  }
Example #12
0
  protected void drawIcon(DrawContext dc, SurfaceTileDrawContext sdc) {
    if (this.locations == null) return;

    GL gl = dc.getGL();
    gl.glMatrixMode(GL.GL_MODELVIEW);
    double drawScale = 1;
    TextureCoords textureCoords = new TextureCoords(0, 0, 1, 1);

    // Compute draw scale only once if not maintaining strict appearance
    if (!this.isMaintainAppearance()) drawScale = this.computeDrawScale(dc, sdc, null);
    // Determine which locations are to be drawn
    Iterable<? extends LatLon> drawLocations = this.computeDrawLocations(dc, sdc);
    // Draw icons
    for (LatLon location : drawLocations) {
      gl.glPushMatrix();

      if (this.isMaintainAppearance()) drawScale = this.computeDrawScale(dc, sdc, location);
      this.applyDrawTransform(dc, sdc, location, drawScale);
      gl.glScaled(this.imageWidth, this.imageHeight, 1d);
      dc.drawUnitQuad(textureCoords);

      gl.glPopMatrix();
    }
  }
Example #13
0
  protected void applyBackground(
      DrawContext dc,
      WWIcon icon,
      Vec4 screenPoint,
      double width,
      double height,
      double pedestalSpacing,
      double pedestalScale) {
    GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.

    double backgroundScale;
    backgroundScale = icon.getBackgroundScale();

    if (icon.getBackgroundTexture() != null) {
      if (icon.getBackgroundTexture().bind(dc)) {
        TextureCoords texCoords = icon.getBackgroundTexture().getTexCoords();
        gl.glPushMatrix();
        gl.glLoadIdentity();
        double bgwidth = backgroundScale * width;
        double bgheight = backgroundScale * height;
        // Offset the background for the highlighted scale.
        // if (icon.isHighlighted())
        // {
        //    gl.glTranslated(0d, height * (icon.getHighlightScale() - 1) / 2, 0d);
        // }
        // Offset the background for the pedestal height.
        gl.glTranslated(0d, (pedestalScale * height) + pedestalSpacing, 0d);
        // Place the background centered behind the icon.
        gl.glTranslated(screenPoint.x - bgwidth / 2, screenPoint.y - (bgheight - height) / 2, 0d);
        // Scale to the background image dimension.
        gl.glScaled(bgwidth, bgheight, 1d);
        dc.drawUnitQuad(texCoords);
        gl.glPopMatrix();
      }
    }
  }
 /**
  * Pop the state set in beginDrawing.
  *
  * @param dc the current draw context.
  */
 protected void endDrawing(DrawContext dc) {
   this.BEogsh.pop(dc.getGL());
 }
Example #15
0
  protected Vec4 drawIcon(DrawContext dc, OrderedIcon uIcon) {
    if (uIcon.point == null) {
      String msg = Logging.getMessage("nullValue.PointIsNull");
      Logging.logger().severe(msg);

      // Record feedback data for this WWIcon if feedback is enabled.
      if (uIcon.icon != null) this.recordFeedback(dc, uIcon.icon, null, null);

      return null;
    }

    WWIcon icon = uIcon.icon;
    if (dc.getView().getFrustumInModelCoordinates().getNear().distanceTo(uIcon.point) < 0) {
      // Record feedback data for this WWIcon if feedback is enabled.
      this.recordFeedback(dc, icon, uIcon.point, null);

      return null;
    }

    final Vec4 screenPoint = dc.getView().project(uIcon.point);
    if (screenPoint == null) {
      // Record feedback data for this WWIcon if feedback is enabled.
      this.recordFeedback(dc, icon, uIcon.point, null);

      return null;
    }

    double pedestalScale;
    double pedestalSpacing;
    if (this.pedestal != null) {
      pedestalScale = this.pedestal.getScale();
      pedestalSpacing = pedestal.getSpacingPixels();
    } else {
      pedestalScale = 0d;
      pedestalSpacing = 0d;
    }

    GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.

    this.setDepthFunc(dc, uIcon, screenPoint);

    gl.glMatrixMode(GL2.GL_MODELVIEW);
    gl.glLoadIdentity();

    Dimension size = icon.getSize();
    double width = size != null ? size.getWidth() : icon.getImageTexture().getWidth(dc);
    double height = size != null ? size.getHeight() : icon.getImageTexture().getHeight(dc);
    gl.glTranslated(
        screenPoint.x - width / 2, screenPoint.y + (pedestalScale * height) + pedestalSpacing, 0d);

    if (icon.isHighlighted()) {
      double heightDelta = this.pedestal != null ? 0 : height / 2; // expand only above the pedestal
      gl.glTranslated(width / 2, heightDelta, 0);
      gl.glScaled(icon.getHighlightScale(), icon.getHighlightScale(), icon.getHighlightScale());
      gl.glTranslated(-width / 2, -heightDelta, 0);
    }

    Rectangle rect =
        new Rectangle(
            (int) (screenPoint.x - width / 2),
            (int) (screenPoint.y),
            (int) width,
            (int) (height + (pedestalScale * height) + pedestalSpacing));

    if (dc.isPickingMode()) {
      // If in picking mode and pick clipping is enabled, check to see if the icon is within the
      // pick volume.
      if (this.isPickFrustumClippingEnabled() && !dc.getPickFrustums().intersectsAny(rect)) {
        // Record feedback data for this WWIcon if feedback is enabled.
        this.recordFeedback(dc, icon, uIcon.point, rect);

        return screenPoint;
      } else {
        java.awt.Color color = dc.getUniquePickColor();
        int colorCode = color.getRGB();
        this.pickSupport.addPickableObject(colorCode, icon, uIcon.getPosition(), false);
        gl.glColor3ub((byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue());
      }
    }

    if (icon.getBackgroundTexture() != null)
      this.applyBackground(dc, icon, screenPoint, width, height, pedestalSpacing, pedestalScale);

    if (icon.getImageTexture().bind(dc)) {
      TextureCoords texCoords = icon.getImageTexture().getTexCoords();
      gl.glScaled(width, height, 1d);
      dc.drawUnitQuad(texCoords);
    }

    if (this.pedestal != null && this.pedestal.getImageTexture() != null) {
      gl.glLoadIdentity();
      gl.glTranslated(screenPoint.x - (pedestalScale * (width / 2)), screenPoint.y, 0d);
      gl.glScaled(width * pedestalScale, height * pedestalScale, 1d);

      if (this.pedestal.getImageTexture().bind(dc)) {
        TextureCoords texCoords = this.pedestal.getImageTexture().getTexCoords();
        dc.drawUnitQuad(texCoords);
      }
    }

    // Record feedback data for this WWIcon if feedback is enabled.
    this.recordFeedback(dc, icon, uIcon.point, rect);

    return screenPoint;
  }
 @Override
 protected void applyModelviewTransform(DrawContext dc, SurfaceTileDrawContext sdc) {
   // Apply the geographic to surface tile coordinate transform.
   Matrix modelview = sdc.getModelviewMatrix();
   dc.getGL().glMultMatrixd(modelview.toArray(new double[16], 0, false), 0);
 }
Example #17
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);
    }
  }
Example #18
0
  // Rendering
  public void draw(DrawContext dc) {
    GL gl = dc.getGL();

    boolean attribsPushed = false;
    boolean modelviewPushed = false;
    boolean projectionPushed = false;

    try {
      gl.glPushAttrib(
          GL.GL_DEPTH_BUFFER_BIT
              | GL.GL_COLOR_BUFFER_BIT
              | GL.GL_ENABLE_BIT
              | GL.GL_TEXTURE_BIT
              | GL.GL_TRANSFORM_BIT
              | GL.GL_VIEWPORT_BIT
              | GL.GL_CURRENT_BIT);
      attribsPushed = true;

      gl.glDisable(GL.GL_TEXTURE_2D); // no textures

      gl.glEnable(GL.GL_BLEND);
      gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
      gl.glDisable(GL.GL_DEPTH_TEST);

      double width = this.size.width;
      double height = this.size.height;

      // Load a parallel projection with xy dimensions (viewportWidth, viewportHeight)
      // into the GL projection matrix.
      java.awt.Rectangle viewport = dc.getView().getViewport();
      gl.glMatrixMode(javax.media.opengl.GL.GL_PROJECTION);
      gl.glPushMatrix();
      projectionPushed = true;
      gl.glLoadIdentity();
      double maxwh = width > height ? width : height;
      gl.glOrtho(0d, viewport.width, 0d, viewport.height, -0.6 * maxwh, 0.6 * maxwh);

      gl.glMatrixMode(GL.GL_MODELVIEW);
      gl.glPushMatrix();
      modelviewPushed = true;
      gl.glLoadIdentity();

      // Scale to a width x height space
      // located at the proper position on screen
      double scale = this.computeScale(viewport);
      Vec4 locationSW = this.computeLocation(viewport, scale);
      gl.glTranslated(locationSW.x(), locationSW.y(), locationSW.z());
      gl.glScaled(scale, scale, 1);

      // Compute scale size in real world
      Position referencePosition = dc.getViewportCenterPosition();
      if (referencePosition != null) {
        Vec4 groundTarget = dc.getGlobe().computePointFromPosition(referencePosition);
        Double distance = dc.getView().getEyePoint().distanceTo3(groundTarget);
        this.pixelSize = dc.getView().computePixelSizeAtDistance(distance);
        Double scaleSize = this.pixelSize * width * scale; // meter
        String unitLabel = "m";
        if (this.unit.equals(UNIT_METRIC)) {
          if (scaleSize > 10000) {
            scaleSize /= 1000;
            unitLabel = "Km";
          }
        } else if (this.unit.equals(UNIT_IMPERIAL)) {
          scaleSize *= 3.280839895; // feet
          unitLabel = "ft";
          if (scaleSize > 5280) {
            scaleSize /= 5280;
            unitLabel = "mile(s)";
          }
        }

        // Rounded division size
        int pot = (int) Math.floor(Math.log10(scaleSize));
        if (!Double.isNaN(pot)) {
          int digit = Integer.parseInt(String.format("%.0f", scaleSize).substring(0, 1));
          double divSize = digit * Math.pow(10, pot);
          if (digit >= 5) divSize = 5 * Math.pow(10, pot);
          else if (digit >= 2) divSize = 2 * Math.pow(10, pot);
          double divWidth = width * divSize / scaleSize;

          // Draw scale
          if (!dc.isPickingMode()) {
            // Set color using current layer opacity
            Color backColor = this.getBackgroundColor(this.color);
            float[] colorRGB = backColor.getRGBColorComponents(null);
            gl.glColor4d(
                colorRGB[0],
                colorRGB[1],
                colorRGB[2],
                (double) backColor.getAlpha() / 255d * this.getOpacity());
            gl.glTranslated((width - divWidth) / 2, 0d, 0d);
            this.drawScale(dc, divWidth, height);

            colorRGB = this.color.getRGBColorComponents(null);
            gl.glColor4d(colorRGB[0], colorRGB[1], colorRGB[2], this.getOpacity());
            gl.glTranslated(-1d / scale, 1d / scale, 0d);
            this.drawScale(dc, divWidth, height);

            // Draw label
            String label = String.format("%.0f ", divSize) + unitLabel;
            gl.glLoadIdentity();
            gl.glDisable(GL.GL_CULL_FACE);
            drawLabel(
                dc,
                label,
                locationSW.add3(
                    new Vec4(divWidth * scale / 2 + (width - divWidth) / 2, height * scale, 0)));
          } else {
            // Picking
            this.pickSupport.clearPickList();
            this.pickSupport.beginPicking(dc);
            // Draw unique color across the map
            Color color = dc.getUniquePickColor();
            int colorCode = color.getRGB();
            // Add our object(s) to the pickable list
            this.pickSupport.addPickableObject(colorCode, this, referencePosition, false);
            gl.glColor3ub((byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue());
            gl.glTranslated((width - divWidth) / 2, 0d, 0d);
            this.drawRectangle(dc, divWidth, height);
            // Done picking
            this.pickSupport.endPicking(dc);
            this.pickSupport.resolvePick(dc, dc.getPickPoint(), this);
          }
        }
      }
    } finally {
      if (projectionPushed) {
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glPopMatrix();
      }
      if (modelviewPushed) {
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glPopMatrix();
      }
      if (attribsPushed) gl.glPopAttrib();
    }
  }