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

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

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

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

GLSL

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

Q&A

解決済

1回答

3011閲覧

glslのフラグメントシェーダでコンパイルエラー 0:1: '<' : syntax error: syntax error

goto-c

総合スコア3

OpenGL

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

GLSL

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

0グッド

1クリップ

投稿2020/07/15 02:28

前提・実現したいこと

OpenGLとGLFWを使ってシェーダープログラミングをしています。
シェーダのソースファイルを読み込んでコンパイル、リンクする関数を作成しているのですが、フラグメントシェーダのコンパイルで失敗してしまいます。
glslはversion 120を使用しています。

発生している問題・エラーメッセージ

実行結果の全文です。

glGetShaderInfoLog()を使用してフラグメントシェーダのコンパイルログを取得した結果、0:1: '<' : syntax error: syntax errorと表示されています。

read vertex file succeeded ! vertex shader compile succeeded ! read fragment file succeeded ! ERROR::SHADER::FRAGMENT::COMPILATION_FAILEDERROR: 0:1: '<' : syntax error: syntax error ERROR::SHADER::PROGRAM::LINKAGE_FAILEDERROR: One or more attached shaders not successfully compiled 1 2 shader program: 3

こちらは、シェーダのソースプログラムを読み込んで表示した結果です。

read vrt_shader: #version 120 varying vec3 normal; void main(){ gl_Position = ftransform(); normal = vec3(gl_NormalMatrix * gl_Normal); } read frg_shader: #version 120 varying vec3 normal; void main(){ gl_FragColor = vec4(0.5*normal + 0.5, 1); }

該当のソースコード

C++

1std::string read_shader_file(std::string &f) 2{ 3 std::string source; 4 source.clear(); 5 6 std::ifstream fin; 7 fin.open(f); 8 if(fin.fail()) 9 std::cout << "shader source file open failed" << std::endl; 10 11 const int BUFF_SIZE = 1024; 12 char buff[BUFF_SIZE]; 13 14 while (!fin.eof()){ 15 fin.getline(buff, BUFF_SIZE); 16 source += buff; 17 source += "\n"; 18 } 19 source.pop_back(); 20 source += "\0"; 21 22 return source; 23} 24 25int use_shader(std::string &vrt_path, 26 std::string &frg_path) 27{ 28 const char *glslvrt = (read_shader_file(vrt_path)).c_str(); 29 const char *glslfrg = (read_shader_file(frg_path)).c_str(); 30 31 std::cout << "read vrt_shader: " << std::endl; 32 std::cout << read_shader_file(vrt_path) << std::endl; 33 std::cout << "read frg_shader: " << std::endl; 34 std::cout << read_shader_file(frg_path) << std::endl; 35 36 if (glslvrt == NULL){ 37 std::cout << "Could not read file: " << vrt_path << std::endl; 38 return -1; 39 } 40 else std::cout << "read vertex file succeeded !" << std::endl; 41 int vertexShader = glCreateShader(GL_VERTEX_SHADER); 42 glShaderSource(vertexShader, 1, &glslvrt, nullptr); 43 glCompileShader(vertexShader); 44 int success; 45 char infoLog[512]; 46 glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); 47 if (!success) 48 { 49 glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog); 50 std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED" << infoLog << std::endl; 51 } 52 else std::cout << "vertex shader compile succeeded !" << std::endl; 53 54 55 if (glslfrg == NULL){ 56 std::cout << "Could not read file: " << frg_path << std::endl; 57 return -1; 58 } 59 else std::cout << "read fragment file succeeded !" << std::endl; 60 int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); 61 glShaderSource(fragmentShader, 1, &glslfrg, nullptr); 62 glCompileShader(fragmentShader); 63 glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); 64 if (!success) 65 { 66 glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog); 67 std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED" << infoLog << std::endl; 68 } 69 else std::cout << "fragment shader compile succeeded !" << std::endl; 70 71 shaderProgram = glCreateProgram(); //プログラムのIDを取得 72 glAttachShader(shaderProgram, vertexShader); 73 glAttachShader(shaderProgram, fragmentShader); 74 glLinkProgram(shaderProgram); 75 glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); 76 if(!success){ 77 glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog); 78 std::cout << "ERROR::SHADER::PROGRAM::LINKAGE_FAILED" << infoLog << std::endl; 79 } 80 else std::cout << "shader program linkage succeeded !" << std::endl; 81 std::cout << vertexShader << " " << fragmentShader << " shader program: " << shaderProgram << std::endl; 82 glDeleteShader(vertexShader); 83 glDeleteShader(fragmentShader); 84 85 glUseProgram(shaderProgram); 86 return -1; 87}

試したこと

フラグメント、バーテックスシェーダプログラム含めて全てmain関数に直接書いていた時には正しくシェーダをコンパイルできていましたが、シェーダソースプログラムを別ファイルに分け、シェーダ関連の操作を関数に分けたところ、コンパイルがうまくいかなくなってしまいました。

コンパイルできていた時も同じフラグメントシェーダを書いていたので、シェーダプログラムの中身自体ではなく読み込みなどの段階で問題があると思うのですが、エラーメッセージなどを調べても解決には至りませんでした。

補足情報(FW/ツールのバージョンなど)

glslは "version 120" を使っています。

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

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

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

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

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

guest

回答1

0

ベストアンサー

use_shader関数の最初でread_shader_fileの戻り値のc_str()を保存していますが、一時オブジェクトの寿命は文の終わりまでらしいので、解放されているのではないでしょうか。

少し書き換えて動かしましたが、戻り値を受け取っておけば動作しました。

C++

1 //const char* glslvrt = (read_shader_file(vrt_path)).c_str(); 2 //const char* glslfrg = (read_shader_file(frg_path)).c_str(); 3 4 std::string sglslvrt = read_shader_file(vrt_path); 5 std::string sglslfrg = read_shader_file(frg_path); 6 const char* glslvrt = sglslvrt.c_str(); 7 const char* glslfrg = sglslfrg.c_str();

投稿2020/07/15 14:48

mah

総合スコア591

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

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

goto-c

2020/07/15 23:12

ご回答ありがとうございます。 こちらでも変更して動かしたところ、期待通りの結果となりました。 また、一時オブジェクトの寿命について調べてみたところ、こちらのページに詳しく書いてありました。 https://codezine.jp/article/detail/276?p=4 大変勉強になりました、ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問