前回の第1回に引き続き、OpenGLの勉強を続けていきます。
最終的には3DCGの描画へと進みますが、その手始めとしてまず2Dで何かを描画してみたいと思います。
今回の環境
・Windows 10
・Visual Studio 2015 Community
2Dでの図形の描画
OpenGLでの図形の描画方法は様々ありますが、今回は一番簡単かつ原始的なやり方で描画を行ってみたいと思います。
ソースコードと実行結果は以下となります。
/* ------------------------------------------------------ | |
基本図形による2D描画の実施 | |
--------------------------------------------------------*/ | |
#include <GL/glut.h> | |
#include <iostream> | |
int display_num = 0; | |
// 描画処理が必要なときに呼ばれる | |
void display(void) | |
{ | |
glClear(GL_COLOR_BUFFER_BIT); // カラーバッファを初期化する | |
glBegin(GL_LINES); | |
glColor3f(1.0, 0.0, 0.0); | |
glVertex2f(-0.8f, -0.8f); // (1.0, 0.0, 0.0) 赤 ① | |
glVertex2f(-0.8f, 0.8f); // (1.0, 0.0, 0.0) 赤 ② | |
glColor3f(0.0, 1.0, 0.0); | |
glVertex2f(0.0f, -0.8f); // (0.0, 1.0, 0.0) 緑 ③ | |
glVertex2f(0.0f, 0.8f); // (0.0, 1.0, 0.0) 緑 ④ | |
glColor3f(0.0, 0.0, 1.0); | |
glVertex2f(0.8f, -0.8f); // (0.0, 0.0, 1.0) 青 ⑤ | |
glColor3f(1.0, 1.0, 0.0); | |
glVertex2f(0.8f, 0.8f); // (1.0, 1.0, 0.0) 黄 ⑥ | |
glEnd(); | |
glBegin(GL_TRIANGLES); | |
glColor3f(1.0, 0.0, 0.0); | |
glVertex2f(-0.4f, -0.4f); // (1.0, 0.0, 0.0) 赤 ⑦ | |
glVertex2f(-0.4f, 0.4f); // (1.0, 0.0, 0.0) 赤 ⑧ | |
glColor3f(1.0, 0.0, 1.0); | |
glVertex2f(-0.2f, 0.0f); // (1.0, 0.0, 1.0) 紫 ⑨ | |
glEnd(); | |
glFlush(); // 描画を行う | |
} | |
void initialize(void) | |
{ | |
glClearColor(1.0, 1.0, 1.0, 1.0); // 画面を白にする | |
} | |
int main(int argc, char** argv) | |
{ | |
glutInit(&argc, argv); // GLUTを初期化する | |
glutInitWindowSize(800, 600); // 画面サイズを指定する | |
glutInitWindowPosition(100, 100); // 画面の初期位置を指定する | |
glutInitDisplayMode(GLUT_RGBA); // 表示モード設定 | |
glutCreateWindow("OpenGL Window"); // ウィンドウの名前 | |
// コールバック関数の設定 | |
glutDisplayFunc(display); // 描画処理が必要なときに呼ばれる | |
initialize(); // 初期化 | |
glutMainLoop(); // 毎フレームのLoop | |
return 0; | |
} |
上記のソースコードを実行すると3本の直線と一つの三角形が描画されます。
glBegin()とglEnd()を用いた図形の描画
glBegin()に図形の形状を指定し、glEnd()との間に頂点を記述することで図形を書くことができます。
まず座標の定義ですが、デフォルトではウィンドウの左下が(-1,-1)、ウィンドウの右上が(1,1)になります。
「glBegin(GL_LINES);」と記述した場合には直線が記述されます。
直線を構成するためには点が二つ必要なので、1つ目と2つ目の頂点、3つ目と4つ目の頂点……と結ばれていくことになります。
glBegin(GL_LINES)~glEnd()の間に複数の直線を書くこともできます。これは他の図形についても同様です。
glBegin(GL_LINES); glColor3f(1.0, 0.0, 0.0); glVertex2f(-0.8f, -0.8f); // (1.0, 0.0, 0.0) 赤 ① glVertex2f(-0.8f, 0.8f); // (1.0, 0.0, 0.0) 赤 ② glColor3f(0.0, 1.0, 0.0); glVertex2f(0.0f, -0.8f); // (0.0, 1.0, 0.0) 緑 ③ glVertex2f(0.0f, 0.8f); // (0.0, 1.0, 0.0) 緑 ④ glColor3f(0.0, 0.0, 1.0); glVertex2f(0.8f, -0.8f); // (0.0, 0.0, 1.0) 青 ⑤ glColor3f(1.0, 1.0, 0.0); glVertex2f(0.8f, 0.8f); // (1.0, 1.0, 0.0) 黄 ⑥ glEnd(); glBegin(GL_TRIANGLES); glColor3f(1.0, 0.0, 0.0); glVertex2f(-0.4f, -0.4f); // (1.0, 0.0, 0.0) 赤 ⑦ glVertex2f(-0.4f, 0.4f); // (1.0, 0.0, 0.0) 赤 ⑧ glColor3f(1.0, 0.0, 1.0); glVertex2f(-0.2f, 0.0f); // (1.0, 0.0, 1.0) 紫 ⑨ glEnd();
次に頂点色の扱いですが、 glColor3fなどでRGBの値を設定できます。最小が0で最大が1となります。
ポイントとなってくるのは、以下のように一度定義したカラーは、glColor関数が再定義されるまでの全ての対象に適用されていくということです。
一度赤の色を定義したら、その後の頂点は全て赤になります。
赤から緑に変えると、その後の色は全て緑になります。
また、色に関しては例えば点Aと点Bを結んだ直線で点Aと点Bの色が違う場合、点Aの色から点Bの色に向かって滑らかにグラデーションした図形が描画されます。
まとめ
今回は、非常に原始的に一つ一つの図形を定義して、三角形や直線を書いてみました。
OpenGLにはもっと効率的に頂点を記述する方法はたくさんあり、それらはOpenGLが新しくなっていく度に追加されてきた機能のようです。
そのあたりについても、今後勉強していくと共に、3DCGの扱いや、他のコールバック関数の扱い等についても学んでいきたいですね。