2011-12-22 4 views
7

これは私が初めてシェーダを実装したことを認めなければなりません。以前は固定機能のパイプラインを使っていました。しかし、私がしたことは全て正しいと確信していますが、間違いがあります。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")で読むことに切り替えたとき、問題はなくなり、ファイルは完全に読み込まれました。いくつかの代替実装を試してみましたが、リンク時に同じエラーが発生しました(正しく表示されるようにファイルを読み込んだ直後にシェーダソースをコンソールに表示します)。

+1

シェーダーの '#version'宣言はどこにありますか? –

+0

私は1つを含んでいなかった...それはそれかもしれないか?私はそれをgoogleにしますが、もし私がそうなら、OpenGL 2.0ターゲットのための適切なシェーダバージョンは何でしょうか? – Kaa

+0

3つの別々のテスト(両方のシェーダーで同じバージョン)で#version 150、#version 140、#version 130を使用してみましたが、結果は同じです - リンクステータスGL_FALSEと情報ログは返されません:( – Kaa

答えて

14

OK、私はこれが恥ずかしいと思っていたのを知っていましたが、それはかなり悪いことです。通常インテルのドライバに付随するIntelグラフィックス設定アプリケーションには3D設定タブがあります。今度は「カスタム設定」チェックボックスはチェックされていませんが、「頂点処理」設定の下にあるグレー表示オプションは「ソフトウェア処理を有効にする」の綴りです。チェックされておらず、すべてがグレー表示されたにもかかわらず、私は単にカスタム設定に入り、すべてを「アプリケーション設定」にチェックしました。

それを修正しました。それはすべてのリンクが必要です!誰がそのオプションを考えていたのか分からず、なぜこれが役立つのでしょうか?見事に外れている唯一のオプションです。

私はいくつかのドライバの再インストール、激しいデバッグと設定の調査を行った、私は推測して、絶対にすべてのことを推測しなければならなかった!恐ろしい、私の最悪の敵にそれを望んでいないだろう。皆さん気にして申し訳ありませんが、私のような別の***があれば歓迎です:)

関連する問題