android opengl camera2 实现相机的实时预览 以及 点坐标samplerExternalOES的纹理坐标

相机一直是我的心病,花了几周的时间学习了下opengl se。并利用opengl来实现android平台下的实时预览。,真的硬着头皮啃 网上的大神的代码,没有什么注解,确实有点苦逼,闲话不说了现在做好笔记 ,方便回顾。

相机的预览

首先回到相机的预览,我们知道camera2,利用surfacetexture 可以在非预览情况下获得相机的数据,,然后利用与surfacetexture同一个texture利用GLsurfaceView中利用opengl来渲染出来。
1、写一个camera的工具,方便用来打开相机,抛出接口,就是setSurfacetexture(),set后打开相机,相机预览的数据就会进入 surfacetexture。这里的surfacetexture的创建是 由glsurfaceview中创建的texture 来创建,这样相机和opengl公用一个texture
2、利用mSurfaceTexture.updateTexImage()来更新texture的纹理,然后利用GLsurfaceview在onDrawFrame()绘制出texture,这样我们才能看见相机的数据。
3、编写定点着色器和片着色器,opengl将texture绘制在屏幕上需要这2点。这里丢出最简单的着色器:
顶点着色器

attribute vec4 vPosition;
uniform mat4 vMatrix;
attribute vec2 inputTextureCoordinate;
varying vec2 textureCoordinate;
void main()
           {
             gl_Position = vPosition*vMatrix;
             textureCoordinate = inputTextureCoordinate;
           }

片着色器

#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 textureCoordinate;
//uniform sampler2D vTexture;
uniform samplerExternalOES vTexture;

void main()
 {
   gl_FragColor = texture2D( vTexture, textureCoordinate );
 }

这里需要注意的是,相机的texture必须为samplerExternalOESsampler2D是二维纹理,后续离屏渲染的时候会用到。
在opengl中,为了和着色器交互,
attribute传入顶点着色器的顶点,texture的映射关系
uniform 来传入普通的,数组、整数等关系。
当然还有一些着色器语法这里就不一一详述了。后续的滤镜美颜,大多图像处理的算法也是在着色器里面来编写的。
java层找到着色器的部分代码:

 	    vPositionLocation = glGetAttribLocation(program , "vPosition");
        vTextureCoordinateLocation = glGetAttribLocation(program , "inputTextureCoordinate");
        vTextureLocation = GLES20.glGetUniformLocation(program, "vTexture");
        vMatrixLocation =  GLES20.glGetUniformLocation(program, "vMatrix");

然后传入相应的数据:

	// 传入矩阵、 顶点和texture的floatbuffer
 	GLES20.glUniformMatrix4fv(vMatrixLocation, 1, false, pointsMatrix, 0);
        GLES20.glVertexAttribPointer(vPositionLocation, 2, GLES20.GL_FLOAT, false, 8, vPositionBuffer);
        GLES20.glVertexAttribPointer(vTextureCoordinateLocation, 2, GLES20.GL_FLOAT, false,
         8,vTextureCoordinateBuffer );
        
         

当然,手机有前后摄像头,前后摄像头获得的数据,旋转角度、和纹理的左右相反等问题,可以根据相机id判断通过 顶点的旋转矩阵pointsMatrix 和 纹理映射矩阵vTextureCoordinateBuffer来解决。
glsurfaceview绘制坐标
2d下,glsurfaceview绘制到屏幕的坐标是归一化到- 1到1

在这里插入图片描述
samplerExternalOES的纹理坐标

在这里插入图片描述

如果纹理本来是正的,则只需要按照一样的映射关系传入到着色器就可以了。如果想旋转90度,则通过Matrix,当然也可以通过 改变纹理映射点的对应关系,如顶点着色器(-1,-1),而 texture对应点为(1,1),其他的对应点也顺时针对应时,则最终显示的图片就会旋转90度。

当然都可以通过matrix来处理,其中经常用的纹理绕中间位置对称互换,如:

   public void flipY(){
        float[] c  = MatrixUtils.getOriginalMatrix();
        MatrixUtils.flip(c,false,true);
        setPointsMatrix(c);
    }

4,创建program,链接着色器,绘制即可。

完整的demo

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值