博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
iOS开发-OpenGL ES入门教程1
阅读量:5912 次
发布时间:2019-06-19

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

http://www.jianshu.com/p/750fde1d8b6a

这里是一篇新手教程,环境是Xcode7+OpenGL ES 2.0,目标写一个OpenGL ES的hello world

OpenGL ES系列教程在。
OpenGL ES系列教程的

你的star和fork是我的源动力,你的意见能让我走得更远

核心思路

通过GLKit,尽量简单地实现把一张图片绘制到屏幕。

效果展示

 

具体细节

1、新建OpenGL ES上下文

- (void)setupConfig {    //新建OpenGLES 上下文    self.mContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; //2.0,还有1.0和3.0    GLKView* view = (GLKView *)self.view; //storyboard记得添加    view.context = self.mContext;    view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;  //颜色缓冲区格式    [EAGLContext setCurrentContext:self.mContext];}

GLKView* view = (GLKView *)self.view;这里需要在storyboard里面把view的类设置成GLKView,其他代码是OpenGL ES上下文的创建。

2、顶点数组和索引数组

//顶点数据,前三个是顶点坐标,后面两个是纹理坐标    GLfloat squareVertexData[] =    {        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, //左下    };

顶点数组里包括顶点坐标,OpenGLES的世界坐标系是[-1, 1],故而点(0, 0)是在屏幕的正中间

纹理坐标系的取值范围是[0, 1],原点是在左下角。故而点(0, 0)在左下角,点(1, 1)在右上角。
索引数组是顶点数组的索引,把squareVertexData数组看成4个顶点,每个顶点会有5个GLfloat数据,索引从0开始。

3、顶点数据缓存

//顶点数据缓存    GLuint buffer;    glGenBuffers(1, &buffer);    glBindBuffer(GL_ARRAY_BUFFER, buffer);    glBufferData(GL_ARRAY_BUFFER, sizeof(squareVertexData), squareVertexData, 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);

这是本章节的核心内容

  • glGenBuffers申请一个标识符
  • glBindBuffer把标识符绑定到GL_ARRAY_BUFFER
  • glBufferData把顶点数据从cpu内存复制到gpu内存
  • glEnableVertexAttribArray 是开启对应的顶点属性
  • glVertexAttribPointer设置合适的格式从buffer里面读取数据

4、纹理贴图

- (void)uploadTexture {    //纹理贴图    NSString* filePath = [[NSBundle mainBundle] pathForResource:@"for_test" ofType:@"jpg"];    NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:@(1), GLKTextureLoaderOriginBottomLeft, nil];//GLKTextureLoaderOriginBottomLeft 纹理坐标系是相反的    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;}
  • GLKTextureLoader读取图片,创建纹理GLKTextureInfo
  • 创建着色器GLKBaseEffect,把纹理赋值给着色器

基础

代码带了很多注释,百度下相应的概念,会有更多解释。

如果对OpengGL ES感兴趣,但是却毫无图形学基础的,可以看看。

思考题

  • 1、代码中有6个顶点坐标,能否使用更少的顶点显示一个图像?
  • 2、顶点缓存数组可以不用glBufferData,要如何实现?
  • 3、如果把这个图变成左右两只对称的熊猫,该如何改?

可以下载demo代码。

思考题答案

思考题1:

可以使用四个顶点,绘制2个三角形 的6个顶点中有2个是重复的,使用索引可以减少重复。

思考题2:

顶点缓存数组可以不用glBufferData,要如何实现?顶点数组可以通过glBufferData放入缓存,也可以直接通过glVertexAttribPointer最后一个参数,直接把顶点数组从CPU传送到GPU。区别:glBufferData里面的顶点缓存可以复用,glVertexAttribPointer是每次都会把顶点数组从CPU发送到GPU,影响性能。

思考题3

如果把这个图变成左右两只对称的熊猫,该如何改?把屏幕切分成4个三角形,左边两个三角形同上,右边两个三角形的纹理坐标的x值调整即可。

作者:落影loyinglin 链接:http://www.jianshu.com/p/750fde1d8b6a 來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
你可能感兴趣的文章
基于MaxCompute打造轻盈的人人车移动端数据平台
查看>>
突然有一个时刻想过静静,我知道你是谁。
查看>>
第二周总结
查看>>
Dojo 表单校验
查看>>
如何让一个矩形外围为同一个数
查看>>
struts2上传文件,文件大小默认最大值的修改
查看>>
DHCP服务器的作用
查看>>
SQLmap工具介绍及其使用
查看>>
Objective-C 学习资源收集
查看>>
关于WMI对象 Get-WmiObject
查看>>
LDAP快速入门
查看>>
Oracle数据库 ORA-28000 错误处理方式
查看>>
keepalived工作原理和配置说明
查看>>
什么是wall-clock time
查看>>
LINUX说细启动顺序解述
查看>>
shell练习-远程监控
查看>>
Apache不记录指定文件类型
查看>>
Cacti 无法启用气象图和气象图中图标添加
查看>>
Mysqlbackup 3.9.0 企业级备份工具详解
查看>>
自动化实现之Jenkins+TestNG+TestLink
查看>>