Jump to content
  • Advertisement
Sign in to follow this  
mickd

OpenGL Adding values to FloatBuffers

This topic is 2691 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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!!

Share this post


Link to post
Share on other sites
Advertisement
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(?).

Share this post


Link to post
Share on other sites

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(?).
[/quote]

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?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!