OpenGLES学习(一)图片显示

简介:电脑或者手机上做图像处理有很多方式,但是目前为止最高效的方法是有效地使用图形处理单元,或者叫 GPU。你的手机包含两个不同的处理单元,CPU 和 GPU。CPU 是个多面手,并且不得不处理所有的事情,而 GPU 则可以集中来处理好一件事情,就是并行地做浮点运算。事实上,图像处理和渲染就是在将要渲染到窗口上的像素上做许许多多的浮点运算。
  通过有效的利用 GPU,可以成百倍甚至上千倍地提高手机上的图像渲染能力。如果不是基于 GPU 的处理,手机上实时高清视频滤镜是不现实,甚至不可能的。

EAGLContext:渲染上下文,OpenGL ES 必须有一个可用的上下文才能绘图;

//新建OpenGles上下文
    self.mContext = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
    GLKView *view = (GLKView *)self.view;//storyboard记得将view对应的类改为GLKView
    view.context = self.mContext;
    view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;//颜色缓冲区格式
    [EAGLContext setCurrentContext:self.mContext];

创建顶点缓冲对象
第一种方法:未设置索引
顶点数组里包括顶点坐标,OpenGLES的世界坐标系是[-1, 1],故而点(0, 0)是在屏幕的正中间。
纹理坐标系的取值范围是[0, 1],原点是在左下角。故而点(0, 0)在左下角,点(1, 1)在右上角。
OpenGL ES不能绘制多边形,只能绘制点,线,三角形,OpenGL可以绘制多边形,由于我们绘制的图片是一个矩形,又两个三角形构成。

 //顶点数据,前三个是顶点坐标,后面两个是纹理坐标
    GLfloat vertexArr[] = {
        -0.74, -0.5, 0,  0.0f, 0.0f, //左下
        -0.74,  0.5, 0,  0.0f, 1.0f, //左上
         0.74, -0.5, 0,  1.0f, 0.0f, //右下

         0.74,  0.5, 0,  1.0f, 1.0f, //右上
         0.74, -0.5, 0,  1.0f, 0.0f, //右下
         -0.74,  0.5, 0,  0.0f, 1.0f, //左上
    };
     /*
     glGenBuffers申请一个标识符
     glBindBuffer把标识符绑定到GL_ARRAY_BUFFER上
     glBufferData把顶点数据从cpu内存复制到gpu内存
     glEnableVertexAttribArray 是开启对应的顶点属性
     glVertexAttribPointer设置合适的格式从buffer里面读取数据
     */

    /*
     创建顶点缓存对象需要3个步骤:
     1,使用glGenBuffers()生成新缓存对象。
     2,使用glBindBuffer()绑定缓存对象。
     3,使用glBufferData()将顶点数据拷贝到缓存对象中。
     */
    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexArr), vertexArr, GL_STATIC_DRAW);

    /*
     默认情况下,出于性能考虑,所有顶点着色器的属性(Attribute)变量都是关闭的,意味着数据在着色器端是不可见的,哪怕数据已经上传到GPU,由glEnableVertexAttribArray启用指定属性,才可在顶点着色器中访问逐顶点的属性数据。glVertexAttribPointer或VBO只是建立CPU和GPU之间的逻辑连接,从而实现了CPU数据上传至GPU。但是,数据在GPU端是否可见,即,着色器能否读取到数据,由是否启用了对应的属性决定,这就是glEnableVertexAttribArray的功能,允许顶点着色器读取GPU(服务器端)数据。
     */
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*5, (GLfloat *)NULL + 0);

    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*5, (GLfloat *)NULL + 3);

第二种方法:设置索引

GLfloat vertexArr[] =
    {
        0.74, -0.5, 0.0f,    1.0f, 0.0f, //右下
        0.74, 0.5,0.0f,    1.0f, 1.0f, //右上

        -0.74, 0.5, 0.0f,    0.0f, 1.0f, //左上
        -0.74, -0.5, 0.0f,   0.0f, 0.0f, //左下
    };
    GLuint indexVertex[] = {
        0, 2, 3,
        0, 1, 2,
    };
    self.mCount = sizeof(indexVertex)/sizeof(GLuint);

    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexArr), vertexArr, GL_STATIC_DRAW);

    GLuint index;
    glGenBuffers(1, &index);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexVertex), indexVertex, GL_STATIC_DRAW);

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*5, (GLfloat *)NULL + 0);

    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*5, (GLfloat *)NULL + 3);

添加图片及着色器
由于纹理坐标系是跟手机显示的Quartz 2D坐标系的y轴正好相反,纹理坐标系使用左下角为原点,往上为y轴的正值,往右是x轴的正值,所以需要设置一下GLKTextureLoaderOriginBottomLeft。

NSString *filePath = [[NSBundle mainBundle]pathForResource:@"rabbit" ofType:@"png"];
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(1),GLKTextureLoaderOriginBottomLeft, nil];
    GLKTextureInfo *textureInfo = [GLKTextureLoader
                                   textureWithContentsOfFile:filePath
                                                     options:options
                                                       error:nil];
    self.mEffect = [[GLKBaseEffect alloc]init];
    self.mEffect.texture2d0.enabled = GL_TRUE;
    self.mEffect.texture2d0.name = textureInfo.name;

图片渲染

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    [self.mEffect prepareToDraw];
    glDrawElements(GL_TRIANGLES, self.mCount, GL_UNSIGNED_INT,0);
    //glDrawArrays(GL_TRIANGLES, 0, 6);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值