package org.jzy3d.plot3d.rendering.canvas;

import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelListener;
import java.io.File;
import java.io.IOException;

import org.jzy3d.chart.factories.IChartComponentFactory;
import org.jzy3d.plot3d.rendering.scene.Scene;
import org.jzy3d.plot3d.rendering.view.Renderer3d;
import org.jzy3d.plot3d.rendering.view.View;

import com.jogamp.nativewindow.ScalableSurface;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GLCapabilitiesImmutable;
import com.jogamp.opengl.GLDrawable;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.util.texture.TextureData;
import com.jogamp.opengl.util.texture.TextureIO;

/**
 * {@link CanvasAWT} is a base implementation that primarily allows to integrate
 * a Jzy3d chart in an AWT application.
 * 
 * Relying on JOGL's {@link GLPanel}, this canvas can actually be used in AWT,
 * Swing, as well as SWT through
 * org.jzy3d.bridge.swt.Bridge.adapt(swt,awt).
 * 
 * 
 * @author Martin Pernollet
 */
public class CanvasAWT extends GLCanvas implements IScreenCanvas {
    public CanvasAWT(IChartComponentFactory factory, Scene scene, Quality quality) {
        this(factory, scene, quality, org.jzy3d.chart.Settings.getInstance().getGLCapabilities());
    }

    public CanvasAWT(IChartComponentFactory factory, Scene scene, Quality quality, GLCapabilitiesImmutable glci) {
        this(factory, scene, quality, glci, false, false);
    }

    /**
     * Initialize a {@link CanvasAWT} attached to a {@link Scene}, with a given
     * rendering {@link Quality}.
     */
    public CanvasAWT(IChartComponentFactory factory, Scene scene, Quality quality, GLCapabilitiesImmutable glci, boolean traceGL, boolean debugGL) {
        super(glci);

        view = scene.newView(this, quality);
        renderer = factory.newRenderer(view, traceGL, debugGL);
        addGLEventListener(renderer);

        setAutoSwapBufferMode(quality.isAutoSwapBuffer());

        if (quality.isAnimated()) {
            animator = new Animator(this);
            getAnimator().start();
        }

        if (quality.isPreserveViewportSize())
            setPixelScale(new float[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE });
    }

    public void setPixelScale(float[] scale) {
        if (scale != null)
            setSurfaceScale(scale);
        else
            setSurfaceScale(new float[] { 1f, 1f });
    }

    @Override
    public void dispose() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                if (animator != null)
                    animator.stop();
                renderer = null;
                view = null;
            }
        }).start();
    }

    @Override
    public String getDebugInfo() {
        GL gl = getView().getCurrentGL();

        StringBuffer sb = new StringBuffer();
        sb.append("Chosen GLCapabilities: " + getChosenGLCapabilities() + "\n");
        sb.append("GL_VENDOR: " + gl.glGetString(GL.GL_VENDOR) + "\n");
        sb.append("GL_RENDERER: " + gl.glGetString(GL.GL_RENDERER) + "\n");
        sb.append("GL_VERSION: " + gl.glGetString(GL.GL_VERSION) + "\n");
        // sb.append("INIT GL IS: " + gl.getClass().getName() + "\n");
        return sb.toString();
    }

    @Override
    public void forceRepaint() {
        if (true) {
            // -- Method1 --
            // Display() is required to use the GLCanvas procedure and to ensure
            // that GL2 rendering occurs in the
            // GUI thread.
            // Actually it seems to be a bad idea, because this call implies a
            // rendering out of the excepted GL2 thread,
            // which:
            // - is slower than rendering in GL2 Thread
            // - throws java.lang.InterruptedException when rendering occurs
            // while closing the window
            display();
        } else {
            // -- Method2 --
            // Composite.repaint() is required with post/pre rendering, for
            // triggering PostRenderer rendering
            // at each frame (instead of ). The counterpart is that OpenGL2
            // rendering will occurs in the caller thread
            // and thus in the thread where the shoot() method was invoked (such
            // as AWT if shoot() is triggered
            // by a mouse event.
            //
            // Implies blinking with some JRE version (6.18, 6.17) but not with
            // some other (6.5)
            repaint();
        }
    }

    @Override
    public TextureData screenshot(File file) throws IOException {
        TextureData screen = screenshot();
        TextureIO.write(screen, file);
        return screen;
    }

    @Override
    public TextureData screenshot() {
        renderer.nextDisplayUpdateScreenshot();
        display();
        return renderer.getLastScreenshot();
    }

    public void triggerMouseEvent(java.awt.event.MouseEvent e) {
        processMouseEvent(e);
    }

    public void triggerMouseMotionEvent(java.awt.event.MouseEvent e) {
        processMouseMotionEvent(e);
    }

    public void triggerMouseWheelEvent(java.awt.event.MouseWheelEvent e) {
        processMouseWheelEvent(e);
    }

    @Override
    public void addMouseController(Object o) {
        addMouseListener((java.awt.event.MouseListener) o);
        if (o instanceof MouseWheelListener)
            addMouseWheelListener((MouseWheelListener) o);
        if (o instanceof MouseMotionListener)
            addMouseMotionListener((MouseMotionListener) o);
    }

    @Override
    public void addKeyController(Object o) {
        addKeyListener((java.awt.event.KeyListener) o);
    }

    @Override
    public void removeMouseController(Object o) {
        removeMouseListener((java.awt.event.MouseListener) o);
        if (o instanceof MouseWheelListener)
            removeMouseWheelListener((MouseWheelListener) o);
        if (o instanceof MouseMotionListener)
            removeMouseMotionListener((MouseMotionListener) o);
    }

    @Override
    public void removeKeyController(Object o) {
        removeKeyListener((java.awt.event.KeyListener) o);
    }

    @Override
    public GLDrawable getDrawable() {
        return this;
    }

    @Override
    public Renderer3d getRenderer() {
        return renderer;
    }

    /** Provide a reference to the View that renders into this canvas. */
    @Override
    public View getView() {
        return view;
    }

    /**
     * Provide the actual renderer width for the open gl camera settings, which
     * is obtained after a resize event.
     */
    @Override
    public int getRendererWidth() {
        return (renderer != null ? renderer.getWidth() : 0);
    }

    /**
     * Provide the actual renderer height for the open gl camera settings, which
     * is obtained after a resize event.
     */
    @Override
    public int getRendererHeight() {
        return (renderer != null ? renderer.getHeight() : 0);
    }

    protected View view;
    protected Renderer3d renderer;
    protected Animator animator;
    private static final long serialVersionUID = 980088854683562436L;
}

 

Ads help maintain this website.