Class EmulGLCanvas

java.lang.Object
java.awt.Component
java.awt.Canvas
jgl.wt.awt.GLCanvas
org.jzy3d.plot3d.rendering.canvas.EmulGLCanvas
All Implemented Interfaces:
ImageObserver, MenuContainer, Serializable, Accessible, IMonitorable, ICanvas, IScreenCanvas

public class EmulGLCanvas extends GLCanvas implements IScreenCanvas, IMonitorable
This canvas allows rendering charts with jGL as OpenGL backend which perform in CPU. The below schema depicts how this canvas does painting :
Author:
Martin Pernollet
See Also:
  • Field Details

    • TO_BE_CHOOSEN_REPAINT_WITH_FLUSH

      public static final boolean TO_BE_CHOOSEN_REPAINT_WITH_FLUSH
      Specify actual way of forcing repaint
      • if true : manual
      • if false : trigger component.resize event to force resize + view.render + glFlush + swap image
      See Also:
    • view

      protected View view
    • painter

      protected EmulGLPainter painter
    • animator

      protected IAnimator animator
    • canvasListeners

      protected List<ICanvasListener> canvasListeners
    • isRenderingFlag

      protected AtomicBoolean isRenderingFlag
    • debugEvents

      protected boolean debugEvents
      set to TRUE to show in console events of the component (to debug GLUT)
    • profileDisplayMethod

      protected boolean profileDisplayMethod
      set to TRUE to overlay performance info on top left corner
    • profileDisplayTimer

      protected TicToc profileDisplayTimer
    • profileDisplayFont

      protected Font profileDisplayFont
    • profileDisplayCount

      protected int profileDisplayCount
    • profileInfo

      protected List<org.jzy3d.plot3d.rendering.canvas.EmulGLCanvas.ProfileInfo> profileInfo
    • monitor

      protected Monitor monitor
    • exporter

      protected AWTImageExporter exporter
    • executor

      protected ExecutorService executor
    • lastRenderingTimeMs

      protected double lastRenderingTimeMs
  • Constructor Details

    • EmulGLCanvas

      public EmulGLCanvas(IChartFactory factory, Scene scene, Quality quality)
      Initialize a canvas for rendering 3D
  • Method Details

    • processEvent

      public void processEvent(AWTEvent e)
      Description copied from class: GLCanvas
      This override let GLUT.processEvent(AWTEvent) be informed of AWTEvent traversing this canvas (mouse, keyboard, resize). One should register GLUT.glutDisplayFunc(String) to register a display callback, GLUT.glutMotionFunc(String) to register a mouse motion callback, etc. NB : This relies on the fact the GLUT already invoked
      invalid @link
      {@link this#glut_enable_events
      }.
      Overrides:
      processEvent in class GLCanvas
    • shouldPrintEvent

      protected boolean shouldPrintEvent(AWTEvent e)
    • init

      protected void init(int width, int height)
      Equivalent to registering a Renderer3d in native canvas.
    • initView

      protected void initView()
    • initGLUT

      protected void initGLUT(int width, int height)
      Configure GLUT callback which yield to the below flow diagram
    • paint

      public void paint(Graphics g)
      This overrides the GLCanvas hence Canvas methods to copy the image of the 3D scene as generated while GL.glFlush(). It is called when the application needs to paint the canvas, which assume a rendering has already been process by doRender() which produce an image that the canvas can use for fast pixel swap. doRender() on its side is triggered when GLUT thinks it is relevant. This may occur because EmulGLCanvas triggered a
      invalid @link
      ComponentEvent.COMPONENT_RESIZED
      event.
      Overrides:
      paint in class GLCanvas
    • display

      public void display()
      Specified by:
      display in interface IScreenCanvas
    • forceRepaint

      public void forceRepaint()
      Can be used to update image if camera has changed position. (usually called by View.shoot()) Warning if this is invoked by a thread external to AWT, this may redraw GL while GL is already used by AWT, which would turn GL into an inconsistent state.
      Specified by:
      forceRepaint in interface ICanvas
      Overrides:
      forceRepaint in class GLCanvas
    • doRender

      public void doRender()
      Triggers an atomic rendering of a frame, measure rendering performance and update the status of rendering (active or not). This method is callback registered in with GLUT.glutDisplayFunc(Consumer) which will be called when OpenGL need to update display. OpenGL updates as soon as the component that GLUT listen to (which is this EmulGLCanvas triggers a
      invalid @link
      ComponentEvent.COMPONENT_RESIZED
      event. Performance measurement can be seen on screen if setProfileDisplayMethod(boolean) was set to true OR can be collected by a Monitor defined by add(Monitor). This method is synchronized to prevent multiple concurrent calls to doDisplay which might make jGL get crazy with GL state consistency : GL states must be consistent during a complete rendering pass, and should not be modified by a second rendering pass in the middle of the first one. Consistency may be on drawing a complete geometry in appropriate order (glBegin, glVertex, glEnd) or in the way OpenGL 1.0 fixed pipeline is cleanly handled. In addition, the display method has a isRenderingFlag so that external components may known that the canvas is currently rendering or not. This allows ignoring a rendering query in case the canvas is not ready for working. This is different from making use of synchronized (which lead to a queue of calls to be resolved) in that one may simply not append work to do according to the status of the canvas.
    • printCallTrace

      public void printCallTrace()
    • printCallTrace

      public void printCallTrace(int from, String filterLine)
      Print stack but drops any class.method name not containing the filter (in case it is not null)
    • getLastRenderingTimeMs

      public double getLastRenderingTimeMs()
      Specified by:
      getLastRenderingTimeMs in interface ICanvas
    • getIsRenderingFlag

      public AtomicBoolean getIsRenderingFlag()
    • doReshape

      public void doReshape(int w, int h)
      Handle resize events emitted by GLUT. GLUT.processComponentEvent(ComponentEvent) is calling reshape handler (this method) THEN the display handler (
      invalid @link
      {@link #doDisplay()), so this method will only inform {@link GLUT
      } and View that window size changed.
    • doMotion

      public void doMotion(int x, int y)
      Handle mouse events emitted by GLUT. Most probably not registered as mouse already handled by Jzy3D.
    • screenshot

      public BufferedImage screenshot()
      Specified by:
      screenshot in interface ICanvas
    • screenshot

      public void screenshot(File file) throws IOException
      Specified by:
      screenshot in interface ICanvas
      Throws:
      IOException
    • updatePainterWithGL

      protected void updatePainterWithGL()
      Register EmulGLPainter.
    • getView

      public View getView()
      Description copied from interface: ICanvas
      Returns a reference to the held view.
      Specified by:
      getView in interface ICanvas
    • getRendererWidth

      public int getRendererWidth()
      Description copied from interface: ICanvas
      Returns the renderer's width, i.e. the display width.
      Specified by:
      getRendererWidth in interface ICanvas
    • getRendererHeight

      public int getRendererHeight()
      Description copied from interface: ICanvas
      Returns the renderer's height, i.e. the display height.
      Specified by:
      getRendererHeight in interface ICanvas
    • getDimension

      public Dimension getDimension()
      Specified by:
      getDimension in interface ICanvas
    • dispose

      public void dispose()
      Description copied from interface: ICanvas
      Performs all required cleanup when destroying a Canvas.
      Specified by:
      dispose in interface ICanvas
    • setPixelScale

      public void setPixelScale(float[] scale)
      Description copied from interface: ICanvas
      Defines pixel scale. On MacOS Retina displays, a X*Y chart uses a (X*2)*(Y*2) viewport. This makes some calculation based on viewport (such as Camera.screenToModel(IPainter, org.jzy3d.maths.Coord3d) output wrong result. When running on Retina display, those two options fixed buggy mouse selections on Retina:
      • setPixelScale(new float[]{0.5f,0.5f})
      • setPixelScale(new float[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE })
        Specified by:
        setPixelScale in interface ICanvas
      • getPixelScale

        public Coord2d getPixelScale()
        Description copied from interface: ICanvas
        Provide pixel scale as feasible by the Hardware, OS, and JVM, independently of what was asked by ICanvas.setPixelScale(float[]). Hence the two functions may not be consistent together.
        Specified by:
        getPixelScale in interface ICanvas
      • getPixelScaleJVM

        public Coord2d getPixelScaleJVM()
        Description copied from interface: ICanvas
        Provide pixel scale as considered feasible by the JVM.
        Specified by:
        getPixelScaleJVM in interface ICanvas
      • getAnimation

        public IAnimator getAnimation()
        Specified by:
        getAnimation in interface IScreenCanvas
      • addMouseController

        public void addMouseController(Object o)
        Description copied from interface: ICanvas
        A generic interface for mouse listener to remain Windowing toolkit independant. Implementation of this method should simply cast the input assuming it will correspond to canvas-compatible mouse listener.
        Specified by:
        addMouseController in interface ICanvas
      • removeMouseController

        public void removeMouseController(Object o)
        Description copied from interface: ICanvas
        A generic interface for key listener to remain Windowing toolkit independant. Implementation of this method should simply cast the input assuming it will correspond to canvas-compatible key listener.
        Specified by:
        removeMouseController in interface ICanvas
      • addKeyController

        public void addKeyController(Object o)
        Description copied from interface: ICanvas
        A generic interface for mouse listener to remain Windowing toolkit independant. Implementation of this method should simply cast the input assuming it will correspond to canvas-compatible mouse listener.
        Specified by:
        addKeyController in interface ICanvas
      • removeKeyController

        public void removeKeyController(Object o)
        Description copied from interface: ICanvas
        A generic interface for key listener to remain Windowing toolkit independant. * Implementation of this method should simply cast the input assuming it will correspond to canvas-compatible key listener.
        Specified by:
        removeKeyController in interface ICanvas
      • addCanvasListener

        public void addCanvasListener(ICanvasListener listener)
        Specified by:
        addCanvasListener in interface ICanvas
      • removeCanvasListener

        public void removeCanvasListener(ICanvasListener listener)
        Specified by:
        removeCanvasListener in interface ICanvas
      • getCanvasListeners

        public List<ICanvasListener> getCanvasListeners()
        Specified by:
        getCanvasListeners in interface ICanvas
      • firePixelScaleChanged

        protected void firePixelScaleChanged(double pixelScaleX, double pixelScaleY)
      • getDebugInfo

        public String getDebugInfo()
        Specified by:
        getDebugInfo in interface ICanvas
      • paintProfileInfo

        protected void paintProfileInfo(BufferedImage glImage)
        Render profile on top of an image (probably the image of the GL scene) previously collected while
        invalid @link
        {@link EmulGLCanvas#doRender().
        Painting profile info is synchronized on the profile info list to ensure it is not modified while drawing (which occurs if synchronization is disabled). Despite we did not observed any lag due to such rendering, it is important to keep in mind that displaying profile information requires a synchronized access to this info list which is on the other side synchronized to protect exporting rendering info of the last call to doRender().
      • profile

        protected void profile(double mili)
      • profile

        protected void profile(String message, int x, int y, Color c)
        Draw a 2d text at the given position
      • profileClear

        protected void profileClear()
      • isDebugEvents

        public boolean isDebugEvents()
      • setDebugEvents

        public void setDebugEvents(boolean debugEvents)
      • isProfileDisplayMethod

        public boolean isProfileDisplayMethod()
      • setProfileDisplayMethod

        public void setProfileDisplayMethod(boolean profileDisplayMethod)
      • checkAlphaChannelOfColorBuffer

        protected void checkAlphaChannelOfColorBuffer(EmulGLPainter painter)
      • printCountGLBegin

        protected void printCountGLBegin()
      • resetCountGLBegin

        protected void resetCountGLBegin()
      • getFullname

        public String getFullname()
        Specified by:
        getFullname in interface IMonitorable
      • getLabel

        public String getLabel()
        Specified by:
        getLabel in interface IMonitorable
      • add

        public void add(Monitor monitor)
        Specified by:
        add in interface IMonitorable
      • monitorRenderingTime

        protected void monitorRenderingTime(Monitor monitor, double mili)
      • getExporter

        public AWTImageExporter getExporter()
      • setExporter

        public void setExporter(AWTImageExporter exporter)
      • isNative

        public boolean isNative()
        Description copied from interface: ICanvas
        Return true if the canvas renders GL with GPU, false if renders GL using CPU executed Java code.
        Specified by:
        isNative in interface ICanvas