Lesson #19: Particles (No Transparency)

Started by
7 comments, last by Dybbuk 18 years, 9 months ago
Helloy everybody, I started with Nehe's Tutorial #19 this morning and implemented the particle system in my application. It works fine after some "adaptions", but now I realize, that my particles won't "burn out", I mean, they are created, they fly their way across the screen or whatever and then they suddenly disappear. But in the lesson application, the particles fade out gradually on their way. I checked everything to my knowledge and can't seem to find out why they won't fade out gradually in my version. Here is the init_particles ( ) function to initialize the particle system:

void init_particles ( void )
// initializes the particle system
{
	// setup the particle system
	for ( int loop = 0; loop < MAX_PARTICLES; loop++ )
	{
		// activate the particle
		particle[loop].active = true;

		// give it full life
		particle[loop].life = 1.0f;

		// give it a random fade speed
		particle[loop].fade = float ( rand ( ) % 100 ) / 1000.0f + 0.003f;

		particle[loop].r = fire_color[rand ( ) % 4][0];
		particle[loop].g = fire_color[rand ( ) % 4][1];
		particle[loop].b = fire_color[rand ( ) % 4][2];

		// give it a random speed
		particle[loop].xi = float ( ( rand ( ) % 50 ) - 25.0f ) * 10.0f;
		particle[loop].yi = float ( ( rand ( ) % 50 ) - 25.0f ) * 10.0f;
		particle[loop].zi = float ( ( rand ( ) % 50 ) - 25.0f ) * 10.0f;

		// give it an upward gravity
		particle[loop].xg = 0.0f;
		particle[loop].yg = 0.6f;
		particle[loop].zg = 0.0f;
	}
}

And here is the draw_particles ( ) function, that draws the particles and updates their movement etc. It gets called by my draw_scene ( ) function every frame.

void draw_particles ( float x, float y, float z )
// draws particles at a specific location
{
	// move for the particle system test
	glTranslatef ( x, y, z );

	// disable depth testing
	glDisable ( GL_DEPTH_TEST );

	// enable blending
	glEnable ( GL_BLEND );

	// select blending type
	glBlendFunc ( GL_SRC_ALPHA, GL_ONE );

	for ( int loop = 0; loop < MAX_PARTICLES; loop++ )
	// loop through all particles
	{
		if ( particle[loop].active )
		// if the particle is active
		{
			float x = particle[loop].x;
			float y = particle[loop].y;
			float z = particle[loop].z;

			// set texture for particle
			glBindTexture ( GL_TEXTURE_2D, texture[2] );

			// set color and transparency for particle
			glColor4f ( particle[loop].r, particle[loop].g, particle[loop].b, particle[loop].life );

			// build quad from triangle strip
			glBegin ( GL_TRIANGLE_STRIP );

				glTexCoord2d ( 1, 1 ); glVertex3f ( x + 0.5f, y + 0.5f, z );
				glTexCoord2d ( 0, 1 ); glVertex3f ( x - 0.5f, y + 0.5f, z );
				glTexCoord2d ( 1, 0 ); glVertex3f ( x + 0.5f, y - 0.5f, z );
				glTexCoord2d ( 0, 0 ); glVertex3f ( x - 0.5f, y - 0.5f, z );

			glEnd ( );

			// move the particle according to his speed
			particle[loop].x += particle[loop].xi / ( 2.0f * 1000 );
			particle[loop].y += particle[loop].yi / ( 2.0f * 1000 );
			particle[loop].z += particle[loop].zi / ( 2.0f * 1000 );

			// move the particle according to his gravity
			particle[loop].xi += particle[loop].xg;
			particle[loop].yi += particle[loop].yg;
			particle[loop].zi += particle[loop].zg;

			// reduce life by fade
			particle[loop].life -= particle[loop].fade;

			if ( particle[loop].life < 0.0f )
			// if the particle is burned out
			{
				// give it new life and a random fade value
				particle[loop].life = 1.0f;
				particle[loop].fade = float ( rand ( ) % 100 ) / 1000.0f + 0.003f;

				// center it
				particle[loop].x = 0.0f;
				particle[loop].y = 0.0f;
				particle[loop].z = 0.0f;

				// give it new speed and direction
				particle[loop].xi = float ( ( rand ( ) % 60 ) - 30.0f );
				particle[loop].yi = float ( ( rand ( ) % 60 ) - 30.0f );
				particle[loop].zi = float ( ( rand ( ) % 60 ) - 30.0f );

				// select new color
				particle[loop].r = fire_color[rand ( ) % 4][0];
				particle[loop].g = fire_color[rand ( ) % 4][1];
				particle[loop].b = fire_color[rand ( ) % 4][2];
			}
		}
	}
	
	// reset color and transparency again
	//glColor4f ( 1.0f, 1.0f, 1.0f, 1.0f );

	// enable depth testing again 
	glEnable ( GL_DEPTH_TEST );

	// and disable blending again
	glDisable ( GL_BLEND );
}

I commented out the third line from the end in the draw_function ( ), but uncommenting it doesn't change a thing. Maybe I should also mention that my particles don't get the color they are supposed to take. It's almost like my glColor ( ) function does not get executed, but I couldn't find anything about this issue in either the tutorial or the OpenGL reference. Thanks, Jan.
Advertisement
It should work since it's allmost exactly the same as NeHe's code, but you can move the glBindTexture call to before the loop, the way your doing it is bad.

You must have changed something else.
Thanks for your kind reply. I moved the command and it improved the gamespeed a whole lot. :)

But back to the point: What is it that I could've changed, so that it won't execute those function calls anymore.

I tried it out to comment the glColor ( ) call and it didn't change anything ingame, so it's like it doesn't even get called for some reason. The particles don't fade and they don't get colored.

That is becoming seriously wierd (to me as a newb atleast)...
i messed around with lesson 19 and the only way i could even begin to replicate the problem slightly where if i added the line glEnable(GL_LIGHTING); somewhere.

so my question is, is it a really bright white particle system or a sort of grayish one.

one more thing i messed with.
I modified these lines.

particle[loop].xi+=particle[loop].xg;
particle[loop].yi+=particle[loop].yg;
particle[loop].zi+=particle[loop].zg;

to this

particle[loop].xi+=particle[loop].xg+(rand()%(spr*2))-spr;
particle[loop].yi+=particle[loop].yg+(rand()%(spr*2))-spr;
particle[loop].zi+=particle[loop].zg+(rand()%(spr*2))-spr;

spr is an int that i can control that goes from 1 and up.
this gives a pretty cool effect

[Edited by - lc_overlord on August 8, 2005 4:03:17 PM]
I seem to recall having this issue once before with a textured quad doing the same thing, but off the top of my head, I can't recall what exactly the issue was. I would suggest checking through your texture code and making sure you have it set up right. If I recall, my issue was something with my textures.

Good luck, and when I get a chance, I'll try to see what I might be able to find out.
Thanks everybody,

while not being connected to the internet this morning, I found out what you, overlord, said. I enabled GL_LIGHTING in my scene. Does enabling LIGHTING disable all glColor function calls? If so, is there anyway to work around that?

I'll try your addition to the effect as well, overlord - you have definately earned your r++ for today... ;)
when you enable lighting it sort of takes over the glColor4f function, to solve this you could either fiddle with the material color or use a fragment shader.

However, most particle systems are not lit by openGL lights anyway.
Thanks again, now I just disable GL_LIGHTING to draw my particle system and then enable it again. I didn't even want to light my particles with those lights...
to combine the lighting and color you need to place

glEnable(GL_COLOR_MATERIAL);

in your init code
that shoul solve it

This topic is closed to new replies.

Advertisement