Xlib 編 (4)

前へ << Xlib 編 (3)

簡単なアニメーション

まずはサンプルをどうぞ。
[Xlib のサンプル画像: 円が左右に動く]
画面内を円が移動するだけだ。 まず右へ移動し、ウィンドウの右端につきあたったら今度は左に移動する。 これを実現するには、円を書く前に画面をクリアしないといけない。

xlib-4-1.c

    1: #include <X11/Xlib.h>
    2: #include <X11/Xutil.h>
    3: 
    4: int main(int argc , char *argv[]){
    5:     Display *display;
    6:     Window window;
    7:     GC     gc,gc_clr;
    8:     XEvent event;
    9:     char title[]      = "This is TITLE";
   10:     char icon_title[] = "ICON!";
   11:     unsigned long background;
   12:     unsigned long foreground;
   13:     int oldx=0 ,x=0;
   14:     int dx=1;
   15:     int arcsize=100;
   16:     int window_width=300;
   17:     int window_height=200;
   18:     
   19: 
   20:     display = XOpenDisplay(NULL);
   21: 
   22:     background = WhitePixel(display, 0);
   23:     foreground = BlackPixel(display, 0);
   24: 
   25:     window = XCreateSimpleWindow(display,
   26:                                  DefaultRootWindow(display),
   27:                                  0, 0, window_width, window_height,
   28:                                  0, 0, background);
   29: 
   30:     XSetStandardProperties(display, window, title, icon_title,
   31:                            None, argv, argc, NULL);
   32: 
   33:     gc = XCreateGC(display, window, 0, 0);
   34:     XSetBackground(display, gc, background);
   35:     XSetForeground(display, gc, foreground);
   36: 
   37:     gc_clr = XCreateGC(display, window, 0, 0);
   38:     XSetBackground(display, gc_clr, background);
   39:     XSetForeground(display, gc_clr, background);
   40: 
   41:     XMapRaised(display, window);
   42: 
   43:     while (1){
   44:         XFillArc(display, window, gc_clr, oldx, 50, arcsize, arcsize, 0, 360*64);
   45:         XFillArc(display, window, gc,        x, 50, arcsize, arcsize, 0, 360*64);
   46:         XFlush(display);
   47: 
   48:         oldx = x;
   49:         x += dx;
   50: 
   51:         if ( x==0 ){
   52:             dx=1;
   53:         } else if ( x==(window_width-arcsize) ){
   54:             dx=-1;
   55:         }
   56:     }
   57: }

では軽く解説を。
   33:     gc = XCreateGC(display, window, 0, 0);
   34:     XSetBackground(display, gc, background);
   35:     XSetForeground(display, gc, foreground);
   36: 
   37:     gc_clr = XCreateGC(display, window, 0, 0);
   38:     XSetBackground(display, gc_clr, background);
   39:     XSetForeground(display, gc_clr, background);
gc は描画用 GC 構造体である。背景色には白、前景色には黒を 設定している。一方、gc_clr は消去用である。 こちらは背景色も前景色も白をセットしてある。 gc_clr を使って線を引いたり文字を書くと、 「前に書いてあったものを消す」効果が得られるわけだ。
   43:     while (1){
   44:         XFillArc(display, window, gc_clr, oldx, 50, arcsize, arcsize, 0, 360*64);
   45:         XFillArc(display, window, gc,        x, 50, arcsize, arcsize, 0, 360*64);
   46:         XFlush(display);
   47: 
   48:         oldx = x;
   49:         x += dx;
   50: 
   51:         if ( x==0 ){
   52:             dx=1;
   53:         } else if ( x==(window_width-arcsize) ){
   54:             dx=-1;
   55:         }
   56:     }
   57: }
一度 Expose を受けたら、while (1) で無限ループに入る。 XFillArc で円を書く。まず、古い座標値に対して gc_clr で円を書く。 つまり前に書いた円を消すわけね。そして新しい円を書く。

1ループごとに X 座標に dx を足し、円が移動しているように見せる。 X 座標が左端か右端ならば、dx の符号を変え、移動方向を変更する。

さて、これは手元で実際に実行してみてほしい。 どう? ちらついてるでしょ。 黒の円を描き、白の円でクリアして、また黒の円を描いてるんだから、 ちらつくのも当然ですな。これを解決するには Pixmap を使う。

Pixmap

Pixmap とは「作業用ウィンドウ」と思えばよい。 これまで XDrawLine などでウィンドウに直接線を描いたり文字を表示してきた。 同じことが Pixmap に対してもできる。文字も描けるし、線も描ける。 Pixmap と Window はとても似ている。違うのは「画面に直接表示できない」ことだけ。 Window に対して XDrawLine すると、実際に画面上に線が引けた。 しかし Pixmap に対して XDrawLine しても実際には見えない。

では Pixmap は何の役に立つのか? 先にも書いたが 「作業用ウィンドウ」として使うのだ。 Pixmap に対して線を引いたり文字を書く。 そして Pixmap から Window にコピーする。 すると画面上では、瞬時に Window に線や文字が描画されたように見える。 ちらつきも起こらないってわけだ。

前へ << Xlib 編 (3)

$Id: xlib-4.html,v 1.1 2004/05/29 11:35:49 68user Exp $