CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Jun 1999
    Posts
    505

    [RESOLVED] Flickering in animation

    Hi,
    I have done this program in TC. But now I am trying to port this code to VC. I am getting flickering. Earlier I was advised on this forum to use SetTimer instead of for loops for avoiding flickering but still my prob persists.

    I have got three functions: road, mountain and stationary_car. These are called from OnDraw(...) method.
    I have used the SetTimer concept. But when I am executing this program, its producing lots of
    flickering. Kindly somebody help me plz. I am using VS2005 under XP.

    Zulfi.


    Code:
    void CTestG1View::mountain(CDC* pDC)
    {
    	//setcolor(BROWN);
    	CPen penBrown(PS_SOLID, 5, RGB(150,75,0));
    	CPen* pOldPen=NULL;
    	pOldPen=pDC->SelectObject(&penBrown);
    	//line(0,250,700,250);
    	pDC->MoveTo(0,250);
    	pDC->LineTo(700,250);
    	//line(0,250,0,160);
    	pDC->MoveTo(0,250);
    	pDC->LineTo(0,160);
    	//line(0,160,30,200);
    	pDC->MoveTo(0,160);
    	pDC->LineTo(30,200);
    	//line(30,200,80,120);
    	pDC->MoveTo(30,200);
    	pDC->LineTo(80,120);
        //arc(90,124,30,150,10);
    	pDC->AngleArc(90,124,10,30,150);
    	//line(99,119,150,180);
    	pDC->MoveTo(99,119);
    	pDC->LineTo(150,180);
    	//line(150,180,220,100);
    	pDC->MoveTo(150,180);
    	pDC->LineTo(220,100);
    	//arc(234,106,30,150,15);
    	pDC->AngleArc(234,106,15,30,150);
    	//line(248,99,320,200);
    	pDC->MoveTo(248,99);
    	pDC->LineTo(320,200);
    	//line(320,200,370,125);
    	pDC->MoveTo(320,200);
    	pDC->LineTo(370,125);
    	//arc(380,129,30,150,10);
    	pDC->AngleArc(380,129,10,30,150);
    	//line(389,124,430,180);
    	pDC->MoveTo(389,124);
    	pDC->LineTo(430,180);
    	//line(430,180,505,90);
    	pDC->MoveTo(430,180);
    	pDC->LineTo(505,90);
    	//arc(519,96,30,150,15);
    	pDC->AngleArc(519,96,15,30,150);
    	//line(533,89,605,200);
    	pDC->MoveTo(533,89);
    	pDC->LineTo(605,200);
    	//line(605,200,700,110);
    	pDC->MoveTo(605,200);
    	pDC->LineTo(700,170);
    	//line(700,170,700,250);
    	pDC->MoveTo(700,170);
    	pDC->LineTo(700,250);
    	CBrush brBrown(RGB(150, 75, 0));
    	CBrush* pOldBrush=NULL;
    	pOldBrush=pDC->SelectObject(&brBrown);
    	pDC->FloodFill(10,245,RGB(150,75,0));
    	pDC->SelectObject(pOldBrush);
    	pDC->SelectObject(pOldPen);
    	
    }
    
    CTestG1View::CTestG1View()
    {
    	// TODO: add construction code here
    	i=150,j=190,k=145,l=140,m=138,n=195,o=197,p=170,q=148,r=185;
    	penGrey.CreatePen(PS_SOLID, 5, RGB(128,128,128));//GREY color
    	penLGrey.CreatePen(PS_SOLID,5, RGB(220,220,220));//LGREY color
    	penBlack.CreatePen(PS_SOLID, 5, RGB(0,0,0));
    	pOldPen=NULL;
    	brGrey.CreateSolidBrush(RGB(128, 128, 128));
    	brLGrey.CreateSolidBrush(RGB(220,220,220));
    	brBlack.CreateSolidBrush(RGB(0, 0, 0));
    	pOldBrush=NULL;
    	
    }
    
    int CTestG1View::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    	if (CView::OnCreate(lpCreateStruct) == -1)
    		return -1;
    	//void (*p)(UINT);
    	//p=&CTestG1View::OnTimer;
    	SetTimer(1,200,NULL);
    	// TODO:  Add your specialized creation code here
    
    	return 0;
    }    
    
    void CTestG1View::OnTimer(UINT  nIDEvent){
    	if(i>0){
    	i=i-3;
    	Invalidate();
    	j=j-3;k=k-3;l=l-3;m=m-3;n=n-3;o=o-3;p=p-3;q=q-3;r=r-3;
    	}
    }
    void CTestG1View::OnDraw(CDC* pDC)
    {
    	CTestG1Doc* pDoc = GetDocument();
    	ASSERT_VALID(pDoc);
    	if (!pDoc)
    		return;
    	road(pDC);
    	mountain(pDC);
    	stationary_car(pDC);
    	//moving_car(pDC);
    	// TODO: add draw code for native data here
    }
    void CTestG1View::stationary_car(CDC* pDC)
    {
    	//int i=150,j=190,k=145,l=140,m=138,n=195,o=197,p=170,q=148,r=185;
    	//CPen penGrey(PS_SOLID, 5, RGB(128,128,128));//GREY color
    	CPen* pOldPen=NULL;
    	pOldPen=pDC->SelectObject(&penGrey);
    	//line(i,402,j,402);
    	pDC->MoveTo(i,402);
    	pDC->LineTo(j,402);
    	//line(j,415,k,415);
    	pDC->MoveTo(j,415);
    	pDC->LineTo(k,415);
    	//line(j,402,j,415);
    	pDC->MoveTo(j,402);
    	pDC->LineTo(j,415);
    	//line(k,415,i,402);
    	pDC->MoveTo(k,415);
    	pDC->LineTo(i,402);
    	//setfillstyle(SOLID_FILL,6);
    	//CBrush brGrey(RGB(128, 128, 128));
    	CBrush* pOldBrush=NULL;
    	//floodfill(p,408,6);
    	//NOTE IF FloodFill done after select object, color mixing would occur 
    	pOldBrush=pDC->SelectObject(&brGrey);
    	pDC->FloodFill(p,408,RGB(128,128,128));
    	//line(n,415,o,428);
    	pDC->MoveTo(n,415);
    	pDC->LineTo(o,428);
    	//line(l,415,m,428);
    	pDC->MoveTo(l,415);
    	pDC->LineTo(m,428);
    	//line(l,415,n,415);
    	pDC->MoveTo(l,415);
    	pDC->LineTo(n,415);
    	//line(o,428,m,428);
    	pDC->MoveTo(o,428);
    	pDC->LineTo(m,428);
    	//setfillstyle(SOLID_FILL,6);
    	//floodfill(p,422,6);
    	pDC->FloodFill(p,422,RGB(128,128,128));
    	pDC->SelectObject(pOldBrush);
    	pDC->SelectObject(pOldPen);
    	//Drawing wheels
    	//circle(q,434,5);
    	CBrush brBlack(RGB(0, 0, 0));
    	pOldBrush=NULL;
    	pOldBrush=pDC->SelectObject(&brBlack);
    	//CPen penBlack(PS_SOLID, 5, RGB(0,0,0));//Black color
    	pOldPen=NULL;
    	pOldPen=pDC->SelectObject(&penBlack);
    	pDC->MoveTo(r,434);
    	pDC->AngleArc(q,434,5,0,360);
    	pDC->FloodFill(q,434,RGB(0,0,0));
    	//circle(r,434,5);
    	pDC->AngleArc(r,434,5,0,360);
    	pDC->SelectObject(pOldPen);
    	pDC->SelectObject(pOldBrush);
    	
    }
    
    void CTestG1View::road(CDC* pDC){ 
    	CPoint poly6[8]={CPoint(0,400), CPoint(210,400),CPoint(210,440),CPoint(0,440)};
    	CPen pen(PS_SOLID, 5, RGB(220,220,220));
    	CPen* pOldPen=NULL;
    	pOldPen=pDC->SelectObject(&pen);
    	CBrush br(RGB(220, 220, 220));
    	CBrush* pOldBrush=NULL;
    	pOldBrush=pDC->SelectObject(&br);
    	pDC->Polygon(poly6, 4);
    	pDC->SelectObject(pOldBrush);
    	pDC->SelectObject(pOldPen);
    	}
    
    
    
    / TestG1View.h : interface of the CTestG1View class
    //
    
    
    #pragma once
    
    
    class CTestG1View : public CView
    {
    protected: // create from serialization only
    	CTestG1View();
    	DECLARE_DYNCREATE(CTestG1View)
    
    // Attributes
    	int i,j,k,l,m,n,o,p,q,r;
    	CPen penGrey, penLGrey, penBlack, *pOldPen;
        CBrush brGrey, brLGrey, *pOldBrush, brBlack;
    public:
    	CTestG1Doc* GetDocument() const;
    
    // Operations
    	void road(CDC*);
    	void stationary_car(CDC*);
    	void mountain(CDC*);
    	
    public:
    
    // Overrides
    public:
    	virtual void OnDraw(CDC* pDC);  // overridden to draw this view
    	virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
    protected:
    	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
    	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
    	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
    
    // Implementation
    public:
    	virtual ~CTestG1View();
    #ifdef _DEBUG
    	virtual void AssertValid() const;
    	virtual void Dump(CDumpContext& dc) const;
    #endif
    
    protected:
    
    // Generated message map functions
    	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
    	afx_msg void OnTimer( UINT nIDEvent );
    protected:
    	DECLARE_MESSAGE_MAP()
    };
    
    #ifndef _DEBUG  // debug version in TestG1View.cpp
    inline CTestG1Doc* CTestG1View::GetDocument() const
       { return reinterpret_cast<CTestG1Doc*>(m_pDocument); }
    #endif

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Flickering in animation

    Are you using a double-buffered render context?

  3. #3
    Join Date
    Jun 1999
    Posts
    505

    Re: Flickering in animation

    I have not worked on double buffering but as you can see from my code that I am placing the image directly on the screen in a periodic fashion.

    Zulfi.

  4. #4
    Join Date
    Jul 2002
    Location
    Portsmouth. United Kingdom
    Posts
    2,727

    Re: Flickering in animation

    The usual trick is to draw onto a local CDC, created from the display one using 'CreateCompatibleDC' and then BitBlt it to the display CDC.

    Check out some of the facilities provided by GDI+ too.
    "It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
    Richard P. Feynman

  5. #5
    Join Date
    Jun 1999
    Posts
    505

    Re: Flickering in animation

    Hi,

    I am now using double buffering but still I am getting jerks. Car is not visible. I am not able to figure out the correct values for BitBlt. Can somebody plz look at this code:
    Code:
    void CTestG1View::mountain(CDC* pDC)
    {
    	//setcolor(BROWN);
    	CPen penBrown(PS_SOLID, 5, RGB(150,75,0));
    	CPen* pOldPen=NULL;
    	pOldPen=pDC->SelectObject(&penBrown);
    	//line(0,250,700,250);
    	pDC->MoveTo(0,250);
    	pDC->LineTo(700,250);
    	//line(0,250,0,160);
    	pDC->MoveTo(0,250);
    	pDC->LineTo(0,160);
    	//line(0,160,30,200);
    	pDC->MoveTo(0,160);
    	pDC->LineTo(30,200);
    	//line(30,200,80,120);
    	pDC->MoveTo(30,200);
    	pDC->LineTo(80,120);
        //arc(90,124,30,150,10);
    	pDC->AngleArc(90,124,10,30,150);
    	//line(99,119,150,180);
    	pDC->MoveTo(99,119);
    	pDC->LineTo(150,180);
    	//line(150,180,220,100);
    	pDC->MoveTo(150,180);
    	pDC->LineTo(220,100);
    	//arc(234,106,30,150,15);
    	pDC->AngleArc(234,106,15,30,150);
    	//line(248,99,320,200);
    	pDC->MoveTo(248,99);
    	pDC->LineTo(320,200);
    	//line(320,200,370,125);
    	pDC->MoveTo(320,200);
    	pDC->LineTo(370,125);
    	//arc(380,129,30,150,10);
    	pDC->AngleArc(380,129,10,30,150);
    	//line(389,124,430,180);
    	pDC->MoveTo(389,124);
    	pDC->LineTo(430,180);
    	//line(430,180,505,90);
    	pDC->MoveTo(430,180);
    	pDC->LineTo(505,90);
    	//arc(519,96,30,150,15);
    	pDC->AngleArc(519,96,15,30,150);
    	//line(533,89,605,200);
    	pDC->MoveTo(533,89);
    	pDC->LineTo(605,200);
    	//line(605,200,700,110);
    	pDC->MoveTo(605,200);
    	pDC->LineTo(700,170);
    	//line(700,170,700,250);
    	pDC->MoveTo(700,170);
    	pDC->LineTo(700,250);
    	CBrush brBrown(RGB(150, 75, 0));
    	CBrush* pOldBrush=NULL;
    	pOldBrush=pDC->SelectObject(&brBrown);
    	pDC->FloodFill(10,245,RGB(150,75,0));
    	pDC->SelectObject(pOldBrush);
    	pDC->SelectObject(pOldPen);
    	
    }
    
    CTestG1View::CTestG1View()
    {
    	// TODO: add construction code here
    	i=150,j=190,k=145,l=140,m=138,n=195,o=197,p=170,q=148,r=185;
    	penGrey.CreatePen(PS_SOLID, 5, RGB(128,128,128));//GREY color
    	penLGrey.CreatePen(PS_SOLID,5, RGB(220,220,220));//LGREY color
    	penBlack.CreatePen(PS_SOLID, 5, RGB(0,0,0));
    	pOldPen=NULL;
    	brGrey.CreateSolidBrush(RGB(128, 128, 128));
    	brLGrey.CreateSolidBrush(RGB(220,220,220));
    	brBlack.CreateSolidBrush(RGB(0, 0, 0));
    	pOldBrush=NULL;
    	
    }
    
    int CTestG1View::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    	if (CView::OnCreate(lpCreateStruct) == -1)
    		return -1;
    	//void (*p)(UINT);
    	//p=&CTestG1View::OnTimer;
    	SetTimer(1,200,NULL);
    	// TODO:  Add your specialized creation code here
    
    	return 0;
    }    
    
    void CTestG1View::OnTimer(UINT  nIDEvent){
    	if(i>0){
    	i=i-3;
    	Invalidate();
    	j=j-3;k=k-3;l=l-3;m=m-3;n=n-3;o=o-3;p=p-3;q=q-3;r=r-3;
    	}
    }
    void CTestG1View::road(CDC* pDC){ 
    	CPoint poly6[8]={CPoint(0,400), CPoint(210,400),CPoint(210,440),CPoint(0,440)};
    	CPen pen(PS_SOLID, 5, RGB(220,220,220));
    	CPen* pOldPen=NULL;
    	pOldPen=pDC->SelectObject(&pen);
    	CBrush br(RGB(220, 220, 220));
    	CBrush* pOldBrush=NULL;
    	pOldBrush=pDC->SelectObject(&br);
    	pDC->Polygon(poly6, 4);
    	pDC->SelectObject(pOldBrush);
    	pDC->SelectObject(pOldPen);
    	}
    
    
    void CTestG1View::stationary_car(CDC* pDC)
    {
    	//int i=150,j=190,k=145,l=140,m=138,n=195,o=197,p=170,q=148,r=185;
    	//CPen penGrey(PS_SOLID, 5, RGB(128,128,128));//GREY color
    	CBitmap XMap,*pOldMap;
    	CPen* pOldPen=NULL;
    	pOldPen=pDC->SelectObject(&penGrey);
    	SIZE Size;
        Size.cx = GetSystemMetrics(SM_CXSCREEN);
        Size.cy = GetSystemMetrics(SM_CYSCREEN);
    	XMap.CreateCompatibleBitmap(pDC,Size.cx,Size.cy);
    	CDC WorkDC;
    	CDC *MyDC=&WorkDC;
    	MyDC->CreateCompatibleDC(pDC);
    	pOldMap=MyDC->SelectObject(&XMap);
    	//line(i,402,j,402);
    	MyDC->MoveTo(i,402);
    	MyDC->LineTo(j,402);
    	//line(j,415,k,415);
    	MyDC->MoveTo(j,415);
    	MyDC->LineTo(k,415);
    	//line(j,402,j,415);
    	MyDC->MoveTo(j,402);
    	MyDC->LineTo(j,415);
    	//line(k,415,i,402);
    	MyDC->MoveTo(k,415);
    	MyDC->LineTo(i,402);
    	//setfillstyle(SOLID_FILL,6);
    	//CBrush brGrey(RGB(128, 128, 128));
    	CBrush* pOldBrush=NULL;
    	//floodfill(p,408,6);
    	//NOTE IF FloodFill done after select object, color mixing would occur 
    	pOldBrush=MyDC->SelectObject(&brGrey);
    	MyDC->FloodFill(p,408,RGB(128,128,128));
    	//line(n,415,o,428);
    	MyDC->MoveTo(n,415);
    	MyDC->LineTo(o,428);
    	//line(l,415,m,428);
    	MyDC->MoveTo(l,415);
    	MyDC->LineTo(m,428);
    	//line(l,415,n,415);
    	MyDC->MoveTo(l,415);
    	MyDC->LineTo(n,415);
    	//line(o,428,m,428);
    	MyDC->MoveTo(o,428);
    	MyDC->LineTo(m,428);
    	//setfillstyle(SOLID_FILL,6);
    	//floodfill(p,422,6);
    	MyDC->FloodFill(p,422,RGB(128,128,128));
    	MyDC->SelectObject(pOldBrush);
    	MyDC->SelectObject(pOldPen);
    	//Drawing wheels
    	//circle(q,434,5);
    	CBrush brBlack(RGB(0, 0, 0));
    	pOldBrush=NULL;
    	pOldBrush=MyDC->SelectObject(&brBlack);
    	//CPen penBlack(PS_SOLID, 5, RGB(0,0,0));//Black color
    	pOldPen=NULL;
    	pOldPen=MyDC->SelectObject(&penBlack);
    	MyDC->MoveTo(r,434);
    	MyDC->AngleArc(q,434,5,0,360);
    	MyDC->FloodFill(q,434,RGB(0,0,0));
    	//circle(r,434,5);
    	MyDC->AngleArc(r,434,5,0,360);
    	pDC->BitBlt(j,k,Size.cx,Size.cy,MyDC,0,0,SRCCOPY);
    	MyDC->SelectObject(pOldPen);
    	MyDC->SelectObject(pOldBrush);
    	MyDC->SelectObject(pOldMap);
    	XMap.DeleteObject();
    	MyDC->DeleteDC();
    
    }
    
    void CTestG1View::OnDraw(CDC* pDC)
    {
    	CTestG1Doc* pDoc = GetDocument();
    	ASSERT_VALID(pDoc);
    	if (!pDoc)
    		return;
    	road(pDC);
    	mountain(pDC);
    	stationary_car(pDC);
    	//moving_car(pDC);
    	// TODO: add draw code for native data here
    }

  6. #6
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    Re: Flickering in animation

    For the double buffering you should create your memory device context and bitmap in your OnDraw handler. For example:
    Code:
      // Get client rectangle
      CRect rc;
      GetClientRect(&rc);
      // Create memory device context for double buffering
      CDC dcMem;
      dcMem.CreateCompatibleDC(pDC);
      // Create memory bitmap for double buffering
      CBitmap bmpMem;
      bmpMem.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());
      // Select the bitmap into the device context
      CBitmap* pOldBmp = dcMem.SelectObject(&bmpMem);
      // render our stuff
      road(&dcMem);
      mountain(&dcMem);
      stationary_car(&dcMem);
      // Blit the memory bitmap to the screen.
      pDC->BitBlt(0, 0, rc.Width(), rc.Height(), &dcMem, 0, 0, SRCCOPY);
      // Select old bitmap again
      dcMem.SelectObject(pOldBmp);
    After that remove all double buffering code from the other functions. It should only be in the OnDraw function.
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  7. #7
    Join Date
    Jun 1999
    Posts
    505

    Re: Flickering in animation

    I have made changes in the OnDraw (...) but I am still getting flickering & the unpainted white space becomes black.
    Kindly help me with this code.

    Zulfi.
    Code:
    void CTestG1View::OnDraw(CDC* pDC)
    {
    	CTestG1Doc* pDoc = GetDocument();
    	ASSERT_VALID(pDoc);
    	if (!pDoc)
    		return;
    	CBitmap XMap,*pOldMap;
    	CRect rc;
        GetClientRect(&rc);
    	XMap.CreateCompatibleBitmap(pDC,rc.Width(), rc.Height());
    	CDC WorkDC;
    	CDC *MyDC=&WorkDC;
    	MyDC->CreateCompatibleDC(pDC);
    	pOldMap=MyDC->SelectObject(&XMap);
    	road(MyDC);
    	mountain(MyDC);
    	stationary_car(MyDC);
    	pDC->BitBlt(0, 0, rc.Width(), rc.Height(), MyDC, 0, 0, SRCCOPY);
    	MyDC->SelectObject(pOldMap);
    	XMap.DeleteObject();
    	MyDC->DeleteDC();
    	//moving_car(pDC);
    	// TODO: add draw code for native data here
    }

  8. #8
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150

    Re: Flickering in animation

    To get rid of the flickering, handle WM_ERASEBKGND and just return TRUE in it.
    To get rid of the black, you need to paint the entire memory DC in the color you want before starting to paint your road etc. You can use FillRect for this.
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  9. #9
    Join Date
    Jun 1999
    Posts
    505

    Re: Flickering in animation

    Thanks everybody. Its working now.

    Zulfi.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured