在 Swift 3 中设置 OpenGL

Setting up OpenGL in Swift 3

我有一个受人尊敬的应用程序,我从 obj-c 中的 Apple 示例代码 GLEssentials 强制转换为 Swift 2,现在我正尝试移动到 Swift 3。它在它的核心有一个 NSOpenGLView,主渲染器仍然不在 Swift 中(我知道:我必须尽快硬着头皮迁移到 Metal 或类似的东西),但其他一切都在。

目前在 OSX 10.12 中,Xcode 8 window 只是空白。我不得不对主要 (Swift) OpenGLView class 进行一些编译器建议的更改,以使其在 Swift 3 中成功编译并 运行,我觉得这就是问题所在,因为渲染器 class 似乎 运行ning 很好;我可以让它报告 60 的 FPS,并且能够放置断点来停止每一帧的代码。我的 OpenGLView class 设置如下,这是大部分新 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(&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 的方法,或者上面的代码是否正确但问题出在其他地方?

原来是一个微妙的腐败 Xcode 项目。唯一不起作用的是 OpenGL 视图。可能只是笔尖不好

我开始了一个新项目,将代码剪切并粘贴到新文件中,然后费力地重建了 UI,一切正常。这将教会我不要以编程方式设置 windows!