2

2つの質問:

  1. さまざまなシェーダーを使用して、大きなVBOで要素をレンダリングしています。GLSL 1.2では、OSXの最新バージョンであるため、正しい場合に使用する必要があります。これは、属性の場所がコンパイラーが決定する場所であることを意味すると思います。これを回避する方法はありますか?たとえば、VBOがインターリーブ(x、y、z、nx、ny、nz、texU、texV)であるため、毎回同じ場所でこれらの属性にアクセスできるようにするには、複数のシェーダーが必要です。しかし、コンパイラがそれらに異なる場所を与えて、その場所が法線になるようにしていることがわかりました。それらの場所が私のVBO属性の場所と一致している必要があります。

  2. 最初のGLSLレンダリングが完了したばかりですが、さまざまなポリゴンを重ねてレンダリングして深度テストを有効にするのを忘れたようです。次の方法で深度テストを有効にしました。

    glEnable(GL_DEPTH_TEST);
    

    そして、問題は解決しません。シェーダーでそれらを有効にする別の方法はありますか?デプスバッファがこれを処理すると思いましたか?

    問題2は解決しました。ウィンドウを作成するときにOpenGL設定を指定する必要があるSFMLの問題であることが判明しました。

4

2 に答える 2

2

属性の場所は、優先度の高いものから低いものの順に、3 つの場所のいずれかに指定されます。

  1. GLSL 3.30 (またはそれ以降) または ARB_explicit_attrib_location 拡張構文を使用することにより、layout(location = #)#属性インデックスです。したがって、 という入力がある場合、次のpositionようにインデックス 3 を指定します。

    layout(location = 3) in vec4 position;
    

    これは、これを処理するための私の好みの方法です。Explicit_attrib_location は、サポートされているほぼすべてのハードウェア (Intel 以外) で利用できます。

  2. による明示的な関連付けglBindVertexAttrib。プログラムをリンクする前に、この関数を呼び出します。上記を行うには、次のようにします。

    GLuint program = glCreateProgram();
    glAttachShader(program, some_shader);
    glBindVertexAttrib(program, 3, "position");
    glLinkProgram(program);
    

    複数の属性を設定できます。実際、複数の属性名を同じインデックスに設定できます。そのアイデアは、一連のマッピングを自動的に設定し、実際のシェーダー コードでどのマッピングが機能するかを OpenGL に判断させることです。したがって、「位置」と「軸」をインデックス 3 にマップすることができ、これらの入力の両方を持つこのシステムにシェーダーを配置しない限り、問題ありません。

    存在しない属性も設定できることに注意してください。シェーダーで指定されていない属性を「通常」に与えることができます。それは結構です。リンカーは、実際に存在する属性のみを考慮します。したがって、この種のことに対して複雑な規則を確立し、リンクする前にすべてのプログラムを実行することができます:

    void AttribConvention(GLuint prog)
    {
      glBindVertexAttrib(program, 0, "position");
      glBindVertexAttrib(program, 1, "color");
      glBindVertexAttrib(program, 2, "normal");
      glBindVertexAttrib(program, 3, "tangent");
      glBindVertexAttrib(program, 4, "bitangent");
      glBindVertexAttrib(program, 5, "texCoord");
    }
    
    GLuint program = glCreateProgram();
    glAttachShader(program, some_shader);
    AttribConvention(program);
    glLinkProgram(program);
    

    特定のシェーダーがこれらの属性のすべてを持っていなくても、機能します。

  3. OpenGL に割り当てさせます。他の方法のいずれかで属性インデックスを属性に割り当てない場合は、GLSL リンカによって割り当てられます。でリンク後の属性を取得できますglGetAttribLocation

    OpenGL は任意にインデックスを割り当てるため、これはお勧めしません。したがって、指定された属性を使用するすべてのシェーダーはposition、異なるインデックス内の位置を持つ可能性があります。私はそれが良い考えだとは思わない。したがって、シェーダーで明示的に設定できない場合は、少なくともリンクする前に OpenGL コードで明示的に設定してください。そうすれば、属性インデックス 0 が意味するもの、インデックス 1 が意味するものなどについて規則を持つことができます。

于 2012-07-29T20:48:23.183 に答える
1

OpenGL 3.3+ではVAOがあり、それらを使用するときにVBOをそれにバインドし、カスタムオーダーで属性を定義できます: http://www.opengl.org/sdk/docs/man3/xhtml/glEnableVertexAttribArray.xml (属性は連続している必要があることに注意してください)

これの優れた/簡単な実装は、XNA: VertexDeclarationで見つけることができます。すべての Vertex* タイプも見たいと思うかもしれません。

v3 を SFML で動作させるためのヒント: http://en.sfml-dev.org/forums/index.php?topic=6314.0

VAO を作成して使用する方法の例: http://www.opentk.com/files/issues/HelloGL3.cs

(C# ですが、理解できると思います)

アップデート :

v2.1では、VAO を作成することはできませんが、http: //www.opengl.org/sdk/docs/man/xhtml/glEnableVertexAttribArray.xml もあります。ほぼ同じ機能を実現できますが、固定パイプライン上にあるため、毎回属性をバインドする必要があります。

于 2012-07-29T01:35:53.440 に答える