If you are craving hallucinogenic simulations, we'll introduce a "trippy trails mode" to our visualizations! The implementation is added to the RenderBox
library itself. If you're using the completed RenderBox
library, then just toggle on the mode in your app. For example, in setup()
of MainActivity
, add the following line of code at the end:
RenderBox.mainCamera.trailsMode = true;
To implement it in your copy of RenderBox
library, open that project (in Android Studio). In the Camera
class (the components/Camera.java
file), add public boolean trailsMode
:
public boolean trailsMode;
Then, in onDrawEye
, instead of erasing the screen for the new frame, we'll draw a full screen quad over the entire frame, with alpha transparency, thus leaving behind a ghostly faded image of the last frame. Every subsequent frame is overdrawn by more semi-transparent black, causing them to fade out over time. Define a color value as follows:
public static float[] customClearColor = new float[]{0,0,0,0.05f};
Then, modify onDrawEye
, so it reads as follows:
public void onDrawEye(Eye eye) { if(trailsMode) { GLES20.glEnable(GLES20.GL_BLEND); GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); customClear(customClearColor); GLES20.glEnable(GLES20.GL_DEPTH_TEST); GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT); } else { GLES20.glEnable(GLES20.GL_DEPTH_TEST); GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); } ...
The customClear
method skips the clear call, leaving behind the colors from the previous frame. Instead, it just draws a semitransparent full-screen black quad with transparency, slightly darkening the "old" image each frame. Before we can do this, the camera needs a shader program to draw the full screen solid color.
fullscreen_solid_color_vertex.shader
is as follows:
attribute vec4 v_Position; void main() { gl_Position = v_Position; }
fullscreen_solid_color_fragment.shader
is as follows:
precision mediump float; uniform vec4 u_Color; void main() { gl_FragColor = u_Color; }
Now back to the Camera
component. We set up the program and define a full screen quad mesh, buffers, and other variables. First, we define the variables we'll need:
static int program = -1; static int positionParam, colorParam; static boolean setup; public static FloatBuffer vertexBuffer; public static ShortBuffer indexBuffer; public static final int numIndices = 6; public boolean trailsMode; public static final float[] COORDS = new float[] { -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f }; public static final short[] INDICES = new short[] { 0, 1, 2, 1, 3, 2 }; public static float[] customClearColor = new float[]{0,0,0,0.05f};
Then, define a method to set up the program:
public static void setupProgram(){ if(program > -1) //This means program has been set up //(valid program or error) return; //Create shader program program = Material.createProgram(R.raw.fullscreen_solid_color_vertex, R.raw.fullscreen_solid_color_fragment); //Get vertex attribute parameters positionParam = GLES20.glGetAttribLocation(program, "v_Position"); //Enable vertex attribute parameters GLES20.glEnableVertexAttribArray(positionParam); //Shader-specific parameters colorParam = GLES20.glGetUniformLocation(program, "u_Color"); RenderBox.checkGLError("Fullscreen Solid Color params"); }
Define a method to allocate the buffers:
public static void allocateBuffers(){ setup = true; vertexBuffer = RenderObject.allocateFloatBuffer(COORDS); indexBuffer = RenderObject.allocateShortBuffer(INDICES); }
Then, call these from the Camera
initializer:
public Camera(){ transform = new Transform(); setupProgram(); allocateBuffers(); }
Finally, we can implement the customClear
method:
public static void customClear(float[] clearColor){ GLES20.glUseProgram(program); // Set the position buffer GLES20.glVertexAttribPointer(positionParam, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer); GLES20.glUniform4fv(colorParam, 1, clearColor, 0); GLES20.glDrawElements(GLES20.GL_TRIANGLES, numIndices, GLES20.GL_UNSIGNED_SHORT, indexBuffer); }
Rebuild the RenderBox
module and copy the library file back to this VisualizeVR
project. Don’t forget to set trailsMode
to true
!
Now when you run the app, it looks trippy and cool!