// <FS:CR Threaded Filepickers> //BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, bool blocking) // </FS:CR Threaded Filepickers> { if( mLocked ) return FALSE; BOOL success = FALSE; OSStatus error = noErr; // if local file browsing is turned off, return without opening dialog if ( check_local_file_access_enabled() == false ) { return FALSE; } reset(); mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; // Modal, so pause agent send_agent_pause(); { error = doNavSaveDialog(filter, filename); } send_agent_resume(); if (error == noErr) { if (getFileCount()) success = true; } // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; }
void LLFloaterColorPicker::showUI () { setVisible ( TRUE ); setFocus ( TRUE ); openFloater(getKey()); // HACK: if system color picker is required - close the SL one we made and use default system dialog if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) ) { LLColorSwatchCtrl* swatch = getSwatch (); setVisible ( FALSE ); // code that will get switched in for default system color picker if ( swatch ) { LLColor4 curCol = swatch->get (); send_agent_pause(); getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] ); send_agent_resume(); setOrigRgb ( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] ); setCurRgb( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] ); LLColorSwatchCtrl::onColorChanged ( swatch, LLColorSwatchCtrl::COLOR_CHANGE ); } closeFloater(); } }
BOOL LLDirPicker::getDir(std::string* filename) { if( mLocked ) return FALSE; BOOL success = FALSE; OSStatus error = noErr; // if local file browsing is turned off, return without opening dialog if ( check_local_file_access_enabled() == false ) { return FALSE; } mFileName = filename; // mNavOptions.saveFileName // Modal, so pause agent send_agent_pause(); { error = doNavChooseDialog(); } send_agent_resume(); if (error == noErr) { if (mDir.length() > 0) success = true; } // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; }
BOOL LLFilePicker::getOpenFile(ELoadFilter filter) { if( mLocked ) return FALSE; BOOL success = FALSE; OSStatus error = noErr; reset(); mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; if(filter == FFLOAD_APP) mNavOptions.optionFlags |= kNavSupportPackages; // Modal, so pause agent send_agent_pause(); { error = doNavChooseDialog(filter); } send_agent_resume(); if (error == noErr) { if (getFileCount()) success = true; } // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; }
BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) { if( mLocked ) return FALSE; BOOL success = FALSE; OSStatus error = noErr; reset(); mNavOptions.optionFlags |= kNavAllowMultipleFiles; // Modal, so pause agent send_agent_pause(); { error = doNavChooseDialog(filter); } send_agent_resume(); if (error == noErr) { if (mFiles.size()) success = true; if (mFiles.size() > 1) mLocked = TRUE; } // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; }
BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) { if( mLocked ) return FALSE; BOOL success = FALSE; OSStatus error = noErr; reset(); mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; // Modal, so pause agent send_agent_pause(); { error = doNavSaveDialog(filter, filename); } send_agent_resume(); if (error == noErr) { if (mFiles.size()) success = true; } // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; }
BOOL LLFilePicker::getOpenFile(ELoadFilter filter) { if( mLocked ) return FALSE; BOOL success = FALSE; OSStatus error = noErr; reset(); mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; if(filter == FFLOAD_ALL) // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful { // mNavOptions.optionFlags |= kNavAllowOpenPackages; mNavOptions.optionFlags |= kNavSupportPackages; } // Modal, so pause agent send_agent_pause(); { error = doNavChooseDialog(filter); } send_agent_resume(); if (error == noErr) { if (getFileCount()) success = true; } // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; }
BOOL LLDirPicker::getDir(std::string* filename, bool blocking) { if( mLocked ) return FALSE; BOOL success = FALSE; OSStatus error = noErr; mFileName = filename; // mNavOptions.saveFileName if (blocking) { // Modal, so pause agent send_agent_pause(); } { error = doNavChooseDialog(); } if (blocking) { send_agent_resume(); // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); } if (error == noErr) { if (mDir.length() > 0) success = TRUE; } return success; }
BOOL LLDirPicker::getDir(std::string* filename) { if( mLocked ) { return FALSE; } // if local file browsing is turned off, return without opening dialog if ( check_local_file_access_enabled() == false ) { return FALSE; } BOOL success = FALSE; // Modal, so pause agent send_agent_pause(); BROWSEINFO bi; memset(&bi, 0, sizeof(bi)); bi.ulFlags = BIF_USENEWUI; bi.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); bi.lpszTitle = NULL; ::OleInitialize(NULL); LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi); if(pIDL != NULL) { WCHAR buffer[_MAX_PATH] = {'\0'}; if(::SHGetPathFromIDList(pIDL, buffer) != 0) { // Set the string value. mDir = utf16str_to_utf8str(llutf16string(buffer)); success = TRUE; } // free the item id list CoTaskMemFree(pIDL); } ::OleUninitialize(); send_agent_resume(); // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; }
bool toggle_agent_pause(const LLSD& newvalue) { if ( newvalue.asBoolean() ) { send_agent_pause(); } else { send_agent_resume(); } return true; }
BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) { if( mLocked ) return FALSE; BOOL success = FALSE; // if local file browsing is turned off, return without opening dialog if ( check_local_file_access_enabled() == false ) { return FALSE; } OSStatus error = noErr; reset(); mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; if(filter == FFLOAD_ALL) // allow application bundles etc. to be traversed; important for DEV-16869, but generally useful { // mNavOptions.optionFlags |= kNavAllowOpenPackages; mNavOptions.optionFlags |= kNavSupportPackages; } if (blocking) { // Modal, so pause agent send_agent_pause(); } { error = doNavChooseDialog(filter); } if (error == noErr) { if (getFileCount()) success = true; } if (blocking) { send_agent_resume(); // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); } return success; }
BOOL LLFilePicker::getOpenFile(ELoadFilter filter, bool blocking) { if( mLocked ) { return FALSE; } BOOL success = FALSE; // if local file browsing is turned off, return without opening dialog if ( check_local_file_access_enabled() == false ) { return FALSE; } // don't provide default file selection mFilesW[0] = '\0'; mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); mOFN.lpstrFile = mFilesW; mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE; mOFN.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR ; mOFN.nFilterIndex = 1; setupFilter(filter); if (blocking) { // Modal, so pause agent send_agent_pause(); } reset(); // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! success = GetOpenFileName(&mOFN); if (success) { std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); mFiles.push_back(filename); } if (blocking) { send_agent_resume(); // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); } return success; }
// <FS:CR Threaded Filepickers> //BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter, bool blocking) // </FS:CR Threaded Filepickers> { if( mLocked ) return FALSE; BOOL success = FALSE; // if local file browsing is turned off, return without opening dialog if ( check_local_file_access_enabled() == false ) { return FALSE; } OSStatus error = noErr; reset(); mNavOptions.optionFlags |= kNavAllowMultipleFiles; // Modal, so pause agent // <FS:CR Threaded Filepickers> { send_agent_pause(); } // </FS:CR Threaded Filepickers> { error = doNavChooseDialog(filter); } // <FS:CR Threaded Filepickers> { send_agent_resume(); } // </FS:CR Threaded Filepickers> if (error == noErr) { if (getFileCount()) success = true; if (getFileCount() > 1) mLocked = true; } // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; }
OSStatus MovieMaker::setupMovie() { OSStatus error = noErr; FSRef fileRef; FSSpec fileSpec; rowBytes = width * 4; bufferSize = height * rowBytes; buffer = (char*)malloc(bufferSize); invertedBuffer = (char*)malloc(bufferSize); rect.left = 0; rect.top = 0; rect.right = width; rect.bottom = height; error = NewGWorldFromPtr(&gworld, k32ARGBPixelFormat, &rect, 0, 0, 0, buffer, rowBytes); if (error == noErr) { LockPixels(GetGWorldPixMap(gworld)); } // MBW -- I think this needs to happen after all the dialogs, etc. // if (error == noErr) // { // Microseconds(&lastFrameTime); // error = grabFrame(); // } if (error == noErr) { error = EnterMovies(); } if (error == noErr) { ci = OpenDefaultComponent(StandardCompressionType,StandardCompressionSubType); if(ci == NULL) error = paramErr; } if (error == noErr) { long flags; SCGetInfo(ci,scPreferenceFlagsType,&flags); flags &= ~scShowBestDepth; flags |= scAllowZeroFrameRate; SCSetInfo(ci,scPreferenceFlagsType,&flags); } if (error == noErr) { send_agent_pause(); gViewerWindow->mWindow->beforeDialog(); error = SCRequestSequenceSettings(ci); gViewerWindow->mWindow->afterDialog(); send_agent_resume(); if (error == scUserCancelled) { // deal with user cancelling. EndCapture(); } } if (error == noErr) { // This is stoopid. I have to take the passed full path, create the file so I can get an FSRef, and Get Info to get the FSSpec for QuickTime. Could Apple make this any more difficult... FILE* file = LLFile::fopen(fname, "w"); /* Flawfinder: ignore */ if (file) { fclose(file); error = FSPathMakeRef((UInt8*)fname, &fileRef, NULL); if (error == noErr) error = FSGetCatalogInfo(&fileRef, 0, NULL, NULL, &fileSpec, NULL); } else { error = paramErr; } } if (error == noErr) { error = CreateMovieFile(&fileSpec, 'TVOD', smCurrentScript, createMovieFileDeleteCurFile | createMovieFileDontCreateResFile, &movieResRef, &movie); } if (error == noErr) { track = NewMovieTrack(movie, FixRatio(width, 1), FixRatio(height, 1), kNoVolume); error = GetMoviesError(); } if (error == noErr) { media = NewTrackMedia(track, VideoMediaType, 600, NULL, 0); error = GetMoviesError(); } if (error == noErr) { Microseconds(&lastFrameTime); error = grabFrame(); } if (error == noErr) { error = SCCompressSequenceBegin(ci,GetPortPixMap(gworld),nil,&idh); } if (error == noErr) { error = BeginMediaEdits(media); } if (error != noErr) { media = NULL; } return error; }
// 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; }
// 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"); }
BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) { if( mLocked ) { return FALSE; } BOOL success = FALSE; mOFN.lpstrFile = mFilesW; if (!filename.empty()) { llutf16string tstring = utf8str_to_utf16str(filename); wcsncpy(mFilesW, tstring.c_str(), FILENAME_BUFFER_SIZE); } /*Flawfinder: ignore*/ else { mFilesW[0] = '\0'; } mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); switch( filter ) { case FFSAVE_ALL: mOFN.lpstrDefExt = NULL; mOFN.lpstrFilter = L"All Files (*.*)\0*.*\0" \ L"WAV Sounds (*.wav)\0*.wav\0" \ L"Targa, Bitmap Images (*.tga; *.bmp)\0*.tga;*.bmp\0" \ L"\0"; break; case FFSAVE_WAV: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.wav", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"wav"; mOFN.lpstrFilter = L"WAV Sounds (*.wav)\0*.wav\0" \ L"\0"; break; case FFSAVE_TGA: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.tga", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"tga"; mOFN.lpstrFilter = L"Targa Images (*.tga)\0*.tga\0" \ L"\0"; break; case FFSAVE_BMP: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.bmp", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"bmp"; mOFN.lpstrFilter = L"Bitmap Images (*.bmp)\0*.bmp\0" \ L"\0"; break; case FFSAVE_PNG: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"png"; mOFN.lpstrFilter = L"PNG Images (*.png)\0*.png\0" \ L"\0"; break; case FFSAVE_JPEG: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.jpeg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"jpg"; mOFN.lpstrFilter = L"JPEG Images (*.jpg *.jpeg)\0*.jpg;*.jpeg\0" \ L"\0"; break; case FFSAVE_AVI: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.avi", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"avi"; mOFN.lpstrFilter = L"AVI Movie File (*.avi)\0*.avi\0" \ L"\0"; break; case FFSAVE_ANIM: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.bvh", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"bvh"; mOFN.lpstrFilter = L"Anim File (*.bvh)\0*.bvh\0" \ L"\0"; break; #ifdef _CORY_TESTING case FFSAVE_GEOMETRY: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.slg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"slg"; mOFN.lpstrFilter = L"SLG SL Geometry File (*.slg)\0*.slg\0" \ L"\0"; break; #endif case FFSAVE_XML: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.xml", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"xml"; mOFN.lpstrFilter = L"XML File (*.xml)\0*.xml\0" \ L"\0"; break; case FFSAVE_COLLADA: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.collada", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"collada"; mOFN.lpstrFilter = L"COLLADA File (*.collada)\0*.collada\0" \ L"\0"; break; case FFSAVE_RAW: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.raw", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"raw"; mOFN.lpstrFilter = RAW_FILTER \ L"\0"; break; case FFSAVE_J2C: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.j2c", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"j2c"; mOFN.lpstrFilter = L"Compressed Images (*.j2c)\0*.j2c\0" \ L"\0"; break; // <edit> case FFSAVE_ANIMATN: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.animatn", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"animatn"; mOFN.lpstrFilter = L"SL Animations (*.animatn)\0*.animatn\0" \ L"\0"; break; case FFSAVE_OGG: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.ogg", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"ogg"; mOFN.lpstrFilter = L"Ogg (*.ogg)\0*.ogg\0" \ L"\0"; break; case FFSAVE_NOTECARD: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.notecard", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"notecard"; mOFN.lpstrFilter = L"Notecards (*.notecard)\0*.notecard\0" \ L"\0"; break; case FFSAVE_GESTURE: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.gesture", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"gesture"; mOFN.lpstrFilter = L"Gestures (*.gesture)\0*.gesture\0" \ L"\0"; break; case FFSAVE_LSL: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.lsl", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"lsl"; mOFN.lpstrFilter = L"LSL (*.lsl)\0*.lsl\0" \ L"Text files (*.txt)\0*.txt\0" L"RTF Files (*.rtf)\0*.rtf\0" L"\0"; break; case FFSAVE_SHAPE: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.shape", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"shape"; mOFN.lpstrFilter = L"Shapes (*.shape)\0*.shape\0" \ L"\0"; break; case FFSAVE_SKIN: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.skin", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"skin"; mOFN.lpstrFilter = L"Skins (*.skin)\0*.skin\0" \ L"\0"; break; case FFSAVE_HAIR: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.hair", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"hair"; mOFN.lpstrFilter = L"Hair (*.hair)\0*.hair\0" \ L"\0"; break; case FFSAVE_EYES: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.eyes", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"eyes"; mOFN.lpstrFilter = L"Eyes (*.eyes)\0*.eyes\0" \ L"\0"; break; case FFSAVE_SHIRT: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.shirt", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"shirt"; mOFN.lpstrFilter = L"Shirts (*.shirt)\0*.shirt\0" \ L"\0"; break; case FFSAVE_PANTS: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.pants", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"pants"; mOFN.lpstrFilter = L"Pants (*.pants)\0*.pants\0" \ L"\0"; break; case FFSAVE_SHOES: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.shoes", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"shoes"; mOFN.lpstrFilter = L"Shoes (*.shoes)\0*.shoes\0" \ L"\0"; break; case FFSAVE_SOCKS: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.socks", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"socks"; mOFN.lpstrFilter = L"Socks (*.socks)\0*.socks\0" \ L"\0"; break; case FFSAVE_JACKET: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.jacket", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"jacket"; mOFN.lpstrFilter = L"Jackets (*.jacket)\0*.jacket\0" \ L"\0"; break; case FFSAVE_GLOVES: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.gloves", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"gloves"; mOFN.lpstrFilter = L"Gloves (*.gloves)\0*.gloves\0" \ L"\0"; break; case FFSAVE_UNDERSHIRT: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.undershirt", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"undershirt"; mOFN.lpstrFilter = L"Undershirts (*.undershirt)\0*.undershirt\0" \ L"\0"; break; case FFSAVE_UNDERPANTS: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.underpants", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"underpants"; mOFN.lpstrFilter = L"Underpants (*.underpants)\0*.underpants\0" \ L"\0"; break; case FFSAVE_SKIRT: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.skirt", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"skirt"; mOFN.lpstrFilter = L"Skirts (*.skirt)\0*.skirt\0" \ L"\0"; break; case FFSAVE_LANDMARK: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.landmark", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"landmark"; mOFN.lpstrFilter = L"Landmarks (*.landmark)\0*.landmark\0" \ L"\0"; break; case FFSAVE_AO: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.ao", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"ao"; mOFN.lpstrFilter = L"Animation overrides (*.ao)\0*.ao\0" \ L"\0"; break; case FFSAVE_INVGZ: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.inv", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L".inv"; mOFN.lpstrFilter = L"InvCache (*.inv)\0*.inv\0" \ L"\0"; break; case FFSAVE_BLACKLIST: if(filename.empty()) { wcsncpy( mFilesW,L"untitled.blacklist", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L".blacklist"; mOFN.lpstrFilter = L"Asset Blacklists (*.blacklist)\0*.blacklist\0" \ L"\0"; break; // </edit> default: return FALSE; } mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE; mOFN.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST; reset(); // Modal, so pause agent send_agent_pause(); { // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! success = GetSaveFileName(&mOFN); if (success) { std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); mFiles.push_back(filename); } gKeyboard->resetKeys(); } send_agent_resume(); // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; }
BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename) { if( mLocked ) { return FALSE; } BOOL success = FALSE; mOFN.lpstrFile = mFilesW; if (!filename.empty()) { llutf16string tstring = utf8str_to_utf16str(filename); wcsncpy(mFilesW, tstring.c_str(), FILENAME_BUFFER_SIZE); } /*Flawfinder: ignore*/ else { mFilesW[0] = '\0'; } mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); switch( filter ) { case FFSAVE_ALL: mOFN.lpstrDefExt = NULL; mOFN.lpstrFilter = L"All Files (*.*)\0*.*\0" \ L"WAV Sounds (*.wav)\0*.wav\0" \ L"Targa, Bitmap Images (*.tga; *.bmp)\0*.tga;*.bmp\0" \ L"\0"; break; case FFSAVE_WAV: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.wav", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"wav"; mOFN.lpstrFilter = L"WAV Sounds (*.wav)\0*.wav\0" \ L"\0"; break; case FFSAVE_TGA: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.tga", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"tga"; mOFN.lpstrFilter = L"Targa Images (*.tga)\0*.tga\0" \ L"\0"; break; case FFSAVE_BMP: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.bmp", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"bmp"; mOFN.lpstrFilter = L"Bitmap Images (*.bmp)\0*.bmp\0" \ L"\0"; break; case FFSAVE_PNG: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"png"; mOFN.lpstrFilter = L"PNG Images (*.png)\0*.png\0" \ L"\0"; break; case FFSAVE_JPEG: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.jpeg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"jpeg"; mOFN.lpstrFilter = L"JPEG Images (*.jpeg)\0*.jpeg\0" \ L"\0"; break; case FFSAVE_AVI: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.avi", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"avi"; mOFN.lpstrFilter = L"AVI Movie File (*.avi)\0*.avi\0" \ L"\0"; break; case FFSAVE_ANIM: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.xaf", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"xaf"; mOFN.lpstrFilter = L"XAF Anim File (*.xaf)\0*.xaf\0" \ L"\0"; break; #ifdef _CORY_TESTING case FFSAVE_GEOMETRY: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.slg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"slg"; mOFN.lpstrFilter = L"SLG SL Geometry File (*.slg)\0*.slg\0" \ L"\0"; break; #endif case FFSAVE_XML: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.xml", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"xml"; mOFN.lpstrFilter = L"XML File (*.xml)\0*.xml\0" \ L"\0"; break; case FFSAVE_COLLADA: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.collada", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"collada"; mOFN.lpstrFilter = L"COLLADA File (*.collada)\0*.collada\0" \ L"\0"; break; case FFSAVE_RAW: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.raw", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } mOFN.lpstrDefExt = L"raw"; mOFN.lpstrFilter = RAW_FILTER \ L"\0"; break; case FFSAVE_J2C: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.j2c", FILENAME_BUFFER_SIZE); } mOFN.lpstrDefExt = L"j2c"; mOFN.lpstrFilter = L"Compressed Images (*.j2c)\0*.j2c\0" \ L"\0"; break; default: return FALSE; } mOFN.nMaxFile = SINGLE_FILENAME_BUFFER_SIZE; mOFN.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST; reset(); // Modal, so pause agent send_agent_pause(); { // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! success = GetSaveFileName(&mOFN); if (success) { std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); mFiles.push_back(filename); } gKeyboard->resetKeys(); } send_agent_resume(); // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; }
BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter) { if( mLocked ) { return FALSE; } BOOL success = FALSE; // don't provide default file selection mFilesW[0] = '\0'; mOFN.hwndOwner = (HWND)gViewerWindow->getPlatformWindow(); mOFN.lpstrFile = mFilesW; mOFN.nFilterIndex = 1; mOFN.nMaxFile = FILENAME_BUFFER_SIZE; mOFN.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_ALLOWMULTISELECT; setupFilter(filter); reset(); // Modal, so pause agent send_agent_pause(); // NOTA BENE: hitting the file dialog triggers a window focus event, destroying the selection manager!! success = GetOpenFileName(&mOFN); // pauses until ok or cancel. if( success ) { // The getopenfilename api doesn't tell us if we got more than // one file, so we have to test manually by checking string // lengths. if( wcslen(mOFN.lpstrFile) > mOFN.nFileOffset ) /*Flawfinder: ignore*/ { std::string filename = utf16str_to_utf8str(llutf16string(mFilesW)); mFiles.push_back(filename); } else { mLocked = TRUE; WCHAR* tptrw = mFilesW; std::string dirname; while(1) { if (*tptrw == 0 && *(tptrw+1) == 0) // double '\0' break; if (*tptrw == 0) tptrw++; // shouldn't happen? std::string filename = utf16str_to_utf8str(llutf16string(tptrw)); if (dirname.empty()) dirname = filename + "\\"; else mFiles.push_back(dirname + filename); tptrw += filename.size(); } } } send_agent_resume(); // Account for the fact that the app has been stalled. LLFrameTimer::updateFrameTime(); return success; }