Class Panel3D

All Implemented Interfaces:
com.jogamp.opengl.GLEventListener, ImageObserver, MenuContainer, Serializable, EventListener, Accessible

public class Panel3D extends JPanel implements com.jogamp.opengl.GLEventListener
Swing component that hosts a JOGL GLJPanel and manages a simple interactive 3D scene.

Panel3D is the central drawing panel used by the MDI-3D extension. It owns the OpenGL panel, the list of Item3D objects to render, the current camera translation, the current scale, and the current orientation. Rotation is stored as a quaternion so mouse-drag arcball rotations compose smoothly without accumulating Euler-angle artifacts.

Subclasses normally customize a panel by overriding createInitialItems(), beforeDraw(GLAutoDrawable), or afterDraw(GLAutoDrawable). Optional Swing components can be placed around the OpenGL canvas by overriding the directional hook methods addNorth(), addSouth(), addEast(), and addWest().

Rendering uses two passes. Opaque items are drawn first with depth writes enabled. Transparent items are then sorted approximately back-to-front and drawn with blending enabled and depth writes disabled. This is not a full order-independent transparency solution, but it is appropriate for the simple educational and diagnostic scenes used by the MDI-3D demos.

The panel supports both unit-scale and large-world scenes. Keyboard panning and mouse-wheel navigation use a configurable navigation step; the default preserves the original small-scene behavior, while larger scenes can call setNavigationStep(float) or setNavigationStepFromExtent(float).

See Also:
  • Field Details

    • BG_DEFAULT

      public static final float BG_DEFAULT
      Default background component used for red, green, and blue.
      See Also:
    • glprofile

      protected com.jogamp.opengl.GLProfile glprofile
    • glcapabilities

      protected com.jogamp.opengl.GLCapabilities glcapabilities
    • gljpanel

      protected final com.jogamp.opengl.awt.GLJPanel gljpanel
      The hosted OpenGL panel, or null if OpenGL could not be initialized on this system (see isGLAvailable()). Every method in this class that touches gljpanel already null-checks it, so a null value here degrades gracefully to a no-op rather than an NPE.
    • glu

      protected com.jogamp.opengl.glu.GLU glu
    • _itemList

      protected Vector<Item3D> _itemList
    • _mouseAdapter

      protected MouseAdapter3D _mouseAdapter
    • _rendererStr

      protected String _rendererStr
    • _versionStr

      protected String _versionStr
  • Constructor Details

    • Panel3D

      public Panel3D(float angleX, float angleY, float angleZ, float xDist, float yDist, float zDist)
      Construct a 3D panel with the default light-gray background.

      The initial orientation is established by resetting the quaternion orientation and then applying rotations about x, y, and z, in that order. The distance parameters are OpenGL model-view translations applied before scaling and rotation.

      Parameters:
      angleX - initial rotation angle about the x axis, in degrees
      angleY - initial rotation angle about the y axis, in degrees
      angleZ - initial rotation angle about the z axis, in degrees
      xDist - initial x translation
      yDist - initial y translation
      zDist - initial z translation
    • Panel3D

      public Panel3D(float angleX, float angleY, float angleZ, float xDist, float yDist, float zDist, float bgRed, float bgGreen, float bgBlue, boolean skipLastStage)
      Construct a 3D panel with an explicit background color.

      The constructor creates the GLJPanel, registers this object as the GLEventListener, installs the MDI-3D keyboard and mouse adapters, and creates any optional border components returned by the directional hook methods. Initial scene contents are created later, when the first OpenGL context is initialized, by calling createInitialItems(). Deferring scene creation avoids invoking an overridable method from this constructor.

      Parameters:
      angleX - initial rotation angle about the x axis, in degrees
      angleY - initial rotation angle about the y axis, in degrees
      angleZ - initial rotation angle about the z axis, in degrees
      xDist - initial x translation
      yDist - initial y translation
      zDist - initial z translation
      bgRed - red component of the background color, in [0, 1]
      bgGreen - green component of the background color, in [0, 1]
      bgBlue - blue component of the background color, in [0, 1]
      skipLastStage - if true, skip the final glLoadIdentity() in display(GLAutoDrawable)
  • Method Details

    • isGLAvailable

      public boolean isGLAvailable()
      Whether OpenGL was successfully initialized for this panel.
      Returns:
      true if this panel has a working GLJPanel; false if GL initialization failed and getGLJPanel() returns null
    • getGLInitError

      public Throwable getGLInitError()
      The reason OpenGL initialization failed, if it did.
      Returns:
      the throwable caught during GL setup, or null if isGLAvailable() is true
    • createInitialItems

      public void createInitialItems()
      Create the initial 3D items for this panel.

      The default implementation is empty. Subclasses normally override this method to populate the panel with axes, lines, surfaces, point clouds, or other Item3D objects.

      The method is invoked once, when the panel's first OpenGL context has been initialized. It is deliberately not called from the Panel3D constructor because subclasses may depend on fields that are not initialized until after the superclass constructor has returned.

      A later OpenGL-context recreation does not rebuild the logical item list. Individual items that own OpenGL resources are responsible for recreating those resources as necessary.

    • addNorth

      protected JComponent addNorth()
      Optional hook for a Swing component on the north side of the panel.

      The default implementation returns null. Subclasses can override this method to add controls, legends, sliders, or other Swing components outside the OpenGL drawing area.

      Returns:
      component to place on the north side, or null
    • addSouth

      protected JComponent addSouth()
      Optional hook for a Swing component on the south side of the panel.

      The default implementation returns null. Subclasses can override this method to add controls, legends, sliders, or other Swing components outside the OpenGL drawing area.

      Returns:
      component to place on the south side, or null
    • addEast

      protected JComponent addEast()
      Optional hook for a Swing component on the east side of the panel.

      The default implementation returns null. Subclasses can override this method to add controls, legends, sliders, or other Swing components outside the OpenGL drawing area.

      Returns:
      component to place on the east side, or null
    • addWest

      protected JComponent addWest()
      Optional hook for a Swing component on the west side of the panel.

      The default implementation returns null. Subclasses can override this method to add controls, legends, sliders, or other Swing components outside the OpenGL drawing area.

      Returns:
      component to place on the west side, or null
    • getGLJPanel

      public com.jogamp.opengl.awt.GLJPanel getGLJPanel()
      Return the JOGL panel hosted by this Swing panel.

      Most callers should interact with Panel3D rather than the raw GLJPanel. This accessor is provided for cases that need direct integration with JOGL or Swing.

      Returns:
      the hosted OpenGL panel
    • setScale

      public void setScale(float xscale, float yscale, float zscale)
      Set the scale factors applied to the scene before rotation.
      Parameters:
      xscale - scale factor in x
      yscale - scale factor in y
      zscale - scale factor in z
    • rotate

      public void rotate(Vector3f axis, float angleRadians)
      Apply an axis-angle rotation to the current orientation.

      This method composes the new rotation with the existing quaternion orientation. The rotation angle is in radians, which matches the values produced by MouseAdapter3D. Invalid or nearly zero-length axes are ignored.

      Parameters:
      axis - rotation axis
      angleRadians - rotation angle, in radians
    • rotateX

      public void rotateX(float angleDeg)
      Rotate the scene about the x axis.
      Parameters:
      angleDeg - rotation angle, in degrees
    • rotateY

      public void rotateY(float angleDeg)
      Rotate the scene about the y axis.
      Parameters:
      angleDeg - rotation angle, in degrees
    • rotateZ

      public void rotateZ(float angleDeg)
      Rotate the scene about the z axis.
      Parameters:
      angleDeg - rotation angle, in degrees
    • loadIdentityMatrix

      public void loadIdentityMatrix()
      Reset the current orientation to the identity rotation.

      Earlier versions of MDI-3D stored the orientation as a matrix. The current implementation stores the orientation as a quaternion; this method preserves the old name while resetting the quaternion to identity.

    • display

      public void display(com.jogamp.opengl.GLAutoDrawable drawable)
      Render the current OpenGL frame.

      JOGL calls this method whenever the GLJPanel needs to draw. The method clears the buffers, applies translation, scale, and quaternion orientation, snapshots the current item list, draws opaque items first, and then draws transparent items in approximate back-to-front order.

      Specified by:
      display in interface com.jogamp.opengl.GLEventListener
      Parameters:
      drawable - JOGL drawable being rendered
    • beforeDraw

      public void beforeDraw(com.jogamp.opengl.GLAutoDrawable drawable)
      Hook called after the model-view transform has been applied and before any items are drawn.

      The default implementation is empty. Subclasses can override this method to draw custom OpenGL content behind the item list.

      Parameters:
      drawable - JOGL drawable being rendered
    • afterDraw

      public void afterDraw(com.jogamp.opengl.GLAutoDrawable drawable)
      Hook called after all items have been drawn and before the model-view matrix is restored.

      The default implementation is empty. Subclasses can override this method to draw custom OpenGL content on top of the item list.

      Parameters:
      drawable - JOGL drawable being rendered
    • init

      public void init(com.jogamp.opengl.GLAutoDrawable drawable)
      Initialize the OpenGL state for this panel.

      JOGL calls this method when the GL context is created. The method records renderer/version strings and configures depth testing, perspective correction, blending, point sizing, and the clear color.

      Specified by:
      init in interface com.jogamp.opengl.GLEventListener
      Parameters:
      drawable - JOGL drawable whose context is being initialized
    • reshape

      public void reshape(com.jogamp.opengl.GLAutoDrawable drawable, int x, int y, int width, int height)
      Update the OpenGL viewport and projection matrix after a resize.

      The projection uses a 45-degree perspective field of view with a broad near/far range appropriate for the simple demo scenes used by MDI-3D.

      Specified by:
      reshape in interface com.jogamp.opengl.GLEventListener
      Parameters:
      drawable - JOGL drawable being reshaped
      x - viewport x origin
      y - viewport y origin
      width - new viewport width
      height - new viewport height
    • deltaX

      public void deltaX(float dx)
      Increment the current x translation.

      Unlike rotateX(float), this does not call refresh() itself — callers (e.g. MouseAdapter3D, KeyAdapter3D) must request a refresh explicitly after the last delta in a batch.

      Parameters:
      dx - change in x translation
    • deltaY

      public void deltaY(float dy)
      Increment the current y translation.

      Unlike rotateY(float), this does not call refresh() itself — callers (e.g. MouseAdapter3D, KeyAdapter3D) must request a refresh explicitly after the last delta in a batch.

      Parameters:
      dy - change in y translation
    • deltaZ

      public void deltaZ(float dz)
      Increment the current z translation.

      Unlike rotateZ(float), this does not call refresh() itself — callers (e.g. MouseAdapter3D, KeyAdapter3D) must request a refresh explicitly after the last delta in a batch.

      Parameters:
      dz - change in z translation
    • refreshQueued

      public void refreshQueued()
      Placeholder for queued refresh support.

      The current implementation is intentionally empty. It is retained for API compatibility with code that may distinguish queued refreshes from immediate or soft refreshes.

    • softRefresh

      public void softRefresh()
      Soft refresh: schedules a repaint through AWT's normal paint mechanism. Use this for layout-driven redraws (resize, move, show). This is safe to call from the EDT and does not race with Swing painting.
    • refresh

      public void refresh()
      Hard refresh: forces an immediate JOGL render. Only call this when you need synchronous GL output, e.g. after a mouse-drag rotation. Do NOT call from component/layout events.
    • reinitGLContext

      public void reinitGLContext()
      Force JOGL to tear down and rebuild the GL context on next paint. Call this once after a lazy view has been made visible with a real native peer, to ensure the FBO is created against the correct surface.
    • addItem

      public void addItem(Item3D item)
      Add an item to the panel.

      If the item is already present, it is moved to the end of the list. Later items are normally drawn later within their opaque/transparent pass.

      The remove-then-add is performed under synchronized(_itemList) so it is atomic with respect to display()'s own synchronized snapshot of _itemList: without this, a concurrent snapshot taken between the remove and the add could observe the item as transiently missing.

      Parameters:
      item - item to add; ignored when null
    • addItem

      public void addItem(int index, Item3D item)
      Add an item at the specified list index.

      If the item is already present, the existing occurrence is removed first.

      Parameters:
      index - insertion index
      item - item to add; ignored when null
    • removeItem

      public void removeItem(Item3D item)
      Remove an item from the panel and refresh the display.
      Parameters:
      item - item to remove; ignored when null
    • clearItems

      public void clearItems()
      Remove all items from the panel and refresh the display.
    • getXScale

      public float getXScale()
      Returns the current X scale factor.
      Returns:
      the current X scale factor
    • getYScale

      public float getYScale()
      Returns the current Y scale factor.
      Returns:
      the current Y scale factor
    • getZScale

      public float getZScale()
      Returns the current Z scale factor.
      Returns:
      the current Z scale factor
    • project

      public void project(com.jogamp.opengl.GL2 gl, float objX, float objY, float objZ, float[] winPos)
      Project object coordinates to window coordinates using the current OpenGL matrices.

      The result is written into winPos: winPos[0] is window x, winPos[1] is window y, and winPos[2] is window z/depth. The caller must provide an array with length at least three.

      Parameters:
      gl - active GL2 context
      objX - object x coordinate
      objY - object y coordinate
      objZ - object z coordinate
      winPos - output array for window coordinates
    • setNavigationStep

      public void setNavigationStep(float navigationStep)
      Set the navigation step used by keyboard panning and mouse-wheel zoom.

      The original default value is suitable for small unit-scale scenes. Larger scenes should set this to a value proportional to the scene extent, for example extent / 50.

      Parameters:
      navigationStep - positive navigation step in world units
    • setNavigationStepFromExtent

      public void setNavigationStepFromExtent(float extent)
      Set the navigation step from a characteristic scene extent.

      This is a convenience method for views whose world coordinates are much larger than order unity. A scene spanning roughly 700 world units, for example, gets a step of about 14 units.

      Parameters:
      extent - characteristic scene extent in world units
    • getZStep

      public float getZStep()
      Return the navigation step used by keyboard panning and mouse-wheel zoom.
      Returns:
      navigation step in world units
    • dispose

      public void dispose(com.jogamp.opengl.GLAutoDrawable drawable)
      Dispose of OpenGL resources associated with this listener.

      Panel3D itself holds no explicit GL resources, but items on the panel may — for example a text-drawing item's lazily-created JOGL TextRenderer, which owns a GPU texture atlas. This gives every item (and its children) a chance to release those via Item3D.disposeItem(GLAutoDrawable) before the GL context goes away, so repeatedly opening and closing 3D views doesn't leak texture memory.

      Specified by:
      dispose in interface com.jogamp.opengl.GLEventListener
      Parameters:
      drawable - JOGL drawable being disposed