Question

I have a simple particle effect in OpenGL using GL_POINTS. The following is called, being passed particles in order from the particle furthest from the camera first to the one nearest the camera last:

void draw_particle(particle* part) {
    /* The following is how the distance is calculated when ordering.
     * GLfloat distance = sqrt(pow(get_camera_pos_x() - part->pos_x, 2) + pow(get_camera_pos_y() - part->pos_y, 2) + pow(get_camera_pos_z() - part->pos_z, 2));
     */

    static GLfloat quadratic[] = {0.005, 0.01, 1/600.0};
    glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic);
    glPointSize(part->size);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_POINT_SPRITE_ARB);
    glEnable(GL_TEXTURE_2D);

    glBegin(GL_POINTS);
        glColor4f(part->r, part->g, part->b, part->a);
        glVertex3f(part->pos_x, part->pos_y, part->pos_z);
    glEnd();

    glDisable(GL_BLEND);
    glDisable(GL_POINT_SPRITE_ARB);
}

However, there is some artifacting when rendering as can be seen in the following effect:artifacted image http://img199.imageshack.us/img199/9574/particleeffect.png

The problems go away if I disable depth testing, but I need the effects to be able to interact with other elements of the scene, appearing in front of and behind elements of the same GL_TRIANGLE_STRIP depending on depth.

Was it helpful?

Solution

If your particules are already sorted you can render like this :

  • Render particule with GL WRITE DEPTH but no depth testing (I don't remember exactly the constants)
  • Render the rest of the scene with depth test.

This way you are sure to get scene interaction with nice-looking particules.

OTHER TIPS

Note: Please specify which OpenGL version you use when you post questions. That goes for any API. When you want to render primitives with alpha blending, you can't have depth writes enabled. You need to draw your blended primitives sorted back-to-front. If you have opaque objects in the scene, render them first, and then draw your transparent primitives in a back-to-front sorted fashion with depth test enabled and depth writes disabled.

glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_POINT_SPRITE);
glEnable(GL_CULL_FACE);

while(1)
{
    ...
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDisable(GL_BLEND);
    glDepthMask(1);
    RenderOpaque();
    SortSprites();
    glEnable(GL_BLEND);
    glDepthMask(0);
    DrawSprites();
    ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top