質問: '?0'; } } int main(int argc, char* argv[]) { glutInit(&argc, argv); myInit(argv[0]); glutKeyboardFunc(myKeyboard); glutMouseFunc(myMouseFunc); glutMotionFunc(myMotionFunc); // モーションイベント用のハンドラーを登録 glutReshapeFunc(myReshape); glutDisplayFunc(myDisplay); glutMainLoop(); return 0; } ### 試したこと ここに問題に対して試したことを記載してください。 ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。
回答: GLUT自体にはUIを簡単に描画できる機能は付属していないようなので、ひとまずキーボード操作で色変更機能と描画クリア機能を作ってみるのがいいかと思います。 描いた線を消すのは、`myInit`内で初期化した時と同じように`xList`、`yList`の中身を全部(-10.0, -10.0)にリセットしてしまえばいいでしょう。 色変えについては、正直自分でもちょっと妙なやり方だとは思うのですが... * 新たな目印値-30.0を導入し、描画時、座標バッファ中にこの目印が現れたら色変えを行う。 * 変えるべき色は座標バッファのy成分、およびその次の座標のx成分とy成分に埋め込む。 といった方法を試してみました。 下記のように`myDisplay`と`myKeyboard`に変更を加え、色情報埋め込み用関数`setColor`を追加しました。 ``` void myDisplay() { int i, j; glClearColor(1.0, 1.0, 1.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); glColor3d(1.0, 0.0, 0.0); // 最初のglColor3dをDrawStringより手前に移動 DrawString(); glBegin(GL_LINE_STRIP); for (i = 0; i < POINTMAX; i++) { j = (pointnum + i) % POINTMAX; if (xList[j] == -20.0) { // 座標バッファに目印となる値が見つかったら、そこをラインストリップの区切りとする glEnd(); glBegin(GL_LINE_STRIP); } else if (xList[j] == -30.0) { // 色変更の目印が見つかったら、そこに埋め込まれた色情報を取り出してglColor3dに渡す double red = yList[j]; i++; j = (pointnum + i) % POINTMAX; double green = xList[j]; double blue = yList[j]; glColor3d(red, green, blue); } else if (xList[j] >= -1.0 && yList[j] >= -1.0) { glVertex2d(xList[j], yList[j]); } } glEnd(); glRasterPos2d(-0.9, -0.7); glutSwapBuffers(); } void setColor(double red, double green, double blue) { // 座標バッファに色変更の目印、および色情報を埋め込む xList[pointnum] = -30.0; // 目印の値 yList[pointnum] = red; // 赤 pointnum = (pointnum + 1) % POINTMAX; xList[pointnum] = green; // 緑 yList[pointnum] = blue; // 青 pointnum = (pointnum + 1) % POINTMAX; } void myKeyboard(unsigned char key, int x, int y) { if (key == 0x1B) exit(0); if (key == 'r') { // Rキー押下...赤色に変更 setColor(1.0, 0.0, 0.0); } else if (key == 'g') { // Gキー押下...緑色に変更 setColor(0.0, 1.0, 0.0); } else if (key == 'b') { // Bキー押下...青色に変更 setColor(0.0, 0.0, 1.0); } else if (key == 'y') { // Yキー押下...座標バッファの内容全体を初期値(-10.0, -10.0)に戻す for (int i = 0; i < POINTMAX; i++) { xList[i] = -10.0; yList[i] = -10.0; } } else { text[textnum] = key; textnum = (textnum + 1) % TEXTMAX; } glutPostRedisplay(); } ``` 本来なら座標だけを格納するべき`xList`、`yList`をどんどん引っかき回してしまい申し訳ないです... この先もっとプログラムを機能拡張していくつもりでしたら、そろそろ設計見直しの頃合いかもしれません。 あいにく私はCやC++の経験が足りず具体的なアドバイスができないのですが、一例としてはオブジェクト指向的に「文字列オブジェクト...文字列、文字の色、描画座標を持つ」「フリーハンド曲線オブジェクト...曲線の色、頂点座標のリストを持つ」...といった感じに図形を設計しておいて、`myDisplay`内では画面内のこれらオブジェクトの描画メソッドを順次実行していく、なんていうのはどうでしょう? ※今回はキーボード入力で各機能を実行する方式にしましたが、GLUT向けのUIキットとしてGLUI(GLUI User Interface Library, v1、GitHub - libglui/glui: GLUI is a GLUT-based C++ user interface library which provides controls such as buttons, checkboxes, radio buttons, and spinners to OpenGL applications. It is window-system independent, using GLUT or FreeGLUT.)といったものがあるようです。 検索してみただけで試してはおりませんが、ボタンなどの他にも3Dオブジェクトの移動や回転のためのコントロールも用意されているようですので、なかなか便利そうです。