#opengl #swift3 #xcode8 #macos-sierra
#opengl #swift3 #xcode8 #macos-sierra
Вопрос:
У меня есть почтенное приложение, которое я перенес из примера кода Apple GLEssentials в obj-c в Swift 2, и теперь я пытаюсь перейти на Swift 3. В его основе лежит NSOpenGLView, основного средства визуализации все еще нет в Swift (я знаю: мне скоро придется стиснуть зубы и перейти на Metal или что-то подобное), но все остальное есть.
В настоящее время в OSX 10.12 с Xcode 8 окно просто пустое. Мне пришлось внести некоторые предложенные компилятором изменения в основной (Swift) класс OpenGLView, чтобы он успешно компилировался и запускался в Swift 3, и я чувствую, что в этом и заключается проблема, поскольку класс рендеринга, похоже, работает нормально; я могу заставить его сообщать о FPS 60и я могу устанавливать точки останова, которые останавливают код в каждом кадре. Мой класс OpenGLView настроен так, как показано ниже, и именно здесь произошло большинство новых изменений в Swift 3:
class BQSOpenGLView: NSOpenGLView {
var m_renderer: OpenGLRenderer = OpenGLRenderer()
var have_setup_renderer: Bool = false
var displayLink: CVDisplayLink?
var has_setup = false
var is_fullscreen: Bool = false
var grid_size: QSGridSize = QSMakeGridSize(1, 1)
var backing_scalar_changed: Bool = false
var backing_scalar: GLfloat = 0.0
override func awakeFromNib() {
backing_scalar = GLfloat((self.window?.backingScaleFactor)!)
NotificationCenter.default.addObserver(self, selector: #selector(BQSOpenGLView.willEnterFullscreen(_:)), name: NSNotification.Name.NSWindowWillEnterFullScreen, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(BQSOpenGLView.willExitFullscreen(_:)), name: NSNotification.Name.NSWindowWillExitFullScreen, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(BQSOpenGLView.backingScaleChange(_:)), name: NSNotification.Name.NSWindowDidChangeBackingProperties, object: nil)
let attributes : [NSOpenGLPixelFormatAttribute] = [
NSOpenGLPixelFormatAttribute(NSOpenGLPFADoubleBuffer),
NSOpenGLPixelFormatAttribute(NSOpenGLPFADepthSize),
NSOpenGLPixelFormatAttribute(24),
NSOpenGLPixelFormatAttribute(NSOpenGLPFASampleBuffers),
NSOpenGLPixelFormatAttribute(1),
NSOpenGLPixelFormatAttribute(NSOpenGLPFASamples),
NSOpenGLPixelFormatAttribute(2),
NSOpenGLPixelFormatAttribute(NSOpenGLPFAOpenGLProfile),
NSOpenGLPixelFormatAttribute(NSOpenGLProfileVersion3_2Core),
NSOpenGLPixelFormatAttribute(0)
]
self.pixelFormat = NSOpenGLPixelFormat(attributes: attributes)
self.wantsBestResolutionOpenGLSurface = true
let context:NSOpenGLContext = NSOpenGLContext.init(format: self.pixelFormat!, share: nil)!
CGLEnable(context.cglContextObj!, kCGLCECrashOnRemovedFunctions)
self.openGLContext = context
}
override func prepareOpenGL() {
super.prepareOpenGL()
// The callback function is called everytime CVDisplayLink says its time to get a new frame.
func displayLinkOutputCallback(_ displayLink: CVDisplayLink, _ inNow: UnsafePointer<CVTimeStamp>, _ inOutputTime: UnsafePointer<CVTimeStamp>, _ flagsIn: CVOptionFlags, _ flagsOut: UnsafeMutablePointer<CVOptionFlags>, _ displayLinkContext: UnsafeMutableRawPointer?) -> CVReturn {
unsafeBitCast(displayLinkContext, to: BQSOpenGLView.self).renderFrame()
return kCVReturnSuccess
}
self.wantsLayer = true
self.wantsBestResolutionOpenGLSurface = true
CVDisplayLinkCreateWithActiveCGDisplays(amp;displayLink)
let success = CVDisplayLinkSetOutputCallback(displayLink!, displayLinkOutputCallback, Unmanaged.passUnretained(self).toOpaque())
if success != kCVReturnSuccess {
Swift.print ("No opengl")
}
CVDisplayLinkStart(displayLink!)
has_setup = true
NotificationCenter.default.post(name: Notification.Name(rawValue: kOPENGL_SETUP_NOTE), object: nil)
self.backingScaleChange(nil)
}
//..
}
Метод визуализации:
func renderFrame() {
self.openGLContext?.makeCurrentContext()
CGLLockContext((self.openGLContext?.cglContextObj)!)
if !have_setup_renderer { //init only when locked all the context
self.backingScaleChange(nil)
m_renderer = OpenGLRenderer.init(defaultFBO: 0, screenSize: (self.window?.screen?.frame.size)!, backingScalar: self.backing_scalar)
have_setup_renderer = true
}
m_renderer.render()
CGLFlushDrawable((self.openGLContext?.cglContextObj)!)
CGLUnlockContext((self.openGLContext?.cglContextObj)!)
}
Существует ли новый Swift 3 способ настройки OpenGL или приведенный выше код правильный, а проблема где-то в другом месте?
Ответ №1:
Оказывается, это был слегка поврежденный проект Xcode. Единственное, что не работало, это представление OpenGL. Возможно, просто наконечник был плохим.
Я запустил новый проект и вырезал вставил код в новые файлы и тщательно перестроил пользовательский интерфейс, и все работало просто отлично. Это научит меня не настраивать windows программно!