M1 macのc++でGLFWを使ってみる

2022/08/07

OpenGL についてまだ全然分かっていませんが、GLFW を使ってアニメーションを表示したいと思っています。とりあえず、M1 mac の c++でウインドウを表示しました。

目次

環境

> uname -m
arm64
> brew config
macOS: 12.5-arm64
Rosetta 2: false

GLFW をインストール

> brew install glfw
> brew --prefix glfw
/opt/homebrew/opt/glfw

コンパイル・実行してみるコード

インストールしただけだとエラーになる

❯ g++ -o main main.cpp -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo
main.cpp:1:10: fatal error: 'GLFW/glfw3.h' file not found
#include <GLFW/glfw3.h>

CPATH, LIBRARY_PATH を環境変数に追加

> vim ~/.zshrc
# 下記を追加
export CPATH=/opt/homebrew/include
export LIBRARY_PATH=/opt/homebrew/lib

コンパイル・実行成功

  • コンパイル成功したけど、warning が沢山出る。これは Apple が OpenGL を基本廃止(非推奨)にしているかららしい。
❯ g++ -o main main.cpp -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo
main.cpp:23:5: warning: 'glClear' is deprecated: first deprecated in macOS 10.14 - OpenGL API deprecated. (Define GL_SILENCE_DEPRECATION to silence these warnings) [-Wdeprecated-declarations]
    glClear(GL_COLOR_BUFFER_BIT);
    ^
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/OpenGL.framework/Headers/gl.h:2394:13: note: 'glClear' has been explicitly marked deprecated here
extern void glClear (GLbitfield mask) OPENGL_DEPRECATED(10.0, 10.14);

warning を非表示にしてみる

  • コードに下記を追加する。
    • #define GL_SILENCE_DEPRECATION によって、非表示になる。
#ifdef __APPLE__
#define GL_SILENCE_DEPRECATION
#include <GLFW/glfw3.h>
#endif

Makefile を作る

CPPFLAGS := -I src/includes
FRAMEWORKS := -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo
LIBS := -lglfw

BUILD_DIR := ./bin
SRC_DIRS := ./src
SRCS := $(shell find $(SRC_DIRS) -name *.cpp)
OBJS := $(addprefix $(BUILD_DIR)/, $(subst .cpp,.o, $(notdir $(SRCS))))

$(BUILD_DIR)/main: $(OBJS)
	clang++ -o $@ $(LIBS) $(FRAMEWORKS) $^
$(BUILD_DIR)/%.o: src/%.cpp
	clang++ -c -o $@ $(CPPFLAGS) $<

do:
	@bin/main
clean:
	rm -rf bin
	mkdir bin

Debug できない

  • vimspector で、.vimspector.jsonを下記のように設定してみたけど、エラーになる。
  • -lglfwがあるとエラーになるっぽい。
{
	"configurations": {
		"CodeLLDB": {
			"adapter": "CodeLLDB",
			"variables": {
				"BUILDME": {
					"shell": "clang++ -o ${workspaceRoot}/bin/debug -g -lglfw -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo ${workspaceRoot}/src/main.cpp"
				}
			},
			"configuration": {
				"request": "launch",
				"program": "${workspaceRoot}/bin/debug",
				"stdio": [null, null, null]
			}
		}
	}
}

青いウインドウを表示するコード

#ifdef __APPLE__
#define GL_SILENCE_DEPRECATION
#include <GLFW/glfw3.h>
#endif

#include <iostream>
using namespace std;

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
  if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
    glfwSetWindowShouldClose(window, GLFW_TRUE);
}

int main(void) {
  GLFWwindow* window;
  if (!glfwInit()) return -1;

  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

  window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
  if (!window) {
    cout << "failed to create window." << endl;
    glfwTerminate();
    return -1;
  }
  cout << "opened window" << endl;
  glfwSetKeyCallback(window, key_callback);
  glfwMakeContextCurrent(window);
  glfwSwapInterval(1);

  const GLubyte* renderer = glGetString(GL_RENDERER);
  const GLubyte* version = glGetString(GL_VERSION);
  std::cout << "Renderer: " << renderer << std::endl;
  std::cout << "OpenGL version supported: " << version << std::endl;

  glClearColor(0.0f, 0.3f, 0.6f, 0.3f);

  while (!glfwWindowShouldClose(window)) {
    glClear(GL_COLOR_BUFFER_BIT);
    glfwSwapBuffers(window);
    glfwPollEvents();
  }

  glfwTerminate();
  cout << "closed window" << endl;
}

リポジトリ

https://github.com/edo1z/cpp-glfw-1

表示されるウインドウ

表示される青いウインドウ

Rust🦀, Network⚡, PostgreSQL🐘, Unity🎮

Tags

rust  (9)
rocket  (7)
svelte  (5)
c++  (4)
ethereum  (3)
solidity  (3)
vscode  (3)
sqlx  (3)
glfw  (2)
opengl  (2)
nestjs  (2)
graphql  (2)
render  (2)
wsl2  (2)
truffle  (1)
goerli  (1)
geth  (1)
hardhat  (1)
nft  (1)
gui  (1)
tetris  (1)
next.js  (1)
jwt  (1)
nextauth  (1)
node.js  (1)
prisma  (1)
passport  (1)
urql  (1)
codegen  (1)
mdsvex  (1)
markdown  (1)
tmux  (1)
nvim  (1)
axum  (1)
atcoder  (1)
vim  (1)
pacman  (1)
tracing  (1)