Android 要用GL渲染到屏幕上和iOS还是有很大的不同。
创建渲染view
iOS是用CAEAGLLayer,要启用这个layer,一般是在UIView中重载layerClass
+(Class)layerClass{
return [CAEAGLLayerclass];
}
Adnroid是GLSurfaceView,要实现GLSurfaceView.Renderer接口,在onDrawFrame中会有每一帧的回调函数,要注意的是,因为GL的设备上下文是GLSurfaceView创建的,所以创建纹理,着色器等只能在,要等onSurfaceCreated回调后调用,否则会创建失败。
Android还有一种方式是使用 jni 层的 ANativeWindow 来渲染。
开启摄像头
iOS是用个AVCaptureSession来管理所有硬件,比如摄像头的输入,YUV/RGBA数据的输出,麦克风的,输出PCM。
Android就比较简单,创建Camera就可以了。摄像头配置的参数比较多。
快速读取纹理
iOS有好用的CVOpenGLESTexture
Android的方案就比较多样,简单的是使用GL3的PBO,还有一种是GL2的扩展。
旋转
这个按理说摄像头输出的都是固定的方向。
这个方面被Android打败了。setDisplayOrientation
public static void setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) { android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); android.hardware.Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay() .getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } int result; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { result = (info.orientation + degrees) % 360; result = (360 - result) % 360; // compensate the mirror } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); }
用GL渲染的地方在,SurfaceTexture 调用 getTransformMatrix 得到旋转的矩阵,应用到GL顶点着色器里面。