質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
GLFW

GLFWは、OpenGLを使用してアプリ開発を行うためのフレームワークです。Macにも対応しているマルチプラットフォームであることが特徴。ウィンドウ管理、解像度切り替え、入力管理などの機能を持ちます。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

GLSL

GLSL (OpenGL Shading Language) はC言語をベースとしたシェーディング言語です。

Q&A

1回答

512閲覧

M1mac でOpenGLのシェーダープログラムを使いたい

nibosi

総合スコア0

GLFW

GLFWは、OpenGLを使用してアプリ開発を行うためのフレームワークです。Macにも対応しているマルチプラットフォームであることが特徴。ウィンドウ管理、解像度切り替え、入力管理などの機能を持ちます。

OpenGL

OpenGLは、プラットフォームから独立した、デスクトップやワークステーション、モバイルサービスで使用可能な映像処理用のAPIです。

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

GLSL

GLSL (OpenGL Shading Language) はC言語をベースとしたシェーディング言語です。

0グッド

1クリップ

投稿2023/12/23 02:01

編集2023/12/23 04:33

実現したいこと

  • 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

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

肝心のここで描画処理を行うの部分にまだ何も描画処理が記述されていないように見えますね。
mainを下記のようにしてみましたが、これならいかがでしょうか。

cpp

1int main() { 2 // GLFW を初期化する 3 if (glfwInit() == GL_FALSE) { 4 // 初期化に失敗した 5 std::cerr << "Can't initialize GLFW" << std::endl; 6 return 1; 7 } 8 // プログラム終了時の処理を登録する 9 atexit(glfwTerminate); 10 11 // OpenGL Version 3.2 Core Profile を選択する 12 glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 13 glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); 14 glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); 15 glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 16 17 // ウィンドウを作成する 18 GLFWwindow *const window(glfwCreateWindow(640, 480, "Hello!", NULL, NULL)); 19 if (window == NULL) { 20 // ウィンドウが作成できなかった 21 std::cerr << "Can't create GLFW window." << std::endl; 22 return 1; 23 } 24 // 作成したウィンドウを OpenGL の処理対象にする 25 glfwMakeContextCurrent(window); 26 27 // GLEW を初期化する 28 glewExperimental = GL_TRUE; 29 if (glewInit() != GLEW_OK) { 30 // GLEW の初期化に失敗した 31 std::cerr << "Can't initialize GLEW" << std::endl; 32 return 1; 33 } 34 35 // 垂直同期のタイミングを待つ 36 glfwSwapInterval(1); 37 38 // 背景色を指定する 39 glClearColor(1.0f, 1.0f, 1.0f, 0.0f); 40 41 // バーテックスシェーダのソースプログラム 42 static constexpr GLchar vsrc[] = 43 "#version 150 core\n" 44 "in vec4 position;\n" 45 "void main()\n" 46 "{\n" 47 " gl_Position = position;\n" 48 "}\n"; 49 // フラグメントシェーダのソースプログラム 50 static constexpr GLchar fsrc[] = 51 "#version 150 core\n" 52 "out vec4 fragment;\n" 53 "void main()\n" 54 "{\n" 55 " fragment = vec4(1.0, 0.0, 0.0, 1.0);\n" 56 "}\n"; 57 // プログラムオブジェクトを作成する 58 const GLuint program(createProgram(vsrc, fsrc)); 59 60 // 頂点座標を定義する 61 // さしあたり画面全体を覆う四角形の四隅を指定しました 62 // 座標配列は成分を単純にx y z x y z...と並べただけです 63 // もっといろいろな頂点属性を使うのでしたら、頂点を表す構造体を 64 // 定義してやると見やすくなるかと思います 65 static constexpr GLfloat vertices[] = 66 { 67 -1.0f, -1.0f, 0.0f, 68 -1.0f, 1.0f, 0.0f, 69 1.0f, -1.0f, 0.0f, 70 1.0f, 1.0f, 0.0f, 71 }; 72 73 // VAOを作成する 74 GLuint vao; 75 glGenVertexArrays(1, &vao); 76 glBindVertexArray(vao); 77 78 // VBOを作成し、頂点データをセットする 79 GLuint vbo; 80 glGenBuffers(1, &vbo); 81 glBindBuffer(GL_ARRAY_BUFFER, vbo); 82 glBufferData(GL_ARRAY_BUFFER, 4 * 3 * sizeof(GLfloat), vertices, GL_STATIC_DRAW); 83 84 // 頂点属性を設定する 85 // 属性0番(つまりバーテックスシェーダ内でいうposition)は3個のGLfloatでできていて、VBO上の頭から隙間を空けずに詰まっている...と伝える 86 glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); 87 glEnableVertexAttribArray(0); 88 89 // ウィンドウが開いている間繰り返す 90 while (glfwWindowShouldClose(window) == GL_FALSE) { 91 // ウィンドウを消去する 92 glClear(GL_COLOR_BUFFER_BIT); 93 94 // シェーダプログラムの使用開始 95 glUseProgram(program); 96 97 // ここで描画処理を行う 98 glBindVertexArray(vao); 99 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 100 101 // カラーバッファを入れ替える 102 glfwSwapBuffers(window); 103 104 // イベントを取り出す 105 glfwWaitEvents(); 106 } 107 108 // VBOを削除する 109 glDeleteBuffers(1, &vbo); 110 111 // VAOを削除する 112 glDeleteVertexArrays(1, &vao); 113 114 // シェーダプログラムを削除する 115 glDeleteProgram(program); 116}

詳しくは「○○くんのために一所懸命書いたものの結局○○くんの卒業に間に合わなかったGLFWによるOpenGL入門」の「第5章 図形の描画」のあたりがご参考になるんじゃないかと思います。

投稿2023/12/24 08:40

Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問