You can split the screen and look into the 3D scene from different camera angles at the same time.
The packages used in this example are com.jme3.renderer.Camera and com.jme3.renderer.ViewPort. You can get the full sample code here: TestMultiViews.java
The default viewPort is as big as the window. If you have several, the must be of different sizes, either overlapping or adjacent to one another. How do you tell jME which of the ViewPorts should appear where on the screen, and how big it should be?
Imagine the window as a 1.0f x 1.0f rectangle. The default cam's viewPort is set to
cam.setViewPort(0f, 1f, 0f, 1f);
This setting makes the ViewPort take up the whole rectangle.
The four values are read in the following order:
cam.setViewPort(x1,x2 , y1,y2);
Here are a few examples:
cam1.setViewPort( 0.0f , 1.0f , 0.0f , 1.0f ); cam2.setViewPort( 0.5f , 1.0f , 0.0f , 0.5f );
These viewport parameters are, (in this order) the left-right extend, and the bottom-top extend of a views's rectangle on the screen.
0.0 , 1.0 1.0 , 1.0
+-----+-----+
|cam1 |
| |
| +-----+
| | |
| |cam2 |
+-----+-----+
0.0 , 0.0 1.0 , 0.0
Example: Cam2's rectangle is int he bottom right: It extends from mid (x1=0.5f) bottom (y1=0.0f), to right (x2=1.0f) mid (y2=0.5f)
Camera cam5 = new Camera(100,100);
In this example, you create four views (2x2) with the same aspect ratio as the window, but each is only half the width and height.
You use the preconfigured Camera cam and viewPort from SimpleApplication for the first view. It's in the bottom right.
cam.setViewPort(.5f, 1f, 0f, 0.5f); // Resize the viewPort to half its size, bottom right.
Optionally, place the main camera in the scene and rotate it in its start position.
cam.setLocation(new Vector3f(3.32f, 4.48f, 4.28f)); cam.setRotation(new Quaternion (-0.07f, 0.92f, -0.25f, -0.27f));
Here is the outline for how you create the three other cams and viewPorts (Full code sample is here.) In the code snippet, cam_n stand for cam_2 - cam_4, respectively, same for view_n.
Here is the abstract code sample for camera n:
Camera cam_n = cam.clone(); cam_n.setViewPort(...); // resize the viewPort cam_n.setLocation(new Vector3f(...)); cam_n.setRotation(new Quaternion(...)); ViewPort view_n = renderManager.createMainView("View of camera #n", cam_n); view_n.setClearEnabled(true); view_n.attachScene(rootNode); view_n.setBackgroundColor(ColorRGBA.Black);
To visualize what you do, use the following drawing of the viewport positions:
0.0 , 1.0 1.0 , 1.0
+-----+-----+
| | |
|cam3 |cam4 |
+-----------+
| | |
|cam2 |cam1 |
+-----+-----+
0.0 , 0.0 1.0 , 0.0
This are the lines of code that set the four cameras to create a four-times split screen.
cam1.setViewPort( 0.5f , 1.0f , 0.0f , 0.5f); ... cam2.setViewPort( 0.0f , 0.5f , 0.0f , 0.5f); ... cam3.setViewPort( 0.0f , 0.5f , 0.5f , 1.0f); ... cam4.setViewPort( 0.5f , 1.0f , 0.5f , 1.0f);
The following code snippet sets up two views, one covers the whole screen, and the second is a small view in the top center.
+-----+-----+
| |cam| |
| | 2 | |
+ +---+ +
| |
| cam |
+-----+-----+
// Setup first full-window view cam.setViewPort(0f, 1f, 0f, 1f); cam.setLocation(new Vector3f(3.32f, 4.48f, 4.28f)); cam.setRotation(new Quaternion(-0.07f, 0.92f, -0.25f, -0.27f)); // Setup second, smaller PiP view Camera cam2 = cam.clone(); cam2.setViewPort(.4f, .6f, 0.8f, 1f); cam2.setLocation(new Vector3f(-0.10f, 1.57f, 4.81f)); cam2.setRotation(new Quaternion(0.00f, 0.99f, -0.04f, 0.02f)); ViewPort viewPort2 = renderManager.createMainView("PiP", cam2); viewPort2.setClearFlags(true, true, true); viewPort2.attachScene(rootNode);
You can customize the camera and the viewPort of each view individually. For example, each view can have a different background color:
viewPort.setBackgroundColor(ColorRGBA.Blue);
You have full control to determine which Nodes the camera can see! It can see the full rootNode…
viewPort1.attachScene(rootNode);
… or you can give each camera a special node whose content it can see:
viewPort2.attachScene(spookyGhostDetectorNode);