155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala/* 255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * Copyright (C) 2011 The Android Open Source Project 355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * 455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License"); 555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * you may not use this file except in compliance with the License. 655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * You may obtain a copy of the License at 755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * 855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * http://www.apache.org/licenses/LICENSE-2.0 955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * 1055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * Unless required by applicable law or agreed to in writing, software 1155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS, 1255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * See the License for the specific language governing permissions and 1455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * limitations under the License. 1555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala */ 1655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 1755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalapackage com.android.gl2cameraeye; 1855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 1955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport java.io.IOException; 2055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport java.nio.ByteBuffer; 2155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport java.nio.ByteOrder; 2255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport java.nio.FloatBuffer; 2355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 2455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport javax.microedition.khronos.egl.EGLConfig; 2555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport javax.microedition.khronos.opengles.GL10; 2655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 2755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.app.Activity; 2855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.content.pm.ActivityInfo; 2955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.os.Bundle; 3055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.view.MotionEvent; 3155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.content.Context; 3255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.util.Log; 3355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 3455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.opengl.GLES20; 3555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.opengl.GLSurfaceView; 3655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.opengl.GLUtils; 3755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.opengl.Matrix; 3855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 3955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.graphics.SurfaceTexture; 4055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 4155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.hardware.Camera; 4255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.hardware.SensorManager; 4355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.hardware.SensorEvent; 4455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.hardware.SensorEventListener; 4555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaimport android.hardware.Sensor; 4655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 4755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalapublic class GL2CameraEye extends Activity { 4855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala @Override 4955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala protected void onCreate(Bundle savedInstanceState) { 5055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala super.onCreate(savedInstanceState); 5155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mGLView = new CamGLSurfaceView(this); 5255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala setContentView(mGLView); 5355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); 5455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 5555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 5655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala @Override 5755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala protected void onPause() { 5855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala super.onPause(); 5955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mGLView.onPause(); 6055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 6155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 6255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala @Override 6355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala protected void onResume() { 6455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala super.onResume(); 6555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mGLView.onResume(); 6655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 6755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 6855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private GLSurfaceView mGLView; 6955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala} 7055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 7155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaclass CamGLSurfaceView extends GLSurfaceView implements SensorEventListener { 7255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public CamGLSurfaceView(Context context) { 7355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala super(context); 7455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala setEGLContextClientVersion(2); 7555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mRenderer = new CamRenderer(context); 7655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala setRenderer(mRenderer); 7755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 7855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); 7955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mAcceleration = mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION); 8055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 8155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 8255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public boolean onTouchEvent(final MotionEvent event) { 8355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala queueEvent(new Runnable(){ 8455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public void run() { 8555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mRenderer.setPosition(event.getX() / getWidth(), 8655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala event.getY() / getHeight()); 8755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala }}); 8855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala return true; 8955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 9055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 9155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala @Override 9255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public void onPause() { 9355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala super.onPause(); 9455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mCamera.stopPreview(); 9555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mCamera.release(); 9655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 9755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mSensorManager.unregisterListener(this); 9855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 9955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 10055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala @Override 10155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public void onResume() { 10255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mCamera = Camera.open(); 10355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Camera.Parameters p = mCamera.getParameters(); 10455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala // No changes to default camera parameters 10555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mCamera.setParameters(p); 10655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 10755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala queueEvent(new Runnable(){ 10855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public void run() { 10955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mRenderer.setCamera(mCamera); 11055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala }}); 11155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 11255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mSensorManager.registerListener(this, mAcceleration, SensorManager.SENSOR_DELAY_GAME); 11355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala super.onResume(); 11455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 11555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 11655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public void onSensorChanged(SensorEvent event) { 11755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (event.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION) { 11855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala final float[] accelerationVector = event.values; 11955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala queueEvent(new Runnable(){ 12055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public void run() { 12155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mRenderer.setAcceleration(accelerationVector); 12255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala }}); 12355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 12455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 12555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 12655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public void onAccuracyChanged(Sensor sensor, int accuracy) { 12755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala // Ignoring sensor accuracy changes. 12855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 12955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 13055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala CamRenderer mRenderer; 13155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Camera mCamera; 13255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 13355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala SensorManager mSensorManager; 13455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Sensor mAcceleration; 13555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala} 13655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 13755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvalaclass CamRenderer implements GLSurfaceView.Renderer, SurfaceTexture.OnFrameAvailableListener { 13855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 13955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public CamRenderer(Context context) { 14055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mContext = context; 14155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 14255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length 14355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * FLOAT_SIZE_BYTES).order(ByteOrder.nativeOrder()).asFloatBuffer(); 14455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mTriangleVertices.put(mTriangleVerticesData).position(0); 14555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 14655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Matrix.setIdentityM(mSTMatrix, 0); 14755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Matrix.setIdentityM(mMMatrix, 0); 14855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 14955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala float[] defaultAcceleration = {0.f,0.f,0.f}; 15055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala setAcceleration(defaultAcceleration); 15155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mPos[0] = 0.f; 15255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mPos[1] = 0.f; 15355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mPos[2] = 0.f; 15455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mVel[0] = 0.f; 15555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mVel[1] = 0.f; 15655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mVel[2] = 0.f; 15755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 15855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 15955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 16055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala /* The following set methods are not synchronized, so should only 16155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * be called within the rendering thread context. Use GLSurfaceView.queueEvent for safe access. 16255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala */ 16355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public void setPosition(float x, float y) { 16455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala /* Map from screen (0,0)-(1,1) to scene coordinates */ 16555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mPos[0] = (x*2-1)*mRatio; 16655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mPos[1] = (-y)*2+1; 16755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mPos[2] = 0.f; 16855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mVel[0] = 0; 16955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mVel[1] = 0; 17055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mVel[2] = 0; 17155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 17255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 17355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public void setCamera(Camera camera) { 17455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mCamera = camera; 17555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Camera.Size previewSize = camera.getParameters().getPreviewSize(); 17655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mCameraRatio = (float)previewSize.width/previewSize.height; 17755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 17855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 17955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public void setAcceleration(float[] accelerationVector) { 18055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mGForce[0] = accelerationVector[0]; 18155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mGForce[1] = accelerationVector[1]; 18255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mGForce[2] = accelerationVector[2]; 18355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 18455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 18555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public void onDrawFrame(GL10 glUnused) { 18655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala synchronized(this) { 18755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (updateSurface) { 18855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mSurface.updateTexImage(); 18955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 19055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mSurface.getTransformMatrix(mSTMatrix); 19155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala long timestamp = mSurface.getTimestamp(); 19255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala doPhysics(timestamp); 19355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 19455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala updateSurface = false; 19555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 19655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 19755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 19855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala // Ignore the passed-in GL10 interface, and use the GLES20 19955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala // class's static methods instead. 20055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); 20155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glUseProgram(mProgram); 20255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glUseProgram"); 20355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 20455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 20555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID); 20655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 20755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mTriangleVertices.position(TRIANGLE_VERTICES_DATA_POS_OFFSET); 20855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 20955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices); 21055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glVertexAttribPointer maPosition"); 21155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glEnableVertexAttribArray(maPositionHandle); 21255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glEnableVertexAttribArray maPositionHandle"); 21355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 21455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mTriangleVertices.position(TRIANGLE_VERTICES_DATA_UV_OFFSET); 21555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glVertexAttribPointer(maTextureHandle, 3, GLES20.GL_FLOAT, false, 21655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices); 21755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glVertexAttribPointer maTextureHandle"); 21855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glEnableVertexAttribArray(maTextureHandle); 21955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glEnableVertexAttribArray maTextureHandle"); 22055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 22155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0); 22255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); 22355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 22455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0); 22555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0); 22655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glUniform1f(muCRatioHandle, mCameraRatio); 22755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 22855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 22955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glDrawArrays"); 23055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 23155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 23255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public void onSurfaceChanged(GL10 glUnused, int width, int height) { 23355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala // Ignore the passed-in GL10 interface, and use the GLES20 23455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala // class's static methods instead. 23555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glViewport(0, 0, width, height); 23655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mRatio = (float) width / height; 23755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Matrix.frustumM(mProjMatrix, 0, -mRatio, mRatio, -1, 1, 3, 7); 23855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 23955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 24055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala public void onSurfaceCreated(GL10 glUnused, EGLConfig config) { 24155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala // Ignore the passed-in GL10 interface, and use the GLES20 24255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala // class's static methods instead. 24355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 24455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala /* Set up alpha blending and an Android background color */ 24555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glEnable(GLES20.GL_BLEND); 24655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 24755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glClearColor(0.643f, 0.776f, 0.223f, 1.0f); 24855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 24955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala /* Set up shaders and handles to their variables */ 25055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mProgram = createProgram(mVertexShader, mFragmentShader); 25155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (mProgram == 0) { 25255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala return; 25355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 25455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala maPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition"); 25555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glGetAttribLocation aPosition"); 25655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (maPositionHandle == -1) { 25755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala throw new RuntimeException("Could not get attrib location for aPosition"); 25855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 25955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala maTextureHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord"); 26055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glGetAttribLocation aTextureCoord"); 26155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (maTextureHandle == -1) { 26255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala throw new RuntimeException("Could not get attrib location for aTextureCoord"); 26355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 26455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 26555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); 26655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glGetUniformLocation uMVPMatrix"); 26755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (muMVPMatrixHandle == -1) { 26855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala throw new RuntimeException("Could not get attrib location for uMVPMatrix"); 26955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 27055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 27155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala muSTMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uSTMatrix"); 27255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glGetUniformLocation uSTMatrix"); 27355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (muMVPMatrixHandle == -1) { 27455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala throw new RuntimeException("Could not get attrib location for uSTMatrix"); 27555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 27655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 27755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala muCRatioHandle = GLES20.glGetUniformLocation(mProgram, "uCRatio"); 27855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glGetUniformLocation uCRatio"); 27955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (muMVPMatrixHandle == -1) { 28055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala throw new RuntimeException("Could not get attrib location for uCRatio"); 28155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 28255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 28355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala /* 28455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * Create our texture. This has to be done each time the 28555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * surface is created. 28655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala */ 28755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 28855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala int[] textures = new int[1]; 28955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glGenTextures(1, textures, 0); 29055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 29155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mTextureID = textures[0]; 29255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, mTextureID); 29355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glBindTexture mTextureID"); 29455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 29555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala // Can't do mipmapping with camera source 29655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, 29755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.GL_NEAREST); 29855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glTexParameterf(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, 29955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.GL_LINEAR); 30055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala // Clamp to edge is the only option 30155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, 30255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.GL_CLAMP_TO_EDGE); 30355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, 30455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.GL_CLAMP_TO_EDGE); 30555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glTexParameteri mTextureID"); 30655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 30755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala /* 30855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * Create the SurfaceTexture that will feed this textureID, and pass it to the camera 30955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala */ 31055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 31155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mSurface = new SurfaceTexture(mTextureID); 31255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mSurface.setOnFrameAvailableListener(this); 31355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala try { 31455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mCamera.setPreviewTexture(mSurface); 31555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } catch (IOException t) { 31655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Log.e(TAG, "Cannot set preview texture target!"); 31755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 31855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 31955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala /* Start the camera */ 32055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mCamera.startPreview(); 32155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 32255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Matrix.setLookAtM(mVMatrix, 0, 0, 0, 5f, 0f, 0f, 0f, 0f, 1.0f, 0.0f); 32355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 32455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mLastTime = 0; 32555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 32655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala synchronized(this) { 32755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala updateSurface = false; 32855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 32955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 33055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 33155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala synchronized public void onFrameAvailable(SurfaceTexture surface) { 33255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala /* For simplicity, SurfaceTexture calls here when it has new 33355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * data available. Call may come in from some random thread, 33455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * so let's be safe and use synchronize. No OpenGL calls can be done here. 33555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala */ 33655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala updateSurface = true; 33755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 33855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 33955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private void doPhysics(long timestamp) { 34055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala /* 34155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala * Move the camera surface around based on some simple spring physics with drag 34255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala */ 34355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 34455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (mLastTime == 0) 34555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mLastTime = timestamp; 34655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 34755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala float deltaT = (timestamp - mLastTime)/1000000000.f; // To seconds 34855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 34955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala float springStrength = 20.f; 35055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala float frictionCoeff = 10.f; 35155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala float mass = 10.f; 35255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala float gMultiplier = 4.f; 35355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala /* Only update physics every 30 ms */ 35455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (deltaT > 0.030f) { 35555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mLastTime = timestamp; 35655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 35755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala float[] totalForce = new float[3]; 35855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala totalForce[0] = -mPos[0] * springStrength - mVel[0]*frictionCoeff + gMultiplier*mGForce[0]*mass; 35955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala totalForce[1] = -mPos[1] * springStrength - mVel[1]*frictionCoeff + gMultiplier*mGForce[1]*mass; 36055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala totalForce[2] = -mPos[2] * springStrength - mVel[2]*frictionCoeff + gMultiplier*mGForce[2]*mass; 36155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 36255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala float[] accel = new float[3]; 36355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala accel[0] = totalForce[0]/mass; 36455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala accel[1] = totalForce[1]/mass; 36555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala accel[2] = totalForce[2]/mass; 36655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 36755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala /* Not a very accurate integrator */ 36855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mVel[0] = mVel[0] + accel[0]*deltaT; 36955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mVel[1] = mVel[1] + accel[1]*deltaT; 37055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mVel[2] = mVel[2] + accel[2]*deltaT; 37155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 37255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mPos[0] = mPos[0] + mVel[0]*deltaT; 37355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mPos[1] = mPos[1] + mVel[1]*deltaT; 37455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala mPos[2] = mPos[2] + mVel[2]*deltaT; 37555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 37655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Matrix.setIdentityM(mMMatrix, 0); 37755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Matrix.translateM(mMMatrix, 0, mPos[0], mPos[1], mPos[2]); 37855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 37955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 38055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 38155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 38255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private int loadShader(int shaderType, String source) { 38355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala int shader = GLES20.glCreateShader(shaderType); 38455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (shader != 0) { 38555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glShaderSource(shader, source); 38655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glCompileShader(shader); 38755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala int[] compiled = new int[1]; 38855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); 38955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (compiled[0] == 0) { 39055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Log.e(TAG, "Could not compile shader " + shaderType + ":"); 39155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Log.e(TAG, GLES20.glGetShaderInfoLog(shader)); 39255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glDeleteShader(shader); 39355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala shader = 0; 39455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 39555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 39655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala return shader; 39755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 39855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 39955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private int createProgram(String vertexSource, String fragmentSource) { 40055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource); 40155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (vertexShader == 0) { 40255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala return 0; 40355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 40455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource); 40555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (pixelShader == 0) { 40655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala return 0; 40755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 40855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 40955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala int program = GLES20.glCreateProgram(); 41055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (program != 0) { 41155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glAttachShader(program, vertexShader); 41255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glAttachShader"); 41355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glAttachShader(program, pixelShader); 41455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala checkGlError("glAttachShader"); 41555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glLinkProgram(program); 41655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala int[] linkStatus = new int[1]; 41755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); 41855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala if (linkStatus[0] != GLES20.GL_TRUE) { 41955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Log.e(TAG, "Could not link program: "); 42055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Log.e(TAG, GLES20.glGetProgramInfoLog(program)); 42155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala GLES20.glDeleteProgram(program); 42255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala program = 0; 42355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 42455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 42555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala return program; 42655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 42755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 42855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private void checkGlError(String op) { 42955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala int error; 43055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { 43155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala Log.e(TAG, op + ": glError " + error); 43255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala throw new RuntimeException(op + ": glError " + error); 43355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 43455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala } 43555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 43655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private static final int FLOAT_SIZE_BYTES = 4; 43755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private static final int TRIANGLE_VERTICES_DATA_STRIDE_BYTES = 5 * FLOAT_SIZE_BYTES; 43855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private static final int TRIANGLE_VERTICES_DATA_POS_OFFSET = 0; 43955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private static final int TRIANGLE_VERTICES_DATA_UV_OFFSET = 3; 44055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private final float[] mTriangleVerticesData = { 44155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala // X, Y, Z, U, V 44255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala -1.0f, -1.0f, 0, 0.f, 0.f, 44355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 1.0f, -1.0f, 0, 1.f, 0.f, 44455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala -1.0f, 1.0f, 0, 0.f, 1.f, 44555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 1.0f, 1.0f, 0, 1.f, 1.f, 44655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala }; 44755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 44855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private FloatBuffer mTriangleVertices; 44955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 45055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private final String mVertexShader = 45155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "uniform mat4 uMVPMatrix;\n" + 45255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "uniform mat4 uSTMatrix;\n" + 45355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "uniform float uCRatio;\n" + 45455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "attribute vec4 aPosition;\n" + 45555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "attribute vec4 aTextureCoord;\n" + 45655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "varying vec2 vTextureCoord;\n" + 45755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "varying vec2 vTextureNormCoord;\n" + 45855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "void main() {\n" + 45955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala " vec4 scaledPos = aPosition;\n" + 46055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala " scaledPos.x = scaledPos.x * uCRatio;\n" + 46155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala " gl_Position = uMVPMatrix * scaledPos;\n" + 46255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala " vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" + 46355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala " vTextureNormCoord = aTextureCoord.xy;\n" + 46455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "}\n"; 46555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 46655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private final String mFragmentShader = 46755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "#extension GL_OES_EGL_image_external : require\n" + 46855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "precision mediump float;\n" + 46955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "varying vec2 vTextureCoord;\n" + 47055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "varying vec2 vTextureNormCoord;\n" + 47155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "uniform samplerExternalOES sTexture;\n" + 47255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "void main() {\n" + 47355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala " gl_FragColor = texture2D(sTexture, vTextureCoord);\n" + 47455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala " gl_FragColor.a = 1.0-min(length(vTextureNormCoord-0.5)*2.0,1.0);\n" + 47555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala "}\n"; 47655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 47755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private float[] mMVPMatrix = new float[16]; 47855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private float[] mProjMatrix = new float[16]; 47955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private float[] mMMatrix = new float[16]; 48055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private float[] mVMatrix = new float[16]; 48155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private float[] mSTMatrix = new float[16]; 48255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 48355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private int mProgram; 48455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private int mTextureID; 48555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private int muMVPMatrixHandle; 48655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private int muSTMatrixHandle; 48755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private int muCRatioHandle; 48855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private int maPositionHandle; 48955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private int maTextureHandle; 49055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 49155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private float mRatio = 1.0f; 49255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private float mCameraRatio = 1.0f; 49355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private float[] mVel = new float[3]; 49455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private float[] mPos = new float[3]; 49555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private float[] mGForce = new float[3]; 49655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 49755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private long mLastTime; 49855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 49955c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private SurfaceTexture mSurface; 50055c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private Camera mCamera; 50155c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private boolean updateSurface = false; 50255c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 50355c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private Context mContext; 50455c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private static String TAG = "CamRenderer"; 50555c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala 50655c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala // Magic key 50755c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala private static int GL_TEXTURE_EXTERNAL_OES = 0x8D65; 50855c617aa2d49e3403f8700b173dc9220654deb74Eino-Ville Talvala} 509