4.iOS如何搭建OpenGL ES上下文环境

2023-07-15  本文已影响0人  LucXion

OpenGL ES 不承担窗口管理,虽然是跨平台,但需要搭建各自平台的上下文环境来提供渲染的基础实现。
iOS 平台搭建OpenGL ES的上下文环境,使用的是EAGL,双缓冲机制,由FrameBuffer(帧缓冲区)与RenderBuffer(绘制缓冲区)一起完成。

1. 创建一个自定义的View,重写 +layerClass 方法,用 CAEAGLLayer 替换掉CALayer。

2. 开辟一个线程,在线程中创建 EAGLContext上下文并绑定。

- (id) initWithFrame:(CGRect)frame{
    
    if ((self = [super initWithFrame:frame])){
        
        _renderBufferWorkingQueue = dispatch_queue_create("renderBufferWorkingQueue", DISPATCH_QUEUE_CONCURRENT);
        
        CAEAGLLayer *eaglLayer = (CAEAGLLayer *)[self layer];
        
        NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
                [NSNumber numberWithBool:NO],
                kEAGLDrawablePropertyRetainedBacking,
                kEAGLColorFormatRGB565,
                kEAGLDrawablePropertyColorFormat,
                nil];
        
         [eaglLayer setOpaque:YES];
         [eaglLayer setDrawableProperties:dict];
        
        [self initializationEAGLContext];
    }
    return self;
}

///建立 EAGL 与 OpenGL ES 的关系
- (void)initializationEAGLContext {
    
    dispatch_async(_renderBufferWorkingQueue, ^{
        // 要在子线程中,创建 EAGLContext 上下文
        EAGLContext* _context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
        
        [EAGLContext setCurrentContext:_context];
    });
}

3. 窗口管理部分:

3.1 创建两个帧缓冲区

glGenFramebuffers(1, &_framebuffer);

glGenRenderbuffers(1, &renderbuffer);

3.2 将帧缓冲区与绘制缓冲区绑定到渲染管线

glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer);

glBindRenderbuffer(GL_RENDERBUFFER, _renderbuffer);

3.3 为 RenderBuffer 分配存储区,一般将 CAEAGLLayer 存储区作为RenderBuffer 的存储区

glGetRenderBufferParameteriv(GL_RENDER_BUFFER, GL_RENDER_BUFFER_WIDTH,
        &_backingWidth);

3.4 获取 RenderBuffer 的像素宽高

glGetRenderBufferParameteriv(GL_RENDER_BUFFER, GL_RENDER_BUFFER_WIDTH,
        &_backingWidth);

glGetRenderBufferParameteriv(GL_RENDER_BUFFER, GL_RENDER_BUFFER_HEIGHT,
      &_backingHeight);

3.5 绑定绘制缓冲区到帧缓冲区

glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, _renderbuffer);

3.6 检查 Framebuffer 的 status。

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if(status != GL_FRAMEBUFFER_COMPLETE){
    //failed to make complete frame buffer object 
}

3.7 完成以上操作,我们就把 EAGL 和我们的 Layer(设备的屏幕)连接起来了,当我们绘制了一帧之后(当然绘制过程也必须在这个线程中),调用以下代码就可以将绘制的结果显示到屏幕上了。

[_context presentRenderbuffer:GL_RENDERBUFFER];
上一篇 下一篇

猜你喜欢

热点阅读