【OpenGL】エンジンを使わないゲーム開発 -GLUTによる図形の描画-

#緒論
[前回表示したウィンドウ](https://qiita.com/Kosuke418/items/2bd2661e824e925c25cd)に自由な描画をできるようになることを目的とする．
#方法
前回，警告文を消さずにプログラムを書いたが以下のサイトより
[【XCode】Mac OSX 10.9 でも GLUTを非警告で使う](http://melank.hatenablog.com/entry/2014/05/20/205858)

```cpp:
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
```
で警告文を消すことができた．
###1.描画する

glBeginとglEndでくくりglVertex2dで座標の指定をするのが一連の流れのようだ．

```cpp:
void Display()
{
    // (GLbitfield mask)ウィンドウを塗りつぶす maskは塗りつぶすためのバッファを指定する
    glClear(GL_COLOR_BUFFER_BIT);
    
    // ▼図形を描くためのプログラム▼
    // (GLdouble r, GLdouble g, GLdouble b)これから描画するものの色を指定する
    glColor3d(0.0, 0.0, 0.0);
    // (GLnum mode)modeに図形タイプを入力 LINE_LOOPは折れ線を描く
    glBegin(GL_LINE_LOOP);
    // (GLdouble x, GLdouble y)二次元の座標値を設定する
    glVertex2d(-0.9, -0.9);
    glVertex2d(0.9, -0.9);
    glVertex2d(0.9, 0.9);
    glVertex2d(-0.9, 0.9);
    // (void)Begin~Endまでに図形の各頂点の座標値を指定する
    glEnd();
    // ▲図形を描くためのプログラム▲
    
    // (void)まだ実行されていないOpenGLの命令を実行
    glFlush();
}
```

結果が以下の通り．今回glBeginのmodeで指定したGL_LINE_LOOPは折れ線を描くものなので指定した座標を繋げた折れ線が描画された．
![スクリーンショット 2019-12-14 16.31.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499636/a9d0031b-548c-5bf7-0da4-f57be01f7956.png)

modeには以下のタイプが指定できるようだ．

>glBegin() の引数 mode に指定できる図形のタイプには以下のようなものがあります. 詳しくは man glBegin を参照してください.
>>GL_POINTS
点を打ちます.
GL_LINES
2 点を対にして, その間を直線で結びます.
GL_LINE_STRIP
折れ線を描きます.
GL_LINE_LOOP
折れ線を描きます. 始点と終点の間も結ばれます.
GL_TRIANGLES / GL_QUADS
3 / 4 点を組にして, 三角形 / 四角形を描きます.
GL_TRIANGLE_STRIP / GL_QUAD_STRIP
一辺を共有しながら帯状に三角形／四角形を描きます.
GL_TRIANGLE_FAN
一辺を共有しながら扇状に三角形を描きます.
GL_POLYGON
凸多角形を描きます.

###2.触ってみる

星型とか描画したいと思い，多角形を描くための関数を作ってみた．

```cpp:
void Polygon(int N)
{
    glColor3d(1.0, 0.0, 0.0);
    for(int i=0;i<N;i++)
    {
        glVertex2d(cos(PI/180*(90+i*360/N))*0.9, sin(PI/180*(90+i*360/N))*0.9);
    }
}
```
これの引数Nを5にしてfor文の条件を(i=0;i<2*n;i+=2)にするとできる．色指定を少し変えて以下の通りになった．
![スクリーンショット 2019-12-14 16.42.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499636/4d083732-021f-47d8-9f13-09c9c560514b.png)
#結果

色々作って遊んでみた．今回作ったPolygon関数の頂点の数を増やせば，ほぼ円になるので日の丸になりました．今回作成した描画は以下の通り．

![スクリーンショット 2019-12-13 15.15.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499636/6f90d3fb-d7c7-ca7a-a49e-a420621ebc0c.png)

<details><summary>main.cpp</summary><div>

```cpp:main.cpp
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#include <math.h>
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#define PI 3.141592

// 多角形を描画するための関数 Nは頂点の数
void Polygon(int N)
{
    for(int i=0;i<N;i++)
    {
        glVertex2d(cos(PI/180*(90+i*360/N))*0.9, sin(PI/180*(90+i*360/N))*0.9);
    }
}

// この中に描画したいものを入れる
void Display()
{
    // (GLbitfield mask)ウィンドウを塗りつぶす maskは塗りつぶすためのバッファを指定する
    glClear(GL_COLOR_BUFFER_BIT);
    
    // ▼図形を描くためのプログラム▼
    // (GLdouble r, GLdouble g, GLdouble b)これから描画するものの色を指定する
    glColor3d(1.0, 0.0, 0.0);
    // (GLnum mode)modeに図形タイプを入力 LINE_LOOPは折れ線を描く
    glBegin(GL_POLYGON);
    // (GLdouble x, GLdouble y)二次元の座標値を設定する
    Polygon(100);
    // (void)Begin~Endまでに図形の各頂点の座標値を指定する
    glEnd();
    // ▲図形を描くためのプログラム▲
    
    // (void)まだ実行されていないOpenGLの命令を実行
    glFlush();
}

// 初期化処理を行う関数
void init(void)
{
    // (GLclampf R, GLclampf G, GLclampf B, GLclampf A)glclearでウィンドウを塗りつぶす際の色の指定
    glClearColor(1.0, 1.0, 1.0, 1.0);
}

int main(int argc, char *argv[])
{
    // (int *argcp, char **argv)GLUTとOpenGL環境の初期化
    glutInit(&argc, argv);
    // (unsigned int mode)ディスプレイの表示モードを設定 GLUT_RGBAを指定すると色の指定を三原色で行える
    glutInitDisplayMode(GLUT_RGBA);
    // (char *name)ウィンドウを開く関数
    glutCreateWindow("Title");
    // (void (*func)(void))ウィンドウが開かれたり再描画の際に実行
    glutDisplayFunc(Display);
    init();
    // (void)無限ループの関数，イベント待ち状態
    glutMainLoop();
    return 0;
}
```

</div></details>

#結論

- 2D描画できるようになった！