The start of 3D
Tags: android, devlog, opengles2, vr
Published: 2020-03-28 20:37:56

#The Aim
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.

#The Setup
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](https://developer.android.com/training/graphics/opengl) to the point where I was drawing a triangle to the screen.
![Screenshot with green triangle in centre](https://dev-to-uploads.s3.amazonaws.com/i/7ot79g0r70xk29spdx3t.png)
The following changes were made to the basic tutorial code:
<ul>
<li>I created an <code>AbstractGameObject</code> class which implemented the common rendering code for the objects and the triangle class inherited from this class.</li>
<li>I changed the parent theme from <code>Theme.AppCompat.Light.DarkActionBar</code> to <code>Theme.AppCompat.Light.NoActionBar</code></li>
<li>I added the following snippet <p>
<code>window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_FULLSCREEN or
                View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
                View.SYSTEM_UI_FLAG_IMMERSIVE)</code> <p>
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)</li>
</ul>
The source code can be found on my github repo as Tagged release [B1.0](https://github.com/longevity-software/AndroidVrGameDemo/releases/tag/B1.0)

#The Development
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](https://github.com/longevity-software/AndroidVrGameDemo/releases/tag/B1.1).
I did not use [ThinMatrix's framebuffer objects tutorial](https://www.youtube.com/watch?v=21UsMuFTN0k) 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](http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-14-render-to-texture/) and
[pixel perfect Render to texture tutorial](https://pixelp3.wordpress.com/2011/05/13/android-opengl-es-2-0-render-to-texture/) for the framebuffer rendering.

#The <code>AbstractTexturedGameObject</code> class
Similar to the Abstract Game Object class which I created in the [B1.0](https://github.com/longevity-software/AndroidVrGameDemo/releases/tag/B1.0) release, I generated an abstract class which will be inherited by any game objects which will be textured.

#The Quads
Each Quad is defined in normalised device coordinates as defined in this [ray casting tutorial](http://antongerdelan.net/opengl/raycasting.html), this means that each quad will be rendered to half the screen without applying any model, view or projection matrices _*Note* the <code>TexturedQuad</code> class inherits from the <code>AbstractTexturedGameObject</code> class so an identity matrix is passed to the <code>draw</code> function which has no effect on the vertices_.  

#The Camera(s)
I created a <code>GameCamera</code> class to define a camera position, look direction and up direction. 
The main renderer instantiates two of these <code>GameCamera</code> objects, one for the left eye and one for the right eye.
Having the <code>GameCamera</code> class allowed me to reduce duplicated code by having a single <code>drawScene</code> function which renders the current scene using the passed <code>GameCamera</code> object _Note the <code>drawScene</code> function does not currently draw anything_.

#The Rendering 
The <code>VrRenderer</code> class's <code>onDrawFrame</code> function has been changed to call a new <code>drawSceneToFrameBuffer</code> function for each side of the screen
<code>
// Draw the left side
drawSceneToFrameBuffer(mLeftCamera,
    mFrameBuffer[LEFT_FRAMEBUFFER_INDEX],
    mRenderTexture[LEFT_FRAMEBUFFER_INDEX],
    mDepthRenderBuffer[LEFT_FRAMEBUFFER_INDEX])
</code><code>
// and the right side
drawSceneToFrameBuffer(mRightCamera,
    mFrameBuffer[RIGHT_FRAMEBUFFER_INDEX],
    mRenderTexture[RIGHT_FRAMEBUFFER_INDEX],
    mDepthRenderBuffer[RIGHT_FRAMEBUFFER_INDEX])
</code>
Each call to the <code>drawSceneToFrameBuffer</code> 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 <code>drawScene</code> 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.
<code>
// draw the quad with the generated textures.
mLeftQuad.draw(identityMatrix, mRenderTexture[LEFT_FRAMEBUFFER_INDEX])
mRightQuad.draw(identityMatrix, mRenderTexture[RIGHT_FRAMEBUFFER_INDEX])
</code>

#The Outcome
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. 
![Screenshot with green half and red half horizontally](https://dev-to-uploads.s3.amazonaws.com/i/kjaho60cobk1hhz92irg.png)
The next blog will detail drawing an actual 3D scene to each of the Quads.