June 24, 2020
GLFWの本家は https://www.glfw.org/ まず, Introductionを見てみよう. プログラムの説明が先でその後にビルドの説明があるが, とりあえずビルドできることが確認できないと一生懸命仕様を把握しようとしたのにビルドできないなんて元の木阿弥だと嘆くことになる. Once you have written a program, see Compiling GLFW and Building applications. と説明があるが, Compiling GLFW はGLFWライブラリをCMakeを使ってソースビルドしてインストールしたいマゾがやることなので, brew install glfwで素直にインストールする. Building applications のページを見てみる.
#include <GLFW/glfw3.h> ではwindows.hなどプラットフォーム特有のヘッダーをglfw側がインクルードするので自分でインクルードは禁止. opengl関係も禁止. If you are using an OpenGL extension loading library such as glad, the extension loader header should be included before the GLFW one. とあるが, いきなりgladの名前が出てきてloaderとはという疑問に有無も言わせずただリンクだけを貼って説明した気になっており怠慢だ. 少なくとも私はgladではない. リンク先を見てみると, GL/GLES/EGL/GLX/WGL Loader-Generator based on the official specs. と書いており, loaderとは厳密に違ってloader generatorというさらによくわからない概念を押しつけられる. Use the webservice to generate the files you need! とあるが, いきなりwebserviceのリンクを貼られても困る. まず, gladはあくまでgeneratorでありpythonアプリケーションである. このgeneratorを使うことで, 自分が使うべきopenglやvulkanなどのグラフィックAPIの機能を自分で細かくインクルードすることなくプラットフォームに応じてgenerator側が対応してくれる. webserviceを使うことでインストールしなくても手軽に生成できる.
glfwの説明に戻ると, gladはglfwよりも前にインクルードしなくてはならないという.
macの環境で解説する. windowsなどは特殊過ぎて訳が分からないので. With CMake and GLFW source はGLFWをいちいちソースコンパイルしたいマゾがやることなので飛ばして, 次の項目をみる:
With Cmake and installed GLFW binaries:Cmakeはありがたみがよく分からない.
With Xcode on macOS: XCode難しいのでよく分からない.
With command-line on macOS: とてもわかりやすい. 今までの苦労は何だったのかと思わされる. 長々と説明していないで, コマンド一行で一発のことをわざわざCmake書いて...と面倒なことをして. staticにしたいならば -lglfwでなくて-lglfw3にすればいいと書いているが, macOSはdynamicとstaticの区別がそんなに難しいものだったのかよく分からず. しかも, -lglfw3にするとコンパイルできていない.
cc -o myprog myprog.c -lglfw -framework Cocoa -framework OpenGL -framework IOKit
さて, サンプルプログラムはGetting startedに用意されていたが, gladライブラリの導入が面倒でビルドが難しい. Gettting startedの癖にビルドが難しいプログラムを用意するのはやめて欲しいものだ. ここでは, 出典を忘れたが上のコマンドでコンパイルできるプログラムを用意した. 実行すると何もしないウィンドウが表示されるだけだ.
#include <GLFW/glfw3.h>
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glfwTerminate();
return 0;
}