void ETHScene::Update( const unsigned long lastFrameElapsedTime, const ETHBackBufferTargetManagerPtr& backBuffer, asIScriptFunction* onUpdateCallbackFunction) { m_destructorManager->RunDestructors(); m_physicsSimulator.Update(lastFrameElapsedTime); // update entities that are always active (dynamic entities with callback or physics and temporary entities) m_activeEntityHandler.UpdateAlwaysActiveEntities(GetZAxisDirection(), m_buckets, lastFrameElapsedTime); // Run onSceneUpdate functon if (onUpdateCallbackFunction) ETHGlobal::ExecuteContext(m_pContext, onUpdateCallbackFunction); // start mapping process float minHeight, maxHeight; assert(m_renderingManager.IsEmpty()); // fill a map containing all entities we should render MapEntitiesToBeRendered( minHeight, maxHeight, backBuffer); // update static mapped entities that weren't called in UpdateAlwaysActiveEntities m_activeEntityHandler.UpdateCurrentFrameEntities(GetZAxisDirection(), m_buckets, lastFrameElapsedTime); m_minSceneHeight = minHeight; m_maxSceneHeight = maxHeight; Randomizer::Seed(m_provider->GetVideo()->GetElapsedTime()); }
bool ETHScene::RenderTransparentLayer(std::list<ETHRenderEntity*> &halos, const float maxHeight, const float minHeight) { GS2D_UNUSED_ARGUMENT(minHeight); GS2D_UNUSED_ARGUMENT(maxHeight); // Draw halos for (std::list<ETHRenderEntity*>::iterator iter = halos.begin(); iter != halos.end(); iter++) { if (m_provider->GetShaderManager()->BeginHaloPass(((*iter)->GetLight()), m_maxSceneHeight)) { (*iter)->DrawHalo(m_maxSceneHeight, m_minSceneHeight, GetHaloRotation(), GetZAxisDirection()); m_provider->GetShaderManager()->EndHaloPass(); } } return true; }
bool ETHScene::RenderScene(const bool roundUp, SpritePtr pOutline, SpritePtr pInvisibleEntSymbol) { m_provider->GetShaderManager()->SetParallaxIntensity(m_sceneProps.parallaxIntensity); float minHeight, maxHeight; m_provider->GetVideo()->SetBlendMode(1, GSBM_ADD); m_tempEntities.CheckTemporaryEntities(GetZAxisDirection(), m_buckets); m_provider->GetVideo()->SetZWrite(true); m_provider->GetVideo()->SetZBuffer(true); // temporary lists that will tell what to render and what to do std::list<ETHRenderEntity*> particles; std::list<ETHRenderEntity*> halos; // draw ambient pass m_provider->GetVideo()->RoundUpPosition(roundUp); RenderList(minHeight, maxHeight, pOutline, pInvisibleEntSymbol, particles, halos, roundUp); m_provider->GetVideo()->RoundUpPosition(false); // draw lights! m_provider->GetVideo()->SetZWrite(false); //RenderLightList(roundUp); m_provider->GetVideo()->SetZWrite(true); RenderParticleList(particles); m_lights.clear(); RenderTransparentLayer(halos, maxHeight, minHeight); m_provider->GetVideo()->SetZWrite(false); m_provider->GetVideo()->SetZBuffer(false); m_minSceneHeight = minHeight; m_maxSceneHeight = maxHeight; return true; }
void ETHScene::Update( const unsigned long lastFrameElapsedTime, const ETHBackBufferTargetManagerPtr& backBuffer) { m_destructorManager->RunDestructors(); m_physicsSimulator.Update(lastFrameElapsedTime); float minHeight, maxHeight; assert(m_renderingManager.IsEmpty()); // fill a map containing all entities we should render MapEntitiesToBeRendered( minHeight, maxHeight, backBuffer); m_activeEntityHandler.UpdateActiveEntities(GetZAxisDirection(), m_buckets, lastFrameElapsedTime); m_minSceneHeight = minHeight; m_maxSceneHeight = maxHeight; Randomizer::Seed(m_provider->GetVideo()->GetElapsedTime()); }
bool ETHScene::RenderParticleList(std::list<ETHRenderEntity*> &particles) { if (m_provider->GetShaderManager()->BeginParticlePass()) { for (std::list<ETHRenderEntity*>::iterator iter = particles.begin(); iter != particles.end();) { ETHRenderEntity *pRenderEntity = (*iter); if (!m_tempEntities.IsTempEntityEligible(pRenderEntity)) { pRenderEntity->UpdateParticleSystems(GetZAxisDirection()); } for (std::size_t t=0; t<pRenderEntity->GetNumParticleSystems(); t++) { pRenderEntity->DrawParticles(t, m_maxSceneHeight, m_minSceneHeight, m_sceneProps); } iter++; } m_provider->GetShaderManager()->EndParticlePass(); } // seed the random number generator Randomizer::Seed(m_provider->GetVideo()->GetElapsedTime()); return true; }
// TODO-TO-DO: this method is too large... bool ETHScene::RenderList(float &minHeight, float &maxHeight, SpritePtr pOutline, SpritePtr pInvisibleEntSymbol, std::list<ETHRenderEntity*> &outParticles, std::list<ETHRenderEntity*> &outHalos, const bool roundUp) { // This multimap will store all entities contained in the visible buckets // It will automatically sort entities to draw them in an "alpha friendly" order std::multimap<float, ETHRenderEntity*> mmEntities; // store the max and min height to assign when everything is drawn maxHeight = m_maxSceneHeight; minHeight = m_minSceneHeight; m_nRenderedEntities = 0; // don't let bucket size be equal to 0 assert(GetBucketSize().x != 0 || GetBucketSize().y != 0); // Gets the list of visible buckets std::list<Vector2> bucketList; const Vector2& v2CamPos = m_provider->GetVideo()->GetCameraPos(); //for debugging pourposes ETHGlobal::GetIntersectingBuckets(bucketList, v2CamPos, m_provider->GetVideo()->GetScreenSizeF(), GetBucketSize(), IsDrawingBorderBuckets(), IsDrawingBorderBuckets()); // Loop through all visible Buckets for (std::list<Vector2>::iterator bucketPositionIter = bucketList.begin(); bucketPositionIter != bucketList.end(); bucketPositionIter++) { ETHBucketMap::iterator bucketIter = m_buckets.Find(*bucketPositionIter); if (bucketIter == m_buckets.GetLastBucket()) continue; if (bucketIter->second.empty()) continue; ETHEntityList::const_iterator iEnd = bucketIter->second.end(); for (ETHEntityList::iterator iter = bucketIter->second.begin(); iter != iEnd; iter++) { ETHSpriteEntity *pRenderEntity = (*iter); // update scene bounding for depth buffer maxHeight = Max(maxHeight, pRenderEntity->GetMaxHeight()); minHeight = Min(minHeight, pRenderEntity->GetMinHeight()); if (pRenderEntity->IsHidden()) continue; // fill the light list for this frame // const ETHEntityFile &entity = pRenderEntity->GetData()->entity; if (pRenderEntity->HasLightSource()) { ETHLight light = *(pRenderEntity->GetLight()); // if it has a particle system in the first slot, adjust the light // brightness according to the number os active particles if (pRenderEntity->GetParticleManager(0) && !pRenderEntity->IsStatic()) { boost::shared_ptr<ETHParticleManager> paticleManager = pRenderEntity->GetParticleManager(0); light.color *= static_cast<float>(paticleManager->GetNumActiveParticles()) / static_cast<float>(paticleManager->GetNumParticles()); } AddLight(light, pRenderEntity->GetPosition()); } // add this entity to the multimap to sort it for an alpha-friendly rendering list const Vector3& v3Pos = pRenderEntity->GetPosition(); const ETH_ENTITY_TYPE type = pRenderEntity->GetType(); const float depth = pRenderEntity->ComputeDepth(maxHeight, minHeight); const float drawHash = ComputeDrawHash(depth, v2CamPos, v3Pos, type); // add the entity to the render map mmEntities.insert(std::pair<float, ETHRenderEntity*>(drawHash, *iter)); m_nRenderedEntities++; } } // Draw visible entities ordered in an alpha-friendly map for (std::multimap<float, ETHRenderEntity*>::iterator iter = mmEntities.begin(); iter != mmEntities.end(); iter++) { ETHRenderEntity *pRenderEntity = (iter->second); m_provider->GetShaderManager()->BeginAmbientPass(pRenderEntity, maxHeight, minHeight); // draws the ambient pass and if we're at the editor, draw the collision box if it's an invisible entity #ifdef _ETHANON_EDITOR if (pOutline && pRenderEntity->IsInvisible() && pRenderEntity->Collidable()) { pRenderEntity->DrawCollisionBox(true, pOutline, GS_WHITE, maxHeight, minHeight, m_sceneProps.zAxisDirection); } #endif m_provider->GetVideo()->RoundUpPosition(roundUp); pRenderEntity->DrawAmbientPass(m_maxSceneHeight, m_minSceneHeight, (m_enableLightmaps && m_showingLightmaps), m_sceneProps); // draw "invisible entity symbol" if we're in the editor #ifdef _ETHANON_EDITOR if (pOutline) { if (pRenderEntity->IsInvisible() && pRenderEntity->Collidable()) { pRenderEntity->DrawCollisionBox(false, pOutline, GS_WHITE, maxHeight, minHeight, m_sceneProps.zAxisDirection); } if (pRenderEntity->IsInvisible() && !pRenderEntity->Collidable()) { const float depth = m_provider->GetVideo()->GetSpriteDepth(); m_provider->GetVideo()->SetSpriteDepth(1.0f); pInvisibleEntSymbol->Draw(pRenderEntity->GetPositionXY()); m_provider->GetVideo()->SetSpriteDepth(depth); } } #endif // fill the halo list // const ETHEntityFile &entity = pRenderEntity->GetData()->entity; if (pRenderEntity->HasLightSource() && pRenderEntity->GetHalo()) { outHalos.push_back(pRenderEntity); } // fill the particle list for this frame if (pRenderEntity->HasParticleSystems()) { outParticles.push_back(pRenderEntity); } // fill the callback list m_tempEntities.AddCallbackWhenEligible(pRenderEntity); m_provider->GetShaderManager()->EndAmbientPass(); //draw light pass for (std::list<ETHLight>::iterator iter = m_lights.begin(); iter != m_lights.end(); iter++) { if (!pRenderEntity->IsHidden()) { if (!(pRenderEntity->IsStatic() && iter->staticLight && m_enableLightmaps)) { m_provider->GetVideo()->RoundUpPosition(roundUp); if (m_provider->GetShaderManager()->BeginLightPass(pRenderEntity, &(*iter), m_maxSceneHeight, m_minSceneHeight, GetLightIntensity())) { pRenderEntity->DrawLightPass(GetZAxisDirection()); m_provider->GetShaderManager()->EndLightPass(); m_provider->GetVideo()->RoundUpPosition(false); if (AreRealTimeShadowsEnabled()) { if (m_provider->GetShaderManager()->BeginShadowPass(pRenderEntity, &(*iter), m_maxSceneHeight, m_minSceneHeight)) { pRenderEntity->DrawShadow(m_maxSceneHeight, m_minSceneHeight, m_sceneProps, *iter, 0); m_provider->GetShaderManager()->EndShadowPass(); } } m_provider->GetVideo()->RoundUpPosition(roundUp); } } } } } mmEntities.clear(); m_nCurrentLights = m_lights.size(); // Show the buckets outline in debug mode #if defined _DEBUG || defined _ETHANON_EDITOR if (m_provider->GetInput()->IsKeyDown(GSK_PAUSE)) { DrawBucketOutlines(); } #endif return true; }