Prevent jerky animation - Xwindows

This is a discussion on Prevent jerky animation - Xwindows ; I have written a simple Xlib application on Linux that rotates a rectangle in a window. The animation is somewhat jerky, and I want to know how I can make it smoother. If anyone can provide some useful feedback I ...

+ Reply to Thread
Results 1 to 7 of 7

Thread: Prevent jerky animation

  1. Prevent jerky animation

    I have written a simple Xlib application on Linux that rotates a
    rectangle in a window. The animation is somewhat jerky, and I want to
    know how I can make it smoother.

    If anyone can provide some useful feedback I would appreciate it.
    The source code is as follows:

    #include
    #include
    #include
    #include

    #include
    #include
    #include

    #include

    #include
    #include

    namespace
    {
    typedef std::vector PointVector;
    bool ConnectToServer(void);
    void CreateWindow(void);
    void SetWindowProperties();

    void SetPoints();

    void DoEventLoop();
    void HandleEvent();
    void DrawRectangle();
    double GetTime();

    void FreeResources();

    int g_nScreen = 0;
    Display* g_pDisplay = NULL;
    Window g_window;
    Pixmap g_buffer;
    GC g_gc;
    PointVector g_points;
    double g_dAngle = 0.0;
    bool g_bDone = false;
    Atom g_deleteWindow;

    class RotatePoints : public std::unary_function XPoint&>
    {
    public:
    XPoint operator ()(const XPoint& point)
    {
    XPoint result(point);
    result.x -= 100;
    result.y -= 100;

    double dCosX = result.x * ::cos(g_dAngle);
    double dSinX = result.x * ::sin(g_dAngle);
    double dCosY = result.y * ::cos(g_dAngle);
    double dSinY = result.y * ::sin(g_dAngle);

    result.x = static_cast(dCosX + dSinY);
    result.y = static_cast(dCosY - dSinX);

    result.x += 100;
    result.y += 100;

    return result;
    }
    };
    }

    int main()
    {
    if(false == ::ConnectToServer()){
    return -1;
    }

    g_nScreen = DefaultScreen(g_pDisplay);

    ::CreateWindow();
    ::SetWindowProperties();
    ::XSelectInput(g_pDisplay, g_window, ExposureMask | KeyPressMask);

    ::SetPoints();

    ::XMapWindow(g_pDisplay, g_window);

    :oEventLoop();

    ::FreeResources();

    return 0;
    }

    namespace{

    bool ConnectToServer()
    {
    char* pszDisplayName = NULL;
    g_pDisplay = ::XOpenDisplay(pszDisplayName);
    if(NULL == g_pDisplay){
    return false;
    }

    return true;
    }

    void CreateWindow()
    {
    Window rootWindow = RootWindow(g_pDisplay, g_nScreen);
    unsigned long lBorderColor = BlackPixel(g_pDisplay, g_nScreen);
    unsigned long lBackgroundColor = WhitePixel(g_pDisplay, g_nScreen);

    g_window = ::XCreateSimpleWindow(g_pDisplay, rootWindow, 0, 0,
    200, 200, 4, lBorderColor, lBackgroundColor);
    }

    void SetWindowProperties()
    {
    char* pszWindowTitle = "Rotating Rectangle";
    XTextProperty windowTitle;
    ::XStringListToTextProperty(&pszWindowTitle, 1, &windowTitle);

    XWMHints wmHints;
    wmHints.flags = StateHint | InputHint;
    wmHints.initial_state = NormalState;
    wmHints.input = True;

    XClassHint classHints;
    classHints.res_name = "RotateRect";
    classHints.res_class = "Basic";

    ::XSetWMProperties(g_pDisplay, g_window, &windowTitle, NULL, NULL, 0,
    NULL,
    &wmHints, &classHints);

    g_buffer = XCreatePixmap(g_pDisplay, g_window, 200, 200,
    DefaultDepth(g_pDisplay, DefaultScreen(g_pDisplay)));

    XGCValues values;
    g_gc = XCreateGC(g_pDisplay, g_buffer, 0, &values);
    }

    void SetPoints()
    {
    XPoint points[] = {{50, 150}, {50, 50}, {150, 50}, {150, 150}};
    g_points.insert(g_points.begin(), points, points + 4);
    }

    void DoEventLoop()
    {
    g_deleteWindow = ::XInternAtom(g_pDisplay, "WM_DELETE_WINDOW",
    False);
    ::XSetWMProtocols(g_pDisplay, g_window, &g_deleteWindow, 1);

    while(!g_bDone){
    if(::XPending(g_pDisplay)){
    ::HandleEvent();
    }
    else{
    :rawRectangle();
    }
    }

    ::XDeleteProperty(g_pDisplay, g_window, g_deleteWindow);
    }

    void HandleEvent()
    {
    XEvent event;
    ::XNextEvent(g_pDisplay, &event);

    switch(event.type){
    case KeyPress:
    ::XClearArea(g_pDisplay, g_window, 0, 0, 0, 0, True);
    break;

    case Expose:
    if(0 == event.xexpose.count){
    DrawRectangle();
    }
    break;

    case ClientMessage:
    if(event.xclient.data.l[0] ==
    static_cast(g_deleteWindow)){

    g_bDone = true;
    }
    break;
    }
    }

    void DrawRectangle()
    {
    const double dPI = 3.1415926;
    const double dTWO_PI = 2.0 * dPI;

    static double dTime = ::GetTime();
    double dCurrentTime = ::GetTime();
    double dTimeChange = dCurrentTime - dTime;
    dTime += dTimeChange;

    g_dAngle += dPI * 0.5 * dTimeChange;
    if(dTWO_PI < g_dAngle){
    g_dAngle -= dTWO_PI;
    }

    XGCValues values;
    values.foreground = 0xFFFFFFFF;
    ::XChangeGC(g_pDisplay, g_gc, GCForeground, &values);
    ::XFillRectangle(g_pDisplay, g_buffer, g_gc, 0, 0, 200, 200);

    PointVector rotated(g_points);

    std::transform(g_points.begin(), g_points.end(), rotated.begin(),
    RotatePoints());

    values.foreground = 0;
    ::XChangeGC(g_pDisplay, g_gc, GCForeground, &values);

    ::XFillPolygon(g_pDisplay, g_buffer, g_gc, &(rotated[0]),
    rotated.size(),
    Convex, CoordModeOrigin);

    ::XFlush(g_pDisplay);

    ::XCopyArea(g_pDisplay, g_buffer, g_window, g_gc, 0, 0, 200, 200, 0,
    0);
    ::XFlush(g_pDisplay);
    }

    double GetTime()
    {
    timeval timeVal;
    ::gettimeofday(&timeVal, NULL);

    double dTime = timeVal.tv_sec;

    const double dMICROSECONDS_PER_SECOND = 1000000.0;
    dTime += timeVal.tv_usec / dMICROSECONDS_PER_SECOND;

    return dTime;
    }

    void FreeResources()
    {
    ::XFreeGC(g_pDisplay, g_gc);
    ::XFreePixmap(g_pDisplay, g_buffer);
    ::XDestroyWindow(g_pDisplay, g_window);
    ::XFlush(g_pDisplay);
    ::XCloseDisplay(g_pDisplay);
    }

    } // namespace

  2. Re: Prevent jerky animation

    tron.thomas@verizon.net (Tron Thomas) writes:

    > I have written a simple Xlib application on Linux that rotates a
    > rectangle in a window. The animation is somewhat jerky, and I want to
    > know how I can make it smoother.


    Add XSync to the DrawRectangle function.

  3. Re: Prevent jerky animation

    On Thu, 04 Dec 2003 19:09:31 +0100, Tron Thomas wrote:

    > I have written a simple Xlib application on Linux that rotates a
    > rectangle in a window. The animation is somewhat jerky, and I want to
    > know how I can make it smoother.


    For faster: Use some Pixmaps to draw into and when done with one frame,
    copy the Pixmap to the display.

    Cheers, Darius.

  4. Re: Prevent jerky animation

    I thought that I was doing that already.

    dmoos AT esigma-systems DOT de wrote in message news:...
    > On Thu, 04 Dec 2003 19:09:31 +0100, Tron Thomas wrote:
    >
    > > I have written a simple Xlib application on Linux that rotates a
    > > rectangle in a window. The animation is somewhat jerky, and I want to
    > > know how I can make it smoother.

    >
    > For faster: Use some Pixmaps to draw into and when done with one frame,
    > copy the Pixmap to the display.
    >
    > Cheers, Darius.


  5. Re: Prevent jerky animation

    I tried XSync, and it did not help. The animation is still jerky.
    Also, if I use True as the second argument of XSync, I cannot close
    the window using the window manager and I have to kill the process
    from the command line.

    Dan Espen wrote in message news:...
    > tron.thomas@verizon.net (Tron Thomas) writes:
    >
    > > I have written a simple Xlib application on Linux that rotates a
    > > rectangle in a window. The animation is somewhat jerky, and I want to
    > > know how I can make it smoother.

    >
    > Add XSync to the DrawRectangle function.


  6. Re: Prevent jerky animation

    tron.thomas@verizon.net (Tron Thomas) writes:

    > Dan Espen wrote in message news:...
    >> tron.thomas@verizon.net (Tron Thomas) writes:
    >>
    >> > I have written a simple Xlib application on Linux that rotates a
    >> > rectangle in a window. The animation is somewhat jerky, and I want to
    >> > know how I can make it smoother.

    >>
    >> Add XSync to the DrawRectangle function.

    > I tried XSync, and it did not help. The animation is still jerky.
    > Also, if I use True as the second argument of XSync, I cannot close
    > the window using the window manager and I have to kill the process
    > from the command line.


    I added:

    ::XSync(g_pDisplay,0);

    as the last instruction in DrawRectangle.
    It smoothed out very nicely.

  7. Re: Prevent jerky animation

    So you verified that the animation was jerky on your computer before you
    added the XSync call?
    I did not notice any difference on my system when I added XSync.
    What kind of system configuration are you using?

    Dan Espen wrote:
    > tron.thomas@verizon.net (Tron Thomas) writes:
    >
    >
    >>Dan Espen wrote in message news:...
    >>
    >>>tron.thomas@verizon.net (Tron Thomas) writes:
    >>>
    >>>
    >>>>I have written a simple Xlib application on Linux that rotates a
    >>>>rectangle in a window. The animation is somewhat jerky, and I want to
    >>>>know how I can make it smoother.
    >>>
    >>>Add XSync to the DrawRectangle function.

    >>
    >>I tried XSync, and it did not help. The animation is still jerky.
    >>Also, if I use True as the second argument of XSync, I cannot close
    >>the window using the window manager and I have to kill the process
    >>from the command line.

    >
    >
    > I added:
    >
    > ::XSync(g_pDisplay,0);
    >
    > as the last instruction in DrawRectangle.
    > It smoothed out very nicely.



+ Reply to Thread