11

我制作了一个带有 NSOpenGLView 的窗口,我正在将 openGL 内容渲染到该窗口中。

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

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

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

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

4

7 回答 7

6

只需调用-setWantsLayer:YESNSOpenGLView 的子视图。

于 2012-05-04T11:46:26.780 回答
6

您有 2 个选择:

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

  2. 像这样设置视图层次结构:

    • 支持层视图
      • 图层托管视图,其图层包含 OpenGL 图层
      • 文本域
于 2010-02-09T12:54:12.180 回答
1

我还没有深入了解 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];

同样,我没有对此进行测试,但看起来它会给你带来你想要的视觉效果。

于 2010-02-08T12:29:39.997 回答
1

根据文档, NSOpenGLView不能有子视图。即使您将 NSOpenGLView 子类化,也不会改变任何内容。

你可以做的是创建一个 NSView 来保存 NSOpenGLView 和 NSTextField。然后,您以正确的顺序将它们重叠,以使一个绘制在另一个之上。

于 2010-02-08T12:28:07.600 回答
1

文本可以渲染成纹理——我只是将它用于一个项目,做了很多寻找示例代码,最终找到了 Apple 的 GLString 演示代码,这是一个绝对的操作方法宝库:

http://developer.apple.com/library/mac/#samplecode/CocoaGL/Listings/GLString_m.html

我没有尝试添加按钮,但是您当然可以自己绘制并将点击事件的位置与按钮的位置进行比较......

于 2011-03-07T01:28:09.517 回答
1

1) NSOpenGLView可以有一个子视图。它甚至可以有很多。

2)一些视图、控件和其他元素被NSOpenGLView欺负的原因是由于应用程序启动时的加载过程。即,如果您在 NSOpenGLView 所在的窗口的内容视图上方添加一个滑块或文本字段,则在应用程序启动时,该文本字段很可能会在 NSOpenGLView 下方结束。

这是一个苹果错误。他们知道这件事。

即使不向 NSOpenGLView 添加子视图,您也可以很容易地解决它...

在 Interface Builder 中,将 CustomView 拖入画布(不是视图)。并使用滑块、文本等按您想要的方式设置它。然后在您的视图控制器中创建一个插座(称之为 topView)。然后在你的代码中的某个地方......也许(applicationDidFinishLaunching)添加这一行......

[_window.contentView addSubview:_topView]; (做你的定位和布局)这将做完全相同的事情,就好像你在 IB 中自己将它拖到 contentView 中一样。只有它会在正确的 Z 位置绘制该死的东西。

您以这种方式放松了 IB 的约束,必须手动进行

也可以只是子类和 CAOpenGLLayer 并将其用作常规 NSView 内的支持层。那里也正确绘制...

这是苹果想要做到这一点的方式。CALayers 是天赐之物;)

在搜索中输入以下字符串 ** NSOpenGLLayer** 并按 Enter 以到达它所在的位置... NSOpenGLLayer

希望这可以帮助....

于 2017-01-30T23:19:15.843 回答
1

这是我的解决方案:

1)创建一个父 NSView (我们称之为parentView)。

2)将 NSOpenGLView Child 添加到parentView

3)添加一个额外的 NSView Child 到parentView(确保这是在层次结构中的 OpenGLView 之后)。您可以在此视图中添加额外的 TextField 等。

4) 在父视图控制器中确保调用 [parentView setWantsLayer: TRUE]; 我在-(void) viewWillAppear内做了这个

于 2016-05-22T13:57:28.340 回答