Fl_Gl_Windowでのアニメーション
をテンプレートにして作成
[
トップ
|
新規
|
一覧
|
検索
|
最終更新
|
ヘルプ
]
開始行:
----
#contents
----
*Fl_Gl_Windowでのアニメーション [#t692a1c6]
[[Fl_Gl_Windowでのキーボード・マウス入力]]にアニメーショ...
***アニメーションのやり方 [#cba48a63]
連続した動きを描画した画像があり,それを高速に切り替えて...
これは仮現運動と呼ばれる現象であり,人間の場合,22〜23fps...
よく使われるのは,24fps, 30fps, 60fpsなどである.動きが激...
通常は30fpsあれば問題ない.
OpenGLプログラムでアニメーションを作る際は,呼び出される...
関数の呼び出し方には一般的に以下の二種類の方法が用意され...
-アイドル関数 : PCが暇なときに呼ばれる.処理内容やそのと...
-タイマー関数 : ある一定の時間幅ごとに呼ばれる.処理内容...
アプリケーションによってこれら2種類を使い分けてアニメーシ...
以下ではFLTKでのアイドル関数,タイマー関数の作り方を説明...
***クラスの宣言 [#y438054c]
[[Fl_Gl_Windowでのキーボード・マウス入力]]で作成したrxFlG...
#code(C){{
class rxFlGLWindow : public Fl_Gl_Window
{
// 描画フラグ
enum DrawObject
{
RX_IDD_VERTEX = 0, //!< 頂点描画
RX_IDD_EDGE, //!< エッジ描画
RX_IDD_FACE, //!< 面描画
};
int m_iDraw; //!< 描画フラグ
rxTrackball m_tbView; //!< トラックボール
bool m_bAnimation; //!< アニメーションの状態
public:
//! コンストラクタ
rxFlGLWindow(int x_, int y_, int w_, int h_, const char*...
: Fl_Gl_Window(x_, y_, w_, h_, l)
{
m_bAnimation = false;
m_iDraw = RX_IDD_FACE;
resizable(this); // ウィンドウリサイズを可能に
end();
}
//! デストラクタ
virtual ~rxFlGLWindow()
{
}
public:
void InitGL(void);
void Resize(int w, int h);
void Display(void);
void Mouse(int button, int state, int x, int y);
void Motion(int x, int y);
void PassiveMotion(int x, int y);
void Keyboard(int key, int x, int y);
static void OnIdle_s(void* x);
static void OnTimer_s(void* x);
inline void Idle(void)
inline void Timer(void)
private:
void draw(void)
void resize(int x_, int y_, int w_, int h_);
int handle(int ev);
};
}}
Idle,Timer関数がそれぞれアイドル関数,タイマー関数である.
OnIdle_s,OnTimer_s関数はFLTKに関数を登録するための引数を1...
何故,staticな関数と通常のメンバ関数の両方を定義している...
アニメーションの状態は変数m_bAnimationに登録する.
そして,キーボードでアニメーションのON/OFFを行う.
***キーボードによる切り替え [#g9eecbe7]
アニメーションのON/OFFはキーボードの"s","t"で行うこととす...
"s"キーでアイドル関数,"t"キーでタイマー関数によるアニメ...
#code(C){{
void rxFlGLWindow::Keyboard(int key, int x, int y)
{
make_current();
switch(key){
case 's':
m_bAnimation ^= 1;
if(m_bAnimation){
Fl::add_idle(OnIdle_s, this);
}
else{
Fl::remove_idle(OnIdle_s, this);
}
break;
case 't':
m_bAnimation ^= 1;
if(m_bAnimation){
Fl::add_timeout(0.033, OnTimer_s, this);
}
break;
}
redraw();
}
}}
FLTKのadd_idle関数に関数ポインタ(OnIdle_s)とその関数に渡...
OnIdle_s関数が指定される.
登録を解除してアニメーションを止める場合は,remove_idle関...
ここで,Idle()でなく,staticなメンバ関数であるOnIdle_s()...
通常,クラスのメンバ関数はクラスのオブジェクトを通して呼...
そのため,メンバ関数はアイドル/タイマー関数としてFLTKに...
(通常,グローバル関数が指定される).
なぜならば,FLTK側はその関数がグローバル関数なのかメンバ...
そこで,staticなメンバ関数を利用する.
static関数はクラスのオブジェクトなしでもアクセス可能な関...
クラスのオブジェクトを通さなくてもアクセスできるため,ア...
ただし,staticなメンバ関数はクラスの中身にはアクセスでき...
つまり,オブジェクトがなければメンバ変数や他の(staticでな...
そのため,関数登録時に第2引数にクラスオブジェクト(this)を...
上記の例では同じクラス内の関数なので関数名だけ記述してい...
Fl::add_idle(rxTest::OnIdle_s, pTest);
のように記述すればよい(pTestはrxTestクラスのオブジェクト).
OnIdle_s,Idle関数の実装は以下.
#code(C){{
static void rxFlGLWindow::OnIdle_s(void* x)
{
((rxFlGLWindow*)x)->Idle();
}
inline void rxFlGLWindow::Idle(void)
{
make_current();
m_tbView.AddRotation(1.0, 0, 1, 0);
redraw();
}
}}
OnIdle_s関数では引数で受け取ったrxFlGLWindowクラスのイン...
Idle関数内では視点変更用のトラックボールに回転を加え,再...
アニメーションを実行している.
一方,add_timeout関数は単純に指定した秒数後に関数を一回実...
第一引数の秒数(ここでは0.033秒),第二引数で呼び出す関数(O...
add_timeout関数は関数を一回実行するだけなので,
呼び出された関数内でさらに,repeat_timeout関数で同様に登...
タイマーによるアニメーションが可能となる.
OnTimer_s,Timer関数の実装は以下.
#code(C){{
static void rxFlGLWindow::OnTimer_s(void* x)
{
((rxFlGLWindow*)x)->Timer();
}
inline void rxFlGLWindow::Timer(void)
{
make_current();
m_tbView.AddRotation(1.0, 0, 1, 0);
redraw();
if(m_bAnimation){
Fl::repeat_timeout(0.033, OnTimer_s, this);
}
}
}}
アイドル関数の時と同様にして,OnTimer_sからTimer関数を呼...
アニメーションを止めるときは単純にrepeat_timeout関数を実...
この判断をするために,m_bAnimation変数の値を参照している.
***ソースコード [#n1341dce]
上記例のソースコードは以下(Viual Studio 2010用プロジェク...
#ref(fltk_simple_opengl3.zip)
実行結果は静止画では [[Fl_Gl_Windowでのキーボード・マウス...
終了行:
----
#contents
----
*Fl_Gl_Windowでのアニメーション [#t692a1c6]
[[Fl_Gl_Windowでのキーボード・マウス入力]]にアニメーショ...
***アニメーションのやり方 [#cba48a63]
連続した動きを描画した画像があり,それを高速に切り替えて...
これは仮現運動と呼ばれる現象であり,人間の場合,22〜23fps...
よく使われるのは,24fps, 30fps, 60fpsなどである.動きが激...
通常は30fpsあれば問題ない.
OpenGLプログラムでアニメーションを作る際は,呼び出される...
関数の呼び出し方には一般的に以下の二種類の方法が用意され...
-アイドル関数 : PCが暇なときに呼ばれる.処理内容やそのと...
-タイマー関数 : ある一定の時間幅ごとに呼ばれる.処理内容...
アプリケーションによってこれら2種類を使い分けてアニメーシ...
以下ではFLTKでのアイドル関数,タイマー関数の作り方を説明...
***クラスの宣言 [#y438054c]
[[Fl_Gl_Windowでのキーボード・マウス入力]]で作成したrxFlG...
#code(C){{
class rxFlGLWindow : public Fl_Gl_Window
{
// 描画フラグ
enum DrawObject
{
RX_IDD_VERTEX = 0, //!< 頂点描画
RX_IDD_EDGE, //!< エッジ描画
RX_IDD_FACE, //!< 面描画
};
int m_iDraw; //!< 描画フラグ
rxTrackball m_tbView; //!< トラックボール
bool m_bAnimation; //!< アニメーションの状態
public:
//! コンストラクタ
rxFlGLWindow(int x_, int y_, int w_, int h_, const char*...
: Fl_Gl_Window(x_, y_, w_, h_, l)
{
m_bAnimation = false;
m_iDraw = RX_IDD_FACE;
resizable(this); // ウィンドウリサイズを可能に
end();
}
//! デストラクタ
virtual ~rxFlGLWindow()
{
}
public:
void InitGL(void);
void Resize(int w, int h);
void Display(void);
void Mouse(int button, int state, int x, int y);
void Motion(int x, int y);
void PassiveMotion(int x, int y);
void Keyboard(int key, int x, int y);
static void OnIdle_s(void* x);
static void OnTimer_s(void* x);
inline void Idle(void)
inline void Timer(void)
private:
void draw(void)
void resize(int x_, int y_, int w_, int h_);
int handle(int ev);
};
}}
Idle,Timer関数がそれぞれアイドル関数,タイマー関数である.
OnIdle_s,OnTimer_s関数はFLTKに関数を登録するための引数を1...
何故,staticな関数と通常のメンバ関数の両方を定義している...
アニメーションの状態は変数m_bAnimationに登録する.
そして,キーボードでアニメーションのON/OFFを行う.
***キーボードによる切り替え [#g9eecbe7]
アニメーションのON/OFFはキーボードの"s","t"で行うこととす...
"s"キーでアイドル関数,"t"キーでタイマー関数によるアニメ...
#code(C){{
void rxFlGLWindow::Keyboard(int key, int x, int y)
{
make_current();
switch(key){
case 's':
m_bAnimation ^= 1;
if(m_bAnimation){
Fl::add_idle(OnIdle_s, this);
}
else{
Fl::remove_idle(OnIdle_s, this);
}
break;
case 't':
m_bAnimation ^= 1;
if(m_bAnimation){
Fl::add_timeout(0.033, OnTimer_s, this);
}
break;
}
redraw();
}
}}
FLTKのadd_idle関数に関数ポインタ(OnIdle_s)とその関数に渡...
OnIdle_s関数が指定される.
登録を解除してアニメーションを止める場合は,remove_idle関...
ここで,Idle()でなく,staticなメンバ関数であるOnIdle_s()...
通常,クラスのメンバ関数はクラスのオブジェクトを通して呼...
そのため,メンバ関数はアイドル/タイマー関数としてFLTKに...
(通常,グローバル関数が指定される).
なぜならば,FLTK側はその関数がグローバル関数なのかメンバ...
そこで,staticなメンバ関数を利用する.
static関数はクラスのオブジェクトなしでもアクセス可能な関...
クラスのオブジェクトを通さなくてもアクセスできるため,ア...
ただし,staticなメンバ関数はクラスの中身にはアクセスでき...
つまり,オブジェクトがなければメンバ変数や他の(staticでな...
そのため,関数登録時に第2引数にクラスオブジェクト(this)を...
上記の例では同じクラス内の関数なので関数名だけ記述してい...
Fl::add_idle(rxTest::OnIdle_s, pTest);
のように記述すればよい(pTestはrxTestクラスのオブジェクト).
OnIdle_s,Idle関数の実装は以下.
#code(C){{
static void rxFlGLWindow::OnIdle_s(void* x)
{
((rxFlGLWindow*)x)->Idle();
}
inline void rxFlGLWindow::Idle(void)
{
make_current();
m_tbView.AddRotation(1.0, 0, 1, 0);
redraw();
}
}}
OnIdle_s関数では引数で受け取ったrxFlGLWindowクラスのイン...
Idle関数内では視点変更用のトラックボールに回転を加え,再...
アニメーションを実行している.
一方,add_timeout関数は単純に指定した秒数後に関数を一回実...
第一引数の秒数(ここでは0.033秒),第二引数で呼び出す関数(O...
add_timeout関数は関数を一回実行するだけなので,
呼び出された関数内でさらに,repeat_timeout関数で同様に登...
タイマーによるアニメーションが可能となる.
OnTimer_s,Timer関数の実装は以下.
#code(C){{
static void rxFlGLWindow::OnTimer_s(void* x)
{
((rxFlGLWindow*)x)->Timer();
}
inline void rxFlGLWindow::Timer(void)
{
make_current();
m_tbView.AddRotation(1.0, 0, 1, 0);
redraw();
if(m_bAnimation){
Fl::repeat_timeout(0.033, OnTimer_s, this);
}
}
}}
アイドル関数の時と同様にして,OnTimer_sからTimer関数を呼...
アニメーションを止めるときは単純にrepeat_timeout関数を実...
この判断をするために,m_bAnimation変数の値を参照している.
***ソースコード [#n1341dce]
上記例のソースコードは以下(Viual Studio 2010用プロジェク...
#ref(fltk_simple_opengl3.zip)
実行結果は静止画では [[Fl_Gl_Windowでのキーボード・マウス...
ページ名: