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); }
/** * 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(); } } }
/** * Draws this ordered renderable and all subsequent Label ordered renderables in the ordered * renderable list. This method differs from {@link * #drawBatchedText(gov.nasa.worldwind.render.DrawContext, TextRenderer) drawBatchedText} in that * this method re-initializes the text renderer to draw the next label, while {@code * drawBatchedText} re-uses the active text renderer context. That is, {@code drawBatchedText} * attempts to draw as many labels as possible that share same text renderer configuration as this * label, and this method attempts to draw as many labels as possible regardless of the text * renderer configuration of the subsequent labels. * * @param dc the current draw context. */ protected void drawBatched(DrawContext dc) { // 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; dc.pollOrderedRenderables(); // take it off the queue nextLabel.doDrawOrderedRenderable(dc, this.pickSupport); nextItem = dc.peekOrderedRenderables(); } } else if (this.isEnableBatchPicking()) { while (nextItem != null && nextItem instanceof TacticalGraphicLabel) { TacticalGraphicLabel nextLabel = (TacticalGraphicLabel) nextItem; if (!nextLabel.isEnableBatchRendering() || !nextLabel.isEnableBatchPicking()) break; if (nextLabel.pickLayer != this.pickLayer) // batch pick only within a single layer break; dc.pollOrderedRenderables(); // take it off the queue nextLabel.doDrawOrderedRenderable(dc, this.pickSupport); nextItem = dc.peekOrderedRenderables(); } } }
protected void applyColor(DrawContext dc, java.awt.Color color, double opacity) { if (dc.isPickingMode()) return; double finalOpacity = opacity * (color.getAlpha() / 255.0); GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility. OGLUtil.applyColor(gl, color, finalOpacity, true); }
/** * 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); } }
/** * 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 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(); } }
protected void applyColor(DrawContext dc, java.awt.Color color, double opacity) { if (dc.isPickingMode()) return; double finalOpacity = opacity * (color.getAlpha() / 255.0); OGLUtil.applyColor(dc.getGL(), color, finalOpacity, true); }
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); } }
/** * Returns true if the IconRenderer should record feedback about how the specified WWIcon has been * processed. * * @param dc the current DrawContext. * @param icon the WWIcon to record feedback information for. * @return true to record feedback; false otherwise. */ protected boolean isFeedbackEnabled(DrawContext dc, WWIcon icon) { if (dc.isPickingMode()) return false; Boolean b = (Boolean) icon.getValue(AVKey.FEEDBACK_ENABLED); return (b != null && b); }
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; }
// 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(); } }