Files
SingularityViewer/indra/newview/llpaneldisplay.cpp
Lirusaito a7f02b3964 Migrate LLFloaterHardwareSettings into a tab in LLPanelDisplay
Still not translated, left the old translated floaters for easier translation.
New Hardware Tab is work in progress, it should be more populated in the future, but is fine for now.
2012-07-25 18:11:48 -04:00

1188 lines
39 KiB
C++

/**
* @file llpaneldisplay.cpp
* @brief Display preferences for the preferences floater
*
* $LicenseInfo:firstyear=2001&license=viewergpl$
*
* Copyright (c) 2001-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
// file include
#include "llpaneldisplay.h"
// linden library includes
#include "llerror.h"
#include "llfontgl.h"
#include "llrect.h"
#include "llstring.h"
// project includes
#include "llagent.h"
#include "llbutton.h"
#include "llcheckboxctrl.h"
#include "llcombobox.h"
#include "llflexibleobject.h"
#include "lllineeditor.h"
#include "llradiogroup.h"
#include "llresmgr.h"
#include "llsliderctrl.h"
#include "llspinctrl.h"
#include "llstartup.h"
#include "lltextbox.h"
#include "lltexteditor.h"
#include "llui.h"
#include "llviewercamera.h"
#include "llviewertexturelist.h"
#include "llviewermessage.h"
#include "llviewerobjectlist.h"
#include "llviewerwindow.h"
#include "llvoavatar.h"
#include "llvovolume.h"
#include "llvotree.h"
#include "llvosky.h"
#include "llwindow.h"
#include "llworld.h"
#include "pipeline.h"
#include "lluictrlfactory.h"
#include "llfeaturemanager.h"
#include "llviewershadermgr.h"
#include "llboost.h"
//RN temporary includes for resolution switching
#include "llglheaders.h"
#include "llviewercontrol.h"
#include "llsky.h"
// parent
#include "llfloaterpreference.h"
// [RLVa:KB]
#include "rlvhandler.h"
// [/RLVa:KB]
#if LL_MSVC
#pragma warning( disable : 4265 ) // "class has virtual functions, but destructor is not virtual"
#endif
#include <boost/regex.hpp>
const F32 MAX_USER_FAR_CLIP = 512.f;
const F32 MIN_USER_FAR_CLIP = 64.f;
const S32 ASPECT_RATIO_STR_LEN = 100;
LLPanelDisplay::LLPanelDisplay()
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_preferences_graphics1.xml");
}
BOOL LLPanelDisplay::postBuild()
{
// return to default values
childSetAction("Defaults", setHardwareDefaults, NULL);
// Help button
childSetAction("GraphicsPreferencesHelpButton", onOpenHelp, this);
//============================================================================
// Resolution
// radio set for fullscreen size
mCtrlWindowed = getChild<LLCheckBoxCtrl>( "windowed mode");
mCtrlWindowed->setCommitCallback(&LLPanelDisplay::onCommitWindowedMode);
mCtrlWindowed->setCallbackUserData(this);
mAspectRatioLabel1 = getChild<LLTextBox>("AspectRatioLabel1");
mFullScreenInfo = getChild<LLTextEditor>("FullScreenInfo");
mDisplayResLabel = getChild<LLTextBox>("DisplayResLabel");
S32 num_resolutions = 0;
LLWindow::LLWindowResolution* supported_resolutions = gViewerWindow->getWindow()->getSupportedResolutions(num_resolutions);
S32 fullscreen_mode = num_resolutions - 1;
mCtrlFullScreen = getChild<LLComboBox>( "fullscreen combo");
LLUIString resolution_label = getString("resolution_format");
for (S32 i = 0; i < num_resolutions; i++)
{
resolution_label.setArg("[RES_X]", llformat("%d", supported_resolutions[i].mWidth));
resolution_label.setArg("[RES_Y]", llformat("%d", supported_resolutions[i].mHeight));
mCtrlFullScreen->add( resolution_label, ADD_BOTTOM );
}
{
BOOL targetFullscreen;
S32 targetWidth;
S32 targetHeight;
gViewerWindow->getTargetWindow(targetFullscreen, targetWidth, targetHeight);
if (targetFullscreen)
{
fullscreen_mode = 0; // default to 800x600
for (S32 i = 0; i < num_resolutions; i++)
{
if (targetWidth == supported_resolutions[i].mWidth
&& targetHeight == supported_resolutions[i].mHeight)
{
fullscreen_mode = i;
}
}
mCtrlFullScreen->setCurrentByIndex(fullscreen_mode);
mCtrlWindowed->set(FALSE);
mCtrlFullScreen->setVisible(TRUE);
}
else
{
// set to windowed mode
//fullscreen_mode = mCtrlFullScreen->getItemCount() - 1;
mCtrlWindowed->set(TRUE);
mCtrlFullScreen->setCurrentByIndex(0);
mCtrlFullScreen->setVisible(FALSE);
}
}
initWindowSizeControls();
if (gSavedSettings.getBOOL("FullScreenAutoDetectAspectRatio"))
{
mAspectRatio = gViewerWindow->getDisplayAspectRatio();
}
else
{
mAspectRatio = gSavedSettings.getF32("FullScreenAspectRatio");
}
S32 numerator = 0;
S32 denominator = 0;
fractionFromDecimal(mAspectRatio, numerator, denominator);
LLUIString aspect_ratio_text = getString("aspect_ratio_text");
if (numerator != 0)
{
aspect_ratio_text.setArg("[NUM]", llformat("%d", numerator));
aspect_ratio_text.setArg("[DEN]", llformat("%d", denominator));
}
else
{
aspect_ratio_text = llformat("%.3f", mAspectRatio);
}
mCtrlAspectRatio = getChild<LLComboBox>( "aspect_ratio");
mCtrlAspectRatio->setTextEntryCallback(onKeystrokeAspectRatio);
mCtrlAspectRatio->setCommitCallback(onSelectAspectRatio);
mCtrlAspectRatio->setCallbackUserData(this);
// add default aspect ratios
mCtrlAspectRatio->add(aspect_ratio_text, &mAspectRatio, ADD_TOP);
mCtrlAspectRatio->setCurrentByIndex(0);
mCtrlAutoDetectAspect = getChild<LLCheckBoxCtrl>( "aspect_auto_detect");
mCtrlAutoDetectAspect->setCommitCallback(onCommitAutoDetectAspect);
mCtrlAutoDetectAspect->setCallbackUserData(this);
// radio performance box
mCtrlSliderQuality = getChild<LLSliderCtrl>("QualityPerformanceSelection");
mCtrlSliderQuality->setSliderMouseUpCallback(boost::bind(&LLPanelDisplay::onChangeQuality,mCtrlSliderQuality,this));
mCtrlSliderQuality->setCallbackUserData(this);
mCtrlCustomSettings = getChild<LLCheckBoxCtrl>("CustomSettings");
mCtrlCustomSettings->setCommitCallback(onChangeCustom);
mCtrlCustomSettings->setCallbackUserData(this);
mGraphicsBorder = getChild<LLViewBorder>("GraphicsBorder");
// Enable Transparent Water
mCtrlTransparentWater = getChild<LLCheckBoxCtrl>("TransparentWater");
//----------------------------------------------------------------------------
// Enable Bump/Shiny
mCtrlBumpShiny = getChild<LLCheckBoxCtrl>("BumpShiny");
//----------------------------------------------------------------------------
// Enable Reflections
mCtrlReflectionDetail = getChild<LLComboBox>("ReflectionDetailCombo");
mCtrlReflectionDetail->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable);
mCtrlReflectionDetail->setCallbackUserData(this);
// WindLight
mCtrlWindLight = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
mCtrlWindLight->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable);
mCtrlWindLight->setCallbackUserData(this);
// Deferred
mCtrlDeferred = getChild<LLCheckBoxCtrl>("RenderDeferred");
mCtrlDeferred->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable);
mCtrlDeferred->setCallbackUserData(this);
mCtrlDeferredDoF = getChild<LLCheckBoxCtrl>("RenderDepthOfField");
mCtrlDeferredDoF->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable);
mCtrlDeferredDoF->setCallbackUserData(this);
mCtrlShadowDetail = getChild<LLComboBox>("ShadowDetailCombo");
mCtrlShadowDetail->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable);
mCtrlShadowDetail->setCallbackUserData(this);
//----------------------------------------------------------------------------
// Terrain Scale
mCtrlTerrainScale = getChild<LLComboBox>("TerrainScaleCombo");
//----------------------------------------------------------------------------
// Enable Avatar Shaders
mCtrlAvatarVP = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
mCtrlAvatarVP->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable);
mCtrlAvatarVP->setCallbackUserData(this);
//----------------------------------------------------------------------------
// Avatar Render Mode
mCtrlAvatarCloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
mCtrlAvatarImpostors = getChild<LLCheckBoxCtrl>("AvatarImpostors");
mCtrlAvatarImpostors->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable);
mCtrlAvatarImpostors->setCallbackUserData(this);
mCtrlNonImpostors = getChild<LLSliderCtrl>("AvatarMaxVisible");
//----------------------------------------------------------------------------
// Checkbox for lighting detail
mCtrlLightingDetail2 = getChild<LLCheckBoxCtrl>("LightingDetailRadio");
//----------------------------------------------------------------------------
// Checkbox for ambient occlusion
mCtrlAmbientOcc = getChild<LLCheckBoxCtrl>("UseSSAO");
//----------------------------------------------------------------------------
// radio set for terrain detail mode
mRadioTerrainDetail = getChild<LLRadioGroup>("TerrainDetailRadio");
//----------------------------------------------------------------------------
// Global Shader Enable
mCtrlShaderEnable = getChild<LLCheckBoxCtrl>("BasicShaders");
mCtrlShaderEnable->setCommitCallback(&LLPanelDisplay::onVertexShaderEnable);
mCtrlShaderEnable->setCallbackUserData(this);
//============================================================================
// Object detail slider
mCtrlDrawDistance = getChild<LLSliderCtrl>("DrawDistance");
mDrawDistanceMeterText1 = getChild<LLTextBox>("DrawDistanceMeterText1");
mDrawDistanceMeterText2 = getChild<LLTextBox>("DrawDistanceMeterText2");
mCtrlDrawDistance->setCommitCallback(&LLPanelDisplay::updateMeterText);
mCtrlDrawDistance->setCallbackUserData(this);
// Object detail slider
mCtrlLODFactor = getChild<LLSliderCtrl>("ObjectMeshDetail");
mLODFactorText = getChild<LLTextBox>("ObjectMeshDetailText");
mCtrlLODFactor->setCommitCallback(&LLPanelDisplay::updateSliderText);
mCtrlLODFactor->setCallbackUserData(mLODFactorText);
// Flex object detail slider
mCtrlFlexFactor = getChild<LLSliderCtrl>("FlexibleMeshDetail");
mFlexFactorText = getChild<LLTextBox>("FlexibleMeshDetailText");
mCtrlFlexFactor->setCommitCallback(&LLPanelDisplay::updateSliderText);
mCtrlFlexFactor->setCallbackUserData(mFlexFactorText);
// Tree detail slider
mCtrlTreeFactor = getChild<LLSliderCtrl>("TreeMeshDetail");
mTreeFactorText = getChild<LLTextBox>("TreeMeshDetailText");
mCtrlTreeFactor->setCommitCallback(&LLPanelDisplay::updateSliderText);
mCtrlTreeFactor->setCallbackUserData(mTreeFactorText);
// Avatar detail slider
mCtrlAvatarFactor = getChild<LLSliderCtrl>("AvatarMeshDetail");
mAvatarFactorText = getChild<LLTextBox>("AvatarMeshDetailText");
mCtrlAvatarFactor->setCommitCallback(&LLPanelDisplay::updateSliderText);
mCtrlAvatarFactor->setCallbackUserData(mAvatarFactorText);
// Avatar physics detail slider
mCtrlAvatarPhysicsFactor = getChild<LLSliderCtrl>("AvatarPhysicsDetail");
mAvatarPhysicsFactorText = getChild<LLTextBox>("AvatarPhysicsDetailText");
mCtrlAvatarPhysicsFactor->setCommitCallback(&LLPanelDisplay::updateSliderText);
mCtrlAvatarPhysicsFactor->setCallbackUserData(mAvatarPhysicsFactorText);
// Terrain detail slider
mCtrlTerrainFactor = getChild<LLSliderCtrl>("TerrainMeshDetail");
mTerrainFactorText = getChild<LLTextBox>("TerrainMeshDetailText");
mCtrlTerrainFactor->setCommitCallback(&LLPanelDisplay::updateSliderText);
mCtrlTerrainFactor->setCallbackUserData(mTerrainFactorText);
// Terrain detail slider
mCtrlSkyFactor = getChild<LLSliderCtrl>("SkyMeshDetail");
mSkyFactorText = getChild<LLTextBox>("SkyMeshDetailText");
mCtrlSkyFactor->setCommitCallback(&LLPanelDisplay::updateSliderText);
mCtrlSkyFactor->setCallbackUserData(mSkyFactorText);
// Particle detail slider
mCtrlMaxParticle = getChild<LLSliderCtrl>("MaxParticleCount");
// Glow detail slider
mCtrlPostProcess = getChild<LLSliderCtrl>("RenderPostProcess");
mPostProcessText = getChild<LLTextBox>("PostProcessText");
mCtrlPostProcess->setCommitCallback(&LLPanelDisplay::updateSliderText);
mCtrlPostProcess->setCallbackUserData(mPostProcessText);
// Text boxes (for enabling/disabling)
mShaderText = getChild<LLTextBox>("ShadersText");
mReflectionText = getChild<LLTextBox>("ReflectionDetailText");
mAvatarText = getChild<LLTextBox>("AvatarRenderingText");
mTerrainText = getChild<LLTextBox>("TerrainDetailText");
mLightingText = getChild<LLTextBox>("LightingDetailText");
mMeshDetailText = getChild<LLTextBox>("MeshDetailText");
mShadowDetailText = getChild<LLTextBox>("ShadowDetailText");
mTerrainScaleText = getChild<LLTextBox>("TerrainScaleText");
// Hardware tab
childSetCommitCallback("vbo", &LLPanelDisplay::onRenderVBOEnable, this);
refresh();
return TRUE;
}
void LLPanelDisplay::initWindowSizeControls()
{
// Window size
mWindowSizeLabel = getChild<LLTextBox>("WindowSizeLabel");
mCtrlWindowSize = getChild<LLComboBox>("windowsize combo");
// Look to see if current window size matches existing window sizes, if so then
// just set the selection value...
const U32 height = gViewerWindow->getWindowDisplayHeight();
const U32 width = gViewerWindow->getWindowDisplayWidth();
for (S32 i=0; i < mCtrlWindowSize->getItemCount(); i++)
{
U32 height_test = 0;
U32 width_test = 0;
mCtrlWindowSize->setCurrentByIndex(i);
if (extractWindowSizeFromString(mCtrlWindowSize->getValue().asString(), width_test, height_test))
{
if ((height_test == height) && (width_test == width))
{
return;
}
}
}
// ...otherwise, add a new entry with the current window height/width.
LLUIString resolution_label = getString("resolution_format");
resolution_label.setArg("[RES_X]", llformat("%d", width));
resolution_label.setArg("[RES_Y]", llformat("%d", height));
mCtrlWindowSize->add(resolution_label, ADD_TOP);
mCtrlWindowSize->setCurrentByIndex(0);
}
LLPanelDisplay::~LLPanelDisplay()
{
// clean up user data
for (S32 i = 0; i < mCtrlAspectRatio->getItemCount(); i++)
{
mCtrlAspectRatio->setCurrentByIndex(i);
}
for (S32 i = 0; i < mCtrlWindowSize->getItemCount(); i++)
{
mCtrlWindowSize->setCurrentByIndex(i);
}
}
void LLPanelDisplay::refresh()
{
LLPanel::refresh();
mFSAutoDetectAspect = gSavedSettings.getBOOL("FullScreenAutoDetectAspectRatio");
mQualityPerformance = gSavedSettings.getU32("RenderQualityPerformance");
mCustomSettings = gSavedSettings.getBOOL("RenderCustomSettings");
mTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
// shader settings
mBumpShiny = gSavedSettings.getBOOL("RenderObjectBump");
mShaderEnable = gSavedSettings.getBOOL("VertexShaderEnable");
mWindLight = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
mAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP");
mDeferred = gSavedSettings.getBOOL("RenderDeferred");
mDeferredDoF = gSavedSettings.getBOOL("RenderDepthOfField");
// combo boxes
mReflectionDetail = gSavedSettings.getS32("RenderReflectionDetail");
mShadowDetail = gSavedSettings.getS32("RenderShadowDetail");
mTerrainScale = gSavedSettings.getF32("RenderTerrainScale");
// avatar settings
mAvatarImpostors = gSavedSettings.getBOOL("RenderUseImpostors");
mNonImpostors = gSavedSettings.getS32("RenderAvatarMaxVisible");
mAvatarCloth = gSavedSettings.getBOOL("RenderAvatarCloth");
// Draw distance
mRenderFarClip = gSavedSettings.getF32("RenderFarClip");
// sliders and their text boxes
mPrimLOD = gSavedSettings.getF32("RenderVolumeLODFactor");
mFlexLOD = gSavedSettings.getF32("RenderFlexTimeFactor");
mTreeLOD = gSavedSettings.getF32("RenderTreeLODFactor");
mAvatarLOD = gSavedSettings.getF32("RenderAvatarLODFactor");
mTerrainLOD = gSavedSettings.getF32("RenderTerrainLODFactor");
mSkyLOD = gSavedSettings.getU32("WLSkyDetail");
mParticleCount = gSavedSettings.getS32("RenderMaxPartCount");
mPostProcess = gSavedSettings.getS32("RenderGlowResolutionPow");
// lighting and terrain radios
mLocalLights = gSavedSettings.getBOOL("RenderLocalLights");
mTerrainDetail = gSavedSettings.getS32("RenderTerrainDetail");
// slider text boxes
updateSliderText(mCtrlLODFactor, mLODFactorText);
updateSliderText(mCtrlFlexFactor, mFlexFactorText);
updateSliderText(mCtrlTreeFactor, mTreeFactorText);
updateSliderText(mCtrlAvatarFactor, mAvatarFactorText);
updateSliderText(mCtrlAvatarPhysicsFactor, mAvatarPhysicsFactorText);
updateSliderText(mCtrlTerrainFactor, mTerrainFactorText);
updateSliderText(mCtrlPostProcess, mPostProcessText);
updateSliderText(mCtrlSkyFactor, mSkyFactorText);
// Hardware tab
mUseVBO = gSavedSettings.getBOOL("RenderVBOEnable");
mUseFBO = gSavedSettings.getBOOL("RenderUseFBO");
mUseAniso = gSavedSettings.getBOOL("RenderAnisotropic");
mFSAASamples = gSavedSettings.getU32("RenderFSAASamples");
mGamma = gSavedSettings.getF32("RenderGamma");
mVideoCardMem = gSavedSettings.getS32("TextureMemory");
mFogRatio = gSavedSettings.getF32("RenderFogRatio");
childSetValue("fsaa", (LLSD::Integer) mFSAASamples);
refreshEnabledState();
}
void LLPanelDisplay::refreshEnabledState()
{
// if in windowed mode, disable full screen options
bool isFullScreen = !mCtrlWindowed->get();
mDisplayResLabel->setVisible(isFullScreen);
mCtrlFullScreen->setVisible(isFullScreen);
mCtrlAspectRatio->setVisible(isFullScreen);
mAspectRatioLabel1->setVisible(isFullScreen);
mCtrlAutoDetectAspect->setVisible(isFullScreen);
mFullScreenInfo->setVisible(!isFullScreen);
mWindowSizeLabel->setVisible(!isFullScreen);
mCtrlWindowSize->setVisible(!isFullScreen);
// disable graphics settings and exit if it's not set to custom
if(!gSavedSettings.getBOOL("RenderCustomSettings"))
{
setHiddenGraphicsState(true);
return;
}
// otherwise turn them all on and selectively turn off others
else
{
setHiddenGraphicsState(false);
}
// Reflections
BOOL reflections = gSavedSettings.getBOOL("VertexShaderEnable")
&& gGLManager.mHasCubeMap
&& LLCubeMap::sUseCubeMaps;
mCtrlReflectionDetail->setEnabled(reflections);
// Bump & Shiny
bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
mCtrlBumpShiny->setEnabled(bumpshiny ? TRUE : FALSE);
if (gSavedSettings.getBOOL("VertexShaderEnable") == FALSE ||
gSavedSettings.getBOOL("RenderAvatarVP") == FALSE)
{
mCtrlAvatarCloth->setEnabled(false);
}
else
{
mCtrlAvatarCloth->setEnabled(true);
}
static LLCachedControl<bool> wlatmos("WindLightUseAtmosShaders",false);
//I actually recommend RenderUseFBO:FALSE for ati users when not using deferred, so RenderUseFBO shouldn't control visibility of the element.
// Instead, gGLManager.mHasFramebufferObject seems better as it is determined by hardware and not current user settings. -Shyotl
//Enabling deferred will force RenderUseFBO to TRUE.
BOOL can_defer = gGLManager.mHasFramebufferObject &&
LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && //Ensure it's enabled in the gpu feature table
LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP") && //Hardware Skinning. Deferred forces RenderAvatarVP to true
LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") && gSavedSettings.getBOOL("VertexShaderEnable") && //Basic Shaders
LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders") && wlatmos; //Atmospheric Shaders
mCtrlDeferred->setEnabled(can_defer);
static LLCachedControl<bool> render_deferred("RenderDeferred",false);
mCtrlShadowDetail->setEnabled(can_defer && render_deferred);
mCtrlAmbientOcc->setEnabled(can_defer && render_deferred);
mCtrlDeferredDoF->setEnabled(can_defer && render_deferred);
// Disable max non-impostors slider if avatar impostors are off
mCtrlNonImpostors->setEnabled(gSavedSettings.getBOOL("RenderUseImpostors"));
// Vertex Shaders
// mCtrlShaderEnable->setEnabled(LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"));
// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0a
// "Basic Shaders" can't be disabled - but can be enabled - under @setenv=n
bool fCtrlShaderEnable = LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable");
mCtrlShaderEnable->setEnabled(fCtrlShaderEnable && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETENV) || !mShaderEnable));
// [/RLVa:KB]
bool shaders = mCtrlShaderEnable->get();
if (shaders)
{
mRadioTerrainDetail->setValue(1);
mRadioTerrainDetail->setEnabled(false);
}
else
{
mRadioTerrainDetail->setEnabled(true);
}
// *HACK just checks to see if we can use shaders...
// maybe some cards that use shaders, but don't support windlight
// mCtrlWindLight->setEnabled(mCtrlShaderEnable->getEnabled() && shaders);
// [RLVa:KB] - Checked: 2009-07-10 (RLVa-1.0.0g) | Modified: RLVa-0.2.0a
// "Atmospheric Shaders" can't be disabled - but can be enabled - under @setenv=n
bool fCtrlWindLightEnable = fCtrlShaderEnable && shaders;
mCtrlWindLight->setEnabled(fCtrlWindLightEnable && (!gRlvHandler.hasBehaviour(RLV_BHVR_SETENV) || !mWindLight));
// [/RLVa:KB]
// turn off sky detail if atmospherics isn't on
mCtrlSkyFactor->setEnabled(wlatmos);
mSkyFactorText->setEnabled(wlatmos);
// Avatar Mode and FBO
childSetEnabled("fbo", gGLManager.mHasFramebufferObject && !LLPipeline::sRenderDeferred);
if (render_deferred && wlatmos && shaders)
{
childSetValue("fbo", true);
mCtrlAvatarVP->setEnabled(false);
mCtrlAvatarVP->setValue(true);
}
else if (!shaders)
{
mCtrlAvatarVP->setEnabled(false);
mCtrlAvatarVP->setValue(false);
}
else
{
mCtrlAvatarVP->setEnabled(true);
}
// Hardware tab
S32 min_tex_mem = LLViewerTextureList::getMinVideoRamSetting();
S32 max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting();
childSetMinValue("GrapicsCardTextureMemory", min_tex_mem);
childSetMaxValue("GrapicsCardTextureMemory", max_tex_mem);
if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
!gGLManager.mHasVertexBufferObject)
{
childSetEnabled("vbo", false);
//Streaming VBOs -Shyotl
childSetEnabled("vbo_stream", false);
}
else
{
childSetEnabled("vbo_stream", LLVertexBuffer::sEnableVBOs);
}
// if no windlight shaders, enable gamma, and fog distance
childSetEnabled("gamma",!wlatmos);
childSetEnabled("fog", !wlatmos);
childSetVisible("note", wlatmos);
// now turn off any features that are unavailable
disableUnavailableSettings();
}
void LLPanelDisplay::disableUnavailableSettings()
{
// if vertex shaders off, disable all shader related products
if(!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"))
{
mCtrlShaderEnable->setEnabled(FALSE);
mCtrlShaderEnable->setValue(FALSE);
mCtrlWindLight->setEnabled(FALSE);
mCtrlWindLight->setValue(FALSE);
mCtrlReflectionDetail->setEnabled(FALSE);
mCtrlReflectionDetail->setValue(FALSE);
mCtrlAvatarVP->setEnabled(FALSE);
mCtrlAvatarVP->setValue(FALSE);
mCtrlAvatarCloth->setEnabled(FALSE);
mCtrlAvatarCloth->setValue(FALSE);
mCtrlDeferred->setEnabled(FALSE);
mCtrlDeferred->setValue(FALSE);
mCtrlAmbientOcc->setEnabled(FALSE);
mCtrlAmbientOcc->setValue(FALSE);
mCtrlDeferredDoF->setEnabled(FALSE);
mCtrlDeferredDoF->setValue(FALSE);
mCtrlShadowDetail->setEnabled(FALSE);
mCtrlShadowDetail->setValue(FALSE);
}
// disabled windlight
if(!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
{
mCtrlWindLight->setEnabled(FALSE);
mCtrlWindLight->setValue(FALSE);
}
// disabled reflections
if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail"))
{
mCtrlReflectionDetail->setEnabled(FALSE);
mCtrlReflectionDetail->setValue(FALSE);
}
// disabled terrain scale
if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderTerrainScale"))
{
mCtrlTerrainScale->setEnabled(false);
mCtrlTerrainScale->setValue(false);
}
// disabled av
if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP"))
{
mCtrlAvatarVP->setEnabled(FALSE);
mCtrlAvatarVP->setValue(FALSE);
mCtrlAvatarCloth->setEnabled(FALSE);
mCtrlAvatarCloth->setValue(FALSE);
}
// disabled cloth
if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth"))
{
mCtrlAvatarCloth->setEnabled(FALSE);
mCtrlAvatarCloth->setValue(FALSE);
}
// disabled impostors
if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderUseImpostors"))
{
mCtrlAvatarImpostors->setEnabled(FALSE);
mCtrlAvatarImpostors->setValue(FALSE);
mCtrlNonImpostors->setEnabled(FALSE);
}
// disabled deferred
if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"))
{
mCtrlDeferred->setEnabled(FALSE);
mCtrlDeferred->setValue(FALSE);
mCtrlAmbientOcc->setEnabled(FALSE);
mCtrlAmbientOcc->setValue(FALSE);
mCtrlDeferredDoF->setEnabled(FALSE);
mCtrlDeferredDoF->setValue(FALSE);
mCtrlShadowDetail->setEnabled(FALSE);
mCtrlShadowDetail->setValue(FALSE);
}
}
void LLPanelDisplay::setHiddenGraphicsState(bool isHidden)
{
// quick check
llassert(mGraphicsBorder != NULL);
llassert(mCtrlDrawDistance != NULL);
llassert(mCtrlLODFactor != NULL);
llassert(mCtrlFlexFactor != NULL);
llassert(mCtrlTreeFactor != NULL);
llassert(mCtrlAvatarFactor != NULL);
llassert(mCtrlTerrainFactor != NULL);
llassert(mCtrlSkyFactor != NULL);
llassert(mCtrlMaxParticle != NULL);
llassert(mCtrlPostProcess != NULL);
llassert(mLODFactorText != NULL);
llassert(mFlexFactorText != NULL);
llassert(mTreeFactorText != NULL);
llassert(mAvatarFactorText != NULL);
llassert(mTerrainFactorText != NULL);
llassert(mSkyFactorText != NULL);
llassert(mPostProcessText != NULL);
llassert(mCtrlTransparentWater != NULL);
llassert(mCtrlBumpShiny != NULL);
llassert(mCtrlWindLight != NULL);
llassert(mCtrlAvatarVP != NULL);
llassert(mCtrlShaderEnable != NULL);
llassert(mCtrlAvatarImpostors != NULL);
llassert(mCtrlNonImpostors != NULL);
llassert(mCtrlAvatarCloth != NULL);
llassert(mCtrlLightingDetail2 != NULL);
llassert(mCtrlAmbientOcc != NULL);
llassert(mRadioTerrainDetail != NULL);
llassert(mCtrlReflectionDetail != NULL);
llassert(mCtrlTerrainScale != NULL);
llassert(mMeshDetailText != NULL);
llassert(mShaderText != NULL);
llassert(mReflectionText != NULL);
llassert(mTerrainScaleText != NULL);
llassert(mAvatarText != NULL);
llassert(mLightingText != NULL);
llassert(mTerrainText != NULL);
llassert(mDrawDistanceMeterText1 != NULL);
llassert(mDrawDistanceMeterText2 != NULL);
// enable/disable the states
mGraphicsBorder->setVisible(!isHidden);
/*
LLColor4 light(.45098f, .51765f, .6078f, 1.0f);
LLColor4 dark(.10196f, .10196f, .10196f, 1.0f);
b ? mGraphicsBorder->setColors(dark, light) : mGraphicsBorder->setColors(dark, dark);
*/
mCtrlDrawDistance->setVisible(!isHidden);
mCtrlLODFactor->setVisible(!isHidden);
mCtrlFlexFactor->setVisible(!isHidden);
mCtrlTreeFactor->setVisible(!isHidden);
mCtrlAvatarFactor->setVisible(!isHidden);
mCtrlAvatarPhysicsFactor->setVisible(!isHidden);
mCtrlTerrainFactor->setVisible(!isHidden);
mCtrlSkyFactor->setVisible(!isHidden);
mCtrlMaxParticle->setVisible(!isHidden);
mCtrlPostProcess->setVisible(!isHidden);
mLODFactorText->setVisible(!isHidden);
mFlexFactorText->setVisible(!isHidden);
mTreeFactorText->setVisible(!isHidden);
mAvatarFactorText->setVisible(!isHidden);
mAvatarPhysicsFactorText->setVisible(!isHidden);
mTerrainFactorText->setVisible(!isHidden);
mSkyFactorText->setVisible(!isHidden);
mPostProcessText->setVisible(!isHidden);
mCtrlTransparentWater->setVisible(!isHidden);
mCtrlBumpShiny->setVisible(!isHidden);
mCtrlWindLight->setVisible(!isHidden);
mCtrlAvatarVP->setVisible(!isHidden);
mCtrlShaderEnable->setVisible(!isHidden);
mCtrlAvatarImpostors->setVisible(!isHidden);
mCtrlNonImpostors->setVisible(!isHidden);
mCtrlAvatarCloth->setVisible(!isHidden);
mCtrlLightingDetail2->setVisible(!isHidden);
mCtrlAmbientOcc->setVisible(!isHidden);
mRadioTerrainDetail->setVisible(!isHidden);
mCtrlReflectionDetail->setVisible(!isHidden);
mCtrlTerrainScale->setVisible(!isHidden);
mCtrlDeferred->setVisible(!isHidden);
mCtrlDeferredDoF->setVisible(!isHidden);
mCtrlShadowDetail->setVisible(!isHidden);
// text boxes
mShaderText->setVisible(!isHidden);
mReflectionText->setVisible(!isHidden);
mAvatarText->setVisible(!isHidden);
mLightingText->setVisible(!isHidden);
mTerrainText->setVisible(!isHidden);
mDrawDistanceMeterText1->setVisible(!isHidden);
mDrawDistanceMeterText2->setVisible(!isHidden);
mShadowDetailText->setVisible(!isHidden);
mTerrainScaleText->setVisible(!isHidden);
// hide one meter text if we're making things visible
if(!isHidden)
{
updateMeterText(mCtrlDrawDistance, this);
}
mMeshDetailText->setVisible(!isHidden);
}
void LLPanelDisplay::cancel()
{
gSavedSettings.setBOOL("FullScreenAutoDetectAspectRatio", mFSAutoDetectAspect);
gSavedSettings.setF32("FullScreenAspectRatio", mAspectRatio);
gSavedSettings.setU32("RenderQualityPerformance", mQualityPerformance);
gSavedSettings.setBOOL("RenderCustomSettings", mCustomSettings);
gSavedSettings.setBOOL("RenderTransparentWater", mTransparentWater);
gSavedSettings.setBOOL("RenderObjectBump", mBumpShiny);
gSavedSettings.setBOOL("VertexShaderEnable", mShaderEnable);
gSavedSettings.setBOOL("WindLightUseAtmosShaders", mWindLight);
gSavedSettings.setBOOL("RenderAvatarVP", mAvatarVP);
gSavedSettings.setBOOL("RenderDeferred", mDeferred);
gSavedSettings.setBOOL("RenderDepthOfField", mDeferredDoF);
gSavedSettings.setS32("RenderReflectionDetail", mReflectionDetail);
gSavedSettings.setS32("RenderShadowDetail", mShadowDetail);
gSavedSettings.setF32("RenderTerrainScale", mTerrainScale);
gSavedSettings.setBOOL("RenderUseImpostors", mAvatarImpostors);
gSavedSettings.setS32("RenderAvatarMaxVisible", mNonImpostors);
gSavedSettings.setBOOL("RenderAvatarCloth", mAvatarCloth);
gSavedSettings.setBOOL("RenderLocalLights", mLocalLights);
gSavedSettings.setS32("RenderTerrainDetail", mTerrainDetail);
gSavedSettings.setF32("RenderFarClip", mRenderFarClip);
gSavedSettings.setF32("RenderVolumeLODFactor", mPrimLOD);
gSavedSettings.setF32("RenderFlexTimeFactor", mFlexLOD);
gSavedSettings.setF32("RenderTreeLODFactor", mTreeLOD);
gSavedSettings.setF32("RenderAvatarLODFactor", mAvatarLOD);
gSavedSettings.setF32("RenderTerrainLODFactor", mTerrainLOD);
gSavedSettings.setU32("WLSkyDetail", mSkyLOD);
gSavedSettings.setS32("RenderMaxPartCount", mParticleCount);
gSavedSettings.setS32("RenderGlowResolutionPow", mPostProcess);
// Hardware tab
gSavedSettings.setBOOL("RenderVBOEnable", mUseVBO);
gSavedSettings.setBOOL("RenderUseFBO", mUseFBO);
gSavedSettings.setBOOL("RenderAnisotropic", mUseAniso);
gSavedSettings.setU32("RenderFSAASamples", mFSAASamples);
gSavedSettings.setF32("RenderGamma", mGamma);
gSavedSettings.setS32("TextureMemory", mVideoCardMem);
gSavedSettings.setF32("RenderFogRatio", mFogRatio);
}
void LLPanelDisplay::apply()
{
applyResolution();
// Only set window size if we're not in fullscreen mode
if (mCtrlWindowed->get())
{
applyWindowSize();
}
// Hardware tab
//Still do a bit of voodoo here. V2 forces restart to change FSAA with FBOs off.
//Let's not do that, and instead do pre-V2 FSAA change handling for that particular case
if(!LLRenderTarget::sUseFBO && (mFSAASamples != (U32)childGetValue("fsaa").asInteger()))
{
bool logged_in = (LLStartUp::getStartupState() >= STATE_STARTED);
LLWindow* window = gViewerWindow->getWindow();
LLCoordScreen size;
window->getSize(&size);
gViewerWindow->changeDisplaySettings(window->getFullscreen(),
size,
gSavedSettings.getBOOL("DisableVerticalSync"),
logged_in);
}
}
void LLPanelDisplay::onChangeQuality(LLUICtrl *ctrl, void *data)
{
LLSliderCtrl* sldr = static_cast<LLSliderCtrl*>(ctrl);
LLPanelDisplay* cur_panel = static_cast<LLPanelDisplay*>(data);
if(sldr == NULL || cur_panel == NULL)
{
return;
}
U32 set = (U32)sldr->getValueF32();
LLFeatureManager::getInstance()->setGraphicsLevel(set, true);
LLFloaterPreference::refreshEnabledGraphics();
cur_panel->refresh();
}
void LLPanelDisplay::onChangeCustom(LLUICtrl *ctrl, void *data)
{
LLFloaterPreference::refreshEnabledGraphics();
}
void LLPanelDisplay::onOpenHelp(void* user_data)
{
LLPanelDisplay* self = static_cast<LLPanelDisplay*>(user_data);
const char* xml_alert = "GraphicsPreferencesHelp";
LLFloater* parent_floater = gFloaterView->getParentFloater(self);
LLNotifications::instance().add(parent_floater->contextualNotification(xml_alert));
}
void LLPanelDisplay::onApplyResolution(LLUICtrl* src, void* user_data)
{
((LLPanelDisplay*) src)->applyResolution();
}
void LLPanelDisplay::applyResolution()
{
gGL.flush();
char aspect_ratio_text[ASPECT_RATIO_STR_LEN]; /*Flawfinder: ignore*/
if (mCtrlAspectRatio->getCurrentIndex() == -1)
{
// *Can't pass const char* from c_str() into strtok
strncpy(aspect_ratio_text, mCtrlAspectRatio->getSimple().c_str(), sizeof(aspect_ratio_text) -1); /*Flawfinder: ignore*/
aspect_ratio_text[sizeof(aspect_ratio_text) -1] = '\0';
char *element = strtok(aspect_ratio_text, ":/\\");
if (!element)
{
mAspectRatio = 0.f; // will be clamped later
}
else
{
LLLocale locale(LLLocale::USER_LOCALE);
mAspectRatio = (F32)atof(element);
}
// look for denominator
element = strtok(NULL, ":/\\");
if (element)
{
LLLocale locale(LLLocale::USER_LOCALE);
F32 denominator = (F32)atof(element);
if (denominator != 0.f)
{
mAspectRatio /= denominator;
}
}
}
else
{
mAspectRatio = (F32)mCtrlAspectRatio->getValue().asReal();
}
// presumably, user entered a non-numeric value if aspect_ratio == 0.f
if (mAspectRatio != 0.f)
{
mAspectRatio = llclamp(mAspectRatio, 0.2f, 5.f);
gSavedSettings.setF32("FullScreenAspectRatio", mAspectRatio);
}
// Screen resolution
S32 num_resolutions;
LLWindow::LLWindowResolution* supported_resolutions =
gViewerWindow->getWindow()->getSupportedResolutions(num_resolutions);
U32 resIndex = mCtrlFullScreen->getCurrentIndex();
gSavedSettings.setS32("FullScreenWidth", supported_resolutions[resIndex].mWidth);
gSavedSettings.setS32("FullScreenHeight", supported_resolutions[resIndex].mHeight);
gViewerWindow->requestResolutionUpdate(!mCtrlWindowed->get());
send_agent_update(TRUE);
// Update enable/disable
refresh();
}
// Extract from strings of the form "<width> x <height>", e.g. "640 x 480".
bool LLPanelDisplay::extractWindowSizeFromString(const std::string& instr, U32 &width, U32 &height)
{
using namespace boost;
cmatch what;
const regex expression("([0-9]+) x ([0-9]+)");
if (regex_match(instr.c_str(), what, expression))
{
width = atoi(what[1].first);
height = atoi(what[2].first);
return true;
}
width = height = 0;
return false;
}
void LLPanelDisplay::applyWindowSize()
{
if (mCtrlWindowSize->getVisible() && (mCtrlWindowSize->getCurrentIndex() != -1))
{
U32 width = 0;
U32 height = 0;
if (extractWindowSizeFromString(mCtrlWindowSize->getValue().asString().c_str(), width,height))
{
LLViewerWindow::movieSize(width, height);
}
}
}
//static
void LLPanelDisplay::onCommitWindowedMode(LLUICtrl* ctrl, void *data)
{
LLPanelDisplay *panel = (LLPanelDisplay*)data;
panel->refresh();
}
//static
void LLPanelDisplay::onCommitAutoDetectAspect(LLUICtrl *ctrl, void *data)
{
LLPanelDisplay *panel = (LLPanelDisplay*)data;
BOOL auto_detect = ((LLCheckBoxCtrl*)ctrl)->get();
F32 ratio;
if (auto_detect)
{
S32 numerator = 0;
S32 denominator = 0;
// clear any aspect ratio override
gViewerWindow->mWindow->setNativeAspectRatio(0.f);
fractionFromDecimal(gViewerWindow->mWindow->getNativeAspectRatio(), numerator, denominator);
std::string aspect;
if (numerator != 0)
{
aspect = llformat("%d:%d", numerator, denominator);
}
else
{
aspect = llformat("%.3f", gViewerWindow->mWindow->getNativeAspectRatio());
}
panel->mCtrlAspectRatio->setLabel(aspect);
ratio = gViewerWindow->mWindow->getNativeAspectRatio();
gSavedSettings.setF32("FullScreenAspectRatio", ratio);
}
}
//static
void LLPanelDisplay::onKeystrokeAspectRatio(LLLineEditor* caller, void* user_data)
{
LLPanelDisplay* panel = (LLPanelDisplay*)user_data;
panel->mCtrlAutoDetectAspect->set(FALSE);
}
//static
void LLPanelDisplay::onSelectAspectRatio(LLUICtrl*, void* user_data)
{
LLPanelDisplay* panel = (LLPanelDisplay*)user_data;
panel->mCtrlAutoDetectAspect->set(FALSE);
}
//static
void LLPanelDisplay::fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator)
{
numerator = 0;
denominator = 0;
for (F32 test_denominator = 1.f; test_denominator < 30.f; test_denominator += 1.f)
{
if (fmodf((decimal_val * test_denominator) + 0.01f, 1.f) < 0.02f)
{
numerator = llround(decimal_val * test_denominator);
denominator = llround(test_denominator);
break;
}
}
}
//static
void LLPanelDisplay::onVertexShaderEnable(LLUICtrl* self, void* data)
{
LLFloaterPreference::refreshEnabledGraphics();
}
//static
void LLPanelDisplay::onRenderVBOEnable(LLUICtrl* self, void* data)
{
LLPanelDisplay* panel = (LLPanelDisplay*)data;
bool enable = panel->childGetValue("vbo").asBoolean();
panel->childSetEnabled("vbo_stream", enable);
if(!enable) panel->childSetValue("vbo_stream", false);
}
void LLPanelDisplay::setHardwareDefaults(void* user_data)
{
LLFeatureManager::getInstance()->applyRecommendedSettings();
LLControlVariable* controlp = gSavedSettings.getControl("RenderAvatarMaxVisible");
if (controlp)
{
controlp->resetToDefault(true);
}
LLFloaterPreference::refreshEnabledGraphics();
}
void LLPanelDisplay::updateSliderText(LLUICtrl* ctrl, void* user_data)
{
// get our UI widgets
LLTextBox* text_box = (LLTextBox*)user_data;
LLSliderCtrl* slider = (LLSliderCtrl*) ctrl;
if(text_box == NULL || slider == NULL)
{
return;
}
//Hack to display 'Off' for avatar physics slider.
if(slider->getName() == "AvatarPhysicsDetail" && !slider->getValueF32())
{
text_box->setText(std::string("Off"));
return;
}
// get range and points when text should change
F32 range = slider->getMaxValue() - slider->getMinValue();
llassert(range > 0);
F32 midPoint = slider->getMinValue() + range / 3.0f;
F32 highPoint = slider->getMinValue() + (2.0f * range / 3.0f);
// choose the right text
if(slider->getValueF32() < midPoint)
{
text_box->setText(std::string("Low"));
}
else if (slider->getValueF32() < highPoint)
{
text_box->setText(std::string("Mid"));
}
else if(slider->getValueF32() < slider->getMaxValue())
{
text_box->setText(std::string("High"));
}
else
{
text_box->setText(std::string("Max"));
}
}
void LLPanelDisplay::updateMeterText(LLUICtrl* ctrl, void* user_data)
{
// get our UI widgets
LLPanelDisplay* panel = (LLPanelDisplay*)user_data;
LLSliderCtrl* slider = (LLSliderCtrl*) ctrl;
LLTextBox* m1 = panel->getChild<LLTextBox>("DrawDistanceMeterText1");
LLTextBox* m2 = panel->getChild<LLTextBox>("DrawDistanceMeterText2");
// toggle the two text boxes based on whether we have 1 or two digits
F32 val = slider->getValueF32();
bool two_digits = val < 100;
m1->setVisible(two_digits);
m2->setVisible(!two_digits);
}