too slow VBO
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.
It seems you are re-loading the data every frame which is indeed slow, could you post your complete code and framerates?
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.
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?
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. :((
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?
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?
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.
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
Popular Topics
Advertisement