surfaceicon.java

来自「world wind java sdk 源码」· Java 代码 · 共 476 行 · 第 1/2 页

JAVA
476
字号
        return this.color;
    }

    /**
     * Set the {@link Color} the source image will be combined with - default to white.
     * <p>
     * A non white color will mostly affect the white portions from the original image. This is mostly useful
     * to alter the appearance of 'colorless' icons - which mainly contain black, white and shades of gray.
     *
     * @param color the {@link Color} the source image will be combined with.
     */
    public void setColor(Color color)
    {
        if (color == null)
        {
            String message = Logging.getMessage("nullValue.ColorIsNull");
            Logging.logger().severe(message);
            throw new IllegalArgumentException(message);
        }
        this.color = color;
    }

    // *** SurfaceObject interface

    public long getLastModifiedTime()
    {
        return System.currentTimeMillis();  // Refresh all the time TODO
    }
    
    public Iterable<? extends Sector> getSectors(DrawContext dc)
    {
        return Arrays.asList(computeSector(dc));
    }

    public void doRenderToRegion(DrawContext dc, Sector sector, int x, int y, int width, int height)
    {
        this.beginDraw(dc);
        try
        {
            this.applyDrawTransform(dc, sector, x, y, width, height);
            this.applyDrawColor(dc);
            
            //Draw
            this.drawIcon(dc);
        }
        finally
        {
            // Restore gl state
            this.endDraw(dc);
        }
    }

    protected Sector computeSector(DrawContext dc)
    {
        Globe globe = dc.getGlobe();
        // Compute real world icon extent depending on distance from eye
        Rectangle2D.Double rect = computeDrawDimension(dc); // meter
        // Compute bounding sector and apply location offset to it
        double dLatRadians = rect.height / globe.getRadius();
        double dLonRadians = rect.width / globe.getRadius() / location.getLatitude().cos();
        double offsetLatRadians = locationOffset != null ? locationOffset.y * dLatRadians / this.imageHeight : 0;
        double offsetLonRadians = locationOffset != null ? locationOffset.x * dLonRadians / this.imageWidth : 0;
        Sector sector = new Sector(
            location.getLatitude().subtractRadians(dLatRadians / 2).addRadians(offsetLatRadians),
            location.getLatitude().addRadians(dLatRadians / 2).addRadians(offsetLatRadians),
            location.getLongitude().subtractRadians(dLonRadians / 2).addRadians(offsetLonRadians),
            location.getLongitude().addRadians(dLonRadians / 2).addRadians(offsetLonRadians)
        );
        // Rotate sector around location 
        return computeRotatedSectorBounds(sector, this.location, computeDrawHeading(dc));
    }

    protected Rectangle2D.Double computeDrawDimension(DrawContext dc)
    {
        // Compute icon extent at 1:1
        double pixelSize = computePixelSizeAtLocation(dc, this.location);
        double height = this.imageHeight * this.scale * pixelSize;
        double width = this.imageWidth * this.scale * pixelSize;
        // Clamp to size range
        double size = height > width ? height : width;
        double scale = size > this.maxSize ? this.maxSize / size : size < this.minSize ? this.minSize / size : 1;

        return new Rectangle2D.Double(0, 0, width * scale, height * scale);
    }

    protected Angle computeDrawHeading(DrawContext dc)
    {
        if (this.heading != null)
            return this.heading;

        return getViewHeading(dc);
    }

    protected void beginDraw(DrawContext dc)
    {
        GL gl = dc.getGL();

        int attributeMask = GL.GL_TRANSFORM_BIT // for modelview
                | GL.GL_CURRENT_BIT // for current color
                | GL.GL_COLOR_BUFFER_BIT // for alpha test func and ref, and blend
                | GL.GL_TEXTURE_BIT // for texture env
                | GL.GL_ENABLE_BIT; // for enable/disable changes
        gl.glPushAttrib(attributeMask);

        // Suppress any fully transparent image pixels
        gl.glEnable(GL.GL_ALPHA_TEST);
        gl.glAlphaFunc(GL.GL_GREATER, 0.001f);

        gl.glMatrixMode(GL.GL_TEXTURE);
        gl.glPushMatrix();

        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glPushMatrix();

        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(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_COMBINE);
            gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_SRC0_RGB, GL.GL_PREVIOUS);
            gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_COMBINE_RGB, GL.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);
            gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);
        }
    }

    protected void endDraw(DrawContext dc)
    {
        if (dc.isPickingMode())
            this.pickSupport.endPicking(dc);

        GL gl = dc.getGL();
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glPopMatrix();

        gl.glMatrixMode(GL.GL_TEXTURE);
        gl.glPopMatrix();

        gl.glPopAttrib();
    }

    protected void applyDrawTransform(DrawContext dc, Sector sector, int x, int y, int width, int height)
    {
        // Compute icon viewport point
        Vec4 point = computeDrawPoint(this.location, sector, x, y, width, height);

        // Compute scaling
        double regionPixelSize = computeDrawPixelSize(dc, sector, width, height);
        double drawPixelSize = computeDrawDimension(dc).width / this.imageWidth;
        double drawScale = drawPixelSize / regionPixelSize;

        GL gl = dc.getGL();
        // Translate to location point
        gl.glTranslated(point.x(), point.y(), point.z());
        // Add x scaling transform to maintain icon width and aspect ratio at any latitude
        gl.glScaled(drawScale/ this.location.getLatitude().cos(), drawScale, 1);
        // Add rotation to account for icon heading
        gl.glRotated(computeDrawHeading(dc).degrees, 0, 0, -1);
        // Translate to lower left corner
        gl.glTranslated(-this.imageWidth / 2, -this.imageHeight / 2, 0);
        // Apply location offset if any
        if (this.locationOffset != null)
            gl.glTranslated(this.locationOffset.x, this.locationOffset.y, 0);
    }

    protected void applyDrawColor(DrawContext dc)
    {
        if (!dc.isPickingMode())
            applyPremultipliedAlphaColor(dc.getGL(), this.color, getOpacity());
    }

    protected void drawIcon(DrawContext dc)
    {
        WWTexture texture = getTexture();
        if (texture == null)
            return;

        texture.bind(dc);
        // Update image width and height
        this.imageWidth = texture.getWidth();
        this.imageHeight = texture.getHeight();
        
        GL gl = dc.getGL();
        gl.glMatrixMode(GL.GL_TEXTURE);
        texture.applyInternalTransform(dc);

        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glScaled(this.imageWidth, this.imageHeight, 1d);
        dc.drawUnitQuad(new TextureCoords(0, 0, 1, 1));
    }

    protected WWTexture getTexture()
    {
        if (this.texture == null)
            this.texture = new BasicWWTexture(this.imageSource);

        return this.texture;
    }

    // *** Movable interface

    public Position getReferencePosition()
    {
        return new Position(this.location, 0);
    }

    public void move(Position delta)
    {
        if (delta == null)
        {
            String msg = Logging.getMessage("nullValue.PositionIsNull");
            Logging.logger().severe(msg);
            throw new IllegalArgumentException(msg);
        }

        this.moveTo(this.getReferencePosition().add(delta));
    }

    public void moveTo(Position position)
    {
        if (position == null)
        {
            String msg = Logging.getMessage("nullValue.PositionIsNull");
            Logging.logger().severe(msg);
            throw new IllegalArgumentException(msg);
        }

        this.setLocation(position.getLatLon());
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?