버그 해결을 위한 모든 질문을 던져
+1 vote
249 views

 

사각형을 이동시키는데 자연스럽게 이동되지않고 깨지면서 이동됩니다.

 

 

이런 현상을 티어링(tearing) 현상이라고 알고있는데요.

혼자서는 도저히 고치질 못하겠어서 고수님들의 조언을 부탁드립니다.

그리는 코드는 아래와 같구요. 풀 코드는 첨부파일로 올립니다. 혹시 지나가다 한번만 봐주시면 정말 감사하겠습니다.

void CTopNavigation::OnPaint()
{
	CPaintDC dc(this); // device context for painting
					   // TODO: 여기에 메시지 처리기 코드를 추가합니다.
					   // 그리기 메시지에 대해서는 CStatic::OnPaint()을(를) 호출하지 마십시오.

	CRect rect;
	GetClientRect(&rect);

	Gdiplus::Graphics mainG(dc.GetSafeHdc());

	// 메모리 생성
	Gdiplus::Bitmap memBmp(rect.Width(), rect.Height());
	{
		Gdiplus::Graphics memG(&memBmp);
		memG.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);

		// 잔상을 없애기 위해 white 채움.
		Gdiplus::SolidBrush brs(Gdiplus::Color::White);
		memG.FillRectangle(&brs, 0, 0, rect.Width(), rect.Height());

		// 메모리상에 그리는 부분
		drawBackground(&memG);	// 배경 그리기
		drawRectangle(&memG);	// 사각형 그리기
	}
	mainG.DrawImage(&memBmp,0,0);
}

 

풀코드

asked (3 point) , 249 views
더블버퍼링을 하셔야 합니다. 더블버퍼링으로 검색해보시면 참고자료를 찾으실 수 있을껍니다.

1 답변

+2 votes
결론부터 말씀드리면 불가능합니다.

c++에서 DirectX로 만드시거나, c#에서 SlimDX를 쓰셔야 합니다. (혹은 OpenGL)

소스를 보니까 백버퍼 개념으로 이미지를 하나 만들고, 거기에 배경과 사각형을 그리고

마지막에 백버퍼로 쓴 그 이미지를 한번에 그리게 되어 있는데요.

그게 바로 더블 버퍼링 개념입니다.

그러니까 이미 더블 버퍼링을 하고 계시는 겁니다.

백버퍼를 만드는 이유는 프런트 버퍼가 준비 되었을 때 최대한 빨리 이미지를 그리기 위한 준비작업 같은 겁니다.

그런데, 테어링을 막으려면 프런트 버퍼의 갱신주기를 기다렸다가 적절한 타이밍에 백버퍼의 내용을 프런트 버퍼로 옮겨야 하는데요.

그걸 vsync(수직 동기화)라고 합니다. vsync 기능이 없으면 테어링을 막을 수 없습니다.

즉, 더블 버퍼링을 하는 것만으로 테어링이 해결되는 게 아닙니다.

문제는 GDI나 GDI+에는 vsync 기능이 아예 존재하질 않는다는 겁니다.

그건 DirectX나 OpenGL에서만 가능한 기능입니다.
answered (445 point)

버그 해결을 위해 도움을 구하고, 도움을 주세요. 우리는 그렇게 발전합니다.

throw bug 는 프로그래밍에 대한 전분야를 다룹니다. 질문,논의거리,팁,정보공유 모든 것이 가능합니다. 프로그래밍과 관련이 없는 내용은 환영받지 못합니다.

184 질문
286 answers
311 댓글
304 users