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
Надеюсь, это поможет...