在MacOS X上,您只需创建一个NSView
然后在其上调用NSOpenGLContext
即可将OpenGL呈现给您选择的任何-setView:
个对象。但是,您只能在任何时候将一个视图与单个OpenGL上下文关联。我的问题是,如果我想在一个窗口内(或可能在两个不同的窗口内)将OpenGL渲染到两个不同的视图,我有两个选择:
创建一个上下文并始终通过每次我想要渲染到另一个视图时适当地调用setView
来更改视图。如果视图位于不同的窗口或不同的屏幕上,这甚至可以工作。
创建两个NSOpenGLContext
个对象,并将一个视图与任一个相关联。这两个上下文可以共享,这意味着大多数资源(如纹理,缓冲区等)都可以在两个视图中使用,而不会浪费两倍的内存。但是,在这种情况下,每次我想要渲染到另一个视图时,我必须通过在进行任何OpenGL调用之前在正确的上下文中调用-makeCurrentContext
来继续切换当前上下文。
我实际上在过去使用过任何一个选项,每个选项都可以满足我的需求,但是,我问自己,在性能,兼容性等方面哪种方式更好。我读到上下文切换实际上非常慢,或者至少过去曾经非常慢,可能同时发生了变化。它可能取决于与上下文(例如资源)相关联的数据量,因为切换活动上下文可能会导致数据在系统内存和GPU内存之间传输。
另一方面,切换视图也可能非常慢,特别是如果这可能导致底层渲染器发生变化;例如如果您的两个视图是位于由两个不同图形适配器驱动的两个不同屏幕上的两个不同窗口的一部分。即使渲染器没有改变,我也不知道在切换视图时系统是否执行了大量昂贵的OpenGL设置/清理,例如创建/销毁渲染/帧缓冲对象。
答案 0 :(得分:4)
我研究了Lion上3个窗口之间的上下文切换,我尝试通过一个有点误用的VTK库来解决一些性能问题,这个库本身非常慢。
你切换渲染上下文或者窗口并不重要, 因为总是有一些开销使得它们都作为三元组流向调用线程。我测量每个交换机大约50ms,其中一些OS / Window管理器开销也是如此。这种开销也很大程度上取决于其他GL调用的安排,因为驱动程序可能被迫等待命令完成,这可以通过阻止调用glFinish()手动实现。
我工作的最有效的设置类似于你的第二个,但有两个专用渲染线程,它们的渲染上下文(共享)和窗口永久绑定。上述上下文切换/绑定只在init上完成一次。
可以使用一些线程来控制线程,例如公共屏障,这样两个线程都可以同步渲染单个帧(在它们再次启动之前,它们都会在屏障处停滞)。数据处理也必须是互锁的,这可以在一个线程中完成,同时停止其他渲染线程。