/** * 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(); } } }
protected static boolean isTileVisible( DrawContext dc, Tile tile, double minDistanceSquared, double maxDistanceSquared) { if (!tile.getSector().intersects(dc.getVisibleSector())) return false; View view = dc.getView(); Position eyePos = view.getEyePosition(); if (eyePos == null) return false; Angle lat = clampAngle( eyePos.getLatitude(), tile.getSector().getMinLatitude(), tile.getSector().getMaxLatitude()); Angle lon = clampAngle( eyePos.getLongitude(), tile.getSector().getMinLongitude(), tile.getSector().getMaxLongitude()); Vec4 p = dc.getGlobe().computePointFromPosition(lat, lon, 0d); double distSquared = dc.getView().getEyePoint().distanceToSquared3(p); //noinspection RedundantIfStatement if (minDistanceSquared > distSquared || maxDistanceSquared < distSquared) return false; return true; }
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); } }
/** * 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); }
/** * Draws text for subsequent Label ordered renderables in the ordered renderable list. This method * is called after the text renderer has been set up (after beginRendering has been called), so * this method can only draw text for subsequent labels that use the same font and rotation as * this label. This method differs from {@link #drawBatched(gov.nasa.worldwind.render.DrawContext) * drawBatched} in that this method reuses the active text renderer context to draw as many labels * as possible without switching text renderer state. * * @param dc the current draw context. * @param textRenderer Text renderer used to draw the label. */ protected void drawBatchedText(DrawContext dc, TextRenderer textRenderer) { // Draw as many as we can in a batch to save ogl state switching. Object nextItem = dc.peekOrderedRenderables(); if (!dc.isPickingMode()) { while (nextItem != null && nextItem instanceof TacticalGraphicLabel) { TacticalGraphicLabel nextLabel = (TacticalGraphicLabel) nextItem; if (!nextLabel.isEnableBatchRendering()) break; boolean sameFont = this.font.equals(nextLabel.getFont()); boolean sameRotation = (this.rotation == null && nextLabel.rotation == null) || (this.rotation != null && this.rotation.equals(nextLabel.rotation)); boolean drawInterior = nextLabel.isDrawInterior(); // We've already set up the text renderer state, so we can can't change the font or text // rotation. // Also can't batch render if the next label needs an interior since that will require // tearing down the // text renderer context. if (!sameFont || !sameRotation || drawInterior) break; dc.pollOrderedRenderables(); // take it off the queue nextLabel.doDrawText(textRenderer); nextItem = dc.peekOrderedRenderables(); } } }
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]); }
/** * Select the visible grid elements * * @param dc the current <code>DrawContext</code>. */ protected void selectRenderables(DrawContext dc) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } Sector vs = dc.getVisibleSector(); OrbitView view = (OrbitView) dc.getView(); // Compute labels offset from view center Position centerPos = view.getCenterPosition(); Double pixelSizeDegrees = Angle.fromRadians( view.computePixelSizeAtDistance(view.getZoom()) / dc.getGlobe().getEquatorialRadius()) .degrees; Double labelOffsetDegrees = pixelSizeDegrees * view.getViewport().getWidth() / 4; Position labelPos = Position.fromDegrees( centerPos.getLatitude().degrees - labelOffsetDegrees, centerPos.getLongitude().degrees - labelOffsetDegrees, 0); Double labelLatDegrees = labelPos.getLatitude().normalizedLatitude().degrees; labelLatDegrees = Math.min(Math.max(labelLatDegrees, -76), 78); labelPos = new Position( Angle.fromDegrees(labelLatDegrees), labelPos.getLongitude().normalizedLongitude(), 0); if (vs != null) { for (GridElement ge : this.gridElements) { if (ge.isInView(dc)) { if (ge.renderable instanceof GeographicText) { GeographicText gt = (GeographicText) ge.renderable; if (labelPos.getLatitude().degrees < 72 || "*32*34*36*".indexOf("*" + gt.getText() + "*") == -1) { // Adjust label position according to eye position Position pos = gt.getPosition(); if (ge.type.equals(GridElement.TYPE_LATITUDE_LABEL)) pos = Position.fromDegrees( pos.getLatitude().degrees, labelPos.getLongitude().degrees, pos.getElevation()); else if (ge.type.equals(GridElement.TYPE_LONGITUDE_LABEL)) pos = Position.fromDegrees( labelPos.getLatitude().degrees, pos.getLongitude().degrees, pos.getElevation()); gt.setPosition(pos); } } this.graticuleSupport.addRenderable(ge.renderable, GRATICULE_UTM); } } // System.out.println("Total elements: " + count + " visible sector: " + vs); } }
/** * Draw this label during ordered rendering. * * @param dc Current draw context. * @param pickSupport Support object used during picking. */ protected void doDrawOrderedRenderable(DrawContext dc, PickSupport pickSupport) { TextRenderer textRenderer = OGLTextRenderer.getOrCreateTextRenderer(dc.getTextRendererCache(), font); if (dc.isPickingMode()) { this.doPick(dc, pickSupport); } else { this.drawText(dc, textRenderer); } }
@SuppressWarnings({"RedundantIfStatement"}) public boolean isInView(DrawContext dc) { if (!viewFrustum.intersects(this.getExtent(dc.getGlobe(), dc.getVerticalExaggeration()))) return false; // Check apparent size if (getSizeInPixels(dc) <= MIN_CELL_SIZE_PIXELS) return false; return true; }
protected Angle computeIconRadius(DrawContext dc, double regionPixelSize, Sector drawSector) { double minCosLat = Math.min(drawSector.getMinLatitude().cos(), drawSector.getMaxLatitude().cos()); if (minCosLat < 0.001) return Angle.POS180; Rectangle2D iconDimension = this.computeDrawDimension(regionPixelSize); // Meter double dLat = iconDimension.getHeight() / dc.getGlobe().getRadius(); double dLon = iconDimension.getWidth() / dc.getGlobe().getRadius() / minCosLat; return Angle.fromRadians(Math.sqrt(dLat * dLat + dLon * dLon) / 2); }
protected static boolean isServiceVisible(DrawContext dc, PlaceNameService placeNameService) { //noinspection SimplifiableIfStatement if (!placeNameService.isEnabled()) return false; return (dc.getVisibleSector() != null) && placeNameService.getMaskingSector().intersects(dc.getVisibleSector()); // // return // placeNameService.getExtent(dc).intersects(dc.getView().getFrustumInModelCoordinates()); }
protected static boolean isNameVisible( DrawContext dc, PlaceNameService service, Position namePosition) { double elevation = dc.getVerticalExaggeration() * namePosition.getElevation(); Vec4 namePoint = dc.getGlobe() .computePointFromPosition( namePosition.getLatitude(), namePosition.getLongitude(), elevation); Vec4 eyeVec = dc.getView().getEyePoint(); double dist = eyeVec.distanceTo3(namePoint); return dist >= service.getMinDisplayDistance() && dist <= service.getMaxDisplayDistance(); }
@Override protected void doRender(DrawContext dc) { if (this.frameTimestamp != dc.getFrameTimeStamp()) { this.assembleControlPoints(dc); this.frameTimestamp = dc.getFrameTimeStamp(); } this.markerRenderer.render(dc, this.controlPoints); if (this.annotation != null && isShowAnnotation()) { this.annotation.render(dc); } }
/** * Draws the graphic as an ordered renderable. * * @param dc the current draw context. */ protected void makeOrderedRenderable(DrawContext dc) { if (this.lines == null || this.position == null) return; this.computeGeometryIfNeeded(dc); // Don't draw if beyond the horizon. double horizon = dc.getView().getHorizonDistance(); if (this.eyeDistance > horizon) return; if (this.intersectsFrustum(dc)) dc.addOrderedRenderable(this); if (dc.isPickingMode()) this.pickLayer = dc.getCurrentLayer(); }
/** * Determine if this label intersects the view or pick frustum. * * @param dc Current draw context. * @return True if this label intersects the active frustum (view or pick). Otherwise false. */ protected boolean intersectsFrustum(DrawContext dc) { View view = dc.getView(); Frustum frustum = view.getFrustumInModelCoordinates(); // Test the label's model coordinate point against the near and far clipping planes. if (this.placePoint != null && (frustum.getNear().distanceTo(this.placePoint) < 0 || frustum.getFar().distanceTo(this.placePoint) < 0)) { return false; } if (dc.isPickingMode()) return dc.getPickFrustums().intersectsAny(this.screenExtent); else return view.getViewport().intersects(this.screenExtent); }
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); }
protected void drawIconsInBatch(DrawContext dc, OrderedIcon uIcon) { this.drawIcon(dc, uIcon); // Draw as many as we can in a batch to save ogl state switching. Object nextItem = dc.peekOrderedRenderables(); while (nextItem != null && nextItem instanceof OrderedIcon) { OrderedIcon oi = (OrderedIcon) nextItem; if (oi.getRenderer() != this) return; dc.pollOrderedRenderables(); // take it off the queue this.drawIcon(dc, oi); nextItem = dc.peekOrderedRenderables(); } }
/** * Compute the lat/lon position of the view center * * @param dc the current DrawContext * @param view the current View * @return the ground position of the view center or null */ protected Position computeGroundPosition(DrawContext dc, View view) { if (view == null) return null; Position groundPos = view.computePositionFromScreenPoint( view.getViewport().getWidth() / 2, view.getViewport().getHeight() / 2); if (groundPos == null) return null; double elevation = dc.getGlobe().getElevation(groundPos.getLatitude(), groundPos.getLongitude()); return new Position( groundPos.getLatitude(), groundPos.getLongitude(), elevation * dc.getVerticalExaggeration()); }
// X-PATCH Marjan // extracted skip conditions into an overrideable method protected boolean meetsRenderCriteria( DrawContext dc, WWIcon icon, Vec4 iconPoint, double eyeDistance) { if (this.isHorizonClippingEnabled() && eyeDistance > dc.getView().getHorizonDistance()) { return false; // don't render horizon-clipped icons } // If enabled, eliminate icons outside the view volume. Primarily used to control icon // visibility beyond // the view volume's far clipping plane. if (this.isViewClippingEnabled() && !dc.getView().getFrustumInModelCoordinates().contains(iconPoint)) { return false; // don't render frustum-clipped icons } return true; }
/** * Compute the bounds of the text, if necessary. * * @param dc the current DrawContext. */ protected void computeBoundsIfNeeded(DrawContext dc) { // Do not compute bounds if they are available. Computing text bounds is expensive, so only do // this // calculation if necessary. if (this.bounds != null) return; TextRenderer textRenderer = OGLTextRenderer.getOrCreateTextRenderer(dc.getTextRendererCache(), this.getFont()); int width = 0; int maxLineHeight = 0; this.lineBounds = new Rectangle2D[this.lines.length]; for (int i = 0; i < this.lines.length; i++) { Rectangle2D lineBounds = textRenderer.getBounds(lines[i]); width = (int) Math.max(lineBounds.getWidth(), width); double thisLineHeight = Math.abs(lineBounds.getY()); maxLineHeight = (int) Math.max(thisLineHeight, maxLineHeight); this.lineBounds[i] = lineBounds; } this.lineHeight = maxLineHeight; // Compute final height using maxLineHeight and number of lines this.bounds = new Rectangle( this.lines.length, maxLineHeight, width, this.lines.length * maxLineHeight + this.lines.length * this.lineSpacing); }
/** * Compute the positions of the arrow head of the graphic's legs. * * @param dc Current draw context * @param base Position of the arrow's starting point. * @param tip Position of the arrow head tip. * @param arrowLength Length of the arrowhead as a fraction of the total line length. * @param arrowAngle Angle of the arrow head. * @return Positions required to draw the arrow head. */ protected List<Position> computeArrowheadPositions( DrawContext dc, Position base, Position tip, double arrowLength, Angle arrowAngle) { // Build a triangle to represent the arrowhead. The triangle is built from two vectors, one // parallel to the // segment, and one perpendicular to it. Globe globe = dc.getGlobe(); Vec4 ptA = globe.computePointFromPosition(base); Vec4 ptB = globe.computePointFromPosition(tip); // Compute parallel component Vec4 parallel = ptA.subtract3(ptB); Vec4 surfaceNormal = globe.computeSurfaceNormalAtPoint(ptB); // Compute perpendicular component Vec4 perpendicular = surfaceNormal.cross3(parallel); double finalArrowLength = arrowLength * parallel.getLength3(); double arrowHalfWidth = finalArrowLength * arrowAngle.tanHalfAngle(); perpendicular = perpendicular.normalize3().multiply3(arrowHalfWidth); parallel = parallel.normalize3().multiply3(finalArrowLength); // Compute geometry of direction arrow Vec4 vertex1 = ptB.add3(parallel).add3(perpendicular); Vec4 vertex2 = ptB.add3(parallel).subtract3(perpendicular); return TacticalGraphicUtil.asPositionList(globe, vertex1, vertex2, ptB); }
protected void assembleControlPoints(DrawContext dc) { // Control points are re-computed each frame this.controlPoints = new ArrayList<Marker>(); this.assembleVertexControlPoints(dc); if (!dc.is2DGlobe()) this.assembleHeightControlPoints(); }
public double getSizeInPixels(DrawContext dc) { View view = dc.getView(); Vec4 centerPoint = getSurfacePoint(dc, this.centroid.getLatitude(), this.centroid.getLongitude()); Double distance = view.getEyePoint().distanceTo3(centerPoint); return this.size / view.computePixelSizeAtDistance(distance); }
public void computeZone(DrawContext dc) { try { Position centerPos = ((OrbitView) dc.getView()).getCenterPosition(); if (centerPos != null) { if (centerPos.latitude.degrees <= UTM_MAX_LATITUDE && centerPos.latitude.degrees >= UTM_MIN_LATITUDE) { UTMCoord UTM = UTMCoord.fromLatLon( centerPos.getLatitude(), centerPos.getLongitude(), dc.getGlobe()); this.zone = UTM.getZone(); } else this.zone = 0; } } catch (Exception ex) { this.zone = 0; } }
public void makeOrderedRenderable(DrawContext dc, AirspaceRenderer renderer) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } if (renderer == null) { String message = Logging.getMessage("nullValue.RendererIsNull"); Logging.logger().severe(message); throw new IllegalArgumentException(message); } for (Layer layer : this.layers) { if (!layer.isVisible()) continue; if (!layer.isAirspaceVisible(dc)) continue; // The layer is responsible for applying its own attributes, so we override its attributes // with our own just // before rendering. layer.setAttributes(this.getAttributes()); // Create an ordered renderable that draws each layer, but specifies this Cake as the picked // object. OrderedRenderable or = renderer.createOrderedRenderable(dc, layer, layer.computeEyeDistance(dc), this); dc.addOrderedRenderable(or); } }
/** * Generate the positions required to draw the line. * * @param dc Current draw context. * @param positions Positions that define the polygon boundary. */ @Override protected void generateIntermediatePositions( DrawContext dc, Iterable<? extends Position> positions) { Globe globe = dc.getGlobe(); boolean useDefaultWaveLength = false; double waveLength = this.getWaveLength(); if (waveLength == 0) { waveLength = this.computeDefaultWavelength(positions, globe); useDefaultWaveLength = true; } // Generate lines that parallel the control line. List<Position> leftPositions = new ArrayList<Position>(); List<Position> rightPositions = new ArrayList<Position>(); this.generateParallelLines( positions.iterator(), leftPositions, rightPositions, waveLength / 2.0, globe); if (useDefaultWaveLength) waveLength = this.computeDefaultWavelength(leftPositions, globe); double radius = (waveLength) / 2.0; // Generate wavy line to the left of the control line. PositionIterator iterator = new PositionIterator(leftPositions, waveLength, globe); this.computedPositions = this.generateWavePositions(iterator, radius / globe.getRadius(), false); this.path.setPositions(this.computedPositions); if (useDefaultWaveLength) waveLength = this.computeDefaultWavelength(rightPositions, globe); radius = (waveLength) / 2.0; // Generate wavy line to the right of the control line. iterator = new PositionIterator(rightPositions, waveLength, globe); this.path2.setPositions(this.generateWavePositions(iterator, radius / globe.getRadius(), true)); }
protected void addToolTip(DrawContext dc, WWIcon icon, Vec4 iconPoint) { if (icon.getToolTipFont() == null && icon.getToolTipText() == null) return; Vec4 screenPoint = dc.getView().project(iconPoint); if (screenPoint == null) return; if (icon.getToolTipOffset() != null) screenPoint = screenPoint.add3(icon.getToolTipOffset()); OrderedText tip = new OrderedText( icon.getToolTipText(), icon.getToolTipFont(), screenPoint, icon.getToolTipTextColor(), 0d); dc.addOrderedRenderable(tip); }
protected void requestTile(DrawContext dc, Tile tile) { Vec4 centroid = dc.getGlobe().computePointFromPosition(tile.getSector().getCentroid(), 0); if (this.getReferencePoint() != null) tile.setPriority(centroid.distanceTo3(this.getReferencePoint())); RequestTask task = new RequestTask(tile, this); this.getRequestQ().add(task); }
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); } }
protected void assembleVertexControlPoints(DrawContext dc) { Terrain terrain = dc.getTerrain(); ExtrudedPolygon polygon = this.getPolygon(); Position refPos = polygon.getReferencePosition(); Vec4 refPoint = terrain.getSurfacePoint(refPos.getLatitude(), refPos.getLongitude(), 0); int altitudeMode = polygon.getAltitudeMode(); double height = polygon.getHeight(); Vec4 vaa = null; double vaaLength = 0; // used to compute independent length of each cap vertex double vaLength = 0; int i = 0; for (LatLon location : polygon.getOuterBoundary()) { Vec4 vert; // Compute the top/cap point. if (altitudeMode == WorldWind.CONSTANT || !(location instanceof Position)) { if (vaa == null) { // Compute the vector lengths of the top and bottom points at the reference position. vaa = refPoint.multiply3(height / refPoint.getLength3()); vaaLength = vaa.getLength3(); vaLength = refPoint.getLength3(); } // Compute the bottom point, which is on the terrain. vert = terrain.getSurfacePoint(location.getLatitude(), location.getLongitude(), 0); double delta = vaLength - vert.dot3(refPoint) / vaLength; vert = vert.add3(vaa.multiply3(1d + delta / vaaLength)); } else if (altitudeMode == WorldWind.RELATIVE_TO_GROUND) { vert = terrain.getSurfacePoint( location.getLatitude(), location.getLongitude(), ((Position) location).getAltitude()); } else // WorldWind.ABSOLUTE { vert = terrain .getGlobe() .computePointFromPosition( location.getLatitude(), location.getLongitude(), ((Position) location).getAltitude() * terrain.getVerticalExaggeration()); } Position vertexPosition = this.wwd.getModel().getGlobe().computePositionFromPoint(vert); this.controlPoints.add( new ControlPointMarker( MOVE_VERTEX_ACTION, vertexPosition, vert, this.vertexControlAttributes, i)); i++; } }