diff options
Diffstat (limited to 'indra/newview/lldrawpoolwater.cpp')
-rwxr-xr-x[-rw-r--r--] | indra/newview/lldrawpoolwater.cpp | 310 |
1 files changed, 209 insertions, 101 deletions
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index 21e17cc207..df06ad31e6 100644..100755 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -2,31 +2,25 @@ * @file lldrawpoolwater.cpp * @brief LLDrawPoolWater class implementation * - * $LicenseInfo:firstyear=2002&license=viewergpl$ - * - * Copyright (c) 2002-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * 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 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * 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 + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * 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. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -54,7 +48,8 @@ #include "llviewershadermgr.h" #include "llwaterparammanager.h" -const LLUUID WATER_TEST("2bfd3884-7e27-69b9-ba3a-3e673f680004"); +const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004"); +const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055"); static float sTime; @@ -64,23 +59,29 @@ BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE; BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE; BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE; LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f); +F32 LLDrawPoolWater::sWaterFogEnd = 0.f; + LLVector3 LLDrawPoolWater::sLightDir; LLDrawPoolWater::LLDrawPoolWater() : LLFacePool(POOL_WATER) { - mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, TRUE); + mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); gGL.getTexUnit(0)->bind(mHBTex[0]) ; mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP); - mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, TRUE); + mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI); gGL.getTexUnit(0)->bind(mHBTex[1]); mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP); - mWaterImagep = LLViewerTextureManager::getFetchedTexture(WATER_TEST); - mWaterImagep->setNoDelete() ; + + mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE); + llassert(mWaterImagep); + mWaterImagep->setNoDelete(); + mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE); + llassert(mOpaqueWaterImagep); mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL); - mWaterNormp->setNoDelete() ; + mWaterNormp->setNoDelete(); restoreGL(); } @@ -97,7 +98,7 @@ void LLDrawPoolWater::restoreGL() LLDrawPool *LLDrawPoolWater::instancePool() { - llerrs << "Should never be calling instancePool on a water pool!" << llendl; + LL_ERRS() << "Should never be calling instancePool on a water pool!" << LL_ENDL; return NULL; } @@ -109,7 +110,7 @@ void LLDrawPoolWater::prerender() // got rid of modulation by light color since it got a little too // green at sunset and sl-57047 (underwater turns black at 8:00) - sWaterFogColor = LLWaterParamManager::instance()->getFogColor(); + sWaterFogColor = LLWaterParamManager::instance().getFogColor(); sWaterFogColor.mV[3] = 0; } @@ -141,7 +142,7 @@ void LLDrawPoolWater::endPostDeferredPass(S32 pass) //=============================== void LLDrawPoolWater::renderDeferred(S32 pass) { - LLFastTimer t(FTM_RENDER_WATER); + LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER); deferred_render = TRUE; shade(); deferred_render = FALSE; @@ -151,7 +152,7 @@ void LLDrawPoolWater::renderDeferred(S32 pass) void LLDrawPoolWater::render(S32 pass) { - LLFastTimer ftm(FTM_RENDER_WATER); + LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER); if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1) { return; @@ -167,6 +168,14 @@ void LLDrawPoolWater::render(S32 pass) std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater()); + // See if we are rendering water as opaque or not + if (!gSavedSettings.getBOOL("RenderTransparentWater")) + { + // render water for low end hardware + renderOpaqueLegacyWater(); + return; + } + LLGLEnable blend(GL_BLEND); if ((mVertexShaderLevel > 0) && !sSkipScreenCopy) @@ -212,7 +221,7 @@ void LLDrawPoolWater::render(S32 pass) water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); } - glColor4fv(water_color.mV); + gGL.diffuseColor4fv(water_color.mV); // Automatically generate texture coords for detail map glEnable(GL_TEXTURE_GEN_S); //texture unit 1 @@ -268,15 +277,15 @@ void LLDrawPoolWater::render(S32 pass) gSky.mVOSkyp->getCubeMap()->enable(0); gSky.mVOSkyp->getCubeMap()->bind(); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); LLMatrix4 camera_rot(camera_mat.getMat3()); camera_rot.invert(); - glLoadMatrixf((F32 *)camera_rot.mMatrix); + gGL.loadMatrix((F32 *)camera_rot.mMatrix); - glMatrixMode(GL_MODELVIEW); + gGL.matrixMode(LLRender::MM_MODELVIEW); LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f, 0.5f*up_dot); gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); @@ -303,9 +312,9 @@ void LLDrawPoolWater::render(S32 pass) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); } @@ -320,6 +329,116 @@ void LLDrawPoolWater::render(S32 pass) gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); } +// for low end hardware +void LLDrawPoolWater::renderOpaqueLegacyWater() +{ + LLVOSky *voskyp = gSky.mVOSkyp; + + LLGLSLShader* shader = NULL; + if (LLGLSLShader::sNoFixedFunction) + { + if (LLPipeline::sUnderWaterRender) + { + shader = &gObjectSimpleNonIndexedTexGenWaterProgram; + } + else + { + shader = &gObjectSimpleNonIndexedTexGenProgram; + } + + shader->bind(); + } + + stop_glerror(); + + // Depth sorting and write to depth buffer + // since this is opaque, we should see nothing + // behind the water. No blending because + // of no transparency. And no face culling so + // that the underside of the water is also opaque. + LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); + LLGLDisable no_cull(GL_CULL_FACE); + LLGLDisable no_blend(GL_BLEND); + + gPipeline.disableLights(); + + mOpaqueWaterImagep->addTextureStats(1024.f*1024.f); + + // Activate the texture binding and bind one + // texture since all images will have the same texture + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->bind(mOpaqueWaterImagep); + + // Automatically generate texture coords for water texture + if (!shader) + { + glEnable(GL_TEXTURE_GEN_S); //texture unit 0 + glEnable(GL_TEXTURE_GEN_T); //texture unit 0 + glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + } + + // Use the fact that we know all water faces are the same size + // to save some computation + + // Slowly move texture coordinates over time so the watter appears + // to be moving. + F32 movement_period_secs = 50.f; + + F32 offset = fmod(gFrameTimeSeconds, movement_period_secs); + + if (movement_period_secs != 0) + { + offset /= movement_period_secs; + } + else + { + offset = 0; + } + + F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset }; + F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset }; + + if (!shader) + { + glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); + glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1); + } + else + { + shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0); + shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1); + } + + gGL.diffuseColor3f(1.f, 1.f, 1.f); + + for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); + iter != mDrawFace.end(); iter++) + { + LLFace *face = *iter; + if (voskyp->isReflFace(face)) + { + continue; + } + + face->renderIndexed(); + } + + stop_glerror(); + + if (!shader) + { + // Reset the settings back to expected values + glDisable(GL_TEXTURE_GEN_S); //texture unit 0 + glDisable(GL_TEXTURE_GEN_T); //texture unit 0 + } + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +} + + void LLDrawPoolWater::renderReflection(LLFace* face) { LLVOSky *voskyp = gSky.mVOSkyp; @@ -344,7 +463,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face) gGL.getTexUnit(0)->bind(mHBTex[dr]); - LLOverrideFaceColor override(this, face->getFaceColor().mV); + LLOverrideFaceColor override(this, LLColor4(face->getFaceColor().mV)); face->renderIndexed(); } @@ -403,14 +522,21 @@ void LLDrawPoolWater::shade() F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight(); + if (eyedepth < 0.f && LLPipeline::sWaterReflections) + { if (deferred_render) { - shader = &gDeferredWaterProgram; + shader = &gDeferredUnderWaterProgram; } - else if (eyedepth < 0.f && LLPipeline::sWaterReflections) + else { shader = &gUnderWaterProgram; } + } + else if (deferred_render) + { + shader = &gDeferredWaterProgram; + } else { shader = &gWaterProgram; @@ -427,7 +553,7 @@ void LLDrawPoolWater::shade() sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; - S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX); + S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX); if (reftex > -1) { @@ -439,7 +565,7 @@ void LLDrawPoolWater::shade() //bind normal map S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP); - LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); + LLWaterParamManager * param_mgr = &LLWaterParamManager::instance(); // change mWaterNormp if needed if (mWaterNormp->getID() != param_mgr->getNormalMapID()) @@ -458,12 +584,12 @@ void LLDrawPoolWater::shade() mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT); } - S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX); + S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX); if (screentex > -1) { - shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); - shader->uniform1f(LLViewerShaderMgr::WATER_FOGDENSITY, + shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); + shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, param_mgr->getFogDensity()); gPipeline.mWaterDis.bindTexture(0, screentex); } @@ -475,7 +601,7 @@ void LLDrawPoolWater::shade() if (mVertexShaderLevel == 1) { sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue; - shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); + shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); } F32 screenRes[] = @@ -483,10 +609,10 @@ void LLDrawPoolWater::shade() 1.f/gGLViewport[2], 1.f/gGLViewport[3] }; - shader->uniform2fv("screenRes", 1, screenRes); + shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes); stop_glerror(); - S32 diffTex = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP); stop_glerror(); light_dir.normVec(); @@ -495,26 +621,26 @@ void LLDrawPoolWater::shade() light_diffuse *= 6.f; //shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix); - shader->uniform1f(LLViewerShaderMgr::WATER_WATERHEIGHT, eyedepth); - shader->uniform1f(LLViewerShaderMgr::WATER_TIME, sTime); - shader->uniform3fv(LLViewerShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV); - shader->uniform3fv(LLViewerShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); - shader->uniform1f(LLViewerShaderMgr::WATER_SPECULAR_EXP, light_exp); - shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV); - shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV); - shader->uniform3fv(LLViewerShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); - - shader->uniform3fv("normScale", 1, param_mgr->getNormalScale().mV); - shader->uniform1f("fresnelScale", param_mgr->getFresnelScale()); - shader->uniform1f("fresnelOffset", param_mgr->getFresnelOffset()); - shader->uniform1f("blurMultiplier", param_mgr->getBlurMultiplier()); + shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth); + shader->uniform1f(LLShaderMgr::WATER_TIME, sTime); + shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV); + shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); + shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp); + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV); + shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV); + shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); + + shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, param_mgr->getNormalScale().mV); + shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, param_mgr->getFresnelScale()); + shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, param_mgr->getFresnelOffset()); + shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, param_mgr->getBlurMultiplier()); F32 sunAngle = llmax(0.f, light_dir.mV[2]); F32 scaledAngle = 1.f - sunAngle; - shader->uniform1f("sunAngle", sunAngle); - shader->uniform1f("scaledAngle", scaledAngle); - shader->uniform1f("sunAngle2", 0.1f + 0.2f*sunAngle); + shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle); + shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle); + shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f*sunAngle); LLColor4 water_color; LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis(); @@ -522,12 +648,12 @@ void LLDrawPoolWater::shade() if (LLViewerCamera::getInstance()->cameraUnderWater()) { water_color.setVec(1.f, 1.f, 1.f, 0.4f); - shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow()); + shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow()); } else { water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); - shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove()); + shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove()); } if (water_color.mV[3] > 0.9f) @@ -535,9 +661,8 @@ void LLDrawPoolWater::shade() water_color.mV[3] = 0.9f; } - glColor4fv(water_color.mV); - { + LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); LLGLDisable cullface(GL_CULL_FACE); for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) @@ -554,40 +679,29 @@ void LLDrawPoolWater::shade() sNeedsReflectionUpdate = TRUE; - if (water->getUseTexture()) + if (water->getUseTexture() || !water->getIsEdgePatch()) { sNeedsDistortionUpdate = TRUE; face->renderIndexed(); } + else if (gGLManager.mHasDepthClamp || deferred_render) + { + face->renderIndexed(); + } else - { //smash background faces to far clip plane - if (water->getIsEdgePatch()) - { - if (deferred_render) - { - face->renderIndexed(); - } - else - { - LLGLClampToFarClip far_clip(glh_get_current_projection()); - face->renderIndexed(); - } - } - else - { - sNeedsDistortionUpdate = TRUE; - face->renderIndexed(); - } + { + LLGLSquashToFarClip far_clip(glh_get_current_projection()); + face->renderIndexed(); } } } - shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); - shader->disableTexture(LLViewerShaderMgr::WATER_SCREENTEX); - shader->disableTexture(LLViewerShaderMgr::BUMP_MAP); - shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - shader->disableTexture(LLViewerShaderMgr::WATER_REFTEX); - shader->disableTexture(LLViewerShaderMgr::WATER_SCREENDEPTH); + shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); + shader->disableTexture(LLShaderMgr::WATER_SCREENTEX); + shader->disableTexture(LLShaderMgr::BUMP_MAP); + shader->disableTexture(LLShaderMgr::DIFFUSE_MAP); + shader->disableTexture(LLShaderMgr::WATER_REFTEX); + shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH); if (deferred_render) { @@ -607,12 +721,6 @@ void LLDrawPoolWater::shade() } -void LLDrawPoolWater::renderForSelect() -{ - // Can't select water! - return; -} - LLViewerTexture *LLDrawPoolWater::getDebugTexture() { return LLViewerFetchedTexture::sSmokeImagep; |