OpenGL最小入門
この記事では以下の視点からOpenGLについて理解を深めていきます。
- 頂点と描画例
- 透視投影とは
- シェーダーとは
また以下の事は扱いません。
- UVと画像表示
- ファイル読み込み
- 様々な最適化
頂点と描画例
頂点とは3D空間の中にある1つの座標をx, y, zの3つの小数で表します。
これから点、線、三角形、四角形といった簡単な図形の描画例を見ていきます。
まずは頂点を1つ表示
座標情報と点の大きさを指定します。大きさを指定しないと点が小さすぎて見つけにくいので、大きめを指定します。
model.SetVertices({
0., 0, 0,
});
model.DrawLines(100.0f);
描画するとこんな感じ。座標0が真ん中を表します。
次に頂点を2つ表示
もう一つ座標を追加し2つの頂点を指定します。
model.SetVertices({
0.5f, 0, 0,
0.7f, 0.5f, 0
});
model.SetDrawLines(100.0f);
右上に点が追加されました。x座標が正だと右、y座標が正だと上に移動します。負の場合はそれぞれ逆方向に移動します。
線を表示
座標を2つと「線を引く」命令で線となります。
model.SetVertices({
0.5f, 0, 0,
-0.5f, 0, 0,
});
model.DrawLines(100.0f);
次に線を2本引いてみます。
model.SetVertices({
0.5f, 0, 0,
-0.5f, 0, 0,
0.5f, 0.5f, 0,
-0.5f, 0.5f, 0,
});
model.DrawLines(100.0f);
そして三角形を表示
三角形はこれまでと少し違います。頂点3つに加え、どの順番で頂点を描画するか順序を指定しないといけません。この順序は頂点インデックスと呼ばれています。
model.SetVertices({
0.5f, -0.5f, 0,![index.png]
0, 0.5f, 0,
-0.5f, -0.5f, 0,
});
model.DrawTriangles({
0, 1, 2
});
最後に四角形を表示
四角形は2つの三角形を合わせて描画します。ここでは4つの頂点と頂点インデックスの組み合わせで、2つの三角形を表現しています。
model.SetVertices({
0.5, -0.5, 0,
0.5, 0.5, 0,
-0.5, 0.5, 0,
-0.5, -0.5, 0,
});
model.DrawTriangles({
0, 1, 2,
0, 2, 3,
});
透視投影とは
透視投影(perspective projection)という図法を使えば3Dっぽく見せることができます。近くのものはより大きく、遠くのものはより小さく写す事で遠近感を表現できます。
透視投影のイメージ図。zが0に近い程に大きく、zが大きくなるに連れ小さく描画されます。
ゲームつくろー!の「② 視錐台を描画空間に変換する」より
引用元サイトで透視投影の理論と計算方法の紹介もあります
これまでと比べて少し複雑ですが、透視投影を使い右斜上からの視点で正方形を描画してみます。
// 正方形の頂点は8点、各頂点はx y zの3つを持つ
model.SetVertices({
1.0, -1.0, -1.0,
1.0, -1.0, 1.0,
-1.0, -1.0, 1.0,
-1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
1.0, 1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, 1.0, -1.0
});
// 正方形の面は6つ、それぞれの面を2つの三角形で表現
model.DrawTriangles({
1, 3, 0,
7, 5, 4,
4, 1, 0,
5, 2, 1,
2, 7, 3,
0, 7, 4,
1, 2, 3,
7, 6, 5,
4, 5, 1,
5, 6, 2,
2, 6, 7,
0, 3, 7
});
// カメラの座標(4, 2, 6)から、正方形の座標(0, 0, 0)を見る射影行列を求める
glm::mat4 mvp = camera.LookAt(glm::vec3(4, 2, 6), glm::vec3(0, 0, 0));
model.SetMVP(mvp);
シェーダーとは
大きく2つの種類があります。「頂点シェーダー」と「フラグメントシェーダー」です。フラグメントシェーダはOpenGLの用語でDirectXでは「ピクセルシェーダー」と呼ばれています。
頂点シェーダーの例。
全ての頂点に同じ処理を行えます。
positionにプログラムで指定した(-1.0, 0.0, -0.5)とかの座標が、mvpには透視投影を行うための行列情報が格納されます。
#version 450
layout (location = 0) in vec3 position;
uniform mat4 mvp;
void main()
{
gl_Position = mvp * vec4(position, 1.0);
}
フラグメントシェーダーの例。
描画対象のピクセルの色を決めています。
vec4(赤, 緑, 青, 透明度)を表し、赤緑青の場合は全て1.0で白、全て0.0で黒を表しその中間で様々な色を表現します。透明度は1.0で不透明、0.0で透明(見えない)、その中間で半透明を表しています。
#version 450
out vec4 out_color;
void main()
{
out_color = vec4(1.0, 1.0, 1.0, 1.0);
}
終わりに
記事で用いたサンプルプログラムと、更に進んだ内容を勉強するための参考URLを記載しておきます。
参考URL
サンプルプログラムの構成
git clone https://github.com/hythof/opengl_tutorial.git
動作確認環境
- Windows 7 (64 bit)
- Microsoft Visual Studio 2015 Pro
- GLFW 3.2. (zlib/libpng license)
- GLEW 2.0 (license link)
- glm 0.9.8.0 (MIT license)
パス | 説明 |
---|---|
src/gldemo/gldemo.sln | VS2015のソリューション |
src/gldemo/gldemo/main.cpp | サンプルプログラムのmain関数 |
src/gldemo/vendors/ | 一般公開されているライブラリ |