<Introduction to the Camera|User's Guide|Z Fighting>
See Camera Javadoc and AbstractCamera Javadoc
The world has a lot of visible objects, and while a game doesn't have as many, most often it has more than what a computer is capable of displaying at any one time. We, therefore, need a way to limit how much we attempt to render at any given time. We will limit objects to only those contained within the view volume. Anything outside this volume will be culled, and anything in this volume (even partially) will be drawn. This volume will be defined by the view frustum. The Camera will be responsible for setting up this volume, and maintaining it.
This frustum is used for the OpenGL glFrustum call. This not only sets up the Camera for culling (within jME), but is used to set up the perspective mode in OpenGL.
Additionally, the Camera allows the user to control where this frustum is located and how it is oriented. A camera is defined by a coordinate system (actually the Camera defines the coordinate system in the game). The coordinate axes are left, up, and direction. These axes must create a valid right-handed coordinate system. This coordinate for the camera is called its frame. There are a number of ways to set the frame of the camera:
setDirection, setLeft, setUp.setAxes (takes both three axes or a Quaternion)setFrame (again can take three axes or a Quaternion)lookAtThe Camera also maintains the viewport information. The Viewport defines the affine transformation of x and y from normalized device coordinates to window coordinates. This allows renderings to fill a screen no matter the resolution. By default the transformation is set to (0,0) being the bottom left.
When making use of Frustum Culling, every scene leaf (Geometry), should have a Model Bound BoundingVolume assigned. This will allow the scene graph to propograte bounding volumes up the tree to make an efficient bounding tree.
During a frame, every Spatial is checked against the Camera for frustum culling. A call to Camera's contains method with the worldBound of the Spatial will determine if that Spatial should be processed or not. Valid responses from the contains method are:
This gives us a few optimizations. First, if OUTSIDE_FRUSTUM is given, we can go ahead and throw out that Spatial from processing. Which means, if it is a Node we don't have to worry about checking the children against the frustum (as the parent will completely contain all the children).
Secondly, if INSIDE_FRUSTUM is given, we know that the Spatial will be drawn. If this is a Node we can go ahead and tell the children to draw, rather than checking if any of the children are outside the frustum.
It's only if INTERSECTS_FRUSTUM occurs that we have to do more work. If the Spatial is a Node then all the children are processed with Camera's contains method, if the Spatial is Geometry it is sent to the graphics card for rendering.
In jME you should never directly create a Camera, this is to reduce the dependancy on any one rendering API. Therefore, request a Camera from Renderer. The only parameters required are the resolution that is to be drawn. This allows the translation to the Viewport to be accurate.