// Write some stats to llinfos void display_stats() { if (gNoRender || !gViewerWindow->mWindow->getVisible() || !gFocusMgr.getAppHasFocus()) { // Do not keep FPS statistics while yielding cooperatively // (i;e. when not running as foreground window) gRecentFrameCount = 0; gRecentFPSTime.reset(); } F32 fps_log_freq = gSavedSettings.getF32("FPSLogFrequency"); if (fps_log_freq > 0.f && gRecentFPSTime.getElapsedTimeF32() >= fps_log_freq) { F32 fps = gRecentFrameCount / fps_log_freq; llinfos << llformat("FPS: %.02f", fps) << llendl; gRecentFrameCount = 0; gRecentFPSTime.reset(); } F32 mem_log_freq = gSavedSettings.getF32("MemoryLogFrequency"); if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq) { gMemoryAllocated = getCurrentRSS(); U32 memory = (U32)(gMemoryAllocated / (1024*1024)); llinfos << llformat("MEMORY: %d MB", memory) << llendl; gRecentMemoryTime.reset(); } }
// Write some stats to llinfos void display_stats() { if (gNoRender || !gViewerWindow->getWindow()->getVisible() || !gFocusMgr.getAppHasFocus()) { // Do not keep FPS statistics while yielding cooperatively // (i;e. when not running as foreground window) gRecentFrameCount = 0; gRecentFPSTime.reset(); } F32 fps_log_freq = gSavedSettings.getF32("FPSLogFrequency"); if (fps_log_freq > 0.f && gRecentFPSTime.getElapsedTimeF32() >= fps_log_freq) { F32 fps = gRecentFrameCount / fps_log_freq; llinfos << llformat("FPS: %.02f", fps) << llendl; llinfos << llformat("VBO: %d glVBO: %d", LLVertexBuffer::sCount, LLVertexBuffer::sGLCount) << llendl; #ifdef LL_OCTREE_STATS OctreeStats::getInstance()->dump(); #endif gRecentFrameCount = 0; gRecentFPSTime.reset(); } F32 mem_log_freq = gSavedSettings.getF32("MemoryLogFrequency"); if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq) { gMemoryAllocated = LLMemory::getCurrentRSS(); U32 memory = (U32)(gMemoryAllocated / (1024*1024)); llinfos << llformat("MEMORY: %d MB", memory) << llendl; llinfos << "THREADS: "<< LLThread::getCount() << llendl; llinfos << "MALLOC: " << SGMemStat::getPrintableStat() <<llendl; LLMemory::logMemoryInfo(TRUE) ; gRecentMemoryTime.reset(); } }
LLColor4U lggBeamMaps::beamColorFromData(lggBeamsColors data) { F32 r, g, b; LLColor4 output; LLColor4U toReturn; F32 timeinc = timer.getElapsedTimeF32()*0.3f*((data.rotateSpeed+.01f)) * (360/(data.endHue-data.startHue)); S32 diference = llround(data.endHue - data.startHue); if(diference == 360 || diference == 720) { //full rainbow //liner one hslToRgb(fmod(timeinc,1.0f), 1.0f, 0.5f, r, g, b); }else { F32 variance = ((data.endHue/360.0f)-(data.startHue/360.0f))/2.0f; hslToRgb((data.startHue/360.0f) + variance + (sinf(timeinc)*(variance)), 1.0f, 0.5f, r, g, b); } output.set(r, g, b); toReturn.setVecScaleClamp(output); return toReturn; }
// Write some stats to llinfos void display_stats() { F32 fps_log_freq = gSavedSettings.getF32("FPSLogFrequency"); if (fps_log_freq > 0.f && gRecentFPSTime.getElapsedTimeF32() >= fps_log_freq) { F32 fps = gRecentFrameCount / fps_log_freq; llinfos << llformat("FPS: %.02f", fps) << llendl; gRecentFrameCount = 0; gRecentFPSTime.reset(); } F32 mem_log_freq = gSavedSettings.getF32("MemoryLogFrequency"); if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq) { gMemoryAllocated = getCurrentRSS(); U32 memory = (U32)(gMemoryAllocated / (1024*1024)); llinfos << llformat("MEMORY: %d MB", memory) << llendl; gRecentMemoryTime.reset(); } }
//static void LLVOCacheEntry::updateDebugSettings() { static LLFrameTimer timer; if(timer.getElapsedTimeF32() < 1.0f) //update frequency once per second. { return; } timer.reset(); //the number of frames invisible objects stay in memory static LLCachedControl<U32> inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime"); sMinFrameRange = inv_obj_time - 1; //make 0 to be the maximum //min radius: all objects within this radius remain loaded in memory static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius"); sNearRadius = llmin((F32)min_radius, gAgentCamera.mDrawDistance); //can not exceed the draw distance sNearRadius = llmax(sNearRadius, 1.f); //minimum value is 1.0m //objects within the view frustum whose visible area is greater than this threshold will be loaded static LLCachedControl<F32> front_pixel_threshold(gSavedSettings,"SceneLoadFrontPixelThreshold"); sFrontPixelThreshold = front_pixel_threshold; //objects out of the view frustum whose visible area is greater than this threshold will remain loaded static LLCachedControl<F32> rear_pixel_threshold(gSavedSettings,"SceneLoadRearPixelThreshold"); sRearPixelThreshold = rear_pixel_threshold; sRearPixelThreshold = llmax(sRearPixelThreshold, sFrontPixelThreshold); //can not be smaller than sFrontPixelThreshold. // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction"); sRearFarRadius = llmax(rear_max_radius_frac * gAgentCamera.mDrawDistance / 100.f, 1.0f); //minimum value is 1.0m sRearFarRadius = llmax(sRearFarRadius, (F32)min_radius); //can not be less than "SceneLoadMinRadius". sRearFarRadius = llmin(sRearFarRadius, gAgentCamera.mDrawDistance); //can not be more than the draw distance. //make the above parameters adaptive to memory usage //starts to put restrictions from low_mem_bound_MB, apply tightest restrictions when hits high_mem_bound_MB static LLCachedControl<U32> low_mem_bound_MB(gSavedSettings,"SceneLoadLowMemoryBound"); static LLCachedControl<U32> high_mem_bound_MB(gSavedSettings,"SceneLoadHighMemoryBound"); LLMemory::updateMemoryInfo() ; U32 allocated_mem = LLMemory::getAllocatedMemKB().value(); allocated_mem /= 1024; //convert to MB. if(allocated_mem < low_mem_bound_MB) { return; } F32 adjust_factor = llmax(0.f, (F32)(high_mem_bound_MB - allocated_mem) / (high_mem_bound_MB - low_mem_bound_MB)); sRearFarRadius = llmin(adjust_factor * sRearFarRadius, 96.f); //[0.f, 96.f] sMinFrameRange = (U32)llclamp(adjust_factor * sMinFrameRange, 10.f, 64.f); //[10, 64] sNearRadius = llmax(adjust_factor * sNearRadius, 1.0f); }
void LLNetMap::draw() { static LLFrameTimer map_timer; if (mObjectImagep.isNull()) { createObjectImage(); } if (gSavedSettings.getS32( "MiniMapCenter") != MAP_CENTER_NONE) { mCurPanX = lerp(mCurPanX, mTargetPanX, LLCriticalDamp::getInterpolant(0.1f)); mCurPanY = lerp(mCurPanY, mTargetPanY, LLCriticalDamp::getInterpolant(0.1f)); } F32 rotation = 0; // Prepare a scissor region { LLGLEnable scissor(GL_SCISSOR_TEST); { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLLocalClipRect clip(getLocalRect()); gGL.matrixMode(LLRender::MM_MODELVIEW); // Draw background rectangle if(isBackgroundVisible()) { LLColor4 background_color = isBackgroundOpaque() ? getBackgroundColor().mV : getTransparentColor().mV; gGL.color4fv( background_color.mV ); gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0); } } // region 0,0 is in the middle S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPanX); S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPanY); gGL.pushMatrix(); gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f); static LLCachedControl<bool> rotate_map("MiniMapRotate", true); if (rotate_map) { // rotate subsequent draws to agent rotation rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); gGL.rotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f); } // figure out where agent is LLColor4 this_region_color = gColors.getColor( "NetMapThisRegion" ); LLColor4 live_region_color = gColors.getColor( "NetMapLiveRegion" ); LLColor4 dead_region_color = gColors.getColor( "NetMapDeadRegion" ); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* regionp = *iter; S32 region_width = llround(regionp->getWidth()); // Find x and y position relative to camera's center. LLVector3 origin_agent = regionp->getOriginAgent(); LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent(); F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale; F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale; // background region rectangle F32 bottom = relative_y; F32 left = relative_x; F32 top = bottom + mScale ; F32 right = left + mScale ; gGL.color4fv(regionp == gAgent.getRegion() ? this_region_color.mV : live_region_color.mV); if (!regionp->isAlive()) { gGL.color4fv(dead_region_color.mV); } // Draw using texture. gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture()); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); gGL.end(); // Draw water gGL.setAlphaRejectSettings(LLRender::CF_GREATER, ABOVE_WATERLINE_ALPHA / 255.f); { if (regionp->getLand().getWaterTexture()) { gGL.getTexUnit(0)->bind(regionp->getLand().getWaterTexture()); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); gGL.end(); } } gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } // Redraw object layer periodically if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f)) { mUpdateNow = false; // Locate the centre of the object layer, accounting for panning LLVector3 new_center = globalPosToView(gAgentCamera.getCameraPositionGlobal(), rotate_map); new_center.mV[VX] -= mCurPanX; new_center.mV[VY] -= mCurPanY; new_center.mV[VZ] = 0.f; mObjectImageCenterGlobal = viewPosToGlobal(llround(new_center.mV[VX]), llround(new_center.mV[VY]), rotate_map); // Create the base texture. U8 *default_texture = mObjectRawImagep->getData(); memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() ); // Draw buildings gObjectList.renderObjectsForMap(*this); mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight()); map_timer.reset(); } LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); map_center_agent -= gAgentCamera.getCameraPositionAgent(); map_center_agent.mV[0] *= mScale/LLWorld::getInstance()->getRegionWidthInMeters(); map_center_agent.mV[1] *= mScale/LLWorld::getInstance()->getRegionWidthInMeters(); gGL.getTexUnit(0)->bind(mObjectImagep); F32 image_half_width = 0.5f*mObjectMapPixels; F32 image_half_height = 0.5f*mObjectMapPixels; gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]); gGL.end(); gGL.popMatrix(); LLVector3d pos_global; LLVector3 pos_map; // Mouse pointer in local coordinates S32 local_mouse_x; S32 local_mouse_y; LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y); mClosestAgentToCursor.setNull(); F32 closest_dist = F32_MAX; F32 min_pick_dist = mDotRadius * MIN_PICK_SCALE; // Draw avatars // LLColor4 mapcolor = gAvatarMapColor; static const LLCachedControl<LLColor4> standard_color(gColors,"MapAvatar",LLColor4(0.f,1.f,0.f,1.f)); static const LLCachedControl<LLColor4> friend_color_stored("AscentFriendColor",LLColor4(1.f,1.f,0.f,1.f)); static const LLCachedControl<LLColor4> em_color("AscentEstateOwnerColor",LLColor4(1.f,0.6f,1.f,1.f)); static const LLCachedControl<LLColor4> linden_color("AscentLindenColor",LLColor4(0.f,0.f,1.f,1.f)); static const LLCachedControl<LLColor4> muted_color("AscentMutedColor",LLColor4(0.7f,0.7f,0.7f,1.f)); // Draw avatars // [RLVa:KB] - Version: 1.23.4 | Alternate: Snowglobe-1.2.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b LLColor4 friend_color = (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? friend_color_stored : standard_color; // [/RLVa:KB] std::vector<LLUUID> avatar_ids; std::vector<LLVector3d> positions; LLWorld::getInstance()->getAvatars(&avatar_ids, &positions); for(U32 i=0; i<avatar_ids.size(); i++) { LLColor4 avColor = standard_color; // TODO: it'd be very cool to draw these in sorted order from lowest Z to highest. // just be careful to sort the avatar IDs along with the positions. -MG pos_map = globalPosToView(positions[i], rotate_map); if (positions[i].mdV[VZ] == 0.f) { pos_map.mV[VZ] = 16000.f; } std::string avName; gCacheName->getFullName(avatar_ids[i], avName); if(LLMuteList::getInstance()->isMuted(avatar_ids[i])) { avColor = muted_color; } LLViewerRegion* avatar_region = LLWorld::getInstance()->getRegionFromPosGlobal(positions[i]); LLUUID estate_owner = avatar_region? avatar_region->getOwner() : LLUUID::null; // MOYMOD Minimap custom av colors. boost::unordered_map<const LLUUID,LLColor4>::const_iterator it = mm_MarkerColors.find(avatar_ids[i]); if(it != mm_MarkerColors.end()) { avColor = it->second; } //Lindens are always more Linden than your friend, make that take precedence else if(LLMuteList::getInstance()->isLinden(avName)) { avColor = linden_color; } //check if they are an estate owner at their current position else if(estate_owner.notNull() && avatar_ids[i] == estate_owner) { avColor = em_color; } //without these dots, SL would suck. else if(is_agent_friend(avatar_ids[i])) { avColor = friend_color; } LLWorldMapView::drawAvatar( pos_map.mV[VX], pos_map.mV[VY], avColor, pos_map.mV[VZ], mDotRadius); F32 dist_to_cursor = dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y)); if(dist_to_cursor < min_pick_dist && dist_to_cursor < closest_dist) { closest_dist = dist_to_cursor; mClosestAgentToCursor = avatar_ids[i]; mClosestAgentPosition = positions[i]; } } // Draw dot for autopilot target if (gAgent.getAutoPilot()) { drawTracking(gAgent.getAutoPilotTargetGlobal(), rotate_map, gTrackColor); } else { LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); if ( LLTracker::TRACKING_AVATAR == tracking_status ) { drawTracking(LLAvatarTracker::instance().getGlobalPos(), rotate_map, gTrackColor); } else if ( LLTracker::TRACKING_LANDMARK == tracking_status || LLTracker::TRACKING_LOCATION == tracking_status ) { drawTracking(LLTracker::getTrackedPositionGlobal(), rotate_map, gTrackColor); } } // Draw dot for self avatar position pos_global = gAgent.getPositionGlobal(); pos_map = globalPosToView(pos_global, rotate_map); LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage; S32 dot_width = llround(mDotRadius * 2.f); you->draw( llround(pos_map.mV[VX] - mDotRadius), llround(pos_map.mV[VY] - mDotRadius), dot_width, dot_width); // Draw frustum F32 meters_to_pixels = mScale/ LLWorld::getInstance()->getRegionWidthInMeters(); F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); F32 far_clip_pixels = far_clip_meters * meters_to_pixels; F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); F32 half_width_pixels = half_width_meters * meters_to_pixels; F32 ctr_x = (F32)center_sw_left; F32 ctr_y = (F32)center_sw_bottom; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); if (rotate_map) { gGL.color4fv(gColors.getColor("NetMapFrustum").mV); gGL.begin( LLRender::TRIANGLES ); gGL.vertex2f( ctr_x, ctr_y ); gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels ); gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels ); gGL.end(); } else { gGL.color4fv(gColors.getColor("NetMapFrustumRotating").mV); // If we don't rotate the map, we have to rotate the frustum. gGL.pushMatrix(); gGL.translatef( ctr_x, ctr_y, 0 ); gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); gGL.begin( LLRender::TRIANGLES ); gGL.vertex2f( 0, 0 ); gGL.vertex2f( -half_width_pixels, far_clip_pixels ); gGL.vertex2f( half_width_pixels, far_clip_pixels ); gGL.end(); gGL.popMatrix(); } } // Rotation of 0 means that North is up setDirectionPos( getChild<LLTextBox>("e_label"), rotation); setDirectionPos( getChild<LLTextBox>("n_label"), rotation + F_PI_BY_TWO); setDirectionPos( getChild<LLTextBox>("w_label"), rotation + F_PI); setDirectionPos( getChild<LLTextBox>("s_label"), rotation + F_PI + F_PI_BY_TWO); setDirectionPos( getChild<LLTextBox>("ne_label"), rotation + F_PI_BY_TWO / 2); setDirectionPos( getChild<LLTextBox>("nw_label"), rotation + F_PI_BY_TWO + F_PI_BY_TWO / 2); setDirectionPos( getChild<LLTextBox>("sw_label"), rotation + F_PI + F_PI_BY_TWO / 2); setDirectionPos( getChild<LLTextBox>("se_label"), rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2); LLView::draw(); }
// Paint the display! void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLFastTimer t(LLFastTimer::FTM_RENDER); if (LLPipeline::sRenderFrameTest) { send_agent_pause(); } gSnapshot = for_snapshot; LLGLSDefault gls_default; LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL); LLVertexBuffer::unbind(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); gPipeline.disableLights(); // Don't draw if the window is hidden or minimized. // In fact, must explicitly check the minimized state before drawing. // Attempting to draw into a minimized window causes a GL error. JC if ( !gViewerWindow->getActive() || !gViewerWindow->mWindow->getVisible() || gViewerWindow->mWindow->getMinimized() ) { // Clean up memory the pools may have allocated if (rebuild) { gFrameStats.start(LLFrameStats::REBUILD); gPipeline.rebuildPools(); } gViewerWindow->returnEmptyPicks(); return; } gViewerWindow->checkSettings(); { LLFastTimer ftm(LLFastTimer::FTM_PICK); LLAppViewer::instance()->pingMainloopTimeout("Display:Pick"); gViewerWindow->performPick(); } LLAppViewer::instance()->pingMainloopTimeout("Display:CheckStates"); LLGLState::checkStates(); LLGLState::checkTextureChannels(); ////////////////////////////////////////////////////////// // // Logic for forcing window updates if we're in drone mode. // if (gNoRender) { #if LL_WINDOWS static F32 last_update_time = 0.f; if ((gFrameTimeSeconds - last_update_time) > 1.f) { InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE); last_update_time = gFrameTimeSeconds; } #elif LL_DARWIN // MBW -- Do something clever here. #endif // Not actually rendering, don't bother. return; } // // Bail out if we're in the startup state and don't want to try to // render the world. // if (LLStartUp::getStartupState() < STATE_STARTED) { LLAppViewer::instance()->pingMainloopTimeout("Display:Startup"); display_startup(); return; } //LLGLState::verify(FALSE); ///////////////////////////////////////////////// // // Update GL Texture statistics (used for discard logic?) // LLAppViewer::instance()->pingMainloopTimeout("Display:TextureStats"); gFrameStats.start(LLFrameStats::UPDATE_TEX_STATS); stop_glerror(); LLImageGL::updateStats(gFrameTimeSeconds); LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName"); LLVOAvatar::sRenderGroupTitles = !gSavedSettings.getBOOL("RenderHideGroupTitleAll"); gPipeline.mBackfaceCull = TRUE; gFrameCount++; gRecentFrameCount++; if (gFocusMgr.getAppHasFocus()) { gForegroundFrameCount++; } ////////////////////////////////////////////////////////// // // Display start screen if we're teleporting, and skip render // if (gTeleportDisplay) { LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport"); const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived. S32 attach_count = 0; if (gAgent.getAvatarObject()) { attach_count = gAgent.getAvatarObject()->getAttachmentCount(); } F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count; F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32(); F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time); if( (gAgent.getTeleportState() != LLAgent::TELEPORT_START) && (teleport_percent > 100.f) ) { // Give up. Don't keep the UI locked forever. gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); gAgent.setTeleportMessage(std::string()); } const std::string& message = gAgent.getTeleportMessage(); switch( gAgent.getTeleportState() ) { case LLAgent::TELEPORT_START: // Transition to REQUESTED. Viewer has sent some kind // of TeleportRequest to the source simulator gTeleportDisplayTimer.reset(); gViewerWindow->setShowProgress(TRUE); gViewerWindow->setProgressPercent(0); gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["requesting"]); break; case LLAgent::TELEPORT_REQUESTED: // Waiting for source simulator to respond gViewerWindow->setProgressPercent( llmin(teleport_percent, 37.5f) ); gViewerWindow->setProgressString(message); break; case LLAgent::TELEPORT_MOVING: // Viewer has received destination location from source simulator gViewerWindow->setProgressPercent( llmin(teleport_percent, 75.f) ); gViewerWindow->setProgressString(message); break; case LLAgent::TELEPORT_START_ARRIVAL: // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator gTeleportArrivalTimer.reset(); gViewerWindow->setProgressCancelButtonVisible(FALSE, std::string("Cancel")); //TODO: Translate gViewerWindow->setProgressPercent(75.f); gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["arriving"]); gImageList.mForceResetTextureStats = TRUE; gAgent.resetView(TRUE, TRUE); break; case LLAgent::TELEPORT_ARRIVING: // Make the user wait while content "pre-caches" { F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY); if( arrival_fraction > 1.f ) { arrival_fraction = 1.f; LLFirstUse::useTeleport(); gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); } gViewerWindow->setProgressCancelButtonVisible(FALSE, std::string("Cancel")); //TODO: Translate gViewerWindow->setProgressPercent( arrival_fraction * 25.f + 75.f); gViewerWindow->setProgressString(message); } break; case LLAgent::TELEPORT_LOCAL: // Short delay when teleporting in the same sim (progress screen active but not shown - did not // fall-through from TELEPORT_START) { if( gTeleportDisplayTimer.getElapsedTimeF32() > TELEPORT_LOCAL_DELAY ) { LLFirstUse::useTeleport(); gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); } } break; case LLAgent::TELEPORT_NONE: // No teleport in progress gViewerWindow->setShowProgress(FALSE); gTeleportDisplay = FALSE; break; default: break; } } else if(LLAppViewer::instance()->logoutRequestSent()) { LLAppViewer::instance()->pingMainloopTimeout("Display:Logout"); F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime; if (percent_done > 100.f) { percent_done = 100.f; } if( LLApp::isExiting() ) { percent_done = 100.f; } gViewerWindow->setProgressPercent( percent_done ); } else if (gRestoreGL) { LLAppViewer::instance()->pingMainloopTimeout("Display:RestoreGL"); F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME; if( percent_done > 100.f ) { gViewerWindow->setShowProgress(FALSE); gRestoreGL = FALSE; } else { if( LLApp::isExiting() ) { percent_done = 100.f; } gViewerWindow->setProgressPercent( percent_done ); } } ////////////////////////// // // Prepare for the next frame // ///////////////////////////// // // Update the camera // // LLAppViewer::instance()->pingMainloopTimeout("Display:Camera"); LLViewerCamera::getInstance()->setZoomParameters(zoom_factor, subfield); LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE); ////////////////////////// // // clear the next buffer // (must follow dynamic texture writing since that uses the frame buffer) // if (gDisconnected) { LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected"); render_ui(); render_disconnected_background(); } ////////////////////////// // // Set rendering options // // LLAppViewer::instance()->pingMainloopTimeout("Display:RenderSetup"); stop_glerror(); /////////////////////////////////////// // // Slam lighting parameters back to our defaults. // Note that these are not the same as GL defaults... stop_glerror(); F32 one[4] = {1.f, 1.f, 1.f, 1.f}; glLightModelfv (GL_LIGHT_MODEL_AMBIENT,one); stop_glerror(); ///////////////////////////////////// // // Render // // Actually push all of our triangles to the screen. // // do render-to-texture stuff here if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) { LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures"); LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES); if (LLDynamicTexture::updateAllInstances()) { gGL.setColorMask(true, true); glClear(GL_DEPTH_BUFFER_BIT); } } gViewerWindow->setupViewport(); gPipeline.resetFrameStats(); // Reset per-frame statistics. if (!gDisconnected) { LLAppViewer::instance()->pingMainloopTimeout("Display:Update"); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { //don't draw hud objects in this frame gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); } if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES)) { //don't draw hud particles in this frame gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES); } //upkeep gl name pools LLGLNamePool::upkeepPools(); stop_glerror(); display_update_camera(); stop_glerror(); // *TODO: merge these two methods LLHUDManager::getInstance()->updateEffects(); LLHUDObject::updateAll(); stop_glerror(); gFrameStats.start(LLFrameStats::UPDATE_GEOM); const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time gPipeline.createObjects(max_geom_update_time); gPipeline.updateGeom(max_geom_update_time); stop_glerror(); gFrameStats.start(LLFrameStats::UPDATE_CULL); S32 water_clip = 0; if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) && (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER) || gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER))) { if (LLViewerCamera::getInstance()->cameraUnderWater()) { water_clip = -1; } else { water_clip = 1; } } LLAppViewer::instance()->pingMainloopTimeout("Display:Cull"); //Increment drawable frame counter LLDrawable::incrementVisible(); LLSpatialGroup::sNoDelete = TRUE; LLPipeline::sUseOcclusion = (!gUseWireframe && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery) ? 2 : 0; if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred) { //force occlusion on for all render types if doing deferred render LLPipeline::sUseOcclusion = 3; } LLPipeline::sFastAlpha = gSavedSettings.getBOOL("RenderFastAlpha"); LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip"); LLVOAvatar::sMaxVisible = gSavedSettings.getS32("RenderAvatarMaxVisible"); LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate"); S32 occlusion = LLPipeline::sUseOcclusion; if (gDepthDirty) { //depth buffer is invalid, don't overwrite occlusion state LLPipeline::sUseOcclusion = llmin(occlusion, 1); } gDepthDirty = FALSE; LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); static LLCullResult result; gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip); stop_glerror(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); BOOL to_texture = !for_snapshot && gPipeline.canUseVertexShaders() && LLPipeline::sRenderGlow; LLAppViewer::instance()->pingMainloopTimeout("Display:Swap"); { { LLFastTimer ftm(LLFastTimer::FTM_CLIENT_COPY); LLVertexBuffer::clientCopy(0.016); } if (gResizeScreenTexture) { gResizeScreenTexture = FALSE; gPipeline.resizeScreenTexture(); } gGL.setColorMask(true, true); glClearColor(0,0,0,0); LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); if (!for_snapshot) { if (gFrameCount > 1) { //for some reason, ATI 4800 series will error out if you //try to generate a shadow before the first frame is through gPipeline.generateSunShadow(*LLViewerCamera::getInstance()); } LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); glh::matrix4f proj = glh_get_current_projection(); glh::matrix4f mod = glh_get_current_modelview(); glViewport(0,0,512,512); LLVOAvatar::updateFreezeCounter() ; LLVOAvatar::updateImpostors(); glh_set_current_projection(proj); glh_set_current_modelview(mod); glMatrixMode(GL_PROJECTION); glLoadMatrixf(proj.m); glMatrixMode(GL_MODELVIEW); glLoadMatrixf(mod.m); gViewerWindow->setupViewport(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); } glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } if (!for_snapshot) { LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery"); gPipeline.generateWaterReflection(*LLViewerCamera::getInstance()); } ////////////////////////////////////// // // Update images, using the image stats generated during object update/culling // // Can put objects onto the retextured list. // // Doing this here gives hardware occlusion queries extra time to complete LLAppViewer::instance()->pingMainloopTimeout("Display:UpdateImages"); LLError::LLCallStacks::clear() ; llpushcallstacks ; gFrameStats.start(LLFrameStats::IMAGE_UPDATE); { LLFastTimer t(LLFastTimer::FTM_IMAGE_UPDATE); LLViewerImage::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(), LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean()); gBumpImageList.updateImages(); // must be called before gImageList version so that it's textures are thrown out first. F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds; // 50 ms/second decode time max_image_decode_time = llclamp(max_image_decode_time, 0.001f, 0.005f ); // min 1ms/frame, max 5ms/frame) gImageList.updateImages(max_image_decode_time); stop_glerror(); } llpushcallstacks ; /////////////////////////////////// // // StateSort // // Responsible for taking visible objects, and adding them to the appropriate draw orders. // In the case of alpha objects, z-sorts them first. // Also creates special lists for outlines and selected face rendering. // LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort"); { gFrameStats.start(LLFrameStats::STATE_SORT); gPipeline.stateSort(*LLViewerCamera::getInstance(), result); stop_glerror(); if (rebuild) { ////////////////////////////////////// // // rebuildPools // // gFrameStats.start(LLFrameStats::REBUILD); gPipeline.rebuildPools(); stop_glerror(); } } LLPipeline::sUseOcclusion = occlusion; { LLAppViewer::instance()->pingMainloopTimeout("Display:Sky"); LLFastTimer t(LLFastTimer::FTM_UPDATE_SKY); gSky.updateSky(); } if(gUseWireframe) { glClearColor(0.5f, 0.5f, 0.5f, 0.f); glClear(GL_COLOR_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart"); //// render frontmost floater opaque for occlusion culling purposes //LLFloater* frontmost_floaterp = gFloaterView->getFrontmost(); //// assumes frontmost floater with focus is opaque //if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp)) //{ // glMatrixMode(GL_MODELVIEW); // glPushMatrix(); // { // gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); // glLoadIdentity(); // LLRect floater_rect = frontmost_floaterp->getScreenRect(); // // deflate by one pixel so rounding errors don't occlude outside of floater extents // floater_rect.stretch(-1); // LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidth(), // (F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeight(), // (F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidth(), // (F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeight()); // floater_3d_rect.translate(-0.5f, -0.5f); // glTranslatef(0.f, 0.f, -LLViewerCamera::getInstance()->getNear()); // glScalef(LLViewerCamera::getInstance()->getNear() * LLViewerCamera::getInstance()->getAspect() / sinf(LLViewerCamera::getInstance()->getView()), LLViewerCamera::getInstance()->getNear() / sinf(LLViewerCamera::getInstance()->getView()), 1.f); // gGL.color4fv(LLColor4::white.mV); // gGL.begin(LLVertexBuffer::QUADS); // { // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f); // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f); // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f); // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f); // } // gGL.end(); // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // } // glPopMatrix(); //} LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE; LLPipeline::updateRenderDeferred(); stop_glerror(); if (to_texture) { gGL.setColorMask(true, true); if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { gPipeline.mDeferredScreen.bindTarget(); gPipeline.mDeferredScreen.clear(); } else { gPipeline.mScreen.bindTarget(); gPipeline.mScreen.clear(); } gGL.setColorMask(true, false); } LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom"); if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) && !gRestoreGL) { gGL.setColorMask(true, false); if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance()); } else { gPipeline.renderGeom(*LLViewerCamera::getInstance(), TRUE); } gGL.setColorMask(true, true); //store this frame's modelview matrix for use //when rendering next frame's occlusion queries for (U32 i = 0; i < 16; i++) { gGLLastModelView[i] = gGLModelView[i]; } stop_glerror(); } LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush"); if (to_texture) { if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { gPipeline.mDeferredScreen.flush(); } else { gPipeline.mScreen.flush(); } } /// We copy the frame buffer straight into a texture here, /// and then display it again with compositor effects. /// Using render to texture would be faster/better, but I don't have a /// grasp of their full display stack just yet. // gPostProcess->apply(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { gPipeline.renderDeferredLighting(); } LLPipeline::sUnderWaterRender = FALSE; LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI"); if (!for_snapshot) { gFrameStats.start(LLFrameStats::RENDER_UI); render_ui(); } LLSpatialGroup::sNoDelete = FALSE; } LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats"); gFrameStats.start(LLFrameStats::MISC_END); stop_glerror(); if (LLPipeline::sRenderFrameTest) { send_agent_resume(); LLPipeline::sRenderFrameTest = FALSE; } display_stats(); LLAppViewer::instance()->pingMainloopTimeout("Display:Done"); }
void LLNetMap::draw() { // Ansariel: Synchronize netmap scale throughout instances if (mScale != sScale) { setScale(sScale); } static LLFrameTimer map_timer; static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white); static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white); static LLUIColor map_avatar_linden_color = LLUIColorTable::instance().getColor("MapAvatarLindenColor", LLColor4::blue); static LLUIColor map_avatar_muted_color = LLUIColorTable::instance().getColor("MapAvatarMutedColor", LLColor4::grey3); static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white); static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white); static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white); static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white); static LLUIColor map_chat_ring_color = LLUIColorTable::instance().getColor("MapChatRingColor", LLColor4::yellow); static LLUIColor map_shout_ring_color = LLUIColorTable::instance().getColor("MapShoutRingColor", LLColor4::red); if (mObjectImagep.isNull()) { createObjectImage(); } static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true); if (auto_center) { mCurPan = lerp(mCurPan, mTargetPan, LLCriticalDamp::getInterpolant(0.1f)); } // Prepare a scissor region F32 rotation = 0; gGL.pushMatrix(); gGL.pushUIMatrix(); LLVector3 offset = gGL.getUITranslation(); LLVector3 scale = gGL.getUIScale(); gGL.loadIdentity(); gGL.loadUIIdentity(); gGL.scalef(scale.mV[0], scale.mV[1], scale.mV[2]); gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]); { LLLocalClipRect clip(getLocalRect()); { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.matrixMode(LLRender::MM_MODELVIEW); // Draw background rectangle LLColor4 background_color = mBackgroundColor.get(); gGL.color4fv( background_color.mV ); gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0); } // region 0,0 is in the middle S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPan.mV[VX]); S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPan.mV[VY]); gGL.pushMatrix(); gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f); static LLUICachedControl<bool> rotate_map("MiniMapRotate", true); if( rotate_map ) { // rotate subsequent draws to agent rotation rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); gGL.rotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f); } // figure out where agent is S32 region_width = llround(LLWorld::getInstance()->getRegionWidthInMeters()); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* regionp = *iter; // Find x and y position relative to camera's center. LLVector3 origin_agent = regionp->getOriginAgent(); LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent(); F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale; F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale; // background region rectangle F32 bottom = relative_y; F32 left = relative_x; F32 top = bottom + mScale ; F32 right = left + mScale ; if (regionp == gAgent.getRegion()) { gGL.color4f(1.f, 1.f, 1.f, 1.f); } else { gGL.color4f(0.8f, 0.8f, 0.8f, 1.f); } if (!regionp->isAlive()) { gGL.color4f(1.f, 0.5f, 0.5f, 1.f); } // Draw using texture. gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture()); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); gGL.end(); // Draw water gGL.setAlphaRejectSettings(LLRender::CF_GREATER, ABOVE_WATERLINE_ALPHA / 255.f); { if (regionp->getLand().getWaterTexture()) { gGL.getTexUnit(0)->bind(regionp->getLand().getWaterTexture()); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); gGL.end(); } } gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } // Redraw object layer periodically if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f)) { mUpdateNow = false; // Locate the centre of the object layer, accounting for panning LLVector3 new_center = globalPosToView(gAgentCamera.getCameraPositionGlobal()); new_center.mV[VX] -= mCurPan.mV[VX]; new_center.mV[VY] -= mCurPan.mV[VY]; new_center.mV[VZ] = 0.f; mObjectImageCenterGlobal = viewPosToGlobal(llfloor(new_center.mV[VX]), llfloor(new_center.mV[VY])); // Create the base texture. U8 *default_texture = mObjectRawImagep->getData(); memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() ); // Draw objects gObjectList.renderObjectsForMap(*this); mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight()); map_timer.reset(); } LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); LLVector3 camera_position = gAgentCamera.getCameraPositionAgent(); map_center_agent -= camera_position; map_center_agent.mV[VX] *= mScale/region_width; map_center_agent.mV[VY] *= mScale/region_width; gGL.getTexUnit(0)->bind(mObjectImagep); F32 image_half_width = 0.5f*mObjectMapPixels; F32 image_half_height = 0.5f*mObjectMapPixels; gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]); gGL.end(); gGL.popMatrix(); // Mouse pointer in local coordinates S32 local_mouse_x; S32 local_mouse_y; //localMouse(&local_mouse_x, &local_mouse_y); LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y); mClosestAgentToCursor.setNull(); F32 closest_dist_squared = F32_MAX; // value will be overridden in the loop F32 min_pick_dist_squared = (mDotRadius * MIN_PICK_SCALE) * (mDotRadius * MIN_PICK_SCALE); LLVector3 pos_map; uuid_vec_t avatar_ids; std::vector<LLVector3d> positions; bool unknown_relative_z; LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgentCamera.getCameraPositionGlobal()); // Draw avatars for (U32 i = 0; i < avatar_ids.size(); i++) { pos_map = globalPosToView(positions[i]); LLUUID uuid = avatar_ids[i]; bool show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(uuid) != NULL); LLColor4 color = show_as_friend ? map_avatar_friend_color : map_avatar_color; // <FS:Ansariel> Check for unknown Z-offset => AVATAR_UNKNOWN_Z_OFFSET //unknown_relative_z = positions[i].mdV[VZ] == COARSEUPDATE_MAX_Z && // camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z; unknown_relative_z = false; if (positions[i].mdV[VZ] == AVATAR_UNKNOWN_Z_OFFSET) { if (camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z) { // No exact data and cam >=1020 => we don't know if // other avatar is above or below us => unknown unknown_relative_z = true; } else { // No exact data but cam is below 1020 => other avatar // is definitely above us => bump Z-offset to F32_MAX // so we get the up chevron pos_map.mV[VZ] = F32_MAX; } } // </FS:Ansariel> // Colorize muted avatars and Lindens std::string fullName; LLMuteList* muteListInstance = LLMuteList::getInstance(); if (muteListInstance->isMuted(uuid)) color = map_avatar_muted_color; else if (gCacheName->getFullName(uuid, fullName) && muteListInstance->isLinden(fullName)) color = map_avatar_linden_color; // Mark Avatars with special colors - Ansariel if (LLNetMap::sAvatarMarksMap.find(uuid) != LLNetMap::sAvatarMarksMap.end()) { color = LLNetMap::sAvatarMarksMap[uuid]; } //color based on contact sets prefs if(LGGContactSets::getInstance()->hasFriendColorThatShouldShow(uuid,FALSE,FALSE,FALSE,TRUE)) { color = LGGContactSets::getInstance()->getFriendColor(uuid); } // [RLVa:KB] - Checked: 2010-04-19 (RLVa-1.2.0f) | Modified: RLVa-1.2.0f | FS-Specific LLWorldMapView::drawAvatar( pos_map.mV[VX], pos_map.mV[VY], ((!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? color : map_avatar_color.get()), pos_map.mV[VZ], mDotRadius, unknown_relative_z); // [/RLVa:KB] // LLWorldMapView::drawAvatar( // pos_map.mV[VX], pos_map.mV[VY], // color, // pos_map.mV[VZ], mDotRadius, // unknown_relative_z); if(uuid.notNull()) { bool selected = false; uuid_vec_t::iterator sel_iter = gmSelected.begin(); for (; sel_iter != gmSelected.end(); sel_iter++) { if(*sel_iter == uuid) { selected = true; break; } } if(selected) { if( (pos_map.mV[VX] < 0) || (pos_map.mV[VY] < 0) || (pos_map.mV[VX] >= getRect().getWidth()) || (pos_map.mV[VY] >= getRect().getHeight()) ) { S32 x = llround( pos_map.mV[VX] ); S32 y = llround( pos_map.mV[VY] ); LLWorldMapView::drawTrackingCircle( getRect(), x, y, color, 1, 10); } else { LLWorldMapView::drawTrackingDot(pos_map.mV[VX],pos_map.mV[VY],color,0.f); } } } F32 dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y)); if(dist_to_cursor_squared < min_pick_dist_squared && dist_to_cursor_squared < closest_dist_squared) { closest_dist_squared = dist_to_cursor_squared; mClosestAgentToCursor = uuid; mClosestAgentPosition = positions[i]; } } // Draw dot for autopilot target if (gAgent.getAutoPilot()) { drawTracking( gAgent.getAutoPilotTargetGlobal(), map_track_color ); } else { LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); if ( LLTracker::TRACKING_AVATAR == tracking_status ) { drawTracking( LLAvatarTracker::instance().getGlobalPos(), map_track_color ); } else if ( LLTracker::TRACKING_LANDMARK == tracking_status || LLTracker::TRACKING_LOCATION == tracking_status ) { drawTracking( LLTracker::getTrackedPositionGlobal(), map_track_color ); } } // Draw dot for self avatar position LLVector3d pos_global = gAgent.getPositionGlobal(); pos_map = globalPosToView(pos_global); S32 dot_width = llround(mDotRadius * 2.f); LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage; if (you) { you->draw(llround(pos_map.mV[VX] - mDotRadius), llround(pos_map.mV[VY] - mDotRadius), dot_width, dot_width); F32 dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y)); if(dist_to_cursor_squared < min_pick_dist_squared && dist_to_cursor_squared < closest_dist_squared) { mClosestAgentToCursor = gAgent.getID(); mClosestAgentPosition = pos_global; } // Draw chat range ring(s) static LLUICachedControl<bool> chat_ring("MiniMapChatRing", true); if(chat_ring) { drawRing(LLWorld::getInstance()->getSayDistance(), pos_map, map_chat_ring_color); drawRing(LLWorld::getInstance()->getShoutDistance(), pos_map, map_shout_ring_color); } } // Draw frustum F32 meters_to_pixels = mScale/ LLWorld::getInstance()->getRegionWidthInMeters(); F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); F32 far_clip_pixels = far_clip_meters * meters_to_pixels; F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); F32 half_width_pixels = half_width_meters * meters_to_pixels; F32 ctr_x = (F32)center_sw_left; F32 ctr_y = (F32)center_sw_bottom; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); if( rotate_map ) { gGL.color4fv((map_frustum_color()).mV); gGL.begin( LLRender::TRIANGLES ); gGL.vertex2f( ctr_x, ctr_y ); gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels ); gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels ); gGL.end(); } else { gGL.color4fv((map_frustum_rotating_color()).mV); // If we don't rotate the map, we have to rotate the frustum. gGL.pushMatrix(); gGL.translatef( ctr_x, ctr_y, 0 ); gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); gGL.begin( LLRender::TRIANGLES ); gGL.vertex2f( 0, 0 ); gGL.vertex2f( -half_width_pixels, far_clip_pixels ); gGL.vertex2f( half_width_pixels, far_clip_pixels ); gGL.end(); gGL.popMatrix(); } } gGL.popMatrix(); gGL.popUIMatrix(); LLUICtrl::draw(); }
void LLNetMap::draw() { static LLFrameTimer map_timer; if (mObjectImagep.isNull()) { createObjectImage(); } mCurPanX = lerp(mCurPanX, mTargetPanX, LLCriticalDamp::getInterpolant(0.1f)); mCurPanY = lerp(mCurPanY, mTargetPanY, LLCriticalDamp::getInterpolant(0.1f)); F32 rotation = 0; // Prepare a scissor region { LLGLEnable scissor(GL_SCISSOR_TEST); { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLLocalClipRect clip(getLocalRect()); glMatrixMode(GL_MODELVIEW); // Draw background rectangle if(isBackgroundVisible()) { gGL.color4fv(isBackgroundOpaque() ? getBackgroundColor().mV : getTransparentColor().mV); gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0); } } // region 0,0 is in the middle S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPanX); S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPanY); gGL.pushMatrix(); gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f); BOOL rotate_map = gSavedSettings.getBOOL( "MiniMapRotate" ); if( rotate_map ) { // rotate subsequent draws to agent rotation rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); glRotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f); } // figure out where agent is S32 region_width = llround(LLWorld::getInstance()->getRegionWidthInMeters()); LLColor4 this_region_color = gColors.getColor( "NetMapThisRegion" ); LLColor4 live_region_color = gColors.getColor( "NetMapLiveRegion" ); LLColor4 dead_region_color = gColors.getColor( "NetMapDeadRegion" ); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* regionp = *iter; // Find x and y position relative to camera's center. LLVector3 origin_agent = regionp->getOriginAgent(); LLVector3 rel_region_pos = origin_agent - gAgent.getCameraPositionAgent(); F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale; F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale; // background region rectangle F32 bottom = relative_y; F32 left = relative_x; F32 top = bottom + mScale ; F32 right = left + mScale ; gGL.color4fv(regionp == gAgent.getRegion() ? this_region_color.mV : live_region_color.mV); if (!regionp->isAlive()) { gGL.color4fv(dead_region_color.mV); } // Draw using texture. gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture()); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); gGL.end(); // Draw water gGL.setAlphaRejectSettings(LLRender::CF_GREATER, ABOVE_WATERLINE_ALPHA / 255.f); { if (regionp->getLand().getWaterTexture()) { gGL.getTexUnit(0)->bind(regionp->getLand().getWaterTexture()); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); gGL.end(); } } gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } LLVector3d old_center = mObjectImageCenterGlobal; LLVector3d new_center = gAgent.getCameraPositionGlobal(); new_center.mdV[0] = (5.f/mObjectMapTPM)*floor(0.2f*mObjectMapTPM*new_center.mdV[0]); new_center.mdV[1] = (5.f/mObjectMapTPM)*floor(0.2f*mObjectMapTPM*new_center.mdV[1]); new_center.mdV[2] = 0.f; if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f)) { mUpdateNow = FALSE; mObjectImageCenterGlobal = new_center; // Center moved enough. // Create the base texture. U8 *default_texture = mObjectRawImagep->getData(); memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() ); // Draw buildings gObjectList.renderObjectsForMap(*this); mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight()); map_timer.reset(); } LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); map_center_agent -= gAgent.getCameraPositionAgent(); map_center_agent.mV[VX] *= mScale/region_width; map_center_agent.mV[VY] *= mScale/region_width; gGL.getTexUnit(0)->bind(mObjectImagep); F32 image_half_width = 0.5f*mObjectMapPixels; F32 image_half_height = 0.5f*mObjectMapPixels; gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]); gGL.end(); gGL.popMatrix(); LLVector3d pos_global; LLVector3 pos_map; // Mouse pointer in local coordinates S32 local_mouse_x; S32 local_mouse_y; LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y); mClosestAgentToCursor.setNull(); F32 closest_dist = F32_MAX; F32 min_pick_dist = mDotRadius * MIN_PICK_SCALE; // Draw avatars LLColor4 avatar_color = gColors.getColor( "MapAvatar" ); LLColor4 friend_color = gColors.getColor( "MapFriend" ); std::vector<LLUUID> avatar_ids; std::vector<LLVector3d> positions; LLWorld::getInstance()->getAvatars(&avatar_ids, &positions); for(U32 i=0; i<avatar_ids.size(); i++) { // TODO: it'd be very cool to draw these in sorted order from lowest Z to highest. // just be careful to sort the avatar IDs along with the positions. -MG pos_map = globalPosToView(positions[i], rotate_map); LLWorldMapView::drawAvatar( pos_map.mV[VX], pos_map.mV[VY], is_agent_friend(avatar_ids[i]) ? friend_color : avatar_color, pos_map.mV[VZ], mDotRadius); F32 dist_to_cursor = dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y)); if(dist_to_cursor < min_pick_dist && dist_to_cursor < closest_dist) { closest_dist = dist_to_cursor; mClosestAgentToCursor = avatar_ids[i]; } } // Draw dot for autopilot target if (gAgent.getAutoPilot()) { drawTracking( gAgent.getAutoPilotTargetGlobal(), rotate_map, gTrackColor ); } else { LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); if ( LLTracker::TRACKING_AVATAR == tracking_status ) { drawTracking( LLAvatarTracker::instance().getGlobalPos(), rotate_map, gTrackColor ); } else if ( LLTracker::TRACKING_LANDMARK == tracking_status || LLTracker::TRACKING_LOCATION == tracking_status ) { drawTracking( LLTracker::getTrackedPositionGlobal(), rotate_map, gTrackColor ); } } // Draw dot for self avatar position pos_global = gAgent.getPositionGlobal(); pos_map = globalPosToView(pos_global, rotate_map); LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage; S32 dot_width = llround(mDotRadius * 2.f); you->draw( llround(pos_map.mV[VX] - mDotRadius), llround(pos_map.mV[VY] - mDotRadius), dot_width, dot_width); // Draw frustum F32 meters_to_pixels = mScale/ LLWorld::getInstance()->getRegionWidthInMeters(); F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); F32 far_clip_pixels = far_clip_meters * meters_to_pixels; F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); F32 half_width_pixels = half_width_meters * meters_to_pixels; F32 ctr_x = (F32)center_sw_left; F32 ctr_y = (F32)center_sw_bottom; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); if( rotate_map ) { gGL.color4fv(gColors.getColor("NetMapFrustum").mV); gGL.begin( LLRender::TRIANGLES ); gGL.vertex2f( ctr_x, ctr_y ); gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels ); gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels ); gGL.end(); } else { gGL.color4fv(gColors.getColor("NetMapFrustumRotating").mV); // If we don't rotate the map, we have to rotate the frustum. gGL.pushMatrix(); gGL.translatef( ctr_x, ctr_y, 0 ); glRotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); gGL.begin( LLRender::TRIANGLES ); gGL.vertex2f( 0, 0 ); gGL.vertex2f( -half_width_pixels, far_clip_pixels ); gGL.vertex2f( half_width_pixels, far_clip_pixels ); gGL.end(); gGL.popMatrix(); } } // Rotation of 0 means that North is up setDirectionPos( getChild<LLTextBox>("e_label"), rotation); setDirectionPos( getChild<LLTextBox>("n_label"), rotation + F_PI_BY_TWO); setDirectionPos( getChild<LLTextBox>("w_label"), rotation + F_PI); setDirectionPos( getChild<LLTextBox>("s_label"), rotation + F_PI + F_PI_BY_TWO); setDirectionPos( getChild<LLTextBox>("ne_label"), rotation + F_PI_BY_TWO / 2); setDirectionPos( getChild<LLTextBox>("nw_label"), rotation + F_PI_BY_TWO + F_PI_BY_TWO / 2); setDirectionPos( getChild<LLTextBox>("sw_label"), rotation + F_PI + F_PI_BY_TWO / 2); setDirectionPos( getChild<LLTextBox>("se_label"), rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2); LLView::draw(); }
void update_statistics(U32 frame_count) { gTotalWorldBytes += gVLManager.getTotalBytes(); gTotalObjectBytes += gObjectBits / 8; // make sure we have a valid time delta for this frame if (gFrameIntervalSeconds > 0.f) { if (gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK) { LLViewerStats::getInstance()->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds); } else if (gAgent.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR) { LLViewerStats::getInstance()->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds); } else if (gFloaterTools && gFloaterTools->getVisible()) { LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds); } } LLViewerStats::getInstance()->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gSavedSettings.getS32("RenderLightingDetail")); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip")); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); #if 0 // 1.9.2 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_OBJECTS, (F64)gSavedSettings.getS32("VertexShaderLevelObject")); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar")); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment")); #endif LLViewerStats::getInstance()->setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_FRAME)); F64 idle_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IDLE); F64 network_secs = gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_NETWORK); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_NETWORK_SECS, network_secs); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_IMAGE_UPDATE)); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_STATESORT )); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime(LLFastTimer::FTM_RENDER_GEOMETRY)); LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); if (cdp) { LLViewerStats::getInstance()->mSimPingStat.addValue(cdp->getPingDelay()); gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1); gSimPingCount++; } else { LLViewerStats::getInstance()->mSimPingStat.addValue(10000); } LLViewerStats::getInstance()->mFPSStat.addValue(1); F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); LLViewerStats::getInstance()->mLayersKBitStat.addValue(layer_bits/1024.f); LLViewerStats::getInstance()->mObjectKBitStat.addValue(gObjectBits/1024.f); LLViewerStats::getInstance()->mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); LLViewerStats::getInstance()->mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); gTransferManager.resetTransferBitsIn(LLTCT_ASSET); if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) { gDebugTimers[0].pause(); } else { gDebugTimers[0].unpause(); } { static F32 visible_avatar_frames = 0.f; static F32 avg_visible_avatars = 0; F32 visible_avatars = (F32)LLVOAvatar::sNumVisibleAvatars; if (visible_avatars > 0.f) { visible_avatar_frames = 1.f; avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames; } LLViewerStats::getInstance()->setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars); } LLWorld::getInstance()->updateNetStats(); LLWorld::getInstance()->requestCacheMisses(); // Reset all of these values. gVLManager.resetBitCounts(); gObjectBits = 0; // gDecodedBits = 0; // Only update texture stats ones per second so that they are less noisy { static const F32 texture_stats_freq = 1.f; static LLFrameTimer texture_stats_timer; if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq) { LLViewerStats::getInstance()->mTextureKBitStat.addValue(LLViewerImageList::sTextureBits/1024.f); LLViewerStats::getInstance()->mTexturePacketsStat.addValue(LLViewerImageList::sTexturePackets); gTotalTextureBytes += LLViewerImageList::sTextureBits / 8; LLViewerImageList::sTextureBits = 0; LLViewerImageList::sTexturePackets = 0; texture_stats_timer.reset(); } } #if LL_LCD_COMPILE bool LCDenabled = gLcdScreen->Enabled(); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LOGITECH_LCD, LCDenabled); #else LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LOGITECH_LCD, false); #endif }
// Paint the display! void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, bool tiling) { LLFastTimer t(FTM_RENDER); if (gWindowResized) { //skip render on frames where window has been resized gGL.flush(); glClear(GL_COLOR_BUFFER_BIT); gViewerWindow->getWindow()->swapBuffers(); LLPipeline::refreshCachedSettings(); gPipeline.resizeScreenTexture(); gResizeScreenTexture = FALSE; gWindowResized = FALSE; return; } //Nope /*if (LLPipeline::sRenderDeferred) { //hack to make sky show up in deferred snapshots for_snapshot = FALSE; }*/ if (LLPipeline::sRenderFrameTest) { send_agent_pause(); } gSnapshot = for_snapshot; LLGLSDefault gls_default; LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL); LLVertexBuffer::unbind(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); stop_glerror(); gPipeline.disableLights(); //reset vertex buffers if needed gPipeline.doResetVertexBuffers(); stop_glerror(); // Don't draw if the window is hidden or minimized. // In fact, must explicitly check the minimized state before drawing. // Attempting to draw into a minimized window causes a GL error. JC if ( !gViewerWindow->getActive() || !gViewerWindow->getWindow()->getVisible() || gViewerWindow->getWindow()->getMinimized() ) { // Clean up memory the pools may have allocated if (rebuild) { gFrameStats.start(LLFrameStats::REBUILD); stop_glerror(); gPipeline.rebuildPools(); stop_glerror(); } stop_glerror(); gViewerWindow->returnEmptyPicks(); stop_glerror(); return; } gViewerWindow->checkSettings(); if(gWindowResized) //Singu Note: gViewerWindow->checkSettings() can call LLViewerWindow::reshape(). If it has then skip this frame. { return; } { LLFastTimer ftm(FTM_PICK); LLAppViewer::instance()->pingMainloopTimeout("Display:Pick"); gViewerWindow->performPick(); } LLAppViewer::instance()->pingMainloopTimeout("Display:CheckStates"); LLGLState::checkStates(); LLGLState::checkTextureChannels(); ////////////////////////////////////////////////////////// // // Logic for forcing window updates if we're in drone mode. // if (gNoRender) { #if LL_WINDOWS static F32 last_update_time = 0.f; if ((gFrameTimeSeconds - last_update_time) > 1.f) { InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE); last_update_time = gFrameTimeSeconds; } #elif LL_DARWIN // MBW -- Do something clever here. #endif // Not actually rendering, don't bother. return; } // // Bail out if we're in the startup state and don't want to try to // render the world. // if (LLStartUp::getStartupState() < STATE_STARTED) { LLAppViewer::instance()->pingMainloopTimeout("Display:Startup"); display_startup(); return; } //LLGLState::verify(FALSE); ///////////////////////////////////////////////// // // Update GL Texture statistics (used for discard logic?) // LLAppViewer::instance()->pingMainloopTimeout("Display:TextureStats"); gFrameStats.start(LLFrameStats::UPDATE_TEX_STATS); stop_glerror(); LLImageGL::updateStats(gFrameTimeSeconds); LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName"); LLVOAvatar::sRenderGroupTitles = !gSavedSettings.getBOOL("RenderHideGroupTitleAll"); gPipeline.mBackfaceCull = TRUE; gFrameCount++; gRecentFrameCount++; if (gFocusMgr.getAppHasFocus()) { gForegroundFrameCount++; } ////////////////////////////////////////////////////////// // // Display start screen if we're teleporting, and skip render // if (gTeleportDisplay) { LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport"); const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived. S32 attach_count = 0; if (isAgentAvatarValid()) { attach_count = gAgentAvatarp->getAttachmentCount(); } F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count; F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32(); F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time); if( (gAgent.getTeleportState() != LLAgent::TELEPORT_START) && (teleport_percent > 100.f) ) { // Give up. Don't keep the UI locked forever. gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); gAgent.setTeleportMessage(std::string()); } static const LLCachedControl<bool> hide_tp_screen("AscentDisableTeleportScreens",false); const std::string& message = gAgent.getTeleportMessage(); switch( gAgent.getTeleportState() ) { case LLAgent::TELEPORT_PENDING: gTeleportDisplayTimer.reset(); if(!hide_tp_screen) gViewerWindow->setShowProgress(TRUE); gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f)); gAgent.setTeleportMessage(LLAgent::sTeleportProgressMessages["pending"]); gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["pending"]); break; case LLAgent::TELEPORT_START: // Transition to REQUESTED. Viewer has sent some kind // of TeleportRequest to the source simulator gTeleportDisplayTimer.reset(); if(!hide_tp_screen) gViewerWindow->setShowProgress(TRUE); gViewerWindow->setProgressPercent(llmin(teleport_percent, 0.0f)); gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["requesting"]); gViewerWindow->setProgressString(LLAgent::sTeleportProgressMessages["requesting"]); break; case LLAgent::TELEPORT_REQUESTED: // Waiting for source simulator to respond gViewerWindow->setProgressPercent( llmin(teleport_percent, 37.5f) ); gViewerWindow->setProgressString(message); break; case LLAgent::TELEPORT_MOVING: // Viewer has received destination location from source simulator gViewerWindow->setProgressPercent( llmin(teleport_percent, 75.f) ); gViewerWindow->setProgressString(message); break; case LLAgent::TELEPORT_START_ARRIVAL: // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator gTeleportArrivalTimer.reset(); gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel")); gViewerWindow->setProgressPercent(75.f); gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["arriving"]); gTextureList.mForceResetTextureStats = TRUE; if(!hide_tp_screen) gAgentCamera.resetView(TRUE, TRUE); break; case LLAgent::TELEPORT_ARRIVING: // Make the user wait while content "pre-caches" { F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY); if( arrival_fraction > 1.f || hide_tp_screen) { arrival_fraction = 1.f; LLFirstUse::useTeleport(); gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); } gViewerWindow->setProgressCancelButtonVisible(FALSE, LLTrans::getString("Cancel")); gViewerWindow->setProgressPercent( arrival_fraction * 25.f + 75.f); gViewerWindow->setProgressString(message); } break; case LLAgent::TELEPORT_LOCAL: // Short delay when teleporting in the same sim (progress screen active but not shown - did not // fall-through from TELEPORT_START) { // <edit> // is this really needed.... I say no. //if( gTeleportDisplayTimer.getElapsedTimeF32() > TELEPORT_LOCAL_DELAY ) // </edit> { LLFirstUse::useTeleport(); gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); } } break; case LLAgent::TELEPORT_NONE: // No teleport in progress gViewerWindow->setShowProgress(FALSE); gTeleportDisplay = FALSE; gTeleportArrivalTimer.reset(); break; default: break; } } else if(LLAppViewer::instance()->logoutRequestSent()) { LLAppViewer::instance()->pingMainloopTimeout("Display:Logout"); F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime; if (percent_done > 100.f) { percent_done = 100.f; } if( LLApp::isExiting() ) { percent_done = 100.f; } gViewerWindow->setProgressPercent( percent_done ); } else if (gRestoreGL) { LLAppViewer::instance()->pingMainloopTimeout("Display:RestoreGL"); F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME; if( percent_done > 100.f ) { gViewerWindow->setShowProgress(FALSE); gRestoreGL = FALSE; } else { if( LLApp::isExiting() ) { percent_done = 100.f; } gViewerWindow->setProgressPercent( percent_done ); } } // Progressively increase draw distance after TP when required. if (gSavedDrawDistance > 0.0f && gAgent.getTeleportState() == LLAgent::TELEPORT_NONE) { if (gTeleportArrivalTimer.getElapsedTimeF32() >= (F32)gSavedSettings.getU32("SpeedRezInterval")) { gTeleportArrivalTimer.reset(); F32 current = gSavedSettings.getF32("RenderFarClip"); if (gSavedDrawDistance > current) { current *= 2.0; if (current > gSavedDrawDistance) { current = gSavedDrawDistance; } gSavedSettings.setF32("RenderFarClip", current); } if (current >= gSavedDrawDistance) { gSavedDrawDistance = 0.0f; gSavedSettings.setF32("SavedRenderFarClip", 0.0f); } } } ////////////////////////// // // Prepare for the next frame // ///////////////////////////// // // Update the camera // // LLAppViewer::instance()->pingMainloopTimeout("Display:Camera"); LLViewerCamera::getInstance()->setZoomParameters(zoom_factor, subfield); LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE); ////////////////////////// // // clear the next buffer // (must follow dynamic texture writing since that uses the frame buffer) // if (gDisconnected) { LLAppViewer::instance()->pingMainloopTimeout("Display:Disconnected"); render_ui(); } ////////////////////////// // // Set rendering options // // LLAppViewer::instance()->pingMainloopTimeout("Display:RenderSetup"); stop_glerror(); /////////////////////////////////////// // // Slam lighting parameters back to our defaults. // Note that these are not the same as GL defaults... stop_glerror(); gGL.setAmbientLightColor(LLColor4::white); stop_glerror(); ///////////////////////////////////// // // Render // // Actually push all of our triangles to the screen. // // do render-to-texture stuff here if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) { LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures"); LLFastTimer t(FTM_UPDATE_TEXTURES); if (LLViewerDynamicTexture::updateAllInstances()) { gGL.setColorMask(true, true); glClear(GL_DEPTH_BUFFER_BIT); } } gViewerWindow->setup3DViewport(); gPipeline.resetFrameStats(); // Reset per-frame statistics. if (!gDisconnected) { LLAppViewer::instance()->pingMainloopTimeout("Display:Update"); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { //don't draw hud objects in this frame gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); } if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES)) { //don't draw hud particles in this frame gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES); } //upkeep gl name pools LLGLNamePool::upkeepPools(); stop_glerror(); display_update_camera(tiling); stop_glerror(); // *TODO: merge these two methods LLHUDManager::getInstance()->updateEffects(); LLHUDObject::updateAll(); stop_glerror(); if(!tiling) { gFrameStats.start(LLFrameStats::UPDATE_GEOM); const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds; // 50 ms/second update time gPipeline.createObjects(max_geom_update_time); gPipeline.processPartitionQ(); gPipeline.updateGeom(max_geom_update_time); stop_glerror(); gPipeline.updateGL(); stop_glerror(); } gFrameStats.start(LLFrameStats::UPDATE_CULL); S32 water_clip = 0; if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) && (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER) || gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER))) { if (LLViewerCamera::getInstance()->cameraUnderWater()) { water_clip = -1; } else { water_clip = 1; } } LLAppViewer::instance()->pingMainloopTimeout("Display:Cull"); //Increment drawable frame counter LLDrawable::incrementVisible(); LLSpatialGroup::sNoDelete = TRUE; LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName(); /*if (LLPipeline::sUseOcclusion && LLPipeline::sRenderDeferred) { //force occlusion on for all render types if doing deferred render LLPipeline::sUseOcclusion = 3; }*/ S32 occlusion = LLPipeline::sUseOcclusion; if (gDepthDirty) { //depth buffer is invalid, don't overwrite occlusion state LLPipeline::sUseOcclusion = llmin(occlusion, 1); } gDepthDirty = FALSE; LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); static LLCullResult result; LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE; gPipeline.updateCull(*LLViewerCamera::getInstance(), result, water_clip); stop_glerror(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); BOOL to_texture = gPipeline.canUseVertexShaders() && LLPipeline::sRenderGlow; LLAppViewer::instance()->pingMainloopTimeout("Display:Swap"); { if (gResizeScreenTexture) { gResizeScreenTexture = FALSE; gPipeline.resizeScreenTexture(); } gGL.setColorMask(true, true); glClearColor(0,0,0,0); LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); if (!for_snapshot || LLPipeline::sRenderDeferred) { if (gFrameCount > 1) { //for some reason, ATI 4800 series will error out if you //try to generate a shadow before the first frame is through gPipeline.generateSunShadow(*LLViewerCamera::getInstance()); } LLVertexBuffer::unbind(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); const LLMatrix4a saved_proj = glh_get_current_projection(); const LLMatrix4a saved_mod = glh_get_current_modelview(); glViewport(0,0,512,512); LLVOAvatar::updateFreezeCounter() ; if(!LLPipeline::sMemAllocationThrottled) { LLVOAvatar::updateImpostors(); } glh_set_current_projection(saved_proj); glh_set_current_modelview(saved_mod); gGL.matrixMode(LLRender::MM_PROJECTION); gGL.loadMatrix(saved_proj); gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.loadMatrix(saved_mod); gViewerWindow->setup3DViewport(); LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); } glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } LLGLState::checkStates(); LLGLState::checkClientArrays(); //if (!for_snapshot) { LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery"); gPipeline.generateWaterReflection(*LLViewerCamera::getInstance()); gPipeline.renderPhysicsDisplay(); } LLGLState::checkStates(); LLGLState::checkClientArrays(); ////////////////////////////////////// // // Update images, using the image stats generated during object update/culling // // Can put objects onto the retextured list. // // Doing this here gives hardware occlusion queries extra time to complete LLAppViewer::instance()->pingMainloopTimeout("Display:UpdateImages"); LLError::LLCallStacks::clear() ; llpushcallstacks ; gFrameStats.start(LLFrameStats::IMAGE_UPDATE); { LLFastTimer t(FTM_IMAGE_UPDATE); { LLFastTimer t(FTM_IMAGE_UPDATE_CLASS); LLViewerTexture::updateClass(LLViewerCamera::getInstance()->getVelocityStat()->getMean(), LLViewerCamera::getInstance()->getAngularVelocityStat()->getMean()); } { LLFastTimer t(FTM_IMAGE_UPDATE_BUMP); gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first. } { LLFastTimer t(FTM_IMAGE_UPDATE_LIST); F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds; // 50 ms/second decode time max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f ); // min 2ms/frame, max 5ms/frame) gTextureList.updateImages(max_image_decode_time); } /*{ LLFastTimer t(FTM_IMAGE_UPDATE_DELETE); //remove dead textures from GL LLImageGL::deleteDeadTextures(); stop_glerror(); }*/ } llpushcallstacks ; LLGLState::checkStates(); LLGLState::checkClientArrays(); /////////////////////////////////// // // StateSort // // Responsible for taking visible objects, and adding them to the appropriate draw orders. // In the case of alpha objects, z-sorts them first. // Also creates special lists for outlines and selected face rendering. // LLAppViewer::instance()->pingMainloopTimeout("Display:StateSort"); { LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; gFrameStats.start(LLFrameStats::STATE_SORT); gPipeline.stateSort(*LLViewerCamera::getInstance(), result); stop_glerror(); if (rebuild) { ////////////////////////////////////// // // rebuildPools // // gFrameStats.start(LLFrameStats::REBUILD); gPipeline.rebuildPools(); stop_glerror(); } } LLGLState::checkStates(); LLGLState::checkClientArrays(); LLPipeline::sUseOcclusion = occlusion; { LLAppViewer::instance()->pingMainloopTimeout("Display:Sky"); LLFastTimer t(FTM_UPDATE_SKY); gSky.updateSky(); } // if(gUseWireframe) // [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.1.3b) | Modified: RLVa-1.1.3b if ( (gUseWireframe) && ((!rlv_handler_t::isEnabled()) || (!gRlvAttachmentLocks.hasLockedHUD())) ) // [/RLVa:KB] { glClearColor(0.5f, 0.5f, 0.5f, 0.f); glClear(GL_COLOR_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart"); //// render frontmost floater opaque for occlusion culling purposes //LLFloater* frontmost_floaterp = gFloaterView->getFrontmost(); //// assumes frontmost floater with focus is opaque //if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp)) //{ // gGL.matrixMode(LLRender::MM_MODELVIEW); // gGL.pushMatrix(); // { // gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); // gGL.loadIdentity(); // LLRect floater_rect = frontmost_floaterp->calcScreenRect(); // // deflate by one pixel so rounding errors don't occlude outside of floater extents // floater_rect.stretch(-1); // LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidthScaled(), // (F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeightScaled(), // (F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidthScaled(), // (F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeightScaled()); // floater_3d_rect.translate(-0.5f, -0.5f); // gGL.translatef(0.f, 0.f, -LLViewerCamera::getInstance()->getNear()); // gGL.scalef(LLViewerCamera::getInstance()->getNear() * LLViewerCamera::getInstance()->getAspect() / sinf(LLViewerCamera::getInstance()->getView()), LLViewerCamera::getInstance()->getNear() / sinf(LLViewerCamera::getInstance()->getView()), 1.f); // gGL.color4fv(LLColor4::white.mV); // gGL.begin(LLVertexBuffer::QUADS); // { // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f); // gGL.vertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f); // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f); // gGL.vertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f); // } // gGL.end(); // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // } // gGL.popMatrix(); //} LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE; LLGLState::checkStates(); LLGLState::checkClientArrays(); stop_glerror(); if (to_texture) { gGL.setColorMask(true, true); if (LLPipeline::sRenderDeferred) { gPipeline.mDeferredScreen.bindTarget(); glClearColor(1,0,1,1); gPipeline.mDeferredScreen.clear(); } else { gPipeline.mScreen.bindTarget(); if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders()) { const LLColor4 &col = LLDrawPoolWater::sWaterFogColor; glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); } gPipeline.mScreen.clear(); } gGL.setColorMask(true, false); } LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom"); if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) && !gRestoreGL) { LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; static LLCachedControl<bool> render_ui_occlusion("RenderUIOcclusion", false); if(render_ui_occlusion && LLGLSLShader::sNoFixedFunction) { LLFloater* floaterp = gFloaterView->getFrontmost(); if(floaterp && floaterp->getVisible() && floaterp->isBackgroundVisible() && floaterp->isBackgroundOpaque()) { LLGLDepthTest depth(GL_TRUE, GL_TRUE); gGL.setColorMask(false, false); gOcclusionProgram.bind(); LLRect rect = floaterp->calcScreenRect(); rect.stretch(-1); gGL.matrixMode(LLRender::MM_PROJECTION); gGL.pushMatrix(); gGL.loadIdentity(); gGL.ortho(0.0f, gViewerWindow->getWindowWidth(), 0.0f, gViewerWindow->getWindowHeight(), 0.f, 1.0f); gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); gGL.loadIdentity(); gGL.color4fv( LLColor4::white.mV ); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.begin( LLRender::QUADS ); gGL.vertex3f(rect.mLeft, rect.mTop,0.f); gGL.vertex3f(rect.mLeft, rect.mBottom,0.f); gGL.vertex3f(rect.mRight, rect.mBottom,0.f); gGL.vertex3f(rect.mRight, rect.mTop,0.f); gGL.end(); gGL.matrixMode(LLRender::MM_PROJECTION); gGL.popMatrix(); gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.popMatrix(); gOcclusionProgram.unbind(); } } static LLCachedControl<bool> render_depth_pre_pass("RenderDepthPrePass", false); if (render_depth_pre_pass && LLGLSLShader::sNoFixedFunction) { LLGLDepthTest depth(GL_TRUE, GL_TRUE); LLGLEnable cull_face(GL_CULL_FACE); gGL.setColorMask(false, false); U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY }; U32 num_types = LL_ARRAY_SIZE(types); gOcclusionProgram.bind(); for (U32 i = 0; i < num_types; i++) { gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); } gOcclusionProgram.unbind(); } gGL.setColorMask(true, false); if (LLPipeline::sRenderDeferred) { gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance()); } else { gPipeline.renderGeom(*LLViewerCamera::getInstance(), TRUE); } gGL.setColorMask(true, true); //store this frame's modelview matrix for use //when rendering next frame's occlusion queries gGLPreviousModelView = gGLLastModelView; gGLLastModelView = gGLModelView; gGLLastProjection = gGLProjection; stop_glerror(); } //Reversed this. disabling a texunit sets its index as current.. randomly breaking LLRender::matrixMode(U32 mode). Make sure unit0 is the 'current' unit. for (S32 i = gGLManager.mNumTextureImageUnits-1; i >= 0; --i) { //dummy cleanup of any currently bound textures if (gGL.getTexUnit((U32)i)->getCurrType() != LLTexUnit::TT_NONE) { gGL.getTexUnit((U32)i)->unbind(gGL.getTexUnit((U32)i)->getCurrType()); gGL.getTexUnit((U32)i)->disable(); } } LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush"); if (to_texture) { if (LLPipeline::sRenderDeferred) { gPipeline.mDeferredScreen.flush(); if(gPipeline.mDeferredScreen.getFBO()) { LLRenderTarget::copyContentsToFramebuffer(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(), 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); } } else { gPipeline.mScreen.flush(); if(gPipeline.mScreen.getFBO()) { LLRenderTarget::copyContentsToFramebuffer(gPipeline.mScreen, 0, 0, gPipeline.mScreen.getWidth(), gPipeline.mScreen.getHeight(), 0, 0, gPipeline.mScreen.getWidth(), gPipeline.mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); } } } //gGL.flush(); if (LLPipeline::sRenderDeferred) { gPipeline.renderDeferredLighting(); } LLPipeline::sUnderWaterRender = FALSE; LLAppViewer::instance()->pingMainloopTimeout("Display:RenderUI"); if (!for_snapshot || LLPipeline::sRenderDeferred) { LLFastTimer t(FTM_RENDER_UI); gFrameStats.start(LLFrameStats::RENDER_UI); render_ui(); } LLSpatialGroup::sNoDelete = FALSE; gPipeline.clearReferences(); gPipeline.rebuildGroups(); } LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats"); gFrameStats.start(LLFrameStats::MISC_END); stop_glerror(); if (LLPipeline::sRenderFrameTest) { send_agent_resume(); LLPipeline::sRenderFrameTest = FALSE; } display_stats(); LLAppViewer::instance()->pingMainloopTimeout("Display:Done"); gShiftFrame = false; }
void LLNetMap::draw() { static LLFrameTimer map_timer; if (mObjectImagep.isNull()) { createObjectImage(); } LLCachedControl<S32> minimap_center(gSavedSettings, "MiniMapCenter"); if (minimap_center != MAP_CENTER_NONE) { mCurPanX = lerp(mCurPanX, mTargetPanX, LLCriticalDamp::getInterpolant(0.1f)); mCurPanY = lerp(mCurPanY, mTargetPanY, LLCriticalDamp::getInterpolant(0.1f)); } LLViewerCamera* camera = LLViewerCamera::getInstance(); F32 rotation = 0; // Prepare a scissor region { LLGLEnable scissor(GL_SCISSOR_TEST); { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); LLLocalClipRect clip(getLocalRect()); glMatrixMode(GL_MODELVIEW); // Draw background rectangle if(isBackgroundVisible()) { gGL.color4fv(isBackgroundOpaque() ? getBackgroundColor().mV : getTransparentColor().mV); gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0); } } // region 0,0 is in the middle S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPanX); S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPanY); gGL.pushMatrix(); gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f); BOOL rotate_map = gSavedSettings.getBOOL( "MiniMapRotate" ); if( rotate_map ) { // rotate subsequent draws to agent rotation rotation = atan2( camera->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); glRotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f); } // figure out where agent is S32 region_width = llround(LLWorld::getInstance()->getRegionWidthInMeters()); LLColor4 this_region_color = gColors.getColor( "NetMapThisRegion" ); LLColor4 live_region_color = gColors.getColor( "NetMapLiveRegion" ); LLColor4 dead_region_color = gColors.getColor( "NetMapDeadRegion" ); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* regionp = *iter; // Find x and y position relative to camera's center. LLVector3 origin_agent = regionp->getOriginAgent(); LLVector3 rel_region_pos = origin_agent - gAgent.getCameraPositionAgent(); F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale; F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale; // background region rectangle F32 bottom = relative_y; F32 left = relative_x; F32 top = bottom + mScale ; F32 right = left + mScale ; gGL.color4fv(regionp == gAgent.getRegion() ? this_region_color.mV : live_region_color.mV); if (!regionp->isAlive()) { gGL.color4fv(dead_region_color.mV); } // Draw using texture. gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture()); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); gGL.end(); // Draw water gGL.setAlphaRejectSettings(LLRender::CF_GREATER, ABOVE_WATERLINE_ALPHA / 255.f); { if (regionp->getLand().getWaterTexture()) { gGL.getTexUnit(0)->bind(regionp->getLand().getWaterTexture()); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); gGL.end(); } } gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } // Redraw object layer periodically if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f)) { mUpdateNow = FALSE; // Locate the centre of the object layer, accounting for panning LLVector3 new_center = globalPosToView(gAgent.getCameraPositionGlobal(), rotate_map); new_center.mV[0] -= mCurPanX; new_center.mV[1] -= mCurPanY; new_center.mV[2] = 0.f; mObjectImageCenterGlobal = viewPosToGlobal(llround(new_center.mV[0]), llround(new_center.mV[1]), rotate_map); // Create the base texture. U8 *default_texture = mObjectRawImagep->getData(); memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() ); // Draw buildings //gObjectList.renderObjectsForMap(*this); LLCachedControl<bool> mm_fastminimap(gSavedSettings, "mm_fastminimap"); if (!mm_fastminimap) { gObjectList.renderObjectsForMap(*this); mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight()); } mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight()); map_timer.reset(); } LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); map_center_agent -= gAgent.getCameraPositionAgent(); map_center_agent.mV[VX] *= mScale/region_width; map_center_agent.mV[VY] *= mScale/region_width; gGL.getTexUnit(0)->bind(mObjectImagep); F32 image_half_width = 0.5f*mObjectMapPixels; F32 image_half_height = 0.5f*mObjectMapPixels; gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]); gGL.end(); gGL.popMatrix(); LLVector3d pos_global; LLVector3 pos_map; // Mouse pointer in local coordinates S32 local_mouse_x; S32 local_mouse_y; LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y); mClosestAgentToCursor.setNull(); F32 closest_dist = F32_MAX; F32 min_pick_dist = mDotRadius * MIN_PICK_SCALE; // Draw avatars // LLColor4 mapcolor = gAvatarMapColor; static LLCachedControl<LLColor4U> sMapAvatar(gColors, "MapAvatar"); LLColor4 avatar_color = (LLColor4)sMapAvatar; LLColor4 standard_color = avatar_color; //LLColor4 friend_color = gColors.getColor( "MapFriend" ); // [RLVa:KB] - Version: 1.23.4 | Alternate: Snowglobe-1.2.4 | Checked: 2009-07-08 (RLVa-1.0.0e) | Modified: RLVa-0.2.0b LLColor4 friend_color = (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? gColors.getColor("MapFriend") : avatar_color; // [/RLVa:KB] LLColor4 linden_color = gColors.getColor( "MapLinden" ); LLColor4 muted_color = gColors.getColor( "MapMuted" ); std::vector<LLUUID> avatar_ids; std::vector<LLVector3d> positions; LLWorld::getInstance()->getAvatars(&avatar_ids, &positions); U32 a; static LLCachedControl<bool> friendsGroupsOnMinimap(gSavedSettings, "PhoenixContactSetsColorizeMiniMap"); for(U32 i=0; i<avatar_ids.size(); i++) { avatar_color = standard_color; // TODO: it'd be very cool to draw these in sorted order from lowest Z to highest. // just be careful to sort the avatar IDs along with the positions. -MG LLVector3d currentPos(positions[i]); bool isHeightUnknown = (currentPos.mdV[VZ] == 0.f); if (avatar_ids[i].notNull() && isHeightUnknown) { LLViewerObject* viewerObject = gObjectList.findObject(avatar_ids[i]); if (viewerObject) { currentPos.mdV[VZ] = viewerObject->getPositionGlobal().mdV[VZ]; isHeightUnknown = false; } } pos_map = globalPosToView(currentPos, rotate_map); std::string first, last; gCacheName->getName(avatar_ids[i], first, last); if (LLMuteList::getInstance()->isMuted(avatar_ids[i])) avatar_color = muted_color; if (is_agent_friend(avatar_ids[i]) || LGGContactSets::getInstance()->isNonFriend(avatar_ids[i])) { if(friendsGroupsOnMinimap) { LLColor4 fgColor = LGGContactSets::getInstance()->getFriendColor(avatar_ids[i]); if(fgColor!=LGGContactSets::getInstance()->getDefaultColor()) avatar_color=fgColor; }else avatar_color = friend_color; } if((last == "Linden") || (last == "Tester")) avatar_color = linden_color; // MOYMOD Minimap custom av colors. for(a=0;a<mm_netmapnum;a+=1)if(avatar_ids[i]==mm_mapkeys[a])avatar_color=mm_mapcols[a]; // [RLVa:KB] - Alternate: Phoenix-370 | Checked: 2009-07-21 (RLVa-1.0.0) | Added: RLVa-1.0.0 // Phoenix-specific: shouldn't be able to tell anything "personal" about anyone from the minimap under @shownames=n LLWorldMapView::drawAvatar( pos_map.mV[VX], pos_map.mV[VY], (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) ? avatar_color : standard_color, pos_map.mV[VZ],mDotRadius, isHeightUnknown); // [/RLVa:KB] // LLWorldMapView::drawAvatar( // pos_map.mV[VX], pos_map.mV[VY], avatar_color, pos_map.mV[VZ],mDotRadius); F32 dist_to_cursor = dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y)); if(dist_to_cursor < min_pick_dist && dist_to_cursor < closest_dist) { closest_dist = dist_to_cursor; mClosestAgentToCursor = avatar_ids[i]; mClosestAgentPosition = currentPos; } } // Draw dot for autopilot target if (gAgent.getAutoPilot()) { drawTracking( gAgent.getAutoPilotTargetGlobal(), rotate_map, gTrackColor ); } else { LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); if ( LLTracker::TRACKING_AVATAR == tracking_status ) { drawTracking( LLAvatarTracker::instance().getGlobalPos(), rotate_map, gTrackColor ); } else if ( LLTracker::TRACKING_LANDMARK == tracking_status || LLTracker::TRACKING_LOCATION == tracking_status ) { drawTracking( LLTracker::getTrackedPositionGlobal(), rotate_map, gTrackColor ); } } // Draw dot for self avatar position pos_global = gAgent.getPositionGlobal(); pos_map = globalPosToView(pos_global, rotate_map); LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage; S32 dot_width = llround(mDotRadius * 2.f); you->draw( llround(pos_map.mV[VX] - mDotRadius), llround(pos_map.mV[VY] - mDotRadius), dot_width, dot_width); // Draw frustum F32 meters_to_pixels = mScale/ LLWorld::getInstance()->getRegionWidthInMeters(); F32 horiz_fov = camera->getView() * LLViewerCamera::getInstance()->getAspect(); F32 far_clip_meters = camera->getFar(); F32 far_clip_pixels = far_clip_meters * meters_to_pixels; F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); F32 half_width_pixels = half_width_meters * meters_to_pixels; F32 ctr_x = (F32)center_sw_left; F32 ctr_y = (F32)center_sw_bottom; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); if( rotate_map ) { gGL.color4fv(gColors.getColor("NetMapFrustum").mV); gGL.begin( LLRender::TRIANGLES ); gGL.vertex2f( ctr_x, ctr_y ); gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels ); gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels ); gGL.end(); } else { gGL.color4fv(gColors.getColor("NetMapFrustumRotating").mV); // If we don't rotate the map, we have to rotate the frustum. gGL.pushMatrix(); gGL.translatef( ctr_x, ctr_y, 0 ); glRotatef( atan2( camera->getAtAxis().mV[VX], camera->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); gGL.begin( LLRender::TRIANGLES ); gGL.vertex2f( 0, 0 ); gGL.vertex2f( -half_width_pixels, far_clip_pixels ); gGL.vertex2f( half_width_pixels, far_clip_pixels ); gGL.end(); gGL.popMatrix(); } } // Rotation of 0 means that North is up setDirectionPos( getChild<LLTextBox>("e_label"), rotation); setDirectionPos( getChild<LLTextBox>("n_label"), rotation + F_PI_BY_TWO); setDirectionPos( getChild<LLTextBox>("w_label"), rotation + F_PI); setDirectionPos( getChild<LLTextBox>("s_label"), rotation + F_PI + F_PI_BY_TWO); setDirectionPos( getChild<LLTextBox>("ne_label"), rotation + F_PI_BY_TWO / 2); setDirectionPos( getChild<LLTextBox>("nw_label"), rotation + F_PI_BY_TWO + F_PI_BY_TWO / 2); setDirectionPos( getChild<LLTextBox>("sw_label"), rotation + F_PI + F_PI_BY_TWO / 2); setDirectionPos( getChild<LLTextBox>("se_label"), rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2); LLView::draw(); }
/* * The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats. * * There's also a compatibility shim for the old fixed-format sim * stats in newsim/llagentinfo.cpp:processViewerStats. * * If you move stats around here, make the corresponding changes in * those locations, too. */ void send_stats() { // IW 9/23/02 I elected not to move this into LLViewerStats // because it depends on too many viewer.cpp globals. // Someday we may want to merge all our stats into a central place // but that day is not today. // Only send stats if the agent is connected to a region. if (!gAgent.getRegion() || gNoRender) { return; } LLSD body; std::string url = gAgent.getRegion()->getCapability("ViewerStats"); if (url.empty()) { LL_WARNS() << "Could not get ViewerStats capability" << LL_ENDL; return; } body["session_id"] = gAgentSessionID; LLSD &agent = body["agent"]; time_t ltime; time(<ime); F32 run_time = F32(LLFrameTimer::getElapsedSeconds()); agent["start_time"] = S32(ltime - S32(run_time)); // The first stat set must have a 0 run time if it doesn't actually // contain useful data in terms of FPS, etc. We use half the // SEND_STATS_PERIOD seconds as the point at which these statistics become // valid. Data warehouse uses a 0 value here to easily discard these // records with non-useful FPS values etc. if (run_time < (SEND_STATS_PERIOD / 2)) { agent["run_time"] = 0.0f; } else { agent["run_time"] = run_time; } // send fps only for time app spends in foreground agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32(); agent["version"] = gCurrentVersion; std::string language = LLUI::getLanguage(); agent["language"] = language; agent["sim_fps"] = ((F32) gFrameCount - gSimFrames) / (F32) (gRenderStartTime.getElapsedTimeF32() - gSimLastTime); gSimLastTime = gRenderStartTime.getElapsedTimeF32(); gSimFrames = (F32) gFrameCount; agent["agents_in_view"] = LLVOAvatar::sNumVisibleAvatars; agent["ping"] = gAvgSimPing; agent["meters_traveled"] = gAgent.getDistanceTraveled(); agent["regions_visited"] = gAgent.getRegionsVisited(); agent["mem_use"] = LLMemory::getCurrentRSS() / 1024.0; LLSD &system = body["system"]; system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB(); system["os"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple(); system["cpu"] = gSysCPU.getCPUString(); unsigned char MACAddress[MAC_ADDRESS_BYTES]; LLUUID::getNodeID(MACAddress); std::string macAddressString = llformat("%02x-%02x-%02x-%02x-%02x-%02x", MACAddress[0],MACAddress[1],MACAddress[2], MACAddress[3],MACAddress[4],MACAddress[5]); system["mac_address"] = macAddressString; system["serial_number"] = LLAppViewer::instance()->getSerialNumber(); std::string gpu_desc = llformat( "%-6s Class %d ", gGLManager.mGLVendorShort.substr(0,6).c_str(), (S32)LLFeatureManager::getInstance()->getGPUClass()) + LLFeatureManager::getInstance()->getGPUString(); system["gpu"] = gpu_desc; system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass(); system["gpu_vendor"] = gGLManager.mGLVendorShort; system["gpu_version"] = gGLManager.mDriverVersionVendorString; system["opengl_version"] = gGLManager.mGLVersionString; LLSD &download = body["downloads"]; download["world_kbytes"] = gTotalWorldBytes / 1024.0; download["object_kbytes"] = gTotalObjectBytes / 1024.0; download["texture_kbytes"] = gTotalTextureBytes / 1024.0; download["mesh_kbytes"] = LLMeshRepository::sBytesReceived/1024.0; LLSD &in = body["stats"]["net"]["in"]; in["kbytes"] = gMessageSystem->mTotalBytesIn / 1024.0; in["packets"] = (S32) gMessageSystem->mPacketsIn; in["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsIn; in["savings"] = (gMessageSystem->mUncompressedBytesIn - gMessageSystem->mCompressedBytesIn) / 1024.0; LLSD &out = body["stats"]["net"]["out"]; out["kbytes"] = gMessageSystem->mTotalBytesOut / 1024.0; out["packets"] = (S32) gMessageSystem->mPacketsOut; out["compressed_packets"] = (S32) gMessageSystem->mCompressedPacketsOut; out["savings"] = (gMessageSystem->mUncompressedBytesOut - gMessageSystem->mCompressedBytesOut) / 1024.0; LLSD &fail = body["stats"]["failures"]; fail["send_packet"] = (S32) gMessageSystem->mSendPacketFailureCount; fail["dropped"] = (S32) gMessageSystem->mDroppedPackets; fail["resent"] = (S32) gMessageSystem->mResentPackets; fail["failed_resends"] = (S32) gMessageSystem->mFailedResendPackets; fail["off_circuit"] = (S32) gMessageSystem->mOffCircuitPackets; fail["invalid"] = (S32) gMessageSystem->mInvalidOnCircuitPackets; // Misc stats, two strings and two ints // These are not expecticed to persist across multiple releases // Comment any changes with your name and the expected release revision // If the current revision is recent, ping the previous author before overriding LLSD &misc = body["stats"]["misc"]; // Screen size so the UI team can figure out how big the widgets // appear and use a "typical" size for end user tests. S32 window_width = gViewerWindow->getWindowWidthRaw(); S32 window_height = gViewerWindow->getWindowHeightRaw(); S32 window_size = (window_width * window_height) / 1024; misc["string_1"] = llformat("%d", window_size); misc["string_2"] = llformat("Texture Time: %.2f, Total Time: %.2f", gTextureTimer.getElapsedTimeF32(), gFrameTimeSeconds); // misc["int_1"] = LLSD::Integer(gSavedSettings.getU32("RenderQualityPerformance")); // Steve: 1.21 // misc["int_2"] = LLSD::Integer(gFrameStalls); // Steve: 1.21 F32 unbaked_time = LLVOAvatar::sUnbakedTime * 1000.f / gFrameTimeSeconds; misc["int_1"] = LLSD::Integer(unbaked_time); // Steve: 1.22 F32 grey_time = LLVOAvatar::sGreyTime * 1000.f / gFrameTimeSeconds; misc["int_2"] = LLSD::Integer(grey_time); // Steve: 1.22 LL_INFOS() << "Misc Stats: int_1: " << misc["int_1"] << " int_2: " << misc["int_2"] << LL_ENDL; LL_INFOS() << "Misc Stats: string_1: " << misc["string_1"] << " string_2: " << misc["string_2"] << LL_ENDL; const S32 namesys = gSavedSettings.getS32("PhoenixNameSystem"); body["DisplayNamesEnabled"] = namesys > 0 && namesys < 4; body["DisplayNamesShowUsername"] = namesys == 1 || namesys == 3; body["MinimalSkin"] = false; LLViewerStats::getInstance()->addToMessage(body); LLHTTPClient::post(url, body, new ViewerStatsResponder); }
void update_statistics() { gTotalWorldBytes += gVLManager.getTotalBytes(); gTotalObjectBytes += gObjectBits / 8; LLViewerStats& stats = LLViewerStats::instance(); // make sure we have a valid time delta for this frame if (gFrameIntervalSeconds > 0.f) { if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) { LLViewerStats::getInstance()->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds); } else if (gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR) { LLViewerStats::getInstance()->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds); } else if (gFloaterTools && gFloaterTools->getVisible()) { LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds); } } stats.setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); stats.setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail()); stats.setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip")); stats.setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles")); #if 0 // 1.9.2 LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_OBJECTS, (F64)gSavedSettings.getS32("VertexShaderLevelObject")); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_AVATAR, (F64)gSavedSettings.getBOOL("VertexShaderLevelAvatar")); LLViewerStats::getInstance()->setStat(LLViewerStats::ST_SHADER_ENVIRONMENT, (F64)gSavedSettings.getBOOL("VertexShaderLevelEnvironment")); #endif stats.setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame")); F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle"); F64 network_secs = gDebugView->mFastTimerView->getTime("Network"); stats.setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs); stats.setStat(LLViewerStats::ST_NETWORK_SECS, network_secs); stats.setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images")); stats.setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State")); stats.setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry")); LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost()); if (cdp) { stats.mSimPingStat.addValue(cdp->getPingDelay()); gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1); gSimPingCount++; } else { stats.mSimPingStat.addValue(10000); } stats.mFPSStat.addValue(1); F32 layer_bits = (F32)(gVLManager.getLandBits() + gVLManager.getWindBits() + gVLManager.getCloudBits()); stats.mLayersKBitStat.addValue(layer_bits/1024.f); stats.mObjectKBitStat.addValue(gObjectBits/1024.f); stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending()); stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f); gTransferManager.resetTransferBitsIn(LLTCT_ASSET); if (LLAppViewer::getTextureFetch()->getNumRequests() == 0) { gTextureTimer.pause(); } else { gTextureTimer.unpause(); } { static F32 visible_avatar_frames = 0.f; static F32 avg_visible_avatars = 0; F32 visible_avatars = (F32)LLVOAvatar::sNumVisibleAvatars; if (visible_avatars > 0.f) { visible_avatar_frames = 1.f; avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames; } stats.setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars); } LLWorld::getInstance()->updateNetStats(); LLWorld::getInstance()->requestCacheMisses(); // Reset all of these values. gVLManager.resetBitCounts(); gObjectBits = 0; // gDecodedBits = 0; // Only update texture stats periodically so that they are less noisy { static const F32 texture_stats_freq = 0.25f; static LLFrameTimer texture_stats_timer; if (texture_stats_timer.getElapsedTimeF32() >= texture_stats_freq) { stats.mHTTPTextureKBitStat.addValue(AICurlInterface::getHTTPBandwidth()/125.f); stats.mUDPTextureKBitStat.addValue(LLViewerTextureList::sTextureBits/1024.f); stats.mTexturePacketsStat.addValue(LLViewerTextureList::sTexturePackets); gTotalTextureBytes += LLViewerTextureList::sTextureBits / 8; LLViewerTextureList::sTextureBits = 0; LLViewerTextureList::sTexturePackets = 0; texture_stats_timer.reset(); } } { static const F32 mem_stats_freq = 10.f; static LLFrameTimer mem_stats_timer; if (mem_stats_timer.getElapsedTimeF32() >= mem_stats_freq) { stats.mMallocStat.addValue(SGMemStat::getMalloc()/1024.f/1024.f); mem_stats_timer.reset(); } } }
void LLNetMap::draw() { static LLFrameTimer map_timer; static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white); static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white); static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white); //static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white); static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white); static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white); if (mObjectImagep.isNull()) { createObjectImage(); } static LLUICachedControl<bool> auto_center("MiniMapAutoCenter", true); if (auto_center) { mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f)); } // Prepare a scissor region F32 rotation = 0; gGL.pushMatrix(); gGL.pushUIMatrix(); LLVector3 offset = gGL.getUITranslation(); LLVector3 scale = gGL.getUIScale(); gGL.loadIdentity(); gGL.loadUIIdentity(); gGL.scalef(scale.mV[0], scale.mV[1], scale.mV[2]); gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]); { LLLocalClipRect clip(getLocalRect()); { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.matrixMode(LLRender::MM_MODELVIEW); // Draw background rectangle LLColor4 background_color = mBackgroundColor.get(); gGL.color4fv( background_color.mV ); gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0); } // region 0,0 is in the middle S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPan.mV[VX]); S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPan.mV[VY]); gGL.pushMatrix(); gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f); static LLUICachedControl<bool> rotate_map("MiniMapRotate", true); if( rotate_map ) { // rotate subsequent draws to agent rotation rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); gGL.rotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f); } // figure out where agent is S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters()); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* regionp = *iter; // Find x and y position relative to camera's center. LLVector3 origin_agent = regionp->getOriginAgent(); LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent(); F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale; F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale; // background region rectangle F32 bottom = relative_y; F32 left = relative_x; F32 top = bottom + mScale ; F32 right = left + mScale ; if (regionp == gAgent.getRegion()) { gGL.color4f(1.f, 1.f, 1.f, 1.f); } else { gGL.color4f(0.8f, 0.8f, 0.8f, 1.f); } if (!regionp->isAlive()) { gGL.color4f(1.f, 0.5f, 0.5f, 1.f); } // Draw using texture. gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture()); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); gGL.end(); // Draw water gGL.setAlphaRejectSettings(LLRender::CF_GREATER, ABOVE_WATERLINE_ALPHA / 255.f); { if (regionp->getLand().getWaterTexture()) { gGL.getTexUnit(0)->bind(regionp->getLand().getWaterTexture()); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); gGL.end(); } } gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } // Redraw object layer periodically if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f)) { mUpdateNow = false; // Locate the centre of the object layer, accounting for panning LLVector3 new_center = globalPosToView(gAgentCamera.getCameraPositionGlobal()); new_center.mV[VX] -= mCurPan.mV[VX]; new_center.mV[VY] -= mCurPan.mV[VY]; new_center.mV[VZ] = 0.f; mObjectImageCenterGlobal = viewPosToGlobal(llfloor(new_center.mV[VX]), llfloor(new_center.mV[VY])); // Create the base texture. U8 *default_texture = mObjectRawImagep->getData(); memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() ); // Draw objects gObjectList.renderObjectsForMap(*this); mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight()); map_timer.reset(); } LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); LLVector3 camera_position = gAgentCamera.getCameraPositionAgent(); map_center_agent -= camera_position; map_center_agent.mV[VX] *= mScale/region_width; map_center_agent.mV[VY] *= mScale/region_width; gGL.getTexUnit(0)->bind(mObjectImagep); F32 image_half_width = 0.5f*mObjectMapPixels; F32 image_half_height = 0.5f*mObjectMapPixels; gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]); gGL.end(); gGL.popMatrix(); // Mouse pointer in local coordinates S32 local_mouse_x; S32 local_mouse_y; //localMouse(&local_mouse_x, &local_mouse_y); LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y); mClosestAgentToCursor.setNull(); F32 closest_dist_squared = F32_MAX; // value will be overridden in the loop F32 min_pick_dist_squared = (mDotRadius * MIN_PICK_SCALE) * (mDotRadius * MIN_PICK_SCALE); LLVector3 pos_map; uuid_vec_t avatar_ids; std::vector<LLVector3d> positions; bool unknown_relative_z; LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgentCamera.getCameraPositionGlobal()); // Draw avatars for (U32 i = 0; i < avatar_ids.size(); i++) { LLUUID uuid = avatar_ids[i]; // Skip self, we'll draw it later if (uuid == gAgent.getID()) continue; pos_map = globalPosToView(positions[i]); bool show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(uuid) != NULL); LLColor4 color = show_as_friend ? map_avatar_friend_color : map_avatar_color; unknown_relative_z = positions[i].mdV[VZ] == COARSEUPDATE_MAX_Z && camera_position.mV[VZ] >= COARSEUPDATE_MAX_Z; LLWorldMapView::drawAvatar( pos_map.mV[VX], pos_map.mV[VY], color, pos_map.mV[VZ], mDotRadius, unknown_relative_z); if(uuid.notNull()) { bool selected = false; uuid_vec_t::iterator sel_iter = gmSelected.begin(); for (; sel_iter != gmSelected.end(); sel_iter++) { if(*sel_iter == uuid) { selected = true; break; } } if(selected) { if( (pos_map.mV[VX] < 0) || (pos_map.mV[VY] < 0) || (pos_map.mV[VX] >= getRect().getWidth()) || (pos_map.mV[VY] >= getRect().getHeight()) ) { S32 x = ll_round( pos_map.mV[VX] ); S32 y = ll_round( pos_map.mV[VY] ); LLWorldMapView::drawTrackingCircle( getRect(), x, y, color, 1, 10); } else { LLWorldMapView::drawTrackingDot(pos_map.mV[VX],pos_map.mV[VY],color,0.f); } } } F32 dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y)); if(dist_to_cursor_squared < min_pick_dist_squared && dist_to_cursor_squared < closest_dist_squared) { closest_dist_squared = dist_to_cursor_squared; mClosestAgentToCursor = uuid; } } // Draw dot for autopilot target if (gAgent.getAutoPilot()) { drawTracking( gAgent.getAutoPilotTargetGlobal(), map_track_color ); } else { LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); if ( LLTracker::TRACKING_AVATAR == tracking_status ) { drawTracking( LLAvatarTracker::instance().getGlobalPos(), map_track_color ); } else if ( LLTracker::TRACKING_LANDMARK == tracking_status || LLTracker::TRACKING_LOCATION == tracking_status ) { drawTracking( LLTracker::getTrackedPositionGlobal(), map_track_color ); } } // Draw dot for self avatar position LLVector3d pos_global = gAgent.getPositionGlobal(); pos_map = globalPosToView(pos_global); S32 dot_width = ll_round(mDotRadius * 2.f); LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage; if (you) { you->draw(ll_round(pos_map.mV[VX] - mDotRadius), ll_round(pos_map.mV[VY] - mDotRadius), dot_width, dot_width); F32 dist_to_cursor_squared = dist_vec_squared(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y)); if(dist_to_cursor_squared < min_pick_dist_squared && dist_to_cursor_squared < closest_dist_squared) { mClosestAgentToCursor = gAgent.getID(); } } // Draw frustum F32 meters_to_pixels = mScale/ LLWorld::getInstance()->getRegionWidthInMeters(); F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); F32 far_clip_pixels = far_clip_meters * meters_to_pixels; F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); F32 half_width_pixels = half_width_meters * meters_to_pixels; F32 ctr_x = (F32)center_sw_left; F32 ctr_y = (F32)center_sw_bottom; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); if( rotate_map ) { gGL.color4fv((map_frustum_color()).mV); gGL.begin( LLRender::TRIANGLES ); gGL.vertex2f( ctr_x, ctr_y ); gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels ); gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels ); gGL.end(); } else { gGL.color4fv((map_frustum_rotating_color()).mV); // If we don't rotate the map, we have to rotate the frustum. gGL.pushMatrix(); gGL.translatef( ctr_x, ctr_y, 0 ); gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); gGL.begin( LLRender::TRIANGLES ); gGL.vertex2f( 0, 0 ); gGL.vertex2f( -half_width_pixels, far_clip_pixels ); gGL.vertex2f( half_width_pixels, far_clip_pixels ); gGL.end(); gGL.popMatrix(); } } gGL.popMatrix(); gGL.popUIMatrix(); LLUICtrl::draw(); }
void LLNetMap::draw() { static LLFrameTimer map_timer; if (mObjectImagep.isNull()) { createObjectImage(); } mCurPanX = lerp(mCurPanX, mTargetPanX, LLCriticalDamp::getInterpolant(0.1f)); mCurPanY = lerp(mCurPanY, mTargetPanY, LLCriticalDamp::getInterpolant(0.1f)); // Prepare a scissor region F32 rotation = 0; { LLGLEnable scissor(GL_SCISSOR_TEST); { LLGLSNoTexture no_texture; LLLocalClipRect clip(getLocalRect()); glMatrixMode(GL_MODELVIEW); // Draw background rectangle gGL.color4fv( mBackgroundColor.mV ); gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0); } // region 0,0 is in the middle S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPanX); S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPanY); gGL.pushMatrix(); gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f); if( LLNetMap::sRotateMap ) { // rotate subsequent draws to agent rotation rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); glRotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f); } // figure out where agent is S32 region_width = llround(LLWorld::getInstance()->getRegionWidthInMeters()); for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->mActiveRegionList.begin(); iter != LLWorld::getInstance()->mActiveRegionList.end(); ++iter) { LLViewerRegion* regionp = *iter; // Find x and y position relative to camera's center. LLVector3 origin_agent = regionp->getOriginAgent(); LLVector3 rel_region_pos = origin_agent - gAgent.getCameraPositionAgent(); F32 relative_x = (rel_region_pos.mV[0] / region_width) * gMiniMapScale; F32 relative_y = (rel_region_pos.mV[1] / region_width) * gMiniMapScale; // background region rectangle F32 bottom = relative_y; F32 left = relative_x; F32 top = bottom + gMiniMapScale ; F32 right = left + gMiniMapScale ; if (regionp == gAgent.getRegion()) { gGL.color4f(1.f, 1.f, 1.f, 1.f); } else { gGL.color4f(0.8f, 0.8f, 0.8f, 1.f); } if (!regionp->isAlive()) { gGL.color4f(1.f, 0.5f, 0.5f, 1.f); } // Draw using texture. LLViewerImage::bindTexture(regionp->getLand().getSTexture()); gGL.begin(LLVertexBuffer::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); gGL.end(); // Draw water gGL.setAlphaRejectSettings(LLRender::CF_GREATER, ABOVE_WATERLINE_ALPHA / 255.f); { if (regionp->getLand().getWaterTexture()) { LLViewerImage::bindTexture(regionp->getLand().getWaterTexture()); gGL.begin(LLVertexBuffer::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); gGL.end(); } } gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } LLVector3d old_center = mObjectImageCenterGlobal; LLVector3d new_center = gAgent.getCameraPositionGlobal(); new_center.mdV[0] = (5.f/mObjectMapTPM)*floor(0.2f*mObjectMapTPM*new_center.mdV[0]); new_center.mdV[1] = (5.f/mObjectMapTPM)*floor(0.2f*mObjectMapTPM*new_center.mdV[1]); new_center.mdV[2] = 0.f; if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f)) { mUpdateNow = FALSE; mObjectImageCenterGlobal = new_center; // Center moved enough. // Create the base texture. U8 *default_texture = mObjectRawImagep->getData(); memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() ); // Draw buildings gObjectList.renderObjectsForMap(*this); mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight()); map_timer.reset(); } LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); map_center_agent -= gAgent.getCameraPositionAgent(); map_center_agent.mV[VX] *= gMiniMapScale/region_width; map_center_agent.mV[VY] *= gMiniMapScale/region_width; LLViewerImage::bindTexture(mObjectImagep); F32 image_half_width = 0.5f*mObjectMapPixels; F32 image_half_height = 0.5f*mObjectMapPixels; gGL.begin(LLVertexBuffer::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]); gGL.end(); gGL.popMatrix(); LLVector3d pos_global; LLVector3 pos_map; // Draw avatars for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->mActiveRegionList.begin(); iter != LLWorld::getInstance()->mActiveRegionList.end(); ++iter) { LLViewerRegion* regionp = *iter; const LLVector3d& origin_global = regionp->getOriginGlobal(); S32 count = regionp->mMapAvatars.count(); S32 i; LLVector3 pos_local; U32 compact_local; U8 bits; // TODO: it'd be very cool to draw these in sorted order from lowest Z to highest. // just be careful to sort the avatar IDs along with the positions. -MG for (i = 0; i < count; i++) { compact_local = regionp->mMapAvatars.get(i); bits = compact_local & 0xFF; pos_local.mV[VZ] = F32(bits) * 4.f; compact_local >>= 8; bits = compact_local & 0xFF; pos_local.mV[VY] = (F32)bits; compact_local >>= 8; bits = compact_local & 0xFF; pos_local.mV[VX] = (F32)bits; pos_global.setVec( pos_local ); pos_global += origin_global; pos_map = globalPosToView(pos_global); BOOL show_as_friend = FALSE; if( i < regionp->mMapAvatarIDs.count()) { show_as_friend = is_agent_friend(regionp->mMapAvatarIDs.get(i)); } LLWorldMapView::drawAvatar( pos_map.mV[VX], pos_map.mV[VY], show_as_friend ? gFriendMapColor : gAvatarMapColor, pos_map.mV[VZ]); } } // Draw dot for autopilot target if (gAgent.getAutoPilot()) { drawTracking( gAgent.getAutoPilotTargetGlobal(), gTrackColor ); } else { LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); if ( LLTracker::TRACKING_AVATAR == tracking_status ) { drawTracking( LLAvatarTracker::instance().getGlobalPos(), gTrackColor ); } else if ( LLTracker::TRACKING_LANDMARK == tracking_status || LLTracker::TRACKING_LOCATION == tracking_status ) { drawTracking( LLTracker::getTrackedPositionGlobal(), gTrackColor ); } } // Draw dot for self avatar position pos_global = gAgent.getPositionGlobal(); pos_map = globalPosToView(pos_global); LLUIImagePtr you = LLWorldMapView::sAvatarYouSmallImage; you->draw( llround(pos_map.mV[VX]) - you->getWidth()/2, llround(pos_map.mV[VY]) - you->getHeight()/2); // Draw frustum F32 meters_to_pixels = gMiniMapScale/ LLWorld::getInstance()->getRegionWidthInMeters(); F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); F32 far_clip_pixels = far_clip_meters * meters_to_pixels; F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); F32 half_width_pixels = half_width_meters * meters_to_pixels; F32 ctr_x = (F32)center_sw_left; F32 ctr_y = (F32)center_sw_bottom; LLGLSNoTexture no_texture; if( LLNetMap::sRotateMap ) { gGL.color4fv(gFrustumMapColor.mV); gGL.begin( LLVertexBuffer::TRIANGLES ); gGL.vertex2f( ctr_x, ctr_y ); gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels ); gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels ); gGL.end(); } else { gGL.color4fv(gRotatingFrustumMapColor.mV); // If we don't rotate the map, we have to rotate the frustum. gGL.pushMatrix(); gGL.translatef( ctr_x, ctr_y, 0 ); glRotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); gGL.begin( LLVertexBuffer::TRIANGLES ); gGL.vertex2f( 0, 0 ); gGL.vertex2f( -half_width_pixels, far_clip_pixels ); gGL.vertex2f( half_width_pixels, far_clip_pixels ); gGL.end(); gGL.popMatrix(); } } // Rotation of 0 means that North is up setDirectionPos( mTextBoxEast, rotation ); setDirectionPos( mTextBoxNorth, rotation + F_PI_BY_TWO ); setDirectionPos( mTextBoxWest, rotation + F_PI ); setDirectionPos( mTextBoxSouth, rotation + F_PI + F_PI_BY_TWO ); setDirectionPos( mTextBoxNorthEast, rotation + F_PI_BY_TWO / 2); setDirectionPos( mTextBoxNorthWest, rotation + F_PI_BY_TWO + F_PI_BY_TWO / 2); setDirectionPos( mTextBoxSouthWest, rotation + F_PI + F_PI_BY_TWO / 2); setDirectionPos( mTextBoxSouthEast, rotation + F_PI + F_PI_BY_TWO + F_PI_BY_TWO / 2); LLUICtrl::draw(); }
void LLNetMap::draw() { static LLFrameTimer map_timer; static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white); static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white); static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white); static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white); static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white); static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white); if (mObjectImagep.isNull()) { createObjectImage(); } mCurPanX = lerp(mCurPanX, mTargetPanX, LLCriticalDamp::getInterpolant(0.1f)); mCurPanY = lerp(mCurPanY, mTargetPanY, LLCriticalDamp::getInterpolant(0.1f)); // Prepare a scissor region F32 rotation = 0; gGL.pushMatrix(); gGL.pushUIMatrix(); LLVector3 offset = gGL.getUITranslation(); LLVector3 scale = gGL.getUIScale(); glLoadIdentity(); gGL.loadUIIdentity(); glScalef(scale.mV[0], scale.mV[1], scale.mV[2]); gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]); { LLLocalClipRect clip(getLocalRect()); { gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); glMatrixMode(GL_MODELVIEW); // Draw background rectangle LLColor4 background_color = mBackgroundColor.get(); gGL.color4fv( background_color.mV ); gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0); } // region 0,0 is in the middle S32 center_sw_left = getRect().getWidth() / 2 + llfloor(mCurPanX); S32 center_sw_bottom = getRect().getHeight() / 2 + llfloor(mCurPanY); gGL.pushMatrix(); gGL.translatef( (F32) center_sw_left, (F32) center_sw_bottom, 0.f); static LLUICachedControl<bool> rotate_map("MiniMapRotate", true); if( rotate_map ) { // rotate subsequent draws to agent rotation rotation = atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ); glRotatef( rotation * RAD_TO_DEG, 0.f, 0.f, 1.f); } // figure out where agent is S32 region_width = llround(LLWorld::getInstance()->getRegionWidthInMeters()); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* regionp = *iter; // Find x and y position relative to camera's center. LLVector3 origin_agent = regionp->getOriginAgent(); LLVector3 rel_region_pos = origin_agent - gAgent.getCameraPositionAgent(); F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale; F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale; // background region rectangle F32 bottom = relative_y; F32 left = relative_x; F32 top = bottom + mScale ; F32 right = left + mScale ; if (regionp == gAgent.getRegion()) { gGL.color4f(1.f, 1.f, 1.f, 1.f); } else { gGL.color4f(0.8f, 0.8f, 0.8f, 1.f); } if (!regionp->isAlive()) { gGL.color4f(1.f, 0.5f, 0.5f, 1.f); } // Draw using texture. gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture()); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); gGL.end(); // Draw water gGL.setAlphaRejectSettings(LLRender::CF_GREATER, ABOVE_WATERLINE_ALPHA / 255.f); { if (regionp->getLand().getWaterTexture()) { gGL.getTexUnit(0)->bind(regionp->getLand().getWaterTexture()); gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(left, top); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(left, bottom); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(right, bottom); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(right, top); gGL.end(); } } gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } LLVector3d old_center = mObjectImageCenterGlobal; LLVector3d new_center = gAgent.getCameraPositionGlobal(); new_center.mdV[0] = (5.f/mObjectMapTPM)*floor(0.2f*mObjectMapTPM*new_center.mdV[0]); new_center.mdV[1] = (5.f/mObjectMapTPM)*floor(0.2f*mObjectMapTPM*new_center.mdV[1]); new_center.mdV[2] = 0.f; if (mUpdateNow || (map_timer.getElapsedTimeF32() > 0.5f)) { mUpdateNow = FALSE; mObjectImageCenterGlobal = new_center; // Center moved enough. // Create the base texture. U8 *default_texture = mObjectRawImagep->getData(); memset( default_texture, 0, mObjectImagep->getWidth() * mObjectImagep->getHeight() * mObjectImagep->getComponents() ); // Draw buildings gObjectList.renderObjectsForMap(*this); mObjectImagep->setSubImage(mObjectRawImagep, 0, 0, mObjectImagep->getWidth(), mObjectImagep->getHeight()); map_timer.reset(); } LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); map_center_agent -= gAgent.getCameraPositionAgent(); map_center_agent.mV[VX] *= mScale/region_width; map_center_agent.mV[VY] *= mScale/region_width; gGL.getTexUnit(0)->bind(mObjectImagep); F32 image_half_width = 0.5f*mObjectMapPixels; F32 image_half_height = 0.5f*mObjectMapPixels; gGL.begin(LLRender::QUADS); gGL.texCoord2f(0.f, 1.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, image_half_height + map_center_agent.mV[VY]); gGL.texCoord2f(0.f, 0.f); gGL.vertex2f(map_center_agent.mV[VX] - image_half_width, map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 0.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], map_center_agent.mV[VY] - image_half_height); gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]); gGL.end(); gGL.popMatrix(); LLVector3d pos_global; LLVector3 pos_map; // Mouse pointer in local coordinates S32 local_mouse_x; S32 local_mouse_y; //localMouse(&local_mouse_x, &local_mouse_y); LLUI::getMousePositionLocal(this, &local_mouse_x, &local_mouse_y); mClosestAgentToCursor.setNull(); F32 closest_dist = F32_MAX; F32 min_pick_dist = mDotRadius * MIN_PICK_SCALE; // Draw avatars for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* regionp = *iter; const LLVector3d& origin_global = regionp->getOriginGlobal(); S32 count = regionp->mMapAvatars.count(); S32 i; LLVector3 pos_local; U32 compact_local; U8 bits; // TODO: it'd be very cool to draw these in sorted order from lowest Z to highest. // just be careful to sort the avatar IDs along with the positions. -MG for (i = 0; i < count; i++) { compact_local = regionp->mMapAvatars.get(i); bits = compact_local & 0xFF; pos_local.mV[VZ] = F32(bits) * 4.f; compact_local >>= 8; bits = compact_local & 0xFF; pos_local.mV[VY] = (F32)bits; compact_local >>= 8; bits = compact_local & 0xFF; pos_local.mV[VX] = (F32)bits; pos_global.setVec( pos_local ); pos_global += origin_global; pos_map = globalPosToView(pos_global); BOOL show_as_friend = FALSE; if( i < regionp->mMapAvatarIDs.count()) { show_as_friend = (LLAvatarTracker::instance().getBuddyInfo(regionp->mMapAvatarIDs.get(i)) != NULL); } LLWorldMapView::drawAvatar( pos_map.mV[VX], pos_map.mV[VY], show_as_friend ? map_avatar_friend_color : map_avatar_color, pos_map.mV[VZ], mDotRadius); F32 dist_to_cursor = dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y)); if(dist_to_cursor < min_pick_dist && dist_to_cursor < closest_dist) { closest_dist = dist_to_cursor; mClosestAgentToCursor = regionp->mMapAvatarIDs.get(i); } } } // Draw dot for autopilot target if (gAgent.getAutoPilot()) { drawTracking( gAgent.getAutoPilotTargetGlobal(), map_track_color ); } else { LLTracker::ETrackingStatus tracking_status = LLTracker::getTrackingStatus(); if ( LLTracker::TRACKING_AVATAR == tracking_status ) { drawTracking( LLAvatarTracker::instance().getGlobalPos(), map_track_color ); } else if ( LLTracker::TRACKING_LANDMARK == tracking_status || LLTracker::TRACKING_LOCATION == tracking_status ) { drawTracking( LLTracker::getTrackedPositionGlobal(), map_track_color ); } } // Draw dot for self avatar position pos_global = gAgent.getPositionGlobal(); pos_map = globalPosToView(pos_global); LLUIImagePtr you = LLWorldMapView::sAvatarYouLargeImage; S32 dot_width = llround(mDotRadius * 2.f); you->draw(llround(pos_map.mV[VX] - mDotRadius), llround(pos_map.mV[VY] - mDotRadius), dot_width, dot_width); // Draw frustum F32 meters_to_pixels = mScale/ LLWorld::getInstance()->getRegionWidthInMeters(); F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); F32 far_clip_pixels = far_clip_meters * meters_to_pixels; F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); F32 half_width_pixels = half_width_meters * meters_to_pixels; F32 ctr_x = (F32)center_sw_left; F32 ctr_y = (F32)center_sw_bottom; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); if( rotate_map ) { gGL.color4fv((map_frustum_color()).mV); gGL.begin( LLRender::TRIANGLES ); gGL.vertex2f( ctr_x, ctr_y ); gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels ); gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels ); gGL.end(); } else { gGL.color4fv((map_frustum_rotating_color()).mV); // If we don't rotate the map, we have to rotate the frustum. gGL.pushMatrix(); gGL.translatef( ctr_x, ctr_y, 0 ); glRotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); gGL.begin( LLRender::TRIANGLES ); gGL.vertex2f( 0, 0 ); gGL.vertex2f( -half_width_pixels, far_clip_pixels ); gGL.vertex2f( half_width_pixels, far_clip_pixels ); gGL.end(); gGL.popMatrix(); } } gGL.popMatrix(); gGL.popUIMatrix(); LLUICtrl::draw(); }
// Paint the display! void display(BOOL rebuild, F32 zoom_factor, int subfield) { LLFastTimer t(LLFastTimer::FTM_RENDER); LLGLSDefault gls_default; LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL); // No clue where this is getting unset, but safe enough to reset it here. LLGLState::resetTextureStates(); #ifndef LL_RELEASE_FOR_DOWNLOAD LLGLState::checkStates(); LLGLState::checkTextureChannels(); #endif gPipeline.disableLights(); // Don't draw if the window is hidden or minimized. // In fact, must explicitly check the minimized state before drawing. // Attempting to draw into a minimized window causes a GL error. JC if ( !gViewerWindow->getActive() || !gViewerWindow->mWindow->getVisible() || gViewerWindow->mWindow->getMinimized() ) { // Clean up memory the pools may have allocated if (rebuild) { gFrameStats.start(LLFrameStats::REBUILD); gPipeline.rebuildPools(); } return; } gViewerWindow->checkSettings(); gViewerWindow->performPick(); #ifndef LL_RELEASE_FOR_DOWNLOAD LLGLState::checkStates(); LLGLState::checkTextureChannels(); #endif ////////////////////////////////////////////////////////// // // Logic for forcing window updates if we're in drone mode. // if (gNoRender) { #if LL_WINDOWS static F32 last_update_time = 0.f; if ((gFrameTimeSeconds - last_update_time) > 1.f) { InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE); last_update_time = gFrameTimeSeconds; } #elif LL_DARWIN // MBW -- Do something clever here. #endif // Not actually rendering, don't bother. return; } // // Bail out if we're in the startup state and don't want to try to // render the world. // if (LLStartUp::getStartupState() < STATE_STARTED) { display_startup(); return; } //LLGLState::verify(FALSE); ///////////////////////////////////////////////// // // Update GL Texture statistics (used for discard logic?) // gFrameStats.start(LLFrameStats::UPDATE_TEX_STATS); stop_glerror(); LLImageGL::updateStats(gFrameTimeSeconds); LLVOAvatar::sRenderName = gSavedSettings.getS32("RenderName"); LLVOAvatar::sRenderGroupTitles = gSavedSettings.getBOOL("RenderGroupTitleAll"); gPipeline.mBackfaceCull = TRUE; gFrameCount++; if (gFocusMgr.getAppHasFocus()) { gForegroundFrameCount++; } ////////////////////////////////////////////////////////// // // Display start screen if we're teleporting, and skip render // if (gTeleportDisplay) { const F32 TELEPORT_ARRIVAL_DELAY = 2.f; // Time to preload the world before raising the curtain after we've actually already arrived. S32 attach_count = 0; if (gAgent.getAvatarObject()) { attach_count = gAgent.getAvatarObject()->getAttachmentCount(); } F32 teleport_save_time = TELEPORT_EXPIRY + TELEPORT_EXPIRY_PER_ATTACHMENT * attach_count; F32 teleport_elapsed = gTeleportDisplayTimer.getElapsedTimeF32(); F32 teleport_percent = teleport_elapsed * (100.f / teleport_save_time); if( (gAgent.getTeleportState() != LLAgent::TELEPORT_START) && (teleport_percent > 100.f) ) { // Give up. Don't keep the UI locked forever. gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); gAgent.setTeleportMessage(""); } const LLString& message = gAgent.getTeleportMessage(); switch( gAgent.getTeleportState() ) { case LLAgent::TELEPORT_START: // Transition to REQUESTED. Viewer has sent some kind // of TeleportRequest to the source simulator gTeleportDisplayTimer.reset(); gViewerWindow->setShowProgress(TRUE); gViewerWindow->setProgressPercent(0); gAgent.setTeleportState( LLAgent::TELEPORT_REQUESTED ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["requesting"]); break; case LLAgent::TELEPORT_REQUESTED: // Waiting for source simulator to respond gViewerWindow->setProgressPercent( llmin(teleport_percent, 37.5f) ); gViewerWindow->setProgressString(message); break; case LLAgent::TELEPORT_MOVING: // Viewer has received destination location from source simulator gViewerWindow->setProgressPercent( llmin(teleport_percent, 75.f) ); gViewerWindow->setProgressString(message); break; case LLAgent::TELEPORT_START_ARRIVAL: // Transition to ARRIVING. Viewer has received avatar update, etc., from destination simulator gTeleportArrivalTimer.reset(); gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel"); gViewerWindow->setProgressPercent(75.f); gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING ); gAgent.setTeleportMessage( LLAgent::sTeleportProgressMessages["arriving"]); gImageList.mForceResetTextureStats = TRUE; break; case LLAgent::TELEPORT_ARRIVING: // Make the user wait while content "pre-caches" { F32 arrival_fraction = (gTeleportArrivalTimer.getElapsedTimeF32() / TELEPORT_ARRIVAL_DELAY); if( arrival_fraction > 1.f ) { arrival_fraction = 1.f; gAgent.setTeleportState( LLAgent::TELEPORT_NONE ); } gViewerWindow->setProgressCancelButtonVisible(FALSE, "Cancel"); gViewerWindow->setProgressPercent( arrival_fraction * 25.f + 75.f); gViewerWindow->setProgressString(message); } break; case LLAgent::TELEPORT_NONE: // No teleport in progress gViewerWindow->setShowProgress(FALSE); gTeleportDisplay = FALSE; break; } } else if(LLAppViewer::instance()->logoutRequestSent()) { F32 percent_done = gLogoutTimer.getElapsedTimeF32() * 100.f / gLogoutMaxTime; if (percent_done > 100.f) { percent_done = 100.f; } if( LLApp::isExiting() ) { percent_done = 100.f; } gViewerWindow->setProgressPercent( percent_done ); } else if (gRestoreGL) { F32 percent_done = gRestoreGLTimer.getElapsedTimeF32() * 100.f / RESTORE_GL_TIME; if( percent_done > 100.f ) { gViewerWindow->setShowProgress(FALSE); gRestoreGL = FALSE; } else { if( LLApp::isExiting() ) { percent_done = 100.f; } gViewerWindow->setProgressPercent( percent_done ); } } ////////////////////////// // // Prepare for the next frame // // Hmm... Should this be moved elsewhere? - djs 09/09/02 // do render-to-texture stuff here if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES)) { // LLFastTimer t(LLFastTimer::FTM_UPDATE_TEXTURES); if (LLDynamicTexture::updateAllInstances()) { glClear(GL_COLOR_BUFFER_BIT); } } ///////////////////////////// // // Update the camera // // gCamera->setZoomParameters(zoom_factor, subfield); gCamera->setNear(MIN_NEAR_PLANE); ////////////////////////// // // clear the next buffer // (must follow dynamic texture writing since that uses the frame buffer) // if (gDisconnected) { glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); render_disconnected_background(); } else if (!gViewerWindow->isPickPending()) { glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT ); //DEBUG TEMPORARY glClear(GL_COLOR_BUFFER_BIT); } gViewerWindow->setupViewport(); ////////////////////////// // // Set rendering options // // stop_glerror(); if (gSavedSettings.getBOOL("ShowDepthBuffer")) { pre_show_depth_buffer(); } //MK if ((!RRenabled || !gAgent.mRRInterface.mContainsDetach) && gUseWireframe) //mk { glClearColor(0.5f, 0.5f, 0.5f, 0.f); glClear(GL_COLOR_BUFFER_BIT); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); LLPipeline::sUseOcclusion = FALSE; } else { LLPipeline::sUseOcclusion = gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery && gFeatureManagerp->isFeatureAvailable("UseOcclusion"); } stop_glerror(); /////////////////////////////////////// // // Slam lighting parameters back to our defaults. // Note that these are not the same as GL defaults... stop_glerror(); F32 one[4] = {1.f, 1.f, 1.f, 1.f}; glLightModelfv (GL_LIGHT_MODEL_AMBIENT,one); stop_glerror(); //Increment drawable frame counter LLDrawable::incrementVisible(); ///////////////////////////////////// // // Render // // Actually push all of our triangles to the screen. // if (!gDisconnected) { if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { //don't draw hud objects in this frame gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); } LLFastTimer t(LLFastTimer::FTM_WORLD_UPDATE); stop_glerror(); display_update_camera(); stop_glerror(); // *TODO: merge these two methods gHUDManager->updateEffects(); LLHUDObject::updateAll(); stop_glerror(); gFrameStats.start(LLFrameStats::UPDATE_GEOM); const F32 max_geom_update_time = 0.005f; // 5 ms update time gPipeline.updateGeom(max_geom_update_time); stop_glerror(); LLSpatialPartition* part = gPipeline.getSpatialPartition(LLPipeline::PARTITION_VOLUME); part->processImagery(gCamera); display_update_camera(); gFrameStats.start(LLFrameStats::UPDATE_CULL); gPipeline.updateCull(*gCamera); stop_glerror(); /////////////////////////////////// // // StateSort // // Responsible for taking visible objects, and adding them to the appropriate draw orders. // In the case of alpha objects, z-sorts them first. // Also creates special lists for outlines and selected face rendering. // { LLFastTimer t(LLFastTimer::FTM_REBUILD); gFrameStats.start(LLFrameStats::STATE_SORT); gPipeline.stateSort(*gCamera); stop_glerror(); if (rebuild) { ////////////////////////////////////// // // rebuildPools // // gFrameStats.start(LLFrameStats::REBUILD); gPipeline.rebuildPools(); stop_glerror(); } } } //// render frontmost floater opaque for occlusion culling purposes //LLFloater* frontmost_floaterp = gFloaterView->getFrontmost(); //// assumes frontmost floater with focus is opaque //if (frontmost_floaterp && gFocusMgr.childHasKeyboardFocus(frontmost_floaterp)) //{ // glMatrixMode(GL_MODELVIEW); // glPushMatrix(); // { // LLGLSNoTexture gls_no_texture; // glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); // glLoadIdentity(); // LLRect floater_rect = frontmost_floaterp->getScreenRect(); // // deflate by one pixel so rounding errors don't occlude outside of floater extents // floater_rect.stretch(-1); // LLRectf floater_3d_rect((F32)floater_rect.mLeft / (F32)gViewerWindow->getWindowWidth(), // (F32)floater_rect.mTop / (F32)gViewerWindow->getWindowHeight(), // (F32)floater_rect.mRight / (F32)gViewerWindow->getWindowWidth(), // (F32)floater_rect.mBottom / (F32)gViewerWindow->getWindowHeight()); // floater_3d_rect.translate(-0.5f, -0.5f); // glTranslatef(0.f, 0.f, -gCamera->getNear()); // glScalef(gCamera->getNear() * gCamera->getAspect() / sinf(gCamera->getView()), gCamera->getNear() / sinf(gCamera->getView()), 1.f); // glColor4fv(LLColor4::white.mV); // glBegin(GL_QUADS); // { // glVertex3f(floater_3d_rect.mLeft, floater_3d_rect.mBottom, 0.f); // glVertex3f(floater_3d_rect.mLeft, floater_3d_rect.mTop, 0.f); // glVertex3f(floater_3d_rect.mRight, floater_3d_rect.mTop, 0.f); // glVertex3f(floater_3d_rect.mRight, floater_3d_rect.mBottom, 0.f); // } // glEnd(); // glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // } // glPopMatrix(); //} if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot()) && !gRestoreGL && !gDisconnected) { gPipeline.renderGeom(*gCamera); stop_glerror(); } //render hud attachments glMatrixMode(GL_PROJECTION); glPushMatrix(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices(FALSE)) { LLCamera hud_cam = *gCamera; glClear(GL_DEPTH_BUFFER_BIT); LLVector3 origin = hud_cam.getOrigin(); hud_cam.setOrigin(-1.f,0,0); hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1)); LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE); //only render hud objects U32 mask = gPipeline.getRenderTypeMask(); gPipeline.setRenderTypeMask(0); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); BOOL has_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); if (has_ui) { gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); } BOOL use_occlusion = gSavedSettings.getBOOL("UseOcclusion"); gSavedSettings.setBOOL("UseOcclusion", FALSE); //cull, sort, and render hud objects gPipeline.updateCull(hud_cam); gPipeline.toggleRenderType(LLDrawPool::POOL_ALPHA_POST_WATER); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME); { LLFastTimer ftm(LLFastTimer::FTM_REBUILD); gPipeline.stateSort(hud_cam); } gPipeline.renderGeom(hud_cam); //restore type mask gPipeline.setRenderTypeMask(mask); if (has_ui) { gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); } gSavedSettings.setBOOL("UseOcclusion", use_occlusion); } glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); gFrameStats.start(LLFrameStats::RENDER_UI); if (gHandleKeysAsync) { process_keystrokes_async(); stop_glerror(); } #ifndef LL_RELEASE_FOR_DOWNLOAD LLGLState::checkStates(); #endif render_ui_and_swap(); #ifndef LL_RELEASE_FOR_DOWNLOAD LLGLState::checkStates(); #endif gFrameStats.start(LLFrameStats::MISC_END); stop_glerror(); }
void LLWLParamManager::update(LLViewerCamera * cam) { LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WLPARAM); // update clouds, sun, and general mCurParams.updateCloudScrolling(); // update only if running if(mAnimator.mIsRunning) { mAnimator.update(mCurParams); } // update the shaders and the menu propagateParameters(); // sync menus if they exist if(LLFloaterWindLight::isOpen()) { LLFloaterWindLight::instance()->syncMenu(); } if(LLFloaterDayCycle::isOpen()) { LLFloaterDayCycle::instance()->syncMenu(); } if(LLFloaterEnvSettings::isOpen()) { LLFloaterEnvSettings::instance()->syncMenu(); } F32 camYaw = cam->getYaw(); stop_glerror(); // *TODO: potential optimization - this block may only need to be // executed some of the time. For example for water shaders only. { F32 camYawDelta = mSunDeltaYaw * DEG_TO_RAD; LLVector3 lightNorm3(mLightDir); lightNorm3 *= LLQuaternion(-(camYaw + camYawDelta), LLVector3(0.f, 1.f, 0.f)); mRotatedLightDir = LLVector4(lightNorm3, 0.f); LLViewerShaderMgr::shader_iter shaders_iter, end_shaders; end_shaders = LLViewerShaderMgr::instance()->endShaders(); for(shaders_iter = LLViewerShaderMgr::instance()->beginShaders(); shaders_iter != end_shaders; ++shaders_iter) { if (shaders_iter->mProgramObject != 0 && (gPipeline.canUseWindLightShaders() || shaders_iter->mShaderGroup == LLGLSLShader::SG_WATER)) { shaders_iter->mUniformsDirty = TRUE; } } } //Mix windlight settings if needed if(sNeedsMix == TRUE) { if(sMixSet == NULL) { sNeedsMix = FALSE; return; } if (wlSmoothTransitionTimer.getElapsedTimeF32() >= (sMixTime / 100)) //100 steps inbetween { wlSmoothTransitionTimer.reset(); mCurParams.mix(mCurParams, *sMixSet, sMixCount / 100);//.01 to 1.0 } sMixCount++; if((sMixCount / 100) == 1) { //All done sNeedsMix = FALSE; std::string wlSkyPresetName = "(Region settings)"; mCurParams.mName = wlSkyPresetName; removeParamSet( wlSkyPresetName, true ); addParamSet( wlSkyPresetName, mCurParams ); savePreset( wlSkyPresetName ); mAnimator.mIsRunning = false; mAnimator.mUseLindenTime = false; loadPreset( wlSkyPresetName, true ); sMixSet = NULL; } } }