使用GLKit openGL-iOS绘制YUV图像

使用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

我想在iOS设备上渲染yuv图像。我认为它可以通过openGL实现。(实际上我必须连续渲染多个这样的图像)

据我所知,GLKit是iOS创建的一个抽象,其中有一个
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
    vs
    caeaglayer
  • 一般来说,
    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
      vs
      caeaglayer
    • 一般来说,
      glkbaseffect
      GLKTextureLoader
      如何适合OpenGL ES绘图
    • 拥有纹理后如何绘制纹理
    • 如何渲染YUV图像数据
    我将尝试依次解决每个问题


    GLKView
    适用于您想要执行的任何OpenGL ES绘图--它可以为您执行链接到的旧文档所做的一切(设置帧缓冲区、
    caeaglayer
    s等),因此您无需编写该代码。在
    GLKView
    绘图方法(
    drawRect:
    GLKView:drawInRect:
    ,具体取决于您是在子类中还是在委托中绘图)中,您可以为
    CaeAglayer
    (或任何其他系统)编写相同的OpenGL ES绘图代码


    您可以相互独立地使用
    GLKView
    GLKTextureLoader
    、和
    glkbaseffect
    。如果要编写所有自己的绘图代码并使用自己的着色器,可以在