0

頂点バッファー オブジェクトを使用しようとしています。

この厄介な状況に陥るまで、最初は何の問題もありませんでした。

glPointSize(2.0f);
glBegin(GL_POINTS);
for (Entity p : points) {
    glVertex3f(p.x, p.y, p.z);
}
glEnd();

これを Vertex Buffers Object render に変換するにはどうすればよいですか?

ご覧のとおり、データ (x、y、z) はポイントごとに毎回変更されます (ループです)。

では、Vertex Buffers Object render をこれに実装するにはどうすればよいでしょうか?

4

3 に答える 3

8

基本的に、すべての頂点データを に入れ、FloatBufferそれを OpenGL に渡します。三角形の頂点と色を格納してレンダリングする VBO の小さな例と、それを削除する方法を作成しました。

VBO の作成

これは、実際の頂点とカラー バッファを作成し、それらを VBO にバインドするコードです。

int vertices = 3;

int vertex_size = 3; // X, Y, Z,
int color_size = 3; // R, G, B,

FloatBuffer vertex_data = BufferUtils.createFloatBuffer(vertices * vertex_size);
vertex_data.put(new float[] { -1f, -1f, 0f, });
vertex_data.put(new float[] { 1f, -1f, 0f, });
vertex_data.put(new float[] { 1f, 1f, 0f, });
vertex_data.flip();

FloatBuffer color_data = BufferUtils.createFloatBuffer(vertices * color_size);
color_data.put(new float[] { 1f, 0f, 0f, });
color_data.put(new float[] { 0f, 1f, 0f, });
color_data.put(new float[] { 0f, 0f, 1f, });
color_data.flip();

int vbo_vertex_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
glBufferData(GL_ARRAY_BUFFER, vertex_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

int vbo_color_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_color_handle);
glBufferData(GL_ARRAY_BUFFER, color_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

vertex_dataもちろん、必要に応じてさらに頂点と色を追加することもできcolor_dataます! ただし、頂点データの量はカラー データの量と一致する必要があり、その逆も同様であることに注意してください。

重要: VBO は 1 回だけ作成し、必要な場合にのみ更新してください。フレームごとに作成しないでください。レンダリングに即時モードを使用する場合よりもフレームレートが低下するためです。

VBO のレンダリング

これは、VBO をレンダリングするために呼び出す必要があるコードです。

glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
glVertexPointer(vertex_size, GL_FLOAT, 0, 0l);

glBindBuffer(GL_ARRAY_BUFFER, vbo_color_handle);
glColorPointer(color_size, GL_FLOAT, 0, 0l);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

glDrawArrays(GL_TRIANGLES, 0, vertices);

glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

VBO の削除

その後、VBO の使用が終了し、不要になったら、次の手順で削除できます。

glDeleteBuffers(vbo_vertex_handle);
glDeleteBuffers(vbo_color_handle);
于 2013-10-13T15:33:07.527 に答える
1

バッファに関する優れたチュートリアルは次のとおりです。

あなたの質問について:

ポイントの最大数の VBO を作成することをお勧めします (または、ポイントの数が一定である可能性があります)。次に、このバッファを NULL で埋めます。

ポイントをレンダリングしたいときはmap、そのコンテンツをバッファリングして更新する必要があります。

float *data = (float *)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
update_points(data); // write new positions for all points
glUnmapBuffer(GL_ARRAY_BUFFER); 

次に、次の方法で描画します。

bind_and_set_your_buffer();
glDrawArrays(GL_POINTS, 0, VertexCount);
  • 更新のために、次の使用を検討できます: glBufferSubData または glMapBufferRange
于 2013-10-13T14:39:52.517 に答える
1

私も同じ問題を抱えていましたが、バレンティンの答えは非常に満足のいくものです。ですから、JOGL のために、コード全体を公開したいと思います。

package alican_tuts.VBO;

import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.nio.FloatBuffer;

import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.awt.GLCanvas;
import javax.media.opengl.glu.GLU;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.util.FPSAnimator;

public class VBO_Example extends GLCanvas implements GLEventListener {
    private static final long serialVersionUID = 1L;

    private static String TITLE = "AliCan VBO EXAMPLE";
    private static final int CANVAS_WIDTH = 800;
    private static final int CANVAS_HEIGHT = 600;
    private static final int FPS = 60;

    private GLU glu;

    // VBO related variables
    int vertices = 3; // Triangle vertices

    int vertex_size = 3; // X,Y,Z
    int color_size = 3; // R, G, B

    private FloatBuffer vertex_data;
    private FloatBuffer color_data;

    private int[] vbo_vertex_handle = new int[1];
    private int[] vbo_color_handle = new int[1];

    // ===========================================================
    // GUI creation and program's main function
    // ===========================================================
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                GLCanvas canvas = new VBO_Example();
                canvas.setPreferredSize(new Dimension(CANVAS_WIDTH, CANVAS_HEIGHT));

                final FPSAnimator animator = new FPSAnimator(canvas, FPS, true);

                final JFrame frame = new JFrame();

                frame.getContentPane().add(canvas);
                frame.addWindowListener(new WindowAdapter() {
                    @Override
                    public void windowClosing(WindowEvent e) {

                        new Thread() {
                            @Override
                            public void run() {
                                if (animator.isStarted())
                                    animator.stop();
                                System.exit(0);
                            }
                        }.start();
                    }
                });
                frame.setTitle(TITLE);
                frame.pack();
                frame.setVisible(true);
                animator.start();
            }
        });
    }

    public VBO_Example() {
        this.addGLEventListener(this);
    }

    // ===========================================================
    // VBO Related Functions
    // ===========================================================

    private void initVBOs(GL2 gl) {
        vertex_data = Buffers.newDirectFloatBuffer(vertices * vertex_size);
        // vertex_data = FloatBuffer.allocate(vertices * vertex_size);
        vertex_data.put(new float[] { 0.0f, 1.0f, 0f });
        vertex_data.put(new float[] { -1.0f, -1.0f, 0f });
        vertex_data.put(new float[] { 1.0f, -1.0f, 0f });
        vertex_data.flip();

        color_data = Buffers.newDirectFloatBuffer(vertices * color_size);
        // color_data = FloatBuffer.allocate(vertices * color_size);
        color_data.put(new float[] { 1f, 0f, 0f });
        color_data.put(new float[] { 0f, 1f, 0f });
        color_data.put(new float[] { 0f, 0f, 1f });
        color_data.flip();

        gl.glGenBuffers(1, vbo_vertex_handle, 0);
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vbo_vertex_handle[0]);

        gl.glBufferData(GL2.GL_ARRAY_BUFFER, vertices * vertex_size * Buffers.SIZEOF_FLOAT, vertex_data,
                GL2.GL_STATIC_DRAW);
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);

        gl.glGenBuffers(1, vbo_color_handle, 0);
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vbo_color_handle[0]);
        gl.glBufferData(GL2.GL_ARRAY_BUFFER, vertices * vertex_size * Buffers.SIZEOF_FLOAT, color_data,
                GL2.GL_STATIC_DRAW);
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, 0);

    }

    private void renderVBOs(GL2 gl) {
        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vbo_vertex_handle[0]);
        gl.glVertexPointer(vertex_size, GL2.GL_FLOAT, 0, 0l);

        gl.glBindBuffer(GL2.GL_ARRAY_BUFFER, vbo_color_handle[0]);
        gl.glColorPointer(color_size, GL2.GL_FLOAT, 0, 0l);

        gl.glEnableClientState(GL2.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL2.GL_COLOR_ARRAY);

        gl.glDrawArrays(GL2.GL_TRIANGLES, 0, vertices);

        gl.glDisableClientState(GL2.GL_COLOR_ARRAY);
        gl.glDisableClientState(GL2.GL_VERTEX_ARRAY);
    }

    // ===========================================================
    // OpenGL Callback Functions
    // ===========================================================
    @Override
    public void init(GLAutoDrawable drawable) {
        GL2 gl = drawable.getGL().getGL2();
        glu = new GLU();
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glClearDepth(1.0f);
        gl.glEnable(GL2.GL_DEPTH_TEST);
        gl.glDepthFunc(GL2.GL_LEQUAL);
        gl.glHint(GL2.GL_PERSPECTIVE_CORRECTION_HINT, GL2.GL_NICEST);

        gl.glShadeModel(GL2.GL_SMOOTH);

        initVBOs(gl);
    }

    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
        GL2 gl = drawable.getGL().getGL2();

        if (height == 0)
            height = 1;
        float aspect = (float) width / height;

        gl.glViewport(0, 0, width, height);

        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(45.0, aspect, 0.1, 100.0);

        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

    @Override
    public void display(GLAutoDrawable drawable) {
        GL2 gl = drawable.getGL().getGL2();
        gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);

        gl.glLoadIdentity();

        gl.glTranslatef(0.0f, 0.0f, -6.0f);
        renderVBOs(gl);
    }

    @Override
    public void dispose(GLAutoDrawable drawable) {
    }

}
于 2015-02-10T14:36:14.853 に答える