1

位置 (3)、テクスチャ (2)、および頂点法線 (3) を含む Vertex データ型があります。これらを使用して頂点シェーダーに渡していますglVertexAttribPointer(こちらを参照)。

残念ながら、ロードしたモデルに関係なく、デス スターが表示されました。基本的には、ワイヤーフレーム レンダリングに切り替えたときにのみ表示される頂点の球体です。

モジュールから多数の頂点を削除しようとしたところ、最終的に部分的に構築されたデス スターにたどり着きました。この時点で、法線が頂点であるかのようにプロットされていることが明らかになりました。頂点がまったくプロットされていることを知りません。

追加の 2 つの三角形を描画して、仮説を確認しました。1 つは頂点があるべき場所を表し、もう 1 つは法線を表します。また、オブジェクト自体と区別できるように、1.1 倍にスケーリングしました。はい、間違いなく頂点ではなく法線を描画しています。

誰かが理由を知っていますか?シェーダーの属性の順序を切り替えてみましたが、(奇妙なことに) 役に立ちませんでした。

以下は、2 つのテスト オブジェクト (完全な n20r4_d5.obj と非常に部分的な test11.obj) を含む完全な最小限の動作例です。

4

1 に答える 1

4

OpenGL 2.1 を使用しているため、 を使用して属性インデックスをプルする必要がありますglGetAttribLocation()0GLSL コンパイラが頂点と texcoords をオンにすることを期待することはできません2

void render(Shader* shader_program = NULL) 
{
    if (shader_program) 
        shader_program->bind();

    GLint position_loc = glGetAttribLocation( shader_program->id(), "position" );
    GLint tex_loc = glGetAttribLocation( shader_program->id(), "tex" );
    GLint normal_loc = glGetAttribLocation( shader_program->id(), "normal" );

    glEnableVertexAttribArray( position_loc );
    glEnableVertexAttribArray( normal_loc );
    glEnableVertexAttribArray( tex_loc );

    for (size_t i = 0; i < entries.size(); ++i) 
    {
        glBindBuffer(GL_ARRAY_BUFFER, entries[i].vb);

        // I think this tells it where to look for the vertex information we've loaded.
        glVertexAttribPointer(position_loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
        glVertexAttribPointer(normal_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)12); // starts at 12 because 3 floats for position before 2 floats for normal
        glVertexAttribPointer(tex_loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)20); // makes room for 5 floats
        ...

シェーダーをリンクする前に OpenGL にそれらを配置する場所 ( ) を指定することもできますglBindAttribLocation()が、設定方法によっては面倒です。

OpenGL 3.1+ では、layout修飾子を介して特定のインデックスに属性を配置するようにコンパイラに強制できます。

于 2014-02-21T22:25:37.753 に答える