続きです。
前回からの変更点は、
・定数化
・画面中央にカーソルブロック配置
・マウス移動で注視点を変える
・ブロックをランダムに設置
です。実行動画。
glut mouse
では前回からのソース変更箇所です。
takk@deb9:~$ cat -n cube.c 1 #include <stdio.h> 2 #include <string.h> 3 #include <GL/glut.h> 4 #include <math.h> 5 6 #define CB_DEFAULT_SCREEN_WIDTH 640 7 #define CB_DEFAULT_SCREEN_HEIGHT 400 8 #define CB_WORLD_X_LIMIT 64 9 #define CB_WORLD_Z_LIMIT 64 10 #define CB_WORLD_XZ_LIMIT CB_WORLD_X_LIMIT*CB_WORLD_Z_LIMIT 11 12 int cb_screen_width = CB_DEFAULT_SCREEN_WIDTH; 13 int cb_screen_height = CB_DEFAULT_SCREEN_HEIGHT; 14 15 GLdouble cb_world_map[CB_WORLD_XZ_LIMIT][4]; 16 int cb_world_size; 17 18 int cb_mouse_pos_x=CB_DEFAULT_SCREEN_WIDTH/2;
気に向くままに数字を定数に置き換え。あっちこっち探すのが面倒なので、なるべく同じファイル内に定数定義はしたいのですが、普通ならヘッダ化するんでしょうね。ヘッダファイルってのが、いまだ慣れません。
18行目に追加した変数は、マウス操作で注視点を変えるための、前回座標を記憶しておく変数です。初期値は画面中央にしています。
149 void cb_set_cursor() 150 { 151 GLdouble v[3]; 152 153 v[0] = cb_player_pos[0] + 40 * cos((double)cb_player_direction*M_PI/180.0), 154 v[1] = cb_player_pos[1] - 5, 155 v[2] = cb_player_pos[2] + 40 * sin((double)cb_player_direction*M_PI/180.0), 156 157 cb_set_cube(v); 158 } 159
set_cursorと名前がついてはいるのですが、実際は遠くに立方体を描くだけの処理です。見た目は現段階で重要ではないので、なるべくすぐに実現できそうな方法でプログラミングしています。
160 void cb_callback_display() 161 { 162 int i; 163 164 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 165 166 glLoadIdentity(); 167 168 cb_look(); 169 170 glLightfv(GL_LIGHT0, GL_POSITION, cb_light0_pos); 171 glLightfv(GL_LIGHT1, GL_POSITION, cb_light1_pos); 172 173 for(i=0; i<cb_world_size; i++) 174 if(cb_wire_flag){ 175 cb_set_wire_cube(cb_world_map[i]); 176 }else 177 cb_set_cube(cb_world_map[i]); 178 179 cb_set_cursor(); 180 181 glutSwapBuffers(); 182 glFlush(); 183 }
179行目にさきほどのカーソル描画を追加しています。これでカーソルのように常時中央に立方体が表示されます。
そのうち中身を書き換えて十字カーソルが表示できるようにする予定です。
212 void cb_callback_passivemotion(int x, int y) 213 { 214 if(cb_mouse_pos_x > x){ 215 cb_player_direction--; 216 if(cb_player_direction < 0)cb_player_direction=359; 217 glutPostRedisplay(); 218 } 219 if(cb_mouse_pos_x < x){ 220 cb_player_direction++; 221 if(cb_player_direction >= 360)cb_player_direction=0; 222 glutPostRedisplay(); 223 } 224 cb_mouse_pos_x = x; 225 }
これがマウスを移動したときに、実行される関数になります。ボタンは押していない状態で、マウスの移動だけで本処理が呼び出しされます。
マウスの前回のX座標を記憶しておいて、左右どちらに移動したかで角度を決めています。
289 void cb_world_cratete() 290 { 291 int i,x,z,r; 292 i=0; 293 for(x=0; x<CB_WORLD_X_LIMIT; x++){ 294 for(z=0; z<CB_WORLD_Z_LIMIT; z++){ 295 r = rand()%2; 296 if(r == 0){ 297 r = rand()%7+1; 298 cb_world_map[i][0]=x; 299 cb_world_map[i][1]=0; 300 cb_world_map[i][2]=z; 301 cb_world_map[i][3]=r; 302 i++; 303 if(i>=CB_WORLD_XZ_LIMIT)goto over; 304 } 305 } 306 } 307 over: 308 cb_world_size = i; 309 }
前回外部ファイルから読み込んでいたデータを、思い切ってランダム生成に変更しました。
ランダムといっても、srandしていないので、毎回同じになります。
312 int main(int argc, char *argv[]) 313 { ~省略~ 329 glutPassiveMotionFunc(cb_callback_passivemotion); 330 glutKeyboardFunc(cb_callback_keyboard); ~省略~ 342 glutMainLoop(); 343 return 0; 344 } 345 takk@deb9:~$
329行目のglutPassiveMotionFuncで、さきほどのマウス移動時のコールバック関数を登録しています。
つづく
コメント