too slow VBO

Started by
12 comments, last by Tera_Dragon 19 years, 6 months ago
Hello! I tried to replace my vertex arrays with VBO, and the result is a very slow code (speed is 1/8 compared with vertex arrays ). I have a Radeon9600XT, so VBO is supported. Any correction, error recognition could be usefull... Here is my code: // gl.glGenBuffersARB( 4, temp ); gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, colorCoordinateName = temp[0] ); 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, textureCoordinateName = temp[1] ); gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, 4 * 2 * vertexCount, textureCoordinateBuffer,GL.GL_STATIC_DRAW_ARB ); gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0); gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, bumpTextureCoordinateName = temp[2] ); gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, 4 * 2 * vertexCount, bumpTextureCoordinateBuffer,GL.GL_STATIC_DRAW_ARB ); gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0); gl.glBindBufferARB( GL.GL_ELEMENT_ARRAY_BUFFER_ARB, vertexIndexName = temp[3] ); gl.glBufferDataARB( GL.GL_ELEMENT_ARRAY_BUFFER_ARB, 4 * vertexIndexCount, vertexIndexBuffer, GL.GL_STATIC_DRAW_ARB ); gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, 0); // same lines with vertex coordinates // drawing - my terrain is divided to pieces (for loop) gl.glEnableClientState( GL.GL_VERTEX_ARRAY ); gl.glEnableClientState( GL.GL_COLOR_ARRAY ); gl.glEnableClientState( GL.GL_TEXTURE_COORD_ARRAY ); for(int k=0; k< linenumber_of_pieces; ++k){ for(int l=0; l< colnumber_of_pieces; ++l){ gl.glDisable( GL.GL_TEXTURE_2D ); gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, colorCoordinateName ); gl.glColorPointer( 3, GL.GL_UNSIGNED_BYTE, 0, BufferUtils.bufferOffset( 0 ) ); gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, vertexName[actualTerrain][k][l] ); gl.glVertexPointer( 3, GL.GL_FLOAT, 0, BufferUtils.bufferOffset( 0 ) ); gl.glBindBufferARB( GL.GL_ELEMENT_ARRAY_BUFFER_ARB, vertexIndexName ); gl.glDrawElements( GL.GL_TRIANGLE_STRIP, vertexIndexCount, GL.GL_UNSIGNED_INT, BufferUtils.bufferOffset( 0 ) ); } Thanks.
Advertisement
It seems you are re-loading the data every frame which is indeed slow, could you post your complete code and framerates?
The framerate is 20fps. It only render 128x128 terrain-piece with 32x32 vertex information.
code:

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

vertexIndexBuffer = BufferUtils.newIntBuffer( vertexIndexCount );

colorCoordinateBuffer = BufferUtils.newByteBuffer( 4 * vertexCount );

textureCoordinateBuffer = BufferUtils.newFloatBuffer( 2 * vertexCount );

bumpTextureCoordinateBuffer = BufferUtils.newFloatBuffer( 2 * vertexCount );
}

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 loadBasicVBOs(){

int[] temp = CreationFactory.createInt1DArray( 4 );

gl.glGenBuffersARB( 4, temp );
gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, colorCoordinateName = temp[0] );
gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, 4 * vertexCount, (Buffer) null ,GL.GL_STATIC_DRAW_ARB );
gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0);

gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, textureCoordinateName = temp[1] );
gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, 4 * 2 * vertexCount, (Buffer) null ,GL.GL_STATIC_DRAW_ARB );
gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0);

gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, bumpTextureCoordinateName = temp[2] );
gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, 4 * 2 * vertexCount, (Buffer) null ,GL.GL_STATIC_DRAW_ARB );
gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0);

gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, vertexIndexName = temp[3] );
gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, 4 * vertexIndexCount, (Buffer) null ,GL.GL_STATIC_DRAW_ARB );
gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, 0);
}

private static void fillVertexArrays(){
int shiftXIndex = 0, shiftZIndex = 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;
vertexBuffer[actualTerrain][k][l].clear();
for(int m = 0; m<SpellinaWorldStatics.WATERTEXTUREINDEX; ++m){
colorBuffer[actualTerrain][k][l][m].clear();
}
for (int i = 0; i <= SpellinaWorldStatics.SEGMENTSIZE; ++i ) {
for (int j = 0; j <= SpellinaWorldStatics.SEGMENTSIZE; ++j) {
vertexBuffer[actualTerrain][k][l].put( (shiftXIndex + i)*2 - steps[actualTerrain] );
vertexBuffer[actualTerrain][k][l].put( SpellinaTerrainStatics.getAltitude( actualTerrain, shiftXIndex + i, shiftZIndex + j )*1.0f );
vertexBuffer[actualTerrain][k][l].put( (shiftZIndex + j)*2 - steps[actualTerrain] );

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

}
}
}

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

initArrayBuffers();

fillCoordinateBuffers();

fillIndexBuffers();

loadBasicVBOs();

fillVertexArrays();
}

// 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< linenumber_of_pieces; ++k){
for(int l=0; l< colnumber_of_pieces; ++l){

gl.glDisable( GL.GL_TEXTURE_2D );
gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, colorCoordinateName );
gl.glColorPointer( 3, GL.GL_UNSIGNED_BYTE, 0, BufferUtils.bufferOffset( 0 ) );
gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, vertexName[actualTerrain][k][l] );
gl.glVertexPointer( 3, GL.GL_FLOAT, 0, BufferUtils.bufferOffset( 0 ) );

gl.glBindBufferARB( GL.GL_ELEMENT_ARRAY_BUFFER_ARB, vertexIndexName );
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 );
}

That is my code broadly speaking.
I tried this:

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

vertexIndexBuffer = BufferUtils.newIntBuffer( vertexIndexCount );//ByteBuffer.allocateDirect( vertexIndexCount * 4 ).asIntBuffer();

colorCoordinateBuffer = BufferUtils.newByteBuffer( 3 * vertexCount );//ByteBuffer.allocateDirect( 4 * vertexCount );

textureCoordinateBuffer = BufferUtils.newFloatBuffer( 2 * vertexCount );//ByteBuffer.allocateDirect( 4 * 2 * vertexCount ).asFloatBuffer();

bumpTextureCoordinateBuffer = BufferUtils.newFloatBuffer( 2 * vertexCount );//ByteBuffer.allocateDirect( 4 * 2 * vertexCount ).asFloatBuffer();
}

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.glEnableClientState( GL.GL_VERTEX_ARRAY );
gl.glBindBufferARB( GL.GL_ELEMENT_ARRAY_BUFFER_ARB, names[0] );
gl.glBufferDataARB( GL.GL_ELEMENT_ARRAY_BUFFER_ARB, vertexIndexCount * 4, vertexIndexBuffer, GL.GL_STATIC_DRAW_ARB );
vertexIndexBuffer.clear(); vertexIndexBuffer = null;

gl.glEnableClientState( GL.GL_COLOR_ARRAY );
gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, names[1] );
gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, 3 * vertexCount, colorCoordinateBuffer, GL.GL_STATIC_DRAW_ARB );
colorCoordinateBuffer.clear(); colorCoordinateBuffer = null;

gl.glEnableClientState( GL.GL_TEXTURE_COORD_ARRAY );
gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, names[2] );
gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, 2 * vertexCount * 4, textureCoordinateBuffer, GL.GL_STATIC_DRAW_ARB );
textureCoordinateBuffer.clear(); textureCoordinateBuffer = null;

gl.glEnableClientState( GL.GL_TEXTURE_COORD_ARRAY );
gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, names[3] );
gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, 2 * vertexCount * 4, bumpTextureCoordinateBuffer, GL.GL_STATIC_DRAW_ARB );
bumpTextureCoordinateBuffer.clear(); bumpTextureCoordinateBuffer = null;

System.gc();
}

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

initArrayBuffers();

fillCoordinateBuffers();

fillIndexBuffers();

initVBONames();

}

private static void fillVertexArrays(){
int shiftXIndex = 0, shiftZIndex = 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;
vertexBuffer[actualTerrain][k][l].clear();
for(int m = 0; m<SpellinaWorldStatics.WATERTEXTUREINDEX; ++m){
colorBuffer[actualTerrain][k][l][m].clear();
}
for (int i = 0; i <= SpellinaWorldStatics.SEGMENTSIZE; ++i ) {
for (int j = 0; j <= SpellinaWorldStatics.SEGMENTSIZE; ++j) {
vertexBuffer[actualTerrain][k][l].put( (shiftXIndex + i)*2 - steps[actualTerrain] );
vertexBuffer[actualTerrain][k][l].put( SpellinaTerrainStatics.getAltitude( actualTerrain, shiftXIndex + i, shiftZIndex + j )*1.0f );
vertexBuffer[actualTerrain][k][l].put( (shiftZIndex + j)*2 - steps[actualTerrain] );

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

}
}
}

private static void createVBONames(){
for(int k=0; k<stepLimits[actualTerrain]; ++k)
for(int l=0; l<stepLimits[actualTerrain]; ++l){
int[] temp = new int[ SpellinaWorldStatics.WATERTEXTUREINDEX + 1 ];
gl.glGenBuffersARB( SpellinaWorldStatics.WATERTEXTUREINDEX + 1, temp);

gl.glEnableClientState( GL.GL_VERTEX_ARRAY );
gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, vertexNames[actualTerrain][k][l] = temp[ SpellinaWorldStatics.WATERTEXTUREINDEX ] );
gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, 3 * vertexCount * 4, vertexBuffer[actualTerrain][k][l], GL.GL_STATIC_DRAW_ARB );
vertexBuffer[actualTerrain][k][l].clear(); vertexBuffer[actualTerrain][k][l] = null;

for(int m = 0; m<SpellinaWorldStatics.WATERTEXTUREINDEX; ++m){
gl.glEnableClientState( GL.GL_COLOR_ARRAY );
gl.glBindBufferARB( GL.GL_ARRAY_BUFFER_ARB, colorNames[actualTerrain][k][l][m] = temp[m] );
gl.glBufferDataARB( GL.GL_ARRAY_BUFFER_ARB, 4 * vertexCount, colorBuffer[actualTerrain][k][l][m], GL.GL_STATIC_DRAW_ARB );
colorBuffer[actualTerrain][k][l][m].clear(); colorBuffer[actualTerrain][k][l][m] = null;
}

}
System.gc();
}

//
// render loop
//
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][k][l] );
gl.glVertexPointer( 3, GL.GL_FLOAT, 0, BufferUtils.bufferOffset(0) );

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 );

}

So, with vertex arrays, it runs over 120fps, with vertex object under 25.

Have I made errors somewhere?
OK. I tried to use 1 big buffer for vertex buffer object, but the result is the same.
Here are my new code:

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 ) );


}
}

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) );
}
}

}
}
}

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 ];

}

I'm out of ideas. :((
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?

Should be 100% (it runs over twice as fast as vertex arrays at my comp).
Quote:Original post by fazekaim
I found the solution: unsigned byte.

No. You problem isn't the ubyte, but the 3 color components you used combined with the ubyte. Just add a fourth (alpha) component to the color, and you'll be fine using ubytes. It will even be faster than 3 floats due to lower bandwidth usage.
2x speed with vbo?
How can I make it?
I made everything written in the NVidia VBO white paper.

I declare the buffer to static.
I load it, and I use one big buffer using offset to positioning in it.
I use glDrawRangeElements in place of glDrawElements.
(I use indexing)

Should I use byte instead of float? Or in the index buffer short instead of int?

What else can I do?

Thanks.

This topic is closed to new replies.

Advertisement