lldrawpoolalpha.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "lldrawpoolalpha.h"
00035 
00036 #include "llglheaders.h"
00037 #include "llviewercontrol.h"
00038 #include "llcriticaldamp.h"
00039 #include "llfasttimer.h"
00040 
00041 #include "llcubemap.h"
00042 #include "llsky.h"
00043 #include "llagent.h"
00044 #include "lldrawable.h"
00045 #include "llface.h"
00046 #include "llviewercamera.h"
00047 #include "llviewerimagelist.h"  // For debugging
00048 #include "llviewerobjectlist.h" // For debugging
00049 #include "llviewerwindow.h"
00050 #include "pipeline.h"
00051 #include "llglslshader.h"
00052 #include "llviewerregion.h"
00053 #include "lldrawpoolwater.h"
00054 #include "llspatialpartition.h"
00055 
00056 BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
00057 
00058 
00059 
00060 LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
00061                 LLRenderPass(type), current_shader(NULL), target_shader(NULL),
00062                 simple_shader(NULL), fullbright_shader(NULL)
00063 {
00064 
00065 }
00066 
00067 LLDrawPoolAlpha::~LLDrawPoolAlpha()
00068 {
00069 }
00070 
00071 
00072 void LLDrawPoolAlpha::prerender()
00073 {
00074         mVertexShaderLevel = LLShaderMgr::getVertexShaderLevel(LLShaderMgr::SHADER_OBJECT);
00075 }
00076 
00077 void LLDrawPoolAlpha::beginRenderPass(S32 pass)
00078 {
00079         LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA);
00080         
00081         if (LLPipeline::sUnderWaterRender)
00082         {
00083                 simple_shader = &gObjectSimpleWaterProgram;
00084                 fullbright_shader = &gObjectFullbrightWaterProgram;
00085         }
00086         else
00087         {
00088                 simple_shader = &gObjectSimpleProgram;
00089                 fullbright_shader = &gObjectFullbrightProgram;
00090         }
00091 
00092         if (mVertexShaderLevel > 0)
00093         {
00094                 // Start out with no shaders.
00095                 current_shader = target_shader = NULL;
00096                 glUseProgramObjectARB(0);
00097         }
00098         gPipeline.enableLightsDynamic();
00099 }
00100 
00101 void LLDrawPoolAlpha::endRenderPass( S32 pass )
00102 {
00103         LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA);
00104         LLRenderPass::endRenderPass(pass);
00105 
00106         if(gPipeline.canUseWindLightShaders()) 
00107         {
00108                 glUseProgramObjectARB(0);
00109         }
00110 }
00111 
00112 void LLDrawPoolAlpha::render(S32 pass)
00113 {
00114         LLFastTimer t(LLFastTimer::FTM_RENDER_ALPHA);
00115 
00116         LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ? GL_TRUE : GL_FALSE);
00117 
00118         LLGLSPipelineAlpha gls_pipeline_alpha;
00119         
00120         renderAlpha(getVertexDataMask());
00121 
00122         if (sShowDebugAlpha)
00123         {
00124                 if(gPipeline.canUseWindLightShaders()) 
00125                 {
00126                         glUseProgramObjectARB(0);
00127                 }
00128                 gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
00129                 glColor4f(1,0,0,1);
00130                 LLViewerImage::sSmokeImagep->addTextureStats(1024.f*1024.f);
00131         LLViewerImage::sSmokeImagep->bind();
00132                 renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |
00133                                                         LLVertexBuffer::MAP_TEXCOORD);
00134         }
00135 }
00136 
00137 void LLDrawPoolAlpha::renderAlpha(U32 mask)
00138 {
00139         for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
00140         {
00141                 LLSpatialGroup* group = *i;
00142                 if (group->mSpatialPartition->mRenderByGroup &&
00143                         !group->isDead())
00144                 {
00145                         renderGroupAlpha(group,LLRenderPass::PASS_ALPHA,mask,TRUE);
00146                 }
00147         }
00148 }
00149 
00150 void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
00151 {
00152         for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
00153         {
00154                 LLSpatialGroup* group = *i;
00155                 if (group->mSpatialPartition->mRenderByGroup &&
00156                         !group->isDead())
00157                 {
00158                         LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];  
00159 
00160                         for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) 
00161                         {
00162                                 LLDrawInfo& params = **k;
00163                                 
00164                                 if (params.mParticle)
00165                                 {
00166                                         continue;
00167                                 }
00168 
00169                                 LLRenderPass::applyModelMatrix(params);
00170 
00171                                 params.mVertexBuffer->setBuffer(mask);
00172                                 params.mVertexBuffer->drawRange(LLVertexBuffer::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
00173                                 gPipeline.addTrianglesDrawn(params.mCount/3);
00174                         }
00175                 }
00176         }
00177 }
00178 
00179 void LLDrawPoolAlpha::renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)
00180 {
00181         BOOL initialized_lighting = FALSE;
00182         BOOL light_enabled = TRUE;
00183         BOOL is_particle = FALSE;
00184         BOOL use_shaders = (LLPipeline::sUnderWaterRender && gPipeline.canUseVertexShaders())
00185                 || gPipeline.canUseWindLightShadersOnObjects();
00186         F32 dist;
00187 
00188         // check to see if it's a particle and if it's "close"
00189         is_particle = !LLPipeline::sUnderWaterRender && (group->mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_PARTICLES);
00190         dist = group->mDistance;
00191         
00192         // don't use shader if debug setting is off and it's close or if it's a particle
00193         // and it's close
00194         if(is_particle && !gSavedSettings.getBOOL("RenderUseShaderNearParticles"))
00195         {
00196                 if((dist < LLViewerCamera::getInstance()->getFar() * gSavedSettings.getF32("RenderShaderParticleThreshold")))
00197                 {
00198                         use_shaders = FALSE;
00199                 }
00200         }
00201 
00202         LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
00203 
00204         if (group->mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_CLOUDS)
00205         {               
00206                 if (!gSavedSettings.getBOOL("SkyUseClassicClouds"))
00207                 {
00208                         return;
00209                 }
00210                 // *TODO - Uhhh, we should always be doing some type of alpha rejection.  These should probably both be 0.01f
00211                 glAlphaFunc(GL_GREATER, 0.f);
00212         }
00213         else
00214         {
00215                 if (LLPipeline::sImpostorRender)
00216                 {
00217                         glAlphaFunc(GL_GREATER, 0.5f);
00218                 }
00219                 else
00220                 {
00221                         glAlphaFunc(GL_GREATER, 0.01f);
00222                 }
00223         }
00224 
00225         for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) 
00226         {
00227                 LLDrawInfo& params = **k;
00228 
00229                 LLRenderPass::applyModelMatrix(params);
00230 
00231                 if (texture && params.mTexture.notNull())
00232                 {
00233                         glActiveTextureARB(GL_TEXTURE0_ARB);
00234                         params.mTexture->bind();
00235                         params.mTexture->addTextureStats(params.mVSize);
00236                         if (params.mTextureMatrix)
00237                         {
00238                                 glMatrixMode(GL_TEXTURE);
00239                                 glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
00240                                 gPipeline.mTextureMatrixOps++;
00241                         }
00242                 }
00243 
00244                 if (params.mFullbright)
00245                 {
00246                         // Turn off lighting if it hasn't already been so.
00247                         if (light_enabled || !initialized_lighting)
00248                         {
00249                                 initialized_lighting = TRUE;
00250                                 if (use_shaders) 
00251                                 {
00252                                         target_shader = fullbright_shader;
00253                                 }
00254                                 else
00255                                 {
00256                                         gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
00257                                 }
00258                                 light_enabled = FALSE;
00259                         }
00260                 }
00261                 // Turn on lighting if it isn't already.
00262                 else if (!light_enabled || !initialized_lighting)
00263                 {
00264                         initialized_lighting = TRUE;
00265                         if (use_shaders) 
00266                         {
00267                                 target_shader = simple_shader;
00268                         }
00269                         else
00270                         {
00271                                 gPipeline.enableLightsDynamic();
00272                         }
00273                         light_enabled = TRUE;
00274                 }
00275 
00276                 // If we need shaders, and we're not ALREADY using the proper shader, then bind it
00277                 // (this way we won't rebind shaders unnecessarily).
00278                 if(use_shaders && (current_shader != target_shader))
00279                 {
00280                         llassert(target_shader != NULL);
00281                         current_shader = target_shader;
00282                         current_shader->bind();
00283                 }
00284                 else if (!use_shaders && current_shader != NULL)
00285                 {
00286                         glUseProgramObjectARB(0);
00287                         current_shader = NULL;
00288                 }
00289 
00290                 params.mVertexBuffer->setBuffer(mask);
00291                 params.mVertexBuffer->drawRange(LLVertexBuffer::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
00292                 gPipeline.addTrianglesDrawn(params.mCount/3);
00293 
00294                 if (params.mTextureMatrix && texture && params.mTexture.notNull())
00295                 {
00296                         glLoadIdentity();
00297                         glMatrixMode(GL_MODELVIEW);
00298                 }
00299         }
00300 
00301         if (!light_enabled)
00302         {
00303                 gPipeline.enableLightsDynamic();
00304         }
00305 }

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