GLKit中的GLKViewController控制GLKView实现手动控制glkView:drawInRect

一、简单介绍

在ios平台下,苹果给我们封装好了GLKViewController这样的一个类,简化了我们通过OpenGL ES渲染图形的工作。在这里就简单的介绍在如何通过手动调用GLKView的display方法去控制glkView:drawInRect的调用。

先来看下一个GLKViewDelegate的代理方法,我们在使用GLKViewController的时候如果我们没有给GLKView设置代理,那么GLKViewController就会自动成为其的代理。

如果我们在GLKViewController中实现下面的这个代理方法,在GLKViewController中会被自动的调用

官方文档对于这个方法的描述是该方法的语义与drawRect:方法相同,用来绘制view的内容的

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

对于调用这个方法的刷新频率我们是可以设置的,通过GLKViewController的preferredFramesPerSecond属性来设置的

关于preferredFramesPerSecond的描述,官方文档是这么说的

当您的应用程序设置它的首选帧率时,视图控制器会根据屏幕上显示的视图的功能选择一个尽可能接近的帧速率。实际的帧速率通常是屏幕最大刷新速率的一个因素,以提供一致的帧速率。例如,如果屏幕的最大刷新率是每秒60帧,那也是最高帧速率,视图控制器设置为实际帧速率。然而,如果你要求一个较低的帧率,它可能会选择30、20、15或其他一些因素来作为实际帧速率。您的应用程序应该选择一个可以持续维护的帧速率。默认值是每秒30帧。

就比如说如果我们设置了这个属性为1,就会1秒中去调用一次-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect方法

self.preferredFramesPerSecond=1;

二、代码实现控制

其实实现手动控制glkView:drawInRect的调用很简单,其实我们只需要用到几行代码就可以了,比如说GLKViewController中有一个属性,用于控制渲染循环是否暂停。

@property (nonatomic, getter=isPaused) BOOL paused;

所以我们其实可以在glkView:(GLKView *)view drawInRect:(CGRect)rect方法中进行设置

-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
self.paused=YES;
}

然后在一个按钮的点击事件中进行设置其恢复为NO,这样的话就可以进行控制了。

- (IBAction)change:(UIButton *)sender {
self.paused=NO; 
} 

当然我们还可以在button的点击方法中调用GLKView的display方法也是可以的。

- (IBAction)change:(UIButton *)sender {
[view display];
} 

调用display方法就会去立即重新绘制视图的内容。该方法会立即调用您的绘图方法,然后将呈现的图像呈现给屏幕,这个方法会去调用-drawRect:方法,然后在drawRect方法中会去判断delegate有没有实现-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect方法,如果实现了就会去调用。

还有需要注意的是千万不要在绘图方法中去调用display方法,什么是绘图方法,比如说UIView的drawRect:(CGRect)rect方法还有glkView:(GLKView *)view drawInRect:(CGRect)rect。因为会循环调用,循环调用导致崩溃。

通过函数堆栈调用其实我们可以发现display方法中会去调用了glkView:(GLKView *)view drawInRect:(CGRect)rect方法,而且还去调用了setFrameBuffer的方法和setCurrentContext的方法。




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这里是一段简单的 iOS OpenGL 代码,可以在 Xcode 运行: ```objective-c #import <GLKit/GLKit.h> @interface ViewController : GLKViewController @property (nonatomic, strong) EAGLContext *context; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; GLKView *view = (GLKView *)self.view; view.context = self.context; view.drawableDepthFormat = GLKViewDrawableDepthFormat24; [EAGLContext setCurrentContext:self.context]; // 设置 OpenGL 状态 glClearColor(0.0, 0.0, 0.0, 1.0); // 初始化顶点数组和索引数组 GLfloat vertices[] = { -1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 0.0, 1.0, 0.0 }; GLuint indices[] = {0, 1, 2}; // 创建顶点缓冲对象和索引缓冲对象 GLuint vertexBuffer, indexBuffer; glGenBuffers(1, &vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glGenBuffers(1, &indexBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); } - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { glClear(GL_COLOR_BUFFER_BIT); // 启用顶点属性数组 glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, NULL); // 绘制三角形 glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, NULL); // 关闭顶点属性数组 glDisableVertexAttribArray(GLKVertexAttribPosition); } @end ``` 这段代码创建了一个 GLKViewController,用于管理 OpenGL 渲染上下文和视图。在 viewDidLoad 方法,我们创建了一个 OpenGL ES 3.0 的渲染上下文,并将其绑定到 GLKView 上。然后,我们设置了 OpenGL 的状态,包括背景颜色和顶点数组。 在 glkView:drawInRect: 方法,我们清空了颜色缓冲区,启用了顶点属性数组,并绘制了一个三角形。最后,我们关闭了顶点属性数组。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值