Android 仿抖音之使用OpenGL显示摄像头

前言

在上一篇博客中,简单介绍了一下有关于OpenGL的基础内容,没看过的,可以看一下OpenGL ES基础,如果对里面有很多内容还是不懂的话,就百度一下吧,里面我都是简单说了一下大概内容,从这一篇开始,用仿抖音的项目来一步步具体介绍怎么在Android中使用OpenGL。
首先抖音其实就是录制前处理和录制后特效的处理,今天先来第一步使用OpenGL显示摄像头,为后面的工作做准备。

需求

使用OpenGL显示摄像头,分析一下需求,其实也就是两步,第一步采集摄像头数据,第二步将摄像头数据显示到屏幕上

采集摄像头数据

使用Android的Camera就可以实现采集

将摄像头数据显示到屏幕上

这里显示到屏幕上,其实有很多方法,比如ANative_window等等,但是这个是使用OpenGL实现,使用OpenGL怎么实现呢,在上一篇博客中说到了OpenGL的绘制流程,基本就是按照那个流程进行实现的。
下面是项目结构中一个不太规范的类图,下面根据这种图来实现具体的代码
 一张不太规范的类图
简单点说,我们都知道SurfaceView实质是将底层显存Surface显示到界面上,而GLSurfaceView实际就是在这个基础之上增加了OpenGL环境,DouyinView实际就相当于一块画布,而ScreenFilter中是封装了如何使用画笔去画当前摄像头采集到的内容,而DouyinRender渲染器,就是将ScreenFilter中的画渲染到画布上。

创建工程

创建一个JNI工程,就是在一开始创建项目的时候,勾选上 Include C++ support,这样就创建好了

配置文件 AndroidManifest.xml

OpenGL的使用还需要有设备制造商提供支持,以下是设备的支持情况,项目里都是用来2.0

OpenGL ES 1.0 和 1.1 :Android 1.0和更高的版本支持这个API规范。
OpenGL ES 2.0 :Android 2.2(API 8)和更高的版本支持这个API规范。
OpenGL ES 3.0 :Android 4.3(API 18)和更高的版本支持这个API规范。
OpenGL ES 3.1 : Android 5.0(API 21)和更高的版本支持这个API规范。

DouyinView.java

在这里插入图片描述

DouyinRender.java


这里使用的Render,是实现了OpenGL配置好EGL的渲染器,后面会自己来配置,这里先使用这个,上面也有提到过,OpenGL的操作都是在GLThread线程中完成,所以这里的onSurfaceCreated,onSurfaceChanged,onDrawFrame都是在GLThread中实现的,下面单独看看每个方法的使用
在这里插入图片描述
CameraHelper是封装了对Camera的一系列操作
在这里插入图片描述
在这里插入图片描述

创建着色器
  • AS里面有个插件可以支持GLSL的高亮显示,在plugin里面搜索 GLSL Support
  • 顶点着色器
    顶点着色器
  • 片元着色器
  • 这里我们需要画的是矩形,也就是两个三角形,给了4个点的坐标,这4个点,会执行4次顶点着色器,依次将顶点传递给gl_Position,当4个点都传递完成之后,会进行光栅化,将一个矩形变换成一个个的片元,然后再去使用gl_FragColor去着色
  • 因为SurfaceTexture是Android中的,并不是OpenGL的,所以需要使用额外扩展的采样器samplerExternalOES,而不是普通的sample2D采样器,在使用samplerExternalOES时候,需要再添加一句:#extension GL_OES_EGL_image_external : require
ScreenFilter.java
 public ScreenFilter(Context context) {
   

        //把camera_vertext内容读出来
        String vertexSource= OpenUtils.readRawTextFile(context, R.raw.camera_vertex);
        String fragSource = OpenUtils.readRawTextFile(context, R.raw.camera_frag);


        //通过字符串创建着色器程序
        //使用opengl
        //一.顶点着色器
        //1.1创建顶点着色器
        int vSharderId = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
        //1.2绑定代码到着色器中
        G
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在OpenGL显示摄像头视频,你需要完成以下步骤: 1. 打开摄像头并捕获视频帧 2. 将捕获的帧上传到纹理中 3. 在OpenGL中绘制纹理 下面是一个示例代码片段,可以帮助你开始: ```c++ #include <opencv2/opencv.hpp> #include <GL/glut.h> using namespace cv; GLuint textureID; // 纹理ID Mat frame; // 视频帧 void display() { glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, textureID); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0); glTexCoord2f(1.0, 0.0); glVertex2f(1.0, -1.0); glTexCoord2f(1.0, 1.0); glVertex2f(1.0, 1.0); glTexCoord2f(0.0, 1.0); glVertex2f(-1.0, 1.0); glEnd(); glFlush(); glutSwapBuffers(); } void init() { glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); // 设置纹理参数 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // 加载空白纹理 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, frame.cols, frame.rows, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, frame.data); } void captureFrame() { VideoCapture cap(0); // 打开默认摄像头 cap >> frame; } void timer(int) { captureFrame(); // 将帧上传到纹理中 glBindTexture(GL_TEXTURE_2D, textureID); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frame.cols, frame.rows, GL_BGR_EXT, GL_UNSIGNED_BYTE, frame.data); glutPostRedisplay(); glutTimerFunc(1000/60, timer, 0); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowSize(640, 480); glutCreateWindow("Camera Viewer"); init(); glutDisplayFunc(display); glutTimerFunc(0, timer, 0); glutMainLoop(); return 0; } ``` 这段代码使用OpenCV捕获默认摄像头的视频帧,并将其上传到OpenGL中的纹理中。在 `display` 函数中,我们使用纹理来绘制一个矩形,并在每一帧结束时交换缓冲区。在 `timer` 函数中,我们使用定时器来捕获新的视频帧并更新纹理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值