Login  Register

How to use VBO?

Posted by Chaz on Jan 18, 2015; 11:44am
URL: https://forum.jogamp.org/How-to-use-VBO-tp4033871.html

Hello. I have to display large amount of quads, and for more performance I decide to use VBO for that task. But something goes wrong, and I got a batch of exceptions on
gl.glBufferData(targetsBuffer.get(0), fBuff.capacity(),fBuff,gl.GL_STATIC_DRAW);
Here is class which I use for creating and using VBO

public class Terrain implements IShape {
    private ObjectArrayList<Vector3f> vectors;
    private GL2 gl;
    private FloatBuffer fBuff;
    private IntBuffer targetsBuffer;

    public Terrain(GL2 gl) throws Exception
    {
        this.gl=gl;
        vectors=new ObjectArrayList<Vector3f>();
           Import(".//data.exp");
    }

    private void Import(String path) throws Exception
    {
        byte[] bytes = Files.readAllBytes(Paths.get(path)); // import files with heights
        int resolution = (int)Math.sqrt(bytes.length/4); // define resolution
        float[] floats=new float[resolution*resolution];
        ByteBuffer.wrap(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer().get(floats);
        float step = 100/(resolution-1.0f);

        fBuff = FloatBuffer.allocate(resolution*resolution*3*4); // create buffer with vertices

        for(int i =0; i<resolution-1; i++)
        {
            for(int j =0; j<resolution-1; j++) // here I create a grid, 4 vertices for each quad
            {
                float x1=i,y1=floats[i*resolution+j]*600,z1=j;
                vectors.add(new Vector3f(x1,y1,z1));  // physics engine needs it for create a collider
                float x2=i+1,y2=floats[(i+1)*resolution+j]*600,z2=j;
                vectors.add(new Vector3f(x2,y2,z2));
                float x3=i+1,y3=floats[(i+1)*resolution+(j+1)]*600,z3=j+1;
                vectors.add(new Vector3f(x3,y3,z3));
                float x4=i,y4=floats[i*resolution+(j+1)]*600,z4=j+1;
                vectors.add(new Vector3f(x4,y4,z4));

                fBuff.put(x1); // add vertices to buffer
                fBuff.put(y1);
                fBuff.put(z1);

                fBuff.put(x2);
                fBuff.put(y2);
                fBuff.put(z2);

                fBuff.put(x3);
                fBuff.put(y3);
                fBuff.put(z3);

                fBuff.put(x4);
                fBuff.put(y4);
                fBuff.put(z4);
            }
        }
        float max=Float.MIN_VALUE,min=Float.MAX_VALUE;
        for(float f : floats)
        {
            if(f>max)max=f;
            if(f<min)min=f;
        }

        System.out.println(floats[0]+" : "+floats[floats.length-1]);

        System.out.println("Max: "+max+"\nMin: "+min);
    }

    public ObjectArrayList<Vector3f> GetVertexes()
    {
        return vectors;
    }

    public void CreateBuffer(GL2 gl)
    {
        this.gl=gl;
        targetsBuffer = IntBuffer.allocate(1);
        gl.glGenBuffers(1,targetsBuffer);
        gl.glBindBuffer(gl.GL_ARRAY_BUFFER,targetsBuffer.get(0));
        gl.glBufferData(targetsBuffer.get(0), fBuff.capacity(),fBuff,gl.GL_STATIC_DRAW);
    }

    @Override
    public void Draw() {
        gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
        gl.glBindVertexArray(targetsBuffer.get(0));
        gl.glDrawArrays(gl.GL_QUADS,0,fBuff.capacity());
        gl.glDisableClientState(gl.GL_VERTEX_ARRAY);
    }
}

In Main class I have initialize this class

terrain=new Terrain();

And then call methods from init and render methods

 @Override
    public void init(GLAutoDrawable glAutoDrawable) {
        glu=GLU.createGLU(glAutoDrawable.getGL().getGL2());
        glut=new GLUT();
        gl=glAutoDrawable.getGL().getGL2();
        //gl.glPolygonMode(gl.GL_FRONT_AND_BACK,gl.GL_LINE);

        terrain.CreateBuffer(gl);
        System.out.println(gl.isExtensionAvailable("GL_ARB_vertex_buffer_object"));
    }

 private void render(GLAutoDrawable drawable)
    {
        gl.glEnable(gl.GL_DEPTH_TEST);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        gl.glClearColor(0.2f, 0.4f, 0.7f, 0);
        gl.glMatrixMode(gl.GL_MODELVIEW);
        gl.glLoadIdentity();
        glu.gluLookAt(cameraPos.x, cameraPos.y, cameraPos.z, pointOfInterest.x, pointOfInterest.y, pointOfInterest.z, 0, 1, 0);

        gl.glPushMatrix();

        int x=0;
        for(RigidBody ball : balls)
        {
            gl.glPushMatrix();
            {
                float[] buff = new float[16];
                ball.getWorldTransform(new Transform()).getOpenGLMatrix(buff);
                gl.glMultMatrixf(FloatBuffer.wrap(buff));
                gl.glColor3f(0, 1, 0);
                glut.glutSolidSphere(1,10,10);
            }
            gl.glPopMatrix();

            x++;
        }

        gl.glColor3f(0.5f,0,0);
        gl.glPopMatrix();
        terrain.Draw();
    }


But I have exception which appears in this method
     public void CreateBuffer(GL2 gl)  
on call
    gl.glBufferData(targetsBuffer.get(0), fBuff.capacity(),fBuff,gl.GL_STATIC_DRAW);

So what I did wrong?