/* map.c --- 地図の表示 */ /* compile: cc map.c -g -O2 -Wall -Wno-unused-result -o map -I/usr/include/freetype2 -lftgl -lglfw -lGLU -lGL -lX11 -lXrandr -lm */ #include #include #include #include #include #define CROSSING_SIZE 100 /* 交差点数=100 */ #define MAX_NAME_SIZE 50 /* 最大文字数50文字(半角) */ /* 座標変換マクロの定義 */ #define ORIGIN_X -3.0 #define ORIGIN_Y 0.0 #define REAL_SIZE_X 8.0 #define REAL_SIZE_Y 8.0 #ifndef FONT_FILENAME /* フォントのファイル名 */ #define FONT_FILENAME "/usr/share/fonts/truetype/takao-gothic/TakaoGothic.ttf" #endif FTGLfont *font; /* 読み込んだフォントを差すポインタ */ /* データ構造の定義 */ typedef struct { double x, y; /* 位置 x, y */ } Position; /* 位置を表す構造体 */ typedef struct { int id; /* 交差点番号 */ Position pos; /* 位置を表す構造体 */ double wait; /* 平均待ち時間 */ char jname[MAX_NAME_SIZE]; /* 交差点名(日本語) */ char ename[MAX_NAME_SIZE]; /* 交差点名(ローマ字) */ int points; /* 交差道路数 */ int next[5]; /* 隣接する交差点番号 */ } Crossing; /* データを格納する変数の定義 */ Crossing cross[CROSSING_SIZE]; /* 円を描画 */ void draw_circle(double x, double y, double r) { /* 描画処理を記述しましょう */ } /* 文字列を描画 */ void draw_outtextxy(double x, double y, char const *text) { double const scale = 0.01; glPushMatrix(); glTranslated(x, y, 0.0); glScaled(scale, scale, scale); ftglRenderFont(font, text, FTGL_RENDER_ALL); glPopMatrix(); } /* ファイルの読み込み */ int map_read(char *filename) { /* ex8-1.c を参考に埋めてください */ } /* 道路網の表示。新しく作成する部分、そのままでは動きません */ void map_show(int crossing_number) { /* 指定した交差点の数をだけ、ウィンドウに交差点(地図)を * * 表示する。まず各交差には赤丸を描き、隣接する交差点への * * 道路を直線で描く。 */ int i, j; double x0, y0, x1, y1; for (i = 0; i < crossing_number; i++) { /* 交差点毎のループ */ x0 = cross[i].pos.x; y0 = cross[i].pos.y; /* 交差点を表す円を描く */ glColor3d(1.0, 0.5, 0.5); draw_circle(x0, y0, 0.1); /* 交差点の名前を描く */ glColor3d(1.0, 1.0, 0.0); draw_outtextxy(x0, y0, cross[i].jname); /* 交差点から伸びる道路を描く */ /* for文を使って、隣接交差点の数だけ、現時点からの交差道路を記述しよう */ glColor3d(1.0, 1.0, 1.0); glBegin(GL_LINES); for (j = 0; j < cross[i].points; j++) { /* 隣接交差点の位置を書く */ glVertex2d(x0, y0); glVertex2d(x1, y1); } glEnd(); } } int main(void) { int crossing_number; /* 交差点数 */ /* グラフィック環境を初期化して、ウィンドウを開く */ glfwInit(); glfwOpenWindow(640, 640, 0, 0, 0, 0, 0, 0, GLFW_WINDOW); /* (ORIGIN_X, ORIGIN_Y) を中心に、REAL_SIZE_X * REAL_SIZE_Y の範囲の 空間をビューポートに投影する */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(ORIGIN_X + REAL_SIZE_X * -0.5, ORIGIN_X + REAL_SIZE_X * 0.5, ORIGIN_Y + REAL_SIZE_Y * -0.5, ORIGIN_Y + REAL_SIZE_Y * 0.5, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* それ以外の座標変換は行わない */ /* 文字列描画のためのフォントの読み込みと設定 */ font = ftglCreateExtrudeFont(FONT_FILENAME); if (font == NULL) { perror(FONT_FILENAME); fprintf(stderr, "could not load font\n"); exit(1); } ftglSetFontFaceSize(font, 24, 24); ftglSetFontDepth(font, 0.01); ftglSetFontOutset(font, 0, 0.1); ftglSetFontCharMap(font, ft_encoding_unicode); /* マップファイルの読み込み */ crossing_number = map_read("map2.dat"); if (crossing_number < 0) { fprintf(stderr, "couldn't read map file\n"); exit(1); } while (1) { int width, height; /* Esc が押されるかウィンドウが閉じられたらおしまい */ if (glfwGetKey(GLFW_KEY_ESC) || !glfwGetWindowParam(GLFW_OPENED)) break; glfwGetWindowSize(&width, &height); /* 現在のウィンドウサイズを取得する */ glViewport(0, 0, width, height); /* ウィンドウ全面をビューポートにする */ glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); /* バックバッファを黒で塗り潰す */ map_show(crossing_number); /* 道路網の表示 */ glfwSwapBuffers(); /* フロントバッファとバックバッファを入れ替える */ } glfwTerminate(); return 0; }