protected void drawToolTip(
      DrawContext dc,
      java.awt.Rectangle viewport,
      String text,
      int x,
      int y,
      ToolTipAttributes attributes) {
    java.awt.geom.Rectangle2D textBounds = this.computeTextBounds(dc, text, attributes.getFont());
    java.awt.geom.Rectangle2D bgBounds =
        this.computeBackgroundBounds(
            dc, textBounds.getWidth(), textBounds.getHeight(), attributes.getInsets());

    java.awt.Point screenPoint = this.adjustDrawPointToViewport(x, y, bgBounds, viewport);
    java.awt.geom.Point2D textTranslation =
        this.computeTextTranslation(dc, textBounds, attributes.getInsets());

    GL2 gl = dc.getGL();
    OGLStackHandler stackHandler = new OGLStackHandler();

    stackHandler.pushModelview(gl);
    try {
      gl.glTranslated(
          screenPoint.getX() + bgBounds.getX(), screenPoint.getY() + bgBounds.getY(), 0);
      this.drawToolTipInterior(dc, bgBounds.getWidth(), bgBounds.getHeight(), attributes);
      this.drawToolTipOutline(dc, bgBounds.getWidth(), bgBounds.getHeight(), attributes);

      gl.glTranslated(textTranslation.getX(), textTranslation.getY(), 0);
      this.drawToolTipText(dc, text, 0, 0, attributes);
    } finally {
      stackHandler.pop(gl);
    }
  }
  protected void endRendering(DrawContext dc, OGLStackHandler stackHandler) {
    if (dc == null) {
      String message = Logging.getMessage("nullValue.DrawContextIsNull");
      Logging.logger().fine(message);
      throw new IllegalArgumentException(message);
    }

    GL2 gl = dc.getGL();

    stackHandler.pop(gl);
  }
  protected void beginRendering(DrawContext dc, OGLStackHandler stackHandler) {
    if (dc == null) {
      String message = Logging.getMessage("nullValue.DrawContextIsNull");
      Logging.logger().fine(message);
      throw new IllegalArgumentException(message);
    }

    GL2 gl = dc.getGL();

    int attribMask =
        GL2.GL_COLOR_BUFFER_BIT // for alpha test func and ref, blend func
            | GL2.GL_CURRENT_BIT // for current color
            | GL2.GL_ENABLE_BIT // for enable/disable
            | GL2.GL_LINE_BIT // for line width
            | GL2.GL_TRANSFORM_BIT; // for matrix mode
    stackHandler.pushAttrib(gl, attribMask);

    stackHandler.pushTextureIdentity(gl);
    stackHandler.pushProjectionIdentity(gl);
    java.awt.Rectangle viewport = dc.getView().getViewport();
    gl.glOrtho(
        viewport.x, viewport.x + viewport.width, viewport.y, viewport.y + viewport.height, -1, 1);
    stackHandler.pushModelviewIdentity(gl);

    // Enable the alpha test.
    gl.glEnable(GL2.GL_ALPHA_TEST);
    gl.glAlphaFunc(GL2.GL_GREATER, 0.0f);

    // Enable blending in premultiplied color mode.
    gl.glEnable(GL2.GL_BLEND);
    OGLUtil.applyBlending(gl, true);

    gl.glDisable(GL2.GL_CULL_FACE);
    gl.glDisable(GL2.GL_DEPTH_TEST);
    gl.glDisable(GL2.GL_LIGHTING);
    gl.glDisable(GL2.GL_TEXTURE_2D);
  }
  @Override
  public void draw(IDelegateView view, DrawContext dc, DrawableSceneController sc) {
    GL2 gl = dc.getGL().getGL2();
    init(gl);

    if (distortionShader.isCreationFailed()) {
      view.draw(dc, sc);
      return;
    }

    Rectangle oldViewport = view.getViewport();

    hmd.beginFrameTiming(++frameCount);
    {
      Posef[] eyePoses = hmd.getEyePoses(frameCount, eyeOffsets);
      // RiftLogger.logPose(eyePoses);

      renderEyes = true;
      frameBuffer.bind(gl);
      {
        sc.clearFrame(dc);

        for (int i = 0; i < ovrEye_Count; i++) {
          int eye = hmd.EyeRenderOrder[i];
          Posef pose = eyePoses[eye];
          this.eyePoses[eye].Orientation = pose.Orientation;
          this.eyePoses[eye].Position = pose.Position;

          this.eye = eye;

          gl.glViewport(
              eyeRenderViewport[eye].Pos.x,
              eyeRenderViewport[eye].Pos.y,
              eyeRenderViewport[eye].Size.w,
              eyeRenderViewport[eye].Size.h);

          sc.applyView(dc);
          sc.draw(dc);
        }
      }
      frameBuffer.unbind(gl);
      renderEyes = false;

      OGLStackHandler oglsh = new OGLStackHandler();
      oglsh.pushAttrib(gl, GL2.GL_ENABLE_BIT);
      oglsh.pushClientAttrib(gl, GL2.GL_CLIENT_VERTEX_ARRAY_BIT);
      try {
        gl.glViewport(0, 0, hmd.Resolution.w, hmd.Resolution.h);
        gl.glDisable(GL2.GL_DEPTH_TEST);

        gl.glEnable(GL2.GL_TEXTURE_2D);
        gl.glActiveTexture(GL2.GL_TEXTURE0);
        gl.glBindTexture(GL2.GL_TEXTURE_2D, frameBuffer.getTexture().getId());
        for (int eyeNum = 0; eyeNum < ovrEye_Count; eyeNum++) {
          OvrMatrix4f[] timeWarpMatricesRowMajor = new OvrMatrix4f[2];
          hmd.getEyeTimewarpMatrices(eyeNum, eyePoses[eyeNum], timeWarpMatricesRowMajor);
          distortionShader.use(
              gl,
              uvScaleOffset[eyeNum][0].x,
              -uvScaleOffset[eyeNum][0].y,
              uvScaleOffset[eyeNum][1].x,
              1 - uvScaleOffset[eyeNum][1].y,
              timeWarpMatricesRowMajor[0].M,
              timeWarpMatricesRowMajor[1].M);

          gl.glClientActiveTexture(GL2.GL_TEXTURE0);
          gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
          gl.glEnableClientState(GL2.GL_TEXTURE_COORD_ARRAY);
          gl.glEnableClientState(GL2.GL_COLOR_ARRAY);

          gl.glBindBuffer(
              GL2.GL_ARRAY_BUFFER, distortionObjects[eyeNum][DistortionObjects.vbo.ordinal()]);
          {
            int stride = 10 * 4;
            gl.glVertexPointer(4, GL2.GL_FLOAT, stride, 0);
            gl.glTexCoordPointer(2, GL2.GL_FLOAT, stride, 4 * 4);
            gl.glColorPointer(4, GL2.GL_FLOAT, stride, 6 * 4);

            gl.glBindBuffer(
                GL2.GL_ELEMENT_ARRAY_BUFFER,
                distortionObjects[eyeNum][DistortionObjects.ibo.ordinal()]);
            {
              gl.glDrawElements(GL2.GL_TRIANGLES, indicesCount, GL2.GL_UNSIGNED_INT, 0);
            }
            gl.glBindBuffer(GL2.GL_ELEMENT_ARRAY_BUFFER, 0);
          }
          gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);

          distortionShader.unuse(gl);
        }
      } finally {
        oglsh.pop(gl);
      }
    }
    hmd.endFrameTiming();

    // apply the old viewport, and ensure that the view is updated for the next picking round
    gl.glViewport(oldViewport.x, oldViewport.y, oldViewport.width, oldViewport.height);
    sc.applyView(dc);

    view.firePropertyChange(
        AVKey.VIEW, null, view); // make the view draw repeatedly for oculus rotation
  }
  protected void doRenderGeometry(DrawContext dc, String drawStyle) {
    if (dc == null) {
      String message = Logging.getMessage("nullValue.DrawContextIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (dc.getGL() == null) {
      String message = Logging.getMessage("nullValue.DrawingContextGLIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    double[] angles = this.computeAngles();
    // Angles are equal, fallback to drawing a closed cylinder.
    if (angles == null) {
      super.doRenderGeometry(dc, drawStyle);
      return;
    }

    double[] altitudes = this.getAltitudes(dc.getVerticalExaggeration());
    boolean[] terrainConformant = this.isTerrainConforming();
    double[] radii = this.getRadii();
    int slices = this.getSlices();
    int stacks = this.getStacks();
    int loops = this.getLoops();

    if (this.isEnableLevelOfDetail()) {
      DetailLevel level = this.computeDetailLevel(dc);

      Object o = level.getValue(SLICES);
      if (o != null && o instanceof Integer) slices = (Integer) o;

      o = level.getValue(STACKS);
      if (o != null && o instanceof Integer) stacks = (Integer) o;

      o = level.getValue(LOOPS);
      if (o != null && o instanceof Integer) loops = (Integer) o;

      o = level.getValue(DISABLE_TERRAIN_CONFORMANCE);
      if (o != null && o instanceof Boolean && ((Boolean) o))
        terrainConformant[0] = terrainConformant[1] = false;
    }

    Vec4 referenceCenter = this.computeReferenceCenter(dc);
    this.setExpiryTime(this.nextExpiryTime(dc, terrainConformant));
    this.clearElevationMap();

    GL gl = dc.getGL();
    OGLStackHandler ogsh = new OGLStackHandler();
    try {
      dc.getView().pushReferenceCenter(dc, referenceCenter);

      if (Airspace.DRAW_STYLE_OUTLINE.equals(drawStyle)) {
        this.drawRadialWallOutline(
            dc,
            radii,
            angles[0],
            altitudes,
            terrainConformant,
            loops,
            stacks,
            GeometryBuilder.INSIDE,
            referenceCenter);
        this.drawRadialWallOutline(
            dc,
            radii,
            angles[1],
            altitudes,
            terrainConformant,
            loops,
            stacks,
            GeometryBuilder.OUTSIDE,
            referenceCenter);

        // Outer cylinder isn't rendered if outer radius is zero.
        if (radii[1] != 0.0) {
          this.drawPartialCylinderOutline(
              dc,
              radii[1],
              altitudes,
              terrainConformant,
              slices,
              stacks,
              GeometryBuilder.OUTSIDE,
              angles[0],
              angles[2],
              referenceCenter);
        }
        // Inner cylinder isn't rendered if inner radius is zero.
        if (radii[0] != 0.0) {
          this.drawPartialCylinderOutline(
              dc,
              radii[0],
              altitudes,
              terrainConformant,
              slices,
              stacks,
              GeometryBuilder.INSIDE,
              angles[0],
              angles[2],
              referenceCenter);
        }
      } else if (Airspace.DRAW_STYLE_FILL.equals(drawStyle)) {
        if (this.isEnableCaps()) {
          ogsh.pushAttrib(gl, GL.GL_POLYGON_BIT);
          gl.glEnable(GL.GL_CULL_FACE);
          gl.glFrontFace(GL.GL_CCW);
        }

        if (this.isEnableCaps()) {
          // Caps aren't rendered if radii are equal.
          if (radii[0] != radii[1]) {
            this.drawPartialDisk(
                dc,
                radii,
                altitudes[1],
                terrainConformant[1],
                slices,
                loops,
                GeometryBuilder.OUTSIDE,
                angles[0],
                angles[2],
                referenceCenter);
            // Bottom cap isn't rendered if airspace is collapsed.
            if (!this.isAirspaceCollapsed()) {
              this.drawPartialDisk(
                  dc,
                  radii,
                  altitudes[0],
                  terrainConformant[0],
                  slices,
                  loops,
                  GeometryBuilder.INSIDE,
                  angles[0],
                  angles[2],
                  referenceCenter);
            }
          }
        }

        // Cylinders aren't rendered if airspace is collapsed.
        if (!this.isAirspaceCollapsed()) {
          this.drawRadialWall(
              dc,
              radii,
              angles[0],
              altitudes,
              terrainConformant,
              loops,
              stacks,
              GeometryBuilder.INSIDE,
              referenceCenter);
          this.drawRadialWall(
              dc,
              radii,
              angles[1],
              altitudes,
              terrainConformant,
              loops,
              stacks,
              GeometryBuilder.OUTSIDE,
              referenceCenter);

          // Outer cylinder isn't rendered if outer radius is zero.
          if (radii[1] != 0.0) {
            this.drawPartialCylinder(
                dc,
                radii[1],
                altitudes,
                terrainConformant,
                slices,
                stacks,
                GeometryBuilder.OUTSIDE,
                angles[0],
                angles[2],
                referenceCenter);
          }
          // Inner cylinder isn't rendered if inner radius is zero.
          if (radii[0] != 0.0) {
            this.drawPartialCylinder(
                dc,
                radii[0],
                altitudes,
                terrainConformant,
                slices,
                stacks,
                GeometryBuilder.INSIDE,
                angles[0],
                angles[2],
                referenceCenter);
          }
        }
      }
    } finally {
      dc.getView().popReferenceCenter(dc);
      ogsh.pop(gl);
    }
  }
  protected void doRenderGeometry(
      DrawContext dc, String drawStyle, List<LatLon> locations, List<Boolean> edgeFlags) {
    if (dc == null) {
      String message = Logging.getMessage("nullValue.DrawContextIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (dc.getGL() == null) {
      String message = Logging.getMessage("nullValue.DrawingContextGLIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }
    if (locations == null) {
      String message = "nullValue.LocationsIsNull";
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    if (locations.size() == 0) return;

    double[] altitudes = this.getAltitudes(dc.getVerticalExaggeration());
    boolean[] terrainConformant = this.isTerrainConforming();
    boolean enableCaps = this.isEnableCaps();
    int subdivisions = this.subdivisions;

    if (this.getAltitudeDatum()[0].equals(AVKey.ABOVE_GROUND_REFERENCE)
        || this.getAltitudeDatum()[1].equals(AVKey.ABOVE_GROUND_REFERENCE)) {
      this.adjustForGroundReference(dc, terrainConformant, altitudes);
    }

    if (this.isEnableLevelOfDetail()) {
      DetailLevel level = this.computeDetailLevel(dc);

      Object o = level.getValue(SUBDIVISIONS);
      if (o != null && o instanceof Integer) subdivisions = (Integer) o;

      o = level.getValue(DISABLE_TERRAIN_CONFORMANCE);
      if (o != null && o instanceof Boolean && (Boolean) o)
        terrainConformant[0] = terrainConformant[1] = false;
    }

    Vec4 referenceCenter = this.computeReferenceCenter(dc);
    this.setExpiryTime(this.nextExpiryTime(dc, terrainConformant));
    this.clearElevationMap();

    GL gl = dc.getGL();
    OGLStackHandler ogsh = new OGLStackHandler();
    try {
      dc.getView().pushReferenceCenter(dc, referenceCenter);

      if (Airspace.DRAW_STYLE_FILL.equals(drawStyle)) {
        if (enableCaps && !this.isAirspaceCollapsed()) {
          ogsh.pushAttrib(gl, GL.GL_POLYGON_BIT);
          gl.glEnable(GL.GL_CULL_FACE);
          gl.glFrontFace(GL.GL_CCW);
        }

        this.drawPolygonFill(
            dc,
            locations,
            edgeFlags,
            altitudes,
            terrainConformant,
            enableCaps,
            subdivisions,
            referenceCenter);
      } else if (Airspace.DRAW_STYLE_OUTLINE.equals(drawStyle)) {
        this.drawPolygonOutline(
            dc,
            locations,
            edgeFlags,
            altitudes,
            terrainConformant,
            enableCaps,
            subdivisions,
            referenceCenter);
      }
    } finally {
      dc.getView().popReferenceCenter(dc);
      ogsh.pop(gl);
    }
  }
Beispiel #7
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);
    }
  }