1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146 |
- /**
- * @file llvosky.cpp
- * @brief LLVOSky class implementation
- *
- * $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"
- #include "llvosky.h"
- #include "imageids.h"
- #include "llcubemap.h"
- #include "llfasttimer.h"
- #include "llgl.h"
- #include "llagent.h"
- #include "lldrawable.h"
- #include "lldrawpoolsky.h"
- #include "lldrawpoolwater.h"
- #include "lldrawpoolwlsky.h"
- #include "llenvironment.h"
- #include "llface.h"
- #include "llfeaturemanager.h"
- #include "llpipeline.h"
- #include "llsky.h"
- #include "llviewercamera.h"
- #include "llviewercontrol.h"
- #include "llviewerobjectlist.h"
- #include "llviewerregion.h"
- #include "llviewertexturelist.h"
- #include "llworld.h"
- // Constants
- // Exported
- const F32 NIGHTTIME_ELEVATION_COS = sinf(NIGHTTIME_ELEVATION * DEG_TO_RAD);
- constexpr S32 NUM_TILES_X = 8;
- constexpr S32 NUM_TILES_Y = 4;
- constexpr S32 NUM_TILES = NUM_TILES_X * NUM_TILES_Y;
- // Amortize updating face; see sTileResX
- constexpr S32 UPDATE_TILES = NUM_TILES / 8;
- constexpr S32 NUM_CUBEMAP_FACES = 6;
- constexpr S32 TOTAL_TILES = NUM_CUBEMAP_FACES * NUM_TILES;
- constexpr S32 MAX_TILES = TOTAL_TILES + 1;
- // Heavenly body constants
- constexpr F32 SUN_DISK_RADIUS = 0.5f;
- constexpr F32 MOON_DISK_RADIUS = SUN_DISK_RADIUS * 0.9f;
- constexpr F32 SUN_INTENSITY = 1e5f;
- // Texture coordinates:
- const LLVector2 TEX00 = LLVector2(0.f, 0.f);
- const LLVector2 TEX01 = LLVector2(0.f, 1.f);
- const LLVector2 TEX10 = LLVector2(1.f, 0.f);
- const LLVector2 TEX11 = LLVector2(1.f, 1.f);
- constexpr F32 UPDATE_EXPIRY = 0.05f;
- constexpr F32 UPDATE_MIN_DELTA_THRESHOLD = 0.001f;
- // Exported globals
- LLUUID gSunTextureID = IMG_SUN;
- LLUUID gMoonTextureID = IMG_MOON;
- // Helpers
- bool almost_equal(const F32& a, const F32& b)
- {
- F32 diff = fabs(a - b);
- if (diff < F_APPROXIMATELY_ZERO)
- {
- return true;
- }
- if (diff < llmax(fabs(a), fabs(b)) * UPDATE_MIN_DELTA_THRESHOLD)
- {
- return true;
- }
- return false;
- }
- bool almost_equal(const LLColor3& a, const LLColor3& b)
- {
- return almost_equal((F32)a.mV[0], (F32)b.mV[0]) &&
- almost_equal((F32)a.mV[1], (F32)b.mV[1]) &&
- almost_equal((F32)a.mV[2], (F32)b.mV[2]);
- }
- bool almost_equal(const LLVector4& a, const LLVector4& b)
- {
- return almost_equal((F32)a.mV[0], (F32)b.mV[0]) &&
- almost_equal((F32)a.mV[1], (F32)b.mV[1]) &&
- almost_equal((F32)a.mV[2], (F32)b.mV[2]) &&
- almost_equal((F32)a.mV[3], (F32)b.mV[3]);
- }
- // Clip quads with top and bottom sides parallel to horizon.
- F32 clip_side_to_horizon(const LLVector3& V0, const LLVector3& V1,
- F32 cos_max_angle)
- {
- const LLVector3 V = V1 - V0;
- const F32 k2 = 1.f / (cos_max_angle * cos_max_angle) - 1.f;
- const F32 A = V.mV[0] * V.mV[0] + V.mV[1] * V.mV[1] -
- k2 * V.mV[2] * V.mV[2];
- const F32 B = V0.mV[0] * V.mV[0] + V0.mV[1] * V.mV[1] -
- k2 * V0.mV[2] * V.mV[2];
- const F32 C = V0.mV[0] * V0.mV[0] + V0.mV[1] * V0.mV[1] -
- k2 * V0.mV[2] * V0.mV[2];
- if (fabsf(A) < 1e-7f)
- {
- return -0.1f; // v0 is cone origin and v1 is on the surface of the cone
- }
- const F32 det = sqrtf(B * B - A * C);
- const F32 t1 = (-B - det) / A;
- const F32 t2 = (-B + det) / A;
- const F32 z1 = V0.mV[2] + t1 * V.mV[2];
- const F32 z2 = V0.mV[2] + t2 * V.mV[2];
- if (z1 * cos_max_angle < 0.f)
- {
- return t2;
- }
- else if (z2 * cos_max_angle < 0.f)
- {
- return t1;
- }
- else if (t1 < 0.f || t1 > 1.f)
- {
- return t2;
- }
- else
- {
- return t1;
- }
- }
- class LLFastLn
- {
- public:
- LLFastLn()
- {
- mTable[0] = 0.f;
- for (S32 i = 1; i < 257; ++i)
- {
- mTable[i] = logf((F32)i);
- }
- }
- F32 ln(F32 x)
- {
- constexpr F32 OO_255 = 0.003921568627450980392156862745098f;
- constexpr F32 LN_255 = 5.5412635451584261462455391880218f;
- if (x < OO_255)
- {
- return logf(x);
- }
- else if (x < 1.f)
- {
- x *= 255.f;
- S32 index = llfloor(x);
- F32 t = x - (F32)index;
- F32 low = mTable[index];
- F32 high = mTable[index + 1];
- return low + t * (high - low) - LN_255;
- }
- else if (x <= 255.f)
- {
- S32 index = llfloor(x);
- F32 t = x - (F32)index;
- F32 low = mTable[index];
- F32 high = mTable[index + 1];
- return low + t * (high - low);
- }
- else
- {
- return logf(x);
- }
- }
- F32 pow(F32 x, F32 y)
- {
- return (F32)LL_FAST_EXP(y * ln(x));
- }
- private:
- F32 mTable[257]; // index 0 is unused
- };
- static LLFastLn gFastLn;
- // Functions used a lot.
- LL_INLINE void color_pow(LLColor3& col, F32 e)
- {
- col.mV[0] = gFastLn.pow(col.mV[0], e);
- col.mV[1] = gFastLn.pow(col.mV[1], e);
- col.mV[2] = gFastLn.pow(col.mV[2], e);
- }
- LL_INLINE LLColor3 componentPowF(const LLColor3& v, F32 exponent)
- {
- return LLColor3(gFastLn.pow(v.mV[0], exponent),
- gFastLn.pow(v.mV[1], exponent),
- gFastLn.pow(v.mV[2], exponent));
- }
- LL_INLINE LLColor3 color_norm(const LLColor3& col)
- {
- const F32 m = color_max(col);
- if (m > 1.f)
- {
- return 1.f / m * col;
- }
- else return col;
- }
- LL_INLINE void color_gamma_correct(LLColor3& col)
- {
- constexpr F32 gamma_inv = 1.f / 1.2f;
- if (col.mV[0] != 0.f)
- {
- col.mV[0] = gFastLn.pow(col.mV[0], gamma_inv);
- }
- if (col.mV[1] != 0.f)
- {
- col.mV[1] = gFastLn.pow(col.mV[1], gamma_inv);
- }
- if (col.mV[2] != 0.f)
- {
- col.mV[2] = gFastLn.pow(col.mV[2], gamma_inv);
- }
- }
- /***************************************
- SkyTex
- ***************************************/
- S32 LLSkyTex::sComponents = 4;
- S32 LLSkyTex::sResolution = 64;
- F32 LLSkyTex::sInterpVal = 0.f;
- S32 LLSkyTex::sCurrent = 0;
- LLSkyTex::LLSkyTex()
- : mSkyData(NULL),
- mSkyDirs(NULL),
- mIsShiny(false)
- {
- }
- void LLSkyTex::init(bool shiny)
- {
- mIsShiny = shiny;
- mSkyData = new LLColor4U[sResolution * sResolution];
- mSkyDirs = new LLVector3[sResolution * sResolution];
- for (S32 i = 0; i < 2; ++i)
- {
- mTexture[i] = LLViewerTextureManager::getLocalTexture(false);
- mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
- mImageRaw[i] = new LLImageRaw(sResolution, sResolution, sComponents);
- initEmpty(i);
- }
- }
- void LLSkyTex::cleanupGL()
- {
- mTexture[0] = NULL;
- mTexture[1] = NULL;
- }
- void LLSkyTex::restoreGL()
- {
- for (S32 i = 0; i < 2; ++i)
- {
- mTexture[i] = LLViewerTextureManager::getLocalTexture(false);
- mTexture[i]->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
- }
- LLSkyTex::~LLSkyTex()
- {
- delete[] mSkyData;
- mSkyData = NULL;
- delete[] mSkyDirs;
- mSkyDirs = NULL;
- }
- void LLSkyTex::initEmpty(S32 tex)
- {
- U8* data = mImageRaw[tex]->getData();
- if (data)
- {
- for (S32 i = 0; i < sResolution; ++i)
- {
- for (S32 j = 0; j < sResolution; ++j)
- {
- const S32 basic_offset = i * sResolution + j;
- S32 offset = basic_offset * sComponents;
- data[offset] = 0;
- data[++offset] = 0;
- data[++offset] = 0;
- data[++offset] = 255;
- mSkyData[basic_offset].setToBlack();
- }
- }
- }
- createGLImage(tex);
- }
- void LLSkyTex::create()
- {
- U8* data = mImageRaw[sCurrent]->getData();
- if (data)
- {
- for (S32 i = 0; i < sResolution; ++i)
- {
- for (S32 j = 0; j < sResolution; ++j)
- {
- const S32 basic_offset = i * sResolution + j;
- S32 offset = basic_offset * sComponents;
- U32* pix = (U32*)(data + offset);
- *pix = mSkyData[basic_offset].asRGBA();
- }
- }
- }
- createGLImage(sCurrent);
- }
- void LLSkyTex::createGLImage(S32 which)
- {
- mTexture[which]->setExplicitFormat(GL_RGBA8, GL_RGBA);
- mTexture[which]->createGLTexture(0, mImageRaw[which], 0, true);
- mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
- void LLSkyTex::bindTexture(bool curr)
- {
- gGL.getTexUnit(0)->bind(mTexture[getWhich(curr)]);
- }
- /***************************************
- Sky
- ***************************************/
- F32 LLHeavenBody::sInterpVal = 0.f;
- S32 LLVOSky::sResolution = LLSkyTex::getResolution();
- S32 LLVOSky::sTileResX = sResolution / NUM_TILES_X;
- S32 LLVOSky::sTileResY = sResolution / NUM_TILES_Y;
- LLVOSky::LLVOSky(const LLUUID& id, LLViewerRegion* regionp)
- : LLStaticViewerObject(id, LL_VO_SKY, regionp, true),
- mSun(SUN_DISK_RADIUS),
- mMoon(MOON_DISK_RADIUS),
- mBrightnessScale(1.f),
- mBrightnessScaleNew(0.f),
- mBrightnessScaleGuess(1.f),
- mCloudDensity(0.2f),
- mWind(0.f),
- mWorldScale(1.f),
- mSunScale(1.f),
- mMoonScale(1.f),
- mInterpVal(0.f),
- mAtmHeight(ATM_HEIGHT),
- mBumpSunDir(0.f, 0.f, 1.f),
- mDrawRefl(0),
- mDomeRadius(SKY_DOME_RADIUS),
- mDomeOffset(SKY_DOME_OFFSET),
- mGamma(1.f),
- mHazeDensity(0.f),
- mDensityMultiplier(0.f),
- mCloudShadow(0.f),
- mMaxY(0.f),
- mHazeHorizon(1.f),
- mCubeMapUpdateStage(-1),
- mCubeMapUpdateTile(0),
- mWeatherChange(false),
- mForceUpdate(false),
- mNeedUpdate(true),
- mHeavenlyBodyUpdated(false),
- mInitialized(false)
- {
- mCanSelect = false;
- mUpdateTimer.reset();
- mForceUpdateThrottle.setTimerExpirySec(UPDATE_EXPIRY);
- mForceUpdateThrottle.reset();
- for (S32 i = 0; i < NUM_CUBEMAP_FACES; ++i)
- {
- mSkyTex[i].init(false);
- mShinyTex[i].init(true);
- }
- for (S32 i = 0; i < FACE_COUNT; ++i)
- {
- mFace[i] = NULL;
- }
- mCameraPosAgent = gAgent.getCameraPositionAgent();
- mEarthCenter = LLVector3(mCameraPosAgent.mV[0], mCameraPosAgent.mV[1],
- -EARTH_RADIUS);
- mSun.setIntensity(SUN_INTENSITY);
- mMoon.setIntensity(SUN_INTENSITY *
- gSavedSettings.getF32("RenderMoonLightIntensity"));
- mAmbientScale = gSavedSettings.getF32("SkyAmbientScale");
- mNightColorShift = gSavedSettings.getColor3("SkyNightColorShift");
- mFogColor.mV[VRED] = mFogColor.mV[VGREEN] = mFogColor.mV[VBLUE] = 0.5f;
- mFogColor.mV[VALPHA] = 0.f;
- if (gSunTextureID != IMG_SUN ||
- LLViewerFetchedTexture::sDefaultSunImagep.isNull())
- {
- mSunTexturep[0] =
- LLViewerTextureManager::getFetchedTexture(gSunTextureID,
- FTT_DEFAULT, true,
- LLGLTexture::BOOST_UI);
- mSunTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
- else
- {
- mSunTexturep[0] = LLViewerFetchedTexture::sDefaultSunImagep;
- }
- if (gMoonTextureID != IMG_MOON ||
- LLViewerFetchedTexture::sDefaultMoonImagep.isNull())
- {
- mMoonTexturep[0] =
- LLViewerTextureManager::getFetchedTexture(gMoonTextureID,
- FTT_DEFAULT, true,
- LLGLTexture::BOOST_UI);
- mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
- else
- {
- mMoonTexturep[0] = LLViewerFetchedTexture::sDefaultMoonImagep;
- }
- mBloomTexturep[0] = LLViewerFetchedTexture::sBloomImagep;
- mCloudNoiseTexturep[0] = LLViewerFetchedTexture::sDefaultCloudNoiseImagep;
- }
- LLVOSky::~LLVOSky()
- {
- // Do not delete images: they will get deleted by gTextureList on shutdown
- // This needs to be done for each texture
- mCubeMap = NULL;
- }
- void LLVOSky::init()
- {
- LLSettingsSky::ptr_t skyp = gEnvironment.getCurrentSky();
- bool has_sky = false;
- if (skyp) // Paranoia
- {
- has_sky = true;
- skyp->update();
- updateDirections(skyp);
- initAtmospherics(skyp);
- }
- // Initialize the cached normalized direction vectors
- for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
- {
- for (S32 tile = 0; tile < NUM_TILES; ++tile)
- {
- initSkyTextureDirs(side, tile);
- if (has_sky) // Paranoia
- {
- createSkyTexture(skyp, side, tile);
- }
- }
- mSkyTex[side].create();
- mShinyTex[side].create();
- }
- initCubeMap();
- mInitialized = true;
- mHeavenlyBodyUpdated = false;
- }
- void LLVOSky::initCubeMap()
- {
- std::vector<LLPointer<LLImageRaw> > images;
- for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
- {
- images.emplace_back(mShinyTex[side].getImageRaw());
- }
- if (mCubeMap)
- {
- mCubeMap->init(images);
- }
- else if (LLPipeline::sRenderWater)
- {
- mCubeMap = new LLCubeMap();
- mCubeMap->init(images);
- }
- gGL.getTexUnit(0)->disable();
- }
- void LLVOSky::cleanupGL()
- {
- for (S32 i = 0; i < NUM_CUBEMAP_FACES; ++i)
- {
- mSkyTex[i].cleanupGL();
- }
- if (getCubeMap())
- {
- getCubeMap()->destroyGL();
- }
- }
- void LLVOSky::restoreGL()
- {
- for (S32 i = 0; i < NUM_CUBEMAP_FACES; ++i)
- {
- mSkyTex[i].restoreGL();
- }
- const LLSettingsSky::ptr_t& skyp = gEnvironment.getCurrentSky();
- if (skyp) // Paranoia
- {
- setSunTextures(skyp->getSunTextureId(), skyp->getNextSunTextureId());
- setMoonTextures(skyp->getMoonTextureId(),
- skyp->getNextMoonTextureId());
- updateDirections(skyp);
- }
- if (LLPipeline::sRenderWater)
- {
- initCubeMap();
- }
- mForceUpdate = mNeedUpdate = true;
- mCubeMapUpdateStage = -1;
- mCubeMapUpdateTile = 0;
- if (mDrawable)
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
- }
- }
- void LLVOSky::initSkyTextureDirs(S32 side, S32 tile)
- {
- S32 tile_x = tile % NUM_TILES_X;
- S32 tile_y = tile / NUM_TILES_X;
- S32 tile_x_pos = tile_x * sTileResX;
- S32 tile_y_pos = tile_y * sTileResY;
- F32 coeff[3] = { 0.f, 0.f, 0.f };
- const S32 curr_coef = side >> 1; // 0/1 = Z axis, 2/3 = Y, 4/5 = X
- const S32 side_dir = ((side & 1) << 1) - 1; // even = -1, odd = 1
- const S32 x_coef = (curr_coef + 1) % 3;
- const S32 y_coef = (x_coef + 1) % 3;
- coeff[curr_coef] = (F32)side_dir;
- F32 inv_res = 1.f / sResolution;
- for (S32 y = tile_y_pos; y < tile_y_pos + sTileResY; ++y)
- {
- for (S32 x = tile_x_pos; x < tile_x_pos + sTileResX; ++x)
- {
- coeff[x_coef] = F32((x << 1) + 1) * inv_res - 1.f;
- coeff[y_coef] = F32((y << 1) + 1) * inv_res - 1.f;
- LLVector3 dir(coeff[0], coeff[1], coeff[2]);
- dir.normalize();
- mSkyTex[side].setDir(dir, x, y);
- mShinyTex[side].setDir(dir, x, y);
- }
- }
- }
- void LLVOSky::createSkyTexture(const LLSettingsSky::ptr_t& skyp, S32 side,
- S32 tile)
- {
- S32 tile_x = tile % NUM_TILES_X;
- S32 tile_y = tile / NUM_TILES_X;
- S32 tile_x_pos = tile_x * sTileResX;
- S32 tile_y_pos = tile_y * sTileResY;
- for (S32 y = tile_y_pos; y < tile_y_pos + sTileResY; ++y)
- {
- for (S32 x = tile_x_pos; x < tile_x_pos + sTileResX; ++x)
- {
- const LLVector3& sky_dir = mSkyTex[side].getDir(x, y);
- mSkyTex[side].setPixel(calcSkyColorInDir(skyp, sky_dir), x, y);
- const LLVector3& shiny_dir = mShinyTex[side].getDir(x, y);
- mShinyTex[side].setPixel(calcSkyColorInDir(skyp, shiny_dir, true),
- x, y);
- }
- }
- }
- void LLVOSky::initAtmospherics(const LLSettingsSky::ptr_t& skyp)
- {
- mGamma = skyp->getGamma();
- mBlueDensity = skyp->getBlueDensity();
- mBlueHorizon = skyp->getBlueHorizon();
- mHazeDensity = skyp->getHazeDensity();
- mHazeHorizon = skyp->getHazeHorizon();
- mDensityMultiplier = skyp->getDensityMultiplier();
- mMaxY = skyp->getMaxY();
- mSunNorm = gEnvironment.getClampedSunNorm();
- mSunlight = skyp->getIsSunUp() ? skyp->getSunlightColor()
- : skyp->getMoonlightColor();
- mAmbient = skyp->getAmbientColor();
- mGlow = skyp->getGlow();
- mCloudShadow = skyp->getCloudShadow();
- // Note: the following components are derived from the already fetched
- // settings above; the (simple) formulae to compute them have been kept as
- // inlined static methods of LLSettingsSky, so that should they get changed
- // it will be easy to find them rather than scattering them among the rest
- // of the viewer sources). HB
- mTotalDensity = LLSettingsSky::totalDensity(mBlueDensity, mHazeDensity);
- mLightAttenuation = LLSettingsSky::lightAttenuation(mBlueDensity,
- mHazeDensity,
- mDensityMultiplier,
- mMaxY);
- mLightTransmittance = LLSettingsSky::lightTransmittance(mTotalDensity,
- mDensityMultiplier,
- mMaxY);
- LLUUID tex_id = skyp->getRainbowTextureId();
- if (mRainbowMap.isNull() || mRainbowMap->getID() != tex_id)
- {
- mRainbowMap =
- LLViewerTextureManager::getFetchedTexture(tex_id, FTT_DEFAULT,
- true,
- LLGLTexture::BOOST_UI);
- }
- tex_id = skyp->getHaloTextureId();
- if (mHaloMap.isNull() || mHaloMap->getID() != tex_id)
- {
- mHaloMap =
- LLViewerTextureManager::getFetchedTexture(tex_id, FTT_DEFAULT,
- true,
- LLGLTexture::BOOST_UI);
- }
- #if LL_VARIABLE_SKY_DOME_SIZE
- // NOTE: this is for now a constant equal to SKY_DOME_RADIUS.
- mDomeRadius = skyp->getDomeRadius();
- // NOTE: this is for now a constant equal to SKY_DOME_OFFSET.
- mDomeOffset = skyp->getDomeOffset();
- #endif
- }
- LLColor4 LLVOSky::calcSkyColorInDir(const LLSettingsSky::ptr_t& skyp,
- const LLVector3& dir, bool is_shiny)
- {
- constexpr F32 sky_saturation = 0.25f;
- constexpr F32 land_saturation = 0.1f;
- if (is_shiny && dir.mV[VZ] < -0.02f)
- {
- LLColor4 col;
- LLColor3 desat_fog(mFogColor);
- F32 brightness = desat_fog.brightness();
- // So that shiny somewhat shows up at night.
- if (brightness < 0.15f)
- {
- brightness = 0.15f;
- desat_fog = smear(0.15f);
- }
- F32 greyscale_sat = brightness * (1.f - land_saturation);
- desat_fog = desat_fog * land_saturation + smear(greyscale_sat);
- if (gPipeline.canUseWindLightShaders())
- {
- col = LLColor4(desat_fog * 0.5f, 0.f);
- }
- else
- {
- col = LLColor4(desat_fog, 0.f);
- }
- F32 x = 1.f - fabsf(-0.1f - dir.mV[VZ]);
- x *= x;
- col.mV[0] *= x * x;
- col.mV[1] *= powf(x, 2.5f);
- col.mV[2] *= x * x * x;
- return col;
- }
- // Undo OGL_TO_CFR_ROTATION and negate vertical direction.
- LLVector3 pn = LLVector3(-dir[1] , -dir[2], -dir[0]);
- // Calculate mHazeColor
- calcSkyColorVert(pn);
- LLColor3 sky_color;
- if (is_shiny)
- {
- F32 brightness = mHazeColor.brightness();
- F32 greyscale_sat = brightness * (1.f - sky_saturation);
- sky_color = mHazeColor * sky_saturation + smear(greyscale_sat);
- #if 0 // SL-12574 EEP sky is being attenuated too much
- sky_color *= 0.5f + 0.5f * brightness;
- #endif
- }
- else if (gPipeline.canUseWindLightShaders())
- {
- sky_color = LLSettingsSky::gammaCorrect(mHazeColor * 2.f, mGamma);
- }
- else
- {
- sky_color = mHazeColor * 2.f;
- }
- return LLColor4(sky_color, 0.f);
- }
- void LLVOSky::calcSkyColorVert(LLVector3& pn)
- {
- // Project the direction ray onto the sky dome.
- F32 phi = acosf(pn[1]);
- F32 sin_a = sinf(F_PI - phi);
- if (fabsf(sin_a) < 0.01f)
- {
- // Avoid division by zero
- sin_a = 0.01f;
- }
- F32 p_len = mDomeRadius *
- sinf(F_PI + phi + asinf(mDomeOffset * sin_a)) / sin_a;
- pn *= p_len;
- // Set altitude
- if (pn[1] > 0.f)
- {
- pn *= mMaxY / pn[1];
- }
- else
- {
- pn *= -32000.f / pn[1];
- }
- p_len = pn.length();
- pn /= p_len;
- // Initialize temp variables
- LLColor3 sunlight = mSunlight;
- // Calculate relative weights
- LLColor3 temp1 = mTotalDensity;
- LLColor3 blue_factor = mBlueHorizon *
- componentDiv(mBlueDensity, temp1);
- LLColor3 haze_factor = mHazeHorizon *
- componentDiv(smear(mHazeDensity), temp1);
- // Compute sunlight from P & lightnorm (for long rays like sky)
- LLColor3 temp2;
- temp2.mV[1] = llmax(F_APPROXIMATELY_ZERO,
- llmax(0.f, pn[1]) + mSunNorm.mV[1]);
- temp2.mV[1] = 1.f / temp2.mV[1];
- componentMultBy(sunlight, componentExp(mLightAttenuation * -temp2.mV[1]));
- componentMultBy(sunlight, mLightTransmittance);
- // Distance
- temp2.mV[2] = p_len * mDensityMultiplier;
- // Transparency (-> temp1)
- temp1 = componentExp(temp1 * -temp2.mV[2]);
- // Compute haze glow
- temp2.mV[0] = pn * LLVector3(mSunNorm);
- // temp2.x is 0 at the sun and increases away from sun
- temp2.mV[0] = 1.f - temp2.mV[0];
- // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- temp2.mV[0] = llmax(temp2.mV[0], 0.001f);
- // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
- temp2.mV[0] *= mGlow.mV[0];
- // glow.z should be negative, so we are doing a sort of (1 / "angle")
- // function
- temp2.mV[0] = powf(temp2.mV[0], mGlow.mV[2]);
- // Add "minimum anti-solar illumination"
- temp2.mV[0] += 0.25f;
- // Haze color above cloud
- mHazeColor = blue_factor * (sunlight + mAmbient) +
- componentMult(haze_factor, sunlight * temp2.mV[0] + mAmbient);
- #if 0 // 'hazeColorBelowCloud' in LL's EEP viewer (which would be
- // mHazeColorBelowCloud for the Cool VL Viewer) is never used...
- // Increase ambient when there are more clouds
- LLColor3 ambient = mAmbient + (LLColor3::white - mAmbient) *
- mCloudShadow * 0.5f;
- // Dim sunlight by cloud shadow percentage
- sunlight *= 1.f - mCloudShadow;
- // Haze color below cloud
- mHazeColorBelowCloud = blue_factor * (sunlight + ambient) +
- componentMult(mHazeColor,
- sunlight * temp2.mV[0] + ambient);
- // Final atmosphere additive
- componentMultBy(mHazeColor, LLColor3::white - temp1);
- // Attenuate cloud color by atmosphere (less atmos opacity/more
- // transparency below clouds)
- temp1 = componentSqrt(temp1);
- // At horizon, blend high altitude sky color towards the darker color below
- // the clouds
- mHazeColor += componentMult(mHazeColorBelowCloud - mHazeColor,
- LLColor3::white - componentSqrt(temp1));
- #else
- // Final atmosphere additive
- componentMultBy(mHazeColor, LLColor3::white - temp1);
- #endif
- }
- void LLVOSky::calcAtmospherics()
- {
- const LLSettingsSky::ptr_t& skyp = gEnvironment.getCurrentSky();
- if (skyp) // Paranoia
- {
- initAtmospherics(skyp);
- mSun.setColor(skyp->getSunDiffuse());
- }
- mMoon.setColor(LLColor3::white);
- mSun.renewDirection();
- mSun.renewColor();
- mMoon.renewDirection();
- mMoon.renewColor();
- }
- bool LLVOSky::updateSky()
- {
- if (mDead || gGLManager.mIsDisabled ||
- !gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
- {
- return true;
- }
- const LLSettingsSky::ptr_t& skyp = gEnvironment.getCurrentSky();
- if (!skyp) // Paranoia
- {
- return true;
- }
- static S32 next_frame = 0;
- mNeedUpdate = mForceUpdate;
- ++next_frame;
- next_frame = next_frame % MAX_TILES;
- mInterpVal = mInitialized ? (F32)next_frame / (F32)MAX_TILES : 1.f;
- LLSkyTex::setInterpVal(mInterpVal);
- LLHeavenBody::setInterpVal(mInterpVal);
- updateDirections(skyp);
- if (!mCubeMap || LLPipeline::sReflectionProbesEnabled)
- {
- mCubeMapUpdateStage = NUM_CUBEMAP_FACES;
- mForceUpdate = false;
- return true;
- }
- if (mCubeMapUpdateStage < 0)
- {
- LL_TRACY_TIMER(TRC_VOSKY_CALC);
- calcAtmospherics();
- if (!mNeedUpdate)
- {
- mNeedUpdate = haveValuesChanged();
- }
- if (mNeedUpdate && (mForceUpdate || mForceUpdateThrottle.hasExpired()))
- {
- // Start updating cube map sides
- updateFog(gViewerCamera.getFar());
- mCubeMapUpdateStage = 0;
- mCubeMapUpdateTile = 0;
- mForceUpdate = false;
- }
- }
- else if (mCubeMapUpdateStage >= NUM_CUBEMAP_FACES &&
- !LLPipeline::sReflectionProbesEnabled)
- {
- LL_TRACY_TIMER(TRC_VOSKY_UPDATEFORCED);
- LLSkyTex::stepCurrent();
- bool cannot_use_wl = !gPipeline.canUseWindLightShaders();
- S32 tex = mSkyTex[0].getWhich(true);
- LLImageRaw* raw1;
- LLImageRaw* raw2;
- for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
- {
- if (cannot_use_wl)
- {
- raw1 = mSkyTex[side].getImageRaw(true);
- raw2 = mSkyTex[side].getImageRaw(false);
- raw2->copy(raw1);
- mSkyTex[side].createGLImage(tex);
- }
- raw1 = mShinyTex[side].getImageRaw(true);
- raw2 = mShinyTex[side].getImageRaw(false);
- raw2->copy(raw1);
- mShinyTex[side].createGLImage(tex);
- }
- next_frame = 0;
- // Update the sky texture
- if (cannot_use_wl)
- {
- for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
- {
- mSkyTex[side].create();
- }
- }
- for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
- {
- mShinyTex[side].create();
- }
- // Update the environment map
- initCubeMap();
- saveCurrentValues();
- mNeedUpdate = mForceUpdate = false;
- mForceUpdateThrottle.setTimerExpirySec(UPDATE_EXPIRY);
- if (mDrawable.notNull() && mDrawable->getFace(0) &&
- !mDrawable->getFace(0)->getVertexBuffer())
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
- }
- mCubeMapUpdateStage = -1;
- mCubeMapUpdateTile = 0;
- }
- // mCubeMapUpdateStage >= 0 && mCubeMapUpdateStage < NUM_CUBEMAP_FACES
- else if (!LLPipeline::sReflectionProbesEnabled)
- {
- LL_TRACY_TIMER(TRC_VOSKY_CREATETEXTURES);
- S32 side = mCubeMapUpdateStage;
- S32 start_tile = mCubeMapUpdateTile;
- for (S32 tile = 0; tile < UPDATE_TILES; ++tile)
- {
- createSkyTexture(skyp, side, start_tile + tile);
- }
- mCubeMapUpdateTile += UPDATE_TILES;
- if (mCubeMapUpdateTile >= NUM_TILES)
- {
- ++mCubeMapUpdateStage;
- mCubeMapUpdateTile = 0;
- }
- }
- return true;
- }
- bool LLVOSky::haveValuesChanged()
- {
- if (!almost_equal(mOldCloudShadow, mCloudShadow))
- {
- return true;
- }
- if (!almost_equal(mOldHazeDensity, mHazeDensity))
- {
- return true;
- }
- if (!almost_equal(mOldHazeHorizon, mHazeHorizon))
- {
- return true;
- }
- if (!almost_equal(mOldSunNorm, mSunNorm))
- {
- return true;
- }
- if (!almost_equal(mOldSunlight, mSunlight))
- {
- return true;
- }
- if (!almost_equal(mOldAmbient, mAmbient))
- {
- return true;
- }
- if (!almost_equal(mOldBlueDensity, mBlueDensity))
- {
- return true;
- }
- if (!almost_equal(mOldBlueHorizon, mBlueHorizon))
- {
- return true;
- }
- if (!almost_equal(mOldDensityMultiplier, mDensityMultiplier))
- {
- return true;
- }
- if (!almost_equal(mOldGlow, mGlow))
- {
- return true;
- }
- if (!almost_equal(mOldMaxY, mMaxY))
- {
- return true;
- }
- if (!almost_equal(mOldGamma, mGamma))
- {
- return true;
- }
- #if 0 // These components are derived from the above ones, so need to save
- // and test them... HB
- if (!almost_equal(mOldLightAttenuation, mLightAttenuation))
- {
- return true;
- }
- if (!almost_equal(mOldLightTransmittance, mLightTransmittance))
- {
- return true;
- }
- if (!almost_equal(mOldTotalDensity, mTotalDensity))
- {
- return true;
- }
- #endif
- return false;
- }
- void LLVOSky::saveCurrentValues()
- {
- mOldGamma = mGamma;
- mOldHazeDensity = mHazeDensity;
- mOldHazeHorizon = mHazeHorizon;
- mOldDensityMultiplier = mDensityMultiplier;
- mOldMaxY = mMaxY;
- mOldCloudShadow = mCloudShadow;
- mOldSunNorm = mSunNorm;
- mOldGlow = mGlow;
- mOldSunlight = mSunlight;
- mOldAmbient = mAmbient;
- mOldBlueDensity = mBlueDensity;
- mOldBlueHorizon = mBlueHorizon;
- #if 0 // These components are derived from the above ones, so need to save
- // and test them... HB
- mOldLightAttenuation = mLightAttenuation;
- mOldLightTransmittance = mLightTransmittance;
- mOldTotalDensity = mTotalDensity;
- #endif
- }
- void LLVOSky::updateTextures()
- {
- F32 max_area = gMaxImageSizeDefault * gMaxImageSizeDefault;
- if (mSunTexturep[0])
- {
- mSunTexturep[0]->addTextureStats(max_area);
- }
- if (mMoonTexturep[0])
- {
- mMoonTexturep[0]->addTextureStats(max_area);
- }
- if (mBloomTexturep[0])
- {
- mBloomTexturep[0]->addTextureStats(max_area);
- }
- if (mCloudNoiseTexturep[0])
- {
- mCloudNoiseTexturep[0]->addTextureStats(max_area);
- }
- if (mSunTexturep[1])
- {
- mSunTexturep[1]->addTextureStats(max_area);
- }
- if (mMoonTexturep[1])
- {
- mMoonTexturep[1]->addTextureStats(max_area);
- }
- if (mBloomTexturep[1])
- {
- mBloomTexturep[1]->addTextureStats(max_area);
- }
- if (mCloudNoiseTexturep[1])
- {
- mCloudNoiseTexturep[1]->addTextureStats(max_area);
- }
- }
- LLDrawable* LLVOSky::createDrawable()
- {
- gPipeline.allocDrawable(this);
- mDrawable->setLit(false);
- LLDrawPoolSky* poolp =
- (LLDrawPoolSky*)gPipeline.getPool(LLDrawPool::POOL_SKY);
- poolp->setSkyTex(mSkyTex);
- mDrawable->setRenderType(LLPipeline::RENDER_TYPE_SKY);
- for (S32 i = 0; i < NUM_CUBEMAP_FACES; ++i)
- {
- mFace[FACE_SIDE0 + i] = mDrawable->addFace(poolp, NULL);
- }
- mFace[FACE_SUN] = mDrawable->addFace(poolp, NULL);
- mFace[FACE_MOON] = mDrawable->addFace(poolp, NULL);
- mFace[FACE_BLOOM] = mDrawable->addFace(poolp, NULL);
- mFace[FACE_SUN]->setMediaAllowed(false);
- mFace[FACE_MOON]->setMediaAllowed(false);
- mFace[FACE_BLOOM]->setMediaAllowed(false);
- return mDrawable;
- }
- bool LLVOSky::updateGeometry(LLDrawable* drawable)
- {
- LL_FAST_TIMER(FTM_GEO_SKY);
- if (mFace[FACE_REFLECTION] == NULL)
- {
- LLDrawPoolWater* poolp =
- (LLDrawPoolWater*)gPipeline.getPool(LLDrawPool::POOL_WATER);
- if (gPipeline.getPool(LLDrawPool::POOL_WATER)->getShaderLevel())
- {
- mFace[FACE_REFLECTION] = drawable->addFace(poolp, NULL);
- }
- }
- mCameraPosAgent = drawable->getPositionAgent();
- mEarthCenter.mV[0] = mCameraPosAgent.mV[0];
- mEarthCenter.mV[1] = mCameraPosAgent.mV[1];
- LLVector3 v_agent[8];
- for (S32 i = 0; i < 8; ++i)
- {
- F32 x_sgn = (i & 1) ? 1.f : -1.f;
- F32 y_sgn = (i & 2) ? 1.f : -1.f;
- F32 z_sgn = (i & 4) ? 1.f : -1.f;
- v_agent[i] = HORIZON_DIST * SKY_BOX_MULT *
- LLVector3(x_sgn, y_sgn, z_sgn);
- }
- LLStrider<LLVector3> verticesp;
- LLStrider<LLVector3> normalsp;
- LLStrider<LLVector2> texcoordsp;
- LLStrider<U16> indicesp;
- for (S32 side = 0; side < NUM_CUBEMAP_FACES; ++side)
- {
- LLFace* face = mFace[FACE_SIDE0 + side];
- if (!face || face->getVertexBuffer())
- {
- continue;
- }
- face->setSize(4, 6);
- face->setGeomIndex(0);
- face->setIndicesIndex(0);
- LLVertexBuffer* buff =
- new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK);
- buff->allocateBuffer(4, 6);
- face->setVertexBuffer(buff);
- U16 index_offset = face->getGeometry(verticesp, normalsp, texcoordsp,
- indicesp);
- S32 vtx = 0;
- S32 curr_bit = side >> 1; // 0/1 = Z axis, 2/3 = Y, 4/5 = X
- S32 side_dir = side & 1; // even - 0, odd - 1
- S32 i_bit = (curr_bit + 2) % 3;
- S32 j_bit = (i_bit + 2) % 3;
- LLVector3 axis;
- axis.mV[curr_bit] = 1.f;
- face->mCenterAgent = (F32)((side_dir << 1) - 1) * axis * HORIZON_DIST;
- vtx = side_dir << curr_bit;
- *verticesp++ = v_agent[vtx];
- *verticesp++ = v_agent[vtx | 1 << j_bit];
- *verticesp++ = v_agent[vtx | 1 << i_bit];
- *verticesp++ = v_agent[vtx | 1 << i_bit | 1 << j_bit];
- *texcoordsp++ = TEX00;
- *texcoordsp++ = TEX01;
- *texcoordsp++ = TEX10;
- *texcoordsp++ = TEX11;
- // Triangles for each side
- *indicesp++ = index_offset;
- *indicesp++ = index_offset + 1;
- *indicesp++ = index_offset + 3;
- *indicesp++ = index_offset;
- *indicesp++ = index_offset + 3;
- *indicesp++ = index_offset + 2;
- buff->unmapBuffer();
- }
- const LLVector3& look_at = gViewerCamera.getAtAxis();
- LLVector3 right = look_at % LLVector3::z_axis;
- LLVector3 up = right % look_at;
- right.normalize();
- up.normalize();
- constexpr F32 cos_max_angle = 1.f;
- bool draw_sun = updateHeavenlyBodyGeometry(drawable, true, mSun,
- cos_max_angle, up, right);
- bool draw_moon = updateHeavenlyBodyGeometry(drawable, false, mMoon,
- cos_max_angle, up, right);
- draw_sun &= gEnvironment.getIsSunUp();
- draw_moon &= gEnvironment.getIsMoonUp();
- mSun.setDraw(draw_sun);
- mMoon.setDraw(draw_moon);
- F32 water_height = 0.01f;
- LLViewerRegion* regionp = gAgent.getRegion();
- if (regionp)
- {
- water_height += regionp->getWaterHeight();
- }
- F32 camera_height = mCameraPosAgent.mV[2];
- F32 height_above_water = camera_height - water_height;
- bool sun_flag = !mMoon.isVisible() || look_at * mSun.getDirection() > 0.f;
- if (height_above_water > 0)
- {
- bool render_ref =
- gPipeline.getPool(LLDrawPool::POOL_WATER)->getShaderLevel() == 0;
- if (sun_flag)
- {
- setDrawRefl(0);
- if (render_ref)
- {
- updateReflectionGeometry(drawable, height_above_water, mSun);
- }
- }
- else
- {
- setDrawRefl(1);
- if (render_ref)
- {
- updateReflectionGeometry(drawable, height_above_water, mMoon);
- }
- }
- }
- else
- {
- setDrawRefl(-1);
- }
- return true;
- }
- bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable* drawable, bool is_sun,
- LLHeavenBody& hb, F32 cos_max_angle,
- const LLVector3& up,
- const LLVector3& right)
- {
- mHeavenlyBodyUpdated = true;
- LLVector3 to_dir, hb_right, hb_up;
- LLQuaternion rot = hb.getRotation();
- to_dir = LLVector3::x_axis * rot;
- hb_right = to_dir % LLVector3::z_axis;
- hb_up = hb_right % to_dir;
- // At zenith so math below fails spectacularly
- if (to_dir * LLVector3::z_axis > 0.99f)
- {
- hb_right = LLVector3::y_axis_neg * rot;
- hb_up = LLVector3::z_axis * rot;
- }
- hb_right.normalize();
- hb_up.normalize();
- LLVector3 draw_pos = to_dir * HEAVENLY_BODY_DIST;
- const F32 enlargm_factor = 1.f - to_dir.mV[2];
- F32 horiz_enlargement = 1.f + enlargm_factor * 0.3f;
- F32 vert_enlargement = 1.f + enlargm_factor * 0.2f;
- LLVector3 v_clipped[4];
- F32 scale = is_sun ? mSunScale : mMoonScale;
- scale *= HEAVENLY_BODY_DIST * HEAVENLY_BODY_FACTOR;
- const LLVector3 scaled_right = horiz_enlargement * scale *
- hb.getDiskRadius() * hb_right;
- const LLVector3 scaled_up = vert_enlargement * scale *
- hb.getDiskRadius() * hb_up;
- v_clipped[0] = draw_pos - scaled_right + scaled_up;
- v_clipped[1] = draw_pos - scaled_right - scaled_up;
- v_clipped[2] = draw_pos + scaled_right + scaled_up;
- v_clipped[3] = draw_pos + scaled_right - scaled_up;
- hb.setVisible(true);
- const S32 f = is_sun ? FACE_SUN : FACE_MOON;
- LLFace* facep = mFace[f];
- if (!facep) return false;
- if (!facep->getVertexBuffer())
- {
- facep->setSize(4, 6);
- LLVertexBuffer* buff =
- new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK);
- if (!buff->allocateBuffer(facep->getGeomCount(),
- facep->getIndicesCount()))
- {
- llwarns << "Failure to allocate a vertex buffer with "
- << facep->getGeomCount() << " vertices and "
- << facep->getIndicesCount() << " indices" << llendl;
- return true;
- }
- facep->setGeomIndex(0);
- facep->setIndicesIndex(0);
- facep->setVertexBuffer(buff);
- }
- LLStrider<LLVector3> verticesp;
- LLStrider<LLVector3> normalsp;
- LLStrider<LLVector2> texcoordsp;
- LLStrider<U16> indicesp;
- S32 index_offset = facep->getGeometry(verticesp, normalsp, texcoordsp,
- indicesp);
- if (index_offset == -1)
- {
- return true;
- }
- for (S32 vtx = 0; vtx < 4; ++vtx)
- {
- hb.corner(vtx) = v_clipped[vtx];
- *(verticesp++) = hb.corner(vtx) + mCameraPosAgent;
- }
- *texcoordsp++ = TEX01;
- *texcoordsp++ = TEX00;
- *texcoordsp++ = TEX11;
- *texcoordsp++ = TEX10;
- *indicesp++ = index_offset;
- *indicesp++ = index_offset + 2;
- *indicesp++ = index_offset + 1;
- *indicesp++ = index_offset + 1;
- *indicesp++ = index_offset + 2;
- *indicesp++ = index_offset + 3;
- facep->getVertexBuffer()->unmapBuffer();
- return true;
- }
- F32 dtReflection(const LLVector3& p, F32 cos_dir_from_top,
- F32 sin_dir_from_top, F32 diff_angl_dir)
- {
- LLVector3 P = p;
- P.normalize();
- const F32 cos_dir_angle = -P.mV[VZ];
- const F32 sin_dir_angle = sqrtf(1.f - cos_dir_angle * cos_dir_angle);
- F32 cos_diff_angles = cos_dir_angle * cos_dir_from_top +
- sin_dir_angle * sin_dir_from_top;
- F32 diff_angles;
- if (cos_diff_angles > 1.f - 1e-7f)
- {
- diff_angles = 0.f;
- }
- else
- {
- diff_angles = acosf(cos_diff_angles);
- }
- const F32 rel_diff_angles = diff_angles / diff_angl_dir;
- const F32 dt = 1.f - rel_diff_angles;
- return dt >= 0.f ? dt : 0.f;
- }
- F32 dtClip(const LLVector3& v0, const LLVector3& v1, F32 far_clip2)
- {
- const LLVector3 otrezok = v1 - v0;
- const F32 A = otrezok.lengthSquared();
- const F32 B = v0 * otrezok;
- const F32 C = v0.lengthSquared() - far_clip2;
- const F32 det = sqrtf(B * B - A * C);
- F32 dt_clip = (-B - det) / A;
- if (dt_clip < 0.f || dt_clip > 1.f)
- {
- dt_clip = (-B + det) / A;
- }
- return dt_clip;
- }
- void LLVOSky::updateReflectionGeometry(LLDrawable* drawable, F32 h,
- const LLHeavenBody& hb)
- {
- const LLVector3& look_at = gViewerCamera.getAtAxis();
- LLVector3 to_dir = hb.getDirection();
- LLVector3 hb_pos = to_dir * (HORIZON_DIST - 10.f);
- LLVector3 to_dir_proj = to_dir;
- to_dir_proj.mV[VZ] = 0.f;
- to_dir_proj.normalize();
- LLVector3 right = to_dir % LLVector3::z_axis;
- LLVector3 up = right % to_dir;
- right.normalize();
- up.normalize();
- // Finding angle between look direction and sprite.
- LLVector3 look_at_right = look_at % LLVector3::z_axis;
- look_at_right.normalize();
- const F32 enlargm_factor = 1.f - to_dir.mV[2];
- F32 horiz_enlargement = 1.f + enlargm_factor * 0.3f;
- F32 vert_enlargement = 1.f + enlargm_factor * 0.2f;
- F32 vert_size =
- vert_enlargement * HEAVENLY_BODY_SCALE * hb.getDiskRadius();
- right *= horiz_enlargement * HEAVENLY_BODY_SCALE * hb.getDiskRadius();
- up *= vert_size;
- LLVector3 v_corner[2];
- LLVector3 stretch_corner[2];
- LLVector3 top_hb = v_corner[0] = stretch_corner[0] = hb_pos - right + up;
- v_corner[1] = stretch_corner[1] = hb_pos - right - up;
- LLVector2 TEX0t = TEX00;
- LLVector2 TEX1t = TEX10;
- LLVector3 lower_corner = v_corner[1];
- top_hb.normalize();
- const F32 cos_angle_of_view = fabsf(top_hb.mV[VZ]);
- const F32 extension = llmin(5.f, 1.f / cos_angle_of_view);
- constexpr S32 cols = 1;
- const S32 raws = lltrunc(16 * extension);
- S32 quads = cols * raws;
- stretch_corner[0] = lower_corner + extension *
- (stretch_corner[0] - lower_corner);
- stretch_corner[1] = lower_corner + extension *
- (stretch_corner[1] - lower_corner);
- F32 cos_dir_from_top[2];
- LLVector3 dir = stretch_corner[0];
- dir.normalize();
- cos_dir_from_top[0] = dir.mV[VZ];
- dir = stretch_corner[1];
- dir.normalize();
- cos_dir_from_top[1] = dir.mV[VZ];
- const F32 sin_dir_from_top = sqrtf(1.f - cos_dir_from_top[0] *
- cos_dir_from_top[0]);
- const F32 sin_dir_from_top2 = sqrtf(1.f - cos_dir_from_top[1] *
- cos_dir_from_top[1]);
- const F32 cos_diff_dir = cos_dir_from_top[0] * cos_dir_from_top[1] +
- sin_dir_from_top * sin_dir_from_top2;
- const F32 diff_angl_dir = acosf(cos_diff_dir);
- v_corner[0] = stretch_corner[0];
- v_corner[1] = lower_corner;
- LLVector2 TEX0tt = TEX01;
- LLVector2 TEX1tt = TEX11;
- LLVector3 v_refl_corner[4];
- LLVector3 v_sprite_corner[4];
- for (S32 vtx = 0; vtx < 2; ++vtx)
- {
- LLVector3 light_proj = v_corner[vtx];
- light_proj.normalize();
- const F32 z = light_proj.mV[VZ];
- const F32 sin_angle = sqrtf(1.f - z * z);
- light_proj *= 1.f / sin_angle;
- light_proj.mV[VZ] = 0.f;
- const F32 to_refl_point = h * sin_angle / fabsf(z);
- v_refl_corner[vtx] = to_refl_point * light_proj;
- }
- for (S32 vtx = 2; vtx < 4; ++vtx)
- {
- const LLVector3 to_dir_vec = (to_dir_proj * v_refl_corner[vtx - 2]) *
- to_dir_proj;
- v_refl_corner[vtx] = v_refl_corner[vtx - 2] +
- 2.f * (to_dir_vec - v_refl_corner[vtx - 2]);
- }
- for (S32 vtx = 0; vtx < 4; ++vtx)
- {
- v_refl_corner[vtx].mV[VZ] -= h;
- }
- LLVector3 refl_corn_norm[2];
- refl_corn_norm[0] = v_refl_corner[1];
- refl_corn_norm[0].normalize();
- refl_corn_norm[1] = v_refl_corner[3];
- refl_corn_norm[1].normalize();
- F32 cos_refl_look_at[2];
- cos_refl_look_at[0] = refl_corn_norm[0] * look_at;
- cos_refl_look_at[1] = refl_corn_norm[1] * look_at;
- S32 side = 0;
- if (cos_refl_look_at[1] > cos_refl_look_at[0])
- {
- side = 2;
- }
- #if 0
- const F32 far_clip = (gViewerCamera.getFar() - 0.01f) / far_clip_factor;
- const F32 far_clip2 = far_clip * far_clip;
- #else
- constexpr F32 far_clip = 512;
- constexpr F32 far_clip2 = far_clip * far_clip;
- #endif
- F32 dt_clip;
- if (v_refl_corner[side].lengthSquared() > far_clip2)
- {
- // Whole thing is sprite: reflection is beyond far clip plane.
- dt_clip = 1.1f;
- quads = 1;
- }
- else if (v_refl_corner[side + 1].lengthSquared() > far_clip2)
- {
- // Part is reflection, the rest is sprite.
- dt_clip = dtClip(v_refl_corner[side + 1], v_refl_corner[side],
- far_clip2);
- const LLVector3 p = (1.f - dt_clip) * v_refl_corner[side + 1] +
- dt_clip * v_refl_corner[side];
- F32 dt_tex = dtReflection(p, cos_dir_from_top[0], sin_dir_from_top,
- diff_angl_dir);
- TEX0tt = LLVector2(0.f, dt_tex);
- TEX1tt = LLVector2(1.f, dt_tex);
- ++quads;
- }
- else
- {
- // Whole thing is correct reflection.
- dt_clip = -0.1f;
- }
- LLFace* face = mFace[FACE_REFLECTION];
- if (!face) return;
- if (!face->getVertexBuffer() || face->getGeomCount() != quads * 4)
- {
- face->setSize(quads * 4, quads * 6);
- LLVertexBuffer* buff =
- new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK);
- if (!buff->allocateBuffer(face->getGeomCount(),
- face->getIndicesCount()))
- {
- llwarns << "Failure to allocate a vertex buffer with "
- << face->getGeomCount() << " vertices and "
- << face->getIndicesCount() << " indices" << llendl;
- return;
- }
- face->setIndicesIndex(0);
- face->setGeomIndex(0);
- face->setVertexBuffer(buff);
- }
- LLStrider<LLVector3> verticesp;
- LLStrider<LLVector3> normalsp;
- LLStrider<LLVector2> texcoordsp;
- LLStrider<U16> indicesp;
- S32 index_offset = face->getGeometry(verticesp, normalsp, texcoordsp,
- indicesp);
- if (index_offset == -1)
- {
- return;
- }
- LLColor3 hb_col3 = hb.getInterpColor();
- hb_col3.clamp();
- const LLColor4 hb_col = LLColor4(hb_col3);
- constexpr F32 min_attenuation = 0.4f;
- constexpr F32 max_attenuation = 0.7f;
- const F32 attenuation = min_attenuation +
- cos_angle_of_view *
- (max_attenuation - min_attenuation);
- LLColor4 hb_refl_col = (1.f - attenuation) * hb_col + attenuation *
- mFogColor;
- face->setFaceColor(hb_refl_col);
- LLVector3 v_far[2];
- v_far[0] = v_refl_corner[1];
- v_far[1] = v_refl_corner[3];
- if (dt_clip > 0.f)
- {
- if (dt_clip >= 1.f)
- {
- for (S32 vtx = 0; vtx < 4; ++vtx)
- {
- F32 ratio = far_clip / v_refl_corner[vtx].length();
- *verticesp++ = v_refl_corner[vtx] = ratio *
- v_refl_corner[vtx] +
- mCameraPosAgent;
- }
- const LLVector3 draw_pos = 0.25 * (v_refl_corner[0] +
- v_refl_corner[1] +
- v_refl_corner[2] +
- v_refl_corner[3]);
- face->mCenterAgent = draw_pos;
- }
- else
- {
- F32 ratio = far_clip / v_refl_corner[1].length();
- v_sprite_corner[1] = v_refl_corner[1] * ratio;
- ratio = far_clip / v_refl_corner[3].length();
- v_sprite_corner[3] = v_refl_corner[3] * ratio;
- v_refl_corner[1] = (1.f - dt_clip) * v_refl_corner[1] +
- dt_clip * v_refl_corner[0];
- v_refl_corner[3] = (1.f - dt_clip) * v_refl_corner[3] +
- dt_clip * v_refl_corner[2];
- v_sprite_corner[0] = v_refl_corner[1];
- v_sprite_corner[2] = v_refl_corner[3];
- for (S32 vtx = 0; vtx < 4; ++vtx)
- {
- *verticesp++ = v_sprite_corner[vtx] + mCameraPosAgent;
- }
- const LLVector3 draw_pos = 0.25 * (v_refl_corner[0] +
- v_sprite_corner[1] +
- v_refl_corner[2] +
- v_sprite_corner[3]);
- face->mCenterAgent = draw_pos;
- }
- *texcoordsp++ = TEX0tt;
- *texcoordsp++ = TEX0t;
- *texcoordsp++ = TEX1tt;
- *texcoordsp++ = TEX1t;
- *indicesp++ = index_offset;
- *indicesp++ = index_offset + 2;
- *indicesp++ = index_offset + 1;
- *indicesp++ = index_offset + 1;
- *indicesp++ = index_offset + 2;
- *indicesp++ = index_offset + 3;
- index_offset += 4;
- }
- if (dt_clip < 1.f)
- {
- if (dt_clip <= 0.f)
- {
- const LLVector3 draw_pos = 0.25 * (v_refl_corner[0] +
- v_refl_corner[1] +
- v_refl_corner[2] +
- v_refl_corner[3]);
- face->mCenterAgent = draw_pos;
- }
- const F32 raws_inv = 1.f / raws;
- const F32 cols_inv = 1.f / cols;
- LLVector3 left = v_refl_corner[0] - v_refl_corner[1];
- LLVector3 right = v_refl_corner[2] - v_refl_corner[3];
- left *= raws_inv;
- right *= raws_inv;
- F32 dt_v0, dt_v1;
- for (S32 raw = 0; raw < raws; ++raw)
- {
- const LLVector3 bl = v_refl_corner[1] + (F32)raw * left;
- const LLVector3 br = v_refl_corner[3] + (F32)raw * right;
- const LLVector3 el = bl + left;
- const LLVector3 er = br + right;
- dt_v1 = dtReflection(el, cos_dir_from_top[0], sin_dir_from_top,
- diff_angl_dir);
- dt_v0 = dt_v1;
- for (S32 col = 0; col < cols; ++col)
- {
- F32 dt_h0 = col * cols_inv;
- *verticesp++ = (1.f - dt_h0) * el + dt_h0 * er +
- mCameraPosAgent;
- *verticesp++ = (1.f - dt_h0) * bl + dt_h0 * br +
- mCameraPosAgent;
- F32 dt_h1 = (col + 1) * cols_inv;
- *verticesp++ = (1.f - dt_h1) * el + dt_h1 * er +
- mCameraPosAgent;
- *verticesp++ = (1.f - dt_h1) * bl + dt_h1 * br +
- mCameraPosAgent;
- *texcoordsp++ = LLVector2(dt_h0, dt_v1);
- *texcoordsp++ = LLVector2(dt_h0, dt_v0);
- *texcoordsp++ = LLVector2(dt_h1, dt_v1);
- *texcoordsp++ = LLVector2(dt_h1, dt_v0);
- *indicesp++ = index_offset;
- *indicesp++ = index_offset + 2;
- *indicesp++ = index_offset + 1;
- *indicesp++ = index_offset + 1;
- *indicesp++ = index_offset + 2;
- *indicesp++ = index_offset + 3;
- index_offset += 4;
- }
- }
- }
- face->getVertexBuffer()->unmapBuffer();
- }
- void LLVOSky::updateFog(F32 distance)
- {
- if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG))
- {
- return;
- }
- F32 water_height = 0.01f;
- LLViewerRegion* regionp = gAgent.getRegion();
- if (regionp)
- {
- water_height += regionp->getWaterHeight();
- }
- F32 camera_height = gAgent.getCameraPositionAgent().mV[2];
- F32 near_clip_height = gViewerCamera.getAtAxis().mV[VZ] *
- gViewerCamera.getNear();
- camera_height += near_clip_height;
- LLColor3 res_color[3];
- LLColor3 sky_fog_color = LLColor3::white;
- LLColor3 render_fog_color = LLColor3::white;
- LLVector3 tosun;
- tosun.set(gEnvironment.getClampedLightNorm());
- const F32 tosun_z = tosun.mV[VZ];
- tosun.mV[VZ] = 0.f;
- tosun.normalize();
- LLVector3 perp_tosun;
- perp_tosun.mV[VX] = -tosun.mV[VY];
- perp_tosun.mV[VY] = tosun.mV[VX];
- LLVector3 tosun_45 = tosun + perp_tosun;
- tosun_45.normalize();
- constexpr F32 delta = 0.06f;
- tosun.mV[VZ] = perp_tosun.mV[VZ] = tosun_45.mV[VZ] = delta;
- tosun.normalize();
- perp_tosun.normalize();
- tosun_45.normalize();
- // Sky colors, just slightly above the horizon in the direction of the sun,
- // perpendicular to the sun, and at a 45 degree angle to the sun.
- const LLSettingsSky::ptr_t& skyp = gEnvironment.getCurrentSky();
- initAtmospherics(skyp);
- res_color[0] = calcSkyColorInDir(skyp, tosun);
- res_color[1] = calcSkyColorInDir(skyp, perp_tosun);
- res_color[2] = calcSkyColorInDir(skyp, tosun_45);
- sky_fog_color = color_norm(res_color[0] + res_color[1] + res_color[2]);
- constexpr F32 full_off = -0.25f;
- constexpr F32 full_on = 0.f;
- F32 on = llclamp((tosun_z - full_off) / (full_on - full_off), 0.01f, 1.f);
- sky_fog_color *= 0.5f * on;
- // We need to clamp these to non-zero, in order for the gamma correction to
- // work. 0^y = ???
- for (S32 i = 0; i < 3; ++i)
- {
- sky_fog_color.mV[i] = llmax(0.0001f, sky_fog_color.mV[i]);
- }
- color_gamma_correct(sky_fog_color);
- render_fog_color = sky_fog_color;
- if (camera_height > water_height)
- {
- LLColor4 fog(render_fog_color);
- mGLFogCol = fog;
- }
- else
- {
- F32 depth = water_height - camera_height;
- // Adjust the color based on depth. We are doing linear approximations.
- static LLCachedControl<F32> gldepthscale(gSavedSettings,
- "WaterGLFogDepthScale");
- F32 depth_scale = gldepthscale > 0.f ? gldepthscale : 1.f;
- static LLCachedControl<F32> gldepthfloor(gSavedSettings,
- "WaterGLFogDepthFloor");
- F32 depth_floor = gldepthfloor > 0.f ? gldepthfloor : 0.f;
- F32 depth_modifier = 1.f - llmin(llmax(depth / depth_scale, 0.01f),
- depth_floor);
- LLColor4 fog_col = LLDrawPoolWater::sWaterFogColor * depth_modifier;
- fog_col.setAlpha(1.f);
- // Set the gl fog color
- mGLFogCol = fog_col;
- }
- mFogColor = sky_fog_color;
- mFogColor.setAlpha(1.f);
- stop_glerror();
- }
- void LLVOSky::initSunDirection(const LLVector3& sun_dir)
- {
- LLVector3 sun_direction = sun_dir.length() != 0.f ? sun_dir
- : LLVector3::x_axis;
- sun_direction.normalize();
- mSun.setDirection(sun_direction);
- mSun.renewDirection();
- mSun.setAngularVelocity(LLVector3::zero);
- mMoon.setDirection(-mSun.getDirection());
- mMoon.renewDirection();
- mLastLightingDirection = mSun.getDirection();
- if (!mInitialized)
- {
- init();
- LLSkyTex::stepCurrent();
- }
- }
- void LLVOSky::setSunDirection(const LLVector3& sun_dir,
- const LLVector3& sun_ang_velocity)
- {
- LLVector3 sun_direction = sun_dir.length() != 0.f ? sun_dir
- : LLVector3::x_axis;
- sun_direction.normalize();
- // Push the sun "South" as it approaches directly overhead so that we can
- // always see bump mapping on the upward facing faces of cubes.
- LLVector3 new_dir = sun_direction;
- // Same as dot product with the up direction + clamp.
- F32 sun_dot = llmax(0.f, new_dir.mV[2]);
- sun_dot *= sun_dot;
- // Create normalized vector that has the sun_dir pushed south about an hour
- // and change.
- LLVector3 adjusted_dir = (new_dir + LLVector3(0.f, -0.70711f, 0.70711f)) *
- 0.5f;
- // Blend between normal sun dir and adjusted sun dir based on how close we
- // are to having the sun overhead.
- mBumpSunDir = adjusted_dir * sun_dot + new_dir * (1.f - sun_dot);
- mBumpSunDir.normalize();
- mSun.setDirection(sun_direction);
- mSun.setAngularVelocity(sun_ang_velocity);
- mMoon.setDirection(-sun_direction);
- F32 dp = mLastLightingDirection * sun_direction;
- if (dp < 0.995f)
- {
- // The sun jumped a great deal, update immediately
- mForceUpdate = true;
- }
- }
- void LLVOSky::setSunDirectionCFR(const LLVector3& sun_dir_cfr)
- {
- mSun.setDirection(sun_dir_cfr);
- mSun.setAngularVelocity(LLVector3::zero);
- // Push the sun "South" as it approaches directly overhead so that we can
- // always see bump mapping on the upward facing faces of cubes.
-
- // Same as dot product with the up direction + clamp.
- F32 sun_dot = llmax(0.f, sun_dir_cfr.mV[2]);
- sun_dot *= sun_dot;
- // Create normalized vector that has the sun_dir pushed south about an hour
- // and change.
- LLVector3 adjusted_dir = (sun_dir_cfr +
- LLVector3(0.f, -0.70711f, 0.70711f)) * 0.5f;
-
- // Blend between normal sun dir and adjusted sun dir based on how close we
- // are to having the sun overhead.
- mBumpSunDir = adjusted_dir * sun_dot + sun_dir_cfr * (1.f - sun_dot);
- mBumpSunDir.normalize();
- const LLSettingsSky::ptr_t& skyp = gEnvironment.getCurrentSky();
- if (skyp) // Paranoia
- {
- updateDirections(skyp);
- }
- }
- void LLVOSky::setMoonDirectionCFR(const LLVector3& moon_dir)
- {
- mMoon.setDirection(moon_dir);
- const LLSettingsSky::ptr_t& skyp = gEnvironment.getCurrentSky();
- if (skyp) // Paranoia
- {
- updateDirections(skyp);
- }
- }
- void LLVOSky::updateDirections(const LLSettingsSky::ptr_t& skyp)
- {
- mSun.setDirection(skyp->getSunDirection());
- mSun.setAngularVelocity(LLVector3::zero);
- mSun.setRotation(skyp->getSunRotation());
- mMoon.setDirection(skyp->getMoonDirection());
- mMoon.setRotation(skyp->getMoonRotation());
- mSun.renewDirection();
- mMoon.renewDirection();
- }
- void LLVOSky::setSunTextures(const LLUUID& sun_tex1, const LLUUID& sun_tex2)
- {
- if (sun_tex1.isNull())
- {
- if (gSunTextureID != IMG_SUN)
- {
- mSunTexturep[0] =
- LLViewerTextureManager::getFetchedTexture(gSunTextureID,
- FTT_DEFAULT, true,
- LLGLTexture::BOOST_UI);
- mSunTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
- else
- {
- mSunTexturep[0] = LLViewerFetchedTexture::sDefaultSunImagep;
- }
- }
- else
- {
- mSunTexturep[0] =
- LLViewerTextureManager::getFetchedTexture(sun_tex1,
- FTT_DEFAULT, true,
- LLGLTexture::BOOST_UI);
- mSunTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
- if (sun_tex2.isNull())
- {
- mSunTexturep[1] = NULL;
- }
- else
- {
- mSunTexturep[1] =
- LLViewerTextureManager::getFetchedTexture(sun_tex2,
- FTT_DEFAULT, true,
- LLGLTexture::BOOST_UI);
- mSunTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
- LLFace* facep = mFace[FACE_SUN];
- if (!facep)
- {
- return;
- }
- LLViewerTexture* tex = facep->getTexture(LLRender::DIFFUSE_MAP);
- if (tex && tex != mSunTexturep[0] && tex->isViewerMediaTexture())
- {
- ((LLViewerMediaTexture*)tex)->removeMediaFromFace(facep);
- }
- tex = facep->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP);
- if (tex && tex != mSunTexturep[1] && tex->isViewerMediaTexture())
- {
- ((LLViewerMediaTexture*)tex)->removeMediaFromFace(facep);
- }
- facep->setTexture(LLRender::DIFFUSE_MAP, mSunTexturep[0]);
- if (mSunTexturep[1] && gPipeline.canUseWindLightShaders())
- {
- facep->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mSunTexturep[1]);
- }
- }
- void LLVOSky::setMoonTextures(const LLUUID& moon_tex1, const LLUUID& moon_tex2)
- {
- if (moon_tex1.isNull())
- {
- if (gMoonTextureID != IMG_MOON)
- {
- mMoonTexturep[0] =
- LLViewerTextureManager::getFetchedTexture(gMoonTextureID,
- FTT_DEFAULT, true,
- LLGLTexture::BOOST_UI);
- mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
- else
- {
- mMoonTexturep[0] = LLViewerFetchedTexture::sDefaultMoonImagep;
- }
- }
- else
- {
- mMoonTexturep[0] =
- LLViewerTextureManager::getFetchedTexture(moon_tex1,
- FTT_DEFAULT, true,
- LLGLTexture::BOOST_UI);
- mMoonTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
- if (moon_tex2.isNull())
- {
- mMoonTexturep[1] = NULL;
- }
- else
- {
- mMoonTexturep[1] =
- LLViewerTextureManager::getFetchedTexture(moon_tex2,
- FTT_DEFAULT, true,
- LLGLTexture::BOOST_UI);
- mMoonTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
- LLFace* facep = mFace[FACE_MOON];
- if (!facep)
- {
- return;
- }
- LLViewerTexture* tex = facep->getTexture(LLRender::DIFFUSE_MAP);
- if (tex && tex != mMoonTexturep[0] && tex->isViewerMediaTexture())
- {
- ((LLViewerMediaTexture*)tex)->removeMediaFromFace(facep);
- }
- tex = facep->getTexture(LLRender::ALTERNATE_DIFFUSE_MAP);
- if (tex && tex != mMoonTexturep[1] && tex->isViewerMediaTexture())
- {
- ((LLViewerMediaTexture*)tex)->removeMediaFromFace(facep);
- }
- facep->setTexture(LLRender::DIFFUSE_MAP, mMoonTexturep[0]);
- if (mMoonTexturep[1] && gPipeline.canUseWindLightShaders())
- {
- facep->setTexture(LLRender::ALTERNATE_DIFFUSE_MAP, mMoonTexturep[1]);
- }
- }
- void LLVOSky::setCloudNoiseTextures(const LLUUID& tex1, const LLUUID& tex2)
- {
- if (tex1.isNull())
- {
- mCloudNoiseTexturep[0] =
- LLViewerFetchedTexture::sDefaultCloudNoiseImagep;
- }
- else
- {
- mCloudNoiseTexturep[0] =
- LLViewerTextureManager::getFetchedTexture(tex1, FTT_DEFAULT, true,
- LLGLTexture::BOOST_UI);
- mCloudNoiseTexturep[0]->setAddressMode(LLTexUnit::TAM_WRAP);
- }
- if (tex2.isNull())
- {
- mCloudNoiseTexturep[1] = NULL;
- return;
- }
- mCloudNoiseTexturep[1] =
- LLViewerTextureManager::getFetchedTexture(tex2, FTT_DEFAULT, true,
- LLGLTexture::BOOST_UI);
- mCloudNoiseTexturep[1]->setAddressMode(LLTexUnit::TAM_WRAP);
- }
- void LLVOSky::setBloomTextures(const LLUUID& tex1, const LLUUID& tex2)
- {
- if (tex1.isNull())
- {
- mBloomTexturep[0] = LLViewerFetchedTexture::sBloomImagep;
- }
- else
- {
- mBloomTexturep[0] =
- LLViewerTextureManager::getFetchedTexture(tex1, FTT_DEFAULT, true,
- LLGLTexture::BOOST_UI);
- if (mBloomTexturep[0])
- {
- mBloomTexturep[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
- }
- if (tex2.isNull())
- {
- mBloomTexturep[1] = mBloomTexturep[0];
- return;
- }
- mBloomTexturep[1] =
- LLViewerTextureManager::getFetchedTexture(tex2, FTT_DEFAULT, true,
- LLGLTexture::BOOST_UI);
- mBloomTexturep[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
- }
|