2017-10-05 35 views
1

我試圖在美國宇航局的Worldwind中實現自己的雜波濾波器,它引起了一個奇怪的問題 - 雜波濾波器還沒有做很多,但我會用它來移動東西當我通過了「閃爍」的問題。每當鼠標移動時,GlobeAnnotation渲染器都會閃爍。當我將雜波濾鏡設置爲空時,閃爍似乎不會發生。WorldWind Java中的閃爍註釋

這裏是一個GIF圖片,展示了我的意思:https://media.giphy.com/media/xT9IgFiZwYZ3VJHQU8/giphy.gif

我從這裏克隆NASA世界風代碼:https://github.com/NASAWorldWind/WorldWindJava。我做了一些改變,使我的最終過濾器的工作。需要注意的是,我希望GlobeAnnotations顯示爲始終位於其他位置之上。

我該如何讓GlobeAnnotations不會互相爭鬥並且閃爍,但仍然會出現在其他任何事物的頂部 - 同時開啓雜波濾波器?

請注意,以下代碼僅僅是一個示例,我將它們放在一起以顯示我在「真實」應用程序中看到的問題。我希望GlobeAnnotations始終處於一切領先地位 - 但不會閃爍並與對方交戰。

這裏是我的測試車手:

package gov.nasa.worldwindx.examples; 

import java.awt.Color; 

import gov.nasa.worldwind.geom.LatLon; 
import gov.nasa.worldwind.geom.Position; 
import gov.nasa.worldwind.layers.AnnotationLayer; 
import gov.nasa.worldwind.layers.RenderableLayer; 
import gov.nasa.worldwind.render.GlobeAnnotation; 
import gov.nasa.worldwind.render.Material; 
import gov.nasa.worldwind.render.airspaces.CappedCylinder; 

public class FlashyAnnotations extends ApplicationTemplate { 
    @SuppressWarnings("unchecked") 
    private static class AppFrame extends ApplicationTemplate.AppFrame { 

     private AnnotationLayer layer; 

     public AppFrame() { 

      this.getWwd().getSceneController().setClutterFilter(new SimpleClutterFilter()); 

      CappedCylinder cappedCyl = new CappedCylinder(LatLon.fromDegrees(27, -100), 3000000); 
      cappedCyl.getAttributes().setDrawInterior(true); 
      cappedCyl.getAttributes().setInteriorMaterial(Material.GREEN); 
      cappedCyl.getAttributes().setInteriorOpacity(.75f); 
      cappedCyl.setAltitudes(10, 100000); 
      RenderableLayer renderLayer = new RenderableLayer(); 

      renderLayer.addRenderable(cappedCyl); 
      insertBeforeCompass(this.getWwd(), renderLayer); 

      // Create example annotations 
      this.setupAnnotations(); 

     } 

     private void setupAnnotations() { 

      // Create an AnnotationLayer with lots of annotations 
      this.layer = new AnnotationLayer(); 

      GlobeAnnotation ga = new GlobeAnnotation("Annotation", Position.fromDegrees(20, -100.9, 1000)); 
      ga.getAttributes().setTextColor(Color.white); 
      ga.getAttributes().setBackgroundColor(Color.BLACK); 
      ga.getAttributes().setOpacity(.75f); 
      ga.setAlwaysOnTop(true); 
      layer.addAnnotation(ga); 

      ga = new GlobeAnnotation("Annotation", Position.fromDegrees(25, -100.9, 1000)); 
      ga.getAttributes().setTextColor(Color.white); 
      ga.getAttributes().setBackgroundColor(Color.BLACK); 
      ga.getAttributes().setOpacity(.75f); 
      ga.setAlwaysOnTop(true); 
      layer.addAnnotation(ga); 

      // Add layer to the layer list and update the layer panel 
      insertBeforeCompass(this.getWwd(), layer); 
     } 

    } 

    public static void main(String[] args) { 
     ApplicationTemplate.start("WorldWind Annotations", AppFrame.class); 
    } 
} 

這裏是我的(基本上沒有-OP)雜波濾除:

package gov.nasa.worldwindx.examples; 

import java.util.List; 

import gov.nasa.worldwind.render.Declutterable; 
import gov.nasa.worldwind.render.DrawContext; 
import gov.nasa.worldwind.util.ClutterFilter; 

public class SimpleClutterFilter implements ClutterFilter{ 

    @Override 
    public void apply(DrawContext dc, List<Declutterable> shapes) { 
     for(Declutterable shape: shapes) { 
      dc.addOrderedRenderable(shape); 
     } 

    } 

} 

而且我也不得不更新gov.nasa.worldwind.render .BasicAnnotationRenderer將它創建的OrderedAnnotations實現爲Declutterable。 (這個內部類的唯一變化是添加isEnableDecluttering和getBounds):

public class OrderedAnnotation implements OrderedRenderable, Declutterable 
{ 
protected Annotation annotation; 


protected double eyeDistance; 
protected Layer layer; 

public OrderedAnnotation(Annotation annotation, double eyeDistance) 
{ 
    this.annotation = annotation; 
    this.eyeDistance = eyeDistance; 
} 

public OrderedAnnotation(Annotation annotation, Layer layer, double eyeDistance) 
{ 
    this.annotation = annotation; 
    this.eyeDistance = eyeDistance; 
    this.layer = layer; 
} 

public double getDistanceFromEye() 
{ 
    return this.eyeDistance; 
} 

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() instanceof 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); 
    } 
} 

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() instanceof 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 
    } 
} 

protected void doRender(DrawContext dc, OrderedAnnotation oa) 
{ 
    // Swap the draw context's current layer with that of the ordered annotation 
    Layer previousCurrentLayer = dc.getCurrentLayer(); 
    try 
    { 
     dc.setCurrentLayer(oa.layer); 
     oa.annotation.renderNow(dc); 
    } 
    finally 
    { 
     dc.setCurrentLayer(previousCurrentLayer); // restore the original layer 
    } 
} 

@Override 
public boolean isEnableDecluttering() { 
    return (annotation instanceof GlobeAnnotation); 
} 

@Override 
public Rectangle2D getBounds(DrawContext dc) { 
    if(annotation instanceof GlobeAnnotation) { 
     return ((GlobeAnnotation) annotation).computeBounds(dc); 
    } 
    return null; 
} 

} 
+0

看起來像z緩衝渲染閃爍,這發生在多個對象呈現與攝像機相同的距離時。難道你不能手動設置距離(高度邊際差異),以擺脫這一點? – Caramiriel

+0

我認爲既然我想「永遠在上面」設置,眼睛的距離可能會被worldwind邏輯忽略? – systemoutprintln

回答

1

首先;

Draw order of PointPlacemarks

https://forum.worldwindcentral.com/forum/world-wind-java-forums/development-help/13263-layer-priority-order

setupAnnotations方法,設置alwaysOnTop兩個GlobeAnnotation對象爲真。這可能是原因。

private void setupAnnotations() { 

      // Create an AnnotationLayer with lots of annotations 
      this.layer = new AnnotationLayer(); 

      GlobeAnnotation ga = new GlobeAnnotation("Annotation", Position.fromDegrees(20, -100.9, 1000)); 
      ga.getAttributes().setTextColor(Color.white); 
      ga.getAttributes().setBackgroundColor(Color.BLACK); 
      ga.getAttributes().setOpacity(.75f); 
      **ga.setAlwaysOnTop(true);** 
      layer.addAnnotation(ga); 

      ga = new GlobeAnnotation("Annotation", Position.fromDegrees(25, -100.9, 1000)); 
      ga.getAttributes().setTextColor(Color.white); 
      ga.getAttributes().setBackgroundColor(Color.BLACK); 
      ga.getAttributes().setOpacity(.75f); 
      **ga.setAlwaysOnTop(true);** 
      layer.addAnnotation(ga); 

      // Add layer to the layer list and update the layer panel 
      insertBeforeCompass(this.getWwd(), layer); 
     } 

取而代之的是,將要始終在最前面成單獨的層和其餘的到另一個層可以通過使用上面的鏈接是解決方案的註釋。

+0

我希望它們都是真實的 - 因爲我希望註釋能夠在其他任何東西之上 - 但不會互相爭鬥。這只是我放在一起展示問題的一個例子。我會在我的帖子中澄清。 – systemoutprintln

+0

有一個'頂部',所以在這兩個GlobeAnnotation之間競速,並且由於閃爍的發生對我來說是預期的行爲。 –

+0

是的,這可能是正確的 - 但爲什麼當Clutter Filter設置爲null時不會發生? – systemoutprintln