"2D blocks game" water falling

I am making 2D blocks game, everything is ok, but i cant make water falling correct. Water falling is working, but it takes too much FPS.
My water blocks extends class Blocks. To render blocks i am using VBOs (one chunk - one VBO). Right now i am updating chunk VBO, when water block moves. I am doing it like that:

for(int cx = 0;cx < sizex;cx++){
				for(int cy = 0;cy < sizey;cy++){
					for(int bx = 0;bx < 16;bx++){
						for(int by = 0;by < 16;by++){
							if(cy == sizex-1 && by == 15){
							}else{
							if(chunks[cx][cy].blocks[bx][by].isWater){
											if(by == 15){
												if(chunks[cx][cy+1].blocks[bx][0].id == IDS.airBlockID){
											        chunks[cx][cy+1].blocks[bx][0] = new WaterBlock(...);
											        chunks[cx][cy].blocks[bx][by] = new AirBlock(...);
                                          chunks[cx][cy].updateVBOTextures();
                                          chunks[cx][cy+1].updateVBOTextures();
												}
											}else{
												if(chunks[cx][cy].blocks[bx][by+1].id == IDS.airBlockID){
											        chunks[cx][cy].blocks[bx][by+1] = new WaterBlock(...);
												    chunks[cx][cy].blocks[bx][by] = new AirBlock(...);
											        chunks[cx][cy].updateVBOTextures();
												}
											}
										}
									}
						}
					}
				}
			}

My main FPS problem here is this line:

  chunks[...][...].updateVBOTextures();

I am updating VBOs every tick, and it takes too much FPS. I want to ask, how i can avoid this VBOs updating every tick, and still get similar result (i want to see how water falling).

how are you updating your vbo?

can i see your shaders and updateVBOTextures method

also what version of openGL are you using for the most part and what is your limit?

Are you using GL_STREAM_DRAW instead of GL_STATIC_DRAW?

if he is changing data he should be using GL_DYNAMIC_DRAW, not static, also all this does is tell openGL how to put the buffer in memory and shouldn’t cause huge drops in FPS with what is probably a small amount of data anyway

Dynamic Draw is for multiple updates pre-render and GL_STREAM_DRAW is intended for when you know you will need to update once per frame or less, but your right, I dont think it would cause a frame rate drop in a simple 2d game.

I could be wrong.

What is in your updateVBOTextures method?

You are mistaken. Dynamic is multiple changes in the lifetime of the BO and used frequently. Static is no changes once set and used frequently. Steam is set once and not used often.

The way I understand it is:

STATIC_DRAW - 1:N
DYNAMIC_DRAW - M:N
STREAM_DRAW - 1:1

Where the ratio is Uploads:Drawings.

So static is upload once, draw any amount of times.
Dynamic is upload any amount of times, and drawn any amount of times per upload.
Stream is upload any amount of times, and draw once per upload.

Of course, these are just hints to the GPU, which lets it store the buffer in a way that makes it fastest for that sort of operation. You can draw STREAM_DRAW buffers as much as you like, but it would be more optimised to use dynamic.

public void updateVBOTextures(){
		for(int xb = 0;xb < 16;xb++){
			for(int yb = 0;yb < 16;yb++){
				changeTextureVBO((xb*16)+yb,blocks[xb][yb].textureX,blocks[xb][yb].textureY);
			}
		}
		glBindBuffer(GL_ARRAY_BUFFER, vboVertexID);
		glBufferData(GL_ARRAY_BUFFER, (FloatBuffer) BufferUtils.createFloatBuffer(data.length).put(data).flip() , GL_STATIC_DRAW);
		
	}
public void changeTextureVBO(int target,float textureX, float textureY){
		target = target * 32;
		data[target+2] = textureX;
		data[target+3] = textureY;
		
		data[target+2+8] = textureX + texSize;
		data[target+3+8] = textureY;
		
		data[target+10+8] = textureX + texSize;
		data[target+11+8] = textureY + texSize;
		
		data[target+18+8] = textureX ;
		data[target+19+8] = textureY + texSize;
		
		target = 0;
		
	}

I am using static draw. I am not using any shaders.

Use dynamic draw, use glBufferSubData (or glMapBuffers if you wanna be more modern). Instead of remaking the float buffer, flip it again and use .put(float[], offset, size). Will be way faster :slight_smile: