前言
上一篇介绍了在Android端构建OpenGLES,这一篇介绍在iOS端调用OpenGLES。
步骤
1.创建Xcode工程,链接GLKit.framework
framework
2.将上一篇中创建的GLES文件夹添加到工程
GLES可以看到,大部分代码都可以在Common下用C++实现,Android、iOS用来写平台相关的代码,并封装调用C++的接口。
3.创建GLESViewController继承GLKViewController
GLESViewController.h ↓
#import <GLKit/GLKit.h>
#import "Renderer.h"
@interface GLESViewController : GLKViewController
- (id)initWithView:(UIView*)view;
@end
GLESViewController.mm ↓ 因为包含了C++代码,所以文件名后缀应为mm
#import "GLESViewController.h"
@interface GLESViewController ()
@property (strong, nonatomic) EAGLContext *context;
@end
@implementation GLESViewController
- (id)initWithView:(UIView*)view
{
if (self = [super init]) {
self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
if (!self.context) {
NSLog(@"Failed to create ES context");
}
GLKView *glkView = [[GLKView alloc] initWithFrame:[view bounds] context:self.context];
glkView.drawableDepthFormat = GLKViewDrawableDepthFormat24;
glkView.userInteractionEnabled = YES; //启用视图交互
glkView.multipleTouchEnabled = YES; //启用多点触摸
glkView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.view = glkView;
self.preferredFramesPerSecond = 60;
float scale = [[UIScreen mainScreen] scale];
//NSLog(@"scale: %f", scale);
[EAGLContext setCurrentContext:self.context];
surfaceCreated();
surfaceChanged([view bounds].size.width * scale, [view bounds].size.height * scale);
[view addSubview:self.view];
}
return self;
}
- (void)viewWillLayoutSubviews {
//NSLog(@"view bounds: %@", NSStringFromCGRect([self.view bounds]));
float scale = [[UIScreen mainScreen] scale];
surfaceChanged([self.view bounds].size.width * scale, [self.view bounds].size.height * scale);
}
- (void)dealloc
{
if ([EAGLContext currentContext] == self.context) {
[EAGLContext setCurrentContext:nil];
}
}
#pragma mark - GLKView and GLKViewController delegate methods
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
drawFrame();
}
@end
这里的initWithView相当于Android GLSurfaceView的onSurfaceCreated,
viewWillLayoutSubviews相当于onSurfaceChanged,
drawInRect相当于onDrawFrame,还是很容易理解的。
4.显示GLES视图
这里我还是按Android端的习惯,把GLESView添加为一个UIView的子视图,这个在initWithView函数中完成了,还要把GLESViewController添加为当前ViewController的子视图控制器,否则drawInRect只会在初始化时调用一次,不会每帧调用。
ViewController.m ↓
#import "ViewController.h"
#import "GLESViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIView *showView;
@property (strong, nonatomic) GLESViewController *glesViewController;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 创建GLES视图并添加
self.glesViewController = [[GLESViewController alloc] initWithView:self.showView];
[self addChildViewController:self.glesViewController];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
iOS运行结果
后记
- Demo工程下载
网友评论