00001
00032 #include "llviewerprecompiledheaders.h"
00033 #include "llfeaturemanager.h"
00034 #include "lldrawpoolwater.h"
00035
00036 #include "llviewercontrol.h"
00037 #include "lldir.h"
00038 #include "llerror.h"
00039 #include "m3math.h"
00040
00041 #include "llagent.h"
00042 #include "llcubemap.h"
00043 #include "lldrawable.h"
00044 #include "llface.h"
00045 #include "llsky.h"
00046 #include "llviewercamera.h"
00047 #include "llviewerimagelist.h"
00048 #include "llviewerregion.h"
00049 #include "llvosky.h"
00050 #include "llvowater.h"
00051 #include "llworld.h"
00052 #include "pipeline.h"
00053 #include "llglslshader.h"
00054 #include "llwaterparammanager.h"
00055
00056 const LLUUID WATER_TEST("2bfd3884-7e27-69b9-ba3a-3e673f680004");
00057
00058 static float sTime;
00059
00060 BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;
00061 BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
00062 BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
00063 LLColor4 LLDrawPoolWater::sWaterFogColor = LLColor4(0.2f, 0.5f, 0.5f, 0.f);
00064 LLVector3 LLDrawPoolWater::sLightDir;
00065
00066 LLDrawPoolWater::LLDrawPoolWater() :
00067 LLFacePool(POOL_WATER)
00068 {
00069 mHBTex[0] = gImageList.getImage(gSunTextureID, TRUE, TRUE);
00070 mHBTex[0]->bind();
00071 mHBTex[0]->setClamp(TRUE, TRUE);
00072
00073 mHBTex[1] = gImageList.getImage(gMoonTextureID, TRUE, TRUE);
00074 mHBTex[1]->bind();
00075 mHBTex[1]->setClamp(TRUE, TRUE);
00076
00077 mWaterImagep = gImageList.getImage(WATER_TEST);
00078 mWaterNormp = gImageList.getImage(DEFAULT_WATER_NORMAL);
00079
00080 restoreGL();
00081 }
00082
00083 LLDrawPoolWater::~LLDrawPoolWater()
00084 {
00085 }
00086
00087
00088 void LLDrawPoolWater::restoreGL()
00089 {
00090
00091 }
00092
00093 LLDrawPool *LLDrawPoolWater::instancePool()
00094 {
00095 llerrs << "Should never be calling instancePool on a water pool!" << llendl;
00096 return NULL;
00097 }
00098
00099
00100 void LLDrawPoolWater::prerender()
00101 {
00102 mVertexShaderLevel = (gGLManager.mHasCubeMap && LLFeatureManager::getInstance()->isFeatureAvailable("RenderCubeMap")) ?
00103 LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_WATER) : 0;
00104
00105
00106
00107 sWaterFogColor = LLWaterParamManager::instance()->getFogColor();
00108 sWaterFogColor.mV[3] = 0;
00109
00110 }
00111
00112 S32 LLDrawPoolWater::getNumPasses()
00113 {
00114 if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f)
00115 {
00116 return 1;
00117 }
00118
00119 return 0;
00120 }
00121
00122 void LLDrawPoolWater::render(S32 pass)
00123 {
00124 LLFastTimer ftm(LLFastTimer::FTM_RENDER_WATER);
00125 if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1)
00126 {
00127 return;
00128 }
00129
00130
00131 for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
00132 iter != mDrawFace.end(); iter++)
00133 {
00134 LLFace* facep = *iter;
00135 facep->mDistance = -facep->mCenterLocal.mV[2];
00136 }
00137
00138 std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater());
00139
00140 LLGLEnable blend(GL_BLEND);
00141
00142 if ((mVertexShaderLevel > 0) && !sSkipScreenCopy)
00143 {
00144 shade();
00145 return;
00146 }
00147
00148 LLVOSky *voskyp = gSky.mVOSkyp;
00149
00150 stop_glerror();
00151
00152 if (!gGLManager.mHasMultitexture)
00153 {
00154
00155 return;
00156 }
00157
00158 LLFace* refl_face = voskyp->getReflFace();
00159
00160 gPipeline.disableLights();
00161
00162 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
00163
00164 LLGLDisable cullFace(GL_CULL_FACE);
00165
00166
00167 mWaterImagep->addTextureStats(1024.f*1024.f);
00168 mWaterImagep->bind(1);
00169 glActiveTextureARB(GL_TEXTURE1_ARB);
00170
00171 glEnable(GL_TEXTURE_2D);
00172
00173 LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
00174 F32 up_dot = camera_up * LLVector3::z_axis;
00175
00176 LLColor4 water_color;
00177 if (LLViewerCamera::getInstance()->cameraUnderWater())
00178 {
00179 water_color.setVec(1.f, 1.f, 1.f, 0.4f);
00180 }
00181 else
00182 {
00183 water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
00184 }
00185
00186 glColor4fv(water_color.mV);
00187
00188
00189 glEnable(GL_TEXTURE_GEN_S);
00190 glEnable(GL_TEXTURE_GEN_T);
00191 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
00192 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
00193
00194
00195 F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f);
00196 F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f};
00197 F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f};
00198 glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
00199 glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
00200
00201 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
00202 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
00203 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
00204
00205 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
00206 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
00207 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
00208 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
00209 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
00210 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
00211
00212 glActiveTextureARB(GL_TEXTURE0_ARB);
00213
00214 glClearStencil(1);
00215 glClear(GL_STENCIL_BUFFER_BIT);
00216 LLGLEnable gls_stencil(GL_STENCIL_TEST);
00217 glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
00218 glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
00219
00220 for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
00221 iter != mDrawFace.end(); iter++)
00222 {
00223 LLFace *face = *iter;
00224 if (voskyp->isReflFace(face))
00225 {
00226 continue;
00227 }
00228 face->bindTexture();
00229 face->renderIndexed();
00230 }
00231
00232
00233 glActiveTextureARB(GL_TEXTURE1_ARB);
00234 glDisable(GL_TEXTURE_2D);
00235 glDisable(GL_TEXTURE_GEN_S);
00236 glDisable(GL_TEXTURE_GEN_T);
00237 LLImageGL::unbindTexture(1, GL_TEXTURE_2D);
00238
00239
00240 glActiveTextureARB(GL_TEXTURE0_ARB);
00241 LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
00242
00243 stop_glerror();
00244
00245 if (gSky.mVOSkyp->getCubeMap())
00246 {
00247 gSky.mVOSkyp->getCubeMap()->enable(0);
00248 gSky.mVOSkyp->getCubeMap()->bind();
00249
00250 glMatrixMode(GL_TEXTURE);
00251 glLoadIdentity();
00252 LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
00253 LLMatrix4 camera_rot(camera_mat.getMat3());
00254 camera_rot.invert();
00255
00256 glLoadMatrixf((F32 *)camera_rot.mMatrix);
00257
00258 glMatrixMode(GL_MODELVIEW);
00259 LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f, 0.5f*up_dot);
00260
00261 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00262
00263 for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
00264 iter != mDrawFace.end(); iter++)
00265 {
00266 LLFace *face = *iter;
00267 if (voskyp->isReflFace(face))
00268 {
00269
00270 continue;
00271 }
00272
00273 if (face->getGeomCount() > 0)
00274 {
00275 face->renderIndexed();
00276 }
00277 }
00278
00279 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00280
00281 if (gSky.mVOSkyp->getCubeMap())
00282 {
00283 gSky.mVOSkyp->getCubeMap()->disable();
00284 }
00285 LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
00286 glEnable(GL_TEXTURE_2D);
00287 glMatrixMode(GL_TEXTURE);
00288 glLoadIdentity();
00289 glMatrixMode(GL_MODELVIEW);
00290
00291 }
00292
00293 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
00294
00295 if (refl_face)
00296 {
00297 glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
00298 renderReflection(refl_face);
00299 }
00300
00301 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00302 }
00303
00304 void LLDrawPoolWater::renderReflection(LLFace* face)
00305 {
00306 LLVOSky *voskyp = gSky.mVOSkyp;
00307
00308 if (!voskyp)
00309 {
00310 return;
00311 }
00312
00313 if (!face->getGeomCount())
00314 {
00315 return;
00316 }
00317
00318 S8 dr = voskyp->getDrawRefl();
00319 if (dr < 0)
00320 {
00321 return;
00322 }
00323
00324 LLGLSNoFog noFog;
00325
00326 LLViewerImage::bindTexture(mHBTex[dr]);
00327
00328 LLOverrideFaceColor override(this, face->getFaceColor().mV);
00329 face->renderIndexed();
00330 }
00331
00332 void LLDrawPoolWater::shade()
00333 {
00334 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
00335
00336 LLVOSky *voskyp = gSky.mVOSkyp;
00337
00338 if(voskyp == NULL)
00339 {
00340 return;
00341 }
00342
00343 LLGLDisable blend(GL_BLEND);
00344
00345 LLColor3 light_diffuse(0,0,0);
00346 F32 light_exp = 0.0f;
00347 LLVector3 light_dir;
00348 LLColor3 light_color;
00349
00350 if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS)
00351 {
00352 light_dir = gSky.getSunDirection();
00353 light_dir.normVec();
00354 light_color = gSky.getSunDiffuseColor();
00355 if(gSky.mVOSkyp) {
00356 light_diffuse = gSky.mVOSkyp->getSun().getColorCached();
00357 light_diffuse.normVec();
00358 }
00359 light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0);
00360 light_diffuse *= light_exp + 0.25f;
00361 }
00362 else
00363 {
00364 light_dir = gSky.getMoonDirection();
00365 light_dir.normVec();
00366 light_color = gSky.getMoonDiffuseColor();
00367 light_diffuse = gSky.mVOSkyp->getMoon().getColorCached();
00368 light_diffuse.normVec();
00369 light_diffuse *= 0.5f;
00370 light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0);
00371 }
00372
00373 light_exp *= light_exp;
00374 light_exp *= light_exp;
00375 light_exp *= light_exp;
00376 light_exp *= light_exp;
00377 light_exp *= 256.f;
00378 light_exp = light_exp > 32.f ? light_exp : 32.f;
00379
00380 LLGLSLShader* shader;
00381
00382 F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - gAgent.getRegion()->getWaterHeight();
00383
00384 if (eyedepth < 0.f && LLPipeline::sWaterReflections)
00385 {
00386 shader = &gUnderWaterProgram;
00387 }
00388 else
00389 {
00390 shader = &gWaterProgram;
00391 }
00392
00393 sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
00394
00395 S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
00396
00397 if (reftex > -1)
00398 {
00399 glActiveTextureARB(GL_TEXTURE0_ARB+reftex);
00400 gPipeline.mWaterRef.bindTexture();
00401 glActiveTextureARB(GL_TEXTURE0_ARB);
00402 }
00403
00404
00405 S32 bumpTex = shader->enableTexture(LLShaderMgr::BUMP_MAP);
00406
00407 LLWaterParamManager * param_mgr = LLWaterParamManager::instance();
00408
00409
00410 if (mWaterNormp->getID() != param_mgr->getNormalMapID())
00411 {
00412 mWaterNormp = gImageList.getImage(param_mgr->getNormalMapID());
00413 }
00414
00415 mWaterNormp->addTextureStats(1024.f*1024.f);
00416 mWaterNormp->bind(bumpTex);
00417 if (!gSavedSettings.getBOOL("RenderWaterMipNormal"))
00418 {
00419 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00420 }
00421 else
00422 {
00423 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
00424 }
00425
00426 S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
00427 stop_glerror();
00428
00429 shader->bind();
00430
00431 if (screentex > -1)
00432 {
00433 shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
00434 shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY,
00435 param_mgr->getFogDensity());
00436 }
00437
00438 gPipeline.mWaterDis.bindTexture();
00439
00440 if (mVertexShaderLevel == 1)
00441 {
00442 sWaterFogColor.mV[3] = param_mgr->mDensitySliderValue;
00443 shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV);
00444 }
00445
00446 F32 screenRes[] =
00447 {
00448 1.f/gGLViewport[2],
00449 1.f/gGLViewport[3]
00450 };
00451 shader->uniform2fv("screenRes", 1, screenRes);
00452 stop_glerror();
00453
00454 S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
00455 stop_glerror();
00456
00457 light_dir.normVec();
00458 sLightDir = light_dir;
00459
00460 light_diffuse *= 6.f;
00461
00462
00463 shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth);
00464 shader->uniform1f(LLShaderMgr::WATER_TIME, sTime);
00465 shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
00466 shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
00467 shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
00468 shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, param_mgr->getWave1Dir().mV);
00469 shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, param_mgr->getWave2Dir().mV);
00470 shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
00471
00472 shader->uniform3fv("normScale", 1, param_mgr->getNormalScale().mV);
00473 shader->uniform1f("fresnelScale", param_mgr->getFresnelScale());
00474 shader->uniform1f("fresnelOffset", param_mgr->getFresnelOffset());
00475 shader->uniform1f("blurMultiplier", param_mgr->getBlurMultiplier());
00476
00477 F32 sunAngle = llmax(0.f, light_dir.mV[2]);
00478 F32 scaledAngle = 1.f - sunAngle;
00479
00480 shader->uniform1f("sunAngle", sunAngle);
00481 shader->uniform1f("scaledAngle", scaledAngle);
00482 shader->uniform1f("sunAngle2", 0.1f + 0.2f*sunAngle);
00483
00484 LLColor4 water_color;
00485 LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
00486 F32 up_dot = camera_up * LLVector3::z_axis;
00487 if (LLViewerCamera::getInstance()->cameraUnderWater())
00488 {
00489 water_color.setVec(1.f, 1.f, 1.f, 0.4f);
00490 shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleBelow());
00491 }
00492 else
00493 {
00494 water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
00495 shader->uniform1f(LLShaderMgr::WATER_REFSCALE, param_mgr->getScaleAbove());
00496 }
00497
00498 if (water_color.mV[3] > 0.9f)
00499 {
00500 water_color.mV[3] = 0.9f;
00501 }
00502
00503 glColor4fv(water_color.mV);
00504
00505 {
00506 LLGLDisable cullface(GL_CULL_FACE);
00507 for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
00508 iter != mDrawFace.end(); iter++)
00509 {
00510 LLFace *face = *iter;
00511
00512 if (voskyp->isReflFace(face))
00513 {
00514 continue;
00515 }
00516
00517 LLVOWater* water = (LLVOWater*) face->getViewerObject();
00518 face->bindTexture(diffTex);
00519
00520 sNeedsReflectionUpdate = TRUE;
00521
00522 if (water->getUseTexture())
00523 {
00524 sNeedsDistortionUpdate = TRUE;
00525 face->renderIndexed();
00526 }
00527 else
00528 {
00529 if (water->getIsEdgePatch())
00530 {
00531 LLGLClampToFarClip far_clip(glh_get_current_projection());
00532 face->renderIndexed();
00533 }
00534 else
00535 {
00536 sNeedsDistortionUpdate = TRUE;
00537 face->renderIndexed();
00538 }
00539 }
00540 }
00541 }
00542
00543 shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB);
00544 shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);
00545 shader->disableTexture(LLShaderMgr::BUMP_MAP);
00546 shader->disableTexture(LLShaderMgr::DIFFUSE_MAP);
00547 shader->disableTexture(LLShaderMgr::WATER_REFTEX);
00548 shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
00549 shader->unbind();
00550
00551 glActiveTextureARB(GL_TEXTURE0_ARB);
00552 glEnable(GL_TEXTURE_2D);
00553 glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
00554
00555 }
00556
00557 void LLDrawPoolWater::renderForSelect()
00558 {
00559
00560 return;
00561 }
00562
00563
00564 void LLDrawPoolWater::renderFaceSelected(LLFace *facep,
00565 LLImageGL *image,
00566 const LLColor4 &color,
00567 const S32 index_offset, const S32 index_count)
00568 {
00569
00570 return;
00571 }
00572
00573
00574 LLViewerImage *LLDrawPoolWater::getDebugTexture()
00575 {
00576 return LLViewerImage::sSmokeImagep;
00577 }
00578
00579 LLColor3 LLDrawPoolWater::getDebugColor() const
00580 {
00581 return LLColor3(0.f, 1.f, 1.f);
00582 }