PDA

View Full Version : blending probs



09-24-2002, 08:53 PM
Help!
New to opengl, and having trouble understanding how to use blending.
Does it not work with glDrawPixels?
I want a sort of fading effect between frames.
The rough idea in pseudo code is:

//init RGBA pixel buffer
pixels = AllocMem( width*height*4 );

while (looping) {
//clear viewport
glClear;

//enable blending
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ZERO );

//draw previous framebuffer;
glDrawPixels( width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels );

//disable blending
glDisable(GL_BLEND);

//set color
glColor4f( 1, 1, 1, 0.9 );

//draw points
glBegin( GL_POINTS );
...
...
glEnd;

//copy framebuffer to pixel buffer
glReadPixels( x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels );

SwapBuffers;
}


I thought this would draw the previous framebuffer with decreasing alpha, so the older points would gradually fade away. However, they seem to be drawn at full intensity. If blending is left enabled, the points drawn in the current frame are blended with the previous, so blending is working. What am I doing wrong, or do I need to copy the buffer to a texture instead and forget about using glReadPixels? I've read that glDrawPixels treats the pixels the same as typical fragments, so I don't know why it wouldn't work.

mikael_aronsson
09-24-2002, 10:41 PM
Hi !

When you call the first glDrawPixels the framebuffer is empty so there is nothing to blend with. To get it to work your way you would need to modify the alpha value in the framebuffer for each frame.... pretty slow I guess.

Mikael

09-25-2002, 12:23 PM
>Hi !
>When you call the first glDrawPixels the >framebuffer is empty so there is nothing to >blend with.

Yes, but that't not important. In my actual code I initialize the first frame and copy it to the pixel buffer, then enter the loop.

The thing is I've seen a demo using the same idea, but it copies the viewport to a texture instead of using glReadPixels, and uses it to texture a fullscreen quad. But I can't find it again. I'm working on something a little different than motion blur, so that's why I want a full-res copy. Is there anything I'm leaving out?

zeckensack
09-25-2002, 01:37 PM
If this is C or C++ (which I suppose it is but you never know ...), the mistake may be in the function calls without arguments.

You use eg
glClear;
which is broken syntax. It won't do anything. This is a function pointer being discarded, so it's a valid C statement, but nothing will happen.
Always add the empy parantheses in these cases.

eg
glClear();

Fix the others too http://www.opengl.org/discussion_boards/ubb/wink.gif

09-25-2002, 03:26 PM
the actual code is written in delphi, but I intended to just write some pseudo code to show what I'm trying to do.
As stated I'm a newbie, but it seems this should be possible. Probably best to track down that demo, get it working, then try and convert the texture copying routines to use glReadPixels. Most effects of this type I've seen use the texture method, as it is faster on low-end hardware in general. But I want to try it the other way :-)

09-25-2002, 08:33 PM
I think it's a case of being confused by how blending works. The redbook gives a brief description of how to use glDrawPixels to create a paintbrush effect, soft edges and all. Although I sort of got it working sometimes, I have absolutely no idea why or how it worked. I'm yet to find simple explanations of the blending factors. Just can't get my head around it.

To try and figure it out, what I'm after is something like (in
delphi):

// ---begin code---

// not sure about the alpha value here
glClearColor( 0,0,0,1 );

glClear( GL_COLOR_BUFFER_BIT );

// create a test brush by drawing to back buffer
glBegin( GL_POINTS );
for i := 0 to Random(100) + 50 do
begin
glColor4f( Random, Random, Random, 0.15 );
glVertex3f( (0.5-Random)*300, (0.5-Random)*300, 0 );
end;
glEnd;

// copy back buffer as brush
// vp holds values returned by glGet with parameter GL_VIEWPORT
glReadPixels( vp[0], vp[1], vp[2], vp[3], GL_RGB, GL_UNSIGNED_BYTE,
brushpixels );

while (running) do
begin
glEnable( GL_BLEND );

// not sure about next line.
// redbook says use "alpha of the incoming color and
// (1-alpha) of the color already at the pixel"
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC?? or DST??_ALPHA );

glDrawPixels( vp[2], vp[3], GL_RGB, GL_UNSIGNED_BYTE, brushpixels
);
glDisable( GL_BLEND );

SwapBuffers( hdc );
end;
// ---end code---


Now I expected this - or one of the many derivatives I've tried - to
fade the viewport from black to the brush colors. But it doesn't work.
So what am I doing wrong? Does anyone have some sample code I could
try?