Interface ILspPainter

All Superinterfaces:
All Known Subinterfaces:
ILspEditableStyledPainter, ILspLabelPainter, ILspPathLocationLabelPainter, ILspStampLocationLabelPainter
All Known Implementing Classes:
TLsp3DMeshPainter, TLspDensityPainter, TLspLabelPainter, TLspLOSCoveragePainter, TLspOpenFlightPainter, TLspShapePainter, TLspTiledWMSProxyPainter

public interface ILspPainter extends ILspPaintGroupsChangeListener
Paints a visual representation of an object in a view. Examples of visual representations include the geometry of a shape, icons or text labels. The paintObjects method is responsible for the actual painting.

The LuciadLightspeed API provides a small number of ILspPainter implementations that allow you to customize the visualization of domain objects. Most importantly, TLspShapePainter can be used for all ILcdShape objects. This painter is flexibly customizable using the ILspStyler and ILspShapeDiscretizer API.

This means that it is not recommended to implement your own ILspPainter extension, unless if you are certain that your particular use case is not supported by the API. If in doubt, feel free to contact Luciad support to verify that you need to implement your own ILspPainter, and to allow possible future improvements to the API to support your use case.

Paint passes

The paintObjects method will typically be invoked multiple times for each repaint of a view. Each of these calls will receive a different TLspPaintPass argument, based on which the painter must choose a different subset of objects or object representations to draw:
  • Object bodies, labels, etc.;
  • Regular, selected or edited objects;
  • Transparent or opaque objects;
  • Draped or non-draped objects.

See TLspPaintPass for details.

In case a painter wishes to drape objects it should paint these objects when the DRAPING or ALL PaintDraping mode is passed. In addition, the painter should also request and use a terrain context from the view. See ILspTerrainSupport for more details.

Performance considerations

To ensure high performance, painters should consider the following guidelines:
  • paintObjects takes a Collection of domain objects as input. This enables the painter to perform certain optimizations, such as setting common OpenGL state only once, or batching the data of multiple objects for more efficient transfer to the GPU.
  • Painters are encouraged to perform as little work as possible in the calling thread. If expensive processing is required before an object can be painted (e.g. discretization and transformation of its geometry), the painter is advised to perform this processing asynchronously by using the ILspTaskExecutor provided by the view. This implies, however, that not all objects may have been fully processed when a paintObjects call returns. For this reason, the paintObjects method returns a progress object which can be used to indicate to the user that a view is not yet fully up-to-date.
  • Painters can use the ILcdMultiKeyCache provided by the view to cache the visual representations of objects. Note that correct use of the cache also protects the painter against problems that might occur if the same painter instance is used by multiple layers or multiple views.

OpenGL usage

Painters have full access to the OpenGL API via ILcdGLDrawable. There are, however, a few restrictions to which painters must adhere:
  • Not all OpenGL features are guaranteed to be available on all end user systems. Therefore, an ILspPainter must indicate its minimum requirements via the getRequiredOpenGLProfile method. The returned TLspOpenGLProfile can then be checked for compatibility with the view in which the painter is being used.
  • Only the paintObjects method is allowed to render into the view's OpenGL context. Other methods cannot assume that an OpenGL context is active when they are called, unless they have an ILcdGLDrawable argument.
  • All OpenGL state which a painter modifies inside its paintObjects method should be restored before paintObjects returns (e.g. using glPushAttrib and glPopAttrib). This rule ensures that painters do not interfere with one another. The following exceptions apply to this rule:
    • The values of vertex attributes (e.g. the current color, normal or texture coordinates) do not need to be reverted.
    • It is not allowed to change the blending state (i.e. enabling or disabling GL_BLEND or setting glBlendFunc).

Paint group events

Any painter automatically implements ILspPaintGroupsChangeListener. Paint group events can be used to update internal data structures without re-evaluating all the objects. Paint group events describe changes in the list of painted objects due to various external events: model changes, selection changes, view navigation, etc.

In addition, the paint group event mechanism can be used to provide synchronization between different painters (for example, body and label). For this, a two-phased commit cycle is used:

  1. Painter receives ILspPaintGroupsChangeListener.prepareChanges(java.util.List<com.luciad.view.lightspeed.layer.paintgroup.TLspPaintGroupsChangedEvent>, java.lang.Object, com.luciad.view.lightspeed.layer.paintgroup.ILspPaintGroupsChangeListener.Callback)
  2. Painter applies changes on a copy of the internal data structure that is not painted
  3. Painter calls ILspPaintGroupsChangeListener.Callback.changesReady(java.lang.Object) when ready
  4. Painter receives ILspPaintGroupsChangeListener.commitChanges(java.lang.Object)
  5. Painter swaps old data structure with new, so the new data is painted

It is however optional to work this way. You can simply ignore the paint group events, or apply them immediately to your internal data structure. You must however still call ILspPaintGroupsChangeListener.Callback.changesReady(java.lang.Object).

  • Method Details

    • registerLayer

      void registerLayer(ILspInteractivePaintableLayer aLayer, TLspPaintRepresentation aPaintRepresentation)
      Registers a layer with this painter. This notifies the painter that it is going to be used in combination with the given layer, for the given paint representation. This allows it to implement setup code if necessary, or to keep track of all layers on which it is set.

      Layers registered with this method must be unregistered when the layer stops using this painter, using unregisterLayer(ILspInteractivePaintableLayer, com.luciad.view.lightspeed.layer.TLspPaintRepresentation).

      aLayer - A layer with which this painter will be used.
      aPaintRepresentation - The paint representation for which this painter will be used.
    • unregisterLayer

      void unregisterLayer(ILspInteractivePaintableLayer aLayer, TLspPaintRepresentation aPaintRepresentation)
      Unregisters a layer from this painter. This notifies the painter that it will no longer be used in combination with the given layer, for the given paint representation. This allows it to implement cleanup code if necessary.

      Layers unregistered with this method must have been registered before calling this method with the method registerLayer(ILspInteractivePaintableLayer, com.luciad.view.lightspeed.layer.TLspPaintRepresentation).

      aLayer - A layer that needs to be unregistered
      aPaintRepresentation - The paint representation for which this painter was used with aLayer
    • paintObjects

      TLspPaintProgress paintObjects(ILcdGLDrawable aGLDrawable, List<TLspPaintGroup> aPaintGroups, TLspPaintPass aPass, TLspContext aContext)

      Paints the specified groups of objects into a view. The objects are partitioned into TLspPaintGroups, which are created by the layer which invoked this painter. Painters are advised to also implement ILspPaintGroupsChangeListener, which allows them to keep track of changes to the supplied list of paint groups. This way, the painter can exploit temporal coherence and perform its work in the most optimal way.

      This method returns a TLspPaintProgress which describes the completeness of the paint operation. If the painter scheduled one or more tasks to be executed asynchronously, it may return from its paintObjects() method before having rendered all the objects it was given. In this case, the returned progress object can describe the amount of work that has been done and the work that is still remaining.

      aGLDrawable - the ILcdGLDrawable in which the objects are to be painted
      aPaintGroups - the objects to be painted
      aPass - the current paint pass
      aContext - provides context information to the painter
      a TLspPaintProgress object describing the completeness of the paint operation
    • getRequiredOpenGLProfile

      TLspOpenGLProfile getRequiredOpenGLProfile()
      Returns the minimum required OpenGL profile that a view must support in order to be compatible with this painter.
      a TLspGLProfile
    • addPropertyChangeListener

      void addPropertyChangeListener(PropertyChangeListener aPropertyChangeListener)
      Adds a PropertyChangeListener to the list of listeners that must be notified when any of the properties of this ILspPainter changes.
      aPropertyChangeListener - the listener that from now on will be notified of all changes to properties of this painter
    • removePropertyChangeListener

      void removePropertyChangeListener(PropertyChangeListener aPropertyChangeListener)
      Removes a PropertyChangeListener from the list of listeners. This listener will no longer be notified of any changes to the properties of this ILspPainter
      aPropertyChangeListener - the listener that no longer will be notified of any changes to properties of this painter
    • getStyler

      ILspStyler getStyler(TLspPaintState aPaintState)
      Returns the styler used by this painter for the given PaintState. Can return null in case the painter does not use or expose a styler.
      aPaintState - the paint state for which a styler is requested
      the styler used by this object, or null.
    • query

      <T> boolean query(List<TLspPaintGroup> aPaintGroups, ALspPaintQuery<T> aQuery, TLspPaintRepresentationState aPaintRepresentationState, TLspContext aContext)
      Retrieves a set of domain objects and data based on the parameters given by the query.
      aPaintGroups - the paint groups
      aQuery - the query
      aPaintRepresentationState - the paint representation state for which the query should be performed
      aContext - the context
      true if the query completed, false if it was aborted.
      UnsupportedOperationException - if the query is not supported