lldrawpoolwlsky.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "lldrawpoolwlsky.h"
00035 
00036 #include "llerror.h"
00037 #include "llgl.h"
00038 #include "pipeline.h"
00039 #include "llviewercamera.h"
00040 #include "llimage.h"
00041 #include "llwlparammanager.h"
00042 #include "llsky.h"
00043 #include "llvowlsky.h"
00044 #include "llagent.h"
00045 #include "llviewerregion.h"
00046 #include "llface.h"
00047 #include "llglimmediate.h"
00048 
00049 LLPointer<LLImageGL> LLDrawPoolWLSky::sCloudNoiseTexture = NULL;
00050 
00051 LLPointer<LLImageRaw> LLDrawPoolWLSky::sCloudNoiseRawImage = NULL;
00052 
00053 
00054 
00055 LLDrawPoolWLSky::LLDrawPoolWLSky(void) :
00056         LLDrawPool(POOL_WL_SKY)
00057 {
00058         const LLString cloudNoiseFilename(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", "clouds2.tga"));
00059         llinfos << "loading WindLight cloud noise from " << cloudNoiseFilename << llendl;
00060 
00061         LLPointer<LLImageFormatted> cloudNoiseFile(LLImageFormatted::createFromExtension(cloudNoiseFilename));
00062 
00063         if(cloudNoiseFile.isNull()) {
00064                 llerrs << "Error: Failed to load cloud noise image " << cloudNoiseFilename << llendl;
00065         }
00066 
00067         cloudNoiseFile->load(cloudNoiseFilename);
00068 
00069         sCloudNoiseRawImage = new LLImageRaw();
00070 
00071         cloudNoiseFile->decode(sCloudNoiseRawImage, 0.0f);
00072 
00073         LLImageGL::create(sCloudNoiseTexture, sCloudNoiseRawImage, TRUE);
00074 
00075         LLWLParamManager::instance()->propagateParameters();
00076 }
00077 
00078 LLDrawPoolWLSky::~LLDrawPoolWLSky()
00079 {
00080         //llinfos << "destructing wlsky draw pool." << llendl;
00081         sCloudNoiseTexture = 0;
00082 }
00083 
00084 LLViewerImage *LLDrawPoolWLSky::getDebugTexture()
00085 {
00086         return NULL;
00087 }
00088 
00089 void LLDrawPoolWLSky::beginRenderPass( S32 pass )
00090 {
00091 }
00092 
00093 void LLDrawPoolWLSky::endRenderPass( S32 pass )
00094 {
00095 }
00096 
00097 void LLDrawPoolWLSky::renderDome(F32 camHeightLocal, LLGLSLShader * shader) const
00098 {
00099         LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
00100 
00101         llassert_always(NULL != shader);
00102 
00103         glPushMatrix();
00104 
00105         //chop off translation
00106         if (LLPipeline::sReflectionRender && origin.mV[2] > 256.f)
00107         {
00108                 glTranslatef(origin.mV[0], origin.mV[1], 256.f-origin.mV[2]*0.5f);
00109         }
00110         else
00111         {
00112                 glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]);
00113         }
00114                 
00115 
00116         // the windlight sky dome works most conveniently in a coordinate system
00117         // where Y is up, so permute our basis vectors accordingly.
00118         glRotatef(120.f, 1.f / F_SQRT3, 1.f / F_SQRT3, 1.f / F_SQRT3);
00119 
00120         glScalef(0.333f, 0.333f, 0.333f);
00121 
00122         glTranslatef(0.f,-camHeightLocal, 0.f);
00123         
00124         // Draw WL Sky  
00125         shader->uniform3f("camPosLocal", 0.f, camHeightLocal, 0.f);
00126 
00127         gSky.mVOWLSkyp->drawDome();
00128 
00129         glPopMatrix();
00130 }
00131 
00132 void LLDrawPoolWLSky::renderSkyHaze(F32 camHeightLocal) const
00133 {
00134         if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
00135         {
00136                 LLGLSLShader* shader =
00137                         LLPipeline::sUnderWaterRender ?
00138                                 &gObjectSimpleWaterProgram :
00139                                 &gWLSkyProgram;
00140 
00141                 LLGLDisable blend(GL_BLEND);
00142 
00143                 shader->bind();
00144 
00146                 renderDome(camHeightLocal, shader);     
00147 
00148                 shader->unbind();
00149         }
00150 }
00151 
00152 void LLDrawPoolWLSky::renderStars(void) const
00153 {
00154         LLGLSPipelineSkyBox gls_sky;
00155         LLGLEnable blend(GL_BLEND);
00156         gGL.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00157         
00158         // *NOTE: have to have bound the cloud noise texture already since register
00159         // combiners blending below requires something to be bound
00160         // and we might as well only bind once.
00161         //LLGLEnable gl_texture_2d(GL_TEXTURE_2D);
00162         
00163         gPipeline.disableLights();
00164 
00165         if (!LLPipeline::sReflectionRender)
00166         {
00167                 glPointSize(2.f);
00168         }
00169 
00170         // *NOTE: we divide by two here and GL_ALPHA_SCALE by two below to avoid
00171         // clamping and allow the star_alpha param to brighten the stars.
00172         bool error;
00173         LLColor4 star_alpha(LLColor4::black);
00174         star_alpha.mV[3] = LLWLParamManager::instance()->mCurParams.getFloat("star_brightness", error) / 2.f;
00175         llassert_always(!error);
00176 
00177         // gl_FragColor.rgb = gl_Color.rgb;
00178         // gl_FragColor.a = gl_Color.a * star_alpha.a;
00179         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
00180         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE);
00181         glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_ARB, GL_MODULATE);
00182         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);
00183         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
00184         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_ARB, GL_PREVIOUS);
00185         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_ARB, GL_SRC_ALPHA);
00186         glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_CONSTANT);
00187         glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA);
00188         glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 2.0f);
00189         glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, star_alpha.mV);
00190 
00191         gSky.mVOWLSkyp->drawStars();
00192 
00193         glPointSize(1.f);
00194 
00195         // and disable the combiner states
00196         glTexEnvf(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1.0f);
00197         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00198 }
00199 
00200 void LLDrawPoolWLSky::renderSkyClouds(F32 camHeightLocal) const
00201 {
00202         if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS))
00203         {
00204                 LLGLSLShader* shader =
00205                         LLPipeline::sUnderWaterRender ?
00206                                 &gObjectSimpleWaterProgram :
00207                                 &gWLCloudProgram;
00208 
00209                 LLGLEnable blend(GL_BLEND);
00210                 LLGLSBlendFunc blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00211                 glAlphaFunc(GL_GREATER, 0.01f);
00212 
00213                 sCloudNoiseTexture->bind();
00214                 shader->bind();
00215 
00217                 renderDome(camHeightLocal, shader);
00218 
00219                 shader->unbind();
00220         }
00221 }
00222 
00223 void LLDrawPoolWLSky::renderHeavenlyBodies()
00224 {
00225         LLGLSPipelineSkyBox gls_skybox;
00226         LLGLEnable blend_on(GL_BLEND);
00227         gPipeline.disableLights();
00228 
00229 #if 0 // when we want to re-add a texture sun disc, here's where to do it.
00230         LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN];
00231         if (gSky.mVOSkyp->getSun().getDraw() && face->getGeomCount())
00232         {
00233                 LLImageGL * tex  = face->getTexture();
00234                 tex->bind();
00235                 LLColor4 color(gSky.mVOSkyp->getSun().getInterpColor());
00236                 LLFacePool::LLOverrideFaceColor color_override(this, color);
00237                 face->renderIndexed();
00238         }
00239 #endif
00240 
00241         LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON];
00242 
00243         if (gSky.mVOSkyp->getMoon().getDraw() && face->getGeomCount())
00244         {
00245                 // *NOTE: even though we already bound this texture above for the
00246                 // stars register combiners, we bind again here for defensive reasons,
00247                 // since LLImageGL::bind detects that it's a noop, and optimizes it out.
00248                 LLImageGL * tex  = face->getTexture();
00249                 tex->bind();
00250                 LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor());
00251                 F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2];
00252                 if (a > 0.f)
00253                 {
00254                         a = a*a*4.f;
00255                 }
00256                         
00257                 color.mV[3] = llclamp(a, 0.f, 1.f);
00258                 
00259                 LLFacePool::LLOverrideFaceColor color_override(this, color);
00260                 face->renderIndexed();
00261         }
00262 }
00263 
00264 void LLDrawPoolWLSky::render(S32 pass)
00265 {
00266         if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
00267         {
00268                 return;
00269         }
00270         LLFastTimer ftm(LLFastTimer::FTM_RENDER_WL_SKY);
00271 
00272         const F32 camHeightLocal = LLWLParamManager::instance()->getDomeOffset() * LLWLParamManager::instance()->getDomeRadius();
00273 
00274         LLGLSNoFog disableFog;
00275         LLGLDepthTest depth(GL_TRUE, GL_FALSE);
00276         LLGLDisable clip(GL_CLIP_PLANE0);
00277 
00278         LLGLClampToFarClip far_clip(glh_get_current_projection());
00279 
00280         renderSkyHaze(camHeightLocal);
00281 
00282         LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
00283         glPushMatrix();
00284 
00285                 glTranslatef(origin.mV[0], origin.mV[1], origin.mV[2]);
00286 
00287                 // *NOTE: have to bind a texture here since register combiners blending in
00288                 // renderStars() requires something to be bound and we might as well only
00289                 // bind the moon's texture once.
00290                 LLImageGL * tex  = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON]->getTexture();
00291                 tex->bind();
00292 
00293                 renderHeavenlyBodies();
00294 
00295                 renderStars();
00296                 
00297 
00298         glPopMatrix();
00299 
00300         renderSkyClouds(camHeightLocal);
00301 
00302         LLImageGL::unbindTexture(0);
00303 }
00304 
00305 void LLDrawPoolWLSky::prerender()
00306 {
00307         //llinfos << "wlsky prerendering pass." << llendl;
00308 }
00309 
00310 LLDrawPoolWLSky *LLDrawPoolWLSky::instancePool()
00311 {
00312         return new LLDrawPoolWLSky();
00313 }
00314 
00315 LLViewerImage* LLDrawPoolWLSky::getTexture()
00316 {
00317         return NULL;
00318 }
00319 
00320 void LLDrawPoolWLSky::resetDrawOrders()
00321 {
00322 }
00323 
00324 //static
00325 void LLDrawPoolWLSky::cleanupGL()
00326 {
00327         sCloudNoiseTexture = NULL;
00328 }
00329 
00330 //static
00331 void LLDrawPoolWLSky::restoreGL()
00332 {
00333         LLImageGL::create(sCloudNoiseTexture, sCloudNoiseRawImage, TRUE);
00334 }

Generated on Fri May 16 08:33:20 2008 for SecondLife by  doxygen 1.5.5