need help in vertex buffer objects!!!

Hello!

I user vertex arrays in my program, and I wanted to user vbo, but the speed is down by 500%. I posted the code in the gamedev.net, and nobody knows (yet) where is the error? I really appriciate if you could help me
Code:

The code render a terrain divided into (128x128) pieces (size:32x32).
The codetry to use 1 big buffer for all verteces (vertexBuffer). The code display the result with unexceptable speed.

private static void initArrayBuffers(){
vertexIndexCount = (2*(SpellinaWorldStatics.SEGMENTSIZE+1)-1)*SpellinaWorldStatics.SEGMENTSIZE + 1;
vertexCount = (SpellinaWorldStatics.SEGMENTSIZE+1) * (SpellinaWorldStatics.SEGMENTSIZE+1);

    vertexIndexBuffer = setupIntBuffer(ByteBuffer.allocateDirect( vertexIndexCount * BufferUtils.SIZEOF_INT ));

    colorCoordinateBuffer = setupByteBuffer(ByteBuffer.allocateDirect( 4 * vertexCount ));

    textureCoordinateBuffer = setupFloatBuffer(ByteBuffer.allocateDirect( 2 * vertexCount * BufferUtils.SIZEOF_FLOAT ));

    bumpTextureCoordinateBuffer = setupFloatBuffer(ByteBuffer.allocateDirect( 2 * vertexCount * BufferUtils.SIZEOF_FLOAT ));
}

private static void fillCoordinateBuffers(){
colorCoordinateBuffer.clear();
textureCoordinateBuffer.clear();
bumpTextureCoordinateBuffer.clear();
for (int i = 0; i <= SpellinaWorldStatics.SEGMENTSIZE; ++i ) {
for (int j = 0; j <= SpellinaWorldStatics.SEGMENTSIZE; ++j) {
colorCoordinateBuffer.put( (byte)0 );
colorCoordinateBuffer.put( (byte)0 );
colorCoordinateBuffer.put( (byte)0 );
textureCoordinateBuffer.put( 1.0f * j / SpellinaWorldStatics.SEGMENTSIZE );
textureCoordinateBuffer.put( 1-1.0f * i / SpellinaWorldStatics.SEGMENTSIZE );

            bumpTextureCoordinateBuffer.put( 1.0f * j / SpellinaWorldStatics.SEGMENTSIZE );
            bumpTextureCoordinateBuffer.put( 1.0f * i / SpellinaWorldStatics.SEGMENTSIZE );
        }
    }
}

private static void fillIndexBuffers(){
    vertexIndexBuffer.clear();
    for (int i = 0; i+1 <= SpellinaWorldStatics.SEGMENTSIZE; ++i ) {
        if( (i  % 2) == 0){
            for (int j = 0; j <= SpellinaWorldStatics.SEGMENTSIZE; ++j) {
                vertexIndexBuffer.put( getElement(i,j) );
                vertexIndexBuffer.put( getElement(i+1,j) );
            }
        }
        else{
            for (int j = SpellinaWorldStatics.SEGMENTSIZE; j >= 0; --j) {
                if( j != SpellinaWorldStatics.SEGMENTSIZE){
                    vertexIndexBuffer.put( getElement(i,j) );
                }
                if( j != 0 || i+1 == SpellinaWorldStatics.SEGMENTSIZE ){
                    vertexIndexBuffer.put( getElement(i+1,j) );
                }
            }
        }
    }
}

 private static void initVBONames(){
    gl.glGenBuffersARB( 4, names );

    gl.glBindBufferARB( GL.GL_ELEMENT_ARRAY_BUFFER_ARB, names[0] );
    gl.glBufferDataARB( GL.GL_ELEMENT_ARRAY_BUFFER_ARB, vertexIndexCount * BufferUtils.SIZEOF_FLOAT, vertexIndexBuffer, GL.GL_STATIC_DRAW_ARB );
    gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, 0);

    gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, names[1] );
    gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, 4 * vertexCount, colorCoordinateBuffer, GL.GL_STATIC_DRAW_ARB );
    gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0);

    gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, names[2] );
    gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, 2 * vertexCount * BufferUtils.SIZEOF_FLOAT, textureCoordinateBuffer, GL.GL_STATIC_DRAW_ARB );
    gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0);

    gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, names[3] );
    gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, 2 * vertexCount * BufferUtils.SIZEOF_FLOAT, bumpTextureCoordinateBuffer, GL.GL_STATIC_DRAW_ARB );
    gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0);
}

// init method
public static void initEngine(GL gl, GLU glu){

    initArrayBuffers();

    fillCoordinateBuffers();

    fillIndexBuffers();

    initVBONames();


}

private static IntBuffer setupIntBuffer(ByteBuffer buf) {
buf.order(ByteOrder.nativeOrder());
return buf.asIntBuffer();
}

private static FloatBuffer setupFloatBuffer(ByteBuffer buf) {
    buf.order(ByteOrder.nativeOrder());
    return buf.asFloatBuffer();
}

private static ByteBuffer setupByteBuffer(ByteBuffer buf) {
    buf.order(ByteOrder.nativeOrder());
    return buf;
}

// allocating memory for the buffers
private static void initArrays(){

    vertexBuffer[actualTerrain] = setupFloatBuffer(ByteBuffer.allocateDirect( stepLimits[ actualTerrain ] * stepLimits[ actualTerrain ] * 3 * vertexCount * BufferUtils.SIZEOF_FLOAT ));
    colorBuffer[actualTerrain] = setupByteBuffer(ByteBuffer.allocateDirect( stepLimits[ actualTerrain ] * stepLimits[ actualTerrain ] * SpellinaWorldStatics.WATERTEXTUREINDEX * 4 * vertexCount ));

    vertexOffsets[actualTerrain] = new int[ stepLimits[ actualTerrain ] ][ stepLimits[actualTerrain] ];
    colorOffsets[actualTerrain] = new int[ stepLimits[actualTerrain] ][ stepLimits[actualTerrain] ][ SpellinaWorldStatics.WATERTEXTUREINDEX ];


}

// fill the buffers up
private static void fillVertexArrays(){
int shiftXIndex = 0, shiftZIndex = 0; int vertexIndex = 0, colorIndex = 0;
for(int k=0; k<stepLimits[actualTerrain]; ++k)
for(int l=0; l<stepLimits[actualTerrain]; ++l){
shiftXIndex = k * SpellinaWorldStatics.SEGMENTSIZE;
shiftZIndex = l * SpellinaWorldStatics.SEGMENTSIZE;
vertexOffsets[actualTerrain][k][l] = vertexIndex;
for(int m = 0; m<SpellinaWorldStatics.WATERTEXTUREINDEX; ++m){
colorOffsets[actualTerrain][k][l][m] = colorIndex;
}
for (int i = 0; i <= SpellinaWorldStatics.SEGMENTSIZE; ++i ) {
for (int j = 0; j <= SpellinaWorldStatics.SEGMENTSIZE; ++j) {
vertexBuffer[actualTerrain].put( vertexIndex++, (shiftXIndex + i)*2 - steps[actualTerrain] );
vertexBuffer[actualTerrain].put( vertexIndex++, SpellinaTerrainStatics.getAltitude( actualTerrain, shiftXIndex + i, shiftZIndex + j )*1.0f );
vertexBuffer[actualTerrain].put( vertexIndex++, (shiftZIndex + j)*2 - steps[actualTerrain] );

                for(int m = 0; m<SpellinaWorldStatics.WATERTEXTUREINDEX; ++m){
                    colorBuffer[actualTerrain].put( colorIndex++, (byte)255 );
                }
                for(int m = 0; m<SpellinaWorldStatics.WATERTEXTUREINDEX; ++m){
                    colorBuffer[actualTerrain].put( colorIndex++, (byte)255 );
                }
                for(int m = 0; m<SpellinaWorldStatics.WATERTEXTUREINDEX; ++m){
                    colorBuffer[actualTerrain].put( colorIndex++, (byte)255 );
                }
                for(int m = 0; m<SpellinaWorldStatics.WATERTEXTUREINDEX; ++m){
                    colorBuffer[actualTerrain].put( colorIndex++, (byte)(alphas[actualTerrain][shiftXIndex+i][shiftZIndex+j][m]+128) );
                }
            }

        }
    }
}

// creating the names of terrain pices
private static void createVBONames(){
int[] temp = CreationFactory.createInt1DArray( 1 );
gl.glGenBuffersARB( 1, temp );
gl.glBindBufferARB( GL.GL_ELEMENT_ARRAY_BUFFER_ARB, vertexNames[actualTerrain] = temp[0] );
gl.glBufferDataARB( GL.GL_ELEMENT_ARRAY_BUFFER_ARB, stepLimits[ actualTerrain ] * stepLimits[ actualTerrain ] * 3 * vertexCount * BufferUtils.SIZEOF_FLOAT, vertexBuffer[actualTerrain], GL.GL_STATIC_DRAW_ARB );
gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0);

    temp = CreationFactory.createInt1DArray( 1 );
    gl.glGenBuffersARB( 1, temp );
    gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, colorNames[actualTerrain] = temp[0] );
    gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, stepLimits[ actualTerrain ] * stepLimits[ actualTerrain ] * SpellinaWorldStatics.WATERTEXTUREINDEX * 4 * vertexCount, colorBuffer[actualTerrain], GL.GL_STATIC_DRAW_ARB );
    gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0);
}

// render method
public static void renderVBOTerrain(){
gl.glEnableClientState( GL.GL_VERTEX_ARRAY );
gl.glEnableClientState( GL.GL_COLOR_ARRAY );
gl.glEnableClientState( GL.GL_TEXTURE_COORD_ARRAY );

    for(int k=0; k< stepLimits[actualTerrain]; ++k){
        for(int l=0; l< stepLimits[actualTerrain]; ++l){

            gl.glDisable( GL.GL_TEXTURE_2D );

            gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, names[1] );
            gl.glColorPointer( 3,  GL.GL_UNSIGNED_BYTE, 0, BufferUtils.bufferOffset( 0 ) );

            gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, vertexNames[actualTerrain] );
            gl.glVertexPointer( 3,  GL.GL_FLOAT, 0, BufferUtils.bufferOffset( vertexOffsets[actualTerrain][k][l] * BufferUtils.SIZEOF_FLOAT ) );

            gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, names[0] );
            gl.glDrawElements( GL.GL_TRIANGLE_STRIP, vertexIndexCount, GL.GL_UNSIGNED_INT, BufferUtils.bufferOffset( 0 ) );

          }
     }
    gl.glDisableClientState( GL.GL_VERTEX_ARRAY );
    gl.glDisableClientState( GL.GL_COLOR_ARRAY );
    gl.glDisableClientState( GL.GL_TEXTURE_COORD_ARRAY );

}

}

I found the solution: unsigned byte.
When I commented out the glColorPointer, the speed is boosted up.
So, I redefined the color buffer to float type, and it is 10% faster than vertex array.

Is it sufficient? Or Do I have to do another something?

I don’t think the UNSIGNED_BYTE was the problem, colors are supposed to be in that format.

I’m more suspicious of the index buffer. Try using a different index format (short if the vertices are few enough).