Problem with particle system

Hello! I’m having problems with the particle system i’ve downloaded from NeHe . I’ve tried using it in one of my project and it is working fine,but when I am trying it on another one, the particles are represented only with the bitmap file loaded.

The working example:

The one I’m having problems with:

The base code for both of them are the same. Anyone knows what the problem might be?

Please post the source code. I’m afraid we can’t be of much help otherwise.

Your ‘working example’ does not seem to be working correctly, unless the boxes are meant to look like random colored noise… Here’s the output I get when running the code from lesson 19:

PS. I used this code.

At first sight, it looks like you disabled blending when drawing the particles.

N.

I’ve modified my code… In fact,the boxes are textured with a wood bitmap.

The code to initialise parameters:


void initGL(){
    glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);                       // Setup The Ambient Light
	//glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);                       // Setup The Diffuse Light
	//glLightfv(GL_LIGHT1, GL_SPECULAR, LightSpecular);                     // Setup The Specular Light
	//glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);                     // Position The Light
	glEnable(GL_LIGHT1);                                                  // Enable Light One


	glShadeModel(GL_SMOOTH);							// Enable Smooth Shading
	glClearColor(0.0f,0.0f,0.0f,0.0f);					// Black Background
	glClearDepth(1.0f);									// Depth Buffer Setup
	glDisable(GL_DEPTH_TEST);							// Disable Depth Testing
	glEnable(GL_BLEND);									// Enable Blending
	glBlendFunc(GL_SRC_ALPHA,GL_ONE);					// Type Of Blending To Perform
	glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);	// Really Nice Perspective Calculations
	glHint(GL_POINT_SMOOTH_HINT,GL_NICEST);				// Really Nice Point Smoothing
	glEnable(GL_TEXTURE_2D);							// Enable Texture Mapping
	glBindTexture(GL_TEXTURE_2D,texture[9]);			// Select Our Texture

	for (loop=0;loop<MAX_PARTICLES;loop++)				// Initials All The Textures
	{
		particle[loop].active=true;								// Make All The Particles Active
		particle[loop].life=1.0f;								// Give All The Particles Full Life
		particle[loop].fade=float(rand()%100)/1000.0f+0.003f;	// Random Fade Speed
		particle[loop].r=colors[loop*(12/MAX_PARTICLES)][0];	// Select Red Rainbow Color
		particle[loop].g=colors[loop*(12/MAX_PARTICLES)][1];	// Select Red Rainbow Color
		particle[loop].b=colors[loop*(12/MAX_PARTICLES)][2];	// Select Red Rainbow Color
		particle[loop].xi=float((rand()%50)-26.0f)*10.0f;		// Random Speed On X Axis
		particle[loop].yi=float((rand()%50)-25.0f)*10.0f;		// Random Speed On Y Axis
		particle[loop].zi=float((rand()%50)-25.0f)*10.0f;		// Random Speed On Z Axis
		particle[loop].xg=0.0f;									// Set Horizontal Pull To Zero
		particle[loop].yg=0.8f;								// Set Vertical Pull Downward
		particle[loop].zg=0.0f;									// Set Pull On Z Axis To Zero
	}							
}

The function to draw particles:


void DrawGLScene(void)										// Here's Where We Do All The Drawing
{
	for (loop=0;loop<MAX_PARTICLES;loop++)					// Loop Through All The Particles
	{
		if (particle[loop].active)							// If The Particle Is Active
		{
			float x=particle[loop].x;						// Grab Our Particle X Position
			float y=particle[loop].y;						// Grab Our Particle Y Position
			float z=particle[loop].z+zoom;					// Particle Z Pos + Zoom

			// Draw The Particle Using Our RGB Values, Fade The Particle Based On It's Life
			glColor4f(particle[loop].r,particle[loop].g,particle[loop].b,particle[loop].life);

			glBegin(GL_TRIANGLE_STRIP);						// Build Quad From A Triangle Strip
			    glTexCoord2d(1,1); glVertex3f(x+0.5f,y+0.5f,z); // Top Right
				glTexCoord2d(0,1); glVertex3f(x-0.5f,y+0.5f,z); // Top Left
				glTexCoord2d(1,0); glVertex3f(x+0.5f,y-0.5f,z); // Bottom Right
				glTexCoord2d(0,0); glVertex3f(x-0.5f,y-0.5f,z); // Bottom Left
			glEnd();										// Done Building Triangle Strip

			particle[loop].x+=particle[loop].xi/(slowdown*1000);// Move On The X Axis By X Speed
			particle[loop].y+=particle[loop].yi/(slowdown*1000);// Move On The Y Axis By Y Speed
			particle[loop].z+=particle[loop].zi/(slowdown*1000);// Move On The Z Axis By Z Speed

			particle[loop].xi+=particle[loop].xg;			// Take Pull On X Axis Into Account
			particle[loop].yi+=particle[loop].yg;			// Take Pull On Y Axis Into Account
			particle[loop].zi+=particle[loop].zg;			// Take Pull On Z Axis Into Account
			particle[loop].life-=particle[loop].fade;		// Reduce Particles Life By 'Fade'

			if (particle[loop].life<0.0f)					// If Particle Is Burned Out
			{
				particle[loop].life=1.0f;					// Give It New Life
				particle[loop].fade=float(rand()%100)/1000.0f+0.003f;	// Random Fade Value
				particle[loop].x=0.0f;						// Center On X Axis
				particle[loop].y=0.0f;						// Center On Y Axis
				particle[loop].z=0.0f;						// Center On Z Axis
				particle[loop].xi=xspeed+float((rand()%60)-32.0f);	// X Axis Speed And Direction
				particle[loop].yi=yspeed+float((rand()%60)-30.0f);	// Y Axis Speed And Direction
				particle[loop].zi=float((rand()%60)-30.0f);	// Z Axis Speed And Direction
				particle[loop].r=colors[col][0];			// Select Red From Color Table
				particle[loop].g=colors[col][1];			// Select Green From Color Table
				particle[loop].b=colors[col][2];			// Select Blue From Color Table
			}
		}
    }
}

By the way,I have other codes that are using the blending properties. For example,the tree is a billboard.

Your problem looks like typical “forgot to enable”, “forgot to disable” case. Look carefully through your initialization and rendering code. See what parameters you set and what you enable/disable.

If that won’t help, comment-out ALL other code and make particles work. Then start uncommenting fragments of code.

also dont forget that if you render your particles first, and “blend” on top (ie additive for fire/glow, or decal, for transparency), that the background is important.
e.g in a fresh “cleared” scene that might be black

and if you write your particles into the zbuffer later geometry wont “overwrite” those particles depending on z-test, which might also create the problems you have.

so for “non-solid” particles, you must always render them last.

I’ve tried checking the codes by commenting and then uncommenting, and I’ve found that when the particles are rendered correctly, the other objects are blended. Is there any way to correct this problem?

When I try building the forests with the billboard technique the scene returns as follows:

The code for loading the trees:


void DrawTrees()
{
	tgaInfo *image;

	glEnable(GL_DEPTH_TEST);

	glGenTextures(1, texName);
	image = tgaLoad("tree.tga");
	glBindTexture(GL_TEXTURE_2D,texName[0]);
	glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,	GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,	GL_REPEAT);

	glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER	,GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER	,GL_LINEAR);
	
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image->width, image->height,0, GL_RGBA, GL_UNSIGNED_BYTE, image->imageData);

	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, 0);

	glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GREATER, 0);
	glBindTexture(GL_TEXTURE_2D,texName[0]);

	for( int i = -50; i < 20; i++)
		for(int j = -10; j < 10; j++)
		{
			glPushMatrix();
			glTranslatef(5+i*2.0,0,-40);

			l3dBillboardCheatSphericalBegin();

			glBegin(GL_QUADS);
				glTexCoord2f(0,0);glVertex3f(-3.0f, 0.0f, 0.0f);
				glTexCoord2f(1,0);glVertex3f(3.0f, 0.0f, 0.0f);
				glTexCoord2f(1,1);glVertex3f(3.0f, 6.0f,  0.0f);
				glTexCoord2f(0,1);glVertex3f(-3.0f, 6.0f,  0.0f);
			glEnd();

			glPopMatrix();
		}
	glBindTexture(GL_TEXTURE_2D,0);
}

BMP doesn’t has alpha channel, try TGA file as particle texture.

The TGA file is only for the trees. Is it the code that loads the TGA file which is conflicting with the particle system??

Don’t put things such as glEnable(GL_BLEND) in an initGL function that is only being called at initialization time. Such a function should only contain calls that need to be made once and do not change (unlike the blending op which needs to be disabled when rendering the scene and enabled when rendering the particles). It’s good practice to enable the states you need when entering a function and disabling them when leaving the function so that you can rely on the default OpenGL state.

N.

Ok… It works now.