#

Some comments on OpenGL rendering of particles

When rendering particles in OpenGL there are many possible ways to represent them. The following goes through some of the possibilities with associated pseudo-code.

At the very basic level it is possible to simply render the particles as points:

glPointSize( 3.f );
glColor4f (1.0f,1.0f,1.0f,1.0f);
glBegin(GL_POINTS);
for(i=0; i<npoints; i+=nskip)
{
glVertex3f(x[i], y[i], z[i]);
}
// Done drawing points
glEnd();

This produces a plot below:

In the next level, it is possible to replace the points with "point sprites". It is also possible to scale the points according to their distance from the camera.

glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, sizes);
glEnable( GL_POINT_SPRITE_ARB );
glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, sizes[1] );
glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, sizes[0]);
glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic );
glTexEnvi( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
glColor4f (1.0f,1.0f,1.0f,1.0f);
glBegin(GL_POINTS);
for(i=0; i<npoints; i+=nskip)
{
glVertex3f(x[i], y[i], z[i]);
}
// Done drawing points
glEnd();
glDisable( GL_POINT_SPRITE_ARB );

This produces a plot below:

The next stage is to put a texture on the point sprites. We will use the image:

glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, sizes);
glEnable( GL_POINT_SPRITE_ARB );
glPointParameterfARB( GL_POINT_SIZE_MAX_ARB, sizes[1] );
glPointParameterfARB( GL_POINT_SIZE_MIN_ARB, sizes[0]);
glPointParameterfvARB( GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic );
glTexEnvi( GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE );
image = new Bitmap();
if (image->loadBMP("particle.bmp") == false)
{
return;
}
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &g_textureID);
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D(GL_TEXTURE_2D, 0, 3, image->width, image->height, 0,
GL_RGB, GL_UNSIGNED_BYTE, image->data);
glEnable( GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_CONSTANT_COLOR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glDepthMask(GL_FALSE);
glColor4f (1.0f,1.0f,1.0f,1.0f);
glBegin(GL_POINTS);
for(i=0; i<npoints; i+=nskip)
{
glBindTexture(GL_TEXTURE_2D, g_textureID);
glVertex3f(x[i], y[i], z[i]);
}
// Done drawing points
glEnd();
glDisable( GL_POINT_SPRITE_ARB );

This produces a plot below:

In the next two stages we show the effect of adding transparency and color as functions of physical quantities (viz. density and internal energy of the gas). This can be done by putting in the line:

glColor4f (c.r,c.g,c.b,opacity);

In the above opacity can be calculated as:

float opacity=log10(density);
opacity-=mindens;
opacity/=maxdens-mindens;

This produces a plot below:

Color can be calculated from the internal energy of the gas particles using some prescription like:

if (v < (vmin + 0.25 * dv))
{
c.g = 4 * (v - vmin) / dv;
}
else if (v < (vmin + 0.5 * dv))
{
c.r = 0;
c.b = 1 + 4 * (vmin + 0.25 * dv - v) / dv;
}
else if (v < (vmin + 0.75 * dv))
{
c.r = 4 * (v - vmin - 0.5 * dv) / dv;
c.b = 0;
}
else
{
c.g = 1 + 4 * (vmin + 0.75 * dv - v) / dv;
c.b = 0;
}

This produces a plot below:

CC BY-NC 4.0 This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License. Permissions beyond the scope of this license may be available at Attribution.