これは私が初めてシェーダを実装したことを認めなければなりません。以前は固定機能のパイプラインを使っていました。しかし、私がしたことは全て正しいと確信していますが、間違いがあります。OpenGL glLinkProgramはfalseを返しますが、infoログは空です。すべてをチェックしました
glLinkProgram(program)
- GL_LINK_STATUS
については、GL_FALSE
を返します。さらに、インフォメーションログは空です(ログの長さを問い合わせると、それは1であり、これはドキュメントごとにヌルターミネータであり、チェックアウトします)。リンカのエラーとログはありません。さらに、割り当て中と計算に使用する場合の両方で、gl_Position
という変数を頂点シェーダで使用するとすぐにリンカの問題が発生することがわかりました。私はあらゆる種類のシェーダのバリエーションを試しましたが、それはエラーですが、ログを生成することができません - いつでもgl_Position
がタッチされるとGL_FALSE
を返すようです。面白いことに、フラグメントシェーダーは問題を起こさない。
フラグメントシェーダと頂点シェーダの両方がエラーなしでコンパイルされます。構文エラーを導入すると、それらは検出され、印刷され、プログラム作成前にプロセスが中断されます(したがって、正常に動作するように見えます)。私はデバッグし、ファイルが正しくロードされ、ソースがヌルで終了し、サイズが正しいことを確認しました。添付されたプログラムの数を確認しました.2(正しいlol)です。明確にするために削除されていますが、私はcheckForErrors()
の方法でopenglエラーをチェックして表示していますが、何も検出されません。
私は困惑しています。助けてください!私はので(定数GLchar **)にキャスト - glShaderSource:
FILE *file = fopen(fileName.c_str(), "rb");
if(file == NULL)
{
Log::error("file does not exist: \"" + fileName + "\"");
return NULL;
}
// Calculate file size
fseek(file , 0 , SEEK_END);
int size = ftell(file);
rewind(file);
// If file size is 0
if(size == 0)
{
Log::error("file is empty: \"" + fileName + "\"");
return NULL;
}
char **source = new char*[1];
source[0] = new char[size+1];
source[0][size] = '\0';
// If we weren't able to read the entire file into memory
int readSize = fread(source[0], sizeof(char), size, file);
if(size != readSize)
{
int fileError = ferror(file);
// Free the source, log an error and return false
delete source[0];
delete [] source;
fclose(file);
Log::error("couldn't load file into memory [ferror(" + toString<int>(fileError) + ")]: \"" + fileName + "\" (Size: " + toString<int>(readSize) + "/" + toString<int>(size) + " bytes)");
return NULL;
}
// Close the file
fclose(file);
// Create the shader object
// shaderType is GLenum that is set based on the file extension. I assure you it is correctly set to either GL_VERTEX_SHADER or GL_FRAGMENT_SHADER
GLuint shaderID = glCreateShader(shaderType);
// If we could not create the shader object, check for OpenGL errors and return false
if(shaderID == 0)
{
checkForErrors();
Log::error("error creating shader \"" + name);
delete source[0];
delete [] source;
return NULL;
}
// Load shader source and compile it
glShaderSource(shaderID, 1, (const GLchar**)source, NULL);
glCompileShader(shaderID);
GLint success;
glGetShaderiv(shaderID, GL_COMPILE_STATUS, &success);
if(!success)
{
GLchar error[1024];
glGetShaderInfoLog(shaderID, 1024, NULL, error);
Log::error("error compiling shader \"" + name + "\"\n Log:\n" + error);
delete source[0];
delete [] source;
return NULL;
}
else
{
Log::debug("success! Loaded shader \"" + name + "\"");
}
// Clean up
delete source[0];
delete [] source;
クイックノート:私は、これはシェーダをロードするためのコードです...今2日間、この上
を睡眠を失ってきましたGCCは、非const charポインタに対してconstについて苦情を言います。そうでなければ、私は完全に準拠していると信じています
ところで、エラーはありません。シェーダ(下記)はエラーなしでコンパイルされます。
バーテックスシェーダ:
void main()
{
// If I comment the line below, the link status is GL_TRUE.
gl_Position = vec4(1.0, 1.0, 1.0, 1.0);
}
フラグメントシェーダ:以下
void main()
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
それは通常:
// Create a new shader program
GLuint program = glCreateProgram();
if(program == 0)
{
Log::error("RenderSystem::loadShaderProgram() - could not create OpenGL shader program; This one is fatal, sorry.");
getContext()->fatalErrorIn("RenderSystem::loadShaderProgram(shader1, shader2)", "OpenGL failed to create object using glCreateProgram()");
return NULL;
}
// Attach shader objects to program
glAttachShader(program, vertexShaderID);
glAttachShader(program, fragmentShaderID);
// Link the program
GLint success = GL_FALSE;
glLinkProgram(program);
checkForErrors();
glGetProgramiv(program, GL_LINK_STATUS, &success);
if(success == GL_FALSE)
{
GLchar errorLog[1024] = {0};
glGetProgramInfoLog(program, 1024, NULL, errorLog);
Log::error(std::string() + "error linking program: " + errorLog);
return NULL;
}
success = GL_FALSE;
glValidateProgram(program);
glGetProgramiv(program, GL_VALIDATE_STATUS, &success);
if(success == GL_FALSE)
{
GLchar errorLog[1024] = {0};
glGetProgramInfoLog(program, 1024, NULL, errorLog);
checkForErrors();
Log::error(std::string() + "error validating shader program; Details: " + errorLog);
return NULL;
}
、シェーダプログラムを作成するコードであるオブジェクトとのリンクなどを添付プログラムを検証することさえできません...私はこれに非常に不満です、それは非常に難しいですb e。下品。
あなたの助けが必要です。本当にありがとうございました!
EDIT:私はIntel HD 3000ですべてを実行しています(OpenGLは最大3.1までサポートしています)。私のターゲットOpenGLバージョンは2.0です。
EDIT2: "r"または "rt"フラグをfopenに設定した場合、テキストファイルからシェーダを読み取る際にいくつかの問題があることにも気付きたいと思います。読み取りサイズは実際のサイズよりも約10小さいバイト(一貫してすべてのファイル) - feof()はtrueを返します。私がバイナリ( "rb")で読むことに切り替えたとき、問題はなくなり、ファイルは完全に読み込まれました。いくつかの代替実装を試してみましたが、リンク時に同じエラーが発生しました(正しく表示されるようにファイルを読み込んだ直後にシェーダソースをコンソールに表示します)。
シェーダーの '#version'宣言はどこにありますか? –
私は1つを含んでいなかった...それはそれかもしれないか?私はそれをgoogleにしますが、もし私がそうなら、OpenGL 2.0ターゲットのための適切なシェーダバージョンは何でしょうか? – Kaa
3つの別々のテスト(両方のシェーダーで同じバージョン)で#version 150、#version 140、#version 130を使用してみましたが、結果は同じです - リンクステータスGL_FALSEと情報ログは返されません:( – Kaa