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); }
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 }