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感兴趣,但是却毫无图形学基础的,可以看看LearnOpenGL教程

思考题

  • 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
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

最新文章

  1. 用c的数组简单的模拟了入栈
  2. JPHP最新进展 v0.6
  3. Expression Blend4经验分享:文字公告无缝循环滚动效果
  4. JavaScript中判断对象类型方法大全2
  5. loj 1037(状压dp)
  6. ok6410内存初始化
  7. QR二维码(转)
  8. 【转】Netty那点事(一)概述
  9. org/hamcrest/SelfDescribing
  10. 2015第15周六Java线程池
  11. RBF径向基神经网络——乳腺癌医学诊断建模
  12. OAuth的一个.NET开源实现
  13. Mocking framework
  14. Python学习入门基础教程(learning Python)--2.3.3Python函数型参详解
  15. 在 Windows 上测试 Redis Cluster的集群填坑笔记
  16. spring(二) AOP之AspectJ框架的使用
  17. 腾迅云CDN的使用
  18. 设计模式之解释器模式——Java语言描述
  19. 关于Ajax的认识和封装(小记)
  20. git stash pop 冲突,git stash list 中的记录不会自动删除的解决方法

热门文章

  1. PHP 使用header函数设置HTTP头的示例方法 表头 (xlsx下载)
  2. What is Gensim?
  3. traceroute 排查 nginx 反向代理 配置
  4. hmm前后向算法
  5. PHP使用 zip 扩展压缩文件
  6. extjs分页
  7. javascript php 数组 json 对比 总结
  8. Mirror--如何在主库上增加文件
  9. 014-Spring Boot web【三】拦截器HandlerInterceptor、异常处理页面,全局异常处理ControllerAdvice
  10. PAT 1040 Longest Symmetric String[dp][难]