📄 airspacerenderer.java
字号:
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
this.renderer = renderer;
this.airspace = airspace;
this.layer = layer;
this.eyeDistance = eyeDistance;
}
public AirspaceRenderer getRenderer()
{
return this.renderer;
}
public Airspace getAirspace()
{
return this.airspace;
}
public Layer getLayer()
{
return this.layer;
}
public double getDistanceFromEye()
{
return this.eyeDistance;
}
public void render(DrawContext dc)
{
if (dc == null)
{
String msg = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
// The render method does not bind any pickable objects.
this.draw(dc, null);
}
public void pick(DrawContext dc, Point pickPoint)
{
if (dc == null)
{
String msg = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
if (pickPoint == null)
{
String msg = Logging.getMessage("nullValue.PickPoint");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
PickSupport pickSupport = this.getRenderer().getPickSupport();
pickSupport.beginPicking(dc);
try
{
// The pick method will bind pickable objects to the renderer's PickSupport.
this.draw(dc, pickSupport);
}
finally
{
pickSupport.endPicking(dc);
}
pickSupport.resolvePick(dc, pickPoint, this.getLayer());
pickSupport.clearPickList();
}
protected void draw(DrawContext dc, PickSupport pickSupport)
{
AirspaceRenderer renderer = this.getRenderer();
renderer.drawOrderedAirspace(dc, this, pickSupport);
}
}
protected void drawOrderedAirspace(DrawContext dc, OrderedAirspace orderedAirspace, PickSupport pickSupport)
{
if (dc == null)
{
String msg = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
if (orderedAirspace == null)
{
String msg = Logging.getMessage("nullValue.OrderedAirspace");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
this.beginRendering(dc);
try
{
this.drawAirspace(dc, orderedAirspace.getAirspace(), pickSupport);
this.drawOrderedAirspaces(dc, pickSupport);
}
finally
{
this.endRendering(dc);
}
}
protected void drawOrderedAirspaces(DrawContext dc, PickSupport pickSupport)
{
if (dc == null)
{
String msg = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
// Batch render as many Airspaces as we can to save OpenGL state switching.
OrderedRenderable top = dc.getOrderedRenderables().peek();
while (top != null && top instanceof OrderedAirspace)
{
OrderedAirspace oa = (OrderedAirspace) top;
// If the next OrderedAirspace's renderer is different, then we must stop batching. Otherwise, we would
// render an airspace with a renderer with potentially different properties or behavior.
if (this != oa.getRenderer())
return;
this.drawAirspace(dc, oa.getAirspace(), pickSupport);
// Take the ordered airspace off the queue, then peek at the next item in the queue (but do not remove it).
dc.getOrderedRenderables().poll();
top = dc.getOrderedRenderables().peek();
}
}
//**************************************************************//
//******************** Airspace Rendering ********************//
//**************************************************************//
protected void drawAirspaces(DrawContext dc, Iterable<? extends Airspace> airspaces, PickSupport pickSupport)
{
if (dc == null)
{
String msg = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
if (airspaces == null)
{
String msg = Logging.getMessage("nullValue.AirspaceIterableIsNull");
Logging.logger().severe(msg);
throw new IllegalArgumentException(msg);
}
for (Airspace airspace : airspaces)
{
try
{
if (airspace != null)
{
this.drawAirspace(dc, airspace, pickSupport);
}
}
catch (Exception e)
{
String message = Logging.getMessage("generic.ExceptionWhileRenderingAirspace");
Logging.logger().log(java.util.logging.Level.SEVERE, message, e);
}
}
}
protected void drawAirspace(DrawContext dc, Airspace airspace, PickSupport pickSupport)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (airspace == null)
{
String message = Logging.getMessage("nullValue.AirspaceIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
try
{
if (pickSupport != null)
{
this.bindPickableObject(dc, airspace, pickSupport);
}
this.doDrawAirspace(dc, airspace);
}
catch (Exception e)
{
String message = Logging.getMessage("generic.ExceptionWhileRenderingAirspace");
Logging.logger().log(java.util.logging.Level.SEVERE, message, e);
}
}
protected void doDrawAirspace(DrawContext dc, Airspace airspace)
{
if (!airspace.isVisible())
return;
if (!airspace.isAirspaceVisible(dc))
return;
this.drawAirspaceShape(dc, airspace);
if (!dc.isPickingMode())
{
if (this.isDrawExtents())
airspace.renderExtent(dc);
}
}
protected void drawAirspaceShape(DrawContext dc, Airspace airspace)
{
// Draw the airspace shape using a multiple pass algorithm. The motivation for this algorithm is twofold:
//
// 1. We want to draw the airspace on top of other intersecting shapes with similar depth values to eliminate
// z-fighting between shapes. However we do not wish to offset the actual depth values, which would cause
// a cascading increase in depth offset when many shapes are drawn.
// 2. The airspace outline appears both in front of and behind the shape. If the outline will be drawn using
// GL line smoothing, or GL blending, then either the line must be broken into two parts, or rendered in
// two passes.
//
// These issues are resolved by making several passes for the interior and outline, as follows:
GL gl = dc.getGL();
// If the outline and interior will be drawn, then draw the outline color, but do not affect the depth buffer
// (outline pixels do not need the depth test). When the interior is drawn, it will draw on top of these
// colors, and the outline will be visible behind the potentially transparent interior.
if (airspace.getAttributes().isDrawOutline() && airspace.getAttributes().isDrawInterior())
{
gl.glColorMask(true, true, true, true);
gl.glDepthMask(false);
this.drawAirspaceOutline(dc, airspace);
}
// If the interior will be drawn, then make two passes as follows. The first pass draws the interior depth
// values to the depth buffer without any polygon offset. This enables the shape to contribute to the depth
// buffer and occlude other geometries as it normally would. The second pass draws the interior color values
// with offset depth values, but does not affect the depth buffer. This has the effect of givign this airspace
// depth priority over whatever is already in the depth buffer. By rendering the depth values normally, we
// avoid the problem of having to use ever increasing depth offsets.
if (airspace.getAttributes().isDrawInterior())
{
if (this.isEnableDepthOffset())
{
// Draw depth.
gl.glColorMask(false, false, false, false);
gl.glDepthMask(true);
gl.glPolygonOffset(0, 0);
this.drawAirspaceInterior(dc, airspace);
// Draw color.
gl.glColorMask(true, true, true, true);
gl.glDepthMask(false);
gl.glPolygonOffset((float) this.getDepthOffsetFactor(), (float) this.getDepthOffsetUnits());
this.drawAirspaceInterior(dc, airspace);
}
else
{
gl.glColorMask(true, true, true, true);
gl.glDepthMask(true);
this.drawAirspaceInterior(dc, airspace);
}
}
// If the outline will be drawn, then draw the outline color, but do not affect the depth buffer (outline
// pixels do not need the depth test). This will blend outline pixels with the interior pixels which are
// behind the outline.
if (airspace.getAttributes().isDrawOutline())
{
gl.glColorMask(true, true, true, true);
gl.glDepthMask(false);
this.drawAirspaceOutline(dc, airspace);
}
}
protected void drawAirspaceInterior(DrawContext dc, Airspace airspace)
{
if (!dc.isPickingMode())
{
if (this.isEnableLighting())
{
dc.getGL().glEnable(GL.GL_LIGHTING);
}
airspace.getAttributes().applyInterior(dc, this.isEnableLighting());
}
airspace.renderGeometry(dc, Airspace.DRAW_STYLE_FILL);
}
protected void drawAirspaceOutline(DrawContext dc, Airspace airspace)
{
if (dc.isPickingMode())
{
double lineWidth = airspace.getAttributes().getOutlineWidth();
// If the airspace interior isn't drawn, make the outline wider during picking.
if (!airspace.getAttributes().isDrawInterior())
{
if (lineWidth != 0.0)
lineWidth += this.getLinePickWidth();
}
dc.getGL().glLineWidth((float) lineWidth);
}
else
{
if (this.isEnableLighting())
{
dc.getGL().glDisable(GL.GL_LIGHTING);
}
airspace.getAttributes().applyOutline(dc, false);
}
airspace.renderGeometry(dc, Airspace.DRAW_STYLE_OUTLINE);
}
protected void beginRendering(DrawContext dc)
{
if (dc == null)
{
String message = Logging.getMessage("nullValue.DrawContextIsNull");
Logging.logger().severe(message);
throw new IllegalArgumentException(message);
}
if (dc.getGL() == null)
{
String message = Logging.getMessage("nullValue.DrawingContextGLIsNull");
Logging.logger().severe(message);
throw new IllegalStateException(message);
}
GL gl = dc.getGL();
gl.glPushClientAttrib(GL.GL_CLIENT_VERTEX_ARRAY_BIT);
gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
if (!dc.isPickingMode())
{
int attribMask =
(this.isEnableLighting() ? GL.GL_LIGHTING_BIT : 0) // For lighting, material, and matrix mode
| GL.GL_COLOR_BUFFER_BIT // For color write mask. If blending is enabled: for blending src and func, and alpha func.
| GL.GL_CURRENT_BIT // For current color.
| GL.GL_DEPTH_BUFFER_BIT // For depth test, depth func, depth write mask.
| GL.GL_LINE_BIT // For line width, line smoothing.
| GL.GL_POLYGON_BIT // For polygon mode, polygon offset.
| GL.GL_TRANSFORM_BIT; // For matrix mode.
gl.glPushAttrib(attribMask);
if (this.isDrawWireframe())
{
gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE);
}
if (this.isEnableBlending())
{
this.setBlending(dc);
}
if (this.isEnableLighting())
{
gl.glEnableClientState(GL.GL_NORMAL_ARRAY);
this.setLighting(dc);
}
if (this.isEnableAntialiasing())
{
gl.glEnable(GL.GL_LINE_SMOOTH);
}
}
else
{
int attribMask =
GL.GL_CURRENT_BIT // For current color.
| GL.GL_DEPTH_BUFFER_BIT // For depth test and depth func.
| GL.GL_LINE_BIT; // For line width.
gl.glPushAttrib(attribMask);
}
if (this.isEnableDepthOffset())
{
gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
}
gl.glEnable(GL.GL_DEPTH_TEST);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -