2016-11-19 2 views
0

Похоже, что что-то сломалось в macOS 10.12 при прохождении NSOpenGLPFAColorFloat в качестве одного из параметров при создании NSOpenGLPixelFormat. Мы в основном пытаемся следовать образцу кода Apple Deep Image Display with OpenGL, чтобы отображать на экране широкоэкранные изображения на дисплеях, поддерживающих 30-битный цвет (10 бит для каждого цветового канала RGB).NSOpenGLPFAColorFloat сломанный в macOS 10.12 (Sierra) для рендеринга широкого диапазона (30 бит)?

Это включает в себя создание NSOpenGLPixelFormat с NSOpenGLPFAColorSize набором до 64 (то есть 64 бит на пиксель RGBA) и NSOpenGLPFAColorFloat поддержку (то есть 16-битовых половины поплавкового суб-пикселями). Затем вы используете этот формат пикселей для создания NSOpenGLContext, который использует 16-битовые значения с половинным поплавком для каждого подпикселя, то есть 64 бит для каждого пикселя RGBA.

Все это работало в macOS 10.11. Тем не менее, до 10.12 все наше окно OpenGL оказывается выцветшим, как если бы оно смешивалось с серой или белой рамкой. Вот как это выглядит - обратите внимание, что в строке заголовка окна правильно оказывается темно-серый, но все ниже, что (с нашей точки зрения OpenGL) утрачен:

10,12 (Faded)

10.12 (Faded)

10,11 (Correct)

enter image description here

Я проверил, что наш OpenGL рендеринг является правильным. Если я использую glReadPixels(), чтобы прочитать содержимое буфера кадра после рендеринга, то содержимое буфера кадра будет правильным - содержимое не будет выцветано, и они содержат правильный «глубокий» (более 8 бит на субпиксельный) цвет данные. Похотливое рендеринг, похоже, происходит где-то вне нашего приложения, возможно, с помощью компоновщика окон или чего-то еще. Таким образом, это ошибка macOS 10.12, или мы ничего не делаем правильно при настройке NSWindow, NSView или CAOpenGLLayer.

Образец приложения Apple Deep Image Display with OpenGL выглядит нормально, на 10.12. Однако есть несколько различий между тем, как это работает и как работает наше приложение. Наш формат пикселей немного отличается:

NSOpenGLPixelFormatAttribute attrs[] = { 
    NSOpenGLPFANoRecovery, 
    NSOpenGLPFAColorSize, 64, 
    NSOpenGLPFAColorFloat, 
    NSOpenGLPFADepthSize, 16, 
    NSOpenGLPFAAccelerated, 
    0 
}; 

Основное отличие заключается в том, что образец компании Apple использует NSOpenGLProfileVersion4_1Core и мы используем NSOpenGLProfileVersionLegacy (по умолчанию, если не указан профиль). Таким образом, возможно, что он работает для профилей 4.1 Core, но не для устаревших профилей (Pre-OpenGL 3.0).

Другим отличием является то, что образец от Apple использует подкласс NSOpenGLView в то время как мы используем подкласс NSView с подклассом CAOpenGLLayer, где мы делаем рендеринга OpenGL. Я подозреваю, что проблема может быть с CAOpenGLLayer, но я действительно не знаю.

Существуют различные свойства на NSWindow, NSView и CAOpenGLLayer, которые вы можете установить, которые относятся к широкому спектру изображения. Но до сих пор ни один из них не имел никакого эффекта.Свойства, которые я пытался до сих пор:

  • NSWindow.depthLimit = NSWindowDepthSixtyfourBitRGB
  • NSView.wantsExtendedDynamicRangeOpenGLSurface = YES
  • CAOpenGLLayer.wantsExtendedDynamicRangeContent = YES
  • CALayer.contentsFormat = kCAContentsFormatRGBA16Float

Я довольно много перепробовал все, что я могу думать в этот момент. Если у кого есть какие-либо советы или предложения, я бы очень их оценил.

+0

В моем текущем кодовом пространстве требуется основной профиль, поэтому я не могу легко воспроизвести настройки прямо сейчас, но одна вещь, которая наводит меня немного странно на ваш формат пикселей, - это использование 16 бит для буфера глубины. Мне интересно, если бы вы случайно путали глубину цвета с глубиной буфера Z, так как 16-битный буфер Z считается древним в наши дни. Я понимаю, что это не связано с обработкой цветового пространства вообще, но возможно, вы получите из-за этого нечетный формат пикселей. – Falken

+0

@Falken, я могу просто прокомментировать строку 'NSOpenGLPFADepthSize' или установить 32 вместо 16 и получить тот же результат. Я также пробовал использовать те же параметры формата пикселей, что и в образце [Deep Image Display with OpenGL] (https://developer.apple.com/library/prerelease/content/samplecode/DeepImageDisplayWithOpenGL/Introduction/Intro.html) образца (минус использование 'NSOpenGLProfileVersion4_1Core') и получить тот же результат. Единственный параметр, который, по-видимому, изменяет поведение, - это когда включен NSOpenGLPFAColorFloat. – Cutterpillow

+0

Ах, все равно, это был выстрел в темноте. :) Извините, у меня сейчас нет других идей. – Falken

ответ

0

Попытайтесь проверить colorspaceCAOpenGLLayer и окно.

Если они не подходят для широкой гаммы, попробуйте изменить их. Если окно хорошее, а слой - нет, лучше всего установить, чтобы слой соответствовал окну (т. Е. layer.colorspace = window.colorspace.CGColorSpace;).

Или вы могли бы просто попробовать установить слой, чтобы CGColorSpaceCreateWithName() с именем kCGColorSpaceSRGB, kCGColorSpaceExtendedSRGB, kCGColorSpaceLinearSRGB, kCGColorSpaceExtendedLinearSRGB или kCGColorSpaceDisplayP3, чтобы увидеть, если какой-либо помогает.

+0

Интересно, что это действительно работает, но меня это беспокоит. Цветовое пространство слоя по умолчанию равно NULL, которое в соответствии с документами: _... ** Если nil, то не происходит colormatching. ** Если non-nil, отображаемый контент будет сопоставлен с цветовым пространством контекста, содержащего этот слой (обычно цветовое пространство дисплея) ._ Мы не хотим, чтобы совпадение цветов на слое соответствовало нашему цвету. Установка цветового пространства для соответствия средств окна, что не должно быть никакого соответствия цветов в любом случае, так что надеюсь, что это спорный вопрос. Но это похоже на возможную ошибку ColorSync? – Cutterpillow

Смежные вопросы