2012-05-11 13 views
1

私のglsl 130のコードは、若干現代的な(ATI 5850)ハードウェアで正しく動作しませんが、同じコードは私が持っているNVIDIAカードを搭載した古いノートパソコンでは正常に動作します。私が使っているOpenGLコンテキスト。何が起こるかは、ベクトルです:in_position、in_colour、およびin_normalは新しいハードウェア上で正しくバインドされません。新しいハードウェアでglsl(330)の新しいバージョンに強制されているようです。OpenGL 3.3+はglsl 130コードと互換性がありませんか?

頂点シェーダのglslコードです。それはかなり単純で基本的です。

#version 130 

uniform mat4 projectionMatrix; 
uniform mat4 viewMatrix; 
uniform mat4 modelMatrix; 
uniform mat4 normalMatrix; 

in vec4 in_position; 
in vec4 in_colour; 
in vec3 in_normal; 

out vec4 pass_colour; 

smooth out vec3 vNormal; 

void main() 
{ 
    gl_Position = projectionMatrix * viewMatrix * modelMatrix * in_position; 
    vec4 vRes = normalMatrix*vec4(in_normal, 0.0); 
    vNormal = vRes.xyz; 
    pass_colour = in_colour; 
} 

のために何が起こるかというとデータです:

in vec4 in_position; 
in vec4 in_colour; 
in vec3 in_normal; 

が完全にバインドされていませんかん。値は奇妙に歪んでいます。私のテストでは、他のすべてが適切に動作します。バージョンを330に変更してlocationキーワードを使用すると問題は解決されますが、これによってコードは古いバージョンのOpenGLと互換性がなくなります。

ここでは、これらの場所を指定するためのコードのサンプルを示します。

プログラムのために:データ自体の

glBindAttribLocation(LD_standard_program, 0, "in_position"); 
glBindAttribLocation(LD_standard_program, 1, "in_colour"); 
glBindAttribLocation(LD_standard_program, 2, "in_normal"); 

以降:

--- code to buffer vertex data 
glEnableVertexAttribArray(0); 
glVertexAttribPointer((GLuint) 0, 4, GL_FLOAT, GL_FALSE, 0, 0); 
--- code to buffer colour data 
glEnableVertexAttribArray(1); 
glVertexAttribPointer((GLuint) 1, 4, GL_FLOAT, GL_FALSE, 0, 0); 
--- code to buffer normal data 
glEnableVertexAttribArray(2); 
glVertexAttribPointer((GLuint) 2, 3, GL_FLOAT, GL_FALSE, 0, 0); 

私の質問は:OpenGLの後方互換性を持つように想定されていません?私は別のハードウェア上でプログラムを動作させるために、openglのシングルバージョン用に別々のシェーダを書かなければならないのではないかと心配し始めています...これらの属性をバインドするのは非常に基本的な機能なので、ATI実装...

+0

準拠していないコードが動作するのを許したNVIDIAのバグ、または適合するコードが失敗する原因となったATIのバグのいずれかが発生した可能性があります。または両方。とにかく、頂点属性をバインドするコードはどこに置いたのですか? –

+0

「バインドしていない、または完全にはしていない」ことについて詳しく説明できますか?どういう意味ですか?すべてのglGetErrors、またはシェーダーリンクのエラー? – Tim

答えて

1

glLinkProgramの前にglBindAttribLocationを呼び出していますか? afterを呼び出すと効果はありません。なぜなら、頂点属性にはglLinkProgramの間だけインデックスが割り当てられるからです。 GLSLで

3.30+ GLSLコードで直接属性インデックスをspecifiyingのより良い方法があります:

layout(location=0) in vec4 in_position; 
layout(location=1) in vec4 in_colour; 
layout(location=2) in vec3 in_normal; 

編集:ああ、私はあなたがすでにレイアウトキーワードを試してみまし部分をスキップ。

+0

いいえプログラムを作成すると、まずglLinkProgramが呼び出されます。私はレイアウト(場所= 0)などについて知っています...私はglsl 330コードは素晴らしい作品を書かれている。この場合、私は自分のアプリケーションをglslの新しいバージョンを実行できない古いハードウェアと互換性を持たせるように書いたコードを提示しています。そのコードは古いバージョンではうまく動作しますが、新しいバージョンではうまく動作しません。私はopenglが下位互換性があるという印象を受けていたので、私は混乱しています。しかし、私のケースでは、glsl 130コードは古いものだが新しいハードウェアではうまく動作していることが分かっている。 – kkuryllo

+0

glBindAttribLocationの前にglLinkProgramを呼び出すのは問題だ。頂点属性インデックスは、glLinkProgram呼び出しで割り当てられます。その点までglBindAttribLocationを呼び出さなかった場合は、driver/gpuのコンボが好む順番どおりに、インデックスが空いていても属性が割り当てられます。 –

+0

ありがとうございました。その1行をシフトするだけで、すべてのコードが修正されました。私はそれを好きにしたチュートリアルのオンラインに従っていました。私は、私の正常な頂点データが交換されていることに気付きました。私はすべてのポリゴンが中央の球に溶け込んでいるのを見ていたので意味があります。即ちゼロから正確に1単位の半径だけ離れている。 – kkuryllo

関連する問題