Exemplo n.º 1
0
void Display::DrawBillboards()
{
    BillboardDisplayListRecord* temp = NULL;

    glDepthMask(GL_FALSE);

    bool lightingEnable = (glIsEnabled(GL_LIGHTING) == GL_TRUE);
    glDisable(GL_LIGHTING);

    if (!BillboardDisplayList.empty())
        BillboardDisplayList.sort(BubbleSortDistance);

    for (std::list<BillboardDisplayListRecord*>::iterator itr = BillboardDisplayList.begin(); itr != BillboardDisplayList.end();)
    {
        temp = (*itr);

        if (!temp)
        {
            itr = BillboardDisplayList.erase(itr);
            continue;
        }

        if (temp->remove)
        {
            if (temp->displayList)
                glDeleteLists(temp->displayList, temp->displayListSize);
            if (temp->AnimTicket)
                sAnimator->DestroyAnimTicket(temp->AnimTicket);
            if (temp)
                delete temp;
            itr = BillboardDisplayList.erase(itr);
            continue;
        }

        // Zabezpeceni proti vykreslovani billboardu, ktere jsou od nas vzdalene vice jak 14 jednotek
        // - Zvysuje vykon
        if (pythagoras_c(fabs(temp->x-fabs(m_targetX)), fabs(temp->z-fabs(m_targetZ))) > 14.0f)
        {
            ++itr;
            continue;
        }

        glLoadIdentity();
        glColor3ub(255, 255, 255);

        AdjustViewToTarget();

        if (temp->AnimTicket)
            BindTexture(sAnimator->GetActualTexture(temp->AnimTicket));
        else
            BindTexture(temp->textureId);

        // Pruhledne objekty potrebuji mit zapnuty mod pro blending a mod one minus src alpha pro
        // spravne vykresleni pruhlednosti
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        // Nechat depth test pro ted zapnuty, zpusobuje nepruhlednost
        // vykreslenych spritu vuci jinym spritum
        //glDisable(GL_DEPTH_TEST);

        // TODO: blending zvlast kanalu
        //       asi useless
        //glColor4f(1,1,1,0.85);

        glTranslatef(temp->x, temp->y, temp->z);
        if (temp->billboard_y)
            glRotatef(90.0f-m_angleY,  0.0f, 1.0f, 0.0f);
        if (temp->billboard_x)
            glRotatef(m_angleX, 0.0f, 0.0f, -1.0f);

        if (temp->displayList > 0)
        {
            glCallList(temp->displayList);
        }
        else
        {
            glBegin(GL_TRIANGLE_STRIP);
                glTexCoord2f(1.0f, 1.0f); glVertex3f(0, 0             , (-temp->scale_x/2));
                glTexCoord2f(0.0f, 1.0f); glVertex3f(0, 0             , ( temp->scale_x/2));
                glTexCoord2f(1.0f, 0.0f); glVertex3f(0, temp->scale_y , (-temp->scale_x/2));
                glTexCoord2f(0.0f, 0.0f); glVertex3f(0, temp->scale_y , ( temp->scale_x/2));
            glEnd();
        }

        // Nezapomeneme vypnout blending, jen jako slusnacci
        glDisable(GL_BLEND);

        // Netreba, viz. komentar vyse
        //glEnable(GL_DEPTH_TEST);

        ++itr;
    }
    glDepthMask(GL_TRUE);

    if (lightingEnable)
        glEnable(GL_LIGHTING);

    glLoadIdentity();

    glRotatef(m_angleX, 1.0f,  0.0f, 0.0f);
    glRotatef(m_angleY, 0.0f, -1.0f, 0.0f);
    glTranslatef(m_viewX, m_viewY, m_viewZ);
}
Exemplo n.º 2
0
bool ParticleEmitter::Update(const clock_t diff)
{
    //Nejdrive pricist k celkovemu casu ten ubehly (milisekundy)
    totaltime += diff;

    //Pak porovnat celkovy cas, zdali uz ubehnul maximalni cas
    if(totaltime >= time)
        return false; //--> odstranit emitter z listu pro update
    //TODO: dodelat "dojizdeni" emitteru - cas po ktery uz nebudou vydavany castice, ale
    //stare castice se budou stale pohybovat, az zmizi. Po tu dobu vracet stale true!

    uint32 newparticlescount = 10;

    //Zde update vsech castic a emit novych
    while(newparticlescount > 0)
    {
        if (Particles.size() < velocity-1)
        {
            if (nextParticleCountdown < diff)
            {
                //vytvorit novou castici
                Particle* pNew = new Particle;
                //a priradit ji veskere hodnoty

                //velice neuniverzalni a ne prilis profesionalni postup zde
                pNew->sx = x;
                pNew->sz = z;
                if (dirangleh < PI/4 || dirangleh > 7*PI/4 || (dirangleh > 3*PI/4 && dirangleh < 5*PI/4) )
                    pNew->sz = z+frand(square1,square3);
                else
                    pNew->sx = x+frand(square1,square3);
                pNew->sy = y+frand(square2,square4);
                //az sem

                pNew->modelId = modelId;
                pNew->actTime = 0;
                pNew->destrange = frand(minrange,maxrange);
                pNew->hangle = frand(dirangleh-angleh/2,dirangleh+angleh/2);
                pNew->vangle = frand(diranglev-anglev/2,diranglev+anglev/2);
                pNew->modelSize = modelSize+frand(min(0,sizevar),max(0,sizevar));
                float rotate = 0.0f;
                if (flags & EMIT_FLAG_RANDOM_ROTATE)
                    rotate = frand(0,PI);

                //pridat ji do display listu a ulozit pointer
                pNew->pRec = gDisplay.DrawModel(x,y,z,modelId, ANIM_IDLE,false,pNew->modelSize,rotate);

                Particles.push_back(pNew);
                nextParticleCountdown = density;
            } else nextParticleCountdown -= diff;
        }
        --newparticlescount;
    }

    Particle* temp;
    // Projit particles a rozpohybovat je
    for (std::list<Particle*>::iterator itr = Particles.begin(); itr != Particles.end(); ++itr)
    {
        temp = *itr;

        //pricist cas ktery ubehl [ms]
        temp->actTime += diff;

        if (!temp->pRec)
            continue;

        //speed [pocet tisicin rozmeru za 1 sekundu]
        temp->pRec->x = temp->sx+(float(temp->actTime)/1000)*(float(speed)/1000)*cos(temp->hangle);
        temp->pRec->y = temp->sy+(float(temp->actTime)/1000)*(float(speed)/1000)*sin(temp->vangle);
        temp->pRec->z = temp->sz+(float(temp->actTime)/1000)*(float(speed)/1000)*sin(temp->hangle);

        //pokud castice urazila drahu jakou ma urazit, vymazeme ji
        if (pythagoras_c(pythagoras_c(temp->pRec->x-temp->sx,temp->pRec->z-temp->sz),temp->pRec->y-temp->sy) > temp->destrange)
        {
            temp->pRec->remove = true;
            itr = Particles.erase(itr);
            if (itr == Particles.end())
                break;
            if (itr != Particles.begin())
                --itr;
            continue;
        }
    }

    return true; //false pokud emitter dosahne maximalniho casu pusobeni nebo je jinak odstranen
}