llpaneldisplay.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 // file include
00035 #include "llpaneldisplay.h"
00036 
00037 // linden library includes
00038 #include "llerror.h"
00039 #include "llfontgl.h"
00040 #include "llrect.h"
00041 #include "llstring.h"
00042 
00043 // project includes
00044 #include "llagent.h"
00045 #include "llbutton.h"
00046 #include "llcheckboxctrl.h"
00047 #include "llcombobox.h"
00048 #include "llflexibleobject.h"
00049 #include "lllineeditor.h"
00050 #include "llradiogroup.h"
00051 #include "llresmgr.h"
00052 #include "llsliderctrl.h"
00053 #include "llspinctrl.h"
00054 #include "llstartup.h"
00055 #include "lltextbox.h"
00056 #include "lltexteditor.h"
00057 #include "llui.h"
00058 #include "llviewercamera.h"
00059 #include "llviewerimage.h"
00060 #include "llviewerimagelist.h"
00061 #include "llviewermessage.h"
00062 #include "llviewerobjectlist.h"
00063 #include "llviewerwindow.h"
00064 #include "llvoavatar.h"
00065 #include "llvovolume.h"
00066 #include "llvotree.h"
00067 #include "llvosky.h"
00068 #include "llwindow.h"
00069 #include "llworld.h"
00070 #include "pipeline.h"
00071 #include "lluictrlfactory.h"
00072 #include "llfeaturemanager.h"
00073 #include "llglslshader.h"
00074 #include "llfloaterhardwaresettings.h"
00075 #include "llboost.h"
00076 
00077 //RN temporary includes for resolution switching
00078 #include "llglheaders.h"
00079 #include "llviewercontrol.h"
00080 #include "llsky.h"
00081 
00082 // parent
00083 #include "llfloaterpreference.h"
00084 
00085 #include <boost/regex.hpp>
00086 
00087 const F32 MAX_USER_FAR_CLIP = 512.f;
00088 const F32 MIN_USER_FAR_CLIP = 64.f;
00089 
00090 const S32 ASPECT_RATIO_STR_LEN = 100;
00091 
00092 LLPanelDisplay::LLPanelDisplay()
00093 {
00094         LLUICtrlFactory::getInstance()->buildPanel(this, "panel_preferences_graphics1.xml");
00095 }
00096 
00097 BOOL LLPanelDisplay::postBuild()
00098 {
00099         // return to default values
00100         childSetAction("Defaults", setHardwareDefaults, NULL);
00101         
00102         // Help button
00103         childSetAction("GraphicsPreferencesHelpButton", onOpenHelp, this);
00104 
00105         // Hardware settings button
00106         childSetAction("GraphicsHardwareButton", onOpenHardwareSettings, NULL);
00107 
00108         //============================================================================
00109         // Resolution
00110         
00111         // radio set for fullscreen size
00112         
00113         mCtrlWindowed = getChild<LLCheckBoxCtrl>( "windowed mode");
00114         mCtrlWindowed->setCommitCallback(onCommitWindowedMode);
00115         mCtrlWindowed->setCallbackUserData(this);
00116 
00117         mAspectRatioLabel1 = getChild<LLTextBox>("AspectRatioLabel1");
00118         mFullScreenInfo = getChild<LLTextEditor>("FullScreenInfo");
00119         mDisplayResLabel = getChild<LLTextBox>("DisplayResLabel");
00120 
00121         S32 num_resolutions = 0;
00122         LLWindow::LLWindowResolution* supported_resolutions = gViewerWindow->getWindow()->getSupportedResolutions(num_resolutions);
00123 
00124         S32 fullscreen_mode = num_resolutions - 1;
00125 
00126         mCtrlFullScreen = getChild<LLComboBox>( "fullscreen combo");
00127         
00128         LLUIString resolution_label = getUIString("resolution_format");
00129 
00130         for (S32 i = 0; i < num_resolutions; i++)
00131         {
00132                 resolution_label.setArg("[RES_X]", llformat("%d", supported_resolutions[i].mWidth));
00133                 resolution_label.setArg("[RES_Y]", llformat("%d", supported_resolutions[i].mHeight));
00134                 mCtrlFullScreen->add( resolution_label, ADD_BOTTOM );
00135         }
00136 
00137         {
00138                 BOOL targetFullscreen;
00139                 S32 targetWidth;
00140                 S32 targetHeight;
00141                 
00142                 gViewerWindow->getTargetWindow(targetFullscreen, targetWidth, targetHeight);
00143                 
00144                 if (targetFullscreen)
00145                 {
00146                         fullscreen_mode = 0; // default to 800x600
00147                         for (S32 i = 0; i < num_resolutions; i++)
00148                         {
00149                                 if (targetWidth == supported_resolutions[i].mWidth
00150                                 &&  targetHeight == supported_resolutions[i].mHeight)
00151                                 {
00152                                         fullscreen_mode = i;
00153                                 }
00154                         }
00155                         mCtrlFullScreen->setCurrentByIndex(fullscreen_mode);
00156                         mCtrlWindowed->set(FALSE);
00157                         mCtrlFullScreen->setVisible(TRUE);
00158                 }
00159                 else
00160                 {
00161                         // set to windowed mode
00162                         //fullscreen_mode = mCtrlFullScreen->getItemCount() - 1;
00163                         mCtrlWindowed->set(TRUE);
00164                         mCtrlFullScreen->setCurrentByIndex(0);
00165                         mCtrlFullScreen->setVisible(FALSE);
00166                 }
00167         }
00168 
00169         initWindowSizeControls();
00170         
00171         if (gSavedSettings.getBOOL("FullScreenAutoDetectAspectRatio"))
00172         {
00173                 mAspectRatio = gViewerWindow->getDisplayAspectRatio();
00174         }
00175         else
00176         {
00177                 mAspectRatio = gSavedSettings.getF32("FullScreenAspectRatio");
00178         }
00179 
00180         S32 numerator = 0;
00181         S32 denominator = 0;
00182         fractionFromDecimal(mAspectRatio, numerator, denominator);
00183 
00184         LLUIString aspect_ratio_text = getUIString("aspect_ratio_text");
00185         if (numerator != 0)
00186         {
00187                 aspect_ratio_text.setArg("[NUM]", llformat("%d",  numerator));
00188                 aspect_ratio_text.setArg("[DEN]", llformat("%d",  denominator));
00189         }
00190         else
00191         {
00192                 aspect_ratio_text = llformat("%.3f", mAspectRatio);
00193         }
00194 
00195         mCtrlAspectRatio = getChild<LLComboBox>( "aspect_ratio");
00196         mCtrlAspectRatio->setTextEntryCallback(onKeystrokeAspectRatio);
00197         mCtrlAspectRatio->setCommitCallback(onSelectAspectRatio);
00198         mCtrlAspectRatio->setCallbackUserData(this);
00199         // add default aspect ratios
00200         mCtrlAspectRatio->add(aspect_ratio_text, &mAspectRatio, ADD_TOP);
00201         mCtrlAspectRatio->setCurrentByIndex(0);
00202 
00203         mCtrlAutoDetectAspect = getChild<LLCheckBoxCtrl>( "aspect_auto_detect");
00204         mCtrlAutoDetectAspect->setCommitCallback(onCommitAutoDetectAspect);
00205         mCtrlAutoDetectAspect->setCallbackUserData(this);
00206 
00207         // radio performance box
00208         mCtrlSliderQuality = getChild<LLSliderCtrl>("QualityPerformanceSelection");
00209         mCtrlSliderQuality->setSliderMouseUpCallback(onChangeQuality);
00210         mCtrlSliderQuality->setCallbackUserData(this);
00211 
00212         mCtrlCustomSettings = getChild<LLCheckBoxCtrl>("CustomSettings");
00213         mCtrlCustomSettings->setCommitCallback(onChangeCustom);
00214         mCtrlCustomSettings->setCallbackUserData(this);
00215 
00216         mGraphicsBorder = getChild<LLViewBorder>("GraphicsBorder");
00217 
00218         //----------------------------------------------------------------------------
00219         // Enable Bump/Shiny
00220         mCtrlBumpShiny = getChild<LLCheckBoxCtrl>("BumpShiny");
00221         
00222         //----------------------------------------------------------------------------
00223         // Enable Reflections
00224         mCtrlReflections = getChild<LLCheckBoxCtrl>("Reflections");
00225         mCtrlReflections->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable);
00226         mCtrlReflections->setCallbackUserData(this);
00227         mRadioReflectionDetail = getChild<LLRadioGroup>("ReflectionDetailRadio");
00228         
00229         // WindLight
00230         mCtrlWindLight = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
00231         mCtrlWindLight->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable);
00232         mCtrlWindLight->setCallbackUserData(this);
00233 
00234         //----------------------------------------------------------------------------
00235         // Enable Avatar Shaders
00236         mCtrlAvatarVP = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
00237         mCtrlAvatarVP->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable);
00238         mCtrlAvatarVP->setCallbackUserData(this);
00239 
00240         //----------------------------------------------------------------------------
00241         // Avatar Render Mode
00242         mCtrlAvatarCloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
00243         mCtrlAvatarImpostors = getChild<LLCheckBoxCtrl>("AvatarImpostors");
00244 
00245         //----------------------------------------------------------------------------
00246         // radio set for lighting detail
00247         mRadioLightingDetail2 = getChild<LLRadioGroup>("LightingDetailRadio");
00248 
00249         //----------------------------------------------------------------------------
00250         // radio set for terrain detail mode
00251         mRadioTerrainDetail = getChild<LLRadioGroup>("TerrainDetailRadio");
00252 
00253         //----------------------------------------------------------------------------
00254         // Global Shader Enable
00255         mCtrlShaderEnable = getChild<LLCheckBoxCtrl>("BasicShaders");
00256         mCtrlShaderEnable->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable);
00257         mCtrlShaderEnable->setCallbackUserData(this);
00258         
00259         //============================================================================
00260 
00261         // Object detail slider
00262         mCtrlDrawDistance = getChild<LLSliderCtrl>("DrawDistance");
00263         mDrawDistanceMeterText1 = getChild<LLTextBox>("DrawDistanceMeterText1");
00264         mDrawDistanceMeterText2 = getChild<LLTextBox>("DrawDistanceMeterText2");
00265         mCtrlDrawDistance->setCommitCallback(&LLPanelDisplay::updateMeterText);
00266         mCtrlDrawDistance->setCallbackUserData(this);
00267 
00268         // Object detail slider
00269         mCtrlLODFactor = getChild<LLSliderCtrl>("ObjectMeshDetail");
00270         mLODFactorText = getChild<LLTextBox>("ObjectMeshDetailText");
00271         mCtrlLODFactor->setCommitCallback(&LLPanelDisplay::updateSliderText);
00272         mCtrlLODFactor->setCallbackUserData(mLODFactorText);
00273 
00274         // Flex object detail slider
00275         mCtrlFlexFactor = getChild<LLSliderCtrl>("FlexibleMeshDetail");
00276         mFlexFactorText = getChild<LLTextBox>("FlexibleMeshDetailText");
00277         mCtrlFlexFactor->setCommitCallback(&LLPanelDisplay::updateSliderText);
00278         mCtrlFlexFactor->setCallbackUserData(mFlexFactorText);
00279 
00280         // Tree detail slider
00281         mCtrlTreeFactor = getChild<LLSliderCtrl>("TreeMeshDetail");
00282         mTreeFactorText = getChild<LLTextBox>("TreeMeshDetailText");
00283         mCtrlTreeFactor->setCommitCallback(&LLPanelDisplay::updateSliderText);
00284         mCtrlTreeFactor->setCallbackUserData(mTreeFactorText);
00285 
00286         // Avatar detail slider
00287         mCtrlAvatarFactor = getChild<LLSliderCtrl>("AvatarMeshDetail");
00288         mAvatarFactorText = getChild<LLTextBox>("AvatarMeshDetailText");
00289         mCtrlAvatarFactor->setCommitCallback(&LLPanelDisplay::updateSliderText);
00290         mCtrlAvatarFactor->setCallbackUserData(mAvatarFactorText);
00291 
00292         // Terrain detail slider
00293         mCtrlTerrainFactor = getChild<LLSliderCtrl>("TerrainMeshDetail");
00294         mTerrainFactorText = getChild<LLTextBox>("TerrainMeshDetailText");
00295         mCtrlTerrainFactor->setCommitCallback(&LLPanelDisplay::updateSliderText);
00296         mCtrlTerrainFactor->setCallbackUserData(mTerrainFactorText);
00297 
00298         // Terrain detail slider
00299         mCtrlSkyFactor = getChild<LLSliderCtrl>("SkyMeshDetail");
00300         mSkyFactorText = getChild<LLTextBox>("SkyMeshDetailText");
00301         mCtrlSkyFactor->setCommitCallback(&LLPanelDisplay::updateSliderText);
00302         mCtrlSkyFactor->setCallbackUserData(mSkyFactorText);
00303 
00304         // Particle detail slider
00305         mCtrlMaxParticle = getChild<LLSliderCtrl>("MaxParticleCount");
00306 
00307         // Glow detail slider
00308         mCtrlPostProcess = getChild<LLSliderCtrl>("RenderPostProcess");
00309         mPostProcessText = getChild<LLTextBox>("PostProcessText");
00310         mCtrlPostProcess->setCommitCallback(&LLPanelDisplay::updateSliderText);
00311         mCtrlPostProcess->setCallbackUserData(mPostProcessText);
00312 
00313         // Text boxes (for enabling/disabling)
00314         mShaderText = getChild<LLTextBox>("ShadersText");
00315         mReflectionText = getChild<LLTextBox>("ReflectionDetailText");
00316         mAvatarText = getChild<LLTextBox>("AvatarRenderingText");
00317         mTerrainText = getChild<LLTextBox>("TerrainDetailText");
00318         mLightingText = getChild<LLTextBox>("LightingDetailText");
00319         mMeshDetailText = getChild<LLTextBox>("MeshDetailText");
00320 
00321         refresh();
00322 
00323         return TRUE;
00324 }
00325 
00326 void LLPanelDisplay::initWindowSizeControls()
00327 {
00328         // Window size
00329         mWindowSizeLabel = getChild<LLTextBox>("WindowSizeLabel");
00330         mCtrlWindowSize = getChild<LLComboBox>("windowsize combo");
00331 
00332         // Look to see if current window size matches existing window sizes, if so then
00333         // just set the selection value...
00334         const U32 height = gViewerWindow->getWindowDisplayHeight();
00335         const U32 width = gViewerWindow->getWindowDisplayWidth();
00336         for (S32 i=0; i < mCtrlWindowSize->getItemCount(); i++)
00337         {
00338                 U32 height_test = 0;
00339                 U32 width_test = 0;
00340                 mCtrlWindowSize->setCurrentByIndex(i);
00341                 if (extractWindowSizeFromString(mCtrlWindowSize->getValue().asString().c_str(), width_test, height_test))
00342                 {
00343                         if ((height_test == height) && (width_test == width))
00344                         {
00345                                 return;
00346                         }
00347                 }
00348         }
00349         // ...otherwise, add a new entry with the current window height/width.
00350         LLUIString resolution_label = getUIString("resolution_format");
00351         resolution_label.setArg("[RES_X]", llformat("%d", width));
00352         resolution_label.setArg("[RES_Y]", llformat("%d", height));
00353         mCtrlWindowSize->add(resolution_label, ADD_TOP);
00354         mCtrlWindowSize->setCurrentByIndex(0);
00355 }
00356 
00357 LLPanelDisplay::~LLPanelDisplay()
00358 {
00359         // clean up user data
00360         for (S32 i = 0; i < mCtrlAspectRatio->getItemCount(); i++)
00361         {
00362                 mCtrlAspectRatio->setCurrentByIndex(i);
00363         }
00364         for (S32 i = 0; i < mCtrlWindowSize->getItemCount(); i++)
00365         {
00366                 mCtrlWindowSize->setCurrentByIndex(i);
00367         }
00368 }
00369 
00370 void LLPanelDisplay::refresh()
00371 {
00372         LLPanel::refresh();
00373         
00374         mFSAutoDetectAspect = gSavedSettings.getBOOL("FullScreenAutoDetectAspectRatio");
00375 
00376         mQualityPerformance = gSavedSettings.getU32("RenderQualityPerformance");
00377         mCustomSettings = gSavedSettings.getBOOL("RenderCustomSettings");
00378 
00379         // shader settings
00380         mBumpShiny = gSavedSettings.getBOOL("RenderObjectBump");
00381         mShaderEnable = gSavedSettings.getBOOL("VertexShaderEnable");
00382         mWindLight = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
00383         mReflections = gSavedSettings.getBOOL("RenderWaterReflections");
00384         mAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP");
00385 
00386         // reflection radio
00387         mReflectionDetail = gSavedSettings.getS32("RenderReflectionDetail");
00388 
00389         // avatar settings
00390         mAvatarImpostors = gSavedSettings.getBOOL("RenderUseImpostors");
00391         mAvatarCloth = gSavedSettings.getBOOL("RenderAvatarCloth");
00392 
00393         // Draw distance
00394         mRenderFarClip = gSavedSettings.getF32("RenderFarClip");
00395 
00396         // sliders and their text boxes
00397         mPrimLOD = gSavedSettings.getF32("RenderVolumeLODFactor");
00398         mFlexLOD = gSavedSettings.getF32("RenderFlexTimeFactor");
00399         mTreeLOD = gSavedSettings.getF32("RenderTreeLODFactor");
00400         mAvatarLOD = gSavedSettings.getF32("RenderAvatarLODFactor");
00401         mTerrainLOD = gSavedSettings.getF32("RenderTerrainLODFactor");
00402         mSkyLOD = gSavedSettings.getU32("WLSkyDetail");
00403         mParticleCount = gSavedSettings.getS32("RenderMaxPartCount");
00404         mPostProcess = gSavedSettings.getS32("RenderGlowResolutionPow");
00405         
00406         // lighting and terrain radios
00407         mLightingDetail = gSavedSettings.getS32("RenderLightingDetail");
00408         mTerrainDetail =  gSavedSettings.getS32("RenderTerrainDetail");
00409 
00410         // slider text boxes
00411         updateSliderText(mCtrlLODFactor, mLODFactorText);
00412         updateSliderText(mCtrlFlexFactor, mFlexFactorText);
00413         updateSliderText(mCtrlTreeFactor, mTreeFactorText);
00414         updateSliderText(mCtrlAvatarFactor, mAvatarFactorText);
00415         updateSliderText(mCtrlTerrainFactor, mTerrainFactorText);
00416         updateSliderText(mCtrlPostProcess, mPostProcessText);
00417         updateSliderText(mCtrlSkyFactor, mSkyFactorText);
00418 
00419         refreshEnabledState();
00420 }
00421 
00422 void LLPanelDisplay::refreshEnabledState()
00423 {
00424         // if in windowed mode, disable full screen options
00425         bool isFullScreen = !mCtrlWindowed->get();
00426 
00427         mDisplayResLabel->setVisible(isFullScreen);
00428         mCtrlFullScreen->setVisible(isFullScreen);
00429         mCtrlAspectRatio->setVisible(isFullScreen);
00430         mAspectRatioLabel1->setVisible(isFullScreen);
00431         mCtrlAutoDetectAspect->setVisible(isFullScreen);
00432         mFullScreenInfo->setVisible(!isFullScreen);
00433         mWindowSizeLabel->setVisible(!isFullScreen);
00434 
00435         // disable graphics settings and exit if it's not set to custom
00436         if(!gSavedSettings.getBOOL("RenderCustomSettings"))
00437         {
00438                 setHiddenGraphicsState(true);
00439                 return;
00440         }
00441 
00442         // otherwise turn them all on and selectively turn off others
00443         else
00444         {
00445                 setHiddenGraphicsState(false);
00446         }
00447 
00448         // Reflections
00449         BOOL reflections = gSavedSettings.getBOOL("VertexShaderEnable") 
00450                 && gGLManager.mHasCubeMap 
00451                 && LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap");
00452         mCtrlReflections->setEnabled(reflections);
00453         
00454         // Bump & Shiny
00455         bool bumpshiny = gGLManager.mHasCubeMap && LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap") && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
00456         mCtrlBumpShiny->setEnabled(bumpshiny ? TRUE : FALSE);
00457         
00458         for (S32 i = 0; i < mRadioReflectionDetail->getItemCount(); ++i)
00459         {
00460                 mRadioReflectionDetail->setIndexEnabled(i, mCtrlReflections->get() && reflections);
00461         }
00462 
00463         // Avatar Mode
00464         S32 max_avatar_shader = LLShaderMgr::sMaxAvatarShaderLevel;
00465         mCtrlAvatarVP->setEnabled((max_avatar_shader > 0) ? TRUE : FALSE);
00466         
00467         if (gSavedSettings.getBOOL("VertexShaderEnable") == FALSE || 
00468                 gSavedSettings.getBOOL("RenderAvatarVP") == FALSE)
00469         {
00470                 mCtrlAvatarCloth->setEnabled(false);
00471         } 
00472         else
00473         {
00474                 mCtrlAvatarCloth->setEnabled(true);
00475         }
00476 
00477         // Vertex Shaders
00478         mCtrlShaderEnable->setEnabled(LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"));
00479 
00480         BOOL shaders = mCtrlShaderEnable->get();
00481         if (shaders)
00482         {
00483                 mRadioTerrainDetail->setValue(1);
00484                 mRadioTerrainDetail->setEnabled(FALSE);
00485         }
00486         else
00487         {
00488                 mRadioTerrainDetail->setEnabled(TRUE);
00489         }
00490 
00491         // *HACK just checks to see if we can use shaders... 
00492         // maybe some cards that use shaders, but don't support windlight
00493         mCtrlWindLight->setEnabled(mCtrlShaderEnable->getEnabled() && shaders);
00494 
00495         // turn off sky detail if atmostpherics isn't on
00496         mCtrlSkyFactor->setEnabled(gSavedSettings.getBOOL("WindLightUseAtmosShaders"));
00497         mSkyFactorText->setEnabled(gSavedSettings.getBOOL("WindLightUseAtmosShaders"));
00498 
00499         // now turn off any features that are unavailable
00500         disableUnavailableSettings();
00501 }
00502 
00503 void LLPanelDisplay::disableUnavailableSettings()
00504 {       
00505         // if vertex shaders off, disable all shader related products
00506         if(!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"))
00507         {
00508                 mCtrlShaderEnable->setEnabled(FALSE);
00509                 mCtrlShaderEnable->setValue(FALSE);
00510 
00511                 mCtrlWindLight->setEnabled(FALSE);
00512                 mCtrlWindLight->setValue(FALSE);
00513 
00514                 mCtrlReflections->setEnabled(FALSE);
00515                 mCtrlReflections->setValue(FALSE);
00516 
00517                 mCtrlAvatarVP->setEnabled(FALSE);
00518                 mCtrlAvatarVP->setValue(FALSE);
00519 
00520                 mCtrlAvatarCloth->setEnabled(FALSE);
00521                 mCtrlAvatarCloth->setValue(FALSE);
00522         }
00523 
00524         // disabled windlight
00525         if(!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
00526         {
00527                 mCtrlWindLight->setEnabled(FALSE);
00528                 mCtrlWindLight->setValue(FALSE);
00529         }
00530 
00531         // disabled reflections
00532         if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderWaterReflections"))
00533         {
00534                 mCtrlReflections->setEnabled(FALSE);
00535                 mCtrlReflections->setValue(FALSE);
00536         }
00537 
00538         // disabled av
00539         if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP"))
00540         {
00541                 mCtrlAvatarVP->setEnabled(FALSE);
00542                 mCtrlAvatarVP->setValue(FALSE);
00543 
00544                 mCtrlAvatarCloth->setEnabled(FALSE);
00545                 mCtrlAvatarCloth->setValue(FALSE);
00546         }
00547         // disabled cloth
00548         if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth"))
00549         {
00550                 mCtrlAvatarCloth->setEnabled(FALSE);
00551                 mCtrlAvatarCloth->setValue(FALSE);
00552         }
00553         // disabled impostors
00554         if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderUseImpostors"))
00555         {
00556                 mCtrlAvatarImpostors->setEnabled(FALSE);
00557                 mCtrlAvatarImpostors->setValue(FALSE);
00558         }
00559 }
00560 
00561 void LLPanelDisplay::setHiddenGraphicsState(bool isHidden)
00562 {
00563         // quick check
00564         llassert(mGraphicsBorder != NULL);
00565 
00566         llassert(mCtrlDrawDistance != NULL);
00567         llassert(mCtrlLODFactor != NULL);
00568         llassert(mCtrlFlexFactor != NULL);
00569         llassert(mCtrlTreeFactor != NULL);
00570         llassert(mCtrlAvatarFactor != NULL);
00571         llassert(mCtrlTerrainFactor != NULL);
00572         llassert(mCtrlSkyFactor != NULL);
00573         llassert(mCtrlMaxParticle != NULL);
00574         llassert(mCtrlPostProcess != NULL);
00575 
00576         llassert(mLODFactorText != NULL);
00577         llassert(mFlexFactorText != NULL);
00578         llassert(mTreeFactorText != NULL);
00579         llassert(mAvatarFactorText != NULL);
00580         llassert(mTerrainFactorText != NULL);
00581         llassert(mSkyFactorText != NULL);
00582         llassert(mPostProcessText != NULL);
00583 
00584         llassert(mCtrlBumpShiny != NULL);
00585         llassert(mCtrlReflections != NULL);
00586         llassert(mCtrlWindLight != NULL);
00587         llassert(mCtrlAvatarVP != NULL);
00588         llassert(mCtrlShaderEnable != NULL);
00589         llassert(mCtrlAvatarImpostors != NULL);
00590         llassert(mCtrlAvatarCloth != NULL);
00591         llassert(mRadioLightingDetail2 != NULL);
00592 
00593         llassert(mRadioTerrainDetail != NULL);
00594         llassert(mRadioReflectionDetail != NULL);
00595 
00596         llassert(mMeshDetailText != NULL);
00597         llassert(mShaderText != NULL);
00598         llassert(mReflectionText != NULL);
00599         llassert(mAvatarText != NULL);
00600         llassert(mLightingText != NULL);
00601         llassert(mTerrainText != NULL);
00602         llassert(mDrawDistanceMeterText1 != NULL);
00603         llassert(mDrawDistanceMeterText2 != NULL);
00604 
00605         // enable/disable the states
00606         mGraphicsBorder->setVisible(!isHidden);
00607         /* 
00608         LLColor4 light(.45098f, .51765f, .6078f, 1.0f);
00609         LLColor4 dark(.10196f, .10196f, .10196f, 1.0f);
00610         b ? mGraphicsBorder->setColors(dark, light) : mGraphicsBorder->setColors(dark, dark);
00611         */
00612 
00613         mCtrlDrawDistance->setVisible(!isHidden);
00614         mCtrlLODFactor->setVisible(!isHidden);  
00615         mCtrlFlexFactor->setVisible(!isHidden); 
00616         mCtrlTreeFactor->setVisible(!isHidden); 
00617         mCtrlAvatarFactor->setVisible(!isHidden);       
00618         mCtrlTerrainFactor->setVisible(!isHidden);
00619         mCtrlSkyFactor->setVisible(!isHidden);
00620         mCtrlMaxParticle->setVisible(!isHidden);
00621         mCtrlPostProcess->setVisible(!isHidden);
00622 
00623         mLODFactorText->setVisible(!isHidden);  
00624         mFlexFactorText->setVisible(!isHidden); 
00625         mTreeFactorText->setVisible(!isHidden); 
00626         mAvatarFactorText->setVisible(!isHidden);       
00627         mTerrainFactorText->setVisible(!isHidden);
00628         mSkyFactorText->setVisible(!isHidden);
00629         mPostProcessText->setVisible(!isHidden);
00630 
00631         mCtrlBumpShiny->setVisible(!isHidden);
00632         mCtrlReflections->setVisible(!isHidden);
00633         mCtrlWindLight->setVisible(!isHidden);
00634         mCtrlAvatarVP->setVisible(!isHidden);
00635         mCtrlShaderEnable->setVisible(!isHidden);
00636         mCtrlAvatarImpostors->setVisible(!isHidden);
00637         mCtrlAvatarCloth->setVisible(!isHidden);
00638         mRadioLightingDetail2->setVisible(!isHidden);
00639 
00640         mRadioTerrainDetail->setVisible(!isHidden);
00641         mRadioReflectionDetail->setVisible(!isHidden);
00642 
00643         // text boxes
00644         mShaderText->setVisible(!isHidden);
00645         mReflectionText->setVisible(!isHidden);
00646         mAvatarText->setVisible(!isHidden);
00647         mLightingText->setVisible(!isHidden);
00648         mTerrainText->setVisible(!isHidden);
00649         mDrawDistanceMeterText1->setVisible(!isHidden);
00650         mDrawDistanceMeterText2->setVisible(!isHidden);
00651 
00652         // hide one meter text if we're making things visible
00653         if(!isHidden)
00654         {
00655                 updateMeterText(mCtrlDrawDistance, this);
00656         }
00657 
00658         mMeshDetailText->setVisible(!isHidden);
00659 }
00660 
00661 void LLPanelDisplay::cancel()
00662 {
00663         gSavedSettings.setBOOL("FullScreenAutoDetectAspectRatio", mFSAutoDetectAspect);
00664         gSavedSettings.setF32("FullScreenAspectRatio", mAspectRatio);
00665 
00666         gSavedSettings.setU32("RenderQualityPerformance", mQualityPerformance);
00667 
00668         gSavedSettings.setBOOL("RenderCustomSettings", mCustomSettings);
00669 
00670         gSavedSettings.setBOOL("RenderObjectBump", mBumpShiny);
00671         gSavedSettings.setBOOL("VertexShaderEnable", mShaderEnable);
00672         gSavedSettings.setBOOL("WindLightUseAtmosShaders", mWindLight);
00673         gSavedSettings.setBOOL("RenderWaterReflections", mReflections);
00674         gSavedSettings.setBOOL("RenderAvatarVP", mAvatarVP);
00675 
00676         gSavedSettings.setS32("RenderReflectionDetail", mReflectionDetail);
00677 
00678         gSavedSettings.setBOOL("RenderUseImpostors", mAvatarImpostors);
00679         gSavedSettings.setBOOL("RenderAvatarCloth", mAvatarCloth);
00680 
00681         gSavedSettings.setS32("RenderLightingDetail", mLightingDetail);
00682         gSavedSettings.setS32("RenderTerrainDetail", mTerrainDetail);
00683 
00684         gSavedSettings.setF32("RenderFarClip", mRenderFarClip);
00685         gSavedSettings.setF32("RenderVolumeLODFactor", mPrimLOD);
00686         gSavedSettings.setF32("RenderFlexTimeFactor", mFlexLOD);
00687         gSavedSettings.setF32("RenderTreeLODFactor", mTreeLOD);
00688         gSavedSettings.setF32("RenderAvatarLODFactor", mAvatarLOD);
00689         gSavedSettings.setF32("RenderTerrainLODFactor", mTerrainLOD);
00690         gSavedSettings.setU32("WLSkyDetail", mSkyLOD);
00691         gSavedSettings.setS32("RenderMaxPartCount", mParticleCount);
00692         gSavedSettings.setS32("RenderGlowResolutionPow", mPostProcess);
00693 }
00694 
00695 void LLPanelDisplay::apply()
00696 {
00697         applyResolution();
00698         
00699         // Only set window size if we're not in fullscreen mode
00700         if (mCtrlWindowed->get())
00701         {
00702                 applyWindowSize();
00703         }
00704 }
00705 
00706 void LLPanelDisplay::onChangeQuality(LLUICtrl *ctrl, void *data)
00707 {
00708         LLSliderCtrl* sldr = static_cast<LLSliderCtrl*>(ctrl);
00709         LLPanelDisplay* cur_panel = static_cast<LLPanelDisplay*>(data);
00710 
00711         if(sldr == NULL || cur_panel == NULL)
00712         {
00713                 return;
00714         }
00715 
00716         U32 set = (U32)sldr->getValueF32();
00717         LLFeatureManager::getInstance()->setGraphicsLevel(set, true);
00718         
00719         LLFloaterPreference::refreshEnabledGraphics();
00720         cur_panel->refresh();
00721 }
00722 
00723 void LLPanelDisplay::onChangeCustom(LLUICtrl *ctrl, void *data)
00724 {
00725         LLFloaterPreference::refreshEnabledGraphics();
00726 }
00727 
00728 void LLPanelDisplay::onOpenHelp(void* user_data)
00729 {
00730         LLPanelDisplay* self = static_cast<LLPanelDisplay*>(user_data);
00731 
00732         const char* xml_alert = "GraphicsPreferencesHelp";
00733         LLAlertDialog* dialogp = gViewerWindow->alertXml(xml_alert);
00734         if (dialogp)
00735         {
00736                 LLFloater* root_floater = gFloaterView->getParentFloater(self);
00737                 if (root_floater)
00738                 {
00739                         root_floater->addDependentFloater(dialogp);
00740                 }
00741         }       
00742 }
00743 
00744 void LLPanelDisplay::onOpenHardwareSettings(void* user_data)
00745 {
00746         LLFloaterHardwareSettings::show();
00747 }
00748 
00749 void LLPanelDisplay::onApplyResolution(LLUICtrl* src, void* user_data)
00750 {
00751         ((LLPanelDisplay*) src)->applyResolution();
00752 }
00753 
00754 void LLPanelDisplay::applyResolution()
00755 {
00756         char aspect_ratio_text[ASPECT_RATIO_STR_LEN];           /*Flawfinder: ignore*/
00757         if (mCtrlAspectRatio->getCurrentIndex() == -1)
00758         {
00759                 strncpy(aspect_ratio_text, mCtrlAspectRatio->getSimple().c_str(), sizeof(aspect_ratio_text) -1);        /*Flawfinder: ignore*/
00760                 aspect_ratio_text[sizeof(aspect_ratio_text) -1] = '\0';
00761                 char *element = strtok(aspect_ratio_text, ":/\\");
00762                 if (!element)
00763                 {
00764                         mAspectRatio = 0.f; // will be clamped later
00765                 }
00766                 else
00767                 {
00768                         LLLocale locale(LLLocale::USER_LOCALE);
00769                         mAspectRatio = (F32)atof(element);
00770                 }
00771 
00772                 // look for denominator
00773                 element = strtok(NULL, ":/\\");
00774                 if (element)
00775                 {
00776                         LLLocale locale(LLLocale::USER_LOCALE);
00777 
00778                         F32 denominator = (F32)atof(element);
00779                         if (denominator != 0.f)
00780                         {
00781                                 mAspectRatio /= denominator;
00782                         }
00783                 }
00784         }
00785         else
00786         {
00787                 mAspectRatio = (F32)mCtrlAspectRatio->getValue().asReal();
00788         }
00789 
00790         // presumably, user entered a non-numeric value if aspect_ratio == 0.f
00791         if (mAspectRatio != 0.f)
00792         {
00793                 mAspectRatio = llclamp(mAspectRatio, 0.2f, 5.f);
00794                 gSavedSettings.setF32("FullScreenAspectRatio", mAspectRatio);
00795                 if (gSavedSettings.getBOOL("FullScreenAutoDetectAspectRatio"))
00796                 {
00797                         gViewerWindow->getWindow()->setNativeAspectRatio(0.f);
00798                 }
00799                 else
00800                 {
00801                         gViewerWindow->getWindow()->setNativeAspectRatio(mAspectRatio);
00802                 }
00803         }
00804         gViewerWindow->reshape(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight());
00805 
00806         // Screen resolution
00807         S32 num_resolutions;
00808         LLWindow::LLWindowResolution* supported_resolutions = gViewerWindow->getWindow()->getSupportedResolutions(num_resolutions);
00809 
00810         // switching to windowed
00811         BOOL fullscreen = !mCtrlWindowed->get();
00812 
00813         // check if resolution has changed
00814         BOOL targetFullscreen;
00815         S32 targetWidth;
00816         S32 targetHeight;
00817         
00818         gViewerWindow->getTargetWindow(targetFullscreen, targetWidth, targetHeight);
00819 
00820         if ((fullscreen != targetFullscreen) ||
00821                 (fullscreen &&
00822                  (supported_resolutions[mCtrlFullScreen->getCurrentIndex()].mWidth != targetWidth ||
00823                   supported_resolutions[mCtrlFullScreen->getCurrentIndex()].mHeight != targetHeight)
00824                  ))
00825         {
00826                 // change fullscreen resolution or switch in/out of windowed mode
00827                 BOOL result;
00828 
00829                 BOOL logged_in = (LLStartUp::getStartupState() >= STATE_STARTED);
00830                 if (fullscreen)
00831                 {
00832                         result = gViewerWindow->changeDisplaySettings(TRUE, 
00833                                 LLCoordScreen(  supported_resolutions[mCtrlFullScreen->getCurrentIndex()].mWidth, 
00834                                                                 supported_resolutions[mCtrlFullScreen->getCurrentIndex()].mHeight), 
00835                                 gSavedSettings.getBOOL("DisableVerticalSync"),
00836                                 logged_in);
00837                 }
00838                 else
00839                 {
00840                         result = gViewerWindow->changeDisplaySettings(FALSE, 
00841                                 LLCoordScreen(gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight")), 
00842                                 TRUE,
00843                                 logged_in);
00844                 }
00845                 if (!result)
00846                 {
00847 
00848                         // GL is non-existent at this point, so we can't continue.
00849                         llerrs << "LLPanelDisplay::apply() failed" << llendl;
00850                 }
00851         }
00852 
00853         // force aspect ratio
00854         if (fullscreen)
00855         {
00856                 LLViewerCamera::getInstance()->setAspect( gViewerWindow->getDisplayAspectRatio() );
00857         }
00858 
00859         send_agent_update(TRUE);
00860 
00861         // Update enable/disable
00862         refresh();
00863 }
00864 
00865 // Extract from strings of the form "<width> x <height>", e.g. "640 x 480".
00866 bool LLPanelDisplay::extractWindowSizeFromString(const char *sInput, U32 &width, U32 &height)
00867 {
00868         using namespace boost;
00869         cmatch what;
00870         const regex expression("([0-9]+) x ([0-9]+)");
00871         if (regex_match(sInput, what, expression))
00872         {
00873                 width = atoi(what[1].first);
00874                 height = atoi(what[2].first);
00875                 return true;
00876         }
00877         
00878         width = height = 0;
00879         return false;
00880 }
00881 
00882 void LLPanelDisplay::applyWindowSize()
00883 {
00884         if (mCtrlWindowSize->getVisible() && (mCtrlWindowSize->getCurrentIndex() != -1))
00885         {
00886                 U32 width = 0;
00887                 U32 height = 0;
00888                 if (extractWindowSizeFromString(mCtrlWindowSize->getValue().asString().c_str(), width,height))
00889                 {
00890                         LLViewerWindow::movieSize(width, height);
00891                 }
00892         }
00893 }
00894 
00895 //static 
00896 void LLPanelDisplay::onCommitWindowedMode(LLUICtrl* ctrl, void *data)
00897 {
00898         LLPanelDisplay *panel = (LLPanelDisplay*)data;
00899 
00900         panel->refresh();
00901 }
00902 
00903 //static
00904 void LLPanelDisplay::onCommitAutoDetectAspect(LLUICtrl *ctrl, void *data)
00905 {
00906         LLPanelDisplay *panel = (LLPanelDisplay*)data;
00907 
00908         BOOL auto_detect = ((LLCheckBoxCtrl*)ctrl)->get();
00909         F32 ratio;
00910 
00911         if (auto_detect)
00912         {
00913                 S32 numerator = 0;
00914                 S32 denominator = 0;
00915                 
00916                 // clear any aspect ratio override
00917                 gViewerWindow->mWindow->setNativeAspectRatio(0.f);
00918                 fractionFromDecimal(gViewerWindow->mWindow->getNativeAspectRatio(), numerator, denominator);
00919 
00920                 LLString aspect;
00921                 if (numerator != 0)
00922                 {
00923                         aspect = llformat("%d:%d", numerator, denominator);
00924                 }
00925                 else
00926                 {
00927                         aspect = llformat("%.3f", gViewerWindow->mWindow->getNativeAspectRatio());
00928                 }
00929 
00930                 panel->mCtrlAspectRatio->setLabel(aspect);
00931 
00932                 ratio = gViewerWindow->mWindow->getNativeAspectRatio();
00933                 gSavedSettings.setF32("FullScreenAspectRatio", ratio);
00934         }
00935 }
00936 
00937 //static 
00938 void LLPanelDisplay::onKeystrokeAspectRatio(LLLineEditor* caller, void* user_data)
00939 {
00940         LLPanelDisplay* panel = (LLPanelDisplay*)user_data;
00941 
00942         panel->mCtrlAutoDetectAspect->set(FALSE);
00943 }
00944 
00945 //static
00946 void LLPanelDisplay::onSelectAspectRatio(LLUICtrl*, void* user_data)
00947 {
00948         LLPanelDisplay* panel = (LLPanelDisplay*)user_data;
00949 
00950         panel->mCtrlAutoDetectAspect->set(FALSE);
00951 }
00952 
00953 //static
00954 void LLPanelDisplay::fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator)
00955 {
00956         numerator = 0;
00957         denominator = 0;
00958         for (F32 test_denominator = 1.f; test_denominator < 30.f; test_denominator += 1.f)
00959         {
00960                 if (fmodf((decimal_val * test_denominator) + 0.01f, 1.f) < 0.02f)
00961                 {
00962                         numerator = llround(decimal_val * test_denominator);
00963                         denominator = llround(test_denominator);
00964                         break;
00965                 }
00966         }
00967 }
00968 
00969 //static
00970 void LLPanelDisplay::onVertexShaderEnable(LLUICtrl* self, void* data)
00971 {
00972         LLFloaterPreference::refreshEnabledGraphics();
00973 }
00974 
00975 void LLPanelDisplay::setHardwareDefaults(void* user_data)
00976 {
00977         LLFeatureManager::getInstance()->applyRecommendedSettings();
00978         LLFloaterPreference::refreshEnabledGraphics();
00979 }
00980 
00981 void LLPanelDisplay::updateSliderText(LLUICtrl* ctrl, void* user_data)
00982 {
00983         // get our UI widgets
00984         LLTextBox* text_box = (LLTextBox*)user_data;
00985         LLSliderCtrl* slider = (LLSliderCtrl*) ctrl;
00986         if(text_box == NULL || slider == NULL)
00987         {
00988                 return;
00989         }
00990 
00991         // get range and points when text should change
00992         F32 range = slider->getMaxValue() - slider->getMinValue();
00993         llassert(range > 0);
00994         F32 midPoint = slider->getMinValue() + range / 3.0f;
00995         F32 highPoint = slider->getMinValue() + (2.0f * range / 3.0f);
00996 
00997         // choose the right text
00998         if(slider->getValueF32() < midPoint)
00999         {
01000                 text_box->setText(LLString("Low"));
01001         } 
01002         else if (slider->getValueF32() < highPoint)
01003         {
01004                 text_box->setText(LLString("Mid"));
01005         }
01006         else
01007         {
01008                 text_box->setText(LLString("High"));
01009         }
01010 }
01011 
01012 void LLPanelDisplay::updateMeterText(LLUICtrl* ctrl, void* user_data)
01013 {
01014         // get our UI widgets
01015         LLPanelDisplay* panel = (LLPanelDisplay*)user_data;
01016         LLSliderCtrl* slider = (LLSliderCtrl*) ctrl;
01017 
01018         LLTextBox* m1 = panel->getChild<LLTextBox>("DrawDistanceMeterText1");
01019         LLTextBox* m2 = panel->getChild<LLTextBox>("DrawDistanceMeterText2");
01020 
01021         // toggle the two text boxes based on whether we have 1 or two digits
01022         F32 val = slider->getValueF32();
01023         bool two_digits = val < 100;
01024         m1->setVisible(two_digits);
01025         m2->setVisible(!two_digits);
01026 }
01027 
01028 
01029 

Generated on Fri May 16 08:33:50 2008 for SecondLife by  doxygen 1.5.5