我创建了一个带有NSOpenGLView的窗口,我正在将OpenGL内容渲染到其中。
我想在视图中添加一些按钮和文本字段:我可以使用界面构建器(或代码)添加NSTextFields和NSButton,但它们不会出现。
NSOpenGLView被记录为无法拥有子视图,因此我通过直接从NSView派生并实现代码来创建和使用NSOpenGLContext来创建我自己的CustomGLView。但是子视图仍然没有出现: - OpenGL上下文描绘了它们。
在Windows上,这个问题不存在: - 用于托管OpenGL的Windows必须拥有 WS_CLIPCHILDREN
和 WS_CHIPSIBLINGS
样式集确保OpenGL表面不会遮挡任何对等或子子(视图)。
如何在使用OpenGL绘制的NSView上显示子视图?
只需致电 -setWantsLayer:YES
在NSOpenGLView的子视图上。
我还没有深入研究OpenGL,但我的理解是你可以完成视觉效果 影响 Quartz Extreme的子视图使用图层支持的视图;然而,那些可能是 问题。由于不直接支持子视图,因此任何解决方案都可能成为黑客。
实际上,该链接中的解决方案实际上会破坏第二个窗口显示在您的OpenGL显示上,第二个窗口显示您想要的Cocoa视图。
下面的代码(来自上面的链接)是我没有测试的东西(再次不是OpenGL的人 - 但是)看起来像一个相当聪明的方法:
// This is the GL Window and view you already have
glWindow = [[GLWindow alloc] initWithContentRect:windowRect];
glView = [[[GLView alloc] initWithFrame:NSMakeRect(0, 0, windowRect.size.width, windowRect.size.height)] autorelease];
[glView translateOriginToPoint:NSMakePoint(glView.bounds.size.width/2, glView.bounds.size.height/2)];
[glWindow setContentView:glView];
// And here's your transparent UI window
uiWindow = [[TransparentWindow alloc] initWithContentRect:windowRect];
uiView = [[[NSView alloc] initWithFrame:NSMakeRect(0, 0, windowRect.size.width, windowRect.size.height)] autorelease];
[uiView translateOriginToPoint:NSMakePoint(uiView.bounds.size.width/2, uiView.bounds.size.height/2)];
uiView.wantsLayer = YES;
[uiWindow setContentView:uiView];
[glWindow addChildWindow:uiWindow ordered:NSWindowAbove];
同样,我没有对此进行过测试,但看起来它会为您带来您想要的视觉效果。
文本可以渲染成纹理 - 我只是将它用于项目,做了很多寻找示例代码,最终找到了Apple的GLString演示代码,这是一个绝对的方法:
http://developer.apple.com/library/mac/#samplecode/CocoaGL/Listings/GLString_m.html
我没有尝试过添加按钮,但你可以自己绘制并将点击事件的位置与按钮的位置进行比较......
这是我的解决方案:
1)创建父NSView(让我们称之为 parentView)。
2)添加NSOpenGLView子项 parentView。
3)添加一个额外的NSView子项 parentView (确保这是在层次结构中的OpenGLView之后)。您可以向此视图添加其他TextField等。
4)在父控件的ViewController中确保调用[parentView setWantsLayer:TRUE];我这样做了 - (void)viewWillAppear
1)NSOpenGLView 能够 有一个子视图。它甚至可以充足。
2)原因 一些 视图,控件和其他元素被NSOpenGLView欺负是由于应用程序启动时的加载过程。即如果添加滑块或文本字段 以上 并且在NSOpenGLView所在的窗口的内容视图中,在Application-Launch上,文本字段很可能会在NSOpenGLView下面结束。
这是Apple Bug。他们知道这件事。
即使不向NSOpenGLView添加子视图,您也可以轻松解决它...
在Interface Builder中,将CustomView拖动到画布中(不是视图)。并使用滑块,文本和不需要的方式设置它。然后在视图控制器中创建一个插座(称之为topView)。然后你的代码中的某个地方......也许(applicationDidFinishLaunching)添加这一行......
[_window.contentView addSubview:_topView];
(做你的定位和布局)
这将完全相同,就像您在IB内部将其拖入contentView一样。只有它会在正确的Z位置画出令人讨厌的东西。
你以这种方式放松IB的约束并且必须手动操作
也可以只是子类化和CAOpenGLLayer,并将其用作常规NSView内部的后备层。它也被正确绘制了......
这是Apple希望这样做的方式。 CALayers是天赐之物;)
在搜索中输入以下字符串** NSOpenGLLayer **并按Enter键以到达它所在的位置...
NSOpenGLLayer
希望这可以帮助....
NSOpenGLView 根据文档不能有子视图。即使你是NSOpenGLView的子类,也不会改变任何东西。
你可以做的是创建一个NSView,它将同时包含NSOpenGLView和NSTextField。然后,您按正确的顺序重叠它们,以便在另一个上面进行一次绘制。