PageRenderTime 84ms CodeModel.GetById 55ms app.highlight 25ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/lldrawpoolwlsky.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 418 lines | 267 code | 97 blank | 54 comment | 23 complexity | 047beb1f094d4015f5140ae8d76287c0 MD5 | raw file
  1/** 
  2 * @file lldrawpoolwlsky.cpp
  3 * @brief LLDrawPoolWLSky class implementation
  4 *
  5 * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "lldrawpoolwlsky.h"
 30
 31#include "llerror.h"
 32#include "llgl.h"
 33#include "pipeline.h"
 34#include "llviewercamera.h"
 35#include "llimage.h"
 36#include "llwlparammanager.h"
 37#include "llviewershadermgr.h"
 38#include "llglslshader.h"
 39#include "llsky.h"
 40#include "llvowlsky.h"
 41#include "llviewerregion.h"
 42#include "llface.h"
 43#include "llrender.h"
 44
 45LLPointer<LLViewerTexture> LLDrawPoolWLSky::sCloudNoiseTexture = NULL;
 46
 47LLPointer<LLImageRaw> LLDrawPoolWLSky::sCloudNoiseRawImage = NULL;
 48
 49static LLGLSLShader* cloud_shader = NULL;
 50static LLGLSLShader* sky_shader = NULL;
 51
 52
 53LLDrawPoolWLSky::LLDrawPoolWLSky(void) :
 54	LLDrawPool(POOL_WL_SKY)
 55{
 56	const std::string cloudNoiseFilename(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", "clouds2.tga"));
 57	llinfos << "loading WindLight cloud noise from " << cloudNoiseFilename << llendl;
 58
 59	LLPointer<LLImageFormatted> cloudNoiseFile(LLImageFormatted::createFromExtension(cloudNoiseFilename));
 60
 61	if(cloudNoiseFile.isNull()) {
 62		llerrs << "Error: Failed to load cloud noise image " << cloudNoiseFilename << llendl;
 63	}
 64
 65	if(cloudNoiseFile->load(cloudNoiseFilename))
 66	{
 67		sCloudNoiseRawImage = new LLImageRaw();
 68
 69		if(cloudNoiseFile->decode(sCloudNoiseRawImage, 0.0f))
 70		{
 71			//debug use			
 72			lldebugs << "cloud noise raw image width: " << sCloudNoiseRawImage->getWidth() << " : height: " << sCloudNoiseRawImage->getHeight() << " : components: " << 
 73				(S32)sCloudNoiseRawImage->getComponents() << " : data size: " << sCloudNoiseRawImage->getDataSize() << llendl ;
 74			llassert_always(sCloudNoiseRawImage->getData()) ;
 75
 76			sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);
 77		}
 78		else
 79		{
 80			sCloudNoiseRawImage = NULL ;
 81		}
 82	}
 83
 84	LLWLParamManager::getInstance()->propagateParameters();
 85}
 86
 87LLDrawPoolWLSky::~LLDrawPoolWLSky()
 88{
 89	//llinfos << "destructing wlsky draw pool." << llendl;
 90	sCloudNoiseTexture = NULL;
 91	sCloudNoiseRawImage = NULL;
 92}
 93
 94LLViewerTexture *LLDrawPoolWLSky::getDebugTexture()
 95{
 96	return NULL;
 97}
 98
 99void LLDrawPoolWLSky::beginRenderPass( S32 pass )
100{
101	sky_shader =
102		LLPipeline::sUnderWaterRender ?
103			&gObjectFullbrightNoColorWaterProgram :
104			&gWLSkyProgram;
105
106	cloud_shader =
107			LLPipeline::sUnderWaterRender ?
108				&gObjectFullbrightNoColorWaterProgram :
109				&gWLCloudProgram;
110}
111
112void LLDrawPoolWLSky::endRenderPass( S32 pass )
113{
114}
115
116void LLDrawPoolWLSky::beginDeferredPass(S32 pass)
117{
118	sky_shader = &gDeferredWLSkyProgram;
119	cloud_shader = &gDeferredWLCloudProgram;
120}
121
122void LLDrawPoolWLSky::endDeferredPass(S32 pass)
123{
124
125}
126
127void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) const
128{
129	LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
130
131	llassert_always(NULL != shader);
132
133	gGL.pushMatrix();
134
135	//chop off translation
136	if (LLPipeline::sReflectionRender && origin.mV[2] > 256.f)
137	{
138		gGL.translatef(origin.mV[0], origin.mV[1], 256.f-origin.mV[2]*0.5f);
139	}
140	else
141	{
142		gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
143	}
144		
145
146	// the windlight sky dome works most conveniently in a coordinate system
147	// where Y is up, so permute our basis vectors accordingly.
148	gGL.rotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3);
149
150	gGL.scalef(0.333f, 0.333f, 0.333f);
151
152	gGL.translatef(0.f,-camHeightLocal, 0.f);
153	
154	// Draw WL Sky	
155	shader->uniform3f("camPosLocal", 0.f, camHeightLocal, 0.f);
156
157	gSky.mVOWLSkyp->drawDome();
158
159	gGL.popMatrix();
160}
161
162void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const
163{
164	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
165	{
166		LLGLDisable blend(GL_BLEND);
167
168		sky_shader->bind();
169
170		/// Render the skydome
171		renderDome(camHeightLocal, sky_shader);	
172
173		sky_shader->unbind();
174	}
175}
176
177void LLDrawPoolWLSky::renderStars(void) const
178{
179	LLGLSPipelineSkyBox gls_sky;
180	LLGLEnable blend(GL_BLEND);
181	gGL.setSceneBlendType(LLRender::BT_ALPHA);
182	
183	// *NOTE: have to have bound the cloud noise texture already since register
184	// combiners blending below requires something to be bound
185	// and we might as well only bind once.
186	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
187	
188	gPipeline.disableLights();
189	
190	// *NOTE: we divide by two here and GL_ALPHA_SCALE by two below to avoid
191	// clamping and allow the star_alpha param to brighten the stars.
192	bool error;
193	LLColor4 star_alpha(LLColor4::black);
194	star_alpha.mV[3] = LLWLParamManager::getInstance()->mCurParams.getFloat("star_brightness", error) / 2.f;
195	llassert_always(!error);
196
197	gGL.getTexUnit(0)->bind(gSky.mVOSkyp->getBloomTex());
198
199	gGL.pushMatrix();
200	gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
201	// gl_FragColor.rgb = gl_Color.rgb;
202	// gl_FragColor.a = gl_Color.a * star_alpha.a;
203	if (LLGLSLShader::sNoFixedFunction)
204	{
205		gCustomAlphaProgram.bind();
206		gCustomAlphaProgram.uniform1f("custom_alpha", star_alpha.mV[3]);
207	}
208	else
209	{
210		gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_VERT_COLOR);
211		gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT_X2, LLTexUnit::TBS_CONST_ALPHA, LLTexUnit::TBS_TEX_ALPHA);
212		glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, star_alpha.mV);
213	}
214
215	gSky.mVOWLSkyp->drawStars();
216
217	gGL.popMatrix();
218
219	if (LLGLSLShader::sNoFixedFunction)
220	{
221		gCustomAlphaProgram.unbind();
222	}
223	else
224	{
225		// and disable the combiner states
226		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
227	}
228}
229
230void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const
231{
232	if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && sCloudNoiseTexture.notNull())
233	{
234		LLGLEnable blend(GL_BLEND);
235		gGL.setSceneBlendType(LLRender::BT_ALPHA);
236		
237		gGL.getTexUnit(0)->bind(sCloudNoiseTexture);
238
239		cloud_shader->bind();
240
241		/// Render the skydome
242		renderDome(camHeightLocal, cloud_shader);
243
244		cloud_shader->unbind();
245	}
246}
247
248void LLDrawPoolWLSky::renderHeavenlyBodies()
249{
250	LLGLSPipelineSkyBox gls_skybox;
251	LLGLEnable blend_on(GL_BLEND);
252	gPipeline.disableLights();
253
254#if 0 // when we want to re-add a texture sun disc, here's where to do it.
255	LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN];
256	if (gSky.mVOSkyp->getSun().getDraw() && face->getGeomCount())
257	{
258		LLViewerTexture * tex  = face->getTexture();
259		gGL.getTexUnit(0)->bind(tex);
260		LLColor4 color(gSky.mVOSkyp->getSun().getInterpColor());
261		LLFacePool::LLOverrideFaceColor color_override(this, color);
262		face->renderIndexed();
263	}
264#endif
265
266	LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON];
267
268	if (gSky.mVOSkyp->getMoon().getDraw() && face->getGeomCount())
269	{
270		// *NOTE: even though we already bound this texture above for the
271		// stars register combiners, we bind again here for defensive reasons,
272		// since LLImageGL::bind detects that it's a noop, and optimizes it out.
273		gGL.getTexUnit(0)->bind(face->getTexture());
274		LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor());
275		F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2];
276		if (a > 0.f)
277		{
278			a = a*a*4.f;
279		}
280			
281		color.mV[3] = llclamp(a, 0.f, 1.f);
282		
283		if (gPipeline.canUseVertexShaders())
284		{
285			gHighlightProgram.bind();
286		}
287
288		LLFacePool::LLOverrideFaceColor color_override(this, color);
289		
290		face->renderIndexed();
291
292		if (gPipeline.canUseVertexShaders())
293		{
294			gHighlightProgram.unbind();
295		}
296	}
297}
298
299void LLDrawPoolWLSky::renderDeferred(S32 pass)
300{
301	if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
302	{
303		return;
304	}
305	LLFastTimer ftm(FTM_RENDER_WL_SKY);
306
307	const F32 camHeightLocal = LLWLParamManager::getInstance()->getDomeOffset() * LLWLParamManager::getInstance()->getDomeRadius();
308
309	LLGLSNoFog disableFog;
310	LLGLDepthTest depth(GL_TRUE, GL_FALSE);
311	LLGLDisable clip(GL_CLIP_PLANE0);
312
313	gGL.setColorMask(true, false);
314
315	LLGLSquashToFarClip far_clip(glh_get_current_projection());
316
317	renderSkyHaze(camHeightLocal);
318
319	LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
320	gGL.pushMatrix();
321
322		
323		gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
324
325		gDeferredStarProgram.bind();
326		// *NOTE: have to bind a texture here since register combiners blending in
327		// renderStars() requires something to be bound and we might as well only
328		// bind the moon's texture once.		
329		gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture());
330
331		renderHeavenlyBodies();
332
333		renderStars();
334		
335		gDeferredStarProgram.unbind();
336
337	gGL.popMatrix();
338
339	renderSkyClouds(camHeightLocal);
340
341	gGL.setColorMask(true, true);
342	//gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
343
344}
345
346void LLDrawPoolWLSky::render(S32 pass)
347{
348	if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
349	{
350		return;
351	}
352	LLFastTimer ftm(FTM_RENDER_WL_SKY);
353
354	const F32 camHeightLocal = LLWLParamManager::getInstance()->getDomeOffset() * LLWLParamManager::getInstance()->getDomeRadius();
355
356	LLGLSNoFog disableFog;
357	LLGLDepthTest depth(GL_TRUE, GL_FALSE);
358	LLGLDisable clip(GL_CLIP_PLANE0);
359
360	LLGLSquashToFarClip far_clip(glh_get_current_projection());
361
362	renderSkyHaze(camHeightLocal);
363
364	LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
365	gGL.pushMatrix();
366
367		gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
368
369		// *NOTE: have to bind a texture here since register combiners blending in
370		// renderStars() requires something to be bound and we might as well only
371		// bind the moon's texture once.		
372		gGL.getTexUnit(0)->bind(gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture());
373
374		renderHeavenlyBodies();
375
376		renderStars();
377		
378
379	gGL.popMatrix();
380
381	renderSkyClouds(camHeightLocal);
382
383	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
384}
385
386void LLDrawPoolWLSky::prerender()
387{
388	//llinfos << "wlsky prerendering pass." << llendl;
389}
390
391LLDrawPoolWLSky *LLDrawPoolWLSky::instancePool()
392{
393	return new LLDrawPoolWLSky();
394}
395
396LLViewerTexture* LLDrawPoolWLSky::getTexture()
397{
398	return NULL;
399}
400
401void LLDrawPoolWLSky::resetDrawOrders()
402{
403}
404
405//static
406void LLDrawPoolWLSky::cleanupGL()
407{
408	sCloudNoiseTexture = NULL;
409}
410
411//static
412void LLDrawPoolWLSky::restoreGL()
413{
414	if(sCloudNoiseRawImage.notNull())
415	{
416		sCloudNoiseTexture = LLViewerTextureManager::getLocalTexture(sCloudNoiseRawImage.get(), TRUE);
417	}
418}