-
August 19th, 2015, 02:02 PM
#46
Re: [win32] - avoid flicker and do a correct redraw
Hmmm sometimes passing FALSE instead of true to InvalidateRect() can stop the blinking if memory serves...
ahoodin
To keep the plot moving, that's why.
-
August 20th, 2015, 12:29 AM
#47
Re: [win32] - avoid flicker and do a correct redraw
From MSDN:
bErase [in]
Specifies whether the background within the update region is to be erased when the update region is processed. If this parameter is TRUE, the background is erased when the BeginPaint function is called. If this parameter is FALSE, the background remains unchanged.
Victor Nijegorodov
-
August 20th, 2015, 09:16 AM
#48
Re: [win32] - avoid flicker and do a correct redraw
yes, but that may or may not cause correct painting... painting the background may be a necessary process. Failure to erase the background can cause "old stuff" to remain on screen and not go away.
Flicker happens because a pixel (or typically a group of pixels) is in one color, gets *temporarily* overwritten by some other color during an intermediary step. Then gets painted back in it's original color.
Since the screen updating is not usually (i can be on some videocards) synchronised with the screen refresh cycle, there are moments where you will see the "temporary" colored pixel, and that is what causes the disturbing flicker.
As I have said before (3x now), the best way to solve this kind of flicker is to prevent the intermediary stages from even making it to the screen. Which is achieved with making a memory DC, doing all intermediate painting onto the memory DC, then blit the resulting bitmap at once to screen. WS_EX_COMPOSITED has Windows attempt to do this on it's own, but it can't really fix flicker because the video can't know what are the intermediate stages and what aren't.
There are other screen artefacts that are sometimes called "flicker" but are actually entirely different beasts with different causes and solutions.
-
August 20th, 2015, 11:44 AM
#49
Re: [win32] - avoid flicker and do a correct redraw
Originally Posted by OReubens
yes, but that may or may not cause correct painting... painting the background may be a necessary process. Failure to erase the background can cause "old stuff" to remain on screen and not go away.
Flicker happens because a pixel (or typically a group of pixels) is in one color, gets *temporarily* overwritten by some other color during an intermediary step. Then gets painted back in it's original color.
Since the screen updating is not usually (i can be on some videocards) synchronised with the screen refresh cycle, there are moments where you will see the "temporary" colored pixel, and that is what causes the disturbing flicker.
As I have said before (3x now), the best way to solve this kind of flicker is to prevent the intermediary stages from even making it to the screen. Which is achieved with making a memory DC, doing all intermediate painting onto the memory DC, then blit the resulting bitmap at once to screen. WS_EX_COMPOSITED has Windows attempt to do this on it's own, but it can't really fix flicker because the video can't know what are the intermediate stages and what aren't.
There are other screen artefacts that are sometimes called "flicker" but are actually entirely different beasts with different causes and solutions.
by some reason i can't put the WS_EX_COMPOSITED working
but see these: the Invalidate() TRUE or FALSE(for clean the background or not) redraw the entire window inclued the child controls make them flickering. heres my WM_PAINT:
Code:
case WM_ERASEBKGND:
{
return TRUE;
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(inst->hwnd, &ps);
//draw a background on inst->imgForm
inst->imgForm.Brush(inst->clrBackColor);
pen test;
inst->imgForm.Pen(test);
inst->imgForm.DrawRectangle(0,0,inst->imgForm.width()+1, inst->imgForm.height()+1);//draw the backcolor
//call the Paint lambda
if (inst->Paint!=NULL)
inst->Paint((HDC)inst->imgForm);
//change the HDC backcolor\brush
FillRect(ps.hdc,&ps.rcPaint,(HBRUSH)CreateSolidBrush(inst->clrBackColor));
//TransparentBlt() for avoid overloading the pixel
TransparentBlt(ps.hdc, inst->pntScrollDC.x,inst->pntScrollDC.y , inst->imgForm.width(), inst->imgForm.height(), inst->imgForm,0 ,0, inst->imgForm.width(), inst->imgForm.height(), GetPixel(inst->imgForm,0,0));
EndPaint(inst->hwnd, &ps);
return 0;
}
break;
Code:
void Refresh()
{
RECT a={0,0,imgForm.width(),imgForm.height()};
InvalidateRect(hwnd, &a, FALSE);
}
i call the Refresh() using a timer animation. i get several flickers. i'm sorry, but i don't understand how avoid them
-
August 21st, 2015, 01:44 AM
#50
Re: [win32] - avoid flicker and do a correct redraw
Originally Posted by Cambalinho
heres my WM_PAINT:
Your paint handler must do only a single operation with physical DC (ps.hdc): XxxBlt between your physical DC and memory DC. All the other operations must be done only in memory DC. This is what OReubens constantly tells you, and you seem never hear him.
Last edited by Igor Vartanov; August 21st, 2015 at 02:46 AM.
Best regards,
Igor
-
August 21st, 2015, 04:57 AM
#51
Re: [win32] - avoid flicker and do a correct redraw
Originally Posted by Igor Vartanov
Your paint handler must do only a single operation with physical DC (ps.hdc): XxxBlt between your physical DC and memory DC. All the other operations must be done only in memory DC. This is what OReubens constantly tells you, and you seem never hear him.
Igor sorry if i make you think on that way. i hear everyone. i'm trying to understand more.
finally i understand why the WS_EX_COMPOSITED was not working.... for avoid a flicker i must do:
1 -avoid averrride pixels;
2 - use WS_EX_COMPOSITED and WS_CLIPCHILDREN on parent window, and WS_CLIPSIBLINGS on child window. if, when execute the program, we see a black color, so we invalidate it;
3 - InvalidateRect() refresh the window, but must be FALSE for not repaint the background and we do it on WM_PAINT;
4 - we avoid the CS_VREDRAW and CS_HREDRAW on style WNDCLASS member;
5 - the WM_ERASEBKGND(some child controls use another message) returns TRUE;
6 - we use Double-Buffering on WM_PAINT for, on end, we draw it only once. advice do the variables outside of WM_PAINT for save time and CPU and not, always recreate them.
now i have very less flickers.
Last edited by Cambalinho; August 21st, 2015 at 05:00 AM.
-
August 21st, 2015, 05:07 AM
#52
Re: [win32] - avoid flicker and do a correct redraw
i fix another flicker. but see these code:
Code:
case WM_ERASEBKGND:
{
return TRUE;
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(inst->hwnd, &ps);
//draw a background on inst->imgForm
inst->imgForm.Brush(inst->clrBackColor);
pen test;
inst->imgForm.Pen(test);
inst->imgForm.DrawRectangle(0,0,inst->imgForm.width()+1, inst->imgForm.height()+1);//draw the backcolor
//call the Paint lambda
if (inst->Paint!=NULL)
inst->Paint((HDC)inst->imgForm);
BitBlt(ps.hdc, inst->pntScrollDC.x, inst->pntScrollDC.y ,inst->imgForm.width(), inst->imgForm.height() , inst->imgForm,0 ,0, SRCCOPY);
RECT rctWindowUnPainted={inst->pntScrollDC.x+ inst->imgForm.width(),inst->pntScrollDC.y+inst->imgForm.height(),inst->imgForm.width(), inst->imgForm.height() };
FillRect(ps.hdc,&rctWindowUnPainted,(HBRUSH)CreateSolidBrush(inst->clrBackColor));
EndPaint(inst->hwnd, &ps);
return 0;
}
break;
my question is: why the redraw isn't clean?(see the image)
-
August 21st, 2015, 05:43 AM
#53
Re: [win32] - avoid flicker and do a correct redraw
I have no idea what your code does, so I have no answer to your question. If I were you, I would always fill the entire memDC with background color first, and only then painted the essential parts.
I can see scrolling somehow involved here, so you have to carefully revise your viewport logic.
Using the WM_PAINT Message
About Painting and Drawing
Last edited by Igor Vartanov; August 21st, 2015 at 05:51 AM.
Best regards,
Igor
-
August 21st, 2015, 06:37 AM
#54
Re: [win32] - avoid flicker and do a correct redraw
Code:
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(inst->hwnd, &ps);
//draw a background on inst->imgForm
inst->imgForm.Brush(inst->clrBackColor);
pen test;
inst->imgForm.Pen(test);
inst->imgForm.DrawRectangle(0,0,inst->imgForm.width()+1, inst->imgForm.height()+1);//draw the backcolor
//call the Paint lambda
if (inst->Paint!=NULL)
inst->Paint((HDC)inst->imgForm);
FillRect(ps.hdc,&ps.rcPaint,(HBRUSH)CreateSolidBrush(inst->clrBackColor));
BitBlt(ps.hdc, inst->pntScrollDC.x, inst->pntScrollDC.y ,inst->imgForm.width(), inst->imgForm.height() , inst->imgForm,0 ,0, SRCCOPY);
EndPaint(inst->hwnd, &ps);
return 0;
}
doing these, is redrawing correctly. but do the flickers
-
August 21st, 2015, 07:50 AM
#55
Re: [win32] - avoid flicker and do a correct redraw
now see these code:
Code:
case WM_ERASEBKGND:
{
return TRUE;
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(inst->hwnd, &ps);
//inst is the form object pointer
//imgForm is my image object
//draw a background on imgForm
inst->imgForm.Brush(inst->clrBackColor);
pen test;
inst->imgForm.Pen(test);
inst->imgForm.DrawRectangle(0,0,inst->imgForm.width()+1, inst->imgForm.height()+1);//draw the backcolor
//call the Paint lambda
if (inst->Paint!=NULL)
inst->Paint((HDC)inst->imgForm);
//draw the form background
FillRect(ps.hdc,&ps.rcPaint,(HBRUSH)CreateSolidBrush(inst->clrBackColor));
//draw the imgForm without the background color
TransparentBlt(ps.hdc, inst->pntScrollDC.x, inst->pntScrollDC.y ,inst->imgForm.width(), inst->imgForm.height() , inst->imgForm,0 ,0, inst->imgForm.width(), inst->imgForm.height(), GetPixel(inst->imgForm, 0,0));
EndPaint(inst->hwnd, &ps);
return 0;
}
break;
now, maybe you can understand it.
- 1st i must draw the form background color on Client Rect;
- then i draw the image where i need it.... i use transparent for avoid more the flicker. the image can be on or out of Client Rect.
-
August 21st, 2015, 08:22 AM
#56
Re: [win32] - avoid flicker and do a correct redraw
finally i came with 1 thot. i did 1 temp image for draw the background with image in scroll way:
Code:
case WM_ERASEBKGND:
{
return TRUE;
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(inst->hwnd, &ps);
//inst is the form object pointer
//imgForm is my image object
//creating a temp image for draw the background color and the image on scroll way
image imgTemp(inst->imgForm.width(), inst->imgForm.height());
//draw the background color on temp image
imgTemp.Brush(inst->clrBackColor);
pen test;
imgTemp.Pen(test);
imgTemp.DrawRectangle(0,0,inst->imgForm.width()+1, inst->imgForm.height()+1);//draw the backcolor
//draw a background on imgForm
inst->imgForm.Brush(inst->clrBackColor);
inst->imgForm.Pen(test);
inst->imgForm.DrawRectangle(0,0,inst->imgForm.width()+1, inst->imgForm.height()+1);//draw the backcolor
//call the Paint lambda
if (inst->Paint!=NULL)
inst->Paint((HDC)inst->imgForm);
//imgTemp will recive the image on scroll way
inst->imgForm.draw(imgTemp,inst->pntScrollDC.x, inst->pntScrollDC.y);
//draw the entire image(the temp image) to HDC window
BitBlt(ps.hdc,0,0,inst->imgForm.width(), inst->imgForm.height(),imgTemp,0,0, SRCCOPY);
EndPaint(inst->hwnd, &ps);
return 0;
}
break;
now works fine and no flicker that i see
thanks for all to all.
i hope the thread help more readers with these subject. that's it's complicated at 1st.
thanks
-
August 21st, 2015, 09:05 AM
#57
Re: [win32] - avoid flicker and do a correct redraw
Originally Posted by Cambalinho
//draw the entire image(the temp image) to HDC window
BitBlt(ps.hdc,0,0,inst->imgForm.width(), inst->imgForm.height(),imgTemp,0,0, SRCCOPY);
and this is what I've been saying all along. use a SINGLE paint to screen.
in the previous ones you still had
-> paint everything black
-> paint image on top of black
put that in a loop and you'll see alternating black and image => flicker
-
August 21st, 2015, 12:13 PM
#58
Re: [win32] - avoid flicker and do a correct redraw
Originally Posted by OReubens
and this is what I've been saying all along. use a SINGLE paint to screen.
in the previous ones you still had
-> paint everything black
-> paint image on top of black
put that in a loop and you'll see alternating black and image => flicker
don't be mad with me. i was trying.... and we fix it
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|