PDA

View Full Version : Pixel operation (blur) on gl_texture_rectangle



ToxiT
12-14-2010, 08:07 AM
Hi Guys, sorry for my bad english ;)

I'm quite of a beginner in C++/OpengGl. My task is to implement a zoom-blur in a video stream. I have to do this for work, so i really hope you can help me.

I have a running VS Project (2008) where YUV-images are bind to gl_texture_rectangle and then rendered and I planned to use this code for a zoom-blur:

http://mierendo.com/software/3d_filter_blurring/

I thought it would be quite a copy/paste thing, but actually i got problems with the gl_texture_rectangle.
The filter blurring example works with gl_texture_2d and my source code with 3 layers (yuv) of gl_texture_rectangle.
The streamed image is black/white anywhere, so i tried to manipulate the first layer, representing the Y value but failed.



int i;
int passes = 20;

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_RECTANGLE,1);
glTexImage2D(GL_TEXTURE_RECTANGLE,0,GL_LUMINANCE,W IDTH,HEIGHT,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,0);

glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

while (passes > 0) {
for (i = 0; i < 2; i++)
{
glColor4f (1.0f,1.0f,1.0f,1.0 / (i+1));
glBegin (GL_TRIANGLE_STRIP);
glTexCoord2f (0 - (i*0.5)/WIDTH, 1 + (i*0.5)/HEIGHT); glVertex2f (0, 0);
glTexCoord2f (0 - (i*0.5)/WIDTH, 0 - (i*0.5)/HEIGHT); glVertex2f (0, HEIGHT);
glTexCoord2f (1 + (i*0.5)/WIDTH, 1 + (i*0.5)/HEIGHT); glVertex2f (WIDTH, 0);
glTexCoord2f (1 + (i*0.5)/WIDTH, 0 - (i*0.5)/HEIGHT); glVertex2f (WIDTH, HEIGHT);
glEnd ();
}
glCopyTexImage2D (GL_TEXTURE_RECTANGLE, 0, GL_LUMINANCE, 0, 0, WIDTH, HEIGHT, 0);
passes--;
}
glDisable (GL_BLEND);

It seems like Texture_Rectangle can't handle the float values (i also tested integer but failed)
I get a picture black and white, perhaps u can call it blurry, but no grey in it any more. Like there are just 1 or 0.

I also tried to read pixels from the Pixelbuffer (glReadPixels) but i got a error in the Dissasembly, no matter how big data is.

uint8_t data[640*480];
glReadPixels(0,0,640,480,GL_LUMINANCE,GL_UNSIGNED_ BYTE,data);

Is there any possibility to get the gl_texture_2d into a gl_texture_2d, so i can use the code from above?
If not, can i read the texture data from the framebuffer into a gl_texture_2d, manupulate it and then write the data to framebuffer?

I'm dealing with this problem since 3 weeks and really tried, but I'm no computer scientist and meanwhile a little bit depressed.

Because i'm not shure whether i'm allowed to post all the code, someone who is interessted in helping me, just pn me.
Apart from that i hope for any help.

ZbuffeR
12-14-2010, 08:44 AM
No need to get depressed.
Rectangle texture and classic 2D textures are very similar, the main differences are that texcoords are normalized for 2D (within 0.0 to 1.0) and not for rectangle (going from 0 to width and 0 to height, in texels).
So just multiply x part by WIDTH and y part by HEIGHT in the texture coords.

ToxiT
12-14-2010, 02:54 PM
Hi ZbuffeR,

thx for your reply. I already knew this and tried this (Video is 640x480):



glTexCoord2f (0 - (i*0.5)/640, 480 + (i*0.5)/480); glVertex2f (0, 0);
glTexCoord2f (0 - (i*0.5)/640, 0 - (i*0.5)/480); glVertex2f (0, 480);
glTexCoord2f (640 + (i*0.5)/640, 480 + (i*0.5)/480); glVertex2f (640, 0);
glTexCoord2f (640 + (i*0.5)/640, 0 - (i*0.5)/480); glVertex2f (640, 480);


It didn't change anything.

I think it can't handle the float and is copying the Picture but not translating it (translating by 0 pixels) because i*0,5/640 is null in integer.

If I change to:



int i;
int passes = 40;

glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

while (passes > 0) {
for (i = 0; i < 2; i++)
{
glColor4f (1.0f,1.0f,1.0f,1.0 / (i+1));
glBegin (GL_TRIANGLE_STRIP);
glTexCoord2f (0 - 1, 480 + 1); glVertex2f (0, 0);
glTexCoord2f (0 - 1, 0 - 1); glVertex2f (0, 480);
glTexCoord2f (640 + 1, 480 + 1); glVertex2f (640, 0);
glTexCoord2f (640 + 1, 0 - 1); glVertex2f (640, 480);
glEnd ();
}
glCopyTexImage2D (GL_TEXTURE_RECTANGLE, 0, GL_LUMINANCE, 0, 0, w, h, 0);
passes--;
}
glDisable (GL_BLEND);

glDrawPixels(w,h,GL_LUMINANCE,GL_UNSIGNED_BYTE,0);


it does change something. After 40 passes a chess field looks like the picture i attached. As you can see it is a little bit like zoom-blur.The edges in the middle are sharp and the boxes are getting "blurry" to the border.
But there should be a grey scale blurring the edges instead of being just black or white.

ugluk
12-14-2010, 11:58 PM
I'm no expert in blurring, but I think you have to place some alpha values into the texture. I don't see the point in blending if both source and destination alphas are 0. I don't think blending does any averaging of neighboring texels by itself.

ToxiT
12-15-2010, 02:25 AM
The original blur code has this line:

glColor4f (1.0f,1.0f,1.0f,1.0 / (i+1));

So the copied picture is set to alpha=0,5.
But it doesn't matter what i enter as values in this line. So if i type glColor4f (0.0f,0.0f,0.0f,0.0 / (i+1)) or glColor4i (255,255,255,255 / (i+1))etc it doesn't change anything. Like the line is not compiled at all.

Furthermore the Blending mode is set so Alpha blending, so two pictures should be blended correctly by halving the colors and alpha and then mixing them.

You see, I really tried... :(

Thanks again for your help!

ugluk
12-15-2010, 06:49 AM
Then you must be doing something wrong, alpha is not ignored if you blend like you are doing it. Maybe try some other blending function and see if blending is really ignored. If it is, then there is not much you can do, except maybe try a software renderer like mesa3d.