# Vertex Buffer Objects mit JOGL



## xorm (5. Okt 2009)

Hallo,

nachdem ich jetzt schon den ganzen Tag probiere VBOs zum laufen zu kriegen und JOGL einfach nicht so will wie ich, dachte ich, ich frag mal die Experten 

Ich habe ein kleines Java Programm geschrieben indem ich ein einzelnes Dreieck mit den Eckpunkten (0,0,0), (1,0,0) und (1,1,0) über ein VBO zeichnen will.


```
import java.awt.BorderLayout;
import java.nio.FloatBuffer;

import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLJPanel;
import javax.swing.JFrame;

import com.sun.opengl.util.BufferUtil;

public class Main extends JFrame implements GLEventListener {

	private GLJPanel glPanel;
	private FloatBuffer vertices;
	private int[] vertexName;

	public Main() {
		setSize(500, 500);
		setLayout(new BorderLayout());
		glPanel = new GLJPanel();
		glPanel.addGLEventListener(this);
		add(glPanel, BorderLayout.CENTER);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
	}

	@Override
	public void display(GLAutoDrawable drawable) {
		GL gl = drawable.getGL();
		gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
		gl.glColor3d(1.0, 0.6, 0.2);

//		gl.glBegin(GL.GL_TRIANGLES);
//		gl.glVertex3d(0.0, 0.0, 0.0);
//		gl.glVertex3d(1.0, 0.0, 0.0);
//		gl.glVertex3d(1.0, 1.0, 0.0);
//		gl.glEnd();
		
		gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vertexName[0]);
		gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
		gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3);

		gl.glFlush();
	}

	@Override
	public void displayChanged(GLAutoDrawable drawable, boolean arg1, boolean arg2) {}

	@Override
	public void init(GLAutoDrawable drawable) {
		GL gl = drawable.getGL();
		gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
		gl.glEnable(GL.GL_DEPTH_TEST);
		gl.glShadeModel(GL.GL_FLAT);

		vertices = BufferUtil.newFloatBuffer(9);
		vertices.put(0.0f);
		vertices.put(0.0f);
		vertices.put(0.0f);

		vertices.put(1.0f);
		vertices.put(0.0f);
		vertices.put(0.0f);

		vertices.put(1.0f);
		vertices.put(1.0f);
		vertices.put(0.0f);

		vertexName = new int[1];
		
		gl.glGenBuffersARB(1, vertexName, 0);
		gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
		gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vertexName[0]);
		gl.glBufferDataARB(GL.GL_ARRAY_BUFFER_ARB, 9 * BufferUtil.SIZEOF_FLOAT, vertices,
				GL.GL_STATIC_DRAW_ARB);
	}

	@Override
	public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
		GL gl = drawable.getGL();
		gl.glViewport(0, 0, w, h);
		gl.glMatrixMode(GL.GL_PROJECTION);
		gl.glLoadIdentity();
		gl.glOrtho(0.0, 1.0, 0.0, 1.0, -0.5, 10.0);
		gl.glMatrixMode(GL.GL_MODELVIEW);
		gl.glLoadIdentity();
	}

	public static void main(String[] args) {
		new Main();
	}

}
```

Innerhalb von init() schreibe ich die 3 Vertices für das Dreieck in einen FloatBuffer und erstelle mir danach mein VBO. In display() möchte ich dann dieses Dreieck zeichnen.

Allerdings sehe ich nur schwarz. Wenn ich das Dreieck ohne VBOs zeichne (auskommentierte Zeilen) füllt es wie gewollt die rechte untere Hälfte meines Fensters.

Irgendwie scheine ich blind zu sein und sehe den Fehler nicht :bahnhof:


----------



## Marco13 (5. Okt 2009)

Ja, dass da kein Fehler erscheint oder so ... und das das nötig ist ... hat mich auch etliches an Zeit gekostet  Nachdem der "vertices" Buffer gefüllt wurde, muss er mit
        vertices.rewind();
zurückgespult werden...


----------



## xorm (5. Okt 2009)

Args, danke daran lags. Darauf muss man auch erstmal kommen. :autsch:


----------



## gerdgerdgerd (10. Nov 2009)

Hallo zusammen,

wie kann ich den FloatBuffer mehrmals zeichnen? Hier ist mein Ansatz:


```
gl.glColor3d(1.0, 0.6, 0.2);
gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vertexName[0]);
gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3);

gl.glColor3d(0.2, 0.3, 0.8);
gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vertexName[0]);
gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3);
gl.glTranslatef(-0.5f, -0.5f, 0);
```

Leider funktioniert das nicht wie ich mir gedacht habe, da eigentlich 2 Dreiecke zu sehen sein müssten!

Danke!


----------



## Marco13 (10. Nov 2009)

Ist an so einem Schnipsel nur schwer nachzuvollziehen ...


----------



## gerdgerdgerd (10. Nov 2009)

Ich habe das Beispiel von oben genommen, also komplette quellcode sieht dann so aus:


```
import java.awt.BorderLayout;
import java.nio.FloatBuffer;
 
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLJPanel;
import javax.swing.JFrame;
 
import com.sun.opengl.util.BufferUtil;
 
public class Main extends JFrame implements GLEventListener {
 
    private GLJPanel glPanel;
    private FloatBuffer vertices;
    private int[] vertexName;
 
    public Main() {
        setSize(500, 500);
        setLayout(new BorderLayout());
        glPanel = new GLJPanel();
        glPanel.addGLEventListener(this);
        add(glPanel, BorderLayout.CENTER);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
 
    @Override
    public void display(GLAutoDrawable drawable) {
        GL gl = drawable.getGL();
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        
        gl.glColor3d(1.0, 0.6, 0.2);
        gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vertexName[0]);
        gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
        gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3);

        gl.glColor3d(0.2, 0.3, 0.8);
        gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vertexName[0]);
        gl.glVertexPointer(3, GL.GL_FLOAT, 0, 0);
        gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3);
        gl.glTranslatef(-0.5f, -0.5f, 0);
 
        gl.glFlush();
    }
 
    @Override
    public void displayChanged(GLAutoDrawable drawable, boolean arg1, boolean arg2) {}
 
    @Override
    public void init(GLAutoDrawable drawable) {
        GL gl = drawable.getGL();
        gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        gl.glEnable(GL.GL_DEPTH_TEST);
        gl.glShadeModel(GL.GL_FLAT);
 
        vertices = BufferUtil.newFloatBuffer(9);
        vertices.put(0.0f);
        vertices.put(0.0f);
        vertices.put(0.0f);
 
        vertices.put(1.0f);
        vertices.put(0.0f);
        vertices.put(0.0f);
 
        vertices.put(1.0f);
        vertices.put(1.0f);
        vertices.put(0.0f);
 
        vertexName = new int[1];
        
        gl.glGenBuffersARB(1, vertexName, 0);
        gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
        gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vertexName[0]);
        gl.glBufferDataARB(GL.GL_ARRAY_BUFFER_ARB, 9 * BufferUtil.SIZEOF_FLOAT, vertices,
                GL.GL_STATIC_DRAW_ARB);
    }
 
    @Override
    public void reshape(GLAutoDrawable drawable, int x, int y, int w, int h) {
        GL gl = drawable.getGL();
        gl.glViewport(0, 0, w, h);
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glOrtho(0.0, 1.0, 0.0, 1.0, -0.5, 10.0);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }
 
    public static void main(String[] args) {
        new Main();
    }
 
}
```


----------



## Marco13 (10. Nov 2009)

Wenn du das genau so testest: vertices.rewind(); fehlt, und ... das zweite Dreieck sieht genau so aus wie das erste: Die Verschiebung (glTranslate) sollte VOR dem Zeichnen gemacht werden, und außerdem eher um (0.5f,0.5f,0), weil das zweite Dreieck sonst nach unten links aus dem Bildschirm rausgeschoben wird...


----------



## gerdgerdgerd (10. Nov 2009)

vertices.rewind(); habe ich bereits eingefügt, habe es nur vergessen zu kopieren .

Natürlich war das ein Denkfehler, bezüglich der Reihenfolge. Nachdem ich das Dreieck in eine andere Richtung verschoben habe, war es sichtbar ... Manchmal steht man echt auf dem Schlauch  

Danke


----------

