在iOS上使用OpenGL ES渲染YUV

2018-06-26  本文已影响14人  半岛夏天

1)创建OpenGL context

[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

2)layer设置成不透明

_eaglLayer = (CAEAGLLayer*) self.layer;

_eaglLayer.opaque = YES;

3)创建YUV texture

glGenTextures(1, &m_nTexturePlanarY);

glGenTextures(1, &m_nTexturePlanarU);

glGenTextures(1, &m_nTexturePlanarV);

4)添加shader

GLuint vertexShader = CompileShader(_VERTEX_SHADER_Y_U_V, GL_VERTEX_SHADER);

GLuint fragmentShader = CompileShader(_FRAGMENT_SHADER_Y_U_V, GL_FRAGMENT_SHADER);

glAttachShader(m_nProgramHandle, vertexShader);

glAttachShader(m_nProgramHandle, fragmentShader);

摘录一段GLSL介绍

OpenGL着色语言(GLSL―OpenGL Shading Language)是用来在OpenGL中着色编程的语言,也即开发人员写的短小的自定义程序,他们是在图形卡的GPU (Graphic Processor Unit图形处理单元)上执行的,代替了固定的渲染管线的一部分,使渲染管线中不同层次具有可编程型。比如:视图转换、投影转换等。GLSL(GL Shading Language)的着色器代码分成2个部分:Vertex Shader(顶点着色器)和Fragment(片断着色器),有时还会有Geometry Shader(几何着色器)。负责运行顶点着色的是顶点着色器。它可以得到当前OpenGL 中的状态,GLSL内置变量进行传递。GLSL其使用C语言作为基础高阶着色语言,避免了使用汇编语言或硬件规格语言的复杂性。

5)创建render buffer

glGenRenderbuffers(1, &nColorRenderBuffer);

glBindRenderbuffer(GL_RENDERBUFFER, nColorRenderBuffer);

6)创建frame buffer

glGenFramebuffers(1, &nFrameBuffer);

glBindFramebuffer(GL_FRAMEBUFFER, nFrameBuffer);

7)创建viewport

glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &nBackingWidth);

glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &nBackingHeight);

glViewport(0, 0, nBackingWidth, nBackingHeight);

glClearColor(0.0, 0.0, 0.0, 1.0);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

8)设置四个顶点,四个顶点的设置顺序不同,可以实现图像的上下、左右翻转。

在最后render到屏幕时会用到这些顶点,如下

glVertexAttribPointer(m_nPositionSlot, 2, GL_FLOAT, 0, 0, m_fSquareVertices);

glVertexAttribPointer(m_nTexCoordSlot, 2, GL_FLOAT, 0, 0, m_fTextureVertices);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

9)YUV数据到来时,即可以开始渲染,步骤如下

a. YUV数据更新到texture上

GLTexImage2D(m_nTexturePlanarY, m_pFrameData, m_nTextureWidth, m_nTextureHeight);

GLTexImage2D(m_nTexturePlanarU, pBuffer - (nWidthUV * nHeightUV), nWidthUV, nHeightUV);

GLTexImage2D(m_nTexturePlanarV, pBuffer, nWidthUV, nHeightUV);

b. Bind YUV texture

glActiveTexture(GL_TEXTURE0);

glBindTexture(GL_TEXTURE_2D, m_nTexturePlanarY);

glUniform1i(m_nTextureUniformY, 0);

glActiveTexture(GL_TEXTURE1);

glBindTexture(GL_TEXTURE_2D, m_nTexturePlanarU);

glUniform1i(m_nTextureUniformU, 1);

glActiveTexture(GL_TEXTURE2);

glBindTexture(GL_TEXTURE_2D, m_nTexturePlanarV);

glUniform1i(m_nTextureUniformV, 2);

c. 绘制图像

glVertexAttribPointer(m_nPositionSlot, 2, GL_FLOAT, 0, 0, m_fSquareVertices);

glVertexAttribPointer(m_nTexCoordSlot, 2, GL_FLOAT, 0, 0, m_fTextureVertices);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

d. 在屏幕上显示出来

[m_pContext presentRenderbuffer:GL_RENDERBUFFER];

10)程序退出时释放所有之前分配出来的资源

上一篇下一篇

猜你喜欢

热点阅读