使用OpenGLES实现UIImageView显示效果

栏目: IOS · 发布时间: 5年前

内容简介:本篇使用

本篇使用 OpenGLES 实现 UIImageView 的显示功能,代码已做详细注释。 OpenGL 相关文章参考前几篇。

代码如下

//
//  ViewController.m
//  OpenGLES
//
//  Created by dowZhang on 2019/6/2.
//  Copyright © 2019 dowZhang. All rights reserved.
//

#import "ViewController.h"
#import <OpenGLES/ES3/gl.h>
#import <OpenGLES/ES3/glext.h>

@interface ViewController ()
{
    EAGLContext *context;
    GLKBaseEffect *cEffect;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self setupConfig];
    
    [self setupVertexData];
    
    [self setupTexture];
}

-(void)setupConfig {
    context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES3];
    if (context == nil) {
        NSLog(@"create context error");
    }
    [EAGLContext setCurrentContext:context];
    GLKView *view = (GLKView *)self.view;
    view.context = context;
    /**
     GLKViewDrawableColorFormatRGBA8888 = 0,
     缓存区的每个像素的最小组成部分(RGBA)使用8个bit,(所以每个像素4个字节,4*8个bit
     
     drawableDepthFormat: 深度缓存区格式 GLKViewDrawableDepthFormatNone:没有缓冲区
     */
    view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
    view.drawableDepthFormat = GLKViewDrawableDepthFormat16;
    glClearColor(0.0f, 1.0f, 0.5f, 1.0f);
}

-(void)setupVertexData {
    
    /**
     顶点坐标取值范围[-1,1],中心点为(0,0)
     *顶点坐标和纹理坐标,一个数组保存开一个缓冲区,操作也更方便
     *顶点数组:这部分数据存储在内存中,在绘制的时候由内存传入顶点数据。
     *顶点缓存区:性能更高的做法是,提前分配一块显存,将顶点数据预先存入到显存中,这部分显存被称为顶点缓冲区
     */
    GLfloat vertexData[] = {
        
        0.5, -0.5, 0.0f,    1.0f, 0.0f, //右下
        0.5, 0.5, -0.0f,    1.0f, 1.0f, //右上
        -0.5, 0.5, 0.0f,    0.0f, 1.0f, //左上
        
        0.5, -0.5, 0.0f,    1.0f, 0.0f, //右下
        -0.5, 0.5, 0.0f,    0.0f, 1.0f, //左上
        -0.5, -0.5, 0.0f,   0.0f, 0.0f, //左下
    };
    
    //开辟顶点缓存区
    GLuint bufferID;
    glGenBuffers(1, &bufferID);
    //缓存区作用
    glBindBuffer(GL_ARRAY_BUFFER, bufferID);
    //将内存数据copy到GPU显存中
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
    
    //打开通道
    /*
     (1)在iOS中, 默认情况下,出于性能考虑,所有顶点着色器的属性(Attribute)变量都是关闭的.
     意味着,顶点数据在着色器端(服务端)是不可用的. 即使你已经使用glBufferData方法,将顶点数据从内存拷贝到顶点缓存区中(GPU显存中).
     所以, 必须由glEnableVertexAttribArray 方法打开通道.指定访问属性.才能让顶点着色器能够访问到从CPU复制到GPU的数据.
     注意: 数据在GPU端是否可见,即,着色器能否读取到数据,由是否启用了对应的属性决定,这就是glEnableVertexAttribArray的功能,允许顶点着色器读取GPU(服务器端)数据。
     
     (2)方法简介
     glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
     
     功能: 上传顶点数据到显存的方法(设置合适的方式从buffer里面读取数据)
     参数列表:
     index,指定要修改顶点属性
     size, 每次读取数量。(如position是由3个(x,y,z)组成,而颜色是4个(r,g,b,a),纹理则是2个.)
     type,指定数组中每个组件的数据类型。可用的符号常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT,GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值为GL_FLOAT。
     normalized,指定当被访问时,固定点数据值是否应该被归一化(GL_TRUE)或者直接转换为固定点值(GL_FALSE)
     stride,指定连续顶点属性之间的偏移量。如果为0,那么顶点属性会被理解为:它们是紧密排列在一起的。初始值为0
     ptr指定一个指针,指向数组中第一个顶点属性的第一个组件。初始值为0
     */
    
    //顶点坐标
    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);
    
}

-(void)setupTexture {
    
    NSString *filePath = [[NSBundle mainBundle]pathForResource:@"me" ofType:@"png"];
        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(true),GLKTextureLoaderOriginBottomLeft, nil];
    GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
    //GLKit 提供GLKBaseEffect 完成着色器工作(顶点/片元)
    cEffect = [[GLKBaseEffect alloc]init];
    cEffect.texture2d0.enabled = GL_TRUE;
    cEffect.texture2d0.name = textureInfo.name;
}

#pragma mark -- GLKviewDelegate
// GLKView对象使其OpenGL ES上下文成为当前上下文,并将其framebuffer绑定为OpenGL ES呈现命令的目标。然后,委托方法应该绘制视图的内容。
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    
    glClear(GL_COLOR_BUFFER_BIT);
    [cEffect prepareToDraw];
    glDrawArrays(GL_TRIANGLES, 0, 6);
}
@end

复制代码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Algorithms and Data Structures

Algorithms and Data Structures

Kurt Mehlhorn、Peter Sanders / Springer / 2008-08-06 / USD 49.95

Algorithms are at the heart of every nontrivial computer application, and algorithmics is a modern and active area of computer science. Every computer scientist and every professional programmer shoul......一起来看看 《Algorithms and Data Structures》 这本书的介绍吧!

在线进制转换器
在线进制转换器

各进制数互转换器

html转js在线工具
html转js在线工具

html转js在线工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具