iOS 视频渲染gles_01

 

参考简书

https://www.jianshu.com/p/750fde1d8b6a

https://www.jianshu.com/p/be190b93baef

capture1 简单地图片显示

 

 

 注意使用glkview的时候,custom class 的view类

--------简单显示一幅图

gles可以直接显示点,线,三角形。但是四边形是通过三角形片元拼接的。

 

 

 

流程:

 

1 创建上下文:指定gles的版本,将上下文赋值给当前glkit view 的上下文;设置颜色深度缓冲区,指定当前上下文。

2 (2.1)设置顶点数据,纹理数据,索引表 :这里注意,使用GL_ARRAY_BUFFER的即使用顶点数据缓冲,重复顶点要写多次。当使用顶点索引数据缓冲的时候GL_ELEMENT_ARRAY_BUFFER,重复顶点可以不用在squareVertexData,中一一列出,只要,索引能够对应上顶点的顺序即可 ;这两个参数分别代表了绑定顶点缓冲区对象和顶点索引缓冲区对象

  (2.2) 创建顶点缓冲,并将数据拷贝到GPU:

顶点缓存区: 性能更高的做法是,提前分配一块显存,将顶点数据预先传入到显存当中。这部分的显存,就被称为顶点缓冲区

//顶点数据缓存 GLuint buffer;//顶点缓冲区存储标识 glGenBuffers(1, &buffer); glBindBuffer(GL_ARRAY_BUFFER, buffer); glBufferData(GL_ARRAY_BUFFER, sizeof(squareVertexData), squareVertexData, GL_STATIC_DRAW); //索引数据缓冲 GLuint index; glGenBuffers(1, &index); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
使用索引缓冲的时候必须考一遍顶点,但是直接使用顶点缓冲的时候,不需要所以缓冲拷贝

    第一种写法是创建并绑定顶点缓冲,第二种是创建并绑定顶点索引缓冲。两者取一种使用。GL_STATIC_DRAW:参数的说明:"Static”意味着VBO中的数据不会被改变(一次修改,多次使用),"dynamic”意味着数据可以被频繁修改(多次修改,多次使用),"stream”意味着数据每帧都不同(一次修改,一次使用)。"Draw”意味着数据将会被送往GPU进行绘制,"read”意味着数据会被用户的应用读取,"copy”意味着数据会被用于绘制和读取。注意在使用VBO时,只有draw是有效的,而copy和read主要将会在像素缓冲区(PBO)和帧缓冲区(FBO)中发挥作用(转载:https://blog.csdn.net/zangle260/article/details/47145251)

(2.3)打开读数据通道,让着色器能够访问到顶点数据和属性:

(1)在iOS中, 默认情况下,出于性能考虑,所有顶点着色器的属性(Attribute)变量都是关闭的.

     意味着,顶点数据在着色器端(服务端)是不可用的. 即使你已经使用glBufferData方法,将顶点数据从内存拷贝到顶点缓存区中(GPU显存中).

     所以, 必须由glEnableVertexAttribArray 方法打开通道.指定访问属性.才能让顶点着色器能够访问到从CPU复制到GPU的数据.

     注意: 数据在GPU端是否可见,即,着色器能否读取到数据,由是否启用了对应的属性决定,这就是glEnableVertexAttribArray的功能,
     允许顶点着色器读取GPU(服务器端)数据。
   
    (2)方法简介
    glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
   
    功能: 上传顶点数据到显存的方法(设置合适的方式从buffer里面读取数据)
    参数列表:
        index,指定要修改的顶点属性的索引值,例如
        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指定一个指针,指向数组中第一个顶点属性的第一个组件。初始值为0

 

3 加载需要显示的纹理图片 加载纹理图片,JPG,png。设置坐标原点。创建baseeffect用来着色。

4 绘制图片
GLKView对象将其OpenGL ES上下文设置为当前上下文,并将其帧缓冲区绑定为OpenGL ES呈现命令的目标。然后,
delegate方法应该绘制视图的内容。
   清除颜色缓冲-着色器准备-画图
-----------------------------------------------------------------------------------------------------------------
完整代码
#import <UIKit/UIKit.h>
#import <GLKit/GLKit.h>
@interface ViewController : GLKViewController


@end

#import "ViewController.h"
#import <CoreImage/CoreImage.h>
@interface ViewController ()

@property (nonatomic , strong) EAGLContext* mContext;
@property (nonatomic , strong) GLKBaseEffect* mEffect;

@property (nonatomic , assign) int mCount;
@end

@implementation ViewController
{
}
- (void)viewDidLoad {
    [super viewDidLoad];
   
    /*
        EAGLContext 是苹果iOS平台下实现OpenGLES 渲染层.
        kEAGLRenderingAPIOpenGLES1 = 1, 固定管线
        kEAGLRenderingAPIOpenGLES2 = 2,
        kEAGLRenderingAPIOpenGLES3 = 3,
        */
    //新建OpenGLES 上下文
    self.mContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; //2.0,还有1.0和3.0
    GLKView* view = (GLKView *)self.view; //storyboard记得添加
    view.context = self.mContext;
    
    /*3.配置视图创建的渲染缓存区.
        
        (1). drawableColorFormat: 颜色缓存区格式.
        简介:  OpenGL ES 有一个缓存区,它用以存储将在屏幕中显示的颜色。你可以使用其属性来设置缓冲区中的每个像素的颜色格式。
        
        GLKViewDrawableColorFormatRGBA8888 = 0,
        默认.缓存区的每个像素的最小组成部分(RGBA)使用8个bit,(所以每个像素4个字节,4*8个bit)。
        
        GLKViewDrawableColorFormatRGB565,
        如果你的APP允许更小范围的颜色,即可设置这个。会让你的APP消耗更小的资源(内存和处理时间)
        
        (2). drawableDepthFormat: 深度缓存区格式
        
        GLKViewDrawableDepthFormatNone = 0,意味着完全没有深度缓冲区
        GLKViewDrawableDepthFormat16,
        GLKViewDrawableDepthFormat24,
        如果你要使用这个属性(一般用于3D游戏),你应该选择GLKViewDrawableDepthFormat16
        或GLKViewDrawableDepthFormat24。这里的差别是使用GLKViewDrawableDepthFormat16
        将消耗更少的资源
        
        */
       
    view.drawableColorFormat = GLKViewDrawableColorFormatRGBA8888;  //颜色缓冲区格式
    [EAGLContext setCurrentContext:self.mContext];
   
    
    //顶点数据,前三个是顶点坐标,后面两个是纹理坐标
    GLfloat squareVertexData[] =
    {
       0.5, -0.5, 0.0f,    1.0f, 0.0f, //右下
       0.5, 0.5, -0.0f,    1.0f, 1.0f, //右上
       -0.5, 0.5, 0.0f,    0.0f, 1.0f, //左上
       
       0.5, -0.5, 0.0f,    1.0f, 0.0f, //右下
       -0.5, 0.5, 0.0f,    0.0f, 1.0f, //左上
       -0.5, -0.5, 0.0f,   0.0f, 0.0f, //左下
    };

    //顶点索引
    GLuint indices[] =
    {
        0, 1, 2,
        1, 3, 0
    };
    self.mCount = sizeof(indices) / sizeof(GLuint);

    
    //顶点数据缓存
    GLuint buffer;
    glGenBuffers(1, &buffer);
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(squareVertexData), squareVertexData, GL_STATIC_DRAW);
    
//    GLuint index;
//    glGenBuffers(1, &index);
//    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index);
//    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
//使用这块代码的时候,上边的顶点纹理数组可以去除重复的。
glEnableVertexAttribArray(GLKVertexAttribPosition); //顶点数据缓存 glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 0); glEnableVertexAttribArray(GLKVertexAttribTexCoord0); //纹理 glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 3); NSString* filePath = [[NSBundle mainBundle] pathForResource:@"tuut" ofType:@"png"]; NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:@(1), GLKTextureLoaderOriginBottomLeft, nil];//GLKTextureLoaderOriginBottomLeft 纹理坐标系是相反的 GLKTextureInfo* textureInfo = [GLKTextureLoader textureWithContentsOfFile:filePath options:options error:nil]; //着色器 self.mEffect = [[GLKBaseEffect alloc] init]; self.mEffect.texture2d0.enabled = GL_TRUE; self.mEffect.texture2d0.name = textureInfo.name; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } /** * 场景数据变化 */ - (void)update { } /** * 渲染场景代码 */ - (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { glClearColor(0.3f, 0.6f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //启动着色器 [self.mEffect prepareToDraw]; //glDrawElements(GL_TRIANGLES, self.mCount, GL_UNSIGNED_INT, 0);//按照索引画 glDrawArrays(GL_TRIANGLES, 0, 6);//按照顶点画 } @end

posted on 2020-05-15 14:31  邗影  阅读(21)  评论(0)    收藏  举报

导航