GLFWの基本的な使い方をメモします.
*GLFW とは
OpenGLを使う上で便利な機能を提供してくれるオープンソースのライブラリです.windowの生成や入力デバイスのイベント処理を簡単に実装できます.
{{small:GLFW公式サイト: [link:http://www.glfw.org/] }}
{{small:hello world のサンプル: [link:http://www.glfw.org/documentation.html] }}
*導入方法
環境によって様々な導入方法があります.
それぞれ参考になるサイト様を紹介させて頂きたいと思います.
{{small:・Windows}}
{{small:cmakeを使う方法 ミッチ様 [link:http://mittip.hatenablog.com/entry/2013/11/19/020806] }}
{{small:NuGet を使う方法 cho_design_lab様 [link:https://qiita.com/cho_design_lab/items/a49338660b26525f3217] }}
{{small:・Linux, Mac}}
{{small:aptコマンド を使う方法 grainrigi様 [link:http://grainrigi.hatenablog.com/entry/2017/08/27/144218] }}
*基本的なwindow生成のサンプル
{#
#include <GLFW/glfw3.h>
int main(){
GLFWwindow* window;
// ライブラリglfw の初期化
if (!glfwInit()) return -1;
// ウィンドウを作成
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window) {
glfwTerminate();
return -1;
}
// 作成したウィンドウを,OpenGLの描画関数のターゲットにする
glfwMakeContextCurrent(window);
// 描画のループ
while (!glfwWindowShouldClose(window)) {
// 画面を塗りつぶす
glClear(GL_COLOR_BUFFER_BIT);
// 白色三角形の描画
{
glColor3d(1.0, 1.0, 1.0);
glBegin(GL_LINE_LOOP);
glVertex2d(+0.0, +0.9);
glVertex2d(-0.9, -0.9);
glVertex2d(+0.9, -0.9);
glEnd();
}
// 上記描画した図形を表画面のバッファにスワップする
glfwSwapBuffers(window);
// 受け取ったイベント(キーボードやマウス入力)を処理する
glfwPollEvents();
}
glfwTerminate();
return 0;
}
#}
[img:pxs5]
{{small:図1 実行結果}}
*基本的なイベント処理のサンプル
キーボードやマウス,ドラッグ&ドロップによるイベントを処理するサンプルです.
{#
#include <stdio.h>
#include <GLFW/glfw3.h>
// 各イベンドで呼び出す関数を定義
void windowSizeCB(GLFWwindow *window, int width, int height) {
printf("windowSizeCB %d %d\n", width, height);
}
void mouseButtonCB(GLFWwindow *window, int button, int action, int mods) {
printf("mouseButtonCB %d %d %d\n", button, action, mods);
}
void mousePosCB(GLFWwindow *window, double x, double y) {
printf("mousePosCB %.1lf %.1lf\n", x, y);
}
void mouseScrollCB(GLFWwindow *window, double x, double y) {
printf("mouseScrollCB %.1lf %.1lf\n", x, y);
}
void keyFunCB(GLFWwindow* window, int key, int scancode, int action, int mods) {
printf("keyFunCB %d %d %d %d\n", key, scancode, action, mods);
}
void charFunCB(GLFWwindow* window, unsigned int charInfo) {
printf("charFunCB %d\n", charInfo);
}
void dropCB(GLFWwindow *window, int num, const char **paths) {
printf("dropCB %d\n", num);
for (int i = 0; i < num; i++) {
printf("%s\n", paths[i]);
}
}
int main() {
GLFWwindow* window;
if (!glfwInit()) return -1;
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window) {
glfwTerminate();
return -1;
}
// コールバック関数の設定
{
// ウィンドウのサイズ変更時に呼び出す関数を設定
glfwSetWindowSizeCallback(window, windowSizeCB);
// マウス操作時に呼び出す関数を設定
glfwSetMouseButtonCallback(window, mouseButtonCB);
glfwSetCursorPosCallback(window, mousePosCB);
glfwSetScrollCallback(window, mouseScrollCB);
// キー入力時に呼び出す関数を設定
glfwSetKeyCallback(window, keyFunCB);
glfwSetCharCallback(window, charFunCB);
// ファイルをドラッグ&ドロップした時に呼び出す関数を設定
glfwSetDropCallback(window, dropCB);
}
glfwMakeContextCurrent(window);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
#}
*クラスを使って実装する場合のサンプル
コールバック関数の設定に少し工夫が必要です.ただ,コールバック関数の対応付けがなされたクラスを作っておけば,それを基底クラスとして使いまわすこともできると思います.
{#
#include <stdio.h>
#include <GLFW/glfw3.h>
class BaseWindow {
public:
virtual void windowSize(int width, int height) {
printf("windowSize %d %d\n", width, height);
}
virtual void mouseButton(int button, int action, int mods) {
printf("mouseButton %d %d %d\n", button, action, mods);
}
virtual void mousePos(double x, double y) {
printf("mousePos %.1lf %.1lf\n", x, y);
}
virtual void mouseScroll(double x, double y) {
printf("mouseScroll %.1lf %.1lf\n", x, y);
}
virtual void keyFun(int key, int scancode, int action, int mods) {
printf("keyFun %d %d %d %d\n", key, scancode, action, mods);
}
virtual void charFun(unsigned int charInfo) {
printf("charFun %d\n", charInfo);
}
virtual void drop(int num, const char **paths) {
printf("drop %d\n", num);
for (int i = 0; i < num; i++) {
printf("%s\n", paths[i]);
}
}
virtual void display() {
glColor3d(1.0, 1.0, 1.0);
glBegin(GL_LINE_LOOP);
glVertex2d(+0.0, +0.9);
glVertex2d(-0.9, -0.9);
glVertex2d(+0.9, -0.9);
glEnd();
}
public:
void execute(const char *name, const int width, const int height) {
if (!glfwInit()) return;
GLFWwindow *window = glfwCreateWindow(width, height, name, NULL, NULL);
if (!window) {
glfwTerminate();
return;
}
glfwMakeContextCurrent(window);
// 作成したウィンドウにコールバック関数を設定する
setCallback(window);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
display();
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
}
protected:
void _windowSize(int width, int height) {
windowSize(width, height);
}
void _mouseButton(int button, int action, int mods) {
mouseButton(button, action, mods);
}
void _mousePos(double x, double y) {
mousePos(x, y);
}
void _mouseScroll(double x, double y) {
mouseScroll(x, y);
}
void _keyFun(int key, int scancode, int action, int mods) {
keyFun(key, scancode, action, mods);
}
void _charFun(unsigned int charInfo) {
charFun(charInfo);
}
void _dropCB(int num, const char **paths) {
drop(num, paths);
}
protected:
void setCallback(GLFWwindow *window) {
// ウィンドウとクラスのポインタを関連付ける
glfwSetWindowUserPointer(window, this);
glfwSetWindowSizeCallback(window, windowSizeCB);
glfwSetMouseButtonCallback(window, mouseButtonCB);
glfwSetCursorPosCallback(window, mousePosCB);
glfwSetScrollCallback(window, mouseScrollCB);
glfwSetKeyCallback(window, keyFunCB);
glfwSetCharCallback(window, charFunCB);
glfwSetDropCallback(window, dropCB);
}
static BaseWindow* getThisPtr(GLFWwindow *window) {
return static_cast<BaseWindow*>(glfwGetWindowUserPointer(window));
}
static void windowSizeCB(GLFWwindow *window, int width, int height) {
getThisPtr(window)->_windowSize(width, height);
}
static void mouseButtonCB(GLFWwindow *window, int button, int action, int mods) {
getThisPtr(window)->_mouseButton(button, action, mods);
}
static void mousePosCB(GLFWwindow *window, double x, double y) {
getThisPtr(window)->_mousePos(x, y);
}
static void mouseScrollCB(GLFWwindow *window, double x, double y) {
getThisPtr(window)->_mouseScroll(x, y);
}
static void keyFunCB(GLFWwindow* window, int key, int scancode, int action, int mods) {
getThisPtr(window)->_keyFun(key, scancode, action, mods);
}
static void charFunCB(GLFWwindow* window, unsigned int charInfo) {
getThisPtr(window)->_charFun(charInfo);
}
static void dropCB(GLFWwindow *window, int num, const char **paths) {
getThisPtr(window)->_dropCB(num, paths);
}
};
int main() {
BaseWindow window;
window.execute("Hellow World", 640, 480);
return 0;
}
#}
>> ご意見・ご質問など お気軽にご連絡ください.info