- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想用一个包含 yuv 数据的采样器在 opengl es 着色器中将 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));
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);
}
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);
}
最佳答案
看看这里的代码: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);
}
关于opengl-es - 使用opengl es shader将YUV转换为RGB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17105386/
在 OpenGL/ES 中,在实现渲染到纹理功能时,您必须小心,不要引起反馈循环(从正在写入的同一纹理中读取像素)。由于显而易见的原因,当您读取和写入纹理的相同像素时,行为是未定义的。但是,如果您正在
正如我们最终都知道的那样,规范是一回事,实现是另一回事。大多数错误是我们自己造成的,但有时情况并非如此。 我相信列出以下内容会很有用: GPU 驱动程序中当前已知的与最新版本的 OpenGL 和 GL
很难说出这里问的是什么。这个问题是模棱两可的、模糊的、不完整的、过于宽泛的或修辞的,无法以目前的形式得到合理的回答。为了帮助澄清这个问题以便可以重新打开它,visit the help center
我正在学习 OpenGL,非常想知道与显卡的交互如何。 我觉得了解它是如何在图形驱动程序中实现的,会让我了解 opengl 的完整内部结构(通过这个我可以知道哪些阶段/因素影响我对 opengl 性能
我正在尝试绘制到大于屏幕尺寸(即 320x480)的渲染缓冲区 (512x512)。 执行 glReadPixels 后,图像看起来是正确的,除非图像的尺寸超过屏幕尺寸——在本例中,超过 320 水平
我正在 Windows 中制作一个 3D 小行星游戏(使用 OpenGL 和 GLUT),您可以在其中穿过一堆障碍物在太空中移动并生存下来。我正在寻找一种方法来针对无聊的 bg 颜色选项设置图像背景。
如果我想要一个包含 100 个 10*10 像素 Sprite 的 Sprite 表,是否可以将它们全部排成一排来制作 1,000*10 像素纹理?还是 GPU 对不那么窄的纹理表现更好?这对性能有什
这个问题在这里已经有了答案: Rendering 2D sprites in a 3D world? (7 个答案) 关闭 6 年前。 我如何概念化让图像始终面对相机。我尝试将三角函数与 arcta
是否可以在 OpenGL 中增加缓冲区? 假设我想使用实例化渲染。每次在世界上生成一个新对象时,我都必须用实例化数据更新缓冲区。 在这种情况下,我有一个 3 个 float 的缓冲区 std::v
有人可以向我解释为什么下面的代码没有绘制任何东西,但如果我使用 GL_LINE_LOOP 它确实形成了一个闭环吗? glBegin(GL_POLYGON); for(int i = 0; i <= N
正如标题所说,OpenGL 中的渲染目标是什么?我对 OpenGL 很陌生,我看到的所有网站都让我很困惑。 它只是一个缓冲区,我在其中放置稍后将用于渲染的东西吗? 如果您能提供一个很好的引用来阅读它,
当使用 OpenGL 1.4 固定功能多纹理时,每个纹理阶段的输出在传递到下一个阶段之前是否都固定在 [0, 1]? spec说(第 153 页): If the value of TEXTURE_E
我比较了 2 个函数 openGL ES 和 openGL gvec4 texelFetchOffset(gsampler2DArray sampler, ivec3 P, int lod, ivec
关闭。这个问题是off-topic .它目前不接受答案。 想改进这个问题吗? Update the question所以它是on-topic用于堆栈溢出。 关闭 10 年前。 Improve thi
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 6年前关闭。 Improve this qu
那么当你调用opengl函数时,比如glDraw或者gLBufferData,是否会导致程序线程停止等待GL完成调用呢? 如果不是,那么 GL 如何处理调用像 glDraw 这样的重要函数,然后立即更
我正在尝试实现级联阴影贴图,当我想访问我的视锥体的每个分区的相应深度纹理时,我遇到了一个错误。 更具体地说,当我想选择正确的阴影纹理时会出现我的问题,如果我尝试下面的代码,我会得到一个像 this 中
我想为OpenGL ES和OpenGL(Windows)使用相同的着色器源。为此,我想定义自定义数据类型并仅使用OpenGL ES函数。 一种方法是定义: #define highp #define
我尝试用 6 个位图映射立方体以实现天空盒效果。我的问题是一个纹理映射到立方体的每个面。我已经检查了 gDEBugger,在立方体纹理内存中我只有一个 图像(因为我尝试加载六个图像)。 代码准备纹理:
在 OpenGL 中偏移深度的最佳方法是什么?我目前每个多边形都有索引顶点属性,我将其传递给 OpenGL 中的顶点着色器。我的目标是在深度上偏移多边形,其中最高索引始终位于较低索引的前面。我目前有这
我是一名优秀的程序员,十分优秀!