OpenGL ES
android中 GLSurfaceView 繼承 SurfaceView
GLSurfaceView 中有 GLThread
setEGLContextClientVersion(2);//使用openGLES 2.0上下文
setRenderer(...);//設(shè)置渲染回調(diào)接口 該方法中實(shí)例化GLThread
/**
* 刷新方式:
* RENDERMODE_WHEN_DIRTY 手動(dòng)刷新,調(diào)用requestRender();
* RENDERMODE_CONTINUOUSLY 自動(dòng)刷新,大概16ms自動(dòng)回調(diào)一次onDraw方法
*/
//注意必須在setRenderer 后面。
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
openGL 渲染管線 頂點(diǎn)->圖元裝配->光柵化(像素化)
著色器(頂點(diǎn)著色器和片元著色器)
Android Studio 集成GLSLSupport插件 編輯OpenGL著色器語言(GLSL)時(shí)關(guān)鍵字高亮智能提示
openGL著色語言
attribute 屬性變量(只在頂點(diǎn)著色器使用)
uniforms 一致變量(片元著色器使用)
varying 易編變量(頂點(diǎn)著色器輸出數(shù)據(jù)到片元著色器)
gl_Position 坐標(biāo)(x,y,z,w)
samplerExternalOES 圖片采樣器
samplerExternalOES 相當(dāng)于rgba 使用texture2D(...)
precision / mediump / float 精度定義
openGL的世界坐標(biāo)和紋理坐標(biāo)
static final float COORD[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
static final float TEXTURE_COORD[] = {
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
};

-
onSurfaceCreated
@Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { //創(chuàng)建OpenGL 紋理 ,把攝像頭的數(shù)據(jù)與這個(gè)紋理關(guān)聯(lián) textures = new int[1]; //當(dāng)做能在opengl用的一個(gè)圖片的ID mCameraTexure.attachToGLContext(textures[0]); // 當(dāng)攝像頭數(shù)據(jù)有更新回調(diào) onFrameAvailable mCameraTexure.setOnFrameAvailableListener(this);//監(jiān)聽更新時(shí)手動(dòng)調(diào)用requestRender() screenFilter = new ScreenFilter(cameraView.getContext()); }創(chuàng)建和初始化著色器供, 這些過程一般分為7個(gè)步驟:
創(chuàng)建頂點(diǎn)著色器對象(glcreateShader);
向頂點(diǎn)著色器對象中填充著色器程序的源代碼(glshaderSource);
編譯頂點(diǎn)著色器(glcompileShander);
創(chuàng)建片元著色器對象(glcreateShader);
向片元著色器對象中填充著色器程序的源代碼(glshaderSource);
編譯片元著色器(glcompileShander);
創(chuàng)建程序?qū)ο螅╣lcreateProgram);
為程序?qū)ο蠓峙渲鳎╣lattachShader);
連接程序?qū)ο螅╣llinkProgram);
使用程序?qū)ο螅╣luseProgram)
//著色器程序準(zhǔn)備
public static int loadProgram(String vSource, String fSource) {
/**
* 頂點(diǎn)著色器
*/
int vShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
//加載著色器代碼
GLES20.glShaderSource(vShader, vSource);
//編譯(配置)
GLES20.glCompileShader(vShader);
//查看配置 是否成功
int[] status = new int[1];
GLES20.glGetShaderiv(vShader, GLES20.GL_COMPILE_STATUS, status, 0);
if (status[0] != GLES20.GL_TRUE) {
//失敗
throw new IllegalStateException("load vertex shader:" + GLES20.glGetShaderInfoLog
(vShader));
}
/**
* 片元著色器
* 流程和上面一樣
*/
int fShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
//加載著色器代碼
GLES20.glShaderSource(fShader, fSource);
//編譯(配置)
GLES20.glCompileShader(fShader);
//查看配置 是否成功
GLES20.glGetShaderiv(fShader, GLES20.GL_COMPILE_STATUS, status, 0);
if (status[0] != GLES20.GL_TRUE) {
//失敗
throw new IllegalStateException("load fragment shader:" + GLES20.glGetShaderInfoLog
(vShader));
}
/**
* 創(chuàng)建著色器程序
*/
int program = GLES20.glCreateProgram();
//綁定頂點(diǎn)和片元
GLES20.glAttachShader(program, vShader);
GLES20.glAttachShader(program, fShader);
//鏈接著色器程序
GLES20.glLinkProgram(program);
//獲得狀態(tài)
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, status, 0);
if (status[0] != GLES20.GL_TRUE) {
throw new IllegalStateException("link program:" + GLES20.glGetProgramInfoLog(program));
}
GLES20.glDeleteShader(vShader);
GLES20.glDeleteShader(fShader);
return program;
}
onSurfaceChanged設(shè)置寬高
-
onDrawFrame
@Override public void onDrawFrame(GL10 gl) { //todo 更新紋理 mCameraTexure.updateTexImage();//拿到最新的圖像數(shù)據(jù) mCameraTexure.getTransformMatrix(mtx); screenFilter.setTransformMatrix(mtx); screenFilter.onDraw(textures[0]); }public int onDraw(int texture, FilterChain filterChain) { FilterContext filterContext = filterChain.filterContext; //設(shè)置繪制區(qū)域 GLES20.glViewport(0, 0, filterContext.width, filterContext.height); GLES20.glUseProgram(program); vertexBuffer.position(0); // 4、歸一化 normalized [-1,1] . 把[2,2]轉(zhuǎn)換為[-1,1] GLES20.glVertexAttribPointer(vPosition, 2, GLES20.GL_FLOAT, false, 0, vertexBuffer); //CPU傳數(shù)據(jù)到GPU,默認(rèn)情況下著色器無法讀取到這個(gè)數(shù)據(jù)。 需要我們啟用一下才可以讀取 GLES20.glEnableVertexAttribArray(vPosition); textureBuffer.position(0); // 4、歸一化 normalized [-1,1] . 把[2,2]轉(zhuǎn)換為[-1,1] GLES20.glVertexAttribPointer(vCoord, 2, GLES20.GL_FLOAT, false, 0, textureBuffer); //CPU傳數(shù)據(jù)到GPU,默認(rèn)情況下著色器無法讀取到這個(gè)數(shù)據(jù)。 需要我們啟用一下才可以讀取 GLES20.glEnableVertexAttribArray(vCoord); //相當(dāng)于激活一個(gè)用來顯示圖片的畫框 GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture); // 0: 圖層ID GL_TEXTURE0 // GL_TEXTURE1 , 1 GLES20.glUniform1i(vTexture, 0); beforeDraw(); //通知畫畫, GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); return texture; }openGL ES離屏渲染 FBO(Frame Buffer Object)幀緩存對象
public void createFrame(int width, int height) { releaseFrame(); //創(chuàng)建FBO /** * 1、創(chuàng)建FBO + FBO中的紋理 */ frameBuffer = new int[1]; frameTextures = new int[1]; GLES20.glGenFramebuffers(1, frameBuffer, 0); OpenGLUtils.glGenTextures(frameTextures); /** * 2、fbo與紋理關(guān)聯(lián) */ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, frameTextures[0]); GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null); //紋理關(guān)聯(lián) fbo GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuffer[0]); //綁定FBO GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, frameTextures[0], 0); /** * 3、解除綁定 */ GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); }
EGL庫 管理窗口 將Surface和EGLSurface綁定

openGL是在GLThread子線程 同樣需要搭建一個(gè)EGL環(huán)境在子線程
1.創(chuàng)建Display獲取顯示窗口
EGLDisplay mEglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
EGL14.eglinitialize(...);//初始化
2.配置屬性選項(xiàng)
EGL.eglChooseConfig(...)
3.創(chuàng)建EGL上下文
EGL14.eglCreateWindowSurface(...)
5.繪制
//先綁定當(dāng)前線程的顯示屏diplay
EGL14.eglMakeCurrent(EGLDisplay, EGLSurface, EGLSurface, EGLContext);
//EGLSurface是雙緩沖模式
EGLExt.eglPresentationTimeANDROID(EGLDisplay,EGLSurface,時(shí)間戳);
EGL14.eglSwapBuffers(EGLDisplay,EGLSurface);
實(shí)現(xiàn)功能一 、調(diào)整快慢幀
//只需要調(diào)整bufferInfo參數(shù)中的時(shí)間戳
Muxer.writeSampleData(track,encodeData,bufferInfo);
//改變時(shí)間的速率
bufferInfo.presentationTimeUs = bufferInfo.presentationTimeUs/speed;
實(shí)現(xiàn)功能二、識別臉部 使用Seetaface FaceLandmarker
圖像局部縮放

實(shí)現(xiàn)功能三、圖像遮罩物
openGL圖像混合
GLES20.gleEnable(GLES20.GL_BLEND);
GLES20.GLBlendFunc(GLES20.GLONE,GLES20.GL_ONE_MINUS_SRC_ALPHA);
//GL_ONE采用源顏色的alpha值作為因子
//GL_ONE_MINUS_SRC_ALPHA表示用1.0減去源顏色的aplha作為因子
利用GLES20.glViewPort(x,y,width,heigh)或openGL中轉(zhuǎn)換世界坐標(biāo)系
GLUtils.textImage2D(...)將Bitmap圖片綁定openGL中
實(shí)現(xiàn)功能四、美顏
1.模糊效果(水平方向和垂直方向)設(shè)計(jì)11*11算子
2.高反差保留 邊緣化 高反差=原圖-模糊圖
3.保留邊緣細(xì)節(jié)不被模糊掉
4.磨皮調(diào)整
實(shí)現(xiàn)功能五、閃爍 以中心點(diǎn)(0.5,0.5)向四周擴(kuò)散
實(shí)現(xiàn)功能六、分配 以屏幕0.25~0.75繪制(大于0.5則減去0.25,否則加上0.25)