OpenGL ES - GLKit Study

GLKit framework

GLKit framework is designed to simplify application development OpenGL / OpenGL ES's. It appears to accelerate the development of OpenGL or OpenGL ES applications. Use math library, background texture loading, pre-create shader effects, as well as the standard view and the view controller to achieve rendering loop.
GLKit framework provides functions and classes, can be reduced to create a new shader based on the amount should be Use ⼯ the desired program,
or dependent on an earlier version of support OpenGL ES or OpenGL vertex functions provided by existing fixed segment processing of still pictures or
application program.

GLKView 、GLKViewController

In iOS platform, Apple gave us a good package of a class such GLKViewController, it simplifies our rendering graphics through OpenGL ES work.

//初始化GLKView
- (instancetype)initWithFrame:(CGRect)frame context:(EAGLContext *)context;

//颜色渲染缓冲区格式
@property (nonatomic) GLKViewDrawableColorFormat drawableColorFormat;

//深度渲染缓冲区格式
@property (nonatomic) GLKViewDrawableDepthFormat drawableDepthFormat;

//模板渲染缓冲区格式
@property (nonatomic) GLKViewDrawableStencilFormat drawableStencilFormat;

//多重采样缓冲区格式
@property (nonatomic) GLKViewDrawableMultisample drawableMultisample;

//帧缓冲区属性
@property (nonatomic, readonly) NSInteger drawableWidth;    //缓冲区对象宽度
@property (nonatomic, readonly) NSInteger drawableHeight;  //缓冲区对象高度

/**
*  GLKViewDelegate必须实现的方法:在这个方法里进行绘图
* - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect;
*/
@property (nullable, nonatomic, assign) IBOutlet id <GLKViewDelegate> delegate;

//将底层的FrameBuffer对象绑定到OpenGL ES
- (void)bindDrawable;

//删除视图FrameBuffer对象 
- (void)deleteDrawable;

//绘制视图内容并将其作为图像对象返回
@property (readonly, strong) UIImage *snapshot;

//布尔,指定视图是否响应使得视图内容无效的信息
@property (nonatomic) BOOL enableSetNeedsDisplay;

//立即重绘
- (void)display;

GLKTextureInfo

Use GLKTextureLoader can create an add OpenGL texture information:

GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:nil error:nil];

GLKTextureInfo有以下信息:
    GLuint                      name;        //纹理名称
    GLenum                      target;    //纹理绑定的目标
    GLuint                      width;        //加载纹理的宽度
    GLuint                      height;        //加载纹理的高度
    GLKTextureInfoAlphaState    alphaState;  //加载纹理中alpha状态
    GLKTextureInfoOrigin        textureOrigin;  //加载纹理的原点位置
    BOOL                        containsMipmaps;  //布尔值,加载的纹理是否包含mip贴图

GLKBaseEffect

GLKBaseEffect is a simple light / OpenGL ES coloring system provided for shader based rendering.

Configuration of light
//为基元两侧计算光照 (系统去做,开发者来控制开关)
@property (nonatomic, assign)         GLboolean                          lightModelTwoSided;
//计算渲染图元光照使⽤的材质属性
@property (nonatomic, readonly)       GLKEffectPropertyMaterial          *material; 
//环境颜⾊色,应⽤用效果渲染的所有图元
@property (nonatomic, assign)         GLKVector4                         lightModelAmbientColor;

//第1、2、3个光照属性
GLKEffectPropertyLight              *_light0, *_light1, *_light2;
Configuration texture
//配置第1、2个纹理
GLKEffectPropertyTexture            *_texture2d0, *_texture2d1;
//纹理应用于渲染图元的顺序
NSArray                             *_textureOrder;
Configuration atomization
GLKEffectPropertyFog                *_fog;
Color configuration information
//表示计算光照与材质交互时是否使用颜色顶点属性
@property (nonatomic, assign)         GLboolean                          colorMaterialEnabled;
//是否使用常量颜色
@property (nonatomic, assign)         GLboolean                          useConstantColor; 
//不提供每个顶点颜色数据时使用常量颜⾊
@property (nonatomic, assign)         GLKVector4                         constantColor; 
Ready to draw results
- (void) prepareToDraw;    //准备绘制效果(必须在绘制前写上)

The following demonstrates the use of GLKit to draw a picture on the screen

Configuration Environment

//配置环境
- (void)setupUpEnv {
    //初始化上下文
    context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];

    if (context == nil) {
        NSLog(@"content create fail");
        return;
    }
    
    [EAGLContext setCurrentContext:context];
    
    //获取GLKView 设置context
    GLKView * view = (GLKView *)self.view;
    view.context = context;
    view.delegate = self;
    
    //配置视图创建的渲染缓冲区
    view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;
    view.drawableDepthFormat = GLKViewDrawableDepthFormat24;
    
    //配置背景颜色
    glClearColor(0, 1, 1, 1);
}

Vertex data configuration

// 设置顶点数据数组(顶点坐标、纹理坐标)
- (void)setUpVertexData {
    
        //顶点数据和纹理数据都存在一个数组中 ,6个顶点,每五个数据 前三个为xyz顶点坐标  后两个为纹理坐标st
    GLfloat vertexData [] = {
        0.6, -0.5, 0.0f,    1.0f, 0.0f, //右下
        0.6, 0.5, -0.0f,    1.0f, 1.0f, //右上
        -0.6, 0.5, 0.0f,    0.0f, 1.0f, //左上
        
        0.6, -0.5, 0.0f,    1.0f, 0.0f, //右下
        -0.6, 0.5, 0.0f,    0.0f, 1.0f, //左上
        -0.6, -0.5, 0.0f,   0.0f, 0.0f, //左下
    };
    
    //将顶点数据copyj到顶点缓冲区 : 这样做会提前分配一块显存,将顶点数据copy进去,这样可以性能更高
    GLuint bufferID;
    glGenBuffers(1, &bufferID);         //创建顶点缓冲区的标识符ID
    glBindBuffer(GL_ARRAY_BUFFER, bufferID);    //绑定顶点缓冲区
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW); //将顶点数据copy到顶点缓冲区
    
    
    
    
    /**打开读取通道(默认是关闭的,这一步是必须要写的)
     方法简介 : 上传顶点数据到显存的方法(设置合适的方式从buffer里面读取数据)
         glVertexAttribPointer(GLuint indx , GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *ptr)
     * 参数列表:
     * indx :指定要修改的顶点属性索引值 :比如 GLKVertexAttribPosition代表顶点 GLKVertexAttribTexCoord0代表纹理
     * size :每次读取的数量 (如position是由3个(x,y,z)组成,而颜色是4个(r,g,b,a),纹理则是2个.)
     * type :指定数组中每个组件的数据类型。可用的有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT,GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值为GL_FLOAT。
     * normalized :指定当被访问时,固定点数据值是否应该被归一化(GL_TRUE)或者直接转换为固定点值(GL_FALSE)
     * stride :指定连续顶点属性之间的偏移量。如果为0,那么顶点属性会被理解为:它们是紧密排列在一起的。初始值为0
     * ptr :指定一个指针,指向数组中第一个属性组件
     */
    
    //顶点坐标数据
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    /** 每次读3个数据,即x y z。 顶点偏移量为5:
    * 第一个顶点从下标0开始,第二个顶点从下标5开始,以此类推。。。
    * (GLfloat *)NULL + 0 :表示首次读取的位置,因为此时读取是从显存读的  所以不能用数组地址去取  (GLfloat *)NULL表示首地址
    */
    glVertexAttribPointer(GLKVertexAttribPosition , 3, GL_FLOAT,GL_FALSE, 5, (GLfloat *)NULL + 0);
    
    //纹理坐标数据
    glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
    glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 5, (GLfloat *)NULL + 3);
}

Vertex data configuration

//配置纹理
- (void)setUpTexture {
    NSString * filePath = [[NSBundle mainBundle] pathForResource:@"memory" ofType:@"jpg"];
    
    //因为纹理坐标和屏幕坐标是需要翻转的,所以这里需要配置一下映射关系
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:@(1),GLKTextureLoaderOriginBottomLeft, nil];
    
    GLKTextureInfo * textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil];
    
    //使用 GLKBaseEffect 完成着色器的工作
    cEffect = [[GLKBaseEffect alloc] init];
    cEffect.texture2d0.enabled = GL_TRUE;
    cEffect.texture2d0.name = textureInfo.name;
}

GLKViewDelegate begin drawing

#pragma mark - GLKViewDelegate
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    glClear(GL_COLOR_BUFFER_BIT);
    
    //重要的一步!!!
    [cEffect prepareToDraw];
    
    //开始绘制
    glDrawArrays(GL_TRIANGLES, 0, 6);
}

in turn call viewDidLoad

    [self setupUpEnv];
    [self setUpVertexData];
    [self setUpTexture];

Operating results are as follows:


6163123-ecf344bf62b3052f.png
image.png

Guess you like

Origin blog.csdn.net/weixin_33971205/article/details/90943369