본문 바로가기

Developement/C/C++

[FLTK] Win32/X11 에서 FLTK 고속 rednering (또는 redraw)


 FLTK 에서는 사실상 Fl::check(); 나 Fl::wait(); 등으로 화면을 갱신 하는 방법이 있습니다. 하지만 이 방법을 사용할 경우 잘못된 화면 출력이나 프로그램 자체가 멈추는 문제가 발생되는 단점이 있습니다.

 실질적으로 FLTK 는 강제적인 redraw 를 할수 있는 조건을 FLTK 자체가 결정 하는 구조이며, Windows 에서는 비활성화 된 Window 에서는 1초에 한번 그리는 경악적인 상태로 바뀝니다. 문제는 활성화 된 상태 이더라도 Fl_Window 객체를 아무리 redraw(); 하더라도 갱신은 "니 맘대로 되는것이 아니란다" 라는 단점이 있습니다.


 이를 해결 하기 위해 여러 방법을 찾다가 문듯, 활성화된 FLTK Window 위에서 마우스를 계속 움직이면 고속으로 화면이 갱신 되는 것을 발견, '이를 강제적으로 FLTK 에 전달 하면 고속으로 화면 갱신이 가능하겠다' 라는 아이디어를 얻었습니다. 그래서 이전에 WVGA 해상도로 도는 MP3 player 에 이를 적용하고, 초당 100fps 를 그리도록 해 보았습니다.


 그 결과 ! 기존의 Fl::Wait(), Fl::check() 등으로 그리면 폰트가 깨져서 그려진다거나, DC 가 엉뚱한데로 가서 바탕화면에 그리게 된다거나 하는 문제가 말끔히 사라 졌습니다.

 FLTK 를 빠르게 다시 그리게 하는 방법은 다음과 같은 함수를 하나 만들고 적용 하였습니다.


#ifdef _WIN32
    #include <windows.h>
#else
	#include <X11⁄Xlib.h>
#endif

void RedrawFLTK()
{
#ifdef _WIN32
    HWND hWnd = fl_xid( mainWindow );
    if ( hWnd != NULL )
    {
        RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
    }
#else
    extern Display *fl_display;

    Window wind = fl_xid( mainWindow );
    if ( wind != NULL )
    {
        XEvent xevt = {0};
        xevt.type = Expose;
        xevt.xexpose.window = wind;

        XSendEvent( fl_display, wind, false, ExposureMask, &xevt );
        XFlush( fl_display );
    }
#endif
}

 위의 함수를 사용하여 mainWindow (예로 든 Fl_Double_Window 이름) 를 redraw() 지정 한 다음 RedrawFLTK(); 함수를 화면 갱신 제일 마지막 부분에 적용 해 준다면 빠르고 안전하게 그려지는 FLTK 를 적용할 수 있습니다.