Ejemplo n.º 1
0
        /**
         * Removes the model-view matrix on top of the matrix stack, and restores the original matrix.
         *
         * @param dc the current World Wind drawing context on which the original matrix will be restored.
         *
         * @throws ArgumentException if <code>dc</code> is null, or if the <code>Globe</code> or <code>GL</code>
         *                                  instances in <code>dc</code> are null.
         */
        public void popReferenceCenter(DrawContext dc)
        {
            if (dc == null)
            {
                String message = Logging.getMessage("nullValue.DrawContextIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }
            if (dc.getGL() == null)
            {
                String message = Logging.getMessage("nullValue.DrawingContextGLIsNull");
                Logging.logger().severe(message);
                throw new IllegalStateException(message);
            }

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

            // Store the current matrix-mode state.
            OGLStackHandler ogsh = new OGLStackHandler();

            try
            {
                ogsh.pushAttrib(gl, GL2.GL_TRANSFORM_BIT);

                gl.MatrixMode(GL2.GL_MODELVIEW);

                // Pop the top model-view matrix.
                gl.PopMatrix();
            }
            finally
            {
                ogsh.pop(gl);
            }
        }
            public void pick(DrawContext dc, java.awt.Point pickPoint)
            {
                OGLStackHandler stackHandler = new OGLStackHandler();

                BasicAnnotationRenderer.this.pickSupport.clearPickList();
                BasicAnnotationRenderer.this.beginDrawAnnotations(dc, stackHandler);
                try
                {
                    this.annotation.setPickSupport(BasicAnnotationRenderer.this.pickSupport);
                    this.doRender(dc, this);
                    // Draw as many as we can in a batch to save ogl state switching.
                    while (dc.peekOrderedRenderables() is OrderedAnnotation)
                    {
                        OrderedAnnotation oa = (OrderedAnnotation)dc.pollOrderedRenderables();
                        oa.annotation.setPickSupport(BasicAnnotationRenderer.this.pickSupport);
                        this.doRender(dc, oa);
                    }
                }
                catch (WWRuntimeException e)
                {
                    Logging.logger().log(Level.SEVERE, "generic.ExceptionWhilePickingAnnotation", e);
                }
                catch (Exception e)
                {
                    Logging.logger().log(Level.SEVERE, "generic.ExceptionWhilePickingAnnotation", e);
                }
                finally
                {
                    BasicAnnotationRenderer.this.endDrawAnnotations(dc, stackHandler);
                    BasicAnnotationRenderer.this.pickSupport.resolvePick(dc, pickPoint, this.layer);
                    BasicAnnotationRenderer.this.pickSupport.clearPickList(); // to ensure entries can be garbage collected
                }
            }
            public void render(DrawContext dc)
            {
                OGLStackHandler stackHandler = new OGLStackHandler();

                BasicAnnotationRenderer.this.beginDrawAnnotations(dc, stackHandler);
                try
                {
                    this.doRender(dc, this);
                    // Draw as many as we can in a batch to save ogl state switching.
                    while (dc.peekOrderedRenderables() is OrderedAnnotation)
                    {
                        OrderedAnnotation oa = (OrderedAnnotation)dc.pollOrderedRenderables();
                        this.doRender(dc, oa);
                    }
                }
                catch (WWRuntimeException e)
                {
                    Logging.logger().log(Level.SEVERE, "generic.ExceptionWhileRenderingAnnotation", e);
                }
                catch (Exception e)
                {
                    Logging.logger().log(Level.SEVERE, "generic.ExceptionWhileRenderingAnnotation", e);
                }
                finally
                {
                    BasicAnnotationRenderer.this.endDrawAnnotations(dc, stackHandler);
                }
            }
        /**
         * Causes this SurfaceObject to draw a representation of itself suitable for use during picking.
         *
         * @param dc the current DrawContext.
         */
        protected void drawPickRepresentation(DrawContext dc)
        {
            // The pick representation is stored as a list of surface tiles. If the list is empty, then this surface object
            // was not picked. This method might be called when the list is null or empty because of an upstream
            // exception that prevented creation of the list.
            if (this.pickTileBuilder == null || this.pickTileBuilder.getTileCount(dc) == 0)
            {
                return;
            }

            // Draw the pickable representation of this surface object created during preRendering.
            GL2             gl   = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.
            OGLStackHandler ogsh = new OGLStackHandler();

            ogsh.pushAttrib(gl, GL2.GL_POLYGON_BIT); // For cull face enable, cull face, polygon mode.
            try
            {
                gl.glEnable(GL.GL_CULL_FACE);
                gl.glCullFace(GL.GL_BACK);
                gl.glPolygonMode(GL2.GL_FRONT, GL2.GL_FILL);

                dc.getGeographicSurfaceTileRenderer().renderTiles(dc, this.pickTileBuilder.getTiles(dc));
            }
            finally
            {
                ogsh.pop(gl);
                // Clear the list of pick tiles to avoid retaining references to them in case we're never picked again.
                this.pickTileBuilder.clearTiles(dc);
            }
        }
Ejemplo n.º 5
0
        public Matrix pushReferenceCenter(DrawContext dc, Vec4 referenceCenter)
        {
            if (dc == null)
            {
                String message = Logging.getMessage("nullValue.DrawContextIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }
            if (dc.getGL() == null)
            {
                String message = Logging.getMessage("nullValue.DrawingContextGLIsNull");
                Logging.logger().severe(message);
                throw new IllegalStateException(message);
            }
            if (referenceCenter == null)
            {
                String message = Logging.getMessage("nullValue.PointIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }

            Matrix modelview = getModelviewMatrix();

            // Compute a new model-view matrix with origin at referenceCenter.
            Matrix matrix = null;

            if (modelview != null)
            {
                matrix = modelview.multiply(Matrix.fromTranslation(referenceCenter));
            }

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

            // Store the current matrix-mode state.
            OGLStackHandler ogsh = new OGLStackHandler();

            try
            {
                ogsh.pushAttrib(gl, GL2.GL_TRANSFORM_BIT);

                gl.MatrixMode(GL2.GL_MODELVIEW);

                // Push and load a new model-view matrix to the current OpenGL context held by 'dc'.
                gl.PushMatrix();
                if (matrix != null)
                {
                    double[] matrixArray = new double[16];
                    matrix.toArray(matrixArray, 0, false);
                    gl.LoadMatrix(matrixArray);
                }
            }
            finally
            {
                ogsh.pop(gl);
            }

            return(matrix);
        }
        protected void endDrawAnnotations(DrawContext dc, OGLStackHandler stackHandler)
        {
            GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.

            if (dc.isPickingMode())
            {
                this.pickSupport.endPicking(dc);
            }

            stackHandler.pop(gl);
        }
        //**************************************************************//
        //********************  Diagnostic Support  ********************//
        //**************************************************************//

        /**
         * Causes this SurfaceObject to render its bounding sectors to the specified region in geographic coordinates. The
         * specified viewport denotes the geographic region and its corresponding screen viewport.
         * <p/>
         * The bounding sectors are rendered as a 1 pixel wide green outline.
         *
         * @param dc  the current DrawContext.
         * @param sdc the context containing a geographic region and screen viewport corresponding to a surface tile.
         *
         * @see #getSectors(DrawContext)
         */
        protected void drawBoundingSectors(DrawContext dc, SurfaceTileDrawContext sdc)
        {
            List <Sector> sectors = this.getSectors(dc);

            if (sectors == null)
            {
                return;
            }

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

            int attributeMask =
                GL2.GL_COLOR_BUFFER_BIT // For alpha test enable, blend enable, alpha func, blend func.
                | GL2.GL_CURRENT_BIT    // For current color.
                | GL2.GL_LINE_BIT;      // For line smooth, line width.

            OGLStackHandler ogsh = new OGLStackHandler();

            ogsh.pushAttrib(gl, attributeMask);
            ogsh.pushModelview(gl);
            try
            {
                gl.glEnable(GL.GL_BLEND);
                OGLUtil.applyBlending(gl, false);

                gl.glDisable(GL.GL_LINE_SMOOTH);
                gl.glLineWidth(1f);

                gl.glColor4f(1f, 1f, 1f, 0.5f);

                // Set the model-view matrix to transform from geographic coordinates to viewport coordinates.
                Matrix matrix = sdc.getModelviewMatrix();
                gl.glMultMatrixd(matrix.toArray(new double[16], 0, false), 0);

                foreach (Sector s in sectors)
                {
                    LatLon[] corners = s.getCorners();
                    gl.glBegin(GL2.GL_LINE_LOOP);
                    gl.glVertex2f((float)corners[0].getLongitude().degrees, (float)corners[0].getLatitude().degrees);
                    gl.glVertex2f((float)corners[1].getLongitude().degrees, (float)corners[1].getLatitude().degrees);
                    gl.glVertex2f((float)corners[2].getLongitude().degrees, (float)corners[2].getLatitude().degrees);
                    gl.glVertex2f((float)corners[3].getLongitude().degrees, (float)corners[3].getLatitude().degrees);
                    gl.glEnd();
                }
            }
            finally
            {
                ogsh.pop(gl);
            }
        }
        protected void beginDrawAnnotations(DrawContext dc, OGLStackHandler stackHandler)
        {
            GL2 gl = dc.getGL().getGL2();                 // GL initialization checks for GL2 compatibility.

            int attributeMask = GL2.GL_COLOR_BUFFER_BIT   // for alpha test func and ref, blend func
                                | GL2.GL_CURRENT_BIT      // for current color
                                | GL2.GL_DEPTH_BUFFER_BIT // for depth test, depth mask, depth func
                                | GL2.GL_ENABLE_BIT       // for enable/disable changes
                                | GL2.GL_HINT_BIT         // for line smoothing hint
                                | GL2.GL_LINE_BIT         // for line width, line stipple
                                | GL2.GL_TRANSFORM_BIT    // for matrix mode
                                | GL2.GL_VIEWPORT_BIT;    // for viewport, depth range

            stackHandler.pushAttrib(gl, attributeMask);

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

            // Push identity matrices on the texture and modelview matrix stacks. Leave the matrix mode as modelview.
            stackHandler.pushTextureIdentity(gl);
            stackHandler.pushModelviewIdentity(gl);

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

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

            // Disable lighting and backface culling.
            gl.glDisable(GL2.GL_LIGHTING);
            gl.glDisable(GL.GL_CULL_FACE);

            if (!dc.isPickingMode())
            {
                // Enable blending in premultiplied color mode.
                gl.glEnable(GL.GL_BLEND);
                OGLUtil.applyBlending(gl, true);
            }
            else
            {
                this.pickSupport.beginPicking(dc);
            }
        }
Ejemplo n.º 9
0
//    public static void main(String[] args)
//    {
//        Box box = new Box(new Vec4[] {new Vec4(1, 0, 0), new Vec4(0, 1, 0), new Vec4(0, 0, 1)},
//            -.5, .5, -.5, .5, -.5, .5);
//        Line line = new Line(new Vec4(-1, 0.5, 0.5), new Vec4(1, 0, 0));
//        Intersection[] intersections = box.intersect(line);
//        if (intersections != null && intersections.Length > 0 && intersections[0] != null)
//            System.out.println(intersections[0]);
//        if (intersections != null && intersections.Length > 1 && intersections[1] != null)
//            System.out.println(intersections[1]);
//    }

//    /** {@inheritDoc} */
//    public Intersection[] intersect(Line line)
//    {
//        return WWMath.polytopeIntersect(line, this.planes);
//        // Algorithm from "3-D Computer Graphics" by Samuel R. Buss, 2005, Section X.1.4.
//
//        // Determine intersection with each plane and categorize the intersections as "front" if the line intersects
//        // the front side of the plane (dot product of line direction with plane normal is negative) and "back" if the
//        // line intersects the back side of the plane (dot product of line direction with plane normal is positive).
//
//        double fMax = -Double.MaxValue;
//        double bMin = Double.MaxValue;
//        bool isTangent = false;
//
//        Vec4 u = line.getDirection();
//        Vec4 p = line.getOrigin();
//
//        foreach (Plane plane in this.planes)
//        {
//            Vec4 n = plane.getNormal();
//            double d = -plane.getDistance();
//
//            double s = u.dot3(n);
//            if (s == 0) // line is parallel to plane
//            {
//                double pdn = p.dot3(n);
//                if (pdn > d) // is line in positive halfspace (in front of) of the plane?
//                    return null; // no intersection
//                else
//                {
//                    if (pdn == d)
//                        isTangent = true; // line coincident with plane
//                    continue; // line is in negative halfspace; possible intersection; check other planes
//                }
//            }
//
//            // Determine whether front or back intersection.
//            double a = (d - p.dot3(n)) / s;
//            if (u.dot3(n) < 0) // line intersects front face and therefore entering box
//            {
//                if (a > fMax)
//                {
//                    if (a > bMin)
//                        return null;
//                    fMax = a;
//                }
//            }
//            else // line intersects back face and therefore leaving box
//            {
//                if (a < bMin)
//                {
//                    if (a < 0 || a < fMax)
//                        return null;
//                    bMin = a;
//                }
//            }
//        }
//
//        // Compute the Cartesian intersection points. There will be no more than two.
//        if (fMax >= 0) // intersects frontface and backface; point origin is outside the box
//            return new Intersection[]
//                {
//                    new Intersection(p.add3(u.multiply3(fMax)), isTangent),
//                    new Intersection(p.add3(u.multiply3(bMin)), isTangent)
//                };
//        else // intersects backface only; point origin is within the box
//            return new Intersection[] {new Intersection(p.add3(u.multiply3(bMin)), isTangent)};
//    }

        /**
         * Draws a representation of the <code>Box</code>.
         *
         * @param dc the <code>DrawContext</code> to be used.
         */
        public void render(DrawContext dc)
        {
            if (dc == null)
            {
                String message = Logging.getMessage("nullValue.DocumentSourceIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }

            if (dc.isPickingMode())
            {
                return;
            }

            Vec4 a = this.s.add3(this.t).multiply3(-0.5);
            Vec4 b = this.s.subtract3(this.t).multiply3(0.5);
            Vec4 c = this.s.add3(this.t).multiply3(0.5);
            Vec4 d = this.t.subtract3(this.s).multiply3(0.5);

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

            ogsh.pushAttrib(gl, GL2.GL_COLOR_BUFFER_BIT // For alpha enable, blend enable, alpha func, blend func.
                            | GL2.GL_CURRENT_BIT        // For current color.
                            | GL2.GL_LINE_BIT           // For line width.
                            | GL2.GL_TRANSFORM_BIT      // For matrix mode.
                            | GL2.GL_DEPTH_BUFFER_BIT); // For depth test enable, depth func.
            try
            {
                gl.glLineWidth(1f);
                gl.glEnable(GL.GL_BLEND);
                OGLUtil.applyBlending(gl, false);
                gl.glEnable(GL.GL_DEPTH_TEST);

                gl.glDepthFunc(GL.GL_LEQUAL);
                gl.glColor4f(1f, 1f, 1f, 0.5f);
                this.drawBox(dc, a, b, c, d);

                gl.glDepthFunc(GL.GL_GREATER);
                gl.glColor4f(1f, 0f, 1f, 0.4f);
                this.drawBox(dc, a, b, c, d);
            }
            finally
            {
                ogsh.pop(gl);
            }
        }
Ejemplo n.º 10
0
        protected void drawBox(DrawContext dc, Vec4 a, Vec4 b, Vec4 c, Vec4 d)
        {
            Vec4 e  = a.add3(this.r);
            Vec4 f  = d.add3(this.r);
            GL2  gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.

            dc.getView().pushReferenceCenter(dc, this.bottomCenter);
            OGLStackHandler ogsh = new OGLStackHandler();

            ogsh.pushModelview(gl);
            try
            {
                // Draw parallel lines in R direction
                int  n  = 20;
                Vec4 dr = this.r.multiply3(1d / (double)n);

                this.drawOutline(dc, a, b, c, d);
                for (int i = 1; i < n; i++)
                {
                    gl.glTranslated(dr.x, dr.y, dr.z);
                    this.drawOutline(dc, a, b, c, d);
                }

                // Draw parallel lines in S direction
                n = 20;
                Vec4 ds = this.s.multiply3(1d / (double)n);

                gl.glPopMatrix();
                gl.glPushMatrix();
                this.drawOutline(dc, a, e, f, d);
                for (int i = 1; i < n; i++)
                {
                    gl.glTranslated(ds.x, ds.y, ds.z);
                    this.drawOutline(dc, a, e, f, d);
                }
            }
            finally
            {
                ogsh.pop(gl);
                dc.getView().popReferenceCenter(dc);
            }
        }
Ejemplo n.º 11
0
        protected bool generateTexture(DrawContext dc, int width, int height)
        {
            GL2             gl   = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.
            OGLStackHandler ogsh = new OGLStackHandler();

            Matrix geoToCartesian = this.computeGeographicToCartesianTransform(this.sector);

            try
            {
                ogsh.pushAttrib(gl, GL2.GL_COLOR_BUFFER_BIT
                                | GL2.GL_ENABLE_BIT
                                | GL2.GL_TRANSFORM_BIT
                                | GL2.GL_VIEWPORT_BIT);

                // Fill the frame buffer with transparent black.
                gl.glClearColor(0f, 0f, 0f, 0f);
                gl.glClear(GL.GL_COLOR_BUFFER_BIT);

                gl.glDisable(GL.GL_BLEND);
                gl.glDisable(GL.GL_CULL_FACE);
                gl.glDisable(GL.GL_DEPTH_TEST);

                // Setup a viewport with the dimensions of the texture, and a projection matrix of dimension 2.0 (along
                // each axis) centered at the origin. Using a projection matrix with these dimensions ensures that incoming
                // vertices are rasterized without any rounding error.
                ogsh.pushProjectionIdentity(gl);
                gl.glViewport(0, 0, width, height);
                gl.glOrtho(-1d, 1d, -1d, 1d, -1d, 1d);

                ogsh.pushModelviewIdentity(gl);
                ogsh.pushTextureIdentity(gl);

                if (this.sourceTexture != null)
                {
                    try
                    {
                        gl.glEnable(GL.GL_TEXTURE_2D);
                        if (!this.sourceTexture.bind(dc))
                        {
                            return(false);
                        }

                        this.sourceTexture.applyInternalTransform(dc);

                        // Setup the texture to replace the fragment color at each pixel.
                        gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_REPLACE);

                        int tessellationDensity = this.getTessellationDensity();
                        this.drawQuad(dc, geoToCartesian, tessellationDensity, tessellationDensity);
                    }
                    finally
                    {
                        gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, OGLUtil.DEFAULT_TEX_ENV_MODE);
                        gl.glBindTexture(GL.GL_TEXTURE_2D, 0);
                    }
                }
            }
            finally
            {
                ogsh.pop(gl);
            }

            return(true);
        }
 protected AbstractAnnotationLayout()
 {
     this.stackHandler = new OGLStackHandler();
 }
Ejemplo n.º 13
0
        /**
         * Sets the the opengl modelview and projection matrices to the given matrices.
         *
         * @param dc         the drawing context
         * @param modelview  the modelview matrix
         * @param projection the projection matrix
         */
        public static void loadGLViewState(DrawContext dc, Matrix modelview, Matrix projection)
        {
            if (dc == null)
            {
                String message = Logging.getMessage("nullValue.DrawContextIsNull");
                Logging.logger().severe(message);
                throw new ArgumentException(message);
            }
            if (dc.getGL() == null)
            {
                String message = Logging.getMessage("nullValue.DrawingContextGLIsNull");
                Logging.logger().severe(message);
                throw new IllegalStateException(message);
            }
            if (modelview == null)
            {
                Logging.logger().fine("nullValue.ModelViewIsNull");
            }
            if (projection == null)
            {
                Logging.logger().fine("nullValue.ProjectionIsNull");
            }

            double[] matrixArray = new double[16];

            GL2 gl = dc.getGL().getGL2(); // GL initialization checks for GL2 compatibility.
            // Store the current matrix-mode state.
            OGLStackHandler ogsh = new OGLStackHandler();

            try
            {
                ogsh.pushAttrib(gl, GL2.GL_TRANSFORM_BIT);

                // Apply the model-view matrix to the current OpenGL context.
                gl.MatrixMode(GL2.GL_MODELVIEW);
                if (modelview != null)
                {
                    modelview.toArray(matrixArray, 0, false);
                    gl.LoadMatrix(matrixArray);
                }
                else
                {
                    gl.LoadIdentity();
                }

                // Apply the projection matrix to the current OpenGL context.
                gl.MatrixMode(GL2.GL_PROJECTION);
                if (projection != null)
                {
                    projection.toArray(matrixArray, 0, false);
                    gl.LoadMatrix(matrixArray);
                }
                else
                {
                    gl.LoadIdentity();
                }
            }
            finally
            {
                ogsh.pop(gl);
            }
        }
Ejemplo n.º 14
0
        /**
         * Display the cylinder.
         *
         * @param dc the current draw context.
         *
         * @throws ArgumentException if the draw context is null.
         */
        public void render(DrawContext dc)
        {
            if (dc == null)
            {
                String msg = Logging.getMessage("nullValue.DrawContextIsNull");
                Logging.logger().severe(msg);
                throw new ArgumentException(msg);
            }

            // Compute a matrix that will transform world coordinates to cylinder coordinates. The negative z-axis
            // will point from the cylinder's bottomCenter to its topCenter. The y-axis will be a vector that is
            // perpendicular to the cylinder's axisUnitDirection. Because the cylinder is symmetric, it does not matter
            // in what direction the y-axis points, as long as it is perpendicular to the z-axis.
            double tolerance = 1e-6;
            Vec4   upVector  = (this.axisUnitDirection.cross3(Vec4.UNIT_Y).getLength3() <= tolerance) ?
                               Vec4.UNIT_NEGATIVE_Z : Vec4.UNIT_Y;
            Matrix transformMatrix = Matrix.fromModelLookAt(this.bottomCenter, this.topCenter, upVector);

            double[] matrixArray = new double[16];
            transformMatrix.toArray(matrixArray, 0, false);

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

            OGLStackHandler ogsh = new OGLStackHandler();

            ogsh.pushAttrib(gl, GL2.GL_CURRENT_BIT | GL2.GL_ENABLE_BIT | GL2.GL_TRANSFORM_BIT | GL2.GL_DEPTH_BUFFER_BIT);
            try
            {
                // The cylinder is drawn with as a wireframe plus a center axis. It's drawn in two passes in order to
                // visualize the portions of the cylinder above and below an intersecting surface.

                gl.glEnable(GL.GL_BLEND);
                OGLUtil.applyBlending(gl, false);
                gl.glEnable(GL.GL_DEPTH_TEST);

                // Draw the axis
                gl.glDepthFunc(GL.GL_LEQUAL); // draw the part that would normally be visible
                gl.glColor4f(1f, 1f, 1f, 0.4f);
                gl.glBegin(GL2.GL_LINES);
                gl.glVertex3d(this.bottomCenter.x, this.bottomCenter.y, this.bottomCenter.z);
                gl.glVertex3d(this.topCenter.x, this.topCenter.y, this.topCenter.z);
                gl.glEnd();

                gl.glDepthFunc(GL.GL_GREATER); // draw the part that is behind an intersecting surface
                gl.glColor4f(1f, 0f, 1f, 0.4f);
                gl.glBegin(GL2.GL_LINES);
                gl.glVertex3d(this.bottomCenter.x, this.bottomCenter.y, this.bottomCenter.z);
                gl.glVertex3d(this.topCenter.x, this.topCenter.y, this.topCenter.z);
                gl.glEnd();

                // Draw the exterior wireframe
                ogsh.pushModelview(gl);
                gl.glMultMatrixd(matrixArray, 0);

                GLUquadric quadric = dc.getGLU().gluNewQuadric();
                dc.getGLU().gluQuadricDrawStyle(quadric, GLU.GLU_LINE);

                gl.glDepthFunc(GL.GL_LEQUAL);
                gl.glColor4f(1f, 1f, 1f, 0.5f);
                dc.getGLU().gluCylinder(quadric, this.cylinderRadius, this.cylinderRadius, this.cylinderHeight, 30, 30);

                gl.glDepthFunc(GL.GL_GREATER);
                gl.glColor4f(1f, 0f, 1f, 0.4f);
                dc.getGLU().gluCylinder(quadric, this.cylinderRadius, this.cylinderRadius, this.cylinderHeight, 30, 30);

                dc.getGLU().gluDeleteQuadric(quadric);
            }
            finally
            {
                ogsh.pop(gl);
            }
        }