NSTextField над NSOpenGLView

Я создал окно с NSOpenGLView, в которое я передаю содержимое openGL.

Я хочу добавить в представление некоторые кнопки и текстовые поля: я могу добавить NSTextFields и NSButtons с помощью конструктора интерфейса (или кода), но они не отображаются.

NSOpenGLView задокументирован как неспособный иметь sub-представления, поэтому я сделал свой собственный CustomGLView, выведя непосредственно из NSView и внедряя код для создания и использования NSOpenGLContext в нем. Но subviews все еще не отображаются: - контекст OpenGL рисует над ними.

В Windows эта проблема не существует: - Windows, используемая для размещения OpenGL, ДОЛЖНА иметь установленные стили WS_CLIPCHILDREN и WS_CHIPSIBLINGS, гарантирующие, что все одноранговые или дочерние дочерние элементы (представления) не будут закрыты поверхностью OpenGL.

Как мне получить представление в виде представлений через NSView, используя чертеж с использованием OpenGL?

Ответ 1

У вас есть 2 варианта:

  • Создайте окно только для текстового поля. Добавить как дочернее окно того, на котором размещено представление OpenGL. Основной недостаток заключается в том, что вам нужно правильно управлять позиционированием, если перемещено изображение Open GL.

  • Настройте иерархию вида следующим образом:

    • Слойное изображение
      • Слой-хостинг, слой которого содержит слой OpenGL
      • Текстовое поле

Ответ 2

Просто вызовите -setWantsLayer:YES в подпунктах NSOpenGLView.

Ответ 3

В OpenGL пока еще не сильно, но я понимаю, что вы можете добиться визуального эффекта subviews с помощью Quartz Extreme, используя образы с поддержкой слоев; однако это может быть проблематично. Поскольку subviews не поддерживаются напрямую, любое решение может быть взломанным.

В самом деле, решение в этой ссылке фактически отображает второе окно, отображаемое на вашем дисплее 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 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

Текст может быть отображен в текстуру - я просто использовал это для проекта, много искал пример кода и в конечном итоге нашел демонстрационный код Apple GLString, который был абсолютной практикой:

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

Я не пробовал добавлять кнопки, но вы можете, конечно, нарисовать свои собственные и сравнить позиции событий click с кнопками...

Ответ 5

NSOpenGLView не может иметь подзаголовки в соответствии с документацией. Даже если вы подклассифицируете NSOpenGLView, это ничего не изменит.

Что вы можете сделать, так это создать NSView, который будет содержать NSOpenGLView и NSTextField. Затем вы перекрываете их в правильном порядке, чтобы сделать одну ничью поверх другой.

Ответ 6

Это было мое решение:

1) Создайте родительский NSView (позвоните ему parentView).

2) Добавьте дочернего элемента NSOpenGLView в parentView.

3) Добавьте дополнительного дочернего элемента NSView в parentView (убедитесь, что это после OpenGLView в иерархии). Вы можете добавить к этому виду дополнительные текстовые поля и т.д.

4) В ViewController для родителя убедитесь, что вы вызываете [parentView setWantsLayer: TRUE]; Я сделал это в - (void) viewWillAppear

Ответ 7

1) NSOpenGLView может иметь подвью. Это может быть даже много.

2) Причина появления некоторых представлений, элементов управления и других элементов в NSOpenGLView вызвана процессом загрузки при запуске приложения. I.Если вы добавите слайдер или текстовое поле выше и в представление содержимого окна, в котором также находится NSOpenGLView, при запуске приложения это текстовое поле, скорее всего, окажется под NSOpenGLView.

Это ошибка Apple. И они знают об этом.

Вы можете легко решить эту проблему даже без добавления подпрограммы NSOpenGLView...

В интерфейсе Builder перетащите, т.е. CustomView в холст (не представление). И установите его так, как вы хотите, с ползунками, текстом, а что нет. Затем создайте розетку (Call it i.e topView) в вашем контроллере просмотра. Тогда где-то в вашем коде... Возможно (applicationDidFinishLaunching) добавить эту строку...

[_ window.contentView addSubview: _topView]; (Сделайте свое позиционирование и расположение) Это будет делать то же самое, что если бы вы перетащили его в contentView самостоятельно внутри IB. Только он будет рисовать черную вещь в правильной позиции Z.

Вы освобождаете ограничения IB таким образом и им приходится вручную

Можно также просто подклассы и CAOpenGLLayer и использовать это как поддерживающий слой внутри обычного NSView. Там тоже правильно рисуется...

Вот способ Apple, желающий это сделать. CALayers - это Godsend;)

Введите следующую строку String ** NSOpenGLLayer ** в поиске и нажмите enter, чтобы добраться туда, где это... NSOpenGLLayer

Надеюсь, это поможет...