Package org.lwjgl.opengl

Source Code of org.lwjgl.opengl.AWTGLCanvas

/*
* Copyright (c) 2002-2008 LWJGL Project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
*   notice, this list of conditions and the following disclaimer in the
*   documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'LWJGL' nor the names of
*   its contributors may be used to endorse or promote products derived
*   from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.lwjgl.opengl;

import org.lwjgl.LWJGLException;
import org.lwjgl.LWJGLUtil;
import org.lwjgl.PointerBuffer;
import org.lwjgl.Sys;

import java.awt.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;

/**
* <p/>
* An AWT rendering context.
* <p/>
*
* @author $Author: spasi $
*         $Id: AWTGLCanvas.java 3418 2010-09-28 21:11:35Z spasi $
* @version $Revision: 3418 $
*/
public class AWTGLCanvas extends Canvas implements DrawableLWJGL, ComponentListener, HierarchyListener {

  private static final long serialVersionUID = 1L;

  private static final AWTCanvasImplementation implementation;
  private boolean update_context;
  private Object SYNC_LOCK = new Object();

  /** The requested pixel format */
  private final PixelFormat pixel_format;

  /** The drawable to share context with */
  private final Drawable drawable;

  /** The ContextAttribs to use when creating the context */
  private final ContextAttribs attribs;

  /** Context handle */
  private PeerInfo peer_info;
  private Context context;

  /**
   * re-entry counter for support for re-entrant
   * redrawing in paint(). It happens when using dialog boxes.
   */
  private int reentry_count;

  /** Tracks whether initGL() needs to be called */
  private boolean first_run;

  static {
    Sys.initialize();
    implementation = createImplementation();
  }

  static AWTCanvasImplementation createImplementation() {
    switch ( LWJGLUtil.getPlatform() ) {
      case LWJGLUtil.PLATFORM_LINUX:
        return new LinuxCanvasImplementation();
      case LWJGLUtil.PLATFORM_WINDOWS:
        return new WindowsCanvasImplementation();
      case LWJGLUtil.PLATFORM_MACOSX:
        return new MacOSXCanvasImplementation();
      default:
        throw new IllegalStateException("Unsupported platform");
    }
  }

  private void setUpdate() {
    synchronized ( SYNC_LOCK ) {
      update_context = true;
    }
  }

  /** This method should only be called internally. */
  public Context getContext() {
    return context;
  }

  /** This method should only be called internally. */
  public Context createSharedContext() throws LWJGLException {
    synchronized ( SYNC_LOCK ) {
      if ( context == null ) throw new IllegalStateException("Canvas not yet displayable");

      return new Context(peer_info, context.getContextAttribs(), context);
    }
  }

  /** Constructor using the default PixelFormat. */
  public AWTGLCanvas() throws LWJGLException {
    this(new PixelFormat());
  }

  /**
   * Create an AWTGLCanvas with the requested PixelFormat on the default GraphicsDevice.
   *
   * @param pixel_format The desired pixel format. May not be null
   */
  public AWTGLCanvas(PixelFormat pixel_format) throws LWJGLException {
    this(GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(), pixel_format);
  }

  /**
   * Create an AWTGLCanvas with the requested PixelFormat on the default GraphicsDevice.
   *
   * @param device       the device to create the canvas on.
   * @param pixel_format The desired pixel format. May not be null
   */
  public AWTGLCanvas(GraphicsDevice device, PixelFormat pixel_format) throws LWJGLException {
    this(device, pixel_format, null);
  }

  /**
   * Create an AWTGLCanvas with the requested PixelFormat on the specified GraphicsDevice.
   *
   * @param device       the device to create the canvas on.
   * @param pixel_format The desired pixel format. May not be null
   * @param drawable     The Drawable to share context with
   */
  public AWTGLCanvas(GraphicsDevice device, PixelFormat pixel_format, Drawable drawable) throws LWJGLException {
    this(device, pixel_format, drawable, null);
  }

  /**
   * Create an AWTGLCanvas with the requested PixelFormat on the specified GraphicsDevice.
   *
   * @param device       the device to create the canvas on.
   * @param pixel_format The desired pixel format. May not be null
   * @param drawable     The Drawable to share context with
   * @param attribs      The ContextAttribs to use when creating the context. (optional, may be null)
   */
  public AWTGLCanvas(GraphicsDevice device, PixelFormat pixel_format, Drawable drawable, ContextAttribs attribs) throws LWJGLException {
    super(implementation.findConfiguration(device, pixel_format));
    if ( pixel_format == null )
      throw new NullPointerException("Pixel format must be non-null");
    addHierarchyListener(this);
    addComponentListener(this);
    this.drawable = drawable;
    this.pixel_format = pixel_format;
    this.attribs = attribs;
  }

  /* (non-Javadoc)
     * @see java.awt.Canvas#addNotify()
     */
  public void addNotify() {
    super.addNotify();
  }

  /* (non-Javadoc)
     * @see java.awt.Component#removeNotify()
     */
  public void removeNotify() {
    synchronized ( SYNC_LOCK ) {
      destroy();
      super.removeNotify();
    }
  }

  /** Set swap interval. */
  public void setSwapInterval(int swap_interval) {
    synchronized ( SYNC_LOCK ) {
      if ( context == null )
        throw new IllegalStateException("Canvas not yet displayable");
      Context.setSwapInterval(swap_interval);
    }
  }

  /** Enable vsync */
  public void setVSyncEnabled(boolean enabled) {
    setSwapInterval(enabled ? 1 : 0);
  }

  /** Swap the canvas' buffer */
  public void swapBuffers() throws LWJGLException {
    synchronized ( SYNC_LOCK ) {
      if ( context == null )
        throw new IllegalStateException("Canvas not yet displayable");
      Context.swapBuffers();
    }
  }

  public boolean isCurrent() throws LWJGLException {
    synchronized ( SYNC_LOCK ) {
      if ( context == null ) throw new IllegalStateException("Canvas not yet displayable");

      return context.isCurrent();
    }
  }

  /**
   * Make the canvas' context current. It is highly recommended that the context
   * is only made current inside the AWT thread (for example in an overridden paintGL()).
   */
  public void makeCurrent() throws LWJGLException {
    synchronized ( SYNC_LOCK ) {
      if ( context == null )
        throw new IllegalStateException("Canvas not yet displayable");
      context.makeCurrent();
    }
  }

  public void releaseContext() throws LWJGLException {
    synchronized ( SYNC_LOCK ) {
      if ( context == null )
        throw new IllegalStateException("Canvas not yet displayable");
      if ( context.isCurrent() )
        Context.releaseCurrentContext();
    }
  }

  /** Destroy the OpenGL context. This happens when the component becomes undisplayable */
  public final void destroy() {
    synchronized ( SYNC_LOCK ) {
      try {
        if ( context != null ) {
          context.forceDestroy();
          context = null;
          reentry_count = 0;
          peer_info.destroy();
          peer_info = null;
        }
      } catch (LWJGLException e) {
        throw new RuntimeException(e);
      }
    }
  }

  public final void setCLSharingProperties(final PointerBuffer properties) throws LWJGLException {
    synchronized ( SYNC_LOCK ) {
      if ( context == null )
        throw new IllegalStateException("Canvas not yet displayable");
      context.setCLSharingProperties(properties);
    }
  }

  /**
   * Override this to do initialising of the context.
   * It will be called once from paint(), immediately after
   * the context is created and made current.
   */
  protected void initGL() {
  }

  /** Override this to do painting */
  protected void paintGL() {
  }

  /**
   * The default paint() operation makes the context current and calls paintGL() which should
   * be overridden to do GL operations.
   */
  public final void paint(Graphics g) {
    LWJGLException exception = null;
    synchronized ( SYNC_LOCK ) {
      if ( !isDisplayable() )
        return;
      try {
        if ( peer_info == null ) {
          this.peer_info = implementation.createPeerInfo(this, pixel_format);
        }
        peer_info.lockAndGetHandle();
        try {
          if ( context == null ) {
            this.context = new Context(peer_info, attribs, drawable != null ? ((DrawableLWJGL)drawable).getContext() : null);
            first_run = true;
          }

          if ( reentry_count == 0 )
            context.makeCurrent();
          reentry_count++;
          try {
            if ( update_context ) {
              context.update();
              update_context = false;
            }
            if ( first_run ) {
              first_run = false;
              initGL();
            }
            paintGL();
          } finally {
            reentry_count--;
            if ( reentry_count == 0 )
              Context.releaseCurrentContext();
          }
        } finally {
          peer_info.unlock();
        }
      } catch (LWJGLException e) {
        exception = e;
      }
    }
    if ( exception != null )
      exceptionOccurred(exception);
  }

  /**
   * This method will be called if an unhandled LWJGLException occurs in paint().
   * Override this method to be notified of this.
   *
   * @param exception The exception that occurred.
   */
  protected void exceptionOccurred(LWJGLException exception) {
    LWJGLUtil.log("Unhandled exception occurred, skipping paint(): " + exception);
  }

  /** override update to avoid clearing */
  public void update(Graphics g) {
    paint(g);
  }

  public void componentShown(ComponentEvent e) {
  }

  public void componentHidden(ComponentEvent e) {
  }

  public void componentResized(ComponentEvent e) {
    setUpdate();
  }

  public void componentMoved(ComponentEvent e) {
    setUpdate();
  }

  public void setLocation(int x, int y) {
    super.setLocation(x, y);
    setUpdate();
  }

  public void setLocation(Point p) {
    super.setLocation(p);
    setUpdate();
  }

  public void setSize(Dimension d) {
    super.setSize(d);
    setUpdate();
  }

  public void setSize(int width, int height) {
    super.setSize(width, height);
    setUpdate();
  }

  public void setBounds(int x, int y, int width, int height) {
    super.setBounds(x, y, width, height);
    setUpdate();
  }

  public void hierarchyChanged(HierarchyEvent e) {
    setUpdate();
  }

}
TOP

Related Classes of org.lwjgl.opengl.AWTGLCanvas

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.