创建OpenGL ES 项目

  1. 创建iOS工程


    创建iOS工程
  2. 更改Main.storyBoard中view为GLKView


    更改Main.storyBoard中view为GLKView
  3. ViewController.h中导入GLKit框架,将ViewController的继承父类改为GLKViewController

#import <UIKit/UIKit.h>
#import <GLKit/GLKit.h>

@interface ViewController : GLKViewController

@end
  • GLKViewController内部实现
// GLKViewController继承于UIViewController,可以使用UIViewController的所有属性和方法
@interface GLKViewController : UIViewController <NSCoding, GLKViewDelegate>
{
    
}

// 提供了更新Update和暂停Pause的代理方法
@property (nullable, nonatomic, assign) IBOutlet id <GLKViewControllerDelegate> delegate;

/*
 For setting the desired frames per second at which the update and drawing will take place.
 The default is 30.
帧之间切换的速率,默认30帧/秒
 */
@property (nonatomic) NSInteger preferredFramesPerSecond;

/*
 The actual frames per second that was decided upon given the value for preferredFramesPerSecond
 and the screen for which the GLKView resides. The value chosen will be as close to
 preferredFramesPerSecond as possible, without exceeding the screen's refresh rate. This value
 does not account for dropped frames, so it is not a measurement of your statistical frames per
 second. It is the static value for which updates will take place.
 */
@property (nonatomic, readonly) NSInteger framesPerSecond;

/*
 Used to pause and resume the controller.
 */
@property (nonatomic, getter=isPaused) BOOL paused;

/*
 The total number of frames displayed since drawing began.
视图控制器自创建以来发送的帧更新数
 */
@property (nonatomic, readonly) NSInteger framesDisplayed;

/*
 Time interval since properties.
timeSinceFirstResume 自视图控制器第一次恢复发送更新事件以来经过的时间量
timeSinceLastResume 自上次视图控制器恢复发送更新事件以来更新的时间量
timeSinceLaseUpdate 自上次视图控制器调用委托方法以及经过的时间量
timeSinceLastDraw 自上次视图控制器调用视图display方法以来经过的时间量
 */
@property (nonatomic, readonly) NSTimeInterval timeSinceFirstResume;
@property (nonatomic, readonly) NSTimeInterval timeSinceLastResume;
@property (nonatomic, readonly) NSTimeInterval timeSinceLastUpdate;
@property (nonatomic, readonly) NSTimeInterval timeSinceLastDraw;

/*
 If true, the controller will pause when the application recevies a willResignActive notification.
 If false, the controller will not pause and it is expected that some other mechanism will pause
 the controller when necessary.
 The default is true.
 */
@property (nonatomic) BOOL pauseOnWillResignActive;

/*
 If true, the controller will resume when the application recevies a didBecomeActive notification.
 If false, the controller will not resume and it is expected that some other mechanism will resume
 the controller when necessary.
 The default is true.
 */
@property (nonatomic) BOOL resumeOnDidBecomeActive;

@end

#pragma mark -
#pragma mark GLKViewControllerDelegate
#pragma mark -

@protocol GLKViewControllerDelegate <NSObject>

@required
/*
 Required method for implementing GLKViewControllerDelegate. This update method variant should be used
 when not subclassing GLKViewController. This method will not be called if the GLKViewController object
 has been subclassed and implements -(void)update.
更新视图内容,在显示每个帧之前调用
 */
- (void)glkViewControllerUpdate:(GLKViewController *)controller;

@optional
/*
 Delegate method that gets called when the pause state changes. 
在渲染循环暂停或恢复之前调用
 */
- (void)glkViewController:(GLKViewController *)controller willPause:(BOOL)pause;

@end
  1. ViewController.m中导入OpenGLES,创建上下文并设置为当前上下文,获取GLKView设置背景颜色,代理里清除颜色缓冲区
#import "ViewController.h"
#import <OpenGLES/ES3/gl.h>
#import <OpenGLES/ES3/glext.h>

@interface ViewController ()
{
    EAGLContext *context; //上下文,管理OpenGL ES 状态
}

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    //1. 初始化上下文
    context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
    if (!context) {
        NSLog(@"Create ES context failed.");
    }
    
    //2. 设置上下文
    [EAGLContext setCurrentContext:context];
    
    //3. 获取GLKView
    GLKView *view = (GLKView *)self.view;
    view.context = context;
    
    //4. 设置背景颜色
    glClearColor(0.5, 0, 0, 1);
}

#pragma mark - GLKViewDelegate
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    glClear(GL_COLOR_BUFFER_BIT);
}

@end
  • EAGLContext内部实现
@interface EAGLContext : NSObject 
{
@public
    struct _EAGLContextPrivate *_private;
}

// 初始化
- (nullable instancetype) init NS_UNAVAILABLE;
- (nullable instancetype) initWithAPI:(EAGLRenderingAPI) api;
- (nullable instancetype) initWithAPI:(EAGLRenderingAPI) api sharegroup:(EAGLSharegroup*) sharegroup NS_DESIGNATED_INITIALIZER;

// 设置当前上下文
+ (BOOL)                     setCurrentContext:(nullable EAGLContext*) context;
// 获取当前上下文
+ (nullable EAGLContext*)    currentContext;

@property (readonly)          EAGLRenderingAPI   API;
@property (nonnull, readonly) EAGLSharegroup*    sharegroup;

@property (nullable, copy, nonatomic) NSString* debugLabel NS_AVAILABLE_IOS(6_0);
@property (getter=isMultiThreaded, nonatomic) BOOL multiThreaded NS_AVAILABLE_IOS(7_1);
@end
  • GLKView内部实现
@interface GLKView : UIView <NSCoding>
{

}
// 初始化视图
- (instancetype)initWithFrame:(CGRect)frame context:(EAGLContext *)context;

@property (nullable, nonatomic, assign) IBOutlet id <GLKViewDelegate> delegate;

@property (nonatomic, retain) EAGLContext *context;

// 绘制对象的宽/高,只读状态
@property (nonatomic, readonly) NSInteger drawableWidth;
@property (nonatomic, readonly) NSInteger drawableHeight;

@property (nonatomic) GLKViewDrawableColorFormat drawableColorFormat; // 颜色缓冲区格式
@property (nonatomic) GLKViewDrawableDepthFormat drawableDepthFormat; // 深度缓冲区格式
@property (nonatomic) GLKViewDrawableStencilFormat drawableStencilFormat; // 模板缓冲区格式
@property (nonatomic) GLKViewDrawableMultisample drawableMultisample; // 多重采样

/*
 Binds the context and drawable. This needs to be called when the currently bound framebuffer
 has been changed during the draw method.
将底层FrameBuffer对象绑定到OpenGL ES
 */
- (void)bindDrawable;

/*
 deleteDrawable is normally invoked by the GLKViewController when an application is backgrounded, etc.
 It is the responsibility of the developer to call deleteDrawable when a GLKViewController isn't being used.
删除视图FrameBuffer对象
 */
- (void)deleteDrawable;

/*
 Returns a UIImage of the resulting draw. Snapshot should never be called from within the draw method.
绘制视图内容并将其作为新图像对象返回
 */
@property (readonly, strong) UIImage *snapshot;

/*
 Controls whether the view responds to setNeedsDisplay. If true, then the view behaves similarily to a UIView.
 When the view has been marked for display, the draw method is called during the next drawing cycle. If false,
 the view's draw method will never be called during the next drawing cycle. It is expected that -display will be
 called directly in this case. enableSetNeedsDisplay is automatically set to false when used in conjunction with
 the GLKViewController. This value is true by default.
设置是否显示
 */
@property (nonatomic) BOOL enableSetNeedsDisplay;

/*
 -display should be called when the view has been set to ignore calls to setNeedsDisplay. This method is used by
 the GLKViewController to invoke the draw method. It can also be used when not using a GLKViewController and custom
 control of the display loop is needed.
立即重绘
 */
- (void)display;

@end

#pragma mark -
#pragma mark GLKViewDelegate
#pragma mark -

@protocol GLKViewDelegate <NSObject>

@required
/*
 Required method for implementing GLKViewDelegate. This draw method variant should be used when not subclassing GLKView.
 This method will not be called if the GLKView object has been subclassed and implements -(void)drawRect:(CGRect)rect.
绘制视图内容
 */
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect;

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

推荐阅读更多精彩内容