OpenGL ES GLKit初探

#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 <GLKViewDelegate> 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 设置contextGLKView * 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顶点坐标  后两个为纹理坐标stGLfloat 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);         //创建顶点缓冲区的标识符IDglBindBuffer(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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/424184.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个封装了的ADO类,功能非常强大,并做了一个DEMO演示如何操作ACCESS数据库

呵呵&#xff0c;说实在的&#xff0c;这个类俺是从外国论坛上下载的&#xff0c;自己研究了下如何使用并做了一个DEMO&#xff0c;演示如何操作ACCESS数据库。希望给那些没有接触数据库编程的初学者一点启发吧。有任何问题请及时与我联系^_^。程序下载地址&#xff1a;/Files/…

93. Restore IP Addresses

文章目录1 题目理解2 回溯1 题目理解 输入&#xff1a;字符串s 输出&#xff1a;可能的ip地址 规则&#xff1a;一个有效的ip地市是一连串数字&#xff0c;数字范围在0到255&#xff0c;每个数字不能有前导0。例如"0.1.2.201" and "192.168.1.1"是有效ip地…

spring mvc学习(22):/textpath/*/helen

目录结构 web.xml <?xml version"1.0" encoding"UTF-8"?> <web-app xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xmlns"http://java.sun.com/xml/ns/javaee" xsi:schemaLocation"http://java.sun.com/xml…

131. Palindrome Partitioning

文章目录1 题目理解2 回溯3 动态规划1 题目理解 输入&#xff1a;字符串s 规则&#xff1a;将字符串s分割&#xff0c;分割后每一个部分都是一个回文串。 输出&#xff1a;所有的分割方式 Example 1: Input: s “aab” Output: [[“a”,“a”,“b”],[“aa”,“b”]] Examp…

4 文件操作 支持图片 视频 mp3 文本等

#文件操作:send_file,支持图片 视频 mp3 文本等app.route("/img")def img(): return send_file("1.jpg")转载于:https://www.cnblogs.com/ajaxa/p/11156483.html

我的博客开张了!!!

留个脚印,嘻嘻! 转载于:https://www.cnblogs.com/stu-acer/archive/2006/04/26/385453.html

第一百零五期:5年前,跳槽涨薪,你笑了,5年后,跳槽降薪,你慌了!

去年&#xff0c;我在年度绩效面谈中与某中年技术男就 “从测试转向产品经理” 的这个话题上进行了一些探讨与分析。 作者&#xff1a;王晔倞 图片来自 Pexels 或许是因为分析的角度比较客观、真实&#xff0c;再加上俩人都比较会演戏&#xff0c;我激情&#xff0c;他投入&a…

241. Different Ways to Add Parentheses

文章目录1 题目理解2 分治法1 题目理解 输入&#xff1a;字符串input&#xff0c;包含数字和操作符 规则&#xff1a;给input的不同位置加括号&#xff0c;使得input可以得到不同的计算结果。 输出&#xff1a;返回可能的计算结果 Example 1: Input: “2-1-1” Output: [0, 2…

第一百零六期:长相不讨AI喜欢面试就会挂?全球百万求职者经历AI“看脸”面试

AI不仅会筛选你的简历&#xff0c;还会通过看脸决定你能否通过面试。这不是将来时。全球已有超过一百万求职者&#xff0c;经历过AI面试官的冷酷“凝视”。 作者&#xff1a;鱼羊 本文经AI新媒体量子位&#xff08;公众号ID:QbitAI&#xff09;授权转载&#xff0c;转载请联系…

最近比较忙

最近项目真是忙的可以不过还好前几天没事搞了个电影小偷,闲下来看看电影真是不错站在这里要的回下就可以了http://www.ve99.com 转载于:https://www.cnblogs.com/flashicp/archive/2006/04/29/388972.html

服务器控件HtmlTable下控件赋值问题

在程序开发过程中&#xff0c;碰到这样的问题&#xff1a; 1<table>2<tr>3<td><asp:DropDownList iddropdownlist1 runatserver></td>4</tr>5</table>在基类页中有如下代码&#xff1a;1foreach(Control pagectl inPage.Controls[1]…

Foundry feats. MultiverseStudio

https://www.foundry.com/news-awards/foundry-jcube-announcement 经过这么多年的过程&#xff0c;本周本产品终于发布了PR&#xff0c;这次是由Foundry独家代理销售。 目前本产品已经在全球第一线的工作室的流程内使用&#xff0c;用来装配无法想象巨大的场景&#xff0c;如果…

842. Split Array into Fibonacci Sequence

文章目录1 题目理解2 回溯1 题目理解 输入&#xff1a;一个数字字符串S。例如S“123456579”。 规则&#xff1a;我们可以把这个字符串分割为菲波那切数列&#xff0c;例如&#xff1a;[123, 456, 579]。 一个菲波那切数列需要符合以下条件&#xff1a; 1 0<F[i]<231−1…

第一百零七期:她说,嫁人就选程序员!

又是一年双十一&#xff0c;单身狗们还好吗?想脱单?找个程序猿/程序媛是不错的选择&#xff0c;要不要了解一下? 作者&#xff1a;李二狗 图片来自 Pexels 程序员&#xff0c;已经渐渐成当代相亲市场的一只主力军。甚至可以说是“香饽饽”。 越来越多的妹子&#xff0c;在…

第一百零八期:比较容易理解的Hbase架构全解,10分钟学会,建议收藏

依然是Hadoop组件的讲解&#xff0c;今天说到HBase 架构&#xff0c;都是一字一句打出来的&#xff0c;希望各位转发加关注&#xff0c;会一直给大家写优质的内容。 作者&#xff1a;IT技术管理那些事儿 依然是Hadoop组件的讲解&#xff0c;今天说到HBase 架构&#xff0c;都…

Surface 系统恢复

Surface Pro 6超详细教程之下载Surface 系统恢复镜像并制作系统恢复U盘 https://www.jianshu.com/p/d1b41d913f91 怎样创建Windows 10系统恢复驱动器(U盘) https://jingyan.baidu.com/article/63f236286bd7c90208ab3dd7.html Surface Pro 6超详细教程之恢复Surface Pro6 window…

在Matlab2006a中如何创建.net组件

在Matlab2006a中如何创建.net组件 为了创建一个.NET组件&#xff0c;你必须首先写一个M-Code&#xff08;或者使用已存在的代码&#xff09;然后在MATLAB Builder for .NET中创建一个工程以打包这些代码. 1、编写、调试、保存Matlab代码以便作为.NET组件的基础 2、当你依然在Ma…

315. Count of Smaller Numbers After Self

文章目录1 题目理解2 暴力解法3 分治法1 题目理解 输入&#xff1a;int[] nums 输出&#xff1a;计数的数组int[] counts 规则&#xff1a;counts[i]表示nums中下标大于i&#xff0c;值小于nums[i]的个数 Example 1: Input: nums [5,2,6,1] Output: [2,1,1,0] Explanation: T…

SQL Server执行计划那些事儿(3)——书签查找

接下来的文章是记录自己曾经的盲点&#xff0c;同时也透漏了自己的发展历程&#xff08;可能发展也算不上&#xff0c;只能说是瞎混&#xff09;。当然&#xff0c;一些盲点也在工作和探究过程中慢慢有些眉目&#xff0c;现在也愿意发扬博客园的奉献精神&#xff0c;拿出来和大…

博客堂怎么连个搜索功能都没有

今天想去博客堂搜索下文章看看&#xff0c;结果找了半天&#xff0c;差点把显示器翻过来看也没找到个搜索的功能。是我真的没找到&#xff0c;还是博客堂觉的搜索功能没必要啊??? 转载于:https://www.cnblogs.com/BearsTaR/archive/2006/06/07/419837.html