Chapter 2 : Drawables

Overview

Drawable objects are organized into a hierarchy that reflects features they offer. The below section explain features provided by Drawables, Wireframeables, and Composites objects.

drawableHierarchy

Any shape (e.g. Sphere) implementing Enlightable, Selectable, or Pickable, will have as actual class name EnlightableSphere, SelectableSphere, or PickableSphere

Base features

Drawables

AbstractDrawable objects make use of OpenGL primitives. JOGL exposes a GL context allowing to call OpenGL native methods. Thus, a drawable object is expected to implement the method: public void draw(GL gl, GLU glu, Camera camera) where:

  • gl is the GL context of the canvas in which you render your drawables.
  • glu is a global GLU instance provided by the View.
  • camera is a Camera instance provided by the View. It let you define rendering relative to the camera position. Let’s dive into the draw() method implementation of a Point object:
public void draw(IPainter painter){
  if(transform!=null)
    transform.execute(gl);
  gl.glPointSize(width);
  gl.glBegin(GL.GL_POINTS);
  gl.glColor4f(rgb.r, rgb.g, rgb.b, rgb.a);
  gl.glVertex3f(xyz.x, xyz.y, xyz.z);
  gl.glEnd();
}

As shown by the above piece of code, drawing imply first to apply a current transform to the object which is most frequently provided by the View. Then the implementation simply calls the required open GL functions to render the object, according to its properties (position, color, etc). Objects implementing Drawable have the following properties available:

  • Transform
  • BoundingBox3d
  • Legend
  • Is object displayed
  • Is legend displayed
  • DrawableListener(s)

A drawable object may then be

  • singled colored, and implementing ISingleColorable
  • colored by a a Colormap, and implementing IMultiColorable

The actual geometry of the object must be defined by its implementation. As each object may have its own datamodel, there is no interface method through which you should build your own drawable, but as a convention, Jzy3d uses setData(…)

Wireframeables

Wireframeable objects have additional properties:

  • Wireframe color
  • Wireframe width
  • Wireframe displayed or not
  • Face displayed or not

Among the various wireframeable object, some of them of advanced GL features, especially Polygon that

  • A polygon mode: FRONT / BACK / FRONT_AND_BACK (default). When culling is enabled for rendering, FRONT polygons are rendered when they are facing camera only, whereas BACK polygons are rendered when there back is facing to the camera only.
  • A polygon offset mode: (ON / OFF). Ability to very slightly change the polygon face and wireframe position at rendering to avoid pitfalls with the Open GL Z-Buffer when the chart is not enabled for alpha.

Composites

Composite are collections of other drawable object. The purpose of this class is to provide an implementation that delegates all above mentioned properties setting to its children. Among the different available composites, CompilableComposite is able to compile its GL work into a GL display list for faster rendering. It is especially usefull for large surface such as chromatograms (see demos.surface.big).

Enlightables

Enlightable objects basically hold as properties those provided by OpenGL concerning lights:

  • Material emission color
  • Material specular reflection color
  • Material diffuse reflection color
  • Material ambient reflection color
  • Material shininess

Selectable

Drawable objects that implement Selectable are able to

  • process(…) and hold the result of their own 2d projection on the screen
  • Compute their convex hull Projection of selectable objects is scheduled by a dedicated SelectableView. See chapter “Interactive objects” for more information.

Pickable

Drawable objects that implement Pickable are simply able to store an object ID that is used to identify which objects stand within a given small region around the mouse. See chapter “Interactive objects” for more information.

Textured

Texture support lets you build drawable objects based on X, Y, or Z planes holding a texture.

One can use a TextureCube and a TexturedCylinder (that supports textures on top and bottom but not on the edge, as a cylinder edge is not a plane).

Masks

Masks are PNG images made of white pixels describing the pattern you want to draw, and translucent pixels elsewhere. Using a pair of masks, one can build a face symbol and its negative masks (the one having white pixels where the primary symbol mask has translucent pixels), and apply dynamic coloring on the masks. With that feature, you may edit a catalog of drawable skins, and inject them as Jzy3d drawables. Here is how one can setup a cube volume with masks and coloring:

SharedTexture t1 = TextureFactory.get("data/textures/masks/sharp-bg-100.png");
SharedTexture t2 = TextureFactory.get("data/textures/masks/sharp-sym-100.png");
MaskPair mask = new MaskPair(t1, t2);
TexturedCube cube = new TexturedCube(coord, color, color.negative(), mask);
cube.setAlphaFactor(0.8f);

textured

Faster drawables with Vertex Buffer Objects

All above mentioned primitives involve sending lot of geometrical instructions to the GPU each time the chart must be updated, which happens continuously. For simple objects such as medium size surface, it is not a problem at all, but when working with a 1 million polygon objects, the chart rendering is slowing down. Vertex Buffer Objects are able to store the whole object geometry in the GPU memory at the beginning of the program, and then query transforms or rendering very efficiently without intense communication between CPU and GPU.

DrawableVBO2 is a base implementation allowing to send single colored objects out of .OBJ file or .MAT files. As reading such file must occur when a GL context is available, one must use a IGLLoader (such as OBJFileLoader or MatlabVBOLoader) that is able to mount the object geometry to the GPU once the program initialize the GL contexts.

See VBO in action in org.jzy3d.demos.vbo, and compare rendering speed with org.jzy3d.demos.matlab relying on same files but using non VBO rendering.

Text

Text renderers

The API provides few utility classes to deal with Strings to be rendered at a given 3d coordinate, that will always face the camera whatever the viewpoint.

On top of all text related classes hierarchy stands the ITextRenderer interface. It will show you that all text renderers support:

  • a text color
  • a horizontal alignement (left, right, or center)
  • a vertical alignement (top, ground, center, bottom)
  • an 2D offset, relative to the screen
  • a 3D offset, relative to the scene

Looking at the interface, you may also notice that calling drawText(…) will let you retrieve a BoundingBox3d, that lets you know the actual space occupied by the text with the current scale and viewpoint.

The two first text renderers, TextBillboardRenderer and TextBitmapRenderer share these common features:

  • they do not resize when the scene scale changes.
  • they are made of a single non resizable font
  • they render ASCII characters (a square will be displayed for non supported characters).

The JOGLTextRenderer is different:

  • text is resized when the scene scale changes.
  • it supports any java Font
  • it supports a ITextStyle.

textRenderers

Drawable text

One may wish to treat texts as standard 3d drawable objects. The DrawableTextWrapper utility let you embed a renderer to setup text, alignement, offsets and color through properties. See the dedicated DrawableTextBitmap and DrawableTextBillboard that wrap the text renderers mentioned by their name.