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
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
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
00117
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
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
00159
00160
00161
00162
00163 gPipeline.disableLights();
00164
00165 if (!LLPipeline::sReflectionRender)
00166 {
00167 glPointSize(2.f);
00168 }
00169
00170
00171
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
00178
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
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
00246
00247
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
00288
00289
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
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
00325 void LLDrawPoolWLSky::cleanupGL()
00326 {
00327 sCloudNoiseTexture = NULL;
00328 }
00329
00330
00331 void LLDrawPoolWLSky::restoreGL()
00332 {
00333 LLImageGL::create(sCloudNoiseTexture, sCloudNoiseRawImage, TRUE);
00334 }