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
浙公网安备 33010602011771号