博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OpenGL ES GLKit初探
阅读量:5124 次
发布时间:2019-06-13

本文共 6477 字,大约阅读时间需要 21 分钟。

#GLKit框架 GLKit框架的设计目的是为了简化OpenGL/OpenGL ES的应用开发。它的出现加快了OpenGL或OpenGL ES应用程序的开发。使用数学库、背景纹理加载,预先创建着色器效果,以及标准视图和视图控制器来实现渲染循环。 GLKit框架提供了功能和类,可以减少创建新的基于着色器的应⽤程序所需的⼯作量, 或者支持依赖早期版本的OpenGL ES或OpenGL提供的固定函数顶点或⽚段处理的现有 应用程序。

#GLKView 、GLKViewController 在iOS平台下,苹果给我们封装好了GLKViewController这样的一个类,简化了我们通过OpenGL ES渲染图形的工作。

//初始化GLKView- (instancetype)initWithFrame:(CGRect)frame context:(EAGLContext *)context;//颜色渲染缓冲区格式@property (nonatomic) GLKViewDrawableColorFormat drawableColorFormat;//深度渲染缓冲区格式@property (nonatomic) GLKViewDrawableDepthFormat drawableDepthFormat;//模板渲染缓冲区格式@property (nonatomic) GLKViewDrawableStencilFormat drawableStencilFormat;//多重采样缓冲区格式@property (nonatomic) GLKViewDrawableMultisample drawableMultisample;//帧缓冲区属性@property (nonatomic, readonly) NSInteger drawableWidth;    //缓冲区对象宽度@property (nonatomic, readonly) NSInteger drawableHeight;  //缓冲区对象高度/***  GLKViewDelegate必须实现的方法:在这个方法里进行绘图* - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect;*/@property (nullable, nonatomic, assign) IBOutlet id 
delegate;//将底层的FrameBuffer对象绑定到OpenGL ES- (void)bindDrawable;//删除视图FrameBuffer对象 - (void)deleteDrawable;//绘制视图内容并将其作为图像对象返回@property (readonly, strong) UIImage *snapshot;//布尔,指定视图是否响应使得视图内容无效的信息@property (nonatomic) BOOL enableSetNeedsDisplay;//立即重绘- (void)display;复制代码

#GLKTextureInfo 使用GLKTextureLoader可以创建加载OpenGL纹理信息:

GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:nil error:nil];GLKTextureInfo有以下信息:    GLuint                      name;        //纹理名称    GLenum                      target;    //纹理绑定的目标    GLuint                      width;        //加载纹理的宽度    GLuint                      height;        //加载纹理的高度    GLKTextureInfoAlphaState    alphaState;  //加载纹理中alpha状态    GLKTextureInfoOrigin        textureOrigin;  //加载纹理的原点位置    BOOL                        containsMipmaps;  //布尔值,加载的纹理是否包含mip贴图复制代码

#GLKBaseEffect GLKBaseEffect是OpenGL ES提供的一种简单的光照/着色系统,用于基于着色器的渲染。 #####配置光照

//为基元两侧计算光照 (系统去做,开发者来控制开关)@property (nonatomic, assign)         GLboolean                          lightModelTwoSided;//计算渲染图元光照使⽤的材质属性@property (nonatomic, readonly)       GLKEffectPropertyMaterial          *material; //环境颜⾊色,应⽤用效果渲染的所有图元@property (nonatomic, assign)         GLKVector4                         lightModelAmbientColor;//第1、2、3个光照属性GLKEffectPropertyLight              *_light0, *_light1, *_light2;复制代码

#####配置纹理

//配置第1、2个纹理GLKEffectPropertyTexture            *_texture2d0, *_texture2d1;//纹理应用于渲染图元的顺序NSArray                             *_textureOrder;复制代码

#####配置雾化

GLKEffectPropertyFog                *_fog;复制代码

#####配置颜色信息

//表示计算光照与材质交互时是否使用颜色顶点属性@property (nonatomic, assign)         GLboolean                          colorMaterialEnabled;//是否使用常量颜色@property (nonatomic, assign)         GLboolean                          useConstantColor; //不提供每个顶点颜色数据时使用常量颜⾊@property (nonatomic, assign)         GLKVector4                         constantColor; 复制代码

#####准备绘制效果

- (void) prepareToDraw;    //准备绘制效果(必须在绘制前写上)复制代码

#下面演示使用GLKit来画一个图片到屏幕上

配置环境

//配置环境- (void)setupUpEnv {    //初始化上下文    context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];    if (context == nil) {        NSLog(@"content create fail");        return;    }        [EAGLContext setCurrentContext:context];        //获取GLKView 设置context    GLKView * view = (GLKView *)self.view;    view.context = context;    view.delegate = self;        //配置视图创建的渲染缓冲区    view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;    view.drawableDepthFormat = GLKViewDrawableDepthFormat24;        //配置背景颜色    glClearColor(0, 1, 1, 1);}复制代码

###配置顶点数据

// 设置顶点数据数组(顶点坐标、纹理坐标)- (void)setUpVertexData {            //顶点数据和纹理数据都存在一个数组中 ,6个顶点,每五个数据 前三个为xyz顶点坐标  后两个为纹理坐标st    GLfloat vertexData [] = {        0.6, -0.5, 0.0f,    1.0f, 0.0f, //右下        0.6, 0.5, -0.0f,    1.0f, 1.0f, //右上        -0.6, 0.5, 0.0f,    0.0f, 1.0f, //左上                0.6, -0.5, 0.0f,    1.0f, 0.0f, //右下        -0.6, 0.5, 0.0f,    0.0f, 1.0f, //左上        -0.6, -0.5, 0.0f,   0.0f, 0.0f, //左下    };        //将顶点数据copyj到顶点缓冲区 : 这样做会提前分配一块显存,将顶点数据copy进去,这样可以性能更高    GLuint bufferID;    glGenBuffers(1, &bufferID);         //创建顶点缓冲区的标识符ID    glBindBuffer(GL_ARRAY_BUFFER, bufferID);    //绑定顶点缓冲区    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW); //将顶点数据copy到顶点缓冲区                    /**打开读取通道(默认是关闭的,这一步是必须要写的)     方法简介 : 上传顶点数据到显存的方法(设置合适的方式从buffer里面读取数据)         glVertexAttribPointer(GLuint indx , GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *ptr)     * 参数列表:     * indx :指定要修改的顶点属性索引值 :比如 GLKVertexAttribPosition代表顶点 GLKVertexAttribTexCoord0代表纹理     * 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 :指定一个指针,指向数组中第一个属性组件     */        //顶点坐标数据    glEnableVertexAttribArray(GLKVertexAttribPosition);    /** 每次读3个数据,即x y z。 顶点偏移量为5:    * 第一个顶点从下标0开始,第二个顶点从下标5开始,以此类推。。。    * (GLfloat *)NULL + 0 :表示首次读取的位置,因为此时读取是从显存读的  所以不能用数组地址去取  (GLfloat *)NULL表示首地址    */    glVertexAttribPointer(GLKVertexAttribPosition , 3, GL_FLOAT,GL_FALSE, 5, (GLfloat *)NULL + 0);        //纹理坐标数据    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 5, (GLfloat *)NULL + 3);}复制代码

###配置顶点数据

//配置纹理- (void)setUpTexture {    NSString * filePath = [[NSBundle mainBundle] pathForResource:@"memory" ofType:@"jpg"];        //因为纹理坐标和屏幕坐标是需要翻转的,所以这里需要配置一下映射关系    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(1),GLKTextureLoaderOriginBottomLeft, nil];        GLKTextureInfo * textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];        //使用 GLKBaseEffect 完成着色器的工作    cEffect = [[GLKBaseEffect alloc] init];    cEffect.texture2d0.enabled = GL_TRUE;    cEffect.texture2d0.name = textureInfo.name;}复制代码

###GLKViewDelegate开始绘图

#pragma mark - GLKViewDelegate- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {    glClear(GL_COLOR_BUFFER_BIT);        //重要的一步!!!    [cEffect prepareToDraw];        //开始绘制    glDrawArrays(GL_TRIANGLES, 0, 6);}复制代码

###viewDidLoad里依次调用

[self setupUpEnv];    [self setUpVertexData];    [self setUpTexture];复制代码

运行效果如下:

转载于:https://juejin.im/post/5d22f34fe51d45598611b9d5

你可能感兴趣的文章
《网络攻防》第6周作业
查看>>
Linux学习——echo和read命令用法
查看>>
WPF中的数据绑定Data Binding使用小结
查看>>
java读写注册表的两种方式,Preferences与jRegistry
查看>>
轻量级web富文本框——wangEditor使用手册(4)——配置下拉菜单 demo
查看>>
[C++程序设计]用指向数组的指针作函数参数
查看>>
深入理解C# 静态类与非静态类、静态成员的区别 [转载]
查看>>
套接字结构汇总
查看>>
JS脚本病毒调试脚本-Trojan[Downloader]:JS/Nemucod
查看>>
谈谈两种标准库类型---string和vector
查看>>
ERROR: JDWP Transport dt_socket failed to initialize, TRANSPORT_INIT(510)
查看>>
支付宝app支付java后台流程、原理分析(含nei wang chuan tou)
查看>>
Codeforces 480.E Parking Lot
查看>>
构造函数demo
查看>>
Python web开发——自定义userprofile(用户描述)
查看>>
ibatis的简介与初步搭建应用
查看>>
什么是单工、半双工和双工通信?有哪些实际应用的例子
查看>>
SQL Server-聚焦APPLY运算符(二十七)
查看>>
常用开发环境搭建配置教程(OneStall)
查看>>
SystemVerilog例子---traffic light
查看>>