diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/newview/lldrawpoolwlsky.cpp | 343 |
1 files changed, 343 insertions, 0 deletions
diff --git a/linden/indra/newview/lldrawpoolwlsky.cpp b/linden/indra/newview/lldrawpoolwlsky.cpp new file mode 100644 index 0000000..65d1d20 --- /dev/null +++ b/linden/indra/newview/lldrawpoolwlsky.cpp | |||
@@ -0,0 +1,343 @@ | |||
1 | /** | ||
2 | * @file lldrawpoolwlsky.cpp | ||
3 | * @brief LLDrawPoolWLSky class implementation | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2007&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2007-2008, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
21 | * | ||
22 | * By copying, modifying or distributing this software, you acknowledge | ||
23 | * that you have read and understood your obligations described above, | ||
24 | * and agree to abide by those obligations. | ||
25 | * | ||
26 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
27 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
28 | * COMPLETENESS OR PERFORMANCE. | ||
29 | * $/LicenseInfo$ | ||
30 | */ | ||
31 | |||
32 | #include "llviewerprecompiledheaders.h" | ||
33 | |||
34 | #include "lldrawpoolwlsky.h" | ||
35 | |||
36 | #include "llerror.h" | ||
37 | #include "llgl.h" | ||
38 | #include "pipeline.h" | ||
39 | #include "llviewercamera.h" | ||
40 | #include "llimage.h" | ||
41 | #include "llwlparammanager.h" | ||
42 | #include "llsky.h" | ||
43 | #include "llvowlsky.h" | ||
44 | #include "llagent.h" | ||
45 | #include "llviewerregion.h" | ||
46 | #include "llface.h" | ||
47 | #include "llglimmediate.h" | ||
48 | |||
49 | LLPointer<LLImageGL> LLDrawPoolWLSky::sCloudNoiseTexture = NULL; | ||
50 | |||
51 | LLPointer<LLImageRaw> LLDrawPoolWLSky::sCloudNoiseRawImage = NULL; | ||
52 | |||
53 | |||
54 | |||
55 | LLDrawPoolWLSky::LLDrawPoolWLSky(void) : | ||
56 | LLDrawPool(POOL_WL_SKY) | ||
57 | { | ||
58 | const LLString cloudNoiseFilename(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", "clouds2.tga")); | ||
59 | llinfos << "loading WindLight cloud noise from " << cloudNoiseFilename << llendl; | ||
60 | |||
61 | LLPointer<LLImageFormatted> cloudNoiseFile(LLImageFormatted::createFromExtension(cloudNoiseFilename)); | ||
62 | |||
63 | if(cloudNoiseFile.isNull()) { | ||
64 | llerrs << "Error: Failed to load cloud noise image " << cloudNoiseFilename << llendl; | ||
65 | } | ||
66 | |||
67 | cloudNoiseFile->load(cloudNoiseFilename); | ||
68 | |||
69 | sCloudNoiseRawImage = new LLImageRaw(); | ||
70 | |||
71 | cloudNoiseFile->decode(sCloudNoiseRawImage); | ||
72 | |||
73 | LLImageGL::create(sCloudNoiseTexture, sCloudNoiseRawImage, TRUE); | ||
74 | |||
75 | LLWLParamManager::instance()->propagateParameters(); | ||
76 | } | ||
77 | |||
78 | LLDrawPoolWLSky::~LLDrawPoolWLSky() | ||
79 | { | ||
80 | //llinfos << "destructing wlsky draw pool." << llendl; | ||
81 | sCloudNoiseTexture = 0; | ||
82 | } | ||
83 | |||
84 | LLViewerImage *LLDrawPoolWLSky::getDebugTexture() | ||
85 | { | ||
86 | return NULL; | ||
87 | } | ||
88 | |||
89 | void LLDrawPoolWLSky::beginRenderPass( S32 pass ) | ||
90 | { | ||
91 | } | ||
92 | |||
93 | void LLDrawPoolWLSky::endRenderPass( S32 pass ) | ||
94 | { | ||
95 | } | ||
96 | |||
97 | void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) const | ||
98 | { | ||
99 | LLVector3 const & origin = gCamera->getOrigin(); | ||
100 | |||
101 | llassert_always(NULL != shader); | ||
102 | |||
103 | glPushMatrix(); | ||
104 | |||
105 | //chop off translation | ||
106 | if (LLPipeline::sReflectionRender && origin.mV[2] > 256.f) | ||
107 | { | ||
108 | glTranslatef(origin.mV[0], origin.mV[1], 256.f-origin.mV[2]*0.5f); | ||
109 | } | ||
110 | else | ||
111 | { | ||
112 | glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]); | ||
113 | } | ||
114 | |||
115 | |||
116 | // the windlight sky dome works most conveniently in a coordinate system | ||
117 | // where Y is up, so permute our basis vectors accordingly. | ||
118 | glRotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3); | ||
119 | |||
120 | glScalef(0.333f, 0.333f, 0.333f); | ||
121 | |||
122 | glTranslatef(0.f,-camHeightLocal, 0.f); | ||
123 | |||
124 | // Draw WL Sky | ||
125 | shader->uniform3f("camPosLocal", 0.f, camHeightLocal, 0.f); | ||
126 | |||
127 | gSky.mVOWLSkyp->drawDome(); | ||
128 | |||
129 | glPopMatrix(); | ||
130 | } | ||
131 | |||
132 | void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const | ||
133 | { | ||
134 | if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) | ||
135 | { | ||
136 | LLGLSLShader* shader = | ||
137 | LLPipeline::sUnderWaterRender ? | ||
138 | &gObjectSimpleWaterProgram : | ||
139 | &gWLSkyProgram; | ||
140 | |||
141 | LLGLDisable blend(GL_BLEND); | ||
142 | |||
143 | shader->bind(); | ||
144 | |||
145 | /// Render the skydome | ||
146 | renderDome(camHeightLocal, shader); | ||
147 | |||
148 | shader->unbind(); | ||
149 | } | ||
150 | } | ||
151 | |||
152 | void LLDrawPoolWLSky::renderStars(void) const | ||
153 | { | ||
154 | LLGLSPipelineSkyBox gls_sky; | ||
155 | LLGLEnable blend(GL_BLEND); | ||
156 | gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
157 | |||
158 | // *NOTE: have to have bound the cloud noise texture already since register | ||
159 | // combiners blending below requires something to be bound | ||
160 | // and we might as well only bind once. | ||
161 | //LLGLEnable gl_texture_2d(GL_TEXTURE_2D); | ||
162 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
163 | glDisableClientState(GL_NORMAL_ARRAY); | ||
164 | |||
165 | gPipeline.disableLights(); | ||
166 | |||
167 | if (!LLPipeline::sReflectionRender) | ||
168 | { | ||
169 | glPointSize(2.f); | ||
170 | } | ||
171 | |||
172 | // *NOTE: we divide by two here and GL_ALPHA_SCALE by two below to avoid | ||
173 | // clamping and allow the star_alpha param to brighten the stars. | ||
174 | bool error; | ||
175 | LLColor4 star_alpha(LLColor4::black); | ||
176 | star_alpha.mV[3] = LLWLParamManager::instance()->mCurParams.getFloat("star_brightness", error) / 2.f; | ||
177 | llassert_always(!error); | ||
178 | |||
179 | // gl_FragColor.rgb = gl_Color.rgb; | ||
180 | // gl_FragColor.a = gl_Color.a * star_alpha.a; | ||
181 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); | ||
182 | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); | ||
183 | glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE); | ||
184 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS); | ||
185 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); | ||
186 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS); | ||
187 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA); | ||
188 | glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_CONSTANT); | ||
189 | glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA); | ||
190 | glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 2.0f); | ||
191 | glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, star_alpha.mV); | ||
192 | |||
193 | gSky.mVOWLSkyp->drawStars(); | ||
194 | |||
195 | glPointSize(1.f); | ||
196 | |||
197 | // and disable the combiner states | ||
198 | glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0f); | ||
199 | glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); | ||
200 | } | ||
201 | |||
202 | void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const | ||
203 | { | ||
204 | if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS)) | ||
205 | { | ||
206 | LLGLSLShader* shader = | ||
207 | LLPipeline::sUnderWaterRender ? | ||
208 | &gObjectSimpleWaterProgram : | ||
209 | &gWLCloudProgram; | ||
210 | |||
211 | LLGLEnable blend(GL_BLEND); | ||
212 | LLGLSBlendFunc blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
213 | glAlphaFunc(GL_GREATER, 0.01f); | ||
214 | |||
215 | sCloudNoiseTexture->bind(); | ||
216 | shader->bind(); | ||
217 | |||
218 | /// Render the skydome | ||
219 | renderDome(camHeightLocal, shader); | ||
220 | |||
221 | shader->unbind(); | ||
222 | } | ||
223 | } | ||
224 | |||
225 | void LLDrawPoolWLSky::renderHeavenlyBodies() | ||
226 | { | ||
227 | glEnableClientState(GL_VERTEX_ARRAY); | ||
228 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); | ||
229 | glDisableClientState(GL_NORMAL_ARRAY); | ||
230 | LLGLSPipelineSkyBox gls_skybox; | ||
231 | LLGLEnable blend_on(GL_BLEND); | ||
232 | gPipeline.disableLights(); | ||
233 | |||
234 | #if 0 // when we want to re-add a texture sun disc, here's where to do it. | ||
235 | LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN]; | ||
236 | if (gSky.mVOSkyp->getSun().getDraw() && face->getGeomCount()) | ||
237 | { | ||
238 | LLImageGL * tex = face->getTexture(); | ||
239 | tex->bind(); | ||
240 | LLColor4 color(gSky.mVOSkyp->getSun().getInterpColor()); | ||
241 | LLFacePool::LLOverrideFaceColor color_override(this, color); | ||
242 | face->renderIndexed(); | ||
243 | mIndicesDrawn += face->getIndicesCount(); | ||
244 | } | ||
245 | #endif | ||
246 | |||
247 | LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]; | ||
248 | |||
249 | if (gSky.mVOSkyp->getMoon().getDraw() && face->getGeomCount()) | ||
250 | { | ||
251 | // *NOTE: even though we already bound this texture above for the | ||
252 | // stars register combiners, we bind again here for defensive reasons, | ||
253 | // since LLImageGL::bind detects that it's a noop, and optimizes it out. | ||
254 | LLImageGL * tex = face->getTexture(); | ||
255 | tex->bind(); | ||
256 | LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor()); | ||
257 | F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2]; | ||
258 | if (a > 0.f) | ||
259 | { | ||
260 | a = a*a*4.f; | ||
261 | } | ||
262 | |||
263 | color.mV[3] = llclamp(a, 0.f, 1.f); | ||
264 | |||
265 | LLFacePool::LLOverrideFaceColor color_override(this, color); | ||
266 | face->renderIndexed(); | ||
267 | mIndicesDrawn += face->getIndicesCount(); | ||
268 | } | ||
269 | |||
270 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
271 | } | ||
272 | |||
273 | void LLDrawPoolWLSky::render(S32 pass) | ||
274 | { | ||
275 | if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY)) | ||
276 | { | ||
277 | return; | ||
278 | } | ||
279 | LLFastTimer ftm(LLFastTimer::FTM_RENDER_WL_SKY); | ||
280 | |||
281 | const F32 camHeightLocal = LLWLParamManager::instance()->getDomeOffset() * LLWLParamManager::instance()->getDomeRadius(); | ||
282 | |||
283 | LLGLSNoFog disableFog; | ||
284 | LLGLDepthTest depth(GL_TRUE, GL_FALSE); | ||
285 | LLGLDisable clip(GL_CLIP_PLANE0); | ||
286 | |||
287 | LLGLClampToFarClip far_clip(glh_get_current_projection()); | ||
288 | |||
289 | renderSkyHaze(camHeightLocal); | ||
290 | |||
291 | LLVector3 const & origin = gCamera->getOrigin(); | ||
292 | glPushMatrix(); | ||
293 | |||
294 | glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]); | ||
295 | |||
296 | // *NOTE: have to bind a texture here since register combiners blending in | ||
297 | // renderStars() requires something to be bound and we might as well only | ||
298 | // bind the moon's texture once. | ||
299 | LLImageGL * tex = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture(); | ||
300 | tex->bind(); | ||
301 | |||
302 | renderHeavenlyBodies(); | ||
303 | |||
304 | renderStars(); | ||
305 | |||
306 | |||
307 | glPopMatrix(); | ||
308 | |||
309 | renderSkyClouds(camHeightLocal); | ||
310 | |||
311 | LLImageGL::unbindTexture(0); | ||
312 | } | ||
313 | |||
314 | void LLDrawPoolWLSky::prerender() | ||
315 | { | ||
316 | //llinfos << "wlsky prerendering pass." << llendl; | ||
317 | } | ||
318 | |||
319 | LLDrawPoolWLSky *LLDrawPoolWLSky::instancePool() | ||
320 | { | ||
321 | return new LLDrawPoolWLSky(); | ||
322 | } | ||
323 | |||
324 | LLViewerImage* LLDrawPoolWLSky::getTexture() | ||
325 | { | ||
326 | return NULL; | ||
327 | } | ||
328 | |||
329 | void LLDrawPoolWLSky::resetDrawOrders() | ||
330 | { | ||
331 | } | ||
332 | |||
333 | //static | ||
334 | void LLDrawPoolWLSky::cleanupGL() | ||
335 | { | ||
336 | sCloudNoiseTexture = NULL; | ||
337 | } | ||
338 | |||
339 | //static | ||
340 | void LLDrawPoolWLSky::restoreGL() | ||
341 | { | ||
342 | LLImageGL::create(sCloudNoiseTexture, sCloudNoiseRawImage, TRUE); | ||
343 | } | ||