美文网首页OpenGLOpenGLOpenGL ES
OpenGL ES入门01-OpenGL ES概述

OpenGL ES入门01-OpenGL ES概述

作者: 秦明Qinmin | 来源:发表于2017-02-09 19:50 被阅读2046次

    前言

    本文是关于OpenGL ES的系统性学习过程,记录了自己在学习OpenGL ES时的收获。
    这篇文章的目标是搭建OpenGL ES开发环境。
    环境是Xcode8.1+OpenGL ES 2.0
    目前代码已经放到github上面,OpenGL ES入门01-OpenGL ES概述

    欢迎关注我的 OpenGL ES入门专题

    概述

    OpenGL一般它被认为是一个API(Application Programming Interface, 应用程序编程接口),包含了一系列可以操作图形、图像的函数。然而,OpenGL本身并不是一个API,它仅仅是一个由Khronos组织制定并维护的规范(Specification)。OpenGL ES 是专门为手持设备制定的 3D 规范,它是 OpenGL 的简化版。目前较新的 iOS 支持OpenGL ES 3.0。

    效果概述

    实现效果图

    实现思路

    1、建立项目,创建OpenGLESView;
    2、初始化OpenGLES上下文;
    3、创建帧缓存和渲染缓存,并进行绑定;
    4、清屏并进行相关绘制;
    5、清理缓存;

    实现过程

    1、建立项目,创建OpenGLESView

    //
    //  OpenGLESView.m
    //  OpenGLES01-环境搭建
    //
    //  Created by qinmin on 2017/2/9.
    //  Copyright © 2017年 qinmin. All rights reserved.
    //
    
    #import "OpenGLESView.h"
    
    @interface OpenGLESView ()
    
    @end
    
    @implementation OpenGLESView
    
    @end
    
    

    2、初始化OpenGLES上下文

    - (void)setupContext
    {
        // 设置OpenGLES的版本为2.0 当然还可以选择1.0和最新的3.0的版本,以后我们会讲到2.0与3.0的差异,目前为了兼容性选择2.0的版本
        _context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
        if (!_context) {
            NSLog(@"Failed to initialize OpenGLES 2.0 context");
            exit(1);
        }
        
        // 将当前上下文设置为我们创建的上下文
        if (![EAGLContext setCurrentContext:_context]) {
            NSLog(@"Failed to set current OpenGL context");
            exit(1);
        }
    }```
    
    3、创建帧缓存和渲染缓存,并进行绑定
    ```OC
    - (void)setupFrameAndRenderBuffer
    {
        glGenRenderbuffers(1, &_colorRenderBuffer);
        glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
        // 为 color renderbuffer 分配存储空间
        [_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:_eaglLayer];
        
        glGenFramebuffers(1, &_frameBuffer);
        // 设置为当前 framebuffer
        glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
        // 将 _colorRenderBuffer 装配到 GL_COLOR_ATTACHMENT0 这个装配点上
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                  GL_RENDERBUFFER, _colorRenderBuffer);
    }
    

    帧缓存:它是屏幕所显示画面的一个直接映象,又称为位映射图(Bit Map)或光栅。帧缓存的每一存储单元对应屏幕上的一个像素,整个帧缓存对应一帧图像。

    渲染缓存:是OpenGLES管理的一处高效内存区域,它可以储存格式化的图像数据。渲染缓存中的数据只有关联到一个帧缓存对象才有意义,并且需要保正图像缓存格式必须与OpenGLES要求的渲染格式相符(比如:不能将颜色值渲染到深度缓存中)。

    帧缓存附件:

    附件名称 描述
    GL_COLOR_ATTACHMENT(0-i) 第i个颜色缓存(0-GL_MAX_COLOR_ATTACHMENTS-1)0为默认的颜色缓存
    GL_DEPTH_ATTACHMENT 深度缓存
    GL_STENCIL_ATTACHMENT 模板缓存

    函数:

    • 分配n个未使用的帧缓存对象,并将它存储到framebuffers中。
    glGenFramebuffers (GLsizei n, GLuint* framebuffers) 
    
    • 设置一个可读可写的帧缓存。当第一次来绑定某个帧缓存的时候,它会分配这个对象的存储空间并初始化,此后再调用这个函数的时候会将指定的帧缓存对象绑定为当前的激活状态。
    glBindFramebuffer (GLenum target, GLuint framebuffer)
    
    • 该函数是将相关的 buffer(三大buffer之一)attach到framebuffer上(如果 renderbuffer不为 0,知道前面为什么说glGenRenderbuffers 返回的id 不会为 0 吧)或从 framebuffer上detach(如果 renderbuffer为 0)。参数 attachment 是指定 renderbuffer 被装配到那个装配点上,其值是GL_COLOR_ATTACHMENTi, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT中的一个,分别对应 color,depth和 stencil三大buffer。
    glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
    
    • 判断是否是程序生成的帧缓存对象,如果是返回GL_TRUE。如果为0或者未分配返回GL_FALSE。
    glIsFramebuffer (GLuint framebuffer)
    
    • 释放帧缓存对象
    glDeleteFramebuffers (GLsizei n, const GLuint* framebuffers)
    

    <br />

    • 分配n个未使用的渲染缓存对象,并将它存储到renderbuffers中。注意:返回的 id不会为0,0是OpenGL ES 保留的,我们也不能使用 id 为0的 renderbuffer。
    glGenRenderbuffers (GLsizei n, GLuint* renderbuffers)
    
    • 创建并绑定渲染缓存。当第一次来绑定某个渲染缓存的时候,它会分配这个对象的存储空间并初始化,此后再调用这个函数的时候会将指定的渲染缓存对象绑定为当前的激活状态。
    glBindRenderbuffer (GLenum target, GLuint renderbuffer)
    
    • 为当前绑定的渲染缓存对象分配图像数据空间。在iOS中函数(- (BOOL)renderbufferStorage:(NSUInteger)target fromDrawable:(id<EAGLDrawable>)drawable)内部是通过调用glRenderbufferStorage来分配图像数据空间。
    glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
    
    • 判断是否是程序生成的渲染缓存,如果是返回GL_TRUE。如果为0或者未分配返回GL_FALSE。
    glIsRenderbuffer(GLuint renderbuffer)
    
    • 释放渲染缓存
    glDeleteRenderbuffers (GLsizei n, const GLuint* renderbuffers)
    

    4、清屏并进行相关绘制

    - (void)render
    {
        glClearColor(1.0, 1.0, 0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
        
        //将指定 renderbuffer 呈现在屏幕上,在这里我们指定的是前面已经绑定为当前 renderbuffer 的那个,在renderbuffer可以被呈现之前,必须调用renderbufferStorage:fromDrawable: 为之分配存储空间。
        [_context presentRenderbuffer:GL_RENDERBUFFER];
    }
    
    • 用来设置清屏颜色,默认为黑色;glClear (GLbitfieldmask)用来指定要用清屏颜色来清除由mask指定的buffer,mask 可以是 GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT和GL_STENCIL_BUFFER_BIT的自由组合。
    glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
    

    5、清理缓存

    - (void)destoryRenderAndFrameBuffer
    {
        glDeleteFramebuffers(1, &_frameBuffer);
        _frameBuffer = 0;
        glDeleteRenderbuffers(1, &_colorRenderBuffer);
        _colorRenderBuffer = 0;
    }
    

    设备支持

    iOS版本支持情况
    iOS版本 OpenGL ES版本
    2.x 1.x
    3.0~6.x 1.x 2.x
    7.0 1.x 2.x 3.x
    设备支持情况
    Compatibility iPhone 7 iPhone 7 Plus iPhone 6s iPhone 6s Plus iPhone SE iPhone 6 iPhone 6 Plus iPhone 5s iPhone 5 iPhone 5c iPhone 4s iPhone 4
    opengles-1 1 1 1 1 1 1 1 1 1 1 1 1
    opengles-2 1 1 1 1 1 1 1 1 1 1 1 1
    opengles-3 1 1 1 1 1 1 1 1 0 0 0 0

    参考链接

    https://developer.apple.com/library/prerelease/content/documentation/DeviceInformation/Reference/iOSDeviceCompatibility/DeviceCompatibilityMatrix/DeviceCompatibilityMatrix.html#//apple_ref/doc/uid/TP40013599-CH17-SW1

    https://developer.apple.com/library/prerelease/content/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/BestPracticesforAppleA7GPUsandLater/BestPracticesforAppleA7GPUsandLater.html#//apple_ref/doc/uid/TP40008793-CH505-DontLinkElementID_10

    http://blog.csdn.net/kesalin/article/details/8221393

    相关文章

      网友评论

      • 小白学AI:楼主您好,看了您的GPUImage系列文章,很有收获。尤其是
        GPUImageRawDataInput、GPUImageRawDataOutput、GPUImageTextureInput、GPUImageTextureOutput 这几个类,是从您这边我才了解到的。我现在有一个困惑,如果我在处理视频,想获取视频每一帧的数据,比如R、G、B通道的数值应该如何操作呢?
        我目前找到的一种能解决方案是从GPUImageFramebuffer中读取,但是具体如何从视频中获取GPUImageFramebuffer我还不是很清楚。希望楼主不吝赐教。
      • 9a5f9a19e9d3:写的很赞,看完很有帮助,非常感谢:+1: :+1: :+1:
      • 33387b654091:挺详细的:smile:

      本文标题:OpenGL ES入门01-OpenGL ES概述

      本文链接:https://www.haomeiwen.com/subject/urriittx.html