In order to display the same scene from two different viewpoints i.e. left eye and right eye, we need to render the scene to two different framebuffers and then apply each of these as a texture to a left and right quad.
Prior to the development as part of this blog post, I started with a new Empty activity project targeting Android 8.1 and followed the Android developers Displaying graphics with openGL series to the point where I was drawing a triangle to the screen.
The following changes were made to the basic tutorial code:
- I created an
AbstractGameObjectclass which implemented the common rendering code for the objects and the triangle class inherited from this class.
- I changed the parent theme from
- I added the following snippet
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE)
to the Activity's onCreate method to force full screen mode as per the [Android Developers guide to enabling full screen mode](https://developer.android.com/training/system-ui/immersive)
The source code can be found on my github repo as Tagged release B1.0
I started detailing every step of the development, but quickly decided that I would just focus on the key points, the final source code at the end of this development can be found on my github repo as Tagged release B1.1.
I did not use ThinMatrix's framebuffer objects tutorial as part of this development but when I was originally learning about rendering to framebuffers, this tutorial and others of his were great, so for anyone new to openGL the ThinMatrix youtube channel is where I would recommend starting.
As part of this development I merged the code from the following two tutorials, opengl-tutorial.org Render to texture tutorial and
pixel perfect Render to texture tutorial for the framebuffer rendering.
Similar to the Abstract Game Object class which I created in the B1.0 release, I generated an abstract class which will be inherited by any game objects which will be textured.
Each Quad is defined in normalised device coordinates as defined in this ray casting tutorial, this means that each quad will be rendered to half the screen without applying any model, view or projection matrices Note the
TexturedQuad class inherits from the
AbstractTexturedGameObject class so an identity matrix is passed to the
draw function which has no effect on the vertices.
I created a
GameCamera class to define a camera position, look direction and up direction.
The main renderer instantiates two of these
GameCamera objects, one for the left eye and one for the right eye.
GameCamera class allowed me to reduce duplicated code by having a single
drawScene function which renders the current scene using the passed
GameCamera object Note the
drawScene function does not currently draw anything.
onDrawFrame function has been changed to call a new
drawSceneToFrameBuffer function for each side of the screen
// Draw the left side
// and the right side
Each call to the
drawSceneToFrameBuffer function binds the passed framebuffer, sets the viewport to the framebuffer size, temporarily sets to clear colour for each framebuffer to a different colour, renders the scene using the
drawScene function before unbinding the framebuffer.
Finally, the viewport is reset back to the screen size before the left quad is drawn using the left texture and the right quad is rendered using the right texture.
// draw the quad with the generated textures.
At the end of all of this, I am rendering a green quad to the left side of the screen and a red quad to the right side of the screen, this may not look like much but it is the starting point for all the good stuff.
The next blog will detail drawing an actual 3D scene to each of the Quads.