【问题标题】:Using the same EAGLContext across different ViewControllers/EAGLViews跨不同的 ViewControllers/EAGLViews 使用相同的 EAGLContext
【发布时间】:2012-01-26 00:12:18
【问题描述】:

我在 EAGLViews 中使用相同的 EAGLContext 时遇到了一些问题。我有两个视图控制器,每个都有一个EAGLView

每个View Controller分配一个新的EAGLContext,并为每个各自的EAGLView创建一个后续的framebuffer/colorbuffer,但是这样很浪费内存资源。

我知道可以通过简单地将不同的帧缓冲区/颜色缓冲区绑定到不同的EAGLViews 来跨 ViewControllers 使用相同的EAGLContext

Using Multiple OpenGL Views And UIKit

但到目前为止我还没有做到这一点。

有什么想法吗?

提前致谢。

【问题讨论】:

    标签: iphone objective-c opengl-es eaglview eaglcontext


    【解决方案1】:

    终于解决了这个问题。

    在我使用的其中一个视图控制器中:

    dispatch_async(openGLESContextQueue, ^{
    
            [(EAGLView *)self.view setFramebuffer];
    
            (...opengl draw code...)
    
            [(EAGLView *)self.view presentFramebuffer];
    
        });
    

    在多线程环境中使用 EAGLContext 时,必须小心防止其他线程同时使用:

    @syncronized(context) { ...opengl drawing here...}
    

    并在将控制权传递给另一个 ViewController(通过 presentViewController:) 之前耗尽当前的 dispatch_queue,使用:

    dispatch_sync(openGLESContextQueue, ^{});
    

    因此,通过使用这两个技巧,我能够在多个视图中只使用一个 EAGLContext。还必须特别注意 EAGLContext 的当前状态。我得到了意想不到的结果,因为在第一个视图中我有:

    glVertexPointer(2, GL_FLOAT, 0, squareVertices);
    glEnableClientState(GL_VERTEX_ARRAY);
    glColorPointer(4, GL_UNSIGNED_BYTE, 0, squareColors);
    glEnableClientState(GL_COLOR_ARRAY);
    

    在第二个视图中,我有完全不同的绘图代码,当然我忘了使用:

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    

    瞧!

    谢谢:)

    【讨论】:

      【解决方案2】:

      EAGLView 实际上不是一个类;它是一系列具有相同名称的类,Apple 倾向于将其放入其示例文件中。因此,就具体修改提出建议是相对困难的。

      我最初的解决方案是创建一个单例类,该类出售一个共享的EAGLContextEAGLContexts 一次只能在一个线程上使用,因此这不一定是一个完整的解决方案,但您想要做什么可能取决于您的程序的语义,并且感觉与您的实际问题不同。

      Xcode 4.1 'OpenGL ES Application' 模板在视图之外创建上下文,而我认为它以前在视图内部,这使事情变得更容易一些。

      【讨论】:

      • 我已经通过委托实现了两个视图控制器之间的 EAGLContext 共享(但也可能是一个单例类),当我执行 presentviewcontroller 以展示第二个视图控制器时一切正常,但是当我回来时到第一个 - 通过驳回 - 这里的任何 opengl 指令都会引发 BAD_ACCESS 异常:(
      • 我什至实现了信号量以确保共享的 EAGLContext 不会同时获得多个访问权限,但这并没有解决问题。有趣的是,在模拟器中一切正常。是不是很奇怪?
      • 你真的在跳线程吗?如果没有,那么信号量就不是必需的——一切都将在主线程上,在正常的运行循环中。可能值得打开僵尸来确认或否认上下文仍然存在。或者使用 retainreleasedeallocautorelease 的实现子类化 EAGLView,除了调用 super 之外什么都不做,然后使用它们作为断点来捕获任何虐待。
      猜你喜欢
      • 1970-01-01
      • 2015-11-27
      • 2021-11-09
      • 1970-01-01
      • 2015-07-30
      • 2020-06-23
      • 2022-09-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多