What's wrong with YUV 2 RGB shader

Started by
4 comments, last by kRogue 15 years, 3 months ago
Hi, I have a fragment shader to work for YUV 4:2:0 conversion to RGB, the shader is like this the vertex shader: void main(void){ gl_TexCoord[0] = gl_MultiTexCoord0; gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; } the fragment shader: uniform sampler2DRect Ytex; uniform sampler2DRect Utex,Vtex; void main(void) { float nx,ny,r,g,b,y,u,v; nx=gl_TexCoord[0].s; ny=576-gl_TexCoord[0].t; y=texture2DRect(Ytex,vec2(nx,ny)).r; u=texture2DRect(Utex,vec2(nx/2.0,ny/2.0)).r; v=texture2DRect(Vtex,vec2(nx/2.0,ny/2.0)).r; y=1.1643*(y-0.0625); u=u-0.5; v=v-0.5; r=y+1.5958*v; g=y-0.39173*u-0.81290*v; b=y+2.017*u; gl_FragColor=vec4(r,g,b,1.0); } The code for display function: void display(){ int i; glShadeModel(GL_SMOOTH); //Select texture unit 1 as the active unit and bind the U texture glActiveTexture(GL_TEXTURE1); i=glGetUniformLocationARB(PHandle,"Utex"); glBindTexture(GL_TEXTURE_2D,1); glUniform1iARB(i,1);//Bind Utex to texture unit 1 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL); glTexImage2D(GL_TEXTURE_2D, 0,GL_LUMINANCE, B_WIDTH/2, B_HEIGHT/2, 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_2D,2);//Bind Vtext to texture unit 2 glUniform1iARB(i,2); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, B_WIDTH/2, B_HEIGHT/2, 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"); glBindTexture(GL_TEXTURE_2D,0); glUniform1iARB(i,0);//Bind Ytex to texture unit 0 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL); glTexImage2D(GL_TEXTURE_2D, 0,GL_LUMINANCE, B_WIDTH,B_HEIGHT, 0,GL_LUMINANCE, GL_UNSIGNED_BYTE, Ytex); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glColor3f(1.0,0.0,0.0); glBegin(GL_QUADS); glTexCoord2i(0,0); glVertex2i(0,0); glTexCoord2i(B_WIDTH,0); glVertex2i(B_WIDTH,0); glTexCoord2i(B_WIDTH,B_HEIGHT); glVertex2i(B_WIDTH,B_HEIGHT); glTexCoord2i(0,B_HEIGHT); glVertex2i(0,B_HEIGHT); glEnd(); glFlush(); glutSwapBuffers(); } But the result is it don't work. Only quanter half of right-top shows some uniform colors, the other parts are all dark.... What's wrong?
Advertisement
You should not bind zero. glBindTexture(GL_TEXTURE_2D,0)
Also, use glGenTextures from now on.

Also, glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL) has no effect. You are using shaders.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
TO make things easier, I have remove all the shaders and textures

and the display function is like this

void display()
{
glMaxtrix(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

glBegin(GL_QUADS);
glVertex2i(0,0);
glVertex2i(w,0);
glVertex2i(w,h);
glVertex2i(0,h);
glEnd();

glPopMatrix();
glFlush();
glutSwapBuffers();
}


The result is:
no matter what value w and h is,
the right top quanter of the window goes white,
and the other parts still in dark,

What's the reason?
Thanks.
it seems it can removed by the float point coordinate.

Now the whole program is like this,

shader:
//Fragment
uniform sampler2DRect Ytex;
uniform sampler2DRect Utex,Vtex;
void main(void) {
float nx,ny,r,g,b,y,u,v;
vec4 txl,ux,vx;
nx=gl_TexCoord[0].x;
ny=576-gl_TexCoord[0].y;
y=texture2DRect(Ytex,vec2(nx,ny)).r;
u=texture2DRect(Utex,vec2(nx/2.0,ny/2.0)).r;
v=texture2DRect(Vtex,vec2(nx/2.0,ny/2.0)).r;
y=1.1643*(y-0.0625);
u=u-0.5;
v=v-0.5;

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

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

//Vertex
char* VProgram=
void main(void){
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}



The display function
void display()
{

char *s;
int i;
glShadeModel(GL_SMOOTH);

//Select texture unit 1 as the active unit and bind the U texture
glActiveTexture(GL_TEXTURE1);
i=glGetUniformLocationARB(PHandle,"Utex");
glBindTexture(GL_TEXTURE_RECTANGLE_NV,textures[0]);
glUniform1iARB(i,1);//Bind Utex to texture unit 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, B_WIDTH/2, B_HEIGHT/2,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,textures[1]);//Bind Vtext to texture unit 2
glUniform1iARB(i,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, B_WIDTH/2, B_HEIGHT/2, 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");
glBindTexture(GL_TEXTURE_RECTANGLE_NV,textures[2]);
glUniform1iARB(i,0);//Bind Ytex to texture unit 0

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,B_WIDTH,B_HEIGHT,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,Ytex);


glClear(GL_COLOR_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor3f(1.0,0.0,0.0);

glBegin(GL_QUADS);
glTexCoord2f(-1.0f,-1.0f);
glVertex2f(-1.0f,-1.0f);
glTexCoord2f(1.0f,-1.0f);
glVertex2f(1.0f,-1.0f);
glTexCoord2f(1.0f,1.0f);
glVertex2f(1.0f,1.0f);
glTexCoord2f(-1.0f,1.0f);
glVertex2f(-1.0f,1.0f);
glEnd();

glFlush();
glutSwapBuffers();
}


As you can see, I have avoided to use glBindTexture(GL_TEXTURE_RECTANGLE_NV,0)
the textures(id) are created by call glGenTextures(3,textures)
and the shaders are all compiled and linked without any error

But the problem is still there:
The shader language does not seem to work, only fixed a few values in Ytex, Utex, Vtex can influence the colors on the show window,
and the colors are almost all the same....

In fact, Only value in Utex[B_WIDHT*(B_HEIGHT-2)/4] and Vtex[B_WIDHT*(B_HEIGHT-2)/4] will effect the color shown in the window....

As I am very new to OpenGL, I have no idea about the reasons...
Any answer will be wellcomed.
Thanks.


I am working on a NVidia Geformce 8400M GPU and it implements OpenGL2.1 and GLSL 1.10.
Does anyone has some suggestions? Thanks very much.
check/set your projection matrix is my guess.
Close this Gamedev account, I have outgrown Gamedev.

This topic is closed to new replies.

Advertisement