1

私は最近、LWJGL と OpenGL を使用して 3D キューブをレンダリングする方法を見つけました。とても興奮して、2000 をレンダリングしたところ、コンピューターが効果的にフリーズしました。ディスプレイ リストや VBO などのことは聞いたことがありますが、グーグルで検索しても使い方がわかりません。

現在、私は

for (Block b : blocks) {
    GL11.glTranslatef(b.position.x, b.position.y, b.position.z); // Translate to draw the cube.
    GL11.glBegin(GL_QUADS); // Start to draw the quad.
    b.render(); // Renders the quad.
    GL11.glEnd(); // Finishes rendering.
}

キューブのレンダリング。呼び出しb.renderは立方体をレンダリングするだけです

@Override
public void render() {
    //front face
    GL11.glNormal3f(0f, 0f, 1f);
    GL11.glTexCoord2f(0f, 1f);
    GL11.glVertex3f(1f, 0f, 0f);
    GL11.glTexCoord2f(1f, 1f);
    GL11.glVertex3f(0f, 0f, 0f);
    GL11.glTexCoord2f(1f, 0f);
    GL11.glVertex3f(0f, 1f, 0f);
    GL11.glTexCoord2f(0f, 0f);
    GL11.glVertex3f(1f, 1f, 0f);

    //back face
    GL11.glNormal3f(0f, 0f, -1f);
    GL11.glTexCoord2f(0f, 1f);
    GL11.glVertex3f(0f, 0f, 1f);
    GL11.glTexCoord2f(1f, 1f);
    GL11.glVertex3f(1f, 0f, 1f);
    GL11.glTexCoord2f(1f, 0f);
    GL11.glVertex3f(1f, 1f, 1f);
    GL11.glTexCoord2f(0f, 0f);
    GL11.glVertex3f(0f, 1f, 1f);

    cap.bind(); // top texture
    //top face
    GL11.glNormal3f(0f, -1f, 0f);
    GL11.glTexCoord2f(0f, 1f);
    GL11.glVertex3f(1f, 1f, 0f);
    GL11.glTexCoord2f(1f, 1f);
    GL11.glVertex3f(0f, 1f, 0f);
    GL11.glTexCoord2f(1f, 0f);
    GL11.glVertex3f(0f, 1f, 1f);
    GL11.glTexCoord2f(0f, 0f);
    GL11.glVertex3f(1f, 1f, 1f);

    //bottom face
    GL11.glNormal3f(0f, 1f, 0f);
    GL11.glTexCoord2f(0f, 1f);
    GL11.glVertex3f(1f, 0f, 1f);
    GL11.glTexCoord2f(1f, 1f);
    GL11.glVertex3f(0f, 0f, 1f);
    GL11.glTexCoord2f(1f, 0f);
    GL11.glVertex3f(0f, 0f, 0f);
    GL11.glTexCoord2f(0f, 0f);
    GL11.glVertex3f(1f, 0f, 0f);

    side.bind(); // left texture
    //left face
    GL11.glNormal3f(-1f, 0f, 0f);
    GL11.glTexCoord2f(0f, 1f);
    GL11.glVertex3f(1f, 0f, 1f);
    GL11.glTexCoord2f(1f, 1f);
    GL11.glVertex3f(1f, 0f, 0f);
    GL11.glTexCoord2f(1f, 0f);
    GL11.glVertex3f(1f, 1f, 0f);
    GL11.glTexCoord2f(0f, 0f);
    GL11.glVertex3f(1f, 1f, 1f);

    //right face
    GL11.glNormal3f(1f, 0f, 0f);
    GL11.glTexCoord2f(0f, 1f);
    GL11.glVertex3f(0f, 0f, 0f);
    GL11.glTexCoord2f(1f, 1f);
    GL11.glVertex3f(0f, 0f, 1f);
    GL11.glTexCoord2f(1f, 0f);
    GL11.glVertex3f(0f, 1f, 1f);
    GL11.glTexCoord2f(0f, 0f);
    GL11.glVertex3f(0f, 1f, 0f);
}

キャップがトップ テクスチャで、サイドがサイド テクスチャです。

私が本当に助けを必要としているのは、パフォーマンスを向上させるために、コード VBO や表示リストを互換性のあるものにする方法を見つけることです。また、目に見える顔だけをレンダリングすることができれば、多くの計算を節約できると思いますが、そのようなことを行う方法は考えられません.

編集:

次のコードを使用して、各ブロックが独自の VBO オブジェクトを作成するようになりました...

private int vboID;
private FloatBuffer vertices;
private float[] verts = {0, 1, 2, 2, 3, 0, 0, 3, 4, 4, 5, 0, 0, 5, 6, 6, 1, 0, 1, 6, 7, 7, 2, 1, 7, 4, 3, 3, 2, 7, 4, 7, 6, 6, 5, 4}; // Not sure on the numbers for making a cube?

private void generateVBO() {
    vertices = BufferUtils.createFloatBuffer(verts.length); // Create a FloatBuffer...
    vertices.put(verts); // Add all the vertices in...
    vboID = GL15.glGenBuffers(); // Generate the VBO...
    GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vboID); // Bind it...
    GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertices, GL15.GL_STATIC_DRAW); // Buffer in the data...
    verts = null; // Free up memory allocation because these are unnecessary now...
    vertices = null;
    System.out.println("VBO created with a vboID of '"+vboID+"'.");
}

プログラムの開始時に、1000 個のブロック オブジェクトを作成するので、出力は実質的に「n の vboID で VBO を作成」、1000 回になります。

プログラムの最後に、VBO を破棄する必要があることは理解していますが (各 VBO を呼び出すだけだと思いGL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0)ますか?)、まず、各 VBO を描画する必要があります。

VBO を描画するコマンドは何ですか?

4

2 に答える 2

1

ディスプレイリストは使用しないでください。古く、廃止されています。VBOを効果的に使用するには、頂点アレイを使用する必要があります。頂点配列を使用する場合は、すべての頂点位置とその他の属性を配列に入れ、glDrawArraysへの1回の呼び出しを使用して、多数の三角形の描画をバッチ処理します(配列は、次々に処理される頂点の長いリストであると想定しています)。またはglDrawElements(頂点配列の要素を参照するインデックスのリストを含む追加の配列を取ります)。

頂点配列に関するチュートリアルは次のとおりです。

http://www.songho.ca/opengl/gl_vertexarray.html

頂点配列を機能させると、VBOへの小さなステップになります。

于 2013-02-12T10:49:21.990 に答える