2010-03-15 5 views
6

WinForms 앱에서 18.66666 ... 초당 프레임 수 (140 BPM의 음악과 동기화 됨, 프레임 속도가 이상한 이유)로 애니메이션을 실행하고 있습니다. 애니메이션의 각 셀은 사전 계산되고 애니메이션은 고해상도 멀티미디어 타이머에 의해 구동됩니다. 애니메이션 자체는 매끄 럽지 만 화면이 새로 고침되어 중간에 고양이가 잡히는 결과 인 "찢어짐"이 상당량 발생합니다.애니메이션에서 찢어짐을 제거하는 방법은 무엇입니까?

내 프로그램에서 렌더링 한 셀 집합을 가져 와서 AVI 파일에 기록한 다음 Windows Media Player에서 AVI 파일을 재생할 때 전혀 찢어지지 않는 것을 볼 수 있습니다. DirectX (또는 다른 것)를 사용하고 화면의 새로 고침 활동과 렌더링을 동기화 할 수 있기 때문에 WMP가 파일을 부드럽게 재생한다고 가정합니다. 애니메이션이 오디오와 동기화되어 있기 때문에 프레임 속도는 변경되지 않습니다.

WMP가 찢어지지 않고 애니메이션을 렌더링 할 수있는 이유는 무엇입니까? 아니면 뭔가 빠져 있습니까? 내 프로그램이 현재 스캔 라인이 어디에 있는지를 알 수 있도록 DirectX (또는 다른 것)를 사용할 수있는 방법이 있습니까? 그렇다면 실제로 DirectX를 사용하지 않고도이 정보를 사용하여 찢어짐을 제거 할 수있는 방법이 있습니다. 셀을 표시하기 위해? 아니면이 문제를 해결하기 위해 렌더링을 위해 DirectX를 완전히 사용해야합니까?

업데이트 : 세부 정보를 잊어 버렸습니다. 내 응용 프로그램은 Graphics.DrawImage를 사용하여 각 셀을 PictureBox에 렌더링합니다. 이것은 BitBlt를 사용하는 것보다 상당히 느려서 BitBlt를 사용하여 적어도 일부는 찢어지는 것을 제거 할 수 있습니까?

업데이트 2 : 내가 보는 효과는 분명히 깜박 거리지 않습니다 (이는 찢어짐과 다릅니다). 내 패널은 이중 버퍼링되고 AllPaintingInWmPaint, UserPaint, OptimizedDoubleBuffer 등의 컨트롤 스타일을 설정하고 onPaintBackGround를 재정의하는 등의 작업을 수행합니다. 이 모든 것들이 깜박 거림을 없애기 위해 필요하지만, 찢어지는 문제는 여전히 남아 있습니다. 애니메이션이 매우 빠르게 움직이는 물체 나 빛에서 어두움으로 변화하는 물체를 매우 빠르게 가질 때 특히 두드러집니다. 물체가 느리게 움직이고 색이 빠르게 변하지 않는 경우, 연속적인 셀이 항상 서로 매우 유사하기 때문에 눈물이 나지 않는 효과가 눈에 띄지 않습니다.

+0

별도의 스레드에서 렌더링을 실행하고 있습니까? –

+0

@Ardman : 예, 렌더링은 별도의 스레드 (UI 스레드와 별도)에서 수행됩니다. – MusiGenesis

답변

3

이미지가 모니터의 재생 빈도와 동기화되지 않을 때 끊어짐이 발생합니다. 모니터에는 새 이미지의 일부인 이전 이미지의 일부가 표시됩니다. 이미지의 오브젝트가 빠르게 움직일 때 그 효과는 상당히 눈에.니다.

Windows Forms에서는 수정할 수 없지만 비디오 어댑터의 v-sync 신호에는 연결할 수 없습니다. DirectX app에 있습니다.

0

그런 작업에는 directx (또는 OpenGL)를 사용하는 것이 좋습니다. 그러나 winforms 만 사용하려면 DoubleBuffered 속성을 사용하십시오.

+1

나는 DoubleBuffered를 사용하여 깜박임 현상을 없애지 만, 찢어 지는데 도움이되지 않습니다. – MusiGenesis

+0

또한, Mono와의 크로스 플랫폼을 만들기 위해 노력하고 있습니다. 가능한 경우 DirectX와 같은 플랫폼 관련 사항을 피하고 싶습니다. – MusiGenesis

+0

그래서 opengl을 사용하십시오! 그것은 directx의 크로스 플랫폼 아날로그입니다. 글쎄, 난 winforms 십자가 아니라고 생각 pl. – Andrey

0

이중 버퍼링.

Windows 스타일을 사용하여 이중 버퍼링을 사용하도록 설정할 수 있습니다. 또는 화면에서 그림으로 그려서 전환하는 것이 더 쉽습니다.

이것이 작동하지 않는다면 가장 좋은 방법은 비트 블릿과 더블 버퍼입니다.

본질적으로 동일합니다.

두 비트 맵에 대한 참조가 있는데, 하나는 화면이고 다른 하나는 버퍼입니다. 먼저 버퍼에 그린 다음 그 전체를 화면에 blit합니다. 이렇게하면 라이브 데이터 만 버퍼에 쓸 수 있습니다. sceen은 이전에 만든 것 (파란색 피터 스타일)을 보여줍니다.

+2

죄송합니다. 제 질문에 더 분명하게 대답 했어야합니다. 이중 버퍼링 (이미 사용하고있는)은 찢어지는 효과가 없습니다. – MusiGenesis

+0

아, 걱정할 필요가 없습니다. 그림 상자를 사용하지 말고 직접 화면에 씁니다. (이중 버퍼링 사용) – Chris

2

현재 제가 작업하고있는 프로젝트에서 이중 버퍼링 아이디어를 시도했지만 그로 인해 아주 좋은 결과를 얻지 못했습니다. 결국, 나는 다음을 만들었습니다 :

  1. A 오프 스크린 버퍼를위한 System.Drawing.Bitmap. 애니메이션을이 비트 맵으로 디코딩하십시오.
  2. UserControl은 (1)의 이미지와 크기가 같고 OnPaintBackground 메서드가 비어있는 경우 (드로잉 및 기본 클래스 호출이없는 경우) OnPaint는 화면에 오프 스크린 이미지를 복사하기 위해 Graphics.DrawImage를 수행했습니다.

이제 애니메이션 속도가 이상해지기 때문에 화면 업데이트 속도와 화면 재생 빈도의 불일치가 거의 발생합니다. 화면의 새로 고침 중간에 화면을 업데이트하므로 화면 상단에 이전 프레임이 표시되고 화면 하단에는 새 프레임이 그려집니다. 프레임 속도와 화면 재생 빈도를 동기화 할 수 있으면 끊어짐이 없어야합니다.

+1

2 개의 비트 맵을 오프 스크린 버퍼로 사용하기는하지만 필자가 설명하는 것은 본질적입니다. 그래서 다른 하나가 그려지는 동안 업데이트 할 수 있습니다 화면에. 내 애니메이션을 새로 고침 빈도 (60Hz)와 동기화하려고 시도하고 그 결과가 나를 위해 무엇을하는지 봅니다. – MusiGenesis

0

찢어짐은 다른 프레임 위에 그려지는 프레임의 아티팩트입니다. 그것을 피할 수있는 유일한 안전한 방법은 a) vsync에서 기다리거나 b) 빔 뒤에서 그리는 것입니다 (이것은 다소 까다 롭습니다). Double buffer만으로도 버퍼가 두 배가되지만 vsync가 꺼져 있기 때문에 찢어지지 않을 수 있습니다. 일부 카드에는 vsync 대기 옵션 "강제 종료"가있을 수도 있습니다. vsync에 관한 문서와 그 위치를 확인하는 방법을 확인해야합니다. 이것이 유일한 방법입니다. 또한 이것이 프레임 속도를 잠글 것임을 명심하십시오.

+1

WMP가 찢어지지 않고 잘 렌더링 할 수 있기 때문에 애니메이션을 음악과 동기화해야하기 때문에 선택한 프레임 속도로 프레임을 찢지 않고 애니메이션을 만들 수있는 방법이 있어야합니다 (프레임 속도는 제한되어 있습니다). 어쩌면 WMP는 어떤 종류의 프레임 간 보간을합니까? – MusiGenesis

관련 문제