[面试官:请使用 OpenGL 实现 RGB 到 YUV 的图像格式转换。...我 ……] 最近,有位读者大人在后台反馈:在参加一场面试的时候,面试官要求他用 shader 实现图像格式 RGB 转 YUV ,他听了之后一脸懵,然后悻悻地对面试官说,他只用 shader 做过 YUV...针对他的这个疑惑,今天专门写文章介绍一下如何使用 OpenGL 实现 RGB 到 YUV 的图像格式转换,帮助读者大人化解此类问题。...YUV 格式图像 UV 分量的默认值分别是 127 ,Y 分量默认值是 0 ,8 个 bit 位的取值范围是 0 ~ 255,由于在 shader 中纹理采样值需要进行归一化,所以 UV 分量的采样值需要分别减去...需要注意的是 OpenGL ES 实现 YUV 渲染需要用到 GL_LUMINANCE 和 GL_LUMINANCE_ALPHA 格式的纹理,其中 GL_LUMINANCE 纹理用来加载 NV21 Y
纹理对象通常是通过纹理图片读取到的,这个数据保存到一个二维数组中,这个数组中的元素称为纹素(texel),纹素包含颜色值和alpha值。...这组提前计算的按比例缩小的纹理就是Mipmaps。...,picHeight,0, GL_RGB, GL_UNSIGNED_BYTE, imageData);// 定义纹理图像 1 2 3 4 5 6 7 其中glTexImage2D函数定义纹理图像的格式...3.internalFormat指定OpenGL存储纹理的格式,我们读取的图片格式包含RGB颜色,因此这里也是用RGB颜色。...上面的数据格式如下图所示(来自www.learnopengl.com): ? 这个格式的说明在OpenGL学习脚印: 绘制一个三角形已经讲过,如果不清楚,可以回过头去查看。
版本(否则有一些异常问题出现) OpenGL中的gl库是核心库,glu是实用库,glut是实用工具库,gl是核心,glu是对gl的部分封装,glut是OpenGL的跨平台工具库 OPenGL...) glDrawElements(按索引数组,绘制顶点数组----两个数组) glDrawRangeElements(按索引数组,绘制顶点数组的任意段) OpenGL四种矩阵堆栈: GL_MODELVIEW...对象赋值(像素RGB) 纹理对象: GL_TEXTURE_1D、GL_TEXTURE_2D、 GL_TEXTURE_3D、GL_TEXTURE_CUBE_MAP 纹理坐标: S、T...、R三个轴,范围(0~1),超出范围使用glTexParamteri设置,纹理坐标描述纹理与顶点的映射关系 glTexCoord控制坐标、glTexGen纹理坐标自动生成 (纹理坐标:s\...获取dc),glCallList单个显示调用(需要循环) 字体设置两种方法wglUseFontBitmaps、wglUseFontOutline 光栅化:数据转化为计算机可显示的像素格式(设置光栅位置
在实际应用特别是游戏中纹理占用了相当大的包体积,而且GPU无法直接解码目前流行的图片格式,图片必须转换为RGB等类型的格式才能上传到GPU内存,这显然增加了GPU内存的占用。...压缩纹理的常见格式 基于OpenGL ES的压缩纹理有常见的如下几种实现: 1)ETC1(Ericsson texture compression) 2)ETC2(Ericsson texture...当加载压缩纹理时,参数支持如下格式: GL_ETC1_RGB8_OES(RGB,每个像素0.5个字节) ETC2 ETC2 是 ETC1 的扩展,压缩比率一样,但压缩质量更高,而且支持透明通道,能完整存储...通过这种方式进行图像压缩增加了纹理加载的开销,但却能够通过更有效地使用纹理存储空间来增加纹理性能,如果由于某些原因无法对纹理进行压缩,OpenGL就会使用下表中所列出的基本内部格式,并加载未经压缩的纹理...GL_COMPRESSED_TEXTURE_FORMATS:支持的压缩纹理格式数组 GL_TEXTURE_COMPRESSION_HINT: 选择压缩格式的方式 11)指定选择压缩格式的方式 glHint
// 闪烁的星星 BOOL tp; // 'T' 按下了么?...]; // 使用 'stars' 结构生成一个包含 'num'个元素的 'star'数组 GLfloat zoom=-15.0f; // 星星离观察者的距离 GLfloat tilt...| // 格式支持窗口 PFD_SUPPORT_OPENGL | // 格式必须支持OpenGL PFD_DOUBLEBUFFER, // 必须支持双缓冲...PFD_TYPE_RGBA, // 申请 RGBA 格式 bits, // 选定色彩深度 0, 0, 0, 0, 0, 0, // 忽略的色彩位...{ keys[VK_F1]=FALSE; // 若是,使对应的Key数组中的值为 FALSE KillGLWindow(); // 销毁当前的窗口 fullscreen
一.整体思路 我们在用纹理增加细节那篇文章中提到过,要将图片渲染在屏幕上,首先要拿到图片的像素数组数据,然后将像素数组数据通过纹理单元传递到片段着色器中,最后通过纹理采样函数将纹理中对应坐标的颜色值采样出来...等几种 width:指定纹理图像的宽度,必须是2的n次方 height:指定纹理图像的高度,必须是2的n次方 border:指定边框的宽度,必须为0 format:像素数据的颜色格式, 不需要和internalformat...它又给我们提供了GL_LUMINANCE这种格式,它表示只取一个颜色通道,假如传入的值为r,则在片段着色器中的纹理单元中读出的值为(r,r,r,1)。...由于我们之前设置的格式是GL_LUMINANCE,假设传入的y分量对应坐标位置的值为r,则在片段着色器中的纹理单元中读出的值为(r,r,r,1),那么我们取r就是取第一个元素的值,其实这里前3个的值都是一样的...在opengl es2.0编程中,用于绘制的顶点数组数据首先保存在cpu内存,在调用glDrawArrays函数进行绘制时,需要将顶点数组数据从cpu内存拷贝到gpu显存中。
GPUImage有哪些特性 丰富的输入组件 摄像头、图片、视频、OpenGL纹理、二进制数据、UIElement(UIView, CALayer) 大量现成的内置滤镜(4大类) 1)....OpenGL纹理。...; 通常我们创建一般纹理的时候都会设成GL_RGBA,传入的图像数据也会是rgba格式的; 而这里y数据因为只包含一个通道,所以设成了GL_LUMINANCE(灰度图); uv数据则包含2个通道,所以设成了...(yuv->rgb)的shader(shader是OpenGL可编程着色器,可以理解为GPU侧的代码,关于shader需要一些OpenGL编程基础(传送门)),绘制到目标纹理: // fullrange...的数值范围是不同的,因此转换公式也不同,这里会有2个颜色转换shader,根据实际的采样格式选择正确的shader; 渲染输出到目标纹理后就得到一个转换成rgb格式的GPU纹理,完成了获取输入数据的工作
最近,有位读者大人在后台反馈:在参加一场面试的时候,面试官要求他用 shader 实现图像格式 RGB 转 YUV ,他听了之后一脸懵,然后悻悻地对面试官说,他只用 shader 做过 YUV 转 RGB...针对这位读者大人的疑惑,今天专门写文章介绍一下如何使用 OpenGL 实现 RGB 到 YUV 的图像格式转换,帮助读者大人化解此类问题。...OpenGL 实现 RGB 转 YUV 好处 使用 shader 实现 RGB 到 YUV 的图像格式转换有什么使用场景呢?在生产环境中使用极为普遍。...YUV 格式图像 UV 分量的默认值分别是 127 ,Y 分量默认值是 0 ,8 个 bit 位的取值范围是 0 ~ 255,由于在 shader 中纹理采样值需要进行归一化,所以 UV 分量的采样值需要分别减去...需要注意的是 OpenGL ES 实现 YUV 渲染需要用到 GL_LUMINANCE 和 GL_LUMINANCE_ALPHA 格式的纹理。
总和案例.gif 通过观察这个案例中有三部分: 地板 自转大球 公转小球 这篇文章中会省略一部分基本的初始化代码,而且代码都是按模块进行了分割,如果想要了解可以去另一篇文章中了解一下OpenGL..., GL_LINEAR, GL_REPEAT); } 项目涉及到3个纹理,所以创建3个纹理对象保存到texture数组中。.../参数1:纹理维度 //参数2:mip贴图层次 //参数3:纹理单元存储的颜色成分(从读取像素图是获得)-将内部参数nComponents改为了通用压缩纹理格式GL_COMPRESSED_RGB...//参数4:加载纹理宽 //参数5:加载纹理高 //参数6:加载纹理的深度 //参数7:像素数据的数据类型(GL_UNSIGNED_BYTE,每个颜色分量都是一个8位无符号整数...时刻记着:OpenGL是一个巨大的状态机。OpenGL没有对象的概念,是面向过程的编程方式,根据代码执行的顺序完成赋值操作。
因为有不少人都问过我压缩格式的问题,今天飞哥又重新提醒了一次。整理一下发个贴,以供大家查阅和讨论。 各种纹理格式,大家参照下U3D MANUAL里面的具体描述介绍,这是官方的东西。...ETC2只有OPENGL3.0支持,PVRTC是Imagination PowerVR提供的,ATC是Qualcomm Snapdragon提供的。一般来说,IOS只支持PVRTC的压缩格式。...一旦相应的贴图格式不兼容的时候,U3D会自动将其转换成RGB(A)格式。最好的兼容是针对GPU进行打包,例如针对小米的都用ATC格式,但一般开发做不到太细化的选择。...非正方贴图只有16位的压缩(相当于真彩色减半),所以最好游戏中都是正方的贴图。以下是个人选择贴图压缩格式遵循的一些规则,大家可以参考下,若有问题可以一起交流一下。...非正方贴图: 一般采用16位压缩,16位会带来颜色损失,但如果本来美术就是按16BITS画的话,就不会损失,日本好些手游都是按16BITS来画的。这样的游戏一般少渐变艳度高比较容易看出来。
当然我们也可以针对GPU提供的接口,转换GPU中的数据,例如将OpenGL的纹理从原来的YUV转换成RGB以获得理想的硬解数据流,上述都是我们在考虑硬解优化时想到的解决方案。...现在很多硬解都是以YUV作为输出格式如NV12等,当然排除个别定制化产品通过参数配置调整输出格式为RGB的情况,根据经验硬解一般选用YUV作为输出格式。...首先是因为RGB的输出实际上是在GPU内部进行的色彩空间转换,会对性能产生一定影响;其次我们也面临无法保证YUV转换成RGB的精确性,矩阵系数是定值则无法适应多样场景的问题。...D3D11的硬解输出结果为D3D11纹理,输出格式为NV12。后续在转换纹理时我们有两个思路:思路一较为常见,这里就不再赘述。...macOS也可通过TextureCache方法实现纹理转换并输出RGB型纹理,但性能较为低下,不在此赘述。
4)图谱路径:采集/音频采集/声音数字化/量化位深 对模拟音频信号的幅度轴进行数字化,它决定了模拟信号数字化以后的动态范围。...8 bit 位深对应 48 分贝的动态范围(最大声压级 = 20 * lg(2^8) = 48.16),16 bit 位深对应 96 分贝的动态范围,24 bit 位深对应 144 分贝的动态范围。...5)图谱路径:采集/视频采集/图像/颜色模型 CIE RGB 颜色模型:基于人眼视觉感知三原色理论,CIE 通过大量实验数据建立了 RGB 颜色模型,标准化了 RGB 表示。...6)图谱路径:采集/视频采集/纹理/数据与纹理转换/纹理转数据(GPU → CPU)/Android 方案 glReadPixels OpenGL ES 2.0 和 3.0 均支持,兼容性较好。...目前通用的优化方法是在 shader 中将处理完成的 RGBA 转成 YUV (一般是 YUYV 格式),然后基于 RGBA 的格式读出 YUV 图像,这样传输数据量会降低一半,性能提升明显。
尤其是针对深度缓存附件、模板缓存附件这类不需要在着色器中读取的缓存数据,OpenGL 还提供了另一种更加高效的缓存区附件——渲染缓冲对象(Renderbuffer Object, RBO)附件,用于存储渲染结果...渲染缓冲对象(RBO)是 OpenGL 提供的一种存储渲染结果的帧缓冲对象(FrameBuffer Object,FBO)附件,与帧缓冲对象(FBO)配合使用。...由于其不可被直接读取的特性,给了OpenGL很多优化空间:RBO直接存储渲染数据,无需进行额外的向纹理特定格式的转换,从而减少了内存带宽的占用。...: 返回的 RBO ID 数组 void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers); // 绑定渲染缓冲对象 // target: 要绑定的目标...); // 删除渲染缓冲对象 // n: 要删除的 RBO 数量 // renderbuffers: 要删除的 RBO ID 数组 void glDeleteRenderbuffers(GLsizei
Texture 纹理,就是一堆被精心排列过的像素; 因为 OpenGL 就是图像处理库,所以 Texture 在 OpenGL 里面有多重要,可想而知; 其中间接地鉴明了一点,图片本身可以有多大变化,OpenGL...】 即只有在具备了 光 + 影 的知识,去学习 环境贴图才好理解;【贴图:HDR 图片 (效果中的那张蓝色森林就是 HDR 图,没有做 CubeMap) + CubeMap 格式】 CubeMap 图片格式...* internalformat 指 像素数据的格式是什么 GL_RGB 等等 width 指 一块像素的宽 [2D 下只有一块,cubemap 会有多块(六个面)] height 指 一块像素的高...;】 【MipMapping 发挥作用的地方就是在缩小的时候,OpenGL 会自动选择合适大小的像素数据】 如果纹理像素在 x、y 方向上是做同一个动作【拉伸或压缩】,则需要放大或缩小像素;如果纹理像素在...函数指名的颜色格式要一致,不然不可能显示正常【如,你这里定义成 CYMK, 指名了 GL_RGB 那么肯定不对的】 3、确定最终像素的位深与位数 这里是明确用多少位来表示一个像素位【如:R 用 8 位表示
本文是基于前面两篇OpenGl理论学习的实际应用,更好的巩固一下前面的学习内容,重点讲下如何使用OpenGl去渲染一个yuv格式视频。 什么是YUV YUV,是一种颜色编码方法。...“Y”表示明亮度,“U”和“V”则是色度、浓度相对我们都比较熟悉的编码格式RGB,RGB诉求于人眼对色彩的感应,YUV则着重于视觉对于亮度的敏感程度。...所以,并不是每个像素点都需要包含了 Y、U、V 三个分量,根据不同的采样格式,可以每个 Y 分量都对应自己的 UV 分量,也可以几个 Y 分量共用 UV 分量。相比 RGB,能够节约不少存储空间。...在这里我们也需要了解一下OpenGL的纹理知识。 OpenGL纹理绘制 OpenGl提供了纹理概念,将一张图片贴到任意位置。 实际就是对图片进行采样,再将采样到的颜色数据绘制到图形相应的位置。...内部格式,告诉OpenGL内部用什么格式存储和使用这个纹理数据。
glReadPixels glReadPixels 是 OpenGL ES 的 API ,OpenGL ES 2.0 和 3.0 均支持。使用非常方便,下面一行代码即可搞定,但是效率很低。...glReadPixels 性能瓶颈一般出现在大分辨率图像的读取,所以目前通用的优化方法是在 shader 中将处理完成的 RGBA 转成 YUV (一般是 YUYV 格式),然后基于 RGBA 的格式读出...主要步骤:首先需要创建 AHardwareBuffer 和 EGLImageKHR 对象,然后将目标纹理(FBO 的颜色附着)与 EGLImageKHR 对象绑定,渲染结束之后便可以读取纹理图像。...YUV (YUV420)格式的图像,只需要在 shader 中实现 RGB 到 YUV 的格式转换。...; vec3 yuv = rgb_2_yuv(rgbColor, conv_standard);//实现 RGB 到 YUV 的格式转换 outColor = vec4(yuv, 1.0
OpenGL ES文集,这一篇介绍以下知识点: AVFoundation——加载视频; CoreVideo——配置纹理; OpenGL ES——渲染视频; 3D数学——球体以及3维变换; 核心思路 通过...AVFoundation加载视频源,读取到每一帧的CMSampleBuffer之后,用CoreVideo创建OpenGL ES纹理缓存并上传GPU;OpenGL ES按照球体的模型来渲染视频;用移动摄像机朝向或者旋转球体的方式来响应手指的移动达到移动镜头的效果...; 通过CVBufferGetAttachment获取pixelBuffer的颜色空间格式,决定使用的颜色转换矩阵,用于下一步的YUV到RGB颜色空间的转换; 通过glActiveTexture启用纹理...创建的亮度纹理为frameHeight * frameWidth,格式为GL_LUMINANCE; CVOpenGLESTextureCacheCreateTextureFromImage创建的亮度纹理为...是否可以不使用CV直接读取纹理信息? 4、YUV到RGB颜色空间的转换; YUV颜色空间由亮度+色度组成,GPU支持的RGB的颜色空间,故而需要进行一次转换。
和图片不同的是,视频需要不断地刷新,每当有新的一帧来时,我们都应该更新纹理,然后重新绘制。用 OpenGL 播放视频就是把视频贴到屏幕上。...urfaceTexture 配合进行纹理更新和格式转换。...需要注意的是MediaPlayer的输出往往不是RGB格式(一般是YUV),而GLSurfaceView需要RGB格式才能正常显示。...之前提到视频解码的输出格式是YUV的(YUV420sp,应该是),那么这个扩展纹理的作用就是实现YUV格式到RGB的自动转化,我们就不需要再为此写YUV转RGB的代码了。...之前提到视频解码的输出格式是YUV的(YUV420p,应该是),那么这个扩展纹理的作用就是实现YUV格式到RGB的自动转化, 我们就不需要再为此写YUV转RGB的代码了*/
上文Android OpenGL ES(三)-平面图形的最后,我们通过渲染纹理,终于将我们的2D图片渲染到了OpenGL中。...这章,我们再接再厉,为我们的纹理添加单独的滤镜效果 上一章加载图片的过程,在这里就不做赘述。 黑白效果 基础分析 之前我们通过YUV数据格式的处理知道,只要保留Y的数据,就是灰度的图片。...但是OpenGL中处理的是RGB格式的数据,我们要如何去取得灰度图呢? 我们可以通过公式,计算出新的RGB值,就是灰度的图片了。...更新代码 按照之前的想法,我们需要将我们的公式中的系数传递进入,就可以完成我们的操作了。基于之前的认识,我们知道传递我们的属性uniform给OpenGL的都是通过创建数组,绑定属性,这一套流程。...//0 创建数组 //黑白图片的公式:RGB 按照 0.2989 R,0.5870 G 和 0.1140 B 的比例构成像素灰度值。
是OpenGL ES的纹理,表示的是存储在显存的图像数据。...CVPixelBufferRef Metal纹理在Metal入门教程(五)视频渲染有详细的介绍; CVPixelBufferRef OpenGL ES纹理在OpenGL ES文集也有相关的介绍...; 本文就是基于CVPixelBufferRef,将Metal的纹理转成CVPixelBufferRef,再用CVPixelBufferRef转成OpenGL ES的纹理,实现Metal到OpenGL...参数(第七个)需要特别注意,这里的格式要和CVPixelBufferCreate方法的pixelFormatType(第四个)对应,否则会出现图片颜色异常的情况。...总结 本文介绍基于CVPixelBufferRef如何把Metal纹理转成OpenGL ES纹理,而OpenGL ES纹理转成Metal纹理的操作也类似。
领取专属 10元无门槛券
手把手带您无忧上云