小编Jeb*_*Jeb的帖子

如何从iOS上的Grand Central Dispatch Queue异步绘制到GLKit的OpenGL ES上下文

我正在尝试将冗长的OpenGL绘制操作移动到GCD队列中,这样我就可以在GPU磨合的同时完成其他工作.我会更愿意倾向于与GCD与增加实际线程我的应用程序来做到这一点.字面上我想做的就是能够

  • 不会阻止glDrawArrays()调用,因此当GL渲染变得非常慢时,UI的其余部分可以保持响应.
  • 当我们还没有完成它们时放下glDrawArrays()调用(不要建立一个只增长和增长的帧队列)

在Apple的网站上,文档说:

GCD和NSOperationQueue对象可以在他们选择的线程上执行您的任务.他们可以专门为该任务创建一个线程,或者他们可以重用现有的线程.但在任何一种情况下,您都无法保证哪个线程执行任务.对于OpenGL ES应用程序,这意味着:

  • 每个任务必须在执行任何OpenGL ES命令之前设置上下文.
  • 访问相同上下文的两个任务可能永远不会同时执行.
  • 每个任务都应该在退出之前清除线程的上下文.

听起来很简单.

为了简化这个问题,我首先介绍了一个新的骨架版Apple模板,它出现在"OpenGL ES"游戏的"New Project"对话框中.当您实例化它,编译并运行时,您应该看到在灰色字段上旋转的两个立方体.

对于该代码,我添加了一个GCD队列.从接口部分开始ViewController.m:

dispatch_queue_t openGLESDrawQueue;
Run Code Online (Sandbox Code Playgroud)

然后将它们设置为ViewController viewDidLoad:

openGLESDrawQueue = dispatch_queue_create("GLDRAWINGQUEUE", NULL);
Run Code Online (Sandbox Code Playgroud)

最后,我对drawInRectCADisplayLink最终触发的方法进行了这些非常小的更改:

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
void (^glDrawBlock)(void) = ^{
    [EAGLContext setCurrentContext:self.context];
    glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindVertexArrayOES(_vertexArray);

    // Render the object with GLKit
    [self.effect prepareToDraw];

    glDrawArrays(GL_TRIANGLES, 0, 36);

    // Render the object again with ES2
    glUseProgram(_program);

    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
    glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);

    glDrawArrays(GL_TRIANGLES, 0, …
Run Code Online (Sandbox Code Playgroud)

opengl-es grand-central-dispatch ios objective-c-blocks

4
推荐指数
1
解决办法
2554
查看次数