C言語+GLUT(マウス移動で注視点を変える)

続きです。

前回からの変更点は、
・定数化
・画面中央にカーソルブロック配置
・マウス移動で注視点を変える
・ブロックをランダムに設置
です。実行動画。

では前回からのソース変更箇所です。

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で、さきほどのマウス移動時のコールバック関数を登録しています。

つづく

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA