vertex array slower than glbegin/glend?

Why is the vertex array slower than the glbegin/glend? And how could i improve the performance.

The code is part of a particle engine.
vertex array:
init:


    vertices = com.sun.opengl.util.BufferUtil.newFloatBuffer(4*3*5000);
    colors = com.sun.opengl.util.BufferUtil.newFloatBuffer(5000*4*4);
    texturecord = com.sun.opengl.util.BufferUtil.newFloatBuffer(5000*4*2);
    
    gl.glEnableClientState(GL.GL_COLOR_ARRAY);
    gl.glEnableClientState(GL.GL_VERTEX_ARRAY); 
    gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY); 
    
    gl.glColorPointer(4, GL.GL_FLOAT, 0, colors);
    gl.glVertexPointer(3, GL.GL_FLOAT, 0, vertices);
    gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, texturecord);

draw:


    if (particleList_.size() > 0) { 
      vertices.clear();
      vertices.rewind();
      colors.clear();
      colors.rewind();
      texturecord.clear();
      texturecord.rewind();
      
      for (Particle particle: particleList_){
        particle.paint(vertices,colors,texturecord,right,up,view);
      } 
  
      vertices.flip();  //rewind();
      colors.flip();  //rewind();
      texturecord.flip();

      int test=vertices.limit()/3; 
      gl.glDrawArrays(GL.GL_QUADS, 0, test);
    }

Particle:


  public void paint(FloatBuffer vertex, FloatBuffer color,FloatBuffer texturecord, Vector3D right, Vector3D up, Vector3D view){

    float r=color_.getR();
    float g=color_.getG();
    float b=color_.getB();
    color.put(r);
    color.put(g);
    color.put(b);
    color.put(alpha_);  
    color.put(r);
    color.put(g);
    color.put(b);
    color.put(alpha_);
    color.put(r);
    color.put(g);
    color.put(b);
    color.put(alpha_);
    color.put(r);
    color.put(g);
    color.put(b);
    color.put(alpha_);
    
    float x=position.getX();
    float y=position.getY();
    float z=position.getZ();
    
    vertex.put(x+up.getX()*size);
    vertex.put(y+up.getY()*size);
    vertex.put(z+up.getZ()*size);
    vertex.put(x);
    vertex.put(y);
    vertex.put(z);
    vertex.put(x+right.getX()*size);
    vertex.put(y+right.getY()*size);
    vertex.put(z+right.getZ()*size);
    vertex.put(x+(right.getX()+up.getX())*size);
    vertex.put(y+(right.getY()+up.getY())*size);
    vertex.put(z+(right.getZ()+up.getZ())*size);
    
    texturecord.put(0f);
    texturecord.put(0f);
    texturecord.put(0f);
    texturecord.put(1f); 
    texturecord.put(1f);
    texturecord.put(1f);
    texturecord.put(1f);
    texturecord.put(0f); 
  }


glBegin/glEnd
draw:


    gl.glBegin(GL.GL_QUADS);
    for (Particle particle: particleList_){
      particle.paint(gl,right,up,view);
    } 
    gl.glEnd();

Particle


  public void paint(GL gl, Vector3D right, Vector3D up, Vector3D view){
    
    gl.glColor4f(color_.getR(), color_.getG(), color_.getB(), alpha_);
    
    float x=position.getX();
    float y=position.getY();
    float z=position.getZ();
   
    gl.glTexCoord2f(0,0);
    gl.glVertex3f(x+up.getX()*size, y+up.getY()*size, z+up.getZ()*size);
    gl.glTexCoord2f(0,1);
    gl.glVertex3f(x, y, z);
    gl.glTexCoord2f(1,1);
    gl.glVertex3f(x+right.getX()*size, y+right.getY()*size, z+right.getZ()*size);
    gl.glTexCoord2f(1,0);
    gl.glVertex3f(x+(right.getX()+up.getX())*size, y+(right.getY()+up.getY())*size, z+(right.getZ()+up.getZ())*size);
    
  }

See the JavaOne slides from 2002 and later years on the JOGL home page for some performance recommendations, including for example using the absolute put() methods on NIO Buffers like FloatBuffers. See also the source code for the JOGL demos, some of which use vertex arrays with good effectiveness.

i tried the absulte put but that didnt improve the performace much. It is still slower than immediate mode. I think the problem is that i have to set the color four times instead of only once with immediate mode.

Similiar performace issues will occur even if you perfect the code. The problem i guess is with the buffers themselves! (i might be wrong). But OpenGL introduced vertex arrays as a performance speedup since internally when you use the conventional Begin/End the driver will process them into a structure much similiar to vertex arrays which is what is actually done in assigning a vertex array (somehow). So when this process is not optimal and making memory increase exp. I think there is a problem in JOGL’s Buffers and connection/transfer of data.

In all of my code, I’ve never had vertex arrays perform slower than begin-end code. I use newer cards, so perhaps its a driver issue or it could be that the performance loss is not because of jogl but from filling the buffers. This has no bearing on jogl and is just a side affect of using vertex arrays with dynamic content.

If you want to speed it up, try minimizing the amount of data you have to copy each time. For example, do you need to need to fill the color buffer each frame, instead remember buffers for each particle system of a given color so that buffer doesn’t have change. All you’d need to do is update the positions, same can be done with texture coordinates as with the colors (since each time they’re 0 or 1).

IMO vertex arrays only make sense when you render really A LOT of vertices. if you render just a few, than vertex arrays can be slower than glBegin/glEnd.
we had a similar issue in the jogl textrenderer, when the rendering with vertex arrays was actually slower, than without.

I agree with emzic here, the algorithm for processing vertex arrays is designed for huge number of vertices, so ofcourse rocessing a vertex array with 3 vertices will be slower than glBegin/glEnd but I assume this isnt the case!

I think that this is because you are using Java FloatBuffers, which are Big-Endian. OpenGL in most implementations is little endian, so I think there is a convertsion that is being done by JOGL internally.

When I render my meshes I ‘export’ then with my C++ exporter, and then I load then with java.nio as raw ByteBuffers, and this is what I send to glBufferData/glTexImage*D . I’ve necer tried until now to modify the meshes with java so far(It would be very expensive right?), so I’m not sure if this is your problem.

Bye!

No. JOGL does no data conversion.

For correct operation with JOGL you need to set the endian order of your ByteBuffers to ByteOrder.nativeOrder() before viewing them as for example a FloatBuffer. The JOGL BufferUtil class does this for you which is why I recommend its use.

I agree with you. Using vertex arrays can be slower than immediate mode when you draw less than 10 vertices as far as I know.

Nevertheless, the use of vertex arrays (and VBO) can really improve the performance of an application if you use them correctly. Don’t forget that the immediate mode will disappear in OpenGL 3.0.

I agree with you but dont forget that OpenGL 3.0 is a long way ahead, i mean currently 2.0 is not fully implemented !!!

Yes you’re right and I’m worried about that point.