Jump to content

  • Log In with Google      Sign In   
  • Create Account


Adding values to FloatBuffers


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
4 replies to this topic

#1 mickd   Members   -  Reputation: 100

Like
0Likes
Like

Posted 09 April 2011 - 05:05 AM

Hi guys, I've stumbled across a bug in my code. A few of my friends and i have all had a look through it, and still cant figure it out. I also posted this on the opengl official forums a while ago, but since FloatBuffer is a java implementation, i thought it might be more appropriate to post it here!

Any help greatly appreciated!

The program:
I'm creating a flame in a simple particle system. It has the ability to do the bezier calculations on the cpu or through the shader (toggle-able). Adding particles while its rendering without using the shader works perfectly.

The problem:
When i turn on the shader, adding particles to the FloatBuffers behave unexpectedly.

Say i have my current floatbuffer, which can hold 3000 floats (before it buffer overflows), and i have exactly 3000 floats in it. While not using the shader, if i increase the number of floats to 4500, my code creates a new floatbuffer that can hold double the previous one (6k floats), copies the old 3000 floats into it, and adds the new 1500 floats ontop of it.

The result is i have a float buffer that can hold 6000 floats, and has 4500 in it currently.

When i do the same thing when the shader is turned in, instead of adding the 1500 extra floats ontop of the 3000, it seems like its wiping the buffer clean, and adding the 1500 new floats.

The result is i have a float buffer that can hold 3000 still (since it never tried to add the 3001st float, the function never creates a bigger buffer), but with only 1500 floats (the new floats i think) only.

I hope that makes some sense. The weird thing is, its the exact same createParticle() code that is being called when the cpu calculated flame or the shader calculated flame is running.

All attributes are bound and passed successfully into the vertex shader this time!

Here's hopefully all the relevant code...

The drawing code: drawParticles is called in display()
	double lastRendered = System.currentTimeMillis();
	
	protected void drawParticles(GL gl) {
    	
    	gl.glColor4f(0.7f, 0.2f, 0.1f, 0.8f);
    	gl.glPointSize(20);
    	
    	if(useShader) {
            
            GPUrenderer(gl);
    	}
    	else {
            
            CPUrenderer(gl);
    	}
    	
    	if((System.currentTimeMillis() - lastRendered) >= 30) {
            
            time += 0.03f;
            lastRendered = System.currentTimeMillis();
    	}
    	
    	if(time > 1) time = 0;
	}
	
	private void CPUrenderer(GL gl) {
    	
    	gl.glUseProgram(0);
    	
    	gl.glBegin(GL.GL_POINTS);
    	
    	FlameParticle particle;
    	Vector3D particleLocation;
    	
    	for(int i = 0; i < particleList.size(); i++) {
            
            particle = (FlameParticle)particleList.get(i);
            
            particleLocation = particle.currPosition(time);
            
            gl.glVertex3f(particleLocation.x, particleLocation.y, particleLocation.z);
    	}
    	
    	gl.glEnd();
	}
	
	private void GPUrenderer(GL gl) {
    	
    	gl.glUseProgram(shader.getProgram());
    	
    	gl.glUniform1f(gl.glGetUniformLocation(shader.getProgram(), "time"), time);
    	
//        System.out.println(cp1.capacity());
    	
    	
    	cp0.rewind();
    	gl.glVertexPointer(3, GL.GL_FLOAT, 0, cp0); // bezier cp0
    	cp1.rewind();
    	gl.glVertexAttribPointer(BEZIER_CP1, 3, GL.GL_FLOAT, false, 0, cp1);
    	cp2.rewind();
    	gl.glVertexAttribPointer(BEZIER_CP2, 3, GL.GL_FLOAT, false, 0, cp2);
    	cp3.rewind();
    	gl.glVertexAttribPointer(BEZIER_CP3, 3, GL.GL_FLOAT, false, 0, cp3);
    	startTime.rewind();
    	gl.glVertexAttribPointer(START_TIME, 1, GL.GL_FLOAT, false, 0, startTime);
    	
    	gl.glEnableClientState(GL.GL_VERTEX_ARRAY); // bezier cp0
//        gl.glEnableVertexAttribArray(BEZIER_CP0);
    	gl.glEnableVertexAttribArray(BEZIER_CP1);
    	gl.glEnableVertexAttribArray(BEZIER_CP2);
    	gl.glEnableVertexAttribArray(BEZIER_CP3);
    	gl.glEnableVertexAttribArray(START_TIME);

    	gl.glDrawArrays(GL.GL_POINTS, 0, particleList.size());
    	
    	gl.glDisableClientState(GL.GL_VERTEX_ARRAY); // bezier cp0
//        gl.glDisableVertexAttribArray(BEZIER_CP0);
    	gl.glDisableVertexAttribArray(BEZIER_CP1);
    	gl.glDisableVertexAttribArray(BEZIER_CP2);
    	gl.glDisableVertexAttribArray(BEZIER_CP3);
    	gl.glDisableVertexAttribArray(START_TIME);
	}

setting up the floatbuffers initially, called in init()
	protected FloatBuffer cp0, cp1, cp2, cp3, startTime;
	
	protected void setupBuffers() {
		
		cp0 = BufferUtil.newFloatBuffer(3 * 1000);
		cp1 = BufferUtil.newFloatBuffer(3 * 1000);
		cp2 = BufferUtil.newFloatBuffer(3 * 1000);
		cp3 = BufferUtil.newFloatBuffer(3 * 1000);
		startTime = BufferUtil.newFloatBuffer(1000);
	}

addParticles(amount to add) called when i press + on the keyboard
	private void addParticles(int toAdd) {
		
		int count = 0;
		
		while(count < toAdd) {
			
			createParticle();
			
			count++;
		}
	}

	protected void createParticle() {
		
		FlameParticle particle = new FlameParticle();
		
		particleList.add(particle);
		
		FloatBuffer temp;
		
		if(cp0.remaining() < 3) {
			System.out.println("here");
//			cp0.rewind();
			temp = BufferUtil.newFloatBuffer(cp0.capacity());
			temp.put(cp0);
			temp.rewind();
			cp0.rewind();
			cp0 = BufferUtil.newFloatBuffer(cp0.capacity() * 2);
			cp0.put(temp);
//			cp0.position(temp.position());
		}
		
		if(cp1.remaining() < 3) {
			
//			cp1.rewind();
			temp = BufferUtil.newFloatBuffer(cp1.capacity());
			temp.put(cp1);
			temp.rewind();
			cp1.rewind();
			cp1 = BufferUtil.newFloatBuffer(cp1.capacity() * 2);
			cp1.put(temp);
//			cp1.position(temp.position());
		}
		
		if(cp2.remaining() < 3) {
			
//			cp2.rewind();
			temp = BufferUtil.newFloatBuffer(cp2.capacity());
			temp.put(cp2);
			temp.rewind();
			cp2.rewind();
			cp2 = BufferUtil.newFloatBuffer(cp2.capacity() * 2);
			cp2.put(temp);
//			cp2.position(temp.position());
		}
		
		if(cp3.remaining() < 3) {
			
//			cp3.rewind();
			temp = BufferUtil.newFloatBuffer(cp3.capacity());
			temp.put(cp3);
			temp.rewind();
			cp3.rewind();
			cp3 = BufferUtil.newFloatBuffer(cp3.capacity() * 2);
			cp3.put(temp);
//			cp3.position(temp.position());
		}
		
		if(startTime.remaining() < 1) {
			
//			startTime.rewind();
			temp = BufferUtil.newFloatBuffer(startTime.capacity());
			temp.put(startTime);
			temp.rewind();
			startTime.rewind();
			startTime = BufferUtil.newFloatBuffer(startTime.capacity() * 2);
			startTime.put(temp);
//			startTime.position(temp.position());
		}
		
//		System.out.println(cp0.position());
		
//		cp0.position((particleList.size()-1)*3);
//		cp1.position((particleList.size()-1)*3);
//		cp2.position((particleList.size()-1)*3);
//		cp3.position((particleList.size()-1)*3);
//		startTime.position(particleList.size()-1);
		
		cp0.put(particle.cp0.x);
		cp0.put(particle.cp0.y);
		cp0.put(particle.cp0.z);
		
		cp1.put(particle.cp1.x);
		cp1.put(particle.cp1.y);
		cp1.put(particle.cp1.z);
		
		cp2.put(particle.cp2.x);
		cp2.put(particle.cp2.y);
		cp2.put(particle.cp2.z);
		
		cp3.put(particle.cp3.x);
		cp3.put(particle.cp3.y);
		cp3.put(particle.cp3.z);
		
		startTime.put(particle.startTime);
		
		System.out.println(cp0.position());
		System.out.println("remaining " + cp0.remaining());
		System.out.println("capacity " + cp0.capacity());
		
	}


I hope that's everything relevant. To recap: when i toggle "useShader" to true, adding to FloatBuffers seems to "clear" the buffer before adding particles. When "useShader" is false, FloatBuffer's work as intended.

Once again, any help would be greatly appreciated!!

Sponsor:

#2 Danny02   Members   -  Reputation: 275

Like
0Likes
Like

Posted 09 April 2011 - 10:25 AM

i don't think u got the "GPU" drawing right. You need some Buffer Objects to draw from. The attributepointer functions don't work as u think. The last attribut is a offset into an uploaded BO. Your framework probably uses the position of the FloatBuffer(?).

#3 karwosts   Members   -  Reputation: 840

Like
0Likes
Like

Posted 09 April 2011 - 10:30 AM

You need some Buffer Objects to draw from. The attributepointer functions don't work as u think. The last attribut is a offset into an uploaded BO. Your framework probably uses the position of the FloatBuffer(?).


That's not quite true, if you use attribute pointers without a buffer bound, the last argument, pointer, is treated as a pointer into system memory. This is called using vertex arrays, and his syntax appears to be correct (though I don't know the language).

To OP: have you tried stepping through in a debugger and seeing what's going on when you add particles?
My Projects:
Portfolio Map for Android - Free Visual Portfolio Tracker
Electron Flux for Android - Free Puzzle/Logic Game

#4 Danny02   Members   -  Reputation: 275

Like
0Likes
Like

Posted 09 April 2011 - 10:59 AM

sure? is this not only true for the actual drawArrays call?
never tried this before^^

#5 karwosts   Members   -  Reputation: 840

Like
0Likes
Like

Posted 09 April 2011 - 11:22 AM

sure?


Yes.

Vertex Arrays
My Projects:
Portfolio Map for Android - Free Visual Portfolio Tracker
Electron Flux for Android - Free Puzzle/Logic Game




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS