OpenGL ES (一)镜像图片

bancheng发布

导语

使用GPUImage 库写过一点效果,更加好奇它的底层OpenGL ES 是怎么工作的,再加上swift已经到4.0版本,平时零零碎碎的看过一些基本东西,但是自己却一直没动手写过什么东西。临渊羡鱼,不如退而结网;笨鸟慢飞,贵在坚持。

两个坐标系

1、OpenGL ES 中世界坐标系是以屏幕中心为原点(0, 0, 0),且是始终不变的。你面对 屏幕,你的右边是x正轴,上面是y正轴,屏幕指向你的为z正轴。长度单位这样来定: 窗口范围按此单位恰好是(-1,-1)到(1,1),即屏幕左下角坐标为(-1,-1),右上角坐标为(1,1)。

2、纹理坐标,纹理坐标是以图片的左下角为原点,向上为Y轴的正方向,区间[0,1],向右为X轴的正方向区间为[0,1]。

GLKit框架

GLKit框架是苹果为了简化基于OpenGL或者OpenGL ES的应用开发而封装的一套高级API框架
GLKit 主要的功能:
1. 纹理加载(Texture loading): GLKTextuerLoader Class.
2. 性能卓越的科学运算库, 支持矢量, 四元数,矩阵运算等。
3. 实现的常见的标准Shader特效。 GLKit允许你配置你所需要的特效,它会自动创建和加载对应的Shader。
GLKBaseEffect, GLKReflectionMapEffect, GLKSkyboxEffect Class.
4. 对应于GLKit的View和ViewController。 GLKView Class 和 GLKViewController Class.
# 流程

  • 生成(Generate)
  • 绑定(Bind)
  • 缓存数据(Buffer Data)
  • 启用(Enable)或者禁用(Disable)
  • 设置指针(Set Pointers)
  • 绘图(Draw)
  • 删除(Delete)

    # 关键代码
    1、配置环境
    “`swift
    func setupConfig(){

        let glView:GLKView = self.view as! GLKView;
        glView.context = context;
        //设置渲染颜色格式
        glView.drawableColorFormat = .RGBA8888;
        //设置渲染深度
        glView.drawableDepthFormat = .format24;
        EAGLContext.setCurrent(context);
    
    }
    

    “`

    2、加载纹理
    “`swift
    func loadTexture() {

        let filePath :String = Bundle.main.path(forResource: "test", ofType: "jpg")!;
    
        do {
            //[GLKTextureLoaderOriginBottomLeft:false]
            let textureInfo:GLKTextureInfo = try GLKTextureLoader.texture(withContentsOfFile: filePath, options:nil);
            effect.texture2d0.enabled = GLboolean(GL_TRUE);
            effect.texture2d0.name = textureInfo.name;
    
        } catch let error {
    
            print("error is \(error.localizedDescription)");
        }
    
    }
    

    “`

    3、提交数据
    “`swift
    func initVertexCoordinates() {

    // [-0.5 0] [0,0.5]
    //前三位顶点坐标 后两位纹理坐标
    let vertext:[GLfloat] = [
    //左半部分
    0, 1.0, 0.0, 0.5, 0.0, //右下
    0, -1.0, 0.0, 0.5, 1.0, //右上
    -1.0, -1.0, 0.0, 0, 1.0, //左上

            0.0, 1.0, 0.0,    0.5, 0.0, //右下
            -1.0, -1.0, 0.0,   0, 1.0, //左上
            -1.0, 1.0, 0.0,   0.0, 0.0, //左下
    
            //右半部分
            1.0, 1.0, 0.0,     0.0, 0.0, //右下
            1.0, -1.0, 0.0,    0, 1.0, //右上
            0, -1.0, 0.0,     0.5, 1.0, //左上
    
            1.0, 1.0, 0.0,    0.0, 0.0, //右下
            0.0, -1.0, 0.0,   0.5, 1.0, //左上
            0.0, 1.0, 0.0,   0.5, 0.0, //左下
        ];
        //生成新缓存对象。并返回缓存buffer id
        glGenBuffers(1, &buffer);
        //将申请的缓存对象绑定到GL_ARRAY_BUFFER中
        glBindBuffer(GLenum(GL_ARRAY_BUFFER), buffer);
        //将顶点数据拷贝到缓存对象中
        glBufferData(GLenum(GL_ARRAY_BUFFER), GLsizeiptr(MemoryLayout<GLfloat>.size * vertext.count) , vertext, GLenum(GL_STATIC_DRAW));
    
        //启用顶点
        glEnableVertexAttribArray(GLuint(GLKVertexAttrib.position.rawValue));
        glVertexAttribPointer(GLuint(GLKVertexAttrib.position.rawValue),
                              3,
                              GLenum(GL_FLOAT),
                              GLboolean(GL_FALSE),
                              GLsizei(MemoryLayout<GLfloat>.size * 5), nil);
    
        //启用纹理
        let offset :GLsizeiptr = MemoryLayout<GLfloat>.size * 3;
        glEnableVertexAttribArray(GLuint(GLKVertexAttrib.texCoord0.rawValue));
        glVertexAttribPointer(GLuint(GLKVertexAttrib.texCoord0.rawValue),
                              2,
                              GLenum(GL_FLOAT),
                              GLboolean(GL_FALSE),
                              GLsizei(MemoryLayout<GLfloat>.size * 5),
                              UnsafeRawPointer.init(bitPattern: offset));
    
    
    }
    

    4、渲染swift
    func glkView(_ view: GLKView, drawIn rect: CGRect) {
    glClearColor(0.1, 0.5, 0.0, 1);
    glClear(GLbitfield(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
    effect.prepareToDraw();
    glDrawArrays(GLenum(GL_TRIANGLES), 0, 12);

    }
    

    “`
    # 写在最后
    * 花的时间较多地方还是在 swift这块。语法的不适应和swift指针的类型的转换花掉了不少时间,基本是边百度边写的状态完成的。
    * 镜像效果不难,了解OpenGL 或者用GPUImage 写过效果的都会很自然的想到使用 纹理裁剪

  • 分类: OpenGL ES

    bancheng

    iOS开发者一枚,现就职中国北京。在这里记录自己开发遇到的问题和学习记录的笔记。喜欢学习、摄影。

    发表评论

    电子邮件地址不会被公开。 必填项已用*标注