/* Copyright (C) 2001, 2006 United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All Rights Reserved. */ package gov.nasa.worldwind.render; import com.sun.opengl.util.BufferUtil; import gov.nasa.worldwind.Movable; import gov.nasa.worldwind.geom.*; import gov.nasa.worldwind.util.Logging; import javax.media.opengl.GL; import java.awt.*; import java.nio.DoubleBuffer; /** * @author tag * @version $Id: Quadrilateral.java 2471 2007-07-31 21:50:57Z tgaskins $ */ public class Quadrilateral implements Renderable, Movable { private LatLon southwestCorner; private LatLon northeastCorner; private double elevation; private Vec4 referenceCenter; private DoubleBuffer vertices; private int antiAliasHint = GL.GL_FASTEST; private Color color = Color.WHITE; public Quadrilateral(LatLon southwestCorner, LatLon northeastCorner, double elevation) { if (southwestCorner == null || northeastCorner == null) { String msg = Logging.getMessage("nullValue.PositionIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } this.southwestCorner = southwestCorner; this.northeastCorner = northeastCorner; this.elevation = elevation; } public Quadrilateral(Sector sector, double elevation) { if (sector == null) { String msg = Logging.getMessage("nullValue.SectorIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } this.southwestCorner = new LatLon(sector.getMinLatitude(), sector.getMinLongitude()); this.northeastCorner = new LatLon(sector.getMaxLatitude(), sector.getMaxLongitude()); this.elevation = elevation; } public Color getColor() { return color; } public void setColor(Color color) { if (color == null) { String msg = Logging.getMessage("nullValue.ColorIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } this.color = color; } public int getAntiAliasHint() { return antiAliasHint; } public void setAntiAliasHint(int hint) { if (!(hint == GL.GL_DONT_CARE || hint == GL.GL_FASTEST || hint == GL.GL_NICEST)) { String msg = Logging.getMessage("generic.InvalidHint"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } this.antiAliasHint = hint; } public void setCorners(LatLon southWest, LatLon northEast) { this.southwestCorner = southWest; this.northeastCorner = northEast; this.vertices = null; } public LatLon[] getCorners() { LatLon[] retVal = new LatLon[2]; retVal[0] = this.southwestCorner; retVal[1] = this.northeastCorner; return retVal; } public double getElevation() { return elevation; } public void setElevation(double elevation) { this.elevation = elevation; this.vertices = null; } private void intializeGeometry(DrawContext dc) { DoubleBuffer verts = BufferUtil.newDoubleBuffer(12); Vec4[] p = new Vec4[4]; p[0] = dc.getGlobe().computePointFromPosition(this.southwestCorner.getLatitude(), this.southwestCorner.getLongitude(), this.elevation); p[1] = dc.getGlobe().computePointFromPosition(this.southwestCorner.getLatitude(), this.northeastCorner.getLongitude(), this.elevation); p[2] = dc.getGlobe().computePointFromPosition(this.northeastCorner.getLatitude(), this.northeastCorner.getLongitude(), this.elevation); p[3] = dc.getGlobe().computePointFromPosition(this.northeastCorner.getLatitude(), this.southwestCorner.getLongitude(), this.elevation); Vec4 refcenter = new Vec4( (p[0].x + p[2].x) / 2.0, (p[0].y + p[2].y) / 2.0, (p[0].z + p[2].z) / 2.0); for (int i = 0; i < 4; i++) { verts.put(p[i].x - refcenter.x); verts.put(p[i].y - refcenter.y); verts.put(p[i].z - refcenter.z); } this.referenceCenter = refcenter; this.vertices = verts; } public void render(DrawContext dc) { if (dc == null) { String message = Logging.getMessage("nullValue.DrawContextIsNull"); Logging.logger().severe(message); throw new IllegalStateException(message); } if (this.vertices == null) { this.intializeGeometry(dc); if (this.vertices == null) return; // TODO: logger a warning } GL gl = dc.getGL(); int attrBits = GL.GL_HINT_BIT | GL.GL_CURRENT_BIT; if (!dc.isPickingMode()) { if (this.color.getAlpha() != 255) attrBits |= GL.GL_COLOR_BUFFER_BIT; } gl.glPushAttrib(attrBits); gl.glPushClientAttrib(GL.GL_CLIENT_VERTEX_ARRAY_BIT); dc.getView().pushReferenceCenter(dc, this.referenceCenter); try { if (!dc.isPickingMode()) { if (this.color.getAlpha() != 255) { gl.glEnable(GL.GL_BLEND); gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA); } dc.getGL().glColor4ub((byte) this.color.getRed(), (byte) this.color.getGreen(), (byte) this.color.getBlue(), (byte) this.color.getAlpha()); } gl.glHint(GL.GL_POLYGON_SMOOTH_HINT, this.antiAliasHint); gl.glEnableClientState(GL.GL_VERTEX_ARRAY); gl.glVertexPointer(3, GL.GL_DOUBLE, 0, this.vertices.rewind()); gl.glDrawArrays(GL.GL_QUADS, 0, 4); } finally { gl.glPopClientAttrib(); gl.glPopAttrib(); dc.getView().popReferenceCenter(dc); } } public Position getReferencePosition() { return new Position(this.southwestCorner, this.elevation); } public void move(Position delta) { if (delta == null) { String msg = Logging.getMessage("nullValue.PositionIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } this.northeastCorner = this.northeastCorner.add(delta); this.southwestCorner = this.southwestCorner.add(delta); this.elevation = this.elevation + delta.getElevation(); this.vertices = null; } public void moveTo(Position position) { if (position == null) { String msg = Logging.getMessage("nullValue.PositionIsNull"); Logging.logger().severe(msg); throw new IllegalArgumentException(msg); } Position delta = position.subtract(this.getReferencePosition()); this.move(delta); } }