Annotation of /trunk/indra/newview/lldrawpoolwater.cpp
Parent Directory
|
Revision Log
Revision 137 - (view) (download)
| 1 : | mjm | 135 | /** |
| 2 : | * @file lldrawpoolwater.cpp | ||
| 3 : | * @brief LLDrawPoolWater class implementation | ||
| 4 : | * | ||
| 5 : | * $LicenseInfo:firstyear=2002&license=viewergpl$ | ||
| 6 : | * | ||
| 7 : | mjm | 137 | * Copyright (c) 2002-2010, Linden Research, Inc. |
| 8 : | mjm | 135 | * |
| 9 : | * Second Life Viewer Source Code | ||
| 10 : | * The source code in this file ("Source Code") is provided by Linden Lab | ||
| 11 : | * to you under the terms of the GNU General Public License, version 2.0 | ||
| 12 : | * ("GPL"), unless you have obtained a separate licensing agreement | ||
| 13 : | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
| 14 : | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
| 15 : | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
| 16 : | * | ||
| 17 : | * There are special exceptions to the terms and conditions of the GPL as | ||
| 18 : | * it is applied to this Source Code. View the full text of the exception | ||
| 19 : | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
| 20 : | * online at | ||
| 21 : | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
| 22 : | * | ||
| 23 : | * By copying, modifying or distributing this software, you acknowledge | ||
| 24 : | * that you have read and understood your obligations described above, | ||
| 25 : | * and agree to abide by those obligations. | ||
| 26 : | * | ||
| 27 : | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
| 28 : | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
| 29 : | * COMPLETENESS OR PERFORMANCE. | ||
| 30 : | * $/LicenseInfo$ | ||
| 31 : | */ | ||
| 32 : | |||
| 33 : | #include "llviewerprecompiledheaders.h" | ||
| 34 : | #include "llfeaturemanager.h" | ||
| 35 : | #include "lldrawpoolwater.h" | ||
| 36 : | |||
| 37 : | #include "llviewercontrol.h" | ||
| 38 : | #include "lldir.h" | ||
| 39 : | #include "llerror.h" | ||
| 40 : | #include "m3math.h" | ||
| 41 : | #include "llrender.h" | ||
| 42 : | |||
| 43 : | #include "llagent.h" | ||
| 44 : | #include "llcubemap.h" | ||
| 45 : | #include "lldrawable.h" | ||
| 46 : | #include "llface.h" | ||
| 47 : | #include "llsky.h" | ||
| 48 : | #include "llviewercamera.h" | ||
| 49 : | #include "llviewerimagelist.h" | ||
| 50 : | #include "llviewerregion.h" | ||
| 51 : | #include "llvosky.h" | ||
| 52 : | #include "llvowater.h" | ||
| 53 : | #include "llworld.h" | ||
| 54 : | #include "pipeline.h" | ||
| 55 : | #include "llviewershadermgr.h" | ||
| 56 : | #include "llwaterparammanager.h" | ||
| 57 : | |||
| 58 : | const LLUUID WATER_TEST("2bfd3884-7e27-69b9-ba3a-3e673f680004"); | ||
| 59 : | |||
| 60 : | static float sTime; | ||
| 61 : | |||
| 62 : | BOOL deferred_render = FALSE; | ||
| 63 : | |||
| 64 : | BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE; | ||
| 65 : | BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE; | ||
| 66 : | BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE; | ||
| 67 : | LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f); | ||
| 68 : | LLVector3 LLDrawPoolWater::sLightDir; | ||
| 69 : | |||
| 70 : | LLDrawPoolWater::LLDrawPoolWater() : | ||
| 71 : | LLFacePool(POOL_WATER) | ||
| 72 : | { | ||
| 73 : | mHBTex[0] = gImageList.getImage(gSunTextureID, TRUE, TRUE); | ||
| 74 : | gGL.getTexUnit(0)->bind(mHBTex[0].get()); | ||
| 75 : | mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP); | ||
| 76 : | |||
| 77 : | mHBTex[1] = gImageList.getImage(gMoonTextureID, TRUE, TRUE); | ||
| 78 : | gGL.getTexUnit(0)->bind(mHBTex[1].get()); | ||
| 79 : | mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP); | ||
| 80 : | |||
| 81 : | mWaterImagep = gImageList.getImage(WATER_TEST); | ||
| 82 : | mWaterImagep->setNoDelete() ; | ||
| 83 : | mWaterNormp = gImageList.getImage(DEFAULT_WATER_NORMAL); | ||
| 84 : | mWaterNormp->setNoDelete() ; | ||
| 85 : | |||
| 86 : | restoreGL(); | ||
| 87 : | } | ||
| 88 : | |||
| 89 : | LLDrawPoolWater::~LLDrawPoolWater() | ||
| 90 : | { | ||
| 91 : | } | ||
| 92 : | |||
| 93 : | //static | ||
| 94 : | void LLDrawPoolWater::restoreGL() | ||
| 95 : | { | ||
| 96 : | |||
| 97 : | } | ||
| 98 : | |||
| 99 : | LLDrawPool *LLDrawPoolWater::instancePool() | ||
| 100 : | { | ||
| 101 : | llerrs << "Should never be calling instancePool on a water pool!" << llendl; | ||
| 102 : | return NULL; | ||
| 103 : | } | ||
| 104 : | |||
| 105 : | |||
| 106 : | void LLDrawPoolWater::prerender() | ||
| 107 : | { | ||
| 108 : | mVertexShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? | ||
| 109 : | LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; | ||
| 110 : | |||
| 111 : | // got rid of modulation by light color since it got a little too | ||
| 112 : | // green at sunset and sl-57047 (underwater turns black at 8:00) | ||
| 113 : | sWaterFogColor = LLWaterParamManager::instance()->getFogColor(); | ||
| 114 : | sWaterFogColor.mV[3] = 0; | ||
| 115 : | |||
| 116 : | } | ||
| 117 : | |||
| 118 : | S32 LLDrawPoolWater::getNumPasses() | ||
| 119 : | { | ||
| 120 : | if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f) | ||
| 121 : | { | ||
| 122 : | return 1; | ||
| 123 : | } | ||
| 124 : | |||
| 125 : | return 0; | ||
| 126 : | } | ||
| 127 : | |||
| 128 : | void LLDrawPoolWater::beginPostDeferredPass(S32 pass) | ||
| 129 : | { | ||
| 130 : | beginRenderPass(pass); | ||
| 131 : | deferred_render = TRUE; | ||
| 132 : | } | ||
| 133 : | |||
| 134 : | void LLDrawPoolWater::endPostDeferredPass(S32 pass) | ||
| 135 : | { | ||
| 136 : | endRenderPass(pass); | ||
| 137 : | deferred_render = FALSE; | ||
| 138 : | } | ||
| 139 : | |||
| 140 : | void LLDrawPoolWater::render(S32 pass) | ||
| 141 : | { | ||
| 142 : | LLFastTimer ftm(LLFastTimer::FTM_RENDER_WATER); | ||
| 143 : | if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1) | ||
| 144 : | { | ||
| 145 : | return; | ||
| 146 : | } | ||
| 147 : | |||
| 148 : | //do a quick 'n dirty depth sort | ||
| 149 : | for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); | ||
| 150 : | iter != mDrawFace.end(); iter++) | ||
| 151 : | { | ||
| 152 : | LLFace* facep = *iter; | ||
| 153 : | facep->mDistance = -facep->mCenterLocal.mV[2]; | ||
| 154 : | } | ||
| 155 : | |||
| 156 : | std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater()); | ||
| 157 : | |||
| 158 : | LLGLEnable blend(GL_BLEND); | ||
| 159 : | |||
| 160 : | if ((mVertexShaderLevel > 0) && !sSkipScreenCopy) | ||
| 161 : | { | ||
| 162 : | shade(); | ||
| 163 : | return; | ||
| 164 : | } | ||
| 165 : | |||
| 166 : | LLVOSky *voskyp = gSky.mVOSkyp; | ||
| 167 : | |||
| 168 : | stop_glerror(); | ||
| 169 : | |||
| 170 : | if (!gGLManager.mHasMultitexture) | ||
| 171 : | { | ||
| 172 : | // Ack! No multitexture! Bail! | ||
| 173 : | return; | ||
| 174 : | } | ||
| 175 : | |||
| 176 : | LLFace* refl_face = voskyp->getReflFace(); | ||
| 177 : | |||
| 178 : | gPipeline.disableLights(); | ||
| 179 : | |||
| 180 : | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); | ||
| 181 : | |||
| 182 : | LLGLDisable cullFace(GL_CULL_FACE); | ||
| 183 : | |||
| 184 : | // Set up second pass first | ||
| 185 : | mWaterImagep->addTextureStats(1024.f*1024.f); | ||
| 186 : | gGL.getTexUnit(1)->activate(); | ||
| 187 : | gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); | ||
| 188 : | gGL.getTexUnit(1)->bind(mWaterImagep.get()); | ||
| 189 : | |||
| 190 : | LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis(); | ||
| 191 : | F32 up_dot = camera_up * LLVector3::z_axis; | ||
| 192 : | |||
| 193 : | LLColor4 water_color; | ||
| 194 : | if (LLViewerCamera::getInstance()->cameraUnderWater()) | ||
| 195 : | { | ||
| 196 : | water_color.setVec(1.f, 1.f, 1.f, 0.4f); | ||
| 197 : | } | ||
| 198 : | else | ||
| 199 : | { | ||
| 200 : | water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); | ||
| 201 : | } | ||
| 202 : | |||
| 203 : | glColor4fv(water_color.mV); | ||
| 204 : | |||
| 205 : | // Automatically generate texture coords for detail map | ||
| 206 : | glEnable(GL_TEXTURE_GEN_S); //texture unit 1 | ||
| 207 : | glEnable(GL_TEXTURE_GEN_T); //texture unit 1 | ||
| 208 : | glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); | ||
| 209 : | glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); | ||
| 210 : | |||
| 211 : | // Slowly move over time. | ||
| 212 : | F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f); | ||
| 213 : | F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f}; | ||
| 214 : | F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f}; | ||
| 215 : | glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); | ||
| 216 : | glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1); | ||
| 217 : | |||
| 218 : | gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); | ||
| 219 : | gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA); | ||
| 220 : | |||
| 221 : | gGL.getTexUnit(0)->activate(); | ||
| 222 : | |||
| 223 : | glClearStencil(1); | ||
| 224 : | glClear(GL_STENCIL_BUFFER_BIT); | ||
| 225 : | LLGLEnable gls_stencil(GL_STENCIL_TEST); | ||
| 226 : | glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP); | ||
| 227 : | glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); | ||
| 228 : | |||
| 229 : | for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); | ||
| 230 : | iter != mDrawFace.end(); iter++) | ||
| 231 : | { | ||
| 232 : | LLFace *face = *iter; | ||
| 233 : | if (voskyp->isReflFace(face)) | ||
| 234 : | { | ||
| 235 : | continue; | ||
| 236 : | } | ||
| 237 : | gGL.getTexUnit(0)->bind(face->getTexture()); | ||
| 238 : | face->renderIndexed(); | ||
| 239 : | } | ||
| 240 : | |||
| 241 : | // Now, disable texture coord generation on texture state 1 | ||
| 242 : | gGL.getTexUnit(1)->activate(); | ||
| 243 : | gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); | ||
| 244 : | gGL.getTexUnit(1)->disable(); | ||
| 245 : | glDisable(GL_TEXTURE_GEN_S); //texture unit 1 | ||
| 246 : | glDisable(GL_TEXTURE_GEN_T); //texture unit 1 | ||
| 247 : | |||
| 248 : | // Disable texture coordinate and color arrays | ||
| 249 : | gGL.getTexUnit(0)->activate(); | ||
| 250 : | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | ||
| 251 : | |||
| 252 : | stop_glerror(); | ||
| 253 : | |||
| 254 : | if (gSky.mVOSkyp->getCubeMap()) | ||
| 255 : | { | ||
| 256 : | gSky.mVOSkyp->getCubeMap()->enable(0); | ||
| 257 : | gSky.mVOSkyp->getCubeMap()->bind(); | ||
| 258 : | |||
| 259 : | glMatrixMode(GL_TEXTURE); | ||
| 260 : | glLoadIdentity(); | ||
| 261 : | LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); | ||
| 262 : | LLMatrix4 camera_rot(camera_mat.getMat3()); | ||
| 263 : | camera_rot.invert(); | ||
| 264 : | |||
| 265 : | glLoadMatrixf((F32 *)camera_rot.mMatrix); | ||
| 266 : | |||
| 267 : | glMatrixMode(GL_MODELVIEW); | ||
| 268 : | LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f, 0.5f*up_dot); | ||
| 269 : | |||
| 270 : | gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); | ||
| 271 : | |||
| 272 : | for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); | ||
| 273 : | iter != mDrawFace.end(); iter++) | ||
| 274 : | { | ||
| 275 : | LLFace *face = *iter; | ||
| 276 : | if (voskyp->isReflFace(face)) | ||
| 277 : | { | ||
| 278 : | //refl_face = face; | ||
| 279 : | continue; | ||
| 280 : | } | ||
| 281 : | |||
| 282 : | if (face->getGeomCount() > 0) | ||
| 283 : | { | ||
| 284 : | face->renderIndexed(); | ||
| 285 : | } | ||
| 286 : | } | ||
| 287 : | |||
| 288 : | gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); | ||
| 289 : | |||
| 290 : | gSky.mVOSkyp->getCubeMap()->disable(); | ||
| 291 : | |||
| 292 : | gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); | ||
| 293 : | gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); | ||
| 294 : | glMatrixMode(GL_TEXTURE); | ||
| 295 : | glLoadIdentity(); | ||
| 296 : | glMatrixMode(GL_MODELVIEW); | ||
| 297 : | |||
| 298 : | } | ||
| 299 : | |||
| 300 : | glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); | ||
| 301 : | |||
| 302 : | if (refl_face) | ||
| 303 : | { | ||
| 304 : | glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF); | ||
| 305 : | renderReflection(refl_face); | ||
| 306 : | } | ||
| 307 : | |||
| 308 : | gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); | ||
| 309 : | } | ||
| 310 : | |||
| 311 : | void LLDrawPoolWater::renderReflection(LLFace* face) | ||
| 312 : | { | ||
| 313 : | LLVOSky *voskyp = gSky.mVOSkyp; | ||
| 314 : | |||
| 315 : | if (!voskyp) | ||
| 316 : | { | ||
| 317 : | return; | ||
| 318 : | } | ||
| 319 : | |||
| 320 : | if (!face->getGeomCount()) | ||
| 321 : | { | ||
| 322 : | return; | ||
| 323 : | } | ||
| 324 : | |||
| 325 : | S8 dr = voskyp->getDrawRefl(); | ||
| 326 : | if (dr < 0) | ||
| 327 : | { | ||
| 328 : | return; | ||
| 329 : | } | ||
| 330 : | |||
| 331 : | LLGLSNoFog noFog; | ||
| 332 : | |||
| 333 : | gGL.getTexUnit(0)->bind(mHBTex[dr].get()); | ||
| 334 : | |||
| 335 : | LLOverrideFaceColor override(this, face->getFaceColor().mV); | ||
| 336 : | face->renderIndexed(); | ||
| 337 : | } | ||
| 338 : | |||
| 339 : | void LLDrawPoolWater::shade() | ||
| 340 : | { | ||
| 341 : | gGL.setColorMask(true, true); | ||
| 342 : | |||
| 343 : | LLVOSky *voskyp = gSky.mVOSkyp; | ||
| 344 : | |||
| 345 : | if(voskyp == NULL) | ||
| 346 : | { | ||
| 347 : | return; | ||
| 348 : | } | ||
| 349 : | |||
| 350 : | LLGLDisable blend(GL_BLEND); | ||
| 351 : | |||
| 352 : | LLColor3 light_diffuse(0,0,0); | ||
| 353 : | F32 light_exp = 0.0f; | ||
| 354 : | LLVector3 light_dir; | ||
| 355 : | LLColor3 light_color; | ||
| 356 : | |||
| 357 : | if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS) | ||
| 358 : | { | ||
| 359 : | light_dir = gSky.getSunDirection(); | ||
| 360 : | light_dir.normVec(); | ||
| 361 : | light_color = gSky.getSunDiffuseColor(); | ||
| 362 : | if(gSky.mVOSkyp) { | ||
| 363 : | light_diffuse = gSky.mVOSkyp->getSun().getColorCached(); | ||
| 364 : | light_diffuse.normVec(); | ||
| 365 : | } | ||
| 366 : | light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); | ||
| 367 : | light_diffuse *= light_exp + 0.25f; | ||
| 368 : | } | ||
| 369 : | else | ||
| 370 : | { | ||
| 371 : | light_dir = gSky.getMoonDirection(); | ||
| 372 : | light_dir.normVec(); | ||
| 373 : | light_color = gSky.getMoonDiffuseColor(); | ||
| 374 : | light_diffuse = gSky.mVOSkyp->getMoon().getColorCached(); | ||
| 375 : | light_diffuse.normVec(); | ||
| 376 : | light_diffuse *= 0.5f; | ||
| 377 : | light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0); | ||
| 378 : | } | ||
| 379 : | |||
| 380 : | light_exp *= light_exp; | ||
| 381 : | light_exp *= light_exp; | ||
| 382 : | light_exp *= light_exp; | ||
| 383 : | light_exp *= light_exp; | ||
| 384 : | light_exp *= 256.f; | ||
| 385 : | light_exp = light_exp > 32.f ? light_exp : 32.f; | ||
| 386 : | |||
| 387 : | LLGLSLShader* shader; | ||
| 388 : | |||
| 389 : | F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight(); | ||
| 390 : | |||
| 391 : | if (deferred_render) | ||
| 392 : | { | ||
| 393 : | shader = &gDeferredWaterProgram; | ||
| 394 : | } | ||
| 395 : | else if (eyedepth < 0.f && LLPipeline::sWaterReflections) | ||
| 396 : | { | ||
| 397 : | shader = &gUnderWaterProgram; | ||
| 398 : | } | ||
| 399 : | else | ||
| 400 : | { | ||
| 401 : | shader = &gWaterProgram; | ||
| 402 : | } | ||
| 403 : | |||
| 404 : | sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; | ||
| 405 : | |||
| 406 : | S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX); | ||
| 407 : | |||
| 408 : | if (reftex > -1) | ||
| 409 : | { | ||
| 410 : | gGL.getTexUnit(reftex)->activate(); | ||
| 411 : | gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef); | ||
| 412 : | gGL.getTexUnit(0)->activate(); | ||
| 413 : | } | ||
| 414 : | |||
| 415 : | //bind normal map | ||
| 416 : | S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP); | ||
| 417 : | |||
| 418 : | LLWaterParamManager * param_mgr = LLWaterParamManager::instance(); | ||
| 419 : | |||
| 420 : | // change mWaterNormp if needed | ||
| 421 : | if (mWaterNormp->getID() != param_mgr->getNormalMapID()) | ||
| 422 : | { | ||
| 423 : | mWaterNormp = gImageList.getImage(param_mgr->getNormalMapID()); | ||
| 424 : | } | ||
| 425 : | |||
| 426 : | mWaterNormp->addTextureStats(1024.f*1024.f); | ||
| 427 : | gGL.getTexUnit(bumpTex)->bind(mWaterNormp.get()); | ||
| 428 : | if (gSavedSettings.getBOOL("RenderWaterMipNormal")) | ||
| 429 : | { | ||
| 430 : | mWaterNormp->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC); | ||
| 431 : | } | ||
| 432 : | else | ||
| 433 : | { | ||
| 434 : | mWaterNormp->setFilteringOption(LLTexUnit::TFO_POINT); | ||
| 435 : | } | ||
| 436 : | |||
| 437 : | S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX); | ||
| 438 : | |||
| 439 : | if (deferred_render) | ||
| 440 : | { | ||
| 441 : | gPipeline.bindDeferredShader(*shader); | ||
| 442 : | } | ||
| 443 : | else | ||
| 444 : | { | ||
| 445 : | shader->bind(); | ||
| 446 : | } | ||
| 447 : | |||
| 448 : | if (screentex > -1) | ||
| 449 : | { | ||
| 450 : | shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); | ||
| 451 : | shader->uniform1f(LLViewerShaderMgr::WATER_FOGDENSITY, | ||
| 452 : | param_mgr->getFogDensity()); | ||
| 453 : | gPipeline.mWaterDis.bindTexture(0, screentex); | ||
| 454 : | } | ||
| 455 : | |||
| 456 : | stop_glerror(); | ||
| 457 : | |||
| 458 : | gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis); | ||
| 459 : | |||
| 460 : | if (mVertexShaderLevel == 1) | ||
| 461 : | { | ||
| 462 : | sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue; | ||
| 463 : | shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); | ||
| 464 : | } | ||
| 465 : | |||
| 466 : | F32 screenRes[] = | ||
| 467 : | { | ||
| 468 : | 1.f/gGLViewport[2], | ||
| 469 : | 1.f/gGLViewport[3] | ||
| 470 : | }; | ||
| 471 : | shader->uniform2fv("screenRes", 1, screenRes); | ||
| 472 : | stop_glerror(); | ||
| 473 : | |||
| 474 : | S32 diffTex = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); | ||
| 475 : | stop_glerror(); | ||
| 476 : | |||
| 477 : | light_dir.normVec(); | ||
| 478 : | sLightDir = light_dir; | ||
| 479 : | |||
| 480 : | light_diffuse *= 6.f; | ||
| 481 : | |||
| 482 : | //shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix); | ||
| 483 : | shader->uniform1f(LLViewerShaderMgr::WATER_WATERHEIGHT, eyedepth); | ||
| 484 : | shader->uniform1f(LLViewerShaderMgr::WATER_TIME, sTime); | ||
| 485 : | shader->uniform3fv(LLViewerShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV); | ||
| 486 : | shader->uniform3fv(LLViewerShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV); | ||
| 487 : | shader->uniform1f(LLViewerShaderMgr::WATER_SPECULAR_EXP, light_exp); | ||
| 488 : | shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV); | ||
| 489 : | shader->uniform2fv(LLViewerShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV); | ||
| 490 : | shader->uniform3fv(LLViewerShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV); | ||
| 491 : | |||
| 492 : | shader->uniform3fv("normScale", 1, param_mgr->getNormalScale().mV); | ||
| 493 : | shader->uniform1f("fresnelScale", param_mgr->getFresnelScale()); | ||
| 494 : | shader->uniform1f("fresnelOffset", param_mgr->getFresnelOffset()); | ||
| 495 : | shader->uniform1f("blurMultiplier", param_mgr->getBlurMultiplier()); | ||
| 496 : | |||
| 497 : | F32 sunAngle = llmax(0.f, light_dir.mV[2]); | ||
| 498 : | F32 scaledAngle = 1.f - sunAngle; | ||
| 499 : | |||
| 500 : | shader->uniform1f("sunAngle", sunAngle); | ||
| 501 : | shader->uniform1f("scaledAngle", scaledAngle); | ||
| 502 : | shader->uniform1f("sunAngle2", 0.1f + 0.2f*sunAngle); | ||
| 503 : | |||
| 504 : | LLColor4 water_color; | ||
| 505 : | LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis(); | ||
| 506 : | F32 up_dot = camera_up * LLVector3::z_axis; | ||
| 507 : | if (LLViewerCamera::getInstance()->cameraUnderWater()) | ||
| 508 : | { | ||
| 509 : | water_color.setVec(1.f, 1.f, 1.f, 0.4f); | ||
| 510 : | shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow()); | ||
| 511 : | } | ||
| 512 : | else | ||
| 513 : | { | ||
| 514 : | water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); | ||
| 515 : | shader->uniform1f(LLViewerShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove()); | ||
| 516 : | } | ||
| 517 : | |||
| 518 : | if (water_color.mV[3] > 0.9f) | ||
| 519 : | { | ||
| 520 : | water_color.mV[3] = 0.9f; | ||
| 521 : | } | ||
| 522 : | |||
| 523 : | glColor4fv(water_color.mV); | ||
| 524 : | |||
| 525 : | { | ||
| 526 : | LLGLDisable cullface(GL_CULL_FACE); | ||
| 527 : | for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); | ||
| 528 : | iter != mDrawFace.end(); iter++) | ||
| 529 : | { | ||
| 530 : | LLFace *face = *iter; | ||
| 531 : | |||
| 532 : | if (voskyp->isReflFace(face)) | ||
| 533 : | { | ||
| 534 : | continue; | ||
| 535 : | } | ||
| 536 : | |||
| 537 : | LLVOWater* water = (LLVOWater*) face->getViewerObject(); | ||
| 538 : | gGL.getTexUnit(diffTex)->bind(face->getTexture()); | ||
| 539 : | |||
| 540 : | sNeedsReflectionUpdate = TRUE; | ||
| 541 : | |||
| 542 : | if (water->getUseTexture()) | ||
| 543 : | { | ||
| 544 : | sNeedsDistortionUpdate = TRUE; | ||
| 545 : | face->renderIndexed(); | ||
| 546 : | } | ||
| 547 : | else | ||
| 548 : | { //smash background faces to far clip plane | ||
| 549 : | if (water->getIsEdgePatch()) | ||
| 550 : | { | ||
| 551 : | LLGLClampToFarClip far_clip(glh_get_current_projection()); | ||
| 552 : | face->renderIndexed(); | ||
| 553 : | } | ||
| 554 : | else | ||
| 555 : | { | ||
| 556 : | sNeedsDistortionUpdate = TRUE; | ||
| 557 : | face->renderIndexed(); | ||
| 558 : | } | ||
| 559 : | } | ||
| 560 : | } | ||
| 561 : | } | ||
| 562 : | |||
| 563 : | shader->disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); | ||
| 564 : | shader->disableTexture(LLViewerShaderMgr::WATER_SCREENTEX); | ||
| 565 : | shader->disableTexture(LLViewerShaderMgr::BUMP_MAP); | ||
| 566 : | shader->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); | ||
| 567 : | shader->disableTexture(LLViewerShaderMgr::WATER_REFTEX); | ||
| 568 : | shader->disableTexture(LLViewerShaderMgr::WATER_SCREENDEPTH); | ||
| 569 : | |||
| 570 : | if (deferred_render) | ||
| 571 : | { | ||
| 572 : | gPipeline.unbindDeferredShader(*shader); | ||
| 573 : | } | ||
| 574 : | else | ||
| 575 : | { | ||
| 576 : | shader->unbind(); | ||
| 577 : | } | ||
| 578 : | |||
| 579 : | gGL.getTexUnit(0)->activate(); | ||
| 580 : | gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); | ||
| 581 : | gGL.setColorMask(true, false); | ||
| 582 : | |||
| 583 : | } | ||
| 584 : | |||
| 585 : | void LLDrawPoolWater::renderForSelect() | ||
| 586 : | { | ||
| 587 : | // Can't select water! | ||
| 588 : | return; | ||
| 589 : | } | ||
| 590 : | |||
| 591 : | |||
| 592 : | void LLDrawPoolWater::renderFaceSelected(LLFace *facep, | ||
| 593 : | LLImageGL *image, | ||
| 594 : | const LLColor4 &color, | ||
| 595 : | const S32 index_offset, const S32 index_count) | ||
| 596 : | { | ||
| 597 : | // Can't select water | ||
| 598 : | return; | ||
| 599 : | } | ||
| 600 : | |||
| 601 : | |||
| 602 : | LLViewerImage *LLDrawPoolWater::getDebugTexture() | ||
| 603 : | { | ||
| 604 : | return LLViewerImage::sSmokeImagep; | ||
| 605 : | } | ||
| 606 : | |||
| 607 : | LLColor3 LLDrawPoolWater::getDebugColor() const | ||
| 608 : | { | ||
| 609 : | return LLColor3(0.f, 1.f, 1.f); | ||
| 610 : | } |
| ViewVC Help | |
| Powered by ViewVC 1.0.0 |

