macOS的CAOpenGLLayer中如何启用OpenGL3.2 core profile

在macOS的openGL编程中,我们有时为了想在自己的OpenGL图层上再加些自己的某些图层,必须得用 CAOpenGLLayer 而不是 NSOpenGLView,由于在 NSOpenGLView 上添加任何子视图都会变得无效。

其实,在 CAOpenGLLayer 自定义的子类中要追加支持OpenGL Core Profile很简单,只需要重写其 - (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask 方法即可。如以下代码所示:

// 重写父类的方法,提供自己的CGLPixelFormatObj
- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask
{
    CGLPixelFormatAttribute attribs[] =  {
        
        kCGLPFADisplayMask, 0,
        kCGLPFAColorSize, 24,
        kCGLPFAAccelerated,
        kCGLPFADoubleBuffer,
        
        // Use OpenGL 3.2 Core Profile
        kCGLPFAOpenGLProfile, (CGLPixelFormatAttribute)kCGLOGLPVersion_3_2_Core,
        
        // Use multi-sample
        kCGLPFAMultisample,
        kCGLPFASampleBuffers, (CGLPixelFormatAttribute)1,
        kCGLPFASamples, (CGLPixelFormatAttribute)4,
        
        0
    };
    // 将kCGLPFADisplayMask设置为传递过来的display mask。这个步骤是必须的!
    attribs[1] = mask;
    
    CGLPixelFormatObj pixFormatObj = NULL;
    GLint numPixFormats = 0;
    CGLChoosePixelFormat(attribs, &pixFormatObj, &numPixFormats);
    
    return pixFormatObj;
}

然后,我们可以在自己的子类中添加对CGLContextObj对象的引用来做一些标记。另外,我们必须重写 CAOpenGLLayer 的这个方法:

- (void)drawInCGLContext:(CGLContextObj)glContext
             pixelFormat:(CGLPixelFormatObj)pixelFormat
            forLayerTime:(CFTimeInterval)timeInterval
             displayTime:(const CVTimeStamp *)timeStamp

如以下代码所示:

- (void)drawInCGLContext:(CGLContextObj)glContext
             pixelFormat:(CGLPixelFormatObj)pixelFormat
            forLayerTime:(CFTimeInterval)timeInterval
             displayTime:(const CVTimeStamp *)timeStamp
{
    // 这里必须先将传进来的上下文作为当前OpenGL执行上下文对象,否则后续对OpenGL的状态设置都将无效
    CGLSetCurrentContext(glContext);
    
    [self setupContext];
    
    // mContext主要用于判别当前OpenGL上下文是否已经设置好,以及在render方法中的引用
    mContext = glContext;
    
    [self render];
}

- (void)setupContext 是自定义方法,在里面做顶点设置、全局启用某些OpenGL功能状态,并设置viewport等等。

- (void)render 也是自定义方法,用来做真正的图形绘制。

如以下代码所示:

- (void)render
{
    // render
    glClear(GL_COLOR_BUFFER_BIT);
    
    glDrawArrays(GL_LINE_STRIP, 0, 721);
    
    glFlush();
    
    CGLFlushDrawable(mContext);
}

随后,我们自己提供shader代码,并进行加载即可。这些可以放在 - (void)setupContext 自定义方法中实现。

当然,在macOS中要使用OpenGL core profile必须引入 这个头文件。目前,3.2 core profile以及4.1 core profile都是用此头文件。

你可能感兴趣的:(图形渲染与图像处理,macOS,iOS与Cocoa,Framework,macos,着色器,图形渲染)