使用opengl es着色器将YUV转换为RGB

2024-02-11

我想在 opengl es 着色器中仅使用一个包含 yuv 数据的采样器将 yuv 转换为 RGB。我的代码如下:

1)我将 yuv 数据发送到纹理:

GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE,
            mData.w, mData.h * 3 / 2, 0, GLES20.GL_LUMINANCE,
            GLES20.GL_UNSIGNED_BYTE, ByteBuffer.wrap(mData.yuv));

2)我的顶点着色器:

attribute vec4 position;
attribute vec2 inputTextureCoordinate;
attribute mediump float width;

varying vec2 v_texCoord;
varying mediump vec2 v_vuTexCoord;
varying mediump float x_coord;

void main()
{
    gl_Position = position;
    v_texCoord = vec2(inputTextureCoordinate.x, inputTextureCoordinate.y * 0.6666667);
    v_vuTexCoord = vec2(inputTextureCoordinate.x, inputTextureCoordinate.y * 0.333333 + 0.6666667);
    x_coord = floor(inputTextureCoordinate.x * width);
}

3)我的片段着色器:

uniform sampler2D inputImageTexture;  
varying mediump vec2 v_texCoord;
varying mediump vec2 v_vuTexCoord;
varying mediump float x_coord;
uniform mediump float u_one_over_tex_size;

void main()
{
    mediump vec3 yuv;
    mediump vec3 rgb;
    mediump float valx = mod(x_coord , 2.0);
    if(valx < 1.0) 
    {
        yuv.y = texture2D(inputImageTexture, v_vuTexCoord + vec2(u_one_over_tex_size, 0)).r - 0.5;
        yuv.z = texture2D(inputImageTexture, v_vuTexCoord).r - 0.5;
    } 
    else {
        yuv.y = texture2D(inputImageTexture, v_vuTexCoord).r - 0.5;
        yuv.z = texture2D(inputImageTexture, v_vuTexCoord + vec2(u_one_over_tex_size, 0)).r - 0.5;
    }
    yuv.x = texture2D(inputImageTexture, v_texCoord).r;
    rgb = mat3(    1,       1,     1,
                   0, -.34413, 1.772,
               1.402, -.71414,     0) * yuv;
    gl_FragColor = vec4(rgb, 1);
}

但结果并不如我所想。如果我将 yuv 数据拆分为 y 和 uv 采样器并更改顶点和片段着色器,我可以获得正确的结果。但我怎么可能只送一个样品呢
像上面那样?


看看这里的代码:http://www.fourcc.org/source/YUV420P-OpenGL-GLSLang.c http://www.fourcc.org/source/YUV420P-OpenGL-GLSLang.c

/*
 * Very simple example of how to perform YUV->RGB (YCrCb->RGB)
 * conversion with an OpenGL fragmen shader. The data (not included)
 * is presumed to be three files with Y, U and V samples for a 720x576
 * pixels large image.
 *
 * Note! The example uses NVidia extensions for rectangular textures
 * to make it simpler to read (non-normalised coordinates).
 * Rewriting it without the extensions is quite simple, but left as an
 * exercise to the reader. (The trick is that the shader must know the
 * image dimensions instead)
 *
 * The program also does not check to see if the shader extensions are
 * available - this is after all just a simple example.
 *
 * This code is released under a BSD style license. Do what you want, but
 * do not blame me.
 *
 * Peter Bengtsson, Dec 2004.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <GL/gl.h>
#include <GL/glext.h>
#include <SDL/SDL.h>

int Quit=0;

static int B_WIDTH=640;
static int B_HEIGHT=480;

int main(int cnt,char *arg[])
{
SDL_Surface *Win=NULL;
GLubyte *Ytex,*Utex,*Vtex;
SDL_Event evt;
int i;
GLhandleARB FSHandle,PHandle;
char *s;
FILE *fp;

char *FProgram=
  "uniform sampler2DRect Ytex;\n"
  "uniform sampler2DRect Utex,Vtex;\n"
  "void main(void) {\n"
  "  float nx,ny,r,g,b,y,u,v;\n"
  "  vec4 txl,ux,vx;"
  "  nx=gl_TexCoord[0].x;\n"
  "  ny=576.0-gl_TexCoord[0].y;\n"
  "  y=texture2DRect(Ytex,vec2(nx,ny)).r;\n"
  "  u=texture2DRect(Utex,vec2(nx/2.0,ny/2.0)).r;\n"
  "  v=texture2DRect(Vtex,vec2(nx/2.0,ny/2.0)).r;\n"

  "  y=1.1643*(y-0.0625);\n"
  "  u=u-0.5;\n"
  "  v=v-0.5;\n"

  "  r=y+1.5958*v;\n"
  "  g=y-0.39173*u-0.81290*v;\n"
  "  b=y+2.017*u;\n"

  "  gl_FragColor=vec4(r,g,b,1.0);\n"
  "}\n";


if(!SDL_Init(SDL_INIT_VIDEO)) {

  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);

  Win=SDL_SetVideoMode(B_WIDTH,B_HEIGHT,32,SDL_HWSURFACE|SDL_ANYFORMAT|SDL_OPENGL);

  if(Win) {
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0,B_WIDTH,0,B_HEIGHT,-1,1);
    glViewport(0,0,B_WIDTH,B_HEIGHT);
    glClearColor(0,0,0,0);
    glColor3f(1.0,0.84,0.0);
    glHint(GL_POLYGON_SMOOTH_HINT,GL_NICEST);

    /* Set up program objects. */
    PHandle=glCreateProgramObjectARB();
    FSHandle=glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);

    /* Compile the shader. */
    glShaderSourceARB(FSHandle,1,&FProgram,NULL);
    glCompileShaderARB(FSHandle);

    /* Print the compilation log. */
    glGetObjectParameterivARB(FSHandle,GL_OBJECT_COMPILE_STATUS_ARB,&i);
    s=malloc(32768);
    glGetInfoLogARB(FSHandle,32768,NULL,s);
    printf("Compile Log: %s\n", s);
    free(s);

    /* Create a complete program object. */
    glAttachObjectARB(PHandle,FSHandle);
    glLinkProgramARB(PHandle);

    /* And print the link log. */
    s=malloc(32768);
    glGetInfoLogARB(PHandle,32768,NULL,s);
    printf("Link Log: %s\n", s);
    free(s);

    /* Finally, use the program. */
    glUseProgramObjectARB(PHandle);

    /* Load the textures. */
    Ytex=malloc(414720);
    Utex=malloc(103680);
    Vtex=malloc(103680);

    fp=fopen("Image.Y","rb");
    fread(Ytex,414720,1,fp);
    fclose(fp);
    fp=fopen("Image.U","rb");
    fread(Utex,103680,1,fp);
    fclose(fp);
    fp=fopen("Image.V","rb");
    fread(Vtex,103680,1,fp);
    fclose(fp);

    /* This might not be required, but should not hurt. */
    glEnable(GL_TEXTURE_2D);

    /* Select texture unit 1 as the active unit and bind the U texture. */
    glActiveTexture(GL_TEXTURE1);
    i=glGetUniformLocationARB(PHandle,"Utex");
    glUniform1iARB(i,1);  /* Bind Utex to texture unit 1 */
    glBindTexture(GL_TEXTURE_RECTANGLE_NV,1);

    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
    glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_LUMINANCE,376,288,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,Utex);

    /* Select texture unit 2 as the active unit and bind the V texture. */
    glActiveTexture(GL_TEXTURE2);
    i=glGetUniformLocationARB(PHandle,"Vtex");
    glBindTexture(GL_TEXTURE_RECTANGLE_NV,2);
    glUniform1iARB(i,2);  /* Bind Vtext to texture unit 2 */

    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
    glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_LUMINANCE,376,288,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,Vtex);

    /* Select texture unit 0 as the active unit and bind the Y texture. */
    glActiveTexture(GL_TEXTURE0);
    i=glGetUniformLocationARB(PHandle,"Ytex");
    glUniform1iARB(i,0);  /* Bind Ytex to texture unit 0 */
    glBindTexture(GL_TEXTURE_RECTANGLE_NV,3);

    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
    glTexParameteri(GL_TEXTURE_RECTANGLE_NV,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
    glTexImage2D(GL_TEXTURE_RECTANGLE_NV,0,GL_LUMINANCE,752,576,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,Ytex);

    /* Simple loop, just draws the image and waits for quit. */
    while(!Quit) {
      if(SDL_PollEvent(&evt)) {
        switch(evt.type) {
        case  SDL_KEYDOWN:
        case  SDL_QUIT:
          Quit=1;
        break;
        }
      }

      glClear(GL_COLOR_BUFFER_BIT);

      /* Draw image (again and again). */

      glBegin(GL_QUADS);
        glTexCoord2i(0,0);
        glVertex2i(0,0);
        glTexCoord2i(720,0);
        glVertex2i(B_WIDTH,0);
        glTexCoord2i(720,576);
        glVertex2i(B_WIDTH,B_HEIGHT);
        glTexCoord2i(0,576);
        glVertex2i(0,B_HEIGHT);
      glEnd();

      /* Flip buffers. */

      glFlush();
      SDL_GL_SwapBuffers();

      sleep(1);
    } /* while(!Quit) */

    /* Clean up before exit. */

    glUseProgramObjectARB(0);
    glDeleteObjectARB(sprog);

    free(Ytex);
    free(Utex);
    free(Vtex);

  } else {
    fprintf(stderr,"Unable to create primary surface. \"%s\".\n",SDL_GetError());
  }
  SDL_Quit();
} else {
  fprintf(stderr,"Initialisation failed. \"%s\".\n",SDL_GetError());
}

return(0);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用opengl es着色器将YUV转换为RGB 的相关文章

  • 绑定第二个顶点缓冲区似乎破坏了我的第一个顶点缓冲区,OpenGL OES ios 5.1

    我正在创建两个不同的顶点缓冲区 使用两个不同的着色器来渲染它们 一旦我绑定第二个顶点缓冲区 我停放在第一个顶点缓冲区中的数据似乎已损坏或丢失 如果我只生成并绘制一个顶点缓冲区 如下所示 glGenBuffers 1 vb1 glBindBu
  • 将预览帧转换为位图

    我知道这个主题已经在黑板上出现过很多次了 但无论如何我都无法让它发挥作用 我想将预览中的视图帧保存为 jpeg 文件 它看起来或多或少 代码被简化 没有额外的逻辑 异常等 像这样 public void onPreviewFrame byt
  • 创建并加载用于 openGL 的 RGBA4444 RGBA5551 中的 .png

    我正在创建一个 openGL 游戏 到目前为止 我一直在使用 RGBA8888 格式的 png 作为纹理表 但这些太占用内存了 而且我的应用程序经常崩溃 我在 Apple 网站上读到 这种格式仅在需要太多质量时才使用 并建议使用 RGBA4
  • 使用硬件加速内容截取 WKWebview 的屏幕截图

    我在截屏时遇到严重问题WKWebview内容当有硬件加速内容 一些在 iframe 内运行的特定赌场游戏 到目前为止 我使用了像大家建议的标准截图方式 UIGraphicsBeginImageContextWithOptions conta
  • Android——在 OnDrawFrame 方法之外将 GLSurfaceView.Renderer 置于睡眠状态(如 Thread.sleep(20))

    我想控制 GLSurfaceView Renderer 的渲染速率 我在扩展 GLSurfaceView 的类中实现了一个线程 并在 while true 循环中定期将其置于睡眠状态 这不会减慢渲染器的速度 有一个很好的答案here htt
  • 执行eglSwapBuffer和eglMakeCurrent时性能低下

    我正在开发一个 Android Unity 插件 允许用户记录他 她的游戏玩法我的解决方案概述 使用 OpenGl FrameBufferObject FBO 使 Unity 离屏渲染到此 FBO Get the offscreen tex
  • OpenGL 与 Cocos2d:该选择什么?

    我知道 cocos2d 它是非常简单的 API 我可以用它来做简单而巨大的 2D 甚至有时 3D 游戏 应用程序 我也知道 OpenGL 它更复杂 它的 API 级别较低等 问题 实现 2D 3D 游戏用什么更好 如果我们有cocos2d这
  • 全屏背景纹理与 OpenGL 性能问题 (iPad)

    我对在 OpenGL 中使用带纹理的三角形网格绘制全屏背景时所看到的糟糕性能感到非常困惑 仅绘制背景而没有其他内容 使用最基本的着色器时最高可达 40 fps 使用默认值时最高可达 50 fps管道 虽然 40 fps 看起来并不算太糟糕
  • YUV420 到 RGB 转换

    我使用以下公式将 RGB 矩阵转换为 YUV 矩阵 Y 0 257 R 0 504 G 0 098 B 16 Cr V 0 439 R 0 368 G 0 071 B 128 Cb U 0 148 R 0 291 G 0 439 B 128
  • 如何在Android中渲染OBJ或FBX? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有几个 obj 和 fbx 格式的 3D 对象 其中包含 mtl 和纹理文件 我想知道哪个是在 An
  • 防止没有 GL 扩展的设备从 Google Play 下载应用程序

    是否可以使应用程序在 Google Play 商店中没有特定 OpenGL ES 扩展的设备上不可用 Since
  • 着色器/矩阵问题 - 看不到对象

    我试图在屏幕上放置一个立方体并点亮它 我想要在立方体上添加 phong 阴影 当我运行代码时 我可以看到背景图像 但看不到立方体 我相当确定立方体本身是正确的 因为我已经设法用纯色着色器显示它 我已经设法编译着色器程序 但我根本看不到立方体
  • 在 OpenGL 中移动相机时出现故障

    我正在为 iPhone 编写一个基于图块的游戏引擎 除了以下故障之外 它基本上可以正常工作 基本上 相机将始终将玩家保持在屏幕中央 并且它会移动以正确跟随玩家并在静止时正确绘制所有内容 然而 当玩家移动时 玩家行走的表面瓷砖会出现故障 如下
  • YUV 422、YUV 420、YUV 444

    例如 我有 4 4 图像 我想分别提取 Y U 和 V 分量 如果图像是 YUV 422 YUV 420 和 YUV444 该怎么办 我有兴趣了解 Y U 和 V 的数组结构如何存储在 422 420 和 444 中 以便可以访问它 Thi
  • 减少 OpenGL ES 1.1 中纹理的内存使用

    我在 OpenGL ES 中的场景需要几个大分辨率纹理 但它们是灰度的 因为我仅将它们用于蒙版 我需要减少内存使用 我尝试使用 Bitmap Config ALPHA 8 和 RGB 565 加载这些纹理 ALPHA 8 似乎实际上增加了内
  • Android GLSurfaceView 具有可绘制背景

    我有一个带有可绘制对象作为背景的 GLSurfaceView 但是在没有 surfaceView setZOrderOnTop true 的情况下渲染时只有背景可见 我需要避免使用 setZOrderOnTop true 因为在 GLSur
  • WebGL:enablevertexattribarray索引超出范围

    这是我的顶点和片段着色器
  • 渲染脚本渲染在Android上比OpenGL渲染慢很多

    背景 我想根据Android相机应用程序的代码添加实时滤镜 但Android相机应用程序的架构是基于OpenGL ES 1 x 我需要使用着色器来自定义我们的过滤器实现 然而 将相机应用程序更新到OpenGL ES 2 0太困难了 然后我必
  • WebGL - 如何传递无符号字节顶点属性颜色值?

    我的顶点由具有以下结构的数组组成 Position colour float float float byte byte byte byte 传递顶点位置没有问题 gl bindBuffer gl ARRAY BUFFER this vbo
  • OpenGL ES 2.0 中的纹理点?

    我正在尝试在 OpenGL ES 2 0 中为粒子系统实现纹理点 例如点精灵 我遇到的问题是所有点都渲染为实心黑色方块 而不是正确映射纹理 我已经验证 gl PointCoord 实际上返回从 0 0 到 1 0 的 x y 值 这将映射到

随机推荐

  • SOA:跨多个服务连接数据

    假设我们有 2 项服务 产品和订单 根据我对SOA的理解 我知道每个服务都可以有自己的数据存储 一个单独的数据库 或者同一数据库中的一组表 但任何服务都不允许直接接触另一个服务的数据存储 现在 假设我们已将产品和订单数据独立存储在产品和订单
  • Python Dash:将 pandas 数据帧加载到数据表中

    我一直在尝试构建一个应用程序Dash https plot ly products dash 最近 尽管浏览了许多指南 我还是无法弄清楚如何将 pandas 数据框导入到 Dash 的数据表中 本质上是一个 pandas 数据框 除了网络托
  • 是否应该将 AssemblyInfo.cs 置于版本控制中?

    我有一个使用 CruiseControl 的自动构建系统 我正在使用 SvnRevisionLabeller 来获取要使用的版本字符串 有了这个字符串 我可以使用 nant 更新 AssemblyInfo cs 这样当我构建时它就有正确的构
  • 绘制完后如何删除所有形状

    从这里参考来源谷歌地图绘图工具 http code google com p gmaps samples v3 source browse trunk drawing drawing tools html r 282 如何一键删除所有绘图形
  • 调用另一个 lisp 文件中的函数

    我必须用 Lisp 写一个游戏 为了清楚起见 我想将代码拆分到不同的 lisp 文件中 如何从另一个文件中的函数中调用函数 例如 file1 lisp 有一个名为 function1 的函数 file2 lisp 有一个名为 functio
  • 如何测试 Web 应用程序中的上下文菜单功能?

    我正在使用一个有上下文菜单 右键单击 的 grails 应用程序 上下文菜单是使用 Chris Domigan 构建的jquery 上下文菜单插件 http www trendskitchens co nz jquery contextme
  • 我们如何使用 Cake 构建对安全的 NuGet 服务器进行身份验证?

    我们正在致力于使用 Cake Build 实现构建自动化 并使用 nuget org 中的 NuGet 包 但我们也有自己的 NuGet Feed 服务器 该服务器具有用户名 密码身份验证来访问 我们如何将 Cake Build 与具有身份
  • ImportError:无法在 Google Cloud Language API 中导入名称语言

    我正在尝试使用 Google Natural Language API 中的示例代码来获取情绪分数 但是 每次运行代码时 我都会收到 ImportError 无法导入名称语言 第一行错误 我已经 pip 安装了该库 尝试卸载并重新安装 在控
  • 如何在 Hive 中访问 HBase 表,反之亦然?

    作为一名开发人员 我通过使用以下命令从现有 MySQL 表导入数据 为我们的项目创建了 HBase 表 sqoop job 问题是我们的数据分析师团队熟悉MySQL语法 意味着他们可以查询HIVE轻松上桌 对于他们 我需要在 HIVE 中公
  • 带 Spannable 的按钮 setText 不适用于 Android 5.0 Lollipop

    我有一个简单的Button
  • 正确使用数据上下文的“Using”语句

    我正在使用 Linq to Entities 最近我发现很多人建议将数据上下文包装在 using 语句中 如下所示 Using DataContext db new DataContext var xx db customers 这是有道理
  • 如何将 SPARQL 发布到 Virtuoso?

    我正在使用两种不同的HTTP POST公用事业 poster https addons mozilla org en US firefox addon poster 从 Firefox 以及Python requests http docs
  • Swing - 如何*现在*抓住焦点?

    如何指示我的 Swing 组件获取焦点现在 requestFocus 好像没有立即发送 理想情况下 我想要这个 从 EDT 运行 textInput requestFocusInWindow System out println textI
  • CLI 模式下的 PHP APC

    PHP中的APC模块在CLI模式下运行时是否支持代码优化 例如 当我运行一个文件时php f
  • XmlMassUpdate - 替换值节点

    我正在尝试使用 XmlMassUpdate 根据构建版本类型更新我的配置文件 似乎没有关于如何在任何地方更新新的 app config vs2008 设置格式的文档 这是配置部分
  • 在命令行上评估 emacs lisp 表达式

    我是 emacs 的新手 我正在 redhat linux 上使用 emacs 24 1 并尝试评估 elisp 表达式 我想要 emacs 做的是评估 elisp 表达式而不启动 emacs 本身 我正在尝试不同的事情 emacs eva
  • 将一个列表中的元素添加到另一个 C#

    将一个列表的元素添加到另一个列表的最简单方法是什么 例如 我有两个列表 列表 A 包含 x 项 列表 B 包含 y 项 我想将 B 的元素添加到 A 中 以便 A 现在包含 X Y 项 我知道这可以使用循环来完成 但是有内置的方法吗 或者有
  • App Engine 上的云数据存储客户端库 - NDB 或 google-cloud-datastore

    根据 Google 的文档 我似乎有两个使用 Python 连接到数据存储的主要选项 App Engine 的 NDB 数据存储库和适用于 Python 的 Google Cloud Datastore API 我目前使用的是 App En
  • 如何查找 PostgreSQL 中是否存在函数?

    与表或序列不同 用户定义的函数无法通过pg class http www postgresql org docs 9 3 static catalog pg class html 有以下问题如何找到要删除的所有函数的列表 https sta
  • 使用opengl es着色器将YUV转换为RGB

    我想在 opengl es 着色器中仅使用一个包含 yuv 数据的采样器将 yuv 转换为 RGB 我的代码如下 1 我将 yuv 数据发送到纹理 GLES20 glTexImage2D GLES20 GL TEXTURE 2D 0 GLE