Introduction to jReality programming

From JReality Wiki
Jump to: navigation, search

Source file: ViewerAppDemo


This introduction is designed to teach you the basics of jReality programming. It is generally modeled on the User Tutorial. Here, you will learn how to program the capabilities that you there learned how to activate interactively.


Note: At the current time [January 6, 2009], the examples shown here are all available as subsets of a single Java class de.jreality.tutorial.intro.ViewerAppDemo. If you wish to run these examples directly from this class, provide an integer argument to the main() method, in the range 0 to 7, to choose which of the following examples to execute.



Display an empty ViewerApp viewer

Source file: Intro01


This is perhaps the simplest jReality program that does something. In this case, it pops up an empty ViewerApp window.

import de.jreality.ui.viewerapp.ViewerApp;
 
public class ViewerAppDemo {
  
  public static void main(String[] args) {
    
	ViewerApp.display(null);
  }
}


Load a geometry in ViewerApp

Source file: Intro02


Calling ViewerApp.display(SceneGraphNode node) opens the jReality viewer and displays the node node. The node should be an instance of Geometry or SceneGraphComponent if you want to see anything!

The following method reads in the file dodec.off which we used in the User Tutorial. Notice that it's expected that you have a copy of this file in the directory where you are running these examples (see the getResource() method call). If you're using the jReality src-tutorial folder itself, then the file is already present there. Otherwise, you'll need to copy it to wherever you're running these examples.


import java.io.IOException;
import java.net.URL;
 
import de.jreality.reader.Readers;
import de.jreality.scene.SceneGraphComponent;
import de.jreality.util.Input;
 
  private static SceneGraphComponent readDodec() {
    URL url = ViewerAppDemo.class.getResource("dodec.off");
    SceneGraphComponent scp = null;
    try {
      scp = Readers.read(Input.getInput(url));
      scp.setName("Dodecahedron");
    } catch (IOException e) {
      e.printStackTrace();
    }
    return scp;
  }

If you prefer to access the file as a URL, replace the method call shown with

    scp = Readers.read(Input.getInput(
      "http://www3.math.tu-berlin.de/jreality/download/data/dodec.off"));


Pass the component returned from this method to the ViewerApp.display() method. Customize the resulting ViewerApp to display the navigator panel. And finally, encompass the scene.


import de.jreality.util.CameraUtility;
import de.jreality.ui.viewerapp.ViewerApp;
 
public class ViewerAppDemo {
  
  public static void main(String[] args) {
 
    // read geometry and make viewer
    SceneGraphComponent dodecSGC = readDodec();
    ViewerApp va = ViewerApp.display(dodecSGC);
 
    // some viewer settings
    va.setAttachNavigator(true);
    va.setExternalNavigator(false);
    va.update(); // execute changes
	    	
    // encompass the geometry
    CameraUtility.encompass(va.getCurrentViewer());
  }
}


The resulting code should pop up a window looking like this (taken from the User Tutorial):

After loading a dodecahedron

Set appearance attributes

Source file: Intro03

JavaDoc: Appearance

In order to simulate the appearance changes carried out in the user tutorial, we can work directly with the underlying Appearance instances. Here's the code that needs to be added to the main() method above to get the results seen in the User Tutorial:


import java.awt.Color;
import static de.jreality.shader.CommonAttributes.*;
import de.jreality.scene.Appearance;
 
...
 
Appearance ap = dodecSGC.getAppearance();
// change the color and size of the tubes and spheres
// do so without using shader interfaces
ap.setAttribute(LINE_SHADER+"."+DIFFUSE_COLOR, Color.yellow);
ap.setAttribute(LINE_SHADER+"."+TUBE_RADIUS, .05);
ap.setAttribute(POINT_SHADER+"."+DIFFUSE_COLOR, Color.red);
ap.setAttribute(POINT_SHADER+"."+POINT_RADIUS, .1);
ap.setAttribute(POLYGON_SHADER+"."+SMOOTH_SHADING, false);
// turn on transparency for faces but keep tubes and spheres opaque
ap.setAttribute(TRANSPARENCY_ENABLED, true);
ap.setAttribute(OPAQUE_TUBES_AND_SPHERES, true);
ap.setAttribute(POLYGON_SHADER+"."+TRANSPARENCY, .4);


The resulting code should pop up a window looking like this (taken from the User Tutorial):

After loading a dodecahedron

Use shader interfaces

JavaDoc: DefaultPointShader

JavaDoc: DefaultLineShader

JavaDoc: DefaultPolygonShader


We can achieve the same result a bit more cleanly by using shader interfaces instead of direct access to the Appearances. For more on shader interfaces, see article on jReality scene graph, particularly the section on "Shading", for details. Here's what the equivalent code looks like:


import java.awt.Color;
import de.jreality.scene.Appearance;
import de.jreality.shader.DefaultGeometryShader;
import de.jreality.shader.DefaultLineShader;
import de.jreality.shader.DefaultPointShader;
import de.jreality.shader.DefaultPolygonShader;
import de.jreality.shader.ShaderUtility;
import de.jreality.shader.RenderingHintsShader;
...
    Appearance ap = dodecSGC.getAppearance();
    DefaultGeometryShader dgs;
    DefaultLineShader dls;
    DefaultPointShader dpts;
    RenderingHintsShader rhs;
    DefaultPolygonShader dps;
 
    dgs = ShaderUtility.createDefaultGeometryShader(ap, true);
    dls = (DefaultLineShader) dgs.createLineShader("default");
    dls.setDiffuseColor(Color.yellow);
    dls.setTubeRadius(.05);
    dpts = (DefaultPointShader) dgs.createPointShader("default");
    dpts.setDiffuseColor(Color.red);
    dpts.setPointRadius(.1);
    dps = (DefaultPolygonShader) dgs.createPolygonShader("default");
    dps.setSmoothShading(false);
    rhs = ShaderUtility.createDefaultRenderingHintsShader(ap, true);
    rhs.setTransparencyEnabled(true);
    rhs.setOpaqueTubesAndSpheres(true);
    dps.setTransparency(.5);



Set the camera

Source file: Intro05

JavaDoc: Camera


In this example we show how to locate the current camera, and then how to activate stereo mode in the camera. The code to do this is:


    dgs.setShowFaces(false);
    CameraUtility.getCamera(va.getViewerSwitch()).setStereo(true);

Note: the only backend that currently (December, 2008) support stereo viewing is the JOGL backend.


The result should like something like this (except the colors might be different!):


After loading a dodecahedron


Use tools

Building on the example preceding the stereo camera, add the following code in order to display the PickShowTool as was done in the User Tutorial using the "Edit->Add tool..." menu item.


import de.jreality.tools.PickShowTool;
...
    dodecSGC.addTool(new PickShowTool());


Now when your cursor is over the dodecahedron, you should see a small colored sphere representing the current picked point.


Use 2D textures

JavaDoc: Texture2D


First, load a cylinder from the Primitives class, turn off display of lines and points, and set the polygon diffuse color to white:

import de.jreality.geometry.Primitives;
...
    SceneGraphComponent myscene = SceneGraphUtility.createFullSceneGraphComponent("myscene");
    myscene.setGeometry(Primitives.cylinder(20));
    ViewerApp va = myViewerApp(myscene);
    va.update();
    CameraUtility.encompass(va.getViewerSwitch());
    Appearance ap = myscene.getAppearance();
    dgs = ShaderUtility.createDefaultGeometryShader(ap, true);
    dgs.setShowLines(false);
    dgs.setShowPoints(false);
    dps = (DefaultPolygonShader) dgs.createPolygonShader("default");
    dps.setDiffuseColor(Color.white);


To apply a texture to this white cylinder, add the following code. (The file "gridSmall.jpg" needs to be located in the same folder with the source code you are executing, just as the file "dodec.off" in the earlier example.)


import de.jreality.shader.Texture2D;
import de.jreality.shader.ImageData;
import de.jreality.scene.data.AttributeEntityUtility;
import de.jreality.math.MatrixBuilder;
...    
    Texture2D tex2d = (Texture2D) AttributeEntityUtility.
    createAttributeEntity(Texture2D.class, POLYGON_SHADER+"."+TEXTURE_2D,ap, true);
    URL is = ViewerAppDemo.class.getResource("gridSmall.jpg");
    ImageData id = null;
    try {
      id = ImageData.load(new Input(is));
    } catch (IOException ee) {
      ee.printStackTrace();
    }
    tex2d.setImage(id);


It's also possible to replace the Java resource reference above by an http:// address as with the geometry file above. If you want to do this, replace the code with the following:


    Texture2D tex2d = null;
    String textureFileURL = "http://www3.math.tu-berlin.de/jreality/downloads/data/gridSmall.jpg";
    try {
      tex2d = TextureUtility.createTexture(ap, POLYGON_SHADER,textureFileURL);
    } catch (IOException e) {
    }

Finally, apply a scaling matrix to the texture. There won't be many surprises in this section, if you've worked through the User Tutorial since we did everything there using the Bean shell, which means you've already programmed this in Java.

    Matrix foo = new Matrix();
    MatrixBuilder.euclidean().scale(10, 5, 1).assignTo(foo);
    tex2d.setTextureMatrix(foo);

You should now see a picture that looks like this:

Texture mapping

Further options for the Texture2D can be found in the interface de.jreality.shader.Texture2D.


Use transformations

JavaDoc: Transformation


This example shows how to display a ready-made cube from the Primitives class. It also includes the code necessary to stretch the cube using a scaling transformation. The method createFullSceneGraphComponent() is a utility method which creates a SceneGraphComponent which contains an appearance and transformation. Notice also the use of the MatrixBuilder class; it contains a variety of convenience methods for creating and concatenating 4x4 matrices together.


    SceneGraphComponent myscene = SceneGraphUtility.createFullSceneGraphComponent("myscene");
    myscene.setGeometry(Primitives.coloredCube());
    ViewerApp va = myViewerApp(myscene);
    va.update();
    MatrixBuilder.euclidean().scale(2,.8,1).assignTo(myscene);


This code should result in an image like this one from the User Tutorial:


Scaled cube

Conclusion

This concludes the introduction to jReality programming. Return to the Developer Tutorial for further topics.

Previous: Developer Tutorial Developer Tutorial: Contents Next: Display a geometry