2020년 11월 13일 금요일

C#에서의 더블버퍼링(Double Buffering)

일반적으로 윈도우의 DC에 그림을 그리면 그릴 때마다 번쩍거리는 현상이 일어납니다. 이러한 현상을 막기 위해 Double Buffering이라는 기법을 사용합니다.

이것은 화면을 두개 마련해 놓고, 뒤 화면에 그림을 그린 후 한번에 앞쪽으로 옮기는 방법이죠.

다른 언어에서는 화면을 두개 만드는 것부터 어렵지만 C#에서는 상당히 쉽게 되는군요.

C#에서 다음과 같은 Form Application으로 form과 panel을 만들었습니다.


그리고 양쪽에 큰 원을 그렸습니다.


        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.FillEllipse(Brushes.Black, 100, 100, 300, 300);
        }
        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            g.FillEllipse(Brushes.Black, 10, 10, 300, 300);
        }

이 상태로는 더블버퍼링이 적용되지 않아 원이 깜박입니다.

더블버퍼링을 적용하기 위해서는


        public Form1()
        {
            InitializeComponent();
            DoubleBuffered = true;
        }
를 포함시켜야 합니다. 실행해 보면 form에 그리는 원은 잘 출력되는 반면 panel에 그리는 원은 여전히 깜박입니다. 이것은 더블버퍼링이 form에만 적용되었다는 뜻이죠. 판넬에도 DoubleBuffered를 true로 세팅해야 합니다.

해당 컨트롤의 Load이벤트가 있는 경우에는 그곳에 넣어도 되지만, 없을 경우에는 다음과 같이 확장된 컨트롤을 만들어야죠

    internal class DoublePanel : System.Windows.Forms.Panel
    {
        internal DoublePanel()
        {
            DoubleBuffered = true;
        }
    }
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.panel1 = new DoublePanel();
            this.SuspendLayout();
            // 
이부분은 원래 System.Windows.Forms.Panel() 였지만, DoublePanel로 바꿈으로써 기존의 Panel역할을 그대로 하면서 생성될 때 DoubleBuffered를 true로 세팅하게 됩니다.