Nvidia point sprites.

Hi,

My engine is complete, and while writing a tech game with it, I decided to add a particle system using nvidia point sprites, for g3+.

But, they’re not showing up right. I can see them sometimes, but they’re always 1 pixel thick(I.e a texture line) and don’t fit in with the scene at all.

This is the code I use to render them.

 BBD void BBC Particle_RenderNV(){
particle *p;
GLuint lockedTex;
	glEnable(GL_BLEND);
	glBlendFunc(GL_ONE,GL_ONE);
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_POINT_SPRITE_NV);
	glTexEnvf(GL_POINT_SPRITE_NV,GL_COORD_REPLACE_NV,GL_TRUE);

	//glPointParameterf(GL_POINT_SPRITE_R_MODE_NV,GL_ZERO);
	glPointSize(1);
	glLoadIdentity();
		glPushMatrix();
		glRotatef(camroll,0,0,1); 
		glRotatef(campitch,1,0,0);
		glRotatef(camyaw,0,1,0);
		glPushMatrix();
		glTranslatef(camx,camy,camz);
		glBegin(GL_POINTS);
	for(int j=0;j<parc;j++){
		p=sys[j];
		if(!p->texture==lockedTex){ 
			glBindTexture(GL_TEXTURE_2D,p->texture);
			lockedTex=p->texture;}
			glVertex3f(p->x,p->y,p->z);
	};
	glEnd();
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_POINT_SPRITE_NV);
	glPopMatrix();
	glPopMatrix();
};

 

Camx,camy,camz/pitch/yaw/roll are what I use to render my scene. Which all displays fine btw, using vbos.

I guess my question is, how do I integrate the particles into the same viewport as I render my objects.

I figured simply setting up the same camera position, then using glVertex with the particles world position would do it.

I also tried manually setting the viewport for each particle, then passing a vert at 0,0,0. Identical code to what my mesh renderer uses, but this time, I could only see if I moved far away from 0,0,0 and while looking down. barely.

Any ideas where I’m going wrong?

Start fixing with this: It’s illegal to call glBindTexture(GL_TEXTURE_2D,p->texture) inside begin-end.

Doh. Thanks for poting that silly mistake out. Should just call end and recall glBegin in the loop when a texture change occurs.

You’re setting a point size of 1, which is in units of pixels, so your points will each have a diameter of 1 pixel (unless you’re using the ARB_point_parameters extension to attenuate point sizes by distance.) Try something like glPointSize(20.).

My recent experience with point sprites has been that they’re just not worth it. Granted, I was using the nearly equivalent ARB_point_sprite on ATI hardware (Radeon 9800 SE and 9800 Pro), so maybe NVIDIA hardware has a better implementation. The rendering of points was erratic, with many points inexplicably appearing or disappearing between frames. Also, if your points are relatively large and slow moving, you’ll notice that an entire point disappears as soon as its center falls off the screen (since they’re clipped as points, not quads). But for small points with motion, you won’t notice.

I switched to screen-aligned quads, which are a bit more work; you have to pass 4 overlapping vertices per “point” and use a vertex program/shader to move each vertex to the appropriate corner (or compute the offsets on the CPU if performance isn’t a concern). In any event, you need to pass 4 times as many vertices to GL, but if they’re stored as a VBO, you’d have to have a ton of points before performance becomes a problem on modern GPU’s.