NSTextField超过NSOpenGLView

时间:2010-02-08 12:16:05

标签: cocoa opengl nsopenglview

我创建了一个带有NSOpenGLView的窗口,我正在将OpenGL内容呈现为。

我想在视图中添加一些按钮和文本字段:我可以使用界面构建器(或代码)添加NSTextFields和NSButton,但它们不会出现。

NSOpenGLView被记录为无法拥有子视图,因此我通过直接从NSView派生并实现代码来创建和使用NSOpenGLContext来创建自己的CustomGLView。但是子视图仍然没有出现: - OpenGL上下文描绘了它们。

在Windows上,这个问题不存在: - 用于托管OpenGL的Windows必须设置WS_CLIPCHILDRENWS_CHIPSIBLINGS样式,以确保任何对等体或子子节点(视图)不会被遮挡。 OpenGL表面。

如何在使用OpenGL绘制的NSView上显示子视图?

7 个答案:

答案 0 :(得分:6)

您有两个选择:

  1. 仅为文本字段创建一个窗口。添加为托管OpenGL视图的窗口的子窗口。主要的缺点是,如果移动Open GL视图,您必须正确管理它。

  2. 设置视图层次结构如下:

    • Layer- 支持视图
      • 图层<托管视图,其图层包含OpenGL图层
      • 文字字段

答案 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

希望这会有所帮助......