Alright! We're getting closer. We're now ready to build a little scene in RenderBox
using the code we created earlier. To start, the scene will simply consist of a colored cube and, of course, a camera.
At the beginning of this project, we created the skeleton RenderBox
class, which implements CardboardView.StereoRenderer
.
To this, we now add a Camera
instance. At the top of the RenderBox
class, declare mainCamera
, which will get initialized in onSurfaceCreated
:
public static Camera mainCamera;
Note that Android Studio may find other Camera
classes; ensure that it uses the one that we created in this package.
Shortly after your app starts and the MainActivity
class is instantiated, the onSurfaceCreated
callback is called. This is where we can clear the screen, allocate buffers, and build shader programs. Let's add that now:
public void onSurfaceCreated(EGLConfig eglConfig) { RenderBox.reset(); GLES20.glClearColor(0.1f, 0.1f, 0.1f, 0.5f); mainCamera = new Camera(); checkGLError("onSurfaceCreated"); callbacks.setup(); }
To be safe, the first thing it does is call reset, which will destroy any materials that might have already been compiled by resetting their program handles, before possibly compiling others. The need for this will become clear in the later projects where we will implement the intent feature to launch/relaunch the apps:
/** * Used to "clean up" compiled shaders, which have to be recompiled for a "fresh" activity */ public static void reset(){ VertexColorMaterial.destroy(); }
The last thing onSurfaceCreated
does is invoke the setup
callback. This will be implemented in the interface implementer, which in our case is MainActivity
.
In each new frame, we will call the camera's onNewFrame
method to build the camera matrix and apply it to its model-view.
Let's also capture the current head pose (headView
and headAngles
as transformation matrices and angles, respectively) if we want to reference it in the later projects (refer to https://developers.google.com/cardboard/android/latest/reference/com/google/vrtoolkit/cardboard/HeadTransform#public-constructors). Still in RenderBox
, add the following code:
public static final float[] headView = new float[16]; public static final float[] headAngles = new float[3]; public void onNewFrame(HeadTransform headTransform) { headTransform.getHeadView(headView, 0); headTransform.getEulerAngles(headAngles, 0); mainCamera.onNewFrame(); callbacks.preDraw(); }
Then, when the Cardboard SDK goes to draw each eye (for the left and right split screen stereoscopic views), we will call the camera's onDrawEye
method:
public void onDrawEye(Eye eye) { mainCamera.onDrawEye(eye); }
While we're at it, we can also enable the preDraw
and postDraw
callbacks (in the previous code, in onNewFrame
, and in onFinishFrame
, respectively).
public void onFinishFrame(Viewport viewport) { callbacks.postDraw(); }
Should these interface callbacks be implemented in MainActivity
, they will be called from here.
Now, we can build a scene that uses a Camera
, a Cube
, and the VertexColorMaterial
class.