diff options
Diffstat (limited to 'linden')
28 files changed, 477 insertions, 167 deletions
diff --git a/linden/indra/llrender/llgl.cpp b/linden/indra/llrender/llgl.cpp index 61194c4..c08ad0d 100644 --- a/linden/indra/llrender/llgl.cpp +++ b/linden/indra/llrender/llgl.cpp | |||
@@ -552,41 +552,46 @@ extern LLCPUInfo gSysCPU; | |||
552 | void LLGLManager::initExtensions() | 552 | void LLGLManager::initExtensions() |
553 | { | 553 | { |
554 | #if LL_MESA_HEADLESS | 554 | #if LL_MESA_HEADLESS |
555 | # if GL_ARB_multitexture | 555 | # ifdef GL_ARB_multitexture |
556 | mHasMultitexture = TRUE; | 556 | mHasMultitexture = TRUE; |
557 | # else | 557 | # else |
558 | mHasMultitexture = FALSE; | 558 | mHasMultitexture = FALSE; |
559 | # endif | 559 | # endif |
560 | # if GL_ARB_texture_env_combine | 560 | # ifdef GL_ARB_texture_env_combine |
561 | mHasARBEnvCombine = TRUE; | 561 | mHasARBEnvCombine = TRUE; |
562 | # else | 562 | # else |
563 | mHasARBEnvCombine = FALSE; | 563 | mHasARBEnvCombine = FALSE; |
564 | # endif | 564 | # endif |
565 | # if GL_ARB_texture_compression | 565 | # ifdef GL_ARB_texture_compression |
566 | mHasCompressedTextures = TRUE; | 566 | mHasCompressedTextures = TRUE; |
567 | # else | 567 | # else |
568 | mHasCompressedTextures = FALSE; | 568 | mHasCompressedTextures = FALSE; |
569 | # endif | 569 | # endif |
570 | # if GL_ARB_vertex_buffer_object | 570 | # ifdef GL_ARB_vertex_buffer_object |
571 | mHasVertexBufferObject = TRUE; | 571 | mHasVertexBufferObject = TRUE; |
572 | # else | 572 | # else |
573 | mHasVertexBufferObject = FALSE; | 573 | mHasVertexBufferObject = FALSE; |
574 | # endif | 574 | # endif |
575 | # if GL_EXT_framebuffer_object | 575 | # ifdef GL_EXT_framebuffer_object |
576 | mHasFramebufferObject = TRUE; | 576 | mHasFramebufferObject = TRUE; |
577 | # else | 577 | # else |
578 | mHasFramebufferObject = FALSE; | 578 | mHasFramebufferObject = FALSE; |
579 | # endif | 579 | # endif |
580 | # if GL_EXT_framebuffer_multisample | 580 | # ifdef GL_EXT_framebuffer_multisample |
581 | mHasFramebufferMultisample = TRUE; | 581 | mHasFramebufferMultisample = TRUE; |
582 | # else | 582 | # else |
583 | mHasFramebufferMultisample = FALSE; | 583 | mHasFramebufferMultisample = FALSE; |
584 | # endif | 584 | # endif |
585 | # if GL_ARB_draw_buffers | 585 | # ifdef GL_ARB_draw_buffers |
586 | mHasDrawBuffers = TRUE; | 586 | mHasDrawBuffers = TRUE; |
587 | #else | 587 | #else |
588 | mHasDrawBuffers = FALSE; | 588 | mHasDrawBuffers = FALSE; |
589 | # endif | 589 | # endif |
590 | # if defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp) | ||
591 | mHasDepthClamp = TRUE; | ||
592 | #else | ||
593 | mHasDepthClamp = FALSE; | ||
594 | #endif | ||
590 | mHasMipMapGeneration = FALSE; | 595 | mHasMipMapGeneration = FALSE; |
591 | mHasSeparateSpecularColor = FALSE; | 596 | mHasSeparateSpecularColor = FALSE; |
592 | mHasAnisotropic = FALSE; | 597 | mHasAnisotropic = FALSE; |
@@ -612,6 +617,7 @@ void LLGLManager::initExtensions() | |||
612 | && ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts); | 617 | && ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts); |
613 | mHasFramebufferMultisample = mHasFramebufferObject && ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts); | 618 | mHasFramebufferMultisample = mHasFramebufferObject && ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts); |
614 | mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts); | 619 | mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts); |
620 | mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts); | ||
615 | #if !LL_DARWIN | 621 | #if !LL_DARWIN |
616 | mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts); | 622 | mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts); |
617 | #endif | 623 | #endif |
@@ -634,6 +640,7 @@ void LLGLManager::initExtensions() | |||
634 | mHasFramebufferObject = FALSE; | 640 | mHasFramebufferObject = FALSE; |
635 | mHasFramebufferMultisample = FALSE; | 641 | mHasFramebufferMultisample = FALSE; |
636 | mHasDrawBuffers = FALSE; | 642 | mHasDrawBuffers = FALSE; |
643 | mHasDepthClamp = FALSE; | ||
637 | mHasMipMapGeneration = FALSE; | 644 | mHasMipMapGeneration = FALSE; |
638 | mHasSeparateSpecularColor = FALSE; | 645 | mHasSeparateSpecularColor = FALSE; |
639 | mHasAnisotropic = FALSE; | 646 | mHasAnisotropic = FALSE; |
@@ -685,10 +692,11 @@ void LLGLManager::initExtensions() | |||
685 | if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S | 692 | if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S |
686 | if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S | 693 | if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S |
687 | if (strchr(blacklist,'s')) mHasFramebufferMultisample = FALSE; | 694 | if (strchr(blacklist,'s')) mHasFramebufferMultisample = FALSE; |
695 | if (strchr(blacklist,'t')) mHasDepthClamp = FALSE; | ||
688 | 696 | ||
689 | } | 697 | } |
690 | #endif // LL_LINUX || LL_SOLARIS | 698 | #endif // LL_LINUX || LL_SOLARIS |
691 | 699 | ||
692 | if (!mHasMultitexture) | 700 | if (!mHasMultitexture) |
693 | { | 701 | { |
694 | LL_INFOS("RenderInit") << "Couldn't initialize multitexturing" << LL_ENDL; | 702 | LL_INFOS("RenderInit") << "Couldn't initialize multitexturing" << LL_ENDL; |
@@ -1773,7 +1781,7 @@ LLGLDepthTest::~LLGLDepthTest() | |||
1773 | } | 1781 | } |
1774 | } | 1782 | } |
1775 | 1783 | ||
1776 | LLGLClampToFarClip::LLGLClampToFarClip(glh::matrix4f P) | 1784 | LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P) |
1777 | { | 1785 | { |
1778 | for (U32 i = 0; i < 4; i++) | 1786 | for (U32 i = 0; i < 4; i++) |
1779 | { | 1787 | { |
@@ -1786,7 +1794,7 @@ LLGLClampToFarClip::LLGLClampToFarClip(glh::matrix4f P) | |||
1786 | glMatrixMode(GL_MODELVIEW); | 1794 | glMatrixMode(GL_MODELVIEW); |
1787 | } | 1795 | } |
1788 | 1796 | ||
1789 | LLGLClampToFarClip::~LLGLClampToFarClip() | 1797 | LLGLSquashToFarClip::~LLGLSquashToFarClip() |
1790 | { | 1798 | { |
1791 | glMatrixMode(GL_PROJECTION); | 1799 | glMatrixMode(GL_PROJECTION); |
1792 | glPopMatrix(); | 1800 | glPopMatrix(); |
diff --git a/linden/indra/llrender/llgl.h b/linden/indra/llrender/llgl.h index 00ff1e2..cc7ebff 100644 --- a/linden/indra/llrender/llgl.h +++ b/linden/indra/llrender/llgl.h | |||
@@ -88,6 +88,7 @@ public: | |||
88 | BOOL mHasOcclusionQuery; | 88 | BOOL mHasOcclusionQuery; |
89 | BOOL mHasPointParameters; | 89 | BOOL mHasPointParameters; |
90 | BOOL mHasDrawBuffers; | 90 | BOOL mHasDrawBuffers; |
91 | BOOL mHasDepthClamp; | ||
91 | 92 | ||
92 | // Other extensions. | 93 | // Other extensions. |
93 | BOOL mHasAnisotropic; | 94 | BOOL mHasAnisotropic; |
@@ -306,11 +307,11 @@ private: | |||
306 | leaves this class. | 307 | leaves this class. |
307 | Does not stack. | 308 | Does not stack. |
308 | */ | 309 | */ |
309 | class LLGLClampToFarClip | 310 | class LLGLSquashToFarClip |
310 | { | 311 | { |
311 | public: | 312 | public: |
312 | LLGLClampToFarClip(glh::matrix4f projection); | 313 | LLGLSquashToFarClip(glh::matrix4f projection); |
313 | ~LLGLClampToFarClip(); | 314 | ~LLGLSquashToFarClip(); |
314 | }; | 315 | }; |
315 | 316 | ||
316 | /* | 317 | /* |
diff --git a/linden/indra/llrender/llglheaders.h b/linden/indra/llrender/llglheaders.h index c7178a5..9e3ae9d 100644 --- a/linden/indra/llrender/llglheaders.h +++ b/linden/indra/llrender/llglheaders.h | |||
@@ -819,5 +819,15 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *); | |||
819 | 819 | ||
820 | #endif // LL_MESA / LL_WINDOWS / LL_DARWIN | 820 | #endif // LL_MESA / LL_WINDOWS / LL_DARWIN |
821 | 821 | ||
822 | // Even when GL_ARB_depth_clamp is available in the driver, the (correct) | ||
823 | // headers, and therefore GL_DEPTH_CLAMP might not be defined. | ||
824 | // In that case GL_DEPTH_CLAMP_NV should be defined, but why not just | ||
825 | // use the known numeric. | ||
826 | // | ||
827 | // To avoid #ifdef's in the code. Just define this here. | ||
828 | #ifndef GL_DEPTH_CLAMP | ||
829 | // Probably (still) called GL_DEPTH_CLAMP_NV. | ||
830 | #define GL_DEPTH_CLAMP 0x864F | ||
831 | #endif | ||
822 | 832 | ||
823 | #endif // LL_LLGLHEADERS_H | 833 | #endif // LL_LLGLHEADERS_H |
diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index bd4e05c..966b1af 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml | |||
@@ -9840,6 +9840,17 @@ | |||
9840 | <key>Value</key> | 9840 | <key>Value</key> |
9841 | <integer>0</integer> | 9841 | <integer>0</integer> |
9842 | </map> | 9842 | </map> |
9843 | <key>RenderWaterVoidCulling</key> | ||
9844 | <map> | ||
9845 | <key>Comment</key> | ||
9846 | <string>Cull void water objects when off-screen.</string> | ||
9847 | <key>Persist</key> | ||
9848 | <integer>1</integer> | ||
9849 | <key>Type</key> | ||
9850 | <string>Boolean</string> | ||
9851 | <key>Value</key> | ||
9852 | <integer>1</integer> | ||
9853 | </map> | ||
9843 | <key>RotateRight</key> | 9854 | <key>RotateRight</key> |
9844 | <map> | 9855 | <map> |
9845 | <key>Comment</key> | 9856 | <key>Comment</key> |
diff --git a/linden/indra/newview/lldrawable.cpp b/linden/indra/newview/lldrawable.cpp index 14aa38a..494ac5b 100644 --- a/linden/indra/newview/lldrawable.cpp +++ b/linden/indra/newview/lldrawable.cpp | |||
@@ -361,6 +361,8 @@ void LLDrawable::makeActive() | |||
361 | { | 361 | { |
362 | U32 pcode = mVObjp->getPCode(); | 362 | U32 pcode = mVObjp->getPCode(); |
363 | if (pcode == LLViewerObject::LL_VO_WATER || | 363 | if (pcode == LLViewerObject::LL_VO_WATER || |
364 | pcode == LLViewerObject::LL_VO_HOLE_WATER || | ||
365 | pcode == LLViewerObject::LL_VO_EDGE_WATER || | ||
364 | pcode == LLViewerObject::LL_VO_SURFACE_PATCH || | 366 | pcode == LLViewerObject::LL_VO_SURFACE_PATCH || |
365 | pcode == LLViewerObject::LL_VO_PART_GROUP || | 367 | pcode == LLViewerObject::LL_VO_PART_GROUP || |
366 | pcode == LLViewerObject::LL_VO_HUD_PART_GROUP || | 368 | pcode == LLViewerObject::LL_VO_HUD_PART_GROUP || |
diff --git a/linden/indra/newview/lldrawpool.cpp b/linden/indra/newview/lldrawpool.cpp index e1bf1ed..3421731 100644 --- a/linden/indra/newview/lldrawpool.cpp +++ b/linden/indra/newview/lldrawpool.cpp | |||
@@ -95,6 +95,7 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0) | |||
95 | case POOL_SKY: | 95 | case POOL_SKY: |
96 | poolp = new LLDrawPoolSky(); | 96 | poolp = new LLDrawPoolSky(); |
97 | break; | 97 | break; |
98 | case POOL_VOIDWATER: | ||
98 | case POOL_WATER: | 99 | case POOL_WATER: |
99 | poolp = new LLDrawPoolWater(); | 100 | poolp = new LLDrawPoolWater(); |
100 | break; | 101 | break; |
diff --git a/linden/indra/newview/lldrawpool.h b/linden/indra/newview/lldrawpool.h index 87c3cca..f8c2ead 100644 --- a/linden/indra/newview/lldrawpool.h +++ b/linden/indra/newview/lldrawpool.h | |||
@@ -63,6 +63,7 @@ public: | |||
63 | POOL_BUMP, | 63 | POOL_BUMP, |
64 | POOL_INVISIBLE, | 64 | POOL_INVISIBLE, |
65 | POOL_AVATAR, | 65 | POOL_AVATAR, |
66 | POOL_VOIDWATER, | ||
66 | POOL_WATER, | 67 | POOL_WATER, |
67 | POOL_GLOW, | 68 | POOL_GLOW, |
68 | POOL_ALPHA, | 69 | POOL_ALPHA, |
diff --git a/linden/indra/newview/lldrawpoolground.cpp b/linden/indra/newview/lldrawpoolground.cpp index 889b494..c65524b 100644 --- a/linden/indra/newview/lldrawpoolground.cpp +++ b/linden/indra/newview/lldrawpoolground.cpp | |||
@@ -74,7 +74,7 @@ void LLDrawPoolGround::render(S32 pass) | |||
74 | 74 | ||
75 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); | 75 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); |
76 | 76 | ||
77 | LLGLClampToFarClip far_clip(glh_get_current_projection()); | 77 | LLGLSquashToFarClip far_clip(glh_get_current_projection()); |
78 | 78 | ||
79 | F32 water_height = gAgent.getRegion()->getWaterHeight(); | 79 | F32 water_height = gAgent.getRegion()->getWaterHeight(); |
80 | glPushMatrix(); | 80 | glPushMatrix(); |
diff --git a/linden/indra/newview/lldrawpoolsky.cpp b/linden/indra/newview/lldrawpoolsky.cpp index f0ed380..bed1030 100644 --- a/linden/indra/newview/lldrawpoolsky.cpp +++ b/linden/indra/newview/lldrawpoolsky.cpp | |||
@@ -101,7 +101,7 @@ void LLDrawPoolSky::render(S32 pass) | |||
101 | 101 | ||
102 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); | 102 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); |
103 | 103 | ||
104 | LLGLClampToFarClip far_clip(glh_get_current_projection()); | 104 | LLGLSquashToFarClip far_clip(glh_get_current_projection()); |
105 | 105 | ||
106 | LLGLEnable fog_enable( (mVertexShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0); | 106 | LLGLEnable fog_enable( (mVertexShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0); |
107 | 107 | ||
diff --git a/linden/indra/newview/lldrawpoolwater.cpp b/linden/indra/newview/lldrawpoolwater.cpp index ce3425d..81e1c68 100644 --- a/linden/indra/newview/lldrawpoolwater.cpp +++ b/linden/indra/newview/lldrawpoolwater.cpp | |||
@@ -523,6 +523,7 @@ void LLDrawPoolWater::shade() | |||
523 | glColor4fv(water_color.mV); | 523 | glColor4fv(water_color.mV); |
524 | 524 | ||
525 | { | 525 | { |
526 | LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); | ||
526 | LLGLDisable cullface(GL_CULL_FACE); | 527 | LLGLDisable cullface(GL_CULL_FACE); |
527 | for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); | 528 | for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); |
528 | iter != mDrawFace.end(); iter++) | 529 | iter != mDrawFace.end(); iter++) |
@@ -538,24 +539,20 @@ void LLDrawPoolWater::shade() | |||
538 | gGL.getTexUnit(diffTex)->bind(face->getTexture()); | 539 | gGL.getTexUnit(diffTex)->bind(face->getTexture()); |
539 | 540 | ||
540 | sNeedsReflectionUpdate = TRUE; | 541 | sNeedsReflectionUpdate = TRUE; |
541 | 542 | ||
542 | if (water->getUseTexture()) | 543 | if (water->getUseTexture() || !water->isEdgeWater()) |
543 | { | 544 | { |
544 | sNeedsDistortionUpdate = TRUE; | 545 | sNeedsDistortionUpdate = TRUE; |
545 | face->renderIndexed(); | 546 | face->renderIndexed(); |
546 | } | 547 | } |
548 | else if (gGLManager.mHasDepthClamp) | ||
549 | { | ||
550 | face->renderIndexed(); | ||
551 | } | ||
547 | else | 552 | else |
548 | { //smash background faces to far clip plane | 553 | { |
549 | if (water->getIsEdgePatch()) | 554 | LLGLSquashToFarClip far_clip(glh_get_current_projection()); |
550 | { | 555 | face->renderIndexed(); |
551 | LLGLClampToFarClip far_clip(glh_get_current_projection()); | ||
552 | face->renderIndexed(); | ||
553 | } | ||
554 | else | ||
555 | { | ||
556 | sNeedsDistortionUpdate = TRUE; | ||
557 | face->renderIndexed(); | ||
558 | } | ||
559 | } | 556 | } |
560 | } | 557 | } |
561 | } | 558 | } |
diff --git a/linden/indra/newview/lldrawpoolwlsky.cpp b/linden/indra/newview/lldrawpoolwlsky.cpp index 6ff65c7..451d08e 100644 --- a/linden/indra/newview/lldrawpoolwlsky.cpp +++ b/linden/indra/newview/lldrawpoolwlsky.cpp | |||
@@ -269,7 +269,7 @@ void LLDrawPoolWLSky::render(S32 pass) | |||
269 | LLGLDepthTest depth(GL_TRUE, GL_FALSE); | 269 | LLGLDepthTest depth(GL_TRUE, GL_FALSE); |
270 | LLGLDisable clip(GL_CLIP_PLANE0); | 270 | LLGLDisable clip(GL_CLIP_PLANE0); |
271 | 271 | ||
272 | LLGLClampToFarClip far_clip(glh_get_current_projection()); | 272 | LLGLSquashToFarClip far_clip(glh_get_current_projection()); |
273 | 273 | ||
274 | renderSkyHaze(camHeightLocal); | 274 | renderSkyHaze(camHeightLocal); |
275 | 275 | ||
diff --git a/linden/indra/newview/llfloatergodtools.cpp b/linden/indra/newview/llfloatergodtools.cpp index 2bbbc65..461dfe2 100644 --- a/linden/indra/newview/llfloatergodtools.cpp +++ b/linden/indra/newview/llfloatergodtools.cpp | |||
@@ -252,13 +252,6 @@ void LLFloaterGodTools::onTabChanged(void* data, bool from_click) | |||
252 | // static | 252 | // static |
253 | void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) | 253 | void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) |
254 | { | 254 | { |
255 | LLHost host = msg->getSender(); | ||
256 | if (host != gAgent.getRegionHost()) | ||
257 | { | ||
258 | // update is for a different region than the one we're in | ||
259 | return; | ||
260 | } | ||
261 | |||
262 | //const S32 SIM_NAME_BUF = 256; | 255 | //const S32 SIM_NAME_BUF = 256; |
263 | U32 region_flags; | 256 | U32 region_flags; |
264 | U8 sim_access; | 257 | U8 sim_access; |
@@ -276,6 +269,8 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) | |||
276 | S32 redirect_grid_y; | 269 | S32 redirect_grid_y; |
277 | LLUUID cache_id; | 270 | LLUUID cache_id; |
278 | 271 | ||
272 | LLHost host = msg->getSender(); | ||
273 | |||
279 | msg->getStringFast(_PREHASH_RegionInfo, _PREHASH_SimName, sim_name); | 274 | msg->getStringFast(_PREHASH_RegionInfo, _PREHASH_SimName, sim_name); |
280 | msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_EstateID, estate_id); | 275 | msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_EstateID, estate_id); |
281 | msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, parent_estate_id); | 276 | msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, parent_estate_id); |
@@ -285,6 +280,15 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg) | |||
285 | msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, object_bonus_factor); | 280 | msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, object_bonus_factor); |
286 | msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_BillableFactor, billable_factor); | 281 | msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_BillableFactor, billable_factor); |
287 | msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height); | 282 | msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height); |
283 | |||
284 | if (host != gAgent.getRegionHost()) | ||
285 | { | ||
286 | // Update is for a different region than the one we're in. | ||
287 | // Just check for a waterheight change. | ||
288 | LLWorld::getInstance()->waterHeightRegionInfo(sim_name, water_height); | ||
289 | return; | ||
290 | } | ||
291 | |||
288 | msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainRaiseLimit, terrain_raise_limit); | 292 | msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainRaiseLimit, terrain_raise_limit); |
289 | msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainLowerLimit, terrain_lower_limit); | 293 | msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_TerrainLowerLimit, terrain_lower_limit); |
290 | msg->getS32Fast(_PREHASH_RegionInfo, _PREHASH_PricePerMeter, price_per_meter); | 294 | msg->getS32Fast(_PREHASH_RegionInfo, _PREHASH_PricePerMeter, price_per_meter); |
diff --git a/linden/indra/newview/llspatialpartition.cpp b/linden/indra/newview/llspatialpartition.cpp index 31b537c..01ed375 100644 --- a/linden/indra/newview/llspatialpartition.cpp +++ b/linden/indra/newview/llspatialpartition.cpp | |||
@@ -1302,7 +1302,11 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) | |||
1302 | { | 1302 | { |
1303 | if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) | 1303 | if (mSpatialPartition->isOcclusionEnabled() && LLPipeline::sUseOcclusion > 1) |
1304 | { | 1304 | { |
1305 | if (earlyFail(camera, this)) | 1305 | static LLCachedControl<BOOL> render_water_void_culling("RenderWaterVoidCulling", TRUE); |
1306 | // Don't cull hole/edge water, unless RenderWaterVoidCulling is set and we have the GL_ARB_depth_clamp extension. | ||
1307 | if ((mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER && | ||
1308 | !(render_water_void_culling && gGLManager.mHasDepthClamp)) || | ||
1309 | earlyFail(camera, this)) | ||
1306 | { | 1310 | { |
1307 | setState(LLSpatialGroup::DISCARD_QUERY); | 1311 | setState(LLSpatialGroup::DISCARD_QUERY); |
1308 | assert_states_valid(this); | 1312 | assert_states_valid(this); |
@@ -1324,11 +1328,28 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) | |||
1324 | buildOcclusion(); | 1328 | buildOcclusion(); |
1325 | } | 1329 | } |
1326 | 1330 | ||
1331 | // Depth clamp all water to avoid it being culled as a result of being | ||
1332 | // behind the far clip plane, and in the case of edge water to avoid | ||
1333 | // it being culled while still visible. | ||
1334 | bool const use_depth_clamp = | ||
1335 | gGLManager.mHasDepthClamp && | ||
1336 | (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER || | ||
1337 | mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER); | ||
1338 | if (use_depth_clamp) | ||
1339 | { | ||
1340 | glEnable(GL_DEPTH_CLAMP); | ||
1341 | } | ||
1342 | |||
1327 | glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQuery); | 1343 | glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQuery); |
1328 | glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts); | 1344 | glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts); |
1329 | glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, | 1345 | glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, |
1330 | GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0])); | 1346 | GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0])); |
1331 | glEndQueryARB(GL_SAMPLES_PASSED_ARB); | 1347 | glEndQueryARB(GL_SAMPLES_PASSED_ARB); |
1348 | |||
1349 | if (use_depth_clamp) | ||
1350 | { | ||
1351 | glDisable(GL_DEPTH_CLAMP); | ||
1352 | } | ||
1332 | } | 1353 | } |
1333 | 1354 | ||
1334 | setState(LLSpatialGroup::QUERY_PENDING); | 1355 | setState(LLSpatialGroup::QUERY_PENDING); |
@@ -2280,9 +2301,11 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE) | |||
2280 | gGL.color4f(0.5f,0.5f,0.5f,1.0f); | 2301 | gGL.color4f(0.5f,0.5f,0.5f,1.0f); |
2281 | break; | 2302 | break; |
2282 | case LLViewerObject::LL_VO_PART_GROUP: | 2303 | case LLViewerObject::LL_VO_PART_GROUP: |
2283 | case LLViewerObject::LL_VO_HUD_PART_GROUP: | 2304 | case LLViewerObject::LL_VO_HUD_PART_GROUP: |
2284 | gGL.color4f(0,0,1,1); | 2305 | gGL.color4f(0,0,1,1); |
2285 | break; | 2306 | break; |
2307 | case LLViewerObject::LL_VO_EDGE_WATER: | ||
2308 | case LLViewerObject::LL_VO_HOLE_WATER: | ||
2286 | case LLViewerObject::LL_VO_WATER: | 2309 | case LLViewerObject::LL_VO_WATER: |
2287 | gGL.color4f(0,0.5f,1,1); | 2310 | gGL.color4f(0,0.5f,1,1); |
2288 | break; | 2311 | break; |
diff --git a/linden/indra/newview/llspatialpartition.h b/linden/indra/newview/llspatialpartition.h index df96152..be0163b 100644 --- a/linden/indra/newview/llspatialpartition.h +++ b/linden/indra/newview/llspatialpartition.h | |||
@@ -481,7 +481,6 @@ private: | |||
481 | drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES]; | 481 | drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES]; |
482 | }; | 482 | }; |
483 | 483 | ||
484 | |||
485 | //spatial partition for water (implemented in LLVOWater.cpp) | 484 | //spatial partition for water (implemented in LLVOWater.cpp) |
486 | class LLWaterPartition : public LLSpatialPartition | 485 | class LLWaterPartition : public LLSpatialPartition |
487 | { | 486 | { |
@@ -491,6 +490,13 @@ public: | |||
491 | virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { } | 490 | virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count) { } |
492 | }; | 491 | }; |
493 | 492 | ||
493 | //spatial partition for hole and edge water (implemented in LLVOWater.cpp) | ||
494 | class LLVoidWaterPartition : public LLWaterPartition | ||
495 | { | ||
496 | public: | ||
497 | LLVoidWaterPartition(); | ||
498 | }; | ||
499 | |||
494 | //spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp) | 500 | //spatial partition for terrain (impelmented in LLVOSurfacePatch.cpp) |
495 | class LLTerrainPartition : public LLSpatialPartition | 501 | class LLTerrainPartition : public LLSpatialPartition |
496 | { | 502 | { |
diff --git a/linden/indra/newview/llsurface.cpp b/linden/indra/newview/llsurface.cpp index a27f0e2..caaba05 100644 --- a/linden/indra/newview/llsurface.cpp +++ b/linden/indra/newview/llsurface.cpp | |||
@@ -1167,8 +1167,13 @@ void LLSurface::setWaterHeight(F32 height) | |||
1167 | if (!mWaterObjp.isNull()) | 1167 | if (!mWaterObjp.isNull()) |
1168 | { | 1168 | { |
1169 | LLVector3 water_pos_region = mWaterObjp->getPositionRegion(); | 1169 | LLVector3 water_pos_region = mWaterObjp->getPositionRegion(); |
1170 | bool changed = water_pos_region.mV[VZ] != height; | ||
1170 | water_pos_region.mV[VZ] = height; | 1171 | water_pos_region.mV[VZ] = height; |
1171 | mWaterObjp->setPositionRegion(water_pos_region); | 1172 | mWaterObjp->setPositionRegion(water_pos_region); |
1173 | if (changed) | ||
1174 | { | ||
1175 | LLWorld::getInstance()->updateWaterObjects(); | ||
1176 | } | ||
1172 | } | 1177 | } |
1173 | else | 1178 | else |
1174 | { | 1179 | { |
diff --git a/linden/indra/newview/llviewerdisplay.cpp b/linden/indra/newview/llviewerdisplay.cpp index ad186d5..5316337 100644 --- a/linden/indra/newview/llviewerdisplay.cpp +++ b/linden/indra/newview/llviewerdisplay.cpp | |||
@@ -602,7 +602,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) | |||
602 | gFrameStats.start(LLFrameStats::UPDATE_CULL); | 602 | gFrameStats.start(LLFrameStats::UPDATE_CULL); |
603 | S32 water_clip = 0; | 603 | S32 water_clip = 0; |
604 | if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) && | 604 | if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) && |
605 | gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER)) | 605 | (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER) || |
606 | gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER))) | ||
606 | { | 607 | { |
607 | if (LLViewerCamera::getInstance()->cameraUnderWater()) | 608 | if (LLViewerCamera::getInstance()->cameraUnderWater()) |
608 | { | 609 | { |
diff --git a/linden/indra/newview/llviewerobject.cpp b/linden/indra/newview/llviewerobject.cpp index a854583..f3353bb 100644 --- a/linden/indra/newview/llviewerobject.cpp +++ b/linden/indra/newview/llviewerobject.cpp | |||
@@ -144,6 +144,9 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco | |||
144 | res = new LLVOSurfacePatch(id, pcode, regionp); break; | 144 | res = new LLVOSurfacePatch(id, pcode, regionp); break; |
145 | case LL_VO_SKY: | 145 | case LL_VO_SKY: |
146 | res = new LLVOSky(id, pcode, regionp); break; | 146 | res = new LLVOSky(id, pcode, regionp); break; |
147 | case LL_VO_EDGE_WATER: | ||
148 | case LL_VO_HOLE_WATER: | ||
149 | res = new LLVOVoidWater(id, pcode, regionp); break; | ||
147 | case LL_VO_WATER: | 150 | case LL_VO_WATER: |
148 | res = new LLVOWater(id, pcode, regionp); break; | 151 | res = new LLVOWater(id, pcode, regionp); break; |
149 | case LL_VO_GROUND: | 152 | case LL_VO_GROUND: |
diff --git a/linden/indra/newview/llviewerobject.h b/linden/indra/newview/llviewerobject.h index 7f8bd63..c443441 100644 --- a/linden/indra/newview/llviewerobject.h +++ b/linden/indra/newview/llviewerobject.h | |||
@@ -506,15 +506,16 @@ public: | |||
506 | { | 506 | { |
507 | LL_VO_CLOUDS = LL_PCODE_APP | 0x20, | 507 | LL_VO_CLOUDS = LL_PCODE_APP | 0x20, |
508 | LL_VO_SURFACE_PATCH = LL_PCODE_APP | 0x30, | 508 | LL_VO_SURFACE_PATCH = LL_PCODE_APP | 0x30, |
509 | //LL_VO_STARS = LL_PCODE_APP | 0x40, | 509 | LL_VO_WL_SKY = LL_PCODE_APP | 0x40, |
510 | LL_VO_SQUARE_TORUS = LL_PCODE_APP | 0x50, | 510 | LL_VO_SQUARE_TORUS = LL_PCODE_APP | 0x50, |
511 | LL_VO_SKY = LL_PCODE_APP | 0x60, | 511 | LL_VO_SKY = LL_PCODE_APP | 0x60, |
512 | LL_VO_WATER = LL_PCODE_APP | 0x70, | 512 | LL_VO_EDGE_WATER = LL_PCODE_APP | 0x70, |
513 | LL_VO_GROUND = LL_PCODE_APP | 0x80, | 513 | LL_VO_HOLE_WATER = LL_PCODE_APP | 0x80, |
514 | LL_VO_PART_GROUP = LL_PCODE_APP | 0x90, | 514 | LL_VO_WATER = LL_PCODE_APP | 0x90, |
515 | LL_VO_TRIANGLE_TORUS = LL_PCODE_APP | 0xa0, | 515 | LL_VO_GROUND = LL_PCODE_APP | 0xa0, |
516 | LL_VO_WL_SKY = LL_PCODE_APP | 0xb0, // should this be moved to 0x40? | 516 | LL_VO_PART_GROUP = LL_PCODE_APP | 0xb0, |
517 | LL_VO_HUD_PART_GROUP = LL_PCODE_APP | 0xc0, | 517 | LL_VO_TRIANGLE_TORUS = LL_PCODE_APP | 0xc0, |
518 | LL_VO_HUD_PART_GROUP = LL_PCODE_APP | 0xd0, | ||
518 | } EVOType; | 519 | } EVOType; |
519 | 520 | ||
520 | LLUUID mID; | 521 | LLUUID mID; |
@@ -713,8 +714,8 @@ public: | |||
713 | class LLStaticViewerObject : public LLViewerObject | 714 | class LLStaticViewerObject : public LLViewerObject |
714 | { | 715 | { |
715 | public: | 716 | public: |
716 | LLStaticViewerObject(const LLUUID& id, const LLPCode type, LLViewerRegion* regionp, BOOL is_global = FALSE) | 717 | LLStaticViewerObject(const LLUUID& id, const LLPCode pcode, LLViewerRegion* regionp, BOOL is_global = FALSE) |
717 | : LLViewerObject(id,type,regionp, is_global) | 718 | : LLViewerObject(id, pcode, regionp, is_global) |
718 | { } | 719 | { } |
719 | 720 | ||
720 | virtual void updateDrawable(BOOL force_damped); | 721 | virtual void updateDrawable(BOOL force_damped); |
diff --git a/linden/indra/newview/llviewerregion.cpp b/linden/indra/newview/llviewerregion.cpp index 4257f70..4fd3bfb 100644 --- a/linden/indra/newview/llviewerregion.cpp +++ b/linden/indra/newview/llviewerregion.cpp | |||
@@ -215,6 +215,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle, | |||
215 | //MUST MATCH declaration of eObjectPartitions | 215 | //MUST MATCH declaration of eObjectPartitions |
216 | mObjectPartition.push_back(new LLHUDPartition()); //PARTITION_HUD | 216 | mObjectPartition.push_back(new LLHUDPartition()); //PARTITION_HUD |
217 | mObjectPartition.push_back(new LLTerrainPartition()); //PARTITION_TERRAIN | 217 | mObjectPartition.push_back(new LLTerrainPartition()); //PARTITION_TERRAIN |
218 | mObjectPartition.push_back(new LLVoidWaterPartition()); //PARTITION_VOIDWATER | ||
218 | mObjectPartition.push_back(new LLWaterPartition()); //PARTITION_WATER | 219 | mObjectPartition.push_back(new LLWaterPartition()); //PARTITION_WATER |
219 | mObjectPartition.push_back(new LLTreePartition()); //PARTITION_TREE | 220 | mObjectPartition.push_back(new LLTreePartition()); //PARTITION_TREE |
220 | mObjectPartition.push_back(new LLParticlePartition()); //PARTITION_PARTICLE | 221 | mObjectPartition.push_back(new LLParticlePartition()); //PARTITION_PARTICLE |
diff --git a/linden/indra/newview/llviewerregion.h b/linden/indra/newview/llviewerregion.h index b0a98a9..09280a5 100644 --- a/linden/indra/newview/llviewerregion.h +++ b/linden/indra/newview/llviewerregion.h | |||
@@ -75,6 +75,7 @@ public: | |||
75 | { | 75 | { |
76 | PARTITION_HUD=0, | 76 | PARTITION_HUD=0, |
77 | PARTITION_TERRAIN, | 77 | PARTITION_TERRAIN, |
78 | PARTITION_VOIDWATER, | ||
78 | PARTITION_WATER, | 79 | PARTITION_WATER, |
79 | PARTITION_TREE, | 80 | PARTITION_TREE, |
80 | PARTITION_PARTICLE, | 81 | PARTITION_PARTICLE, |
diff --git a/linden/indra/newview/llviewerwindow.cpp b/linden/indra/newview/llviewerwindow.cpp index eb8977c..43a0d19 100644 --- a/linden/indra/newview/llviewerwindow.cpp +++ b/linden/indra/newview/llviewerwindow.cpp | |||
@@ -1303,6 +1303,11 @@ LLViewerWindow::LLViewerWindow( | |||
1303 | gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE); | 1303 | gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE); |
1304 | } | 1304 | } |
1305 | 1305 | ||
1306 | if (!gGLManager.mHasDepthClamp) | ||
1307 | { | ||
1308 | LL_INFOS("RenderInit") << "Missing feature GL_ARB_depth_clamp. Void water might disappear in rare cases." << LL_ENDL; | ||
1309 | } | ||
1310 | |||
1306 | // If we crashed while initializng GL stuff last time, disable certain features | 1311 | // If we crashed while initializng GL stuff last time, disable certain features |
1307 | if (gSavedSettings.getBOOL("RenderInitError")) | 1312 | if (gSavedSettings.getBOOL("RenderInitError")) |
1308 | { | 1313 | { |
diff --git a/linden/indra/newview/llvosurfacepatch.cpp b/linden/indra/newview/llvosurfacepatch.cpp index d86f758..1671880 100644 --- a/linden/indra/newview/llvosurfacepatch.cpp +++ b/linden/indra/newview/llvosurfacepatch.cpp | |||
@@ -86,7 +86,7 @@ public: | |||
86 | //============================================================================ | 86 | //============================================================================ |
87 | 87 | ||
88 | LLVOSurfacePatch::LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) | 88 | LLVOSurfacePatch::LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) |
89 | : LLStaticViewerObject(id, LL_VO_SURFACE_PATCH, regionp), | 89 | : LLStaticViewerObject(id, pcode, regionp), |
90 | mDirtiedPatch(FALSE), | 90 | mDirtiedPatch(FALSE), |
91 | mPool(NULL), | 91 | mPool(NULL), |
92 | mBaseComp(0), | 92 | mBaseComp(0), |
diff --git a/linden/indra/newview/llvowater.cpp b/linden/indra/newview/llvowater.cpp index 5b6a949..7e9470a 100644 --- a/linden/indra/newview/llvowater.cpp +++ b/linden/indra/newview/llvowater.cpp | |||
@@ -70,17 +70,16 @@ const F32 WAVE_STEP_INV = (1. / WAVE_STEP); | |||
70 | 70 | ||
71 | 71 | ||
72 | LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) | 72 | LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) |
73 | : LLStaticViewerObject(id, LL_VO_WATER, regionp) | 73 | : LLStaticViewerObject(id, pcode, regionp) |
74 | { | 74 | { |
75 | // Terrain must draw during selection passes so it can block objects behind it. | 75 | // Terrain must draw during selection passes so it can block objects behind it. |
76 | mbCanSelect = FALSE; | 76 | mbCanSelect = FALSE; |
77 | setScale(LLVector3(256.f, 256.f, 0.f)); // Hack for setting scale for bounding boxes/visibility. | 77 | setScale(LLVector3(256.f, 256.f, 0.f)); // Hack for setting scale for bounding boxes/visibility. |
78 | 78 | ||
79 | mUseTexture = TRUE; | 79 | mUseTexture = TRUE; |
80 | mIsEdgePatch = FALSE; | 80 | mRenderType = LLPipeline::RENDER_TYPE_WATER; |
81 | } | 81 | } |
82 | 82 | ||
83 | |||
84 | void LLVOWater::markDead() | 83 | void LLVOWater::markDead() |
85 | { | 84 | { |
86 | LLViewerObject::markDead(); | 85 | LLViewerObject::markDead(); |
@@ -123,7 +122,7 @@ LLDrawable *LLVOWater::createDrawable(LLPipeline *pipeline) | |||
123 | { | 122 | { |
124 | pipeline->allocDrawable(this); | 123 | pipeline->allocDrawable(this); |
125 | mDrawable->setLit(FALSE); | 124 | mDrawable->setLit(FALSE); |
126 | mDrawable->setRenderType(LLPipeline::RENDER_TYPE_WATER); | 125 | mDrawable->setRenderType(mRenderType); |
127 | 126 | ||
128 | LLDrawPoolWater *pool = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER); | 127 | LLDrawPoolWater *pool = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER); |
129 | 128 | ||
@@ -254,11 +253,6 @@ void LLVOWater::setUseTexture(const BOOL use_texture) | |||
254 | mUseTexture = use_texture; | 253 | mUseTexture = use_texture; |
255 | } | 254 | } |
256 | 255 | ||
257 | void LLVOWater::setIsEdgePatch(const BOOL edge_patch) | ||
258 | { | ||
259 | mIsEdgePatch = edge_patch; | ||
260 | } | ||
261 | |||
262 | void LLVOWater::updateSpatialExtents(LLVector3 &newMin, LLVector3& newMax) | 256 | void LLVOWater::updateSpatialExtents(LLVector3 &newMin, LLVector3& newMax) |
263 | { | 257 | { |
264 | LLVector3 pos = getPositionAgent(); | 258 | LLVector3 pos = getPositionAgent(); |
@@ -271,8 +265,13 @@ void LLVOWater::updateSpatialExtents(LLVector3 &newMin, LLVector3& newMax) | |||
271 | } | 265 | } |
272 | 266 | ||
273 | U32 LLVOWater::getPartitionType() const | 267 | U32 LLVOWater::getPartitionType() const |
274 | { | 268 | { |
275 | return LLViewerRegion::PARTITION_WATER; | 269 | return LLViewerRegion::PARTITION_WATER; |
270 | } | ||
271 | |||
272 | U32 LLVOVoidWater::getPartitionType() const | ||
273 | { | ||
274 | return LLViewerRegion::PARTITION_VOIDWATER; | ||
276 | } | 275 | } |
277 | 276 | ||
278 | LLWaterPartition::LLWaterPartition() | 277 | LLWaterPartition::LLWaterPartition() |
@@ -283,3 +282,9 @@ LLWaterPartition::LLWaterPartition() | |||
283 | mDrawableType = LLPipeline::RENDER_TYPE_WATER; | 282 | mDrawableType = LLPipeline::RENDER_TYPE_WATER; |
284 | mPartitionType = LLViewerRegion::PARTITION_WATER; | 283 | mPartitionType = LLViewerRegion::PARTITION_WATER; |
285 | } | 284 | } |
285 | |||
286 | LLVoidWaterPartition::LLVoidWaterPartition() | ||
287 | { | ||
288 | mDrawableType = LLPipeline::RENDER_TYPE_VOIDWATER; | ||
289 | mPartitionType = LLViewerRegion::PARTITION_VOIDWATER; | ||
290 | } | ||
diff --git a/linden/indra/newview/llvowater.h b/linden/indra/newview/llvowater.h index 9c33e74..37480b6 100644 --- a/linden/indra/newview/llvowater.h +++ b/linden/indra/newview/llvowater.h | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include "llviewerobject.h" | 36 | #include "llviewerobject.h" |
37 | #include "llviewerimage.h" | 37 | #include "llviewerimage.h" |
38 | #include "pipeline.h" | ||
38 | #include "v2math.h" | 39 | #include "v2math.h" |
39 | 40 | ||
40 | const U32 N_RES = 16; //32 // number of subdivisions of wave tile | 41 | const U32 N_RES = 16; //32 // number of subdivisions of wave tile |
@@ -71,18 +72,29 @@ public: | |||
71 | /*virtual*/ void updateTextures(); | 72 | /*virtual*/ void updateTextures(); |
72 | /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area | 73 | /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area |
73 | 74 | ||
74 | virtual U32 getPartitionType() const; | 75 | /*virtual*/ U32 getPartitionType() const; |
75 | 76 | ||
76 | /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. | 77 | /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. |
77 | 78 | ||
78 | void setUseTexture(const BOOL use_texture); | 79 | void setUseTexture(const BOOL use_texture); |
79 | void setIsEdgePatch(const BOOL edge_patch); | ||
80 | BOOL getUseTexture() const { return mUseTexture; } | 80 | BOOL getUseTexture() const { return mUseTexture; } |
81 | BOOL getIsEdgePatch() const { return mIsEdgePatch; } | 81 | |
82 | bool isEdgeWater(void) const { return mPrimitiveCode == LL_VO_EDGE_WATER; } | ||
82 | 83 | ||
83 | protected: | 84 | protected: |
84 | BOOL mUseTexture; | 85 | BOOL mUseTexture; |
85 | BOOL mIsEdgePatch; | 86 | LLPipeline::LLRenderTypeMask mRenderType; |
87 | }; | ||
88 | |||
89 | class LLVOVoidWater : public LLVOWater | ||
90 | { | ||
91 | public: | ||
92 | LLVOVoidWater(LLUUID const& id, LLPCode pcode, LLViewerRegion* regionp) : LLVOWater(id, pcode, regionp) | ||
93 | { | ||
94 | mRenderType = LLPipeline::RENDER_TYPE_VOIDWATER; | ||
95 | } | ||
96 | |||
97 | /*virtual*/ U32 getPartitionType() const; | ||
86 | }; | 98 | }; |
87 | 99 | ||
88 | #endif // LL_VOSURFACEPATCH_H | 100 | #endif // LL_VOSURFACEPATCH_H |
diff --git a/linden/indra/newview/llworld.cpp b/linden/indra/newview/llworld.cpp index 90ab49b..5026808 100644 --- a/linden/indra/newview/llworld.cpp +++ b/linden/indra/newview/llworld.cpp | |||
@@ -61,6 +61,12 @@ | |||
61 | #include "llappviewer.h" // for do_disconnect() | 61 | #include "llappviewer.h" // for do_disconnect() |
62 | 62 | ||
63 | #include "hippoLimits.h" | 63 | #include "hippoLimits.h" |
64 | |||
65 | #include <deque> | ||
66 | #include <queue> | ||
67 | #include <map> | ||
68 | #include <cstring> | ||
69 | |||
64 | // | 70 | // |
65 | // Globals | 71 | // Globals |
66 | // | 72 | // |
@@ -810,10 +816,69 @@ F32 LLWorld::getLandFarClip() const | |||
810 | 816 | ||
811 | void LLWorld::setLandFarClip(const F32 far_clip) | 817 | void LLWorld::setLandFarClip(const F32 far_clip) |
812 | { | 818 | { |
819 | static S32 const rwidth = (S32)REGION_WIDTH_U32; | ||
820 | S32 const n1 = (llceil(mLandFarClip) - 1) / rwidth; | ||
821 | S32 const n2 = (llceil(far_clip) - 1) / rwidth; | ||
822 | bool need_water_objects_update = n1 != n2; | ||
823 | |||
813 | mLandFarClip = far_clip; | 824 | mLandFarClip = far_clip; |
825 | |||
826 | if (need_water_objects_update) | ||
827 | { | ||
828 | updateWaterObjects(); | ||
829 | } | ||
814 | } | 830 | } |
815 | 831 | ||
832 | // Some region that we're connected to, but not the one we're in, gave us | ||
833 | // a (possibly) new water height. Update it in our local copy. | ||
834 | void LLWorld::waterHeightRegionInfo(std::string const& sim_name, F32 water_height) | ||
835 | { | ||
836 | for (region_list_t::iterator iter = mRegionList.begin(); iter != mRegionList.end(); ++iter) | ||
837 | { | ||
838 | if ((*iter)->getName() == sim_name) | ||
839 | { | ||
840 | (*iter)->setWaterHeight(water_height); | ||
841 | break; | ||
842 | } | ||
843 | } | ||
844 | } | ||
816 | 845 | ||
846 | // There are three types of water objects: | ||
847 | // Region water objects: the water in a region. | ||
848 | // Hole water objects: water in the void but within current draw distance. | ||
849 | // Edge water objects: the water outside the draw distance, up till the horizon. | ||
850 | // | ||
851 | // For example: | ||
852 | // | ||
853 | // -----------------------horizon------------------------- | ||
854 | // | | | | | ||
855 | // | Edge Water | | | | ||
856 | // | | | | | ||
857 | // | | | | | ||
858 | // | | | | | ||
859 | // | | | | | ||
860 | // | | rwidth | | | ||
861 | // | | <-----> | | | ||
862 | // ------------------------------------------------------- | ||
863 | // | |Hole |other| | | | ||
864 | // | |Water|reg. | | | | ||
865 | // | |-----------------| | | ||
866 | // | |other|cur. |<--> | | | ||
867 | // | |reg. | reg.| \__|_ draw distance | | ||
868 | // | |-----------------| | | ||
869 | // | | | |<--->| | | ||
870 | // | | | | \__|_ range | | ||
871 | // ------------------------------------------------------- | ||
872 | // | |<----width------>|<--horizon ext.->| | ||
873 | // | | | | | ||
874 | // | | | | | ||
875 | // | | | | | ||
876 | // | | | | | ||
877 | // | | | | | ||
878 | // | | | | | ||
879 | // | | | | | ||
880 | // ------------------------------------------------------- | ||
881 | // | ||
817 | void LLWorld::updateWaterObjects() | 882 | void LLWorld::updateWaterObjects() |
818 | { | 883 | { |
819 | if (!gAgent.getRegion()) | 884 | if (!gAgent.getRegion()) |
@@ -826,128 +891,264 @@ void LLWorld::updateWaterObjects() | |||
826 | return; | 891 | return; |
827 | } | 892 | } |
828 | 893 | ||
829 | // First, determine the min and max "box" of water objects | 894 | // Region width in meters. |
830 | S32 min_x = 0; | 895 | S32 const rwidth = (S32)REGION_WIDTH_U32; |
831 | S32 min_y = 0; | 896 | |
832 | S32 max_x = 0; | 897 | // The distance we might see into the void |
833 | S32 max_y = 0; | 898 | // when standing on the edge of a region, in meters. |
899 | S32 const draw_distance = llceil(mLandFarClip); | ||
900 | |||
901 | // We can only have "holes" in the water (where there no region) if we | ||
902 | // can have existing regions around it. Taking into account that this | ||
903 | // code is only executed when we enter a region, and not when we walk | ||
904 | // around in it, we (only) need to take into account regions that fall | ||
905 | // within the draw_distance. | ||
906 | // | ||
907 | // Set 'range' to draw_distance, rounded up to the nearest multiple of rwidth. | ||
908 | S32 const nsims = (draw_distance + rwidth - 1) / rwidth; | ||
909 | S32 const range = nsims * rwidth; | ||
910 | |||
911 | // Get South-West corner of current region. | ||
912 | LLViewerRegion const* regionp = gAgent.getRegion(); | ||
834 | U32 region_x, region_y; | 913 | U32 region_x, region_y; |
835 | |||
836 | S32 rwidth = 256; | ||
837 | |||
838 | // We only want to fill in water for stuff that's near us, say, within 256 or 512m | ||
839 | S32 range = LLViewerCamera::getInstance()->getFar() > 256.f ? 512 : 256; | ||
840 | |||
841 | LLViewerRegion* regionp = gAgent.getRegion(); | ||
842 | from_region_handle(regionp->getHandle(), ®ion_x, ®ion_y); | 914 | from_region_handle(regionp->getHandle(), ®ion_x, ®ion_y); |
843 | 915 | ||
844 | min_x = (S32)region_x - range; | 916 | // The min. and max. coordinates of the South-West corners of the Hole water objects. |
845 | min_y = (S32)region_y - range; | 917 | S32 const min_x = (S32)region_x - range; |
846 | max_x = (S32)region_x + range; | 918 | S32 const min_y = (S32)region_y - range; |
847 | max_y = (S32)region_y + range; | 919 | S32 const max_x = (S32)region_x + range; |
920 | S32 const max_y = (S32)region_y + range; | ||
921 | |||
922 | // Attempt to determine a sensible water height for all the | ||
923 | // Hole Water objects. | ||
924 | // | ||
925 | // It make little sense to try to guess what the best water | ||
926 | // height should be when that isn't completely obvious: if it's | ||
927 | // impossible to satisfy every region's water height without | ||
928 | // getting a jump in the water height. | ||
929 | // | ||
930 | // In order to keep the reasoning simple, we assume something | ||
931 | // logical as a group of connected regions, where the coastline | ||
932 | // is at the outer edge. Anything more complex that would "break" | ||
933 | // under such an assumption would probably break anyway (would | ||
934 | // depend on terrain editing and existing mega prims, say, if | ||
935 | // anything would make sense at all). | ||
936 | // | ||
937 | // So, what we do is find all connected regions within the | ||
938 | // draw distance that border void, and then pick the lowest | ||
939 | // water height of those (coast) regions. | ||
940 | S32 const n = 2 * nsims + 1; | ||
941 | S32 const origin = nsims + nsims * n; | ||
942 | std::vector<F32> water_heights(n * n); | ||
943 | std::vector<U8> checked(n * n, 0); // index = nx + ny * n + origin; | ||
944 | U8 const region_bit = 1; | ||
945 | U8 const hole_bit = 2; | ||
946 | U8 const bordering_hole_bit = 4; | ||
947 | U8 const bordering_edge_bit = 8; | ||
948 | // Use the legacy waterheight for the Edge water in the case | ||
949 | // that we don't find any Hole water at all. | ||
950 | F32 water_height = DEFAULT_WATER_HEIGHT; | ||
951 | int max_count = 0; | ||
952 | LL_DEBUGS("WaterHeight") << "Current region: " << regionp->getName() << "; water height: " << regionp->getWaterHeight() << " m." << LL_ENDL; | ||
953 | std::map<S32, int> water_height_counts; | ||
954 | typedef std::queue<std::pair<S32, S32>, std::deque<std::pair<S32, S32> > > nxny_pairs_type; | ||
955 | nxny_pairs_type nxny_pairs; | ||
956 | nxny_pairs.push(nxny_pairs_type::value_type(0, 0)); | ||
957 | water_heights[origin] = regionp->getWaterHeight(); | ||
958 | checked[origin] = region_bit; | ||
959 | // For debugging purposes. | ||
960 | int number_of_connected_regions = 1; | ||
961 | int uninitialized_regions = 0; | ||
962 | int bordering_hole = 0; | ||
963 | int bordering_edge = 0; | ||
964 | while(!nxny_pairs.empty()) | ||
965 | { | ||
966 | S32 const nx = nxny_pairs.front().first; | ||
967 | S32 const ny = nxny_pairs.front().second; | ||
968 | LL_DEBUGS("WaterHeight") << "nx,ny = " << nx << "," << ny << LL_ENDL; | ||
969 | S32 const index = nx + ny * n + origin; | ||
970 | nxny_pairs.pop(); | ||
971 | for (S32 dir = 0; dir < 4; ++dir) | ||
972 | { | ||
973 | S32 const cnx = nx + gDirAxes[dir][0]; | ||
974 | S32 const cny = ny + gDirAxes[dir][1]; | ||
975 | LL_DEBUGS("WaterHeight") << "dir = " << dir << "; cnx,cny = " << cnx << "," << cny << LL_ENDL; | ||
976 | S32 const cindex = cnx + cny * n + origin; | ||
977 | bool is_hole = false; | ||
978 | bool is_edge = false; | ||
979 | LLViewerRegion* new_region_found = NULL; | ||
980 | if (cnx < -nsims || cnx > nsims || | ||
981 | cny < -nsims || cny > nsims) | ||
982 | { | ||
983 | LL_DEBUGS("WaterHeight") << " Edge Water!" << LL_ENDL; | ||
984 | // Bumped into Edge water object. | ||
985 | is_edge = true; | ||
986 | } | ||
987 | else if (checked[cindex]) | ||
988 | { | ||
989 | LL_DEBUGS("WaterHeight") << " Already checked before!" << LL_ENDL; | ||
990 | // Already checked. | ||
991 | is_hole = (checked[cindex] & hole_bit); | ||
992 | } | ||
993 | else | ||
994 | { | ||
995 | S32 x = (S32)region_x + cnx * rwidth; | ||
996 | S32 y = (S32)region_y + cny * rwidth; | ||
997 | U64 region_handle = to_region_handle(x, y); | ||
998 | new_region_found = getRegionFromHandle(region_handle); | ||
999 | is_hole = !new_region_found; | ||
1000 | checked[cindex] = is_hole ? hole_bit : region_bit; | ||
1001 | } | ||
1002 | if (is_hole) | ||
1003 | { | ||
1004 | // This was a region that borders at least one 'hole'. | ||
1005 | // Count the found coastline. | ||
1006 | F32 new_water_height = water_heights[index]; | ||
1007 | LL_DEBUGS("WaterHeight") << " This is void; counting coastline with water height of " << new_water_height << LL_ENDL; | ||
1008 | S32 new_water_height_cm = llround(new_water_height * 100); | ||
1009 | int count = (water_height_counts[new_water_height_cm] += 1); | ||
1010 | // Just use the lowest water height: this is mainly about the horizon water, | ||
1011 | // and whatever we do, we don't want it to be possible to look under the water | ||
1012 | // when looking in the distance: it is better to make a step downwards in water | ||
1013 | // height when going away from the avie than a step upwards. However, since | ||
1014 | // everyone is used to DEFAULT_WATER_HEIGHT, don't allow a single region | ||
1015 | // to drag the water level below DEFAULT_WATER_HEIGHT on it's own. | ||
1016 | if (bordering_hole == 0 || // First time we get here. | ||
1017 | (new_water_height >= DEFAULT_WATER_HEIGHT && | ||
1018 | new_water_height < water_height) || | ||
1019 | (new_water_height < DEFAULT_WATER_HEIGHT && | ||
1020 | count > max_count) | ||
1021 | ) | ||
1022 | { | ||
1023 | water_height = new_water_height; | ||
1024 | } | ||
1025 | if (count > max_count) | ||
1026 | { | ||
1027 | max_count = count; | ||
1028 | } | ||
1029 | if (!(checked[index] & bordering_hole_bit)) | ||
1030 | { | ||
1031 | checked[index] |= bordering_hole_bit; | ||
1032 | ++bordering_hole; | ||
1033 | } | ||
1034 | } | ||
1035 | else if (is_edge && !(checked[index] & bordering_edge_bit)) | ||
1036 | { | ||
1037 | checked[index] |= bordering_edge_bit; | ||
1038 | ++bordering_edge; | ||
1039 | } | ||
1040 | if (!new_region_found) | ||
1041 | { | ||
1042 | // Dead end, there is no region here. | ||
1043 | continue; | ||
1044 | } | ||
1045 | // Found a new connected region. | ||
1046 | ++number_of_connected_regions; | ||
1047 | if (new_region_found->getName().empty()) | ||
1048 | { | ||
1049 | // Uninitialized LLViewerRegion, don't use it's water height. | ||
1050 | LL_DEBUGS("WaterHeight") << " Uninitialized region." << LL_ENDL; | ||
1051 | ++uninitialized_regions; | ||
1052 | continue; | ||
1053 | } | ||
1054 | nxny_pairs.push(nxny_pairs_type::value_type(cnx, cny)); | ||
1055 | water_heights[cindex] = new_region_found->getWaterHeight(); | ||
1056 | LL_DEBUGS("WaterHeight") << " Found a new region (name: " << new_region_found->getName() << "; water height: " << water_heights[cindex] << " m)!" << LL_ENDL; | ||
1057 | } | ||
1058 | } | ||
1059 | llinfos << "Number of connected regions: " << number_of_connected_regions << " (" << uninitialized_regions << | ||
1060 | " uninitialized); number of regions bordering Hole water: " << bordering_hole << | ||
1061 | "; number of regions bordering Edge water: " << bordering_edge << llendl; | ||
1062 | llinfos << "Coastline count (height, count): "; | ||
1063 | bool first = true; | ||
1064 | for (std::map<S32, int>::iterator iter = water_height_counts.begin(); iter != water_height_counts.end(); ++iter) | ||
1065 | { | ||
1066 | if (!first) llcont << ", "; | ||
1067 | llcont << "(" << (iter->first / 100.f) << ", " << iter->second << ")"; | ||
1068 | first = false; | ||
1069 | } | ||
1070 | llcont << llendl; | ||
1071 | llinfos << "Water height used for Hole and Edge water objects: " << water_height << llendl; | ||
848 | 1072 | ||
849 | F32 height = 0.f; | 1073 | // Update all Region water objects. |
850 | 1074 | for (region_list_t::iterator iter = mRegionList.begin(); iter != mRegionList.end(); ++iter) | |
851 | for (region_list_t::iterator iter = mRegionList.begin(); | ||
852 | iter != mRegionList.end(); ++iter) | ||
853 | { | 1075 | { |
854 | LLViewerRegion* regionp = *iter; | 1076 | LLViewerRegion* regionp = *iter; |
855 | LLVOWater* waterp = regionp->getLand().getWaterObj(); | 1077 | LLVOWater* waterp = regionp->getLand().getWaterObj(); |
856 | height += regionp->getWaterHeight(); | ||
857 | if (waterp) | 1078 | if (waterp) |
858 | { | 1079 | { |
859 | gObjectList.updateActive(waterp); | 1080 | gObjectList.updateActive(waterp); |
860 | } | 1081 | } |
861 | } | 1082 | } |
862 | 1083 | ||
1084 | // Clean up all existing Hole water objects. | ||
863 | for (std::list<LLVOWater*>::iterator iter = mHoleWaterObjects.begin(); | 1085 | for (std::list<LLVOWater*>::iterator iter = mHoleWaterObjects.begin(); |
864 | iter != mHoleWaterObjects.end(); ++ iter) | 1086 | iter != mHoleWaterObjects.end(); ++iter) |
865 | { | 1087 | { |
866 | LLVOWater* waterp = *iter; | 1088 | LLVOWater* waterp = *iter; |
867 | gObjectList.killObject(waterp); | 1089 | gObjectList.killObject(waterp); |
868 | } | 1090 | } |
869 | mHoleWaterObjects.clear(); | 1091 | mHoleWaterObjects.clear(); |
870 | 1092 | ||
871 | // Now, get a list of the holes | 1093 | // Let the Edge and Hole water boxes be 1024 meter high so that they |
872 | S32 x, y; | 1094 | // are never too small to be drawn (A LL_VO_*_WATER box has water |
873 | for (x = min_x; x <= max_x; x += rwidth) | 1095 | // rendered on it's bottom surface only), and put their bottom at |
1096 | // the current regions water height. | ||
1097 | F32 const box_height = 1024; | ||
1098 | F32 const water_center_z = water_height + box_height / 2; | ||
1099 | |||
1100 | // Create new Hole water objects within 'range' where there is no region. | ||
1101 | for (S32 x = min_x; x <= max_x; x += rwidth) | ||
874 | { | 1102 | { |
875 | for (y = min_y; y <= max_y; y += rwidth) | 1103 | for (S32 y = min_y; y <= max_y; y += rwidth) |
876 | { | 1104 | { |
877 | U64 region_handle = to_region_handle(x, y); | 1105 | U64 region_handle = to_region_handle(x, y); |
878 | if (!getRegionFromHandle(region_handle)) | 1106 | if (!getRegionFromHandle(region_handle)) |
879 | { | 1107 | { |
880 | LLVOWater* waterp = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, gAgent.getRegion()); | 1108 | LLVOWater* waterp = (LLVOWater*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_HOLE_WATER, gAgent.getRegion()); |
881 | waterp->setUseTexture(FALSE); | 1109 | waterp->setUseTexture(FALSE); |
882 | waterp->setPositionGlobal(LLVector3d(x + rwidth/2, | 1110 | waterp->setPositionGlobal(LLVector3d(x + rwidth / 2, y + rwidth / 2, water_center_z)); |
883 | y + rwidth/2, | 1111 | waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, box_height)); |
884 | 256.f+DEFAULT_WATER_HEIGHT)); | ||
885 | waterp->setScale(LLVector3((F32)rwidth, (F32)rwidth, 512.f)); | ||
886 | gPipeline.createObject(waterp); | 1112 | gPipeline.createObject(waterp); |
887 | mHoleWaterObjects.push_back(waterp); | 1113 | mHoleWaterObjects.push_back(waterp); |
888 | } | 1114 | } |
889 | } | 1115 | } |
890 | } | 1116 | } |
891 | 1117 | ||
892 | // Update edge water objects | 1118 | // Center of the region. |
893 | S32 wx, wy; | 1119 | S32 const center_x = region_x + rwidth / 2; |
894 | S32 center_x, center_y; | 1120 | S32 const center_y = region_y + rwidth / 2; |
895 | wx = (max_x - min_x) + rwidth; | 1121 | // Width of the area with Hole water objects. |
896 | wy = (max_y - min_y) + rwidth; | 1122 | S32 const width = rwidth + 2 * range; |
897 | center_x = min_x + (wx >> 1); | 1123 | S32 const horizon_extend = 2048 + 512 - range; // Legacy value. |
898 | center_y = min_y + (wy >> 1); | 1124 | // The overlap is needed to get rid of sky pixels being visible between the |
899 | 1125 | // Edge and Hole water object at greater distances (due to floating point | |
900 | S32 add_boundary[4] = { | 1126 | // round off errors). |
901 | 512 - (max_x - region_x), | 1127 | S32 const edge_hole_overlap = 1; // Twice the actual overlap. |
902 | 512 - (max_y - region_y), | 1128 | |
903 | 512 - (region_x - min_x), | 1129 | for (S32 dir = 0; dir < 8; ++dir) |
904 | 512 - (region_y - min_y) }; | ||
905 | |||
906 | S32 dir; | ||
907 | for (dir = 0; dir < 8; dir++) | ||
908 | { | 1130 | { |
909 | S32 dim[2] = { 0 }; | 1131 | // Size of the Edge water objects. |
910 | switch (gDirAxes[dir][0]) | 1132 | S32 const dim_x = (gDirAxes[dir][0] == 0) ? width : (horizon_extend + edge_hole_overlap); |
911 | { | 1133 | S32 const dim_y = (gDirAxes[dir][1] == 0) ? width : (horizon_extend + edge_hole_overlap); |
912 | case -1: dim[0] = add_boundary[2]; break; | 1134 | // And their position. |
913 | case 0: dim[0] = wx; break; | 1135 | S32 const water_center_x = center_x + (width + horizon_extend) / 2 * gDirAxes[dir][0]; |
914 | default: dim[0] = add_boundary[0]; break; | 1136 | S32 const water_center_y = center_y + (width + horizon_extend) / 2 * gDirAxes[dir][1]; |
915 | } | ||
916 | switch (gDirAxes[dir][1]) | ||
917 | { | ||
918 | case -1: dim[1] = add_boundary[3]; break; | ||
919 | case 0: dim[1] = wy; break; | ||
920 | default: dim[1] = add_boundary[1]; break; | ||
921 | } | ||
922 | 1137 | ||
923 | // Resize and reshape the water objects | ||
924 | const S32 water_center_x = center_x + llround((wx + dim[0]) * 0.5f * gDirAxes[dir][0]); | ||
925 | const S32 water_center_y = center_y + llround((wy + dim[1]) * 0.5f * gDirAxes[dir][1]); | ||
926 | |||
927 | LLVOWater* waterp = mEdgeWaterObjects[dir]; | 1138 | LLVOWater* waterp = mEdgeWaterObjects[dir]; |
928 | if (!waterp || waterp->isDead()) | 1139 | if (!waterp || waterp->isDead()) |
929 | { | 1140 | { |
930 | // The edge water objects can be dead because they're attached to the region that the | 1141 | // The edge water objects can be dead because they're attached to the region that the |
931 | // agent was in when they were originally created. | 1142 | // agent was in when they were originally created. |
932 | mEdgeWaterObjects[dir] = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_WATER, | 1143 | mEdgeWaterObjects[dir] = (LLVOWater *)gObjectList.createObjectViewer(LLViewerObject::LL_VO_EDGE_WATER, gAgent.getRegion()); |
933 | gAgent.getRegion()); | ||
934 | waterp = mEdgeWaterObjects[dir]; | 1144 | waterp = mEdgeWaterObjects[dir]; |
935 | waterp->setUseTexture(FALSE); | 1145 | waterp->setUseTexture(FALSE); |
936 | waterp->setIsEdgePatch(TRUE); | ||
937 | gPipeline.createObject(waterp); | 1146 | gPipeline.createObject(waterp); |
938 | } | 1147 | } |
939 | 1148 | ||
940 | waterp->setRegion(gAgent.getRegion()); | 1149 | waterp->setRegion(gAgent.getRegion()); |
941 | LLVector3d water_pos(water_center_x, water_center_y, | 1150 | LLVector3d water_pos(water_center_x, water_center_y, water_center_z); |
942 | DEFAULT_WATER_HEIGHT+256.f); | 1151 | LLVector3 water_scale((F32) dim_x, (F32) dim_y, box_height); |
943 | LLVector3 water_scale((F32) dim[0], (F32) dim[1], 512.f); | ||
944 | |||
945 | //stretch out to horizon | ||
946 | water_scale.mV[0] += fabsf(2048.f * gDirAxes[dir][0]); | ||
947 | water_scale.mV[1] += fabsf(2048.f * gDirAxes[dir][1]); | ||
948 | |||
949 | water_pos.mdV[0] += 1024.f * gDirAxes[dir][0]; | ||
950 | water_pos.mdV[1] += 1024.f * gDirAxes[dir][1]; | ||
951 | 1152 | ||
952 | waterp->setPositionGlobal(water_pos); | 1153 | waterp->setPositionGlobal(water_pos); |
953 | waterp->setScale(water_scale); | 1154 | waterp->setScale(water_scale); |
diff --git a/linden/indra/newview/llworld.h b/linden/indra/newview/llworld.h index 46aefd9..2c5815c 100644 --- a/linden/indra/newview/llworld.h +++ b/linden/indra/newview/llworld.h | |||
@@ -142,6 +142,7 @@ public: | |||
142 | 142 | ||
143 | LLViewerImage *getDefaultWaterTexture(); | 143 | LLViewerImage *getDefaultWaterTexture(); |
144 | void updateWaterObjects(); | 144 | void updateWaterObjects(); |
145 | void waterHeightRegionInfo(std::string const& sim_name, F32 water_height); | ||
145 | void shiftRegions(const LLVector3& offset); | 146 | void shiftRegions(const LLVector3& offset); |
146 | 147 | ||
147 | void setSpaceTimeUSec(const U64 space_time_usec); | 148 | void setSpaceTimeUSec(const U64 space_time_usec); |
diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index f10aca5..e024e4c 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp | |||
@@ -1833,11 +1833,12 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f | |||
1833 | void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) | 1833 | void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) |
1834 | { | 1834 | { |
1835 | const U32 face_mask = (1 << LLPipeline::RENDER_TYPE_AVATAR) | | 1835 | const U32 face_mask = (1 << LLPipeline::RENDER_TYPE_AVATAR) | |
1836 | (1 << LLPipeline::RENDER_TYPE_GROUND) | | 1836 | (1 << LLPipeline::RENDER_TYPE_GROUND) | |
1837 | (1 << LLPipeline::RENDER_TYPE_TERRAIN) | | 1837 | (1 << LLPipeline::RENDER_TYPE_TERRAIN) | |
1838 | (1 << LLPipeline::RENDER_TYPE_TREE) | | 1838 | (1 << LLPipeline::RENDER_TYPE_TREE) | |
1839 | (1 << LLPipeline::RENDER_TYPE_SKY) | | 1839 | (1 << LLPipeline::RENDER_TYPE_SKY) | |
1840 | (1 << LLPipeline::RENDER_TYPE_WATER); | 1840 | (1 << LLPipeline::RENDER_TYPE_VOIDWATER) | |
1841 | (1 << LLPipeline::RENDER_TYPE_WATER); | ||
1841 | 1842 | ||
1842 | if (mRenderTypeMask & face_mask) | 1843 | if (mRenderTypeMask & face_mask) |
1843 | { | 1844 | { |
@@ -4436,6 +4437,11 @@ void LLPipeline::toggleRenderType(U32 type) | |||
4436 | { | 4437 | { |
4437 | U32 bit = (1<<type); | 4438 | U32 bit = (1<<type); |
4438 | gPipeline.mRenderTypeMask ^= bit; | 4439 | gPipeline.mRenderTypeMask ^= bit; |
4440 | if (type == RENDER_TYPE_WATER) | ||
4441 | { | ||
4442 | bit = (1 << RENDER_TYPE_VOIDWATER); | ||
4443 | gPipeline.mRenderTypeMask ^= bit; | ||
4444 | } | ||
4439 | } | 4445 | } |
4440 | 4446 | ||
4441 | //static | 4447 | //static |
@@ -5744,18 +5750,19 @@ void LLPipeline::renderDeferredLighting() | |||
5744 | LLGLDisable stencil(GL_STENCIL_TEST); | 5750 | LLGLDisable stencil(GL_STENCIL_TEST); |
5745 | 5751 | ||
5746 | U32 render_mask = mRenderTypeMask; | 5752 | U32 render_mask = mRenderTypeMask; |
5747 | mRenderTypeMask = mRenderTypeMask & | 5753 | mRenderTypeMask = mRenderTypeMask & |
5748 | ((1 << LLPipeline::RENDER_TYPE_SKY) | | 5754 | ((1 << LLPipeline::RENDER_TYPE_SKY) | |
5749 | (1 << LLPipeline::RENDER_TYPE_CLOUDS) | | 5755 | (1 << LLPipeline::RENDER_TYPE_CLOUDS) | |
5750 | (1 << LLPipeline::RENDER_TYPE_WL_SKY) | | 5756 | (1 << LLPipeline::RENDER_TYPE_WL_SKY) | |
5751 | (1 << LLPipeline::RENDER_TYPE_ALPHA) | | 5757 | (1 << LLPipeline::RENDER_TYPE_ALPHA) | |
5752 | (1 << LLPipeline::RENDER_TYPE_AVATAR) | | 5758 | (1 << LLPipeline::RENDER_TYPE_AVATAR) | |
5753 | (1 << LLPipeline::RENDER_TYPE_WATER) | | 5759 | (1 << LLPipeline::RENDER_TYPE_VOIDWATER) | |
5754 | (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) | | 5760 | (1 << LLPipeline::RENDER_TYPE_WATER) | |
5755 | (1 << LLPipeline::RENDER_TYPE_VOLUME) | | 5761 | (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) | |
5756 | (1 << LLPipeline::RENDER_TYPE_GLOW) | | 5762 | (1 << LLPipeline::RENDER_TYPE_VOLUME) | |
5757 | (1 << LLPipeline::RENDER_TYPE_BUMP)); | 5763 | (1 << LLPipeline::RENDER_TYPE_GLOW) | |
5758 | 5764 | (1 << LLPipeline::RENDER_TYPE_BUMP)); | |
5765 | |||
5759 | renderGeomPostDeferred(*LLViewerCamera::getInstance()); | 5766 | renderGeomPostDeferred(*LLViewerCamera::getInstance()); |
5760 | mRenderTypeMask = render_mask; | 5767 | mRenderTypeMask = render_mask; |
5761 | } | 5768 | } |
@@ -5910,10 +5917,11 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) | |||
5910 | 5917 | ||
5911 | if (LLDrawPoolWater::sNeedsDistortionUpdate) | 5918 | if (LLDrawPoolWater::sNeedsDistortionUpdate) |
5912 | { | 5919 | { |
5913 | mRenderTypeMask &= ~((1<<LLPipeline::RENDER_TYPE_WATER) | | 5920 | mRenderTypeMask &= ~((1<<LLPipeline::RENDER_TYPE_WATER) | |
5914 | (1<<LLPipeline::RENDER_TYPE_GROUND) | | 5921 | (1<<LLPipeline::RENDER_TYPE_VOIDWATER) | |
5915 | (1<<LLPipeline::RENDER_TYPE_SKY) | | 5922 | (1<<LLPipeline::RENDER_TYPE_GROUND) | |
5916 | (1<<LLPipeline::RENDER_TYPE_CLOUDS)); | 5923 | (1<<LLPipeline::RENDER_TYPE_SKY) | |
5924 | (1<<LLPipeline::RENDER_TYPE_CLOUDS)); | ||
5917 | 5925 | ||
5918 | if (gSavedSettings.getBOOL("RenderWaterReflections")) | 5926 | if (gSavedSettings.getBOOL("RenderWaterReflections")) |
5919 | { //mask out selected geometry based on reflection detail | 5927 | { //mask out selected geometry based on reflection detail |
@@ -5955,8 +5963,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) | |||
5955 | if (last_update) | 5963 | if (last_update) |
5956 | { | 5964 | { |
5957 | camera.setFar(camera_in.getFar()); | 5965 | camera.setFar(camera_in.getFar()); |
5958 | mRenderTypeMask = type_mask & (~(1<<LLPipeline::RENDER_TYPE_WATER) | | 5966 | mRenderTypeMask = type_mask & ~((1<<LLPipeline::RENDER_TYPE_WATER) | |
5959 | (1<<LLPipeline::RENDER_TYPE_GROUND)); | 5967 | (1<<LLPipeline::RENDER_TYPE_VOIDWATER) | |
5968 | (1<<LLPipeline::RENDER_TYPE_GROUND)); | ||
5960 | stop_glerror(); | 5969 | stop_glerror(); |
5961 | 5970 | ||
5962 | LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? FALSE : TRUE; | 5971 | LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? FALSE : TRUE; |
diff --git a/linden/indra/newview/pipeline.h b/linden/indra/newview/pipeline.h index 1a32b30..3f3309a 100644 --- a/linden/indra/newview/pipeline.h +++ b/linden/indra/newview/pipeline.h | |||
@@ -314,8 +314,9 @@ public: | |||
314 | RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR, | 314 | RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR, |
315 | RENDER_TYPE_TREE = LLDrawPool::POOL_TREE, | 315 | RENDER_TYPE_TREE = LLDrawPool::POOL_TREE, |
316 | RENDER_TYPE_INVISIBLE = LLDrawPool::POOL_INVISIBLE, | 316 | RENDER_TYPE_INVISIBLE = LLDrawPool::POOL_INVISIBLE, |
317 | RENDER_TYPE_VOIDWATER = LLDrawPool::POOL_VOIDWATER, | ||
317 | RENDER_TYPE_WATER = LLDrawPool::POOL_WATER, | 318 | RENDER_TYPE_WATER = LLDrawPool::POOL_WATER, |
318 | RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA, | 319 | RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA, |
319 | RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW, | 320 | RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW, |
320 | 321 | ||
321 | // Following are object types (only used in drawable mRenderType) | 322 | // Following are object types (only used in drawable mRenderType) |