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 + -
显示快捷键?