Search code examples
opengltransparencytexture2d

vbo with 2D texture - real-time transparency issue


I am working on a n-body code which models the dynamics of a stellar disk. In the rendering, there are two types of particles : "classic" particles ( whites in the below image) and "dark matter" particles (in blue).

Here's this image at the start of simulation :

enter image description here

Everything seems to be ok with transparency but if I zoom during the run, I notice that actually, some particles keeps the same intermediate color, i.e there are purple.

Here's an example on this image ( which is the stellar disk seen from the side) :

enter image description here

My main problem is so that I don't understand why the color doesn't change as a function of others particles which are behind. For example, I would like a white/blue particle to be partially shaded by the others blue/white particles, and in real-time.

I show you my drawPoints() function where I use transparency :

void drawPoints()
{
    glEnable(GL_POINT_SPRITE);
    glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
    glEnable(GL_VERTEX_PROGRAM_POINT_SIZE_NV);

    glEnable(GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    //glEnable( GL_DEPTH_TEST );

    glUseProgram(m_program);
    glUniform1f( glGetUniformLocation(m_program, "pointRadius"), m_particleRadius );
    glUniform1f( glGetUniformLocation(m_program, "pointScale"), m_pointScale );

    GLuint vbo_disk;

        glBindBuffer(GL_ARRAY_BUFFER, vbo_disk);
        glVertexPointer(4, GL_DOUBLE, 4*sizeof(double), pos);
        glEnableClientState(GL_VERTEX_ARRAY);

        glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
        glDrawArrays(GL_POINTS, 0, numBodies_disk);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glDisableClientState(GL_VERTEX_ARRAY);

    GLuint vbo_halo;

        glBindBuffer(GL_ARRAY_BUFFER, vbo_halo);
        glVertexPointer(4, GL_DOUBLE, 4*sizeof(double), &pos[numBodies_disk]);
        glEnableClientState(GL_VERTEX_ARRAY);

        glColor4f(0.0f, 0.0f, 1.0f, 0.5f);
        glDrawArrays(GL_POINTS, 0, numBodies_halo);

        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glDisableClientState(GL_VERTEX_ARRAY); 

        glDisable(GL_BLEND);        
    glDisable(GL_POINT_SPRITE);
}

I tried to use glEnable( GL_DEPTH_TEST ) but it draws 2D texture with black background squares.

Could you give me some clues to have this cumulated and partial transparency in real-time ?


Solution

  • Make sure you disable depth testing:

    glDisable( GL_DEPTH_TEST );
    

    Then, you may want to try different blending modes such as additive blending:

    glBlendFunc( GL_SRC_ALPHA, GL_ONE );
    

    While additive blending is really pretty, it may produce too much white which could defeat the purpose of this visualization. You may try lowering alpha values in glColor4f. Another solution would be to use blue and red particles to accentuate the difference.