blob: b1a786b812639a7b082da05883f29c18bd4d2770 [file] [log] [blame]
/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.game.qualification.example;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.util.Log;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import java.util.Random;
public class MyGLRenderer implements GLSurfaceView.Renderer {
private static final String TAG = "MyGLRenderer";
private Sphere[] mSphere;
private int numSpheres = 1;
// mMVPMatrix is an abbreviation for "Model View Projection Matrix"
private final float[] mMVPMatrix = new float[16];
private final float[] mProjectionMatrix = new float[16];
private final float[] mViewMatrix = new float[16];
private float[][] mPosition;
private float[][] mVelocity;
private float mHeight;
private float mWidth;
public void onSurfaceCreated(GL10 unused, EGLConfig config) {
// Set the background frame color
GLES20.glClearColor(0.0f, 0.5f, 0.5f, 1.0f);
Random rand = new Random(5);
mSphere = new Sphere[numSpheres];
mVelocity = new float[numSpheres][3];
mPosition = new float[numSpheres][3];
for (int i = 0; i < mSphere.length; ++i) {
mSphere[i] = new Sphere(0.05f, 75);
mVelocity[i][0] = (rand.nextFloat() * 2 - 1) * 0.02f;
mVelocity[i][1] = (rand.nextFloat() * 2 - 1) * 0.02f;
mVelocity[i][2] = 0.0f;
}
}
public void onDrawFrame(GL10 unused) {
float[] scratch = new float[16];
// Redraw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
// Set the camera position (View matrix)
Matrix.setLookAtM(mViewMatrix, 0, 0, 0, 10, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
// Calculate the projection and view transformation
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
for (int i = 0; i < mSphere.length; i++) {
// Update position;
mPosition[i][0] += mVelocity[i][0];
mPosition[i][1] += mVelocity[i][1];
mPosition[i][2] += mVelocity[i][2];
if (mPosition[i][0] - mSphere[i].getRadius() < 0.0f
|| mPosition[i][0] + mSphere[i].getRadius() > mWidth) {
mVelocity[i][0] = -mVelocity[i][0];
}
if (mPosition[i][1] - mSphere[i].getRadius() < 0.0f
|| mPosition[i][1] + mSphere[i].getRadius() > mHeight) {
mVelocity[i][1] = -mVelocity[i][1];
}
Matrix.translateM(scratch, 0, mMVPMatrix, 0, mPosition[i][0], mPosition[i][1], mPosition[i][2]);
mSphere[i].draw(scratch);
}
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
GLES20.glViewport(0, 0, width, height);
float ratio = (float) width / height;
mHeight = 1;
mWidth = ratio;
for (int i = 0; i < mSphere.length; i++) {
mPosition[i][0] = mWidth / 2.0f;
mPosition[i][1] = mHeight / 2.0f;
}
// This projection matrix is applied to object coordinates in the onDrawFrame() method.
// Using orthographic projection to make it easier to determine edge of screen.
Matrix.orthoM(mProjectionMatrix, 0, 0, ratio, 0, 1, 3, 20);
}
/**
* Utility method for compiling a OpenGL shader.
*
* <p><strong>Note:</strong> When developing shaders, use the checkGlError()
* method to debug shader coding errors.</p>
*
* @param type - Vertex or fragment shader type.
* @param shaderCode - String containing the shader code.
* @return - Returns an id for the shader.
*/
public static int loadShader(int type, String shaderCode){
// create a vertex shader type (GLES20.GL_VERTEX_SHADER)
// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
// add the source code to the shader and compile it
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
/**
* Utility method for debugging OpenGL calls. Provide the name of the call
* just after making it:
*
* <pre>
* mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
* MyGLRenderer.checkGlError("glGetUniformLocation");</pre>
*
* If the operation is not successful, the check throws an error.
*
* @param glOperation - Name of the OpenGL call to check.
*/
public static void checkGlError(String glOperation) {
int error;
while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) {
Log.e(TAG, glOperation + ": glError " + error);
throw new RuntimeException(glOperation + ": glError " + error);
}
}
}