18f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown/*
28f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * Copyright (C) 2013 The Android Open Source Project
38f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown *
48f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
58f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * you may not use this file except in compliance with the License.
68f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * You may obtain a copy of the License at
78f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown *
88f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
98f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown *
108f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * Unless required by applicable law or agreed to in writing, software
118f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
128f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * See the License for the specific language governing permissions and
148f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * limitations under the License.
158f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown */
168f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
178f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brownpackage com.android.accessorydisplay.source.presentation;
188f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
198f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brownimport javax.microedition.khronos.egl.EGLConfig;
208f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brownimport javax.microedition.khronos.opengles.GL10;
218f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
228f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brownimport android.opengl.GLSurfaceView;
238f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
248f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown/**
258f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown * Render a pair of tumbling cubes.
268f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown */
278f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
288f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brownpublic class CubeRenderer implements GLSurfaceView.Renderer {
298f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    private boolean mTranslucentBackground;
308f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    private Cube mCube;
318f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    private float mAngle;
328f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    private float mScale = 1.0f;
338f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    private boolean mExploding;
348f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
358f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    public CubeRenderer(boolean useTranslucentBackground) {
368f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        mTranslucentBackground = useTranslucentBackground;
378f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        mCube = new Cube();
388f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    }
398f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
408f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    public void explode() {
418f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        mExploding = true;
428f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    }
438f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
448f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    public void onDrawFrame(GL10 gl) {
458f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        /*
468f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         * Usually, the first thing one might want to do is to clear
478f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         * the screen. The most efficient way of doing this is to use
488f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         * glClear().
498f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         */
508f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
518f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
528f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
538f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        /*
548f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         * Now we're ready to draw some 3D objects
558f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         */
568f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
578f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        gl.glMatrixMode(GL10.GL_MODELVIEW);
588f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        gl.glLoadIdentity();
598f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        gl.glTranslatef(0, 0, -3.0f);
608f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        gl.glRotatef(mAngle,        0, 1, 0);
618f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        gl.glRotatef(mAngle*0.25f,  1, 0, 0);
628f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
638f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
648f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
658f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
668f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        gl.glScalef(mScale, mScale, mScale);
678f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        mCube.draw(gl);
688f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
698f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        gl.glRotatef(mAngle*2.0f, 0, 1, 1);
708f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        gl.glTranslatef(0.5f, 0.5f, 0.5f);
718f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
728f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        mCube.draw(gl);
738f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
748f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        mAngle += 1.2f;
758f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
768f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        if (mExploding) {
778f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown            mScale *= 1.02f;
788f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown            if (mScale > 4.0f) {
798f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown                mScale = 1.0f;
808f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown                mExploding = false;
818f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown            }
828f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        }
838f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    }
848f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
858f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    public void onSurfaceChanged(GL10 gl, int width, int height) {
868f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         gl.glViewport(0, 0, width, height);
878f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
888f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         /*
898f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown          * Set our projection matrix. This doesn't have to be done
908f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown          * each time we draw, but usually a new projection needs to
918f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown          * be set when the viewport is resized.
928f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown          */
938f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
948f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         float ratio = (float) width / height;
958f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         gl.glMatrixMode(GL10.GL_PROJECTION);
968f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         gl.glLoadIdentity();
978f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
988f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    }
998f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
1008f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
1018f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        /*
1028f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         * By default, OpenGL enables features that improve quality
1038f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         * but reduce performance. One might want to tweak that
1048f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         * especially on software renderer.
1058f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         */
1068f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        gl.glDisable(GL10.GL_DITHER);
1078f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
1088f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown        /*
1098f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         * Some one-time OpenGL initialization can be made here
1108f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         * probably based on features of this particular context
1118f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         */
1128f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,
1138f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown                 GL10.GL_FASTEST);
1148f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown
1158f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         if (mTranslucentBackground) {
1168f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown             gl.glClearColor(0,0,0,0);
1178f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         } else {
1188f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown             gl.glClearColor(1,1,1,1);
1198f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         }
1208f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         gl.glEnable(GL10.GL_CULL_FACE);
1218f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         gl.glShadeModel(GL10.GL_SMOOTH);
1228f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown         gl.glEnable(GL10.GL_DEPTH_TEST);
1238f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown    }
1248f3b1307678fcd1896c7fb8ba4cc20553dc032e8Jeff Brown}
125