Example #1
0
/*
===============
R_DrawParticles
===============
*/
void R_DrawParticles (void)
{
	int				i;
	particle_t		*p;

	VectorScale (vright, xscaleshrink, r_pright);
	VectorScale (vup, yscaleshrink, r_pup);
	VectorCopy (vpn, r_ppn);
	
	for (i = 0, p = r_refdef2.particles; i < r_refdef2.numParticles; i++, p++)
	{
		D_DrawParticle (p);
	}
}
Example #2
0
/*
===============
R_DrawParticles
===============
*/
void R_DrawParticles(void)
{
   particle_t *p;

   D_StartParticles();

   VectorScale(vright, xscaleshrink, r_pright);
   VectorScale(vup, yscaleshrink, r_pup);
   VectorCopy(vpn, r_ppn);

   for (p = active_particles; p; p = p->next)
      D_DrawParticle(p);

   D_EndParticles();
}
Example #3
0
void R_DrawParticles (void)
{
	particle_t		*p, *kill;
	float			grav;
	int				i;
	float			time2, time3;
	float			time1;
	float			dvel;
	float			frametime;
	
#ifdef GLQUAKE
	vec3_t			up, right;
	float			scale;

    GL_Bind(particletexture);
	glEnable (GL_BLEND);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glBegin (GL_TRIANGLES);

	VectorScale (vup, 1.5, up);
	VectorScale (vright, 1.5, right);
#else
	D_StartParticles ();

	VectorScale (vright, xscaleshrink, r_pright);
	VectorScale (vup, yscaleshrink, r_pup);
	VectorCopy (vpn, r_ppn);
#endif
	frametime = cl.time - cl.oldtime;
	time3 = frametime * 15;
	time2 = frametime * 10; // 15;
	time1 = frametime * 5;
	grav = frametime * sv_gravity.value * 0.05;
	dvel = 4*frametime;
	
	for ( ;; ) 
	{
		kill = active_particles;
		if (kill && kill->die < cl.time)
		{
			active_particles = kill->next;
			kill->next = free_particles;
			free_particles = kill;
			continue;
		}
		break;
	}

	for (p=active_particles ; p ; p=p->next)
	{
		for ( ;; )
		{
			kill = p->next;
			if (kill && kill->die < cl.time)
			{
				p->next = kill->next;
				kill->next = free_particles;
				free_particles = kill;
				continue;
			}
			break;
		}

#ifdef GLQUAKE
		// hack a scale up to keep particles from disapearing
		scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
			+ (p->org[2] - r_origin[2])*vpn[2];
		if (scale < 20)
			scale = 1;
		else
			scale = 1 + scale * 0.004;
		glColor3ubv ((byte *)&d_8to24table[(int)p->color]);
		glTexCoord2f (0,0);
		glVertex3fv (p->org);
		glTexCoord2f (1,0);
		glVertex3f (p->org[0] + up[0]*scale, p->org[1] + up[1]*scale, p->org[2] + up[2]*scale);
		glTexCoord2f (0,1);
		glVertex3f (p->org[0] + right[0]*scale, p->org[1] + right[1]*scale, p->org[2] + right[2]*scale);
#else
		D_DrawParticle (p);
#endif
		p->org[0] += p->vel[0]*frametime;
		p->org[1] += p->vel[1]*frametime;
		p->org[2] += p->vel[2]*frametime;
		
		switch (p->type)
		{
		case pt_static:
			break;
		case pt_fire:
			p->ramp += time1;
			if (p->ramp >= 6)
				p->die = -1;
			else
				p->color = ramp3[(int)p->ramp];
			p->vel[2] += grav;
			break;

		case pt_explode:
			p->ramp += time2;
			if (p->ramp >=8)
				p->die = -1;
			else
				p->color = ramp1[(int)p->ramp];
			for (i=0 ; i<3 ; i++)
				p->vel[i] += p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_explode2:
			p->ramp += time3;
			if (p->ramp >=8)
				p->die = -1;
			else
				p->color = ramp2[(int)p->ramp];
			for (i=0 ; i<3 ; i++)
				p->vel[i] -= p->vel[i]*frametime;
			p->vel[2] -= grav;
			break;

		case pt_blob:
			for (i=0 ; i<3 ; i++)
				p->vel[i] += p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_blob2:
			for (i=0 ; i<2 ; i++)
				p->vel[i] -= p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_grav:
#ifdef QUAKE2
			p->vel[2] -= grav * 20;
			break;
#endif
		case pt_slowgrav:
			p->vel[2] -= grav;
			break;
		}
	}

#ifdef GLQUAKE
	glEnd ();
	glDisable (GL_BLEND);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
#else
	D_EndParticles ();
#endif
}
void R_DrawParticles (void)
{
	int				i;
	float			grav, time1, time2, time3, dvel, frametime;
	particle_t		*p, *kill;
	float			scale;	
	vec3_t			up, right;
	

#ifdef PSP_HARDWARE_VIDEO

	int 			part_buffer_size = PART_BUFFER_SIZE;
	psp_particle* 	part_buffer = NULL;
	part_buffer 	= D_CreateBuffer(part_buffer_size);

	VectorScale (vup, 1.25, up);
	VectorScale (vright, 1.25, right);
#endif
	D_StartParticles ();

 #ifdef PSP_HARDWARE_VIDEO
	//VectorScale (vright, xscaleshrink, r_pright);
	//VectorScale (vup, yscaleshrink, r_pup);
	//VectorCopy (vright, r_pright);
	//VectorCopy (vup, r_pup);
 #else
	VectorScale (vright, xscaleshrink, r_pright);
	VectorScale (vup, yscaleshrink, r_pup);
 #endif
	VectorCopy (vpn, r_ppn);

	frametime = cl.time - cl.oldtime;
	time3 = frametime * 15;
	time2 = frametime * 10; // 15;
	time1 = frametime * 5;
	grav = frametime * sv_gravity.value * 0.05;
	dvel = 4*frametime;

	for ( ;; )
	{
		kill = active_particles;
		if (kill && kill->die < cl.time)
		{
			active_particles = kill->next;
			kill->next = free_particles;
			free_particles = kill;
			continue;
		}
		break;
	}

	for (p=active_particles ; p ; p=p->next)
	{
		for ( ;; )
		{
			kill = p->next;
			if (kill && kill->die < cl.time)
			{
				p->next = kill->next;
				kill->next = free_particles;
				free_particles = kill;
				continue;
			}
			break;
		}

#ifdef PSP_HARDWARE_VIDEO
		// hack a scale up to keep particles from disapearing
		scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] + (p->org[2] - r_origin[2])*vpn[2];
		if (scale < 20)
			scale = 1;
		else
			scale = 1 + scale * 0.004;

		// D_DrawParticle (p, up, right, scale);
		int rv = D_DrawParticleBuffered(part_buffer,p, up, right, scale);
		if (rv == -1)
			part_buffer = D_CreateBuffer(part_buffer_size);

#else
		D_DrawParticle (p);
#endif
		p->org[0] += p->vel[0]*frametime;
		p->org[1] += p->vel[1]*frametime;
		p->org[2] += p->vel[2]*frametime;

		switch (p->type)
		{
		case pt_static:
			break;

		case pt_fire:
			p->ramp += time1;
			if (p->ramp >= 6)
				p->die = -1;
			else
				p->color = ramp3[(int)p->ramp];
			p->vel[2] += grav;
			break;

		case pt_explode:
			p->ramp += time2;
			if (p->ramp >=8)
				p->die = -1;
			else
				p->color = ramp1[(int)p->ramp];
			for (i=0 ; i<3 ; i++)
				p->vel[i] += p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_explode2:
			p->ramp += time3;
			if (p->ramp >=8)
				p->die = -1;
			else
				p->color = ramp2[(int)p->ramp];
			for (i=0 ; i<3 ; i++)
				p->vel[i] -= p->vel[i]*frametime;
			p->vel[2] -= grav;
			break;

		case pt_blob:
			for (i=0 ; i<3 ; i++)
				p->vel[i] += p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_blob2:
			for (i=0 ; i<2 ; i++)
				p->vel[i] -= p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_grav:
		case pt_slowgrav:
			p->vel[2] -= grav;
			break;
		}
	}
#ifdef PSP_HARDWARE_VIDEO
	D_DeleteBuffer(part_buffer);
#endif
	D_EndParticles ();
}
Example #5
0
void R_DrawParticles (void)
{
#ifdef WIN32
	particle_t		*p, *kill;
	int				i;
	float			vel0, vel1, vel2;
	vec3_t			save_org;

#ifdef GLQUAKE
	float			scale;

	GL_Bind(particletexture);
	glEnable (GL_BLEND);
	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glBegin (GL_TRIANGLES);

	VectorScale (vup, 1.5, r_pup);
	VectorScale (vright, 1.5, r_pright);
#else

	VectorScale (vright, xscaleshrink, r_pright);
	VectorScale (vup, yscaleshrink, r_pup);
	VectorCopy (vpn, r_ppn);
#endif

	for ( ;; ) 
	{
		kill = active_particles;
		if (kill && kill->die < cl.time)
		{
			active_particles = kill->next;
			kill->next = free_particles;
			free_particles = kill;
			continue;
		}
		break;
	}

	for (p=active_particles ; p ; p=p->next)
	{
		for ( ;; )
		{
			kill = p->next;
			if (kill && kill->die < cl.time)
			{
				p->next = kill->next;
				kill->next = free_particles;
				free_particles = kill;
				continue;
			}
			break;
		}
		
		if (p->type==pt_rain)
		{
#ifdef GLQUAKE
			// hack a scale up to keep particles from disapearing
			scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
				+ (p->org[2] - r_origin[2])*vpn[2];
			if (scale < 20)
				scale = 1;
			else
				scale = 1 + scale * 0.004;
			if (p->color <= 255)
				glColor3ubv ((byte *)&d_8to24table[(int)p->color]);
			else
				glColor4ubv ((byte *)&d_8to24TranslucentTable[(int)p->color-256]);
			
			//fixme: need rain texture
			glTexCoord2f (1,0);
			glVertex3fv (p->org);
			glTexCoord2f (1,0.5);
			glVertex3f (p->org[0] + r_pup[0]*scale, p->org[1] + r_pup[1]*scale, p->org[2] + r_pup[2]*scale);
			glTexCoord2f (0.5,0);
			glVertex3f (p->org[0] + r_pright[0]*scale, p->org[1] + r_pright[1]*scale, p->org[2] + r_pright[2]*scale);
#else
			VectorCopy(p->org,save_org);

			vel0 = p->vel[0]*.001;
			vel1 = p->vel[1]*.001;
			vel2 = p->vel[2]*.001;

			for(i=0;i<4;i++)
			{
				D_DrawParticle(p);
				p->org[0] += vel0;
				p->org[1] += vel1;
				p->org[2] += vel2;
 			}
			D_DrawParticle(p);

			VectorCopy(save_org,p->org);//Restore origin
#endif
		}
		else if (p->type==pt_snow)
		{
#ifdef GLQUAKE
//IDEA: Put a snowflake texture on two-sided poly
//texture comes from glrmisc.c: R_InitParticleTexture 
			scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
				+ (p->org[2] - r_origin[2])*vpn[2];
			if (scale < 20)
				scale = p->count/10;	
			else
				scale = p->count/10 + scale * 0.004;

			if (p->color <= 255)
				glColor3ubv ((byte *)&d_8to24table[(int)p->color]);
			else
				glColor4ubv ((byte *)&d_8to24TranslucentTable[(int)p->color-256]);
	
			if(p->count>=69)
				glTexCoord2f (1,1);//happy snow!- bottom right
			else if(p->count>=40)	
				glTexCoord2f (0,0);	//normal snow - top left
			else if(p->count>=30)
				glTexCoord2f (0,1);	//bottom left
			else
				glTexCoord2f (1,0);	//top right

			glVertex3fv (p->org);
			if(p->count>=69)
				glTexCoord2f (1,.18);//top right
			else if(p->count>=40)	
				glTexCoord2f (.815,0);//top right
			else if(p->count>=30)
				glTexCoord2f (0.5,1);//bottom middle
			else
				glTexCoord2f (1,0.5);//middle right

			glVertex3f (p->org[0] + r_pup[0]*scale, p->org[1] + r_pup[1]*scale, p->org[2] + r_pup[2]*scale);

			if(p->count>=69)
				glTexCoord2f (.18,1);//bottom left
			else if(p->count>=40)	
				glTexCoord2f (0,.815);//bottom left
			else if(p->count>=30)
				glTexCoord2f (0,0.5);//left middle
			else
				glTexCoord2f (0.5,0);//middle top
			
			glVertex3f (p->org[0] + r_pright[0]*scale, p->org[1] + r_pright[1]*scale, p->org[2] + r_pright[2]*scale);
#else
			VectorCopy(p->org,save_org);
			D_DrawParticle (p);

			for(i=1;i<p->count;i++)
			{
				switch(i)
				{//FIXME:  More translucency on outside particles?
//				case 0:	//original
//					break;
				case 1:	//One to right
					p->org[0] = save_org[0] + vright[0];
					p->org[1] = save_org[1] + vright[1];
					p->org[2] = save_org[2] + vright[2];
					break;
				case 2: //One above
					p->org[0] = save_org[0] + vup[0];
					p->org[1] = save_org[1] + vup[1];
					p->org[2] = save_org[2] + vup[2];
					break;
				case 3:	//One to left
					p->org[0] = save_org[0] - vright[0];
					p->org[1] = save_org[1] - vright[1];
					p->org[2] = save_org[2] - vright[2];
					break;
				case 4:	//One below
					p->org[0] = save_org[0] - vup[0];
					p->org[1] = save_org[1] - vup[1];					
					p->org[2] = save_org[2] - vup[2];
					break;
				default:
				   Con_Printf ("count too big!\n");
					break;
				}
				D_DrawParticle (p);
			}
			VectorCopy(save_org,p->org);//Restore origin
#endif
		}
		else
		{
#ifdef GLQUAKE
			// hack a scale up to keep particles from disapearing
			scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
				+ (p->org[2] - r_origin[2])*vpn[2];
			if (scale < 20)
				scale = 1;
			else
				scale = 1 + scale * 0.004;
			if (p->color <= 255)
				glColor3ubv ((byte *)&d_8to24table[(int)p->color]);
			else
				glColor4ubv ((byte *)&d_8to24TranslucentTable[(int)p->color-256]);
			glTexCoord2f (1,0);
			glVertex3fv (p->org);
			glTexCoord2f (1,0.5);
			glVertex3f (p->org[0] + r_pup[0]*scale, p->org[1] + r_pup[1]*scale, p->org[2] + r_pup[2]*scale);
			glTexCoord2f (0.5,0);
			glVertex3f (p->org[0] + r_pright[0]*scale, p->org[1] + r_pright[1]*scale, p->org[2] + r_pright[2]*scale);
#else
			D_DrawParticle (p);
#endif
		}
	}

#ifdef GLQUAKE
	glEnd ();
	glDisable (GL_BLEND);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
#endif
#endif
}
Example #6
0
void R_DrawParticles (void)
{
	particle_t		*p, *kill;
	float			grav;
	int				i;
	float			time2, time3;
	float			time1;
	float			dvel;
	float			frametime;
#ifdef USE_OPENGLES
	float*			pPos = gVertexBuffer;
	unsigned char*	pColor = (unsigned char*) gColorBuffer;
	unsigned char*  pUV = (unsigned char*) gTexCoordBuffer;
	int				particleIndex = 0;
	int				maxParticleIndex = (int) sizeof(gVertexBuffer) / (sizeof(float) * 3) - 3;
#endif
#ifdef GLQUAKE
	vec3_t			up, right;
	float			scale;

	GL_Bind(particletexture);

	glEnable (GL_BLEND);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

#ifdef USE_OPENGLES
	glEnableClientState(GL_COLOR_ARRAY);
	glVertexPointer(3, GL_FLOAT, 0, gVertexBuffer);
	glTexCoordPointer(2, GL_BYTE, 0, gTexCoordBuffer);
	glColorPointer(4, GL_UNSIGNED_BYTE, 0, gColorBuffer);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
#else
	glBegin (GL_TRIANGLES);
#endif

	VectorScale (vup, 1.5, up);
	VectorScale (vright, 1.5, right);
#else
	D_StartParticles ();

	VectorScale (vright, xscaleshrink, r_pright);
	VectorScale (vup, yscaleshrink, r_pup);
	VectorCopy (vpn, r_ppn);
#endif
	frametime = cl.time - cl.oldtime;
	time3 = frametime * 15;
	time2 = frametime * 10; // 15;
	time1 = frametime * 5;
	grav = frametime * sv_gravity.value * 0.05;
	dvel = 4*frametime;

	for ( ;; )
	{
		kill = active_particles;
		if (kill && kill->die < cl.time)
		{
			active_particles = kill->next;
			kill->next = free_particles;
			free_particles = kill;
			continue;
		}
		break;
	}

	for (p=active_particles ; p ; p=p->next)
	{
		for ( ;; )
		{
			kill = p->next;
			if (kill && kill->die < cl.time)
			{
				p->next = kill->next;
				kill->next = free_particles;
				free_particles = kill;
				continue;
			}
			break;
		}

#ifdef GLQUAKE
		// hack a scale up to keep particles from disapearing
		scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
			+ (p->org[2] - r_origin[2])*vpn[2];
		if (scale < 20)
			scale = 1;
		else
			scale = 1 + scale * 0.004;
#ifdef USE_OPENGLES

		if(particleIndex >= maxParticleIndex)
		{
			glDrawArrays(GL_TRIANGLES, 0, particleIndex);
			particleIndex = 0;
			pPos = gVertexBuffer;
			pColor = (unsigned char*) gColorBuffer;
			pUV = (unsigned char*) gTexCoordBuffer;
		}

		memcpy(pColor, (byte *)&d_8to24table[(int)p->color], 3);
		pColor[3] = 255;
		pColor += 4;
		*pUV++ = 0;
		*pUV++ = 0;
		*pPos++ = p->org[0];
		*pPos++ = p->org[1];
		*pPos++ = p->org[2];

		memcpy(pColor, (byte *)&d_8to24table[(int)p->color], 3);
		pColor[3] = 255;
		pColor += 4;
		*pUV++ = 1;
		*pUV++ = 0;
		*pPos++ = p->org[0] + up[0]*scale;
		*pPos++ = p->org[1] + up[1]*scale;
		*pPos++ = p->org[2] + up[2]*scale;

		memcpy(pColor, (byte *)&d_8to24table[(int)p->color], 3);
		pColor[3] = 255;
		pColor += 4;
		*pUV++ = 0;
		*pUV++ = 1;
		*pPos++ = p->org[0] + right[0]*scale;
		*pPos++ = p->org[1] + right[1]*scale;
		*pPos++ = p->org[2] + right[2]*scale;

		particleIndex += 3;

#else
		glColor3ubv ((byte *)&d_8to24table[(int)p->color]);
		glTexCoord2f (0,0);
		glVertex3fv (p->org);
		glTexCoord2f (1,0);
		glVertex3f (p->org[0] + up[0]*scale, p->org[1] + up[1]*scale, p->org[2] + up[2]*scale);
		glTexCoord2f (0,1);
		glVertex3f (p->org[0] + right[0]*scale, p->org[1] + right[1]*scale, p->org[2] + right[2]*scale);
#endif // !USE_OPENGLES
#else
		D_DrawParticle (p);
#endif
		p->org[0] += p->vel[0]*frametime;
		p->org[1] += p->vel[1]*frametime;
		p->org[2] += p->vel[2]*frametime;

		switch (p->type)
		{
		case pt_static:
			break;
		case pt_fire:
			p->ramp += time1;
			if (p->ramp >= 6)
				p->die = -1;
			else
				p->color = ramp3[(int)p->ramp];
			p->vel[2] += grav;
			break;

		case pt_explode:
			p->ramp += time2;
			if (p->ramp >=8)
				p->die = -1;
			else
				p->color = ramp1[(int)p->ramp];
			for (i=0 ; i<3 ; i++)
				p->vel[i] += p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_explode2:
			p->ramp += time3;
			if (p->ramp >=8)
				p->die = -1;
			else
				p->color = ramp2[(int)p->ramp];
			for (i=0 ; i<3 ; i++)
				p->vel[i] -= p->vel[i]*frametime;
			p->vel[2] -= grav;
			break;

		case pt_blob:
			for (i=0 ; i<3 ; i++)
				p->vel[i] += p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_blob2:
			for (i=0 ; i<2 ; i++)
				p->vel[i] -= p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_grav:
#ifdef QUAKE2
			p->vel[2] -= grav * 20;
			break;
#endif
		case pt_slowgrav:
			p->vel[2] -= grav;
			break;
	    default:
	        break;
		}
	}

#ifdef GLQUAKE
#ifdef USE_OPENGLES
	glDrawArrays(GL_TRIANGLES, 0, particleIndex);
	glDisableClientState(GL_COLOR_ARRAY);
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
#else
	glEnd ();
#endif
	glDisable (GL_BLEND);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
#else
	D_EndParticles ();
#endif
}
Example #7
0
	/* clamp color to 0-511: particle->type 10 and 11 (pt_c_explode
	 * and pt_c_explode2, e.g. Crusader's ice particles hitting a
	 * wall) lead to negative values, because R_UpdateParticles ()
	 * decrements their color against time. */
		color = ((int)p->color) & 0x01ff;
		if (color < 256)
			glColor3ubv_fp ((byte *)&d_8to24table[color]);
		else
			glColor4ubv_fp ((byte *)&d_8to24TranslucentTable[color-256]);

		// setup texture coordinates
		i = 0;
		if (p->type == pt_snow)
		{
			if (p->count >= 69)
				i = 3;	// happy snow!
			else if (p->count >= 40)
				i = 2;
			else if (p->count >= 30)
				i = 1;
		}

		glTexCoord2fv_fp (ptex_coord[i][0]);
		glVertex3fv_fp (p->org);
		glTexCoord2fv_fp (ptex_coord[i][1]);
		glVertex3f_fp (p->org[0] + r_pup[0]*scale, p->org[1] + r_pup[1]*scale, p->org[2] + r_pup[2]*scale);
		glTexCoord2fv_fp (ptex_coord[i][2]);
		glVertex3f_fp (p->org[0] + r_pright[0]*scale, p->org[1] + r_pright[1]*scale, p->org[2] + r_pright[2]*scale);
	}

	glEnd_fp ();
	glDisable_fp (GL_BLEND);
	glTexEnvf_fp(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
#else	/* !GLQUAKE */
void R_DrawParticles (void)
{
	particle_t	*p;
	int		i;
	float		vel0, vel1, vel2;
	vec3_t		save_org;

	D_StartParticles ();

	VectorScale (vright, xscaleshrink, r_pright);
	VectorScale (vup, yscaleshrink, r_pup);
	VectorCopy (vpn, r_ppn);

	for (p = active_particles ; p ; p = p->next)
	{
		switch (p->type)
		{
		case pt_snow:
			VectorCopy(p->org, save_org);
			D_DrawParticle (p);

			for (i = 1; i < p->count; i++)
			{
				switch (i)
				{
				// FIXME:  More translucency
				//	   on outside particles?

			//	case 0:
			//	// original
			//		break;
				case 1:
				// One to right
					p->org[0] = save_org[0] + vright[0];
					p->org[1] = save_org[1] + vright[1];
					p->org[2] = save_org[2] + vright[2];
					break;
				case 2:
				// One above
					p->org[0] = save_org[0] + vup[0];
					p->org[1] = save_org[1] + vup[1];
					p->org[2] = save_org[2] + vup[2];
					break;
				case 3:
				// One to left
					p->org[0] = save_org[0] - vright[0];
					p->org[1] = save_org[1] - vright[1];
					p->org[2] = save_org[2] - vright[2];
					break;
				case 4:
				// One below
					p->org[0] = save_org[0] - vup[0];
					p->org[1] = save_org[1] - vup[1];
					p->org[2] = save_org[2] - vup[2];
					break;
				default:
					Con_Printf ("count too big!\n");
					break;
				}
				D_DrawParticle (p);
			}
			VectorCopy(save_org, p->org);	// Restore origin
			break;

		case pt_rain:
			VectorCopy(p->org, save_org);

			vel0 = p->vel[0]*.001;
			vel1 = p->vel[1]*.001;
			vel2 = p->vel[2]*.001;

			for (i = 0; i < 4; i++)
			{
				D_DrawParticle(p);
				p->org[0] += vel0;
				p->org[1] += vel1;
				p->org[2] += vel2;
 			}
			D_DrawParticle(p);

			VectorCopy(save_org, p->org);	// Restore origin
			break;

		default:
			D_DrawParticle (p);
			break;
		}
	}

	D_EndParticles ();
}
Example #8
0
/*
===============
R_DrawParticles
===============
*/
void R_DrawParticles (void)
{
	particle_t		*p, *kill;
	float			grav;
	int				i;
	float			time2, time3;
	float			time1;
	float			dvel;
	float			frametime;
// >>> FIX: For Nintendo Wii using devkitPPC / libogc
// Support for GX hardware:
//#ifdef GLQUAKE
#ifdef GXQUAKE
	unsigned char	*at;
	unsigned char	theAlpha;
	vec3_t			up, right;
	float			scale;

    GX_Bind(particletexture);
	GX_SetBlendMode(GX_BM_BLEND, gxu_blend_src_value, gxu_blend_dst_value, GX_LO_NOOP); 
	GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);

	VectorScale (vup, 1.5, up);
	VectorScale (vright, 1.5, right);
#elif GLQUAKE
// <<< FIX
	unsigned char	*at;
	unsigned char	theAlpha;
	vec3_t			up, right;
	float			scale;
	qboolean		alphaTestEnabled;
    
	GL_Bind(particletexture);
	alphaTestEnabled = glIsEnabled(GL_ALPHA_TEST);
	
	if (alphaTestEnabled)
		glDisable(GL_ALPHA_TEST);
	glEnable (GL_BLEND);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	glBegin (GL_TRIANGLES);

	VectorScale (vup, 1.5, up);
	VectorScale (vright, 1.5, right);
#else
	D_StartParticles ();

	VectorScale (vright, xscaleshrink, r_pright);
	VectorScale (vup, yscaleshrink, r_pup);
	VectorCopy (vpn, r_ppn);
#endif

	frametime = host_frametime;
	time3 = frametime * 15;
	time2 = frametime * 10; // 15;
	time1 = frametime * 5;
	grav = frametime * 800 * 0.05;
	dvel = 4*frametime;
	
	for ( ;; ) 
	{
		kill = active_particles;
		if (kill && kill->die < cl.time)
		{
			active_particles = kill->next;
			kill->next = free_particles;
			free_particles = kill;
			continue;
		}
		break;
	}

	for (p=active_particles ; p ; p=p->next)
	{
		for ( ;; )
		{
			kill = p->next;
			if (kill && kill->die < cl.time)
			{
				p->next = kill->next;
				kill->next = free_particles;
				free_particles = kill;
				continue;
			}
			break;
		}

// >>> FIX: For Nintendo Wii using devkitPPC / libogc
// Support for GX hardware:
//#ifdef GLQUAKE
#ifdef GXQUAKE
		// hack a scale up to keep particles from disapearing
		scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
			+ (p->org[2] - r_origin[2])*vpn[2];
		if (scale < 20)
			scale = 1;
		else
			scale = 1 + scale * 0.004;
		at = (byte *)&d_8to24table[(int)p->color];
		if (p->type==pt_fire)
			theAlpha = 255*(6-p->ramp)/6;
//			theAlpha = 192;
//		else if (p->type==pt_explode || p->type==pt_explode2)
//			theAlpha = 255*(8-p->ramp)/8;
		else
			theAlpha = 255;
		gxu_cur_r = *at;
		gxu_cur_g = *(at+1);
		gxu_cur_b = *(at+2);
		gxu_cur_a = theAlpha;
//		glColor3ubv (at);
//		glColor3ubv ((byte *)&d_8to24table[(int)p->color]);
		GX_Begin (GX_TRIANGLES, gxu_cur_vertex_format, 3);
		GX_Position3f32(p->org[0], p->org[1], p->org[2]);
		GX_Color4u8(gxu_cur_r, gxu_cur_g, gxu_cur_b, gxu_cur_a);
		GX_TexCoord2f32 (0,0);
		GX_Position3f32(p->org[0] + up[0]*scale, p->org[1] + up[1]*scale, p->org[2] + up[2]*scale);
		GX_Color4u8(gxu_cur_r, gxu_cur_g, gxu_cur_b, gxu_cur_a);
		GX_TexCoord2f32 (1,0);
		GX_Position3f32(p->org[0] + right[0]*scale, p->org[1] + right[1]*scale, p->org[2] + right[2]*scale);
		GX_Color4u8(gxu_cur_r, gxu_cur_g, gxu_cur_b, gxu_cur_a);
		GX_TexCoord2f32 (0,1);
		GX_End();

#elif GLQUAKE
// <<< FIX
		// hack a scale up to keep particles from disapearing
		scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
			+ (p->org[2] - r_origin[2])*vpn[2];
		if (scale < 20)
			scale = 1;
		else
			scale = 1 + scale * 0.004;
		at = (byte *)&d_8to24table[(int)p->color];
		if (p->type==pt_fire)
			theAlpha = 255*(6-p->ramp)/6;
//			theAlpha = 192;
//		else if (p->type==pt_explode || p->type==pt_explode2)
//			theAlpha = 255*(8-p->ramp)/8;
		else
			theAlpha = 255;
		glColor4ub (*at, *(at+1), *(at+2), theAlpha);
//		glColor3ubv (at);
//		glColor3ubv ((byte *)&d_8to24table[(int)p->color]);
		glTexCoord2f (0,0);
		glVertex3fv (p->org);
		glTexCoord2f (1,0);
		glVertex3f (p->org[0] + up[0]*scale, p->org[1] + up[1]*scale, p->org[2] + up[2]*scale);
		glTexCoord2f (0,1);
		glVertex3f (p->org[0] + right[0]*scale, p->org[1] + right[1]*scale, p->org[2] + right[2]*scale);

#else
		D_DrawParticle (p);
#endif

		p->org[0] += p->vel[0]*frametime;
		p->org[1] += p->vel[1]*frametime;
		p->org[2] += p->vel[2]*frametime;
		
		switch (p->type)
		{
		case pt_static:
			break;
		case pt_fire:
			p->ramp += time1;
			if (p->ramp >= 6)
				p->die = -1;
			else
				p->color = ramp3[(int)p->ramp];
			p->vel[2] += grav;
			break;

		case pt_explode:
			p->ramp += time2;
			if (p->ramp >=8)
				p->die = -1;
			else
				p->color = ramp1[(int)p->ramp];
			for (i=0 ; i<3 ; i++)
				p->vel[i] += p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_explode2:
			p->ramp += time3;
			if (p->ramp >=8)
				p->die = -1;
			else
				p->color = ramp2[(int)p->ramp];
			for (i=0 ; i<3 ; i++)
				p->vel[i] -= p->vel[i]*frametime;
			p->vel[2] -= grav;
			break;

		case pt_blob:
			for (i=0 ; i<3 ; i++)
				p->vel[i] += p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_blob2:
			for (i=0 ; i<2 ; i++)
				p->vel[i] -= p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_slowgrav:
		case pt_grav:
			p->vel[2] -= grav;
			break;
		}
	}

// >>> FIX: For Nintendo Wii using devkitPPC / libogc
// Support for GX hardware:
//#ifdef GLQUAKE
#ifdef GXQUAKE
	GX_SetBlendMode(GX_BM_NONE, gxu_blend_src_value, gxu_blend_dst_value, GX_LO_NOOP); 
	GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE);
#elif GLQUAKE
// <<< FIX
	glEnd ();
	glDisable (GL_BLEND);
	if (alphaTestEnabled)
		glEnable(GL_ALPHA_TEST);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
#else
	D_EndParticles ();
#endif
}
Example #9
0
void R_DrawParticles (void)
{
	particle_t		*p, *kill;
	float			grav;
	int				i;
	float			time2, time3;
	float			time1;
	float			dvel;
	float			frametime;
	
#ifdef GLQUAKE
	vec3_t			up, right;
	float			scale;

    GL_Bind(particletexture);
	glEnable (GL_BLEND);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	//glEnable(GL_COLOR_MATERIAL);

	VectorScale (vup, 1.5, up);
	VectorScale (vright, 1.5, right);
#else
	D_StartParticles ();

	VectorScale (vright, xscaleshrink, r_pright);
	VectorScale (vup, yscaleshrink, r_pup);
	VectorCopy (vpn, r_ppn);
#endif
	frametime = cl.time - cl.oldtime;
	time3 = frametime * 15;
	time2 = frametime * 10; // 15;
	time1 = frametime * 5;
	grav = frametime * sv_gravity.value * 0.05;
	dvel = 4*frametime;
	
	for ( ;; ) 
	{
		kill = active_particles;
		if (kill && kill->die < cl.time)
		{
			active_particles = kill->next;
			kill->next = free_particles;
			free_particles = kill;
			continue;
		}
		break;
	}

	for (p=active_particles ; p ; p=p->next)
	{
		for ( ;; )
		{
			kill = p->next;
			if (kill && kill->die < cl.time)
			{
				p->next = kill->next;
				kill->next = free_particles;
				free_particles = kill;
				continue;
			}
			break;
		}

#ifdef GLQUAKE
		// hack a scale up to keep particles from disapearing
		scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
			+ (p->org[2] - r_origin[2])*vpn[2];
		if (scale < 20)
			scale = 1;
		else
			scale = 1 + scale * 0.004;
#ifdef ESQUAKE
		byte * colorEntry = (byte *)&d_8to24table[(int)p->color];
		GLubyte colors[4*3] = 
		{
			colorEntry[0], colorEntry[1], colorEntry[2], 255,
			colorEntry[0], colorEntry[1], colorEntry[2], 255,
			colorEntry[0], colorEntry[1], colorEntry[2], 255
		};
		GLfloat texCoords[2*3] = 
		{
			0, 0, 1, 0, 0, 1
		};
		GLfloat verts[3*3] =
		{
			p->org[0],                  p->org[1],                  p->org[2],
			p->org[0] + up[0]*scale,    p->org[1] + up[1]*scale,    p->org[2] + up[2]*scale,
			p->org[0] + right[0]*scale, p->org[1] + right[1]*scale, p->org[2] + right[2]*scale
		};
		glEnableClientState(GL_COLOR_ARRAY);
		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		glEnableClientState(GL_VERTEX_ARRAY);
		glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
		glTexCoordPointer(2, GL_FLOAT, sizeof(float)*2, texCoords);
		glVertexPointer(3, GL_FLOAT, sizeof(float)*3, verts);
		glDrawArrays(GL_TRIANGLES, 0, 3);
		glDisableClientState(GL_COLOR_ARRAY);
		glDisableClientState(GL_VERTEX_ARRAY);
		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#else
		glBegin (GL_TRIANGLES);
		glColor3ubv ((byte *)&d_8to24table[(int)p->color]);
		glTexCoord2f (0,0);
		glVertex3fv (p->org);
		glTexCoord2f (1,0);
		glVertex3f (p->org[0] + up[0]*scale, p->org[1] + up[1]*scale, p->org[2] + up[2]*scale);
		glTexCoord2f (0,1);
		glVertex3f (p->org[0] + right[0]*scale, p->org[1] + right[1]*scale, p->org[2] + right[2]*scale);
		glEnd ();
#endif
#else
		D_DrawParticle (p);
#endif
		p->org[0] += p->vel[0]*frametime;
		p->org[1] += p->vel[1]*frametime;
		p->org[2] += p->vel[2]*frametime;
		
		switch (p->type)
		{
		case pt_static:
			break;
		case pt_fire:
			p->ramp += time1;
			if (p->ramp >= 6)
				p->die = -1;
			else
				p->color = ramp3[(int)p->ramp];
			p->vel[2] += grav;
			break;

		case pt_explode:
			p->ramp += time2;
			if (p->ramp >=8)
				p->die = -1;
			else
				p->color = ramp1[(int)p->ramp];
			for (i=0 ; i<3 ; i++)
				p->vel[i] += p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_explode2:
			p->ramp += time3;
			if (p->ramp >=8)
				p->die = -1;
			else
				p->color = ramp2[(int)p->ramp];
			for (i=0 ; i<3 ; i++)
				p->vel[i] -= p->vel[i]*frametime;
			p->vel[2] -= grav;
			break;

		case pt_blob:
			for (i=0 ; i<3 ; i++)
				p->vel[i] += p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_blob2:
			for (i=0 ; i<2 ; i++)
				p->vel[i] -= p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_grav:
#ifdef QUAKE2
			p->vel[2] -= grav * 20;
			break;
#endif
		case pt_slowgrav:
			p->vel[2] -= grav;
			break;
		}
	}

#ifdef GLQUAKE
	glDisable (GL_BLEND);
	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
	//glDisable(GL_COLOR_MATERIAL);
#else
	D_EndParticles ();
#endif
}
Example #10
0
/*
===============
R_DrawParticles
===============
*/
void
R_DrawParticles(void)
{
    particle_t *p;

#ifdef GLQUAKE
#ifdef QW_HACK
    unsigned char *at;
    unsigned char theAlpha;
#endif
    qboolean alphaTestEnabled;
    vec3_t up, right;
    float scale;

#ifdef NQ_HACK
    /*
     * FIXME - shouldn't need to do this, just get the caller to make sure
     *         multitexture is not enabled.
     */
    GL_DisableMultitexture();
#endif
    GL_Bind(particletexture);

    alphaTestEnabled = glIsEnabled(GL_ALPHA_TEST);
    if (alphaTestEnabled)
	glDisable(GL_ALPHA_TEST);

    glEnable(GL_BLEND);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glDepthMask(GL_FALSE);

    glBegin(GL_TRIANGLES);

    VectorScale(vup, 1.5, up);
    VectorScale(vright, 1.5, right);
#else
    D_StartParticles();

    VectorScale(vright, xscaleshrink, r_pright);
    VectorScale(vup, yscaleshrink, r_pup);
    VectorCopy(vpn, r_ppn);
#endif

    for (p = active_particles; p; p = p->next) {

#ifdef GLQUAKE
	// hack a scale up to keep particles from disapearing
	scale =
	    (p->org[0] - r_origin[0]) * vpn[0] + (p->org[1] -
						  r_origin[1]) * vpn[1]
	    + (p->org[2] - r_origin[2]) * vpn[2];
	if (scale < 20)
	    scale = 1;
	else
	    scale = 1 + scale * 0.004;
#ifdef QW_HACK
	at = (byte *)&d_8to24table[(int)p->color];
	if (p->type == pt_fire)
	    theAlpha = 255 * (6 - p->ramp) / 6;
	else
	    theAlpha = 255;
	glColor4ub(*at, *(at + 1), *(at + 2), theAlpha);
#endif
#ifdef NQ_HACK
	glColor3ubv((byte *)&d_8to24table[(int)p->color]);
#endif
	glTexCoord2f(0, 0);
	glVertex3fv(p->org);
	glTexCoord2f(1, 0);
	glVertex3f(p->org[0] + up[0] * scale, p->org[1] + up[1] * scale,
		   p->org[2] + up[2] * scale);
	glTexCoord2f(0, 1);
	glVertex3f(p->org[0] + right[0] * scale,
		   p->org[1] + right[1] * scale,
		   p->org[2] + right[2] * scale);
#else
	D_DrawParticle(p);
#endif
    }

#ifdef GLQUAKE
    glEnd();
    glDepthMask(GL_TRUE);
    glDisable(GL_BLEND);
    if (alphaTestEnabled)
	glEnable(GL_ALPHA_TEST);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
#else
    D_EndParticles();
#endif
}
Example #11
0
void R_DrawParticles (void)
{
	particle_t		*p, *kill;
	float			grav;
	int				i;
	float			time2, time3;
	float			time1;
	float			dvel;
	float			frametime;
	
#ifdef GLQUAKE
	vec3_t			up, right;
	float			scale;

    GL_Use (gl_coloredpolygon1textureprogram);
    
    glUniformMatrix4fv(gl_coloredpolygon1textureprogram_transform, 1, 0, gl_polygon_matrix);

    GL_Bind(particletexture);
	glEnable (GL_BLEND);

	VectorScale (vup, 1.5, up);
	VectorScale (vright, 1.5, right);
#else
	D_StartParticles ();

	VectorScale (vright, xscaleshrink, r_pright);
	VectorScale (vup, yscaleshrink, r_pup);
	VectorCopy (vpn, r_ppn);
#endif
	frametime = cl.time - cl.oldtime;
	time3 = frametime * 15;
	time2 = frametime * 10; // 15;
	time1 = frametime * 5;
	grav = frametime * sv_gravity.value * 0.05;
	dvel = 4*frametime;
	
	for ( ;; ) 
	{
		kill = active_particles;
		if (kill && kill->die < cl.time)
		{
			active_particles = kill->next;
			kill->next = free_particles;
			free_particles = kill;
			continue;
		}
		break;
	}

#ifdef GLQUAKE
    int mark = Hunk_LowMark();
    
    int vertexcount = 0;

    for (p=active_particles ; p ; p=p->next)
    {
        vertexcount += 3;
    }
    
    if (vertexcount == 0) return;
    
    GLfloat* vertices = Hunk_AllocName (vertexcount * 9 * sizeof(GLfloat), "vertex_buffer");
    
    int vertexpos = 0;
#endif
    
	for (p=active_particles ; p ; p=p->next)
	{
		for ( ;; )
		{
			kill = p->next;
			if (kill && kill->die < cl.time)
			{
				p->next = kill->next;
				kill->next = free_particles;
				free_particles = kill;
				continue;
			}
			break;
		}

#ifdef GLQUAKE
		// hack a scale up to keep particles from disapearing
		scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1]
			+ (p->org[2] - r_origin[2])*vpn[2];
		if (scale < 20)
			scale = 1;
		else
			scale = 1 + scale * 0.004;

        unsigned c = d_8to24table[(int)p->color];
        
        GLfloat r = (GLfloat)(c & 0xFF) / 255.0;
        GLfloat g = (GLfloat)((c >> 8) & 0xFF) / 255.0;
        GLfloat b = (GLfloat)((c >> 16) & 0xFF) / 255.0;
        GLfloat a = (GLfloat)((c >> 24) & 0xFF) / 255.0;
        
        vertices[vertexpos++] = p->org[0];
        vertices[vertexpos++] = p->org[1];
        vertices[vertexpos++] = p->org[2];
        vertices[vertexpos++] = r;
        vertices[vertexpos++] = g;
        vertices[vertexpos++] = b;
        vertices[vertexpos++] = a;
        vertices[vertexpos++] = 0.0;
        vertices[vertexpos++] = 0.0;
        
        vertices[vertexpos++] = p->org[0] + up[0] * scale;
        vertices[vertexpos++] = p->org[1] + up[1] * scale;
        vertices[vertexpos++] = p->org[2] + up[2] * scale;
        vertices[vertexpos++] = r;
        vertices[vertexpos++] = g;
        vertices[vertexpos++] = b;
        vertices[vertexpos++] = a;
        vertices[vertexpos++] = 1.0;
        vertices[vertexpos++] = 0.0;
        
        vertices[vertexpos++] = p->org[0] + right[0] * scale;
        vertices[vertexpos++] = p->org[1] + right[1] * scale;
        vertices[vertexpos++] = p->org[2] + right[2] * scale;
        vertices[vertexpos++] = r;
        vertices[vertexpos++] = g;
        vertices[vertexpos++] = b;
        vertices[vertexpos++] = a;
        vertices[vertexpos++] = 0.0;
        vertices[vertexpos++] = 1.0;
#else
		D_DrawParticle (p);
#endif
		p->org[0] += p->vel[0]*frametime;
		p->org[1] += p->vel[1]*frametime;
		p->org[2] += p->vel[2]*frametime;
		
		switch (p->type)
		{
		case pt_static:
			break;
		case pt_fire:
			p->ramp += time1;
			if (p->ramp >= 6)
				p->die = -1;
			else
				p->color = ramp3[(int)p->ramp];
			p->vel[2] += grav;
			break;

		case pt_explode:
			p->ramp += time2;
			if (p->ramp >=8)
				p->die = -1;
			else
				p->color = ramp1[(int)p->ramp];
			for (i=0 ; i<3 ; i++)
				p->vel[i] += p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_explode2:
			p->ramp += time3;
			if (p->ramp >=8)
				p->die = -1;
			else
				p->color = ramp2[(int)p->ramp];
			for (i=0 ; i<3 ; i++)
				p->vel[i] -= p->vel[i]*frametime;
			p->vel[2] -= grav;
			break;

		case pt_blob:
			for (i=0 ; i<3 ; i++)
				p->vel[i] += p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_blob2:
			for (i=0 ; i<2 ; i++)
				p->vel[i] -= p->vel[i]*dvel;
			p->vel[2] -= grav;
			break;

		case pt_grav:
#ifdef QUAKE2
			p->vel[2] -= grav * 20;
			break;
#endif
		case pt_slowgrav:
			p->vel[2] -= grav;
			break;
		}
	}

#ifdef GLQUAKE
    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, vertexcount * 9 * sizeof(GLfloat), vertices, GL_STATIC_DRAW);
    
    glEnableVertexAttribArray(gl_coloredpolygon1textureprogram_position);
    glVertexAttribPointer(gl_coloredpolygon1textureprogram_position, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), (const GLvoid *)0);
    glEnableVertexAttribArray(gl_coloredpolygon1textureprogram_color);
    glVertexAttribPointer(gl_coloredpolygon1textureprogram_color, 4, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), (const GLvoid *)(3 * sizeof(GLfloat)));
    glEnableVertexAttribArray(gl_coloredpolygon1textureprogram_texcoords);
    glVertexAttribPointer(gl_coloredpolygon1textureprogram_texcoords, 2, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), (const GLvoid *)(7 * sizeof(GLfloat)));
    
    glDrawArrays(GL_TRIANGLES, 0, vertexcount);
    
    glDisableVertexAttribArray(gl_coloredpolygon1textureprogram_texcoords);
    glDisableVertexAttribArray(gl_coloredpolygon1textureprogram_color);
    glDisableVertexAttribArray(gl_coloredpolygon1textureprogram_position);
    
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    
    glDeleteBuffers(1, &vertexbuffer);

    Hunk_FreeToLowMark (mark);
    
	glDisable (GL_BLEND);
#else
	D_EndParticles ();
#endif
}