実現したいこと
- M1macでGLSL のシェーダプログラムを利用したいです。
前提
C++でOlenGLのシェーダプログラムを使って、赤い画面を表示したいです。
しかし、シェーダープログラムが反映されず、白い画面のままになってしまいます。
発生している問題・エラーメッセージ
シェーダープログラムが反映されません。
コンパイル、実行はどちらも正常に行えます。エラーや警告は出ていません。
調査したこと・試したこと
コンパイルコマンド
cmd
1g++ -o main main.cpp -lglfw -lglew -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo -std=c++11
で実行すると、シェーダープログラムが反映されず、白い画面が表示される。
該当のソースコード
C++
1#ifdef __APPLE__ 2#define GL_SILENCE_DEPRECATION 3#include <GL/glew.h> 4#include <GLFW/glfw3.h> 5#endif 6 7#include <cstdlib> 8#include <fstream> 9#include <iostream> 10#include <vector> 11using namespace std; 12 13// シェーダオブジェクトのコンパイル結果を表示する 14// shader: シェーダオブジェクト名 15// str: コンパイルエラーが発生した場所を示す文字列 16GLboolean printShaderInfoLog(GLuint shader, const char *str) { 17 // コンパイル結果を取得する 18 GLint status; 19 glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 20 if (status == GL_FALSE) std::cerr << "Compile Error in " << str << std::endl; 21 // シェーダのコンパイル時のログの長さを取得する 22 GLsizei bufSize; 23 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &bufSize); 24 if (bufSize > 1) { 25 // シェーダのコンパイル時のログの内容を取得する 26 std::vector<GLchar> infoLog(bufSize); 27 GLsizei length; 28 glGetShaderInfoLog(shader, bufSize, &length, &infoLog[0]); 29 std::cerr << &infoLog[0] << std::endl; 30 } 31 return static_cast<GLboolean>(status); 32} 33 34// プログラムオブジェクトのリンク結果を表示する 35// program: プログラムオブジェクト名 36GLboolean printProgramInfoLog(GLuint program) { 37 // リンク結果を取得する 38 GLint status; 39 glGetProgramiv(program, GL_LINK_STATUS, &status); 40 if (status == GL_FALSE) std::cerr << "Link Error." << std::endl; 41 // シェーダのリンク時のログの長さを取得する 42 GLsizei bufSize; 43 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufSize); 44 if (bufSize > 1) { 45 // シェーダのリンク時のログの内容を取得する 46 std::vector<GLchar> infoLog(bufSize); 47 GLsizei length; 48 glGetProgramInfoLog(program, bufSize, &length, &infoLog[0]); 49 std::cerr << &infoLog[0] << std::endl; 50 } 51 return static_cast<GLboolean>(status); 52} 53 54// プログラムオブジェクトを作成する 55// vsrc: バーテックスシェーダのソースプログラムの文字列 56// fsrc: フラグメントシェーダのソースプログラムの文字列 57GLuint createProgram(const char *vsrc, const char *fsrc) { 58 // 空のプログラムオブジェクトを作成する 59 const GLuint program(glCreateProgram()); 60 if (vsrc != NULL) { 61 // バーテックスシェーダのシェーダオブジェクトを作成する 62 const GLuint vobj(glCreateShader(GL_VERTEX_SHADER)); 63 glShaderSource(vobj, 1, &vsrc, NULL); 64 glCompileShader(vobj); 65 // バーテックスシェーダのシェーダオブジェクトをプログラムオブジェクトに組み込む 66 if (printShaderInfoLog(vobj, "vertex shader")) 67 glAttachShader(program, vobj); 68 glDeleteShader(vobj); 69 } 70 if (fsrc != NULL) { 71 // フラグメントシェーダのシェーダオブジェクトを作成する 72 const GLuint fobj(glCreateShader(GL_FRAGMENT_SHADER)); 73 glShaderSource(fobj, 1, &fsrc, NULL); 74 glCompileShader(fobj); 75 // フラグメントシェーダのシェーダオブジェクトをプログラムオブジェクトに組み込む 76 if (printShaderInfoLog(fobj, "fragment shader")) 77 glAttachShader(program, fobj); 78 glDeleteShader(fobj); 79 } 80 // プログラムオブジェクトをリンクする 81 glBindAttribLocation(program, 0, "position"); 82 glBindFragDataLocation(program, 0, "fragment"); 83 glLinkProgram(program); 84 // 作成したプログラムオブジェクトを返す 85 if (printProgramInfoLog(program)) return program; 86 // プログラムオブジェクトが作成できなければ 0 を返す 87 glDeleteProgram(program); 88 return 0; 89} 90 91int main() { 92 // GLFW を初期化する 93 if (glfwInit() == GL_FALSE) { 94 // 初期化に失敗した 95 std::cerr << "Can't initialize GLFW" << std::endl; 96 return 1; 97 } 98 // プログラム終了時の処理を登録する 99 atexit(glfwTerminate); 100 101 // OpenGL Version 3.2 Core Profile を選択する 102 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 103 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); 104 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 105 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 106 107 // ウィンドウを作成する 108 GLFWwindow *const window(glfwCreateWindow(640, 480, "Hello!", NULL, NULL)); 109 if (window == NULL) { 110 // ウィンドウが作成できなかった 111 std::cerr << "Can't create GLFW window." << std::endl; 112 return 1; 113 } 114 // 作成したウィンドウを OpenGL の処理対象にする 115 glfwMakeContextCurrent(window); 116 117 // GLEW を初期化する 118 glewExperimental = GL_TRUE; 119 if (glewInit() != GLEW_OK) { 120 // GLEW の初期化に失敗した 121 std::cerr << "Can't initialize GLEW" << std::endl; 122 return 1; 123 } 124 125 // 垂直同期のタイミングを待つ 126 glfwSwapInterval(1); 127 128 // 背景色を指定する 129 glClearColor(1.0f, 1.0f, 1.0f, 0.0f); 130 131 // バーテックスシェーダのソースプログラム 132 static constexpr GLchar vsrc[] = 133 "#version 150 core\n" 134 "in vec4 position;\n" 135 "void main()\n" 136 "{\n" 137 " gl_Position = position;\n" 138 "}\n"; 139 // フラグメントシェーダのソースプログラム 140 static constexpr GLchar fsrc[] = 141 "#version 150 core\n" 142 "out vec4 fragment;\n" 143 "void main()\n" 144 "{\n" 145 " fragment = vec4(1.0, 0.0, 0.0, 1.0);\n" 146 "}\n"; 147 // プログラムオブジェクトを作成する 148 const GLuint program(createProgram(vsrc, fsrc)); 149 150 // ウィンドウが開いている間繰り返す 151 while (glfwWindowShouldClose(window) == GL_FALSE) { 152 // ウィンドウを消去する 153 glClear(GL_COLOR_BUFFER_BIT); 154 155 // シェーダプログラムの使用開始 156 glUseProgram(program); 157 158 // 159 // ここで描画処理を行う 160 // 161 // カラーバッファを入れ替える 162 glfwSwapBuffers(window); 163 // イベントを取り出す 164 glfwWaitEvents(); 165 } 166}
補足情報(FW/ツールのバージョンなど)
PCの環境
OS: macOS Monterey version 12.3.1
MacBook Air (M1, 2020)
チップ: Apple M1
メモ:16GB
g++バージョン
Apple clang version 13.1.6 (clang-1316.0.21.2.3)
コンパイルコマンド
cmd
1g++ -o main main.cpp -lglfw -lglew -framework Cocoa -framework OpenGL -framework IOKit -framework CoreVideo -std=c++11
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。