続きです。
前回からの変更点は、
・定数化
・画面中央にカーソルブロック配置
・マウス移動で注視点を変える
・ブロックをランダムに設置
です。実行動画。
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で、さきほどのマウス移動時のコールバック関数を登録しています。
つづく


コメント