OpenGL ES - GLKit研究

GLKitフレームワーク

GLKitフレームワークは、アプリケーション開発のOpenGL / OpenGL ESの年代を簡素化するために設計されています。OpenGLまたはOpenGL ESアプリケーションの開発を加速するために表示されます。ループのレンダリングを実現するために数学ライブラリ、背景テクスチャの読み込み、事前に作成するシェーダ効果だけでなく、標準ビューとビューコントローラを使用してください。
GLKitフレームワークは⼯使用しなければならない量に基づいて新しいシェイダーを作成するために低減することができ、所望の番組を関数とクラスを提供し、
又は静止画又は既存の固定区分処理によって提供されるサポートのOpenGL ESまたはOpenGL頂点関数の以前のバージョンに依存する
アプリケーションプログラム。

GLKView、GLKViewController

iOSのプラットフォームでは、Appleが私たちのクラスなどGLKViewControllerの良いパッケージを与え、それは、OpenGL ESの仕事を通じて、当社のレンダリンググラフィックスを簡素化します。

//初始化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

使用GLKTextureLoaderを追加OpenGLのテクスチャ情報を作成することができます。

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は、シェーダベースのレンダリングのために提供される単純な光/ OpenGL ESの着色システムです。

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

//第1、2、3个光照属性
GLKEffectPropertyLight              *_light0, *_light1, *_light2;
コンフィギュレーション・テクスチャ
//配置第1、2个纹理
GLKEffectPropertyTexture            *_texture2d0, *_texture2d1;
//纹理应用于渲染图元的顺序
NSArray                             *_textureOrder;
コンフィギュレーション・微粒化
GLKEffectPropertyFog                *_fog;
カラー設定情報
//表示计算光照与材质交互时是否使用颜色顶点属性
@property (nonatomic, assign)         GLboolean                          colorMaterialEnabled;
//是否使用常量颜色
@property (nonatomic, assign)         GLboolean                          useConstantColor; 
//不提供每个顶点颜色数据时使用常量颜⾊
@property (nonatomic, assign)         GLKVector4                         constantColor; 
結果を描画する準備ができました
- (void) prepareToDraw;    //准备绘制效果(必须在绘制前写上)

以下は、画面に絵を描くようにGLKitの使用方法を示しています

構成環境

//配置环境
- (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);
}

頂点データの設定

// 设置顶点数据数组(顶点坐标、纹理坐标)
- (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);
}

頂点データの設定

//配置纹理
- (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

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

ターン呼び出し中のviewDidLoad

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

次のように業績は以下のとおりです。


6163123-ecf344bf62b3052f.png
image.png

おすすめ

転載: blog.csdn.net/weixin_33971205/article/details/90943369