1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.cts.verifier.sensors.sixdof.Renderer.Renderable; 17 18 import static com.android.cts.verifier.sensors.sixdof.Utils.MathsUtils.X; 19 import static com.android.cts.verifier.sensors.sixdof.Utils.MathsUtils.Y; 20 import static com.android.cts.verifier.sensors.sixdof.Utils.MathsUtils.Z; 21 22 import android.opengl.GLES20; 23 24 import com.android.cts.verifier.sensors.sixdof.Renderer.RenderUtils.Colour; 25 import com.android.cts.verifier.sensors.sixdof.Renderer.RenderUtils.ConeModelMatrixCalculator; 26 import com.android.cts.verifier.sensors.sixdof.Renderer.RenderUtils.DrawParameters; 27 import com.android.cts.verifier.sensors.sixdof.Renderer.RenderUtils.ObjImporter; 28 import com.android.cts.verifier.sensors.sixdof.Renderer.RenderUtils.ShaderHelper; 29 30 import java.nio.ByteBuffer; 31 import java.nio.ByteOrder; 32 import java.nio.FloatBuffer; 33 import java.nio.IntBuffer; 34 35 /** 36 * Object that needs to be collected by user in last test. 37 */ 38 public class ConeRenderable extends Renderable { 39 private static final int BYTES_PER_INT = 4; 40 public static final float[] CONE_OFFSET = new float[]{ 41 0.2f, -0.1f, -1.0f}; // Offset from camera position. 42 43 private FloatBuffer mPositionBuffer; 44 private IntBuffer mIndicesBuffer; 45 private FloatBuffer mNormalsBuffer; 46 private FloatBuffer mColorBuffer; 47 private int mColorHandle; 48 private int mLightPosHandle; 49 private int mLightStrengthHandle; 50 private int mNormalHandle; 51 52 private ConeModelMatrixCalculator mModelMatrixCalculator; 53 54 public ConeRenderable(int toRotate, float[] upVector) { 55 mModelMatrixCalculator = new ConeModelMatrixCalculator(toRotate, upVector); 56 } 57 58 public void initialise(ObjImporter.ObjectData coneData) { 59 mVertexCount = coneData.getIndicesData().length; 60 61 int colourCount = mVertexCount * COLOUR_DATA_SIZE; // Vertex count * rgba 62 float[] colours = new float[colourCount]; 63 64 for (int i = 0; i < colourCount; i++) { 65 int index = i % COLOUR_DATA_SIZE; 66 colours[i] = Colour.WHITE[index]; 67 } 68 69 // Initialize the buffers. 70 mPositionBuffer = ByteBuffer.allocateDirect(coneData.getVertexData().length * BYTES_PER_FLOAT) 71 .order(ByteOrder.nativeOrder()).asFloatBuffer(); 72 mColorBuffer = ByteBuffer.allocateDirect(colours.length * BYTES_PER_FLOAT) 73 .order(ByteOrder.nativeOrder()).asFloatBuffer(); 74 mNormalsBuffer = ByteBuffer.allocateDirect(coneData.getNormalsData().length * BYTES_PER_FLOAT) 75 .order(ByteOrder.nativeOrder()).asFloatBuffer(); 76 mIndicesBuffer = ByteBuffer.allocateDirect(coneData.getIndicesData().length * BYTES_PER_INT) 77 .order(ByteOrder.nativeOrder()).asIntBuffer(); 78 79 mPositionBuffer.put(coneData.getVertexData()).position(0); 80 mColorBuffer.put(colours).position(0); 81 mNormalsBuffer.put(coneData.getNormalsData()).position(0); 82 mIndicesBuffer.put(coneData.getIndicesData()).position(0); 83 84 final String vertexShader = ShaderHelper.getAugmentedRealityVertexShader(); 85 final String fragmentShader = ShaderHelper.getAugmentedRealityFragmentShader(); 86 87 final int vertexShaderHandle = 88 ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, vertexShader); 89 final int fragmentShaderHandle = 90 ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShader); 91 92 mProgramHandle = ShaderHelper.createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle, 93 new String[]{"a_Position", "a_Color", "a_Normal"}); 94 } 95 96 @Override 97 public float[] getModelMatrix() { 98 // We want a model matrix that has camera extrinsics taken into account. 99 return mModelMatrixCalculator.getModelMatrix(); 100 } 101 102 public void updateModelMatrix(float[] translation, float[] rotation, float[] lookAtPosition) { 103 mModelMatrixCalculator.updateModelMatrix(translation, rotation, lookAtPosition); 104 } 105 106 public void setDevice2IMUMatrix(float[] translation, float[] quaternion) { 107 mModelMatrixCalculator.setDevice2IMUMatrix(translation, quaternion); 108 } 109 110 public void setColorCamera2IMUMatrix(float[] translation, float[] quaternion) { 111 mModelMatrixCalculator.setColorCamera2IMUMatrix(translation, quaternion); 112 } 113 114 @Override 115 public void draw(DrawParameters drawParameters) { 116 GLES20.glUseProgram(mProgramHandle); 117 118 // Set program handles for cone drawing. 119 mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVPMatrix"); 120 mMVMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVMatrix"); 121 mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position"); 122 mColorHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Color"); 123 124 // Used to calculate shadows. 125 mLightPosHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_LightPos"); 126 mLightStrengthHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_LightStrength"); 127 mNormalHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Normal"); 128 129 // Calculate lighting information 130 float[] lightPosInEyeSpace = drawParameters.getLight() 131 .getPositionInEyeSpace(drawParameters.getViewMatrix()); 132 GLES20.glUniform3f(mLightPosHandle, 133 lightPosInEyeSpace[X], lightPosInEyeSpace[Y], lightPosInEyeSpace[Z]); 134 GLES20.glUniform1f(mLightStrengthHandle, drawParameters.getLight().getStrength()); 135 136 updateMvpMatrix(drawParameters.getViewMatrix(), drawParameters.getProjectionMatrix()); 137 drawCone(); 138 } 139 140 private void drawCone() { 141 // Pass in the position information 142 mPositionBuffer.position(0); 143 GLES20.glVertexAttribPointer(mPositionHandle, POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, 144 0, mPositionBuffer); 145 146 GLES20.glEnableVertexAttribArray(mPositionHandle); 147 148 // Pass in the modelview matrix. 149 GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, getMvMatrix(), 0); 150 151 // Pass in the combined matrix. 152 GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, getMvpMatrix(), 0); 153 154 // Pass in the color information 155 mColorBuffer.position(0); 156 GLES20.glVertexAttribPointer(mColorHandle, COLOUR_DATA_SIZE, GLES20.GL_FLOAT, false, 157 0, mColorBuffer); 158 159 GLES20.glEnableVertexAttribArray(mColorHandle); 160 161 // Pass in the normal information 162 mNormalsBuffer.position(0); 163 GLES20.glVertexAttribPointer(mNormalHandle, NORMAL_DATA_SIZE, GLES20.GL_FLOAT, false, 164 0, mNormalsBuffer); 165 166 GLES20.glEnableVertexAttribArray(mNormalHandle); 167 168 // Draw the cone. 169 GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, mVertexCount); 170 } 171 172 @Override 173 public void destroy() { 174 mPositionBuffer = null; 175 mIndicesBuffer = null; 176 mNormalsBuffer = null; 177 mColorBuffer = null; 178 } 179 } 180