Document

5-
5.
イベント処理
キーボードやマウスの指定に従って画像生成を操作する.
(拡大・縮小,回転・移動,その他)
1
5-
5.1.2. 一般キーに対する設定
・キーを操作したときの動作を指定する関数を初期化時に登録
glutKeyboardFunc(myKbd);
・これで,キーボードの一般キーが押されるとユーザ定義の
関数myKbdが呼び出されるよう設定される.
void myKbd(unsigned char key, int x, int y);
文字変数keyには押されたkeyのASCIIコードが入る.
x,yにはマウスポインタの位置座標が渡る.
この関数の中で動作を設定する=例えばEscが押されたら終了
2
5-
5.1.3. 特殊キーに対する設定(Fキーなど)
glutSpecialFunc(mySkey);
同様に,キーボードの特殊キーが押されたときに呼び出
される関数名を設定
void mySkey(int key, int x, int y);
整数変数keyには押された特殊keyの番号がはいる.
プログラムの中で比較する際には数字を使うのではなく,
GLUT_KEY_F1,GLUT_KEY_F2,…
や
GLUT_KEY_LEFT,GLUT_KEY_RIGHT
などといった外部定義された定数比較の使い方をする.
3
5-
5.1.4. キー割り込みの例
実行!
c5-1.cをコピーして実行する.
・矢印キーを押した回数だけ物体の位置が変化する.
・wキーを押すたびにワイヤーフレームと塗りつぶされた状態が
変わる.Cキーを押すたびに物体の色がランダムに変化する.
練習問題5-1:
1)プログラムc5-1.cにおいてF1キーを押すたびに物体がy軸周りに10°づ
つ回転し,F2キーを押すたびに-10°づつ回転するように設定する.また,R
キーを押すと初期状態に戻るように設定する.
p5-1.c
4
5-
P5-1ヒント:
1) float theta =0.0;
をグローバル変数で宣言する.
2)display関数内でglTranslatefの後に
glRotatef(theta,0.0,1.0,0.0);/*Y軸周りにtheta回転
3)void mySkey(int key,int x, int y)
の関数の中で
switch(key) {
case GLUT_KEY_F1:
何かをする;
break;
…
}
という形にする.
5
5-
5.2. マウス操作
マウス操作で拡大・縮小や回転を行わせる
5.2.2. クリック情報の獲得
コールバック関数を初期化時に登録
glutMouseFunc(myMouse);
void myMouse(int button, int state, int x, int y);
button: 押されたボタンの種類
GLUT_LEFT_BUTTON:左ボタン
GLUT_MIDDLE_BUTTON:中ボタン
GLUT_RIGHT_BUTTON:右ボタン
state:ボタンが押されているかどうかの別
GLUT_DOWN:押されている
GLUT_UP:押されていない
6
5-
5.2.3 ドラッグ情報の獲得
コールバック関数の登録
glutMotionFunc(myMotion);
void myMotion(int x, int y);
マウスボタンが押されてマウスが移動している間,一定時間
間隔でmyMotionが呼び出される
7
5-
5.2.4. マウスドラッグの例
実行!
c5-2.cをコピーして実行する.
・マウス操作でpolarviewのパラメータを変化させる
・左ボタンで左右ドラッグすると垂直軸周り,上下ドラッグで
水平軸周りに回転
・右ボタンで上下ドラッグすると拡大・縮小
・中ボタンを押すと回転が停止・再開
8
5-
練習問題5-2:
1)プログラムc5-2.cにおいて中ボタンをクリックすると色がラン
ダムに変化するように設定する.p5-2-1.c
ヒント:
a)実数変数rColor,gColor,bColorをグローバル変数として定義
する(初期値1.0).
b)display関数のglColor3fではこの変数を使う
c) Middle Buuttonが押されるとchangeColor関数が呼ばれる
ようにする
d)changeColor関数の中で
rColor = rand() / (float) RAND_MAX ;とする
2)マウスの右ボタンで横方向にドラッグするとtwistが変化して
物体が傾くように設定する.p5-2-2.c
9
5- 10
5.3 ウィンドウのリシェープ
ユーザがマウスをドラッグしてウィンドウサイズを変更したと
きに生じるイベントに対するウィンドウ書き換え処理機能
5.3.2. 設定方法
コールバック関数の登録
glutReshapeFunc(myReshape);
void myReshape(int width, int height);
システムからwidth,heightにウィンドウ変更後のサイズが
渡されるので書き直しをする.
5- 11
Reshape関数の例
void myReshape(int width,int height)/*リシェープコールバック関数*/
{
float aspect =(float)width/(float)height;
glViewport(0,0,width,height);/*ビューポートの再設定*/
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0,aspect,1.0,10.0);/*ビューボリュームの再
定義*/
glMatrixMode(GL_MODELVIEW);
}
5- 12
5.3.3 リシェープの例
c5-3.c(c4-1.cにリシェープ機能をつけたも
の)をコピーして実行する.
実行!
glViewport()は表示領域を設定する関数であ
り,リシェープには不可欠.
練習問題5-3:
1)c5-2.cにreshape機能をつける(p5-3.c)
5- 13
条件4を実現させるヒント:
第一段以下を切り離して下に動いていくようにする.
i)moveFLAGを設けて,F1キーが押されたらGL_TRUEとFLASEを切り替え,
TRUEだったらglutIdleFunc(idle)を呼ぶ.
ii)関数idleの中では,fly = fmod(fly - 0.01, 10000.0);と設定する.
iii)display関数の,第一段の記述の手前で
moveFLAGがTRUEならglTranslatef( 0.0, fly, 0.0);
FALSEだったらfly=0.0;
とする
resetviewの初期値
void resetview(void)
{
distance = 14.0;
twist = 10.0;
elevation = -30.0;
azimuth = 0.0;
}