📐

OpenGLで三角形を描く

2022/12/05に公開

以前、「MacでOpen GLの開発環境(VS Code)を構築する」という記事を書きました。
この記事では、開発環境の構築しかしていなかったので今回は簡単な図形の描き方を記します。
また、詳細なソースコードの説明はせず、三角形を描くことに注目して解説します。
https://zenn.dev/k41531/articles/aa375915ce4e8c

参考資料

https://learnopengl.com/
https://www.khronos.org/opengl/wiki/Main_Page
https://www.youtube.com/watch?v=45MIykWJ-C4

ファイルの構成

依存ファイルや設定ファイルについては、冒頭で紹介した私の記事もしくはリポジトリを参照ください。
https://github.com/k41531/opengl-mac

.
├── EBO.cpp
├── EBO.h
├── VAO.cpp
├── VAO.h
├── VBO.cpp
├── VBO.h
├── default.frag
├── default.vert
├── gl.c
├── main.cpp
├── shaderClass.cpp
├── shaderClass.h
├── dependencies
└── .vscode

VAO

Vertex Array Object
1つまたは複数のBuffer Objectを持つオブジェクトで、頂点データに必要な情報を全て保存します。

Buffer Object

GPUに割り当てられたフォーマットされていないメモリの配列を格納するオブジェクト。
頂点データやピクセルデータなど様々なものを格納するために使用することができます。

VBO

Vertext Buffer Object
Buffer Objectが頂点データを保存するために使われた場合の通称です。
頂点の位置を表す座標などが格納されます。
DirectXでは頂点バッファーと呼ばれているものです。

EBO

Element Buffer Object
EBOは、ポリゴンを描くのに必要な頂点の番号が格納されます。
また、VAOがバインドされている間は最後にバインドされたEBOがVAOにリンクされます。
DirectXではインデックスバッファーと呼ばれているものです。

三角形(トライフォース)を描く

頂点座標と頂点の順序を表す番号の配列で用意します。
ちなみに、float型ではなくGLfloatを使う理由は、使用するシステムごとにサイズが変わらないようにするためです。

トライフォースなので頂点が6つ必要です。

GLfloat vertices[] =
{
  -0.5f, -0.5f * float(sqrt(3)) / 3, 0.0f,    // 左下の頂点
  0.5f, -0.5f * float(sqrt(3)) / 3, 0.0f,     // 右下の頂点
  0.0f, 0.5f * float(sqrt(3)) * 2 / 3, 0.0f,  // 上の頂点
  -0.5f / 2, 0.5f * float(sqrt(3)) / 6, 0.0f, // 左の頂点
  0.5f / 2, 0.5f * float(sqrt(3)) / 6, 0.0f,  // 右の頂点
  0.0f, -0.5f * float(sqrt(3)) / 3, 0.0f      // 下の頂点
};

どの頂点を使って三角形を描くかを示す整数の配列

GLuint indices[] =
{
  0, 3, 5, // 左下の三角形
  3, 2, 4, // 右下の三角形
  5, 4, 1  // 上の三角形
};

VAO、VBO、EBOを使ってGPUに頂点データを格納する。

// VAOを生成してバインドする。
VAO VAO1;
VAO1.Bind();

// VBOとEBOを作成し、先ほどの配列をそれぞれのオブジェクトにリンク付けする。
VBO VBO1(vertices, sizeof(vertices));
EBO EBO1(indices, sizeof(indices));

// VBOをVAOにリンクする。
VAO1.LinkVBO(VBO1, 0);

// 誤って変更しないようにするために、リンクが終わったらバインドを解除する。
VAO1.Unbind();
VBO1.Unbind();
EBO1.Unbind();

描画に関する関数

// 描きたい頂点データが含まれたVAOをバインドし、OpenGLが使えるようにする。
VAO1.Bind();
// EBOの情報をもとに頂点の順番を取得し描画します。
glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_INT, 0);

フルのコードはこちらです。
https://github.com/k41531/opengl-mac/blob/main/main.cpp

Discussion