iOS OpenGL ES菜鸟学习笔记(1)——画一个简单的三角形

最近工作需要用到OpenGLES,正在好好研究,也把研究的笔记记录下来与大家分享一下。在这里,我不研究如何进行iOS开发,只看OpenGL ES相关的知识。(ps:菜鸟学习笔记,如有不对,大神请指教)

一、使用Xcode新建一个Single View Application

new Project.png

二、导入GLKit.framework,OpenGLES.framework

import framework.png

三、ViewController配置修改

1、在ViewController中导入GLKit;

2、将ViewController改为从GLKViewController继承

ViewController从GLKViewController继承很多 基本功能,如ViewController.view的类型自动变为GLKView(因为GLKViweController的view为GLKView类型),特别地,GLKViewController会自动重新设置OpenGL ES和应用的GLKView实例以响应设备方向的变化并可视化过渡效果,如淡入淡出。

3、在Main.storyboard中将ViewController的view的类型改为GLKView。ViewController与Main.storyboard是关联的,所以我们也需要将Main.storyboard中ViewController的view也设为GLKView类型。

以下为截图:


import GLKit.png
GLKView.png

四、添加属性和变量

@interface ViewController ()
{
    GLuint vertexBufferId;
}

@property (strong, nonatomic) GLKBaseEffect *baseEffect;

@end

GLuint vertextBuffer

此变量用于保存盛放本例即将用到的顶点数据的缓存的OpenGL ES标识符。

GLKBaseEffect *baseEffect

此属性的存在是为了简化OpenGL ES的很多常用操作(好吧,我也不太懂这个)。
GLKBaseEffect隐藏了iOS设备支持的多个OpenGL ES版本之间的差异。在应用中使用GLKBaseEffect能减少代码的数量。

五、创建三角形的顶点数据

// 这个数据类型用于存储每一个顶点数据
typedef struct {
  GLKVector3 positionCoords;
} SceneVertex;

// 创建本例中要用到的三角形顶点数据
const SceneVertex vertices []  = 
{
  {{-0.5, -0.5, 0.0}},  // 左下
  {{ 0.5, -0.5, 0.0}},  // 右下
  {{-0.5,  0.5, 0.0}}  // 左上
};

六、写代码

1、- (void)viewDidLoad

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    GLKView *view = (GLKView *)self.view;
    NSAssert([view isKindOfClass:[GLKView class]], @"ViewController's view is not a GLKView");
    
    
    // 创建一个OpenGL ES 2.0 context(上下文)并将其提供给view
    view.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    
    // 将刚刚创建的context设置为当前context
    [EAGLContext setCurrentContext:view.context];
    
    // 创建一个提供标准OpenGL ES 2.0的GLKBaseEffect
    self.baseEffect = [[GLKBaseEffect alloc] init];
    // 启用Shading Language programs(着色语言程序)
    self.baseEffect.useConstantColor = GL_TRUE;
    // 设置渲染图形用的颜色为白色
    self.baseEffect.constantColor = GLKVector4Make(1.0, 1.0, 1.0, 1.0);
    
    // 设置当前context的背景色为黑色
    glClearColor(0.0, 0.0, 0.0, 1.0);
    
    
    /*
     * glGenBuffers(GLsizei n, GLuint *buffers);
     * 生成缓存,指定缓存数量,并保存在vertexBufferId中
     * 第一个参数:指定要生成的缓存标识符的数量
     * 第二个参数:指针,指向生成的标识符的内存位置(熟悉C和C++的小伙伴应该不陌生了)
     */
    glGenBuffers(1, &vertexBufferId);
    
    /*
     * glBindBuffer(GLenum target, GLuint buffer);
     * 绑定由于指定标识符的缓存到当前缓存
     * 第一个参数:用于指定要绑定哪一类型的内存(GL_ARRAY_BUFFER | GL_ELEMENT_ARRAY_BUFFER),GL_ARRAY_BUFFER用于指定一个顶点属性数组
     * 第二个参数:要绑定魂缓存的标识符
     */
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
    
    /*
     * glBufferData(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage);
     * 复制应用的顶点数据到context所绑定的顶点缓存中
     * 第一个参数:指定要更新当前context中所绑定的是哪一类型的缓存
     * 第二个参数:指定要复制进缓存的字节的数量
     * 第三个参数:要复制的字节的地址
     * 第四个参数:提示缓存在未来的运算中将被怎样使用(GL_STATIC_DRAW | GL_DYNAMIC_DRAW),GL_STATIC_DRAW是指缓存中的内容可以复制到GPU的内存中,因为很少对其进行更改。
     */
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
    
}

2、- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    // 告诉baseEffect准备好当前OpenGL ES的context,马上就要绘画了
    [self.baseEffect prepareToDraw];
    
    // 清除当前绑定的帧缓存的像素颜色渲染缓存中的每一个像素的颜色为前面使用glClearColor函数设置的值
    glClear(GL_COLOR_BUFFER_BIT);
    
    /*
     * glEnableVertexAttribArray(GLuint index)
     * 启动某项缓存的渲染操作(GLKVertexAttribPosition | GLKVertexAttribNormal | GLKVertexAttribTexCoord0 | GLKVertexAttribTexCoord1)
     * GLKVertexAttribPosition 用于顶点数据
     * GLKVertexAttribNormal 用于法线
     * GLKVertexAttribTexCoord0 与 GLKVertexAttribTexCoord1 均为纹理
     */
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    
    /*
     * glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *ptr);
     * 渲染相应数据(此处绘制顶点数据)
     * 第一个参数:当前要绘制的值什么类型的数据,与glEnableVertexAttribArray()相同
     * 第二个参数:每个位置有3个部分
     * 第三个参数:每个部分都保存为一个float值
     * 第四个参数:告诉OpenGL ES小数点固定数据是否可以被改变
     * 第五个参数:“步幅”,即从一个顶点的内存开始位置转到下一个顶点的内存开始位置需要跳过多少字节
     * 第六个参数:告诉OpenGL ES从当前的绑定的顶点缓存的开始位置访问顶点数据
     */
    glVertexAttribPointer(GLKVertexAttribPosition,  // 当前绘制顶点数据
                          3,    // 每个顶点3个值
                          GL_FLOAT, // 数据为float
                          GL_FALSE, // 不需要做任何转化
                          sizeof(SceneVertex),  // 每个顶点之间的内存间隔为sizeof(SceneVertex)
                          NULL); // 偏移量为0,从开始绘制,也可以传0
    
    
    /*
     * glDrawArrays(GLenum mode, GLint first, GLsizei count)
     * 执行绘图操作
     * 第一个参数:告诉GPU如何处理绑定的顶点缓存内的数据
     * 第二个参数:指定缓存内需要渲染的第一个数据(此处为顶点)的位置,0即为从开始绘制
     * 第三个参数:指定缓存内需要渲染的数据(此处为顶点)的数量
     */
    glDrawArrays(GL_TRIANGLES,  // 绘制三角形
                 0, // 从开始绘制
                 3);    // 共3个顶点
}

七、运行

到这里,一个三角形就绘制完成了。好了,我们来看看结果。
command+R,就能看到这样的界面了

没有源码的示例不是一个好示例(更新与2017-04-25) https://github.com/JunesYin/LyOpenGLES/tree/master/LyOpenGLES_01

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,302评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,563评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,433评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,628评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,467评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,354评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,777评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,419评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,725评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,768评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,543评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,387评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,794评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,032评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,305评论 1 252
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,741评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,946评论 2 336

推荐阅读更多精彩内容