1

GL_TRIANGLE_STRIPSとLWJGLOpenGLJavaバインディングを使用して高さマップを実装しています。'GL_BEGIN / GL_END'を使用して'direct'を描画すると、完全に機能しますが、ハイトマップが大きすぎると、動作が遅くなります。

VBOの使用を続けたいので、VertexArrayの使用方法を学習しています。これは私が問題を抱えているところです、描画はちょうど間違っています。ストリップの最後の三角形が最初の三角形に戻っているようです。Perhepsの写真の方が優れています:

良い絵: 良い直接描画

悪い頂点配列の描画: 頂点配列の描画が正しくありません

私のコードは通常の描画では次のとおりです。

public void renderDirect() {
    //adapt the camera to the map
    float scale = 5.0f / Math.max(w - 1, l - 1);
    GL11.glScalef(scale, scale, scale);
    GL11.glTranslatef(-(float) (w - 1) / 2, 0.0f, -(float) (l - 1) / 2);

    //choose map color
    GL11.glColor3f(0.3f, 0.9f, 0.0f);

    for (int z = 0; z < l - 1; z++) {
        //Makes OpenGL draw a triangle at every three consecutive vertices
        GL11.glBegin(GL11.GL_TRIANGLE_STRIP);
        for (int x = 0; x < w; x++) {
            Vector3f normal = getNormal(x, z);
            GL11.glNormal3f(normal.getX(), normal.getY(), normal.getZ());
            GL11.glVertex3f(x, getHeight(x, z), z);
            normal = getNormal(x, z + 1);
            GL11.glNormal3f(normal.getX(), normal.getY(), normal.getZ());
            GL11.glVertex3f(x, getHeight(x, z + 1), z + 1);
        }
        glEnd();
    }
}

私のコードは、頂点配列の描画では次のとおりです。

private void loadArrays(){
    //calculate the length of the buffers
    bLength = (l-1) * w * 6;
    //create the normal and vertex buffer array's
    dataBuffer = BufferUtils.createFloatBuffer(bLength*2);
    cBuffer = BufferUtils.createFloatBuffer(bLength);

    for (int z = 0; z < l - 1; z++) {
        //Fill up the buffers
        for (int x = 0; x < w; x++) {
            Vector3f normal = getNormal(x, z);
            dataBuffer.put(x).put(getHeight(x,z)).put(z);
            dataBuffer.put(normal.getX()).put(normal.getY()).put(normal.getZ());
            normal = getNormal(x, z + 1);
            dataBuffer.put(x).put(getHeight(x,z+1)).put(z+1);
            dataBuffer.put(normal.getX()).put(normal.getY()).put(normal.getZ());              
        }
    } 
}

int stride = 6*4;
public void renderDirect() {
    //adapt the camera to the map
    float scale = 5.0f / Math.max(w - 1, l - 1);
    GL11.glScalef(scale, scale, scale);
    GL11.glTranslatef(-(float) (w - 1) / 2, 0.0f, -(float) (l - 1) / 2);

    //choose map color
    GL11.glColor3f(0.3f, 0.9f, 0.0f);

    //Draw the vertex arrays
    glEnableClientState(GL_VERTEX_ARRAY);      
    glEnableClientState(GL_NORMAL_ARRAY); 

    dataBuffer.position(0);
    glVertexPointer(3, stride, dataBuffer);
    dataBuffer.position(3);
    glNormalPointer(stride,dataBuffer);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, bLength/3);    

    glDisableClientState(GL_VERTEX_ARRAY);      
    glDisableClientState(GL_NORMAL_ARRAY);
}    

私は何が間違っているのですか?

4

2 に答える 2

3

このように三角ストリップを連続して連結すると、期待どおりに機能しません。

およびパラメータをglDrawArrays()調整するループを呼び出して元の三角ストリップを描画するか、各行の最後に縮退した三角形を追加してストリップの開始位置をリセットします。firstcountN

または単に使用してGL_TRIANGLESください:)

于 2012-02-02T15:52:23.963 に答える
0

ストリップ内に連続して描画される三角形の数が十分に多い場合に多くの時間を安全にできる別の解決策は、次のとおりです。

三角ストリップをレンダリングする場合、OpenGLに頂点情報のストリームを提供し、新しい頂点ごとに三角形をレンダリングします(たとえば、シーケンスABCDEFは三角形ABC、BCD、CDE、DEFを提供します)。これで、これは常に単一のストリップになります(これが、GL_TRIANGLE_STRIPと呼ばれ、一般的な複数形の命名ではない理由です)。

とにかく、ギャップを導入する必要がある場合は、描画関数を複数回呼び出すことができますが(それは避けたいことですが)、無効なポリゴンを使用することもできます。

無効なポリゴンとは、サーフェスがないポリゴンです。ABBやABAのような同一のポイントを提供することにより、無効なポリゴンを作成できます。私の知る限り、このようなポリゴンはパイプラインのかなり早い段階で拒否されるため、オーバーヘッドはそれほど大きくありません。今あなたの特定の問題に。この「ABC|DEF」のようなギャップ(垂直バーで示される)があると仮定します。この「ABCCEEDEF」のようにストリームを変更します。この嫌悪感はあなたに三角形ABC、BCC、CCE、CEE、EDE、DEFを与えます。無効なものの早期拒否を説明すると、ABCとDEFが得られます-まさにあなたが望んでいたものです。

エルゴ、合計すると、各ギャップは頂点ストリームを3つの三角形で爆破します。これにより、複雑さの点でさえも損益分岐点を簡単に確認できます。

とにかく、ギャップを構築する必要がある場合は、無効な三角形を提供することでそうすることができます

于 2012-03-05T15:26:02.380 に答える