aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/lldrawpoolwater.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/lldrawpoolwater.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/lldrawpoolwater.cpp')
-rw-r--r--linden/indra/newview/lldrawpoolwater.cpp748
1 files changed, 748 insertions, 0 deletions
diff --git a/linden/indra/newview/lldrawpoolwater.cpp b/linden/indra/newview/lldrawpoolwater.cpp
new file mode 100644
index 0000000..e3802a1
--- /dev/null
+++ b/linden/indra/newview/lldrawpoolwater.cpp
@@ -0,0 +1,748 @@
1/**
2 * @file lldrawpoolwater.cpp
3 * @brief LLDrawPoolWater class implementation
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "llviewerprecompiledheaders.h"
29#include "llfeaturemanager.h"
30#include "lldrawpoolwater.h"
31
32#include "llviewercontrol.h"
33#include "lldir.h"
34#include "llerror.h"
35#include "m3math.h"
36
37#include "llagent.h" // for gAgent for getRegion for getWaterHeight
38#include "llagparray.h"
39#include "llcubemap.h"
40#include "lldrawable.h"
41#include "llface.h"
42#include "llsky.h"
43#include "llviewercamera.h" // to get OGL_TO_CFR_ROTATION
44#include "llviewerimagelist.h"
45#include "llviewerregion.h"
46#include "llvosky.h"
47#include "llvowater.h"
48#include "llworld.h"
49#include "pipeline.h"
50#include "viewer.h" // gSunTextureID, gMoonTextureID
51
52const LLUUID WATER_TEST("2bfd3884-7e27-69b9-ba3a-3e673f680004");
53
54static float sTime;
55
56int nhpo2(int v)
57{
58 int r = 1;
59 while (r < v) {
60 r *= 2;
61 }
62 return r;
63}
64
65static GLuint sScreenTex = 0;
66
67LLDrawPoolWater::LLDrawPoolWater() :
68 LLDrawPool(POOL_WATER, DATA_SIMPLE_IL_MASK, DATA_SIMPLE_NIL_MASK)
69{
70 mCleanupUnused = TRUE;
71 mHBTex[0] = gImageList.getImage(gSunTextureID, TRUE, TRUE);
72 mHBTex[0]->bind();
73 mHBTex[0]->setClamp(TRUE, TRUE);
74
75 mHBTex[1] = gImageList.getImage(gMoonTextureID, TRUE, TRUE);
76 mHBTex[1]->bind();
77 mHBTex[1]->setClamp(TRUE, TRUE);
78
79 mWaterImagep = gImageList.getImage(WATER_TEST);
80 mWaterNormp = gImageList.getImage(LLUUID(gViewerArt.getString("water_normal.tga")));
81
82 restoreGL();
83}
84
85LLDrawPoolWater::~LLDrawPoolWater()
86{
87}
88
89//static
90void LLDrawPoolWater::restoreGL()
91{
92 if (gPipeline.getVertexShaderLevel(LLPipeline::SHADER_ENVIRONMENT) >= SHADER_LEVEL_RIPPLE)
93 {
94 //build screen texture
95 glClientActiveTextureARB(GL_TEXTURE0_ARB);
96 glActiveTextureARB(GL_TEXTURE0_ARB);
97 glGenTextures(1, &sScreenTex);
98 LLGLEnable gl_texture_2d(GL_TEXTURE_2D);
99 glBindTexture(GL_TEXTURE_2D, sScreenTex);
100 GLint viewport[4];
101 glGetIntegerv(GL_VIEWPORT, viewport);
102 GLuint resX = nhpo2(viewport[2]);
103 GLuint resY = nhpo2(viewport[3]);
104
105 gImageList.updateMaxResidentTexMem(-1, resX*resY*3);
106 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, resX, resY, 0, GL_RGB, GL_FLOAT, NULL);
107
108 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
109 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
111 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
112 }
113}
114
115
116LLDrawPool *LLDrawPoolWater::instancePool()
117{
118 llerrs << "Should never be calling instancePool on a water pool!" << llendl;
119 return NULL;
120}
121
122
123void LLDrawPoolWater::prerender()
124{
125#if 1 // 1.9.1
126 mVertexShaderLevel = gSavedSettings.getBOOL("RenderRippleWater") ?
127 gPipeline.getVertexShaderLevel(LLPipeline::SHADER_ENVIRONMENT) : 0;
128#else
129 mVertexShaderLevel = gPipeline.getVertexShaderLevel(LLPipeline::SHADER_ENVIRONMENT);
130#endif
131}
132
133extern LLColor4U MAX_WATER_COLOR;
134
135void LLDrawPoolWater::render(S32 pass)
136{
137 LLFastTimer ftm(LLFastTimer::FTM_RENDER_WATER);
138 if (mDrawFace.empty())
139 {
140 return;
141 }
142
143 LLGLSPipelineAlpha alphaState;
144
145 if ((mVertexShaderLevel >= SHADER_LEVEL_RIPPLE))
146 {
147 shade();
148 return;
149 }
150
151 if ((mVertexShaderLevel > 0))
152 {
153 renderShaderSimple();
154 return;
155 }
156
157 LLVOSky *voskyp = gSky.mVOSkyp;
158
159 stop_glerror();
160
161 if (!gGLManager.mHasMultitexture)
162 {
163 // Ack! No multitexture! Bail!
164 return;
165 }
166
167 const LLFace* refl_face = voskyp->getReflFace();
168
169 gPipeline.disableLights();
170
171 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
172
173 LLGLDisable cullFace(GL_CULL_FACE);
174
175 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
176 glEnableClientState(GL_VERTEX_ARRAY);
177 glEnableClientState(GL_NORMAL_ARRAY);
178
179 bindGLVertexPointer();
180 bindGLNormalPointer();
181 bindGLTexCoordPointer();
182
183 // Set up second pass first
184 glActiveTextureARB(GL_TEXTURE1_ARB);
185 mWaterImagep->addTextureStats(1024.f*1024.f);
186 mWaterImagep->bind(1);
187
188 glClientActiveTextureARB(GL_TEXTURE1_ARB);
189 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
190 glEnable(GL_TEXTURE_2D); // Texture unit 1
191
192 LLVector3 camera_up = gCamera->getUpAxis();
193 F32 up_dot = camera_up * LLVector3::z_axis;
194
195 LLColor4 water_color;
196 if (gCamera->cameraUnderWater())
197 {
198 water_color.setVec(1.f, 1.f, 1.f, 0.4f);
199 }
200 else
201 {
202 water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
203 }
204
205 glColor4fv(water_color.mV);
206
207 // Automatically generate texture coords for detail map
208 glEnable(GL_TEXTURE_GEN_S); //texture unit 1
209 glEnable(GL_TEXTURE_GEN_T); //texture unit 1
210 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
211 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
212
213 // Slowly move over time.
214 F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f);
215 F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f};
216 F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f};
217 glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
218 glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
219
220 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
221 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE);
222 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
223
224 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
225 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
226 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
227 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
228 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
229 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
230
231 glClientActiveTextureARB(GL_TEXTURE0_ARB);
232 glActiveTextureARB(GL_TEXTURE0_ARB);
233
234 glClearStencil(1);
235 glClear(GL_STENCIL_BUFFER_BIT);
236 LLGLEnable gls_stencil(GL_STENCIL_TEST);
237 glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
238 glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
239
240 for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
241 iter != mDrawFace.end(); iter++)
242 {
243 LLFace *face = *iter;
244 if (voskyp->isReflFace(face))
245 {
246 continue;
247 }
248 face->bindTexture();
249 face->renderIndexed(getRawIndices());
250 mIndicesDrawn += face->getIndicesCount();
251 }
252
253 // Now, disable texture coord generation on texture state 1
254 glClientActiveTextureARB(GL_TEXTURE1_ARB);
255 glActiveTextureARB(GL_TEXTURE1_ARB);
256 glDisable(GL_TEXTURE_2D); // Texture unit 1
257 LLImageGL::unbindTexture(1, GL_TEXTURE_2D);
258 glDisable(GL_TEXTURE_GEN_S); //texture unit 1
259 glDisable(GL_TEXTURE_GEN_T); //texture unit 1
260
261 // Disable texture coordinate and color arrays
262 glClientActiveTextureARB(GL_TEXTURE0_ARB);
263 glActiveTextureARB(GL_TEXTURE0_ARB);
264 LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
265
266 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
267 stop_glerror();
268
269 if (gSky.mVOSkyp->getCubeMap())
270 {
271 gSky.mVOSkyp->getCubeMap()->enable(0);
272 gSky.mVOSkyp->getCubeMap()->bind();
273
274 glMatrixMode(GL_TEXTURE);
275 glLoadIdentity();
276 LLMatrix4 camera_mat = gCamera->getModelview();
277 LLMatrix4 camera_rot(camera_mat.getMat3());
278 camera_rot.invert();
279
280 glLoadMatrixf((F32 *)camera_rot.mMatrix);
281
282 glMatrixMode(GL_MODELVIEW);
283 LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f, 0.5f*up_dot);
284
285 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
286
287 /*glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
288 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD);
289 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_REPLACE);
290
291 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
292 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
293 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
294 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
295 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS_ARB);
296 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);*/
297
298 for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
299 iter != mDrawFace.end(); iter++)
300 {
301 LLFace *face = *iter;
302 if (voskyp->isReflFace(face))
303 {
304 //refl_face = face;
305 continue;
306 }
307
308 if (face->getGeomCount() > 0)
309 {
310 face->renderIndexed(getRawIndices());
311 mIndicesDrawn += face->getIndicesCount();
312 }
313 }
314
315 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
316
317 if (gSky.mVOSkyp->getCubeMap())
318 {
319 gSky.mVOSkyp->getCubeMap()->disable();
320 }
321 LLImageGL::unbindTexture(0, GL_TEXTURE_2D);
322 glEnable(GL_TEXTURE_2D);
323 glMatrixMode(GL_TEXTURE);
324 glLoadIdentity();
325 glMatrixMode(GL_MODELVIEW);
326
327 }
328
329 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
330
331 if (refl_face)
332 {
333 glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
334 renderReflection(refl_face);
335 }
336
337 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
338 glDisableClientState(GL_NORMAL_ARRAY);
339
340 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
341
342}
343
344
345void LLDrawPoolWater::renderShaderSimple()
346{
347 LLVOSky *voskyp = gSky.mVOSkyp;
348
349 stop_glerror();
350
351 if (!gGLManager.mHasMultitexture)
352 {
353 // Ack! No multitexture! Bail!
354 return;
355 }
356
357 const LLFace* refl_face = voskyp->getReflFace();
358
359 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
360
361 LLGLDisable cullFace(GL_CULL_FACE);
362
363 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
364 glEnableClientState(GL_VERTEX_ARRAY);
365 glEnableClientState(GL_NORMAL_ARRAY);
366
367 bindGLVertexPointer();
368 bindGLNormalPointer();
369 bindGLTexCoordPointer();
370
371 // Set up second pass first
372 S32 bumpTex = gPipeline.mWaterProgram.enableTexture(LLPipeline::GLSL_BUMP_MAP);
373 mWaterImagep->addTextureStats(1024.f*1024.f);
374 mWaterImagep->bind(bumpTex);
375
376 glClientActiveTextureARB(GL_TEXTURE1_ARB);
377 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
378
379 LLVector3 camera_up = gCamera->getUpAxis();
380 F32 up_dot = camera_up * LLVector3::z_axis;
381
382 LLColor4 water_color;
383 if (gCamera->cameraUnderWater())
384 {
385 water_color.setVec(1.f, 1.f, 1.f, 0.4f);
386 }
387 else
388 {
389 water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
390 }
391
392 glColor4fv(water_color.mV);
393
394 // Automatically generate texture coords for detail map
395 glActiveTextureARB(GL_TEXTURE1_ARB);
396 glEnable(GL_TEXTURE_GEN_S); //texture unit 1
397 glEnable(GL_TEXTURE_GEN_T); //texture unit 1
398 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
399 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
400
401 // Slowly move over time.
402 F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f);
403 F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f};
404 F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f};
405 glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
406 glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
407
408 glClientActiveTextureARB(GL_TEXTURE0_ARB);
409 glActiveTextureARB(GL_TEXTURE0_ARB);
410
411 glClearStencil(1);
412 glClear(GL_STENCIL_BUFFER_BIT);
413 LLGLEnable gls_stencil(GL_STENCIL_TEST);
414 glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
415 glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
416
417 S32 envTex = -1;
418
419 if (gSky.mVOSkyp->getCubeMap())
420 {
421 envTex = gPipeline.mWaterProgram.enableTexture(LLPipeline::GLSL_ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB);
422 gSky.mVOSkyp->getCubeMap()->bind();
423
424 glMatrixMode(GL_TEXTURE);
425 glLoadIdentity();
426 LLMatrix4 camera_mat = gCamera->getModelview();
427 LLMatrix4 camera_rot(camera_mat.getMat3());
428 camera_rot.invert();
429
430 glLoadMatrixf((F32 *)camera_rot.mMatrix);
431
432 glMatrixMode(GL_MODELVIEW);
433 }
434
435 S32 scatterTex = gPipeline.mWaterProgram.enableTexture(LLPipeline::GLSL_SCATTER_MAP);
436 LLViewerImage::bindTexture(gSky.mVOSkyp->getScatterMap(), scatterTex);
437
438 S32 diffTex = gPipeline.mWaterProgram.enableTexture(LLPipeline::GLSL_DIFFUSE_MAP);
439
440 gPipeline.mWaterProgram.bind();
441
442 for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
443 iter != mDrawFace.end(); iter++)
444 {
445 LLFace *face = *iter;
446 if (voskyp->isReflFace(face))
447 {
448 continue;
449 }
450 face->bindTexture(diffTex);
451 face->renderIndexed(getRawIndices());
452 mIndicesDrawn += face->getIndicesCount();
453 }
454
455 if (gSky.mVOSkyp->getCubeMap())
456 {
457 gPipeline.mWaterProgram.disableTexture(LLPipeline::GLSL_ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB);
458 glMatrixMode(GL_TEXTURE);
459 glLoadIdentity();
460 glMatrixMode(GL_MODELVIEW);
461 }
462
463 // Now, disable texture coord generation on texture state 1
464 gPipeline.mWaterProgram.disableTexture(LLPipeline::GLSL_BUMP_MAP);
465 LLImageGL::unbindTexture(bumpTex, GL_TEXTURE_2D);
466
467 glActiveTextureARB(GL_TEXTURE1_ARB);
468 glDisable(GL_TEXTURE_GEN_S); //texture unit 1
469 glDisable(GL_TEXTURE_GEN_T); //texture unit 1
470
471 gPipeline.mWaterProgram.disableTexture(LLPipeline::GLSL_DIFFUSE_MAP);
472 gPipeline.mWaterProgram.disableTexture(LLPipeline::GLSL_SCATTER_MAP);
473
474 // Disable texture coordinate and color arrays
475 LLImageGL::unbindTexture(diffTex, GL_TEXTURE_2D);
476
477 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
478 stop_glerror();
479
480 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
481
482 glUseProgramObjectARB(0);
483 gPipeline.disableLights();
484
485 glActiveTextureARB(GL_TEXTURE0_ARB);
486 glClientActiveTextureARB(GL_TEXTURE0_ARB);
487 glEnable(GL_TEXTURE_2D);
488
489 if (refl_face)
490 {
491 glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
492 renderReflection(refl_face);
493 }
494
495 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
496 glDisableClientState(GL_NORMAL_ARRAY);
497}
498
499void LLDrawPoolWater::renderReflection(const LLFace* face)
500{
501 LLVOSky *voskyp = gSky.mVOSkyp;
502
503 if (!voskyp)
504 {
505 return;
506 }
507
508 if (!face->getGeomCount())
509 {
510 return;
511 }
512
513 S8 dr = voskyp->getDrawRefl();
514 if (dr < 0)
515 {
516 return;
517 }
518
519 LLGLSNoFog noFog;
520
521 glEnableClientState(GL_VERTEX_ARRAY);
522 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
523
524 LLViewerImage::bindTexture(mHBTex[dr]);
525
526 LLOverrideFaceColor override(this, face->getFaceColor().mV);
527 face->renderIndexed(getRawIndices());
528 mIndicesDrawn += face->getIndicesCount();
529
530 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
531}
532
533void bindScreenToTexture()
534{
535 GLint viewport[4];
536 glGetIntegerv(GL_VIEWPORT, viewport);
537 GLuint resX = nhpo2(viewport[2]);
538 GLuint resY = nhpo2(viewport[3]);
539
540 glBindTexture(GL_TEXTURE_2D, sScreenTex);
541 GLint cResX;
542 GLint cResY;
543 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &cResX);
544 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &cResY);
545
546 if (cResX != (GLint)resX || cResY != (GLint)resY)
547 {
548 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, resX, resY, 0, GL_RGB, GL_FLOAT, NULL);
549 gImageList.updateMaxResidentTexMem(-1, resX*resY*3);
550 }
551
552 glCopyTexSubImage2D(GL_TEXTURE_2D, 0, viewport[0], viewport[1], 0, 0, viewport[2], viewport[3]);
553
554 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
555 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
556 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
557 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
558
559 float scale[2];
560 scale[0] = (float) viewport[2]/resX;
561 scale[1] = (float) viewport[3]/resY;
562 glUniform2fvARB(gPipeline.mWaterProgram.mUniform[LLPipeline::GLSL_WATER_FBSCALE], 1, scale);
563
564 LLImageGL::sBoundTextureMemory += resX * resY * 3;
565}
566
567void LLDrawPoolWater::shade()
568{
569 static LLVector2 d1( 0.5f, -0.17f );
570 static LLVector2 d2( 0.58f, -0.67f );
571 static LLVector2 d3( 0.5f, 0.25f );
572
573 static LLVector3 wave1(1,0.42f,1);
574 static LLVector3 wave2(0.58f,0.42f,0.17f);
575 static LLVector3 wave3(0.42f,0.67f,0.33f);
576
577 /*static LLVector2 d1( 0.83f, -1 );
578 static LLVector2 d2( 0.58f, 1 );
579 static LLVector2 d3( 1, -0.88f );
580
581 static LLVector4 wave1(0.75f,0.08f,0.5f,0.67f);
582 static LLVector4 wave2(0.17f,0.33f,0.53f,0.62f);
583 static LLVector4 wave3(0.17f,0.6f,0.67f,1);*/
584
585 /*LLDebugVarMessageBox::show("Wave Direction 1", &d1, LLVector2(1,1), LLVector2(0.01f, 0.01f));
586 LLDebugVarMessageBox::show("Wave Direction 2", &d2, LLVector2(1,1), LLVector2(0.01f, 0.01f));
587 LLDebugVarMessageBox::show("Wave Direction 3", &d3, LLVector2(1,1), LLVector2(0.01f, 0.01f));
588
589 LLDebugVarMessageBox::show("Wave 1", &wave1, LLVector3(2,1,4), LLVector3(0.01f, 0.01f, 0.01f));
590 LLDebugVarMessageBox::show("Wave 2", &wave2, LLVector3(2,1,4), LLVector3(0.01f, 0.01f, 0.01f));
591 LLDebugVarMessageBox::show("Wave 3", &wave3, LLVector3(2,1,4), LLVector3(0.01f, 0.01f, 0.01f));*/
592
593 LLVOSky *voskyp = gSky.mVOSkyp;
594
595 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
596 glEnableClientState(GL_VERTEX_ARRAY);
597 glEnableClientState(GL_NORMAL_ARRAY);
598 LLGLDisable blend(GL_BLEND);
599 bindGLVertexPointer();
600 bindGLNormalPointer();
601 bindGLTexCoordPointer();
602
603 LLColor3 light_diffuse(0,0,0);
604 F32 light_exp = 0.0f;
605 LLVector3 light_dir;
606
607 if (gSky.getSunDirection().mV[2] > NIGHTTIME_ELEVATION_COS)
608 {
609 light_dir = gSky.getSunDirection();
610 light_dir.normVec();
611 light_diffuse = gSky.mVOSkyp->getSun().getColorCached();
612 light_diffuse.normVec();
613 light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0);
614 light_diffuse *= light_exp + 0.25f;
615 }
616 else
617 {
618 light_dir = gSky.getMoonDirection();
619 light_dir.normVec();
620 light_diffuse = gSky.mVOSkyp->getMoon().getColorCached();
621 light_diffuse.normVec();
622 light_diffuse *= 0.5f;
623 light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0);
624 }
625
626 light_exp *= light_exp;
627 light_exp *= light_exp;
628 light_exp *= light_exp;
629 light_exp *= light_exp;
630 light_exp *= light_exp;
631 light_exp *= 512.f;
632 light_exp = light_exp > 32.f ? light_exp : 32.f;
633
634 sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f;
635
636 LLCubeMap* skyMap = gSky.mVOSkyp->getCubeMap();
637
638 gPipeline.mWaterProgram.enableTexture(LLPipeline::GLSL_ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB);
639 skyMap->bind();
640
641 //bind normal map
642 S32 bumpTex = gPipeline.mWaterProgram.enableTexture(LLPipeline::GLSL_BUMP_MAP);
643 mWaterNormp->addTextureStats(1024.f*1024.f);
644 mWaterNormp->bind(bumpTex);
645
646 gPipeline.mWaterProgram.enableTexture(LLPipeline::GLSL_WATER_SCREENTEX);
647
648 gPipeline.mWaterProgram.bind();
649
650 bindScreenToTexture();
651
652 S32 scatterTex = gPipeline.mWaterProgram.enableTexture(LLPipeline::GLSL_SCATTER_MAP);
653 LLViewerImage::bindTexture(gSky.mVOSkyp->getScatterMap(), scatterTex);
654
655 S32 diffTex = gPipeline.mWaterProgram.enableTexture(LLPipeline::GLSL_DIFFUSE_MAP);
656
657 LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
658
659 glUniform1fARB(gPipeline.mWaterProgram.mUniform[LLPipeline::GLSL_WATER_TIME], sTime);
660 glUniform3fvARB(gPipeline.mWaterProgram.mUniform[LLPipeline::GLSL_WATER_SPECULAR], 1, light_diffuse.mV);
661 glUniform1fARB(gPipeline.mWaterProgram.mUniform[LLPipeline::GLSL_WATER_SPECULAR_EXP], light_exp);
662 glUniform3fvARB(gPipeline.mWaterProgram.mUniform[LLPipeline::GLSL_WATER_EYEVEC], 1, gCamera->getOrigin().mV);
663 glUniform2fvARB(gPipeline.mWaterProgram.mUniform[LLPipeline::GLSL_WATER_WAVE_DIR1], 1, d1.mV);
664 glUniform2fvARB(gPipeline.mWaterProgram.mUniform[LLPipeline::GLSL_WATER_WAVE_DIR2], 1, d2.mV);
665 glUniform3fvARB(gPipeline.mWaterProgram.mUniform[LLPipeline::GLSL_WATER_LIGHT_DIR], 1, light_dir.mV);
666
667 LLColor4 water_color;
668 LLVector3 camera_up = gCamera->getUpAxis();
669 F32 up_dot = camera_up * LLVector3::z_axis;
670 if (gCamera->cameraUnderWater())
671 {
672 water_color.setVec(1.f, 1.f, 1.f, 0.4f);
673 glUniform1fARB(gPipeline.mWaterProgram.mUniform[LLPipeline::GLSL_WATER_REFSCALE], 0.25f);
674 }
675 else
676 {
677 water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
678 glUniform1fARB(gPipeline.mWaterProgram.mUniform[LLPipeline::GLSL_WATER_REFSCALE], 0.01f);
679 }
680 if (water_color.mV[3] > 0.9f)
681 {
682 water_color.mV[3] = 0.9f;
683 }
684
685 glColor4fv(water_color.mV);
686
687 {
688 LLGLDisable cullface(GL_CULL_FACE);
689 for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
690 iter != mDrawFace.end(); iter++)
691 {
692 LLFace *face = *iter;
693
694 if (voskyp->isReflFace(face))
695 {
696 continue;
697 }
698
699 face->bindTexture(diffTex);
700 face->renderIndexed(getRawIndices());
701 mIndicesDrawn += face->getIndicesCount();
702 }
703 }
704
705 gPipeline.mWaterProgram.disableTexture(LLPipeline::GLSL_ENVIRONMENT_MAP, GL_TEXTURE_CUBE_MAP_ARB);
706 gPipeline.mWaterProgram.disableTexture(LLPipeline::GLSL_WATER_SCREENTEX);
707 gPipeline.mWaterProgram.disableTexture(LLPipeline::GLSL_BUMP_MAP);
708 gPipeline.mWaterProgram.disableTexture(LLPipeline::GLSL_SCATTER_MAP);
709 gPipeline.mWaterProgram.disableTexture(LLPipeline::GLSL_DIFFUSE_MAP);
710
711 glActiveTextureARB(GL_TEXTURE0_ARB);
712 glEnable(GL_TEXTURE_2D);
713 glUseProgramObjectARB(0);
714
715 glClientActiveTextureARB(GL_TEXTURE0_ARB);
716 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
717
718 /*glDisableClientState(GL_TEXTURE_COORD_ARRAY);
719 glDisableClientState(GL_VERTEX_ARRAY);
720 glDisableClientState(GL_NORMAL_ARRAY);*/
721}
722
723void LLDrawPoolWater::renderForSelect()
724{
725 // Can't select water!
726 return;
727}
728
729
730void LLDrawPoolWater::renderFaceSelected(LLFace *facep,
731 LLImageGL *image,
732 const LLColor4 &color,
733 const S32 index_offset, const S32 index_count)
734{
735 // Can't select water
736 return;
737}
738
739
740LLViewerImage *LLDrawPoolWater::getDebugTexture()
741{
742 return LLViewerImage::sSmokeImagep;
743}
744
745LLColor3 LLDrawPoolWater::getDebugColor() const
746{
747 return LLColor3(0.f, 1.f, 1.f);
748}