我创建了一个带有NSOpenGLView的窗口,我正在将OpenGL内容呈现为。
我想在视图中添加一些按钮和文本字段:我可以使用界面构建器(或代码)添加NSTextFields和NSButton,但它们不会出现。
NSOpenGLView被记录为无法拥有子视图,因此我通过直接从NSView派生并实现代码来创建和使用NSOpenGLContext来创建自己的CustomGLView。但是子视图仍然没有出现: - OpenGL上下文描绘了它们。
在Windows上,这个问题不存在: - 用于托管OpenGL的Windows必须设置WS_CLIPCHILDREN
和WS_CHIPSIBLINGS
样式,以确保任何对等体或子子节点(视图)不会被遮挡。 OpenGL表面。
如何在使用OpenGL绘制的NSView上显示子视图?
答案 0 :(得分:6)
您有两个选择:
仅为文本字段创建一个窗口。添加为托管OpenGL视图的窗口的子窗口。主要的缺点是,如果移动Open GL视图,您必须正确管理它。
设置视图层次结构如下:
答案 1 :(得分:5)
只需在NSOpenGLView的子视图上调用-setWantsLayer:YES
。
答案 2 :(得分:1)
NSOpenGLView不能拥有子视图。即使您继承了NSOpenGLView,也不会改变任何内容。
您可以做的是创建一个既包含NSOpenGLView又包含NSTextField的NSView。然后,您按正确的顺序重叠它们,以便在另一个上面进行一次绘制。
答案 3 :(得分:1)
我还没有深入研究OpenGL,但我的理解是你可以使用支持图层的视图使用Quartz Extreme完成子视图的视觉效果;但是,这些可能是problematic。由于不直接支持子视图,任何解决方案都可能是黑客攻击。
实际上,该链接中的解决方案实际上会破坏第二个窗口显示在您的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];
同样,我没有对此进行过测试,但它看起来会让你获得你想要的视觉效果。
答案 4 :(得分:1)
文本可以渲染成纹理 - 我只是将它用于项目,做了很多寻找示例代码,最终找到了Apple的GLString演示代码,这是一个绝对的方法:
http://developer.apple.com/library/mac/#samplecode/CocoaGL/Listings/GLString_m.html
我没有尝试添加按钮,但您当然可以自己绘制并将点击事件的位置与按钮的位置进行比较......
答案 5 :(得分:1)
这是我的解决方案:
1)创建父NSView(让我们称之为 parentView )。
2)将NSOpenGLView子项添加到 parentView 。
3)将另一个NSView子项添加到 parentView (确保它位于层次结构中的OpenGLView之后)。您可以在此视图中添加其他TextField等。
4)在父级的ViewController中确保调用[parentView setWantsLayer:TRUE];我是在 - (void)viewWillAppear
中完成的答案 6 :(得分:1)
1)NSOpenGLView 可以有一个子视图。它甚至可以充足。
2)NSOpenGLView欺负某些视图,控件和其他元素的原因是由于Application启动时的加载过程。即如果您在上面添加滑块或文本字段并进入NSOpenGLView所在窗口的内容视图,则在应用程序启动时,该文本字段很可能会在NSOpenGLView下面结束。
这是Apple Bug。他们知道这件事。
即使不向NSOpenGLView添加子视图,您也可以轻松解决它...
在Interface Builder中将CustomView拖动到画布(不是视图)。并使用滑块,文本和不需要的方式设置它。然后在视图控制器中创建一个插座(称之为topView)。然后在你的代码中的某个地方...也许(applicationDidFinishLaunching)添加这一行......
[_ window.contentView addSubview:_topView]; (做你的定位和布局) 这将完全相同,就像你在IB内部将其拖入contentView一样。只有它会在正确的Z位置画出令人生畏的东西。
你以这种方式放松了IB的限制并且必须手动
也可以只是子类化和CAOpenGLLayer,并将其用作常规NSView内部的后备层。它也被正确绘制......
这是Apple希望这样做的方式。 CALayers是天赐之物;)
在搜索中输入以下字符串** NSOpenGLLayer **并按Enter键以到达它所在的位置... NSOpenGLLayer
希望这会有所帮助......