使用GLKit openGL-iOS绘制YUV图像
我想在iOS设备上渲染yuv图像。我认为它可以通过openGL实现。(实际上我必须连续渲染多个这样的图像) 据我所知,GLKit是iOS创建的一个抽象,其中有一个使用GLKit openGL-iOS绘制YUV图像,ios,opengl-es,rendering,glkit,Ios,Opengl Es,Rendering,Glkit,我想在iOS设备上渲染yuv图像。我认为它可以通过openGL实现。(实际上我必须连续渲染多个这样的图像) 据我所知,GLKit是iOS创建的一个抽象,其中有一个GLKView,它将拥有并处理渲染缓冲区。我目前正在尝试使用GLKViewController,并且正在使用所需的fps成功完成帧更新。我通过使用glClear函数调用来确认这一点 现在的任务是在视图上渲染图像 有一个类glkbaseffect,它将具有基本着色器。我不知道要设置什么属性,所以我只是创建它并在每次渲染之前调用prepar
GLKView
,它将拥有并处理渲染缓冲区。我目前正在尝试使用GLKViewController
,并且正在使用所需的fps成功完成帧更新。我通过使用glClear
函数调用来确认这一点
现在的任务是在视图上渲染图像
有一个类glkbaseffect
,它将具有基本着色器。我不知道要设置什么属性,所以我只是创建它并在每次渲染之前调用prepareToDraw
有一个用于处理纹理的类,GLKTextureLoader
,但在我看来,它只适用于石英图像,即yuv420 planar无法使用该类加载到纹理中
// create the texture
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, [imageNSData bytes]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
我使用这段代码生成纹理并绑定它,但我真的不知道我在这里要做什么。不管是什么,它都不会在屏幕上显示任何图像,我也不知道下一步该怎么做
我还没有创建任何着色器,假设baseEffect会产生一些效果
这告诉我我必须使用EAGLayer在屏幕上渲染图像
我可以使用GLKit渲染图像吗?如果是,我们有没有不使用
GLKTextureLoader
类的示例代码或教程(我找不到)?如果没有,是否有类似的教程可供使用eaglayer进行渲染(我到目前为止还没有对此进行过探讨)?听起来您真的在问一些不同的主题:
- 如何使用
GLKView
vscaeaglayer
- 一般来说,
glkbaseffect
和GLKTextureLoader
如何适合OpenGL ES绘图
- 拥有纹理后如何绘制纹理
- 如何渲染YUV图像数据
我将尝试依次解决每个问题
GLKView
适用于您想要执行的任何OpenGL ES绘图--它可以为您执行链接到的旧文档所做的一切(设置帧缓冲区、caeaglayer
s等),因此您无需编写该代码。在GLKView
绘图方法(drawRect:
或GLKView:drawInRect:
,具体取决于您是在子类中还是在委托中绘图)中,您可以为CaeAglayer
(或任何其他系统)编写相同的OpenGL ES绘图代码
您可以相互独立地使用GLKView
、GLKTextureLoader
、和glkbaseffect
。如果要编写所有自己的绘图代码并使用自己的着色器,可以在GLKView
中绘制,而无需使用glkbaseffect
。(你甚至可以混合搭配glkbaseffect
和你自己的东西,就像你用OpenGL游戏模板创建一个新的Xcode项目时看到的那样。)同样地,GLKTextureLoader
加载图像数据并吐出你需要的name
来绑定它进行绘图,无论您是否使用glkbaseffect
绘制,都可以使用它
获得纹理后,无论是通过GLKTextureLoader
还是自己读取/解码数据并将其提供给glTexImage2D
,使用纹理绘制有三个基本步骤:
使用glBindTexture
绑定纹理名称
绘制一些要进行纹理处理的几何体(使用glDrawArrays
、glDrawElements
或类似工具)
拥有一个片段着色器,用于查找纹理并输出颜色
如果您只想绘制一个填充视图的图像,只需绘制一个四边形(两个三角形)。下面是当我想要绘制全屏时,我用来设置带有一个四边形的顶点数组对象的代码:
typedef struct __attribute__((packed)) {
GLKVector3 position;
GLKVector2 texcoord;
} Vertex;
static Vertex vertexData[] = {
{{-1.0f, 1.0f, -1.0f}, {0.0f, 0.0f}},
{{-1.0f, -1.0f, -1.0f}, {0.0f, 1.0f}},
{{ 1.0f, 1.0f, -1.0f}, {1.0f, 0.0f}},
{{ 1.0f, -1.0f, -1.0f}, {1.0f, 1.0f}},
};
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData), vertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid *)offsetof(Vertex, position));
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid *)offsetof(Vertex, texcoord));
glBindVertexArrayOES(0);
然后,画它:
glBindVertexArrayOES(_vertexArray);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
这只是几何图形部分。将其与一个glkbaseffect
——其transform
属性是默认的标识转换相结合,其texture2d0
属性设置为通过GLKTextureLoader
或其他方式加载的纹理的名称
,您将看到一个填充有纹理的广告牌
最后,YUV部分。。。我主要是为了这个。你从哪里得到你的YUV纹理数据?如果它来自设备摄像头,您应该查看CVOpenGLESTexture
/CVOpenGLESTextureCache
,如所述。无论如何,您应该能够使用APPLE_rgb_422
扩展来处理YUV纹理,如中所述。您还可以查看一些关于编写片段着色器以动态处理YUV到RGB的帮助。听起来您真的在问一些不同的主题:
- 如何使用
GLKView
vscaeaglayer
- 一般来说,
glkbaseffect
和GLKTextureLoader
如何适合OpenGL ES绘图
- 拥有纹理后如何绘制纹理
- 如何渲染YUV图像数据
我将尝试依次解决每个问题
GLKView
适用于您想要执行的任何OpenGL ES绘图--它可以为您执行链接到的旧文档所做的一切(设置帧缓冲区、caeaglayer
s等),因此您无需编写该代码。在GLKView
绘图方法(drawRect:
或GLKView:drawInRect:
,具体取决于您是在子类中还是在委托中绘图)中,您可以为CaeAglayer
(或任何其他系统)编写相同的OpenGL ES绘图代码
您可以相互独立地使用GLKView
、GLKTextureLoader
、和glkbaseffect
。如果要编写所有自己的绘图代码并使用自己的着色器,可以在