Solution Explorer

main.cpp

programs.cpp

code.cpp

resume.cpp

aboutMe.cpp

struct Particle_Code {

Welcome to my Particle Code page. Here you can see a few snippets of code that I wrote for my particle system, and the UI interface I made for the particle editor.

My Particle system uses OpenGL to draw point sprite images with 3D coordinates. However setting up OpenGL to correctly render the point sprites the way I wanted was a harder task then I had initially thought. The problem comes with the fact that OpenGL needs to know how to scale the images as the camera zooms in and out. To do this, I had to specify an attenuation function for OpenGL to use when rendering the sprites. This function is applied to all the points before drawing them, using the model-view matrix. See Particle_Code_1.

I also had to create a particle editor, because there were just too many variables for me to tweak and rebuilding every time can be tedious. You can learn more about the editor at its project page. I made a few UI elements that I call simple UI, because they just use OpenGL draw functions to represent a UI interface. The sliders simply take a reference to a variable and then change it, nothing too special. The Buttons and Radio Boxes however had to use function pointers. Particles_Code_2 shows off the implementation for the Radio Boxes. Notice how they are grouped together so that only one can be active at a time.

Particle_Code_1: Draw code for particle emitters


void BaseParticleEmitter::draw()
{
    glPushAttrib(GL_ALL_ATTRIB_BITS);
    // Enable the texture rectangle extension
    glEnable( GL_TEXTURE_2D );
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);

    if(qeTexBind(textureHandle)<0)
        qePrintf("failed to bind handle: %s", textureHandle);

    //qePrintf("%d\n",particles.numOfNodes);

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

    /*  Attenuation:
     *       1
     *  ----------
     *  a+b*d+c*d^2
     *  (a, b, c) = attenuation variables
     *  d = distance from point to eye
     */

    float quadratic[] =  { 1.0f, 0.0f, 0.01f };
    glPointParameterfv( GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic );

    // Specify point sprite texture coordinate replacement mode for each 
    // texture unit
    glTexEnvf( GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE );

    glEnable(GL_POINT_SPRITE);
    glDepthMask(GL_FALSE);
    {
        particles.goToBegin();
        while(particles.getCurrentElement() != NULL)
        {   
            Particle* p = particles.getCurrentElement();
            glPointSize(p->m_size);
            p->draw();
            particles.goToNext();
        }
    }
    glDisable(GL_POINT_SPRITE);
    glDisable(GL_BLEND);
    glDisable(GL_TEXTURE_2D);
    glDepthMask(GL_TRUE);
    glPopAttrib();
}
   

Particle_Code_2: Full implementation for a simple radio box. Only functions that return void and take no parameters can be passed into it.

///////////////////////////////////////////////////////////////////////////////
// SIMPLE RADIO BOX

SimpleRadioBox::SimpleRadioBox(Point pos, float radius)
: BaseSimpleUI(pos), m_radius(radius), active(false), funcPtr_action(NULL), group(NULL)
{ }

void SimpleRadioBox::setFuncPointer(void (*fncPointer)(void))
{ funcPtr_action = fncPointer; }


void SimpleRadioBox::update(int mouseX, int mouseY)
{
    //is mouse button clicked
    lb, pre_lb = 0;
    pre_lb = lb;
    lb = qeInpButton(QEINPBUTTON_MOUSELB);
    if( !(pre_lb&1) && lb&1 )
    {
        if(mouseX > m_pos[X]-(m_radius/2) && mouseX < m_pos[X]+(m_radius/2) &&

            mouseY < m_pos[Y]+(m_radius/2) && mouseY > m_pos[Y]-(m_radius/2))
        {
            active = !active;
            if(group != NULL)
                deactivateOthers();
        }
    }
    if(active)
    {
        if(funcPtr_action != NULL)
            (*funcPtr_action)();
    }
}


void SimpleRadioBox::draw()
{
    //change the camera
    qefnSysCam2D();

    //save off the states
    glPushMatrix();
    glPushAttrib(GL_ALL_ATTRIB_BITS);

    glLoadIdentity();
    
    glColor3f(1.0,0.0,0.0);
    int drawMode = active ? GL_FILL : GL_LINE;
    glPolygonMode(GL_FRONT, drawMode);
    drawSquare(
        (m_pos[X]-(m_radius/2))/SCREEN_WIDTH,
        1-(m_pos[Y]-(m_radius/2))/SCREEN_HEIGHT,
        (m_pos[X]+(m_radius/2))/SCREEN_WIDTH,
        1-(m_pos[Y]+(m_radius/2))/SCREEN_HEIGHT);
    glPopMatrix();
    glPopAttrib();
}


void SimpleRadioBox::deactivateOthers()
{
    for(int i=0; i<group->m_numMembers; i++)
    {
        if((group->members[i]) != this)
            (group->members[i])->active = false;
    }
}


void SimpleRadioBox::setAsActive()
{
    active = true;

    if(group != NULL)
        deactivateOthers();
}
      

}//end Particle_Code