Android OpenGL小结之专业名词理解

作者: jackzhoud | 来源:发表于2019-12-06 11:17 被阅读0次

    Android OpenGL小结之专业名词理解


    image
    出入之间,境界始大。不仅收其精微,汇其宏阔,且人情与道理兼具,生气同高致并存。入而不出,狭隘;出而不入,浮浅。故善学者,善于深思与总结。学习如此,创作如此,生活亦如此。

    学习不仅仅是接受一些新知识,而且要擅于总结,把学习的新知识转化为自己的知识,才能学以致用;故把之前的OpenGL学习遇到的名词总结一番。

    OpenGL ES库


    OpenGL ES库是针对于嵌入式设备而裁剪的版本库,在Android端是以NDK形式存在,此库可用于GPU的图像开发,数据到图像的过程

    EGL


    不同产商底层驱动实现不同,为了是OpenGL在不同产商设备上能成功执行,EGL作为中间的桥梁搭建,为OpenGL提供渲染环境;EGL提供抽象显示display、渲染上下文Context以及创建3中不同的window surface;OpenGL的渲染操作必须要EGL为其提供渲染环境,Android里面常见的GLSurfaceView不用,因为其内部已经显示了EGL环境,但是如其他的SurfaceView、TextureView则需要自己去实现EGL环境

    GLSL


    用于指导GPU可编程管线的编程语言,与C语言类似;主要用于指导GPU管线如何去绘制图元、颜色;编写好程序后需要提交给OpenGL进行编译、链接才能使用;这里主要编写顶点着色器和片元着色器

    纹理


    纹理主要是用于图像数据的展示,创建纹理后,绑定图像数据textImage2D(),最后在渲染时,首先激活纹理,然后片元着色器的采样器Sampler会根据传入的纹理坐标来这个纹理数据里面取色渲染

    FBO


    Frame Buffer Object帧缓冲对象,在屏幕上显示的最后一步,就是将所有的任务提交给FBO,由FBO输出到屏幕上;日常开发中没有使用FBO而屏幕上却显示了,那是因为默认激活的FBO ID为0,这个ID为0的就是屏幕的FBO;所以我们可以创建ID非0的FBO,这样我们输出到FBO的图像就不会显示到屏幕;

    那FBO有什么用?

    • 可以对图像预处理,如图像美颜,处理完成后再通过其他收发输出到屏幕
    • FBO突破屏幕尺寸,不在受默认FBO屏幕尺寸的限制

    如何使用FBO?
    详情可以点击这里,FBO提供颜色附着和深度附着,我们可以使用纹理以及renderBuffer附着到FBO上,当我们激活FBO后,正常渲染操作都会输出到FBO,然后可以通过预先附着的纹理和renderBuffer提取图像

    Android与OpenGL相关的组件


    SurfaceView


    复杂的2D图像绘制显示,不阻塞主线程
    必须在子线程中使用,并且在回调SurfaceHolder的surfaceCreated和surfaceDestroyed方法之间才能绘制
    双缓冲机制,绘制完成后显示,lockCanvas获取画布进行绘制,unlockCanvasAndPost提交更新
    伪代码例子:

    public class MyView extends SurfaceView 
                        implements SurfaceHolder.Callback
                        ,Runnable {
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            running=true;
            new Thread(this).start();
     
        }
     
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
     
        }
     
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            running=false;
        }
        @Override
        public void run() {
            while(shouldDrawing){
                    Canvas=surfaceHolder.lockCanvas();
                    //drawing
                    surfaceHolder.unlockCanvasAndPost(mCanvas);
            }
        }
    
    }
    

    GLSurfaceView


    GLSurfaceView集成与SurfaceView,集成了SurfaceView的特性,不同的是它使用了OpenGL环境来渲染,其内部已实现了EGL环境,使用方法主要是:

    • 设置Render渲染器
    • 设置渲染方式
    glSurfaceView.setRenderer(renderer);
    glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
    

    RENDERMODE_WHEN_DIRTY 触发式手动刷新 RENDERMODE_CONTINUOUSLY 持续刷新 固定周期刷新

    • Render渲染器,渲染具体流程
    public class GLRender implements GLSurfaceView.Renderer {
        //surfaceView创建时调用
        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        }
    
        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
        }
    
        //surfaceView绘制时回调
        @Override
        public void onDrawFrame(GL10 gl) {
        }
    }
    

    TextureView


    TextureView可用于显示图像流,来自相机或者OpenGL渲染的图像;主要是通过TexttureView方法onSurfaceTextureAvailable的参数SurfaceTexture表面纹理来实现的

    TextureView与相机Camera搭配


    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
              mCamera = Camera.open();
              try {
                  mCamera.setPreviewTexture(surface);
                  mCamera.startPreview();
              } catch (IOException ioe) {
                  // Something bad happened
              }
          }
    

    TextureView与OpenGL搭配


    • EGL创建windowSurface以及OpenGL的渲染环境
    • 与TextureView的SurfaceTexture绑定makecurrent
    • OpenGL正常的渲染绘制
    • swapBuffer进行显示

    SurfaceTexture


    表面纹理SurfaceTexture,实质也是一个纹理的封装类,其内部纹理可以作为图像流的输出对象,来自相机或者解码的视频流均可以;

    小测验


    你理解了上面的名词解释了吗?或者你自学OpenGL觉得OK了吗?那咱们来个小测验吧!
    相机美颜过程如何实现的?只需要一个大概的理解就可以,无需太详细,先不要看后面的答案!

    image
    问题分析:
    首先,我们要拿到相机的预览数据,而且不能马上显示到屏幕,这就需要FBO;
    然后,对拿到的相机数据进行美颜处理,这里处理就需要glsl的美颜算法;
    最后,在将修改的数据渲染的默认的屏幕FBO上去,显示即可;
    还需要注意的一点是:相机预览数据一般均是YUV格式,而OpenGL只能显示RGB图像,这里需要设置SurfaceTexture纹理特定的格式OES让其内部自动转换 image

    大致如上图流程,最后一步View显示不一定非得是TextureView,也可以是GLSurfaceView和SurfaceView,那样的话涉及4和5步骤的处理方式不同;如果是GLSufaceView,直接从第4步开始,渲染到GLSurfaceView的渲染器Render即可;如果是SurfaceView,则需要在第5步骤,将前一步骤FBO里面的纹理数据glReadPixels拷贝出来,在绘制到SurfaceView的Canvas上去即可。

    我的项目地址

    加入公众号,我们一同成长!

    image

    相关文章

      网友评论

        本文标题:Android OpenGL小结之专业名词理解

        本文链接:https://www.haomeiwen.com/subject/sawsgctx.html