/** * Init CameraManager gl texture id, camera SurfaceTexture, bind to EXTERNAL_OES, and redirect * camera preview to the surfaceTexture. * * @throws IOException when camera cannot be open */ private void initCameraSurface() throws IOException { // Gen openGL texture id int texture[] = new int[1]; GLES10.glGenTextures(1, texture, 0); mCameraTextureId = texture[0]; if (mCameraTextureId == 0) { throw new RuntimeException("Cannot create openGL texture (initCameraSurface())"); } // Camera preview is redirected to SurfaceTexture. // SurfaceTexture works with TEXTURE_EXTERNAL_OES, so we bind this textureId so that camera // will automatically fill it with its video. GLES10.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, mCameraTextureId); // Can't do mipmapping with camera source GLES10.glTexParameterf( GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES10.GL_TEXTURE_MIN_FILTER, GLES10.GL_LINEAR); GLES10.glTexParameterf( GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES10.GL_TEXTURE_MAG_FILTER, GLES10.GL_LINEAR); // Clamp to edge is the only option GLES10.glTexParameterf( GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES10.GL_TEXTURE_WRAP_S, GLES10.GL_CLAMP_TO_EDGE); GLES10.glTexParameterf( GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES10.GL_TEXTURE_WRAP_T, GLES10.GL_CLAMP_TO_EDGE); // create a SurfaceTexture associated to this openGL texture... mCameraSurfaceTex = new SurfaceTexture(mCameraTextureId); mCameraSurfaceTex.setDefaultBufferSize(640, 480); // ... and redirect camera preview to it mCameraManager.setPreviewSurface(mCameraSurfaceTex); // Setup viewfinder mViewFinder = new TexturedPlane(mViewFinderSize); mViewFinder.setTexture( BitmapDecoder.safeDecodeBitmap(mContext.getResources(), VIEWFINDER_RESSOURCE_ID)); mViewFinder.recycleTexture(); mViewFinder.translate(0, 0, VIEWFINDER_DISTANCE); mViewFinder.setAlpha(VIEWFINDER_ATTENUATION_ALPHA); }
private void reinitCameraSurface() throws IOException { // for an unknown reason, the camera preview is not in correct direction by default. Need to // rotate it final int screenRotation = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)) .getDefaultDisplay() .getRotation(); mCameraRoll = 270; mTargetsLock.lock(); switch (screenRotation) { case Surface.ROTATION_0: mCameraRoll += 0.0f; mContours = mContours34; break; case Surface.ROTATION_90: mCameraRoll += 90.0f; mContours = mContours43; break; case Surface.ROTATION_180: mCameraRoll += 180.0f; mContours = mContours34; break; default: mCameraRoll += 270.0f; mContours = mContours43; break; } ; mTargetsLock.unlock(); mCameraRoll %= 360; // create a new TexturedPlane, that holds the camera texture. mCameraSurface = new TexturedPlane(mCameraSize, CAMERA_RATIO); mCameraSurface.setTexture(mCameraTextureId); mCameraSurface.setAlpha(CAMERA_SURFACE_ALPHA); // for unknown reason, the preview is not in correct orientation mCameraSurface.rotate(0, 0, mCameraRoll); mCameraSurface.translate(0, 0, CAMERA_DISTANCE); }
@Override public void onDrawFrame(GL10 gl) { // draws the skybox if (mUseSkybox) super.onDrawFrame(gl); // refresh camera texture if (mCameraFrameAvaible) { mCameraSurfaceTex.updateTexImage(); mCameraFrameAvaible = false; } mCameraSurfaceTex.setOnFrameAvailableListener(this); // draw camera surface gl.glEnable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); mCameraSurface.draw(gl, mViewMatrix); gl.glDisable(GLES11Ext.GL_TEXTURE_EXTERNAL_OES); // draw the viewFinder mViewFinder.draw(gl, mViewMatrix); // launch memory cleanup?? Runtime info = Runtime.getRuntime(); long freeMem = info.freeMemory() / 1048576L; if (freeMem < MEMORY_CLEANUP_THRESHOLD) mHasToFreeMemory = true; else mHasToFreeMemory = false; // the snapshots that are in FOV mSnapshotsLock.lock(); for (Snapshot3D snap : mSnapshots) { float distance = this.getSnapshotDisnance(snap); if (mHasToFreeMemory && distance > AUTO_UNLOADTEXTURE_ANGLE) { snap.unloadGLTexture(gl); } else if (this.getSnapshotDisnance(snap) < AUTO_LOADTEXTURE_ANGLE) { snap.loadGLTexture(gl); } if (distance > 120.0f) snap.setVisible(false); else { snap.setVisible(true); snap.draw(gl, super.getRotationMatrix()); } } mSnapshotsLock.unlock(); // ... and then all markers with newly computed alpha float d; // draw markers if (mUseMarkers) { mTargetsLock.lock(); for (Snapshot3D dot : mDots) { d = getSnapshotDisnance(dot); if (d > 60.0f) { dot.setVisible(false); } else { dot.setVisible(true); // Set alpha based on camera distance to the point d = d * mMarkersAttenuationFactor / 360.0f; d = (d > 1.0f ? 1.0f : d); dot.setAlpha(1.0f - d); dot.draw(gl, super.getRotationMatrix()); } } mTargetsLock.unlock(); } if (mUseContours) { mTargetsLock.lock(); for (Snapshot3D contour : mContours) { d = getSnapshotDisnance(contour); if (d > 60.0f) { contour.setVisible(false); } else { contour.setVisible(true); // Set alpha based on camera distance to the point d = d * mMarkersAttenuationFactor / 360.0f; d = (d > 1.0f ? 1.0f : d); contour.setAlpha(1.0f - d); contour.draw(gl, super.getRotationMatrix()); } } mTargetsLock.unlock(); } }
/* ******** * ACCESSORS * ********/ public void setCamPreviewVisible(boolean visible) { mCameraSurface.setVisible(visible); }