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

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

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

charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

OpenGL

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

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

C++

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

GLSL

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

Q&A

解決済

1回答

1965閲覧

シェーダーファイルの読み込みで関係ないchar型文字が一つ代入される理由が知りたい。

退会済みユーザー

退会済みユーザー

総合スコア0

char

charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

OpenGL

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

文字コード

文字コードとは、文字や記号をコンピュータ上で使用するために用いられるバイト表現を指します。

C++

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

GLSL

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

0グッド

0クリップ

投稿2021/06/30 12:33

提示画像ですがシェーダーファイルを読み込むとエラーが出ます不明なchar - が入っていますとのエラーですが頂点、フラグメント両方なんな文字を入っていません。これはなぜでしょうか?提示コード二つ目はシェーダーファイルを読み込むコードですが何が悪いのでしょうか?

イメージ説明

cpp

1 2// ##################################### プログラムオブジェクト作成 ##################################### 3GLuint FrameWork::Shader::CreateProgram(std::shared_ptr<GLchar*> vert, std::shared_ptr<GLchar*> frag) 4{ 5 const GLuint program = glCreateProgram(); //シェーダープログラムを作成 6 7 if (vert != nullptr) 8 { 9 const GLuint vobj = glCreateShader(GL_VERTEX_SHADER); 10 11 GLchar *v[] = { NULL }; 12 v[0] = *vert; 13 14 glShaderSource(vobj, 1,v, NULL); 15 glCompileShader(vobj); 16 CompileInfoLog(vobj, "Complie Error: Vertex Shader"); 17 glAttachShader(program, vobj); 18 glDeleteShader(vobj); 19 } 20 else 21 { 22 std::cerr << "頂点シェーダー読み込み失敗" << std::endl; 23 } 24 25 if (frag != nullptr) 26 { 27 const GLuint fobj = glCreateShader(GL_FRAGMENT_SHADER); 28 GLchar *v[] = {NULL}; 29 v[0] = *frag; 30 31 glShaderSource(fobj, 1, v, NULL); 32 glCompileShader(fobj); 33 CompileInfoLog(fobj, "Complie Error: Fragment Shader"); 34 glAttachShader(program, fobj); 35 glDeleteShader(fobj); 36 } 37 else 38 { 39 std::cerr << "フラグメントシェーダー読み込み失敗" << std::endl; 40 } 41 42 glLinkProgram(program); //リンクプログラム 43 ProgramInfoLog(program); //リンク時のログを表示 44 45 return program; 46} 47

cpp

1 2// ##################################### シェーダーを読み込む ##################################### 3void FrameWork::Resource::LoadShader(Asset assetName) 4{ 5 6 std::shared_ptr<Shader> data = std::make_shared<Shader>(); 7 8 data->fileData = std::make_shared<GLchar*>(); 9 10 for (std::vector<Resource_File>::const_iterator itr = resourceFile->begin(); itr != resourceFile->end(); itr++) 11 { 12 if (itr->assetName == assetName) 13 { 14 15 std::ifstream file(itr->fileName, std::ios::binary); 16 if (file.fail() == true) 17 { 18 std::cerr << "シェーダーファイルを読み込めません: " << itr->fileName << std::endl; 19 20 file.close(); 21 assert(0); 22 break; 23 } 24 else 25 { 26 std::vector<GLchar> buffer(0); 27 file.seekg(0L, std::ios::end); 28 GLsizei length = static_cast<GLsizei>(file.tellg()); 29 buffer.resize(length + 1); 30 file.seekg(0L, std::ios::beg); 31 file.read(buffer.data(), length); 32 buffer.at(length) = ('\0'); 33 *data->fileData = buffer.data(); 34 file.close(); 35 36 shader->push_back(std::make_shared<Shader_Data>(Shader_Data{ data,assetName })); 37 } 38 39 file.close(); 40 break; 41 } 42 } 43 44}

glsl

1/*######################################################################### 2# 単色の二次元描画 頂点シェーダー 3###########################################################################*/ 4#version 330 //バージョン 5#extension GL_ARB_explicit_attrib_location: enable // 6 7 8// ###################### 頂点属性 ###################### 9layout(location = 0) in vec2 vertexPosition; //頂点座標 10 11// ###################### 出力 ###################### 12layout(location = 2) out vec4 vFragment; //頂点カラー 13 14// ###################### Uniform ###################### 15uniform mat4 uScale; //スケール 16uniform mat4 uRotate; //回転 17uniform mat4 uTranslate; //平行移動 18uniform mat4 uViewProjection; //ビュープロジェクション行列 19uniform vec4 uFragment; //色 20 21 22void main() 23{ 24 vec4 vertex = vec4(vertexPosition,0.0,1.0); //頂点座標 25 mat4 model = uTranslate * uRotate * uScale; //モデル行列 26 27 gl_Position = (uViewProjection * model) * vertex; 28 29 vFragment = uFragment; //カラー 30}

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

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

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

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

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

guest

回答1

0

ベストアンサー

2点問題があります。

問題点その1 シェーダプログラムに日本語が入っている事
コメント部分だけならば問題ないことになっているらしいですが、
VisualStudioで日本語ソースを保存した場合おそらくBOM付きUTF-8になるため先頭にBOMが付与される

問題点その2 FrameWork::Shader::CreateProgramが呼び出された段階でfileDataの中身の寿命が切れている可能性が高い
実際の処理順が分かりませんが、FrameWork::Resource::LoadShaderを抜けた段階でbufferの寿命が切れていますのでおそらくは

そもそもstd::shared_ptr<GLchar*>は以前も指摘しましたが意味が違います。
Shaderのポインタを管理するためのstd::shared_ptr<Shader>なのと同様に
GLcharへのポインタを管理するためにはstd::shared_ptr<GLchar>(もしくはstd::shared_ptr<GLchar[]>)を用います。
(追記: deleterの問題があるのでC++17以降ではstd::shared_ptr<GLchar[]>を用いた方がいいですね。)
std::shared_ptr<GLchar*>GLchar*へのポインタを管理しますのでGLchar*自体は寿命が切れている事もありえますしメモリリークもします。
また、所有権を他と共有しないのであればstd::vector<GLchar>を持った方がいいです。
個人的にはシェーダーファイルの所有権はShaderのみが持てばよいように感じます

投稿2021/06/30 14:21

編集2021/06/30 22:51
asm

総合スコア15149

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

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

fana

2021/07/01 01:31 編集

全然関係ない話で恐縮ですが, 「シェーダのコードを外部ファイルから動的に読み込む」という形の{意義,利点,etc}がどうにもわからない…… 動的に読み込む ってことは,読み込んでみるまでどんな内容のコードがやってくるかわからない,ってことだけど, C++側としては,そのシェーダコードについての全てを知ってなければまずまともに使えないと思うんですよね. 結局は,「attribute やら uniform やらにどんなやつがあって,それらは何なのか?」みたいな仕様を完全把握しているC++側コードと対になって初めて仕事ができる. つまり ・シェーダのコード だけが有っても意味が無いわけで ・そのシェーダのコードに対応した固有のPC側処理実装 が必要になるんだけど, この両者を物理的に分離することはただただ弊害(面倒)が生じるだけにしか思えない. もちろん,【何らかの仕様をきっちり決めてしまえば】 C++側を全く変えずに(リコンパイルせずに)シェーダ処理だけを差し替える ことはできるだろうけども…… (そんなことがしたい場面ってあるのかなぁ?) 動的にファイルから読み込んだシェーダコードがその仕様に従う物なのか?っていうチェック処理はどうするのか? とか考えるだけで,ただただ面倒な仕組みに思える.
asm

2021/07/01 04:22

あまりシェーダについては詳しくないのですがそうなのですか
fana

2021/07/01 04:43 編集

(こちらもあまり詳しくないからこそ疑問であるわけですが) シェーダの処理に必要なデータ値は転送してやなきゃならない. 例えばシェーダの処理で何か座標変換を行うための変換マトリクスの値が必要とか. ↓ つーことは,それを転送する側としては,シェーダが何をどんな形で必要とするのかを知っている必要がある. 変換マトリクスの例で言えば ・マトリクスの値を外界から設定してやる必要があること ・そのマトリクスの大きさや要素の型 ・それがシェーダコード上で何という変数名なのか ・それが何を意味するものなのか(何の変換であって,妥当な値とは何か) くらいを知らないとならないハズ. ※シェーダコード文字列を自前で解釈するとかすれば上から3つまではわかるかもしれないが,最後のは無理だよね.
退会済みユーザー

退会済みユーザー

2021/07/01 06:55

質問ですがメモ帳でbomなしで上書きしましたが同じエラーが出ます。これはなぜでしょうか?
asm

2021/07/01 07:37

> fanaさん よくわかりませんが、コンパイル済みシェーダを使った方がいいという主張でしょうか? それはOpenGLには存在しない(かった)機能です > saijou_chanさん 提示した問題点両方を解決しないと寿命が切れているオブジェクトには何の保証もありません。
fana

2021/07/01 07:51 編集

テキストファイルから実行時に読むんじゃなくて,最も単純には const GLchar Code[] = "シェーダコード"; とかでいいんじゃないのか的な. どうせ使う側の実装とセットで用意するんだし.
asm

2021/07/01 08:09

なるほど。raw string literal使うのも悪くないですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問