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 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); } }
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); } }